stats

Naucz się programowania w 10 lat

Popularny esej Petera Norviga, amerykańskiego informatyka, wykładowcy i ojca współczesnej sztucznej inteligencji, poddający pod wątpliwość przyspieszone podejście do nauki programowania.

Dlaczego wszystkim tak się śpieszy?

Wejdź do jakiejkolwiek księgarni i zobaczysz „Jak nauczyć się Javy w 24 godziny” w towarzystwie nieskończonych wariacji oferujących w kilka dni lub godzin naukę C, SQL-a, Ruby’ego, algorytmów i tak dalej. Wyszukiwanie zaawansowane Amazona dla [title: teach, yourself, hours, since: 2000] znalazło 512 tego typu książek. Z pierwszej dziesiątki dziewięć stanowią książki o programowaniu (pozostała dotyczy księgowości). Podobne wyniki ukazują się przy zastąpieniu „teach yourself” (naucz się) przez „learn” (ucz) bądź „hours” (godzin) przez „days” (dni)1.

Wniosek jest taki, że albo ludzie bardzo pośpiesznie chcą uczyć się o programowaniu, albo że programowanie jest jakimś sposobem bajecznie łatwiejsze w nauce niż inne rzeczy.

Felleisen et al. pochylają się nad tym trendem w książce „Projektowanie oprogramowania” (ang. „How to Design Programs”), gdy mówią: „Złe programowanie jest łatwe. Idioci mogą się go nauczyć w 21 dni, nawet jeżeli są głupi”. Odniósł się do tego również komiks „Abtruse Goose”.

Przeanalizujmy, co mógłby oznaczać tytuł podobny do „Naucz się C++ w 24 godziny”:

  • Naucz się: W 24 godziny nie będziesz mieć czasu na napisanie wielu ważnych programów i uczenie się z ich pomocą na błędach i sukcesach. Nie będziesz mieć czasu na pracę z doświadczonym programistą i na zrozumienie, jak to jest żyć w środowisku C++. W skrócie: nie będziesz mieć czasu, aby nauczyć się zbyt wiele. Książka może więc powiedzieć jedynie o powierzchownym podobieństwie, nie o głębokim zrozumieniu. Jak powiedział Alexander Pope: „odrobina nauki jest rzeczą niebezpieczną”.

  • C++: W 24 godziny możesz nauczyć się trochę składni C++ (jeżeli znasz już inny język), lecz nie będziesz w stanie nauczyć się wiele o użytkowaniu języka. W skrócie: gdyby twoim językiem programowania był np. Basic, możliwe byłoby nauczenie się pisania programów w stylu Basica z użyciem składni C++, lecz nie tego w czym naprawdę dobry (bądź zły) jest C++. Jaki w tym sens? Alan Perlis powiedział kiedyś: „Język, który nie wpływa na sposób twojego myślenia o programowaniu, nie jest wart nauki”. Jedno z możliwych uzasadnień mogłoby być takie, że musisz nauczyć się małego fragmentu C++ (albo, co bardziej prawdopodobne, czegoś jak JavaScript bądź Processing), bo potrzebujesz interfejsu z istniejącym narzędziem, aby zrealizować określone zadanie. Jednak wtedy nie uczysz się jak programować; uczysz się jak wykonać to zadanie.

  • w 24 godziny: Niestety, to za mało, co pokazuje kolejna sekcja.

Naucz się programowania w 10 lat

Badacze naukowi – Bloom (1985)2, Bryan i Harter (1899)3, Hayes (1989)4, Simmon i Chase (1973)5 – pokazali, że rozwinięcie wiedzy eksperckiej w dowolnej z wielu różnych dziedzin, zajmuje w przybliżeniu dziesięć lat, włączając w to grę w szachy, komponowanie muzyki, obsługę telegrafu, malarstwo, grę na pianinie, pływanie, grę w tenisa czy badania z zakresu neuropsychologii i topologii. Kluczem jest rozważna praktyka: nie tylko wykonywanie czegoś wciąż i wciąż, lecz stawianie sobie wyzwań z użyciem zadań, które wykraczają poza obecne zdolności, mierzenie się z nimi, analizowanie własnej wydajności przed i po ich wykonaniu, a także poprawianie błędów. Następnie powtarzanie. I kolejne powtarzanie. Wygląda na to, że nie ma drogi na skróty: nawet Mozart, który był cudownym dzieckiem muzyki w wieku 4 lat, potrzebował jeszcze 13 lat zanim zaczął tworzyć muzykę na światowym poziomie. Biorąc inny gatunek muzyczny: Beatlesi wydawali się wkroczyć na scenę z serią hitów i pojawić w programie Eda Sullivana w roku 1964. Jednak już wcześniej, od roku 1957, grywali oni w małych klubach Liverpoolu i Hamburga, i chociaż wcześniej cieszyli się masową popularnością, to ich pierwszym wielkim sukcesem w oczach krytyków była produkcja „Sgt. Pepper’s” wydana w roku 1967.

Malcolm Gladwell upowszechnił powyższy pogląd, chociaż skupia się na 10 000 godzinach, a nie 10 latach. Henri Cartier–Bresson (1908–2004) używał innego wskaźnika: „Twoje pierwsze 10 000 fotografii są twoimi najgorszymi”. (Nie przewidział, że dzięki aparatom cyfrowym niektórzy ludzie mogą osiągnąć ten poziom w ciągu tygodnia). Prawdziwa wiedza ekspercka może pochłonąć całe życie; Samuel Johnson (1709–1784) powiedział: „Mistrzostwo w każdej dziedzinie można osiągnąć tylko wysiłkiem całego życia; nie da się go kupić po niższej cenie”. Z kolei Chaucer (1340–1400) skarżył się, że „żywot tak krótki, rzemiosło tak długie do nauczenia”. Hipokrates (ok. 400 p.n.e) znany jest z cytatu Ars longa, vita brevis, który jest częścią dłuższej maksymy Ars longa, vita brevis, occasio praeceps, experimentum periculosum, iudicium difficile, tłumaczonej: „Życie krótkie, sztuka długa, okazja ulotna, doświadczenie niebezpieczne, sąd niełatwy”. Oczywiście, żadna liczba nie będzie ostateczną odpowiedzią: nie wydaje się rozsądnym zakładać, że wszystkie umiejętności (np. programowanie, gra w szachy, gra w warcaby bądź gra na instrumencie muzycznym) będą wymagały dokładnie takiego samego czasu do ich opanowania, ani że wszystkim ludziom zajmie to dokładnie tyle samo. Jak ujmuje to prof. K. Anders Ericsson: „W większości dziedzin niezwykłe jest to, jak dużo czasu potrzebują nawet najbardziej utalentowane jednostki, aby osiągnąć najwyższe poziomy uzdolnienia”6. Liczba 10 000 godzin po prostu daje poczucie, że mówimy o 10 do 20 godzin tygodniowo potrzebnych przez lata do osiągnięcia najwyższego poziomu przez tych, o których zwykło się mówić, że są najbardziej utalentowanymi jednostkami.

Więc chcesz zostać programistą?

Oto mój przepis na sukces w programowaniu:

  • Zainteresuj się programowaniem i zajmuj się nim, ponieważ sprawia frajdę. Upewnij się, że nie przestaje być wystarczająco zabawne, aby możliwym było poświęcenie mu dziesięciu lat / 10 000 godzin.

  • Programuj. Najlepszym rodzajem uczenia się jest uczenie się przez działanie. Ujmując to bardziej technicznie, „maksymalny poziom wydajności osób w danym obszarze nie jest automatycznie osiągalny jako funkcja zwiększającego się doświadczenia, ale poziom wydajności może być zwiększany nawet przez jednostki bardzo doświadczone w wyniku rozważnych wysiłków mających na celu doskonalenie się” (str. 366), a „najefektywniejsze uczenie się wymaga dobrze zdefiniowanego zadania z odpowiednim poziomem trudności dla konkretnej osoby, sensownej informacji zwrotnej, a także sposobności do powtarzania się i korygowania błędów” (str. 20–21). Książka „Poznanie w praktyce: umysł, matematyka i kultura w codziennym życiu” (ang. „Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life”)7 jest ciekawym odniesieniem do tego punktu widzenia.

  • Rozmawiaj z innymi programistami; czytaj inne programy. Jest to ważniejsze niż każda książka czy kurs.

  • Jeżeli chcesz, poświęć cztery lata na studia (lub więcej na studia podyplomowe). Dzięki temu uzyskasz dostęp do niektórych zawodów wymagających dyplomu, da ci to również głębsze zrozumienie dziedziny; jeżeli jednak nie lubisz szkoły, możesz (przy pewnym zaangażowaniu) zdobyć podobne doświadczenie samodzielnie bądź w pracy. W każdym razie uczenie się wyłącznie z książek nie wystarczy. „Edukacja informatyczna nie jest w stanie uczynić kogoś ekspertem w dziedzinie programowania bardziej, niż studiowanie pędzli i pigmentów nie uczyni kogoś ekspertem malarstwa” – powiedział Eric Raymond, autor „Nowego słownika hakerów” (ang. „The New Hacker’s Dictionary”). Jeden z najlepszych programistów, jakich kiedykolwiek zatrudniłem, miał tylko wykształcenie średnie; stworzył wiele świetnego oprogramowania, miał poświęconą sobie grupę dyskusyjną i zarobił wystarczająco w opcjach na akcje, aby kupić własny klub nocny.

  • Pracuj nad projektami z innymi programistami. Bądź najlepszym programistą w niektórych projektach; bądź najgorszym w innych. Gdy jesteś najlepszy, masz szansę sprawdzić się w prowadzeniu projektu, a także inspirować innych swoją wizją. Kiedy jesteś najgorszy, ucz się tego, co robią mistrzowie, a także tego, czego nie lubią robić (ponieważ każą ci robić to za nich).

  • Pracuj nad projektami po innych programistach. Zrozum program napisany przez kogoś innego. Zobacz, czego potrzeba, aby go zrozumieć i naprawić, gdy w pobliżu nie ma oryginalnych programistów. Pomyśl, w jaki sposób projektować własne programy, aby ułatwić zadanie tym, którzy będą się nimi zajmowali po tobie.

  • Naucz się co najmniej sześciu języków programowania. Uwzględnij jeden język, który kładzie nacisk na abstrakcje klasowe (jak Java czy C++), jeden kładący nacisk na abstrakcje funkcyjne (jak Lisp, ML bądź Haskell), jeden obsługujący abstrakcje składniowe (jak Lisp), jeden z obsługą specyfikowania deklaratywnego (jak Prolog czy szablony z C++), a także jeden, w którym nacisk położono na współbieżność (jak Clojure lub Go).

  • Pamiętaj, że w pojęciu „nauki komputerowe” jest termin „komputer”. Dowiedz się jak długo zajmuje twojemu komputerowi wykonanie instrukcji, pobranie słowa z pamięci (zarówno z trafieniem w wartość z pamięci podręcznej, jak i bez niego), odczyt kolejnych słów z dysku, a także przesunięcie się do nowej dyskowej lokalizacji. (Tu odpowiedzi).

  • Zaangażuj się w wysiłki zmierzające do standaryzacji języków. Może być to komitet ANSI C++, albo może być to podejmowanie decyzji odnośnie tego, czy twój styl kodowania będzie polegał na 2 bądź 4 spacjach do oznaczania poziomów wcięć. W każdym razie dowiaduj się, co innym ludziom podoba się w języku, jak głęboko to czują, a może nawet dlaczego tak to czują.

  • Miej wyczucie kiedy należy przestać zajmować się standaryzacją języków, tak szybko, jak to możliwe.

Mając na uwadze powyższe, powstaje wątpliwość, jak daleko zaprowadzić cię może uczenie się wyłącznie z książek. Zanim urodziło się moje pierwsze dziecko, czytałem wszystkie książki How To, a wciąż czułem się jak bezradny nowicjusz. Czy 30 miesięcy później, gdy pojawiło się drugie dziecko, wróciłem do tych książek, aby odświeżyć wiedzę? Nie. Zamiast tego polegałem na osobistym doświadczeniu, które okazało się o wiele bardziej użyteczne i uspokajające, niż tysiące stron napisanych przez ekspertów.

Fred Brooks, w napisanym przez siebie eseju „Brak srebrej kuli” (ang. „No Silver Bullet”)8 nakreślił trzyczęściowy plan znajdowania świetnych projektantów oprogramowania:

  1. Systematycznie identyfikuj najlepszych projektantów możliwie najwcześniej.

  2. Przypisz zawodowego mentora, który będzie odpowiedzialny za rozwój nowicjusza i starannie przechowuj dokumentację kariery.

  3. Stwórz rozwijającym się projektantom możliwości interakcji i wzajemnej stymulacji.

Zakłada to, że niektórzy ludzie mają już cechy niezbędne do stania się wspaniałymi projektantami; zadanie polega na odpowiednim przekonaniu ich. Alan Perlis ujął to nieco zwięźlej: „Każdego można nauczyć rzeźbiarstwa: Michała Anioła trzeba by było nauczyć, jak tego nie robić. Podobnie jest ze świetnymi programistami”. Perlis mówi, że ludzie wielcy mają wewnętrzną jakość, która wykracza poza proces ich szkolenia się. Jednak skąd pochodzi ta jakość? Czy jest wrodzona? Czy może wykształcają ją pracowitością? Jak ujął to Auguste Gusteau (fikcyjny szef kuchni z „Ratatouille”): „Każdy może gotować, ale tylko nieustraszeni mogą być wielcy”. Mam tu na myśli bardziej chęć poświęcenia przez kogoś znacznej części własnego życia na rozważną praktykę; lecz może sposobem na podsumowanie tego jest nieustraszoność; lub też, jak mawia krytyk Gusteau, Anton Ego: „Nie każdy może być wielkim artystą, ale wielki artysta może objawić się w każdym”. Śmiało więc, kup tę książkę o Javie/Rubym/JavaScripcie/PHP – prawdopodobnie do czegoś ci się przyda. Jednak nie zmieni twojego życia, ani twojej ogólnej wiedzy programistycznej w 24 godziny czy 21 dni. Co powiesz na ciężką pracę, aby ciągle doskonalić się przez 24 miesiące? Cóż, teraz zaczynamy dokądś zmierzać…

Odpowiedzi

Przybliżony czas wykonywania różnych operacji na typowym komputerze:

wykonaj typową instrukcję1/1 000 000 000 s = 1 nanosekunda
pobierz z pamięci podręcznej L10,5 nanosekundy
błąd prognozy rozgałęzienia5 nanosekund
pobierz z pamięci podręcznej L27 nanosekund
blokuj/zwolnij mutex25 nanosekund
pobierz z pamięci głównej100 nanosekund
wyślij 2 K bajtów przez sieć 1 Gbps20 000 nanosekund
odczytaj 1 MB sekwencyjnie z pamięci250 000 nanosekund
pobierz z nowej lokalizacji na dysku (pozycjonowanie)8 000 000 nanosekund
odczytaj 1 MB sekwencyjnie z dysku20 000 000 nanosekund
wyślij pakiet z USA do Europy i z powrotem150 milisekund = 150 000 000 nanosekund

Dodatek: Wybór języka

Kilkoro ludzi zapytało, jakiego języka programowania powinni nauczyć się najpierw. Nie ma jednej odpowiedzi, ale rozważ te punkty:

  • Skorzystaj ze znajomych. Gdy jestem pytany o to, „jakiego systemu operacyjnego powinienem/powinnam użyć: Windows, Uniksa czy Maka”, moja odpowiedź zazwyczaj jest następująca: „użyj tego, czego używają twoi znajomi”. Korzyść związana z uczeniem się od przyjaciół zrównoważy wszelkie wewnętrzne różnice między OS-ami, a nawet językami programowania. Przemyśl też, jacy będą twoi przyszli znajomi: społeczność programistów, której staniesz się częścią, gdy będziesz kontynuować. Czy wybrany przez ciebie język programowania ma dużą, powiększającą się społeczność, czy może małą, ginącą? Czy istnieją książki, strony webowe bądź fora online, z których można uzyskać odpowiedzi? Czy lubisz ludzi z tych forów?

  • Zachowaj prostotę. Języki programowania, takie jak C++ i Java, są stworzone do profesjonalnego budowania aplikacji przez duże zespoły doświadczonych programistów, którzy troszczą się o czasową wydajność wykonywania swojego kodu. W rezultacie języki te mają skomplikowane części zaprojektowane na takie okoliczności. Twoim zmartwieniem powinno być uczenie się programowania. Nie potrzebujesz komplikacji. Chcesz języka, który zaprojektowany został tak, aby każdy nowy programista mógł łatwo się go uczyć i zapamiętywać.

  • Baw się. W jaki sposób chciałbyś/chciałabyś nauczyć się gry na pianinie: w zwykłym, interaktywnym, gdzie słyszysz każdą nutę, kiedy tylko naciśniesz klawisz, czy w trybie „wsadowym”, gdzie słyszysz nuty dopiero, kiedy skończysz cały utwór? Najwyraźniej tryb interaktywny czyni proces nauki łatwiejszym w przypadku pianina, ale również w przypadku programowania. Obstawaj przy języku, który ma tryb interaktywny i korzystaj z niego.

Biorąc pod uwagę te kryteria, moje zalecenia odnośnie pierwszego języka programowania to Python lub Scheme. Innym wyborem jest JavaScript, nie dlatego, że jest doskonale zaprojektowany dla początkujących, lecz dlatego, że istnieje dla niego wiele samouczków online, takich jak podręcznik Khan Academy. Twoje okoliczności mogą się jednak różnić i istnieją inne, dobre wybory. Jeżeli jesteś w jednocyfrowym wieku, możesz woleć języki Alice, Squeak lub Blockly (ten może również spodobać się starszakom). Ważne jest, żeby dokonać wyboru i zacząć.

Dodatek: książki i inne zasoby

Kilkoro ludzi zapytało, z jakich książek i stron webowych powinni się uczyć. Powtórzę, że „nauka z książek nie będzie wystarczająca”, ale mogę polecić następujące:

Uwagi

T. Capey zwraca uwagę, że strona książki „Complete Problem Solver” na Amazonie zawiera teraz pozycje „Naucz się bengalskiego w 21 dni” i „Naucz się gramatyki i stylu” w sekcji Klienci, którzy zakupili ten przedmiot, kupili również te. Domyślam się, że duża część ludzi, którzy poszukiwali tej książki pochodzi z tej strony. Dziękuję Rossowi Cohenowi ze pomoc z Hipokratesem.

Peter Norvig (Copyright 2001–2014)


  1. Polskie tłumaczenia wyszukiwanych fraz (przyp. tłum.) ↩︎

  2. Benjamin Bloom (red.), „Developing Talent in Young People”, Ballantine, 1985. ↩︎

  3. W.L. Bryan, N. Harter, „Studies on the telegraphic language: The acquisition of a hierarchy of habits” [w:] „Psychology Review”, 1899, 8, 345–375. ↩︎

  4. John R. Hayes, „Complete Problem Solver Lawrence Erlbaum”, 1989. ↩︎

  5. William G. Chase, Herbert A. Simon, „Perception in Chess” [w:] „Cognitive Psychology”, 1973, 4, 55–81. ↩︎

  6. Różnice między poszczególnymi rodzajami zdolności mogą być bardzo duże, por. „Deliberate Practice and Performance in Music, Games, Sports, Education, and Professions: A Meta-Analysis” (przyp. red.) ↩︎

  7. Jean Lave, „Cognition in Practice: Mind, Mathematics, and Culture in Everyday Life”, Cambridge University Press, 1988. ↩︎

  8. Fred Brooks, „No Silver Bullet. Essence and Accidents in Software Engineering”, IEEE Computer, wyd. 20, nr 4, 1987, str. 10–19. ↩︎

Tłumaczenie: PW
Źródło: www.norvig.com
Jesteś w sekcji .
Tematyka:

Taksonomie: