Enunciado y contexto aplicable
Diseña un servicio de chat de texto con 50 millones de usuarios activos diarios, 5 millones de conexiones concurrentes en horas pico y 2000 millones de mensajes por día. Admite conversaciones directas, grupos de como máximo 200 miembros, múltiples dispositivos por usuario, recuperación sin conexión, confirmaciones de entrega y lectura, presencia e indicadores de escritura. Los archivos adjuntos, canales públicos, escrituras activo-activo multirregión, búsqueda de texto completo y cifrado de extremo a extremo quedan como alcance para preguntas de seguimiento.
El servicio confirma (ACK) un envío únicamente después de que el mensaje se ha almacenado de forma duradera. No debe perder de forma silenciosa ningún mensaje confirmado. Para los destinatarios que ya están en línea bajo una carga normal, el p99 desde la aceptación duradera hasta la llegada a un dispositivo conectado debe ser inferior a un segundo. El transporte puede reenviar mensajes, por lo que los clientes deben ver un único mensaje lógico tras la deduplicación. Se requiere ordenamiento dentro de una misma conversación, no entre conversaciones no relacionadas.
Tres guías públicas de diseño de sistemas publicadas o actualizadas en 2026 presentan el chat como un tema directo de entrevista y examinan reiteradamente conexiones persistentes, enrutamiento de conexiones, ordenamiento por conversación, sincronización sin conexión, confirmaciones de lectura/entrega y presencia. El estándar WebSocket define el transporte bidireccional y las tramas de control, mientras que la especificación cliente-servidor de Matrix proporciona ejemplos de nivel de producción de ID de transacción de cliente, tokens de sincronización incremental, confirmaciones de lectura y eventos efímeros de escritura. Esas fuentes establecen que el tema y sus límites de falla son actuales y técnicamente fundamentados; la escala y el SLO de este enunciado son datos ficticios para la entrevista.
Qué evalúa el entrevistador
La primera señal es la precisión del contrato. «Enviado», «entregado» y «leído» son hechos distintos. Una confirmación del servidor significa aceptación duradera. Una confirmación de entrega significa que un dispositivo destinatario específico recibió el mensaje. Una confirmación de lectura requiere una regla de producto explícita que indique que el usuario efectivamente visualizó la conversación. Tratar los tres como un solo estado genera falsas afirmaciones de confiabilidad y recuentos incorrectos de mensajes no leídos.
La segunda señal es si el candidato evita prometer un «exactamente una vez» (exactly-once) de extremo a extremo. Un cliente puede agotar el tiempo de espera después de que el servidor confirme la transacción pero antes de que llegue la confirmación. Una puerta de enlace (gateway) puede repetir una entrega tras una reconexión. El contrato práctico es un transporte de «al menos una vez» (at-least-once) combinado con un ID de mensaje de cliente estable, un registro de idempotencia en el servidor y deduplicación en el cliente por ID de mensaje de servidor.
La tercera señal es el límite de ordenamiento. Un orden global serializaría conversaciones no relacionadas. Un contrato de producto útil otorga a cada mensaje aceptado una secuencia monotónica dentro de su conversación. Por lo tanto, todas las escrituras de una conversación llegan a un único dueño o secuenciador actual. Esto preserva el orden local al tiempo que permite que diferentes conversaciones escalen de forma independiente, y expone un límite real de conversación de alto tráfico («hot conversation»).
La cuarta señal es la separación del estado duradero y el efímero. Los mensajes, los intervalos de membresía y los cursores de lectura sobreviven a los fallos. La presencia y el estado de escritura pueden expirar y descartarse. Permitir que el tráfico de escritura comparta el registro de mensajes duradero desperdicia almacenamiento y hace que una ráfaga cosmética pueda retrasar mensajes reales.
La señal final es el razonamiento de recuperación. La respuesta debe contemplar la pérdida de confirmación de envío, caídas de gateways, tormentas de reconexión, dueños de conversación obsoletos, dispositivos lentos, cambios de membresía, fan-out duplicado y grupos de alto tráfico. Las cifras de capacidad deben derivarse del enunciado y luego calibrarse mediante pruebas de carga en lugar de presentarse como límites de servidor universales.
Preguntas para clarificar antes de responder
- ¿Qué tipos de contenido y conversación están dentro del alcance? Esta respuesta aborda texto, conversaciones directas y grupos de hasta 200 miembros. Los archivos adjuntos utilizan almacenamiento de objetos y mensajes de metadatos; los canales públicos requieren una estrategia diferente de fan-out e historial.
- ¿Qué significa cada confirmación de estado (receipt)? Servidor aceptó, dispositivo recibió y usuario leyó son hechos monotónicos independientes. «Leído» ocurre únicamente cuando el cliente muestra la conversación relevante, no cuando simplemente recibe una notificación push.
- ¿Qué ordenamiento se requiere? El enunciado exige un orden estable por conversación. No promete que el reloj de pared de un usuario determine el orden ni que dos conversaciones diferentes compartan una secuencia.
- ¿Puede un usuario enviar desde múltiples dispositivos? Sí. Cada dispositivo tiene su propia conexión autenticada y cursor de sincronización; los reintentos del emisor reutilizan el mismo ID de mensaje de cliente.
- ¿Qué sucede cuando cambia la membresía? La autorización se verifica al momento de la aceptación. El producto debe definir si un nuevo miembro puede leer el historial anterior y qué conserva localmente un miembro eliminado. Este diseño almacena intervalos de membresía indexados por la secuencia de la conversación.
- ¿Cuánto tiempo se retienen los mensajes y los registros de idempotencia? La retención de mensajes es una decisión de producto y cumplimiento normativo. El mapeo de idempotencia debe cubrir la ventana máxima de reintento del cliente; borrarlo antes puede recrear duplicados.
- ¿Qué regiones se utilizan? La respuesta base asigna a cada conversación una región principal (home region) y realiza conmutación por error (failover) de forma deliberada. Las réplicas de escritura simultáneas en múltiples regiones requieren un modelo de resolución de conflictos y ordenamiento más complejo.
- ¿Qué queda fuera del objetivo de un segundo? La visualización de notificaciones push sin conexión, la recuperación tras reconexión, el tiempo de lectura del usuario y la recuperación ante desastres multirregión se miden por separado de la entrega en vivo a un dispositivo ya conectado.
Estructura de respuesta en 30 segundos
«Separaría la gestión de conexiones de la ruta de mensajes duraderos. El cliente envía mensajes a través de un WebSocket autenticado con un ID de mensaje de cliente estable. Un servicio enrutado por conversación vuelve a verificar la membresía, asigna la siguiente secuencia por conversación, almacena atómicamente el mensaje y el resultado de idempotencia, y solo entonces envía la confirmación. Un worker asíncrono de fan-out busca los dispositivos receptores activos y envía el mensaje a sus gateways; los dispositivos desconectados o que fallaron se recuperan mediante una API de sincronización basada en cursores. Los cursores de entrega y lectura avanzan de forma monotónica, mientras que la presencia y el estado de escritura utilizan una ruta independiente con expiración. El transporte es al menos una vez, por lo que tanto el servidor como el cliente deduplican. A la escala planteada, planificaría aproximadamente 23 000 envíos promedio y 230 000 en pico por segundo, alrededor de 2 TB de datos lógicos de mensajes por día a 1 KB cada uno, y probaría mediante pruebas de carga conexiones persistentes, grupos de alto tráfico, tormentas de reconexión, reintentos, cambios de membresía y failover de dueños frente al SLO».
Análisis detallado paso a paso
Paso 1: Congelar los contratos de producto y calcular la primera estimación de capacidad.
Dos mil millones de mensajes por día promedian cerca de 23 148 envíos por segundo. Si el pico es diez veces el promedio, la planificación de entrada comienza alrededor de 230 000 envíos por segundo. Asumiendo 1 KB por mensaje almacenado, incluidos metadatos comunes e índices, el volumen de escritura lógica es de aproximadamente 2 TB por día; tres réplicas representan cerca de 6 TB por día antes de compactación, reserva del sistema de archivos, respaldos y escrituras de confirmaciones. Estas son suposiciones de planificación, no límites de hardware medidos.
Cinco millones de conexiones concurrentes dominan la planificación de gateways. Supongamos que una prueba de carga en la instancia seleccionada, configuración TLS, intervalo de latidos (heartbeats) y p99 objetivo demuestra 50 000 conexiones estables por gateway. El mínimo estricto es de 100 gateways. Operar al 70% de ese límite medido requiere aproximadamente 143, redondeado a 150, más una reserva para fallos de zona. La prueba debe incluir mensajes, reconexiones y clientes lentos; un recuento de sockets inactivos por sí solo resulta engañoso.
Paso 2: Definir el protocolo de cliente y sus identidades.
Cada dispositivo abre un WebSocket autenticado hacia un gateway regional. El gateway valida el origen cuando corresponde, limita el tamaño de trama y la tasa de envío, actualiza la autorización y utiliza ping/pong junto con un arrendamiento (lease) para detectar conexiones caídas. RFC 6455 proporciona la mecánica de conexión; el protocolo de aplicación sigue siendo responsable de la autenticación, confirmaciones, secuenciación, reintentos y contrapresión (backpressure).
Las tramas centrales pueden expresarse como:
SEND {
conversation_id, client_message_id, body, client_sent_at
}
ACK {
client_message_id, message_id, conversation_seq, accepted_at
}
MESSAGE {
conversation_id, message_id, conversation_seq, sender_id, body, accepted_at
}
SYNC {
device_sync_cursor, limit
}client_message_id se genera una vez y se reutiliza para cada reintento desde ese dispositivo emisor. message_id es la identidad de servidor utilizada para la deduplicación del destinatario. conversation_seq es el orden de visualización y recuperación dentro de una conversación. accepted_at es la hora del servidor para fines de diagnóstico, no la autoridad de ordenamiento.
Paso 3: Confirmar una sola vez por envío lógico antes de responder con ACK.
El gateway reenvía SEND al servicio de chat. El servicio obtiene el fragmento (shard) de conversación actual, autentica al emisor, verifica la membresía en la versión actual de membresía, valida el tamaño y aplica límites por usuario y por conversación. El dueño del shard serializa las escrituras aceptadas para esa conversación.
En una sola transacción duradera, asigna la siguiente secuencia, escribe el mensaje y guarda un mapeo único como (sender_device_id, client_message_id) → message_id. Una solicitud duplicada devuelve el resultado previo en lugar de agregar otro mensaje. Solo un registro confirmado por quórum recibe ACK. Si la confirmación se pierde, reintentar es seguro. Si el almacenamiento falla antes del commit, no se envía ninguna confirmación.
Los mensajes se particionan por conversation_id y se ordenan por conversation_seq. Los cambios de membresía también se ordenan o hacen referencia a límites de secuencia efectivos, de modo que la autorización no dependa únicamente de una caché de miembros actuales eventualmente consistente. Una época (epoch) de dueño cercada (fenced) evita que un dueño antiguo acepte escrituras tras un failover.
Paso 4: Realizar el fan-out después del commit duradero.
El registro confirmado emite una tarea de entrega. Un directorio de conexiones mapea (user_id, device_id) a un gateway y un arrendamiento de conexión. Para una conversación directa o un grupo de como máximo 200 miembros, el worker de fan-out carga la instantánea de membresía vigente en la secuencia del mensaje, agrupa los dispositivos en línea por gateway y envía comandos por lotes al gateway. El cuerpo del mensaje se almacena una sola vez; el fan-out transporta una referencia o evento compacto en lugar de copiar un cuerpo duradero por cada destinatario.
El gateway coloca el evento en la cola de salida acotada de cada conexión. Un dispositivo devuelve un cursor de entrega monotónico después de haber aceptado el evento localmente. Si una conexión es lenta, el gateway deja de almacenar en búfer de forma indefinida, la marca para resincronización y la cierra con una razón a nivel de aplicación. El registro duradero sigue siendo la fuente de la verdad, por lo que descartar una entrega en vivo en memoria no pierde el mensaje.
Para un usuario desconectado, el sistema puede enviar un indicio de push móvil que preserve la privacidad. Las notificaciones push son un mecanismo de reactivación, no almacenamiento de mensajes ni prueba de entrega. Al abrirse, el cliente se autentica y sincroniza desde el servicio duradero.
Paso 5: Hacer explícita la reconexión y la sincronización multidispositivo.
Cada dispositivo persiste un device_sync_cursor opaco. GET /sync?after=cursor o la trama equivalente devuelve deltas ordenados de conversaciones, cambios de membresía, deltas de confirmaciones y un nuevo cursor. El servidor no debe avanzar el cursor más allá de los eventos omitidos en la respuesta. Si un cursor ha expirado o la brecha es demasiado grande, el servidor devuelve una instantánea acotada más tokens de continuación en lugar de intentar una reproducción ilimitada sobre una sola conexión.
La entrega en vivo y la sincronización pueden superponerse, por lo que el cliente fusiona por message_id y ordena por (conversation_id, conversation_seq). Un nuevo dispositivo recibe el historial permitido por las políticas y establece su propio cursor. El estado de lectura es a nivel de usuario y monotónico por conversación; el estado de entrega puede mantenerse por dispositivo. Las reglas de agregación deben especificar si «entregado» significa cualquier dispositivo o todos los dispositivos activos.
Paso 6: Mantener la integridad de confirmaciones, presencia y escritura.
Una actualización de lectura transporta el conversation_seq visualizado más alto; el servidor utiliza un máximo condicional para que las solicitudes tardías no puedan retroceder el cursor. El modelo de confirmaciones de la especificación Matrix ilustra por qué la lectura es un delta que reemplaza una posición anterior y por qué la mera recepción no es evidencia suficiente de que un usuario haya visto el contenido.
La presencia y el estado de escritura siguen una ruta diferente. Los gateways renuevan un arrendamiento corto de presencia. Los eventos de escritura se autorizan, se limitan por tasa, se acotan a una conversación, se combinan (coalesce) y expiran tras unos segundos. Pueden descartarse durante sobrecargas y nunca entran en el registro de mensajes duradero. La «última conexión» (last seen) requiere una política de privacidad explícita y actualizaciones de granularidad gruesa para evitar convertir el tráfico de latidos en una tormenta de escrituras.
Paso 7: Diseñar las rutas de fallo antes de afirmar confiabilidad.
- Pérdida de
ACK: el cliente reintenta con el mismoclient_message_id; el servidor devuelve el resultado almacenado. - Caída de gateway: los dispositivos se reconectan con fluctuación aleatoria (jitter) y reanudan desde sus cursores; el arrendamiento de conexión expira.
- Caída de worker de fan-out: la tarea de entrega duradera se reintenta; los gateways y clientes deduplican.
- Caída del dueño de conversación: una nueva época y estado de quórum eligen un reemplazo; los dueños obsoletos quedan cercados (fenced).
- Dispositivo lento: las colas acotadas activan una resincronización en lugar de consumir memoria ilimitada.
- Conversación de alto tráfico: un solo secuenciador limita la tasa de escritura. Agrupa commits por lotes, aísla el shard sobrecargado y aplica un límite de tasa a nivel de producto; agregar particiones hash ordinarias no puede paralelizar una secuencia estricta única.
- Condición de carrera en membresía: secuencia los cambios de membresía junto con los mensajes y autoriza contra el intervalo vigente.
- Interrupción regional: enruta la conversación a una réplica promovida solo después de cercar la región principal anterior; el tiempo de recuperación y la posible pérdida no confirmada se evalúan por separado de la garantía de cero pérdidas para mensajes confirmados.
Los intentos de reconexión utilizan retroceso exponencial con fluctuación aleatoria (jittered exponential backoff) y control de admisión. De lo contrario, el reinicio de un gateway regional puede convertir cinco millones de clientes sanos en una tormenta de negociaciones (handshakes) que impida la recuperación.
Paso 8: Demostrar las invariantes con pruebas estratificadas y observabilidad.
Las pruebas basadas en propiedades generan reintentos, entregas reordenadas, cambios de membresía y épocas de dueños, y luego verifican un único mensaje lógico por ID de cliente, secuencias únicas por conversación, cursores monotónicos y la ausencia de mensajes no autorizados tras un límite de eliminación. Las pruebas de integración provocan caídas del proceso antes del commit, después del commit pero antes de la confirmación, y durante el fan-out. Las pruebas de caos eliminan un gateway, worker, dueño de shard, zona y partición del directorio de conexiones.
Las pruebas de carga modelan cinco millones de conexiones de larga duración, 230 000 envíos pico por segundo, fan-out grupal, destinatarios lentos y reconexiones masivas. Observa la latencia de aceptación, latencia de entrega en vivo, retraso de sincronización (sync lag), tasa de duplicados antes y después de la deduplicación del cliente, brechas de secuencia, saturación de shards calientes, bytes en cola de salida, admisión de reconexión y rechazos de lectura no autorizada. Un despliegue canary solo se expande mientras las invariantes de durabilidad y autorización permanezcan intactas.
Respuesta de ejemplo de alta calidad
«Primero definiría tres resultados diferentes: aceptación duradera en el servidor, entrega al dispositivo y lectura del usuario. El servicio confirma únicamente después de que un quórum ha almacenado el mensaje. La entrega por red sigue siendo al menos una vez, por lo que un ID de mensaje generado por el cliente emisor hace que los reintentos sean idempotentes y los receptores deduplican por ID de mensaje del servidor.
Los clientes se conectan a gateways regionales de WebSocket. Un directorio de conexiones indica a los workers de fan-out qué gateway aloja el dispositivo de cada usuario, pero los gateways no poseen el historial. Un servicio de chat enruta cada escritura por ID de conversación al dueño actual cercado (fenced owner). Ese dueño vuelve a verificar la membresía, asigna una secuencia por conversación y almacena atómicamente el mensaje junto con el resultado de idempotencia. Las conversaciones no relacionadas se ejecutan en paralelo; una conversación con tráfico muy alto permanece deliberadamente como un cuello de botella serial.
Tras el commit, los workers realizan fan-out hacia los dispositivos en línea. Las entregas fallidas o sin conexión se subsanan a través de una API de sincronización basada en cursores. Las rutas en vivo y de reproducción pueden superponerse, por lo que los ID de mensaje absorben duplicados y las secuencias de conversación restauran el orden local. Los cursores de lectura avanzan por secuencia máxima. La presencia y el estado de escritura utilizan un estado efímero de mejor esfuerzo (best-effort) y no pueden bloquear los mensajes duraderos.
Con 2000 millones de mensajes al día, el ingreso promedio es de unos 23 000 por segundo; planificaría para unos 230 000 en un pico de diez veces. Bajo la premisa de planificación de 1 KB del enunciado, el almacenamiento lógico de mensajes es de aproximadamente 2 TB por día y 6 TB con tres réplicas. Para cinco millones de conexiones, un límite medido de 50 000 conexiones por gateway implica 100 nodos como mínimo o unos 150 al 70% de utilización antes de la reserva por zona.
Validaría pérdidas de confirmaciones, caídas de gateways y dueños, épocas obsoletas, fan-out duplicado, dispositivos lentos, carreras de membresía, grupos de alto tráfico y tormentas de reconexión. El criterio de liberación es cero pérdidas de mensajes confirmados, ningún mensaje lógico duplicado tras deduplicación, ninguna regresión de secuencia, ningún acceso fuera de los intervalos de membresía y el p99 de entrega en vivo especificado bajo una carga representativa».
Errores comunes
- Error: Denominar a la aceptación del servidor, la entrega y la lectura como un solo estado → Consecuencia: Las métricas de confiabilidad y mensajes no leídos se vuelven inverificables → Solución: Definir estados monotónicos y dueños independientes.
- Error: Prometer entrega de exactamente una vez sobre la red → Consecuencia: Una confirmación perdida o una reconexión produce un duplicado inexplicable → Solución: Utilizar transporte de al menos una vez con ID de envío estables y deduplicación.
- Error: Ordenar todos los mensajes globalmente → Consecuencia: Conversaciones no relacionadas comparten un único cuello de botella → Solución: Asignar una secuencia únicamente dentro de cada conversación.
- Error: Responder con ACK antes del commit duradero → Consecuencia: El fallo de un proceso o zona puede borrar silenciosamente un mensaje aceptado → Solución: Confirmar con ACK únicamente un registro confirmado por quórum.
- Error: Almacenar el historial en los gateways de WebSocket → Consecuencia: El movimiento de conexiones se convierte en movimiento de datos y la pérdida de un gateway amenaza el historial → Solución: Mantener los gateways sin estado más allá del estado de conexión acotado.
- Error: Almacenar en búfer indefinidamente para un dispositivo lento → Consecuencia: Un solo cliente puede agotar la memoria del gateway → Solución: Acotar la cola, desconectar y resincronizar desde el almacenamiento duradero.
- Error: Colocar presencia y escritura en el registro duradero → Consecuencia: El tráfico cosmético con expiración eleva los costos y puede retrasar mensajes → Solución: Usar una ruta autorizada, limitada por tasa, de mejor esfuerzo y con TTL.
- Error: Autorizar únicamente desde una caché de miembros actuales obsoleta → Consecuencia: Usuarios eliminados pueden enviar o recibir durante una condición de carrera → Solución: Ordenar los límites de membresía y cercar la aceptación contra ellos.
- Error: Dimensionar gateways por recuento de sockets inactivos → Consecuencia: TLS, heartbeats, fan-out y reconexiones desbaratan la planificación → Solución: Evaluar la carga de trabajo completa en el p99 objetivo y reservar margen para fallos.
Preguntas de seguimiento y respuestas
Pregunta de seguimiento 1: ¿Cómo agregarías cifrado de extremo a extremo?
Cifraría los cuerpos de los mensajes en los dispositivos emisores y almacenaría únicamente el texto cifrado más los metadatos de enrutamiento requeridos. Cada dispositivo necesita una clave de identidad, una lista de dispositivos firmada y distribución de claves de conversación; agregar o eliminar un dispositivo o miembro rota o redistribuye claves según la directiva. El servidor aún puede secuenciar y enrutar el texto cifrado, pero la búsqueda en el servidor, moderación de contenido, recuperación, vistas previas y control de abusos se ven limitados. Los metadatos de entrega, conjuntos de participantes, tiempos y tamaños pueden seguir siendo observables, por lo que el cifrado no elimina el trabajo de privacidad sobre los metadatos.
Pregunta de seguimiento 2: ¿Se puede dividir un grupo de alto tráfico entre varios secuenciadores?
No si se desea preservar una secuencia contigua estricta sin otra autoridad de ordenamiento. Distribuir la conversación por hash entre más shards comunes sigue dejando un punto de consenso o fusión. Primero agrupa commits por lotes y aísla el shard, luego aplica límites por conversación. Si el producto puede aceptar un orden parcial, particiona por hilo o por emisor y expón relaciones causales, pero eso modifica el contrato y la complejidad del cliente.
Pregunta de seguimiento 3: El emisor ve un ACK, pero un destinatario permanece desconectado durante una semana. ¿Se entregó el mensaje?
Fue aceptado, no entregado a ese dispositivo. El mensaje duradero permanece disponible según la directiva de retención, y una notificación push puede reactivar el dispositivo. Al reconectarse, el dispositivo se sincroniza desde su cursor y luego reporta la entrega. La interfaz de usuario y las métricas del producto deben mantener separados: aceptado por el servidor, entregado a algún dispositivo, entregado a todos los dispositivos activos y leído.
Pregunta de seguimiento 4: ¿Cómo interactúan las ediciones y eliminaciones con el ordenamiento?
Se representan como nuevos eventos ordenados que hacen referencia al mensaje original en lugar de mutar el historial de forma invisible. Los clientes combinan el flujo de eventos en una vista actual. La autorización se comprueba cuando se acepta la edición o eliminación, y la directiva define límites de tiempo y si la eliminación borra el contenido, marca un tombstone o activa un borrado asíncrono en almacenes secundarios.
Pregunta de seguimiento 5: ¿Qué pasa si un miembro eliminado se reconecta con un cursor antiguo?
El servicio de sincronización evalúa los intervalos de membresía del usuario, no el mero hecho de poseer un cursor. Devuelve únicamente los eventos autorizados para ese usuario e incluye el límite de revocación de membresía. Un cursor es una posición opaca, no una credencial de acceso (capability). Los archivos adjuntos en caché y las copias locales requieren expectativas independientes de revocación y retención, ya que el servidor no puede borrar datos ya guardados en un dispositivo.
Pregunta de seguimiento 6: ¿Cómo soportarías canales públicos muy grandes?
El diseño de fan-out en escritura para grupos de 200 ya no resulta adecuado. Se almacena el registro del canal una sola vez, se permite que los seguidores lean mediante cursores (pull), se distribuyen solo indicios compactos de no leídos o notificaciones push, se almacenan en caché los segmentos populares y se relajan las confirmaciones de entrega individuales. La partición, moderación, descubrimiento y los puntos calientes de canales de celebridades se convierten en problemas de primer orden, por lo que debe tratarse como una carga de trabajo distinta y no como un simple valor numérico más alto dentro del mismo diseño.