Sau khoảng 8–10 năm làm Java, câu hỏi không còn là:
“Bạn biết Spring Boot không?”
hay
“Bạn có dùng Kafka chưa?”
Mà chuyển thành:
“Bạn có thể design, scale, debug và vận hành một hệ thống production lớn không?”
Ở level này, kỹ sư không chỉ viết code tốt mà còn phải hiểu JVM, concurrency, distributed system, database consistency, system design, incident handling và trade-off kỹ thuật.
Trong bài viết này, mình sẽ tổng hợp những kỹ năng mà một Java Engineer nhiều năm kinh nghiệm nên thật sự nắm vững nếu muốn tiến tới Senior Staff / Principal Engineer / Architect.
1. Java Core – Không Chỉ Biết Dùng
Rất nhiều người làm Java nhiều năm nhưng kiến thức Java core vẫn dừng ở mức CRUD application.
Điều này thường bị lộ rất nhanh trong các buổi technical interview senior-level.
Những phần bắt buộc phải rất chắc
OOP và SOLID
Không chỉ thuộc định nghĩa.
Bạn cần trả lời được:
- Khi nào không nên áp dụng SOLID?
- Over abstraction gây hại như thế nào?
- Vì sao nhiều project bị “design pattern overkill”?
Một senior engineer phải biết cân bằng giữa:
clean architecture
vs
simple enough
equals() và hashCode()
Đây là câu hỏi interview kinh điển.
Bạn cần hiểu:
- Contract của equals/hashCode
- Tại sao HashMap phụ thuộc hashCode
- Điều gì xảy ra nếu override equals nhưng quên hashCode
Ví dụ bug production rất phổ biến:
Set<User> users = new HashSet<>();
users.add(new User(1L));
users.contains(new User(1L)); // false
Generic
Phải hiểu:
List<? extends Number>
List<? super Integer>
Wildcard covariance và contravariance.
Không chỉ biết syntax.
Immutable Object
Một senior engineer nên ưu tiên immutable object khi có thể.
Ví dụ:
public final class Money {
private final BigDecimal amount;
private final String currency;
}
Lợi ích:
- thread-safe
- tránh side effect
- dễ reasoning hơn
Stream API
Biết dùng nhưng không lạm dụng.
Bad:
orders.stream()
.filter(...)
.map(...)
.collect(...)
cho logic phức tạp gây khó debug.
Senior engineer phải biết:
khi nào stream làm code clean hơn
khi nào imperative code dễ maintain hơn
2. Concurrency – Skill Phân Biệt Senior Java Engineer
Đây là kỹ năng cực kỳ quan trọng với Java backend.
Nếu làm fintech/payment/high TPS system thì gần như bắt buộc phải mạnh.
Thread lifecycle
Hiểu rõ flow:
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
Race Condition
Ví dụ kinh điển:
Hai request rút tiền cùng lúc.
Cả hai đều check balance = 100.
Mỗi request trừ 80.
Kết quả:
Balance = -60
Senior engineer phải hiểu cách xử lý concurrency ở:
- JVM level
- Database level
- Distributed system level
Synchronized vs Lock
Hiểu:
synchronized
vs
ReentrantLock
Khi nào nên dùng cái nào?
synchronized
Ưu điểm:
- simple
- JVM optimized
ReentrantLock
Ưu điểm:
- tryLock()
- timeout
- fair lock
volatile
Câu hỏi rất phổ biến:
volatile có thread-safe không?
Câu trả lời:
Không.
Nó chỉ đảm bảo:
- visibility
- memory ordering
Không đảm bảo atomicity.
CAS (Compare-And-Swap)
Hiểu internals của:
AtomicInteger
Ví dụ:
count.incrementAndGet();
không dùng lock mà dùng CAS.
Câu hỏi thường gặp:
tại sao CAS nhanh hơn synchronized trong low contention?
CompletableFuture
Ở senior level phải dùng thành thạo.
Ví dụ:
Parallel external calls:
CompletableFuture<BalanceResult> balanceFuture =
CompletableFuture.supplyAsync(
() -> accountService.checkBalance(customerId),
executor
);
CompletableFuture<CardResult> cardFuture =
CompletableFuture.supplyAsync(
() -> cardService.checkCard(cardId),
executor
);
CompletableFuture.allOf(
balanceFuture,
cardFuture
).join();
Tối ưu latency:
200ms + 150ms = 350ms
thành:
max(200,150) = 200ms
Thread Pool Sizing
Một senior engineer phải hiểu:
CPU-bound:
N = CPU core
IO-bound:
N = CPU * (1 + waitTime / computeTime)
Sai thread pool sizing có thể dẫn đến:
- thread starvation
- OOM
- latency spike
Virtual Thread (Java 21+)
Một topic rất hot.
Hiểu:
- lightweight thread
- parking
- carrier thread
Khi nào phù hợp:
- IO-heavy system
Khi nào không nên dùng:
- CPU-intensive task
3. JVM – Debug Production Chứ Không Chỉ Học Lý Thuyết
Sau nhiều năm làm Java, JVM là thứ bắt buộc phải hiểu.
Nếu production memory leak mà không biết đọc heap dump thì rất khó lên senior staff level.
JVM Memory
Phải nắm:
Heap
- Young generation
- Old generation
Stack
Per-thread memory.
Metaspace
Chứa class metadata.
Garbage Collection
Hiểu flow:
Reachable
↓
Unreachable
↓
GC
Hiểu các collector:
G1GC
General purpose.
ZGC
Ultra-low latency.
Shenandoah
Low pause time.
Ví dụ:
Payment system yêu cầu:
P99 < 20ms
thì long GC pause là vấn đề nghiêm trọng.
ClassLoader
Một senior engineer phải giải thích được:
Parent Delegation Model
Tại sao:
String.class.getClassLoader()
trả về:
null
Debugging Production
Biết dùng:
jstack
thread dump.
jmap
heap dump.
jcmd
JVM diagnostic.
4. Spring Ecosystem – Không Chỉ CRUD
IOC & Bean Lifecycle
Hiểu flow:
Bean creation
↓
Dependency injection
↓
@PostConstruct
↓
Ready
AOP & Proxy
Senior engineer phải hiểu:
Spring AOP hoạt động bằng proxy.
JDK Dynamic Proxy:
interface-based
CGLIB:
subclass proxy
Transaction Internals
Câu hỏi rất phổ biến:
Tại sao self invocation làm @Transactional không hoạt động?
Ví dụ:
this.processPayment();
Không đi qua proxy.
Transaction bị bypass.
Isolation Level
Hiểu:
- READ COMMITTED
- REPEATABLE READ
- SERIALIZABLE
Ví dụ:
Banking transfer thường yêu cầu consistency cao.
5. Database – Senior Không Thể Yếu SQL
Index
Hiểu sâu:
Composite index
Ví dụ:
(customer_id, status, created_at)
Query nào dùng được?
✅ customer_id
✅ customer_id + status
❌ status only
MVCC
Hiểu:
Vì sao SELECT không bị block bởi UPDATE?
Locking
Optimistic lock
Version field.
Pessimistic lock
SELECT ...
FOR UPDATE
Ví dụ:
Money transfer thường dùng pessimistic lock.
Atomic Update
Ví dụ ATM withdrawal:
UPDATE account_balance
SET balance = balance - :amount
WHERE account_id = :id
AND balance >= :amount;
Đây là pattern cực kỳ phổ biến để tránh double spending.
6. Distributed System – Phần Khó Nhất
Đây là nơi phân biệt:
senior developer
và
principal engineer
CAP theorem
Hiểu trade-off:
Consistency
Availability
Partition tolerance
Không thể có cả 3.
Idempotency
Payment retry:
Partner timeout.
User retry lần 2.
Không được charge tiền 2 lần.
Pattern:
idempotency key
Retry Pattern
Không retry vô hạn.
Nên có:
exponential backoff
và:
dead letter queue
Circuit Breaker
External API timeout liên tục.
Nếu không có circuit breaker:
toàn bộ system có thể bị cascade failure.
Saga Pattern
Distributed transaction.
Hai kiểu:
choreography
Event-based.
orchestration
Central coordinator.
7. Kafka – Gần Như Bắt Buộc
Senior backend nên rất chắc Kafka.
Hiểu:
- partition
- ISR
- leader election
- consumer rebalance
- ordering guarantee
Case thực tế:
Duplicate event
Làm sao tránh double payment?
Hot partition
1 key quá nhiều message.
Scale thế nào?
8. Redis – Không Chỉ Cache
Các use case phổ biến:
Rate limit
Voucher claim once
Attendance system
Login session
Feed ranking
Hiểu:
cache penetration
cache breakdown
cache avalanche
9. Security – Đặc Biệt Nếu Làm Fintech
Hiểu:
JWT
Refresh token rotation
OAuth2
TLS handshake
RSA vs AES
bcrypt vs Argon2
Nếu làm payment:
Hiểu:
PCI-DSS
PAN masking
Tokenization
10. System Design – Skill Quan Trọng Nhất
Senior engineer nên design được:
- Payment system
- Wallet
- ATM withdrawal
- Notification system
- Audit log
- Chat system
- Rate limiter
Quan trọng nhất:
trade-off thinking
Ví dụ:
Kafka hay DB polling?
Sync hay async?
Redis hay DB?
Không có đáp án tuyệt đối đúng.
Điều quan trọng là:
hiểu cái giá phải trả của mỗi lựa chọn.
Kết Luận
Sau khoảng 8–10 năm làm Java, thứ tạo ra sự khác biệt không còn là:
biết nhiều framework
Mà là:
hiểu sâu hệ thống
Một senior/principal engineer nên tập trung vào:
- Java + JVM internals
- Concurrency
- Database consistency
- Distributed system
- System design
- Production debugging
- Security mindset
Framework có thể thay đổi.
Nhưng tư duy hệ thống và nền tảng kỹ thuật sẽ đi theo bạn rất lâu.
Be First to Comment