Learning Outcome & Exercises: Spring Data JPA
Tổng kết chương Spring Data JPA: học xong mình phải làm được gì, và làm bài tập nào để chứng minh?
Đọc hiểu chưa đủ để đi phỏng vấn. Mỗi chương kết thúc bằng những việc làm được và chứng minh được: có code chạy, có test cho cả trường hợp lỗi, có log hoặc số đo. Bài tập nằm trong repo riêng java-backend-interview-labs, thư mục labs/spring-jpa.
1. Mục tiêu đầu ra
Học xong chương này, bạn tự làm được:
- Phát hiện N+1 bằng log SQL / đếm query trong test và sửa bằng fetch join hoặc @EntityGraph.
- Chứng minh optimistic locking (@Version) ném lỗi khi hai transaction cùng sửa.
- So sánh offset pagination ở trang sâu với keyset pagination bằng số đo.
2. Basic: Bắt N+1
Trạng thái: ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành
Đếm số câu SQL khi load 50 order kèm item; sửa và assert số query = 1.
Bài liên quan: N+1 query, Lazy loading
Hoàn thành khi:
- Test đếm query trước/sau
- SQL log trong evidence/
3. Intermediate: Locking
Trạng thái: ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành
Hai transaction cùng sửa một Product: @Version → ObjectOptimisticLockingFailureException; PESSIMISTIC_WRITE → transaction sau chờ.
Bài liên quan: Locking trong JPA, @Transactional và các bẫy, Propagation & rollback
Hoàn thành khi:
- Test cả hai chiến lược
- Giải thích khi nào chọn cái nào
4. Challenge: Keyset pagination
Trạng thái: ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành
Bảng 1 triệu dòng: đo trang 1 và trang 10 000 với OFFSET và với keyset (created_at, id); chèn dữ liệu đồng thời và chứng minh keyset không trùng/sót.
Bài liên quan: Phân trang & sort, Batch insert & hiệu năng
Hoàn thành khi:
- Bảng số đo
- Test không trùng/sót khi có insert
5. Tiêu chí hoàn thành chung
- Tự giải thích được bài toán và vì sao chọn giải pháp.
- Code chạy được bằng lệnh ghi trong README, không chứa secret.
- Có test tự động cho happy path và failure path.
- Có log hoặc số đo trong
evidence/chứng minh kết quả. - Có câu trả lời phỏng vấn ngắn bằng tiếng Việt và tiếng Anh.
- README của lab có link ngược về bài học tương ứng.
6. Lab và trạng thái
| Mức | Bài tập | Trạng thái | Test / bằng chứng |
|---|---|---|---|
| Basic | Bắt N+1 | ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành | — |
| Intermediate | Locking | ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành | — |
| Challenge | Keyset pagination | ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành | — |
Repo lab: java-backend-interview-labs/labs/spring-jpa. TODO: link GitHub là placeholder cho tới khi repo được push.
evidence/; chỉ đánh dấu xong khi có bằng chứng.Phỏng vấn hỏi về Spring Data JPA, câu nào hay gặp nhất và trả lời sao?
Q1. N+1 query là gì, xử lý thế nào?
🇻🇳 Tiếng Việt:
Load N bản ghi cha rồi mỗi bản ghi lại bắn 1 query lấy con, tổng N+1 query. Em sửa bằng fetch join hoặc @EntityGraph cho use case cần, hoặc batch fetch, và có test đếm số query để không tái phát.
🇬🇧 English:
Loading N parent rows and then one extra query per row for the children gives N+1 queries. I fix it with a fetch join or @EntityGraph for that use case, or batch fetching, and keep a test that counts queries to prevent regressions.
Cách nhớ ngắn gọn
- Mỗi bài tập = code + test + log.
- Luôn có ít nhất một failure case.
- Chưa có bằng chứng thì chưa xong.
Tự kiểm tra
Bài tập Basic (Bắt N+1) được coi là xong khi nào?
Test đếm query trước/sau; SQL log trong evidence/. Chưa có code chạy và bằng chứng thì chưa tính là xong.
Bài tập Intermediate (Locking) được coi là xong khi nào?
Test cả hai chiến lược; Giải thích khi nào chọn cái nào. Chưa có code chạy và bằng chứng thì chưa tính là xong.
Bài tập Challenge (Keyset pagination) được coi là xong khi nào?
Bảng số đo; Test không trùng/sót khi có insert. Chưa có code chạy và bằng chứng thì chưa tính là xong.