Guía completa para oposiciones — Teoría + Práctica
La arquitectura cliente/servidor es un modelo de computación distribuida en el que las tareas o cargas de trabajo se reparten entre los proveedores de recursos o servicios, llamados servidores, y los demandantes de dichos servicios, llamados clientes.
Características fundamentales:
- El cliente inicia la comunicación (rol activo).
- El servidor espera peticiones y las atiende (rol pasivo).
- La comunicación se realiza a través de una red.
- El servidor puede atender a múltiples clientes simultáneamente.
[CLIENTE] <---red---> [SERVIDOR]
(UI + lógica) (BD + datos)
[CLIENTE] <---> [SERVIDOR DE APLICACIONES] <---> [SERVIDOR BD]
(UI) (lógica de negocio) (datos)
| Tipo | Función | Ejemplo |
|---|---|---|
| Servidor Web | Sirve contenido HTTP/HTTPS | Apache, Nginx, IIS |
| Servidor de Aplicaciones | Lógica de negocio | Tomcat, JBoss, WebLogic |
| Servidor de Base de Datos | Gestión de datos | MySQL, PostgreSQL, Oracle |
| Servidor de Archivos | Almacenamiento compartido | Samba, NFS |
| Servidor de Correo | Postfix, Exchange | |
| Servidor DNS | Resolución de nombres | BIND, Windows DNS |
| Servidor Proxy | Intermediario | Squid, HAProxy |
Ventajas:
- Centralización de recursos y datos.
- Facilidad de mantenimiento y actualización.
- Seguridad centralizada.
- Escalabilidad (vertical y horizontal).
- Múltiples clientes comparten recursos.
Inconvenientes:
- Dependencia de la red.
- Cuello de botella en el servidor.
- Mayor coste inicial de infraestructura.
- Punto único de fallo (si no hay redundancia).
La arquitectura multicapas (N-tier) es una extensión del modelo cliente/servidor donde la aplicación se divide en múltiples capas lógicas y físicas, cada una con responsabilidades bien definidas y que se comunican con las capas adyacentes.
┌─────────────────────────────────┐
│ CAPA DE PRESENTACIÓN │ ← Frontend / UI
│ (HTML, CSS, JS, React, Angular)│
└────────────────┬────────────────┘
│ HTTP/REST
┌────────────────▼────────────────┐
│ CAPA DE LÓGICA DE NEGOCIO │ ← Backend / Application Server
│ (Java, .NET, Python, Node.js) │
└────────────────┬────────────────┘
│ SQL/ORM
┌────────────────▼────────────────┐
│ CAPA DE DATOS │ ← Base de Datos
│ (MySQL, PostgreSQL, Oracle) │
└─────────────────────────────────┘
[PRESENTACIÓN] → [APLICACIÓN] → [LÓGICA DE NEGOCIO] → [DATOS]
[UI Adapter]
|
[DB Adapter]─[DOMINIO]─[REST Adapter]
|
[Email Adapter]
Evolución natural de las arquitecturas multicapas:
[API Gateway]
|
┌──┴──────────────────────┐
│ │
[Servicio Usuario] [Servicio Pedidos] [Servicio Catálogo]
| | |
[BD Users] [BD Orders] [BD Products]
Principios:
- Cada servicio es independiente y desplegable por separado.
- Cada uno tiene su propia base de datos.
- Comunicación vía API REST o mensajería asíncrona.
- Escalado independiente por servicio.
Ventajas:
- Alta escalabilidad y disponibilidad.
- Despliegue independiente.
- Tecnología heterogénea por servicio.
Inconvenientes:
- Mayor complejidad operacional.
- Gestión de transacciones distribuidas (SAGA pattern).
- Latencia de red entre servicios.
| Patrón | Descripción |
|---|---|
| MVC (Model-View-Controller) | Separa modelo, vista y controlador |
| MVP (Model-View-Presenter) | El presenter maneja la lógica de vista |
| MVVM (Model-View-ViewModel) | Binding bidireccional entre vista y viewmodel |
| Repository | Abstrae el acceso a datos |
| DAO (Data Access Object) | Objeto de acceso a datos |
| DTO (Data Transfer Object) | Objeto para transferir datos entre capas |
| Factory | Creación de objetos |
| Singleton | Instancia única de un objeto |
| Observer | Notificación de cambios de estado |
Un servicio web es un sistema software diseñado para soportar la interoperabilidad entre máquinas a través de una red. Permite la comunicación entre aplicaciones heterogéneas.
Tipos principales:
1. SOAP (Simple Object Access Protocol) — basado en XML.
2. REST (Representational State Transfer) — basado en HTTP.
3. GraphQL — lenguaje de consulta para APIs.
4. gRPC — framework de RPC de alto rendimiento de Google.
5. WebSockets — comunicación bidireccional en tiempo real.
Definición: Protocolo de intercambio de mensajes basado en XML para comunicación entre aplicaciones a través de HTTP, SMTP, etc.
Estructura de un mensaje SOAP:
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<!-- Cabeceras opcionales: autenticación, seguridad -->
</soap:Header>
<soap:Body>
<GetUserRequest>
<UserId>123</UserId>
</GetUserRequest>
</soap:Body>
</soap:Envelope>
Componentes SOAP:
- WSDL (Web Services Description Language): describe el servicio.
- UDDI (Universal Description, Discovery and Integration): registro de servicios.
- XSD (XML Schema Definition): define tipos de datos.
Características:
- Independiente del protocolo de transporte.
- Soporte para seguridad (WS-Security).
- Soporte para transacciones (WS-AtomicTransaction).
- Verboso (mucho XML).
- Más utilizado en entornos empresariales legacy.
Definición: Estilo arquitectónico para sistemas distribuidos propuesto por Roy Fielding en su tesis doctoral (2000). No es un protocolo, sino un conjunto de restricciones.
Un recurso es cualquier información que puede ser nombrada. Se identifica con una URI.
# Colección
GET /api/usuarios
# Recurso individual
GET /api/usuarios/123
# Sub-recursos
GET /api/usuarios/123/pedidos
# Filtrado
GET /api/usuarios?rol=admin&activo=true
Buenas prácticas URI:
- Usar sustantivos, nunca verbos (/usuarios, NO /getUsuarios).
- Plural para colecciones.
- Minúsculas y guiones.
- Versionar la API: /api/v1/usuarios.
| Método | CRUD | Descripción | Idempotente | Seguro |
|---|---|---|---|---|
| GET | Read | Obtener recurso | Sí | Sí |
| POST | Create | Crear recurso | No | No |
| PUT | Update | Actualizar recurso completo | Sí | No |
| PATCH | Update | Actualizar recurso parcial | No | No |
| DELETE | Delete | Eliminar recurso | Sí | No |
| HEAD | - | Como GET pero sin body | Sí | Sí |
| OPTIONS | - | Opciones disponibles | Sí | Sí |
Idempotente: el resultado es el mismo aunque se repita la operación.
Seguro: no modifica el estado del servidor.
| Rango | Categoría | Ejemplos |
|---|---|---|
| 1xx | Informacional | 100 Continue |
| 2xx | Éxito | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirección | 301 Moved Permanently, 304 Not Modified |
| 4xx | Error del cliente | 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 422 Unprocessable Entity |
| 5xx | Error del servidor | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable |
Las respuestas incluyen enlaces para navegar por la API:
{
"id": 123,
"nombre": "Juan García",
"_links": {
"self": { "href": "/api/usuarios/123" },
"pedidos": { "href": "/api/usuarios/123/pedidos" },
"eliminar": { "href": "/api/usuarios/123", "method": "DELETE" }
}
}
# Crear usuario
POST /api/v1/usuarios
Content-Type: application/json
{
"nombre": "Ana López",
"email": "ana@ejemplo.com"
}
# Respuesta
HTTP/1.1 201 Created
Location: /api/v1/usuarios/456
Content-Type: application/json
{
"id": 456,
"nombre": "Ana López",
"email": "ana@ejemplo.com"
}
# Obtener usuario
GET /api/v1/usuarios/456
Accept: application/json
# Actualizar parcialmente
PATCH /api/v1/usuarios/456
Content-Type: application/json
{ "email": "ana.lopez@ejemplo.com" }
# Eliminar
DELETE /api/v1/usuarios/456
# Respuesta: 204 No Content
Definición: Lenguaje de consulta para APIs, desarrollado por Facebook (2015). El cliente especifica exactamente qué datos necesita.
Problema que resuelve:
- Over-fetching: REST devuelve más datos de los necesarios.
- Under-fetching: REST requiere múltiples peticiones para obtener datos relacionados.
Ejemplo:
# Consulta (Query)
query {
usuario(id: "123") {
nombre
email
pedidos {
id
total
}
}
}
# Mutación (escritura)
mutation {
crearUsuario(nombre: "Pedro", email: "pedro@ej.com") {
id
nombre
}
}
# Suscripción (tiempo real)
subscription {
nuevoPedido {
id
total
}
}
Ventajas: Flexibilidad, una sola petición, tipado fuerte, introspección.
Inconvenientes: Mayor complejidad del servidor, caché más difícil.
Definición: Framework de RPC (Remote Procedure Call) de Google, basado en HTTP/2 y Protocol Buffers (protobuf).
Características:
- Alto rendimiento (binario, no JSON).
- Tipado fuerte mediante archivos .proto.
- Streaming bidireccional.
- Ideal para microservicios internos.
// Definición del servicio
service UsuarioService {
rpc GetUsuario (UsuarioRequest) returns (Usuario);
rpc ListarUsuarios (ListarRequest) returns (stream Usuario);
}
message UsuarioRequest {
int32 id = 1;
}
message Usuario {
int32 id = 1;
string nombre = 2;
string email = 3;
}
Definición: Protocolo que proporciona un canal de comunicación bidireccional y full-duplex sobre una única conexión TCP.
Funcionamiento:
1. El cliente inicia con HTTP (handshake WebSocket).
2. El servidor acepta la actualización del protocolo.
3. Se establece una conexión persistente.
4. Ambos pueden enviar mensajes en cualquier momento.
// Cliente JavaScript
const ws = new WebSocket('wss://servidor.com/chat');
ws.onopen = () => ws.send(JSON.stringify({ tipo: 'saludo', texto: 'Hola' }));
ws.onmessage = (event) => console.log(JSON.parse(event.data));
ws.onclose = () => console.log('Conexión cerrada');
Casos de uso: Chat en tiempo real, juegos online, dashboards en vivo, notificaciones push.
| Característica | SOAP | REST | GraphQL | gRPC |
|---|---|---|---|---|
| Formato | XML | JSON/XML | JSON | Protobuf (binario) |
| Protocolo | HTTP, SMTP... | HTTP | HTTP | HTTP/2 |
| Estado | Stateful/Stateless | Stateless | Stateless | Stateless |
| Tipado | Fuerte (WSDL) | Débil | Fuerte (Schema) | Fuerte (.proto) |
| Caché | Difícil | Fácil (GET) | Difícil | Difícil |
| Rendimiento | Bajo | Medio | Medio | Alto |
| Uso típico | Empresarial legacy | APIs públicas | Apps flexibles | Microservicios |
| Herramientas | WSDL, UDDI | Swagger/OpenAPI | GraphiQL | Proto compiler |
HTTP (HyperText Transfer Protocol) — Protocolo de la capa de aplicación (OSI capa 7).
HTTPS: HTTP sobre TLS/SSL. Proporciona:
- Confidencialidad (cifrado de datos).
- Integridad (los datos no se modifican en tránsito).
- Autenticación (verifica la identidad del servidor).
Especificación estándar para documentar APIs REST.
openapi: 3.0.0
info:
title: API de Usuarios
version: 1.0.0
paths:
/usuarios/{id}:
get:
summary: Obtener usuario por ID
parameters:
- name: id
in: path
required: true
schema:
type: integer
responses:
'200':
description: Usuario encontrado
content:
application/json:
schema:
$ref: '#/components/schemas/Usuario'
'404':
description: No encontrado
components:
schemas:
Usuario:
type: object
properties:
id:
type: integer
nombre:
type: string
email:
type: string
API Key:
GET /api/usuarios
X-API-Key: mi-clave-secreta
Basic Auth:
GET /api/usuarios
Authorization: Basic dXN1YXJpbzpjb250cmFzZcOxYQ==
JWT (JSON Web Token):
Header.Payload.Signature
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV
OAuth 2.0: Framework de autorización delegada.
- Flujos: Authorization Code, Client Credentials, Implicit, PKCE.
- Se complementa con OpenID Connect para autenticación.
Prácticas de seguridad:
- HTTPS obligatorio.
- Rate limiting y throttling.
- Validación de entrada.
- CORS (Cross-Origin Resource Sharing).
- OWASP API Security Top 10.
Un sistema de control de versiones (VCS, Version Control System) registra los cambios realizados sobre un conjunto de ficheros a lo largo del tiempo, permitiendo recuperar versiones específicas.
Tipos de VCS:
- Local: solo en el equipo local (ej. RCS).
- Centralizado: un único servidor central (ej. SVN, CVS).
- Distribuido: cada cliente tiene una copia completa del repositorio (ej. Git, Mercurial).
Git es un sistema de control de versiones distribuido, creado por Linus Torvalds en 2005 para el desarrollo del kernel de Linux. Es el VCS más utilizado del mundo.
Características:
- Distribuido: cada clon es un repositorio completo.
- Rápido y eficiente (almacena snapshots, no diferencias).
- Integridad garantizada (SHA-1/SHA-256).
- Ramificación y fusión eficiente.
- Software libre (GPLv2).
Git almacena datos como instantáneas (snapshots) del sistema de archivos, no como diferencias (a diferencia de SVN).
Objetos de Git:
- Blob: contenido de un archivo.
- Tree: directorio (contiene blobs y otros trees).
- Commit: instantánea con metadatos (autor, fecha, mensaje, referencia al tree padre).
- Tag: etiqueta anotada.
Todos los objetos se identifican por su hash SHA-1 (40 caracteres hexadecimales).
[Directorio de trabajo] → git add → [Índice/Staging Area] → git commit → [Repositorio local] → git push → [Repositorio remoto]
Untracked → Staged → Committed
↑ ↓
Modified ←──┘
git config --global user.name "Nombre Apellido"
git config --global user.email "email@ejemplo.com"
git config --global core.editor "vim"
git config --list # Ver configuración
git init # Inicializar repositorio
git clone https://repo.git # Clonar repositorio
git clone https://repo.git nombre # Clonar con nombre personalizado
git status # Estado del directorio de trabajo
git log # Historial de commits
git log --oneline # Historial resumido
git log --oneline --graph --all # Árbol de ramas visual
git diff # Diferencias no añadidas al staging
git diff --staged # Diferencias en staging
git show abc1234 # Ver detalles de un commit
git add archivo.txt # Añadir archivo al staging
git add . # Añadir todos los cambios
git add -p # Añadir cambios interactivamente (por hunks)
git commit -m "mensaje" # Hacer commit
git commit -am "mensaje" # add + commit (solo archivos tracked)
git commit --amend # Modificar el último commit
git restore archivo.txt # Descartar cambios en working dir (nuevo)
git restore --staged archivo # Quitar del staging
git revert abc1234 # Crear commit que deshace otro
git reset --soft HEAD~1 # Deshacer último commit (mantiene staging)
git reset --mixed HEAD~1 # Deshacer último commit (mantiene working dir)
git reset --hard HEAD~1 # Deshacer último commit (PELIGROSO, borra cambios)
git clean -fd # Eliminar archivos no rastreados
git branch # Listar ramas locales
git branch -a # Listar todas las ramas
git branch nueva-rama # Crear rama
git checkout -b nueva-rama # Crear y cambiar a rama
git switch -c nueva-rama # Crear y cambiar a rama (moderno)
git switch rama # Cambiar de rama (moderno)
git branch -d rama # Eliminar rama (segura)
git branch -D rama # Eliminar rama (forzado)
# Merge: crea un commit de merge
git checkout main
git merge feature/login
# Merge fast-forward (sin commit de merge)
git merge --ff-only feature/login
# Merge sin fast-forward (fuerza commit de merge)
git merge --no-ff feature/login
# Rebase: reaplica commits sobre otra base
git checkout feature/login
git rebase main
# Rebase interactivo (para limpiar historial)
git rebase -i HEAD~3
Diferencia Merge vs Rebase:
- merge: preserva el historial completo, crea commit de fusión.
- rebase: historial lineal, NO usar en ramas compartidas.
git remote -v # Ver remotos
git remote add origin https://repo.git # Añadir remoto
git fetch origin # Descargar cambios sin fusionar
git pull origin main # Fetch + merge
git pull --rebase origin main # Fetch + rebase
git push origin main # Subir cambios
git push -u origin feature/login # Subir rama y establecer upstream
git push origin --delete rama # Eliminar rama remota
git tag # Listar tags
git tag v1.0.0 # Tag ligero
git tag -a v1.0.0 -m "Release" # Tag anotado
git push origin v1.0.0 # Subir tag
git push origin --tags # Subir todos los tags
git stash # Guardar cambios temporalmente
git stash push -m "descripción" # Guardar con descripción
git stash list # Listar stashes
git stash pop # Recuperar último stash
git stash apply stash@{2} # Aplicar stash específico
git stash drop stash@{0} # Eliminar stash
git cherry-pick abc1234 # Aplicar un commit específico en la rama actual
git bisect start # Búsqueda binaria de bugs
git bisect bad # Marcar commit actual como malo
git bisect good v1.0 # Marcar versión buena
git blame archivo.txt # Ver quién modificó cada línea
git reflog # Log de referencias (recuperación)
git submodule add https://... # Añadir submódulo
Un conflicto ocurre cuando dos ramas modifican la misma línea de un archivo.
<<<<<<< HEAD
línea en la rama actual
=======
línea en la rama que se fusiona
>>>>>>> feature/login
Resolución:
1. Editar el archivo y elegir/combinar los cambios.
2. Eliminar los marcadores <<<<<<<, =======, >>>>>>>.
3. git add archivo_resuelto.txt
4. git commit
Ramas principales:
- main (o master): código en producción.
- develop: integración de características.
Ramas de soporte:
- feature/xxx: nuevas funcionalidades (sale de develop).
- release/x.x.x: preparación de releases (sale de develop, va a main y develop).
- hotfix/xxx: correcciones urgentes en producción (sale de main, va a main y develop).
main: ●───────────────────●───●
│ │ │
develop: ●──●──────────────●─┤ │
│ │ │
feature: ●──●──●────●──┘ │
│
hotfix: ●──●──┘
Más sencillo, para despliegue continuo:
1. Crear rama desde main.
2. Añadir commits.
3. Abrir Pull Request.
4. Revisar y discutir.
5. Merge a main.
6. Desplegar inmediatamente.
Combina características de Git Flow y GitHub Flow. Añade ramas de entorno:
- main → pre-production → production.
trunk/main).Archivo que especifica qué archivos/directorios deben ser ignorados por Git.
# Archivos de compilación
*.class
*.pyc
build/
dist/
target/
# Dependencias
node_modules/
vendor/
# Variables de entorno y secretos
.env
*.key
*.pem
# IDEs
.idea/
.vscode/
*.swp
# Sistema operativo
.DS_Store
Thumbs.db
# Logs
*.log
logs/
Mensajes de commit (Conventional Commits):
<tipo>[ámbito opcional]: <descripción>
[cuerpo opcional]
[notas al pie opcionales]
Tipos:
- feat: nueva funcionalidad.
- fix: corrección de bug.
- docs: documentación.
- style: formato, sin cambios lógicos.
- refactor: refactorización.
- test: añadir/corregir tests.
- chore: tareas de mantenimiento.
- perf: mejora de rendimiento.
- ci: cambios en CI/CD.
Ejemplos:
feat(auth): añadir autenticación con JWT
fix(usuarios): corregir validación de email duplicado
docs: actualizar README con instrucciones de instalación
Otras buenas prácticas:
- Commits pequeños y atómicos (un cambio por commit).
- Siempre escribir mensajes descriptivos.
- No hacer commit de archivos generados o secretos.
- Usar Pull Requests para revisión de código.
- Proteger la rama main (branch protection rules).
- Usar tags para versiones de release.
| Característica | Git | SVN |
|---|---|---|
| Modelo | Distribuido | Centralizado |
| Historial | Local completo | Solo online |
| Ramas | Baratas y rápidas | Lentas y costosas |
| Commits offline | Sí | No |
| Rendimiento | Alto | Medio |
| Curva de aprendizaje | Alta | Media |
| Popularidad | Muy alta | Media (declinando) |
Una metodología de desarrollo de software es un marco de trabajo que define el proceso, las prácticas, las herramientas y las técnicas a seguir para desarrollar software de manera sistemática.
Clasificación principal:
- Predictivas (clásicas o en cascada): el plan se define al inicio.
- Ágiles (iterativas e incrementales): flexibles, orientadas al cambio.
Propuesto por Winston Royce (1970). Proceso secuencial y lineal.
[Requisitos] → [Diseño] → [Implementación] → [Verificación] → [Mantenimiento]
Fases:
1. Análisis de requisitos: qué debe hacer el sistema.
2. Diseño del sistema: arquitectura, módulos, interfaces.
3. Implementación: codificación.
4. Pruebas (verificación): detección de errores.
5. Despliegue: puesta en producción.
6. Mantenimiento: correcciones y mejoras.
Ventajas:
- Simple y fácil de gestionar.
- Documentación exhaustiva.
- Adecuado para proyectos con requisitos estables.
Inconvenientes:
- No apto para requisitos cambiantes.
- El cliente no ve resultados hasta el final.
- Los errores detectados tardíamente son muy costosos.
Extensión del modelo en cascada que enfatiza la verificación y validación.
Análisis ────────────────── Aceptación
Diseño sistema ──────── Integración
Diseño detallado ── Pruebas unitarias
Implementación
Modelo iterativo que combina elementos del cascada con prototipos. Se centra en la gestión del riesgo.
Cuatro cuadrantes por iteración:
1. Determinación de objetivos: objetivos, alternativas, restricciones.
2. Evaluación de alternativas: análisis y reducción de riesgos.
3. Desarrollo y prueba: prototipo, implementación.
4. Planificación: revisión y plan siguiente iteración.
Proceso de desarrollo iterativo e incremental, basado en UML. Desarrollado por IBM Rational.
Fases:
1. Inicio (Inception): alcance, viabilidad, casos de negocio.
2. Elaboración: arquitectura base, reducción de riesgos.
3. Construcción: desarrollo iterativo del producto.
4. Transición: entrega al usuario final, formación.
Disciplinas:
- Modelado del negocio.
- Requisitos.
- Análisis y diseño.
- Implementación.
- Pruebas.
- Despliegue.
- Gestión del proyecto.
- Gestión de la configuración.
- Entorno.
El Manifiesto Ágil (2001) establece 4 valores:
1. Individuos e interacciones sobre procesos y herramientas.
2. Software funcionando sobre documentación exhaustiva.
3. Colaboración con el cliente sobre negociación de contratos.
4. Respuesta ante el cambio sobre seguir un plan.
12 Principios Ágiles (resumidos):
- Satisfacción del cliente mediante entrega continua.
- Bienvenida a cambios, incluso tardíos.
- Entregas frecuentes de software funcional.
- Colaboración diaria entre negocio y desarrolladores.
- Proyectos con personas motivadas y entorno de apoyo.
- Conversación cara a cara como método más eficiente.
- Software funcionando como medida principal de progreso.
- Ritmo de desarrollo sostenible.
- Atención continua a la excelencia técnica.
- Simplicidad (maximizar trabajo no realizado).
- Equipos autoorganizados generan mejores resultados.
- Reflexión periódica y ajuste del comportamiento.
Framework ágil más popular. Desarrollado por Ken Schwaber y Jeff Sutherland (1995).
| Rol | Responsabilidad |
|---|---|
| Product Owner (PO) | Maximiza el valor del producto. Gestiona el Product Backlog. Representa al cliente. |
| Scrum Master (SM) | Facilita el proceso Scrum. Elimina impedimentos. Coach del equipo. |
| Developers | Equipo multifuncional (3-9 personas). Autoorganizado. Entrega el Incremento. |
| Evento | Duración | Propósito |
|---|---|---|
| Sprint | 1-4 semanas (fija) | Iteración de desarrollo |
| Sprint Planning | Máx. 8h (Sprint 4 sem.) | Planificar el Sprint |
| Daily Scrum | 15 minutos | Sincronización diaria del equipo |
| Sprint Review | Máx. 4h | Demo e inspección del incremento |
| Sprint Retrospective | Máx. 3h | Mejora del proceso |
Daily Scrum (3 preguntas):
- ¿Qué hice ayer que ayudó al objetivo del Sprint?
- ¿Qué haré hoy para ayudar al objetivo del Sprint?
- ¿Hay algún impedimento que me bloquea?
Formato estándar:
Como [tipo de usuario],
quiero [funcionalidad],
para [beneficio/valor].
Criterios de aceptación (INVEST):
- Independiente
- Negociable
- Valiosa
- Estimable
- Small (pequeña)
- Testeable
Estimación con Story Points (Fibonacci: 1, 2, 3, 5, 8, 13, 21, ∞).
Planning Poker: técnica de estimación colaborativa.
Framework ágil orientado al flujo de trabajo continuo. Origen en Toyota (sistema de producción JIT).
Principios:
1. Empezar con lo que hay ahora.
2. Aceptar el cambio evolutivo e incremental.
3. Respetar los roles, responsabilidades y títulos actuales.
Prácticas:
1. Visualizar el flujo de trabajo (tablero Kanban).
2. Limitar el WIP (Work In Progress).
3. Gestionar el flujo.
4. Hacer las políticas explícitas.
5. Implementar bucles de retroalimentación.
6. Mejorar de forma colaborativa.
Tablero Kanban:
| Por hacer | En progreso | Revisión | Hecho |
|-----------|-------------|----------|-------|
| Tarea A | Tarea B | Tarea C | Tarea D |
| Tarea E | | | |
Métricas Kanban:
- Lead Time: tiempo desde que se solicita hasta que se entrega.
- Cycle Time: tiempo desde que se empieza hasta que se termina.
- Throughput: elementos completados por unidad de tiempo.
Metodología ágil de alta ingeniería, propuesta por Kent Beck (1999).
Valores XP: Simplicidad, Comunicación, Retroalimentación, Valentía, Respeto.
Prácticas XP principales:
| Práctica | Descripción |
|---|---|
| TDD (Test-Driven Development) | Primero el test, luego el código |
| Pair Programming | Dos desarrolladores en un ordenador |
| Refactoring continuo | Mejorar el código sin cambiar funcionalidad |
| Integración Continua | Integrar y compilar varias veces al día |
| Releases pequeños | Entregas frecuentes y pequeñas |
| Diseño simple | El código más sencillo que funcione |
| Código colectivo | Cualquiera puede modificar cualquier código |
| 40 horas semanales | Sin horas extra sostenidas |
| Cliente en el sitio | Cliente disponible para preguntas |
| Estándares de código | Convenciones compartidas |
Framework para escalar ágil en organizaciones grandes. Niveles:
- Team: Scrum/Kanban.
- Program: Agile Release Train (ART).
- Large Solution: coordinación de múltiples ARTs.
- Portfolio: gestión estratégica.
| Metodología | Tipo | Equipo | Requisitos | Documentación | Entregables |
|---|---|---|---|---|---|
| Cascada | Predictiva | Cualquier tamaño | Estables | Muy alta | Al final |
| RUP | Iterativa | Grande | Cambiantes | Alta | Por fases |
| Scrum | Ágil | 3-9 personas | Cambiantes | Mínima | Cada Sprint |
| Kanban | Ágil/Lean | Cualquiera | Flujo continuo | Mínima | Continuo |
| XP | Ágil/técnica | Pequeño | Muy cambiantes | Mínima | Semanal |
| SAFe | Ágil escalado | Empresa | Cambiantes | Media | PI Planning |
Las pruebas de software (testing) son el proceso de evaluación de un sistema para verificar que satisface los requisitos especificados e identificar defectos.
Objetivos:
- Detectar defectos (bugs).
- Verificar que el software cumple los requisitos.
- Aumentar la confianza en la calidad.
- Prevenir defectos (en etapas tempranas).
Principios del testing (ISTQB):
1. El testing muestra la presencia de defectos, no su ausencia.
2. El testing exhaustivo es imposible.
3. El testing temprano ahorra tiempo y dinero.
4. Los defectos se agrupan (regla 80/20 — Principio de Pareto).
5. La paradoja del pesticida (los tests se vuelven menos efectivos con el tiempo).
6. El testing depende del contexto.
7. La falacia de la ausencia de errores.
/\
/UI\ ← Pruebas de extremo a extremo (E2E)
/────\
/Integr\ ← Pruebas de integración
/─────────\
/ Unitarias \ ← Pruebas unitarias (base, más abundantes)
/───────────────\
// Ejemplo en Java con JUnit 5
@Test
void testSumar() {
Calculadora calc = new Calculadora();
assertEquals(5, calc.sumar(2, 3));
assertEquals(-1, calc.sumar(2, -3));
}
# Ejemplo en Python con pytest
def test_suma():
assert suma(2, 3) == 5
assert suma(-1, 1) == 0
Ejemplo partición equivalencia:
Campo edad (1-120):
- Clase válida: 1-120
- Clase inválida: <1, >120, no numérico
| Tipo | Qué verifica |
|---|---|
| Rendimiento | Tiempo de respuesta, throughput |
| Carga | Comportamiento bajo carga esperada |
| Estrés | Comportamiento más allá de los límites normales |
| Volumen | Comportamiento con grandes volúmenes de datos |
| Escalabilidad | Capacidad de escalar ante mayor demanda |
| Seguridad | Vulnerabilidades, autenticación, autorización |
| Usabilidad | Facilidad de uso |
| Compatibilidad | Distintos navegadores, SO, dispositivos |
| Accesibilidad | WCAG, discapacidades |
| Fiabilidad | MTBF (Mean Time Between Failures) |
| Recuperación | Recuperación ante fallos |
Desarrollo guiado por tests. El ciclo TDD es:
Red → Green → Refactor
Ventajas:
- Diseño orientado a la testabilidad.
- Cobertura de tests alta desde el inicio.
- Documentación viva del comportamiento.
- Detecta errores de diseño temprano.
BDD (Behaviour-Driven Development): extensión de TDD que utiliza lenguaje natural (Gherkin) para escribir tests comprensibles por negocio.
# Gherkin (BDD)
Feature: Inicio de sesión
Scenario: Usuario válido
Given que estoy en la página de login
When introduzco usuario "admin" y contraseña "1234"
Then debería redirigirme al dashboard
And debería ver el mensaje "Bienvenido, admin"
Herramientas BDD: Cucumber, SpecFlow, Behave (Python).
| Lenguaje | Unit Testing | Mocking | E2E / Integración |
|---|---|---|---|
| Java | JUnit 5, TestNG | Mockito, PowerMock | Selenium, Cucumber |
| Python | pytest, unittest | unittest.mock | Selenium, Robot Framework |
| JavaScript | Jest, Mocha, Jasmine | Sinon.js | Cypress, Playwright |
| .NET | NUnit, xUnit | Moq | SpecFlow |
| PHP | PHPUnit | Mockery | Behat |
Cobertura de código:
- Java: JaCoCo.
- Python: coverage.py.
- JavaScript: Istanbul (nyc).
- .NET: Coverlet.
Ciclo de vida de un defecto:
Nuevo → Asignado → En progreso → Resuelto → Verificado → Cerrado
↓
Reabierto
Severidad vs Prioridad:
- Severidad: impacto técnico del defecto (Crítico, Mayor, Menor, Trivial).
- Prioridad: urgencia de resolución (Alta, Media, Baja).
Un defecto puede ser de alta severidad y baja prioridad (o viceversa).
Información en un informe de defecto:
- ID único.
- Título descriptivo.
- Descripción detallada.
- Pasos para reproducir.
- Resultado esperado vs. resultado obtenido.
- Severidad y prioridad.
- Versión del software.
- Entorno (SO, navegador, etc.).
- Capturas de pantalla/logs.
El proceso de construcción (build) es el proceso automatizado de transformar el código fuente en un artefacto ejecutable o desplegable. Incluye compilación, enlazado, empaquetado y otras tareas.
Definición: Práctica de desarrollo donde los miembros del equipo integran su trabajo frecuentemente (al menos una vez al día), y cada integración se verifica mediante builds y tests automatizados.
Objetivos:
- Detectar problemas de integración tempranamente.
- Reducir el riesgo de integración ("integration hell").
- Mantener el software siempre en estado funcional.
Flujo CI típico:
Commit → Push → Build → Test → Análisis de código → Notificación
Prácticas CI:
- Repositorio de código único.
- Build automatizado.
- Tests automatizados.
- Builds rápidos (< 10 minutos idealmente).
- Arreglar builds rotos inmediatamente.
- Visibilidad del estado del build para todo el equipo.
Definición: El software está siempre en un estado que puede ser desplegado a producción en cualquier momento. El despliegue a producción es una decisión humana.
CI → Build → Test → Deploy a Staging → Aprobación manual → Deploy a Producción
Definición: Cada cambio que supera todos los tests se despliega automáticamente a producción, sin intervención humana.
CI → Build → Test → Deploy a Staging → Test → Deploy a Producción (automático)
Continuous Integration
←──────────────────→
Commit → Build → Test → Staging → [Aprobación] → Producción
←──────────────────────────────────────→
Continuous Delivery
←──────────────────────────────────────────────→
Continuous Deployment (sin aprobación)
| Herramienta | Tipo | Características |
|---|---|---|
| Jenkins | Autohosteado | Muy flexible, gran ecosistema de plugins |
| GitHub Actions | SaaS/YAML | Integrado con GitHub, fácil de usar |
| GitLab CI/CD | SaaS/Autohosteado | Integrado con GitLab, potente |
| Azure DevOps | SaaS | Ecosistema Microsoft |
| CircleCI | SaaS | Rápido, fácil de configurar |
| Travis CI | SaaS | Popular en open source |
| Bamboo | Atlassian | Integrado con Jira/Bitbucket |
| ArgoCD | GitOps | Despliegue en Kubernetes |
Ejemplo de pipeline con GitHub Actions:
# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configurar Java 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Compilar
run: mvn compile
- name: Ejecutar tests
run: mvn test
- name: Análisis SonarCloud
run: mvn sonar:sonar
- name: Construir artefacto
run: mvn package -DskipTests
- name: Publicar cobertura
uses: codecov/codecov-action@v3
deploy-staging:
needs: build-and-test
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- name: Desplegar en Staging
run: |
echo "Desplegando en entorno de staging..."
# Comandos de despliegue aquí
deploy-production:
needs: build-and-test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production # Requiere aprobación manual
steps:
- name: Desplegar en Producción
run: |
echo "Desplegando en producción..."
<!-- Maven pom.xml (fragmento) -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
// Gradle build.gradle (fragmento)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web:3.1.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.0'
}
{
"scripts": {
"build": "webpack --mode production",
"test": "jest",
"lint": "eslint src/"
},
"dependencies": {
"react": "^18.0.0"
},
"devDependencies": {
"jest": "^29.0.0"
}
}
Docker permite empaquetar aplicaciones en contenedores, garantizando que se ejecuten igual en cualquier entorno.
# Dockerfile de ejemplo para aplicación Java
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY target/mi-aplicacion.jar app.jar
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget -qO- http://localhost:8080/health || exit 1
ENTRYPOINT ["java", "-jar", "app.jar"]
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
depends_on:
- db
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb
db:
image: postgres:15
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
| Métrica | Descripción |
|---|---|
| Bugs | Defectos en el código |
| Vulnerabilidades | Problemas de seguridad |
| Code Smells | Problemas de mantenibilidad |
| Cobertura | % de código cubierto por tests |
| Deuda técnica | Tiempo estimado para arreglar code smells |
| Duplicaciones | % de código duplicado |
| Complejidad ciclomática | Número de caminos independientes |
Repositorios de artefactos para almacenar los productos del build:
- Nexus Repository: JARs, Maven, Docker images.
- JFrog Artifactory: universal, múltiples formatos.
- GitHub Packages: integrado con GitHub.
- Docker Hub / Registry: imágenes Docker.
Definición: Gestión y aprovisionamiento de infraestructura mediante código, en lugar de procesos manuales.
Herramientas:
- Terraform: declarativo, multi-cloud.
- Ansible: automatización de configuración.
- Helm: gestión de aplicaciones en Kubernetes.
- Pulumi: IaC con lenguajes de programación convencionales.
# Terraform ejemplo
resource "aws_instance" "servidor_web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = {
Name = "ServidorWeb"
Env = "produccion"
}
}
Práctica donde los cambios en infraestructura y aplicaciones se gestionan mediante Pull Requests en Git, y herramientas como ArgoCD o Flux sincronizan el estado del repositorio con el clúster de Kubernetes.
| Sigla | Significado |
|---|---|
| API | Application Programming Interface |
| BDD | Behaviour-Driven Development |
| CI | Continuous Integration |
| CD | Continuous Delivery / Deployment |
| CRUD | Create, Read, Update, Delete |
| DAO | Data Access Object |
| DDD | Domain-Driven Design |
| DTO | Data Transfer Object |
| E2E | End-to-End |
| gRPC | Google Remote Procedure Call |
| HATEOAS | Hypermedia As The Engine Of Application State |
| HTTP | HyperText Transfer Protocol |
| IaC | Infrastructure as Code |
| JWT | JSON Web Token |
| MVC | Model-View-Controller |
| MVP | Model-View-Presenter |
| MVVM | Model-View-ViewModel |
| ORM | Object-Relational Mapping |
| PO | Product Owner |
| REST | Representational State Transfer |
| RUP | Rational Unified Process |
| SOAP | Simple Object Access Protocol |
| SM | Scrum Master |
| TDD | Test-Driven Development |
| TLS | Transport Layer Security |
| UAT | User Acceptance Testing |
| URI | Uniform Resource Identifier |
| VCS | Version Control System |
| WIP | Work In Progress |
| WSDL | Web Services Description Language |
| XP | Extreme Programming |
Documento generado para preparación de oposiciones — Tema 2: Arquitectura de sistemas cliente/servidor y multicapas. Versión completa con contenido teórico y práctico.