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

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

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

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

РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
Download Telegram
👀 Задача с собеса: «Single-flight» объединение запросов к внешнему API (middle+)

Компания ловит шторма трафика: десятки потоков одновременно дергают один и тот же медленный эндпоинт (например, профили клиентов). Хотят убрать дубликаты запросов и снизить нагрузку на апстрим. Задача:

Реализуйте in-memory «single-flight» слой, который:

— Для одного и того же ключа выполняет ровно ОДНУ загрузку, остальные ожидают тот же результат.
— Имеет короткоживущий кэш (TTL) для защиты от штамповки (cache stampede).
— Потокобезопасен и работает за O(1) на обращение (без полных проходов).
— Прозрачно пробрасывает исключение всем конкурентным ожидателям, если загрузчик упал.


▪️ Условия


— API: CompletableFuture<V> getOrLoad(K key, Supplier<V> loader) (или Supplier<CompletableFuture<V>>, если загрузка уже async).

— Если в кэше есть не сгоревший ключ, вернуть немедленно. Если нет — запустить единственную загрузку на ключ и раздать один и тот же Future всем конкурентным вызовам.

— По завершении загрузки положить результат в кэш с expireAt.

— Удаление сгоревших записей ленивое (на чтении/записи), без фоновых сканеров.

— Критические секции минимальные; без глобальных блокировок.

💡 Ключевые моменты

— Объединение запросов: ConcurrentHashMap<K, CompletableFuture<V>> inFlight + computeIfAbsent исключит дубликаты.

— Кэш: ConcurrentHashMap<K, Entry<V>> cache, где Entry хранит value и expireAt.

— TTL: проверка сроков строго точечная; протухшее удаляем перед использованием.

— Ошибки: один промах/ошибка должны одинаково прилететь всем конкурентным ожидающим.

— Производительность: никакой синхронизации на весь объект; один ключ — одна «тонкая» операция.

💬 Возможная реализация в комментариях. Пишите также ваши реализация и способы оптимизации.

🐸 Библиотека собеса по Java
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61🔥1
🚀 Всё о курсе «ИИ-агенты для DS-специалистов»

Зачем нужны ИИ-агенты?

Это системы, которые берут на себя задачи аналитики и автоматизации. Именно они становятся основой для работы с корпоративными данными и для поддержки принятия решений.

Зачем мне курс?

Курс отвечает на три ключевых вопроса:

— Как построить собственную систему агентов с нуля?
— Каким образом использовать RAG-подход для работы с корпоративными данными?
— Как адаптировать LLM под реальные задачи бизнеса?

Подходит ли это мне?

Курс рассчитан на специалистов уровня middle+ и senior: ML/AI инженеров, Data Scientists, backend и platform-разработчиков. Подойдёт и студентам CS/DS, если вы готовы к продвинутым практикам.

Запись вводной встречи «ИИ-агенты: новая фаза развития искусственного интеллекта» доступна по ссылке.

Когда старт?

Обучение начинается 3 октября.

Сколько стоит?

До 28 сентября действует скидка → 57 000 ₽ вместо 69 000 ₽ (промокод datarascals).

🔗 Описание программы и регистрация
☕️ Java && Coffee

Релиз в пятницу и упавший прод уже позади, надеюсь все успели отдохнуть от кода и насладиться выходными.

Как проходят ваши выходные? Отправляйте фото в комментарии👇🏻

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

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
😍31👍1
Последние часы со скидкой!

Мы уже закрыли вебинар «ИИ-агенты: новая фаза развития AI», но запись всё ещё доступна.

А дальше остаётся только практика. На курсе «ИИ-агенты для DS-специалистов» ты научишься разрабатывать агентов, собирать RAG-системы и адаптировать LLM под бизнес.

Сегодня цена ещё 57.000 ₽ с промокодом datarascals.
Завтра — 69.000 ₽.

👉 Успеть оплатить до полуночи
👑 IntelliJ IDEA: Analyze Data Flow

Когда код становится сложнее, простого Find Usages уже мало. Хотите понять, откуда пришло значение переменной или куда оно утекает? Для этого есть Analyze Data Flow.

🔹 Что делает

— Позволяет проследить поток данных: где переменная инициализируется, как модифицируется и где используется
— Работает не только для переменных, но и для параметров методов, полей и возвращаемых значений
— Может анализировать как «куда идёт», так и «откуда пришло» (Forward/Backward analysis)

🔹 Зачем это нужно


— Быстро понять, почему метод получает null (и где он берётся)
— Выявить неочевидные зависимости между частями кода
— Ускорить отладку без бесконечного «шагания» по дебаггеру

🔹 Как использовать

— Выделите переменную или метод
— Analyze → Data Flow to Here / Data Flow from Here
— IDEA визуально покажет дерево зависимостей

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3👏21
👀 Внутреннее устройство LinkedList

LinkedList — это классическая реализация двусвязного списка. На поверхности он выглядит как обычная коллекция, реализующая интерфейсы List, Deque и Queue. Но под капотом это структура узлов (Node), которые связаны друг с другом через ссылки на предыдущий и следующий элемент.

📦 Базовая структура


Каждый элемент списка хранится в отдельном объекте Node<E>, который содержит:

▪️ E item — сам элемент
▪️ Node<E> next — ссылка на следующий узел
▪️ Node<E> prev — ссылка на предыдущий узел

У LinkedList есть два поля:

▪️ first — голова списка
▪️ last — хвост списка

Это позволяет быстро добавлять элементы в начало и конец.

⚡️ Добавление и удаление

— Добавление в начало (addFirst) или конец (addLast) → O(1): меняем ссылки у пары узлов.
— Удаление головы или хвоста также → O(1).
— Вставка или удаление в середине требует сначала дойти до нужного узла → O(n).

🌊 Поиск элемента


— По индексу: список не хранит массив, значит придётся идти по ссылкам.
— Оптимизация: если индекс ближе к голове, обход идёт с first, если к хвосту — с last.
Сложность в среднем — O(n/2), то есть линейная.

📊 Производительность

— Доступ по индексу → O(n).
— Добавление/удаление в начало или конец → O(1).
— Вставка/удаление в середину → O(n).
— Итерация по списку → O(n), но эффективно, так как используется последовательный проход по ссылкам.

⚖️ Важные нюансы

— В отличие от ArrayList, в LinkedList нет операций с массивами и «ресайзинга».
— Но расходует больше памяти: каждый узел хранит не только элемент, но и две ссылки (prev/next).
— Итераторы fail-fast: изменение списка во время обхода бросает ConcurrentModificationException.

🔄 Итераторы и Deque

LinkedList реализует Deque, что делает его удобным для очередей и стеков. Offer, poll, peek работают за O(1). Push/pop превращают список в стек.

🧮 Когда использовать

На практике ArrayList почти всегда быстрее по времени и эффективнее по памяти.
LinkedList может быть полезен только в редких случаях, когда нужны очень частые вставки/удаления в середину коллекции (без итерации по коллекции) и не важен доступ по индексу. В остальных случаях выбирайте ArrayList.

🔗 Документация: OpenJDK — LinkedList source | Официальная JavaDoc (Java 17)

Ставьте 🔥, если хотите такой же пост по другим коллекциям, например CopyOnWriteArrayList.

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥192👍2😁2
🤖 Курс «ИИ-агенты для DS-специалистов»

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

📚 Бонус: при оплате до 30 сентября вы получите дополнительный лонгрид для подготовки к курсу. Это отличный способ подойти к занятиям уже с базой.

🔥 А ещё после прохождения курса у вас будет достаточно знаний, чтобы участвовать в хакатоне с призовым фондом 1 125 000 ₽.

🔗 Записаться на курс и узнать подробности
🧩 final vs finally vs finalize()

Казалось бы, три похожих ключевых слова → final, finally, finalize(). А смысл принципиально разный. Давайте разберёмся.

