Если вам понравился этот пост, я был бы рад, если бы вы проверили мой будущий продукт для тестирования производительности и нагрузки браузера: Browserpath.

У меня есть несколько друзей, которые являются «младшими» разработчиками. Недавно один из них рассказывал мне об упражнении на собеседовании, которое им было предложено на должность младшего разработчика Ruby. Я хочу рассказать вам историю того, что произошло, когда я и еще один мой друг пытались решить эту задачу. Мы пригласили двух старших разработчиков на задание для младшего собеседника, и результаты вас поразят. У меня есть несколько могущественных соображений в этой области, и я хотел бы поделиться с вами тем, что я думаю.

Эта проблема

Моего друга попросили реализовать связанный список на Java за 30 минут. "Не проблема!" Я слышу, как ты плачешь. Это была моя первая реакция. Я думаю, что даже для людей без диплома в области компьютерных наук связанный список представляет собой довольно доступную структуру данных.

Хотя я бы вряд ли назвал это очевидным, как только вам представилась идея, что это список узлов, каждый из которых имеет указатель на следующий, ваш мозг может начать понимать, как это будет работать. Вставка берет предыдущий и следующий узел и меняет местами некоторые указатели. Удаление включает перемещение указателя по 1 узлу. При поиске необходимо следовать указателям, пока не найдете нужный элемент. Это одна из первых «не встроенных» структур данных, которую вы изучаете, если изучаете C в университетской программе CS. Связанные списки настолько полезны, что в такой пустой стандартной библиотеке, как C, знание того, как их кодировать, необходимо практически для любых дальнейших упражнений по программированию на CS.

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

Я был сбит с толку, почему мой друг был так взволнован интервью. Именно тогда они объяснили ту часть, которую я упустил. В одном предложении я перешел от восторга от простоты упражнения к ужасу от устрашающей сложности. Они сказали мне: «Интервьюер попросил меня привести его в соответствие со списком ‹T›».

Welp.

Я подозреваю, что у вас есть дела поважнее, чем тратить ее на изучение интерфейсов в стандартной библиотеке Java. Итак, давайте разберемся, что такое List ‹T› на самом деле. List ‹T› - это общий интерфейс Java для всего, что реализует упорядоченную коллекцию, которая может содержать многие из одинаковых значений. Это огромный интерфейс. В нем есть буквально все, что вам может понадобиться для типа данных позиционного списка. У него 25 общедоступных методов. Два из них возвращают дополнительные интерфейсы, которые в сумме имеют 12 общедоступных методов. Это в общей сложности 37 общедоступных методов, которые вам нужно создать и протестировать в реализации. Часть ‹T› означает, что это общий интерфейс. Может принимать любой тип. Это нелепая задача. Повторюсь, моему другу дали 30 минут.

Итак ... действительно ли эта проблема решаема для человека с опытом работы в отрасли менее двух лет? Короткий ответ: нет. Длинный ответ: чтобы точно определить, насколько это неразумно, я хотел «заняться наукой» (для тех из вас, кто знаком с научным методом, не стесняйтесь пробивать дыры в подходе ниже, я, конечно, знаю, что могу). Я мог бы просто выполнить эту задачу самостоятельно. Я «старший» разработчик. Я программировал на Java буквально больше половины своей жизни. Я плохо знаком с инструментами, но глубоко. Количество времени, которое требуется только мне, должно быть разумной нижней границей задачи.

Однако этого недостаточно. Чтобы добиться большего, мы можем добиться большего. Парное программирование - одна из моих любимых техник, позволяющих делать работу быстрее. Это заставляет вас объяснять, что вы делаете, в уме и получать помощь, когда вы устали. Итак, я схватил своего хорошего приятеля Стивена Беста, и мы взялись за решение проблемы. Первые 20 минут мы потратили на настройку инструментов, набросок проблемы, запуск набора тестов и так далее. Мы предполагаем, что в контексте интервью это предусмотрено для вас.

Мы начали довольно быстро. Раньше мы со Стивеном работали вместе 6 месяцев, примерно треть этого времени проводя вместе. У нас есть рабочий процесс TDD, который нам подходит.

Мы начали с того, что Eclipse автоматически сгенерировал для нас полный скелет интерфейса. На тот момент мы были практически готовы приступить к реализации. К сожалению, мы не реализовали задачу, которую взяли на себя.

