Java-разработчик
80 задач. Условие и варианты ответа открыты всем; проверка, подсказка и разбор — в клубе.
Java Core и многопоточность
- Объект без hashCode в роли ключа HashMap: что вернёт get
- Строка передана в метод и изменена внутри: что увидит вызывающий код
- Stream без терминальной операции: сколько строк попадёт в лог
- Удаление элемента внутри for-each по ArrayList
- orElse с обращением в базу: когда выполнится дорогой вызов
- volatile-счётчик обработанных сообщений теряет инкременты
- Задачи в ExecutorService падают, а в логах пусто
- parallelStream с блокирующими вызовами тормозит соседние эндпоинты
Spring Boot и REST API
- Две реализации одного интерфейса и внедрение по конструктору
- Ответ API на некорректные данные клиента
- Изменяемое поле в @Service: сколько экземпляров бина в приложении
- @Transactional не срабатывает при вызове метода внутри того же класса
- Переименование поля в ответе публичного API
- Циклическая зависимость двух сервисов при конструкторной инъекции
- Медленный внешний API кладёт сервис целиком
- Значение из application.yml не применилось в проде
PostgreSQL, JPA и производительность запросов
- Сколько запросов уйдёт в базу при обходе ленивой коллекции
- Чтение вывода EXPLAIN ANALYZE по медленному запросу
- Обращение к ленивой коллекции после выхода из транзакции
- Два инстанса списывают бонусы: почему баланс сходится неверно
- Составной индекс не помогает запросу по второй колонке
- Checked-исключение внутри @Transactional и откат
- join fetch вместе с постраничной выборкой
- Индекс по колонке статуса не ускорил чтение и замедлил запись
Kafka и надёжность распределённых сервисов
- Пять консьюмеров одной группы на топик из трёх партиций
- События одного заказа приходят в перепутанном порядке
- Гарантия at-least-once и повторная обработка сообщения
- Порядок коммита оффсета и обработки сообщения
- Одно неразбираемое сообщение остановило обработку партиции
- Запись в базу и отправка события в одном методе
- Повторы запросов усугубили аварию у смежного сервиса
- Проверка базы в liveness-пробе и циклические перезапуски подов
Тестирование: JUnit 5, Mockito, Testcontainers
- Юнит-тест сервиса скидок падает с NullPointerException внутри проверяемого метода
- Тест одного метода расчёта комиссии запускается 15 секунд
- Сообщение упавшего теста утверждает, что ожидалось неправильное значение
- Пять почти одинаковых тестов на валидацию ИНН отличаются только входной строкой
- Интеграционные тесты на H2 зелёные, а запрос падает на PostgreSQL в проде
- После рефакторинга сервиса упали 30 тестов, хотя поведение не изменилось
- Тест истечения подписки проходит днём и падает в ночь на первое число
- Каждый интеграционный тестовый класс заново поднимает контекст Spring
- Интеграционный тест Kafka-консьюмера ждёт результат через Thread.sleep(5000)
- Тест контроллера зелёный, а в проде LazyInitializationException
- Testcontainers поднимает новый PostgreSQL для каждого из 60 тестовых классов
- Команда заказов переименовала поле в ответе, и у соседей упала интеграция
JVM в контейнере, сборка и зависимости
- Сборка проходит у разработчика и падает на CI: не найдена зависимость
- Почему приложение Spring Boot запускается одной командой java -jar
- Образ сервиса на Java весит 900 МБ и содержит Maven и исходники
- Контейнер падает на старте с UnsupportedClassVersionError
- После добавления новой библиотеки в проде NoSuchMethodError в чужом коде
- Под перезапускается с OOMKilled, а в логах приложения нет OutOfMemoryError
- Контейнеру выдали 4 ГиБ памяти, а сервис падает с OutOfMemoryError на 1 ГиБ кучи
- Модуль использует классы из зависимости соседнего модуля, и сборка не компилируется
- Сканер уязвимостей нашёл критическую CVE в библиотеке, которой нет в pom.xml
- Раз в минуту время ответа сервиса подскакивает до 800 мс на всех запросах сразу
- Куча занята на 60%, а контейнер всё равно убивают за превышение памяти
- После добавления прогрева кэша под не может запуститься и перезапускается по кругу
Кэш и Redis в Spring
- После смены цены в админке карточка товара неделю показывает старую
- Менеджер обновил описание товара, а в каталоге оно появилось только через 10 минут
- Кэш остатков на складе с TTL 5 минут привёл к продаже отсутствующих товаров
- Очистка кэша командой KEYS остановила все сервисы, работающие с Redis
- Пользователи видят чужие персональные рекомендации
- После релиза чтение из кэша падает с ошибкой десериализации
- Redis с кэшем недоступен, и каталог отвечает 500, хотя база работает
- После обновления тарифа разные запросы показывают то старую, то новую цену
- Проверка повторного запроса через Redis иногда пропускает дубли
- С @Cacheable(sync = true) база всё равно получает шесть одинаковых тяжёлых запросов
- Цена обновлена и кэш сброшен, но в кэше снова оказалась старая цена
- Весь каталог из 60 тысяч товаров кэшируется одним ключом, и Redis тормозит
Наблюдаемость: логи, метрики Micrometer, трассировка
- В логе ошибки оплаты только текст «null», и непонятно, где она возникла
- Какой тип метрики выбрать для числа оплаченных заказов и для длины очереди
- Prometheus не собирает метрики сервиса, хотя Micrometer подключён
- Чтобы разобрать инцидент, в проде включили DEBUG для всего приложения и забыли выключить
- После добавления тега с идентификатором клиента Prometheus перестал справляться
- В Kibana невозможно отфильтровать логи по идентификатору заказа
- Профайлер показывает, что сервис тратит 15% процессора на отладочные логи при уровне INFO
- Трасса запроса обрывается на вызове сервиса доставки
- Эндпоинты Actuator сервиса оказались доступны из интернета
- p99 времени ответа на дашборде нельзя посчитать для всех подов вместе
- В логах асинхронной отправки уведомлений пропал идентификатор трассы
- Партнёрский API упал, и сервис полностью пропал из балансировки
