Зачем использовать `
- Включение или отключение бинов и конфигураций на основе значений в `application.properties` без изменения кода
- Загрузка разных бинов для разных сред с помощью конфигурационных параметров
- Исключение лишних бинов снижает потребление памяти и упрощает логику
🔸 Включить бин, если свойство существует:
Используется аннотация
Бин будет создан, если свойство my.prop существует и его значение не "false".
🔸 Включить бин, если свойство равно определённому значению:
Добавляется параметр
Бин будет создан только в том случае, если значение свойства строго равно "yes".
🔸 Включить бин, если свойство отсутствует:
Используется параметр
Бин будет создан даже в случае, если соответствующее свойство вообще не определено в конфигурации.
🔸 Переключение реализаций в зависимости от значения свойства:
Определяются несколько бинов с разными значениями
Будет создан только тот бин, значение которого соответствует текущему значению свойства.
👉 Java Portal
@ConditionalOnProperty
`?- Включение или отключение бинов и конфигураций на основе значений в `application.properties` без изменения кода
- Загрузка разных бинов для разных сред с помощью конфигурационных параметров
- Исключение лишних бинов снижает потребление памяти и упрощает логику
Используется аннотация
@ConditionalOnProperty(name="my.prop")
.Бин будет создан, если свойство my.prop существует и его значение не "false".
Добавляется параметр
havingValue="yes"
.Бин будет создан только в том случае, если значение свойства строго равно "yes".
Используется параметр
matchIfMissing=true
.Бин будет создан даже в случае, если соответствующее свойство вообще не определено в конфигурации.
Определяются несколько бинов с разными значениями
havingValue
.Будет создан только тот бин, значение которого соответствует текущему значению свойства.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍4
Spring Boot Actuator это мощный набор инструментов в составе Spring Boot, который помогает мониторить и управлять приложением в продакшене. Он предоставляет доступ к различным endpoint'ам, через которые можно получить информацию о внутреннем состоянии приложения - метрики, окружение, дампы потоков и т.д.
Что даёт Actuator:
- статус, метрики, окружение и прочее
- Поддержка мониторинга и управления через HTTP, JMX или кастомные endpoint'ы
- Повышенная наблюдаемость, особенно в связке с Prometheus, Grafana, Micrometer или Spring Boot Admin
Часто используемые endpoint'ы:
🔸 /actuator/health
Показывает статус работоспособности приложения
Доступ по умолчанию: Public
🔸 /actuator/info
Выводит информацию из
Доступ по умолчанию: Public
🔸 /actuator/metrics
Показывает различные метрики производительности
Доступ по умолчанию: Restricted
🔸 /actuator/env
Показывает переменные окружения
Доступ по умолчанию: Restricted
🔸 /actuator/beans
Показывает все Spring Beans
Доступ по умолчанию: Restricted
🔸 /actuator/threaddump
Дамп потоков приложения
Доступ по умолчанию: Restricted
🔸 /actuator/loggers
Просмотр или изменение уровней логирования на лету
Доступ по умолчанию: Restricted
🔸 /actuator/heapdump
Скачивание heap dump
Доступ по умолчанию: Restricted
🔸 /actuator/prometheus
Метрики в формате Prometheus (если подключён micrometer-registry-prometheus)
Доступ по умолчанию: Public
👉 Java Portal
Что даёт Actuator:
- статус, метрики, окружение и прочее
- Поддержка мониторинга и управления через HTTP, JMX или кастомные endpoint'ы
- Повышенная наблюдаемость, особенно в связке с Prometheus, Grafana, Micrometer или Spring Boot Admin
Часто используемые endpoint'ы:
Показывает статус работоспособности приложения
Доступ по умолчанию: Public
Выводит информацию из
application.properties
Доступ по умолчанию: Public
Показывает различные метрики производительности
Доступ по умолчанию: Restricted
Показывает переменные окружения
Доступ по умолчанию: Restricted
Показывает все Spring Beans
Доступ по умолчанию: Restricted
Дамп потоков приложения
Доступ по умолчанию: Restricted
Просмотр или изменение уровней логирования на лету
Доступ по умолчанию: Restricted
Скачивание heap dump
Доступ по умолчанию: Restricted
Метрики в формате Prometheus (если подключён micrometer-registry-prometheus)
Доступ по умолчанию: Public
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
Лучшие практики для микросервисов
1. Отдельное хранилище данных
🔸 Каждый микросервис должен использовать свою собственную базу данных, чтобы обеспечить изоляцию данных и слабую связанность.
2. Единый уровень зрелости кода
🔸 Старайтесь поддерживать код всех сервисов примерно на одинаковом уровне зрелости (тестируемость, покрытие, качество).
3. Отдельная сборка для каждого микросервиса
🔸 У каждого сервиса должна быть своя сборочная цепочка (CI/CD pipeline), чтобы обеспечить независимость деплоя.
4. Принцип единственной ответственности
🔸 Один сервис — одна бизнес-задача. Не смешивайте домены и обязанности в рамках одного микросервиса.
5. Развёртывание в контейнерах
🔸 Используйте контейнеры (например, Docker) для упаковки и запуска каждого микросервиса независимо.
6. Обрабатывайте серверы как статeless
🔸 Сервисы не должны хранить состояние между запросами. Состояние — либо в БД, либо во внешнем хранилище.
7. Domain-Driven Design (DDD)
🔸 Стройте архитектуру на основе бизнес-домена: делите систему на логически обоснованные сервисы, а не технические модули.
8. Микрофронтенд
🔸 Разделяйте frontend-приложения по тому же принципу, что и backend: независимые фронты взаимодействуют через API Gateway.
9. Оркестрация микросервисов
🔸 Используйте системы оркестрации (например, Kubernetes), чтобы управлять масштабированием, деплоем и связью между сервисами.
👉 Java Portal
1. Отдельное хранилище данных
2. Единый уровень зрелости кода
3. Отдельная сборка для каждого микросервиса
4. Принцип единственной ответственности
5. Развёртывание в контейнерах
6. Обрабатывайте серверы как статeless
7. Domain-Driven Design (DDD)
8. Микрофронтенд
9. Оркестрация микросервисов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤2🔥2
Проект на Spring Boot + Spring AI + OpenAI.
Он принимает текст или файл с заметками встречи и автоматически генерирует JSON-тикеты с классификацией (баг, фича и т.д.).
Теперь в open source: чистый код и готовность к импорту в JIRA.
GitHub: https://github.com/ayushstwt/smart-ticket-ai.git
👉 Java Portal
Он принимает текст или файл с заметками встречи и автоматически генерирует JSON-тикеты с классификацией (баг, фича и т.д.).
Теперь в open source: чистый код и готовность к импорту в JIRA.
GitHub: https://github.com/ayushstwt/smart-ticket-ai.git
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1
Algorithmic Thinking Patterns
🔸 Паттерн: Two Pointers
Суть идеи: Ввести два индекса и двигать их по массиву
Когда использовать: Отсортированные массивы, удаление дубликатов, реверс
Типовые задачи: Reverse array in-place, 3Sum, Remove Duplicates
🔸 Паттерн: Sliding Window
Суть идеи: Оптимизация задач на подмассивы путём расширения/сжатия окна
Когда использовать: Строки, макс/мин в окне, шаблоны фиксированной длины
Типовые задачи: Longest substring w/o repeats, Max sum of k-size subarray
🔸 Паттерн: Binary Search on Answer
Суть идеи: Вместо поиска элемента ищем min/max значение, удовлетворяющее условию
Когда использовать: Монотонное пространство поиска
Типовые задачи: Min eating speed, Aggressive cows, Capacity to ship packages
🔸 Паттерн: Prefix Sum / Difference Array
Суть идеи: Предобработка для ответов на запросы за O(1)
Когда использовать: Сумма/частота на интервалах, перекрывающиеся диапазоны
Типовые задачи: Subarray sum = K, Difference array for range updates
🔸 Паттерн: Greedy
Суть идеи: Выбираем на каждом шаге локально лучший вариант, надеясь на глобальный оптимум
Когда использовать: Когда выбор можно отсортировать или сравнить
Типовые задачи: Activity selection, Gas Station, Jump Game
🔸 Паттерн: Backtracking
Суть идеи: Перебираем все варианты и откатываемся с неверных путей
Когда использовать: Комбинации, перестановки, ограничения
Типовые задачи: N-Queens, Sudoku Solver, Subset Sum
🔸 Паттерн: Bitmasking
Суть идеи: Используем биты для представления подмножеств или флагов
Когда использовать: Маленькие N (N ≤ 20), переключаем состояния
Типовые задачи: Count set bits, Subset sum, Traveling Salesman
🔸 Паттерн: Union-Find (DSU)
Суть идеи: Эффективно объединяем и находим компоненты
Когда использовать: Связность, обнаружение циклов
Типовые задачи: Number of Provinces, Kruskal's MST, Friend Circles
🔸 Паттерн: Monotonic Stack / Queue
Суть идеи: Поддерживаем монотонно возрастающую или убывающую структуру
Когда использовать: Следующий больше/меньше, максимум по диапазону
Типовые задачи: Daily Temperatures, Largest rectangle in histogram
🔸 Паттерн: Topological Sort
Суть идеи: Линейный порядок задач по зависимостям
Когда использовать: Ацикличные графы (DAG), планирование
Типовые задачи: Course Schedule, Build Order, Alien Dictionary
🔸 Паттерн: Dynamic Programming (Tabulation)
Суть идеи: Итеративное решение снизу вверх с мемоизацией
Когда использовать: Пересекающиеся подзадачи
Типовые задачи: 0/1 Knapsack, Edit Distance, House Robber
🔸 Паттерн: Divide & Conquer
Суть идеи: Рекурсивное деление входных данных
Когда использовать: Сортировка, сложные рекурсии
Типовые задачи: Merge Sort, Count Inversions, Median of Two Sorted Arrays
🔸 Паттерн: DFS with Memoization
Суть идеи: Сохраняем уже посчитанные значения, чтобы не вычислять повторно
Когда использовать: DAG, рекурсивное ДП
Типовые задачи: Word Break, Unique Paths III, Longest Increasing Path
🔸 Паттерн: Meet in the Middle
Суть идеи: Делим массив пополам, решаем обе части и объединяем
Когда использовать: N ≤ 40, полный перебор слишком дорог
Типовые задачи: Partition to Equal Sum, K-Sum Variants
🔸 Паттерн: Trie-Based Search
Суть идеи: Деревья префиксов
Когда использовать: Поиск слов, автодополнение
Типовые задачи: Implement Trie, Replace Words, Word Squares
🔸 Паттерн: Segment Tree / BIT
Суть идеи: Эффективные запросы и обновления на диапазонах
Когда использовать: Большие массивы, частые модификации
Типовые задачи: Range sum/min/max, Inversions, Lazy Propagation
🔸 Паттерн: Floyd’s Cycle Detection
Суть идеи: Обнаружение цикла с быстрым и медленным указателями
Когда использовать: Связные списки, конечные автоматы
Типовые задачи: Linked List Cycle, Happy Number
👉 Java Portal
Суть идеи: Ввести два индекса и двигать их по массиву
Когда использовать: Отсортированные массивы, удаление дубликатов, реверс
Типовые задачи: Reverse array in-place, 3Sum, Remove Duplicates
Суть идеи: Оптимизация задач на подмассивы путём расширения/сжатия окна
Когда использовать: Строки, макс/мин в окне, шаблоны фиксированной длины
Типовые задачи: Longest substring w/o repeats, Max sum of k-size subarray
Суть идеи: Вместо поиска элемента ищем min/max значение, удовлетворяющее условию
Когда использовать: Монотонное пространство поиска
Типовые задачи: Min eating speed, Aggressive cows, Capacity to ship packages
Суть идеи: Предобработка для ответов на запросы за O(1)
Когда использовать: Сумма/частота на интервалах, перекрывающиеся диапазоны
Типовые задачи: Subarray sum = K, Difference array for range updates
Суть идеи: Выбираем на каждом шаге локально лучший вариант, надеясь на глобальный оптимум
Когда использовать: Когда выбор можно отсортировать или сравнить
Типовые задачи: Activity selection, Gas Station, Jump Game
Суть идеи: Перебираем все варианты и откатываемся с неверных путей
Когда использовать: Комбинации, перестановки, ограничения
Типовые задачи: N-Queens, Sudoku Solver, Subset Sum
Суть идеи: Используем биты для представления подмножеств или флагов
Когда использовать: Маленькие N (N ≤ 20), переключаем состояния
Типовые задачи: Count set bits, Subset sum, Traveling Salesman
Суть идеи: Эффективно объединяем и находим компоненты
Когда использовать: Связность, обнаружение циклов
Типовые задачи: Number of Provinces, Kruskal's MST, Friend Circles
Суть идеи: Поддерживаем монотонно возрастающую или убывающую структуру
Когда использовать: Следующий больше/меньше, максимум по диапазону
Типовые задачи: Daily Temperatures, Largest rectangle in histogram
Суть идеи: Линейный порядок задач по зависимостям
Когда использовать: Ацикличные графы (DAG), планирование
Типовые задачи: Course Schedule, Build Order, Alien Dictionary
Суть идеи: Итеративное решение снизу вверх с мемоизацией
Когда использовать: Пересекающиеся подзадачи
Типовые задачи: 0/1 Knapsack, Edit Distance, House Robber
Суть идеи: Рекурсивное деление входных данных
Когда использовать: Сортировка, сложные рекурсии
Типовые задачи: Merge Sort, Count Inversions, Median of Two Sorted Arrays
Суть идеи: Сохраняем уже посчитанные значения, чтобы не вычислять повторно
Когда использовать: DAG, рекурсивное ДП
Типовые задачи: Word Break, Unique Paths III, Longest Increasing Path
Суть идеи: Делим массив пополам, решаем обе части и объединяем
Когда использовать: N ≤ 40, полный перебор слишком дорог
Типовые задачи: Partition to Equal Sum, K-Sum Variants
Суть идеи: Деревья префиксов
Когда использовать: Поиск слов, автодополнение
Типовые задачи: Implement Trie, Replace Words, Word Squares
Суть идеи: Эффективные запросы и обновления на диапазонах
Когда использовать: Большие массивы, частые модификации
Типовые задачи: Range sum/min/max, Inversions, Lazy Propagation
Суть идеи: Обнаружение цикла с быстрым и медленным указателями
Когда использовать: Связные списки, конечные автоматы
Типовые задачи: Linked List Cycle, Happy Number
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤3🔥3😁1👀1
Модернизация алгоритмов: От наивного → оптимального
🔸 Two Sum (пара с заданной суммой)
Наивно: O(n²) — двойной цикл
Оптимально: O(n) с использованием HashMap
🔸 Find Duplicate Number (найти дубликат, 1 ≤ num ≤ n)
Наивно: HashSet или дополнительная память
Оптимально: Обнаружение цикла Флойда (O(1) по памяти)
🔸 Kth Largest Element (k-й по величине элемент)
Наивно: Сортировка массива (O(n log n))
Оптимально: QuickSelect (в среднем O(n)) или куча (Heap)
🔸 Longest Palindromic Substring (длиннейшая палиндромная подстрока)
Наивно: O(n³) — перебор всех подстрок
Оптимально: Расширение из центра (Expand Around Center, O(n²)), или алгоритм Манакера (O(n))
🔸 Max Subarray Sum (максимальная сумма подмассива)
Наивно: Генерация всех подмассивов
Оптимально: Алгоритм Кадане (Kadane’s Algorithm, O(n))
🔸 All Pairs Shortest Paths (кратчайшие пути между всеми вершинами)
Наивно: Запускать Dijkstra для каждой вершины
Оптимально: Алгоритм Флойда–Уоршелла (Floyd-Warshall, O(V³)), эффективен для плотных графов
🔸 Median in Data Stream (медиана в потоке данных)
Наивно: Сортировать после каждой вставки
Оптимально: Две кучи (Min Heap и Max Heap), вставка за O(log n)
🔸 Valid Anagram (анаграмма?)
Наивно: Сортировка строк
Оптимально: Подсчёт частот символов в массиве (O(n))
🔸 Permutations (перестановки)
Наивно: Сгенерировать и сохранить все перестановки
Оптимально: Рекурсивный Backtracking с отсечениями
🔸 Subset Sum Exists (проверка, существует ли сумма из подмножества)
Наивно: Перебор всех подмножеств (2ⁿ)
Оптимально: Динамическое программирование — снизу вверх или с мемоизацией
🔸 Product of Array Except Self (произведение всех кроме текущего)
Наивно: Умножать все кроме текущего, O(n²)
Оптимально: Префикс + суффикс произведения (O(n))
🔸 Shortest Unsorted Subarray (самый короткий несортированный подмассив)
Наивно: Сортировка и сравнение
Оптимально: Два указателя для границ (O(n))
🔸 Min Window Substring (минимальная подстрока с нужными символами)
Наивно: Перебор всех подстрок
Оптимально: Sliding Window + HashMap, O(n)
🔸 Search in Rotated Array (поиск в повернутом массиве)
Наивно: Линейный поиск
Оптимально: Модифицированный бинарный поиск
🔸 Count Inversions (подсчёт инверсий)
Наивно: Вложенные циклы, O(n²)
Оптимально: Модифицированный Merge Sort, O(n log n)
🔸 Check if Tree is Balanced (проверка сбалансированности дерева)
Наивно: Пересчитывать высоту на каждом шаге
Оптимально: Один проход — возвращаем высоту и статус баланса
🔸 Merge k Sorted Lists (слияние k отсортированных списков)
Наивно: Объединить всё и отсортировать
Оптимально: Слияние k списков через Min Heap, O(N log k)
🔸 Longest Consecutive Sequence (длиннейшая последовательность чисел)
Наивно: Сортировка и проход
Оптимально: HashSet + сканирование, O(n)
🔸 Word Ladder (преобразование слов)
Наивно: BFS от каждого слова
Оптимально: Предобработка + двусторонний BFS
🔸 Number of Islands (количество островов)
Наивно: DFS без отметок
Оптимально: DFS/BFS/Union-Find с отслеживанием посещённых клеток
👉 Java Portal
Наивно: O(n²) — двойной цикл
Оптимально: O(n) с использованием HashMap
Наивно: HashSet или дополнительная память
Оптимально: Обнаружение цикла Флойда (O(1) по памяти)
Наивно: Сортировка массива (O(n log n))
Оптимально: QuickSelect (в среднем O(n)) или куча (Heap)
Наивно: O(n³) — перебор всех подстрок
Оптимально: Расширение из центра (Expand Around Center, O(n²)), или алгоритм Манакера (O(n))
Наивно: Генерация всех подмассивов
Оптимально: Алгоритм Кадане (Kadane’s Algorithm, O(n))
Наивно: Запускать Dijkstra для каждой вершины
Оптимально: Алгоритм Флойда–Уоршелла (Floyd-Warshall, O(V³)), эффективен для плотных графов
Наивно: Сортировать после каждой вставки
Оптимально: Две кучи (Min Heap и Max Heap), вставка за O(log n)
Наивно: Сортировка строк
Оптимально: Подсчёт частот символов в массиве (O(n))
Наивно: Сгенерировать и сохранить все перестановки
Оптимально: Рекурсивный Backtracking с отсечениями
Наивно: Перебор всех подмножеств (2ⁿ)
Оптимально: Динамическое программирование — снизу вверх или с мемоизацией
Наивно: Умножать все кроме текущего, O(n²)
Оптимально: Префикс + суффикс произведения (O(n))
Наивно: Сортировка и сравнение
Оптимально: Два указателя для границ (O(n))
Наивно: Перебор всех подстрок
Оптимально: Sliding Window + HashMap, O(n)
Наивно: Линейный поиск
Оптимально: Модифицированный бинарный поиск
Наивно: Вложенные циклы, O(n²)
Оптимально: Модифицированный Merge Sort, O(n log n)
Наивно: Пересчитывать высоту на каждом шаге
Оптимально: Один проход — возвращаем высоту и статус баланса
Наивно: Объединить всё и отсортировать
Оптимально: Слияние k списков через Min Heap, O(N log k)
Наивно: Сортировка и проход
Оптимально: HashSet + сканирование, O(n)
Наивно: BFS от каждого слова
Оптимально: Предобработка + двусторонний BFS
Наивно: DFS без отметок
Оптимально: DFS/BFS/Union-Find с отслеживанием посещённых клеток
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥2
Spring Boot + Swagger
Документирование API без лишней головной боли.
Полное руководство читай здесь: тык
👉 Java Portal
Документирование API без лишней головной боли.
Полное руководство читай здесь: тык
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍3
Мини руководство по паттернам проектирования
🔸 Singleton
Реализация: статический экземпляр + приватный конструктор
Пример: логгер, менеджер конфигурации, пул подключений к БД
🔸 Factory
Реализация: метод create(String type) возвращает нужный подкласс
Пример: парсеры файлов (.json, .xml), отправка уведомлений
🔸 Abstract Factory
Реализация: интерфейс для создания связанных объектов без указания их классов
Пример: UI-темы (тёмная/светлая), фабрики виджетов операционной системы
🔸 Builder
Реализация: цепочка вызовов .set() + .build()
Пример: создание сложных объектов, например HTTP-запросов
🔸 Prototype
Реализация: клонирование существующего объекта через .clone()
Пример: игровые персонажи, шаблоны документов, клоны интерфейсов
🔸 Strategy
Реализация: интерфейс + метод setStrategy()
Пример: алгоритмы сортировки, платёжные процессоры
🔸 Observer
Реализация: список подписчиков + цикл notifyAll()
Пример: система событий, UI-слушатели, подписки на YouTube
🔸 Decorator
Реализация: обёртка над объектом + добавление поведения на лету
Пример: логгирование, сжатие, кэширование
🔸 Adapter
Реализация: класс-обёртка, преобразующий интерфейс
Пример: интеграция с легаси API, InputStreamReader
🔸 Facade
Реализация: один класс делегирует вызовы нескольким подсистемам
Пример: java.util.logging, фасад медиаплеера
🔸 Command
Реализация: инкапсуляция действия в объект с методом execute()
Пример: Undo/Redo, обработка нажатий кнопок
🔸 Chain of Responsibility
Реализация: каждый обработчик решает — обработать или передать дальше
Пример: эскалация тикетов в техподдержке, всплытие событий (event bubbling)
🔸 Template Method
Реализация: базовый класс задаёт общий алгоритм, подклассы переопределяют шаги
Пример: обработка онлайн-заказа — оплата → подтверждение → доставка
🔸 State
Реализация: поведение определяется текущим объектом состояния
Пример: состояния медиаплеера — воспроизведение/пауза/стоп
🔸 Mediator
Реализация: центральный объект управляет взаимодействием компонентов
Пример: менеджер чата, валидация форм в UI
🔸 Memento
Реализация: сохранение и восстановление внутреннего состояния объекта
Пример: история изменений, снапшоты состояния в текстовом редакторе
🔸 Visitor
Реализация: внешний класс выполняет операции над элементами структуры
Пример: обход файловой системы, обработка AST
🔸 Proxy
Реализация: обёртка над реальным объектом для контроля доступа или производительности
Пример: ленивая загрузка, контроль доступа, удалённые прокси
🔸 Composite
Реализация: древовидная структура, где элементы и группы обрабатываются одинаково
Пример: иерархия файлов и папок, UI-компоненты
🔸 Flyweight
Реализация: повторное использование объектов с общим внутренним состоянием
Пример: глифы шрифта, иконки интерфейса, текстуры в играх
🔸 Bridge
Реализация: разделение абстракции и реализации
Пример: представление UI → движок отрисовки (SVG, Canvas и т.д.)
👉 Java Portal
Реализация: статический экземпляр + приватный конструктор
Пример: логгер, менеджер конфигурации, пул подключений к БД
Реализация: метод create(String type) возвращает нужный подкласс
Пример: парсеры файлов (.json, .xml), отправка уведомлений
Реализация: интерфейс для создания связанных объектов без указания их классов
Пример: UI-темы (тёмная/светлая), фабрики виджетов операционной системы
Реализация: цепочка вызовов .set() + .build()
Пример: создание сложных объектов, например HTTP-запросов
Реализация: клонирование существующего объекта через .clone()
Пример: игровые персонажи, шаблоны документов, клоны интерфейсов
Реализация: интерфейс + метод setStrategy()
Пример: алгоритмы сортировки, платёжные процессоры
Реализация: список подписчиков + цикл notifyAll()
Пример: система событий, UI-слушатели, подписки на YouTube
Реализация: обёртка над объектом + добавление поведения на лету
Пример: логгирование, сжатие, кэширование
Реализация: класс-обёртка, преобразующий интерфейс
Пример: интеграция с легаси API, InputStreamReader
Реализация: один класс делегирует вызовы нескольким подсистемам
Пример: java.util.logging, фасад медиаплеера
Реализация: инкапсуляция действия в объект с методом execute()
Пример: Undo/Redo, обработка нажатий кнопок
Реализация: каждый обработчик решает — обработать или передать дальше
Пример: эскалация тикетов в техподдержке, всплытие событий (event bubbling)
Реализация: базовый класс задаёт общий алгоритм, подклассы переопределяют шаги
Пример: обработка онлайн-заказа — оплата → подтверждение → доставка
Реализация: поведение определяется текущим объектом состояния
Пример: состояния медиаплеера — воспроизведение/пауза/стоп
Реализация: центральный объект управляет взаимодействием компонентов
Пример: менеджер чата, валидация форм в UI
Реализация: сохранение и восстановление внутреннего состояния объекта
Пример: история изменений, снапшоты состояния в текстовом редакторе
Реализация: внешний класс выполняет операции над элементами структуры
Пример: обход файловой системы, обработка AST
Реализация: обёртка над реальным объектом для контроля доступа или производительности
Пример: ленивая загрузка, контроль доступа, удалённые прокси
Реализация: древовидная структура, где элементы и группы обрабатываются одинаково
Пример: иерархия файлов и папок, UI-компоненты
Реализация: повторное использование объектов с общим внутренним состоянием
Пример: глифы шрифта, иконки интерфейса, текстуры в играх
Реализация: разделение абстракции и реализации
Пример: представление UI → движок отрисовки (SVG, Canvas и т.д.)
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍5
This media is not supported in your browser
VIEW IN TELEGRAM
Кто не в курсе: Spring Debugger — это инструмент в IntelliJ IDEA, который помогает разбираться в контексте Spring Boot-приложения.
Прямо в проекте можно:
🔸 посмотреть список загруженных и неактивных бинов,
🔸 проверить значения конфигурационных свойств,
🔸 увидеть детали подключения к базе.
Удобно для дебага, особенно когда неясно, почему бин не поднялся или почему конфигурация работает не так, как ожидалось.
👉 Java Portal
Прямо в проекте можно:
Удобно для дебага, особенно когда неясно, почему бин не поднялся или почему конфигурация работает не так, как ожидалось.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤12
Совет дня:
Проверка (
- Первый блок проверяет, что по
- Второй блок проверяет, что по
👉 Java Portal
Проверка (
assert
) одиночного объекта против List<Object>
в ответах при использовании MockMvcTester
в Spring.- Первый блок проверяет, что по
/api/posts/1
возвращается Post, у которого title
равен "Post title here"
- Второй блок проверяет, что по
/api/posts
приходит список из 4 элементов типа Post
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍3🔥2👀2
Вопросы уровня Easy/Medium на собеседовании по Java
1. Что такое ключевое слово
Ответ:
Статические члены принадлежат классу, а не экземпляру.
Можно обращаться к ним без создания объекта.
В памяти существует только одна копия.
2. В чём разница между
Ответ:
- Абстрактный класс: может содержать реализации методов, конструкторы, поддерживает одиночное наследование
- Интерфейс: начиная с Java 8, может иметь методы по умолчанию, поддерживает множественное наследование, содержит только публичные методы
3. Что такое wrapper-классы и зачем они нужны?
Ответ:
Это объектные обёртки над примитивами (
Используются в коллекциях, обобщениях и там, где требуются объекты вместо примитивов.
4. Что делает оператор
Ответ:
Проверяет, является ли объект экземпляром определённого класса или интерфейса.
Возвращает boolean.
5. Что такое инкапсуляция и как её реализовать?
Ответ:
Сокрытие внутреннего состояния и предоставление доступа через методы.
Реализуется с помощью приватных полей и публичных геттеров/сеттеров.
6. Что такое абстракция и как она реализуется?
Ответ:
Сокрытие деталей реализации и упрощение интерфейса.
Реализуется через абстрактные классы и интерфейсы.
7. Можно ли переопределить
Ответ:
Нет. Приватные методы недоступны в наследниках, поэтому их нельзя переопределить.
8. Может ли класс быть одновременно
Ответ:
Нет.
а
9. Что такое marker-интерфейсы?
Ответ:
Интерфейсы без методов, используемые как метки.
Примеры:
10. Что такое diamond problem (проблема ромбовидного наследования)?
Ответ:
Проблема возникает при множественном наследовании,
если класс наследует двух родителей, имеющих общего предка — возникает неоднозначность, какой метод использовать.
11. В чём разница между
Ответ:
-
-
12. Что такое
Ответ:
- Fail-fast: выбрасывает
- Fail-safe: работает с копией коллекции, поэтому не выбрасывает исключений
👉 Java Portal
1. Что такое ключевое слово
static
и где оно используется?Ответ:
Статические члены принадлежат классу, а не экземпляру.
Можно обращаться к ним без создания объекта.
В памяти существует только одна копия.
2. В чём разница между
abstract class
и interface
?Ответ:
- Абстрактный класс: может содержать реализации методов, конструкторы, поддерживает одиночное наследование
- Интерфейс: начиная с Java 8, может иметь методы по умолчанию, поддерживает множественное наследование, содержит только публичные методы
3. Что такое wrapper-классы и зачем они нужны?
Ответ:
Это объектные обёртки над примитивами (
Integer
, Boolean
и т. д.). Используются в коллекциях, обобщениях и там, где требуются объекты вместо примитивов.
4. Что делает оператор
instanceof
?Ответ:
Проверяет, является ли объект экземпляром определённого класса или интерфейса.
Возвращает boolean.
5. Что такое инкапсуляция и как её реализовать?
Ответ:
Сокрытие внутреннего состояния и предоставление доступа через методы.
Реализуется с помощью приватных полей и публичных геттеров/сеттеров.
6. Что такое абстракция и как она реализуется?
Ответ:
Сокрытие деталей реализации и упрощение интерфейса.
Реализуется через абстрактные классы и интерфейсы.
7. Можно ли переопределить
private
-метод?Ответ:
Нет. Приватные методы недоступны в наследниках, поэтому их нельзя переопределить.
8. Может ли класс быть одновременно
abstract
и final
?Ответ:
Нет.
abstract
означает, что класс предназначен для наследования, а
final
— что класс нельзя наследовать.9. Что такое marker-интерфейсы?
Ответ:
Интерфейсы без методов, используемые как метки.
Примеры:
Serializable
, Cloneable
.10. Что такое diamond problem (проблема ромбовидного наследования)?
Ответ:
Проблема возникает при множественном наследовании,
если класс наследует двух родителей, имеющих общего предка — возникает неоднозначность, какой метод использовать.
11. В чём разница между
Collection
и Collections
?Ответ:
-
Collection
— корневой интерфейс для всех коллекций-
Collections
— утилитарный класс с набором статических методов для работы с коллекциями12. Что такое
fail-fast
и fail-safe
итераторы?Ответ:
- Fail-fast: выбрасывает
ConcurrentModificationException
, если коллекция была изменена во время итерации- Fail-safe: работает с копией коллекции, поэтому не выбрасывает исключений
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15👍7🔥5
Обзор версий Java
Схема версионирования Java, Java 8 и старше
- Система версионирования Java долгое время была нетипичной по сравнению с большинством других языков и платформ.
- Раньше номера версий выглядели как "1.x", например:
- Официальная схема именования использовала формат "Java SE x.y", где
Примеры:
- Java SE 5.0 → Java 1.5
- Java SE 6.0 → Java 1.6
- Java SE 8.0 → Java 1.8
Эта схема создавала путаницу, потому что казалось, будто Java всё ещё находится на версии 1.x, хотя фактически язык уже прошёл через множество мажорных релизов.
Схема версионирования Java, начиная с Java 9
- Начиная с Java 9, префикс
- Теперь версии называются просто по мажорному номеру:
Java 9 — это просто
- Это изменение внесли, чтобы:
- устранить путаницу,
- привести систему к стандартной практике версионирования в индустрии.
- Кроме того, это отражает серьёзные архитектурные изменения, которые начались с Java 9 и продолжились в последующих версиях.
Эволюция версий Java:
👉 Java Portal
Java — JDK 25 выйдет уже в сентябре этого года
Схема версионирования Java, Java 8 и старше
- Система версионирования Java долгое время была нетипичной по сравнению с большинством других языков и платформ.
- Раньше номера версий выглядели как "1.x", например:
1.5
, 1.6
. Это отражало раннюю историю развития языка.- Официальная схема именования использовала формат "Java SE x.y", где
x
— мажорная версия, а y
— минорная.Примеры:
- Java SE 5.0 → Java 1.5
- Java SE 6.0 → Java 1.6
- Java SE 8.0 → Java 1.8
Эта схема создавала путаницу, потому что казалось, будто Java всё ещё находится на версии 1.x, хотя фактически язык уже прошёл через множество мажорных релизов.
Схема версионирования Java, начиная с Java 9
- Начиная с Java 9, префикс
1.
был официально отброшен.- Теперь версии называются просто по мажорному номеру:
Java 9 — это просто
9
, Java 10 — это 10
и т. д.- Это изменение внесли, чтобы:
- устранить путаницу,
- привести систему к стандартной практике версионирования в индустрии.
- Кроме того, это отражает серьёзные архитектурные изменения, которые начались с Java 9 и продолжились в последующих версиях.
Эволюция версий Java:
Java 1.0 — 23.01.1996🔸 Первый релиз: апплеты, базовые библиотеки, core API
Java 1.1 — 19.02.1997🔸 Внутренние классы, JDBC, AWT event-модель
Java 1.2 — 08.12.1998🔸 Swing GUI, коллекции, JIT-компилятор
Java 1.3 — 08.05.2000🔸 HotSpot JVM, RMI по IIOP (CORBA)
Java 1.4 — 06.02.2002🔸 Assertions, Logging API, регулярки, улучшенная модель памяти
Java 1.5 — 30.09.2004🔸 Дженерики, аннотации, enum, цикл for-each
Java 1.6 — 11.12.2006🔸 Scripting API, аннотации, улучшения JVM и рантайма
Java 1.7 — 28.07.2011🔸 Diamond-оператор, try-with-resources, строки в switch
Java 1.8 (LTS) — 18.03.2014🔸 Лямбды, Stream API, default-методы, новый Date/Time API
Java 9 — 21.09.2017🔸 Модульная система (Project Jigsaw), HTTP Client, JShell
Java 10 — 20.03.2018🔸 var, GC интерфейс, Class-Data Sharing
Java 11 (LTS) — 25.09.2018🔸 HTTP Client, dynamic class constants, Nest-Based Access Control
Java 12 — 19.03.2019🔸 switch (preview), Teeing Collectors, компактное форматирование чисел
Java 13 — 17.09.2019🔸 Text blocks, улучшения switch, ZGC
Java 14 — 17.03.2020🔸 Pattern matching (instanceof), Records (preview), JFR streaming
Java 15 — 15.09.2020🔸 Sealed-классы, скрытые классы, удалён Nashorn
Java 16 — 16.03.2021🔸 Records, Pattern Matching, Vector API, Foreign Memory API
Java 17 (LTS) — 14.09.2021🔸 Pattern Matching for switch, Sealed-классы, Foreign Function API
Java 18 — 22.03.2022🔸 UTF-8 по умолчанию, Web Server, Code snippets в API
Java 19 — 20.09.2022🔸 Record Patterns, Virtual Threads, Structured Concurrency
Java 20 — 21.03.2023🔸 Scoped Values, Virtual Threads (prod)
Java 21 (LTS) — 19.09.2023🔸 Sequenced Collections, Record Patterns, Virtual Threads, KEM API
Java 22 — 19.03.2024🔸 Region Pinning, Foreign Function API, Unnamed Variables & Patterns
Java 23 — 17.09.2024🔸 Pattern Matching, Scoped Values, Structured Concurrency
Java 24 — 18.03.2025🔸 Stream Gatherers, Compact Object Headers
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤5
Слабая связность — минимизация зависимостей между компонентами
Высокая связность — группировка функционально связанных элементов
Абстракция — скрытие деталей реализации
Единая ответственность — каждый компонент делает одну вещь хорошо
Разделение ответственности — разделение системы на отдельные модули
Бездействие (Statelessness) — по возможности избегать хранения сессий
Идемпотентность — операции можно безопасно повторять
Событийная согласованность — временное несоответствие для доступности и производительности
Быстрое обнаружение ошибок (Fail-Fast) — быстрое выявление и сообщение об ошибках
Circuit Breaker — изоляция сбойных компонентов
Механизмы повторных попыток — автоматический повтор неудачных операций
Асинхронность — дизайн для неблокирующей коммуникации
Таймауты/Дедлайны — установка лимитов для предотвращения бесконечных ожиданий
Распределённые базы данных
- NoSQL — MongoDB, Cassandra, DynamoDB (гибкая схема, масштабируемые)
- NewSQL — CockroachDB, YugabyteDB (масштабируемые с возможностями SQL)
Распределённые файловые системы
- HDFS — для больших данных (Hadoop)
- Ceph — унифицированная распределённая файловая система
Кеширование — Redis, Memcached (в памяти для скорости)
ACID — атомарность, согласованность, изоляция, долговечность (гарантии реляционных БД)
BASE — в основном доступная, с мягкой согласованностью (характеристики NoSQL)
Шардирование данных — распределение данных по нодам (шардинг, хеширование, диапазоны)
Стратегии репликации — копирование данных для отказоустойчивости
Сеть надёжна | Задержка равна нулю | Пропускная способность бесконечна | Сеть защищена | Топология не меняется | Есть один администратор | Стоимость передачи равна нулю | Сеть однородна
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3❤1
Шпаргалка по распределённым системам
🔸 Основные концепции
🔸 Архитектуры
🔸 Ключевые технологии
🔸 Коммуникация
🔸 Координация и консенсус
Распределённая система — набор взаимосвязанных компьютеров, которые общаются и координируются для достижения общей цели
Масштабируемость — обработка возросшей нагрузки
- Горизонтальная — добавление новых машин (нод)
- Вертикальная — апгрейд существующих машин (например, CPU, RAM)
Надёжность — корректная работа несмотря на сбои
Доступность — доля времени работы системы без простоев
Согласованность — согласие по значениям данных между всеми нодами в заданный момент
Устойчивость к разделению сети (Partition Tolerance) — работа при сетевых разрывах
Теорема CAP — из трёх свойств (Согласованность, Доступность, Устойчивость к разделениям) можно выбрать только два
Управление состоянием — хранение и синхронизация данных между нодами (без состояния/со состоянием)
Шардирование данных — разделение данных для масштабируемости (горизонтальное/вертикальное, по хешу/диапазону)
Стратегии репликации — копирование данных для отказоустойчивости (синхронная/асинхронная/на основе кворума)
Модели согласованности — компромиссы между согласованием данных и производительностью (строгая/событийная/каузальная)
Порядок и время — упорядочивание событий (метки Лэмпорта/векторные часы)
Отказоустойчивость — управление сбоями (фейловер/резервирование)
Управление конкурентным доступом — одновременный доступ к ресурсам (оптимистичный/пессимистичный контроль)
Клиент-сервер — клиенты запрашивают сервисы у серверов
P2P (одноранговая сеть) — ноды одновременно клиенты и серверы
Master-Slave — один мастер-узел координирует, множество слейвов выполняют задачи
Микросервисы — система разбита на мелкие независимые сервисы
Событийно-ориентированная архитектура — компоненты реагируют на события
SOA (сервис-ориентированная архитектура) — набор сервисов, общающихся между собой
Lambda-архитектура — гибридная архитектура для пакетной и потоковой обработки
Оркестрация контейнеров — Kubernetes, Docker Swarm
Сервис-дискавери — Consul, etcd
API-шлюзы — Kong, Tyk, Apigee, AWS API Gateway
Балансировщики нагрузки — HAProxy, NGINX, Traefik, Amazon ELB
Мониторинг и наблюдаемость — Prometheus, Grafana
Распределённый трейсинг — Zipkin, Jaeger
Сервисная сетка (Service Mesh) — Istio, Linkerd
Инфраструктура как код (IaC) — Terraform, CloudFormation
Управление конфигурациями — Ansible, Chef, Puppet
Распределённые кеши — Redis, Memcached
Обработка потоков — Apache Flink, Apache Spark Streaming
Оркестрация рабочих процессов — Apache Airflow, Argo Workflows
Планировщики заданий — Quartz, Apache Oozie, Kubernetes CronJobs
Облачные провайдеры — AWS, Azure, Google Cloud Platform
Безсерверные платформы — AWS Lambda, Azure Functions, Google Cloud Functions
Удалённый вызов процедур (RPC) — вызов функции на удалённой машине
Обмен сообщениями — асинхронное взаимодействие между нодами
- Очереди сообщений (Point-to-Point) — RabbitMQ, Amazon SQS
- Брокеры сообщений (Publish-Subscribe) — Kafka, Apache Pulsar
REST — язык запросов для API с точечным доступом к данным
GraphQL — TLS/SSL, HTTPS, SSH
gRPC — высокопроизводительный RPC с использованием Protocol Buffers
Webhooks — автоматические уведомления при определённых событиях
Алгоритмы консенсуса — Paxos, Raft
Распределённые блокировки — ZooKeeper, etcd
Распределённые транзакции — двухфазный коммит (2PC)
Выбор лидера — выбор координатора
Протокол госсипа — децентрализованное распространение информации
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤1
Динамические прокси для логирования в стиле AOP
Используй
Это позволяет эмулировать AOP без Spring — идеально подходит для обработки сквозной логики (cross-cutting concerns).
В этом примере мы логируем до и после вызова метода.
Такой подход даёт гибкий способ динамически абстрагировать поведение.
> Динамические прокси позволяют внедрять поведение — например, логирование, тайминг или проверку безопасности — без изменений исходного кода.
Этот паттерн активно используется во фреймворках вроде Spring и Hibernate.
👉 Java Portal
Используй
java.lang.reflect.Proxy
, чтобы перехватывать вызовы методов на этапе выполнения. Это позволяет эмулировать AOP без Spring — идеально подходит для обработки сквозной логики (cross-cutting concerns).
В этом примере мы логируем до и после вызова метода.
Такой подход даёт гибкий способ динамически абстрагировать поведение.
> Динамические прокси позволяют внедрять поведение — например, логирование, тайминг или проверку безопасности — без изменений исходного кода.
Этот паттерн активно используется во фреймворках вроде Spring и Hibernate.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👀2
This media is not supported in your browser
VIEW IN TELEGRAM
Конкурентность vs параллелизм - это НЕ одно и то же
Конкурентность:
Конкурентность означает, что приложение продвигается по нескольким задачам одновременно.
Хотя один CPU-ядро может обрабатывать только одну задачу за раз, оно достигает конкурентности, быстро переключаясь между задачами.
Пример: Слушание музыки во время написания кода. CPU быстро переключается между этими задачами так эффективно, что кажется, будто обе выполняются одновременно.
Основная цель конкурентности — максимизировать использование процессора, минимизируя время простоя.
Параллелизм:
Параллелизм означает выполнение нескольких задач одновременно.
Для достижения параллелизма задачи разбиваются на более мелкие независимые подзадачи и обрабатываются одновременно на нескольких процессорах, ядрах или GPU.
Пример: Обучение модели глубокого обучения, разделив датасет на батчи и обрабатывая каждый батч одновременно на нескольких GPU.
Цель параллелизма — ускорить обработку, выполняя несколько задач одновременно.
Они не являются взаимно исключающимися:
🔸 Можно иметь конкурентность без параллелизма.
🔸 Можно иметь параллелизм без конкурентности.
🔸 Или можно использовать и то, и другое для высокопроизводительных систем.
👉 Java Portal
Конкурентность:
Конкурентность означает, что приложение продвигается по нескольким задачам одновременно.
Хотя один CPU-ядро может обрабатывать только одну задачу за раз, оно достигает конкурентности, быстро переключаясь между задачами.
Пример: Слушание музыки во время написания кода. CPU быстро переключается между этими задачами так эффективно, что кажется, будто обе выполняются одновременно.
Основная цель конкурентности — максимизировать использование процессора, минимизируя время простоя.
Параллелизм:
Параллелизм означает выполнение нескольких задач одновременно.
Для достижения параллелизма задачи разбиваются на более мелкие независимые подзадачи и обрабатываются одновременно на нескольких процессорах, ядрах или GPU.
Пример: Обучение модели глубокого обучения, разделив датасет на батчи и обрабатывая каждый батч одновременно на нескольких GPU.
Цель параллелизма — ускорить обработку, выполняя несколько задач одновременно.
Они не являются взаимно исключающимися:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤1