что такое system design interview
Netflix за 45 минут: Краткий рассказ о system design-интервью, чего ожидать + подборка полезных ссылок
В нашем блоге мы много пишем о построении карьеры в ИТ в разных странах, поиске работы, отличиях в процессе собеседований крупных компаний. В сегодняшней статье мы пойдем дальше и раскроем тему так называемых интервью по system design – это один из этапов собеседований известных технологических компаний, на котором отсеиваются многие кандидаты.
Итак, что такое system design и как пройти интервью такого типа?
Что это такое
В современном мире ИТ-системы стали крайне сложными. Каждая новая «фича» в продукте должна соответствовать множеству требований, всегда есть ограничения, между которыми приходится балансировать инженерам. То, что для обычного пользователя выглядит супер-просто – как например, отправка поискового запроса через Google или Яндекс – на самом деле несет в себе огромный уровень сложности.
Отличие интервью по проектированию систем от обычных технических собеседований в том, что здесь от кандидата ждут не четких ответов на вопросы по структурам данных и алгоритмам. Как правило задачи на этом этапе таковы, что для них не существует однозначно верного или неверного решения, они провоцируют мыслительный процесс – именно в нем и раскрывается кандидат.
Грубо говоря, интервью по system design – это что-то типа сессии мозгового штурма, где человек мыслит вслух, перебирает возможные решения и анализирует недостатки каждого из них в режиме реального времени. В этом трудность, но и главный плюс – мыслительный процесс здесь важнее результата. Как правило, такие интервью проводят крупные компании, разрабатывающие масштабные системы (FAANG и подобные).
Как же проходить интервью по проектированию систем? Ниже – несколько практических советов.
Чтобы попасть на интервью в компании, где инженеры действительно проектируют масштабные системы, используйте бота @g-jobbot. Это сервис, который найдет и бесплатно пришлет вам прямо в Telegram вакансии, которые подходят вам лучше всего – в том числе удаленная работа, в том числе с релокацией.
Самое важное – четко разобраться с задачей
Поскольку в интервью по system design самое важное – это то, как вы решаете задачу, крайне важно на самом первом этапе четко ее для себя уяснить. Бывший инженер Microsoft и Facebook в своей статье на практическом примере показывает важность этого факта.
Обычно задача звучит примерно как «Как бы вы спроектировали Netflix за 45 минут?» На первый взгляд, такие вопросы – полный бред. Подобные масштабные системы проектируют и реализуют сотни и тысячи инженеров на протяжение многих лет. Сорока пяти минут будет недостаточно даже чтобы начать обсуждать хоть один из компонентов такого продукта!
Как раз здесь очень важно понимание задачи. Нужно понять, чего хочет интервьюер. А он очевидно хочет, чтобы ему:
На каких-то из этих компонентов можно остановиться чуть подробнее – вам укажут на это, или нужно будет спросить. Обычно на интервью по проектированию систем даже код писать не нужно, а если вы сразу углубитесь в технические дебри, без того, чтобы сначала обсудить всю систему в целом – это будет минусом.
Задавайте уточняющие вопросы
Главная цель интервью по проектированию систем – дать кандидату возможность продемонстрировать свои знания и опыт. Как уже было сказано выше, нет правильных и неправильных ответов. Гораздо важнее не решить задачу как таковую – тем более, что это может быть просто невозможно за отведенное время – а показать свой мыслительный процесс во всей красе.
Поэтому крайне важно задавать вопросы, даже если вдруг получилось так, что вы четко знаете ответ на поставленный вопрос. В такой ситуации не нужно просто писать решение задачи, это противоречит целям интервью. Нужно забыть известное решение, и начать искать новое, по ходу дела задавая вопросы.
Это позволит интервьюеру понять сразу несколько вещей:
Вопросы могут быть такими:
Информации стало заметно больше, теперь уже можно думать о решении такой уточненной задачи.
Не пытайтесь произвести впечатление
Частая ошибка на интервью по проектированию систем – многие кандидаты думают, что раз на этом этапе нужно работать на уровне абстракции, то достаточно будет накидать в ходе разговора крутых терминов и названий модных технологий, чтобы сойти за эксперта. Так это не работает.
Во-первых, на интервью по системному дизайну наверняка будет не просто рекрутер, а инженер, который ищет человека себе в команду. Такому человеку недостаточно просто услышать слова вроде No-SQL, Mongo DB и Hadoop. Он явно начнет задавать уточняющие вопросы, и если у вас на самом деле нет особого опыта в работе с упоминаемыми технологиями, это все очень быстро станет ясно.
Будьте честными
Интервью по проектированию систем – это как раз тот случай, когда не страшно чего-то не знать наверняка. Поэтому ответы вида «Я с этой конкретной технологией никогда не работал, но знаю, что ее часто используют для решения подобных задач» – это хороший вариант. Помимо честности, здесь кандидат показал определенные знания и дал интервьюеру понять, с чего он начнет решение задачи (попробует известное решение, если не получится, будет «копать» дальше).
Помимо этого, не стоит выдавать свое решение за идеальное и не содержащее никаких минусов. Ограничения есть всегда, и опытный инженер-интервьюер это понимает как никто другой. Поэтому в ходе интервью стоит честно говорить о том, что в решение есть такие и такие узкие места, но их можно попробовать обойти таким и таким способом, использовать дополнительные инструменты или провести еще больше исследований.
Так станет понятно, что кандидат не просто придумывает решение и затем жестко пытается его продавить, но может быть гибким, вносить корректировки, и вообще адекватен и понимает, что всегда можно сделать лучше.
Вот прекрасный вымышленный диалог на интервью по проектированию систем, который показывает, как НЕ надо делать:
Интервьюер: Давайте сделаем свой Twitter. Как вы будете хранить твиты?
Кандидат: Я использую NoSQL-базу MongoDB.
Интервьюер: Почему не MySQL?
Кандидат: СУБД не масштабируются. Для нашей задачи точно понадобится MongoDB или BigTable.
Интервьюер: Но мы тут в Twitter храним все твиты в MySQL, все нормально масштабируется.
Кандидат: Ну, тогда, возможно, у вас просто еще пока недостаточно большой объем. По-настоящему огромные системы типа Facebook используют NO-SQL.
Интервьюер: Но Facebook также использует MySQL.
Кандидат: Хм, не знаю, как они его масштабируют, надо разобраться. Возможно, у них MySQL только на фронтенде, а на бэке BigTable.
Интервьюер: Неважно. А где будем хранить аналитические данные?
Кандидат: Очевидно, что в MySQL.
Интервьюер: Но не слишком ли их много для MySQL? Сейчас у нас для этого HDFS.
Кандидат: Похоже, что вы начали разрабатывать Twitter еще до того, как MongoDB достаточно развился. MongoDB может легко вместить и твиты и аналитические данные.
Интервьюер: Супер, спасибо за ваше время. Было приятно пообщаться.
Как подготовиться к интервью: полезные ссылки
Несмотря на то, что проектирование систем – один из наиболее нечетких этапов интервью, к нему можно подготовиться. В помощь кандидатам мы собрали список полезных материалов:
Что еще почитать
Чтобы попасть на интервью в компании, где инженеры действительно проектируют масштабные системы, используйте бота @g-jobbot. Это сервис, который найдет и бесплатно пришлет вам прямо в Telegram вакансии, которые подходят вам лучше всего – в том числе удаленная работа, в том числе с релокацией.
«Netflix за 45 минут»: что ждать на system design-интервью + подборка полезных ссылок
Интервью по system design – это один из этапов собеседований известных технологических компаний, на котором отсеиваются многие кандидаты. Итак, что это такое и как пройти интервью такого типа?
В современном мире ИТ-системы стали крайне сложными. Каждая новая «фича» в продукте должна соответствовать множеству требований, всегда есть ограничения, между которыми приходится балансировать инженерам. То, что для обычного пользователя выглядит супер-просто – как например, отправка поискового запроса через Google или Яндекс – на самом деле несет в себе огромный уровень сложности.
Отличие интервью по проектированию систем от обычных технических собеседований в том, что здесь от кандидата ждут не четких ответов на вопросы по структурам данных и алгоритмам. Как правило задачи на этом этапе таковы, что для них не существует однозначно верного или неверного решения, они провоцируют мыслительный процесс – именно в нем и раскрывается кандидат.
Грубо говоря, интервью по system design – это что-то типа сессии мозгового штурма, где человек мыслит вслух, перебирает возможные решения и анализирует недостатки каждого из них в режиме реального времени. В этом трудность, но и главный плюс – мыслительный процесс здесь важнее результата. Как правило, такие интервью проводят крупные компании, разрабатывающие масштабные системы (FAANG и подобные).
Как же проходить интервью по проектированию систем? Ниже – несколько практических советов.
Поскольку в интервью по system design самое важное – это то, как вы решаете задачу, крайне важно на самом первом этапе четко ее для себя уяснить. Бывший инженер Microsoft и Facebook в своей статье на практическом примере показывает важность этого факта.
Обычно задача звучит примерно как «Как бы вы спроектировали Netflix за 45 минут?» На первый взгляд, такие вопросы – полный бред. Подобные масштабные системы проектируют и реализуют сотни и тысячи инженеров на протяжение многих лет. Сорока пяти минут будет недостаточно даже чтобы начать обсуждать хоть один из компонентов такого продукта!
Как раз здесь очень важно понимание задачи. Нужно понять, чего хочет интервьюер. А он очевидно хочет, чтобы ему:
На каких-то из этих компонентов можно остановиться чуть подробнее – вам укажут на это, или нужно будет спросить. Обычно на интервью по проектированию систем даже код писать не нужно, а если вы сразу углубитесь в технические дебри, без того, чтобы сначала обсудить всю систему в целом – это будет минусом.
Главная цель интервью по проектированию систем – дать кандидату возможность продемонстрировать свои знания и опыт. Как уже было сказано выше, нет правильных и неправильных ответов. Гораздо важнее не решить задачу как таковую – тем более, что это может быть просто невозможно за отведенное время – а показать свой мыслительный процесс во всей красе.
Поэтому крайне важно задавать вопросы, даже если вдруг получилось так, что вы четко знаете ответ на поставленный вопрос. В такой ситуации не нужно просто писать решение задачи, это противоречит целям интервью. Нужно забыть известное решение, и начать искать новое, по ходу дела задавая вопросы.
Это позволит интервьюеру понять сразу несколько вещей:
В этой статье инженер Twitter, поделился своим опытом прохождения интервью. В частности, он дал хорошее описание того, как надо задавать вопросы. Представим, что на интервью вам дали задание спроектировать коробку. Больше никакой информации сходу не дают.
Вопросы могут быть такими:
Ответы на них позволят понять, что нужно создать желтую коробку с нарисованным на ней смайликом, в которую поместится хотя бы один теннисный мяч. Однако, мяч не совсем обычный – его радиус составляет полметра, а вес около 1 кг. Коробку будут просто переносить, держа за дно, так что ручки на ней не нужны.
Информации стало заметно больше, теперь уже можно думать о решении такой уточненной задачи.
Частая ошибка на интервью по проектированию систем – многие кандидаты думают, что раз на этом этапе нужно работать на уровне абстракции, то достаточно будет накидать в ходе разговора крутых терминов и названий модных технологий, чтобы сойти за эксперта. Так это не работает.
Во-первых, на интервью по системному дизайну наверняка будет не просто рекрутер, а инженер, который ищет человека себе в команду. Такому человеку недостаточно просто услышать слова вроде No-SQL, Mongo DB и Hadoop. Он явно начнет задавать уточняющие вопросы, и если у вас на самом деле нет особого опыта в работе с упоминаемыми технологиями, это все очень быстро станет ясно.
Интервью по проектированию систем – это как раз тот случай, когда не страшно чего-то не знать наверняка. Поэтому ответы вида «Я с этой конкретной технологией никогда не работал, но знаю, что ее часто используют для решения подобных задач» – это хороший вариант. Помимо честности, здесь кандидат показал определенные знания и дал интервьюеру понять, с чего он начнет решение задачи (попробует известное решение, если не получится, будет «копать» дальше).
Помимо этого, не стоит выдавать свое решение за идеальное и не содержащее никаких минусов. Ограничения есть всегда, и опытный инженер-интервьюер это понимает как никто другой. Поэтому в ходе интервью стоит честно говорить о том, что в решение есть такие и такие узкие места, но их можно попробовать обойти таким и таким способом, использовать дополнительные инструменты или провести еще больше исследований.
Так станет понятно, что кандидат не просто придумывает решение и затем жестко пытается его продавить, но может быть гибким, вносить корректировки, и вообще адекватен и понимает, что всегда можно сделать лучше.
Вот прекрасный вымышленный диалог на интервью по проектированию систем, который показывает, как НЕ надо делать:
Интервьюер: Давайте сделаем свой Twitter. Как вы будете хранить твиты?
Кандидат: Я использую NoSQL-базу MongoDB.
Интервьюер: Почему не MySQL?
Кандидат: СУБД не масштабируются. Для нашей задачи точно понадобится MongoDB или BigTable.
Интервьюер: Но мы тут в Twitter храним все твиты в MySQL, все нормально масштабируется.
Кандидат: Ну, тогда, возможно, у вас просто еще пока недостаточно большой объем. По-настоящему огромные системы типа Facebook используют NO-SQL.
Интервьюер: Но Facebook также использует MySQL.
Кандидат: Хм, не знаю, как они его масштабируют, надо разобраться. Возможно, у них MySQL только на фронтенде, а на бэке BigTable.
Интервьюер: Неважно. А где будем хранить аналитические данные?
Кандидат: Очевидно, что в MySQL.
Интервьюер: Но не слишком ли их много для MySQL? Сейчас у нас для этого HDFS.
Кандидат: Похоже, что вы начали разрабатывать Twitter еще до того, как MongoDB достаточно развился. MongoDB может легко вместить и твиты и аналитические данные.
Интервьюер: Супер, спасибо за ваше время. Было приятно пообщаться.
Несмотря на то, что проектирование систем – один из наиболее нечетких этапов интервью, к нему можно подготовиться. В помощь кандидатам мы собрали список полезных материалов:
Чтобы попасть на интервью в компании, где инженеры действительно проектируют масштабные системы, используйте бота @g-jobbot. Это сервис, который найдет и бесплатно пришлет вам прямо в Telegram вакансии, которые подходят вам лучше всего — в том числе удаленная работа, в том числе с релокацией.
Техническое собеседование: проектирование систем
Перевод статьи «Get Hired: The System Design Interview, Explained».
Во время поиска работы я сделал открытие. Такое впечатление, что все статьи для разработчиков про подготовку к техническим собеседованиям фокусируются на кодинге. Но ключ к хорошим деньгам — успешное прохождение собеседований, где обсуждается проектирование систем. Собеседования для проверки умения писать код можно или пройти, или провалить, потому что вы либо найдете нужно решение, либо нет. Но собеседования по проектированию систем в этом плане отличаются. У них больше градаций, больше вариантов ответов.
Также следует сказать, что собеседования, связанные с проектированием систем, позволяют отделять разработчиков-джуниоров от сеньоров. Задачи на кодинг призваны проверить, умеете ли вы писать код. А задания, связанные с проектированием систем, позволяют проверить, умеете ли вы создавать программы.
Проходя собеседования на позиции старших full-stack разработчиков, я заметил, что не во всех компаниях проверяли мои знания структур данных и алгоритмов, но буквально на каждом собеседовании были вопросы, касающиеся проектирования систем. В общем, эти собеседования важны.
И, честно говоря, я думаю, что это круто. То есть, в моей практике бывали провалы на таких интервью, но и успешно пройденные собеседования тоже были. На нескольких собеседованиях буквально чувствовалось, насколько интересным занятием является проектирование системы.
В этой статье я расскажу вам, какие вопросы я задавал, проводя собеседования с разработчиками в своей старой команде. Также я покажу, чем отличаются ответы джуниоров от ответов сеньоров. И, конечно, я дам рекомендации по подготовке к подобным собеседованиям. Если что-то покажется вам незнакомым, — не паникуйте: в конце статьи будет несколько ссылок на материалы, из которых можно узнать больше.
О каких собеседованиях идет речь?
Прежде всего, давайте разберем, что из себя представляет собеседование с заданиями по проектированию систем. Речь идет о собеседовании, где кандидата просят спроектировать программное обеспечение от начала до конца. В самой базовой форме задача может формулироваться как «Спроектируйте Twitter». И кандидату дается, скажем, час на то, чтобы изобразить, как бы он спроектировал Twitter, включая модель данных и API. На некоторых собеседованиях кандидата направляют: интервьюер рисует на доске существующую архитектуру, а кандидат должен расширить проект. Но часто кандидату приходится начинать с нуля и проектировать весь продукт в ходе собеседования.
Что подразумевается под словами «спроектировать от начала до конца»? Это именно то, что отличает джуниоров от сеньоров. Когда вы новичок в разработке программ, перспектива у вас не слишком широка. Естественно, что вы фокусируетесь на деталях реализации. Большая часть времени у вас может уйти на обсуждение структуры классов в приложении и модели данных. Сеньор эти вопросы тоже затронет, но он будет говорить и о таких вещах как схемы репликации базы данных и балансировщики нагрузки. Разница в масштабе.
Как отвечать на вопросы по проектированию систем
Вот мой алгоритм решения задач по проектированию систем:
Ответ, безусловно, зависит от формата собеседования, но если вам не задали жесткую структуру, вполне можно воспользоваться этой последовательностью шагов. Давайте посмотрим, как это выглядит на практике.
Пример задания: «Спроектируйте мессенджер Facebook»
Почему я выбрал именно такой вопрос? Подобные задания были на собеседованиях в моей старой команде в Salesforce. Нашим продуктом тоже был мессенджер, хотя и далеко не такой известный. Естественно, от сеньоров мы ожидали, что они будут иметь базовые знания работы чат-приложений. Если кандидат не был знаком с мессенджером Facebook, мы делали обзор функционала этого приложения и говорили кандидату, какую функцию он должен спроектировать.
1. Прояснить вопрос и узнать масштаб продукта
Первым вашим вопросом должно быть «На каких функциях мне сфокусироваться?». Затем следует спросить, на какое число пользователей следует рассчитывать. Ответы на эти вопросы определят ваш проект. От функционала зависит дизайн базы данных и API, а масштаб определяет лучший способ для оптимизации.
Для наших целей предположим, что мы ориентируемся на 1 миллион сообщений в секунду, а из функционала у нас должна быть возможность отправлять и получать сообщения, а также просматривать историю сообщений. То есть, пользователь может переписываться с любыми другими пользователями, а история переписки должна сохраняться неопределенное время.
2. Нарисовать самую базовую инфраструктуру
Любое решение предполагает наличие, как минимум, сервера, клиента и базы данных. В данном случае у нас будут два клиента, использующих сервер в качестве посредника при переписке, и база данных для хранения информации о пользователях и истории сообщений.
Все это — основа вашей схемы. Рисование такой маленькой диаграммы может показаться тривиальной задачей, но интервьюеры поймут вас гораздо лучше, если при объяснении решения вы будете показывать движение данных на схеме.
На этом этапе следует принять одно важное решение: базу данных какого типа вы будете использовать. SQL или NoSQL? Будьте готовы обсуждать плюсы и минусы каждого варианта, а также обосновывать свой выбор. В нашем случае можно, конечно, воспользоваться NoSQL-базой данных, но мы все же используем SQL, потому что хотим привязать сообщения к идентификаторам аккаунтов.
3. Определить API между сервером и клиентом
Мы уже сказали, что будем фокусироваться на отправке и получении сообщений. Как будет выглядеть движение данных для этих целей?
Пользователь А отсылает сообщение на сервер. Сервер перенаправляет сообщение пользователю В. Пользователь В получает сообщение, которое отображается в его клиенте.
Мы можем взять это словесное описание и преобразовать его в псевдокод.
Ваш интервьюер может предложить вам для реализации какие-то особые сценарии. Например, проводя подобные собеседования, я часто спрашивал кандидата, что он будет делать, если сообщение не отправится. В таком случае можно изменить существующие методы API, чтобы включить в них экспоненциальную повторную попытку, или добавить повторную отправку сообщений в качестве функции с собственными методами API.
Разобравшись с одной функцией (обмен сообщениями), можно переходить к следующей (просмотр истории чата).
4. Определить схему базы данных
Хочу подчеркнуть, что на протяжении всего процесса проектирования следует делать все как можно проще. На каждом шаге старайтесь сводить все к минимально жизнеспособному продукту. Схема базы данных — не исключение из этого правила.
Вот как может выглядеть простая схема базы данных для мессенджера:
Здесь есть сущность User, содержащая ID пользователя и его имя, и есть сущность Message, содержащая ID сообщения, ID пользователя-отправителя, ID пользователя-получателя, метку времени сообщения и тело сообщения.
Вы заметили, что я не указал типы данных? Это стратегия, которой вы можете пользоваться, чтобы вести обсуждение на высоком уровне. Если интервьюеру будет интересно, он задаст уточняющий вопрос. Вот тогда и расскажете, данные какого типа будут в каждом столбце. Но если вас об этом не спросят, не стоит первым поднимать эту тему: таким образом вы избежите необходимости принимать целую кучу технических решений.
5. Оптимизировать производительность и доступность
Итак, у вас есть система, позволяющая отправлять и получать сообщения, а также хранить их. Следующий шаг — определить узкие места.
Наша система делает две вещи: отправку и получение сообщений между пользователями, а также хранение и извлечение сообщений из базы данных. Давайте посмотрим, что может замедлить каждую из этих операций, и подумаем, как это исправить.
1. Отправка и получение сообщений
Как мы будем обрабатывать миллион сообщений в секунду? Как правило, один сервер может обрабатывать 50 тысяч соединений одновременно. Это означает, что для обработки миллиона сообщений нам понадобится 20 серверов. Чтобы распределить запросы поровну, мы добавим балансировщик нагрузки, использующий алгоритм round-robin для определения, какой клиент к какому серверу направляется.
2. Хранение и извлечение сообщений
Поскольку мы записываем каждое сообщение в базу данных, мы будем осуществлять миллион операций записи в секунду. Как насчет операций чтения? Нам определенно понадобится извлекать сообщения из базы данных при каждой загрузке страницы пользователем. Но мы не можем загружать сразу всю историю сообщений, поскольку производительность такого запроса будет очень низкой. Нам нужно реализовать lazy loading, чтобы извлекать заранее только определенный набор сообщений, а затем, по мере прокрутки истории пользователем, запрашивать следующие сообщения.
Имея это в виду, предположим, что у нас ежесекундно будет читаться 10 тысяч сообщений — при загрузке страницы пользователем и при прокрутке. Это дает нам соотношение чтение/запись, равное 1/100, т. е., в нашей системе превалируют операции записи (write-heavy system). Значит, нам нужно оптимизировать число конкурентных операций записи.
Можно разделить базу данных на основе хэша ID отправителя и разместить шарды на разных серверах. Это снизит конкуренцию соединений с базой данных, поскольку трафик будет равномерно распределяться между шардами. Это также будет способствовать эффективности извлечения сообщений, поскольку для выемки истории каждого диалога потребуется обратиться к двум шардам.
Дальнейшие шаги
По своему опыту могу судить, что описанные выше действия займут все 60 минут собеседования. Если у вас останется время, можно оптимизировать доступность путем репликации базы данных или добавить дополнительный функционал. Например, можно реализовать список друзей в системе.
Источники
Вот некоторые ресурсы по теме проектирования систем: