kim jest dobry programista

Dobry programista, czyli jaki? 7 rad eksperta

Czytasz ten tekst, więc prawdopodobnie jesteś początkującym programistą lub chcesz zacząć swoją przygodę z IT. Dam Tobie kilka wskazówek, które moim zdaniem, pomogą Ci zostać dobrym programistą. Patrzę na to zagadnienie z perspektywy programisty (mam nadzieję, że niezłego) oraz osoby, która często bierze udział w procesie rekrutacji młodych talentów.

Kim jest dobry programista? To osoba, która łączy w sobie wiele umiejętności technicznych i nietechnicznych. Jedne nabywa się dość łatwo, inne trudniej, kolejne przychodzą z doświadczeniem. Warto jednak być otwartym na każde z doświadczeń, wyzwań, czy to związanych bezpośrednio z technologią, czy z kompetencjami miękkimi.

rady dla juniora

Seweryn Sobieszek. Web and Mobile Apps Tech Lead, Vice President w Citi Private Bank. Software Engineer z kilkunastoletnim stażem, pracował m.in. przy aplikacjach internetowych i mobilnych, integracji, rozwiązaniach telekomunikacyjnych, trochę AI. Występuje w różnych rolach: programista, architekt, manager i wciąż największą satysfakcję sprawia mu napisanie eleganckiego kawałka kodu. IT lubi najbardziej za ciągłe poznawanie nowych rzeczy. Gdy nie poznaje nic nowego, to biega lub pływa.


1. Jaki język programowania wybrać?

Z perspektywy programisty ważną rzeczą jest wybór języka programowania. Zastanów się, jakie zastosowania chciałbyś programować, ponieważ to zawęża wybór języka do tych stosowanych w danej domenie.

Jeśli interesujesz się tematami embedded (programowanie blisko sprzętu), warto spojrzeć na Rust, C/C++ itp., może też assembler danego procesora. W webie (frontendzie) mocno rozpycha się Typescript, ale najbardziej popularny jest wciąż jego starszy brat Javascript (nie tylko w przeglądarce, ale coraz częściej także na serwerze). Javascript to w ogóle najbardziej popularny język programowania! Pomiędzy embedded i frontendem (oraz na boki) jest bardzo duża przestrzeń języków do wyboru, np.:

  • backend, tj. wszelkiego rodzaju przetwarzanie na serwerze, w tym udostępnianie usług (integracyjnych lub dla webu) – głównie Java, C#, PHP, Python,
  • aplikacje mobilne – Android to w zasadzie tylko Kotlin i Java, iOS z kolei to Swift i Objective C,
  • data science – głównie Python i R,
  • desktop, czyli tradycyjne programy narzędziowe – tutaj też w zależności od platformy na którą programujesz,
  • i wiele innych…

Każdy programista ma też swoje preferencje dotyczące języków programowania i ja również je mam. Jednak niezależnie od preferencji, do ważniejszych zadań sugeruję stosować języki kompilowane i silnie typowane, do szybkich akcji wystarczy najprostszy język skryptowy, chociażby bash. Chodzi o dwie kluczowe sprawy, które daje nam dobry kompilator:

  1. Wykrycie błędów na wczesnym etapie, a nie podczas testowania lub uruchamiania kodu.
  2. Wykonanie jak najwięcej pracy związanej ze sprawdzeniem poprawności kodu przez komputer (kompilator), a nie pilnowanie ich samemu.

Nie bez znaczenia jest też popularność języka programowania – dla popularniejszego łatwiej będzie znaleźć wartościowe materiały i jest więcej osób dostępnych, którym możesz zadać pytanie (czy to w firmie, w kręgu znajomych lub w internecie). Coroczna ankieta przeprowadzana przez JetBrains fajnie prezentuje informacje na temat aktualnego stanu i trendów w programowaniu. Polecam zwłaszcza statystyki „What are your primary programming languages?”, „What types of software do you develop? (By primary languages)”.

Nie przejmuj się jednak za bardzo, jeśli wybrany przez Ciebie język nie jest popularny. Moim językiem pierwszego wyboru jest obecnie Scala i to w niej najwięcej programuję. W ankiecie JetBrains jako język podstawowy (można wskazać do 3 języków) wskazało ją zaledwie 2% respondentów, a 5% w ogóle używało jej przez ostatnie 12 miesięcy – nie wygląda na popularną, ale wierz mi, nie mam z tym żadnego problemu.

2. Zadbaj o środowisko programistyczne

Naukę wybranego dla siebie języka programowania najłatwiej zacząć z artykułów typu „Getting started” i tutoriali, które są dostępne na oficjalnych witrynach danego języka. Inne popularne sposoby to kursy on-line, książki itd. – każdy znajdzie coś dla siebie w zależności od tego, w jaki sposób lubi się uczyć. Jednak język programowania to nie wszystko.

Jako programista większość czasu będziesz spędzać na pisaniu, uruchamianiu i testowaniu kodu. Dobrze jest wybrać narzędzia (lub IDE), które Cię w tym wspomogą. Warto wypróbować kilka alternatyw dostępnych dla danego języka/platformy i podjąć decyzję w zależności od preferencji. Gdy już podejmiesz taką decyzję koniecznie poświęć czas, żeby poznać jak najwięcej możliwości swojego środowiska i przydatnych skrótów. Po co?

Po to, żeby swój czas wykorzystywać głównie na programowanie, a nie „walkę” ze środowiskiem. Na przykład gdy opanujesz debugger nie będzie trzeba już wypisywać na ekran wartości zmiennych, żeby zobaczyć co się z nimi dzieje. Gdy nauczysz się skrótów klawiaturowych dla najczęściej wykorzystywanych przez siebie operacji, zaoszczędzisz dużo czasu nie odrywając ręki od klawiatury.

Następne w kolejce jest wersjonowanie kodu. Przydatne nawet jeśli pracujesz nad kodem w pojedynkę. Dzisiaj standardem de facto jest git i to jego koncepcji i obsługi powinieneś się nauczyć. Niektóre edytory/IDE mają wbudowane wsparcie dla git-a i pewnie tego będziesz używać w 80-90% przypadków. Jednak trzeba też w pewnym stopniu znać interfejs command-line, ponieważ nie wszystkie możliwości git dostępne będą w IDE i czasem niektóre operacje będzie trzeba wykonać z konsoli.

Potem mamy inne narzędzia, które są przydatne praktycznie codziennie:

  • Issue tracker – będziesz ich używać, gdy będziesz pracować w większym projekcie. Github, Jira, Gitlab, Youtrack… jest ich trochę i na pewno będą się zmieniać między projektami. Nie musisz poznawać ich wszystkich, ale gdy zaczynasz korzystać z jakiegoś to zapoznaj się z nim dobrze, zwłaszcza z operacjami na ticketach: wyszukiwanie, zapisywanie filtrów, przekazywanie, zmiana stanów.
  • Język skryptowy powłoki – bash, Power Shell lub coś innego – zależnie od platformy deweloperskiej i uruchomieniowej. Ja polecam bash, bo jest uniwersalny (natywnie na Linuksie i M acu, w Windows przez Cygwina lub WSL2). Warto zainwestować tu swój czas, zawsze będzie trzeba coś zautomatyzować.
  • Narzędzie CI/CD – Jenkins, Github, Gitlab… te też są bardzo zależne od projektu. Warto osiągnąć pewien poziom przyzwoitości, gdy zaczniesz takiego używać, natomiast nie zawsze będziesz sam go musiał konfigurować. Z reguły w każdym zespole jest ktoś w roli devops, kto ogarnia takie rzeczy.

3. Algorytmy to twoja przewaga

Algorytmika i podstawy teoretyczne moim zdaniem wyróżniają dobrego programistę na tle innych. Tak, można programować nie znając podstawowych pojęć z algorytmiki i najważniejszych algorytmów oraz struktur danych, ale prędzej czy później kończy się to wpadką podobną do tej, którą zaliczył Rockstar z GTA Online.

Czy GTA Online działało? Działało. Czy mogło startować szybciej? Mogło, ponad 3 razy szybciej, gdyby tylko programista, który to kodował, użył odpowiednich struktur danych. A wierzcie mi, „3 razy wolniej” to nie jest najgorsza rzecz, która może się wydarzyć.

Programista zdecydowanie powinien znać notację „duże O”, złożoności podstawowych algorytmów i struktury danych, które pozwalają efektywnie przechowywać/znajdować dane. Powinien też używać tych wszystkich rzeczy korzystając z biblioteki standardowej języka lub rozszerzeń. W dzisiejszych czasach dla większości języków nie trzeba samemu implementować standardowych algorytmów lub struktur danych.

Cała ta wiedza potrzebna jest po to, by potem umieć oszacować złożoność napisanego przez siebie algorytmu/programu i krytycznie ocenić czy nie jest za duża. Jeśli tego jeszcze nie umiesz, to zdecydowanie warto zainwestować czas i się nauczyć, żeby lepiej programować. Dla chętnych algorytmy zaawansowane i rozproszone.

4. Ucz się na błędach, aby nie popełnić ich kolejny raz

Każdy czasem popełnia błędy. Każdy, nawet najlepszy programista – bo „nie myli się tylko ten, kto nic nie robi”. Szkopuł w tym, żeby błędów raz popełnionych nie powtarzać w przyszłości.

Co zrobi programista, który odkryje błąd w swoim kodzie lub dostanie zgłoszenie błędu? Zlokalizuje przyczynę i poprawi. Co zrobi dobry programista? To samo… ale oprócz tego napisze wcześniej test automatyczny, który będzie wywoływał i testował wadliwe działanie kodu. Przed poprawką błędu ten test będzie się wykonywał z błędem, po poprawce będzie wykonywał się poprawnie. Jak to się ma do tematu punktu? Taki test zostanie z kodem „na zawsze” i będzie pilnował, żeby ten konkretny błąd już nigdy się nie pojawił. Z czasem (i kolejnymi błędami) takich testów będzie naprawdę dużo i będą one pełniły rolę dobrych, bezlitosnych strażników kodu.

Automatyzuj wszystko, co się da – pozwoli Ci to uniknąć błędów, których jeszcze nawet nie popełniłeś. Zbudowanie wersji instalacyjnej lub deployment nawet niedużego programu będzie procesem wielokrokowym. Każdy krok musi być wykonany poprawnie i w odpowiedniej kolejności. Idealne miejsce na popełnienie mnóstwa błędów, ale też idealne miejsce na automatyzację. Ile razy już słyszałem, że „mój proces budowania/deploymentu jest tak skomplikowany, że nie da się go zautomatyzować”. Jeśli rzeczywiście jest skomplikowany, to tym bardziej trzeba go zautomatyzować, bo tylko automat się w nim nie pomyli!

Inny przykład błędów, których można uniknąć, to potencjalne błędy. Dobry programista nie ignoruje ostrzeżeń kompilatora, bo każde z nich jest potencjalnym błędem, który może objawić się w najmniej oczekiwanym momencie.

5. Dąż do doskonałości w tym, co robisz

Dobry programista, dobry inżynier, dobry „ktokolwiek” dąży do bycia coraz lepszym w tym, co robi. Co robić, żeby być coraz lepszym programistą? Nie trzeba od razu celować w bezbłędne kodowanie programu współbieżnego, można zacząć od prostszych rzeczy. Na początek zachęcam do nauki pisania bezwzrokowego. Trywialne i mało istotne? Pomyśl, ile czasu Ci zaoszczędzi ta umiejętność. Czasu, który możesz wykorzystać na myślenie, kodowanie, testowanie… na cokolwiek!

Jak prawie we wszystkim, kluczem do sukcesu w pisaniu bezwzrokowym jest regularność. Dobra wiadomość jest taka, że wystarczy 15 minut dziennie. Codzienne ćwiczenia 15 minut przez 2-3 tygodnie wystarczą, żebyś zauważył efekty. To się opłaci, bo jest to umiejętność, która zostanie z Tobą na zawsze.

Koncentrując się na doskonaleniu warsztatu stricte programistycznego powiedziałbym, że najważniejszą cechą popychającą do przodu są dyskusje z innymi programistami. Wymiana poglądów, argumentacja swoich racji, szukanie „dziury” w argumentacji kolegów są świetnym motorem do myślenia o kawałku kodu, na temat którego toczy się rozmowa oraz na temat własnego kodu w ogóle.

Od czasu początków pandemii COVID-19 zniknęły rozmowy w kilkuosobowym gronie „w kuchni przy kawie”. Dlatego teraz jak najmocniej należy wykorzystywać do tego code review – skrupulatne przeglądanie kodu kolegów, komentarze i późniejsza dyskusja pozwalają na naukę w obie strony. Często można dostać wartościowe komentarze, jak również nauczyć się czegoś nowego jako przeglądający. Code review to świetne narzędzie do rozwoju całego zespołu.

Jako programista ciągle odkrywasz coś nowego (a przynajmniej powinieneś), uczysz się nowych możliwości języka, nowych bibliotek i API. To wszystko sprawia, że gdy wracasz do swojego kodu, który ma tylko kilka miesięcy, okazuje się, że dziś prawdopodobnie napisałbyś to inaczej (lepiej). I bardzo dobrze! To oznacza, że przez kilka miesięcy nauczyłeś się czegoś nowego (lepszego).

Jeśli czujesz, że Twój kod należałoby zmienić (zrefaktoryzować), to powinieneś to zrobić! Należy to jednak zrobić odpowiedzialnie, tak żeby nie wprowadzić błędów. Z drugiej strony nie możesz rezygnować z refaktoryzacji tylko z powodu ryzyka wprowadzenia błędów. A to dlatego, że tego ryzyka można uniknąć (lub je zminimalizować) dzięki pokryciu testami zmienianego kodu. Mogą to być testy jednostkowe, testy integracyjne, testy regresji – dowolna kombinacja, która pozwala Ci przetestować automatycznie poprawność kodu, który należy zmienić.

Jeśli już posiadasz wystarczające testy do tego kodu, to super, zabieraj się za refaktoryzację i pilnuj poprawnego wykonania testów. Jeśli testów jest za mało, to stwórz/uzupełnij je przed zmianą. Dzięki temu osiągniesz znacznie więcej niż „tylko” poprawisz swój stary kod, bo dodasz też testy, które będą strzegły poprawności każdego kodu (starego, nowego i jeszcze nowszego, który napiszesz w przyszłości).

6. Ciągle się rozwijaj

Czytając ten tekst możesz odnieść wrażenie, że najważniejsze w pracy programisty to ciągły rozwój. I tak jest w istocie! Świat technologii gna naprzód i to coraz szybciej. Technologie, które kilkadziesiąt lat temu były na topie w większości zostały zapomniane. Technologie, które są na topie dzisiaj zostaną zapomniane znacznie szybciej. Dlatego ten ciągły rozwój jest tak ważny. Kto stoi w miejscu, ten de facto się cofa, bo świat naokoło idzie do przodu, coraz szybciej i szybciej. Brzmi jak slogan, ale tak naprawdę jest.

Z jednej strony praca programisty jest idealna dla kogoś, kto lubi się uczyć i ciągle poznawać coś nowego. Z drugiej strony, jeśli tego nie lubisz, to może lepiej znaleźć inne zajęcie, bo bez nauki i rozwoju prędzej czy później Twoja wiedza stanie się przestarzała i niewiele warta (chyba że programujesz w COBOL-u – tutaj podobno cały czas jest popyt).

Nadążanie za technologiami i narzędziami jest ważne, bo one zmieniają się najczęściej, ale jako programista nie zapominałbym o czymś innym. Czymś, co na szczęście zmienia się rzadziej – paradygmaty i inne języki programowania. Technologie oraz narzędzia i tak poznasz, jak będziesz chciał ich użyć do konkretnego zadania. Z innymi językami i paradygmatami programowania jest trochę inaczej – bez ich poznawania przez długi czas można się obejść, jednak moim zdaniem wiele się przez to traci.

W zasadzie każdy obecnie używany język programowania jest językiem obiektowym (może oprócz czystego C), więc ten aspekt pominę. Zakładam, że posługujesz się językiem obiektowym i rozumiesz to pojęcie (jeśli nie to szybko nadrób). Języki można podzielić ze względu na paradygmaty. Gdy używasz głównie jednego paradygmatu i/lub języka zachęcam do eksperymentowania z innymi, np.:

  • Jeśli zawsze programowałeś imperatywnie (klasyczne języki z pętlami i wyrażeniami warunkowymi), polecam spróbowanie programowania funkcyjnego – obecnie większość popularnych języków mniej lub bardziej wspiera programowanie funkcyjne, które często prowadzi do mniejszej liczby błędów i takie programy mają bardziej zwartą konstrukcję.
  • Polecam też spróbowanie programowania deklaratywnego w Prologu jako czegoś zupełnie innego niż używa się na co dzień. Implementacja solvera sudoku z pomocą biblioteki clpfd naprawdę zachwyca swoją prostotą.

Próbuj nowych rzeczy i je poznawaj, każdy nowy paradygmat i język uczynią z Ciebie lepszego programistę. Nawet jeżeli nie będziesz ich od razu wykorzystywać, to wiesz, że istnieją i czekają na to, żeby zostać użyte. Powiększysz Twój arsenał narzędzi, których możesz użyć do rozwiązywania problemów – na pewno zdążyłeś już zauważyć, że nie ma jednego języka, który jest najlepszy do wszystkiego. Język dobiera się do domeny i konkretnego problemu. Poszerzanie horyzontów pomoże Ci także zrobić lepszy użytek z aktualnie wykorzystywanych języków, bo bardzo prawdopodobne jest, że polepszy się Twój sposób ich wykorzystywania. Niestety zobaczysz też w nich braki, których nie widziałeś wcześniej.

Rozwijając typowo techniczne umiejętności nie można zapominać o umiejętnościach nietechnicznych, które też są potrzebne w pracy programisty. Rozwinę ten temat w kolejnym punkcie, teraz chciałbym jednak poruszyć temat tzw. „rozwoju osobistego”. Warto znaleźć zajęcie, które będzie odskocznią od programowania (i pracy), w trakcie którego będziesz mieć czas na pomyślenie, poukładanie sobie różnych spraw. Albo wręcz odwrotnie (zależy od Twojego charakteru) – na reset głowy, która nie będzie w stanie zająć się niczym innym.

Dla mnie idealnie nadają się do tego różne aktywności ruchowe/sportowe – skoro siedzę przed komputerem przez długie godziny, to ruch i sport traktuję wręcz jako spłatę długu wobec ciała. Przy okazji wyrzut endorfin poprawiając nastrój rzeczywiście daje pozytywnego kopa na resztę dnia. Aktywności o niskim poziomie intensywności (spacer lub lekki jogging, turystyczna przejażdżka na rowerze) świetnie nadają się do przemyśleń, to jest też dobry czas na myślenie o rozwiązaniach dla aktualnych zadań programistycznych. Z kolei aktywności o wysokim poziomie intensywności pozwalają zapomnieć o nawet najbardziej wyczerpującym intelektualnie dniu.

Nie musi to być ruch/sport, ważne, żeby to było zajęcie, które:

  • Daje odpocząć Twojej głowie od tego czym zajmujesz się na co dzień.
  • Daje Ci możliwość rozwoju i satysfakcji z tego rozwoju – na dłuższą metę ciężko żyć samym programowaniem.

Znam ludzi, którzy uczą się tańca, uczą się wybranego języka obcego, robią kursy on-line – szczęśliwszy człowiek, to lepszy programista.

7. Zwracaj uwagę na umiejętności miękkie

My programiści często mamy tendencję do zaniedbywania umiejętności nietechnicznych (miękkich), wręcz uznawania ich za nieistotne. Dopóki piszemy programy tylko dla siebie i pracujemy w pojedynkę, to może nawet działać… tylko że takie sytuacje nie występują w przyrodzie.

Oprogramowanie pisane jest dla użytkowników i bardzo rzadko w pojedynkę. Nawet jeśli będziesz jedynym programistą w zespole, to i tak będziesz pracować z innymi ludźmi. Dlatego umiejętności związane z pracą zespołową są bardzo ważne, np.:

  • Umiejętność komunikacji – dla programisty komunikacja najczęściej oznacza uzyskanie lub uszczegółowienie wymagań od użytkowników lub analityków biznesowych, komunikację z zespołem testowym dotyczącą funkcjonalności do przetestowania lub zgłoszonych błędów, komunikację z innymi programistami lub architektami w celu koordynacji współpracy nad projektem itp. Issue tracker, e-mail i komunikatory to świetne narzędzia, które bardzo usprawniają pracę, ale często jedna krótka rozmowa zaoszczędzi kilkudniowej wymiany korespondencji. Nie bój się zadzwonić i bądź dostępny dla innych – zobaczysz o ile łatwiej będzie Wam współpracować.
  • Pomaganie innym – w zespole chodzi o wspólny cel, dlatego warto pomagać innym, gdy mają problemy. Dzięki temu wszyscy przybliżamy się do tego wspólnego celu. Dziś Ty pomożesz komuś, jutro on pomoże Tobie – brzmi prozaicznie, ale w ten sposób buduje się zaufanie i dobrą atmosferę w zespole.
  • Umiejętność poproszenia o pomoc – gdy masz problem, nie wstydź się poprosić o pomoc. W zespole o zdrowych relacjach nie zostanie to odebrane jako Twoja słabość, tylko troska o wspólny cel (patrz wyżej).

Cechą, która jest ważna niezależnie od tego, czy pracujesz w zespole, czy sam, jest umiejętność realizowania zadań i doprowadzania ich do końca mimo przeszkód. Zdarza się (czasem dość często), że musisz przerwać jakieś zadanie i potem do niego wrócić, często masz otwartych kilka-kilkanaście-kilkadziesiąt zadań – musisz nauczyć się w nich poruszać, nie zapominając o żadnym z nich.

Sugeruję zapoznać się z jedną z metodyk „zarządzania sobą w czasie” (bo podobno czasem nie da się zarządzać, zawsze płynie tak samo, cokolwiek byś nie robił), np. „Getting Things Done” i zaimplementować ją używając dostępnych narzędzi. Jako taką regułę kciuka proponuję każde zadanie typowo projektowe umieszczać w projektowym issue trackerze (powinno być tam od początku), zadania indywidualne (nieprojektowe) w jednym wybranym miejscu (najlepiej ten sam issue tracker co dla zadań projektowych). I to byłoby na tyle…

Oczywiście powyższe rady są subiektywne, inni programiści mogą mieć swoje zdanie. Wierzę jednak, że stosowanie chociaż części z nich zrobi z Ciebie jutro lepszego programistę, niż byłeś wczoraj. Powodzenia!


Zdjęcie główne artykułu pochodzi z unsplash.com.

Zapraszamy do dyskusji

Patronujemy

 
 
More Stories
Urodziny Wikipedii
Wikipedia kończy 20 lat!