🧪 Problem-Driven Systems Lab

đŸŒ± GuĂ­a para principiantes#

Para quien estĂĄ empezando a programar y quiere recorrer este laboratorio sin perderse.

🧭 ÂżNo sos del mundo del desarrollo? EmpezĂĄ por ÂżQuĂ© es esto? — explicaciĂłn en lenguaje simple. EstĂĄ escrito sin jerga y no supone ningĂșn conocimiento previo.


1ïžâƒŁ La ruta en 6 pasos#

#PasoDocumento
1Entender la idea general del laboratorioREADME.md
2Ver qué problema profesional resuelvepositioning-and-objective.md
3Identificar los casos y su estado realcase-catalog.md
4Levantar un caso con DockerINSTALL.md
5Destrabar lo que no arranqueRUNBOOK.md
6Comparar el mismo caso en otro lenguajecases/NN-*/comparison.md

💡 Los 20 casos estĂĄn operativos en los 7 stacks: PHP, Python, Node.js, Java, .NET, Go y Rust. PodĂ©s recorrer cualquier caso en cualquiera de ellos.


🧠 TĂ©rminos clave de este repositorio#

TérminoSignificado acå
Problem-drivenEl problema manda; el stack se elige para resolverlo, no al revés
OperativoCaso implementado con evidencia real y Docker funcional
Legacy vs optimizedLas dos variantes de cada caso: la que tiene el problema y la que lo resuelve. EstĂĄn vivas al mismo tiempo para poder compararlas
HubUn contenedor que sirve los 20 casos de un lenguaje detrás de un puerto (:8100 PHP, :8300 Node, 
)
Modo aisladoLevantar un solo caso en su propio contenedor, Ăștil cuando la mediciĂłn necesita el runtime sin ruido
PrimitivaLa herramienta que el lenguaje trae de fĂĄbrica para resolver algo (un canal en Go, un Semaphore en Java)
ComparativaEl comparison.md de cada caso: los 7 stacks lado a lado y un veredicto razonado

đŸšȘ Por dĂłnde empezar#

Los 20 problemas agrupados por naturaleza

CasoPor qué empezar ahí
02 · N+1 en base de datosEl mås fåcil de entender. El problema se ve contando consultas: 101 en vez de 2
01 · API lenta bajo cargaEl mås completo: base de datos, worker, métricas y dashboards en Grafana
03 · Observabilidad deficienteMuestra råpido por qué unos logs sin contexto no sirven para nada
04 · Timeouts y reintentosPara entender circuit breaker y degradación controlada
06 · Pipeline frågilHace visible por qué preflight y rollback importan

🔍 Cómo leer un caso#

Cada caso tiene siempre la misma estructura. Leerlos en este orden hace que el cĂłdigo se entienda solo:

text
cases/NN-nombre-del-caso/
├── README.md          ← empezá acá: el problema en contexto
├── comparison.md      ← los 7 stacks lado a lado + veredicto
├── docs/
│   ├── context.md          ← la situación
│   ├── symptoms.md         ← quĂ© se ve desde afuera
│   ├── diagnosis.md        ← cómo se buscó la causa
│   ├── root-causes.md      ← quĂ© lo provoca de verdad
│   ├── solution-options.md ← los caminos posibles
│   ├── trade-offs.md       ← quĂ© se gana y quĂ© se pierde
│   ├── business-value.md   ← por quĂ© le importa a la empresa
│   └── postmortem.md       ← quĂ© se aprendiĂł
├── php/  python/  node/  java/  dotnet/  go/  rust/
└── shared/

📌 La regla de oro: leĂ© README.md y docs/ antes de abrir el cĂłdigo. El repositorio estĂĄ construido para que el cĂłdigo sea la conclusiĂłn de un razonamiento, no el punto de partida.


đŸ§Ș Tu primer experimento#

LevantĂĄ el caso 02 en Go y mirĂĄ el problema con tus propios ojos:

bash
docker compose -f compose.go.yml up -d --build
bash
curl -s "localhost:8600/02/report-legacy?limit=20"

Fijate en el campo db_hits: va a ser 1 + N. Una consulta para traer la lista, y una mĂĄs por cada fila.

bash
curl -s "localhost:8600/02/report-optimized?limit=20"

Ahora db_hits es un nĂșmero chico y constante, sin importar cuĂĄntas filas pidas. Ese salto —de crecer con los datos a no crecer— es el caso 02 entero.

Cuando termines:

bash
docker compose -f compose.go.yml down

🌍 Y despuĂ©s, el mismo caso en otro lenguaje#

Es la parte mĂĄs formativa del laboratorio. El mismo experimento en Rust:

bash
docker compose -f compose.rust.yml up -d --build

Mismo problema, mismo arreglo, primitiva distinta. La comparativa cases/02-*/comparison.md explica por qué Rust queda primero en ese caso concreto: collect::<Result<Vec<_>>>() hace imposible ignorar un fallo a mitad del recorrido, algo que en los otros seis stacks depende de que el programador se acuerde.

Para entender qué es cada lenguaje y en qué es bueno, estån los perfiles de lenguaje.


💡 Cuatro consejos que ahorran tiempo#

  1. Un caso por vez. No levantes los siete stacks juntos "para ver si funciona". El ruido tapa lo que querés observar.
  2. Comparar siempre legacy contra optimized. Un nĂșmero solo no dice nada; la diferencia entre los dos, sĂ­.
  3. Descartar el arranque. En Java y .NET las primeras peticiones son mĂĄs lentas porque el runtime todavĂ­a se estĂĄ calentando. TirĂĄ trĂĄfico un rato antes de medir.
  4. Leer el veredicto de la comparativa al final, no al principio. Si lo leés primero, ya no vas a sacar tus propias conclusiones.

📚 AdĂłnde ir despuĂ©s#

DocumentoPara qué
QUE-ES-ESTO.mdLa versión sin jerga, para compartir con alguien no técnico
languages/Qué es cada lenguaje, sus primitivas y sus límites
case-methodology.mdCĂłmo se construye un caso antes de escribir cĂłdigo
docker-strategy.mdPor qué Docker es el modelo operativo del laboratorio
executive-summary.mdLos 20 casos en una pĂĄgina

Ver esta carpeta en GitHub ↗