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

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

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

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

РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
Download Telegram
👀 Внутреннее устройство ConcurrentSkipListMap

ConcurrentSkipListMap — это потокобезопасная реализация NavigableMap из пакета java.util.concurrent.

В отличие от ConcurrentHashMap, эта структура поддерживает упорядоченность элементов и основана на вероятностной структуре данных Skip List (список с пропусками).

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

Внутри ConcurrentSkipListMap использует многоуровневый связанный список Skip List (см. фото).

Главная особенность:

— Элементы отсортированы по ключу (естественный порядок или Comparator).

— Несколько уровней индексации для быстрого поиска.

— Lock-free операции чтения через CAS (Compare-And-Swap).

— Минимальные блокировки только при изменении структуры.

🔍 Как устроено хранение

Базовые компоненты:

▪️ Node<K,V> — узел нижнего уровня.
▪️ Index<K,V> — узел индексного уровня.
▪️ HeadIndex<K,V> — голова уровня, хранит высоту.

Принцип работы

— Данные хранятся только на нижнем уровне (в Node).

— Верхние уровни содержат Index — указатели для быстрого прыжка.

— При вставке элемента случайно определяется высота (вероятность ~50% для каждого уровня).

— Максимальная высота ограничена 64 уровнями.

⚡️ Операции поиска, вставки и удаления

🔎 get(K key) — поиск

1. Начинается с верхнего уровня HeadIndex.
2. Движется вправо, пока ключ не станет больше искомого.
3. Спускается на уровень ниже.
4. Повторяет до нижнего уровня → O(log n).
5. Без блокировок, читает volatile-ссылки.

put(K key, V value) — вставка

1. Выполняется поиск позиции (как в get).
2. Если ключ существует, обновляется через CAS → O(log n).
3. Если новый:
— Создаётся новый Node.
— Вставляется в нижний уровень с CAS.
— Случайно генерируется высота (геометрическое распределение).
— Создаются Index-узлы для верхних уровней.
— Связываются с соседями через CAS.
4. При необходимости увеличивается высота всей структуры.

Блокировки: минимальны, только при изменении указателей через CAS-retry loops.

remove(Object key) — удаление

1. Находится узел на нижнем уровне.
2. Помечается как удалённый (marker node) через CAS.
3. Физически отсоединяется от списка.
4. Индексы на верхних уровнях удаляются постепенно (ленивое удаление).
5. Если верхние уровни опустели, высота уменьшается.

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

1. Вероятностная балансировка

В отличие от AVL/Red-Black деревьев, балансировка достигается случайной высотой узлов.
Нет гарантии идеального баланса, но ожидаемая сложность O(log n).

2. Null и сравнения

Null ключи запрещены (NullPointerException).
Null значения допустимы (в отличие от ConcurrentHashMap).
Ключи должны быть Comparable или нужен Comparator.

3. Memory Consistency

Гарантии happens-before для put/get одного и того же ключа.
Weakly consistent bulk операции (putAll, clear).

✔️ Полезно для

— Упорядоченных concurrent-карт: логи по времени, рейтинги, приоритетные кэши.

— Range-запросы: subMap(from, to), headMap(to), tailMap(from).

— Навигация: firstEntry(), lastEntry(), floorEntry(key), ceilingEntry(key).

— Concurrent sorted set: keySet() даёт ConcurrentNavigableSet.

— Когда нужен порядок + потокобезопасность без глобальных блокировок.

🔗 Документация: JavaDoc (Java 17)

Ставьте 🔥, если хотите ещё разбор.

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍42
🤡 Неожиданный холиварчик

Наткнулся недавно на пост про винду, очень удивился, что после закрытия поддержки десятки народ массово переходит обратно на семёрку 😳

Думал будут прыгать на одиннадцатую или *nix системы.

💬 Какая ОС у вас на личном компе?

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

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
😁8👍1🔥1
Как между собой связаны Iterable, Iterator и цикл for-each?

Iterable — это интерфейс с единственным методом iterator(), который возвращает объект Iterator. Любой класс, реализующий Iterable, может использоваться в цикле for-each.

Iterator — это интерфейс для последовательного обхода элементов коллекции. Содержит методы hasNext(), next() и remove().

Цикл for-each — это синтаксический сахар. Компилятор автоматически преобразует его в вызов iterator() и работу с Iterator.

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

#core
Please open Telegram to view this post
VIEW IN TELEGRAM
👍133🔥1
🎁 Конкурс от Proglib Academy!

Кстати, если кто-то ещё не в курсе — у нас тут раздают MacBook Pro 14.
Да-да, не шутка, настоящий, железный, с M3 Pro

Но! Чтобы успеть пройти 2 недели обучения к 15 ноября, курс нужно взять до конца октября — и сейчас на всё скидка 40%.

Чтобы поучаствовать, нужно:

1️⃣ Покупаешь любой курс до конца октября;
2️⃣ Проходишь 2 недели обучения к 15 ноября;
3️⃣ Написать куратору в чат #розыгрыш.

До 15 ноября, потом всё — поезд (и макбук) уйдёт.

👉 Участвовать в розыгрыше
Сохраняйте шпаргалку по командам git

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍123🔥2
🔍 Просто о сложном: Virtual Threads

В Java 21 появились Virtual Threads — легковесные потоки, которые позволяют писать синхронный код с производительностью асинхронного.

