Parcial de práctica — Ingeniería de Software

Temas: partes 1 y 2 del curso (semanas 1 a 7) · Duración: 2 horas

Este es un examen de práctica con el formato del parcial. Sirve para medir cuánto tiempo les toma cada tipo de pregunta: resuélvanlo sin herramientas de IA, sin mirar los apuntes y con el reloj corriendo. El formato general está en exams/README.md.

Indicaciones

  • El examen da un caso que no han visto. Usen sus datos: una respuesta que serviría para cualquier sistema no responde la pregunta.
  • Los errores menores de sintaxis de TypeScript no importan si la idea es correcta.
  • Cuando se pide justificar, la justificación es parte de la respuesta: un resultado correcto sin ella está incompleto.
  • Todos los montos van en céntimos, como enteros (S/ 6.00 es 600).
Parte Preguntas Tiempo sugerido
Leer el caso 5 min
A. Ingeniería de software y procesos 1–5 15 min
B. Requisitos 6–8 25 min
C. Especificaciones 9–10 20 min
D. Diseño 11 20 min
E. APIs y patrones 12–15 15 min
F. Arquitectura 16–18 20 min
Total 120 min

El caso: el comedor Wiñay

Wiñay quiere decir crecer en quechua. Es un comedor popular de Villa El Salvador, organizado por las vecinas. Las partes B a F son sobre este caso. Nélida, su presidenta, le contó esto a un equipo de estudiantes:

“Cocinamos de lunes a sábado, unas 120 raciones. Hoy los vecinos me separan su ración por WhatsApp y yo anoto en un cuaderno. A veces anoto más de lo que cocinamos, a las 12 ya no alcanza y la gente reclama. Quiero que separen desde el celular hasta las 11 de la mañana, y que la app sea rápida, porque muchas señoras tienen celulares antiguos. Cada familia separa las raciones que necesite, máximo 4. La ración cuesta S/ 6, S/ 4 para los socios, y los del padrón de apoyo social no pagan. Una separación se puede anular hasta las 11. Eso sí, a las 9 ya compramos en el mercado, así que después de las 9 nadie debería anular. El que no recoge igual paga. A las 11:15 la cocina tiene que saber cuántas raciones salen. Y quisiera que paguen con Yape.”

Parte A — Ingeniería de software y procesos

Respondan cada pregunta en pocas líneas.

Pregunta 1

Otro equipo del distrito construyó un panel que llama a la API del comedor. La respuesta trae dishes, una lista de platos, y siempre sale primero la sopa, aunque la documentación no promete ningún orden. El panel toma dishes[0] como la sopa. El equipo del comedor quiere ordenar los platos alfabéticamente. ¿Qué ley describe esta situación? ¿Basta con responder “nunca lo prometimos”? ¿Qué harían antes de hacer el cambio?

Pregunta 2

Cada afirmación es falsa según la Guía de Scrum de 2020. Corrijan cada una.

a) “Una historia con el código listo, pero sin la revisión que exige la Definition of Done, se presenta en la sprint review como casi terminada.”

b) “La daily sirve para que cada developer le informe su avance al Scrum master.”

c) “El compromiso del product backlog es la Definition of Done.”

Pregunta 3

El equipo que mantiene la aplicación trabaja con Kanban. Tiene 15 ítems en curso y termina 3 por semana.

a) ¿Cuál es su cycle time promedio? ¿Y si limitan el WIP a 6? Digan qué ley usan y bajo qué condiciones vale.

b) Respetan el límite de WIP, pero un ítem lleva cinco semanas en En revisión. ¿Qué métrica de flujo lo detecta? ¿Qué harían?

Pregunta 4

La municipalidad tiene dos equipos: A, con una velocity de 40 puntos, y B, con 25. Decide premiar a A y exigirle a B llegar a 40 el próximo sprint.

a) Expliquen por qué la comparación no tiene sentido y qué va a pasar con los puntos. ¿Qué ley lo describe?

b) ¿Qué diferencia hay entre una estimación y un compromiso?

Pregunta 5

Este estudio es inventado para el examen. Una consultora encuesta a 300 desarrolladores de 20 empresas peruanas. El 82 % responde que con herramientas de IA “termina más rápido”, y las empresas donde más se usan reportan menos errores en producción. El informe concluye: “la IA acelera a los equipos y reduce los errores; toda empresa debería adoptarla”.

a) ¿Qué tipo de estudio es? Den dos cosas que el informe concluye y que sus datos no permiten concluir, y digan por qué.

b) ¿Qué lección del estudio de METR de 2025 se aplica aquí?

