Spring Boot Interview Questions and Answers for Experienced Developers

Spring Boot interviews for experienced Java developers go far beyond "what is a bean?" Hiring managers want to see that you can ship production APIs—configure auto-wiring correctly, reason about transactions and lazy loading, secure endpoints with OAuth2/JWT, debug slow queries, and explain how your service behaves under load. Loops for 5–10 years of experience often blend framework depth with system design: caching, messaging, deployment on Kubernetes, and trade-offs between monolith modules and microservices.

Below are 45 questions aimed at Spring Boot interview questions for experienced candidates—including senior and 10 years experienced loops. Answers are written so you can learn while prepping: tables, small code samples, with elaborate answers; technical sections include a strong answer sample you can say aloud. Pair this guide with OOP interview questions for SOLID and design-pattern depth, Java interview questions part 1 and part 2 for JVM and concurrency fundamentals, Kafka interview questions for event streaming and messaging depth, Kubernetes interview questions for deploying services to clusters, PostgreSQL interview questions for JPA datasource and query tuning depth, full stack developer interviews for React/Spring integration, Maven interview questions for build and BOM imports, Selenium interview questions for UI test automation alongside @SpringBootTest, and SQL technical interviews when JPA questions turn into query plans.

NOTE
Prep target: Experienced loops favor scenario answers—a REST API with JPA, a failed transaction you debugged, a security filter chain you customized, or a production incident traced with Actuator and logs. Use What interviewers are testing to understand the competency behind each question, then practise A strong answer is naturally in your own words.

Interview context and how to prepare

What do Spring Boot interviews test for experienced developers?

Spring Boot is the default way most Java teams bootstrap web applications, batch jobs, and microservices. Interviewers are not checking whether you memorized every starter artifact—they want proof you can build and operate Spring applications.

Typical skill layers:

Layer What interviewers probe
Core & DI Beans, scopes, @Configuration, component scanning
Auto-config How starters wire defaults; when to override
Web layer REST design, validation, exception handling
Data Spring Data JPA, transactions, N+1, migrations
Security Filter chain, JWT/OAuth2, method security
Testing Slice tests, Testcontainers, mocking boundaries
Production Actuator, metrics, profiles, health checks
Modern Java Records as DTOs, virtual threads, Spring Boot 4 / Jakarta (Boot 3.x still common in production)
Experience What changes in the room
3–5 years CRUD APIs, basic JPA, starter dependencies
5–8 years Transactions, security, testing strategy, performance
8–10+ years System design, microservices boundaries, operability, mentoring

A strong answer is:

Experienced Spring Boot interviews test whether I can connect framework concepts to production behavior—dependency injection, transactions, security, database performance, testing, observability, and deployment—not just recognize annotations.

Spring Boot vs Spring Framework — what is the difference?

What interviewers are testing: Whether you distinguish Spring Framework core capabilities from Spring Boot's conventions, starters, auto-configuration, and production packaging.

Spring Framework is the core inversion-of-control container: beans, AOP, MVC, transaction abstraction, and integration modules. You can build apps with plain Spring, but you assemble a lot manually—XML or Java config, embedded server setup, dependency versions.

Spring Boot sits on top and optimizes for convention over configuration:

Concern Spring Framework alone Spring Boot
Dependency versions You align JAR versions BOM / parent POM (spring-boot-dependencies)
Embedded server You wire Tomcat/Jetty spring-boot-starter-web brings Tomcat by default
Auto-configuration Manual @Configuration Classpath-driven @EnableAutoConfiguration
Run command Deploy WAR to external server java -jar app.jar or spring-boot:run
Production features Add Actuator yourself spring-boot-starter-actuator

Spring Boot does not replace Spring concepts—you still need to understand beans, @Transactional, and MVC. Boot removes boilerplate so you focus on business code.

A strong answer is:

Spring Boot does not replace Spring concepts—you still need to understand beans, @Transactional, and MVC. Boot removes boilerplate so you focus on business code.

What is a typical Spring Boot interview loop for 5–10 years experience?

What interviewers are testing: Whether you know what experienced Spring Boot interview loops emphasize beyond basic CRUD—architecture, operability, and production scenarios.

Loops vary by company (product, bank, consultancy, startup), but experienced Java Spring Boot patterns often look like this:

Round Duration Focus
Recruiter / HM 30 min Projects, team size, cloud exposure
Spring Boot deep dive 60–90 min JPA, security, REST, configuration, testing
System design 45–60 min Microservice boundaries, messaging, caching, deployment
Live coding / review 45–60 min Fix a controller, write a repository query, debug a test
Behavioral 30–45 min Incidents, deadlines, code review culture

For 10 years experienced roles, expect more architecture and operability—how you roll out config changes, handle schema migrations, and observe services in Kubernetes or VM fleets.

A strong answer is:

For 10 years experienced roles, expect more architecture and operability—how you roll out config changes, handle schema migrations, and observe services in Kubernetes or VM fleets.

What is a realistic 4–6 week prep plan?

Treat prep as one reference application you can explain aloud—not fifty disconnected flashcards.

Week Focus Concrete output
1 Core Boot — starters, auto-config, profiles Run a small REST app; list beans with Actuator
2 Data — JPA, transactions, Flyway CRUD + custom query; reproduce and fix N+1
3 Security — JWT or OAuth2 resource server Protect one endpoint; document filter chain
4 Testing — slices + Testcontainers @WebMvcTest, @DataJpaTest, one integration test
5 Production — metrics, logging, virtual threads Enable Actuator; try spring.threads.virtual.enabled on Java 21
6 Scenarios — design + stories Whiteboard order service; rehearse two production incidents

A strong answer is:

I prepare one Spring Boot service end to end: REST and DI first, JPA and transactions next, then security, testing, observability, and finally a few production scenarios I can explain from experience.


Core Spring Boot and dependency injection

What does @SpringBootApplication do?

What interviewers are testing: Whether you know what @SpringBootApplication composes and how component scanning and auto-configuration begin from the application class.

@SpringBootApplication is a composed annotation that combines three important switches:

java
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

Under the hood it typically includes:

Annotation Role
@SpringBootConfiguration Marks the class as a source of @Bean definitions (specialized @Configuration)
@EnableAutoConfiguration Imports auto-configuration classes based on classpath
@ComponentScan Scans the package of the application class and sub-packages for stereotypes

SpringApplication.run bootstraps the context, starts the embedded web server (if spring-boot-starter-web is present), and registers shutdown hooks.

Common follow-up: How do you exclude an auto-configuration? Use @SpringBootApplication(exclude = SomeAutoConfiguration.class) or spring.autoconfigure.exclude in properties.

A strong answer is:

@SpringBootApplication enables component scanning and auto-configuration from my main class package downward, and SpringApplication.run starts the embedded container and refreshes the application context.

How does Spring Boot auto-configuration work?

What interviewers are testing: Whether you understand conditional auto-configuration, how candidates are loaded, and how to override defaults safely.

Auto-configuration is conditional bean registration. Spring Boot loads candidate configuration classes listed in:

  • META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (Boot 3.x)
  • Older Boot 2.x used spring.factories

Each auto-config class uses @ConditionalOn* annotations, for example:

Condition Meaning
@ConditionalOnClass Classpath contains a type (e.g. DataSource)
@ConditionalOnMissingBean User has not defined their own bean of that type
@ConditionalOnProperty Property flag is set
@ConditionalOnWebApplication Running as servlet or reactive web app

Example flow for JPA:

  1. Classpath has spring-boot-starter-data-jpa and a JDBC driver.
  2. DataSourceAutoConfiguration creates a DataSource if you did not define one.
  3. HibernateJpaAutoConfiguration sets up EntityManagerFactory when JPA is on the classpath.

You override by defining your own @Bean or setting properties (spring.datasource.url, etc.). In interviews, mention you can inspect what applied via the conditions report (/actuator/conditions when exposed).

A strong answer is:

Auto-configuration registers beans only when classpath and properties match, and backs off when I define my own bean—so defaults are safe to start with but fully overridable.

What are Spring Boot starters and why use them?

What interviewers are testing: Whether you can explain what starters bundle and why they pair with the Spring Boot BOM for aligned dependency versions.

Starters are dependency bundles that pull in libraries plus matching auto-configuration. They keep your pom.xml or build.gradle readable.

Starter Brings in (high level)
spring-boot-starter-web Spring MVC, Jackson, embedded Tomcat
spring-boot-starter-data-jpa Hibernate, Spring Data JPA, JDBC
spring-boot-starter-security Spring Security filter chain
spring-boot-starter-test JUnit, Mockito, AssertJ, Spring Test
spring-boot-starter-actuator Production endpoints and metrics
spring-boot-starter-validation Bean Validation (Hibernate Validator)

Starters are not magic—they are curated Maven coordinates. Custom starters follow the same pattern for internal platforms.

Interview tip: connect starters to the Spring Boot BOM imported by spring-boot-starter-parent or spring-boot-dependencies so versions stay aligned—see Maven interview questions.

A strong answer is:

Starters group dependencies that work together and trigger the right auto-configuration, so I add one coordinate instead of juggling ten JAR versions manually.

What is the difference between @Component, @Service, @Repository, and @Controller?

What interviewers are testing: Whether you know how bean stereotypes signal layering intent and what special behavior @Repository adds.

All are stereotypes of @Component—they mark classes for component scanning and register them as Spring beans.

Stereotype Typical use Special behavior
@Component Generic bean None
@Service Business logic layer Semantic only (documentation)
@Repository Data access Translates persistence exceptions to Spring DataAccessException
@Controller MVC controller returning views Pair with @ResponseBody or use @RestController
@RestController REST API @Controller + @ResponseBody on class

Layering interviewers expect:

text
@RestController → @Service → @Repository / JpaRepository

Keep controllers thin—validation and HTTP mapping only; business rules in services.

A strong answer is:

Stereotypes are all discoverable beans; the names document layer intent, and @Repository adds persistence exception translation while @RestController is the REST entry point.

How does dependency injection work in Spring Boot?

What interviewers are testing: Whether you understand constructor injection, bean resolution, scopes, qualifiers, and why explicit dependencies improve testability.

Spring creates objects (beans) and wires dependencies through the container.

Common injection styles:

Style Example Notes
Constructor public OrderService(OrderRepo repo) Preferred—immutable, test-friendly
Field @Autowired private OrderRepo repo Works but harder to test; avoid in new code
Setter @Autowired setRepo(...) Optional dependencies

@Autowired resolves by type; use @Qualifier when multiple beans share a type.

Scopes matter in experienced loops:

Scope Behavior
singleton (default) One instance per container
prototype New instance per injection
request / session Web scopes for per-request state

Circular dependencies: constructor injection between two singletons fails at startup—fix by redesigning boundaries or using @Lazy sparingly.

A strong answer is:

I use constructor injection so dependencies are explicit and required at startup; Spring resolves beans from the context by type and honors scope and qualifier metadata.

When do you use @Configuration and @Bean instead of @Component?

What interviewers are testing: Whether you know when @Configuration and @Bean are needed for third-party or conditional factory setup versus annotating your own classes.

Use @Configuration classes when you need programmatic bean setup—third-party classes you cannot annotate, conditional beans, or complex factory logic.

java
@Configuration
public class JacksonConfig {

    @Bean
    @ConditionalOnProperty(name = "app.json.pretty", havingValue = "true")
    ObjectMapper objectMapper() {
        return JsonMapper.builder()
            .enable(SerializationFeature.INDENT_OUTPUT)
            .build();
    }
}
Approach When
@Component on your class You own the type; let Spring construct it
@Bean method in @Configuration You configure a library class or need explicit lifecycle
Auto-configuration Framework provides sensible default

@Configuration classes are proxied so @Bean methods stay singleton-safe when they call each other.

A strong answer is:

I put my own business types on @Service/@Repository, and use @Configuration + @Bean when I integrate libraries or need conditional factory methods the framework cannot guess.


Configuration, profiles, and Spring Boot 3

application.properties vs application.yml — how do you choose?

What interviewers are testing: Whether you understand property-source precedence and when to choose YAML over properties for nested configuration.

Both feed the same Environment abstraction.

Spring Boot has a defined property-source precedence where higher-precedence sources override lower ones. In practice, packaged application.properties/YAML can be overridden by external config, environment variables, system properties, SPRING_APPLICATION_JSON, and command-line arguments. Test-specific property sources can override these further during tests.

Format Pros
.properties Simple, flat, universal
.yml Hierarchy without repeating prefixes; readable for nested config

Example profile file: application-prod.yml activated with spring.profiles.active=prod.

Relaxed binding maps spring.datasource.urlSPRING_DATASOURCE_URL in environment variables—important for Kubernetes and cloud deployment interviews.

A strong answer is:

I pick YAML when configuration is nested and repeated prefixes would clutter properties; either way I keep secrets out of git and override with environment-specific files or env vars in production.

What are Spring profiles and how do you use them?

What interviewers are testing: Whether you can use profiles to activate environment-specific beans and configuration without duplicating business logic.

Profiles label beans and configuration for environments—dev, test, staging, prod.

Ways to activate:

properties
spring.profiles.active=dev,local

Or @Profile("dev") on a @Configuration or @Bean:

java
@Configuration
@Profile("dev")
public class DevDataSourceConfig { /* in-memory H2 */ }
Use case Profile pattern
Local H2 vs prod PostgreSQL @Profile("dev") / @Profile("prod")
Mock payment gateway @Profile("!prod")
Integration tests @ActiveProfiles("test") on test class

Avoid profile explosion—prefer externalized config (URLs, feature flags) over duplicating entire @Configuration classes per environment.

A strong answer is:

Profiles switch which beans and property files load per environment; I use them for environment-specific infrastructure while keeping business code identical across profiles.

How do you externalize secrets in a Spring Boot production deployment?

What interviewers are testing: Whether you externalize secrets through platform injection, config trees, and optional secret-manager integrations without committing credentials.

Never commit secrets to git. Common patterns:

Pattern How it works
Environment variables SPRING_DATASOURCE_PASSWORD injected by K8s/VM
Secret managers AWS Secrets Manager, Azure Key Vault, HashiCorp Vault
Spring Cloud Config Central server with encrypted values
Kubernetes secrets Mounted secret directories consumed through a config tree, e.g. spring.config.import=optional:configtree:/run/secrets/
Vault (Spring Cloud) With Spring Cloud Vault on the classpath/configured, Vault can participate in Config Data imports

Spring Boot 2.4+ supports spring.config.import for external config locations. Vault imports such as optional:vault:// rely on Spring Cloud Vault providing that config-data location resolver—not plain Spring Boot alone.

Operational practices interviewers like:

  • Rotate credentials without redeploying code
  • Least-privilege DB users per service
  • No secrets in Actuator env dump exposed publicly

A strong answer is:

Secrets live in the platform secret store or environment injection, referenced by property placeholders at runtime—never hard-coded and never logged by my application.

@ConfigurationProperties vs @Value — when do you use each?

What interviewers are testing: Whether you choose type-safe @ConfigurationProperties for grouped settings versus @Value for one-off properties.

Feature @Value("${app.page-size}") @ConfigurationProperties(prefix="app")
Binding Single property Groups related properties on a type-safe class
Validation Manual Works with @Validated + JSR-303
Relaxed binding Limited pageSizepage-size
IDE support Weaker Metadata in spring-configuration-metadata.json
java
@ConfigurationProperties(prefix = "app.pagination")
public record PaginationProps(int pageSize, int maxPageSize) {}

Enable with @EnableConfigurationProperties(PaginationProps.class) or @ConfigurationPropertiesScan.

Use @Value for one-off toggles; use @ConfigurationProperties for structured config you pass around as a bean.

A strong answer is:

I use @ConfigurationProperties for grouped, validated settings with clear prefixes, and reserve @Value for simple single-property injection.

What changed in Spring Boot 3 and the Jakarta EE namespace?

What interviewers are testing: Whether you understand the Boot 2→3 Jakarta migration baseline and how Boot 4 extends it—Java baseline, namespaces, observability, and native support.

Spring Boot 3 requires Java 17+ and migrates javax.* enterprise APIs to jakarta.* (Servlet, JPA, Validation, etc.).

Spring Boot 4 builds on that baseline with Spring Framework 7 and a newer dependency baseline, while many production estates still interview heavily around the Boot 2→3 Jakarta migration.

Area Impact
Java baseline 17 minimum; teams adopt 21 for virtual threads
Jakarta packages jakarta.persistence.Entity, jakarta.validation.Valid
Security OAuth2 resource server improvements; lambda DSL defaults
Observability Micrometer Observation API, native tracing hooks
AOT / native GraalVM native image support via Spring AOT

Migration interview talking points:

  • Update imports in entities and controllers
  • Confirm third-party libs support Jakarta
  • Re-run integration tests and security config

Pair with Java part 2 for records and virtual threads on modern JDKs.

A strong answer is:

Boot 3 moves the ecosystem to Jakarta namespaces and Java 17+, and adds first-class observability and native compilation paths—I plan migrations by dependency compatibility and regression tests, not search-and-replace alone.


Spring Data JPA, transactions, and persistence

How does Spring Data JPA simplify data access?

What interviewers are testing: Whether you understand what Spring Data repositories generate for you and where JPA, SQL, and transaction knowledge is still required.

Spring Data JPA generates repository implementations from interfaces—you declare queries by method name, @Query, or specifications.

java
public interface OrderRepository extends JpaRepository<Order, Long> {

    List<Order> findByStatusOrderByCreatedAtDesc(OrderStatus status);

    @Query("select o from Order o join fetch o.customer where o.id = :id")
    Optional<Order> findWithCustomer(@Param("id") Long id);
}
Concept Role
JpaRepository CRUD + paging + batch helpers
Derived queries findBy...And... parsed at startup
@Query JPQL or native SQL when derived names are awkward
Projections Interface or DTO views without loading full entities

Under the hood: Spring Data creates a JDK proxy that delegates to EntityManager. You still need to understand JPA mapping, flush timing, and SQL—see SQL interviews for index and join depth.

A strong answer is:

Spring Data JPA removes boilerplate DAO code; I use repositories for query declaration but still own entity design, fetch strategy, and transaction boundaries in the service layer.

What is the N+1 problem in JPA and how do you fix it?

What interviewers are testing: Whether you diagnose N+1 as repeated SELECTs and fix it with explicit fetch plans without blindly switching to EAGER.

N+1 commonly appears when iterating associations that were not fetched with the original query. Collections are LAZY by default in JPA; to-one associations such as ManyToOne are EAGER by default, yet can still result in additional SELECTs depending on the query/fetch plan.

Symptoms:

  • API looks fine in dev with little data
  • Production list endpoint fires hundreds of SQL statements
  • DB CPU spikes; latency grows with page size

Fixes:

Fix When
join fetch in JPQL Controlled fetch in one query
@EntityGraph Declarative fetch plan on repository method
DTO projection Select only columns you need
Batch fetching hibernate.default_batch_fetch_size
Redesign API Avoid returning deep object graphs
java
@Query("select o from Order o join fetch o.items where o.status = :status")
List<Order> findWithItems(@Param("status") OrderStatus status);

Detect with spring.jpa.show-sql=true in dev, Hibernate statistics, or APM traces.

A strong answer is:

N+1 is lazy loading multiplied by row count; I fix it with explicit fetch joins or projections and verify with SQL logging or metrics—not by blindly switching everything to EAGER.

Explain @Transactional propagation and rollback rules.

What interviewers are testing: Whether you understand transaction boundaries, propagation, rollback rules, self-invocation pitfalls, and when local transactions should not span remote calls.

@Transactional establishes a transaction boundary through Spring's transaction infrastructure; with JPA this typically coordinates the persistence context and underlying database transaction.

Common propagation values:

Propagation Behavior
REQUIRED (default) Join caller's transaction or start new
REQUIRES_NEW Suspend caller; always new transaction
NESTED Nested savepoint when the transaction manager and underlying resource support it—not identical across every JPA setup
SUPPORTS Run non-transactionally if none exists
NOT_SUPPORTED Suspend existing transaction
MANDATORY Must run inside existing transaction
NEVER Must not run inside a transaction

Rollback rules:

  • Unchecked exceptions roll back by default
  • Checked exceptions commit unless you set rollbackFor
  • Self-invocation (this.save()) bypasses the proxy—call through another bean or refactor
java
@Transactional(rollbackFor = Exception.class)
public void placeOrder(PlaceOrderCommand cmd) { /* ... */ }

A strong answer is:

I place transaction boundaries around cohesive database work, understand propagation and rollback behavior, and avoid holding a database transaction open across slow remote calls. For database-plus-message consistency I use patterns such as an outbox rather than pretending one local transaction covers both systems.

Lazy vs eager loading — when do you use each?

What interviewers are testing: Whether you prefer lazy associations by default and fetch intentionally per use case rather than tuning fetch types globally.

Fetch type Behavior Risk
LAZY (default on collections) Loads association when accessed N+1 if accessed in a loop
EAGER Loads with parent Over-fetching, cartesian products

Default rule: prefer LAZY; fetch intentionally in queries for each use case.

EAGER on OneToMany is a common production incident—large joins and memory pressure.

For read-heavy screens, prefer read models: DTO queries, materialized views, or CQRS-style separation instead of tuning fetch types globally.

A strong answer is:

I keep associations lazy by default and fetch exactly what each endpoint needs with join fetch or projections—never global EAGER to paper over design gaps.

Why separate entity and DTO in Spring Boot APIs?

What interviewers are testing: Whether you separate persistence entities from API DTOs for security, performance, and contract stability.

Entities map to database tables and carry JPA annotations, lazy associations, and lifecycle concerns. DTOs shape what crosses the API boundary.

Reasons to separate:

Concern Entity exposure risk
Serialization Jackson may trigger lazy loads or expose internals
Security Password hash or internal flags leak in JSON
API stability Schema changes should not equal table redesign
Performance DTOs carry only needed fields

Java records make immutable DTOs concise:

java
public class RecordDtoDemo {
    public record OrderResponse(Long id, String status, java.time.Instant createdAt) {}

    public static void main(String[] args) {
        var order = new OrderResponse(42L, "PAID", java.time.Instant.parse("2026-06-27T10:00:00Z"));
        System.out.println(order.id() + " " + order.status());
    }
}
Output

When you click Run, you should see 42 PAID on one line—the record exposes accessors without boilerplate getters.

Map with MapStruct, manual mappers, or Spring's mapping helpers—avoid exposing JpaRepository entities directly from controllers.

A strong answer is:

Entities model persistence; DTOs model contracts—I map between them so API evolution, security, and fetch strategy stay under my control.

How do you manage database schema migrations in Spring Boot?

What interviewers are testing: Whether you version schema changes with Flyway or Liquibase and keep production on validate-only DDL.

Flyway and Liquibase version schema changes alongside application code.

Flyway example on classpath:

text
src/main/resources/db/migration/V1__create_orders.sql
src/main/resources/db/migration/V2__add_order_index.sql
properties
spring.flyway.enabled=true
spring.jpa.hibernate.ddl-auto=validate
Setting Production intent
ddl-auto=validate Hibernate checks mapping matches DB; does not mutate schema
ddl-auto=update Dev only—unsafe for prod
Flyway/Liquibase Repeatable, reviewed SQL or XML changelogs

Interview scenario: blue/green deploy with backward-compatible migrations (expand-contract pattern)—add column nullable first, deploy code, backfill, add constraint later.

A strong answer is:

I treat schema as code—Flyway migrations in the repo, ddl-auto=validate in production, and backward-compatible steps so rolling deploys never break old instances.

How do you implement pagination with Spring Data?

What interviewers are testing: Whether you implement pagination with Pageable, choose Page vs Slice vs Window/ScrollPosition appropriately, and cap page size.

Use Pageable and return Page<T> or Slice<T>:

java
@GetMapping("/orders")
public Page<OrderResponse> list(Pageable pageable) {
    return orderService.findOrders(pageable);
}
Approach Use when
Page<T> Need content plus total count
Slice<T> Need only whether another page exists
Window<T> + ScrollPosition Offset/keyset scrolling through large results

Sort: ?sort=createdAt,desc. Cap size in validation to prevent abuse.

For very large tables, prefer keyset pagination over deep OFFSET—see SQL interviews.

A strong answer is:

I expose page and size with sensible caps, use Page when totals matter and Slice or keyset when OFFSET becomes expensive at scale.


Spring Security

How does the Spring Security filter chain work?

What interviewers are testing: Whether you can explain how Spring Security establishes authentication and applies authorization before a request reaches application code.

Spring Security uses a FilterChainProxy containing ordered security filters. Depending on configuration, filters establish/load the security context, handle exploits such as CSRF, perform authentication, translate security exceptions, manage sessions, and ultimately apply authorization before protected application resources execute.

In Spring Boot 3, configure with a SecurityFilterChain bean:

java
@Bean
SecurityFilterChain apiSecurity(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable())
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/actuator/health").permitAll()
            .anyRequest().authenticated())
        .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()));
    return http.build();
}

Stateless REST APIs typically disable CSRF and use token auth; session-based apps keep CSRF protection.

A strong answer is:

Requests pass through ordered security filters that authenticate credentials and enforce authorization before they reach my controller—I configure one SecurityFilterChain bean per security domain.

Walk through JWT authentication in a Spring Boot REST API.

What interviewers are testing: Whether you can narrate a stateless JWT resource-server flow end to end—including validation, claims mapping, and authorization.

Typical stateless JWT flow:

Step Actor Action
1 Client POST credentials to /login or external IdP
2 Auth server Validates user; issues signed JWT (access + optional refresh)
3 Client Sends Authorization: Bearer <token> on API calls
4 Resource server Validates signature, expiry, audience, issuer
5 Spring Security Builds Authentication with granted authorities
6 Controller @PreAuthorize or URL rules enforce fine-grained access

Spring Boot setup:

  • spring-boot-starter-oauth2-resource-server
  • spring.security.oauth2.resourceserver.jwt.issuer-uri pointing to IdP metadata

Validate: clock skew, key rotation (JWKS endpoint), never log full tokens.

A strong answer is:

The client presents a Bearer JWT; Spring's resource server validates issuer and signature, maps claims to authorities, and my authorization rules run before business logic executes.

OAuth2 resource server vs OAuth2 client — what is the difference?

What interviewers are testing: Whether you distinguish OAuth2 resource server, client, and authorization server roles in a Spring Boot architecture.

Role Your app is… Typical use
Resource server API protecting resources Validates incoming JWTs or opaque tokens
OAuth2 client App calling other APIs on behalf of a user Authorization code flow, token exchange
Authorization server Issues tokens Keycloak, Entra ID, Okta, or Spring Authorization Server

A Spring Boot API is usually a resource server. A backend-for-frontend might be both client (to downstream APIs) and resource server (to the browser).

Confuse these in interviews and you will mix up redirect URIs with JWT issuer configuration.

A strong answer is:

My REST API is a resource server that validates tokens; if it must call Google or a partner API with user consent, I add OAuth2 client support for the outbound leg.

Do you need CSRF protection for REST APIs?

What interviewers are testing: Whether you know when CSRF matters for cookie-based session auth versus header-based bearer tokens.

CSRF matters when browsers automatically attach authentication credentials to cross-site requests, most commonly session/authentication cookies. A bearer token that application JavaScript deliberately places in the Authorization header is generally not automatically attached by the browser to a cross-site request, so conventional CSRF exposure is different from cookie authentication.

App style CSRF
Session cookie auth Enable CSRF (or use SameSite cookies + double-submit)
Bearer token in header Often disabled for pure APIs
Browser cookie + SPA Careful—use SameSite, CSRF tokens, or BFF pattern

If you store JWT in HttpOnly cookies from a SPA, CSRF matters again—see full stack interviews for cookie vs header trade-offs.

A strong answer is:

I enable CSRF when authentication relies on session cookies; for header-based JWT APIs I disable CSRF but still enforce CORS and never move tokens into cookies without a CSRF strategy.

How does method-level security with @PreAuthorize work?

What interviewers are testing: Whether you apply method-level security with SpEL so authorization is enforced beyond URL rules.

Enable with @EnableMethodSecurity. Annotate service or controller methods:

java
@PreAuthorize("hasRole('ADMIN') or #order.customerId == authentication.principal.id")
public OrderDto getOrder(Long orderId, Order order) { /* ... */ }

Spring evaluates SpEL expressions after authentication. authentication.principal is your UserDetails or JWT claims adapter.

Annotation Use
@PreAuthorize Check before method runs
@PostAuthorize Check return value
@Secured("ROLE_ADMIN") Simple role list

Prefer service-layer enforcement so all entry points (REST, messaging, scheduler) share rules.

A strong answer is:

Method security applies SpEL checks on top of URL rules—I centralize authorization on services with @PreAuthorize so every caller path respects the same policy.


REST APIs, validation, and error handling

What are REST API best practices in Spring Boot?

What interviewers are testing: Whether you design REST resources with correct HTTP semantics, status codes, versioning, and thin controllers.

Practice Detail
Resource URLs Nouns (/orders/{id}), not verbs
HTTP verbs GET read, POST create, PUT replace, PATCH partial, DELETE remove
Status codes 201 + Location on create; 404 when missing; 409 on conflict
Idempotency PUT/DELETE idempotent; POST is not—use keys for payments
Versioning URL (/v1/), header, or media type—pick one and document
Pagination Query params or Pageable; link headers optional

Keep controllers thin:

java
@RestController
@RequestMapping("/api/v1/orders")
@RequiredArgsConstructor
public class OrderController {
    private final OrderService orderService;

    @PostMapping
    ResponseEntity<OrderResponse> create(@Valid @RequestBody CreateOrderRequest req) {
        OrderResponse created = orderService.create(req);
        URI location = URI.create("/api/v1/orders/" + created.id());
        return ResponseEntity.created(location).body(created);
    }
}

Document with springdoc-openapi or Spring REST Docs for consumer contracts.

A strong answer is:

I model resources with clear HTTP semantics, return correct status codes and DTOs, version intentionally, and document the API so frontend and mobile teams integrate without guesswork.

How do you validate request bodies with Bean Validation?

What interviewers are testing: Whether you validate request DTOs at the boundary with Bean Validation and consistent 400 handling.

Add spring-boot-starter-validation and annotate DTOs:

java
public record CreateOrderRequest(
    @NotNull Long customerId,
    @NotEmpty @Size(max = 50) List<@NotNull @Positive Integer> itemIds
) {}

Controller:

java
@PostMapping
public OrderResponse create(@Valid @RequestBody CreateOrderRequest req) { /* ... */ }

Validation runs before your method body; failures throw MethodArgumentNotValidException—handle globally (next question).

Custom constraints: @interface + ConstraintValidator for domain rules (e.g. valid SKU format).

A strong answer is:

I validate at the boundary with JSR-303 annotations on DTOs, add custom validators for domain rules, and return consistent 400 responses with field-level errors.

How do you handle exceptions globally with @ControllerAdvice?

What interviewers are testing: Whether you centralize exception mapping with @ControllerAdvice and RFC 9457 Problem Details.

@ControllerAdvice centralizes exception mapping to HTTP responses:

java
@RestControllerAdvice
public class ApiExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    ResponseEntity<ProblemDetail> handleValidation(MethodArgumentNotValidException ex) {
        ProblemDetail problem = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
        problem.setTitle("Validation failed");
        // map field errors to problem properties
        return ResponseEntity.badRequest().body(problem);
    }

    @ExceptionHandler(OrderNotFoundException.class)
    ResponseEntity<ProblemDetail> handleNotFound(OrderNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
            .body(ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage()));
    }
}

Prefer RFC 9457 Problem Details (ProblemDetail) over ad-hoc JSON error shapes.

Never leak stack traces to clients in production; log server-side with correlation IDs.

A strong answer is:

@ControllerAdvice maps domain and validation exceptions to stable Problem Details responses while full diagnostics go to structured logs.

How do you choose HTTP status codes in Spring Boot APIs?

What interviewers are testing: Whether you map business outcomes to intentional HTTP status codes rather than defaulting everything to 200/500.

Situation Status
Success GET 200 OK
Created resource 201 Created + Location
Accepted async job 202 Accepted
No content success 204 No Content
Validation error 400 Bad Request
Missing auth 401 Unauthorized
Authenticated but forbidden 403 Forbidden
Missing resource 404 Not Found
Business rule conflict 409 Conflict
Precondition failed (ETag) 412 Precondition Failed
Rate limited 429 Too Many Requests
Server error 500 — only for unexpected failures

Use domain exceptions mapped in @ControllerAdvice so controllers stay clean.

A strong answer is:

I map business outcomes to intentional status codes—404 for missing entities, 409 for conflicts, 400 for bad input—and reserve 500 for truly unexpected exceptions we alert on.

PUT vs PATCH — how do you implement partial updates?

What interviewers are testing: Whether you implement PUT vs PATCH correctly and handle optimistic-lock conflicts with deliberate status choices.

Verb Semantics Implementation
PUT Replace entire resource Client sends full representation
PATCH Partial update JSON Merge Patch or JSON Patch

Spring example for partial update:

java
@PatchMapping("/{id}")
public OrderResponse patch(@PathVariable Long id,
                           @RequestBody Map<String, Object> updates) {
    return orderService.applyPatch(id, updates);
}

Production services often use explicit patch DTOs instead of open maps—type safety and validation.

Concurrency: use ETags or version columns (@Version) to prevent lost updates. Map optimistic-lock conflicts deliberately—commonly 409 Conflict; when enforcing conditional requests through If-Match/ETags, 412 Precondition Failed may be more appropriate.

A strong answer is:

PUT replaces the whole resource; PATCH applies a controlled partial update with validation and optimistic locking when multiple clients edit the same row.


Testing, Actuator, and observability

@SpringBootTest vs slice tests — when do you use each?

What interviewers are testing: Whether you choose slice tests for fast feedback and full-context tests for wiring/integration risks.

Annotation Loads Use for
@SpringBootTest Full Spring Boot application context Broad integration/application wiring tests
@WebMvcTest MVC layer only Controller mapping, security, JSON
@DataJpaTest JPA + in-memory or Testcontainers DB Repositories, queries
@JsonTest Jackson Serialization contracts
@RestClientTest REST clients Outbound HTTP client behavior

Rule: test narrow by default, widen when integration risk appears.

@SpringBootTest(webEnvironment = RANDOM_PORT) gives you a real HTTP server boundary for HTTP integration tests—use TestRestTemplate or WebTestClient against it.

A strong answer is:

I use slice tests for fast feedback on controllers and repositories, and a small set of @SpringBootTest or Testcontainers tests to prove the wiring that slices mock away.

How do @WebMvcTest and @DataJpaTest work?

What interviewers are testing: Whether you structure @WebMvcTest and @DataJpaTest slices with appropriate mocks and collaborators.

@WebMvcTest (example):

java
@WebMvcTest(OrderController.class)
class OrderControllerTest {

    @Autowired
    MockMvc mockMvc;

    @MockitoBean
    OrderService orderService;

    @Test
    void returns404WhenMissing() throws Exception {
        when(orderService.findById(1L)).thenThrow(new OrderNotFoundException(1L));
        mockMvc.perform(get("/api/v1/orders/1"))
            .andExpect(status().isNotFound());
    }
}

Only MVC infrastructure starts—no full database. Test the service layer separately with its own unit or slice tests.

On Spring Framework 6.2+ / current Spring Boot generations, use Spring Framework's @MockitoBean; older Boot code commonly uses Boot's @MockBean.

@DataJpaTest:

java
@DataJpaTest
class OrderRepositoryTest {
    @Autowired OrderRepository orders;
    @Autowired TestEntityManager em;

    @Test
    void findsByStatus() { /* persist + query */ }
}

