# Quiz de la fase 4: Seguridad, Concurrencia y Reactividad vs Virtual Threads

> 14 afirmaciones de verdadero o falso, con la respuesta explicada, sobre los días de esta fase del plan JavaMastery.

Versión interactiva: https://aprende-java.webs-economicas.es/quiz/fase-4/

## Afirmaciones

### 1. En Spring Security 6, `WebSecurityConfigurerAdapter` ya no existe: la configuración se declara como un bean `SecurityFilterChain`.

**Respuesta:** Verdadero. Se marcó como obsoleto en 5.7 y se eliminó en 6.0.

**Para recordarlo:** Spring Security 6: un `@Bean SecurityFilterChain` con lambdas, sin heredar de ningún adaptador.

Se estudia en el [día 16: Seguridad Stateless con Spring Security 6 y JWT en Java 17/21](https://aprende-java.webs-economicas.es/dias/spring-security-jwt.md).

### 2. Un JWT firmado está cifrado: nadie puede leer su contenido sin la clave.

**Respuesta:** Falso. La cabecera y el payload son Base64URL: cualquiera puede leerlos. La firma solo garantiza que no se han alterado. Nunca pongas secretos en un JWT.

**Para recordarlo:** Firmado no es cifrado: pega un JWT en un decodificador y lo leerás entero.

Se estudia en el [día 16: Seguridad Stateless con Spring Security 6 y JWT en Java 17/21](https://aprende-java.webs-economicas.es/dias/spring-security-jwt.md).

### 3. En una API stateless con JWT, el servidor guarda la sesión de cada usuario en memoria.

**Respuesta:** Falso. Cada petición trae su token y se valida por sí misma. Precisamente por eso la API puede escalar a varias instancias sin sesión compartida.

**Para recordarlo:** Stateless = el servidor no recuerda nada entre peticiones; el token lo lleva todo.

Se estudia en el [día 16: Seguridad Stateless con Spring Security 6 y JWT en Java 17/21](https://aprende-java.webs-economicas.es/dias/spring-security-jwt.md).

### 4. BCrypt usa una sal aleatoria, así que la misma contraseña genera hashes distintos cada vez.

**Respuesta:** Verdadero. La sal va guardada dentro del propio hash, y `matches()` la usa para comprobar la contraseña.

**Para recordarlo:** Con BCrypt, compara siempre con `matches()`, nunca generando otro hash y comparando textos.

Se estudia en el [día 16: Seguridad Stateless con Spring Security 6 y JWT en Java 17/21](https://aprende-java.webs-economicas.es/dias/spring-security-jwt.md).

### 5. Para que `@PreAuthorize` funcione hay que activar la seguridad a nivel de método con `@EnableMethodSecurity`.

**Respuesta:** Verdadero. Sin esa anotación, `@PreAuthorize` se ignora sin dar ningún error.

**Para recordarlo:** `@PreAuthorize` sin `@EnableMethodSecurity` no protege nada y no avisa.

Se estudia en el [día 16: Seguridad Stateless con Spring Security 6 y JWT en Java 17/21](https://aprende-java.webs-economicas.es/dias/spring-security-jwt.md).

### 6. Los virtual threads hacen que el código que consume mucha CPU vaya más rápido.

**Respuesta:** Falso. Ayudan cuando los hilos pasan mucho tiempo esperando I/O. Con trabajo de CPU el límite siguen siendo los núcleos.

**Para recordarlo:** Virtual threads = esperar barato, no calcular más rápido.

Se estudia en el [día 18: Concurrencia en la JVM: De Hilos Clásicos a Virtual Threads en Java 21](https://aprende-java.webs-economicas.es/dias/virtual-threads.md).

### 7. En Java 21, un virtual thread que se bloquea dentro de un bloque `synchronized` puede quedar anclado (pinning) a su carrier thread.

**Respuesta:** Verdadero. Mientras está anclado no libera el hilo de plataforma. JDK 24 lo resolvió con la JEP 491, pero en Java 21 conviene usar `ReentrantLock`.

**Para recordarlo:** En Java 21, no hagas I/O dentro de `synchronized`: usa `ReentrantLock`.

Se estudia en el [día 18: Concurrencia en la JVM: De Hilos Clásicos a Virtual Threads en Java 21](https://aprende-java.webs-economicas.es/dias/virtual-threads.md).

### 8. En Spring Boot 3.2 o superior, `spring.threads.virtual.enabled=true` hace que las peticiones se atiendan con virtual threads.

**Respuesta:** Verdadero. Afecta a Tomcat, a `@Async` y a varios ejecutores. Requiere Java 21.

**Para recordarlo:** Boot 3.2+ y Java 21: basta con una propiedad, `spring.threads.virtual.enabled=true`.

Se estudia en el [día 18: Concurrencia en la JVM: De Hilos Clásicos a Virtual Threads en Java 21](https://aprende-java.webs-economicas.es/dias/virtual-threads.md).

### 9. En Project Reactor, un `Flux` normal no emite nada hasta que alguien se suscribe.

**Respuesta:** Verdadero. Los publishers son perezosos ("cold"): declarar la cadena no ejecuta nada hasta el `subscribe()`, que en WebFlux hace el framework.

**Para recordarlo:** En Reactor, nada ocurre hasta el `subscribe()`.

Se estudia en el [día 19: Programación Reactiva (Project Reactor, WebFlux, RxJava) vs Virtual Threads](https://aprende-java.webs-economicas.es/dias/programacion-reactiva-webflux.md).

### 10. Llamar a un método bloqueante dentro de un pipeline de WebFlux no tiene consecuencias.

**Respuesta:** Falso. WebFlux usa muy pocos hilos de event loop. Bloquear uno frena todas las peticiones que dependen de él. Ese trabajo va en `Schedulers.boundedElastic()`.

**Para recordarlo:** En WebFlux, lo bloqueante va a `Schedulers.boundedElastic()` o fuera del pipeline.

Se estudia en el [día 19: Programación Reactiva (Project Reactor, WebFlux, RxJava) vs Virtual Threads](https://aprende-java.webs-economicas.es/dias/programacion-reactiva-webflux.md).

### 11. `volatile` hace que `contador++` sea atómico.

**Respuesta:** Falso. `volatile` garantiza que los hilos ven la última escritura, pero `contador++` son tres pasos (leer, sumar y escribir) que pueden intercalarse. Hace falta `AtomicInteger` o un lock.

**Para recordarlo:** `volatile` = visibilidad. Atomicidad = atómicos o locks.

Se estudia en el [día 17: Concurrencia Clásica y Java Memory Model](https://aprende-java.webs-economicas.es/dias/concurrencia-java-memory-model.md).

### 12. En un `ConcurrentHashMap`, `if (!map.containsKey(k)) map.put(k, v)` es seguro porque cada operación es atómica.

**Respuesta:** Falso. Cada operación por separado es segura, pero entre las dos otro hilo puede insertar la clave. Hay que usar `putIfAbsent` o `computeIfAbsent`, que lo hacen en un solo paso.

**Para recordarlo:** Comprobar y luego actuar = condición de carrera. Usa las operaciones compuestas del mapa.

Se estudia en el [día 17: Concurrencia Clásica y Java Memory Model](https://aprende-java.webs-economicas.es/dias/concurrencia-java-memory-model.md).

### 13. Si no pasas un executor, `CompletableFuture.supplyAsync` usa el `ForkJoinPool.commonPool()`.

**Respuesta:** Verdadero. Es el pool común de la JVM, compartido también por los parallel streams y dimensionado para tareas de CPU. Para llamadas de red conviene pasar un executor propio.

**Para recordarlo:** `supplyAsync` con I/O: siempre con tu propio executor.

Se estudia en el [día 17: Concurrencia Clásica y Java Memory Model](https://aprende-java.webs-economicas.es/dias/concurrencia-java-memory-model.md).

### 14. Después de `thread.join()` ves todo lo que escribió ese hilo antes de terminar.

**Respuesta:** Verdadero. El Java Memory Model establece una relación happens-before entre todo lo que hace un hilo y el retorno de `join()` sobre él.

**Para recordarlo:** `start()` y `join()` crean happens-before: lo de antes y lo de después se ven.

Se estudia en el [día 17: Concurrencia Clásica y Java Memory Model](https://aprende-java.webs-economicas.es/dias/concurrencia-java-memory-model.md).

