Библиотека джависта | Java, Spring, Maven, Hibernate
23.7K subscribers
2.1K photos
43 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
🔥 Вечерний холиварчик: стоит ли вообще посещать Java-конференции?

С одной стороны:

— живое общение, нетворкинг, свежие идеи и практики из первых уст
— возможность поговорить с авторами библиотек и топовыми инженерами
— комьюнити-движ и вдохновение

С другой стороны:

— иногда билеты стоят как половина MacBook'а
— многие доклады потом доступны на YouTube
— часть контента выглядит «для новичков», хотя и подаётся как «advanced»

💬 А как считаете вы: конференции — это must have или пустая трата времени?

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6🔥21👍1
🔍 Просто о сложном: AtomicInteger

В многопоточном коде даже простая операция count++ не является атомарной. Она распадается на три шага:

1. Прочитать значение переменной.
2. Увеличить его.
3. Записать обратно.

Если два потока выполнят это одновременно, получится гонка данных (race condition). Итоговое значение будет меньше ожидаемого.

🔹 Как решает проблему AtomicInteger

AtomicInteger — это класс из пакета java.util.concurrent.atomic, который предоставляет атомарные (неделимые) операции над целыми числами.

Под капотом он использует механизм CAS (Compare-And-Swap), который поддерживается на уровне процессора.

Принцип работы:
— Читаем текущее значение.
— Проверяем, не изменилось ли оно за это время.
— Если совпадает, записываем новое.
— Если нет, повторяем попытку (spin loop).

🔹 Пример использования

public class Counter {
private final AtomicInteger count = new AtomicInteger(0);

public void increment() {
count.incrementAndGet(); // атомарное ++
}

public int get() {
return count.get();
}
}

Здесь incrementAndGet() гарантирует, что два потока не «перетрут» друг друга, а каждый инкремент будет учтён.

🔹 Основные методы

▪️ get() — получить текущее значение.
▪️ set(int newValue) — установить новое значение.
▪️ incrementAndGet() / getAndIncrement() — инкремент.
▪️ decrementAndGet() — декремент.
▪️ addAndGet(int delta) — прибавить значение.
▪️ compareAndSet(int expect, int update) — вручную применить CAS.

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

— Спин-блокировки

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

— ABA-проблема

Значение могло измениться на «A → B → A». Для простых счётчиков это не критично, но в сложных структурах данных используют AtomicStampedReference.

— Ограниченность

AtomicInteger работает только с int. Для более сложных случаев есть AtomicLong, AtomicReference, LongAdder (оптимизирован для высокой конкуренции).

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

✔️ Подходит:

— Для простых счётчиков, метрик.
— В неблокирующих алгоритмах (lock-free).
— В высоконагруженных сценариях, где synchronized слишком дорог.

Не подходит:

— Для сложных бизнес-операций над несколькими переменными (лучше использовать мьютексы или транзакции).
— При очень высокой конкуренции, может быть лучше взять LongAdder.

🔹 Итог

AtomicInteger — это лёгкий способ избавиться от гонок при работе с числами в многопоточности.

Это не магия, а всего лишь тонкая обёртка над CAS, встроенным в процессоры. Понимание этого механизма помогает писать по-настоящему безопасный и быстрый многопоточный код.

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍105🔥2
Сохраняйте шпаргалку по лямбдам и стрим апи

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
13👍6🔥4
🛡 Role-Based Access Control (RBAC) в Spring Security

В корпоративных системах управление доступом часто становится узким местом — особенно когда речь идёт о гибкой настройке ролей и разрешений. Вместо ручного «if-else администрирования» можно подключить AI и быстро нагенерировать полноценный слой RBAC.

📝 Промпт:
Generate a Spring Security configuration for a Spring Boot 3 application with Role-Based Access Control (RBAC).

— Configure Spring Security with role-based access (ADMIN, USER, MANAGER).
— Implement method-level security with @PreAuthorize and SpEL expressions.
— Set up JWT authentication with custom claims (roles, permissions).
— Create a PermissionEvaluator for fine-grained access checks (e.g. entity-level access).
— Integrate with a database-backed UserDetailsService for dynamic role management.
— Add an admin API endpoint for managing roles and permissions at runtime.
— Ensure audit logging of access control decisions.


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

— Добавьте Multi-tenancy support with tenant-aware role resolution.
— Добавьте Attribute-Based Access Control (ABAC) для сложных бизнес-правил.
— Добавьте Integration with Keycloak или OAuth2 provider для централизованного управления доступом.

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥1👏1
🆕 Java Digest: IDE, виртуальные потоки и OLAP-запросы

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

1️⃣ IDE для Java-разработчиков

Исследование по выбору IDE среди российских Java/Spring-разработчиков. Интересно посмотреть, как распределяются предпочтения между IntelliJ IDEA, VS Code и другими инструментами.

2️⃣ Подводные камни виртуальных потоков

Статья подробно разбирает, где виртуальные потоки Java могут подвести: от deadlock’ов и проблем с synchronized до нюансов работы с блокирующими API. Отличный разбор для тех, кто планирует использовать Project Loom в продакшене.

3️⃣ Оптимизация OLAP-запросов

Практика ускорения аналитических запросов: профилирование на уровне СУБД, Linux perf и eBPF-трассировка, методики Intel Top-down. Полезный материал для тех, кто работает с хранилищами данных и high-load аналитикой.

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

#News
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42🔥1
🤫 Всё, что не пропустит ТГ можно найти на Х

Друзья, можно было бы послать вас на Х, но я просто предложу подписаться на наш профиль в Х.

Там можно найти много:

🖥 Интересных и полезных материалов
🤡 Смешных мемов
🔥 Горячих и полезных лайфхаков

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

#News
Please open Telegram to view this post
VIEW IN TELEGRAM
😁3🔥2👍1
CI/CD упал, тесты красные, релиз завис. А на календаре — пятница вечер, пицца и уже забронированное место в баре. Что делать?
Anonymous Poll
28%
Уйти, всё равно в понедельник чинить 🥳
24%
Остаться и додавить до зелёного ✔️
32%
Зависит от критичности бага
16%
Спрятаться и сделать вид, что не видел пайплайны 😁
😁6🔥2👍1
👀 Задача с собеса: «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
👍51🔥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
🔥152👍2😁2