28 lutego, 2013

Rekrutacja programistów albo czekanie na Godota

Post ten jest kompilacją różnych przemyśleń po uczestnictwie w kilku rozmowach kwalifikacyjnych, gdzie zostałem zaproszony jako "techniczny" do przepytywania kandydatów i, powiem szczerze, nie jest dobrze, Bob. Nie jest dobrze.

Są różne podejścia do rekrutowania i sprawdzania umiejętności programowania. Osobiście jestem wrogiem prób przyłapania kandydata na tym, że czegoś nie wie; przykładem takiego podejścia jest ten test. Co mi się nie podoba w tych pytaniach? Polegają na spostrzegawczości - jeżeli widziałeś kiedykolwiek podobne konstrukcje, to wiesz dokładnie, na jakie rzeczy zwracać uwagę. Jeżeli spędziło się kiedyś przed komputerem dwie godziny zastanawiając się, dlaczego ten cholerny warunek nie działa, jak powinien, tylko po to, żeby odkryć, że postawiło się pojedynczy znak równości zamiast podwójnego, to na zawsze zostanie to wryte w mózg. Jeżeli się tego nie przeżyło, niełatwo to zauważyć. Sęk w tym, że w większości przypadków kompilator nas ustrzeże przed takim siedzeniem, jeżeli tylko wykażemy dość rozsądku, żeby włączyć ostrzeżenia i je potem przejrzeć. Już nie wspominam o pytaniach o konstrukcje, których nigdy nie zobaczycie w produkcyjnym kodzie. x+++3? Jasne, już widzę, jak przepuszczam to przez recenzję... W każdym razie takie podejście nie sprawdza, moim skromnym zdaniem, umiejętności programowania.

Jest za to inne podejście, które sobie upodobałem, które oczywiście podkradłem komu innemu... podejście to zaleca między innymi Jeff Atwood. Chodzi o to, żeby zadając proste pytania móc zaobserwować kilka rzeczy:

  • Po pierwsze, czy jeżeli da się petentowi problem, to on naprawdę chce go rozwiązać. Nie wiem, czy też to zauważacie, ale programiści bardzo często chcą wiedzieć bezzwłocznie. To są właśnie Ci ludzie, którzy, jeżeli zadać im ciekawe pytanie podczas imprezy, wyciągną telefon z wifi i zaczną szukać odpowiedzi. Jest problem? Potrzebujemy rozwiązania; Teraz. To jest pasja i zawziętość, które ciężko zafałszować.
  • Po drugie, czy osoba podająca się za programistę potrafi rozwiązywać proste problemy mniej-więcej tak szybko, jak jest w stanie pisać. To jest bardzo ważne. Programowanie w dużej mierze przypomina żonglerkę - jeżeli musisz na chwilę przestać i pomyśleć, to jest spora szansa, że upuścisz kilka piłek.
  • Po trzecie, czy kandydat dąży do perfekcji. Może to moje własne zboczenie, ale uważam to za kluczowe dla bycia dobrym programistą. Program nie zachowuje się mniej-więcej tak, jak powinien; albo robi wszystko tak, jak tego oczekujemy, albo nie. Poprawność się nie stopniuje.
Dotychczasowe doświadczenia rekrutacyjne nie napawają mnie optymizmem. Nie jest źle, bo nie natknąłem się jeszcze na kandydata, któremu wysmażenie programu typu FizzBuzz zajęłoby 10-15 minut... ale nie natknąłem się też na takiego, który zrobiłby to bezbłędnie. To bym jeszcze przeżył, błędy się zdarzają, często w prostych rzeczach, ale radzenie sobie z tymi błędami zazwyczaj pozostawia wiele do życzenia. Ale o tym innym razem, teraz i tak się rozpisałem.

02 listopada, 2012

NIDE 1: Problem

Chciałbym poruszyć problem, który mnie dotyczy od pewnego czasu, a mianowicie pracy w środowisku, które nazywam NIDE. Wygląda na to, że wyjdzie z tego cały cykl. Zaczynajmy!
Photo by meantux

IDE są świetne. Uwielbiam środowiska, które pozwalają mi w jednym okienku robić wszystko, od designu po testy integracyjne i deployment (czyli zazwyczaj commit do repozytorium). Problem w tym, że nie zawsze mam możliwość pracy w takim środowisku, czyli w projekcie mamy odgórnie ustalone NIDE - Non-Integraied Development Environment.

Uroki NIDE wynikają zazwyczaj z pracy nad systemami wbudowanymi. W moim obecnym projekcie mamy następujące feature'y:

  1. Brak odgórnie ustalonego edytora kodu i setki tysięcy (miliony?) linii kodu do ogarnięcia
  2. Dość rozbudowany skrypt konfigurujący linię komend, w której możemy kompilować i przeprowadzać statyczną analizę kodu
  3. Niezbyt popularny build toolchain i strukturę projektu opartą o coś na kształ makefile'ów
  4. Testy modułowe odpalamy na emulatorze uruchamiany z Visual Studio
  5. Za samo odpalenie testów odpowiedzialny jest program Rational Test Real-Time
  6. Żeby przetestować kod na działającym systemie musimy go wrzucić na sprzęt docelowy np. przez Visual Studio
  7. Informacje ze sprzętu trafiają do nas przez port COM, więc potrzebujemy jakiegoś programu do zbierania i przeglądania logów z portu szeregowego.
  8. Repozytorium kodu zamknięte szczelnie jak radziecki słoik i obsługiwane przez klienta napisanego w Javie.
Punkty od 2. do 8. są poza jurysdykcją programisty - takie są wymagania, tak musimy pracować. Okej, z tym się jestem w stanie pogodzić, skoro mogę wybrać edytor! Czego bym wymagał od edytora? Bez szczególnej kolejności:
  • Możliwości skakania pomiędzy plikami, w szczególności do definicji funkcji/zmiennych... i oczywiście możliwość automatycznego szukania tych definicji.
  • Program ma być darmowy. To się nie wydaje takie oczywiste, ale przede wszystkim zależy mi na społeczności. Wokół zamkniętych programów rzadko organizuje się grupa zapaleńców, a kiedy napotykam na jakiś problem i próbuję googlać za rozwiązaniem, to słyszę świerszcze.
  • Szybkości. Dużo czasu mi schodzi na obsługę całej reszty NIDE, nie chciał bym dodatkowo walczyć z narzędziem, w którym realizuję sedno mojej pracy.
  • Możliwie dobrej integracji z build toolchainem. Większość osób w projekcie skacze pomiędzy oknami edytora i linii komend: Zmiana w kodzie, [Switch!] kompilacja, sprawdzenie ewentualnych błędów, [Switch! i to kilkukrotnie] lokalizacja w edytorze, poprawki, [Switch!] kompilacja. Przy dwóch monitorach da się z tym żyć, ale... mi szkoda życia.
  • Niezawodności. Nie wyobrażam sobie, żebym stracił choćby pół godziny pracy w wyniku jakiegoś tyci problemiku.
  • Rozszerzalności. Jeżeli edytor nie ma czegoś, czego będę potrzebował, to chcę móc to sobie dorobić; łatwo i przyjemnie.
Uff... sporo się zrobiło tych wymagań. W następnej części pokażę, jak tym wymaganiom sprostał uwielbiany przez niektórych Eclipse. Narzekaniom nie będzie końca. Oczywiście żartuję... ale czy na pewno?

26 października, 2012

Bezwzględne testowanie

O testach modułowych pisałem już wcześniej, tak jak i o DevDay, ale wykład Grega Younga wzbudził u mnie pewien rezonans. Ten sam wykład z innej konferencji można obejrzeć np. tutaj. Polecam wszystkim chętnym.

Greg Young otworzył mi oczy na zupełnie nowe spojrzenie na testowanie programów. Od pewnego czasu miałem wrażenie, że napisanie dobrych testów nie jest łatwe i że jeszcze trudniej zmierzyć jakość testów, ale to były tylko przeczucia, a Greg pokazał, jak można do tego podejść w sposób bardzo ścisły i konsekwentny. Jednak nie to przykuło moją uwagę najbardziej.


Photo by kabils
Najciekawszą częścią wykładu była dla mnie część, w której autor postulował celowe zmiany w kodzie aby sprawdzić, czy testy się wysypią. Bingo! Dodałeś do zmiennej 'x' 1? A jeżeli zmienię zamienię 1 na 5, to co się stanie? Program ewidentnie się zmieni, ale czy te super-testy które napisałeś się wysypią? A jeżeli zamiast dodać odejmę, co wtedy? Kiedy o tym poważnie pomyśleć, to jest jedyny sposób sprawdzenia, czy testy działają. Gdybym miał czujnik przeciwpożarowy, który nie podniesie alarmu, kiedy przytknę do niego zapaloną zapałkę... nie czuł bym się do końca bezpiecznie. Najbardziej Greg zaimponował mi kiedy powiedział, że pracują nad narzędziem, które będzie wprowadzało takie zmiany automatycznie. Wow.

Później przyszła jeszcze jedna refleksja: ja już o tym gdzieś czytałem. Pragmatyczny programista, porada 64: "Użyj sabotażystów żeby testować swoje testy". Po raz kolejny okazuje się, że w informatyce wymyślono już multum dobrych idei, które tylko czekają na swój czas.

Dwa wnioski na dziś:

  1. Koniecznie przeczytać jeszcze raz Pragmatycznego programistę.
  2. Przydałby się post na temat tej książki i innych, które miały na mnie największy wpływ.

19 października, 2012

Wielokulturowość, wielonarzędziowość

Już wcześniej pisałem o powiązaniach pomiędzy językiem a myśleniem i o tym, jak osoby bikulturalne potrafią myśleć inaczej na ten sam temat, w zależności od tego, w jakim języku zadamy pytanie. Te przemyślenia skorelowały mi się z wystąpieniem Martina Mazura na DevDay, o którym pisałem w zeszłym tygodniu. Jeżeli ktoś ma ochotę to można ten wykład obejrzeć tutaj, choć to nagranie z innej konferencji.

Myślę, że to kuszące, jeżeli jedynym narzędziem, jakie posiadamy jest młotek, aby traktować wszystko jak gwóźdź. -- A. Maslow 
Ten cudowny cytat z Maslowa pokazuje cały problem, jaki wynika z ograniczania zestawu narzędzi, których używamy; w życiu, w pracy, w myśleniu. Dodatkowa trudność polega na tym, że kiedy już widzimy dookoła tylko gwoździe, to ciężko się przekonać, że być może istnieją inne problemy i inne narzędzia do ich rozwiązania.

Ja miałem szczęście. Udało mi się znaleźć środowiska, które wymusiły na mnie poszukanie nowych narzędzi. Mówię między innymi o kursach on-line, w których wziąłem udział. Jednak wcześniej była jeszcze potrzeba przygotowania pewnego narzędzia wewnętrznego w moim obecnym projekcie, która wymusiła na mnie poznanie Perla i... to było olśnienie.

Zanim jeszcze zostałem zawodowym programistą (czyt. zaczęli mi za to płacić) poznałem Pascala, C, C++ i C#... pomijając pierwszą pozycję już na pierwszy rzut oka widać tu obrzydliwą spójność gatunkową. Poznanie Perla było dla mnie wejściem w zupełnie nowy wymiar w którym o dziwo poczułem się dobrze. Perl jest tak elastycznym narzędziem, że poczułem się jakbym zakładał na mózg dobrze dopasowaną rękawiczkę.

Photo by Bill Liao
Podczas kursów Coursery poznałem kolejne narzędzia, które może nie były do mnie już tak dobrze dopasowane, ale świetnie nadawały się do rozwiązywania problemów, które stawiali przed nami wykładowcy. Kiedy myślałem o tym, jak rozwiązywałbym te same problemy w językach, które już znałem, już na etapie koncepcji stawała mi przed oczami wizja wbijania śrubek młotkiem. Niepiękna to wizja.

Prawda jest taka, że moja skrzynka z narzędziami stała się ostatnio dużo cięższa i kiedy zabieram się dziś do nowego problemu robię wcześniej sumienny przegląd narzędzi.

Poza językami programowania odkryłem jeszcze inne narzędzia, ale to już temat na osobny post.

12 października, 2012

DevDay 2012, minirelacja

W zeszłym tygodniu byłem z kuzynem na konferencji DevDay 2012 w Krakowie. Jak ktoś nie wierzy, to może mnie poszukać na zdjęciach z konferencji. ;-)

Krótka relacja z kolejnych prezentacji tego dnia:

  • Wykład otwierający w wykonaniu Scotta Hanselmana był dokładnie taki, jak oczekiwałem. Pogadanka o dbaniu o zdrowie psychiczne będąc programistą, dużo humoru, fajne rady i spostrzeżenia. Gdyby odwołano resztę konferencji nadal nie żałowałbym 22 godzin w pociągach.
  • Na drugim wykładzie Mark Rendle pokazywał, w jak niepojęte sposoby można wygiąć C#  dla własnych potrzeb i jak ciekawe efekty można dzięki temu uzyskać. Interesujące i mocno techniczne.
  • Dość dziwny wykład w wykonaniu Sebastiena Lambli. Może po prostu nie interesuje mnie cachowanie HTTP? Za to ciekawa uwaga ze strony prowadzącego - w jego opinii nikt na sali nie zajmował się "współczesną web-developerką" i wezwanie do obudzenia się: Guys, there's a world out there! Mocne.
  • Występ Roba Ashtona z mocno komediowymi akcentami poświęcony javascript'owi. Ashton pokazał jak sobie radzić z niedogodnościami pisania w języku, którego się nie lubi i który rzekomo nie ma odpowiednich narzędzi. Fajny wykład i plus za Vim'a,
  • Polsko-norweski kodujący wiking czyli Martin Mazur opowiadający o tym, co można wynieść z relacji międzykulturowych i obalenia podziału na "naszych" i "innych". Dobry balans pomiędzy techniczną i miękką stroną prezentacji. Sporo jego uwag pokrywa się z tym w co gorąco sam wierzę.
  • Trochę irytująca samochwałka w wykonaniu Antka Piechnika. Każdy ma prawo chwalić swoją firmę, ale wyszło ciut zbyt nachalnie, szczególnie że wiele pomysłów mało oryginalnych. Jeden ciekawy pomysł na narzędzie typu fire-and-forget konfigurujące środowisko developerskie. Przy dużych projektach to może zaoszczędzić ogrom czasu podczas onboardingu.
  • Trochę niespodziewany bardzo dobry wykład na zamknięcie konferencji w wykonaniu Grega Youga. Świetne przykłady data-miningu na systemach kontroli wersji i na zależnościach pomiędzy modułami. Dało mi sporo do myślenia i dużo funu.
Po wszystkim krótki wypad na after-party, gdzie można było się pointegrować z innymi uczestnikami konferencji, a potem niestety 11-godzinna randka z PKP.

Duży szacunek dla ABB, sponsora konferencji, za bardzo profesjonalne podejście poprzez brak nachalnego marketingu. Poza tym ekipa organizacyjna spisała się na medal. Pełny profesjonalizm. W przyszłym roku znów spróbuję się wybrać i polecam to samo każdemu.,

05 października, 2012

Coursera, minirecenzja

Pod koniec kwietnia 2012 zacząłem przygodę z serwisem Coursera, gdzie zapisałem się na dwa kursy on-line: o kompilatorach i o machine learning. Obecnie ciągnę kurs z algorytmów(który niestety chyba obleję...) oraz programowania funkcyjnego w Scali. Chciałem się podzielić skrótem z wrażeń:

  • Machine Learning to bardzo fajny kurs. Niezbyt trudny, szczególnie jeżeli ma się podstawy algebry i znajomość octave albo matlaba. Kurs traktuje o bardzo ciekawych zagadnieniach i pokazuje praktyczne przykłady zastosowania technik z zakresu "machine learning". W ramach kursu napiszemy własny system rekomendujący filmy czy sieć neuronową do rozpoznawania zeskanowanych cyfer. Fun!
  • Kompilatory to kurs, moim skromnym zdaniem, fundamentalny dla każdego programisty. Nie powtórzcie mojego błędu i nie bierzcie na siebie tego kursu wraz z innym albo jeżeli nie wiecie, czy będziecie mieli na niego czas. W ramach tego kursu napisałem swój własny kompilator i kompletnie zmieniłem sposób, w jaki myślę o programach. Kurs zaliczyłem z problemami, ale nie żałuję ani godziny na niego poświęconej.
  • Algorytmy są bardzo ciekawym kursem, ale też wymagającym odrobiny czasu. Prowadzący są ewidentnie kompetentni i zadają bardzo ciekawe problemy do rozwiązania w ramach zadań domowych. Niestety nie udało mi się wyłuskać wystarczającej ilości czasu, żeby spokojnie zaliczyć kurs, ale już wiem, że go powtórzę przy następnej edycji.
  • Programowanie funkcyjne w Scali to najlepsza rzecz, jaka zdarzyła mi się od sięgnięcia po Code Complete McConnel'a. Bardzo fajny kurs, który zmienia mózg w sposób, który ciężko opisać... jeżeli nigdy nie programowaliście funkcyjnie, a chcielibyście poćwiczyć szare komórki, to gorąco polecam. Dodatkowym plusem jest fakt, że kurs prowadzi jeden z autorów języka Scala, Martin Odersky.

Photo by Rickydavid
Poza tym staram się monitorować EdX i Udacity. Jeżeli znajdę któryś z tamtejszych kursów interesującym, to dam znać.

Ogólna rekomendacja brzmi: idźcie i uczcie się!

28 września, 2012

Testy modułowe albo mit pokrycia


Nie sądziłem, że ten post jest konieczny, ale wygląda na to, że dopadł mnie syndrom Blutfelda.
<dygresja>
Tych, którzy nie wiedzą, o co chodzi z Herr Blutfeldem, odsyłam do powieści Jacka Dukaja "Lód". W dużym skrócie Herr Blutfeld, jeden z drugoplanowych bohaterów wyżej wymienionej powieści, nie zabiera głosu w prawie żadnej dyskusji, których w opowieści jest naprawdę mnogo. W czasie, kiedy inni współpasażerowie Kolei Transsyberyjskiej spierają się żywo i efektownie, on woli oddawać się przyjemności jedzenia wszystkiego, co da się zjeść, od czego nabawił się paru dodatkowych podbródków.
Podczas jednego z postojów Herr Blutfeld nie wytrzymuje i wybucha. Okazuje się, że nie jest głupawy ani pozbawiony własnych poglądów - przeciwnie! Nie zgadza się z żadnym ze współpasażerów i uważa wszystkie ich opinie za głupie, nietrafione i kretyńskie. Problem w tym, że za każdym razem kiedy ma się już odezwać i wytknąć towarzyszom błędy w rozumowaniu, dochodzi do wniosku, że nie ma najmniejszego sensu się odzywać ponieważ wszystko, co ma do powiedzenia jest oczywiste! O-czy-wis-te! Nie ma sensu zużywać tlenu i drażnić neurony; tracić energię na tłumaczenie rzeczy tak prostych i po trzykroć oczywistych.
Podczas swojej przemowy nasz bohater ani na chwilę nie przestaje jeść. Priorytety!
</dygresja>
Przechodząc do rzeczy:
Ostatnio w rozmowie z dość kompetentnymi ludźmi usłyszałem taką opinię:
Nasze testy modułowe są dobre ponieważ mamy wysokie pokrycie kodu.

Photo by roxj
Na początku pomyślałem, że kolega sobie zażartował, ale ponieważ mój czujnik sarkazmu nawet nie drgnął, zapytałem czy oby na pewno nie raczył żartować... Niestety nie. Witki mi opadły. Gratulacje! Odkryliśmy pewną miarę jakości testów modułowych! Nie potrzebujemy o nich już żadnych książek, szkoleń ani dobrych praktyk! Wiemy już wszystko!


W dużym skrócie:
Dobre testy będą miały wysokie pokrycie kodu, ale wysokie pokrycie nie zagwarantuje nam, że testy są dobre. Dlaczego? Zastanówmy się, czym jest pokrycie kodu... to że linia kodu jest pokryta podczas testu oznacza, że w ramach wykonania testu ta linia została odwiedzona, nic więcej. Procesor przemielił instrukcje, które stały pod tą linią kodu. Nie ma tu mowy o sprawdzaniu, czy te instrukcje zrobiły to, czego się spodziewaliśmy. Nie ma nawet słowa o tym, czego się spodziewaliśmy.

Dobre testy dokładnie określają czego się spodziewamy, łącznie z tym, co się nie powinno wydarzyć... problem jest taki, że do tego opisu ciężko przypiąć liczbę.
Jest to zaleta, którą mierzenie pokrycia posiada i która jest niestety nadużywana.