Spartańskie programowanie

Oryginalny post: Spartan Programming

Autor: Jeff Atwood

W miarę jak staję się starszy i mądrzejszy jeszcze starszy jako programista, zauważyłem, że mój osobisty styl pisania kodu podąża mocno w stronę minimalizmu.

Byłem zadowolony, dowiedziawszy się, iż wiele z konwencji kodowania, na które się zdecydowałem w ciągu ostatnich 20 lat zostało usystematyzowanych w Spartańskim programowaniu.

Nie, nie w tym sensie spartańskie, aczkolwiek istnieje historyczne powiązanie. Konkretne znaczenie słowa spartański, do którego się odnoszę to:

(przymiotnik) ascetyczny, surowy, spartański (praktykujący wyrzekanie się) "Być systematycznie ascetycznym...robić...coś z tego samego powodu, dla którego wolałbyś tego nie robić" - William James; "skromne życie pustynnego koczownika"; "spartańska dieta"; "spartański byt"

Próbowałem pisać skromniej, nawet do tego stopnia by nie pisać żadnego kodu tam, gdzie mogę się bez niego obyć. Spartańskie programowanie doskonale zrównuje się z tymi celami. Dążysz do jednoczesnej minimalizacji swojego kodu w wielu wymiarach:

  1. Złożoność pozioma. Głębokość zagnieżdżania struktur sterujących.
  2. Złożoność pionowa. Liczba linii bądź długość kodu.
  3. Liczba tokenów.
  4. Liczba znaków.
  5. Parametry. Liczba parametrów procedury bądź struktury generycznej.
  6. Zmienne.
  7. Instrukcje pętli. Liczba instrukcji iteracyjnych oraz ich poziom zagnieżdżenia.
  8. Warunki. Liczba wyrażeń if oraz switch.

Dyscyplina spartańskiego programowania oznacza oszczędne używanie zmiennych:

  1. Minimalizuj liczbę zmiennych. Zmienne używane tylko raz deklaruj inline. Wykorzystuj pętle foreach.
  2. Minimalizuj widoczność zmiennych oraz innych identyfikatorów. Definiuj zmienne w możliwie najmniejszym zakresie.
  3. Minimalizuj dostępność zmiennych. Preferuj lepsze kapsułkowanie zmiennych private.
  4. Minimalizuj niestałość zmiennych. Staraj się robić zmienne final w Javie i const w C++. Używaj adnotacji albo restrykcji gdzie to możliwe.
  5. Minimalizuj czas życia zmiennych. Preferuj krótkotrwałe zmienne od tych długożyjących. Unikaj trwałych zmiennych takich jak pliki.
  6. Minimalizuj nazwy zmiennych. Krótkożyjące, mające wąski zasięg zmienne mogą używać treściwych i zwięzłych nazw.
  7. Minimalizuj używanie zmiennych tablicowych. Zastępuj je kolekcjami dostarczonymi przez Twoje standardowe biblioteki.

Dyscyplina ta również oznacza oszczędne używanie struktur sterujących, z możliwie najwcześniejszym zwracaniem wartości. Najlepiej to zilustrować konkretnym przykładem, zaczynając od nieprzerobionego kodu i refaktoryzując go używając technik programowania spartańskiego:

Nie zgadzam się ze wszystkimi przedstawionymi zasadami i wskazówkami, ale kiwałem głową przy większości rzeczy na tej stronie. Minimalizm nie zawsze jest dobrym wyborem, ale rzadko jest złym wyborem. Z pewnością mógłbyś zrobić coś gorszego niż zaadoptowanie dyscypliny spartańskiego programowania przy swoim następnym projekcie programistycznym.

(czapki z głów dla Yuval'a Tobias'a za przesłanie mi tego odnośnika)

Data publikacji oryginału: lipiec 8, 2008

Kodowanie: to po prostu pisanie

Oryginalny post: Coding: It's Just Writing

Autor: Jeff Atwood

W swoim artykule Programistyczne aforyzmy Strunka i Whitea, James Devlin jak zwykle znakomicie opisuje coś, co sam zacząłem coraz częściej dostrzegać w ciągu ostatnich pięciu lat, a mianowicie:

Niespodziewany związek pomiędzy pisaniem kodu, a pisarstwem.

Prawdopodobnie nie ma na świecie lepszego opracowania na temat pisarstwa niż książka The Elements of Style (w wolnym tłumaczeniu: "Składowe stylu") autorstwa Strunka i Whitea. Jest to jedna z tych książek, które odkrywasz w liceum bądź w koledżu, a następnie przez resztę swego życia zastanawiasz się, dlaczego inne podręczniki tak marnują Twój czas poprzez wykorzystywanie tylu niepotrzebnych słów, aby przekazać jakąś treść. Jak wszystkie wielkie dzieła, książka ta na zawsze odmienia Twój sposób postrzegania świata, nawet jeśli czyni to tylko w niewielkim stopniu.

Na Wikipedii można poczytać trochę na temat historii i okoliczności powstania tej ponadczasowej książki:

[Książka "The Elements of Style"] pierwotnie napisana została w 1918 roku i prywatnie opublikowana przez profesora Williama Strunka Juniora, profesora wykładającego na Cornell University. W 1935 roku, przy pomocy Edwarda A. Tenneya powstała pierwsza jej rewizja. W 1957 uwagę na nią zwrócił E. B. White, który przez wiele lat pisał dla New Yorkera. White studiował pod skrzydłami Strunka jeszcze w roku 1919, ale od tamtej pory nie wspominał tej "książeczki", którą sam nazwał "czterdziesto trzy stronicowym podsumowaniem na temat czystości, dokładności i zwięzłości w posługiwaniu się językiem angielskim".

The Elements of Style

Kilka tygodni później White napisał artykuł do New Yorkera, w którym sławił profesora Strunka i jego przywiązanie do "klarowności" w posługiwaniu się angielską prozą. Po tym jak autor książki zmarł w 1946 roku, wydawnictwo Macmillan and Company upoważniło Whitea do opracowania nowego wydania "Składowych stylu". Opublikowane ono zostało w 1959 roku w postaci znacznie rozszerzonej i zmodernizowanej przez Whitea. Ta właśnie wersja znana jest milionom pisarzy i studentów jako po prostu "Strunk and White". Pierwsze wydanie Whitea sprzedało się w liczbie dwóch milionów kopii. Całkowita sprzedaż wszystkich trzech wydań przekroczyła 10 milionów kopii na przestrzeni czterech dekad.

Wszystko pięknie i fajnie jeśli planujesz zostać pisarzem, ale jaki jest związek między tą małą, ponadczasową książeczką a pisaniem programu komputerowego?

Napiasnie programu zrozumiałego dla komputera z pewnością jest wyzwaniem. Z tego powodu, mówiąc ogólnie, stosunkowo niewielu ludzi zostaje kompetentnymi programistami. Jednakże pisanie akapitów i zdań, których odbiorcą ma być drugi człowiek -- cóż, to jest jeszcze trudniejsze. Im dłużej zajmujesz się tworzeniem oprogramowania, i im starszy się stajesz, w końcu zdajesz sobie sprawę, że aby odnieść prawdziwy sukces w tej dziedzinie, musisz pisać programy, które będą zrozumiałe nie tylko dla komputera, ale również dla Twoich kolegów po fachu.

Ze wszystkich okrutnych niespodzianek, jakie czyhają na nas w dziedzinie inżynierii oprogramowania, ta musi być chyba najbardziej bezlitosna. Większość z nas zaczęła zajmować się programowaniem komputerów, ponieważ maszyny są o wiele bardziej logiczne niż ludzie. Mimo to, nawet jeśli piszesz kod przeznaczony dla maszyny, to nadal jest to proces pisania. Dla innych ludzi. Omylnych, niepozbawionych wad, roztargnionych istot ludzkich -- takich jak Ty. I to właśnie jest ta prawdziwie trudna część.

Uważam, że Knuth miał na myśli to samo, gdy ukuł pojęcie programowania piśmiennego (pdf).

Spróbujmy zmienić nasze tradycyjne podejście do tworzenia oprogramowania: Zamiast wyobrażać sobie, że naszym głównym zadaniem jest poinstruowanie komputera, co ma zrobić, skoncentrujmy się na wytłumaczeniu istotom ludzkim, czego od komputera oczekujemy.

Praktyk programowania piśmiennego może być postrzegany jako eseista, który skupia się na prezencji i doskonałości stylu. Taki autor, uzbrojony w tezaurus, ostrożnie wybiera nazwy zmiennych i tłumaczy, jakie jest ich znaczenie. On czy ona stara się stworzyć program, który będzie jak najbardziej zrozumiały dla innych ludzi, porządkuje pewne koncepcje w określonej, naturalnej dla człowieka kolejności, używa w tym celu zarówno formalnych jak i nieformalnych metod, które wzajemnie uzupełniają się i wzmacniają.

Oczywiście łatwiej powiedzieć niż zrobić. Większość z nas spędza całe swe życie, ucząc się, jak pisać efektywnie. Książka taka jak "Składowe stylu" dostarcza wielu cennych wskazówek, które niemalże w całości dają się zastosować do procesu kodowania. Chciałbym szczególną uwagę zwrócić na jedną z zasad ze "Składowych stylu", do której sam nieustannie wracam, odkąd po raz pierwszy ją przeczytałem wiele lat temu.

13. Pomijaj zbędne słowa.

Mocne pisarstwo jest zwięzłe. Zdanie nie powinno zawierać niepotrzebnych słów, akapit -- zbędnych zdań, z tego samego powodu, dla którego rysunek nie powinien zawierać niepotrzebnych kresek a maszyna niepotrzebnych części. Nie oznacza to, że pisarz skraca wszystkie swoje zdania, albo że unika szczegółów i traktuje temat pobieżnie. Oznacza to, że każde słowo wnosi dodatkową treść.

Jak ma się to do Twojego pisania? A do Twojego kodu?

W końcu kodowanie to przecież tylko pisanie. Czy może to być aż tak trudne?

Data publikacji oryginału: listopad 8, 2008

Jedna rzecz, o której powinien wiedzieć każdy programista

Oryginalny post: The One Thing Every Software Engineer Should Know

Autor: Jeff Atwood

Jestem wielkim fanem Stevea Yegge, więc dużym zaszczytem była dla mnie możliwość goszczenia go przy okazji ostatniego podkasta Stack Overflow. Nie spodziewałem się natomiast, że jeden konkretny temat, związany z doświadczeniami Stevea z Google i Amazona, będzie się nieustannie przewijał:

Gdybym każdego programistę miał nauczyć tylko jednej rzeczy, byłby to marketing.

Nie jak pisać na klawiaturze, nie jak pisać w ogóle, nie jak zaprojektować język programowania, ale marketingu.

Wiem, bolesna prawda dla nas programistów, ponieważ kochamy kodować. Ale cały ten genialny kod jest całkowicie bez znaczenia, jeśli:

  1. ludzie nie rozumieją tego, co robisz,
  2. ludzi nie interesuje to, co robisz,
  3. ludzie nie są entuzjastyczni w stosunku do tego, co robisz.

To właśnie jest w skrócie marketing. Oczywiście jeśli zajmujesz się marketingiem, to nie musi to od razu oznaczać, że jesteś jedną z hien marketingowych. Te dwie rzeczy są mocno skorelowane, to fakt, ale u podstaw marketingu nie leży więcej, niż można dowiedzieć się ze średniozaawansowanych kursów na temat komunikacji międzyludzkiej. Nie do końca dziedzina, w której my programiści jesteśmy biegli.

Z tego powodu nawet najbardziej hardkorowi z hardkorowych programistów powinni słuchać ludzi takich jak Seth Godin. Steve natomiast mówił o marketingu w szerszym znaczeniu, a mianowicie jak sprawić, by ludzie zainteresowali się Twoimi pomysłami.

Po tym jak Steve wspomniał o tym kilka razy podczas naszego podkasta -- i po tym, jak zobaczyłem jego wykład zatytułowany "How to Ignore Marketing and Become Irrelevant in Two Easy Steps" -- nagle zdałem sobię sprawę, dlaczego tak bardzo zafascynowany byłem dwiema książkami, które ostatnio odkryłem. Do tych książek odwoływałem się caly czas podczas pracy nad Stack Overflow.

Whatever You Think, Think the Opposite (Cokolwiek myślisz, pomyśl odwrotnie) It's Not How Good You Are, It's How Good You Want to Be (Nieważne jak dobry jesteś -- liczy się to, jak dobry chcesz być)
Whatever you think, think the opposite It's Not How Good You Are, It's How Good You Want to Be

Nie byłem w stanie odłożyć tych małych książeczek Paula Ardena, zanim nie przeczytałem ich do końca. Zgadnijcie, w jaki sposób pan Arden zarabiał kiedyś na życie. Zgadza się, był wykonawczym dyrektorem kreatywnym w Saatchi & Saatchi - firmie zajmującej się reklamą.

Zdarzyło mi się czytać brzydkie książki. Książki o marketingu. I to nawet z własnej, nieprzymuszonej woli. Trochę mi wstyd przyznawać się do tego, ponieważ zazwyczaj nabijam się z ludzi, którzy czytają książki tego typu. Ale przeczytanie tych wlaśnie książek uświadomiło mi, że większość spraw, którymi zajmujemy się podczas prac nad Stack Overflow nie ma nic wspólnego z tym, jak wspaniały jest nasz kod -- za to ma wiele wspólnego z marketingiem.

Jako że wszyscy tutaj jesteśmy programistami, pozwólcie, że zobrazuję to w bardziej zrozumiały sposób: za pomocą statystyk postaci w Dungeons & Dragons. Wiecie, klasyka.

RPG character stats: STR DEX CON INT WIS CHA

Jeśli jesteś programistą i chcesz z roku na rok stawać się lepszym w tym, co robisz, to mogłoby Ci się wydawać, że najistotniejszą charakterystyką jest kodowanie. Załóżmy, że to podpada pod INT. Tak więc po wielu latach harówki, Twoje statystyki wyglądają mniej więcej tak:

str 6
dex 9
con 12
int 51
wis 13
chr 4

OK, jesteś genialnym programistą. Ale Twój kod może nigdy nie ujrzeć światła dziennego z przyczyn, na które nie masz wpływu. To iluzja. Jesteś w stanie kontrolować kiedy, jak i gdzie Twój kod się pojawia. Jednak prawdopodobnie spędziłeś za dużo czasu na tworzeniu kodu, a za mało poświęciłeś na promowanie swojego kodu. Czy wytłumaczyłeś ludziom, co Twój kod robi, dlaczego jest "cool" i dlaczego jest ważny? Czy przedstawiłeś im powody, dla których Twój kod uczyni ich życia lepszymi, nawet w niewielkim stopniu? Czy zrobiłeś coś, by ułatwić ludziom znalezienie i używanie Twojego kodu?

Sądzę, że większość programistów zyskałaby więcej w kontekście swoich karier zawodowych, gdyby starała się rozwijać swe charakterystki raczej w ten sposób:

str 16
dex 14
con 15
int 18
wis 16
chr 17

Czasami stajesz się lepszym programistą poprzez decyzję niepisania kodu. Zgadzam się tutaj ze Stevem: gdybym mógł nauczyć swoich kolegów-programistów tylko jednej rzeczy, byłaby to wiedza jak promować siebie, swój kod i swoje projekty.

Data publikacji oryginału: październik 22, 2008

Zaproszenie do beta-testów nowego serwisu

Zapraszamy wszystkich chętnych do beta-testów nowego serwisu internetowego: http://www.metafoto.pl. Kod dostępu to: let.me.in. Będziemy wdzięczni za wszelkie komentarze i sugestie.

Immortal & Rafek

Ilość zawsze przebija jakość

Oryginalny post: Quantity Always Trumps Quality

Autor: Jeff Atwood

Nathan Bowers wskazał mi ten pięcioletni wpis na Cool Tools o książce Art & Fear.

Mimo iż nie jestem gotów nazwać tworzenia oprogramowania "sztuką" -- być może "rzemiosło" byłoby bardziej odpowiednie, albo "inżynieria" jeśli wolisz -- podobieństwa pomiędzy niekórymi poradami zawartymi w książce a moim doświadczeniem w pisaniu oprogramowania są wyraźne.

Nauczyciel od ceramiki ogłosił na początku dnia, że podzieli całą klasę na dwie grupy. Wszyscy Ci po lewej stronie studio, powiedział, skupią się jedynie na ilości wyprodukowanych dzieł, a wszyscy po prawej stronie na jakości. Jego metoda była prosta: na koniec zajęć przyniesie swoją wagę łazienkową i zważy dzieła grupy "ilościowej": 50 funtów garnków ocenionych na "A", 40 funtów na "B" i tak dalej. Natomiast ci skupieni na "jakości", mieli wyprodukować tylko jeden garnek - aczkolwiek perfekcyjny - aby dostać "A".

Tak więc nastał czas oceniania i pojawił się ciekawy fakt: wszystkie dzieła najwyższej jakości były wyprodukowane przez grupę skupiającą się na ilości. Okazuje się, że podczas gdy grupa "ilościowa" pracowicie ucierała mnóstwo dzieł - i uczyła się na swoich błędach - grupa "jakościowa" siedziała teoretyzując na temat perfekcji, a na koniec miała niewiele więcej do pokazania niż wspaniałe teorie oraz stertę zmarnowanej gliny.

Gdzie to wcześniej słyszałem?

  1. Przestań teoretyzować.
  2. Pisz dużo oprogramowania.
  3. Ucz się na swoich błędach.

Ilość zawsze przebija jakość. Dlatego właśnie jedną z małych porad, której zawsze udzielam ambitnym blogerom jest ustalenie harmonogramu i trzymanie się go. To jedyna rada jaka ma znaczenie, ponieważ dopóki nie zaangażujesz się, by powtarzać coś na okrągło, nie udoskonalisz się. Nie jesteś w stanie.

Ta sama zasada sprawdza się również w dziedzinie tworzenia oprogramowania. Jeśli nie tworzysz, nie uczysz się. Zamiast zadręczać się, czy tworzysz odpowiednią rzecz, po prostu ją stwórz. A jeśli ta nie działa, kontynuuj tworzenie dopóki otrzymasz taką, która działa.

Data publikacji oryginału: sierpień 2, 2008

PHP to badziew, ale to nie ma znaczenia

Oryginalny post: PHP Sucks, But It Doesn't Matter

Autor: Jeff Atwood

Oto lista wszystkich funkcji zaczynających się na literę "A" w indeksie funkcji PHP:

abs() apc_load_constants() array_intersect() array_values()
acos() apc_sma_info() array_intersect_assoc() array_walk()
acosh() apc_store() array_intersect_key() array_walk_recursive()
addcslashes() apd_breakpoint() array_intersect_uassoc() ArrayIterator::current()
addslashes() apd_callstack() array_intersect_ukey() ArrayIterator::key()
aggregate() apd_clunk() array_key_exists() ArrayIterator::next()
aggregate_info() apd_continue() array_keys() ArrayIterator::rewind()
aggregate_methods() apd_croak() array_map() ArrayIterator::seek()
aggregate_methods_by_list() apd_dump_function_table() array_merge() ArrayIterator::valid()
aggregate_methods_by_regexp() apd_dump_persistent_resources() array_merge_recursive() ArrayObject::__construct()
aggregate_properties() apd_dump_regular_resources() array_multisort() ArrayObject::append()
aggregate_properties_by_list() apd_echo() array_pad() ArrayObject::count()
aggregate_properties_by_regexp() apd_get_active_symbols() array_pop() ArrayObject::getIterator()
aggregation_info() apd_set_pprof_trace() array_product() ArrayObject::offsetExists()
apache_child_terminate() apd_set_session() array_push() ArrayObject::offsetGet()
apache_get_modules() apd_set_session_trace() array_rand() ArrayObject::offsetSet()
apache_get_version() apd_set_socket_session_trace() array_reduce() ArrayObject::offsetUnset()
apache_getenv() array() array_reverse() arsort()
apache_lookup_uri() array_change_key_case() array_search() ascii2ebcdic()
apache_note() array_chunk() array_shift() asin()
apache_request_headers() array_combine() array_slice() asinh()
apache_reset_timeout() array_count_values() array_splice() asort()
apache_response_headers() array_diff() array_sum() aspell_check()
apache_setenv() array_diff_assoc() array_udiff() aspell_check_raw()
apc_add() array_diff_key() array_udiff_assoc() aspell_new()
apc_cache_info() array_diff_uassoc() array_udiff_uassoc() aspell_suggest()
apc_clear_cache() array_diff_ukey() array_uintersect() assert()
apc_compile_file() array_fill() array_uintersect_assoc() assert_options()
apc_define_constants() array_fill_keys() array_uintersect_uassoc() atan()
apc_delete() array_filter() array_unique() atan2()
apc_fetch() array_flip() array_unshift() atanh()

Pamiętam moje pierwsze doświadczenie z PHP dawno temu, w 2001 roku. Pomimo mojego wątpliwego pochodzenia z ASP i Visual Basic'a, przeglądanie alfabetycznej listy funkcji PHP wystarczyło, by odstraszyć mnie na lata. Jakkolwiek by nie było, przeglądając powyższą listę, nie sądzę, żeby wiele się zmieniło od tamtego czasu.

Nie jestem specjalistą od języków, ale projektowanie ich jest trudne. Istnieje powód, dla którego większość sławnych informatyków na świecie jest także projektantami języków programowania. I wielka szkoda, że żaden z nich nie miał nigdy okazji pracować z PHP. Na tyle na ile go znam, PHP nie jest językiem, a raczej losową kolekcją przypadkowych rzeczy, wirtualną eksplozją w fabryce słów kluczowych i funkcji. Miej na uwadze, że te słowa pochodzą od człowieka, który był przyzwyczajony do BASIC'a, języka, który otrzymuje tyle respektu co Rodney Dangerfield. Tak więc tego rodzaju rzeczy nie są mi obce.

Oczywiście to są stare nowiny. Jak stare? Prastare. Z czasów Internet Explorera 4. Internet jest przepełniony artykułami o tym, że PHP jest beznadziejne -- praktycznie zabrakło mi zakładek w przeglądarce, żeby otworzyć je wszystkie. Tim Bray dzielnie przełamał tę tendencję razem ze swoim wpisem z długotrwałej serii "On PHP":

Oto mój problem, w oparciu o moje ograniczone doświadczenie z PHP (uruchomienie paru darmowych aplikacji, które robia to i tamto, oraz debugowanie strony dla nietechnicznego przyjaciela tu i tam): nie zdarzyło mi się jeszcze widzieć kodu PHP, który nie byłby niechlujnym, niemożliwym do utrzymania bajzlem. Spaghetti SQL opakowany w spaghetti PHP, opakowany w spaghetti HTML, powtarzany w niewiele różniącej się formie w wielu miejscach.

Artykuł Tim'a jest dobrym początkiem jak każdy inny; wyłapał grupkę powiązanych odnośników w następującej dyskusji. Jak będziesz go czytał, zauważysz oczywiste podobieństwo pomiędzy amatorszczyzną w programowaniu w PHP a w Visual Basicu 6, porónwanie, na które wielu programistów samemu by wpadło.

Fredrik Holmström:

Każde oprogramowanie jakie kiedykolwiek widziałem, bądź pisałem w PHP, sprawiało wrażenie niezdarnego i nieporęcznego, nie było w nim ani trochę elegancji, czy wdzięku. Pracowanie z PHP jest troche jak rzucanie 10 funtowego betonowego pustaka z dziesięciopiętrowego budynku: Szybko dostaniesz się tam dokąd zmierzasz, ale nie jest to piękne. ... Kocham PHP, i jest to odpowiednie narzędzie do niektórych zadań. Jest po prostu brzydki, nieporęczny i sprawia, że chce mi się płakać i mam koszmary. To jest nowy VB6 w przebraniu C.

Kral Seguin:

Z mojego własnego doświadczenia, oraz z niezliczonych tutoriali i blogów z sieci, wielu programistów PHP jest winnych tego samego badziewia, co kiedyś programiści VB. OO, N-Warstwowość, obsługa wyjątków, modelowanie domeny, refaktoryzacja oraz testy jednostkowe są obcymi konceptami w świecie PHP.

Zrozum, że jako stary programista VB jestem pełen współczucia do wyśmiewania, jakiego doświadczysz, programując w bardzo popularnym języku programowania, który nie jest uznawany za "profesjonalny".

Pisałem w VB jak i w PHP, i według mnie porównanie jest rażąco niesprawiedliwe dla Visual Basica. Czy PHP jest beznadziejne? Oczywiście, że jest. Czy przeczytałeś jakikolwiek z odnośników we wpisie na blogu Tim'a? To galaktyczna supernowa, niepojęcie olbrzymiego, niedającego się zrozumieć, okropnego badziewia. Jeśli usiądziesz, żeby coś napisać w PHP i masz w sobie choć odrobinę talentu programisty, nie ma możliwości, aby wyciągnąć z tego jakiś inny wniosek. Jest nieodparty.

Ale również chciałem powiedzieć, że nie ma to znaczenia.

TIOBE community index, do którego odniosłem się powyżej? Jest napisany w PHP. Wikipedia, która jest na pierwszych miejscach wyników wyszukiwarek w dzisiejszych czasach? Napisana w PHP. Digg, społecznościowy serwis z zakładkami, który jest tak popularny, że odnośnik na stronie głównej może spowodować, iż nawet najmocniejsze serwery odmówią posłuszeństwa? Napisany w PHP. WordPress, niewątpliwie najbardziej popularna platforma dla blogów w obecnej chwili? Napisany w PHP. YouTube, najbardziej znany serwis internetowy umożliwiający prezentowanie klipów video? Napisany w PHP. Facebook, warte miliardy dolarów społecznościowe oczko w głowie inwestorów funduszy Venture Capital? Napisany w PHP. (Update: Początkowo, Youtube został napisany w PHP, ale został zmigrowany do Pythona przez Matt'a Cutts'a i Guido van Rossum'a niedługo po tym jak powstał)

Zauważasz pewną zależność?

Niektóre z największych stron w Internecie -- stron, z którymi prawdopodobnie masz doczynienia codziennie -- są napisane w PHP. Skoro PHP jest tak bardzo beznadziejne, to dlaczego zasila tak znaczną część Internetu?

Jedyny wniosek jaki mogę wysnuć jest taki, że stworzenie atrakcyjnej aplikacji jest o wiele ważniejsze niż wybór języka. O ile PHP nie byłoby moim wyborem, a jeśli zmuszony, mógłbym się kłócić, że nie powinien być wyborem żadnego rozumnego człowieka siedzącego przed komputerem, nie mogę zaprzeczać wynikom.

Prawdopodobnie słyszałeś, że odpowiednio niekompetentni programiści mogą pisać stylem FORTRANowym w każdym języku. To prawda. Ale odwrotność jest również prawdziwa: odpowiednio utalentowani programiści mogą pisać wspaniałe aplikacje w okoropnych językach. To bolesna lekcja, ale ważna.

Po co z tym walczyć? Lpeiej naucz się to akceptować. Połącz się ze mną w celebrowaniu następnych 50 lat wspaniałego PHP tworzącego Internet. Tylko nie zapominaj wywoływać funkcji PHP utrzymuj_moją_wolę_do_życia() co pewien czas!

Data publikacji oryginału: maj 20, 2008

Niebezpieczne Java-Szkoły

Oryginalny post: The Perils of JavaSchools

Autor: Joel Spolsky

Leniwe dzieciaki.

Gdzie się podział kult ciężkiej pracy?

Niewątpliwą oznaką mojego starzenia się jest biadolenie i zrzędzenie, jaka to beznadziejna jest "ta dzisiejsza młodzież". Jeśli coś wymaga od nich wysiłku, to im się nie chce albo nie potrafią.

"Byłeś szczęściarzem. My to przez trzy miesiące musieliśmy mieszkać w pojemniku septycznym wyściełanym zwykłym kartonem. Musieliśmy wstawać o szóstej rano, czyścić karton, jeść twardy jak kamień chleb i gonić do pracy przy młynie, dzień w dzień, po czternaście godzin, a gdy wracaliśmy do domu, ojciec tulił nas do snu przy pomocy paska." — Latający Cyrk Monty Pythona, Four Yorkshiremen

Gdy ja byłem dzieckiem, uczyłem się programować na kartach perforowanych. Jeśli zdarzyło Ci się popełnić jakiś błąd, nie miałeś do dyspozycji żadnych nowoczesnych ficzerów, takich jak na przykład klawisz Backspace. Musiałeś wyrzucić kartę i zacząć od nowa.

Gdy w roku 1991 zaczynałem przeprowadzać rozmowy kwalifikacyjne z programistami, zazwyczaj pozwalałem im wybrać język programowania, w którym chcieliby rozwiązać postawiony przed nimi problem. 99% z nich wybierało język C.

W obecnych czasach wybierają Javę.

Nie zrozumcie mnie źle: Java, jako język stosowany w praktyce, jest całkiem w porządku.

Chwila, chciałbym inaczej sformułować tę myśl. Nie twierdzę wcale, w tym konkretnym artykule, że z Javą, jako językiem stosowanym w praktyce, jest coś nie tak. Z Javą wiele rzeczy jest nie w porządku, ale to musi poczekać na kolejny artykuł.

Twierdzę natomiast, że Java, generalnie, nie jest wystarczająco trudnym językiem, by móc go użyć do odróżnienia programisty przeciętnego od wybitnego. Być może jest to język, w którym wygodnie się pracuje, ale nie to jest dzisiejszym tematem. Mógłbym nawet pójść dalej i powiedzieć, że to, że Java jest stosunkowo łatwym językiem, to ficzer, a nie bug. Ale nie zmienia to faktu, że problem, o którym wspomniałem, wciąż istnieje.

Być możę zabrzmię trochę arogancko, ale moje skromne doświadczenie nauczyło mnie, że na uczelniach, na których wykłada się informatykę, tradycyjnie są dwa zagadnienia, ktorych wiele osób nigdy nie będzie w stanie w pełni pojąć: wskaźniki i rekurencja.

Na studiach dosyć szybko zaczynasz mieć do czynienia ze strukturami danych -- listami połączonymi, tablicami haszującymi itp. Bez wskaźników ani rusz. Tego typu przedmioty często służą do selekcji pierwszoroczniaków: są tak trudne, że każdy, kto nie jest w stanie podjąć umysłowego wyzwania, w końcu się poddaje. I dobrze. Jeśli sądzisz, że wskaźniki są trudne, poczekaj, aż przyjdzie Ci udowodnić coś w teorii punktu stałego.

Historia wielu dzieciaków, którym w liceum dobrze szło programowanie w BASICu kolejnych wersji Ponga, jest taka, że po pójściu do koledżu, zapisaniu się na przedmiot CompSci 101 (struktury danych) i zetknięciu ze wskaźnikami, ich mózgi zwyczajnie eksplodują. Nawet się nie spostrzeżesz, gdy okazuje się, że decydują się jednak skończyć nauki polityczne, bo ten kierunek wydaje im się lepszym pomysłem. Widziałem wiele statystyk pokazujących liczbę studentów, którzy rezygnują ze studiów informatycznych. Zazwyczaj oscylują one w granicach 40% - 70%. Uniwersytety mają skłonność do widzenia tego jako jakiejś straty; Ja z kolei uważam, że to po prostu niezbędny odsiew ludzi, którzy nie byliby szczęśliwi, bądź nie odnieśliby sukcesu, jako programiści.

Innym przedmiotem, sprawiającym wiele trudności młodym studentom informatyki, był ten przedmiot, na którym uczono programowania funkcjonalnego (również programowania rekurencyjnego). MIT postawiło wysoką poprzeczkę, tworząc obowiązkowy kurs (6.001) i wydając podręcznik (Structure and Interpretation of Computer Programs, Abelson & Sussman). Na wielu topowych uczelniach informatycznych używano ich jako de facto wprowadzenia do informatyki. (Masz możliwość, i powinieneś, obejrzeć online starszą wersję tych wykładów.)

Poziom trudności tych kursów jest zdumiewający. Na pierwszym wykładzie poznajesz właściwie wszystko na temat języka Scheme i przedstawiają Ci funkcję z punktem stałym, która na wejściu bierze inną funkcję. Gdy sam walczyłem z tym przedmiotem na Uniwersytecie w Pensylwanii, widziałem jak wielu, jeśli nie większość, studentów po prostu nie dawała rady. Materiał był za trudny. Napisałem wtedy długiego, rzewnego maila do profesora, w którym żaliłem się, że to Nie W Porządku. Ktoś na uniwersytecie musiał mnie posłuchać (albo jednego z innych narzekających), ponieważ teraz, przy prowadzeniu tego kursu, używa się Javy.

Żałuję, że posłuchali.

Myślisz, że się nadajesz? Sprawdź się!

W tym tkwi problem. Lata narzekań leniwych studentów wraz z zarzutami ze strony przemysłu, jak to mało jest absolwentów informatyki, dały się we znaki i w ostatniej dekadzie spora liczba dobrych uczelni całkowicie przerzuciła się na Javę. Super, rekruterom, którzy używają "grepa" do filtrowania życiorysów, to się podoba, i, co najlepsze, żaden aspekt Javy nie jest na tyle trudny, by można było odsiać tych programistów, którzy nie posiadają części mózgu odpowiadającej za wskaźniki i rekurencję, więc statystyki rezygnacji są niższe, a wydziały informatyki mają więcej studentów, wyższe budżety, i wszystko idzie dobrze.

Tym szczęściarzom z Java-Szkół nigdy nie będzie dane zobaczyć dziwnych segfaultów podczas próby implementacji tablic haszujących za pomocą wskaźników. Nigdy nie będą rwać sobie włosów z głowy podczas prób upakowania czegoś w jak najmniejszej liczbie bitów. Nigdy nie będą musieli wytężać swoich umysłow, aby zrozumieć jak to jest, że w czystym języku funkcjonalnym, wartość zmiennej nigdy się nie zmienia, a jednak zmienia się cały czas. Paradoks!

Nie potrzebują tej części mózgu, aby dostać 4 z obrony.

Czy nie jestem przypadkiem jednym z tych staroświeckich maruderów, jak w Four Yorkshiremen, przechwalających się, jakim to twardym trzeba było kiedyś być, żeby to wszystko przetrwać?

Cholera, w roku 1900 łacina i greka były obowiązkowe w koledżu, nie dlatego, że były do czegoś potrzebne, ale dlatego, że uważało się ich znajomość za całkiem oczywistą wśród wykształconych ludzi. W pewnym sensie moje argumenty nie róźnią się niczym od tych przedstawianych przez zwolenników łaciny (wszystkich czterech). "[Łacina] ćwiczy umysł. Ćwiczy pamięć. Rozszyfrowywanie łacińskich zdań jest doskonałym ćwiczeniem myślenia, prawdziwą intelektualną zagadką, oraz dobrym wprowadzeniem do logicznego myślenia.", pisze Scott Barker. W dzisiejszych czasach ciężko jednak znaleźć jakiś uniwersytet, na którym nauka łaciny byłaby wymagana. Czy wskaźniki i rekurencja są łaciną i greką informatyki?

Przyznaję, że programowanie z użyciem wskaźników nie jest potrzebne w 90% kodu pisanego w dzisiejszych czasach, byłoby to wręcz niebezpieczne w kodzie produkcyjnym. W porządku. A programowania funkcjonalnego nie używa się za wiele w praktyce. Zgoda.

Jednakże są to rzeczy ważne, gdy chce się brać udział w niektórych z najbardziej ekscytujących projektów programistycznych. Przykładowo, bez wskaźników nigdy nie będziesz w stanie pracować nad jądrem Linuksa. Nie zrozumiesz nawet jednego wiersza kodu Linuksa (ani żadnego innego systemu operacyjnego) bez dogłębnego zrozumienia wskaźników.

Bez zrozumienia programowania funkcjonalnego nie wymyślisz MapReduce, algorytmu, który sprawia, że infrastruktura Google jest tak skalowalna. Pojęcia Map i Reduce pochodzą od Lispa i ogólnie od programowania funkcjonalnego. Koncepcja MapReduce, patrząc z perspektywy czasu, powinna być trywialna dla każdego, kto ze studiów pamięta, że programy napisane w czystym języku funkcjonalnym nie mają efektów ubocznych i dzięki temu łatwo da się je zrównoleglić. Sam fakt, że to w Google, a nie w Microsofcie, wynaleziono MapReduce, po części tłumaczy, dlaczego Microsoft wciąż męczy się z implementacją najprostszych funkcjonalności dotyczących wyszukiwania, podczas gdy Google zajął się już kolejnym problemem: budową Skynetu^H^H^H^H^H^H - największego na świecie równoległego superkomputera. Sądzę, że Microsoft nie zdaje sobie sprawy, jak daleko jest w tyle.

Poza dostrzegalnym na pierwszy rzut oka znaczeniem wskaźników i rekurencji, ich prawdziwą wartością jest to, że sama nauka o nich daje Ci pewną elastyczność umysłową, niezbędną, aby budować duże, skomplikowane systemy; Wymagają tej mentalnej postawy, która sprawia, że udaje Ci się uniknąć odsiewu na pierwszym roku studiów. Wskaźniki i rekurencja wymagają umiejętności rozumowania, abstrakcyjnego myślenia oraz, co najważniejsze, spojrzenia na problem na wielu poziomach abstrakcji równocześnie. Tak więc zdolność rozumienia wskaźników i rekurencji jest bezpośrednio skorelowana ze zdolnością bycia ponadprzeciętnym programistą.

Fakt ukończenia Java-Szkoły nie ma w sobie nic, co pozwoliłoby od razu rozpoznać absolwentów, którym brakuje umysłowej zwinności pozwalającej zajmować się tymi koncepcjami. Jako pracodawca zauważyłem, że Java-Szkoły zaczynają produkować wielu absolwentów, którzy nie są na tyle bystrzy, by móc pracować w zawodzie programisty nad czymkolwiek bardziej skomplikowanym niż Kolejna Javowa Aplikacja Dla Księgowości, chociaż udało im się jakoś prześlizgnąć przez ten nowy, mocno uproszczony program studiów. Tym studentom nigdy nie udałoby się przetrwać kursu 6.001 na MIT czy CS 323 na Yale, i szczerze mówiąc, jest to jeden z powodów, dla którego ja, jako pracodawca, znacznie bardziej cenię dyplom z MIT czy Yale niż z Duke, które ostatnio całkowicie przerzuciło się na Javę, czy Penn, gdzie na kursie, który nieomal zabił mnie i moich znajomych (CSE121), języki Scheme i ML zastąpiono Javą. To nie tak, że nie chcę zatrudniać bystrzaków z Duke czy Penn -- chcę -- ale jest mi zdecydowanie trudniej ocenić, którzy to są. Kiedyś mogłem ich odróżnić, ponieważ Ci bystrzy potrafili przeanalizować rekurencyjny algorytm w kilka sekund albo zaimplementować funkcje operujące na listach połączonych tak szybko, jak tylko umieli pisać na tablicy. W przypadku absolwenta Java-Szkoły, nie wiem, czy nie radzi on sobie z tymi problemami dlatego, że jest niedoedukowany, czy też może dlatego, że nie posiada on tej wyjątkowej części mózgu, której potrzebuje, by móc ponadprzeciętnie wykonywać swoją pracę jako programista. Paul Graham nazywa ich Blub Programmers.

Fakt, że Java-Szkoły nie odsiewają tych studentów, którzy nigdy nie będą znakomitymi programistami, jest wystarczająco przygnębiający. Uczelnie mogą powiedzieć, że to nie ich problem. Przemysł, a przynajmniej rekruterzy, będący zwolennikami grepa, wydają się być zadowoleni z tego, że uczy się Javy.

Ale Java-Szkoły odnoszą także porażkę, nie ćwicząc umysłów studentów, by byli oni na tyle biegli, sprawni i elastyczni, by dobrze projektować oprogramowanie (i nie mam tutaj na myśli projektowania obiektowego, gdzie spędzasz niezliczone godziny na przepisywaniu kodu, aby przetasować hierarchię klas albo zamartwiasz się fałszywmi "problemami" w rodzaju has-a vs. is-a). Potrzebujesz treningu w myśleniu na wielu poziomach abstrakcji równocześnie, taki rodzaj treningu jest właśnie tym, co pozwoli Ci tworzyć znakomite architektury oprogramowania.

Być może zastanawiasz się, czy nauka programowania obiektowego (OOP - Object-Oriented Programming) jest w stanie zastąpić wskaźniki i rekurencję pod względem zdolności odsiewowej. Szybka odpowiedź: nie. Nie wdając się zbytnio w szczegóły, programowanie obiektowe nie jest wystarczająco trudne, aby odsiać przeciętnych programistów. Nauka programowania obiektowego w szkołach sprowadza się zazwyczaj do wkuwania pojęć w rodzaju "enkapsulacja" czy "dziedziczenie" i rozwiązywania testów wielokrotnego wyboru na temat różnic pomiędzy polimorfizmem i przeciążaniem. Będąc niewiele bardziej wymagającym niż zapamiętywanie znanych dat i nazwisk na lekcjach historii, programowanie obiektowe nie stanowi adekwatnego wyzwania umysłowego, aby odstraszyć pierwszoroczniaków. Gdy męczysz się z jakimś problemem z dziedziny programowania obiektowego, twój program ciągle działa, może jedynie być trudniejszy w utrzymaniu. Powiedzmy. Ale gdy walczysz ze wskaźnikami, a Twój program powoduje błąd segmentacji, nie masz pojęcia, czym to jest spowodowane, dopóki nie zatrzymasz się, nie weźmiesz głębokiego oddechu i naprawdę nie postarasz się zmusić swojego umysłu do pracy na dwóch różnych poziomach abstrakcji równocześnie.

A tak na marginesie, specjalnie ośmieszam tutaj rekruterów korzystających z grepa. Nie spotkałem nigdy nikogo, kto znałby Scheme, Haskella i C, a kto nie potrafiłby opanować Javy w dwa dni i tworzyć w niej lepszy kod niż ludzie z pięcioletnim doświadczeniem w Javie, ale spróbuj wytłumaczyć to przeciętnemu trutniowi z HR.

Co w takim razie z misją wydziałów informatyki? To nie są zawodówki! Ich celem nie powinno być nauczanie ludzi, jak pracować w przemyśle. To zadanie szkół pomaturalnych albo programów rządowych dla pracowników zmuszonych do przekwalifikowania się. Uczelnie powinny oferować studentom podstawowe narzędzia na całe życie, a nie przygotowywać ich do pracy przez kilka pierwszych tygodni. Prawda?

Informatyka to dowody (rekurencja), algorytmy (rekurencja), języki (rachunek lambda), systemy operacyjne (wskaźniki), kompilatory (rachunek lambda) -- chodzi mi o to, że taka Java-Szkoła, na której nie wykłada się C ani Scheme, tak naprawdę nie uczy również informatyki. Jakkolwiek bezużyteczne w prawdziwym świecie może wydawać się pojęcie rozwijania funkcji (ang. function currying), to jego znajomość powinna być oczywistym wymogiem dla absolwentów informatyki. Nie mogę zrozumieć, dlaczego profesorzy, którzy biorą udział w ustalaniu programu studiów, zgodzili się na takie uproszczenia, które w rezultacie sprawiają, że uczelnie nie są w stanie produkować programistów zdolnych do wykonywania swojego zawodu. Co więcej, nie są nawet w stanie wyprodukować absolwentów, którzy podejmą studia doktoranckie a w przyszłości powalczą o tytuły profesorskie. Chwila. Nieważne. Może jednak rozumiem.

Właściwie to jeśli cofnąć się w czasie i przyjrzeć dyskusjom toczonym w środowiskach akademickich podczas Wielkiego Przewrotu Javowego, można zauważyć, że największym zmartwieniem było to, czy Java jest wystarczająco prostym językiem, aby używać go w celach dydaktycznych.

Mój Boże, pomyślałem, oni chcą pójść jeszcze dalej z tym upraszczaniem programu studiów! Może powinniśmy podawać studentom wszystko na tacy? Niech asystenci zdają za nich egzaminy. Jak ktokolwiek ma się czegoś nauczyć, jeśli program studiów został starannie zaprojektowany w taki sposób, aby uczynić wszystko łatwiejszym niż jest? Zdaje się, że w planach jest nawet utworzenie specjalnej grupy zadaniowej, której celem miałoby być opracowanie podzbioru Javy, którego używano by do nauczania studentów i stworzenie dokumentacji ukrywającej cały ten bajzel EJB/J2EE przed ich wrażliwymi umysłami, dzięki czemu nie musieliby zaprzątać swoich małych główek tymi wszystkim klasami, niepotrzebnymi do rozwiązania i tak coraz łatwiejszych zadań informatycznych.

Najzabawniejszym wytłumaczeniem, dlaczego wydziały informatyki są tak skłonne do upraszczania swoich programów nauczania, jest to, że dzięki temu mają więcej czasu na naukę naprawdę istotnych koncepcji informatycznych, że nie muszą marnować dwóch wykładów na wyjaśnianie studentom różnicy między javowym słowem kluczowym int a klasą Integer. Cóż, jeśli istotnie tak jest, to kurs 6.001 ma dla nich idealną odpowiedź: Scheme, dydaktyczny język tak prosty, że bystrym studentom można wyłożyć go w ciągu 10 minut; potem cały semestr można poświęcić na teorię punktu stałego.

Heh.

Wracam do zer i jedynek.

(Miałeś jedynki? Szczęściarz z ciebie! My mieliśmy tylko zera.)

Data publikacji oryginału: grudzień 29, 2005

Czy wszyscy programiści powinni mieć wielordzeniowe procesory?

Oryginalny post: Should All Developers Have Manycore CPUs?

Autor: Jeff Atwood

Dwurdzeniowe procesory są już dzisiaj standardem, i to z dobrego powodu -- istnieją pokaźne, dające się udowodnić wzrosty wydajności, wynikające z posiadania drugiego procesora, czekającego na zadania, których pierwszy procesor nie może obsłużyć, w momencie, gdy jest zapracowany. Jeśli tak, to dwurdzeniowe procesory chronią Cię przed źle napisanym oprogramowaniem; jeśli zepsuta aplikacja zużywa całą moc procesora, to wszystko co może dostać, to 50% jego mocy. Nadal dostępny jest drugi procesor, który zagwarantuje, że system operacyjny pozwoli Ci ubić CrashyApp 5.80 SP1 Enterprise Edition w rozsądny sposób. To kumpelski układ w krzemowej formie.

Mój poprzedni wpis o modernizowaniu procesora w Twoim komputerze był bardziej kontrowersyjny niż zamierzałem. Oto co napisałem:

Moim zdaniem, czterordzeniowe procesory są nadal marnotrawieniem prądu chyba, że umieścisz je w serwerze. Cztery rdzenie w komputerze są dobre do przechwalania się i do matematycznej wyższości (tak, 4 > 2), ale te cztery rdzenie nie dostarczają mierzalnego wzrostu wydajności w aplikacjach używanych przez większość ludzi. Włączając w to narzędzia do programowania.

Niefortunnie to ująłem, ponieważ powyższe stwierdzenie przyciemniło resztę wpisu. Moim zamierzeniem było zachęcenie ludzi do podejmowania uzasadnionych decyzji podczas wyboru procesora. Doprawdy, wybierz taki procesor jaki chcesz; ważną częścią tego wpisu było pozbycie się obaw przed rozbudową swojego komputera. Na tyle na ile powyższy paragraf rozproszył uwagę czytelników od tego celu -- przepraszam.

Niemniej jednak, mam silne uczucia w tym temacie. Za często widuję użytkowników uwiedzionych przez kampanię reklamową Intela, ślepo zakładając, że jeśli dwa rdzenie procesora są lepsze od jednego rdzenia, to, no.. cztery, osiem, albo szesnaście musi być szalenie szybkie! I opróżniają swoje portfele. Obawiam się, iż wielu użytkowników pada ofiarą marketingowych łasic, płacąc dodatkowo za wydajność, która nigdy się nie urzeczywistni. To tak jak za starych, niedobrych czasów Pentium 4 z tym, że zamiast absurdalnej ilości megaherców, mamy absurdalną liczbę rdzeni procesora.

Chciałbym, aby ludzie zrozumieli, że istnieje tylko garść aplikacji, która potrafi wykorzystać moc więcej niż dwóch rdzeni, i mają one tendencje skupiania się wokół pewnych wyspecjalizowanych dziedzin. Jak dla mnie, chodzi tylko o dane z benchmarków, a one nie wykazują żadnych nieodpartych powodów, aby przejść na cztery rdzienie, o ile regularnie nie zajmujesz się jednym z poniższych:

  • "ripowanie" bądź kodowanie video
  • profesjonalne renderowanie scen 3D
  • uruchamianie naukowych symulacji

Jeśli często robisz jedno z powyższych, niewątpliwie cztery rdzenie (albo osiem) są dobrym wyborem. Ale jest to jedynie moja rekomendacja, bazująca na danych z benchmarków, a nie żelazny fakt. To Twoje pieniądze. Wydaj je jak chcesz. Jedyne co proponuję, to abyś wydał je rozsądnie.

Ach, ale zostaje jeszcze argument wielozadaniowości. Wybłagałem komentatorów, którzy byli pewni korzyści płynących z czterech rdzeni, aby wskazali mi benchamarki wielozadaniowości, które wskazywałyby głęboką różnicę w wydajności pomiędzy dwu a więcej-niż-dwurdzeniowymi procesorami. To ciekawe. Sieć jest zalana zylionem stron z recenzjami sprzętu, ale ciężko jest znaleźć benchmark wielozadaniowości na którejkolwiek z nich. Myślę, że to dlatego, iż liczba zadań wykonywanych równocześnie potrzebna, aby poważnie obciążyć więcej niż dwa rdzenie, leży na granicy absurdu. Jak to wskazał Anand:

Kiedy próbowaliśmy wymyślać nowe benchmarki dla wielozadaniowości, aby poważnie obciążyć platformy Kentsfield oraz Quad FX [czterordzeniowe], ciągle natykaliśmy się na interesujące, ale nierealne scenariusze, które świetnie sprawdzały się przy obciążaniu testowanych urządzeń, ale kiepsko w dawaniu dobrego powodu, dla którego warto byłoby używać czterech rdzeni.

Co możesz znaleźć natomiast to ten oto benchmarkowy refren powtarzany w kółko:

Tak jak większość dzisiejszych aplikacji, WorldBench, łącznie ze swoimi komponentami, nie zyskuje wiele od więcej niż dwóch rdzeni procesora.

Po tym wszytkim myślę, że popełniłem błąd w moim oryginalnym stwierdzeniu. Programiści nie są typowymi użytkownikami. W rzeczy samej, można rozsądnie założyć, że programiści są z definicji specyficznymi użytkownikami i stąd, powinni poszukiwać wielordzeniowych procesorów, tak jak Kevin powiedział w komentarzach:

Jak wyobrażasz sobie, że programiści piszą aplikacje (to jest to kim jesteśmy i co robimy, prawda?), które potrafią wykorzystać 4, 8, itd... procesorów, jeśli wykorzystujemy platformy z jednym bądź dwoma rdzeniami? Pokażę to na przykładzie wielu monitorów. Programiści potrzebują ich nie tylko po to, by zwiększyć swoją produktywność, ale dlatego, że nie zrozumieją jak kiepsko ich aplikacja działa na wielu monitorach, dopóki jej nie użyją w ten sposób. To samo pozostaje prawdą przy wielordzeniowych procesorach.

Mam na to dwie odpowidzi. Jedna za nich prawdopodobnie się Wam nie spodoba.

Zacznijmy od pierwszej. Absolutnie zgadzam się z tym, iż istotnym jest, żeby programiści rozważyli programowanie pod wiele rdzeni, i posiadanie takiej platformy jest dla nich warunkiem zasadniczym. Najpierw napisałem o tym, dawno w 2004 roku, w "Wątki, współbieżność i najbardziej potężny psychokinetyczny ładunek wybuchowy we Wszechświecie". W istocie, dwójka ludzi, których cytowałem w tym starym wpisie -- prawdziwi liderzy w dziedzinie programowania współbieżnego -- przysłali wczoraj bezpośrednie odpowiedzi do tego wpisu, i obaj zasługują na odpowiedź.

Rick Brewster, od naprawdę niesamowitego projektu Paint.NET, odpowiedział:

He? Pewnym jest, że Paint.NET wykazuje spore osiągnięcia dla czterordzeniowych procesorów, w przeciwieństwie do dwurdzeniowych. Jest nawet benchmark. Powiedziałbym, że zalicza się to do "aplikacji, których używa większość ludzi".

On ma absolutną rację. Czterordzeniowy Q6700 @ 2.66 GHz bije mojego dwurdzeniowego E8500 @ 4.0 GHz na tym benchmarku z wynikiem 26 sekund do 31. Ale z całym szacunkiem do Ricka -- i poważnie, jak najbardziej, uwielbiam Paint.NET, a jego wielowątkowy kod jest niesamowity -- czuję, że ten benchmark testuje wyspecjalizowane (i poddające się zrównoleglaniu) filtry aniżeli główną funkcjonalność. Istnieje długa historia benchmarków Photoshopa w podobnym stylu; to przypadek renderowania 3D bez jednego wymiaru. Jeśli spędzasz znaczną część dnia używająć Photoshopa, powinieneś wybrać platformę, która radzi sobie z nim najlepiej.

Ale jesteśmy programistami, nie projektantami. Spędzamy większość czasu rozmawiając z kompilatorami, interpreterami oraz edytorami różnego rodzaju. Herb Sutter poświęcił cały wpis na swoim blogu, wyjaśniając, że w rzeczy samej, narzędzia do programowania wykorzystują czterordzeniowe procesory:

Musisz używać nie tych narzędzi co trzeba. :-) Na przykład, oto trzy, które znam:

  1. Flaga /MP w Visual C++ 2008, informuje kompilator, aby kompilował pliki w tym samym projekcie równolegle.
  2. Od Visual Studio 2005 obsługujemy równoległe kompilowanie projektów w trybie Batch Build.
  3. Excel 2007 robi równoległą rekalkulację. Zakładając, że arkusz kalkulacyjny jest duży i zawiera nie tylko sekwencyjne zależności między komórkami, skaluje się zazwyczaj liniowo do przynajmniej ośmiu rdzeni.

Herb jest ekspertem w dziedzinie programowania równoległego oraz ogólnym guru C++, i oczywiście ma rację we wszystkich trzech punktach. Zupełnie zapomniałem o kompilacji C++, albo raczej, uczciwie powiedziawszy, nie chciałem pamiętać. Czego oczekujecie od gościa wywodzącego się do BASIC'a? Czas kompilacji to olbrzymi cios dla produktywności programistów C++ pracujących na dużych projektach. Czas kompilacji używając gcc oraz time make -j<# of cores + 1> jest dziadkiem wszystkich wielordzeniowych benchmarków programistów. Oto reprezentatywne wyniki kompilowania źródła LAME 3.97:

1 Xeon E5150 (2.66 GHz Dual-Core) 12.06 s
1 Xeon E5320 (1.86 GHz Quad-Core) 11.08 s
2x Xeon E5150 8.26 s
2x Xeon E5320 8.45 s

Może liczby te wydają się małe, ale procenty są niesamowicie ujmujące, szczególnie jeśli zsumujesz sobie ile razy kompilujesz dziennie. Jeśli jesteś programistą C++, potrzebujesz czterordzeniowego procesora od wczoraj. Wymagaj tego.

Ale co z nami, programistami kodu zarządzanego, z naszym brakiem wskaźników i jawnej alokacji pamięci? Herb wspomniał o równoległym kompilowaniu projektów w Visual Studio 2008; jest w menu Tools, Options, Project and Solutions, Build and Run.

Jak obiecano, domyślnie dostosowywuje się do ilości rdzeni jakie posiadam w swoim komputerze -- dwóch. Ściągnałem największy projekt .NET'owy jaki mogłem sobie wyobrazić -- SharpDevelop. Cała solucja jest zadowalająco duża; zawiera 60 projektów. Przekompilowałem to kilka razy w Visual Studio 2008, ale menedżer zadań nie wskazywał dużego obciążenia moich marnych dwóch rdzeni:

Zauważyłem parę szczytów powyżej 50%, ale to jest strasznie średni wynik w porównaniu do make -j4. Nie widzę tu nic, co by wskazywało na polepszenie czasu kompilacji kodu zarządzanego przy przejściu na więcej niż dwa rdzenie. Ciekaw jestem, czy kompilatory Java (albo inne kompilatory języków .NET-opodobnych) radzą sobie lepiej.

Wracając do pytania Kevina: tak, jeśli jesteś programistą, piszącym aplikacje desktopowe, które choć w najmniejszym stopniu mają coś, co da się zrównoleglać, powinieneś mieć taką liczbę rdzeni porcesora w swoim komputerze, jaką potrzebujesz aby testować i debugować swój kod. Proponuję rozpocząć od skalowania do dwóch rdzeni jako, że to wygląda na najbardziej wyzywającą część zadania. Jeśli chcesz więcej, to powodzenia, ponieważ wszytko, co czytałem w temacie pisania skalowalnych, współbieżnych aplikacji, daje z siebie co może, by wytłumaczyć z potwornymi szczegółami, jak piekielnie trudno pisze się kod tego rodzaju.

A oto druga część odpowiedzi, którą obiecałem Wam wcześniej. Ta, której możecie nie polubić. Większość programistów nie pisze aplikacji desktopowych. Piszą aplikacje webowe. Wielu z nich może pisać w językach skryptowych, które nie są kompilowane, lecz interpretowane -- takie jak Ruby, Python czy PHP. Do licha, one nawet nie są wielowątkowe. Pomimo tego, taki kod jakoś osiąga niesamowity poziom współbieżności, skaluje sie do wielkich obciążeń, i dźwiga niektóre z największych serwisów w Internecie. A wszystko to, bez odrobiny myślenia o współbieżności, wątkach, czy wielobieżności. To rodzaj magii, jeśli się o tym pomyśli.

Biorąc pod uwagę to, że siłą rzeczy, podczas tworzenia aplikacji komputery programistów muszą odwzorowywać środowisko serwerowe, powinny one mieć tyle rdzeni, ile jest to możliwe.

Programowanie dla brutalnych psychopatów

Oryginalny post: Coding For Violent Psychopaths

Autor: Jeff Atwood

Dzisiejsze rozmyślanie jest dla ludzi o mocnych nerwach. Pochodzi z czcigodnej strony C2 Wiki -- Code For The Maintainer:

Zawsze programuj tak, jakby osoba, która będzie utrzymywała Twój kod, była okrutnym psychopatą, który wie gdzie mieszkasz.

Być może jest to trochę na wyrost, ale możliwe, że taki wstrząs jest tym, czego potrzebujemy, aby przekazać tę ważną wiadomość naszym kolegom programistom.

Jeśli taktyka zastraszania nie działa, miejmy nadzieję, że jesteś w stanie rozwinąć w sobie wymuszony szacunek do szlachetnej sztuki utrzymywania kodu.

Może nie jest to fascynujące, ale tak wygląda 99% pracy programistycznej na tym świecie.

Related Posts with Thumbnails