Cos'è una Hash Table? Hashing e Collisioni Spiegati

Cerca una chiave in un dict Python con dieci elementi e ci metti lo stesso tempo che cercarla in un dict con dieci milioni. Non è un caso dovuto a un linguaggio veloce. Il dict di Python, la HashMap di Java e la Map di JavaScript sono tutte hash table, e l’intero design esiste per far girare lookup, inserimento e cancellazione in O(1) in media. La notazione Big O chiama questa lookup “tempo costante”. Ecco il meccanismo che se lo merita. ...

4 novembre 2026 · 8 minuti · 1588 parole · SpaghettiCoder

Mock, Stub, Fake e Spy: i Test Double Spiegati

Un test per place_order ha bisogno di un gateway di pagamento, un client SMS e un calcolatore delle tasse. Se collegassi quelli veri, ogni esecuzione del test addebiterebbe una carta e manderebbe un SMS a un numero reale. Un test unitario deve girare in pochi millisecondi, senza rete, quindi tutti e tre vanno sostituiti con qualcos’altro. Quel “qualcos’altro” si presenta in cinque forme — ognuna risolve un problema diverso — e trattarle come intercambiabili è il motivo per cui le discussioni “basta mockarlo” in code review girano in tondo. ...

2 novembre 2026 · 8 minuti · 1646 parole · SpaghettiCoder

Espressioni Regolari Spiegate: Come Funziona il Regex

<.+> contro <b>bold</b> and <i>italic</i> non trova <b>. Trova l’intera stringa, dal primo < all’ultimo >. Non c’è nessun bug. È esattamente quello che un quantificatore greedy deve fare, ed è anche il bug più comune in assoluto quando “il regex matcha troppo”. Una volta capito cosa fa il motore mentre legge il pattern, questo bug e i suoi parenti smettono di essere misteriosi. Come un Motore Regex Legge il Pattern Un motore regex non confronta il pattern con la stringa come si confrontano due stringhe per uguaglianza. I motori che usi ogni giorno (re di Python, RegExp di JavaScript, PCRE, .NET, Java) sono regex-directed: scorrono il pattern da sinistra a destra, token per token, e per ogni token provano a consumare caratteri dalla stringa nella posizione attuale. Quando un token trova corrispondenza, il motore avanza sia il puntatore del pattern che quello della stringa. Quando un token fallisce, il motore fa backtracking: torna all’ultimo punto in cui aveva una scelta, come un quantificatore che poteva fermarsi prima o un ramo di un’alternanza non ancora provato, e prova l’altra opzione. ...

28 ottobre 2026 · 8 minuti · 1578 parole · SpaghettiCoder

Cosa Sono Unicode e la Codifica UTF-8

Apri un file salvato come UTF-8 in uno strumento che assume una codifica diversa e café diventa café. I byte sul disco non sono cambiati. È cambiata solo la regola usata per trasformarli di nuovo in caratteri, e le due regole non sono d’accordo su cosa significhi il byte 0xC3. La maggior parte dei bug da “caratteri strani” — nomi di file corrotti, moduli web illeggibili, emoji che fanno fallire un insert nel database, due stringhe identiche all’occhio ma diverse nel confronto — nasce dalla stessa confusione tra due cose distinte: Unicode e UTF-8. ...

20 ottobre 2026 · 8 minuti · 1589 parole · SpaghettiCoder

Cos'è il TDD e Come Funziona il Ciclo Red-Green-Refactor

Un test scritto dopo il codice tende a verificare quello che il codice fa, non quello che doveva fare. Il test-driven development risolve il problema invertendo l’ordine: scrivi il test, guardalo fallire, poi scrivi il minimo codice che lo fa passare. Dato che il test esiste prima del codice che controlla, non può confermare silenziosamente qualunque cosa il codice restituisca. Kent Beck ha formalizzato questo ciclo come red, green, refactor nel suo libro del 2002 Test-Driven Development: By Example. Il nome è rimasto. ...

18 ottobre 2026 · 7 minuti · 1393 parole · SpaghettiCoder

La Ricorsione Spiegata: Quando Usarla e Quando Evitarla

Una funzione che richiama se stessa ha una profondità massima, ed è più piccola di quanto la maggior parte delle persone si aspetti: 1.000 chiamate in CPython di default, circa 10.000-15.000 in Node e nei motori dei browser, a seconda di quanto pesa ogni frame. Superarla non significa che il programma rallenta: crasha. Python solleva RecursionError: maximum recursion depth exceeded; JavaScript solleva RangeError: Maximum call stack size exceeded. Entrambi gli errori hanno la stessa causa, e una volta vista capisci subito quando la ricorsione è lo strumento giusto e quando diventa un rischio. ...

13 ottobre 2026 · 7 minuti · 1461 parole · SpaghettiCoder

Principi SOLID Spiegati con Esempi in Python

Una classe che salva un utente nel database, gli manda un’email di benvenuto e formatta una ricevuta è a una modifica di distanza dal rompere due funzionalità con cui non ha niente a che fare. Tocchi il template dell’email e rischi la scrittura sul database. Tocchi il layout della ricevuta e rischi l’email. SOLID sono cinque regole che attaccano questo tipo di groviglio da angolazioni diverse, e condividono un’idea sola: una classe deve cambiare per un solo motivo, e il resto del codice deve dipendere da cosa qualcosa promette di fare, non da come lo fa. ...

10 ottobre 2026 · 10 minuti · 1924 parole · SpaghettiCoder

Cos'è una Race Condition e Come Risolverla

Due richieste arrivano sullo stesso endpoint “preleva 100€” a mezzo millisecondo di distanza. Il conto ha 150€. Entrambe le richieste leggono quel saldo, entrambe vedono fondi sufficienti, entrambe approvano, entrambe sottraggono 100€. Il conto finisce a -50€, e nessun ramo del codice avrebbe dovuto permetterlo. Questa è una race condition: il risultato dipende da quale operazione finisce prima, e quel “prima” non lo decide il codice. Cosa causa una race condition? Servono due ingredienti insieme: stato condiviso mutabile, e più di un percorso di esecuzione che lo tocca senza coordinarsi. I percorsi possono essere thread, task async, processi, o due server che colpiscono la stessa riga di database. Togli uno dei due ingredienti e il bug scompare. Un singolo thread non può entrare in race con se stesso, e uno stato immutabile non si corrompe anche se viene letto più volte. ...

9 ottobre 2026 · 9 minuti · 1868 parole · SpaghettiCoder

Decoratori Python Spiegati con Esempi Pratici

Cosa fa davvero un decoratore alla tua funzione Vuoi misurare il tempo di ogni funzione che chiama un’API esterna lenta. Puoi incollare chiamate a time.perf_counter() in ognuna, oppure scrivere la misurazione una sola volta e applicarla ovunque. Un decoratore è la seconda opzione: è una funzione che prende un’altra funzione, la avvolge in un comportamento aggiuntivo e restituisce la versione avvolta con lo stesso nome originale. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import time def timed(func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) elapsed = time.perf_counter() - start print(f"{func.__name__} took {elapsed:.3f}s") return result return wrapper @timed def fetch_price(ticker): time.sleep(0.2) # al posto di una chiamata di rete return 142.50 fetch_price("AAPL") # fetch_price took 0.201s @timed sopra def fetch_price è l’abbreviazione di fetch_price = timed(fetch_price). Python chiama timed una sola volta, subito dopo la definizione di fetch_price, e ricollega il nome fetch_price a quello che timed restituisce. Tutto quello che fa la @ è questo. ...

7 ottobre 2026 · 7 minuti · 1329 parole · SpaghettiCoder

Perché 0.1 + 0.2 Non Fa 0.3: la Virgola Mobile Spiegata

Esegui 0.1 + 0.2 in una shell Python e non ottieni 0.3. Ottieni 0.30000000000000004. Prova in JavaScript, Java, Go, C o Rust e trovi la stessa coda di sedici cifre. Ognuno di questi linguaggi fa esattamente quello che impone lo standard hardware. Un numero che richiederebbe infinite cifre binarie viene compresso in 64 bit, e qualcosa deve cedere. Perché 0.1 non si può memorizzare esattamente in binario I computer memorizzano i numeri in virgola mobile in base 2. In base 2, la frazione 1/10 ha uno sviluppo periodico, proprio come 1/3 si ripete all’infinito in base 10 (0.3333...). Scritto per intero, 0.1 in binario inizia così: ...

6 ottobre 2026 · 6 minuti · 1173 parole · SpaghettiCoder