Питер Норвиг: Обучитесь программированию за… 10 лет +21


Примечание переводчика: данная статья была опубликована Питером Норвигом в 2001 году. По варианту 2001 года был выполнен перевод на русский язык. В 2014 году статья была обновлена, но перевод не был обновлен. Поэтому я выполнил свой перевод статьи по ее современному варианту 2014 года. Считаю, что статья не потеряла своей актуальности, хоть и несколько устарела. Если найдете какие-то ошибки в переводе, пишите в личку.

Куда все так спешат?


Зайдите в любой книжный магазин и вы тут же увидите книгу, как выучить Java за 24 часа, а также бесконечные варианты, как выучить C, SQL, Ruby, алгоритмы и так далее за несколько дней или часов. Расширенный поиск на Amazon [title: teach, yourself, hours, since: 2000] выдает список из 512 книг. Из первой десятки девять – книги по программированию (лишь одна – о бухгалтерском учете). Такие же результаты вы получите, заменив "teach yourself" на "learn", а "hours" – на "days".

Отсюда следует вывод: либо люди очень торопятся обучиться программированию, либо каким-то сказочным образом программированию выучиться легче, чем чему-либо другому. Felleisen et al. упомнули об этом в своей книге How to Design Programs, когда писали «Плохо программировать – проще простого. Идиоты могут научиться этому за 21 день, даже если они полные кретины». Сайт комисов Abtruse Goose тоже прошелся по этой теме (вот ссылка).

Давайте разберемся, что может означать название книги Teach Yourself C++ in 24 Hours:

  • Teach Yourself: За 24 часа у вас не будет времени написать несколько значительных программ, и сделать выводы из своих успехов и неудач. У вас не будет времени поработать с опытным программистом и понять, что такое идеология С++. Короче, за это короткое время вы выучите не так уж и много. Так что книга имеет в виду лишь поверхностное знакомство, но не глубоко понимание. Как сказал Александр Поуп: «Малознание – опасная вещь».
  • C++: За 24 часа вы вполне способны выучить что-то из синтаксиса С++ (если вы уже знаете другой язык программирования), но вы не так уж много узнаете, как пользоваться этим языком. Короче, если вы, скажем программист на Basic, вы выучитесь, как писать программы в стиле Basic, используя ситаксис С++, но вы не поймете, для каких задач С++ реально хорош (или плох). Ну и что, скажете вы? Как сказал Alan Perlis: «Если язык не меняет ваших представлений о программировании, изучать его бесполезно». Ну разве что, вам нужно выучить немножко С++, чтобы понять, как использовать какую-то библиотеку для какой-то определенной задачи. Но в таком случае речь не идет об обучении программированию на языке; вы просто учитесь выполнению конкретной задачи.
  • in 24 Hours: К сожалению, как я покажу ниже, этого времени недостаточно.

Обучитесь программированию за 10 лет


Исследования (Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973)) показали, что требуется примерно десять лет, для того, чтобы овладеть навыками в какой-то определенной области, например, в игре в шахматы, музыкальной композиции, работе с телеграфом, рисовании, игре на пианино, плавании, теннисе, нейрофизиологии и топологии. Секрет заключается в обдуманной практике: не просто механическое повторение, но поиск задач, которые выше вашего нынешнего уровня, решение их, анализ ваших действий во время их решения и после того, как они решены, исправление сделанных ошибок. И опять. И снова. Более короткого пути нет: даже Моцарту, в 4 года ставшему музыкальным чудо-ребенком, понадобилось 13 лет, прежде чем он стал создавать музыку мирового класса. Битлз в 1964 году ворвались на сцену с кучей хитов и выступили в шоу Эда Салливана. Но до этого они играли в маленьких клубах Ливерпуля и Гамбурга с 1957 года. И несмотря на свою мировую славу среди фанатов, их первый успех среди музкальных критиков пришел с выходом «Сержанта Пеппера» в 1967 году.

Эту мысль популяризировал Malcolm Gladwell в своей книге, хотя там он говорит о 10.000 часах, а не о 10 годах. Знаменитый фотограф Анри Картье-Брессон (1908-2004) выразил эту мысль так: «Первые 10.000 фотографий будут вашими наихудшими» (Он тогда и не подозревал, что с помощью цифровой камеры некоторым удается достичь этой цифры за неделю). Реальный опыт приходит с жизнью: Сэмюэль Джонсон (1709-1784) писал «Опыт в любой сфере может быть получен только трудом целой жизни; меньшей цены не бывает»; Чосер (1340-1400) жаловался: «Столь мало жить, столь многому учиться». Гиппократ (400 г. д.н.э ) известен своим высказыванием «жизнь коротка, наука обширна», которое полностью звучит так: "Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile", а в русском переводе «Жизнь коротка, наука обширна, случай шаток, опыт обманчив, суждение затруднительно». Конечно, ни одно число не может являться точным ответом: нет никаких оснований предполагать, что все навыки (программирование, игра в шахматы, в шашки, на музыкально инструменте) требуют в точности одинакового времени на их освоение, как и то, что разным людям требуется в точности одинаковое время. Как сказал профессор K. Anders Ericsson: «В большинстве сфер просто удивительно, сколько времени требуется даже самым талантливым, чтобы овладеть мастерствов. Число ‘10.000 часов’ просто помогает вам понять, что речь идет о нескольких годах упорных трудов по 10-20 часов в неделю для достижения высочайшего уровня даже для самых природно одаренных с рождения талантов»

Итак, вы хотите стать программистом


Вот вам мой рецепт успеха в программировании:

  • Заинтересуйтесь програмированием, и создайте что-то просто ради интереса. Вам это должно быть настолько интересно, чтобы не жалко было потратить на это следующие 10 лет / 10.000 часов.
  • Программируйте. Самое лучшее обучение — это практика. Говоря техническими терминами, «максимальный урововень производительности для индивидуума в определенной области не достигается автоматически с опытом, напротив уровень производительности может быть повышен даже у самых опытных индивидуумов за счет сознательного стремления к улучшению» (стр.366) и «для самого эффективного обучения требуется хорошо поставленная задача с соотвествующим уровнем сложности для конкретного индивидуума, понятная оценка ее выполнения и возможности для ее повтороного выполнения и исправления допущенных ошибок» (стр.20-21) Книга Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life весьма поучительное чтение по этой мысли.
  • Говоритес другими программистами; читайте другие программы. Это намного важнее, чем любая книга или обучающий курс.
  • Если хотите, посвятите четыре года учебе в университете (или в аспирантуре). Это даст вам доступ к той работе, где требуются подтвержденные звания и титулы. Но если учеба вам не нравится, вы можете (при определенном усердии) получить все те же знания самостоятельно или прямо на работе. В любом случае, учёбы только по книгам недостаточно. «Образование в области компьютерных науки никого не сделает экспертом в программировании, точно также как изучение кистей и красочных пигментов никого не может сделать мастером-художником», пишет Эрик Реймонд, автор книги The New Hacker's Dictionary.У самого лучшего программиста, которого мне когда-либо приходилось нанимать на работу, за спиной был только курс общеобразовательной школы, а он создал прекрасные программы, модерирует мейл-лист собственных фанатов, и достаточно заработал на опционах, чтобы купить свой собственный ночной клуб.
  • Работайте над проектами с другими програмистами. Будьте лучшим программистом в одних проектах; будьте худшим – в других. Когда вы лучший, вы проверяете свои способности вести проект и вдохновлять других своим видением. Когда вы худший, вы учитесь у мастеров, что они делают, и что они не любят делать (это то, что они поручают делать вам).
  • Работайте над проектами после других программистов. Попробуйте разобраться в программе, написанной кем-то другим. Присмотритесь, что требуется, чтобы понять код и исправить его, когда рядом нет программистов, его написавших. Подумайте о том, как спроектировать свои программы так, чтобы их легче было поддерживать тем, кто будет с ними работать после вас.
  • Выучите по крайней мере полдюжины языков программирования. Выберите для изучения один язык, который основан на абстракциях классов (например, Java или C++), одни – поддерживающий функциональные абстракции (например, Lisp или ML или Haskell), один – поддерживающйи синтаксическую абстракцию (например, Lisp), один декларативный язык (например, Prolog или C++-шаблоны), и один – делающий упор на параллелизм (например, Clojure или Go).
  • Не забывайте, что в словосочетании «компьютерные науки» есть слово компьютер. Запомните, сколько времени требуется вашему компьютеру на выполнение одной инструкции, на чтение машинного слова из памяти (с и без промаха в кэше), на чтение последовательности машинных слов с диска, поиска записи на диске (Ответы здесь)
  • Примите участие в стандартизации языка программирования. Это может быть комиссия по ANSI C++, или совещание в вашей команде, где вы определите сколько пробелов вы отводите для отступов в коде – 2 или 4. В любом случае, вы узнаете, что другим людям нравится в языке, как глубоко их это чувство, а также возможно узнаете, от чего оно пошло.
  • Умейте понять, когда пришло время уйти из комиссии по стандартизации языка как можно быстрее.

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

Фред Брукс в своей статье «Серебряной пули не существует» обозначил три шага в поиске отличных программистов:

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

Получается, некоторые люди уже имеют качества, позволяющие им стать великими программистами; надо их только направить по правильному пути. Алан Перилс (Alan Perlis) выразил это более кратко: «Каждого можно научить лепить скульптуры; Микельанджело бы пришлось учить, как их не лепить. Точно также и с великим программистами». Перлис хотел сказать, что у великих есть некоторые внутренние качества, которые не приобретаются путем обучения. Но откуда эти качества появляются? Это врожденное? Или они вырабатываются усердием? Как сказал Агюст Густо (персонаж мультфильма Ratatouille) «готовить может всякий, но только бесстрашный может стать великим». Я считаю, что в нашем случае речь идет о жгучем желании посвятить большую часть своей жизни целенаправленному самообучению программированию. Но может быть бесстрашный более подходящее слово. Или, как сказал Антон Его (критик Агюста Густо): «не всякий может стать великим художником, но великий художник может появиться отовсюду».

Так что, вперед, покупайте книгу по Java/Ruby/JavaScript/PHP; возможно вы извлечете из нее какую-то пользу. Но вы не сможете поменять свою жизнь и не станете экспертом в программировании за 24 часа или за 21 день. Как насчет того, чтобы потратить 24 месяца упорного труда на непрерывное овладение предметом? Вот теперь мы уже ведём серьезный разговор…

Литература


  • Bloom, Benjamin (ed.) Developing Talent in Young People, Ballantine, 1985.
  • Brooks, Fred, No Silver Bullets, IEEE Computer, vol. 20, no. 4, 1987, p. 10-19.
  • Bryan, W.L. & Harter, N. "Studies on the telegraphic language: The acquisition of a hierarchy of habits. Psychology Review, 1899, 8, 345-375
  • Hayes, John R., Complete Problem Solver Lawrence Erlbaum, 1989.
  • Chase, William G. & Simon, Herbert A. "Perception in Chess" Cognitive Psychology, 1973, 4, 55-81.
  • Lave, Jean, Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life, Cambridge University Press, 1988.

Ответы


Примерное время на выполнение различных операций в типичном ПК:
выполнение типичной инструкции 1/1,000,000,000 sec = 1 nanosec
чтение из кеша L1 0.5 nanosec
ошибка в предсказании перехода 5 nanosec
чтение из кэша L2 7 nanosec
захват/освобождение мутекса 25 nanosec
чтение из основной памяти 100 nanosec
послать 2K по 1Gbps сети 20,000 nanosec
чтение 1MB последовательно из памяти 250,000 nanosec
чтение с диска с поиском (seek) 8,000,000 nanosec
чтение 1MB последовательно с диска 20,000,000 nanosec
отправка пакета данных из США в Европу и обратно 150 milliseconds = 150,000,000 nanosec


