Примечание переводчика: данная статья была опубликована Питером Норвигом в 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:
Исследования (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 часов в неделю для достижения высочайшего уровня даже для самых природно одаренных с рождения талантов»
Вот вам мой рецепт успеха в программировании:
При всем вышесказанном одно лишь чтение книг даст вам не так уж и много. До рождения моего первого ребенка, я прочитал все книги об уходе за малышами, и все равно совершенно не понимал, что нужно делать. 30 месяцев спустя, когда готовился появиться на свет мой второй ребенок, думаете я заглядывал в книги, чтобы освежить память? Нет. Я полагался на свой собственный опыт, который оказался намного полезнее и качественнее, чем тысячи страниц, написаных экспертами.
Фред Брукс в своей статье «Серебряной пули не существует» обозначил три шага в поиске отличных программистов:
Получается, некоторые люди уже имеют качества, позволяющие им стать великими программистами; надо их только направить по правильному пути. Алан Перилс (Alan Perlis) выразил это более кратко: «Каждого можно научить лепить скульптуры; Микельанджело бы пришлось учить, как их не лепить. Точно также и с великим программистами». Перлис хотел сказать, что у великих есть некоторые внутренние качества, которые не приобретаются путем обучения. Но откуда эти качества появляются? Это врожденное? Или они вырабатываются усердием? Как сказал Агюст Густо (персонаж мультфильма Ratatouille) «готовить может всякий, но только бесстрашный может стать великим». Я считаю, что в нашем случае речь идет о жгучем желании посвятить большую часть своей жизни целенаправленному самообучению программированию. Но может быть бесстрашный более подходящее слово. Или, как сказал Антон Его (критик Агюста Густо): «не всякий может стать великим художником, но великий художник может появиться отовсюду».
Так что, вперед, покупайте книгу по Java/Ruby/JavaScript/PHP; возможно вы извлечете из нее какую-то пользу. Но вы не сможете поменять свою жизнь и не станете экспертом в программировании за 24 часа или за 21 день. Как насчет того, чтобы потратить 24 месяца упорного труда на непрерывное овладение предметом? Вот теперь мы уже ведём серьезный разговор…
Примерное время на выполнение различных операций в типичном ПК:
Некоторые читатели задавали мне вопрос, какой язык программированяи им стоит учить первым. Однозначного ответа на этот вопрос не существует, но учтите следующие моменты:
С учетом всех этих критериев, я рекомендую в качестве первого языка программирования Python или Scheme. Или же JavaScript, но не потому что он идеально создан для начинающих, а потому что по этому языку очень много учебников, например, в Академии Кана. Но ваш конкретный случай может быть особенным, так что есть множество и других языков на выбор. Если вам до десяти лет, вам может понравится язык Alice или Squeak или Blockly (ученикам постарше они тоже могут понравиться). Главное – сделать выбор и начать учиться.
Меня спрашивают, какие книги и веб-сайты лучше всего подходят для обучения. Я повторю еще раз: «чтения одних только книг не достаточно», но порекомендую следующее:
Куда все так спешат?
Зайдите в любой книжный магазин и вы тут же увидите книгу, как выучить 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 месяцев спустя, когда готовился появиться на свет мой второй ребенок, думаете я заглядывал в книги, чтобы освежить память? Нет. Я полагался на свой собственный опыт, который оказался намного полезнее и качественнее, чем тысячи страниц, написаных экспертами.
Фред Брукс в своей статье «Серебряной пули не существует» обозначил три шага в поиске отличных программистов:
- Систематически определяйте лучших программистов как можно раньше
- Назначьте программисту ментора, который будет заниматься развитием таланта и тщательно следить за его карьерой
- Всячески содествуйте общению растущих талантов друг с другом, чтобы они обменивались идеями
Получается, некоторые люди уже имеют качества, позволяющие им стать великими программистами; надо их только направить по правильному пути. Алан Перилс (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, который не очень широко известен, но служит основой для изучения других языков.