Dentro la mente di un programmatore: ecco come nascono i bug
I bug non nascono dentro il computer. Nascono nella testa del programmatore.
È un’affermazione che può sembrare strana, soprattutto a chi immagina il programmatore come una specie di creatura infallibile che digita comandi perfetti e crea software impeccabili. La verità è molto più semplice e molto più divertente: un bug è quasi sempre il risultato di un momento di distrazione, di eccessiva sicurezza o di fretta. E tutti i programmatori, prima o poi, ci cascano.
Quando nasce davvero un bug
Cominciamo dall’inizio. Immaginiamo un programmatore che si siede alla scrivania, apre il computer e guarda la nuova funzionalità da sviluppare. La studia per qualche secondo e si convince che sarà veloce da implementare.
Pensa: “Questa la faccio in mezz’ora.”
È una frase che, nel mondo della programmazione, porta quasi sempre guai. Nel momento stesso in cui nasce questo pensiero, da qualche parte nella testa del programmatore si pianta il seme di un bug. Non è ancora un vero errore, ma è la porta che si spalanca verso la distrazione.
L’eccesso di sicurezza e il codice scritto di corsa
Il programmatore comincia a scrivere codice sicuro di sé. È convinto di aver capito tutto e per questo tende a sorvolare su alcune verifiche. È un atteggiamento umano: quando qualcosa sembra semplice, non la controlliamo con attenzione.
È così che, tra una parentesi e una variabile, può scivolare un errore piccolissimo ma potenzialmente devastante.
Una variabile chiamata result invece di results.
Un confronto scritto come assegnazione:
if (user.isAdmin = true)
invece di:
if (user.isAdmin == true)
Oppure una funzione usata nel modo sbagliato, come quando in Python qualcuno scrive:
items = items.append("nuovo")
senza ricordarsi che append() non restituisce la lista, ma modifica quella
esistente. È una riga apparentemente innocua che però trasforma items in
None, facendo crollare tutto quello che viene dopo.
Il bug esiste già, ma nessuno lo sa
Il bug, a questo punto, esiste già. È lì, nella riga di codice scritta in buona fede, e sta aspettando solo il momento giusto per rivelarsi.
Ma il programmatore non lo sa. O meglio, non immagina nemmeno che ci possa essere un problema.
Fa una prova veloce: apre la pagina, clicca un bottone, vede che funziona e decide che i test approfonditi può farli dopo. O domani. O magari mai.
È un classico.
I programmatori testano sempre il percorso perfetto, quello che nella loro testa rappresenta “l’uso normale”. Ciò che non testano quasi mai è ciò che potrebbe fare un utente reale: inserire un dato imprevisto, cliccare due volte di fila, cambiare pagina e tornare indietro, oppure fare le cose in un ordine che non era stato considerato.
Quando il bug decide di colpire
Quando la funzionalità viene pubblicata, il programmatore si sente soddisfatto. Magari pensa: “Visto? Era davvero semplice.”
È qui che il bug fa la sua mossa. Di solito sceglie il momento peggiore per manifestarsi.
Può essere durante una demo importante, quando il cliente sta guardando lo schermo con curiosità. Oppure durante la presentazione al team. O ancora nei cinque minuti prima di andare a casa, quando qualcuno apre una pagina e improvvisamente tutto si blocca.
La classica frase “Ma ieri funzionava!” è il segnale che qualcosa è andato storto.
La fase della negazione
A questo punto comincia la fase della negazione. Nessun programmatore, davanti a un bug imprevisto, pensa subito che sia colpa sua.
La mente cerca spiegazioni alternative.
La rete non va. Il server è lento. La cache non si è aggiornata. È stato cambiato qualcosa da qualcun altro. La libreria esterna ha un problema.
Qualsiasi cosa, tranne ammettere che quell’errore microscopico era stato scritto proprio da lui.
L’indagine: quando il puzzle si ricompone
Poi arriva il momento dell’indagine vera e propria. Si aprono i log, si inseriscono stampe di debug, si ricostruisce il percorso del codice.
È un processo che può durare pochi minuti o anche ore, ma segue sempre lo stesso schema: all’inizio regna la confusione, poi pian piano tutti i pezzi si ricompongono.
Ed è in quel momento che, come un lampo improvviso, tutto diventa chiaro.
Il programmatore si accorge che il bug stava sempre lì, nella riga scritta di corsa, nella funzione copiata e incollata senza cambiare due variabili, o in una condizione logica apparentemente innocua che però impediva il funzionamento corretto del programma.
Il sollievo, l’imbarazzo e la risata
È un momento strano. Da un lato c’è sollievo, perché finalmente si è capito dov’era il problema. Dall’altro c’è un leggero imbarazzo, perché l’errore era quasi sempre banale.
E si ride, perché spesso i bug più frustranti nascono da sciocchezze.
Riguardando il codice, tutto diventa ovvio, come quando si risolve un indovinello e ci si chiede come fosse possibile non averlo capito prima.
Bug “simpatici” e bug leggendari
Date e fusi orari: il classico bug invisibile
A volte il bug è ancora più simpatico, perché nasce da situazioni particolari. Ad esempio quando si lavora con date e fusi orari e si dà per scontato che tutti gli utenti siano nello stesso Paese.
Così, un utente americano si ritrova una riunione alle tre del mattino.
Il bug del venerdì pomeriggio
Una categoria speciale è il bug del venerdì pomeriggio. Nasce quando qualcuno, stanco o di fretta, decide di “aggiungere un’ultima modifica veloce prima del weekend”.
In locale funziona tutto. In produzione, naturalmente, no.
È quasi un rito di iniziazione: prima o poi capita a tutti.
Il bug della doppia negazione
E poi c’è il classico bug della doppia negazione. Nasce quando si ha fretta e si cerca di essere “furbi”, scrivendo condizioni criptiche come:
if (!(!isValid))
In quel momento sembra una buona idea. Dopo un giorno nessuno capisce più cosa significhi, nemmeno chi l’ha scritto.
La riflessione finale del programmatore
Quando finalmente il bug viene risolto, si entra nella fase della riflessione.
Il programmatore promette a sé stesso che la prossima volta testerà meglio, scriverà codice più chiaro, eviterà scorciatoie rischiose e, soprattutto, che non svilupperà quando è stanco.
È una promessa che tutti fanno. E tutti infrangono entro pochi giorni, semplicemente perché la programmazione è un lavoro pieno di variabili, distrazioni, pressioni e tempi stretti.
Perché i bug non sono il nemico
Alla fine, la verità è che i bug non sono nemici. Sono parte del viaggio.
Sono la prova che il programmatore è un essere umano che lavora con concetti complessi e che inevitabilmente può sbagliare.
Ogni bug risolto rende il codice migliore e il programmatore un po’ più consapevole. Ed è questo che rende la programmazione un lavoro che non smette mai di insegnare qualcosa.
I bug nascono nella testa, ma muoiono nel codice
I bug nascono nella testa di chi scrive, ma muoiono grazie alla pazienza di chi torna sul codice, lo analizza e lo corregge.
È un ciclo continuo fatto di errori e correzioni, frustrazione e soddisfazione, confusione e illuminazione.
Ed è proprio questo ciclo a rendere la programmazione un’avventura che non finisce mai.
10 bug Python che ti rovineranno la giornata
Prima di lasciarci voglio elencarti 10 bug Python che ti rovineranno la giornata. E poi chiudiamo con 10 bug reali accaduti in Italia, diventati veri e propri casi di studio.
1. Usare = invece di == nei confronti
In Python il simbolo = serve per assegnare un valore, mentre == serve per
confrontarlo. Quando si usa = dentro un’istruzione if, il codice non
funziona e genera un errore di sintassi.
if x = 5: # Errore
print("ok")
È uno degli errori più frequenti quando si inizia a programmare.
2. Dimenticare il return in una funzione
In Python, se una funzione non contiene un return, restituisce
automaticamente None. Se in seguito si tenta di usare quel valore come lista,
stringa o iterabile, il programma si blocca.
def get_items():
items = [1, 2, 3] # manca il return
result = get_items()
for x in result:
print(x) # Errore: NoneType non è iterabile
Il problema nasce semplicemente dal non aver restituito il valore.
3. Modificare una lista mentre la si percorre
Quando si rimuovono o aggiungono elementi a una lista all’interno di un ciclo che la percorre, l’ordine e la lunghezza cambiano, causando comportamenti imprevisti.
items = [1, 2, 3]
for i in items:
items.remove(i)
Alcuni elementi vengono saltati perché l’indice interno cambia mentre il ciclo è in corso.
4. Usare append() come se restituisse la lista
Il metodo append() modifica la lista esistente e non restituisce nulla. Il
suo valore di ritorno è None.
items = []
items = items.append(5)
print(items) # None
Errore molto comune per chi arriva da altri linguaggi.
5. Parametri di default mutabili
Usare una lista o un dizionario come valore di default in una funzione può generare comportamenti inattesi.
def add_item(x, lista=[]):
lista.append(x)
return lista
Ogni chiamata condivide la stessa lista.
6. Usare is al posto di ==
is confronta l’identità degli oggetti, == il contenuto.
a = "ciao"
b = "ciao"
a is b # Non sempre affidabile
7. Sovrascrivere nomi di funzioni built-in
list = [1, 2, 3]
list("ciao") # Errore
La funzione list() viene nascosta dal nome della variabile.
8. Indentazione non corretta
In Python l’indentazione è parte della sintassi.
if condizione:
print("ciao") # Errore
9. Intercettare eccezioni in modo troppo generico
try:
operazione()
except:
pass
Si rischia di nascondere problemi reali.
10. Errori off-by-one nei cicli
for i in range(1, len(items)):
print(items[i])
Il primo elemento viene ignorato e si rischia di uscire dai limiti.
Questi sono i bug Python più comuni: quelli che incontrerai, amerai, odierai e soprattutto ricorderai.
10 bug reali accaduti in Italia diventati casi di studio
Per concludere vi voglio lasciare con i 10 bug accaduti realmente in italia che sono diventati veri e propri casi di studio.
Bug Sistemi aeroportuali
I sistemi aeroportuali italiani bloccati per un bug meteorologico (2015). In alcuni aeroporti italiani i sistemi di check-in e gestione voli andarono in tilt perché il software non interpretava correttamente un valore meteorologico anomalo (una temperatura negativa non prevista). Un numero non previsto in un campo dati → voli bloccati e ritardi nazionali.
Bug del 29 febbraio nel sistema dei pedaggi autostradali (2016)
Nell’anno bisestile alcuni sistemi di esazione automatica entrarono in errore perché non gestivano correttamente il 29 febbraio. Un classico caso di date non validate. Un giorno in più nel calendario → caselli lenti o bloccati in tutta Italia.
La carta d’identità elettronica (CIE) che si bloccava per un “carattere speciale” (2018)
Alcuni cittadini non riuscivano a registrare i propri dati perché il sistema non accettava caratteri come apostrofi o lettere accentate in certi campi. Classico errore di validazione input. Un apostrofo nel cognome → sistema KO per giorni.
L’errore del sistema “NoiPA” che calcolò stipendi sbagliati (2018)
In un aggiornamento, una formula di calcolo errata generò stipendi incompleti o ritardati per molti dipendenti pubblici. Un coefficiente sbagliato → migliaia di buste paga sballate.
Il “click day” INPS del 2020
Quando si aprì la piattaforma per il bonus Covid, il sito INPS collassò in pochi minuti. Il problema non fu solo il sovraccarico: alcuni utenti vedevano le informazioni personali di altri utenti, segno che c’era un errore nella gestione della sessione e della cache. Un errore piccolo nella gestione dei dati in memoria, combinato con il traffico altissimo → esposizione di dati sensibili e piattaforma inutilizzabile.
Il bug dei biglietti Trenitalia a 0 euro (2020)
Nella notte di Capodanno, per alcune ore, il sito Trenitalia vendette biglietti a prezzi irrisori (anche 0,10 € o 0,00 €). Era un errore nella gestione delle tariffe promozionali, legato al cambio dell’anno e alla generazione automatica delle offerte. Un calcolo tariffario sbagliato → migliaia di biglietti venduti praticamente gratis.
Il blackout informatico della Regione Lazio (2021)
Spesso ricordato come “attacco ransomware”, ma c’è anche una componente tecnica importante: gli accessi interni erano gestiti con password di default e procedure non aggiornate. Non è un bug in senso tecnico, ma è il classico errore banale — una password sbagliata al posto giusto — che apre la strada al disastro. Una password lasciata lì dove non dovrebbe stare → sistema sanitario regionale paralizzato per settimane.
Poste Italiane e il crash del sistema SPID (vari episodi)
Negli anni, diversi blackout dei servizi SPID sono stati causati da errori molto semplici: incompatibilità dopo un aggiornamento software, configurazioni sbagliate o code interne che non smaltivano le richieste. Un parametro sbagliato in un server SPID → mezza Italia bloccata nei servizi online.
Il bug di PagoPA che bloccò i pagamenti scolastici (2021)
Per alcune ore PagoPA non accettava pagamenti di tasse scolastiche, multe e bollettini. La causa fu un errore nella gestione delle notifiche e delle code interne: una modifica minore produsse una cascata di errori. Una piccola modifica in un sistema critico → file di genitori impotenti davanti a una schermata di errore.
Il crash del portale università (test d’ingresso) per troppi login simultanei (annuale)
Ogni anno vari portali universitari italiani vanno giù durante i test d’ingresso. Dietro non c’è solo sovraccarico: spesso emergono problemi molto banali come query non ottimizzate o cache mal configurate. Una query lenta → migliaia di studenti bloccati senza poter accedere alle prove.
Conclusione
I bug fanno parte del mestiere. Prima o poi arrivano, sempre nel momento peggiore.
La differenza la fa cosa fai dopo: se li ignori, li giustifichi… oppure se li usi per capire come lavori davvero.
Se ti sei riconosciuto in almeno uno di questi bug, allora sei nel posto giusto. Perché programmare non è non sbagliare mai, ma imparare qualcosa ogni volta che qualcosa si rompe.