first commit

This commit is contained in:
Tatiana Villa 2026-04-24 20:03:15 +02:00
parent beeb673fcd
commit 1271a5e25b
18 changed files with 6021 additions and 17 deletions

Binary file not shown.

770
bloque3/tema2.md Normal file
View File

@ -0,0 +1,770 @@
# Bloque 3 · Tema 2
# Lenguajes de programación. Representación de tipos de datos. Operadores. Instrucciones condicionales. Bucles y recursividad. Procedimientos, funciones y parámetros. Vectores y registros. Estructura de un programa.
---
# 1. Esquema introductorio (visión rápida)
**Lenguajes de programación**
→ Herramientas formales para expresar algoritmos que una máquina puede ejecutar.
**Clasificación principal**
- Por nivel de abstracción: bajo, medio, alto nivel
- Por paradigma: imperativo, orientado a objetos, funcional, lógico
- Por ejecución: compilados, interpretados, mixtos (bytecode)
**Elementos básicos de un programa**
- Tipos de datos
- Operadores
- Variables y constantes
- Instrucciones de control (condicionales y bucles)
- Subprogramas (procedimientos y funciones)
- Estructuras de datos (vectores, registros)
---
# 2. Lenguajes de programación
## 2.1 Concepto
Un **lenguaje de programación** es un lenguaje formal que especifica un conjunto de instrucciones para que un ordenador realice determinadas tareas.
Consta de:
- **Sintaxis:** reglas que definen cómo escribir las instrucciones (forma).
- **Semántica:** significado de cada instrucción (lo que hace).
- **Pragmática:** uso práctico del lenguaje.
## 2.2 Clasificación por nivel de abstracción
| Nivel | Descripción | Ejemplos |
|-------|-------------|---------|
| **Bajo nivel** | Cercano al hardware, directamente comprensible por la máquina | Lenguaje máquina, ensamblador |
| **Medio nivel** | Combina control de bajo nivel con abstracciones | C |
| **Alto nivel** | Alejado del hardware, cercano al lenguaje humano | Python, Java, C++, Pascal |
### Lenguaje máquina
- Instrucciones en binario (0 y 1).
- Dependiente del procesador.
- Difícil de programar y mantener.
### Ensamblador (Assembler)
- Usa **nemónicos** (MOV, ADD, JMP…) en lugar de binario.
- Requiere un **ensamblador** para traducir al lenguaje máquina.
- Sigue siendo dependiente del hardware.
### Lenguajes de alto nivel
- Independientes del hardware.
- Requieren **compiladores** o **intérpretes** para ejecutarse.
- Mayor productividad y mantenibilidad.
## 2.3 Clasificación por paradigma
| Paradigma | Descripción | Ejemplos |
|-----------|-------------|---------|
| **Imperativo / procedural** | Secuencia de instrucciones que modifican el estado | C, Pascal, COBOL |
| **Orientado a objetos (POO)** | Modela la realidad con objetos que tienen estado y comportamiento | Java, C++, Python |
| **Funcional** | Basado en funciones matemáticas, sin estado mutable | Haskell, Lisp, Erlang |
| **Lógico / declarativo** | Se declara qué se quiere, no cómo obtenerlo | Prolog, SQL |
| **Orientado a eventos** | El flujo lo dirigen eventos (clics, mensajes…) | JavaScript, Visual Basic |
| **Multiparadigma** | Combina varios paradigmas | Python, Scala, Kotlin |
## 2.4 Clasificación por mecanismo de ejecución
| Tipo | Proceso | Ventajas | Ejemplos |
|------|---------|----------|---------|
| **Compilado** | El compilador traduce todo el código fuente a código máquina antes de ejecutar | Velocidad de ejecución | C, C++, Go |
| **Interpretado** | Un intérprete lee y ejecuta línea a línea en tiempo real | Portabilidad, desarrollo rápido | Python, Ruby, JavaScript |
| **Bytecode / VM** | Se compila a un código intermedio ejecutado por una máquina virtual | Portabilidad + rendimiento | Java (JVM), C# (.NET CLR) |
### Compilador vs. Intérprete
| | Compilador | Intérprete |
|--|-----------|-----------|
| Traducción | Todo antes de ejecutar | Línea a línea en ejecución |
| Velocidad ejecución | Mayor (código nativo) | Menor |
| Detección de errores | Antes de ejecutar | Durante ejecución |
| Portabilidad | Menor (binario específico) | Mayor |
### Fases del compilador
1. **Análisis léxico** divide el código en tokens.
2. **Análisis sintáctico** verifica la gramática (árbol sintáctico).
3. **Análisis semántico** verifica el significado (tipos, declaraciones).
4. **Generación de código intermedio**.
5. **Optimización**.
6. **Generación de código final** (lenguaje máquina o bytecode).
---
# 3. Representación de tipos de datos
## 3.1 Qué es un tipo de dato
Un **tipo de dato** define:
- El **conjunto de valores** posibles que puede tomar una variable.
- Las **operaciones** que se pueden realizar sobre ella.
- La **representación interna** en memoria (número de bytes).
## 3.2 Tipos de datos simples (o primitivos)
### Enteros (integer, int)
- Representan números sin parte decimal.
- Se almacenan en complemento a dos (para negativos).
| Tipo | Tamaño típico | Rango |
|------|--------------|-------|
| `byte` / `char` | 1 byte (8 bits) | 128 a 127 (con signo) / 0 a 255 (sin signo) |
| `short` | 2 bytes | 32.768 a 32.767 |
| `int` | 4 bytes | 2.147.483.648 a 2.147.483.647 |
| `long` | 8 bytes | ±9,2 × 10¹⁸ |
### Reales / Coma flotante (float, double)
- Representan números con parte decimal.
- Estándar **IEEE 754**.
| Tipo | Tamaño | Precisión |
|------|--------|-----------|
| `float` | 4 bytes | ~7 dígitos decimales |
| `double` | 8 bytes | ~15 dígitos decimales |
- Se almacenan como: `signo | exponente | mantisa`.
### Caracteres (char)
- Representan un único carácter.
- Codificaciones: **ASCII** (7/8 bits, 128/256 caracteres), **Unicode / UTF-8** (hasta 4 bytes, >1 millón de caracteres).
### Booleano (boolean, bool)
- Solo dos valores: **verdadero** (`true`) / **falso** (`false`).
- Ocupa 1 byte en la mayoría de implementaciones.
- Fundamental en expresiones lógicas y control de flujo.
### Enumerados (enum)
- Tipo que define un conjunto finito de valores con nombre.
```
enum DiaSemana { LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO }
```
## 3.3 Tipos de datos compuestos (o estructurados)
- **Vectores / Arrays:** colección de elementos del mismo tipo, acceso por índice.
- **Registros / Structs:** colección de campos de distintos tipos bajo un mismo nombre.
- **Cadenas (String):** secuencia de caracteres.
- **Listas, pilas, colas:** estructuras de datos dinámicas.
- **Clases / Objetos:** en POO, agrupan datos y comportamiento.
## 3.4 Variables y constantes
| Concepto | Descripción |
|----------|-------------|
| **Variable** | Posición en memoria con un nombre simbólico cuyo valor puede cambiar durante la ejecución |
| **Constante** | Igual que una variable pero su valor no puede modificarse tras la inicialización |
**Declaración típica:**
```
int edad = 25; // variable
const double PI = 3.14159; // constante
```
**Ámbito (scope):**
- **Local:** visible solo dentro del bloque donde se declara.
- **Global:** visible en todo el programa.
- **Estática:** conserva su valor entre llamadas a la función.
**Conversión de tipos (casting):**
- **Implícita (widening):** automática, sin pérdida de información (int → long → double).
- **Explícita (narrowing):** manual, posible pérdida de información (double → int).
---
# 4. Operadores
## 4.1 Tipos de operadores
### Aritméticos
| Operador | Operación | Ejemplo |
|----------|-----------|---------|
| `+` | Suma | `a + b` |
| `-` | Resta | `a - b` |
| `*` | Multiplicación | `a * b` |
| `/` | División | `a / b` |
| `%` | Módulo (resto) | `a % b` |
| `**` / `^` | Potencia | `a ** 2` |
> En división entera (int/int), el resultado es entero: `7 / 2 = 3`.
### Relacionales (comparación)
Devuelven un valor booleano.
| Operador | Significado |
|----------|-------------|
| `==` | Igual a |
| `!=` | Distinto de |
| `<` | Menor que |
| `>` | Mayor que |
| `<=` | Menor o igual |
| `>=` | Mayor o igual |
### Lógicos
| Operador | Significado | Descripción |
|----------|-------------|-------------|
| `&&` / `AND` | Y lógico | Verdadero si ambos son verdaderos |
| `\|\|` / `OR` | O lógico | Verdadero si al menos uno es verdadero |
| `!` / `NOT` | Negación | Invierte el valor booleano |
**Cortocircuito:** en `A && B`, si A es falso, B no se evalúa. En `A || B`, si A es verdadero, B no se evalúa.
### De asignación
| Operador | Equivale a |
|----------|-----------|
| `=` | Asignación simple |
| `+=` | `a = a + b` |
| `-=` | `a = a - b` |
| `*=` | `a = a * b` |
| `/=` | `a = a / b` |
| `%=` | `a = a % b` |
### De bits (bitwise)
Operan sobre los bits individuales del número.
| Operador | Descripción |
|----------|-------------|
| `&` | AND bit a bit |
| `\|` | OR bit a bit |
| `^` | XOR bit a bit |
| `~` | Complemento a uno (NOT) |
| `<<` | Desplazamiento izquierda (×2 por bit) |
| `>>` | Desplazamiento derecha (÷2 por bit) |
### Otros
- **Operador ternario:** `condicion ? valor_si_true : valor_si_false`
- **Operador de dirección (`&`)** y **desreferenciación (`*`)** en C/C++.
- **`instanceof`** en Java para comprobar el tipo de un objeto.
## 4.2 Precedencia de operadores
De mayor a menor prioridad (simplificado):
1. `()` Paréntesis
2. `!`, `~`, `++`, `--` Unarios
3. `*`, `/`, `%` Multiplicativos
4. `+`, `-` Aditivos
5. `<<`, `>>` Desplazamiento
6. `<`, `<=`, `>`, `>=` Relacionales
7. `==`, `!=` Igualdad
8. `&`, `^`, `|` Bitwise
9. `&&`, `||` Lógicos
10. `?:` Ternario
11. `=`, `+=`, `-=` Asignación
> Ante la duda, usar **paréntesis** para forzar el orden deseado.
---
# 5. Instrucciones condicionales
Las instrucciones condicionales permiten **tomar decisiones** en función del valor de una condición booleana.
## 5.1 If Else if Else
```
if (condicion1) {
// bloque A: se ejecuta si condicion1 es verdadera
} else if (condicion2) {
// bloque B: se ejecuta si condicion1 es falsa y condicion2 es verdadera
} else {
// bloque C: se ejecuta si ninguna condicion es verdadera
}
```
- Solo se ejecuta **un bloque**.
- El `else` es opcional.
- Se pueden encadenar tantos `else if` como haga falta.
## 5.2 Switch Case
Útil cuando se compara la misma variable contra múltiples valores constantes.
```
switch (variable) {
case valor1:
// instrucciones
break;
case valor2:
// instrucciones
break;
default:
// si no coincide ningún caso
}
```
- **`break`** es esencial para evitar el **fall-through** (ejecución de casos siguientes).
- **`default`** es el equivalente al `else`.
- En Java/C, solo funciona con tipos enteros, char o String (Java 7+).
## 5.3 Operador ternario
Versión compacta del `if-else` para asignaciones simples:
```
int max = (a > b) ? a : b;
```
## 5.4 Condicionales en pseudocódigo (examen)
```
SI condicion ENTONCES
instrucciones
SINO SI condicion2 ENTONCES
instrucciones
SINO
instrucciones
FIN_SI
```
---
# 6. Bucles y recursividad
Los **bucles** (o estructuras de repetición) permiten ejecutar un bloque de código **varias veces**.
## 6.1 Bucle while (mientras)
Se ejecuta mientras la condición sea verdadera. La condición se comprueba **antes** de cada iteración.
```
while (condicion) {
// cuerpo del bucle
}
```
- Si la condición es falsa desde el inicio, el cuerpo **no se ejecuta nunca**.
- Riesgo de **bucle infinito** si la condición nunca se hace falsa.
**Pseudocódigo:**
```
MIENTRAS condicion HACER
instrucciones
FIN_MIENTRAS
```
## 6.2 Bucle do-while (hacer…mientras)
El cuerpo se ejecuta **al menos una vez**; la condición se comprueba **al final**.
```
do {
// cuerpo del bucle
} while (condicion);
```
**Pseudocódigo:**
```
HACER
instrucciones
MIENTRAS condicion
```
## 6.3 Bucle for (para)
Ideal cuando se conoce el **número de iteraciones** de antemano.
```
for (inicializacion; condicion; actualizacion) {
// cuerpo del bucle
}
// Ejemplo
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
```
Partes:
- **Inicialización:** se ejecuta una vez al inicio.
- **Condición:** se evalúa antes de cada iteración; si es falsa, termina el bucle.
- **Actualización:** se ejecuta al final de cada iteración.
**Pseudocódigo:**
```
PARA i DESDE 1 HASTA 10 HACER
instrucciones
FIN_PARA
```
## 6.4 For-each (para cada)
Recorre automáticamente todos los elementos de una colección.
```
for (Tipo elemento : coleccion) {
// usar elemento
}
```
## 6.5 Control de bucles
| Instrucción | Efecto |
|-------------|--------|
| `break` | Sale inmediatamente del bucle |
| `continue` | Salta a la siguiente iteración (omite el resto del cuerpo) |
| `return` | Sale de la función (también termina el bucle) |
## 6.6 Recursividad
Una función es **recursiva** cuando **se llama a sí misma** para resolver un problema.
### Estructura de una función recursiva
```
funcion factorial(n):
SI n == 0 ENTONCES // Caso base (condicion de parada)
DEVOLVER 1
SINO
DEVOLVER n * factorial(n - 1) // Llamada recursiva
FIN_SI
```
### Elementos clave
| Elemento | Descripción |
|----------|-------------|
| **Caso base** | Condición que detiene la recursión (sin él → bucle infinito → desbordamiento de pila) |
| **Llamada recursiva** | La función se invoca a sí misma con un subproblema más pequeño |
| **Convergencia** | Cada llamada debe acercarse al caso base |
### Cómo funciona internamente
Cada llamada recursiva añade un **marco de activación** a la **pila de llamadas** (*call stack*). Si hay demasiadas llamadas anidadas se produce un **StackOverflowError**.
### Recursividad vs. Iteración
| | Recursividad | Iteración (bucle) |
|--|-------------|-------------------|
| Legibilidad | Mayor (en problemas divisibles) | Mayor (en secuencias simples) |
| Coste de memoria | Mayor (pila de llamadas) | Menor |
| Riesgo | Stack overflow | Bucle infinito |
| Idóneo para | Árboles, grafos, divide y vencerás | Bucles simples, arrays |
### Tipos de recursividad
- **Directa:** la función se llama a sí misma.
- **Indirecta (mutua):** A llama a B, y B llama a A.
- **De cola (tail recursion):** la llamada recursiva es la **última operación** (los compiladores pueden optimizarla a iteración).
### Ejemplos clásicos
- Factorial: `n! = n * (n-1)!`
- Fibonacci: `fib(n) = fib(n-1) + fib(n-2)`
- Torres de Hanói
- Búsqueda binaria
- Recorrido de árboles
---
# 7. Procedimientos, funciones y parámetros
## 7.1 Concepto de subprograma
Un **subprograma** (subrutina) es un bloque de código con nombre que realiza una tarea concreta y puede ser llamado desde distintos puntos del programa.
**Ventajas:**
- Reutilización de código.
- Modularidad y mantenibilidad.
- Abstracción (ocultar detalles de implementación).
- Facilita las pruebas.
## 7.2 Procedimiento vs. Función
| | Procedimiento | Función |
|-|--------------|---------|
| Devuelve valor | No (o `void`) | Sí |
| Se usa en | Instrucción independiente | Expresión o asignación |
| Ejemplo (pseudocódigo) | `PROCEDIMIENTO imprimirSaludo()` | `FUNCION calcularArea(r): real` |
> En Java y C, la distinción se hace mediante el tipo de retorno: `void` para procedimientos, cualquier tipo para funciones.
## 7.3 Parámetros y argumentos
| Término | Definición |
|---------|-----------|
| **Parámetro formal** | Variable declarada en la firma de la función |
| **Argumento (parámetro real)** | Valor concreto que se pasa al llamar la función |
```java
// Parámetros formales: radio, pi
double calcularCircunferencia(double radio, double pi) {
return 2 * pi * radio;
}
// Argumentos: 5.0, 3.14159
double c = calcularCircunferencia(5.0, 3.14159);
```
## 7.4 Paso de parámetros
### Por valor (by value)
- Se copia el valor del argumento en la variable del parámetro.
- Cambios dentro de la función **no afectan** a la variable original.
- Java usa este mecanismo para tipos primitivos.
```
funcion incrementar(x):
x = x + 1 // modifica la copia local, no el original
```
### Por referencia (by reference)
- Se pasa la **dirección de memoria** de la variable.
- Cambios dentro de la función **sí afectan** al original.
- Usado en C/C++ con punteros (`&`), Ç en Java para objetos (referencia al objeto).
```c
void incrementar(int *x) {
(*x)++; // modifica el valor en la dirección recibida
}
```
### Por nombre (by name)
- El argumento se evalúa cada vez que se usa dentro de la función (lazy evaluation).
- Típico de lenguajes funcionales (Haskell).
### Resumen
| Mecanismo | Modifica el original | Lenguajes |
|-----------|---------------------|----------|
| Por valor | No | Java (primitivos), C (por defecto) |
| Por referencia | Sí | C++ (`&`), C (punteros), C# (`ref`) |
| Por nombre | Depende | Haskell, algunos funcionales |
## 7.5 Tipos de parámetros según su uso
| Tipo | Dirección del flujo de datos |
|------|------------------------------|
| **Entrada (IN)** | Del llamador a la función |
| **Salida (OUT)** | De la función al llamador |
| **Entrada/Salida (IN/OUT)** | Ambas direcciones |
## 7.6 Funciones de orden superior
En lenguajes funcionales o modernos (Python, JavaScript, Java 8+), las funciones son **ciudadanos de primera clase**: pueden pasarse como parámetros, devolverse como resultado y almacenarse en variables.
```python
def aplicar(funcion, valor):
return funcion(valor)
resultado = aplicar(lambda x: x * 2, 5) # 10
```
## 7.7 Sobrecarga (overloading)
**Overloading:** definir varias funciones con el **mismo nombre** pero diferente número o tipo de parámetros. El compilador elige cuál usar según los argumentos.
```java
int suma(int a, int b) { return a + b; }
double suma(double a, double b) { return a + b; }
```
---
# 8. Vectores y registros
## 8.1 Vectores (arrays / arreglos)
Un **vector** es una estructura de datos que almacena una colección **ordenada** de elementos del **mismo tipo**, accesibles mediante un **índice**.
### Características
- Tamaño **fijo** (definido en la declaración, en arrays estáticos).
- Acceso **directo** (O(1)): conociendo el índice, se accede al elemento en tiempo constante.
- Los índices suelen empezar en **0** (C, Java, Python) o en **1** (Pascal, algunos pseudocódigos).
### Declaración y acceso
```java
// Declaración
int[] notas = new int[10]; // array de 10 enteros
// Inicialización
int[] primos = {2, 3, 5, 7, 11};
// Acceso por índice
notas[0] = 8;
int primera = primos[0]; // 2
```
### Vectores multidimensionales (matrices)
- **Bidimensional (matriz):** `int[][] matriz = new int[3][4];`
- Acceso: `matriz[fila][columna]`
### Operaciones típicas con vectores
- Recorrido (for, for-each).
- Búsqueda lineal (O(n)) y búsqueda binaria (O(log n), requiere ordenación).
- Ordenación: burbuja, inserción, selección, quicksort, mergesort.
- Inserción y eliminación (en arrays estáticos implica desplazar elementos).
### Pseudocódigo para recorrer un vector
```
PARA i DESDE 0 HASTA longitud(v)-1 HACER
ESCRIBIR v[i]
FIN_PARA
```
## 8.2 Cadenas de caracteres (String)
- Secuencia de caracteres, internamente un array de `char`.
- En muchos lenguajes son **inmutables** (Java: `String`; Python: `str`).
- Operaciones típicas: longitud, concatenación, subcadena, búsqueda, comparación, conversión a mayúsculas/minúsculas.
## 8.3 Registros (records / structs)
Un **registro** es una estructura de datos que agrupa variables de **distintos tipos** bajo un mismo nombre. Cada variable del registro se llama **campo**.
### Ejemplo en pseudocódigo
```
REGISTRO Empleado
nombre: cadena
dni: cadena
edad: entero
salario: real
FIN_REGISTRO
```
### Uso
```
Empleado e;
e.nombre = "Ana García";
e.edad = 34;
e.salario = 2500.00;
```
### En lenguajes reales
- **C:** `struct`
- **Pascal:** `record`
- **Java/C++:** `class` (aunque con más funcionalidades: métodos, acceso controlado)
### Arrays de registros
Se pueden combinar: un array donde cada elemento es un registro.
```
Empleado[] plantilla = new Empleado[100];
plantilla[0].nombre = "Ana";
```
## 8.4 Diferencias clave
| | Vector / Array | Registro / Struct |
|--|---------------|-----------------|
| Tipos de elementos | Todos iguales (homogéneo) | Pueden ser distintos (heterogéneo) |
| Acceso | Por índice numérico | Por nombre del campo |
| Tamaño | Fijo (estático) o dinámico (ArrayList) | Fijo (definido por los campos) |
| Uso típico | Colecciones ordenadas del mismo tipo | Representar una entidad con varios atributos |
---
# 9. Estructura de un programa
## 9.1 Estructura general
Un programa bien estructurado se organiza en bloques diferenciados:
```
[1] ZONA DE DECLARACIONES
- Importaciones / usos de módulos
- Constantes globales
- Tipos de datos definidos por el usuario
- Variables globales
[2] SUBPROGRAMAS (funciones y procedimientos)
- Cada uno con su cabecera y cuerpo
[3] PROGRAMA PRINCIPAL
- Punto de entrada
- Llamadas a subprogramas
- Secuencia principal de instrucciones
```
## 9.2 Ejemplo en pseudocódigo
```
PROGRAMA CalculadoraSimple
CONSTANTE PI = 3.14159
FUNCION cuadrado(x: real): real
DEVOLVER x * x
FIN_FUNCION
FUNCION areaCirculo(radio: real): real
DEVOLVER PI * cuadrado(radio)
FIN_FUNCION
INICIO
radio ← LEER("Introduce el radio: ")
area ← areaCirculo(radio)
ESCRIBIR("Área = ", area)
FIN
```
## 9.3 Estructura en Java (ejemplo)
```java
// 1. Declaración del paquete e importaciones
package com.ejemplo;
import java.util.Scanner;
// 2. Declaración de la clase
public class Calculadora {
// 3. Constantes y variables de clase
static final double PI = 3.14159;
// 4. Métodos (subprogramas)
static double cuadrado(double x) {
return x * x;
}
static double areaCirculo(double radio) {
return PI * cuadrado(radio);
}
// 5. Método principal (punto de entrada)
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Introduce el radio: ");
double radio = sc.nextDouble();
System.out.println("Área = " + areaCirculo(radio));
}
}
```
## 9.4 Principios de buena estructura
| Principio | Descripción |
|-----------|-------------|
| **Modularidad** | Dividir el problema en módulos independientes |
| **Cohesión** | Cada módulo hace una sola cosa (alta cohesión) |
| **Acoplamiento** | Los módulos deben depender lo menos posible entre sí (bajo acoplamiento) |
| **Legibilidad** | Nombres descriptivos, indentación consistente, comentarios |
| **Reutilización** | Escribir código que pueda usarse en otros contextos |
## 9.5 Programación estructurada
Tres estructuras de control son **suficientes** para expresar cualquier algoritmo (**Teorema de Böhm-Jacopini**):
1. **Secuencia:** instrucciones una tras otra.
2. **Selección:** condicionales (if-else, switch).
3. **Repetición:** bucles (while, for, do-while).
La programación estructurada evita el uso de `GOTO`, que genera código difícil de seguir (*spaghetti code*).
---
# 10. Resumen: conceptos clave para el examen
| Concepto | Dato clave |
|----------|-----------|
| Lenguaje compilado | Todo se traduce antes de ejecutar (C, C++) |
| Lenguaje interpretado | Se traduce línea a línea (Python, JavaScript) |
| Bytecode | Código intermedio para máquina virtual (Java → JVM, C# → CLR) |
| Fases del compilador | Léxico → Sintáctico → Semántico → Generación → Optimización → Código final |
| IEEE 754 | Estándar para representación de números en coma flotante |
| Complemento a dos | Representación de enteros negativos en binario |
| Cortocircuito | `&&` no evalúa el segundo operando si el primero es falso |
| Recursión: caso base | Condición de parada que evita el bucle infinito |
| Stack overflow | Error por exceso de llamadas recursivas (pila llena) |
| Paso por valor | Se copia el dato; cambios no afectan al original |
| Paso por referencia | Se pasa la dirección; cambios sí afectan al original |
| Array | Colección de elementos del mismo tipo, acceso por índice O(1) |
| Registro / Struct | Agrupación de campos de distintos tipos |
| Teorema de Böhm-Jacopini | Secuencia + Selección + Repetición son suficientes |
| Sobrecarga | Mismo nombre de función, distintos parámetros |

564
bloque3/tema3.md Normal file
View File

@ -0,0 +1,564 @@
# Bloque 3 · Tema 3
# Lenguajes de interrogación de bases de datos. Estándar ANSI SQL. Procedimientos almacenados. Eventos y disparadores.
---
# 1. Esquema introductorio (visión rápida)
**SQL (Structured Query Language)**
→ Lenguaje estándar para interactuar con bases de datos relacionales.
**Sublenguajes de SQL**
- DDL Definición (CREATE, ALTER, DROP)
- DML Manipulación (SELECT, INSERT, UPDATE, DELETE)
- DCL Control (GRANT, REVOKE)
- TCL Transacciones (COMMIT, ROLLBACK, SAVEPOINT)
**Objetos avanzados**
- Vistas (VIEW)
- Índices (INDEX)
- Procedimientos almacenados
- Funciones de usuario
- Disparadores (TRIGGER)
- Eventos
---
# 2. Estándar ANSI SQL
## 2.1 Historia y versiones
| Versión | Año | Novedades principales |
|---------|-----|----------------------|
| SQL-86 | 1986 | Primera normalización ANSI/ISO |
| SQL-89 | 1989 | Mejoras de integridad referencial |
| SQL-92 | 1992 | Estándar ampliamente adoptado (joins, subconsultas) |
| SQL:1999 | 1999 | POO, recursividad, tipos complejos |
| SQL:2003 | 2003 | XML, MERGE, funciones ventana |
| SQL:2011 | 2011 | Datos temporales |
| SQL:2016 | 2016 | JSON |
## 2.2 DDL Lenguaje de Definición de Datos
Permite crear y modificar la estructura de la base de datos.
### CREATE TABLE
```sql
CREATE TABLE empleados (
id INT PRIMARY KEY AUTO_INCREMENT,
nombre VARCHAR(100) NOT NULL,
dni CHAR(9) UNIQUE NOT NULL,
departamento_id INT,
salario DECIMAL(10,2) DEFAULT 0.00,
fecha_alta DATE,
FOREIGN KEY (departamento_id) REFERENCES departamentos(id)
ON DELETE SET NULL
ON UPDATE CASCADE
);
```
### Restricciones (CONSTRAINTS)
| Restricción | Descripción |
|------------|-------------|
| `PRIMARY KEY` | Identifica únicamente cada fila; implica NOT NULL + UNIQUE |
| `FOREIGN KEY` | Referencia a la clave primaria de otra tabla (integridad referencial) |
| `UNIQUE` | Los valores del campo son únicos |
| `NOT NULL` | El campo no puede ser nulo |
| `DEFAULT` | Valor por defecto si no se especifica |
| `CHECK` | Condición que deben cumplir los valores |
### ALTER TABLE
```sql
-- Añadir columna
ALTER TABLE empleados ADD COLUMN email VARCHAR(200);
-- Modificar tipo
ALTER TABLE empleados MODIFY COLUMN salario DECIMAL(12,2);
-- Eliminar columna
ALTER TABLE empleados DROP COLUMN email;
-- Añadir restricción
ALTER TABLE empleados ADD CONSTRAINT chk_salario CHECK (salario >= 0);
```
### DROP
```sql
DROP TABLE empleados; -- Elimina tabla y datos
DROP TABLE IF EXISTS empleados; -- Evita error si no existe
TRUNCATE TABLE empleados; -- Vacía la tabla (más rápido que DELETE)
```
## 2.3 DML Lenguaje de Manipulación de Datos
### SELECT Consulta de datos
```sql
-- Estructura completa (orden obligatorio)
SELECT columnas
FROM tabla
JOIN otra_tabla ON condicion
WHERE filtros
GROUP BY agrupacion
HAVING filtro_sobre_grupos
ORDER BY columna [ASC|DESC]
LIMIT n OFFSET m;
```
**Ejemplo completo:**
```sql
SELECT d.nombre AS departamento,
COUNT(e.id) AS num_empleados,
AVG(e.salario) AS salario_medio
FROM empleados e
JOIN departamentos d ON e.departamento_id = d.id
WHERE e.fecha_alta >= '2020-01-01'
GROUP BY d.nombre
HAVING AVG(e.salario) > 2000
ORDER BY salario_medio DESC
LIMIT 5;
```
### Tipos de JOIN
| JOIN | Resultado |
|------|-----------|
| `INNER JOIN` | Solo filas que coinciden en ambas tablas |
| `LEFT JOIN` | Todas las de la izquierda + coincidencias de la derecha |
| `RIGHT JOIN` | Todas las de la derecha + coincidencias de la izquierda |
| `FULL OUTER JOIN` | Todas las filas de ambas tablas |
| `CROSS JOIN` | Producto cartesiano (todas las combinaciones posibles) |
| `SELF JOIN` | La tabla se une consigo misma |
### Funciones de agregación
| Función | Descripción |
|---------|-------------|
| `COUNT(*)` | Número de filas |
| `COUNT(col)` | Número de valores no nulos |
| `SUM(col)` | Suma |
| `AVG(col)` | Media |
| `MAX(col)` | Valor máximo |
| `MIN(col)` | Valor mínimo |
### Subconsultas (subqueries)
```sql
-- En WHERE
SELECT nombre FROM empleados
WHERE salario > (SELECT AVG(salario) FROM empleados);
-- Con IN
SELECT nombre FROM empleados
WHERE departamento_id IN (SELECT id FROM departamentos WHERE nombre = 'IT');
-- Subconsulta correlacionada
SELECT nombre, salario FROM empleados e
WHERE salario = (
SELECT MAX(salario) FROM empleados
WHERE departamento_id = e.departamento_id
);
```
### INSERT
```sql
-- Una fila
INSERT INTO empleados (nombre, dni, salario) VALUES ('Ana López', '12345678A', 2500);
-- Varias filas
INSERT INTO empleados (nombre, salario) VALUES
('Luis Pérez', 2200),
('Marta Ruiz', 2800);
-- Desde otra tabla
INSERT INTO empleados_backup SELECT * FROM empleados WHERE fecha_alta < '2020-01-01';
```
### UPDATE
```sql
UPDATE empleados
SET salario = salario * 1.05, -- subida del 5%
fecha_alta = CURDATE()
WHERE departamento_id = 3;
```
### DELETE
```sql
DELETE FROM empleados WHERE id = 42;
-- Con condición compuesta
DELETE FROM empleados
WHERE salario < 1000 AND departamento_id IS NULL;
```
## 2.4 DCL Lenguaje de Control de Datos
```sql
-- Conceder permisos
GRANT SELECT, INSERT ON empleados TO usuario1;
GRANT ALL PRIVILEGES ON base_datos.* TO admin@'localhost';
-- Revocar permisos
REVOKE INSERT ON empleados FROM usuario1;
```
## 2.5 TCL Control de Transacciones
Una **transacción** es un conjunto de operaciones que se tratan como una unidad atómica (todas o ninguna).
```sql
START TRANSACTION;
UPDATE cuentas SET saldo = saldo - 1000 WHERE id = 1;
UPDATE cuentas SET saldo = saldo + 1000 WHERE id = 2;
COMMIT; -- confirma los cambios
-- o
ROLLBACK; -- deshace todos los cambios desde START TRANSACTION
-- Punto de guardado
SAVEPOINT punto1;
ROLLBACK TO SAVEPOINT punto1;
```
### Propiedades ACID
| Propiedad | Descripción |
|-----------|-------------|
| **Atomicidad** | Todo o nada |
| **Consistencia** | La BD pasa de un estado válido a otro válido |
| **Aislamiento** | Las transacciones concurrentes no interfieren entre sí |
| **Durabilidad** | Los cambios confirmados persisten aunque haya fallo |
## 2.6 Vistas (VIEW)
Una **vista** es una consulta almacenada que se comporta como una tabla virtual.
```sql
-- Crear vista
CREATE VIEW empleados_activos AS
SELECT id, nombre, salario FROM empleados
WHERE activo = 1;
-- Usar la vista como si fuera una tabla
SELECT * FROM empleados_activos WHERE salario > 2000;
-- Eliminar vista
DROP VIEW empleados_activos;
```
**Ventajas:** seguridad (ocultan columnas/filas sensibles), simplicidad, reutilización.
## 2.7 Índices (INDEX)
Los índices aceleran las consultas a costa de mayor espacio en disco y más lentitud en escrituras.
```sql
-- Índice normal
CREATE INDEX idx_nombre ON empleados(nombre);
-- Índice único
CREATE UNIQUE INDEX idx_dni ON empleados(dni);
-- Índice compuesto
CREATE INDEX idx_dept_sal ON empleados(departamento_id, salario);
-- Eliminar índice
DROP INDEX idx_nombre ON empleados;
```
**Tipos de índices:** B-Tree (más común), Hash, Full-Text, Espacial.
**Cuándo usarlos:** columnas muy consultadas en WHERE, JOIN o ORDER BY.
**Cuándo evitarlos:** tablas pequeñas, columnas con poca selectividad (ej. booleanos).
---
# 3. Procedimientos almacenados
## 3.1 Concepto
Un **procedimiento almacenado** (*stored procedure*) es un bloque de código SQL (y lógica de control) que se guarda en la propia base de datos y se puede invocar por nombre.
**Ventajas:**
- Reutilización de código.
- Rendimiento (se compilan y optimizan una vez).
- Seguridad (solo se expone el nombre del procedimiento, no las tablas).
- Reducción del tráfico de red (se ejecuta en el servidor).
- Centralización de la lógica de negocio.
**Inconvenientes:**
- Difícil depuración.
- Dependencia del SGBD (menor portabilidad).
- Más complejidad en el mantenimiento.
## 3.2 Sintaxis (MySQL / MariaDB)
```sql
DELIMITER $$
CREATE PROCEDURE actualizar_salario(
IN p_departamento INT,
IN p_porcentaje DECIMAL(5,2),
OUT p_afectados INT
)
BEGIN
-- Variables locales
DECLARE v_count INT DEFAULT 0;
-- Lógica
UPDATE empleados
SET salario = salario * (1 + p_porcentaje / 100)
WHERE departamento_id = p_departamento;
SET v_count = ROW_COUNT();
SET p_afectados = v_count;
END$$
DELIMITER ;
-- Llamada
CALL actualizar_salario(3, 5.0, @afectados);
SELECT @afectados;
```
## 3.3 Tipos de parámetros
| Tipo | Dirección | Descripción |
|------|-----------|-------------|
| `IN` | Entrada | El llamador pasa un valor; no se modifica en el exterior |
| `OUT` | Salida | El procedimiento devuelve un valor |
| `INOUT` | Bidireccional | Entrada y salida |
## 3.4 Estructuras de control en procedimientos
```sql
-- Condicional
IF condicion THEN
instrucciones;
ELSEIF otra_condicion THEN
instrucciones;
ELSE
instrucciones;
END IF;
-- CASE
CASE variable
WHEN valor1 THEN instrucciones;
WHEN valor2 THEN instrucciones;
ELSE instrucciones;
END CASE;
-- Bucle WHILE
WHILE condicion DO
instrucciones;
END WHILE;
-- Bucle LOOP con LEAVE
mi_bucle: LOOP
IF condicion_salida THEN LEAVE mi_bucle; END IF;
instrucciones;
END LOOP;
-- Cursor (recorrer filas)
DECLARE cur CURSOR FOR SELECT id, nombre FROM empleados;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
FETCH cur INTO v_id, v_nombre;
CLOSE cur;
```
## 3.5 Funciones de usuario (UDF)
Similares a los procedimientos pero **devuelven un valor** y pueden usarse dentro de consultas SQL.
```sql
CREATE FUNCTION calcular_irpf(salario DECIMAL(10,2))
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
DECLARE irpf DECIMAL(10,2);
IF salario < 12450 THEN SET irpf = salario * 0.19;
ELSEIF salario < 20200 THEN SET irpf = salario * 0.24;
ELSE SET irpf = salario * 0.30;
END IF;
RETURN irpf;
END;
-- Uso dentro de SELECT
SELECT nombre, salario, calcular_irpf(salario) AS irpf FROM empleados;
```
| | Procedimiento | Función |
|-|--------------|---------|
| Devuelve valor | No (usa OUT) | Sí (RETURNS) |
| Uso dentro de SELECT | No | Sí |
| Transacciones (COMMIT/ROLLBACK) | Sí | No (generalmente) |
---
# 4. Disparadores (TRIGGERS)
## 4.1 Concepto
Un **disparador** (*trigger*) es un bloque de código que se ejecuta **automáticamente** cuando ocurre un evento concreto (INSERT, UPDATE, DELETE) sobre una tabla.
No se llama directamente: se activa de forma implícita cuando se produce el evento.
## 4.2 Sintaxis
```sql
CREATE TRIGGER nombre_trigger
{ BEFORE | AFTER }
{ INSERT | UPDATE | DELETE }
ON nombre_tabla
FOR EACH ROW
BEGIN
-- cuerpo del trigger
-- acceso a filas con NEW y OLD
END;
```
## 4.3 NEW y OLD
| | INSERT | UPDATE | DELETE |
|-|--------|--------|--------|
| `NEW` | Nueva fila | Fila después de actualizar | No disponible |
| `OLD` | No disponible | Fila antes de actualizar | Fila eliminada |
## 4.4 BEFORE vs AFTER
| | BEFORE | AFTER |
|-|--------|-------|
| Se ejecuta | Antes de la operación | Después de la operación |
| Puede cancelar la operación | Sí (usando SIGNAL) | No |
| Uso típico | Validaciones, modificar valores antes de insertar | Auditoría, actualizar tablas relacionadas |
## 4.5 Ejemplos
```sql
-- AFTER INSERT: guardar en tabla de auditoría
CREATE TRIGGER trg_auditoria_empleados
AFTER INSERT ON empleados
FOR EACH ROW
BEGIN
INSERT INTO auditoria (accion, tabla, id_registro, fecha)
VALUES ('INSERT', 'empleados', NEW.id, NOW());
END;
-- BEFORE UPDATE: no permitir reducir el salario
CREATE TRIGGER trg_controlar_salario
BEFORE UPDATE ON empleados
FOR EACH ROW
BEGIN
IF NEW.salario < OLD.salario THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'No se puede reducir el salario';
END IF;
END;
-- AFTER DELETE: actualizar contador en departamento
CREATE TRIGGER trg_actualizar_contador
AFTER DELETE ON empleados
FOR EACH ROW
BEGIN
UPDATE departamentos
SET num_empleados = num_empleados - 1
WHERE id = OLD.departamento_id;
END;
```
## 4.6 Gestión de triggers
```sql
-- Ver triggers
SHOW TRIGGERS FROM nombre_base_datos;
-- Eliminar trigger
DROP TRIGGER IF EXISTS trg_auditoria_empleados;
```
## 4.7 Usos habituales de los triggers
- **Auditoría:** registrar automáticamente quién cambió qué y cuándo.
- **Integridad:** validaciones complejas que no pueden expresarse con CHECK.
- **Sincronización:** mantener datos derivados actualizados (contadores, totales).
- **Soft delete:** marcar como borrado en lugar de eliminar físicamente.
- **Historial:** guardar versiones anteriores de un registro.
---
# 5. Eventos (EVENT)
## 5.1 Concepto
Un **evento** en MySQL/MariaDB es una tarea programada que se ejecuta automáticamente en un momento concreto o de forma periódica. Es como un *cron job* dentro del propio SGBD.
```sql
-- Habilitar el planificador de eventos
SET GLOBAL event_scheduler = ON;
```
## 5.2 Sintaxis
```sql
CREATE EVENT nombre_evento
ON SCHEDULE
{ AT timestamp | EVERY intervalo [STARTS inicio] [ENDS fin] }
[ON COMPLETION { NOT } PRESERVE]
[ENABLE | DISABLE]
DO
sentencia_sql;
```
## 5.3 Ejemplos
```sql
-- Ejecutar una vez en el futuro
CREATE EVENT limpiar_logs_antiguos
ON SCHEDULE AT '2026-12-31 23:59:00'
DO DELETE FROM logs WHERE fecha < '2026-01-01';
-- Ejecutar periódicamente
CREATE EVENT backup_diario
ON SCHEDULE EVERY 1 DAY
STARTS '2026-01-01 02:00:00'
ON COMPLETION PRESERVE
DO CALL hacer_backup_diario();
-- Cada hora
CREATE EVENT purgar_sesiones
ON SCHEDULE EVERY 1 HOUR
DO DELETE FROM sesiones WHERE expira < NOW();
```
## 5.4 Gestión de eventos
```sql
SHOW EVENTS; -- Ver eventos
ALTER EVENT backup_diario DISABLE; -- Desactivar
DROP EVENT IF EXISTS backup_diario; -- Eliminar
```
---
# 6. Resumen: conceptos clave para el examen
| Concepto | Dato clave |
|----------|-----------|
| DDL | CREATE, ALTER, DROP define la estructura |
| DML | SELECT, INSERT, UPDATE, DELETE manipula datos |
| DCL | GRANT, REVOKE controla permisos |
| TCL | COMMIT, ROLLBACK, SAVEPOINT gestiona transacciones |
| ACID | Atomicidad, Consistencia, Aislamiento, Durabilidad |
| INNER JOIN | Solo filas que coinciden en ambas tablas |
| LEFT JOIN | Todas las de la izquierda + coincidencias |
| GROUP BY + HAVING | Agrupa filas; HAVING filtra sobre grupos (≠ WHERE) |
| Vista | Consulta guardada como tabla virtual |
| Índice | Acelera consultas; B-Tree es el más común |
| Procedimiento almacenado | Bloque SQL guardado en BD, invocado con CALL |
| Función de usuario | Como procedimiento pero devuelve valor; usable en SELECT |
| Parámetros IN/OUT/INOUT | Entrada / Salida / Bidireccional |
| Trigger BEFORE | Se ejecuta antes; puede cancelar la operación con SIGNAL |
| Trigger AFTER | Se ejecuta después; útil para auditoría |
| NEW / OLD en trigger | Fila nueva (INSERT/UPDATE) / fila antigua (UPDATE/DELETE) |
| Evento (EVENT) | Tarea programada dentro del SGBD (cron job de SQL) |

451
bloque3/tema9.md Normal file
View File

@ -0,0 +1,451 @@
# Bloque 3 · Tema 9
# Repositorios: estructura y actualización. Generación de código y documentación. Metodologías de desarrollo. Pruebas. Programas para control de versiones. Plataformas de desarrollo colaborativo de software.
---
# 1. Esquema introductorio (visión rápida)
**Control de versiones**
→ Sistema que registra los cambios en el código a lo largo del tiempo.
**Tipos de repositorios**
- Locales, centralizados (SVN), distribuidos (Git)
**Metodologías de desarrollo**
- Tradicionales: cascada, espiral
- Ágiles: Scrum, Kanban, XP
**Pruebas de software**
- Unitarias, integración, sistema, aceptación
- Caja blanca vs. caja negra
**Plataformas colaborativas**
- GitHub, GitLab, Bitbucket
---
# 2. Repositorios: concepto y estructura
## 2.1 Qué es un repositorio
Un **repositorio** (*repository* o *repo*) es un almacén centralizado o distribuido donde se guarda el código fuente y el historial de todos los cambios realizados sobre él.
Contiene:
- El **árbol de trabajo** (*working tree*): los archivos actuales.
- El **historial de commits**: cada instantánea del proyecto.
- Las **ramas** (*branches*): líneas de desarrollo paralelas.
- Las **etiquetas** (*tags*): marcas en commits concretos (versiones).
- Los **metadatos** del sistema de control de versiones.
## 2.2 Tipos de repositorios
### Repositorio local
- Existe solo en el equipo del desarrollador.
- Sin colaboración directa.
### Repositorio centralizado (VCS centralizado)
- Un único servidor central almacena el historial.
- Los desarrolladores hacen *checkout* del servidor.
- Ejemplos: **SVN (Subversion)**, CVS.
- Desventaja: punto único de fallo; sin acceso hay sin historial.
### Repositorio distribuido (DVCS)
- Cada desarrollador tiene una copia completa del repositorio (historial incluido).
- Se puede trabajar sin conexión.
- Ejemplos: **Git**, Mercurial.
- Ventaja: redundancia, velocidad, flujos de trabajo flexibles.
## 2.3 Estructura de un repositorio Git
```
proyecto/
├── .git/ ← Directorio oculto con todos los metadatos de Git
│ ├── HEAD ← Apunta a la rama actual
│ ├── config ← Configuración del repositorio
│ ├── objects/ ← Objetos (blobs, trees, commits, tags)
│ ├── refs/
│ │ ├── heads/ ← Ramas locales
│ │ └── tags/ ← Etiquetas
│ └── index ← Área de staging (índice)
├── src/
├── tests/
└── README.md
```
## 2.4 Objetos internos de Git
| Objeto | Descripción |
|--------|-------------|
| **blob** | Contenido de un archivo |
| **tree** | Directorio (lista de blobs y otros trees) |
| **commit** | Instantánea + autor + mensaje + referencia al commit padre |
| **tag** | Referencia con nombre a un commit concreto |
Todos los objetos se identifican por su **hash SHA-1** (40 caracteres hexadecimales).
---
# 3. Control de versiones con Git
## 3.1 Áreas de trabajo en Git
```
Working Directory → Staging Area (index) → Repositorio local → Repositorio remoto
(editar) (git add) (git commit) (git push)
```
| Área | Descripción |
|------|-------------|
| **Working directory** | Archivos que ves y editas |
| **Staging area** | Archivos preparados para el próximo commit |
| **Repositorio local** | Historial de commits almacenado en `.git/` |
| **Repositorio remoto** | Copia en servidor (GitHub, GitLab…) |
## 3.2 Comandos principales de Git
```bash
# Configuración inicial
git config --global user.name "Nombre"
git config --global user.email "email@ejemplo.com"
# Iniciar repositorio
git init # nuevo repo local
git clone URL # clonar repo remoto
# Ciclo básico
git status # ver estado de los archivos
git add archivo.py # añadir al staging
git add . # añadir todo
git commit -m "mensaje" # crear commit
git log --oneline --graph # ver historial
# Ramas
git branch # listar ramas
git branch nueva-rama # crear rama
git checkout nueva-rama # cambiar a rama
git checkout -b nueva-rama # crear y cambiar
git merge otra-rama # fusionar rama
git branch -d rama # eliminar rama
# Repositorio remoto
git remote add origin URL # vincular remoto
git push origin main # subir cambios
git pull origin main # bajar cambios
git fetch origin # descargar sin fusionar
# Etiquetas
git tag v1.0.0 # etiqueta ligera
git tag -a v1.0.0 -m "msg" # etiqueta anotada
git push origin --tags # subir etiquetas
# Deshacer
git revert HASH # crear commit que deshace otro
git reset --soft HEAD~1 # deshacer commit, mantener staging
git reset --hard HEAD~1 # deshacer commit y cambios (¡destructivo!)
git stash # guardar cambios sin commit
git stash pop # recuperar stash
```
## 3.3 Flujos de trabajo (workflows) con Git
### Gitflow
Workflow estructurado con ramas fijas:
- `main` código en producción.
- `develop` integración de features.
- `feature/*` nuevas funcionalidades.
- `release/*` preparación de versión.
- `hotfix/*` correcciones urgentes en producción.
### GitHub Flow / Trunk-Based
- Solo `main` + ramas de feature.
- Pull Request → revisión → merge a main.
- Más sencillo, orientado a despliegue continuo.
### Resolución de conflictos
Ocurre cuando dos ramas modifican las mismas líneas. Git marca el conflicto y el desarrollador debe resolverlo manualmente:
```
<<<<<<< HEAD
código de la rama actual
=======
código de la rama a fusionar
>>>>>>> otra-rama
```
---
# 4. Generación de código y documentación
## 4.1 Generación de código
### Herramientas de generación
| Herramienta | Descripción |
|-------------|-------------|
| **Scaffolding** | Genera estructura básica del proyecto (Rails, Angular CLI, Spring Initializr) |
| **ORM / generadores de mapeo** | Genera clases desde el esquema de BD (Hibernate, Entity Framework) |
| **Generadores de API** | Genera código desde especificación OpenAPI/Swagger |
| **Compiladores / transpiladores** | TypeScript → JavaScript, SASS → CSS |
| **Plantillas (templates)** | Freemarker, Thymeleaf, Mustache |
### Integración Continua (CI) y Entrega Continua (CD)
- **CI (Continuous Integration):** los cambios se integran y construyen automáticamente con cada push.
- **CD (Continuous Delivery):** el software puede desplegarse en cualquier momento.
- **CD (Continuous Deployment):** cada cambio validado se despliega automáticamente.
Herramientas: **Jenkins**, **GitHub Actions**, **GitLab CI/CD**, Travis CI.
## 4.2 Documentación del código
### Javadoc (Java)
```java
/**
* Calcula el área de un círculo.
*
* @param radio El radio del círculo (debe ser positivo).
* @return El área calculada.
* @throws IllegalArgumentException si el radio es negativo.
*/
public double calcularArea(double radio) {
if (radio < 0) throw new IllegalArgumentException("Radio negativo");
return Math.PI * radio * radio;
}
```
### Docstrings (Python)
```python
def calcular_area(radio: float) -> float:
"""
Calcula el área de un círculo.
Args:
radio: El radio del círculo (debe ser positivo).
Returns:
El área calculada.
Raises:
ValueError: Si el radio es negativo.
"""
```
### Herramientas de documentación
| Herramienta | Lenguaje |
|-------------|---------|
| **Javadoc** | Java |
| **Sphinx / pdoc** | Python |
| **JSDoc** | JavaScript |
| **Doxygen** | C, C++, y otros |
| **Swagger / OpenAPI** | APIs REST |
| **ReadTheDocs** | Publicación online |
---
# 5. Metodologías de desarrollo de software
## 5.1 Metodologías tradicionales (predictivas)
### Cascada (Waterfall)
Fases secuenciales, sin retroceso entre ellas:
1. Requisitos → 2. Diseño → 3. Implementación → 4. Pruebas → 5. Despliegue → 6. Mantenimiento
**Ventajas:** simple, bien documentado, adecuado para proyectos estables.
**Inconvenientes:** inflexible ante cambios de requisitos; los errores se descubren tarde.
### Modelo en V
Extiende la cascada asociando cada fase de desarrollo con una fase de pruebas:
- Diseño de sistema ↔ Pruebas de sistema
- Diseño de componentes ↔ Pruebas de integración
- Codificación ↔ Pruebas unitarias
### Modelo en Espiral (Boehm)
Combina iteración con análisis de riesgos en cada ciclo.
Cada espiral: Planificación → Análisis de riesgos → Ingeniería → Evaluación.
### RUP (Rational Unified Process)
- Iterativo e incremental.
- 4 fases: Inicio, Elaboración, Construcción, Transición.
- Usa artefactos UML.
## 5.2 Metodologías ágiles
El **Manifiesto Ágil (2001)** establece 4 valores:
- Individuos e interacciones > procesos y herramientas.
- Software funcionando > documentación exhaustiva.
- Colaboración con el cliente > negociación de contratos.
- Respuesta al cambio > seguir un plan.
### Scrum
| Elemento | Descripción |
|----------|-------------|
| **Sprint** | Iteración de 1-4 semanas con entregable funcional |
| **Product Backlog** | Lista priorizada de funcionalidades |
| **Sprint Backlog** | Tareas del sprint actual |
| **Daily Scrum** | Reunión diaria de 15 min (¿qué hice? ¿qué haré? ¿impedimentos?) |
| **Sprint Review** | Demostración del producto al cliente al final del sprint |
| **Sprint Retrospective** | Mejora del proceso del equipo |
| **Product Owner** | Representa al cliente, prioriza el backlog |
| **Scrum Master** | Facilita el proceso, elimina impedimentos |
| **Development Team** | Equipo autogestionado que desarrolla el producto |
### Kanban
- Visualización del trabajo en un tablero con columnas (Pendiente / En progreso / Hecho).
- Límite de trabajo en curso (WIP limits).
- Flujo continuo sin sprints fijos.
### XP (Extreme Programming)
Prácticas técnicas intensas: **TDD** (Test-Driven Development), **pair programming**, integración continua, refactoring, releases frecuentes.
### Comparativa
| | Cascada | Scrum | Kanban |
|-|---------|-------|--------|
| Plan | Fijo | Iterativo (sprints) | Continuo |
| Cambios | Difíciles | Cada sprint | En cualquier momento |
| Documentación | Extensa | Mínima necesaria | Mínima |
| Adecuado para | Requisitos claros y estables | Proyectos medianos/grandes con cambios | Mantenimiento, flujo continuo |
---
# 6. Pruebas de software
## 6.1 Objetivos de las pruebas
- Detectar defectos (*bugs*).
- Verificar que el software cumple los requisitos.
- Validar que el software satisface las necesidades del usuario.
- Aumentar la confianza en la calidad del producto.
> **Verificación:** ¿estamos construyendo el sistema correctamente?
> **Validación:** ¿estamos construyendo el sistema correcto?
## 6.2 Niveles de prueba
### Pruebas unitarias (Unit Testing)
- Prueban la **unidad mínima de código** (función, método, clase) de forma aislada.
- Se usan mocks/stubs para sustituir dependencias externas.
- Herramientas: **JUnit** (Java), **pytest** (Python), **Jest** (JavaScript).
### Pruebas de integración
- Verifican que varios módulos o componentes funcionan correctamente **juntos**.
- Detectan problemas de interfaz entre módulos.
### Pruebas de sistema
- Prueban el sistema completo como un todo.
- Verifican el comportamiento frente a los requisitos funcionales y no funcionales.
### Pruebas de aceptación (UAT)
- Realizadas por el usuario final o cliente.
- Confirman que el sistema cumple los requisitos del negocio.
- Criterio de **DoD** (Definition of Done).
## 6.3 Técnicas de prueba
### Caja negra (Black-box)
- No se conoce (o no importa) la implementación interna.
- Se prueba la **funcionalidad**: entradas → salidas esperadas.
- Técnicas: particiones de equivalencia, valores límite, tablas de decisión.
### Caja blanca (White-box / Glass-box)
- Se conoce y analiza el código fuente interno.
- Se persigue cubrir el máximo de rutas del código.
- Métricas: **cobertura de líneas**, **cobertura de ramas**, **cobertura de caminos**.
- Técnicas: recorrido de código, análisis de flujo de control.
### Caja gris (Grey-box)
- Combinación de las dos anteriores.
## 6.4 Tipos de pruebas por objetivo
| Tipo | Qué verifica |
|------|-------------|
| **Pruebas de regresión** | Que los cambios nuevos no rompen funcionalidad existente |
| **Pruebas de rendimiento / carga** | Comportamiento bajo condiciones de estrés |
| **Pruebas de seguridad (Pen Testing)** | Vulnerabilidades explotables |
| **Pruebas de usabilidad** | Facilidad de uso para el usuario |
| **Pruebas de accesibilidad** | Cumplimiento de estándares WCAG |
| **Smoke testing** | Verificación rápida de las funciones básicas |
| **Pruebas de humo / regresión automatizadas** | CI/CD pipeline |
## 6.5 TDD Test Driven Development
Ciclo **Red → Green → Refactor**:
1. **Red:** escribir un test que falle (la funcionalidad no existe aún).
2. **Green:** escribir el código mínimo para que el test pase.
3. **Refactor:** mejorar el código sin romper los tests.
**Ventajas:** código más simple, mejor diseño, alta cobertura de tests, documentación viva.
---
# 7. Plataformas de desarrollo colaborativo
## 7.1 GitHub
- Mayor plataforma de alojamiento de código Git basada en la web.
- **Pull Request (PR):** propuesta de cambios para revisión antes de mergear.
- **Issues:** gestión de tareas, bugs y mejoras.
- **GitHub Actions:** CI/CD integrado.
- **GitHub Pages:** alojamiento de sitios estáticos.
- **GitHub Copilot:** asistente de código basado en IA.
- Propiedad de Microsoft (desde 2018).
## 7.2 GitLab
- Alternativa a GitHub, disponible también como instalación **on-premise**.
- Incluye CI/CD integrado muy completo.
- **GitLab CI/CD Pipelines** con fichero `.gitlab-ci.yml`.
- Gestión de proyectos, wikis, registros de contenedores Docker.
- Muy usado en la Administración Pública y entornos corporativos.
## 7.3 Bitbucket
- Propiedad de **Atlassian** (misma empresa que Jira y Confluence).
- Integración nativa con Jira para gestión de proyectos.
- Compatible con Git y Mercurial (Mercurial fue descontinuado en 2020).
- Muy usado en entornos empresariales con ecosistema Atlassian.
## 7.4 Otras herramientas
| Herramienta | Tipo | Descripción |
|-------------|------|-------------|
| **Jira** | Gestión de proyectos | Seguimiento de tareas, sprints, backlog |
| **Confluence** | Documentación | Wiki corporativa |
| **SonarQube** | Calidad de código | Análisis estático, detección de code smells |
| **Jenkins** | CI/CD | Servidor de automatización open-source |
| **Docker Hub** | Registro de contenedores | Imágenes Docker públicas y privadas |
| **Nexus / Artifactory** | Repositorios de artefactos | Maven, npm, Docker |
## 7.5 Funcionalidades colaborativas clave
| Función | Descripción |
|---------|-------------|
| **Fork** | Copia independiente de un repositorio en tu cuenta |
| **Pull Request / Merge Request** | Solicitud para integrar cambios tras revisión |
| **Code review** | Revisión del código por otro desarrollador antes de mergear |
| **Branch protection** | Impide push directo a ramas protegidas (ej. main) |
| **Webhooks** | Notificaciones automáticas a servicios externos en cada evento |
| **Wiki** | Documentación del proyecto integrada en la plataforma |
---
# 8. Resumen: conceptos clave para el examen
| Concepto | Dato clave |
|----------|-----------|
| DVCS | Sistema de control de versiones distribuido; cada clon tiene el historial completo |
| Git | DVCS más usado; crea repositorios con `.git/` |
| Commit | Instantánea del proyecto identificada por hash SHA-1 |
| Branch | Línea de desarrollo paralela; `main` es la rama principal |
| Merge | Fusión de dos ramas |
| Gitflow | Rama main + develop + feature/* + release/* + hotfix/* |
| CI/CD | Integración y entrega/despliegue continuo (Jenkins, GitHub Actions…) |
| Cascada | Fases secuenciales, sin retroceso |
| Scrum | Sprints, Product Owner, Scrum Master, Daily, Review, Retrospective |
| Kanban | Tablero visual, límites WIP, flujo continuo |
| TDD | Test → Código → Refactor (Red → Green → Refactor) |
| Prueba unitaria | Prueba la unidad mínima de forma aislada |
| Prueba de integración | Prueba varios módulos juntos |
| Prueba de aceptación (UAT) | La realiza el usuario final |
| Caja negra | Prueba funcionalidad sin ver el código |
| Caja blanca | Prueba conociendo la implementación interna |
| Pull Request | Propuesta de cambios para revisión antes de mergear |
| GitHub / GitLab / Bitbucket | Principales plataformas de desarrollo colaborativo |
| SonarQube | Análisis estático de calidad del código |

403
bloque4/tema10.md Normal file
View File

@ -0,0 +1,403 @@
# Bloque 4 · Tema 10
# Redes locales. Tipología. Técnicas de transmisión. Métodos de acceso. Dispositivos de interconexión.
---
# 1. Esquema introductorio (visión rápida)
**LAN (Local Area Network):** red de comunicaciones de corto alcance (edificio o campus).
**Topologías físicas:** bus, estrella, anillo, malla, árbol.
**Topologías lógicas:** bus (CSMA/CD), anillo de token.
**Técnicas de transmisión:**
- Banda base (baseband): señal digital sobre todo el ancho de banda del medio.
- Banda ancha (broadband): múltiples canales sobre el ancho de banda.
**Métodos de acceso al medio:**
- **CSMA/CD (Ethernet):** detecta colisiones.
- **CSMA/CA (Wi-Fi):** evita colisiones.
- **Token Ring:** turno garantizado.
**Dispositivos:** repetidor, hub, bridge, switch, router, gateway.
---
# 2. Redes de área local (LAN) Concepto y clasificación
## 2.1 Definición
Una **LAN (Local Area Network)** es una red de comunicaciones que cubre un área geográfica limitada (habitación, edificio, campus). Se caracteriza por:
- Alta velocidad de transmisión (100 Mbps 100 Gbps).
- Baja tasa de errores.
- Propiedad privada (la organización es dueña de la infraestructura).
- Tecnologías predominantes: **Ethernet** (IEEE 802.3) y **Wi-Fi** (IEEE 802.11).
## 2.2 Clasificación por extensión
| Tipo | Cobertura | Velocidad típica | Ejemplo |
|------|-----------|-----------------|---------|
| **PAN** | ~10 m | 1-100 Mbps | Bluetooth, USB |
| **LAN** | Edificio/campus | 100 Mbps 100 Gbps | Ethernet, Wi-Fi |
| **MAN** | Ciudad | 10 Mbps 10 Gbps | Metro Ethernet, WiMAX |
| **WAN** | País/internacional | Variable | Internet, MPLS |
---
# 3. Topologías de red
La **topología** describe la estructura física o lógica de cómo están interconectados los nodos.
## 3.1 Topología en bus
```
[PC1]---[PC2]---[PC3]---[PC4]
←── Cable coaxial ──→
(terminadores en extremos)
```
- Todos los nodos comparten el mismo medio de transmisión.
- Las señales se propagan en ambos sentidos.
- **Terminadores:** impiden las reflexiones en los extremos del cable.
- **Ventaja:** sencilla y económica.
- **Desventaja:** un corte en el cable inutiliza toda la red; colisiones frecuentes; difícil diagnóstico.
- Ejemplo: Ethernet 10BASE2 (coaxial delgado), 10BASE5 (grueso).
## 3.2 Topología en estrella
```
[PC1]
|
[PC2]--[SWITCH]--[PC3]
|
[PC4]
```
- Todos los nodos se conectan a un **nodo central** (switch, hub).
- **Ventaja:** fallo de un nodo no afecta al resto; fácil diagnóstico; sencillo de ampliar.
- **Desventaja:** el nodo central es **punto único de fallo**; coste del cableado a cada nodo.
- **La topología más utilizada en LAN modernas** (con switches).
## 3.3 Topología en anillo
```
[PC1] → [PC2] → [PC3] → [PC4] → [PC1]
```
- Los nodos forman un círculo; los datos circulan en un sentido (o en ambos en anillos duales).
- Acceso al medio: **Token Ring (IEEE 802.5)** o **FDDI**.
- **Ventaja:** predecible; no hay colisiones (acceso ordenado por token).
- **Desventaja:** un fallo en el anillo interrumpe la red; en desuso frente a Ethernet.
## 3.4 Topología en malla
- Cada nodo está conectado directamente a todos los demás nodos (malla completa) o a varios (malla parcial).
- **Ventaja:** muy alta redundancia y tolerancia a fallos.
- **Desventaja:** coste muy elevado en cables y puertos.
- Uso: redes de backbone críticas, Internet (malla parcial).
## 3.5 Topología en árbol (jerárquica)
```
[Core Switch]
/ \
[Distrib SW] [Distrib SW]
/ \ / \
[Access] [Access] [Access] [Access]
```
- Jerarquía de nodos en tres niveles: **core, distribución, acceso**.
- La más usada en redes corporativas (arquitectura de tres capas).
- **Ventaja:** escalable y fácil de gestionar.
- **Desventaja:** dependencia de los nodos superiores.
## 3.6 Topología lógica vs física
| Tipo | Descripción |
|------|-------------|
| **Topología física** | Cómo están conectados físicamente los cables y dispositivos |
| **Topología lógica** | Cómo fluye la información lógicamente en la red |
Ejemplo: Ethernet moderno tiene **topología física en estrella** (con switch) pero **topología lógica de bus** (todos comparten el dominio de broadcast).
---
# 4. Técnicas de transmisión
## 4.1 Banda base (Baseband)
- La señal digital ocupa **todo el ancho de banda** del medio.
- Solo se puede transmitir una señal a la vez.
- Codificación típica: **Manchester** (combinación de señal de reloj y datos).
- Ejemplo: **Ethernet (10BASE-T, 100BASE-TX)**.
- Es la técnica estándar en LAN.
## 4.2 Banda ancha (Broadband)
- El ancho de banda del medio se divide en **múltiples canales** de frecuencia (multiplexación por frecuencia, FDM).
- Cada canal puede llevar una señal diferente.
- Ejemplo: **ADSL, cable coaxial (TV por cable), DOCSIS**.
- En LAN se usa excepcionalmente (ej. 10BROAD36, obsoleto).
## 4.3 Comparativa
| Característica | Banda base | Banda ancha |
|---------------|-----------|------------|
| Señal | Digital | Analógica (modulada) |
| Canales | Uno | Varios |
| Distancia | Corta (LAN) | Larga (WAN/MAN) |
| Uso en LAN | Sí (estándar) | Excepcional |
## 4.4 Codificación de la señal
| Codificación | Descripción | Uso |
|-------------|-------------|-----|
| **NRZ (Non-Return to Zero)** | 1 = voltaje alto, 0 = voltaje bajo; no tiene señal de reloj integrada | Básica |
| **Manchester** | Transición a mitad del bit (↑ = 1, ↓ = 0); reloj auto-sincronizado | 10BASE-T Ethernet |
| **Manchester diferencial** | La transición indica el bit; más robusto al ruido | Token Ring |
| **4B5B / 8B10B** | Bloques de código; balance DC y sincronización | Fast Ethernet, Gigabit Ethernet |
| **PAM-4** | 4 niveles de amplitud por símbolo; dobla la tasa | 25G/400G Ethernet |
---
# 5. Métodos de acceso al medio
El **método de acceso al medio (MAC Medium Access Control)** controla cómo los nodos comparten el medio de transmisión para evitar o resolver colisiones.
## 5.1 CSMA/CD Carrier Sense Multiple Access with Collision Detection
**Usado en: Ethernet (IEEE 802.3) en topología de bus o con hub.**
Algoritmo:
1. **Carrier Sense (CS):** el nodo escucha el medio antes de transmitir.
2. **Multiple Access (MA):** varios nodos pueden transmitir si el medio está libre.
3. Si dos nodos transmiten a la vez → **colisión**.
4. **Collision Detection (CD):** los nodos detectan la colisión.
5. Se envía una señal **jam** para notificar la colisión a todos.
6. Cada nodo espera un tiempo aleatorio (**backoff exponencial binario**) y reintenta.
**Nota importante:** con switches modernos (full-duplex), no hay colisiones → CSMA/CD ya no es relevante en redes actuales, pero se sigue estudiando como concepto.
## 5.2 CSMA/CA Carrier Sense Multiple Access with Collision Avoidance
**Usado en: Wi-Fi (IEEE 802.11).**
- En inalámbrico, una estación no puede detectar colisiones mientras transmite (no oye su propia señal reflejada).
- En lugar de detectar, intenta **evitar** las colisiones.
- Mecanismo: **DIFS + espera aleatoria (ventana de contención)** antes de transmitir.
- **ACK obligatorio:** el receptor confirma la recepción de cada trama.
- Variante: **RTS/CTS (Request to Send / Clear to Send)** para evitar el problema del nodo oculto.
### Problema del nodo oculto
Dos estaciones (A y C) no se "escuchan" entre sí pero ambas pueden comunicarse con B.
Si A y C transmiten simultáneamente a B → colisión en B sin que A ni C la detecten.
Solución: **RTS/CTS**.
## 5.3 Token Ring (IEEE 802.5)
- Un **token** (ficha) circula por el anillo.
- Solo el nodo que tiene el token puede transmitir.
- Acceso **determinista**: sin colisiones; latencia predecible.
- Velocidades: 4 Mbps y 16 Mbps.
- **Obsoleto**; reemplazado por Ethernet switched.
## 5.4 FDDI (Fiber Distributed Data Interface)
- Anillo dual de fibra óptica a **100 Mbps**.
- Acceso por token; tolerante a fallos (anillo secundario de backup).
- Usado en MAN y backbone en los 90.
- **Obsoleto**; reemplazado por Fast/Gigabit Ethernet y fibra.
## 5.5 Comparativa de métodos de acceso
| Método | Tecnología | Tipo | Colisiones | Determinista |
|--------|-----------|------|-----------|-------------|
| **CSMA/CD** | Ethernet legacy | Contención | Detecta y recupera | No |
| **CSMA/CA** | Wi-Fi | Contención | Evita | No |
| **Token Ring** | IEEE 802.5 | Turno | Sin colisiones | Sí |
| **FDDI** | Fibra FDDI | Turno (token) | Sin colisiones | Sí |
| **Full-duplex Ethernet** | Ethernet moderno | Conmutación | Sin colisiones | No (pero muy baja latencia) |
---
# 6. Ethernet El estándar de LAN
## 6.1 Historia y evolución
| Versión | Velocidad | Medio | Estándar |
|---------|-----------|-------|---------|
| **10BASE5** | 10 Mbps | Coaxial grueso | IEEE 802.3 (1983) |
| **10BASE2** | 10 Mbps | Coaxial delgado | IEEE 802.3a |
| **10BASE-T** | 10 Mbps | Par trenzado UTP Cat3 | IEEE 802.3i (1990) |
| **100BASE-TX** | 100 Mbps | UTP Cat5 | IEEE 802.3u (1995) Fast Ethernet |
| **1000BASE-T** | 1 Gbps | UTP Cat5e | IEEE 802.3ab (1999) Gigabit Ethernet |
| **10GBASE-T** | 10 Gbps | UTP Cat6A | IEEE 802.3an (2006) |
| **10GBASE-SR/LR** | 10 Gbps | Fibra | IEEE 802.3ae |
| **40/100GBASE** | 40/100 Gbps | Fibra | IEEE 802.3ba (2010) |
| **400GBASE** | 400 Gbps | Fibra | IEEE 802.3bs (2017) |
La nomenclatura `VelocidadBASE-Tipo` sigue el patrón:
- **Velocidad** en Mbps o Gbps.
- **BASE** = banda base.
- **Tipo:** T = par trenzado, S = fibra multimodo (short), L = fibra monomodo (long), X = codificación especial.
## 6.2 Trama Ethernet (IEEE 802.3)
```
| Preámbulo | SFD | MAC Dst | MAC Src | EtherType/Longitud | Datos (payload) | FCS |
| 7 bytes | 1 B | 6 bytes | 6 bytes | 2 bytes | 46-1500 bytes | 4 B |
```
- **Preámbulo:** sincronización del receptor (patrón 10101010...).
- **SFD (Start Frame Delimiter):** indica el inicio de la trama (10101011).
- **MAC Dst / Src:** direcciones físicas (48 bits / 6 bytes) en notación hexadecimal.
- **EtherType:** indica el protocolo de capa superior (0x0800 = IPv4, 0x0806 = ARP, 0x86DD = IPv6).
- **FCS (Frame Check Sequence):** CRC para detección de errores.
**MTU:** 1500 bytes (payload máximo).
**Tamaño mínimo de trama:** 64 bytes (para que CSMA/CD funcione correctamente).
## 6.3 Dirección MAC
- **48 bits** (6 bytes) = 12 dígitos hexadecimales (ej. `00:1A:2B:3C:4D:5E`).
- Los primeros 24 bits: **OUI (Organizationally Unique Identifier)** → identifica al fabricante.
- Los últimos 24 bits: asignados por el fabricante (número de serie).
- **Dirección broadcast:** `FF:FF:FF:FF:FF:FF` (enviada a todos los nodos).
- **Dirección multicast:** bit LSB del primer byte = 1.
## 6.4 VLANs (IEEE 802.1Q)
Una **VLAN (Virtual LAN)** segmenta una LAN física en múltiples LANs virtuales independientes.
```
[SWITCH]
/ | \
VLAN10 VLAN20 VLAN30
(Ventas) (IT) (RRHH)
```
- Los dispositivos de distintas VLANs no pueden comunicarse directamente sin un **router o switch L3**.
- **Puerto de acceso (access):** asignado a una VLAN; el switch agrega la etiqueta 802.1Q internamente.
- **Puerto troncal (trunk):** transporta tráfico de múltiples VLANs; la etiqueta 802.1Q viaja en los frames.
- **VLAN tag (802.1Q):** 4 bytes adicionales en la trama Ethernet con el ID de VLAN (VID, 12 bits → hasta 4094 VLANs).
**Ventajas:**
- Segmentación de tráfico → mayor seguridad.
- Reducción del dominio de broadcast.
- Flexibilidad: agrupación lógica sin cambios físicos.
---
# 7. Dispositivos de interconexión
## 7.1 Repetidor (capa 1)
- Regenera la señal digital para extender el alcance del cable.
- No filtra ni procesa: transmite todos los bits.
- Extiende el dominio de colisión.
- Prácticamente en desuso (sustituido por switches).
## 7.2 Hub (concentrador capa 1)
- Conecta múltiples dispositivos en topología estrella.
- Funciona como repetidor multipuerto: retransmite a todos los puertos.
- Un único dominio de colisión y broadcast para todos los nodos.
- **Obsoleto**; sustituido por switches.
## 7.3 Bridge (puente capa 2)
- Conecta dos segmentos de red.
- Aprende direcciones MAC de cada segmento.
- Filtra el tráfico: solo retransmite tramas al segmento donde está el destino.
- Separa dominios de colisión (pero no de broadcast).
- **STP (Spanning Tree Protocol IEEE 802.1D):** evita bucles lógicos en redes con múltiples bridges.
## 7.4 Switch (conmutador capa 2)
El switch es el dispositivo central de las LAN modernas.
**Funcionamiento:**
1. Cuando llega una trama, el switch aprende la MAC origen y el puerto de entrada.
2. Busca la MAC destino en su **tabla CAM (Content Addressable Memory)**.
3. Si encuentra la entrada → envía la trama solo por ese puerto (**unicast**).
4. Si no la encuentra → **flooding** (envía por todos los puertos excepto el de entrada).
5. Broadcasts y multicasts → envía por todos los puertos.
**Modos de conmutación:**
| Modo | Descripción | Latencia | Errores |
|------|-------------|----------|---------|
| **Store-and-Forward** | Almacena la trama completa, verifica FCS antes de reenviar | Mayor | Filtra errores |
| **Cut-Through** | Empieza a reenviar en cuanto lee la MAC destino | Menor | No filtra errores |
| **Fragment-Free** | Lee los primeros 64 bytes (detecta fragmentos de colisión) | Media | Parcial |
**Switch capa 3:**
- Añade capacidad de enrutamiento IP al switch.
- Enrutamiento inter-VLAN sin necesidad de router externo.
- Más rápido que un router para el tráfico interno (enrutamiento hardware).
### STP Spanning Tree Protocol (IEEE 802.1D)
Evita **bucles físicos** en redes con enlaces redundantes entre switches.
- Se elige un **Root Bridge** (switch raíz).
- Se calculan los caminos más cortos al Root Bridge.
- Los puertos redundantes quedan en estado **blocking** (bloqueados).
- Si el camino activo falla → STP reconverge y activa el camino bloqueado.
- **RSTP (IEEE 802.1w):** Rapid STP; converge en milisegundos (vs 30-50 s del STP original).
- **MSTP (IEEE 802.1s):** Multiple STP; instancias STP por VLAN.
## 7.5 Router (encaminador capa 3)
- Conecta redes diferentes (distintas subredes IP).
- Toma decisiones de enrutamiento basadas en la dirección **IP destino**.
- **Tabla de enrutamiento:** lista de redes conocidas con el siguiente salto.
- Separa dominios de broadcast.
## 7.6 Gateway (pasarela)
- Traduce entre protocolos de redes heterogéneas.
- Opera en todas las capas (hasta capa 7).
- Ejemplo: gateway entre red IP y red ATM.
## 7.7 Resumen comparativo
| Dispositivo | Capa OSI | Dirección usada | Dom. colisión | Dom. broadcast | Inteligencia |
|-------------|---------|----------------|--------------|----------------|-------------|
| Repetidor | 1 | — | Extende | — | Ninguna |
| Hub | 1 | — | Único | Único | Ninguna |
| Bridge | 2 | MAC | Separa | Único | Tabla MAC |
| Switch | 2 (o 3) | MAC (o IP) | Separa | Único (o VLAN) | Tabla CAM |
| Router | 3 | IP | Separa | Separa | Tabla enrutamiento |
| Gateway | 1-7 | Todas | — | — | Protocolo app |
---
# 8. Resumen: conceptos clave para el examen
| Concepto | Dato clave |
|----------|-----------|
| LAN | Red local; alta velocidad; propiedad privada |
| Topología estrella | La más común en LAN; nodo central = switch |
| Topología bus | Cable coaxial compartido; terminadores; colisiones |
| Topología anillo | Token circulante; IEEE 802.5; obsoleto |
| Banda base | Señal digital; todo el ancho de banda; Ethernet |
| Banda ancha | Múltiples canales FDM; ADSL, cable coaxial |
| Codificación Manchester | Transición a mitad del bit; 10BASE-T Ethernet |
| CSMA/CD | Ethernet legacy; detecta colisiones; backoff exponencial |
| CSMA/CA | Wi-Fi; evita colisiones; DIFS + ventana aleatoria |
| Token Ring | Acceso determinista; sin colisiones; IEEE 802.5 |
| Trama Ethernet | Preámbulo+SFD+MAC dst+MAC src+EtherType+Datos+FCS |
| MAC | 48 bits (6 bytes); OUI (24 bits fabricante) |
| Broadcast MAC | FF:FF:FF:FF:FF:FF |
| MTU Ethernet | 1500 bytes |
| VLAN (IEEE 802.1Q) | Hasta 4094 VLANs; tag de 4 bytes; trunk/access |
| Switch tabla CAM | Aprende MACs; unicast, flooding, broadcast |
| Store-and-Forward | Almacena y verifica FCS; filtra errores |
| Cut-Through | Reenvía leyendo solo MAC destino; menor latencia |
| STP (IEEE 802.1D) | Evita bucles; Root Bridge; puertos blocking |
| RSTP (IEEE 802.1w) | STP rápido; converge en milisegundos |
| Switch L3 | Enrutamiento inter-VLAN sin router externo |
| Router | Capa 3; separa dominios broadcast; tabla enrutamiento |
| 100BASE-TX | Fast Ethernet; 100 Mbps; UTP Cat5; IEEE 802.3u |
| 1000BASE-T | Gigabit Ethernet; 1 Gbps; UTP Cat5e; IEEE 802.3ab |

469
bloque4/tema5.md Normal file
View File

@ -0,0 +1,469 @@
# Bloque 4 · Tema 5
# Conceptos de seguridad de los sistemas de información. Seguridad física. Seguridad lógica. Amenazas y vulnerabilidades. Técnicas criptográficas y protocolos seguros. Mecanismos de firma digital. Infraestructura física de un CPD: acondicionamiento y equipamiento. Sistemas de gestión de incidencias. Control remoto de puestos de usuario.
---
# 1. Esquema introductorio (visión rápida)
**Seguridad de la información tríada CIA**
- **Confidencialidad:** solo acceden los autorizados.
- **Integridad:** la información no se altera sin autorización.
- **Disponibilidad:** el sistema está accesible cuando se necesita.
**Tipos de seguridad**
- Física: protección del hardware y las instalaciones.
- Lógica: protección del software, datos y accesos.
**Criptografía**
- Simétrica (clave única): AES, DES, 3DES.
- Asimétrica (clave pública/privada): RSA, ECC.
- Hash: SHA-256, MD5 (obsoleta).
- Firma digital: autenticidad + integridad + no repudio.
---
# 2. Conceptos fundamentales de seguridad
## 2.1 Tríada CIA
| Propiedad | Descripción | Medidas |
|-----------|-------------|---------|
| **Confidencialidad** | Solo los autorizados pueden acceder a la información | Cifrado, control de acceso, VPN |
| **Integridad** | La información no es alterada sin autorización | Hash, firmas digitales, checksums |
| **Disponibilidad** | El sistema funciona y da servicio cuando se necesita | Redundancia, backups, monitorización |
## 2.2 Otras propiedades de seguridad
| Propiedad | Descripción |
|-----------|-------------|
| **Autenticidad** | Se puede verificar la identidad del emisor |
| **No repudio** | El emisor no puede negar haber enviado un mensaje |
| **Trazabilidad / Auditoría** | Se registra quién hizo qué y cuándo |
| **Control de acceso** | Se gestiona quién puede acceder a qué recursos |
## 2.3 Amenazas, vulnerabilidades y riesgos
| Concepto | Definición |
|----------|-----------|
| **Amenaza** | Evento que puede causar daño (ataque, catástrofe, error humano) |
| **Vulnerabilidad** | Debilidad del sistema que puede ser explotada |
| **Riesgo** | Probabilidad × Impacto de que una amenaza explote una vulnerabilidad |
| **Impacto** | Consecuencia del incidente (económica, reputacional, operacional) |
| **Contramedida** | Acción que reduce el riesgo |
## 2.4 Tipos de amenazas
### Amenazas externas
- **Malware:** virus, gusanos (*worms*), troyanos, ransomware, spyware, rootkits.
- **Ataques de red:** DoS/DDoS, Man-in-the-Middle (MitM), spoofing, sniffing.
- **Intrusión:** acceso no autorizado a sistemas.
- **Ingeniería social:** phishing, vishing, pretexting.
### Amenazas internas
- Empleados malintencionados.
- Errores humanos.
- Privilegios excesivos.
### Amenazas físicas
- Incendio, inundación, seísmo.
- Robo de equipos.
- Corte eléctrico.
## 2.5 OWASP Top 10 (principales vulnerabilidades web)
Las 10 vulnerabilidades de aplicaciones web más críticas, publicadas por OWASP:
1. Control de acceso roto.
2. Fallos criptográficos.
3. Inyección (SQL, XSS, command injection).
4. Diseño inseguro.
5. Mala configuración de seguridad.
6. Componentes vulnerables y desactualizados.
7. Fallos de identificación y autenticación.
8. Fallos en la integridad del software y los datos.
9. Fallos en el registro y monitorización de seguridad.
10. Server-Side Request Forgery (SSRF).
---
# 3. Seguridad física
La **seguridad física** protege el hardware, las instalaciones y las personas frente a amenazas físicas.
## 3.1 Control de acceso físico
- **Perímetro de seguridad:** vallas, muros, control de acceso al edificio.
- **Control de acceso a las instalaciones:** tarjetas de proximidad, biometría (huella, iris, facial), guardias de seguridad.
- **Zonas de seguridad:** recepción, zona de trabajo, CPD (sala de servidores).
- **CCTV:** videovigilancia con cámaras de seguridad.
- **Registro de visitas:** quién entra y sale, y cuándo.
## 3.2 Protección contra desastres físicos
### Incendios
- Detectores de humo y temperatura.
- Sistemas de extinción: **agente limpio** (gases inertes como FM-200, Novec) en CPD para no dañar los equipos; evitar agua o polvo.
- Separación de zonas (cortafuegos físicos).
### Suministro eléctrico
- **SAI / UPS (Sistema de Alimentación Ininterrumpida):** batería que mantiene el sistema en marcha ante cortes breves.
- **Grupos electrógenos (generadores):** energía de emergencia para cortes prolongados.
- **Redundancia de suministro:** conexiones a distintas subestaciones eléctricas.
- **PDU redundantes:** distribución de energía dentro del CPD.
### Temperatura y humedad
- **Sistemas HVAC:** climatización (aire acondicionado de precisión).
- **Temperatura recomendada en CPD:** 18-27°C; humedad relativa 40-60%.
- Monitorización continua de temperatura y humedad.
### Otros riesgos físicos
- Protección frente a inundaciones (drenaje, ubicación elevada).
- Protección antisísmica.
- Protección frente a interferencias electromagnéticas (jaula de Faraday).
---
# 4. Seguridad lógica
La **seguridad lógica** protege los sistemas de información frente al acceso, alteración o destrucción no autorizados a través de medios electrónicos.
## 4.1 Control de acceso lógico
### Identificación y autenticación
| Factor | Descripción | Ejemplo |
|--------|-------------|---------|
| **Algo que sabes** | Contraseña, PIN, pregunta secreta | Password |
| **Algo que tienes** | Token físico, tarjeta inteligente, OTP | DNIe, Google Authenticator |
| **Algo que eres** | Biometría | Huella dactilar, reconocimiento facial |
**MFA (Autenticación Multifactor):** combina al menos dos factores distintos.
**2FA:** caso particular con exactamente dos factores.
### Modelos de control de acceso
| Modelo | Descripción |
|--------|-------------|
| **DAC (Discretionary Access Control)** | El propietario del recurso decide quién accede (ej. permisos UNIX) |
| **MAC (Mandatory Access Control)** | El sistema impone reglas según etiquetas de seguridad (clasificada/secreta) |
| **RBAC (Role-Based Access Control)** | Los permisos se asignan a roles; los usuarios tienen roles |
| **ABAC (Attribute-Based Access Control)** | Acceso basado en atributos del usuario, recurso y entorno |
**Principio de mínimo privilegio:** cada usuario/servicio solo tiene los permisos estrictamente necesarios.
## 4.2 Gestión de contraseñas
Buenas prácticas:
- Longitud mínima de 12 caracteres.
- Combinación de mayúsculas, minúsculas, números y caracteres especiales.
- No reutilizar contraseñas.
- **No almacenar contraseñas en texto claro** → usar funciones de hash con sal (*salt*): bcrypt, Argon2, PBKDF2.
- Política de caducidad y bloqueo tras intentos fallidos.
## 4.3 Antivirus y protección contra malware
- Software que detecta, bloquea y elimina código malicioso.
- Técnicas: firmas, heurística, análisis de comportamiento (sandbox).
- Soluciones actuales: **EDR (Endpoint Detection and Response)**.
## 4.4 Firewall (cortafuegos)
Filtra el tráfico de red basándose en reglas (IP, puerto, protocolo).
| Tipo | Descripción |
|------|-------------|
| **Filtrado de paquetes** | Reglas por IP de origen/destino y puerto |
| **Stateful inspection** | Rastrea el estado de las conexiones |
| **Proxy / Application-level gateway** | Intermediario que entiende el protocolo de aplicación |
| **NGFW (Next-Generation Firewall)** | Inspección profunda de paquetes, IDS/IPS integrado, control por aplicación |
## 4.5 IDS/IPS
| Sistema | Función |
|---------|---------|
| **IDS** (Intrusion Detection System) | Detecta y **alerta** sobre intrusiones |
| **IPS** (Intrusion Prevention System) | Detecta **y bloquea** las intrusiones en tiempo real |
Técnicas de detección:
- **Basada en firmas:** compara con patrones de ataques conocidos.
- **Basada en anomalías:** detecta desvíos del comportamiento normal.
---
# 5. Técnicas criptográficas y protocolos seguros
## 5.1 Criptografía simétrica
Utiliza la **misma clave** para cifrar y descifrar.
**Ventaja:** muy rápida.
**Inconveniente:** problema de distribución de claves (¿cómo compartir la clave de forma segura?).
| Algoritmo | Estado | Descripción |
|-----------|--------|-------------|
| **DES** | Obsoleto | 56 bits de clave; vulnerable a fuerza bruta |
| **3DES** | En desuso | Aplica DES tres veces; más lento y debilitándose |
| **AES** | Estándar actual | Claves de 128, 192 o 256 bits; muy eficiente |
| **ChaCha20** | Moderno | Alternativa a AES en dispositivos sin hardware AES |
Modos de operación de AES: ECB, CBC, CTR, GCM (autenticado; el más recomendado).
## 5.2 Criptografía asimétrica (de clave pública)
Utiliza un **par de claves**:
- **Clave pública:** se distribuye libremente; cifra datos o verifica firmas.
- **Clave privada:** se guarda en secreto; descifra datos o genera firmas.
**Lo que cifra la clave pública solo lo descifra la clave privada (y viceversa).**
**Ventaja:** no hay problema de distribución de claves.
**Inconveniente:** mucho más lenta que la simétrica.
| Algoritmo | Uso | Notas |
|-----------|-----|-------|
| **RSA** | Cifrado y firma | Clave de 2048+ bits recomendada |
| **DSA** | Solo firma digital | |
| **ECDSA / ECC** | Firma y cifrado | Clave más corta con igual seguridad que RSA |
| **Diffie-Hellman (DH)** | Intercambio de claves | No cifra datos, acuerda clave simétrica entre dos extremos |
**Uso híbrido (habitual):** la clave de cifrado simétrico (sesión) se intercambia con criptografía asimétrica → TLS, PGP.
## 5.3 Funciones hash criptográficas
Transforman una entrada de cualquier longitud en una **cadena de longitud fija** (resumen o *digest*).
Propiedades:
- **Deterministas:** misma entrada → mismo hash.
- **Unidireccionales:** imposible obtener la entrada a partir del hash.
- **Resistencia a colisiones:** muy difícil encontrar dos entradas con el mismo hash.
- **Efecto avalancha:** un pequeño cambio en la entrada cambia completamente el hash.
| Algoritmo | Longitud del hash | Estado |
|-----------|------------------|--------|
| **MD5** | 128 bits | Obsoleto (colisiones conocidas) |
| **SHA-1** | 160 bits | Obsoleto (colisiones demostradas) |
| **SHA-256** | 256 bits | **Estándar actual** (familia SHA-2) |
| **SHA-3** | Variable | Más reciente, basado en Keccak |
**Usos:** verificar integridad de archivos, almacenar contraseñas (con salt), firma digital.
## 5.4 Firma digital
La **firma digital** garantiza simultáneamente:
- **Autenticidad:** el mensaje proviene realmente del firmante.
- **Integridad:** el mensaje no ha sido modificado.
- **No repudio:** el firmante no puede negar haber firmado.
### Proceso de firma y verificación
```
FIRMA:
1. Calcular el hash del mensaje (e.g. SHA-256)
2. Cifrar el hash con la CLAVE PRIVADA del firmante
→ Resultado: firma digital
VERIFICACIÓN:
1. Descifrar la firma con la CLAVE PÚBLICA del firmante → hash original
2. Calcular el hash del mensaje recibido
3. Comparar ambos hashes → si son iguales, firma válida
```
## 5.5 Certificados digitales y PKI
Un **certificado digital** vincula una clave pública con la identidad de su propietario, avalado por una **Autoridad de Certificación (CA)**.
Estándar: **X.509**.
### PKI (Public Key Infrastructure)
Infraestructura que gestiona certificados digitales:
- **CA (Certification Authority):** emite y firma certificados.
- **RA (Registration Authority):** verifica la identidad del solicitante.
- **CRL (Certificate Revocation List):** lista de certificados revocados.
- **OCSP (Online Certificate Status Protocol):** verificación en tiempo real del estado del certificado.
### En España
- **FNMT-RCM:** Fábrica Nacional de Moneda y Timbre → emite certificados a ciudadanos.
- **DNIe:** chip criptográfico con certificado de identidad y de firma.
- **@Firma:** plataforma de validación de firmas de la AGE.
## 5.6 Protocolos seguros
| Protocolo | Capa | Función |
|-----------|------|---------|
| **TLS** (Transport Layer Security) | Transporte | Cifrado de comunicaciones (sustituyó a SSL) |
| **SSL** | Transporte | Obsoleto (vulnerabilidades POODLE, BEAST) |
| **HTTPS** | Aplicación | HTTP + TLS; protege la web |
| **SSH** | Aplicación | Acceso remoto seguro a servidores |
| **S/MIME** | Aplicación | Firma y cifrado de correo electrónico |
| **PGP / GPG** | Aplicación | Cifrado y firma de ficheros y correo |
| **IPsec** | Red | Cifrado a nivel de paquete IP; base de muchas VPN |
| **SFTP / FTPS** | Aplicación | Transferencia segura de ficheros |
### TLS (versiones)
- TLS 1.0 y 1.1: obsoletos y desaconsejados.
- **TLS 1.2:** ampliamente usado.
- **TLS 1.3:** versión actual; más rápido y seguro (elimina algoritmos débiles).
---
# 6. Infraestructura física de un CPD
## 6.1 Concepto de CPD
Un **CPD (Centro de Procesamiento de Datos)** es la instalación física que alberga los sistemas informáticos de una organización: servidores, almacenamiento, equipos de red y telecomunicaciones.
## 6.2 Clasificación por disponibilidad (TIER)
Estándar del **Uptime Institute**:
| Nivel | Disponibilidad | Tiempo de inactividad máximo/año | Características |
|-------|---------------|----------------------------------|----------------|
| **TIER I** | 99,671% | 28,8 h | Sin redundancia |
| **TIER II** | 99,741% | 22 h | Componentes redundantes |
| **TIER III** | 99,982% | 1,6 h | Concurrentemente mantenible |
| **TIER IV** | 99,995% | 26 min | Tolerante a fallos |
## 6.3 Acondicionamiento del CPD
### Ubicación
- Planta baja o sótano (riesgo de inundación) → mejor planta intermedia o elevada.
- Lejos de áreas con riesgo de inundación, zonas sísmicas, etc.
- Control de acceso físico estricto.
### Suelo técnico
- Suelo elevado (falso suelo) para el paso de cables y la distribución del aire frío.
### Climatización
- Precisión en temperatura (18-27°C) y humedad (40-60%).
- Sistemas de **pasillos fríos/calientes** (*hot aisle/cold aisle*) para optimizar el flujo de aire.
- Sistemas redundantes (N+1 o 2N).
### Electricidad
- SAI / UPS: protección ante microcortes y cortes breves.
- Generadores diésel: cortes prolongados.
- PDU (Power Distribution Unit) redundantes.
- Doble circuito eléctrico para equipos críticos.
### Contra incendios
- Detección precoz: detectores de humo, temperatura, aspiración de partículas (VESDA).
- Extinción con **gases inertes** (FM-200, Novec 1230, CO₂) que no dañan equipos.
- Compartimentación con puertas y paredes cortafuegos.
### Seguridad física
- Control de acceso por zonas (tarjeta, biometría).
- CCTV.
- Doble puerta (SAS Sistema de Acceso de Seguridad): antesala que impide acceso simultáneo desde exterior e interior.
## 6.4 Equipamiento del CPD
| Equipo | Función |
|--------|---------|
| **Servidores rack** | Procesamiento; montados en armarios rack (unidades U) |
| **Blade servers** | Muchos servidores en un chasis compartido; alta densidad |
| **SAN / NAS** | Almacenamiento en red |
| **Switches de core/distribución/acceso** | Conectividad de red |
| **Routers / Firewalls** | Conectividad externa y seguridad perimetral |
| **KVM** | Control de varios servidores con un solo teclado/monitor |
| **DCIM** | Data Center Infrastructure Management: monitorización global |
---
# 7. Sistemas de gestión de incidencias
## 7.1 Concepto
Un **sistema de gestión de incidencias** (*ticketing system*) es una herramienta que permite registrar, clasificar, priorizar, asignar y resolver los incidentes de soporte técnico de forma organizada.
## 7.2 Marco ITIL
**ITIL (Information Technology Infrastructure Library)** es un conjunto de buenas prácticas para la gestión de servicios de TI.
Conceptos clave de ITIL relacionados con incidencias:
| Concepto | Descripción |
|----------|-------------|
| **Incidente** | Interrupción no planificada o degradación de un servicio |
| **Problema** | Causa raíz desconocida de uno o más incidentes |
| **Workaround** | Solución temporal para restaurar el servicio |
| **SLA (Service Level Agreement)** | Acuerdo de nivel de servicio: tiempo de respuesta y resolución |
| **RCA (Root Cause Analysis)** | Análisis de la causa raíz del problema |
## 7.3 Ciclo de vida de un incidente
1. **Detección y registro:** el usuario reporta o el sistema detecta el incidente.
2. **Clasificación y priorización:** según impacto y urgencia.
3. **Diagnóstico inicial:** soporte de primer nivel intenta resolver.
4. **Escalado:** si no se resuelve, pasa a segundo o tercer nivel.
5. **Resolución y restauración del servicio.**
6. **Cierre:** confirmación del usuario y documentación.
## 7.4 Herramientas de gestión de incidencias
| Herramienta | Descripción |
|-------------|-------------|
| **Jira Service Management** | Muy extendida, basada en ITIL |
| **ServiceNow** | Plataforma empresarial completa |
| **Remedy (BMC)** | Muy usada en grandes organizaciones |
| **Zammad / osTicket** | Open-source |
| **Zendesk** | Orientada a soporte al cliente |
---
# 8. Control remoto de puestos de usuario
## 8.1 Concepto
El **control remoto** permite acceder y gestionar un equipo desde otro equipo a través de la red, como si estuviera físicamente delante de él.
## 8.2 Protocolos y tecnologías
| Tecnología | Protocolo | Puerto | Descripción |
|------------|-----------|--------|-------------|
| **RDP** (Remote Desktop Protocol) | Propietario Microsoft | TCP 3389 | Escritorio remoto en Windows |
| **VNC** (Virtual Network Computing) | RFB | TCP 5900 | Multiplataforma; comparte el escritorio gráfico |
| **SSH** | SSH | TCP 22 | Acceso remoto a la línea de comandos (Linux/Unix) |
| **TeamViewer** | Propietario | Vario | Fácil de usar; muy extendido en soporte técnico |
| **AnyDesk** | Propietario | Vario | Alternativa a TeamViewer |
| **SPICE / RDP sobre VDI** | Vario | Vario | Virtual Desktop Infrastructure |
## 8.3 Seguridad en el control remoto
Riesgos:
- Acceso no autorizado si las credenciales son débiles.
- Exposición del escritorio a través de la red.
- Ataques de fuerza bruta al puerto RDP (3389).
Medidas:
- Usar autenticación fuerte (MFA).
- **No exponer RDP directamente a Internet** → acceder a través de VPN.
- Cambiar puertos por defecto.
- Cifrado TLS en todas las sesiones remotas.
- Registro y auditoría de sesiones.
- Listas de IPs autorizadas.
---
# 9. Resumen: conceptos clave para el examen
| Concepto | Dato clave |
|----------|-----------|
| Tríada CIA | Confidencialidad, Integridad, Disponibilidad |
| No repudio | El emisor no puede negar haber firmado/enviado |
| AES | Cifrado simétrico estándar; claves 128/192/256 bits |
| RSA | Cifrado asimétrico; par de claves público-privada |
| SHA-256 | Función hash estándar actual (familia SHA-2) |
| MD5 / SHA-1 | Obsoletos; colisiones conocidas |
| Firma digital | Hash del mensaje cifrado con clave privada |
| Certificado X.509 | Vincula clave pública con identidad; emitido por CA |
| FNMT / @Firma / DNIe | Infraestructura de PKI en la AGE española |
| TLS 1.3 | Versión actual del protocolo de cifrado web |
| HTTPS | HTTP + TLS; cifra la comunicación web |
| SSH | Acceso remoto seguro a servidores (puerto 22) |
| SAI / UPS | Alimentación ininterrumpida ante cortes eléctricos |
| TIER IV CPD | 99,995% disponibilidad; tolerante a fallos |
| Pasillos fríos/calientes | Optimización del flujo de aire en CPD |
| Gases inertes en CPD | FM-200, Novec; extinción sin dañar equipos |
| ITIL | Marco de buenas prácticas para gestión de servicios TI |
| SLA | Acuerdo de nivel de servicio (tiempos de respuesta) |
| RDP | Escritorio remoto Windows; puerto TCP 3389 |
| MFA | Autenticación multifactor; al menos dos factores |
| RBAC | Control de acceso basado en roles |

356
bloque4/tema6.md Normal file
View File

@ -0,0 +1,356 @@
# Bloque 4 · Tema 6
# Comunicaciones. Medios de transmisión. Modos de comunicación. Equipos terminales y equipos de interconexión y conmutación. Redes de comunicaciones. Redes de conmutación y redes de difusión. Comunicaciones móviles e inalámbricas.
---
# 1. Esquema introductorio (visión rápida)
**Comunicación de datos:** transmisión de información entre sistemas.
**Medios de transmisión**
- Guiados: par trenzado (UTP/STP), coaxial, fibra óptica.
- No guiados (inalámbricos): ondas de radio, microondas, infrarrojos.
**Modos de comunicación**
- Simplex (un sentido), Half-duplex (alternado, ej. walkie-talkie), Full-duplex (bidireccional simultáneo).
**Redes**
- Conmutación de circuitos (PSTN, RDSI): camino dedicado.
- Conmutación de paquetes (Internet): los datos viajan en paquetes independientes.
- Difusión (broadcast): todos reciben el mensaje (ej. Ethernet legacy, radio, TV).
---
# 2. Medios de transmisión
## 2.1 Medios guiados
### Par trenzado
El cable más utilizado en redes de área local (LAN).
| Tipo | Descripción |
|------|-------------|
| **UTP** (Unshielded Twisted Pair) | Sin blindaje; más económico y flexible |
| **STP** (Shielded Twisted Pair) | Con blindaje; mejor protección contra interferencias |
| **FTP** | Pantalla global sobre todos los pares |
**Categorías:**
| Categoría | Ancho de banda | Uso típico |
|-----------|---------------|------------|
| Cat 5e | 100 MHz | Fast Ethernet (100 Mbps) |
| Cat 6 | 250 MHz | Gigabit Ethernet |
| Cat 6A | 500 MHz | 10 Gigabit Ethernet |
| Cat 7 | 600 MHz | 10 GbE con mejor blindaje |
| Cat 8 | 2000 MHz | 40 GbE en CPD |
Conectores: **RJ-45** (8P8C).
### Cable coaxial
- Conductor central + aislante + malla conductora + cubierta exterior.
- Usado en TV por cable, redes antiguas (10Base2, 10Base5).
- En desuso en redes LAN modernas.
### Fibra óptica
Transmite luz a través de un núcleo de vidrio o plástico. No sufre interferencias electromagnéticas.
| Tipo | Descripción | Distancia |
|------|-------------|-----------|
| **Monomodo (SMF)** | Solo un modo de propagación; núcleo muy fino (~9 µm); láser | Decenas de km |
| **Multimodo (MMF)** | Varios modos; núcleo más grueso (50/62,5 µm); LED o VCSEL | Hasta ~2 km |
Conectores: SC, LC, ST, MTP/MPO.
Velocidades: 1 Gbps, 10 Gbps, 40 Gbps, 100 Gbps, 400 Gbps+.
## 2.2 Medios no guiados (inalámbricos)
| Medio | Frecuencia | Uso |
|-------|-----------|-----|
| **Ondas de radio** | < 300 MHz | Radiodifusión AM/FM, comunicaciones móviles |
| **Microondas terrestres** | 300 MHz 300 GHz | Enlace punto a punto (repetidores) |
| **Microondas por satélite** | 1-30 GHz | GPS, TV satélite, comunicaciones globales |
| **Infrarrojos** | 300 GHz 430 THz | Mandos a distancia; corto alcance; sin obstáculos |
### Wi-Fi (IEEE 802.11)
| Estándar | Frecuencia | Velocidad máxima | Nombre comercial |
|----------|-----------|-----------------|-----------------|
| 802.11b | 2,4 GHz | 11 Mbps | Wi-Fi 1 |
| 802.11a | 5 GHz | 54 Mbps | Wi-Fi 2 |
| 802.11g | 2,4 GHz | 54 Mbps | Wi-Fi 3 |
| 802.11n | 2,4/5 GHz | 600 Mbps | Wi-Fi 4 |
| 802.11ac | 5 GHz | 6,9 Gbps | Wi-Fi 5 |
| 802.11ax | 2,4/5/6 GHz | 9,6 Gbps | Wi-Fi 6 / 6E |
| 802.11be | 2,4/5/6 GHz | 46 Gbps | Wi-Fi 7 |
---
# 3. Modos de comunicación
| Modo | Descripción | Ejemplo |
|------|-------------|---------|
| **Simplex** | Solo en un sentido | TV, radio (emisión) |
| **Half-duplex** | Ambos sentidos, pero no simultáneamente | Walkie-talkie, CB radio |
| **Full-duplex** | Ambos sentidos simultáneamente | Teléfono, Ethernet moderno |
---
# 4. Parámetros de la transmisión
| Concepto | Definición |
|----------|-----------|
| **Ancho de banda** | Rango de frecuencias disponible (Hz) o tasa máxima de transferencia (bps) |
| **Velocidad de transmisión** | Bits por segundo (bps, Kbps, Mbps, Gbps) |
| **Latencia / Retardo** | Tiempo que tarda un bit en ir de origen a destino |
| **Jitter** | Variación en la latencia; crítico en voz/video en tiempo real |
| **Tasa de error (BER)** | Bit Error Rate: proporción de bits recibidos con error |
| **Throughput** | Tasa de transferencia real efectiva |
### Teorema de Nyquist (canal sin ruido)
$$C = 2B \cdot \log_2(M)$$
Donde $B$ es el ancho de banda en Hz y $M$ es el número de niveles de señal.
### Teorema de Shannon (canal con ruido)
$$C = B \cdot \log_2(1 + S/N)$$
Donde $S/N$ es la relación señal/ruido.
---
# 5. Equipos terminales y de interconexión
## 5.1 Equipos terminales (DTE Data Terminal Equipment)
Dispositivos que generan o consumen información:
- Ordenadores, servidores.
- Teléfonos, smartphones.
- Impresoras en red.
## 5.2 Equipos de interconexión
### Repetidor (capa 1)
- Regenera la señal eléctrica para extender el alcance.
- Opera en capa 1 del modelo OSI.
- No filtra, no procesa: retransmite todos los bits.
### Hub (concentrador capa 1)
- Conecta varios equipos en estrella.
- Retransmite a todos los puertos (dominio de colisión único).
- En desuso: sustituido por el switch.
### Bridge (puente capa 2)
- Conecta dos segmentos de red.
- Aprende direcciones MAC; filtra tramas por segmento.
### Switch (conmutador capa 2)
- Conecta dispositivos en LAN.
- Crea una **tabla MAC** → envía la trama solo al puerto de destino.
- Cada puerto es un dominio de colisión independiente.
- Puede crear **VLANs** (redes virtuales).
- **Switch de capa 3:** también enruta (tiene capacidades de router).
### Router (encaminador capa 3)
- Conecta redes distintas (LAN-WAN, entre subredes).
- Trabaja con **direcciones IP**.
- Selecciona la mejor ruta mediante protocolos de enrutamiento.
- Separa dominios de broadcast.
| Protocolo de enrutamiento | Tipo | Descripción |
|--------------------------|------|-------------|
| **RIP** | Vector-distancia | Métrica: número de saltos; max. 15 |
| **OSPF** | Estado del enlace | Métrica: coste; más escalable |
| **BGP** | Vector de ruta | Enrutamiento entre sistemas autónomos (Internet) |
| **EIGRP** | Híbrido | Propietario Cisco |
### Gateway (pasarela capa 7)
- Traduce entre protocolos distintos (ej. red IP a red X.25).
- Opera en todas las capas si es necesario.
### Comparación de dispositivos
| Dispositivo | Capa OSI | Dirección usada | Dominio de colisión | Dominio broadcast |
|-------------|---------|----------------|--------------------|--------------------|
| Hub | 1 | — | Único | Único |
| Bridge | 2 | MAC | Separado por puerto | Único |
| Switch | 2 (o 3) | MAC (o IP) | Separado por puerto | Único (excepto VLAN) |
| Router | 3 | IP | Separado | Separado |
---
# 6. Redes de comunicaciones
## 6.1 Clasificación por cobertura geográfica
| Tipo | Cobertura | Ejemplo |
|------|-----------|---------|
| **PAN** | Personal (~10 m) | Bluetooth, ZigBee |
| **LAN** | Local (edificio) | Ethernet, Wi-Fi |
| **MAN** | Metropolitana (ciudad) | Metro Ethernet, WiMAX |
| **WAN** | Amplia (país/internacional) | Internet, MPLS, ATM |
## 6.2 Topologías de red
| Topología | Descripción | Ventajas | Desventajas |
|-----------|-------------|----------|-------------|
| **Bus** | Todos comparten un cable único | Sencilla, barata | Un fallo afecta a todos |
| **Estrella** | Todos conectados a un nodo central | Fácil de gestionar | El nodo central es punto de fallo |
| **Anillo** | Cada nodo conectado al siguiente y al anterior | Predecible | Un fallo afecta a todos |
| **Malla** | Cada nodo conectado a todos los demás | Alta redundancia | Muy cara |
| **Árbol** | Jerarquía de estrellas | Escalable | El nodo raíz es punto de fallo |
---
# 7. Redes de conmutación y redes de difusión
## 7.1 Redes de conmutación de circuitos
- **Se establece un camino dedicado** entre origen y destino antes de transmitir.
- El circuito está reservado durante toda la comunicación, aunque no haya datos.
- Ejemplo: red telefónica pública (**PSTN**), **RDSI (ISDN)**.
**Ventaja:** latencia predecible, calidad constante.
**Desventaja:** ineficiente (recursos reservados aunque no se usen).
### RDSI (Red Digital de Servicios Integrados / ISDN)
- Digitaliza la línea telefónica convencional.
- Canales B (64 Kbps, para datos/voz) y canal D (señalización).
- **BRI (Basic Rate Interface):** 2B+D (128 Kbps de datos + señalización).
- **PRI (Primary Rate Interface):** 30B+D en Europa (E1 = 2 Mbps).
- Actualmente en desuso; sustituida por ADSL, fibra y VoIP.
## 7.2 Redes de conmutación de paquetes
- Los datos se dividen en **paquetes**, cada uno con cabecera (origen, destino, número de secuencia).
- Los paquetes viajan de forma independiente por la red y pueden tomar rutas distintas.
- El receptor reensambla los paquetes.
- Ejemplo: **Internet (IP/TCP)**, Frame Relay, X.25, ATM.
**Ventaja:** uso eficiente de la red; comparte recursos entre muchos usuarios.
**Desventaja:** latencia variable (jitter); no garantizado por defecto.
### Variantes
| Variante | Descripción |
|---------|-------------|
| **Datagramas** | Paquetes completamente independientes (UDP) |
| **Circuito virtual** | Se establece un camino lógico antes de transmitir pero los recursos no son dedicados (ATM, Frame Relay) |
## 7.3 Redes de difusión (broadcast)
- Un nodo transmite y **todos los nodos** de la red reciben el mensaje.
- Ejemplo: Ethernet en hub, Wi-Fi, radio, televisión terrestre.
**Multidifusión (multicast):** los datos se envían a un grupo de receptores suscritos, no a todos.
---
# 8. Comunicaciones móviles e inalámbricas
## 8.1 Generaciones de la telefonía móvil
| Generación | Tecnología | Velocidad | Características |
|-----------|-----------|-----------|----------------|
| **1G** | AMPS, NMT | ~2,4 Kbps | Analógica; solo voz |
| **2G** | GSM, CDMA | 14,4 Kbps 384 Kbps | Digital; SMS; GPRS/EDGE |
| **3G** | UMTS, HSPA | 384 Kbps 42 Mbps | Internet móvil; vídeo llamada |
| **4G** | LTE, LTE-A | 100 Mbps 1 Gbps | Totalmente basado en IP |
| **5G** | NR (New Radio) | Hasta 20 Gbps | Baja latencia (<1 ms); IoT masivo |
### Términos de 2G
- **GSM (Global System for Mobile communications):** estándar europeo de 2G.
- **SIM (Subscriber Identity Module):** tarjeta identificadora del usuario.
- **GPRS:** extensión de GSM para transmisión de datos (hasta 172 Kbps).
- **EDGE:** mejora de GPRS (hasta 384 Kbps); también llamado 2,5G.
## 8.2 Bluetooth
| Versión | Velocidad | Alcance | Notas |
|---------|-----------|---------|-------|
| Bluetooth 4.0 (BLE) | 1 Mbps | ~50 m | Bajo consumo; IoT |
| Bluetooth 5.0 | 2 Mbps | ~240 m | Más alcance y velocidad |
| Bluetooth 5.4 | 2 Mbps | — | Seguridad mejorada |
Usa la banda de 2,4 GHz (ISM); frecuencia *hopping* para evitar interferencias.
## 8.3 Otras tecnologías inalámbricas
| Tecnología | Frecuencia | Velocidad | Uso |
|------------|-----------|-----------|-----|
| **ZigBee** (IEEE 802.15.4) | 2,4 GHz | 250 Kbps | Domótica, IoT, bajo consumo |
| **Z-Wave** | 868/915 MHz | 100 Kbps | Domótica; menor interferencia con Wi-Fi |
| **WiMAX** (IEEE 802.16) | 2-66 GHz | Hasta 1 Gbps | WAN inalámbrica; alternativa DSL en zonas rurales |
| **NFC** | 13,56 MHz | 424 Kbps | Pago contactless; distancia < 20 cm |
| **RFID** | 125 KHz 5,8 GHz | Variable | Identificación de objetos; logística |
| **LoRa / LoRaWAN** | 868 MHz | < 50 Kbps | IoT de largo alcance y bajo consumo |
## 8.4 WLAN Wi-Fi (IEEE 802.11)
Ya detallado en la sección de medios. Aspectos adicionales:
- **SSID:** nombre de la red Wi-Fi.
- **WPA2 / WPA3:** protocolos de seguridad actuales (reemplazaron WEP y WPA, que son inseguros).
- **802.11i:** estándar de seguridad; base de WPA2.
- **MIMO (Multiple Input Multiple Output):** múltiples antenas para mejorar el rendimiento.
- **OFDM (Orthogonal Frequency-Division Multiplexing):** modulación usada en 802.11a/g/n/ac/ax.
---
# 9. Modelo OSI y TCP/IP (referencia de capas)
## 9.1 Modelo OSI (7 capas)
| Nº | Capa | Función | Protocolos/tecnologías |
|----|------|---------|----------------------|
| 7 | **Aplicación** | Interfaz con el usuario/app | HTTP, FTP, SMTP, DNS, SSH |
| 6 | **Presentación** | Formato, cifrado, compresión | SSL/TLS, JPEG, MPEG |
| 5 | **Sesión** | Control de diálogo, sesiones | NetBIOS, RPC |
| 4 | **Transporte** | Transporte extremo a extremo, control de flujo | TCP, UDP |
| 3 | **Red** | Enrutamiento, direccionamiento lógico | IP, ICMP, BGP, OSPF |
| 2 | **Enlace de datos** | Acceso al medio, direccionamiento físico | Ethernet, Wi-Fi, PPP |
| 1 | **Física** | Transmisión de bits por el medio | Cables, señales, conectores |
## 9.2 Modelo TCP/IP (4 capas)
| Capa TCP/IP | Capas OSI equivalentes | Protocolos |
|-------------|----------------------|------------|
| **Aplicación** | 5, 6, 7 | HTTP, DNS, SMTP, FTP, SSH |
| **Transporte** | 4 | TCP, UDP |
| **Internet** | 3 | IP, ICMP, ARP |
| **Acceso a red** | 1, 2 | Ethernet, Wi-Fi, PPP |
## 9.3 TCP vs UDP
| Característica | TCP | UDP |
|----------------|-----|-----|
| Orientado a conexión | Sí (three-way handshake) | No |
| Fiabilidad | Sí (ACK, retransmisión) | No |
| Control de flujo | Sí | No |
| Orden de llegada | Garantizado | No garantizado |
| Velocidad | Más lento | Más rápido |
| Uso | Web, email, FTP | Streaming, DNS, VoIP, juegos |
---
# 10. Resumen: conceptos clave para el examen
| Concepto | Dato clave |
|----------|-----------|
| Par trenzado Cat 6 | Gigabit Ethernet; conector RJ-45 |
| Fibra monomodo | Larga distancia (km); láser; núcleo ~9 µm |
| Fibra multimodo | Corta distancia (~2 km); LED; núcleo 50 µm |
| Full-duplex | Transmisión bidireccional simultánea |
| Fórmula de Shannon | $C = B \cdot \log_2(1 + S/N)$ |
| Hub | Capa 1; dominio de colisión único |
| Switch | Capa 2; tabla MAC; por puerto dominio colisión |
| Router | Capa 3; enrutamiento IP; separa broadcasts |
| Conmutación de circuitos | Camino dedicado; PSTN, RDSI |
| Conmutación de paquetes | Paquetes independientes; Internet, TCP/IP |
| RDSI BRI | 2B+D; 128 Kbps de datos |
| 4G/LTE | 100 Mbps 1 Gbps; totalmente IP |
| 5G | Hasta 20 Gbps; latencia <1 ms; IoT masivo |
| WPA3 | Protocolo de seguridad Wi-Fi actual |
| IEEE 802.11ax | Wi-Fi 6; 2,4/5/6 GHz; hasta 9,6 Gbps |
| Bluetooth BLE | 4.0; bajo consumo; IoT; 2,4 GHz |
| NFC | 13,56 MHz; <20 cm; pago contactless |
| OSI capa 3 | Red; enrutamiento; IP |
| TCP three-way handshake | SYN → SYN-ACK → ACK |
| UDP | No orientado a conexión; más rápido; streaming/VoIP |

352
bloque4/tema9.md Normal file
View File

@ -0,0 +1,352 @@
# Bloque 4 · Tema 9
# Seguridad y protección en redes de comunicaciones. Seguridad perimetral. Acceso remoto seguro a redes. Redes privadas virtuales (VPN). Seguridad en el puesto del usuario.
---
# 1. Esquema introductorio (visión rápida)
**Seguridad en redes:** conjunto de medidas técnicas y organizativas que protegen la integridad, confidencialidad y disponibilidad de la información en tránsito.
**Seguridad perimetral:** "muralla" entre la red interna (confiable) y el exterior (no confiable).
Herramientas: firewall, DMZ, IDS/IPS, proxy, WAF.
**VPN:** túnel cifrado sobre una red pública (Internet) que simula una red privada.
Protocolos: IPsec, OpenVPN, WireGuard, SSL/TLS.
**Seguridad en el puesto final:** antivirus/EDR, actualizaciones, cifrado de disco, DLP.
---
# 2. Fundamentos de seguridad en redes
## 2.1 Amenazas en redes
| Amenaza | Descripción |
|---------|-------------|
| **Sniffing (escucha)** | Captura de tráfico de red con herramientas como Wireshark |
| **Spoofing** | Suplantación de identidad: IP spoofing, ARP spoofing, DNS spoofing |
| **Man-in-the-Middle (MitM)** | Interposición entre dos comunicantes para capturar o alterar datos |
| **DoS / DDoS** | Saturación de un servicio para hacerlo inaccesible |
| **Port scanning** | Exploración de puertos abiertos para buscar vulnerabilidades (ej. Nmap) |
| **Replay attack** | Reenvío de un paquete capturado para repetir una acción |
| **SQL Injection / XSS** | Inyección de código malicioso en aplicaciones web |
## 2.2 Principios básicos de diseño seguro de redes
- **Defensa en profundidad:** múltiples capas de seguridad; ningún mecanismo único es suficiente.
- **Mínimo privilegio:** cada sistema/usuario solo accede a lo estrictamente necesario.
- **Segmentación:** dividir la red en zonas con distintos niveles de confianza.
- **Zero Trust:** ningún usuario ni dispositivo es de confianza por defecto, aunque esté dentro de la red.
---
# 3. Seguridad perimetral
## 3.1 Concepto
La **seguridad perimetral** es el conjunto de técnicas y dispositivos que protegen la red interna de amenazas externas, controlando el tráfico que entra y sale.
## 3.2 Firewall (cortafuegos)
Ya visto en el tema 5. Resumen en contexto de red perimetral:
| Tipo | Nivel OSI | Funcionamiento |
|------|----------|---------------|
| **Filtrado de paquetes** | 3-4 | Filtra por IP, puerto, protocolo |
| **Stateful inspection** | 3-4 | Rastrea el estado de las conexiones |
| **Application-level gateway (Proxy)** | 7 | Inspecciona el contenido; entiende el protocolo |
| **NGFW** | 3-7 | DPI, IDS/IPS integrado, control por app, SSL inspection |
### Reglas de firewall
Las reglas se procesan en orden. Política por defecto: **denegar todo lo no permitido explícitamente** (*default deny*).
```
Ejemplo de reglas típicas:
1. ALLOW TCP ANY → 80,443 (HTTP/HTTPS saliente)
2. ALLOW TCP ANY → 22 (SSH saliente)
3. ALLOW TCP DMZ:80 → INTERNET (Servidor web accesible)
4. DENY ALL ANY → ANY (Default deny)
```
## 3.3 DMZ (Zona Desmilitarizada)
Una **DMZ** es una subred intermedia, separada tanto de la red interna como de Internet, donde se ubican los servidores que deben ser accesibles desde el exterior.
```
[INTERNET]
|
[FIREWALL 1] <- Primer firewall perimetral
|
[DMZ - Zona Pública] <- Servidores web, correo, DNS
| |
[Web] [Mail]
|
[FIREWALL 2] <- Segundo firewall interno
|
[RED INTERNA] <- Servidores corporativos, BD, usuarios
```
**Servidores típicos en DMZ:**
- Servidor web (HTTP/HTTPS).
- Servidor de correo (SMTP entrante).
- Servidor DNS público.
- Proxy inverso.
**Ventaja:** si el servidor web es comprometido, el atacante no tiene acceso directo a la red interna.
## 3.4 Proxy
Un **proxy** es un intermediario entre los clientes internos e Internet.
| Tipo | Descripción |
|------|-------------|
| **Proxy directo (forward proxy)** | Los clientes internos acceden a Internet a través del proxy |
| **Proxy inverso (reverse proxy)** | Recibe solicitudes de Internet y las redirige a servidores internos (ej. nginx, HAProxy) |
| **Proxy transparente** | Intercepta el tráfico sin necesidad de configuración en el cliente |
**Funciones del proxy directo:**
- Control y filtrado de contenidos (listas negras, categorías).
- Caché de contenidos (rendimiento).
- Autenticación de usuarios.
- Anonimización (oculta las IPs internas).
- Log de navegación.
## 3.5 WAF (Web Application Firewall)
- Protege aplicaciones web frente a ataques de capa 7: SQL Injection, XSS, CSRF, etc.
- Analiza tráfico HTTP/HTTPS.
- Puede operar en modo: *detección* (solo alerta) o *prevención* (bloquea).
- Ejemplos: ModSecurity, AWS WAF, Cloudflare WAF.
## 3.6 IDS / IPS
| Sistema | Posición | Respuesta |
|---------|----------|-----------|
| **IDS** | Pasiva (copia del tráfico, fuera de banda) | Solo alerta (no bloquea por sí mismo) |
| **IPS** | Activa (en línea, *inline*) | Detecta y bloquea el tráfico malicioso |
| **HIDS** | En el host | Monitoriza eventos del sistema (logs, ficheros) |
| **NIDS** | En la red | Monitoriza el tráfico de red |
**Técnicas de detección:**
- **Basada en firmas:** compara con patrones de ataques conocidos.
- **Basada en anomalías:** modelo de comportamiento normal; alerta ante desviaciones.
## 3.7 SIEM (Security Information and Event Management)
Agregación, correlación y análisis de eventos de seguridad de múltiples fuentes:
- Firewalls, IDS/IPS, servidores, aplicaciones.
- Alertas en tiempo real.
- Cumplimiento normativo (auditoría, ENS, GDPR).
- Ejemplos: Splunk, IBM QRadar, Microsoft Sentinel, Wazuh (open-source).
---
# 4. Acceso remoto seguro
## 4.1 Por qué es necesario el acceso remoto seguro
El **teletrabajo**, los **desplazamientos** y la administración remota de sistemas requieren acceder a la red corporativa desde redes no controladas (Wi-Fi pública, Internet). Sin medidas de seguridad, las comunicaciones quedan expuestas.
## 4.2 SSH (Secure Shell)
- Acceso remoto **seguro** a la línea de comandos de servidores Linux/Unix.
- Puerto estándar: **TCP 22**.
- Cifrado: TLS (en versiones modernas, curva25519, AES-256-GCM).
- Autenticación: contraseña o **par de claves RSA/ECDSA** (más seguro).
- Funciones adicionales: **SCP** (copia segura de ficheros), **SFTP**, **port forwarding** (túnel SSH).
```bash
# Generar par de claves SSH
ssh-keygen -t ed25519 -C "usuario@ejemplo.com"
# Conectar a un servidor
ssh usuario@servidor.ejemplo.com
# Copiar ficheros de forma segura
scp archivo.txt usuario@servidor:/ruta/destino/
```
## 4.3 SSL VPN / TLS VPN
- VPN que funciona sobre **HTTPS (TLS/SSL)**, puerto 443.
- Solo requiere un navegador o cliente ligero.
- Muy flexible; funciona a través de firewalls y NAT.
- Ejemplo: **OpenVPN**, Cisco AnyConnect, Pulse Secure.
---
# 5. Redes Privadas Virtuales (VPN)
## 5.1 Concepto
Una **VPN (Virtual Private Network)** crea un **túnel cifrado** a través de una red pública (Internet) que conecta dos puntos como si estuvieran en la misma red privada.
**Proporciona:**
- **Confidencialidad:** el tráfico viaja cifrado.
- **Autenticidad:** se verifica la identidad de los extremos.
- **Integridad:** los datos no son alterados en tránsito.
## 5.2 Tipos de VPN
| Tipo | Descripción | Uso típico |
|------|-------------|-----------|
| **VPN de acceso remoto (cliente-a-sitio)** | Un usuario se conecta a la red corporativa | Teletrabajador → oficina |
| **VPN de sitio a sitio** | Connecta dos redes corporativas permanentemente | Sede central ↔ sucursal |
| **VPN de cliente a cliente** | Conecta dos usuarios individuales | P2P cifrado |
## 5.3 Protocolos VPN
### IPsec
- Estándar IETF para asegurar comunicaciones IP.
- Opera en **capa 3 (red)**.
- **Dos modos:**
- **Modo transporte:** solo cifra el payload del paquete IP (no la cabecera).
- **Modo túnel:** cifra el paquete IP completo y añade nueva cabecera → más seguro para VPN.
- **Dos protocolos:**
- **AH (Authentication Header):** autenticación e integridad, *sin* cifrado.
- **ESP (Encapsulating Security Payload):** autenticación, integridad *y* cifrado.
- **IKE / IKEv2 (Internet Key Exchange):** protocolo de negociación de claves para IPsec.
| Protocolo IPsec | Autenticación | Integridad | Cifrado |
|----------------|--------------|------------|---------|
| AH | ✓ | ✓ | ✗ |
| ESP | ✓ | ✓ | ✓ |
### OpenVPN
- Open-source; basado en **TLS/SSL**.
- Puerto: **1194/UDP** (o TCP 443 para evitar bloqueos).
- Muy flexible y ampliamente auditado.
- Usa certificados X.509 para autenticación.
### WireGuard
- Protocolo moderno (2020); código muy reducido (~4.000 líneas vs ~100.000 de IPsec).
- **Extremadamente rápido** y sencillo.
- Criptografía moderna: **ChaCha20, Poly1305, Curve25519, BLAKE2**.
- Puerto: **UDP 51820** (por defecto).
- Integrado en el kernel Linux desde la versión 5.6.
### L2TP/IPsec
- **L2TP (Layer 2 Tunneling Protocol):** crea el túnel (capa 2) pero sin cifrado propio.
- Se combina con **IPsec** para el cifrado.
- Común en sistemas operativos sin necesidad de cliente adicional.
### PPTP (Point-to-Point Tunneling Protocol)
- Antiguo protocolo de Microsoft.
- **Obsoleto e inseguro;** no debe usarse.
### Comparativa de protocolos VPN
| Protocolo | Seguridad | Velocidad | Complejidad | Uso |
|-----------|-----------|-----------|-------------|-----|
| IPsec/IKEv2 | Alta | Alta | Media | Empresarial |
| OpenVPN | Alta | Media | Media | Empresarial/Personal |
| **WireGuard** | Muy alta | Muy alta | Baja | Moderno, recomendado |
| L2TP/IPsec | Media-Alta | Media | Media | Legado |
| PPTP | **Muy baja** | Alta | Baja | Obsoleto |
## 5.4 Componentes de una VPN
- **Concentrador VPN / VPN Gateway:** servidor que acepta conexiones VPN entrantes.
- **Cliente VPN:** software en el puesto del usuario.
- **Certificados / PSK (PreShared Key):** para autenticación.
- **Split tunneling:** solo el tráfico corporativo va por la VPN; el resto va directamente a Internet.
- **Full tunneling:** todo el tráfico pasa por la VPN.
---
# 6. Seguridad en el puesto del usuario
## 6.1 Endpoint Security
El **puesto de usuario (endpoint)** es el punto de entrada más habitual de los atacantes (email malicioso, USB infectado, navegación web).
## 6.2 Antivirus y EDR
| Solución | Descripción |
|----------|-------------|
| **Antivirus tradicional** | Detección por firmas; necesita actualizaciones constantes |
| **EDR (Endpoint Detection & Response)** | Monitorización continua del comportamiento; respuesta automática a incidentes |
| **XDR (Extended Detection & Response)** | EDR + correlación con red, cloud, email |
## 6.3 Actualizaciones y parcheo
- **Mantener el SO y las aplicaciones actualizados** es la medida con mayor impacto en seguridad.
- Los parches corrigen vulnerabilidades conocidas (CVEs).
- **Patch Management:** proceso de gestión y despliegue centralizado de actualizaciones.
- Herramientas: WSUS (Windows), Red Hat Satellite, Ansible.
## 6.4 Cifrado del disco
| Solución | Sistema | Notas |
|---------|---------|-------|
| **BitLocker** | Windows | Cifrado de disco completo; TPM |
| **FileVault** | macOS | Cifrado de disco con clave del usuario |
| **LUKS (Linux Unified Key Setup)** | Linux | Estándar de facto en Linux |
| **VeraCrypt** | Multiplataforma | Cifrado de volúmenes y contenedores |
El cifrado de disco protege los datos si el equipo es robado.
## 6.5 DLP (Data Loss Prevention)
- Evita que datos sensibles salgan de la organización (USB, email, nube).
- Clasifica la información por nivel de sensibilidad.
- Políticas: bloquear, cifrar, alertar según el tipo de dato.
- Ejemplos: Microsoft Purview DLP, Symantec DLP, Forcepoint.
## 6.6 Gestión de identidad y acceso (IAM)
- **SSO (Single Sign-On):** el usuario se autentica una vez y accede a todas las aplicaciones.
- **MFA:** obligatorio en accesos críticos.
- **PAM (Privileged Access Management):** control de cuentas privilegiadas (administradores).
- **Directorio activo (Active Directory):** gestión centralizada de usuarios y políticas (GPO).
- **LDAP/Kerberos:** protocolos de autenticación en redes corporativas.
## 6.7 Políticas de seguridad en el puesto
- **Bloqueo automático de pantalla** tras inactividad.
- **Prohibición de medios extraíbles** (USB) no autorizados.
- **Navegación segura:** filtrado de URLs, certificado SSL obligatorio.
- **Correo electrónico seguro:** filtros antispam, antiphishing, DKIM/SPF/DMARC.
- **Formación al usuario:** la ingeniería social es la principal causa de incidentes.
---
# 7. ENS (Esquema Nacional de Seguridad)
El **ENS (Real Decreto 311/2022)** establece los principios y requisitos mínimos de seguridad para las Administraciones Públicas españolas que traten información en sistemas electrónicos.
| Aspecto | Descripción |
|---------|-------------|
| **Ámbito** | Toda la AGE y demás administraciones que usen medios electrónicos |
| **Categorías** | Básica, Media, Alta (según el impacto de un incidente) |
| **Dimensiones de seguridad** | Confidencialidad (C), Integridad (I), Disponibilidad (D), Autenticidad (A), Trazabilidad (T) |
| **CCN-CERT** | Centro Criptológico Nacional Computer Emergency Response Team de la AGE |
| **Guías CCN-STIC** | Guías técnicas del CCN para implementar el ENS |
---
# 8. Resumen: conceptos clave para el examen
| Concepto | Dato clave |
|----------|-----------|
| Defensa en profundidad | Múltiples capas de seguridad |
| Zero Trust | Ningún dispositivo/usuario es confiable por defecto |
| DMZ | Subred intermedia para servicios públicos |
| Default deny | Denegar todo lo no permitido explícitamente |
| WAF | Firewall de aplicación web; protege contra SQLi, XSS |
| IPS | En línea; detecta Y bloquea tráfico malicioso |
| SIEM | Agregación y correlación de eventos de seguridad |
| VPN de acceso remoto | Teletrabajador → red corporativa cifrada |
| VPN de sitio a sitio | Sede central ↔ sucursal |
| IPsec AH | Solo autenticación e integridad; sin cifrado |
| IPsec ESP | Autenticación, integridad Y cifrado |
| IPsec modo túnel | Cifra el paquete IP completo; más seguro |
| WireGuard | VPN moderno; ChaCha20; muy rápido; kernel Linux 5.6+ |
| OpenVPN | TLS-based; puerto 1194/UDP; open-source |
| PPTP | Obsoleto e inseguro |
| SSH | Acceso remoto seguro; puerto TCP 22 |
| Split tunneling | Solo tráfico corporativo por VPN |
| EDR | Monitorización del comportamiento del endpoint |
| BitLocker | Cifrado de disco Windows; requiere TPM |
| ENS | Real Decreto 311/2022; seguridad en AAPP; CCN-CERT |
| CCN-STIC | Guías técnicas del CCN para el ENS |

1088
css/style.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,33 +2,161 @@
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Cuestionarios TAI</title>
<link rel="stylesheet" href="css/estilos.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAI AGE | Cuestionarios</title>
<link rel="stylesheet" href="../css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
<h1>Cuestionarios TAI</h1>
<!-- ── Topbar ─────────────────────────────────────────── -->
<nav class="topbar">
<span class="topbar-brand"><i class="fas fa-graduation-cap"></i> TAI AGE</span>
<nav class="topbar-nav">
<a href="../index.html">Inicio</a>
<a href="../curso.html">Temario</a>
<a href="index.html" class="active">Cuestionarios</a>
<a href="../noticias.html">Noticias</a>
</nav>
</nav>
<select id="selector">
<option value="">Selecciona un examen</option>
<!-- ── Layout ────────────────────────────────────────── -->
<div class="quiz-layout" style="margin-top:calc(var(--topbar-h) + 1.5rem)">
<div class="quiz-header">
<h1><i class="fas fa-file-alt"></i> Cuestionarios TAI</h1>
<p>Exámenes reales de convocatorias anteriores (2019 2024).<br>
Fórmula AGE: <strong>Nota = (Aciertos Fallos/3) / Total × 10</strong></p>
</div>
<!-- Marcador -->
<div class="quiz-scoreboard">
<div class="score-chip aciertos">
<span class="val" id="val-aciertos">0</span>
<span class="lbl">Aciertos</span>
</div>
<div class="score-chip fallos">
<span class="val" id="val-fallos">0</span>
<span class="lbl">Fallos</span>
</div>
<div class="score-chip total">
<span class="val" id="val-progreso">0 / 0</span>
<span class="lbl">Progreso</span>
</div>
<div class="score-chip" style="border-color:var(--warning)">
<span class="val" id="val-nota" style="color:var(--warning)"></span>
<span class="lbl">Nota est.</span>
</div>
</div>
<!-- Controles -->
<div class="quiz-controls">
<select id="sel-examen" class="quiz-select">
<option value="">Selecciona un examen…</option>
<option value="data/TAI_2019.json">TAI 2019</option>
<option value="data/TAI_2023.json">TAI 2023</option>
<option value="data/TAI_2024A.json">TAI 2024 Modelo A</option>
<option value="data/TAI_2024B.json">TAI 2024 Modelo B</option>
</select>
<button id="btn-iniciar" class="btn btn-primary" disabled>
<i class="fas fa-play"></i> Iniciar
</button>
</div>
<div id="quiz"></div>
<!-- PDFs del examen seleccionado -->
<div id="exam-pdfs" class="exam-pdfs" style="display:none"></div>
<!--<button id="corregir">Corregir</button>-->
<div id="resultado"></div>
<!-- Empty state -->
<div id="seccion-empty" class="empty-state">
<i class="fas fa-question-circle" style="color:var(--accent)"></i>
<p>Selecciona un examen y pulsa <strong>Iniciar</strong> para comenzar a practicar.</p>
</div>
<!--<button id="aleatoria">Pregunta aleatoria</button>-->
<!-- Pregunta activa -->
<div id="seccion-quiz" style="display:none">
<div class="question-card">
<div class="question-num" id="pregunta-num">Pregunta 1 de …</div>
<div class="question-text" id="pregunta-txt"></div>
<div id="contexto-pregunta" class="supuesto-context" style="display:none"></div>
<ul class="options-list" id="opciones"></ul>
<div class="question-feedback" id="feedback"></div>
</div>
<div id="pregunta-actual"></div>
<div class="quiz-nav-row">
<button id="btn-siguiente" class="btn btn-primary" style="display:none">
Siguiente <i class="fas fa-chevron-right"></i>
</button>
</div>
</div>
<div id="feedback"></div>
<!-- Selector de supuestos prácticos -->
<div id="seccion-supuesto-sel" style="display:none">
<div class="sup-sel-header">
<h2><i class="fas fa-clipboard-list"></i> Supuestos prácticos</h2>
<p>Has completado las preguntas tipo test. Ahora elige <strong>uno de los dos supuestos prácticos</strong> para practicarlo con su material de referencia.</p>
</div>
<div id="sup-cards" class="sup-cards-grid"></div>
</div>
<!-- Pantalla final -->
<div id="seccion-final" style="display:none">
<div class="final-screen">
<h2><i class="fas fa-flag-checkered"></i> ¡Examen completado!</h2>
<div class="final-score-big" id="final-nota"></div>
<div class="final-score-sub">sobre 10 (fórmula AGE)</div>
<div class="quiz-scoreboard" style="margin:1.5rem 0">
<div class="score-chip aciertos">
<span class="val" id="final-aciertos">0</span>
<span class="lbl">Aciertos</span>
</div>
<div class="score-chip fallos">
<span class="val" id="final-fallos">0</span>
<span class="lbl">Fallos</span>
</div>
<div class="score-chip">
<span class="val" id="final-sin" style="color:var(--text-muted)">0</span>
<span class="lbl">Sin resp.</span>
</div>
<div class="score-chip total">
<span class="val" id="final-total">0</span>
<span class="lbl">Total</span>
</div>
</div>
<div style="display:flex;gap:1rem;justify-content:center;flex-wrap:wrap">
<button class="btn btn-primary" onclick="reiniciar()">
<i class="fas fa-redo"></i> Volver a intentarlo
</button>
<a href="../curso.html" class="btn btn-outline">
<i class="fas fa-book-open"></i> Repasar temario
</a>
</div>
</div>
<!-- Análisis de fallos -->
<div id="repaso-wrap" class="repaso-wrap" style="display:none"></div>
</div>
</div>
<script>
function reiniciar() {
['seccion-final','seccion-quiz','seccion-supuesto-sel'].forEach(id => {
document.getElementById(id).style.display = 'none';
});
document.getElementById('seccion-empty').style.display = 'block';
document.getElementById('sel-examen').value = '';
document.getElementById('btn-iniciar').disabled = true;
document.getElementById('btn-iniciar').innerHTML = '<i class="fas fa-play"></i> Iniciar';
['val-aciertos','val-fallos'].forEach(id => document.getElementById(id).textContent = '0');
document.getElementById('val-progreso').textContent = '0 / 0';
document.getElementById('val-nota').textContent = '—';
}
</script>
<script src="js/quiz.js"></script>
<script src="js/app.js"></script>
</body>
</html>

378
cuestionarios/js/quiz.js Normal file
View File

@ -0,0 +1,378 @@
/**
* cuestionarios/js/quiz.js
* Lógica del cuestionario TAI con fórmula de corrección AGE.
* Fórmula: Nota = (Aciertos - Fallos/3) / TotalPreguntas * 10
*/
// ── Estado ──────────────────────────────────────────────────
let preguntas = [];
let supuestosData = {}; // { "Supuesto I": [...], "Supuesto II": [...] }
let faseActual = 'test'; // 'test' | 'supuesto'
let indice = 0;
let aciertos = 0;
let fallos = 0;
let respondida = false;
let preguntasFalladas = []; // { pregunta, elegida }
// ── Mapa de temas y palabras clave ──────────────────────────
const TEMAS_KW = [
{ id:'const', label:'Constitución Española', link:'../curso.html?bloque=1', kw:['constitución','constitucional','rey ','cortes generales','senado','congreso','diputad','tribunal constitucional','defensor del pueblo','artículo 62','artículo 63','título i','título ii','artículo 1 ','capítulo'] },
{ id:'p39', label:'Procedimiento Adm. (Ley 39/2015)', link:'../curso.html?bloque=1', kw:['ley 39','procedimiento administrativo','recurso de alzada','silencio administrativo','notificación','expediente administrativo','recurso potestativo','recurso extraordinario'] },
{ id:'p40', label:'Régimen Jurídico (Ley 40/2015)', link:'../curso.html?bloque=1', kw:['ley 40','órgano colegiado','delegación de competencia','avocación','administración general del estado','convenio interadministrativo'] },
{ id:'lcsp', label:'Contratación Pública (LCSP)', link:'../curso.html?bloque=1', kw:['contratos del sector público','lcsp','licitación','adjudicación','pliego','contrato menor','concesión de servicios','poder adjudicador'] },
{ id:'trebep', label:'Función Pública (TREBEP)', link:'../curso.html?bloque=1', kw:['trebep','funcionario','empleado público','oposición','provisión de puestos','situaciones administrativas','excedencia','régimen disciplinario','carrera profesional'] },
{ id:'hac', label:'Hacienda Pública / Presupuestos', link:'../curso.html?bloque=1', kw:['presupuesto','hacienda pública','igae','tribunal de cuentas','crédito presupuestario','gasto público','control financiero','intervención general'] },
{ id:'html', label:'HTML / CSS / JavaScript', link:'../curso.html?bloque=3', kw:['html','css','javascript','dom','<input','etiqueta','formulario web','diseño web','responsive','selector css'] },
{ id:'bd', label:'Bases de Datos / SQL', link:'../curso.html?bloque=3', kw:['sql','select ','join','base de datos','normalización','índice','relacional','trigger','procedimiento almacenado','sgbd','tabla '] },
{ id:'prog', label:'Programación / Algoritmos', link:'../curso.html?bloque=3', kw:['algoritmo','lenguaje de programación','java ','python','c# ','compilad','interpreta','orientado a objetos','array','recursiv','metodología ágil','scrum','git'] },
{ id:'redes', label:'Redes y Comunicaciones', link:'../curso.html?bloque=4', kw:['tcp/ip','protocolo','router','switch','vlan','dirección ip','máscara de red','ethernet','arp','dns','dhcp','ospf','bgp','mpls'] },
{ id:'seg', label:'Seguridad Informática', link:'../curso.html?bloque=4', kw:['cifrado','criptografía','firma digital','certificado digital','ssl','tls','vpn','firewall','ciberincidente','autenticación','hash','ransomware','ids ','ips '] },
{ id:'so', label:'Sistemas Operativos / Hardware', link:'../curso.html?bloque=2', kw:['sistema operativo','linux','windows server','proceso','kernel','sistema de ficheros','raid','virtualización','contenedor','cpu','procesador','memoria ram'] },
];
function detectarTema(txt) {
const t = txt.toLowerCase();
for (const tema of TEMAS_KW) {
if (tema.kw.some(k => t.includes(k))) return tema;
}
return { id:'otro', label:'Otros / Material general', link:'../curso.html' };
}
// ── Elementos DOM ────────────────────────────────────────────
const selExamen = document.getElementById('sel-examen');
const btnIniciar = document.getElementById('btn-iniciar');
const btnSiguiente = document.getElementById('btn-siguiente');
const seccionQuiz = document.getElementById('seccion-quiz');
const seccionFinal = document.getElementById('seccion-final');
const seccionEmpty = document.getElementById('seccion-empty');
const seccionSupSel = document.getElementById('seccion-supuesto-sel');
const supCardsWrap = document.getElementById('sup-cards');
const contextoPanel = document.getElementById('contexto-pregunta');
const examPdfsPanel = document.getElementById('exam-pdfs');
// ── Mapa de PDFs por examen ───────────────────────────────────
const EXAM_PDFS = {
'data/TAI_2019.json': [
{ label: 'Cuestionario oficial', icon: 'fa-file-alt', url: 'pdfs/cues_1er_ejer_TAI-L_oep19_154AB89SD658.pdf' },
{ label: 'Plantilla definitiva', icon: 'fa-check-square', url: 'pdfs/Plantilla_defTAI-L1ejer_154AB89SD658.pdf' },
{ label: 'Plantilla provisional', icon: 'fa-clipboard', url: 'pdfs/plant_prov_1er_ejer_TAI-L_oep19_154AB89SD658.pdf' },
{ label: 'Material adicional (supuesto)', icon: 'fa-book-open', url: 'pdfs/07TAIL_154AB89SD658.pdf' },
],
'data/TAI_2023.json': [
{ label: 'Cuestionario oficial', icon: 'fa-file-alt', url: 'pdfs/Cuestionario TAI-L_2023.pdf' },
{ label: 'Plantilla de respuestas', icon: 'fa-check-square', url: 'pdfs/PlantillaRespuestas TAI-L_2023.pdf' },
],
'data/TAI_2024A.json': [
{ label: 'Cuestionario oficial', icon: 'fa-file-alt', url: 'pdfs/Cuestionario_TAI_LI_2024_A_M8L91VL1CL_154AB89SD658.pdf' },
{ label: 'Plantilla de respuestas', icon: 'fa-check-square', url: 'pdfs/Plantilla_Respuestas_PROV_TAI_LI_2024_A_6J5MFQ8OEN_154AB89SD658.pdf' },
{ label: 'Material supuesto II', icon: 'fa-book-open', url: 'data/tai_2024A_supuesto2.md' },
],
'data/TAI_2024B.json': [
{ label: 'Cuestionario oficial', icon: 'fa-file-alt', url: 'pdfs/Cuestionario_TAI_LI_2024_B_DNFGFEK45R_154AB89SD658.pdf' },
{ label: 'Plantilla de respuestas', icon: 'fa-check-square', url: 'pdfs/Plantilla_Respuestas_PROV_TAI_LI_2024_B_JQE95HBC1R_154AB89SD658.pdf' },
],
};
const elPreguntaNum = document.getElementById('pregunta-num');
const elPreguntaTxt = document.getElementById('pregunta-txt');
const elOpciones = document.getElementById('opciones');
const elFeedback = document.getElementById('feedback');
const elAciertos = document.getElementById('val-aciertos');
const elFallos = document.getElementById('val-fallos');
const elProgreso = document.getElementById('val-progreso');
const elNota = document.getElementById('val-nota');
// ── Eventos ──────────────────────────────────────────────────
btnIniciar.addEventListener('click', iniciarExamen);
btnSiguiente.addEventListener('click', siguiente);
selExamen.addEventListener('change', () => {
btnIniciar.disabled = !selExamen.value;
renderExamPdfs(selExamen.value);
});
function renderExamPdfs(url) {
const pdfs = EXAM_PDFS[url];
if (!pdfs || !pdfs.length) { examPdfsPanel.style.display = 'none'; return; }
examPdfsPanel.innerHTML =
'<span class="exam-pdfs-label"><i class="fas fa-file-pdf"></i> Documentos INAP:</span>' +
pdfs.map(p =>
`<a href="${encodeURI(p.url)}" target="_blank" rel="noopener" class="exam-pdf-link">` +
`<i class="fas ${p.icon}"></i> ${escHtml(p.label)}</a>`
).join('');
examPdfsPanel.style.display = 'flex';
}
// ── Funciones ────────────────────────────────────────────────
async function iniciarExamen() {
const url = selExamen.value;
if (!url) return;
btnIniciar.disabled = true;
btnIniciar.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Cargando…';
try {
const datos = await fetch(url).then(r => r.json());
const todas = Array.isArray(datos) ? datos : (datos.preguntas || []);
// Separar preguntas tipo test de supuestos prácticos
const testQs = todas.filter(p => !p.contexto?.supuesto);
const supuestoQs = todas.filter(p => p.contexto?.supuesto);
preguntas = mezclar(testQs);
supuestosData = {};
for (const p of supuestoQs) {
const nombre = p.contexto.supuesto;
if (!supuestosData[nombre]) supuestosData[nombre] = [];
supuestosData[nombre].push(p);
}
} catch (e) {
alert('Error cargando el examen. Comprueba la ruta del fichero.');
btnIniciar.disabled = false;
btnIniciar.innerHTML = '<i class="fas fa-play"></i> Iniciar';
return;
}
faseActual = 'test';
indice = 0;
aciertos = 0;
fallos = 0;
respondida = false;
preguntasFalladas = [];
mostrarSolo('quiz');
actualizarMarcador();
mostrarPregunta();
btnIniciar.disabled = false;
btnIniciar.innerHTML = '<i class="fas fa-redo"></i> Reiniciar';
}
function mostrarSolo(seccion) {
seccionEmpty.style.display = seccion === 'empty' ? 'block' : 'none';
seccionQuiz.style.display = seccion === 'quiz' ? 'block' : 'none';
seccionFinal.style.display = seccion === 'final' ? 'block' : 'none';
seccionSupSel.style.display = seccion === 'supsel' ? 'block' : 'none';
}
function mostrarSelectorSupuesto() {
supCardsWrap.innerHTML = '';
for (const [nombre, pregs] of Object.entries(supuestosData)) {
const ctx = pregs[0]?.contexto || {};
const ref = ctx.referencia_diagrama || ctx.referencia || null;
const esImg = ref && /\.(png|jpg|jpeg|gif|webp)$/i.test(ref);
const esPdf = ref && /\.pdf$/i.test(ref);
const card = document.createElement('div');
card.className = 'sup-card';
card.innerHTML = `
<div class="sup-card-header">
<i class="fas fa-file-code"></i>
<strong>${escHtml(nombre)}</strong>
<span class="sup-card-num">${pregs.length} preguntas</span>
</div>
<p class="sup-card-desc">${escHtml(ctx.descripcion || '')}</p>
${esImg ? `<div class="sup-material"><img src="data/${ref}" alt="Material ${escHtml(nombre)}" style="max-width:100%;border-radius:6px;margin:.5rem 0"></div>` : ''}
${esPdf ? `<div class="sup-material"><a href="data/${ref}" target="_blank" rel="noopener" class="btn btn-outline" style="font-size:.85rem"><i class="fas fa-file-pdf"></i> Ver enunciado (PDF)</a></div>` : ''}
<button class="btn btn-primary" style="margin-top:.75rem" onclick="iniciarSupuesto('${nombre.replace(/'/g, "\\'")}')"><i class="fas fa-play"></i> Practicar este supuesto</button>
`;
supCardsWrap.appendChild(card);
}
mostrarSolo('supsel');
}
function iniciarSupuesto(nombre) {
preguntas = supuestosData[nombre] || [];
faseActual = 'supuesto';
indice = 0;
aciertos = 0;
fallos = 0;
respondida = false;
preguntasFalladas = [];
mostrarSolo('quiz');
actualizarMarcador();
mostrarPregunta();
}
function mostrarPregunta() {
respondida = false;
btnSiguiente.style.display = 'none';
elFeedback.className = 'question-feedback';
elFeedback.textContent = '';
if (indice >= preguntas.length) {
if (faseActual === 'test' && Object.keys(supuestosData).length > 0) {
mostrarSelectorSupuesto();
} else {
finalizarExamen();
}
return;
}
const p = preguntas[indice];
elPreguntaNum.textContent = `Pregunta ${indice + 1} de ${preguntas.length}`;
elPreguntaTxt.textContent = p.pregunta;
// Mostrar contexto si estamos en un supuesto práctico
if (faseActual === 'supuesto' && p.contexto?.descripcion) {
contextoPanel.style.display = 'block';
contextoPanel.innerHTML = `<i class="fas fa-info-circle"></i> <strong>Contexto:</strong> ${escHtml(p.contexto.descripcion)}`;
} else {
contextoPanel.style.display = 'none';
}
elOpciones.innerHTML = '';
for (const [letra, texto] of Object.entries(p.opciones)) {
const li = document.createElement('li');
li.className = 'options-list__item';
const label = document.createElement('label');
label.className = 'option-label';
label.innerHTML = `
<input type="radio" name="resp" value="${letra}">
<span class="option-letter">${letra.toUpperCase()})</span>
<span>${escHtml(texto)}</span>`;
label.querySelector('input').addEventListener('change', () => {
if (!respondida) comprobar(p);
});
li.appendChild(label);
elOpciones.appendChild(li);
}
actualizarMarcador();
}
function comprobar(p) {
respondida = true;
const marcada = document.querySelector('input[name="resp"]:checked');
if (!marcada) return;
// Deshabilitar todos los radio
document.querySelectorAll('input[name="resp"]').forEach(r => r.disabled = true);
// Marcar opciones
document.querySelectorAll('.option-label').forEach(label => {
const val = label.querySelector('input').value;
if (val === p.correcta) label.classList.add('correct');
else if (val === marcada.value) label.classList.add('incorrect');
});
if (marcada.value === p.correcta) {
aciertos++;
elFeedback.textContent = '✔ ¡Correcto!';
elFeedback.className = 'question-feedback show ok';
} else {
fallos++; preguntasFalladas.push({ pregunta: p, elegida: marcada.value }); elFeedback.textContent = `✘ Incorrecto. La respuesta correcta era la ${p.correcta.toUpperCase()})`;
elFeedback.className = 'question-feedback show ko';
}
actualizarMarcador();
btnSiguiente.style.display = 'inline-flex';
btnSiguiente.focus();
}
function siguiente() {
indice++;
mostrarPregunta();
// mostrarPregunta() detecta si el índice superó el total y actúa
}
function actualizarMarcador() {
const contestadas = aciertos + fallos;
const puntosNetos = aciertos - fallos / 3;
const nota = contestadas > 0
? Math.max(0, (puntosNetos / preguntas.length) * 10).toFixed(2)
: '—';
elAciertos.textContent = aciertos;
elFallos.textContent = fallos;
elProgreso.textContent = `${contestadas} / ${preguntas.length}`;
elNota.textContent = nota;
}
function finalizarExamen() {
mostrarSolo('final');
const total = preguntas.length;
const puntosNetos = aciertos - fallos / 3;
const nota = Math.max(0, (puntosNetos / total) * 10).toFixed(2);
const sinRespuesta = total - aciertos - fallos;
document.getElementById('final-nota').textContent = nota;
document.getElementById('final-aciertos').textContent = aciertos;
document.getElementById('final-fallos').textContent = fallos;
document.getElementById('final-sin').textContent = sinRespuesta;
document.getElementById('final-total').textContent = total;
const notaNum = parseFloat(nota);
const color = notaNum >= 5 ? 'var(--success)' : notaNum >= 4 ? 'var(--warning)' : 'var(--error)';
document.getElementById('final-nota').style.color = color;
renderRepaso();
}
function renderRepaso() {
const wrap = document.getElementById('repaso-wrap');
if (!wrap) return;
if (preguntasFalladas.length === 0) {
wrap.innerHTML = '<p class="repaso-perfecto"><i class="fas fa-star"></i> ¡Sin fallos! Dominas todo el temario de este examen.</p>';
wrap.style.display = 'block';
return;
}
// Agrupar fallos por tema detectado
const grupos = {};
for (const { pregunta, elegida } of preguntasFalladas) {
const tema = detectarTema(pregunta.pregunta);
if (!grupos[tema.id]) grupos[tema.id] = { tema, items: [] };
grupos[tema.id].items.push({ pregunta, elegida });
}
const n = preguntasFalladas.length;
wrap.innerHTML = `
<h3 class="repaso-titulo"><i class="fas fa-exclamation-triangle"></i> Necesitas repasar</h3>
<p class="repaso-intro">Has fallado <strong>${n}</strong> pregunta${n > 1 ? 's' : ''}. Estos son los temas donde debes reforzar:</p>
${Object.values(grupos).map(g => `
<details class="repaso-grupo" open>
<summary class="repaso-tema">
<span class="repaso-tema-name"><i class="fas fa-book"></i> ${escHtml(g.tema.label)}</span>
<span class="repaso-badge">${g.items.length} fallo${g.items.length > 1 ? 's' : ''}</span>
</summary>
<ul class="repaso-lista">
${g.items.map(({ pregunta: p, elegida }) => `
<li class="repaso-item">
<p class="repaso-q">${escHtml(p.pregunta.length > 140 ? p.pregunta.slice(0,140)+'…' : p.pregunta)}</p>
<div class="repaso-answers">
<span class="repaso-ans ko"><i class="fas fa-times"></i> Tu resp.: ${elegida.toUpperCase()}) ${escHtml((p.opciones[elegida]||'').length > 70 ? p.opciones[elegida].slice(0,70)+'' : (p.opciones[elegida]||''))}</span>
<span class="repaso-ans ok"><i class="fas fa-check"></i> Correcta: ${p.correcta.toUpperCase()}) ${escHtml((p.opciones[p.correcta]||'').length > 70 ? p.opciones[p.correcta].slice(0,70)+'' : (p.opciones[p.correcta]||''))}</span>
</div>
</li>
`).join('')}
</ul>
<a href="${g.tema.link}" class="repaso-link-tema"><i class="fas fa-book-open"></i> Estudiar este tema</a>
</details>
`).join('')}
`;
wrap.style.display = 'block';
}
// ── Helpers ───────────────────────────────────────────────────
function mezclar(arr) {
const a = [...arr];
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
function escHtml(str) {
return str
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}

54
curso.html Normal file
View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAI AGE | Temario</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
<!-- ── Topbar ─────────────────────────────────────────── -->
<nav class="topbar">
<button class="menu-toggle" id="menu-toggle" aria-label="Menú">
<i class="fas fa-bars"></i>
</button>
<a href="index.html" class="topbar-brand" style="text-decoration:none">
<i class="fas fa-graduation-cap"></i> TAI AGE
</a>
<nav class="topbar-nav">
<a href="index.html">Inicio</a>
<a href="curso.html" class="active">Temario</a>
<a href="cuestionarios/index.html">Cuestionarios</a>
<a href="noticias.html"><i class="fas fa-bell"></i> Noticias</a>
</nav>
<span class="topbar-progress" id="topbar-progress">1 / 33</span>
</nav>
<!-- ── Layout ─────────────────────────────────────────── -->
<div class="player-layout">
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<!-- Rellena js/curso.js -->
</aside>
<!-- Content -->
<main class="content-pane">
<div id="lesson-content">
<div class="spinner"><i class="fas fa-circle-notch fa-spin"></i></div>
</div>
</main>
</div>
<!-- ── Scripts ────────────────────────────────────────── -->
<!-- marked.js para renderizar Markdown en el cliente -->
<script src="https://cdn.jsdelivr.net/npm/marked@12/marked.min.js"></script>
<script src="js/temas.js"></script>
<script src="js/curso.js"></script>
</body>
</html>

194
index.html Normal file
View File

@ -0,0 +1,194 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAI AGE | Temario oposición</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
<!-- ── Topbar ─────────────────────────────────────────── -->
<nav class="topbar">
<span class="topbar-brand"><i class="fas fa-graduation-cap"></i> TAI AGE</span>
<nav class="topbar-nav">
<a href="index.html" class="active">Inicio</a>
<a href="curso.html">Temario</a>
<a href="cuestionarios/index.html">Cuestionarios</a>
<a href="noticias.html">Noticias</a>
</nav>
</nav>
<!-- ── Banner cambios INAP ──────────────────────────────── -->
<div id="inap-cambio-banner" class="inap-cambio-banner" style="display:none">
<div class="inap-cambio-inner">
<i class="fas fa-exclamation-circle"></i>
<div class="inap-cambio-txt">
<strong>¡La página de la convocatoria TAI ha cambiado!</strong>
<span>El INAP ha actualizado la información del proceso selectivo.</span>
</div>
<a class="inap-banner-link btn btn-primary" href="#" target="_blank" rel="noopener" style="white-space:nowrap">
<i class="fas fa-external-link-alt"></i> Ver cambios
</a>
<button class="inap-banner-close" onclick="cerrarBannerInap()" aria-label="Cerrar">
<i class="fas fa-times"></i>
</button>
</div>
</div>
<!-- ── Hero ──────────────────────────────────────────── -->
<section class="home-hero">
<h1><i class="fas fa-laptop-code"></i> Temario TAI AGE</h1>
<p>Técnico/a en Informática Administración General del Estado.<br>
Todos los bloques, todos los temas. Sin filtros.</p>
<div class="home-stats">
<div class="stat-item">
<div class="stat-num">4</div>
<div class="stat-lbl">Bloques</div>
</div>
<div class="stat-item">
<div class="stat-num">33</div>
<div class="stat-lbl">Temas</div>
</div>
<div class="stat-item">
<div class="stat-num">4</div>
<div class="stat-lbl">Exámenes reales</div>
</div>
</div>
<div style="display:flex;gap:1rem;justify-content:center;flex-wrap:wrap;">
<a href="curso.html" class="btn btn-primary"><i class="fas fa-play"></i> Empezar el temario</a>
<a href="cuestionarios/index.html" class="btn btn-outline"><i class="fas fa-question-circle"></i> Practicar exámenes</a>
</div>
<!-- Cuenta atrás -->
<div class="countdown-wrap">
<div class="countdown-label"><i class="fas fa-calendar-alt"></i> Examen TAI · 23 de mayo de 2026</div>
<div class="countdown-units" id="countdown">
<div class="cd-unit"><span class="cd-num" id="cd-days">--</span><span class="cd-lbl">días</span></div>
<div class="cd-sep">:</div>
<div class="cd-unit"><span class="cd-num" id="cd-hours">--</span><span class="cd-lbl">horas</span></div>
<div class="cd-sep">:</div>
<div class="cd-unit"><span class="cd-num" id="cd-mins">--</span><span class="cd-lbl">min</span></div>
<div class="cd-sep">:</div>
<div class="cd-unit"><span class="cd-num" id="cd-secs">--</span><span class="cd-lbl">seg</span></div>
</div>
</div>
</section>
<script src="js/inap-watch.js"></script>
<script>
(function () {
const target = new Date('2026-05-23T00:00:00');
function tick() {
const diff = target - Date.now();
if (diff <= 0) {
document.getElementById('countdown').innerHTML = '<span style="color:var(--accent);font-size:1.4rem">¡Hoy es el día! 🎯</span>';
return;
}
const d = Math.floor(diff / 86400000);
const h = Math.floor((diff % 86400000) / 3600000);
const m = Math.floor((diff % 3600000) / 60000);
const s = Math.floor((diff % 60000) / 1000);
document.getElementById('cd-days').textContent = String(d).padStart(2, '0');
document.getElementById('cd-hours').textContent = String(h).padStart(2, '0');
document.getElementById('cd-mins').textContent = String(m).padStart(2, '0');
document.getElementById('cd-secs').textContent = String(s).padStart(2, '0');
}
tick();
setInterval(tick, 1000);
})();
</script>
<!-- ── Bloques ────────────────────────────────────────── -->
<section class="bloques-section">
<h2>Bloques del temario</h2>
<div class="bloques-grid">
<article class="bloque-card" onclick="location.href='curso.html?bloque=1&tema=1'">
<div class="bloque-num">Bloque I</div>
<h3>Organización del Estado y Administración electrónica</h3>
<p>Constitución, EBEP, igualdad, identidad digital, protección de datos, sede electrónica.</p>
<ul class="bloque-temas-list">
<li>T1 Constitución Española de 1978</li>
<li>T2 Cortes Generales y Tribunal Constitucional</li>
<li>T3 El Gobierno</li>
<li>T4 EBEP, transparencia y ODS</li>
<li>T5 Igualdad y discapacidad</li>
<li>T6 Sociedad de la información e identidad digital</li>
<li>T7 Protección de datos</li>
<li>T8 Acceso electrónico a los servicios públicos</li>
<li>T9 Sedes e infraestructuras electrónicas</li>
</ul>
</article>
<article class="bloque-card" onclick="location.href='curso.html?bloque=2&tema=1'">
<div class="bloque-num">Bloque II</div>
<h3>Tecnología básica</h3>
<p>Hardware, periféricos, estructuras de datos, sistemas operativos, BBDD.</p>
<ul class="bloque-temas-list">
<li>T1 Informática básica y arquitectura</li>
<li>T2 Periféricos y almacenamiento</li>
<li>T3 Tipos de datos y algoritmos</li>
<li>T4 Sistemas operativos</li>
<li>T5 Sistemas gestores de BBDD</li>
</ul>
</article>
<article class="bloque-card" onclick="location.href='curso.html?bloque=3&tema=1'">
<div class="bloque-num">Bloque III</div>
<h3>Desarrollo de sistemas</h3>
<p>Modelado de datos, SQL, POO, Java EE, web, UML, pruebas y control de versiones.</p>
<ul class="bloque-temas-list">
<li>T1 Modelado y diseño de BBDD</li>
<li>T2 Lenguajes de programación</li>
<li>T3 SQL y procedimientos almacenados</li>
<li>T4 POO y patrones de diseño</li>
<li>T5 Java EE / .NET</li>
<li>T6 Arquitecturas cliente/servidor y web services</li>
<li>T7 Desarrollo web front-end y back-end</li>
<li>T8 Accesibilidad y seguridad en desarrollo</li>
<li>T9 Repositorios y metodologías</li>
</ul>
</article>
<article class="bloque-card" onclick="location.href='curso.html?bloque=4&tema=1'">
<div class="bloque-num">Bloque IV</div>
<h3>Sistemas y comunicaciones</h3>
<p>Administración de SO, BBDD, correo, redes, seguridad, TCP/IP, Internet, VPN.</p>
<ul class="bloque-temas-list">
<li>T1 Administración del SO</li>
<li>T2 Administración de BBDD y virtualización</li>
<li>T3 Servidores de correo y contenedores</li>
<li>T4 Administración de redes de área local</li>
<li>T5 Seguridad de sistemas</li>
<li>T6 Comunicaciones y redes</li>
<li>T7 Modelos TCP/IP y OSI</li>
<li>T8 Internet y HTTP/S</li>
<li>T9 Seguridad perimetral y VPN</li>
<li>T10 Redes locales</li>
</ul>
</article>
</div>
</section>
<!-- ── Cuestionarios banner ───────────────────────────── -->
<section class="quiz-card">
<div class="quiz-banner">
<div class="quiz-banner-icon"><i class="fas fa-file-alt" style="color:var(--accent)"></i></div>
<div>
<h3>Exámenes reales TAI (2019 2024)</h3>
<p>Practica con preguntas de convocatorias anteriores: TAI 2019, TAI 2023, TAI 2024 A y B.</p>
</div>
<a href="cuestionarios/index.html" class="btn btn-primary">
<i class="fas fa-play"></i> Practicar ahora
</a>
</div>
</section>
</body>
</html>

202
js/curso.js Normal file
View File

@ -0,0 +1,202 @@
/**
* js/curso.js
* Lógica del visor de curso: sidebar, carga de markdown y navegación.
* Depende de: js/temas.js + marked.js (CDN)
*/
// ── Estado ──────────────────────────────────────────────────
let currentBloque = 1;
let currentTema = 1;
// ── Init ────────────────────────────────────────────────────
document.addEventListener('DOMContentLoaded', () => {
const params = new URLSearchParams(location.search);
currentBloque = parseInt(params.get('bloque') || '1', 10);
currentTema = parseInt(params.get('tema') || '1', 10);
buildSidebar();
loadTema(currentBloque, currentTema);
});
// ── Build sidebar ───────────────────────────────────────────
function buildSidebar() {
const sidebar = document.querySelector('.sidebar');
if (!sidebar) return;
let html = '<div class="sidebar-header">TEMARIO TAI AGE</div>';
for (const bloque of TEMARIO) {
const isOpenBloque = (bloque.id === currentBloque);
html += `
<div class="bloque-group ${isOpenBloque ? 'open' : ''}" id="bloque-group-${bloque.id}">
<div class="bloque-group-header" onclick="toggleBloque(${bloque.id})">
<span style="color:${bloque.color}">&#x25A0;</span>
<span>Bloque ${toRoman(bloque.id)}</span>
<span class="chevron">&#9654;</span>
</div>
<div class="bloque-group-items">`;
for (const tema of bloque.temas) {
const isActive = (bloque.id === currentBloque && tema.num === currentTema);
const shortTitle = shortTemaTitle(tema.titulo);
html += `
<div class="sidebar-item ${isActive ? 'active' : ''}"
id="item-${bloque.id}-${tema.num}"
onclick="navigateTo(${bloque.id}, ${tema.num})">
<span class="item-num">${tema.num}.</span>
<span>${shortTitle}</span>
</div>`;
}
html += `
</div>
</div>`;
}
sidebar.innerHTML = html;
}
// ── Toggle bloque ────────────────────────────────────────────
function toggleBloque(id) {
const group = document.getElementById(`bloque-group-${id}`);
if (group) group.classList.toggle('open');
}
// ── Navigate ─────────────────────────────────────────────────
function navigateTo(bloqueId, temaNum) {
currentBloque = bloqueId;
currentTema = temaNum;
const url = new URL(location.href);
url.searchParams.set('bloque', bloqueId);
url.searchParams.set('tema', temaNum);
history.pushState({}, '', url.toString());
updateSidebarActive();
loadTema(bloqueId, temaNum);
// Cerrar sidebar en móvil
document.querySelector('.sidebar')?.classList.remove('open');
}
// ── Load markdown ─────────────────────────────────────────────
async function loadTema(bloqueId, temaNum) {
const bloque = TEMARIO.find(b => b.id === bloqueId);
if (!bloque) return showError('Bloque no encontrado.');
const tema = bloque.temas.find(t => t.num === temaNum);
if (!tema) return showError('Tema no encontrado.');
const content = document.getElementById('lesson-content');
if (!content) return;
content.innerHTML = '<div class="spinner"><i class="fas fa-circle-notch fa-spin"></i></div>';
try {
const resp = await fetch(tema.archivo);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const md = await resp.text();
renderMarkdown(md, tema, bloque, bloqueId, temaNum);
} catch (e) {
showError(`No se ha podido cargar <strong>${tema.archivo}</strong>.<br><small>${e.message}</small>`);
}
}
function renderMarkdown(md, tema, bloque, bloqueId, temaNum) {
const { prev, next, pos, total } = getNavigation(bloqueId, temaNum);
const prevBtn = prev
? `<button class="lesson-nav-btn" onclick="navigateTo(${prev.bloqueId},${prev.temaNum})">
<i class="fas fa-chevron-left"></i> Anterior
</button>`
: `<button class="lesson-nav-btn disabled"><i class="fas fa-chevron-left"></i> Anterior</button>`;
const nextBtn = next
? `<button class="lesson-nav-btn" onclick="navigateTo(${next.bloqueId},${next.temaNum})">
Siguiente <i class="fas fa-chevron-right"></i>
</button>`
: `<button class="lesson-nav-btn disabled">Siguiente <i class="fas fa-chevron-right"></i></button>`;
const html = marked.parse(md);
document.getElementById('lesson-content').innerHTML = `
<div class="md-body">${html}</div>
<nav class="lesson-nav" aria-label="Navegación entre temas">
${prevBtn}
<span class="lesson-pos">Tema ${pos} de ${total} &nbsp;·&nbsp; Bloque ${toRoman(bloqueId)}</span>
${nextBtn}
</nav>`;
// Actualizar título de pestaña
document.title = `T${temaNum} Bloque ${toRoman(bloqueId)} | TAIAGE`;
// Scroll arriba
document.querySelector('.content-pane')?.scrollTo(0, 0);
// Actualizar progress en topbar
updateTopbarProgress(pos, total);
}
function showError(msg) {
document.getElementById('lesson-content').innerHTML = `
<div class="empty-state">
<i class="fas fa-exclamation-triangle" style="color:var(--warning)"></i>
<p>Error cargando el tema</p>
<p style="font-size:.85rem;color:var(--text-muted)">${msg}</p>
</div>`;
}
// ── Sidebar active ────────────────────────────────────────────
function updateSidebarActive() {
document.querySelectorAll('.sidebar-item').forEach(el => el.classList.remove('active'));
const el = document.getElementById(`item-${currentBloque}-${currentTema}`);
if (el) {
el.classList.add('active');
el.scrollIntoView({ block: 'nearest' });
}
// Abrir bloque activo
document.querySelectorAll('.bloque-group').forEach(g => g.classList.remove('open'));
document.getElementById(`bloque-group-${currentBloque}`)?.classList.add('open');
}
// ── Topbar progress ───────────────────────────────────────────
function updateTopbarProgress(pos, total) {
const el = document.querySelector('.topbar-progress');
if (el) el.textContent = `${pos} / ${total}`;
}
// ── Hamburger (móvil) ─────────────────────────────────────────
document.addEventListener('DOMContentLoaded', () => {
const toggle = document.getElementById('menu-toggle');
if (toggle) {
toggle.addEventListener('click', () => {
document.querySelector('.sidebar').classList.toggle('open');
});
}
// Cerrar sidebar al pulsar fuera (móvil)
document.addEventListener('click', e => {
if (window.innerWidth > 768) return;
const sidebar = document.querySelector('.sidebar');
if (sidebar && !sidebar.contains(e.target) && e.target.id !== 'menu-toggle') {
sidebar.classList.remove('open');
}
});
});
// ── broswer back/forward ──────────────────────────────────────
window.addEventListener('popstate', () => {
const params = new URLSearchParams(location.search);
currentBloque = parseInt(params.get('bloque') || '1', 10);
currentTema = parseInt(params.get('tema') || '1', 10);
updateSidebarActive();
loadTema(currentBloque, currentTema);
});
// ── Helpers ───────────────────────────────────────────────────
function toRoman(n) {
return ['', 'I', 'II', 'III', 'IV', 'V'][n] ?? n;
}
/**
* Acorta el título del tema al primer fragmento antes de "." o ":" (máx 55 chars).
*/
function shortTemaTitle(titulo) {
const first = titulo.split(/[.:]/)[0].trim();
return first.length > 55 ? first.slice(0, 53) + '…' : first;
}

106
js/inap-watch.js Normal file
View File

@ -0,0 +1,106 @@
'use strict';
/**
* inap-watch.js
* Comprueba si la página de la convocatoria TAI del INAP ha cambiado
* desde la última visita. Si detecta cambios, muestra un banner en la
* página de inicio.
*
* Estrategia:
* 1. Descarga la página via un proxy CORS (allorigins.win)
* 2. Extrae solo el texto visible (sin scripts/estilos) y normaliza espacios
* 3. Calcula un hash djb2 del texto
* 4. Compara con el hash almacenado en localStorage
* 5. Si difiere muestra el banner y guarda el nuevo hash
* (el usuario puede silenciarlo con "Lo he visto")
*/
const INAP_URL = 'https://sede.inap.gob.es/es/procedimientos-y-servicios/seleccion/procesos-selectivos-de-cuerpos-y-escalas-generales/cuerpo-de-tecnicos-auxiliares-de-informatica-de-la-administracion-del-estado-ingreso-libre-convocatoria-2025';
const PROXY = 'https://api.allorigins.win/get?url=';
const STORE_KEY = 'inap_tai_hash';
const SEEN_KEY = 'inap_tai_hash_seen';
function djb2(str) {
let h = 5381;
for (let i = 0; i < str.length; i++) {
h = ((h << 5) + h) ^ str.charCodeAt(i);
h = h >>> 0; // mantener 32 bits sin signo
}
return h.toString(16);
}
function extraerTexto(html) {
// Eliminar scripts, estilos, comentarios y atributos dinámicos
return html
.replace(/<script[\s\S]*?<\/script>/gi, '')
.replace(/<style[\s\S]*?<\/style>/gi, '')
.replace(/<!--[\s\S]*?-->/g, '')
.replace(/<[^>]+>/g, ' ') // quitar etiquetas
.replace(/\s+/g, ' ') // normalizar espacios
.trim();
}
function mostrarBanner(urlPagina) {
const banner = document.getElementById('inap-cambio-banner');
if (!banner) return;
banner.style.display = 'flex';
banner.querySelector('.inap-banner-link').href = urlPagina;
}
function ocultarBanner() {
const banner = document.getElementById('inap-cambio-banner');
if (!banner) return;
banner.style.display = 'none';
// Marcar como visto para esta versión del hash
const hash = localStorage.getItem(STORE_KEY);
if (hash) localStorage.setItem(SEEN_KEY, hash);
}
async function comprobarCambios() {
// Si el navegador no tiene fetch o localStorage, salir silenciosamente
if (typeof fetch === 'undefined' || typeof localStorage === 'undefined') return;
const hashPrevio = localStorage.getItem(STORE_KEY);
const hashVisto = localStorage.getItem(SEEN_KEY);
// Si ya hay cambio pendiente que el usuario aún no ha marcado como visto → mostrar banner
if (hashPrevio && hashPrevio !== hashVisto) {
mostrarBanner(INAP_URL);
// Seguir para comprobar si hay cambios adicionales desde entonces
}
try {
const resp = await fetch(PROXY + encodeURIComponent(INAP_URL), { cache: 'no-store' });
if (!resp.ok) return;
const data = await resp.json();
const texto = extraerTexto(data.contents || '');
if (!texto) return;
const hashNuevo = djb2(texto);
if (!hashPrevio) {
// Primera visita: guardar referencia silenciosamente
localStorage.setItem(STORE_KEY, hashNuevo);
localStorage.setItem(SEEN_KEY, hashNuevo);
return;
}
if (hashNuevo !== hashPrevio) {
// La página cambió
localStorage.setItem(STORE_KEY, hashNuevo);
mostrarBanner(INAP_URL);
}
} catch (_) {
// Fallo de red o proxy caído: no hacer nada, sin ruido
}
}
// ── Arranque ───────────────────────────────────────────────────
// Exponer función de cierre al botón del banner
window.cerrarBannerInap = ocultarBanner;
// Ejecutar cuando la página esté lista (sin bloquear el render)
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', comprobarCambios);
} else {
comprobarCambios();
}

84
js/noticias.js Normal file
View File

@ -0,0 +1,84 @@
'use strict';
// ── Configuración ──────────────────────────────────────────────
// BOE Sección II-B: Oposiciones, concursos y vacantes
const BOE_RSS = 'https://www.boe.es/rss/boe_dias.php?s=2B';
// Proxy CORS gratuito que convierte RSS a JSON
const RSS2JSON = 'https://api.rss2json.com/v1/api.json?rss_url=';
// Palabras clave para resaltar entradas de interés informático/TAI
const KW_TAI = /\b(TAI|T\.A\.I|técnico[a]? (de )?administración (general |de la )?inform|inform[aá]tic|sistemas?\s+de\s+información|AGE\b)/i;
// ── Carga del feed BOE ─────────────────────────────────────────
async function cargarBOE() {
const panel = document.getElementById('boe-items');
const badge = document.getElementById('boe-fecha');
try {
const resp = await fetch(RSS2JSON + encodeURIComponent(BOE_RSS));
if (!resp.ok) throw new Error('HTTP ' + resp.status);
const data = await resp.json();
if (data.status !== 'ok') throw new Error('Feed error: ' + data.message);
const items = data.items || [];
if (items.length === 0) {
panel.innerHTML = '<p class="news-empty">No hay publicaciones recientes en esta sección.</p>';
badge.textContent = 'Sin datos';
return;
}
// Separar: primero los que coincidan con TAI/informática, luego el resto
const importantes = items.filter(it => KW_TAI.test(it.title + ' ' + (it.description || '')));
const resto = items.filter(it => !KW_TAI.test(it.title + ' ' + (it.description || '')));
const ordenados = [...importantes, ...resto].slice(0, 25);
// Fecha de la última actualización del feed
const fechaFeed = data.feed?.lastBuildDate
? new Date(data.feed.lastBuildDate).toLocaleDateString('es-ES', { day:'2-digit', month:'short', year:'numeric' })
: 'hoy';
badge.textContent = 'Act. ' + fechaFeed;
panel.innerHTML = ordenados.map(item => {
const esTAI = KW_TAI.test(item.title + ' ' + (item.description || ''));
const fecha = item.pubDate
? new Date(item.pubDate).toLocaleDateString('es-ES', { day:'2-digit', month:'short', year:'numeric' })
: '';
const titulo = escHtml(truncar(item.title || 'Sin título', 120));
return `
<a href="${escHtml(item.link || '#')}" target="_blank" rel="noopener"
class="news-item${esTAI ? ' news-item--tai' : ''}">
<div class="news-item-meta">
${esTAI
? '<span class="news-tag-tai"><i class="fas fa-star"></i> TAI / Informática</span>'
: ''}
<span class="news-date">${fecha}</span>
</div>
<div class="news-title">${titulo}</div>
</a>`;
}).join('');
} catch (err) {
console.warn('[noticias.js] Error cargando BOE:', err.message);
badge.textContent = 'Error';
panel.innerHTML = `
<div class="news-error">
<i class="fas fa-exclamation-triangle"></i>
No se pudo cargar el feed automáticamente. Consulta el BOE directamente:
<a href="https://www.boe.es/diario_boe/ultimos_dias.php" target="_blank" rel="noopener">
Últimas publicaciones BOE <i class="fas fa-external-link-alt"></i>
</a>
</div>`;
}
}
// ── Helpers ────────────────────────────────────────────────────
function escHtml(s) {
return (s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
function truncar(s, max) {
return s.length > max ? s.slice(0, max) + '…' : s;
}
// ── Arranque ───────────────────────────────────────────────────
cargarBOE();

226
js/temas.js Normal file
View File

@ -0,0 +1,226 @@
/**
* js/temas.js
* Mapa completo del temario TAI AGE.
* Cada bloque incluye todos los temas del README.md exactamente.
*/
const TEMARIO = [
{
id: 1,
titulo: "Organización del Estado y Administración electrónica",
color: "#007acc",
temas: [
{
num: 1,
titulo: "La Constitución Española de 1978. Derechos y deberes fundamentales. Su garantía y suspensión. La Corona: funciones constitucionales del Rey.",
archivo: "bloque1/tema1.md"
},
{
num: 2,
titulo: "Las Cortes Generales: atribuciones del Congreso de los Diputados y del Senado. El Tribunal Constitucional: composición y atribuciones. El Defensor del Pueblo.",
archivo: "bloque1/tema2.md"
},
{
num: 3,
titulo: "El Gobierno: composición, nombramiento y cese. Las funciones del Gobierno. Relaciones entre el Gobierno y las Cortes Generales.",
archivo: "bloque1/tema3.md"
},
{
num: 4,
titulo: "Estatuto Básico del Empleado Público: derechos y deberes, provisión de puestos, promoción interna, carrera profesional, situaciones administrativas, incompatibilidades y régimen sancionador. Ley 19/2013 de transparencia. Agenda 2030 y ODS.",
archivo: "bloque1/tema4.md"
},
{
num: 5,
titulo: "Políticas de igualdad y contra la violencia de género. Igualdad LGTBI. Discapacidad y dependencia.",
archivo: "bloque1/tema5.md"
},
{
num: 6,
titulo: "Sociedad de la información. Identidad y firma electrónica. DNIe. Agenda Digital para España.",
archivo: "bloque1/tema6.md"
},
{
num: 7,
titulo: "Protección de datos personales: principios, derechos y obligaciones. Derechos digitales.",
archivo: "bloque1/tema7.md"
},
{
num: 8,
titulo: "Acceso electrónico a los servicios públicos. Registros, notificaciones, medios electrónicos. ENS y ENI. NTI.",
archivo: "bloque1/tema8.md"
},
{
num: 9,
titulo: "Instrumentos de acceso electrónico: sedes electrónicas, canales, identificación y autenticación. Infraestructuras y servicios comunes.",
archivo: "bloque1/tema9.md"
}
]
},
{
id: 2,
titulo: "Tecnología básica",
color: "#c586c0",
temas: [
{
num: 1,
titulo: "Informática básica. Representación y comunicación de la información: elementos constitutivos de un sistema de información. Características y funciones. Arquitectura de ordenadores. Componentes internos de los equipos microinformáticos.",
archivo: "bloque2/tema1.md"
},
{
num: 2,
titulo: "Periféricos: conectividad y administración. Elementos de impresión. Elementos de almacenamiento. Elementos de visualización y digitalización.",
archivo: "bloque2/tema2.md"
},
{
num: 3,
titulo: "Tipos abstractos y Estructuras de datos. Organizaciones de ficheros. Algoritmos. Formatos de información y ficheros.",
archivo: "bloque2/tema3.md"
},
{
num: 4,
titulo: "Sistemas operativos. Características y elementos constitutivos. Sistemas Windows. Sistemas Unix y Linux. Sistemas operativos para dispositivos móviles.",
archivo: "bloque2/tema4.md"
},
{
num: 5,
titulo: "Sistemas de gestión de bases de datos relacionales, orientados a objetos y NoSQL: características y componentes.",
archivo: "bloque2/tema5.md"
}
]
},
{
id: 3,
titulo: "Desarrollo de sistemas",
color: "#d7ba7d",
temas: [
{
num: 1,
titulo: "Modelado de datos, metodologías y reglas. Entidades, atributos y relaciones. Diseño de bases de datos. Diseño lógico y físico. El modelo lógico relacional. Normalización.",
archivo: "bloque3/tema1.md"
},
{
num: 2,
titulo: "Lenguajes de programación. Representación de tipos de datos. Operadores. Instrucciones condicionales. Bucles y recursividad. Procedimientos, funciones y parámetros. Vectores y registros. Estructura de un programa.",
archivo: "bloque3/tema2.md"
},
{
num: 3,
titulo: "Lenguajes de interrogación de bases de datos. Estándar ANSI SQL. Procedimientos almacenados. Eventos y disparadores.",
archivo: "bloque3/tema3.md"
},
{
num: 4,
titulo: "Diseño y programación orientada a objetos. Elementos y componentes software: objetos, clases, herencia, métodos, sobrecarga. Ventajas e inconvenientes. Patrones de diseño y lenguaje de modelado unificado (UML).",
archivo: "bloque3/tema4.md"
},
{
num: 5,
titulo: "Arquitectura Java EE/Jakarta EE y plataforma .NET: componentes, persistencia y seguridad. Características, elementos, lenguajes y funciones en ambos entornos. Desarrollo de interfaces.",
archivo: "bloque3/tema5.md"
},
{
num: 6,
titulo: "Arquitectura de sistemas cliente/servidor y multicapas: componentes y operación. Arquitecturas de servicios web y protocolos asociados.",
archivo: "bloque3/tema6.md"
},
{
num: 7,
titulo: "Aplicaciones web. Desarrollo web front-end y en servidor, multiplataforma y multidispositivo. Lenguajes: HTML, XML y sus derivaciones. Navegadores y lenguajes de programación web. Lenguajes de script.",
archivo: "bloque3/tema7.md"
},
{
num: 8,
titulo: "Accesibilidad, diseño universal y usabilidad. Acceso y usabilidad de las tecnologías, productos y servicios relacionados con la sociedad de la información. Confidencialidad y disponibilidad de la información en puestos de usuario final. Conceptos de seguridad en el desarrollo de los sistemas.",
archivo: "bloque3/tema8.md"
},
{
num: 9,
titulo: "Repositorios: estructura y actualización. Generación de código y documentación. Metodologías de desarrollo. Pruebas. Programas para control de versiones. Plataformas de desarrollo colaborativo de software.",
archivo: "bloque3/tema9.md"
}
]
},
{
id: 4,
titulo: "Sistemas y comunicaciones",
color: "#4ec9b0",
temas: [
{
num: 1,
titulo: "Administración del Sistema operativo y software de base. Actualización, mantenimiento y reparación del sistema operativo.",
archivo: "bloque4/tema1.md"
},
{
num: 2,
titulo: "Administración de bases de datos. Sistemas de almacenamiento y su virtualización. Políticas, sistemas y procedimientos de backup y su recuperación. Backup de sistemas físicos y virtuales. Virtualización de sistemas y virtualización de puestos de usuario.",
archivo: "bloque4/tema2.md"
},
{
num: 3,
titulo: "Administración de servidores de correo electrónico y sus protocolos. Administración de contenedores y microservicios.",
archivo: "bloque4/tema3.md"
},
{
num: 4,
titulo: "Administración de redes de área local. Gestión de usuarios. Gestión de dispositivos. Monitorización y control de tráfico.",
archivo: "bloque4/tema4.md"
},
{
num: 5,
titulo: "Conceptos de seguridad de los sistemas de información. Seguridad física. Seguridad lógica. Amenazas y vulnerabilidades. Técnicas criptográficas y protocolos seguros. Mecanismos de firma digital. Infraestructura física de un CPD: acondicionamiento y equipamiento. Sistemas de gestión de incidencias. Control remoto de puestos de usuario.",
archivo: "bloque4/tema5.md"
},
{
num: 6,
titulo: "Comunicaciones. Medios de transmisión. Modos de comunicación. Equipos terminales y equipos de interconexión y conmutación. Redes de comunicaciones. Redes de conmutación y redes de difusión. Comunicaciones móviles e inalámbricas.",
archivo: "bloque4/tema6.md"
},
{
num: 7,
titulo: "El modelo TCP/IP y el modelo de referencia de interconexión de sistemas abiertos (OSI) de ISO. Protocolos TCP/IP.",
archivo: "bloque4/tema7.md"
},
{
num: 8,
titulo: "Internet: arquitectura de red. Origen, evolución y estado actual. Principales servicios. Protocolos HTTP, HTTPS y SSL/TLS.",
archivo: "bloque4/tema8.md"
},
{
num: 9,
titulo: "Seguridad y protección en redes de comunicaciones. Seguridad perimetral. Acceso remoto seguro a redes. Redes privadas virtuales (VPN). Seguridad en el puesto del usuario.",
archivo: "bloque4/tema9.md"
},
{
num: 10,
titulo: "Redes locales. Tipología. Técnicas de transmisión. Métodos de acceso. Dispositivos de interconexión.",
archivo: "bloque4/tema10.md"
}
]
}
];
/**
* Total de temas en el temario.
*/
const TOTAL_TEMAS = TEMARIO.reduce((acc, b) => acc + b.temas.length, 0);
/**
* Dado un bloque (1-based) y un num de tema (1-based) devuelve
* el tema anterior y el siguiente en orden lineal, o null.
*/
function getNavigation(bloqueId, temaNum) {
const flat = [];
for (const bloque of TEMARIO) {
for (const tema of bloque.temas) {
flat.push({ bloqueId: bloque.id, temaNum: tema.num });
}
}
const idx = flat.findIndex(x => x.bloqueId === bloqueId && x.temaNum === temaNum);
return {
prev: idx > 0 ? flat[idx - 1] : null,
next: idx < flat.length - 1 ? flat[idx + 1] : null,
pos: idx + 1,
total: flat.length
};
}

179
noticias.html Normal file
View File

@ -0,0 +1,179 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TAI AGE | Noticias y Convocatorias</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
<!-- ── Topbar ─────────────────────────────────────────── -->
<nav class="topbar">
<span class="topbar-brand"><i class="fas fa-graduation-cap"></i> TAI AGE</span>
<nav class="topbar-nav">
<a href="index.html">Inicio</a>
<a href="curso.html">Temario</a>
<a href="cuestionarios/index.html">Cuestionarios</a>
<a href="noticias.html" class="active">Noticias</a>
</nav>
</nav>
<div class="noticias-layout" style="margin-top:calc(var(--topbar-h) + 2rem)">
<div class="noticias-header">
<h1><i class="fas fa-bell"></i> Noticias y Convocatorias</h1>
<p>Actualiza esta página para ver los últimos avisos del INAP, novedades del BOE y nuevas convocatorias de las CCAA.</p>
</div>
<!-- ── INAP Convocatoria TAI ─────────────────────── -->
<section class="noticias-section">
<div class="noticias-section-hdr">
<h2><i class="fas fa-university"></i> INAP Convocatoria TAI en curso</h2>
<span class="noticias-src-badge">inap.es</span>
</div>
<div class="inap-links-grid">
<a href="https://sede.inap.gob.es/es/procedimientos-y-servicios/seleccion/procesos-selectivos-de-cuerpos-y-escalas-generales/cuerpo-de-tecnicos-auxiliares-de-informatica-de-la-administracion-del-estado-ingreso-libre-convocatoria-2025" target="_blank" rel="noopener" class="inap-link-card inap-link-primary">
<i class="fas fa-bullhorn"></i>
<span>Convocatoria TAI INAP</span>
<i class="fas fa-external-link-alt inap-ext"></i>
</a>
<a href="https://sede.inap.gob.es/es/procedimientos-y-servicios/seleccion/procesos-selectivos-de-cuerpos-y-escalas-generales" target="_blank" rel="noopener" class="inap-link-card">
<i class="fas fa-list-ul"></i>
<span>Procesos selectivos en curso</span>
<i class="fas fa-external-link-alt inap-ext"></i>
</a>
<a href="https://www.boe.es/buscar/doc.php?campo[0]=TITN&dato[0]=tai" target="_blank" rel="noopener" class="inap-link-card">
<i class="fas fa-search"></i>
<span>Buscar "TAI" en el BOE</span>
<i class="fas fa-external-link-alt inap-ext"></i>
</a>
<a href="https://www.boe.es/buscar/boe.php?campo[0]=TITN&dato[0]=tecnico+administracion+informatica&campo[1]=DDES&dato[1]=&field=todos&texto=&desde=&hasta=&sort_field[0]=fech&sort_order[0]=desc&accion=buscar" target="_blank" rel="noopener" class="inap-link-card">
<i class="fas fa-file-alt"></i>
<span>Resoluciones TAI en BOE</span>
<i class="fas fa-external-link-alt inap-ext"></i>
</a>
</div>
<div class="inap-info-box">
<i class="fas fa-info-circle"></i>
<p>El INAP publica actualizaciones de la convocatoria (listas provisionales, definitivas, llamamientos, fechas de examen) en su web oficial y en el BOE Sección II-B.
Revisa periódicamente la página de la convocatoria TAI o configura una alerta en el BOE para no perderte ninguna resolución.
</p>
</div>
</section>
<!-- ── BOE Oposiciones y concursos ──────────────── -->
<section class="noticias-section">
<div class="noticias-section-hdr">
<h2><i class="fas fa-newspaper"></i> BOE Oposiciones y Concursos (AGE)</h2>
<span id="boe-fecha" class="noticias-src-badge">Cargando…</span>
</div>
<p class="noticias-section-desc">Últimas publicaciones de la Sección II-B del BOE (Oposiciones, concursos y vacantes). Las entradas relacionadas con TAI / informática se marcan en verde.</p>
<div id="boe-items" class="news-list">
<div class="news-loading"><i class="fas fa-spinner fa-spin"></i> Cargando noticias del BOE…</div>
</div>
<a href="https://www.boe.es/diario_boe/ultimos_dias.php" target="_blank" rel="noopener" class="btn btn-outline" style="margin-top:1rem;font-size:.85rem">
<i class="fas fa-external-link-alt"></i> Ver BOE completo
</a>
</section>
<!-- ── Boletines CCAA ──────────────────────────────── -->
<section class="noticias-section">
<div class="noticias-section-hdr">
<h2><i class="fas fa-map-marked-alt"></i> Boletines Oficiales de las CCAA</h2>
<span class="noticias-src-badge">17 CCAA + Ceuta + Melilla</span>
</div>
<p class="noticias-section-desc">Acceso directo a los boletines oficiales autonómicos para consultar convocatorias de cuerpos de informática de cada comunidad.</p>
<div class="ccaa-grid">
<a href="https://www.juntadeandalucia.es/boja" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOJA</span>
<span class="ccaa-nombre">Andalucía</span>
</a>
<a href="https://www.boa.aragon.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOA</span>
<span class="ccaa-nombre">Aragón</span>
</a>
<a href="https://sede.asturias.es/bopa" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOPA</span>
<span class="ccaa-nombre">Asturias</span>
</a>
<a href="https://www.caib.es/boib" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOIB</span>
<span class="ccaa-nombre">Baleares</span>
</a>
<a href="https://www.gobiernodecanarias.org/librodigital/boc/" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOC</span>
<span class="ccaa-nombre">Canarias</span>
</a>
<a href="https://boc.cantabria.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOC</span>
<span class="ccaa-nombre">Cantabria</span>
</a>
<a href="https://docm.castillalamancha.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">DOCM</span>
<span class="ccaa-nombre">Castilla-La Mancha</span>
</a>
<a href="https://bocyl.jcyl.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOCYL</span>
<span class="ccaa-nombre">Castilla y León</span>
</a>
<a href="https://dogc.gencat.cat" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">DOGC</span>
<span class="ccaa-nombre">Cataluña</span>
</a>
<a href="https://doe.juntaex.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">DOE</span>
<span class="ccaa-nombre">Extremadura</span>
</a>
<a href="https://www.xunta.gal/dog" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">DOG</span>
<span class="ccaa-nombre">Galicia</span>
</a>
<a href="https://www.larioja.org/es/gobierno-rioja/boletines" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOR</span>
<span class="ccaa-nombre">La Rioja</span>
</a>
<a href="https://www.bocm.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOCM</span>
<span class="ccaa-nombre">Madrid</span>
</a>
<a href="https://www.borm.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BORM</span>
<span class="ccaa-nombre">Murcia</span>
</a>
<a href="https://bon.navarra.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BON</span>
<span class="ccaa-nombre">Navarra</span>
</a>
<a href="https://www.euskadi.eus/bopv" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOPV</span>
<span class="ccaa-nombre">País Vasco</span>
</a>
<a href="https://dogv.gva.es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">DOGV</span>
<span class="ccaa-nombre">C. Valenciana</span>
</a>
<a href="https://www.ceuta.es/ceuta/index.php/boletin-oficial" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOCCE</span>
<span class="ccaa-nombre">Ceuta</span>
</a>
<a href="https://www.melilla.es/melillaPortal/contenedor1.jsp?seccion=s_lofb_d4_v1.jsp&contenido=17547&nivel=1400&tipo=6&codResi=1&language=es" target="_blank" rel="noopener" class="ccaa-card">
<span class="ccaa-sigla">BOME</span>
<span class="ccaa-nombre">Melilla</span>
</a>
</div>
</section>
</div>
<script src="js/noticias.js"></script>
</body>
</html>