[Перевод] Думай как программист. Урок по решению задач

image

Если вы интересуетесь программированием, то возможно слышали фразу:

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

— Стив Джобс


Наверное вы тоже задавались вопросом, что значит думать как программист?

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

Данный пост ставит целью научить вас этому.

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

Почему это важно?


Решение задач — это базовый навык.

Мы постоянно решаем задачи. Большие и маленькие. Как мы это делаем? Иногда хорошо… если повезет.

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

  1. пробуете решение,
  2. если оно не подходит, то пробуете другое,
  3. если не получилось, то повторяете пункт 2 до победы.


Вам может везти, но это худший способ! И он может отнять очень много времени.

Лучший способ:

  1. иметь системный подход,
  2. применять его на практике.


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

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

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

—  Hacker Rank (2018 Developer Skills Report)


Системный подход


Чтобы найти правильный подход, я последовал советам из книги Тима Феррисса об обучении «The 4-Hour Chef».

Это привело меня к интервью с двумя действительно впечатляющими людьми: C. Jordan Ball (занимает 1-е или 2-е место из 65 000 пользователей Coderbyte) и V. Anton Spraul (автор книги «Думай как программист. Креативный подход к созданию кода.»).

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

Скоро вы тоже их узнаете.

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

«Самая серьезная ошибка, которую я вижу у молодых программистов — это сосредоточеность на изучении синтаксиса, вместо изучения того, как решать задачи.»

— V. Anton Spraul


Итак, что делать, когда вы сталкнетесь с новой задачей?

Разберем по шагам:

1. Понимание


Поймите, что конкретно нужно сделать. Большинство задач сложны, потому что вы их не понимаете (вот почему это первый шаг).

Как узнать, что вы поняли суть задачи? Попытайтесь объяснить её простым языком.

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

Большинству программистов знакомо это чувство.

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

«Если вы не можете объяснить что-то простым языком, то вы не понимаете этого.»

—  Richard Feynman


2. Планирование


Не начинайте решать задачу без плана, надеясь не запутаться в ней. Планируйте свое решение!

В программировании не надо «идти напролом». Дайте вашему мозгу время для анализа и обработки информации.

Чтобы получить хороший план, ответьте себе на простой вопрос:

«Подав на вход X, какие шаги нужно сделать, чтоб получить Y на выходе?»

Примечание: у программистов для этого есть отличный инструмент. Комментарии!

3. Декомпозиция


Это самый важный шаг. Будьте внимательны!

Не пытайтесь решить одну большую задачу.

Вместо этого разделите её на подзадачи. Решить их будет гораздо проще.

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

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

Соединение всех маленьких задач даст вам решение исходной.
Поздравляем!

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

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

Предположим, что необходимо написать программу, которая берет 10 цифр и возвращает третье по величине. Для новичка это может стать сложной задачей, хотя требует только знаний базового синтаксиса.

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

Уменьшайте задачу пока не поймете как её решить. Запишите решение. Затем разворачивайте задачу до момента, пока не вернетесь к начальному вопросу.

—  V. Anton Spraul


4. Застряли?


Сейчас вы вероятно сидите и думаете: «Эй, это все круто, но что если я не смогу решить эту задачу?».

Прежде всего сделайте глубокий вдох. Не волнуйтесь. Это происходит со всеми!

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

На самом деле, вот три вещи, которые нужно попробовать сделать, когда сталкиваетесь со сложностями:

  1. Отладка. Проверяйте шаг за шагом, где вы могли ошибиться в своем решении. Программисты называют это дебаггингом.

    «Искуство отладки заключается в выяснении разницы того, что вы написали в программе, и того, что вы хотели написать»

    — Andrew Singer

  2. Смена подхода. Вернитесь на шаг назад. Посмотрите на задачу под другим углом. Можно ли абстрагироваться от реализации и применить более общий подход?

    «Иногда мы так сильно углубляемся в детали, что не учитываем общие принципы, с помощью которых можно решить задачу на более высоком уровне. […]

    Классическим примером этого, конечно же, является суммирование длинного списка последовательных целых чисел 1 + 2 + 3 +… + n, который молодой Гаусс легко посчитал по формуле n (n + 1) / 2, избежав проблем, связанных с увеличением количества элементов»

    — C. Jordan Ball


    Примечание: Иногда лучше удалить все и начать сначала с новыми силами. Я серьезно. Вы будете удивлены тем, насколько это может быть эффективно.
  3. Исследование. Эх, старый добрый Google. Независимо от того, какая у вас задача, скорее всего кто-то уже решал её до вас. Найдите этого человека или решение. Сделайте это даже если разобрались сами. Можно многому научиться у других людей.

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


Практика


Не надейтесь стать профессионалом через неделю. Для того, чтоб хорошо решать задачи, нужно решить много задач!

Практика. Практика. И еще раз практика. Только со временем вы сможете сказать: «Эта задача может быть легко решена с помощью <подставьте свое решение сюда>».

Как тренироваться? Есть интеренсые варианты!

Шахматные головоломки, математические задачи, судоку, го, монополия, видео игры и т.д.

На самом деле, общая практика среди успешных людей — это их привычка «решать микрозадачи». Например, Питер Тиль играет в шахматы, а Илон Маск играет в видеоигры.

Байрон Ривз сказал: «Если вы хотите посмотреть, как могут выглядить руководители бизнеса через три-пять лет, посмотрите в онлайн-играх».

Быстрая перемотка вперед. Илон Маск, Рид Хоффман, Марк Цукерберг и многие другие говорят, что игры были основополагающими для их успеха в создании своих компаний.

— Mary Meeker (2017 internet trends report)


Значит ли это, что вы должны только играть в игры? Конечно нет.

Но в чем суть большинства игр? Правильно, в решении задач!

Так что же должно быть в практических занятиях. Что-то, что позволит вам решать много микрозадач (и в идеале это вам нравится).

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

Как я уже сказал, все задачи имеют сходные модели решения.

Вывод


Это все!

Теперь вы знаете, что значит «думать как программист».

Вы также знаете, что решение задач — невероятный (базовый) навык, который надо развивать.

Обратите внимание, теперь вы также знаете, как практиковать свои навыки решения задач!

Наконец, я хочу, чтобы вы столкнулись с множеством задач.

«Когда вы думаете, что успешно преодолели одно препятствие, появляется другое. Но именно это делает жизнь интересной. […]

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

С каждым разом вы узнаете что-то новое.

С каждым разом вы будете развивать силу, мудрость и перспективы.

С каждым разом будет все меньше конкуренов. И в конце останется только ваша улучшеная версия.»

— Ryan Holiday (The Obstacle is the Way)


Теперь идите решать задачи!

И пусть вам сопутствует удача!

Особая благодарность C. Jordan Ball и V. Anton Spraul. За полезные совет которые они дали.

Кроме того, я не мог бы преобрести своих знаний в области программирования так быстро без Lambda School. Не могу не поблагодарить и не рекомендовать их.

© Habrahabr.ru