Qual è il modo migliore per evitare la catastrofe causata da negligenza? [duplicare]

26

Sono stato un programmatore per quasi 1 anno.

Come adulto ADHD, naturalmente non ho la stessa forza di attenzione sugli oggetti ordinari come fanno i miei colleghi.

E trovo che la catastrofe fatta da me sia di solito causata da banale negligenza.

Per oggi, ho trovato che il processo cron sul server è crollato al mattino.

Dopo mezz'ora di debug. Ho trovato che ho scritto nel cron

* 4 * * * sh daily_task.sh

invece di

0 4 * * * sh daily_task.sh

Che esegue l'enorme shell 59 volte al mattino invece del previsto 1 volta.

Esiste qualche tipo di comportamento coltivabile o qualche strumento o qualcosa che possa aiutarmi a ridurre almeno questo tipo di errore?

Come fai a evitare questo tipo di errore?

    
posta Zen 29.01.2015 - 05:18
fonte

7 risposte

47

Is there some kind of cultivatable behaviour [...] that can help me at least reduce such kind of mistake

Assolutamente, si chiama principio dei quattro occhi .

Se avessi mostrato la tua iscrizione crontab a una seconda persona (una persona che conosce cron, ovviamente), è probabile che l'errore sarebbe stato evitato.

Nella programmazione, quando si parla di questo, la gente pensa principalmente a recensioni di codice, ma in realtà è la stessa cosa.

    
risposta data 29.01.2015 - 08:30
fonte
15

Non hai bisogno dell'ADHD per avere questo problema. Potrebbe essere che lavori in un ambiente in cui ti interrompi spesso o dove lavori su più cose contemporaneamente. Quindi perdere la traccia dei tuoi progressi o commettere piccoli errori è quasi garantito.

C'è una cosa che puoi fare per ridurre quegli errori: test basati sulle specifiche.

Innanzitutto, annota le specifiche nel modo più dettagliato possibile. In caso di codice, questo dovrebbe essere sotto forma di test automatici. Il modo migliore è seguire TDD. Quindi quando improvvisamente ti distrai, i tuoi test ti diranno cosa hai già fatto e ti permetteranno di riprendere rapidamente dove sei finito. Inoltre, rende più facile il test di regressione.

In un caso, in cui il codice di test non è possibile, assicurati di avere qualcun altro da esaminare ciò che hai creato e fargli testare il software in base alle specifiche. Dovresti sempre testare il software in ambiente di testing prima che entri in produzione. Il problema di cui parli potrebbe essere facilmente rilevato eseguendolo per un giorno nell'ambiente di testing e controllando i log.

    
risposta data 29.01.2015 - 08:17
fonte
12

Devi sempre essere almeno a due passi dal disastro. Ciò significa che non spingere mai direttamente qualcosa che hai appena scritto in produzione. Puoi testarlo, o lo hai testato, o lo hai rivisto, o trovare un altro modo per avere un percorso in due fasi fino al disastro. A volte lascerò qualcosa per il giorno successivo e rivedrò di nuovo il mio lavoro prima di impegnarmi.

Nei casi in cui qualcosa è veramente critico, aggiungi una terza fase: un secondo revisore, un secondo test indipendente, ecc ...

Errare è umano. I nostri cervelli non sono costruiti per la precisione. Ognuno fa errori, tutti scrivono bug, anche se alcuni più di altri (fare attenzione paga ancora). Devi capire un processo che si basa sul presupposto che il lavoro di qualcuno sia difettoso.

    
risposta data 29.01.2015 - 09:27
fonte
6

Le risposte precedenti menzionavano due punti:

  • recensioni.

  • Test.

ma ci sono anche tre elementi aggiuntivi che possono aiutare:

  • Migliore visualizzazione.

    Usando strumenti che ti consentono di visualizzare meglio ciò che fai, potresti rilevare errori in precedenza. Questo è particolarmente illustrativo con i lavori di cron. Immagina di avere uno strumento di visualizzazione che ti mostra graficamente quando i lavori cron che hai definito sono eseguiti. Immediatamente, vedi che c'è qualcosa che non va.

    L'evidenziazione della sintassi, ad esempio, è lo strumento di visualizzazione degli sviluppatori più popolare, ed in effetti aiuta a trovare errori nelle fasi iniziali (spesso entro secondi dopo aver scritto qualcosa di sbagliato), prima dell'esecuzione del compilatore o dei test.

  • Monitoraggio continuo.

    Perché il server è collassato? Non c'era un modo per vedere che qualcosa andava storto prima cose brutte?

    I server avrebbero dovuto essere monitorati correttamente. O una persona o un'app dovrebbe aver visto che dopo l'ultima modifica, l'utilizzo della CPU è aumentato da, ad esempio, una media del 42% a una media del 100% e potrebbe fare qualcosa per impedire al server di collassare.

    Questo mi porta all'integrazione continua e più specificamente alla distribuzione continua. Nella distribuzione continua, quando si esegue un commit, la nuova revisione viene creata, testata e distribuita alla produzione su alcuni server. Quindi, quei server sono guardati da un'app. Se l'app rileva un aumento anomalo dell'utilizzo delle risorse o una quantità anomala di avvisi in syslog provenienti da tali server, i server vengono ripristinati allo stato precedente.

  • Rigore.

    Le linee guida e le regole sono di solito fastidiose (non convinto? Prova a scrivere una piccola app C # conforme alle analisi StyleCop e Code e ha buoni risultati con le metriche Code e ha una copertura di codice decente!) ma anche particolarmente utile. Questo è il motivo per cui alcuni progetti mirano a zero avvisi con checker statici e avvisi zero con il compilatore impostato su un livello massimo: gli errori trovati in precedenza sono errori che non devi risolvere quando è troppo tardi.

    Anche se questo non è d'aiuto con i lavori di cron, aiuta quando si scrive codice.

risposta data 29.01.2015 - 09:59
fonte
4

Penso che la soluzione diretta, specialmente per il tipo di problema che hai esemplificato, sia quella di fare errori vistosi .

Se guardi le due linee che hai dato, la differenza è in realtà piuttosto sottile. Devi avere molta sintassi dettagliata e sfumata "nella tua mente" quando la leggi se vuoi cogliere l'errore. Devi anche tenere d'occhio le caratteristiche visive difficili da vedere ( * e 0 possono essere facili da confondere).

Ad esempio, nel tuo esempio, se la sintassi cron era simile alla seguente:

minute=0 hour=4 day=every week=every month=every year=every

È meno probabile che lo confondano con:

minute=every hour=4 day=every week=every month=every year=every

Non puoi davvero cambiare la sintassi di cron, ma tu potresti scrivere un semplice programma CLI per te stesso che prende argomenti denominati come sopra, e poi li passa al cron effettivo. Dovresti rivedere attentamente il codice che converte dagli argomenti nominati, ma devi farlo solo una volta, quindi puoi permetterti di concentrarti davvero e fare il miglio in più nel controllo degli errori - stampare il codice, leggere e spiegare a te stesso ad alta voce e così via.

Quando hai un programma come questo, puoi anche aggiungere un controllo di integrità. Dopo aver creato un nuovo cron job, fallo pubblicare:

This new job will run 1 times a day.

(forse cerca di trovare il periodo di tempo più breve che si traduce in un numero intero)

Ora sarà davvero difficile per te commettere lo stesso errore. Il tuo compromesso è:

  1. Ora sono necessarie più sequenze di tasti per digitare i comandi e appaiono più impegnativi (probabilmente perché cron ha ricevuto la sintassi che era in primo luogo).
  2. Hai speso tempo e sforzi per impostare il modello di interfaccia resistente agli errori e il controllo di integrità (ma in questo caso puoi probabilmente farlo in un'ora o due).

Ora, non sto necessariamente suggerendo di farlo per cron . Sembra un po 'eccessivo, a meno che tu non imposti e modifichi le attività su cron molto spesso. Ho appena usato il tuo esempio per illustrare i due trucchi utili: controlli Sanity e preferendo la sintassi che rende gli errori molto evidenti anche se non li cerchi. L'idea è di assicurarsi che gli errori odorino .

Con la sintassi, le due cose ovvie che puoi fare sono:

  1. Seleziona strumenti e linguaggi con sintassi più resistente agli errori, ad esempio C # rispetto a Perl. Notate di nuovo il compromesso tra la cattura degli errori velocemente e il dover fare più lavoro.
  2. Avvolge la sintassi scadente con una sintassi migliore. Ad esempio, crea la tua funzione wrapper per le funzioni con un nome errato con nomi di argomenti ambigui, crea il tuo programma wrapper per strumenti arcani, usa un editor che supporta l'evidenziazione dei colori e così via.

Non ha senso fare tutto questo in ogni momento. Vuoi chiedertelo, cosa conta di più in un dato compito: la correttezza o il tuo tempo? È inutile contestare che l'hacking insieme a uno script veloce in Perl stia andando a ottenere il lavoro più velocemente della scrittura di un programma C # ben strutturato con una chiara gerarchia OOP. Se non sei preoccupato per gli errori e hai fretta, perché preoccuparsi? Ma tieni a mente che ogni volta che prendi questa scorciatoia, stai facendo una scommessa: scommetti molta frustrazione e digrignare i denti con la speranza che non dovrai tornare indietro ed estendere il tuo progetto nel lontano futuro, molto tempo dopo hai dimenticato come avrebbe dovuto funzionare (o che non ti rendessi conto a metà strada che il tuo design originale non funzionerà, e ora deve essere radicalmente modificato).

    
risposta data 29.01.2015 - 23:49
fonte
2

Sono d'accordo con tutte le altre risposte, ma l'idea di codifica difensiva potrebbe anche aiutare qui.

Quando pratichi la codifica difensiva, scriviamo il nostro codice in base al presupposto che verrà usato in modo errato; sia da noi, sia da qualcun altro. In questo caso, lo script della shell è stato utilizzato in modo errato (eseguito 59 volte invece di una volta).

Come potremmo difenderci da questo? Un modo semplice ma approssimativo sarebbe quello di registrare un timestamp da qualche parte all'inizio della corsa, e solo eseguire se viene trovato il timestamp e più, diciamo, di 20 ore.

Il problema con questo approccio a grana grossa è che potremmo voler attivare manualmente lo script, ad es. se parte della sua funzionalità deve essere eseguita di nuovo, ma non interamente. In tal caso, un approccio a grana fine sarebbe meglio, ad es. "se l'ultimo backup del DB è più vecchio di 20 ore, esegui il backup del DB", "se l'ultimo annuncio è stato inviato più di 20 ore fa, invia un annuncio", ecc.

    
risposta data 29.01.2015 - 13:46
fonte
1

Oltre a test ...

Ho trovato che stampare il codice su carta, quindi eseguire il codice in un debugger e spuntare ogni riga una volta che ho confermato che tutti i valori erano come previsto nel debugger era un ottimo modo. Questo ti porta a guardare il tuo codice in un altro modo.

Guidare il "controllo del debugger" con unit test è bello ...

    
risposta data 29.01.2015 - 11:48
fonte

Leggi altre domande sui tag