Лучше всего я могу описать этот процесс - «Долбаный гребаный удар». Одна из приятных особенностей интерфейса List ‹T› заключается в том, что вы можете реализовать одни методы поверх других. Самое неприятное в интерфейсе List ‹T› в том, что он чертовски огромен. Примерно через 6 часов мы сдались. Мы потерпели поражение. Мы не только не смогли завершить реализацию за 30 минут. Мы не смогли завершить реализацию за один присест.

Мы перешли к методу listIterator (), который должен возвращать объект ListIterator ‹T› и объявлять время выхода из системы. Java: когда вы почти закончили реализацию одного массивного интерфейса, из ниоткуда появляется другой.

Мы выполнили все основные операции, большинство с хорошим тестовым покрытием. Я могу указать на тонкости реализации, которые требуются контрактом List ‹T›, которые система типов Java не может выразить достаточно мощно. Эти части контракта оставлены исполнителю для обеспечения их выполнения. Пример того, что мы пропустили, - это доступ к проверке диапазона. С моей реализацией и реализацией Стивенса вы можете полностью запросить элемент в позиции -17 или length + 12, и вы получите исключение нулевого указателя, а не ошибку диапазона. Мы пропустили их, потому что они не соблюдаются абсолютно, и у нас не было времени.

Я даже представить себе не могу, что такое чувство, которое может возникнуть в голове у «младшего» разработчика, когда ему поставят эту задачу. Это работа по разработке Ruby. Я не понимаю, почему этого человека просят реализовать глубокий, широкий и сложный интерфейс на Java. Безусловно, многие идеи объектно-ориентированного программирования можно перенести с Java на Ruby. Может быть, в этом суть собеседования. Единственная причина, по которой я и Стивен смогли выполнить эту задачу, - это то, что я хорошо знаком с построением универсальных систем на Java. Когда вы пишете строки вроде:

private ‹A› A reduceNodes (аккумулятор, NodeCallback ‹A, T› обратный вызов) {

Что включает в себя параметр типа класса, параметр типа метода и обратный вызов анонимного интерфейса, вы явно ушли из глубокой части Java. Мы построили это как абстракцию, чтобы построить остальную систему достаточно СУХИМ способом. Я почти уверен, что даже интервьюер был бы очень сбит с толку, если бы вы сделали это во время интервью. Возможно, мы со Стивеном не смогли бы получить работу младшего разработчика Ruby, если бы прошли это собеседование. Может, это красный флаг.

Итак, давайте немного поговорим о том, что это означает, прежде чем двигаться дальше. Это интервью «думаешь под давлением». Вы даете кому-то проблему, которую он явно не может решить за отведенное время. Повторяю: Я почти уверен, что никто не сможет создать связанный список List ‹T› за 30 минут. Это действительно нечестно. Сразу же вы случайным образом фильтруете людей, которые хорошо мыслят, с которым большинство программистов не сталкивается каждый день. Хуже того, вы подорвете доверие многих людей. В следующем разделе мы рассмотрим несколько причин, по которым я думаю, что мы делаем это с младшими разработчиками.

Лига плюща CS Shibboleth

Итак, если собеседование не фильтрует людей, которые могут его выполнить, для чего оно фильтруется? Что ж, вашу реакцию на невозможную проблему невозможно измерить объективно. Вместо постановки задачи, когда интервьюер измеряет «завершил или не завершил», он дает интервьюеру возможность принимать субъективные решения.

Люди странные. Мы запрограммированы на создание племен. Племена - это доисторические группы людей, которые были к нам ближе всего (в географическом смысле). Это означает, что это люди, похожие на нас, и мы стараемся их максимально фильтровать. Предоставление интервьюеру возможности принимать субъективные решения почти наверняка означает, что в конечном итоге они выберут людей, которые больше всего на них похожи. Это одна из причин, почему многие компании, возглавляемые людьми с опытом работы в сфере информационных технологий, любят проводить собеседования с помощью досок. На собеседовании с помощью интерактивной доски очень хорошо отбираются люди с дипломами в области CS из хороших университетов. Привилегия порождает привилегии и все такое.

Здесь проблема. За последние несколько лет мы стали свидетелями огромного всплеска числа людей, не связанных с CS (назвать это нетрадиционным кажется шуткой, учитывая возраст нашей отрасли), людей, пришедших в отрасль. Эта новая волна молодых разработчиков в основном прибывает из буткемпов. На учебных курсах не учат, как построить красно-черное дерево или как реализовать хеш-таблицу на C. В этом нет необходимости. Большинство их разработчиков не собираются останавливаться там, где им нужно делать эти вещи изо дня в день. Хорошо. Это довольно редкий день, когда мне нужно получить степень CS, когда я работаю над приложением Rails.

В большинстве случаев собеседования, проводимые с помощью досок, на самом деле очень хреновые. Я сделал несколько из них в своей жизни. Мне буквально ни разу не перезвонили. Я белый цис-мужчина со степенью магистра CS. Так что, по крайней мере, анекдотично, фильтр «выбирайте для таких людей, как мы», похоже, не работает так хорошо. Я полагаю, что моя основная проблема с собеседованиями с использованием интерактивной доски заключается в том, что я считаю их серьезным отрывом от реальной работы, которую выполняет большинство людей.

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

Я слышал, что в некоторых учебных курсах для начинающих есть специальные занятия, посвященные обучению младших разработчиков заучивать ответы на вопросы доски. Манипулирование указателями, работа со структурами данных, которые вам не нужны для создания приложения rails, и т. Д. И все потому, что без этих курсов у студентов CS будет невероятная выгода в этих произвольно структурированных собеседованиях. В свое время я встречал много выпускников учебных курсов. Многих из них я охотно найму на каждого студента последнего курса CS, которого я знаю в настоящее время.

Итак, выпускники буткемпа:

  • Они вещь.
  • Они действительно хороши.
  • Если вы нанимаете младшего разработчика Ruby, у вас гораздо больше шансов найти кого-нибудь на учебном семинаре, чем на программе CS.

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

История интервью со старшим разработчиком

Я хотел бы рассказать вам об опыте собеседований со «старшими» разработчиками. И мои собственные, и чужие. С точки зрения наблюдения, элемент «доска» полностью отсутствует на старшей стадии. Часто, но не всегда, этап «кодирования» интервью также проходит. Большинство этих собеседований имеют форму технического обсуждения с интервьюером. Я обычно обнаруживаю, что есть некоторые предположения, что вы могли бы быть более умелыми, чем человек, интервьюирующий вас. Таким образом, они готовы выслушать все ваши идеи и задать много уважительных вопросов о том, почему вы делаете то или иное дело.

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

Техническое обсуждение - лучшее место для начала интервью. На человека не оказывают давления. Вместо этого у человека появляется возможность поговорить, исправить предыдущие ошибки, выслушать, отреагировать и, как правило, узнать о человеке. Общение - это самое важное, что мы делаем как разработчики. Все компьютерные проблемы - это проблемы людей. Давайте возьмем такое интервью. Выходя из технической дискуссии, обычно чувствуешь себя довольно хорошо. Собеседники любят рассказывать о своих расчетах. Интервьюеры любят слышать эти расчеты и реагировать на них. Мы будем работать вместе, если сможем работать вместе, исходя из того, насколько разумны наши реакции, готовы ли мы уступить место, где мы ошибаемся, и, в целом, продемонстрировать, как нам нравится работать.

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

Заключение: лучшие интервью с юниорами.

Один из моих других друзей в настоящее время проводит ряд собеседований с младшими разработчиками и изучает CS уровня 101 как сумасшедший. Это окупается. Я думаю, что так быть не должно. На протяжении двух лет они неоднократно демонстрировали способность писать производственный код, с которым сталкиваются десятки тысяч людей. Им не нужно «учиться», чтобы получить работу на уровне, эквивалентном тому, который у них уже есть. Они должны иметь возможность говорить о своей повседневной жизни, о том, что они делают, а что нет. Им следует обсудить то, что они изучают, каковы другие разработчики в их команде и в какой среде им комфортно работать.

Информатика прекрасна, интеллектуально интересна и ценится каждым, кто занимается программированием. Большинство людей не используют большую часть того, чему они научились, получая степень CS, в своей повседневной работе по программированию. Хорошо! Это, однако, означает, что мы не должны фильтровать людей, имеющих степень CS, в наших собеседованиях для этих вакансий.

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