Jak najlepiej uczyć programistów?

Wykorzystawszy wszystkie możliwości, jakie oferowały pliki *.bat w dosie, jakimś cudem wszedłem w posiadanie książki o podstawach C/C++. Autorowi powinno się połamać palce za pisanie takiego szmelcu i może właśnie ogólny poziom tego produktu książkodpodobnego był powodem tego, że przez dłuższy czas nie mogłem zrozumieć pewnych rzeczy (i dałem sobie z nimi spokój na jakiś czas), ale w końcu co nieco załapałem (wskaźniki to jest bardzo prosta rzecz, ale dopiero wtedy, gdy się je już rozumie). Inna sprawa, że młody byłem. Tak, czy siak, później przyszła pora na assembler, no a dalej całość już się jakoś potoczyłą (gdzie gigantyczny skok jakościowy przyszedł wraz ze stałką i dołączeniem do załogi G... znaczy -- PLD).

Do czego zmierzam? Otóż znajomość niskopoziomowych rzeczy jest praktycznie niezbędna do pełnego zrozumienia jak działa system, ale ze względu na jednak dosyć wysoko ustawioną poprzeczkę na wejściu (jak ja się namęczyłem z załapaniem tych pointerów) i tendencję młodych ludzi do popadania w skrajność (premature optimization is the root of all evil, ale niestety nie zrozumie tego ktoś, kto nie ma odpowiedniej perspektywy, bo zna tylko tę jedną rzecz; assssembler my presssssciousssss; i mówię to tak z obserwacji innych, jak i z własnego doświadczenia), doszedłem do wniosku, że naukę powinno się zaczynać od czegoś, co nie wymaga zagłębiania się w niskopoziomowe meandry. Java? C#? Python? (Python na pewno :). Zrozumienie tych języków pozwala na wydajne pisanie działających programów, które coś robią. Później można się doszkolić w szczegółach działania stosu, rejestrach, null termination, prymitywnych dziurach w stdlibie C, wskaźnikach i hgw czym jeszcze. Ale to dopiero jako dodatek po opanowaniu wysokopoziomowych podstaw.

Jednak Joel Spolsky twierdzi, że takie myślenie jest błędne i żeby programista rzeczywiście się do czegoś nadawał, to powinien zaczynać właśnie od rzeczy niskopoziomowych (sam stawia na "Język C" K&R co dla mnie jest wręcz bluźnierstwem, bo ja z tego klocka nie korzystam, bo jest zbyt ciężkostrawny, mimo, że C znam). Cholernie kłóci się to z moimi własnymi wnioskami i "podstawami pedagogiki", że tak powiem (uczy się od ogółu do szczegółu, a nie vice versa), ale może on ma rację? Ja nie zaczynałem od Javy. Znajomego licealistę uważam za obiecującego właśnie dlatego, że zna assemblera (i pomimo negatywnych tego efektów), a nie dlatego, że cośtam tłucze w Pascalu. A wy? Od czego wyście zaczynali? (znaczy, to jest pytanie retoryczne, bo większość dobrych programistów mnie czytających jest pewnie za starych, by zaczynać od czegoś innego, niż assembler 86 i C; więc zapytam inaczej -- jakie jest wasze zdanie o tym, od czego powinno się zaczynać naukę?)

  1. 1. Enif

    Ja zaczynałem od Basic'a na moim komunijnym C64 z syntezą mowy :] Chociaż w technikum rok trzaskałem assemblera i wiem, że aby być prawdziwym magikiem trzeba go mieć w małym palcu to jednak szczerze nie lubie tego języka i programowania ze specyfikacją na kolanach. Znajomym polecam start od C lub HTML'a :)

  2. 2. Nazon

    IIMHO naukę programowanie powinno się zaczynać od... czegoś co za cholerę nie przypomina języka programowania - jakiegokolwiek poziomu.
    Bo jak dla mnie programowanie to po prostu odpowiedni sposób myślenia, podejścia do problemów, postrzegania możliwości i oceniania potencjalnych rozwiązań.

    A sposobu myślenia nie da się nauczyć - najwyżej można go wytrenować długą praktyką. Język programowania jest już tylko narzędziem do wykonania celu (często specyficznym dla celu ;) ).

    Wracając do tematu "szkolenia programostów":
    - warto zauważyć tendencję, że często (przy założenu podobnej znajomoścui wymaganej technoloogii, bez patrzenia na resztę wiedzy "informatycznej") na stanowiska programistów poszukiwane są osoby kończące studia związane np. fizyką [modelowanie procesów] czy matematyką.
    - nie ma co zakładać "zaczynajmy od obiektowego języka wysokiego poziomu a kończmy na assemblerze" (lub odwrotnie) - napływ technologi, możliwości jakie one niosą, szybkość z jaką się rozwijają nie pozwala być dobrym we wszystkim. A lepiej być w czymś konkretnym dobrym niż znać "po łebkach" wszystko.

    Ze swojego osobistego doświadczenia raczej skupiłbym się na jednej rzeczy, a nie uczył np assemblera żeby potem programowanie obiektowe lepiej zrozumieć.

    Reasumując: jak dla mnie kurs programowania powinien zaczynać się od hipotetycznych problemów logicznych koniecznych do rozwiązania za pomocą danego zestawu narzędzi (na starcie niekoniecznie związanych z jakimkolwiek językiem programowania).
    A jeśłi chodzi o naukę indywidualną - IMHO oba podejścia są dobre. A raczej oba są całkowicie nieprzewidywalne. Bo to jest kwestia bardzo indywidualna. Jeśli kogoś zafascynował assembler język niskiego poziomu czy podobało mu się programowanie strukturalne, to potem może podświadomie popełniać błędy z tym związane programjąc obiektowo.

  3. 3. marcoos

    Moja ewolucja:

    (podstawówka) Commodore 64 BASIC V2 -> assembler 6502 -> Microsoft AmigaBASIC -> AMOS -> odrobinka Rexxa (ARexx na Amidze, nic z już tego poza 'say "hello world"' nie pamiętam ;))

    (liceum) -> C, pseudo-C++, PHP, JavaScript

    (studia) -> "prawdziwe" C++, Java, C#, assembler x86, ostatnio wmusili we mnie na uczelni ASP/VisualBasic.

    Najbardziej dumny jestem z tego, że udało mi się uniknąć Pascala, mimo że zewsząd mnie atakował. :-)

  4. 4. ggodlewski

    Basic -> Pascal -> Assembler -> C -> C++ -> PHP
    A po drodze pare innych drobnych.
    Naukę trzeba zaczynać od jakiegoś języka skryptowego, gdzie nie trzeba deklarować zmiennych, martwić się typami, alokacją pamięci. A potem jakieś C, potem Assembler :)

  5. 5. gszczepa

    BASIC->Assembler(Atari)->Pascal->C(PC-Win)->C++->Python(PC-Linux)
    Inna sprawa że większość rzeczy które obecnie pisuję to bash+awk. Python jest niezłym wyborem do nauki ale brakuje mu trochę rygoryzmu który dobrze na początku mieć - zaleta Pascala, niestety Pascal jest nieco przestarzały.

  6. 6. axquan

    Może lepiej zacząć od dosyć oczywistej rzeczy, trzeba *coś* robić i owym cosiem jest praktyka. Wiem, bo sam popadłem w teoretyzacje i jak wspomniał Nazon, "po łebkach" to znam prawie wszystko :-D Ale konkretnie nic.

  7. 7. axquan

    A Joel nie jest wyrocznią, pamiętaj o tym :)

  8. 8. Jajcus

    1. BASIC na ZX Spectrum
    2. BASIC na Atari
    3. Assemler 6502
    4. Action!
    5. Pascal
    6. C, C++
    7. bash, perl
    8. Python

    Po nieznaczące drodze przygody z Logo, OCAML i różnymi innymi dziwnymi językami.

  9. 9. zgoda (jarek)

    Ja zacząłem od paszczala, ale potem był fortran i ada. Niestety, pracę znalazłem w paszczalu (a właściwie w ObjectPascalu/Delphi) i tak już mi zostało.
    Joela S. cenię za co innego więc pozwalam sobie mieć inne zdanie w tej kwestii. Każdy powinien zaczynać od tego, co mu odpowiada i lubi (matematycy od assemblera, C i lispa, humaniści od Pythona, Ruby czy paszczala), zwłaszcza "lubienie" jest ważne na początku, bo bardzo łatwo jest się zniechęcić.

  10. 10. Ktos

    "humaniści od Pythona, Ruby czy paszczala"
    o, jestem humanistą :)

    Bo ewolucja wyglądała tak: Basic -> Pascal -> Delphi + potem PHP, teraz zaczątki C# i Pythona

    Asma nie umiem. C nie umiem. I żyje mi się z tym dobrze :)

  11. 11. Nazon

    Jakoś też się nie zgadzam z teorią zgody (jarka) odnośni podziału humaniści-matematycy.
    Generalnie w "zawodzie" programistów raczej nieczęsto spotyka się humanistów. Raczej nie jest to zajęcie dla ludi myślących w "humanistyczny" sposób.
    A obecnie jeszcze nie ma możliwości porównania który schemat jest lepszy - zauważmy, że większość osób z doświadczeniem zajmujących się programowaniem, raczej nie miała możliwości rozpocząć nauki od języka obiektowego wysokiego poziomu - nie było takiego.
    Dlatego na temat jaki model nauki programowania możemy tylko teoretyzować. Prawda jest taka, że jak ktoś umie _programować_ to znajomość konkretnego języka będzie tylko znajomością innych technik, możliwości i narzędzi.

  12. 12. zgoda (jarek)

    Podział na "humanistów" i "matematyków" nie odzwierciedla rzeczywistych naukowych upodobań, raczej skłonność akceptowania różnych poziomów abstrakcji.

  13. 13. DeeJay1

    Assembler to całkiem sprawna rzecz ale a) ja nie trawię b) jak się zna wszystkie możliwe architektury, bo wywalić program na innej arch dość łatwo :)
    Moja ścieżka to C64 Basic -> Delphi -> Paszczal -> C/C++ -> obecnie Java i C#, Pythona to jak kiedyś będę miał wystarczająco dużo czasu, by wywiedzieć się jak "Hello world" napisać ;)

  14. 14. Bender

    Też zaczynałęm na C64 i Basic. :)
    Później Pascal, C, C++ i niestety Java, którą mi na siłe wciskają w szkole i której mam dość. Obrzydło mi programowanie (w Javie i w szkole) przez to.

  15. 15. sztywny

    Rozpoczęcie od C jest dobre - kto dobrze załapie ten język, choć może nie będzie łatwo, z wszystkimi innymi co bardziej popularnymi narzędziami (java, c#, python, ruby, delphi itp.) też sobie poradzi bez jakiś wielkich problemów. Przesiadka w drugą stronę jest dużo trudniejsza.

    Ze to kogoś kto "tłucze w asemblerze" przeciwnie do ciebie, skreśliłbym z miejsca. W czasach procesorów rozpędzonych do gigaherców jest z tego pożytek bardzo rzadko, więc o ile znajomość może być plusem, to już pisanie w tym całych programów to pomyłka IMHO.

  16. 16. Patrys

    A ja pamiętam jeszcze przeklepywanie listingów z Bajtka w roku 1990, zanim poszedłem do podstawówki nauczyłem się liczyć na heksach ;]

  17. 17. Patrys

    A tak odpowiadając na twoje pytanie:

    Uczyć się powinno programowania, a nie implementacji w danym języku i zjego ograniczeniami, więc moim zdaniem zanim posadzi się kogoś przy Pascalu czy innym C (IMHO Pascal jest lepszy na początek, jest bardziej matematyczny i mniej hardcorowy w alokacji pamięci), powinno się dać mu klikalny, klockowy edytor schematów przepływu kontroli. Proste operatory modyfikacji zmiennych, proste bramki (IF/ELSE), proste konstrukcje sterowania (JUMP).

    Jeśli zacznie się od języka, to potem mamy guru od składni, którzy nie potrafią najprostszego algorytmu sami wymyślić i pojawia się problem wyższości JedynegoSłusznegoJęzyka nad ResztąŚwiata.

    Potem jakiś prosty język (Pascal), podstawy (ASM przykładowej archotektury, niekoniecznie realnej, na ii.uni.wroc.pl na ten przykład pisaliśmy kompilatory i assemblery dla języków i architektur zbudowanych na potrzeby wykładu).

    Na koniec języki trzeciej generacji, Pythony, Ruby, C# (mimo mojego uprzedzenia do samego pomysłu .NET) i Javy, bo to raczej jest przyszłość programowania (relatywnie niewielu jest ludzi programujących na poziomie sprzętu, to raczej kierunki dla studentów specjalizujących się w mikrosterownikach i niskopoziomowych systemach czasu rzeczywistego).

  18. 18. sprae

    moja przygoda to:
    --atari--
    1. atari basic
    2. asm6502
    3. Action!
    --c64--
    4. asm6502
    --zx-spec--
    5. basic
    6. asm z80
    --pc--
    7. qbasic
    8. pacal
    9. pascal + wstawki asm
    10. asm x85
    11. c
    --linux--
    12. c
    13. python
    ---studia---
    asm x86 -> c -> c++ -> reszta smieci
    zawsze ewolucja polegala na znalezieniu lepszego kompromisu pomiedzy szybkoscia wykonywania programu, a wygoda programowania. Platformy 8 bitowe opanowywalem prawie rownolegle i raczej nostalgicznie (bo redaktorzy bajtka zaczynali od zx to tez musialem go "liznac").
    Mysle, ze zaczynajac od basica "zalapalem" budowe algorytmow i to na czym polega programowanie. Potem przechodzac na asm chcac zwiekszyc szybkosc aplikacji, przy okazji zrozumialem na czym to wszystko polega. Potem to mi bardzo pomagalo w tlumaczeniu sobie roznych zjawisk zwiazanych z programownaiuem i komputerem. Rownolegle rozwijalem tez znajomosc budowy architektury kompa.
    Osobiscie uwazam, ze powinno sie zaczynac od czegos takiego jak basic, co jeszcze nie jest obiektowe i pozwala na sekwencyjne wykonywanie instrukcji, prawie jak w asmie.
    Potem przechodzac na asma mozna sobie wytlumaczyc ze goto jest jak jmp itp. Potem oczywiscie C (moje ulubione) ktore nadaje sie do pisania core-aplikacji. Nastepnie juz wg wlasnego uznania. Uwazam ze obiektowka tez wymaga jakiegos wprowadzenia do ktorego nadaje sie python... to taki basic majacy na celu zrozumienie obiektow. Wcale nie jest to szybkie, ale za to wygodne i latwe w nauce.

  19. 19. timi

    Ja zaczynałem od Pascala i asemblera, po drodze przewineło się C, VC++, Java, php... aż w końcu zadomowiłem się w Delphi :) Wydaje mi się, że można pomyśleć o innym podejściu: powinno się zaczynać od łatwych do przyswojenia (aby się nie zniechęcić) jezyków jak Pascla lub C których efektem działania jest aplikacja w konsoli. Natomiast w żadnym wypadku nie należy zaczynać od języków wizualnych, gdyż potem można mieć odrobinę niewłaściwe podejście... takie myszkowato-wzrokowe zamiast klawiaturowo-umysłowe :)
    Natomiast również nie zgadzam się z podziałem na humanistów i matematyków. Jeśli już to na techników (asm) i resztę :) ale to także z przymróżeniem oka :)

  20. 20. Arghil

    Ja zaczynałem od ZX Basica, assemblera Z80 (nie ma to jak pisać hexem asseblerowe kody;)), później różne BASIC-ki (C64,Atari,Acorn BBC, i inne), fortran, forth, pascal, C, C++ i sporo innych. ;)
    Ze swojego skromnego doświadczenia myślę, że głównie powinno się nacisk kłaść na rozwiązywania algorytmów i takiego sposobu myślenia, by nie robić bałaganu w kodach. Opanowanie jednego czy drugiego języka programowania to już kwestia praktyki. (na tyle szybko się moda/trendy zmieniają, że po paru latach nie wiadomo co będzie dobre).
    Jak się wie co się ma zrobić to się prędzej czy później to zrobi za pomocą wybranego języka.

  21. 21. Arghil

    PS.
    Czy może trafiłeś na książkę pana Jan B. (Bielecki). ;)

  22. 22. mmazur

    Nie, Adam Majczak bodajże.

  23. 23. Hawk

    Swojej historii jezykow programowania nie bede powtarzal. Kiedys pisalem o tym :) Co do tematu to popieram wypowiedzi, ze powinno sie uczyc zasad programowania i projektowania algorytmow, a nie implementacji w danym jezyku. Mi na studiach wpajano, ze dla dobrego programisty jezyk uzywany do kodowania nie ma znaczenia. I popieram to w calej rozciaglosci, bo choc programista ze mnie zaden, to przestawianie sie na dowolny jezyk nie stanowi dla mnie zadnego problemu. Wystarczy ze mam sciage z lista polecen i ich skladnia. W koncu algorytmy sa te same, nie wazne w czym sa zapisane :) Ale nie o tym mialem... Czy zdarzylo sie wam kiedys myslec algorytmami? Np "widziec" rozwiazanie w czasie gdy ktos jeszcze przedstawia wam problem do rozwiazania? Dziwne uczucie :)

  24. 24. Nazon

    Hawk: Dziwne uczucie to jest wtedy, gdy po "maratonie" spędzonym nad jakimś projektem związanym z programowaniem obiektowym idziesz ulicą i widziane otoczenie rozbijasz na obiekty, metody itd ;) Matrix :)
    A mówili praca przy kompie nie szkodzi ;>

  25. 25. D-

    Hawk: To nie do końca tak. Rozwiązanie zalezy od języka. A zwłaszcza od tego, który paradygmat wspiera. Nie tak prosto przetworzyć ten sam algorytm na wersje obiektowa i funkcyjną i zazwyczaj jedna z nich będzie dla danego zastosowania optymalniejsza. I dlatego z punktu widzenia jakości programisty moim skromnym należałoby uczyć możliwie szerokiego spojrzenia (czyli przynajmniej jednego języka dla każdego z paradygmatów).

  26. 26. Hawk

    D-: o algorytmach uczono mnie +/- 8 lat temu, napewno duzo rzeczy zdazylem zapmniec. Ale powiedz sam, jezeli mamy problem: "wykonywac polecenie X do czasu gdy zmienna Y bedzie ujemna", to czy rozwiazanie wypadaloby widziec jako while(Y>=0) { X(); } czy jako" wykonywanie X w petli z warunkiem zakonczenia Y<0"?

  27. 27. D-

    To zalezy. To nawet może być źle postawiony problem.
    Bo może polecenie brzmiało: ze zbioru Y zrób zbiór X tak, że elementy X powstaną z elementów Y w wyniku operacji z, a jawna petla wcale nie musi byc jedynym rozwiązaniem? ;)

  28. 28. Jajcus

    Hawk: ty już pytanie zadałeś zakładając imperatywne rozwiązanie. W programowaniu funkcyjnym nie ma pętli. O to właśnie chodzi, że problem "wykonywac polecenie X do czasu gdy zmienna Y bedzie ujemna" można rozwiązać bez robienia pętli (chociaż właściwie w programowaniu funkcyjnym takie zadanie nie ma sensu, bo nie ma zmiennych -- opisałeś już algorytm, a nie problem do rozwiązania). W większości języków funkcyjnych można też to w postaci pętli zapisać, i tak pewnie zrobi to ktoś kto programowania funkcyjnego nie zna, a w języku funkcyjnym ma to zapisać, ale nie będzie to rozwiązanie eleganckie i niekoniecznie najwydajniesze (to zależy od optymalizatora).

  29. 29. Hawk

    OK, OK, jak juz pisalem programista ze mnie zaden. Odpuscilem sobie programowanie na pewnym etapie bo stwierdzilem, ze to jednak nie dla mnie. Ta szczatkowa wiedza, ktora posiadam w tej dziedzinie w zupelnosci mi wystarcza. O co mi chodzilo, to o fakt, ze pewne zasady tworzenia algorytmow sa takie same, niezaleznie w czym algorytm ow zostanie potem zaimplementowany. Np taki bzdet ktorego ucza chyba wszedzie, sortowanie babelkowe. Jest to pewne rozwiazanie, perwnego problemu. Czy ono zalezy od jakiegokolwiek jezyka programowania? Nie wydaje mi sie.

  30. 30. Sikor

    Hmm, najważniejszy jest sposób myślenia. Na początek: algorytmy (N. Wirth...?). Potem - proste programy w prostym języku (bez znaczenia: basic, logo, pascal...) - które uczą czytać owe "algorytmy" ;) A potem - w zależności od potrzeb.
    Hmm, dla początkujących - warto popisać na 8-mio bitowe komputery (osobiście używałem iu używam Atari) - uczą dobrego myślenia przy konstrukcji programów (mała ilość pamięci RAM), więc raczej nie p[ozwalają na marnotrastwo i dzięki tak wyrobionemu sposobowi myślenia - później tworzy się bardziej optymalne oprogramowanie ;)

  31. 31. Antek

    Najpierw spodnie, potem buty: przede wszystkim dobry nauczyciel. Potem od ogółu do szczegółu i jak najdłużej wara od implementacji!

    Jestem grafikiem, ale nie "komputerowym", tylko prawdziwym, a więc tzw. humanistą. Programowania uczyłem się sam, ze względu na zainteresowanie multimediami: nie chciałem żeby ktoś mi szklił, że czegoś w moim projekcie nie da się zrobić. Ponieważ straciłbym pół życia na uczenie się języków, uznałem że powinienem poznać podstawowe ich elementy, zasady działania, algorytmy, trochę podstawowych problemów dla hobbystów... Dzięki temu rozumiem przykłady napisane w językach których nie znam, potrafię ocenić jakość kodu, i mam pamięć wolną od śmieci. A przy tym wszystkim - nie jestem programistą!!!


Adde commentarium: (textile lite)