Diseño de Sistemas Preguntas de entrevista
Las entrevistas de diseño de sistemas evalúan cómo delimitas un problema ambiguo y razonas sobre compensaciones a escala. No hay una única respuesta correcta — los entrevistadores quieren un enfoque claro y estructurado.
Lo que cubren las entrevistas de Diseño de Sistemas
Requisitos y alcance
Aclarar los requisitos funcionales y no funcionales antes de diseñar cualquier cosa.
Estimación
Cálculos aproximados de tráfico, almacenamiento y ancho de banda para justificar decisiones.
Diseño de alto nivel
APIs, modelo de datos, componentes principales y el flujo de datos entre ellos.
Escalado y compensaciones
Caché, fragmentación, replicación, colas, consistencia vs disponibilidad y cuellos de botella.
Ejemplos de preguntas de entrevista sobre Diseño de Sistemas
- Diseña un acortador de URLs como bit.ly.Lo que cubre una buena respuesta
- Determinación de ID único: hash de base62 o generación secuencial con consistencia distribuida
- Redirección HTTP 301 vs 302: caching vs actualización de metadatos
- Almacenamiento: base de datos relacional con indexación O(1) por clave corta
- Balanceo de carga y escalabilidad: decodificación en caché (Redis) para accesos frecuentes
Ver respuesta de ejemplo
Para diseñar un acortador de URLs como bit.ly, primero se define un sistema de generación de claves únicas cortas. Una opción es usar un contador global con base62 codificado (0-9, a-z, A-Z) o una función hash como MD5 truncada. Se almacena la relación clave-URL original en una base de datos relacional (por ejemplo, PostgreSQL) indexada por clave para consultas O(log n) o O(1) con hash. El flujo es: el usuario envía la URL, el servidor genera una clave única, la guarda con metadatos (creación, expiración opcional) y devuelve la URL corta. Para redirigir, se recibe la clave, se busca en caché (Redis) primero; si no existe, se consulta la BD y se actualiza el caché. La redirección puede ser 301 (permanente, cacheable por navegadores) o 302 (temporal, permite actualizar estadísticas). Para escalar, se replica la BD con líder-seguidor y se usan múltiples servidores web con un balanceador de carga. Un error común es no manejar colisiones en generación de claves; se debe verificar unicidad o usar un rango reservado. También se debe planificar la limpieza de URLs expiradas para evitar crecimiento infinito.
- Diseña un feed de noticias (por ejemplo, la línea de tiempo de Twitter/Instagram).Lo que cubre una buena respuesta
- Fan-out en escritura vs fan-out en lectura: coste de almacenamiento vs latencia
- Feed basado en amigos o seguidores: grafos sociales en bases de datos NoSQL
- Ordenación temporal: inversión de índices y timestamps con precisión O(log n)
- Caching de feeds: precomputación para usuarios activos y generación bajo demanda para inactivos
Ver respuesta de ejemplo
Para diseñar un feed de noticias como el timeline de Twitter o Instagram, se debe elegir entre fan-out en escritura y fan-out en lectura. Fan-out en escritura: cuando un usuario publica un post, se inserta en los feeds de todos sus seguidores. Esto da lecturas rápidas (O(1) por usuario) pero puede ser costoso en escritura para usuarios con muchos seguidores (celebrities). Alternativamente, fan-out en lectura: cada usuario solicita su feed y se consultan los posts de los usuarios que sigue, mezclándolos por fecha; esto escala bien en escritura pero la lectura es O(n) donde n es el número de seguidos. En la práctica se usa un híbrido: los usuarios normales reciben fan-out en escritura mediante un workqueue (Kafka, RabbitMQ) que llena una tabla de feeds (ej. Cassandra o Redis), mientras que los seguidores de celebridades obtienen sus posts bajo demanda desde una caché de posts recientes. La ordenación se basa en timestamps con monótonos (ej. milisegundos) o un ranking algorítmico (puntuación de relevancia). Se deben almacenar metadatos como likes, comentarios, que pueden actualizarse asíncronamente para evitar latencia. Un error común es asumir que todos los seguidores ven el feed en tiempo real; el sistema debe tolerar retrasos de segundos a minutos. Para escalar, se particiona por usuario (sharding por ID de usuario) y se usan CDN para contenido multimedia.
- Diseña un limitador de tasa para una API pública.Lo que cubre una buena respuesta
- Algoritmos de limitación: Token Bucket, Leaky Bucket, Ventana Deslizante, Contador Fijo
- Almacenamiento de estado: Redis con clave por IP/usuario y TTL
- Estrategia de respuesta: HTTP 429 con cabeceras Retry-After y X-RateLimit
- Distribución: consistencia eventual y balanceo entre nodos de limitadores
Ver respuesta de ejemplo
Para diseñar un limitador de tasa para una API pública, se define una política por cliente (IP, API key) con un límite de peticiones por ventana (ej. 1000 requests/hora). El algoritmo Token Bucket es común: un bucket almacena hasta N tokens y se rellena a R tokens/segundo; cada petición consume un token. Se puede implementar en memoria o con Redis usando un contador con TTL y clave por cliente. La ventana deslizante (sliding window) es más precisa que un contador fijo: se almacenan timestamps en un sorted set de Redis y se cuentan los que caen en el intervalo. Al superar el límite, se responde con estado 429 y cabeceras como X-RateLimit-Limit, X-RateLimit-Remaining, y Retry-After. Para escalar horizontalmente, los limitadores deben compartir estado en un almacenamiento centralizado (Redis, Memcached) o usar algoritmos distribuidos con consistencia eventual (ej. token bucket con balanceo de carga y tolerancia a error). Un error común es no considerar la localidad de los nodos; si hay múltiples instancias sin estado compartido, el límite global se sobrepasaría. Se debe usar Redis cluster con replicación o un sistema de contadores distribuidos como Cloudflare. También es clave la monitorización para ajustar límites dinámicamente.
- Diseña un sistema de chat que soporte mensajería grupal y recibos de lectura.Lo que cubre una buena respuesta
- Mensajería persistente: base de datos SQL o NoSQL con índices por sala y timestamp
- Mensajería en tiempo real: WebSocket para baja latencia con reconexión (fallback a long polling)
- Recibos de lectura: actualizaciones asíncronas con indicador leído/entregado por usuario y mensaje
- Mensajería grupal: fan-out en escritura a la sala e índice de miembros para actualizar metadatos
Ver respuesta de ejemplo
Para diseñar un sistema de chat con soporte grupal y recibos de lectura, se requiere una capa de comunicación en tiempo real (WebSocket) y un almacenamiento persistente. Los mensajes se guardan en una base de datos NoSQL (Cassandra, DynamoDB) o SQL particionada por sala (chat_room_id), con un timestamp compuesto (UUID ordenable o número de secuencia). Cuando un usuario envía un mensaje a un grupo, el servidor lo persiste y lo reenvía a todos los miembros conectados mediante WebSocket, con un acuse de recibo a nivel de red (ACK). Para recibos de lectura, cada usuario envía un evento 'read' cuando visualiza un mensaje; el servidor actualiza un marcador de último mensaje leído por usuario en la sala, almacenado en Redis para consultas rápidas. Esto permite mostrar a otros usuarios quién ha leído hasta dónde. Para escalar, se usan servidores de chat con sharding por sala (basado en hash del ID de sala) y un balanceador de carga sticky. Los mensajes se replican en una cola (Kafka) para persistencia asíncrona. Un error común es no manejar la concurrencia del orden de mensajes: usar un reloj de vector o un timestamp monotónico por servidor. También los recibos de lectura pueden causar tráfico excesivo; se deben coalescer (enviar cada pocos segundos). La mensajería grupal requiere que el servidor conozca la lista de miembros, gestionada en un servicio de directorio (ej. Redis sorted set por sala).
- ¿Cómo escalarías un servicio de 1k a 10M de usuarios?Lo que cubre una buena respuesta
- Separación de responsabilidades: servidores web, aplicación, base de datos, caché
- Escalabilidad vertical vs horizontal: añadir recursos vs máquinas, coste y límites
- Caché: Redis/Memcached para reducir carga en BD, con estrategia de expiración LRU
- Sharding de base de datos: partición por ID de usuario o funcional, con consistencia distributiva
Ver respuesta de ejemplo
Para escalar un servicio de 1.000 a 10 millones de usuarios, se debe evolucionar de una arquitectura monolítica a una distribuida. Inicialmente, con 1k usuarios, un solo servidor con base de datos relacional (PostgreSQL) y servidor web (Nginx+WSGI) basta. Al crecer, se escala verticalmente el servidor (más RAM, CPU) hasta que el costo sea prohibitivo. Luego, se escala horizontalmente: se separa la base de datos en un clúster con replicación maestro-esclavo para separar lecturas de escrituras. Se introduce una capa de caché (Redis) para consultas frecuentes, con invalidación por expiración temporal. Se balancean peticiones HTTP mediante un balanceador de carga (HAProxy, AWS ELB) hacia múltiples instancias web sin estado. Para la base de datos, se implementa sharding (particionamiento horizontal) por ID de usuario con un proxy como Vitess, o se migra a una base de datos NoSQL (Cassandra, DynamoDB) que escala nativamente. Se utilizan colas de mensajes (RabbitMQ, Kafka) para tareas asíncronas (envío de emails, procesamiento de imágenes). También se debe cachear páginas estáticas en CDN. Un error común es no planificar la migración de datos entre shards o no tener una estrategia de replicación geográfica para latencia global. Finalmente, se monitorea con métricas (CPU, QPS, latencia) y se automatiza el escalado con balanceo elástico.
- Diseña un almacén de clave-valor distribuido con alta disponibilidad.Lo que cubre una buena respuesta
- Particionamiento: hash consistente con anillos virtuales y replicación de factores (N nodos)
- Alta disponibilidad: replicación asíncrona o síncrona (Raft/Paxos) para tolerancia a fallos
- Operaciones: get/put con quorum de lectura y escritura (R + W > N)
- Gestión de fallos: detección mediante gossip protocol y handoff para escrituras pendientes
Ver respuesta de ejemplo
Para diseñar un almacén de clave-valor distribuido con alta disponibilidad, se utiliza una arquitectura basada en hash consistente sobre un anillo de nodos (como DynamoDB o Cassandra). Cada clave se asigna a una posición en el anillo y se replica a N nodos siguientes (por ejemplo, N=3). Las operaciones de get y put se realizan con un quorum: el cliente envía la solicitud a todos los nodos replicados y espera al menos W/2 respuestas para escritura (W=1: escritura eventual; W=N: fuerte). Para disponibilidad, se prefiere consistencia eventual con resolución de conflictos mediante relojes vectoriales. La replicación puede ser asíncrona para baja latencia (mejor disponibilidad) o síncrona con Raft para consistencia fuerte (menor disponibilidad). Para detectar fallos, cada nodo usa un protocolo gossip para mantener una lista de nodos vivos; si un nodo cae, otro nodo se hace cargo temporalmente (handoff). La persistencia se realiza en disco (SSD) con estructuras como LSM Trees (Cassandra) o B-Trees (RocksDB). Un error común es no balancear la carga durante añadidos/eliminaciones de nodos; el hash consistente con réplicas virtuales ayuda a distribuir la reubicación de datos. También se debe implementar una capa de proxy (Twemproxy) o cliente con lógica de consistencia para simplificar las aplicaciones.
Cómo prepararse
- Siempre empieza aclarando requisitos y restricciones — no saltes a una solución.
- Usa un marco de trabajo repetible: requisitos → estimación → API → modelo de datos → escalado → compensaciones.
- Expresa las compensaciones explícitamente (por ejemplo, consistencia vs disponibilidad); rara vez hay una única respuesta correcta.
- Dirige la conversación y gestiona el tiempo — cubre primero la amplitud, luego profundiza donde te pregunten.
Preguntas frecuentes
¿Cómo me preparo para una entrevista de diseño de sistemas?
Aprende un marco de trabajo repetible, estudia un puñado de diseños canónicos (feed, chat, acortador de URLs, limitador de tasa) y practica hablar sobre compensaciones en voz alta.
¿Necesito conocer tecnologías específicas?
Conoce los componentes básicos (balanceadores de carga, cachés, colas, SQL vs NoSQL, fragmentación) y sus compensaciones. Nombrar productos exactos importa menos que el razonamiento.
¿Cuál es el error más común?
Saltar directamente a un diseño sin aclarar requisitos o hacer estimaciones, y no expresar las compensaciones.
¿El diseño de sistemas es solo para roles senior?
Es más común en niveles intermedios y senior, pero los candidatos junior pueden obtener una versión más ligera enfocada en un solo componente.
Practica preguntas sobre Diseño de Sistemas con retroalimentación instantánea de IA
Sube tu currículum, obtén una entrevista simulada personalizada y ve exactamente qué mejorar — gratis para empezar.