javaproglib | Unsorted

Telegram-канал javaproglib - Библиотека джависта | Java, Spring, Maven, Hibernate

25698

Все самое полезное для Java-разработчика в одном канале. Список наших каналов: https://t.me/proglibrary/9197 Обратная связь: @proglibrary_feedback_bot По рекламе: @proglib_adv Прайс: @proglib_advertising

Subscribe to a channel

Библиотека джависта | Java, Spring, Maven, Hibernate

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

📨 Transactional Outbox c AI

Сценарий: сохранил сущность, опубликовал событие в Kafka, транзакция откатилась — событие уже ушло. Или наоборот: транзакция прошла, Kafka недоступна — событие потеряно.

Outbox Pattern решает это на уровне архитектуры. Промпт:

Ты Senior Java-разработчик. Сгенерируй реализацию Transactional Outbox Pattern для Spring Boot.

Требования:
- Сущность OutboxEvent: id (UUID), aggregateType, aggregateId, eventType,
payload (JSONB), createdAt, processedAt, status (PENDING/PROCESSED/FAILED)
- OutboxEventPublisher: сохраняет событие в той же транзакции что и бизнес-данные
- OutboxPoller: @Scheduled, читает PENDING-события, публикует в Kafka
- SELECT FOR UPDATE SKIP LOCKED при выборке — объясни зачем в комментарии
- @Transactional(propagation = REQUIRES_NEW) на polling-методе
- Flyway-миграция для таблицы

Стек: Java 21, Spring Boot 3.2, Spring Kafka, PostgreSQL, Flyway

Верни код сущности, репозитория, сервисов, SQL-миграцию, конфиг Kafka.


══════ Навигация ══════
ВакансииЗадачиСобесы

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

#Enterprise

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

Библиотека джависта | Java, Spring, Maven, Hibernate

✌🏻 У нас две новости — хорошая и плохая!

Хорошая: Ваших знаний, скорее всего, хватит, чтобы собрать рабочую демку AI-агента в Colab. 🫡

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

Для защиты от таких сценариев мы полностью пересобрали курс «Разработка AI-агентов». Теперь внутри плотная работа с экономикой ресурсов, дебаг через time-travel в LangGraph, извлечение данных из кривых сканов для RAG и комплаенс по 152-ФЗ.

Если всё ещё сомневаетесь, послушайте голосовое от спикера курса Влада Прошинского, где он объясняет, как правильно тестировать агентов перед релизом.


Программа курса, полный состав спикеров и другие подробности 👈🏻

ВАЖНО! До 5 апреля на курс действует скидка, но свободные места могут закончиться раньше.

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

Библиотека джависта | Java, Spring, Maven, Hibernate

🎁 Паттерн Decorator

Decorator — структурный паттерн, который добавляет объектам новое поведение, оборачивая их в объекты-обёртки. Альтернатива наследованию, когда комбинаций поведения много и они меняются в рантайме.

Использование

🔹 Когда нужно добавить поведение объекту, не меняя его класс и не трогая остальные объекты.
🔹 Когда наследование порождает взрывной рост классов из-за комбинаций поведений.
🔹 Когда поведение нужно добавлять и убирать динамически в рантайме.

Преимущества

1️⃣ Гибкость комбинирования поведений

Каждый декоратор делает одно дело. Нужно кеширование + логирование + метрики? Оборачиваете в три слоя в любом порядке. Не нужны метрики — просто не добавляете этот слой.

2️⃣ Единая ответственность

Кеширование живёт в одном классе, логирование — в другом. Каждый декоратор легко читать, тестировать и заменять независимо.

3️⃣ Прозрачность для клиента

Декоратор реализует тот же интерфейс, что и оригинал. Клиентский код не знает, с чем работает — с оригиналом или с обёрткой.

⚠️ Порядок декораторов имеет значение. Метрики снаружи кеша видят кеш-хиты корректно. Метрики внутри — не видят их вообще.

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#CoreJava

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

Библиотека джависта | Java, Spring, Maven, Hibernate

🖥 JDK 21 или 25, что выбрать новичку

Вышла Java 25, которую все хотят попробовать. Но ставить ли её или взять проверенную Java 21 LTS?

В этом гайде — пошаговая установка Java на Windows с картинками, разбор различий между версиями, настройка JAVA_HOME и PATH.

Ориентирован для начинающих разработчиков, изучающих Java

🔗 Читайте в статье

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#Enterprise

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

Библиотека джависта | Java, Spring, Maven, Hibernate

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

👑 IntelliJ IDEA: Evaluate Expression

Открывается через Run → Evaluate Expression или Alt + F8 (Option + F8 на macOS).

🔹 Что это вообще такое


Небольшое окно с полем ввода, в котором можно написать любое Java-выражение и мгновенно получить результат. Код выполняется в контексте текущего фрейма — видны все локальные переменные, this, поля класса.

🔹 Примеры из реальной жизни


▪️ Вызов метода на живом объекте

userService.findById(42L)

Не нужно писать тест — просто вызываете метод и смотрите, что он реально вернёт с текущими данными в БД.

▪️ Проверка сложного условия
order.getItems().stream()
.anyMatch(i -> i.getPrice().compareTo(BigDecimal.ZERO) < 0)

Подозреваете, что в заказе есть товары с отрицательной ценой? Проверяете прямо сейчас, не добавляя логов.

▪️ Изменение переменной на лету

user.setRole(Role.ADMIN)

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

▪️ Десериализация или парсинг

objectMapper.writeValueAsString(response)

Получаете красивый JSON из объекта прямо в дебаггере — удобно проверить, что именно уйдёт клиенту.

🔹 Продвинутые трюки

— В окне Evaluate есть переключатель с однострочного режима на Code Fragment — там можно писать многострочный код с переменными, условиями и циклами.

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

⚠️ Evaluate выполняет код реально — если вызовете метод с side-effect (запись в БД, отправка события), это произойдёт по-настоящему.

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#CoreJava

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

Библиотека джависта | Java, Spring, Maven, Hibernate

😱 Если ваш продукт не умеет отдавать данные в формате, понятном AI-агенту, то вас просто не существует

Скрипт не будет кликать по красивым кнопкам в браузере, он уйдёт к конкуренту с нормальным API. Перестроить архитектуру под машинных клиентов — это уже не хайп, а необходимое условие сохранения конкурентоспособности.

Как адаптировать продукт и не исчезнуть из выдачи:

— интегрировать MCP и A2A-взаимодействие, чтобы агенты могли вас читать;
— научиться контролировать стоимость (лимиты, кэш, роутинг между моделями);
— настроить AgentOps: трейсинг, логирование и отлов регрессий.

Всё это ждёт вас на обновлённом курсе «Разработка AI-агентов». Мы специально сделали фокус на утилитарном инжиниринге и production-ready решениях.

Кстати, до 29 марта можно забрать курс с большой скидкой, и стоит поторопиться — мест на потоке всё меньше.

Зафиксировать цену и начать деплоить агентов без слива бюджета 👈

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

Библиотека джависта | Java, Spring, Maven, Hibernate

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

😮 Топ-вакансий для джавистов за неделю

Java Developer - офис (Санкт-Петербург)

Middle (Middle+) Backend Developer - офис (Санкт-Петербург)

Middle/Senior Java Developer - офис (Москва)

➡️ Еще больше топовых вакансий — в нашем канале Java jobs

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

Библиотека джависта | Java, Spring, Maven, Hibernate

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

🧵 StampedLock: когда ReentrantReadWriteLock уже не справляется

Если знаком с ReentrantReadWriteLock, то знаешь идею: много читателей одновременно, но запись эксклюзивна. Звучит разумно, но у этой модели есть фундаментальная проблема: читатели блокируют писателей.

Поток, который хочет писать, ждёт пока все читатели закончат. При высокой read-нагрузке писатель может ждать очень долго. StampedLock решает именно это.

🔵 Три режима, не два

ReentrantReadWriteLock даёт два режима — read и write. StampedLock добавляет третий — optimistic read.

StampedLock lock = new StampedLock();

// обычный read lock
long stamp = lock.readLock();
try {
// читаем
} finally {
lock.unlockRead(stamp);
}

// write lock
long stamp = lock.writeLock();
try {
// пишем
} finally {
lock.unlockWrite(stamp);
}


Это знакомо. Но вот где начинается интересное:
long stamp = lock.tryOptimisticRead();
// читаем данные без блокировки вообще
int value = this.value;

if (!lock.validate(stamp)) {
// кто-то писал пока мы читали — перечитываем под реальным локом
stamp = lock.readLock();
try {
value = this.value;
} finally {
lock.unlockRead(stamp);
}
}

tryOptimisticRead() не захватывает никакого лока, а просто возвращает штамп. validate() проверяет — была ли запись с момента получения штампа. Если нет, то данные консистентны, идём дальше, если да, то фолбэк на обычный read lock.

🔵 Что такое stamp

Это long, который кодирует состояние лока. Каждая успешная запись инвалидирует все оптимистичные штампы. Поэтому validate() — это просто битовая проверка, без CAS, без синхронизации, так что она очень дешёвая.

🔵 Где это реально даёт профит

Сценарий: данные читаются в 95% случаев, пишутся редко. Классический пример — кеш, конфигурация, счётчики с инкрементом.
С ReentrantReadWriteLock все читатели всё равно захватывают shared lock — это операция на AQS, есть накладные расходы. С StampedLock + optimistic read при отсутствии конкурентных записей блокировки нет вообще.

🔵 Подводные камни

— StampedLock не реентерабельный. Если поток захватил write lock и попытается захватить его снова — дедлок. Это принципиальное отличие от ReentrantReadWriteLock.

— Нет поддержки Condition. Если тебе нужен await/signal — StampedLock не подойдёт.

— Нет поддержки прерывания в обычных методах readLock()/writeLock(). Есть отдельные readLockInterruptibly() — но это уже осознанный выбор.

StampedLock — инструмент для конкретного профиля нагрузки: много чтений, редкие записи, нет реентерабельности. Не замена всем локам подряд. Но в правильном месте даёт ощутимый прирост без усложнения архитектуры.

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#CoreJava

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

Библиотека джависта | Java, Spring, Maven, Hibernate

👑 IntelliJ IDEA: продвинутый дебаг

Представь, что есть цикл на 10 000 элементов, и баг воспроизводится только на одном конкретном объекте. Без Conditional Breakpoints придется жать F8 вручную сотни раз. А с ними дебаггер сам остановится в нужный момент.

🔹 Как включить


Кликни правой кнопкой на кружок брейкпоинта → появится поле Condition. Введите любое булево Java-выражение. Всё, дебаггер будет останавливаться только когда оно true.

🔹 Примеры из реальной жизни

▪️ Фильтрация по ID

user.getId() == 42

Останавливаемся только на конкретном пользователе — удобно при обработке списка сущностей из БД.

▪️ Фильтрация по содержимому строки
request.getUrl().contains("/admin")

Отлавливаем только определённые HTTP-запросы в фильтре или интерцепторе.

▪️ Ловим NPE до того, как он случился
order.getItems() == null

Останавливаемся именно тогда, когда данные уже сломаны, а не после падения.

▪️ Условие по индексу в цикле
i == 999

Прыгаем сразу к последней итерации, не прокручивая весь цикл.

🔹 Продвинутые трюки

— Log message вместо остановки. Если не хотите прерывать выполнение, а просто логировать — в том же окне брейкпоинта включите "Evaluate and log" и введите выражение.

— Pass count. Чуть ниже в настройках брейкпоинта есть поле "Pass count" — брейкпоинт сработает только на N-м попадании.

— Disable until hit. Можно настроить цепочку: один брейкпоинт активирует другой. В настройках есть "Disable until breakpoint is hit" — указываете другой брейкпоинт, и текущий начнёт работать только после срабатывания того.

⚠️ Condition вычисляется на каждом попадании в брейкпоинт — это вызов на стороне JVM. В горячих местах (tight loop, высоконагруженный метод) это может заметно тормозить приложение.

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#CoreJava

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

Библиотека джависта | Java, Spring, Maven, Hibernate

✔️ Java-тест: кэш убивает прод под нагрузкой

Метрики норм, тесты зелёные, при пике трафика — БД ложится 👇

📦 Задание — code review

Сервис отдаёт профили пользователей. Для ускорения добавили кэш на 5 минут.

@Service
@RequiredArgsConstructor
public class UserProfileService {

private final UserRepository userRepository;
private final RedisTemplate<String, UserProfile> redisTemplate;

private static final Duration TTL = Duration.ofMinutes(5);

public UserProfile getProfile(Long userId) {
String key = "profile:" + userId;

UserProfile cached = redisTemplate.opsForValue().get(key);
if (cached != null) {
return cached;
}

UserProfile profile = userRepository.findById(userId)
.map(UserProfile::from)
.orElseThrow(UserNotFoundException::new);

redisTemplate.opsForValue().set(key, profile, TTL);
return profile;
}
}


▪️ Объясни

— Что именно происходит при истечении TTL под нагрузкой.
— Почему добавление @Cacheable над методом не спасёт ситуацию.

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise

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

Библиотека джависта | Java, Spring, Maven, Hibernate

🌐 Зачем нужен CDN и как он работает

Когда пользователь из Сиднея открывает ваш сайт, его запрос летит на сервер в Германии и обратно. Это ~300 мс только на «дорогу» — и это для каждого изображения, шрифта, JS-файла.

CDN (Content Delivery Network / Сеть доставки контента) решает эту проблему в лоб: вместо одного сервера — тысячи точек по всему миру. Пользователь получает файлы с ближайшей к нему ноды, а не с вашего origin-сервера.

🔹 Origin и Edge

В архитектуре с CDN появляются два новых понятия:

Origin Server (Главный сервер): это ваш настоящий сервер, где крутится Spring Boot, лежит база данных и хранятся оригиналы всех файлов (например, в Amazon S3).

Edge Servers (Граничные серверы / Точки присутствия - PoP): это тысячи серверов CDN-провайдера (например, Cloudflare или Akamai), раскиданные по всему земному шару: в Сиднее, Токио, Нью-Йорке, Лондоне, Москве.

🔹 Как работает кэш

Первый запрос к конкретному файлу всё равно идёт до origin. CDN его скачивает, кэширует у себя и отдаёт пользователю. Все последующие запросы на тот же файл edge-сервер обрабатывает сам, не трогая ваш бэкенд. Это называется cache hit.

🔹 Что кладем в CDN

CDN идеально подходит для статического контента:

— Картинки, видео, аудио.
— Скомпилированные файлы JavaScript и CSS.
— Шрифты.

CDN не подходит для динамического контента:

— Корзина товаров.
— Приватные данные пользователя.
(Запросы к API /api/v1/users/me должны идти напрямую на ваш сервер, минуя кэш CDN).

🔹 Защита от DDoS

Современные CDN (тот же Cloudflare) - это не просто кэш. Это гигантский щит.

Если хакеры решат «положить» ваш сайт и отправят миллион запросов в секунду, этот удар примут на себя серверы CDN. Их пропускная способность измеряется терабитами. Они отфильтруют «мусорный» трафик, и ваш маленький Origin-сервер даже не заметит атаки.

🔹 Побочные эффекты

Ускорение: пользователи получают тяжелый контент мгновенно, потому что скачивают его из своего же города.

Экономия: ваш главный сервер больше не тратит процессорное время и трафик на отдачу терабайтов картинок. Вы платите за сервера меньше.

Безопасность: CDN скрывает реальный IP-адрес вашего сервера и защищает от DDoS-атак.

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#CoreJava

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

Библиотека джависта | Java, Spring, Maven, Hibernate

✔️ Java-тест: 1 запрос в коде = 10 000 запросов в БД

Код чистый, тесты быстрые, на реальных данных — pg_stat_activity в огне 👇

📦 Задание — code review

Ручка возвращает список заказов с информацией о товарах. Работает корректно, но DBA прибежал с графиком: каждый вызов делает тысячи запросов к БД.

@Entity
public class Order {
@Id
private Long id;
private Long userId;
private LocalDateTime createdAt;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "order")
private List<OrderItem> items;
}

@Entity
public class OrderItem {
@Id
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
private Order order;

@ManyToOne(fetch = FetchType.LAZY)
private Product product;

private Integer quantity;
}

@RestController
@RequiredArgsConstructor
public class OrderController {

private final OrderRepository orderRepository;

@GetMapping("/orders")
public List<OrderDto> getOrders(@RequestParam Long userId) {
List<Order> orders = orderRepository.findByUserId(userId);

return orders.stream()
.map(order -> new OrderDto(
order.getId(),
order.getItems().stream()
.map(item -> new ItemDto(
item.getProduct().getName(),
item.getQuantity()
))
.toList()
))
.toList();
}
}


▪️ Объясни

— Точную механику N+1: где и сколько раз запросы уходят в БД в этом коде.
— Почему FetchType.EAGER «решит» проблему, но создаст другую.
— Как можно решить проблему.

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise

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

Библиотека джависта | Java, Spring, Maven, Hibernate

👩‍💻 Разработка на Java требует глубокого понимания не только языка, но и принципов работы JVM, многопоточности и современных фреймворков.

🎯 Курс «Java Developer. Professional» — это структурированное обучение для разработчиков, которые хотят выйти на новый уровень, освоить актуальный стек технологий и уверенно претендовать на позиции уровня Middle+.

Вы получите 96 часов практической работы, на живых вебинарах разберете ключевые аспекты работы JVM, научитесь строить эффективные многопоточные приложения, освоите Spring WebFlux, Kafka, реактивный Postgres и Kubernetes.

📚Программа OTUS постоянно обновляется, соответствуя требованиям рынка, а диплом ценится работодателями.

➡️ Пройдите вступительное тестирование и присоединяйтесь к группе: https://clc.to/0LN5fQ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

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

Библиотека джависта | Java, Spring, Maven, Hibernate

😮 Топ-вакансий для джавистов за неделю

Java-разработчик Middle - от 200 000 до 250 000 ₽ - гибрид (Новосибирск)

Java-разработчик - от 280 000 ₽ - удалёнка

Tech Lead (Java / Spark) - 400 000 ₽ - офис (Москва)

➡️ Еще больше топовых вакансий — в нашем канале Java jobs

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

Библиотека джависта | Java, Spring, Maven, Hibernate

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

🧵 GC: как выбрать сборщик мусора и не пожалеть

Выбирал ли ты GC хоть раз осознанно? Часто запустил приложение — работает, и ладно. Но когда начинаются проблемы с латентностью или throughput, первый вопрос от SRE: «А какой у вас GC?».

🔹 Разберём что выбрать и почему.

Все GC балансируют между двумя вещами:

▪️ Throughput — сколько полезной работы делает приложение за единицу времени
▪️ Latency — насколько долго приложение паузится на GC

Идеального нет. Выбор всегда зависит от профиля нагрузки.

🔹 Serial и Parallel — если латентность не важна

-XX:+UseSerialGC / -XX:+UseParallelGC


Serial GC однопоточный. И Minor, и Major GC выполняет один поток, всё приложение стоит. Звучит как антиквариат, но на маленьком heap (< 256MB) и однопоточной среде накладные расходы на координацию потоков не нужны, Serial реально быстрее.

Parallel GC — то же самое, но сборку делают несколько потоков одновременно. STW никуда не девается, просто сама пауза короче за счёт параллелизма. На Major GC всё равно можешь получить сотни миллисекунд.

Где уместно: batch-обработка, утилиты, CLI-инструменты. Там где важен максимальный throughput и никто не ждёт response time.

🔹 G1 — дефолт с Java 9

-XX:+UseG1GC


G1 делит heap на регионы фиксированного размера (~1-32MB) и собирает их инкрементально. Не нужно собирать весь heap за раз — выбираются регионы с наибольшим количеством мусора (отсюда "Garbage First").

Главная настройка:
bash-XX:MaxGCPauseMillis=200  # целевое время паузы


Это не гарантия, это цель. G1 будет подстраивать размер собираемых регионов, чтобы уложиться.

Где уместно: большинство серверных приложений с heap от 4GB. Хороший баланс throughput/latency без тюнинга.

🔹 ZGC и Shenandoah — когда паузы недопустимы

-XX:+UseZGC / -XX:+UseShenandoahGC


Оба делают большую часть работы конкурентно — параллельно с работой приложения. STW-паузы измеряются единицами миллисекунд вне зависимости от размера heap.

Где уместно: real-time системы, trading, API с жёсткими SLA по p99 латентности. Платишь немного throughput — получаешь предсказуемые паузы.

🔹 Как выбирать на практике

Не угадывать, а мерить. Включаешь GC логи и смотришь что происходит:
bash-Xlog:gc*:file=gc.log:time,uptime:filecount=5,filesize=20m

Дальше либо GCEasy, либо руками смотришь на паузы и частоту сборок.

🔹 Три вопроса которые определяют выбор

1. Какой размер heap?
До 4GB — G1 справится. Больше 16GB — смотри на ZGC, у G1 начинаются долгие Mixed GC.

2. Какие требования к латентности?
Есть SLA на p99 < 50ms — только ZGC или Shenandoah. Нет жёстких требований — G1.

3. Какой профиль аллокаций?
Много short-lived объектов — генерационный GC справится хорошо. Много long-lived крупных объектов — G1 может давать длинные паузы на evacuation, ZGC справится лучше.

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#CoreJava

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

Библиотека джависта | Java, Spring, Maven, Hibernate

✔️ Java-тест: утечка в фильтре

Memory leak, который живёт неделями и не воспроизводится локально 👇

📦 Задание — code review


Написали фильтр для аудита запросов. В продакшне через несколько дней — OutOfMemoryError.

@Component
public class AuditFilter implements Filter {

private static final ThreadLocal<AuditContext> CONTEXT =
new ThreadLocal<>();

@Override
public void doFilter(
ServletRequest request,
ServletResponse response,
FilterChain chain
) throws IOException, ServletException {

AuditContext ctx = new AuditContext(
((HttpServletRequest) request).getRequestURI(),
System.currentTimeMillis()
);
CONTEXT.set(ctx);

try {
chain.doFilter(request, response);
} finally {
auditLog(CONTEXT.get());
}
}

public static AuditContext current() {
return CONTEXT.get();
}

private void auditLog(AuditContext ctx) {
// пишем в БД...
}
}


▪️ Объясни

— Почему объекты в ThreadLocal не собираются GC, даже если запрос завершён.
— Какая одна строчка кода здесь отсутствует, и где именно она должна быть.

* Есть ли риски при использовании ThreadLocal в virtual threads (Project Loom)?

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise

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

Библиотека джависта | Java, Spring, Maven, Hibernate

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

♻️ Redis-кеш с AI

@Cacheable над методом поставить несложно. Сложнее объяснить тимлиду почему прод лежит, когда Redis недоступен — а CacheErrorHandler никто не написал.

Промпт, который закрывает этот пробел сразу:

Ты Senior Java-разработчик. Сгенерируй модуль кеширования для Spring Boot 3.x с Redis.

Требования:
- RedisCacheConfiguration с GenericJackson2JsonRedisSerializer
- CacheManager с раздельными TTL для разных кешей (RedisCacheManagerBuilder)
- 2 сервиса с @Cacheable, @CachePut, @CacheEvict — с комментарием когда что применять
- Кастомный CacheErrorHandler (деградация без исключения при недоступном Redis)
- application.yml конфиг
- Тест: @SpringBootTest + Testcontainers Redis

Стек: Java 21, Spring Boot 3.2, Spring Data Redis, Testcontainers 1.19

@EnableCaching — только в отдельном @Configuration, не в Application-классе.

Верни код классов, yml, тест.


══════ Навигация ══════
ВакансииЗадачиСобесы

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

#Enterprise

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

Библиотека джависта | Java, Spring, Maven, Hibernate

В чём разница между Statement и PreparedStatement?

— Statement используется для выполнения простых SQL-запросов без параметров. Он формирует запрос как строку и каждый раз компилирует его заново, что может быть медленно и небезопасно.

— PreparedStatement предварительно компилируется базой данных и позволяет задавать параметры через плейсхолдеры. Что повышает производительность при многократном выполнении одного запроса и защищает от SQL-инъекций (данные не конкатенируются со строкой запроса, а подставляются корректно).

Поэтому в реальных проектах почти всегда используют PreparedStatement.

🐸 Библиотека собеса по Java

#core

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

Библиотека джависта | Java, Spring, Maven, Hibernate

🔨 Паттерн Builder

Builder — порождающий паттерн, который разделяет конструирование сложного объекта и его представление. Позволяет создавать объекты пошагово и получать разные результаты, используя одинаковый процесс построения.

Использование

🔹 Когда конструктор принимает много параметров — особенно если часть из них опциональна.
🔹 Когда порядок шагов построения важен или требует валидации перед созданием.
🔹 Когда нужно создавать разные представления одного и того же объекта.

Преимущества

1️⃣ Читаемость и явное намерение

Конструктор с 7 параметрами — это загадка. Builder с именованными шагами — спецификация. Читая вызов, вы сразу понимаете, что создаётся и почему.

2️⃣ Безопасная валидация

Вся проверка параметров сосредоточена в методе build(). Объект либо создаётся корректным, либо не создаётся вообще. Нет промежуточных невалидных состояний.

3️⃣ Иммутабельность

Builder накапливает параметры, build() создаёт финальный неизменяемый объект. Это удобно в многопоточном коде и делает объекты предсказуемыми.

4️⃣ Поддержка опциональных параметров без перегрузок

Вместо пяти перегруженных конструкторов — один Builder. Указываете только то, что нужно, остальное берёт дефолт.

⚠️ Lombok даёт @Builder за одну аннотацию — но понимать механику всё равно стоит.

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#CoreJava

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

Библиотека джависта | Java, Spring, Maven, Hibernate

😁 Развернем холиварчик

К статье на Хабре «Я два месяца платил 300к человеку, который тихо скармливал мои задачи в ChatGPT» уже почти 900 комментов.

Прочитайте, давайте тоже обсудим 💬

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

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

#DevLife

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

Библиотека джависта | Java, Spring, Maven, Hibernate

Почитали тут свежий отчёт по рынку ИИ-ускорителей в РФ: оказывается, 54% компаний тормозят внедрение ИИ исключительно из-за конских цен на инфраструктуру.

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

По сути, сейчас мало уметь собирать RAG. Нужно считать токены, настраивать time-travel дебаг в LangGraph и уметь роутить запросы на лету. Всё это мы учли в обновлённом курсе по разработке AI-агентов, где акцент сделан именно на AgentOps и жёсткий контроль ресурсов.

Также в программе:

— оценка качества, трейсинг и защита от деградации пайплайнов;
— мультиагентные паттерны и интеграция по протоколу MCP;
— локальный деплой Open Source под 152-ФЗ (когда данные нельзя выносить наружу).

Кажется, это единственный адекватный roadmap по переходу от блокнотов к enterprise-решениям.

Прямо сейчас можно урвать курс с увесистой скидкой (49 000 ₽ 62 990 ₽ за базовый тариф и 99 000 ₽ 124 990 ₽ за продвинутый трек), но стоит поторопиться — на потоке осталось всего 5 мест.

👉 Зафиксировать цену и начать собирать агентов, за которых не стыдно в проде

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

Библиотека джависта | Java, Spring, Maven, Hibernate

🔐 Security-модуль за 5 минут с AI

Каждый раз одно и то же: новый проект, пишешь JWT с нуля, лезешь в старые репозитории за шаблоном, получаешь deprecated код на Spring Security 5.

Можно иначе — сформулировал промпт так, чтобы AI сразу выдал то, что не придётся переписывать.

Ты Senior Java-разработчик. Сгенерируй production-ready модуль безопасности для Spring Boot 3.x.

Требования:
- JWT (access + refresh токены), фильтр OncePerRequestFilter
- SecurityFilterChain: csrf off, session stateless
- UserDetailsService через JPA-репозиторий
- Пакеты: security/config, security/filter, security/service
- Обработка AuthenticationException и AccessDeniedException — отдельные handler-классы
- Никакого WebSecurityConfigurerAdapter

Стек: Java 21, Spring Boot 3.2, Spring Security 6, JJWT 0.12.x

Верни полный код всех классов с import и package.


Дальше подгоняешь под свою модель пользователя и роли. Основа готова.

══════ Навигация ══════
ВакансииЗадачиСобесы

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

#Enterprise

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