Thanks to visit codestin.com
Credit goes to www.geeksforgeeks.org

Open In App

Java Microservices Architecture & Development Interview Questions

Last Updated : 28 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Java Microservices Architecture is a style of designing applications where the system is broken into small, independent services, each responsible for a specific function and communicating through APIs. Java Microservices Development refers to the actual process of building these services using Java frameworks like Spring Boot and Spring Cloud, and deploying them with tools such as Docker and Kubernetes.

1. Compare monolithic and microservices architectures in the context of scalability, deployment, and fault tolerance. Support with real-world examples and diagrams if needed.

A monolithic architecture is a single deployable unit where all functionalities reside together, making initial development fast but scaling and deploying harder. A microservices architecture splits the system into independently deployable services.

Scalability: Monoliths scale as a whole (costly), while microservices scale components independently (e.g., scale only “Inventory” service during sales).

Deployment:

  • Monoliths require full redeployment even for small changes.
  • Microservices enable continuous deployment using CI/CD tools.

Fault Tolerance:

  • A crash in a monolith affects the entire app.
  • In microservices, failure is isolated (e.g., fallback in payment system).

2. Explain how you would decompose a large monolithic e-commerce application into microservices. What role does Domain-Driven Design (DDD) and bounded context play?

Decomposition should be based on business capabilities, not just technical layers.

Steps:

  • Identify Bounded Contexts: E.g., Product, Cart, Order, Payment, User services.
  • Use DDD principles: Design Ubiquitous Language for each domain. Map aggregates, entities, value objects.

Benefits:

  • Avoid shared models across services.
  • Better encapsulation and ownership.

3. How would you structure a real-world Spring Boot microservice project with layered and modular design? Explain how it helps CI/CD and team ownership.

A layered and modular project structure in Spring Boot separates responsibilities across controllers, services, repositories, and configuration. This design improves maintainability, testability, and supports efficient CI/CD and team collaboration.

Structure:

  • controller/
  • service/
  • repository/
  • dto/
  • model/
  • config/

CI/CD Impact:

  • Easier unit test coverage
  • Logical separation for PRs
  • Enables parallel team work (e.g., UI devs consume controller contracts)

4. Design a RESTful Spring Boot service with layered architecture. Explain how concerns are separated and how this aids maintainability and testing.

Layered Architecture in Spring Boot:

1. Controller Layer (API Layer):

  • Handles HTTP requests/responses.
  • Delegates logic to Service layer.

Example:

Java
@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService service;
    @GetMapping("/{id}") public User getUser(@PathVariable Long id) {
        return service.getUser(id);
    }
}

2. Service Layer (Business Logic):

  • Encapsulates business logic.
  • Calls Repository for persistence.

Example:

Java
@Service
public class UserService {
    private final UserRepository repo;
    public User getUser(Long id) { return repo.findById(id).orElseThrow(); }
}

Repository Layer (Data Access):

  • Interacts with DB using JPA/Hibernate.
  • Example:

public interface UserRepository extends JpaRepository<User, Long> {}

Benefits:

  • Easier to test each layer independently.
  • Promotes SOLID design.

Testing Tip: Use @WebMvcTest for controller, @DataJpaTest for repository.

5. Discuss five important Spring annotations used in microservices development. Explain their purpose, differences, and behavior at runtime.

AnnotationPurpose
@RestControllerMarks a class as a REST controller. Combines @Controller + @ResponseBody.
@ServiceMarks a class as part of the business/service layer.
@RepositoryMarks a class as a Data Access Object (DAO).
@ComponentGeneric stereotype annotation for Spring-managed beans.
@AutowiredEnables dependency injection by type (constructor, field, or setter).

6. What is the internal working of Spring Boot’s auto-configuration mechanism? How would you disable a specific auto-configuration and provide a custom implementation?

Spring Boot auto-config loads beans conditionally from spring.factories. You can disable unwanted ones using exclude, and override defaults by defining your own beans with @Bean (and @Primary if needed).

Internal Working:

1. Triggered by @EnableAutoConfiguration (included in @SpringBootApplication).

2. Reads auto-config classes from META-INF/spring.factories (or AutoConfiguration.imports in newer versions).

3. Uses conditional annotations:

  • @ConditionalOnClass-> applies if class is on classpath.
  • @ConditionalOnMissingBean-> applies only if no bean is already defined.
  • @ConditionalOnProperty -> applies based on property values.

4. Ensures Boot config is applied only when needed and is overridden if user defines a bean.

Disabling Auto-Config:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })

7. Explain multiple REST API versioning strategies. Which one is most REST-compliant and why? Show how you would implement it in Spring Boot.

REST API Versioning Strategies: Techniques used to manage and deliver different versions of a RESTful API while maintaining backward compatibility.

Types of Versioning:

1. URI-based: /api/v1/customers

  • Simple, widely used, version in path.

2. Query Parameter-based: /api/customers?version=1

  • Easy, but mixes resource identity with version.

3. Header-based (Content Negotiation): Accept: application/vnd.api+json;version=1

  • Most REST-compliant: keeps URIs stable, follows uniform interface.

Implementation (URI-based):

@RestController

