R
Interview Deckreact · next.js · senior/staff
0·0·122
System Design

System Design — Trade-offs Essenciais

Idempotência, hot/cold path, schema versioning, ordenação, escala, amostragem, privacidade.

Trade-offs centrais que toda entrevista de System Design cobra: (1) Idempotência via event_id (UUID) — broker entrega "ao menos uma vez", processor descarta duplicados. (2) Hot path vs cold path — Lambda/Kappa. (3) Schema versionado — backward compatibility, registry. (4) Ordenação e relógio — client_timestamp + server_timestamp, event time + watermark. (5) Resiliência de coleta — sendBeacon + queue local + retry exponencial. (6) Escala e pico — partition + autoscaling + back-pressure. (7) Amostragem — só sob pico extremo, nunca em purchase. (8) Privacidade/LGPD — consent first, anonimização, retenção.

Problema
Entrar em uma entrevista de System Design sem ter esses trade-offs prontos é entrar para perder. O entrevistador vai cutucar: "e se o pico triplicar?", "e se o evento for reenviado?", "e se o schema mudar?". Sem resposta pronta para cada um, demonstra falta de experiência.
Solução
Memorize os 7 trade-offs com a fórmula: "Problema → Solução → Por quê". Ex: "Eventos chegam fora de ordem? → event time + watermark. Por quê? Porque client clock não é confiável, mas o processor pode tolerar atraso N e ainda agrupar corretamente".
Tip
Termine cada parte da arquitetura mencionando o trade-off antes do entrevistador perguntar. "Aqui uso Kafka com partição por session_id — isso desacopla produtor de consumidor e absorve picos. Trade-off: ordem só é garantida por sessão, não global."
// Os 7 trade-offs com solução prática

// 1. Idempotência → event_id (UUID) + dedupe no processor
// 2. Hot path vs Cold path → ClickHouse + Lake/Warehouse
// 3. Schema versionado → Confluent Schema Registry
// 4. Ordenação → event_time + watermark + client+server timestamps
// 5. Resiliência cliente → sendBeacon + queue + backoff
// 6. Escala → partition by session_id + autoscale + back-pressure
// 7. Amostragem → só sob pico, NUNCA purchase
// 8. LGPD → consent first + anonimização + retention policy

// Frases prontas para a entrevista:
const TALKING_POINTS = {
  pico: "Se o pico triplicar, o gargalo é o processor. Mitigo aumentando partições (scale Flink) e ativando amostragem em eventos de baixo valor.",
  duplicacao: "Reenvio é normal — broker entrega at-least-once. event_id resolve: dedupe no processor com state TTL de 1h.",
  schemaEvolution: "Schema Registry valida compatibilidade backward antes de publicar. Se o novo campo é opcional, OK. Se renomeia, exige campo deprecation antes.",
  ordenacao: "Eventos chegam fora de ordem. Uso event_time + watermark de 30s. Eventos atrasados > 30s vão para um side-output para análise.",
  blackFriday: "Provisionamento por capacidade do pico, não da média. Autoscale do collector + back-pressure do Kafka. Teste de carga com k6 simulando 5x o pico esperado.",
}
Q.O que é idempotência e como garantir?
A.Idempotência = mesma operação aplicada N vezes tem o mesmo efeito de 1 vez. Em tracking: event_id (UUID gerado no cliente) é a chave. Broker pode entregar 2x se a confirmação se perder; processor consulta state (RocksDB) e descarta se já viu esse event_id. TTL no state evita crescimento infinito.
Q.Quando amostrar eventos?
A.Só sob pico extremo (Black Friday picando 5x acima do esperado). Amostre eventos de baixo valor primeiro: page_view, scroll. NUNCA amostre purchase, add_to_cart, ou qualquer evento que vire métrica de receita. Amostragem com hash do session_id para que análise por sessão ainda seja válida.
Q.Qual a diferença entre at-least-once e exactly-once?
A.At-least-once: broker garante entrega, mas pode duplicar se a confirmação se perder. Implementação simples e robusta — Kafka padrão. Exactly-once: nenhuma duplicação possível. Custosa: precisa de transações distribuídas. Em tracking, at-least-once + idempotência (event_id) = efeito de exactly-once a custo baixo.
109/122← →