Odpowiadając na pytanie “Jak się uczyć programowania?”, proponuję dwie drogi . Pierwszą z nich jest podejście nazwane “top-down” – bierzemy jakiś tutorial, przechodzimy go krok po kroku i w ten sposób bardzo szybko realizujemy konkretny projekt. Druga opcja to podejście “bottom-up”, w którym każdy krok w świecie programowania stawiamy bardzo dokładnie, kompleksowo ucząc się teorii i mozolnie dokładając kolejne klocki w naszej edukacji. Jak nietrudno się domyślić i jak to zazwyczaj w życiu bywa, oba podejścia mają swoje dobre i złe strony, i wcale nie jest tak łatwo zdecydować się na któreś z nich. A może da się oba te podejścia połączyć?
Moje początki z programowaniem
Wracam czasem myślami do czasów, kiedy napisałem swój pierwszy program w życiu. Miałem wtedy czternaście lat i właśnie rozpocząłem naukę w gimnazjum. Lubiłem komputery i ogarniałem je całkiem nieźle, miałem też już za sobą pierwsze stworzone strony w HTML, ale daleko mi było do takiego typowego komputerowego geeka. W wolnym czasie zamiast siedzieć przed monitorem zdecydowanie bardziej wolałem grać w siatkówkę, koszykówkę i piłkę nożną, a o tym jak się uczyć programowania, nie myślałem. Przejrzałem co prawda kilka odcinków kursu programowania w Pascalu, który prowadzony był w prenumerowanym przeze mnie kultowym magazynie CD-ACTION, ale przedstawiane w kursie problemy – takie jak liczenie silni czy kolejnych wyrazów ciągu Fibonacciego – niespecjalnie mnie ekscytowały. I pewnie długo nie napisałbym swojego pierwszego programu, gdyby nie fakt, że na niektórych przedmiotach wprowadzona została tak zwana średnia ważona. Wiecie o co chodzi, oceny z klasówek mnożone były razy trzy, te z kartkówek razy dwa, a pozostałe oceny zostawiane były z pojedynczym mnożnikiem. A to oznaczało strasznie dużo pracy przy liczeniu oceny z danego przedmiotu. Trzeba było dodawać, mnożyć, potem znowu dodawać, dzielić, komu by się to wszystko chciało robić? I wtedy właśnie pomyślałem “a może by tak napisać program, który to wszystko zrobi za mnie?”. Wtedy nie wiedziałem jeszcze, że istnieje powiedzenie, że “dobry programista to leniwy programista”. Wiedziałem jedynie, że jestem piątkowym uczniem, który nie lubi się przepracowywać i to podejście sprawiło, że postanowiłem ułatwić sobie życie i zautomatyzować tę przeraźliwie nudną czynność liczenia średniej. Wziąłem do ręki kilka odcinków kursów, ściągnąłem kompilator Turbo Pascala i napisałem swój pierwszy kod! Działał. I liczył średnią. Nie był to oczywiście nadzwyczaj skomplikowany program, ale dla mnie było to coś naprawdę wyjątkowego. Wtedy po raz pierwszy poczułem tę satysfakcję i radość pojawiające się, gdy rozwiążemy jakiś problem, gdy uda nam się stworzyć coś z niczego. Wydawać by się mogło, że to jest ten moment, kiedy pójdę za ciosem, kiedy bez reszty wciągnę się w programowanie i będę pisał jeden program za drugim, ale tak się wcale nie stało. Do programowania – tym razem w PHP i MySQL – wróciłem dopiero po trzech, czterech lat, gdy magazyn muzyczny, z którym współpracowałem uzyskał nową szatę graficzną, a ja podjąłem się stworzenia CMS-a pozwalającego na zarządzanie treściami dodawanymi do serwisu.
Szybkie efekty czy mozolna praca?
Dlaczego w międzyczasie nie czułem potrzeby dalszego rozwoju w dziedzinie programowania? Dlaczego przez ten czas nie napisałem ani jednej linii kodu? Odpowiedź jest prosta – brakowało mi problemów do rozwiązania, a co się z tym wiąże także satysfakcji płynącej z ich rozwiązania, satysfakcji napędzającej do dalszej pracy i dalszej nauki. A powiedzmy sobie szczerze – jakie problemy wymagające pisania kodu może mieć czternasto- czy piętnastolatek?
I właśnie ta satysfakcja i radość, o których po raz kolejny wspominam, to moim zdaniem klucz do sukcesu, główny powód, dla którego człowiek chce się uczyć programowania i zgłębiać kolejne zagadnienia. Z tego powodu jestem ogromnym zwolennikiem rozpoczynania nauki programowania od rzeczy efektownych, takich, w których efekty naszej pracy widoczne są bardzo szybko. Jeżeli pokazując komuś programowanie, wybierzemy mozolną drogę od absolutnych podstaw, tłumacząc najpierw czym jest system dziesiętny i system binarny, potem przechodząc do różnic pomiędzy stosem a kolejką, a następnie opowiadając o charakterystykach typów danych w wybranym języku, istnieje bardzo duże ryzyko, że nasz uczeń / słuchacz / widz, bardzo szybko się zniechęci i uzna, że programowanie jest:
a) bardzo trudne
b) bardzo nudne
A przecież ani punkt a ani (zwłaszcza!) punkt b nie są prawdziwe.
Wybierając drugą ścieżkę – szybko pokazując fajne efekty, które można uzyskać pisząc kod – mamy dużą większą szansę na zaszczepienie w drugiej osobie prawdziwego bakcyla do programowania. Oczywiście nie jest to warunek konieczny do zostania programistą – możliwe, że są osoby, które uczą się programowania tylko dlatego, że słyszały o wysokich zarobkach w branży IT i jest to ich jedyna motywacja – ale jednak dużo łatwiej o satysfakcjonujące efekty, gdy nauce towarzyszy autentyczna radość. I teraz bardzo ważne, żebyśmy nie zrozumieli się źle – wszystko to, o czym wspominam w tym akapicie jest niezmiernie ważne. Każdy programista powinien potrafić bez najmniejszego problemu przeliczyć liczby pomiędzy systemem dziesiętnym a binarnym, ani przez chwilę nie powinien mieć wątpliwości czym jest stos a czym kolejka, a zapytany o to, kiedy używamy zmiennej typu long, a kiedy wystarczy int, poprawnej odpowiedzi powinien udzielić bez najmniejszego zająknięcia.
Nie oglądaj się za siebie? Wprost przeciwnie!
Dlatego uważam, że oba podejścia – top-down i bottom-up – należy nieustannie, przez cały czas, gdy uczymy się programowania, ze sobą łączyć. Jak to może wyglądać w praktyce? Powiedzmy, że mamy do zaimplementowania jakąś nową funkcjonalność albo chcemy nauczyć się nowego frameworku. Nie ma nic złego, jeżeli otworzymy odpowiedni tutorial, wykonamy po kolei opisane w nim kroki i osiągniemy oczekiwany przez nas rezultat, nie rozumiejąc wszystkiego, co robiliśmy po drodze. Bo to jest właśnie ten moment, kiedy trzeba te zaległości nadrobić – zrobić kilka kroków w tył, zatrzymać się przy pewnych zagadnieniach, doczytać niektóre tematy w dokumentacji.
Nauka programowania nie jest drogą jednokierunkową, w której nigdy nie oglądamy się za siebie. Czasem pewne rzeczy dobrze jest zrobić szybciej, bez niepotrzebnego zatrzymywania się w jakimś miejscu, po to, by szybciej osiągnąć końcowy cel i po to, by szybciej pojawiła się związana z tym satysfakcja. Ale to nie zwalnia nas z obowiązku robienia tych rzeczy dobrze. Jeżeli na którymś etapie odrobinę się pospieszyliśmy, na moment przycisnęliśmy mocniej gaz, w miejscu gdzie było ograniczenie prędkości, teraz poświęćmy trochę czasu na naukę podstaw. Jeżeli to zaniedbamy, w przyszłości zapłacimy za to bardzo wysoką cenę.
Jak się uczyć programowania? Iteracyjnie!
O nauce programowania lubię myśleć podobnie jak o tworzeniu oprogramowania. W dzisiejszych czasach w dziedzinie zarządzania projektami prym wiodą metodyki agile’owe czyli metodyki zwinne, w których oprogramowanie wytwarza się w sposób iteracyjny, przyrostowy. Dla osób, które nie pracowały jeszcze w branży IT szybkie wytłumaczenie – chodzi o to, by z każdą kolejną iteracją dostarczać klientowi pełnoprawny, funkcjonalny produkt i nie dopuścić do sytuacji, kiedy klient mógłby usłyszeć z naszych ust słowa “pracowaliśmy nad tym miesiąc, ale tak naprawdę wszystko rozgrzebaliśmy i póki co nic nie działa”. Zamiast rozpoczynać więc pracę nad kilkoma funkcjonalnościami naraz czy próbując wprowadzać bardzo duże zmiany od razu, staramy się wszystko dzielić na mniejsze fragmenty i z każdą kolejną iteracją dokładać małe cegiełki do całości. Czasem jedną funkcjonalność dzieli się na kilka mniejszych, które możliwe są do zaimplementowania jedna po drugiej, tak by w każdym momencie mieć działający i gotowy do zaprezentowania klientowi produkt.
Uważam, że podobne podejście doskonale sprawdza się podczas nauki programowania. Nie chodzi o to, żeby wziąć temat A i przerobić go od deski do deski i dopiero potem zabrać się za temat B. W kolejce przecież czekają już tematy C i D, rekrutująca nas osoba chętnie poznałaby naszą opinię na temat tematu E, a w wymaganiach wyraźnie napisane było, że znajomość tematów F i G też jest mile widziana. To co ja proponuję to poznać trochę tematu A, potem przejść do tematu B, wybrać to co jest nam na ten moment potrzebne, a potem zobaczyć czym jest temat C. Gdy poznamy podstawy każdego z interesujących nas tematów i użyjemy tej wiedzy w praktyce – na przykład tworząc prosty projekt – będzie to idealny moment, by wrócić do tematu A i tym razem zgłębić go nieco dokładniej. A potem, w kolejnej iteracji pochylić się nad nim jeszcze mocniej, jednocześnie dokładając kolejne tematy. W ten sposób w naturalny sposób będziemy zdobywać przekrojową i bardzo konkretną, przydatną w praktyce wiedzę.
Praktyka, praktyka i jeszcze raz praktyka
Tym sposobem dochodzimy do podsumowania tego artykułu. Przed chwilą pojawiło się bardzo istotne słowo. Słowo – klucz. Praktyka. I to właśnie praktyka jest najważniejszym konceptem w całej sztuce nauki programowania, bez której każda odpowiedź na pytanie “jak się uczyć programowania?” jest niepełna. Bez praktyki, bez pisania kodu, bez faktycznego rozwiązywania problemów, pojawiających się podczas pracy z kodem, nie zostaniesz programistą. Możesz przeczytać dziesiątki książek i obejrzeć setki godzin tutoriali, ale bez pisania kodu, bez tworzenia własnych projektów, będzie to czas stracony. Dlatego twórz dużo, koduj dużo, realizuj projekty (top-down), nie zapominając jednocześnie o tym, by na żadnym etapie nie zaniedbywać podstaw (bottom-up). A potem zapętl ten cykl i pracuj ciężko, cierpliwie i wytrwale. Radość i satysfakcja są tego warte.