en
Feedback
Библиотека Java разработчика

Библиотека Java разработчика

Open in Telegram

📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP

Show more

📈 Analytical overview of Telegram channel Библиотека Java разработчика

Channel Библиотека Java разработчика (@bookjava) in the Russian language segment is an active participant. Currently, the community unites 10 123 subscribers, ranking 11 760 in the Technologies & Applications category and 63 248 in the Russia region.

📊 Audience metrics and dynamics

Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 10 123 subscribers.

According to the latest data from 25 August, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by -74 over the last 30 days and by -6 over the last 24 hours, overall reach remains high.

  • Verification status: Not verified
  • Engagement rate (ER): The average audience engagement rate is 7.20%. Within the first 24 hours after publication, content typically collects 3.71% reactions from the total number of subscribers.
  • Post reach: On average, each post receives 729 views. Within the first day, a publication typically gains 376 views.
  • Reactions and interaction: The audience actively supports content: the average number of reactions per post is 5.
  • Thematic interests: Content is focused on key topics such as string, интерфейс, строка, boot, api.

📝 Description and content policy

The author describes the resource as a platform for expressing subjective opinions:
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP

Thanks to the high frequency of updates (latest data received on 26 August, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.

10 123
Subscribers
-624 hours
-137 days
-7430 days
Posts Archive
🧠 Spring Boot: правильно логируем @ExceptionHandler Сейчас покажу простой, но часто упускаемый момент при обработке ошибок в
🧠 Spring Boot: правильно логируем @ExceptionHandler Сейчас покажу простой, но часто упускаемый момент при обработке ошибок в Spring Boot. Если у вас есть глобальный @ExceptionHandler, убедитесь, что вы не теряете stacktrace при логировании. ❌ Плохо:

@ExceptionHandler(MyException.class)
public ResponseEntity<String> handle(MyException ex) {
    log.error("MyException occurred: {}", ex.getMessage()); // stacktrace теряется!
    return ResponseEntity.status(500).body("Error");
}
Хорошо:

@ExceptionHandler(MyException.class)
public ResponseEntity<String> handle(MyException ex) {
    log.error("MyException occurred", ex); // stacktrace будет видно в логе
    return ResponseEntity.status(500).body("Error");
}
📌 log.error(String, Throwable) — правильный способ логировать исключения. Это позволяет: * Сохранять stacktrace для дебага; * Не терять вложенные причины (getCause()); * Работать с лог-агрегаторами (ELK, Grafana, etc). 💡 Если вы используете Slf4j и формат log.error("message: {}", ex.getMessage()), вы теряете почти всю полезную информацию об ошибке. ⚠️ И не забывайте: глобальные хендлеры — это хорошо, но не глушите все ошибки без разбора. Лучше создавать разные @ExceptionHandler под каждую категорию исключений. 📲 Мы в MAX 👉@BookJava

🧠 Spring Boot: как НЕ попасть в ловушку с @Scheduled и многопоточностью Когда используете @Scheduled для периодических задач
🧠 Spring Boot: как НЕ попасть в ловушку с @Scheduled и многопоточностью Когда используете @Scheduled для периодических задач в Spring Boot, важно понимать: по умолчанию все задачи выполняются в одном потоке.

@Scheduled(fixedRate = 5000)
public void syncData() {
    // долгая операция
}
📌 Если таких задач несколько или они работают долго — остальные ждут. Это создаёт бутылочное горлышко и приводит к неожиданным задержкам. 💡 Решение: настроить кастомный executor:

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar registrar) {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5); // количество параллельных задач
        scheduler.setThreadNamePrefix("scheduled-task-");
        scheduler.initialize();
        registrar.setTaskScheduler(scheduler);
    }
}
Теперь все @Scheduled - методы будут использовать пул потоков, а не один. ⚠️ Не забывайте: если задача критична к ресурсам или зависит от внешних сервисов — добавьте внутреннюю защиту от повторного выполнения, например, с помощью Redis lock или базы. ✅ Подключение пула — must-have для production-проектов, где @Scheduled выполняет реальные задачи, а не просто println. 📲 Мы в MAX 👉@BookJava

🚀 Подборка полезных 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 Типичный Сисадмин https://max.ru/channel_win_sysadmin Системный Администратор Windows https://max.ru/channel_linux_admin Linux: Системный администратор https://max.ru/channel_linuxmod Linux https://max.ru/channel_i_linux Системный администратор https://max.ru/channel_devopslib DevOps, SRE, Sysadmin https://max.ru/channel_devops_star DevOps Star (Звезда Девопса) Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак Английский с нуля 🇬🇧 https://max.ru/UchuEnglish 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С https://max.ru/channel_DevLab1C 1С:Предприятие 8 Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика https://max.ru/channel_cpp_geek C++ geek Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Rust📌 https://max.ru/channel_rust_lib Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика https://max.ru/channel_java_geek Java Geek 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 Обучающие видео, книги по Физике и Математике Вакансии в IT📌 https://max.ru/progjob https://max.ru/channel_rabotait Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Городские📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП https://max.ru/channel_krasnodar_novosty Краснодар Новости https://max.ru/channel_novosibirsk_novosti Новосибирск https://max.ru/channel_samara_novosti Новости Самары https://max.ru/channel_ekaterinburg_novosti Новости Екатеринбурга https://max.ru/channel_kazan_novosti Новости Казани https://max.ru/channel_omsk_novosti Новости Омска https://max.ru/channel_moskva_24 Москва 24

💡 Не делай этого в @PostConstruct — особенно в проде Сейчас расскажу, почему инициализировать важную бизнес-логику в @PostCo
💡 Не делай этого в @PostConstruct — особенно в проде Сейчас расскажу, почему инициализировать важную бизнес-логику в @PostConstruct — плохая идея. Типичный пример:

@Component
public class CacheLoader {

    private final SomeService service;

    public CacheLoader(SomeService service) {
        this.service = service;
    }

    @PostConstruct
    public void init() {
        service.loadDataIntoCache(); // ⚠️ обращение к БД
    }
}
🧨 Проблема: @PostConstruct вызывается до того, как приложение полностью поднялось. Если внутри будет ошибка (например, БД недоступна) — приложение может упасть, или что хуже — запуститься в полурабочем состоянии. 📌 Кроме того: * ❌ Нет контроля над порядком выполнения таких методов; * ❌ Нельзя легко переиспользовать эту логику (например, вручную перезагрузить кеш); * ❌ В тестах или dev-среде — такие вызовы часто мешают. ✅ Современный подход — использовать ApplicationListener:

@Component
public class CacheLoader implements ApplicationListener<ApplicationReadyEvent> {

    private final SomeService service;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        service.loadDataIntoCache(); // 👍 вызывается только после старта
    }
}
📌 Альтернатива — аннотация @EventListener:

@EventListener(ApplicationReadyEvent.class)
public void onReady() {
    // безопасно загружаем данные
}
📦 В Spring Boot это нативный и рекомендованный способ выполнения кода после старта. 🧠 Резюме: 🔹 @PostConstruct — только для простой инициализации бинов. 🔹 Бизнес-логику и I/O — в @EventListener(ApplicationReadyEvent.class). 📲 Мы в MAX 👉@BookJava

🧠 JVM-разработчики, стягиваемся в Москву 29 августа В последнюю субботу лета бэкенд- и JVM-комьюнити соберется на JVM Day, к
🧠 JVM-разработчики, стягиваемся в Москву 29 августа В последнюю субботу лета бэкенд- и JVM-комьюнити соберется на JVM Day, который устраивает Т-Банк. Ждут всех разработчиков, архитекторов и тимлидов, которые работают с Java, Kotlin и Scala. В программе: – Андрей Кулешов расскажет о том, что изменилось в мире JVM за год. – Сергей Петрелевич разберет Mechanical Sympathy. – Александр Ланцов покажет, какие модели конкурентности актуальны после появления Loom. – Антон Курако объяснит, почему красивые показатели бенчмарков могут вводить в заблуждение. А после докладов во дворе штаб-квартиры Т-Банка пройдут: – Игры на Sega и ИТ-Квиз. – PowerPoint Party и открытый микрофон с историями ошибок. – Диджей-сет на виниле под открытым небом. Места ограничены, регистрироваться тут. Пишите в комментариях, если идете на конфу. 📲 Мы в MAX 👉@BookJava

🧠 @Value в Spring — это ловушка, если вы используете списки или map'ы Многие знают, что можно заинжектить список строк из application.yml вот так:

app:
  langs:
    - en
    - fr
    - de

@Value("${app.langs}")
private List<String> langs;
Но знаете, что вы получите? ⚠️ ОШИБКУ. @Value не умеет парсить YAML-массивы. Он ожидает строку, и даже с CSV-строкой (en,fr,de) — всё не так очевидно: Spring не применяет ConversionService для списков. 📌 Решение — использовать @ConfigurationProperties:

app:
  langs:
    - en
    - fr
    - de

@ConfigurationProperties(prefix = "app")
@Component
public class AppProps {
    private List<String> langs;
    // геттеры/сеттеры
}
💡 Профит: - работает с List, Map, вложенными объектами; - валидация через @Validated и @NotEmpty; - легко покрыть тестами; - меньше магии. ⚠️ @Value хорош для простых скаляров. Всё остальное — через @ConfigurationProperties. 📲 Мы в MAX 👉@BookJava

👩‍💻 Работа с Kafka через библиотеку Kafka Clients Приглашаем на открытый урок. 🗓 26 августа в 20:00 МСК 🆓 Бесплатно. Урок
👩‍💻 Работа с Kafka через библиотеку Kafka Clients Приглашаем на открытый урок. 🗓 26 августа в 20:00 МСК 🆓 Бесплатно. Урок в рамках старта курса «Java разработчик. Продвинутый уровень». Kafka Clients это нижний уровень для работы с Kafka из Java. Все более высокоуровневые библиотеки основаны на нем. Данный открытый урок проходит в рамках курса Java разработчик. Продвинутый уровень. О чем поговорим: ✔️ Чтение и отправка сообщений в Kafka ✔️ Управление топиками ✔️ Разные форматы: текст, JSON, Avro ✔️ Использование транзакций 🔗 Ссылка на регистрацию: https://vk.cc/d0zMZ5 Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

🧠 Нюанс с Optional.map() и методами, возвращающими Optional Многие Java-разработчики на автомате пишут что-то вроде: Optiona
🧠 Нюанс с Optional.map() и методами, возвращающими Optional Многие Java-разработчики на автомате пишут что-то вроде:

Optional<User> user = findUserById(id); // возвращает Optional<User>

Optional<String> email = user.map(User::getEmail); // getEmail тоже возвращает Optional<String>
⚠️ Проблема: map() в Optional не "разворачивает" вложенные Optional. В этом примере email будет типа Optional<Optional<String>>, что почти всегда нежелательно. 📌 Правильный способ — использовать flatMap():

Optional<String> email = user.flatMap(User::getEmail);
💡 flatMap() позволяет избежать "двойной обёртки", если метод внутри map() уже возвращает Optional. 🔁 Аналогичная ситуация с Stream.map() — если внутри map() вызывается метод, возвращающий Stream, то получится Stream<Stream<T>>, и опять же нужно использовать flatMap(). 🧪 Мини-памятка: * map() — когда метод возвращает обычный тип (T → R); * flatMap() — когда метод возвращает Optional или Stream (T → Optional<R> или T → Stream<R>). 📲 Мы в MAX 👉@BookJava

Почему ты получаешь отказ после "норм собеса"? Дело не в знаниях - ты просто не знаешь, что реально проверяют на собеседовани
Почему ты получаешь отказ после "норм собеса"? Дело не в знаниях - ты просто не знаешь, что реально проверяют на собеседованиях Отсюда:  — непонимание, какие навыки надо качать, чтобы выйти на следующий грейд  — ощущение стагнации и отсутствие роста в скиллах  — долгое время на одной и той же зп Решение — знать, что от тебя ждёт интервьюер, и умение правильно донести свою мысль Для этого ребята из ШОРТКАТ (менторской программы для разработчиков) собрали в один файл ОТВЕТЫ НА 50 СЛОЖНЫХ ВОПРОСОВ с Java-собеседований 🔥 Они проанализировали более 100 мок-интервью и собрали внутри реальные вопросы + ответы сильного кандидата Забрать можно бесплатно (!) в боте — @shortcut_sh_bot Переходите по ссылке выше и забирайте файл, чтобы быстрее выйти на новый уровень ☝️ Реклама. О рекламодателе.

+7
Java. Сортировки Java. Сортировка пузырьком. Java. О сортировке выбором. Java. Быстрая сортировка. Объяснение на пальцах) Java. Оценка сложности алгоритмов сортировки. Java. Сортировка слиянием. Java. Сортировка подсчетом. Java. Сортировка вставками. Java. Сортировка расческой. От пузырька до расчески. 📲 Мы в MAX 👉@BookJava

🧠 Как в Java сломать equals() и потерять данные в HashMap Сегодня покажу, как неочевидный баг в equals()/hashCode() может пр
🧠 Как в Java сломать equals() и потерять данные в HashMap Сегодня покажу, как неочевидный баг в equals()/hashCode() может привести к потере данных при работе с HashMap. Допустим, у вас есть Entity:

public class User {
    private String id;
    private String name;

    // equals/hashCode только по id
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return Objects.equals(id, user.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
Вроде норм. Но теперь добавим такого юзера в HashMap, а потом... изменим его id:

User user = new User();
user.setId("1");
user.setName("Alice");

Map<User, String> map = new HashMap<>();
map.put(user, "value");

user.setId("2"); // ⚠️ ключ стал "невидимым"

System.out.println(map.get(user)); // null 😱
📌 Почему так происходит? HashMap ищет ключ по hashCode() → ищет бакет → сравнивает через equals(). А hashCode() уже другой, и объект "теряется". 💡 Совет: если вы используете объект как ключ в мапе или добавляете его в Set, не изменяйте его поля, участвующие в equals()/hashCode()! 📌 А как правильно? - Делайте такие поля final; - Или используйте неизменяемые типы (record); - Или не используйте такие объекты как ключи вовсе. Вот безопасный вариант с record:

public record User(String id, String name) {}
📲 Мы в MAX 👉@BookJava

💡Сегодня покажу крутую фишку для оптимизации чтения больших коллекций из базы через JPA. 📌 Проблема: Когда загружаем большу
💡Сегодня покажу крутую фишку для оптимизации чтения больших коллекций из базы через JPA. 📌 Проблема: Когда загружаем большую коллекцию через @OneToMany, Hibernate часто делает это лениво (LAZY), но при первом доступе — забирает всю коллекцию целиком. Это может привести к OutOfMemoryError или резкому проседанию производительности. 📌 Решение: использовать пагинацию (batch-size) или запрос коллекции порциями. Как настроить batch-size на уровне сущности:

@Entity
public class User {
    
    @OneToMany(mappedBy = "user", fetch = FetchType.LAZY)
    @BatchSize(size = 50)
    private List<Order> orders;
}
🧠 Теперь Hibernate будет загружать за раз по 50 элементов, а не всю коллекцию сразу! 📌 Или можно настроить глобально через application.properties:

spring.jpa.properties.hibernate.default_batch_fetch_size=50
⚠️ Важно: - @BatchSize работает только для LAZY-связей. - Это не пагинация в SQL, а оптимизация внутренних запросов Hibernate. - Если коллекция огромная (100k+ записей) — лучше делать явные paged запросы в репозитории. 💡Помните: без настройки batch-size Hibernate может сломать приложение под нагрузкой. Оптимизируйте загрузку коллекций заранее! 📲 Мы в MAX 👉@BookJava

Как работают instance initializer blocks. Пример с родительским и дочерним классами:

class Parent {
    int a = 5;

    {
        System.out.println("Parent instance initializer");
        a = 10;
    }

    Parent() {
        System.out.println("Parent constructor, a = " + a);
    }
}

class Child extends Parent {
    int b = 15;

    {
        System.out.println("Child instance initializer");
        b = 25;
    }

    Child() {
        System.out.println("Child constructor, b = " + b);
    }
}

public class Test {
    public static void main(String[] args) {
        Child child = new Child();
    }
}
Вывод программы:
Parent instance initializer
Parent constructor, a = 10
Child instance initializer
Child constructor, b = 25
Пошаговое выполнение: 1. Сначала загружается родительский класс Parent. 2. Выполняется: - Инициализация полей родителя (a = 5), - Потом instance initializer блока родителя (a = 10), - Потом конструктор родителя (Parent()). 3. Далее переходим к дочернему классу Child: - Инициализация полей дочернего класса (b = 15), - Потом instance initializer блока дочернего класса (b = 25), - Потом конструктор дочернего класса (Child()). Важный порядок действий: 1. Инициализация родителя → 2. Конструктор родителя → 3. Инициализация потомка → 4. Конструктор потомка. Блоки инициализации всегда выполняются до тела конструктора, но после вызова super(). 📲 Мы в MAX 👉@BookJava

🚀 Подборка полезных 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 Типичный Сисадмин https://max.ru/channel_win_sysadmin Системный Администратор Windows https://max.ru/channel_linux_admin Linux: Системный администратор https://max.ru/channel_linuxmod Linux https://max.ru/channel_i_linux Системный администратор https://max.ru/channel_devopslib DevOps, SRE, Sysadmin https://max.ru/channel_devops_star DevOps Star (Звезда Девопса) Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак Английский с нуля 🇬🇧 https://max.ru/UchuEnglish 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С https://max.ru/channel_DevLab1C 1С:Предприятие 8 Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика https://max.ru/channel_cpp_geek C++ geek Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Rust📌 https://max.ru/channel_rust_lib Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика https://max.ru/channel_java_geek Java Geek 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 Обучающие видео, книги по Физике и Математике Вакансии в IT📌 https://max.ru/progjob https://max.ru/channel_rabotait Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Городские📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП https://max.ru/channel_krasnodar_novosty Краснодар Новости https://max.ru/channel_novosibirsk_novosti Новосибирск https://max.ru/channel_samara_novosti Новости Самары https://max.ru/channel_ekaterinburg_novosti Новости Екатеринбурга https://max.ru/channel_kazan_novosti Новости Казани https://max.ru/channel_omsk_novosti Новости Омска https://max.ru/channel_moskva_24 Москва 24

В Java instance initializer blocks (блоки инициализации экземпляра) выполняются в следующем порядке: - Они выполняются каждый раз, когда создается новый объект класса. - Выполнение происходит после вызова конструктора родительского класса (super()), но до тела конструктора текущего класса. Порядок инициализации: 1. Сначала инициализируются поля в порядке их объявления. 2. Затем выполняются instance initializer blocks, в том порядке, в котором они написаны в коде. 3. После этого выполняется тело конструктора. Пример:

class Example {
    int x = 10;

    {
        System.out.println("Instance initializer block");
        x = 20;
    }

    Example() {
        System.out.println("Constructor");
        System.out.println("x = " + x);
    }

    public static void main(String[] args) {
        Example ex = new Example();
    }
}
Вывод:
Instance initializer block
Constructor
x = 20
Ключевые моменты: - Статические блоки (static {}) — другое дело: они выполняются один раз при загрузке класса. - Instance initializer blocks полезны для общей инициализации, которую нужно выполнять вне зависимости от того, какой конструктор вызывается. 📲 Мы в MAX 👉@BookJava

🔴 Завтра тестовое собеседование с Java-разработчиком 5 августа(уже завтра!) в 19:00 по мск приходи онлайн на открытое собесе
🔴 Завтра тестовое собеседование с Java-разработчиком 5 августа(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика. Как это будет: 📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Сергею Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot Реклама. О рекламодателе.

🧠 Сегодня покажу вам полезный трюк для Spring Boot: как элегантно валидировать параметры контроллера без лишнего кода. Часто
🧠 Сегодня покажу вам полезный трюк для Spring Boot: как элегантно валидировать параметры контроллера без лишнего кода. Часто вижу, как в контроллерах вручную проверяют @RequestParam на пустоту или формат. Это шумит код и приводит к ошибкам. Вместо этого используйте аннотации валидации прямо на параметрах:

@RestController
@RequestMapping("/api")
@Validated // Обязательно!
public class UserController {

    @GetMapping("/users")
    public List<User> getUsers(
            @RequestParam @NotBlank String name,
            @RequestParam @Min(18) int age
    ) {
        // Если валидация не пройдена — автоматически вернётся 400 Bad Request
        return userService.findUsers(name, age);
    }
}
📌 Ключевые моменты: - Обязательно ставим @Validated над классом контроллера. - На параметры добавляем любые стандартные аннотации из jakarta.validation.constraints. - Ошибки валидации Spring обработает автоматически через MethodArgumentNotValidException. 💡 Можно кастомизировать ответ на ошибку, добавив глобальный @ExceptionHandler. ⚠️ Без @Validated аннотации на контроллере валидация параметров работать не будет! 📲 Мы в MAX 👉@BookJava

🧠 JPA: подводный камень с @ElementCollection и fetch = FetchType.EAGER Сегодня покажу, почему @ElementCollection(fetch = Fet
🧠 JPA: подводный камень с @ElementCollection и fetch = FetchType.EAGER Сегодня покажу, почему @ElementCollection(fetch = FetchType.EAGER) — скрытая угроза производительности и неожиданного поведения. 📌 Суть проблемы При использовании @ElementCollection с EAGER Hibernate делает отдельный SELECT на каждую коллекцию, даже при JOIN FETCH на родительскую сущность.

@Entity
class User {
    @Id Long id;

    @ElementCollection(fetch = FetchType.EAGER)
    List<String> tags;
}
Запрос findAll() приведёт к N+1 проблеме: 1 запрос на User, потом по одному на каждый tags. 💡 Почему это больно Даже если вы используете JOIN FETCH на User, Hibernate не может сделать JOIN на @ElementCollection. Это ограничение — Hibernate всегда грузит коллекцию отдельным запросом. ⚠️ Особенно опасно при pagination Если вы делаете Page<User> — Hibernate сначала грузит User'ов, а затем делает N запросов на коллекции. В проде это быстро становится проблемой. ✅ Что делать 1. Делайте fetch = FetchType.LAZY (по умолчанию так и есть). 2. Если нужно подгрузить коллекцию — используйте @BatchSize:

@ElementCollection
@BatchSize(size = 20)
List<String> tags;
Или вручную:

SELECT u FROM User u LEFT JOIN FETCH u.tags WHERE u.id IN :ids
👉 Следи за @ElementCollection — он не так прост, как кажется. 📲 Мы в MAX 👉@BookJava

🧠 Как избежать N+1 при использовании @OneToMany в JPA Одна из самых коварных ловушек JPA - это N+1 проблема. Особенно часто она проявляется при @OneToMany, например:

@Entity
class Author {
    @OneToMany(mappedBy = "author", fetch = FetchType.LAZY)
    private List<Book> books;
}
Вы загружаете список авторов, а потом проходите по каждому и вызываете getBooks() — и BAM 💥: 1 запрос на авторов и N запросов на книги. 📌 Решение - @EntityGraph или JOIN FETCH Оба варианта решают проблему, но @EntityGraph — декларативный и более гибкий способ:

@EntityGraph(attributePaths = "books")
List<Author> findAll(); // Spring Data JPA
⚡️ Или через JPQL:

@Query("SELECT a FROM Author a JOIN FETCH a.books")
List<Author> findAllWithBooks();
💡 Совет: всегда думайте о графе объектов. Если вам нужно сразу подтянуть связанные сущности — делайте это явно. Не надейтесь на LAZY по умолчанию. ⚠️ Осторожно с пагинацией и JOIN FETCH — могут появиться дубликаты или проблемы с LIMIT. В таких случаях лучше использовать @BatchSize или подзапросы. 📲 Мы в MAX 👉@BookJava

Чем отличаются checked и unchecked исключения в java? В Java исключения делятся на два основных типа: checked и unchecked. Разница между ними ключевая и касается как обработки, так и структуры кода. ✅ Checked Exceptions (Проверяемые исключения) Примеры: IOException, SQLException, FileNotFoundException Отличия: 1. Проверяются компилятором — вы обязаны либо обработать их с помощью try-catch, либо явно пробросить (throws) в сигнатуре метода. 2. Производные от Exception, но не от RuntimeException. 3. Используются для ситуаций, которые можно разумно ожидать и обработать (например, отсутствие файла, проблемы с сетью). Пример:

public void readFile(String path) throws IOException {
    FileReader reader = new FileReader(path);  // может выбросить IOException
}
Unchecked Exceptions (Непроверяемые исключения) Примеры: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException Отличия: 1. Не проверяются компилятором — вы не обязаны их обрабатывать или декларировать. 2. Производные от RuntimeException. 3. Возникают в результате ошибок в логике программы или непредвиденных ситуаций. Пример:

public void printLength(String str) {
    System.out.println(str.length());  // может выбросить NullPointerException
}
Если кратко: Checked — ошибки среды, требующие явной обработки. Unchecked — ошибки в логике, ответственность программиста. 📲 Мы в MAX 👉@BookJava