10 câu hỏi có thể gặp khi phỏng vấn
Chọn theo kỹ năng và cấp của tin (Java, DevOps & CI/CD, System Design & Kiến trúc). Gợi ý trả lời do Drama Công Ty biên soạn để bạn ôn nhanh, không phải đề của công ty.
01So sánh
synchronized,volatile,ReentrantLockvàConcurrentHashMap. Bạn tránh race condition thế nào?Java · SeniorGợi ý trả lời
Ôn thêm câu hỏi Java →Race condition xảy ra khi nhiều thread đọc-sửa-ghi cùng dữ liệu mà không đồng bộ. Mỗi công cụ giải quyết một phần:
volatile: đảm bảo visibility (thread khác thấy giá trị mới nhất), nhưng không làmcount++thành atomic.synchronized: vừa loại trừ lẫn nhau vừa đảm bảo visibility (quan hệ happens-before).ReentrantLock: nhưsynchronizednhưng cótryLockvới timeout, lock có thể ngắt, nhiềuCondition.AtomicInteger/LongAdder: đếm không cần lock.ConcurrentHashMap: thread-safe với độ tranh chấp thấp. Dùngcompute/merge/putIfAbsentcho thao tác kép, đừnggetrồiput.
Hay sai: dùng
Collections.synchronizedMaprồi duyệt map mà không lock, hoặc kiểm traif (!map.containsKey(k)) map.put(k, v)trên map đồng thời: hai bước riêng lẻ vẫn bị chen ngang. Cách tốt nhất vẫn là giảm state dùng chung (object bất biến, mỗi thread một bản).02Một service Spring Boot trên production đột nhiên chậm, CPU cao hoặc bị OOM. Bạn điều tra thế nào?Java · Senior
Gợi ý trả lời
Ôn thêm câu hỏi Java →Đi từ số liệu đến bằng chứng, đừng đoán rồi sửa.
- Xem metrics (Actuator, Micrometer): latency, số request, heap, GC pause, connection pool đang chờ, thời gian gọi DB và API ngoài.
- CPU cao: lấy thread dump vài lần cách nhau vài giây (
jcmd <pid> Thread.printhoặcjstack), tìm thread luôn RUNNABLE ở cùng chỗ. Có thể là vòng lặp, regex xấu, hoặc GC chạy liên tục. - Chậm mà CPU thấp: thread đang chờ: hết connection DB, lock, gọi API ngoài không có timeout.
- OOM hoặc heap tăng dần: bật
-XX:+HeapDumpOnOutOfMemoryError, mở heap dump bằng Eclipse MAT, xem ai giữ nhiều bộ nhớ nhất. - Java Flight Recorder (
jcmd <pid> JFR.start) cho profile chi phí thấp, dùng được trên production.
Người phỏng vấn muốn nghe: có quy trình rõ ràng, biết cả cách giảm thiệt hại tạm thời (rollback, scale) trước khi tìm nguyên nhân gốc.
03Hai người cùng đặt mua sản phẩm cuối cùng trong kho. Bạn xử lý cập nhật đồng thời trong JPA thế nào?Java · Senior
Gợi ý trả lời
Ôn thêm câu hỏi Java →Đây là bài toán lost update. Có hai hướng chính, chọn theo mức độ tranh chấp:
- Optimistic locking: thêm field
@Version. Khi update, Hibernate kèm điều kiệnwhere version = ?; nếu người khác đã sửa trước, bạn nhậnOptimisticLockExceptionvà có thể retry hoặc báo lỗi. Hợp khi tranh chấp ít. - Pessimistic locking:
@Lock(LockModeType.PESSIMISTIC_WRITE)sinhSELECT ... FOR UPDATE, giữ khoá đến hết transaction. Hợp khi tranh chấp nhiều, đổi lại throughput giảm và có nguy cơ deadlock. - Đơn giản nhất cho tồn kho: update có điều kiện ngay trong DB:
UPDATE product SET stock = stock - 1 WHERE id = ? AND stock > 0;Kiểm tra số dòng bị ảnh hưởng: bằng 0 nghĩa là hết hàng.
Hay sai: dùng
synchronizedtrong code Java. Nó vô dụng khi chạy nhiều instance, và cũng không bảo vệ được dữ liệu ở DB.- Optimistic locking: thêm field
04SLI, SLO và error budget là gì? Bạn đặt alert dựa trên chúng thế nào?DevOps & CI/CD · Senior
Gợi ý trả lời
Ôn thêm câu hỏi DevOps & CI/CD →SLI là chỉ số đo trải nghiệm người dùng (tỷ lệ request thành công, độ trễ p99); SLO là mục tiêu cho SLI đó trong một khoảng thời gian; error budget là phần được phép hỏng còn lại.
- Ví dụ: SLO 99.9% request thành công trong 30 ngày, nghĩa là budget 0.1% request lỗi.
- Alert theo burn rate: budget đang bị tiêu nhanh bất thường (đo trên cửa sổ ngắn và dài) thì báo, thay vì báo mỗi khi CPU cao.
- Hết budget: ưu tiên việc ổn định, chậm lại tính năng mới.
Hay sai: đặt alert trên nguyên nhân (CPU, RAM) thay vì triệu chứng người dùng thấy, dẫn đến báo động giả và mệt mỏi vì alert.
05GitOps là gì? Bạn tổ chức repo và quy trình deploy cho nhiều môi trường, nhiều service ra sao?DevOps & CI/CD · Senior
Gợi ý trả lời
Ôn thêm câu hỏi DevOps & CI/CD →GitOps coi Git là nguồn sự thật cho trạng thái hệ thống; một agent trong cluster (Argo CD, Flux) liên tục kéo và đồng bộ, thay vì CI đẩy thẳng bằng
kubectl.- Tách repo code ứng dụng và repo cấu hình deploy; CI build image rồi mở PR cập nhật tag.
- Cấu hình dùng chung bằng Helm chart hoặc Kustomize, overlay riêng cho dev/staging/prod.
- Lên prod qua PR có review; rollback bằng
git revert. - Bật phát hiện drift và tự sửa lệch cấu hình.
- CI không cần giữ credential admin của cluster.
Người phỏng vấn muốn nghe: cân nhắc được đánh đổi, ví dụ secret vẫn cần giải pháp riêng và số lượng PR cập nhật tag có thể nhiều.
06Là kiến trúc sư, bạn đưa ra và ghi lại một quyết định kiến trúc quan trọng như thế nào?System Design & Kiến trúc · Senior
Gợi ý trả lời
Ôn thêm câu hỏi System Design & Kiến trúc →Quyết định kiến trúc là chọn trade-off dựa trên ràng buộc thực tế (nghiệp vụ, đội ngũ, ngân sách, thời gian), không phải chọn công nghệ "tốt nhất".
- Xác định các thuộc tính chất lượng quan trọng nhất (hiệu năng, sẵn sàng, bảo mật, chi phí, khả năng thay đổi) và sắp xếp ưu tiên cùng stakeholder.
- Đưa ra 2–3 phương án, so sánh rủi ro; làm POC hoặc spike cho điểm chưa chắc chắn.
- Ghi lại bằng ADR (Architecture Decision Record): bối cảnh, quyết định, phương án đã loại, hệ quả. Lưu cùng repo để người sau hiểu "vì sao".
- Phân biệt quyết định khó đảo ngược (chọn DB, ranh giới service) với quyết định dễ thay đổi; quyết định dễ đảo ngược thì nên làm nhanh.
- Xem lại quyết định khi bối cảnh thay đổi.
Người phỏng vấn muốn nghe: bạn thuyết phục đội ngũ bằng dữ liệu, lắng nghe phản biện, và kể được một quyết định từng sai cùng cách bạn sửa.
07Phân biệt
==vàequals(). Vì sao overrideequals()thì phải override cảhashCode()?Java · JuniorGợi ý trả lời
Ôn thêm câu hỏi Java →==so sánh tham chiếu (hai biến có trỏ cùng một object không), cònequals()so sánh nội dung theo logic bạn định nghĩa.- Hợp đồng: hai object
equalsnhau thì bắt buộc có cùnghashCode. HashMap/HashSetdùnghashCodeđể chọn bucket trước, rồi mới dùngequalsđể so trong bucket. Nếu chỉ overrideequals, hai object "bằng nhau" có thể rơi vào hai bucket khác nhau, nênset.contains(x)trả vềfalsedù đã add.- Với Java 16+,
recordtự sinhequals/hashCode/toStringtheo các field.
Hay sai: so sánh
StringhoặcIntegerbằng==. Nó có thể chạy đúng nhờ string pool hoặc cacheIntegertừ -128 đến 127, rồi sai với giá trị khác.- Hợp đồng: hai object
08Vì sao
Stringlà immutable? Khi nào dùngStringBuilderthay choString?Java · JuniorGợi ý trả lời
Ôn thêm câu hỏi Java →Stringbất biến: mọi thao tác "sửa" đều tạo object mới. Nhờ vậy nó an toàn khi chia sẻ giữa nhiều thread, dùng làm key choHashMapđược (hash không đổi) và JVM có thể dùng chung qua string pool.- Nối chuỗi trong vòng lặp bằng
+tạo nhiều object trung gian, nên dùngStringBuilder:
var sb = new StringBuilder(); for (String s : items) sb.append(s).append(','); String result = sb.toString();StringBuffergiốngStringBuildernhưng các method cósynchronized, chậm hơn và hiếm khi cần.- Nối vài chuỗi trên một dòng thì cứ dùng
+, compiler đã tối ưu sẵn.
Người phỏng vấn muốn nghe: bạn hiểu lý do thiết kế (an toàn, hash, pool), không chỉ thuộc định nghĩa.
- Nối chuỗi trong vòng lặp bằng
09Checked exception và unchecked exception khác nhau thế nào?
try-with-resourcesdùng để làm gì?Java · JuniorGợi ý trả lời
Ôn thêm câu hỏi Java →Checked exception (kế thừa
Exceptionnhưng không phảiRuntimeException) bị compiler bắt buộc phảicatchhoặc khai báothrows, ví dụIOException. Unchecked (RuntimeExceptionvà con của nó) thì không, ví dụNullPointerException,IllegalArgumentException.- Checked hợp với lỗi bên ngoài mà caller có thể xử lý được; unchecked thường là lỗi lập trình hoặc vi phạm điều kiện.
try-with-resourcestự gọiclose()cho mọi object implementAutoCloseable, kể cả khi có exception:
try (var reader = Files.newBufferedReader(path)) { return reader.readLine(); }Hay sai:
catch (Exception e) {}rồi bỏ trống, làm mất dấu lỗi. Ít nhất phải log kèm stack trace, hoặc bọc lại thành exception có ý nghĩa và ném tiếp.10Mức lương mong muốn của bạn là bao nhiêu?Câu hỏi hành vi & văn hoá
Gợi ý trả lời
Ôn thêm câu hỏi Câu hỏi hành vi & văn hoá →Tìm hiểu trước mặt bằng lương cho vị trí và số năm kinh nghiệm (dữ liệu lương trên Drama Công Ty, bạn bè cùng ngành), rồi đưa ra một khoảng có căn cứ.
- Nói rõ gross hay net. Gross là lương trước khi trừ bảo hiểm bắt buộc và thuế thu nhập cá nhân; net là số thực nhận.
- Hỏi tổng thu nhập: lương tháng 13 (không bắt buộc theo luật), thưởng, chu kỳ review lương, bảo hiểm sức khoẻ.
- Lương thử việc theo luật tối thiểu bằng 85% lương chính thức; nhiều công ty trả 100%, cứ hỏi rõ.
Câu mẫu: "Dựa trên kinh nghiệm và mặt bằng thị trường, em mong muốn khoảng X đến Y triệu gross. Em cũng muốn hiểu thêm về thưởng và review lương bên mình."
Hay sai: nói "tuỳ công ty" (dễ bị trả thấp), hoặc khai khống lương hiện tại.
Bạn đã phỏng vấn ở ATOMI DIGITAL?
Kể lại các vòng và câu hỏi đã gặp (ẩn danh) để người sau ôn đúng trọng tâm.
Chia sẻ kinh nghiệm phỏng vấn