Microservice Interview Questions for Java Backend Developers series-3

Hey there! In Java interviews, Spring Boot and microservices take the spotlight. Mastering microservices is key for both interviews and your day-to-day work. Ready to dive in? Let’s get started!

Ajay Rathod
13 min readDec 25, 2023

(A bit of context: I’ve conducted numerous interviews for software engineering positions in most of the MNCs.)

Are you preparing for a job interview as a Java developer?

Find my book Guide To Clear Java Developer Interview here Gumroad (PDF Format) and Amazon (Kindle eBook).

Guide To Clear Spring-Boot Microservice Interview here Gumroad (PDF Format) and Amazon (Kindle eBook).

Guide To Clear Front-End Developer Interview here Gumroad (PDF Format) and Amazon (Kindle eBook).

Download the sample copy here:

Guide To Clear Java Developer Interview[Free Sample Copy]

Guide To Clear Spring-Boot Microservice Interview[Free Sample Copy]

Guide To Clear Front-End Developer Interview [Sample_Copy]

Ready for personalized guidance? Book your 1-on-1 session with me here: https://topmate.io/ajay_rathod11

What are the design principles of Microservices?

Microservices is an architectural style for building software applications as a collection of small, independent services. These services are loosely coupled, meaning they have minimal dependencies on each other, and they communicate with each other over well-defined APIs.

Modularity: Services should be self-contained and have a single, well-defined purpose.

Scalability: Services should be able to scale independently to handle the increasing load.

Decentralization: The system should be decentralized, allowing for loosely coupled services.

High Availability: Services should be designed to be highly available to ensure system reliability.

Resilience: Services should be designed to handle failures gracefully.

Data Management: Services should manage their own data and not share a common database.

Statelessness: Services should be stateless to allow for easy scaling and caching.

Independent Deployment: Services should be deployable independently of other services.

Observability: The system should have built-in monitoring and logging capabilities to allow visibility into system behaviour.

Automation: Deployment, testing, and scaling should be automated as much as possible.

Which design patterns are used for database design in microservices?

Common design patterns used for database design in microservices are:

Database per Service: Each service has its database, allowing for a high degree of independence and autonomy.

Shared Database: A shared database is used by multiple services to store data that is commonly used across the system.

Event Sourcing: The state of the system is stored as a series of events, allowing for better scalability and fault tolerance.

Command Query Responsibility Segregation (CQRS): Queries and commands are separated, allowing for improved scalability and performance.

Saga: A long-running transaction is broken down into smaller, autonomous transactions that can be executed by different services.

Materialized View: A pre-computed view of data is used to provide fast access to commonly used data.

API Composition: APIs are composed to provide a unified view of data from multiple services.

Read Replicas: Read replicas are used to offload read requests from the primary database, improving performance and scalability.

Explain the CQRS concept

CQRS Microservice pattern: CQRS stands for Command and Query Responsibility Segregation, a pattern that separates read and update operations for a data store. Implementing CQRS in your application can maximize its performance, scalability, and security. The flexibility created by migrating to CQRS allows a system to better evolve over time and prevents update commands from causing merge conflicts at the domain level.

Benefits of CQRS include:

· Independent scaling. CQRS allows the read and write workloads to scale independently, and may result in fewer lock contentions.

· Optimized data schemas. The read side can use a schema that is optimized for queries, while the write side uses a schema that is optimized for updates.

· Security. It’s easier to ensure that only the right domain entities are performing writes on the data.

· Separation of concerns. Segregating the read and write sides can result in models that are more maintainable and flexible. Most of the complex business logic goes into the write model. The read model can be relatively simple.

Simpler queries. By storing a materialized view in the read database, the application can avoid complex joins when querying.

Separation of the read and write stores also allows each to be scaled appropriately to match the load. For example, read stores typically encounter a much higher load than write stores.

If separate read and write databases are used, they must be kept in sync. Typically, this is accomplished by having the write model publish an event whenever it updates the database.

Below diagram illustrates, how we have segregated Read write databses for read and write heavy operation, although thet needs to be in sync.

Explain the Choreography concept.

Choreography:

Choreography is a way to coordinate sagas where participants exchange events without a centralized point of control. With choreography, each local transaction publishes domain events that

Benefits

· Good for simple workflows that require few participants and don’t need a coordination logic.

· Doesn’t require additional service implementation and maintenance.

· Doesn’t introduce a single point of failure, since the responsibilities are distributed across the saga participants.

Drawbacks

· Workflow can become confusing when adding new steps, as it’s difficult to track which saga participants listen to which commands.

· There’s a risk of cyclic dependency between saga participants because they have to consume each other’s commands.

· Integration testing is difficult because all services must be running to simulate a transaction.

trigger local transactions in other services.

Explain the circuit breaker concept.

The Circuit Breaker design pattern is a resilience pattern used in software development to detect and respond to failures in external services or remote endpoints. It aims to prevent cascading failures and protect the overall system from being overwhelmed by excessive requests to a failing service.

When to use this pattern

Use this pattern:

To prevent an application from trying to invoke a remote service or access a shared resource if this operation is highly likely to fail.

Example

In a web application, several of the pages are populated with data retrieved from an external service. If the system implements minimal caching, most hits to these pages will cause a round trip to the service. Connections from the web application to the service could be configured with a timeout period (typically 60 seconds), and if the service doesn’t respond in this time the logic in each web page will assume that the service is unavailable and throw an exception.

However, if the service fails and the system is very busy, users could be forced to wait for up to 60 seconds before an exception occurs. Eventually resources such as memory, connections, and threads could be exhausted, preventing other users from connecting to the system, even if they aren’t accessing pages that retrieve data from the service.

Scaling the system by adding further web servers and implementing load balancing might delay when resources become exhausted, but it won’t resolve the issue because user requests will still be unresponsive and all web servers could still eventually run out of resources.

Wrapping the logic that connects to the service and retrieves the data in a circuit breaker could help to solve this problem and handle the service failure more elegantly. User requests will still fail, but they’ll fail more quickly and the resources won’t be blocked.

Key Features of Circuit Breaker Pattern:

Failure Detection: The Circuit Breaker monitors the health of an external service by tracking the success or failure of requests.

State Transition: Based on the monitored failure rate, the Circuit Breaker transitions into different states: Open, Closed, or Half-Open.

Open State: In the Open state, the Circuit Breaker rejects all requests to the failing service, preventing further failures and cascading effects.

Closed State: When the failure rate drops, the Circuit Breaker transitions to the Closed state, allowing requests to pass through and resume normal operation.

Half-Open State: To cautiously check the service’s recovery, the Circuit Breaker enters the Half-Open state, allowing a limited number of requests to pass through. If these requests succeed, the Circuit Breaker transitions to the Closed state. If they fail, it returns to the Open state.

Timeout Mechanism: The Circuit Breaker implements a timeout mechanism to prevent the system from being stuck in the Open state indefinitely. After a certain timeout period, the Circuit Breaker transitions to the Half-Open state to attempt recovery.

Applications of Circuit Breaker Pattern:

External Service Calls: Protecting the system from failures in external services, such as APIs, databases, or third-party providers.

Remote Endpoints: Handling failures when communicating with remote endpoints, preventing cascading failures and improving system resilience.

Resource-Intensive Operations: Protecting resource-intensive operations from being overwhelmed by excessive requests, ensuring overall system stability.

Microservice Architecture: Preventing failures in one microservice from affecting the entire system by isolating and managing failures at the individual service level.

Which library you have used to implement it circuit-breaker?

Netflix Hystrix and Resilience4j are two open-source libraries that provide solutions for fault tolerance and resilience in distributed systems. They both implement the circuit breaker pattern, which is a technique for preventing cascading failures.

Hystrix was originally developed by Netflix to improve the resilience of their own microservices architecture. It provides a number of features that can help to make microservices more resilient to failures, such as:

· Circuit breakers: Circuit breakers can be used to isolate microservices from each other and to prevent cascading failures.

