📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP
🧵 Как правильно логировать ошибки в Java-приложении
Привет, друзья! Сегодня я расскажу о простой, но критически важной теме — логирование ошибок. Часто вижу, как разработчики либо совсем не логируют исключения, либо делают это неправильно. В итоге: баг есть, а откуда он взялся — непонятно.
Вот пара реальных примеров:
❌ Плохо:
try {
doSomething();
} catch (Exception e) {
System.out.println("Error happened");
}
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
try {
doSomething();
} catch (Exception e) {
logger.error("Failed to do something", e);
}
logger.error
позволяет видеть стек исключения, а это ключ к диагностике.logger.warn
или logger.info
в зависимости от уровня важности.traceId
, userId
, requestId
и другие полезные метаданные.Docker и Spring Boot микросервис (Быстрый старт)
Разберем основные понятия докера и запустим spring boot микросервис в докере
00:00 Intro
00:58 Установить докер
02:05 Развитие виртуализации
09:30 Компоненты Docker
11:25 Docker Daemon
11:50 Dockerfile
12:42 Docker Image
13:12 Docker Registry
13:45 Docker Container
14:00 Dockerhub
14:57 Практика. Пишем микросервис
17:30 Практика. Пишем dockerfile
23:25 Практика. Создаем docker образ
25:48 Практика. Запускам docke контейнер
27:19 Практика. Основные команды
30:00 Best practice. Как еще можно написать dockerfile
33:14 Best practice. Рекомендации
35:01 Итог
источник
👉@BookJava
⚡️👩💻 Хотите освоить Java с нуля и стать востребованным разработчиком? Это один из самых популярных языков программирования, который используется в крупных компаниях по всему миру.
🦾 Курс «Специализация: Java-разработчик» — это три ступени обучения, которые помогут вам пройти путь от новичка до востребованного Middle-разработчика. Вы научитесь создавать серверные приложения, работать с базами данных, осваивать Spring, Docker, Kubernetes и многое другое.
Обучение ведут практикующие эксперты, программа адаптирована для новичков, а диплом OTUS котируется в ведущих IT-компаниях.
Наш партнер — СберКорус, разработчик передовых цифровых решений!
Осталось всего несколько дней, чтобы записаться на курс и получить скидку.
👉 Успейте оставить заявку прямо сейчас: https://vk.cc/cKaEMl
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Хранилище файлов. Java + WebDav
Java + WebDav - загружаем файл на webdav через Rest запрос.
00:00 Приветствие
00:34 Spring Init
00:55 Docker Hub
01:54 docker-compose
04:25 webdav.conf
06:00 application.yaml
06:50 Sardine
07:36 WebDavConfig
09:15 WebConfig
11:40 FileService
14:09 Controller
17:22 Docker Fix
17:47 Postman
18:16 что не так?
20:46 Подписывайтесь
источник
👉@BookJava
Совет💡: если ты обожаешь Ctrl + C
и Ctrl + V
, тебе точно понравится и Ctrl + W
.
Это как выделение текста с помощью AI 😉
https://www.jetbrains.com/help/idea/working-with-source-code.html#editor_code_selection
👉@BookJava
🤝 Если код работает, это еще не значит, что он работает эффективно. Хотите разобраться, как ускорить приложения, найти утечки памяти и правильно деплоить их в облака?
🦾 На повышении квалификации «Java Developer. Advanced» вы изучите JVM на глубоком уровне, научитесь профилировать приложения, оптимизировать их под высокие нагрузки и выстраивать продвинутый мониторинг.
✔️ Глубокое погружение в устройство JVM
✔️ Практика с профилированием и трассировкой
✔️ Работа с Kubernetes, Prometheus и Grafana
✔️ Настройка метрик и логирования
Осталось несколько дней до закрытия набора.
➡️ Пройдите короткое тестирование для проверки своих навыков и присоединяйтесь к группе: https://vk.cc/cJT8Ny
🎁 Начните обучение со скидкой, подробности у менеджеров. ПРОМОКОД: JAVA_03
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Совет Spring Framework💡
Вы можете инжектировать (autowire) бины, которые могут отсутствовать, обернув их в java.util.Optional
. Таким образом вы сообщаете, что этот бин является необязательным, избегаете исключения, если он не существует, и можете аккуратно обработать его отсутствие с помощью Optional API.
👉@BookJava
Java 24 уже доступна!
Download Now: https://jdk.java.net/24/
Release notes: https://jdk.java.net/24/release-notes
API Javadoc: https://docs.oracle.com/en/java/javase/24/docs/api/index.html
Features: https://openjdk.org/projects/jdk/24/
Inside Java on JDK 24: https://inside.java/2025/03/18/the-arrival-of-java-24/
👉 @BookJava
👩💻 Создание приложения Блокнот на Java 👩💻
🗓 24 марта в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».
На вебинаре мы разработаем полноценное приложение «Блокнот» с графическим пользовательским интерфейсом, демонстрирующее базовые принципы создания текстового редактора на Java.
В процессе занятия мы реализуем такие функциональные возможности, как:
- создание нового текстового файла, его сохранение,
- загрузка уже существующего файла,
- редактирование текста, подсчет статистических данных и другие операции, характерные для текстовых редакторов.
Особое внимание будет уделено работе с файловой системой, потоками ввода/вывода и обработке событий, что позволит создать удобное и интуитивно понятное приложение.
Спикер Александр Фисунов — Senior Kotlin Developer в SSP Software на проекте ВТБ, опытный Java-разработчик и кандидат технических наук.
🔗 Ссылка на регистрацию: https://vk.cc/cJP0NY
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
#Java springboot
Совет: Нужно быстро собрать разрозненные данные в POST-запросе?
Просто создайте встроенную record в вашем @RestController
и используйте её как @RequestBody
.
Не нужно определять DTO в отдельном классе – record будет видна только внутри этого контроллера. 🚀
👉@BookJava
Подборка Telegram каналов для программистов
/channel/bash_srv Bash Советы
/channel/win_sysadmin Системный Администратор Windows
/channel/lifeproger Жизнь программиста. Авторский канал.
/channel/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
/channel/rabota1C_rus Вакансии для программистов 1С
Системное администрирование 📌
/channel/sysadmin_girl Девочка Сисадмин
/channel/srv_admin_linux Админские угодья
/channel/linux_srv Типичный Сисадмин
/channel/linux_odmin Linux: Системный администратор
/channel/devops_star DevOps Star (Звезда Девопса)
/channel/i_linux Системный администратор
/channel/linuxchmod Linux
/channel/sys_adminos Системный Администратор
/channel/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
/channel/sysadminof Книги для админов, полезные материалы
/channel/i_odmin Все для системного администратора
/channel/i_odmin_book Библиотека Системного Администратора
/channel/i_odmin_chat Чат системных администраторов
/channel/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
/channel/sysadminoff Новости Линукс Linux
1C разработка 📌
/channel/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
/channel/DevLab1C 1С:Предприятие 8
Программирование C++📌
/channel/cpp_lib Библиотека C/C++ разработчика
/channel/cpp_knigi Книги для программистов C/C++
/channel/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
/channel/pythonofff Python академия. Учи Python быстро и легко🐍
/channel/BookPython Библиотека Python разработчика
/channel/python_real Python подборки на русском и английском
/channel/python_360 Книги по Python Rus
Java разработка 📌
/channel/BookJava Библиотека Java разработчика
/channel/java_360 Книги по Java Rus
/channel/java_geek Учим Java на примерах
GitHub Сообщество 📌
/channel/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
/channel/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
/channel/developer_mobila Мобильная разработка
/channel/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
/channel/frontend_1 Подборки для frontend разработчиков
/channel/frontend_sovet Frontend советы, примеры и практика!
/channel/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
/channel/game_devv Все о разработке игр
Библиотеки 📌
/channel/book_for_dev Книги для программистов Rus
/channel/programmist_of Книги по программированию
/channel/proglb Библиотека программиста
/channel/bfbook Книги для программистов
/channel/books_reserv Книги для программистов
БигДата, машинное обучение 📌
/channel/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
Программирование 📌
/channel/bookflow Лекции, видеоуроки, доклады с IT конференций
/channel/coddy_academy Полезные советы по программированию
/channel/rust_lib Полезный контент по программированию на Rust
/channel/golang_lib Библиотека Go (Golang) разработчика
/channel/itmozg Программисты, дизайнеры, новости из мира IT
/channel/php_lib Библиотека PHP программиста 👨🏼💻👩💻
/channel/nodejs_lib Подборки по Node js и все что с ним связано
/channel/ruby_lib Библиотека Ruby программиста
QA, тестирование 📌
/channel/testlab_qa Библиотека тестировщика
Шутки программистов 📌
/channel/itumor Шутки программистов
Защита, взлом, безопасность 📌
/channel/thehaking Канал о кибербезопасности
/channel/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
/channel/ux_web Статьи, книги для дизайнеров
Математика 📌
/channel/Pomatematike Канал по математике
/channel/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак📌
/channel/Excel_lifehack
/channel/tikon_1 Новости высоких технологий, науки и техники💡
/channel/mir_teh Мир технологий (Technology World)
Вакансии 📌
/channel/sysadmin_rabota Системный Администратор
/channel/progjob Вакансии в IT
👩💻 Курс «Java-разработчик»: помощь в превращении стажёра в сильного Middle
🔥 Вы платите не только за знания, но и за эффективное карьерное сопровождение. Быстрее найдя работу, вы окупите затраты и начнёте уверенно расти в доходе.
💻 Наше обучение — это живые вебинары с действующими экспертами в области, которые проведут тебя от новичка до уверенного Middle-разработчика. Ты освоишь Spring, Hibernate, PostgreSQL, Docker, Kafka, Kubernetes и другие актуальные технологии!
✔️ Трехступенчатая поддержка до полного трудоустройства
- Мы сопровождаем студента не только в момент обучения и поиска работы, но и в период адаптации после выхода в новую компанию.
✔️ Индивидуальный подход на вебинарах и консультациях
- Мы не выдаем всем «один и тот же скрипт»: во время карьерных вебинаров отвечаем на конкретные вопросы студентов.
✔️ Профессиональное резюме под руководством HR-экспертов
- Подготовка резюме и разбор «точек роста». Эксперт помогает сформулировать сильные стороны, уникальные достижения и убрать «лишнее», чтобы резюме работало на конкретные вакансии.
✔️ Поддержка после оффера
- Даем рекомендации, как вести себя в первые месяцы, какие вопросы задавать руководителю, как справляться со стрессом и «синдромом самозванца». Это особенно важно, когда студент переходит из стажерской/джуниор роли в более серьезную позицию.
Наш партнер — СберКорус, разработчик передовых цифровых решений!
👉 Оставь заявку и получи скидку на курс: https://vk.cc/cJFwz6
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Доброе утро, коллеги!
Сегодня я хочу обсудить с вами одну из распространённых проблем, с которыми сталкиваются Java-разработчики, — "ад зависимостей".
Что такое "ад зависимостей"?
"Ад зависимостей" возникает, когда ваше приложение зависит от множества библиотек, каждая из которых, в свою очередь, имеет свои зависимости. Это может привести к следующим проблемам:
- Множество зависимостей: Приложение требует загрузки большого числа библиотек, что увеличивает время сборки и объём занимаемого дискового пространства.
- Длинные цепочки зависимостей: Одна библиотека зависит от другой, та — от третьей и так далее. Это усложняет управление и может привести к конфликтам версий.
- Конфликтующие зависимости: Разные библиотеки требуют разные версии одной и той же зависимости, что может привести к несовместимости и ошибкам при выполнении приложения.
Как избежать "ада зависимостей"?
1. Используйте системы управления зависимостями: Инструменты, такие как Maven или Gradle, помогают автоматически управлять зависимостями, разрешать конфликты версий и упрощают процесс сборки проекта.
2. Ограничивайте количество зависимостей: Перед добавлением новой библиотеки задумайтесь, действительно ли она необходима. Возможно, функциональность можно реализовать с помощью уже используемых инструментов или собственными силами.
3. Следите за версиями библиотек: Старайтесь использовать стабильные и проверенные версии зависимостей. Избегайте использования библиотек, которые давно не обновлялись или имеют известные проблемы совместимости.
4. Проводите регулярные ревизии зависимостей: Периодически проверяйте, какие библиотеки используются в проекте, и удаляйте неиспользуемые или устаревшие зависимости.
5. Изолируйте зависимости: Если возможно, используйте механизмы модульности (например, Java Modules) для изоляции зависимостей и предотвращения конфликтов между ними.
Заключение
Управление зависимостями — ключевой аспект разработки на Java. Грамотный подход к этому вопросу поможет избежать множества проблем и обеспечит стабильность и надёжность вашего приложения. Делитесь своим опытом и подходами к управлению зависимостями в комментариях!
👉@BookJava
📝 Как улучшить читаемость кода в Java?
Сегодня поговорим о читаемости кода — важном аспекте, который отличает хорошего разработчика от посредственного. Если твой код понятен, его легче поддерживать, расширять и дебажить. Вот несколько проверенных приемов:
✅ Говорящие имена переменных и методов
Не используй x
, temp
, data
— дай переменным осмысленные названия. Например, вместо:
int d = 365;
int daysInYear = 365;
if (user != null) {
if (user.isActive()) {
process(user);
}
}
if (user == null) return;
if (!user.isActive()) return;
process(user);
3.14159
, 86400
— вынеси их в константы:
private static final int SECONDS_IN_A_DAY = 86400;
NullPointerException
, возвращай Optional<T>
вместо null
и Collections.emptyList()
вместо пустых списков. Ctrl + Alt + L
в IntelliJ IDEA). Совет по Spring Boot💡
Ошибка конфигурации сервера Spring Boot ⬇
https://gist.github.com/aoudiamoncef/bba3f7c79f1056a22a3a82b3a171b5b3
👉@BookJava
📕 Открытый урок по разработке веб-приложений на Scala
На открытом уроке 1 апреля в 20:00 мск мы погрузимся в мир бэкенд-разработки на Scala.
📗 В результате вы:
— Узнаете ключевые аспекты создания современных веб-приложений на Scala;
— Познакомитесь с популярными фреймворками и инструментами для работы с базами данных;
— На практике создадите простое CRUD-приложение для закрепления навыков.
Спикер: Алексей Воронец — руководитель разработки департамента проектных решений и поисковых систем в компании Naumen, эксперт с 14-летним опытом, специализирующийся на Scala и функциональном программировании.
👉 Регистрируйтесь прямо сейчас, чтобы не пропустить мероприятие
https://vk.cc/cKbqwh
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Пишем рекомендательную систему музыки на Java
Андрей Кузнецов — Мастер-класс
Машинное обучение обычно рассматривают как отдельно стоящую область, требующую специфических знаний. Однако на практике бывает, что для решения бизнес-задач может быть достаточно и простых решений, имплементация которых не представляет сложностей для разработчика.
Используя открытый датасет, мы пишем с нуля на Java рекомендательную систему музыки и разберем, какие из наивных решений могут не сработать в реальных системах. На примере технологий Одноклассников спикер рассказывает, как решаются ML-задачи в гетерогенных продакшенах, где необходимо использовать вместе Java и Python.
Мастер-класс будет интересен разработчикам, которым интересна тема машинного обучения, но они либо еще не погружались в нее, либо сделали самые первые шаги.
источник
👉@BookJava
🔧 Как ускорить сборку Maven проекта в 3 раза
Сегодня покажу пару приёмов, которые помогут тебе значительно ускорить сборку Maven проекта. Особенно полезно, если ты работаешь с большими монолитами или частыми CI/CD прогонками.
🚀 1. Включи параллельную сборку
Добавь флаг -T
(thread count), чтобы Maven собирал модули параллельно:
mvn clean install -T 1C
1C
— это количество потоков = количеству ядер CPU. Можешь указать, например, -T 4
для 4 потоков. Эффект — сборка может стать в 2–4 раза быстрее.
mvn clean install -DskipTests
-DskipTests
— пропускает *и* компиляцию тестов, и сами тесты.
mvn clean install -Dmaven.test.skip=false -DskipTests=true
mvn dependency:go-offline
mvn dependency:go-offline
👩💻 Rate-limiter. Bucket4j
Приглашаем на открытый урок.
🗓 24 марта в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java Developer. Professional».
Продолжаем изучать библиотеки обеспечения устойчивости приложений. На примере Bucket4j посмотрим устройство распределенного Rate-limiter-а.
О чём поговорим:
✔️ Познакомимся с библиотекой Bucket4j.
✔️ Узнаем основные принципы действия и сценарии применения.
Кому будет интересно:
Вебинар будет полезен Java-разработчикам, архитекторам ПО и инженерам по устойчивости систем, заинтересованным в эффективном управлении потоками запросов и защите приложений от перегрузок.
🔗 Ссылка на регистрацию: https://vk.cc/cJUU0G
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Что такое synchronized?
это ключевое слово в Java, которое используется для управления доступом к критическим секциям кода при многопоточном выполнении. Оно гарантирует, что только один поток может выполнить блок кода или метод в определённый момент времени.
synchronized —
Зачем нужен synchronized
?
Когда несколько потоков обращаются к общим данным (например, к переменной, коллекции, объекту), может возникнуть состояние гонки (race condition), приводящее к некорректной работе программы. Чтобы этого избежать, и используется synchronized
.
Как работает?synchronized
блокирует объект или класс, чтобы другие потоки не могли войти в синхронизированную секцию, пока текущий поток её не покинет.
Примеры
🔹 Синхронизация метода (экземпляра):
public synchronized void increment() {
count++;
}
public void increment() {
synchronized (this) {
count++;
}
}
public static synchronized void increment() {
staticCount++;
}
synchronized (MyClass.class) {
staticCount++;
}
synchronized
влияет на производительность, т.к. вызывает блокировки.java.util.concurrent.locks.Lock
или атомарные классы (AtomicInteger
и т.д.).📌 Почему Optional
не стоит использовать в качестве параметра метода?
Сегодня разберем один из популярных вопросов: можно ли использовать Optional
в параметрах метода? Казалось бы, это удобный способ передавать необязательный аргумент, но есть нюансы.
🚫 Почему это плохая практика?
1️⃣ Усложнение API
Когда метод принимает Optional
, это вынуждает вызывающий код создавать Optional.of(value)
, даже если он не использует Optional
в своем контексте. Это добавляет лишнюю работу.
2️⃣ Неявность кода
Если метод принимает Optional
, становится неясно, можно ли просто передать null
или обязательно использовать Optional.empty()
.
3️⃣ Снижение читаемости и удобства
Обычное условие if (param != null)
проще и понятнее, чем if (param.isPresent())
.
4️⃣ Не поддерживается стандартом Java API
В JDK не встретишь API, где Optional
используется как параметр метода. Это не случайность — так принято по соглашению.
✅ Как правильно?
Используйте обычные перегруженные методы или @Nullable
аннотацию:
public void process(String value) {
// обработка значения
}
public void process() {
process("default");
}
null
, то лучше явно работать с null
, чем принудительно оборачивать его в Optional
. 👩💻 Открытый урок «DAO на Spring JDBC»
🗓 26 марта в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Разработчик на Spring Framework»
Использование нативного SQL с Spring JDBC позволяет создать безопасное, поддерживаемое и тестируемое DAO для эффективного доступа к данным.
О чём поговорим:
- Преимущества нативного SQL при разработке DAO.
- Основные возможности Spring JDBC для работы с запросами.
- Подходы к обеспечению безопасности и тестируемости DAO.
🔗 Ссылка на регистрацию: https://vk.cc/cJRacK
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🛠️ SOLID: Почему важно соблюдать принципы?
Сегодня поговорим о SOLID – пяти принципах, которые делают код понятным, гибким и легким для поддержки. Если ты хочешь писать код, который не треснет по швам через пару месяцев, эти принципы — твои лучшие друзья.
1. Single Responsibility Principle (SRP)
Одна ответственность – один класс.
Если у класса больше одной причины измениться, значит, он нарушает SRP. Такой код сложно поддерживать, потому что при изменении одной логики мы можем случайно сломать другую.
✅ Правильно:
class ReportGenerator {
void generateReport() { /* Логика генерации отчета */ }
}
class ReportSaver {
void saveReport() { /* Логика сохранения отчета */ }
}
class ReportService {
void generateAndSaveReport() { /* Генерация + сохранение отчета */ }
}
interface Payment {
void process();
}
class CreditCardPayment implements Payment {
public void process() { /* Логика оплаты картой */ }
}
class PayPalPayment implements Payment {
public void process() { /* Логика оплаты PayPal */ }
}
class Bird {
void fly() { /* Летает */ }
}
class Penguin extends Bird {
void fly() { throw new UnsupportedOperationException("Пингвины не летают!"); }
}
Penguin
нарушает контракт родителя.
interface Bird { }
interface FlyingBird extends Bird { void fly(); }
class Sparrow implements FlyingBird {
public void fly() { /* Летает */ }
}
class Penguin implements Bird {
// Пингвин вообще не имеет метода fly()
}
interface Worker {
void work();
void eat();
}
class Robot implements Worker {
public void work() { /* Работает */ }
public void eat() { throw new UnsupportedOperationException("Роботы не едят!"); }
}
interface Workable {
void work();
}
interface Eatable {
void eat();
}
class Robot implements Workable {
public void work() { /* Работает */ }
}
class Lamp {
void turnOn() { /* Включить */ }
}
class Switch {
private Lamp lamp;
Switch(Lamp lamp) {
this.lamp = lamp;
}
void press() { lamp.turnOn(); }
}
interface Switchable {
void turnOn();
}
class Lamp implements Switchable {
public void turnOn() { /* Включить */ }
}
class Switch {
private Switchable device;
Switch(Switchable device) {
this.device = device;
}
void press() { device.turnOn(); }
}
🚀 Совет по Spring API 🚀
LocaleContextHolder
Стратегия для хранения текущей локали потокобезопасным способом. Полезно для получения текущей локали без необходимости передавать её явно через параметры методов. 🔥
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/i18n/LocaleContextHolder.html
👉@BookJava
📌 Stream API: Группировка данных в Java
Привет, друзья! Сегодня разберем мощную возможность Stream API – группировка данных с помощью Collectors.groupingBy()
. Это отличный инструмент, когда нужно собирать элементы в группы по какому-то признаку.
📌 Как это работает?
Метод groupingBy
используется в Collectors
и позволяет группировать элементы по ключу, который мы указываем. Давайте рассмотрим на примере:
import java.util.*;
import java.util.stream.Collectors;
class Person {
String name;
String city;
Person(String name, String city) {
this.name = name;
this.city = city;
}
@Override
public String toString() {
return name;
}
}
public class GroupingExample {
public static void main(String[] args) {
List<Person> people = List.of(
new Person("Иван", "Москва"),
new Person("Анна", "Санкт-Петербург"),
new Person("Сергей", "Москва"),
new Person("Мария", "Казань"),
new Person("Алексей", "Санкт-Петербург")
);
Map<String, List<Person>> groupedByCity = people.stream()
.collect(Collectors.groupingBy(person -> person.city));
groupedByCity.forEach((city, residents) ->
System.out.println(city + ": " + residents)
);
}
}
people
с объектами Person
, у которых есть name
и city
. groupingBy
, передавая person -> person.city
в качестве критерия группировки. Map<String, List<Person>>
, где ключ – город, а значение – список людей из этого города. forEach
.
Москва: [Иван, Сергей]
Санкт-Петербург: [Анна, Алексей]
Казань: [Мария]
groupingBy()
– это универсальный инструмент, который решает такие задачи.
Map<String, Long> countByCity = people.stream()
.collect(Collectors.groupingBy(p -> p.city, Collectors.counting()));
Map<String, Set<String>> namesByCity = people.stream()
.collect(Collectors.groupingBy(p -> p.city,
Collectors.mapping(p -> p.name, Collectors.toSet())));
Оптимизация SQL-запросов в Hibernate
Сегодня я хочу поделиться с вами одной из распространённых проблем в Hibernate — N+1 проблема. Если вы используете ORM без оптимизаций, то скорее всего сталкивались с этим.
📌 В чём суть?
Допустим, у нас есть две связанные сущности:@Entity
public class Author {
@Id @GeneratedValue
private Long id;
private String name;
@OneToMany(mappedBy = "author", fetch = FetchType.LAZY)
private List<Book> books;
}@Entity
public class Book {
@Id @GeneratedValue
private Long id;
private String title;
@ManyToOne
private Author author;
}
Теперь, если мы получим список авторов и для каждого загрузим книги:List<Author> authors = entityManager.createQuery("SELECT a FROM Author a", Author.class).getResultList();
for (Author author : authors) {
System.out.println(author.getBooks().size());
}
Мы получаем 1 запрос для авторов + N запросов для книг. Это и есть N+1 проблема!
🚀 Как исправить?
Используем JOIN FETCH:List<Author> authors = entityManager.createQuery(
"SELECT a FROM Author a JOIN FETCH a.books", Author.class).getResultList();
Теперь будет один SQL-запрос вместо кучи мелких.
🔥 Альтернативы:
• Entity Graph – даёт гибкость в загрузке связей.
• Batch Size в Hibernate – уменьшает количество запросов.
• DTO и кастомные запросы – загружаем только нужные данные.
Оптимизация SQL-запросов в ORM — ключ к быстродействию вашего приложения!
👉@BookJava
📌 Как правильно писать equals и hashCode в Java?
Сейчас разберем один из самых частых вопросов у Java-разработчиков: как правильно переопределять equals()
и hashCode()
?
Эти методы нужны для корректного сравнения объектов и работы коллекций (`HashMap`, HashSet
, HashTable
и т. д.). Неправильная реализация может привести к неожиданным багам, которые трудно отловить.
✅ Основные правила для equals()
1️⃣ Рефлексивность – x.equals(x)
должно всегда возвращать true
.
2️⃣ Симметричность – x.equals(y)
должно возвращать тот же результат, что и y.equals(x)
.
3️⃣ Транзитивность – если x.equals(y)
и y.equals(z)
, то x.equals(z)
.
4️⃣ Стабильность – если объекты не менялись, результат вызова equals()
не должен меняться.
5️⃣ Не null
– x.equals(null)
всегда должен возвращать false
.
Пример корректного equals()
:
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
MyClass myClass = (MyClass) obj;
return Objects.equals(field1, myClass.field1) &&
Objects.equals(field2, myClass.field2);
}
hashCode()
equals()
возвращает true
, то hashCode()
должен быть одинаковым. equals()
возвращает false
, то hashCode()
может быть одинаковым, но лучше минимизировать коллизии. hashCode()
должен быть быстрым и эффективно распределять объекты. hashCode()
:
@Override
public int hashCode() {
return Objects.hash(field1, field2);
}
==
вместо equals()
для объектов. hashCode()
, из-за чего HashMap
работает некорректно. hashCode()
– при изменении объекта он может потеряться в HashMap
. Objects.equals()
и Objects.hash()
, чтобы избежать рутины! equals()
и hashCode()
? Были ли у вас баги из-за их неправильной работы? Делитесь в комментариях! ⚡️ Квиз на знание Java
Пройти тестирование — сложно! А ты справишься?
22 вопроса, 30 минут
Проверь себя - пройди квиз и оцени свой уровень навыков, а также свою готовность к обучению на курсе — «Java Developer. Advanced» от Отус.
👩💻 На курсе ты научишься профилировать приложения, настраивать GC, работать с реактивными подходами и мониторить метрики в Grafana. Пройдешь весь путь от JVM до Kubernetes, научишься анализировать «горячие точки», оптимизировать приложения и настраивать интеграции с Prometheus.
➡️ ПРОЙТИ ТЕСТ: https://vk.cc/cJDbVm
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
📚 Greenplum, PostgreSQL и Airflow в одном открытом вебинаре.
Освойте ключевые инструменты работы с данными.
Встречаемся на открытом вебинаре 18 марта в 20:00 мск.
🔍 На уроке вы:
- Создадите инструмент для генерации данных в PostgreSQL
- Настроите хранение истории данных в ArenadataDB
- Напишете ETL-пайплайн для автоматической загрузки данных
После занятия вы сможете строить дата-пайплайны и автоматизировать загрузку данных, что существенно упростит вашу работу с данными.
🎓 Записывайтесь и получите скидку на большое обучение «Greenplum для разработчиков и архитекторов баз данных»: https://vk.cc/cJD2rT
Не упустите возможность прокачать свои навыки и освоить современные технологии! 🚀
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🚀 Оптимизация SQL-запросов в Java: используем Query Hints правильно!
Сегодня я хочу поговорить о Query Hints – мощном, но часто игнорируемом инструменте, который может значительно ускорить SQL-запросы в Java-приложениях.
🔥 Что такое Query Hints?
Query Hints – это специальные инструкции для базы данных, которые помогают оптимизатору запросов выбрать наиболее эффективный план выполнения. В Java (Hibernate, JPA, Spring Data) их можно использовать для управления кешированием, выбором индексов и стратегией выполнения.
⚡ Как использовать Query Hints в Hibernate?
В Hibernate есть два способа добавления Query Hints:
1. Через EntityManager
Query query = entityManager.createQuery("SELECT u FROM User u WHERE u.age > :age")
.setParameter("age", 25)
.setHint("org.hibernate.cacheable", true);
List<User> users = query.getResultList();
@QueryHint
(Spring Data JPA)
@QueryHints({@QueryHint(name = "org.hibernate.readOnly", value = "true")})
@Query("SELECT u FROM User u WHERE u.status = 'ACTIVE'")
List<User> findActiveUsers();
org.hibernate.cacheable = true
– разрешает кеширование результата.org.hibernate.fetchSize = N
– задаёт количество строк, загружаемых за раз.org.hibernate.readOnly = true
– отключает слежение за изменениями (ускоряет SELECT).org.hibernate.comment = 'My custom hint'
– добавляет комментарий к запросу.