{
 "subtemas": [],
 "tarjetas": [
  {
   "sub": "Resiliencia",
   "q": "Latency budget: diseñar el P99 antes de codificar",
   "a": "Define el objetivo: buscar producto < 300ms P99.\nPresupuesto por tramo: gateway 20ms, auth 15ms, servicio 150ms, DB 80ms, margen 35ms.\nConsecuencias prácticas: cada dependencia tiene su timeout (≤ presupuesto), el agregador degrada ramas lentas, el caché existe donde el presupuesto no alcanza.\nSin presupuesto, cada equipo optimiza a ciegas.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Circuit breaker: métricas de apertura y tuning fino",
   "a": "Cuenta fallos en ventana (últimos N o últimos T segundos): ratio > umbral → OPEN.\nTuning: failing calls mínimas antes de evaluar (evitar abrir por 2 fallos de tráfico bajo), slow calls (latencia > umbral) cuentan como fallos, half-open con pocas llamadas de prueba.\nExpón el estado como métrica y dashboard — un breaker abierto es un incidente de dependencia visible.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Fallbacks con criterio: qué responder cuando todo falla",
   "a": "Buen fallback: valor default razonable (recomendaciones → 'populares'), caché stale (últimos precios conocidos), función reducida (checkout sin sugerencias).\nMal fallback: exception genérica 500 (para eso no hacías breaker), respuesta VACÍA que la UI interpreta como 'no hay nada'.\nDocumentar el comportamiento degradado en el diseño, no improvisarlo en el incidente.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Bulkhead: aíslar por dependencia y por prioridad",
   "a": "Pools separados: conexiones/hilos para 'pagos' no pueden ser consumidos por 'analytics'.\nPor prioridad: clientes premium / free con capas distintas de rate limit y capacidad.\nConsecuencia: el colapso de una dependencia solo degrada SU compartimiento.\nEn Resilience4j: bulkhead semáforo (in-process) o thread pool (aislamiento duro).",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Load shedding: soltar carga antes de caer",
   "a": "Cuando la saturación llega (cola llena, CPU alta): responder 503 + Retry-After a lo NUEVO y prioritario, o al revés (proteger pago, degradar búsqueda).\nRequiere clasificar requests (endpoint, usuario, prioridad).\nMejor 90% de requests OK que 100% con timeout.\nK8s: HPA + PDB + queue limits; app: límite de cola + criterio de descarte.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Graceful degradation: la matriz de degradación",
   "a": "Tabla: dependencia caída → qué dejo de hacer → qué muestro.\nEjemplos: recomendaciones caídas → ocultar sección; reviews caídas → 'temporalmente no disponible' (no página rota); pagos caídos → modo mantenimiento SOLO de checkout.\nSe diseña en el contrato del frontend (estados vacíos/degradados).\nSe prueba: chaos engineering apaga dependencias en staging.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Chaos engineering: el experimento bien planteado",
   "a": "Hipótesis medible: 'si cae Redis, el P99 solo sube a X y el error rate queda < Y'.\nExperimento: definir blast radius (solo staging, % pods), inyectar fallo (network delay, kill pod, llenar disco), observar métricas vs hipótesis, documentar y arreglar lo roto.\nHerramientas: Chaos Mesh/Litmus en k8s, Gremlin.\nNunca en producción sin kill switch y ventanas acordadas.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Health checks que no mienten",
   "a": "Liveness: solo 'el proceso responde' — NUNCA dependencias (BD caída ≠ reiniciar todos los pods: tormenta).\nReadiness: incluye dependencias críticas CON cache/timeout corto (BD lenta ≠ muerta).\nStartup: para apps que tardan (JVM + migraciones).\nCachear resultados de health (1-5s) para no convertir el health check en ataque.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Serve-stale: la caché como red de seguridad",
   "a": "Al fallar la BD/upstream, responder el valor cached aunque expirado (con header/etiqueta de staleness).\nImplementación: caché con soft-TTL (fresco) y hard-TTL (aceptable si el origen cae).\nEn Redis/locales: guardado con versión + timestamp; el cliente decide si tolera datos viejos.\nTransforma un outage en un degrade silencioso.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Thundering herd en reintentos: jitter y token bucket",
   "a": "Todos los clientes reintentan al mismo tiempo → sincronización que tumba al que se recupera.\nJitter: backoff = base * 2^n * random(0.5, 1.5) — desincroniza.\nToken bucket server-side: el servidor acepta N reintentos/min totales (retry budget), excedente falla inmediato.\nClient-side: circuit breaker evita reintentar contra servicio en OPEN.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Anatomía de una cascada de fallos (y dónde cortarla)",
   "a": "C lento → B acumula hilos esperando → B agota pool → B rechaza a A → A también se ahoga → cascada total.\nPuntos de corte: timeout en C (B no espera eterno), bulkhead en B (pool aislado), circuit breaker A→B (deja de insistir), load shedding en A (suelta tráfico), autoscaling como salida lenta.\nCada patrón corta UNA propagación — necesitas varios.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Resiliencia",
   "q": "Resilience4j en Spring: configuración YAML típica",
   "a": "resilience4j:\n  circuitbreaker.instances.pagos: slidingWindowSize: 20, failureRateThreshold: 50, waitDurationInOpenState: 30s, slowCallDurationThreshold: 2s, slowCallRateThreshold: 80\n  retry.instances.pagos: maxAttempts: 3, waitDuration: 200ms, enableExponentialBackoff: true\n  timelimiter.instances.pagos: timeoutDuration: 3s\nMétricas automáticas en /actuator/metrics (resilience4j.circuitbreaker.state).",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Instrumentación con OpenTelemetry: qué se auto-detecta",
   "a": "Agent/SDK auto-instrumenta: HTTP servers/clients, gRPC, JDBC (queries como spans), Kafka/PubSub, Redis, log correlation.\nManual: spans de lógica de negocio (reservar stock), atributos de negocio (tenant, order_id) — respetando cardinales bajos.\nPropagación: context extractor/injector (W3C traceparent) automático en protocolos comunes; manual en colas custom.\nExporter: OTLP → collector → backend.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Tracing: sampling head vs tail y su costo",
   "a": "Head sampling: decide al INICIO (1% de traces) — barato, pero pierdes los errores raros.\nTail sampling: decides al FINAL con criterios (guardar 100% de errores y lentos, 1% del resto) — necesita collector con buffer.\nRecomendación prod: head bajo + tail policy (errors, latencia p99, endpoints críticos).\nBaggage: datos de negocio viajando con el trace (tenant_id) con cuidado en cardinalidad.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Métricas con cardinalidad: el error que cuesta dinero",
   "a": "Cardinalidad = combinaciones de labels: path=/users/{id} (no el id real!), status, método — miles de series ok.\nFatal: labels con user_id, order_id, session → millones de series → Prometheus/Cloud Monitoring se ahoga y la factura explota.\nRegla: cada label debe tener decenas-centenas de valores máximos.\nDatos de alta cardinalidad → logs o traces, no métricas.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "SLOs por microservicio: quién define qué y cómo se negocia",
   "a": "El equipo dueño define SLOs por servicio basados en EXPECTATIVA DEL USUARIO, no en el valor default 99.9.\nDependencia en cadena: tu SLO requiere que el upstream cumpla (documento el requisito: 'necesito pagos con 99.95 y p99 300ms').\nError budget como contrato de riesgo: si lo agotas, se prioriza confiabilidad sobre features.\nRevisar trimestralmente con datos, no con intuición.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Logging en microservicios: estructura y muestreo",
   "a": "Estructurado JSON: timestamp, level, service, trace_id, span_id, tenant, msg, y contexto como campos (no string concatenado).\nMuestreo de logs exitosos (1 de 10) si el volumen mata el presupuesto; SIEMPRE 100% de errores y warnings.\nPII: mask en el appender (regex o librería) — compliance no es opcional.\nCorrelación: mismo trace_id en logs de todos los servicios = grep end-to-end.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Alertas multi-ventana multi-burn-rate (el estándar SRE)",
   "a": "Rápido: burn 14.4x en 1h (página — 'esto se cae ya').\nLento: burn 6x en 6h (página/aviso — 'consumirás el budget del mes').\nWindows combinadas (1h + 5m) para confirmar y evitar flapping.\nTodo sobre el error budget del SLO, no sobre CPU.\nResultado: páginas POCA pero RELEVANTES.",
   "nivel": "avanzado",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Dependencias externas: cómo observar lo que no controlas",
   "a": "Métricas por dependencia: latencia p95, tasa de error, rate — separadas (tag provider).\nTimeouts + breakers por dependencia; dashboard con estado de cada una.\nStatus pages de terceros enlazadas; SLA documentado.\nContratos: si el tercero no da SLO, asume el peor caso y diseña fallback — el riesgo es tuyo.",
   "nivel": "intermedio",
   "clave": false
  },
  {
   "sub": "Observabilidad",
   "q": "Postmortem blameless: estructura que funciona",
   "a": "1) Resumen ejecutivo (impacto: usuarios/dinero/duración).\n2) Timeline con datos de métricas.\n3) Causa raíz (contributing factors, no culpables).\n4) Qué funcionó, qué falló (detección, mitigación, comunicación).\n5) Action items con OWNER y FECHA (fixes, alertas faltantes, runbook).\nBlameless: el sistema falló, las personas operaron el sistema que existía.",
   "nivel": "intermedio",
   "clave": false
  }
 ]
}