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

Эта статья больше посвящена подходу, а не ресурсам.

Имейте предприимчивые амбиции:

Мыслить (проектировать) глобально; действовать (кодекс) локально.

-Анонимный

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

(Не начинайте сразу гуглить «посевной инвестор для более быстрого списка ссылок». Хотя несколько раз спустя вы можете спросить себя: а почему бы и нет?!)

Предпринимательские амбиции означают каждый день задавать себе один вопрос:

Что лучше всего я могу извлечь сегодня со своего компьютера (опционально, также из API web, Kaggle, GitHub Explore и многих других реестров пакетов, таких как NPM JS), что может быть полезно мне, моим друзьям и общество в целом?

Предпринимательский дух включает переключатель вашей мотивации — самый важный компонент в изучении сложных идей, таких как алгоритмы и структуры данных.

Наличие цели попасть в FAAMG также может мотивировать вас, но это недостижимая цель. (см. ниже)

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

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

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

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

Минимизируйте экранное время:

Если вы практикуете 10000 часов, вы можете стать экспертом в любой области.

-Малкольм Гладуэлл

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

В книге Малкольма Гладуэлла Outliers сформулировано известное правило 10 000 часов. Самый упрощенный вариант этого правила гласит, что если попрактиковаться 10000 часов, можно стать экспертом в любой области.

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

Однако многие программисты совершают ошибку, приравнивая это время к тому времени, которое они проводят перед своими компьютерами.

Сначала они читают Cracking the Coding Interview. Затем они переходят на один из сайтов братства LeetCode, Codechef, Hackerrank или TopCoder. Эти места приклеивают их к экрану своими проблемами, форумами и интенсивно геймифицированными достижениями.

Это просто слишком быстро истощает энергию. Зачем тратить его на то, чтобы напрягать глаза, когда вы можете использовать его для своего мозга?

Все, что вам нужно, это вещь, на которой вы будете писать свой псевдокод; компьютер для этого слишком мощная штука

Если кто-то составит список проблем, для решения которых нужны машины, алгоритмы и структуры данных будут последними. Устранение неполадок стоит на первом месте. Тестирование идет вторым.

Единственными инструментами Эйнштейна для переписывания космических правил были ручка и бумага. С Ньютоном дела обстояли не лучше.

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

Единственными инструментами Эйнштейна для переписывания космических правил были ручка и бумага.

Все, что вам нужно, это вещь, на которой вы будете писать свой псевдокод; компьютер для этого слишком мощное устройство!

Вот предлагаемый подход:

  • Прочитайте главу из вашей любимой книги по алгоритмам/структурам данных. По желанию посмотрите видео.
  • Посетите онлайн-задачи, связанные с темой.
  • Визуализируйте проблему.
  • Нарисуйте структуры входных и выходных данных (например, для перестановки строк «abcde» является входом, а «edcba» — выходом). Здесь хранятся ваши данные.
  • Самое важное: отображать изменения состояния в структурах данных (например, для Фибоначчи: f(n) = (n-1) + (n-2)). Это желаемая серия операций, которую вы должны согласовать. Нарисуйте соответствующие ведра для ваших элементов, например. для связанного списка не забывайте об отношениях узлов.
  • Используйте карандаш и бумагу (или белую доску) для решения. Даже если вы знаете, что ваше решение отстой, постарайтесь сделать его максимально совершенным офлайн.
  • Пишите псевдокод, а не синтаксис.
  • Пишите значения на каждом шагу. При необходимости нарисуйте диаграмму состояний.
  • Когда будете готовы, введите его на ПК/Mac/веб-консоли.
  • Если по ошибке не получится решить по-своему, попробуйте визуализатор алгоритмов, но не переусердствуйте в ущерб своим глазам.

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

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

Используйте бездействующие потоки:

Прогресс делают ленивые люди, ищущие более простые способы делать вещи.

Роберт А. Хайнлайн

Процессор, о котором мы говорим, — это ваш мозг.

Когда вы не работаете (случайная прогулка в парке или мытье посуды), ваш мозг наслаждается столь необходимым отдыхом. Именно в это время ваш мозг получает возможность снова соединить некоторые из своих нейронных точек, которые он разъединил, концентрируясь на вашей последней насущной проблеме.

Без перерыва нет возможности поразмышлять над своим дизайном.

На самом деле, эта истина не нуждается ни в каких доказательствах. Почему еще, несмотря на то, что дети очень хваткие, им разрешены перемены во время школьных занятий?

Как можно использовать время простоя для решения алгоритмических задач:

  • Прочтите задачу на вашем сайте Code Challenge. Поймите это досконально.
  • Вскоре после этого покиньте свой стол. Возьмите случайное задание, в котором больше никого нет. Совершите прогулку, займитесь домашними делами, приготовьте кофе или отправьтесь за покупками, не требующими особого выбора.
  • Небрежно подумайте о решении.
  • Мысленно разделите 1) что у вас есть 2) что вы можете извлечь 3) чего у вас нет. Запишите их.
  • Попробуйте первый черновик на бумаге/белой доске
  • Если вам не хватает логики, спросите у онлайн-одноклассников/учителя. В конце концов, программирование — это дисциплина, которая создает структуру. Структурированный вы создаете более структурированный код и более структурированные вопросы для других, чтобы помочь вам.
  • Вернитесь к бумаге, доработайте решение
  • Включите компьютер и введите/отправьте его.

Максимально используйте время перерыва вашего мозга для создания мысленного дизайна. Не тратьте свою осанку и глаза на чтение с экрана или бесполезную шутку.

Быть в Зоне:

Лучший выход всегда через.

Роберт Фрост

Вскоре после колледжа я писал бинарный поиск за 3 минуты. Мои друзья были даже быстрее меня. Но спустя 2 года не прикасаясь к нему, я совсем про него забыл. На интервью, на которое я пришел неподготовленным, мне не удалось его произвести.

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

Почему?

Ответ кроется в элементе под названием мозговой кеш (он же недавняя память).

Мозг не просто забывает то, что выучил. Но если последняя встреча не была недавней, восстановление любого полезного вывода занимает больше времени.

Мой учитель программного обеспечения сказал:

Если вы хорошо потренируетесь, вы сможете написать лучший код во сне.

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

Для большинства кодеров алгоритмическое совершенство происходит непрерывно:

  • Изучите концепцию (например, бинарный поиск).
  • Практика с большинством основных проблем.
  • Постепенно повышайте уровень сложности.
  • Пересмотрите теорию оптимизации.

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

Возможно, вы все еще не забыли циклы for и while, но по мере роста сложности кэш MRU вашего мозга будет заполняться другими вещами. Когда вы вернетесь к этим проблемам, ЦП вашего мозга должен будет выполнить дисковый ввод-вывод. Это столкнется с более длительными задержками. Stackoverflow неизбежен, и он все равно не решит проблему.

Ключ в том, чтобы умело переплести свою реальную (нерабочую) жизнь с кодом.

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

Единственный способ поддерживать пламя — это никогда не брать ментальный отпуск из-за алгоритмического мышления.

Никогда не позволяйте полосе прерваться. Никогда не выходите из зоны.

Ключ к этому — не конкурировать постоянно на LeetCode/Topcoder.

Это утомительно. Это неэффективно. Если у вас есть семья, это почти невозможно.

Ключ в том, чтобы умело переплести свою реальную (нерабочую) жизнь с кодом.

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

Будьте осторожны, чтобы не переусердствовать, потому что это может сказаться на вашей личной жизни. Один из способов смягчить ее — обсудить проблему со своими партнерами (друзьями или членами семьи), опустив технические детали, такие как обозначение большой буквой O. Это отличный способ открыть канал совместного решения проблем. Это пригодится в ваших будущих интервью и обсуждениях развития.

Когда у меня не хватает времени на выполнение задач, я с большим успехом пробовал еще один трюк (часто на рабочем месте) — это посещать StackOverflow для алгоритмических вопросов, получивших наибольшее количество голосов. StackOverflow, известный только устранением неполадок, в этой области сильно недооценен. Вы получаете бесплатные консультации от опытных ветеранов отрасли. Качество этого — то, чего не могут обеспечить ни авторы книг (хардкорные академики), ни те, кто зарабатывает на учебниках (учителя Udemy/Youtube).

Держите под рукой профессиональные хитрости:

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

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

  • Экономия циклов ЦП: O(1) всегда лучше всего. O(n) лучше, чем O(n^x). O (n ^ x) - худшее. В большинстве интервью ваша первая задача — преобразовать проблему в задачу, решаемую с помощью подхода O(1) или O(n).
  • Экономия памяти. Мемоизация (динамическое программирование) лучше, чем рекурсия.
  • Оптимизировать для информационной иерархии (в дереве), если вам нужны разнообразные данные, рекомендуется BFS (поиск в ширину). Если вам нужны релевантные данные, вам нужен DFS (поиск в глубину).

Не стремитесь исключительно к FAAMG+:

«Проблема участия в крысиных бегах в том, что даже если ты выиграешь, ты все равно остаешься крысой».

Лили Томлин

В прошлом я категорически не рекомендовал стрессовую подготовку к собеседованию. Я также советовал не делать FAAMG пунктом своей мечты.

Вот краткое изложение того, почему:

  • Проблема не в самом FAAMG (и его братьях и сестрах среднего звена, таких как Netflix, Uber и др.). Это ложное чувство амбиций, привязанное к ярлыкам вместо совершенства.
  • Погоня за крупной целью завышает ставки, увеличивая тем самым стресс. Давление сверстников отвлекает вас от вашей настоящей любви к программированию.
  • Получение работы отвлекает в обучении. Погоня за топ-работой важнее. Есть многочисленные примеры отличных кодеров, которые достигли вершины, даже не достигнув трудового возраста. Они больше не гоняются за работой, а работа гонится за ними.
  • Конкуренция (более 100 тысяч заявок в год) в сочетании с 4–7 изнурительными раундами собеседований делают результаты FAAMG гораздо менее предсказуемыми.
  • Иногда, несмотря на все ваши усилия, вы становитесь жертвой сложной сети рекрутеров.
  • Когда вы проваливаете собеседование, вы совершаете ошибку, ставя под сомнение обоснованность своих алгоритмических способностей. В чем вы действительно должны усомниться, так это в своем неуместном стремлении связать себя с громкими именами.

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

Сделайте FAAMG+ не пунктом назначения, а потенциальным пунктом вашего путешествия.

Заключение:

Программирование (особенно алгоритмы и структуры данных) — это навык, для которого характерна странная кривая обучения.

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

Это хорошо. Но и скучно для многих.

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

Амбиции и терпение — вот ключи к тому, чтобы это произошло.

  • Если вы хотите получать электронные письма в любое время после публикации Pen Magnet, пожалуйста, нажмите здесь.
  • Если вы еще не являетесь участником Medium и хотите им стать, нажмите здесь. (Часть вашей абонентской платы может быть оплачена Pen Magnet.)