Привет, Хабр!

  Хочу поделиться своим опытом прохождения Системного Дизайна (aka System Design) в Бигтех. От первых шагов и провалов до успешно пройденной секции. Лично мне изначально эта секция показалась попроще чем алгоритмы. В целом я до сих пор так думаю, но проще – это не значит просто. Что же кроется в мелочах? Давайте разберемся.

База

  Для того, чтобы совсем уж не потеряться, нужно не так уж и много – Load Balancer, Sharding (Шардирование), можно еще Partitioning (Партиционирование), Replication (Репликация), Message Queue (Очереди сообщений), и немного про базы данных. Чтобы все совсем в голове не перемешалось – можно каждую из тем читать в разные дни. За пару недель регулярных заходов можно покрыть достаточно хорошо, чтобы сильно не теряться. Имея этот базовый набор можно уже пробовать собеседоваться, и для менее крупных компаний этого вполне может хватить.

Спроектируй мне …

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

  1. Спроектируй соцсеть с новостной лентой

  2. Спроектируй видеохостинг

  3. Спроектируй карты

  В большинстве своем, спрашивают именно бэкенд, но мне доводилось участвовать и на фронтенд System Design. Причем самое интересное – фронтенд спрашивают дополнительно, если собеседуетесь на фронтенд вакансию, а бэкенд спрашивают всегда.

Нужно делать так, как нужно. А как не нужно, делать не нужно! .

  Казалось бы :) И тем не менее. Правило номер 1: нужно много спрашивать! К примеру, собеседование начинается вот так: "Мы поняли, что можем делать более точные карты (чтобы открыв карту можно было найти кафе неподалеку, например). Мы открыли инновационный способ получения данных, поэтому верим в успех. Давайте попробуем их спроектировать."

  Самое простое (и неправильное) здесь – сразу приступать к реализации. Я завалил несколько собеседований, потому-что мало спрашивал. Например, вы можете сразу взахлеб рассказывать, как бы вы делали построение маршрута, потому-что как раз про это недавно читали, и вот она! Возможность блеснуть знаниями! Но эта функциональность была не нужна. В итоге интервьюеру придется постоянно вас перебивать, вы будете теряться, и не понимать, что нужно.

  Первые минут 5 нужно посвятить вопросам. А что хотим? Что наши карты будут уметь? Нужно ли нам считать, сколько ресурсов потратим, и какое железо нам нужно (обычно не спрашивают, но иногда хотят)? Словом, собираем функциональные ("фичи") и нефункциональные (безопасность, надежность, …) требования. Только после того, как наша фантазия на вопросы закончилась – можем приступать к реализации.

Дьявол кроется в деталях. A vs B

  Базовые концепты покрываются достаточно быстро. На самом деле их не так много. Есть несколько типов СУБД, есть возможность "размазать" нагрузку при помощи очередей (Message brokers) либо периодически запускаемых процессов (Batch jobs). Для того, чтобы 2 штуки чего-то общались между собой есть Push модель (А говорит В: "я сделал") и Pull модель (В спрашивает А: "ты сделал?").

  Для того, чтобы проходить собеседования (и еще в бóльшей степени, чтобы применять на практике) нужно четко разделять, почему вы делаете этот выбор в конкретной ситуации.

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

  1. Я выбрал очереди (Message brokers) для распределения нагрузки вместо "джоб". Сказал что очереди хорошо размазывают нагрузку, а "джобы" с периодическим запуском усложняют архитектуру, и вносят больше задержки в обработке. Меня спросили "А в каком случае вы бы выбрали batch jobs?". И я понял, что ни в каком (кстати, хороший маркер того, что я не понимаю технологию). Я как раз работал на проекте где "пострадал" от этой архитектуры, у нас были неприятные дежурства, мы перешли на очереди и было все хорошо. В общем, ответ был в том, что "джобы" можно назначить на запуск в конкретное время, что часто нужно бизнесу. Сейчас пишу и думаю, как же это очевидно, но на собеседовании я не смог вообще осознать, зачем они нужны в 2020+ году

  2. Pull vs Push. Штука А делает работу, штуке В надо это узнать. Пусть когда А доделает тогда и скажет об этом. В чем проблема? Не буду расписывать, но я регулярно терял внятные инструменты и не мог понять, как же лучше, и почему. Кстати, даже отправка метрик по разному делается в разных инструментах(Prometheus - pull, InfluxDB - push). Я несколько раз выходил после собеседований с фразой "Опять Push/Pull не вспомнил"

Я настолько устал ошибаться на Push/Pull, что нарисовал себе схемку и распечатал:

Компромиссы (tradeoff)

  Серебряной пули не существует. Это вроде все знают, а вроде и забывают :) Особенно на собеседованиях от кандидатов мне часто приходилось слышать "штука А это круто, а штука Б это плохо". Обычно это некоторый ПТСР, идущий из проекта, где кандидат от этого пострадал. Всплывают фразы вида: "Строгая типизация это плюс, динамическая это минус", "Монолит это плохо, микросервисы это хорошо", "Ой нет, был у меня опыт с Cassandra, ужасно работало, PostgreSQL - венец эволюции. Надо всегда выбирать его". 

  Senior/Principal инженер подразумевает более глубокое понимание. Это всегда компромиссы. Выбирая определенный путь мы всегда чем-то жертвуем. Если мы берем монолит - мы жертвуем масштабируемостью, если мы берем микросервисы - мы жертвуем скоростью (разработки, а часто и ответа). 

  Чем выше уровень инженера – тем более глубоко он понимает, чем NoSQL выиграет у SQL и наоборот. Это и структуры данных для хранения (LSM / B-Tree), и обязательства наличия схемы данных, и наличие/отсутствие связей между сущностями, и т д.

  В идеале для любого выбора вы должны понимать Tradeoff (я вольно трактую это слово как "Компромисс", но в разговоре использую все-таки "трейдоф"). Что вы теряете (вы всегда теряете что-то) от этого решения, и насколько это критично.

Материалы для подготовки

  Я готовился так – покупал бумажные книги и карандашом делал на них заметки. Там где отметил – загибал листочек в углу. Так выглядят мои книги сейчас:

  Итак, что же это за книги, и в каком порядке лично я рекомендую их читать:

Alex Xu - System Design Interview Volume 1

  Честно говоря, я считаю, что после этой книги можно пробоваться. Из 6 собеседований в Бигтех 3 задания были взяты отсюда. Это хороший фундамент для ознакомления не только с базой и основными подходами, но еще и с самыми популярными заданиями. На мой взгляд это "must have".

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

System Design Interview volume 2

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

Designing Data-Intensive Applications

  Легендарная книга с максимальным погружением в вопросы "почему". Как устроены структуры данных в одном или другом типе СУБД, какие есть проблемы при масштабировании, какие есть проблемы распределенных систем и какие есть подходы к их решению.

  Мое мнение - не стоит начинать читать эту книгу первой. Я рад, что я начал ее решать спустя 2 другие книги, и решение алгоритмов.

  На мой взгляд эта книга – путь в "больше чем Senior". Она дает ту "дополнительную" глубину, которой обладают хорошие технические лидеры, Principal/Staff инженеры, и т д.

 P.S. Эта книга про рост и глубину. К моменту прохождения собеседования в Бигтех я дочитал ее где-то наполовину.

Финальные мысли

  System Design это очень интересная секция, которая может развенчать много "магии" вокруг инструментов. Как делают игры, карты, платежные системы, видеохостинги, S3, прочие сервисы.

  Эту секцию можно быстро нахватать по верхам, и уже как-то отбиваться на собеседованиях.

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