System Design Colloquio — Cheat Sheet

Tags: system-design, distributed-systems, scalability, architecture, microservices, databases

Level: advanced

TL;DR: Framework e pattern architetturali per affrontare colloqui di system design: scoping dei requisiti, stime di scala, trade-off CAP e storage.

Key concepts

Chiarire subito requisiti funzionali e non funzionali prima di proporre componenti.

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

Definire le API contrattuali (REST o gRPC) identificando chiaramente payload, parametri e codici di stato.

Tracciare l'architettura ad alto livello partendo dal client verso CDN, Load Balancer e API Gateway.

Applicare la separazione tra read path e write path tramite pattern CQRS ed event-driven architecture.

Valutare trade-off di storage: SQL relazionale per consistenza ACID contro NoSQL per scalabilita orizzontale.

Introdurre caching a piu livelli: client-side, CDN per asset statici e Redis o Memcached per dati calcolati.

Scalare il database tramite read replica, sharding orizzontale e consistent hashing per distribuire le chiavi.

Gestire elaborazioni asincrone e picchi di carico inserendo message broker come Kafka o RabbitMQ.

Considerare osservabilita, affidabilita e resiliency: rate limiting, circuit breaker, retry con backoff esponenziale e monitoring.

Typical questions and ready answers

Q: Come approcci un problema di system design aperto nei primi 5 minuti?R: Parto definendo i requisiti funzionali minimi e i requisiti non funzionali come disponibilita, latenza attesa e consistenza dati, concordando le priorita con l'intervistatore.

Q: Quando scegli SQL rispetto a NoSQL?R: Scelgo SQL per relazioni complesse, integrita referenziale e transazioni ACID critiche; opto per NoSQL per modelli dati flessibili, scritture ad altissimo volume e sharding orizzontale nativo.

Q: Come gestisci la consistenza in un sistema distribuito secondo il teorema CAP?R: Valuto il trade-off: se scelgo CP punto su consistenza forte sacrificando disponibilita durante partizioni di rete; se scelgo AP garantisco risposta accettando consistenza eventuale.

Q: In che modo eviti problemi di hotspot quando effettui lo sharding di un database?R: Evito chiavi sequenziali o monotone, utilizzo consistent hashing con nodi virtuali e combino ID utente con hashing su bucket bilanciati.

Q: Come proteggi i backend da picchi improvvisi di traffico?R: Implemento rate limiting sull'API Gateway con algoritmi token bucket, metto in coda le richieste asincrone su Kafka ed espongo cache per le letture.

Pitfalls and common mistakes

Saltare subito al disegno dei microservizi senza chiarire requisiti e vincoli di scala.

Sovradimensionare l'architettura con troppi componenti distribuiti quando un monolite modulare basta.

Ignorare i single point of failure (SPOF) a livello di load balancer, database master o caching layer.

Proporre caching ovunque senza definire una chiara strategia di invalidazione e gestione di cache stampede.

Dimenticare la consistenza dei dati tra database primario e indici di ricerca o code di eventi.

Tralasciare la gestione dell'idempotenza nelle API che generano transazioni o scritture su code.

Snippets and commandsTypeScript

// Esempio header e logica per garantire l'idempotenza su API di scrittura
interface RequestHeaders {
  'Idempotency-Key': string;
  'Authorization': string;
}

async function handlePayment(idempotencyKey: string, payload: PaymentData): Promise<PaymentResult> {
  const cached = await redis.get(`idemp:${idempotencyKey}`);
  if (cached) return JSON.parse(cached);

  const lock = await redis.set(`lock:${idempotencyKey}`, '1', 'NX', 'EX', 10);
  if (!lock) throw new ConflictError('Request already in processing');

  const result = await paymentService.process(payload);
  await redis.set(`idemp:${idempotencyKey}`, JSON.stringify(result), 'EX', 86400);
  return result;
}

To review

[ ] Calcolo mentale rapido per QPS, storage in TB e banda in Gbps.

[ ] Strategie di caching: Cache-Aside, Write-Through, Write-Behind e relative invalidazioni.

[ ] Funzionamento del Consistent Hashing con nodi virtuali per bilanciamento partizioni.

[ ] Protocolli di consenso distribuito (Raft, Paxos) e 2-Phase Commit vs Saga pattern.

[ ] Meccanismi di Rate Limiting (Token Bucket, Leaky Bucket, Sliding Window Log).

References

Designing Data-Intensive Applications (Martin Kleppmann)

System Design Interview – An Insider's Guide (Alex Xu)

Building Microservices (Sam Newman)

Jarvis Interviews
Jarvis