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

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

Kanalga Telegram’da o‘tish

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

Ko'proq ko'rsatish

📈 Telegram kanali Библиотека Java разработчика analitikasi

Библиотека Java разработчика (@bookjava) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 10 115 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 11 697-o'rinni va Rossiya mintaqasida 62 901-o'rinni egallagan.

📊 Auditoriya ko‘rsatkichlari va dinamika

невідомо sanasidan buyon loyiha tez o‘sib, 10 115 obunachiga ega bo‘ldi.

27 Avgust, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni -73 ga, so‘nggi 24 soatda esa -3 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.

  • Tasdiqlash holati: Tasdiqlanmagan
  • Jalb etish (ER): Auditoriya o‘rtacha 7.20% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 3.71% ini tashkil etuvchi reaksiyalarni to‘playdi.
  • Post qamrovi: Har bir post o‘rtacha 729 marta ko‘riladi; birinchi sutkada odatda 375 ta ko‘rish yig‘iladi.
  • Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 7 ta reaksiya keladi.
  • Tematik yo‘nalishlar: Kontent string, интерфейс, строка, boot, api kabi asosiy mavzularga jamlangan.

📝 Tavsif va kontent siyosati

Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate. По всем вопросам @evgenycarter РКН clck.ru/3KoGeP

Yuqori yangilanish chastotasi (oxirgi ma’lumot 28 Avgust, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.

10 115
Obunachilar
-324 soatlar
-167 kunlar
-7330 kunlar
Postlar arxiv
🔍Тестовое собеседование с 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