Please enable JavaScript to view this page.

Mastering Spring Boot: Scenario-Based Interview Questions for Freshers & 0-3 Years Exp.

Mastering Spring Boot: Scenario-Based Interview Questions for Freshers & 0-3 Years Exp. - IT Defined Blog
IT Defined By IT Defined Team
2026-07-06 Backend Development

Ace your next Java Spring Boot interview with our scenario-based questions and expert answers. This guide covers core concepts like dependency injection, JPA, error handling, and microservices communication, crucial for freshers and candidates with 0-3 years experience.

Landing your first job or making a career switch in the IT sector, especially in India, requires more than just theoretical knowledge. Recruiters and hiring managers are increasingly looking for candidates who can think on their feet and apply concepts to real-world problems. This is where scenario-based interview questions come into play.

Today, we'll dive into some common yet crucial Java Spring Boot interview questions presented as scenarios. These are designed to test your practical understanding of building robust applications, from basic setup to handling complex architectures like microservices. Let's get started!

Scenario 1: Building a Simple REST API with Dependency Injection

The Problem:

You're tasked with developing a new feature for an existing Spring Boot application. This feature requires fetching user details from a database. You've created a UserService and a UserRepository. How would you ensure that your UserService gets an instance of UserRepository without manually creating it, adhering to Spring's best practices?

The Solution:

This scenario tests your understanding of Spring's Inversion of Control (IoC) container and Dependency Injection (DI). In Spring Boot, you'd leverage annotations to let the container manage object creation and their dependencies.

@Repository
public class UserRepository {
    public String findUserById(Long id) {
        // Simulate fetching from a database
        return 'User ' + id;
    }
}

@Service
public class UserService {
    private final UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public String getUserDetails(Long id) {
        return userRepository.findUserById(id);
    }
}

@RestController
@RequestMapping('/api/users')
public class UserController {
    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping('/{id}')
    public String getUser(@PathVariable Long id) {
        return userService.getUserDetails(id);
    }
}

Explanation:

  • The @Repository, @Service, and @RestController annotations mark these classes as Spring components. The Spring IoC container scans for these and creates instances (beans) of them.
  • The @Autowired annotation on the constructor of UserService tells Spring to automatically inject an instance of UserRepository when creating UserService. Similarly for UserController and UserService.
  • This approach promotes loose coupling and makes your code more testable and maintainable.

Scenario 2: Handling Data Persistence with JPA and Hibernate

The Problem:

Your Spring Boot application needs to store and retrieve 'Product' information from a MySQL database. Describe the steps and key components you would use to set up data persistence for a Product entity, enabling basic CRUD operations.

The Solution:

This question focuses on your knowledge of Java Persistence API (JPA) and its most common implementation, Hibernate, within a Spring Boot context. Spring Data JPA simplifies database interactions significantly.

// application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/productdb
spring.datasource.username=root
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

// Product.java (Entity)
@Entity
@Table(name = 'products')
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private double price;

    // Getters and Setters
    // Constructors
}

// ProductRepository.java
public interface ProductRepository extends JpaRepository<Product, Long> {
    // Spring Data JPA automatically provides CRUD methods
    // You can also define custom query methods here, e.g., List<Product> findByName(String name);
}

// ProductService.java
@Service
public class ProductService {
    private final ProductRepository productRepository;

    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public Product saveProduct(Product product) {
        return productRepository.save(product);
    }

    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }

    public Optional<Product> getProductById(Long id) {
        return productRepository.findById(id);
    }

    public void deleteProduct(Long id) {
        productRepository.deleteById(id);
    }
}

Explanation:

  • application.properties: Configures the database connection details for MySQL. spring.jpa.hibernate.ddl-auto=update tells Hibernate to update the schema based on your entities.
  • Product.java (Entity): Annotated with @Entity and @Table to map it to a database table. @Id marks the primary key, and @GeneratedValue configures auto-incrementing IDs.
  • ProductRepository.java: By extending JpaRepository<Product, Long>, Spring Data JPA automatically provides implementations for common CRUD operations (save, findById, findAll, deleteById, etc.) without writing any boilerplate code.
  • ProductService.java: Uses @Service and @Autowired to inject the ProductRepository, providing business logic around data operations.

Scenario 3: Implementing Robust Error Handling

The Problem:

In your Spring Boot REST API, if a request comes for a product ID that doesn't exist, the application currently throws an internal server error or a generic exception. How would you implement a custom error handling mechanism to return a meaningful 404 Not Found status with a custom error message to the client?

The Solution:

Proper error handling is crucial for any production-ready API. Spring Boot provides powerful mechanisms to centralize exception handling.

// Custom exception
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ProductNotFoundException extends RuntimeException {
    public ProductNotFoundException(String message) {
        super(message);
    }
}

// Global Exception Handler
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ProductNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleProductNotFoundException(ProductNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage(), System.currentTimeMillis());
        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
    }

    // You can add more @ExceptionHandler methods for other exceptions

    // A generic error response class (POJO)
    public static class ErrorResponse {
        private int status;
        private String message;
        private long timestamp;

        public ErrorResponse(int status, String message, long timestamp) {
            this.status = status;
            this.message = message;
            this.timestamp = timestamp;
        }

        // Getters
    }
}

// Modified ProductService (to throw the exception)
@Service
public class ProductService {
    // ... (repository injection and other methods)

    public Product getProductById(Long id) {
        return productRepository.findById(id)
                .orElseThrow(() -> new ProductNotFoundException('Product not found with ID: ' + id));
    }
}

Explanation:

  • ProductNotFoundException: A custom exception extending RuntimeException. The @ResponseStatus(HttpStatus.NOT_FOUND) annotation is a simple way to map this exception to a 404 status code, though @RestControllerAdvice offers more control.
  • GlobalExceptionHandler: Annotated with @RestControllerAdvice, this class becomes a global handler for exceptions thrown by any controller.
  • @ExceptionHandler(ProductNotFoundException.class): This method specifically catches ProductNotFoundException. It constructs a custom ErrorResponse object (a simple POJO) and returns it within a ResponseEntity, allowing you to set the HTTP status (HttpStatus.NOT_FOUND in this case) and body.
  • Modified ProductService: Instead of returning an Optional directly, we use orElseThrow() to throw our custom exception if the product isn't found.

Scenario 4: Inter-Service Communication in Microservices

The Problem:

You're working on a microservices architecture. You have a 'Order Service' that needs to fetch the current stock quantity of a product from a separate 'Inventory Service' before placing an order. How would you design this communication between the two Spring Boot microservices?

The Solution:

In a microservices setup, services often need to communicate with each other. For synchronous communication, Spring Boot applications commonly use RestTemplate or the newer, non-blocking WebClient.

// In Order Service (Client)
@Service
public class OrderService {
    private final RestTemplate restTemplate;

    @Autowired
    public OrderService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String placeOrder(Long productId, int quantity) {
        // Assume Inventory Service is running on http://localhost:8081
        String inventoryServiceUrl = 'http://localhost:8081/api/inventory/check-stock/' + productId;

        // Make a GET request to Inventory Service
        ResponseEntity<Integer> response = restTemplate.getForEntity(inventoryServiceUrl, Integer.class);

        if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
            Integer availableStock = response.getBody();
            if (availableStock >= quantity) {
                // Logic to place order
                return 'Order placed for ' + productId + ' with quantity ' + quantity;
            } else {
                return 'Not enough stock for product ' + productId + '. Available: ' + availableStock;
            }
        } else {
            return 'Failed to check inventory for product ' + productId;
        }
    }
}

// In Inventory Service (Server)
@RestController
@RequestMapping('/api/inventory')
public class InventoryController {

    // Simulate a simple stock check
    private Map<Long, Integer> productStock = new HashMap<>();

    public InventoryController() {
        productStock.put(101L, 50);
        productStock.put(102L, 20);
    }

    @GetMapping('/check-stock/{productId}')
    public ResponseEntity<Integer> checkStock(@PathVariable Long productId) {
        if (productStock.containsKey(productId)) {
            return ResponseEntity.ok(productStock.get(productId));
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}

Explanation:

  • RestTemplate (or WebClient): In OrderService, RestTemplate is used to make an HTTP GET request to the InventoryService. You'd typically configure RestTemplate as a bean in your application.
  • Service Discovery: In a real microservices environment, you wouldn't hardcode URLs (like http://localhost:8081). Instead, you'd use a service discovery mechanism like Eureka or Consul, combined with a client-side load balancer like Spring Cloud LoadBalancer (formerly Ribbon), to locate the InventoryService dynamically.
  • ResponseEntity: It's good practice to use ResponseEntity to get full control over the HTTP response, including status codes and headers.
  • Inventory Service: It exposes an endpoint (/api/inventory/check-stock/{productId}) that the OrderService can call to get stock information.

These scenarios cover fundamental aspects of Java Spring Boot development that are frequently tested in interviews. Understanding these concepts deeply, along with practical implementation experience, will significantly boost your confidence.

Keep practicing these concepts and building small projects. The more you code, the better you'll understand. Don't forget to follow itdefined.org for more valuable insights and career guidance to stay ahead in your IT journey!