Question 1
How does Spring Boot Auto-Configuration work under the hood?
Theoretical Concept
Auto-configuration inspects the application classpath, existing beans, and configuration properties to automatically wire reasonable defaults.
Comprehensive Answer
Spring Boot leverages @EnableAutoConfiguration (included in @SpringBootApplication). During bootstrap, Spring factories loaders inspect META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. Each configuration class utilizes conditional annotations such as @ConditionalOnClass, @ConditionalOnMissingBean, and @ConditionalOnProperty. If the required classes (like Tomcat or DataSource) are on the classpath and no custom bean is defined, Spring Boot instantiates and registers the default bean.
Code Demonstration
@Configuration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
public class DataSourceAutoConfiguration {
// Automatically creates HikariCP DataSource if user hasn't defined one!
}
Real-World Enterprise Scenario
Adding spring-boot-starter-data-jpa and postgresql dependency to pom.xml automatically initializes a HikariCP connection pool without needing manual XML configuration.
Interviewer Pro Tip: Mention how to debug auto-configuration by starting the application with the --debug flag to generate the ConditionsEvaluationReport.
Common Candidate Mistake: Failing to realize that defining your own @Bean of a specific type automatically overrides the auto-configured default bean due to @ConditionalOnMissingBean.
Related follow-up question: What is the purpose of spring-boot-starter-parent?
Question 2
What is the Hibernate N+1 Query Problem and how do you resolve it in Spring Data JPA?
Theoretical Concept
The N+1 problem occurs when fetching an entity with lazy relationships triggers one initial query plus N additional queries for each child record.
Comprehensive Answer
When fetching an entity (e.g. 100 Orders) where each order has a lazily loaded Customer, accessing order.getCustomer() in a loop executes 1 query for the orders, followed by 100 individual queries for each customer (1 + N = 101 queries). This severely degrades database performance. It can be resolved by: 1) Using JOIN FETCH in JPQL queries. 2) Applying @EntityGraph on repository query methods to specify which relationships should be eagerly fetched in a single SQL JOIN.
Code Demonstration
// Problematic: default lazy fetch in repository
List<Order> findAll(); // Generates 1 query for orders + N queries for customers
// Solution 1: JPQL JOIN FETCH
@Query("SELECT o FROM Order o JOIN FETCH o.customer")
List<Order> findAllWithCustomer();
// Solution 2: Spring Data @EntityGraph
@EntityGraph(attributePaths = {"customer"})
List<Order> findAll();
Real-World Enterprise Scenario
An admin reporting dashboard displaying recent order rows alongside customer contact info was timing out under load until JOIN FETCH replaced default lazy proxy iterations.
Interviewer Pro Tip: Emphasize that changing FetchType to EAGER on the entity model does not solve N+1; it simply triggers the N queries eagerly. JOIN FETCH or Entity Graphs are the true solutions.
Common Candidate Mistake: Setting all relationships to FetchType.EAGER globally, which leads to massive unneeded data transfers across all other queries in the application.
Related follow-up question: What is the difference between FetchType.LAZY and FetchType.EAGER?