Capítulo 8 de 10 · 100 proyectos para hacer con tu coding agent

Sistemas y bajo nivel (71-80)

Intérpretes, bases de datos, control de versiones y protocolos de red. Los proyectos que cambian cómo entiendes el software que usas cada día.

6 min de lecturaActualizado el 8 de septiembre de 2026

Este es el capítulo que más te va a enseñar y también el que más veces vas a querer dejar a medias. Son proyectos en los que el agente ayuda muchísimo con el andamiaje, pero en los que el valor está en que tú entiendas cada decisión. Si dejas que lo haga todo solo, habrás perdido el tiempo.

71. Intérprete de un lenguaje propio

Léxico, sintaxis, evaluación. Al terminar tienes un lenguaje con funciones, cierres y recursión que has escrito tú, y una idea mucho más clara de qué hace tu lenguaje favorito por dentro.

Implementa un intérprete para un lenguaje de juguete tipo Lox o Monkey.

Por fases, con tests en cada una:
1. Lexer.
2. Parser de descenso recursivo a AST, con precedencia correcta de operadores.
3. Evaluador con entornos, variables, condicionales y bucles.
4. Funciones de primera clase y cierres.
5. Estructuras: listas y diccionarios, con sus operaciones básicas.
6. REPL con mensajes de error que incluyan línea y columna.

Explícame la diferencia entre ámbito léxico y dinámico cuando llegues a los cierres.

72. Máquina virtual de pila con compilador

El siguiente paso natural. En vez de recorrer el árbol, compilas a bytecode y lo ejecutas en una máquina virtual. Diez veces más rápido y bastante más instructivo.

Añade a tu intérprete un compilador a bytecode y una VM de pila.

- Conjunto de instrucciones documentado (OP_CONST, OP_ADD, OP_JUMP...).
- Compilador de una pasada del AST a bytecode.
- VM con pila de operandos, marcos de llamada y variables locales por índice.
- Desensamblador para inspeccionar el código generado.
- Recolector de basura por marcado y barrido, con umbral configurable.

Compara el rendimiento con el intérprete de árbol en un fib(30) y explica
de dónde viene la diferencia.

73. Base de datos clave-valor con WAL

Durabilidad de verdad. Escribe primero en el log, luego en el índice, y que sobreviva a un kill -9 en mitad de una escritura. Ese test es el que da miedo y el que enseña.

Construye un almacén clave-valor persistente.

- Log de escritura anticipada (WAL) con checksum por registro.
- Índice en memoria (hash o árbol) reconstruible desde el WAL al arrancar.
- Compactación del log en segundo plano sin bloquear escrituras.
- Transacciones simples: begin/commit/rollback sobre varias claves.
- API por red con un protocolo binario propio.

Test decisivo: matar el proceso con kill -9 durante escrituras continuas.
Al reiniciar, todo lo confirmado debe estar y nada a medias.

74. Control de versiones al estilo git

Blobs, árboles, commits y un índice. Cuando lo escribes, git deja de dar miedo para siempre, porque descubres que por debajo es mucho más simple de lo que aparenta.

Implementa un control de versiones con el modelo de objetos de git.

- Objetos blob, tree y commit direccionados por hash, comprimidos con zlib.
- Comandos: init, add (con índice), commit, log, status, diff, checkout.
- Ramas como referencias a commits y un HEAD que puede estar separado.
- Fusión de tres vías con detección de conflictos y marcadores en el fichero.

Al terminar, escribe un README explicando por qué git es un sistema de
contenido direccionable y qué implica eso para el rendimiento.

75. Servidor DNS con caché

Parsear el formato binario de DNS es un ejercicio precioso, con su compresión de nombres por punteros y todo. De paso entiendes por qué un cambio a veces tarda en propagarse.

Escribe un servidor DNS recursivo con caché.

- Parseo y serialización del formato binario (cabecera, cuestiones, respuestas,
  incluida la compresión de nombres por punteros).
- Resolución recursiva desde los servidores raíz.
- Caché que respete el TTL de cada registro.
- Registros A, AAAA, CNAME, MX, TXT y NS.
- Modo bloqueo: devuelve NXDOMAIN para dominios de una lista.

Compruébalo con dig apuntando a tu servidor y enséñame la salida.

76. Implementación de Raft

El algoritmo de consenso, entendido a base de implementarlo: elecciones, replicación del log y tolerancia a fallos. El paper se lee mucho mejor después.

Implementa el algoritmo de consenso Raft.

- Elección de líder con temporizadores aleatorios y términos.
- Replicación del log con AppendEntries y comprobación de consistencia.
- Confirmación por mayoría y aplicación a una máquina de estados
  (un simple clave-valor).
- Simulador de red con particiones, retardos y pérdida de mensajes.

Escenarios que deben pasar: partición del líder, reincorporación de un nodo
retrasado, y tres nodos de cinco caídos (el clúster debe quedarse sin progresar
pero sin corromperse).

77. Compresor de ficheros

Huffman primero, luego LZ77, y al final comparas con gzip. Vas a perder, pero descubrirás que la compresión no es magia, es estadística.

Escribe un compresor y descompresor de ficheros desde cero.

1. Codificación Huffman con árbol serializado en la cabecera.
2. LZ77 con ventana deslizante.
3. Combinación de ambos (deflate simplificado).

Formato propio con cabecera versionada y checksum del contenido.
Tabla comparativa contra gzip y zstd: ratio y tiempo sobre texto,
JSON y un binario. Sin excusas si pierdes: explica por qué.

78. Depurador con ptrace

Puntos de ruptura, ejecución paso a paso e inspección de memoria. Lo que hace GDB, en pequeño y entendiendo cada llamada a ptrace.

Construye un depurador para Linux usando ptrace.

- Lanzar un proceso o adjuntarse a uno existente.
- Puntos de ruptura por software (int3) con restauración del byte original.
- Continuar, paso de instrucción, y lectura y escritura de registros y memoria.
- Resolución de símbolos y líneas desde la información DWARF (aunque sea básica).
- Traza de la pila de llamadas.

Explícame qué ocurre exactamente en el kernel cuando el proceso hijo
se detiene en un breakpoint.

79. Pila TCP en espacio de usuario

Sobre un dispositivo TUN, implementas el handshake, las ventanas y las retransmisiones. Es duro, y es de las cosas más brillantes que puedes hacer con un ordenador.

Implementa una pila TCP/IP mínima en espacio de usuario sobre un dispositivo TUN.

- Parseo de IPv4 y TCP, checksums correctos.
- Máquina de estados TCP completa: three-way handshake, transferencia y cierre
  ordenado (incluido TIME_WAIT).
- Ventana deslizante, ACKs acumulativos y retransmisión por timeout.
- Un servidor de eco que funcione con nc y curl desde otra terminal.

Ve enseñándome capturas de tcpdump que demuestren cada fase.

80. Sistema de ficheros en FUSE

Montas un directorio que en realidad es otra cosa: un fichero cifrado, una base de datos, una API remota. Y luego usas cp y grep encima como si nada.

Escribe un sistema de ficheros con FUSE.

Elige uno de estos y móntalo:
- Un sistema de ficheros cifrado sobre un directorio real.
- Un sistema de ficheros que exponga una base de datos SQLite como directorios.
- Un sistema de ficheros con versiones: cada escritura guarda una revisión.

Requisitos: operaciones básicas (getattr, readdir, open, read, write, unlink,
rename), permisos correctos y comportamiento razonable con ficheros grandes.
Prueba con cp, mv, grep y un editor de texto real.