Я занимаюсь разработкой больше 10 лет, прошел множество разных собеседований на самые разные позиции, и вот какая мысль сегодня пришла мне в голову. Ни на одном собеседовании мне не задавали вопросов, которые бы действительно осветили мой опыт и знания, а главное - ценность как сотрудника, эффективно решающего задачи.
На написание статьи меня подтолкнула собственная боль, пронесенная через года, размышления о роли Google и GPT в работе программиста и старый анекдот про инженера и объем резинового мяча.
Анекдот
Физику, математику и инженеру дали задание — найти объём красного резинового мячика. Физик погрузил мяч в стакан с водой и измерил объём вытесненной жидкости. Математик измерил диаметр мяча и рассчитал тройной интеграл. Инженер достал из стола свою «Таблицу объёмов красных резиновых мячей» и нашёл нужное значение.
КДПВ взята с devhumor
UPD. Дискуссия в комментариях заставила меня добавить дисклеймер. В дальнейшем тексте я выступаю в качестве соискателя, а не интервьюера. Я привожу список вопросов, которые я хотел бы услышать именно в качестве потенциального сотрудника. Также я не утверждаю, что все интервью должно состоять исключительно из этих вопросов. Это дополнение к техническим вопросам и лайв-кодинг сессии, которое показывает способность кандидата реализовать не просто рабочий код, но качественную систему, минимизировать количество ошибок и обеспечить быстрый SLA при их возникновении, так как наибольшие затраты времени требуются именно для диагностики и решения проблем продукта после релиза.
Большинство алгоритмов, паттернов проектирования и прочих стандартных решений (и даже критерии их выбора под конкретную ситуацию) сегодня можно найти в интернете, а еще проще - попросить ChatGPT сгенерировать код. Именно поэтому я считаю, что наличие этих знаний у современного разработчика сильно переоценено. Хороший инженер всегда знает, какой справочник нужно использовать.
Однако есть класс прикладных (особенно с точки зрения бизнеса) задач, которые не решаются одним лишь справочником, а требуют определенного набора знаний и опыта. Именно эти задачи и определяют программиста как эффективного сотрудника, и именно вопросы о них я бы хотел слышать (и задавать) на собеседованиях. Кроме того, я верю, что человек, который ответил для себя на эти вопросы, действительно является хорошим программистом уровня Middle+. Я постараюсь не давать свои ответы на эти вопросы, так как абсолютно правильного ответа чаще всего нет - все зависит от конкретной ситуации и команды.
Так как большинство моего опыта связано с Java и Web-сервисами, заранее извиняюсь за возможный перекос в эту сторону.
Дизайн и архитектура
Основная цель этих вопросов - понять, насколько разработчик умеет работать в команде и грамотно расходовать ресурсы (время и деньги) компании. Оптимальная скорость и удобство разработки часто определяется тем, насколько сложен код в чтении и поддержке.
Когда стоит закладывать в код расширяемость, а когда нет?
Никто не любит слишком большого количества абстракций. Хороший разработчик должен понимать, а еще лучше - уметь спрашивать у руководителя (Product Owner-а, например), какие планы по развитию функциональности у приложения, которое он разрабатывает. Нет смысла использовать фабрики фабрик, мудреные стратегии и фасады, если код предполагается написать один раз и лишь поддерживать в дальнейшем. Пример - утилиты, скрипты командной строки, миграции. И наоборот, хорошим тоном будет заложить расширяемость в те места, которые предполагается развивать в будущем. Даже если не планируется развивать, но есть прогноз на интенсивное использование - стоит это сделать, так как в дальнейшем с увеличением кодовой базы, резко возрастает цена поддержки и модернизации. Сервисы, комплексные фронтенды, API, библиотеки - в них стоит продумать точки расширения, едва написав первую абстракцию.
Как бы вы распределили код по пакетам/модулям/директориям?
Все современные языки в том или ином виде поддерживают такую возможность, и при работе в команде крайне важно ее правильно использовать. Об это сломано много копий, но в целом можно выделить две концепции распределения кода: по техническому назначению и по доменной принадлежности. Важно понимать, какую концепцию лучше использовать в разработке конкретного приложения и исходя из целей и привычек команды. Так, например, вынесение по техническому назначению очень хорошо (на мой взгляд) подходит микросервисам и небольшим приложениям. Монолитный же сервис есть смысл организовать по доменам - таким образом, чтобы код, связанный по смыслу, находился рядом.
Как использовать чистые функции и функции с состоянием?
Чистая функция - это функция, которая принимает входные данные и возвращает результат, не меняя глобальное состояние программы (состояние между вызовами). Часто их использование связано с дополнительными расходами памяти, однако делает программу более читаемой. Промежуточное хранимое состояние в свою очередь часто позволяет повысить производительность, но при этом создает дополнительные ограничения и взаимосвязи. Так, например, разнообразные лексеры и парсеры часто реализованы с сохранением состояния в объекте (паттерн "Посетитель") и поэтому ограничены в многопоточном использовании, например, многострадальный java.util.DateFormat. В то же время, чистые функции могут быть использованы без опасений.
Большинство остальных вопросов, таких как конкретные архитектуры и их применения, я считаю слишком частными. В дальнейшем я еще вернусь к дизайну и архитектуре, но это произойдет в рамках блока о качестве и тестировании.
Логирование и диагностика
Здесь мы снова возвращаемся к вопросу эффективного использования ресурсов. Большинство самых трудоемких задач относятся к диагностированию и разбору ошибок. Вне зависимости от того, как в компании организован сбор, хранение и анализ логов, разработчику важно понимать, как он может ускорить диагностику проблем бизнеса в случае сбоев.
На каком этапе необходимо закладывать возможности диагностики?
В общем случае, чем раньше - тем лучше. Я встречал множество разработчиков, которые добавляют логирование только тогда, когда что-то сломалось в продакшне. Чем раньше мы заложим возможности диагностики и выработаем культуру логирования, тем меньше будут расходы на диагностику в будущем.
Что и на каких уровнях логировать?
В разных средах и в разных ситуациях нужно понимать, что логировать и на каком уровне. Так, в боевом окружении довольно часто включено логирование только на уровне информации (в целях повышения производительности), а на тестовой среде - добавлено отладочное логирование. Однако информационные сообщения в стиле "Job completed" часто не помогают в диагностике, а только раздражают. Разработчик должен уметь оценивать количество данных, которые он хочет использовать в диагностике на каждом окружении. В то же время, если писать в информационные сообщения все параметры, переданные методу, это может вызвать накладные расходы (например, на строковое представление и сериализацию), поэтому такие сообщения нужно выносить в уровень отладки или трассировки.
Что такое сквозная трассировка идентификаторов и как ее использовать?
В многопоточных приложениях, таких как Web-сервисы, не всегда можно абсолютно точно идентифицировать, какие сообщения лога относятся к каким операциям. В Java, например, для этого служат MDC/NDC. Они позволяют задать сквозные идентификаторы, которые в дальнейшем позволяют сгруппировать сообщения лога в рамках одного конктекста (в базовом случае - потока). В асинхронных средах (таких как реактивные фреймворки с переиспользованием потоков) это может быть реализовано сложнее, но это не умаляет важность использования сквозных идентификаторов. Программист должен уметь выбрать идентификаторы и знать как настроить их сквозную трассировку.
Как организовать вывод ошибок пользователю?
Важно понимать, какая информация должна показываться конечному пользователю, обеспечить возможность предоставить технические детали поддержке и ускорить диагностику. Если мы говорим о трассировке стека, важно понимать, насколько доступ пользователя к трассировке может подвергнуть приложение возможности реверс-инжениринга и проникновения. Есть разные пути предотвратить это и при этом не усложнять диагностику: уникальные идентификаторы сообщений (в случае серверов), коды ошибок, уникальная формулировка сообщений. Выбор способов зависит от конкретного приложения и среды запуска.
Качество и тестируемость кода
В этом блоке вопросов я уделяю больше всего внимания двум аспектам. Во-первых, это конкретно юнит-тесты, так как из всего многообразия уровней тестирования, именно за юнит-тесты чаще всего отвечает непосредственно разработчик, и именно с неумением их проектировать и писать связано большинство проблем. Во-вторых, это взаимодействие с отделом контроля качества при проведении остальных видов тестирования.
Что такое тестируемость кода и как ее обеспечить?
В общих чертах, тестируемость кода - это количество трудозатрат на написание тестов. Код, который спроектирован с учетом необходимости писать тесты, потребует меньших трудозатрат на их написание. Существует множество подходов к написанию собственно тестов (тот же TDD, к примеру), и выбор конкретного подхода не является сутью этого вопроса. Здась гораздо важнее поговорить об архитектуре приложения, разбиении его на отдельные изолированные блоки. Так, с большой вероятностью, человек, который озабочен тестируемостью своего кода, следует принципам SOLID автоматически. На примере Web-приложения тестируемость проявляется в разделении REST-контроллеров, сервисов, трансформеров и слоя доступа к данным. Если вся логика (даже самая правильная) сложена в REST-контроллер, тесты будут максимально комплексными и трудозатратными. С другой стороны, при грамотном разбиении на функциональные части, можно отбросить (поставить заглушки) на каждый из слоев и протестировать, например, бизнес-логику, доступ к данным и соблюдение REST-контракта, по отдельности. Такие тесты будут небольшими, изолированными и простыми в поддержке.
Как можно приоритизировать тесты? Что покрывать в первую очередь?
Как правило, наибольшие проблемы возникают там, где имеются неконтролируемые входные данные. Пользовательский ввод, данные третьих систем при интеграции - все это потенциальный источник проблем. С другой стороны, крайние ситуации (corner cases) в бизнес-логике так же часто являются неочевидными. Разработчик должен понимать, с какой системой он работает, и в зависимости от этого выбирать, какую ее часть наиболее экстенсивно покрыть тестами. Очень хорошо, если есть возможно согласовать покрытие юнит-тестами с отделом тестирования, подключить аналитиков для выявления нестандартных ситуаций и реакций на них. Очень часто тестами покрываются только позитивные сценарии, но важно правильно приоритизировать и протестировать так же поведение в негативных.
Ревью кода и работа в команде
Очень часто про это так же забывается, как и про тестирование. Однако ревью кода повышает уровень взаимодействия в команде и общее качество продукта (хотя оно и отбирает время на первый взгляд, в долгосрочной перспективе это не так).
На что вы обращаете внимание при ревью кода в первую очередь?
Мы все люди, у каждого свой уровень и свой способ мышления. Возможно, разработчик, который зацепляется за выбор библиотеки, но игнорирует покрытие тестами, привнесет в процесс ревью больше токсичности, чем реальной пользы. Что действительно важно в процессе ревью - это понимание разработчика, что для команды важнее на этом этапе, как сформировать культуру кода, которая будет устраивать всех. Правильно расставленные приоритеты при ревью существенно повышают общую эффективность.
Общий вывод
Я довольно часто слышу на собеседованиях вопросы про HashMap/TreeMap, различные реализации List и основы JDBC, даже на вакансии уровня Senior. Все это безусловно важно, но инженер уровня Middle+ должен обладать этими знаниями по умолчанию. В конечном счете, в большой бизнес-машине важна именно производительность сотрудника и его экономичность. Все выливается не в конкретные знания библиотек, особенностей, алгоритмов, а в способность писать читаемый, поддерживаемый и масштабируемый код, который может быть передан любому другому сотруднику без потери его (любого сотрудника) производительности.
А что вы бы добавили/изменили в этом списке?
Комментарии (71)
Kostik_s_v
12.04.2023 13:54+7Все выливается не в конкретные знания библиотек, особенностей, алгоритмов, а в способность писать читаемый, поддерживаемый и масштабируемый код, который может быть передан любому другому сотруднику без потери его (любого сотрудника) производительности.
Золотые слова, многие не понимают этого, и работать потом приходится с «самыми начитанными и умными» но совершенно безрукими…
tatar88t
12.04.2023 13:54+5Так а где вопросы то в итоге? То что здесь представлено это так темы для дискуссии. Конкретных ответов на них нет, тем более никакой конкретики в самих вопросах нет. И соответственно критериев правильности ответов тоже никаких нет. И получается просто вкусовщина. Вы просто будете ждать какого то конкретного, удовлетворяющего именно вас ответа на такой вопрос, а учитывая что конкретики там нет кандидат может начать рассказывать совсем не то что вы ожидали.
sickfar Автор
12.04.2023 13:54Так и тема в целом философская и дискуссионная. Я практически в начале оговариваюсь, что стараюсь не писать свои четкие ответы. Впрочем, почти к каждому вопросу я даю рекомендацию, о чем может говорить ответ.
Например, если говорить об организации каталогов, лично я предпочитаю доменную, но в моей нынешней команде принята организация по назначению. Что из этого правильно? Правильно то, что принято в команде, но важно обсудить причину, плюсы и минусы.
Вы попробуйте для себя лично ответить на каждый вопрос. Можете сформулировать конкретное мнение (конктретную методику) и обосновать его выбор?
Для меня оказалось, что когда на собеседовании вообще не спрашивают про тестабилити кода, то в компании "не принято" писать юнит тесты. И если мы не говорим про диагностику, то в логах просто свалка. И наоборот, если мы в процессе хотя бы поверхностно затрагиваем эти темы, то культура кода в компании находится на довольно приятном для меня уровне.
poterin
12.04.2023 13:54+5Плохой интервьюер проверяет знания кандидата, хороший - его мировоззрение. Утрировано конечно, одно другому не противоречит, но, тем не менее, компании, как правило, нужен не справочник, а хороший работник, который будет выдавать результат и не создавать проблем. Именно это и требуется выяснить на интервью.
piton_nsk
12.04.2023 13:54+1В целом да, но есть нюансы. Если кандидат наврал в резюме с три короба, или приходит выпускник, который 6 лет учился на ИТ специальности, и вообще ничего не знает, вот буквально. Это мировоззрение или нет?
Когда говоришь вот с таким выпускником, буквально уже не знаешь что и спросить, знает он хоть что-нибудь или нет. Со стороны кандидата, наверное, это выглядит как будто злой интервьюер валит самыми разными вопросами, лишь бы докопаться.
poterin
12.04.2023 13:546 лет учился на ИТ специальности, и вообще ничего не знает, вот буквально. Это мировоззрение или нет?
Конечно мировоззрение! Если человек "6 лет учился на ИТ специальности, и вообще ничего не знает", то этот человек смотрит на мир как раздолбай, потому что это и есть раздолбай.
vvbob
12.04.2023 13:54С другой стороны. Я как-то присутствовал на одном собесе, в качестве зрителя (ну так вот получилось) и искренне сочувствовал соискателю. Как по мне вполне себе толковый синьор, работавший лидом довольно продолжительный срок, был буквально слит примитивными вопросами для джунов. Было вполне заметно что человек не может ответить не потому что полный ноль в теме, а просто оттого что давно не приходилось во всем этом копаться, проблемы и задачи, которые он решал, были намного более высокоуровневые. Попыток поспрашивать о чем-то сложнее чем "перечислите все методы класса Object" даже не было, ну и правда, ведь он полный ноль и самозванец - о чем тут спрашивать! А на прошлом месте видимо просто дурачки были, что за пяток лет не заметили мошенника, который от мидла-- вырос до синьора-лида.
piton_nsk
12.04.2023 13:54Безусловно собеседование для джуна и синьора должно быть разным. Но люди бывают преувеличивают, а иногда и просто банально врут. Встречались советы наврать о своем опыте. Может он сеньор, а может пытается проскочить на авось, он вообще говоря ничем не рискует. Не пройдет собес, да и ладно.
Я когда-то тоже удивлялся, почему мне такие примитивные вопросы задают? Я же и тут работал, и там., знаю то, знаю это. В резюме написано, читайте, спрашивайте. А когда впервые оказался с другой стороны (сначала просто присутствовал, потом уже самостоятельно), то реально офигел от того, как резюме приукрашивают, а то и врут. Поэтому несколько простых вопросов для разогрева это нормально. А вот если уж сеньор-помидор их не знает, ну это уже на размышления наводит. Может забыл, а может никогда и не знал.
А на прошлом месте видимо просто дурачки были, что за пяток лет не заметили мошенника, который от мидла-- вырос до синьора-лида.
Вообще говоря, может и были, разве мало бывает дурачков, или вы их знаете и точно уверены что не дурачки? Это же не аргумент, что дорос, иначе надо брать без собеса, если на прошлой работе с миддла стал лидом. Из смешного на Хабре была статья про 17-летнего сеньора, в билайне явно не дурачки, стало быть, надо предлагать оффер. А может и не дурачки, просто учились вместе, пиво пили в одной тусовке, общаются хорошо, где надо промолчит, где надо выскажется, вот и вырос, и такое бывает. А может у них просто так принято, что растут по выслуге лет и/или знанию местных уникальных велосипедов. Вариантов куча на самом деле. Вы сами-то как поняли, что сеньор прям сеньор? Ведь до серьезных вопросов дело не дошло, а на несерьезных он посыпался.
sickfar Автор
12.04.2023 13:54Вы категорически правы! Я в начале своей карьеры работал в телеком галере (широко известной в узких кругах), их продукт - фреймворк с безграничной возможностью конфигурации через дб модель и интерфейс модулей (и немного можно дописать джаву). Оттуда вышли десятки Senior Developer с опытом 10+, которые писали код от силы 20% этого стажа, а все остальное время занимались накликиванием конфигураций. Мой друг до сих пор там работает сениором, потому что его даже миддлом не берут, и уж тем более на зп, которую он хочет.
dom1n1k
12.04.2023 13:54+1Попыток поспрашивать о чем-то сложнее чем "перечислите все методы класса Object" даже не было
Тут важнее не то, насколько этот вопрос сложный или простой, а то что он справочный. Это так себе практика для собеседования любого уровня.
vvbob
12.04.2023 13:54+1Именно! Часто задают такие вопросы, ответы на которые нормальный специалист быстро нагуглит, оттого в памяти и не держит, либо держит только когда работает вот прямо сейчас по этой теме. Что-то вроде подробностей использования clone() из того-же Object, подавляющее большинство разрабов этой штукой в обычной работе не пользуются (напрямую, по крайней мере) и все эти тонкости если и знали, то уже основательно забыли, зачем о таком спрашивать? Ну вдруг понадобится мне погрузиться во все это клонирование - залезу в исходники посмотрю, почитаю доки, хелпы, разберусь быстро, а помнить все это постоянно..
event1
12.04.2023 13:54Что это за мировоззрение такое и почему интервьюеру до него должно быть дело? Интервьюер проверяет обладание нужными навыками. Если он делает это точно, то он хороший.
poterin
12.04.2023 13:54+1А вот и нет. Человек с нужными навыками может по итогу быть плохим работником, как и наоборот. И таких случаев полно.
event1
12.04.2023 13:54Умение взаимодействовать с людьми — это тоже навык. Если вы об этом. Если же вы о том, что работник может оказаться, скажем наркоманом или прогульщиком, то это вряд ли можно проверить на интервью. Тем более изучая "мировоззрение" кандидата.
murkin-kot
12.04.2023 13:54+7На самом деле за кучей слов вижу одно простое желание - интервьюируемый должен быть приятен лично мне. Всё, больше автору ничего на самом деле не надо.
Объясняю. Все эти микросервисы и чистые функции есть очень зависящие от контекста инструменты. Поэтому всегда (подчеркну - именно всегда) можно указать на ситуацию, когда любимый интервьюирующим подход хотя бы относительно полезен и вполне работает. Отсюда следствие - интервьюирующий сегодня может ожидать от интервьюируемого любую чушь, лишь бы она укладывалась в мировосприятие интервьюирующего, потому что для любых странных вещей всегда можно придумать ситуацию, когда эту странность можно как-то использовать.
Разве правильно строить софт на основе личных предпочтений свободных художников? Но именно о таких предпочтениях весь текст.
В общем случае это называется "локальная оптимизация". Именно ею сегодня страдают подавляющее большинство людей, называющих себя тим-лидами или архитекторами (и именно они проводят интервью).
Противоположность локальности - глобальная оптимизация. Но привычка подчиняться строгой иерархии заставляет смело расписывающих преимущества чистых функций внезапно переходить на поддакивание начальству. И если кто-то где-то сверху решил, что он хочет микросервисы, то задача наёмного архитектора/тимлида состоит не в указании на набор проблем, вытекающих из такого выбора, но в нахождении обоснований требований начальника. То есть задача оптимизируется под заведомо непрофессионально поставленные ограничения, что является типичным случаем локальной оптимизации. Но да, для глобальной оптимизации нужно подвинуть начальника, что в подавляющем большинстве случаев невозможно.
Как минимум, хотелось бы, что бы читатели представляли себе контекст, в котором варятся разработчики, то есть понимали бы неизбежность требования оправдания любых безумств в обмен на приём на работу. Ну и, обладая пониманием контекста, читателям станет проще понимать подноготную подобных статей, описывающих исключительно личное мнение отдельно взятого индивида, хотя и, к сожалению, весьма распространённое среди тех, кто проводит отбор на должность разработчиков.
Или короче - автор не обязательно прав. Правоту определяет глобальная выгода. Далее всё зависит от умения читателя видеть картину именно глобально.
sickfar Автор
12.04.2023 13:54+2Не совсем с вами согласен. Тестируемость и диагностируемость кода - вполне конкретные критерии. Подходы могут быть разными, и уж тем более они зависят от стека. И как раз эти подходы уже обсуждаемы и могут быть приятны/неприятны (чаще всего я все-таки ориентируюсь на командную культуру, а не личные предпочтения).
Кандидат может классно знать все виды сортировки, но когда продакшн завалится из-за того, что он перепутал плюс и минус в вычислении (банальная человеческая ошибка), то проблема тут как раз в том, что 1) он не сделал диагностируемый сервис 2) он недостаточно обеспечил его тестируемость. Компания потратит сотни денег на воспроизведение и фикс. И с точки зрения компании, этого можно было избежать, если бы эти вопросы были обсуждаемы на интервью.
murkin-kot
12.04.2023 13:54+5Тестируемость и диагностируемость кода - вполне конкретные критерии
И где конкретика? Сколько и каких метрик вы считаете достаточными? Почему? Вы уверены, что при смене контекста все ваши расчёты не окажутся неправильными?
Подходы могут быть разными, и уж тем более они зависят от стека
А как от стека зависит прибыль фирмы, нанимающей программистов? Мне кажется - практически никак (в стандартной области с учётно-распределёнными системами).
но когда продакшн завалится из-за того, что он перепутал плюс и минус в
вычислении (банальная человеческая ошибка), то проблема тут как раз в
том, что 1) он не сделал диагностируемый сервис 2) он недостаточно
обеспечил его тестируемость.Не согласен. В большинстве случаев - кто-то банально переусложнил код. И обычно это не джун, поскольку у старших товарищей есть все права для диктовки джуну что и как писать.
Если система сложно-наблюдаемая, то да, раз уж дошли до жизни такой, тогда и приходится нажимать на диагностику и тестирование. Но опять же, если кто-то разрешил писать сложный код без тестов, заведомо зная, что код будет слабо наблюдаемым, то "перепутал плюс и минус" опять относится не к разработчику, а всё туда же - тимлид и архитектор. Но как раз они же и приняли на работу перепутавшего плюс с минусом, а потом не написавшего нужной обвязки. Они же вводили принятого в курс дел, рассказывали, что и как принято, как должно быть и т.д. Ну и вот результат - они обвалили продакшн. А отвечать будет рядовой разработчик. Вы ведь именно его хотели указать в качестве виновника?
с точки зрения компании, этого можно было избежать, если бы эти вопросы были обсуждаемы на интервью
С точки рения компании обсуждения на интервью являются вопросом десятистепенной важности, после таких "простых" моментов, как адекватность высшего руководства компании, например, или же их умение планировать, развивать внутренние системы, работать с коллективом, понимать важные детали в тех областях, которыми взялись руководить, ну и много чего ещё.
Повторюсь - вы оптимизируете только около себя. Поэтому когда машина не едет, вам придётся, например, начать шлифовать краску, что бы уменьшить сопротивление воздуха, а на самом деле проблема может оказаться в отсутствии мотора. Но к пуговицам претензий не будет, разумеется.
sickfar Автор
12.04.2023 13:54Я вообще никого не указываю в качестве виновника, вы странным образом трактуете мои слова. Равно как и про стек я не говорил в контексте компании (ей вообще по барабану), а в контексте команды, которая ей эту прибыль и делает. И тут, извините, придется знать как логирование делается в С++, а как в Java.
А касаемо ответственности, о том же и речь, что сначала тимлид и архитектор НЕ спрашивают на собеседовании "а ты тесты-то писать умеешь?", а потом начинается подсчет денег, утекших на хот-фикс. Об этом и есть статья. Требовать это надо еще при приеме на работу, тогда все всё обговорили и понимают как будут работать. И вот уже тогда можно искать "виновника", который эти договоренности (желательно еще и зафиксированные как Corporate code style) нарушил.
UPD: а еще вы совершенно неверно поняли контекст статьи. Это не вопросы, которые я бы задал кому-то, чтобы понять, нравится он мне или нет. Это вопросы, которые я бы хотел услышать. Чтобы их задавали мне.
Corsonamor
12.04.2023 13:54+2Думаю, что всё так и есть. Но в итоге автор находит себе команду, с которой не будет спорить по поводу архитектуры или кодстайла. Интервьюер получает сотрудника, разделяющего его взгляды на разработку. Все в плюсе. Но это не значит, что как обсудили на собеседовании - так и будет. Часто в команде можно что-то вынести на обсуждение: улучшить качество ревью, определиться с написанием тестов, внедрить тдд.
Но в целом так и получается, что ищется подходящий человек в команду, с которым совпадают взгляды. Возможно, это как-то специально не проговаривается, но это так. Иначе можно было бы ограничиться тестом, как на егэ
panzerfaust
12.04.2023 13:54+1Ревью кода и работа в команде
Я еще спрашиваю, какие проблемы в коде кандидата чаще всего обнаруживаются на код-ревью. Если "да особо никаких" на уровне джун-мид, то это даже не звоночек, а рында. Как правило, потом я предлагаю собственно провести код-ревью на кусочке кода, написанным с особым цинизмом, - и там все становится понятно.
ermadmi78
12.04.2023 13:54+4Интервью вообще холиварная тема. Так что позволю себе немного похоливарить. Вот чем мне не нравится такой подход (а я за свою карьеру провел, наверное, около сотни собеседований), так это тем, что каждый ваш вопрос предполагает целый спектр "правильных" ответов. Но для вас, как для интервьюера, "правильным" будет ровно тот ответ, который у вас в голове. Я такие собеседования называю игрой "угадай мелодию". Кандидату нужно угадать ответ, который есть в вашей голове. Т.е. по факту ваше интервью проходит не наиболее профессиональный, а наиболее удачливый кандидат.
В идеале результат собеседования кандидата не должен зависеть от того, что у интервьюера в голове. Интервьюер - это просто измерительный прибор. И, если этот прибор вносит неадекватно большие погрешности в результаты измерения, то этот прибор не годится для измерений.
Вопросы для собеседований нужно подбирать так, чтобы у "прибора измерения" был минимальный люфт в трактовке ответов.sickfar Автор
12.04.2023 13:54-1В целом, вы правы. Но, во-первых, я выступаю не с точки зрения интервьюера, а с точки зрения соискателя. После 10 лет разработки мне надоело одинаково отвечать на одинаковые вопросы, и на такие интервью я обычно даю отказ. Эти вопросы показывают как хорошо я подготовился, а не как хорошо я решаю боевые задачи и обеспечиваю высокий SLA при проблемах и создаю качественный код. Во-вторых, ставя себя на место интервьюера, для меня важно, что человек, с которым мне предстоит работать, вообще осознает такие концепции, как тестируемость, диагностируемость, продуктивное ревью. Он может их осознавать не совсем так, как хотелось бы мне, но гораздо хуже полное отсутствие. Здесь еще играет роль фактор собственной боли. Мне приходилось (и не единожды) работать в команде «сениоров», которые могут себе позволить класс на 3000 строк без единого теста. Лишь пару раз так напоровшись, я уже начал сам задавать вопросы «а как у вас в команде с тестами и CI/CD?». Но как соискателю, мне бы хотелось, чтобы об этом спрашивали меня.
К тому же, я не утверждаю, что все интервью должно состоять лишь из этих вопросов. Отличное дополнение для тех частей, где «просто побеседовать».
ermadmi78
12.04.2023 13:54+3Ну, значит работодателю придется угадать правильный вопрос, чтобы вас нанять ;) Может компании нужны именно вы. И именно вы лучше всего справитесь с задачами компании. А вы, сузив спектр "правильных" вопросов до тех, что находятся у вас в голове, не позволяете "прибору измерения" корректно вас измерить и сравнить с другими кандидатами. В результате работодатель вас не нанимает, и теряет огромные деньги, проигрывая в конкурентной борьбе. Отсюда и все наши проблемы в имортозамещении и технологическом отставании! ;)
piton_nsk
12.04.2023 13:54Вопросы для собеседований нужно подбирать так, чтобы у "прибора измерения" был минимальный люфт в трактовке ответов.
Проблема в том, что это вырождается в откровенно дурацкие тесты. Типа что выведет этот код или сколько параметров в конструкторе такого-то класса. Но люфт минимален, это да. Еще и разработчика отвлекать не надо, можно кандидату хоть бумажку с вопросами дать (если лень делать веб-форму), пусть галочки ставит.
ermadmi78
12.04.2023 13:54У меня по другому. Но, боюсь, большинству читателей мой подход не понравится. Лайфкодинг в реальной IDE. С автокомплитом, документацией, компилятором, дебагером. Можно пользоваться гуглом. Собственно условия простые - всем, чем в реальной работе пользуешься, тем же и у меня на собеседовании можно пользоваться.
PS
Предвкушаю провокационный вопрос - а ChatGPT можно пользоваться? Пока никто из кандидатов не пользовался. Даже не знаю, как я к этому отнесусь. Но, учитывая то, что даже с гуглом собеседование проходят примерно 2 кандидата из 10, то с ChatGPT я думаю результат будет не лучше.
Travisw
12.04.2023 13:54А ваше это чатжпт разрешает коммерческое использование его кода для начала ответьте?
hoack
12.04.2023 13:54+2Все вопросы, которые приведены в статье, очень правильные, и действительно по делу. Однако, к сожалению, они в основном относятся к общей осведомленности кандидата о современных аспектах разработки и к его способности хорошо об этом поговорить. Это важно; однако, когда я ищу разработчика, мне важны еще несколько вещей:
Умение не только говорить, но и делать - способен ли кандидат написать работающий код, пусть и не супер сложный? Ну не ФиззБазз - но, скажем, вариацию на тему Фибоначчи. Увы, мне попадалось немало кандидатов, красиво рассуждающих о тестировании и контейнерах, но неспособных самостоятельно перевести в лоб заданный алгоритм в рабочий код.
Наличие базового уровня технической грамотности. Хреново, если кандидат вообще себе не представляет разницу между линейной и квадратичной вычислительной сложностью.
Наличие опыта (если речь не идет о самой начальной позиции). Помимо рассуждений о том, как надо - пытался ли кандидат таки сделать так, как он рассказывает, и что из этого вышло (и почему).
И вот для того, чтобы получить представление об этих способностях кандидата, и приходится спрашивать про хэш-таблицы, заставлять писать код и въедливо допрашивать про прошлые проекты.
sickfar Автор
12.04.2023 13:54-1Парой комментариев выше написал, но повторюсь: я не утверждаю, что все интервью должно состоять лишь из этих вопросов. И уж тем более эти вопросы имеют смысл лишь для программиста с опытом и неплохим уровнем. Я с удовольствием побеседую и об опыте, и попишу на лайв-код сессии. Тем не менее, интервью, состоящее лишь из базовых вопросов, не дает хорошего представления о реальном скиле человека уровня Middle+
bookmist
12.04.2023 13:54-1Спасибо за статью. Эти животрепещущие вопросы очень редко поднимаются даже в дискуссиях, не говоря уже о статьях и книгах. Хотел бы я хоть раз увидеть хотя бы обсуждение вопроса, что логировать и на каком уровне.
KReal
12.04.2023 13:54-1Не сказать, чтобы невероятно свежий взгляд на вещи, но в то же время очень хорошая и грамотная подборка, однозначно плюс! Спасибо.
event1
12.04.2023 13:54На все вопросы ответы будут очень разные в разных проектах. Либо слишком общие. Если бы у меня такое спросили как у кандидата, я бы пытался угадать, а что собственно интервьюер хочет услышать.
onyxmaster
Я прошу людей в качестве тестового задания реализовать несложную структуру данных (оффлайн, не на интервью, можно пользоваться чем угодно, лимита на время нет). Удовлетворительных решений за несколько лет -- 4 что ли штуки. При этом большинство оценивают себя в "от 300к".
О чём тут можно дальше разговаривать, найти хотя бы того кто знает как хэш-таблица работает...
sickfar Автор
Я тоже такую тенденцию замечаю (на собесе лично я точно не сделаю, домашкой - в зависимости от критериев приемлемости, наверное, справлюсь), но тут вечный вопрос - а насколько часто вы в бою пишете структуры данных? Если в вашей сфере это рядовая задача - вопросов нет. Я вот очень давно учил структуры и алгоритмы, практически все забыл по причине неиспользования в моей сфере.
UPD: собственно, об этом я и написал. Такие данные я отношу к справочным. Но вот если ваши кандидаты даже справочником пользоваться не умеют, это большая проблема.
slonopotamus
Я извиняюсь, а как вы организуете хранение данных программ в памяти, если не складываете их в структуры?
sickfar Автор
Обычно я использую структуры из стандартной библиотеки, заворачивая их в свои классы. В крайнем случае - ищу подходящую в сторонних, исходя из критериев использования. Самому писать связные списки и прочие деревья мне еще ни разу не приходилось.
slonopotamus
Кажется, вы называете структурами не то что я понимаю под этим словом.
olartamonov
(тяжело вздохнув) Я вживую видел человека с красивым резюме, который в реальном проекте структуру данных (в протоколе связи, а не хранении в памяти, но не суть) описывал простынёй дефайнов, задающих байтовые смещения внутри массива для каждого из членов структуры.
joffer
пресвятые пироги...(
onyxmaster
Мы, как и существенное количество компаний, перекладываем JSON-ы между дисками и ОЗУ по сети. Но стараемся делать это не слишком дорого, поэтому требования у нас чуть повыше чем в среднем наверное. Бывают модифицированные хэш-таблицы, бывают префиксные деревья (Ахо-Корасик) для обработки текста, бывают просто списки для обработки больших массивов (и нужно понимать что в List<> длинной в несколько сотен тысяч не надо вставлять в цикле в середину). Всякое бывает.
Мне кажется, что если инженер и забыл что-то, то он должен быть в состоянии разобраться и выдать годное решение. Есть декомпиляторы на худой конец, примеры "в интернете" и т.д., а разобраться в применимости -- тут придётся использовать навык разработчика, какой вариант хороший, а какой плохой и почему, и людям без этого навыка в разработке не место. Это они думают что память бесконечная, процессор тоже и создавать по 100к объектов на один запрос это нормально, GC соберёт если что.
Я, если что, не прошу интервальное дерево "в голове" написать или реализовать с первой попытки без ошибок алгоритм Кнута-Морриса-Пратта, я прошу хэш-таблицу с дополнительными свойствами, причём дома, используя что угодно доступное.
sickfar Автор
Золотые слова! Именно это и отличает хорошего инженера от того же ChatGPT. И, к теме статьи, мало просто это написать, нужно это качественно покрыть тестами и обеспечить хорошую диагностируемость. Чтобы даже в случае проблем с GC и 100к объектов иметь возможность быстро продиагностировать и как минимум выдать рекомендации что с этим добром делать прямо сейчас когда задержки посыпались.
event1
Это проверка общих знаний. У нас в тестовой задаче просят найти стороны прямоугольного треугольника определённого вида. Насколько часто наши разработчики сталкиваются с прямоугольными треугольниками? Никогда. Найму ли я программиста, который не в состоянии написать программу из двух циклов или не знает что такое теорема Пифагора? Тоже никогда.
neolink
Разобраться с тем как работает хеш-таблица можно минут за 15 с перекурами, а делать тестовое - это надо прям хотеть попасть именно в конкретную компанию, топовые компании такое не практикуют, соответственно вероятность найти тех кто "может" таким способом мала...
onyxmaster
У нас на интервью кодирования нет, например, мы его вытесняем в тестовое задание, чтобы минимизировать стресс и посмотреть что человек может сделать в нормальной обстановке.
Не очень понял связь между тем что топовые компании такое не практикуют и вероятность что к нам таким образом попадёт человек мала.
dom1n1k
Ну типа бытует мнение, что уважающий себя специалист (тм) снизойдет до тестового задания, только если оно будет от компании мечты. В иных случаях тестовые выполняют либо джуны, либо клинические лузеры, а стало быть и вероятность найти среди них кого-то стоящего очень мала.
onyxmaster
А, ну значит я всё-таки правильно понял в своём втором ответе. Видимо я недостаточно себя уважаю, но мне в целом было бы не лень выполнить тестовое задание на вакансию, которая по остальным признакам меня устраивает (и "компания мечты" это очень абстрактный критерий, с моей точки зрения я уже там, но это же субъективщина жуткая =).
Norgorn
Вы просто не учитываете, что тестовое требует каждый второй. И после нескольких отказов по причинам типа "ой, а чего вы 100% тестами не покрыли? А чего код в тестовом типа на 4 часа неидеальный" мотивация очень сильно падает. Мало того, что реально уходит совсем не 4 часа, дак ещё и никого обсуждения чаще всего нет - отказ и всё, совсем не "повод поговорить". Да, именно, большинство работодателей просто врут о своём тестовом.
Если ваше сильно отличается (а можете немного изменённый пример? очень интересно, что там примерно за структура данных) - это отлично, скорее всего, соискатель это заметит и таки сделает. Но общий настрой именно как я описал - не вдохновляют тестовые совсем.
onyxmaster
https://habr.com/ru/articles/728572/comments/#comment_25438896
onyxmaster
"Коллективный разум" в действии. Минус за комментарий со ссылкой на задание, о котором попросили в исходном комментарии. Браво, товарищи.
onyxmaster
Я не могу и не планирую отвечать за других людей, в том числе за работодателей. Только за себя и, в меньшей степени, за коллег.
piton_nsk
Если есть несколько вакансий, все вакансии с тестовыми заданиями уходят в конец списка. Это просто вопрос оптимизации.
А если вакансий не десять, если само тестовое явно не на два часа, если четких требований нет, то делать тестовые в принципе нереально. Потому что это будет полноценная фуллтайм работа. Это не говоря об откровенных глупостях типа используйте именно определенную версию скл сервера.
Если тестовое не обременительно по времени, если это повод поговорить, то почему бы и нет. Времени уйдет как на собеседование все равно.
onyxmaster
Если не хочется делать тестовое задание, то может и интервью тоже лишнее, да и просто можно номер счёта в мне Телеграм прислать куда зарплату отправлять? =)
Лучший результат исполнения этого задания, который я видел (и он лучше моего) помещается в 300 строк (без учёта тестов), это 6 экранов кода. Не выглядит титаническим усилием, честно говоря с точки зрения времени, если ты знаешь что делаешь.
А если чтобы сделать хэш-таблицу с некоторыми особенностями человеку дома за его компьютером в удобной обстановке нужно несколько дней, то наверное нам такой человек не нужен =)
neolink
Давать несколько лет тестовое задание и сделать из результата вывод - на рынке есть я и ещё 4 нормальных прогера, довольно странно не находите?
Тестовое задание скорее отфильтрует людей по мотивации - банально из вариантов:
есть некое тестовое на которое ты потратишь +- 2 часа + 2 часа поговорить
просто 2 часа поговорить и пописать немного код (30 строчек, а не 300 + тесты)
логично вроде выбрать второе? а чтобы выбирали первое - либо у человека много времени, либо он очень ищет работу, либо очень интересное задание, что хочется сделать...
Ну и при живом общении сразу можно посмотреть насколько пассивно-агрессивен интервьюер... А так ты потратишь 2х времени, а потом банально не захочешь туда идти.
onyxmaster
Вывод "на рынке есть я и 4 нормальных прогера" сделали вы, а не я =)
У меня задачи найма 10 или 100 человек нет. Не наймём в этот раз, подождём ещё, никаких проблем, наймём позже.
onyxmaster
Ну и я дополню, тут был интересный момент. Один из кандидатов прислал решение, которое было сделано, скажем так, недостаточно хорошо с моей точки зрения. Я написал что получилось, а что нет, в ответ на что услышал "ну у меня времени не было, я вообще обычно бесплатно тестовые задания не делаю". На моё замечание что про это можно было бы сказать и мы бы решили этот вопрос, ведь я предлагаю кандидатам сначала задать любые интересующие их вопросы до выполнения задания, кандидат общение прекратил.
Времени на людей, которые не в состоянии дать понять что им нужно у меня очень мало, самому бы разобраться =)
vvbob
Я лично при выборе между тестовым дома и лайфкодингом, однозначно бы выбрал тест, ненавижу лайфкодинг, написать что-то годное в условиях очень сжатого времени и психологического давления в виде кряхтящего за кадром интервьювера, для меня лично очень непросто, даже на простых каких-то задачках чувствую себя тупым джуном.
Captain_Jack
Как раз наоборот - чтобы сделать хэш-таблицу без багов и косяков производительности (если вы конечно не делаете это в 25-й раз или не перепечатываете из книжки), нужно очень хорошо и внимательно подумать, написать много тестов, в том числе и на производительность. За 2 часа это физически не сделать.
Даже в стандартных библиотеках периодически находят косяки в реализации структур, хотя к их написанию и тестированию приложено на порядки больше ресурса.
Вы учитываете "эффект учителя"? Это когда вы 25 лет даёте всем одну и ту же задачу, уже 200 раз проверяли её решение, и знаете все места, где можно накосячить. И вам начинает казаться, что там же всё очевидно, и "я сам могу за час сесть и написать", и "как можно было допустить тут такую ошибку, это надо быть совсем некомпетентным".
Сам попадал в такое искажение. Чтобы из него выбраться, есть 2 хороших рецепта:
Дайте эту задачку своим друзьям/коллегам, которых вы считаете компетентными и кто ещё её не решал. Удивитесь, как много из них вы бы отсеяли.
Попробуйте каждому соискателю давать разные задачи на разные структуры. Вам будет, возможно, гораздо сложней, зато будет лучше ощущаться, сколько реально ресурсов надо на задачу.
Говорят, что большинство разработчиков, уже работающих в компании, не смогут пройти собеседование на свою же позицию. И я бы не сказал, что дело тут в их поголовной некомпетентности.
onyxmaster
Все ошибки, допущенные разработчиками, из-за чего им было отказано, были не багами в реализации (ошибся с индексом или что-то такое), а результатом непонимания того, как функционирует среда исполнения (почти поголовное использование LinkedListNode<>) и что такое алгоритмическая сложность (тут даже в треде был пример -- предлагали добавить List<> для учёта порядка, хотя это превращает O(1) в O(n) для некоторых операций). Так что никаких сложных тестов не нужно, нужно хотя бы спроектировать её нормально, не то что бы ей реализовать.
После этого комментария мне вероятно придётся сменить тестовое задание, но задании нет ничего про запрет использования готового кода, если что можно просто пойти взять исходник Dictionary<,> на referencesource.com или через ILSpy и добавить то что в него нужно добавить, чтобы получить соответствие исходному заданию. Это самый простой вариант и потребует, на мой взгляд, минут 40.
Про обобщения вида "говорят что большинство разработчиков" мне сказать нечего, вполне возможно что это так, но у нас все эту задачу знают и успешно решали её.
Спасибо за попытку помочь мне с рефлексией, но с учётом первого абзаца моего ответа, ваши советы кажутся мне нерелевантными.
onyxmaster
То есть я ни одно из "непрошедших" решений даже не пытался скомпилировать. Ошибка в стратегии моделирования видна сразу. Если бы там была ошибка с индексом, мы бы просто поговорили с человеком про то, как такое можно было бы диагностировать тестами "потом" и заодно перешли бы на тему property-based testing и т.д.
А тут приходят люди, которые не знают модель организации памяти и не знают свойств контейнеров из базовой библиотеки. Поголовно. Конечно, это не мешает им делать line-of-business applications например, или ещё что-то, но у нас требования чуть повыше.
b00
Было бы интересно взглянуть на ваше тестовое :)
Если, конечно, это не секрет.
onyxmaster
Не секрет, задача для .NET-разработчиков: реализовать IDictionary<,> таким образом, чтобы перечисление его элементов сохраняло порядок, соответствующий порядку вставки, при этом не изменяя алгоритмическую сложность операций относительно обычного Dictionary<,>.
b00
По принципу действия - это нечто вроде LinkedHashMap ожидается? Уточняю для понимания задачи.
По big-O интересно сравнить с HashMap, спасибо за идею.
onyxmaster
Принцип действия предполагается что разработчик придумает сам. Если я расскажу что ожидается, то в общем-то мне проще написать самому, не находите?
По данной реализации -- важно учесть то, что в C# есть value-типы, определяемые пользователем, поэтому решение, которое подходит для Java может не подойти так просто для C#.
MikhailD
Это полная формулировка задания, нет ли ограничений по дополнительной памяти или по использованию существующих в .NET структур данных? Если нет, на сколько, на ваш взгляд, было бы корректным решение использовать комбинацию стандартного Dictionary и List: при добавления элемента, класть его в Dictionary и дополнительно ключ элемента добавлять в List. Все операции, кроме перечисления, редиректить на Dictionary, перечисление делать по List, беря из него очередной ключ и по ключу получая из Dictionary значение.
brain_tyrin
Тут сложность удаления по ключу вырастает до линейной :)
onyxmaster
Я рад что не перевелись ещё те, кто читает задание до конца! =)
onyxmaster
Простите, но я разбор задания здесь делать не планирую. Ограничения конечно же есть, и это одна из вещей, которую я проверяю заданием, не-джуниор должен понимать последствия выбора и находить баланс между тем чтобы всё писать на ассемблере или использовать ArrayList для хранения 1 миллиона байт =)
Kanut
А вы уверены что у вас выборка репрезентативная? Ну то есть банально что те, кто действительно стоят "от 300к", хотят связываться с вашим тестовым или даже компанией как таковой?
onyxmaster
Требовать репрезентативности выборки имеет смысл при использовании данных, полученных на выборке, для обобщений. Я таких обобщений не делаю, я констатирую факт -- из откликнувшихся на вакансию и выполнивших задание, с ним удовлетворительно справилось меньшинство.
Может ли быть что на нашу вакансию "клюют" преимущественно неквалифицированные разработчики? Я об этом не задумывался, но если и попробовать задуматься, то причины мне неизвестны. Мы -- небольшая продуктовая компания, и про это написано в вакансии. Все квалифицированные специалисты предпочитают работать в компаниях другого рода? Мне это кажется сомнительным. Кроме того, даже если так, то компания не изменится и значит мне просто придётся смириться с тем, что к нам обращаются преимущественно низкоквалифицированные специалисты.
Является ли дурным тоном предложение тестового задания? Мы его раньше не предлагали, а приглашали людей поговорить, не могу сказать что результаты были лучше, но требовалась синхронизация и значимое количество бессмысленно потраченного времени. Кроме того, даже в этой теме был как минимум один комментарий, что человек предпочитает тестовое задание кодированию на интервью.
Предположу, что в данном случае что бы я ни написал, всё равно нашлись бы недовольные.
Забавно (нет) как существенное количество людей, которым что-то не понравилось в трудоустройстве в других местах огорчается тем, что наши требования так похожи на требования в тех местах и это одно (судя по всему) даёт им повод огорчаться.
Есть тестовое задание -- "они хотят чтобы я бесплатно на них работал" (можно договориться), "все работодатели врут про тестовые задания" (я не все, могу и не врать), "каждый второй хочет тестовое, времени нет" (значит вы на эту вакансию не подходите, проходите к следующей пожалуйста).
Нет тестового задания -- "фу, лайвкодинг на интервью, это стресс" (лично я согласен, потому и тестовое а не лайвкодинг), "алгоритмическое интервью не проверяет используемые в работе навыки" (да, и я не фанат такого, но обычно альтернативой тестовому является алгоритмическое интервью, иногда ещё и не одно, см. Яндекс) и т.д.
А, вот ещё, "не дают фидбека" (я даю, с подробным описанием проблемы, со ссылками на книги, сайты и репозитории где можно почитать как стать лучше).