Java Books
Java Библиотека По всем вопросам- @notxxx1 @ai_machinelearning_big_data - machine learning @pythonl - Python @itchannels_telegram - 🔥 best it channels @ArtificialIntelligencedl - AI @pythonlbooks-📚 @programming_books_it -it 📚 № 5032728887
Больше📈 Аналитический обзор Telegram-канала Java Books
Канал Java Books (@java_library) является активным участником. Сейчас сообщество объединяет 14 244 подписчиков, занимая 9 078 место в категории Технологии и приложения и 46 675 место в регионе Россия.
📊 Показатели аудитории и динамика
С момента создания невідомо проект демонстрирует стремительный рост, собрав аудиторию из 14 244 подписчиков.
Согласно последним данным от 23 июня, 2026, канал показывает стабильную активность. За последние 30 дней изменение числа участников составило -24, а за последние 24 часа — -5, при этом общий охват остаётся высоким.
- Статус верификации: Не верифицирован
- Уровень вовлечённости (ER): Средний показатель вовлечённости аудитории составляет 7.12%. В первые 24 часа после публикации контент обычно набирает 4.33% реакций от общего числа подписчиков.
- Охват публикаций: В среднем каждый пост получает 1 014 просмотров. В течение первых суток публикация набирает 617 просмотров.
- Реакции и взаимодействия: Аудитория активно поддерживает контент: среднее количество реакций на один пост — 11.
- Тематические интересы: Контент сосредоточен на ключевых темах, таких как docker, собеседование, sql, boot, string.
📝 Описание и контентная политика
Автор описывает ресурс как площадку для выражения субъективного мнения:
“Java Библиотека
По всем вопросам- @notxxx1
@ai_machinelearning_big_data - machine learning
@pythonl - Python
@itchannels_telegram - 🔥 best it channels
@ArtificialIntelligencedl - AI
@pythonlbooks-📚
@programming_books_it -it 📚
№ 503272888...”
Благодаря высокой частоте обновлений (последние данные получены 24 июня, 2026) канал поддерживает актуальность и высокий уровень охвата публикаций. Аналитика показывает, что аудитория активно взаимодействует с контентом, что делает его важной точкой влияния в категории Технологии и приложения.
BufferedReader, InputStream, OutputStream, FileReader, соединениями или другими ресурсами, которые нужно закрывать, используйте try-with-resources.
Плохо:
BufferedReader reader = new BufferedReader(new FileReader("data.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
На первый взгляд всё нормально.
Но если внутри чтения файла вылетит исключение, reader.close() может не выполниться. В итоге останутся открытые file handles, stream’ы или соединения.
Лучше так:
try (BufferedReader reader =
new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
try-with-resources автоматически вызовет close() даже при исключении.
Почему это важно:
* не нужен ручной finally
* меньше boilerplate-кода
* ниже риск утечек ресурсов
* код проще читать
* безопаснее работать с файлами, сетью и БД
Правило простое:
если объект реализует AutoCloseable или Closeable, почти всегда стоит использовать try-with-resources.
Это одна из тех привычек, которые делают Java-код чище и надёжнее.86400, 7, 1.21 или 5000, компилятору всё равно. Человеку - нет. Через месяц уже приходится вспоминать, что это было: секунд в дне, дней сессии, НДС или задержка перед повторной попыткой.
Плохой вариант выглядит так:
if (sessionAgeSeconds > 86400 * 7)
Формально код работает. Но смысл спрятан внутри чисел.
Нормальный вариант:
SECONDS_PER_DAY
SESSION_DAYS
VAT_RATE
RETRY_DELAY_MS
Теперь намерение видно прямо в месте вызова. Не нужно угадывать, почему именно 7, что означает 5000 и можно ли безопасно поменять значение.
Это особенно важно в бизнес-логике, где числа редко бывают случайными. Лимиты, комиссии, таймауты, скидки, сроки жизни сессии, количество попыток - всё это правила продукта, а не просто цифры в коде.
Хорошее правило простое: если число несёт смысл, дай ему имя. Исключения вроде 0, 1, индексов и простых счётчиков можно не трогать.
Чистый код часто начинается не с архитектуры, а с таких скучных вещей: убрать загадочные числа и оставить будущему разработчику понятный контекст.
#java #cleancodeorderRepository.findAll()
А потом в цикле обращаетесь к order.getItems().
Hibernate сначала делает один запрос за заказами, а потом ещё по одному запросу на каждый заказ, чтобы достать items.
100 заказов = 101 SQL-запрос.
И вот здесь спасает @EntityGraph.
Он позволяет явно сказать репозиторию, какие связи нужно подтянуть сразу:
@EntityGraph(attributePaths = {"items"})
В итоге Hibernate может сгенерировать один запрос с JOIN, вместо десятков лишних походов в базу.
Что получаем:
- меньше SQL-запросов
- меньше нагрузки на БД
- чище код репозитория
- без ручного JPQL
- fetch-стратегия управляется точечно под конкретный кейс
LAZY сам по себе не зло. Зло - когда вы не контролируете, где и как он срабатывает.
@EntityGraph - один из самых простых способов держать N+1 под контролем в Spring Boot.try/catch.
Для этого есть @RestControllerAdvice.
Идея простая: вы выносите обработку исключений в один глобальный класс, а контроллеры оставляете чистыми.
Например:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> handleNotFound(ResourceNotFoundException ex) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse("NOT_FOUND", ex.getMessage()));
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<?> handleBadRequest(IllegalArgumentException ex) {
return ResponseEntity
.badRequest()
.body(new ErrorResponse("BAD_REQUEST", ex.getMessage()));
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleGeneric(Exception ex) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("INTERNAL_ERROR", "Something went wrong"));
}
}
После этого контроллер может выглядеть спокойно:
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
Если пользователь не найден - сервис кидает ResourceNotFoundException, а Spring сам отправит нормальный 404.
Что это даёт:
• меньше мусора в контроллерах
• единый формат ошибок
• проще поддерживать API
• легче логировать исключения
• меньше копипасты в endpoint-ах
Контроллер должен описывать сценарий запроса, а не превращаться в свалку обработки ошибок.orderRepository.findAll()
А потом в цикле обращаетесь к order.getItems().
Hibernate сначала делает один запрос за заказами, а потом ещё по одному запросу на каждый заказ, чтобы достать items.
100 заказов = 101 SQL-запрос.
И вот здесь спасает @EntityGraph.
Он позволяет явно сказать репозиторию, какие связи нужно подтянуть сразу:
@EntityGraph(attributePaths = {"items"})
В итоге Hibernate может сгенерировать один запрос с JOIN, вместо десятков лишних походов в базу.
Что получаем:
- меньше SQL-запросов
- меньше нагрузки на БД
- чище код репозитория
- без ручного JPQL
- fetch-стратегия управляется точечно под конкретный кейс
LAZY сам по себе не зло. Зло - когда вы не контролируете, где и как он срабатывает.
@EntityGraph - один из самых простых способов держать N+1 под контролем в Spring Boot.
`@Scheduled(fixedRate = 5000)`
Лучше вынести значение в конфиг:
`@Scheduled(fixedRateString = "${task.interval}")`
А в application.properties указать:
`task.interval=5000`
Почему так лучше:
• интервал можно менять без правки кода;
• настройки проще различать для dev, staging и production;
• меньше магических чисел в бизнес-логике;
• конфигурация становится прозрачнее.
Мелочь, но именно из таких мелочей и складывается нормальная поддерживаемость Spring Boot-проекта.WebMvcConfigurer: указать маршруты, разрешенные origins, HTTP-методы, заголовки и работу с credentials.
Главное - не ставить бездумно * везде подряд, особенно если используете cookies, токены или allowCredentials(true). В проде лучше явно перечислять доверенные домены, например frontend-домен приложения.
Такой подход дает централизованный контроль: вы один раз задаете политику CORS и не размазываете настройки по каждому контроллеру.
Для Java backend-разработчика это базовая, но важная вещь: CORS должен быть частью архитектуры API, а не случайной правкой перед деплоем.Ownership, traits, generics, async, unsafe - всё, что казалось магией, станет рабочим инструментом.
А бонусом - портфолио проектов: от CLI-утилит до REST API и WebAssembly.
Вы и так знаете, что Rust - ваш следующий язык. Этот курс просто сделает это реальностью.
Сегодня - 55% процентов от цены, торопись: https://stepik.org/a/269250/createUser(firstName, lastName, email, phone, address, city, country)
Это уже сигнал, что модель данных развалилась.
Проблема не только в читаемости.
Такие методы сложнее поддерживать, расширять и тестировать. Любое изменение ломает сигнатуру и тянет за собой каскад правок.
Нормальный вариант - собрать связанные данные в объект:
UserInfo userInfo
Получаем:
- чище API
- проще добавлять поля
- меньше ошибок при передаче параметров
- код начинает отражать доменную модель, а не список строк
Это базовый приём, но именно на нём чаще всего экономят, а потом платят сложностью.
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserDTO {
private String name;
private int age;
}
Теперь Jackson просто игнорирует лишние поля вместо того, чтобы ломать приложение.
Полезно, когда API живёт долго, клиенты обновляются быстрее бэка, а ломать совместимость нельзя.
Уже доступно! Исследование Telegram 2025 — ключевые инсайты года 
