Phụ lục
Ba phụ lục dưới đây dùng cho tuần cuối trước ngày phỏng vấn. Phụ lục A là bộ câu hỏi nhanh để tự kiểm tra. Phụ lục B liệt kê các "kiến thức" lỗi thời hoặc sai vẫn lưu hành trong nhiều bộ đề trên mạng. Phụ lục C là checklist cho những ngày cuối.
A. Ngân hàng câu hỏi tự kiểm tra theo 3 mức
Cách dùng: che cột "Ý chính cần nói", tự trả lời thành tiếng trong khoảng 1–2 phút, rồi đối chiếu. Câu nào bạn chỉ nói được định nghĩa mà không nói được cơ chế hoặc trade-off thì quay lại chương tương ứng.
Mức 1: Nền tảng (không được phép trượt)
Ở mức 2–4 năm, trả lời sai nhóm này gần như đồng nghĩa với trượt vòng kỹ thuật. Người phỏng vấn thường dùng chúng để khởi động trước khi đào sâu. Câu nào bạn còn ấp úng, hãy quay lại Nền tảng 1 (Java, OOP) hoặc Nền tảng 2 (SQL, Web, Spring, Hibernate) trước khi học tiếp phần chuyên sâu.
| Câu hỏi | Ý chính cần nói | Chương |
|---|---|---|
| equals và hashCode liên quan gì? | equals true thì hashCode bằng nhau; sai thì HashSet chứa trùng, get trả null | N1.9, 1.2 |
| Java pass-by-value hay reference? | Luôn by-value; với object là bản sao tham chiếu | N1.14, 1.4 |
| Interface khác abstract class? | Khác ở trạng thái và mục đích; interface có default/static/private method | N1.7, 1.1 |
| Checked và unchecked exception? | Checked bị compiler bắt xử lý; Spring dùng unchecked; @Transactional mặc định không rollback checked | N1.12, 1.7, 4.5 |
| Stack và Heap chứa gì? | Stack: frame, biến cục bộ, riêng từng thread; Heap: object, dùng chung, do GC quản lý | 2.2 |
| Tạo thread thế nào trong thực tế? | Qua ExecutorService/thread pool, không new Thread thủ công | 3.2 |
| IoC và DI là gì? | Container tạo và nối dependency; ưu tiên constructor injection | N2.7, 4.1 |
| Bean scope mặc định? | Singleton, một instance mỗi container, không tự thread-safe | 4.2 |
| INNER, LEFT JOIN khác nhau? | LEFT giữ mọi dòng bảng trái, không khớp thì cột phải là NULL | N2.2, 6.1 |
| WHERE và HAVING? | WHERE lọc dòng trước GROUP BY; HAVING lọc nhóm sau khi gộp | N2.2, 6.1 |
| ACID là gì? | Atomicity, Consistency, Isolation, Durability; durability nhờ redo log/WAL | N2.4, 6.3 |
| PUT và PATCH? | PUT thay toàn bộ, idempotent; PATCH sửa một phần | 7.2 |
| 401 và 403? | 401 chưa xác thực; 403 đã xác thực nhưng không có quyền | 5.1, 7.3 |
| Vì sao cần message queue? | Tách rời hệ thống, xử lý bất đồng bộ, san tải khi đột biến | 8.7 |
| Unit test và integration test? | Unit cô lập bằng mock, chạy nhanh; integration chạy với DB/Spring thật | 10.6 |
| Overloading và overriding? | Overloading: cùng tên khác tham số, chọn lúc biên dịch; overriding: lớp con định nghĩa lại, chọn lúc runtime | N1.6 |
| static và final nghĩa là gì? | static thuộc về class, không thuộc object; final: biến không gán lại, method không override, class không kế thừa | N1.3 |
| == và equals với String? | == so tham chiếu, equals so nội dung; literal nằm trong pool nên == đôi khi true, không được dựa vào | N1.8, 1.3 |
| ArrayList và LinkedList? | ArrayList get(i) O(1), gần như luôn là lựa chọn mặc định; LinkedList get(i) O(n) | N1.11, 1.5 |
| Comparable và Comparator? | Comparable là thứ tự tự nhiên cài trong class; Comparator là thứ tự bên ngoài, tạo được nhiều cách sort | N1.10 |
| Optional dùng để làm gì? | Kiểu trả về cho "có thể không có giá trị", thay cho trả null; không dùng làm field hay tham số | N1.15, 1.8 |
| JDK, JRE, JVM khác nhau? | JDK có compiler và công cụ; JRE đủ để chạy; JVM thực thi bytecode, có JIT | N1.1, 2.1 |
| Primary key và unique constraint? | PK không NULL, mỗi bảng một PK; unique có thể nhiều, thường cho phép NULL | N2.1 |
| Index là gì, cái giá phải trả? | Cấu trúc B-Tree giúp tìm nhanh; tốn dung lượng và làm chậm INSERT/UPDATE | N2.4, 6.2 |
| GET và POST? | GET chỉ đọc, safe và idempotent; POST tạo hoặc xử lý, không idempotent | N2.5, 7.2 |
| Cookie và session? | Cookie lưu ở trình duyệt; session lưu ở server, cookie chỉ giữ session ID | N2.5, 5.3 |
| @Component, @Service, @Repository? | Đều đăng ký bean; @Repository thêm dịch exception của DB; @Service thể hiện tầng nghiệp vụ | N2.7, 4.1 |
| Spring Boot thêm gì so với Spring? | Auto-configuration, starter, server nhúng, cấu hình mặc định hợp lý | N2.9, 4.3 |
| Lazy và Eager loading? | Lazy tải khi truy cập, Eager tải ngay; @ManyToOne mặc định EAGER | N2.11, 6.4 |
| Status 200, 201, 204, 400, 404, 500? | Thành công, đã tạo, không có nội dung, request sai, không tìm thấy, lỗi server | 7.3 |
| Big-O của HashMap.get và ArrayList.contains? | O(1) trung bình và O(n); gọi contains trong vòng for là O(n^2) | 12.3 |
| Docker image và container? | Image là bản đóng gói chỉ đọc gồm nhiều layer; container là tiến trình chạy từ image | 11.2 |
| git merge và rebase? | Merge giữ nguyên lịch sử, thêm merge commit; rebase viết lại lịch sử cho thẳng, không rebase nhánh đã chia sẻ | N2.13, 11.1 |
| Các log level dùng thế nào? | ERROR, WARN, INFO, DEBUG; production thường ở INFO, không log mật khẩu hay token | 11.5 |
Mức 2: Hiểu cơ chế (phân biệt 2 năm với 4 năm)
Đây là nhóm quyết định level. Câu trả lời tốt phải có "vì sao" và ít nhất một hệ quả thực tế.
| Câu hỏi | Ý chính cần nói | Chương |
|---|---|---|
| HashMap put hoạt động thế nào? | Trộn hash, index = hash & (n-1), collision, treeify khi bucket quá 8 node và capacity từ 64, resize ở 0.75 | 1.5 |
| Vì sao String bất biến? | String pool, thread-safe, cache hashCode, an toàn | N1.8, 1.3 |
| Memory leak trong Java khi đã có GC? | Object còn được tham chiếu: static collection, cache không giới hạn, ThreadLocal, listener | 2.4 |
| G1 và ZGC khác gì? | G1 mặc định, cân bằng throughput/pause; ZGC pause rất ngắn cho heap lớn | 2.3 |
| volatile đảm bảo gì? | Visibility và happens-before; không đảm bảo atomic cho count++ | 3.3, 3.4 |
| ConcurrentHashMap thread-safe thế nào? | Java 8+: CAS và synchronized trên node đầu bucket, không còn segment | 3.8 |
| Cấu hình ThreadPoolExecutor ra sao? | Core, max, queue có giới hạn, rejection policy; tránh queue vô hạn | 3.6 |
| @Transactional gọi trong cùng class? | Self-invocation không đi qua proxy nên annotation không có tác dụng | 4.4, 4.5 |
| REQUIRED và REQUIRES_NEW? | REQUIRES_NEW treo transaction ngoài, tốn thêm connection | 4.5 |
| Bean lifecycle? | Khởi tạo, inject, Aware, BeanPostProcessor, @PostConstruct, proxy, @PreDestroy | 4.2 |
| N+1 là gì và sửa thế nào? | 1 query cha + N query con do lazy; JOIN FETCH, EntityGraph, batch size, DTO projection | 6.4 |
| Optimistic và pessimistic lock? | @Version kiểm tra khi update, hợp ít xung đột; FOR UPDATE khóa dòng, hợp xung đột cao | 6.3 |
| Index không được dùng khi nào? | Hàm trên cột, LIKE '%x', lệch kiểu dữ liệu, sai thứ tự composite index | 6.2 |
| JWT và session? | JWT stateless, khó thu hồi, cần access ngắn hạn + refresh token; session dễ thu hồi, cần lưu trạng thái | 5.3 |
| Cache-aside cập nhật thế nào? | Ghi DB rồi xóa cache (sau commit), đọc miss thì nạp lại | 8.4 |
| Type erasure và PECS? | Thông tin generic bị xóa lúc runtime; producer extends, consumer super | 1.6 |
| record dùng khi nào? | Class dữ liệu bất biến, tự sinh equals/hashCode/toString; hợp cho DTO, không hợp làm JPA entity | 1.8 |
| Class loading và parent delegation? | ClassLoader hỏi loader cha trước khi tự nạp, tránh nạp đè class lõi của JDK | 2.1 |
| Happens-before là gì? | Quy tắc đảm bảo ghi của thread này được thread khác thấy: unlock/lock, ghi/đọc volatile, start/join | 3.3 |
| synchronized và ReentrantLock? | Lock có tryLock timeout, chờ bị interrupt được, fairness, nhiều Condition; phải unlock trong finally | 3.4 |
| CompletableFuture xử lý lỗi và timeout? | exceptionally/handle, orTimeout/completeOnTimeout; không dùng common pool cho I/O | 3.7 |
| ThreadLocal gây rò rỉ thế nào? | Thread pool tái dùng thread nên giá trị còn sót sang request sau; luôn remove trong finally | 3.9 |
| Virtual threads có lợi khi nào? | Nhiều tác vụ chờ I/O; không nhanh hơn với tác vụ CPU; cẩn thận pinning | 3.10 |
| Auto-configuration hoạt động ra sao? | Các @Conditional theo classpath, property, bean có sẵn; bean bạn khai báo được ưu tiên | 4.3 |
| JDK proxy và CGLIB? | JDK proxy dựa trên interface, CGLIB tạo lớp con; method final/private không bị chặn | 4.4 |
| Filter, Interceptor và AOP? | Filter ở tầng servlet, Interceptor quanh handler của Spring MVC, AOP quanh method của bean | 4.6 |
| Khi nào được tắt CSRF? | API stateless xác thực bằng token trong header thì tắt được; dùng cookie session thì phải bật | 5.5 |
| Isolation Level và các hiện tượng đọc? | Dirty read, non-repeatable read, phantom; mặc định MySQL là REPEATABLE READ, PostgreSQL là READ COMMITTED | 6.3 |
| Phân trang offset và keyset? | Offset chậm dần ở trang sâu và lệch khi dữ liệu thay đổi; keyset lọc theo khóa của dòng cuối | 7.5 |
| Cache penetration, breakdown, avalanche? | Key không tồn tại (cache giá trị rỗng, bloom filter); key nóng hết hạn (mutex); nhiều key hết hạn cùng lúc (TTL ngẫu nhiên) | 8.5 |
| Partition và consumer group trong Kafka? | Thứ tự chỉ đảm bảo trong một partition; mỗi partition một consumer trong group; consumer nhiều hơn partition thì thừa | 8.8 |
| Kafka và RabbitMQ chọn thế nào? | Kafka lưu log lâu, đọc lại được, throughput cao; RabbitMQ routing linh hoạt, hợp hàng đợi tác vụ | 8.9 |
| Open/Closed trong SOLID qua ví dụ? | Thêm hành vi bằng class mới (strategy) thay vì sửa chuỗi if-else có sẵn | 10.2 |
| Mock và Testcontainers? | Mock nhanh nhưng không bắt được lỗi SQL hay mapping; Testcontainers chạy DB thật trong test | 10.6 |
| Vì sao sliding window là O(n)? | Hai con trỏ chỉ tiến, tổng số bước của cả hai tối đa 2n | 12.5 |
Mức 3: Thực chiến và thiết kế (mức Middle)
Nhóm này không có đáp án duy nhất. Người phỏng vấn chấm cách bạn lập luận, nêu trade-off và dựa vào kinh nghiệm thật.
| Câu hỏi | Ý chính cần nói | Chương |
|---|---|---|
| Production OOM, bạn làm gì? | Có heap dump sẵn (HeapDumpOnOutOfMemoryError), phân tích bằng MAT, tìm dominator, phân biệt với OOMKilled của container | 2.6, 11.8 |
| CPU 100% sau deploy? | Rollback trước; top -H tìm thread, jstack đối chiếu, xem GC log | 2.6, 11.8 |
| Deadlock trong DB và trong Java? | Khóa theo thứ tự cố định, transaction ngắn, tryLock có timeout, đọc log deadlock/jstack | 3.5, 6.3 |
| Gọi API bên ngoài trong @Transactional? | Giữ connection lâu, cạn pool; tách gọi API ra ngoài transaction, dùng outbox | 4.5, 8.11 |
| Kafka đảm bảo không mất và không xử lý trùng? | acks=all, idempotent producer, commit sau khi xử lý, consumer idempotent | 8.10 |
| Ghi DB và gửi message nhất quán? | Dual write gây lệch; Transactional Outbox | 8.11 |
| Transaction qua nhiều service? | Tránh 2PC; Saga với compensating transaction, chấp nhận eventual consistency | 9.5 |
| Chống oversell khi flash sale? | Trừ kho nguyên tử (UPDATE có điều kiện hoặc Redis), hàng đợi, idempotency key | 9.10 |
| Thiết kế URL shortener? | Sinh ID (base62), đọc nhiều nên cache, redirect 301/302, ước lượng dung lượng | 9.9 |
| Service phụ thuộc bị chậm? | Timeout, retry có backoff + jitter, circuit breaker, bulkhead, fallback | 9.4 |
| API thanh toán bị gọi 2 lần? | Idempotency key lưu kèm kết quả, unique constraint | 7.4 |
| Bạn review code nhìn gì trước? | Đúng nghiệp vụ, transaction, xử lý lỗi, bảo mật, hiệu năng query, test | 10.7 |
| Sự cố production khó nhất bạn xử lý? | Kể theo STAR, có số liệu, nêu bài học và cách phòng ngừa | 13.4 |
| Nếu làm lại dự án, bạn đổi gì? | Thể hiện tư duy trade-off, không đổ lỗi | 13.3, 13.9 |
| Vì sao chọn công nghệ X trong dự án? | Bối cảnh, phương án đã cân nhắc, lý do chọn, cái giá phải trả | 13.3 |
| p95 của API tăng gấp 3 sau release? | So sánh metric trước và sau, xem query chậm, pool, GC; rollback trước nếu ảnh hưởng lớn | 11.6, 11.8 |
| Pod restart liên tục? | describe pod, exit code (137 là OOMKilled), logs --previous, kiểm tra probe | 11.3, 11.8 |
| Thiết kế rate limiting cho API công khai? | Token bucket, trạng thái lưu ở Redis, trả 429 kèm Retry-After | 7.6, 9.4 |
| Dự án mới: monolith hay microservices? | Đội nhỏ, domain chưa rõ thì modular monolith; tách service khi có lý do đo được | 9.1 |
| Gọi đồng bộ hay phát event giữa service? | Cần kết quả ngay thì REST/gRPC; không cần thì event, chấp nhận eventual consistency | 9.2, 9.6 |
| Distributed lock bằng Redis cần chú ý gì? | SET NX PX, giá trị token để chỉ chủ mới unlock, lock hết hạn giữa chừng, fencing token | 8.6 |
| Cache và DB bị lệch dữ liệu? | Xóa cache sau commit, TTL làm lưới an toàn, cân nhắc delayed double delete | 8.4 |
| Consumer lag tăng liên tục? | Tăng partition và consumer, xử lý theo batch, tách việc nặng, đưa message lỗi vào DLQ | 8.8, 8.10 |
| Thiết kế JWT an toàn? | Access token ngắn hạn, refresh token xoay vòng, thu hồi bằng denylist hoặc token version | 5.3 |
| Race condition trong singleton bean? | Bean mặc định singleton, dùng chung giữa các request; không giữ state thay đổi được trong field | 3.11 |
| Hai request cùng cập nhật số dư? | Lost update; UPDATE nguyên tử có điều kiện, optimistic lock @Version hoặc SELECT FOR UPDATE | 6.3, 6.4 |
| Query chậm trên production? | EXPLAIN ANALYZE, index phù hợp thứ tự cột, tránh hàm trên cột, kiểm tra thống kê bảng | 6.2 |
| Thay đổi API không tương thích ngược? | Versioning qua URL hoặc header, chạy song song hai version, thông báo deprecate có thời hạn | 7.5 |
| Chiến lược test cho service thanh toán? | Unit cho logic tính tiền, integration với Testcontainers, test idempotency và retry | 10.6 |
| Theo dõi một request qua nhiều service? | traceId truyền qua header, đưa vào MDC để log, dùng OpenTelemetry | 9.7, 11.5 |
| Log vô tình chứa dữ liệu nhạy cảm? | Che (mask) ở tầng logging, review, không log token, mật khẩu, số thẻ | 11.5, 5.6 |
| Live coding đúng nhưng input 10 triệu phần tử? | Nói Big-O, ước lượng bộ nhớ, đẩy tính toán xuống DB hoặc xử lý theo batch | 12.3, 12.15 |
| HR đưa offer thấp hơn mong muốn? | Dựa trên giá trị và mặt bằng thị trường, hỏi các thành phần khác, xin thời gian có hạn | 13.7, 13.9 |
B. Sửa lỗi tài liệu cũ
Nhiều bộ câu hỏi lưu hành (kể cả một phần tài liệu gốc dùng để biên soạn cẩm nang này) được viết từ thời Java 6, Spring 3, EJB. Nếu bạn trả lời theo chúng, người phỏng vấn sẽ đánh giá kiến thức của bạn đã cũ. Bảng dưới đây tổng hợp các điểm hay gặp nhất.
Java Core và JVM
| Tài liệu cũ nói | Thực tế hiện nay |
|---|---|
| Interface chỉ có method trừu tượng | Từ Java 8 có default và static method, Java 9 có private method |
| Sửa String thì object mới được lưu vào String pool | Chuỗi tạo lúc runtime là object thường trên Heap, chỉ vào pool khi gọi intern() |
| Iterator tạo bản sao, không ảnh hưởng collection | Iterator không copy; iterator.remove() sửa trực tiếp collection |
| Deep copy bằng Cloneable hoặc Serialization là cách chuẩn | Ưu tiên copy constructor hoặc static factory; Cloneable và Java serialization không còn được khuyến khích |
| Có thể "đăng ký" GC bằng finalize() | finalize() deprecated từ Java 9, đánh dấu sẽ xóa (JEP 421); System.gc() chỉ là gợi ý |
| Method area / PermGen chứa class và static | Java 8 thay PermGen bằng Metaspace (chỉ metadata); static field và String pool nằm trong Heap |
| Lambda sinh ra một anonymous class | Lambda được tạo qua invokedynamic, không sinh anonymous class lúc biên dịch |
| HashMap tệ nhất là O(n) | Từ Java 8, bucket nhiều node được treeify nên tệ nhất khoảng O(log n), nhất là khi key implement Comparable |
| Dùng Java 6 làm phiên bản tham chiếu, JAXB có sẵn | Chuẩn hiện nay là Java 17/21; JAXB đã bị gỡ khỏi JDK từ Java 11 |
| OutOfMemoryError là một loại lỗi 500 | OOM là Error của JVM; pod bị OOMKilled (exit 137) là container bị giết, không có heap dump |
| Nối chuỗi luôn phải dùng StringBuffer | StringBuilder cho code một thread; + ngoài vòng lặp được compiler tối ưu (invokedynamic từ Java 9), chỉ trong vòng lặp mới cần StringBuilder |
| Dùng lớp Stack làm stack | Stack kế thừa Vector, đồng bộ không cần thiết; dùng ArrayDeque |
| Vector, Hashtable là collection thread-safe nên dùng | Là lớp legacy; dùng ConcurrentHashMap, CopyOnWriteArrayList hoặc khóa rõ ràng |
| Xử lý ngày giờ bằng Date, Calendar, SimpleDateFormat | Dùng java.time (LocalDate, Instant, ZonedDateTime) từ Java 8; SimpleDateFormat không thread-safe |
| Tạo wrapper bằng new Integer(5) | Constructor của wrapper deprecated for removal; dùng Integer.valueOf hoặc autoboxing |
Concurrency
| Tài liệu cũ nói | Thực tế hiện nay |
|---|---|
| volatile đọc/ghi thẳng RAM, bỏ qua CPU cache | Bản chất là memory barrier và quan hệ happens-before |
| ConcurrentHashMap khóa theo 16 segment | Đó là Java 7; từ Java 8 dùng CAS và synchronized trên node đầu mỗi bucket |
| Thread có trạng thái Running | Thread.State chỉ có NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED |
| setPriority() đảm bảo thread A chạy trước B | Priority chỉ là gợi ý; dùng join, CountDownLatch hoặc CompletableFuture |
| Tạo thread: extends Thread hoặc implements Runnable | Thực tế dùng ExecutorService, CompletableFuture, và virtual threads từ Java 21 |
| ConcurrentHashMap là fail-safe | Chính xác là weakly consistent: không ném lỗi, không đảm bảo thấy thay đổi đồng thời |
| Double-checked locking không cần volatile | Thiếu volatile thì thread khác có thể thấy object khởi tạo dở; tốt hơn dùng holder class hoặc enum |
| ThreadLocal tự được dọn khi request kết thúc | Thread pool tái dùng thread nên giá trị còn sót; phải remove() trong finally |
Spring, JPA và Database
| Tài liệu cũ nói | Thực tế hiện nay |
|---|---|
| Spring có 5 scope, gồm global session | Global session bị bỏ từ Spring 5; hiện có singleton, prototype, request, session, application, websocket |
| Bean lifecycle: tìm định nghĩa, tạo instance, gọi setter | Còn Aware, BeanPostProcessor, @PostConstruct, tạo proxy AOP, @PreDestroy |
| Pointcut là tập hợp các join point | Pointcut là biểu thức chọn ra join point |
| Entity có 3 trạng thái | Có 4: transient, managed, detached, removed |
| Luôn khai báo LAZY là đủ | Cần biết mặc định: @ManyToOne và @OneToOne là EAGER, phải khai báo LAZY tường minh |
| N+1 làm sập DB vì hết connection | Vấn đề là số query và số round-trip, thường vẫn dùng cùng một connection |
| save() chưa chạy SQL cho tới khi commit | Với IDENTITY, INSERT chạy ngay; flush còn xảy ra trước query JPQL |
| Serializable chạy các transaction tuần tự | Chỉ đảm bảo kết quả tương đương một thứ tự tuần tự (lock ở MySQL, SSI ở PostgreSQL) |
| MVCC chụp snapshot lúc transaction bắt đầu | READ COMMITTED chụp theo từng câu lệnh; REPEATABLE READ của InnoDB chụp ở lần đọc đầu tiên |
| TRUNCATE không rollback được | Đúng với MySQL/Oracle; PostgreSQL TRUNCATE rollback được trong transaction |
| View giúp tăng hiệu năng | View thường không nhanh hơn; chỉ materialized view lưu sẵn kết quả |
| Composite key là khóa gồm hai bảng | Composite key là khóa gồm từ hai cột trở lên |
| Hibernate L2 cache thường dùng Redis | L2 thường dùng JCache/Ehcache; Redis thường đi với Spring Cache |
| Field injection bằng @Autowired là cách chuẩn | Ưu tiên constructor injection; từ Spring 4.3 constructor duy nhất không cần @Autowired |
| Cấu hình security bằng WebSecurityConfigurerAdapter | Đã bị gỡ ở Spring Security 6; khai báo bean SecurityFilterChain |
| RestTemplate là HTTP client mặc định | RestTemplate ở chế độ bảo trì; dùng RestClient (Spring 6.1) hoặc WebClient |
| Import javax.persistence, javax.validation | Spring Boot 3 chuyển sang jakarta.persistence, jakarta.validation |
Kiến trúc, công cụ và công nghệ
| Tài liệu cũ nói | Thực tế hiện nay |
|---|---|
| CAP: chọn 2 trong 3 | Không bỏ được P; khi có partition mới phải chọn C hoặc A |
| Mỗi partition một consumer nên không bao giờ đọc trùng | Vẫn trùng khi rebalance hoặc consumer chết trước khi commit; consumer phải idempotent |
| Service Locator là pattern nên dùng | Trong thời DI nó bị coi là anti-pattern vì che giấu dependency |
| Hystrix cho circuit breaker | Hystrix đã ngừng phát triển; dùng Resilience4j |
| WADL, Jersey client, SOAP UI, add-on Firefox | OpenAPI (springdoc), RestClient/WebClient, Postman |
| Theo dõi JVM bằng JConsole trên Tomcat ngoài | Ứng dụng dùng Tomcat nhúng; dùng jcmd, JFR, Micrometer + Prometheus |
| EJB, JAXB, XSLT là trọng tâm phỏng vấn | Hầu như không còn hỏi ở vị trí Spring Boot; chỉ cần biết khái niệm |
| spring.redis.*, @MockBean | Boot 3 dùng spring.data.redis.*; @MockBean deprecated từ Boot 3.4, thay bằng @MockitoBean |
| Zuul, Ribbon, Eureka là bộ microservice mặc định | Zuul và Ribbon đã ngừng; dùng Spring Cloud Gateway, Spring Cloud LoadBalancer, hoặc service discovery của Kubernetes |
| Kafka bắt buộc chạy kèm ZooKeeper | Chế độ KRaft sẵn sàng production từ Kafka 3.3; Kafka 4.0 đã bỏ hẳn ZooKeeper |
C. Checklist những ngày cuối
Một tuần trước
Một ngày trước
Trong buổi phỏng vấn
Sau buổi phỏng vấn
Mẹo từ người phỏng vấn
Lời cuối từ người ngồi phía bên kia bàn: chúng tôi không tìm người biết mọi thứ. Chúng tôi tìm người hiểu sâu những gì họ đã làm, trung thực về những gì họ chưa biết, và cho thấy họ học nhanh. Nếu bạn làm được ba điều đó, bạn đã hơn phần lớn ứng viên tôi từng gặp. Chúc bạn thành công.