Перевод статьи «How a year-long LeetCode habit upped my professional game» из блога Злых марсиан.
Культ лайвкодинга и алгоритмических задач процветает до сих пор. Вопросы в стиле «как преобразовать бинарное дерево» или «как написать пирамидальную сортировку» регулярно встречаются на собеседованиях не только в бигтехе — хотя это и не те задачи, которые каждый день решает среднестатистический разработчик. Из-за этого многие программисты начинают искренне ненавидеть алгоритмы.
Однажды я зашла на LeetCode, одну из популярных платформ для решения алгоритмических задач. Сразу уточню: мне не нужно было готовиться к собеседованию, и моя работа не требовала продвинутого знания алгоритмов. Тем не менее я заметила, что у меня стали заполняться пробелы в знаниях, и я продолжила решать задачи — каждый день понемногу.
С тех пор у меня накопилось более 400 решённых задач на LeetCode. Теперь я уверена, что такие платформы как LeetCode, HackerRank или CodeWars, при правильном подходе, способны поднять профессиональные навыки любого разработчика на новый уровень.
Вот чему я научилась за год ежедневного решения задач:
В моём коде стало меньше багов. Навык самопроверки улучшился, появилась привычка думать об ограничениях и пессимистичных сценариях;
При этом заметно увеличилась скорость написания кода. Многие вещи теперь делаются на «автомате»;
Я больше не боюсь сложных рабочих задач;
Я научилась качественнее объяснять свои решения и больше думать о чистоте кода;
Мой уровень самодисциплины возрос.
Но обо всём по порядку.

1. Больше внимательности, меньше багов
Привычка думать о случаях, в которых написанный тобой код «сломается», – очень полезна для разработчиков.
Я люблю LeetCode за то, что он мягко заставляет тебя если не писат��, то хотя бы мысленно просчитывать разные тестовые сценарии. Перед тем, как принять решение задачи, платформа всегда проверяет его по многочисленным тестам.
Может случиться так, что падает всего один сценарий из сорока, и он вынуждает тебя переписывать половину твоего кода. Это может сильно раздражать. Да и в целом видеть после отправки решения грустные красные буквы «Wrong Answer» – удовольствие ниже среднего. Особенно если задача сложная.
Поэтому с увеличением количества решённых проблем я заметила, что стала чаще анализировать указанные ограничения перед тем, как приниматься за задачу; больше думать о том, в каких случаях код даст сбой; и проверять всё больше тестовых случаев перед тем, как отправить итоговое решение.
Особенно приятно то, что с течением времени это стало проявляться не только при решении алгоритмических задач, но и на моей работе, а также при написании собственных проектов. Как правило, в обычной рабочей атмосфере нам не высвечиваются слова «Wrong Answer», когда мы допустили ошибку — это всплывает позднее в виде бага у клиента.
Поэтому задаваться вопросами в духе «упадёт ли моя функция, если входные данные были очень большие или, наоборот, пустые» – отличная привычка. Тренировка на коротких алгоритмических задачах помогает развить её лучше всего.
Что ещё поможет, чтобы наработать внимательность и делать меньше ошибок?
Обращать внимание, как те или иные ограничения в задаче влияют на предполагаемое решение. Например, если в массиве может быть миллиард элементов, то решение брутфорсом вряд ли подойдёт;
Анализировать, насколько велика сложность решения по времени и по памяти, используя нотацию «О» большое. Не стоит обращать внимание на процент «успешности» времени выполнения кода, который показывает Leetcode после отправки. Он бесполезен; в этой статье подробно рассказывается, почему это так;
Всегда помнить про пессимистичные сценарии, а не только про общие.
2. Скорость написания кода растёт, решения изобретаются быстрее
Я не ожидала этого, но с приятным удивлением заметила через полгода: у меня стало уходить примерно в 1.5 раза меньше времени на задачу по сравнению с тем, когда я начинала.
С чем это связано? Даже при выборе разнообразных задач в них прослеживаются общие паттерны и подходы к решению. Например, обход бинарного дерева – через несколько месяцев периодического решения «деревьев» ты напишешь этот алгоритм с закрытыми глазами и без лишних раздумий.
Это касается и скорости выбора способа решения. В своё время я набила шишек, выбирая изначально неверный подход к задаче. Это нормальный процесс обучения; сейчас я быстрее соображаю, куда нужно пойти в начале, чтобы с большей вероятностью выйти на верный ответ. Например, если не знаешь, как решить задачу, где в качестве входных данных даётся массив элементов, то сначала попробуй отсортировать его.
Может быть, вам никогда не понадобятся алгоритмы из сложных задач на Leetcode. Но быстро писать реализацию несложных вещей и совершенно не задумываться над ней довольно неплохо, не правда ли?
Вот мои советы по развитию скорости:
Осваивайте темы в комфортном для себя темпе, переходите к следующей, только когда вы уже чувствуете уверенность в текущей. Например, сначала прорешайте 7 лёгких задач на деревья, 10 средних и 4 сложных, и только затем переходите, например, к спискам. Я не советую брать каждый день случайные задачи, поскольку это не позволяет сфокусироваться на освоении конкретной темы;
Не забывайте повторять старые темы. Даже если вы освоили тему деревьев, выполняйте задание по ним каждые пару недель;
Попробуйте решить лёгкую для себя задачу, но введя ограничение по времени, – например, десять минут. Иногда создание искусственной нехватки времени может заметно увеличить продуктивность.
3. Прививка от страха перед сложными задачами
Я не пытаюсь продвигать иллюзию того, что продвинутое знание алгоритмов, вообще-то, абсолютно необходимый навык, без которого нельзя стать программистом. Для определённых разработчиков, работающих со сложными предметными областями и оптимизациями, – вполне возможно, это будет очень нужно. Но не всем подряд.
Я – фронтенд-разработчик, и за последний год встречалась с необходимостью использовать нетривиальные алгоритмы несколько раз. Наиболее сложные случаи были связаны с визуализацией графов.
Но хоть это и было несколько раз, я чётко осознаю, что столкнись я с такими задачами раньше – я бы испугалась сильнее и потратила бы на задачу больше нервов и времени. Однако с закалкой на LeetCode я восприняла их не как «что-то новое и страшное», а «наконец-то интересное и азартное».
Алгоритмические задачи не только отлично готовят к сложным рабочим задачам, которые встречаются редко, но метко. Я заметила, что активное решение лёгких задач позволяет нарабатывать автоматизм и даже подтянуть знание языка программирования.
Например, сейчас я совершенно не задумываюсь, как работают встроенные методы в JS: что возвращает .push()
, или мутируют ли исходный массив методы .slice()
или .splice()
. Эти знания нельзя назвать алгоритмическими, однако регулярное решение LeetCode помогает твёрдо их усвоить.
Вот как можно начать чувствовать себя намного увереннее независимо от уровня сложности задачи:
Некоторые сложные задачи могут быть довольно экзотическими, так что не расстраивайтесь и не опускайте руки, если не можете их решить. Даже если вы готовитесь к собеседованию, по статистике, они встречаются очень редко.
Не забывайте пробовать применять полученные знания на работе ('use it or you lose it'). Например, когда это уместно и имеет смысл, попробуйте использовать структуру данных Set вместо Array;
Если вы только осваиваете новый язык программирования, то простейшие задачи хорошо помогают с этим. Вы поймёте синтаксис и особенности языка намного быстрее, чем если бы просто читали теорию.
4. Почва для искусства объяснения решений и чистого кода
Пару раз я натыкалась на критику, что сайты вроде LeetCode плохи тем, что они позволяют писать код как угодно грязно, лишь бы он работал. Это верно; но приучение разработчика писать чисто и не является их основной целью.
Тем не менее я заметила, что всё же есть возможность научиться писать код чище и объяснять решения, используя LeetCode. Почти всегда на подобных сайтах есть раздел, где разработчики публикуют собственные решения. Иногда их можно оценивать, и тогда в топ попадают наиболее понятные решения с лучшими объяснениями.

Когда я начала прояснять непонятные задачи, вчитываясь в решения и объяснения опытных разработчиков, мой процесс обучения пошёл в гору. Я и сама попробовала выкладывать собственные решения. К тому времени я поняла, что людям полезно, когда решения объяснены кратко, но ясно.
И тогда я стала работать над детальным описанием решений, а ещё над чистотой кода — стыдно ведь выложить грязное решение на общий суд. Мне хотелось, чтобы мой вариант был максимально понятным и читаемым. Впоследствии я заметила, что стала переносить этот принцип и в рабочие задачи. А ещё – лучше объяснять свои решения коллегам.
Так как же улучшить навык чистого кода и объяснения решений, пользуясь LeetCode?
Не стесняйтесь публиковать свои решения, даже если они не уникальны (только сначала постарайтесь максимально почистить код);
Потренируйтесь писать объяснения своих решений. Постарайтесь формулировать их так, чтобы всё понял даже новичок;
Решив задачу, посмотрите решения, находящиеся в топе выложенных. Это позволит научиться не только новым подходам, но и тому, как качественно умеют преподнести своё видение проблемы некоторые разработчики.
5. Развитие самодисциплины
В любом деле важна мотивация и регулярность, будь то вышивание, занятия спортом или решение алгоритмических задач. Если мотивация заниматься на LeetCode уже появилась – из-за желания получить работу мечты или из-за чего-то ещё — то дело остаётся за регулярностью.
Я сделала решение задач своей привычкой и твёрдо решила, что буду находить время для этого время каждый день – хотя бы по полчаса. Когда копится стрик на протяжении одного, двух, трёх месяцев, пропустить новый день становится уже обидно.
Будет легче, если решать задачи каждый день в одно и то же время. Я выбрала время утром перед работой, но кому-то удобнее заниматься вечером. При выборе важно учитывать свой уровень интеллектуальной активности в течение дня, у всех он разный.
Несколько советов, чтобы сохранять мотивацию для достижения регулярности (без неё никуда):
Не пытайтесь каждый день решать много сложных задач, вы просто быстро выгорите. Постепенно увеличивайте сложность и уделяйте задачам определенное время (например, сорок минут в день);
Отслеживайте свой прогресс. Вы можете вести календарь и отмечать каждый день, когда садились за решение задач. Когда мотивация угасает, посмотрите, как далеко вы уже продвинулись;
Никогда не сравнивайте себя с другими. Чье-то опубликованное решение может выглядеть намного лучше вашего, но как узнать, сколько лет этот программист потратил на изучение алгоритмов?
Ежедневно хвалите с��бя: как только вы начинаете день, вы уже начинаете знать немного больше, чем вчера.
Подводя итоги. Чему же я всё-таки научилась?
За год на LeetCode я поняла, что алгоритмические задачи – не панацея, но отличные помощники. Они способны привить автоматизм при написании рутинного кода, убрать страх трудностей, приучить думать о разных тестовых сценариях. Публикация решений, с учётом старания сделать их чистыми и детальными, позволяет прокачать навык объяснения своего кода.
И даже если вы не стремитесь на собеседование лайвкодингом, самодисциплина, прокачанная в процессе регулярного решения задач, поможет в любой работе.
Всё ещё сомневаетесь? Просто попробуйте решить первую задачу сегодня.