Системный дизайн
Секция системного дизайна устроена не так, как остальные. Здесь нет одного правильного ответа — есть правильный ход рассуждений. Интервьюер смотрит не на то, назвали ли вы Kafka, а на то, вывели ли вы потребность в очереди из чисел, которые сами же и посчитали. Поэтому вся тема держится на одном навыке — уметь превратить размытое «спроектируйте ленту новостей» в набор конкретных ограничений и уже из этих ограничений вывести архитектуру. Кандидат, начинающий с технологий, проектирует в вакууме, и это видно с первой минуты.
Python здесь не даёт поблажек, а местами добавляет собственных ловушек. GIL означает, что один процесс занимает одно ядро, поэтому «горизонтальное масштабирование» начинается уже внутри одной машины — gunicorn с восемью воркерами это восемь независимых процессов, и любой модульный кеш, счётчик или планировщик существует в восьми экземплярах, а не в одном. Дальше идут те же ловушки, что и в любом другом языке — сессия в локальной памяти, ключ шардирования с горячей точкой, повторная доставка после падения воркера, вызов RPC без таймаута и метрика с user_id в метке. Слои ниже разбирают каждый механизм отдельно и идут в том порядке, в каком их применяют на реальном интервью.
Карта темы
- Процесс дизайн-интервью — пять шагов от уточнения требований до узких мест и почему технологии называют последними.
- Оценка нагрузки на салфетке — как из дневных чисел вывести
RPS, объём хранения и полосу, и зачем множитель пика. - Вертикальное и горизонтальное масштабирование — потолок одной машины, требование отсутствия состояния и лестница приёмов до миллиарда пользователей.
- Шардирование и ключ шардирования — разбиение данных против репликации, проблема перешардирования и консистентное хеширование.
- Очереди сообщений и гарантии доставки — развязка производителя и потребителя, at-least-once, идемпотентность и dead-letter.
- RPC — вызов процедуры через сеть — стабы, сериализация, дырявая абстракция «как локальный вызов» и обязательный таймаут.
- gRPC поверх HTTP/2 и protobuf — мультиплексирование, бинарная схема с номерами полей, четыре режима потоков и когда gRPC вреден.
- Наблюдаемость — метрики, логи, трейсы — три столпа, кардинальность меток и что на самом деле значат SLI и SLO.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
Назвать Redis, Kafka и Nginx до выяснения требований | Дизайн подгоняется под стек, а не под задачу; компромиссы не обоснованы числами |
Взять дневное число запросов за RPS или считать только средний трафик | Ошибка в 86 400 раз; а ёмкость по среднему не переживает час пик, где нагрузка выше на порядок |
Ждать, что load balancer сам масштабирует сервис с состоянием | Сессия в памяти узла теряется при его падении, а «липкие» сессии перекашивают нагрузку |
Путать sharding с репликацией | Репликация копирует данные целиком и масштабирует чтение; шардирование разбивает их и масштабирует и запись, и объём |
| Выбрать ключ шардирования по удобству, а не по распределению | Горячий шард принимает почти весь трафик, а частые запросы превращаются в перебор всех шардов |
| Рассчитывать на exactly-once доставку от брокера | Практическая гарантия — at-least-once; без ключа идемпотентности повтор спишет деньги дважды |
| Вызвать удалённую процедуру без таймаута | Зависший сервер удерживает воркеры вызывающей стороны, и отказ каскадом идёт вверх по цепочке |
Положить user_id в метку метрики | Взрыв кардинальности — миллионы временных рядов кладут базу метрик раньше, чем упадёт само приложение |
Значение для собеседований
Проверяют прежде всего дисциплину процесса. Junior-вопросы звучат как «какие шаги структурируют дизайн-интервью» и «что такое очередь сообщений» — здесь достаточно назвать порядок (требования, оценка, API, схема, детализация с компромиссами) и не броситься сразу писать код. На middle-уровне спрашивают то, что проверяется числами и определениями — вертикальное против горизонтального, шардирование против репликации, из чего складывается оценка нагрузки, что такое gRPC и на чём он построен. Ответ «горизонтальное масштабирование ускоряет каждый запрос» проваливает вопрос сразу — узлы поднимают пропускную способность, а не задержку одного запроса.
Senior-уровень отличается тем, что от вас ждут порядок применения приёмов, а не их список. Правильная лестница — сначала сервисы без состояния за балансировщиком, потом кеш и CDN, потом реплики на чтение, очередь и лимиты, и только когда всё это исчерпано — шардирование и несколько регионов. Кандидат, начинающий с шардирования, платит максимальную цену за самый ранний ход. Отдельно любят два уточняющих вопроса — «почему сервис обязан быть без состояния» и «чем метрики отличаются от логов и трейсов»; оба отсекают тех, кто выучил слова, но не разбирал инцидент руками.