c) Su equipo quiere decidir si usar un agente en su proyecto. ¿Qué medirían, además de preguntarle al equipo cómo se siente?

Parte B — Requisitos

Pregunta 6

Escriban dos historias de usuario para el comedor, con dos criterios de aceptación cada una en la forma dado, cuando, entonces. Los criterios tienen que usar datos concretos y comprobarse con un sí o un no. Pueden suponer que hoy es lunes 16 de marzo de 2026; si necesitan decidir algo que Nélida no dijo, escriban el supuesto.

Pregunta 7

a) Encuentren en lo que dijo Nélida una contradicción y tres cosas ambiguas. Para cada una, citen sus palabras, digan qué tiene de malo y escriban la pregunta que le harían.

b) Un compañero propone preguntarle: “¿no sería mejor que todos paguen con Yape?”. ¿Qué tiene de malo? Reescríbanla.

c) “Quisiera que paguen con Yape” es una solución. ¿Qué problema podría haber detrás? ¿Cómo lo averiguarían?

Pregunta 8

a) Reescriban “que la app sea rápida, porque muchas señoras tienen celulares antiguos” como un requisito no funcional que se pueda verificar.

b) Digan qué letra de INVEST cumple peor cada historia, y por qué. Reescriban una.

  1. “Como desarrollador, quiero crear la tabla orders con el campo family_id.”
  2. “Como presidenta, quiero administrar todo el comedor desde la aplicación.”
  3. “Como vecina, quiero que la aplicación se vea bonita.”

Parte C — Especificaciones

Nélida ya resolvió las dudas. Las reglas que valen de aquí en adelante son estas:

  • Solo se separa para el menú de hoy, y antes de las 11:00: a las 11:00 en punto ya no se puede. Para el menú de otro día no se puede separar a ninguna hora.
  • Una familia no puede tener más de 4 raciones activas en un día, sumando todas sus separaciones. Una separación está activa si no está anulada.
  • Las raciones activas de todas las familias no pueden pasar de las cocinadas.
  • La ración cuesta 600 céntimos, 400 para los socios (member) y 0 para el padrón de apoyo social (support).

Pregunta 9

type Plan = 'regular' | 'member' | 'support';
type LimaTime = { date: string; hour: number };
type DayMenu = { date: string; cookedPortions: number };
type ReserveRequest = { id: number; family: string; plan: Plan; portions: number };

function reservePortions(menu: DayMenu, dayOrders: readonly Order[], request: ReserveRequest, now: LimaTime): ReserveResult

a) Escriban la especificación de reservePortions: precondiciones, postcondiciones y los errores con un código para cada uno. Decidan si la función es parcial o total, y justifiquen. La postcondición tiene que ser completa.

b) Escriban dos invariantes del sistema. ¿Se pueden comprobar mirando solo el resultado de una llamada?

c) Un agente implementa la función a partir de su especificación y genera pruebas, y todas pasan. ¿Qué tendría que ser cierto para que confíen en ese código?

Pregunta 10

Un compañero escribió este tipo:

type Order = {
  id: number;
  family: string;
  portions: number;
  status: string;
  collectedAt?: string;
  cancelledAt?: string;
};

a) Den dos valores que compilan con este tipo y que son estados inválidos.

b) Escriban los tipos para los estados separado, recogido y anulado, de forma que esos valores ya no compilen.

c) Escriban label(order), que devuelve un texto para cada estado, con un switch exhaustivo. ¿Qué pasa con esa función si mañana se agrega un cuarto estado?

d) Una parte del código hace JSON.parse(body) as Order. ¿Qué garantiza eso? ¿Qué harían en su lugar, y dónde?

Parte D — Diseño

Pregunta 11

Este código del comedor funciona y pasa sus pruebas:

// st: 1 separado, 2 anulado, 3 recogido.
export type Row = { id: number; fam: string; date: string; qty: number; st: number; amount: number };

export class PortionTable {
  rows: Row[] = [];

  insert(row: Row): void {
    this.rows.push(row);
  }

  setSt(id: number, st: number): void {
    const row = this.rows.find((r) => r.id === id);
    if (row) row.st = st;
  }
}

export class PortionManager {
  table = new PortionTable();

  insert(row: Row): void {
    this.table.insert(row);
  }

  setSt(id: number, st: number): void {
    this.table.setSt(id, st);
  }

  rows(): Row[] {
    return this.table.rows;
  }

  // mode: 'new' separa, 'cancel' anula, 'collect' entrega.
  process(mode: string, id: number, fam: string, date: string, qty: number,
          isMember: boolean, isSupport: boolean, hour: number): boolean {
    if (mode === 'new') {
      if (hour >= 11) return false;
      const amount = isSupport ? 0 : qty * (isMember ? 400 : 600);
      this.insert({ id, fam, date, qty, st: 1, amount });
      return true;
    }
    if (mode === 'cancel') {
      if (hour >= 11) return false;
      this.setSt(id, 2);
      return true;
    }
    if (mode === 'collect') {
      this.setSt(id, 3);
      return true;
    }
    return false;
  }
}

// kitchen.ts: cuántas raciones salen hoy.
export function kitchenCount(manager: PortionManager, date: string): number {
  return manager.rows()
    .filter((r) => r.date === date && r.st !== 2)
    .reduce((sum, r) => sum + r.qty, 0);
}

// cash.ts: la caja del día.
export function dayCash(manager: PortionManager, date: string): number {
  return manager.rows()
    .filter((r) => r.date === date && r.st === 3)
    .reduce((sum, r) => sum + r.amount, 0);
}

a) Señalen tres problemas de diseño distintos. Para cada uno: nómbrenlo con el vocabulario del curso, señalen dónde está y den un cambio o un caso concreto en que duele.

b) Propongan una interfaz mejor: las firmas de sus operaciones, sin la implementación. Digan qué decisiones esconde y cómo se enteran quienes llaman de que algo no se pudo hacer.

c) Nélida pide un estado nuevo: no recogió, que ya se cocinó y que igual se cobra. Un compañero agrega st: 4 y llama a setSt. Sin cambiar nada más, ¿qué responden kitchenCount y dayCash para esa separación? ¿Son correctos? ¿Qué síntoma de complejidad es este? ¿Qué cambia en su diseño de (b)?

Parte E — APIs y patrones

Pregunta 12

Diseñen la API para estas operaciones: ver el menú de un día con las raciones que quedan, separar y anular una separación. Para cada una, escriban el método, la ruta, la respuesta de éxito y los errores con su código de estado y un código estable. Escriban la regla que usan para separar 400, 409 y 422.

Pregunta 13

a) Una vecina toca “Separar”, la señal se corta y el celular no recibe respuesta. ¿Qué pasa si la aplicación reintenta el POST? ¿Cómo lo resuelven? Digan qué manda quien llama, qué guarda el servidor y qué responde este si la misma clave llega con otro cuerpo. ¿Por qué no basta con “revisar si la familia ya tiene una separación”?

b) Según la definición de RFC 9110, ¿son idempotentes los métodos POST, PUT y DELETE? Si un segundo POST /api/orders/12/cancel responde 409 y el pedido queda igual, ¿qué se puede decir de esa operación?

Pregunta 14

La API ya tiene clientes HTTP. Clasifiquen cada cambio como compatible o incompatible, y justifiquen en una línea.

a) Agregar remainingPortions a la respuesta del menú.

b) Cambiar portions por quantity en el cuerpo de la separación.

c) Pasar SOLD_OUT de 409 a 422.

d) Agregar un parámetro opcional ?district= a la lista de menús.

Pregunta 15

Un compañero propone, para el precio de una ración, una interfaz PriceStrategy, tres clases (RegularPrice, MemberPrice, SupportPrice) y una PriceStrategyFactory. ¿Qué le responden en la revisión de código? ¿Con qué lo reemplazarían? ¿Qué pedido futuro sí justificaría una strategy?

Parte F — Arquitectura

La municipalidad quiere llevar el sistema a seis comedores del distrito. Son unas 200 separaciones al día en total, casi todas entre las 10:30 y las 11:00. Después del curso, lo van a mantener dos técnicos de la municipalidad, que hoy manejan un solo servidor virtual de S/ 60 al mes. Cada comedor tiene sus propios menús y precios. Un consultor recomienda cuatro microservicios (menús, separaciones, pagos y avisos) “para que escale”.

Pregunta 16

Escriban el ADR de la decisión de arquitectura, con las secciones Estado, Contexto, Decisión, Alternativas consideradas (por lo menos dos, con lo bueno y lo malo de cada una) y Consecuencias (qué se gana, qué se pierde y qué hay que hacer). Usen los datos del caso.

Pregunta 17

Escriban el atributo de calidad más importante de este caso como un escenario medible, con sus cuatro partes. ¿Con qué otro atributo compite?

Pregunta 18

a) El comedor va a avisar por WhatsApp cuando se confirma una separación, y el proveedor puede cambiar. Con arquitectura hexagonal, ¿qué es el puerto, qué es el adaptador y hacia dónde apunta la dependencia? ¿Qué código no cambia al cambiar de proveedor?

b) ¿Qué dice la ley de Conway, y qué sugiere sobre la propuesta de cuatro microservicios en este caso?