@RequestMapping("/api/v1/customers")

public class CustomerV1Controller {

@GetMapping

public String getCustomersV1() { return "Customer data V1"; }

}

8. Implement pagination and sorting in a Spring Boot REST endpoint using Spring Data JPA. Explain how it benefits large-scale applications.

Pagination and Sorting in Spring Boot is a mechanism to retrieve subsets of data (pages) and order them based on specific fields, reducing payload size and improving performance. It allows efficient handling of large datasets in REST APIs.

Implementation using Spring Data JPA:

@GetMapping("/products")

public Page<Product> getProducts(Pageable pageable) {

return productRepository.findAll(pageable);

}

Usage: /products?page=0&size=10&sort=name,desc

Benefits:

  • Reduces response payload for large datasets.
  • Improves performance and server memory usage.
  • Enables better user experience with paginated views or infinite scrolling.

9. What is HATEOAS in REST APIs? When should it be used? Provide an example using Spring HATEOAS library.

HATEOAS (Hypermedia As The Engine Of Application State) is a REST principle where API responses include links to related actions or resources, allowing clients to navigate the API dynamically.

When to Use:

  • When building hypermedia-driven clients that should discover actions dynamically without hardcoded URLs.

Spring HATEOAS Example:

EntityModel<Product> product = EntityModel.of(p);
product.add(linkTo(methodOn(ProductController.class).getById(p.getId())).withSelfRel());

10. What problems arise from hardcoded configuration in microservices? Explain how Spring Cloud Config solves these and how to secure it.

Spring Cloud Config is a centralized configuration management tool for microservices that externalizes application settings from the code. It enables dynamic updates, environment consistency, and secure storage of sensitive data.

Problems with Hardcoded Config:

  • Risk of sensitive data leaks (e.g., passwords, API keys).
  • Inconsistent configuration across environments.
  • Requires redeployment for config changes.

Spring Cloud Config Solution:

  • Externalizes configuration in a central repository (Git, SVN, etc.).
  • Supports dynamic refresh with Spring Actuator (/refresh).
  • Secures sensitive data with encryption and authentication (e.g., Vault, Git credentials).

11. How would you build fault-tolerant APIs in Spring Boot? Explain how to handle retries, circuit breakers, and timeouts using Resilience4j.

Fault-Tolerant APIs in Spring Boot is a techniques to make microservices resilient against failures, ensuring continuous operation. Resilience4j provides features like retries, circuit breakers, and timeouts to handle service disruptions gracefully.

Implementation with Resilience4j:

  • Retry: Automatically retry failed requests.
  • Circuit Breaker: Opens the circuit after repeated failures to prevent cascading errors.
  • Timeout: Limits execution time to avoid blocking resources.

Example:

Java
@Retry(name = "productService")
@CircuitBreaker(name = "productService", fallbackMethod = "fallbackProduct")
@TimeLimiter(name = "productService")
public Product getProduct(Long id) { ... }

public Product fallbackProduct(Long id, Throwable ex) {
    return new Product(id, "Fallback Product");
}

12. Create a centralized exception handling mechanism using @ControllerAdvice. Explain how to return custom structured error responses.

A centralized mechanism to handle exceptions across all controllers in Spring Boot, providing consistent and structured error responses.

Implementation Example:

Java
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(NotFoundException.class)
    public ResponseEntity<ErrorDto> handleNotFound(NotFoundException e) {
        return new ResponseEntity<>(new ErrorDto("404", e.getMessage()), HttpStatus.NOT_FOUND);
    }
}

Benefits:

  • Reusable
  • Centralized
  • Structured error format

13. How would you validate complex nested request bodies in Spring Boot using Hibernate Validator? Include example annotations and nested class behavior.

Hibernate Validator allows validating complex and nested request objects using annotations, ensuring all fields, including nested objects, meet specified constraints.

Implementation Example:

Java
public class Order {
    @NotBlank(message = "Order ID is required")
    private String orderId;

    @Valid
    private Address address; // Nested object
}

public class Address {
    @NotNull(message = "Street cannot be null")
    private String street;

    @NotBlank(message = "City cannot be blank")
    private String city;
}

Key Points:

  • Use @Valid on nested objects to trigger recursive validation.
  • Common annotations: @NotNull, @NotBlank, @Size, @Pattern.
  • Optionally, use BindingResult in controller to handle validation errors and return structured messages.

14. How does constructor-based injection differ from field injection in Spring Boot? Which is preferred and why?

  • Field Injection: Uses @Autowired directly on fields; easy but not testable and violates immutability.
  • Constructor Injection: Injects dependencies via constructor; promotes immutability, easier testing, and cleaner code.

15. How do you handle partial failures or degraded services in a microservice ecosystem? Describe a fallback strategy and graceful degradation approach.

Partial failures in microservices are managed using fallback strategies and graceful degradation. Implement fallback methods (e.g., with Resilience4j @CircuitBreaker) to return cached or default responses, notify users of limited functionality, and prevent cascading failures.

Example:

@CircuitBreaker(name = "ratingService", fallbackMethod = "fallbackRatings")
public List<Rating> getRatings(...) { ... }


Explore