• Пітер Норвіг: Навчіться програмувати за десять років

    18.03.2013 • Цікаве навчання

    Чому всі так поспішають?

    Зайдіть у будь-яку книжкову крамницю і ви побачите, що вам запропонують вивчити мову програмування Java за сім днів за допомогою книжки Teach Yourself Java in 7 Days, разом із іншими численними варіантами учбових посібників, які пропонують вивчити Visual Basic, Windows,Інтернет і багато чого іншого за кілька днів або годин. Я провів наступний пошук на Amazon.com:

    pubdate: after 1992 and title: days and
    (title: learn or title: teach yourself)

    І отримав 248 результатів. Перші 78 вказували на комп’ютерні книги (під номером 79 знаходилась книга Learn Bengali in 30 days (вивчіть бенгальську за 30 днів). Я замінив слово “days” (дні) на слово “hours” (години) і отримав такі самі дивовижні результати: запит повернув ще 253 книги, серед яких перші 77 були комп’ютерними книгами, а за ними під номером 78 знаходилась книга Teach Yourself Grammar and Style in 24 Hours (оволодійте граматикою та стилем за 24 години). Серед перших 200 книг 96% були про комп’ютерні технології.

    На підставі цих фактів можна зробити один із двох висновків: або люди дуже поспішають дізнатися щось про комп’ютери, або вивчення комп’ютерної тематики набагато простіше в порівнянні з іншими заняттями. У продажу не знайшлося жодної книги, яка б дозволяла за декілька днів пізнати музику Бетховена, вивчити квантову фізику і навіть навчитися доглядати за собаками. У книзі «Як розробляти програми» (How to Design Programs, Felleisen et al.) автори визнають цю тенденцію, коли говорять: «Легко програмувати погано. Ідіоти можуть навчитись цьому за 21 день, навіть якщо вони чайники».

    Спробуємо проаналізувати, щоб могла означати назва Learn С++ in Three Days (Вивчіть C++ за три дні):

    • Learn: Впродовж трьох днів ви не знайдете часу для написання хоча б кількох значущих програм і не будете в змозі збагнути досвід всіх попередніх невдач у роботі з ними. У вас не буде часу, аби попрацювати разом з досвідченим програмістом і зрозуміти, як це жити в середовищі C++. Коротше кажучи, у вас не буде часу вивчити багато. Таким чином, ця книга може надати тільки поверхневе знайомство, але не глибоке розуміння. Проте, як казав англійський поет Олександр Поуп: знати мало – небезпечно.
    • С++: За три дні ви зможете вивчити трохи синтаксису мови С++ (якщо ви вже знаєте якусь іншу мову програмування), але не зможете в достатній мірі навчитись, як користуватись мовою. Наприклад, якщо ви програмуєте на Basic, ви зможете навчитись як писати програми стилю Basic використовуючи синтаксис C++, проте ви не зможете зрозуміти в чому фактично складаються переваги (та недоліки) С++. То в чому ж справа? Алан Перліс (Alan Perlis) зауважив : «Мова програмування, оволодіння якої не дозволяє знайти нові підходи до програмування, не заслуговує уваги». Одна з можливих причин вивчити трохи C++ (або щось на кшталт JavaScript чи Flash Flex) – це потреба в інтерфейсі між існуючим інструментом для виконання певної задачі. Але в такому разі ви не вчитесь програмувати; ви вчитесь тому, як вирішити цю конкретну задачу.
    • In three days. На жаль, як показує наступний розділ, цього недостатньо.

    Навчіться програмувати за десять років

    Дослідники (Bloom (1985), Bryan & Harter (1899), Hayes (1989), Simmon & Chase (1973)) показали,що для отримання експертних знань в будь-якій галузі людської діяльності, включаючи шахи, створення музики, малювання, гру на фортепіано, плавання, теніс, а також проведенні досліджень з нейропсихології та топології, потрібно приблизно десять років. Ключем тут є зважена практика: не просто робити це знову і знову, але знаходити для себе задачі, які знаходяться якраз за межами ваших поточних здібностей, намагаючись вирішувати їх, аналізуючи власну продуктивність до та після розв’язання таких задач, та виправляючи помилки. Потім повторювати. І знову повторювати. Причому складається, що тут не може бути скорочень: навіть Моцарту, який був музичним вундеркіндом у віці 4 років, знадобилося ще 13 років, аби він почав створювати музику світового рівня. Може видаватись, що Бітлз увірвались на велику сцену в іншому музичному напрямку зі своїми хітами та виступом у шоу Еда Селлівена у 1964 році. Але вони грали в маленьких клубах Ліверпуля і Гамбурга починаючи з 1957 року, і хоч часто давали виступи, змогли записати перший свій по-справжньому успішний диск «Sgt.Peppers» тільки у 1967 році.

    Малкольм Ґледвіл (Malcolm Gladwell) провів порівняння студентів берлінської музичної академії, які відносились до кращої, середньої та гіршої третин класу, поставивши їм питання про те, скільки часу вони вже займаються музикою:

    Студенти з усіх трьох груп почали займатись музикою приблизно в однаковому віці: близько п’яти років. У перші роки всі практикувались приблизно однаково: десь дві-три години на тиждень. Але у віці приблизно восьми років почали з’являтись відчутні відмінності. Студенти, які стали в кінці навчання в академії кращими у своїх класах, почали займатись більше ніж інші: шість годин на тиждень у дев’ять років, вісім годин у 12 років, 16 годин у 14 років, і далі все більше і більше, допоки у 20 років займались більше 30 годин на тиждень. У 20 років всі найкращі виконавці мали 10 000 годин музичної практики протягом життя. Середні студенти, для порівняння, мали 8 000 годин практики, а майбутні вчителі музики – тільки лише 4 000 годин.

    Тож, можливо, 10 000 годин, а не 10 років, і є магічним числом. (Анрі Картьє-Брессон (1908-2004) зазначив: «Ваші перші 10 000 фотографій – найгірші», але він робив більше ніж одну на годину). Семюель Джонсон (1709-1784) вважав, що потрібно навіть більше: «Майстерність у будь-якій галузі досягається тільки працею протягом всього життя; його не можна отримати за меншу ціну». І Чосер (1340-1400) висловлював сум: «життя таке коротке, майстерності так довго вчитись». Гіппократ (близько 400 до н.е.) відомий цитатою «ars longa, vita brevis», що є частиною довшого висловлювання «Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile», що можна перекласти як: «Життя коротке, майстерність тривала, можливості швидкоплинні, досвід дорогоцінний, розважливість важка». І хоч латиною ars може означати як мистецтво, так і майстерність, оригінальне грецьке слово τέχνη (техне) означає тільки «вміння», а не «мистецтво».

    Ви вирішили стати програмістом

    Ось мій рецепт досягнення успіху в програмуванні:

    • Зацікавтесь програмуванням і займайтесь цим заради задоволення. Намагайтесь зробити ці заняття настільки цікавими, щоб вам захотілось присвятити цьому ваші 10 років / 10 000 годин.
    • Програмуйте. Найкращий тип навчання – це навчання працею. Якщо більш детально, то «в обраній галузі найвищий рівень продуктивності не досягається автоматично як функція зростаючого досвіду, проте навіть для досвідченого фахівця рівень продуктивності може зрости як результат розмірених та спланованих зусиль на покращення» та «найбільш ефективне навчання потребує добре визначену задачу із доступним рівнем складності для конкретної людини, інформативного зворотного зв’язку, а також можливостей для повторень та виправлень помилок». Книга «Сприйняття на практиці: розум, математика та культура у повсякденному житті» (Cognition in Pracitce: Mind, Mathematics, and Culture in Everyday Life) є цікавим продовженням цього погляду.
    • Спілкуйтесь з іншими програмістами; читайте інші програми. Це значно важливіше в порівнянні з будь-якою книгою чи навчальним курсом.
    • Якщо у вас є таке бажання, присвятіть 4 роки навчанню у коледжі (або ще більше у магістратурі). Завдяки цьому ви отримаєте доступ до деяких посад, для яких потрібен диплом про освіту, а також зможете отримати більш глибокі знання в обраній спеціальності. Але якщо вам не подобається школа чи університет, то ви зможете (з деякою певністю) отримати аналогічний досвід самостійно або на робочому місці. У будь-якому разі лише книжних знань буде не достатньо. Як сказав Ерік Реймонд (Eric Raymond), автор книги «Новий словник хакера» (The New Hacker’s Dictionary), «навчання комп’ютерним наукам не може зробити когось фаховим програмістом, так само як вивчення пензлів та фарб не робить когось фаховим художником». Один з найкращих програмістів, якого я коли-небудь наймав, мав лише середню освіту; він створив великий об’єм надзвичайного програмного забезпечення, веде власну групу новин, і заробив достатньо щоб купити власний нічний клуб.
    • Працюйте над проектами разом з іншими програмістами. Будьте найкращим програмістом в деяких проектах; будьте найгіршим в деяких інших. Коли ви найкращий, вам потрібно перевіряти свої можливості вести проект та надихати інших своїм баченням. Коли ви найгірший, ви вчитесь тому, що вміють майстри, а також тому, що вони не хочуть робити (адже вони змушують робити це вас замість них).
    • Працюйте над проектами після інших програмістів. Намагайтесь розібратись в програмах, написаних кимось іншим. Дізнайтесь, як це зрозуміти та виправити щось, коли поруч немає авторів. Подумайте про те, як спроектувати власні програми, аби полегшити роботу для тих, хто буде їх супроводжувати після вас.
    • Вивчіть принаймні півдюжини мов програмування. Включіть у це число по одній мові із тих, які підтримують абстракцію класів (як Java або C++), функціональну абстракцію (як Lisp або ML), синтаксичну абстракцію (як Lisp), декларативні специфікації (як Prolog або шаблони C++), співпрограми (як Icon чи Scheme) та паралелізм (як Sisal).
    • Не забувайте, що термін «комп’ютерні науки» містить «комп’ютер». Дізнайтесь, скільки часу потрібно вашому комп’ютеру для виконання різних інструкцій, вибірки слова з пам`яті (з потраплянням і без потрапляння у кеш), читання послідовності слів з диску та пошуку нової ділянки на диску. (Відповіді наведені тут)
    • Прийміть участь у роботі по стандартизації мови програмування. Це може бути комітет по розробці стандарту ANSI C++ або це може бути вибір вашого локального стилю кодування, який міститиме 2 чи 4 пробіли відступу. У будь-якому випадку ви вивчите, що інші люди люблять у мові, як глибоко вони її відчувають, а також, можливо, трошки про те, чому вони відчувають саме так.
    • Але покличте на допомогу свій здоровий глузд, щоб правильно обрати час розлучення з цією працею по стандартизації.

    Якщо врахувати все сказане, виникають сумніви у тому, наскільки далеко можна просунутись, отримуючи лише книжкові знання. До народження моєї першої дитини я прочитав всі книги «Як вивчити…», і все одно почував себе недосвідченим початківцем. Як ви думаєте, чи став я перечитувати ці книги через 30 місяців, коли прийшов час народитися моїй другій дитині? Ні. Замість цього я покладався на власний досвід, котрий виявився набагато кориснішим і надійнішим, ніж тисячі сторінок написаних експертами.

    Фред Брукс (Fred Brooks) у своєму есе «Без срібних куль» (No Silver Bullets) навів план пошуку першокласних розробників програм, складений з 3-х частин:

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

    Це передбачає, що деякі люди вже мають якості, необхідні для того, щоб бути великим розробником; тож робота полягає в тому, щоб правильно переконати їх. Алан Перліс (Alan Perlis) висловив це більш коротко: «Кожного можна навчити як творити скульптури, проте Мікеланджело потрібно було навчитись як цього не потрібно робити. Те ж стосується видатних програмістів». Перліс говорить, що великі мають деяку внутрішню якість, яка виходить за межі їхнього навчання. Але звідки походить ця якість? Чи вона вроджена? Чи вони досягали її через старанність? Як каже Огюст Гюсто (Auguste Gusteau) – вигаданий кухар з мультфільму Рататуй (Ratatouille): “кожен може куховарити, але тільки безстрашні стають великими». Я дивлюсь на це більше як на готовність присвятити велику частину життя спланованій та розміреній практиці. Але, можливо, безстрашність підкреслює все це. Або, як каже критик Гюсто – Антон Его: «Не кожен може стати великим художником, але великий художник може прийти нізвідки».

    Тож не зупиняйтесь і купіть цю книгу з Java/Ruby/Javascript/PHP; можливо ви знайдете її в чомусь корисною. Але ви не зміните своє життя або своє вміння програмувати за 24 години, дні та навіть тижні. Як щодо того, щоб важко попрацювати безперервно протягом більше ніж 24 місяців? Що ж, тепер ви починаєте чогось досягати…

    Література

    Відповіді

    Приблизні витрати часу при виконанні різноманітних операцій на типовому персональному комп`ютері.

    Виконання однієї команди 1 нс = (1/1 000 000 000) с
    Вибірка слова з кеш-пам’яті першого рівня (L1 cache) 0,5 нс
    Помилка передбачення напрямку розгалуження 5 нс
    Вибірка слова з кеш-пам’яті другого рівня (L2 cache) 7 нс
    Закриття/відкриття м’ютексу 25 нс
    Вибірка слова з основної пам’яті 100 нс
    Переслати 2K за каналом 1Gbps 20 000 нс
    Послідовно прочитати 1MB з пам’яті 250 000 нс
    Прочитати з нової позиції на диску (seek) 8 000 000 нс
    Послідовно прочитати 1MB з диску 20 000 000 нс
    Відправити один пакет з США до Європи та назад 150 мс = 150 000 000 нс

     Додаток. Вибір мови

    Багато-хто з людей цікавиться, яку мову програмування слід вивчити у першу чергу. На це питання немає однозначної відповіді, але врахуйте наступне.

    • Скористайтесь допомогою друзів. На питання, яку операційну систему потрібно використовувати, Windows, Unix чи Mac, я зазвичай відповідаю: ту, яку використовують ваші друзі. Переваги, які ви отримаєте, коли вчитесь у ваших друзів, перевищать будь-які суттєві відмінності між різними операційними системами та мовами програмування. Подумайте про ваших майбутніх друзів: спільноту програмістів, частиною якої ви станете в майбутньому. Чи обрана вами мова має швидко зростаючу спільноту чи маленьку та вмираючу? Чи існують книги, веб сайти та онлайн форуми, звідки можна отримувати відповіді? Чи вам подобаються люди на цих форумах?
    • Не ускладнюйте собі життя. Такі мови програмування як С++ чи Java, створені для проведення професійної розробки за участі крупних колективів досвідчених програмістів, які намагаються отримати максимальну швидкодію створюваного ними коду. В зв`язку з цим такі мови мають складні частини, розроблені для подібних ситуацій. Вам потрібна мова легка для вивчення та запам’ятовування одним програмістом.
    • Грайтесь. Який спосіб вивчання гри на фортепіано ви оберете: звичайний, «інтерактивний», коли ви чуєте кожну ноту як тільки натискаєте клавішу, чи «пакетний» режим, в якому ви чуєте ноти тільки після того, як програли всю композицію? Зрозуміло, що інтерактивний підхід робить навчання грі на фортепіано легшим; те саме стосується й програмування. Зупиніться  на мові з інтерактивним режимом програмування та використовуйте його.

    Відповідно за цими критеріями, я порекомендував би в якості вивчення першої мови  програмування вибрати Python чи Scheme. Але все залежить від конкретних обставин і можна знайти багато інших підходящих  варіантів. Якщо ваш вік вимірюється однією цифрою, то вам може краще підійде Alice чи Squeak (старші також можуть вподобати ці мови). Важливіше за все обрати щось та почати працювати.

    Додаток. Книги та інші ресурси

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

    • 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).  Цю книгу багато-хто вважає сучасним нащадком вказаної вище книги Абельсона та Зюссмана. Вона представляє собою огляд найбільш значимих ідей програмування, покриваючи більш широке коло питань ніж книга Абельсона та Зюссмана, але, можливо, виявляється більш легкою для читання та вивчення. В ній використовується мова  Oz, яка не так сильно відома, проте є основою для вивчення інших мов програмування.

    Про автора

    Пітер НорвігПітер Норвіг (Peter Norvig) — американський вчений в галузі обчислювальної техніки та штучного інтелекту. На даний час працює директором з досліджень в компанії Google. Член Ради Американської асоціації штучного інтелекту. Співавтор книги “Штучний інтелект: сучасний підхід“, яка на даний час є стандартом з галузі ШІ в багатьох навчальних закладах. Раніше був головою Підрозділу обчислювальної техніки в дослідницькому центрі Amec NASA, де займався розробками NASA в галузях анатомії та робототехніки, автоматизованої розробки ПЗ, аналізу даних, нейроінженерії, розробки колективних систем, та прийнятті рішень на основі симуляцій.

    Оригінальна стаття Teach Yourself Programming in Ten Years by Peter Norvig (2001) на сайті автора.

    Особлива подяка за допомогу в перекладі Сергію Хараузову, студента групи ІС-21.