Dành riêng cho Architect, System Design và Distributed Specialist. Câu hỏi scenario-based từ dự án thực tế.
1. Clean Architecture & CQRS
Câu hỏi lý thuyết
- [Senior] Clean Architecture tách biệt Domain ở giữa. Sự khác biệt giữa DTO, Entity, và ViewModels? Tại sao Validation phải chia thành 2 lớp (Application vs Domain)?
- [Architect] MediatR CQRS: điểm bất cập khi lạm dụng Publisher sinh quá nhiều Subscriber? Thiết kế nào bù đắp khi hệ thống phình to?
- [Architect] "Anemic Domain Model" là gì? Tại sao Entity có toàn
{ get; set; }public lại phá vỡ Encapsulation của DDD?
🎯 Use Case 1: Thiết Kế Order Processing từ Đầu
Bạn được giao setup project Order Management System cho công ty logistics. Requirements:
- 50 API endpoints
- 15 entities, business rules phức tạp (pricing rules, validation, state machine)
- Team 8 devs, cần onboard nhanh
- Tương lai sẽ tách microservices
- [Architect] Bạn chọn Clean Architecture, Vertical Slice, hay Modular Monolith? Justify bằng trade-offs cụ thể.
- [Architect] Nếu chọn Clean Architecture, làm sao tránh nó thành "Folder Architecture" (đúng cấu trúc nhưng logic vẫn nằm hết trong Application layer, Domain rỗng)?
- [Senior] MediatR Pipeline Behaviors: bạn sẽ đặt Validation, Logging, Transaction ở behavior nào? Thứ tự register matters không?
🎯 Use Case 2: CQRS Read/Write Split cho Report System
Hệ thống e-commerce:
- Write path: đặt hàng, cập nhật kho - cần domain validation, ACID
- Read path: dashboard báo cáo doanh thu - cần query phức tạp với JOIN 8 bảng, aggregate
- [Architect] Bạn có cần tách Read DB riêng (SQL Read Replica) hay Query trên cùng DB đủ?
- [Architect] Projection/Denormalization: bạn viết materialized view hay dùng background worker build read model? Tradeoffs data staleness vs complexity?
2. Microservices & Distributed Consistency
Câu hỏi lý thuyết
- [Senior] CAP Theorem: tại sao Microservices luôn phải chọn P, nên bài toán thực chất chỉ còn đánh đổi C vs A?
- [Architect] Idempotency: implement cơ chế chống Double-Charge khi Client retries 1 POST request 3 lần vì rớt mạng?
🎯 Use Case 3: Overselling - Tình Huống Kinh Hoàng E-Commerce
Order Service xử lý 5,000 đơn/phút, publish event sang Inventory Service. Inventory Service sập 1 giờ. Khi phục hồi, xử lý tồn đọng → phát hiện hàng bị âm kho (Overselling 200 sản phẩm).
- [Architect] Root cause: Event-Driven mà không reserve stock trước? Hay Inventory check at order time nhưng eventual consistency gap?
- [Architect] Giải pháp thiết kế: Saga with reservation step? Two-Phase approach? Hay "Accept order, compensate later"?
- [Architect] Nếu dùng Saga, compensation flow khi Inventory reject: notify user? Refund? Auto-cancel? Business decision matrix?
🎯 Use Case 4: Payment Double-Charge
User click "Pay" → server gọi Stripe API charge $100 → response timeout → User click "Pay" lần 2 → charge $100 lần 2.
- [Senior] Thiết kế Idempotency Key: client-generated hay server-generated? Lưu ở đâu (Redis TTL hay DB)?
- [Architect] Stripe đã charge lần 1 thành công nhưng response timeout. Server không biết kết quả. Bạn xử lý "unknown state" thế nào? (Reconciliation pattern)
🎯 Use Case 5: Service-to-Service Communication Decision
Bạn có 4 services: Order, Payment, Inventory, Notification. Cần giao tiếp.
- [Architect] Vẽ communication map: cặp nào dùng sync (REST/gRPC), cặp nào dùng async (events)?
- [Architect] Order → Payment CẦN biết kết quả ngay (đồng bộ). Order → Notification KHÔNG cần response. Order → Inventory cần response nhưng CÓ THỂ đợi. Design pattern cho từng cặp?
3. Communication & Saga
Câu hỏi lý thuyết
- [Senior] Khác biệt API Gateway (YARP/Ocelot) vs Service Mesh (Dapr/Istio). gRPC so với REST API httpClient?
- [Architect] Choreography vs Orchestration Saga. Tại sao Choreography thành "Nồi mỳ ý" khi chuỗi business kéo dài đến 5 Services?
- [Architect] Outbox Pattern: vì sao
SaveChangesAsync()rồiPublish(event)có rủi ro dual-write?
🎯 Use Case 6: Booking System - 5-Step Saga
Flight booking cần:
-
Reserve Seat → 2. Charge Payment → 3. Issue Ticket → 4. Send Email → 5. Update Loyalty Points
-
[Architect] Step 3 (Issue Ticket) fail. Compensation: unreserve seat + refund payment. Nhưng refund API cũng có thể fail. Nested compensation xử lý thế nào?
-
[Architect] Timeout: Step 2 (Payment) không response sau 30 giây. Bạn auto-cancel hay retry? Nếu payment đã charge nhưng response lost?
🎯 Use Case 7: Event Storm - Debug Production
Production: Order Created event publish 1 lần, nhưng Email Service gửi 3 emails cho cùng 1 order.
- [Senior] Nguyên nhân: message retry? Duplicate publish? Consumer không idempotent?
- [Architect] Thiết kế idempotent consumer: dedup table (MessageId), hoặc check "email already sent for OrderId"? Trade-offs?
⚠️ Anti-Patterns - Architecture & Distributed
| # | Anti-Pattern | Tại sao nguy hiểm |
|---|---|---|
| 1 | Distributed Monolith - Microservices nhưng mọi service phải deploy cùng lúc, share DB | Worst of both worlds: complexity of microservices + coupling of monolith |
| 2 | Synchronous chain - A calls B calls C calls D synchronously | Latency = sum(all services). 1 service down → cascade failure |
| 3 | No circuit breaker - Retry vô hạn khi downstream service down | Amplify failure → thread exhaustion → cascade crash |
| 4 | Shared database giữa services - 2 services CRUD trên cùng bảng | Coupling: đổi schema bảng → cả 2 services deploy lại |
| 5 | Event without schema versioning - Thay đổi event payload → consumer cũ crash | Breaking change. Cần event versioning (v1, v2) hoặc schema registry |
| 6 | Saga without compensation - Happy path OK nhưng không code rollback | Partial failure → data inconsistency, ghost orders |
| 7 | Choreography spaghetti - 8 services pub/sub events lẫn nhau, không ai biết full flow | Không trace được business flow. Debug = nightmare |
| 8 | Publish event NGOÀI transaction - SaveChanges OK nhưng Publish fail → lost event | Dual-write problem. Dùng Outbox pattern |
| 9 | Không idempotent consumer - Process same message 2x → duplicate side effects | Message brokers guarantee at-least-once, NOT exactly-once |
| 10 | Over-engineering: Microservices cho 3 devs - Split 5 services cho startup team nhỏ | Operational overhead >> benefit. Start with modular monolith |
👉 Xem đáp án chi tiết tại: Answers/ans-03-architecture.md