Plantilla de Respuesta para Entrevistas de System Design
La mayoría de la gente fracasa en las entrevistas de system design no porque le falte conocimiento técnico, sino porque le falta estructura. Saben de load balancers, capas de cache y colas de mensajes — pero cuando el entrevistador dice “Diseña Twitter,” su cerebro vuelca todo a la vez sin ningún orden particular.
Esta plantilla te da la estructura. Es un framework para rellenar que puedes usar en cualquier pregunta de system design. La construí después de refinar el framework URDGE a lo largo de decenas de entrevistas de práctica. El framework te dice qué pasos seguir. Esta plantilla te dice exactamente qué escribir en la pizarra en cada paso.
La Plantilla (35-45 minutos en total)
Paso 1: Clarificar requisitos (5 minutos)
Escribe estos encabezados en tu pizarra o documento compartido:
REQUISITOS FUNCIONALES
-----------------------
1. [Funcionalidad principal que el sistema DEBE hacer]
2. [Segunda funcionalidad más importante]
3. [Tercera funcionalidad]
(Limita a 3-5. Más = scope creep.)
REQUISITOS NO FUNCIONALES
----------------------------
- Objetivo de disponibilidad: [99.9%? 99.99%?]
- Objetivo de latencia: [< 200ms? < 1s?]
- Modelo de consistencia: [Fuerte? Eventual?]
- Escala: [DAU? QPS? Volumen de datos?]
FUERA DE ALCANCE
-----------------
- [Funcionalidad que explícitamente NO estás diseñando]
- [Otro elemento fuera de alcance]
Qué decir: “Antes de empezar a diseñar, quiero asegurarme de que entiendo bien los requisitos. Esto es lo que estoy entendiendo — corrígeme si me equivoco.”
Por qué funciona: Esto le muestra al entrevistador que piensas antes de construir. También fija el alcance para que no pierdas tiempo en funcionalidades que nadie pidió.
Paso 2: Estimación rápida (3 minutos)
ESTIMACIONES DE ESCALA
-----------------------
Usuarios: [___] DAU
QPS de lectura: [___] peticiones/seg
QPS de escritura: [___] peticiones/seg
Almacenamiento: [___] GB/día → [___] TB en 5 años
Ancho de banda: [___] MB/s
RATIO CLAVE: Lectura:Escritura = [___:___]
Qué decir: “Déjame hacer unas cuentas rápidas para entender la escala para la que estamos diseñando. Esto va a guiar nuestras decisiones de arquitectura.”
Fórmulas para recordar:
- QPS = DAU × peticiones promedio por usuario / 86.400
- QPS en pico ≈ 2-5× el QPS promedio
- Almacenamiento = registros nuevos por día × tamaño del registro × período de retención
Cuándo saltarte este paso: Si el entrevistador dice “no te preocupes por los números” o vas justo de tiempo. A algunos entrevistadores les importa esto, a otros no. Lee la situación.
Paso 3: Diseño de alto nivel (10-15 minutos)
Dibuja estos componentes. Todo system design incluye la mayoría de ellos:
ARQUITECTURA DE ALTO NIVEL
============================
[Cliente] → [Load Balancer] → [API Gateway / Servidores Web]
↓
[Servicio(s) de Aplicación]
↓ ↓
[Base de Datos] [Capa de Cache]
↓
[Almacenamiento de Objetos] (si hay media/archivos)
ENDPOINTS DE LA API
--------------------
POST /api/v1/[recurso] → Crear [cosa]
GET /api/v1/[recurso]/:id → Leer [cosa]
GET /api/v1/[recurso] → Listar [cosas] (paginado)
DELETE /api/v1/[recurso]/:id → Eliminar [cosa]
MODELO DE DATOS
----------------
Tabla: [entidad_principal]
- id: UUID (clave primaria)
- [campo_1]: [tipo]
- [campo_2]: [tipo]
- created_at: timestamp
- updated_at: timestamp
- INDEX en [campo] para [patrón de consulta]
Tabla: [entidad_relacionada]
- id: UUID (clave primaria)
- [campo_fk]: UUID (clave foránea → entidad_principal)
- [campo]: [tipo]
Qué decir: “Esta es mi arquitectura de alto nivel. Déjame guiarte por el flujo de una petición para el caso de uso principal.”
Consejo: Recorre UN flujo completo de petición desde el cliente hasta la base de datos y de vuelta.
Paso 4: Profundización en componentes clave (10-15 minutos)
Elige 2-3 componentes para profundizar. Selecciónalos según los desafíos más interesantes para ESTE sistema en concreto.
PROFUNDIZACIÓN: [Nombre del Componente]
=========================================
Desafío: [¿Qué hace esto difícil a escala?]
Enfoque: [Tu solución]
Alternativas consideradas:
- [Opción A]: [Ventaja] / [Desventaja]
- [Opción B]: [Ventaja] / [Desventaja]
- [Enfoque elegido]: [Por qué este gana para nuestros requisitos]
Detalle de implementación:
[Detalle técnico específico que demuestra profundidad]
Temas comunes de profundización y cuándo usarlos:
| Tema | Usar cuando el sistema necesita… |
|---|---|
| Particionamiento de base de datos | Alto rendimiento de escritura o volumen masivo de datos |
| Estrategia de cache | Lecturas de baja latencia, ratio lectura:escritura alto |
| Cola de mensajes / procesamiento asíncrono | Servicios desacoplados, consistencia eventual aceptable |
| Limitación de tasa (rate limiting) | API pública, prevención de abuso |
| Búsqueda / indexación | Búsqueda de texto completo, recomendaciones |
| Sistema de notificaciones | Actualizaciones en tiempo real, fan-out |
| CDN / almacenamiento de media | Servir imágenes/vídeos, distribución global |
| Protocolo de consistencia | Transacciones financieras, gestión de inventario |
Qué decir: “Creo que el desafío más interesante en este sistema es [X]. Déjame profundizar en cómo lo manejaría.”
Paso 5: Cuellos de botella y trade-offs (5 minutos)
CUELLOS DE BOTELLA Y MITIGACIONES
====================================
1. Punto único de fallo: [componente]
→ Mitigación: [estrategia de redundancia]
2. Partición caliente / clave caliente: [escenario]
→ Mitigación: [estrategia de distribución]
3. Consistencia de datos: [dónde importa]
→ Mitigación: [enfoque de consistencia]
TRADE-OFFS REALIZADOS
=======================
- Elegí [A] sobre [B] porque [el requisito X importa más que Y]
- Acepté [limitación] a cambio de [beneficio]
- Revisaría [decisión] si [la condición cambia]
Qué decir: “Ningún diseño es perfecto. Déjame repasar los trade-offs que he hecho y los posibles modos de fallo.”
Aquí es donde los candidatos senior se diferencian. Los juniors presentan su diseño como si fuera impecable. Los seniors identifican proactivamente las debilidades y explican por qué son aceptables dados los requisitos.
Ejemplo completo: Diseñar un acortador de URL
Requisitos
REQUISITOS FUNCIONALES
- Los usuarios pueden crear una URL corta a partir de una URL larga
- Los usuarios pueden visitar una URL corta y ser redirigidos
- Las URLs cortas expiran después de un TTL configurable
REQUISITOS NO FUNCIONALES
- Objetivo de disponibilidad: 99.99% (las lecturas deben funcionar siempre)
- Latencia: < 50ms para redirecciones
- Consistencia: eventual está bien (un pequeño retraso antes de que una nueva URL funcione es OK)
- Escala: 100M DAU, 1.000M de redirecciones/día
FUERA DE ALCANCE
- Panel de analíticas
- URLs personalizadas (vanity URLs)
- Cuentas de usuario
Estimación
QPS de lectura: 1.000M / 86.400 ≈ ~12.000/seg (pico: ~36.000/seg)
QPS de escritura: 100M / 86.400 ≈ ~1.200/seg (pico: ~3.600/seg)
Lectura:Escritura = 10:1
Almacenamiento: 100M URLs/día × 500 bytes ≈ 50 GB/día → ~90 TB en 5 años
Diseño de alto nivel
[Cliente] → [Load Balancer] → [Servidores API]
↓
[Cache Redis] ← [Servicio de URLs] → [PostgreSQL]
POST /api/v1/urls {long_url, ttl} → Devuelve {short_url}
GET /:short_code → Redirección 301 a long_url
Tabla: urls
- short_code: VARCHAR(7) PRIMARY KEY
- long_url: TEXT
- created_at: TIMESTAMP
- expires_at: TIMESTAMP
- INDEX en expires_at para limpieza
Profundización: Generación del código corto
Desafío: Generar códigos únicos de 7 caracteres a 3.600/seg sin colisiones.
Enfoque: Codificación Base62 de un contador de un generador de IDs distribuido (estilo Snowflake).
Alternativas:
- Hash MD5 + truncado: Simple pero riesgo de colisión a escala
- Generación aleatoria + verificación en BD: Funciona pero añade latencia en escritura
- Basado en contador (elegido): Único garantizado, predecible, rápido
Detalle: Usar un ID estilo Snowflake (timestamp + ID del worker + secuencia).
Codificar en Base62 para obtener una cadena de 7 caracteres. Ninguna colisión posible por construcción.
Trade-offs
- Elegí consistencia eventual: las nuevas URLs pueden tardar 1-2 segundos en propagarse
a todos los nodos de cache. Aceptable porque los usuarios no comparten una URL
en el primer milisegundo.
- Elegí PostgreSQL sobre DynamoDB: operaciones más simples, y nuestro QPS de escritura
(3.600/seg) está perfectamente dentro de las capacidades de PostgreSQL con connection pooling.
- Acepté que los códigos basados en contador son predecibles: si se necesita privacidad
en las URLs, cambiaría a generación aleatoria con reintento en caso de colisión.
Cómo practicar con esta plantilla
- Elige una pregunta de system design (acortador de URL, app de chat, feed de noticias, sistema de parking).
- Pon un temporizador de 40 minutos.
- Rellena cada sección de la plantilla en papel o en una pizarra.
- Cronometra cada sección. Si pasas más de 5 minutos en los requisitos, estás ampliando demasiado el alcance.
- Practica explicando cada sección en voz alta como si un entrevistador te estuviera observando.
Repite con una pregunta diferente cada dos o tres días. Después de cinco sesiones de práctica, la plantilla se vuelve automática y puedes concentrarte completamente en el contenido técnico en lugar de preguntarte “¿qué digo ahora?”.
La estructura es la red de seguridad. Tu conocimiento es la actuación. Esta plantilla garantiza que la red esté siempre ahí para que puedas arriesgarte en tus decisiones de diseño sin caer en el caos.