Citazione di Torvalds sul buon programmatore [chiuso]


238

Per inciso, mi sono imbattuto nella seguente citazione di Linus Torvalds:

"I cattivi programmatori si preoccupano del codice. I buoni programmatori si preoccupano delle strutture di dati e delle loro relazioni."

Ci ho pensato negli ultimi giorni e sono ancora confuso (che probabilmente non è un buon segno), quindi ho voluto discutere di quanto segue:

  • Quale interpretazione di questo possibile / ha senso?
  • Cosa può essere applicato / imparato da esso?

18
Penso che questa domanda abbia probabilmente più risposte ugualmente valide. Ma è comunque una buona domanda. Adoro quella citazione. Esprime il motivo per cui non capisco i programmatori che si preoccupano di cambiare lingua. Raramente è la lingua che conta in un programma, sono le strutture di dati e il modo in cui si relazionano.
Ryan Kinal,

5
Forse se prendi il tempo di rendere "eleganti" le strutture dati, allora il codice non deve essere contorto per gestire queste strutture dati? Probabilmente sono troppo stupido per conoscere davvero il significato della citazione di Torvalds. :}
programmatore

3
@RyanKinal Ma ovviamente la lingua è importante , perché semplifica notevolmente la gestione e la riflessione su determinate strutture di dati. Pensa a tutte le lingue specializzate in LISt Parsing, ad esempio, o alle lingue che hanno il supporto nativo per le strutture di dati che devono essere hackerate in altre lingue (vengono in mente set e array sparsi).
Kojiro,

83
Torvalds non è solo in questo, a proposito: "Mostrami il tuo diagramma di flusso e nascondi i tuoi tavoli, e io continuerò ad essere sconcertato. Mostrami i tuoi tavoli e di solito non avrò bisogno del tuo diagramma di flusso; sarà ovvio. " - Fred Brooks, The Mythical Man-Month. "Mostrami il tuo codice e nascondi le tue strutture di dati, e io continuerò a essere sconcertato. Mostrami le tue strutture di dati e di solito non avrò bisogno del tuo codice; sarà ovvio." e "Le strutture di dati intelligenti e il codice stupido funzionano molto meglio del contrario." - Eric S. Raymond, The Cathedral e The Bazaar.
Jörg W Mittag

4
Questo spiega perché il kernel Linux è un disastro :)
l1x

Risposte:


326

Potrebbe essere utile considerare ciò che Torvalds ha detto prima:

git ha in realtà un design semplice, con strutture dati stabili e ragionevolmente ben documentate. In effetti, sono un grande sostenitore della progettazione del codice in base ai dati, piuttosto che viceversa, e penso che sia uno dei motivi per cui Git ha avuto un discreto successo [...] In effetti, affermerò che la differenza tra un cattivo programmatore e uno buono è se considera il suo codice o le sue strutture di dati più importanti.

Quello che sta dicendo è che le buone strutture di dati rendono il codice molto facile da progettare e mantenere, mentre il codice migliore non può compensare le strutture di dati scadenti.

Se ti stai chiedendo l'esempio di git, molti sistemi di controllo della versione cambiano il loro formato di dati in modo relativamente regolare al fine di supportare nuove funzionalità. Quando si aggiorna per ottenere la nuova funzionalità, spesso è necessario eseguire una sorta di strumento per convertire anche il database.

Ad esempio, quando DVCS è diventato popolare per la prima volta, molte persone non sono riuscite a capire che cosa il modello distribuito ha reso le fusioni molto più pulite del controllo centralizzato della versione. La risposta è assolutamente nulla, tranne che le strutture di dati distribuite dovevano essere molto migliori per avere una speranza di lavorare a tutti. Credo che da allora gli algoritmi di unione centralizzata abbiano raggiunto, ma ci è voluto molto tempo perché le loro vecchie strutture dati limitavano il tipo di algoritmi che potevano usare e le nuove strutture dati rompevano molto codice esistente.

Al contrario, nonostante un'esplosione di funzionalità in git, le sue strutture di dati sottostanti sono appena cambiate. Preoccupati prima delle strutture di dati e il tuo codice sarà naturalmente più pulito.


25
il codice migliore non può compensare le scarse strutture di dati. Un buon sugo è quello vero
Conrad Frix

5
Parla dal punto di vista dei programmatori che apportano modifiche a Git stesso. Il punto di vista dell'utente finale è completamente ortogonale a questa discussione, oltre al codice facilmente gestibile che crea meno bug e aggiunte di funzionalità più veloci.
Karl Bielefeldt,

2
@James: Sta dicendo che il software è migliore (quindi più facile da usare e utilizzato da più persone) perché le strutture di dati sono migliori. Ovviamente non hai bisogno di conoscere le strutture dati del software che usi, ma ti importa di loro, indirettamente, anche se non te ne rendi conto, perché le strutture dati sono ciò che guida le cose che realizzi preoccupati.
Ruakh,

1
+1. Questa risposta pone il contesto su un'affermazione che potrebbe altrimenti essere interpretata come qualcosa di molto diverso. Chiunque abbia letto una mostruosità di 5000 righe di un file sa esattamente cosa intendo.
riwalk

20
"Preoccupati prima delle strutture dei dati e il tuo codice sarà naturalmente più pulito.": Lo statista romano Catone ( en.wikipedia.org/wiki/Cato_the_Elder ) era solito dire "Rem tene, verba sequentur" = "Spiega l'argomento in la tua mente, le parole seguiranno naturalmente ". Stessa cosa con la programmazione: capire prima le strutture dati e progettare, il codice effettivo seguirà da solo.
Giorgio,

60

Algoritmi + Strutture dati = Programmi

Il codice è solo il modo di esprimere gli algoritmi e le strutture di dati.



Questo è vero per la programmazione procedurale; in OOP è un po 'diverso.
m3th0dman,

3
Non è fondamentalmente alcun diverso. Hai dei dati e fai una serie di operazioni su di essi. Variabili e metodi dei membri. Esattamente la stessa cosa. L'intera essenza dell'informatica sin dagli anni '50 è stata costruita su quella regola molto semplice secondo la quale i programmi consistono in algoritmi che modificano le strutture di dati e continua a essere valida 60 anni dopo. Potresti anche considerare i programmi come funzioni . Prendono input su cui operano per produrre output . Esattamente come fanno le funzioni matematiche.
zxcdw,

31

Questa citazione è molto familiare a una delle regole di "The Art of Unix Programming", secondo cui il forte di Torvalds è il creatore di Linux. Il libro si trova online qui

Dal libro è la seguente citazione che spiega ciò che Torvalds sta dicendo.

Regola di rappresentazione: piega la conoscenza nei dati in modo che la logica del programma possa essere stupida e solida.

Anche la logica procedurale più semplice è difficile da verificare per gli esseri umani, ma le strutture di dati piuttosto complesse sono abbastanza facili da modellare e ragionare. Per vedere questo, confronta l'espressività e la potenza esplicativa di un diagramma di (diciamo) un albero puntatore a cinquanta nodi con un diagramma di flusso di un programma a cinquanta righe. In alternativa, confrontare un inizializzatore di array che esprime una tabella di conversione con un'istruzione switch equivalente. La differenza di trasparenza e chiarezza è drammatica. Vedi la regola 5 di Rob Pike.

I dati sono più tracciabili della logica del programma. Ne consegue che dove vedi una scelta tra complessità nelle strutture dati e complessità nel codice, scegli la prima. Altro: nell'evoluzione di un progetto, dovresti cercare attivamente modi per spostare la complessità dal codice ai dati.

La comunità Unix non ha originato questa intuizione, ma molto codice Unix mostra la sua influenza. La facilità del linguaggio C di manipolare i puntatori, in particolare, ha incoraggiato l'uso di strutture di riferimento modificate dinamicamente a tutti i livelli di codifica dal kernel verso l'alto. Inseguimenti puntatori semplici in tali strutture spesso svolgono compiti che le implementazioni in altre lingue dovrebbero invece incorporare in procedure più elaborate.


Anche questo me lo ricordavo!
Jesvin Jose,

1
OTOH, guarda qualsiasi domanda su StackOverflow int**. Ciò dovrebbe convincerti che i dati NON sono in realtà ovvi; diventa così solo attribuendo significato ai dati. E quel significato è nel codice.
MSalters,

29

Il codice è facile, è la logica dietro il codice che è complessa.

Se ti preoccupi del codice, ciò significa che non hai ancora queste nozioni di base e probabilmente ti perdi nel complesso (ovvero le strutture di dati e le loro relazioni).


17
Heh, mi chiedo se la prossima generazione di programmatori chiederà: "Una volta Morons ha detto Code is easy, it's the logic behind the code that is complex, cosa voleva dire?"
yannis,

36
@YannisRizos Ciò sarà particolarmente confuso quando le persone non sono sicure se è stato detto da persone che erano idioti, o da una sola persona di nome Moroni.
KChaloux,

14

Per espandere un po 'la risposta di Morons , l'idea è che comprendere i dettagli del codice (sintassi e, in misura minore, struttura / layout) sia abbastanza facile da creare strumenti in grado di farlo. I compilatori possono comprendere tutto ciò che deve essere conosciuto sul codice per trasformarlo in un programma / libreria funzionante. Ma un compilatore non può effettivamente risolvere i problemi che i programmatori fanno.

Potresti portare l'argomento un ulteriore passo avanti e dire "ma abbiamo programmi che generano codice", ma il codice che genera si basa su una sorta di input che è quasi sempre costruito a mano.

Quindi, qualunque sia la strada che segui per arrivare al codice: che si tratti di una sorta di configurazione o di un altro input che quindi produce codice tramite uno strumento o se lo stai scrivendo da zero, non è il codice che conta. È il pensiero critico di tutti i pezzi necessari per arrivare a quel codice che conta. Nel mondo di Linus ci sono in gran parte strutture di dati e relazioni, anche se in altri settori potrebbero essere altri pezzi. Ma in questo contesto, Linus sta solo dicendo "Non mi interessa se riesci a scrivere codice, mi importa che tu possa capire le cose che risolveranno i problemi con cui ho a che fare".


Ogni programmatore utilizza programmi che generano codice. Sono spesso chiamati "compilatori", a volte in combinazione con "linker". Prendono un input (relativamente) leggibile e scrivibile dall'uomo, che di solito (ma non sempre) viene fornito in una sorta di formato di testo, e lo trasformano in dati che il computer può comprendere come istruzioni ed eseguire.
un CVn il

13

Linus significa questo:

Mostrami i tuoi diagrammi di flusso [codice] e nascondi le tue tabelle [schema], e continuerò a essere sconcertato; mostrami i tuoi tavoli [schema] e di solito non avrò bisogno dei tuoi diagrammi di flusso [codice]: saranno ovvi.

- Fred Brooks, "The Mythical Man Month", cap 9.


12

Penso che stia dicendo che il design generale di alto livello (strutture di dati e le loro relazioni) è molto più importante dei dettagli di implementazione (codice). Penso che apprezzi i programmatori che possono progettare un sistema rispetto a quelli che possono concentrarsi solo sui dettagli di un sistema.

Entrambi sono importanti, ma concordo sul fatto che in genere è molto meglio ottenere il quadro generale e avere problemi con i dettagli rispetto al contrario. Questo è strettamente correlato a ciò che stavo cercando di esprimere sulla suddivisione di grandi funzioni in piccole .


+1: sono d'accordo con te. Un altro aspetto è che spesso i programmatori sono più preoccupati per quale funzione linguistica interessante useranno, invece di concentrarsi sulle loro strutture di dati e algoritmi e su come scriverli in modo semplice e chiaro.
Giorgio,

Sono anche d'accordo. Il fatto è che è facile cambiare pezzi di codice isolati, ma è più difficile cambiare le strutture di dati o le interfacce tra pezzi di codice (poiché questi tipi di modifiche possono influenzare molte cose anziché solo una cosa).
Brendan,

5

Bene, non posso essere completamente d'accordo, perché devi preoccuparti di tutto. E del resto, una delle cose che amo della programmazione sono i passaggi attraverso diversi livelli di astrazione e dimensioni che passano rapidamente dal pensare ai nanosecondi al pensare ai mesi e viceversa.

Tuttavia, le cose più alte sono più importanti.

Se ho un difetto in un paio di righe di problemi che causano comportamenti errati, probabilmente non è troppo difficile da risolvere. Se sta causando un rendimento inferiore, probabilmente non ha nemmeno importanza.

Se ho un difetto nella scelta della struttura dei dati in un sottosistema, ciò causa un comportamento errato, è un problema molto più grande e più difficile da risolvere. Se sta causando una performance insufficiente, potrebbe essere abbastanza grave o sopportabile, ancora sensibilmente meno buono di un approccio rivale.

Se ho un difetto nella relazione tra le più importanti strutture di dati in un'applicazione, ciò causa un comportamento errato, ho una riprogettazione enorme di fronte a me. Se sta causando un rendimento inferiore, potrebbe essere così male che sarebbe quasi meglio se si stesse comportando in modo sbagliato.

E sarà ciò che rende difficile trovare quei problemi di livello inferiore (correggere i bug di basso livello è normalmente facile, è trovarli che possono essere difficili).

La roba di basso livello è importante e la sua importanza rimanente è spesso seriamente sottovalutata, ma impallidisce rispetto alla roba grande.


2

Qualcuno che conosce il codice vede gli "alberi". Ma qualcuno che capisce le strutture di dati vede la "foresta". Pertanto un buon programmatore si concentrerà più sulle strutture di dati che sul codice.


2
Ma concentrarsi sulla foresta o sugli alberi ad esclusione dell'altro può essere dannoso, quindi non credo che questa analogia si adatti.
Kojiro,

1
@kojiro: nell'espressione non si vede la foresta per gli alberi , si presume che qualcuno che può vedere la foresta vedrà anche gli alberi (vedi en.wiktionary.org/wiki/see_the_forest_for_the_trees ). Quindi penso che sia una buona analogia qui.
Treb

2

Sapere come scorreranno i dati è molto importante. Conoscere il flusso richiede la progettazione di buone strutture di dati.

Se torni indietro di vent'anni, questo è stato uno dei maggiori punti di forza dell'approccio orientato agli oggetti usando SmallTalk, C ++ o Java. Il grande passo - almeno con C ++ perché è quello che ho imparato prima - era progettare la classe e i metodi, e poi tutto il resto sarebbe andato a posto.

Linus indubbiamente parlava in termini più ampi, ma le strutture di dati mal progettate spesso richiedono una rilavorazione aggiuntiva del codice, che può anche portare ad altri problemi.


2

Cosa può essere applicato / imparato da esso?

Se posso, la mia esperienza nelle ultime settimane. Le discussioni precedenti hanno chiarito la risposta alla mia domanda: "che cosa ho imparato?"

Ho riscritto un po 'di codice e riflettendo sui risultati che continuavo a vedere e dire "struttura, struttura ..." è il motivo per cui c'era una differenza così drammatica. Ora vedo che è stata la struttura dei dati a fare la differenza. E intendo tutto .

  • Dopo aver testato la mia consegna originale, l'analista aziendale mi ha detto che non funzionava. Abbiamo detto "aggiungi 30 giorni" ma intendevamo "aggiungere un mese" (il giorno nella data risultante non cambia). Aggiungi anni, mesi, giorni discreti; non 540 giorni per 18 mesi per esempio.

  • La correzione: nella struttura dei dati sostituire un singolo intero con una classe contenente più numeri interi, la modifica alla sua costruzione era limitata a un metodo. Modifica le dichiarazioni aritmetiche della data effettiva, tutte e 2.

The Payoff

  • La nuova implementazione aveva più funzionalità ma il codice dell'algoritmo era più breve e chiaramente più semplice.

In Correzione del comportamento / risultati del codice:

  • Ho cambiato la struttura dei dati, non l'algoritmo.
  • Nessuna logica di controllo è stata toccata in nessun punto del codice.
  • Nessuna API è stata modificata.
  • La classe di fabbrica della struttura dati non è cambiata affatto.

1

Mi piace immaginare una squadra di bibliotecari molto intelligente in una biblioteca ben fatta con un milione di libri casuali e brillanti, sarebbe una vera follia.


1

Non posso essere più d'accordo con Linus. Concentrarsi sui dati aiuta a distillare notevolmente una soluzione semplice e flessibile a un determinato problema. Git stesso è un esempio lampante: fornendo così tante funzionalità supportate negli anni di sviluppo, la struttura dei dati principali rimane sostanzialmente invariata. Questa è magia! --2c


0

Ho visto che questo è numerose aree.

Pensa all'analisi aziendale ... Supponiamo che tu stia analizzando il modo migliore per supportare il marketing presso un'azienda di prodotti di consumo come Colgate. Se inizi con finestre fantasiose o con la tecnologia più recente, non aiuterai il business quasi come se pensassi prima ai bisogni di dati del business e poi ti preoccupi della presentazione in seguito. Il modello di dati supera il software di presentazione.

Valuta di fare una pagina web. È molto meglio pensare a quello che vuoi mostrare prima (HTML) e preoccuparti di stile (CSS) e script (scegli il tuo strumento) dopo.

Questo non vuol dire che anche la codifica non sia importante. Hai bisogno di capacità di programmazione per ottenere ciò di cui hai bisogno alla fine. È che i dati sono alla base. Un modello di dati scadente riflette un modello di business eccessivamente complesso o impensato.


0

Mi ritrovo a scrivere nuove funzioni e ad aggiornare quelle esistenti molto più spesso che dover aggiungere nuove colonne o tabelle al mio schema di database. Questo è probabilmente vero per tutti i sistemi ben progettati. Se devi cambiare il tuo schema ogni volta che devi cambiare il tuo codice, è un chiaro segno che sei uno sviluppatore molto cattivo.

indicatore di qualità del codice = [modifiche al codice] / [modifiche allo schema del database]

"Mostrami i tuoi diagrammi di flusso e nascondi i tuoi tavoli, e io continuerò a essere sconcertato. Mostrami i tuoi tavoli e di solito non avrò bisogno dei tuoi diagrammi di flusso; saranno ovvi." (Fred Brooks)


-2

Sembra che questa idea abbia varie interpretazioni nei vari tipi di programmazione. È valido per lo sviluppo di sistemi e vale anche per lo sviluppo aziendale. Ad esempio, si potrebbe sostenere che il brusco spostamento dell'attenzione verso il dominio nella progettazione guidata dal dominio è molto simile all'attenzione per le strutture e le relazioni dei dati.


-4

Ecco la mia interpretazione: usi il codice per creare strutture di dati, quindi l'attenzione dovrebbe essere su quest'ultimo. È come costruire un ponte: dovresti iniziare a progettare una struttura solida anziché una che sembri attraente. Accade così che strutture di dati e bridge ben scritti abbiano un bell'aspetto grazie ai loro progetti efficienti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.