Roadmap de Fundamentos de Sistemas Backend y Sistemas Distribuidos

Roadmap Desarrollo Backend

Motivación

Durante mi jornada de estudio en desarrollo Backend, me he visto atorado múltiples ocasiones por no saber por dónde empezar, con qué continuar, o hacia qué enfocarme, resultando en un tipo de procrastinación a la que muchos nos enfrentamos. Por ello, decidí extraer de diversos recursos en línea los temas esenciales y ricos en teoría y práctica, para una ruta de aprendizaje sólida y de alto rendimiento en desarrollo Backend, consolidándolos en el roadmap que presento a continuación.

Este roadmap es producto de un par de meses de recopilación, desde múltiples recursos en línea (libros, videos, temarios), hasta foros y el mismo plan de estudio de mi licenciatura.


Stack

Este roadmap contiene fundamentos genéricos e independientes del lenguaje de programación y herramientas, pero particularicé un stack que permita aterrizar satisfactoriamente estos fundamentos, con tal vez un poco de sesgo consecuencia de mis intereses:

  • Java (lenguaje principal)
  • Scala (lenguaje secundario)
  • Spring Boot
  • PostgreSQL
  • Redis
  • Kafka
  • Docker
  • Kubernetes
  • Gradle
  • Prometheus + Grafana
  • ELK / Loki
  • REST + gRPC
  • Linux

Etapa 0: Fundamentos de Programación e Introducción al desarrollo de Software

Fundamentos generales de programación

  • Paradigmas de programación (imperativo, declarativo)
  • Sintaxis y estructuras básicas
  • Tipos de datos
  • Variables y alcance
  • Estructuras de control y condicionales
  • Funciones y modularidad
  • Manejo básico de errores
  • Manejo de archivos I/O
  • Recursión

Programación Orientada a Objetos

  • Clases y objetos
  • Encapsulamiento
  • Herencia
  • Polimorfismo
  • Abstracción
  • Interfaces y clases abstractas
  • Principios SOLID
  • Composición
  • Patrones de diseño (Singleton, Factory, Observer, Strategy)

Estructuras de Datos y Algoritmos

  • ¿Que es un algoritmo?
  • Notación Big O
  • Genéricos
  • Estructuras lineales: arreglos, listas, pilas, colas
  • Estructuras no lineales: hashing, tablas hash, mapas hash, árboles, grafos
  • Búsqueda binaria
  • Algoritmos de ordenamiento
  • Algoritmos de balanceo en árboles
  • Algoritmos de búsqueda (BFS y DFS)
  • Recursión aplicada
  • Programación dinámica básica (memoización, tabulación)

Software

  • Git y control de versiones
  • Línea de comandos/terminal
  • Depuración
  • Testing básico

Etapa 1: Fundamentos de Bases de Datos

Conceptos Fundamentales

  • ¿Qué es una base de datos y para qué sirve?
  • ¿Qué es un DBMS y cuál es su rol?
  • Modelos de datos: relacional, documental, clave-valor, columnar, grafo
  • Diferencias entre bases de datos SQL y NoSQL
  • Persistencia vs. almacenamiento en memoria
  • ACID: Atomicidad, Consistencia, Aislamiento, Durabilidad
  • BASE: Basically Available, Soft state, Eventual consistency
  • Teorema CAP

Diseño Conceptual: Modelo Entidad-Relación

  • ¿Qué es el modelado conceptual y por qué es el primer paso?
  • Entidades y atributos
  • Relaciones y cardinalidad: uno a uno, uno a muchos, muchos a muchos
  • Entidades débiles y dependientes
  • Diagrama ER y notación crow’s foot
  • Diferencia entre modelo conceptual, lógico y físico

Modelo Relacional (Modelo Lógico)

  • Traducción del modelo ER al modelo relacional
  • Tablas, filas y columnas
  • Claves primarias y claves foráneas
  • Restricciones: NOT NULL, UNIQUE, CHECK, DEFAULT
  • Tablas de unión (junction tables)
  • Vistas (views)
  • Formas normales: 1FN, 2FN, 3FN y BCNF
  • Desnormalización y cuándo aplicarla
  • Diseño orientado a consultas vs. diseño orientado a escritura

Modelo Físico e Implementación con SQL

  • Tipos de datos primitivos (enteros, flotantes, cadenas, booleanos, fechas)
  • DDL: CREATE, ALTER, DROP, TRUNCATE
  • DML: SELECT, INSERT, UPDATE, DELETE
  • Filtros y condiciones: WHERE, BETWEEN, IN, LIKE, IS NULL
  • Ordenamiento y paginación: ORDER BY, LIMIT, OFFSET
  • Agregaciones: COUNT, SUM, AVG, MIN, MAX
  • Agrupamiento: GROUP BY, HAVING
  • Joins: INNER, LEFT, RIGHT, FULL OUTER, CROSS, SELF JOIN
  • Subconsultas y consultas correlacionadas
  • CTEs (Common Table Expressions) con WITH
  • Funciones de ventana: OVER, PARTITION BY, ROW_NUMBER, RANK, LAG, LEAD

Índices

  • ¿Qué es un índice y cómo mejora las consultas?
  • Índices B-Tree, Hash, GIN, GiST (conceptual)
  • Índices simples, compuestos y parciales
  • Cuándo indexar y cuándo no
  • Impacto de los índices en escrituras y almacenamiento
  • EXPLAIN / EXPLAIN ANALYZE para analizar planes de ejecución

Transacciones y Control de Concurrencia

  • ¿Qué es una transacción y por qué existe?
  • BEGIN, COMMIT, ROLLBACK
  • Niveles de aislamiento: Read Uncommitted, Read Committed, Repeatable Read, Serializable
  • Anomalías de concurrencia: dirty reads, non-repeatable reads, phantom reads
  • Bloqueos (locks): compartidos, exclusivos, deadlocks
  • Optimistic vs. Pessimistic locking
  • MVCC (Multi-Version Concurrency Control): concepto general

Fundamentos de NoSQL

  • Motivaciones para NoSQL: escalabilidad horizontal, esquema flexible, alto throughput
  • Bases de datos de documentos: concepto (MongoDB como referencia)
  • Bases de datos clave-valor: concepto (Redis como referencia)
  • Bases de datos columnares: concepto (Cassandra como referencia)
  • Bases de datos de grafos: concepto (Neo4j como referencia)
  • Cuándo elegir SQL vs. NoSQL

Fundamentos de Almacenamiento y Rendimiento

  • Almacenamiento en disco vs. en memoria
  • Row-oriented vs. column-oriented storage
  • Write-ahead log (WAL): concepto y propósito
  • Buffer pool / page cache
  • Conceptos de particionamiento: horizontal (sharding) y vertical
  • Replicación: primary/replica, sincrónica vs. asincrónica
  • Connection pooling: qué es y por qué importa

Etapa 2: PostgreSQL y Persistencia

Introducción a PostgreSQL

  • ¿Por qué PostgreSQL? Historia y casos de uso
  • Instalación y configuración inicial
  • Herramientas: psql, pgAdmin, DBeaver
  • Estructura interna: databases, schémas, roles
  • Archivos de configuración: postgresql.conf, pg_hba.conf
  • Variables de entorno y conexión

Tipos de datos Avanzados

  • Tipos numéricos: smallint, integer, bigint, numeric, real, double precision
  • Tipos de texto: char, varchar, text
  • Tipos de fecha y hora: date, time, timestamp, timestamptz, interval
  • Tipo booleano
  • UUID: generación y uso como clave primaria
  • JSON y JSONB: diferencias y cuándo usar cada uno
  • Arrays en PostgreSQL
  • Tipos enumerados (ENUM)
  • Tipos de red: inet, cidr, macaddr

DDL Avanzado

  • Creación de esquemas y namespaces
  • Herencia de tablas (table inheritance)
  • Tablas temporales
  • Secuencias (SEQUENCE) y columnas SERIAL / GENERATED
  • Triggers: concepto, creación y casos de uso
  • Funciones almacenadas con PL/pgSQL: estructura básica
  • Reglas (RULES): concepto general
  • Extensiones: pg_crypto, uuid-ossp, postgis (referencia)

Consultas Avanzadas en PostgreSQL

  • Operadores específicos de PostgreSQL: ILIKE, SIMILAR TO, expresiones regulares
  • Operadores de JSON/JSONB: ->, ->>, #>, @>, ?
  • Consultas sobre arrays: ANY, ALL, array_agg, unnest
  • DISTINCT ON: filtrado avanzado por grupo
  • RETURNING en INSERT, UPDATE y DELETE
  • UPSERT con ON CONFLICT DO UPDATE / DO NOTHING
  • LATERAL joins: concepto y uso práctico
  • Full-text search: tsvector, tsquery, to_tsvector, to_tsquery, GIN index

Índices en PostgreSQL (Profundización)

  • Índices parciales con WHERE
  • Índices de expresión
  • Índices multicolumna: orden y selectividad
  • Índices GIN para arrays y JSONB
  • Índices GiST para rangos y geometría básica
  • BRIN: cuándo tiene sentido
  • Índices únicos y parcialmente únicos
  • Reconstrucción y mantenimiento: REINDEX, VACUUM, ANALYZE

Rendimiento y Optimización

  • Planes de ejecución: cómo leer EXPLAIN ANALYZE
  • Estadísticas del planificador: pg_statistic, pg_stats
  • Configuración del planificador: work_mem, effective_cache_size, random_page_cost
  • Problema N+1 en consultas: identificación y solución
  • Estrategias de paginación: OFFSET vs. keyset pagination
  • Vistas materializadas: creación y actualización
  • Particionamiento de tablas: por rango, lista y hash
  • pg_stat_statements: monitoreo de consultas lentas

Transacciones en PostgreSQL

  • Savepoints: SAVEPOINT, ROLLBACK TO SAVEPOINT
  • Advisory locks: pg_try_advisory_lock, pg_advisory_unlock
  • Deadlock detection en PostgreSQL
  • MVCC en práctica: visibilidad de filas y snapshots
  • Tablas sin logging: UNLOGGED TABLE (rendimiento vs. durabilidad)
  • VACUUM y autovacuum: por qué existen y cómo configurarlos

Migraciones y Gestión de Esquemas

  • ¿Qué es una migración de base de datos?
  • Migraciones incrementales y reversibles
  • Herramientas: Flyway y Liquibase (conceptos y comparación)
  • Estrategias para migraciones sin downtime: expand-contract pattern
  • Control de versiones de esquemas junto al código
  • Ambientes: desarrollo, staging, producción

Persistencia desde la Aplicación

  • Drivers de conexión: JDBC (Java), psycopg2 (Python), pg (Node.js)
  • Connection pooling desde la aplicación: HikariCP, PgBouncer
  • ORM vs. query builders vs. SQL plano: cuándo usar cada uno
  • Introducción a ORMs: Hibernate/JPA (Java), SQLAlchemy (Python), Prisma (Node.js)
  • Mapeo objeto-relacional: entidades, relaciones, lazy vs. eager loading
  • Problemas comunes con ORMs: N+1, over-fetching, under-fetching
  • Repositorios y patrones de acceso a datos: Repository Pattern, DAO

Etapa 3: Computación Concurrente y Fundamentos de la JVM

Fundamentos de Concurrencia

  • ¿Qué es la concurrencia y por qué importa?
  • Concurrencia vs paralelismo: diferencias conceptuales
  • Procesos vs hilos (threads): modelo del sistema operativo
  • Condiciones de carrera (race conditions)
  • Sección crítica y exclusión mutua
  • Deadlocks, livelocks y starvation
  • Modelo de memoria: visibilidad y reordenamiento de instrucciones

Hilos en Java

  • La clase Thread y la interfaz Runnable
  • Ciclo de vida de un hilo: NEW, RUNNABLE, BLOCKED, WAITING, TERMINATED
  • Creación y arranque de hilos
  • Métodos: start, join, sleep, interrupt, isInterrupted
  • Variables locales de hilo: ThreadLocal
  • Problemas comunes: shared mutable state, visibilidad

Sincronización en Java

  • La palabra clave synchronized: métodos y bloques sincronizados
  • Monitores y el modelo de lock intrínseco
  • volatile: visibilidad sin exclusión mutua
  • Clase Object: wait,notify, notifyAll
  • java.util.concurrent.locks: Lock, ReentrantLock, ReadWriteLock
  • Condiciones con Condition: await, signal, signalAll
  • Comparación: synchronized vs. ReentrantLock

Concurrencia de Alto Nivel en Java

  • Executor framework: Executor, ExecutorService, ScheduledExecutorService
  • Tipos de thread pools: fixed, cached, single, scheduled
  • Callable y Future: tareas con resultado
  • CompletableFuture: composición asíncrona
  • Operaciones de CompletableFuture: thenApply, thenCompose, thenCombine, exceptionally, allOf, anyOf
  • ForkJoinPool: concepto y uso para tareas divisibles

Colecciones Concurrentes

  • Problemas de usar colecciones estándar en contextos concurrentes
  • ConcurrentHashMap: segmentación y operaciones atómicas
  • CopyOnWriteArrayList: cuándo tiene sentido
  • BlockingQueue: ArrayBlockingQueue, LinkedBlockingQueue
  • Patrón productor-consumidor con BlockingQueue
  • Deque concurrente: ConcurrentLinkedDeque

Clases Atómicas y Variables Atómicas

  • Operaciones compare-and-swap (CAS)
  • AtomicInteger, AtomicLong, AtomicBoolean, AtomicReference
  • AtomicIntegerArray, AtomicLongArray
  • LongAdder y DoubleAdder: mejor rendimiento bajo alta contención
  • Cuándo preferir atómicas vs. locks

Fundamentos de la JVM

  • ¿Qué es la JVM y por qué existe?
  • El proceso de compilación: código fuente → bytecode → ejecución
  • JVM, JRE y JDK: diferencias y roles
  • Especificación vs. implementación: OpenJDK, GraalVM, Amazon Corretto
  • Estructura interna: ClassLoader, Heap, Stack, Method Area, PC Register
  • Bytecode: instrucciones básicas y herramienta javap

Gestión de Memoria en la JVM

  • Stack vs. Heap: qué vive en cada uno
  • Objetos y referencias: cómo se almacenan
  • Garbage Collection: concepto y motivación
  • Algoritmos de GC: Mark-and-Sweep, Copying, Mark-and-Compact
  • Generational GC: Young Generation (Eden, Survivor), Old Generation
  • GC collectors disponibles: Serial, Parallel, G1, ZGC, Shenandoah
  • Métricas de GC: throughput, latencia, pause time
  • OutOfMemoryError: causas comunes y diagnóstico básico

JIT y Optimizaciones de la JVM

  • Interpretación vs. compilación JIT
  • C1 y C2 compilers: tiered compilation
  • Inlining, escape analysis, scalar replacement
  • Warm-up de la JVM: por qué las primeras requests son más lentas
  • Herramientas de profiling: JVisualVM, Java Flight Recorder (JFR), async-profiler
  • Flame graphs: lectura básica

Herramientas y Ecosistema JVM

  • Build tools: Maven y Gradle (estructura, dependencias, ciclo de vida)
  • Gestión de dependencias: repositorios, versiones, conflictos
  • Logging en Java: SLF4J, Logback, Log4j2
  • Configuración de aplicaciones: properties, YAML, variables de entorno
  • Introducción a Spring Framework: IOC, DI, ApplicationContext
  • Spring Boot: autoconfiguración, starters, propiedades
  • Kotlin como alternativa a Java en la JVM: conceptos básicos

Etapa 4: Comunicación y Redes

Fundamentos de Redes

  • Modelo OSI y modelo TCP/IP: capas y responsabilidades
  • Direcciones IP: IPv4, IPv6, clases, CIDR, subnetting básico
  • Puertos y sockets: concepto y uso
  • DNS: resolución de nombres, registros A, CNAME, MX, TTL
  • NAT y proxies: cómo funcionan
  • Firewalls y grupos de seguridad: conceptos básicos

TCP y UDP

  • TCP: conexión orientada, confiabilidad, orden de entrega
  • Three-way handshake y four-way teardown
  • Control de flujo y congestión en TCP
  • UDP: datagrama, sin conexión, cuándo preferirlo
  • Diferencias de uso: streaming, videollamadas, juegos (UDP) vs. HTTP, bases de datos (TCP)
  • Timeouts y retransmisiones

HTTP

  • Historia: HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3
  • Estructura de una petición HTTP: método, URL, headers, body
  • Estructura de una respuesta HTTP: status code, headers, body
  • Métodos HTTP: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
  • Códigos de estado: 1xxx, 2xx, 3xx, 4xx, 5xx
  • Headers importantes: Content-Type, Authorization, Cache-Control, Accept, CORS
  • Cookies y sesiones: Set-Cookie, Cookie, SameSite, HttpOnly, Secure
  • HTTP/2: multiplexing, server push, header compression
  • HTTP/3 y QUIC: motivación y diferencias

HTTPS y Seguridad en la Capa de Transporte

  • TLS: propósito, handshake y versiones (1.2 vs. 1.3)
  • Certificados digitales: X.509, CA, cadena de confianza
  • Let’s Encrypt y certificados gratuitos
  • HSTS: forzar conexiones seguras
  • Pinning de certificados: concepto
  • Problemas comunes: certificados expirados, mixed content

APIs REST

  • ¿Qué es REST? Principios de Fielding
  • Recursos y URIs: diseño de endpoints
  • Operaciones CRUD mapeadas a HTTP
  • Representaciones: JSON, XML, selección de formato
  • Statelessness: por qué el servidor no guarda estado de cliente
  • HATEOAS: concepto (sin profundidad excesiva)
  • Versionado de APIs: URL path, query param, header
  • Paginación en APIs: page/size, cursor-based
  • Filtrado, ordenamiento y búsqueda en endpoints
  • Idempotencia: GET, PUT, DELETE vs. POST
  • Diseño de respuestas de error: estructura consistente
  • Documentación con OpenAPI / Swagger

gRPC y Protobuf

  • Limitaciones de REST/JSON que motivan gRPC
  • Protocol Buffers: definición de mensajes en .proto
  • Tipos de datos en Protobuf y serialización binaria
  • Servicios gRPC: unary, server streaming, client streaming, bidirectional
  • Generación de código desde .proto
  • Comparación gRPC vs. REST: cuándo elegir cada uno
  • gRPC-Web: uso desde navegadores
  • Interceptors en gRPC

WebSockets y Comunicación en Tiempo Real

  • Limitaciones de HTTP para tiempo real: polling, long polling
  • WebSocket: handshake, frames, full-duplex
  • Casos de uso: chat, notificaciones, dashboards en vivo
  • Bibliotecas: Socket.IO, Spring WebSocket (Java)
  • Server-Sent Events (SSE): alternativa unidireccional
  • Comparación: WebSocket vs. SSE vs. polling

Autenticación y Autorización en APIs

  • Autenticación vs. autorización: diferencia conceptual
  • API Keys: uso y limitaciones
  • Basic Auth: concepto y por qué no usar en producción
  • JWT (JSON Web Tokens): estructura, firma, verificación
  • Access token vs. refresh token: flujo de renovación
  • OAuth 2.0: roles, flujos (Authorization Code, Client Credentials)
  • OpenID Connect (OIDC): capa de identidad sobre OAuth 2.0
  • Almacenamiento seguro de tokens en cliente
  • Validación de tokens en el servidor

Proxies, Gateways y Balanceo de Carga

  • Forward proxy vs. reverse proxy
  • Load balancer: round-robin, least connections, IP hash
  • API Gateway: responsabilidades y diferencia con load balancer
  • Rate limiting: algoritmos token bucket y leaky bucket
  • Circuit breaker: concepto y patrón de implementación
  • Herramientas: nginx, HAProxy, Kong (referencia)

Etapa 5: Diseño de Servicios Backend

Principios de Diseño de Software

  • Separation of concerns
  • Don’t repeat yourself (DRY)
  • Keep it simple, stupid (KISS)
  • You aren’t gonna need it (YAGNI)
  • Principio de mínima sorpresa
  • Acoplamiento y cohesión
  • Deuda técnica: concepto y gestión

Arquitectura en Capas

  • Arquitectura tradicional de tres capas: presentación, lógica, datos
  • Capas en una aplicación backend: controller, service, repository
  • Dependencias entre capas y dirección del flujo
  • Separación de responsabilidades por capa
  • Problemas comunes: fat controllers, anemic domain models

Patrones de Diseño Aplicados al Backend

  • Repository Pattern: abstracciön del acceso a datos
  • Service Layer: encapsulamiento de lógica de negocio
  • DTO (Data Transfer Object): separar representación de dominio
  • Mapper: conversión entre capas
  • Factory Pattern en contexto backend
  • Strategy Pattern para comportamiento intercambiable
  • Decorator Pattern para funcionalidades transversales
  • Facade Pattern para simplificar subsistemas complejos

Domain-Driven Design (Introducción)

  • ¿Qué es DDD y por qué importa?
  • Ubiquitous Language: vocabulario compartido con el negocio
  • Bounded Context: delimitar el dominio
  • Entidades vs. Value Objects
  • Aggregates y Aggregate Root
  • Repositorios en DDD
  • Domain Events: concepto
  • Diferencia entre DDD táctico y estratégico

Clean Architecture y Hexagonal Architecture

  • Motivación: independencia de frameworks, bases de datos y detalles
  • Clean Architecture: capas (Entities, Use Cases, Interface Adapters, Frameworks)
  • Regla de dependencia: apuntar hacia adentro
  • Hexagonal Architecture (Ports and Adapters): puertos de entrada y salida
  • Diferencias y similitudes entre ambas
  • Cuándo aplicarlas y cuándo es sobreingeniería

Manejo de Errores y Validaciones

  • Errores esperados vs. errores inesperados
  • Excepciones vs. valores de retorno de error (Result type)
  • Jerarquía de excepciones en Java
  • Checked vs. unchecked exceptions
  • Global exception handler: centralizar respuestas de error
  • Validación de entrada: Bean Validation (JSR-380), anotaciones personalizadas
  • Mensajes de error consistentes para APIs
  • Logging de errores: qué loggear y qué no

Seguridad en Aplicaciones Backend

  • OWASP Top 10: visión general
  • SQL Injection: cómo ocurre y cómo prevenirla (prepared statements)
  • XSS (Cross-Site Scripting): tipos y mitigación
  • CSRF: token de protección
  • Inyección de dependencias maliciosas
  • Gestión segura de secretos: variables de entorno, vaults
  • Hashing de contraseñas: bcrypt, argon2
  • Principio de menor privilegio
  • CORS: configuración correcta
  • Seguridad en headers HTTP: Content-Security-Policy, X-Frame-Options

Cacheo

  • ¿Por qué cachear? Latencia vs. consistencia
  • Tipos de caché: en proceso, distribuida, CDN
  • Estrategias: cache-aside, read-through, write-through, write-behind
  • Invalidación de caché: el problema difícil
  • TTL y expiración
  • Redis como caché: estructuras de datos, comandos básicos, TTL
  • Cache stampede y cómo mitigarlo
  • HTTP caching: Cache-Control, ETag, Last-Modified

Configuración y Entornos

  • Separación de configuración y código (12-factor app)
  • Variables de entorno: uso y buenas prácticas
  • Archivos de configuración por entorno: dev, staging, prod
  • Gestión de secretos: no committing secrets al repositorio
  • Feature flags: activar funcionalidades sin deployar
  • Configuration as Code

Monorepo vs. Multirepo

  • Definición de monorepo y multirepo
  • Ventajas y desventajas de cada enfoque
  • Herramientas para monorepos: Nx, Turborepo, Bazel (referencia)
  • Cuándo tiene sentido cada estrategia

Etapa 6: Testing y Calidad

Fundamentos de Testing

  • ¿Por qué testeamos? Confianza, documentación, refactoring seguro
  • Pirámide de testing: unitarios, integración, end-to-end
  • Definiciones: SUT (System Under Test), fixture, assertion
  • Ciclo Red-Green-Refactor (TDD)
  • Falsos positivos y falsos negativos en tests
  • Tests frágiles (flaky tests): causas y cómo evitarlos

Testing Unitario

  • Características de un buen test unitario: FIRST (Fast, Isolated, Repeatable, Self-validating, Timely)
  • Estructura AAA: Arrange, Act, Assert
  • JUnit 5 en Java: @Test, @BeforeEach, @AfterEach, @BeforeAll, @AfterAll
  • Assertions: assertEquals, assertThrows, assertAll
  • Parametrized tests: @ParameterizedTest, @ValueSource, @CsvSource
  • Herramientas equivalentes en otros lenguajes: pytest, Jest, RSpec

Mocking y Test Doubles

  • ¿Qué es un test double? Tipos: dummy, stub, spy, mock, fake
  • Mockito en Java: @Mock, @InjectMocks, when/thenReturn, verify
  • Cuándo mockear y cuándo no
  • Mocking de repositorios y servicios externos
  • Problemas de mockear en exceso: tests que no prueban nada real

Testing de Integración

  • Qué prueba un test de integración
  • Testcontainers: bases de datos reales en tests con Docker
  • Spring Boot Test: @SpringBootTest, contexto de aplicacion
  • Sliced tests: @WebMvcTest, @DataJpaTest
  • Testing de repositorios contra base de datos real
  • Fixtures y data setup: estrategias para datos de prueba

Testing de APIs

  • Testing de endpoints HTTP: MockMvc (Spring), Supertest (Node.js)
  • Verificación de status codes, headers y body
  • Testing de casos de error y validaciones
  • Contract testing: concepto y herramienta Pact
  • Generación de documentación desde tests: Spring REST Docs

Calidad de Código

  • Cobertura de código: qué mide y sus límites
  • Análisis estático: linters, SonarQube, Checkstyle, SpotBugs
  • Code smells: long methods, god classes, feature envy, duplicated code
  • Refactoring: técnicas básicas (extract method, rename, move, inline)
  • Revisión de código (code review): qué buscar, cómo dar feedback
  • Pair programming: concepto y beneficios

CI/CD y Automatización de Calidad

  • Integración Continua (CI): qué es y por qué importa
  • Pipeline de CI: build, test, lint, análisis estático
  • GitHub Actions: workflows, jobs, steps
  • GitLab CI / Jenkins: referencia conceptual
  • Fail fast: el pipeline debe fallar ante cualquier regresión
  • Entrega Continua (CD): diferencia entre continuous delivery y deployment
  • Estrategias de deployment: blue-green, canary, rolling update

Etapa 7: Sistemas Basados en Eventos

Fundamentos de Comunicación Asíncrona

  • Comunicación síncrona vs. asíncrona: diferencias y tradeoffs
  • ¿Cuándo usar mensajeríia en lugar de llamadas directas?
  • Desacoplamiento temporal y espacial
  • At-most-once, at-least-once, exactly-once: semánticas de entrega
  • Idempotencia en consumidores: por qué es necesaria
  • Poison messages: mensajes que no se pueden procesar

Colas de Mensajes

  • ¿Qué es una cola de mensajes?
  • Modelo punto a punto vs. publicar-suscribir (pub/sub)
  • Componentes: productor, cola, consumidor, broker
  • Dead letter queue (DLQ): propósito y configuración
  • Acknowledgment y requeue: flujo de confirmación
  • RabbitMQ: exchanges, queues, bindings, routing keys
  • Tipos de exchanges en RabbitMQ: direct, fanout, topic, headers
  • Durabilidad de mensajes y colas en RabbitMQ

Apache Kafka

  • ¿Qué es Kafka y por qué existe?
  • Arquitectura de Kafka: broker, topic, partition, offset, segment
  • Productores: configuración, serialización, partitioner
  • Consumidores: consumer group, rebalancing, lag
  • Offsets: auto-commit vs manual commit
  • Retención de mensajes: por tiempo y por tamaño
  • Replicación: leader, follower, ISR (in-sync replicas)
  • Kafka vs. RabbitMQ: cuándo elegir cada uno
  • Schema Registry y Avro: por qué tipar los mensajes importa
  • Kafka Streams: concepto de procesamiento de streams

Patrones de Mensajería

  • Saga Pattern: coordinación de transacciones distribuidas
  • Coreografía vs. orquestación en sagas
  • Outbox Pattern: garantizar consistencia entre base de datos y mensajes
  • Event Sourcing: concepto, estado derivado de eventos
  • CQRS (Command Query Responsibility Segregation): separación de lecturas y escrituras
  • Relación entre CQRS y Event Sourcing
  • Competing Consumers: escalar el consumo de mensajes
  • Message Deduplication: evitar procesamiento duplicado

Diseño de Eventos

  • ¿Qué información debe llevar un evento?
  • Eventos de dominio vs. eventos de integración
  • Versionado de eventos y compatibilidad hacia atrás
  • Thin events vs. fat events: tradeoffs
  • Convenciones de nomenclatura para eventos
  • Trazabilidad: correlation ID y causation ID

Etapa 8: Computación Distribuida

Fundamentos de Sistemas Distribuidos

  • ¿Qué es un sistema distribuido?
  • Las 8 falacias de la computación distribuida
  • Problemas fundamentales: relojes, orden de eventos, consenso
  • Relojes lógicos: Lamport timestamps
  • Relojes vectoriales: concepto
  • Consistencia eventual vs. consistencia fuerte
  • Teorema CAP en la práctica:trade-offs reales
  • PACELC: extensión del teorema CAP

Microservicios

  • ¿Que son los microservicios y de dónde vienen?
  • Monolito vs. microservicios: ventajas y desventajas
  • Principios de microservicios: autonomía, responsabilidad única, deployabilidad independiente
  • Comunicación entre servicios: síncrona vs. asíncrona
  • Service discovery: client-side vs. server-side (Consul, Eureka)
  • API Gateway en arquitecturas de microservicios
  • Strangler Fig Pattern: migración incremental desde monolito
  • Cuándo NO usar microservicios

Resiliencia y Tolerancia a Fallos

  • Fallos parciales en sistemas distribuidos
  • Timeout: configuración y estrategias
  • Retry con backoff exponencial y jitter
  • Circuit Breaker: estados (closed, open, half-open), Resilience4j
  • Bulkhead Pattern: aislar fallos entre componentes
  • Fallback: comportamiento degradado
  • Health checks: liveness vs. readiness probes
  • Chaos Engineering: concepto y herramienta Chaos Monkey

Consistencia y Transacciones Distribuidas

  • Por qué no hay transacciones ACID entre servicios
  • Two-Phase Commit (2PC): concepto y problemas
  • Saga Pattern en profundidad: coreografía vs. orquestación
  • Compensating transactions: deshacer efectos parciales
  • Eventual consistency en la práctica: manejo de inconsistencias temporales
  • Distributed locking: Redis SETNX, Redlock

Escalabilidad

  • Escalado vertical vs. horizontal
  • Stateless vs. stateful services: por qué stateless escala mejor
  • Sharding: estrategias de distribución de datos
  • Consistent hashing: distribución uniforme sin remapping total,
  • Read replicas: escalar lecturas
  • CQRS en contexto distribuido: separar modelos de lectura y escritura
  • Rate limiting distribuido
  • Back-pressure: controlar la velocidad del productor

Contenedores y Orquestación

  • ¿Qué es un contenedor? Docker: imagen, contenedor, Dockerfile
  • Diferencia entre contenedores y máquinas virtuales
  • Docker Compose: orquestación local para desarrollo
  • Registro de imágenes: Docker Hub, ECR, GCR
  • Kubernetes: motivación y arquitectura básica
  • Objetos de Kubernetes: Pod, Deployment, Service, ConfigMap, Secret, Ingress
  • kubectl: comandos básicos
  • Namespaces: aislamiento lógico de recursos
  • Horizontal Pod Autoscaler (HPA): escalado automático
  • Helm: gestión de aplicaciones en Kubernetes con charts

Almacenamiento Distribuido

  • Bases de datos distribuidas: retos de consenso y replicación
  • Algoritmo Raft: concepto de consenso distribuido
  • CockroachDB y YugabyteDB: bases SQL distribuidas (referencia)
  • Redis Cluster: sharding y replicación en Redis
  • S3 y almacenamiento de objetos: modelo y casos de uso
  • CDN: distribución geográfica de contenido

Etapa 9: Infraestructura y Observabilidad

Infrastructure as Code

  • ¿Qué es IaC y por qué importa?
  • Terraform: providers, resources, state, plan, apply
  • Módulos en Terraform: reutilización de configuración
  • Variables y outputs en Terraform
  • Remote state: almacenamiento compartido del estado
  • Ansible: concepto de configuration management (referencia)
  • Diferencia entre provisioning (Terraform) y configuration management (Ansible)

Cloud Computing

  • Modelos de servicio: IaaS, PaaS, SaaS, FaaS
  • Principales proveedores: AWS, GCP, Azure (conceptos agnósticos)
  • Regiones y zonas de disponibilidad (AZs)
  • Compute: instancias EC2 / VM, tipos y tamaños
  • Almacenamiento: S3/GCS (objetos), EBS/PD (bloques), EFS/Filestore (archivos)
  • Redes en la nube: VPC, subnets, security groups, route tables
  • Managed databases: RDS, Cloud SQL, Aurora
  • Serverless: AWS Lambda, Cloud Functions: casos de uso y limitaciones
  • Load balancers en la nube: ALB, NLB (AWS)
  • IAM: roles, políticas, least privilege en la nube

Monitoreo y Alertas

  • ¿Por qué observabilidad? Conocer el estado de los sistemas en producción
  • Los tres pilares de la observabilidad: métricas, logs, trazas
  • Métricas: tipos (contador, gauge, histograma, summary)
  • Prometheus: modelo de datos, scraping, PromQL básico
  • Grafana: dashboards, datasources, alertas visuales
  • RED method: Rate,Errors, Duration para servicios
  • USE method: Utilization, Saturation, Errors para recursos
  • SLI, SLO y SLA: definiciones y relaciones
  • Error budget: concepto y uso en SRE

Logging

  • Logging estructurado: JSON vs. texto plano
  • Niveles de log: DEBUG, INFO, WARN, ERROR, FATAL
  • Correlación de logs: request ID, trace ID
  • Centralización de logs: ELK stack (Elasticsearch, Logstash, Kibana), Loki + Grafana
  • Log rotation y retención
  • Qué no loggear: datos sensibles, PII
  • Búsqueda y filtrado de logs en producción

Distributed Tracing

  • ¿Qué es el tracing distribuido?
  • Span y Trace: jerarquía y propagación de contexto
  • OpenTelemetry: estándar de instrumentación
  • Instrumentación automática vs. manual
  • Backends de tracing: Jaeger, Zipkin, Tempo
  • Cómo identificar cuellos de botella con trazas
  • Correlación entre trazas, métricas y logs

Seguridad en Infraestructura

  • Principio de menor privilegio en sistemas
  • Gestión de secretos: HashiCorp Vault, AWS Secrets Manager
  • Escaneo de imagenes Docker: Trivy, Snyk
  • Network policies en Kubernetes
  • mTLS: autenticación mutua entre servicios
  • Service mesh: Istio y Linkerd (concepto y motivación)
  • SAST y DAST: análisis de seguridad estático y dinámico

Gestión de Incidentes

  • Qué es un incidente y cómo clasificarlo (severidad)
  • On-call y rotaciones
  • Runbooks: documentación operacional
  • Post-mortem sin culpa (blameless post-mortem)
  • Análisis de causa raíz: 5 Whys, fishbone diagram
  • SRE como disciplina: principios generales

Etapa 10: Paradigmas Avanzados (Scala y Sistemas Funcionales)

Fundamentos de Programación Funcional

  • ¿Qué es la programación funcional y de dónde viene?
  • Funciones puras: misma entrada, misma salida, sin efectos secundarios
  • Inmutabilidad: ventajas en sistemas concurrentes y distribuidos
  • Funciones de orden superior: map, filter, reduce, flatMap
  • Composición de funciones
  • Transparencia referencial
  • Recursión y recursión de cola (tail recursion)
  • Lazy evaluation: concepto y beneficios

Introducción a Scala

  • ¿Por qué Scala? Multiparadigma, JVM, ecosistema
  • Configuración del entorno: sbt, Scala CLI
  • Sintaxis básica: val, var, def, tipos de datos
  • Inferencia de tipos
  • Clases, case classes y objects
  • Traits: composicion de comportamiento
  • Pattern matching: match/case, deconstrucción
  • Option, Either, Try: manejo funcional de errores
  • Colecciones inmutables: List, Vector, Map, Set
  • For-comprehensions: azúcar sintáctico sobre flatMap/map

Tipos Avanzados en Scala

  • Generics y varianza: covarianza, contravarianza, invarianza
  • Type bounds: upper bounds, lower bounds
  • Implicit parameters y given/using (Scala 3)
  • Type classes: concepto y definición en Scala
  • Extension methods
  • Opaque types: encapsulamiento de tipos
  • Union types e Intersection types (Scala 3)

Efectos y Manejo de la Complejidad Funcional

  • El problema de los efectos secundarios en FP
  • Functor: qué es y cómo se usa (map)
  • Monad: concepto, flatMap, composición secuencial
  • Applicative: independencia entre efectos
  • Cats: biblioteca de abstracciones funcionales en Scala
  • Cats Effect: IO monad, referential transparency, runtime
  • Fibers: concurrencia ligera con Cats Effect
  • Resource: gestión segura de recursos con bracket

Akka y el Modelo de Actores

  • ¿Qué es el modelo de actores?
  • Actor: estado, comportamiento, buzón de mensajes
  • ActorSystem y jerarquía de actores
  • Typed Actors vs. Classic Actors en Akka
  • Supervisión y tolerancia a fallos: let it crash
  • Ask pattern vs. tell pattern
  • Akka Streams: Source, Flow, Sink
  • Backpressure en Akka Streams
  • Akka HTTP: construcción de APIs con Akka
  • Akka Cluster: distribución de actores en múltiples nodos (concepto)

Programación Reactiva

  • ¿Qué es la programación reactiva?
  • Manifiesto Reactivo: responsive, resilient, elastic, message-driven
  • Reactive Streams: especificación y backpressure
  • Project Reactor (Java): Mono y Flux
  • RxJava: Observable, Single, Flowable
  • Spring WebFlux: endpoints reactivos no bloqueantes
  • Cuándo usar programación reactiva y cuándo no

Diseño de Sistemas a Escala

  • Entrevistas de diseño de sistemas: cómo abordarlas
  • Estimaciones de capacidad: usuarios, requests por segundo, almacenamiento
  • Diseño de un sistema de URL shortener
  • Diseño de un sistema de rate limiter
  • Diseño de un feed de noticias
  • Diseño de un sistema de notificaciones
  • Diseño de un sistema de búsqueda
  • Trade-offs: consistencia vs. disponibilidad, latencia vs. throughput
  • Documentación de arquitectura: ADRs (Architecture Decision Records)