Please open Telegram to view this post
VIEW IN TELEGRAM
😁20💯7🔥1
🚀 Просто о сложном: паттерны проектирования микросервисов
Проектирование микросервисов — это не просто «разбить монолит на части». Нужны паттерны, которые помогают сервисам надёжно общаться, масштабироваться независимо и корректно восстанавливаться при сбоях.
Разбираем ключевые паттерны микросервисной архитектуры, которые должен знать каждый инженер:
1️⃣ API Gateway
→ Единая точка входа для всех клиентов
→ Скрывает сложность внутренней архитектуры
→ Берёт на себя аутентификацию, rate limiting, маршрутизацию
→ N запросов от клиента — 1 запрос через gateway
2️⃣ Saga Pattern
→ Для распределённых транзакций (когда несколько сервисов должны завершиться успешно или откатиться)
→ Два подхода: оркестрация или хореография
→ Гарантирует консистентность данных без глобальных блокировок
3️⃣ Circuit Breaker
→ Защищает систему от медленных или падающих downstream-сервисов
→ «Размыкает цепь» при превышении порога ошибок
→ Предотвращает каскадные падения
→ Автоматически восстанавливается после стабилизации
4️⃣ Event-Driven Architecture
→ Сервисы общаются через события вместо прямых вызовов
→ Слабая связанность компонентов
→ Отличная масштабируемость
→ Идеально для real-time обновлений
5️⃣ Strangler Fig
→ Постепенная миграция монолита
→ Выносим модули один за другим
→ Маршрутизируем трафик через gateway
→ Миграция без даунтайма
6️⃣ Database per Service
→ Каждый сервис владеет своими данными
→ Слабая связанность
→ Независимые деплои
→ Избегаем bottleneck «одной большой общей БД»
💬 Какие паттерны используете часто? Делитесь опытом в комментах 👇
🔹 Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib
🐸 Библиотека джависта
#CoreJava
Проектирование микросервисов — это не просто «разбить монолит на части». Нужны паттерны, которые помогают сервисам надёжно общаться, масштабироваться независимо и корректно восстанавливаться при сбоях.
Разбираем ключевые паттерны микросервисной архитектуры, которые должен знать каждый инженер:
→ Единая точка входа для всех клиентов
→ Скрывает сложность внутренней архитектуры
→ Берёт на себя аутентификацию, rate limiting, маршрутизацию
→ N запросов от клиента — 1 запрос через gateway
→ Для распределённых транзакций (когда несколько сервисов должны завершиться успешно или откатиться)
→ Два подхода: оркестрация или хореография
→ Гарантирует консистентность данных без глобальных блокировок
→ Защищает систему от медленных или падающих downstream-сервисов
→ «Размыкает цепь» при превышении порога ошибок
→ Предотвращает каскадные падения
→ Автоматически восстанавливается после стабилизации
→ Сервисы общаются через события вместо прямых вызовов
→ Слабая связанность компонентов
→ Отличная масштабируемость
→ Идеально для real-time обновлений
→ Постепенная миграция монолита
→ Выносим модули один за другим
→ Маршрутизируем трафик через gateway
→ Миграция без даунтайма
→ Каждый сервис владеет своими данными
→ Слабая связанность
→ Независимые деплои
→ Избегаем bottleneck «одной большой общей БД»
🔹 Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3🔥2
Please open Telegram to view this post
VIEW IN TELEGRAM
😁27🔥4💯3
От
Java-разработчики привыкли к строгой типизации и надёжной архитектуре. Но когда дело доходит до анализа данных, возникает «чёрный ящик»: мы можем интегрировать ML-модель, но не всегда понимаем математическую логику её работы.
Чтобы реально прокачаться, нужно спуститься на уровень ниже библиотек — к линейной алгебре.
На курсе «Математика для разработки AI-моделей» мы перезапустили формат: теперь с живыми вебинарами. Первый уже прошёл (отзывы — огонь), но вы ещё успеваете влететь в поток.
Что разбираем на ближайших лекциях:
— векторы, матрицы, определители (основа эффективных вычислений);
— линейную регрессию и метод наименьших квадратов (реализуем алгоритм с нуля);
— SVD-разложение (ключ к созданию рекомендательных систем).
Это не сухая теория, а практика на
Последний шанс присоединиться (до 9.12)
Spring Boot к матричным разложениямJava-разработчики привыкли к строгой типизации и надёжной архитектуре. Но когда дело доходит до анализа данных, возникает «чёрный ящик»: мы можем интегрировать ML-модель, но не всегда понимаем математическую логику её работы.
Чтобы реально прокачаться, нужно спуститься на уровень ниже библиотек — к линейной алгебре.
На курсе «Математика для разработки AI-моделей» мы перезапустили формат: теперь с живыми вебинарами. Первый уже прошёл (отзывы — огонь), но вы ещё успеваете влететь в поток.
Что разбираем на ближайших лекциях:
— векторы, матрицы, определители (основа эффективных вычислений);
— линейную регрессию и метод наименьших квадратов (реализуем алгоритм с нуля);
— SVD-разложение (ключ к созданию рекомендательных систем).
Это не сухая теория, а практика на
NumPy.Последний шанс присоединиться (до 9.12)
👍2🔥1👏1
Forwarded from Библиотека собеса по Java | вопросы с собеседований
Напишите конфигурацию для production-приложения 👇
📦 Задание
Есть REST API с эндпоинтами:
/api/public/** — публичные данные/api/user/** — данные пользователя/api/admin/** — админ-панель/actuator/health — health check/actuator/** — остальные actuator endpointsНастройте SecurityFilterChain с правильными правами доступа и защитой от основных атак.
📋 Требования
— Доступы
/api/public/** — доступ всем (включая неавторизованных)/api/user/** — только авторизованным с ролью USER или ADMIN/api/admin/** — только ADMIN/actuator/health — доступ всем/actuator/** — только ADMIN— Безопасность
→ Включить защиту от CSRF для state-changing операций
→ Настроить CORS: разрешить запросы только с https://example.com
→ Добавить security headers (XSS, clickjacking protection)
→ Использовать stateless сессии (JWT/token-based)
→ Настроить обработку ошибок 401/403
Ставьте → 🔥, если нравится формат. Если нет → 🤔
#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3🎉1
🔥 Как настроить Prometheus и Grafana для мониторинга
Prometheus + Grafana — индустриальный стандарт для мониторинга и визуализации метрик. Time-series база данных, pull-based сбор метрик, powerful query язык (PromQL), оповещения.
Мониторинг JVM, HTTP requests, кастомных метрик, cache hit rates в реальном времени с историей и алертами.
1️⃣ Добавляем зависимости
Для экспорта метрик в Prometheus нужны spring-boot-starter-actuator и micrometer-registry-prometheus. Micrometer автоматически собирает JVM и application метрики.
Критически важно включить prometheus endpoint через management.endpoints.web.exposure.include=prometheus в application.yml. Без этого /actuator/prometheus не будет доступен.
2️⃣ Устанавливаем и настраиваем Prometheus
Скачайте Prometheus или запустите через Docker. Создайте prometheus.yml конфиг файл с определением targets для scraping.
Добавьте job для вашего приложения: job_name: 'spring-boot-app', targets: ['localhost:8080']. Укажите metrics_path: '/actuator/prometheus' и scrape_interval: 15s. Prometheus начнёт периодически собирать метрики.
3️⃣ Настраиваем кастомные метрики
Inject MeterRegistry в сервисы для регистрации метрик. Используйте Counter для монотонно растущих значений: registry.counter("orders.created", "region", "EU").increment().
Для текущих значений используйте Gauge: registry.gauge("queue.size", queue, Queue::size). Для измерения времени операций используйте Timer с tags для группировки: Timer.builder("api.request.duration").tags("endpoint", "/users").register(registry).
4️⃣ Устанавливаем и подключаем Grafana
Установите Grafana или запустите через Docker. При первом входе (admin/admin) добавьте Prometheus как data source через Configuration → Data Sources.
Укажите URL Prometheus (http://localhost:9090), настройте scrape interval. Grafana автоматически проверит подключение через Test кнопку. После успешного подключения можно создавать дашборды.
5️⃣ Создаём дашборды в Grafana
Импортируйте готовый дашборд для Spring Boot: используйте ID 4701 или 6756 из Grafana Marketplace. Они содержат панели для JVM memory, GC, HTTP metrics, database pool.
Создайте кастомные панели для бизнес метрик. Используйте PromQL для запросов: rate(http_server_requests_seconds_count[5m]) для requests per second, sum by (status)(http_server_requests_seconds_count) для группировки по HTTP статусам.
6️⃣ Настраиваем алерты
В Grafana создайте alert rules через Alerting → Alert rules. Определите условия: например, high error rate — rate(http_server_requests_seconds_count{status="500"}[5m]) > 10.
Настройте каналы оповещения (Slack, email, PagerDuty, webhook) для получения алертов. Укажите threshold values, evaluation interval и for duration (как долго условие должно быть true перед отправкой алерта).
7️⃣ Best practices и оптимизация
▪️ Используйте tags (labels) для всех метрик — это позволяет фильтровать и группировать
▪️ Не создавайте метрики с high cardinality tags (например, user_id) — это убьёт Prometheus
▪️ Настройте retention policy в Prometheus для баланса между историей и хранилищем
▪️ Используйте recording rules в Prometheus для предагрегации часто используемых запросы
▪️ Используйте @Timed(percentiles = {0.5, 0.95, 0.99}) для SLA трекинга
✔️ Что происходит под капотом
Micrometer собирает метрики во время работы приложения: подсчитывает request rate, измеряет latency, собирает JVM статистику. Метрики хранятся в памяти в формате Prometheus.
Prometheus периодически делает HTTP GET запрос к /actuator/prometheus, получает все метрики в текстовом формате. Сохраняет их в time-series БД с timestamp. Grafana запрашивает данные у Prometheus через PromQL, строит графики и проверяет условия алёртов.
🔹 Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib
🐸 Библиотека джависта
#Enterprise
Prometheus + Grafana — индустриальный стандарт для мониторинга и визуализации метрик. Time-series база данных, pull-based сбор метрик, powerful query язык (PromQL), оповещения.
Мониторинг JVM, HTTP requests, кастомных метрик, cache hit rates в реальном времени с историей и алертами.
Для экспорта метрик в Prometheus нужны spring-boot-starter-actuator и micrometer-registry-prometheus. Micrometer автоматически собирает JVM и application метрики.
Критически важно включить prometheus endpoint через management.endpoints.web.exposure.include=prometheus в application.yml. Без этого /actuator/prometheus не будет доступен.
Скачайте Prometheus или запустите через Docker. Создайте prometheus.yml конфиг файл с определением targets для scraping.
Добавьте job для вашего приложения: job_name: 'spring-boot-app', targets: ['localhost:8080']. Укажите metrics_path: '/actuator/prometheus' и scrape_interval: 15s. Prometheus начнёт периодически собирать метрики.
Inject MeterRegistry в сервисы для регистрации метрик. Используйте Counter для монотонно растущих значений: registry.counter("orders.created", "region", "EU").increment().
Для текущих значений используйте Gauge: registry.gauge("queue.size", queue, Queue::size). Для измерения времени операций используйте Timer с tags для группировки: Timer.builder("api.request.duration").tags("endpoint", "/users").register(registry).
Установите Grafana или запустите через Docker. При первом входе (admin/admin) добавьте Prometheus как data source через Configuration → Data Sources.
Укажите URL Prometheus (http://localhost:9090), настройте scrape interval. Grafana автоматически проверит подключение через Test кнопку. После успешного подключения можно создавать дашборды.
Импортируйте готовый дашборд для Spring Boot: используйте ID 4701 или 6756 из Grafana Marketplace. Они содержат панели для JVM memory, GC, HTTP metrics, database pool.
Создайте кастомные панели для бизнес метрик. Используйте PromQL для запросов: rate(http_server_requests_seconds_count[5m]) для requests per second, sum by (status)(http_server_requests_seconds_count) для группировки по HTTP статусам.
В Grafana создайте alert rules через Alerting → Alert rules. Определите условия: например, high error rate — rate(http_server_requests_seconds_count{status="500"}[5m]) > 10.
Настройте каналы оповещения (Slack, email, PagerDuty, webhook) для получения алертов. Укажите threshold values, evaluation interval и for duration (как долго условие должно быть true перед отправкой алерта).
▪️ Используйте tags (labels) для всех метрик — это позволяет фильтровать и группировать
▪️ Не создавайте метрики с high cardinality tags (например, user_id) — это убьёт Prometheus
▪️ Настройте retention policy в Prometheus для баланса между историей и хранилищем
▪️ Используйте recording rules в Prometheus для предагрегации часто используемых запросы
▪️ Используйте @Timed(percentiles = {0.5, 0.95, 0.99}) для SLA трекинга
Micrometer собирает метрики во время работы приложения: подсчитывает request rate, измеряет latency, собирает JVM статистику. Метрики хранятся в памяти в формате Prometheus.
Prometheus периодически делает HTTP GET запрос к /actuator/prometheus, получает все метрики в текстовом формате. Сохраняет их в time-series БД с timestamp. Grafana запрашивает данные у Prometheus через PromQL, строит графики и проверяет условия алёртов.
🔹 Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤2🔥2
Please open Telegram to view this post
VIEW IN TELEGRAM
😁30👏5❤1👍1💯1
Если стандартных возможностей IDE для контроля покрытия тестами уже недостаточно, стоит обратить внимание на JaCoCo. Этот инструмент выходит за рамки базового функционала.
В отличие от встроенных средств IntelliJ IDEA, которые отлично справляются с локальной разработкой, JaCoCo предлагает комплексный подход к анализу покрытия:
JaCoCo идеален для проектов, где важна прозрачность метрик тестирования и автоматизация проверок качества кода на всех этапах разработки.
🔹 Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3❤1
Дебажишь сложную бизнес-логику? Остановился на breakpoint, видишь 15 переменных в Variables, но нужно проверить результат user.getOrders().stream().filter(o -> o.getStatus() == PAID).count().
Обычный путь: добавить переменную, пересобрать, перезапустить дебаг. Или лезть в Watch и там собирать выражение.
А IDEA позволяет выполнять произвольный Java-код прямо в точке остановки — с полным доступом к контексту.
🔹 Что делает
— Выполняет любой Java-код в текущей области видимости (методы объектов, статика, создание новых объектов)
— Видит все локальные переменные, поля класса, this, параметры метода
— Поддерживает многострочные выражения с промежуточными переменными
— Работает с лямбдами, стримами, рефлексией — любой валидный Java
— Code Completion работает как в обычном редакторе
— Результат можно раскрыть, посмотреть поля, добавить в Watches
🔹 Зачем это нужно
— Проверить гипотезу без изменения кода (а что если отфильтровать по другому полю?)
— Вызвать приватный метод или геттер для отладки
— Протестировать фикс: user.setStatus(ACTIVE); service.process(user) — сработает?
— Посмотреть сложную агрегацию: items.stream().collect(groupingBy(...))
🔹 Как использовать
— Поставить breakpoint, дождаться остановки
— Alt+F8 (Cmd+F8 на Mac) или ПКМ → Evaluate Expression
— Написать код, Enter — видишь результат
— Для многострочного: Code Fragment Mode (переключатель в диалоге)
— Можно выделить код прямо в редакторе и нажать Alt+F8 — он подставится автоматически
🔹 Курс «Алгоритмы и структуры данных»
🔹 Получить консультацию менеджера
🔹 Сайт Академии 🔹 Сайт Proglib
#Enterprise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍4❤1
Forwarded from Библиотека задач по Java | тесты, код, задания
Почему при стресс тесте и высокой нагрузке может быть выброшено NPE?
Anonymous Quiz
25%
Из-за race condition - оба потока читают одно и то же
31%
Из-за instruction reordering - процессор может переставить строки 1 и 2
10%
Из-за garbage collection в неудачный момент
18%
Это невозможно - если deploymentReady true, то config уже инициализирован
17%
Посмотреть ответ
🤔5👍1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁26👍3🔥3
Forwarded from Библиотека программиста | программирование, кодинг, разработка
Летим зимовать ✈️
Когда холодает, айтишники пакуют чемоданы, а мы разыгрываем ваучер на 50 000 рублей в Островке.
Поехать к морю или остаться среди снежных пейзажей — выбирайте сами!
Чтобы участвовать, нужно оставить любую реакцию под этим постом и подписаться на каналы ниже:
😎 Типичный программист
🐸 Библиотека программиста
🟢 Ostrovok! Tech
Теперь осталось нажать на кнопку участия под этим постом и вы в игре!
Итоги подведём 12 декабря. Победителя выберем с помощью бота. Подробнее с правилами можно ознакомиться здесь.
Всем удачи!
Участников: 111
Призовых мест: 1
Дата розыгрыша: 19:00, 12.12.2025 MSK (3 дня)
Когда холодает, айтишники пакуют чемоданы, а мы разыгрываем ваучер на 50 000 рублей в Островке.
Поехать к морю или остаться среди снежных пейзажей — выбирайте сами!
Чтобы участвовать, нужно оставить любую реакцию под этим постом и подписаться на каналы ниже:
Теперь осталось нажать на кнопку участия под этим постом и вы в игре!
Итоги подведём 12 декабря. Победителя выберем с помощью бота. Подробнее с правилами можно ознакомиться здесь.
Всем удачи!
Участников: 111
Призовых мест: 1
Дата розыгрыша: 19:00, 12.12.2025 MSK (3 дня)
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
LinkedList — это реализация интерфейса List и Deque на основе двусвязного списка. Отличный выбор для частых вставок/удалений, но медленный доступ по индексу.
📦 Базовая структура
LinkedList состоит из узлов (Node), связанных ссылками:
public class LinkedList<E> {
transient int size = 0;
transient Node<E> first; // голова списка
transient Node<E> last; // хвост списка
private static class Node<E> {
E item;
Node<E> next; // следующий узел
Node<E> prev; // предыдущий узел
}
}Главные особенности:
— O(1) для add/remove с концов (first/last).
— O(n) для доступа по индексу (нужен обход).
— O(1) для вставки/удаления при наличии ссылки на узел.
— Больше памяти чем ArrayList (~24 байта overhead на элемент).
Внутренности Node
→ item: элемент
→ prev: ссылка на предыдущий узел
→ next: ссылка на следующий узел
Преимущества двусвязного списка
— Обход в обе стороны (вперёд и назад).
— Быстрое удаление узла при наличии ссылки на него.
— Динамический размер без перевыделения памяти.
➕ add(E element) — добавление в конец
1. Создаётся новый Node:
newNode = new Node<>(last, element, null).2. Если список пустой
(last == null), то first = last = newNode.3. Иначе:
last.next = newNode И last = newNode.4. Увеличивается size.
Сложность: O(1).
➕ add(int index, E element) — вставка по индексу
1. Проверяется range:
index > size → IndexOutOfBoundsException.2. Если
index == size, вызывается addLast().3. Иначе находится узел по индексу через
node(index).4. Создаётся новый узел и вставляется перед найденным.
5. Обновляются ссылки prev/next соседних узлов.
Сложность: O(n) — нужен поиск узла по индексу.
🔎 get(int index) — получение по индексу
1. Проверка границ:
index >= size → IndexOutOfBoundsException.2. Вызывается
node(index) для поиска узла.3.
node(index) использует оптимизацию:— Если index < size/2: обход от first вперёд.
— Иначе: обход от last назад.
4. Возвращается item найденного узла.
Сложность: O(n) — в худшем случае обход половины списка.
➖ remove(int index) — удаление по индексу
1. Находится узел по индексу через
node(index).2. Узел отсоединяется от списка:
— node.prev.next = node.next (если prev != null).
— node.next.prev = node.prev (если next != null).
3. Обновляются first/last если нужно.
4. Обнуляются ссылки в узле для GC:
node.item = null; node.next = node.prev = null.Сложность: O(n) — поиск узла O(n), удаление O(1).
➕ addFirst(E e) / addLast(E e)
Специальные методы для работы как Deque:
list.addFirst("A"); // O(1) — добавление в начало
list.addLast("Z"); // O(1) — добавление в конецСложность: O(1) — прямое изменение first/last.
➖ removeFirst() / removeLast()
list.removeFirst(); // O(1) — удаление первого
list.removeLast(); // O(1) — удаление последнего
Сложность: O(1) — прямой доступ к first/last.
⚖️ Важные нюансы
LinkedList может работать как двусторонняя очередь. Идеально для реализации стеков и очередей.
Каждый узел требует ~24 байта overhead (на 64-bit JVM):
— 12 байт заголовок объекта
— 8 байт ссылка item
— 8 байт ссылка next
— 8 байт ссылка prev
— Padding до 8 байт
Для списка из 1000 элементов overhead ~24 КБ против ~4 КБ у ArrayList.
LinkedList НЕ реализует RandomAccess marker interface. Это сигнал для алгоритмов использовать итераторы вместо get(i).
// ❌ Медленно — O(n²)
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
}
// ✅ Быстро — O(n)
for (String s : list) {
// iterator используется автоматически
}
ListIterator позволяет двунаправленный обход и модификацию.
LinkedList допускает null значения.
→ Частые вставки/удаления с концов.
→ Модификация при итерации.
→ Неизвестный размер с частым ростом (Нет overhead на расширение массива как у ArrayList).
Ставьте 🔥, если хотите ещё разбор.
#CoreJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3❤1
This media is not supported in your browser
VIEW IN TELEGRAM