INTERVIEW PREPARATION GUIDE
Monolith to Microservices
Migration Project · Real World Scenario · Challenges & Solutions
Java · Spring Boot · Spring Cloud · Docker · Kubernetes · API Gateway · Kafka
■ Project ■ Architecture ■ Tech Stack ■ Goal
E-Commerce Platform Monolith → 8 Services Java 17, Spring Boot 3.x Interview Ready 100%
TABLE OF CONTENTS
1 Project Background & Real-World Scenario
2 Monolith Architecture – What We Had
3 Why We Migrated – Pain Points
4 Migration Strategy – Strangler Fig Pattern
5 Microservices Architecture – What We Built
6 Tech Stack Deep Dive
7 Real Challenges Faced & How We Solved Them
8 Interview Q&A; – Basic to Advanced
9 System Design Diagrams (Text Format)
10 Key Metrics & Results
Confidential – Interview Preparation Document Page 1
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
1. PROJECT BACKGROUND & REAL-WORLD
SCENARIO
The Project – E-Commerce Platform (ShopEasy)
Real World Context: ShopEasy is a mid-sized B2C e-commerce platform serving 500K+ daily active users
across India. Originally built as a monolithic Spring MVC application 5 years ago with a single Oracle DB, the
system handles Product Catalog, User Management, Order Processing, Payment, Inventory, Notifications,
Search, and Analytics — all in one deployable WAR file.
How You Explain It In Interview:
Start with context, then pain, then solution. Interviewers love stories — don't just list technologies. Walk them
through your journey.
■ Interviewer: Tell me about your project.
■ You: I worked on migrating ShopEasy — a monolithic Java EE / Spring MVC e-commerce application — to
a microservices architecture using Spring Boot 3.x and Spring Cloud. The system had ~2 million lines of
code, a single Oracle DB, and was deployed as one WAR file. During peak sales events like Diwali, the
system would go down completely even if only the Payment module had an issue. My role was Lead
Developer responsible for decomposing the monolith, setting up the service mesh, inter-service
communication, and CI/CD pipelines.
Project Timeline
Phase Duration Key Activities
Phase 1 – Analysis 3 months Identify service boundaries, domain
modeling, DDD
Phase 2 – Foundation 2 months API Gateway, Service Registry, Config
Server, CI/CD
Phase 3 – Extraction 6 months User, Product, Order, Payment
services extracted
Phase 4 – Migration 4 months Inventory, Notification, Search,
Analytics services
Phase 5 – Cutover 1 month Traffic migration, monolith
decommission, monitoring
Confidential – Interview Preparation Document Page 2
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
2. MONOLITH ARCHITECTURE – WHAT WE HAD
Original Monolith Stack
Aspect Technology Pain Point
Language Java 8 Single WAR deployment on Tomcat 8.5
Framework Spring MVC 4.x + Hibernate One ApplicationContext, shared
transaction
Database Oracle 12c (single schema) All 40+ tables in same DB
Frontend JSP + jQuery Served from same WAR
Build Maven Single [Link], 45-min build time
Deployment Manual WAR copy Zero downtime deployment impossible
Monitoring Log4j files only No distributed tracing or metrics
Monolith Architecture (Text Diagram)
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■
SHOPEASE MONOLITH (WAR) ■ ■ ■ ■ ■■■■■■■■■■■■ ■■■■■■■■■■■■ ■■■■■■■■■■■■
■■■■■■■■■■■■ ■ ■ ■ User ■ ■ Product ■ ■ Order ■ ■ Payment ■ ■ ■ ■ Module ■ ■ Module ■ ■
Module ■ ■ Module ■ ■ ■ ■■■■■■■■■■■■ ■■■■■■■■■■■■ ■■■■■■■■■■■■ ■■■■■■■■■■■■ ■ ■
■ ■ ■ ■ ■ ■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■ ■ ■
SHARED SERVICE LAYER (Spring Beans) ■ ■ ■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■ ■ ■ ■ ■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■ ■ ■ ORACLE DB
(Single Schema) ■ ■ ■ ■ users | products | orders | payments | inventory ■ ■ ■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ↕ All
traffic routed through single entry point
Confidential – Interview Preparation Document Page 3
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
3. WHY WE MIGRATED – PAIN POINTS
Monolith Problems Microservices Benefits
• Build takes 45 min – slow feedback • One bug kills • Independent builds under 5 min • Fault isolation – one
entire platform • Can't scale Payment without scaling service failure is contained • Scale only what needs
everything • DB is a single point of failure • Hard to scaling • Each service has own DB • Small services –
onboard new devs – 1M+ LOC • Release every 3 weeks team owns one domain • Deploy multiple times per day •
due to risk • Different teams stepping on each other • Teams work independently • Choose best tech per
Can't try new tech in one module service
■ Interviewer: Why did you decide to migrate to microservices?
■ You: During the 2023 Diwali sale, our Payment service had a memory leak. Because everything was in one
JVM, the memory leak brought down the entire platform — Product, Orders, everything. We lost
approximately 40 lakh rupees in revenue in 2 hours. After that incident, management approved the migration.
Beyond the immediate crisis, we had scaling issues — to handle peak traffic on Payment, we had to scale the
entire 4GB WAR file across 8 servers, which was extremely wasteful.
Confidential – Interview Preparation Document Page 4
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
4. MIGRATION STRATEGY – STRANGLER FIG
PATTERN
What is Strangler Fig Pattern?
Named after the strangler fig tree that grows around a host tree and eventually replaces it. We incrementally
replace monolith functionality with microservices. The monolith and microservices run in parallel — traffic is
gradually routed to new services. Zero big-bang rewrite. Each service is extracted one at a time, starting with
least-coupled modules.
Migration Steps We Followed
Step 1 Domain Analysis Used Domain-Driven Design (DDD) to identify Bounded Contexts —
each BC became a candidate microservice. Drew context maps to find
coupling.
Step 2 Shared Database Each new service got its own schema/DB. We used the
Decomposition Database-per-Service pattern. Migration from shared Oracle to separate
DBs.
Step 3 API Gateway First Set up Spring Cloud Gateway as the single entry point before extracting
any service. This gave us routing control to direct traffic to monolith OR
new services.
Step 4 Extract Leaf Services Started with Notification Service (least coupled). Then User Service,
First Product Service, moving toward core Order/Payment last.
Step 5 Event-Driven Used Kafka for async communication between services to avoid tight
Communication coupling. Replaced direct method calls with domain events.
Step 6 Gradual Traffic Shift Used API Gateway routing rules to shift 1%→10%→50%→100% traffic
to new services. Canary deployment approach.
Confidential – Interview Preparation Document Page 5
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
5. MICROSERVICES ARCHITECTURE – WHAT WE
BUILT
8 Microservices Extracted
Service Responsibility Tech Port
User Service User registration, auth, profiles Spring Boot + PostgreSQL + JWT 8081
Product Service Product catalog, categories, images Spring Boot + MongoDB 8082
Order Service Order lifecycle management Spring Boot + PostgreSQL 8083
Payment Service Payment processing, refunds Spring Boot + PostgreSQL 8084
Inventory Service Stock management, reservations Spring Boot + PostgreSQL 8085
Notification Service Email, SMS, push notifications Spring Boot + MongoDB + Kafka 8086
Search Service Product search, filters, ranking Spring Boot + Elasticsearch 8087
API Gateway Routing, auth filter, rate limiting Spring Cloud Gateway 8080
Microservices Architecture Diagram
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■ ■ CLIENT (Browser / Mobile) ■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■ HTTPS ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■▼■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■ API GATEWAY (Spring Cloud
Gateway :8080) ■ ■ Auth Filter ■ Rate Limiter ■ Load Balancer ■ Router ■ ■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■ ■ ■ ■ ■
■ ▼ ▼ ▼ ▼ ▼ ▼ ■■■■■■■■■■ ■■■■■■■■■■ ■■■■■■■■■■ ■■■■■■■■■■■■ ■■■■■■■■■■■■■
■■■■■■■■■■■■ ■ User ■ ■Product ■ ■ Order ■ ■ Payment ■ ■Inventory ■ ■ Search ■ ■Service
■ ■Service ■ ■Service ■ ■ Service ■ ■ Service ■ ■ Service ■ ■ :8081 ■ ■ :8082 ■ ■ :8083 ■
■ :8084 ■ ■ :8085 ■ ■ :8087 ■ ■ PgSQL ■ ■MongoDB ■ ■ PgSQL ■ ■ PgSQL ■ ■ PgSQL ■ ■
ElasticS■ ■■■■■■■■■■ ■■■■■■■■■■ ■■■■■■■■■■ ■■■■■■■■■■■■ ■■■■■■■■■■■■■
■■■■■■■■■■■■ ■ ■ ■ ■ ■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■ ■■■■■■■■■■■■■■■▼■■■■■■■■■■■■■■■■■■■ ■ KAFKA (Event Bus) ■ ■ OrderPlaced ■
PaymentDone ■ ■ StockUpdated ■ UserRegistered ■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■ ■■■■■■■■■■▼■■■■■■■■■■■ ■ Notification Svc ■ ■ :8086 ■ ■■■■■■■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■ ■ Eureka Server■ ■Config
Server ■ ■ Zipkin ■ ■ (Discovery) ■ ■ (git-backed)■ ■ (Tracing) ■ ■■■■■■■■■■■■■■■■
■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■
Confidential – Interview Preparation Document Page 6
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
6. TECH STACK DEEP DIVE
Core Services
Technology Purpose / Usage
Java 17 LTS version, records, sealed classes, text blocks
Spring Boot 3.2 Auto-configuration, actuator, native image support
Spring Data JPA Repository pattern, query methods, pagination
Spring Security + JWT Stateless auth, token validation at Gateway
Spring Cloud Components
Technology Purpose / Usage
Spring Cloud Gateway API Gateway, predicates, filters, rate limiting
Spring Cloud Netflix Eureka Service discovery and registration
Spring Cloud Config Centralized config, git-backed, refresh scope
Spring Cloud OpenFeign Declarative REST client for sync communication
Spring Cloud Sleuth + Zipkin Distributed tracing, correlation IDs
Resilience4j Circuit breaker, retry, rate limiter, bulkhead
Messaging & Data
Technology Purpose / Usage
Apache Kafka 3.x Async event-driven communication between services
PostgreSQL 15 Primary relational DB for User, Order, Payment
MongoDB 6 Product catalog and Notification logs
Redis Caching, session store, rate limiter state
Elasticsearch Full-text product search with filters
Infrastructure
Technology Purpose / Usage
Docker + Docker Compose Containerization, local dev environment
Kubernetes (EKS) Orchestration, auto-scaling, rolling deploys
Helm Charts Kubernetes package management
Jenkins + GitHub Actions CI/CD pipelines, automated testing
Prometheus + Grafana Metrics collection and dashboards
Confidential – Interview Preparation Document Page 7
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
7. REAL CHALLENGES FACED & HOW WE SOLVED
THEM
These are your STAR stories — use them confidently in interviews!
■ Challenge: Distributed Transaction Management (SAGA Pattern)
Problem: In monolith, creating an order was a single database transaction: reserve inventory + create order +
initiate payment — all in one ACID transaction. In microservices, these are 3 separate services with 3 separate
DBs. If Payment fails after Order is created, we need to rollback Order and release Inventory — but there's no
distributed ACID transaction.
Solution: Implemented SAGA Pattern using Choreography-based approach with Kafka. Each service
publishes events and listens for compensating events. Also implemented Outbox Pattern to ensure events are
published reliably (no dual-write problem).
// OrderService publishes event after saving @Transactional public Order
createOrder(OrderRequest req) { Order order = [Link](new Order(req)); //
Outbox pattern - save event in same transaction [Link](new
OutboxEvent("ORDER_CREATED", order)); return order; } // InventoryService listens and
reserves stock @KafkaListener(topics = "order-created") public void
onOrderCreated(OrderCreatedEvent event) { try {
[Link]([Link]()); [Link]("inventory-reserved",
new InventoryReservedEvent(event)); } catch (InsufficientStockException e) {
[Link]("inventory-failed", new InventoryFailedEvent(event)); } }
■ Challenge: Circuit Breaker – Cascading Failure Prevention
Problem: Product Service calls Inventory Service to show stock status on product page. During a network blip,
Inventory Service became slow (10s response). This caused Product Service threads to pile up waiting,
eventually making Product Service also fail — cascading failure across services.
Solution: Implemented Circuit Breaker using Resilience4j. When Inventory Service fails more than 50% of
requests in a 10-second window, circuit opens and returns cached/default data (fallback). After 30 seconds,
circuit enters half-open state to test recovery.
@CircuitBreaker(name = "inventoryService", fallbackMethod = "getDefaultStock")
@TimeLimiter(name = "inventoryService") public CompletableFuture getStockInfo(Long
productId) { return [Link](productId); } public CompletableFuture
getDefaultStock(Long productId, Exception ex) { [Link]("Inventory service down,
returning cached data for {}", productId); return [Link](
[Link]().productId(productId).available(true) .message("Stock info
temporarily unavailable").build() ); }
■ Challenge: Data Consistency – Shared Database Decomposition
Problem: In monolith, Order table had a FK to User table and Product table — all in same Oracle DB. When
we split into separate DBs, we lost referential integrity. An order could reference a deleted user or product.
Joins across services were impossible.
Confidential – Interview Preparation Document Page 8
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
Solution: Implemented Event Sourcing for critical data. Each service maintains its own read-model of data it
needs from other services. User Service publishes UserUpdated events; Order Service maintains a local
user_snapshot table updated via Kafka. No cross-service JOINs.
// Order Service maintains local User snapshot @KafkaListener(topics = "user-events")
public void handleUserEvent(UserEvent event) { [Link](
[Link]([Link](), [Link](), [Link]()) ); } // Order
can now get user info locally public OrderDetails getOrder(Long orderId) { Order order =
[Link](orderId).orElseThrow(); UserSnapshot user =
[Link]([Link]()); return [Link](order,
user); // No cross-service call needed }
■ Challenge: Service Discovery & Load Balancing
Problem: In monolith, services communicated via method calls. In microservices, services need to find each
other dynamically — IP addresses change when Kubernetes reschedules pods. Hardcoded URLs fail in
dynamic environments.
Solution: Used Eureka Server for service registration and discovery. Each service registers itself with a
service name. Spring Cloud LoadBalancer (replaced Ribbon) handles client-side load balancing. Feign clients
use service names, not IPs.
@FeignClient(name = "inventory-service") // Uses service name, not IP public interface
InventoryClient { @GetMapping("/api/inventory/{productId}") StockInfo
getStock(@PathVariable Long productId); } // In [Link] — service registers with
Eureka eureka: client: serviceUrl: defaultZone: [Link]
instance: preferIpAddress: true instanceId: ${[Link]}:${[Link]}
■ Challenge: Distributed Tracing – Debugging Across Services
Problem: A customer reported order checkout failing. In monolith, we'd look at one log file. In microservices, a
checkout flow touches Gateway → Order Service → Inventory Service → Payment Service → Notification
Service. Logs are spread across 5 different services. Finding the root cause took hours.
Solution: Implemented distributed tracing with Micrometer Tracing (replacing Sleuth) + Zipkin. Every request
gets a traceId that propagates across all service calls via HTTP headers. We can visualize the entire flow in
Zipkin UI and see exactly where latency/errors occur.
// Automatically injected by Spring Boot 3 + Micrometer // traceId and spanId are
auto-propagated in headers: X-B3-TraceId, X-B3-SpanId // In logs, you'll see: // INFO
[order-service,traceId=3d9f2a,spanId=8b4c1e] OrderController - Creating order // INFO
[inventory-service,traceId=3d9f2a,spanId=2f7a9c] InventoryService - Reserving stock #
[Link] management: tracing: sampling: probability: 1.0 # 100% sampling in dev
zipkin: tracing: endpoint: [Link]
■ Challenge: API Gateway – Authentication & Rate Limiting
Problem: With 8 services, we can't duplicate auth logic in every service. Also, during attack scenarios,
individual services were getting overwhelmed. We needed centralized security and traffic management.
Confidential – Interview Preparation Document Page 9
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
Solution: Spring Cloud Gateway acts as the single entry point. JWT validation happens at Gateway —
services receive user context via HTTP headers. Redis-based rate limiting applied globally (1000 req/min per
IP). Route predicates handle routing logic.
// Gateway filter for JWT validation @Component public class JwtAuthFilter implements
GatewayFilter { @Override public Mono filter(ServerWebExchange exchange,
GatewayFilterChain chain) { String token = [Link]().getHeaders()
.getFirst([Link]); if ([Link](token)) { Claims
claims = [Link](token); ServerHttpRequest mutated =
[Link]().mutate() .header("X-User-Id", [Link]())
.header("X-User-Role", [Link]("role", [Link])) .build(); return
[Link]([Link]().request(mutated).build()); } return onError(exchange,
[Link]); } }
Confidential – Interview Preparation Document Page 10
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
8. INTERVIEW Q&A; – BASIC TO ADVANCED
BASIC LEVEL QUESTIONS
■ Interviewer: What is a microservice?
■ You: A microservice is a small, independently deployable service that does one thing well (Single
Responsibility). It has its own database, is deployed independently, communicates via APIs or messaging,
and is owned by a small team. For example, our Payment Service only handles payment processing —
nothing else.
■ Interviewer: What is the difference between monolith and microservices?
■ You: In a monolith, all business logic is in a single deployable unit. One codebase, one DB, one
deployment. In microservices, each business capability is a separate service with its own DB. You deploy
independently. Monolith is simpler to start with but becomes painful at scale. Microservices give scalability
and team independence but add operational complexity.
■ Interviewer: What is Spring Boot and why use it for microservices?
■ You: Spring Boot is an opinionated framework that removes boilerplate configuration from Spring. It
provides auto-configuration, embedded servers (Tomcat/Netty), production-ready actuators, and starter
dependencies. For microservices, each service is a standalone Spring Boot app with embedded Tomcat —
no application server needed. We just run 'java -jar [Link]'.
INTERMEDIATE LEVEL QUESTIONS
■ Interviewer: How do services communicate in your architecture?
■ You: We use two patterns. Synchronous: REST via OpenFeign for real-time requests where the caller
needs an immediate response — like checking if a product exists before creating an order. Asynchronous:
Kafka for events that don't need immediate response — like sending a notification after payment is done.
Async gives us better decoupling and resilience.
■ Interviewer: How did you handle authentication across microservices?
■ You: Centralized JWT authentication at the API Gateway. When a user logs in, User Service issues a JWT
token signed with a secret key. For every request, the API Gateway validates the JWT using the same key —
if valid, it extracts userId and role, adds them as X-User-Id and X-User-Role headers, and forwards the
request. Downstream services trust these headers — they don't re-validate JWT, keeping services simple
and stateless.
■ Interviewer: What is the Saga Pattern? When did you use it?
Confidential – Interview Preparation Document Page 11
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
■ You: SAGA is a sequence of local transactions where each step publishes an event to trigger the next step.
If a step fails, compensating transactions undo previous steps. We used it for the order creation flow: (1)
Order Service creates order → publishes OrderCreated event. (2) Inventory Service reserves stock →
publishes StockReserved event. (3) Payment Service processes payment → publishes PaymentCompleted
event. If Payment fails, a compensating event releases the inventory reservation.
■ Interviewer: What is Circuit Breaker? Why is it important?
■ You: Circuit Breaker prevents cascading failures. When a downstream service is failing, instead of waiting
for timeout on every call — which blocks threads and degrades performance — the circuit opens and
immediately returns a fallback response. Three states: CLOSED (normal), OPEN (not calling downstream,
returning fallback), HALF-OPEN (testing if service recovered). We used Resilience4j. Saved us during an
Inventory Service outage — Product Service continued serving with 'stock info unavailable' instead of going
down.
ADVANCED LEVEL QUESTIONS
■ Interviewer: How did you handle the dual-write problem when publishing Kafka events?
■ You: Classic problem: you save to DB and then publish to Kafka — if Kafka publish fails, your DB has the
record but no event was published. Services downstream miss the event. Solution: Outbox Pattern. We save
the event to an 'outbox' table IN THE SAME DATABASE TRANSACTION as the business record. A separate
background process (using Debezium CDC or a scheduler) reads the outbox table and publishes to Kafka. If
the publish fails, the outbox record is retried. Transactional outbox guarantees at-least-once delivery.
■ Interviewer: How do you ensure idempotency in your microservices?
■ You: Critical for Kafka consumers — a message might be delivered twice. We make consumers
idempotent using an idempotency key. For Order Service processing PaymentCompleted: we check if the
orderId was already processed by storing processed event IDs in a Redis set with a TTL. If the event ID
already exists, we skip processing. For external APIs like Payment Gateway, we send a unique idempotency
key with each request — if retried, the gateway returns the same response without double-charging.
■ Interviewer: What challenges did you face with inter-service data consistency and how did you
solve it?
■ You: Without distributed transactions, eventual consistency is the reality. The challenge was that reads
across services showed stale data. Solution was CQRS + Event Sourcing for critical flows. Each service
maintains its own read-model populated via events. For non-critical data, we accepted eventual consistency
and communicated this in the UI — for example, search results might be 30 seconds behind the actual
catalog. For critical data like payment status, we used synchronous Feign calls to get real-time data.
■ Interviewer: How did you handle service versioning and backward compatibility?
■ You: We follow Semantic Versioning and never make breaking changes in the same major version. For
REST APIs, we version via URL: /api/v1/orders, /api/v2/orders. Old version stays active until all consumers
migrate. For Kafka events, we use Avro schemas with Schema Registry — schema evolution rules enforce
backward/forward compatibility. Field additions are allowed; field type changes are rejected at schema
registration time.
Confidential – Interview Preparation Document Page 12
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
■ Interviewer: How do you monitor your microservices in production?
■ You: Observability has three pillars: Metrics, Logs, and Traces. (1) Metrics: Micrometer + Prometheus
collects JVM metrics, HTTP request rates, error rates, Kafka lag. Grafana dashboards alert on anomalies. (2)
Logs: Structured JSON logging with Logback, shipped to ELK stack. All logs include traceId for correlation.
(3) Traces: Zipkin for distributed tracing. We set alerts on: error rate > 1%, P99 latency > 500ms, Kafka
consumer lag > 1000.
Confidential – Interview Preparation Document Page 13
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
9. SYSTEM DESIGN CONCEPTS
SAGA Pattern – Order Flow
ORDER CREATION SAGA (Choreography-based) OrderService InventoryService PaymentService
NotificationService ■ ■ ■ ■ ■■■save(order)■■■ DB ■ ■ ■ ■■■publish(ORDER_CREATED)■■■ Kafka
■ ■ ■ ■ ■ ■ ■ ■■■consume(ORDER_CREATED)■■ ■ ■ ■ reserve(stock)■■■ DB ■ ■ ■
publish(STOCK_RESERVED)■■■ Kafka ■ ■ ■ ■ ■ ■ ■ ■■■consume(STOCK_RESERVED)■■ ■ ■ ■
processPayment()■■■ DB ■ ■ ■ publish(PAYMENT_DONE)■■■ Kafka ■ ■ ■ ■ ■ ■
■■■consume(PAYMENT_DONE)■■ ■ ■ ■ updateStatus(CONFIRMED)■■■ DB ■ ■ ■ ■ ■
■■■consume(PAYMENT_DONE)■■ ■ ■ ■ sendEmail()■■■ SMTP ■ COMPENSATING TRANSACTION (Payment
Fails): ■ ■ ■ ■ ■ paymentFailed■■■ Kafka ■ ■■■consume(PAYMENT_FAILED)■■ ■
updateStatus(FAILED) ■ ■ publish(ORDER_FAILED)■■■ Kafka ■ ■■■consume(ORDER_FAILED)■■ ■
releaseStock()■■■ DB
Resilience4j Circuit Breaker States
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■■■■■ ■ CIRCUIT BREAKER STATE MACHINE ■ ■ ■ ■ ■■■■■■■■■■■ failure rate > 50%
■■■■■■■■■■■ ■ ■ ■ CLOSED ■ ■■■■■■■■■■■■■■■■■■■■■■ ■ OPEN ■ ■ ■ ■(Normal) ■ ■(No
calls■ ■ ■ ■■■■■■■■■■■ ■fallback)■ ■ ■ ▲ ■■■■■■■■■■■ ■ ■ ■ all probes succeed ■ wait
30 sec ■ ■ ■ ■■■■■■▼■■■■■■ ■ ■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ HALF-OPEN ■ ■ ■ ■
(probe 5 ■ ■ ■ ■ requests)■ ■ ■ ■■■■■■■■■■■■■ ■ ■ ■ ■ Config: slidingWindowSize=10,
failureRateThreshold=50, ■ ■ waitDurationInOpenState=30s, permittedCallsInHalfOpen=5 ■ ■■■■
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■■
Confidential – Interview Preparation Document Page 14
Monolith → Microservices | Java & Spring Boot Interview Guide Tech Stack: Java · Spring Boot · Spring Cloud
10. KEY METRICS & RESULTS
Before vs After Migration – Quantifiable Impact
Metric Before After Impact
Deployment Frequency Every 3 weeks Multiple times/day per service ■ 15x improvement
Build Time 45 minutes 3-5 min per service ■ 10x faster
Incident Recovery Time 2-4 hours 15-30 minutes ■ 8x faster MTTR
Infrastructure Cost 8 large VMs always Scale pods on demand ■ 40% cost reduction
Team Velocity Blocked on releases Teams deploy independently ■ 3x throughput
System Uptime 99.2% SLA 99.95% SLA ■ 0.75% improvement
Peak TPS 500 TPS (breaking) 3000+ TPS with auto-scale ■ 6x capacity
Key Interview Takeaways
■ Strangler Fig Pattern: Never do a big-bang rewrite. Migrate incrementally, service by service.
SAGA over 2PC: Distributed transactions with 2-phase commit are fragile. Use SAGA with
■ compensating transactions.
Outbox Pattern: Solves dual-write problem — always publish events as part of the same DB
■ transaction.
Circuit Breaker: Every synchronous call to another service MUST have a circuit breaker and
■ fallback.
■ Idempotency: All Kafka consumers and external API calls must be idempotent for safe retries.
■ Observability: You need metrics + logs + traces (the three pillars) from day one in microservices.
Team Structure: Conway's Law: your microservices architecture mirrors your team structure. One
■ team per service.
■ Database Per Service: Shared DB is an anti-pattern in microservices — it creates hidden coupling.
Pro Tip for Interviews: Always tie your technical decisions back to business impact. Don't just say 'we
used Kafka' — say 'we used Kafka because it let us decouple Order and Notification services, which
reduced Order Service latency by 200ms and let the Notification team deploy independently.'
Interviewers love business context with technical depth.
Confidential – Interview Preparation Document Page 15