Uses @Transactional rollback by default; add Testcontainers for dialect-specific SQL.

A strong answer is:

@WebMvcTest exercises controller HTTP contracts with mocked services; @DataJpaTest proves queries against a real persistence context without booting the entire application.

How do Testcontainers improve Spring Boot integration tests?

What interviewers are testing: Whether you use Testcontainers for production-like integration tests when in-memory databases hide dialect issues.

Testcontainers spins real PostgreSQL, Kafka, Redis, etc. in Docker during tests.

java
@SpringBootTest
@Testcontainers
class OrderApiIT {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");

    @DynamicPropertySource
    static void registerProps(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }
}

Benefits:

  • Catch SQL dialect and constraint issues H2 hides
  • Test Flyway migrations realistically
  • Reproducible CI with Docker available

Trade-off: slower than in-memory DB—keep the suite small and tagged.

A strong answer is:

Testcontainers gives me production-like dependencies in CI—I use it for migration and integration paths that H2 cannot represent faithfully.

What is Spring Boot Actuator and which endpoints matter in production?

What interviewers are testing: Whether you expose and secure Actuator endpoints for health checks, metrics, and operational visibility.

Actuator exposes operational endpoints over HTTP or JMX:

Endpoint Purpose
/actuator/health Liveness/readiness (K8s probes)
/actuator/info Build/git metadata
/actuator/metrics Micrometer metrics
/actuator/prometheus Prometheus scrape format
/actuator/loggers Tune log levels at runtime

Secure aggressively:

properties
management.endpoints.web.exposure.include=health,info,prometheus
management.endpoint.health.show-details=when_authorized

Custom health indicators implement HealthIndicator for downstream dependencies (DB, queue).

A strong answer is:

Actuator is how operators check health and scrape metrics—I expose the minimum endpoints, protect them with auth/network policy, and add custom health checks for critical dependencies.

How do logging and distributed tracing work in Spring Boot 3?

What interviewers are testing: Whether you use Micrometer Observation and tracing bridges to correlate logs, metrics, and distributed traces.

Spring Boot's observability stack builds on Micrometer Observation, with Micrometer Tracing bridges providing trace/span propagation and export integrations.

Practices:

Practice Detail
Structured logging JSON logs with traceId, spanId (Logback encoder)
Correlation IDs Use trace/span IDs for distributed tracing; add a separate business correlation/request ID only when the application needs one
Tracing bridge OpenTelemetry or Brave with Zipkin/Jaeger/OTLP export
MDC Map diagnostic context in OncePerRequestFilter
properties
management.tracing.sampling.probability=1.0

In incidents, you pivot from user report → trace ID → slow SQL span—interviewers want that workflow, not just "we use logs."

A strong answer is:

I emit structured logs and traces with shared correlation IDs so I can follow one request from gateway through controller, service, and database query during an outage.


Microservices, resilience, and messaging

Monolith vs microservices — when does Spring Boot fit each?

What interviewers are testing: Whether you justify monolith vs microservice boundaries based on scaling, ownership, and data ownership—not arbitrary size.

Spring Boot supports modular monoliths and microservices equally well—the question is operational cost.

Approach Spring Boot pattern
Modular monolith Single deployable; modules as packages or Gradle/Maven multi-modules
Microservices One service per bounded context; each owns its persistence boundary/schema—other services do not query its data directly
Strangler fig Extract hot paths gradually behind API gateway

Extract a service when you need independent scaling, deployment, or team ownership—not because the monolith hit arbitrary line count.

Spring tools for microservices:

  • Spring Cloud OpenFeign — declarative HTTP clients
  • Spring Cloud Gateway — edge routing
  • Spring Cloud Config — central configuration

See full stack monolith vs micro for product-level framing.

A strong answer is:

I start with a well-bounded Spring Boot monolith and split services only when scaling or ownership forces the operational investment—not by default.

Explain Spring Cloud Config, Gateway, and service discovery at interview level.

What interviewers are testing: Whether you can explain Spring Cloud Config, Gateway, and discovery at interview level and how Kubernetes/GitOps alternatives map to the same problems.

Component Role
Config Server Git-backed central application.yml; clients refresh with /actuator/refresh or Spring Cloud Bus
Gateway Reactive edge: routing, rate limiting, auth termination
Discovery (Eureka, Consul) Service registry so clients find instances dynamically
Load balancing Spring Cloud LoadBalancer with RestTemplate/WebClient

Modern deployments often replace Eureka with Kubernetes DNS and Config Server with ConfigMaps, Secrets, external secret operators/managers, and GitOps workflows—still know the Spring Cloud abstractions for legacy enterprise stacks.

A strong answer is:

Spring Cloud centralizes config and routing; in Kubernetes I may use native ingress and ConfigMaps instead, but the problems—dynamic endpoints and environment-specific settings—stay the same.

How do circuit breakers work with Resilience4j in Spring Boot?

What interviewers are testing: Whether you apply Resilience4j patterns—circuit breaker, retry, rate limiting, and bulkheads—for failing dependencies.

Resilience4j implements fault tolerance patterns:

Pattern Purpose
Circuit breaker Stop calling failing dependency; fail fast
Retry Transient errors with backoff
Rate limiter Protect your service
Bulkhead Limit concurrent work or isolate execution capacity so one dependency cannot exhaust the service
java
@CircuitBreaker(name = "inventory", fallbackMethod = "fallbackStock")
public StockResponse checkStock(Long skuId) {
    return inventoryClient.getStock(skuId);
}

States: CLOSED → OPEN (after failure threshold) → HALF_OPEN (probe).

Expose metrics via Micrometer; tune thresholds from production data, not guesses.

A strong answer is:

I wrap outbound calls with circuit breakers and fallbacks so cascading failures do not take down my API, and I monitor breaker state to know when dependencies recover.


Modern Java, performance, and caching

How do virtual threads work in Spring Boot?

What interviewers are testing: Whether you understand when virtual threads help I/O-heavy Spring Boot workloads and what pinning, keep-alive, and thread-local caveats remain.

Virtual threads (Project Loom) are lightweight threads scheduled on carrier platform threads—ideal for blocking I/O heavy workloads.

Enable in Spring Boot 3.2+ (still the property in Boot 4):

properties
spring.threads.virtual.enabled=true

Tomcat and @Async can use virtual threads for request handling when configured. Java 21 is the minimum for virtual threads; Java 24+ gives the best experience per current Spring Boot guidance.

Workload Fit
Many concurrent blocking JDBC/HTTP calls Good candidate
CPU-bound computation Virtual threads do not increase available CPU; bound concurrency to available cores / use an appropriate executor

Production caveats from current Boot docs:

  • Pinned virtual threadssynchronized or native code can pin carriers; understand pinning in your JDK version
  • Thread-pool assumptions — traditional pool sizing no longer maps 1:1 when requests use virtual threads
  • Daemon behavior — virtual threads are daemon threads; use spring.main.keep-alive=true where the JVM must stay alive after request work completes
  • Thread-local state — virtual threads support ThreadLocal, but review libraries that attach large amounts of state per thread or assume a small long-lived thread pool

Connect to Java part 2 virtual threads for JVM-level detail.

A strong answer is:

On Java 21+ I enable Spring Boot virtual thread support for I/O-heavy APIs, load-test against platform-thread baselines, and watch for pinning, thread-local libraries, and keep-alive behavior—not every app benefits on day one.

What are GraalVM native images with Spring Boot?

What interviewers are testing: Whether you understand Spring AOT preparation and GraalVM native-image trade-offs for startup and memory.

Spring AOT + GraalVM Native Image prepares applications for faster startup and lower memory—useful for serverless and dense Kubernetes.

Spring AOT analyzes the application at build time and generates optimized bootstrap metadata/code required for a GraalVM native image. Native-image compilation then creates the native executable. Spring Boot treats AOT as a mandatory preparation step for a Spring application context in a native image.

Trade-offs:

Benefit Cost
Fast cold start Longer build times
Lower RSS Reflection hints; limited dynamic behavior
Smaller containers Some libraries need reachability metadata

Build through Spring Boot's native build support/Cloud Native Buildpacks or GraalVM Native Build Tools.

Not every Spring app is a native candidate—validate with benchmarks before committing.

A strong answer is:

Native images trade build complexity for startup and memory wins—I use them when cold start or footprint dominates cost, after proving our Spring features and libraries are native-compatible.

How does Spring caching with @Cacheable work?

What interviewers are testing: Whether you use @Cacheable with explicit eviction and cache provider choice for local vs distributed consistency.

Enable with @EnableCaching. Annotate read methods:

java
@Cacheable(value = "orders", key = "#id")
public OrderDto findById(Long id) {
    return orderRepository.findById(id).map(mapper::toDto).orElseThrow();
}

@CacheEvict(value = "orders", key = "#id")
public void delete(Long id) { orderRepository.deleteById(id); }

Providers: Caffeine (local), Redis (distributed).

Concern Practice
Stale data TTL + eviction on writes
Stampede Sync cache load or probabilistic early expiration
Serialization DTOs in Redis, not lazy entities

A strong answer is:

I cache expensive reads with explicit keys and TTL, evict on mutations, and choose Redis when multiple instances need a shared cache.


Senior scenarios and final prep

Scenario: A Spring Boot API is slow in production — how do you debug?

What interviewers are testing: Whether you diagnose production latency from evidence—metrics, traces, database behavior, downstream calls, pools, and recent changes—before proposing fixes.

Structured approach interviewers want:

Step Action
1 Confirm scope—one endpoint or global? spike vs gradual?
2 Check metrics (latency percentiles, error rate, thread pool, DB pool)
3 Pull traces for slow requests—identify DB, external HTTP, or GC
4 Check database evidence: query latency, connection-pool saturation, N+1 patterns, lock waits, execution plans
5 Review recent deploys—config, pool size, feature flag
6 Reproduce in staging with production-like data volume
7 Fix, load-test, roll out with canary

Tools: Actuator metrics, APM (Datadog, New Relic), Hibernate SQL log (dev only), pg_stat_statements, heap dump if GC thrash.

A strong answer is:

I start with metrics and traces to see whether latency is database, downstream HTTP, or pool exhaustion, reproduce with realistic data, fix the root cause—often N+1 or missing index—and verify with load tests before full rollout.

What should you rehearse the week before a senior Spring Boot interview?

What interviewers are testing: Whether you can turn your Spring Boot knowledge into concise stories about architecture, transactions, security, testing, deployment, and incidents.

Checklist:

  • Whiteboard one service: controller → service → repo → DB + auth filter
  • Explain a transaction bug you fixed (rollback, propagation, self-invocation)
  • Explain a security choice (JWT resource server, roles, method security)
  • Walk through testing pyramid for that service
  • Two STAR stories—production incident and performance win
  • Trade-off answers: monolith vs micro, cache invalidation, optimistic locking
  • Java fundamentals refresh—part 1 and part 2
  • Build/deploy story—Maven/Gradle, Docker, CI, health probes

A strong answer is:

I rehearse one real Spring Boot system end to end—security, data, tests, and how we run it in production—so every answer ties to something I actually shipped, not generic framework definitions.


Pattern cheat sheet (quick reference)

Need Spring Boot starting point
REST API spring-boot-starter-web + @RestController
Database access spring-boot-starter-data-jpa + Flyway
Validation spring-boot-starter-validation + @Valid
Security spring-boot-starter-security + OAuth2 resource server
Testing @WebMvcTest, @DataJpaTest, Testcontainers
Production ops spring-boot-starter-actuator + Micrometer
Caching @EnableCaching + Caffeine or Redis
Async / I/O scale Virtual threads on Java 21
Microservices edge Spring Cloud Gateway + Config (or K8s native)
Resilience Resilience4j circuit breaker

References


Summary

Experienced Spring Boot interviews test auto-configuration, JPA and transactions, security, testing, and production operability—not annotation trivia. Answer aloud and compare your structure to each section. Pair with Java part 1 and part 2, full stack interviews, and SQL interviews when persistence becomes execution plans.

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)