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

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

Відкрити в Telegram

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

Показати більше

📈 Аналітичний огляд Telegram-каналу Библиотека Java разработчика

Канал Библиотека Java разработчика (@bookjava) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 10 115 підписників, посідаючи 11 697 місце в категорії Технології та додатки та 62 901 місце у регіоні Росія.

📊 Показники аудиторії та динаміка

З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 10 115 підписників.

За останніми даними від 27 серпня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на -73, а за останні 24 години на -3, загальне охоплення залишається високим.

  • Статус верифікації: Не верифікований
  • Рівень залученості (ER): Середній показник залученості аудиторії становить 7.20%. Протягом перших 24 годин після публікації контент зазвичай збирає 3.71% реакцій від загальної кількості підписників.
  • Охоплення публікацій: В середньому кожен допис отримує 729 переглядів. Протягом першої доби публікація в середньому набирає 375 переглядів.
  • Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 7.
  • Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як string, интерфейс, строка, boot, api.

📝 Опис та контентна політика

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

Завдяки високій частоті оновлень (останні дані отримано 28 серпня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.

10 115
Підписники
-324 години
-167 днів
-7330 день
Архів дописів
🔍Тестовое собеседование с Java-разработчиком из Т1 Иннотех уже завтра 4 июня(уже завтра!) в 19:00 по мск приходи онлайн на о
🔍Тестовое собеседование с Java-разработчиком из Т1 Иннотех уже завтра 4 июня(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика. Как это будет: 📂 Илья Аров, старший разработчик в Т1, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Илья будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Илье Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqvL6bDw

🧠 Конфигурация Spring Boot 3 через record и @ConstructorBinding Вместо традиционных @Data + пустого конструктора можно сразу использовать Java 17 record для настройки свойств: 📌 Почему это полезно? 🔴Полная иммутабельность: поля конфигов больше нельзя случайно перезаписать. 🔴Минимум «шаблонного» кода: не нужны геттеры, сеттеры, toString(), equals() и т.д. 🔴Чёткая связь с Java 17+ и актуальными best practices. 💡 Как сделать: 1. Подключаем зависимость:

   <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-configuration-processor</artifactId>
     <optional>true</optional>
   </dependency>
   
Это нужно, чтобы IDE и Spring метаинфу подхватили. 2. Создаём record с аннотацией:

   import org.springframework.boot.context.properties.ConfigurationProperties;
   import org.springframework.boot.context.properties.ConstructorBinding;

   @ConstructorBinding
   @ConfigurationProperties(prefix = "app.mail")
   public record MailProperties(
       String host,
       int port,
       String username,
       String password
   ) {}
   
3. Регистрируем бин в Spring:

   import org.springframework.boot.context.properties.EnableConfigurationProperties;
   import org.springframework.context.annotation.Configuration;

   @Configuration
   @EnableConfigurationProperties(MailProperties.class)
   public class AppConfig { }
   
4. Конфигурируем в application.yml (или .properties):

   app:
     mail:
       host: smtp.example.com
       port: 587
       username: user@example.com
       password: secret123
   
⚠️ Обратите внимание: 🔴Без @ConstructorBinding Spring не сможет смотать значения в record’ы. 🔴Уберите все сеттеры и по умолчанию конструктор генерируется автоматически. 🔴Если вам нужна валидация свойств, добавьте @Validated и JSR-303 аннотации (@NotNull, @Min и т.д.). 🧠 Что получилось? 🔴Минимум «мусора» в коде: один блок record заменил класс с 4 полями, геттерами и конструктором. 🔴Полная типобезопасность и поддержка автокомплита при обращении к полям. 🔴Быстрый переход на Java 17+ подходы без потери функциональности. 💡 Дополнительный лайфхак: Если вам нужно разделить конфиги по окружениям (dev/prod), просто создайте два record’а с разными префиксами или используйте @Profile. В Spring Boot 3 этот подход «из коробки» работает наилучшим образом. 👉@BookJava

Релиз через два дня. Код готов. Почти... Остались тесты. Ну, точнее — покрытие. Потому что QA уже дышит в затылок, а ты сидиш
Релиз через два дня. Код готов. Почти... Остались тесты. Ну, точнее — покрытие. Потому что QA уже дышит в затылок, а ты сидишь и выбираешь: спать или корпеть до утра. Explyt Test умеет создавать тесты под твой код — сам. Быстро. В IDE. Без плясок. Хочешь, чтобы релиз прошёл, а не пролетел? Попробуй бесплатно! 👉 explyt.ai

В асинхронных или веб-сервисах на реактиве нужно быть осторожным: SecurityContext не “переходит” автоматически в новые потоки. Для этого используют SecurityContextRepository и специальные методы в WebFlux. ⚠️ Важно: не храните SecurityContext в сессии, если у вас stateless-приложение (REST API). Вместо сессии используйте JWT или OAuth 2.0. 🧠 5. Авторизация: FilterSecurityInterceptor & AccessDecisionManager FilterSecurityInterceptor запускается в конце цепочки фильтров и проверяет доступ к URL. Он запрашивает у SecurityMetadataSource список необходимых ролей для данного эндпоинта (Spring на основании @PreAuthorize, HttpSecurity конфигурации или XML). Затем передаёт дело в AccessDecisionManager (по умолчанию AffirmativeBased), который опрашивает список AccessDecisionVoter (например, RoleVoter для проверок ролей, WebExpressionVoter для SpEL).

FilterSecurityInterceptor
   └─> SecurityMetadataSource (что нужно: ROLE_ADMIN)
   └─> AccessDecisionManager.vote() 
       ├─ RoleVoter.vote() → совпадает?
       └─ WebExpressionVoter.vote() → SpEL-выражения?
Если хотя бы один голос “grant”, AffirmativeBased отпускает запрос (по умолчанию). Можно менять стратегию на Consensus или Unanimous. 💡 Трюк: чтобы локально протестировать SecurityContext, можно в тестах использовать аннотацию @WithMockUser(roles = "ADMIN") и проверять, что нужный эндпоинт доступен. 🧠 6. Аннотации & Method Security Помимо URL-уровня, есть методная проверка:

@EnableMethodSecurity // (Spring Boot 3+) вместо @EnableGlobalMethodSecurity
public class SecurityConfig { ... }

// Где-то в сервисе:
@PreAuthorize("hasRole('ADMIN') and #id == principal.id")
public void deleteUser(Long id) { ... }
* 📌 @PreAuthorize / @PostAuthorize / @Secured / @RolesAllowed — все используют тот же механизм Voter’ов, но проверяют уже на методах сервиса. * 💡 Совет: включайте методную безопасность только там, где действительно нужна тонкая грануляция. 🧠 7. Хранение паролей & PasswordEncoder С Java 17+ используйте PasswordEncoder с алгоритмами Argon2 или BCrypt:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder(12);
}
⚠️ Никогда не храните пароли в открытом виде и не используйте MD5/SHA-1 — они считаются небезопасными. 🧠 8. Stateless vs Stateful * Stateful (Сессии): Spring создаёт HTTP-сессию, а SecurityContextPersistenceFilter хранит контекст в сессии. Удобно для монолитов с классическим web-приложением. * Stateless (JWT/OAuth2): убираем SessionCreationPolicy.STATELESS, используем BearerTokenAuthenticationFilter, аутентификация и авторизация проверяются по JWT в каждом запросе. 💡 Современный стек (Spring Boot 3+): 1. Настраиваем SecurityFilterChain с oauth2ResourceServer().jwt(). 2. Подключаем spring-boot-starter-oauth2-resource-server. 3. Указываем issuer-uri или jwk-set-uri в application.yml.

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://keycloak.example.com/realms/myrealm
🧠 9. Подпись запросов & CSRF * По умолчанию CSRF включён для “форменных” запросов (POST, PUT, DELETE). Для stateless-API его обычно отключают:

  http.csrf().disable();
  
* Если используете формы, не забудьте добавить в шаблон:

  <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
  
⚠️ Внимание: не отключайте CSRF, если ваше приложение использует сессии и cookie на фронтенде! 💡 Совет по отладке: включите логирование фильтров:

logging.level.org.springframework.security=DEBUG
Тогда в логах вы увидите, как проходит запрос через каждый фильтр и где происходит отказ. 👉@BookJava

📌 Spring Security: основная архитектура 🧠 1. SecurityFilterChain & FilterChainProxy Spring Security строит всё вокруг цепочки фильтров (FilterChainProxy). При запросе к приложению запрос проходит через набор фильтров, каждый из которых отвечает за свой кусок логики: * ⚙️ ChannelProcessingFilter – перенаправление на HTTPS, если нужно. * ⚙️ SecurityContextPersistenceFilter – загружает/сохраняет SecurityContext (где хранится Authentication). * ⚙️ UsernamePasswordAuthenticationFilter – обрабатывает форму логина (если вы используете formLogin). * ⚙️ BasicAuthenticationFilter – поддерживает HTTP Basic (для REST). * ⚙️ BearerTokenAuthenticationFilter (Spring Boot 3+) – для JWT/OAuth2 Bearer-токенов. * ⚙️ ExceptionTranslationFilter – перехватывает AccessDeniedException и AuthenticationException, перенаправляет на страницу логина или возвращает 401. * ⚙️ FilterSecurityInterceptor – проверяет, есть ли у аутентифицированного пользователя разрешение (ROLE_*) для доступа к ресурсу. Каждый фильтр решает конкретную задачу, и порядок важен: если, например, фильтр авторизации (FilterSecurityInterceptor) стоит раньше, чем фильтр аутентификации, вы получите неожиданный отказ. 💡 Современный подход (Spring Boot 3+):

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
      .csrf().disable()
      .authorizeHttpRequests(auth -> auth
          .requestMatchers("/public/**").permitAll()
          .anyRequest().authenticated()
      )
      .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
      .oauth2ResourceServer(oauth2 -> oauth2.jwt()); // JWT из OIDC/JWK  
    return http.build();
}
Таким образом вы сами управляете порядком фильтров и включаете только нужные. 🧠 2. AuthenticationManager & ProviderManager Когда UsernamePasswordAuthenticationFilter (или другой аутентификатор) получает учётные данные, он создает UsernamePasswordAuthenticationToken с неверифицированными (unauthenticated) флагом. Затем передаёт этот токен в AuthenticationManager:

UsernamePasswordAuthenticationFilter → AuthenticationManager.authenticate()
AuthenticationManager по умолчанию — это ProviderManager, который хранит список AuthenticationProvider (например, DaoAuthenticationProvider для UserDetailsService или JwtAuthenticationProvider для токенов). Каждый Provider пытается аутентифицировать токен, и если успешно, возвращает уже аутентифицированный Authentication с authorities. 📌 Совет: если нужно добавить кастомную проверку (например, MFA), реализуйте свой AuthenticationProvider и зарегистрируйте его перед DaoAuthenticationProvider. 🧠 3. UserDetailsService & UserDetails DaoAuthenticationProvider опирается на UserDetailsService (или ReactiveUserDetailsService в WebFlux), чтобы получить UserDetails (имя, пароль, роли, статус аккаунта). В Java 17+ можно пользоваться Map.of(...) или List.of(...), но в реальных проектах лучше хранить в БД через JPA/Hibernate.

@Service
public class CustomUserDetailsService implements UserDetailsService {
    private final UserRepository repo;
    @Override
    public UserDetails loadUserByUsername(String username) {
        UserEntity user = repo.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found"));
        return User.withUsername(user.getUsername())
                   .password(user.getPassword())
                   .authorities(user.getRoles().toArray(new String[0]))
                   .accountLocked(!user.isAccountNonLocked())
                   .build();
    }
}
🧠 4. SecurityContext & SecurityContextHolder После успешной аутентификации фильтр устанавливает SecurityContext в SecurityContextHolder. По умолчанию используется стратегия MODE_THREADLOCAL, т.е. контекст привязан к текущему потоку.

SecurityContextHolder.getContext().setAuthentication(authenticatedToken);

«Я слышу свой код»: как работает Java-программист, потерявший зрение Константин Евтеев собирает Java-код с помощью диктора NV
«Я слышу свой код»: как работает Java-программист, потерявший зрение Константин Евтеев собирает Java-код с помощью диктора NVDA, редактирует его в Блокноте и передает на Linux по SSH через самописные bash-скрипты. После потери зрения он не потерял интереса к жизни и желания быть полезным и выстроил собственную инженерную экосистему: оглавления по строкам .txt-файлами, навигация по main и маленьким методам, отладка на слух. https://habr.com/ru/companies/axiomjdk/articles/913748/ 👉@BookJava

🧠 Чем Spring Native Image отличается от обычного Spring-приложения? 📌 Обычный Spring: * Запускается на JVM, динамически заг
🧠 Чем Spring Native Image отличается от обычного Spring-приложения? 📌 Обычный Spring: * Запускается на JVM, динамически загружает классы, использует рефлексию. * Медленный старт (секунды), выше потребление памяти. * Подходит для сложной логики с динамическим поведением (настройки, рефлексия, прокси). 📌 Spring Native Image (GraalVM): * Компиляция в нативный бинарник. * ⚡️ Мгновенный старт (миллисекунды), низкое потребление памяти. * Отсутствие динамики: ограничения в рефлексии, прокси и динамической загрузке. 💡 Когда что использовать? * Native Image — идеален для микросервисов и Serverless-приложений. * Обычный JVM Spring — когда важна максимальная гибкость и динамика. ⚠️ Помни, что Native Image требует больше усилий по настройке и ограничений на библиотеки. 👉@BookJava

🚀 Подборка Telegram каналов для программистов Системное администрирование, DevOps 📌 https://t.me/bash_srv Bash Советы https://t.me/win_sysadmin Системный Администратор Windows https://t.me/sysadmin_girl Девочка Сисадмин https://t.me/srv_admin_linux Админские угодья https://t.me/linux_srv Типичный Сисадмин https://t.me/devopslib Библиотека девопса | DevOps, SRE, Sysadmin 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 https://t.me/razrab_1C 1C Разработчик https://t.me/buh1C_prog 1C Программист | Бухгалтерия и Учёт https://t.me/rabota1C_rus Вакансии для программистов 1С Программирование 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 академия. https://t.me/BookPython Библиотека Python разработчика https://t.me/python_real Python подборки на русском и английском https://t.me/python_360 Книги по Python 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/bigdata_1 Big Data, Machine Learning Программирование 📌 https://t.me/bookflow Лекции, видеоуроки, доклады с IT конференций 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 программиста https://t.me/lifeproger Жизнь программиста. Авторский канал. 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 Обучающие видео, книги по Физике и Математике https://t.me/matgeoru Математика | Геометрия | Логика Excel лайфхак📌 https://t.me/Excel_lifehack https://t.me/mir_teh Мир технологий (Technology World) Вакансии 📌 https://t.me/sysadmin_rabota Системный Администратор https://t.me/progjob Вакансии в IT

Как не завалить приложение из-за N+1 запросов в Hibernate 🧨 N+1 проблема — больной зуб почти любого Java-разработчика. Hiber
Как не завалить приложение из-за N+1 запросов в Hibernate 🧨 N+1 проблема — больной зуб почти любого Java-разработчика. Hibernate делает жизнь проще, пока не сталкиваешься с этим 👻 📌 Суть проблемы Допустим, у тебя есть сущности User и связанные с ними сущности Order. При запросе пользователей:

List<User> users = userRepository.findAll(); // Один запрос
for(User user : users) {
    List<Order> orders = user.getOrders(); // +1 запрос на каждого пользователя!
}
Если пользователей 1000, то будет 1 + 1000 SQL-запросов. Это убийственно для производительности ⚠️ 🛠 Как решить? 💡 Вариант 1: JOIN FETCH Самый быстрый и простой путь — сразу подтянуть связанные сущности:

@Query("SELECT u FROM User u JOIN FETCH u.orders")
List<User> findAllWithOrders();
✅ Всего один SQL-запрос ❌ Может привести к дублированию строк, если связей много и они сложные 💡 Вариант 2: Entity Graph (Spring Data JPA) Entity Graph — более гибкий подход:

@EntityGraph(attributePaths = {"orders"})
List<User> findAll();
✅ Удобно и понятно, нет дублей ✅ Можно легко настраивать под конкретный запрос 💡 Вариант 3: Batch fetching (настройка Hibernate)

spring.jpa.properties.hibernate.default_batch_fetch_size=20
Hibernate будет автоматически загружать связанные сущности пачками. ✅ Просто настроить и сразу эффект ❌ Всё равно несколько запросов, хотя и пачками 🧠 Когда что использовать? ▫️ JOIN FETCH — когда связи простые, а данных немного. ▫️ Entity Graph — если нужна гибкость и удобство. ▫️ Batch fetching — когда настроить проще, чем переписывать код. Не забывай проверять SQL-запросы в логах и профилировать приложение 🔥 👉@BookJava

🗑 Понимание различных сборщиков мусора в Java 🔵 Serial Garbage Collector: Лучший вариант для однопоточных приложений с небольшими кучами. Он использует один поток для выполнения как малых, так и больших сборок мусора, что приводит к значительным паузам, но минимальной нагрузке на систему. 🔵 Parallel Garbage Collector: Подходит для приложений с высокими требованиями к пропускной способности. Использует несколько потоков для выполнения как малых, так и больших сборок мусора, уменьшая время пауз, но при этом увеличивая использование CPU. 🔵 Concurrent Mark-Sweep (CMS) Garbage Collector: Разработан для минимизации пауз за счёт выполнения основной части работы по сборке мусора параллельно с выполнением приложений. Подходит для приложений, где критически важна низкая задержка. 🔵 G1 Garbage Collector: Сбалансированный сборщик мусора, который стремится обеспечить предсказуемое время пауз, разделяя кучу на регионы и выполняя сборку мусора поэтапно. Является хорошим выбором по умолчанию для большинства приложений. 🔵 Z Garbage Collector и Shenandoah: Сборщики мусора с ультранизкой задержкой, разработанные для работы с большими кучами. Основная часть работы по сборке мусора выполняется параллельно, что позволяет минимизировать время пауз даже при очень больших кучах. 👉@BookJava

Серия статей: «Дюк, вынеси мусор!» Все, что нужно знать о сборке мусора в Java 🔹 Если работа с JVM для тебя не просто слова,
Серия статей: «Дюк, вынеси мусор!» Все, что нужно знать о сборке мусора в Java 🔹 Если работа с JVM для тебя не просто слова, а параметры вроде Xmx и Xms ты прописываешь с закрытыми глазами, самое время разобраться, что же реально происходит с памятью в Java и как новые сборщики мусора могут повлиять на производительность твоего приложения. 🗂 В этой серии — подробный разбор всех современных GC, доступных в Java HotSpot VM: от базовых до самых продвинутых. Для каждого — объяснение принципов, сценарии применения, плюсы и минусы, а также практические советы по настройке. Список статей: 1️⃣ Введение 2️⃣ Serial GC и Parallel GC 3️⃣ CMS и G1 4️⃣ ZGC 5️⃣ Epsilon GC 6️⃣ Shenandoah GC 👉@BookJava

👩‍💻 Хотите выйти за пределы стандартных подходов в Java-разработке? Разобраться в JVM, многопоточности и современных фреймв
👩‍💻 Хотите выйти за пределы стандартных подходов в Java-разработке? Разобраться в JVM, многопоточности и современных фреймворках? 🔥 Актуальное обучение, курс «Java Developer. Professional» — это 96 часов практики, детальный разбор технологий, код-ревью от опытных экспертов и работа с Spring WebFlux, Kafka, Kubernetes. После обучения вы сможете разрабатывать сложные Java-приложения уровня Middle+, понимать работу JVM изнутри и писать чистый, оптимизированный код. 🎁 Дарим промокод, который дает скидку на обучение - JAVA_06 ➡️ Пройдите вступительное тестирование и получите скидку: https://vk.cc/cMonpN Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

🧠 Сейчас расскажу о распределённых транзакциях в Java и почему их стоит использовать с осторожностью. Когда твое приложение
🧠 Сейчас расскажу о распределённых транзакциях в Java и почему их стоит использовать с осторожностью. Когда твое приложение работает с несколькими источниками данных (например, двумя базами или базой + очередью), часто появляется соблазн обернуть всё в одну большую транзакцию с помощью JTA (Java Transaction API) и XA-ресурсов. Но на практике это почти всегда антипаттерн. 📌 Почему? * XA-транзакции медленные и сложно отлаживаются. * Они ломают горизонтальное масштабирование: один сбой — откат по всем участникам. * Могут приводить к блокировкам и deadlock-ам, если инфраструктура нестабильна. 💡 Современные альтернативы: 1. Transaction outbox pattern — сначала пишем событие/задачу в outbox-таблицу в той же БД, где меняем данные, и только потом публикуем во внешний сервис. 2. Event sourcing — строим архитектуру так, чтобы любые изменения происходили через событийную модель (и проще компенсировать сбои). 3. Idempotency & retries — делаем операции идемпотентными и безопасными к повтору. ⚠️ Не используешь JTA без реальной необходимости. Spring Boot 3+ по умолчанию уже не настраивает JTA — и правильно делает. Если всё же нужен XA: * Используй Atomikos, Narayana или Bitronix — это современные провайдеры. * Но всегда сначала подумай: "Могу ли я упростить архитектуру и уйти от XA?" Пример из кода на Spring Boot:

// НЕ рекомендуется:
@EnableTransactionManagement
public class Config {
  @Bean
  public JtaTransactionManager transactionManager() {
      return new JtaTransactionManager();
  }
}

// Лучше outbox + отдельный publisher
🧠 В 99% случаев проще и надёжнее строить архитектуру вокруг событий и простых локальных транзакций, чем бороться с XA. 👉@BookJava

🧠 Сегодня разберём Saga — паттерн, который часто всплывает на собеседованиях уровня сеньор, особенно если речь о микросервис
🧠 Сегодня разберём Saga — паттерн, который часто всплывает на собеседованиях уровня сеньор, особенно если речь о микросервисах. 📌 Зачем нужна Saga? Когда нужно выполнить бизнес-операцию, затрагивающую несколько микросервисов, важно обеспечить целостность данных. Классические транзакции (@Transactional) тут не подходят — нет распределённого ACID. Saga решает эту проблему через последовательность локальных транзакций с возможностью отката (compensation). 💡 Виды Saga 1. Choreography Нет единого оркестратора. Каждый сервис реагирует на события предыдущих через очередь (Kafka, RabbitMQ). * Простой flow * Меньше точек отказа 2. Orchestration Есть выделенный "оркестратор", который координирует выполнение саги, рассылая команды сервисам. * Более явный контроль * Лучше трассировка ⚖️ Плюсы * Обеспечивает согласованность между сервисами * Высокая отказоустойчивость: каждый шаг можно компенсировать * Гибкость — легко расширять и модифицировать бизнес-логику ⚠️ Минусы * Сложнее реализовать, чем простые транзакции * Не моментальная консистентность — возможны временные аномалии * Нужно проектировать compensating transactions для каждого шага * Тяжело тестировать крайние случаи и "сорванные" шаги 🔁 Альтернативы * Distributed Transactions (XA, 2PC) — редко используются из-за сложности и слабой поддержки в современных cloud-системах. * Event Sourcing — другой паттерн работы с изменениями, но сложнее для чтения. * Idempotency + Retry — иногда достаточно, если бизнес-процесс допускает. 💡 Совет: для большинства бизнес-операций с межсервисным взаимодействием, где требуется отмена — Saga остаётся самым практичным выбором. В Spring есть библиотека Axon Framework, также стоит посмотреть на Camunda. 👉@BookJava

Ищем Java-разработчика в команду онлайн-рекомендаций AI VK 🤖 Будем вместе разрабатывать высоконагруженные микросервисы на Ja
Ищем Java-разработчика в команду онлайн-рекомендаций AI VK 🤖 Будем вместе разрабатывать высоконагруженные микросервисы на Java. Кроме кода доверим коллеге принимать архитектурные и технические решения, гибко настраивать ML-эксперименты и рекомендательный пайплайн. Если любите технически сложные задачи и хотите работать с большими данными, ждём ваше резюме на сайте VK Team!

🧠 Как быстро написать компаратор в Java и не забыть про null Часто нужно сортировать коллекции по какому-то полю. Вместо ста
🧠 Как быстро написать компаратор в Java и не забыть про null Часто нужно сортировать коллекции по какому-то полю. Вместо старых анонимных классов используем лямбды и статические методы из Comparator:

List<User> users = ...;

users.sort(Comparator
    .comparing(User::getName, Comparator.nullsLast(String::compareToIgnoreCase))
    .thenComparingInt(User::getAge)
);
📌 comparing — сравнивает по полю (например, name). 📌 nullsLast или nullsFirst — удобно обрабатывать возможные null. 📌 thenComparingInt — дополнительная сортировка (например, по возрасту). 💡 Такой подход краткий, читабельный и отлично работает с любыми полями, даже если они могут быть null. ⚠️ Никогда не забывай про null, особенно если сортируешь данные из БД или внешних источников. Ошибка NullPointerException во время сортировки может неожиданно прилететь в проде. 👉@BookJava

Сегодня покажу вам интересный костыль, который до сих пор живёт в JDK и влияет на сортировку списков. 🧠 Если ты когда-нибудь
Сегодня покажу вам интересный костыль, который до сих пор живёт в JDK и влияет на сортировку списков. 🧠 Если ты когда-нибудь пробовал сортировать LinkedList через Collections.sort(), знай — под капотом происходит скрытая магия. 📌 Collections.sort(list) сначала проверяет, какой это список. Если это RandomAccess-list (например, ArrayList) — используется быстрый сортировщик (TimSort) прямо по массиву. ⚠️ Но если это LinkedList (или любой не-рандом-доступ список), внутри происходит... преобразование списка в массив! Сначала все элементы копируются в массив, потом сортируются, а затем результат обратно заливается в твой список.

// Да, это реально работает так:
List<Integer> list = new LinkedList<>();
// ...заполняем...
Collections.sort(list);
💡 Почему так? Сортировка напрямую через LinkedList была бы очень медленной — доступ к элементам по индексу у него O(n), а не O(1) как у ArrayList. Поэтому JDK идёт на компромисс: временная потеря памяти, но ускорение времени сортировки. ⚠️ Следствие: если у тебя большой LinkedList, сортировка будет требовать двойную память: сначала весь список копируется в массив. Совет: Для больших коллекций, которые часто сортируются, используй ArrayList, либо готовься к затратам памяти. 👉@BookJava

📊 Приглашаем на открытый урок: Создание RLE архиватора на Java Хотите узнать, как работают алгоритмы сжатия данных? В нашем
📊 Приглашаем на открытый урок: Создание RLE архиватора на Java Хотите узнать, как работают алгоритмы сжатия данных? В нашем вебинаре мы шаг за шагом создадим архиватор на Java, используя алгоритм RLE. Вы разработаете интерфейс программы и поймете, как реализовать самые эффективные методы сжатия. Протестировав алгоритм на реальных данных, вы увидите, когда он работает наилучшим образом. Присоединяйтесь к нам и погрузитесь в мир программирования и алгоритмов! 🗓 28 мая в 20:00 МСК 🆓 Бесплатно. Урок в рамках старта курса «Алгоритмы и структуры данных». 🎁 Всем участникам вебинара дарим промокод, который дает скидку на обучение - Algo5 👉 Регистрация на вебинар: https://vk.cc/cMl0ID Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

Двоичная Java: CDS, CRaC и AOT для ускорения запуска и прогрева JVM В этой статье вы узнаете о повышении перфоманса Java-прил
Двоичная Java: CDS, CRaC и AOT для ускорения запуска и прогрева JVM В этой статье вы узнаете о повышении перфоманса Java-приложений. Разберём: 🔹Как работает HotSpot. 🔹Процессы исполнения байт-кода и в чём же основные проблемы. 🔹Технологии для повышения перформанса: CDS, CRaC и AOT. 🔹Два мира сборки приложений: статический и динамический. Поговорим о двух болях, которые есть в Java-приложениях — это время запуска и время достижения пиковой производительности. https://habr.com/ru/companies/axiomjdk/articles/911568/ 👉@BookJava

🧠 10 правил безопасного Java-приложения: 1️⃣ Валидация на всех уровнях. 📌 Всегда проверяй входные данные (API, формы, запро
🧠 10 правил безопасного Java-приложения: 1️⃣ Валидация на всех уровнях. 📌 Всегда проверяй входные данные (API, формы, запросы к БД). Используй Bean Validation (@Valid, @NotNull). 2️⃣ Используй PreparedStatement. ⚠️ Никогда не конкатенируй SQL-запросы напрямую, чтобы избежать SQL-инъекций. 3️⃣ Не раскрывай детали исключений. 📌 Отправляй клиенту общий код ошибки, а детали логируй. 4️⃣ Скрывай конфигурацию. 💡 Используй application.yml с переменными окружения для чувствительных данных (пароли, ключи API). 5️⃣ Ограничивай доступ. 📌 Spring Security — твой друг. Используй @PreAuthorize и грамотно настраивай роли и права доступа. 6️⃣ Безопасная сериализация. ⚠️ Избегай Java-стандартной сериализации. Предпочитай JSON (Jackson) с явными DTO. 7️⃣ Используй актуальные версии библиотек. 📌 Регулярно проверяй зависимости (dependency-check), чтобы избежать известных уязвимостей. 8️⃣ Грамотно логируй. 💡 Не логируй пароли, токены и персональные данные. Используй SLF4J с Logback, настрой уровень логов. 9️⃣ Безопасные куки и заголовки. 📌 Используй атрибуты куки: Secure, HttpOnly, SameSite. Spring Security поможет тебе настроить это быстро. 🔟 Настрой Security Headers. 📌 Используй заголовки: * X-Frame-Options: DENY * X-Content-Type-Options: nosniff * Content-Security-Policy (CSP) Безопасность — это не разовая задача, а процесс 💡 👉@BookJava