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

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

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

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

РКН: https://gosuslugi.ru/snet/67a5bbda1b17b35b6c1a55c4
Download Telegram
☕️ 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👍52
Как работает ConcurrentHashMap?

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

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

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

#concurrency
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥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", "https://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
👍6🔥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
🔥14👍3👏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://t.iss.one/esuleimanov 🤓
👍5🤔21😁1