Разработка
Мой опыт прохождения собеседования в Google
Как и большинство инженеров-программистов, получить работу в Google было моей мечтой на протяжении многих лет.
Я работал в Facebook* London в команде Instagram*, когда начал задумываться о возвращении в Индию. Возможно, я поделюсь своими причинами в другой статье.
В ноябре 2022 года со мной связался рекрутер Google. Они упомянули о вакансии на должность L5 в Бенгалуру и спросили, не заинтересован ли я.
Поскольку я уже подумывал о переезде в Индию и ранее проходил собеседование в Google, но мне предложили более низкую должность (L4), чем я рассчитывал, после этого опыта я перешел в META на уровень E5 (подробности о моем собеседовании в META вы можете найти здесь).
Я сообщил рекрутеру, что хочу назначить собеседование на март 2023 года. Это было связано с тем, что я скоро стану отцом и хотел уделить время своей семье в этот важный период.
Рекрутер согласился с моей просьбой и предоставил материалы для подготовки к собеседованию. Он упомянул, что в марте свяжется со мной для проведения интервью, а тем временеме будет проверять, как проходит моя подготовка.
В этот раз на моем пути к подготовке возникла уникальная проблема — в семье появилось восхитительное пополнение, новорожденный. Подгузники и программирование конкурировали за мое внимание, выкраивание времени для целенаправленной учебы превратилось в настоящее приключение! У меня было около 25-30 дней, чтобы овладеть искусством успокаивания ребенка и успешно пройти собеседования.
Моя подготовка
Решил около 75 вопросов LeetCode
Проработал следующие темы данных, структур и алгоритмов
- Граф: BFS, DFS, топологическая сортировка, кратчайший путь
- Дерево: двоичное дерево, двоичное дерево поиска, N-арное дерево
- Префиксное дерево: префиксный поиск, поиск слов с подсчетами
- Объединение дизъюнктивных множеств
- Куча: медиана в потоке, максимум в скользящем окне, k топ элементов
- Бинарный поиск: нижняя граница, верхняя граница, вопросы, в которых двоичный поиск не является очевидным выбором
- Вопросы на основе скользящего окна и двух указателей
- Динамическое программирование
- Строки: KMP, сортировка строк
- Специальные вопросы по применению массива, стека, очереди, HashMap, TreeMap
Подготовился по системному дизайну
Прочитал несколько научных работ:
- Amazon Dynamo: Amazon’s Highly Available Key-Value Store
- The Google File System
- Spanner: Google’s Globally Distributed Database
- Cassandra — A Decentralized Structured Storage System
- MapReduce: Simplified Data Processing on Large Clusters
- Bigtable: A Distributed Storage System for Structured Data
Попрактиковался в решении популярных задач по проектированию систем, таких как разработка сервиса сокращения URL, Pastebin, Instagram, Dropbox, Facebook Messenger, Twitter, YouTube/Netflix, Typeahead Suggestion, API Rate Limiter, Twitter Search.
Попрактиковался в проектировании систем для некоторых продуктов Google, включая Google Search, YouTube, Google Photo Sharing and Storage, Google Docs, Google Drive.
Пересмотрел концепции проектирования систем, такие как теоремах CAP и PACELC, SQL vs No-SQL, типы баз данных No-SQL и их применение, последовательное хэширование, фильтры Блума, балансировщики нагрузки, горизонтальное масштабирование, кэширование, разделение/шардинг баз данных, индексы, ограничение скорости, распределенные очереди, дедупликация запросов.
Посмотрел несколько видеороликов на YouTube по проектированию систем.
Провел 7 пробных собеседований — 3 с друзьями и 4 на Pramp
Мои собеседования
Раунд 1: DSA (45 минут) — дерево, обход в порядке следования, топологическая сортировка
Во время собеседования интервьюер опубликовал в редакторе кода длинный вопрос и попросил меня прочитать его. После прочтения я задал несколько уточняющих вопросов, чтобы лучше понять суть проблемы.
После того как я все понял, я предложил использовать дерево в качестве структуры данных и применить обход дерева для решения проблемы. Затем интервьюер попросил меня объяснить решение на примере, что я и сделал.
После объяснения интервьюер попросил меня реализовать решение. Приступая к написанию кода, я стремился сделать его модульным. Для этого я создал класс TreeNode, класс TreeClass и отдельный класс специально для решения задачи. Из-за нехватки времени и моей ориентации на модульность я столкнулся с некоторыми трудностями, но в итоге мне удалось написать работающий код.
У интервьюера было несколько дополнительных вопросов, но он не смог их задать из-за нехватки времени. К концу раунда я понял, что облажался. Позже я понял, что ту же задачу можно решить с помощью топологической сортировки.
Раунд 2: DSA (1 час) — дерево с N детьми, обход деревьев
Во втором раунде я был удивлен тем, что продолжительность собеседования была 1 час, так как обычно раунды DSA в Google длятся 45 минут.
Когда собеседование началось, я быстро понял, почему этот раунд был продлен до 1 часа. Интервьюер представил задачу, используя Google Doc, который содержал длинный вопрос, занимающий 4-5 страниц. Кроме того, был слайд с диаграммой, дающей полное представление о проблеме.
Увидев объемную проблему, я немного занервничал. Читая задачу, я обнаружила, что забыл детали предыдущих страниц, дойдя до третьей. К счастью, интервьюер оказался очень отзывчивым и уделил время объяснению проблемы. Я задавал многочисленные уточняющие вопросы, и мне потребовалось около 20-25 минут, чтобы полностью разобраться в тонкостях проблемы.
Как и сама сложность вопроса, решение этой задачи также было обширным. Задача была посвящена деревьям, в частности деревьям с N-детьми. Несмотря на сложность, мне удалось написать полный код. К концу раунда я немного вспотел, но чувствовал уверенность в том, что справился с задачей.
Раунд 3: DSA (45 минут) — средняя задача Leetcode, дерево, куча, рекурсия
Этот раунд отличался от двух предыдущих. Интервьюер представил стандартную задачу LeetCode, а именно задачу среднего уровня с фокусом на деревьях и небольшой модификацией. Я быстро предложил решение, проверил его на примерах, после чего меня попросили написать код. Я быстро закодировал решение и указал временную и пространственную сложность.
Follow-up 1: Интервьюер немного изменил задачу и спросил, как я изменю свой код, чтобы приспособить его к новой функции. Я быстро определил необходимые изменения, сделав свой код не только адаптируемым к модификации, но и более модульным, чтобы легко приспособить его к таким изменениям с помощью паттерна проектирования Стратегия.
Follow-up 2: Интервьюер задал сложный вопрос. Мне потребовалось некоторое время, чтобы найти оптимальное решение, и объяснение решения на примерах также заняло некоторое время. Модификации, которые я сделал ранее для повышения модульности кода, оказались полезными для быстрой адаптации к изменениям, заданным в последующем вопросе 2. Я смог написать код в срок.
Follow-up 3: Это было связано с выпуском моего решения в прод. Я предложил несколько подходов, с помощью которых мой код может работать в производственной среде.
Завершив этот раунд, я почувствовал себя уверенно.
После первых трех раундов рекрутер сообщил, что в одном из раундов DSA я получил смешанные отзывы. Я уже подозревал об этом, так как чувствовал, что не показал хороших результатов в первом раунде. Рекрутер рекомендовал провести дополнительный раунд DSA, чтобы убедиться, что у комиссии по найму нет никаких опасений, учитывая сильные отзывы о найме, полученные в двух других раундах.
Раунд 4: DSA (45 минут) — строки, сортировка, двоичный поиск, префиксное дерево
Я нервничал перед этим раундом. Интервьюер представил проблему, с которой я раньше не сталкивался. Хотя сама задача не была слишком сложной, она требовала применения множества концепций DSA, таких как хеширование, сортировка, двоичный поиск, верхняя граница, нижняя граница и рассмотрение крайних случаев. Кроме того, интервьюер попросил написать соответствующие тесты.
Поразмыслив около 5 минут (и думая вслух), мне удалось разработать алгоритм решения задачи. Я объяснил решение, проверил его на примерах, а затем объяснил временную и пространственную сложность своего решения. Затем интервьюер попросил меня написать код. Я быстро написал код, создал тестовые примеры и убедился, что все крайние случаи покрыты.
Follow-up 1: Интервьюер задал вопрос, немного изменив исходные данные и ожидая получить еще более оптимальное решение. Рассмотрев несколько примеров, я придумал решение с помощью префиксного дерева, которое соответствовало ожиданиям интервьюера.
Follow-up 2: Интервьюер поинтересовался масштабируемостью моего решения для работы с очень большими наборами данных и его жизнеспособностью в производственной среде. Я обсудил возможность разделения структуры данных дерева, описав различные стратегии для эффективного разделения. Кроме того, я представил альтернативный подход с использованием хранилища «ключ->значение», хотя мы не стали углубляться в эту альтернативу. После этого интервьюер попросил меня реализовать решение на основе дерева.
Код для этого решения был очень длинным, и мне пришлось спешить, чтобы закончить его в отведенное время. В целом, этот раунд прошел хорошо.
Раунд 5: Системный дизайн (45 минут)
Интервьюер поручил мне спроектировать один из продуктов Google. Вооружившись предварительными знаниями о системном дизайне, после нескольких уточняющих вопросов я эффективно сформулировал функциональные и нефункциональные требования, подтвердив их у интервьюера. Затем разговор перешел к детальному обсуждению конкретных функций, что сделало этот раунд более разговорным по своей природе.
Мы рассмотрели несколько подходов, тщательно изучив плюсы и минусы каждого из них. Благодаря интерактивному и поддерживающему поведению интервьюера этот раунд превратился из обычного собеседования в техническую дискуссию. В целом, это был отличный опыт.
Однако, с другой стороны, я не был уверен в своей работе в этом раунде.
Раунд 6: Гугливость (45 минут)
Мы углубились в мой предыдущий опыт работы и выяснили причины моего решения покинуть META. После этого интервьюер задал несколько вопросов на соответствие компании, которые носили ситуационный характер. Интервьюер предложил несколько интригующих сценариев, а я отвечал на них, опираясь на свои прошлые проекты и опыт. Интервьюер на протяжении всей сессии сохранял дружелюбный и благожелательный настрой.
В целом, этот раунд прошел гладко, и я считаю, что он прошел хорошо.
Прошел собеседование в Google
В течение всего этого долгого периода я с нетерпением ждал результатов. В наших немногочисленных беседах рекрутер упоминал, что они ожидают решения комитета по найму. Через три недели рекрутер позвонил и поздравил меня, сообщив радостную новость — я прошел собеседование в Google, и комиссия по найму дала положительный результат.
Переговоры и принятие предложения
В этот раз мне не пришлось долго обсуждать предложение, в отличие от того, когда я получил предложение от META. Первоначальное предложение соответствовало моим ожиданиям, поэтому я с радостью принял его.
Как и в META*, Google предложила щедрые льготы при переезде, что сделало переход из Лондона в Бенгалуру гораздо более плавным.
Подбор команды
Процесс подбора команды в Google довольно обширный. У меня было несколько встреч с менеджерами различных команд, чтобы найти подходящий вариант. В итоге я присоединился к команде Google Cloud Databases, которая показалась мне очень интригующей.
Я официально присоединился к Google 16 октября 2023 года. Вот краткая хронология этого пути:
- Ноябрь 2022 года: со мной связался рекрутер
- Март 2023 года: я прошел собеседование
- Август 2023 года: получил предложение
- Октябрь 2023 года: присоединился к Google
Основные выводы
- Хорошо изучите структуры данных и их применение. Вопросы о деревьях были постоянной темой трех раундов моего собеседования.
- Google делает акцент на качестве вашего решения, в отличие от META, где во главу угла ставится скорость.
- Ответы на последующие вопросы имеют значительный вес.
- Будьте готовы к тому, что во время собеседования вам придется решать объемные задачи и писать сложный код.
- Некоторые последующие вопросы могут касаться сложностей, связанных с внедрением вашего решения в производственную среду.
Как и большинство инженеров-программистов, получить работу в Google было моей мечтой на протяжении многих лет. Google славится своей инженерной культурой, сложными задачами и инновационными технологиями. Возможность работать в такой влиятельной компании рядом с лучшими умами в отрасли была для меня главным стимулом.
После напряженного процесса собеседования, потребовавшего тщательной подготовки, я с радостью могу назвать себя сотрудником Googler. Я с нетерпением жду возможности постоянно участвовать в интересных проектах и расширять свои навыки, учась у своих талантливых коллег. Я с нетерпением жду нового этапа своей карьеры.
Дополнительные ссылки
- Как получить работу в Apple без колледжа и LeetCode
- Онлайн собеседования мобильных разработчиков
- Я прошел собеседования в Google… Как?
- Как устроены собеседования в SberDevices