По сути, это JVM-управляемые потоки (а не OS-потоки), которых можно создавать миллионы без значительных затрат памяти. Они решают главную проблему масштабирования традиционных потоков.

🔹 Зачем они нужны

Классические Platform Threads имеют проблемы:

— дорогие в создании (~1MB стека на поток);
— ограничены числом (~тысячи потоков максимум);
— при блокировке (IO, sleep) поток простаивает, занимая ресурсы.

Virtual Threads весят ~1KB, создаются мгновенно, и при блокировке платформенного потока освобождается для других задач. Это позволяет обрабатывать миллионы конкурентных запросов.

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

▪️ Thread.ofVirtual() — создание билдера для virtual thread.
▪️ Thread.startVirtualThread() — быстрый старт задачи.
▪️ Executors.newVirtualThreadPerTaskExecutor() — пул для каждой задачи создаёт новый VT.
▪️ Автоматическое отсоединение от платформенного потока при блокировке (IO, sleep, wait, park).
▪️ Присоединение к платформенным потокам из ForkJoinPool.

🔹 Под капотом

Когда виртуальный поток блокируется (например, на IO), он "отцепляется" от платформенного потока. Освободившийся платформенный поток берёт другой готовый виртуальный поток. Когда операция завершается, виртуальный поток "подцепляется" обратно к доступному платформенному потоку.

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

— Pinning (закрепление)

Virtual thread может "застрять" на платформенном потоке при:
• Synchronized блоках
• Нативных методах (JNI)

В таких случаях carrier thread блокируется вместе с virtual thread. Решение: использовать ReentrantLock вместо synchronized.

— ThreadLocal может быть опасен

Миллионы virtual threads с ThreadLocal приведут к огромному потреблению памяти. Используйте ScopedValue (preview feature в Java 21+).

— Не подходит для CPU-bound задач

Virtual threads оптимизированы для IO-bound операций. Для вычислений лучше параллельные стримы или ForkJoinPool.

— Мониторинг
Стандартные инструменты мониторинга потоков могут показывать некорректные данные — они заточены под platform threads.

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

— Высоконагруженные web-серверы с множеством конкурентных запросов.
— Микросервисы с большим количеством внешних вызовов (HTTP, БД).
— Когда нужна простота синхронного кода без сложности реактивного.
— Замена больших thread pools для IO-операций.

Не подходит:

— CPU-intensive вычисления (сортировки, криптография).
— Код с большим количеством synchronized блоков (pinning).
— Легаси-код с активным использованием ThreadLocal.

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥51💯1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁22🔥4💯4❤‍🔥2👍1
Код-ревью Java-проекта прямо в браузере, как в IDE? Похоже на правду! 👀

Джависты, внимание. Платформа SourceCraft выкатила кодонавигацию для Java, которая работает прямо в веб-интерфейсе. Можно открыть любой класс и одним кликом перейти к декларации метода, увидеть все его использования (Find Usages), посмотреть историю изменений по коммитам. 🔥

Это дико удобно при ревью или анализе больших проектов — не нужно клонировать репо и настраивать IDE. Всё работает из браузера. Для команд это реальная экономия времени. По сути, полноценное code-review пространство со встроенными IDE-инструментами.
👍7🔥1
🎃 Хэллоуин в Proglib Academy: скидки, призы и... немного паники

Сегодня 31 октября, и это не просто время тыкв и призраков, это ПОСЛЕДНИЙ ДЕНЬ, когда ты можешь выиграть макбук!

→ Купи любой курс со скидкой 40% 💸
→ Начни обучение, чтобы пройти 2 недели к 15 ноября 🎓
→ Напиши куратору #розыгрыш ✍️

Всё! Теперь ты в игре.

👉 Сейчас или никогда!
😁1
🎭 LangChain4j + Spring Boot

Забудьте про «LLM в лоб». LangChain4j — это промышленный слой интеграции AI с Java-приложениями. Он превращает LLM в часть архитектуры, а не игрушку для экспериментов.

🧩 Вместо того чтобы вызывать модель напрямую, вы описываете цепочку: загрузка данных → векторизация → поиск → рассуждение → ответ. Всё это живёт в Spring-экосистеме, с DI, профилями, бинами и транзакциями.

📝 Промпт:

Generate a production-ready Spring Boot 3 + LangChain4j integration for enterprise RAG and AI agent workflows:

— Configure LangChain4j client with OpenAI or Ollama connector, API-key management, and retry policy.
— Implement document ingestion pipeline: PDF, Markdown, and web sources → chunking → embedding store (Postgres + pgvector).
— Add Retrieval-Augmented Generation chain with context ranking, token budget control, and caching.
— Implement conversational memory (message buffer + summary).
— Create multi-agent setup: retriever → reasoner → summarizer → verifier.
— Secure API credentials using Spring Config / Vault integration.
— Add async streaming responses (Server-Sent Events).
— Integrate observability: OpenTelemetry tracing, metrics with Micrometer + Prometheus.
— Add custom interceptors for logging prompts and responses.
— Provide JUnit tests for chain determinism and data isolation.
— Example endpoint: /ai/ask — retrieves context, runs reasoning chain, returns structured JSON answer.


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

— добавьте Guardrails для валидации ответов и отказов от токсичного контента;
— настройте дашборд Grafana: latency, token usage, accuracy, fallback-rate.

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41🔥1