System design отделяет «могу закрыть тикет» от «могу спроектировать кусок системы и назвать цену решения». Код здесь почти не пишут. Смотрят, умеете ли вы уточнить требования, оценить масштаб, выбрать хранилище и очередь не из моды, а из паттерна доступа, и вовремя сказать, где система сломается. Правильного ответа как у задачи на сумму массива нет. Есть ход мысли, который можно обсуждать.
Ниже — кому это вообще светит, универсальный каркас, два прохода на классических постановках (сокращатель ссылок и сервис уведомлений) и как готовиться с нуля за несколько недель, не заучивая чужие схемы из блога. Соседние этапы: интервью backend и live coding. Общий каркас вопросов — вопросы на собеседовании.
Коротко:
- Не рисуйте коробки, пока не зафиксировали функциональные и нефункциональные требования и порядок цифр по нагрузке.
- Каркас один: требования → масштаб → API → данные → схема → одно узкое место глубоко → отказ.
- Молчание хуже простой схемы. Компромисс надо назвать вслух: цена кэша, цена очереди, цена шарда.
- Junior видит упрощённый вариант. Middle+ и платформа — почти всегда. Смотрите слоты в backend и senior.
- Готовьте 8–10 задач одним каркасом, а не 40 картинок из интернета.
Что проверяют на самом деле
Умение не угадать «эталонную архитектуру Twitter», а вести разговор: что важно продукту, сколько примерно пишут и читают, где можно быть неточным, где нельзя потерять запись. Интервьюер часто сам сужает задачу. Если вы уже нарисовали Kafka, Kubernetes и пять баз, а нагрузка — сотни запросов в минуту, вы провалили калибровку, не «недостаточно энтерпрайза».
Коммуникация здесь часть оценки. То же правило, что на behavioral: ясный вклад, граница, урок. Только объект — система, не конфликт. Самопрезентацию на design-раунд не тратьте — её уже слышали. Рассказ о себе оставьте скринингу.
Кому и в каком виде это встречается
Backend, fullstack, платформенные инженеры middle+, техлиды — почти всегда. Junior — реже и короче: «нарисуйте API и таблицу для объявлений». Если в вакансии нет слова design, навык всё равно всплывает в «как устроен ваш сервис». Тогда готовьте свою схему, не shorten URL на память.
Международный слот часто ведёт этот раунд на английском. Каркас тот же, слова — из интервью на английском. Не переключайтесь на русский «потому что так быстрее думать», если процесс заявлен как English.
Универсальный каркас ответа
- Требования. Что система должна делать. Что сознательно не делает в этой версии. Нефункциональное: задержка, доступность, консистентность, срок хранения, регуляторика, если всплыла.
- Масштаб. Порядок пользователей, RPS чтения и записи, размер объекта, рост за год. Не точная бухгалтерия — порядок, от которого зависит, нужна ли очередь и шард.
- API. Два-четыре метода. Контракт фиксирует границы лучше, чем облако из сервисов.
- Данные. Что ключ, какие запросы, TTL. Реляционка, ключ-значение, очередь, файловое хранилище — под доступ, не под резюме.
- Схема. Клиент, шлюз, сервис, база, кэш, очередь, воркер. Один путь счастливый, один путь отказа.
- Глубокое место. Одно на выбор интервьюера или ваше: шарды, кэш и его враньё, идемпотентность, фан-аут ленты, ретраи.
- Узкие места. Что умрёт первым при x10. Что мониторите. Как деградируете.
Не пропускайте пункт 1 из желания «уже показать уровень». Большинство провалов — решение не той системы.
Цифры масштаба можно и нужно брать как гипотезу. Скажите: «считаем миллион активных в день, чтение к записи 100 к 1, объект ссылки мелкий — если порядок другой, схема сдвинется вот здесь». Интервьюер поправит. Молчаливое рисование «как в статье» без порядка величины почти всегда приводит к лишней очереди и лишнему шарду. Если цифр совсем нет, предложите две ветки: малая нагрузка — одна база и кэш; большая — вот что добавим первым.
Строительные блоки, без которых каркас пустой
Балансировщик и несколько инстансов приложения. Репликация чтения. Шард, когда один узел больше не держит данные или запись. Кэш: что ключ, кто инвалидирует, что будет, если кэш соврал. Очередь: зачем (пик, повтор, развязка HTTP), цена (задержка, порядок, poison). Идемпотентность ключом. Таймаут и повтор. Идемпотентный консьюмер. «Доступность против строгой согласованности» — одной фразой на вашем кейсе, не лекцией про CAP на доске.
Этого набора хватает на большинство учебных задач. Не добавляйте сервис «просто чтобы был». Каждая коробка должна отвечать на вопрос из требований.
Проход 1. Сокращатель ссылок — каркас, не эталон из блога
Постановка: «спроектируйте сервис коротких ссылок». Не копируйте чужую картинку. Пройдите каркас вслух.
Сначала зафиксирую: пользователь даёт длинный URL, получает короткий код, по коду редирект. Нужны ли свои домены, аналитика кликов, срок жизни, кастомный алиас, авторизация — спрошу. Для версии на интервью предложу: анонимное создание, редирект, опциональный TTL, без полной аналитики в первой версии, если не попросите.
Масштаб: чтение сильно больше записи. Если цифр нет, проверю порядок: миллионы редиректов в день против тысяч созданий — тогда кэш горячих кодов и простая база на запись. Если запись тоже огромная — отдельно ключи и шарды.
API: POST /links {url, ttl?} → {code}; GET /{code} → 302. Идемпотентность создания не критична, коллизии кода — да: генерируем, пишем уникальный индекс, при конфликте ещё попытка.
Данные: ключ code, поля url, expires_at, created_at. Хранилище ключ-значение или таблица с PK по code. Кэш редиректа с TTL короче, чем у ссылки. Узкое место — генерация короткого кода и горячие ключи. Не тащу очередь в создание ссылки, пока не доказали, что синхронной записи не хватает. Не рисую микросервис аналитики, если клики не требовали.
Дальше интервьюер почти наверняка спросит: как генерировать код, как не столкнуться, что если кэш отстал от удаления ссылки. Отвечайте компромиссом: «кэш может отдать старое до TTL — для редиректа часто приемлемо; если ссылку отозвали по безопасности, инвалидируем явно и режем TTL». Это и есть раунд.