Classificazione di un algoritmo: leggibilità e compattezza [chiuso]

4

Considera la seguente domanda di esame / intervista:

Implementa la funzione strcpy () in C: void strcpy(char *destination, char *source);

La funzione strcpy copia la stringa C puntata da source nella matrice puntata da destination , incluso il carattere nullo terminante. Supponiamo che la dimensione dell'array puntata da destination sia abbastanza lunga da contenere la stessa stringa C di source , e non si sovrapponga in memoria con source .

Supponiamo che tu fossi l'intervistatore / esaminatore, come valuteresti le seguenti risposte a questa domanda?

1)

void strcpy(char *destination, char *source)
{
  while (*source != '
void strcpy(char *destination, char *source)
    {
       while (*(destination++) = *(source++)) ;
    }
') { *destination = *source; source++; destination++; } *destination = *source; }

2)

void strcpy(char *destination, char *source)
{
  while (*source != '
void strcpy(char *destination, char *source)
    {
       while (*(destination++) = *(source++)) ;
    }
') { *destination = *source; source++; destination++; } *destination = *source; }

La prima implementazione è semplice: è leggibile e adatta ai programmatori.

La seconda implementazione è più breve (una riga di codice) ma meno adatta ai programmatori; non è così facile capire come funziona questo codice, e se non hai familiarità con le priorità in questo codice, allora è un problema.

Mi chiedo se la prima risposta mostrerà più complessità e pensiero più avanzato, negli occhi dell'analista, anche se entrambi gli algoritmi si comportano allo stesso modo e sebbene la leggibilità del codice sia considerata più importante della compattezza del codice. Mi sembra che, dal momento che creare un algoritmo, questo compatto sia più difficile da implementare, mostrerà un livello superiore di pensiero come risposta in un esame. Tuttavia, è anche possibile che un intervistatore / esaminatore consideri la seconda risposta non valida perché non è leggibile.

Vorrei anche ricordare che questo non è specifico per questo esempio, ma generale per la leggibilità del codice e la compattezza quando si implementa un algoritmo, in particolare negli esami \ interviews.

    
posta amiregelz 02.09.2012 - 17:11
fonte

8 risposte

8

La seconda risposta mostra che lo sviluppatore comprende meglio i casi edge C. Tuttavia, la prima versione è più facile da leggere e comprendere perché non richiede la comprensione di questi casi limite.

Se ti viene fatta la domanda, chiedi all'intervistatore o all'esaminatore cosa stanno cercando. In caso di dubbio, ogni volta leggi il codice leggibile su compattezza. Gli intervistatori e gli esaminatori possono raggiungere rapidamente l'affaticamento decisionale e renderlo più facile per loro ti aiuterà.

Se l'intervistatore o l'esaminatore ne vuole di più, fai prima la versione leggibile, poi dà loro la seconda versione e spiega perché funziona. Questo ti aiuterà anche perché puoi fare salti concettuali più brevi.

    
risposta data 02.09.2012 - 17:26
fonte
7

Tutto dipende dai requisiti per quel pezzo di codice.

  • È pensato per essere veloce?
  • Vuol dire usare memoria minima?
  • È pensato per essere affidabile?
  • Significava essere mantenibile?

L'altra cosa che devi considerare è la linea guida:

Make it right, then make it fast

Il primo esempio sarebbe la prima implementazione ideale della funzione che soddisfi i requisiti 3 rd e 4 th della mia lista precedente. Sarebbe anche sufficiente per un'applicazione che non fosse critica nel tempo o limitata nella memoria, ecc. Il secondo esempio potrebbe essere quello che si codificherebbe se fosse necessario soddisfare 1 st e 2 e o in seguito hai scoperto problemi con il tuo codice iniziale (improbabile in questo caso specifico).

Per quanto riguarda un tester, il completamento effettivo non dovrebbe essere un fattore nel determinare se il codice supera o meno i test. Tutto ciò che conta è che:

  1. Produce il risultato corretto
  2. Lo fa in un tempo "ragionevole" (che varierà da un'applicazione all'altra)
  3. Utilizza una quantità "ragionevole" di risorse del computer (idem)

Tuttavia, rileggendo la tua domanda, vedo che stai usando la parola "tester" per la persona che conduce l'intervista. In questo caso, mentre stai guardando il codice per giudicare il livello di abilità o competenza del programmatore, il secondo esempio sarebbe "migliore" in quanto mostra che il programmatore comprende come funzionano i puntatori e l'incremento del puntatore.

L'avvertenza è che a meno che il codice non sia veramente "scrivi una volta" (cioè non verrà mai più guardato) vorresti il codice nel primo esempio.

    
risposta data 02.09.2012 - 17:27
fonte
6

In C l'espressione x ++ = y ++ è estremamente comune e quindi facilmente comprensibile, e IMO dovrebbe essere preferito per il più lungo x = y; x ++; y ++; quando possibile in quanto esprime meglio l'INTENTO. Questo lascia il controllo per terminare il ciclo.

while(*source != '
while(*source)
')

vs

while(*destination++ = *source++){}

vs

while(*source != '
while(*source)
')

Comprendere il 2 ° e il 3 ° dipende dalla comprensione di due cose, che C considera zero come falso e tutto diverso da zero per essere vero e che gli operatori di assegnazione restituiscono un risultato.

Entrambi dovrebbero essere radicati anche in un programmatore C minore e facilmente reperibili da quelli provenienti da un'altra lingua.

In breve, non considero il secondo più difficile da leggere, e in effetti trovo il primo più difficile da leggere nel contesto di un programma C - in una lingua senza ++ il prima sarebbe naturalmente richiesto, ma programmare in lingue come se fosse linguaggio b è fonte di confusione. La domanda "perché questo codice lo fa" è molto più difficile di "cosa fa questo codice", e l'utilizzo non standard mi fa chiedere perché ...

Ora, se vuoi segnarli per qualche motivo, non guardare oltre la mancanza di commenti. Quando si tratta di indicazioni, tali restrizioni non dichiarate sono solo supplichevoli di errori.

    
risposta data 02.09.2012 - 20:40
fonte
3

In generale, se chiedo alle persone di scrivere il codice in un'intervista, sto cercando di vedere se scrivono il codice che vorrei fare il debug e mantenere. Ciò mi indurrebbe a preferire risposte come il primo esempio.

Tuttavia, chiunque stia facendo questa domanda specifica probabilmente sta verificando per vedere se l'intervistato conosce il linguaggio molto comune strcpy nel secondo esempio. Questo è un test della loro conoscenza dei puntatori e di C, non della leggibilità o della compattezza del loro codice.

    
risposta data 02.09.2012 - 17:28
fonte
1

Ci sono alcune cose che ti vengono in mente.

Se funziona, dovrebbe essere abbastanza buono. Concentrarsi ossessivamente sulla formattazione del codice non è più produttivo come concentrarsi ossessivamente sull'ottimizzazione prematura. Nella maggior parte dei casi non aggiunge alcun valore.

Hai menzionato " non è così facile capire come funziona questo codice, e se non hai familiarità con le priorità in questo codice, allora è un problema. ". Questo è quindi un problema perché il programmatore non è abbastanza competente con tali strutture . Tali strutture compatte sono in realtà abbastanza comuni in semplici pezzi di codice come questo, e qualsiasi programmatore esperto capisce immediatamente e in realtà li preferisce perché sono semplici .

Questa è una questione di stile, che varia tra le persone. Non penso che ci sia una risposta corretta a domande come questa.

    
risposta data 02.09.2012 - 17:28
fonte
1

Contesto del tester

Per prima cosa, definiamo i tester. La distinzione tra lo sviluppo del software e i ruoli di test del software coinvolge l'accesso al codice sorgente. Gli sviluppatori sono costantemente in contatto con i dettagli del codice, concentrandosi sui test delle unità. I membri del team chiamati tester sono quasi sempre intenzionalmente ignari dei più bassi livelli di implementazione, concentrandosi su test di integrazione, test di stress, test di carico, test di compatibilità. È quindi più probabile che un tester rilevi la struttura del codice sorgente quando un errore di battitura rompe una compilazione o quando una traccia dello stack raggiunge i registri.

L'uso di qualsiasi stile che gli altri membri del tuo team trovano facile da mantenere di solito significa che i tester vedranno meno rotture di build e carenze comportamentali nel lungo periodo. In caso di dubbi, chiedi alla tua squadra o segui la semplicità.

Contesto di revisione del codice

Quando il codice viene esaminato da un altro sviluppatore prima del commit, ovviamente le differenze nello stile del codice sono importanti. Quello standard all'interno dell'organizzazione / prodotto / progetto, o altrimenti familiare agli altri membri del team, è quello corretto. Gli altri non sono corretti - meno punti e rielaborazione.

Se uno sviluppatore può spiegare perché una particolare pratica è a suo avviso migliore dello standard attuale, e perché lo standard dovrebbe essere aggiornato (questa domanda fornisce già un sacco di argomenti disponibili in entrambi i casi), cioè più punti, ma lì non c'è motivo per deviare intenzionalmente per primo e spiegare solo in secondo luogo.

Contesto intervista

Durante un'intervista, errori di battitura, differenze di indentazione, ecc., non contano davvero. Le tue due implementazioni compilano lo stesso identico codice binario. Rispetto alle implementazioni standard (destinate allo scopo) della stessa attività, entrambi i nostri esempi equivalenti sono molto più facili da leggere, molto più lenti e anche molto più sicuro da usare per le persone che non conoscono bene la libreria C standard. Ciò è in parte dovuto al fatto che la parte "non sovrapposta" dell'attività potrebbe essere stata convertita nella parola chiave restrict ma non lo è stata.

La differenza nello stile di codifica dice cose sull'anima dello sviluppatore. Entrambi gli stili di codifica visualizzati sono completamente standard del settore, quindi sarebbe sciocco giudicare l'esperienza o le abilità del candidato basandosi esclusivamente sullo stile di codifica. Tuttavia, è possibile che i due programmatori alla fine offrano ruoli orientati in modo diverso, o che una particolare organizzazione possa trovare un adattamento solo con uno di questi due stili di personalità.

    
risposta data 02.09.2012 - 19:42
fonte
1

Perché non puoi dare entrambe le risposte?

Una volta qualcuno mi ha detto di avere la risposta sbagliata in un'intervista e di negarmi il lavoro, anche se la mia procedura ha funzionato. Voleva il modo rapido invece del modo leggibile (era una società di giochi). Ha spiegato la sua scorciatoia intelligente, ma è stata comunque una grande delusione per me. Mi sono sentito imbrogliato per un paio di settimane prima di alzare lo sguardo e provare la sua soluzione. Si è scoperto un bug grave che avrebbe impedito il suo funzionamento!

Con il senno di poi, avrei dovuto continuare a lavorare sul problema subito dopo aver lasciato l'intervista (o almeno il giorno dopo, quando mi sono calmato). In questo modo avrei potuto contattarlo e continuare la discussione sul problema, magari inviandogli un caso di prova via email per dimostrare dove falliva la sua soluzione preferita e suggerito una correzione che risolvesse il problema più vicino alla sua strada, ma senza il bug.

La maggior parte dei candidati a cui ho fatto domande nelle interviste li ha fatti sbagliare. Alla fine ho rinunciato e ho appena chiesto ai candidati di descrivere un progetto recente di cui si sentivano entusiasti. Questa è probabilmente una domanda di intervista migliore in ogni caso. Poiché è a tempo indeterminato, si ha un'idea dello stile e della prospettiva di qualcuno, nonché delle proprie conoscenze e abilità. Se qualcuno mi avesse mai dato due risposte corrette a una domanda e discusso i punti di forza e di debolezza relativi, penso che sarei svenuto. Qualcuno del genere dovrebbe essere un serial killer condannato e un molestatore sessuale per non ottenere il lavoro! Forse non stavo assumendo dal miglior pool di talenti, ma ce l'hai.

    
risposta data 03.09.2012 - 20:10
fonte
1

The first implementation is straightforward - it is readable and programmer-friendly.

The second implementation is shorter (one line of code) but less programmer-friendly; it's not so easy to understand the way this code is working, and if you're not familiar with the priorities in this code then it's a problem.

Hai la tua risposta lì.

Quando gli intervistatori guardano il tuo codice, vedranno anche il tuo stile di codifica. La leggibilità è importante per il codice di produzione, quindi prova a mostrare loro che puoi scrivere tale codice.
Per un esame dovresti mirare anche alla comprensibilità, quindi il tuo codice non è erroneamente determinato per essere difettoso.

    
risposta data 03.09.2012 - 18:39
fonte

Leggi altre domande sui tag