Tổng hợp 104 câu hỏi phỏng vấn Backend Essentials kèm đáp án chi tiết, song ngữ Việt–Anh — sắp xếp từ cơ bản đến nâng cao. Ôn luyện miễn phí, tự động lưu tiến độ.
- Unit test: kiểm tra một đơn vị nhỏ (hàm, class) tách riêng, mock/stub dependency. Chạy trong mili-giây, fail chỉ đúng chỗ hỏng → dễ tìm nguyên nhân, viết nhiều nhất. - Integration test: kiểm tra nhiều thành phần ghép với nhau — code với…
DI là technique mà object nhận dependencies từ bên ngoài thay vì tự tạo — là cơ chế triển khai DIP. Ba loại DI: Framework DI: NestJS dùng IoC container với decorators @Injectable(), @Inject() — tự động resolve dependency tree. Trong Go không có framework…
RabbitMQ là message broker mã nguồn mở, cho phép các ứng dụng giao tiếp bất đồng bộ thông qua một broker trung gian thay vì gọi trực tiếp lẫn nhau. Dùng khi cần decouple các service, xử lý tác vụ nền như gửi email, resize…
Có 4 loại exchange chính: (1) Direct — định tuyến dựa trên exact match routingkey, dùng phân phối task đến worker cụ thể; (2) Fanout — broadcast mọi message đến tất cả queue đã bind bất kể routingkey, dùng cho notification; (3) Topic — định…
RabbitMQ không tự retry message bị lỗi — đó là nhiệm vụ của consumer. Các pattern phổ biến: (1) Nack + requeue: consumer bắt exception, gửi nack với requeue=true, message quay lại queue (cần cẩn thận để tránh loop vô hạn). (2) Dead-letter + retry:…
Merge: tạo merge commit, preserve history đầy đủ. git log --graph thấy nhánh. Non-destructive — không thay đổi existing commits. Rebase: replay commits lên trên branch khác, tạo linear history. Rewrite commit hashes. Golden Rule of Rebasing: KHÔNG BAO GIỜ rebase branch đã được share/push…
Worst case conflict: không phải thêm/xoá dòng đơn giản mà là structural refactor — function bị rename, logic được reorganize. Quy trình an toàn: 1. Hiểu context trước khi resolve: 2. Dùng 3-panel merge tool — git mergetool (trái: ours, phải: theirs, giữa: base —…
Reset (git reset --hard HEAD~1): di chuyển HEAD pointer về commit cũ, xoá commits khỏi history. KHÔNG dùng trên main/shared branch — sẽ cần force push, làm hỏng history của mọi người đã pull. Revert (git revert <commit): tạo commit MỚI undo changes của commit…
REST (Representational State Transfer) là kiểu kiến trúc cho API trên HTTP. Nguyên tắc chính: - Stateless: mỗi request tự chứa đủ thông tin; server không giữ trạng thái phiên giữa các request → dễ scale ngang. - Tài nguyên (resource) + URI: mỗi thực…
Một method idempotent khi gửi request đó một lần hay nhiều lần đều cho cùng một tác động lên server. - Idempotent: GET, HEAD, PUT, DELETE, OPTIONS. - KHÔNG idempotent: POST (mỗi lần thường tạo bản ghi mới), PATCH (tuỳ cách implement). Ý nghĩa thực…
Năm nhóm theo chữ số đầu: - 1xx Informational — request đã nhận, đang xử lý. - 2xx Success — thành công: 200 OK, 201 Created, 204 No Content. - 3xx Redirection — cần bước tiếp: 301 (chuyển vĩnh viễn), 304 Not Modified (cache). -…
Mục tiêu: thay đổi API mà không phá client cũ. Các cách: - URI versioning (/v1/users): rõ ràng, dễ cache/định tuyến — phổ biến nhất, nhưng lẫn version vào URL tài nguyên. - Query param (/users?version=1): đơn giản, nhưng dễ bị bỏ sót. - Header…
SQL (quan hệ): dữ liệu ở bảng, schema cố định, quan hệ qua khoá chính/ngoại, ACID đầy đủ, thường scale dọc. Hợp hệ giao dịch cần nhất quán mạnh và quan hệ dữ liệu chặt (tài chính, đơn hàng). NoSQL: nhiều loại — document (JSON),…
Index là cấu trúc dữ liệu riêng, có thứ tự (thường là B-tree) giữ bản sao cột được đánh index + con trỏ tới hàng. Nhờ có thứ tự, DB tìm bằng cách đi cây thay vì quét toàn bảng (full table scan) → tra…
Cache giữ dữ liệu hay dùng ở tầng nhanh (RAM, vd Redis) → giảm tải DB, tăng tốc đọc. Chiến lược đọc/ghi: - Cache-aside (lazy loading): app đọc cache trước; miss thì đọc DB rồi ghi vào cache. Phổ biến nhất; cache chỉ chứa dữ…
SQL injection xảy ra khi app ghép chuỗi input người dùng vào câu SQL → kẻ tấn công chèn lệnh SQL để lộ/sửa dữ liệu, thậm chí chiếm DB. Phòng chống (theo thứ tự hiệu quả — OWASP): 1. Prepared statement / parameterized query —…
- Authentication (xác thực): bạn là ai — kiểm danh tính (mật khẩu, OAuth, passkey). - Authorization (phân quyền): bạn được làm gì — kiểm quyền truy cập tài nguyên (RBAC, scope). Thứ tự: xác thực trước, phân quyền sau. Sai quyền → 403; chưa…
- REST: nhiều endpoint theo tài nguyên, thường trả JSON trên HTTP (không phụ thuộc phiên bản HTTP cụ thể). Đơn giản, cache HTTP tốt, phổ biến rộng rãi. Điểm yếu: hay over-fetch/under-fetch (trả dư hoặc thiếu field, phải gọi nhiều lần). - GraphQL: một…
Cả ba giải bài toán server đẩy dữ liệu về client mà không đợi client hỏi liên tục. - Long-polling: client gửi request, server giữ mở tới khi có dữ liệu rồi trả về; client lập tức gọi lại. Chạy trên HTTP thường, tương thích…
Webhook là cách hệ ngoài chủ động gọi tới URL của bạn khi có sự kiện, thay vì bạn phải liên tục hỏi (polling). Còn gọi là "reverse API" / "push callback" — vd SePay báo thanh toán thành công, GitHub báo có push. Khi…
Normalization: tổ chức dữ liệu để loại trùng lặp — tách thành nhiều bảng liên kết bằng khoá, mỗi dữ kiện lưu một chỗ (theo các dạng chuẩn 1NF/2NF/3NF). - Lợi: ghi/cập nhật gọn, tránh dữ liệu mâu thuẫn, tiết kiệm dung lượng. - Hại:…
ORM (Object-Relational Mapping) ánh xạ bảng DB ↔ object/class trong code, để thao tác dữ liệu bằng đối tượng thay vì viết SQL tay (vd Prisma, TypeORM, Hibernate, Drizzle). Ưu: - Viết nhanh, ít boilerplate, code gần với domain. - An toàn hơn: query được…
Reverse proxy (vd Nginx, HAProxy) đứng trước server, nhận request thay cho chúng và chuyển tiếp. Chức năng hạ tầng chung: TLS termination, load balancing, cache, nén, che giấu topology nội bộ. API gateway là một reverse proxy chuyên cho API, thêm các phần việc…
Stateless: server không giữ trạng thái phiên trong bộ nhớ giữa các request — mỗi request tự chứa đủ thông tin, hoặc trạng thái được đẩy ra kho ngoài dùng chung (DB, Redis, JWT phía client). Vì sao quan trọng cho horizontal scaling (thêm nhiều…
Health check: endpoint (vd /healthz) để load balancer/orchestrator (Kubernetes) biết instance có sống và sẵn sàng nhận traffic không. Hai loại thường phân biệt: - Liveness: process còn sống không? Fail → restart instance. - Readiness: đã sẵn sàng phục vụ chưa (đã nối DB,…
Observability là khả năng hiểu hệ đang xảy ra gì từ bên ngoài qua dữ liệu nó phát ra — để trả lời "cái gì hỏng, ở đâu, vì sao", nhất là trong hệ phân tán. Ba trụ cột: - Logs: bản ghi sự kiện…
Hashing khác encryption: encryption hai chiều (có khoá để giải mã lại). Hash một chiều — không thể đảo ngược. Mật khẩu phải hash, không encrypt: DB chỉ giữ hash, kể cả bị lộ cũng không lấy lại được mật khẩu gốc. Tuyệt đối không…
HTTPS = HTTP chạy trên TLS. TLS cho ba đảm bảo: mã hoá (nghe lén không đọc được), toàn vẹn (không sửa được giữa đường), xác thực (chắc đang kết nối tới đúng server qua chứng chỉ). Handshake (rút gọn) trước khi truyền dữ liệu:…
Trình duyệt áp same-origin policy: JS ở origin A mặc định không đọc được response từ origin B (khác scheme/host/port). CORS là cơ chế server cho phép có kiểm soát một số cross-origin request, bằng cách trả các header phản hồi. Đây là quyết định…
OWASP Top 10 là danh sách 10 nhóm rủi ro bảo mật web nghiêm trọng nhất, cập nhật định kỳ — dùng làm khung tối thiểu để rà soát ứng dụng. Vài mục cốt lõi: - Broken Access Control: kiểm quyền thiếu/sai → user thấy/sửa…
Transaction là một nhóm câu lệnh chạy như một đơn vị atomic — hoặc tất cả thành công, hoặc không gì cả. - BEGIN: mở transaction. - COMMIT: xác nhận; mọi thay đổi trở nên bền vững và thấy được với transaction khác. - ROLLBACK:…
Một topic Kafka được chia thành nhiều partition — mỗi partition là một log append-only, có thứ tự. Ghi/đọc song song trên nhiều partition là cách Kafka scale throughput. - Thứ tự chỉ đảm bảo trong một partition, không phải toàn topic. Message cùng key…
DLQ là một hàng đợi phụ chứa các message không xử lý được sau khi đã retry đủ số lần (sai định dạng, bug consumer, dữ liệu không hợp lệ...). Vì sao cần: - Tránh poison message làm kẹt hoặc lặp vô hạn cả hàng…
Cả hai là mô hình phân quyền (authorization): - RBAC (Role-Based): gán quyền theo vai trò (admin, editor, viewer); user nhận quyền qua role. Đơn giản, dễ hiểu và audit; hợp phần lớn ứng dụng. Nhược điểm: bùng nổ số role khi luật quá chi…
- Validation: kiểm input có hợp lệ không (kiểu, độ dài, khoảng giá trị, định dạng) và từ chối nếu sai. Ưu tiên allow-list (chỉ chấp nhận cái đúng) hơn deny-list (chặn cái xấu — dễ sót). - Sanitization: làm sạch/biến đổi input để an…
Cả hai giảm rủi ro khi release và tránh downtime: - Blue-green: chạy hai môi trường song song — "blue" (đang live) và "green" (bản mới). Test xong thì chuyển toàn bộ traffic sang green một lần; nếu lỗi thì switch ngược tức thì. Rollback…
Race condition xảy ra khi nhiều request/process truy cập cùng một tài nguyên đồng thời và kết quả phụ thuộc vào thứ tự thực thi. Ví dụ kinh điển: hai request cùng đọc số dư 100, cùng trừ 30 rồi ghi lại → cả hai…
- Blocking I/O: thread gọi thao tác I/O (đọc file, query DB, gọi HTTP) phải đứng chờ đến khi có kết quả — trong lúc đó không làm được việc khác. - Non-blocking I/O: lời gọi trả về ngay; kết quả được báo lại qua…
Bốn nguyên tắc chính: - Format nhất quán toàn API: mọi endpoint trả lỗi cùng một cấu trúc để client viết một handler dùng chung — không chỗ trả { error }, chỗ trả { message }. - Status code đúng ngữ nghĩa: 400 request…
Middleware là các hàm xếp thành pipeline giữa request và response: request đi qua từng middleware theo thứ tự, mỗi cái có thể đọc/sửa request-response, kết thúc sớm (trả response luôn), hoặc chuyển tiếp cho middleware kế (trong Express là gọi next()). Cùng ý tưởng…
- Máy ảo (VM): ảo hoá phần cứng qua hypervisor; mỗi VM chạy hệ điều hành khách đầy đủ riêng. Cô lập mạnh, nhưng nặng (hàng GB, khởi động chậm hàng chục giây). - Container: ảo hoá ở tầng hệ điều hành; các container dùng…
- Primary key (khoá chính): một hoặc nhiều cột định danh duy nhất mỗi hàng. Giá trị phải duy nhất và khác NULL; mỗi bảng có tối đa một primary key (thường tự tạo index B-tree cho nó). - Foreign key (khoá ngoại): cột trong…
CDN (Content Delivery Network) là mạng lưới server phân tán theo địa lý đặt gần người dùng, lưu bản sao cache của nội dung để phục vụ từ điểm gần nhất thay vì luôn phải về server gốc (origin). Lợi ích: - Giảm độ trễ:…
- Session (stateful): sau khi đăng nhập, server lưu dữ liệu phiên ở phía server (bộ nhớ/Redis/DB) và trả về một session id dạng opaque (chuỗi vô nghĩa, không chứa thông tin) trong cookie. Mỗi request server tra store để biết là ai. Ưu: thu…
Mở một kết nối DB tốn kém: bắt tay TCP, thiết lập TLS, xác thực, cấp phát tài nguyên phía server — mất mili-giây và tiêu tốn bộ nhớ mỗi kết nối. Nếu mỗi request mở rồi đóng kết nối riêng thì độ trễ và…
HTTP có sẵn cơ chế cache để trình duyệt/CDN/proxy tái dùng response cũ, giảm round-trip và tải origin. Hai lớp: - Freshness (còn tươi) — Cache-Control: - max-age=<giây: thời gian được coi là còn tươi, dùng thẳng từ cache không hỏi server. - no-cache: được…
CSRF (Cross-Site Request Forgery) lợi dụng việc trình duyệt tự động gửi cookie theo mọi request tới một site. Kẻ tấn công dụ user đã đăng nhập truy cập trang độc hại; trang đó âm thầm gửi request tới site nạn nhân (vd form chuyển…
- Đồng bộ (synchronous): client gửi request và chờ tới khi xong, nhận kết quả ngay trong response. Đơn giản, dễ suy luận, nhưng giữ tài nguyên (connection, thread) suốt thời gian xử lý và độ trễ = thời gian tác vụ. - Bất đồng…
Hai mô hình gửi message bất đồng bộ, khác nhau ở ai nhận message: - Message queue (point-to-point): mỗi message được đúng một consumer xử lý. Nhiều consumer cùng đọc một queue thì chia nhau việc (competing consumers) để tăng throughput, nhưng một message chỉ…
- HTTP/1.1: giao thức văn bản, mỗi kết nối TCP xử lý một request tại một thời điểm → head-of-line (HOL) blocking: request chậm chặn các request sau. Có keep-alive, nhưng trình duyệt phải mở nhiều kết nối song song (và dùng mẹo như domain…
- Scale dọc (scale up): làm một máy mạnh hơn — thêm CPU, RAM, ổ đĩa. Đơn giản, không cần đổi kiến trúc/code, tránh được độ phức tạp phân tán. Nhược: có trần phần cứng, giá tăng phi tuyến ở cấu hình cao, và vẫn…
- Continuous Integration (CI): lập trình viên merge thay đổi vào nhánh chính thường xuyên (ít nhất mỗi ngày); mỗi lần merge tự động build + chạy test. Mục tiêu: phát hiện xung đột/lỗi tích hợp sớm, khi còn nhỏ, thay vì gộp một cục…
Access token ngắn hạn (5–15 phút) gửi kèm Authorization: Bearer; refresh token dài hạn chỉ dùng để xin access mới. Lưu ở đâu: refresh token trong cookie httpOnly + Secure + SameSite (JS không đọc được → chống XSS đánh cắp); access token giữ in-memory…
Mục tiêu: chỉ chủ email thật mới đặt lại được mật khẩu, và không rò rỉ tài khoản nào tồn tại. Luồng: 1. User nhập email → luôn trả lời cùng một thông báo ("nếu email tồn tại, chúng tôi đã gửi link") bất kể…
Khác biệt gốc: session giữ trạng thái ở server (cookie chỉ mang session id, muốn thu hồi thì xoá bản ghi), còn JWT đẩy trạng thái vào token đã ký để mỗi service tự verify mà không gọi về auth service — đổi lại token…
Phối nhiều lớp, không dựa vào một biện pháp duy nhất: - Rate limit theo IP và theo tài khoản (vd tối đa N lần/phút). Khoá theo account chống việc đổi IP; khoá theo IP chống spray một IP nhiều account. - Exponential backoff: mỗi…
Mỗi chỗ đánh đổi giữa hai nguy cơ khác nhau — XSS và CSRF. - localStorage: JS đọc/ghi dễ, tiện gắn Authorization header (nên miễn nhiễm CSRF). Nhưng XSS đọc được → một script chèn vào là mất token. Không nên dùng cho token nhạy…
Đừng đẩy toàn bộ byte đi qua server ứng dụng — nó chiếm bộ nhớ/băng thông và giới hạn payload. Dùng direct-to-storage bằng presigned URL. Luồng presigned (S3): 1. Client gọi API xin quyền upload. Server xác thực + phân quyền, sinh presigned URL (chữ…
Tách lúc nhận ảnh khỏi lúc phục vụ ảnh. Nhận (upload): client upload ảnh gốc thẳng lên object storage bằng presigned URL (như câu file lớn). Kiểm tra type/size trước khi cấp URL. Xử lý (transform): hai hướng phổ biến — - Xử lý sẵn…
Ba hướng, mỗi hướng hợp một bối cảnh: - Object storage (S3/GCS/R2): lưu byte trên storage, chỉ giữ metadata + key/URL trong DB. Ưu: scale gần như vô hạn, rẻ, phục vụ qua CDN dễ, không gánh app server. Nhược: cần dịch vụ ngoài, nhất…
Không gửi inline trong request. SMTP/nhà cung cấp có thể chậm hoặc lỗi tạm thời; nếu chờ, response bị treo và nếu gửi lỗi thì cả request signup fail dù user đã tạo xong. Thiết kế: ghi user vào DB → đẩy một message vào…
Với bảng hàng triệu dòng, chốt cursor (keyset) cho API chính; offset chỉ giữ cho màn admin cần nhảy tới trang số N trên dữ liệu vừa phải. Truy vấn: mốc là giá trị dòng cuối trang trước, so sánh theo bộ (createdat, id). Thiếu…
Chốt cơ chế trước: client gửi kèm một idempotency key duy nhất cho mỗi ý định đặt hàng; lần đầu server tạo đơn rồi lưu kết quả theo key, gặp lại đúng key thì trả lại kết quả cũ thay vì tạo đơn mới. Cách…
Vấn đề: gom hết dữ liệu vào bộ nhớ rồi trả trong một HTTP request đồng bộ → tốn RAM, vượt timeout của proxy/gateway. Hai hướng: 1. Streaming response (dữ liệu vừa/lớn vừa): - Query theo lô (cursor/LIMIT), ghi từng chunk ra response stream, Transfer-Encoding:…
Bốn thuật toán thường gặp: fixed window (đếm theo mốc thời gian cố định — rẻ nhất nhưng cho lọt gấp đôi trần ở ranh giới hai cửa sổ), sliding window (mượt hơn, tốn bộ nhớ hơn), token bucket (nạp token đều, cho tiêu dồn…
Các loại JOIN (ví dụ users ↔ orders): - INNER JOIN: chỉ hàng khớp ở cả hai bảng — user có ít nhất một đơn. - LEFT JOIN: mọi hàng bảng trái + phần khớp bảng phải; không khớp → cột phải là NULL —…
- PUT = thay cả bản ghi: client phải gửi payload đầy đủ, field không gửi coi như bị xoá/reset (RFC 9110). - PATCH = sửa một phần: chỉ gửi field cần đổi (RFC 5789). Tính idempotent (gọi lại nhiều lần, trạng thái cuối không…
- Hard delete: DELETE thật — dữ liệu biến mất, bảng/index gọn, nhưng không khôi phục được và mất dấu vết. - Soft delete: chỉ đánh dấu đã xoá (cột deletedat timestamp, NULL = còn sống); mọi query đọc phải lọc WHERE deletedat IS NULL.…
Đi từ danh từ trong nghiệp vụ → bảng, rồi chốt quan hệ và ràng buộc. Bảng lõi cho đơn hàng: Những quyết định cần nói được: - Quan hệ n–n tách bảng nối: một đơn nhiều sản phẩm, một sản phẩm ở nhiều đơn…
N+1 xảy ra khi lấy một danh sách rồi lặp gọi thêm một truy vấn riêng cho từng phần tử: 1 query lấy N bản ghi cha + N query lấy dữ liệu con → N+1 lần vào DB. Thường gặp với ORM khi truy…
Redis là kho dữ liệu key–value in-memory (lưu chủ yếu trong RAM) → đọc/ghi cực nhanh (thường dưới 1ms). Điểm mạnh là nó không chỉ lưu chuỗi mà là "data structure server" với nhiều kiểu dữ liệu có sẵn: - String: giá trị đơn (cache…
Cả hai là giao thức tầng transport, nhưng đánh đổi khác nhau giữa độ tin cậy và tốc độ. - TCP — hướng kết nối, tin cậy: bắt tay 3 bước, đảm bảo đến nơi, đúng thứ tự, có kiểm soát lỗi, retransmit, flow control…
DNS (Domain Name System) là "danh bạ" của internet — dịch tên miền dễ nhớ (example.com) sang địa chỉ IP mà máy dùng để kết nối. Quá trình phân giải (đệ quy) khi truy cập một tên chưa cache: 1. Resolver (thường của ISP) nhận…
Load balancer chia traffic cho nhiều server để tránh quá tải và loại bỏ single point of failure. - L4 (transport): định tuyến theo IP/port, không đọc nội dung → nhanh, throughput cao, nhưng ít linh hoạt. - L7 (application): đọc HTTP (path, header, cookie)…
- Monolith: toàn bộ ứng dụng trong một codebase/deploy. Ưu: đơn giản, dễ dev/test/deploy lúc đầu, gọi hàm trong tiến trình rất nhanh, không có độ phức tạp phân tán. Nhược: khi lớn thì build/deploy chậm, coupling tăng, khó scale từng phần. - Microservices: chia…
Design pattern là giải pháp tái sử dụng cho các vấn đề thiết kế phần mềm hay lặp lại — không phải code copy-paste, mà là khuôn mẫu để tổ chức lớp/đối tượng. Lợi ích: có từ vựng chung (nói "Observer" là hiểu ngay), tránh…
Singleton đảm bảo một lớp chỉ có đúng một thể hiện (instance) trong toàn ứng dụng và cung cấp một điểm truy cập toàn cục tới nó. Thường dùng cho tài nguyên dùng chung: config, logger, connection pool, cache. Cách làm điển hình: constructor private…
Vấn đề: khi code tạo đối tượng bằng new ConcreteClass() rải rác, nó bị gắn chặt vào lớp cụ thể → muốn đổi/ thêm loại phải sửa nhiều nơi. - Factory Method: định nghĩa một phương thức tạo đối tượng, để lớp con quyết định…
Năm nguyên tắc thiết kế hướng đối tượng giúp code dễ bảo trì, mở rộng, ít coupling (Robert C. Martin tổng hợp): - S – Single Responsibility: mỗi lớp chỉ có một lý do để thay đổi (một trách nhiệm). - O – Open/Closed: mở…