· Fallbacks: Fallbacks can be used to provide a backup plan in case a microservice fails.

· Thread pools: Hystrix provides thread pools to isolate microservices from each other and to prevent performance problems.

· Metrics: Hystrix provides metrics that can be used to monitor the performance and health of microservices.

Hystrix is designed to do the following:

· Give protection from and control over latency and failure from dependencies accessed (typically over the network) via third-party client libraries.

· Stop cascading failures in a complex distributed system.

· Fail fast and rapidly recover.

· Fallback and gracefully degrade when possible.

· Enable near real-time monitoring, alerting, and operational control.

Resilience4j is a newer library that is inspired by Hystrix. It provides a number of features that are similar to Hystrix, but it also has some additional features, such as:

Support for reactive programming: Resilience4j provides support for reactive programming, which makes it easier to build resilient microservices using reactive frameworks such as RxJava and Reactor.

Bulkheads: Bulkheads can be used to isolate groups of microservices from each other and to prevent cascading failures.

Rate limiters: Rate limiters can be used to control the flow of traffic to microservices and to prevent performance problems.

Both Hystrix and Resilience4j are powerful tools that can help you to build resilient microservices-based applications. However, there are some key differences between the two libraries:

Hystrix is a more mature library with a larger community of users.

Resilience4j is a newer library with some additional features, such as support for reactive programming and bulkheads.

How distributed tracing is done?

Distributed tracing plays a crucial role in monitoring and debugging microservices applications, where requests flow across multiple services. Spring Cloud provides various tools and libraries to implement distributed tracing effectively:

1. Spring Cloud Sleuth:

A core component for distributed tracing in Spring Cloud.

· Generates unique trace IDs for requests and propagates them across services.

· Supports various tracing backends, including Zipkin, Jaeger, and OpenTelemetry.

· Provides annotations like @Trace and @Span for tracing specific methods and spans.

2. Zipkin:

A popular open-source tracing backend used with Spring Cloud Sleuth.

· Collects and stores trace data from various services.

· Offers a web interface for visualizing traces and identifying performance bottlenecks.

3. Jaeger:

· Another popular tracing backend with similar functionalities to Zipkin.

· Offers advanced features like dependency analysis and causal tracing.

4. Spring Cloud Stream:

· Enables tracing messages flowing through message brokers in microservices.

· Integrates with Spring Cloud Sleuth to provide end-to-end tracing across services and message processing.

5. OpenTelemetry:

· Emerging standard for instrumenting and monitoring applications.

· Provides a unified API for generating and collecting tracing data.

· Offers integration with various tracing backends and Spring Cloud Sleuth.

Implementation Strategies:

· Manual instrumentation: Developers manually add tracing code to application logic using Sleuth annotations.

· Aspect-based instrumentation: Utilizes aspects to automatically inject tracing logic into application code.

Spring Boot Starter for Sleuth: Simplifies integration with Spring Boot applications.

Benefits of Distributed Tracing:

· Improved troubleshooting: Provides insights into request flow and identifies root causes of issues faster.

· Performance monitoring: Helps identify performance bottlenecks and optimize service interactions.

· Debugging complex workflows: Enables visualizing and analyzing the flow of requests across multiple services.

Suggest a design for how to connect internal and external services in microservices.

Connecting internal and external services in a microservices architecture requires careful consideration to maintain loose coupling and high autonomy. Here are some design suggestions:

API Gateway:

  • Single gateway for external access: A central API gateway serves as the entry point for all external clients, including web applications, mobile apps, and third-party systems. It routes requests to the appropriate internal services and aggregates responses if needed. This increases security and simplifies client-side integration.
  • Separate gateways for internal access: While some may advocate for using the same gateway for internal and external calls, consider having internal-specific gateways. This allows tighter control over internal APIs, different authentication/authorization mechanisms, and potentially optimized communication protocols.

