Fork me on GitHub
con Valerio Galano

Il podcast dove si ragiona da informatici

Un informatico risolve problemi, a volte anche usando il computer

Riflessioni e idee dal mondo del software

Episodio del podcast

Perché ci sono bug nei software?

8 ottobre 2020 Podcast Episodio 43 Stagione 1
Perché ci sono bug nei software?

Descrizione

Molto spesso nei software ci sono dei bug. Ma quando vengono individuati, di solito in tempi anche brevi, arrivano anche le correzioni. Ma allora perché non si correggono tutti i bug prima di rilasciare i software?

Fonti:
Software Development, Design and Coding* - https://amzn.to/3e6Swcq

——————————————
Sito ufficiale di Pensieri in codice - https://pensieriincodice.it

Attrezzatura:
Microfono Blue Yeti* - https://amzn.to/3kSE35f
Filtro anti-pop* - https://amzn.to/3baPMsh
Filtro anti-pop* - https://amzn.to/2MH0Wf1
Schermo fonoassorbente* - https://amzn.to/3sOZE0P

Sostieni il progetto

Sostieni tramite Satispay
Sostieni tramite Revolut
Sostieni tramite PayPal (applica commissioni)
Sostieni utilizzando i link affiliati di Pensieri in codice: Amazon, Todoist, Readwise Reader, Satispay

Partner

GrUSP (Codice sconto per tutti gli eventi: community_PIC)
Schrödinger Hat

Crediti

Montaggio - Daniele Galano - https://www.instagram.com/daniele_galano/
Voce intro - Costanza Martina Vitale
Musica - Kubbi - Up In My Jam
Musica - Light-foot - Moldy Lotion
Cover e trascrizione - Francesco Zubani

Mostra testo dell'episodio

Nascondi

Quella che segue è una trascrizione automatica dell'episodio.

Pensieri in codice. Idee dal mondo del software a cura di Valerio Galano. Salve a tutti e bentornati su Pensieri in codice. Oggi parliamo di bug. Viviamo in un’epoca nella quale ognuno di noi, chi più chi meno, è abituato ogni giorno ad avere a che fare con decine, centinaia o anche migliaia di software. Dagli smartphone ai computer, dagli elettrodomestici fino ai mezzi di trasporto, siamo tutti a contatto con dei software con i quali interagiamo più o meno volontariamente. Alcuni di questi software funzionano meglio, altri funzionano un po’ peggio, di alcuni non sappiamo neanche l’esistenza, mentre di altri abbiamo magari una conoscenza abbastanza approfondita. Ed è per questo che a volte, o di tanto in tanto, o spesso, questo dipende dai casi, ci capita di incappare in errori o comportamenti strani di tali software che comunemente vengono definiti bug. Questa parola è entrata ormai a far parte del nostro dizionario in maniera piuttosto stabile. Un’app va in crash? Allora c’è un bug. Un programma non dà il risultato che ci aspettiamo? Allora c’è un bug. Quel sito non si visualizza nel modo corretto? E allora c’è un bug. In ogni caso, l’idea che c’è alla base del concetto di bug è che se in un software qualcosa non funziona, qualcuno, probabilmente un programmatore, in qualche punto del processo di produzione ha commesso un errore. Ma in realtà il concetto non è così semplice e nell’episodio di oggi vorrei provare a spiegarvi il perché. Prima di procedere però un piccolo avviso. Siccome ho ricevuto parecchi messaggi da ascoltatori che hanno difficoltà a seguire Pensieri in Codice da Spotify, d’ora in poi proverò a pubblicare sui vari social il link agli episodi su Spreaker, che in teoria non dovrebbe richiedere né login né altri passaggi fastidiosi. In ogni caso, il consiglio è quello di evitare Spotify per ascoltare i podcast in generale. Questo perché Spotify si sta attrezzando da poco tempo per supportare i podcast e quindi manca di tante piccole funzionalità che in realtà praticamente tutte le altre app implementano senza problemi. Pensieri in Codice lo trovate praticamente su tutte le piattaforme e tutte le app, quindi vi conviene utilizzare qualcosa anche di molto semplice tipo Google Podcast o Apple Podcast o l’app di Spreaker. Ma in ogni caso, se preferite, potete seguirmi su Twitter, su Telegram o su Instagram, trovate tutti i link in descrizione, e semplicemente cliccare sui link che pubblicherò agli episodi di volta in volta. Ora però bando alle ciance e iniziamo con l’argomento di oggi. Come tutti sappiamo, i bug all’interno di un software sono qualcosa di molto fastidioso. Fanno perdere tempo, potenzialmente fanno perdere soldi, sono frustranti e in generale ci fanno sembrare che il software sia di cattiva qualità. Non importa se si parla di un’app per smartphone o un programma per computer, non importa quanto l’abbiamo pagato, non importa quante funzionalità ha, quanto è veloce o quanto è semplice. Qualsiasi sia il software di cui stiamo parlando, è possibile, anzi probabile, che in esso si annidi qualche bug. Ma visto che una volta scoperti, questi bug vengono puntualmente, o quasi sempre, fixati, corretti, perché non li si corregge semplicemente tutti prima del lancio di un software? O perché non si aspetta a lanciare finché tutti i bug sono stati corretti? Beh, la risposta breve è che individuare e correggere tutti i bug è così complesso da essere praticamente impossibile. Ma per capire come mai dobbiamo chiarire alcuni concetti, il primo dei quali è cos’è un bug e come è fatto. Ora, a grandi linee cos’è un bug lo sappiamo un po’ tutti. In pratica stiamo parlando di un errore nel software da qualche parte che ne provoca dei comportamenti inaspettati. Ma quello che non tutti sanno è che questi errori, questi bug, possono essere suddivisi principalmente in tre categorie distinte. La prima di queste categorie è quella dei bug di sintassi, cioè quegli errori commessi dal programmatore mentre sta scrivendo il codice del software. Si tratta di meri errori materiali nell’utilizzo del linguaggio, quindi ad esempio segni di punteggiatura mancanti o nomi di funzioni errate, utilizzo di variabili non dichiarate e cose del genere. Nel 2020 questo tipo di errori sono davvero complicati da commettere. Prima di tutto perché in caso ce ne fossero un software farebbe molta fatica ad essere eseguito o comunque soffrirebbe di malfunzionamenti piuttosto evidenti. Senza contare che qualsiasi sia il linguaggio utilizzato, un ambiente di sviluppo avanzato o un compilatore sono perfettamente in grado di individuare questo tipo di errori e persino suggerire la giusta soluzione allo sviluppatore. Decisamente più complessa, invece, è la seconda categoria di bug, che è quella degli errori logici. In questo tipo di errori il codice risulta scritto correttamente e pertanto si esegue senza dare problemi. Tuttavia l’errore sta nel fatto che il programma non svolge correttamente il compito per il quale è stato creato. Per fare un esempio particolarmente semplice immaginiamo di scrivere un piccolo programma che prenda in input il lato di un quadrato e debba calcolarne il perimetro. Si tratterebbe di un programma piuttosto banale che dovrebbe semplicemente prendere un numero e moltiplicarlo per 4. Ma se nello scrivere il codice commettessimo un mero errore di battitura e al posto del numero 4 scrivessimo il numero 5 o il numero 3, a quel punto il nostro programma moltiplicherebbe la lunghezza del lato per 5 o per 3. In un’istruzione del genere non c’è nessun errore di sintassi, è perfettamente lecito moltiplicare il valore di una variabile per 3 o per 5. Tuttavia il risultato del nostro calcolo sarebbe errato dal punto di vista logico, perché con il nostro programma buggato un quadrato con lato uguale a 5 risulterebbe avere un perimetro uguale a 25 o a 15, in ogni caso diverso dal risultato corretto, cioè 20. La terza e sicuramente più infida categoria di bug è quella degli errori di runtime. Questo tipo di errori si verifica solamente a volte, in presenza di determinate condizioni. In pratica si parla di codice che a volte funziona e a volte no, a seconda ad esempio dei dati che sta elaborando o della disponibilità o meno di risorse esterne delle quali ha bisogno per lavorare. Gli esempi più classici che mi vengono in mente sono ad esempio il caso in cui ci si trova a fare una divisione per un valore 0, che è un’operazione impossibile e spesso in molti linguaggi non è gestita. Oppure un altro caso classico è quello in cui il valore all’interno di una variabile cresce e viene incrementato fino al punto di superare il limite gestibile da quel tipo di variabile. O se vogliamo pensare a qualcosa di più complesso, possiamo immaginare un programma che abbia bisogno di scrivere un file ma trovi l’unità bloccata in scrittura oppure il disco pieno. Anche in questo caso si parlerebbe di un errore di runtime. Ad ogni modo però, come potreste ben immaginare, questo tipo di bug è il più complicato non tanto da risolvere, quanto piuttosto da individuare o addirittura da prevedere. Sottotitoli e revisione a cura di QTSS Ora, a prescindere da cosa possano immaginare i non addetti ai lavori, passatemi il termine, la guerra contro i bug per la maggior parte dei software coinvolge ogni giorno moltissime persone e varie figure professionali, le quali hanno anche a disposizione un gran numero di tecniche atte appunto a scovare i bug. Ovviamente in un podcast di pochi minuti non mi illudo neanche di poter scalfire la superficie di questo argomento, tuttavia vorrei che passasse almeno il concetto principale, e cioè che nella maggior parte dei casi il problema di un bug non è tanto come risolverlo, per quello una soluzione si trova, il problema in realtà è individuarlo. Ed è proprio per perseguire questo obiettivo che nel corso degli anni sono state sviluppate varie tecniche sempre più efficaci, che chi si occupa di sviluppo del software può applicare in misura maggiore o minore a seconda delle risorse che ha a disposizione. Accade quindi che a valle della produzione di un certo codice ci siano figure specializzate come gli sviluppatori senior che ispezionano e revisionano il codice alla ricerca di eventuali problemi, o i tester che verificano le varie funzionalità di un programma alla ricerca di malfunzionamenti, o ancora gli stessi programmatori che spesso utilizzano gli unit tests per assicurarsi che determinate porzioni di codice funzionino sempre nel modo corretto. Esistono persino aziende specializzate nel fare audit per verificare la sicurezza o le performance di un certo software. Insomma, anche senza scendere nei dettagli, appare chiaro che viene fatto un lavoro notevole per la ricerca ed eliminazione dei bug. E allora, come mai alcuni di essi riescono comunque a sfuggire ai controlli ed arrivare agli utenti? Beh, le risposte a questa domanda sono principalmente due. La prima è banale, ma vale la pena di ricordarla. E c’è che i programmatori, i analisti, i tester e tutte le figure che lavorano allo sviluppo di un software non sono perfetti. E quindi, in realtà, non ha molto senso aspettarsi da loro un prodotto perfetto. Banalmente, un programmatore può commettere un errore e, allo stesso modo, un tester può commettere un errore nel fare il test o nel programmarlo, se si tratta di test automatici. E questo ci porta direttamente alla seconda motivazione per cui i bug riescono a superare tutti questi controlli. E cioè che, tra tutti i prodotti dell’ingegno umano, il software è uno dei più complessi. Come abbiamo visto nel primo blocco, un bug si può annidare in una semplice istruzione di moltiplicazione. E allora che dire di un software che è composto da più di 50.000 righe? O di 100.000? O di un milione di righe? Aspettarsi che qualcuno, leggendo un codice o lanciando dei test, possa essere in grado di individuare tutte le possibili esecuzioni di tale codice, in realtà non è poi cosa così sensata. In questo caso, un software va visto come un insieme di percorsi, ognuno dei quali è frutto della combinazione di tutta una serie di valori, di eventi, di risorse, di interazione con gli utenti, eccetera. In una visione del genere, già un piccolo software si compone di tantissimi percorsi. Immaginiamo quindi cosa potrebbe accadere al crasher di tale software. Per avere un ordine di grandezza, dobbiamo pensare che, all’interno di un programma, ogni volta che aggiungiamo una semplice istruzione IF, stiamo in linea generale raddoppiando la quantità di percorsi disponibili. Per non parlare, invece, se ad esempio inseriamo la possibilità di input da parte dell’utente. In un contesto del genere, pensare di avere un approccio a forza bruta, quindi pensare di poter coprire qualsiasi possibile test per scovare qualsiasi possibile bug, semplicemente non ha senso. Sarebbe necessario così tanto tempo da rendere impossibile la pubblicazione del software e quindi inutili gli stessi test. Quindi, nel mondo reale, l’approccio è quello logico, cioè si cerca di immaginare quali siano i potenziali problemi e di produrre la maggior quantità possibile di test inerenti ad essi, con la consapevolezza che esisterà sempre una certa probabilità che qualcosa sfuga. E siamo giunti al termine dell’episodio di oggi. Spero che l’argomento sia stato interessante, voi come al solito fatemi sapere cosa ne pensate nei commenti su Twitter, su Telegram, su Instagram o dove volete. Condividete il più possibile questo episodio sui vostri social per far crescere la community, unitevi al gruppo Telegram Pensieri in Codice e non dimenticate che un informatico risolve problemi, a volte anche usando il computer. A presto!

Nascondi