Прочитав этот пост, написанный farwayer, сначала хотел просто оставить комментарий, но, подумав пару десятков минут, решил, что тема глубокая, и мне есть что сказать на целый пост. Все таки, с одной стороны, я один из тех, кто на собеседованиях не смотрит на код и кого разочаровывает незнание оценки сложности поиска по индексу в реляционных СУБД, с другой, считаю, что могу дать понимание того, как мыслит достаточно большой кластер интервьюверов, зачем они поступают (на первый взгляд) нелогично и деструктивно, и какие проблемы сами хотят этим решить. Есть надежда, что понимание картины мира «врага» само по себе ответит на множество вопросов.
Для начала расскажу о себе. Надеюсь, что это лучше поможет осознать описанное ниже. В разработке ПО 9 лет, некоторое время работал на себя (создавал биржевых роботов и торговал на собственные деньги), основное время был наемным разработчиком (в том числе lead developer). С недавнего времени занимаю продуктовую должность. Собрал 2 команды senior уровня. Провел несколько десятков (хотя и меньше 100) технических собеседований на позиции middle2senior, senior, lead. В аутсорсе не работал ни дня за всю жизнь провел 18 дней. Поэтому, могу сказать, что весь опыт связан с продуктом (собственным или нанимателя), и все собеседования проводил с мотивацией «найти человека, который принесет максимальную пользу продукту». Признаю, что опыт автора исходной статьи больше моего, но цель, — не рассказать, как правильно, или дать совет, как надо поступать, а рассказать, как можно на те же вещи посмотреть с другой, альтернативной, и не факт, что правильной, точки зрения.
Поехали по пунктам (названия взяты из оригинального поста).
Никому нет дела до твоего кода
Прежде всего вопрос в том, а что такое хороший код и какие ожидания от кода, который производит опытный программист. Для меня хороший код — это функция от задачи, условий, в которых эта задача поставлена, принятых в команде (компании) гайдлайнов, ожиданий техлида (архитектора), менеджера по продукту, лид QA. К примеру, рассмотрим несколько задач:
- Разработать API для последующей выдачи его всем пятистам B2B клиентам компании для интеграции продукта в их решения, — ожидается продуманное и хорошо документированное решение с максимально понятной структурой, соответствием принятым на рынке стандартам, максимально строгой валидацией данных, полным покрытием тестами, расширяемостью, продуманным логгированием, соблюдением всех требований безопасности, масштабируемостью по производительности, устойчивостью к хотя-бы примитивным примерам DoS и DDoS;
- Реализовать соответствие продукта требованию регулятора, которое вступает в силу через месяц, и может привести к остановке всего бизнеса, — ожидается надежное решение с упором на тестирование;
- Пофиксить баг на проде, связанный с кешированием, о котором стало известно за час до наступления Черной Пятницы, — ожидается, что решение будет написано и развернуто на проде за 30 минут и ничего не поломает. Другие требования уходят на второй план;
- Проверить гипотезу, для которой надо разово спарсить 250 страниц сайта конкурента, после чего на их основании сформировать для бизнес-аналитика документ в google spreadsheet, — ожидается, что программист не будет делать лишней работы и напишет write-only код, не затратив на это много времени;
- Проверить производительность Aerospike на задаче, для которой традиционно в компании используется PostgreSQL, и наблюдаются проблемы с производительностью, — ожидается, что будут учтены алгоритмические нюансы и профиль нагрузки, но при этом весь код пойдет на выброс вне зависимости от результатов эксперимента.
Согласитесь, что неправильно оценивать код, закрывающий все эти задачи по одним лекалам. А ведь, от хорошего программиста в продуктовой разработке часто ожидают эффективного решения всех вышеупомянутых задач. Практика показывает, что эффективность программиста во всех этих кейсах проще определить кейсовыми вопросами и обсуждением опыта, чем рассматриванием кода, написанного при неизвестных для интервьювера переменных. Плюс, код, который собеседуемый хочет показать != код, который он пишет, решая коммерческие задачи.
Торжество бесполезных знаний
Отлично пониманию негодование, связанное с
А то, что поиск по B-tree индексам в PostgreSQL имеет логарифмическую сложность? Я вчера узнал, вот теперь и вы
Но что с другой стороны? Баги, связанные с алгоритмической сложностью, одни из самых неприятных для бизнеса. Они не покрываются юнит тестами (O(N^2) при тестовом запуске, где N=10, это реально быстро), они не покрываются автоматическими, интеграционными, регрессионными и ручными тестами по той же причине. Они не всплывают на dbe, uat, sit (ведь для N=1000 это все еще быстро). Они могут ждать своего часа годами, не напоминая о себе, пока один покупатель не добавит себе в корзину 250 продуктов, или пока не появится клиент брокерской компании, решивший собрать себе HFT-робота на коленке. Но, когда они проявляются, поплохеть может всему бизнесу.
Сюда же относятся и вопросы про ACID. Баги, связанные с блокировками в СУБД, race condition, транзакциями в СУБД, — это тоже самая мякотка для бизнеса. Они точно так же, как и баги, связанные с алгоритмической сложностью, могут сидеть тихо годами и ударить очень больно. Когда основная оперативная СУБД компании, развернутая на монструозном сервере с максимальным резервированием всего, просто останавливается с нулевой нагрузкой на CPU и IO в момент максимальной активности клиентов, поверьте, это крайне неприятно и, да, это может стоить годовой зарплаты команды программистов. Поэтому, знать наизусть каждую букву ACID не нужно (по крайней мере, я никогда не спрашиваю знания расшифровки аббревиатур да и сам не помню их наизусть), но вот незнание сути каждой из букв — это уже серьезная заявка на внедрение в код подобных багов. Если программистов с таким незнанием в команде двое, то code review тоже не станет лечением.
Тебя валят
А тут вот это. И ребята вроде адекватные. Фиг пойми. А потом видишь, что вакансия полгода открытой висит. Ну-ну.
То, что на сайте компании (или на аггрегаторе вакансий) доступна вакансия, не означает, что компания ищет одного человека в одну команду. Реальность продуктовых компаний в период роста — это вечный кадровый голод. Или масштабируешься, захватываешь рынок, выдавливаешь конкурентов, или умираешь. И у менеджера по продукту вечная головная боль — «что выкинуть». Не «а чего бы крутого такого придумать, чтобы 100 программистов загрузить на месяцок, чтобы не скучали», а что бы из крутого, нужного, запланированного и ожидаемого (и обещанного) клиентами выкинуть из планов, чтобы не затянуть очередной релиз на год. Поэтому, нет лишних рук, и тот факт, что вакансия полгода висит, не отменяет факта, что 10 человек по ней уже нашли и взяли на работу, и с удовольствием возьмут еще столько же. Снова таки, не везде и не всегда, но описанная мною ситуация нормальна и допустима для продуктовой разработки.
Пофигу на прошлые проекты
Я всегда спрашиваю. Так что, тут полностью согласен с автором. Но точка зрения части тех, кто не спрашивает, мне ясна тоже. Эти люди часто не понимают, как сравнивать разный опыт различных кандидатов между собой. Ответы на закрытые вопросы им сравнивать проще.
Опытные разрабы
Тут есть важный момент. Что, да, опытный и сообразительный разраб быстро вникает. Но если уж человек заявляет что много работал с условным OAuth на нескольких проектах (важно, именно так, а не «как-то разок использовал в прототипе»), а интервьювер тоже работал с OAuth, то почему бы и не поспрашивать? Глубина ответов покажет, насколько человек будет глубоко вникать в новые, встретившиеся на пути технологии, понимает ли подкапотные принципы, или копирует с SO, пытается ли предвосхитить грабли.
Еще несколько мыслей
Но и тут можно выкрутиться, дав небольшое тестовое на час-два (только не на месте: для многих собеседование это всё-таки стресс).
Тут могут быть разные мысли на этот счет, но лично я считаю тестовое задание оскорбительным даже для middle уровня. Все таки, тестовое задание, — это очень сильная диспропорция по затраченному времени компании и соискателя. Условно, соискатель тратит 3 часа на написание кода + еще 5 на вылизывание и поиск лучших практик в гугле, а представитель компании за 1 минуту дает вердикт. Для этого соискателю нужна мотивация. Поэтому, хорошая практика, но не для оценки опытных и востребованных программистов, которых готовы брать и без тестового.
И мысли по интересному комментарию от loppi
А если есть проблема, для которой я не знаю сходу решения — всегда можно изучить вопрос и найти это решение.
Интервьюверу важно не просто факт, что соискатель изучит вопрос и найдет решение. Важно, как он это сделает, — рассмотрит ли все варианты, или найдет первый попавшийся, как отреагирует на столкновение с фактом, что избранный вариант решения несостоятелен, и надо искать новый, и так далее. Для разных обстоятельств могут быть различные ожидания.
Только одно собеседование кардинально выделялось из общей массы, разговор шел тет-а-тет с техдиром, он распросил с какими технологиями я работал, а потом мы разговаривали про различные проблемы на их проекте и на моих прошлых проектах, и как эти проблемы решались или можно решить.
Да, отличный способ собеседования (сам так считаю и использую), который хорошо дополняет другие вопросы. И, что странно, есть огромный % senior разработчиков, которые отлично знают теорию и имеют реальный многолетний опыт, но при этом крайне слабо себя показывают при попытке решить задачу с большим количеством степеней свободы. Из минусов этого способа собеседования, что он требует длительной подготовки (из реальных кейсов надо извлечь суть, опустив ненужные детали и обобщив) и может быть неэффективным, если ключевые вызовы как соискателя, так и собеседователя были специфичными.
Автор: algotrader2013