Top 100 Preguntas Completas de Java
Las 100 Preguntas Completas de Java
Section titled “Las 100 Preguntas Completas de Java”Esta guía cubre desde fundamentos hasta temas avanzados. Las preguntas 1-50 están en las guías anteriores.
Java 8+ Features (51-65)
Section titled “Java 8+ Features (51-65)”51. ¿Qué novedades trajo Java 8?
Section titled “51. ¿Qué novedades trajo Java 8?”¿Por qué es importante? Java 8 fue la actualización más significativa. Introdujo programación funcional.
Novedades principales:
- Lambdas y Streams
- Optional
- Interfaces funcionales
- Métodos default en interfaces
- Method references
- Nueva API de fecha/hora
- Nashorn JavaScript Engine
52. ¿Qué es la nueva API de Date/Time?
Section titled “52. ¿Qué es la nueva API de Date/Time?”¿Qué es? API moderna para fechas/horas que reemplaza a Date y Calendar.
Ventajas: Inmutable, thread-safe, más intuitiva, soporte de zonas horarias.
import java.time.*;
// Clases inmutables y thread-safeLocalDate fecha = LocalDate.now();LocalDate cumple = LocalDate.of(1990, Month.MARCH, 15);
LocalTime hora = LocalTime.now();LocalTime mediodia = LocalTime.of(12, 0);
LocalDateTime fechaHora = LocalDateTime.now();
ZonedDateTime conZona = ZonedDateTime.now(ZoneId.of("America/Lima"));
// OperacionesLocalDate manana = fecha.plusDays(1);LocalDate haceMes = fecha.minusMonths(1);
// Período y duraciónPeriod periodo = Period.between(cumple, fecha);Duration duracion = Duration.between(hora, mediodia);
// FormateoDateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");String formateado = fecha.format(formatter);LocalDate parseado = LocalDate.parse("15/03/1990", formatter);53. ¿Qué novedades trajo Java 9?
Section titled “53. ¿Qué novedades trajo Java 9?”Principal novedad: Sistema de módulos (Project Jigsaw) para encapsular código.
Otras mejoras: Factory methods para colecciones, mejoras en Stream y Optional.
// Módulos (Project Jigsaw)module mi.modulo { requires java.sql; exports com.mi.paquete;}
// Factory methods para coleccionesList<String> lista = List.of("a", "b", "c");Set<Integer> set = Set.of(1, 2, 3);Map<String, Integer> mapa = Map.of("uno", 1, "dos", 2);
// Stream improvementsStream.ofNullable(posibleNull);stream.takeWhile(n -> n < 5);stream.dropWhile(n -> n < 5);
// Optional improvementsoptional.ifPresentOrElse( valor -> System.out.println(valor), () -> System.out.println("Vacío"));optional.or(() -> Optional.of("default"));optional.stream();
// Private methods en interfacesinterface MiInterface { private void metodoPrivado() {}}54. ¿Qué novedades trajo Java 10?
Section titled “54. ¿Qué novedades trajo Java 10?”Principal novedad: var para inferencia de tipos en variables locales.
Importante: Solo para variables locales con inicializador, NO para campos o parámetros.
// var - inferencia de tipos localvar lista = new ArrayList<String>(); // ArrayList<String>var mapa = Map.of("a", 1); // Map<String, Integer>
// Solo para variables locales con inicializador// NO para campos, parámetros o return types
// copyOf para colecciones inmutablesList<String> copia = List.copyOf(listaOriginal);55. ¿Qué novedades trajo Java 11?
Section titled “55. ¿Qué novedades trajo Java 11?”¿Por qué es importante? Primera versión LTS después de Java 8. Muy usada en producción.
Novedades: var en lambdas, métodos de String, HttpClient, ejecutar .java directamente.
// var en lambdasBiFunction<String, String, String> concat = (var a, var b) -> a + b;
// Nuevos métodos de String" hola ".strip(); // "hola" (mejor que trim)" hola ".stripLeading(); // "hola "" hola ".stripTrailing();// " hola""".isBlank(); // true"holamundo".lines(); // Stream<String>"ab".repeat(3); // "ababab"
// HTTP Client (estándar)HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.example.com")) .build();HttpResponse<String> response = client.send( request, HttpResponse.BodyHandlers.ofString());
// FilesString contenido = Files.readString(Path.of("archivo.txt"));Files.writeString(Path.of("archivo.txt"), "contenido");56. ¿Qué novedades trajo Java 14-17?
Section titled “56. ¿Qué novedades trajo Java 14-17?”Novedades clave: Records, Pattern Matching, Switch expressions, Text blocks, Sealed classes.
Java 17 es LTS - Versión recomendada para producción actualmente.
// Records (Java 14 preview, 16 final)public record Persona(String nombre, int edad) {}// Genera: constructor, getters, equals, hashCode, toString
// Pattern Matching para instanceof (Java 14 preview, 16 final)if (obj instanceof String s) { System.out.println(s.length());}
// Switch expressions (Java 14)String resultado = switch (dia) { case LUNES, MARTES -> "Inicio de semana"; case MIERCOLES -> "Mitad de semana"; case JUEVES, VIERNES -> "Fin de semana laboral"; default -> "Fin de semana";};
// Text blocks (Java 15)String json = """ { "nombre": "Juan", "edad": 25 } """;
// Sealed classes (Java 17)public sealed class Figura permits Circulo, Rectangulo, Triangulo {}public final class Circulo extends Figura {}public non-sealed class Rectangulo extends Figura {}57. ¿Qué novedades trajo Java 21?
Section titled “57. ¿Qué novedades trajo Java 21?”¿Por qué es importante? Última versión LTS. Incluye Virtual Threads (revolucionario para concurrencia).
Novedades: Virtual Threads, Pattern Matching mejorado, Record Patterns, Sequenced Collections.
// Virtual Threads (Project Loom)Thread.startVirtualThread(() -> { System.out.println("Virtual thread");});
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { executor.submit(() -> hacerTarea());}
// Pattern Matching para switchString resultado = switch (obj) { case Integer i -> "Entero: " + i; case String s -> "String: " + s; case null -> "Nulo"; default -> "Otro";};
// Record Patternsrecord Point(int x, int y) {}if (obj instanceof Point(int x, int y)) { System.out.println(x + ", " + y);}
// Sequenced CollectionsSequencedCollection<String> seq = new LinkedHashSet<>();seq.addFirst("primero");seq.addLast("último");seq.getFirst();seq.getLast();seq.reversed();58. ¿Qué son los Virtual Threads?
Section titled “58. ¿Qué son los Virtual Threads?”¿Qué es? Threads ligeros gestionados por la JVM (no el OS). Puedes crear millones.
¿Para qué sirve? Operaciones I/O-bound (HTTP, BD). NO para CPU-intensive.
// Virtual Threads - threads ligeros (Project Loom)// Pueden crear millones sin problema
// Crear virtual threadThread vThread = Thread.ofVirtual().start(() -> { System.out.println("Virtual thread");});
// Con ExecutorServicetry (var executor = Executors.newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 10000).forEach(i -> { executor.submit(() -> { Thread.sleep(Duration.ofSeconds(1)); return i; }); });}
// Diferencias con Platform Threads:// - Muy ligeros (KB vs MB)// - Gestionados por JVM, no por OS// - Ideales para I/O blocking// - No usar para CPU-intensive59. ¿Qué es un Record?
Section titled “59. ¿Qué es un Record?”¿Qué es? Clase inmutable para transportar datos. Genera automáticamente constructor, getters, equals, hashCode, toString.
¿Para qué sirve? DTOs, value objects, eliminar boilerplate.
// Record - clase inmutable para datospublic record Persona(String nombre, int edad) { // Constructor compacto para validación public Persona { if (edad < 0) { throw new IllegalArgumentException("Edad negativa"); } nombre = nombre.trim(); }
// Métodos adicionales public String nombreMayusculas() { return nombre.toUpperCase(); }
// Constructor adicional public Persona(String nombre) { this(nombre, 0); }}
// UsoPersona p = new Persona("Juan", 25);String nombre = p.nombre(); // getterint edad = p.edad();
// Automáticamente tiene:// - Constructor con todos los campos// - Getters (nombre(), edad())// - equals() y hashCode()// - toString()60. ¿Qué son las Sealed Classes?
Section titled “60. ¿Qué son las Sealed Classes?”¿Qué es? Clases que restringen explícitamente qué otras clases pueden heredar de ellas.
¿Para qué sirve? Modelar dominios cerrados, mejor pattern matching, control de jerarquía.
// Sealed class - restringe qué clases pueden heredarpublic sealed class Figura permits Circulo, Rectangulo, Triangulo {}
// Subclases deben ser: final, sealed, o non-sealedpublic final class Circulo extends Figura { private double radio;}
public sealed class Rectangulo extends Figura permits Cuadrado {}
public final class Cuadrado extends Rectangulo {}
public non-sealed class Triangulo extends Figura { // Cualquiera puede heredar de Triangulo}
// Útil para pattern matching exhaustivodouble area = switch (figura) { case Circulo c -> Math.PI * c.getRadio() * c.getRadio(); case Rectangulo r -> r.getAncho() * r.getAlto(); case Triangulo t -> t.getBase() * t.getAltura() / 2; // No necesita default - es exhaustivo};61. ¿Qué es Pattern Matching?
Section titled “61. ¿Qué es Pattern Matching?”¿Qué es? Extraer datos de objetos de forma declarativa, combinando instanceof + cast + asignación.
Tipos: Para instanceof, para switch, para records (deconstrucción).
// Pattern Matching para instanceofObject obj = "Hola";
// Antesif (obj instanceof String) { String s = (String) obj; System.out.println(s.length());}
// Ahoraif (obj instanceof String s) { System.out.println(s.length());}
// Pattern Matching en switchString resultado = switch (obj) { case Integer i when i > 0 -> "Positivo: " + i; case Integer i -> "No positivo: " + i; case String s when s.length() > 5 -> "String largo"; case String s -> "String corto: " + s; case null -> "Nulo"; default -> "Otro tipo";};
// Record Patternsrecord Point(int x, int y) {}record Line(Point start, Point end) {}
void procesar(Object obj) { if (obj instanceof Line(Point(var x1, var y1), Point(var x2, var y2))) { System.out.println("Línea de (" + x1 + "," + y1 + ") a (" + x2 + "," + y2 + ")"); }}62. ¿Qué son los Text Blocks?
Section titled “62. ¿Qué son los Text Blocks?”¿Qué es? Strings multilínea con triple comilla. Preservan formato e indentación.
¿Para qué sirve? JSON, HTML, SQL, cualquier texto largo.
// Text Blocks - strings multilíneaString json = """ { "nombre": "Juan", "edad": 25, "activo": true } """;
String html = """ <html> <body> <h1>Título</h1> </body> </html> """;
// Caracteres de escapeString conComillas = """ Él dijo: "Hola" """;
// Interpolación (no nativa, usar formatted)String nombre = "Juan";String saludo = """ Hola, %s! Bienvenido. """.formatted(nombre);63. ¿Qué son las Switch Expressions?
Section titled “63. ¿Qué son las Switch Expressions?”¿Qué es? Switch que retorna un valor. Usa -> en vez de : y no necesita break.
Ventajas: Más conciso, sin fall-through accidental, exhaustivo.
// Switch tradicional (statement)String tipo;switch (dia) { case LUNES: case MARTES: tipo = "Inicio"; break; default: tipo = "Otro";}
// Switch expression (Java 14+)String tipo = switch (dia) { case LUNES, MARTES -> "Inicio"; case MIERCOLES -> "Mitad"; case JUEVES, VIERNES -> "Fin laboral"; case SABADO, DOMINGO -> "Fin de semana";};
// Con yield para bloquesString descripcion = switch (dia) { case LUNES -> { System.out.println("Procesando lunes"); yield "Primer día"; } default -> "Otro día";};64. ¿Qué es el Garbage Collector G1?
Section titled “64. ¿Qué es el Garbage Collector G1?”¿Qué es? GC por defecto desde Java 9. Divide heap en regiones, prioriza las más llenas.
Características: Pausas predecibles, ideal para heaps >4GB.
// G1 GC - Garbage First (default desde Java 9)// Divide el heap en regiones de igual tamaño
// Características:// - Pausas predecibles// - Compactación concurrente// - Ideal para heaps grandes (>4GB)
// Configuración// -XX:+UseG1GC (default)// -XX:MaxGCPauseMillis=200// -XX:G1HeapRegionSize=16m
// Otros GCs disponibles:// - ZGC: Ultra-low latency (<1ms pausas)// -XX:+UseZGC// - Shenandoah: Low-pause// -XX:+UseShenandoahGC// - Parallel GC: Throughput// -XX:+UseParallelGC65. ¿Qué es el JIT Compiler?
Section titled “65. ¿Qué es el JIT Compiler?”¿Qué es? Compilador que convierte bytecode a código nativo en runtime para mejorar performance.
Tipos: C1 (rápido, menos optimizado), C2 (lento, más optimizado), Tiered (ambos, default).
- C1 (Client): Compilación rápida, menos optimizaciones
- C2 (Server): Compilación lenta, más optimizaciones
- Tiered Compilation: Usa ambos (default)
// Ver compilación JIT// -XX:+PrintCompilation
// GraalVM - JIT alternativo más avanzado// Ahead-of-Time compilation con native-imagePatrones de Diseño (66-80)
Section titled “Patrones de Diseño (66-80)”66. ¿Qué es el patrón Factory?
Section titled “66. ¿Qué es el patrón Factory?”¿Qué es? Patrón que delega la creación de objetos a un método/clase especializada.
¿Para qué sirve? Desacoplar creación de uso, crear objetos según condiciones.
// Factory Methodpublic interface Animal { void hablar();}
public class Perro implements Animal { public void hablar() { System.out.println("Guau"); }}
public class Gato implements Animal { public void hablar() { System.out.println("Miau"); }}
public class AnimalFactory { public static Animal crear(String tipo) { return switch (tipo.toLowerCase()) { case "perro" -> new Perro(); case "gato" -> new Gato(); default -> throw new IllegalArgumentException("Tipo desconocido"); }; }}
// UsoAnimal animal = AnimalFactory.crear("perro");67. ¿Qué es el patrón Builder?
Section titled “67. ¿Qué es el patrón Builder?”¿Qué es? Patrón para construir objetos complejos paso a paso.
¿Para qué sirve? Objetos con muchos parámetros opcionales, inmutabilidad, legibilidad.
public class Persona { private final String nombre; private final int edad; private final String email; private final String telefono;
private Persona(Builder builder) { this.nombre = builder.nombre; this.edad = builder.edad; this.email = builder.email; this.telefono = builder.telefono; }
public static class Builder { private String nombre; private int edad; private String email; private String telefono;
public Builder nombre(String nombre) { this.nombre = nombre; return this; }
public Builder edad(int edad) { this.edad = edad; return this; }
public Builder email(String email) { this.email = email; return this; }
public Builder telefono(String telefono) { this.telefono = telefono; return this; }
public Persona build() { return new Persona(this); } }}
// UsoPersona persona = new Persona.Builder() .nombre("Juan") .edad(25) .email("juan@email.com") .build();68. ¿Qué es el patrón Observer?
Section titled “68. ¿Qué es el patrón Observer?”¿Qué es? Patrón donde un objeto (subject) notifica cambios a múltiples objetos dependientes (observers).
¿Para qué sirve? Eventos, notificaciones, actualizaciones en tiempo real.
import java.util.*;
// Subjectpublic class EventoNotificador { private List<Observador> observadores = new ArrayList<>();
public void agregar(Observador o) { observadores.add(o); }
public void remover(Observador o) { observadores.remove(o); }
public void notificar(String evento) { for (Observador o : observadores) { o.actualizar(evento); } }}
// Observerpublic interface Observador { void actualizar(String evento);}
public class EmailObservador implements Observador { @Override public void actualizar(String evento) { System.out.println("Email: " + evento); }}
// UsoEventoNotificador notificador = new EventoNotificador();notificador.agregar(new EmailObservador());notificador.notificar("Nuevo pedido");69. ¿Qué es el patrón Strategy?
Section titled “69. ¿Qué es el patrón Strategy?”¿Qué es? Patrón que define una familia de algoritmos intercambiables en runtime.
¿Para qué sirve? Métodos de pago, algoritmos de ordenamiento, validaciones.
// Strategy interfacepublic interface EstrategiaPago { void pagar(double monto);}
// Estrategias concretaspublic class PagoTarjeta implements EstrategiaPago { @Override public void pagar(double monto) { System.out.println("Pagando $" + monto + " con tarjeta"); }}
public class PagoPayPal implements EstrategiaPago { @Override public void pagar(double monto) { System.out.println("Pagando $" + monto + " con PayPal"); }}
// Contextpublic class CarritoCompras { private EstrategiaPago estrategia;
public void setEstrategia(EstrategiaPago estrategia) { this.estrategia = estrategia; }
public void checkout(double monto) { estrategia.pagar(monto); }}
// UsoCarritoCompras carrito = new CarritoCompras();carrito.setEstrategia(new PagoTarjeta());carrito.checkout(100.0);70. ¿Qué es el patrón Decorator?
Section titled “70. ¿Qué es el patrón Decorator?”¿Qué es? Patrón que añade funcionalidad a objetos dinámicamente sin modificar su clase.
¿Para qué sirve? Streams de Java, wrappers, extensiones de funcionalidad.
// Componentpublic interface Cafe { double getCosto(); String getDescripcion();}
// Concrete Componentpublic class CafeSimple implements Cafe { public double getCosto() { return 1.0; } public String getDescripcion() { return "Café"; }}
// Decoratorpublic abstract class CafeDecorator implements Cafe { protected Cafe cafe;
public CafeDecorator(Cafe cafe) { this.cafe = cafe; }}
// Concrete Decoratorspublic class ConLeche extends CafeDecorator { public ConLeche(Cafe cafe) { super(cafe); }
public double getCosto() { return cafe.getCosto() + 0.5; } public String getDescripcion() { return cafe.getDescripcion() + " + Leche"; }}
public class ConAzucar extends CafeDecorator { public ConAzucar(Cafe cafe) { super(cafe); }
public double getCosto() { return cafe.getCosto() + 0.2; } public String getDescripcion() { return cafe.getDescripcion() + " + Azúcar"; }}
// UsoCafe cafe = new ConAzucar(new ConLeche(new CafeSimple()));System.out.println(cafe.getDescripcion()); // Café + Leche + AzúcarSystem.out.println(cafe.getCosto()); // 1.771. ¿Qué es el patrón Adapter?
Section titled “71. ¿Qué es el patrón Adapter?”¿Qué es? Patrón que permite que interfaces incompatibles trabajen juntas.
¿Para qué sirve? Integrar librerías externas, legacy code, APIs diferentes.
// Target interfacepublic interface MediaPlayer { void play(String filename);}
// Adaptee (clase existente con interfaz incompatible)public class VlcPlayer { public void playVlc(String filename) { System.out.println("Playing VLC: " + filename); }}
// Adapterpublic class VlcAdapter implements MediaPlayer { private VlcPlayer vlcPlayer;
public VlcAdapter() { this.vlcPlayer = new VlcPlayer(); }
@Override public void play(String filename) { vlcPlayer.playVlc(filename); }}
// UsoMediaPlayer player = new VlcAdapter();player.play("video.vlc");72. ¿Qué es el patrón Proxy?
Section titled “72. ¿Qué es el patrón Proxy?”¿Qué es? Patrón que proporciona un sustituto o placeholder para controlar acceso a otro objeto.
Tipos: Virtual (lazy loading), Protection (control de acceso), Remote (objetos remotos).
// Subjectpublic interface Imagen { void mostrar();}
// Real Subjectpublic class ImagenReal implements Imagen { private String archivo;
public ImagenReal(String archivo) { this.archivo = archivo; cargarDesdeDisc(); }
private void cargarDesdeDisc() { System.out.println("Cargando " + archivo); }
@Override public void mostrar() { System.out.println("Mostrando " + archivo); }}
// Proxypublic class ImagenProxy implements Imagen { private ImagenReal imagenReal; private String archivo;
public ImagenProxy(String archivo) { this.archivo = archivo; }
@Override public void mostrar() { if (imagenReal == null) { imagenReal = new ImagenReal(archivo); // Lazy loading } imagenReal.mostrar(); }}73. ¿Qué es el patrón Template Method?
Section titled “73. ¿Qué es el patrón Template Method?”¿Qué es? Patrón que define el esqueleto de un algoritmo, delegando pasos a subclases.
¿Para qué sirve? Reutilizar estructura común, permitir personalización de pasos específicos.
// Abstract class con template methodpublic abstract class Bebida { // Template method public final void preparar() { hervirAgua(); agregarIngrediente(); servir(); if (clienteQuiereCondimentos()) { agregarCondimentos(); } }
private void hervirAgua() { System.out.println("Hirviendo agua"); }
protected abstract void agregarIngrediente();
private void servir() { System.out.println("Sirviendo en taza"); }
protected abstract void agregarCondimentos();
// Hook method protected boolean clienteQuiereCondimentos() { return true; }}
public class Cafe extends Bebida { @Override protected void agregarIngrediente() { System.out.println("Agregando café"); }
@Override protected void agregarCondimentos() { System.out.println("Agregando azúcar y leche"); }}74. ¿Qué es el patrón Command?
Section titled “74. ¿Qué es el patrón Command?”¿Qué es? Patrón que encapsula una solicitud como objeto.
¿Para qué sirve? Undo/redo, colas de comandos, logging, transacciones.
// Command interfacepublic interface Comando { void ejecutar(); void deshacer();}
// Receiverpublic class Luz { public void encender() { System.out.println("Luz encendida"); } public void apagar() { System.out.println("Luz apagada"); }}
// Concrete Commandpublic class EncenderLuzComando implements Comando { private Luz luz;
public EncenderLuzComando(Luz luz) { this.luz = luz; }
@Override public void ejecutar() { luz.encender(); }
@Override public void deshacer() { luz.apagar(); }}
// Invokerpublic class Control { private Comando comando;
public void setComando(Comando comando) { this.comando = comando; }
public void presionarBoton() { comando.ejecutar(); }}75. ¿Qué es el patrón State?
Section titled “75. ¿Qué es el patrón State?”¿Qué es? Patrón que permite a un objeto cambiar su comportamiento cuando cambia su estado interno.
¿Para qué sirve? Máquinas de estado, workflows, evitar condicionales complejos.
// State interfacepublic interface Estado { void insertar(); void expulsar(); void dispensar();}
// Contextpublic class MaquinaExpendedora { private Estado estado;
public void setEstado(Estado estado) { this.estado = estado; }
public void insertar() { estado.insertar(); } public void expulsar() { estado.expulsar(); } public void dispensar() { estado.dispensar(); }}
// Concrete Statespublic class SinMoneda implements Estado { private MaquinaExpendedora maquina;
@Override public void insertar() { System.out.println("Moneda insertada"); maquina.setEstado(new ConMoneda(maquina)); }
@Override public void expulsar() { System.out.println("No hay moneda"); }
@Override public void dispensar() { System.out.println("Inserte moneda primero"); }}76. ¿Qué es Dependency Injection?
Section titled “76. ¿Qué es Dependency Injection?”¿Qué es? Patrón donde las dependencias se proporcionan externamente en vez de crearlas internamente.
Beneficios: Desacoplamiento, testabilidad, flexibilidad.
// Sin DI (acoplado)public class ServicioUsuario { private RepositorioUsuario repo = new RepositorioUsuarioImpl();}
// Con DI (desacoplado)public class ServicioUsuario { private final RepositorioUsuario repo;
// Constructor injection (preferido) public ServicioUsuario(RepositorioUsuario repo) { this.repo = repo; }}
// Setter injectionpublic class ServicioUsuario { private RepositorioUsuario repo;
public void setRepo(RepositorioUsuario repo) { this.repo = repo; }}
// UsoRepositorioUsuario repo = new RepositorioUsuarioImpl();ServicioUsuario servicio = new ServicioUsuario(repo);77. ¿Qué es el principio SOLID?
Section titled “77. ¿Qué es el principio SOLID?”¿Qué es? Cinco principios de diseño orientado a objetos para código mantenible y escalable.
| Principio | Descripción |
|---|---|
| Single Responsibility | Una clase, una responsabilidad |
| Open/Closed | Abierto para extensión, cerrado para modificación |
| Liskov Substitution | Subtipos deben ser sustituibles por sus tipos base |
| Interface Segregation | Interfaces específicas mejor que una general |
| Dependency Inversion | Depender de abstracciones, no de implementaciones |
78. ¿Qué es el patrón Repository?
Section titled “78. ¿Qué es el patrón Repository?”¿Qué es? Patrón que abstrae el acceso a datos, proporcionando una colección de objetos de dominio.
Beneficios: Desacopla lógica de negocio de persistencia, facilita testing.
// Repository interfacepublic interface UsuarioRepository { Optional<Usuario> findById(Long id); List<Usuario> findAll(); Usuario save(Usuario usuario); void delete(Long id); List<Usuario> findByNombre(String nombre);}
// Implementationpublic class UsuarioRepositoryImpl implements UsuarioRepository { private EntityManager em;
@Override public Optional<Usuario> findById(Long id) { return Optional.ofNullable(em.find(Usuario.class, id)); }
@Override public List<Usuario> findAll() { return em.createQuery("SELECT u FROM Usuario u", Usuario.class) .getResultList(); }
@Override public Usuario save(Usuario usuario) { if (usuario.getId() == null) { em.persist(usuario); } else { usuario = em.merge(usuario); } return usuario; }}79. ¿Qué es el patrón Service Layer?
Section titled “79. ¿Qué es el patrón Service Layer?”¿Qué es? Capa que contiene la lógica de negocio, orquestando operaciones entre repositorios.
Responsabilidades: Validaciones, transacciones, coordinación de operaciones.
// Service layer - lógica de negocio@Servicepublic class UsuarioService { private final UsuarioRepository repository; private final EmailService emailService;
public UsuarioService(UsuarioRepository repository, EmailService emailService) { this.repository = repository; this.emailService = emailService; }
@Transactional public Usuario registrar(UsuarioDTO dto) { // Validaciones de negocio if (repository.existsByEmail(dto.getEmail())) { throw new EmailDuplicadoException(); }
// Crear usuario Usuario usuario = new Usuario(); usuario.setNombre(dto.getNombre()); usuario.setEmail(dto.getEmail()); usuario.setPassword(encriptar(dto.getPassword()));
// Guardar usuario = repository.save(usuario);
// Enviar email de bienvenida emailService.enviarBienvenida(usuario);
return usuario; }}80. ¿Qué es el patrón DTO?
Section titled “80. ¿Qué es el patrón DTO?”¿Qué es? Objeto para transferir datos entre capas/sistemas sin exponer entidades de dominio.
¿Para qué sirve? Seguridad (ocultar campos), performance (solo datos necesarios).
// DTO - Data Transfer Objectpublic class UsuarioDTO { private String nombre; private String email; // Sin password ni datos sensibles
// Getters y setters}
// Record como DTO (Java 16+)public record UsuarioDTO(String nombre, String email) {}
// Mapperpublic class UsuarioMapper { public static UsuarioDTO toDTO(Usuario usuario) { return new UsuarioDTO( usuario.getNombre(), usuario.getEmail() ); }
public static Usuario toEntity(UsuarioDTO dto) { Usuario usuario = new Usuario(); usuario.setNombre(dto.nombre()); usuario.setEmail(dto.email()); return usuario; }}Testing y Buenas Prácticas (81-90)
Section titled “Testing y Buenas Prácticas (81-90)”81. ¿Qué es JUnit 5?
Section titled “81. ¿Qué es JUnit 5?”¿Qué es? Framework de testing para Java. Versión actual con arquitectura modular.
Componentes: JUnit Platform, JUnit Jupiter (API), JUnit Vintage (compatibilidad).
import org.junit.jupiter.api.*;import static org.junit.jupiter.api.Assertions.*;
class CalculadoraTest { private Calculadora calc;
@BeforeEach void setUp() { calc = new Calculadora(); }
@Test @DisplayName("Suma de dos números positivos") void testSumar() { assertEquals(5, calc.sumar(2, 3)); }
@Test void testDividirPorCero() { assertThrows(ArithmeticException.class, () -> calc.dividir(1, 0)); }
@ParameterizedTest @ValueSource(ints = {1, 2, 3, 4, 5}) void testEsPositivo(int numero) { assertTrue(calc.esPositivo(numero)); }
@RepeatedTest(5) void testRepetido() { assertNotNull(calc); }}82. ¿Qué es Mockito?
Section titled “82. ¿Qué es Mockito?”¿Qué es? Framework para crear mocks (objetos simulados) en tests unitarios.
¿Para qué sirve? Aislar la unidad bajo test, simular dependencias.
import static org.mockito.Mockito.*;
class UsuarioServiceTest { @Mock private UsuarioRepository repository;
@InjectMocks private UsuarioService service;
@BeforeEach void setUp() { MockitoAnnotations.openMocks(this); }
@Test void testBuscarUsuario() { // Arrange Usuario usuario = new Usuario(1L, "Juan"); when(repository.findById(1L)).thenReturn(Optional.of(usuario));
// Act Usuario resultado = service.buscar(1L);
// Assert assertEquals("Juan", resultado.getNombre()); verify(repository, times(1)).findById(1L); }
@Test void testGuardarUsuario() { Usuario usuario = new Usuario(null, "Ana"); when(repository.save(any(Usuario.class))).thenReturn(new Usuario(1L, "Ana"));
Usuario guardado = service.guardar(usuario);
assertNotNull(guardado.getId()); verify(repository).save(usuario); }}83. ¿Qué es TDD?
Section titled “83. ¿Qué es TDD?”¿Qué es? Test-Driven Development: escribir tests ANTES del código de producción.
Ciclo:
- Red: Escribir test que falla
- Green: Escribir código mínimo para pasar
- Refactor: Mejorar código manteniendo tests verdes
84. ¿Qué es BDD?
Section titled “84. ¿Qué es BDD?”¿Qué es? Behavior-Driven Development: tests escritos en lenguaje natural (Given-When-Then).
Herramientas: Cucumber, JBehave.
// Con CucumberFeature: Login de usuario
Scenario: Login exitosoGiven un usuario registrado con email "juan@test.com"When ingresa su password correctoThen debe ver el dashboard
// Step definitions@Given("un usuario registrado con email {string}")public void usuarioRegistrado(String email) { usuario = new Usuario(email);}
@When("ingresa su password correcto")public void ingresaPassword() { resultado = loginService.login(usuario, "password");}
@Then("debe ver el dashboard")public void verDashboard() { assertTrue(resultado.isExitoso());}85. ¿Qué es Code Coverage?
Section titled “85. ¿Qué es Code Coverage?”¿Qué es? Porcentaje de código ejecutado por tests.
Herramientas: JaCoCo, Cobertura. Meta típica: 80%+ para código crítico.
// Maven con JaCoCo<plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.8</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions></plugin>86. ¿Qué son las anotaciones de validación?
Section titled “86. ¿Qué son las anotaciones de validación?”¿Qué es? Bean Validation (JSR 380): validar objetos con anotaciones.
Anotaciones comunes: @NotNull, @Size, @Email, @Min, @Max, @Pattern.
import jakarta.validation.constraints.*;
public class UsuarioDTO { @NotNull(message = "Nombre requerido") @Size(min = 2, max = 50) private String nombre;
@Email(message = "Email inválido") @NotBlank private String email;
@Min(18) @Max(120) private int edad;
@Pattern(regexp = "^[0-9]{9}$") private String telefono;
@Past private LocalDate fechaNacimiento;}87. ¿Qué es logging en Java?
Section titled “87. ¿Qué es logging en Java?”¿Qué es? Registrar eventos de la aplicación para debugging y monitoreo.
Stack recomendado: SLF4J (API) + Logback (implementación).
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
public class MiServicio { private static final Logger log = LoggerFactory.getLogger(MiServicio.class);
public void procesar() { log.debug("Iniciando proceso"); log.info("Procesando datos"); log.warn("Advertencia: datos incompletos"); log.error("Error al procesar", exception); }}
// logback.xml<configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender>
<root level="INFO"> <appender-ref ref="CONSOLE" /> </root></configuration>88. ¿Qué es Maven vs Gradle?
Section titled “88. ¿Qué es Maven vs Gradle?”Maven: Basado en XML, convención sobre configuración, más usado.
Gradle: Basado en Groovy/Kotlin, más flexible y rápido.
| Maven | Gradle |
|---|---|
| XML (pom.xml) | Groovy/Kotlin (build.gradle) |
| Convención sobre configuración | Más flexible |
| Más verboso | Más conciso |
| Más lento | Más rápido (incremental) |
// Maven pom.xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.2.0</version></dependency>
// Gradle build.gradledependencies { implementation 'org.springframework.boot:spring-boot-starter-web:3.2.0'}89. ¿Qué es Docker con Java?
Section titled “89. ¿Qué es Docker con Java?”¿Qué es? Contenerizar aplicaciones Java para despliegue consistente.
Best practices: Multi-stage builds, usar JRE (no JDK), imágenes Alpine.
# DockerfileFROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY target/mi-app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
# Multi-stage buildFROM eclipse-temurin:21-jdk-alpine AS buildWORKDIR /appCOPY . .RUN ./mvnw package -DskipTests
FROM eclipse-temurin:21-jre-alpineCOPY --from=build /app/target/*.jar app.jarENTRYPOINT ["java", "-jar", "app.jar"]90. ¿Cuáles son las mejores prácticas de Java?
Section titled “90. ¿Cuáles son las mejores prácticas de Java?”Principios clave para código limpio y mantenible:
- Usar tipos inmutables cuando sea posible
- Preferir composición sobre herencia
- Programar contra interfaces
- Usar Optional en vez de null
- Cerrar recursos con try-with-resources
- Usar constantes en vez de magic numbers
- Seguir convenciones de nombres
- Documentar código público con Javadoc
- Escribir tests unitarios
- Usar logging en vez de System.out
Preguntas de Arquitectura (91-100)
Section titled “Preguntas de Arquitectura (91-100)”91. ¿Qué es una arquitectura de microservicios?
Section titled “91. ¿Qué es una arquitectura de microservicios?”¿Qué es? Aplicación dividida en servicios pequeños, independientes, desplegables por separado.
Comunicación: REST, gRPC, mensajería (Kafka, RabbitMQ).
92. ¿Qué es un API Gateway?
Section titled “92. ¿Qué es un API Gateway?”¿Qué es? Punto de entrada único para microservicios.
Funciones: Routing, autenticación, rate limiting, load balancing, transformación.
93. ¿Qué es Circuit Breaker?
Section titled “93. ¿Qué es Circuit Breaker?”¿Qué es? Patrón que previene cascada de fallos cortando llamadas a servicios fallidos.
Estados: Closed (normal), Open (bloqueado), Half-Open (probando).
94. ¿Qué es Event Sourcing?
Section titled “94. ¿Qué es Event Sourcing?”¿Qué es? Almacenar cambios como secuencia de eventos en vez de estado actual.
Beneficios: Auditoría completa, reconstruir estado, debugging temporal.
95. ¿Qué es CQRS?
Section titled “95. ¿Qué es CQRS?”¿Qué es? Command Query Responsibility Segregation: modelos separados para lectura y escritura.
¿Cuándo usarlo? Sistemas con patrones de lectura/escritura muy diferentes.
96. ¿Qué es un Message Broker?
Section titled “96. ¿Qué es un Message Broker?”¿Qué es? Sistema de mensajería asíncrona que desacopla productores y consumidores.
Ejemplos: Kafka (streaming), RabbitMQ (colas tradicionales).
97. ¿Qué es una base de datos NoSQL?
Section titled “97. ¿Qué es una base de datos NoSQL?”¿Qué es? Bases de datos no relacionales, optimizadas para casos de uso específicos.
Tipos: Document (MongoDB), Key-Value (Redis), Column (Cassandra), Graph (Neo4j).
98. ¿Qué es caching?
Section titled “98. ¿Qué es caching?”¿Qué es? Almacenar datos frecuentes en memoria rápida para reducir latencia.
Herramientas: Redis (distribuido), Caffeine (local), EhCache.
99. ¿Qué es un load balancer?
Section titled “99. ¿Qué es un load balancer?”¿Qué es? Distribuye tráfico entre múltiples instancias de un servicio.
Algoritmos: Round Robin, Least Connections, IP Hash, Weighted.
100. ¿Qué es observabilidad?
Section titled “100. ¿Qué es observabilidad?”¿Qué es? Capacidad de entender el estado interno del sistema.
Pilares: Logs, Métricas, Traces. Herramientas: OpenTelemetry, Prometheus, Grafana, Jaeger.