Menu

Spring Boot Topic

Spring Boot Interview Questions and Answers

Beginner Level Questions

1. What is Spring Boot and what are its main advantages?

Answer:
Spring Boot is an extension of the Spring framework that simplifies the development of production-ready applications.

Main advantages:

  • Auto-configuration: Automatically configures Spring based on dependencies

  • Standalone: Creates standalone Spring applications with embedded servers

  • Production-ready: Provides features like metrics, health checks, and externalized configuration

  • No XML: Eliminates need for XML configuration

  • Rapid Development: Reduces development time with starter dependencies

2. What are Spring Boot Starter dependencies?

Answer:
Spring Boot Starters are dependency descriptors that bundle common dependencies for specific functionalities.

Examples:

<!-- Web applications -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<!-- Data JPA -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Testing -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

3. What is the purpose of the @SpringBootApplication annotation?

Answer:
@SpringBootApplication is a convenience annotation that combines three annotations:

  1. @Configuration: Tags class as source of bean definitions

  2. @ComponentScan: Enables component scanning in current package and sub-packages

  3. @EnableAutoConfiguration: Enables Spring Boot auto-configuration

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

4. How does Spring Boot Auto-configuration work?

Answer:
Auto-configuration automatically configures Spring beans based on:

  • Dependencies present in classpath

  • Existing bean definitions

  • Property settings in application.properties

Mechanism:

  1. Spring Boot checks spring.factories files in META-INF

  2. Loads auto-configuration classes annotated with @Configuration

  3. Uses @Conditional annotations to determine if configuration should be applied

Example:

@Configuration
@ConditionalOnClass(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.url")
public class DataSourceAutoConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public DataSource dataSource() {
        // Auto-configure DataSource
    }
}

5. How do you externalize configuration in Spring Boot?

Answer:
Spring Boot supports multiple ways to externalize configuration:

  1. application.properties:

server.port=9090
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
  1. application.yml:

server:
  port: 9090
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
  1. Profile-specific: application-{profile}.properties

  2. Environment variables

  3. Command-line arguments

Accessing properties:

@Value("${server.port}")
private String port;

@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties {
    private String url;
    // getters and setters
}

Intermediate Level Questions

6. What is the difference between @RestController and @Controller?

Answer:

  • @Controller: Used for traditional web applications that return views

  • @RestController: Combination of @Controller + @ResponseBody, used for REST APIs that return data directly

// Traditional controller returning view name
@Controller
public class WebController {
    @GetMapping("/home")
    public String home() {
        return "home"; // Returns home.html view
    }
}

// REST controller returning JSON/XML
@RestController
public class ApiController {
    @GetMapping("/api/users")
    public List<User> getUsers() {
        return userService.findAll(); // Returns JSON directly
    }
}

7. How do you handle exceptions in Spring Boot REST APIs?

Answer:
Using @ControllerAdvice and @ExceptionHandler:

@RestControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
        ErrorResponse error = new ErrorResponse("USER_NOT_FOUND", ex.getMessage());
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGenericException(Exception ex) {
        ErrorResponse error = new ErrorResponse("INTERNAL_ERROR", "Something went wrong");
        return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

// Custom exception
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

8. What is Spring Data JPA and how do you use it?

Answer:
Spring Data JPA simplifies database operations by reducing boilerplate code.

Key components:

  • Repository interfaces: JpaRepository, CrudRepository

  • Query methods: Derive queries from method names

  • Custom queries: Using @Query annotation

public interface UserRepository extends JpaRepository<User, Long> {
    
    // Derived query method
    List<User> findByLastName(String lastName);
    
    // Custom JPQL query
    @Query("SELECT u FROM User u WHERE u.email = :email")
    User findByEmail(@Param("email") String email);
    
    // Native query
    @Query(value = "SELECT * FROM users WHERE age > :age", nativeQuery = true)
    List<User> findUsersOlderThan(@Param("age") int age);
}

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstName;
    private String lastName;
    private String email;
    // getters and setters
}

9. How does Spring Boot handle database migration?

Answer:
Spring Boot integrates with Flyway or Liquibase for database migrations.

Using Flyway:

  1. Add dependency:

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
  1. Create migration files in src/main/resources/db/migration:

-- V1__Create_users_table.sql
CREATE TABLE users (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL
);

-- V2__Add_age_to_users.sql
ALTER TABLE users ADD COLUMN age INT;

Using Liquibase:

<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
</dependency>

10. What are Spring Profiles and how do you use them?

Answer:
Profiles allow you to define environment-specific configurations.

Defining profiles:

@Configuration
@Profile("dev")
public class DevConfig {
    @Bean
    public DataSource devDataSource() {
        // Development datasource
    }
}

@Configuration
@Profile("prod")
public class ProdConfig {
    @Bean
    public DataSource prodDataSource() {
        // Production datasource
    }
}

Activating profiles:

# application.properties
spring.profiles.active=dev,debug

# Or via command line
java -jar app.jar --spring.profiles.active=prod

# Or environment variable
export SPRING_PROFILES_ACTIVE=prod

Profile-specific properties:

  • application-dev.properties

  • application-prod.properties

Advanced Level Questions

11. How do you implement caching in Spring Boot?

Answer:
Spring Boot provides caching abstraction with various providers.

1. Enable caching:

@SpringBootApplication
@EnableCaching
public class Application { }

2. Use caching annotations:

@Service
public class UserService {
    
    @Cacheable("users")  // Cache result
    public User findById(Long id) {
        // Database call
    }
    
    @CacheEvict(value = "users", key = "#id")  // Remove from cache
    public void deleteUser(Long id) {
        // Delete user
    }
    
    @CachePut(value = "users", key = "#user.id")  // Update cache
    public User updateUser(User user) {
        // Update user
    }
}

3. Configure cache provider (e.g., Redis):

spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379

12. What is Spring Boot Actuator and what endpoints does it provide?

Answer:
Spring Boot Actuator provides production-ready features to monitor and manage applications.

Dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Key endpoints:

  • /actuator/health - Application health information

  • /actuator/info - Application information

  • /actuator/metrics - Application metrics

  • /actuator/env - Environment properties

  • /actuator/beans - Spring beans information

  • /actuator/mappings - URL mappings

Configuration:

management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always

13. How do you implement security in Spring Boot using Spring Security?

Answer:
Spring Security provides comprehensive security services.

Basic configuration:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/public/**").permitAll()
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")
                .permitAll()
            )
            .logout(logout -> logout
                .permitAll()
            );
        return http.build();
    }
    
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user);
    }
}

JWT Authentication:

@Component
public class JwtTokenFilter extends OncePerRequestFilter {
    
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                  HttpServletResponse response,
                                  FilterChain chain) throws ServletException, IOException {
        String token = extractToken(request);
        if (token != null && jwtUtil.validateToken(token)) {
            Authentication auth = jwtUtil.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
        chain.doFilter(request, response);
    }
}

14. How do you implement transaction management in Spring Boot?

Answer:
Spring provides declarative transaction management using @Transactional.

Configuration:

@SpringBootApplication
@EnableTransactionManagement
public class Application { }

Usage:

@Service
public class BankService {
    
    @Transactional
    public void transferMoney(Long fromAccountId, Long toAccountId, BigDecimal amount) {
        Account fromAccount = accountRepository.findById(fromAccountId);
        Account toAccount = accountRepository.findById(toAccountId);
        
        fromAccount.debit(amount);
        toAccount.credit(amount);
        
        accountRepository.save(fromAccount);
        accountRepository.save(toAccount);
        
        // If any exception occurs, entire transaction rolls back
    }
    
    @Transactional(readOnly = true)
    public BigDecimal getBalance(Long accountId) {
        return accountRepository.findBalanceById(accountId);
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void auditTransaction(Transaction transaction) {
        // This method will run in a new transaction
    }
}

15. How do you test Spring Boot applications?

Answer:
Spring Boot provides comprehensive testing support.

Unit Testing:

@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    
    @Mock
    private UserRepository userRepository;
    
    @InjectMocks
    private UserService userService;
    
    @Test
    void shouldFindUserById() {
        // Given
        User user = new User(1L, "John");
        when(userRepository.findById(1L)).thenReturn(Optional.of(user));
        
        // When
        User result = userService.findById(1L);
        
        // Then
        assertThat(result.getName()).isEqualTo("John");
        verify(userRepository).findById(1L);
    }
}

Integration Testing:

@SpringBootTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserIntegrationTest {
    
    @Autowired
    private TestRestTemplate restTemplate;
    
    @Autowired
    private UserRepository userRepository;
    
    @Test
    void shouldCreateUser() {
        User user = new User(null, "John", "john@test.com");
        
        ResponseEntity<User> response = restTemplate.postForEntity("/api/users", user, User.class);
        
        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
        assertThat(response.getBody().getId()).isNotNull();
    }
}

Web MVC Test:

@WebMvcTest(UserController.class)
class UserControllerTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private UserService userService;
    
    @Test
    void shouldReturnUser() throws Exception {
        when(userService.findById(1L)).thenReturn(new User(1L, "John"));
        
        mockMvc.perform(get("/api/users/1"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.name").value("John"));
    }
}

Expert Level Questions

16. How does Spring Boot support microservices architecture?

Answer:
Spring Boot provides several features for microservices:

1. Spring Cloud for microservices:

  • Service Discovery: Eureka, Consul

  • API Gateway: Spring Cloud Gateway

  • Configuration: Spring Cloud Config

  • Circuit Breaker: Resilience4j, Hystrix

  • Distributed Tracing: Sleuth, Zipkin

2. Example microservice setup:

// Eureka Client
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication { }

// Feign Client for service-to-service communication
@FeignClient(name = "order-service")
public interface OrderServiceClient {
    @GetMapping("/orders/user/{userId}")
    List<Order> getOrdersByUser(@PathVariable Long userId);
}

// Circuit Breaker
@CircuitBreaker(name = "orderService")
public List<Order> getUserOrders(Long userId) {
    return orderServiceClient.getOrdersByUser(userId);
}

17. What is the difference between @Mock and @MockBean?

Answer:

  • @Mock: From Mockito framework, creates a mock object. Used in plain unit tests without Spring context.

  • @MockBean: From Spring Boot, creates a mock and adds it to Spring application context. Used in integration tests.

// Plain unit test with @Mock
@ExtendWith(MockitoExtension.class)
class PlainUnitTest {
    @Mock
    private UserRepository userRepository;  // Mockito mock
    
    @Test
    void testSomething() {
        // Test without Spring context
    }
}

// Spring integration test with @MockBean
@SpringBootTest
class SpringIntegrationTest {
    @MockBean
    private UserRepository userRepository;  // Spring-managed mock
    
    @Test
    void testSomething() {
        // Test with Spring context
    }
}

18. How do you implement asynchronous processing in Spring Boot?

Answer:
Using @Async annotation and CompletableFuture:

1. Enable async support:

@SpringBootApplication
@EnableAsync
public class Application { }

2. Create async methods:

@Service
public class NotificationService {
    
    @Async
    public CompletableFuture<String> sendEmail(String to, String message) {
        // Simulate email sending delay
        Thread.sleep(2000);
        return CompletableFuture.completedFuture("Email sent to " + to);
    }
    
    @Async("taskExecutor")
    public void processInBackground(String data) {
        // Background processing
    }
}

3. Configure thread pool:

@Configuration
public class AsyncConfig {
    
    @Bean(name = "taskExecutor")
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("Async-");
        executor.initialize();
        return executor;
    }
}

19. How do you handle database connection pooling in Spring Boot?

Answer:
Spring Boot auto-configures connection pooling with HikariCP as default.

Configuration:

# HikariCP configuration
spring.datasource.hikari.connection-timeout=20000
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=1200000

# Or use different connection pool
spring.datasource.type=com.zaxxer.hikari.HikariDataSource

Custom configuration:

@Configuration
public class DatabaseConfig {
    
    @Bean
    @ConfigurationProperties("spring.datasource.hikari")
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }
}

20. How do you implement custom auto-configuration in Spring Boot?

Answer:
Creating custom auto-configuration involves:

1. Create configuration class:

@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyServiceProperties.class)
public class MyServiceAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public MyService myService(MyServiceProperties properties) {
        return new MyService(properties.getUrl(), properties.getTimeout());
    }
}

2. Create configuration properties:

@ConfigurationProperties("my.service")
public class MyServiceProperties {
    private String url = "http://default.url";
    private int timeout = 5000;
    // getters and setters
}

3. Register auto-configuration:
Create src/main/resources/META-INF/spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyServiceAutoConfiguration

4. Use conditional annotations:

  • @ConditionalOnClass - When class is in classpath

  • @ConditionalOnProperty - When property is set

  • @ConditionalOnBean - When bean exists

  • @ConditionalOnMissingBean - When bean doesn't exist

Bonus: Architecture & Design Questions

21. How would you design a RESTful API with Spring Boot?

Answer:
"A well-designed RESTful API should follow these principles:

  1. Resource-based URLs: /api/users, /api/users/{id}

  2. Proper HTTP methods: GET, POST, PUT, DELETE, PATCH

  3. Stateless: No server-side sessions

  4. HATEOAS: Include links for navigation

  5. Versioning: URL versioning or header versioning

  6. Pagination: For large datasets

  7. Filtering, Sorting, Searching

  8. Standardized error responses

  9. API documentation with Swagger/OpenAPI

Example implementation:

@RestController
@RequestMapping("/api/v1/users")
public class UserController {
    
    @GetMapping
    public ResponseEntity<Page<UserResponse>> getUsers(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String sort) {
        // Implementation with pagination
    }
    
    @PostMapping
    public ResponseEntity<UserResponse> createUser(@Valid @RequestBody CreateUserRequest request) {
        // Create user
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
        // Get single user
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<UserResponse> updateUser(@PathVariable Long id, 
                                                  @Valid @RequestBody UpdateUserRequest request) {
        // Update user
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        // Delete user
        return ResponseEntity.noContent().build();
    }
}

22. How do you monitor and optimize Spring Boot application performance?

Answer:
Monitoring:

  1. Spring Boot Actuator: Health checks, metrics, tracing

  2. Micrometer: Application metrics exported to Prometheus, Grafana

  3. APM tools: New Relic, AppDynamics, Elastic APM

  4. Log aggregation: ELK Stack, Splunk

Performance optimization:

  1. Database: Connection pooling, proper indexing, query optimization

  2. Caching: Redis, Ehcache for frequently accessed data

  3. Asynchronous processing: For long-running tasks

  4. Connection timeouts: Proper timeout configuration

  5. JVM tuning: Heap size, garbage collector selection

  6. Static content: CDN for static assets

  7. Compression: Gzip compression for responses

Example monitoring configuration:

management.metrics.export.prometheus.enabled=true
management.endpoint.metrics.enabled=true
management.endpoint.prometheus.enabled=true

These questions cover the essential Spring Boot knowledge needed for technical interviews, from basic concepts to advanced scenarios that demonstrate deep understanding of the framework and its ecosystem.

 

Comments (0)

No comments yet. Be the first to comment!

LecturreAI Assistant

Hello! I'm LecturreAI

What would you like to learn today?