Карточки про синхронизаторы Java
Синхронизаторы позволяют управлять потоками более гибко, мощно и безопасно, чем низкоуровневые и примитивные
Примеры использования:
🔸 Ограничить количество одновременных действий
🔸 Дождаться завершения нескольких потоков
🔸 Запустить все потоки одновременно
🔸 Обменяться данными между потоками
👉 Java Portal
Синхронизаторы позволяют управлять потоками более гибко, мощно и безопасно, чем низкоуровневые и примитивные
synchronized
, wait
, notify
и join
Примеры использования:
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍5🔥3
Как обработать 1 миллион API-запросов в минуту
1. Балансировка нагрузки
Проблема:
Один сервер не выдерживает 1M запросов/мин: перегрузка CPU и памяти, начинается дроп запросов.
Решение:
- Использовать балансировщик нагрузки (NGINX, HAProxy, AWS ELB) для распределения трафика между множеством серверов
- Добавить проверки состояния , чтобы не направлять трафик на нерабочие инстансы
- Настроить авто-масштабирование, чтобы запускать новые инстансы при всплеске трафика
2. Кеширование
Проблема:
Каждый запрос бьет по базе → база становится узким местом (исчерпание соединений, медленные запросы).
Решение:
Добавить уровни кеширования:
- CDN для статических ресурсов (изображения, CSS, JS)
- Redis/Memcached для повторяющихся запросов
- Настроить правила инвалидации кеша, чтобы данные оставались актуальными
> Вместо 1M запросов к базе, возможно, только 100K дойдут после кеширования.
3. Ограничение частоты запросов
Проблема:
Всплеск активности (например, от ботов или злоумышленников) перегружает инфраструктуру → хорошие пользователи получают 503.
Решение:
- Алгоритмы Token Bucket / Leaky Bucket: позволяют короткие всплески, но сохраняют стабильный поток
- Разные лимиты для аутентифицированных и анонимных пользователей
- Возвращать
> Защищает инфраструктуру: один плохой пользователь не портит всё остальным.
4. Асинхронная обработка
Проблема:
Некоторые запросы тяжелые (обработка файлов, аналитика, отправка писем). Если делать их синхронно — ответ замедляется.
Решение:
- Выносить тяжёлые задачи в очередь (Kafka, RabbitMQ, SQS)
- Отвечать сразу с кодом
- Воркеры обрабатывают очередь и выполняют задачи
> Пользователи получают быстрый ответ, тяжёлая работа происходит «за кулисами».
5. Мониторинг и обратное давление
Проблема:
Даже при использовании балансировки, кешей и очередей, резкие всплески могут вызвать каскадные сбои.
Решение:
- Мониторить глубину очередей, задержки при доступе к БД, hit rate кеша
- Применять backpressure: замедлять запросы или отбрасывать нагрузку при приближении к лимитам
- Настроить алерты: Prometheus/Grafana, Datadog, New Relic
👉 Java Portal
1. Балансировка нагрузки
Проблема:
Один сервер не выдерживает 1M запросов/мин: перегрузка CPU и памяти, начинается дроп запросов.
Решение:
- Использовать балансировщик нагрузки (NGINX, HAProxy, AWS ELB) для распределения трафика между множеством серверов
- Добавить проверки состояния , чтобы не направлять трафик на нерабочие инстансы
- Настроить авто-масштабирование, чтобы запускать новые инстансы при всплеске трафика
2. Кеширование
Проблема:
Каждый запрос бьет по базе → база становится узким местом (исчерпание соединений, медленные запросы).
Решение:
Добавить уровни кеширования:
- CDN для статических ресурсов (изображения, CSS, JS)
- Redis/Memcached для повторяющихся запросов
- Настроить правила инвалидации кеша, чтобы данные оставались актуальными
> Вместо 1M запросов к базе, возможно, только 100K дойдут после кеширования.
3. Ограничение частоты запросов
Проблема:
Всплеск активности (например, от ботов или злоумышленников) перегружает инфраструктуру → хорошие пользователи получают 503.
Решение:
- Алгоритмы Token Bucket / Leaky Bucket: позволяют короткие всплески, но сохраняют стабильный поток
- Разные лимиты для аутентифицированных и анонимных пользователей
- Возвращать
429 Too Many Requests
— корректно и информативно> Защищает инфраструктуру: один плохой пользователь не портит всё остальным.
4. Асинхронная обработка
Проблема:
Некоторые запросы тяжелые (обработка файлов, аналитика, отправка писем). Если делать их синхронно — ответ замедляется.
Решение:
- Выносить тяжёлые задачи в очередь (Kafka, RabbitMQ, SQS)
- Отвечать сразу с кодом
202 Accepted
, обработку запускать в фоне - Воркеры обрабатывают очередь и выполняют задачи
> Пользователи получают быстрый ответ, тяжёлая работа происходит «за кулисами».
5. Мониторинг и обратное давление
Проблема:
Даже при использовании балансировки, кешей и очередей, резкие всплески могут вызвать каскадные сбои.
Решение:
- Мониторить глубину очередей, задержки при доступе к БД, hit rate кеша
- Применять backpressure: замедлять запросы или отбрасывать нагрузку при приближении к лимитам
- Настроить алерты: Prometheus/Grafana, Datadog, New Relic
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8👀3👍2
Аннотации в конструкторах Java . декларации и типы
В языке программирования Java можно аннотировать конструкторы. Например, это часто используется в библиотеках для внедрения зависимостей :
В этом примере
🔸 Аннотации деклараций и конструкторы
В этом посте нас не интересуют сами DI-библиотеки — важно лишь то, что аннотацию
Если взглянуть на определение аннотации
Здесь в
🔸 Аннотации типов и конструкторы
До недавнего времени я даже не знал, что конструкторы в Java можно аннотировать также и аннотациями типов. Я много раз просматривал конструкторы, но всё равно упускал, что тип конструктора тоже может быть аннотирован.
Пример — создадим следующую аннотацию:
Это аннотация
Теперь применим её к конструктору:
Код компилируется без ошибок. Обрати внимание: класс
🔸 Извлечение аннотации во время выполнения
Для полноты картины — пример, как извлечь аннотацию типа с конструктора во время выполнения:
Пошагово:
1. Получаем объект
2. Через
3. Из
4. Печатаем аннотации
Пример вывода:
То есть конструктор действительно аннотирован аннотацией типа
В языке программирования Java тело конструктора не должно содержать операторов
Таким образом, в объявлении конструктора присутствует использование типа — типа создаваемого объекта. А в Java можно аннотировать любое использование типа. Такие аннотации называются аннотациями типа
Исходный код, использованный в этом посте, можно найти в этом [Gist]
👉 Java Portal
В языке программирования Java можно аннотировать конструкторы. Например, это часто используется в библиотеках для внедрения зависимостей :
@Inject
MyService(FooProcessor processor, BarLogger logger) {
this.processor = processor;
this.logger = logger;
}
В этом примере
MyService
— это конструктор некоего сервиса, и он помечен аннотацией @Inject
. Эта аннотация сообщает DI-библиотеке, что нужно использовать именно этот конструктор для создания экземпляра сервиса.В этом посте нас не интересуют сами DI-библиотеки — важно лишь то, что аннотацию
@Inject
можно ставить на уровне декларации конструктора.Если взглянуть на определение аннотации
@Inject
, то оно будет примерно таким:@Target({METHOD, CONSTRUCTOR, FIELD})
@Retention(RUNTIME)
public @interface Inject {}
Здесь в
@Target
указано CONSTRUCTOR
, что означает, что аннотацию можно применять к конструкторам. Так как @Inject
применяется к декларациям, её называют аннотацией декларации До недавнего времени я даже не знал, что конструкторы в Java можно аннотировать также и аннотациями типов. Я много раз просматривал конструкторы, но всё равно упускал, что тип конструктора тоже может быть аннотирован.
Пример — создадим следующую аннотацию:
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
@interface T {}
Это аннотация
@T
, которая применяется только к типам (TYPE_USE
). Также указана политика RUNTIME
, чтобы можно было получить доступ к аннотации во время выполнения.Теперь применим её к конструктору:
static class Subject {
public @T Subject() {}
}
Код компилируется без ошибок. Обрати внимание: класс
Subject
— вложенный (static class
), не inner
, поэтому используется модификатор static
.Для полноты картины — пример, как извлечь аннотацию типа с конструктора во время выполнения:
void main() throws NoSuchMethodException {
final Class<?> type = Subject.class;
final Constructor<?> constructor = type.getDeclaredConstructor();
final AnnotatedType annotatedType = constructor.getAnnotatedReturnType();
final Annotation[] typeAnnotations = annotatedType.getDeclaredAnnotations();
print("Type annotations are:", typeAnnotations);
}
private void print(String msg, Annotation[] annotations) {
System.out.println(msg);
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
}
Пошагово:
1. Получаем объект
Constructor
для конструктора класса Subject
2. Через
getAnnotatedReturnType()
получаем AnnotatedType
, представляющий тип возвращаемого значения конструктора3. Из
AnnotatedType
извлекаем все аннотации типа4. Печатаем аннотации
Пример вывода:
Type annotations are:
@TypeAnnotations2.T()
То есть конструктор действительно аннотирован аннотацией типа
@T
.В языке программирования Java тело конструктора не должно содержать операторов
return
с возвращаемым значением. Однако, подобно методу, возвращающему, скажем, объект Foo
, конструктор тоже возвращает значение. Результатом вызова конструктора (если он завершается без исключений) является новый экземпляр объекта, тип которого — это тип класса, в котором объявлен данный конструктор.Таким образом, в объявлении конструктора присутствует использование типа — типа создаваемого объекта. А в Java можно аннотировать любое использование типа. Такие аннотации называются аннотациями типа
Исходный код, использованный в этом посте, можно найти в этом [Gist]
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥2🤔1
GIT Шпаргалка
🔸 Настройка репозитория
🔸 Базовые команды
🔸 Работа с ветками
🔸 Удалённые репозитории
🔸 Отмена изменений
🔸 Продвинутые команды
👉 Java Portal
git init # Инициализировать репозиторий
git clone <url> # Клонировать репозиторий
git config --global user.name "Name" # Установить имя пользователя
git config --global user.email "email" # Установить email
git status # Проверить статус
git add <file> # Проиндексировать файл
git add . # Проиндексировать все файлы
git commit -m "msg" # Зафиксировать изменения
git commit -am "msg" # Индексация + фиксация
git log # История коммитов
git diff # Показать изменения
git branch # Показать список веток
git branch -a # Показать все ветки (вкл. удалённые)
git branch <name> # Создать ветку
git checkout <branch> # Переключиться на ветку
git checkout -b <name> # Создать и переключиться на ветку
git merge <branch> # Слить ветку
git branch -d <name> # Удалить ветку
git remote # Показать список удалённых
git remote -v # Показать URL-адреса удалённых
git push <remote> <branch> # Отправить изменения
git pull <remote> <branch> # Получить изменения
git fetch # Забрать изменения без слияния
git reset <file> # Убрать файл из индекса
git reset --hard # Откат к последнему коммиту
git checkout <file> # Отменить изменения в файле
git revert <commit> # Откатить коммит (реверт)
git stash # Сохранить изменения во временное хранилище
git stash pop # Применить stash
git rebase <branch> # Перебазировать ветку
git tag <name> # Создать тег
git log --oneline # Краткий лог коммитов
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍7
Ссылки на методы и функциональные интерфейсы:
Познакомься с ссылками на методы — более чистым и умным способом передавать поведение в современной Java.
В связке с функциональными интерфейсами они позволяют писать лаконичный, читаемый и элегантный код без потери типобезопасности и выразительности.
👉 Java Portal
Познакомься с ссылками на методы — более чистым и умным способом передавать поведение в современной Java.
В связке с функциональными интерфейсами они позволяют писать лаконичный, читаемый и элегантный код без потери типобезопасности и выразительности.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍3❤2
JetBrains меняет дистрибуцию IntelliJ IDEA
Теперь не будет отдельных установщиков для Community и Ultimate будет единый инсталлятор с полным набором функций.
Подписка по-прежнему нужна для доступа к функциям Ultimate Edition, но без подписки IDE останется полностью рабочей и бесплатной, включая больше возможностей, чем сейчас в Community Edition.
Что ещё важно:
🔸 Открытые сборки будут публиковаться на GitHub.
🔸 Если подписка истечёт, IDE не заблокируется — вы продолжите работать в режиме Community Edition.
🔸 Улучшенный опыт с управлением лицензиями.
Поддержка open-source и бесплатного использования остаётся приоритетом JetBrains.🐒
Подробнее по ссылке - jetbrains.com/blog
👉 Java Portal
Теперь не будет отдельных установщиков для Community и Ultimate будет единый инсталлятор с полным набором функций.
Подписка по-прежнему нужна для доступа к функциям Ultimate Edition, но без подписки IDE останется полностью рабочей и бесплатной, включая больше возможностей, чем сейчас в Community Edition.
Что ещё важно:
Поддержка open-source и бесплатного использования остаётся приоритетом JetBrains.
Подробнее по ссылке - jetbrains.com/blog
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤11🔥6🌚1
Совет по Java: используйте
✅
Но, он не потокобезопасен (используйте
👉 Java Portal
HashMap
как реализацию Map
, когда нужна максимальная производительность общего назначения.HashMap
внутри реализован как хеш-таблица, и в среднем операции put(), get()
и remove()
работают за O(1).Но, он не потокобезопасен (используйте
ConcurrentHashMap
, если нужна потокобезопасность).Please open Telegram to view this post
VIEW IN TELEGRAM
❤12👍10
Телеграфируем кодом Морзе через Java Stream API
Как с помощью Java Stream API реализовать кодирование и декодирование текста в азбуке Морзе. Объясняется история азбуки Морзе, принципы её работы и показано практическое применение функционального программирования в Java для преобразования текста в Морзе и обратно. Приятного изучения💊
Читать гайд
👉 Java Portal
Как с помощью Java Stream API реализовать кодирование и декодирование текста в азбуке Морзе. Объясняется история азбуки Морзе, принципы её работы и показано практическое применение функционального программирования в Java для преобразования текста в Морзе и обратно. Приятного изучения
Читать гайд
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥5❤3
JVM Thread dump
Сегодня поговорим о тред дампах.
Что такое тред дамп?🌟
Это распечатка всех стектрейсов(всех выполняющихся методов) всех существующих тредов внутри JVM.
Зачем снимать треддамп?
Бывают ситуации, что мы запустили операцию, а она долго висит и мы не понимаем где и почему.
Бывают ситуации, когда ряд методов ждут блокировки и нужно понять какой тред блокировку держит и почему не отпускает.
То есть тред дамп позволят заглянуть внутрь JVM и понять чем занимаются все треды.
Так же тред дамп показывает статус всех тредов (
Как снимать треддамп?
Существует несколько команд:
1)
2)
👉 Java Portal
Сегодня поговорим о тред дампах.
Что такое тред дамп?
Это распечатка всех стектрейсов(всех выполняющихся методов) всех существующих тредов внутри JVM.
Зачем снимать треддамп?
Бывают ситуации, что мы запустили операцию, а она долго висит и мы не понимаем где и почему.
Бывают ситуации, когда ряд методов ждут блокировки и нужно понять какой тред блокировку держит и почему не отпускает.
То есть тред дамп позволят заглянуть внутрь JVM и понять чем занимаются все треды.
Так же тред дамп показывает статус всех тредов (
RUNNABLE, WAITING, TIMED WAITING
)Как снимать треддамп?
Существует несколько команд:
1)
jstack
jstack <pid>
2)
jcmd
jcmd <pid> Thread.print
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤4
Регулярные выражения в реальной жизни
🔸 SMS Spam Filter
Ловит спам-ключевые слова.
Примеры: "FREE $500!", "prize winner"
🔸 Password Validator
Проверяет сложность пароля (минимум одна заглавная буква, одна цифра, длина ≥ 8).
Примеры: "MyPass123" ✓, "weak" ✗
🔸 Email Field Check
Валидирует email-адрес.
Пример: "[email protected]" ✓
🔸 Smart Date Detection
Находит даты в тексте.
Пример: "Meeting on 15/8/2025"
🔸 Photo Search
Фильтрует фото по дате.
Пример: "IMG_2025-08-15.jpg"
🔸 Subtitle Timing
Матчит формат таймкодов (субтитры).
Пример: "00:01:23,456"
🔸 Parental Controls
Блокирует URL соцсетей.
Пример: "m.facebook.com"
🔸 Expense Tracking
Извлекает суммы в валюте.
Примеры: "$1,500", "$50,000"
🔸 TV Episode Filter
Матчит конкретные сезоны и эпизоды.
Примеры: "S01E05", "S03E12"
🔸 E-book Chapters
Делит текст книги на главы.
Примеры: "CHAPTER 1", "CHAPTER 15"
🔸 Phone Number (US)
Проверяет формат мобильного номера (США).
Пример: "+1 9876543210"
🔸 Credit Card Mask
Находит номера карт для маскировки.
Пример: "1234 5678 9012 3456"
🔸 Log File Parsing
Парсит таймстемпы логов (формат Apache/Nginx).
Пример: "[01/Aug/2025:10:30:45"
🔸 URL Slug Creator
Удаляет не-URL символы (для генерации slug).
Пример: "My Post!" → "my-post"
🔸 ZIP Code (US)
Матчит почтовые индексы США.
Примеры: "12345", "12345-6789"
Паттерны из реальной жизни
🔸 WhatsApp backup names
🔸 YouTube video IDs
Например: "dQw4w9WgXcQ"
🔸 Hashtag extraction
Извлекает хэштеги из текста.
🔸 IPv4 addresses
🔸 HTML tag removal
Удаляет HTML-теги из текста.
🔸 Bitcoin addresses
👉 Java Portal
FREE \b(prize|winner|URGENT)\b
Ловит спам-ключевые слова.
Примеры: "FREE $500!", "prize winner"
(?=.*[A-Z])(?=.*\d).{8,}
Проверяет сложность пароля (минимум одна заглавная буква, одна цифра, длина ≥ 8).
Примеры: "MyPass123" ✓, "weak" ✗
^[\w.+]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
Валидирует email-адрес.
Пример: "[email protected]" ✓
\b\d{1,2}/\d{1,2}/\d{4}\b
Находит даты в тексте.
Пример: "Meeting on 15/8/2025"
IMG_2025-08-.*\.jpg
Фильтрует фото по дате.
Пример: "IMG_2025-08-15.jpg"
\d+:\d+:\d+,\d+
Матчит формат таймкодов (субтитры).
Пример: "00:01:23,456"
.*(facebook|instagram)\.com.*
Блокирует URL соцсетей.
Пример: "m.facebook.com"
\$\d{1,3}(,\d{3})*
Извлекает суммы в валюте.
Примеры: "$1,500", "$50,000"
S[0-9]{1,2}E\d{1,2}
Матчит конкретные сезоны и эпизоды.
Примеры: "S01E05", "S03E12"
^CHAPTER\s+\d+\b
Делит текст книги на главы.
Примеры: "CHAPTER 1", "CHAPTER 15"
^\+1\d{10}$
Проверяет формат мобильного номера (США).
Пример: "+1 9876543210"
\d{4}\s?\d{4}\s?\d{4}\s?\d{4}
Находит номера карт для маскировки.
Пример: "1234 5678 9012 3456"
\[\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2}
Парсит таймстемпы логов (формат Apache/Nginx).
Пример: "[01/Aug/2025:10:30:45"
[^a-z0-9-]
Удаляет не-URL символы (для генерации slug).
Пример: "My Post!" → "my-post"
^\d{5}(-\d{4})?$
Матчит почтовые индексы США.
Примеры: "12345", "12345-6789"
Паттерны из реальной жизни
WhatsApp.*\d{4}-\d{2}-\d{2}.*\.crypt\d+
[a-zA-Z0-9_-]{11}
Например: "dQw4w9WgXcQ"
#\w+
Извлекает хэштеги из текста.
\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
<[^>]+>
Удаляет HTML-теги из текста.
[13][a-km-zA-HJ-NP-Z1-9]{25,34}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17❤6🔥4🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
Ваш новый секретный арсенал для проектов — более 1500 крутых API в одном месте
Нужны данные о погоде, карты, генерация изображений или мощные NLP-сервисы? Всё это и даже больше в огромной коллекции, которую проверили и отобрали вручную💊
Забираем с сайта или с GitHub🍯
👉 Java Portal
Нужны данные о погоде, карты, генерация изображений или мощные NLP-сервисы? Всё это и даже больше в огромной коллекции, которую проверили и отобрали вручную
Забираем с сайта или с GitHub
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3🔥3
Фича в Java 21 - Pattern Matching в "switch" блоке
До Java 21 блок
- использовать
- проверять типы прямо в case
- деструктуризировать
До этой фичи, проверить тип
С новой фичей проверку на тип и работа с объектом конкретного типа можно через switch:
Чище, безопаснее и не нужно вручную кастовать типы.
👉 Java Portal
До Java 21 блок
switch
работал только с int, enum, String и еще несколькими примитивами. С JEP 441 теперь можно:- использовать
switch
с любыми объектами- проверять типы прямо в case
- деструктуризировать
record
-объектыДо этой фичи, проверить тип
Object
можно было с помощью instanceof
и код был набором if
-ов с приведением типа Object
к нужному:if (obj instanceof String) {
String s = (String) obj;
System.out.println("String length: " + s.length());
} else if (obj instanceof Integer) {
Integer i = (Integer) obj;
System.out.println("Square: " + (i * i));
}
С новой фичей проверку на тип и работа с объектом конкретного типа можно через switch:
Object obj = "abc";
switch (obj) {
case String s -> System.out.println("String length: " + s.length());
case Integer i -> System.out.println("Square: " + (i * i));
default -> System.out.println("Unknown type");
}
Чище, безопаснее и не нужно вручную кастовать типы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍2