Эксперименты
У меня зазвонил телефон.
— Алло, это Джаред.
— Здравствуйте. Я звоню вам насчёт телефонного собеседования в Гигантской Поисковой и Рекламной Компании [очевидно, это Google — прим. пер].
— Да! С нетерпением ждал вашего звонка!
— Хорошо. Можете написать алгоритм для поиска K-го самого большого значения в двоичном дереве?
Я замолкаю. Полностью отключаюсь. Никогда не попадал в такую ситуацию. Пустой документ Google смотрит на меня, а курсор мигает как в замедленной съёмке. Я кое-что набрасываю в качестве первого прохода.
— Можете написать тестовый пример для этого алгоритма?
Конечно. Я бы мог, если бы не был полностью одурманен и моё внутреннее эго не таяло под пылающей яростью мечты, умирающей на моих глазах. Неужели к этому сводится вся моя тяжёлая работа за последние несколько месяцев? Примерно в январе 2019 года я решил, что пришло время найти новую работу. Как будто боги программной инженерии благословили эту самую мысль, и рекрутер Гигантской Поисковой и Рекламной Компании связался со мной в LinkedIn по поводу телефонного собеседования. Это было прекрасно!
Такое случилось уже не в первый раз. Будучи блестящим молодым инженером, только что окончившим школу, я не так давно приступил к первой работе и неплохо справлялся с ней. Но потом мой мир перевернулся с ног на голову. Я работал над особенно неприятной ошибкой и сделал то, что сделал бы любой уважающий себя инженер-программист, прежде чем пытаться решить её самостоятельно: погуглил. Как только я нажал Enter с моим соответствующим тупым запросом в окне поиска, экран почернел и меня выбросило в консоль.
Вы говорите на нашем языке… Хотите решить задачу?
1. Да
2. Нет, спасибо
Я чуть не поперхнулся еле тёплым кофе Costco. Хотелось вскочить и закричать, чтобы коллеги пришли посмотреть. Но потом я вдруг забеспокоился, что у меня глюки, в этом случае я попаду в весьма щекотливую ситуацию. Опасаясь, что мой дух вот-вот вылетит из тела, я нажал 1.
Дан массив nums, содержащий n+1 целых чисел, где каждое целое число находится между 1 и n (включительно). Докажите, что хотя бы одно число повторяется. Предположим, что существует только один дубликат. Найдите его.
У вас 24 часа!
У меня случился небольшой сердечный приступ. Когда мне удалось привести себя в чувство с помощью ещё одной порции кофе Costco, я понял, что вполне могу решить задачу. У меня уже был план. Так я и сделал. Как только я нажал кнопку «Отправить», мне дали решить ещё одну. Это повторялось пять раз, и с каждым разом становилось всё труднее. Когда я отправил последний ответ, то увидел ещё одно сообщение:
Поздравляем! Этот код очень хороший! Хотите пройти собеседование в Гигантской Поисковой и Рекламной Компании?
Вот и всё. Весь мой профессиональный мир изменился. Одна из самых могущественных организаций мира проникла в мой 22-летний мозг и переписала регистр. Ни одна из предыдущих целей в карьере больше не имела значения. До этого я был в блаженном неведении, что меня может нанять такая топовая компания. Но очевидно, что я каким-то образом оказался достаточно достойным внимания.
Телефонное собеседование было похоже на кошмарный сон. Меня попросили за 45 минут запрограммировать игру Конвея «Жизнь». Вообще-то я неплохо справился. Написал всю программу и протестировал её. На следующий день я получил отказ. Внутренне я был подавлен и смущён. Что именно я сделал не так? Разве все тесты ничего не значили? Почему я должен был написать такой сложный алгоритм за такое короткое время?
После первого опыта решения задач на этом уровне я решил, что должен усовершенствовать свои навыки. Собеседование состоялось в апреле этого года. Я составил трёхмесячный учебный план и приступил к делу. Каждое утро я решал три практические задачи перед работой. Вечером после пробежки и перекуса работал ещё. За три месяца в общей сложности я решил 114 практических задач. Массивы, поиск с возвратом, двоичный поиск, двоичные деревья, поиск в ширину, поиск в глубину, динамическое программирование, графы, жадные алгоритмы, хэширование, связные списки, вероятности, сортировка, стеки и префиксные деревья — вот некоторые из тем, которые я изучал. Как я мог потерпеть неудачу с такой подготовкой?
Неудачи
Интервью с Гигантской Поисковой и Рекламной Компанией завершилось в огне. Я не мог решить проблему. Но это было только начало безумия. Сначала я весьма стратегически подошёл к тому, в какие компании обращаться. Мне нужна была не просто «хорошая», а «правильная» работа.
Следующей была компания по производству беспилотных автомобилей. Я получил ответ почти сразу после подачи заявки и настроил редактор кода. Интервьюер раздражённо и с очень сильным акцентом попросил меня закодировать очень сложный алгоритм фильтрации изображений. Я написал его. «Выглядит очень хорошо!» — сказал он. На следующий день я получил шаблонное письмо с отказом.
Затем была аналитическая компания, которая попросила выполнить домашнее задание из трёх предложений. Я сделал всё, что мог, и написал очень сложную многопоточную систему обработки изображений. И получил вежливое «Нет» от рекрутера, а когда попросил объяснить, мне сказали, что моя реализация была «слишком неэффективной».
После этого была компания по обработке платежей. У меня был отличный телефонный разговор с рекрутёром, и она восхищалась, насколько хорошо моё резюме соответствует описанию работы. На следующий день я получил от неё письмо, что они не могут найти вакансию для моего набора навыков.
Другой пример был с Гигантской Компанией Социальных Медиаплатформ: «Джаред! Благодарим за вашу заявку! Думаем, что вы отлично подойдёте для работы в нашей компании! Я отправил ваше заявление непосредственно менеджеру по найму в вашем региональном офисе!» Через восемь минут я получил шаблонное письмо с отказом, в котором было написано, что мои навыки не подходят для этой должности.
Ко мне обращалось бесчисленное количество сторонних рекрутеров. Все разговоры закончились ничем. Пожалуй, больше всего мне понравилась одна компания по звукообработке. Рекрутер связалась со мной и сказала, что после просмотра моего резюме команда очень взволнована и стремится поговорить со мной, так что она установит контакт с менеджером по персоналу. Прошла неделя, я спросил у неё, как дела. Рекрутер сказала, что она связалась с менеджером по персоналу — и он не думает, что мои навыки соответствуют должности. Я смирился с этим… однако в качестве теста отправил своё резюме на другую вакансию — и со мной немедленно связался другой рекрутер. Я был поражён, что они немедленно позвонили. Должен признаться, в этот раз я не очень хорошо проявил себя. На следующий день я получил по почте шаблонный отказ.
Наконец, я дошёл до этапа собеседования в офисе Гигантской Компании Социальных Сетей. Я ответил на серию вопросов по программированию с несколькими людьми в течение четырёх различных интервью — правильно и удовлетворительно ответил на все из них. По пути мне задали ряд запутанных и жёстких вопросов типа «Расскажите о том времени, когда...». Это было освежающе, так как впервые во время поиска работы меня спросили о моём опыте и проницательности как инженера вообще. Затем последовало заключительное собеседование по проектированию систем. Интервьюер быстро дал мне небольшую систему для разработки. Я начал рассказывать о своём решении, а по ходу мне задавали вопросы. Наконец, мы дошли до того, что он сказал: «Хорошо, допустим, у нас микросервисная архитектура… можете её спроектировать...?» Я сразу же сказал, что у меня нет никакого опыта работы с микросервисами. Он вопросительно посмотрел на меня и спросил: «Нет опыта?» Я подтвердил. Я постарался чётко изложить свой набор навыков и опыт в области ПК, встроенных систем и мобильных разработок. Он замолчал как человек, который понимает, что совершил ошибку. Отлично! Я четыре месяца готовился к этому собеседованию, потратил на подготовку практически всё нерабочее время, решая практические задачи, и репетируя, как представить свой опыт по навыкам коммуникации, а он не потрудился потратить 10 минут на чтение моего резюме.
Анализ
Я мог бы продолжать оплакивать множество разочарований, которые испытал в этом трудном поиске работы. Там было многое. Я всегда стремился быть абсолютно честным с самим собой и другими относительно своих способностей. Я не претендовал на работу, требующую многолетнего опыта, которого у меня не было, или отсутствующих навыков. Конечно, я хотел вернуться в веб из программирования встроенных систем, но у меня было два года опыта работы в качестве веб-инженера в дополнение к моему другому опыту в качестве разработчика мобильных приложений и исследователя алгоритмов машинного обучения. Я полностью признаю, что у меня бесчисленное количество возможностей для роста и самосовершенствования. Но с другой стороны, я вполне уверен в наличии навыков, которые позволят очень быстро приступить к новой работе. На мой взгляд, программирование — это дистиллированная форма искусства, определяемая обучением и новым опытом. Ни один инженер-программист не собирается останавливаться в развитии до конца своей карьеры. По крайней мере, я надеюсь, что нет: те, кто сделает так, очень быстро останутся на обочине. Так что же здесь происходит на самом деле? После того, как я так долго переживал этот мрачный процесс, я решил разложить и проанализировать свои наблюдения, а затем обдумать их, чтобы получить более ясную картину.
- Мы поглощены собственной мифологией. Практически каждая популярная концепция программиста, особенно в современном помешанном на технологиях мире, предполагает идею одинокого программиста-индивидуалиста, который может легко решить любой алгоритм по требованию. Архетипический инженер-программист — это социально незащищённый, антиструктурный и крайне идеалистичный человек. Он отчаянно независим, а чтобы сделать работу, не нуждается в общении с кем-либо. Из этого следует, что поскольку мы бессознательно верим в этот архетип, у меня как инженера должны в первую очередь проверить эти черты. Но насколько нам известно, эти черты характера на самом деле отрицательно коррелируют с высокоэффективным кандидатом. В компаниях по разработке программного обеспечения работает одна или несколько команд разработчиков. Команды — это группы людей.
- Чтобы добиться успеха в группе с общей целью индивиды должны:
- Общаться друг с другом — если один из членов команды не понимает цель, он потянет вниз всю команду.
- Общаться с непрограммистами — хотя некоторым программистам это не нравится, но для управления компанией действительно недостаточно одних только разработчиков.
- Взять курс — чаще всего направление для продукта приходит извне команды разработчиков. В конце концов, это своего рода смысл работы в организации: вы воплощаете в жизнь видение, которое не является вашим.
- Учиться друг у друга — всегда есть дисбаланс, кто что знает в команде. Это относится как к знаниям о продукте, так и к техническим навыкам. Существует взвешенный баланс в общем наборе технических навыков для коллектива. Вот почему создаётся иерархия опыта и распределение обязанностей. Это равновесие никогда не бывает и не должно быть статичным. Кто-то всегда должен учиться, и всегда есть кто-то, кого можно научить.
В заключение к этому пункту, кажется, что популярная концепция инженера-программиста слишком сильно влияет на процесс найма. Сильнее, чем черты, которые на самом деле делают инженеров-программистов успешными на работе. - Чтобы добиться успеха в группе с общей целью индивиды должны:
- Мы все знаем, что задачи на знание алгоритмов — это надуманная игра, и этот момент немного трудно прояснить, поскольку в нем есть ряд аспектов.
- Насколько вообще ценны алгоритмы? Есть много точек зрения на этот вопрос. Хотя я не согласен, но есть даже мнение, что вы можете быть отличным программистом, вообще ничего не зная об алгоритмах и даже об устройстве компьютера, если на то пошло. Мой контрапункт заключается в том, что авиамеханик отличается от аэрокосмического инженера. Кто из них ценнее, и кем бы вы предпочли быть? Я оставляю этот мыслительный процесс на ваше усмотрение. Лучше спросить, насколько релевантны алгоритмы.
- Насколько вообще релевантны алгоритмы? Я верю, что для успешного и ценного инженера важно знание алгоритмов и того, как работает компьютер. Но все знают, что эти знания редко используются на работе. В командах повсеместно распространено и навязывается мышление «не изобретать велосипед». Для многих и большинства приложений это хорошая политика. Если есть хорошо проверенная библиотека, то безопаснее и уместнее использовать её, чем заново изобретать колесо. Круглые колёса — это, так сказать, хорошие колёса. Итак, если рассматривать проблемы алгоритмов в связи с этим вопросом, то возникает вопрос, почему, черт возьми, мы вообще задаём эти вопросы. Если так много людей в отрасли думают, что эти вопросы не представляют ценности в ежедневных задачах, то почему мы используем их для оценки программистов?
- Тёмная сторона задач на алгоритмы. Как и во многих философских вопросах в жизни, есть тёмная сторона. Дело в том, что в технологическую индустрию пытается войти огромное количество людей. В течение дня после публикации вакансии в LinkedIn у неё более ста кандидатов. Практически ни у одной компании нет ресурсов, чтобы опросить всех. Задачи на алгоритмы становятся механизмом просеивания кандидатов, которые не подходят для работы или не имеют базовых навыков программирования. Проблема в том, что у каждого, похоже, есть своё представление о том, что означает «базовых» в этом контексте.
- Мы не знаем, насколько трудными они должны быть. В течение семи месяцев во время собеседований я столкнулся с большим количеством очень сложных задач. С одной стороны, меня попросили написать функцию для обращения строки. С другой стороны, меня попросили имитировать социальную сеть и написать алгоритм фильтрации изображений. Одна компания попросила провести два отдельных собеседования по программированию. В первом меня попросили написать простой алгоритм сортировки. На втором — написать рекурсивный генератор перестановок (пермутаций) с использованием динамического программирования, что является непростой задачей. В тот момент я был совершенно сбит с толку. В конце я спросил интервьюера: «Эта проблема кажется немного крутой для телефонного интервью. Часто ли вы пишете рекурсивные алгоритмы в Компании по Обработке Платежей? Он ответил: «Нет, мы не используем рекурсию». Я спросил «А как насчёт пермутаций? Когда вы ими пользовались?» Он ответил: «Наши алгоритмы не нуждаются в пермутациях. Большинство наших инженеров работают над пользовательскими интерфейсами и инфраструктурой». Больше у меня вопросов не было. Почему на аналогичные позиции одна компания предпочитает задавать более простые вопросы, а другая — более сложные?
- Численная оценка не намного лучше, чем русская рулетка. Допустим, вы кандидат. Вы потратили последние пару месяцев на изучение каждой темы, которая может иметь отношение к программированию интервью. Предположим, вы подаёте заявку в компанию A. Она просит вас написать алгоритм поиска в двоичном дереве. Отлично! Вы только что закончили изучать двоичные деревья! Вы проходите с честью. Теперь предположим, что вы подаёте заявление в компанию Б. Та просит написать реализацию префиксного дерева. Нееет! Вы забыли его выучить! Из-за того, что вы не изучали эту тему, вы проваливаете собеседование. Теперь поменяйте местами эти компании: предположим, компания Б задаёт вам алгоритм двоичного дерева, а компания A спрашивает о префиксном дереве: ясно, что получение работы в какой-то компании зависит чисто от темы вопроса.
- Ограничения по времени вредны и дискриминационны. Обычно во время телефонного собеседования на задачу по программированию вам дают 45 минут. Этого достаточно для решения простой задачи. Но когда вас просят написать сложный алгоритм, это просто смешно. Когда меня попросили написать игру «Жизнь», мне потребовалось 50 минут, чтобы получить работающий фрагмент кода, и у меня почти не было времени его протестировать. Когда меня попросили написать алгоритм фильтрации изображений, я потратил первые 15 минут только на то, чтобы понять этот вопрос. У меня кончилось время. Если бы такой сложный алгоритм был написан в реальном мире, вероятно, неделю заняла бы реализация и месяц тестирование. Как минимум. Так почему мы просим инженеров сделать это за 45 минут?
- Вокруг прохождения собеседований существует смежная индустрия. Все эти задачки на алгоритмы начались с популярных компаний, таких как Google. Потом несколько инженеров из этих компаний увидели возможность заработать несколько долларов, предложив материал для подготовки к собеседованиям. На эту тему были написаны две популярные книги: «Взлом интервью по кодированию» и «Элементы собеседований по программированию». Обе книги предлагают материал для подготовки к интервью. Проблема в том, что индустрия получила доступ к этим книгам и адаптировала свои интервью к их материалу. Но когда люди начали массово отвечать на основные вопросы, изложенные в этих книгах, компании поняли, что фильтрация сотрудников перестала работать. Поэтому они написали новые, более сложные вопросы на алгоритмы, чтобы выделиться и нанимать «более квалифицированных кандидатов из всех, казалось бы, квалифицированных». Существует множество историй о нынешних и бывших инженерах высшего звена в конкретных компаниях, которые утверждают, что процесс собеседования стал настолько трудным, что они сами никогда не прошли бы его сейчас. Например, в одной «топовой» технологической компании процесс заключается в том, что, когда кандидат проходит интервью, по его результатам составляется определённый «пакет» с оценками. Затем пакет направляется в комитет, чья работа заключается в беспристрастном рассмотрении пакета для принятия решения о найме. В какой-то момент один комитет стал настолько критичным, что они в течение нескольких месяцев отклоняли все пакеты. Когда отдел кадров пронюхал об этом, они решили устроить проверку. Они послали комитету новую порцию пакетов, и комитет снова отклонил их все. Затем отдел кадров созвал всех на совещание и объяснил, что пакеты, которые они только что рассмотрели, на самом деле были собственными пакетами членов комитета по найму на тот момент, когда они проходили собеседование в этой компании. Они неосознанно отвергли самих себя! Как можно пройти такую планку?
- Насколько вообще ценны алгоритмы? Есть много точек зрения на этот вопрос. Хотя я не согласен, но есть даже мнение, что вы можете быть отличным программистом, вообще ничего не зная об алгоритмах и даже об устройстве компьютера, если на то пошло. Мой контрапункт заключается в том, что авиамеханик отличается от аэрокосмического инженера. Кто из них ценнее, и кем бы вы предпочли быть? Я оставляю этот мыслительный процесс на ваше усмотрение. Лучше спросить, насколько релевантны алгоритмы.
- Почему мы измеряем людей, а не изучаем их? Несколько недель назад я смотрел выступление одного товарища, который провёл большое количество интервью в топовой компании. По его словам, цель состоит в том, чтобы «отточить стратегию извлечения сигнала во время интервью». Что?! Что стало с людьми, которые хотели узнать друг друга? Это отношение кажется таким совершенно роботизированным и, честно говоря, довольно мрачным. Какова здесь логическая последовательность? Будем ли мы сканировать мозг кандидата, чтобы найти сходство с существующими высокоэффективными кандидатами? Это отношение кажется особенно ужасной смесью эгоизма и организационного мачизма. Мне кажется, что сейчас компании больше боятся нанять плохого кандидата, чем радуются возможности нанять отличного. Пока компании не изменят своё отношение, вряд ли улучшится ситуация для кандидатов. Хуже всего то, что кандидат первым делом слышит от рекрутера, какой он отличный профессионал, а как только попадает на собеседование, встречает только подозрения и сомнения в его профессионализме. Я считаю, что подозрительность нужно заменить осторожным оптимизмом.
Я совершенно уверен, что мог бы продолжать в том же духе. У меня в заметках ещё около восьми пунктов. Но на данный момент статья больше похожа на обличительную речь, чем на пост в блоге. Надеюсь, что мне удалось рассказать о некоторых трудностях, через которые я прошёл за последние семь месяцев. В конце концов, у меня двойственные ощущения. Мой текущий работодатель просто уволил весь мой офис, оставив меня без работы и в одиночестве, чтобы написать о том, как мне всё это не нравится. Не совсем уверен, что хочу снова пройти через этот процесс. Я много размышлял о своём опыте и пришёл к некоторым простым выводам:
- Я знаю, как писать софт — за два года я написал около 85 000 строк Java-кода для продакшна, что оказало очень положительное и ярко выраженное влияние на продукт, над которым я работал. Я написал несколько очень сложных реализаций алгоритмов машинного обучения на Python, а также довольно много скриптов. Я написал код embedded C и C++ для различных низкоуровневых приложений, таких как графика на встроенных системах. Я выучил Flutter и опубликовал несколько приложений. Я выучил Clojure, что стало весьма просветляющим опытом. Я работал над кодом C#. Я знаю, как создать статичный веб-сайт. У меня степень по информатике.
- Не понимаю, почему мне не позволяют писать программное обеспечение — существует фундаментальное несоответствие между публичными утверждениями, что компании отчаянно ищут инженеров-программистов, и жестокой реальностью отсеивания кандидатов. Эти проблемы кодирования под сильным давлением «сделай или умри» кажутся скорее механизмом дедовщины, чем ценным инструментом оценки. Использовать их — всё равно что стрелять в кандидатов на работу полицейского, прежде чем спросить, что они знают о законе.
- Не знаю, как это выглядит с другой стороны — дело в том, что критикуемый процесс может быть единственным способом, которым компании могут отсортировать хороших и плохих кандидатов. Я никогда не входил в команду по найму, и уверен, что о многом не знаю.
В заключение у меня несколько мыслей:
- Выживание наиболее приспособленных реально — как бы мне ни хотелось устроиться в известную технологическую компанию, в реальности на эту позицию множество конкурентов. Как и во всём остальном в жизни, ресурсов мало, а желающих много. Каждый хочет получать много денег за написание кода. Подозреваю, что такие агрессивные барьеры отбора ставятся по той причине, что кандидатов с объективно (что бы это ни значило) низким уровнем квалификации намного больше, чем с высоким. К сожалению, вам придётся конкурировать с этим огромным количеством людей независимо от вашего опыта. Как понимает любой разработчик, кривая обучения для получения даже минимального опыта очень крута. Кроме того, ключевые компетенции для успешной работы требуют огромного объёма знаний. Реально трудно освоить определённый набор релевантных и востребованных навыков, а тем более в совершенстве овладеть ими. Независимо от того, какой карьерный путь изберёт разработчик, ясно, что конкуренция — это факт жизни, и в этой отрасли она довольно жёсткая.
- Иерархии реальны — меня немного смущают существующие звания инженеров-программистов. Видимо, существует только два: сеньор и не-сеньор. Как правило, объявления о вакансиях сеньора требуют пятилетнего опыта. Кажется, классификация несовершенна. Как назвать человека с двадцатилетним стажем? Так же, как и с пятилетним? В моем случае, как назвать программиста с четырёхлетним опытом? Я не новичок. Я знаю, как самостоятельно писать программное обеспечение. Знаю, как работает контроль версий и Agile. В некоторых ситуациях нужны люди, которые определят направление моей работы. Чтобы ещё больше усложнить этот вопрос, есть проблема количества лет работы с определённой технологией. Если у человека пятилетний опыт Java и он переходит в команду Python, в которой только люди с менее чем двухлетним опытом Python, должен ли этот человек считаться джуниором? Это настолько запутанная тема, что она заслуживает отдельной статьи, и даже тогда не уверен, что смогу прийти к ответу. Моя точка зрения заключается в том, что я где-то между джуниором и сеньором, и это кажется тонким выбором для моего уровня опыта.
- Жаловаться на это бесполезно — рано или поздно мне придётся искать другую работу. Даже если мне не нравится методология, мне придётся снова пройти этот цикл. Но на сегодня с меня довольно. Кажется маловероятным, что я добьюсь чего-то, повторяя один и тот же процесс снова и снова. В конце концов, я снова сяду на эту карусель, но пока выберу единственный вариант, который сохранит моё душевное здоровье:
Выйти из цикла.
См. также: