— JEP 522, авторы — Ivan Walulya и Thomas Schatzl, нацелен на реализацию в JDK 26; последнее обновление датировано 8 сентября 2025 года.
— Согласно дорожной карте JDK 26, окончательное рассмотрение этого JEP запланировано на 15 сентября 2025 года.
— Предложено снизить накладные расходы на синхронизацию между потоками приложения и сборщика мусора G1, сохранив существующую архитектуру и взаимодействие с пользователем.
— Ключевая идея — внедрение второй таблицы карточек (card table):
▪️ Потоки приложения работают с быстрой, простой, синхронно-нережимой "первой" таблицей
▪️ Потоки-оптимизаторы обрабатывают отдельную вторую таблицу
▪️ При необходимости G1 выполняет атомарный обмен таблицами, позволяя каждому потоку работать автономно и эффективно
— Производительность:
▪️ В сценариях с частыми изменениями ссылок в объектах — прирост производительности в диапазоне 5–15 %
▪️ Даже в менее интенсивных сценариях — прирост до 5 % за счёт упрощения write-барьеров (уменьшение с ~50 до ~12 инструкций на x64)
— Снижение пауз GC: более лёгкая структура таблиц карточек и менее громоздкая синхронизация сокращают продолжительность пауз сборщика мусора
— Дополнительная память:
▪️ Вторая таблица занимает ~0,2 % от кучи — порядка 2 МБ на каждый ГБ JVM-кучи
▪️ Несмотря на это, она заменяет более объёмные вспомогательные структуры и не увеличивает общий объём памяти заметно
#News
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥4❤1💯1
🎯 Как настроить аутентификацию с OAuth2
В Spring Boot 3 интеграция с OAuth2 стала ещё проще благодаря улучшенной поддержке социальных логинов. Рассмотрим, как настроить аутентификацию через Google с использованием Spring Security 6.
1️⃣ Создание проекта
Используйте Spring Initializr для создания проекта с следующими зависимостями:
— Spring Web
— Spring Security
— OAuth2 Client
Или добавьте их вручную в pom.xml:
2️⃣ Получение OAuth2-учётных данных Google
1. Перейдите в Google Cloud Console
2. Создайте новый проект
3. Перейдите в раздел APIs & Services → Credentials
4. Нажмите Create Credentials → OAuth 2.0 Client IDs
5. Укажите тип приложения Web application
6. Добавьте Authorized redirect URI
7. Сохраните и получите Client ID и Client Secret
3️⃣ Конфигурация application.yml
Добавьте следующие настройки в src/main/resources/application.yml:
Замените YOUR_CLIENT_ID и YOUR_CLIENT_SECRET на полученные значения.
4️⃣ Конфигурация безопасности
Создайте класс конфигурации:
🐸 Библиотека джависта
#Enterprise
В Spring Boot 3 интеграция с OAuth2 стала ещё проще благодаря улучшенной поддержке социальных логинов. Рассмотрим, как настроить аутентификацию через Google с использованием Spring Security 6.
Используйте Spring Initializr для создания проекта с следующими зависимостями:
— Spring Web
— Spring Security
— OAuth2 Client
Или добавьте их вручную в pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
1. Перейдите в Google Cloud Console
2. Создайте новый проект
3. Перейдите в раздел APIs & Services → Credentials
4. Нажмите Create Credentials → OAuth 2.0 Client IDs
5. Укажите тип приложения Web application
6. Добавьте Authorized redirect URI
7. Сохраните и получите Client ID и Client Secret
Добавьте следующие настройки в src/main/resources/application.yml:
spring:
security:
oauth2:
client:
registration:
google:
client-id: YOUR_CLIENT_ID
client-secret: YOUR_CLIENT_SECRET
scope:
- profile
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
authorization-grant-type: authorization_code
client-name: Google
provider:
google:
authorization-uri: https://accounts.google.com/o/oauth2/v2/auth
token-uri: https://oauth2.googleapis.com/token
user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo
user-name-attribute: sub
Замените YOUR_CLIENT_ID и YOUR_CLIENT_SECRET на полученные значения.
Создайте класс конфигурации:
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/login", "/error").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login()
.loginPage("/login")
.defaultSuccessUrl("/dashboard", true);
return http.build();
}
}
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍3🔥2🎉1
Anonymous Poll
36%
Да, если он глубоко понимает Java Core и архитектуру приложений
20%
Нет, современные фреймворки — неотъемлемая часть разработки
35%
Зависит от конкретного проекта и требований
9%
Не знаю, но интересно узнать мнение других
😁6💯1👾1
⚙️ Интеграция системы логирования с Logback в Spring Boot
Ищете, как настроить логирование в приложении на Spring Boot? Используйте Logback для эффективного логирования и управления уровнями логов. Используйте AI для ускорения процесса.
📝 Промпт:
💡 Расширения:
— Добавьте
— Добавьте
— Добавьте
🐸 Библиотека джависта
#CoreJava
Ищете, как настроить логирование в приложении на Spring Boot? Используйте Logback для эффективного логирования и управления уровнями логов. Используйте AI для ускорения процесса.
📝 Промпт:
Generate a logging system integration for a Spring Boot 3 application using Logback.
— Set up logback-spring.xml for flexible configuration of logging levels and appenders.
— Define rolling file appender to archive old log files based on size or date.
— Configure log format with PatternLayoutEncoder for structured and readable logs.
— Implement different logging levels (INFO, WARN, ERROR) for different components of the application.
— Integrate MDC (Mapped Diagnostic Context) for tracking user sessions or specific requests.
— Set up asynchronous logging with AsyncAppender to improve performance in high-traffic applications.
— Enable console logging for development and file logging for production environments.
— Добавьте
Set up rolling file appender for log rotation based on size or date
для архивирования старых логов.— Добавьте
Implement asynchronous logging with AsyncAppender
для улучшения производительности в высоконагруженных приложениях.— Добавьте
Integrate custom appenders for external monitoring systems like Elasticsearch or Splunk
для интеграции с внешними системами мониторинга.#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤2🔥1
🎧 Что послушать — #подкаст
🔹 Javaswag #80
Дата выпуска: 22 августа 2025
Ведущий: Дмитрий Волыхин
Гость: Илья Зонов, архитектор
Продолжительность: примерно 2 часа 6 минут
В выпуске обсуждают роль архитектора, подход API First, книгу Code of Architecture, жизненный баланс на высоких ставках, работу с Kafka и сериализацией, а также многие другие аспекты разработки и архитектуры в мире IT.
🔹 Ключевые темы выпуска
00:00 — Начало
06:03 — Linux и эмбеддед системы
12:57 — Проекты на Java
19:03 — Постгресс и банки
30:31 — PostgreSQL
34:55 — Бизнес-процессы
42:13 — Процесс разработки в малых и крупных компаниях
49:12 — Принятие решений в команде
55:16 — Work-life balance на высоких ставках
01:00:36 — Подход API First
01:14:23 — Роль архитектора и Kotlin
01:17:23 — Генерация клиентов
01:25:10 — Книжный клуб Code of Architecture
01:33:48 — Мотивация
01:40:45 — Чтение книг
01:47:29 — Инструменты для работы с текстом и заметками
01:55:10 — Vim и Emacs
01:56:52 — Ответ на предыдущее непопулярное мнение
02:01:35 — Готовность к изменениям
🔗 Слушать выпуск
🐸 Библиотека джависта
#DevLife
🔹 Javaswag #80
Дата выпуска: 22 августа 2025
Ведущий: Дмитрий Волыхин
Гость: Илья Зонов, архитектор
Продолжительность: примерно 2 часа 6 минут
В выпуске обсуждают роль архитектора, подход API First, книгу Code of Architecture, жизненный баланс на высоких ставках, работу с Kafka и сериализацией, а также многие другие аспекты разработки и архитектуры в мире IT.
🔹 Ключевые темы выпуска
00:00 — Начало
06:03 — Linux и эмбеддед системы
12:57 — Проекты на Java
19:03 — Постгресс и банки
30:31 — PostgreSQL
34:55 — Бизнес-процессы
42:13 — Процесс разработки в малых и крупных компаниях
49:12 — Принятие решений в команде
55:16 — Work-life balance на высоких ставках
01:00:36 — Подход API First
01:14:23 — Роль архитектора и Kotlin
01:17:23 — Генерация клиентов
01:25:10 — Книжный клуб Code of Architecture
01:33:48 — Мотивация
01:40:45 — Чтение книг
01:47:29 — Инструменты для работы с текстом и заметками
01:55:10 — Vim и Emacs
01:56:52 — Ответ на предыдущее непопулярное мнение
02:01:35 — Готовность к изменениям
#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥2❤1
Garbage Collector (GC) в Java — это механизм автоматического управления памятью, который отвечает за очистку памяти от объектов, которые больше не используются в программе. Вместо того, чтобы разработчик вручную освобождал память, как в некоторых других языках программирования, Java использует сборщик мусора, который делает это автоматически.
Когда вы создаёте объект в Java, он занимает место в куче (heap) — области памяти, предназначенной для динамического распределения. Однако по мере работы программы некоторые объекты становятся ненужными, и их можно удалить, чтобы освободить память для других задач. Это и есть основная задача GC — найти объекты, которые больше не используются, и освободить память.
1. Маркировка. На первом этапе система анализирует объекты в куче и помечает те, на которые существуют ссылки, то есть которые всё ещё могут быть использованы в программе. Эти объекты называют живыми.
2. Сборка мусора. После маркировки GC удаляет объекты, которые не были помечены как «живые». Эти объекты больше не используются в программе и могут быть безопасно удалены, а занимаемое ими пространство освобождается.
3. Компактизация (Compaction). Иногда после удаления объектов в куче остаются фрагменты пустой памяти. В этом случае GC может перемещать объекты, чтобы устранить фрагментацию и сделать память более сплошной. Это улучшает использование доступных ресурсов.
Java предлагает несколько типов сборщиков мусора, каждый из которых имеет свои особенности и подходит для разных сценариев:
— Serial GC: простой сборщик, использующий один поток для работы с памятью. Это может быть полезно в простых приложениях, но вызывает большие паузы в работе программы, что не подходит для сложных многозадачных приложений.
— Parallel GC: этот сборщик использует несколько потоков для работы, что ускоряет процесс очистки. Он подходит для многозадачных приложений и приложений с большими объемами данных, где важно минимизировать время пауз.
— CMS (Concurrent Mark-Sweep): сборщик мусора, который работает параллельно с основной программой, минимизируя паузы. Он использует несколько шагов для маркировки и уборки мусора, чтобы не блокировать выполнение приложения на долгое время.
— G1 (Garbage First): один из самых современных сборщиков мусора. Он фокусируется на минимизации времени пауз и дает разработчикам больше контроля над процессом. G1 отлично подходит для больших приложений с высоким уровнем взаимодействия.
Одним из главных аспектов работы GC является Stop-the-World пауза, когда приложение временно приостанавливается, чтобы сборщик мусора очистил память. Хотя паузы в большинстве случаев довольно короткие, они могут заметно повлиять на производительность, особенно в приложениях с высокими требованиями к времени отклика.
— Оптимизация размера кучи. Размер кучи можно настроить в зависимости от объема данных, с которым работает ваше приложение. Неправильно выбранный размер может привести к слишком частым или слишком редким сборкам мусора.
— Использование правильного сборщика. Выбор сборщика мусора зависит от особенностей вашего приложения. Например, для приложений с требованием низкой задержки лучше использовать G1 или CMS.
— Профилирование. Используйте инструменты профилирования, чтобы отслеживать, как работает GC в вашем приложении. Это поможет выявить проблемы и оптимизировать использование памяти.
— Когда ваше приложение работает с большим количеством объектов, и необходимо следить за производительностью.
— Если заметны задержки или паузы, вызванные работой GC, и нужно оптимизировать работу с памятью.
— В сложных многозадачных или распределённых приложениях, где важно, чтобы GC не блокировал выполнение других задач.
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤1🔥1👏1
🔥 Последняя неделя перед стартом курса по AI-агентам
Старт курса уже 15го числа! Если вы планировали вписаться — сейчас ПОСЛЕДНИЙ шанс забронировать место
На курсе:
— разложим LLM по косточкам: токенизация, SFT, PEFT, инференс
— соберём RAG и научимся оценивать его адекватно
— построим настоящую мультиагентную систему — архитектуру, которая умеет расти
— разберём CoPilot, сломаем через prompt injection (спасибо Максу)
— и наконец, посмотрим, как это работает в MCP и реальных кейсах
📍 Это 5 живых вебинаров + раздатка + домашки + чат с преподавателями
И главное — возможность реально разобраться, как проектировать системы на LLM, а не просто «поиграться с API»
Промокод на 5.000₽: LASTCALL
👉 Курс здесь
Старт курса уже 15го числа! Если вы планировали вписаться — сейчас ПОСЛЕДНИЙ шанс забронировать место
На курсе:
— разложим LLM по косточкам: токенизация, SFT, PEFT, инференс
— соберём RAG и научимся оценивать его адекватно
— построим настоящую мультиагентную систему — архитектуру, которая умеет расти
— разберём CoPilot, сломаем через prompt injection (спасибо Максу)
— и наконец, посмотрим, как это работает в MCP и реальных кейсах
📍 Это 5 живых вебинаров + раздатка + домашки + чат с преподавателями
И главное — возможность реально разобраться, как проектировать системы на LLM, а не просто «поиграться с API»
Промокод на 5.000₽: LASTCALL
👉 Курс здесь
❤1
Топ-3 статьи о Java за неделю по мнению нашего канала. Нововведения Java 25, паттерны кэширования для микросервисов и оптимизации сборки с помощью Maven.
PVS-Studio в своей статье подробно рассматривает нововведения в Java 25, включая новые API, улучшения синтаксиса и поддержку функционального программирования.
Cтоит отметить появление ScopedValue, который решает проблемы с ThreadLocal, а также возможность использования компактных исходных файлов и методов main.
В статье от OTUS рассматриваются пять основных паттернов кэширования, которые могут значительно повысить производительность микросервисов. Каждый паттерн, от Cache-Aside до Write-Back Cache, имеет свои особенности и сценарии применения.
Особенно рекомендую статью от Spring АйО. Всегда использовал mvn clean install, и, думаю, так делают многие из вас.
Статья посвящена вопросам оптимизации сборки проектов с использованием Maven. Также обсуждается, когда можно обойтись без clean install.
#News
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🎉2🔥1
Forwarded from Библиотека собеса по Java | вопросы с собеседований
Найдите длину наибольшей общей подпоследовательности (LCS) двух строк:
— Даны две строки A и B.
— Нужно найти длину наибольшей общей подпоследовательности между ними.
▪️ Условия
1. Строки могут быть длиной до 1000 символов.
2. Используйте динамическое программирование для решения.
3. Подсчитайте длину LCS.
— Используйте таблицу для хранения промежуточных результатов.
— Если символы в строках совпадают, то прибавляйте 1 к предыдущему значению. Если не совпадают — выбирайте максимум из предыдущих значений.
— Убедитесь, что алгоритм работает с большими строками за время O(n*m), где n и m — длины строк.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍2🔥1
Сплавляюсь сегодня по реке на каяке. Горы, кристально чистая вода, немного тишины и много свежего воздуха. Важно время от времени сделать паузу и немного отдохнуть от кода.
Как проходят ваши выходные? Отправляйте фото в комментарии👇🏻
#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
😍10👍5🔥3❤1🥰1
Хотите править код сразу в нескольких местах? Multi-Caret Editing позволяет поставить несколько курсоров и синхронно редактировать текст.
🔹 Что делает
— Позволяет редактировать одинаковые участки кода одновременно
— Ускоряет массовое переименование переменных, правки форматирования и шаблонных конструкций
— Работает не только в коде, но и в файлах конфигурации, JSON, XML
🔹 Зачем это нужно
— Экономит время при рутинных правках
— Снижает вероятность пропустить один из повторяющихся фрагментов
— Делает код-ревью и рефакторинг быстрее
🔹 Как использовать
— Выделите слово и нажмите Alt+J (Windows/Linux) или Ctrl+G (macOS) — добавится второй курсор
— Продолжайте нажимать, чтобы выбрать следующие вхождения
— Для выбора сразу всех вхождений используйте Ctrl+Alt+Shift+J
— Для произвольных позиций используйте Alt+Click для добавления курсора в нужное место
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2🔥2🤔2
Часто выбор коллекции ограничивается только таблицей сложностей и на этом всё.
Но реальный кейс сложнее: средняя сложность ≠ реальная скорость в продакшне. JVM, кэш процессора, GC и паттерны доступа могут радикально поменять картину.
🔑 Главная мысль
Выбирайте коллекцию под сценарий использования, а не “по самой быстрой ячейке в таблице”.
ArrayList хранит элементы в массиве → локальность памяти + CPU кэш → итерации летят.
Вставка в середину за O(n), но при небольших списках разница с LinkedList исчезающе мала.
🔧 Паттерн использования:
— 90% чтение, редкие вставки → идеально.
— Если заранее известно примерное кол-во элементов → задайте initialCapacity, иначе ArrayList будет несколько раз пересоздавать массив (copy O(n) на каждом росте).
В бенчмарках JMH даже при вставке в середину ArrayList часто быстрее LinkedList просто потому, что LinkedList платит за “pointer chasing” (скачки по памяти, cache-miss).
Да, вставка/удаление в начало или конец за O(1).
Но get(i) = O(n), и каждый шаг = новый объект, новая ссылка → нагрузка на GC.
🔧 Паттерн использования:
— Когда нужна двусторонняя очередь с частыми удалениями/добавлениями в начало и конец.
— Во всех остальных случаях лучше ArrayDeque, он без лишних объектов и быстрее почти всегда.
LinkedList ест больше памяти: на каждый элемент два указателя + объект-узел.
HashMap даёт O(1) доступ при хорошем hashCode().
Но:
— Если хэши “плохие” → коллизии → O(log n)
— При достижении load factor 0.75 → resize → перераспределение всех бакетов (дорогая операция).
🔧 Паттерн использования:
— Когда нужен быстрый поиск по ключу без сохранения порядка или когда важно хранить уникальные элементы или строить словари/кэши по ключу.
— Если знаете примерное кол-во элементов → сразу задайте кол-во элементов в конструкторе new HashMap<>(N).
Начиная с Java 8 при коллизии, когда LinkedList становится длинным (по умолчанию ≥ 8 элементов) → список превращается в красно-чёрное дерево.
Дают O(log n) доступ и всегда хранят ключи отсортированными.
Но если сортировка нужна редко, дешевле собрать HashMap и вызвать sorted() на стриме.
🔧 Паттерн использования:
— Когда важно поддерживать сортировку на каждой операции (напр. Top-N задач в приоритетной очереди).
— Не храните mutable-ключи, т.к. можно “потерять” элемент при изменении поля, участвующего в compareTo.
TreeMap хранит узлы с балансировкой (красно-чёрное дерево) → накладные расходы на память + сравнения ключей.
LinkedHashMap поддерживает порядок вставки или порядок доступа (accessOrder=true).
Можно сделать LRU-кэш, переопределив removeEldestEntry.
🔧 Паттерн использования:
— Когда важен порядок, но сортировка не нужна.
— Когда нужно легко реализовать ограниченный кэш.
Каждый get() в режиме accessOrder вызывает перестановку в двусвязном списке → небольшие накладные расходы.
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤5🔥3
Please open Telegram to view this post
VIEW IN TELEGRAM
😁28👍4💯4
🎯 Интеграционные тесты с Testcontainers
Пошаговая настройка тестов на Spring Boot 3 с Testcontainers + PostgreSQL: быстро, изолированно, воспроизводимо.
1️⃣ Зависимости (Maven/Gradle)
— Maven (pom.xml):
— Gradle (Kotlin DSL):
2️⃣ Включаем Testcontainers
C Spring Boot 3.1 контейнер можно подключить одной аннотацией без ручного прописывания spring.datasource.*.
3️⃣ Миграции для тестов (Flyway)
Положите миграции в src/test/resources/db/migration (отдельно от продовых — удобно для фикстур):
4️⃣ Ускоряем прогоны
▪️ Reusable containers (кэшируемый демон): добавьте в ~/.testcontainers.properties
и .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
Пошаговая настройка тестов на Spring Boot 3 с Testcontainers + PostgreSQL: быстро, изолированно, воспроизводимо.
— 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")
}
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 поднялись на контейнере
}
}
Положите миграции в src/test/resources/db/migration (отдельно от продовых — удобно для фикстур):
src/
└─ test/
└─ resources/
└─ db/
└─ migration/
├─ V1__init.sql
└─ V2__seed.sql
▪️ Reusable containers (кэшируемый демон): добавьте в ~/.testcontainers.properties
testcontainers.reuse.enable=true
и .withReuse(true) для контейнера в тесте.
▪️ Singleton-паттерн контейнера: вынесите контейнер в общий абстрактный класс теста, чтобы один контейнер работал на все тесты.
— Если на 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
🔥7👍3❤2
💎 Как работает String.intern() под капотом
Многие знают, что строки в Java «живут в пуле». Но что реально происходит, когда мы вызываем intern()?
1️⃣ Что такое String Pool
Java хранит все строковые литералы в специальной области памяти — String Intern Pool. Зачем? Чтобы одинаковые строки не занимали память несколько раз.
Обе ссылки указывают на одну и ту же строку из пула.
2️⃣ Как работает intern()
Если вызвать s.intern():
— JVM проверит, есть ли такая строка в пуле.
— Если есть, вернёт ссылку на неё.
— Если нет, добавит текущую строку в пул и вернёт ссылку.
Пример:
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
Многие знают, что строки в Java «живут в пуле». Но что реально происходит, когда мы вызываем intern()?
Java хранит все строковые литералы в специальной области памяти — String Intern Pool. Зачем? Чтобы одинаковые строки не занимали память несколько раз.
String a = "hello";
String b = "hello";
System.out.println(a == b); // true
Обе ссылки указывают на одну и ту же строку из пула.
Если вызвать 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
🔹 До Java 7 String Pool находился в PermGen → можно было легко словить OOM.
🔹 Начиная с Java 7 (HotSpot) пул перенесли в heap, что сильно упростило жизнь.
🔹 Реализация — ConcurrentHashMap внутри JVM, так что intern() потокобезопасен.
🔹 Оптимизация памяти при большом количестве одинаковых строк (например, при парсинге XML/JSON).
🔹 Сравнение строк через == (только если они гарантированно interned).
🔹 При работе с ключами в больших мапах, чтобы уменьшить дубли.
🔹 intern() не бесплатен — поиск в пуле и вставка стоят ресурсов.
🔹 Чрезмерное использование может привести к росту heap-а и GC-паузам.
🔹 Нельзя бездумно использовать вместо обычных строк → легко получить деградацию.
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🤔2🔥1
Чтобы вам было проще ориентироваться в постах, мы разделили весь контент по 4 основным направлениям:
🔹 #CoreJava — фундаментальные знания: JVM, JDK, ООП, многопоточность, паттерны и базовые концепции. Всё, что помогает понимать Java глубже, а не просто «писать код, чтобы работало».
🔹 #Enterprise — прикладные инструменты и практика: Spring, Hibernate, Kafka, Docker, микросервисы. Всё, что встречается в работе разработчика каждый день.
🔹 #DevLife — сообщество и карьера: мемы, холивары, задачи с собесов, советы по развитию и личные рубрики. Всё, что создаёт атмосферу и объединяет нас как комьюнити.
🔹 #News — дайджесты, свежие анонсы, релизы и новости. А также реклама и инфоповоды, которые стоит знать.
👉 Используйте теги, чтобы быстро находить посты по интересующей теме.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3👏1