Микросервисы: как это на самом деле работает
В этом видео мы пошагово разберём, почему реальные корпоративные системы значительно сложнее учебных проектов, и как правильно строить архитектуру приложений.
В этом видео мы разбираемся:
• чем отличается "учебный" монолит от продакшн-системы;
• зачем нужна обсервабилити (метрики, логи, трейсы) и как её реализовать через Grafana, Prometheus, Loki, Tempo, Alloy;
• что такое деградация системы и как работают вертикальное и горизонтальное масштабирование;
• как реализовать распределённые транзакции с помощью паттерна Saga (оркестрация и хореография);
• как организовать безопасность с помощью Keycloak и API Gateway;
• как использовать OpenAPI + codegen для генерации DTO и Feign-клиентов;
• как настроить удобное окружение через Docker Compose + Makefile, Nexus и Spring Boot.
В практической части мы создадим микросервисную систему:
• сервис `person-service` для работы с пользователями;
• API Gateway для регистрации и аутентификации;
• интеграцию с Keycloak;
• аудит изменений (Hibernate Envers);
• инфраструктурный стек мониторинга и логирования.
В конце вы увидите полный цикл: запуск сервисов в Docker, проверка через Postman, метрики и трейсы в Grafana.
Это видео - полноценный практикум по построению микросервисной архитектуры с нуля.
🌐 🗣 СМОТРЕТЬ VKVIDEO
🎞 🗣 СМОТРЕТЬ YOUTUBE
Подписывайся на наш канал в Max🟪
В этом видео мы пошагово разберём, почему реальные корпоративные системы значительно сложнее учебных проектов, и как правильно строить архитектуру приложений.
В этом видео мы разбираемся:
• чем отличается "учебный" монолит от продакшн-системы;
• зачем нужна обсервабилити (метрики, логи, трейсы) и как её реализовать через Grafana, Prometheus, Loki, Tempo, Alloy;
• что такое деградация системы и как работают вертикальное и горизонтальное масштабирование;
• как реализовать распределённые транзакции с помощью паттерна Saga (оркестрация и хореография);
• как организовать безопасность с помощью Keycloak и API Gateway;
• как использовать OpenAPI + codegen для генерации DTO и Feign-клиентов;
• как настроить удобное окружение через Docker Compose + Makefile, Nexus и Spring Boot.
В практической части мы создадим микросервисную систему:
• сервис `person-service` для работы с пользователями;
• API Gateway для регистрации и аутентификации;
• интеграцию с Keycloak;
• аудит изменений (Hibernate Envers);
• инфраструктурный стек мониторинга и логирования.
В конце вы увидите полный цикл: запуск сервисов в Docker, проверка через Postman, метрики и трейсы в Grafana.
Это видео - полноценный практикум по построению микросервисной архитектуры с нуля.
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤3🔥3🎄1
Big O Notation: Сложность алгоритмов
🔵 O(1) — Константное время
Константное время выполнения означает, что время выполнения операции не зависит от размера входных данных. Это как мгновенный доступ к элементу массива по индексу. Независимо от того, сколько данных в массиве, операция займёт одно и то же время.
🔵 O(n) — Линейное время
Линейная сложность указывает на то, что время выполнения алгоритма растёт пропорционально количеству элементов. Поиск элемента в LinkedList — классический пример. Чтобы найти нужный элемент, вам придётся пройти весь список, начиная с головы, что займёт линейное время, если искомый элемент находится в конце.
🔵 O(log n) — Логарифмическое время
В логарифмических алгоритмах задача сокращается на каждом шаге вдвое. Пример — бинарный поиск в отсортированном массиве. На каждом шаге вы делите массив пополам, и продолжаете поиск в нужной половине. Это значительно быстрее, чем линейный поиск.
🔵 O(n^2) — Квадратичное время
В алгоритмах с квадратичной сложностью каждый элемент сравнивается с каждым другим. Примером является сортировка пузырьком (Bubble Sort), где алгоритм многократно сравнивает и обменивает элементы местами, что приводит к квадратичному времени выполнения при увеличении числа элементов.
🔵 O(n^3) — Кубическое время
Кубическая сложность встречается в задачах с тройными вложенными циклами. Пример — умножение матриц, где каждый элемент одной матрицы должен быть умножен на каждый элемент другой, что приводит к тройным вложенным операциям.
🔵 O(n log n) — Линейно-логарифмическое время
Линейно-логарифмическая сложность характерна для более продвинутых алгоритмов сортировки, таких как быстрая сортировка (QuickSort) или сортировка слиянием (MergeSort). Эти алгоритмы делят массив на части и сортируют их, что делает их более эффективными по сравнению с квадратичными.
🔵 O(2^n) — Экспоненциальное время
Экспоненциальная сложность наблюдается в рекурсивных алгоритмах, таких как вычисление чисел Фибоначчи без мемоизации. На каждом шаге создаётся две новые ветви вычислений, что приводит к экспоненциальному росту времени выполнения с увеличением входных данных.
🔵 O(n!) — Факториальное время
Факториальная сложность возникает в задачах, связанных с вычислением всех возможных перестановок или комбинаций. Например, задача генерации всех перестановок строки: с увеличением длины строки число возможных комбинаций возрастает факториально.
🔵 O(√n) — Время квадратного корня
Этот тип сложности встречается, например, в алгоритмах поиска делителей числа или проверки на простоту. Например, чтобы проверить, является ли число простым, достаточно проверить делители до его квадратного корня, что сокращает количество операций по сравнению с линейным подходом.
Подписывайся на наш канал в Max🟪
Константное время выполнения означает, что время выполнения операции не зависит от размера входных данных. Это как мгновенный доступ к элементу массива по индексу. Независимо от того, сколько данных в массиве, операция займёт одно и то же время.
Линейная сложность указывает на то, что время выполнения алгоритма растёт пропорционально количеству элементов. Поиск элемента в LinkedList — классический пример. Чтобы найти нужный элемент, вам придётся пройти весь список, начиная с головы, что займёт линейное время, если искомый элемент находится в конце.
В логарифмических алгоритмах задача сокращается на каждом шаге вдвое. Пример — бинарный поиск в отсортированном массиве. На каждом шаге вы делите массив пополам, и продолжаете поиск в нужной половине. Это значительно быстрее, чем линейный поиск.
В алгоритмах с квадратичной сложностью каждый элемент сравнивается с каждым другим. Примером является сортировка пузырьком (Bubble Sort), где алгоритм многократно сравнивает и обменивает элементы местами, что приводит к квадратичному времени выполнения при увеличении числа элементов.
Кубическая сложность встречается в задачах с тройными вложенными циклами. Пример — умножение матриц, где каждый элемент одной матрицы должен быть умножен на каждый элемент другой, что приводит к тройным вложенным операциям.
Линейно-логарифмическая сложность характерна для более продвинутых алгоритмов сортировки, таких как быстрая сортировка (QuickSort) или сортировка слиянием (MergeSort). Эти алгоритмы делят массив на части и сортируют их, что делает их более эффективными по сравнению с квадратичными.
Экспоненциальная сложность наблюдается в рекурсивных алгоритмах, таких как вычисление чисел Фибоначчи без мемоизации. На каждом шаге создаётся две новые ветви вычислений, что приводит к экспоненциальному росту времени выполнения с увеличением входных данных.
Факториальная сложность возникает в задачах, связанных с вычислением всех возможных перестановок или комбинаций. Например, задача генерации всех перестановок строки: с увеличением длины строки число возможных комбинаций возрастает факториально.
Этот тип сложности встречается, например, в алгоритмах поиска делителей числа или проверки на простоту. Например, чтобы проверить, является ли число простым, достаточно проверить делители до его квадратного корня, что сокращает количество операций по сравнению с линейным подходом.
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤7🔥4
Класс LocalDateTime
Класс LocalDateTime используется для работы с датой и временем без учета часового пояса.
Он появился в Java 8 в пакете java.time и является частью новой date/time API, которая пришла на смену устаревшим классам Date и Calendar.
Основные возможности класса LocalDateTime:
— Хранение даты и времени с точностью до наносекунд.
— Получение различных компонентов даты/времени (год, месяц, день недели и т. д.).
— Выполнение операций сложения и вычитания дат и интервалов.
— Сравнение и сортировка дат по времени.
— Форматирование и парсинг строк по заданному шаблону.
Подписывайся на наш канал в Max🟪
Класс LocalDateTime используется для работы с датой и временем без учета часового пояса.
Он появился в Java 8 в пакете java.time и является частью новой date/time API, которая пришла на смену устаревшим классам Date и Calendar.
Основные возможности класса LocalDateTime:
— Хранение даты и времени с точностью до наносекунд.
— Получение различных компонентов даты/времени (год, месяц, день недели и т. д.).
— Выполнение операций сложения и вычитания дат и интервалов.
— Сравнение и сортировка дат по времени.
— Форматирование и парсинг строк по заданному шаблону.
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍3😁1
🚀 Хотите стать Java-разработчиком с нуля и освоить востребованную профессию?
Онлайн-курс «Java-разработчик» - это трёхступенчатая программа, где за 15 месяцев вы пройдёте путь от новичка до уровня Middle:
- Junior: освоите синтаксис Java, базовые алгоритмы, работу с Docker и базами данных
- Junior+: изучите JVM, паттерны проектирования, многопоточность, серверные приложения и Hibernate
- Middle: разберётесь с Spring, Web-приложениями, NoSQL, транзакциями, авторизацией и облачными сервисами
Вы научитесь создавать приложения на Java, работать с реляционными и NoSQL базами, разрабатывать серверные веб-приложения и использовать инструменты: IntelliJ IDEA, Spring, Hibernate, PostgreSQL, Docker, Kubernetes, Kafka, RabbitMQ, JUnit, Postman, Jira.
🔥 Начните с бесплатного вебинара: «Основы синтаксиса Java: что важно знать при переходе с другого языка?»
📅 20 октября, 20:00
На вебинаре вы:
- Освоите переменные, типы данных, операторы
- Разберёте структуру программы: классы, методы, main()
- Попрактикуетесь в написании первой Java-программы
- Получите ответы на вопросы в реальном времени
⚡️ Не упустите шанс: вебинар бесплатный, а курс поможет пройти путь до Middle Java-разработчика!
📲 Регистрация на вебинар: https://vk.cc/cQw781
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Онлайн-курс «Java-разработчик» - это трёхступенчатая программа, где за 15 месяцев вы пройдёте путь от новичка до уровня Middle:
- Junior: освоите синтаксис Java, базовые алгоритмы, работу с Docker и базами данных
- Junior+: изучите JVM, паттерны проектирования, многопоточность, серверные приложения и Hibernate
- Middle: разберётесь с Spring, Web-приложениями, NoSQL, транзакциями, авторизацией и облачными сервисами
Вы научитесь создавать приложения на Java, работать с реляционными и NoSQL базами, разрабатывать серверные веб-приложения и использовать инструменты: IntelliJ IDEA, Spring, Hibernate, PostgreSQL, Docker, Kubernetes, Kafka, RabbitMQ, JUnit, Postman, Jira.
🔥 Начните с бесплатного вебинара: «Основы синтаксиса Java: что важно знать при переходе с другого языка?»
📅 20 октября, 20:00
На вебинаре вы:
- Освоите переменные, типы данных, операторы
- Разберёте структуру программы: классы, методы, main()
- Попрактикуетесь в написании первой Java-программы
- Получите ответы на вопросы в реальном времени
⚡️ Не упустите шанс: вебинар бесплатный, а курс поможет пройти путь до Middle Java-разработчика!
📲 Регистрация на вебинар: https://vk.cc/cQw781
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
❤2👍2🔥2
Совет 💡
Обычно при сортировке в Spring Data мы указываем свойство, по которому хотим отсортировать, как строку. Однако существует класс
Подписывайся на наш канал в Max🟪
Обычно при сортировке в Spring Data мы указываем свойство, по которому хотим отсортировать, как строку. Однако существует класс
TypedSort, который дает нам возможность передавать функцию в качестве параметра для сортировки. Это повышает безопасность типов в нашем коде.Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22❤6🔥5
— Полный контроль за счёт написания SQL-запросов.
— Без лишней магии запросы выполняются быстро.
— Работает с любой реляционной БД без привязки к ORM.
— Нужно самому писать маппинг объектов, обрабатывать исключения и управлять соединениями.
— Нет встроенного кэширования, ленивой загрузки и работы с графами объектов.
— Нужно следить за autocommit и rollback.
— Работа с БД ведётся через Entity, а SQL-запросы формируются автоматически.
— Поддержка связей (@OneToMany и т. д.), ленивой загрузки и кэширования.
— Поддержка автоматического управления транзакциями через EntityManager.
— Много аннотаций, конфигураций и магии.
— Автоматическая генерация запросов не всегда эффективна.
— Нужно разбираться, какой SQL-запрос Hibernate сгенерировал и почему.
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤3🔥1
Совет 💡
Добавьте в JDBC URL свойство
Подписывайся на наш канал в Max🟪
Добавьте в JDBC URL свойство
ApplicationName (зависит от БД, не в каждой БД оно есть!). Таким образом, в списке сессий вместо имени JDBC-драйвера будет отображаться имя набора. Это поможет при поиске неисправностей, когда несколько приложений подключаются к одной и той же БД.Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥3❤1
Spring управляет созданием бинов через Dependency Injection (DI), но при большом количестве компонентов это замедляет запуск приложения и расходует память.
Используйте @Lazy, чтобы откладывать создание бина до первого вызова:
@Component
public class Component {
@Lazy
@Autowired
private Service service;
}
— Редко используемые сервисы (например, отчёты, аналитика).
— В крупных приложениях с тысячами зависимостей.
— В микросервисах для уменьшения потребления ресурсов.
— При загрузке тяжёлых конфигураций.
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥5❤3❤🔥1
🧑💻 PoCo — генератор классов-сборщиков для сложных объектов. Вместо ручного долгого парсинга POJO, библиотека автоматически генерирует оптимизированные классы-сборщики на этапе компиляции.
📥 Библиотека интегрируется через Gradle-плагин и не требует runtime-зависимостей. В планах разработки — расширение поддержки кастомных контейнеров и интерфейсов, что сделает решение ещё более гибким.
📝 PoCo стоит рассмотреть тем, кто работает с комплексными доменными моделями и устал от длительного ручного парсинга данных.
🖥 Github
Подписывайся на наш канал в Max🟪
📥 Библиотека интегрируется через Gradle-плагин и не требует runtime-зависимостей. В планах разработки — расширение поддержки кастомных контейнеров и интерфейсов, что сделает решение ещё более гибким.
📝 PoCo стоит рассмотреть тем, кто работает с комплексными доменными моделями и устал от длительного ручного парсинга данных.
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍3🔥3
В корпоративных системах управление доступом часто становится узким местом — особенно когда речь идёт о гибкой настройке ролей и разрешений. Вместо ручного «if-else администрирования» можно подключить AI и быстро нагенерировать полноценный слой RBAC.
📝 Промпт:
Generate a Spring Security configuration for a Spring Boot 3 application with Role-Based Access Control (RBAC).
— Configure Spring Security with role-based access (ADMIN, USER, MANAGER).
— Implement method-level security with @PreAuthorize and SpEL expressions.
— Set up JWT authentication with custom claims (roles, permissions).
— Create a PermissionEvaluator for fine-grained access checks (e.g. entity-level access).
— Integrate with a database-backed UserDetailsService for dynamic role management.
— Add an admin API endpoint for managing roles and permissions at runtime.
— Ensure audit logging of access control decisions.
— Добавьте
Multi-tenancy support with tenant-aware role resolution.— Добавьте
Attribute-Based Access Control (ABAC) для сложных бизнес-правил.— Добавьте
Integration with Keycloak или OAuth2 provider для централизованного управления доступом.Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥5👍3
Живая телеметрия без overhead
Если вам нужно анализировать производительность приложения в реальном времени, но профилировщики вроде VisualVM или async-profiler слишком тяжелые, то Java Flight Recorder (JFR) Event Streaming — ваш новый лучший друг.
JFR давно встроен в JVM и собирает метрики без ощутимого влияния на производительность (накладные расходы <1%). Раньше, чтобы получить данные, нужно было снимать дамп и разбирать его постфактум. Начиная с Java 14 пакет jdk.jfr.consumer предоставляет API, благодаря которому можно стримить события в реальном времени прямо в приложение.
🟢 Пример использования
Допустим, вы хотите следить за количеством вызовов System.gc() (или любыми другими JVM-событиями):
🟢 Что происходит
🔘 EventStream.openRepository() — подключается к JFR и слушает события онлайн
🔘 onEvent("jdk.GarbageCollection", callback) — подписывается на сборку мусора
🔘 stream.start(); — запускает стриминг
🟢 Где полезно
1️⃣ Мониторинг продакшена — следите за GC, JIT-компиляцией, блокировками потоков без перезапуска JVM.
2️⃣ Анализ нагрузки — получайте данные о CPU, аллокациях памяти, I/O в реальном времени.
3️⃣ Трассировка медленных запросов — находите узкие места без включения дорогих профилировщиков.
🟢 Что нужно знать
🔘 Работает без agent'ов и почти без overhead.
🔘 Доступно из коробки в OpenJDK 14+.
🔘 Встроенные события JVM уже можно стримить, но для своих нужно создать Custom JFR Events.
❓ Вы уже пробовали JFR Event Streaming?
Подписывайся на наш канал в Max🟪
Если вам нужно анализировать производительность приложения в реальном времени, но профилировщики вроде VisualVM или async-profiler слишком тяжелые, то Java Flight Recorder (JFR) Event Streaming — ваш новый лучший друг.
JFR давно встроен в JVM и собирает метрики без ощутимого влияния на производительность (накладные расходы <1%). Раньше, чтобы получить данные, нужно было снимать дамп и разбирать его постфактум. Начиная с Java 14 пакет jdk.jfr.consumer предоставляет API, благодаря которому можно стримить события в реальном времени прямо в приложение.
Допустим, вы хотите следить за количеством вызовов System.gc() (или любыми другими JVM-событиями):
import jdk.jfr.consumer.*;
public class JfrStreamingExample {
public static void main(String[] args) {
try (var stream = EventStream.openRepository()) {
stream.onEvent("jdk.GarbageCollection", event ->
System.out.println("GC event: " + event.getLong("gcId"))
);
stream.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥7❤3⚡1
В чем разница между map() и flatMap()?
Оба метода используются для трансформации данных в Stream, но с ключевыми отличиями:
▪️ map(Function<T, R>) применяет функцию к каждому элементу потока и возвращает поток с преобразованными элементами (Stream<R>).
▪️ flatMap(Function<T, Stream<R>>) делает то же самое, но ожидает, что функция вернет Stream<R>, а затем "выпрямляет" вложенные потоки в один Stream<R>.
📌 Пример:
Подписывайся на наш канал в Max🟪
Оба метода используются для трансформации данных в Stream, но с ключевыми отличиями:
▪️ map(Function<T, R>) применяет функцию к каждому элементу потока и возвращает поток с преобразованными элементами (Stream<R>).
▪️ flatMap(Function<T, Stream<R>>) делает то же самое, но ожидает, что функция вернет Stream<R>, а затем "выпрямляет" вложенные потоки в один Stream<R>.
List<String> words = List.of("Hello", "World");
// map(): превращает каждое слово в список символов
List<List<Character>> mapped = words.stream()
.map(word -> word.chars()
.mapToObj(c -> (char) c)
.toList())
.toList();
// flatMap(): превращает каждое слово в поток символов и "сплющивает" их в один поток
List<Character> flatMapped = words.stream()
.flatMap(word -> word.chars()
.mapToObj(c -> (char) c))
.toList();
System.out.println(mapped); // [[H, e, l, l, o], [W, o, r, l, d]]
System.out.println(flatMapped); // [H, e, l, l, o, W, o, r, l, d]Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥5❤4
🔥27 октября в 20:00 мск — открытый вебинар в OTUS!
О чём вебинар?
Хотите заглянуть под капот TikTok, Netflix и Telegram? Разберём, как эти гиганты справляются с миллионами пользователей! Узнайте, как TikTok создаёт персональные рекомендации в реальном времени, Netflix обеспечивает бесперебойный стриминг через CDN и микросервисы, а Telegram молниеносно доставляет сообщения.
Что разберём:
- TikTok: алгоритмы рекомендаций и инфраструктура мгновенной доставки контента.
- Netflix: использование CDN и микросервисов для стриминга без сбоев.
- Telegram: очереди, репликация и хранение сообщений под высокой нагрузкой.
- Highload-паттерны: кэширование, шардирование и техники отказоустойчивости.
🎓 После вебинара вы:
- Разберётесь, как ведущие платформы выдерживают колоссальные нагрузки.
- Освоите ключевые подходы к кэшированию, шардированию и отказоустойчивости.
🔧 Присоединяйтесь, чтобы раскрыть секреты архитектур TikTok, Netflix и Telegram и прокачать свои навыки в Highload!
👉 Зарегистрироваться https://vk.cc/cQDKQ3
Бесплатное занятие приурочено к старту курса Highload Architect, обучение на котором позволит освоить решения, которые выдерживают большое количество запросов в секунду и правильно оптимизировать работоспособность серверов
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
О чём вебинар?
Хотите заглянуть под капот TikTok, Netflix и Telegram? Разберём, как эти гиганты справляются с миллионами пользователей! Узнайте, как TikTok создаёт персональные рекомендации в реальном времени, Netflix обеспечивает бесперебойный стриминг через CDN и микросервисы, а Telegram молниеносно доставляет сообщения.
Что разберём:
- TikTok: алгоритмы рекомендаций и инфраструктура мгновенной доставки контента.
- Netflix: использование CDN и микросервисов для стриминга без сбоев.
- Telegram: очереди, репликация и хранение сообщений под высокой нагрузкой.
- Highload-паттерны: кэширование, шардирование и техники отказоустойчивости.
🎓 После вебинара вы:
- Разберётесь, как ведущие платформы выдерживают колоссальные нагрузки.
- Освоите ключевые подходы к кэшированию, шардированию и отказоустойчивости.
🔧 Присоединяйтесь, чтобы раскрыть секреты архитектур TikTok, Netflix и Telegram и прокачать свои навыки в Highload!
👉 Зарегистрироваться https://vk.cc/cQDKQ3
Бесплатное занятие приурочено к старту курса Highload Architect, обучение на котором позволит освоить решения, которые выдерживают большое количество запросов в секунду и правильно оптимизировать работоспособность серверов
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
❤3👍2🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
Ctrl + C и Ctrl + V, тебе точно понравится и Ctrl + W. Это как выделение текста с помощью AI 😉
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍5❤4
Улучшаем работу с Optional
Все используют Optional, но не все знают, как сделать это лучше. Нередко можно встретить такой код:
Такой код не только избыточен, но и может привести к NoSuchElementException, если забыть проверить isPresent(). Поэтому лучше использовать ifPresent(), чтобы оптимизировать код:
📌 Какие ещё варианты
— Для выполнения действия, если значение есть (ifPresent()).
— Для подстановки дефолтного значения (orElse() / orElseGet()).
— Для обработки исключений (orElseThrow()).
⚠️ Плохие практики
🔘 Использовать Optional в качестве аргументов методов — это ломает читаемость API.
🔘 Использовать Optional.get() без проверки — это сводит всю пользу Optional на нет.
Подписывайся на наш канал в Max🟪
Все используют Optional, но не все знают, как сделать это лучше. Нередко можно встретить такой код:
Optional<User> userOpt = findUserById(id);
if (userOpt.isPresent()) {
User user = userOpt.get();
processUser(user);
}
Такой код не только избыточен, но и может привести к NoSuchElementException, если забыть проверить isPresent(). Поэтому лучше использовать ifPresent(), чтобы оптимизировать код:
findUserById(id).ifPresent(this::processUser);
— Для выполнения действия, если значение есть (ifPresent()).
— Для подстановки дефолтного значения (orElse() / orElseGet()).
— Для обработки исключений (orElseThrow()).
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7💯2👍1
Когда код становится сложнее, простого Find Usages уже мало. Хотите понять, откуда пришло значение переменной или куда оно утекает? Для этого есть Analyze Data Flow.
— Позволяет проследить поток данных: где переменная инициализируется, как модифицируется и где используется
— Работает не только для переменных, но и для параметров методов, полей и возвращаемых значений
— Может анализировать как «куда идёт», так и «откуда пришло» (Forward/Backward analysis)
— Быстро понять, почему метод получает null (и где он берётся)
— Выявить неочевидные зависимости между частями кода
— Ускорить отладку без бесконечного «шагания» по дебаггеру
— Выделите переменную или метод
— Analyze → Data Flow to Here / Data Flow from Here
— IDEA визуально покажет дерево зависимостей
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍23🔥9❤4
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥10❤2
Мне НЕ нужно разбираться с управлением памятью в Java, так как за меня всё делает GC
Garbage Collector (GC) действительно очищает неиспользуемые объекты, которые больше не имеют активных ссылок. Благодаря этому в Java не нужно вручную освобождать память, как в C++.
Несколько предпосылок к исходному тезису:
GC удаляет только те объекты, которые больше не имеют активных ссылок. Если же объект остаётся доступным, но фактически не используется, он будет занимать память до завершения работы приложения.
Если создать static List и постоянно добавлять в него объекты, они никогда не будут удалены GC, потому что статические поля живут весь срок жизни приложения.
public class MemoryLeak {
private static final List<byte[]> cache = new ArrayList<>();
public static void main(String[] args) {
while (true) {
cache.add(new byte[10 * 1024 * 1024]);
System.out.println("Добавили 10MB в кеш. Используемая память: " +
(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / (1024 * 1024) + "MB");
}
}
}Через пару минут — OutOfMemoryError
Объекты, хранящиеся в ThreadLocal, привязываются к потоку, а в пуле потоков они могут жить дольше, чем нужно.
public class ThreadLocalLeak {
private static final ThreadLocal<byte[]> threadLocalData = new ThreadLocal<>();
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executor.execute(() -> {
threadLocalData.set(new byte[10 * 1024 * 1024]); // 10MB на поток
System.out.println("Память занята потоком!");
});
}
executor.shutdown();
}
}Поток завершится, а память останется занята, потому что ThreadLocal не очищается автоматически.
Если анонимный класс или лямбда-ссылка ссылается на внешний объект, она может мешать GC очистить его.
public class InnerClassLeak {
private String data = "Очень важные данные";
public void createAnonymousClass() {
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Используем: " + data);
}
};
new Thread(task).start();
}
}task ссылается на data, даже если InnerClassLeak больше не используется → GC не очистит объект.
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥18👍7❤3
Приглашаем на открытый урок.
🗓 27 октября в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java Developer. Advanced».
Minikube — личный Kubernetes для тестов. Научитесь деплоить Java-приложения — база для DevOps, CI/CD и продакшна.
Что будет на вебинаре:
В результате вебинара вы:
Кому будет интересно:
Java-разработчикам, начинающим осваивать Kubernetes и DevOps-подходы, а также инженерам, выстраивающим локальные CI/CD практики.
🔗 Ссылка на регистрацию: https://vk.cc/cQJjuN
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍3🔥2
📊 MQCloud — корпоративный центр управления RocketMQ.
Это единая платформа, которая объединяет управление очередями, мониторинг и алертинг в одном интерфейсе.
Сервис уже обслуживает десятки серверов, сотни топиков и миллиарды сообщений ежедневно. Он умеет показывать топологию кластеров, детализацию по производителям и потребителям, а также предупреждать о проблемах вроде скопления сообщений или сбоев.
Особенно удобно, что MQCloud разграничивает права: обычные пользователи видят только свои очереди, а администраторы получают полный контроль с возможностью согласования изменений.
🖥 GitHub
Подписывайся на наш канал в Max🟪
Это единая платформа, которая объединяет управление очередями, мониторинг и алертинг в одном интерфейсе.
Сервис уже обслуживает десятки серверов, сотни топиков и миллиарды сообщений ежедневно. Он умеет показывать топологию кластеров, детализацию по производителям и потребителям, а также предупреждать о проблемах вроде скопления сообщений или сбоев.
Особенно удобно, что MQCloud разграничивает права: обычные пользователи видят только свои очереди, а администраторы получают полный контроль с возможностью согласования изменений.
Подписывайся на наш канал в Max
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍3🔥3