Библиотека джависта | Java, Spring, Maven, Hibernate
23.7K subscribers
2.1K photos
45 videos
43 files
2.96K links
Все самое полезное для Java-разработчика в одном канале.

Список наших каналов: https://t.iss.one/proglibrary/9197

Для обратной связи: @proglibrary_feeedback_bot

По рекламе: @proglib_adv

РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
Download Telegram
🎯 Интеграционные тесты с Testcontainers

Пошаговая настройка тестов на Spring Boot 3 с Testcontainers + PostgreSQL: быстро, изолированно, воспроизводимо.

1️⃣ Зависимости (Maven/Gradle)

— Maven (pom.xml):
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>1.20.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
</dependencies>


— Gradle (Kotlin DSL):
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
testImplementation("org.flywaydb:flyway-core")
testImplementation("org.postgresql:postgresql")
testImplementation(platform("org.testcontainers:testcontainers-bom:1.20.3"))
testImplementation("org.testcontainers:junit-jupiter")
testImplementation("org.testcontainers:postgresql")
}


2️⃣ Включаем Testcontainers

C Spring Boot 3.1 контейнер можно подключить одной аннотацией без ручного прописывания spring.datasource.*.
@Testcontainers
@ExtendWith(SpringExtension.class)
@SpringBootTest
class PostgresIT {

@Container
@ServiceConnection // Spring сам подставит URL/логин/пароль в DataSource
static PostgreSQLContainer<?> postgres =
new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("app")
.withUsername("app")
.withPassword("secret");

@Test
void contextLoads() {
// проверяем, что контекст и datasource поднялись на контейнере
}
}


3️⃣ Миграции для тестов (Flyway)

Положите миграции в src/test/resources/db/migration (отдельно от продовых — удобно для фикстур):
src/
└─ test/
└─ resources/
└─ db/
└─ migration/
├─ V1__init.sql
└─ V2__seed.sql


4️⃣ Ускоряем прогоны

▪️ Reusable containers (кэшируемый демон): добавьте в ~/.testcontainers.properties
testcontainers.reuse.enable=true

и .withReuse(true) для контейнера в тесте.

▪️ Singleton-паттерн контейнера: вынесите контейнер в общий абстрактный класс теста, чтобы один контейнер работал на все тесты.

5️⃣ Полезные трюки и подводные камни

— Если на MacOS/Colima, проверьте доступность Docker API (docker info) перед тестами.
— Для детерминизма фиксируйте теги образов (например, postgres:16-alpine), не latest.
— Логи контейнеров доступны: postgres.followOutput(...) — удобно для диагностики нестабильных тестов.
— Если нужен R2DBC: поднимайте Postgres как выше, а в application-test.yml указывайте r2dbc URL; @ServiceConnection корректно сконфигурирует оба коннектора, если они в classpath.
— Тяжёлые фикстуры → создавайте через SQL-маски (V*_seed.sql) или @Sql прямо в тестах — не смешивайте тестовые данные с продовыми миграциями.

🐸 Библиотека джависта

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍32
💎 Как работает String.intern() под капотом

Многие знают, что строки в Java «живут в пуле». Но что реально происходит, когда мы вызываем intern()?

1️⃣ Что такое String Pool

Java хранит все строковые литералы в специальной области памяти — String Intern Pool. Зачем? Чтобы одинаковые строки не занимали память несколько раз.
String a = "hello";
String b = "hello";
System.out.println(a == b); // true


Обе ссылки указывают на одну и ту же строку из пула.

2️⃣ Как работает intern()

Если вызвать s.intern():

— JVM проверит, есть ли такая строка в пуле.
— Если есть, вернёт ссылку на неё.
— Если нет, добавит текущую строку в пул и вернёт ссылку.

Пример:
String x = new String("world");
String y = x.intern();
String z = "world";

System.out.println(x == z); // false
System.out.println(y == z); // true


3️⃣ Под капотом JVM

🔹 До Java 7 String Pool находился в PermGen → можно было легко словить OOM.
🔹 Начиная с Java 7 (HotSpot) пул перенесли в heap, что сильно упростило жизнь.
🔹 Реализация — ConcurrentHashMap внутри JVM, так что intern() потокобезопасен.

4️⃣ Где это полезно

🔹 Оптимизация памяти при большом количестве одинаковых строк (например, при парсинге XML/JSON).
🔹 Сравнение строк через == (только если они гарантированно interned).
🔹 При работе с ключами в больших мапах, чтобы уменьшить дубли.

5️⃣ Подводные камни

🔹 intern() не бесплатен — поиск в пуле и вставка стоят ресурсов.
🔹 Чрезмерное использование может привести к росту heap-а и GC-паузам.
🔹 Нельзя бездумно использовать вместо обычных строк → легко получить деградацию.

🔗 Документация: String.intern()

💬 Использовали когда-нибудь intern() в продакшене?

🐸 Библиотека джависта

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍63🤔2🔥1
📌 Как пользоваться тегами в канале

Чтобы вам было проще ориентироваться в постах, мы разделили весь контент по 4 основным направлениям:

🔹 #CoreJava — фундаментальные знания: JVM, JDK, ООП, многопоточность, паттерны и базовые концепции. Всё, что помогает понимать Java глубже, а не просто «писать код, чтобы работало».

🔹 #Enterprise — прикладные инструменты и практика: Spring, Hibernate, Kafka, Docker, микросервисы. Всё, что встречается в работе разработчика каждый день.

🔹 #DevLife — сообщество и карьера: мемы, холивары, задачи с собесов, советы по развитию и личные рубрики. Всё, что создаёт атмосферу и объединяет нас как комьюнити.

🔹 #News — дайджесты, свежие анонсы, релизы и новости. А также реклама и инфоповоды, которые стоит знать.

👉 Используйте теги, чтобы быстро находить посты по интересующей теме.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥3👏1
Библиотека джависта | Java, Spring, Maven, Hibernate pinned «📌 Как пользоваться тегами в канале Чтобы вам было проще ориентироваться в постах, мы разделили весь контент по 4 основным направлениям: 🔹 #CoreJava — фундаментальные знания: JVM, JDK, ООП, многопоточность, паттерны и базовые концепции. Всё, что помогает…»
💬 Расскажите о странной или забавной таске?

🐸 Библиотека джависта

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
😁152💯2
🚀 Релиз Java 25

Сегодня, 16 сентября 2025 года, вышла Java 25, новая версия с долгосрочной поддержкой (LTS). Выпуск включает 18 JEP'ов, среди которых как стабильные, так и экспериментальные и предварительные.

🔹 Полезные новшества:

— JEP 502: Stable Values. Введение нового типа для неизменяемых объектов с отложенной инициализацией.

— JEP 505: Structured Concurrency. Упрощение работы с многозадачностью.

— JEP 506: Scoped Values. Новый способ передачи неизменяемых данных между потоками.

— JEP 513: Flexible Constructor Bodies. Упрощение написания конструктора с кодом до вызова родительского конструктора.

🔹 Не очень важные:


— JEP 512: Compact Source Files. Убирает необходимость в public static void main(String[] args) — интересно только для скриптов и быстрых утилит.

— JEP 511: Module Import Declarations. Упрощение импорта классов и интерфейсов из модулей, хотя это и так на себя берёт IDE.

— JEP 470: PEM Encodings of Cryptographic Objects. Нужно для специфических криптографических нужд, но для большинства проектов — не критично.

— JEP 510: Key Derivation Function API. Обеспечивает работу с производными ключами, но для большинства приложений не станет приоритетом.

— JEP 521: Generational Shenandoah. Улучшения в сборщике мусора для специфических сценариев — для обычных проектов изменения не значительны.

🐸 Библиотека джависта

#News
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥31👏1
💬 Удалёнщики + в комменты

🐸 Библиотека джависта

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
😁26👍3🔥1
⚙️ Byteman

Byteman — это фреймворк для «инъекций» в байткод во время выполнения. Он позволяет менять поведение Java-программ без пересборки и изменения исходного кода.

📌 Фичи:

— Правила-инъекции на DSL (можно подмешать логику в любой метод).
— Удобен для тестирования сложных сценариев (например, эмуляция исключений или задержек).
— Поддержка динамической подгрузки/удаления правил без перезапуска приложения.
— Используется для отладки, тестирования отказоустойчивости и профилирования.

💡 Особенно полезен, когда нужно воспроизвести «трудноуловимый баг» или проверить поведение системы под нестандартными условиями.

🔗 Byteman

🐸 Библиотека джависта

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍31
Ваше идеальное место работы? Обсудим в комменты + и - каждого
Anonymous Poll
19%
Офис с печеньками
74%
Дома в тишине
6%
Уютный коворкинг/кафе
1%
Свой вариант в комменты
👍3🔥3😁2
🔍 Просто о сложном: ORM в Java

ORM (Object-Relational Mapping) — это мост между объектами Java и реляционными базами данных. Вместо того, чтобы писать SQL-запросы руками, вы работаете с привычными объектами и методами.

🔹 Зачем нужен ORM

В Java идет работа с классами, полями, методами. В базе данных всё хранится в виде таблиц, строк и столбцов. ORM выступает «переводчиком»:

— Таблица ↔️ Класс
— Строка ↔️ Объект
— Столбец ↔️ Поле

ORM берёт на себя «грязную работу»:

1. При создании объекта в коде (new User("Alex")) и вызове save(), ORM формирует SQL-запрос INSERT INTO users (name) VALUES ('Alex') и отправляет его в базу.

2. Когда вы хотите достать данные (userRepository.findById(1)), ORM делает SELECT * FROM users WHERE id=1, создаёт объект User и наполняет его полями из результата запроса.

3. Если вы меняете поле (user.setName("Ivan")) и сохраняете, ORM сгенерирует UPDATE users SET name='Ivan' WHERE id=1.

4. Если объект больше не нужен и вы вызываете delete(), ORM сформирует DELETE FROM users WHERE id=1.

То есть вы оперируете объектами и методами, а ORM переводит ваши действия в SQL и обратно.

🔹 Плюсы ORM


— Меньше шаблонного кода. Не нужно постоянно писать INSERT, SELECT, UPDATE.

— Более читаемо. Идет работа с методами вроде userRepository.findByEmail(), а не с SQL запросами.

— Кросс-СУБД. ORM умеет подстраиваться под разные базы (PostgreSQL, MySQL, Oracle).

— Интеграция. Легко комбинируется со Spring и другими фреймворками.

🔹 Минусы ORM

— Иллюзия простоты. Кажется, что можно забыть про SQL, но «под капотом» всё равно генерируются запросы.

— Проблема N+1. Частая ошибка, когда ORM делает сотни мелких запросов вместо одного «жирного».

— Сложные кейсы. Для тяжёлой аналитики или оптимизации всё равно пишут чистый SQL или хранят процедуры.

— Производительность. ORM добавляет прослойку, которая может стать узким местом при больших нагрузках.

🔹 Типичные ловушки ORM

— Ленивая загрузка (Lazy Loading). Может неожиданно тянуть данные из БД в середине транзакции.

— Кэширование. ORM кэширует объекты, но если работать невнимательно, то легко получить «старые» данные.

— Транзакции. Многие забывают, что ORM не волшебная палочка: без грамотной работы с транзакциями данные могут остаться в полупрозрачном состоянии.

🔹 Основные инструменты в Java

— JPA (Java Persistence API). Стандарт, описывающий, как именно должны работать ORM-инструменты.

— Hibernate. Самый популярный провайдер JPA, фактический стандарт в экосистеме Java.

— EclipseLink, OpenJPA. Альтернативные реализации, реже используемые.

— Spring Data JPA. Надстройка над JPA, позволяющая писать репозитории и автогенерировать запросы из названий методов.

🔹 ORM или не ORM

✔️ ORM полезен, если:

— Приложение типовое (CRUD, REST API, веб-сервисы)
— Важна скорость разработки и поддерживаемость
— Команда не хочет тратить часы на ручные SQL-запросы

ORM мешает, если:

— Высоконагруженная система с миллионами записей
— Важен каждый миллисекундный отклик
— Есть сложная аналитика или отчёты (там SQL быстрее и прозрачнее)

📌 Итог

ORM — это «помощник», а не замена знаний SQL. Он снимает рутину и ускоряет разработку, но требует грамотного использования. Понимать, что происходит «под капотом», — ключ к тому, чтобы не наступать на грабли.

🐸 Библиотека джависта

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍96🔥2
Чек-лист по Spring Boot профилям

Чтобы не путаться в окружениях и не тащить dev в прод 🚨 — держите компактный список best practices.
Карточка для сохранения👆🏻

🐸 Библиотека джависта

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥31👾1
This media is not supported in your browser
VIEW IN TELEGRAM
📅 24 сентября в 19:00 МСК — бесплатный вебинар с Максимом Шаланкиным.

Тема: «ИИ-агенты: новая фаза развития искусственного интеллекта».

🔹 Почему все говорят про ИИ-агентов и куда вливаются миллиарды инвестиций.
🔹 Чем они отличаются от ChatGPT и обычных ботов.
🔹 Как работает цикл агента: восприятие → планирование → действие → обучение.
🔹 Живое демо простого агента.
🔹 Потенциал для бизнеса: автоматизация процессов и ROI до 80%.

Не придёшь — будешь потом рассказывать, что «агенты — это как чат-боты», и ловить косые взгляды от коллег 😏

👉 Регистрируйтесь через форму на лендинге
😢31
⚙️ Наблюдаемость и метрики с Micrometer

Spring Boot из коробки интегрируется с Micrometer, позволяя собирать метрики и отправлять их в Prometheus, Grafana или другие системы мониторинга. Чтобы быстро поднять стек наблюдаемости — подключаем AI.

📝 Промпт:

Generate an observability integration for a Spring Boot 3 application using Micrometer and Prometheus.

— Enable Micrometer metrics in a Spring Boot application.
— Configure PrometheusMeterRegistry for collecting application metrics.
— Expose /actuator/prometheus endpoint for Prometheus scraping.
— Add custom application metrics using MeterRegistry (timers, counters, gauges).
— Configure histograms for REST API response times.
— Integrate Micrometer with Logback for unified metrics and logging.
— Enable health checks with Spring Boot Actuator (disk space, DB, cache).
— Set up Grafana dashboards for visualizing metrics and alerts.


💡 Расширения:

— Добавьте Enable Distributed Tracing with OpenTelemetry для отслеживания запросов в распределённых системах.
— Добавьте Configure Grafana Alertmanager integration для настройки алертов и уведомлений.
— Добавьте Implement custom business metrics (e.g. orders per minute) для отслеживания доменных метрик приложения.

🐸 Библиотека джависта

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥21
🆕 Java Digest: Spring Security, распределённый обмен событиями и трейсинг под нагрузкой

Топ-3 статьи о Java и сопутствующих технологиях за неделю по мнению нашего канала.

1️⃣ Spring Security для начинающих

Рекомендую хорошее читабельное введение в Spring Security.

Это не просто обзор API, а систематизированный конспект, где наглядно разобраны ключевые механизмы: фильтры, аутентификация, авторизация, отличие stateful/stateless сценариев, CSRF-защита и работа с JWT.

2️⃣ Обмен событиями распределённого приложения

Реализация системы сообщений между экземплярами сервисов через общую базу данных: секционированная таблица, блокировки, планирование партиций, минимальное использование внешних систем типа Kafka/JMS.

3️⃣ Трейсинг в hh.ru

Реальный кейс построения observability / tracing-системы при росте нагрузки. Здесь и сравнение стека (Zipkin, Jaeger, ClickHouse и др.), и как решать проблемы с семплированием без потери критичных данных.

💬 Пишите, понравилась ли подборка?

🐸 Библиотека джависта

#News
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍1🔥1
⚡️ Бесплатный вебинар — ИИ-агенты: новая фаза развития AI

24 сентября в 19:00 МСК состоится бесплатный вебинар с Максимом Шаланкиным — Data Science Team Lead в финтех-команде MWS, а познакомиться с ним ближе можно в его тг-канале.

Тема:
«ИИ-агенты: новая фаза развития искусственного интеллекта».


На вебинаре разберёмся, почему агенты — это следующий шаг после ChatGPT, чем они отличаются от обычных моделей и как уже приносят бизнесу ROI до 80%. А дальше я покажу, как эта тема ложится в наш курс по ИИ-агентам, который разработан под руководством Никиты Зелинского.

Подробности рассказываем в гс выше — включай, чтобы не пропустить.
👍2
Что делает аннотация @Entity?

Аннотация используется для обозначения класса как сущности, которая будет сопоставлена с таблицей в базе данных при использовании JPA (Java Persistence API). Класс, помеченный этой аннотацией, становится частью модели данных, и каждый его экземпляр будет соответствовать строкам в базе данных. Также важно, чтобы такой класс имел конструктор без параметров и корректно определял идентификатор сущности с помощью аннотации @Id.

🐸 Библиотека собеса по Java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍123🔥2
🎁 Задача на дизайн: сервис подарков

На выходных можно подумать о высоком и попрактиковать дизайн систем. Полезно для будущих собесов, а кому-то просто для тренировки. В реальной задаче функциональные и нефункциональные требования ещё нужно было бы уточнить, но в формате поста сразу добавили их.

🔹 Условие

Перед днём рождения коллеги выбирается ответственный, ему скидывают деньги, он что-то покупает, а потом надо решать, что делать со сдачей. Сервис должен:

— Позволять зарегистрированным пользователям скидываться в общую «копилку»
— Хранить средства до момента покупки
— Дать возможность выбрать товары из каталога маркетплейса
— После закрытия копилки — потратить средства на выбранное и вернуть остаток кэшбеком

🔹 Функциональные требования

— Создание и управление «копилкой»
— Пополнение копилки разными пользователями
— Привязка к каталогу и корзине маркетплейса
— Сценарий покупки и списания денег
— Возврат сдачи кэшбеком
— Уведомления участников о статусе

🔹 Нефункциональные требования

— До 200k DAU, всего ~1 млн пользователей
— Запуск MVP в течение квартала
— Масштабируемость под рост аудитории
— Интеграция с существующими сервисами: биллинг, пользователи, каталог, кэшбек, логистика
— SLA: быстрый отклик API (≤200 мс), отказоустойчивость, логирование

💡 Подсказки

— Если нужно уточнить какие-то вопросы: можете писать в комментарии, расширим вводные
— Подумайте о жизненном цикле копилки: создание → пополнение → покупка → возврат остатка → архив
— Разбейте на сущности: User, GiftPool, Contribution, Order, Refund
— Продумайте API: создание копилки, пополнение, список участников, закрытие, возврат
— Учтите рост нагрузки: кеширование, асинхронные процессы (например, списания)
— Не забудьте про безопасность: кто имеет право закрыть копилку и инициировать возврат

💬 Делитесь вашими результатами в комментариях. Можно развернуть жаркие дебаты о плюсах и минусах разных решений.

🐸 Библиотека джависта

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍21