18.10.2024

Как подготовиться к system design интервью?

Бесплатное пошаговое руководство. Время чтения — 12 минут

ex-Team Lead в Яндекс

Владимир Балун

руководство для тех, кто:

  • готовится к собеседованию по System Design и хочет улучшить свои навыки в проектировании систем;
  • недавно провалил собеседование по проектированию большой системы;
  • посмотрел видео на YouTube по проектированию систем и ничего не понял;
  • давно работает и кому тяжело демонстрировать свои знания и навыки в условиях ограниченного времени на собеседовании.

Читай шаг за шагом или сразу переходи к интересующему разделу по якорной ссылке. Главное помни: это руководство не сделает тебя экспертом, но поможет подготовиться к собеседованию по System Design и чувствовать себя увереннее
Автор — ВЛАДИМИР БАЛУН, ex-team lead в яндекс
руководил разработкой системы трейсинга (11ГБ/с трафик)
Yandex
разрабатывал системы трейсинга и непрерывного профилирования
Ozon
разрабатывал движок по подбору таргетированной рекламы
Tinkoff
разрабатывал Kaspersky Endpoint Security
Kaspersky Lab
поддерживал ICQ и разрабатывал My Teams
Mail.ru
руководил курсом Golang Developer.Professional
OTUS
спикер конференций
CodeFest и Saint HighLoad++
Откроется после 6-ой главы
Содержание

1) Зачем нужно собеседование по System Design

Проектирование системы — один из этапов собеседования в процессе найма backend-разработчиков. Оно предназначено для проверки hard skills:

  • умеешь ли ты проектировать большие высоконагруженные системы;
  • сталкивался ли ты с этим на практике;
  • есть ли у тебя основополагающие знания в этой области;
  • есть ли у тебя понимание и знание системных требований, ограничений и узких мест.

Кроме того, собеседования по System Design (проектированию ИТ-систем) популярны у работодателей, потому что на них легко проверить твои навыки общения и оценить умение решать реальные задачи в условиях неопределенности.

Опытный разработчик может сказать:
«В мире много платных и бесплатных решений, из которых я могу собрать систему, как из деталей конструктора. Если мне нужна база данных, я возьму PostgreSQL и буду хранить свои данные в нем, а сервис реализую на популярном фреймворке для написания HTTP сервисов моего любимого языка программирования»
И это будет отличным решением, если ты собрался писать сервис для небольшой аудитории, но сервисы большой компании сложнее устроены и намного сильнее нагружены.

Если рассматривать Google, Яндекс, VK, Тинькофф и других, то у них все используемые решения очень быстро перестают помещаться на один сервер, а учитывая требования высокой доступности, обязательно располагаются в нескольких локациях. И, как только система становится распределенной, сложность ее архитектуры и реализации на порядок увеличивается. System Design собеседование проверяет твои навыки по проектированию и работе с подобными системами.

Многие боятся собеседований по System Design. Вопросы на них могут быть расплывчатыми и слишком общими.
Например: «Спроектируйте общеизвестный сервис X»
Отсутствие энтузиазма у кандидата вполне объяснимо. В конце концов, кому под силу в течение часа спроектировать популярный сервис, над которым работали сотни или тысячи инженеров?

Хорошая новость заключается в том, что от тебя этого никто не ждет, поскольку в проектировании ИТ-систем не существует единственно правильных решений, а реальные системы имеют чрезвычайно сложную архитектуру.

Например, поиск Яндекса только с виду выглядит просто. Количество технологий, стоящих за этой простотой, поистине потрясающее. Но если никто не ждет, что ты за час успеешь спроектировать настоящую систему, то какая польза от этого собеседования?

Собеседование по проектированию систем имитирует реальный процесс, в ходе которого пара коллег совместно работают над какой-то общей не совсем ясной задачей и находят подходящее решение. Задача носит общий характер, и идеального решения не существует. Важен сам процесс проектирования.

Это позволяет тебе продемонстрировать свои навыки инженера, обосновать выбор тех или иных архитектурных решений и конструктивно ответить на возникшие вопросы. Многие считают, что этот вид собеседования сводится к техническим навыкам проектирования кандидата, но это лишь малая его часть. Эффективное собеседование четко сигнализирует о способности кандидата работать совместно, выдерживать давление и конструктивно справляться с расплывчатыми задачами.

Представь себя на месте интервьюера и попробуй понять: что он пытается узнать во время собеседования по проектированию той или иной системы?

Интервьюер хочет увидеть, что ты:
  • корректно и просто выражаешь свои мысли
  • знаешь и понимаешь системные требования и ограничения
  • можешь отстаивать свои технические решения (как во время разговоров с коллегами на работе)
  • имеешь навыки и опыт проектирования больших высоконагруженных систем

Хороший интервьюер также ищет отрицательные признаки. Чрезмерно усложненные архитектурные решения — болезнь инженеров, которые восхищаются чистотой архитектуры и не желают идти на компромиссы. Они зачастую не догадываются о тех расходах, которые влекут за собой переусложненные системы, и многим компаниям это неведение дорого обходится. Эту склонность явно не стоит демонстрировать. Среди других нежелательных качеств можно выделить узкий кругозор и упрямство:)

2) кому предлагают пройти собеседование по System Design

Секция по System Design проводится только для backend-разработчиков

Для фронтендеров, мобильных разработчиков и ML-инженеров подобный тип собеседований слабо применим. У них есть свои собеседования на проектирование, которые применимы к их предметной области, поэтому эти специальности затрагивать не буду.

Важно понимать, что от компании к компании может все сильно различаться. Например, в Тинькофф и Яндексе собеседование по System Design мидлам раньше не давали. Обычно его проводили тем, кто претендует на роль сеньора и выше
В большинстве случаев, если тебе предлагают пройти интервью, ты претендуешь на позицию, как минимум, старшего специалиста

3) как пройти интервью по System Design (проектированию ИТ-систем)

Собеседование по System Design может быть абсолютно разным от компании к компании. Тебя могут ждать:

  • Проектирование популярного сервиса с нуля
  • Проектирование новой функциональности для существующего сервиса
  • Рассказ об архитектуре твоего проекта (тебе придется рассказать архитектуру с прошлого месте работа и подумать, что было сделано плохо, что можно улучшить и как). Если архитектура с прошлого места под NDA, то тебя могут попросить изобразить архитектуру мечты твоего прошлого проекта, учитывая все боли и проблемы
Часто тема System Design интервью оказывается связана с твоей предметной областью или предметной областью компании, в которую ты устраиваешься.

Например, если ты проходишь собеседование в команду, которая занимается разработкой баз данных, скорее всего, тебя попросят спроектировать именно ее. Потребуется выбрать общую архитектуру, а потом пройтись по всем компонентам или, наоборот, сосредоточиться на каком-то одном аспекте.
Обычно собеседование длится 45-60 минут. Все зависит от того, сколько времени ты потратишь до и после собеседования на различные вопросы и приветствие. По итогам собеседования выходит матрица оценки, где получается взвешенная оценка по каждому из этапов.

Пройти такое собеседование непросто, поскольку в проектировании ИТ-систем нет единственно верного решения. Каждое собеседование по проектированию архитектуры уникально и его можно пройти множеством различных способов.

Например, в собеседованиях по программированию (алгоритмам) какую-то задачу можно решить одним, двумя или максимум тремя способами, а спроектировать систему можно множеством различных.

Да, существуют типичные подходы к решению любой задачи system design, а также приемы при проектировании определенных видов систем, но даже в них можно много чего делать по-разному. Часто у кандидатов получаются абсолютно разные архитектуры систем.

Тем не менее, у всех собеседований по проектированию IT-систем есть общие черты. Рассмотрим основные этапы стандартного сценария, поскольку правильная стратегия и знания являются ключевыми факторами успешного прохождения интервью:

  • Сбор и формализация требований (5-10 минут)
  • Приблизительная оценка нагрузки (5 минут)
  • Проектирование API для будущей системы (5 минут)
  • Проектирование высокоуровневой архитектуры и модели данных (20-30 минут)
  • Обсуждение отказоустойчивости и масштабируемости архитектуры (5 минут)
  • Расчет необходимых ресурсов (железа) для будущей системы (5-10 минут — требуется не везде)
Не думай как программист, думай как технический руководитель.

Во время собеседования ты будешь выступать в роли технического руководителя, а интервьюер — в роли младшего инженера, который будет внедрять твой проект. У младших специалистов будет много вопросов, и ты как технический руководитель должен поощрять и даже предугадывать эти вопросы, т. е. вести интервьюера за руку во время проектирования системы

1. Собери и формализуй требования

Вероятно, ты сталкивался на работе с непонятными ТЗ и требованиями, которые приходилось формализовывать. Здесь так же. Интервьюер не ждет, что ты сразу же начнешь проектировать систему, потому что нельзя сделать то, не знаю что. Это проверка в том числе soft skills и тебе нужно начать диалог, чтобы выяснить, что именно предстоит проектировать

Представь, что тебя попросили разработать «сервис обмена фотографиями» с некоторыми минимально определенными возможностями. Можно сразу начать проектировать что-то вроде Instagram, исходя из предположения, что все изображения будут относительно небольшими, не будут рассматриваться подробно, и что приемлемо значительное сжатие для экономии памяти и пропускной способности. Но интервьюер не сказал ни слова о проектировании Instagram, а кроме него существует множество различных типов сервисов обмена фотографиями. Например, Flickr или 500px — сервисы для фотографов, чтобы демонстрировать работы в высоком разрешении.

В жизни решения, связанные с проектированием систем, часто происходят в условиях нехватки данных. Конечно, важны метрики проекта для его правильного развития и, конечно, аналитики и менеджеры продукта постараются обеспечить тебя наиболее полной информацией. Но и этого может быть мало.
Если вводных на собеседовании недостаточно, можно и нужно выдвигать обоснованные гипотезы на основе той информации, которая уже известна
Сначала тебе нужно определить функциональные требования, т.е. какие функции будут доступны пользователю. Например, будут ли в системе оповещения о пропущенных звонках или поиск товаров по названиям. Здесь очень важно задавать правильные вопросы и уточнять, что входит в задачу, чтобы не тратить время на неважные детали. В конце нужно сделать приоритизацию функциональных требований, чтобы на следующих этапах понимать, чему уделять больше внимания, а чему меньше.
Не трать много времени на сбор функциональных требований. Твоя задача — формализовать основную функциональность.

Не забудь, что для реального проекта сбор требований — один из важнейших этапов. Если на собеседовании тебе нужно сделать это быстро, то на работе собирать функциональные требования нужно очень внимательно
Вторым шагом нужно уточнить нефункциональные требования. Они определяют свойства системы или ограничения, которые не относятся к функциональности. Например, ее производительность и отказоустойчивость. В большинстве случаев хватает сбора следующих:

1) Количество пользователей
  • Вопрос:
    Какое количество пользователей (DAU / MAU) ожидается в будущем приложении, а также, как оно будет расти?
    Ответ:
    50 000 DAU
2) Поведение пользователей
  • Вопрос:
    Сколько в среднем один пользователь будет создавать запросов к будущему приложению в день?
    Ответ:
    Один пользователь в среднем будет делать 12 запросов в день к приложению
3) Регионы использования приложения
  • Вопрос:
    На аудиторию каких регионов/стран будет запущено будущее приложение?
    Ответ:
    Только на СНГ
4) Сезонности в приложении
  • Вопрос:
    Будут ли сезонности, когда приложением в определенный период будут пользоваться большое количество пользователей?
    Ответ:
    Да, сезоны осенних и предновогодних распродаж
5) Условия хранения данных
  • Вопрос:
    Данные храним всегда или можно удалять/агрегировать какие-либо данные спустя какое-либо время?
    Ответ:
    Храним всегда
6) Лимиты и ограничения
  • Вопрос:
    Если делаем подписки, то какое максимальное количество подписчиков может быть у пользователя?
    Ответ:
    1 000 000 подписчиков
7) Временные ограничения
  • Вопрос:
    За сколько письмо должно успевать доходить до адресата?
    Ответ:
    Не более, чем за 5 секунд
8) Доступность приложения
  • Вопрос:
    Сколько по времени приложение может быть недоступно за год?
    Ответ:
    Не более чем несколько часов простоя в год
В конце также определи сравнительную важность нефункциональных требований между собой. Так ты поймешь, чему уделять больше внимания, а чему меньше.

2. Приблизительно оцени нагрузку

После формализации требований выдели пару-тройку основных функций системы и посчитай для них примерную нагрузку. Здесь очень важно слово примерную — не нужно считать все до битиков и байтиков, смело все округляй.

Твоя задача — понять порядок и характер нагрузки, а потом рассказать об этом интервьюеру. В контексте нагрузки, чаще всего требуется:

  • приблизительно подсчитать количество запросов в секунду (RPS)
  • оценить входящий и исходящий трафик
  • подсчитать количество одновременных соединений (CCU) и объем хранимых данных (считается не во всех случаях).
Это очень важно делать, потому что архитектура системы для 100 RPS и 100 000 RPS будет сильно отличаться.
Нагрузка позволит увидеть ограничения или определить функции, которые будет дорого реализовать. Когда такие функции появятся, обсуди с интервьюером необходимость убрать их в целях экономии.

Хорошо, если ты будешь говорить о разных деталях и ограничениях, которые знаешь. Самое главное — делать это коротко и по делу, чтобы не тратить много времени. Так интервьюер сможет понять, что у тебя был с этим опыт работы.

Также, благодаря расчету нагрузки, ты поймешь, чем нагружено приложение (compute/data/network intensive), либо какие операции в нем будут преобладать. Это тоже нужно проговаривать интервьюеру и учитывать в будущей архитектуре.
Например, будут ли в системе преобладать операции чтения или записи

3. Спроектируй API для будущей системы

Когда готовы требования к системе, нужно понять, как она будет взаимодействовать с внешним миром и обрабатывать данные. То есть для формализованных функциональных требований нужно описать API.

Чаще всего достаточно выбрать подход: REST, SOAP, GraphQL или что-то другое, чтобы затем описать контракты псевдокодом. Например, так:
- ListMessages(chatId, offset, limit)
- CreateMessage(chatId, createdAt, data)
- UpdateMessage(messageId, data)
- ...
Уточни насколько подробно необходимо расписывать API. Иногда тебе нужно будет подробно расписывать, например, REST API.

На этом этапе ты можешь выписать основные сущности системы, которые потребуются при проектировании модели данных.

4. Спроектируй высокоуровневую архитектуру и модель данных

Наконец, можно переходить к проектированию архитектуры. Да, у тебя осталось мало времени, чтобы спроектировать какую-то большую систему, но не отчаивайся.
Представь, что на дворе 1999 год и ты с друзьями надеешься сделать что-то из того, к чему мы имеем доступ сегодня. Твоя задача — спроектировать архитектуру, чтобы друзья написали код.

Проблема в том, что минимально жизнеспособный продукт должен быть готов к завтрашнему дню. А значит, нет времени на подготовку и нет необходимости беспокоиться о тонкостях архитектуры системы, которую вы не знаете. Просто ответь на вопрос: «как спроектировать систему, чтобы друзья могли написать ее код сегодня, прямо сейчас?»

Она не должна быть красивой. Она не должна быть сложной. Она не должна никого впечатлять. Она просто должна быть сделана.
Итак, твоя задача — абстрактно описать основные компоненты, не уделяя большого внимания деталям на начальном этапе проектирования. И только когда ты получишь представление обо всей архитектуре, можно углубиться в отдельные компоненты, технологии, модель хранения данных и прочее.
Намного лучше готовая абстрактная архитектура без детальной проработки, чем неготовая архитектура будущего проекта с хорошо проработанным отдельным компонентом
Чаще всего ты будешь проектировать архитектуру для большого числа пользователей с высокой нагрузкой. Как правило, в такой ситуации останавливаются на микросервисной архитектуре, потому что на большие объемах она дает больше преимуществ по сравнению с монолитной.

В большинстве случаев, если ты спроектируешь архитектуру из картинки ниже, собеседование по System Design ты не пройдешь:
Обычно интервьюеры ждут примерно такую схему архитектуры:
Важно сделать ее максимально простой и понятной. Не превращай архитектуру в паутину — она должна легко читаться и эволюционировать в случае необходимости. Следи за тем, насколько удобно и просто сопровождать и эксплуатировать твою систему
Например, как ты планируешь обновлять компоненты системы или хранилища, как будешь наблюдать за системой и т. д.
Построив верхнеуровневую схему, можно начинать добавлять в нее детали. Например, если в системе предполагается использование хранилища, то чаще всего нужно рассказать:
  • что это будет за база данных;
  • где будут храниться данные (в оперативной памяти или на диске);
  • а еще аргументировать, почему ты выбираешь именно эта базу данных, а не другую (иногда не требуется указывать определенные технологии, об этом тоже нужно спрашивать).

Затем нужно описать концептуальную модель данных хранимых в данной базе данных. Например так:
message:
- id
- author_id
- chat_id
- created_at
- data
- ...
Во время проектирования системы выделяй как можно больше времени на компоненты, которые отвечают за самые важные требования. А остальные описывай по остаточному принципу.
Не забывай периодически возвращаться к формализованным требованиям и проверять, все ли отражено в твоей архитектуре
Помимо happy path системы нужно обсудить различные corner case и exceptional flow. Например: что будет, если пользователь забудет оплатить заказ? Что будет, если у него закончатся деньги на счету?

Часто во время проектирования ты будешь сталкиваться с ситуацией, когда у тебя не будет однозначного ответа на вопрос. Это нормальное явление: при проектировании часто появляется такое слово как компромисс. Когда нет однозначного ответа, нужно взвешивать плюсы и минусы различных подходов, чтобы потом выбрать окончательное решение.

Тебе не нужно демонстрировать глубокую экспертизу в какой-либо предметной области. Интервьюеры хотят видеть, что у тебя есть широкое базовое понимание основ проектирования систем, то есть твой кругозор.

Как правило, тебе не нужно знать, как работают внутренние компоненты любого типа базы данных на каком-то внутреннем уровне, однако тебя все равно могут попросить спроектировать эти внутренние компоненты!
Например, базу данных/движок запросов SQL
В этом случае интервьюеру не важно, знаком ли ты с академической литературой по движкам запросов и сколько времени потратил на работу над внутренними компонентами базы данных. Ему интересно, как ты подойдешь к решению проблемы, основываясь на своих знаниях. Скорее всего, твой ответ не будет оптимальным, но это нормально! Интервьюер сосредоточится на процессе, а не на результате.

Отдельно хочу добавить, что не существует «правильного» способа проектирования системы. Если бы два эксперта проектировали одну и ту же систему, мы бы увидели два разных проекта, каждый из которых красив и эстетичен по-своему, и оба они были бы «правильны» относительно друг друга.

При проектировании системы легко сосредоточиться на технических деталях, но компьютерные системы обслуживают людей. Именно поэтому твоя задача — привязывать свои технические решения к пользовательскому опыту, который они обеспечивают.

Представим, что ты разрабатываешь сервис обмена изображениями, и перед загрузкой изображения он требует от пользователя входа в систему. С технической точки зрения, можно отказаться от входа в систему, чтобы упростить логику приложения, но очень важно обсудить возможные подходы и их последствия для пользовательского опыта с интервьюером, прежде чем принимать решение.
Ты никогда не ошибешься, если сделаешь конечного пользователя движущей силой своей архитектуры

5. Расскажи про отказоустойчивость и масштабируемость архитектуры

На этом этапе тебе нужно самостоятельно шатать и ломать свою архитектуру. Критически оцени каждый узел и канал связи системы, а потом расскажи, что произойдет, если они выйдут из строя.
Отдельное внимание следует уделить отказоустойчивости stateless и statefull компонентов архитектуры. Например, если будет использоваться репликация, то какая именно.
Подробно расскажи, как твоя система будет переживать отказы или чем будет жертвовать во время отказов. Помимо отказов отдельных компонентов продуймай, что будет происходить во время отказа ДЦ.

Уточни у интервьюера, будем ли мы решать эту проблему или нет. Например, потому что это слишком дорого. Отказоустойчивость системы можно проговаривать устно или отображать, как на схеме ниже:
После отказоустойчивости следует поговорить о масштабируемости системы, потому что бессмысленно вводить в эксплуатацию систему, которая не сможет расти и развиваться с ростом нагрузки. Тебе нужно оценить, сможет ли твоя архитектура в будущем выдержать x2, x5 или x10 нагрузки, и если да, то как именно.
Отдельное внимание удели масштабированию stateless и statefull компонентов. Например, если будет использоваться шардирование, то как именно данные будут разноситься по шардам
Обычно масштабируемость системы проговаривается устно и не указывается на схеме.

6. Рассчитай необходимые ресурсы

Теперь ты можешь перейти к оценке вычислительных ресурсов. Пройдись по основным компонентам системы и оцени, какие ресурсы им потребуются.
Это требуется не на всех собеседованиях, поэтому об этом лучше спросить заранее
Если компонент предполагает интенсивные вычисления или обработку большого объема данных, необходимо оценить:

  • затраты процессорного времени на выполнение алгоритмов;
  • объемы оперативной памяти;
  • дисковое пространство;
  • пропускную способности сети;
  • будет ли система располагаться в одном датацентре или нескольких;
  • будет ли использоваться CDN и т.д.
У тебя не хватит времени оценить ресурсы для всех компонентов системы. Поэтому выбери те, что будут создавать большую часть нагрузки.
Тут нужно вспомнить latency numbers every programmer should know, а также ограничения различных железяк, потому что может оказаться, что вычислительных возможностей современных серверов будет недостаточно для выполнения каких-либо операций. Будет большим плюсом, если во время расчета ты учтешь финансовый вопрос и предложишь варианты, как это можно сделать выгоднее для компании.

Эта часть собеседования показательно отразится на грейде. Пока ты делаешь расчет, интервьюер оценит множество важных деталей. Например:
  • знаешь ли ты, что доступно только около 85% емкости дисков и почему это так;
  • умножал ли ты число дисков на фактор репликации;
  • учел ли ты бэкапы и многое другое.

4) типичные ошибки при прохождении system design интервью

1. Некорректный или медленный расчет

Старайся не допускать ошибок в расчетах, но и не трать время на точный расчет вплоть до битиков и байтиков. Твоя задача — определить порядок нагрузки и ее характер, чтобы понять, насколько это будет дорого и не упрешься ли ты в какой-то лимит или ограничение при проектировании. Поэтому смело делай приблизительный расчет «на коленке», который не будет занимать много времени.

2. Отсутствие самостоятельности

Очень важно лидировать процесс и уверенно проектировать систему. Чем самостоятельнее ты будешь во время собеседования, тем лучше. Если ты чего-то не знаешь — не стесняйся выдвигать гипотезы и предположения. Это лучше, чем сразу же идти просить о помощи.

3. Попытка сделать все и сразу

Некоторые кандидаты в дополнение к основной функциональности проектируют еще аутентификацию, авторизацию и прочие штуки. Действительно есть системы, где аутентификации и авторизации уделяется много внимания, но, в большинстве случаев этим пренебрегают, чтобы уделить больше времени и внимания основной функциональности. Так что советую уточнять “Будем ли мы проектировать аутентификацию и прочее или это остается за скобками?”

Регистрация занимает <1 минуты

Зарегистрируйся на платформе, чтобы продолжить

Задачи, которые встречаются чаще всего + материалы для подготовки

16 типичных ошибок и советы по подготовке

После регистрации откроются:

2 урока по System Design: теория партиционирования и шардирования

Следующий урок
Партиционирование: виды и способы + сценарии использования

теория шардирования

Шардирование, способы шардирования и перебалансировка