javatg | Unsorted

Telegram-канал javatg - Java

17202

Самая актуальная информация из мира Java По всем вопросам- @haarrp @itchannels_telegram - 🔥лучшие ит-каналы @pythonl - 🐍 @ai_machinelearning_big_data- ml @ArtificialIntelligencedl - AI @datascienceiot - ds @pythonlbooks 📚 РКН: clck.ru/3FmwKr

Subscribe to a channel

Java

☕ Java добралась до GPU Tensor Cores почти без потери производительности

В Project Babylon показали, как один и тот же Java Tensor API можно запускать на разных GPU через HAT — без переписывания логики под каждого производителя.

На NVIDIA A10:

- обычный matrix multiply: около 240 GFLOP/s
- через Tensor Cores: до 7,3 TFLOP/s
- производительность приблизилась к native CUDA/WMMA

На Apple M4 Max тот же Java-код запускается через OpenCL 1.2, а после настройки tile size и параметров запуска получил до 8× ускорения относительно наивной реализации.
Под капотом:

- Project Babylon даёт code reflection
- HAT преобразует Java-код под GPU backend
- Tensor API абстрагирует MMA-операции
- NVIDIA получает аппаратные Tensor Cores, а другие платформы — эквивалентное tiled-исполнение

Интересный шаг к тому, чтобы писать высокопроизводительные GPU-вычисления на Java и сохранять переносимость между разным железом.

https://social.ora.cl/6011BEbmLc

Читать полностью…

Java

Команды ждут тебя на треке программирование роботов на МТС True Tech Champ 2026  — всероссийском чемпионате по программированию с двумя треками и призовым фондом 10 250 000 рублей.

Успей зарегистрироваться до 13 сентября.

В треке программирования роботов тебе предстоит запрограммировать робособаку для доставки груза через полосу препятствий сначала в онлайн-симуляторе, а затем на офлайн-полигоне в финале 22 октября. Рекомендуемые стеки: Go, Java, Python, C#, C++, JS.

Участие в командах 2-5 человек. Если у тебя нет своей команды, кураторы помогут объединиться с другими участниками на платформе.

Масштабный финал объединит борьбу за призовой фонд 10 250 000 рублей, выступления хедлайнеров, доклады спикеров и активности для всех гостей мероприятия.

Успей зарегистрироваться и пройти квалификацию до 13 сентября.

erid:2VSb5xPaMKx

Читать полностью…

Java

💡 Java: переопределяешь `equals()` - переопредели и `hashCode()`

Два объекта с одинаковым email могут быть равны по equals(), но HashSet.contains() при этом вернёт false.

Причина: HashSet и HashMap сначала используют хеш, чтобы определить, где искать объект, а затем проверяют равенство. Если хеши различаются, до equals() дело может не дойти.

Правило: равные объекты обязаны иметь одинаковый `hashCode()`. При этом одинаковый хеш не гарантирует равенство - коллизии допустимы.

В примере на картинке равенство определяется по email, поэтому хеш тоже вычисляется по нему.

И ещё: не меняйте поля, участвующие в `equals()` и `hashCode()`, пока объект хранится в `HashSet` или используется как ключ `HashMap` - поиск может перестать его находить.

#Java #OOP

Читать полностью…

Java

🚀 Spring Boot 4 меняет подход к тестовым зависимостям

Теперь для каждой технологии используется свой test starter по схеме:

spring-boot-starter-*-test

Например, для Spring Security:

spring-boot-starter-security-test

Что это даёт:

- у каждой технологии свой тестовый starter
- spring-boot-starter-test подтягивается транзитивно
- зависимости для тестов становятся понятнее и аккуратнее
- меньше ручной сборки test classpath

Для Security-тестов в Spring Boot 4 лучше подключать именно ...-security-test, а не отдельный spring-security-test.

Читать полностью…

Java

🖥 Spring Boot 4 улучшил наблюдаемость Redis через Observation API.

Теперь команды Redis можно автоматически связывать с метриками и трассировками:

- latency операций
- spans для Redis-команд
- ошибки и длительность запросов
- интеграция с общей системой наблюдаемости приложения

Особенно удобно использовать это вместе с OpenTelemetry starter, чтобы Redis сразу попадал в единый tracing и metrics pipeline.

Для продакшена это полезно тем, что проблемы Redis можно видеть не отдельно, а прямо внутри полного пути запроса через приложение.

#SpringBoot4 #Redis

Читать полностью…

Java

💡 Java: не используй `Thread.sleep()` для ожидания работы

Thread.sleep() - это просто пауза на заданное время.

Проблема в том, что ты угадываешь:

❌ поток может проснуться слишком рано
❌ или наоборот, ждать дольше, чем нужно
❌ polling через sleep() создаёт лишние задержки и проверки

Для координации потоков лучше использовать:

✅ wait() / notify()
✅ CountDownLatch
✅ другие примитивы синхронизации из java.util.concurrent

Например:


CountDownLatch done = new CountDownLatch(1);

done.await(); // ждём сигнал
done.countDown(); // работа завершена


А если задача должна выполняться периодически, вместо бесконечного цикла с sleep() лучше взять



ScheduledExecutorService exec =
Executors.newSingleThreadScheduledExecutor();

exec.scheduleAtFixedRate(
this::doWork,
0,
1,
TimeUnit.SECONDS
);

Thread.sleep() хорошо подходит для простой задержки.


Для ожидания события и периодических задач в Java есть более точные инструменты.

#Java #Concurrency

Читать полностью…

Java

Java-ловушка: . в формате числа не всегда означает точку

В DecimalFormat шаблон вроде:


#,###.##


не гарантирует вывод 1,234.56.

Символы зависят от locale:

🇺🇸 US → 1,234.56
🇮🇹 Italy → 1.234,56

Поэтому если формат предназначен для конкретной страны, лучше задавать её явно:


DecimalFormatSymbols it =
new DecimalFormatSymbols(Locale.ITALY);

DecimalFormat format =
new DecimalFormat("#,###.##", it);


Иначе приложение может внезапно начать форматировать числа иначе просто потому, что JVM запустили с другой локалью.

Мелочь, которая особенно неприятно всплывает в деньгах, отчётах и CSV.

Читать полностью…

Java

⚡️ Spring Boot 4: `@ConfigurationPropertiesSource` для типов из других модулей

В Spring Boot 4 появилась полезная штука для конфигурации больших проектов.

@ConfigurationPropertiesSource позволяет генерировать metadata для типов, которые находятся не в текущем модуле, а, например, в общей библиотеке или отдельном starter-модуле.

Раньше с такими внешними типами IDE-подсказки для application.yml и application.properties могли быть неполными или вообще отсутствовать.

Теперь можно явно указать источник конфигурационных свойств и получить нормальную metadata даже для внешних классов.

Особенно полезно для:

— multi-module проектов
— внутренних Spring Boot starter'ов
— shared configuration libraries
— больших платформенных команд

Мелкая фича, но для DX в крупных Spring Boot проектах очень приятная.

#SpringBoot4 #Config

Читать полностью…

Java

Java Records: меньше шаблонного кода для обычных data-классов

Если класс нужен в основном для хранения данных, record позволяет сильно сократить код.

Вместо обычного класса с полями, конструктором, equals(), hashCode() и toString() можно написать:


public record User(String name, int age, String email) {}


Java сама создаст:


user.name();
user.age();
user.email();

user.equals(other);
user.hashCode();
user.toString();


При этом record остаётся неизменяемым по ссылкам на свои компоненты: сеттеров нет, а поля фактически final.

Можно добавить и компактный конструктор для валидации:


public record User(String name, int age, String email) {
public User {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
}
}


Records появились как preview в Java 14 и стали полноценной частью языка в Java 16.

Удобный вариант для DTO, результатов запросов, событий, конфигурационных объектов и других небольших структур данных.

Читать полностью…

Java

В Java clone() легко принять за полноценную копию объекта. Но super.clone() делает только shallow copy.

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

То есть:


Main shallow = (Main) super.clone();


shallow и оригинал будут разными объектами, но dependency у них может указывать на один и тот же экземпляр.

Поэтому изменение вложенного объекта через одну копию неожиданно отразится и в другой.

Для deep copy нужно отдельно клонировать вложенные поля:


Main deep = (Main) super.clone();
deep.setDependency((Dependency) this.dependency.clone());


Теперь dependency тоже будет отдельным объектом.

Мелочь, на которой легко поймать очень неприятный баг: clone() копирует оболочку, а не весь граф объектов.

Читать полностью…

Java

🔴 Тестовый собес с Java-разработчиком уже завтра! 
[+ разбор 50 сложных вопросов в подарок ]

19 августа (уже завтра!) в 19:00 по мск
приходи онлайн, чтобы посмотреть на настоящее интервью на Middle Java-разработчика!

Собеседование проведёт Сергей Чамкин - старший разработчик из Uzum, ex-WildBerries

Как это будет:

📂 Сергей задаст разработчику-добровольцу вопросы и задачи, которые могут спросить на реальном собесе
📂 После каждого ответа респондента ты услышишь подробный комментарий от ментора и поймёшь, чего на самом деле ожидает собеседующий на интервью
📂 В конце сможешь задать любой вопрос Сергею и получить на него развёрнутый ответ

Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы

Но ты можешь посмотреть его бесплатно 🔥
Только завтра, в прямом эфире!

🎁 Подарок для всех, кто зарегается на веб — файл с ОТВЕТАМИ НА 50 СЛОЖНЫХ ВОПРОСОВ с Java-собеседований 🔥

Жми на кнопку, чтобы попасть на эфир и забрать подарок ↓
@shortcut_sh_bot 

Реклама.
О рекламодателе.

Читать полностью…

Java

💡 В Java можно избавиться от лишнего cast после instanceof.

Старый вариант:


if (animal instanceof Dog) {
Dog d = (Dog) animal;
d.bark();
}


С pattern matching переменная объявляется прямо в проверке:


if (animal instanceof Dog d) {
d.bark();
}


d существует только там, где условие instanceof гарантированно истинно. Меньше кода, меньше лишних приведений типов и проще читать.

#Java #PatternMatching

Читать полностью…

Java

Вам доклады по Go или Java? VK приглашает на митап с двойной начинкой
26 августа VK собирает Go- и Java-инженеров, чтобы прокачать знания.

В программе два трека — Go и Java, по три доклада в каждом.

Трек Go:
• «Компиляция Go в динамическую либу, или как мы ускорили выкатку фичи в два раза, но нам не понравилось», Михаил Кичигин, бэкенд-разработчик, Avito Tech
• «Go-платформа VK: как мы построили единую основу для создания Go-сервисов», Александр Апанасенко, руководитель команды SDK Backend, VK
• «Почтальон от Kubernetes до Palo Alto. Как осуществляется доставка информации об адресах», Дарья Кулькина, бэкенд-разработчик, Точка Банк

Трек Java:
• «Перформанс-трюки в поисковой платформе Ozon», Пётр Портнов, ведущий разработчик среднего поиска, Ozon
• «Архитектура современного движка платёжной системы и переход к новой архитектуре», Игорь Крикунов, технический лидер разработки DBC, Альфа-Банк
• «Переход от федерации S3-кластеров в пользу коммунального и мультитенантного кластера», Кирилл Боблак, ведущий разработчик One-cloud, VK

А ещё будет мастер-класс по прокачке навыка, который сделает вас звездой любого вечера, и афтепати, чтобы обсудить доклады в неформальной обстановке.

Встречаемся в 17:00, начало в 18:00. Участие бесплатное, регистрация обязательна.

Читать полностью…

Java

🔥 Ошибка, которую даже Senior Java-разработчики продолжают делать в 2026 году

Это чрезмерное использование mutable state и общих изменяемых данных.

Результат знаком каждому, кто работал с многопоточностью:

- race conditions;
- трудноуловимые баги;
- лишние synchronized и блокировки;
- проблемы с масштабированием.

Вместо того чтобы постоянно защищать изменяемое состояние, во многих случаях лучше проектировать код так, чтобы его было меньше изначально:

✅ immutable-объекты
✅ Java record
✅ concurrent-коллекции
✅ immutable snapshots через List.copyOf()
✅ минимум shared state

Например, ConcurrentLinkedQueue может убрать необходимость в грубой синхронизации для определённых сценариев, а record отлично подходит для неизменяемых доменных объектов.

Главная идея проста: чем меньше состояние можно изменить, тем меньше способов сломать многопоточный Java-код.

Но ConcurrentLinkedQueue не универсальная замена synchronized - выбор структуры данных всё равно должен исходить из требований к атомарности и консистентности.

Читать полностью…

Java

☕️ Java-совет: не кешируйте данные по `Class<?>` через обычный `ConcurrentHashMap`

Такой код выглядит нормально:


private static final Map<Class<?>, Metadata> CACHE =
new ConcurrentHashMap<>();

Metadata metadata = CACHE.computeIfAbsent(
type,
Metadata::inspect
);


Но в приложениях с динамическими ClassLoader такой кеш может удерживать классы в памяти и мешать их выгрузке.

Для этого в Java есть малоизвестный ClassValue<T>:


private static final ClassValue<Metadata> CACHE =
new ClassValue<>() {
@Override
protected Metadata computeValue(Class<?> type) {
return Metadata.inspect(type);
}
};

Metadata metadata = CACHE.get(User.class);


Почему это лучше:

- потокобезопасно;
- значение вычисляется лениво;
- данные хранятся отдельно для каждого класса;
- класс и связанное значение могут быть выгружены вместе с ClassLoader.

Удалить значение вручную:


CACHE.remove(User.class);


ClassValue отлично подходит для кеширования reflection-метаданных, сериализаторов, валидаторов и обработчиков аннотаций.

Редкий случай, когда встроенный механизм Java и проще, и безопаснее самодельного кеша.

Читать полностью…

Java

Java: рефакторинг legacy-кода начинай с теста

Даже странное поведение старого метода может быть важно для вызывающего кода. Прежде чем «сделать красиво», зафиксируй, как он работает сейчас.

* Добавь тест на текущее поведение. Проверь обычный сценарий и важные граничные случаи.
* Меняй по одному шагу: переименуй переменную, выдели метод, упрости условие.
* После каждого изменения запускай тесты. Если что-то сломалось, причину проще найти в небольшом изменении.
* Исправления багов отделяй от рефакторинга. Изменение поведения лучше делать отдельным шагом с отдельным тестом.

Переписывание целого класса без покрытия усложняет проверку: код выглядит лучше, но сохранил ли он прежнее поведение?

Читать полностью…

Java

🍃 Spring Boot 4: проверьте зависимости Flyway и Liquibase

После обновления одной зависимости flyway-core или liquibase-core недостаточно для автоконфигурации миграций. В Spring Boot 4 поддержку технологий вынесли в отдельные модули.

Используйте соответствующий стартер:

* Flyway → spring-boot-starter-flyway
* Liquibase → spring-boot-starter-liquibase

Для тестов, включая test slices:

* spring-boot-starter-flyway-test
* spring-boot-starter-liquibase-test

Все перечисленные зависимости относятся к группе org.springframework.boot. Тестовые стартеры добавляются с областью test в Maven или через testImplementation в Gradle.

Руководство по миграции: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide#module-dependencies

#SpringBoot #Java #Flyway

Читать полностью…

Java

🚀 Apache Kafka - это распределённая платформа для передачи и хранения потоков событий в реальном времени.

Проще: сервисы не общаются напрямую друг с другом, а отправляют события в Kafka, а другие сервисы читают их когда нужно.

В 2026 Kafka используют для:

• связи микросервисов
• логов и событий
• real-time аналитики
• CDC из баз данных
•• обработки больших потоков данных
построения event-driven архитектуры

Главная причина популярности: высокая пропускная способность, масштабирование и возможность надёжно хранить события и перечитывать их позже.
https://www.youtube.com/shorts/Z-t8CCs7ty4

Читать полностью…

Java

Школа программирования Java Online Projects поздравляет с Днем Знаний!🧑‍🎓📚

Вышло наше финальное занятие курса по Микросервисной архитектуре — «Нагрузочное тестирование. Gatling». На нем мы на практике разбираем, как наше приложение ведет себя под реальной высокой нагрузкой.
Вместе с ним мы запускаем последнюю акцию перед подорожанием:

🔥 Скидка 50% на курсы «Микросервисы, Kafka, Docker Spring Cloud, WebFlux» и «Деплой микросервисов в Kubernetis/Helm»
✨ Бонусы: выпускные проекты Rescue Service и TopJava2
✨ Курс TopKotlin или DocJava в подарок

Суперпредложение: скидка 55% скидка на всю линейку Микросервисов + все бонусы включены🔥

Программа на 100% покрывает продвинутый стек компетенций:

✨ Архитектура и веб-стек — начинаем с реактивных приложений: Project Reactor, Spring WebFlux, R2DBC. Дальше переходим на Spring Boot 4 — полный MVC-стек и виртуальные потоки (Virtual Threads).

✨ Инфраструктура Spring Cloud — отказоустойчивые системы на Spring Cloud Gateway и Config Server, паттерны Circuit Breaker, RateLimiter, Retry.

✨ Event-Driven & Data — асинхронное взаимодействие через Kafka, сериализация в Avro и хранение схем в Schema Registry, паттерн Outbox с Kafka Connect и Debezium поверх PostgreSQL, Hibernate/JPA и миграции Flyway.

✨ Безопасность — сквозная аутентификация и авторизация на Keycloak, OAuth 2.0, OpenID Connect и JWT, защита от CSRF, хранение сессий в Redis.

✨ Тестирование и качество — интеграционные тесты с Testcontainers, WireMock и Awaitility, проверка под высокой нагрузкой с Gatling.

✨ Observability — метрики, логи и распределенные трассировки через Micrometer, Prometheus, Loki, Tempo (или Zipkin) и визуализация всего этого в Grafana.

✨ DevOps и развертывание — пайплайны в GitHub Actions, Docker и Docker Compose, оркестрация в Kubernetes, управление релизами через Helm.

🚀 Больше 30 технологий в одной линейке!

Успейте забрать курсы по суперцене до окончания акции! 💥

Читать полностью…

Java

Spring Boot 4: консольные логи теперь можно отключить одной настройкой.


logging:
console:
enabled: false

Полезно для продакшена и контейнеров, где логи уходят не в stdout, а, например, в файл или через OTLP.

При этом остальные способы логирования можно оставить:

• file appender
• удалённый сбор логов
• OTLP
• собственные appenders

Удобная мелочь, которая позволяет не городить отдельную конфигурацию Logback только ради отключения консоли.

Читать полностью…

Java

🚀 Spring Boot 4 упростил работу с MongoDB health checks

Теперь для проверки состояния MongoDB больше не нужен Spring Data.

Что изменилось:

- health indicators переехали в spring-boot-mongodb
- работают напрямую с MongoDB driver
- для /actuator/health достаточно spring-boot-starter-mongodb
- Spring Data подключать не обязательно

То есть если сервис работает с MongoDB напрямую через драйвер, health check всё равно можно получить без лишней зависимости.

Полезное изменение для более лёгких Spring Boot 4 сервисов.

Читать полностью…

Java

🖥 Java: почему 1.234,56 ломает Double.parseDouble()

В Java число - это не всегда просто строка с точкой.

Например:


Double.parseDouble("1.234,56");


закончится NumberFormatException.

Проблема в локали: в разных странах . и , означают разное.

Для таких случаев лучше использовать:


NumberFormat format =
NumberFormat.getInstance(Locale.ITALY);

Number value = format.parse("1.234,56");

double n = value.doubleValue();


Получим:


1234.56


Главное правило: если число пришло от пользователя, из CSV или внешней системы — сначала узнай его locale.

Иначе можно получить не только ошибку, но и тихо распарсить совсем не то число.

Читать полностью…

Java

🔥 Хочешь быстрее расти в IT? Хватит учиться в одиночку

Окружение решает больше, чем кажется.

Собрал папки и каналы, где можно быстрее влиться в нужное направление, следить за трендами и не вариться в своём пузыре.

AI: t.me/ai_machinelearning_big_data
Python: t.me/pythonl
Linux: t.me/linuxacademiya
Хакинг: t.me/linuxkalii
DevOps: t.me/DevOPSitsec
Docker: /channel/+90Z5TAyfuNU5YmRi
Golang: t.me/Golang_google
Rust: t.me/rust_code
C++: t.me/cpluspluc
C#: t.me/csharp_1001_notes
Java: t.me/javatg
JavaScript: t.me/javascriptv
React: t.me/react_tg
Frontend: t.me/front
PHP: t.me/phpshka
Android: t.me/android_its
Мобильная разработка: t.me/mobdevelop
Базы данных: t.me/sqlhub
Data Science: t.me/data_analysis_ml
Big Data: t.me/bigdatai
Математика: t.me/data_math
Физика: t.me/fizmat
Kubernetes: t.me/kubernetc
GameDev: /channel/gamedev
Haskell: t.me/haskell_tg

Собеседования и карьера:

DS собеседования: t.me/machinelearning_interview
Python собеседования: t.me/python_job_interview

Папка с вакансиями: t.me/addlist/_zyy_jQ_QUsyM2Vi
Папка Go разработчика: t.me/addlist/MUtJEeJSxeY2YTFi
Папка Python разработчика: t.me/addlist/eEPya-HF6mkxMGIy
Папка ML: /channel/addlist/2Ls-snqEeytkMDgy
Папка Frontend: /channel/addlist/mzMMG3RPZhY2M2Iy

Полезное сверху:

ИТ-мемы: t.me/memes_prog
Английский для программистов: t.me/english_forprogrammers
ИИ и технологии: t.me/vistehno
954 ГБ open-source курсов: /channel/+rKBQEMccAA01MTcy
ИТ-книги бесплатно: /channel/addlist/BkskQciUW_FhNjEy

Max Ai: https://max.ru/ai_machinelearning_big_data
Max python: https://max.ru/pythonl
ТЕХНО: https://max.ru/vistehno
Max Go: https://max.ru/Golang_google
Max Linux: https://max.ru/linuxkalii
Devops: https://max.ru/DevOPSitsec
C#: https://max.ru/csharp_ci
C++: https://max.ru/cpluspluc
SQL: https://max.ru/sqlhub
Java: https://max.ru/javatg

Подписывайся на нужные направления и собирай себе ленту, которая реально двигает вперёд.

Читать полностью…

Java

25 августа встречаемся на Agentic Coding Meetup в Сбер.Среде и в онлайне⚡️

AI-агенты уже умеют писать код. Но самое интересное начинается дальше — когда вместе с инструментами меняются роли инженеров, команды и сам процесс разработки.

🔥 Поговорим о том, как agentic coding выглядит на практике: новые инженерные роли и модели команд, SDD и трансформация процессов, coding-агенты и инструменты, подходы к постановке задач и управлению контекстом, а также опыт внедрения AI в разработку больших технологических компаний.

⏳ Начало в 17:00, встреча очных гостей — в 16:00.

Количество очных мест ограничено — успейте зарегистрироваться!

Читать полностью…

Java

☕️ В Spring Boot 4 появился новый JmsClient - более современная альтернатива привычному JmsTemplate.

Главное отличие - fluent API, из-за которого код отправки и получения сообщений становится заметно чище.

При этом JmsTemplate никуда не исчезает и продолжает работать без изменений.

Для старых проектов переписывать ничего не нужно, а для нового JMS-кода Spring теперь рекомендует смотреть в сторону JmsClient.

#SpringBoot4 #JMS

Читать полностью…

Java

☕ Java-баг, который выглядит нормально, но ломает `HashMap`

Что выведет этот код?


Map<List<Integer>, String> map = new HashMap<>();

List<Integer> key = new ArrayList<>(List.of(1, 2));

map.put(key, "Ritesh");

key.add(3);

System.out.println(map.get(key));


Многие ожидают:


Ritesh


Но результат:

```text
null
```

Почему?

HashMap ищет ключ через:

```java
hashCode()
equals()
```

Когда мы сделали:

```java
map.put(key, "Ritesh");
```

ключ был:

```text
[1, 2]
```

У него был один
hashCode.

Но потом:

```java
key.add(3);
```

ключ стал:

```text
[1, 2, 3]
```

И его
hashCode изменился.

HashMap уже положил объект в bucket по старому hash, а при get() ищет по новому.

Схема:

```text
put()

[1,2]
hash = X
↓
bucket X


key.add(3)

[1,2,3]
hash = Y


get()

ищем bucket Y
→ запись не найдена
```

Главное правило:

❌ Не изменяйте объект после того, как использовали его как ключ в
HashMap.

Лучше использовать:

✅
String
✅
Integer
✅
record
✅ immutable-объекты

Например:

```java
Map<List<Integer>, String> map = new HashMap<>();

List<Integer> key = List.of(1, 2);

map.put(key, "value");
```

Самые опасные баги в Java - те, где объект всё ещё существует, ссылка всё та же, но структура данных уже не может его нормально найти.

#java #backend #programming

Читать полностью…

Java

⚡️ Spring Boot 4: для интеграционных тестов REST лучше переходить с TestRestTemplate на RestTestClient.

Почему это удобнее:

- fluent API в стиле RestClient;
- одинаковый подход для тестов через MockMvc и реальный HTTP-порт;
- проще читать цепочки request → response → assertions;
- меньше привязки к старому TestRestTemplate.

Пример:


restTestClient.get()
.uri("/api/users/42")
.exchange()
.expectStatus().isOk()
.expectBody(User.class)
.value(user -> assertThat(user.id()).isEqualTo(42));


Если автоконфигурация не подтянулась автоматически, добавляем:


@AutoConfigureRestTestClient


Если начинаете новый проект на Boot 4, TestRestTemplate уже вряд ли стоит выбирать по привычке.

#SpringBoot4 #Java #RestTestClient #Testing

Читать полностью…

Java

☕️ Java-совет: `LongAdder` вместо `AtomicLong` для горячих счётчиков

Частая ошибка в высоконагруженных системах:


private final AtomicLong requests = new AtomicLong();

requests.incrementAndGet();


Проблема: все потоки конкурируют за одну переменную.

Много потоков → больше CAS-коллизий → меньше производительность.

Для метрик лучше:


private final LongAdder requests = new LongAdder();

requests.increment();


Как работает:


AtomicLong:

Thread 1 ─┐
Thread 2 ─┼──> [100000]
Thread 3 ─┘


LongAdder:

Thread 1 → [10]
Thread 2 → [20]
Thread 3 → [15]

↓
sum()


LongAdder распределяет обновления между несколькими ячейками памяти, снижая конкуренцию.

Идеально для:

✅ Prometheus metrics
✅ счётчиков запросов
✅ статистики JVM
✅ rate limiter

Но важно:


adder.sum()


не гарантирует точный атомарный снимок.

Используйте:

- LongAdder → метрики и статистика;
- AtomicLong → когда нужно точное значение.

Одна замена класса может заметно улучшить производительность под нагрузкой.

#java #jvm #performance

Читать полностью…

Java

✔️ Spring Boot 4 убрал Undertow - при миграции это легко пропустить

Причина простая: Spring Boot 4 перешёл на Servlet 6.1, а Undertow с этой версией Servlet API несовместим. Поэтому из Boot 4 удалили и поддержку embedded Undertow, и spring-boot-starter-undertow.

Если раньше было:


<artifactId>spring-boot-starter-undertow</artifactId>


теперь используйте Tomcat по умолчанию или подключайте Jetty:


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>


Ещё один важный момент: не разворачивайте Spring Boot 4 в старом Servlet-контейнере — требуется совместимость с Servlet 6.1.

Перед миграцией Boot 3 → 4 обязательно проверьте серверную часть приложения.

#SpringBoot4 #Java #Servlet

Читать полностью…

Java

Лето, ИТ-Пикник и музыка известных артистов уже через несколько дней!

8 августа в Коломенском пройдет ИТ-Пикник.

В программе — выступления проекта LAB Антона Беляева, IOWA, Cream Soda, Pompeya, мартина и Совы.

А днем — научпоп-лекции, дискуссии об ИИ и больших языковых моделях, мастер-классы и интерактивы. Полезные знакомства и развлечения тоже будут.

Зарегистрироваться и узнать подробности можно на сайте мероприятия.

В билет входит +1 — можно позвать близких и друзей.

До встречи в месте притяжения ИТ.

Читать полностью…
Subscribe to a channel