Java: используй
1. Read lock (лок на чтение): позволяет нескольким потокам читать одновременно, пока ни один поток не пишет.
2. Write lock (лок на запись): позволяет писать только одному потоку и блокирует всех остальных читателей и писателей, пока лок не будет освобожден.
Используй
1. Твой код часто читает разделяемые данные.
2. Записи происходят редко.
3. Ты хочешь выжать максимум параллелизма: разрешить нескольким читателям работать одновременно, но гарантировать, что запись идет строго эксклюзивно.
Пример:
👉 Java Portal
ReentrantReadWriteLock, если у тебя частые чтения и мало записей.ReentrantReadWriteLock это утилита конкурентности в Java, которая дает два типа локов:1. Read lock (лок на чтение): позволяет нескольким потокам читать одновременно, пока ни один поток не пишет.
2. Write lock (лок на запись): позволяет писать только одному потоку и блокирует всех остальных читателей и писателей, пока лок не будет освобожден.
Используй
ReentrantReadWriteLock, когда:1. Твой код часто читает разделяемые данные.
2. Записи происходят редко.
3. Ты хочешь выжать максимум параллелизма: разрешить нескольким читателям работать одновременно, но гарантировать, что запись идет строго эксклюзивно.
Пример:
public class SharedValue {
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private int value = 0;
public int readValue() {
lock.readLock().lock();
try {
return value;
} finally {
lock.readLock().unlock();
}
}
public void writeValue(int newValue) {
lock.writeLock().lock();
try {
value = newValue;
} finally {
lock.writeLock().unlock();
}
}
}Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3
Что такое BeanPostProcessor в Java Spring Boot?
Это интерфейс, который позволяет вмешиваться в процесс создания и инициализации бинов в Spring-контейнере.
Он предоставляет два основных метода, которые вызываются на разных этапах жизненного цикла бина:
1.
Вызывается до инициализации бина (до вызова метода с
2.
Вызывается после инициализации бина (после того, как все методы инициализации завершились).
Зачем нужен BeanPostProcessor?
Он используется для дополнительной обработки и кастомизации бинов после их создания, но до того, как они будут переданы клиентскому коду.
Примеры:
- Добавление проксирования бинов (например, для AOP или транзакций)
- Валидация или изменение свойств бина
- Логирование жизненного цикла
- Добавление кастомных аннотаций
- Обработка marker-интерфейсов
Как это работает?
1. Spring сканирует контекст на наличие бинов, которые реализуют интерфейс
2. Если такие бины найдены, они применяются ко всем бинам в приложении.
3. Методы
👉 Java Portal
Это интерфейс, который позволяет вмешиваться в процесс создания и инициализации бинов в Spring-контейнере.
Он предоставляет два основных метода, которые вызываются на разных этапах жизненного цикла бина:
1.
postProcessBeforeInitialization(Object bean, String beanName)Вызывается до инициализации бина (до вызова метода с
@PostConstruct или InitializingBean#afterPropertiesSet).2.
postProcessAfterInitialization(Object bean, String beanName)Вызывается после инициализации бина (после того, как все методы инициализации завершились).
Зачем нужен BeanPostProcessor?
Он используется для дополнительной обработки и кастомизации бинов после их создания, но до того, как они будут переданы клиентскому коду.
Примеры:
- Добавление проксирования бинов (например, для AOP или транзакций)
- Валидация или изменение свойств бина
- Логирование жизненного цикла
- Добавление кастомных аннотаций
- Обработка marker-интерфейсов
Как это работает?
1. Spring сканирует контекст на наличие бинов, которые реализуют интерфейс
BeanPostProcessor.2. Если такие бины найдены, они применяются ко всем бинам в приложении.
3. Методы
postProcessBeforeInitialization и postProcessAfterInitialization вызываются для каждого бина, который создаёт Spring.Please open Telegram to view this post
VIEW IN TELEGRAM
❤8
Java-совет: начиная с Java 9 можно использовать
👉 Java Portal
Stream.takeWhile() для удобной "нарезки" списков через стримы.List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
✗ Вместо:
List<Integer> result = new ArrayList<>();
for (Integer n : numbers) {
if (n < 5) {
result.add(n);
} else {
break;
}
}
System.out.println(result); // [1, 2, 3, 4]
✓ Можно так:
result = numbers.stream().takeWhile(n -> n < 5).toList();
System.out.println(result); // [1, 2, 3, 4]
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥3
Я побывал по обе стороны собеседований по system design.
Ниже темы, которые нужно изучить, чтобы действительно хорошо в этом разбираться:
1. [Сервер]
2. [Задержка и пропускная способность]
3. [Масштабирование и его виды]
– Вертикальное и горизонтальное масштабирование
4. [Автомасштабирование]
5. [Прикидочные расчеты]
6. [Теорема CAP]
7. [Масштабирование базы данных]
– Индексы
– Партиционирование
– Архитектура master-slave
– Multi-master
– Шардирование базы данных
– Недостатки шардирования
8. [SQL и NoSQL базы данных и когда что использовать]
9. [База данных]
– SQL-база данных
– NoSQL-база данных
– Масштабирование в NoSQL и SQL
– Когда какую базу использовать?
10. [Микросервисы]
– Монолит vs микросервисы
– Зачем вообще разбивать приложение на микросервисы?
– Когда использовать микросервисы?
– Как клиенты делают запросы в микросервисной архитектуре?
11. [Глубокое погружение в load balancer]
– Зачем нужен load balancer?
– Алгоритмы load balancing
12. [Кеширование]
– Плюсы кеширования
– Типы кешей
– Redis
13. [Blob Storage]
– Что такое blob и зачем нужно blob storage?
– AWS S3
14. [CDN, Content Delivery Network]
– Как работает CDN?
15. [Message Broker]
– Асинхронное программирование
– Зачем ставить message broker между сервисами?
– Очередь сообщений
– Поток сообщений
– Когда использовать message broker
16. [Глубокое погружение в Apache Kafka]
– Когда использовать Kafka
– Внутреннее устройство Kafka
17. [Pub/sub в реальном времени]
18. [Event-Driven Architecture]
– Зачем использовать EDA?
– Простое уведомление о событии
– Передача состояния через событие
19. [Распределенные системы]
20. [Самовосстанавливающаяся система с election лидера]
21. [Глубокое погружение в consistency]
– Строгая согласованность
– Когда выбирать strong consistency
– Eventual consistency
– Когда выбирать eventual consistency
– Способы добиться strong consistency
– Способы добиться eventual consistency
22. [Consistent hashing]
23. [Избыточность данных и восстановление данных]
– Зачем делать базы данных избыточными?
– Разные способы резервного копирования
– Непрерывная избыточность
24. [Прокси]
– Forward proxy vs reverse proxy
👉 Java Portal
Ниже темы, которые нужно изучить, чтобы действительно хорошо в этом разбираться:
1. [Сервер]
2. [Задержка и пропускная способность]
3. [Масштабирование и его виды]
– Вертикальное и горизонтальное масштабирование
4. [Автомасштабирование]
5. [Прикидочные расчеты]
6. [Теорема CAP]
7. [Масштабирование базы данных]
– Индексы
– Партиционирование
– Архитектура master-slave
– Multi-master
– Шардирование базы данных
– Недостатки шардирования
8. [SQL и NoSQL базы данных и когда что использовать]
9. [База данных]
– SQL-база данных
– NoSQL-база данных
– Масштабирование в NoSQL и SQL
– Когда какую базу использовать?
10. [Микросервисы]
– Монолит vs микросервисы
– Зачем вообще разбивать приложение на микросервисы?
– Когда использовать микросервисы?
– Как клиенты делают запросы в микросервисной архитектуре?
11. [Глубокое погружение в load balancer]
– Зачем нужен load balancer?
– Алгоритмы load balancing
12. [Кеширование]
– Плюсы кеширования
– Типы кешей
– Redis
13. [Blob Storage]
– Что такое blob и зачем нужно blob storage?
– AWS S3
14. [CDN, Content Delivery Network]
– Как работает CDN?
15. [Message Broker]
– Асинхронное программирование
– Зачем ставить message broker между сервисами?
– Очередь сообщений
– Поток сообщений
– Когда использовать message broker
16. [Глубокое погружение в Apache Kafka]
– Когда использовать Kafka
– Внутреннее устройство Kafka
17. [Pub/sub в реальном времени]
18. [Event-Driven Architecture]
– Зачем использовать EDA?
– Простое уведомление о событии
– Передача состояния через событие
19. [Распределенные системы]
20. [Самовосстанавливающаяся система с election лидера]
21. [Глубокое погружение в consistency]
– Строгая согласованность
– Когда выбирать strong consistency
– Eventual consistency
– Когда выбирать eventual consistency
– Способы добиться strong consistency
– Способы добиться eventual consistency
22. [Consistent hashing]
23. [Избыточность данных и восстановление данных]
– Зачем делать базы данных избыточными?
– Разные способы резервного копирования
– Непрерывная избыточность
24. [Прокси]
– Forward proxy vs reverse proxy
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥1
Совет по Spring Boot: ускорить приложение можно с помощью
🟢 Позволяет избежать повторных вызовов к БД и API
🟢 Снижает задержки
🟢 По умолчанию Spring использует in-memory map, но в проде можно подключить внешний провайдер кеша
👉 Java Portal
@EnableCaching и @Cacheable.Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
API Gateway, если по-человечески:
Клиент не должен ходить в 6 разных сервисов.
Он должен ходить в одну точку.
Gateway стоит перед всей системой и берёт на себя:
- маршрутизацию входящих запросов в нужный сервис
- валидацию токенов, например JWT и OAuth, ещё до того, как запрос вообще дойдёт до сервисов
- rate limiting, чтобы API не абьюзили
- логирование, чтобы наблюдаемость была в одном месте
- балансировку нагрузки между инстансами сервисов
Без gateway каждый сервис заново городит у себя аутентификацию, логирование и rate limiting.
С gateway всё это решается один раз, централизованно.
Вот и вся суть: одна точка входа и единый слой контроля.
👉 Java Portal
Клиент не должен ходить в 6 разных сервисов.
Он должен ходить в одну точку.
Gateway стоит перед всей системой и берёт на себя:
- маршрутизацию входящих запросов в нужный сервис
- валидацию токенов, например JWT и OAuth, ещё до того, как запрос вообще дойдёт до сервисов
- rate limiting, чтобы API не абьюзили
- логирование, чтобы наблюдаемость была в одном месте
- балансировку нагрузки между инстансами сервисов
Без gateway каждый сервис заново городит у себя аутентификацию, логирование и rate limiting.
С gateway всё это решается один раз, централизованно.
Вот и вся суть: одна точка входа и единый слой контроля.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤3
Не используйте
Использование
Когда используется
Вот наивный пример:
В этом запросе каждая строка, которая не удовлетворяет условию, превращается в
Лучше всего вообще убрать
В этой версии строки, не подходящие под условие, возвращают
👉 Java Portal
ELSE 0 вместе с COUNT и CASEИспользование
ELSE 0 - очень частая ошибка у новичков, когда они комбинируют функцию COUNT с выражением CASE. Обычно это происходит из-за непонимания того, как именно COUNT работает при применении к столбцу.Когда используется
COUNT(column), функция считает все значения, которые не равны NULL, включая нули. Это значит, что если в выражении CASE указан ELSE 0, каждая строка, не попавшая под условие, превращается в значение 0. В результате такие строки тоже попадают в подсчёт.Вот наивный пример:
sql id="g4suvd"
SELECT
Department,
COUNT(CASE
WHEN Status = 'Active' THEN EmployeeID
ELSE 0
END) AS ActiveEmployees
FROM Employees
GROUP BY Department;
В этом запросе каждая строка, которая не удовлетворяет условию, превращается в
0, а это валидное значение, поэтому оно тоже учитывается в COUNT. Из-за этого результат может получиться вводящим в заблуждение.Лучше всего вообще убрать
ELSE. Когда ветка ELSE опущена, выражение CASE возвращает NULL для строк, которые не соответствуют условию. А так как COUNT() игнорирует NULL, будут посчитаны только строки, которые действительно удовлетворяют условию. Вот правильный вариант:sql id="vxa5np"
SELECT
Department,
COUNT(CASE
WHEN Status = 'Active' THEN EmployeeID
END) AS ActiveEmployees
FROM Employees
GROUP BY Department;
В этой версии строки, не подходящие под условие, возвращают
NULL, и COUNT() естественным образом исключает их из подсчёта. В итоге запрос получается чище, а подсчёт корректно отражает только те значения, которые реально соответствуют условию.Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍3
Java tip: используйте
Значение создается лениво
👉 Java Portal
ThreadLocal.withInitial(...), чтобы у каждого потока было свое безопасное значение по умолчанию.Значение создается лениво
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍4
Вопрос на Java-собеседовании:
Что такое Spring Bean Scope?
Основные типы:
- singleton (по умолчанию) — один экземпляр на весь контейнер.
- prototype — новый экземпляр для каждого запроса.
- request — бин живет в рамках одного HTTP-запроса.
- session — бин живет в рамках одной HTTP-сессии.
- application — бин живет в рамках всего веб-приложения.
- websocket — бин живет на протяжении сессии WebSocket.
👉 Java Portal
Что такое Spring Bean Scope?
Spring Bean Scope определяет жизненный цикл и область видимости бина в контейнере.Основные типы:
- singleton (по умолчанию) — один экземпляр на весь контейнер.
- prototype — новый экземпляр для каждого запроса.
- request — бин живет в рамках одного HTTP-запроса.
- session — бин живет в рамках одной HTTP-сессии.
- application — бин живет в рамках всего веб-приложения.
- websocket — бин живет на протяжении сессии WebSocket.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍4
Гайд для новичков по созданию HTTP-сервера с нуля.
Хочешь своими руками написать HTTP-сервер и потом отправлять на него запросы и получать ответы?
Если да, вот как раз гайд, по которому можно пройтись.
Что нужно знать заранее
Нужно знать Java.
Если не знаешь, не страшно: шаги из гайда можно перенести почти на любой язык, с которым тебе удобно работать, просто используя семантически эквивалентные конструкции в коде.
Базовое понимание программирования и OOP.
Текстовый редактор и, возможно, много кофе. Как пойдет.🤭
👉 Java Portal
Хочешь своими руками написать HTTP-сервер и потом отправлять на него запросы и получать ответы?
Если да, вот как раз гайд, по которому можно пройтись.
Что нужно знать заранее
Нужно знать Java.
Если не знаешь, не страшно: шаги из гайда можно перенести почти на любой язык, с которым тебе удобно работать, просто используя семантически эквивалентные конструкции в коде.
Примечание: JS/TS для этого гайда я бы не рекомендовал.
Базовое понимание программирования и OOP.
Текстовый редактор и, возможно, много кофе. Как пойдет.
Please open Telegram to view this post
VIEW IN TELEGRAM
Совет по Java:
👉 Java Portal
List.reversed() возвращает неизменяемое (unmodifiable) представление исходного списка в обратном порядке.Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
Совет по Java : не полагайся полностью на сборщик мусора — утечки памяти всё ещё возможны.
👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3🔥2
Типы классов в Java:
1. Concrete Class (конкретный класс) — обычный класс с полной реализацией методов.
2. Abstract Class (абстрактный класс) — не может быть создан через
3. Final Class (финальный класс) — не может быть унаследован.
4. Static Class (вложенный статический класс) — статический внутренний класс внутри другого класса.
5. Inner Class (внутренний класс) — нестатический класс, объявленный внутри другого класса.
6. Local Class (локальный класс) — класс, определённый внутри метода.
7. Anonymous Class (анонимный класс) — класс без имени, обычно используется для кратковременных реализаций.
8. Singleton Class (синглтон-класс) — гарантирует существование только одного экземпляра класса.
9. POJO (Plain Old Java Object) — простой Java-класс без специальных ограничений или требований.
10. Record Class (Java 14+) — компактный класс для представления неизменяемых данных.
11. Enum Class (класс-перечисление) — определяет фиксированный набор констант.
👉 Java Portal
1. Concrete Class (конкретный класс) — обычный класс с полной реализацией методов.
2. Abstract Class (абстрактный класс) — не может быть создан через
new; может содержать абстрактные методы.3. Final Class (финальный класс) — не может быть унаследован.
4. Static Class (вложенный статический класс) — статический внутренний класс внутри другого класса.
5. Inner Class (внутренний класс) — нестатический класс, объявленный внутри другого класса.
6. Local Class (локальный класс) — класс, определённый внутри метода.
7. Anonymous Class (анонимный класс) — класс без имени, обычно используется для кратковременных реализаций.
8. Singleton Class (синглтон-класс) — гарантирует существование только одного экземпляра класса.
9. POJO (Plain Old Java Object) — простой Java-класс без специальных ограничений или требований.
10. Record Class (Java 14+) — компактный класс для представления неизменяемых данных.
11. Enum Class (класс-перечисление) — определяет фиксированный набор констант.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2🤔1
// Old way:
String season;
switch (month) {
case 12:
case 1:
case 2:
season = "Winter";
break;
case 3:
case 4:
case 5:
season = "Spring";
break;
default:
season = "Invalid";
}
// New switch expression:
String season = switch (month) {
case 12, 1, 2 -> "Winter";
case 3, 4, 5 -> "Spring";
default -> "Invalid";
};
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤5👍3👀1
Совет по Spring AI
Запускаете локальные AI-модели через LM Studio и сталкиваетесь с зависанием соединения, когда ваше приложение Spring AI вызывает API, совместимый с OpenAI?
LM Studio не поддерживает HTTP/2, из-за чего запрос может зависать.
Решение: отключить HTTP/2 для`RestClient`.
👉 Java Portal
Запускаете локальные AI-модели через LM Studio и сталкиваетесь с зависанием соединения, когда ваше приложение Spring AI вызывает API, совместимый с OpenAI?
LM Studio не поддерживает HTTP/2, из-за чего запрос может зависать.
Решение: отключить HTTP/2 для`RestClient`.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Spring Boot: Используйте
В production логирование деталей запроса может привести к раскрытию чувствительной информации.
Когда вы настраиваете свойства Spring-приложения в dev со следующими параметрами:
и конфигурацию фильтра примерно такую:
вы включаете логирование:
1. заголовков запроса (Request headers)
2. query-параметров (Query parameters)
3. данных формы (Form data)
Без этого Spring маскирует или опускает многие из этих деталей, чтобы избежать утечки информации.
Не используйте это в production, иначе вы раскроете чувствительную информацию, например пароли:
👉 Java Portal
spring.mvc.publish-request-params=true только в dev-среде. Это опасно в production.В production логирование деталей запроса может привести к раскрытию чувствительной информации.
Когда вы настраиваете свойства Spring-приложения в dev со следующими параметрами:
# Включить публикацию параметров
spring.mvc.publish-request-params=true
# Установить уровни логирования, чтобы видеть вывод
logging.level.org.springframework.web=DEBUG
logging.level.org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor=DEBUG
и конфигурацию фильтра примерно такую:
@Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true); // 2) Query-параметры
filter.setIncludeHeaders(true); // 1) Заголовки запроса
filter.setIncludePayload(true); // 3) Данные формы
filter.setMaxPayloadLength(1000);
filter.setAfterMessagePrefix("COMPLETE REQUEST: ");
return filter;
}
вы включаете логирование:
1. заголовков запроса (Request headers)
2. query-параметров (Query parameters)
3. данных формы (Form data)
Без этого Spring маскирует или опускает многие из этих деталей, чтобы избежать утечки информации.
Не используйте это в production, иначе вы раскроете чувствительную информацию, например пароли:
POST /login
Body: {"username":"john","password":"mypassword"}
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4❤2
Вопрос на собеседовании по Git:
Ваша основная ветка (main) опережает вашу локальную ветку.
Как обновить свою ветку, не затронув ваши коммиты?
git fetch
Скачивает последние изменения из удалённого репозитория, не изменяя ваши локальные коммиты.
git rebase origin/main
Перенакладывает (reapply) ваши коммиты поверх обновлённой ветки main, сохраняя чистую историю коммитов.
До rebase:
После rebase:
👉 Java Portal
Ваша основная ветка (main) опережает вашу локальную ветку.
Как обновить свою ветку, не затронув ваши коммиты?
git fetch
Скачивает последние изменения из удалённого репозитория, не изменяя ваши локальные коммиты.
git rebase origin/main
Перенакладывает (reapply) ваши коммиты поверх обновлённой ветки main, сохраняя чистую историю коммитов.
До rebase:
A --- B --- C (origin/main)
\
D --- E (ваша ветка)
После rebase:
A --- B --- C --- D --- E
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Java Portal | Программирование
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика
Связь: @devmangx
РКН: https://clck.ru/3H4WUg
Связь: @devmangx
РКН: https://clck.ru/3H4WUg
👍14❤3🤔1
Совет по Java 💡 : используйте
👉 Java Portal
Files.walk() для рекурсивной обработки файлов в директории.Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥10👍4❤2
Обход правила WAF в CloudFront, которое блокирует доступ к Spring Boot.
Все обходы возвращают реальные данные Actuator:
👉 Java Portal
Все обходы возвращают реальные данные Actuator:
GET /%61ctuator/health → HTTP 200 (5122B) ← 'a' закодирована
GET /a%63tuator/health → HTTP 200 (5123B) ← 'c' закодирована
GET /ac%74uator/health → HTTP 200 (5122B) ← 't' закодирована
GET /act%75ator/health → HTTP 200 (5123B) ← 'u' закодирована
GET /actu%61tor/health → HTTP 200 (5123B) ← 'a' закодирована
GET /actua%74or/health → HTTP 200 (5123B) ← 't' закодирована
GET /actuat%6For/health → HTTP 200 (5123B) ← 'o' закодирована
GET /actuato%72/health → HTTP 200 (5123B) ← 'r' закодирована
GET /a%63%74uator/health → HTTP 200 (5123B) ← двойное кодирование
GET /%61ctua%74or/health → HTTP 200 (5123B) ← двойное кодирование
GET /%61%63%74%75%61%74%6F%72/health → HTTP 200 (5122B) ← полностью закодировано
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2