Приложение: выбор языка


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

  • Обратитесь к друзьям. Когда меня спрашивают, «какую операционную систему мне лучше выбрать – Windows, UNIX или Mac?», я отвечаю: «пользуйтесь то, которой пользуются ваши друзья». То, чему вы научитесь у своих друзей, с лихвой перекроет любые внутренние различия между операционными системами или языками программирования. Также учтите и ваших будущих друзей: сообщество программистов, частью которого вы станете, если продолжите свое обучение. Есть ли у выбранного вами языка большое растущее сообщество или оно мало и постепенно вымирает? Есть ли в большом количестве книги, веб-сайты и форумы, где можно получить ответы? Нравятся ли вам люди, тусующиеся на этих форумах?
  • Начните с простого. Языки программирования C++ и Java созданы для профессиональной работы больших команд опытных программистов, которых больше всего заботит эффективность исполнения их кода. Как результат у этих языков программирования есть сложные структуры как раз для решения таких проблем. Вам же важно научиться программировать. Вам не нужны лишние сложности. Вам требуется язык, который специально создан, чтобы его легко было учить и запомнить.
  • Играйте. Как бы вы хотели учиться игре на пианино: обычным интерактивным способом, когда вы слышите каждую ноту сразу, как только нажимаете клавишу, или в «пакетном режиме» — когда вы слышите всю мелодию лишь после того, как нажмете на клавишах все ноты песни? Конечно же интерактивный способ значительно легче, так же и с программированием. Выберите язык, в котором есть интерактивный режим работы, и играйте в нем.

С учетом всех этих критериев, я рекомендую в качестве первого языка программирования Python или Scheme. Или же JavaScript, но не потому что он идеально создан для начинающих, а потому что по этому языку очень много учебников, например, в Академии Кана. Но ваш конкретный случай может быть особенным, так что есть множество и других языков на выбор. Если вам до десяти лет, вам может понравится язык Alice или Squeak или Blockly (ученикам постарше они тоже могут понравиться). Главное – сделать выбор и начать учиться.

Приложение: Книги и прочие ресурсы


