Очень частый сценарий для собеседований по Java/бэкенду, который игнорировать нельзя.
Нужно ли защищать API?
Сценарий = ваш endpoint для логина может вызываться не более 10 раз в минуту для одного пользователя.
→ Простейший подход — Fixed Window Counter (счётчик фиксированного окна) = считаем запросы с 10:01 до 10:02, потом сбрасываем счётчик.
Проблема? Пользователь может сделать 10 запросов в 10:01:59 и ещё 10 в 10:02:01. Итого 20 запросов за 2 секунды🤯
Для более надёжного решения используют Sliding Window для плавного ограничения или Token Bucket, чтобы корректно обрабатывать всплески.
→ Sliding Window
Избегает проблемы резких всплесков на границе окна. Вместо фиксированной минуты (например, 10:01) считает запросы за последние 60 секунд от момента запроса. Дает более плавное и точное ограничение скорости.
→ Token Bucket
Отлично подходит для корректной обработки всплесков. Представьте ведро, которое постепенно наполняется «токенами» (например, 1 токен в секунду, ведро для одного пользователя/IP/endpoint). Каждый API-запрос «съедает» один токен. Если токенов нет — запрос отклоняется. Так контролируется средняя скорость, но при этом пользователи могут накопить несколько токенов для небольшого всплеска.
Выбор алгоритма зависит от того, хотите ли вы строгое ограничение сверху или управлять средней скоростью.
👉 Java Portal
Нужно ли защищать API?
Сценарий = ваш endpoint для логина может вызываться не более 10 раз в минуту для одного пользователя.
→ Простейший подход — Fixed Window Counter (счётчик фиксированного окна) = считаем запросы с 10:01 до 10:02, потом сбрасываем счётчик.
Проблема? Пользователь может сделать 10 запросов в 10:01:59 и ещё 10 в 10:02:01. Итого 20 запросов за 2 секунды
Для более надёжного решения используют Sliding Window для плавного ограничения или Token Bucket, чтобы корректно обрабатывать всплески.
→ Sliding Window
Избегает проблемы резких всплесков на границе окна. Вместо фиксированной минуты (например, 10:01) считает запросы за последние 60 секунд от момента запроса. Дает более плавное и точное ограничение скорости.
→ Token Bucket
Отлично подходит для корректной обработки всплесков. Представьте ведро, которое постепенно наполняется «токенами» (например, 1 токен в секунду, ведро для одного пользователя/IP/endpoint). Каждый API-запрос «съедает» один токен. Если токенов нет — запрос отклоняется. Так контролируется средняя скорость, но при этом пользователи могут накопить несколько токенов для небольшого всплеска.
Выбор алгоритма зависит от того, хотите ли вы строгое ограничение сверху или управлять средней скоростью.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤8🔥5👍2😁2
«99% аптайма достаточно».
Эту сказку слишком многие команды рассказывают сами себе.
А теперь математика:
• 99% аптайма —> примерно 7 часов простоя в месяц
• 99.9% —> около 40 минут
• 99.99% —> около 4 минут
Семь часов вроде не звучат страшно, но на масштабе это убивает доверие, срывает SLA и сжигает деньги.
И даунтайм не всегда выглядит как большой и громкий инцидент.
Он подкрадывается через такие вещи, как:
• платежка, которая теряет запросы без ретраев
• битый конфиг кэша, из-за которого трафик встаёт
• сервис, который тихо отваливается для части пользователей
Поэтому надёжность это не погоня за «100%». Это про системы, которые умеют гнуться, но не ломаться.
Ретраи. Circuit breakers. Фолбэки с сохранением работоспособности.
И правильные метрики — error budgets, а не красивые проценты для отчёта.
Потому что пользователю плевать на твой аптайм в дэшборде.
Ему важно, чтобы продукт работал, когда это реально нужно.
Так что когда кто-то снова скажет «99% это нормально», спроси его
Нормально для графика или нормально для клиента?
👉 Java Portal
Эту сказку слишком многие команды рассказывают сами себе.
А теперь математика:
• 99% аптайма —> примерно 7 часов простоя в месяц
• 99.9% —> около 40 минут
• 99.99% —> около 4 минут
Семь часов вроде не звучат страшно, но на масштабе это убивает доверие, срывает SLA и сжигает деньги.
И даунтайм не всегда выглядит как большой и громкий инцидент.
Он подкрадывается через такие вещи, как:
• платежка, которая теряет запросы без ретраев
• битый конфиг кэша, из-за которого трафик встаёт
• сервис, который тихо отваливается для части пользователей
Поэтому надёжность это не погоня за «100%». Это про системы, которые умеют гнуться, но не ломаться.
Ретраи. Circuit breakers. Фолбэки с сохранением работоспособности.
И правильные метрики — error budgets, а не красивые проценты для отчёта.
Потому что пользователю плевать на твой аптайм в дэшборде.
Ему важно, чтобы продукт работал, когда это реально нужно.
Так что когда кто-то снова скажет «99% это нормально», спроси его
Нормально для графика или нормально для клиента?
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5
Бронировал когда-нибудь онлайн перелёт, отель и машину, но отель сорвался? Вряд ли захочешь остаться с билетом и машиной, но без номера.
Паттерн SAGA работает как умный тревел-агент для микросервисов. Он управляет последовательностью операций —> сначала бронируем перелёт, потом отель.
Если один шаг падает, автоматически запускаются компенсирующие действия, которые откатывают предыдущие шаги —> например отмена перелёта.
Это гарантирует, что система не окажется в неконсистентном состоянии. Такой подход реально выручает, когда нужно работать с транзакциями в распределённых Java-сервисах.
Как это работает:
Успешный путь - bookFlight() → bookHotel() → rentCar() и можно ехать отдыхать.
При провале, если bookHotel() падает, в catch запускается cancelFlight() и первый шаг откатывается.
В итоге ты не остаёшься с перелётом в никуда, а система сохраняет консистентность.
👉 Java Portal
Паттерн SAGA работает как умный тревел-агент для микросервисов. Он управляет последовательностью операций —> сначала бронируем перелёт, потом отель.
Если один шаг падает, автоматически запускаются компенсирующие действия, которые откатывают предыдущие шаги —> например отмена перелёта.
Это гарантирует, что система не окажется в неконсистентном состоянии. Такой подход реально выручает, когда нужно работать с транзакциями в распределённых Java-сервисах.
Как это работает:
Успешный путь - bookFlight() → bookHotel() → rentCar() и можно ехать отдыхать.
При провале, если bookHotel() падает, в catch запускается cancelFlight() и первый шаг откатывается.
В итоге ты не остаёшься с перелётом в никуда, а система сохраняет консистентность.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4❤2👍2
В Java-приложениях одна небольшая настройка может улучшить производительность в 50 раз.
Видите здесь что-нибудь странное?
Аннотация
Хуже всего то, что по умолчанию
- лишние блокировки ресурсов;
- база вынуждена обрабатывать транзакцию даже для простого SELECT.
Что можно сделать:
Это позволит:
Правила, которые стоит помнить:
Не вешайте
Используйте
Убирайте
Регулярно профилируйте приложение — мелкие ошибки выливаются в огромные потери производительности.
👉 Java Portal
@Transactional
public List<Order> getRecentOrders() {
return orderRepository.findRecent();
}
Видите здесь что-нибудь странное?
Аннотация
@Transactional
на методе, который просто делает read/GET вызов.Хуже всего то, что по умолчанию
@Transactional
работает в режиме read-write, то есть:- лишние блокировки ресурсов;
- база вынуждена обрабатывать транзакцию даже для простого SELECT.
Что можно сделать:
@Transactional(readOnly = true)
Это позволит:
Пропустить ненужные flush-операции в Hibernate.
Оптимизировать работу транзакций для SELECT-запросов.
Уменьшить оверхед от прокси и избежать лишних блокировок.
Правила, которые стоит помнить:
Не вешайте
@Transactional
везде подряд только ради «красоты».Используйте
@Transactional(readOnly = true)
для запросов.Убирайте
@Transactional
, если методу вообще не нужна транзакция.Регулярно профилируйте приложение — мелкие ошибки выливаются в огромные потери производительности.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥3
Лучший способ вырасти — это персональный план развития от Senior-инженера из БигТеха.
Вот как все работает:
Мы в ШОРТКАТ провели уже почти 1000 таких мок-интервью и получили оценку 4.9/5, поэтому знаем о чем говорим.
Мы хотим, чтобы у каждого была возможность проверить в деле наш сервис, а потом уже доверить нам свое развитие.
Переходи в нашего бота и забирай свой мок за 900 рублей → @shortcut_sh_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7🤯7
Недавно на собеседовании кандидата спросили о четырёх основных функциональных интерфейсах Java 8. Когда его попросили объяснить каждый из них, он растерялся.
Вот эти 4 основных функциональных интерфейса:
I.
Проверяет, удовлетворяет ли входное значение условию, возвращая true или false.
Как я запоминаю: как фейс-контроллер в клубе, который проверяет, есть ли ты в списке гостей, прежде чем пустить внутрь.
II.
Принимает один аргумент и возвращает один результат, трансформируя данные.
Как я запоминаю: торговый автомат, который принимает монету (вход) и выдает газировку (выход).
III.
Предоставляет результат без необходимости передавать аргументы, как фабричный метод.
Как я запоминаю: волшебная шляпа, из которой по запросу достается кролик, без предварительных условий.
IV.
Принимает входное значение и выполняет над ним действие, но ничего не возвращает.
Как я запоминаю: мусорное ведро, которое принимает твой мусор (вход) и просто утилизирует его, без всякой «квитанции» на выходе.
На скрине пример, который использует все эти 4 интерфейса.
👉 Java Portal
Вот эти 4 основных функциональных интерфейса:
I.
Predicate<T>
Проверяет, удовлетворяет ли входное значение условию, возвращая true или false.
Как я запоминаю: как фейс-контроллер в клубе, который проверяет, есть ли ты в списке гостей, прежде чем пустить внутрь.
II.
Function<T, R>
Принимает один аргумент и возвращает один результат, трансформируя данные.
Как я запоминаю: торговый автомат, который принимает монету (вход) и выдает газировку (выход).
III.
Supplier<T>
Предоставляет результат без необходимости передавать аргументы, как фабричный метод.
Как я запоминаю: волшебная шляпа, из которой по запросу достается кролик, без предварительных условий.
IV.
Consumer<T>
Принимает входное значение и выполняет над ним действие, но ничего не возвращает.
Как я запоминаю: мусорное ведро, которое принимает твой мусор (вход) и просто утилизирует его, без всякой «квитанции» на выходе.
На скрине пример, который использует все эти 4 интерфейса.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤17👍8
Маршрут построен: в пятницу – на VK JT Meetup!
Это неформальная встреча для ML-инженеров и Java-разработчиков от VK.
О чём расскажут:
• Какие вызовы возникают перед бэкендером в процессе создания B2B-продукта
• Как строят единую инфраструктуру поисковой платформы
А также поделятся пошаговым гайдом по выпуску RAG в прод
Дальше гостей ждут два потока: нетворкинг-зона и групповое решение кейсов по ML и Java.
Мероприятие пройдёт только офлайн — редкий шанс пообщаться с коллегами, задать вопросы экспертам и выиграть призы от VK. Регистрируйтесь!
📍 Нижний Новгород, только офлайн
📅 3 октября, сбор с 18:00
🎟 Вход по регистрации
Это неформальная встреча для ML-инженеров и Java-разработчиков от VK.
О чём расскажут:
• Какие вызовы возникают перед бэкендером в процессе создания B2B-продукта
• Как строят единую инфраструктуру поисковой платформы
А также поделятся пошаговым гайдом по выпуску RAG в прод
Дальше гостей ждут два потока: нетворкинг-зона и групповое решение кейсов по ML и Java.
Мероприятие пройдёт только офлайн — редкий шанс пообщаться с коллегами, задать вопросы экспертам и выиграть призы от VK. Регистрируйтесь!
📍 Нижний Новгород, только офлайн
📅 3 октября, сбор с 18:00
🎟 Вход по регистрации
❤1
Парсинг на Java. От основ до парсинга Яндекс Карт
Сегодня разбираем основы парсинга на Java с практическим примером на Яндекс Карт.
В статье рассматривается, что такое HTTP, как работают методы запросов, как использовать HttpClient в Java 11+ для отправки GET и POST-запросов, как обрабатывать HTTP-ответы и извлекать данные. Всё это показано на примере парсинга данных с внешнего сервера через Яндекс Карты, чтобы дать полное представление о работе с сетевыми запросами в Java.
👉 Java Portal
Сегодня разбираем основы парсинга на Java с практическим примером на Яндекс Карт.
В статье рассматривается, что такое HTTP, как работают методы запросов, как использовать HttpClient в Java 11+ для отправки GET и POST-запросов, как обрабатывать HTTP-ответы и извлекать данные. Всё это показано на примере парсинга данных с внешнего сервера через Яндекс Карты, чтобы дать полное представление о работе с сетевыми запросами в Java.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
В продакшн-коде использование длинных цепочек if-else обходится слишком дорого -> лишний else может привести к падению приложения. Понимание того, чем их заменить, отличает джуна от сеньора.
Если ты всё ещё пишешь подобные громоздкие цепочки if-else в ключевой бизнес-логике, ты фактически держишь свой код в заложниках. Такие конструкции просты, но они не масштабируются.
Когда логика усложняется, код становится трудным для тестирования, расширения и чтения.
Что делают опытные Java-разработчики? Они часто заменяют такие конструкции паттерном Strategy.
Strategy можно сравнить с выбором способа добраться до аэропорта. Вместо одной гигантской функции с if-else на тему «поехать на автобусе», «взять такси» или «сесть на поезд» ты создаёшь отдельную «стратегию» под каждый вариант. Основной код просто выбирает нужную стратегию и говорит: «Поехали».
Вместо бесконечных блоков else if ты:
→ Определяешь интерфейс стратегии (PaymentStrategy).
→ Создаёшь отдельные реализации под каждый случай (CreditCardPayment, UpiPayment).
→ Используешь Map для выбора нужной стратегии во время выполнения:
Готово. Теперь можно добавлять новую логику, не трогая старый код. Чисто, масштабируемо и поддерживаемо.
👉 Java Portal
if (paymentType.equals("creditcard")) {
processCreditCard(payment);
} else if (paymentType.equals("upi")) {
processUpi(payment);
} else if (paymentType.equals("crypto")) {
processCrypto(payment);
}
Если ты всё ещё пишешь подобные громоздкие цепочки if-else в ключевой бизнес-логике, ты фактически держишь свой код в заложниках. Такие конструкции просты, но они не масштабируются.
Когда логика усложняется, код становится трудным для тестирования, расширения и чтения.
Что делают опытные Java-разработчики? Они часто заменяют такие конструкции паттерном Strategy.
Strategy можно сравнить с выбором способа добраться до аэропорта. Вместо одной гигантской функции с if-else на тему «поехать на автобусе», «взять такси» или «сесть на поезд» ты создаёшь отдельную «стратегию» под каждый вариант. Основной код просто выбирает нужную стратегию и говорит: «Поехали».
Вместо бесконечных блоков else if ты:
→ Определяешь интерфейс стратегии (PaymentStrategy).
→ Создаёшь отдельные реализации под каждый случай (CreditCardPayment, UpiPayment).
→ Используешь Map для выбора нужной стратегии во время выполнения:
strategyMap.get(type).processPayment(payment);
Готово. Теперь можно добавлять новую логику, не трогая старый код. Чисто, масштабируемо и поддерживаемо.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥5❤2
Представлен бесплатный онлайн-плейграунд для SQL — RunSQL. 🪿
Сервис позволяет создавать таблицы, писать запросы и делиться результатами с командой. Поддерживаются MySQL, PostgreSQL и SQL Server.
Работает прямо из браузера, ничего устанавливать не нужно: http://runsql.com/r
👉 Java Portal
Сервис позволяет создавать таблицы, писать запросы и делиться результатами с командой. Поддерживаются MySQL, PostgreSQL и SQL Server.
Работает прямо из браузера, ничего устанавливать не нужно: http://runsql.com/r
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍5
Сериализация кажется простой, но интервьюеры часто используют её, чтобы понять, кто выходит за рамки обычного кодинга.
Главное, что должен знать каждый Java-разработчик:
serialVersionUID – если не объявлен, JVM сгенерирует свой. При изменении класса старые объекты перестают десериализоваться. Всегда объявляйте явно.
transient-поля – помечайте чувствительные данные (например, пароли) как transient, чтобы они не записывались на диск или в логи.
Возможны атаки через десериализацию. Никогда не десериализуйте ненадёжный ввод.
👉 Java Portal
Главное, что должен знать каждый Java-разработчик:
serialVersionUID – если не объявлен, JVM сгенерирует свой. При изменении класса старые объекты перестают десериализоваться. Всегда объявляйте явно.
transient-поля – помечайте чувствительные данные (например, пароли) как transient, чтобы они не записывались на диск или в логи.
Возможны атаки через десериализацию. Никогда не десериализуйте ненадёжный ввод.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤4
Современный Java, объяснённый просто (с примерами)
Многие думают, что Java сложный или многословный язык.
Но в последних версиях (Java 17 → 21 → 25) язык сильно изменился.
4 современных фичи, которые делают жизнь разработчика проще:
1. Records (меньше повторяющегося кода)
Раньше приходилось писать конструкторы, геттеры, toString…
Достаточно одной строки — всё это генерируется автоматически.
2. Sealed classes (контролируемое наследование)
Позволяет ограничить, какие классы могут наследоваться от другого.
Никто больше не сможет реализовать Shape, кроме разрешённых. Безопасность и ясность.
3. Pattern Matching (более мощный switch)
Теперь switch понимает типы, а не только значения.
Чище, чем использовать instanceof и касты повсюду.
4. Virtual Threads (лёгкая конкуренция)
С Java 21 появились виртуальные потоки → можно создавать тысячи потоков без падения системы.
Идеально для приложений с огромным количеством соединений (APIs, микросервисы).
Java больше не тот тяжёлый язык, каким был раньше.
А с выходом Java 25 как LTS он приносит ещё больше улучшений для разработчиков.
👉 Java Portal
Многие думают, что Java сложный или многословный язык.
Но в последних версиях (Java 17 → 21 → 25) язык сильно изменился.
4 современных фичи, которые делают жизнь разработчика проще:
1. Records (меньше повторяющегося кода)
Раньше приходилось писать конструкторы, геттеры, toString…
Достаточно одной строки — всё это генерируется автоматически.
2. Sealed classes (контролируемое наследование)
Позволяет ограничить, какие классы могут наследоваться от другого.
Никто больше не сможет реализовать Shape, кроме разрешённых. Безопасность и ясность.
3. Pattern Matching (более мощный switch)
Теперь switch понимает типы, а не только значения.
Чище, чем использовать instanceof и касты повсюду.
4. Virtual Threads (лёгкая конкуренция)
С Java 21 появились виртуальные потоки → можно создавать тысячи потоков без падения системы.
Идеально для приложений с огромным количеством соединений (APIs, микросервисы).
Java больше не тот тяжёлый язык, каким был раньше.
А с выходом Java 25 как LTS он приносит ещё больше улучшений для разработчиков.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤4
В Java на собеседованиях могут спросить про альтернативы
Ниже три мощные альтернативы
Используется для временных кэшей, хранения слушателей, метаданных, привязанных к жизненному циклу объекта.
Используется во фреймворках, парсерах и графах зависимостей, где важна физическая идентичность объекта.
Использовать
Используется всегда, если ключи берутся из одного
Быстрый гайд по выбору:
- Нужно автоочищение кэша →
- Нужна идентичность объектов (
- Ключи из
- Всё остальное →
👉 Java Portal
HashMap
, так как он не всегда самый быстрый или экономичный по памяти и иногда приводит к скрытым проблемам с производительностью, утечкам памяти и сложным багам. Ниже три мощные альтернативы
HashMap
и ситуации, когда стоит их использовать. WeakHashMap
: Самоочищающийся кэш HashMap
часто применяют для кэширования, но он держит сильные ссылки на ключи, мешая GC освободить память даже тогда, когда объект уже больше нигде не используется. Это может привести к утечкам памяти. WeakHashMap
хранит ключи через слабые ссылки. Если на объект-ключ больше нет сильных ссылок, GC может удалить его, и запись в мапе исчезнет автоматически. Используется для временных кэшей, хранения слушателей, метаданных, привязанных к жизненному циклу объекта.
IdentityHashMap
: Когда объекты "равны", но не одинаковы HashMap
проверяет ключи через метод .equals()
. Если у вас два объекта с одинаковыми данными, но это разные экземпляры (например, два Person
с одинаковым именем, но разными записями), то HashMap
перезапишет значение. IdentityHashMap
сравнивает ключи только по ссылке (==), игнорируя .equals()
. Разные объекты всегда будут разными ключами, даже если у них одинаковые данные. Используется во фреймворках, парсерах и графах зависимостей, где важна физическая идентичность объекта.
EnumMap
: Оптимизированный вариант для enum-ключей Использовать
enum
как ключ в HashMap
неэффективно. Нужно считать хэши, обрабатывать коллизии, хотя набор ключей фиксирован на этапе компиляции. EnumMap
специально создан для enum-ключей. Внутри он работает через массив, используя ordinal() значения enum в качестве индекса. Это даёт настоящие O(1)-операции и экономит память. Используется всегда, если ключи берутся из одного
enum
. Быстрый гайд по выбору:
- Нужно автоочищение кэша →
WeakHashMap
- Нужна идентичность объектов (
==
) → IdentityHashMap
- Ключи из
enum
→ EnumMap
- Всё остальное →
HashMap
по умолчаниюPlease open Telegram to view this post
VIEW IN TELEGRAM
👍8
Вот 17 авторских обучающих IT каналов по самым востребованным областям программирования:
Выбирай своё направление:
Please open Telegram to view this post
VIEW IN TELEGRAM
Google увеличил функционал Agent Development Kit для Java, внедрив поддержку LangChain4j. Теперь Java-инженеры способны подключать модели OpenAI, Anthropic, Mistral и прочие, разрабатывая многоагентные решения с более гибким контролем и усовершенствованной логикой.
Подробности: тык
👉 Java Portal
Подробности: тык
Please open Telegram to view this post
VIEW IN TELEGRAM
InfoQ
Google's Agent Development Kit for Java Adds Integration with LangChain4j
The latest release of the Agent Development Kit for Java, version 0.2.0, marks a significant expansion of its capabilities through the integration with the LangChain4j LLM framework, which opens it up to all the large language models supported by the framework.
❤3👍2