В этой подборке вопросы сгруппированы по формату «System Design», чтобы подготовку можно было вести от базовых тем к практическим задачам. В подборке чаще встречаются темы: backend, api, database.
Опишите поток: изменения фиксируются в основной БД, событие поступает в Kafka, consumer обновляет или инвалидирует Redis. Redis здесь ускоряет чтение, а Kafka доставляет изменения.
Transactional Outbox сохраняет бизнес-изменение и событие в одной транзакции БД. Отдельный отправитель читает outbox и доставляет события в брокер, устраняя разрыв между commit и публикацией.
Docker-контейнеры меняют упаковку и запуск, но не превращают монолит в микросервисы. Нужны осмысленные границы ответственности, контрактов, данных и независимого выпуска.
Версионируйте внешний контракт, оставляя общую бизнес-логику в сервисах. URL /v1, специальный заголовок или media type в Accept должны выбирать адаптер входа и представление ответа.
Ограничьте размер загрузки и суммарные квоты, пишите во временный файл и контролируйте доступное место. Предварительная проверка свободного диска полезна, но не защищает от параллельных загрузок.
Представьте статусы как конечный автомат с явно разрешёнными переходами. Сервис должен атомарно проверять текущий статус, применять переход и записывать историю.
Уточните, кто платит комиссию, от какой суммы она считается, как округляется и что происходит при возврате. Технически комиссию и перевод нужно учитывать как согласованные записи операции.
Старая версия падает, если миграция уже удалила или переименовала используемый ею столбец. Откат кода не откатывает совместимость схемы; применяют expand–migrate–contract.
Если актуальность отчёта зависит от изменений данных, используйте событийную инвалидацию или версию исходных данных, а TTL оставьте страховкой. Частоту обновления определяет допустимая устарелость.
Для произвольных квот нужны сохраняемые между циклами кредиты или виртуальное время. Независимое округление долей каждого цикла может навсегда лишить маленькую очередь обслуживания.
Спроектируйте поле телефона как расширение профиля: ввод и ошибки в UI, чтение и PATCH на backend, nullable строка в БД. Проверка владения профилем обязательна.
Базовая схема — adjacency list с parent_id и сохранённой глубиной depth. Индекс по depth позволяет быстро выбирать один уровень, но перенос поддерева требует обновить глубины потомков.