⚖️ 👩💻 Сравнение механизмов синхронизации потоков с помощью JMH
Понимание синхронизации — ключ к многопоточности. Оцените эффективность механизмов и проверьте гипотезы с помощью JMH.
🗓 13 марта в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java Developer. Advanced».
📌 О чём поговорим:
- Ключевые механизмы синхронизации в Java (synchronized, ReentrantLock и другие).
- Особенности их применения в многопоточном коде и влияние на производительность.
- Настройка и проведение бенчмарков JMH для объективного сравнения различных подходов.
📌 Кому будет интересно:
Java-разработчикам, инженерам по производительности и любителям многопоточности, желающим оценить скорость и надёжность разных механизмов.
📌 В результате урока вы получите:
- Навык реализации JMH-бенчмарков для сравнения различных инструментов синхронизации.
- Понимание разницы в скорости работы механизмов и уверенность в выборе оптимального решения.
🔗 Ссылка на регистрацию: https://vk.cc/cJlnn7
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Понимание синхронизации — ключ к многопоточности. Оцените эффективность механизмов и проверьте гипотезы с помощью JMH.
🗓 13 марта в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java Developer. Advanced».
- Ключевые механизмы синхронизации в Java (synchronized, ReentrantLock и другие).
- Особенности их применения в многопоточном коде и влияние на производительность.
- Настройка и проведение бенчмарков JMH для объективного сравнения различных подходов.
Java-разработчикам, инженерам по производительности и любителям многопоточности, желающим оценить скорость и надёжность разных механизмов.
- Навык реализации JMH-бенчмарков для сравнения различных инструментов синхронизации.
- Понимание разницы в скорости работы механизмов и уверенность в выборе оптимального решения.
🔗 Ссылка на регистрацию: https://vk.cc/cJlnn7
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
📌 Spring Boot: Как использовать
Сегодня я расскажу вам, как правильно использовать аннотацию
🔹 Что делает
Эта аннотация позволяет выполнять методы в отдельном потоке, не блокируя основной поток приложения. Это удобно, когда нужно, например, отправить email или выполнить сложный расчет без задержки ответа пользователю.
🔹 Как правильно использовать?
1️⃣ Включите поддержку асинхронности
Добавьте в главный класс Spring Boot:
2️⃣ Аннотируйте метод в сервисе
3️⃣ Вызывайте метод асинхронно
🔹 Частые ошибки и их решения
❌ Вызываете асинхронный метод внутри того же класса?
Spring не будет проксировать вызов, и
❌ Нет пула потоков?
По умолчанию Spring использует SimpleAsyncTaskExecutor, который создает новый поток для каждой задачи. Это может перегрузить систему. Лучше явно указать пул:
💡 Вы используете
👉@BookJava
@Async
и не напороться на проблемы?Сегодня я расскажу вам, как правильно использовать аннотацию
@Async
в Spring Boot, чтобы асинхронные задачи работали стабильно и без неожиданностей.🔹 Что делает
@Async
?Эта аннотация позволяет выполнять методы в отдельном потоке, не блокируя основной поток приложения. Это удобно, когда нужно, например, отправить email или выполнить сложный расчет без задержки ответа пользователю.
🔹 Как правильно использовать?
1️⃣ Включите поддержку асинхронности
Добавьте в главный класс Spring Boot:
@EnableAsync
@SpringBootApplication
public class MyApplication {
}
2️⃣ Аннотируйте метод в сервисе
@Service
public class EmailService {
@Async
public void sendEmail(String email) {
System.out.println("Отправка email: " + email + " в потоке " + Thread.currentThread().getName());
}
}
3️⃣ Вызывайте метод асинхронно
@Component
public class NotificationSender {
private final EmailService emailService;
public NotificationSender(EmailService emailService) {
this.emailService = emailService;
}
public void notifyUser(String email) {
emailService.sendEmail(email);
System.out.println("Метод notifyUser выполняется в потоке " + Thread.currentThread().getName());
}
}
🔹 Частые ошибки и их решения
❌ Вызываете асинхронный метод внутри того же класса?
Spring не будет проксировать вызов, и
@Async
просто не сработает. Выносите метод в отдельный бин!❌ Нет пула потоков?
По умолчанию Spring использует SimpleAsyncTaskExecutor, который создает новый поток для каждой задачи. Это может перегрузить систему. Лучше явно указать пул:
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.initialize();
return executor;
}
}
💡 Вы используете
@Async
в своем проекте? Какие были подводные камни? Делитесь в комментариях!👉@BookJava
👍7❤1
⚡️ Квиз на знание Java
Пройти тестирование — сложно! А ты справишься?
21 вопрос, 30 минут
Проверь себя - пройди квиз и оцени свой уровень навыков, а также свою готовность к обучению на курсе — «Разработчик на Spring Framework» от OTUS.
💻 За 5 месяцев обучения ты освоишь современные возможности Spring, научишься быстро проходить путь от идеи до production-grade, создавать Web-приложения на микросервисной архитектуре и решать высокоуровневые задачи по разработке.
👉 ПРОЙТИ ТЕСТ: https://vk.cc/cJotoa
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Пройти тестирование — сложно! А ты справишься?
21 вопрос, 30 минут
Проверь себя - пройди квиз и оцени свой уровень навыков, а также свою готовность к обучению на курсе — «Разработчик на Spring Framework» от OTUS.
💻 За 5 месяцев обучения ты освоишь современные возможности Spring, научишься быстро проходить путь от идеи до production-grade, создавать Web-приложения на микросервисной архитектуре и решать высокоуровневые задачи по разработке.
👉 ПРОЙТИ ТЕСТ: https://vk.cc/cJotoa
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🚀 Пишем эффективные SQL-запросы в Hibernate: ТОП ошибок и их исправление
Сегодня поговорим о распространенных ошибках при работе с Hibernate и SQL-запросами. Многие из них приводят к проблемам с производительностью, искаженными данными и даже утечкам памяти.
❌ Ошибка №1: Избыточные запросы (N+1 Problem)
_Проблема:_ Если загружать список сущностей и затем получать связанные данные в цикле, Hibernate будет делать отдельный SQL-запрос для каждой записи.
_Пример:_
✅ Решение: Используйте
❌ Ошибка №2: Использование
_Проблема:_ Запросы вида
_Пример:_
✅ Решение:
1. Используйте полнотекстовый поиск (например, PostgreSQL full-text search или **Elasticsearch**).
2. Если всё же нужен
❌ Ошибка №3: Неиспользование
_Проблема:_ Если у вас коллекция
✅ Решение: Включаем
Либо добавляем глобально в
❌ Ошибка №4: Неограниченный размер выборки (
_Проблема:_ Запрос без
✅ Решение: Всегда указываем
🏆 Вывод
Проблемы с Hibernate и SQL встречаются часто, но их можно легко избежать! Следите за запросами и используйте JOIN FETCH, индексы, batch_size и LIMIT, чтобы повысить производительность.
А какие проблемы с Hibernate встречались вам? Делитесь в комментариях! 👇
👉@BookJava
Сегодня поговорим о распространенных ошибках при работе с Hibernate и SQL-запросами. Многие из них приводят к проблемам с производительностью, искаженными данными и даже утечкам памяти.
❌ Ошибка №1: Избыточные запросы (N+1 Problem)
_Проблема:_ Если загружать список сущностей и затем получать связанные данные в цикле, Hibernate будет делать отдельный SQL-запрос для каждой записи.
_Пример:_
List<User> users = session.createQuery("FROM User", User.class).getResultList();
for (User user : users) {
System.out.println(user.getOrders().size()); // Генерирует N дополнительных запросов!
}
✅ Решение: Используйте
JOIN FETCH
для загрузки связанных данных одним запросом:
List<User> users = session.createQuery(
"SELECT u FROM User u JOIN FETCH u.orders", User.class).getResultList();
❌ Ошибка №2: Использование
LIKE
без индексов _Проблема:_ Запросы вида
LIKE '%value%'
приводят к полному сканированию таблицы, что критично для больших баз данных. _Пример:_
SELECT * FROM users WHERE username LIKE '%john%';
✅ Решение:
1. Используйте полнотекстовый поиск (например, PostgreSQL full-text search или **Elasticsearch**).
2. Если всё же нужен
LIKE
, постарайтесь использовать его в виде value%
, чтобы индексы работали.❌ Ошибка №3: Неиспользование
batch_size
для @OneToMany
_Проблема:_ Если у вас коллекция
@OneToMany
, Hibernate может загружать каждый элемент отдельным запросом. ✅ Решение: Включаем
batch_size
, чтобы загружать данные пакетами:
@OneToMany(mappedBy = "user")
@BatchSize(size = 10)
private List<Order> orders;
Либо добавляем глобально в
hibernate.cfg.xml
:
<property name="hibernate.default_batch_fetch_size">10</property>
❌ Ошибка №4: Неограниченный размер выборки (
LIMIT
отсутствует) _Проблема:_ Запрос без
LIMIT
может возвращать тысячи строк, нагружая базу и приложение. ✅ Решение: Всегда указываем
LIMIT
или используем setMaxResults()
:
Query<User> query = session.createQuery("FROM User", User.class);
query.setMaxResults(50); // Ограничиваем выборку
List<User> users = query.getResultList();
🏆 Вывод
Проблемы с Hibernate и SQL встречаются часто, но их можно легко избежать! Следите за запросами и используйте JOIN FETCH, индексы, batch_size и LIMIT, чтобы повысить производительность.
А какие проблемы с Hibernate встречались вам? Делитесь в комментариях! 👇
👉@BookJava
👍6
🔥 Stream API: Фильтрация, Преобразование и Сортировка 🔥
Сегодня я покажу вам, как эффективно работать с Stream API в Java, выполняя фильтрацию, преобразование и сортировку данных.
Допустим, у нас есть список пользователей:
Теперь представьте, что у нас есть список пользователей, и мы хотим:
✅ Оставить только совершеннолетних
✅ Отсортировать их по возрасту
✅ Преобразовать в список имен
Легко справимся с этим с помощью Stream API:
Что здесь происходит?
🔹
🔹
🔹
🔹
Stream API позволяет писать чистый, читаемый и декларативный код, избавляя от лишних циклов.
А вы активно используете Stream API в своих проектах? Делитесь в комментариях! 🚀
👉@BookJava
Сегодня я покажу вам, как эффективно работать с Stream API в Java, выполняя фильтрацию, преобразование и сортировку данных.
Допустим, у нас есть список пользователей:
class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return name + " (" + age + ")";
}
}
Теперь представьте, что у нас есть список пользователей, и мы хотим:
✅ Оставить только совершеннолетних
✅ Отсортировать их по возрасту
✅ Преобразовать в список имен
Легко справимся с этим с помощью Stream API:
List<User> users = List.of(
new User("Алекс", 25),
new User("Мария", 17),
new User("Иван", 30),
new User("Ольга", 20)
);
List<String> adultNames = users.stream()
.filter(user -> user.age >= 18) // Фильтрация
.sorted(Comparator.comparingInt(user -> user.age)) // Сортировка
.map(user -> user.name) // Преобразование
.toList();
System.out.println(adultNames); // [Ольга, Алекс, Иван]
Что здесь происходит?
🔹
filter(user -> user.age >= 18)
: Убираем несовершеннолетних. 🔹
sorted(Comparator.comparingInt(user -> user.age))
: Сортируем по возрасту. 🔹
map(user -> user.name)
: Преобразуем User
в String
, оставляя только имена. 🔹
toList()
: Собираем результат в список. Stream API позволяет писать чистый, читаемый и декларативный код, избавляя от лишних циклов.
А вы активно используете Stream API в своих проектах? Делитесь в комментариях! 🚀
👉@BookJava
👍10
🗓 17 марта в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Разработчик на Spring Framework»
Продолжаем готовится к возможному собеседованию.
На уроке мы обсудим вопросы, которые могут встретиться на интервью по теме разработки на Spring.
На очереди Spring Boot.
Подключайтесь.
🔗 Ссылка на регистрацию: https://vk.cc/cJBl4X
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🚀 Оптимизация 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
Здесь "org.hibernate.cacheable" позволяет кешировать результат запроса.
2. Аннотация
Этот hint указывает Hibernate, что данные только для чтения, что может ускорить выполнение.
🔍 Полезные Query Hints
Вот несколько полезных хинтов для Hibernate:
-
-
-
-
❗ Когда использовать?
✅ При сложных JOIN-запросах
✅ При работе с кешем
✅ Для больших выборок (fetchSize)
✅ Если запрос не изменяет данные (readOnly)
А вы используете Query Hints в своих проектах? Делись в комментариях! 👇
👉@BookJava
Сегодня я хочу поговорить о 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();
Здесь "org.hibernate.cacheable" позволяет кешировать результат запроса.
2. Аннотация
@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();
Этот hint указывает Hibernate, что данные только для чтения, что может ускорить выполнение.
🔍 Полезные Query Hints
Вот несколько полезных хинтов для Hibernate:
-
org.hibernate.cacheable = true
– разрешает кеширование результата.-
org.hibernate.fetchSize = N
– задаёт количество строк, загружаемых за раз.-
org.hibernate.readOnly = true
– отключает слежение за изменениями (ускоряет SELECT).-
org.hibernate.comment = 'My custom hint'
– добавляет комментарий к запросу.❗ Когда использовать?
✅ При сложных JOIN-запросах
✅ При работе с кешем
✅ Для больших выборок (fetchSize)
✅ Если запрос не изменяет данные (readOnly)
А вы используете Query Hints в своих проектах? Делись в комментариях! 👇
👉@BookJava
❤5👍4🤓2
Совет по Spring Boot💡
Ошибка конфигурации сервера Spring Boot ⬇
https://gist.github.com/aoudiamoncef/bba3f7c79f1056a22a3a82b3a171b5b3
👉@BookJava
Ошибка конфигурации сервера Spring Boot ⬇
https://gist.github.com/aoudiamoncef/bba3f7c79f1056a22a3a82b3a171b5b3
👉@BookJava
👍2👎1
📚 Greenplum, PostgreSQL и Airflow в одном открытом вебинаре.
Освойте ключевые инструменты работы с данными.
Встречаемся на открытом вебинаре 18 марта в 20:00 мск.
🔍 На уроке вы:
- Создадите инструмент для генерации данных в PostgreSQL
- Настроите хранение истории данных в ArenadataDB
- Напишете ETL-пайплайн для автоматической загрузки данных
После занятия вы сможете строить дата-пайплайны и автоматизировать загрузку данных, что существенно упростит вашу работу с данными.
🎓 Записывайтесь и получите скидку на большое обучение «Greenplum для разработчиков и архитекторов баз данных»: https://vk.cc/cJD2rT
Не упустите возможность прокачать свои навыки и освоить современные технологии! 🚀
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Освойте ключевые инструменты работы с данными.
Встречаемся на открытом вебинаре 18 марта в 20:00 мск.
🔍 На уроке вы:
- Создадите инструмент для генерации данных в PostgreSQL
- Настроите хранение истории данных в ArenadataDB
- Напишете ETL-пайплайн для автоматической загрузки данных
После занятия вы сможете строить дата-пайплайны и автоматизировать загрузку данных, что существенно упростит вашу работу с данными.
🎓 Записывайтесь и получите скидку на большое обучение «Greenplum для разработчиков и архитекторов баз данных»: https://vk.cc/cJD2rT
Не упустите возможность прокачать свои навыки и освоить современные технологии! 🚀
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
📝 Как улучшить читаемость кода в Java?
Сегодня поговорим о читаемости кода — важном аспекте, который отличает хорошего разработчика от посредственного. Если твой код понятен, его легче поддерживать, расширять и дебажить. Вот несколько проверенных приемов:
✅ Говорящие имена переменных и методов
Не используй
лучше:
✅ Меньше вложенности
Глубокая вложенность усложняет чтение. Вместо этого можно использовать guard clauses:
❌ Плохо:
✅ Хорошо:
✅ Разбивай код на небольшие методы
Методы должны делать только одну вещь и быть короткими (10-20 строк). Если метод раздувается, попробуй выделить логику в отдельные функции.
✅ Избавляйся от магических чисел
Если в коде встречаются числа типа
✅ Используй Optional и Collections.emptyList()
Чтобы избежать
✅ Форматируй код по стандарту
Используй Code Style в IDE или автоформатирование (
Какой из этих приемов ты уже используешь? Может, у тебя есть свои лайфхаки? Делись в комментариях! 🚀
👉@BookJava
Сегодня поговорим о читаемости кода — важном аспекте, который отличает хорошего разработчика от посредственного. Если твой код понятен, его легче поддерживать, расширять и дебажить. Вот несколько проверенных приемов:
✅ Говорящие имена переменных и методов
Не используй
x
, temp
, data
— дай переменным осмысленные названия. Например, вместо:
int d = 365;
лучше:
int daysInYear = 365;
✅ Меньше вложенности
Глубокая вложенность усложняет чтение. Вместо этого можно использовать guard clauses:
❌ Плохо:
if (user != null) {
if (user.isActive()) {
process(user);
}
}
✅ Хорошо:
if (user == null) return;
if (!user.isActive()) return;
process(user);
✅ Разбивай код на небольшие методы
Методы должны делать только одну вещь и быть короткими (10-20 строк). Если метод раздувается, попробуй выделить логику в отдельные функции.
✅ Избавляйся от магических чисел
Если в коде встречаются числа типа
3.14159
, 86400
— вынеси их в константы:
private static final int SECONDS_IN_A_DAY = 86400;
✅ Используй Optional и Collections.emptyList()
Чтобы избежать
NullPointerException
, возвращай Optional<T>
вместо null
и Collections.emptyList()
вместо пустых списков. ✅ Форматируй код по стандарту
Используй Code Style в IDE или автоформатирование (
Ctrl + Alt + L
в IntelliJ IDEA). Какой из этих приемов ты уже используешь? Может, у тебя есть свои лайфхаки? Делись в комментариях! 🚀
👉@BookJava
👍10❤2👎1
⚡️ Квиз на знание Java
Пройти тестирование — сложно! А ты справишься?
22 вопроса, 30 минут
Проверь себя - пройди квиз и оцени свой уровень навыков, а также свою готовность к обучению на курсе — «Java Developer. Advanced» от Отус.
👩💻 На курсе ты научишься профилировать приложения, настраивать GC, работать с реактивными подходами и мониторить метрики в Grafana. Пройдешь весь путь от JVM до Kubernetes, научишься анализировать «горячие точки», оптимизировать приложения и настраивать интеграции с Prometheus.
➡️ ПРОЙТИ ТЕСТ: https://vk.cc/cJDbVm
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Пройти тестирование — сложно! А ты справишься?
22 вопроса, 30 минут
Проверь себя - пройди квиз и оцени свой уровень навыков, а также свою готовность к обучению на курсе — «Java Developer. Advanced» от Отус.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
Доброе утро, коллеги!
Сегодня я хочу обсудить с вами одну из распространённых проблем, с которыми сталкиваются Java-разработчики, — "ад зависимостей".
Что такое "ад зависимостей"?
"Ад зависимостей" возникает, когда ваше приложение зависит от множества библиотек, каждая из которых, в свою очередь, имеет свои зависимости. Это может привести к следующим проблемам:
- Множество зависимостей: Приложение требует загрузки большого числа библиотек, что увеличивает время сборки и объём занимаемого дискового пространства.
- Длинные цепочки зависимостей: Одна библиотека зависит от другой, та — от третьей и так далее. Это усложняет управление и может привести к конфликтам версий.
- Конфликтующие зависимости: Разные библиотеки требуют разные версии одной и той же зависимости, что может привести к несовместимости и ошибкам при выполнении приложения.
Как избежать "ада зависимостей"?
1. Используйте системы управления зависимостями: Инструменты, такие как Maven или Gradle, помогают автоматически управлять зависимостями, разрешать конфликты версий и упрощают процесс сборки проекта.
2. Ограничивайте количество зависимостей: Перед добавлением новой библиотеки задумайтесь, действительно ли она необходима. Возможно, функциональность можно реализовать с помощью уже используемых инструментов или собственными силами.
3. Следите за версиями библиотек: Старайтесь использовать стабильные и проверенные версии зависимостей. Избегайте использования библиотек, которые давно не обновлялись или имеют известные проблемы совместимости.
4. Проводите регулярные ревизии зависимостей: Периодически проверяйте, какие библиотеки используются в проекте, и удаляйте неиспользуемые или устаревшие зависимости.
5. Изолируйте зависимости: Если возможно, используйте механизмы модульности (например, Java Modules) для изоляции зависимостей и предотвращения конфликтов между ними.
Заключение
Управление зависимостями — ключевой аспект разработки на Java. Грамотный подход к этому вопросу поможет избежать множества проблем и обеспечит стабильность и надёжность вашего приложения. Делитесь своим опытом и подходами к управлению зависимостями в комментариях!
👉@BookJava
Сегодня я хочу обсудить с вами одну из распространённых проблем, с которыми сталкиваются Java-разработчики, — "ад зависимостей".
Что такое "ад зависимостей"?
"Ад зависимостей" возникает, когда ваше приложение зависит от множества библиотек, каждая из которых, в свою очередь, имеет свои зависимости. Это может привести к следующим проблемам:
- Множество зависимостей: Приложение требует загрузки большого числа библиотек, что увеличивает время сборки и объём занимаемого дискового пространства.
- Длинные цепочки зависимостей: Одна библиотека зависит от другой, та — от третьей и так далее. Это усложняет управление и может привести к конфликтам версий.
- Конфликтующие зависимости: Разные библиотеки требуют разные версии одной и той же зависимости, что может привести к несовместимости и ошибкам при выполнении приложения.
Как избежать "ада зависимостей"?
1. Используйте системы управления зависимостями: Инструменты, такие как Maven или Gradle, помогают автоматически управлять зависимостями, разрешать конфликты версий и упрощают процесс сборки проекта.
2. Ограничивайте количество зависимостей: Перед добавлением новой библиотеки задумайтесь, действительно ли она необходима. Возможно, функциональность можно реализовать с помощью уже используемых инструментов или собственными силами.
3. Следите за версиями библиотек: Старайтесь использовать стабильные и проверенные версии зависимостей. Избегайте использования библиотек, которые давно не обновлялись или имеют известные проблемы совместимости.
4. Проводите регулярные ревизии зависимостей: Периодически проверяйте, какие библиотеки используются в проекте, и удаляйте неиспользуемые или устаревшие зависимости.
5. Изолируйте зависимости: Если возможно, используйте механизмы модульности (например, Java Modules) для изоляции зависимостей и предотвращения конфликтов между ними.
Заключение
Управление зависимостями — ключевой аспект разработки на Java. Грамотный подход к этому вопросу поможет избежать множества проблем и обеспечит стабильность и надёжность вашего приложения. Делитесь своим опытом и подходами к управлению зависимостями в комментариях!
👉@BookJava
👍5💩4
📌 Как правильно писать equals и hashCode в Java?
Сейчас разберем один из самых частых вопросов у Java-разработчиков: как правильно переопределять
Эти методы нужны для корректного сравнения объектов и работы коллекций (`HashMap`,
✅ Основные правила для
1️⃣ Рефлексивность –
2️⃣ Симметричность –
3️⃣ Транзитивность – если
4️⃣ Стабильность – если объекты не менялись, результат вызова
5️⃣ Не
Пример корректного
✅ Основные правила для
🔹 Если
🔹 Если
🔹
Пример
❌ Частые ошибки
🚫 Использование
🚫 Неопределенный
🚫 Изменяемые поля в
Используйте
📢 Как вы реализуете
👉@BookJava
Сейчас разберем один из самых частых вопросов у 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()
? Были ли у вас баги из-за их неправильной работы? Делитесь в комментариях! 👉@BookJava
👍8❤3
👩💻 Курс «Java-разработчик»: помощь в превращении стажёра в сильного Middle
🔥 Вы платите не только за знания, но и за эффективное карьерное сопровождение. Быстрее найдя работу, вы окупите затраты и начнёте уверенно расти в доходе.
💻 Наше обучение — это живые вебинары с действующими экспертами в области, которые проведут тебя от новичка до уверенного Middle-разработчика. Ты освоишь Spring, Hibernate, PostgreSQL, Docker, Kafka, Kubernetes и другие актуальные технологии!
✔️ Трехступенчатая поддержка до полного трудоустройства
- Мы сопровождаем студента не только в момент обучения и поиска работы, но и в период адаптации после выхода в новую компанию.
✔️ Индивидуальный подход на вебинарах и консультациях
- Мы не выдаем всем «один и тот же скрипт»: во время карьерных вебинаров отвечаем на конкретные вопросы студентов.
✔️ Профессиональное резюме под руководством HR-экспертов
- Подготовка резюме и разбор «точек роста». Эксперт помогает сформулировать сильные стороны, уникальные достижения и убрать «лишнее», чтобы резюме работало на конкретные вакансии.
✔️ Поддержка после оффера
- Даем рекомендации, как вести себя в первые месяцы, какие вопросы задавать руководителю, как справляться со стрессом и «синдромом самозванца». Это особенно важно, когда студент переходит из стажерской/джуниор роли в более серьезную позицию.
Наш партнер — СберКорус, разработчик передовых цифровых решений!
👉 Оставь заявку и получи скидку на курс: https://vk.cc/cJFwz6
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
- Мы сопровождаем студента не только в момент обучения и поиска работы, но и в период адаптации после выхода в новую компанию.
- Мы не выдаем всем «один и тот же скрипт»: во время карьерных вебинаров отвечаем на конкретные вопросы студентов.
- Подготовка резюме и разбор «точек роста». Эксперт помогает сформулировать сильные стороны, уникальные достижения и убрать «лишнее», чтобы резюме работало на конкретные вакансии.
- Даем рекомендации, как вести себя в первые месяцы, какие вопросы задавать руководителю, как справляться со стрессом и «синдромом самозванца». Это особенно важно, когда студент переходит из стажерской/джуниор роли в более серьезную позицию.
Наш партнер — СберКорус, разработчик передовых цифровых решений!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
Оптимизация SQL-запросов в Hibernate
Сегодня я хочу поделиться с вами одной из распространённых проблем в Hibernate — N+1 проблема. Если вы используете ORM без оптимизаций, то скорее всего сталкивались с этим.
📌 В чём суть?
Допустим, у нас есть две связанные сущности:
Теперь, если мы получим список авторов и для каждого загрузим книги:
Мы получаем 1 запрос для авторов + N запросов для книг. Это и есть N+1 проблема!
🚀 Как исправить?
Используем JOIN FETCH:
Теперь будет один SQL-запрос вместо кучи мелких.
🔥 Альтернативы:
• Entity Graph – даёт гибкость в загрузке связей.
• Batch Size в Hibernate – уменьшает количество запросов.
• DTO и кастомные запросы – загружаем только нужные данные.
Оптимизация SQL-запросов в ORM — ключ к быстродействию вашего приложения!
👉@BookJava
Сегодня я хочу поделиться с вами одной из распространённых проблем в 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
👍3
Подборка Telegram каналов для программистов
https://t.me/bash_srv Bash Советы
https://t.me/win_sysadmin Системный Администратор Windows
https://t.me/lifeproger Жизнь программиста. Авторский канал.
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
https://t.me/rabota1C_rus Вакансии для программистов 1С
Системное администрирование 📌
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/linux_odmin Linux: Системный администратор
https://t.me/devops_star DevOps Star (Звезда Девопса)
https://t.me/i_linux Системный администратор
https://t.me/linuxchmod Linux
https://t.me/sys_adminos Системный Администратор
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux
1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://t.me/DevLab1C 1С:Предприятие 8
Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://t.me/pythonofff Python академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus
Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://t.me/game_devv Все о разработке игр
Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
https://t.me/books_reserv Книги для программистов
БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию
https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика
https://t.me/itmozg Программисты, дизайнеры, новости из мира IT
https://t.me/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/tikon_1 Новости высоких технологий, науки и техники💡
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
https://t.me/bash_srv Bash Советы
https://t.me/win_sysadmin Системный Администратор Windows
https://t.me/lifeproger Жизнь программиста. Авторский канал.
https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin
https://t.me/rabota1C_rus Вакансии для программистов 1С
Системное администрирование 📌
https://t.me/sysadmin_girl Девочка Сисадмин
https://t.me/srv_admin_linux Админские угодья
https://t.me/linux_srv Типичный Сисадмин
https://t.me/linux_odmin Linux: Системный администратор
https://t.me/devops_star DevOps Star (Звезда Девопса)
https://t.me/i_linux Системный администратор
https://t.me/linuxchmod Linux
https://t.me/sys_adminos Системный Администратор
https://t.me/tipsysdmin Типичный Сисадмин (фото железа, было/стало)
https://t.me/sysadminof Книги для админов, полезные материалы
https://t.me/i_odmin Все для системного администратора
https://t.me/i_odmin_book Библиотека Системного Администратора
https://t.me/i_odmin_chat Чат системных администраторов
https://t.me/i_DevOps DevOps: Пишем о Docker, Kubernetes и др.
https://t.me/sysadminoff Новости Линукс Linux
1C разработка 📌
https://t.me/odin1C_rus Cтатьи, курсы, советы, шаблоны кода 1С
https://t.me/DevLab1C 1С:Предприятие 8
Программирование C++📌
https://t.me/cpp_lib Библиотека C/C++ разработчика
https://t.me/cpp_knigi Книги для программистов C/C++
https://t.me/cpp_geek Учим C/C++ на примерах
Программирование Python 📌
https://t.me/pythonofff Python академия. Учи Python быстро и легко🐍
https://t.me/BookPython Библиотека Python разработчика
https://t.me/python_real Python подборки на русском и английском
https://t.me/python_360 Книги по Python Rus
Java разработка 📌
https://t.me/BookJava Библиотека Java разработчика
https://t.me/java_360 Книги по Java Rus
https://t.me/java_geek Учим Java на примерах
GitHub Сообщество 📌
https://t.me/Githublib Интересное из GitHub
Базы данных (Data Base) 📌
https://t.me/database_info Все про базы данных
Мобильная разработка: iOS, Android 📌
https://t.me/developer_mobila Мобильная разработка
https://t.me/kotlin_lib Подборки полезного материала по Kotlin
Фронтенд разработка 📌
https://t.me/frontend_1 Подборки для frontend разработчиков
https://t.me/frontend_sovet Frontend советы, примеры и практика!
https://t.me/React_lib Подборки по React js и все что с ним связано
Разработка игр 📌
https://t.me/game_devv Все о разработке игр
Библиотеки 📌
https://t.me/book_for_dev Книги для программистов Rus
https://t.me/programmist_of Книги по программированию
https://t.me/proglb Библиотека программиста
https://t.me/bfbook Книги для программистов
https://t.me/books_reserv Книги для программистов
БигДата, машинное обучение 📌
https://t.me/bigdata_1 Data Science, Big Data, Machine Learning, Deep Learning
Программирование 📌
https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций
https://t.me/coddy_academy Полезные советы по программированию
https://t.me/rust_lib Полезный контент по программированию на Rust
https://t.me/golang_lib Библиотека Go (Golang) разработчика
https://t.me/itmozg Программисты, дизайнеры, новости из мира IT
https://t.me/php_lib Библиотека PHP программиста 👨🏼💻👩💻
https://t.me/nodejs_lib Подборки по Node js и все что с ним связано
https://t.me/ruby_lib Библиотека Ruby программиста
QA, тестирование 📌
https://t.me/testlab_qa Библиотека тестировщика
Шутки программистов 📌
https://t.me/itumor Шутки программистов
Защита, взлом, безопасность 📌
https://t.me/thehaking Канал о кибербезопасности
https://t.me/xakep_2 Хакер Free
Книги, статьи для дизайнеров 📌
https://t.me/ux_web Статьи, книги для дизайнеров
Математика 📌
https://t.me/Pomatematike Канал по математике
https://t.me/phis_mat Обучающие видео, книги по Физике и Математике
Excel лайфхак📌
https://t.me/Excel_lifehack
https://t.me/tikon_1 Новости высоких технологий, науки и техники💡
https://t.me/mir_teh Мир технологий (Technology World)
Вакансии 📌
https://t.me/sysadmin_rabota Системный Администратор
https://t.me/progjob Вакансии в IT
Telegram
Bash Советы
🚀 Секреты и советы по Bash
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
По всем вопросам @evgenycarter
🔹 Полезные трюки, хитрые однострочники и лайфхаки для работы в терминале.
🔹 Автоматизация, скрипты и оптимизация работы в Linux.
🔹 Стать мастером Bash легко – просто подпишись!
По всем вопросам @evgenycarter
🤮2
📌 Stream API: Группировка данных в Java
Привет, друзья! Сегодня разберем мощную возможность Stream API – группировка данных с помощью
📌 Как это работает?
Метод
📌 Разбор кода:
1. У нас есть список
2. Мы применяем
3. Результат –
4. Выводим результат, используя
📌 Выходные данные:
👉 Теперь представьте, что у вас есть заказы в интернет-магазине, и вам нужно сгруппировать их по статусу. Или у вас есть список сотрудников, и вы хотите разбить их по департаментам.
📌 Дополнительные фишки:
1. Подсчет количества элементов в группах:
2. Группировка + редукция: (например, получение списка имен)
👉@BookJava
Привет, друзья! Сегодня разберем мощную возможность 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)
);
}
}
📌 Разбор кода:
1. У нас есть список
people
с объектами Person
, у которых есть name
и city
. 2. Мы применяем
groupingBy
, передавая person -> person.city
в качестве критерия группировки. 3. Результат –
Map<String, List<Person>>
, где ключ – город, а значение – список людей из этого города. 4. Выводим результат, используя
forEach
.📌 Выходные данные:
Москва: [Иван, Сергей]
Санкт-Петербург: [Анна, Алексей]
Казань: [Мария]
👉 Теперь представьте, что у вас есть заказы в интернет-магазине, и вам нужно сгруппировать их по статусу. Или у вас есть список сотрудников, и вы хотите разбить их по департаментам.
groupingBy()
– это универсальный инструмент, который решает такие задачи.📌 Дополнительные фишки:
1. Подсчет количества элементов в группах:
Map<String, Long> countByCity = people.stream()
.collect(Collectors.groupingBy(p -> p.city, Collectors.counting()));
2. Группировка + редукция: (например, получение списка имен)
Map<String, Set<String>> namesByCity = people.stream()
.collect(Collectors.groupingBy(p -> p.city,
Collectors.mapping(p -> p.name, Collectors.toSet())));
👉@BookJava
👍6
🚀 Совет по Spring API 🚀
LocaleContextHolder
Стратегия для хранения текущей локали потокобезопасным способом. Полезно для получения текущей локали без необходимости передавать её явно через параметры методов. 🔥
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/i18n/LocaleContextHolder.html
👉@BookJava
LocaleContextHolder
Стратегия для хранения текущей локали потокобезопасным способом. Полезно для получения текущей локали без необходимости передавать её явно через параметры методов. 🔥
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/i18n/LocaleContextHolder.html
👉@BookJava
docs.spring.io
LocaleContextHolder (Spring Framework 6.2.7 API)
declaration: package: org.springframework.context.i18n, class: LocaleContextHolder
👍3
👩💻 Создание приложения Блокнот на Java 👩💻
🗓 24 марта в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».
На вебинаре мы разработаем полноценное приложение «Блокнот» с графическим пользовательским интерфейсом, демонстрирующее базовые принципы создания текстового редактора на Java.
В процессе занятия мы реализуем такие функциональные возможности, как:
- создание нового текстового файла, его сохранение,
- загрузка уже существующего файла,
- редактирование текста, подсчет статистических данных и другие операции, характерные для текстовых редакторов.
Особое внимание будет уделено работе с файловой системой, потоками ввода/вывода и обработке событий, что позволит создать удобное и интуитивно понятное приложение.
Спикер Александр Фисунов — Senior Kotlin Developer в SSP Software на проекте ВТБ, опытный Java-разработчик и кандидат технических наук.
🔗 Ссылка на регистрацию: https://vk.cc/cJP0NY
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🗓 24 марта в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java-разработчик».
На вебинаре мы разработаем полноценное приложение «Блокнот» с графическим пользовательским интерфейсом, демонстрирующее базовые принципы создания текстового редактора на Java.
В процессе занятия мы реализуем такие функциональные возможности, как:
- создание нового текстового файла, его сохранение,
- загрузка уже существующего файла,
- редактирование текста, подсчет статистических данных и другие операции, характерные для текстовых редакторов.
Особое внимание будет уделено работе с файловой системой, потоками ввода/вывода и обработке событий, что позволит создать удобное и интуитивно понятное приложение.
Спикер Александр Фисунов — Senior Kotlin Developer в SSP Software на проекте ВТБ, опытный Java-разработчик и кандидат технических наук.
🔗 Ссылка на регистрацию: https://vk.cc/cJP0NY
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🛠️ SOLID: Почему важно соблюдать принципы?
Сегодня поговорим о SOLID – пяти принципах, которые делают код понятным, гибким и легким для поддержки. Если ты хочешь писать код, который не треснет по швам через пару месяцев, эти принципы — твои лучшие друзья.
1. Single Responsibility Principle (SRP)
Одна ответственность – один класс.
Если у класса больше одной причины измениться, значит, он нарушает SRP. Такой код сложно поддерживать, потому что при изменении одной логики мы можем случайно сломать другую.
✅ Правильно:
❌ Неправильно (всё в одном месте):
2. Open/Closed Principle (OCP)
Код открыт для расширения, но закрыт для модификации.
Когда нам нужно добавить новую функциональность, мы должны расширять существующий код, а не менять его.
✅ Пример с интерфейсом:
Теперь мы можем добавить новый способ оплаты, просто создав новый класс.
3. Liskov Substitution Principle (LSP)
Дочерние классы должны полностью заменять родительские.
Если где-то используется родительский класс, мы должны без проблем подставить его потомка.
❌ Нарушение LSP:
Проблема в том, что
✅ Используем интерфейсы:
4. Interface Segregation Principle (ISP)
Лучше несколько маленьких интерфейсов, чем один большой.
❌ Плохой пример:
✅ Разделяем интерфейсы:
5. Dependency Inversion Principle (DIP)
Модули верхнего уровня не должны зависеть от модулей нижнего уровня.
Оба должны зависеть от абстракций.
❌ Жёсткая зависимость:
✅ Используем абстракции:
📌 Итог
Принципы SOLID помогают писать гибкий, поддерживаемый и расширяемый код. Если следовать этим принципам, код будет легче читать и рефакторить.
Используешь ли ты SOLID в своих проектах? Напиши в комментариях, какой принцип для тебя самый сложный!
👉 @BookJava
Сегодня поговорим о SOLID – пяти принципах, которые делают код понятным, гибким и легким для поддержки. Если ты хочешь писать код, который не треснет по швам через пару месяцев, эти принципы — твои лучшие друзья.
1. Single Responsibility Principle (SRP)
Одна ответственность – один класс.
Если у класса больше одной причины измениться, значит, он нарушает SRP. Такой код сложно поддерживать, потому что при изменении одной логики мы можем случайно сломать другую.
✅ Правильно:
class ReportGenerator {
void generateReport() { /* Логика генерации отчета */ }
}
class ReportSaver {
void saveReport() { /* Логика сохранения отчета */ }
}
❌ Неправильно (всё в одном месте):
class ReportService {
void generateAndSaveReport() { /* Генерация + сохранение отчета */ }
}
2. Open/Closed Principle (OCP)
Код открыт для расширения, но закрыт для модификации.
Когда нам нужно добавить новую функциональность, мы должны расширять существующий код, а не менять его.
✅ Пример с интерфейсом:
interface Payment {
void process();
}
class CreditCardPayment implements Payment {
public void process() { /* Логика оплаты картой */ }
}
class PayPalPayment implements Payment {
public void process() { /* Логика оплаты PayPal */ }
}
Теперь мы можем добавить новый способ оплаты, просто создав новый класс.
3. Liskov Substitution Principle (LSP)
Дочерние классы должны полностью заменять родительские.
Если где-то используется родительский класс, мы должны без проблем подставить его потомка.
❌ Нарушение LSP:
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()
}
4. Interface Segregation Principle (ISP)
Лучше несколько маленьких интерфейсов, чем один большой.
❌ Плохой пример:
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() { /* Работает */ }
}
5. Dependency Inversion Principle (DIP)
Модули верхнего уровня не должны зависеть от модулей нижнего уровня.
Оба должны зависеть от абстракций.
❌ Жёсткая зависимость:
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(); }
}
📌 Итог
Принципы SOLID помогают писать гибкий, поддерживаемый и расширяемый код. Если следовать этим принципам, код будет легче читать и рефакторить.
Используешь ли ты SOLID в своих проектах? Напиши в комментариях, какой принцип для тебя самый сложный!
👉 @BookJava
👍12