System Design Colloquio — Cheat Sheet

Tag: system-design, distributed-systems, scalability, architecture, load-balancing, caching, database, api-design

Livello: avanzato

TL;DR: Framework pratico in quattro fasi per strutturare qualsiasi colloquio di System Design, dai requisiti e stime fino al deep dive architetturale.

Concetti chiave

Chiarire subito requisiti funzionali ed extra-funzionali (latenza, disponibilità, consistenza).

Calcolare stime di scala: DAU, QPS di picco, throughput di rete e storage a 5 anni.

Definire contratti API precisi (REST o gRPC) prima di disegnare i componenti.

Disegnare l'architettura ad alto livello: client, CDN, load balancer, API gateway e servizi.

Scegliere il database corretto in base all'accesso: SQL per ACID, NoSQL per throughput orizzontale.

Scalare i dati con sharding, partizionamento, replication lag e pattern master-replica.

Introdurre caching multi-livello: client, edge CDN, Redis cluster con eviction policy adeguata.

Gestire elaborazioni asincrone e picchi tramite message broker come Kafka o RabbitMQ.

Trattare il teorema CAP chiarendo il trade-off esplicito tra Availability e Consistency.

Indirizzare Single Points of Failure, rate limiting, circuit breaker e ridondanza geografica.

Domande tipiche e risposte pronte

Q: Come approcci un problema aperto di System Design all'inizio del colloquio?R: Dedico i primi cinque minuti a porre domande chiarificatrici, stabilendo l'ambito del problema, i casi d'uso primari, il target di utenti attivi e i vincoli di SLO/SLA.

Q: SQL vs NoSQL: quale criterio guida la tua scelta architetturale?R: Valuto le relazioni e le garanzie transazionali: scelgo RDBMS per query complesse e vincoli ACID, mentre passo a NoSQL (documentale o key-value) se servono scalabilità orizzontale spinta e schemi flessibili.

Q: Come garantisci la consistenza dei dati tra cache e database?R: Adotto il pattern Cache-Aside con invalidazione esplicita su scrittura o Write-Through, impostando sempre un TTL cautelativo per mitigare eventuali discrepanze residue.

Q: Come gestisci picchi improvvisi di traffico su un endpoint di scrittura critico?R: Inserisco un message broker a monte per assorbire il carico (load leveling) ed elaborare le scritture in modo asincrono tramite worker scalabili.

Q: Qual è la strategia per partizionare un database che supera la capacità di un singolo nodo?R: Implemento uno sharding orizzontale basato su una shard key uniforme (come hash di user_id), integrando Consistent Hashing per ridurre il riallocamento dei dati durante l'aggiunta di nodi.

Insidie e errori comuni

Saltare direttamente al diagramma dei blocchi senza aver quantificato QPS e storage.

Sovraingegnerizzare la soluzione introducendo microservizi o cluster distribuiti non giustificati dai volumi.

Dimenticare l'eviction policy della cache (LRU, LFU) o trascurare il problema del Cache Stampede.

Trattare la rete come affidabile e priva di latenza, ignorando timeout, retry esponenziali e jitter.

Omettere l'autenticazione, l'autorizzazione e le policy di rate limiting al livello del gateway.

Snippet e comandiPlaintext

```Client -> Cloudflare (CDN/WAF)

-> API Gateway (Auth & Rate Limit)

-> Service Cluster (Stateless)

|-> Cache Layer (Redis Cluster / LRU)

|-> Primary DB (Write) -> Replica DB (Read)

|-> Message Queue (Kafka) -> Async Consumers

```

Da ripassare

[ ] Formule rapide per stima QPS: 1 milione di richieste al giorno corrispondono a circa 12 QPS costanti.

[ ] Consistent Hashing e gestione del ring con virtual nodes.

[ ] Strategie di mitigazione del failure: bulkhead, circuit breaker e fallback gracefull.

[ ] Trade-off di replica: sincrona, asincrona e semi-sincrona.

[ ] Protocolli di comunicazione: polling lungo, Server-Sent Events e WebSocket.

Jarvis Interviews
Jarvis