Cytat Torvaldsa na temat dobrego programisty [zamknięty]


238

Przypadkowo natknąłem się na następujący cytat Linusa Torvaldsa:

„Źli programiści martwią się o kod. Dobrzy programiści martwią się strukturami danych i ich relacjami”.

Myślałem o tym przez kilka ostatnich dni i nadal jestem zdezorientowany (co prawdopodobnie nie jest dobrym znakiem), dlatego chciałem omówić następujące kwestie:

  • Jaka interpretacja tego jest możliwa / ma sens?
  • Czego można się z tego nauczyć?

18
Myślę, że to pytanie prawdopodobnie ma wiele takich samych odpowiedzi. Ale i tak to dobre pytanie. Uwielbiam ten cytat. Wyjaśnia, dlaczego nie rozumiem programistów, którzy martwią się przełączaniem języków. Rzadko język ma znaczenie w programie, to struktury danych i ich relacje.
Ryan Kinal

5
Może jeśli poświęcisz trochę czasu na uczynienie struktur danych „eleganckimi”, to kod nie musi być zawiły, aby poradzić sobie z tymi strukturami danych? Prawdopodobnie jestem zbyt głupi, aby naprawdę poznać znaczenie cytatu Torvaldsa. :}
programista

3
@RyanKinal Ale język oczywiście ma znaczenie , ponieważ znacznie ułatwia radzenie sobie z pewnymi strukturami danych i myślenie o nich. Pomyśl na przykład o wszystkich językach, które specjalizują się w analizie LISt, lub językach, które mają natywną obsługę struktur danych, które muszą być zhakowane do innych języków (przychodzą mi na myśl zestawy i rzadkie tablice).
kojiro

83
Nawiasem mówiąc, Torvalds nie jest sam: „Pokaż mi swój schemat blokowy i ukryj swoje stoły, a ja nadal będę mistyfikowany. Pokaż mi swoje stoły, a zwykle nie będę potrzebować twojego schematu blokowego; to będzie oczywiste. „ - Fred Brooks, The Mythical Man-Month. „Pokaż mi swój kod i ukryj swoje struktury danych, a ja nadal będę mistyfikowany. Pokaż mi swoje struktury danych i zwykle nie będę potrzebował twojego kodu; to będzie oczywiste”. oraz „Inteligentne struktury danych i głupi kod działają znacznie lepiej niż na odwrót”. - Eric S. Raymond, The Cathedral and The Bazaar.
Jörg W Mittag

4
To wyjaśnia, dlaczego jądro Linuksa to bałagan :)
l1x

Odpowiedzi:


326

Warto zastanowić się nad tym, co powiedział Torvalds:

git ma prostą konstrukcję, ze stabilnymi i dość dobrze udokumentowanymi strukturami danych. W rzeczywistości jestem wielkim zwolennikiem projektowania kodu wokół danych, a nie na odwrót, i myślę, że jest to jeden z powodów, dla których git odnosi sukcesy […] W rzeczywistości twierdzę, że różnica pomiędzy złym programistą a dobrym jest to, czy uważa, że ​​jego kod lub struktury danych są ważniejsze.

Mówi on, że dobre struktury danych sprawiają, że kod jest bardzo łatwy do zaprojektowania i utrzymania, podczas gdy najlepszy kod nie może nadrobić złych struktur danych.

Jeśli zastanawiasz się nad przykładem git, wiele systemów kontroli wersji stosunkowo regularnie zmienia format danych w celu obsługi nowych funkcji. Po uaktualnieniu, aby uzyskać nową funkcję, często musisz uruchomić jakieś narzędzie do konwersji bazy danych.

Na przykład, kiedy DVCS stał się popularny, wiele osób nie było w stanie dowiedzieć się, co w modelu rozproszonym sprawiło, że scalenia były o wiele czystsze niż scentralizowana kontrola wersji. Odpowiedź jest absolutnie niczym, poza tym, że rozproszone struktury danych musiały być znacznie lepsze, aby mieć nadzieję na pracę w ogóle. Uważam, że od tego czasu nadrobiły to scentralizowane algorytmy scalania, ale zajęło to dość dużo czasu, ponieważ ich stare struktury danych ograniczały rodzaje algorytmów, których mogliby użyć, a nowe struktury danych złamały wiele istniejących kodów.

Natomiast pomimo eksplozji funkcji w git, podstawowe struktury danych prawie się nie zmieniły. Martw się najpierw o struktury danych, a Twój kod będzie naturalnie czystszy.


25
najlepszy kod nie może zrekompensować złych struktur danych. Dobry sos to prawda
Conrad Frix

5
Mówi z punktu widzenia programistów dokonujących zmian w samym git. Punkt widzenia użytkownika końcowego jest całkowicie ortogonalny w tej dyskusji, poza łatwym w utrzymaniu kodem, który zapewnia mniej błędów i szybsze dodawanie funkcji.
Karl Bielefeldt,

2
@James: Mówi, że oprogramowanie jest lepsze (stąd łatwiejsze w użyciu i używane przez większą liczbę osób), ponieważ struktury danych są lepsze. Oczywiście nie musisz wiedzieć o strukturach danych, z których korzystasz, ale dbasz o nie pośrednio, nawet jeśli nie zdajesz sobie z tego sprawy, ponieważ struktury danych są motorem rzeczy, które realizujesz troszczyć się o.
ruakh

1
+1. Ta odpowiedź nadaje kontekst stwierdzeniu, które w innym przypadku mogłoby być interpretowane jako coś zupełnie innego. Każdy, kto przeczytał potworność 5000 linii pliku, wie dokładnie, co mam na myśli.
riwalk

20
„Martw się najpierw o struktury danych, a Twój kod będzie naturalnie czystszy.”: Rzymski mąż stanu Cato ( en.wikipedia.org/wiki/Cato_the_Elder ) zwykł mówić „Rem tene, verba sequentur” = „Wyraźny argument w w twoim umyśle słowa pojawią się naturalnie ”. To samo dotyczy programowania: najpierw zrozum struktury danych i projekt, a sam kod sam się pojawi.
Giorgio

60

Algorytmy + struktury danych = programy

Kod to tylko sposób na wyrażenie algorytmów i struktur danych.



Dotyczy to programowania proceduralnego; w OOP jest trochę inny.
m3th0dman

3
Zasadniczo nie jest inaczej. Masz dane i wykonujesz na nich zestaw operacji. Zmienne i metody składowe. Dokładnie to samo. Cała esencja obliczeń od lat 50. opiera się na tej bardzo prostej zasadzie, że programy składają się z algorytmów modyfikujących struktury danych, i zachowuje prawdziwość 60 lat później. Można również traktować programy jako funkcje . Pobierają dane wejściowe, na których działają, w celu uzyskania produkcji . Dokładnie tak, jak pełnią funkcje matematyczne.
zxcdw 24.09.12

31

Ten cytat dobrze zna jedną z zasad zawartych w „The Art of Unix Programming”, która jest mocną stroną Torvaldsa jako twórcy Linuksa. Książka znajduje się tutaj online

Z książki pochodzi następujący cytat, który wyjaśnia, co mówi Torvalds.

Reguła reprezentacji: Podziel wiedzę na dane, aby logika programu była głupia i niezawodna.

Nawet najprostsza logika proceduralna jest trudna do zweryfikowania przez ludzi, ale dość skomplikowane struktury danych są dość łatwe do modelowania i uzasadnienia. Aby to zobaczyć, porównaj ekspresyjność i moc wyjaśniającą diagramu (powiedzmy) drzewa wskaźników pięćdziesięciu węzłów ze schematem blokowym programu pięćdziesięciu linii. Lub porównaj inicjalizator tablicy wyrażający tablicę konwersji z równoważną instrukcją switch. Różnica w przejrzystości i jasności jest dramatyczna. Zobacz zasadę 5 Roba Pike'a.

Dane są bardziej podatne na przetwarzanie niż logika programu. Wynika z tego, że tam, gdzie widzisz wybór między złożonością struktur danych a złożonością kodu, wybierz to pierwsze. Więcej: rozwijając projekt, powinieneś aktywnie poszukiwać sposobów na przeniesienie złożoności z kodu na dane.

Społeczność uniksowa nie zapoczątkowała tego wglądu, ale wiele kodów uniksowych wykazuje jej wpływ. Zwłaszcza funkcja języka C do manipulowania wskaźnikami zachęca do korzystania z dynamicznie modyfikowanych struktur referencyjnych na wszystkich poziomach kodowania od jądra w górę. Proste pościgi wskaźnikowe w takich strukturach często wykonują obowiązki, które implementacje w innych językach musiałyby zamiast tego zawierać bardziej skomplikowane procedury.


Też to zapamiętałem!
Jesvin Jose

1
OTOH, spójrz na dowolne pytanie StackOverflow int**. To powinno cię przekonać, że dane w rzeczywistości NIE są oczywiste; staje się tak tylko poprzez nadanie znaczenia danym. I to znaczenie jest w kodzie.
MSalters

29

Kod jest łatwy, jego logika jest złożona.

Jeśli martwisz się kodem, oznacza to, że nie znasz jeszcze podstaw i prawdopodobnie straciłeś kompleks (tzn. Struktury danych i ich relacje).


17
Heh, zastanawiam się, czy następne pokolenie programistów zapyta: „Morons kiedyś powiedział Code is easy, it's the logic behind the code that is complex, co miał na myśli?”
yannis

36
@YannisRizos Będzie to szczególnie mylące, gdy ludzie nie będą pewni, czy powiedzieli to ludzie, którzy byli kretynami, czy pojedyncza osoba o imieniu Morons.
KChaloux,

14

Aby nieco rozwinąć odpowiedź Moronsa , chodzi o to, że zrozumienie szczegółów kodu (składnia oraz, w mniejszym stopniu, struktura / układ) jest na tyle łatwe, że budujemy narzędzia, które mogą to zrobić. Kompilatory mogą zrozumieć wszystko, co należy wiedzieć o kodzie, aby przekształcić go w działający program / bibliotekę. Ale kompilator nie jest w stanie rozwiązać problemów, które robią programiści.

Możesz pójść o krok dalej i powiedzieć „ale mamy programy, które generują kod”, ale generowany przez niego kod jest oparty na pewnego rodzaju danych wejściowych, które prawie zawsze są ręcznie konstruowane.

Niezależnie od tego, jaką drogą wybierzesz się do kodu: czy to przez jakąś konfigurację lub inne dane wejściowe, które następnie wytwarzają kod za pomocą narzędzia lub jeśli piszesz go od zera, nie jest to kod, który ma znaczenie. Ważne jest krytyczne myślenie o wszystkich elementach wymaganych do uzyskania dostępu do tego kodu. W świecie Linusa, który jest w dużej mierze strukturami danych i relacjami, choć w innych domenach mogą to być inne elementy. Ale w tym kontekście Linus mówi po prostu: „Nie obchodzi mnie, czy umiesz pisać kod, zależy mi, abyś zrozumiał rzeczy, które rozwiążą problemy, z którymi mam do czynienia”.


Każdy programista używa programów generujących kod. Często nazywane są „kompilatorami”, czasem w połączeniu z „linkerami”. Biorą (względnie) czytelny dla człowieka i zapisywalny przez ludzi tekst, który zwykle (ale nie zawsze) jest dostarczany w jakimś formacie tekstowym, i przekształcają go w dane, które komputer może zrozumieć jako instrukcje i wykonać.
CVn

13

Linus oznacza to:

Pokaż mi swoje schematy blokowe [kod] i ukryj swoje tabele [schemat], a będę nadal mistyfikowany; pokaż mi swoje tabele [schemat], a zwykle nie potrzebuję twoich schematów blokowych [kod]: będą oczywiste.

- Fred Brooks, „The Mythical Man Month”, rozdz. 9.


12

Myślę, że mówi, że ogólny projekt wysokiego poziomu (struktury danych i ich relacje) jest znacznie ważniejszy niż szczegóły implementacji (kod). Myślę, że ceni programistów, którzy potrafią zaprojektować system, niż tych, którzy mogą skupić się tylko na jego szczegółach.

Oba są ważne, ale zgodziłbym się, że ogólnie lepiej jest uzyskać duży obraz i mieć problemy ze szczegółami niż na odwrót. Jest to ściśle związane z tym, co próbowałem wyrazić na temat podziału dużych funkcji na małe .


+1: Zgadzam się z tobą. Innym aspektem jest to, że często programiści bardziej martwią się tym, jakiej fajnej funkcji języka będą używać, zamiast skupiać się na swoich strukturach danych i algorytmach oraz na tym, jak zapisać je w prosty, jasny sposób.
Giorgio

Również się zgadzam. Faktem jest, że łatwo jest zmieniać izolowane fragmenty kodu, ale trudniej jest zmieniać struktury danych lub interfejsy między fragmentami kodu (ponieważ tego rodzaju zmiany mogą wpływać na wiele rzeczy, a nie tylko na jedno).
Brendan,

5

Cóż, nie mogę się całkowicie zgodzić, bo musisz się o to martwić. W tym przypadku jedną z rzeczy, które uwielbiam w programowaniu, są przełączanie się między różnymi poziomami abstrakcji i wielkości, które szybko przechodzą od myślenia o nanosekundach do myślenia o miesiącach iz powrotem.

Jednak wyższe rzeczy są ważniejsze.

Jeśli mam wadę w kilku liniach problemów, które powodują nieprawidłowe zachowanie, prawdopodobnie nie jest to zbyt trudne do naprawienia. Jeśli powoduje to słabą wydajność, prawdopodobnie nawet nie ma to znaczenia.

Jeśli mam wadę w wyborze struktury danych w podsystemie, co powoduje nieprawidłowe zachowanie, jest to o wiele większy problem i trudniej go naprawić. Jeśli powoduje to słabą wydajność, może być dość poważne lub, jeśli to możliwe, wciąż znacznie mniej dobre niż podejście konkurencyjne.

Jeśli mam wadę w relacji między najważniejszymi strukturami danych w aplikacji, co powoduje nieprawidłowe zachowanie, to przede wszystkim mam poważne zmiany w projekcie. Jeśli powoduje to jego słabe działanie, może być tak źle, że byłoby prawie lepiej, gdyby zachowywał się źle.

I to właśnie sprawia, że ​​znalezienie problemów na niższym poziomie jest trudne (naprawianie błędów na niskim poziomie jest zwykle łatwe, znalezienie ich może być trudne).

Rzeczy niskiego poziomu ważne, a ich pozostałe znaczenie jest często poważnie zaniżone, ale blednie w porównaniu do dużych rzeczy.


2

Ktoś, kto zna kod, widzi „drzewa”. Ale ktoś, kto rozumie struktury danych, widzi „las”. Dlatego dobry programista skoncentruje się bardziej na strukturach danych niż na kodzie.


2
Ale skupianie się na lesie lub na drzewach, z wyłączeniem innych, może być szkodliwe, więc nie sądzę, aby ta analogia pasowała.
kojiro

1
@kojiro: W wyrażeniu nie widać lasu dla drzew , zakłada się, że ktoś, kto zobaczy las, również zobaczy drzewa (patrz: en.wiktionary.org/wiki/see_the_forest_for_the_trees ). Dlatego uważam, że jest to dobra analogia.
Treb

2

Ważna jest znajomość przepływu danych. Znajomość przepływu wymaga zaprojektowania dobrych struktur danych.

Jeśli cofniesz się o dwadzieścia lat, był to jeden z głównych argumentów za podejściem zorientowanym obiektowo za pomocą SmallTalk, C ++ lub Java. Duży skok - przynajmniej w C ++, ponieważ tego właśnie się nauczyłem - najpierw zaprojektowałem klasę i metody, a potem wszystko inne się ułoży.

Linus niewątpliwie mówił w szerszym znaczeniu, ale źle zaprojektowane struktury danych często wymagają dodatkowej przeróbki kodu, co może również prowadzić do innych problemów.


2

Czego można się z tego nauczyć?

Jeśli mogę, moje doświadczenie z ostatnich kilku tygodni. Poprzednie dyskusje wyjaśniły odpowiedź na moje pytanie: „czego się nauczyłem?”

Przepisałem trochę kodu i zastanawiając się nad wynikami, które ciągle widziałem, i mówiąc „struktura, struktura ...”, to jest tak ogromna różnica. Teraz widzę, że to właśnie struktura danych zrobiła różnicę. I mam na myśli wszystko .

  • Po przetestowaniu mojej oryginalnej dostawy analityk biznesowy powiedział mi, że nie działa. Powiedzieliśmy „dodaj 30 dni”, ale mieliśmy na myśli „dodaj miesiąc” ( dzień w wynikowej dacie nie zmienia się). Dodaj osobne lata, miesiące, dni; na przykład nie 540 dni przez 18 miesięcy.

  • Poprawka: w strukturze danych zastąpiono jedną liczbą całkowitą klasą zawierającą wiele liczb całkowitych, zmiana w jej konstrukcji była ograniczona do jednej metody. Zmień rzeczywistą instrukcję arytmetyczną daty - wszystkie 2 z nich.

Wypłata

  • Nowa implementacja miała większą funkcjonalność, ale kod algorytmu był krótszy i wyraźnie prostszy.

W Naprawianie zachowania / wyników kodu:

  • Zmieniłem strukturę danych, a nie algorytm.
  • Nigdzie w kodzie nie dotknięto żadnej logiki sterowania.
  • Żadne API nie zostało zmienione.
  • Klasa fabryki struktury danych w ogóle się nie zmieniła.

1

Lubię wyobrażać sobie bardzo sprytny zespół bibliotekarzy w pięknie wykonanej bibliotece z milionem przypadkowych i genialnych książek, to byłaby głupota.


1

Nie mogę się bardziej zgodzić z Linusem. Skoncentrowanie się na danych pomaga znacznie uprościć proste i elastyczne rozwiązanie danego problemu. Sam Git jest tego przykładem - dzięki tak wielu funkcjom obsługiwanym w latach rozwoju podstawowa struktura danych w dużej mierze pozostaje niezmieniona. To magia! --2c


0

Widziałem, że jest to wiele obszarów.

Pomyśl o analizie biznesowej ... Powiedzmy, że analizujesz najlepszy sposób wspierania marketingu w firmie produkującej produkty konsumpcyjne, takiej jak Colgate. Jeśli zaczniesz od fantazyjnych okien lub najnowszych technologii, nie pomożesz firmie tak bardzo, jakbyś najpierw przemyślał jej potrzeby w zakresie danych, a potem martwisz się prezentacją. Model danych przewyższa oprogramowanie do prezentacji.

Rozważ zrobienie strony internetowej. O wiele lepiej najpierw pomyśleć o tym, co chcesz pokazać (HTML), a potem martwić się stylem (CSS) i skryptami (wybierz narzędzie).

To nie znaczy, że kodowanie też nie jest ważne. Potrzebujesz umiejętności programowania, aby w końcu zdobyć to, czego potrzebujesz. Chodzi o to, że dane są podstawą. Zły model danych odzwierciedla zbyt skomplikowany lub nierozważny model biznesowy.


0

Piszę nowe funkcje i aktualizuję istniejące znacznie częściej niż dodawanie nowych kolumn lub tabel do schematu bazy danych. Prawdopodobnie dotyczy to wszystkich dobrze zaprojektowanych systemów. Jeśli musisz zmieniać schemat za każdym razem, gdy musisz zmienić kod, jest to wyraźny znak, że jesteś bardzo złym programistą.

wskaźnik jakości kodu = [zmiany kodu] / [zmiany schematu bazy danych]

„Pokaż mi swoje schematy blokowe i ukryj swoje tabele, a ja nadal będę mistyfikowany. Pokaż mi swoje tabele, a zazwyczaj nie będę potrzebować twoich schematów blokowych; będą oczywiste”. (Fred Brooks)


-2

Wygląda na to, że ten pomysł ma różne interpretacje w różnych rodzajach programowania. Dotyczy to rozwoju systemów, a także rozwoju przedsiębiorstw. Na przykład można argumentować, że gwałtowne przesunięcie uwagi na domenę w projektowaniu opartym na domenie przypomina skupienie się na strukturach danych i relacjach.


-4

Oto moja interpretacja tego: używasz kodu do tworzenia struktur danych, więc należy skupić się na tym drugim. To jak budowanie mostu - powinieneś zacząć projektować solidną konstrukcję, a nie taką, która wygląda atrakcyjnie. Tak się składa, że ​​dobrze napisane struktury danych i mosty wyglądają dobrze dzięki wydajnym projektom.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.