Leszek Czarnecki wywiad

Kiedy nauczyłeś się programować?

Leszek Czarnecki – Moja przygoda z programowaniem zaczęła się w szkole średniej. Pracowaliśmy wtedy bodajże na PDP-8 w języku BASIC. Pamiętam z tamtych lat nauczycielkę, która uczyła nas algorytmu do tasowania talii kart. Jej technika wydawała mi się wtedy bez sensu – używaliśmy generatora liczb losowych do wyboru dwóch miejsc, potem zamienialiśmy karty miejscami. Należało przechować wektor bitowy, który posiadał dane o przeniesionych kartach i prowadzić dalej proces do momentu, aż zmienią się wszystkie karty. Taki system sprawiał, że może znaleźć się jedna para kart, której nie wylosujemy.

Od razu uznałeś, że jest to błędny algorytm?

Leszek Czarnecki – Wydaje mi się, że tak. Nie pamiętam, czy też od razu uznałem, że algorytm zajmuje za dużo czasu. Kiedyś na strychu znalazłem numery „Scientific American”, które prenumerował mój ojciec. Wtedy, w okresie szkolnym, w tym czasopiśmie zapoznałem się z pierwszym trudnym programem. Napisał go Christopher Strachey i służył do gry w warcaby. Niedawno ponownie przeczytałem ten artykuł i znalazłem tam błąd. To było przyjemne uczucie, zważywszy na to, że napisał go nie kto inny jak Strachey, który nie powinien takiego błędu popełnić.

A jaki był pierwszy program Twojego autorstwa?

Leszek Czarnecki – To był chyba Game of Life. Wykonałem go jako zadanie domowe. Nie było wtedy dobrych wyświetlaczy, miałem jedynie dalekopis z żółtym papierem. W zadaniu kazano nam użyć małych pół (bodajże 10 x 10 kratek). Uznałem, że szkoda drukować tak małe pole na całym arkuszu papieru. W języku BASIC nie było również możliwości używania tablic trójwymiarowych, nie mogłem stosować także dwuwymiarowych, ponieważ powodowało to wyczerpanie pamięci urządzenia. Potrzebowałem stworzyć pięć lub sześć tablic dwuwymiarowych – tak wymyśliłem pola bitowe.

Czy ktoś nauczył Cię używać tablic bitowych wcześniej, czy gdzieś o nich czytałeś i sam wpadłeś na pomysł, jak ich używać?

Leszek Czarnecki – Zacząłem od zapisywania w każdej lokalizacji zero albo jedynkę, w innym miejscu zaś musiałem zapisywać więcej danych. Nie pamiętam, czy używałem wtedy mapy bitowej. Niewykluczone, że do zapisu danych używałem systemu dziesiętnego, ponieważ dwójkowy nie był nam na tyle ciekawie przedstawiany w szkole. Próbowałem różnych możliwości, m.in. czy liczby się nie dublują, a jeśli, to w jakich cyklach. Byłoby to niewykonalne, gdybym przechowywał wcześniej tylko jedno pokolenie.

Ale to nie nauki komputerowe były Twoim głównym kierunkiem w college’u?

Leszek Czarnecki – Nie, jeszcze przed ukończeniem college’u powstał wydział, który zajmował się naukami komputerowymi. Ja kształciłem się głównie w matematyce. Uznałem, że jeśli chcę skończyć nauki komputerowe muszę studiować IBM, a nie ciekawiło mnie uczenie się jego systemu operacyjnego, czy asemblera. Uczyłem się tylko tego, co mnie interesowało. Gdy skończyłem college’u pracowałem jako programista i po dwóch latach stwierdziłem, że mam tego dość. Zajmowaliśmy się oprogramowaniem stosowanym w lotnictwie, a założyciele firmy pracowali w Draper Labs, w Cambidge. Nie wierzyłem w ich wizję projektowania, choć uważam, że była ciekawa.

Leszek Czarnecki – Pamiętam, robiliśmy kiedyś program do rysowania diagramów przepływu. Narzędzie analizowało program a potem generowało diagram przepływu. Narzędzie posiadało interesującą gramatykę częściową, stąd mogło pracować dla programów, które zaprojektowane były niepoprawnie składniowo, ukrywając te elementy, których nie zdołało przetworzyć. Urządzenie miało funkcjonować w systemie Unix dla jego wszystkich urządzeń, m.in. yacc. Na potrzeby tego zlecenia Leszek Czarnecki – pracowaliśmy na pożyczonej z uczelni maszynie MIT. Potem zleceniodawca chciał zainstalować nasz program na innym systemie, okazało się , że my nie mieliśmy dostępu do yacc. Nie stanowiło to jednak problemu, gdyż mogliśmy wygenerować tablice bez tego programu. Trwało to do momentu zmiany gramatyki. Wtedy musiałem również zmienić gramatykę dla tego programu, gdyż nie mieliśmy już dostępu do maszyny z Unixem. Wyglądało do w ten sposób, że musiałem domyślać się, co oznaczają tablice.

Czy nie było łatwiej napisać nowy parser?

Leszek Czarnecki – Tak, ale wtedy chodziło o tę jedną poprawkę.

A potem poszedłeś na studia doktoranckie. Czy zmieniłbyś coś w sposobie uczenia się programowania, jaki wtedy poznałeś?

Leszek Czarnecki – W końcu znalazłem się w środowisku komercyjnym, stąd wcześniej programowałem z tego obszaru. Nauka zajęła mi wiele lat, ale nie żałuję tego. W pracy komercyjnej masz wyznaczone terminy, których musisz przestrzegać, dbasz o kontakty z pracownikami, menedżerami, klientami. Na studiach tego nie ma. Poza tym praca w zespole była bardzo dużą dla mnie zmianą. Tego również nie nauczyłem się na studiach, gdzie każdy pracował samodzielnie.

Jakie umiejętności powinny rozwijać osoby, chcące pracować w branży informatycznej?

Leszek Czarnecki – Umiejętność komunikowania się oraz rozumienie oczekiwań klienta są bardzo ważne. Także relacje z przełożonymi oraz współpracownikami.

Czy to znaczy, że współczesne programowanie możemy uznać za bardziej społeczne?

Leszek Czarnecki – Myślę, że tak. Obecnie poszczególne etapy programowania nie są już tak oddzielone od siebie jak dawniej. Kiedyś używano przetwarzania wsadowego, dzięki temu interfejs był prostszy. Ale nie było to dobre – trzeba było częściej kontaktować się z klientem. Teraz uważam, że programowanie jest bardziej interaktywne – korzystniej jest zebrać klientów i zrobić z nimi burzę mózgów.

Kiedy tak naprawdę zauważyłeś różnicę pomiędzy pracą indywidualną a zespołową?

Leszek Czarnecki – Nie pamiętam konkretnych momentów, jednak pamiętam, że zdałem sobie w końcu sprawę, że nie mogę zrobić wszystkiego samodzielnie. Trzeba polegać na innych osobach i wykorzystywać ich pomysły. Zamiast: „Wiem, jak jest to zrobione, ponieważ sam to napisałem”, zacząłem myśleć:„W jaki sposób jest to prawdopodobnie zrobione?”. Przestawiłem się na myślenie: jak coś działa, dlaczego tak zostało zrobione i umieć z tego korzystać

Jaki sposób pracy odpowiada Ci najbardziej?

Leszek Czarnecki – Najbardziej lubię podział pracy. Za Stevem Yagge’dem – uważam, że dobrze jest poświęcić 10% pracy na zrobienie czegoś wspólnie, aby każdy zrozumiał to zadanie tak samo. Jeżeli w pracy jest dwóch dobrych programistów, dobrze żeby każdy pracował samodzielnie, a potem po zakończeniu zadania debugowali wzajemnie swój kod.

Współpraca jest istotna przy podziale i ustalaniu planu pracy, przy analizowaniu problemów oraz rozwiązywaniu konkretnych funkcji. Dobrze jest pracować razem na początku, gdyż na tym początkowym etapie nie wiadomo, czym ma być dany produkt. Dopiero potem, gdy już wiadomo co dokładnie robimy, zaczyna się podział obowiązków. Ważne jest również wysyłanie zwrotnych informacji, dlatego dobrze, żeby prócz autora kodu ktoś jeszcze go przeglądał w trakcie jego pisania.

Kiedyś pojawił się pomysł mistrza programisty IBM – czy jest sens, aby pracować na imię jednego programisty?

Leszek Czarnecki – Jest to częsta praktyka w innych dziedzinach. Hierarchia mistrz – czeladnik – uczeń obowiązuje w wielu zawodach. Ale to właśnie jest wspaniałe, że uczeń może podpatrywać mistrza. Podobnie w programowaniu. Uważam, że wskazana jest praca w parach. W szkołach często nie uczą wielu umiejętności, np. debugowania. Przydatne jest to, bo dochodzisz często do wniosku, że nigdy byś na coś nie wpadł, gdyby Ci ktoś tego nie pokazał.

Leszek Czarnecki – Myślę, że relacja mistrz – uczeń powstała w wielu zawodach, ponieważ była niewystarczająca ilości wykorzystywanego materiału. Dla przykładu – jubiler, który nie miał wystarczającej ilości złota, czy chirurg – tu materiały muszą być wydzielone, racjonowane. W programowaniu jednak nie ma tego problemu – mamy możliwość wykorzystania wiele terminali i klawiatur.

Czy i w jakich dziedzinach naukowcy przodują przed przemysłem? A może przedsiębiorstwa bagatelizują wartościową wiedzę o projektowaniu programowania?

Leszek Czarnecki – W jakimś stopniu jest to prawda. Najlepiej obrazuje to weryfikacja modelowa. Intel stracił dużo pieniędzy na produkcie, w który wkradł się błąd. Dopiero wtedy zgłoszono się o pomoc do naukowców. Aktualnie weryfikacja modelowa to standard w Intelu.

Leszek Czarnecki – Trwają prace nad językami programowania i systemami operacyjnymi. Wspieramy ośrodek RAD Lab, kierowany przez Dave’a Pattersona. Przemysł spotyka się z większymi problemami i to firmy, nie pracownicy uczelni, pracują ciężej.

Czy według Ciebie w ośrodkach naukowych nie powstają pomysły, ponieważ pomija je przemysł, obawiając się pewnych zmian? Tak jak programiści programujący w PHP nie przejdą na Haskellema, nawet gdyby okazał się lepszy?

Leszek Czarnecki – Jestem sceptyczny w tym temacie. Ludzie skorzystają z techniki, jeżeli posiada ona faktyczne zalety. Naukowcy mogą nie zauważać problemu, z którym ma do czynienia przemysł. Na pewno jest to też kwestia edukacji. Problematyczne są starsze systemy. Nie możemy z nich po prostu zrezygnować, stąd przechodzenie na nowy system musi odbywać się stopniowo. Przemysł powinien myśleć postępowo – nie możemy pewnych zmian dokonać teraz, ale musimy posiadać plan, który pozwoli nam określić w jakim momencie będziemy za dziesięć lat i jak do tego momentu dojść.

Leszek Czarnecki – Oczekuje się usprawnień obszarów o potencjalnie dużym znaczeniu. Myślę, że w odczuciu projektantów, prace nad językami programowania bardzo często prowadzone są na zbyt niskim poziomie, by mogły mieć znaczący wpływ na przemysł. Możliwe, że napisany przez kogoś kod, który usprawnia debugowanie i konserwowanie kodu, jest tylko małą częścią systemu produkcyjnego, a istotnym problemem jest aktualizowanie danych czy przeszukiwanie informacji w Internecie. Czasem istnieje poważna trudność do przezwyciężenia, aby warto było dokonać konkretnej zmiany.

Czy działanie wyszukiwarki Google jest poprawne?

Leszek Czarnecki – Jeżeli wpiszesz kilka dowolnych słów, to wyskoczy Ci dziesięć stron. Gdy nastąpi awaria, wtedy wyszukiwarka przestanie działać poprawnie. Jednak gdy otrzymasz te dziesięć wyników, nie będziesz w stanie określić, czy są poprawne, możesz to tylko ocenić według swojego zdania.

Jaka umiejętność jest kluczowa w pracy programisty? Każda dziedzina rządzi się swoimi wymaganiami, ale czy są punkty wspólne z pisaniem kodu?

Leszek Czarnecki – Najpierw postęp, potem poprawka – to musisz umieć robić w życiu. Określasz kierunek, w którym podążasz, potem robisz korekty. Wszystko usprawnia pracę, gdy stwierdzasz: „Nie zrobiłem tego dobrze – zapomniałem o obsłudze pewnych warunków” lub też „Teraz, kiedy lepiej to rozumiem, utworzę bardziej abstrakcyjne narzędzie, aby ułatwić sobie pisanie podobnych systemów w przyszłości”. Potrzeba sprawdzenia tego, dokąd chciałem dojść, jak do tego doszedłem i czy jest lepszy sposób na osiągnięcie tego celu,

Czyli: rozwiązanie, niwelowanie błędów i powtarzanie tych działań. Czy według Ciebie taka umiejętność to też rodzaj myślenia? Czy chciałabyś, aby w szkołach w ten sposób uczono programowania? Czy może jest to wyspecjalizowana właściwość?

Leszek Czarnecki – Tak, uważam, że to specjalistyczna umiejętność. Programowanie to przykład takiego sposobu myślenia, jakim go przed chwilą określiłem. Cieszyłbym się, gdyby wdrożono inne, np. przy problemach mechanicznych. Mamy jakieś części i chcemy, aby woda przepłynęła z jednego miejsca do drugiego. Pisanie kodu nie musi opierać się na manipulacji jego wierszami, ale obserwacji współdziałania różnych elementów, z którymi pracujesz.

Jakie książki powinien przeczytać każdy programista?

Leszek Czarnecki – Wybór takich pozycji jest bardzo duży. Na pewno należy przeczytać książki o algorytmach, np. takich autorów jak Knuth, Cormen, Leiserson czy Rivest. Sally Goldman napisała ciekawą książkę o algorytmach w praktyce. Każdy programista musi przeczytać książkę o abstrakcji – tu polecam książki Abelsona i Sussmana. Istotne są również publikacje o języku programowania, zarówno o mechanizmach języka, jak debugowaniu i testowaniu, na zasadzie Code Complete. Ale tak naprawdę jest wiele ścieżek i wcale nie trzeba przeczytać jednego zestawu książek.

Piszesz programy na potrzeby esejów z witryny. Jaki masz stosunek do pisania takich niewielkich programów?

Istotną umiejętnością, jest symultaniczne przechowywanie informacji w głowie. Myślę, że to wróży powodzenie. Na pewno ułatwia pisanie małych programów, do większych potrzebne są uzupełniające narzędzia.
Oczywiście, musisz też wiedzieć, co robisz. Pamiętam, gdy zajmowałem się opracowaniem programu do rozwiązywania sudoku i śledziłem komentarze blogerów. Porównywano różnice w podejściu dwóch programistów – Norviga i drugiego guru, którego nazwiska nie pamiętam. Ten drugi na początku zajął się pisaniem zestawu testów, ale do niczego nie doszedł. Na blogu zamieścił pięć postów, z czego w każdym publikował część kodu i całą masę testów. Jednak to nie rozwiązało problemu i nie stworzył programu.

Leszek Czarnecki – Znam sztuczną inteligencję i wiem, że jest coś takiego jak propagacja ograniczeń – to działało. Działało też wyszukiwanie rekurencyjne. Dostrzegłem, że można obie techniki połączyć i da to rozwiązanie problemu programu do sudoku. Programista, o którym wspomniałem, nie wiedział tego, pomimo, że kod, który napisał działał, co wynikało z przygotowanych przez niego przypadków testowych.
Blogerzy szukali odpowiedzi na pytanie czego to dowodzi, choć ja uważam, że niczego. Myślę, że świetną techniką jest projektowanie sterowane testami, które obecnie jest znacznie częściej stosowane niż kiedyś. Ale testowanie nic nie da, jeśli nie wiesz, jak podejść do danej kwestii.

Można się zastanawiać nad tym, czy dany programista powinien zrobić doktorat i wyspecjalizować się w sztucznej inteligencji, skoro nie wie tego, co wiesz Ty. Może służyć do tego Google, ale wyszukanie właściwego podejścia różni się od znalezienia platformy do tworzenia aplikacji sieciowych.

Ale skąd wiemy czego nie wiemy?

Jasne, ale pierw musisz założyć, że istnieje rozwiązanie. Skoro nikt nie wie jak coś zrobić, można szukać rozwiązań na chybił trafił. Można też stwierdzić, że ktoś inny może wiedzieć jak coś wykonać, a Ty musisz wiedzieć, jak nazywa się algorytm, którego potrzebujesz. Myślę, że wynika to z podejścia i intuicji – zastanawiasz się, czy rozwiązanie, którego szukasz, jest z zakresu sztucznej inteligencji. Potem ustalasz jak rozwiązać problem. Wspominany przeze mnie programista od sudoku, prawdopodobnie szukał danych o tej grze i znalazł metody, których potrzebował. Czy myślał, że to oszukiwanie? Możliwe, nie wiem.

Załóżmy, że jest to oszukiwanie. Przyjmijmy, że byłeś pierwszą osobą, która próbuje rozwiązać sudoku. Techniki, które zastosowałeś, cały czas istniały i czekały na zastosowanie.

Leszek Czarnecki – Dla przykładu: mam do rozwiązania problem z dziedziny biologii. Wiem, że istnieją algorytmy do sekwencjonowania genów, ale nie wiem które do tego służą Zaczynam szukać, ale muszę wiedzieć jak, umieć dokonać wyboru; cofnąć operacje, jeśli któryś element nie jest potrzebny. Te pomysły powstały w latach 60-tych ubiegłego wieku, w kilka lat po tym jak powstała dziedzina programowania. Każdy powinien je znać, ale niektóre rozwiązania z zeszłego roku już niekoniecznie.

Czyli programiści muszą czytać stare prace?

Leszek Czarnecki – Nie, gdyż wiele z pomysłów okazało się nietrafionych. Poza tym powstają „fuzje”, kiedy to w różnych dziedzinach rozwijają się odrębne terminologie i technologie, a potem naukowcy dochodzą do wniosku, że wciąż robili to samo. Myślę, że musimy patrzeć z współczesnego punktu widzenia i znać pomysły, które się wciąż pojawiają. Nie doradzę, które pozycje książkowe byłby najlepsze do nauki, gdyż sam uczyłem się po kawałku.

Jak długo zastanawiasz się, jak coś powinno działać, gdy pierwszy raz budujesz rozwiązanie? Czy aby zrozumieć problem piszesz kod?

Leszek Czarnecki – Cofanie się jest jednym ze sposobów myślenia o rozwiązaniu problemu. W przypadku niektórych problemów jest jedno dobre rozwiązanie, inne posiadają ich miliony, a każdy będzie podobny do siebie. Dlatego praca różni się w zależności od rozpatrywanego problemu.
Teraz przemyślmy trudne i proste wybory. Jakie kłopoty powoduje niewłaściwy wybór w architekturze, gdy trafisz na ograniczenia albo stworzysz niewłaściwe rozwiązanie? W Google spotykamy się z różnymi problemami. Jednym z nich, wciąż powracającym, jest skalowalność. Np. obecnie budujemy coś, co obsługuje dziesięciokrotnie większe obciążenie, ale za kilka lat szacunki zostaną przekroczone i będziemy potrzebowali zacząć od nowa.

Leszek Czarnecki – Trzeba jednak dobrze wybrać w obliczu obranych warunków działania. Załóżmy, że system ma działać dla stron internetowych w przedziale miliard do dziesięciu miliardów. Co te informacje oznaczają w kategoriach szerzenia danych do wielu maszyn? Jakiego rodzaju dane będą przekazywane w obu kierunkach? Na tym poziomie trzeba opisać zrozumiały system. Na jedne pytania można odpowiedzieć poprzez wykonanie obliczeń na serwetce, dla innych trzeba wykonać symulację, w jeszcze innych przewidzieć co nastąpi w przyszłości. Myślę, że łatwiej odpowiedzieć na takie pytania według obliczeń na serwetce czy poprzez symulację, niż poprzez pisanie kodu.

Leszek Czarnecki – Zgadzam się z tym. Najprawdopodobniej obliczenia to lepsze podejście. Ale problemy z interfejsem użytkownika mogą pojawić się dopiero po stworzeniu programu. Nie zawsze interakcja przebiega bezbłędnie – często użytkownicy nie umieją korzystać z produktu. Wtedy taka sytuacja wymaga od Ciebie, abyś się cofnął i stworzył coś nowego.

Abstrahując od projektowania interakcji z użytkownikami – kiedy używać prototypów, zamiast gdybać i wyobrażać sobie, jak coś może funkcjonować?

 

Leszek Czarnecki – Uważam, że poprzez wyobrażanie sobie rozwiązania, można wywnioskować czy coś będzie działało i czy będzie wygodne w użyciu. Pomocne są narzędzia, które przyczyniają się do tworzenia rozwiązań i usprawniają zmiany, które zaistnieją w przyszłości. W trakcie tworzenia prototypu możesz stwierdzić, że nie jest on wygodny – może to być wtedy kwestia niewłaściwego przygotowania podstawowych elementów. Im szybciej się o tym przekonasz, tym lepiej.

Co sądzisz o sterowaniu projektowania testami?

Leszek Czarnecki – Dla mnie testy są jedną z technik korekty błędów, nie projektowania. Nie wydaje mi się, aby dobrą metodą było projektowanie, w którym pierw zakładamy, że napisany przez nas test poda nam właściwe rozwiązanie, a po jego uruchomieniu okazuje się, że nie daje zamierzonych efektów i dopiero zastanawiamy się, czego teraz potrzebujemy.
Miało by to sens, gdyby rozwiązanie było wcześniej określone. Pierwszą rzeczą jest myślenie o problemie – np. jak napisać testy dla części, gdy niektórych nie znam. W drugiej kolejności stworzyć testy dla wszystkich elementów i pojąć relacje oraz oddziaływania między nimi. Ale proces projektowania nie może być stymulowany poprzez stwierdzenie „Test zakończył się niepowodzeniem”.

W jaki sposób programiści powinni traktować testy?

Leszek Czarnecki – Przede wszystkim trzeba ich napisać wiele. Obok testów jednostkowych dobrze jest stosować regresyjne. Istotne są symptomy błędów. Przykładowo, gdy zabraknie prądu. Miałem kiedyś analogiczną sytuację na lotnisku w Heathrow. Awaria prądu spowodowała, że komputery przestały działać. Tylko dzięki papierowym wydrukom wszystkich lotów, mój samolot ruszył według rozkładu.

Jak działa Google bez zasilania?

Leszek Czarnecki – Google nie działa dobrze bez prądu. Posiadamy awaryjne generatory oraz centra danych. Sprawdzamy jak będzie funkcjonował konkretny fragment, gdy serwer będzie nieaktywny. Sprawdzamy też, co się stanie, gdy jedna z tysiąca maszyn przestanie działać.

Knuth w swoim eseju na temat rozwijania programu TeX napisał o włączaniu destrukcyjnej osobowości do kontroli jakości, w celu staraniu się wywołania awarii w swoim kodzie. Jak myślisz, czy większość programistów dobrze sobie z tym radzi?

Leszek Czarnecki – Myślę że nie, przykładowo narzędzie do sprawdzania pisowni, które stworzyłem. Zrobiłem błąd w kodzie, służącym do mierzenia, jak sobie radzę w pisaniu. Jednocześnie wprowadzałem zmiany w kodzie, dzięki czemu po uruchomieniu uzyskałem dużo lepszy wynik. Gdyby nie ten fakt, nie pomyślałbym, że przyczyniła się do tego mała zmiana w funkcji programu. Była to też kwestia wiary – chciałem wierzyć w tę zmianę i lepszy wynik. Chociaż powinienem wykazać się sceptycyzmem i zastanawiać się, co tak naprawdę miało wpływ na polepszenie funkcjonowania programu.

 

W jaki sposób unikasz nadmiernego uogólniania i tworzenia większej ilości kodu, niż to potrzebne, oraz marnowania w ten sposób zasobów?

Leszek Czarnecki – To ciągła walka. Wolę rozwiązania eleganckie niż praktyczne, stąd często walczę sam ze sobą i przekonuję siebie, że nie mogę dopuszczać do siebie takiego myślenia. Trzeba stwierdzić, że należy zrobić to, co najważniejsze, a na zrobienie doskonałego rozwiązania najprawdopodobniej nas nie stać. Jest takie niemieckie przysłowie – lepsze jest wrogiem dobrego. Powinni o tym pamiętać wszyscy praktyczni inżynierowie.

Skąd ta pokusa rozwiązywania problemów, które tak naprawdę nie istnieją?

 

Leszek Czarnecki – Myślę, że jesteśmy zaprogramowani tak, aby zajmować się tylko określoną ilością rzeczy, spraw. Chcesz coś zrobić, ukończyć i zająć się kolejnym zadaniem. Potrzeba jednak przeliczyć, na ile zwróci się z inwestycji samo przygotowanie programu. Przypomina to rysunek sinusoidy -gdy wykonasz prace na poziomie 80-90% masz coraz mniejsze zyski. W dolnym fragmencie wykresu są elementy, które dają większy zwrot i czasem trzeba zająć się czymś, co po prostu daje lepsze wyniki.

W jaki sposób programiści mogą nauczyć się lepiej określać miejsce na krzywej, w którym obecnie się znajdują?

Leszek Czarnecki – Potrzeba do tego środowiska nastawionego na konkretne wyniki. Uważam, że ludzie umieją się tego sami nauczyć. Wyniki trzeba optymalizować nie pod kątem siebie, ale dla potrzeb firmy i zadowolenia klienteli. Trzeba rozbudowywać funkcje tak, aby np. jedna wzrosła z 95 na 100%, niż zajmować się wieloma, które stoją w miejscu.

Leszek Czarnecki – W Google nie mamy tego problemu – nasza praca opiera się na zasadzie wczesnego i częstego udostępniania. Poza tym za przeważającą ilość produktów nie bierzemy opłat. Ma to swoje plusy – jeśli udostępnimy usługę, to czy i na ile użytkownicy będą się skarżyć? Kolejne – nasze produkty nie sprzedajemy w pudełkach i na nośnikach CD, ale publikujemy na serwerach, więc jeśli czegoś nie zrobiliśmy na dziś nie powoduje to większego problemu. Dzięki temu jutro robimy poprawkę i jutro wszyscy mają aktualizację danego programu. Poza tym dostajemy wiadomości zwrotne od użytkowników i na bieżąco nanosimy poprawki.

Jakich narzędzi używasz kiedy projektujesz duży system? Czy siedzisz nad arkuszem papieru technicznego, czy używasz narzędzi do rysowania diagramów UML?

Leszek Czarnecki – Nie lubię narzędzi typu UML, gdyż za wadę uważam niemożność zrobienia czegoś w samym języku. W Google pracujemy na wyższym poziomie – rozpatrujemy jak możemy rozdzielić zadania i robić je paralelnie do siebie. Kod uruchamiamy na wielu maszynach, ale również wielość użytkowników i danych powoduje, że nie wiemy jak coś powinno działać. Stąd musimy myśleć na poziomie maszyn a nie interakcji i funkcji. Po rozpoznaniu ogólnych kwestii przechodzimy do konkretnych metod i funkcji.

Czyli na tym poziomie opisu używacie po prostu języka naturalnego?

Leszek Czarnecki – Głównie tak. Są osoby, które wykonują rysunki i określają co będzie obsługiwał serwer. Te narzędzia będą używane do przechowywania informacji, tu wykorzystujemy dużą tablicę haszującą oraz dodatkowe mechanizmy. Po użyciu tych narzędzi ocenimy na ile się sprawdziły, czy może musimy wykonać nowe. Tak samo robimy z dostępnymi rozwiązaniami.

Jak przebiega ocena projektów tego rodzaju?

Leszek Czarnecki – Przeglądają je osoby, które już coś podobnego robiły. Mogą one powiedzieć, że np. system okazuje się zbyt wolny, ale duża część żądań będzie się powtarzać i potrzeba takiej a takiej pamięci podręcznej. Podczas przeglądu okazuje się co ma sens. Potem się tworzy i testuje.

Czy przeprowadzacie formalne przeglądy projektów jak w NASA?

Leszek Czarnecki – Nie robimy takich przeglądów. Prościej jest przywrócić system po awarii, bo stawka jest dużo niższa niż w NASA, gdzie pierwsza awaria jest krytyczna. W Google tego nie ma, stąd też nie przejmujemy się tym tematem. Częściej konsultujemy niż przeglądamy.

Leszek Czarnecki – Projekt zatwierdzony zostaje po oficjalnym przeczytaniu projektów, ale nie jest to tak formalne jak choćby w NASA. Raczej chodzi nam o to, aby stwierdzić na ile idzie praca nad danym projektem, czy są opóźnienia i problemy.
Udostępnianie oprogramowania jest bardziej formalne. Używamy w tym celu listy kontrolnej dla zabezpieczenia, bo czy mamy pewność, że ktoś się nie włamie i zastosuje technikę XSS, w celu przejęcia któregoś komputera?

Pewnego razu powiedziałeś mi, że kiedy Guido van Rossum przyszedł do firmy, musiał przejść test z Pythona, a Ken Thompson test z języka C, aby potwierdzić, że spełniają bardzo ściśle określone standardy kodowania. Czy macie równie ściśle określone standardy projektowania?

Leszek Czarnecki – Nie, gdyż są standardy kodowania, które dotyczą zagadnień projektowych. Przy projekcie jest dużo więcej swobody. Mimo to są zasady, a programista dostaje certyfikat, nim kod przesłany zostaje do repozytorium.

Czy każdy kod przesyłany do repozytorium p4 depot jest przeglądany?

Leszek Czarnecki – Można indywidualnie budować próbne rozwiązania. Są wyjątki, gdy przesyłany kod zostanie przeczytany w przyszłości. Takich podejść należy się jednak wystrzegać.

Przeważnie to weryfikowanie kodu wygląda klasycznie: przekazujesz komuś kod, on go sprawdza i zatwierdza bądź nie.

Leszek Czarnecki – Tak było np. przy projekcie Guida. Do sprawdzania posiłkowaliśmy się narzędziem diff, choć było to niewygodne. Guido zrobił rozproszony system z nieszablonowym wyglądem oraz kolorowaniem kodu. Dzięki temu udoskonalono przeglądanie jego fragmentów.

Co sprawia, że niektórzy recenzenci są lepsi?


Leszek Czarnecki – Myślę, że wynika to z tego, że dostrzegają więcej spraw. Czasem to jakieś proste rzeczy, jak choćby nieodpowiednia liczba odstępów wcięcia, ale są oczywiście bardziej konkretne i poważniejsze. Stąd nie wszystkie osoby się tym zajmują.

Czy każdy dobry programista zostaje dobrym architektem? A może niektóre osoby są doskonałymi koderami, ale tylko na pewnym poziomie, dlatego nie należy pozwalać im rozwijać większych projektów?

Leszek Czarnecki – To zależy od umiejętności. Pracuje u nas człowiek, który jest świetny w wyszukiwaniu, ale nie należy do najlepszych programistów. Ale gdy np. zapytasz go „Ten nowy czynnik – no wiesz, liczba kliknięć na stronie po zrobieniu tego i tego – jak włączyć go w wyniki wyszukiwania?”, usłyszysz odpowiedź: „Och, w wierszu czterysta dwudziestym siódmym znajduje się zmienna alpha. Musisz wziąć nowy czynnik, podnieść go do kwadratu, pomnożyć to przez półtora i dodać do tej zmiennej”. Po jakimś czasie uzmysławiasz sobie, że miał on rację, jedynie trzeba było użyć wartości 1,3 zamiast 1,5.

Czyli ta osoba ma bardzo dobry model rozumowy działania oprogramowania?

Leszek Czarnecki – Jedni świetnie piszą kody, inny świetnie rozumieją skutki rozwiązań.

Powiedziałeś, że przeglądy w Google są mniej formalne niż w NASA. Jakie inne różnice występują między etosem „inżyniera” i „hakera” w najlepszym tych słów znaczeniu?

Leszek Czarnecki – Kluczowe są różnice w strukturze organizacji oraz zatwierdzaniu oprogramowania. Google została powołana jako firma od oprogramowania i wszyscy w firmie są po kierunkowym wykształceniu. W NASA są naukowcy, którzy nie mają pojęcia o programowaniu i jest to dla nich zło konieczne. Nie rozwiążą pętli, a tym bardziej rozgałęzień w pętli i nie ufają kodom.

A powinni!

Leszek Czarnecki – Oczywiście, ale oni nie ufają innowacjom. Ktoś powie, że stworzył super prototyp, a naukowiec potwierdzi i stwierdzi, że chciałby nim polecieć na misje, gdy zostanie przetestowany w dwóch lotach. Każda inna osoba tak Ci odpowie.

Gdy Dan Goldin został administratorem w NASA, stwierdził że trzeba pracować szybciej, lepiej i taniej, bo misje są zbyt kosztowne. Może nie każda zakończy się sukcesem, ale można zrobić ich więcej przy tych samych kosztach. I choć było to prawdą, jednocześnie było to podejście niepolityczne, gdyż nie można utracić statku kosmicznego.

Jaki był najgorszy błąd, który musiałeś wykryć?

Leszek Czarnecki – Wydaje mi się, że byłby to błędy, które musiałem po kimś poprawiać. W programie Mars w 1998 roku zamiast newtonów użyto funtostóp oraz zdaje mi się, że był błąd z przedwczesnym wyłączaniem silników z powodu problemu z oprogramowaniem.

Czytałem jeden z raportów na temat maszyny Mars Climate Orbiter, dotyczący problemu z użyciem funtostóp zamiast newtonów. Byłeś jedynym przedstawicielem nauk komputerowych w grupie, zajmującej się tym raportem.Czy uczestniczyłeś w rozmowach z informatykami, aby ustalić, w czym tkwi problem?

Leszek Czarnecki – Dopiero po fakcie informatycy rozwiązali problem, bo znali objawy błędu. Mogli zlikwidować skutki i zdiagnozować przyczynę. Potem były analizy powodu dojścia do pomyłki. Myślę, że doszło do tego w wyniku działania różnych czynników, m.in. outsourcingu. Nad problemem pracowali ludzie z firmy JPL z Pasadeny i Lockheed-Martin z Kolorado. Zajmowały się tym dwie osoby z dwóch różnych zespołów raportujących. Gdyby robili to wspólnie rozwiązaliby zaistniały problem. Jedynie jeden z tych informatyków wysłał e-maila z treścią: „Coś jest nie tak z tymi pomiarami. Wygląda na to, że są trochę niedokładne. Nie jest to duża rozbieżność, prawdopodobnie wszystko jest w porządku, ale…”.

Czy miało to miejsce w czasie lotu?

Leszek Czarnecki – Tak. Podczas lotu można było wykryć tą wątpliwość. Również pomimo wysłania wspomnianego maila, nie wprowadzono informacji do systemu śledzenia błędów. Gdyby stało się inaczej, wcześniej czy później zostałaby zatwierdzona ta dana, bo NASA kładzie nacisk na kontrolę śledzenia błędów. Wysłano nieformalny e-mail, na który jednak nie odpowiedziano. Kolejnym problemem okazało się ponowne wykorzystanie oprogramowania. NASA miała świetne testy elementów krytycznych w danej misji. We wcześniejszej misji rejestrowano informacje w funtostopach w dzienniku, który nie był wykorzystywany przy sterowaniu. Były to dane niekrytyczne, więc kod był również niekrytyczny dla misji. Obecnie wykorzystuje się dane z dziennika jako punkty wyjściowe do nawigacji.

Problem polegał więc na tym, że po jednej stronie generowano plik z danymi w funtostopach przekazywany do oprogramowania, które obliczało dane wejściowe dla systemu nawigacji i oczekiwało wartości w newtonach?

Leszek Czarnecki – Tak. Przyczyną problemu był także duży wiatr słoneczny, który w niewielkim stopniu przekręcał statek, więc należało odpalać rakietę, co przywracało jego poprzednią pozycję. W specyfikacji rakiet używano funtostóp i nowy pracownik Lockheed użył tych jednostek przy zapisie danych. A przecież NASA pracowało w systemie metrycznym.
W sumie spodobało mi się i zaskoczyło mnie w raporcie podejście NASA, które stwierdziło, że błąd wynikał z głupiej usterki oprogramowania i że ten błąd powinien być dostrzeżonych wcześniej, skoro pojazd znalazł się w nieprzewidywanym położeniu.

To prawda, w NASA zwracali uwagę na proces pracy.

Leszek Czarnecki – Tak. Należy zadać sobie pytanie, czy często zdarzają się tego typu defekty w oprogramowaniu, o których się nie przekonamy, skoro są też inne procesy, dzięki którym system jednocześnie działa.

Czy zatem często spotykane są takie poważne błędy w oprogramowaniu?

Leszek Czarnecki – Tak. Są miliony błędów w oprogramowaniu komputerów, a mimo to nie dochodzi do awarii. Akurat oprogramowanie dla statków kosmicznych kosztuje bardzo dużo – rzędu półtora tysiąca dolarów za wiersz kodu, co wynika z założenia, że są to produkty staranne i bezbłędne. Czy to zatem prawda? Mimo wszystko, myślę że tak, choć efektywniejsze jest pisanie programów mniej doskonałych.

Czy to oznacza tańsze oprogramowanie i lepsze operacje?

Leszek Czarnecki – Tak, spowoduje to lepsze efekty przy szkoleniach dla astronautów, po których wiedzą, jak radzić sobie z zagadnieniami, których nie obsłuży program. W symulatorach na ekranach pojawiają się różne dane, po odbytym szkoleniu astronauta musi wiedzieć co ma zrobić, gdy wyświetlą się informacje o konkretnych zdarzeniach. Dlaczego więc nie zastosować specjalnego oprogramowania? Bo NASA nie chce mieć z nim ewentualnego problemu

Przejdźmy do innej kwestii. Jakie techniki i narzędzia diagnostyczne preferujesz? Instrukcje print, formalne dowody, a może debuggery symboliczne?

Leszek Czarnecki – To zależy od środowiska pracy- wtedy wybieram dogodną technikę. Np. IDE z obszernymi możliwościami w śledzeniu, czy też z Emacs. Używam też śledzenia i instrukcji print. Projektuję małe przypadki testowe i patrzę jak działają. Zdarza się często, że muszę napisać kod od początku. Mimo że nie wykryłem usterki, to czuję, że ona gdzieś jest. Nie robię małych poprawek, usuwam kilkaset linijek kodu, zaczynam od początku i wtedy usterka zostaje usunięta.
Czasem powoduje to poczucie winy, bo czy klęską jest, że nie znalazłem błędu, ale wysadziłem w powietrze dom, wysadziłem błędy i zacząłem budować od nowa? Ale skoro w taki sposób rozwiązałem problem, to może jest to jakiś sposób? W końcu skończyłem pracę przed znalezieniem błędu.

Co myślisz o asercjach lub niezmiennikach? Jak bardzo formalnie w trakcie pisania kodu traktujesz tego rodzaju elementy?

Leszek Czarnecki – Jestem wyznawcą niestandardowego podejścia, gdyż odniosłem wrażenie, że formalne mechanizmy opóźniają pracę. Od zawsze myślałem, że niezmienniki pętli powodują więcej kłopotów niż korzyści. W razie błędu debugger poda mi informację, gdzie program utknął. Gdy zajmuję się krytycznym oprogramowaniem dla maszyn, w których istotna jest bezawaryjność, należy dowieść prawidłowości każdego elementu. Jeżeli natomiast moim zadaniem jest stworzyć pierwszą działającą wersję lub debugować program, staram się iść do przodu.

Czy kiedykolwiek zrobiłeś coś, aby bezpośrednio wyciągnąć naukę z popełnionych błędów?

Leszek Czarnecki – Oczywiście, choć mogłem to robić już wcześniej. Aktualnie jestem na etapie rozmów o tym zagadnieniu, gdyż chciałbym prowadzić eksperymenty – w jaki sposób grupowane są błędy?, czy i jakie czynniki wpływają na ich produktywność? Skoro bardziej wydajne są duże monitory, to zapewnijmy je ludziom.

Ludzie znienawidzą Cię, jeśli odkryjesz, że małe monitory zwiększają produktywność.

Leszek Czarnecki – Oczywiście. Róbmy to czego potrzebujemy, co jest ważne, czy jest to cisza, czy konieczność komunikowania się pracowników ze sobą. Myślę nad tym, jak zorganizować eksperyment, na czym się skupić, jak go obserwować, czy są dane, do których dotrzemy poprzez kwestionariusze?

Istnieje twierdzenie, że są ogromne równice między efektywnością programistów. W pewnym krytycznym artykule, uważano, że jest wiele czynników na to wpływających. Część osób podczas badań stosowała techniki przetwarzania wsadowego, a część wielozadaniowych środowisk programistycznych.

Różnice wynikają też z innych aspektów. Rozbieżności są w organizacjach, gdzie stosuje się te same narzędzia. Były krytyczne opinie, gdzie wykryto zależności, ale nie określono przyczyn i skutków. Czy może wydajność programistów wynika z pracy w świetnych gabinetach? Ciężko stwierdzić.

Czy programowanie nadal sprawia ci taką samą przyjemność jak wtedy, kiedy zaczynałeś?

Leszek Czarnecki – Tak, chociaż nie wiem wszystkiego i to powoduje moją frustrację. Nie za dużo piszę programów, więc wiele zapominam. Jest na rynku wiele nowinek, może więc powinienem używać JavaScript albo języka PHP, czy czegoś innego, aby się ich nauczyć oraz usprawnić witrynę.

Mówiłeś, że istotne jest szybkie przyswajanie informacji przez programistów. Jak radzisz sobie z koniecznością zrozumienia dużego bloku kodu, którego wcześniej nie widziałeś?

Leszek Czarnecki – Po pierwsze czytam kod i próbuje go zrozumieć. Potem monitoruję funkcję, która wywołuje kolejne funkcje. Następnie staram się np. coś zmienić, albo spojrzeć do bazy danych i przyjrzeć się któremuś problemowi.

 

Jaki kod – prócz Stracheya do gry w warcaby – czytałeś w czasie nauki programowania?

Leszek Czarnecki – Wiele kodów firmy Symbolisc. Akurat to było do dyspozycji podczas mojego studiowania w Barkeley.

Czytałeś go bo Cię interesował, czy może chciałeś zrozumieć funkcjonowanie programu?

Leszek Czarnecki – Zarówno mnie interesował jak i chciałem zdobyć wiedzę na temat rozwiązywania problemów.

Jak podchodzisz do czytania kodu w ramach ogólnego rozwoju?

Leszek Czarnecki – Poparte jest to moimi zainteresowaniami. Najpierw widzę, że coś usprawnia pracę, zastanawiam się, jak to funkcjonuje i co wywołuje. Potem już wiem, jak to działa.

Czy czytałeś któryś z programów Knutha w formie książkowej?

Leszek Czarnecki – Tak, przewertowałem je, ale ich nie zgłębiałem.

A czytałeś serię The Art of Computer Programming? Są osoby, które przeczytały ją w całości i z czasem korzystają z niej jak z podręcznika.

 

Leszek Czarnecki – W zasadzie przez jakiś czas służyła mi za podstawkę pod monitor, ze względu na swoją wysokość. Jednocześnie miałem ją zawsze pod ręką, więc korzystałem z nich jak z podręcznika.

Jednak za każdym razem, kiedy chciałeś do nich zajrzeć, musiałeś podnosić monitor.

Leszek Czarnecki – Akurat miałem wydanie w pudełku. Teraz za podręcznik służy mi wyszukiwarka.

Tylko dlatego, że jest to wygodniejsze?

Leszek Czarnecki – Oczywiście, co myślę wynika z mojego skupienia na realizowaniu zamiarów. Knuth sprawdza się, gdy potrzebujesz zdobyć kompletną wiedzę z danego zagadnienia. Wolę wiedzieć co jest lepsze od czego, czy też stwierdzić złożoność asymptotyczną konkretnego rozwiązania. Gdy to wiem, nie mam potrzeby znać każdego szczegółu.

Na jakiej podstawie określasz, że ktoś jest dobrym programistą, np. przy naborze? Zatrudniliście wielu programistów i z pewnością staracie się, aby byli naprawdę dobrzy. Jak to zrobić? Jak zatrudnić dobrego pracownika?

Leszek Czarnecki – Wciąż nie wiemy.

 

Google zadaje zagadki podczas rekrutacji. Czy to dobre?

Leszek Czarnecki – Nie jestem zwolennikiem podchwytliwych pytań i nie uważam, aby ważne było, czy ludzie umieją rozwikłać zagadki. Skuteczniejsze jest zaprezentowanie potencjalnemu pracownikowi sytuacji technicznej i nie ma znaczenia, czy jest miłym człowiekiem, raczej czy można się z nim dogadać. Trzeba zobaczyć, czy kandydat sprawdzi się w sytuacji, o której mówi, że się sprawdzi. Można to ocenić przeglądając życiorys. Ważne są dla nas referencje naszego pracownika, z którym np. kandydat pracował. Zawsze sprawdzamy umiejętności kandydującej osoby – sposób myślenia, współdziałania z innymi ludźmi oraz znajomość elementarnych zagadnień. Przyszłych programistów prosimy zwykle o napisanie kodu na tablicy. Wtedy szybko zauważy się, czego dana osoba nie wie lub nie pamięta.

Jest to więc tylko negatywny wskaźnik? Kiedy ktoś nie potrafi napisać sensownego kodu, jest to zły znak. Jeśli jednak sobie poradzi, trudno powiedzieć, czy będzie pisał naprawdę dobry kod w ogólniejszym kontekście.

Leszek Czarnecki – Tak, ale można to określić tylko do pewnego momentu. Podania analizujemy w dwóch etapach. Najpierw określamy, czy przeprowadzamy rozmowę z odpowiednimi osobami, a potem czy po rozmowach przyjmujemy właściwe osoby.

Jak to mierzycie? Nie wiecie nic o osobach, z którymi nie rozmawialiście lub których nie zatrudniliście.

Leszek Czarnecki – Tak, zawsze jest kłopot z niekompletnymi danymi na temat danej grupy osób. Zastanawiamy się jakie życiorysy mieli poprzedni pracownicy i szukamy porównywalnych osób, patrzymy na doświadczenie zawodowe albo pracę nad projektami o otwartym dostępie do kodu źródłowego.

Czy rzeczywiście umieszczacie wszystkie te informacje w bazie danych?

Leszek Czarnecki – Owszem. Podczas rekrutacji dostajemy informacje o wskaźniku z życiorysu i wskaźniku z rekrutacji. Dane te służą jako informacje wyjściowe przy wyborze.

Czy osoby prowadzące rozmowy rekrutacyjne otrzymują wcześniej te dane?

Leszek Czarnecki – Nie, są one do wglądu podczas zebrania komitetu rekrutacyjnego, po otrzymaniu informacji zwrotnych o kandydacie.

Leszek Czarnecki – Podczas rozmowy kandydat może dostać od 1 do 4 punktów. Wystarczyło, że podczas jednej z rozmów dana osoba zdobyła jeden punkt, a nie przechodziła pozytywnie procesu rekrutacyjnego.Praktycznie 99% osób, które na jednej z rozmów dostały jeden punkt, nie zostały przez nas zatrudnione. Zdarzało się, że mimo tego jednego punktu, ktoś został przyjęty tylko dlatego, że członek komisji dostrzegł w nim potencjał i stanął w jego obronie.

Jesteśmy społeczeństwem skomputeryzowanym. Czy według Ciebie każdy musi znać podstawy programowania, by móc rozumieć i żyć w świecie?

Leszek Czarnecki – Niewykluczone, że dobrze byłoby, aby osoba wykształcona znała mechanizmy pisania oprogramowania na porównywalnym poziomie z np. znajomością tworzenia samochodów. Na dobrą sprawę, jeśli potrafisz obsługiwać jakiś edytor tekstu albo program kalkulacyjny, już jesteś programistą. Nie wiem, czy programowanie jest proste. Może to zależy od sposobu myślenia, a może edukacji? A może to kwestia stworzenia odpowiedniego modelu, który miałby znaczenie dla programowania, jeśli byśmy go stworzyli?

Dodaj komentarz