На днях я проводил собеседование с разработчиком на 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 к самоочевидным вещам, в корректную работу которых нужно просто слепо верить. Впоследствии я вряд ли стал бы тратить время на то, чтобы вникать в механику этой библиотеки, а просто пользовался бы ей как неким черным ящиком.
Но знакомство с этой книгой сделало меня другим человеком. Я стал вчитываться в исходный код и обнаружил, что реализация многих решений на деле очень прозрачна, даже очевидна. Нет, конечно, самому додуматься до подобного – это уже из другой оперы. Но именно изучение чужого кода и воспроизведение уже существующих решений и помогает нам придумывать что-то свое.
Вдохновение, которые вы почерпнете, и паттерны, которые начнете замечать, изменят вас как разработчика. Вы обнаружите, что та прекрасная библиотека, которой вы постоянно пользуетесь и о которой привыкли думать как о магическом артефакте, работает вовсе не на магии, а просто решает проблему лаконично и находчиво.
Иногда над кодом придется корпеть, разбирая его шаг за шагом, но именно так, продвигаясь мелкими последовательными шажками, вы сможете повторить путь автора к решению. Это позволит вам глубже погрузиться в процесс написания кода и даст больше уверенности при поиске собственных решений.
Когда я только начал работать с промисами, мне казалось, что это чистая магия. Потом я узнал, что в их основе лежат те же обратные вызовы, и мой программистский мир перевернулся. То есть паттерн, цель которого – избавить нас от обратных вызовов, сам реализуется при помощи обратных вызовов?!
Это помогло мне взглянуть на дело иными глазами и осознать, что передо мной не какие-то заумные куски кода, запредельную сложность которые мне никогда в жизни не постигнуть. Это всего лишь паттерны, в которых без проблем можно разобраться при должной любознательности и глубоком погружении. Именно так люди учатся программировать и растут как разработчики.
Изобретите это колесо заново
Так что смело переизобретайте колеса: сами пропишите код для связывания данных, создайте доморощенный промис или даже сделайте своими руками решение для управления состояниями.
Не имеет значения, что всем этим никто никогда не будет пользоваться – зато вы теперь это умеете. А если у вас будет возможность впоследствии использовать такие наработки в собственных проектах, то это вообще здорово. Вы сможете их развивать и научитесь еще чему-нибудь.
Смысл здесь не в том, чтобы отправить свой код в продакшн, а в том, чтобы освоить что-то новое. Самостоятельно прописывать реализацию уже существующего решения – отличный способ учиться у лучших программистов и тем оттачивать свое мастерство.