Некоторые редкие, но ценные паттерны в Java
1. Null Object Pattern (Объект-Заглушка вместо null)
❯ Позволяет избежать проверок на null, возвращая объект с "пустым" поведением, реализующий ожидаемый интерфейс.
❯ Помогает держать код чистым, без множества
❯ Используй, когда возврат
2. Parameter Object Pattern (Объект параметров)
❯ Объединяет логически связанные параметры в один объект.
❯ Такой объект удобно прокидывать через разные уровни приложения, обеспечивая согласованность.
❯ Используй, когда у метода слишком много связанных аргументов.
3. Fluent Interface / Method Chaining (Флюент-интерфейс / Цепочка вызовов)
❯ Позволяет вызывать методы цепочкой, улучшая читаемость и выражая намерение кода (особенно в билдерах и конфигурациях).
❯ Используй в билдерах или для декларативной настройки.
4. Execute Around Method Pattern (Шаблон обёртки вокруг действия)
❯ Инкапсулирует логику подготовки и завершения вокруг основного действия.
❯ Гарантирует корректное освобождение ресурсов.
❯ Используй для управления ресурсами (файлы, БД и т.п.).
5. Initialization-on-Demand Holder (ленивый Singleton без
❯ Безопасный, потокобезопасный и производительный способ ленивой инициализации Singleton'а без явной синхронизации.
❯ Используй, если нужен быстрый и потокобезопасный синглтон.
👉 Java Portal
1. Null Object Pattern (Объект-Заглушка вместо null)
❯ Позволяет избежать проверок на null, возвращая объект с "пустым" поведением, реализующий ожидаемый интерфейс.
❯ Помогает держать код чистым, без множества
if (obj != null)
перед каждым вызовом метода.❯ Используй, когда возврат
null
приводит к захламлению условными конструкциями.2. Parameter Object Pattern (Объект параметров)
❯ Объединяет логически связанные параметры в один объект.
❯ Такой объект удобно прокидывать через разные уровни приложения, обеспечивая согласованность.
❯ Используй, когда у метода слишком много связанных аргументов.
3. Fluent Interface / Method Chaining (Флюент-интерфейс / Цепочка вызовов)
❯ Позволяет вызывать методы цепочкой, улучшая читаемость и выражая намерение кода (особенно в билдерах и конфигурациях).
❯ Используй в билдерах или для декларативной настройки.
4. Execute Around Method Pattern (Шаблон обёртки вокруг действия)
❯ Инкапсулирует логику подготовки и завершения вокруг основного действия.
❯ Гарантирует корректное освобождение ресурсов.
❯ Используй для управления ресурсами (файлы, БД и т.п.).
5. Initialization-on-Demand Holder (ленивый Singleton без
synchronized
)❯ Безопасный, потокобезопасный и производительный способ ленивой инициализации Singleton'а без явной синхронизации.
❯ Используй, если нужен быстрый и потокобезопасный синглтон.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10👍4🔥1
Разные подходы к структуре REST API:
1) Чистый CRUD-стиль
👍 Просто и предсказуемо
👎 Начинает хромать при действиях вне CRUD
2) Эндпоинты-действия
👍 Ясное указание на сайд-эффекты
👎 Нарушает REST-идеи (глаголы в URL)
3) Вложенные ресурсы
👍 Удобно моделирует связи между сущностями
👎 Может вырасти в избыточную иерархию, тяжело поддерживать
4) Плоская структура + фильтры
👍 Гибкие запросы
👎 Требует строгой валидации query-параметров
5) Версионирование API
👍 Безопасное развитие API
👎 Увеличивает накладные расходы на поддержку
👉 Java Portal
1) Чистый CRUD-стиль
GET /users
POST /users
PUT /users/{id}
DELETE /users/{id}
2) Эндпоинты-действия
POST /users/{id}/deactivate
POST /orders/{id}/cancel
3) Вложенные ресурсы
GET /users/{id}/orders
POST /users/{id}/addresses
4) Плоская структура + фильтры
GET /orders?userId=123
GET /products?category=books&page=2
5) Версионирование API
GET /v1/users
Accept: application/vnd.myapp.v2+json
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍3🔥1
Плохие практики в коде, которые кажутся безобидными (но это не так)
1) Чрезмерное использование private-методов, скрывающее сложность
Когда private-методов слишком много, это ломает читаемость и разносит логику по коду. Визуально всё выглядит «чисто», но важные логические шаги оказываются скрытыми.
Когда это плохо:
Вы выносите код в private-методы просто ради самого факта выноса, а не потому что они переиспользуемы или несут отдельный смысл.
Как лучше:
Выделяйте разные зоны ответственности в отдельные классы или сервисы, которые сотрудничают между собой.
2) Автоматическое добавление private + геттеров/сеттеров по умолчанию
Бездумное добавление геттеров и сеттеров превращает ООП в просто «структуры с методами». Это нарушает инкапсуляцию, а не сохраняет её.
Вместо этого:
● Открывайте только те геттеры/сеттеры, которые реально нужны для бизнес-логики.
● Вместо сеттеров лучше использовать методы, которые выполняют осмысленные действия с валидацией.
3) Чрезмерное использование static-методов и переменных
static-методы кажутся удобными, но убивают тестируемость и гибкость. Они привязывают код к жёсткому глобальному состоянию.
Как лучше:
Используйте внедрение зависимостей или передавайте нужную конфигурацию явно туда, где она требуется.
4) Слишком большой класс (“God Object”)
Огромный класс, который делает всё подряд, превращается в чёрный ящик — его сложно тестировать, менять и понимать.
Как лучше:
● Применяйте принцип единственной ответственности (Single Responsibility Principle): у класса должна быть только одна причина для изменения.
● Разделяйте обязанности между меньшими по размеру классами или модулями.
5) Скрытие семантики null / Optional
Возврат null или скрытое использование Optional приводит к неожиданным ошибкам во время выполнения. Отсутствие или наличие значения должно быть выражено явно.
Как лучше:
● Используйте
● Если это действительно ошибка — выбрасывайте чётко определённое исключение.
👉 Java Portal
1) Чрезмерное использование private-методов, скрывающее сложность
Когда private-методов слишком много, это ломает читаемость и разносит логику по коду. Визуально всё выглядит «чисто», но важные логические шаги оказываются скрытыми.
Когда это плохо:
Вы выносите код в private-методы просто ради самого факта выноса, а не потому что они переиспользуемы или несут отдельный смысл.
Как лучше:
Выделяйте разные зоны ответственности в отдельные классы или сервисы, которые сотрудничают между собой.
2) Автоматическое добавление private + геттеров/сеттеров по умолчанию
Бездумное добавление геттеров и сеттеров превращает ООП в просто «структуры с методами». Это нарушает инкапсуляцию, а не сохраняет её.
Вместо этого:
● Открывайте только те геттеры/сеттеры, которые реально нужны для бизнес-логики.
● Вместо сеттеров лучше использовать методы, которые выполняют осмысленные действия с валидацией.
3) Чрезмерное использование static-методов и переменных
static-методы кажутся удобными, но убивают тестируемость и гибкость. Они привязывают код к жёсткому глобальному состоянию.
Как лучше:
Используйте внедрение зависимостей или передавайте нужную конфигурацию явно туда, где она требуется.
4) Слишком большой класс (“God Object”)
Огромный класс, который делает всё подряд, превращается в чёрный ящик — его сложно тестировать, менять и понимать.
Как лучше:
● Применяйте принцип единственной ответственности (Single Responsibility Principle): у класса должна быть только одна причина для изменения.
● Разделяйте обязанности между меньшими по размеру классами или модулями.
5) Скрытие семантики null / Optional
Возврат null или скрытое использование Optional приводит к неожиданным ошибкам во время выполнения. Отсутствие или наличие значения должно быть выражено явно.
Как лучше:
● Используйте
Optional<T>
или другой задокументированный способ, чтобы показать, что результат может отсутствовать.● Если это действительно ошибка — выбрасывайте чётко определённое исключение.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤2🔥1
Пакетная обработка JDBC через StatelessSession в Hibernate
Статья объясняет, как использовать StatelessSession в Hibernate 6 для быстрой пакетной вставки, обновления и удаления данных с помощью JDBC Batching — без лишнего кеша и с высокой производительностью.
⏩ Читать подробнее
👉 Java Portal | #cтатья
Статья объясняет, как использовать StatelessSession в Hibernate 6 для быстрой пакетной вставки, обновления и удаления данных с помощью JDBC Batching — без лишнего кеша и с высокой производительностью.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5🔥1
Советы по Java Stream API: Ленивое вычисление с использованием
Когда возникает необходимость повторно использовать потоковую обработку, можно воспользоваться
👉 Java Portal
Supplier<Stream<T>>
Когда возникает необходимость повторно использовать потоковую обработку, можно воспользоваться
Supplier
. В обычных случаях поток (Stream) нельзя использовать повторно после его обработки.Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥5
14 советов для высокопроизводительной персистентности в Java
⏩ Читать подробнее
👉 Java Portal | #cтатья
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2😁1
Креативные (нетрадиционные) способы использования интерфейсов в Java
1) Конфигурация на основе интерфейсов (расширение паттерна Strategy)
Вместо использования конфигурационных файлов или
🔸 Инкапсулируется поведение, а не просто значения.
🔸 Позволяет менять поведение динамически в рантайме, подставляя разные реализации.
2) Интерфейсы для method chaining с условным выполнением
Интерфейсы могут быть использованы для построения цепочек вызовов методов с возможностью условного выполнения. Это позволяет динамически пропускать определённые вызовы.
Используется при создании fluent API, где некоторые методы должны выполняться только при выполнении условий.
Это:
🔸 Делает код более читаемым и выразительным.
🔸 Избегает ненужных вызовов, если условие не выполнено.
Традиционный аналог:
3) Маркировочные (tagging/marker) интерфейсы с проверкой по типу
Пустые интерфейсы можно использовать для "тегирования" классов и принятия решений во время выполнения или компиляции.
Это позволяет выполнять определённые действия, если класс реализует конкретный marker-интерфейс.
🔸 Чистое разделение ролей без добавления логики
🔸 Хорошо сочетается с
4) Наследование интерфейсов для реализации поведения по умолчанию
Интерфейсы с default-методами можно использовать для композиции переиспользуемой логики.
Применяется, когда нужно разделить общее поведение между разными классами, не прибегая к наследованию от общего базового класса.
👉 Java Portal
1) Конфигурация на основе интерфейсов (расширение паттерна Strategy)
Вместо использования конфигурационных файлов или
enum
для выбора поведения на лету (что считается классическим подходом), можно использовать интерфейсы для инкапсуляции различных конфигураций.2) Интерфейсы для method chaining с условным выполнением
Интерфейсы могут быть использованы для построения цепочек вызовов методов с возможностью условного выполнения. Это позволяет динамически пропускать определённые вызовы.
Используется при создании fluent API, где некоторые методы должны выполняться только при выполнении условий.
Это:
Традиционный аналог:
if (conditionMet) {
obj.doSomething();
obj.doAnotherThing();
}
3) Маркировочные (tagging/marker) интерфейсы с проверкой по типу
Пустые интерфейсы можно использовать для "тегирования" классов и принятия решений во время выполнения или компиляции.
Это позволяет выполнять определённые действия, если класс реализует конкретный marker-интерфейс.
reflection
и generics
4) Наследование интерфейсов для реализации поведения по умолчанию
Интерфейсы с default-методами можно использовать для композиции переиспользуемой логики.
Применяется, когда нужно разделить общее поведение между разными классами, не прибегая к наследованию от общего базового класса.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Сборка мусора в JVM — всё, что нужно знать
1. Сборка мусора (GC) → Автоматическая очистка памяти
🔸 JVM автоматически освобождает память от недостижимых объектов.
🔸 Используется для избегания ручного управления памятью (например, неиспользуемые объекты List очищаются автоматически).
2. Heap → Основная область памяти для объектов
🔸 Здесь хранятся все объекты Java.
🔸 Делится на области: Young, Old и иногда Metaspace.
3. Молодое поколение (Young Generation) → Новые объекты (краткоживущие)
🔸 Большинство новых объектов создаются здесь.
🔸 Пример использования: String s = "abc" сначала попадает в эту область.
4. Старое поколение (Old Generation / Tenured) → Долгоживущие объекты
🔸 Объекты, пережившие несколько сборок мусора, перемещаются сюда.
🔸 Пример использования: кэшированные конфигурации, бины, живущие на протяжении всей жизни приложения.
5. Metaspace → Хранение метаданных классов (начиная с Java 8+)
🔸 Заменяет PermGen.
🔸 Хранит структуру классов, информацию о методах (например, User.class, List.class).
6. Minor GC → Очистка молодого поколения
🔸 Быстрая и частая.
🔸 Срабатывает, когда заполняется пространство Eden (например, при множестве краткоживущих запросов).
7. Major (Full) GC → Очистка старого поколения и Metaspace
🔸 Медленнее и реже.
🔸 Срабатывает, когда почти заполнено старое поколение (например, при больших графах объектов или утечках памяти).
8. Stop-the-World (STW) → Приостановка приложения во время GC
🔸 JVM замораживает все потоки на время GC.
🔸 Может вызывать задержки (например, при большой полной сборке мусора).
9. GC Roots → Точки отсчета для достижимости объектов
🔸 Включает ссылки из регистров, стэков потоков, загрузчиков классов.
🔸 GC отслеживает от них «живые» объекты (например, локальные переменные в методе main()).
Основные типы сборщиков мусора
10. Serial GC → Однопоточный сборщик
🔸 Простой, но останавливает всё приложение.
🔸 Используется для малых heaps (например, CLI-инструменты или тестовые приложения).
11. Parallel GC → Многопоточный сборщик
🔸 Ускоряет GC за счёт многопоточности.
🔸 Используется в приложениях с приоритетом на производительность (например, batch-задачи, нагруженные серверы).
12. CMS (Concurrent Mark Sweep) → Сборщик с низкими паузами (УСТАРЕЛ)
🔸 Работает в фоновом режиме с короткими паузами.
🔸 Использовался в приложениях, чувствительных к задержкам (например, веб-серверы).
13. G1 GC → Сбалансированный сборщик с низкими паузами (по умолчанию с Java 9+)
🔸 Делит heap на регионы; работает параллельно и конкурентно.
🔸 Отличный универсальный сборщик (например, для микросервисов, real-time API).
14. ZGC → Сборщик с ультранизкими паузами
🔸 Разработан для пауз в пределах миллисекунды.
🔸 Используется в системах реального времени с большим heap (например, финтех, игры).
15. Shenandoah → Сборщик с низкими паузами (RedHat/OpenJDK)
🔸 Конкурирует с ZGC.
🔸 Применяется в больших heaps с постоянными требованиями к задержкам.
👉 Java Portal
1. Сборка мусора (GC) → Автоматическая очистка памяти
2. Heap → Основная область памяти для объектов
3. Молодое поколение (Young Generation) → Новые объекты (краткоживущие)
4. Старое поколение (Old Generation / Tenured) → Долгоживущие объекты
5. Metaspace → Хранение метаданных классов (начиная с Java 8+)
6. Minor GC → Очистка молодого поколения
7. Major (Full) GC → Очистка старого поколения и Metaspace
8. Stop-the-World (STW) → Приостановка приложения во время GC
9. GC Roots → Точки отсчета для достижимости объектов
Основные типы сборщиков мусора
10. Serial GC → Однопоточный сборщик
11. Parallel GC → Многопоточный сборщик
12. CMS (Concurrent Mark Sweep) → Сборщик с низкими паузами (УСТАРЕЛ)
13. G1 GC → Сбалансированный сборщик с низкими паузами (по умолчанию с Java 9+)
14. ZGC → Сборщик с ультранизкими паузами
15. Shenandoah → Сборщик с низкими паузами (RedHat/OpenJDK)
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤5
В чем разница между SLEEP и WAIT в java?
Принадлежность
🔸
🔸
Назначение
🔸
🔸
Блокировка
🔸
🔸
Когда использовать
🔸
🔸
Нужен ли synchronized-блок?
🔸
🔸
Может быть прерван?
🔸
🔸
Когда возобновляется
🔸
🔸
Статический или экземплярный метод?
🔸
🔸
👉 Java Portal
Принадлежность
sleep()
— относится к классу Threadwait()
— относится к классу ObjectНазначение
sleep()
используется для приостановки потока на фиксированное времяwait()
используется для взаимодействия между потоками (межпоточная сигнализация)Блокировка
sleep()
не освобождает монитор (lock остаётся удержанным)wait()
освобождает монитор (lock)Когда использовать
sleep()
— когда нужно просто отложить выполнение потокаwait()
— когда один поток должен ожидать сигнал от другого потокаНужен ли synchronized-блок?
sleep()
— нетwait()
— да, должен вызываться внутри synchronized-блока или методаМожет быть прерван?
sleep()
— да, выбрасывает InterruptedException
wait()
— да, выбрасывает InterruptedException
Когда возобновляется
sleep()
— после указанного времениwait()
— после вызова notify()
/notifyAll()
или при прерыванииСтатический или экземплярный метод?
sleep()
— статический метод, вызывается как Thread.sleep()
wait()
— метод экземпляра, вызывается на объекте: obj.wait()
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤3🔥3
HashSet в Java
HashSet — это коллекция для хранения уникальных элементов без гарантии порядка. Относится к пакету java.util и реализует интерфейс Set, внутренне опираясь на HashMap.
Основные особенности Java HashSet:
🔹 Дубликаты игнорируются. Если добавить элемент, который уже есть в множестве — ничего не произойдёт.
🔹 Элементы не упорядочены ни по добавлению, ни по значению.
🔹 Допускается один null-элемент.
Производительность: Базовые операции
Часто используемые операции:
—
—
—
—
—
Как работает внутри
При выводе содержимого
👉 Java Portal
HashSet — это коллекция для хранения уникальных элементов без гарантии порядка. Относится к пакету java.util и реализует интерфейс Set, внутренне опираясь на HashMap.
Основные особенности Java HashSet:
Производительность: Базовые операции
add, remove, contains
выполняются за константное время O(1), при условии качественной хеш-функции.Даже если дважды добавить строку "BMW" — в сете она появится только один раз.
Часто используемые операции:
—
add(E e)
— добавляет элемент, если его ещё нет—
remove(Object o)
— удаляет элемент, если он есть—
contains(Object o)
— проверяет наличие элемента—
size()
— возвращает количество элементов—
clear()
— очищает сетКак работает внутри
HashSet
использует внутренний HashMap
, где элементы сета хранятся как ключи, а значением выступает фиктивный объект. Это позволяет обеспечить уникальность и быстрый доступ.При выводе содержимого
HashSet
— элементы отображаются в произвольном порядке.Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍4