Недавно я провёл 600-е собеседование на interviewing.io (IIO). Хотелось бы поделиться опытом, рассказать, как я подхожу к интервью, и пролить свет на типичные проблемы у кандидатов. Каждый интервьюер на IIO индивидуален, поэтому ваши результаты могут отличаться. У нас на платформе сформировалось замечательное сообщество, где каждый работает над улучшением своих знаний, навыков и результатов интервью.
Мы оцениваем людей по трём четырёхбалльным шкалам. Оценка «один» означает плохой результат, а «четыре» — очень хороший. Я обычно вначале даю кандидату три балла, а затем прибавляю/отнимаю очки по мере интервью.
Каждый интервьюер отдаёт предпочтение какому-то одному аспекту. Лично я проявляю некоторую предвзятость в сторону скиллов «общение» («коммуникация») и «решение проблем», которые мы обсудим ниже.
В этой категории кандидат оценивается по тому, насколько хорошо он владеет выбранным языком, испытывал ли он значительные проблемы с написанием определённого алгоритма, требовалось ли ему много подсказок во время кодирования.
Здесь я оцениваю кандидата по тому, насколько хорошо он разбивает проблему на более мелкие части, придумывает стратегию решения более мелких проблем и сглаживает углы по пути. Способность анализировать проблемы на ходу так же важна, как и написание кода. Заходит ли человек в тупик, когда возникает проблема, или он в состоянии самостоятельно найти первопричину?
Интервьюеры действительно хотят следить за вашим процессом принятия решений. Это также очень важно при отладке кода. Я обычно нанимал людей для небольших команд или групп. Поэтому для меня очень важны способность к сотрудничеству и лёгкость в общении.
Вот основные проблемные области, которые я вижу в собеседованиях, не только на IIO, но и вообще. Надеюсь, вы найдете этот список полезным.
Я вижу это у разработчиков всех типов и уровней, но в основном на «промежуточном» уровне с двух-пятилетним опытом работы. Они слышат проблему, обсуждают высокоуровневый дизайн в течение 30 секунд или меньше — и начинают программировать. Как будто стоит задача сделать как можно быстрее, они реально торопятся закончить работу.
Думаете, это своеобразная гонка, где победителем признают первого, кто пересечёт финишную черту?
Вовсе нет.
Пожалуйста, помедленнее. Планируйте работу. И озвучивайте мыслительный процесс по ходу дела.
Если потратить больше времени на детали реализации, будь то псевдокод или просто написание заметок, то обычно меньше времени уходит на отладку кода впоследствии. Тот, кто сразу бросается кодить, сталкивается с проблемами «проектирования на ходу». Приходится тратить много времени на рефакторинг: нужно изменить переданный параметр или возвращаемое значение или цикл находится в неправильном месте и т. д. Такое хорошо заметно со стороны.
Потратив некоторое время на дизайн среднего уровня (детали реализации), вы не гарантируете себе успех, но в долгосрочной перспективе это может сэкономить время, если вы продумаете свой план немного глубже, и это дополнительное время, которое можно использовать для устранения проблем позже.
Кроме того, я как интервьюер хочу, чтобы вы добились успеха. Особенно если вы пришли на личное собеседование, потому что в таком случае процесс собеседования стоит нашей компании гораздо больше денег. Хотя нужно быть справедливым ко всем кандидатам, но на личной встрече я могу сразу увидеть дизайн, заранее обнаружить недостаток и задать наводящие вопросы, чтобы направить вас к проблеме и раньше исправить подход.
Если вы сразу перейдёте к коду, я понятия не имею, будет ли ваша реализация работать, и это не лучшее место для интервьюера. Мне гораздо труднее исправить дизайн, когда уже написано 100 строк на Java и я пойму, наконец, что происходит в коде.
Я видел, как отсутствие планирования привело к ужасному результату в реальном интервью в 2012 году. Кто-то из отдела кадров привёл ко мне кандидата для интервью и пошёл за водичкой. Мы представились друг другу и перешли к технической задаче. Кандидат не поделился ни деталями, ни дизайном, почти не говорил о высокоуровневом подходе, ничего не записал — и начал строчить код на доске. (Это моё предпоследнее интервью на доске в жизни, ненавижу доску!)
Через несколько минут вернулся HR, громко постучал в дверь, предложил бутылку воды и ушёл. Благодарный кандидат откупорил бутылку, хотел было глотнуть — и тут на его лице появилось это ужасное, опустошающее выражение. Отвлёкшись на воду, он полностью потерял ход своих мыслей, и я никак не мог помочь ему, потому что он не поделился никакими деталями своего подхода. Он потратил несколько минут, переосмысливая проблему — и начал всё сначала.
С другой стороны, вы можете потратить «слишком много времени» на стадии проектирования и не успеть реализовать свой гениальный план. Я видел, как кандидаты обсуждают детали реализации, затем пишут заметки, потом вручную прогоняют пример, чтобы действительно убедиться, что план хорош — и теперь у них осталось всего несколько минут, чтобы фактически реализовать работу. Возможно, он получит пару лишних очков за коммуникацию, но хотелось бы увидеть какой-то рабочий код.
Каков же наилучший подход?
Я обычно рекомендую практиковаться до тех пор, пока у вас не начнёт получаться оптимальное распределение времени: около пяти минут на обдумывание высокоуровневого дизайна, пять минут на планирование деталей реализации и проверку, а затем работа над кодом. Хорошая новость в том, что практика реально помогает — чем больше вы практикуете такую схему, тем лучше результат. Подробнее об этом ниже.
«Полумысли» — понятие, которое я когда-то придумал и часто использую: это когда вы начинаете говорить вслух, заканчиваете мысль в своей голове, а затем меняете что-то в коде. Обычно это звучит примерно так:
«Интересно, можно ли… хотя нет, лучше сделать по-другому».
Вернёмся к скиллу общения.
Интервьюеры хотят понимать ваш мыслительный процесс. Им важно знать, как вы принимаете решения. Как вы выбираете или отбрасываете идеи? Почему решили реализовать что-то определённым образом? Вы заметили потенциальную проблему в коде? Какую именно?
Эта недостающая информация крайне важна для интервьюера. А с вашей стороны займёт всего несколько секунд, чтобы построить фразу примерно так:
«Интересно, можно ли… хм… ну, я подумал о реализации поиска в глубину, но учитывая ограничение вокруг ___, наверное, лучше будет ___, что вы думаете?»
Это займёт, может, две или три дополнительных секунды. Вы спросили моё мнение, теперь мы можем вместе рассмотреть возможности — и вот мы сотрудничаем. Вы уже чувствуете себя моим будущим коллегой!
Для разминки я часто задаю примерно такую задачку:
У вас есть группа целых чисел. Напишите метод, который находит два числа, складывающихся в заданное значение — и сразу выдайте эти числа. Верните два значения ‘null’, если ничего не найдено.
Это отличный вопрос, который показывает ваше отношение к алгоритмам и какие предположения вы делаете, когда начинаете решать проблему.
Я программирую уже довольно давно, с 1982 года. Ни в одном языке, который я когда-либо использовал, нет структуры данных «группа». Итак, какие предположения вы собираетесь сделать по поводу этой проблемы?
Большинство кандидатов сразу предполагают, что «группа» чисел находится в массиве. Вы можете успешно решить эту проблему, используя массив для хранения чисел. Скорее всего, это будет алгоритм квадратичной сложности O(n²), потому что для каждого значения вы будете перебирать остальные значения. Но существует более эффективный способ решить эту проблему за линейное время O(n), выбрав другую структуру данных.
Продолжайте спрашивать интервьюера о проблеме. Если он говорит сделать собственные предположения — это другое, но тогда спросите, являются ли ваши предположения хорошими. Спросите, есть ли альтернативные наборы данных, которые вы будете использовать в качестве тестовых случаев, которые могут повлиять на алгоритм.
Что-что?
Да, вы меня правильно поняли.
Конечно, вы на собеседовании, но вы должны показать, как будете работать в команде, а команды лучше всего работают, когда есть чёткое, открытое общение и чувство локтя. Потратьте первые несколько минут, чтобы установить правила общения и рабочего процесса.
Нет ничего плохого в подобном разговоре с интервьюером: «При решении таких технических задач я обычно спокойно обдумываю проблему и пишу заметки, а через минуту могу обсудить её, чтобы услышать ваше мнение. Затем я пишу код и стараюсь работать молча, но обязательно буду делать паузы, чтобы поделиться ходом своих мыслей, а затем более подробно познакомлю вас с кодом, прежде чем мы его запустим. Вас это устраивает, или у вас другие ожидания относительно того, как мне общаться или работать над проблемой?»
Я обещаю, что вы взорвёте его мозг. Большинство интервьюеров не готовы к тому, чтобы вы подобным образом учитывали их ожидания. Это показывает, что вы будете хорошо работать в команде. Вы создаёте среду, в которой защищаете себя, но также и заботитесь о других. Вы прямо заявляете о своих намерениях и даёте возможность сотрудничать в процессе.
Вероятно, во время решения технической проблемы интервьюер может оказать небольшую помощь. Я не могу обучить вас всему. Но очевидно, что лучше дать подсказку, небольшой толчок и помочь решить проблему, чем молча терпеть мучения человека и топтаться на месте вместе с собеседником, когда оба начинают думать, что интервью — пустая трата времени.
Как профессиональный интервьюер и преподаватель, я довольно хорошо научился задавать наводящие вопросы, которые направляют человека к реализации или ответу, не давая при этом решения.
Ничего страшного признать, что вы зашли в тупик. Это не делает вас неудачником, это делает вас человеком. Пусть интервьюер знает, о чём вы думаете и где у вас возникли проблемы. Прислушайтесь очень внимательно к его ответу — он может дать ключ к решению проблемы или более подробный совет, как действовать дальше.
По окончании интервью я люблю обсудить его с кандидатом, поговорить о том, как ему улучшить свои результаты. Обычно я трачу от 10 до 20 минут, иногда выходя далеко за пределы своего часового таймслота, чтобы ответить на вопросы и более подробно о чём-то рассказать. Мне очень нравится помогать людям.
Вот несколько общих советов, которые я обычно предлагаю.
Нет ничего хуже, чем слушать собственный голос. Но все собеседования на IIO записываются, и я часто предлагаю людям прослушать последние несколько минут. В любое время можно приостановить воспроизведение и посмотреть копию своего кода (конечно, эти записи являются приватными для вас и интервьюера).
Во время воспроизведения слушайте собственный мыслительный процесс и то, как вы передаёте свои идеи. При работе над другими проблемами найдите способ записать свои рассуждения, а потом послушать аудиозапись. Вы станете лучше формулировать полные и законченные мысли.
Другие сайты для практики интервью HackerRank, CodeWars, LeetCode и др. отлично подходят для кодирования, но не дают никакой возможности упражняться в проектировании (дизайне) задач.
Своим студентам я рекомендую проект Эйлера. Эйлер был математиком, поэтому задачи на сайте обычно довольно трудные, но вы можете их упростить на свой вкус. Если вы не знаете, как найти простое число, ничего страшного — проверьте, что число делится на 17 или что-то ещё.
Мне нравится проект Эйлера, потому что там представлены задачи со словесным описанием. Приходится продумать всё самому: алгоритм, какие структуры данных использовать, а особенно как разбить задачу на более мелкие части.
Одна из моих любимых задач — № 19 в архиве: посчитать, сколько месяцев между январем 1901 года и декабрём 1999 года начинаются с воскресенья. Вам известно количество дней в каждом календарном месяце, и то, что 1 января 1900 года — это понедельник, и способ вычисления високосных лет. Остальное зависит от вас.
Чем больше вы решаете разных задач, тем лучше станете находить закономерности.
Студентам мы даём совет решать каждую техническую задачу несколько раз. Наш исполнительный директор Джефф Казимир советует десять раз. Кажется, это слишком много, я больше склоняюсь к цифре 3-4 раза, и вот мои рассуждения:
В первый раз вы просто решаете проблему. Вы могли преодолеть какие-то локальные трудности, но единственное реальное достижение здесь — это завершение задачи.
Если вы удалите всю работу и начнёте её во второй раз, то можете подумать о другом подходе, возможно, более эффективном решении. Может и нет, но вы хотя бы получаете практику с решением такого рода проблем.
Теперь сотрите работу и сделайте её в третий раз. Потом в четвёртый. Именно на этом этапе в мозге начинаются выстраиваться паттерны со стратегией, необходимой для решения этой конкретной проблемы. Эта «мышечная память» поможет, когда вы увидите другие технические проблемы и сможете заметить сходство: «О, а ведь это похоже на задачу о рюкзаке», а поскольку вы решили её несколько раз, то гораздо быстрее составите высокоуровневый дизайн и проработаете детали реализации.
Одну из моих любимых технических задач можно решить различными алгоритмами (DFS, BFS, DP и т. д.). Если вы считаете, что можете решить задачу подобным образом, решите её три или четыре раза с помощью каждого из этих алгоритмов. Вы действительно хорошо научитесь находить сходства и получите отличную коллекцию стратегий для решения других технических проблем.
Я пишу заметки для начинающих разработчиков. Работа не закончена, но у меня много собственных идей о подготовке к техническим интервью, коммуникации и разъяснительной работе, составлению резюме, сопроводительных писем и так далее. Мне ещё предстоит написать несколько глав о тактике ведения переговоров и изящных увольнениях, но я уже сейчас с удовольствием выслушаю отзывы.
Я также веду ежедневную почтовую рассылку о вопросах на интервью. Но не с точки зрения того, как идеально на них отвечать (таких ресурсов много), а с точки зрения интервьюера — я рассматриваю, что конкретно мы спрашиваем, что надеемся услышать в ответ, а что не хотим услышать и так далее. Например, когда вас просят «Расскажите о себе», никому не интересна история вашей жизни. На самом вопрос звучит так: «Расскажите вкратце о том, что делает вас ценным сотрудником».
Пробное интервью на interviewing.io
Мы оцениваем людей по трём четырёхбалльным шкалам. Оценка «один» означает плохой результат, а «четыре» — очень хороший. Я обычно вначале даю кандидату три балла, а затем прибавляю/отнимаю очки по мере интервью.
Каждый интервьюер отдаёт предпочтение какому-то одному аспекту. Лично я проявляю некоторую предвзятость в сторону скиллов «общение» («коммуникация») и «решение проблем», которые мы обсудим ниже.
Техническая квалификация
В этой категории кандидат оценивается по тому, насколько хорошо он владеет выбранным языком, испытывал ли он значительные проблемы с написанием определённого алгоритма, требовалось ли ему много подсказок во время кодирования.
Решение проблем
Здесь я оцениваю кандидата по тому, насколько хорошо он разбивает проблему на более мелкие части, придумывает стратегию решения более мелких проблем и сглаживает углы по пути. Способность анализировать проблемы на ходу так же важна, как и написание кода. Заходит ли человек в тупик, когда возникает проблема, или он в состоянии самостоятельно найти первопричину?
Общение
Интервьюеры действительно хотят следить за вашим процессом принятия решений. Это также очень важно при отладке кода. Я обычно нанимал людей для небольших команд или групп. Поэтому для меня очень важны способность к сотрудничеству и лёгкость в общении.
Общие проблемные области, которые я вижу в интервью
Вот основные проблемные области, которые я вижу в собеседованиях, не только на IIO, но и вообще. Надеюсь, вы найдете этот список полезным.
Общая проблемная область 1: слишком ранний переход к коду
Я вижу это у разработчиков всех типов и уровней, но в основном на «промежуточном» уровне с двух-пятилетним опытом работы. Они слышат проблему, обсуждают высокоуровневый дизайн в течение 30 секунд или меньше — и начинают программировать. Как будто стоит задача сделать как можно быстрее, они реально торопятся закончить работу.
Думаете, это своеобразная гонка, где победителем признают первого, кто пересечёт финишную черту?
Вовсе нет.
Пожалуйста, помедленнее. Планируйте работу. И озвучивайте мыслительный процесс по ходу дела.
Если потратить больше времени на детали реализации, будь то псевдокод или просто написание заметок, то обычно меньше времени уходит на отладку кода впоследствии. Тот, кто сразу бросается кодить, сталкивается с проблемами «проектирования на ходу». Приходится тратить много времени на рефакторинг: нужно изменить переданный параметр или возвращаемое значение или цикл находится в неправильном месте и т. д. Такое хорошо заметно со стороны.
Потратив некоторое время на дизайн среднего уровня (детали реализации), вы не гарантируете себе успех, но в долгосрочной перспективе это может сэкономить время, если вы продумаете свой план немного глубже, и это дополнительное время, которое можно использовать для устранения проблем позже.
Кроме того, я как интервьюер хочу, чтобы вы добились успеха. Особенно если вы пришли на личное собеседование, потому что в таком случае процесс собеседования стоит нашей компании гораздо больше денег. Хотя нужно быть справедливым ко всем кандидатам, но на личной встрече я могу сразу увидеть дизайн, заранее обнаружить недостаток и задать наводящие вопросы, чтобы направить вас к проблеме и раньше исправить подход.
Если вы сразу перейдёте к коду, я понятия не имею, будет ли ваша реализация работать, и это не лучшее место для интервьюера. Мне гораздо труднее исправить дизайн, когда уже написано 100 строк на Java и я пойму, наконец, что происходит в коде.
Я видел, как отсутствие планирования привело к ужасному результату в реальном интервью в 2012 году. Кто-то из отдела кадров привёл ко мне кандидата для интервью и пошёл за водичкой. Мы представились друг другу и перешли к технической задаче. Кандидат не поделился ни деталями, ни дизайном, почти не говорил о высокоуровневом подходе, ничего не записал — и начал строчить код на доске. (Это моё предпоследнее интервью на доске в жизни, ненавижу доску!)
Через несколько минут вернулся HR, громко постучал в дверь, предложил бутылку воды и ушёл. Благодарный кандидат откупорил бутылку, хотел было глотнуть — и тут на его лице появилось это ужасное, опустошающее выражение. Отвлёкшись на воду, он полностью потерял ход своих мыслей, и я никак не мог помочь ему, потому что он не поделился никакими деталями своего подхода. Он потратил несколько минут, переосмысливая проблему — и начал всё сначала.
С другой стороны, вы можете потратить «слишком много времени» на стадии проектирования и не успеть реализовать свой гениальный план. Я видел, как кандидаты обсуждают детали реализации, затем пишут заметки, потом вручную прогоняют пример, чтобы действительно убедиться, что план хорош — и теперь у них осталось всего несколько минут, чтобы фактически реализовать работу. Возможно, он получит пару лишних очков за коммуникацию, но хотелось бы увидеть какой-то рабочий код.
Каков же наилучший подход?
Я обычно рекомендую практиковаться до тех пор, пока у вас не начнёт получаться оптимальное распределение времени: около пяти минут на обдумывание высокоуровневого дизайна, пять минут на планирование деталей реализации и проверку, а затем работа над кодом. Хорошая новость в том, что практика реально помогает — чем больше вы практикуете такую схему, тем лучше результат. Подробнее об этом ниже.
Общая проблемная область 2: общение «полумыслями»
«Полумысли» — понятие, которое я когда-то придумал и часто использую: это когда вы начинаете говорить вслух, заканчиваете мысль в своей голове, а затем меняете что-то в коде. Обычно это звучит примерно так:
«Интересно, можно ли… хотя нет, лучше сделать по-другому».
Вернёмся к скиллу общения.
Интервьюеры хотят понимать ваш мыслительный процесс. Им важно знать, как вы принимаете решения. Как вы выбираете или отбрасываете идеи? Почему решили реализовать что-то определённым образом? Вы заметили потенциальную проблему в коде? Какую именно?
Эта недостающая информация крайне важна для интервьюера. А с вашей стороны займёт всего несколько секунд, чтобы построить фразу примерно так:
«Интересно, можно ли… хм… ну, я подумал о реализации поиска в глубину, но учитывая ограничение вокруг ___, наверное, лучше будет ___, что вы думаете?»
Это займёт, может, две или три дополнительных секунды. Вы спросили моё мнение, теперь мы можем вместе рассмотреть возможности — и вот мы сотрудничаем. Вы уже чувствуете себя моим будущим коллегой!
Общая проблемная область 3: отсутствие уточняющих вопросов
Для разминки я часто задаю примерно такую задачку:
У вас есть группа целых чисел. Напишите метод, который находит два числа, складывающихся в заданное значение — и сразу выдайте эти числа. Верните два значения ‘null’, если ничего не найдено.
Это отличный вопрос, который показывает ваше отношение к алгоритмам и какие предположения вы делаете, когда начинаете решать проблему.
Я программирую уже довольно давно, с 1982 года. Ни в одном языке, который я когда-либо использовал, нет структуры данных «группа». Итак, какие предположения вы собираетесь сделать по поводу этой проблемы?
Большинство кандидатов сразу предполагают, что «группа» чисел находится в массиве. Вы можете успешно решить эту проблему, используя массив для хранения чисел. Скорее всего, это будет алгоритм квадратичной сложности O(n²), потому что для каждого значения вы будете перебирать остальные значения. Но существует более эффективный способ решить эту проблему за линейное время O(n), выбрав другую структуру данных.
Продолжайте спрашивать интервьюера о проблеме. Если он говорит сделать собственные предположения — это другое, но тогда спросите, являются ли ваши предположения хорошими. Спросите, есть ли альтернативные наборы данных, которые вы будете использовать в качестве тестовых случаев, которые могут повлиять на алгоритм.
Общая проблемная область 4: предположение, что интервьюер устанавливает все правила
Что-что?
Да, вы меня правильно поняли.
Конечно, вы на собеседовании, но вы должны показать, как будете работать в команде, а команды лучше всего работают, когда есть чёткое, открытое общение и чувство локтя. Потратьте первые несколько минут, чтобы установить правила общения и рабочего процесса.
Нет ничего плохого в подобном разговоре с интервьюером: «При решении таких технических задач я обычно спокойно обдумываю проблему и пишу заметки, а через минуту могу обсудить её, чтобы услышать ваше мнение. Затем я пишу код и стараюсь работать молча, но обязательно буду делать паузы, чтобы поделиться ходом своих мыслей, а затем более подробно познакомлю вас с кодом, прежде чем мы его запустим. Вас это устраивает, или у вас другие ожидания относительно того, как мне общаться или работать над проблемой?»
Я обещаю, что вы взорвёте его мозг. Большинство интервьюеров не готовы к тому, чтобы вы подобным образом учитывали их ожидания. Это показывает, что вы будете хорошо работать в команде. Вы создаёте среду, в которой защищаете себя, но также и заботитесь о других. Вы прямо заявляете о своих намерениях и даёте возможность сотрудничать в процессе.
Общая проблемная область 5: долго не просить о помощи
Вероятно, во время решения технической проблемы интервьюер может оказать небольшую помощь. Я не могу обучить вас всему. Но очевидно, что лучше дать подсказку, небольшой толчок и помочь решить проблему, чем молча терпеть мучения человека и топтаться на месте вместе с собеседником, когда оба начинают думать, что интервью — пустая трата времени.
Как профессиональный интервьюер и преподаватель, я довольно хорошо научился задавать наводящие вопросы, которые направляют человека к реализации или ответу, не давая при этом решения.
Ничего страшного признать, что вы зашли в тупик. Это не делает вас неудачником, это делает вас человеком. Пусть интервьюер знает, о чём вы думаете и где у вас возникли проблемы. Прислушайтесь очень внимательно к его ответу — он может дать ключ к решению проблемы или более подробный совет, как действовать дальше.
Мои любимые ресурсы для саморазвития
По окончании интервью я люблю обсудить его с кандидатом, поговорить о том, как ему улучшить свои результаты. Обычно я трачу от 10 до 20 минут, иногда выходя далеко за пределы своего часового таймслота, чтобы ответить на вопросы и более подробно о чём-то рассказать. Мне очень нравится помогать людям.
Вот несколько общих советов, которые я обычно предлагаю.
Общение
Нет ничего хуже, чем слушать собственный голос. Но все собеседования на IIO записываются, и я часто предлагаю людям прослушать последние несколько минут. В любое время можно приостановить воспроизведение и посмотреть копию своего кода (конечно, эти записи являются приватными для вас и интервьюера).
Во время воспроизведения слушайте собственный мыслительный процесс и то, как вы передаёте свои идеи. При работе над другими проблемами найдите способ записать свои рассуждения, а потом послушать аудиозапись. Вы станете лучше формулировать полные и законченные мысли.
Решение проблем и среднеуровневое проектирование
Другие сайты для практики интервью HackerRank, CodeWars, LeetCode и др. отлично подходят для кодирования, но не дают никакой возможности упражняться в проектировании (дизайне) задач.
Своим студентам я рекомендую проект Эйлера. Эйлер был математиком, поэтому задачи на сайте обычно довольно трудные, но вы можете их упростить на свой вкус. Если вы не знаете, как найти простое число, ничего страшного — проверьте, что число делится на 17 или что-то ещё.
Мне нравится проект Эйлера, потому что там представлены задачи со словесным описанием. Приходится продумать всё самому: алгоритм, какие структуры данных использовать, а особенно как разбить задачу на более мелкие части.
Одна из моих любимых задач — № 19 в архиве: посчитать, сколько месяцев между январем 1901 года и декабрём 1999 года начинаются с воскресенья. Вам известно количество дней в каждом календарном месяце, и то, что 1 января 1900 года — это понедельник, и способ вычисления високосных лет. Остальное зависит от вас.
Чем больше вы решаете разных задач, тем лучше станете находить закономерности.
Практика, практика, практика
Студентам мы даём совет решать каждую техническую задачу несколько раз. Наш исполнительный директор Джефф Казимир советует десять раз. Кажется, это слишком много, я больше склоняюсь к цифре 3-4 раза, и вот мои рассуждения:
В первый раз вы просто решаете проблему. Вы могли преодолеть какие-то локальные трудности, но единственное реальное достижение здесь — это завершение задачи.
Если вы удалите всю работу и начнёте её во второй раз, то можете подумать о другом подходе, возможно, более эффективном решении. Может и нет, но вы хотя бы получаете практику с решением такого рода проблем.
Теперь сотрите работу и сделайте её в третий раз. Потом в четвёртый. Именно на этом этапе в мозге начинаются выстраиваться паттерны со стратегией, необходимой для решения этой конкретной проблемы. Эта «мышечная память» поможет, когда вы увидите другие технические проблемы и сможете заметить сходство: «О, а ведь это похоже на задачу о рюкзаке», а поскольку вы решили её несколько раз, то гораздо быстрее составите высокоуровневый дизайн и проработаете детали реализации.
Одну из моих любимых технических задач можно решить различными алгоритмами (DFS, BFS, DP и т. д.). Если вы считаете, что можете решить задачу подобным образом, решите её три или четыре раза с помощью каждого из этих алгоритмов. Вы действительно хорошо научитесь находить сходства и получите отличную коллекцию стратегий для решения других технических проблем.
Бесстыдная самореклама
Я пишу заметки для начинающих разработчиков. Работа не закончена, но у меня много собственных идей о подготовке к техническим интервью, коммуникации и разъяснительной работе, составлению резюме, сопроводительных писем и так далее. Мне ещё предстоит написать несколько глав о тактике ведения переговоров и изящных увольнениях, но я уже сейчас с удовольствием выслушаю отзывы.
Я также веду ежедневную почтовую рассылку о вопросах на интервью. Но не с точки зрения того, как идеально на них отвечать (таких ресурсов много), а с точки зрения интервьюера — я рассматриваю, что конкретно мы спрашиваем, что надеемся услышать в ответ, а что не хотим услышать и так далее. Например, когда вас просят «Расскажите о себе», никому не интересна история вашей жизни. На самом вопрос звучит так: «Расскажите вкратце о том, что делает вас ценным сотрудником».