C'è un vantaggio nella compilazione del codice man mano che procedi?


183

Di recente ho avuto un colloquio di lavoro in cui mi hanno concesso un'ora per scrivere del vero codice. Non era un importo enorme, probabilmente meno di 100 righe. Dopo circa 45 minuti, l'ho compilato, eseguito e fatto funzionare. Potrei aver trascorso 5-10 minuti a elaborare errori di compilazione e un paio di bug minori, ma nel complesso è stato molto fluido. (Per inciso, ho ricevuto un'offerta da loro.)

Tuttavia, ciò che mi ha lasciato perplesso è che dopo aver consegnato il codice completo, l'intervistatore mi ha detto che l'unica cosa che ho fatto di sbagliato è stata "non compilare mentre procedo". Gli ho chiesto qual è la differenza, e lui ha detto "cosa avresti fatto se avessi finito il codice e non fosse stato compilato in tempo".

Secondo me questo è un argomento non valido, perché "ottenere la compilazione del codice" per una determinata lunghezza di codice comporta generalmente la correzione di un numero costante di errori di compilazione e richiede un periodo di tempo abbastanza costante, che dovrebbe essere lo stesso se lo si fa dopo di te termina di scrivere il codice o se lo interfogli con il tempo di codifica. Semmai, interrompere la codifica per cercare punti e virgola mancanti sarebbe probabilmente dannoso per la tua efficienza. Tranne in circostanze estreme quando sto sperimentando oscurità attorno a casi limite su cose come funzioni virtuali in classi derivate, ecc. Sembra ragionevole aspettarsi che il codice scritto da uno sviluppatore esperto si compili, meno l'errore di battitura occasionale e persino in caso contrario,

In un altro incidente simile, durante un'intervista mi è stata data una base di codice incompleta e mi è stato chiesto di finirlo e apportare le modifiche necessarie per farlo funzionare. Ho iniziato leggendo il codice esistente e poi dopo alcuni minuti (anche prima che avessi finito di guardare il codice), l'intervistatore mi ha detto che era abbastanza. Quando gli ho chiesto cosa avrebbe fatto (ovvero "cosa ho fatto di sbagliato"), mi ha detto che avrebbe iniziato ottenendo immediatamente la compilazione del codice.

Perché è anche rilevante? Secondo me e nella mia esperienza, la compilazione di un pezzo di codice è essenzialmente casuale, implicando cose come la mancanza di punti e virgola e ha poco a che fare con la correttezza del programma sottostante. (Per me, concentrarsi sulla compilazione è come far scorrere un articolo attraverso un controllo ortografico senza correzione di bozze per controllare la grammatica.)

Se mi dai un pezzo di codice incompleto, la prima cosa che farò sarà leggerlo. Non proverò nemmeno a compilarlo finché non saprò cosa sta facendo il codice e so che l'algoritmo è corretto.

Ad ogni modo, questi sono stati solo un paio di episodi recenti, ma in generale ho sentito molti sviluppatori parlare della compilazione del loro codice mentre procedono, eppure nessuno è stato in grado di dirmi i vantaggi di farlo. Comprendo i vantaggi del test del codice mentre procedi, ma perché compilare?

Quindi la mia domanda è questa: c'è qualcosa che mi sono perso? C'è davvero un vantaggio nella compilazione mentre procedi? O è una sorta di mito propagato dalla comunità del software che devi compilare il tuo codice frequentemente?


54
O quello, o che le mie abitudini vengono definite cattive abitudini da persone che hanno abitudini diverse.
CaptainCodeman,

9
@DocBrown Il confronto è valido se l'obiettivo finale è avere un prodotto corretto. Un programma che "funziona" non è migliore di un programma che funziona in modo errato. Non puoi aspettarti che la compilazione controlli il tuo codice per te più di quanto non ti possa aspettare un controllo ortografico per correggere i tuoi errori grammaticali.
CaptainCodeman,

7
Il fatto che la compilazione disturbi il flusso di lavoro è molto soggettivo e dipende dalla lingua, dall'ambiente di costruzione, dalle dimensioni / complessità del progetto, ecc. È più probabile che l'IMO sia un problema per i progetti legacy di grandi dimensioni.
pjc50,

64
Sono pienamente d'accordo con il PO. Non riesco a capire come qualcuno possa giudicare le proprie abitudini lavorative, ad es. Quando usa per avviare il compilatore. L'unica cosa che conta è l'output degli sforzi. È corretto? È mantenibile? Funziona nei tempi previsti? Quanto tempo ci è voluto per implementarlo? Queste sono le domande interessanti. Tutto il resto è BS arbitrario. Se l'intervistato scrive 2 ore di codice perfetto che viene compilato al primo tentativo, dov'è il problema? Solo perché l'intervistatore lo fa diversamente? Mio Dio.
JensG,

9
Va anche detto che per alcuni linguaggi e IDE (Java / [Eclipse | NetBeans | etc], C # / Visual Studio, ...), l'IDE sta già compilando tutto in background in tempo reale, mentre si digita, in effetto dandoti un ciclo di feedback immediato sul fatto che tu abbia commesso un errore. Si spera che gli sviluppatori IDE abbiano avuto delle ricerche a sostegno di questo approccio di compilazione man mano che procedi.
Ogre Salmo33,

Risposte:


223

C'è davvero un vantaggio nella compilazione mentre procedi?

C'è. Ti dà un ciclo di feedback più breve - che in generale, quando si progetta (UI, software di scrittura, visual design ecc ...) è una buona cosa.

Un breve ciclo di feedback consente di correggere rapidamente gli errori prima che diventino più costosi da correggere.

Per prendere in prestito il tuo esempio, supponi di scrivere in un linguaggio simile a C e di aver dimenticato un punto }nel mezzo del programma.

Se compili subito dopo aver finito di scrivere la dichiarazione, puoi essere certo di aver appena introdotto l'errore di compilazione e di poterlo correggere lì e poi, in pochi secondi.

Se non lo fai, tuttavia, dovresti dedicare una buona quantità di tempo a leggere il codice, cercando la posizione esatta che }è e assicurandoti, una volta individuato l'errore, che la correzione è effettivamente ciò che era previsto. Ciò avverrebbe un po 'dopo che hai lasciato quel bit di codice. Non sarebbe così cristallino come nel momento in cui l'hai scritto.


Ora, sì, il risultato finale è lo stesso, ma hai sprecato una buona quantità di tempo su problemi sintattici che il compilatore è lì per aiutarti - una quantità di tempo che potrebbe essere significativamente più breve se compilati mentre procedevi.


72
In effetti, per errori sintattici del genere, gli IDE moderni essenzialmente si compilano e si ricompilano continuamente per rendere il tuo circuito di feedback il più breve possibile, ed è irragionevolmente utile per rilevare errori minori.
Phoshi,

12
@CaptainCodeman - Direi che ci sono alcuni errori di compilazione che richiedono di scavare un bel po 'di codice. Questo è più vero per basi di codice più grandi e set di modifiche più grandi.
Oded,

29
A volte il compilatore ti dà un puzzle invece di un suggerimento, come ad esempio errori del modello gcc.
pjc50,

14
@ pjc50: assolutamente (che è più facile da gestire non cambiando troppe cose contemporaneamente prima della prossima compilation, quindi sai esattamente cosa hai cambiato alla fine).
Doc Brown,

21
L'idea non è quella di compilare solo casualmente. È compilare ad ogni passaggio significativo, compilare quando ci si aspetta che funzioni ancora correttamente. Ad esempio, eseguirò la compilazione per verificare che gli oggetti vengano creati / eliminati correttamente o per garantire che gli eventi vengano generati correttamente in una nuova classe che ho creato. Se creo una classe e la inserisco nel mio programma in qualche modo, voglio assicurarmi di averla eseguita correttamente prima di iniziare ad agganciare più cose alla mia app. Meno importante con le piccole app, vitale per quelle grandi.
Thebluefish,

108

La compilazione è una forma di test, specialmente nei linguaggi che fanno ampio uso di tipi come Haskell o ML . In altre lingue è una scansione sintattica che ti dice poco.

Detto questo, "compilati mentre vai" mi sembra un'abitudine molto situazionale. Potresti anche essere contrassegnato per essere "nervoso" per compilare più frequentemente del pregiudizio personale dell'intervistatore. Sembra nitpicking; a nessuno piace ammettere che un intervistato ha superato il test; punta le scale della trattativa salariale.

Non tutti i sistemi di compilazione sono veloci. Ho lavorato su un progetto (C ++) in cui Make impiegherebbe 30 secondi a indicare tutto per determinare se è necessario compilarlo o meno, e la maggior parte dei file richiederebbe un paio di minuti per essere compilata se fossero state apportate modifiche. Eravamo riluttanti a farlo più frequentemente di ogni 10-15 minuti. Qualcuno fornirà senza dubbio un aneddoto durante la compilazione coinvolto nel prendere il tuo mazzo di schede perforate e trasportarle in un altro edificio ...

Compila quando ritieni di aver realizzato un'unità concettuale completa nella tua testa e sei pronto per averlo convalidato. Una volta al minuto o una volta alla settimana a seconda del flusso di lavoro.


25
quando porti le tue schede perforate negli sysops per caricarle, assicurati di non lasciarle mai e poi mai perché rimetterle nell'ordine giusto è un vero PitA! Ah, per i giorni in cui uno strumento di debug essenziale era una banda elastica.
gbjbaanb,

3
Quando ho iniziato a programmare ho misurato i miei progressi in base a quanto codice avrei potuto scrivere senza compilare, essenzialmente in base alla qualità del mio compilatore mentale. All'inizio c'erano pochi personaggi, poi alcune righe. Ora non mi interessa. Compilo molto per piccoli cambiamenti di cui voglio solo vedere gli effetti, compilo molto poco quando eseguo il layout strutturale del progetto.
Phil

Hmm. Voglio solo dire che un file C ++ ben scritto non dovrebbe richiedere più di qualche secondo per la compilazione. Se è più lungo, è un odore per codice errato. E se è così grande che crea problemi, direi che l'applicazione è troppo monolitica. La "mia" marca non ha mai avuto problemi, e nemmeno durante la compilazione di Linux.
phresnel,

2
Erano 1,5 milioni di LOC quando me ne sono andato. Nota che Linux è C non C ++; i template sembrano essere lenti in gcc, e se hai fatto qualcosa di intelligente e utile che sembra essere lento da compilare, non c'è modo semplice di profilare il compilatore per capire cosa fosse.
pjc50,

21
@gbjbaanb Penso che sarebbe meglio dire "i giorni in cui il controllo del codice sorgente era una banda elastica". ;)
JasonMArcher il

35

Quindi la mia domanda è questa: c'è qualcosa che mi sono perso?

Sì: la tua mente non è un compilatore. Mentre un compilatore può fare n cambi di contesto al secondo, la tua mente no. Il numero di cambi di contesto che la tua mente può fare in un giorno dipende da una serie di fattori come l'esperienza / familiarità con la base di codice, quanto sei mentalmente immerso nel codice, quanto è pulito il codice, quanto è complesso il problema che stai affrontando, quanto sei stanco, se sei frequentemente interrotto o in un ambiente rumoroso e così via.

Compilare una base di codice (tutti allo stesso tempo), per la prima volta (pensa "progetto con 20 file") ti costringerà a cambiare contesto da quello a cui stai pensando (ad es. "Questo valore è impostato su 5 qui, quindi in blablabla for loop e l'algoritmo complesso restituisce il valore corretto al ritorno ") a un problema di compilazione completamente estraneo a ciò a cui stai pensando (file / modulo / funzione / pre-condizioni / sintassi / nomi variabili diversi, condizioni preliminari ecc. ).

Più codice compili in una sola volta, più contesto deve cambiare la tua mente. Questo non è un problema per una piccola base di codice, quando tutto il codice che hai scritto è quello che hai scritto in un'ora. È tuttavia un grosso problema, quando si lavora in una base di codice esistente, con interdipendenze multiple (e spesso non documentate).

C'è davvero un vantaggio nella compilazione mentre procedi?

Riduci al minimo i cambiamenti di contesto che la tua mente deve fare, permettendoti di concentrarti maggiormente sull'impatto e sugli effetti collaterali dei cambiamenti che apporti. Ti rende anche meno stanco (e meno soggetto a errori) e aumenta la qualità del tuo output (cioè puoi garantire effetti collaterali minimizzati più facilmente quando cambi e compili un file alla volta, rispetto a quando compili e cambi dieci).

Se si compila in iterazioni molto brevi (ciò presuppone che il processo di compilazione sia ottimizzato per richiedere un breve periodo di tempo), è possibile correggere gli errori di compilazione senza uscire dalla "zona".

O è una sorta di mito propagato dalla comunità del software che devi compilare il tuo codice frequentemente?

È propagato anche dalla comunità del software, ma ha buone ragioni dietro.

Secondo me questo è un argomento non valido, perché "ottenere la compilazione del codice" per una determinata lunghezza di codice comporta generalmente la correzione di un numero costante di errori di compilazione e richiede un tempo abbastanza costante

Mi sembra che tu abbia poca (o nessuna) esperienza, nel mantenimento di basi di codice legacy medio-grandi (centinaia o migliaia di file sorgente). Questo è dove questo atteggiamento (ovvero "compilare man mano che vai") ti aiuterà di più, ed è qui che formi questo tipo di abitudine.

Immagino che le persone che ti hanno intervistato abbiano tratto una conclusione simile ("hai poca o nessuna esperienza in grandi basi di codice").


1
"compila e modifica dieci" - molte situazioni in cui questa è la più piccola unità significativa da provare; come l'aggiunta di un nuovo parametro a una funzione e a tutti i suoi siti di chiamata.
pjc50,

7
Interruttori di contesto. Stai scherzando, vero? Se parliamo di compilazione di background automatizzata per indicare errori sintattici nel codice mentre procedi, va bene. Ma il cambio di contesto più veloce non sarà in grado di dirti se la logica dell'algoritmo è implementata correttamente o se l'algoritmo è adatto a tutti. Ma questo è ciò che distingue una soluzione funzionante dal codice ben organizzato, senza errori, compilato e fatto esplodere velocemente, ma assolutamente sbagliato.
JensG,

5
@JenS, no, non sto scherzando. Dover saltare tutto il codice per correggere gli errori di compilazione ti assicura di non pensare più al problema che stai attualmente risolvendo (ti fa uscire dalla zona). Se invece puoi compilare mentre scrivi il codice, puoi continuare a lavorare sul controllo dell'algoritmo, non sulla sintassi. Il modo più veloce per gestire i cambi di contesto è assicurarsi che non ne avrai bisogno). Il mio post assume comunque un mondo ideale (con una veloce compilazione C ++ di basi di codice di grandi dimensioni e interdipendenze minimizzate).
utnapistim,

1
@JensG che sembra essere un errore logico: non si tratta di scegliere tra codice compilato e codice merdoso, ma di eventuali vantaggi della compilazione più di una volta.
Jorg,

1
Dubito che l'affermazione secondo cui interrompere la concentrazione decine di volte per un breve lasso di tempo per correggere singoli errori sintattici sia più veloce che romperla una volta e correggere una dozzina di errori sintattici in una volta sola (dopo che ti sei preoccupato per il tuo algoritmo reale). Questo non è certamente il modo in cui gli switch di contesto funzionano nell'informatica (stiamo cercando di ottimizzare il throughput dopo tutto). E sto lavorando a un progetto con circa 500k LoC di codice C ++ che si è evoluto nel corso di oltre un decennio, quindi spero che non abbiamo ancora disegnato la carta di inesperienza?
Voo,

26

Penso che qui ci sia più di un po 'di snobismo professionale. L'implicazione sembra essere "se non hai mai avuto la necessità di compilare regolarmente quindi non hai mai lavorato con qualcosa di così complicato - vai a fare un po 'di esperienza in più e ritorna quando hai imparato a lavorare esattamente come facciamo noi".

Ma ovviamente c'è un altro lato di questo. Alcuni progetti richiedono un'età per essere compilati. Ho lavorato con framework che richiedono almeno 30 minuti per essere compilati anche dopo modifiche minori. Heaven ti aiuta se hai mai bisogno di modificare un file di intestazione. Le ricompilazioni complete vengono in genere eseguite dall'oggi al domani e se stai facendo affidamento sul compilatore per rilevare i tuoi errori, ci sono ancora errori rari che non verranno rilevati durante una build parziale. In queste condizioni non ti ricompilerai ogni 5 minuti, a meno che non ti senta pigro .

Il compilatore non può aiutarti con errori logici o semantici e gli errori di sintassi in realtà non sono così difficili da evitare che passare la metà della giornata a compilare sia utile. Certo, farai l'errore di battitura occasionale, ma suppongo che puoi sia toccare che scrivere. Se hai la libertà di scegliere, usa uno stile di codifica che faccia buon uso del layout per evidenziare visivamente gli errori e non abbandonerai mai più una parentesi, una parentesi o un punto e virgola. Ci vuole un po 'di pratica e un po' più di disciplina rispetto alla maggior parte delle volte, ma è possibile. Posso scrivere il codice per un paio d'ore alla volta, in un semplice editor di testo, e compilarlo per la prima volta meglio di nove volte su dieci. Certo, potrei compilare più spesso, ma non ricordo l'ultima volta che ho avuto un errore che sarebbe stato più facile da correggere di conseguenza.

Se non sei un fan della costante ricompilazione, sei in buona compagnia. Ecco Donald Knuth:

Quanto alla tua vera domanda, l'idea di compilazione immediata e "unit test" mi attira solo raramente, quando mi sento in un ambiente totalmente sconosciuto e ho bisogno di feedback su ciò che funziona e cosa no. Altrimenti, un sacco di tempo viene sprecato in attività che semplicemente non ho mai bisogno di svolgere o addirittura pensare.


Detto questo ... se stai lavorando in un contesto in cui la compilazione è un'azione gratuita, perché non dovresti? A casa, su progetti personali, premo ctrl-S circa una volta ogni 30 secondi e il collegamento "compila" quasi altrettanto spesso, in un IDE che esegue costantemente il codice attraverso il front-end del compilatore per fornire l'evidenziazione degli errori in tempo reale. Perché rinunciare a un pranzo gratuito?


Non sono d'accordo sul fatto che la compilazione sia gratuita, le distrazioni sono costose! Ma per il resto, buona risposta, grazie :)
CaptainCodeman il

Forse avrei dovuto rendere audace, in corsivo "se" un "iff" invece ... Penso che a seconda del progetto, del compilatore e dell'ambiente possa essere dannatamente vicino a un'azione libera. Se hai una seconda finestra o schermata per l'output del compilatore, puoi compilare quasi tutte le volte che ti fermi a respirare. Se tu fossi davvero hardcore (non lo sono) non avresti nemmeno bisogno di distogliere lo sguardo dal tuo codice - a condizione che il compilatore abbia prodotto errori abbastanza dettagliati da registrarti sulla tua visione periferica. Ancora una volta, questo è se la compilazione è ragionevolmente veloce, altrimenti vedi sopra.
DeveloperInDevelopment

2
I hit ctrl-S about once every 30 seconds. Probabilmente risparmio due volte più spesso lol. È davvero una brutta abitudine. A volte salverò nel mezzo di una riga di codice, quindi salverò di nuovo alla fine. Ogni volta che smetto di pensare per un secondo e non digitando, salvo.
Cruncher,

21

Ci sono meriti per la compilazione man mano che procedi. Ma sono molto d'accordo sul fatto che rimanere in attività è una strategia di codifica OK.

Il beneficio più significativo alla compilazione incrementale è la mentalità molti ottenere in se aspettano per la fine di compilare e testare : siamo più interessati alla fine a ottenere il codice per l'esecuzione di ogni altra cosa in quel punto. Diciamo "Oh, ho solo bisogno di aggiungere questa parentesi in modo che il compilatore smetta di lamentarsi" o "oh, ho solo bisogno di capitalizzare questo" senza pensare se c'è un errore semantico sottostante che questo errore di sintassi nasconde. Trovo davvero errori sintattici che spesso si annidano in errori semantici (il contrario non è vero).

Ad esempio, supponiamo che abbia cambiato il significato di una variabile e, di conseguenza, abbia cambiato il suo nome. La modifica del nome genera un errore di sintassi più avanti nel codice, ma se per favore compiacente il correttore correggendo il nome, ho ignorato il motivo per cui l'errore si è verificato.


5
+1 per evidenziare la connessione tra errori semantici e sintattici
Doc Brown,

15

Comprendo i vantaggi del test del codice mentre procedi, ma perché compilare?

Ma come testerai il tuo codice mentre procedi quando non lo compili di conseguenza?

Il caso estremo è lo sviluppo test-driven (TDD). È ovvio che TDD non funziona con la tua strategia, poiché TDD significa cicli estremamente brevi di test di scrittura, compilazione (dovrebbe fallire), scrittura di codice, compilazione di nuovo, test di esecuzione, correzione di bug, compilazione di nuovo, refactor, compilazione -ainain, run-test, e così via ...

Quindi non tutti fanno TDD, almeno non sempre (anche io, lo ammetto). Con la tua strategia attuale, non avrai mai la possibilità di provare TDD. Ma anche quando non stai facendo TDD, è estremamente utile IMHO testare il tuo codice più regolarmente, il che non è possibile quando non lo compili regolarmente. E quando il test fallisce, devi eseguire il debug (il che può aiutarti a capire perché l'algoritmo bello che hai scritto qualche minuto prima non si comporta così bene come pensavi che dovesse fare). E più codice scrivi senza compilare, più codice scrivi senza test, quindi più è probabile che ti imbatti in un caso in cui non puoi prevedere che il tempo per risolvere il problema è "O (1)", come hai scritto.


1
Sono d'accordo con te, ma penso che ci sia una differenza tra la compilazione di un programma perché vuoi eseguirlo, rispetto alla compilazione quando non c'è nulla di significativo da testare (o per correggere errori di compilazione).
CaptainCodeman,

@CaptainCodeman: Penso che quando si scrivono 100 righe di codice, quasi sempre dovrebbero esserci molte piccole parti che possono essere testate individualmente per conto proprio. 100 righe di codice in genere significano qualcosa tra 4 e 15 funzioni (o> 20, se si codifica nello stile di Bob Martin).
Doc Brown,

5
@CaptainCodeman: in TDD non c'è mai "niente di significativo" da testare. L'esempio classico è che vuoi scrivere una nuova classe (chiamiamola Foo) quindi la prima cosa da fare è creare un test unitario e scrivere new Foo();che ovviamente non riuscirà a compilare poiché non hai scritto la definizione della classe. In TDD questo è un motivo valido per eseguire un compilatore: dimostra che il test unitario funziona (fallendo).
slebetman,

@slebetman: grazie per questo utile commento. Vorrei aggiungere che IMHO non è limitato a TDD. Quando si scrivono 100 righe di codice, c'è sempre qualcosa di significativo da testare tra, se si fa TDD o meno.
Doc Brown,

14

In realtà sono d'accordo con te sul fatto che gli errori del compilatore non dovrebbero essere un grosso problema per uno sviluppatore esperto. Non credo che il costo di risolverli aumenti in modo significativo nel tempo di cui preoccuparsi. Se fosse possibile rimandare la correzione di tutti gli errori del compilatore fino a poco prima di una spinta, lo farei, poiché presenterebbe un'interruzione molto più piccola e più consolidata.

Sfortunatamente, trovare gli errori del compilatore non è l'unica cosa che fanno i compilatori. A rischio di affermare ciò che è ovvio, la compilazione è necessaria per eseguire il programma e l'esecuzione del programma è necessaria per trovare tutti i bug di runtime più complessi, sottili e interessanti che persino gli sviluppatori esperti hanno creato. E questi tipi di bug sono più difficili e quindi più costosi da correggere e più a lungo li rimandano, perché possono costruirsi o mascherarsi a vicenda.

Tuttavia, non segnerei necessariamente qualcuno in un'intervista per rimandare la compilazione fino alla fine. Gli esercizi di intervista tendono ad essere molto semplici e gli sviluppatori esperti di solito conoscono i loro limiti. Più sei sicuro di ciò che hai scritto, più tempo passerai tra le compilazioni. Questa è solo la natura umana.

Per non trascinarti giù, però, la fiducia dovrebbe essere giustificata. Se avessi trascorso 45 minuti a scrivere qualcosa senza compilare, quindi avessi richiesto altri 45 minuti per eseguire il debug, avrei pesato molto contro di te.


8

L'unica cosa importante riguardo alla compilazione frequente, che manca da altre risposte per quanto posso vedere è questa: se compili raramente e ricevi una grande quantità di errori del compilatore, la maggior parte di questi sono privi di significato, perché sono generati dal primo errore. Potrebbe essere perché hai avuto un tipo errato, o un errore di battitura o un errore di sintassi semplice che rende non valida una dichiarazione.

Puoi sempre semplicemente correggere il primo, ricompilare, correggere il successivo rimanente e così via, ma con una base di codice di grandi dimensioni può essere lento. Ma se provi a sfogliare il lungo elenco di errori del compilatore e degli errori di individuazione che sono indipendenti, allora passi molto tempo a leggere messaggi irrilevanti o a navigare il codice dallo spot di errore secondario alla causa effettiva.

Un'altra cosa che va per build regolari è che nulla ti impedisce di iniziare a compilare non appena hai scritto un blocco completo di codice, che dovrebbe essere compilato. È quindi possibile continuare a scrivere più codice durante la compilazione, purché non si salvino le nuove modifiche fino al termine della compilazione. Quindi praticamente non si perde tempo ad aspettare la costruzione. Se aspetti di aver scritto tutto ciò che scriverai in quel momento, devi aspettare la compilazione senza fare nulla. Questa è sostanzialmente la versione manuale di ciò che gli IDE moderni possono fare automaticamente in background.


È interessante notare che questa è una buona ragione per compilare regolarmente anche se la compilazione è lenta . Buon punto.
sleske,

3

Per un programmatore sufficientemente esperto il codice di compilazione non è mai il collo di bottiglia.

Una volta che conosci una lingua abbastanza bene (cioè quando non devi più pensare alla sintassi e invece solo al codice per funzionalità) tendi a non fare semplici errori sintattici. Quelli che fai di solito sono errori di battitura o copia-incolla e possono essere ripuliti in breve tempo con pochi passaggi di compilazione.

Scrivo regolarmente codice tutto il giorno senza compilare, quindi compilerò e sistemerò semplicemente gli errori di sintassi e gli avvisi che il compilatore segnala prima di impegnare il mio codice (con una nota che dice "deve essere testato!" ). Non ho problemi a ripulire oltre 1.000 righe di codice C o C ++ in pochi minuti.

Debug e test d'altra parte è ciò che richiede un po 'di tempo. Sorgono errori logici per ogni sorta di ragioni e devo ancora incontrare un compilatore che mi parlerà della subroutine che ho completamente dimenticato di scrivere, o noterò che il mio albero binario non funziona perché ho incollato node->leftquando avrebbe dovuto essere node->right.

Mentre penso che in genere non sia saggio combattere con un intervistatore, direi che se ritieni che valga la pena difendere il tuo stile, avresti dovuto far notare che ti sei lasciato abbastanza tempo per eseguire il debug del codice che hai scritto. Questa è la cosa che nessun buon programmatore trascura mai.

ps - Se ti avessi visto rivedere il codice leggendolo, ti avrei assunto sul posto. Questo è quello che fa un professionista, ogni volta.


4
"Devo ancora incontrare un compilatore che mi parlerà della subroutine che ho completamente dimenticato di scrivere." Mi affido totalmente al compilatore per dirmi quando non ho completato modifiche di vasta portata. A volte ho anche rinominato una variabile per impedire la compilazione corretta fino a quando non ho controllato ogni istanza del suo utilizzo e dato loro tutto il nuovo nome. Non capisco come si possa dire di non aver trovato un compilatore che non ti avvertirà se manca qualcosa. A meno che tu non stia scrivendo sottoprogrammi segnaposto vuoti e poi ti dimentichi di loro, nel qual caso il paradiso ti aiuterà.
Ian Goldby,

@par Grazie per la risposta; È bello sapere che non sono l'unico a codificare in questo modo!
CaptainCodeman,

3
@CaptainCodeman Sono ben consapevole che gli errori logici sono più insidiosi degli errori del compilatore. Ma era la sua affermazione sul fatto che un compilatore non fosse in grado di dirti del codice mancante che volevo contestare. A meno che tu non stia deliberatamente scrivendo un codice errato (o incompleto) che compila ..., ma che piuttosto sconfigge l'argomento che gli errori che il compilatore non può rilevare sono il vero problema dell'IMO. Cavolo, uso persino il compilatore per spostare il cursore sulla riga in cui ho bisogno di scrivere un po 'di codice. Ma forse sono molto pigro.
Ian Goldby,

1
@IanGoldby: hai perso del tutto il punto e sarei persino arrivato al punto di dire che hai scelto di distorcere le mie parole. Il compilatore non può avvisarti del codice mancante nello stesso modo in cui non posso dirti cosa mangerai a colazione domani. Introdurre intenzionalmente errori di sintassi in modo che il compilatore ti ricordi qualcosa è una tecnica di programmazione; non si qualifica come un errore o non dà al compilatore superpoteri psichici.
par

1
@par mi scuso per l'offesa che ho ovviamente causato dal mio commento - non era inteso e certamente non intendevo travisare quello che hai detto. Ora vedo che quando scrivi un codice incompleto che comunque si compila, lo trasformi in una pratica per assicurarti che non possa essere dimenticato aggiungendo #warning o TODO. Questa è una tecnica legittima. L'importante, su cui siamo entrambi d'accordo, è che il codice che viene compilato ma non funziona è molto più pericoloso del codice che non viene compilato.
Ian Goldby,

3

No, non è irragionevole trattenere la compilazione fino a quando non hai fatto una quantità sufficiente di codice (e una "quantità sufficiente" dipende dal programmatore e dal codice che viene scritto).

Ad esempio, se sei un programmatore fantastico che si prende il suo tempo per farlo bene e non stai scrivendo enormi quantità o codice contorto, compilare regolarmente è uno spreco, e probabilmente anche una distrazione. In caso contrario, compilare ogni funzione può essere una buona cosa. Dipende dalla persona.

Come contro-esempio, immagina di scrivere codice JavaScript: non esiste un compilatore. Invece (data la natura della maggior parte del codice JavaScript) avresti eseguito il programma (o aggiornato la pagina) per vedere i risultati della tua codifica. Ora, non puoi farlo finché non hai scritto abbastanza codice per avere un senso. Di conseguenza, gli sviluppatori JavaScript tendono a "compilare" il più spesso possibile, il che non è necessariamente molto frequente.

In breve, non c'è una risposta corretta qui: l'intervistatore non ha torto, ma nemmeno tu. Fai ciò che ti rende produttivo e dimentica ciò che qualcuno ti dice che dovresti fare. Ci sono molti più importanti fattori nella codifica che la tua tendenza a colpire F7regolarmente (o meno) non ha assolutamente alcuna conseguenza.


Il tuo secondo paragrafo non è chiaro; potresti volerlo modificare, per essere chiaro se il "fantastico programmatore" dovrebbe compilare regolarmente o meno. (Hai aggiunto una "t" e hai cambiato "no" in "non"?)
DougM,

@DougM - ta muchly.
gbjbaanb,

Molto spesso il codice di scripting viene sviluppato "live", ovvero viene eseguito in ambiente REPL. Quindi la "compilazione" si verifica in ogni momento, anche la maggior parte del codice scritto nel file sorgente è stato eseguito una volta. Non tutti scrivono questo codice di script in questo modo, ma direi che qualcuno era abituato e affezionato alla relativa "sicurezza" dei linguaggi tipicamente statici e agli errori del compilatore dati da un codice errato, dovrebbero funzionare in questi linguaggi.
hyde,

2

Con un buon ambiente di sviluppo vedo poche ragioni per compilare a meno che tu non stia pianificando di testare il codice. Gli strumenti di controllo della sintassi in background catturano quasi tutto ciò di cui l'intervistatore sembra parlare, anche se ammetto che ci sono ancora alcuni casi (che coinvolgono cambiamenti che si propagano tra i file) che non sono sempre completamente identificati.

Detto questo, cercherò di compilare ed eseguire praticamente la più piccola unità di codice che può effettivamente produrre un risultato. Mezz'ora fa stavo creando un mezzo per stampare alcuni risultati di ricerca e ho fatto una mezza dozzina di stampe di prova (su .pdf, non su carta) apportando modifiche al risultato per renderlo migliore - un tasso di circa 1 compilazione per 10 Linee.


1

Secondo me e nella mia esperienza, la compilazione di un pezzo di codice è essenzialmente casuale, implicando cose come la mancanza di punti e virgola e ha poco a che fare con la correttezza del programma sottostante. (Per me, concentrarsi sulla compilazione è come far scorrere un articolo attraverso un controllo ortografico senza correzione di bozze per controllare la grammatica.)

La mia esperienza è molto diversa: meno del 5% degli errori di compilazione che ottengo riguardano la sintassi . Conosco bene la lingua, quando ricevo errori si tratta principalmente di errori di tipo, che mi dicono che la semantica non è corretta.

Questo è il motivo per cui sono felice di beneficiare il più rapidamente possibile del feedback del mio compilatore. Hai mai provato a usare un IDE che sottolinea gli errori di compilazione in tempo reale? Avere un ciclo di feedback più breve può essere molto prezioso.

Se mi dai un pezzo di codice incompleto, la prima cosa che farò sarà leggerlo. Non proverò nemmeno a compilarlo finché non saprò cosa sta facendo il codice e so che l'algoritmo è corretto.

Se devi lavorare su un codice scritto da qualcun altro, non hai sempre il tempo di leggere tutto. La buona notizia è che il codice ben scritto ha un basso accoppiamento e dovrebbe consentirti di ragionare in modo indipendente solo sulla parte del codice di cui hai bisogno.

In quei casi devi presumere che il codice che non hai ancora letto sia corretto e investigare pigramente quando c'è un problema.

"ottenere la compilazione del codice" per una determinata lunghezza del codice generalmente comporta la correzione di un numero costante di errori di compilazione e richiede un tempo abbastanza costante, che dovrebbe essere lo stesso sia che lo si faccia dopo aver finito di scrivere il codice, sia se si interleave con il tuo tempo di programmazione.

Il cambio di contesto è costoso per il tuo cervello, quindi correggere piccoli errori non appena li scrivi può essere più efficiente.

EDIT: posso anche fare un'analogia con il controllo delle fonti, quando un intero team sta lavorando sulle stesse fonti. Compilare mentre procedi è come fare frequenti impegni, aiuta a evitare di avere molto dolore alla fine quando devi unire e sistemare tutto.

Dici che disabiliti cose come linee rosse sotto il tuo testo. Lo fai anche quando scrivi un'email o scrivi un documento tecnico? Quindi devi rileggere tutte le pagine invece di correggere gli errori man mano che procedi.

Un altro vantaggio è che, quando si lavora sul codice, se lo si continua a compilare o quasi compilare in ogni momento, è possibile beneficiare di molte funzionalità IDE basate su semantica (rinominazione sicura, refactoring, ricerca degli usi di un simbolo ...) .

Se vuoi avere una migliore comprensione di come queste funzionalità aiutano, potresti provare ad abilitarle e ad esercitarti, a sperimentare te stesso i loro benefici. Potresti anche provare a fare un po 'di programmazione in coppia con chiunque sia abituato a loro, e vedere come ne traggono vantaggio.


1
Di solito disattivo le fastidiose "funzionalità" del compilatore come la formattazione automatica, il disegno di linee rosse sotto il tuo testo, ecc. Poiché trovo che sono più produttivo senza queste funzioni stupide.
CaptainCodeman,

1

Ci ho pensato un po 'di più, perché pensavo che ci fosse qualcosa di molto, molto sbagliato nell'intervistatore e non sapevo esattamente cosa fosse. Ecco il problema: per qualsiasi codice che ho scritto negli ultimi venti anni, il tempo necessario per trasformare un algoritmo praticabile in codice che viene compilato è stato minimo. Qualsiasi guadagno in termini di efficienza in quell'area ha un impatto così ridotto sul tempo totale di sviluppo che è totalmente trascurabile, e un intervistatore che rifiuta un candidato per le inefficienze percepite in quell'area non ha idea di cosa renda un buon sviluppatore.

La maggior parte del tempo dovrebbe essere dedicato alla raccolta di informazioni su ciò che il codice dovrebbe fare, alla raccolta di informazioni e specifiche sui servizi esterni che devono essere utilizzati, alla creazione di un design globale che porterà a un codice corretto e gestibile anziché a quello di un hacker e alla ricerca di algoritmi ciò porterà a un codice funzionante anziché a un codice che viene patchato insieme fino a quando non funziona (codice che ovviamente non ha errori contro codice che non ha errori evidenti).

Quindi arriva un po 'di tempo a scrivere codice che viene compilato.

Quindi arriva una maggiore quantità di tempo speso per assicurarsi che il codice funzioni e per assicurarsi che sappiamo che il codice funziona e continuerà a funzionare. Ciò viene fatto scrivendo unit test, passando attraverso il codice e in larga misura avendo in primo luogo un codice ben progettato.

Questo intervistatore si è concentrato su qualcosa che è coperto da dieci parole nella mia risposta. Che rappresentano il 10 percento o meno dell'orario di lavoro effettivo. E ha un'influenza pressoché nulla sulla capacità di quello sviluppatore di produrre codice affidabile e funzionante.


Questo ha molto senso. A mio avviso, un buon sviluppatore dovrebbe essere in grado di scrivere il codice su carta tutto il giorno, quindi alla fine della giornata digitarlo.
CaptainCodeman,

1

Il vantaggio della "compilazione man mano che procedi" è che ricevi un feedback costante e non avrai la possibilità di andare molto lontano prima di essere spinto nella giusta direzione. Per un programmatore competente come te, questa non è una grande considerazione, ma per molti altri lo è. Detto in altro modo, "compilare mentre procedi" è un modo di "ridurre al minimo la perdita massima", anche se ci sono alcune potenziali perdite di efficienza nel tuo caso.

Le aziende in questi giorni non sono solo interessate a un prodotto finito. Vogliono sapere che è sempre stato "sotto controllo". Per loro, "arrivarci è metà del divertimento".


questo non sembra offrire nulla di sostanziale rispetto a quanto pubblicato nelle precedenti 16 risposte
moscerino del

2
Grazie ma di che tipo di perdita stiamo parlando? Sicuramente, a meno che tu non abbia fatto qualcosa di drastico come scrivere accidentalmente nella lingua sbagliata, non dovresti mai riscrivere alcun codice semplicemente a causa di errori di compilazione.
CaptainCodeman,

@CaptainCodeman: fa stare meglio le aziende ed è una forma di "assicurazione". È qualcosa che costa denaro, ma fa sì che la maggior parte delle persone (compresi i gestori) "dormano meglio di notte".
Tom Au,

@gnat: Il punto che stavo cercando di evidenziare era che la maggior parte dei benefici erano benefici a livello "aziendale", ed è qualcosa che il programmatore dovrebbe fare perché gli ha detto il capo, non perché il programmatore pensa che sia giusto o sbagliato.
Tom Au,

ben punti a favore del "ciclo di feedback più breve" sono già stati fatti e ben spiegati nella prima risposta qui; Sinceramente non vedo come il ripugnante tentativo di indovinare "le aziende di questi tempi" aggiunga qualcosa di degno di ciò che è già stato dichiarato
moscerino del

1

Le altre risposte qui offrono una buona difesa per la compilazione frequente sul lavoro , ma poiché la tua domanda è centrata sulle interviste , mi piacerebbe affrontarlo da questo punto di vista.

Nelle mie interviste, faccio l'esatto contrario: i candidati non possono usare un compilatore. Scrivono brevi programmi alla lavagna e poi ne discutiamo. Ho scoperto che troppi sviluppatori usano il compilatore (o interprete) come stampella, e questo è uno spreco di tempo molto più grande della compilazione troppo di rado. Se ti sto offrendo molti soldi e non riesci nemmeno a scrivere correttamente FizzBuzz senza un compilatore, non lo taglierai mai a lungo termine, lavorando su problemi 100 volte più difficili degli esercizi giocattolo nell'intervista. Eppure questi semplici esercizi eliminano più candidati rispetto a qualsiasi altra parte dell'intervista.

L'obiettivo di un colloquio è valutare l'adattamento reciproco del candidato e del business. Una buona domanda per un colloquio dovrebbe indicare gli obiettivi della domanda e come verrà valutato l'intervistato. Fare una domanda trabocchetto all'intervistato e poi penalizzarlo per non conoscere la risposta nascosta non aiuta l'intervistatore o l'intervistato. Sfortunatamente, la maggior parte dei programmatori, anche di quelli più anziani, non è addestrato a intervistare altri programmatori, quindi si basano solo sui luoghi comuni e pongono gli stessi tipi di domande che sono state poste durante il colloquio, senza pensarci troppo se si tratta di tecniche efficaci per valutare i candidati o no.

Non sto affermando che il mio approccio sia "l'unico vero modo", ma mi è servito molto bene. Come tante metodologie software che iniziano con una lettera maiuscola, esiste un numero uguale di "mandati" per l'intervista. Sono tutti a castello. Devi fare ciò che funziona per te e la tua azienda.


0

Nei progetti più grandi, con diverse subroutine, si desidera testare queste parti, prima di usarle nello schema più grande, poiché è molto più semplice eseguire il debug se si sa che alcune parti funzionano già.

Per testare questi pezzi più piccoli, è necessario compilare.

È possibile che l'intervistatore confonda questa situazione con un piccolo programma che non è progettato in questo modo.


0

Per quanto riguarda la seconda intervista, un vantaggio della compilazione è che puoi osservare, in pochi secondi, ciò che i programmi fanno (o no). Da lì è più facile leggere il codice e concentrare i tuoi sforzi sulle parti pertinenti. Forse è quello che si aspettava l'intervistatore.

Leggere una base di codice sconosciuta come questa dall'inizio alla fine può essere piuttosto improduttivo (non sei un compilatore), mentre la compilazione / esecuzione dell'applicazione ti darà rapidamente un quadro più ampio.


questo non sembra offrire nulla di sostanziale rispetto a quanto pubblicato nelle precedenti 15 risposte
moscerino del
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.