Luyện Phỏng Vấn IT — 2000+ Câu Hỏi Phỏng Vấn IT Có Đáp Án 2026

Danh mục

MongoDB iconMongoDB

MongoDB là document database lưu dữ liệu dạng BSON document trong collections. Nó phù hợp khi domain có cấu trúc document tự nhiên, schema thay đổi nhanh, cần scale ngang, hoặc dữ liệu thường được đọc/ghi theo aggregate document.

Không nên chọn MongoDB chỉ để né schema design. Nếu dữ liệu có quan hệ chặt, cần join phức tạp, transaction nhiều bảng và constraint mạnh, PostgreSQL có thể phù hợp hơn.

Document là đơn vị dữ liệu dạng BSON tương tự JSON object. Collection là nhóm documents, tương tự bảng nhưng không bắt buộc mọi document có cùng shape. Database là namespace chứa nhiều collections.

Dù MongoDB linh hoạt schema, production vẫn cần quy ước schema rõ ràng ở app hoặc bằng JSON Schema validation để tránh dữ liệu bẩn và khó query về sau.

BSON là binary serialization format MongoDB dùng để lưu documents. Nó hỗ trợ thêm types như ObjectId, Date, Decimal128, binary, int32/int64 và nested structures. JSON là text format phổ biến để trao đổi dữ liệu.

Điểm phỏng vấn quan trọng: MongoDB document không chỉ là JSON text. Type mismatch giữa string date và Date, number precision, ObjectId string và ObjectId thật có thể làm query/index không hoạt động như mong muốn.

Các thao tác CRUD cơ bản làm việc với collection: findOne lấy một document, find trả cursor, insertOne thêm document, updateOne cập nhật document match đầu tiên.

Ví dụ:

javascript
await users.insertOne({ email: "a@example.com", name: "Ada" })
await users.updateOne({ email: "a@example.com" }, { $set: { name: "Ada Lovelace" } })
const user = await users.findOne({ email: "a@example.com" })

Cần luôn hiểu filter nào đang dùng index, nếu không collection scan sẽ làm chậm khi dữ liệu lớn.

Index giúp query tìm document nhanh hơn và hỗ trợ sort. Trade-off là tốn disk/RAM và làm write chậm hơn vì insert/update/delete phải cập nhật index.

Ví dụ:

javascript
db.users.createIndex({ email: 1 }, { unique: true })

Không index mọi field.

Hãy dựa vào query shape thật, selectivity, sort pattern và explain("executionStats").

Multikey index được tạo khi index field chứa array. MongoDB index từng element trong array, giúp query match element nhanh hơn.

Ví dụ:

javascript
db.posts.createIndex({ tags: 1 })
db.posts.find({ tags: "mongodb" })

Cần cẩn thận với compound multikey indexes vì array nhiều chiều hoặc nhiều array fields có thể tạo index entries lớn, ảnh hưởng write performance và storage.

ObjectId là kiểu dữ liệu thường dùng cho field _id mặc định trong MongoDB. Nó có kích thước 12 bytes và được sinh sao cho gần như unique, có chứa phần timestamp nên có thể suy ra thời điểm tạo tương đối.

Không nên nhầm ObjectId("...") với string thường. Nếu app lưu id dạng string nhưng query bằng ObjectId hoặc ngược lại, query có thể không match và index cũng không hoạt động như mong muốn.

Projection giới hạn fields trả về, giảm network payload, memory và serialization cost. Nó cũng giúp tránh lộ fields nhạy cảm nếu dùng cẩn thận.

Ví dụ:

javascript
db.users.find({ active: true }, { email: 1, name: 1, _id: 0 })

Projection không thay thế authorization hay response schema ở app layer, nhưng là tối ưu quan trọng cho documents lớn.

Có. MongoDB hỗ trợ multi-document transactions, kể cả trên replica sets và sharded clusters. Nhưng transaction không nên là mặc định cho mọi workflow vì nó tăng overhead và complexity.

Dùng transaction khi cần atomicity qua nhiều documents/collections. Nếu có thể thiết kế aggregate sao cho invariant nằm trong một document, atomic single-document update thường đơn giản và hiệu quả hơn.

Replica set là nhóm mongod processes giữ cùng một dataset để cung cấp redundancy và high availability. Một primary nhận writes, secondaries replicate oplog và có thể phục vụ reads tùy read preference.

Khi primary fail, election chọn primary mới. App cần dùng connection string đúng replica set và xử lý retryable writes/reads vì failover có thể gây lỗi tạm thời.

Embed khi dữ liệu con thuộc aggregate cha, thường được đọc cùng nhau, kích thước bounded và không cần update độc lập nhiều. Reference khi dữ liệu lớn, quan hệ many-to-many, cần query độc lập, hoặc document có thể vượt size limit.

Ví dụ embed addresses trong user nếu số lượng nhỏ:

javascript
{
  _id: ObjectId("..."),
  email: "a@example.com",
  addresses: [{ city: "HCM", type: "shipping" }]
}

Thiết kế MongoDB nên dựa vào query pattern, không phải chuyển 1-1 từ ERD relational.

MongoDB có giới hạn kích thước document, nên array unbounded như comments, events, logs, transactions không nên embed vô hạn trong một document cha.

Nếu collection có thể tăng không giới hạn, dùng reference hoặc bucket pattern. Ví dụ order có line items bounded có thể embed, nhưng user có hàng triệu events thì events nên là collection riêng, có index theo userIdcreatedAt.

Compound index order phụ thuộc query shape. Quy tắc thực tế thường là equality fields trước, sort fields tiếp theo, range fields sau cùng. Index { tenantId: 1, status: 1, createdAt: -1 } tốt cho query lọc tenant/status và sort createdAt.

Ví dụ:

javascript
db.orders.createIndex({ tenantId: 1, status: 1, createdAt: -1 })

Không có một thứ tự đúng cho mọi query.

Nếu query khác nhau nhiều, cần cân nhắc index riêng hoặc đổi access pattern.

TTL index tự động xóa documents sau một thời gian dựa trên date field. Nó phù hợp cho session, token, temporary verification, logs ngắn hạn hoặc cache documents.

Ví dụ:

javascript
db.sessions.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 })

TTL deletion không realtime tuyệt đối; background process chạy định kỳ.

Không dùng TTL nếu cần xóa đúng chính xác từng giây cho business critical workflow.

Aggregation pipeline xử lý data qua nhiều stages như $match, $group, $project, $sort, $lookup, $unwind. Nó phù hợp reporting, transformation, analytics nhẹ và server-side data shaping.

Ví dụ tính revenue theo ngày:

javascript
db.orders.aggregate([
  { $match: { status: "paid" } },
  { $group: { _id: "$day", revenue: { $sum: "$total" } } },
  { $sort: { _id: 1 } }
])

Đặt $match sớm để giảm dữ liệu đi qua pipeline và tận dụng index.

$lookup join documents giữa collections trong aggregation. Nó hữu ích nhưng không nên biến MongoDB thành relational database. Nếu query thường xuyên cần join sâu/nhiều collection, schema có thể đang sai cho MongoDB.

Dùng $lookup cho lookup có kiểm soát, data nhỏ hoặc admin/reporting. Với high-traffic read path, cân nhắc embed, denormalize có kiểm soát, hoặc materialized view để tránh join đắt.

MongoDB đảm bảo atomicity ở mức một document. Các update operators như $set, $inc, $push, $addToSet giúp cập nhật field/array mà không read-modify-write ở app.

Ví dụ tăng counter an toàn:

javascript
db.products.updateOne(
  { _id: productId, stock: { $gt: 0 } },
  { $inc: { stock: -1 } }
)

Nếu invariant nằm trong một document, thiết kế document đúng có thể tránh transaction phức tạp.

Read concern quyết định mức consistency/visibility của reads. Write concern quyết định mức acknowledgement/durability của writes, ví dụ majority yêu cầu đa số replica xác nhận.

Trade-off: concern càng mạnh thì consistency/durability tốt hơn nhưng latency có thể cao hơn. Với dữ liệu quan trọng như payment/order, thường cần write concern majority; với analytics/event không critical, có thể chọn nhẹ hơn tùy rủi ro.

Sharding chia dữ liệu ngang qua nhiều shards để scale storage và throughput. MongoDB route query qua shard key. Shard key quyết định data distribution và query routing.

Chọn shard key sai có thể gây hot shard, scatter-gather query hoặc chunk migration nhiều. Shard key tốt có cardinality cao, phân phối đều, ổn định và xuất hiện trong query pattern chính.

Denormalization copy một số data sang document khác để tối ưu read path và tránh join. Nó phù hợp khi data được đọc nhiều, thay đổi ít hoặc có thể chấp nhận eventual consistency.

Ví dụ order lưu snapshot customerName tại thời điểm mua. Khi customer đổi tên, order lịch sử có thể không cần update. Nhưng nếu data copy phải luôn đồng bộ, cần update strategy, event handler hoặc transaction, nếu không sẽ tạo inconsistency.

Bucket pattern gom nhiều measurements/events nhỏ vào một document bucket theo time range hoặc count, giảm số documents và index overhead. Nó phù hợp time-series, logs, sensor readings hoặc activity events.

Ví dụ bucket theo giờ cho device metrics. Cần giới hạn số entries mỗi bucket để tránh document quá lớn và thiết kế query theo bucket key như deviceId + hour.

Schema validation dùng JSON Schema để enforce shape/rules ở database level. Nó hữu ích khi nhiều services ghi cùng collection hoặc cần bảo vệ khỏi dữ liệu bẩn ngoài app validation.

Ví dụ:

javascript
db.createCollection("users", {
  validator: { $jsonSchema: { required: ["email"], properties: { email: { bsonType: "string" } } } }
})

Validation không thay thế app-level DTO, nhưng là lớp phòng thủ tốt cho dữ liệu quan trọng.

explain("executionStats") cho biết query dùng index nào, docs/keys examined, docs returned, stage tree và thời gian thực thi. Mục tiêu là keys/docs examined gần với số docs returned, không phải scan quá rộng.

Ví dụ:

javascript
db.orders.find({ tenantId: "t1", status: "paid" }).explain("executionStats")

Nếu thấy COLLSCAN, docs examined rất lớn hoặc sort in memory, cần xem lại index/query shape/projection.

MongoDB driver duy trì connection pool. App nên tạo một client singleton per process và reuse, không tạo client mới mỗi request. Tạo client liên tục gây connection storm và latency cao.

Cần cấu hình pool size theo số app replicas, workload và cluster capacity. Tổng connections = replicas x pool size, nên nếu scale Kubernetes replicas mà không giảm pool size, database có thể bị quá tải.

Backup cần nhất quán với replica set/sharded cluster và phải được test restore. Với Atlas có managed backups/PITR; self-managed thường dùng filesystem snapshots, mongodump cho logical backup nhỏ hơn hoặc ops tooling chuyên dụng.

Cần xác định RPO/RTO, mã hóa backup, lưu ngoài cluster, test restore định kỳ và runbook failover. Backup không test restore thì chỉ là giả định.

Oplog là capped collection đặc biệt ghi lại các thay đổi trên primary để secondaries replicate theo thứ tự. Nó là nền tảng cho replication và cũng liên quan tới change streams.

Nếu secondary lag quá xa và oplog đã xoay mất phần nó cần, node có thể phải resync. Vì vậy production cần monitor replication lag, oplog window và write volume, đặc biệt khi có batch writes lớn hoặc secondary bị down lâu.

Production cần authentication bật, TLS, network allowlist/private network, least-privilege users, secrets manager, audit logs khi cần, backup encryption và không expose MongoDB trực tiếp ra internet.

Ở app layer, cần validate input, projection/response schema để tránh lộ field nhạy cảm, rate limit endpoints nguy hiểm và không log connection string chứa credentials.