Вопросы на архитектуру систем: Часть 1

Если вы когда-нибудь интервьюировались в компанию вроде Google, то вы наверняка в курсе, что есть специальный тип интервью – интервью на дизайн. На таких интервью обычно задают очень широкие вопросы про большие системы – вроде “Как бы вы сделали продукт вроде Google Suggest”? Давайте сегодня посмотрим на эти интервью поближе.

Для чего нужны такие интервью?

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

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

На каком уровне нужно понимать архитектуру?

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

Вот пример того, что, мне кажется, знать обязательно: допустим, есть группа машин, которые обслуживают какую-то систему. Пользователь посылает запрос этой системе. Какой компьютер ответит на этот запрос? Принципиально есть два основных варианта – master и peer-to-peer. То есть либо все запросы принимает одна конкретная машина, и сама распределяет куда его передать дальше (тут желательно помнить то, что вам рассказывали на курсе про сети про load balancing). Либо машины по какому-то алгоритму договариваются сами, а запрос принимает случайная машина. Если вы выбрали архитектуру по принципу мастера, то неплохо иметь ответ на вопрос: что будет, если мастер сломается? Если peer-to-peer – как другие машины узнают, что какая-то машина сломалась, и перестанут пересылать ей запросы?

А дальше – чем опытнее кандидат (причем опытный определяется по резюме – это функция количества лет работы по специальности после окончания университета), тем выше ожидания. Исключение составляют кандидаты, которые идут на очень специализированные позиции – вроде iOS Engineer или Front End Developer.

От кандидатов, которые считаются Senior – это обычно 5-8+ лет опыта – ожидается, что они способны взять большую абстрактную задачу (вроде “Design Facebook Messenger” или “Design Google Suggest”) и самостоятельно разбить ее на отдельные подзадачи. Сколько у нас пользователей, где и как хранить данные, как эти данные выдавать, кто их будет запрашивать, какой предоставить API,  и еще много-много чего. Часто ожидается, что какие-то вещи такой кандидат должен знать из своего опыта, так как, скорее всего, он с чем-то подобным сталкивался в своей работе. Какие-то детали желательно понимать на довольно глубоком уровне.

Как проходит такое интервью?

У вопросов на архитектуру нет правильного и неправильного ответа. Есть большая задача, и очень часто дизайн для такой задачи требует каких-то компромиссов. Например, оптимизировать систему для высокой скорости, или для низкого объема хранимых данных? Обычно оптимизация для скорости значит, что понадобится много уровней кеширования. Возможно дополнительные индексы в базе данных. Для этого потребуется много места. А если цель – использовать мало места, то кеша не будет, и скорость обработки данных закономерна будет ниже.

Тут важно понимать какие есть варианты, и что из них следует. Вот для того же Facebook Messenger – лучше заставить пользователя подождать подольше, или сэкономить немного денег на покупке дополнительных машин?

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

Например, план может быть таким:

1) Кто пользователи у этой системы? Сколько их? Будет ли число пользователей расти? Как быстро? Есть ли какие-то характерные особенности, которые помогут в оптимизации (например, все пользователи живут в одной стране)?

2) Как пользователи взаимодействуют с системой? Нужен ли API? Как он будет выглядеть? Как он будет работать?

3) Какие требования у нашей системы? Скорость? Стабильность? Минимальный объем хранимых данных (может быть актуально если речь идет о системе, работающей на спутниках, например)? Как я уже писала выше, нельзя выбрать все и сразу, обычно придется выбирать что-то в ущерб чему-то.

4) Какие у системы должны быть компоненты? Где хранятся данные? Где они обрабатываются? Кто и как их запрашивает?

5) Как система будет обслуживать большое количество пользователей? Что, если количество запросов превысит возможности системы? Тут, например, можно выстраивать запросы в очередь, или сразу возвращать ошибку “Система перегружена”, или еще что-то сделать. Выбор, опять же, зависит от конкретной системы и от требований к ней.  Будет ли количество запросов равномерно распределено во времени? Если нет, можно ли это как-то использовать?

6) Какие нам нужны оптимизации? Нужно ли кеширование? Возможно ли кеширование? Оно может и не иметь смысла, если данные нужны всегда максимально свежие, и они очень часто меняются (например, количество нажатий на рекламу в Google кешировать смысла особо нет, а вот название фирмы вполне можно). Или можно сделать гибридный вариант? Можно ли как-то просчитать данные заранее и сохранить их где-то?

7)  Безопасность. Нужна ли она? Как мы ее гарантируем, если да?

8)  Как система будет тестироваться? Как часто она будет обновляться? Как нам минимизировать вероятность того, что в систему прокрался баг, который портит результаты, или сильно замедляет обработку данных?

9) Как система будет работать на уровне конкретной машины? Какие там будут алгоритмы? Если алгоритмы будут распределены, то как они будут “договариваться” между собой?

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

Неопытным кандидатам немного попроще. Но не сильно. Им тоже нужен план, и нужно иметь хотя бы общее представление обо всех его пунктах. Ну и глубина знаний и опыта от них не требуется.

А что, если опыта нет?

Если вы не сильно опытный кандидат, то все нормально, много опыта и не требуется. Просто удостоверьтесь, что вы неполохо понимаете Computer Science fundamentals и имеете хотя бы общее представление о вещах, которые я упомянула выше. Во второй части я поговорю о материалах для подготовки немного больше, не пропустите.

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

Тут я вас, боюсь, не сильно порадую. Вам все равно придется проходить это интервью, и уровень требований не понизится от того, что у вас нет опыта. Придется готовиться целенаправленно, читать нужную литературу, смотреть вопросы, которые задавали другим кандидатам и думать, что бы на них ответили вы. Изучать best practices в разных областях. Придется потратить немало времени, да. Но из положительных сторон – вы неплохо улучшите свой проффесиональный уровень, и оно того стоит.

Альтернативный вариант – подаваться на узкую позицию, где таких знаний не требуется. Например, от front end developer ожидается, что он круто пишет на JavaScript, Java, HTML, хорошо знает алгоритмы. Но архитектура достаточна на уровне хорошего общего представления. Правда, тут вам реально надо быть гуру в этой узкой области. Если вы последний раз писали на JavaScript в университете и что-то там смутно помните, но больше не помните, то этот вариант не пройдет.

Продолжение следует…