🎯 Banco de Preguntas — Senior
Preguntas de opción múltiple para evaluar conocimientos de nivel Senior en .NET, arquitectura distribuida, cloud y liderazgo técnico. Cubre trade-offs reales, patrones de diseño y decisiones de arquitectura que se discuten en entrevistas senior.
Intenta responder cada pregunta antes de revelar el resultado. Las explicaciones detallan por qué la respuesta correcta es correcta y por qué las demás están mal.
Arquitectura
❓ ¿Cuándo es recomendable empezar con un monolito modular en lugar de microservicios?
A Solo cuando el equipo tiene menos de 5 personasB Cuando el dominio no está completamente definido, el equipo es pequeño y la velocidad de iteración es prioritariaC Cuando el sistema requiere alta disponibilidad y escalabilidad desde el primer díaD Cuando el proyecto usa tecnologías heterogéneas (Python, Java, .NET) por dominio
❓ ¿Qué problema principal resuelve CQRS y cuál es su trade-off más significativo?
A Elimina la necesidad de base de datos relacional al combinarse con Event SourcingB Separa el modelo de escritura del de lectura para optimizarlos independientemente, a costa de mayor complejidad y eventual consistencyC Resuelve la autenticación distribuida entre microservicios mediante tokens compartidosD Garantiza consistencia fuerte entre servicios sin necesidad de transacciones distribuidas
❓ En el teorema CAP, durante una partición de red en un sistema distribuido, ¿qué determina si debes elegir CP o AP?
A Siempre CP, porque la consistencia es fundamental en cualquier sistema serioB Siempre AP, porque un sistema no disponible es inútil para los usuariosC El dominio del negocio: sistemas financieros y de salud prefieren CP; redes sociales y catálogos prefieren APD La tecnología de base de datos: SQL siempre CP, NoSQL siempre AP
❓ ¿En qué escenario tiene valor real implementar Event Sourcing?
A En cualquier aplicación CRUD para tener historial automático de cambiosB Solo cuando se usa junto con CQRS y Kafka en arquitecturas de microserviciosC Cuando el dominio requiere auditoría completa, reproducir el estado en cualquier punto del tiempo o derivar múltiples proyecciones del mismo flujo de eventosD Cuando la base de datos no soporta transacciones ACID y necesitas consistencia eventual
Clean Architecture y DDD
❓ ¿Cuál es el propósito principal de un Aggregate Root en Domain-Driven Design?
A Que todos los objetos del dominio sean inmutables y no expongan setters públicosB Ser el único punto de entrada al cluster de entidades del aggregate, garantizando que las invariantes de negocio siempre se respetenC Que cada aggregate tenga exactamente una tabla correspondiente en la base de datosD Evitar el uso de repositorios externos al encapsular el acceso a datos internamente
❓ ¿Cuál es la diferencia clave entre un Domain Event y un Integration Event?
A Son lo mismo; solo difieren en el nombre según el contexto arquitectónico que los usaB Los Domain Events viajan por HTTP; los Integration Events viajan por message brokersC Los Domain Events son internos al bounded context y se procesan en la misma transacción o inmediatamente; los Integration Events cruzan límites de servicios de forma asíncronaD Los Domain Events solo existen en Event Sourcing; los Integration Events son exclusivos de CQRS
❓ ¿Cuál es la diferencia fundamental entre un Value Object y una Entity en DDD?
A Un Value Object es inmutable; una Entity puede cambiar su estado. Esta es la única diferencia relevanteB Las Entities se identifican por sus atributos (igualdad estructural); los Value Objects tienen identidad única que persisteC Los Value Objects se identifican por sus atributos (igualdad estructural) y son inmutables; las Entities tienen identidad propia que persiste a lo largo de los cambios de estadoD Los Value Objects solo pueden ser tipos primitivos como string o int encapsulados en una clase
❓ ¿Qué define los límites de un Bounded Context en DDD?
A Los límites físicos de los microservicios desplegados en producciónB El lenguaje ubicuo compartido y el modelo de dominio coherente que lo expresa, generalmente alineado con fronteras organizacionalesC La base de datos que utiliza cada servicio como almacenamiento principalD Los repositorios Git donde reside el código fuente de cada módulo
Microservicios Distribuidos
❓ ¿Por qué se prefiere Saga sobre 2PC (Two-Phase Commit) para transacciones distribuidas entre microservicios?
A Porque Saga garantiza consistencia fuerte igual que 2PC pero sin coordinador centralB Porque 2PC es técnicamente imposible de implementar en microservicios modernosC Porque 2PC requiere que todos los servicios estén disponibles simultáneamente y bloquea recursos durante la transacción; Saga acepta eventual consistency con compensating transactionsD Porque Saga es más fácil de implementar y no requiere diseñar operaciones de rollback
❓ ¿Qué problema resuelve el patrón Circuit Breaker y cómo pasa del estado Open al estado Half-Open?
A Resuelve la autenticación entre servicios; pasa a Half-Open cuando expira el token de servicioB Previene que fallos en cascada agoten los recursos del servicio llamante; pasa a Half-Open tras un timeout configurable para probar si el servicio remoto se recuperóC Balancea la carga entre instancias; pasa a Half-Open cuando detecta que una instancia tiene menos cargaD Encripta las llamadas entre servicios; pasa a Half-Open cuando se renueva el certificado TLS
❓ ¿Qué garantía de entrega ofrece el Outbox Pattern y qué problema concreto resuelve?
A Exactly-once delivery; resuelve la duplicación de mensajes en brokers distribuidosB At-least-once delivery; resuelve el problema de que guardar en base de datos y publicar un evento son dos operaciones que pueden quedar inconsistentes si la app falla entre ambasC At-most-once delivery; resuelve la alta latencia de publicación en brokers bajo cargaD Exactly-once delivery; resuelve la falta de soporte transaccional en bases de datos NoSQL
❓ ¿Cuándo conviene usar BFF (Backend for Frontend) en lugar de un API Gateway genérico?
A Siempre, porque BFF es estrictamente superior a un API Gateway en cualquier escenarioB Cuando diferentes clientes (móvil, web, TV) tienen necesidades de datos tan distintas que un API genérico requiere múltiples llamadas o devuelve campos innecesarios en excesoC Solo cuando el frontend está desarrollado en React; para Angular o Vue se usa API GatewayD Cuando el API Gateway no soporta rate limiting o autenticación de forma nativa
Concurrencia .NET
❓ ¿Por qué NO deberías usar Task.Run para envolver operaciones I/O-bound como llamadas a base de datos o HTTP?
A Porque Task.Run no soporta async/await internamente y bloquearía el hilo del callerB Porque Task.Run toma un thread del ThreadPool para esperar bloqueado, desperdiciando recursos que podrían atender otras requests; await directo libera el thread mientras esperaC Porque Task.Run solo funciona con operaciones CPU-bound en versiones modernas de .NETD Porque Task.Run no maneja correctamente los CancellationToken en operaciones de red
❓ ¿Cuándo usar SemaphoreSlim en lugar de lock para sincronización en .NET?
A SemaphoreSlim es siempre preferible; lock es obsoleto en .NET moderno y genera warningsB Cuando necesitas limitar el acceso concurrente a N threads simultáneos, o cuando el código en la sección crítica contiene operaciones async con awaitC Solo cuando trabajas con múltiples procesos del sistema operativo que comparten memoriaD Cuando necesitas un lock distribuido entre múltiples instancias de la aplicación en distintos servidores
❓ ¿Cuál es el caso de uso principal de IAsyncEnumerable en .NET?
A Reemplazar todas las listas y arrays existentes para mejorar el rendimiento de forma automáticaB Permitir consumir secuencias de datos de forma asíncrona elemento por elemento, útil cuando los datos llegan progresivamente desde una base de datos, archivo grande o API paginadaC Paralelizar el procesamiento de colecciones distribuidas en múltiples threads del CPUD Reemplazar Task de List genérico para reducir el uso de memoria en todas las situaciones posibles
❓ ¿Cuál de las siguientes situaciones puede causar un deadlock en código async .NET?
A Usar await en múltiples operaciones I/O en secuencia dentro de un método async TaskB Llamar a .Result o .Wait() sobre un Task en un contexto de sincronización (ASP.NET clásico o UI thread), mientras el Task necesita capturar ese mismo contexto para continuarC Crear demasiados Tasks concurrentes con Task.WhenAll sin límite de paralelismoD Usar CancellationToken en operaciones de larga duración sin timeout configurado
❓ ¿Cómo afecta la diferencia entre operaciones CPU-bound e I/O-bound al diseño de endpoints en una API .NET?
A No afecta el diseño; async/await resuelve ambos casos exactamente de la misma maneraB Las operaciones CPU-bound deben usar await directo; las I/O-bound deben envolverse en Task.RunC Las operaciones I/O-bound se benefician de async/await puro liberando el thread mientras espera; las CPU-bound deben offloadearse con Task.Run para no bloquear el thread de la requestD Solo las operaciones de más de 100 ms deben ser async; las más cortas pueden ser síncronas sin problema
❓ ¿Cuándo usar Redis distribuido en lugar de IMemoryCache en una API .NET desplegada en múltiples instancias?
A Siempre; Redis es más rápido que IMemoryCache porque usa un servidor RAM dedicadoB Cuando múltiples instancias de la app deben compartir el mismo caché, o cuando el caché debe sobrevivir reinicios de la aplicaciónC Solo cuando la cantidad de datos en caché supera 1 GB de tamaño totalD Cuando necesitas invalidar el caché manualmente desde código de la aplicación
❓ ¿Cuál es la diferencia de rendimiento entre Select con proyección vs Include en EF Core?
A Include siempre es más eficiente porque EF Core optimiza automáticamente los JOINs generadosB Select con proyección genera SQL con solo las columnas necesarias; Include trae la entidad completa causando over-fetching cuando solo necesitas campos específicosC No hay diferencia de rendimiento observable; ambos generan SQL equivalente en el motorD Select con proyección solo funciona con tipos anónimos; Include es necesario para proyectar a DTOs tipados
❓ ¿Qué es el problema del thundering herd y cómo se mitiga en una API con caché?
A Cuando demasiados usuarios acceden a la API simultáneamente, sobrecargando el load balancer de entradaB Cuando una entrada de caché expira y múltiples requests concurrentes llegan al mismo tiempo, todas penetrando al backend antes de que el primero haya repoblado el cachéC Cuando el garbage collector de .NET pausa todos los threads simultáneamente bajo carga altaD Cuando múltiples microservicios llaman al mismo endpoint en cascada, creando un efecto de avalancha de llamadas
Seguridad
❓ ¿Qué es BOLA/IDOR y por qué es la vulnerabilidad más común en APIs REST?
A Un ataque de inyección SQL que explota parámetros de ruta mal sanitizados en endpoints RESTB Broken Object Level Authorization: la API no verifica que el recurso solicitado pertenece al usuario autenticado, permitiendo acceder a datos de otros usuarios modificando un ID en la URLC Un tipo de ataque XSS que inyecta scripts maliciosos en respuestas JSON de la APID Un ataque de fuerza bruta contra el endpoint de autenticación que explota la falta de rate limiting
❓ ¿Dónde debe almacenarse un JWT access token en una SPA y por qué?
A En localStorage, porque es la forma más simple y persiste cómodamente entre sesiones del navegadorB En una cookie con atributo HttpOnly y SameSite=Strict para protegerlo completamente de XSS y CSRFC En memoria del módulo JavaScript como variable de módulo, con el refresh token en cookie HttpOnlyD En sessionStorage, porque es más seguro que localStorage al borrarse automáticamente al cerrar la pestaña
❓ ¿Cuál es la diferencia entre Fixed Window y Token Bucket como algoritmos de rate limiting?
A Fixed Window es más preciso; Token Bucket es una aproximación útil solo para alto throughputB Fixed Window permite bursts al inicio de cada ventana temporal; Token Bucket suaviza el tráfico permitiendo bursts controlados con reposición gradual de tokensC Son equivalentes en comportamiento; solo difieren en la nomenclatura según el proveedor cloudD Token Bucket solo funciona para rate limiting por IP; Fixed Window funciona para rate limiting por usuario
❓ ¿Qué protege HSTS (HTTP Strict Transport Security) y cómo funciona?
A Encripta el contenido de las cookies de sesión con AES-256 en el servidorB Indica al navegador que solo debe conectarse al dominio vía HTTPS, incluso si el usuario escribe http://, previniendo ataques de downgrade y SSL strippingC Protege contra ataques CSRF verificando el origen y el referer de cada request entranteD Habilita Certificate Pinning automático para evitar ataques man-in-the-middle con certificados falsos
Cloud y DevOps
❓ ¿Cuál es la diferencia principal entre Blue/Green deployment y Canary deployment?
A Blue/Green es exclusivo para contenedores Docker; Canary es para despliegues en máquinas virtualesB Blue/Green mantiene dos entornos completos y conmuta todo el tráfico de golpe; Canary dirige un porcentaje pequeño del tráfico a la nueva versión y lo aumenta gradualmenteC Son estrategias idénticas; Blue/Green es el nombre que usa AWS y Canary es el nombre de AzureD Blue/Green requiere downtime de varios minutos; Canary no tiene downtime pero es más lento de ejecutar
❓ ¿Por qué se prefiere Managed Identity sobre connection strings para acceder a servicios Azure desde una aplicación?
A Managed Identity es más rápido porque evita el overhead de la capa de autenticación de Azure ADB Porque elimina la necesidad de gestionar, rotar y almacenar secretos: la identidad de la app se autentica automáticamente con Azure AD sin ningún string de conexión en código o configuraciónC Porque los connection strings no funcionan en Azure App Service, solo en máquinas virtualesD Porque Managed Identity permite acceso a servicios on-premise que los connection strings no soportan
❓ ¿Cuándo usar Azure Service Bus en lugar de Azure Event Hub?
A Service Bus para mensajes de más de 1 MB; Event Hub para mensajes pequeños y frecuentesB Service Bus para mensajería empresarial con garantías de entrega, sesiones y dead-letter queue; Event Hub para streaming de telemetría o eventos de alto volumen donde el orden y el reprocesamiento masivo son prioridadC Son equivalentes en funcionalidad; Service Bus es la versión heredada que Event Hub reemplazaD Event Hub para comunicación entre microservicios; Service Bus exclusivamente para notificaciones a usuarios finales
❓ ¿Qué problema fundamental resuelve Infrastructure as Code (IaC) con herramientas como Terraform?
A Automatiza el despliegue del código de la aplicación en los servidores de producciónB Elimina la configuración manual de infraestructura (snowflake servers), haciendo la infraestructura reproducible, versionable y auditable en Git como cualquier otro códigoC Monitoriza la infraestructura en tiempo real y alerta automáticamente cuando hay problemasD Reemplaza los pipelines de CI/CD siendo una alternativa más poderosa al despliegue continuo
Liderazgo Técnico
❓ ¿Cómo priorizarías la deuda técnica en un backlog que compite con features de negocio?
A La deuda técnica siempre tiene prioridad sobre las features porque si no se paga, el proyecto inevitablemente muereB La deuda técnica nunca es prioritaria; primero se entregan todas las features que pide el negocioC Priorizar la deuda que está ralentizando activamente el desarrollo o causando incidentes, y vincularla a features próximas para justificar el costo frente al negocio con ROI concretoD Asignar exactamente el 20% del tiempo de cada sprint a deuda técnica, independientemente del contexto del proyecto
❓ ¿Para qué sirve un ADR (Architecture Decision Record) y cuándo crearlo?
A Es un documento de requisitos funcionales que reemplaza las historias de usuario en proyectos técnicosB Es un registro formal de una decisión arquitectónica significativa: qué se decidió, por qué, qué alternativas se consideraron y qué trade-offs se aceptaronC Es un informe de deuda técnica generado automáticamente por herramientas de análisis estático de códigoD Es un artefacto del framework Scrum que documenta el diseño técnico detallado de cada sprint
❓ ¿Cuál es el criterio más importante en una decisión Build vs Buy para un componente de software?
A Siempre Buy para no distraer al equipo del desarrollo del core del negocioB Siempre Build para mantener control total y evitar dependencias externas en el sistemaC Si el componente es parte del core diferencial del negocio, construir; si es infraestructura commoditizada, comprar o usar open sourceD El costo inicial: si la solución externa es más barata que construir, siempre comprar sin más análisis
❓ Durante un code review, ¿qué deberías revisar con mayor prioridad?
A El estilo de código y el formateo, ya que impactan directamente la legibilidad del equipoB Los nombres de variables y la longitud de los métodos como indicadores de calidadC La corrección lógica, seguridad, manejo de errores y casos borde antes que el estilo o los nombresD Los tests unitarios primero; si los tests pasan y tienen buena cobertura, el código está bien
Observabilidad
❓ ¿Cuál es la diferencia fundamental entre los tres pilares de la observabilidad: logs, métricas y trazas distribuidas?
A Son sinónimos: todos registran eventos del sistema con diferente nivel de detalleB Los logs registran eventos discretos con contexto, las métricas agregan datos numéricos en el tiempo, y las trazas siguen el flujo de una request a través de múltiples serviciosC Las métricas reemplazan a los logs en sistemas modernos porque consumen menos almacenamientoD Las trazas distribuidas solo son necesarias en sistemas con más de 10 microservicios
❓ ¿Por qué se recomienda logging estructurado en lugar de concatenar strings en los logs en sistemas de producción?
A Porque el logging estructurado es más rápido en términos de CPU al evitar concatenación de stringsB Porque el logging estructurado emite JSON con campos tipados como `userId`, `action`, `durationMs`, lo que permite búsquedas, filtros y alertas precisas en sistemas como Elasticsearch o LokiC Porque la concatenación de strings viola las reglas de StyleCop y los linters modernosD Porque el logging estructurado comprime mejor y reduce el costo de almacenamiento en cloud
❓ ¿Cuál es la diferencia entre SLI, SLO y SLA en el contexto de Site Reliability Engineering?
A Son tres formas de nombrar lo mismo: el acuerdo de nivel de servicio con el clienteB SLI es la métrica medida (ej: 99.2% de requests exitosas), SLO es el objetivo interno (ej: 99.5%), y SLA es el contrato externo con penalización económica si se incumple (ej: 99%)C SLO siempre debe ser igual al SLA para garantizar que el servicio cumple el contrato con el clienteD El SLI se define en el contrato con el cliente, el SLO es el objetivo del equipo de operaciones, y el SLA es solo relevante para equipos de ventas
❓ ¿Cuál es la diferencia entre liveness probe y readiness probe en Kubernetes?
A Son equivalentes: Kubernetes usa cualquiera de las dos para decidir si reiniciar un podB Liveness probe determina si el contenedor está vivo (si falla, Kubernetes lo reinicia). Readiness probe determina si el contenedor está listo para recibir tráfico (si falla, se elimina del load balancer sin reiniciarlo)C Readiness probe verifica la salud de las dependencias externas como la base de datos, mientras que liveness solo verifica el proceso principalD Liveness probe es obligatoria en producción y readiness probe es opcional para optimizar el despliegue
Arquitectura Event-Driven
❓ ¿Cuándo elegirías Apache Kafka sobre RabbitMQ para un sistema de mensajería?
A Siempre Kafka, ya que es más moderno y tiene mayor adopción en la industriaB Kafka cuando necesitas retención y replay de eventos, alto throughput y múltiples consumidores independientes. RabbitMQ cuando necesitas routing flexible, colas con prioridad o mensajería punto a punto con confirmaciones por mensajeC RabbitMQ siempre para microservicios porque implementa el protocolo AMQP estándar que todos los lenguajes soportanD Kafka para mensajes pequeños (menos de 1 MB) y RabbitMQ para payloads grandes
❓ ¿Qué problema resuelve el Outbox Pattern y qué garantía proporciona?
A Garantiza que los mensajes lleguen exactamente una vez al broker de mensajes usando transacciones XA distribuidasB Resuelve la dualidad de escritura entre la base de datos y el broker de mensajes: persiste el evento en la misma transacción de base de datos que los datos del dominio, y un proceso separado publica el evento al broker de forma asíncronaC Es un patrón para almacenar los mensajes fallidos en una tabla temporal y reintentarlos con backoff exponencialD Garantiza que el consumidor procesa el mensaje antes de que el productor confirme la operación de negocio
❓ ¿Cuál es la diferencia entre at-least-once y exactly-once delivery, y cuál es más común en la práctica?
A Exactly-once es el estándar en todos los brokers modernos y es la garantía que Kafka ofrece por defectoB At-least-once garantiza que el mensaje se entrega al menos una vez (puede duplicarse), exactly-once garantiza exactamente una entrega. At-least-once es mucho más común porque exactly-once requiere coordinación costosa; la solución práctica es idempotencia en el consumidorC At-most-once y at-least-once son equivalentes en sistemas con acknowledgements automáticosD Exactly-once se logra fácilmente usando transacciones en el consumidor para confirmar el mensaje y actualizar la BD en un solo paso
❓ ¿Cuáles son los trade-offs entre Choreography y Orchestration en el patrón Saga para transacciones distribuidas?
A Choreography es siempre superior porque elimina el punto único de fallo que representa el orquestadorB Orchestration usa un orquestador central que dirige el flujo (más fácil de razonar y observar, pero acoplamiento central). Choreography usa eventos reactivos entre servicios (mayor autonomía, pero el flujo es difícil de razonar y depurar a medida que crece)C Choreography y Orchestration son equivalentes en complejidad; la elección depende únicamente del lenguaje de programaciónD Orchestration requiere mensajería asíncrona y Choreography puede implementarse con llamadas REST síncronas entre servicios
Escalabilidad de Bases de Datos
❓ ¿Cuál es la diferencia entre sharding horizontal y particionamiento vertical de una base de datos?
A Sharding horizontal divide la tabla por columnas y el particionamiento vertical divide por filasB Sharding horizontal distribuye filas entre múltiples nodos usando una shard key (ej: `userId % N`). Particionamiento vertical divide tablas con muchas columnas en tablas más pequeñas separando columnas de acceso frecuente de las de acceso raroC Sharding y particionamiento vertical son sinónimos en la terminología de SQL Server y PostgreSQLD El particionamiento vertical solo aplica a bases de datos NoSQL orientadas a documentos como MongoDB
❓ ¿Qué es un covering index y cómo reduce el I/O en una consulta?
A Un covering index es un índice que cubre todas las tablas del esquema para evitar full table scansB Un covering index incluye todas las columnas que necesita una query específica, permitiendo que el motor resuelva la query completamente desde el índice sin acceder a la tabla (heap o clustered index)C Un covering index es un índice compuesto con más de tres columnas que cubre múltiples condiciones WHERED Los covering indexes solo son posibles en SQL Server mediante la cláusula INCLUDE; PostgreSQL no los soporta
❓ ¿Cuándo es correcto elegir una base de datos NoSQL sobre una relacional SQL para un sistema nuevo?
A Siempre que el proyecto tenga alta carga, porque NoSQL escala mejor horizontalmente que cualquier base SQLB Cuando el esquema es genuinamente variable o no conocido de antemano, se requiere escala horizontal masiva sin joins complejos, o el modelo de datos se ajusta naturalmente a documentos, grafos o series temporalesC Cuando el equipo no tiene experiencia con SQL, ya que NoSQL tiene una curva de aprendizaje más bajaD Cuando el sistema necesita alta disponibilidad, ya que las bases SQL no soportan replicación multi-región
❓ ¿Qué es la estrategia Expand/Contract (también llamada parallel change) para migraciones zero-downtime?
A Es un patrón para expandir la capacidad del servidor antes de una migración y reducirla después para optimizar costosB Es una estrategia de migración en tres fases: Expand (añadir la nueva estructura sin eliminar la antigua), migrar datos y actualizar código gradualmente, y Contract (eliminar la estructura antigua una vez que ningún código la usa)C Es un patrón que expande las transacciones de base de datos para incluir validaciones de esquema automáticas antes de cada despliegueD Es equivalente a una migración con rollback: primero se expande el esquema y si falla se hace rollback contrayendo los cambios
Concurrencia Avanzada
❓ ¿Cuál es la diferencia entre `lock` (Monitor) y `SemaphoreSlim` en .NET y cuándo usar cada uno?
A Son equivalentes: `SemaphoreSlim` es la versión moderna de `lock` con mejor rendimiento en todos los escenariosB `lock` es ideal para secciones críticas síncronas de corta duración con un único thread permitido. `SemaphoreSlim` permite controlar el número de accesos concurrentes y soporta `await` para no bloquear threads del thread poolC `lock` es thread-safe y `SemaphoreSlim` no lo es; por eso `lock` se usa en código de producciónD `SemaphoreSlim` solo es necesario cuando hay más de 10 threads accediendo concurrentemente al mismo recurso
❓ ¿Qué es un deadlock y cómo se produce el escenario clásico en aplicaciones multithreaded?
A Un deadlock ocurre cuando un thread entra en un bucle infinito consumiendo 100% de CPU sin liberar el controlB Un deadlock ocurre cuando dos o más threads se esperan mutuamente para liberar recursos, generando un ciclo de espera del que ninguno puede salir. El escenario clásico: Thread A tiene el Lock 1 y espera el Lock 2; Thread B tiene el Lock 2 y espera el Lock 1C Un deadlock es equivalente a una race condition: ambos ocurren cuando múltiples threads acceden al mismo recurso sin sincronizaciónD Los deadlocks solo ocurren en bases de datos; en código de aplicación .NET son imposibles gracias al garbage collector
❓ ¿Por qué `async void` es peligroso en C# y cuándo es aceptable usarlo?
A `async void` es peligroso porque es más lento que `async Task` al no poder ser esperado por el schedulerB `async void` es peligroso porque las excepciones no pueden ser capturadas por el llamador y si ocurren crashean el proceso. Solo es aceptable en event handlers de UI (Button.Click) porque el framework los requiere con esa firmaC `async void` genera memory leaks porque el runtime no puede rastrear cuándo el método termina para liberar recursosD `async void` es un antipatrón absoluto que no debe usarse nunca en código de producción bajo ninguna circunstancia
System Design
❓ ¿Cómo diseñarías un sistema de caché distribuida para reducir la carga en una base de datos con alto tráfico de lectura?
A Poner Redis delante de todas las queries sin distinción y con TTL de 1 hora para maximizar el hit rateB Identificar los datos calientes con patrones de lectura, aplicar Cache-Aside con TTL apropiado por tipo de dato, manejar explícitamente cache invalidation y diseñar para cache miss storms con probabilistic early expiration o distributed locksC Usar caché solo para queries que tarden más de 500ms según los logs de slow queriesD Replicar la base de datos en múltiples read replicas en lugar de usar caché, ya que las replicas siempre tienen datos frescos
❓ ¿Cuál es el principal trade-off del patrón CQRS (Command Query Responsibility Segregation) en un sistema distribuido?
A El principal trade-off es que CQRS requiere duplicar todo el código de dominio para el modelo de lectura y el de escrituraB El principal trade-off es la eventual consistency entre el Write Model y el Read Model: las proyecciones pueden estar temporalmente desactualizadas, lo que requiere que la UI y los consumidores estén diseñados para tolerarlaC El principal trade-off es el rendimiento: CQRS siempre es más lento que un CRUD tradicional porque requiere dos round-trips a la base de datosD El principal trade-off es la seguridad: al separar comandos y queries es más difícil aplicar autorización consistente
❓ ¿Qué afirma el CAP Theorem y qué eligen los sistemas CP vs AP en la práctica?
A CAP Theorem afirma que un sistema distribuido puede garantizar Consistency, Availability y Performance, pero solo dos de los tres simultáneamenteB CAP Theorem afirma que durante una partición de red un sistema solo puede garantizar Consistency o Availability, no ambas. Los sistemas CP priorizan consistencia (ej: ZooKeeper, etcd). Los sistemas AP priorizan disponibilidad con eventual consistency (ej: Cassandra, DynamoDB en modo eventual)C CAP Theorem aplica solo a bases de datos NoSQL; los sistemas SQL tradicionales están exentos porque usan ACIDD CAP Theorem fue refutado por el PACELC model y ya no es relevante para el diseño de sistemas modernos