Меня спрашивают, какие книги и веб-сайты лучше всего подходят для обучения. Я повторю еще раз: «чтения одних только книг не достаточно», но порекомендую следующее:

  • Scheme: Structure and Interpretation of Computer Programs (Abelson & Sussman) пожалуй лучшее введение в компьютерные науки. Книга обучает программированию как процессу овладения компьютерными науками. По этой книге есть в сети видео, а также полный текст в электронном виде. Книга трудна для освоения, и на ней могут обломаться люди, которые предпочитают другой подход в обучении.
  • Scheme: How to Design Programs (Felleisen et al.) – одна из лучших книг о том, как проектировать программы.
  • Python: Python Programming: An Intro to CS (Zelle) – хорошее введение в программирование с помощью Python.
  • Python: несколько учебников есть на сайте Python.org.
  • Oz: Concepts, Techniques, and Models of Computer Programming (Van Roy & Haridi) – рассматривается как современная книга-наследник курсу Абельсона и Суссмана. Эта презентация многих великих идей в программировании охватывает больший круг тем, чем курс Абельсона и Суссмана и при этом книгу легко читать. В книге используется язык программированиz Oz, который не очень широко известен, но служит основой для изучения других языков.

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (26):

  1. vconst
    /#18847283

    //комикс
    как_выучить_с_за_21_день.png

  2. urticazoku
    /#18847417

    Но ведь правило 10000 не работает

    • saluev
      /#18847631

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

  3. ChePeter
    /#18847601

    «чтение из кеша L1 0.5 nanosec» не понятно, что считывается с такой частотой?
    Бит, байт, слово?

    • onehell
      /#18849413 / +1

      Кэш-линия

      • ChePeter
        /#18850475

        Для программиста что считывается?
        То, что из быстрого кэша это понятно.

        • webmascon
          /#18851143

          Кэш-линия считывается

          • ChePeter
            /#18851917

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

    • MaximNov
      /#18851141

      всегда считывается строка

  4. dom1n1k
    /#18847835

    Личные наблюдения: при обучении с нуля более-менее осмысленно программировать начинаешь через 2-3 года практики (до того из-под пера выходит почти исключительно говнокод и копипаст). Чтобы программировать действительно хорошо… пожалуй, соглашусь с заголовком статьи — порядок сроков примерно такой.

  5. Vlad_fox
    /#18848035

    Отсюда следует вывод: либо люди очень торопятся обучиться программированию
    .
    Бинго, кеп, подобного рода книги пишутся для тех, кому надо срочно (на вчера) освоить азы языка.
    Но да, чтобы глубоко проникнуться, надо курить трехтомник Кнута, желательно не в переводе, а в оригинале. Перемешивая это чтиво с чтением философской литературы и написанием стандартов в каких-то серьезных международных комиссиях.

  6. true-grue
    /#18848981

    Ссылку на статью Норвига приходится давать регулярно, свежий перевод будет весьма кстати, спасибо за него. Одно замечание: учебник по Mozart/Oz действительно очень хороший. Но к легкому чтению я бы его не отнёс. Это текст, скорее, для программистов-теоретиков, которые имеют склонность к разработке языков программирования. Поэтому, очевидно, его редко советуют в блогах. При этом в книге имеется действительно масса интересных идей и концепций, которые все еще ждут более доступного изложения и соответствующего инструментального ПО.

    Еще вспомнилось:

    Он говорил, что знает языки программирования и операционные системы, хотя не имел о них ни малейшего представления, всего лишь прочитав книгу о предмете за несколько часов до интервью. И он умудрялся добиваться места, вешая лапшу на уши.
    «Нам нужны специалисты, которые программируют на BAL», — могли сказать ему, упоминая какой-то таинственный язык программирования, а он мог саркастически рассмеяться:
    «BAL? Да я программирую на BAL последние три года!»
    Затем он немедленно бежал за книгами, потому что он никогда раньше не слышал ни о каком BALe. Но к тому времени когда начиналась реальная работа, он уже доставал всю нужную документацию, обычно представленную в виде тонких, отпечатанных на дешевой бумаге и плохо переплетенных книг, которая была фальшивым доказательством его опыта с BAL, или, по крайней мере, он выигрывал время, до тех пор пока он не добирался до машины и не выяснял что из себя представляет этот BAL.

  7. sshikov
    /#18849073

    >Отсюда следует вывод: либо люди очень торопятся обучиться программированию, либо каким-то сказочным образом программированию выучиться легче, чем чему-либо другому.

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

    • JobberNet
      /#18849713

      Похоже фреймворки для Джавы для того и придуманы — чтобы повысить порог входа так, чтобы человек знающий какой-либо пых (тоже C-подобный язык как и Java) не смог быстро освоить Джаву. :)

      • lkoida
        /#18849849 / +1

        Ой бросьте, как мне кажется, нападки на PHP, морально устарели уже лет пять как.

        • JobberNet
          /#18849927 / -1

          Так, я не про PHP, а про огромнейшую любовь к фреймворкам в Java, приводящую к ситуации когда знание языка без знания фреймворка считается недостаточным.
          PHP тут для примера — можете вместо него подставить C, C++, C#, C--, Objective-C, BCPL, D, Go, Rust и так далее — все равно придётся учить фреймворки, чтобы писать на Java.

          • APXEOLOG
            /#18851251

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


            Это как жаловаться на то, что старого доброго браузерного Javascript'a не хватает, чтобы писать бекенды на ноде

            • JobberNet
              /#18851295

              Не, с php и с java-script я знаком поверхностно, и php — я привёл лишь в качестве красивого примера языка похожего на Java. Реальный опыт у меня в Borland C++ и C++ Builder.

  8. Master255
    /#18849081

    Программистом должен быть каждый!

    • JobberNet
      /#18849715 / +1

      Эффектывный Манагер с галеры мечтающий быстро набрать вместо программистов каких-нибудь продавцов шаурмы с улицы для написания говнокода за зарплату как на уровне продавца шаурмы?

  9. Leoon
    /#18851259

    Вот оно как! А я то думаю, что меня как котенка в *** после 2 летнего опыта на новой работе. Оказывается 2 года — это только «начальная школа», а возможно и «садик» программирования.