Thư Viện Câu Hỏi Phỏng Vấn
Tổng hợp các câu hỏi tuyển dụng thực tế theo nhiều cấp độ từ Entry đến Expert để bạn tự tin chinh phục nhà tuyển dụng.
Khái niệm Bounded Context trong Domain-Driven Design (DDD) là gì và tại sao nó là ranh giới quan trọng khi chia nhỏ Monolith thành Microservices?
Product trong Context "Bán hàng" (Sales) sẽ chứa thông tin về giá, khuyến mãi. Nhưng trong Context "Vận chuyển" (Shipping), Product lại chỉ quan tâm tới kích thước, cân nặng.Định lý CAP là gì? Tại sao một hệ thống phân tán không thể đạt được đồng thời cả 3 yếu tố Consistency, Availability, và Partition Tolerance?
Định lý CAP chỉ ra rằng một hệ thống lưu trữ dữ liệu phân tán chỉ có thể chọn tối đa 2 trong số 3 yếu tố sau:
- Consistency (Tính nhất quán): Mọi node đều đọc được dữ liệu mới nhất cùng lúc.
- Availability (Tính sẵn sàng): Mọi request gửi đến hệ thống đều nhận được phản hồi thành công (không bị lỗi hoặc timeout) dù có node bị sập.
- Partition Tolerance (Tính chịu lỗi phân đoạn): Hệ thống vẫn hoạt động bình thường dù kết nối mạng giữa các node bị đứt quãng.
- Tại sao không thể chọn cả 3: Trên môi trường mạng thực tế, lỗi đường truyền là không thể tránh khỏi (bắt buộc phải có P). Khi xảy ra đứt kết nối giữa Node A và Node B:
- Nếu chọn C (Consistency): Để dữ liệu đồng bộ, Node A không được phép ghi dữ liệu mới khi chưa đồng bộ được sang Node B. Request ghi vào Node A sẽ bị từ chối hoặc treo -> Mất tính sẵn sàng (A).
- Nếu chọn A (Availability): Node A vẫn nhận ghi dữ liệu để đảm bảo hệ thống luôn sẵn sàng phản hồi. Nhưng lúc này dữ liệu trên Node B bị cũ lệch -> Mất tính nhất quán (C).
Sự khác biệt giữa Load Balancer hoạt động ở Layer 4 (Transport Layer) và Layer 7 (Application Layer) is gì?
/api/v1/users về service A, request /static/* về CDN/service B), hỗ trợ Sticky Sessions bằng Cookie và giải mã SSL (SSL Termination) trực tiếp.So sánh sự khác nhau về trường hợp sử dụng (Use Cases) của các loại cơ sở dữ liệu NoSQL: Document, Key-Value, Column-family, và Graph Databases?
Mỗi loại CSDL NoSQL được tối ưu hóa cho các cấu trúc dữ liệu và mô hình truy cập khác nhau:
- Document Databases (như MongoDB, CouchDB): Lưu trữ dữ liệu dưới dạng JSON/BSON. Thích hợp cho các ứng dụng có cấu trúc dữ liệu linh hoạt, thường xuyên thay đổi (ví dụ: Thông tin sản phẩm thương mại điện tử, hệ thống quản lý nội dung CMS, User Profiles).
- Key-Value Stores (như Redis, Memcached): Lưu dữ liệu dạng cặp Khóa - Giá trị đơn giản. Tốc độ đọc/ghi cực nhanh (vài mili giây). Thích hợp cho việc Caching, quản lý Session, đếm số lượt xem (counters), làm hàng đợi tin nhắn (Message Queues).
- Column-family Stores (như Cassandra, ScyllaDB): Lưu dữ liệu theo cột thay vì theo dòng. Khả năng ghi cực kỳ tối ưu và scale tuyến tính trên hàng trăm server. Thích hợp cho lưu trữ dữ liệu chuỗi thời gian (Time-series), Log hệ thống khổng lồ, dữ liệu IoT từ các cảm biến.
- Graph Databases (như Neo4j): Lưu dữ liệu dưới dạng các Đỉnh (Nodes) và Cạnh (Edges - thể hiện mối quan hệ). Tối ưu cho các truy vấn quan hệ nhiều tầng phức tạp. Thích hợp cho Mạng xã hội (Social Networks), Hệ thống gợi ý (Recommendation Engines), Phát hiện gian lận tài chính (Fraud Detection).
Lỗ hổng Race Condition là gì? Phân biệt cơ chế khóa lạc quan (Optimistic Locking) và khóa bi quan (Pessimistic Locking) khi xử lý bất đồng bộ?
Race Condition xảy ra khi nhiều tiến trình/luồng đồng thời đọc và ghi vào một tài nguyên dùng chung mà không được đồng bộ hóa, dẫn đến kết quả cuối cùng phụ thuộc vào thứ tự thực thi ngẫu nhiên của các luồng.
- Pessimistic Locking (Khóa bi quan): Giả định xung đột luôn xảy ra. Khi một luồng đọc dữ liệu, nó sẽ khóa ngay bản ghi đó lại (ví dụ:
SELECT ... FOR UPDATEtrong SQL). Các luồng khác muốn đọc/ghi bản ghi đó bắt buộc phải xếp hàng chờ cho đến khi khóa được giải phóng.- Ưu điểm: Đảm bảo tính nhất quán tuyệt đối, tránh hoàn toàn xung đột.
- Nhược điểm: Dễ gây nghẽn hệ thống (lock contention), giảm hiệu năng và có nguy cơ xảy ra Deadlock.
- Optimistic Locking (Khóa lạc quan): Giả định xung đột rất hiếm khi xảy ra. Khi đọc dữ liệu, không có khóa nào được thiết lập. Nhưng bản ghi sẽ lưu thêm một trường
versionhoặctimestamp. Khi ghi đè thay đổi, hệ thống kiểm tra xemversiontrong DB có còn giống lúc đọc hay không (UPDATE users SET balance = 50, version = version + 1 WHERE id = 1 AND version = 2). Nếu version đã thay đổi do luồng khác ghi trước đó, giao dịch sẽ bị từ chối và luồng hiện tại phải thử lại (retry).- Ưu điểm: Hiệu năng cực cao khi ít xung đột.
- Nhược điểm: Tốn tài nguyên CPU để retry nếu tần suất xung đột lớn.
Service Mesh (như Istio, Linkerd) là gì? Tại sao nó giải quyết tốt các bài toán về Service-to-Service Communication trong Kubernetes?
Service Mesh là một tầng cơ sở hạ tầng chuyên dụng, độc lập được thêm vào hệ thống để quản lý việc giao tiếp an toàn, tin cậy và nhanh chóng giữa các microservices.
- Cơ chế hoạt động (Sidecar Pattern): Service Mesh triển khai một proxy siêu nhẹ (như Envoy) chạy song song bên cạnh mỗi container ứng dụng (gọi là Sidecar Proxy). Mọi lưu lượng mạng đi vào và đi ra khỏi service đều được định tuyến qua sidecar này mà ứng dụng không hề hay biết.
- Các bài toán giải quyết được:
- Traffic Management: Cấu hình định tuyến thông minh, Canary Deployments, A/B Testing, tự động Retry khi lỗi, Circuit Breaking.
- Security: Tự động mã hóa toàn bộ dữ liệu truyền tải giữa các services bằng giao thức mTLS (mutual TLS) và quản lý chứng chỉ số mà không cần sửa đổi mã nguồn ứng dụng.
- Observability: Thu thập số liệu chi tiết (Metrics, Distributed Tracing, Logs) về hiệu năng mạng, tỷ lệ lỗi giữa các cuộc gọi dịch vụ một cách tập trung.
Phân biệt sự khác nhau giữa Sao chép đồng bộ (Synchronous Replication) và Sao chép bất đồng bộ (Asynchronous Replication) trong cơ sở dữ liệu?
Sao chép dữ liệu (Replication) giúp tăng tính sẵn sàng và khả năng chịu lỗi của hệ thống CSDL bằng cách nhân bản dữ liệu từ Node Chính (Leader/Master) sang các Node Phụ (Follower/Replica):
- Synchronous Replication (Sao chép đồng bộ): Khi Leader nhận được yêu cầu ghi, nó ghi dữ liệu cục bộ và gửi dữ liệu đó sang toàn bộ các Followers. Leader sẽ chờ cho đến khi tất cả Followers phản hồi đã ghi thành công rồi mới phản hồi commit thành công cho client.
- Ưu điểm: Nhất quán dữ liệu tuyệt đối (Zero Data Loss). Nếu Leader bị sập, các Followers chắc chắn chứa dữ liệu mới nhất để thay thế.
- Nhược điểm: Tốc độ ghi bị chậm (bằng tốc độ của Follower chậm nhất) và nếu một Follower bị mất mạng, toàn bộ hệ thống sẽ bị treo ghi.
- Asynchronous Replication (Sao chép bất đồng bộ): Leader ghi dữ liệu cục bộ và phản hồi commit thành công ngay lập tức cho client. Việc chuyển dữ liệu sang các Followers được thực hiện ngầm (bất đồng bộ) sau đó.
- Ưu điểm: Tốc độ ghi cực nhanh, hệ thống vẫn hoạt động bình thường kể cả khi các Followers bị mất kết nối.
- Nhược điểm: Có nguy cơ mất dữ liệu (Data Loss) nếu Leader bị sập đột ngột trước khi kịp đồng bộ các thay đổi mới sang Followers.
Hãy giải thích thuật toán Token Bucket và Leaky Bucket dùng trong thiết kế hệ thống giới hạn tần suất yêu cầu (Rate Limiting)?
Cả hai đều là thuật toán kinh điển dùng để giới hạn số lượng request gửi lên hệ thống để chống tấn công DDoS và quá tải:
- Token Bucket (Thùng chứa Token):
- Cơ chế: Có một thùng chứa có dung lượng tối đa là B tokens. Các tokens được thêm vào thùng một cách tuần tự theo tỷ lệ r cố định mỗi giây. Khi một request gửi đến, nó cần tiêu thụ 1 token để được xử lý. Nếu thùng hết token, request bị từ chối.
- Đặc điểm: Cho phép xử lý các đợt lưu lượng truy cập tăng đột biến (burst of traffic) miễn là trong thùng vẫn còn đủ token dự trữ.
- Leaky Bucket (Thùng rò rỉ):
- Cơ chế: Có một thùng chứa nước có dung lượng tối đa là B (tượng trưng cho hàng đợi request). Các request đến giống như nước đổ vào thùng. Đáy thùng có một lỗ nhỏ rò rỉ nước ra ngoài với tốc độ r cố định không đổi để xử lý. Nếu thùng đầy nước, request mới sẽ bị tràn ra ngoài (bị từ chối).
- Đặc điểm: Khống chế tốc độ xử lý đầu ra luôn ở mức ổn định, mượt mà (smooth rate) bất kể tốc độ đầu vào có tăng đột biến như thế nào.
Mẫu thiết kế CQRS (Command Query Responsibility Segregation) kết hợp Event Sourcing hoạt động như thế nào? Ưu và nhược điểm là gì?
Hãy giải thích các chiến lược thu hồi bộ nhớ đệm (Cache Eviction Policies) phổ biến như LRU (Least Recently Used) và LFU (Least Frequently Used)?
Khi bộ nhớ đệm (Cache) bị đầy, hệ thống cần giải phóng không gian bằng cách loại bỏ các key cũ theo các chiến lược nhất định:
- LRU (Least Recently Used - Ít được sử dụng gần đây nhất): Loại bỏ phần tử đã lâu không được truy cập. Cơ chế hoạt động dựa trên thứ tự thời gian của lần truy cập cuối cùng. Mỗi lần một key được truy cập, nó sẽ được đưa lên đầu danh sách. Khi đầy, phần tử ở cuối danh sách (cũ nhất) sẽ bị xóa. Phù hợp cho đa số trường hợp vì dữ liệu vừa được truy cập có khả năng cao sẽ được truy cập lại.
- LFU (Least Frequently Used - Ít được sử dụng thường xuyên nhất): Loại bỏ phần tử có tần suất (số lần) truy cập thấp nhất trong một khoảng thời gian. Cơ chế này đếm số lần truy cập của từng key. Khi đầy, key có bộ đếm nhỏ nhất bị xóa.
- Khác biệt: LRU tập trung vào tính chất thời gian (recency), trong khi LFU tập trung vào độ phổ biến (frequency). LFU có thể gặp vấn đề nếu một key được truy cập rất nhiều lần trong quá khứ nhưng hiện tại không dùng nữa, nó vẫn chiếm chỗ trong cache do bộ đếm tích lũy quá cao (có thể giải quyết bằng cách áp dụng cơ chế suy giảm - aging).
Khái niệm Circuit Breaker Pattern trong thiết kế hệ thống phân tán là gì? Giải thích 3 trạng thái Closed, Open và Half-Open?
Circuit Breaker (Bộ ngắt mạch) là mẫu thiết kế ngăn chặn một service liên tục gửi request đến một service khác đang bị lỗi hoặc quá tải, giúp bảo vệ tài nguyên hệ thống không bị cạn kiệt (như nghẽn luồng) và ngăn sập dây chuyền (Cascading Failure).
- 3 Trạng thái hoạt động:
- Closed (Đóng): Trạng thái bình thường. Mọi request đều được cho phép đi qua. Circuit Breaker sẽ theo dõi tỷ lệ lỗi của các phản hồi. Nếu tỷ lệ lỗi vượt quá ngưỡng cấu hình (ví dụ: 50% request thất bại), nó sẽ chuyển sang trạng thái Open.
- Open (Mở): Trạng thái ngắt mạch. Mọi request gửi đến sẽ bị chặn ngay lập tức và trả về lỗi giả lập (fallback error/timeout) mà không cần gọi đến service đích, giúp service đích có thời gian phục hồi.
- Half-Open (Nửa mở): Sau một khoảng thời gian chờ cấu hình sẵn ở trạng thái Open, Circuit Breaker sẽ tự động chuyển sang Half-Open. Nó cho phép một số lượng nhỏ request thử nghiệm đi qua. Nếu các request này thành công 100%, hệ thống coi như đã phục hồi và chuyển lại về Closed. Nếu có bất kỳ request nào thất bại, nó lập tức quay về trạng thái Open.
Hãy giải thích tính chất nhất quán cuối cùng (Eventual Consistency) và sự khác biệt so với nhất quán mạnh (Strong Consistency)?
- Đặc điểm: Rần dễ lập trình, nhưng tốn nhiều thời gian xử lý và làm giảm tính sẵn sàng (Availability) khi có lỗi mạng.
- Đặc điểm: Tốc độ ghi cực nhanh, tính sẵn sàng cao. Thích hợp cho các hệ thống quy mô lớn như mạng xã hội (số lượt thích, bình luận hiển thị lệch vài giây không ảnh hưởng đến trải nghiệm người dùng).
SOA (Service-Oriented Architecture) là gì? So sánh sự khác nhau giữa kiến trúc SOA và kiến trúc Microservices?
SOA là kiến trúc hướng dịch vụ, chia hệ thống thành các dịch vụ độc lập giao tiếp với nhau qua mạng. Microservices được coi là sự tiến hóa và tối giản hóa của SOA:
- Phạm vi & Chia nhỏ: SOA tập trung vào việc tích hợp các ứng dụng doanh nghiệp lớn khác nhau (Enterprise Application Integration). Microservices tập trung vào việc chia nhỏ một ứng dụng đơn lẻ thành các dịch vụ siêu nhỏ hoạt động độc lập.
- Giao tiếp: SOA sử dụng một trục tích hợp dịch vụ trung tâm lớn (Enterprise Service Bus - ESB) chứa nhiều logic chuyển đổi định dạng phức tạp (như SOAP/XML). Microservices sử dụng cơ chế giao tiếp đơn giản, gọn nhẹ (như RESTful API / JSON, gRPC, Message Broker).
- Quản lý dữ liệu: Trong SOA, các dịch vụ có thể chia sẻ chung một cơ sở dữ liệu lớn. Trong Microservices, mỗi dịch vụ bắt buộc phải sở hữu cơ sở dữ liệu riêng của nó (Database-per-Service) để đảm bảo tính cô lập hoàn toàn.
Enterprise Service Bus (ESB) đóng vai trò gì trong kiến trúc SOA truyền thống và tại sao nó bị loại bỏ trong Microservices?
Trong kiến trúc SOA, ESB hoạt động như một hệ thống bưu điện trung tâm trung chuyển và điều phối toàn bộ thông tin liên lạc giữa các dịch vụ:
- Vai trò của ESB: Chuyển đổi định dạng dữ liệu (ví dụ: XML sang JSON), chuyển đổi giao thức (HTTP sang JMS), định tuyến tin nhắn thông minh và quản lý các giao dịch phức tạp.
- Lý do bị loại bỏ trong Microservices:
- Quá nhiều Business Logic tập trung: ESB vi phạm nguyên tắc "Smart endpoints and dumb pipes" (Điểm cuối thông minh, đường ống ngu ngốc). Việc đưa quá nhiều logic vào ESB biến nó thành một khối Monolith mới, khiến việc nâng cấp, thay đổi một dịch vụ đòi hỏi phải cấu hình lại ESB, gây chậm trễ.
- Single Point of Failure: ESB bị sập sẽ làm toàn bộ hệ thống tê liệt.
- Microservices thay thế bằng API Gateway (chỉ làm nhiệm vụ routing, rate limiting, authentication đơn giản) và để các dịch vụ tự xử lý dữ liệu của chúng.
Cơ chế vô hiệu hóa cache (Cache Invalidation) trong CDN hoạt động như thế nào? Phân biệt giữa Purge và Ban?
Khi dữ liệu tĩnh trên server gốc thay đổi trước khi thời gian hết hạn (TTL) của CDN kết thúc, ta cần vô hiệu hóa cache cũ tại các Edge Servers để người dùng nhận được file mới:
- Purge (Xóa): CDN sẽ xóa bỏ hoàn toàn file cũ khỏi bộ nhớ đệm của Edge Server ngay lập tức. Lần request tiếp theo của người dùng sẽ là Cache Miss, CDN phải quay lại server gốc kéo file mới về. Thích hợp khi biết chính xác URL của file vừa thay đổi.
- Ban (Cấm/Gắn thẻ): Thay vì xóa vật lý, CDN đánh dấu (invalidate) file cũ dựa trên các tiêu chí hoặc biểu thức chính quy (Regex) hoặc HTTP Tags (Cache-Tags). Khi người dùng request, CDN gửi một request gọn nhẹ (HEAD) kèm theo điều kiện (
If-Modified-Since) về server gốc để kiểm tra xem file thực sự đổi chưa. Nếu có, CDN mới kéo file mới về; nếu chưa, nó tiếp tục dùng file cũ. - So sánh: Purge nhanh và triệt để hơn nhưng có thể tạo tải đột biến (thực hiện kéo lại file lớn) lên server gốc. Ban linh hoạt hơn, cho phép xóa hàng loạt file có chung tiền tố.



.png)
.png)