И вновь прошла насыщенная рабочая неделя. Сегодня немного сменилась локация, гуляю вдоль средиземного моря.
Как проходят ваши выходные?
Отправляйте фото в комментарии👇🏻
#DevLife
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7😍2👍1
Когда в проекте сотни файлов и десятки классов — навигация превращается в хаос. А вы знали, что IDEA помнит все места, где вы недавно были?
🔹 Что делает
— Показывает список недавних мест в коде (не просто открытых файлов)
— Можно искать по содержимому, не только по имени
— Можно найти только изменённые фрагменты
🔹 Зачем это нужно
— Молниеносно возвращает к недавнему месту редактирования
— Полезно при ревью, багфиксе или исследовании сложных фрагментов
— Работает лучше, чем "Recent Files", ведь учитывает даже переходы внутри одного файла
🔹 Как использовать
— Нажмите
Ctrl+Shift+E
(Windows/Linux) или ⌘+Shift+E
(macOS)— Появится список последних мест где вы были. Можно также искать лишь изменённые фрагменты (повторно нажмите то же сочетание)
— Начните вводить фрагмент кода или имени и IDEA сама сузит поиск
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍5❤2
Forwarded from Библиотека собеса по Java | вопросы с собеседований
ConcurrentHashMap использует
В отличие от Collections.synchronizedMap(...), который
#concurrency
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥4👏1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁20😢3💯2⚡1
🎯 Как быстро настроить Zero-Downtime деплой Spring Boot-приложения с помощью Docker + Traefik
Обновлять сервис без остановки — не роскошь, а необходимость. Ни пользователи, ни ваши коллеги не должны видеть "502 Bad Gateway", пока вы выкатываете новую версию.
Пошагово разберём, как сделать быстрый и бесшовный деплой с балансировкой между версиями.
1️⃣ Готовим Dockerfile
Собираем образ:
2️⃣ Добавляем Traefik как reverse proxy
Создаём docker-compose.yml:
version: '3.8'
Запускаем:
Traefik автоматически поднимет роутер и начнёт проксировать трафик.
3️⃣ Выкатываем новую версию без даунтайма
Создаём новый образ:
Добавляем в docker-compose.yml рядом:
Теперь Traefik балансирует между двумя версиями — 1.0.0 и 1.1.0.
Можно спокойно проверить, что новая версия работает корректно.
4️⃣ Плавно отключаем старую
Если всё ок — выключаем старый контейнер:
Traefik мгновенно перестроит маршрут — без обрывов соединений.
Ни один пользователь не заметит переключения.
5️⃣ Добавляем health-checks для надёжности
В application.yml:
И в Docker-compose:
Traefik будет держать в балансе только живые инстансы.
Всё просто и надёжно.
💡 Что мы получили:
— Обновления без простоев
— Автоматическую балансировку
— Self-healing через health-checks
— Легко масштабируемую инфраструктуру для staging/prod
🐸 Библиотека джависта
#Enterprise
Обновлять сервис без остановки — не роскошь, а необходимость. Ни пользователи, ни ваши коллеги не должны видеть "502 Bad Gateway", пока вы выкатываете новую версию.
Пошагово разберём, как сделать быстрый и бесшовный деплой с балансировкой между версиями.
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 .
Создаём 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 автоматически поднимет роутер и начнёт проксировать трафик.
Создаём новый образ:
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.
Можно спокойно проверить, что новая версия работает корректно.
Если всё ок — выключаем старый контейнер:
docker compose stop myapp_v1
docker compose rm -f myapp_v1
Traefik мгновенно перестроит маршрут — без обрывов соединений.
Ни один пользователь не заметит переключения.
В 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 хранит данные в обычном массиве
— Все операции чтения (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
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).
Ставьте 🔥, если хотите такой же пост по другим коллекциям. Пишите в комменты, какую коллекцию разобрать следующей.
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍3👏1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁29👍4👏1🤩1🌚1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁16❤11👍3💯2
🔥 Коллеги, годный практикум по микросервисной архитектуре!
По шагам — чем «учебный» монолит отличается от продакшна:
— 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 🤓
По шагам — чем «учебный» монолит отличается от продакшна:
— 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🤔2❤1😁1