È normale che un programmatore non abbia a volte una chiarezza del 100% sul proprio codice? [chiuso]


19

Non sono un programmatore esperto, quindi questo potrebbe essere il motivo, ma ho notato che ogni volta che creo un codice complesso (come un gioco di scacchi che ho fatto di recente), sono in grado di scrivere il codice corretto per far funzionare il programma, anche se lo trovo più tardi, o anche pochi secondi dopo! - Spesso devo fermarmi e pensare, come funziona?

Non solo, ma tendo anche a non pensare al codice e invece scrivo semplicemente via. Ad esempio, nella mia partita a scacchi, ho deciso di utilizzare un array a cinque dimensioni per elaborare le mosse e ho scoperto che avrei potuto farlo senza pensare troppo consapevolmente. Tuttavia, quando mi sono fermato a rileggerlo, ho trovato difficile girare la testa sull'intero concetto tridimensionale e mi ci sono voluti alcuni minuti per capire appieno cosa ho fatto e come funziona il codice stesso.

È normale per i programmatori quando scrivono codice complesso non capire cosa stanno facendo per metà del tempo?


13
È un segno che stai provando troppo a essere intelligente. Devi scrivere un codice più semplice e più modulare se hai problemi a leggerlo da solo.
SHODAN,

3
Per aggiungere altre risposte (perspicaci) nel senso che profuma di codice troppo complicato o di scarsa qualità (non preoccuparti, la maggior parte di noi ha dovuto superare quella fase): Documento . Sia dando nomi propri a variabili / metodi / classi / moduli, aggiungendo una descrizione adeguata a ciascuna funzione, sia scrivendo (quando non vedi altro modo) un semplice commento incorporato che spiega perché e come stai usando qualche frammento complesso di codice.
SJuan76,

4
Non ho mai una chiarezza del 100% sul mio codice.
CodesInChaos,

2
Quell'array 5D sembra davvero che potrebbe usare un po 'di astrazione.

3
Qualche sviluppatore ha sempre il 100% di chiarezza sul suo codice?
Johan,

Risposte:


30

No, non è normale 1 . Almeno, non è normale per i bravi programmatori. Probabilmente è normale che qualcuno impari a programmare.

Scrivere software non è solo schiaffeggiare linee di codice insieme fino a quando non funziona. È necessario lavorare consapevolmente per rendere il codice facile da capire. Un programmatore che rispetto molto una volta mi ha detto "il codice viene letto più volte di quanto sia scritto" . Mentre quello dovrebbe essere completamente ovvio, era un fatto di cui non ero stato a conoscenza fino a quando non me lo ha detto. Gran parte del tuo codice viene scritto solo una volta, forse riscritto una o due volte di più, ma finirai per leggere il codice spesso durante la vita del software.

Se trovi il codice difficile da capire pochi minuti dopo averlo scritto, è un segnale che il tuo codice è troppo complesso. Smetti di aggiungere codice e scopri un modo migliore. Ad esempio, un array a cinque dimensioni non è quasi mai una buona idea. Anche i programmatori davvero intelligenti hanno difficoltà a comprendere una struttura di dati così complessa.

Lo stesso programmatore che mi ha parlato della leggibilità del codice ha anche detto "mostrami le tue strutture di dati e posso dirti come funziona il tuo codice" . Ciò significa che un buon codice inizia con strutture di dati chiare e comprensibili. Se si progettano correttamente i dati, il codice è quasi una preoccupazione secondaria. Certo, questa affermazione è un po 'iperbole perché il software è ovviamente più di un semplice dato, ma inizia con i dati. Pertanto, lavorare sulla creazione di strutture di dati pulite e facili da comprendere e il codice sarà notevolmente più facile da comprendere.


1 Certamente c'è un codice là fuori che è molto complesso e difficile da capire anche dal più intelligente dei programmatori. Alcuni problemi sono intrinsecamente complessi. Tuttavia, oserei dire che la stragrande maggioranza del codice scritto dalla stragrande maggioranza dei programmatori non è quel tipo di codice.


8
[1] Da un punto di vista più pessimistico, è normale ma non è buono.
Dan,

1
Se la "matrice a cinque dimensioni" è semplicemente una mappa da una 4 tupla o una 5 tupla a una strategia, l'autore avrebbe potuto usare una tabella hash o una funzione di ricerca helper. Tuttavia, se l'autore trascorre la maggior parte del tempo a codificare i meccanismi di inizializzazione dell'array (cicli for nidificati), l'attuale "insight dell'algoritmo" verrà annegato nella pila di "codice meccanico". I programmatori cercano di mantenere separato questo tipo di rumore. Pertanto, i bravi programmatori devono saper scrivere le librerie principalmente per ospitare quel codice meccanico.
rwong

L'array 1-D è una linea, 2-d è una griglia, 3-d è un cubo, 4-d è una linea di cubi, 5-d è una griglia di cubi, ecc. Ma non vedo un uso per una struttura di dati così complessa quando si tratta di scacchi.
user2785724

15

Esistono due tipi di questo: 1.) confusione 2.) beata ignoranza

Il primo è cattivo e può scomparire con il tempo e l'esperienza.

Il secondo è positivo se i progetti diventano più grandi: se devi ricordare ogni dettaglio dell'implementazione solo per poter lavorare con il tuo codice, c'è qualcosa che non va (vedi "nascondere le informazioni").

Ogni sviluppatore dimenticherà come funzionava il codice, quindi lo scrive in modo che un altro nuovo sviluppatore lo capisca e sia in grado di mantenerlo senza rompere altre parti del programma che è sconosciuto anche a lui.

Quindi "non sapere" è in realtà una costante nello sviluppo del software - è solo come o se lo gestisci.


1
Stai toccando qualcosa di importante qui, che è fondamentale programmare utilizzando schemi e convenzioni di buon senso , perché i dettagli di implementazione vengono effettivamente dimenticati. Ma se gli schemi e le convenzioni nel codice sono ragionevoli, è abbastanza facile recuperare i dettagli dal contesto quando necessario. D'altra parte, se il codice è tutto monolitico, imperscrutabile e troppo intelligente, alla fine non solo dimenticherai i dettagli, ma altri programmatori che cercano di mantenere il codice avranno un tempo molto più difficile.
Craig,

12

Direi che è più comune di quanto la gente ami ammettere. Perfino Brian Kernighan ha accennato ad esso:

Il debug è due volte più difficile della scrittura del codice in primo luogo. Pertanto, se si scrive il codice nel modo più intelligente possibile, per definizione non si è abbastanza intelligenti da eseguire il debug.

Quando guidiamo verso il negozio, eseguiamo una sequenza di regolazioni dettagliate delle posizioni dei pedali e del volante. Questo è molto semplice al momento. Ora, immagina se hai registrato quegli adattamenti su carta e li hai dati a un amico che aveva bisogno di indicazioni per raggiungere il negozio.

Allo stesso modo, ci piace scrivere il codice a un livello di astrazione, ma ci piace leggerlo in più livelli di astrazione più alti. Il nostro modo preferito di scrivere e leggere il codice è quindi in conflitto. Ciò significa che rendere il codice facile da leggere è di solito un passaggio separato e consapevole, con una diversa serie di abilità.

Ciò che rende un buon programmatore è quando hanno difficoltà a leggere ciò che hanno appena scritto, a quel punto creano un'astrazione. Un programmatore migliore lo fa più volte, diventando sempre più esigente. Alla fine, i programmatori esperti iniziano ulteriormente lungo il processo, ma spesso possono ancora vedere margini di miglioramento dopo aver letto ciò che hanno appena scritto.


Non sono d'accordo con Brian su questo, adoro il debug, sono una delle poche persone che conosco nel settore che lo fa, ma non valuto il codice che scrivo così bene.
James Snell,

@JamesSnell Non ha detto che il debug è cattivo o spiacevole, ma solo che è difficile, e il debug di codici complicati è ancora più difficile.
cbojar,

5

Penso che questo sia qualcosa che andrà via con l'esperienza.

Se stai scrivendo sistemi complessi, devi avere la capacità di scrivere codice pulito e gestibile che sia tu in futuro, sia qualcun altro in futuro, possa capire. Quindi, in sostanza, la cosa che stai facendo ora non è scalabile.

Avrai molti momenti in cui stai guardando un codice che hai scritto 6 mesi fa e pensando "cosa diavolo sta succedendo qui?", Ma se succede un giorno dopo aver scritto il codice, devi pensare 'pulito codice 'altro.

Fonte: mai usato un array a 5 dimensioni :)


3
@ 83457 - perché un array 5d è un modello scadente di un problema 2d. Se pensi davvero che sia un buon codice, trascinalo su codereview.stackexchange.com e vedi quali risposte ottieni.
James Snell,

2
@ 83457 - Se è "confuso come l'inferno", hai risposto tu stesso. Potrebbe essere possibile che un array 5-D non sia confuso ma probabilmente non per la maggior parte di noi, indipendentemente dal nostro livello di abilità.
dbasnett,

2
@ 83457 essere confuso come l'inferno dovrebbe essere già un'ottima motivazione per non usarlo.
Fabio Marcolini,

3
Finché hai una buona ragione per ogni dimensione, non vedo un motivo per evitare un array 5D. Forse esiste una soluzione migliore, come un dizionario con una chiave complessa o più array di dimensioni inferiori, ma posso benissimo immaginare che un array 5D sia appropriato per un problema complicato come un AI di scacchi.
CodesInChaos,

2
@CodesInChaos Tranne per il fatto che quelli non sono solo array, rappresentano sequenze significative (ad esempio alberi di decison nidificati). Denominandoli in modo appropriato e assegnandogli i tipi in modo che non possano essere abusati (anche se quei tipi sono i wrapper sugli array), rendi il codice più chiaro e meno probabile che contenga bug, a malapena a qualsiasi costo.
Deworde,

5

"Normale" è molto soggettivo, quindi dico: è molto comune, ma dovrebbe essere evitato.

Una delle caratteristiche del "buon codice" (ho sentito che esiste una cosa del genere) è la chiarezza: dovrebbe essere chiara come i problemi sottostanti gli permettono di essere. Se il problema è complesso, anche il codice sarebbe complesso, ma questa è una complessità intrinseca , al contrario della complessità accidentale (ho sentito parlare per la prima volta di questa distinzione nei discorsi di Rich Hickey ) introdotti dall'uso errato o non da strumenti, schemi, tecniche e pratiche.

Ci sono casi in cui la mancanza di chiarezza è accettabile anche quando il problema non è molto complesso, ad esempio se si scrive un sito promozionale che si sa che durerà fino a quando la campagna di marketing continua. È un codice usa e getta che non deve essere mantenibile. Per altri (e la maggior parte dei) casi, non è accettabile, perché mantenere tale codice costerà molto. Tuttavia, è comune.

Relazionato:

  • Quando capire significa riscrivere - articolo sul problema della comprensione del codice.
  • ML efficace - una lunga discussione su, tra ML / OCaml, su come scrivere il codice per "lettori" (es. Manutentori): "Favorire i lettori sugli scrittori". Consiglio di guardarlo, indipendentemente dalla lingua che usi.

2

Non penso che sia normale, ma per programmi molto complessi, come il programma di scacchi di cui parli, penso che sia certamente possibile.

Molti anni fa, quando ero appena uscito dalla scuola di specializzazione (quindi ero ancora relativamente inesperto nella scrittura di programmi di grandi dimensioni), ho scritto il mio primo vero compilatore. L'analisi è stata semplice, ma poi ho dovuto scegliere come target quattro diversi set di istruzioni per microprocessore. Intendevo scrivere il compilatore nella sua lingua, quindi per prima cosa ho usato solo le funzionalità della lingua di cui avevo assolutamente bisogno, ho scritto il primo generatore di codice in linguaggio assembly e ho verificato che generasse il codice corretto per il sottoinsieme della lingua. Sono stato quindi in grado di utilizzare il compilatore per compilare se stesso da quel momento in poi, aggiungere le restanti funzionalità e usarle anche nel compilatore stesso

Ho quindi scritto i generatori di codice back-end per ciascun microprocessore e ho verificato che generavano tutti il ​​codice corretto, ma mentre era corretto non era molto ottimale. Quindi ho quindi proceduto alla scrittura di ottimizzatori per ciascun generatore di codice.

Quando stavo testando l'output dei generatori di codice dopo aver aggiunto tutta l'ottimizzazione, sono stato spesso sorpreso dal codice generato dal compilatore. Spesso non era il modo in cui avrei scritto il codice a mano, ma era corretto e piuttosto conciso.

Quando non era ovvio per me come il generatore di codice producesse parte del codice, cercavo di seguire la logica a mano, ma ci sono state volte in cui ho rinunciato. Se avessi aggiunto un sacco di output di traccia sarei stato in grado di seguirlo, ma non mi sono preoccupato poiché il codice generato era soddisfacente e avevo bisogno di passare ad altri progetti.


Mi sembra che tu abbia una formazione estremamente buona con solide basi e che tu abbia interiorizzato le conoscenze a un livello molto alto. Immagino che questo sia piuttosto raro tra i programmatori tipici. I programmatori più comuni (incluso me) devono lottare per stare al passo con le conoscenze necessarie per il compito di oggi, perché la tecnologia cambia così rapidamente.
rwong

@rwong Grazie. La maggior parte è esperienza - scrivo programmi da 46 anni e non ho intenzione di smettere presto.
Tcrosley,

2

Ci sono molte risposte decenti qui.

Ho un paio di prese su questo.

Uno è che se non capisci perché il tuo codice sembra funzionare, allora a) probabilmente non funziona (probabilmente sembra funzionare solo) eb) o non hai capito abbastanza bene il dominio del problema quando ha iniziato a programmare o non ha suddiviso il dominio problematico in unità più piccole e semplificate prima di iniziare.

L'altra mia opinione su questo è che la vera chiave è usare schemi e convenzioni di buon senso nel tuo codice. Questo è un argomento molto più vasto di quello che un post può affrontare. Ma cerca una buona letteratura sull'argomento, inclusi alcuni dei vecchi standbys come i libri "Code Complete" e "Writing Solid Code".

Modifica dei dettagli di implementazione. L'unica vera costante è l'obiettivo funzionale del codice. Se hai mai scritto più di una funzione, nel tempo dimenticherai dettagli specifici e granulari sull'implementazione. Ma dovresti certamente capire come funzionano i pezzi quando li costruisci e dovresti essere in grado di tracciare un diagramma del tutto e capire come i pezzi lavorano insieme.

Se usi schemi e segui convenzioni di buon senso, sarà molto più facile recuperare i dettagli specifici dell'implementazione quando guarderai di nuovo il codice. O quando qualcuno che non ha mai visto il codice prima lo guarda per la prima volta. Inoltre, seguire tali convenzioni e schemi nel corso del tempo comporterà che i dettagli di implementazione si distingueranno dalle convenzioni e dai modelli stessi, che è un altro fattore che renderà più facile la comprensione del codice.

La maggior parte dei problemi che affrontiamo con il software sono complessi per natura. La progettazione del software è un esercizio di gestione della complessità.


1

Non lo definirei normale , ma può sicuramente succedere. Se ti succede poco dopo aver scritto il pezzo di codice in questione, immagino che il tuo codice sia inutilmente complesso e debba essere semplificato, o ti distraggerai facilmente. :)

Ma se metti via il tuo codice, ti concentri su altri progetti e torni ad esso dopo settimane, mesi o addirittura anni, non è una sorpresa che dovrai scoprirlo di nuovo.

Ma c'è qualcosa che puoi fare al riguardo. Da quello che dici, sembra che non pensi abbastanza al tuo codice mentre lo scrivi, e quindi stai rendendo difficile per il tuo io futuro capire cosa sta succedendo. Usa questa conoscenza a tuo vantaggio: questa è la migliore motivazione per produrre codice ben strutturato, ben documentato e comprensibile. Sai per esperienza diretta cosa succede quando non ti occupi della qualità del tuo codice. Sapere che dovrebbe renderti un programmatore migliore a lungo termine. Quando collaborerai a progetti software, i tuoi colleghi ti ringrazieranno per aver prodotto un codice comprensibile. E anche la percentuale di difetti del codice migliorerà.

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.