Câu hỏi phỏng vấn hay gặp
Sắp đi phỏng vấn rồi, cho mình danh sách câu hay gặp nhất để ôn nhanh.
Được. Mình gom từ các lượt "Phỏng vấn hỏi…" trong toàn bộ guide, chọn ra 180 câu xuất hiện nhiều nhất trong phỏng vấn Java backend, chia theo chương.
Cách ôn
- Đọc câu hỏi, tự trả lời thành tiếng trước khi mở.
- Mở ra so với câu trả lời ngắn. Thiếu ý chính thì bấm link sang bài để đọc lại phần Phỏng vấn.
- Câu nào trả lời trôi chảy thì bỏ qua lần sau. Câu nào vấp thì đánh dấu, ôn lại hôm sau.
Câu trả lời dưới đây chỉ là ý lõi một dòng. Khi phỏng vấn thật, hãy mở rộng thành: định nghĩa → ví dụ trong project → trade-off.
1. Java Core
Mở đầu bằng nền tảng: gần như buổi phỏng vấn Java nào cũng hỏi vài câu ở đây.
Vì sao override
equalsphải overridehashCode?Hai object equals mà hashCode khác nhau sẽ rơi vào hai bucket khác nhau, HashMap/HashSet không tìm thấy hoặc lưu trùng. → bài 1.4
HashMap hoạt động bên trong thế nào?
Mảng bucket; hash(key) chọn bucket, va chạm thì nối list (đổi sang cây đỏ-đen khi dài ≥ 8); vượt load factor 0.75 thì resize gấp đôi. → bài 1.4
Vì sao String immutable?
==khácequalsthế nào?Immutable để dùng chung trong String pool, an toàn khi làm key và giữa các thread.
==so địa chỉ,equalsso nội dung. → bài 1.3String, StringBuilder, StringBuffer khác nhau gì?
String bất biến; StringBuilder mutable, không đồng bộ, nhanh; StringBuffer mutable, có synchronized, gần như không còn dùng. → bài 1.3
Interface và abstract class khác nhau gì, khi nào dùng cái nào?
Interface mô tả khả năng (một class implement nhiều cái); abstract class chia sẻ state và code chung cho các lớp con cùng họ. → bài 1.2
Bạn hiểu SOLID thế nào, áp dụng ra sao?
Năm nguyên tắc giúp code dễ đổi: một lý do để sửa, mở rộng không sửa cũ, lớp con thay được lớp cha, interface nhỏ, phụ thuộc abstraction. → bài 1.1
ArrayList và LinkedList khác nhau gì?
ArrayList là mảng động, truy cập theo index O(1), cache-friendly; LinkedList chèn/xóa đầu cuối O(1) nhưng thực tế thường chậm hơn. → bài 1.5
Checked và unchecked exception khác nhau gì?
Checked bắt buộc khai báo/bắt lúc compile (IOException); unchecked là RuntimeException, thường là lỗi lập trình hoặc lỗi nghiệp vụ. → bài 1.8
Java pass-by-value hay pass-by-reference?
Luôn pass-by-value. Với object, giá trị được copy là reference, nên sửa field thấy được nhưng gán lại biến thì không. → bài 1.10
finalcó làm object immutable không?Không. final chỉ cấm gán lại biến; nội dung object vẫn sửa được nếu class không immutable. → bài 1.10
Stream API là gì?
mapkhácflatMap?Pipeline xử lý dữ liệu khai báo, lazy. map biến 1 phần tử thành 1; flatMap biến 1 thành một stream rồi làm phẳng. → bài 1.12
Optional dùng thế nào cho đúng?
Làm kiểu trả về khi có thể không có giá trị; không dùng cho field, tham số; tránh gọi
get()mù. → bài 1.13Record là gì, khác class thường?
Class dữ liệu bất biến, tự sinh constructor, accessor, equals/hashCode/toString; hợp làm DTO. → bài 1.13
Type erasure là gì?
Generic chỉ kiểm tra lúc compile, runtime bị xóa về Object/bound, nên không
new T()hayinstanceof List<String>được. → bài 1.9Singleton viết thread-safe thế nào, có nhược điểm gì?
Dùng enum hoặc holder class; nhược điểm là state toàn cục, khó test, khó thay thế. Trong Spring để container quản lý. → bài 1.16
Spring dùng những design pattern nào?
Factory (BeanFactory), Singleton (bean scope), Proxy (AOP, @Transactional), Template Method (JdbcTemplate), Observer (event). → bài 1.17
2. JVM
Nhóm câu hay hỏi ở level middle trở lên, nhất là phần sự cố production.
JDK, JRE, JVM khác nhau thế nào? JIT là gì?
JVM chạy bytecode; JRE = JVM + thư viện; JDK = JRE + công cụ dev. JIT biên dịch code nóng ra mã máy lúc chạy nên app cần warm-up. → bài 2.1
Stack và Heap khác nhau thế nào?
Stack riêng từng thread, chứa frame và biến local; Heap dùng chung, chứa object, do GC quản lý. → bài 2.2
GC biết object nào là rác bằng cách nào? Generational GC là gì?
Đi từ GC roots, object không tới được là rác. Heap chia young/old vì đa số object chết trẻ; minor GC dọn young, full GC dọn cả heap. → bài 2.4
G1 và ZGC khác nhau thế nào?
G1 là mặc định, cân bằng throughput và pause; ZGC pause dưới mili giây cho heap lớn, đổi lại tốn CPU hơn. → bài 2.4
Java có GC thì memory leak xảy ra thế nào? Xử lý OOM ra sao?
Object vẫn còn được tham chiếu (static map, cache không giới hạn, ThreadLocal). Bật HeapDumpOnOutOfMemoryError, mở dump bằng MAT, xem retained heap. → bài 2.5
ClassNotFoundException khác NoClassDefFoundError?
CNFE khi load động bằng tên mà không có class; NoClassDefFoundError khi lúc compile có nhưng lúc chạy thiếu hoặc static init lỗi. → bài 2.3
Service dùng 100% CPU, bạn điều tra thế nào?
Tìm thread nóng bằng
top -H, lấy thread dump (jstack/jcmd) đối chiếu, hoặc ghi JFR; kiểm tra cả GC log. → bài 2.6
3. Concurrency
Câu nào cũng nên gắn với ví dụ thật: hai request cùng trừ tồn kho, cùng đặt một ghế.
Process và thread khác nhau thế nào?
Process có vùng nhớ riêng; các thread trong một process chia sẻ heap nên nhẹ hơn nhưng phải đồng bộ. → bài 3.1
Runnable khác Callable?
Runnable không trả kết quả, không ném checked exception; Callable trả kết quả qua Future. → bài 3.2
Vì sao dùng thread pool? Cấu hình thế nào?
Tái sử dụng thread, giới hạn tài nguyên. Chọn core/max theo loại việc (CPU hay I/O), queue có giới hạn và rejection policy rõ ràng. → bài 3.3
synchronized, volatile, atomic khác nhau thế nào?
volatile chỉ đảm bảo visibility; atomic dùng CAS cho một biến; synchronized đảm bảo cả mutual exclusion và visibility cho một khối. → bài 3.4
Race condition là gì, tránh thế nào?
Kết quả phụ thuộc thứ tự chạy của nhiều thread/request. Tránh bằng atomic update ở DB, lock, optimistic locking hoặc thiết kế không chia sẻ state. → bài 3.5
Deadlock là gì, tránh thế nào?
Hai bên giữ lock và chờ lock của nhau. Tránh bằng lấy lock theo thứ tự cố định, dùng timeout (tryLock); phát hiện bằng thread dump. → bài 3.6
synchronized và ReentrantLock khác nhau thế nào?
ReentrantLock có tryLock, timeout, fair, nhiều Condition; synchronized gọn hơn, tự nhả khi ra khỏi khối. → bài 3.7
ThreadLocal là gì, vì sao phải
remove()?Biến riêng cho từng thread. Thread trong pool được tái sử dụng nên không remove sẽ rò dữ liệu sang request khác và leak bộ nhớ. → bài 3.8
CompletableFuture dùng khi nào?
Chạy song song nhiều việc độc lập rồi gộp kết quả; nhớ truyền executor riêng, không dùng commonPool cho I/O. → bài 3.9
HashMap và ConcurrentHashMap khác nhau thế nào?
ConcurrentHashMap thread-safe, khóa theo bucket/CAS, không cho null; nhưng check-then-act vẫn phải dùng
compute/merge. → bài 3.10Virtual thread là gì, giải quyết vấn đề gì?
Thread nhẹ do JVM quản lý, block I/O thì nhả carrier thread; giúp code blocking chịu được hàng chục nghìn request đồng thời. → bài 3.11
4. Spring Core / MVC
Spring là trọng tâm của hầu hết vị trí Java backend.
IoC và Dependency Injection là gì?
Container tạo và nối các object thay cho code tự new; DI là cách đưa dependency vào, nên dùng constructor injection. → bài 4.1.1
Bean lifecycle và scope? Singleton bean có thread-safe không?
Khởi tạo → inject → @PostConstruct → dùng → @PreDestroy. Singleton dùng chung cho mọi thread nên chỉ an toàn khi không giữ state thay đổi. → bài 4.1.2
Spring AOP hoạt động thế nào? JDK proxy khác CGLIB?
Spring bọc bean bằng proxy để chạy advice quanh method. JDK proxy dựa trên interface, CGLIB tạo subclass. → bài 4.1.3
Auto-configuration hoạt động thế nào?
Boot đọc danh sách auto-config trong jar, mỗi class có điều kiện @ConditionalOnClass/OnMissingBean; xem báo cáo bằng
--debug. → bài 4.1.4Quản lý cấu hình nhiều môi trường thế nào?
Profile + application-{profile}.yml, giá trị nhạy cảm từ biến môi trường; env var ghi đè yml. → bài 4.1.5
Mô tả luồng một request trong Spring MVC.
Filter → DispatcherServlet → HandlerMapping → Interceptor → HandlerAdapter → Controller → MessageConverter → response. → bài 4.2.1
Filter, Interceptor và AOP khác nhau thế nào?
Filter ở tầng Servlet, thấy mọi request; Interceptor biết handler nào; AOP bọc method của bean bất kỳ. → bài 4.2.8
@Valid và @Validated khác nhau thế nào?
@Valid là chuẩn Jakarta, dùng cho body và nested; @Validated của Spring hỗ trợ validation group và validate tham số method. → bài 4.2.6
Xử lý exception tập trung thế nào?
@RestControllerAdvice + @ExceptionHandler, trả ProblemDetail thống nhất, không lộ stack trace. → bài 4.2.7
Có nên trả Entity JPA trực tiếp ra API không?
Không: lộ field nội bộ, dính lazy loading và vòng lặp JSON, API bị khóa theo schema DB. Dùng DTO/record. → bài 4.2.5
RestTemplate, RestClient, WebClient khác nhau thế nào?
RestTemplate cũ, blocking; RestClient là API fluent mới cho code blocking; WebClient non-blocking, dùng với WebFlux. → bài 4.2.11
5. JPA
Phần dễ ăn điểm nhất nếu bạn kể được lỗi đã gặp thật.
JPA khác Hibernate khác Spring Data JPA thế nào?
JPA là đặc tả; Hibernate là implementation; Spring Data JPA sinh repository trên nền JPA. → bài 4.3.1
Persistence context và dirty checking là gì?
Cache cấp 1 theo transaction giữ entity managed; lúc flush Hibernate so snapshot và tự UPDATE, không cần gọi save(). → bài 4.3.2
@Transactional hoạt động thế nào, vì sao gọi nội bộ không chạy?
Chạy qua proxy; gọi
this.method()đi thẳng vào object nên bỏ qua proxy, không mở transaction. → bài 4.3.3Checked exception có rollback không?
Mặc định không; chỉ RuntimeException và Error. Muốn rollback thì khai báo
rollbackFor. → bài 4.3.3REQUIRED và REQUIRES_NEW khác nhau thế nào?
REQUIRED tham gia transaction đang có; REQUIRES_NEW tạm dừng nó và mở transaction độc lập (hay dùng cho audit log). → bài 4.3.4
N+1 query là gì, xử lý thế nào?
1 query lấy N cha rồi N query lấy con. Sửa bằng JOIN FETCH, @EntityGraph, batch size hoặc projection DTO. → bài 4.3.6
LazyInitializationException là gì? Open-in-view là gì?
Truy cập quan hệ LAZY sau khi session đóng. Open-in-view giữ session tới view, che lỗi và giữ connection lâu, nên tắt. → bài 4.3.7
Optimistic và pessimistic locking khác nhau thế nào?
Optimistic dùng @Version, phát hiện xung đột lúc ghi rồi retry; pessimistic khóa row bằng SELECT FOR UPDATE, hợp khi tranh chấp cao. → bài 4.3.10
Insert 100.000 bản ghi nhanh với JPA thế nào?
Bật jdbc batch_size, dùng SEQUENCE thay IDENTITY, flush/clear theo lô; quá lớn thì dùng JDBC batch hoặc COPY. → bài 4.3.11
6. Spring Security
Nền tảng bảo mật trong Spring; Keycloak, API security và mã hóa có nhóm riêng bên dưới.
Spring Security hoạt động thế nào?
Một chuỗi filter (SecurityFilterChain) chạy trước DispatcherServlet, lo authentication rồi authorization. → bài 4.4.1
401 khác 403 thế nào?
401: chưa xác thực hoặc token sai; 403: đã biết bạn là ai nhưng không có quyền. → bài 4.4.3
JWT là gì, vì sao stateless? Có thu hồi ngay được không?
Token tự chứa claim, có chữ ký nên server verify không cần tra session. Không thu hồi ngay được, phải dùng TTL ngắn + refresh token hoặc blacklist. → bài 4.4.5
Vì sao cần refresh token?
Access token sống ngắn để giảm rủi ro lộ; refresh token dùng để lấy token mới, có rotation và reuse detection. → bài 4.4.6
OAuth2 khác OpenID Connect thế nào?
OAuth2 để ủy quyền truy cập (access token); OIDC thêm lớp xác thực danh tính (ID token). → bài 4.4.7
Mỗi microservice có cần validate JWT không, hay chỉ gateway?
Nên validate ở cả service (resource server, lấy key từ JWKS của Keycloak) để không tin mạng nội bộ một cách mù quáng. → bài 4.4.8
CORS khác CSRF thế nào?
CORS là browser cho phép JS đọc response khác origin; CSRF là tấn công lợi dụng cookie tự gửi. REST dùng Bearer token thường tắt CSRF. → bài 4.4.9
Lưu password thế nào?
Hash chậm có salt (BCrypt/Argon2) qua PasswordEncoder, không dùng MD5/SHA-256 trần. → bài 13.3
7. Reactive
Thường hỏi khi công ty dùng WebFlux hoặc Gateway.
Vì sao cần reactive? Khi nào không nên dùng WebFlux?
Phục vụ nhiều kết nối I/O với ít thread. Không nên khi stack còn blocking (JDBC, JPA) hoặc team chưa quen. → bài 4.5.1
Mono và Flux khác nhau thế nào?
Mono phát 0–1 phần tử, Flux phát 0–N; không subscribe thì không có gì chạy. → bài 4.5.3
Chuyện gì xảy ra nếu event loop bị block?
Vài thread event loop phục vụ mọi request, block một thread là hàng loạt request đứng theo. → bài 4.5.2
Backpressure là gì?
Subscriber báo cho publisher biết mình nhận được bao nhiêu (request(n)) để không bị dội dữ liệu. → bài 4.5.6
WebFlux, MVC hay virtual threads?
Mặc định MVC + virtual threads cho code blocking; WebFlux khi cần streaming, nhiều kết nối dài hoặc gateway. → bài 4.5.10
8. Cloud / Microservices
Hỏi nhiều ở vị trí làm hệ thống microservices.
Monolith khác microservices, khi nào nên chuyển?
Chuyển khi team và domain đủ lớn, cần deploy/scale độc lập; đổi lại phải gánh độ phức tạp phân tán. → bài 4.6.1
Service discovery là gì? Dùng Kubernetes có cần Eureka không?
Service đăng ký và tìm nhau theo tên thay vì IP cứng. Trên K8s, Service + DNS đã làm việc này nên thường bỏ Eureka. → bài 4.6.2
API Gateway để làm gì?
Một điểm vào cho client: routing, auth, rate limiting, logging gom về một chỗ. → bài 4.6.4
Circuit breaker là gì, có những trạng thái nào?
Ngắt gọi sang service đang lỗi để fail fast: CLOSED → OPEN → HALF_OPEN thử lại. → bài 4.6.6
Client-side và server-side load balancing khác nhau thế nào?
Client-side: caller tự chọn instance (Spring Cloud LoadBalancer); server-side: đi qua LB trung gian (Nginx, K8s Service). → bài 4.6.5
Distributed tracing là gì? traceId khác spanId?
Theo dõi một request qua nhiều service. traceId chung cho cả hành trình, spanId cho từng bước. → bài 4.6.8
9. Testing
Ít khi là câu chính, nhưng hay hỏi kèm "bạn test cái này thế nào".
Bạn tổ chức test cho một service Spring Boot thế nào?
Nhiều unit test cho logic, slice test cho web/repository, integration test với Testcontainers, ít E2E. → bài 5.1
Mock, stub, spy khác nhau thế nào? Khi nào không nên mock?
Stub trả dữ liệu dựng sẵn, mock kiểm tra tương tác, spy bọc object thật. Không mock thứ mình không sở hữu như DB, hãy test thật. → bài 5.3
@WebMvcTest khác @SpringBootTest thế nào?
@WebMvcTest chỉ dựng tầng web, nhanh; @SpringBootTest dựng cả context, dùng cho integration test. → bài 5.4
Vì sao dùng Testcontainers thay vì H2?
Test trên đúng PostgreSQL/Kafka thật, tránh khác biệt SQL và hành vi giữa H2 và production. → bài 5.5
10. Database
PostgreSQL: chủ đề hay đào sâu nhất sau Spring.
ACID là gì? Có những isolation level nào?
Atomicity, Consistency, Isolation, Durability. Read Uncommitted → Read Committed (mặc định PostgreSQL) → Repeatable Read → Serializable. → bài 6.1
MVCC trong PostgreSQL hoạt động thế nào?
UPDATE tạo version mới của row, reader thấy snapshot nên đọc không chặn ghi; VACUUM dọn version cũ. → bài 6.3
Index hoạt động thế nào? Query chậm điều tra ra sao?
B-tree giúp tìm nhanh, đổi lại ghi chậm hơn và tốn chỗ. Điều tra bằng EXPLAIN ANALYZE, pg_stat_statements, xem seq scan và số row ước lượng. → bài 6.4
Thứ tự cột trong composite index quan trọng thế nào?
Index dùng được theo tiền tố trái nhất; cột lọc bằng nhau đặt trước, cột range/sort đặt sau. → bài 6.4
Vì sao phân trang OFFSET chậm? Thay bằng gì?
DB vẫn phải đọc và bỏ qua OFFSET dòng. Dùng keyset pagination (WHERE id < last_id). → bài 6.6
Chọn connection pool size thế nào?
Nhỏ hơn bạn nghĩ: tính theo số core DB và tổng instance app; pool to quá làm DB chậm hơn. → bài 6.8
Replication, partition, sharding khác nhau thế nào?
Replication sao chép dữ liệu để đọc/HA; partition chia bảng trong một DB; sharding chia dữ liệu sang nhiều DB theo shard key. → bài 6.9
11. Redis
Gần như project nào cũng có Redis, nên câu hỏi rất thực tế.
Vì sao Redis nhanh? Có phải single-thread không?
Dữ liệu trong RAM, cấu trúc đơn giản, lệnh chạy trên một thread chính nên không tốn lock; I/O mạng có thể đa thread. → bài 7.1
Bạn implement cache thế nào? Cache và DB có nhất quán không?
Cache-aside: đọc cache, miss thì đọc DB rồi set TTL; ghi DB rồi xóa cache. Chỉ nhất quán cuối cùng. → bài 7.2
Cache stampede, penetration, avalanche khác nhau thế nào?
Stampede: key nóng hết hạn, mọi request đổ vào DB; penetration: hỏi key không tồn tại; avalanche: nhiều key hết hạn cùng lúc. → bài 7.2
Restart Redis có mất data không? RDB khác AOF?
RDB là snapshot định kỳ, có thể mất dữ liệu gần nhất; AOF ghi log từng lệnh, an toàn hơn nhưng file lớn hơn. → bài 7.3
Implement distributed lock bằng Redis thế nào?
SET key token NX PX ttl, nhả bằng Lua kiểm tra token; vẫn cần fencing token hoặc constraint DB cho việc quan trọng. → bài 7.5
12. Messaging
Kafka và RabbitMQ: hỏi về mất message, trùng message và thứ tự.
Vì sao dùng message queue?
Tách producer và consumer, xử lý bất đồng bộ, hấp thụ đỉnh tải, một event nhiều bên nhận. → bài 8.1
Idempotency là gì, sao consumer cần idempotent?
Xử lý nhiều lần cho cùng kết quả. At-least-once nên message có thể đến lại, consumer phải chống trùng (bảng processed_message). → bài 8.1
Kafka khác message queue truyền thống ở điểm nào?
Kafka là log lưu bền, message không bị xóa khi đọc, nhiều consumer group đọc lại được theo offset. → bài 8.6
Kafka có đảm bảo thứ tự message không?
Chỉ trong một partition. Muốn giữ thứ tự theo order thì dùng orderId làm key. → bài 8.6
Deploy 5 consumer mà topic có 2 partition thì sao?
Chỉ 2 consumer có việc, 3 consumer ngồi chờ; số consumer hữu ích tối đa bằng số partition. → bài 8.8
At-most-once, at-least-once, exactly-once khác nhau thế nào?
Có thể mất / có thể trùng / đúng một lần. Thực tế: at-least-once + consumer idempotent. → bài 8.9
Consumer xử lý lỗi thì retry thế nào? DLQ là gì?
Retry có backoff, quá số lần thì đẩy sang dead letter queue để xem xét, không chặn message khác. → bài 8.5
RabbitMQ hay Kafka?
RabbitMQ cho task queue, routing linh hoạt; Kafka cho event stream, throughput lớn, cần đọc lại. → bài 8.10
13. Networking
Hay hỏi dạng "sự cố thì debug thế nào".
TCP khác UDP thế nào? Mô tả 3-way handshake.
TCP có kết nối, tin cậy, có thứ tự; UDP không. Handshake: SYN → SYN-ACK → ACK. → bài 9.2
Connection refused khác connection timed out?
Refused: tới máy nhưng port không có ai nghe; timeout: gói tin bị chặn/thất lạc (firewall, sai route). → bài 9.3
TLS handshake diễn ra thế nào?
Client/server thỏa thuận cipher, server gửi certificate, client verify, hai bên trao đổi key rồi mã hóa đối xứng. → bài 9.5
502 và 504 khác nhau thế nào?
502: proxy nhận response hỏng hoặc không kết nối được upstream; 504: upstream trả lời quá chậm. → bài 9.8
Load balancer L4 và L7 khác nhau thế nào?
L4 chia theo IP/port, nhanh; L7 đọc HTTP nên route theo path/header, terminate TLS được. → bài 9.7
Connect timeout khác read timeout? Vì sao timeout ngoài phải lớn hơn trong?
Connect: thời gian mở kết nối; read: chờ dữ liệu. Tầng ngoài timeout trước thì tầng trong vẫn chạy phí công. → bài 9.10
14. Linux
Hỏi khi bạn nói từng tự vận hành service: process, memory, signal, cgroups.
Linux tạo process mới thế nào? Zombie khác orphan ra sao?
fork rồi exec. Zombie đã chết nhưng cha chưa
wait; orphan còn sống nhưng cha đã chết, được PID 1 nhận nuôi. → bài 10.1Vì sao RSS của JVM lớn hơn
-Xmx?-Xmxchỉ giới hạn heap; còn metaspace, code cache, thread stack, GC, direct buffer. Xem bằng Native Memory Tracking, cấp RAM khoảng 1.3–1.5 lần heap. → bài 10.2OOM killer khác
OutOfMemoryErrorthế nào?OOM killer là kernel gửi SIGKILL khi RAM cạn: log app trống, exit 137, xem
dmesg. OutOfMemoryError do JVM ném khi heap/metaspace đầy, có stack trace. → bài 10.2Load 8 trên máy 4 core có phải quá tải?
Chưa chắc: load trên Linux gồm cả task chờ I/O. Xem
vmstat: cột r lớn hơn số core mới là thiếu CPU. → bài 10.3"Too many open files" xử lý thế nào?
Hết file descriptor; socket cũng là fd. Kiểm tra
/proc/PID/fd,lsof: fd tăng đều kèm nhiều CLOSE_WAIT là rò connection, sửa code chứ không chỉ tăng ulimit. → bài 10.4SIGTERM, SIGKILL, SIGQUIT khác nhau thế nào với JVM?
SIGTERM: chạy shutdown hook, Spring tắt graceful. SIGKILL: chết ngay, exit 137. SIGQUIT (
kill -3): in thread dump, app chạy tiếp. → bài 10.4Tìm thread Java đang ăn CPU trên Linux thế nào?
top -H -p PIDlấy TID, đổi sang hex, tìmnidđó trongjcmd Thread.print. → bài 10.5CPU trung bình thấp mà app trong container vẫn chậm, vì sao?
CPU throttling: limit là quota mỗi chu kỳ 100ms tính tổng mọi thread; JVM nhiều thread dùng hết sớm rồi bị dừng tới chu kỳ sau. → bài 10.6
15. API Design & Security
Thiết kế REST và bảo mật API: hỏi ở hầu hết vòng backend.
Bạn thiết kế REST API cho đơn hàng thế nào?
Danh từ số nhiều (
/orders), method là động từ, lồng tối đa hai cấp, hành động đặc biệt thành sub-resource, phân trang, lỗi thống nhất. → bài 11.1Offset hay cursor pagination?
Offset đơn giản, nhảy trang được nhưng chậm ở trang sâu và dễ trùng/sót. Cursor (keyset) ổn định, nhanh, hợp feed. → bài 11.1
Idempotent là gì? Method nào idempotent?
Gọi nhiều lần state cuối như gọi một lần: GET, PUT, DELETE. POST thì không, PATCH tùy format. Quyết định client có được tự retry không. → bài 11.2
PUT khác PATCH thế nào?
PUT thay toàn bộ resource, field thiếu bị xóa; PATCH sửa một phần (JSON Merge Patch hoặc JSON Patch). → bài 11.2
Phân biệt 400, 404, 409, 422.
400 request hỏng cú pháp; 404 không có resource; 409 xung đột state hiện tại; 422 cú pháp đúng nhưng sai validation/nghiệp vụ. → bài 11.2
Làm sao để POST tạo order an toàn khi client retry?
Client gửi Idempotency-Key, server lưu key + hash request + response; gặp lại key thì trả kết quả cũ, đang xử lý thì 409. → bài 11.3
Thiết kế error response cho public API?
RFC 9457 Problem Details: type, title, status, detail, thêm
codeổn định và traceId; không lộ stack trace. → bài 11.3Version API thế nào? Thay đổi nào là breaking?
Major version trong URL cho public API. Breaking: xóa/đổi tên field, đổi kiểu, thêm field bắt buộc, đổi status code. Thêm field tùy chọn thì không. → bài 11.4
CORS có chống được CSRF không?
Không. CORS chỉ cho JS đọc response khác origin; request vẫn tới server. Chống CSRF bằng token, SameSite cookie. → bài 11.5
BOLA là gì, chống thế nào?
API nhận ID object mà không kiểm tra quyền sở hữu, đổi ID là xem dữ liệu người khác. Đưa owner vào truy vấn (
findByIdAndOwnerId). → bài 11.6Bạn quản lý secrets và bảo vệ PII trong log thế nào?
Secret ở Vault/Key Vault, workload identity, có rotation; không log password, token, số thẻ, mask PII. → bài 11.7
16. Keycloak
Hay gặp khi CV có OAuth2/Keycloak.
Vì sao dùng Identity Provider như Keycloak thay vì mỗi service tự làm login?
Credential chỉ nằm một nơi; Keycloak lo login, MFA, SSO, LDAP; service chỉ verify chữ ký JWT. → bài 12.1
Realm khác client? Public client khác confidential client?
Realm là không gian cô lập chứa user, role; client là app được xin token. Public client (SPA, mobile) không giữ secret nên dùng PKCE; confidential client chạy trên server, có secret. → bài 12.1
Team chia sẻ cấu hình realm thế nào?
Export realm JSON, thay secret bằng biến môi trường, commit vào repo, chạy
--import-realm; môi trường dùng chung thì keycloak-config-cli hoặc Terraform. → bài 12.2SPA và service-to-service dùng flow nào?
SPA/mobile: Authorization Code + PKCE với public client. Service gọi service: Client Credentials với service account. ROPC đã deprecated. → bài 12.3
Bạn gán quyền và thêm claim tùy biến vào token thế nào?
Client role gộp thành composite role, gán cho group, user vào group. Claim tùy biến qua client scope có mapper, thêm audience mapper. → bài 12.4
Logout xong access token cũ có còn dùng được không?
Còn tới khi hết hạn vì service verify offline. Giảm rủi ro bằng token ngắn, back-channel logout, introspection cho API nhạy cảm. → bài 12.5
Chạy Keycloak HA trên production thế nào?
Ít nhất hai node
start --optimized, chung Postgres HA, cluster Infinispan, sau load balancer, admin console chỉ mở nội bộ. → bài 12.6
17. Cryptography
Ít khi hỏi sâu toán, nhưng hay hỏi dùng đúng: hash, mã hóa, chữ ký, key.
Encoding, hashing, encryption khác nhau thế nào?
Encoding (Base64) chỉ đổi biểu diễn, ai cũng decode; hash một chiều để kiểm toàn vẹn; encryption dùng key để giữ bí mật và giải mã được. → bài 13.1
HMAC khác hash thường ở đâu? Verify webhook thế nào?
HMAC có secret key nên chứng minh cả nguồn gốc. Verify webhook: raw body + timestamp, tính HMAC-SHA256, so bằng
MessageDigest.isEqual. → bài 13.2Vì sao không dùng SHA-256 để hash password? Salt khác pepper?
SHA-256 quá nhanh, GPU brute-force dễ; dùng Argon2id/BCrypt. Salt ngẫu nhiên mỗi user, lưu cùng hash; pepper là secret chung lưu ngoài DB. → bài 13.3
Mã hóa dữ liệu dùng mode nào? Envelope encryption là gì?
AES-GCM (AEAD) với nonce không lặp, không dùng ECB. Envelope: data key mã hóa dữ liệu, master key trong KMS mã hóa data key. → bài 13.4
RS256 và HS256 cho JWT khác gì?
HS256 dùng shared secret, ai verify được cũng ký được. RS256/ES256 ký bằng private key, resource server chỉ cần public key qua JWKS. → bài 13.5
Keystore khác truststore? Xoay key ký JWT không logout mọi người thế nào?
Keystore chứa private key của mình, truststore chứa CA mình tin. Xoay key: publish key mới lên JWKS trước (theo
kid), rồi mới ký bằng key mới, giữ key cũ tới khi token cũ hết hạn. → bài 13.6
18. Distributed
Câu ăn điểm senior: nói được trade-off.
B gọi C bị timeout, có nên trả "failed" không?
Không chắc: C có thể đã xử lý xong. Trạng thái là "unknown", phải kiểm tra lại hoặc retry idempotent. → bài 14.1
Khi nào nên retry, retry thế nào cho an toàn?
Chỉ lỗi tạm thời và thao tác idempotent; exponential backoff + jitter, giới hạn số lần, tôn trọng deadline. → bài 14.2
Giải thích CAP theorem.
Khi có network partition, phải chọn giữa consistency và availability; không có partition thì cân nhắc latency. → bài 14.5
Saga là gì? Choreography khác orchestration?
Chuỗi transaction cục bộ, lỗi thì chạy bù trừ. Choreography: các service phản ứng theo event; orchestration: một bộ điều phối ra lệnh. → bài 14.6
Vì sao không dùng 2PC?
Coordinator là điểm nghẽn, giữ lock lâu, nhiều broker/DB không hỗ trợ; khó dùng giữa các service. → bài 14.6
Lưu DB rồi publish Kafka, crash ở giữa thì sao? Outbox giải quyết gì?
Mất event. Outbox ghi event vào bảng cùng transaction với dữ liệu, relay (polling/CDC) đẩy lên broker sau. → bài 14.7
CQRS là gì, khi nào nên dùng?
Tách model ghi và model đọc; dùng khi đọc/ghi khác nhau nhiều về hình dạng hoặc tải. → bài 14.8
19. System Design
Luôn đi theo khung: requirement → ước lượng → thiết kế → đào sâu → trade-off.
Bạn tiếp cận một câu hỏi system design như thế nào?
Hỏi rõ requirement, ước lượng tải, vẽ high-level, đào sâu điểm khó, nói trade-off và cách mở rộng. → bài 15.1
SLI, SLO, SLA là gì?
SLI là số đo (latency p99), SLO là mục tiêu nội bộ, SLA là cam kết với khách có điều khoản phạt. → bài 15.2
Rate limiting trong hệ phân tán làm thế nào?
Token bucket/sliding window lưu đếm trong Redis (Lua cho atomic), đặt ở gateway; trả 429 kèm Retry-After. → bài 15.4
Ticket booking: làm sao không bán trùng ghế?
Giữ ghế có TTL bằng UPDATE có điều kiện hoặc unique constraint trong DB; Redis chỉ để chắn tải phía trước. → bài 15.10
Payment: làm sao khách chỉ bị trừ tiền một lần?
Idempotency key ở mọi tầng, trạng thái thanh toán rõ ràng, đối soát với provider khi timeout. → bài 15.11
Flash sale: bán 10.000 sản phẩm làm sao không oversell?
Trừ tồn atomic (Redis DECR/Lua hoặc UPDATE ... WHERE stock > 0), xếp hàng qua queue, tạo order bất đồng bộ. → bài 15.12
20. Docker / K8s
Hỏi nhiều khi bạn tự deploy service.
Image khác container? Container khác VM thế nào?
Image là template chỉ đọc, container là instance đang chạy. Container dùng chung kernel (namespace + cgroups), VM có kernel riêng. → bài 16.3
Bạn containerize Spring Boot thế nào?
Multi-stage build, base image JRE nhỏ, layered jar để tận dụng cache, chạy user không phải root, exec form ENTRYPOINT. → bài 16.2
Container Java bị exit 137 thì điều tra thế nào?
137 = SIGKILL, thường do OOMKilled: heap + non-heap vượt memory limit. Dùng MaxRAMPercentage và xem lại limit. → bài 17.6
Liveness và readiness probe khác nhau thế nào?
Liveness fail thì restart container; readiness fail thì rút khỏi Service, không nhận traffic. → bài 17.2
Kubernetes zero-downtime deployment thế nào?
Rolling update với maxUnavailable 0, readiness probe, graceful shutdown và preStop để không rơi request. → bài 17.3
ClusterIP, NodePort, LoadBalancer khác nhau? Ingress là gì?
ClusterIP nội bộ, NodePort mở port trên node, LoadBalancer xin LB cloud; Ingress route HTTP theo host/path. → bài 17.4
Pod không chạy, bạn debug theo thứ tự nào?
kubectl get→describe(events) →logs --previous→ exec vào kiểm tra config, network. → bài 17.7
21. Git, CI/CD & Cloud
Hỏi để biết bạn đưa code lên production thế nào.
Merge và rebase khác nhau? Revert khác reset?
Merge giữ lịch sử thật, rebase viết lại cho thẳng (không rebase branch đã chia sẻ). Reset viết lại lịch sử, chỉ dùng local; revert tạo commit đảo ngược, dùng cho main. → bài 18.1
Mô tả CI pipeline của dự án bạn. "Build once, deploy many" là gì?
PR chạy build, test, Testcontainers, static analysis, scan dependency; main build image, scan CVE, push registry. Một artifact bất biến được promote qua các môi trường, chỉ đổi config. → bài 18.2
So sánh rolling, blue-green, canary. Rollback app thì database sao?
Rolling rẻ; blue-green rollback nhanh nhưng tốn gấp đôi; canary giảm rủi ro theo metric. Không rollback schema: migration theo expand-contract. → bài 18.3
Terraform state là gì, vì sao cần remote backend?
State ánh xạ code với resource thật để tính diff; remote backend cho team dùng chung, có lock tránh apply đồng thời. → bài 18.4
Ứng dụng trên AWS gọi S3 mà không có access key thế nào?
IAM role cho workload (instance profile, task role, IRSA/Pod Identity); SDK lấy credential tạm qua default chain, least privilege. → bài 18.5
Làm sao không có secret trong cấu hình ứng dụng trên Azure?
Managed Identity / Workload Identity trên AKS, role assignment đúng scope, code dùng
DefaultAzureCredential. → bài 18.6
22. Observability
Câu thể hiện kinh nghiệm vận hành thật.
Log, metric, trace khác nhau thế nào?
Metric cho biết có vấn đề và nặng cỡ nào, trace cho biết chậm ở bước nào, log cho biết chi tiết vì sao; nối bằng traceId. → bài 19.1
Làm sao gom log của một request đi qua nhiều service? MDC dùng làm gì?
Tracing sinh traceId, truyền qua header
traceparent, đặt vào MDC để mọi dòng log có traceId; tìm theo traceId là ra toàn bộ request. → bài 19.1SLI, SLO, SLA và error budget là gì?
SLI là số đo, SLO là mục tiêu nội bộ, SLA là cam kết có phạt. Error budget là phần được phép lỗi: còn thì ship nhanh, hết thì dừng để lo reliability. → bài 19.2
Bạn monitor một hệ microservices và đặt alert thế nào?
RED cho service, USE cho tài nguyên; alert theo SLO burn rate đa cửa sổ thay vì ngưỡng tĩnh. → bài 19.2
Bạn thu thập metrics Spring Boot thế nào? Vì sao không đặt userId làm label?
Actuator + Micrometer xuất
/actuator/prometheus, Prometheus scrape, Grafana vẽ. userId làm bùng nổ số time series, Prometheus hết memory. → bài 19.3OpenTelemetry là gì, vì sao cần Collector?
Chuẩn mở cho trace/metric/log, instrument một lần rồi đổi backend tự do. Collector lo batch, retry, lọc dữ liệu nhạy cảm, tail sampling. → bài 19.4
Một API chậm trên production nhưng CPU thấp, bạn điều tra thế nào?
Xem metric p99, mở trace tìm span chậm; CPU thấp là thread đang chờ nên dùng wall-clock/lock profile để thấy chờ pool, lock hay DB. → bài 19.5
Kể cách bạn xử lý một sự cố production.
Gán vai, triage bằng dashboard, mitigate trước (rollback, tắt flag) rồi mới tìm root cause, sau đó viết blameless postmortem có action item. → bài 19.6
23. Behavioral
Không có đáp án đúng, nhưng có cách trả lời tốt: kể theo STAR, có số liệu.
Giới thiệu về bản thân.
1–2 phút: hiện tại làm gì → kinh nghiệm nổi bật có số liệu → vì sao ứng tuyển vị trí này. → bài PL.2
Kể về project gần nhất của bạn.
Bối cảnh → kiến trúc → vai trò của bạn → vấn đề khó → kết quả có số đo. → bài PL.2
Theo bạn senior khác mid ở đâu? "Ownership" là gì?
Senior chịu trách nhiệm cả kết quả: làm rõ yêu cầu, chọn trade-off, tới khi chạy ổn trên production; lo cả monitoring, runbook. → bài 20.1
Bạn ước lượng thế nào khi yêu cầu chưa rõ?
Chia nhỏ, đưa khoảng thời gian kèm giả định và độ tự tin, spike có timebox cho ẩn số lớn nhất. → bài 20.2
Bạn cân bằng tech debt với feature ra sao?
Quy tech debt ra chi phí business (incident, ngày chậm), trả dần khoảng 20% mỗi sprint gắn với khu vực sắp làm feature. → bài 20.2
Bạn review code thế nào? Giải thích một lựa chọn công nghệ cho thuyết phục ra sao?
Ưu tiên đúng đắn, security, vận hành, rồi test, sau cùng mới tới style. Quyết định lớn ghi ADR: bối cảnh, phương án, lý do chọn, hệ quả. → bài 20.3
Kể lần bạn bất đồng kỹ thuật với đồng nghiệp.
Đưa về dữ liệu và tiêu chí chung, gặp nhanh thay vì cãi trong comment, chốt bằng ADR, kết bằng kết quả. → bài 20.3
Bạn mentor junior và giao tiếp với stakeholder không kỹ thuật thế nào?
Junior: 1:1 định kỳ, hỏi gợi mở thay vì sửa hộ, tăng dần mức tự chủ. Stakeholder: kết luận trước, tác động, điều cần từ họ, bằng ngôn ngữ business. → bài 20.4
Vấn đề khó nhất / sự cố production bạn từng xử lý là gì?
Kể theo STAR, tập trung cách bạn điều tra và quyết định, kết bằng con số và bài học. → bài 20.5
Kể về lần bạn trễ deadline.
Thừa nhận ước lượng sai, báo sớm, đưa phương án cắt scope, rồi nói bạn thay đổi cách ước lượng thế nào. → bài 20.5
Bạn dùng AI trong công việc thế nào, đảm bảo code AI viết là đúng ra sao?
Dùng như đồng đội viết nhanh, đưa context rõ; đọc toàn bộ diff, chạy test, kiểm tra dependency như với code của người mới. → bài 21.1
Tự kiểm tra
Ôn danh sách này thế nào cho hiệu quả?
Tự trả lời thành tiếng trước, mở ra so sánh, câu nào vấp thì đọc lại bài gốc và ôn lại hôm sau.
Một câu trả lời phỏng vấn tốt gồm mấy phần?
Định nghĩa ngắn, ví dụ trong project thật, trade-off hoặc khi nào không nên dùng.
Câu về Keycloak, API Design, Observability ôn ở đâu?
Mỗi chương có nhóm riêng trong danh sách này, link thẳng sang phần Phỏng vấn của bài tương ứng.
Câu "Kể về project" chuẩn bị ở đâu?
Ở Phụ lục 2: tự giới thiệu và kể về project.