С какими основными техническими проблемами вы столкнулись на последнем проекте?

«С какими основными техническими проблемами вы столкнулись на последнем проекте?» — вопрос из категории Софт-скиллы, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый пример ответа, который можно адаптировать под свой опыт.

Ответ

Основные проблемы были связаны с масштабированием и производительностью высоконагруженного сервиса:

  1. Бутылочное горлышко в базе данных (PostgreSQL):

    • Проблема: Высокий RPS (Requests Per Second) приводил к блокировкам (locks) при конкурентных UPSERT-операциях.
    • Решение: Внедрили шардинг по ключу клиента, добавили частичные индексы и пересмотрели уровень изоляции транзакций.
  2. Проблемы с кэшированием (Redis):

    • Проблема: Один инстанс Redis не справлялся с нагрузкой, возникали таймауты.
    • Решение: Перешли на Redis Cluster и добавили двухуровневое кэширование: Redis (распределенный) + Caffeine (in-memory, локальный для каждого экземпляра приложения).
  3. Проблема N+1 в ORM (Hibernate):

    • Проблема: Некоторые API-эндпоинты генерировали десятки запросов к БД из-за ленивой загрузки связанных сущностей.
    • Решение: Использовали JOIN FETCH в JPQL и @EntityGraph для eager-загрузки только необходимых данных за один запрос.

Пример оптимизации запроса N+1:

// БЫЛО: При получении списка пользователей для каждого отдельно выполнялся запрос за его заказами.
@Query("SELECT u FROM User u WHERE u.department = :dept")
List<User> findUsersByDepartment(String dept); // N+1 запрос!

// СТАЛО: Все данные загружаются за один запрос.
@Query("SELECT DISTINCT u FROM User u LEFT JOIN FETCH u.orders WHERE u.department = :dept")
List<User> findUsersByDepartmentWithOrders(String dept); // 1 запрос!
  1. Долгие сборки в CI/CD: Решили переходом на Gradle с использованием конфигурационного кэша и репозитория для зависимостей (Nexus).