Core Spring
Dependency injection and the container. Everything else builds on this.
Basic
Q1
What is dependency injection, and what problem does it solve?
Instead of a class constructing what it needs, the dependencies are handed to it. That means the class depends on an interface rather than a concrete implementation, so the implementation can be swapped — a real gateway in production, a fake in tests — without touching the class. Spring's container is what does the handing over.
Intermediate
Q2
Constructor injection or field injection?
Constructor injection, and it is worth saying why: the dependencies become final so the object cannot exist half-built, they are visible in the signature so a class with too many is obviously doing too much, and the class can be constructed in a plain unit test with no Spring at all. Field injection hides all three.
Basic
Q3
What does @SpringBootApplication actually do?
It is three annotations in one. @Configuration marks the class as a source of bean definitions, @ComponentScan scans this package and below for components, and @EnableAutoConfiguration switches on Boot's conditional configuration.
The follow-upThis is why beans in a package outside the main class's package are silently not found — component scanning starts from where that class lives.
Advanced
Q4
How does auto-configuration work?
Boot ships configuration classes guarded by conditions — @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty. At startup it evaluates them: a database driver on the classpath and no DataSource of your own means Boot defines one. Defining your own bean makes the condition fail, so your definition wins.
The follow-upThen: how would you debug it? Run with --debug for the auto-configuration report, which lists every condition that matched and every one that did not, with the reason.
Intermediate
Q5
What are the bean scopes, and which is the default?
Singleton is the default: one instance for the whole container. Prototype creates a new one per injection. Web applications add request, session and application scopes. The important consequence of the default is that a singleton bean holding mutable instance state is shared across every request — a genuine concurrency bug.
Basic
Q6
What is the difference between @Component, @Service, @Repository and @Controller?
All four register a bean; the last three are specialised @Components that say what the class is for. @Repository additionally translates persistence exceptions into Spring's DataAccessException hierarchy, and @Controller/@RestController are what web request mapping looks for. So the difference is intent, plus that one real behaviour.
REST and web
The half of the interview that maps to what you actually built.
Basic
Q7
What is the difference between @Controller and @RestController?
@RestController is @Controller plus @ResponseBody on every method, so return values are serialised into the response body instead of being resolved as view names. Use it for APIs; use @Controller when you are rendering server-side templates.
Intermediate
Q8
How do you handle exceptions across a whole API?
A @RestControllerAdvice class with @ExceptionHandler methods. It centralises the mapping from exception to status code and response body, so controllers stay free of try/catch and every error in the API comes back in the same shape — which is what clients need.
@RestControllerAdvice
class ApiExceptionHandler {
@ExceptionHandler(NotFoundException.class)
ResponseEntity<ApiError> notFound(NotFoundException e) {
return ResponseEntity.status(404).body(new ApiError(e.getMessage()));
}
}
Basic
Q9
What is the difference between @RequestParam, @PathVariable and @RequestBody?
@PathVariable binds part of the URL path and is for identifying a resource. @RequestParam binds a query parameter and is for filtering, sorting and paging. @RequestBody deserialises the request body, for the payload of a POST or PUT.
Intermediate
Q10
Which HTTP status codes should an API return, and when?
200 for a successful read or update, 201 with a Location header when something was created, 204 when there is nothing to return. 400 for a malformed or invalid request, 401 not authenticated, 403 authenticated but not allowed, 404 not found, 409 for a conflict such as a duplicate. 500 only for an unexpected server failure — a validation error returning 500 is a common review comment.
Intermediate
Q11
How do you validate a request body?
Annotate the DTO's fields with Bean Validation constraints — @NotBlank, @Email, @Min — and put @Valid on the controller parameter. A failure raises MethodArgumentNotValidException, which you map in the advice class above so clients get one consistent error shape with the field names in it.
Data and transactions
Where the questions get specific and the wrong answer is visible.
Advanced
Q12
What does @Transactional actually do?
It wraps the method in a transaction through a proxy: commit on normal return, roll back on an unchecked exception. Two consequences interviewers probe. First, by default it rolls back on RuntimeException only — a checked exception commits unless you set rollbackFor. Second, because it works through a proxy, calling a @Transactional method from another method in the same class bypasses the proxy entirely and no transaction starts.
The follow-upThat self-invocation trap is the most common Spring bug in production code, and a favourite follow-up.
Advanced
Q13
What is the N+1 query problem?
You fetch a list of n entities with one query, then touch a lazy association on each and trigger n more queries. It usually appears only under real data, having looked fine in development. The fixes: a JOIN FETCH in the query, an entity graph, or a batch size so the n queries become a handful.
Intermediate
Q14
What is the difference between JPA, Hibernate and Spring Data JPA?
JPA is the specification. Hibernate is the implementation Boot uses by default. Spring Data JPA sits above both and generates repository implementations from interface method names, so findByEmailAndActiveTrue needs no body.
Intermediate
Q15
What is the difference between lazy and eager loading?
Eager loads an association with its parent; lazy loads it on first access. Lazy is the right default — eager everywhere drags half the object graph into memory for a query that needed one row. The cost of lazy is LazyInitializationException when the association is touched after the session closed, which is a sign the fetch should have been part of the query.
Intermediate
Q16
How do you manage configuration across environments?
Profile-specific property files (application-dev.yml, application-prod.yml) activated by a profile, with @ConfigurationProperties binding them to typed objects rather than scattering @Value strings. Secrets come from environment variables or a secret manager, never from a file in the repository.
Testing, security and services
The last third of the interview, and where projects get discussed.
Intermediate
Q17
What is the difference between @SpringBootTest and @WebMvcTest?
@SpringBootTest starts the whole application context — thorough and slow, right for an integration test. @WebMvcTest loads only the web layer with the rest mocked, so a controller test runs in a fraction of the time. Loading the full context for every test is the usual reason a suite becomes too slow to run.
Intermediate
Q18
How do you test a service class?
As a plain unit test with no Spring at all: construct it with mocked dependencies and assert on behaviour. This is the practical payoff of constructor injection — a class whose dependencies arrive through the constructor needs no container to be tested.
Advanced
Q19
What is the difference between @Mock and @MockBean?
@Mock is Mockito's and creates a mock object with no Spring involved. @MockBean puts a mock into the Spring context, replacing the real bean — which also invalidates the cached context, so overusing it slows the suite by rebuilding the context repeatedly.
Advanced
Q20
How does authentication and authorisation work in Spring Security?
A filter chain runs before your controllers. Authentication establishes who the caller is — a JWT or session is validated and an Authentication is placed in the SecurityContext. Authorisation then decides whether that principal may do this, through URL rules in the chain or @PreAuthorize on methods. Authentication is identity; authorisation is permission.
Advanced
Q21
How would you secure a REST API with JWT?
On login, verify the credentials and return a signed token with a short expiry and the minimum claims needed. A filter validates the signature and expiry on each request and populates the security context. Never put anything secret in the payload — a JWT is signed, not encrypted, so anyone can read it. Use a refresh token for renewal, and keep a way to revoke.
Intermediate
Q22
How do you call another service from Spring Boot?
RestClient or WebClient in current versions; RestTemplate is the older, maintenance-mode option. Whatever you use, set a connect and read timeout — an unbounded call to a hanging dependency exhausts your thread pool and takes your service down with theirs.
Intermediate
Q23
What are actuator endpoints?
Built-in operational endpoints — /health, /metrics, /info, /env — used by load balancers, orchestrators and monitoring. They expose real internals, so expose only what is needed and put them behind authentication or a separate port.
Advanced
Q24
What is the difference between a monolith and microservices?
A monolith is one deployable: simpler to develop, test, debug and deploy, and it scales as a unit. Microservices are separately deployable services that scale and fail independently, at the cost of network calls, distributed data, and much harder debugging. The honest answer for a fresher project is that a monolith was correct — and saying so is stronger than claiming microservices you did not need.