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

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

Но увы. Да, было очевидно, что подобный код встречался ему раньше. Он в общих чертах знал, как там все работает. Нам хватило бы наброска решения, который демонстрировал бы понимание концепта. Однако код, который кандидат писал на доске, был полной бессмыслицей. У него сложилось крайне туманное представление о том, что такое промисы в JavaScript и он не мог толком объяснить, зачем они нужны. Для джуниора это было бы еще простительно, но на позицию сениора уже не тянуло. Как бы этот разработчик сумел устранить баги в сложной цепочке с промисами и объяснить остальным, что именно он сделал?

Разработчики считают готовый код самоочевидным


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

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

Так, наш кандидат на позицию разработчика-сениора считал самоочевидными объекты promise. Он, наверное, представлял, как с ними управляться, когда они встречаются где-то в чужом коде, но общий принцип не понимал и не смог сам его повторить на собеседовании. Возможно, он запомнил фрагмент наизусть – это не так уж сложно:

return new Promise((resolve, reject) => {
  functionWithCallback((err, result) => {
   return err ? reject(err) : resolve(result);
  });
});

Я тоже так делал – да все мы, вероятно, когда-нибудь так делали. Просто заучивали кусок кода, чтобы потом использовать его в работе, при этом только в общих чертах представляя, как там все устроено. Но если бы разработчик по-настоящему понимал концепт, запоминать бы ему ничего не пришлось – он просто знал бы, как это делается, и без труда воспроизвел бы все необходимое в коде.

Обращайтесь к истокам


В 2012, когда еще не установилось господство фреймворков фронтенда, миром правил jQuery, и я читал книгу Secrets of the JavaScript Ninja, автором которой был Джон Резиг, создатель jQuery.

Книга учит читателя, как создать собственную jQuery с нуля и дает уникальную возможность приобщиться к ходу мысли, который привел к созданию библиотеки. В последние годы jQuery утратила свою былую популярность, но книгу я все-таки очень рекомендую. Что меня больше всего в ней поразило – это настойчивое чувство, что я мог бы до этого всего додуматься и сам. Шаги, которые расписывал автор, казались настолько логичными, настолько понятными, что мне всерьез стало казаться, будто и я бы мог запросто создать jQuery, если бы только взялся за дело.

Разумеется, в реальности ничего подобного я бы не осилил – решил бы, что это неподъемно трудно. Собственные решения показались бы мне слишком простыми и наивными, чтобы сработать, и я бы опустил руки. Я бы отнес jQuery к самоочевидным вещам, в корректную работу которых нужно просто слепо верить. Впоследствии я вряд ли стал бы тратить время на то, чтобы вникать в механику этой библиотеки, а просто пользовался бы ей как неким черным ящиком.

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

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

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

Когда я только начал работать с промисами, мне казалось, что это чистая магия. Потом я узнал, что в их основе лежат те же обратные вызовы, и мой программистский мир перевернулся. То есть паттерн, цель которого – избавить нас от обратных вызовов, сам реализуется при помощи обратных вызовов?!

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

Изобретите это колесо заново


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

Смысл здесь не в том, чтобы отправить свой код в продакшн, а в том, чтобы освоить что-то новое. Самостоятельно прописывать реализацию уже существующего решения – отличный способ учиться у лучших программистов и тем оттачивать свое мастерство.

Комментарии (13)


  1. aamonster
    18.10.2019 11:19
    +1

    Ошибка в переводе — Java вместо Javascript в первом абзаце (а потом думаешь: "что, в Java тоже есть промисы?")


    1. gecube
      18.10.2019 11:41

      Полностью поддержу. Мой взгляд тоже зацепился. Только я подумал, что речь про энтерпрайз разработку, как, оказывается, что речь про JS.
      И, да, Java тоже умеет в промисы/futures.


  1. JustDont
    18.10.2019 12:27
    +2

    Он писал код сразу на доске

    Когда уже наконец вымрут люди, считающие, что код в какой бы то ни было ситуации уместно писать на доске?


    1. ip1981
      18.10.2019 12:54

      Чем доска отличается от Вима?


      1. Cerberuser
        18.10.2019 13:00

        Тем, что на доске нельзя написать :sh?


      1. Neikist
        18.10.2019 13:49

        Можно не экономить место, читаемость не зависит от почерка, удобнее форматировать. Так же можно сначала набросать в псевдокоде решение или комментариями а уже потом реализовывать.


      1. Enfriz
        19.10.2019 03:26
        +8

        От доски можно отойти в любой момент, а вот выйти из вима…


        1. maxzhurkin
          19.10.2019 20:48

          :q!
          не благодарите


  1. vba
    18.10.2019 12:58

    Хм, по мне так вы довольно таки вольно перевели(как и сам заголовок статьи):


    Разработчики считают готовый код самоочевидным (Developers Take Abstractions For Granted)

    Я бы сказал что тут речь идет о том что разработчики воспринимают абстракции как данность. Смысл абзаца под заголовком это подчеркивает.


    А так по сути статьи, могу сказать, что на мой взгляд у автора(не переводчика) в голове каша. Не хотите абстракций, попросите собеседуемого, наваять вам простенькую версию "протокола HTTP 1", желательно на ассемблере.


    А проверить понимание концепций можно простыми вопросами, от простого к сложному.


  1. Amareis
    19.10.2019 11:18

    Ну кстати для себя я сформулировал это как "понимаешь — это когда можешь сделать сам". Если человек понимает промизы — он может набросать их черновую реализацию. Замыкания, генераторы, event loop и что там ещё популярно на собеседованиях? То же самое, хотя такие низкоуровневые вещи обычно всё же пишутся уже на другом уровне. Прототипное наследование и оператор new можно написать и на js.


    Поэтому и существует подход "пишем свой react/mobx/эмулятор процессора и т.д.", ведь в обратную сторону тоже работает — если можешь сделать сам, значит понимаешь. Хотя тут свои нюансы есть.


    UPD: а, подзаголовок оригинала так и звучит: To truly understand the wheel, you need to reinvent it


  1. TerraV
    19.10.2019 12:49
    +3

    Мне нравятся подобные собеседования потому что позволяют при минимальных временных издержках избежать разочарований и нервотрепки работы со «звездами». С учетом необъятности технологий фокусироваться на деталях реализации это только тешить свое самолюбие. Естественно спрашивающий лучше подготовлен и может свысока поплевывать на кандидатов — «о, еще один недосеньор, что он там о себе возомнил». Вообще сеньорство это не про технологии. Мне нравится определение junior — пишет код, middle — решает проблемы, senior двигает компанию вперед. Сеньор это человек который смотрит за горизонт. Старается предугадать проблемы которые еще только возникнут, старается понять потребности бизнеса и за счет телефонного разговора на 10 минут может сэкономить 2 месяца разработки. В интервью выше даже возможности раскрыть потенциал не было. Потому что «надо знать реализацию промисов».

    Вообще интервью должно быть про поиск сильных сторон. Если интервьюер ни одну сильную сторону не обнаружил, значит рано ему еще проводить собеседования. Если сильные стороны есть, но не востребованы в команде или уже закрыты другими сотрудниками — то можно и отказать. Самый лучший вопрос для начала — расскажите о какой-нибудь проблеме которая вам встречалась и как вы ее решали (история неудачи). Второй вариант расскажите историю успеха (почему это успех, кто конртибьютил, что было бы провалом и т.д.). Такие вопросы дадут куда больше информации о соискателе, включая насколько адекватно оценивает себя и окружение.


    1. gecube
      19.10.2019 12:50
      +2

      Золотые слова. Т.е. с Вашей колокольни — любой человек ценен, но возможно, что не в этой компании, не в этой команде.


      1. TerraV
        19.10.2019 13:06
        +1

        Скажем так, я считаю это хорошей отправной точкой для начала диалога.