🔹 final

Модификатор, который делает сущность неизменяемой:

▪️ final переменная → нельзя переприсвоить.
▪️ final метод → нельзя переопределить.
▪️ final класс → нельзя наследовать.

Используется для обеспечения immutability и контрактов в коде.

🔹 finally

Блок в try-catch, который выполняется всегда (даже если выброшено исключение).

Гарантирует освобождение ресурсов:
try {
FileReader reader = new FileReader("data.txt");
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("Закрываем ресурсы");
}


🔹 finalize()


Метод класса Object, вызываемый GC перед удалением объекта. Используется редко, считается устаревшим (deprecated с Java 9, удалён в Java 18).

Минус: непредсказуемое время вызова.

Современная альтернатива: try-with-resources или явная очистка.

💡 Вывод

final → контроль изменяемости.
finally → контроль завершения.
finalize() → контроль очистки (но не используйте).

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1👏1
🤖 Курс «ИИ-агенты для DS-специалистов»

Последняя возможность в этом году освоить ИИ-агентов с Proglib— старт живых вебинаров на курсе уже 3 октября!

Уже 24 студента изучают 5 лонгридов подготовительного модуля, чтобы сформировать базу к старту живых вебинаров с Никитой Зелинским.

📚 Бонус: при оплате до 30 сентября вы получите дополнительный лонгрид для подготовки к курсу. Это отличный способ подойти к занятиям уже с базой.

🔥 А ещё после прохождения курса у вас будет достаточно знаний, чтобы участвовать в хакатоне с призовым фондом 1 125 000 ₽.

🔗 Записаться на курс и узнать подробности
Please open Telegram to view this post
VIEW IN TELEGRAM
😁30👍2🥱2🔥1
🎮 DevTools на каждый день

Тут собраны самые популярные и эффективные инструменты для разных направлений: IDE, ИИ, безопасность и многое другое.

💬 Какие инструменты используете в повседневной работе?

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥21
⚡️ Optional: must-have или лишний шум?

✔️ "За" Optional
— Убирает null-ы из кода
— Более читаемая и безопасная API
— Стандартный инструмент, без сторонних либ

"Против" Optional
— Часто приводит к избыточным обёрткам
— Усложняет код при массовом использовании
— Всё равно не решает проблему null на 100%

💬 В комментах напишите, где используете Optional в проде.

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

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
👍101🔥1
🔍 Просто о сложном: Spring Boot

Spring Boot — это не «новый фреймворк», а надстройка над Spring, которая убирает рутину и ускоряет разработку.

В обычном Spring нужно было вручную конфигурировать всё: от DataSource до DispatcherServlet. В Boot это делается автоматически через автоконфигурацию.

🔹 Как работает автоконфигурация

Spring Boot сканирует зависимости и classpath, а затем подключает нужные бины:

— Если у вас есть spring-boot-starter-data-jpa, Boot автоматически создаст EntityManagerFactory, DataSource, транзакционный менеджер.

— Если добавлен spring-boot-starter-web, он поднимет встроенный Tomcat/Jetty и зарегистрирует контроллеры. И так далее.

Магия кроется в аннотации @EnableAutoConfiguration (включается через @SpringBootApplication). Она загружает META-INF/spring.factories → список классов-конфигов → каждый проверяет условия @ConditionalOnClass, @ConditionalOnMissingBean и решает: активироваться или нет.

💡 Почему это работает так гладко

Потому что в Boot сотни готовых конфигураций «на все случаи жизни».

Фактически, это огромная библиотека «если увидишь X — настрой Y».

👀 Подводный слой магии

— Черный ящик

Легко забыть, что именно сконфигурировал Boot. Иногда приходится «копать» в автоконфигурацию, чтобы понять, какой бин реально используется.

— Избыточные зависимости


Подключив Starter, можно случайно притащить половину экосистемы Spring. Это увеличивает время старта и усложняет дебаг.

— Конфликт настроек


Собственная конфигурация может пересечься с автоконфигурацией.

⚡️ Хорошая практика

— Не доверяйте «чёрному ящику»: при старте приложения смотрите Spring Boot Actuator и логи автоконфигурации.

— Знайте про --debug при старте: он показывает, какие автоконфигурации включены или отключены.

— В продакшене лучше контролировать, какие именно стартеры вы тянете. Иногда spring-boot-starter-web приносит в проект в три раза больше, чем реально нужно.

🎯 Итог

Spring Boot — это ускоритель, но не магия. Его сила в автоконфигурациях, а слабость в том, что легко потерять контроль.

Понимание того, как работает @EnableAutoConfiguration и условия @Conditional, отличает разработчика, который «просто пишет на Boot», от того, кто реально управляет приложением.

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92🔥1😁1
🔥 Spring Security: как работает @PreAuthorize и зачем он нужен

В продакшн-коде часто возникает задача ограничить доступ к методам сервиса или контроллера. Делать это вручную — значит плодить дублирование и путать бизнес-логику с проверками. Для этого в Spring Security есть аннотация @PreAuthorize.

🔵 Как это работает

1. Аннотация вешается на метод (контроллер или сервис).

2. При вызове метода Spring Security перехватывает обращение и проверяет условие, указанное в аннотации.

3. Условие описывается на языке SpEL (Spring Expression Language), где доступно:

▪️ authentication — текущий объект аутентификации;
▪️ principal — данные текущего пользователя;
▪️ #id, #dto и т.д. — аргументы метода, к которым можно обратиться напрямую.

Пример:
@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long id) { ... }


→ метод вызовется только для пользователей с ролью ADMIN.

🔵 Что можно писать внутри

— Проверка ролей и прав
hasRole('USER'), hasAnyRole('ADMIN','MODERATOR')

hasAuthority('SCOPE_read') (актуально при работе с OAuth2)


— Собственные условия
@PreAuthorize("#id == authentication.principal.id")
public UserProfile getProfile(Long id) { ... }


→ Здесь доступ только к своему профилю.

— Комбинации условий

Логика пишется прямо в SpEL:
@PreAuthorize("hasRole('ADMIN') or @securityService.isOwner(#docId)")
public Document update(Long docId) { ... }


— Сервисы внутри выражений

В выражение можно подключать свои бины:
@PreAuthorize("@reviewSecurity.isOwner(#id, authentication)")
public Review update(Long id) { ... }


→ бин reviewSecurity должен быть в контексте Spring и возвращать true/false.

🔵 Зачем это нужно

— Не надо вручную писать проверки в каждом методе.

— Авторизация централизована и читается прямо на уровне API.

— Условия можно вынести в отдельный сервис, чтобы не захламлять аннотацию.

👉 В итоге @PreAuthorize — это не только про роли, а про гибкий DSL проверки доступа, который можно расширять под проект: от банальной проверки ролей до бизнес-логики уровня "пользователь может редактировать только свои документы, если они ещё не опубликованы".

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍3🔥1
👾 AI-агенты — настоящее, о котором все говорят!

Уже 3 октября стартует второй поток нашего нового курса «AI-агенты для DS-специалистов».

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

На обучении вы соберёте полноценные LLM-системы с учётом особенностей доменных областей, получите hands-on навыки RAG, Crew-AI / Autogen / LangGraph и агентов.

🎓 В рамках курса вы научитесь:

1️⃣ адаптировать LLM под разные предметные области и данные
2️⃣ собирать свою RAG-систему: от ретривера и реранкера до генератора и оценки качества
3️⃣ строить AI-агентов с нуля — на основе сценариев, функций и взаимодействия с внешней средой

Научитесь применять похожие подходы в разных доменных областях, получите фундамент для уверенного прохождения NLP system design интервью и перехода на следующий грейд.

🗓️ Завтра первый вебинар, успевайте залететь в ряды ИИ-первопроходцев 👈🏻
😁1