Gli errori più imbarazzanti della mia carriera di programmatore (finora)

Gli errori più imbarazzanti della mia carriera di programmatore (finora)
Come si suol dire, se non ti vergogni del tuo vecchio codice, non stai crescendo come programmatore e sono d'accordo con questa opinione. Ho iniziato a programmare per divertimento più di 40 anni fa e professionalmente 30 anni fa, quindi ho commesso molti errori. molto. Come professore di informatica, insegno ai miei studenti a imparare dagli errori: i loro, i miei e quelli degli altri. Penso che sia ora di parlare dei miei errori per non perdere la modestia. Spero che possano essere utili a qualcuno.

Terzo posto: compilatore Microsoft C

Il mio insegnante di scuola credeva che Romeo e Giulietta non potessero essere considerati una tragedia perché i personaggi non avevano alcun senso di colpa tragico: si comportavano semplicemente in modo stupido, come dovrebbero fare gli adolescenti. Allora non ero d’accordo con lui, ma ora vedo nella sua opinione un briciolo di razionalità, soprattutto in relazione alla programmazione.

Quando finii il secondo anno al MIT, ero giovane e inesperto, sia nella vita che nella programmazione. In estate ho svolto uno stage presso Microsoft, nel team del compilatore C. All'inizio mi occupavo di cose di routine come il supporto alla profilazione, quindi mi è stato affidato il lavoro sulla parte più divertente del compilatore (come pensavo): l'ottimizzazione del backend. In particolare, ho dovuto migliorare il codice x86 per le istruzioni branch.

Deciso a scrivere il codice macchina ottimale per ogni caso possibile, mi sono buttato a capofitto in piscina. Se la densità di distribuzione dei valori era elevata, li ho inseriti tabella di transizione. Se avessero un divisore comune, lo userei per rendere la tabella più compatta (ma solo se la divisione poteva essere eseguita utilizzando spostamento di bit). Quando tutti i valori erano potenze di due, ho eseguito un'altra ottimizzazione. Se un insieme di valori non soddisfaceva le mie condizioni, lo suddividevo in più casi ottimizzabili e utilizzavo il codice già ottimizzato.

È stato un incubo. Molti anni dopo mi dissero che il programmatore che aveva ereditato il mio codice mi odiava.

Gli errori più imbarazzanti della mia carriera di programmatore (finora)

Lezione appresa

Come scrivono David Patterson e John Hennessy in Computer Architecture and Computer Systems Design, uno dei principi fondamentali dell’architettura e del design è generalmente quello di far funzionare le cose il più rapidamente possibile.

L'accelerazione dei casi comuni migliorerà le prestazioni in modo più efficace rispetto all'ottimizzazione dei casi rari. Ironicamente, i casi comuni sono spesso più semplici di quelli rari. Questo consiglio logico presuppone che tu sappia quale caso è considerato comune - e questo è possibile solo attraverso un attento processo di test e misurazione.

A mia discolpa, ho provato a capire come apparivano in pratica le istruzioni dei rami (ad esempio quanti rami c'erano e come venivano distribuite le costanti), ma nel 1988 questa informazione non era disponibile. Tuttavia, non avrei dovuto aggiungere casi speciali ogni volta che il compilatore attuale non era in grado di generare codice ottimale per l'esempio artificiale che avevo creato.

Avevo bisogno di chiamare uno sviluppatore esperto e, insieme a lui, pensare a quali fossero i casi comuni e affrontarli in modo specifico. Vorrei scrivere meno codice, ma è una buona cosa. Come ha scritto il fondatore di Stack Overflow Jeff Atwood, il peggior nemico di un programmatore è il programmatore stesso:

So che hai le migliori intenzioni, come tutti noi. Creiamo programmi e amiamo scrivere codice. Siamo fatti così. Pensiamo che qualsiasi problema possa essere risolto con del nastro adesivo, una stampella fatta in casa e un pizzico di codice. Per quanto sia doloroso per i programmatori ammetterlo, il codice migliore è quello che non esiste. Ogni nuova linea necessita di debug e supporto, deve essere compresa. Quando aggiungi un nuovo codice, dovresti farlo con riluttanza e disgusto perché tutte le altre opzioni sono state esaurite. Molti programmatori scrivono troppo codice, rendendolo nostro nemico.

Se avessi scritto un codice più semplice che coprisse i casi più comuni, sarebbe stato molto più semplice aggiornarlo se necessario. Mi sono lasciato alle spalle un disastro con cui nessuno voleva occuparsi.

Gli errori più imbarazzanti della mia carriera di programmatore (finora)

Secondo posto: la pubblicità sui social network

Quando lavoravo in Google sulla pubblicità sui social media (ricordi Myspace?), ho scritto qualcosa del genere in C++:

for (int i = 0; i < user->interests->length(); i++) {
  for (int j = 0; j < user->interests(i)->keywords.length(); j++) {
      keywords->add(user->interests(i)->keywords(i)) {
  }
}

I programmatori potrebbero vedere immediatamente l'errore: l'ultimo argomento dovrebbe essere j, non i. Il test unitario non ha rivelato l'errore, e nemmeno il mio revisore. Il lancio è stato effettuato e una notte il mio codice è andato al server e ha mandato in crash tutti i computer del data center.

Non è successo niente di brutto. Niente si è rotto per nessuno, perché prima del lancio globale il codice è stato testato all'interno di un data center. A meno che gli ingegneri della SRE non abbiano smesso di giocare a biliardo per un po' e abbiano fatto un piccolo passo indietro. La mattina successiva ho ricevuto un'e-mail con un crash dump, ho corretto il codice e ho aggiunto test unitari che avrebbero rilevato l'errore. Dato che ho seguito il protocollo, altrimenti il ​​mio codice semplicemente non sarebbe stato eseguito, non si sono verificati altri problemi.

Gli errori più imbarazzanti della mia carriera di programmatore (finora)

Lezione appresa

Molti sono sicuri che un errore così grave costerà sicuramente il licenziamento del colpevole, ma non è così: in primo luogo, tutti i programmatori commettono errori e, in secondo luogo, raramente commettono lo stesso errore due volte.

In effetti, ho un amico programmatore che era un brillante ingegnere ed è stato licenziato per aver commesso un solo errore. Successivamente, è stato assunto da Google (e presto promosso): ha parlato onestamente dell'errore commesso in un'intervista e non è stato considerato fatale.

Vota hto dire su Thomas Watson, il leggendario capo dell'IBM:

È stato annunciato un ordine governativo del valore di circa un milione di dollari. IBM Corporation - o meglio, Thomas Watson Sr. personalmente - voleva davvero ottenerlo. Sfortunatamente, il rappresentante delle vendite non è stato in grado di farlo e IBM ha perso l'offerta. Il giorno successivo, questo impiegato è entrato nell'ufficio del signor Watson e ha posato una busta sulla sua scrivania. Il signor Watson non si è nemmeno preso la briga di guardarla: stava aspettando un dipendente e sapeva che si trattava di una lettera di dimissioni.

Watson ha chiesto cosa è andato storto.

Il rappresentante delle vendite ha parlato in dettaglio dello stato di avanzamento della gara. Ha nominato gli errori commessi che avrebbero potuto essere evitati. Alla fine disse: “Signor Watson, grazie per avermi permesso di spiegare. So quanto avevamo bisogno di questo ordine. So quanto fosse importante", e si preparò a partire.

Watson gli si avvicinò sulla porta, lo guardò negli occhi e restituì la busta con le parole: “Come posso lasciarti andare? Ho appena investito un milione di dollari nella tua istruzione.

Ho una maglietta che dice: “Se davvero impari dagli errori, allora sono già un maestro”. Infatti, quando si tratta di errori, sono un dottore in scienze.

Primo posto: API App Inventor

Errori davvero terribili colpiscono un numero enorme di utenti, diventano di dominio pubblico, richiedono molto tempo per essere corretti e sono commessi da coloro che non avrebbero potuto commetterli. Il mio più grande errore soddisfa tutti questi criteri.

Peggio è, meglio è

Leggo saggio di Richard Gabriel di questo approccio negli anni Novanta quando ero studente laureato, e mi piace così tanto che lo chiedo ai miei studenti. Se non lo ricordi bene rinfrescati la memoria, è piccolo. Questo saggio contrasta in molti modi tra il desiderio di “fare le cose per bene” e l’approccio “peggio è meglio”, compresa la semplicità.

Come dovrebbe essere: il design dovrebbe essere semplice nell'implementazione e nell'interfaccia. La semplicità dell'interfaccia è più importante della semplicità dell'implementazione.

Peggio è, meglio è: il design dovrebbe essere semplice nell'implementazione e nell'interfaccia. La semplicità dell'implementazione è più importante della semplicità dell'interfaccia.

Dimentichiamolo per un minuto. Purtroppo me ne sono dimenticato per molti anni.

App Inventor

Mentre lavoravo in Google, facevo parte del team App Inventor, un ambiente di sviluppo online drag-and-drop per aspiranti sviluppatori Android. Era il 2009 e avevamo fretta di rilasciare la versione alpha in tempo in modo da poter tenere corsi di perfezionamento in estate per insegnanti che potevano utilizzare l'ambiente durante l'insegnamento in autunno. Mi sono offerto volontario per implementare gli sprite, nostalgico di come scrivevo giochi sulla TI-99/4. Per chi non lo sapesse, uno sprite è un oggetto grafico bidimensionale che può muoversi e interagire con altri elementi software. Esempi di sprite includono astronavi, asteroidi, biglie e racchette.

Abbiamo implementato App Inventor orientato agli oggetti in Java, quindi contiene solo un mucchio di oggetti. Poiché le palline e gli sprite si comportano in modo molto simile, ho creato una classe sprite astratta con proprietà (campi) X, Y, Speed ​​​​(velocità) e Heading (direzione). Avevano gli stessi metodi per rilevare collisioni, rimbalzi sul bordo dello schermo, ecc.

La differenza principale tra una palla e uno sprite è ciò che viene disegnato esattamente: un cerchio pieno o un raster. Dato che ho implementato prima gli sprite, era logico specificare le coordinate xey dell'angolo in alto a sinistra del punto in cui si trovava l'immagine.

Gli errori più imbarazzanti della mia carriera di programmatore (finora)
Una volta che gli sprite funzionavano, ho deciso che avrei potuto implementare oggetti palla con pochissimo codice. L'unico problema è stato che ho seguito il percorso più semplice (dal punto di vista dell'implementatore), indicando le coordinate xey dell'angolo superiore sinistro del contorno che inquadra la palla.

Gli errori più imbarazzanti della mia carriera di programmatore (finora)
Era infatti necessario indicare le coordinate xey del centro del cerchio, come insegna qualsiasi libro di matematica e qualsiasi altra fonte che menzioni i cerchi.

Gli errori più imbarazzanti della mia carriera di programmatore (finora)
A differenza dei miei errori passati, questo ha colpito non solo i miei colleghi, ma anche milioni di utenti di App Inventor. Molti di loro erano bambini o completamente nuovi alla programmazione. Hanno dovuto eseguire molti passaggi non necessari durante il lavoro su ciascuna applicazione in cui era presente la palla. Se ricordo gli altri miei errori ridendo, questo mi fa sudare anche oggi.

Alla fine ho corretto questo bug solo di recente, dieci anni dopo. “Patch”, non “fixed”, perché come dice Joshua Bloch, le API sono eterne. Impossibile apportare modifiche che avrebbero effetto sui programmi esistenti, abbiamo aggiunto la proprietà OriginAtCenter con il valore false nei vecchi programmi e true in tutti quelli futuri. Gli utenti potrebbero porre una domanda logica: chi ha mai pensato di posizionare il punto di partenza in un posto diverso dal centro? A cui? A un programmatore che dieci anni fa era troppo pigro per creare una normale API.

Lezioni imparate

Quando lavori sulle API (cosa che quasi tutti i programmatori devono fare a volte), dovresti seguire i migliori consigli delineati nel video di Joshua Bloch "Come creare una buona API e perché è così importante"o in questo breve elenco:

  • Un'API può offrirti sia grandi vantaggi che grandi danni.. Una buona API crea clienti abituali. Quello cattivo diventa il tuo eterno incubo.
  • Le API pubbliche, come i diamanti, durano per sempre. Dai il massimo: non ci sarà mai un'altra possibilità di fare tutto bene.
  • I contorni dell'API dovrebbero essere brevi — una pagina con firme e descrizioni di classi e metodi, che non occupa più di una riga. Ciò ti consentirà di ristrutturare facilmente l'API se non risulta perfetta la prima volta.
  • Descrivere i casi d'usoprima di implementare l'API o addirittura di lavorare sulle sue specifiche. In questo modo eviterai di implementare e specificare un'API completamente non funzionale.

Se avessi scritto anche una breve sinossi con una sceneggiatura artificiale, molto probabilmente avrei individuato l'errore e lo avrei corretto. In caso contrario, uno dei miei colleghi lo farebbe sicuramente. Qualsiasi decisione che abbia conseguenze di vasta portata deve essere pensata per almeno un giorno (questo vale non solo per la programmazione).

Il titolo del saggio di Richard Gabriel, "Worse Is Better", si riferisce al vantaggio che deriva dall'essere il primo a commercializzare, anche con un prodotto imperfetto, mentre qualcun altro passa un'eternità a inseguire quello perfetto. Riflettendo sul codice sprite, mi rendo conto che non dovevo nemmeno scrivere altro codice per farlo bene. Qualunque cosa si possa dire, mi sbagliavo di grosso.

conclusione

I programmatori commettono errori ogni giorno, sia che si tratti di scrivere codice difettoso o di non voler provare qualcosa che migliorerà le loro capacità e produttività. Naturalmente, puoi essere un programmatore senza commettere errori così gravi come ho fatto io. Ma è impossibile diventare un buon programmatore senza riconoscere i propri errori e imparare da essi.

Incontro costantemente studenti che hanno la sensazione di commettere troppi errori e quindi di non essere tagliati per la programmazione. So quanto sia comune la sindrome dell'impostore nell'IT. Spero che imparerai le lezioni che ho elencato, ma ricorda quella principale: ognuno di noi commette errori: imbarazzanti, divertenti, terribili. Sarò sorpreso e sconvolto se in futuro non avrò abbastanza materiale per continuare l'articolo.

Fonte: habr.com

Aggiungi un commento