Communication Protocols:

  • Standardized protocols: Use standard protocols like HTTP, REST, or gRPC for both internal and external communication. This simplifies implementation, debugging, and integration with various tools and platforms.
  • Asynchronous communication: Leverage asynchronous messaging (e.g., Kafka, RabbitMQ) for inter-service communication. This decouples services, improves scalability, and enables resilience to failures.

Security:

  • Layered security: Implement separate security mechanisms for external and internal communication. For external access, use strong authentication and authorization protocols (e.g., OAuth2, OpenID Connect). For internal calls, consider lightweight token-based authorization or service accounts.
  • Encrypted communication: Use TLS/SSL to encrypt all communication between services and clients, both internal and external.

Design Patterns:

  • API composition: For complex workflows that require data from multiple services, consider API composition patterns like aggregator or chain patterns. These allow building higher-level functionalities through seamless orchestration of internal APIs.
  • Backend for Frontend (BFF): When catering to different client types (web, mobile), consider dedicated BFF services that adapt internal APIs to the specific needs of each client, improving performance and UI/UX.

Explain the Saga pattern in Microservice.

The Saga design pattern is a way to manage data consistency across microservices in distributed transaction scenarios. A saga is a sequence of transactions that updates each service and publishes a message or event to trigger the next transaction step. If a step fails, the saga executes compensating transactions that counteract the preceding transactions.

Key Features of Saga Pattern:

· Distributed Transaction Management: The Saga pattern effectively handles distributed transactions across multiple services, maintaining data consistency in a distributed environment.

· Loose Coupling: Services involved in the Saga are loosely coupled, communicating through asynchronous messages, allowing for independent development and deployment.

· Compensating Transactions: Compensating transactions are implemented to undo the effects of previous local transactions in case of failures, ensuring data consistency.

· Orchestration or Choreography: The Saga pattern can be implemented using either orchestration, where a central coordinator manages the flow of local transactions, or choreography, where services communicate directly with each other to coordinate the Saga.

· Applications of Saga Pattern:

· Order Processing: Managing the complex process of order placement, payment, inventory updates, and shipping confirmations across multiple services.

· Account Management: Handling account creation, balance updates, and fraud detection, ensuring consistency across multiple services involved.

· Inventory Management: Coordinating stock level updates across multiple services involved in sales, fulfillment, and supply chain management.

· Customer Relationship Management (CRM): Synchronizing customer data across multiple services involved in marketing, sales, and support.

The Saga pattern provides transaction management using a sequence of local transactions. A local transaction is the atomic work effort performed by a saga participant. Each local transaction updates the database and publishes a message or event to trigger the next local transaction in the saga. If a local transaction fails, the saga executes a series of compensating transactions that undo the changes that were made by the preceding local transactions.

In Saga patterns:

· Compensable transactions are transactions that can potentially be reversed by processing another transaction with the opposite effect.

· A pivot transaction is the go/no-go point in a saga. If the pivot transaction commits, the saga runs until completion. A pivot transaction can be a transaction that is neither compensable nor retryable, or it can be the last compensable transaction or the first retryable transaction in the saga.

· Retryable transactions are transactions that follow the pivot transaction and are guaranteed to succeed.

There are two common saga implementation approaches, choreography and orchestration. Each approach has its own set of challenges and technologies to coordinate the workflow.

When to use this pattern

· Use the Saga pattern when you need to:

· Ensure data consistency in a distributed system without tight coupling.

· Roll back or compensate if one of the operations in the sequence fails.

The Saga pattern is less suitable for:

· Tightly coupled transactions.

· Compensating transactions that occur in earlier participants.

· Cyclic dependencies.

Other microservice related articles

Microservice Interview Questions for Backend Developers series-1

Thanks for reading

  • 👏 Please clap for the story and follow me 👉
  • 📰 Read more content on my Medium (21 stories on Java Developer interview)

Find my books here:

--

--

Ajay Rathod
Ajay Rathod

Written by Ajay Rathod

Java Programmer | AWS Certified | Writer | Find My Books on Java Interview here - https://rathodajay10.gumroad.com | YouTube - https://www.youtube.com/@ajtheory

No responses yet