Preguntas de entrevista Senior: Spring Boot y Java
En este post te mostrare los principales temas que deberías conocer si quieres avanzar para pasar de semi-senior a senior backend developer Spring Boot con Java.
Antes de continuar con este post te recomiendo ver los siguientes dos videos, en los cuales hablo de junior y semi-senior.
Ahora si, vamos a los temas que deberías saber para poder considerarse senior backend developer con Java y Spring Boot.
Temas que deberías saber
En Youtube he subido un video donde reviso los temas que abordare en este post, asi como también, revisaré algunos conceptos de clean-architecture y algunos ejercicios de programación que suelen poner en los live code challenge de una entrevista técnica.
Principios SOLID
Los principios SOLID son un conjunto de cinco principios de diseño orientado a objetos que promueven la creación de software más comprensible, flexible y mantenible. A continuación se describen cada uno de los principios:
- Single Responsibility Principle (SRP) - Principio de Responsabilidad Única:
- Una clase debe tener una, y solo una, razón para cambiar. Esto significa que una clase debe tener una única responsabilidad o propósito.
- Ejemplo: Una clase
User
debería manejar solo la lógica relacionada con los usuarios, mientras que una claseUserRepository
debería encargarse de las operaciones de persistencia de datos de los usuarios.
- Open/Closed Principle (OCP) - Principio Abierto/Cerrado:
- Las entidades de software (clases, módulos, funciones, etc.) deben estar abiertas para la extensión pero cerradas para la modificación. Esto significa que el comportamiento de una clase debe poder extenderse sin modificar su código fuente.
- Ejemplo: En lugar de modificar una clase para agregar nueva funcionalidad, se debe utilizar la herencia o la composición para extender el comportamiento.
- Liskov Substitution Principle (LSP) - Principio de Sustitución de Liskov:
- Los objetos de una clase derivada deben ser sustituibles por objetos de la clase base sin alterar el comportamiento esperado del programa. Esto significa que una subclase debe ser capaz de sustituir a su superclase sin que el programa falle.
- Ejemplo: Si una clase
Bird
tiene un métodofly
, todas las subclases, comoSparrow
oEagle
, deben implementarfly
de manera que respeten el contrato de la clase baseBird
.
- Interface Segregation Principle (ISP) - Principio de Segregación de Interfaces:
- Los clientes no deben estar forzados a depender de interfaces que no utilizan. Esto significa que es mejor tener muchas interfaces específicas y pequeñas en lugar de una interfaz grande y general.
- Ejemplo: En lugar de tener una interfaz
Animal
con métodosfly
,swim
ywalk
, es mejor tener interfaces más específicas comoFlyable
,Swimmable
yWalkable
.
- Dependency Inversion Principle (DIP) - Principio de Inversión de Dependencias:
- Los módulos de alto nivel no deben depender de módulos de bajo nivel. Ambos deben depender de abstracciones. Además, las abstracciones no deben depender de los detalles; los detalles deben depender de las abstracciones.
- Ejemplo: En lugar de que una clase de alto nivel dependa directamente de una clase de bajo nivel, debería depender de una interfaz o una clase abstracta que la clase de bajo nivel implemente. Por ejemplo, una clase
OrderService
debería depender de una interfazPaymentProcessor
en lugar de una implementación concreta comoPaypalPaymentProcessor
.
Principios de arquitectura
- Principio de Separación de Preocupaciones (Separation of Concerns):
- Divide el sistema en distintas secciones, cada una con una única responsabilidad. Esto mejora la modularidad y facilita el mantenimiento y la evolución del sistema.
- Principio de Abstracción (Abstraction):
- Utiliza abstracciones para reducir la complejidad al ocultar los detalles de implementación, permitiendo a los desarrolladores centrarse en conceptos de más alto nivel.
- Principio de Encapsulación (Encapsulation):
- Agrupa datos y métodos que operan sobre esos datos en un único componente o módulo, restringiendo el acceso a ciertos detalles internos para proteger la integridad del sistema.
- Principio de Modulación (Modularity):
- Descompone el sistema en módulos independientes y reutilizables. Cada módulo debe tener una única responsabilidad y debe ser fácilmente reemplazable y actualizable.
- Principio de Composición sobre Herencia (Composition over Inheritance):
- Prefiere la composición de objetos a la herencia para reutilizar código y mantener la flexibilidad en la estructura del sistema.
- Principio de Cohesión (Cohesion):
- Asegura que los elementos dentro de un módulo estén altamente relacionados y trabajen juntos para lograr una única tarea o propósito.
- Principio de Acoplamiento (Coupling):
- Minimiza las dependencias entre diferentes módulos del sistema para reducir el impacto de los cambios y facilitar el mantenimiento.
- Principio de Interfaz Clara (Clear Interface):
- Diseña interfaces claras y bien definidas para cada módulo o componente, permitiendo una interacción coherente y predecible entre ellos.
- Principio de Reutilización (Reuse):
- Promueve la reutilización de componentes y módulos existentes para reducir el tiempo de desarrollo y mejorar la consistencia del sistema.
- Principio de Simplicidad (Simplicity):
- Diseña soluciones simples siempre que sea posible, evitando la complejidad innecesaria que pueda dificultar el mantenimiento y la evolución del sistema.
- Principio de Transparencia (Transparency):
- Asegura que los sistemas y procesos internos sean fácilmente comprensibles y accesibles para los desarrolladores y usuarios, promoviendo la claridad y la facilidad de diagnóstico.
- Principio de Portabilidad (Portability):
- Diseña el sistema para que pueda ser fácilmente transferido y ejecutado en diferentes entornos y plataformas sin requerir cambios significativos.
- Principio de Escalabilidad (Scalability):
- Asegura que el sistema pueda crecer y manejar un aumento en la carga de trabajo sin degradar su rendimiento.
- Principio de Disponibilidad (Availability):
- Diseña el sistema para minimizar el tiempo de inactividad y asegurar que esté disponible para los usuarios siempre que sea necesario.
- Principio de Seguridad (Security):
- Incorpora medidas de seguridad adecuadas en el diseño del sistema para proteger contra amenazas y vulnerabilidades.
- Principio de Tolerancia a Fallos (Fault Tolerance):
- Diseña el sistema para que pueda continuar funcionando correctamente incluso en presencia de fallos parciales.
- Principio de Consistencia (Consistency):
- Asegura que los datos y el comportamiento del sistema sean coherentes y predecibles, incluso en situaciones de concurrencia y fallos.
- Principio de Desempeño (Performance):
- Optimiza el diseño del sistema para asegurar que se cumplan los requisitos de rendimiento, incluyendo tiempo de respuesta y capacidad de procesamiento.
- Principio de Evolvibilidad (Evolvability):
- Diseña el sistema de manera que sea fácil de modificar y adaptar a futuros cambios en los requisitos o en el entorno.
- Principio de Documentación (Documentation):
- Mantén una documentación clara y completa del diseño y la arquitectura del sistema para facilitar la comprensión y el mantenimiento por parte de otros desarrolladores.
Patrones de arquitectura de software
- Monolítico (Monolithic Architecture):
- Una aplicación unificada que gestiona todas las funcionalidades en un solo despliegue.
- Microservicios (Microservices Architecture):
- Una arquitectura que descompone la aplicación en pequeños servicios independientes, cada uno con su propia lógica de negocio y almacenamiento de datos.
- Event-Driven Architecture (EDA):
- Basada en la producción, detección y reacción a eventos, esta arquitectura permite a los componentes de la aplicación comunicarse a través de eventos asincrónicos.
- Arquitectura en Capas (Layered Architecture):
- Divide la aplicación en capas lógicas, como presentación, lógica de negocio, persistencia de datos, etc., cada una con responsabilidades específicas.
- Arquitectura Hexagonal (Hexagonal Architecture o Ports and Adapters):
- Promueve la separación de la lógica de negocio del código de infraestructura mediante el uso de puertos y adaptadores, permitiendo la intercambiabilidad de componentes.
- Arquitectura de Microkernel (Microkernel Architecture):
- Consta de un núcleo minimalista con funcionalidades básicas y un conjunto de plugins o módulos para añadir características específicas.
- Arquitectura basada en Servicios (Service-Oriented Architecture, SOA):
- Los servicios independientes se comunican entre sí mediante protocolos estándar para realizar tareas específicas y cooperar para formar aplicaciones más grandes.
- Arquitectura Orientada a Eventos (Event-Driven Architecture):
- Utiliza un mecanismo de mensajería para detectar y procesar eventos generados por las acciones de los usuarios u otras aplicaciones.
- Arquitectura de Componentes (Component-Based Architecture):
- La aplicación se divide en componentes independientes que pueden ser ensamblados para formar una aplicación completa.
- Arquitectura de Espacio de Nombres (Space-Based Architecture):
- Diseñada para aplicaciones de gran escala, esta arquitectura utiliza un espacio de memoria compartido para gestionar la distribución y la escalabilidad.
- Arquitectura de Máquina de Estado (State Machine Architecture):
- Modela la lógica de la aplicación como una máquina de estados, donde los estados y transiciones determinan el comportamiento del sistema.
- Arquitectura de Pipelines y Filtros (Pipeline and Filter Architecture):
- Descompone el procesamiento de datos en una serie de etapas (filtros) que se conectan en un pipeline, donde cada filtro realiza una transformación específica.
- Arquitectura de Cliente-Servidor (Client-Server Architecture):
- Divide la aplicación en dos componentes principales: el cliente, que solicita servicios, y el servidor, que proporciona esos servicios.
- Arquitectura de N-capas (N-Tier Architecture):
- Una extensión de la arquitectura en capas, donde cada capa puede residir en un servidor diferente, permitiendo la distribución física de las capas.
- Arquitectura de Agente (Agent-Based Architecture):
- Utiliza agentes autónomos y cooperativos para realizar tareas específicas, comunicándose y colaborando entre sí para alcanzar los objetivos del sistema.
- Arquitectura RESTful:
- Basada en el protocolo HTTP, esta arquitectura utiliza recursos identificados por URIs y operaciones CRUD para la comunicación entre cliente y servidor.
- Arquitectura CQRS (Command Query Responsibility Segregation):
- Separa las operaciones de lectura y escritura en diferentes modelos, optimizando cada uno para su propósito específico.
- Arquitectura Lambda:
- Combina procesamiento batch y en tiempo real para gestionar grandes volúmenes de datos, utilizando una capa de velocidad para el procesamiento en tiempo real y una capa batch para el procesamiento por lotes.
- Arquitectura de Grafos (Graph-Based Architecture):
- Utiliza grafos para representar y gestionar relaciones entre datos, aprovechando bases de datos de grafos para consultas y análisis eficientes.
- Arquitectura de Servidorless (Serverless Architecture):
- Permite a los desarrolladores construir y ejecutar aplicaciones sin gestionar la infraestructura del servidor, delegando la ejecución de funciones a un proveedor de servicios en la nube.
Conocimientos Cloud
Preguntas de entrevista
Preguntas generales sobre tu CV
- ¿Cual era tu rol en la ultima empresa que trabajaste o en la que estas trabajando actualmente?
- ¿Cómo es el flujo de trabajo en la ultima empresa que trabajaste o en la que estas trabajando actualmente?
- ¿Qué tecnologías y versiones de esa tecnología usabas en tu ultimo empleo?
- ¿Has tenido gente a cargo?
- ¿Cómo te sientes en un rol donde tengas personas a cargo?
- ¿Qué es lo mas retador que has hecho a nivel técnico?
- ¿Cómo te mantienes actualizado de nuevas tecnologías?
- ¿Cómo monitoreas que tus servicios estén bien?
- ¿Cuál ha sido la mayor cantidad de datos con la que has trabajado?
Preguntas técnicas
- ¿Qué es un bean en Spring y cómo se define?
- Un bean en Spring es un objeto que forma parte del contenedor de Spring y que es gestionado por el contenedor de IoC (Inversión de Control). Se define usando anotaciones como
@Component
,@Service
,@Repository
, o mediante la configuración XML.
- Un bean en Spring es un objeto que forma parte del contenedor de Spring y que es gestionado por el contenedor de IoC (Inversión de Control). Se define usando anotaciones como
- Explica el ciclo de vida de un bean en Spring.
- El ciclo de vida de un bean en Spring incluye su instanciación, configuración, inicialización y eventual destrucción. Esto se gestiona mediante el contenedor de IoC, que invoca métodos de callback como
@PostConstruct
y@PreDestroy
.
- El ciclo de vida de un bean en Spring incluye su instanciación, configuración, inicialización y eventual destrucción. Esto se gestiona mediante el contenedor de IoC, que invoca métodos de callback como
- ¿Qué es un contenedor de IoC (Inversión de Control) y cuál es su función en Spring?
- El contenedor de IoC es el núcleo de Spring, responsable de la creación, configuración y gestión de los beans. Facilita la inyección de dependencias, permitiendo a los desarrolladores definir las dependencias de los objetos en lugar de crear y gestionar esas dependencias manualmente.
- ¿Qué es la anotación
@RestController
en Spring y cómo se diferencia de@Controller
?-
@RestController
es una combinación de@Controller
y@ResponseBody
. Indica que el controlador maneja solicitudes web y devuelve respuestas JSON o XML. A diferencia de@Controller
, no requiere la anotación@ResponseBody
en cada método.
-
- ¿Cómo manejarías excepciones en una aplicación Spring Boot?
- Se pueden manejar excepciones usando
@ControllerAdvice
y@ExceptionHandler
.@ControllerAdvice
permite definir un manejo global de excepciones para múltiples controladores. Estas excepciones son capturadas y puedes personalizar el mensaje de error que se envía.
- Se pueden manejar excepciones usando
- ¿Qué es la anotación
@Transactional
y cuál es su función?@Transactional
es una anotación que proporciona gestión de transacciones en Spring. Se utiliza para definir los límites de una transacción y asegurar que todas las operaciones dentro de una transacción se completen correctamente o se reviertan si ocurre un error.
- ¿Qué es la inyección de dependencias y cómo se implementa en Spring Boot?
- La inyección de dependencias es un patrón de diseño donde un objeto recibe sus dependencias en lugar de crearlas por sí mismo. En Spring Boot, se implementa usando anotaciones como
@Autowired
,@Inject
, o a través de la configuración de beans en XML o Java.
- La inyección de dependencias es un patrón de diseño donde un objeto recibe sus dependencias en lugar de crearlas por sí mismo. En Spring Boot, se implementa usando anotaciones como
- ¿Cuál es la diferencia entre una clase abstracta y una interfaz en Java?
- Una clase abstracta puede contener métodos implementados y no implementados, así como atributos y constructores. Una interfaz solo puede contener métodos abstractos (hasta Java 7) o métodos predeterminados y estáticos (a partir de Java 8), y no puede tener atributos (excepto constantes).
- ¿Qué es el patrón MVC (Modelo-Vista-Controlador) y cómo se aplica en Spring Boot?
- MVC es un patrón de diseño que separa la aplicación en tres componentes: Modelo (datos y lógica de negocio), Vista (interfaz de usuario) y Controlador (maneja la lógica de flujo de la aplicación). En Spring Boot, se aplica usando anotaciones como
@Controller
para los controladores, y modelos y vistas se manejan mediante objetos de dominio y tecnologías de vista como Thymeleaf o JSP.
- MVC es un patrón de diseño que separa la aplicación en tres componentes: Modelo (datos y lógica de negocio), Vista (interfaz de usuario) y Controlador (maneja la lógica de flujo de la aplicación). En Spring Boot, se aplica usando anotaciones como
- ¿Qué es Spring Security y cómo se configura en una aplicación Spring Boot?
- Spring Security es un marco de seguridad para aplicaciones Java, que proporciona autenticación y autorización. Se configura añadiendo la dependencia de Spring Security al proyecto y definiendo una clase de configuración que extiende
WebSecurityConfigurerAdapter
. Spring Security es tan extenso como el mismo Spring Boot.
- Spring Security es un marco de seguridad para aplicaciones Java, que proporciona autenticación y autorización. Se configura añadiendo la dependencia de Spring Security al proyecto y definiendo una clase de configuración que extiende
- ¿Qué es un filtro en una aplicación web y cómo se configura en Spring Boot?
- Un filtro es un objeto que realiza tareas de filtrado en las solicitudes y respuestas de las aplicaciones web. En Spring Boot, se puede configurar un filtro implementando la interfaz
javax.servlet.Filter
y registrándolo con@WebFilter
o mediante una clase@Configuration
.
- Un filtro es un objeto que realiza tareas de filtrado en las solicitudes y respuestas de las aplicaciones web. En Spring Boot, se puede configurar un filtro implementando la interfaz
- ¿Qué es el patrón de diseño Singleton y cómo se implementa en Java?
- El patrón Singleton asegura que una clase tenga una sola instancia y proporciona un punto de acceso global a ella. En Java, se puede implementar usando una instancia estática y un método estático para obtener la instancia.
- ¿Qué es la serialización en Java y cuál es su uso?
- La serialización es el proceso de convertir un objeto en un flujo de bytes para poder almacenarlo o transmitirlo. Se usa implementando la interfaz
Serializable
en la clase y utilizandoObjectOutputStream
para escribir el objeto yObjectInputStream
para leerlo.
- La serialización es el proceso de convertir un objeto en un flujo de bytes para poder almacenarlo o transmitirlo. Se usa implementando la interfaz
- ¿Cómo se realiza la validación de datos en una aplicación Spring Boot?
- La validación de datos se realiza usando las anotaciones de Bean Validation (JSR 380) como
@NotNull
,@Size
,@Email
, etc., y se puede manejar en los controladores usando@Valid
o@Validated
.
- La validación de datos se realiza usando las anotaciones de Bean Validation (JSR 380) como
- ¿Qué es un perfil de Spring y cuál es su propósito?
- Un perfil de Spring permite definir diferentes configuraciones para diferentes entornos (como desarrollo, prueba, producción). Se activan usando la anotación
@Profile
en las clases de configuración o beans, y se especifican en el archivo de propiedades o mediante variables de entorno.
- Un perfil de Spring permite definir diferentes configuraciones para diferentes entornos (como desarrollo, prueba, producción). Se activan usando la anotación
- ¿Qué es la anotación
@Autowired
y cuándo se utiliza? ¿Qué otros métodos de inyección de dependencias existen?@Autowired
es una anotación que se utiliza para inyectar automáticamente dependencias en Spring. Se puede usar en campos, constructores y métodos de setter para que Spring resuelva y asigne las dependencias necesarias. Entre los demás métodos para inyectas dependencias existen: inyección de dependencia por constructor e inyecciones de dependencia mediante método setter.
- ¿Qué es la anotación
@ComponentScan
en Spring y cómo se configura?-
@ComponentScan
es una anotación que indica a Spring dónde buscar los componentes, servicios y otros beans gestionados por Spring. Se configura en una clase de configuración principal con@Configuration
.
-
- ¿Qué es un servicio RESTful y cómo se implementa en Spring Boot?
- Un servicio RESTful es un servicio web que sigue los principios REST, utilizando HTTP para realizar operaciones CRUD. En Spring Boot, se implementa usando controladores con anotaciones como
@RestController
y métodos anotados con@GetMapping
,@PostMapping
,@PutMapping
, y@DeleteMapping
.
- Un servicio RESTful es un servicio web que sigue los principios REST, utilizando HTTP para realizar operaciones CRUD. En Spring Boot, se implementa usando controladores con anotaciones como
- ¿Cómo gestionarías la seguridad de una API REST en Spring Boot?
- La seguridad de una API REST en Spring Boot se gestiona usando Spring Security para configurar autenticación y autorización, definiendo roles y permisos, y utilizando JWT (JSON Web Tokens) para la autenticación sin estado.
- ¿Qué es JPA (Java Persistence API) y cuál es su relación con Spring Boot?
- JPA es una especificación de Java para la gestión de datos relacionales en aplicaciones Java. Spring Boot facilita la integración de JPA proporcionando configuraciones automáticas y soporte para proveedores como Hibernate. También se suele preguntar la diferencia entre JPA y Hibernate.
- ¿Qué es Hibernate y cómo se integra con Spring Boot para la persistencia de datos?
- Hibernate es una implementación de JPA que proporciona un marco ORM (Object-Relational Mapping). Se integra con Spring Boot añadiendo las dependencias de Hibernate y configurando las propiedades de la base de datos en el archivo de propiedades.
- ¿Qué es el patrón DAO (Data Access Object) y cómo se implementa en Spring Boot?
- El patrón DAO separa la lógica de acceso a datos del negocio, proporcionando una interfaz para realizar operaciones CRUD. En Spring Boot, se implementa creando interfaces que extienden
JpaRepository
oCrudRepository
.
- El patrón DAO separa la lógica de acceso a datos del negocio, proporcionando una interfaz para realizar operaciones CRUD. En Spring Boot, se implementa creando interfaces que extienden
- ¿Qué es un ORM (Object-Relational Mapping) y cuál es su función en una aplicación Spring Boot?
- Un ORM es una técnica de programación que permite mapear objetos de dominio a bases de datos relacionales. En Spring Boot, se usa para facilitar la persistencia de datos mediante herramientas como JPA y Hibernate.
- ¿Qué es el patrón Factory y cuál es su uso en Java?
- El patrón Factory es un patrón de diseño creacional que proporciona una interfaz para crear objetos en una superclase, pero permite que las subclases alteren el tipo de objetos que se crearán. Se usa para manejar la creación de objetos sin especificar la clase exacta de los objetos que se crearán.
- ¿Qué es el patrón Observer y cómo se implementa en Java?
- El patrón Observer es un patrón de diseño de comportamiento que permite a un objeto notificar a otros objetos sobre cambios en su estado. En Java, se puede implementar usando las interfaces
Observer
yObservable
.
- El patrón Observer es un patrón de diseño de comportamiento que permite a un objeto notificar a otros objetos sobre cambios en su estado. En Java, se puede implementar usando las interfaces
- ¿Cómo manejarías la concurrencia en una aplicación Spring Boot?
- La concurrencia se maneja en Spring Boot utilizando las clases del paquete
java.util.concurrent
, comoExecutorService
, y configurando hilos y pools de hilos en las tareas asíncronas con@Async
y@Scheduled
.
- La concurrencia se maneja en Spring Boot utilizando las clases del paquete
Si quieres conocer otros artículos parecidos a Preguntas de entrevista Senior: Spring Boot y Java puedes visitar la categoría Java.
Entradas relacionadas