Научи се да програмираш за десет години
Питър Норвиг
(първоизточникът на английски е тук)
Защо толкова бързат всички?
Влез в коя да е книжарница и ще откриеш как да научиш Java за 7 дни, редом с още безброй подобни предложения за няколко дни или часа, отнасящи се до Visual Basic, Windows, Internet и пр. Търсене с думите „teach yourself days“ сред книгите в Amazon ми дава няколкостотин заглавия. Почти всички са компютърна литература. Същото получавам, ако вместо „days“ напиша „hours“, като заглавията са даже повече.
Изводът е, че или хората искат спешно да изучат компютрите, или че някак си компютрите са – повече от всичко друго – поразително лесни за овладяване. Няма книги за това как да научиш за няколко дни Бетовен, квантова физика или дори как да се грижиш за куче. Фелайзен и др. обръщат внимание на тази тенденция в книгата си Как да съставяме програми, като казват: „Лесно е да се програмира зле. Идиотите могат да се научат за 21 дни, дори ако са тъпаци.“ (Авторите се шегуват, като използват в твърдението и двете изобилно употребявани в заглавията думи: idiots (идиоти) и dummies (тъпаци). – бел. прев.)
Да разсъдим какво би могло да означава заглавие като Научи C++ за три дни.
- Научи
- За три дни няма да успееш да напишеш няколко значителни програми и да се поучиш от успехите и неуспехите си в това начинание. Няма кога да работиш с опитен програмист и да получиш представа какво значи да живееш със C++ като работна среда. Накъсо, нямаш време да научиш много. Тъй че книгата би могла да предлага само повърхностно запознанство, но не и задълбочено разбиране. Както казва Ал. Поуп, малкото знание е опасно.
- C++
- За три дни може да успееш да научиш някои от граматичните правила на C++ (ако вече знаеш друг език), но не би могъл да узнаеш много за използването му. Ако, да речем, програмираш на Basic, би могъл да се научиш да пишеш като на Basic със синтаксиса на C++, но няма да узнаеш в какво всъщност C++ е добър и в какво не е. Тогава има ли смисъл? Алън Пърлис беше казал: „Език, който не променя представата ти за програмиране не си струва да се знае“. Може да е нужно да научиш наистина само малко C++ (по-скоро примерно JavaScript или Flex), ако за решаването на дадена задача трябва да използваш нещо вече написано. Тогава обаче не се учиш да програмираш, а как да решиш конкретната задача.
- за три дни
- За съжаление толкова не стигат, както става ясно по-долу.
Научи се да програмираш за десет години
Изследователи (Блум (1985), Брайън и Хартър (Bryan, W.L. & Harter, N. Studies on the telegraphic language: The acquisition of a hierarchy of habits. Psychology Review, 1899, 8, 345-375), Хейс (1989) и Чейс и Саймън (1973)) сочат, че в много области опитност се придобива за около десет години. Такива са играта на шах, съчиняването на музика, предаването с телеграф, рисуването, свиренето на пиано, плуването, тениса и извършването на изследвания по неврофизиология и топология. Крайно важно е упражняването да става целенасочено: не само да правиш нещо пак и пак, а да си поставиш цел, която е малко над възможностите ти за момента, да се опиташ да я постигнеш, като анализираш как се справяш по време на и след изпълнението, и да поправяш грешките си. После повтаряш. И отново. Оказва се, че преки пътища няма. Дори при Моцарт, който още четиригодишен бил музикално дете чудо, е било нужно да минат още тринайсет години, за да почне да пише първокласна музика. Ако погледнем друг жанр, през 1964 г. Бийтълс като че изведнъж изстреляха цял ред парчета №1 в класациите и се появиха в шоуто на Ед Съливан. Само че те още от 1957 г. свиреха по малки клубове в Ливърпул и Хамбург. Пък и макар отрано да имаха успех сред широката публика, критиката ги оцени високо едва със „Сарджънт Пепър“ през 1967 г.
Малкъм Гладуел съобщава за проучване сред студенти от Берлинската музикална академия, в което се сравняват най-добрата, средната и най-слабата по успех третини от един клас, като студентите са били запитани колко дълго са се упражнявали.
„Всеки от всяка от трите групи е почнал да свири горе-долу на една възраст, около петгодишен. През първите си няколко години всеки се е упражнявал еднакво много с другите – около два или три часа седмично. Съществена разлика се появява около осемгодишна възраст. Тогава оказалите се най-добри в класа са започнали да се упражняват повече от останалите: на девет години – по шест часа седмично, на дванайсет – по осем, на четиринайсет – по шестнайсет, и все по повече, докато към двайсетгодишни се упражняват вече по доста над трийсет часа седмично. Към тази възраст най-добрите изпълнители са натрупали през живота си по 10 хил. часа упражнения. В сравнение с тях, просто добрите са натрупали по 8 хил. часа, а бъдещите учители по музика – по малко над 4 хил.“
Така че може да се окаже, че вълшебното число е не 10 г., а 10 хил. ч. Самюъл Джонсън (1709-1784) е смятал, че отнема повече: „Съвършенство в коя да е област може да бъде достигнато само с работа до живот; на по-малка цена не се купува“. Чосър (1340-1400) пък се жалва: „животът е тъй кратък, умение тъй бавно се постига“. Хипократ (ок. 400 пр. Хр.) е известен със съкратеното „ars longa, vita brevis“, което е част от по-дългия цитат „Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile“, което може да се преведе като „Животът е къс, умението дълго (за научаване), възможностите – мимолетни, опитът подвежда, преценката – трудна“. Въпреки че на латински ars може да значи и „изкуство“, и „занаят“, гръцката дума τέχνη (техне) от първоизточника е само „умение“, а не „изкуство“.
Ето рецептата ми за успех в програмирането:
- Заинтересувай се от програмиране и се позанимавай за забава. Постарай се да запазиш забавата задълго, тъй че да имаш желание да посветиш десет години.
- Общувай с други програмисти. Чети чужди програми. Това е по-важно от кой да е учебник или курс за обучение.
- Програмирай. Най-добре се учи чрез практика. Казано по-формално, „Максимална производителност на работещите в дадена област не се постига в резултат просто на натрупване на опит. Дори у много опитни работници производителността може да бъде повишена чрез целенасочени усилия за подобрение“ (вж. тук). А също, „най-успешното научаване изисква добре формулирана задача с подходяща за конкретния човек трудност, информативна обратна връзка и възможност за повтаряне и поправяне на грешки“. По интересен начин този възглед е застъпен в книгата Познанието в практиката: мислене, математика и култура във всекидневието.
- Може, ако искаш, да отделиш четири години за колеж, или повече за университет. Това ще ти осигури достъп до работни места, за които се изисква образователен ценз, а ще ти даде и по-дълбоко разбиране на областта. Ако пък училището не ти допада, можеш да придобиеш подобни умения и на работа, стига да бъдеш достатъчно отдаден на това. Във всеки случай ученето само от учебник няма да стигне. „Образованието по информатика не може да направи никого истински програмист, поне доколкото и чрез изучаване на четки и бои не се става художник“ – това казва Ерик Реймънд, авторът на Нов речник на хакера. Един от най-добрите наемани от мен програмисти беше с едва средно образование, но той написа множество страхотни програми. Сега има фенгрупа в мрежата и спечели достатъчно на борсата, че да си купи нощен клуб. (Става дума за Джейми Завински (Jamie Zawinski); вж. също интервюто с него в тази книга – бел. прев.)
- Работѝ по проекти с други програмисти. Бъди най-добрия програмист в някои от проектите и най-слабия в други. Когато си най-добър, имаш възможност да се провериш като водещ в проект и да увличаш другите с мащаба на погледа си върху работата. Когато си най-слабия, научаваш как действат майсторите и какво не обичат да правят (защото карат теб да го вършиш вместо тях).
- Работѝ по проекти, над които са работили други програмисти. Разчитай програми, писани от друг. Обръщай внимание какво е нужно, за да разчетеш и поправиш програма, авторът на която не е на разположение. Обмисляй как да съставяш програмите си, че на тези след теб да е по-леко да ги поддържат.
- Научѝ поне пет или шест езика за програмиране. Сред тях да има език като Java или C++ с абстрахиране чрез класове, език като Lisp или ML с функционален стил, език със синтактично абстрахиране като при Lisp, език с декларативен стил (каквито са Prolog или механизмът на шаблоните в C++), език със съпрограми, като при Icon или Scheme и език за паралелно програмиране – напр. SISAL.
- Помнѝ, че компютърната информатика наистина е компютърна. Знай за колко време на твоя компютър се изпълняват команди, извлича се дума от паметта (когато е и когато не е в кеша), четат се съседни стойности от диск и се стига до ново място за четене върху него. (Примерни стойности се дават по-долу.)
- Включѝ се в работата на някоя група по стандартизиране на език за програмиране. Може да е тази на ANSI C++, а може и да е такава, грижа на която е да реши дали в колектива ви да се пише с отстъп от два или четири интервала. Каквато и да е групата, така научаваш какво харесват другите в езика, колко сериозно се отнасят към това, а може би и отчасти защо така смятат.
- Имай здравия разум да се отървеш от заниманията по стандартизиране колкото може по-скоро.
След всичко казано, спорно остава колко можеш да напреднеш само с четене на учебници. Преди да се роди първото ми дете изчетох всички книги от вида „как да …“, но все още се чувствах нищо неразбиращ новак. Върнах ли се за припомняне към книгите след трийсет месеца, когато наближи да се ражда второто? Не – вместо това разчитах на личния си опит, който се оказа за мен много по-полезен и надежден от хилядите написани от специалисти страници.
В есето си за сребърния куршум Фред Брукс посочва план от три точки за откриване на големи програмисти:
- Редовно се оглеждай за най-добрите проектанти, за да ги разпознаеш колкото може по-рано.
- Назначи наставник да отговаря за професионалното развитие на перспективния сътрудник и грижливо следи това развитие.
- Осигури възможност израстващите проектанти да общуват и се подтикват един другиго.
Това предполага, че някои хора така или инак вече имат качества на големи проектанти; задачата е да се насочват правилно. Алан Пърлис е по-лаконичен: „Да скулптира можеш да научиш всекиго. Микеланджело би се наложило да го учиш как не трябва. Така е и при големите програмисти“.
В крайна сметка купи си някоя от онези книги за „бързо учене“ – сигурно ще извлечеш от нея нещо полезно. Няма обаче нито да промениш живота си, нито действителната си квалификация като програмист за двайсет и четири часа, дни, дори месеца.
Справка за приблизителните времена за изпълняване на различни действия на типичен ПК (2001 г.)
изпълнение на типична команда | 1 / 1 000 000 000 sec = 1 nanosec
|
достъп до кешпамет L1 | 0,5 nanosec
|
неуспял преход | 5 nanosec
|
достъп до кешпамет L2 | 7 nanosec
|
заключване/отключване на mutex | 25 nanosec
|
достъп до основната памет | 100 nanosec
|
изпращане на 2K байта през мрежа 1Gbps | 20 000 nanosec
|
последователно четене на 1MB от основната памет | 250 000 nanosec
|
достъп до диск с преместване (търсене) | 8 000 000 nanosec
|
последователно четене на 1MB от диск | 20 000 000 nanosec
|
изпращане на пакет от САЩ до Европа и обратно | 150 msec = 150 000 000 nanosec
|
Приложение: избор на език
Някои питат с кой език за програмиране да започнат. Еднозначен отговор няма, но имай предвид следното.
Използвай приятелите си. На въпроса „коя операционна система да използвам – Windows, Unix или Mac?“, обикновено отговарям „тази, която използват приятелите ти“. Предимството да учиш от приятелите си прави незначителна всяка разлика между системи и езици за програмиране. Има значение и кои ще са ти приятели в бъдеще: общността от програмисти, в която ще си, ако продължиш. Дали избраният от теб език има голяма и растяща или малка и отмираща общност? Има ли книги, уебсайтове и форуми, където би могъл да получиш отговори на въпросите си? Допадат ли ти хората там?
Избягвай сложното. Езици като C++ и Java са проектирани за професионално програмиране в големи колективи от опитни програмисти, за които бързодействието на програмите е важен фактор. Затова тези езици съдържат сложни механизми, проектирани с оглед на такива нужди. Твоята грижа е да се учиш на програмиране и тези усложнения не ти трябват. Трябва ти език, замислен да бъде лесен за научаване и помнене от отделен програмист новак.
„Свирѝ“. По кой начин би се научил да свириш на пиано: естествения, диалогов начин, при който чуваш звук щом натиснеш клавиш, или „пакетния“, при който чуваш нотите едва след завършека на песента на клавиатурата? Ясно е, че при диалоговия начин ученето и на пиано, и на програмиране е по лесно. Придържай се към език с диалогов режим и го използвай.
От гледна точка на изброеното препоръката ми за първи език за програмиране е Python или Scheme. Обстоятелствата при теб може да са други и тогава имаш други добри възможности за избор. Ако си на едноцифрена възраст, може да предпочетеш Alice или Squeak (които може да се харесат и на по-възрастни). Важното е да избереш и почнеш.
Приложение: книги и други източници
Някои питат кои книги и уебстраници да използват за учене. Повтарям, че ученето само по книга не е достатъчно, но мога да препоръчам следното:
- Scheme
- • Структура и интерпретация на компютърни програми: може би най-добрият увод в информатиката. Учи на програмиране като подход към информатиката. По книгата има филмирани лекции. Самата тя също е свободнодостъпна в мрежата. Трудна е – за някои по-подходящи са други книги.
- • Как да съставяме програми, 2-о изд.: една от най-добрите книги за съставяне на истински, елегантни и работещи програми. (Текстът на това издание все още (2010) се пише, но свободнодостъпен уебвариант има и първото издание – бел. прев.)
- (Други две отлични и свободнодостъпни книги са Езикът за програмиране Scheme, 4-то изд. и Просто Scheme, 2-о изд. – бел. прев.)
- Python
- • Програмиране на Python: увод в информатиката е добър увод с езика Python
- • Няколко ръководства
- Oz
- Понятия, похвати и модели на програмирането е смятана за съвременен наследник на Структура и интерпретация …. Тя е обиколка из главните идеи на програмирането, включваща по-широк кръг от теми в сравнение със Структура и интерпретация …, а заедно с това е може би по-лесна за четене. Използваният в нея език Oz не е широко известен, но е основа за опознаване на други езици. (Налице е свободнодостъпен предпечатен вариант на тази книга – бел. прев.)
Peter Norvig (Copyright 2001)