Библиотека Java разработчика
10.3K subscribers
1.05K photos
595 videos
58 files
1.45K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Download Telegram
🚀 Подборка полезных IT каналов в Max


Системное администрирование, DevOps 📌

https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.
https://max.ru/tipsysdmin Типичный Сисадмин

1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С

Программирование C++📌
https://max.ru/cpp_lib Библиотека C/C++ разработчика

Программирование Go📌
https://max.ru/golang_lib Библиотека Go (Golang) разработчика

Программирование React📌
https://max.ru/react_lib React

Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика

Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика

GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub

Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных

Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков

Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов

Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻

Шутки программистов 📌
https://max.ru/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free

Книги, статьи для дизайнеров 📌
https://max.ru/odesigners Статьи, книги для дизайнеров

Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике

Вакансии 📌
https://max.ru/progjob Вакансии в IT

Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных


Бонус 📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
🤮3🖕2👍1
📝 Советы по оптимизации Java кода: избавляемся от лишнего

Привет, друзья! Сегодня поговорим об оптимизации кода. Все мы знаем, что код должен быть не только работоспособным, но и читаемым, эффективным и поддерживаемым. Давайте разберем несколько типичных ошибок и способов их устранения.

🚀 1. Избегайте ненужного создания объектов
Частая ошибка — создавать объекты там, где можно использовать уже существующие.

Плохо:

String str = new String("Hello"); // Избыточно

Хорошо:

String str = "Hello"; // Используем строковый пул

То же самое касается Integer.valueOf() вместо new Integer().

🔄 2. Используйте StringBuilder вместо конкатенации в цикле
Если вы объединяете строки в цикле, StringBuilder будет значительно быстрее.

Плохо:

String result = "";
for (int i = 0; i < 100; i++) {
result += i; // Создает новый объект String на каждой итерации
}

Хорошо:

StringBuilder result = new StringBuilder();
for (int i = 0; i < 100; i++) {
result.append(i);
}

Такой код работает в разы быстрее!

🏎 3. Правильно выбирайте коллекции
Используйте ArrayList, если не нужна частая вставка/удаление элементов в середине списка.
Используйте HashSet, если важны уникальные значения и не нужен порядок.
Используйте LinkedList, если нужна частая вставка/удаление в середине списка.

4. Не злоупотребляйте Stream API
Да, Stream API удобен, но иногда он замедляет код. Например:

Плохо:

List<Integer> numbers = List.of(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, Integer::sum);

Хорошо:

int sum = 0;
for (int num : numbers) {
sum += num;
}

Цикл быстрее, потому что не тратит время на создание объектов и лямбды.

🔥 Вывод
Оптимизация — это не просто ускорение кода, но и улучшение его читаемости и поддержки. Используйте правильные структуры данных, избегайте лишних аллокаций, выбирайте оптимальные конструкции.

А какие советы по оптимизации Java кода используете вы? Пишите в комментариях! 👇 🚀

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🔥1
📝 Разбираем @Transactional в Spring: Где Подводные Камни?

Давайте обсудимм одну из самых популярных аннотаций в Spring — @Transactional. Многие знают, что она используется для управления транзакциями, но не все понимают, как она работает под капотом и какие проблемы могут возникнуть. Давайте разбираться!

🔍 Как работает @Transactional?
Когда вы помечаете метод @Transactional, Spring проксирует этот метод и оборачивает его в транзакцию. Это значит, что до начала метода открывается транзакция, а после — либо коммитится (если нет ошибок), либо откатывается (если есть исключение).

Но тут важно помнить:
🔹 @Transactional работает только на public методах (если используется Spring AOP).
🔹 Вызовы методов внутри одного класса не учитывают @Transactional. Если вызвать метод, аннотированный @Transactional, внутри другого метода того же класса, транзакция не создастся.
🔹 По умолчанию, транзакция откатывается только при RuntimeException. Если бросить checked-исключение, Spring не откатит транзакцию.

