Módulo 18: Perguntas de Entrevista Spring Boot
Objetivos
Este módulo prepara você para entrevistas técnicas em desenvolvimento Java/Spring Boot. As perguntas estão organizadas por nível de dificuldade e por tema, cobrindo os tópicos mais frequentemente abordados em entrevistas.
Não decore as respostas palavra por palavra. Entenda os conceitos e seja capaz de explicá-los com suas próprias palavras e exemplos concretos.
Capítulos do Módulo
| # | Capítulo | Conteúdo |
|---|---|---|
| 1 | JPA & Banco de Dados | Problema N+1, Lazy/Eager loading, @Transactional, paginação, relações entre entidades |
| 2 | Exercícios de Refatoração | Guard clauses, Strategy Pattern, SRP (God Class), constantes mágicas, composição vs herança |
| 3 | Algoritmos & Estruturas de Dados | HashMap, Stack, LinkedList, Binary Search, Two Sum, FizzBuzz, anagramas |
| 4 | Design REST & Design Patterns | API REST, Builder, Singleton, Observer com Spring Events |
| 5 | Depuração & Code Review | Encontrar bugs, code review, vazamento de memória, concorrência, exceções, code smells |
| 6 | Armadilhas Fundamentais do Java | == vs .equals(), hashCode(), final, static, String imutável, Optional, passagem por valor |
| 7 | Coleções Java | List.of() vs new ArrayList<>(), HashMap, HashSet, Stream API, thread-safety, iteração |
| 8 | "O que é...?" — 30 conceitos | DTO, MVC, API REST, CRUD, POJO, Bean, IoC, ORM/JPA, Maven, Docker, JWT, CORS, Lombok, Record... |
Nível 1 : Perguntas Fundamentais
Q1. O que é Spring Boot e em que ele difere do Spring Framework?
Resposta esperada:
Spring Boot é um framework construído sobre o Spring Framework que simplifica a configuração e o deploy. As principais diferenças:
| Aspecto | Spring Framework | Spring Boot |
|---|---|---|
| Configuração | Manual (XML ou Java) | Auto-configuração |
| Servidor | Servidor externo necessário | Servidor embutido (Tomcat) |
| Dependências | Gerenciadas individualmente | Starters pré-configurados |
| Inicialização | Complexa | main() + @SpringBootApplication |
Spring Boot não substitui o Spring, ele o torna mais fácil de usar.
Q2. O que faz a anotação @SpringBootApplication?
Resposta esperada:
É uma meta-anotação que combina três anotações:
@SpringBootConfiguration: indica uma classe de configuração Spring@EnableAutoConfiguration: ativa a auto-configuração baseada nas dependências do classpath@ComponentScan: escaneia o pacote atual e seus subpacotes para encontrar os beans
Q3. O que é injeção de dependências (DI)?
Resposta esperada:
Injeção de dependências é um padrão de design onde as dependências de um objeto são fornecidas de fora, ao invés de serem criadas pelo próprio objeto.
// SEM DI (alto acoplamento)
public class OrderService {
private UserRepository repo = new UserRepository(); // Cria sua própria dependência
}
// COM DI (baixo acoplamento)
public class OrderService {
private final UserRepository repo;
public OrderService(UserRepository repo) { // Injetada externamente
this.repo = repo;
}
}
Vantagens: testabilidade, baixo acoplamento, flexibilidade.
Q4. Qual a diferença entre @Controller e @RestController?
Resposta esperada:
@Controllerretorna nomes de views (templates HTML). Para retornar JSON, é necessário adicionar@ResponseBodyem cada método.@RestController=@Controller+@ResponseBody. Cada método retorna diretamente dados serializados em JSON.
Q5. Quais são os diferentes escopos de bean no Spring?
Resposta esperada:
| Escopo | Descrição |
|---|---|
| singleton | Uma única instância por container (padrão) |
| prototype | Nova instância a cada injeção |
| request | Uma instância por requisição HTTP |
| session | Uma instância por sessão HTTP |
| application | Uma instância por ServletContext |
Q6. Qual a diferença entre application.properties e application.yml?
Resposta esperada:
Mesma funcionalidade, sintaxe diferente:
# application.properties (chave=valor, plano)
server.port=8080
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
# application.yml (hierárquico, mais legível)
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
YAML é mais legível para configurações aninhadas, mas cuidado com a indentação.
Q7. O que é um Starter do Spring Boot?
Resposta esperada:
Um starter é um conjunto de dependências pré-configuradas para um uso específico:
spring-boot-starter-web: aplicação web (Tomcat, Spring MVC, Jackson)spring-boot-starter-data-jpa: persistência (Hibernate, Spring Data JPA)spring-boot-starter-security: segurança (Spring Security)spring-boot-starter-test: testes (JUnit, Mockito, MockMvc)
Eles evitam o gerenciamento manual de compatibilidade entre versões.
Nível 2 : Perguntas Intermediárias
Q8. Explique a arquitetura em camadas de uma aplicação Spring Boot.
Resposta esperada:
Cliente HTTP
↓
┌─────────────────┐
│ Controller │ Recebe as requisições, valida, retorna as respostas
├─────────────────┤
│ Service │ Lógica de negócio, regras de negócio, orquestração
├─────────────────┤
│ Repository │ Acesso a dados (CRUD, queries no banco)
├─────────────────┤
│ Database │ PostgreSQL, MySQL, H2...
└─────────────────┘
Cada camada só se comunica com a camada imediatamente abaixo. O Controller nunca acessa diretamente o Repository.
Q9. Qual a diferença entre JpaRepository, CrudRepository e PagingAndSortingRepository?
Resposta esperada:
JpaRepository (mais completo)
↑ herda de
PagingAndSortingRepository (paginação + ordenação)
↑ herda de
CrudRepository (CRUD básico)
↑ herda de
Repository (marcador)
- CrudRepository :
save(),findById(),findAll(),deleteById() - PagingAndSortingRepository : adiciona
findAll(Pageable),findAll(Sort) - JpaRepository : adiciona
flush(),saveAndFlush(),deleteInBatch(), retornaListao invés deIterable
Na prática, quase sempre usamos JpaRepository.
Q10. Como funciona a auto-configuração no Spring Boot?
Resposta esperada:
O Spring Boot examina o classpath na inicialização e configura automaticamente os beans necessários:
- Se
spring-boot-starter-data-jpaestá no classpath E existe umaDataSourceconfigurada → auto-configura Hibernate, EntityManager, etc. - Se
spring-boot-starter-webestá no classpath → auto-configura Tomcat, Jackson, DispatcherServlet - As anotações
@ConditionalOn...determinam se uma auto-configuração se aplica
Sempre é possível sobrescrever os beans auto-configurados com nossos próprios @Bean.
Q11. O que são Spring Profiles e para que servem?
Resposta esperada:
Os profiles permitem carregar configurações diferentes conforme o ambiente:
# application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:devdb
# application-prod.yml
spring:
datasource:
url: jdbc:postgresql://prod-server:5432/mydb
Ativação: --spring.profiles.active=prod ou SPRING_PROFILES_ACTIVE=prod
Também é possível condicionar beans com @Profile("dev").
Q12. Explique a diferença entre @Transactional de leitura e de escrita.
Resposta esperada:
@Transactional(readOnly = true) // Leitura: otimização do Hibernate (sem dirty checking)
public List<User> findAll() { ... }
@Transactional // Escrita: commit se sucesso, rollback se exceção
public User create(UserDto dto) { ... }
Boa prática: Colocar @Transactional(readOnly = true) no nível da classe de serviço, e @Transactional apenas nos métodos de escrita.
Q13. Como tratar exceções em uma API REST Spring Boot?
Resposta esperada:
Três abordagens, da mais local à mais global:
@ExceptionHandlerem um controller (escopo local)@RestControllerAdvicecom@ExceptionHandler(escopo global)@ResponseStatusem uma exceção customizada
A melhor prática é o @RestControllerAdvice global que centraliza todo o tratamento de erros.
Q14. O que é o problema N+1 no JPA e como resolvê-lo?
Resposta esperada:
O problema N+1 ocorre quando uma entidade é carregada e o JPA executa N queries adicionais para carregar as relações:
1 query para carregar 100 departamentos
+ 100 queries para carregar os funcionários de cada departamento
= 101 queries ao invés de 1 ou 2
Soluções:
JOIN FETCHem JPQL :@Query("SELECT d FROM Department d JOIN FETCH d.employees")@EntityGraph:@EntityGraph(attributePaths = {"employees"})@BatchSize: carrega as relações em lotes
Q15. Como proteger uma API REST com JWT?
Resposta esperada:
O fluxo JWT:
1. Cliente envia login/senha → POST /api/auth/login
2. Servidor verifica as credenciais
3. Se OK → gera um JWT assinado e retorna
4. Cliente armazena o JWT
5. Para cada requisição → Authorization: Bearer <token>
6. JwtAuthenticationFilter extrai e valida o token
7. Se válido → autentica o usuário no SecurityContext
Componentes chave: JwtService (geração/validação), JwtAuthenticationFilter (filtro), SecurityConfig (configuração).
Nível 3 : Perguntas Avançadas
Q16. Explique o padrão IoC (Inversion of Control) no Spring.
Resposta esperada:
IoC inverte o fluxo de controle: ao invés do código criar suas dependências, o container Spring as cria e injeta.
O container Spring (ApplicationContext) é responsável por:
- Criar os objetos (beans)
- Configurar os objetos
- Montar as dependências
- Gerenciar o ciclo de vida
A injeção de dependências (DI) é o principal mecanismo de IoC no Spring.
Q17. Qual a diferença entre @Component, @Service, @Repository e @Controller?
Resposta esperada:
Tecnicamente, os quatro são @Component. A diferença é semântica (papel na arquitetura):
@Component: bean genérico@Service: lógica de negócio@Repository: acesso a dados + tradução automática de exceções SQL para exceções Spring@Controller: manipulação de requisições web
Usar a anotação correta ajuda na legibilidade e permite tratamentos específicos (ex: tradução de exceções para @Repository).
Q18. Como implementar paginação no Spring Data JPA?
Resposta esperada:
// Repository
public interface UserRepository extends JpaRepository<User, Long> {
Page<User> findByRole(Role role, Pageable pageable);
}
// Controller
@GetMapping("/users")
public Page<User> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(defaultValue = "name") String sortBy) {
Pageable pageable = PageRequest.of(page, size, Sort.by(sortBy));
return userRepository.findAll(pageable);
}
O Page<T> retornado contém: conteúdo, número da página, tamanho, total de elementos, número de páginas.
Q19. Explique as diferentes estratégias de propagação do @Transactional.
Resposta esperada:
| Propagação | Comportamento |
|---|---|
REQUIRED (padrão) | Junta-se à transação existente ou cria uma nova |
REQUIRES_NEW | Sempre cria uma nova transação (suspende a existente) |
SUPPORTS | Junta-se se existir, senão executa sem transação |
NOT_SUPPORTED | Sempre executa sem transação (suspende a existente) |
MANDATORY | Exige transação existente, senão lança exceção |
NEVER | Não pode haver transação, senão lança exceção |
NESTED | Transação aninhada (savepoint) |
Caso de uso frequente do REQUIRES_NEW: log de auditoria que deve persistir mesmo se a transação principal falhar.
Q20. Como otimizar a performance de uma aplicação Spring Boot?
Resposta esperada:
-
JPA/Hibernate:
- Evitar o problema N+1 (JOIN FETCH, EntityGraph)
- Usar
@Transactional(readOnly = true)para leituras - Projeções DTO ao invés de entidades completas
- Paginação sistemática
-
Cache:
@Cacheablecom Spring Cache (Redis, Caffeine)- Cache HTTP (ETag, Cache-Control)
-
Configuração:
- Connection pooling (HikariCP bem configurado)
- Compressão GZIP
- Perfis otimizados para produção
-
Arquitetura:
- Operações assíncronas (
@Async) - Indexação adequada no banco de dados
- Lazy loading das relações
- Operações assíncronas (
Q21. O que é Spring Actuator e quais endpoints úteis ele fornece?
Resposta esperada:
Spring Actuator fornece endpoints de monitoramento e gerenciamento:
| Endpoint | Descrição |
|---|---|
/actuator/health | Estado da aplicação (UP/DOWN) |
/actuator/info | Informações da aplicação |
/actuator/metrics | Métricas (memória, CPU, requisições) |
/actuator/env | Variáveis de ambiente |
/actuator/beans | Lista de todos os beans |
/actuator/mappings | Todos os endpoints REST |
/actuator/loggers | Configuração dos loggers |
/actuator/prometheus | Métricas no formato Prometheus |
Em produção, é necessário proteger esses endpoints e expor apenas /health e /info publicamente.
Q22. Explique o ciclo de vida de um bean Spring.
Resposta esperada:
1. Instanciação (construtor)
2. Injeção de dependências (@Autowired)
3. Aware interfaces (BeanNameAware, ApplicationContextAware...)
4. BeanPostProcessor.postProcessBeforeInitialization()
5. @PostConstruct
6. InitializingBean.afterPropertiesSet()
7. init-method customizado
8. BeanPostProcessor.postProcessAfterInitialization()
9. ══════ Bean pronto para uso ══════
10. @PreDestroy
11. DisposableBean.destroy()
12. destroy-method customizado
Na prática, usamos principalmente @PostConstruct e @PreDestroy.
Q23. Como implementar um padrão CQRS simplificado com Spring Boot?
Resposta esperada:
CQRS (Command Query Responsibility Segregation) separa operações de leitura e escrita:
// Command (escrita)
@Service
@Transactional
public class UserCommandService {
public User create(CreateUserCommand cmd) { ... }
public void update(UpdateUserCommand cmd) { ... }
public void delete(Long id) { ... }
}
// Query (leitura)
@Service
@Transactional(readOnly = true)
public class UserQueryService {
public UserDto findById(Long id) { ... }
public Page<UserDto> findAll(Pageable page) { ... }
}
Isso permite otimizar leituras e escritas separadamente (ex: projeções DTO para leitura, validações complexas para escrita).
Perguntas Comportamentais / Cenários
Q24. Você precisa projetar uma API REST para um sistema de e-commerce. Quais endpoints você criaria?
Resposta esperada:
Products:
GET /api/products → Lista paginada
GET /api/products/{id} → Detalhe de um produto
POST /api/products → Criar (ADMIN)
PUT /api/products/{id} → Alterar (ADMIN)
DELETE /api/products/{id} → Remover (ADMIN)
Orders:
POST /api/orders → Realizar um pedido
GET /api/orders → Meus pedidos
GET /api/orders/{id} → Detalhe de um pedido
PATCH /api/orders/{id} → Alterar status (ADMIN)
Auth:
POST /api/auth/register → Cadastro
POST /api/auth/login → Login (retorna JWT)
POST /api/auth/refresh → Refresh do token
Cart:
GET /api/cart → Meu carrinho
POST /api/cart/items → Adicionar ao carrinho
DELETE /api/cart/items/{id} → Remover do carrinho
Q25. Sua aplicação Spring Boot está lenta em produção. Como você diagnostica?
Resposta esperada:
- Métricas do Actuator : verificar
/actuator/metrics/http.server.requestspara identificar endpoints lentos - Logs : ativar
logging.level.org.hibernate.SQL=DEBUGpara ver as queries SQL - Problema N+1 : verificar o número de queries com
spring.jpa.show-sql=true - Connection pool : verificar métricas do HikariCP (
hikaricp.connections.active) - Profiling : VisualVM ou JFR (Java Flight Recorder)
- Índices no banco : analisar queries lentas com
EXPLAIN ANALYZE - Memória : verificar garbage collector e heap size
Checklist de Preparação
Antes da sua entrevista, certifique-se de que você consegue:
- Explicar IoC e DI com um exemplo concreto
- Descrever a arquitetura em camadas de uma aplicação Spring Boot
- Escrever um CRUD completo (Controller → Service → Repository)
- Explicar JWT e o fluxo de autenticação
- Falar sobre seus projetos pessoais com Spring Boot
- Descrever como você trata exceções
- Explicar a diferença entre as principais anotações
- Falar sobre Docker e CI/CD com Spring Boot
- Conhecer o básico de paginação e ordenação
- Saber diagnosticar problemas de performance