⚠️ Распространённые ошибки
Аннотация на private методе
Транзакция просто не будет работать, так как Spring AOP не перехватит вызов.

Вызов @Transactional метода внутри того же класса
Транзакция не создастся, так как вызов происходит без участия Spring Proxy. Решение — выносить такие методы в отдельный бин или использовать TransactionTemplate.

Неправильный rollback
Если в методе выбрасывается checked-исключение, Spring по умолчанию **не откатывает** транзакцию. Чтобы изменить это поведение, нужно явно указать `@Transactional(rollbackFor = Exception.class).

Как избежать проблем?
✔️ Всегда ставьте @Transactional на публичные методы.
✔️ Вызывайте @Transactional-методы только через Spring-управляемые бины.
✔️ Контролируйте rollback через rollbackFor.
✔️ Используйте propagation = REQUIRES_NEW, если хотите создать новую независимую транзакцию.

Кто сталкивался с неожиданным поведением @Transactional? Давайте обсудим в комментариях!

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
🚀 Параметры JVM: Какие ключевые стоит знать?

Сегодня я покажу вам самые важные параметры JVM, которые помогут вам оптимизировать работу вашего Java-приложения. Эти флаги влияют на производительность, управление памятью и отладку.

🔥 Управление памятью:
- -Xms<size> – задает начальный размер кучи.
- -Xmx<size> – задает максимальный размер кучи.
- -XX:NewRatio=<n> – определяет соотношение между молодым и старым поколением.
- -XX:SurvivorRatio=<n> – соотношение между Eden и Survivor.

Гаражная сборка (GC):
- -XX:+UseG1GC – включает G1 Garbage Collector (по умолчанию в Java 9+).
- -XX:+UseParallelGC – включает Parallel GC.
- -XX:+UseZGC – включает экспериментальный ZGC (минимальная пауза).
- -XX:+UseShenandoahGC – еще один GC с низкими задержками.

🛠️ Диагностика и отладка:
- -XX:+PrintGCDetails – подробный вывод информации о сборке мусора.
- -XX:+HeapDumpOnOutOfMemoryError – дамп памяти при OOM.
- -XX:HeapDumpPath=<path> – указывает путь для дампа памяти.
- -XX:+ExitOnOutOfMemoryError – завершает JVM при OOM.

🏎️ Оптимизация JIT:
- -XX:+TieredCompilation – адаптивная компиляция кода.
- -XX:+UseStringDeduplication – уменьшает использование памяти строками.
- -XX:+AlwaysPreTouch – аллокация памяти заранее (полезно для больших heap'ов).

Попробуйте поэкспериментировать с этими параметрами и посмотрите, как они влияют на производительность вашего приложения!

Какие параметры JVM используете вы? Пишите в комментариях!

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🧵 Разбираемся с CompletableFuture в Java

Сегодня я хочу рассказать вам про CompletableFuture — мощный инструмент для работы с асинхронными операциями в Java. Если вам приходилось ждать выполнения долгих задач в коде и хотелось бы улучшить производительность, то этот пост для вас! 🚀

🔹 Что такое CompletableFuture?
CompletableFuture — это часть java.util.concurrent с Java 8, которая позволяет выполнять асинхронные задачи и удобно комбинировать их. В отличие от обычного Future, CompletableFuture поддерживает цепочки вызовов, композицию задач и обработку ошибок.

🔹 Пример использования
Допустим, у нас есть сервис, который загружает данные по сети. Обычный подход синхронного вызова будет блокировать поток, но с CompletableFuture мы можем избежать этого:


import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture.supplyAsync(() -> {
System.out.println("Загружаем данные...");
sleep(2000);
return "Данные загружены";
}).thenApply(data -> {
System.out.println("Обрабатываем: " + data);
return data.toUpperCase();
}).thenAccept(System.out::println)
.exceptionally(ex -> {
System.out.println("Ошибка: " + ex.getMessage());
return null;
});

sleep(3000); // Даем время асинхронной операции завершиться
}

private static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}


🔹 Разбор кода
1️⃣ supplyAsync() — запускает асинхронную задачу в отдельном потоке.
2️⃣ thenApply() — позволяет обработать результат (например, изменить его формат).
3️⃣ thenAccept() — принимает готовый результат и выполняет действие.
4️⃣ exceptionally() — обрабатывает возможные ошибки.

🔹 Зачем это нужно?
Улучшает производительность за счет асинхронного выполнения.
Избегает блокировки основного потока.
Позволяет легко комбинировать операции.

Используете ли вы CompletableFuture в своих проектах? Делитесь опытом в комментариях! 👇

📲 Мы в MAX

👉@BookJava
👍21
🚀 Используем Optional правильно в Java

Сегодня разберем Optional – мощный инструмент, который помогает избежать NullPointerException. Но многие используют его неправильно! Давайте посмотрим, как его применять эффективно.

Как делать НЕ надо:

Optional<String> optional = Optional.ofNullable(getValue());
if (optional.isPresent()) {
System.out.println(optional.get());
}

Почему плохо?
- get() без проверки – потенциальная ловушка.
- Лишний if – можно сделать проще.

Как надо:

Optional.ofNullable(getValue()).ifPresent(System.out::println);

или, если нужно значение по умолчанию:

String value = Optional.ofNullable(getValue()).orElse("Default Value");

Крутые приемы с Optional:
orElseGet – лениво вычисляет значение
orElseThrow – выбрасывает исключение, если Optional пуст
map и flatMap – позволяют трансформировать данные

🔥 Советы:
1️⃣ Не используйте Optional для полей классов – это не сериализуемо.
2️⃣ Не передавайте Optional в аргументах методов – это антипаттерн.
3️⃣ Optional хорош для возвращаемых значений – используйте его вместо null.

Как вы используете Optional в своих проектах? Делитесь в комментариях!

📲 Мы в MAX

👉@BookJava
👍3🤔1
Используем Lombok правильно: Разбираемся с @Slf4j

Сегодня я расскажу вам о @Slf4j из библиотеки Lombok и о том, как его правильно использовать, чтобы ваш код стал чище и удобнее.

Что такое @Slf4j?
Это аннотация, которая добавляет в ваш класс статическое поле логгера org.slf4j.Logger. Вместо того чтобы писать:


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyService {
private static final Logger log = LoggerFactory.getLogger(MyService.class);
}


Достаточно одной аннотации:


import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MyService {
}


Теперь в коде можно просто писать:


log.info("Приложение запущено");
log.error("Произошла ошибка: {}", exception.getMessage());


На что обратить внимание?
1️⃣ @Slf4j использует SLF4J API, поэтому вам все равно потребуется подключить реализацию логирования, например Logback:


<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>


2️⃣ Если нужен другой логгер, можно использовать альтернативные аннотации:
- @Log — для java.util.logging
- @Log4j — для Apache Log4j
- @Log4j2 — для Log4j2

3️⃣ Не забывайте про уровень логирования!
Используйте debug для отладки, info для полезных сообщений, warn для предупреждений и error для ошибок.

Вывод: @Slf4j — это удобный инструмент, который избавляет от лишнего кода и упрощает работу с логированием. Если вы еще не используете Lombok для логирования, самое время попробовать!

📲 Мы в MAX

👉@BookJava
3👍1
🔥 Почему Optional в Java – не просто контейнер!

Сегодня разберём важную тему: Optional в Java – это не просто удобный способ избежать null, но и мощный инструмент для работы с потоками данных.

🚀 Как правильно использовать Optional?

1️⃣ Избегаем null-чеков
Раньше код был полон if (obj != null), но теперь:

Optional<String> name = Optional.ofNullable(user.getName());
name.ifPresent(System.out::println);

Это делает код чище и понятнее.

2️⃣ Комбинируем с map() и flatMap()
Если у нас есть объект, внутри которого другой объект, а внутри него – ещё один, Optional поможет избежать вложенных if-else:

Optional<String> city = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity);

Всё элегантно и лаконично!

3️⃣ Используем orElse() и orElseGet() правильно
Антипаттерн – всегда выполняет new Object():

User user = optionalUser.orElse(new User());

Лучше такorElseGet() вызовется только если optionalUser пуст:

User user = optionalUser.orElseGet(User::new);

Это особенно важно, если объект тяжёлый в создании.

4️⃣ orElseThrow() – избавляемся от null вообще
Когда отсутствие значения – это ошибка, не бойтесь выбрасывать исключение:

User user = optionalUser.orElseThrow(() -> new RuntimeException("User not found"));

Это делает код безопаснее!

Когда не стоит использовать Optional?
- В полях сущностей (например, JPA) – это может ухудшить производительность.
- Для коллекций – лучше возвращать пустую коллекцию, а не Optional<List<T>>.

📲 Мы в MAX

👉@BookJava
👍2
🏆 5 ЗОЛОТЫХ ПРАВИЛ ЧИСТОГО КОДА В JAVA

1️⃣ Понятные названия
Используйте осмысленные имена для переменных, методов и классов. Название должно отвечать на вопрос "Что делает этот код?" без необходимости заглядывать внутрь.
int a = 5;
int maxRetries = 5;

2️⃣ Короткие методы
Огромные методы с кучей логики сложно читать и поддерживать. Разбивайте их на мелкие, понятные части. Хороший метод делает только одну вещь и делает её хорошо.

3️⃣ Минимум вложенности
Чем больше if-else и циклов внутри друг друга — тем сложнее понимать код. Используйте ранний выход (return, continue, break), чтобы уменьшить вложенность.

4️⃣ Избегайте магических чисел
Никогда не вставляйте числа или строки прямо в код. Заводите константы.
if (status == 3) {...}
if (status == ORDER_COMPLETED) {...}

5️⃣ Отказ от комментариев в пользу читаемого кода
Комментарий не должен объяснять что делает код — это обязанность самого кода! Если без комментариев неясно, что происходит, значит, нужно переписать код.

👉 Какое из этих правил вы чаще всего нарушаете? Или, может, у вас есть своё золотое правило чистого кода? Пишите в комментариях!

📲 Мы в MAX

👉@BookJava
📌 Spring Boot: Как использовать @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;
}
}



📲 Мы в MAX

👉@BookJava
👍31
🔥 Stream API: Фильтрация, Преобразование и Сортировка 🔥

Сегодня я покажу вам, как эффективно работать с 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 в своих проектах? Делитесь в комментариях! 🚀

📲 Мы в MAX

👉@BookJava
👍3🔥1
🚀 Подборка полезных IT каналов в Max


Системное администрирование, DevOps 📌

https://max.ru/i_odmin Все для системного администратора
https://max.ru/bash_srv Bash Советы
https://max.ru/sysadminof Книги для админов, полезные материалы
https://max.ru/i_odmin_book Библиотека Системного Администратора
https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др.
https://max.ru/tipsysdmin Типичный Сисадмин

Excel лайфхак 📌
https://t.me/Excel_lifehack Excel лайфхак

1C разработка 📌
https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С

Программирование C++📌
https://max.ru/cpp_lib Библиотека C/C++ разработчика

Программирование Go📌
https://max.ru/golang_lib Библиотека Go (Golang) разработчика

Программирование React📌
https://max.ru/react_lib React

Программирование Python 📌
https://max.ru/python_of Python академия.
https://max.ru/BookPython Библиотека Python разработчика

Java разработка 📌
https://max.ru/bookjava Библиотека Java разработчика

GitHub Сообщество 📌
https://max.ru/githublib Интересное из GitHub

Базы данных (Data Base) 📌
https://max.ru/database_info Все про базы данных

Фронтенд разработка 📌
https://max.ru/frontend_1 Подборки для frontend разработчиков

Библиотеки 📌
https://max.ru/programmist_of Книги по программированию
https://max.ru/proglb Библиотека программиста
https://max.ru/bfbook Книги для программистов

Программирование 📌
https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций
https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT
https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻

Шутки программистов 📌
https://max.ru/itumor Шутки программистов

Защита, взлом, безопасность 📌
https://max.ru/thehaking Канал о кибербезопасности
https://max.ru/xakkep_1 Хакер Free

Книги, статьи для дизайнеров 📌
https://max.ru/odesigners Статьи, книги для дизайнеров

Математика 📌
https://max.ru/Pomatematike Канал по математике
https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике

Вакансии 📌
https://max.ru/progjob Вакансии в IT

Мир технологий 📌
https://max.ru/mir_teh Канал для любознательных


Бонус 📌
https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга
https://max.ru/mockva_life Свежие новости Москвы
https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП
👎2🤮2💩1
🚀 Оптимизация 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();

Здесь "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 в своих проектах? Делись в комментариях! 👇

📲 Мы в MAX

👉@BookJava
👍3
📝 Как улучшить читаемость кода в Java?

Сегодня поговорим о читаемости кода — важном аспекте, который отличает хорошего разработчика от посредственного. Если твой код понятен, его легче поддерживать, расширять и дебажить. Вот несколько проверенных приемов:

Говорящие имена переменных и методов
Не используй 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).

Какой из этих приемов ты уже используешь? Может, у тебя есть свои лайфхаки? Делись в комментариях! 🚀

📲 Мы в MAX

👉@BookJava
👍51
📌 Как правильно писать 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️⃣ Не nullx.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()? Были ли у вас баги из-за их неправильной работы? Делитесь в комментариях!

📲 Мы в MAX

👉@BookJava
👍2❤‍🔥1
🔥 Приглашаем на бесплатный открытый вебинар курса «Высоконагруженные системы: архитектура и масштабирование»:

«Polyglot Persistence: как современные системы живут с десятками баз данных»

🗓 Когда: 2 июня, 20:00 (мск)

Одной базы данных уже давно недостаточно. Современные высоконагруженные системы — это сложная экосистема из разных хранилищ, каждое из которых решает свою задачу.

На вебинаре разберём, как грамотно сочетать PostgreSQL, ClickHouse, Redis, Kafka и Elasticsearch, чтобы система оставалась быстрой, согласованной и отказоустойчивой.

Что будет на вебинаре:
— Принципы Polyglot Persistence и роль каждой базы в современной архитектуре
— Как связать PostgreSQL, ClickHouse, Redis и Kafka без потери согласованности данных
— Event-driven подход, CDC и Outbox-паттерн в высоконагруженных системах
— Архитектурные приёмы построения надёжных data-платформ, способных выдерживать миллионы операций

Кому будет полезно:
— Backend-разработчикам, желающим понимать устройство современных систем
— Архитекторам и DevOps-инженерам, решающим задачи масштабирования и согласованности
— Всем, кто работает с большими данными и хочет эффективно комбинировать разные типы хранилищ

👉 Зарегистрироваться: https://vk.cc/cYcSEc

Бесплатное занятие приурочено к курсу «Highload Architect», на котором вы научитесь проектировать сложные высоконагруженные системы, грамотно выбирать и сочетать технологии хранения и обработки данных.

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
👏5🎉31👍1🔥1
Java springboot
Совет: Нужно быстро собрать разрозненные данные в POST-запросе?

Просто создайте встроенную record в вашем
@RestController и используйте её как @RequestBody.

Не нужно определять DTO в отдельном классе – record будет видна только внутри этого контроллера. 🚀

📲 Мы в MAX

👉@BookJava
👍63🎉3🔥2👏1