- Java là gì và vì sao đến nay vẫn được dùng rộng rãi?
Java là ngôn ngữ hướng đối tượng, strongly-typed, biên dịch ra bytecode và chạy trên JVM. Cùng một file .class có thể chạy trên nhiều hệ điều hành mà không cần biên dịch lại — đó là "Write Once, Run Anywhere" từ 1995, nay do…
- == và .equals() trong Java khác nhau thế nào?
== kiểm tra identity còn .equals() kiểm tra equality theo logic của class. Với primitive như int hay boolean, == so sánh giá trị thực. Với object, == so sánh reference — hai biến có trỏ tới cùng một instance trên heap hay không —…
- Java có phải ngôn ngữ thuần hướng đối tượng không?
Không. Java có primitive types (int, long, double, boolean, char...) sống song song với objects. Primitive không có method, không gán null được, và không kế thừa từ Object. Ngôn ngữ thuần OOP như Smalltalk coi mọi thứ là object — kể cả số 5…
- Bộ nhớ Stack và Heap trong Java khác nhau thế nào?
Stack là vùng nhớ mỗi thread có riêng, lưu biến local và tham chiếu, tự giải phóng khi method kết thúc theo LIFO. Heap là vùng nhớ dùng chung cho toàn JVM, lưu object thật và được Garbage Collector dọn. Hãy hình dung stack như…
- Năm đặc điểm nổi bật của Java là gì?
Java là ngôn ngữ lập trình hướng đối tượng, biên dịch ra bytecode chạy trên JVM, nổi bật với tính độc lập nền tảng, an toàn bộ nhớ, và hỗ trợ đa luồng mạnh. Hãy nghĩ Java như một bộ phim được quay thành phim…
- Tại sao String trong Java là immutable?
String immutable = sau khi tạo xong, nội dung không thể thay đổi; mọi thao tác như concat(), replace() đều trả về một object mới thay vì sửa tại chỗ. Lý do thiết kế: - String pool cần nó: JVM duy trì vùng cache (String…
- String, StringBuilder và StringBuffer khác nhau thế nào?
String là chuỗi bất biến (immutable) trong Java, còn StringBuilder và StringBuffer là hai lớp chuỗi mutable dùng khi bạn cần nối hoặc chỉnh sửa chuỗi nhiều lần. String sau khi tạo thì nội dung không đổi; mọi thao tác như + hay concat() đều…
- Constructor overloading là gì?
Constructor overloading là việc một class có nhiều constructor cùng tên với class nhưng khác danh sách tham số (kiểu, số lượng, hoặc thứ tự). Khi gọi new, compiler chọn constructor khớp với argument truyền vào. Cơ chế hoạt động giống method overloading: Java dùng…
- Các access modifier trong Java là gì? Giải thích từng loại.
Access modifier là từ khoá kiểm soát phạm vi truy cập của class, field, method, hoặc nested class trong Java. Có bốn mức, từ hẹp nhất đến rộng nhất: private, default (không ghi gì), protected, public. Bảng dưới tóm tắt mức truy cập: Modifier Cùng…
- Method overloading và method overriding khác nhau thế nào?
Hai khái niệm dễ nhầm — cùng chữ "over" nhưng giải quyết bài toán khác hẳn. Overloading Overriding --------- Scope Cùng class Subclass override method của parent Signature Khác tham số Trùng signature với parent Resolution Compile-time Runtime (dynamic dispatch) Polymorphism Static Dynamic (subtype) Quy…
- Bốn tính chất của OOP là gì?
Encapsulation — Inheritance — Polymorphism — Abstraction. - Encapsulation (Đóng gói): gom dữ liệu + method thao tác vào cùng class; kiểm soát truy cập qua private/protected, chỉ lộ ra method nghiệp vụ. Ví dụ repo pattern: phần còn lại của hệ thống gọi user.getName()…
- Static member là gì? Khi nào nên dùng?
Static member thuộc về class, không phải instance. Hình dung: private int balance là số dư riêng từng tài khoản; static int totalAccounts là một biến duy nhất dùng chung cho mọi Account. Khi nên dùng: - Utility/helper: Math.abs(), Collections.sort(). - Hằng số: static final…
- NullPointerException là gì và làm thế nào để phòng tránh?
NPE xảy ra khi gọi method/truy cập field/unbox primitive trên reference null. Tony Hoare gọi null là "lỗi tỷ đô" của mình. Phòng tránh, theo độ ưu tiên: 1. Thiết kế không nhận/trả null: dùng Optional<T, list rỗng List.of(), hoặc throw exception. Cách bền nhất.…
- this và super trong Java khác nhau thế nào?
- this = "chính tôi" — reference đến object hiện tại. - super = "phiên bản parent" — truy cập member cha đã bị override/che. this dùng cho: phân biệt field/param trùng tên, gọi constructor khác cùng class this(...), truyền chính object (register(this)), method chaining…
- Keyword final trong Java có mấy cách dùng?
Ba ngữ cảnh, cùng ý "không thể đổi" — nhưng "đổi" gì thì phụ thuộc: - final class — chống extends (vd String, Integer). Bảo vệ invariant + cho JIT inline mạnh hơn. - final method — chống override. Cho template method khung không cho…
- Abstract class và interface khác nhau thế nào?
Abstract class Interface --------- Kế thừa extends 1 cái implements nhiều Constructor Có Không State (instance field) Có Không — (chỉ hằng số) Default method (concrete) Có Có — (Java 8+) Ngữ nghĩa "is-a" "can-do" (capability) Khi nào chọn cái nào: - Abstract class: class…
- Stream API và lập trình hàm trong Java 8 là gì?
- Functional interface là gì? Lambda liên quan thế nào?
- Checked exception và unchecked exception khác nhau thế nào?
- Method reference trong Java là gì? Khác lambda thế nào?
- Optional class trong Java dùng để làm gì?
- Collections Framework trong Java là gì?
Collections Framework là kiến trúc thống nhất trong Java để lưu trữ và thao tác trên nhóm đối tượng, cung cấp các interface, implementation và utility dùng chung. Nó xuất hiện từ JDK 1.2 và là nền tảng cho hầu hết thao tác dữ liệu…
- ArrayList và LinkedList khác nhau thế nào?
ArrayList là mảng động, LinkedList là danh sách liên kết đôi (doubly-linked list). Khác biệt cốt lõi nằm ở cấu trúc dữ liệu bên trong: ArrayList lưu phần tử liên tục trong một mảng, còn LinkedList lưu mỗi phần tử trong một node riêng có…
- HashSet và TreeSet khác nhau thế nào?
HashSet TreeSet --------- Cấu trúc Hash table Red-black tree add/contains O(1) trung bình O(log n) Thứ tự duyệt Không xác định Sắp xếp Null 1 element null Không — (NPE) Yêu cầu hashCode() + equals() đúng Comparable hoặc Comparator API extra — first, last, subSet,…
- HashMap và TreeMap khác nhau thế nào?
HashMap TreeMap --------- Cấu trúc Hash table (Java 8+: bucket nhiều entry → red-black tree) Red-black tree get/put O(1) trung bình O(log n) Thứ tự key Không xác định Sắp xếp Null key 1 cái Không Extra API — firstKey, floorKey, subMap, tailMap Khi dùng:…
- HashSet và HashMap khác nhau thế nào?
Khác mục đích, nhưng bên dưới thực chất là cùng một thứ. HashSet<E HashMap<K,V --------- Implements Set Map Lưu trữ Phần tử duy nhất Cặp key → value Method add, contains, remove put, get, remove Thực ra: HashSet chỉ là wrapper của HashMap — value…
- Iterator interface là gì và tại sao nên dùng?
Iterator<E là interface duyệt collection mà không cần biết cấu trúc bên trong (mảng, linked list, tree...). Lý do quan trọng nhất — xoá an toàn: đoạn sau throw ConcurrentModificationException: Phải dùng iterator.remove() hoặc list.removeIf(String::isEmpty). Lưu ý: - Enhanced for-loop thực ra là syntactic sugar…
- Fail-fast và fail-safe iterator khác nhau thế nào?
Ba mức xử lý "collection bị sửa trong khi đang duyệt": Fail-fast Fail-safe (snapshot) Weakly-consistent ------------ Ví dụ ArrayList, HashMap CopyOnWriteArrayList ConcurrentHashMap Behavior Throw ConcurrentModificationException Duyệt bản sao, không throw, không thấy thay đổi mới Không throw, có thể thấy hoặc không thấy thay đổi…
- Comparable và Comparator khác nhau thế nào?
Comparable<T Comparator<T --------- Đặt ở Bên trong class T Bên ngoài, class riêng/lambda Method int compareTo(T o) int compare(T a, T b) Số cách sắp xếp Một (natural ordering) Nhiều strategy Return value: âm = this đứng trước, 0 = bằng, dương = đứng sau.…
- Queue interface là gì và khi nào nên dùng?
Queue<E là collection FIFO (First-In-First-Out) — "xếp hàng". API có 2 phiên bản: Thao tác Throw exception Return special value --------- Insert add(e) offer(e) → false nếu full Remove remove() → NSEE poll() → null nếu rỗng Peek element() → NSEE peek() → null nếu…
- ConcurrentHashMap khác Hashtable thế nào?
Cả 2 thread-safe, nhưng cách hoàn toàn khác. Hashtable (legacy) ConcurrentHashMap (Java 5+) --------- Lock synchronized toàn method — 1 thread tại 1 thời điểm Bucket-level + CAS (lock-free read) Throughput multi-thread Thấp (contention cao) Cao hơn nhiều lần Iterator Fail-fast → CME Weakly-consistent —…
- Generics và type erasure trong Java là gì?
- Kế thừa (Inheritance) trong Java có mấy loại?
4 dạng theo lý thuyết — thực tế chỉ 3 vì Java không cho multiple class inheritance. Vì sao cấm multiple class inheritance? Diamond problem — nếu D extends B, C mà cả 2 đều có method m(), không rõ gọi version nào. C++ cho…
- Liskov Substitution Principle (LSP) là gì?
LSP (chữ "L" trong SOLID, Barbara Liskov 1987): subtype phải thay thế được supertype mà không phá hành vi chương trình. Code chạy với Animal phải chạy đúng khi đưa Dog vào — không bug bất ngờ. Ví dụ kinh điển vi phạm — Square…
- Polymorphism là gì? Giải thích compile-time và runtime polymorphism.
Polymorphism ("nhiều hình thức") — cùng interface có nhiều hành vi khác nhau. Java có 2 loại: 1. Compile-time — Method overloading: cùng tên, khác signature → compiler chọn lúc biên dịch. 2. Runtime — Method overriding: subclass có version riêng → JVM dispatch theo…
- Abstract class là gì? Khi nào nên dùng?
Abstract class không tạo instance trực tiếp được — chỉ làm template cho subclass. Subclass phải implement các abstract method. Đặc điểm: có constructor, có state (instance field), trộn abstract + concrete method, dùng đủ access modifier. Chỉ 1 parent. Khi nào chọn abstract class…
- Interface là gì? Java 8 thay đổi gì với interface?
Interface định nghĩa contract — danh sách method mà implementation phải cung cấp. Tách "làm được gì" khỏi "làm thế nào". Một class implements nhiều interface. Lịch sử tiến hoá: Phiên bản Thêm gì ------ Java ≤ 7 Chỉ public abstract method + public static…
- SOLID principles là gì? Giải thích S và O.
SOLID là 5 nguyên tắc thiết kế OOP (Robert C. Martin): S Single Responsibility, O Open/Closed, L Liskov Substitution, I Interface Segregation, D Dependency Inversion. S — Single Responsibility: Một class chỉ có một lý do để thay đổi. Không phải "1 class = 1…
- Singleton pattern là gì?
Singleton giới hạn class chỉ có đúng 1 instance trong app, cung cấp điểm truy cập toàn cục. Dùng cho: logger, config, DB connection pool, cache. Các cách implement, từ đơn giản đến tốt nhất: 1. Eager — đơn giản, thread-safe nhờ JVM. Nhược: tạo…
- Factory pattern là gì?
Factory tách "tạo object" khỏi "dùng object". Caller không gọi new ConcreteClass() mà gọi factory; factory quyết định trả về concrete nào. Vì sao cần: thay implementation, ẩn complexity, cache/pool, dễ test (mock factory). 3 biến thể chính: 1. Simple Factory: 2. Factory Method (GoF):…
- Composition và Inheritance — khi nào nên dùng cái nào?
Inheritance ("is-a") Composition ("has-a") --------- Cơ chế class B extends A class B { A a; } Coupling Chặt — biết internal parent Lỏng — chỉ phụ thuộc interface Đổi runtime Không Có (đổi member) Nguyên tắc Effective Java: Favor composition over inheritance. Ví dụ…
- Method hiding là gì? Khác method overriding thế nào?
Method hiding xảy ra khi subclass khai báo static method trùng signature parent → không override mà che giấu. JVM dispatch theo kiểu reference (compile-time). Hiding Overriding --------- Áp dụng static method Instance method Dispatch Theo reference type Theo object type (vtable) @Override Không Có…
- Diamond problem trong Java và cách Java xử lý?
- Java 8 interface default methods và static methods?
- Thread là gì? Có mấy cách tạo thread trong Java?
Thread là đơn vị thực thi cho phép chạy code song song. Mỗi Java app đã có main thread; tạo thêm thread để task không block main. 4 cách tạo, từ cũ → hiện đại: 1. Extend Thread (hiếm dùng — chiếm slot extends). 2.…
- Synchronization là gì và khi nào nên dùng?
Synchronization đảm bảo chỉ một thread vào critical section tại một thời điểm — ngăn race condition khi nhiều thread share state. Keyword synchronized dùng intrinsic lock của object: Vì sao phải sync count++? Compile thành 3 bytecode op (read → add → write). 2…
- Deadlock là gì? Làm thế nào để phòng tránh?
Deadlock xảy ra khi nhiều thread chờ lock của nhau theo vòng tròn — tất cả block vĩnh viễn. App không crash, không exception, chỉ "đứng hình". 4 điều kiện Coffman (phải đủ cả 4): mutual exclusion, hold-and-wait, no preemption, circular wait. Phá circular wait…
- ExecutorService là gì? Khác tạo thread thủ công thế nào?
ExecutorService (Java 5+) quản lý thread pool — bạn submit Runnable/Callable, executor lo phần còn lại. new Thread() thủ công burst 10K request → 10K OS thread → OOM. Không reuse, không backpressure. Factory trong Executors: Factory Khi dùng ------ newFixedThreadPool(n) CPU-bound newCachedThreadPool() Task ngắn,…
- volatile keyword trong Java là gì?
volatile đảm bảo visibility giữa các thread — mọi read/write đi thẳng main memory, không qua CPU cache. Đây là keyword nhẹ nhất trong concurrency toolbox. Không có volatile, JVM/CPU có thể cache biến → thread A đổi nhưng thread B vẫn thấy giá trị…
- Future và CompletableFuture khác nhau thế nào?
Future (Java 5) đại diện cho kết quả async. Hạn chế: get() block, không chain được, exception handling khó. CompletableFuture (Java 8+) khắc phục: non-blocking, chain được, xử lý exception sạch. Operator phổ biến: thenApply (map), thenCompose (flatMap), thenAccept (consumer), thenCombine (zip 2 CF), handle…
- Race condition là gì và làm thế nào để phòng tránh?
Race condition xảy ra khi nhiều thread truy cập shared data đồng thời, kết quả cuối phụ thuộc vào thứ tự thực thi → không thể đoán trước. Phòng tránh, theo thứ tự ưu tiên: 1. Atomic variables: AtomicInteger.incrementAndGet() — lock-free, CAS. 2. synchronized /…
- synchronized và volatile khác nhau thế nào? Khi nào dùng cái nào?
- Happens-before relationship trong Java là gì?
- CountdownLatch và CyclicBarrier khác nhau thế nào?
- JVM, JRE và JDK khác nhau thế nào?
- JVM (Java Virtual Machine): thực thi bytecode, platform-specific (mỗi OS có JVM riêng), cung cấp runtime + GC + JIT. - JRE (Java Runtime Environment): JVM + thư viện chuẩn. Chạy được app Java đã biên dịch, không biên dịch được. - JDK (Java…
- Quá trình Garbage Collection hoạt động thế nào?
GC tự động thu hồi bộ nhớ từ object không còn được tham chiếu — Java dev không cần free() thủ công. 3 bước cốt lõi: 1. Marking — duyệt object graph từ GC roots (stack frame, static field, JNI ref), đánh dấu object reachable.…
- Generational Garbage Collection là gì?
Heap chia thành 2 region dựa trên tuổi object: Lý do (weak generational hypothesis): hầu hết object chết trẻ — tạo rồi mất ngay (vd biến local trong method). Quá trình: 1. Object tạo mới vào Eden. 2. Minor GC chạy thường xuyên ở Young…
- OutOfMemoryError là gì và làm thế nào để phòng tránh?
OutOfMemoryError (OOM) xảy ra khi JVM không cấp phát được bộ nhớ — heap đầy, GC không giải phóng đủ. Các loại OOM thường gặp: - Java heap space — heap đầy. Phổ biến nhất. - GC overhead limit exceeded — GC chạy 98% thời…
- Memory leak trong Java là gì? GC có thu hồi được không?
Memory leak Java: object vẫn còn reference nhưng không còn cần — GC không thể collect (vì nguyên tắc GC: chỉ thu hồi object unreachable). Nguyên nhân phổ biến: - Unclosed resource: file handle, DB connection, network socket. - Listener không unregister: subject giữ reference…
- Stack overflow và heap overflow khác nhau thế nào?
Stack overflow Heap overflow --------- Vùng nhớ Stack (per-thread, ~512KB-1MB) Heap (shared, GB) Nguyên nhân Đệ quy quá sâu, method call lồng Quá nhiều object/memory leak Exception StackOverflowError OutOfMemoryError: Java heap space Phát hiện Nhanh, rõ (stack trace dài) Chậm, GC chạy hoài rồi mới…
- ClassLoader là gì và có mấy loại?
ClassLoader tải file .class vào memory lúc runtime. 3 loại built-in (theo hierarchy): 1. Bootstrap ClassLoader — JVM built-in (C++), tải core class trong java.lang, java.util (rt.jar / Java 9+ module). 2. Platform ClassLoader (Java 9+, trước là Extension) — tải các module platform không…
- Reflection trong Java là gì và dùng khi nào?
- Virtual Threads là gì và chúng giải quyết vấn đề gì của Java?
Virtual Threads (Project Loom, Java 21 GA) là thread nhẹ do JVM quản lý — chạy hàng triệu thread trên chỉ vài OS thread. Vấn đề trước Java 21: Platform Thread = 1:1 với OS thread, ~1MB stack. Server muốn xử lý 10K request đồng…
- Records trong Java là gì? Khi nào nên dùng Record thay vì class thông thường?
Record (Java 16+ — JEP 395) là class đặc biệt cho dữ liệu bất biến. Một dòng thay 50 dòng POJO. Compiler tự sinh: constructor canonical, accessor name() / age() (không có "get"), equals / hashCode / toString, field ngầm private final. Tuỳ biến qua…
- Sealed Classes là gì và tại sao dùng kết hợp với Pattern Matching?
Sealed class (Java 17+) hạn chế những class nào được phép extend nó, khai báo qua permits. Mỗi subclass phải là final, sealed hoặc non-sealed. Lợi ích lớn nhất là khi ghép với Pattern Matching: compiler biết đủ mọi subtype nên kiểm tra được exhaustiveness…
- GraalVM Native Image cải thiện Spring Boot như thế nào và có những thách thức gì?
- So sánh G1GC, ZGC và Shenandoah: workload nào phù hợp với từng GC?
- Làm thế nào để chẩn đoán memory leak trong production bằng heap dump và profiling tools?
- Text block (`"""..."""`) trong Java là gì, giải quyết vấn đề gì?
Text block (Java 15 — JEP 378) là chuỗi nhiều dòng bọc trong """, viết JSON/SQL/HTML mà không phải nối + và escape \n thủ công. Kết quả vẫn là String thông thường, không phải kiểu mới. Compiler tự cắt indent chung của cả khối…
- Pattern matching for switch (Java 21) thay đổi cách viết switch như thế nào?
Pattern matching for switch (Java 21 — JEP 441) cho switch test theo kiểu, vừa bind biến đã ép kiểu, vừa cho thêm when lọc — gom được chuỗi if-instanceof dài. Kết hợp với sealed: compiler bắt buộc xử lý mọi subtype, bỏ sót là…
- equals() và hashCode() có contract gì với nhau? Tại sao phải override cả hai?
Contract Java quy định: 1. Nếu a.equals(b) == true → a.hashCode() == b.hashCode() bắt buộc. 2. Ngược lại không bắt buộc — hai object khác nhau có thể có cùng hashCode (hash collision). Vì sao phải override cả hai: HashMap/HashSet tìm bucket bằng hashCode() trước,…
- Comparable và Comparator trong Java khác nhau thế nào?
Comparable Comparator --------- Package java.lang java.util Method compareTo(T o) compare(T o1, T o2) Implement ở đâu Bên trong class Class riêng / lambda Thứ tự Natural ordering (1 cách) Custom ordering (nhiều cách) Sửa class gốc Bắt buộc Không cần Khi nào dùng cái nào:…
- final, finally và finalize khác nhau thế nào?
Ba từ khoá không liên quan nhau dù tên giống — câu này kiểm tra độ nắm chắc khái niệm cơ bản. - final — modifier: biến không gán lại được, method không override được, class không kế thừa được (chi tiết xem câu keyword…
- wait() và sleep() khác nhau thế nào?
wait() sleep() --------- Thuộc Object (instance method) Thread (static method) Monitor lock Nhả lock khi chờ Giữ nguyên lock Đánh thức notify()/notifyAll() hoặc timeout Hết thời gian Điều kiện gọi Phải trong synchronized (không thì IllegalMonitorStateException) Gọi ở đâu cũng được Dùng cho Phối hợp…
- Java là pass-by-value hay pass-by-reference?
Java luôn luôn pass-by-value — không có pass-by-reference. Điểm gây nhầm: với object, thứ được copy là giá trị của reference (địa chỉ trỏ đến object), không phải bản thân object. Hệ quả: - Method sửa được trạng thái object của caller (vì 2 reference…
- HashMap hoạt động bên trong như thế nào?
Cấu trúc lõi: mảng bucket; entry được đặt vào bucket theo hash(key) & (n - 1) (n = capacity, luôn là luỹ thừa của 2). put(key, value): 1. Tính hash từ hashCode() của key (JDK trộn thêm bit cao để giảm collision). 2. Định vị…
- String pool trong Java là gì? "abc" và new String("abc") khác gì nhau?
String pool (string constant pool) là vùng cache trong heap chứa các String literal — các literal giống nhau dùng chung 1 object. - String a = "hello" → JVM tìm trong pool: có rồi thì trả reference cũ → "hello" == "hello" cho true…
- Làm thế nào để viết một immutable class trong Java?
Immutable class = object không đổi trạng thái sau khi tạo. Quy tắc viết: 1. Class khai báo final — chặn subclass override method làm lộ/đổi state. 2. Mọi field private final. 3. Không có setter — state chỉ gán 1 lần qua constructor. 4.…
- Shallow copy và deep copy khác nhau thế nào?
Shallow copy Deep copy --------- Copy gì Object ngoài cùng; field object bên trong dùng chung reference Đệ quy copy toàn bộ object graph Hệ quả Sửa object con → cả 2 bản cùng thấy 2 bản độc lập hoàn toàn Chi phí Rẻ Đắt…
- JIT compilation là gì và JVM dùng nó thế nào?
JIT (Just-In-Time) compiler biên dịch bytecode → mã máy native ngay lúc chạy, thay vì thông dịch từng lệnh. JVM khởi động ở chế độ interpreter (chạy ngay, không cần warm-up) và song song đếm số lần mỗi method/vòng lặp chạy. Khi vượt ngưỡng ("hot"),…
- Wrapper class là gì, autoboxing/unboxing hoạt động ra sao?
Wrapper class là bản "đóng gói object" của primitive: int→Integer, double→Double, boolean→Boolean... Cần chúng vì Collections/Generics chỉ nhận object (List<Integer, không có List<int). - Autoboxing: compiler tự chèn Integer.valueOf(x) khi gán primitive vào chỗ cần object. - Unboxing: tự chèn i.intValue() ở chiều ngược lại.…
- `>>` và `>>>` khác nhau thế nào?
Cả hai dịch bit sang phải; khác ở bit điền vào bên trái: - (signed / arithmetic): điền bằng bit dấu → số âm vẫn âm. - (unsigned / logical): luôn điền 0 → kết quả không bao giờ âm. Với số dương, hai toán…
- Covariant return type là gì?
Covariant return = khi override một method, class con được phép trả về kiểu con (subtype) của kiểu mà method cha khai báo, thay vì đúng y kiểu đó. Có từ Java 5. Trước Java 5 phải trả đúng Animal, buộc caller ép kiểu (Cat).…
- Từ khoá `transient` là gì, ảnh hưởng tới serialization ra sao?
transient đánh dấu một field không tham gia serialization. Khi object được ObjectOutputStream ghi ra byte, field transient bị bỏ qua; lúc deserialize nó nhận giá trị mặc định (0, false, null). Dùng khi field: (1) nhạy cảm (password, token) không nên nằm trong file/luồng;…
- Marker interface là gì (Serializable, Cloneable)?
Marker interface là interface rỗng (không method) — chỉ dùng để gắn nhãn một class, báo cho JVM/thư viện rằng class đó có một tính chất nào đó. Ví dụ chuẩn: Serializable, Cloneable, RandomAccess. Cơ chế: code khác kiểm tra bằng instanceof. ObjectOutputStream gặp object…
- Vì sao không tạo được generic array trong Java?
- Khi nào và vì sao dùng private constructor?
Đặt constructor private để cấm bên ngoài new trực tiếp, giành lại quyền kiểm soát cách tạo object. Các trường hợp dùng: - Utility class toàn static (như Math, Collections): private constructor để không ai lỡ new. - Singleton: chỉ một instance, lấy qua getInstance().…
- ArrayList tự tăng dung lượng (grow/resize) nội bộ thế nào?
ArrayList bọc một mảng Object[]. Khi add mà mảng đã đầy, nó cấp mảng mới lớn hơn rồi copy toàn bộ phần tử sang. - Khởi tạo mặc định là rỗng; lần add đầu tiên cấp dung lượng 10. - Khi đầy, dung lượng mới…
- Cạm bẫy của clone()/Cloneable là gì và giải pháp thay thế?
- Vì sao `Integer a = 127, b = 127` thì `a == b` ra true, còn với 128 lại ra false?
Vì autoboxing không gọi new Integer(...) mà gọi Integer.valueOf(int), và method này trả về object lấy từ cache với các giá trị nhỏ. - JLS 5.1.7 bắt buộc cache cho boolean, byte, char trong \u0000–\u007f, và short/int trong -128..127. Trong dải này, hai lần boxing…
- Xoá phần tử khi đang duyệt bằng for-each thì gặp lỗi gì? Cách xoá đúng là gì?
Gặp ConcurrentModificationException. Iterator của các collection trong java.util là fail-fast: nó nhớ modCount lúc tạo và so lại ở mỗi lần next(); gọi list.remove(...) trực tiếp làm modCount lệch → ném exception ngay. Ba cách xoá đúng: Lưu ý thêm: xoá phần tử áp chót…
- `Arrays.asList()` trả về List loại gì? Vì sao gọi `add()` lại ném `UnsupportedOperationException`?
Arrays.asList() trả về một view kích thước cố định (java.util.Arrays$ArrayList, không phải java.util.ArrayList) bọc quanh mảng gốc. Nó không có chỗ để chứa thêm phần tử nên add/remove/clear ném UnsupportedOperationException. So với List.of() (Java 9+): - Arrays.asList(): cố định kích thước nhưng set() được, cho…
- Vì sao `0.1 + 0.2 != 0.3` trong Java? Tính tiền thì nên dùng kiểu gì?
double/float theo chuẩn IEEE 754 nhị phân. Số 0.1 và 0.2 là phân số tuần hoàn trong hệ nhị phân nên chỉ được lưu xấp xỉ; cộng lại ra 0.30000000000000004. Với tiền, dùng một trong hai cách: 1. BigDecimal khởi tạo bằng chuỗi, không bằng…
- Từ Java 8, HashMap xử lý bucket bị đụng độ nhiều như thế nào?
Trước Java 8, mọi entry trùng bucket nằm trên một danh sách liên kết → tra cứu xấu nhất là O(n). Từ Java 8, HashMap chuyển bucket thành cây đỏ-đen (red-black tree) khi bucket quá dài: - TREEIFYTHRESHOLD = 8: bucket có từ 8 node…
- Dùng object mutable làm key của HashMap thì chuyện gì xảy ra?
Entry sẽ không tìm lại được dù vẫn nằm trong map. HashMap tính bucket một lần lúc put; nếu sau đó bạn đổi field tham gia hashCode(), giá trị hash mới trỏ sang bucket khác nên get() tìm nhầm chỗ. Hệ quả: - get, containsKey,…
- Cài LRU cache chỉ bằng thư viện chuẩn của Java thì làm thế nào?
Dùng LinkedHashMap với access-order rồi override removeEldestEntry. Cơ chế: - Constructor 3 tham số với accessOrder = true khiến mỗi lần get/put đẩy entry được truy cập về cuối danh sách liên kết nội bộ. Entry ở đầu là entry lâu chưa dùng nhất. -…
- `Collectors.toMap()` có hai cạm bẫy nào khi gom List thành Map?
1. Trùng key ném IllegalStateException. Bản 2 tham số không có cách xử lý va chạm nên nó ném luôn: Sửa bằng tham số thứ ba — merge function — quyết định giữ giá trị nào: 2. Value null ném NullPointerException. toMap dùng map.merge(...) bên…
- Stream có dùng lại được không? Vì sao code có `filter`/`map` mà không thấy chạy?
Không dùng lại được. Mỗi stream chỉ đi qua một thao tác terminal; gọi lần hai ném IllegalStateException: stream has already been operated upon or closed. Không thấy chạy là vì stream lười (lazy): filter, map, peek, sorted chỉ mô tả pipeline. Không có thao…
- try-with-resources khác try/finally thế nào? Suppressed exception là gì?
try-with-resources (Java 7) tự gọi close() cho mọi resource khai báo trong ngoặc, theo thứ tự ngược với thứ tự khai báo, kể cả khi có exception. Điểm khác quan trọng nằm ở tình huống cả khối try lẫn close() cùng ném exception: Suppressed exception…
- Nối chuỗi bằng `+` trong vòng lặp có vấn đề gì? Compiler dịch `a + b` thành gì?
String bất biến nên mỗi phép + tạo ra một chuỗi mới và copy toàn bộ nội dung cũ. Trong vòng lặp n lần, tổng khối lượng copy là O(n²). Compiler dịch thành gì: - Trước Java 9: javac tự đổi a + b +…
- PECS là gì? Khi nào dùng `? extends T`, khi nào dùng `? super T`?
- Gặp `IllegalArgumentException: Comparison method violates its general contract!` khi sort thì nguyên nhân là gì?
- Trong `equals()` nên kiểm tra kiểu bằng `instanceof` hay `getClass()`?
- `orElse` và `orElseGet` khác nhau ra sao? Dùng Optional sai cách kiểu nào hay gặp?
- `String.intern()` làm gì? String pool nằm ở đâu và đã thay đổi thế nào qua các bản Java?
- Một thread trong Java đi qua những trạng thái nào?
Enum Thread.State định nghĩa 6 trạng thái: - NEW — đã new Thread(...) nhưng chưa gọi start(). - RUNNABLE — đang chạy hoặc đang chờ CPU cấp slot. JVM gộp hai tình huống này làm một, không có trạng thái "RUNNING" riêng. - BLOCKED —…
- `Runnable` và `Callable` khác nhau thế nào?
Khác ở giá trị trả về và cách lỗi được truyền đi. Runnable.run() Callable.call() --------- Trả về void V (generic) Checked exception không ném được throws Exception Nộp cho pool execute() hoặc submit() chỉ submit() Kết quả không có Future<V Điểm dễ vấp trong thực…
- Daemon thread khác user thread thế nào?
JVM chỉ chờ user thread. Khi user thread cuối cùng kết thúc, JVM thoát và giết ngay mọi daemon thread đang chạy dở. Hệ quả quan trọng: daemon bị dừng đột ngột, finally và shutdown logic có thể không chạy. Vì vậy không dùng daemon…
- Khi nào một object đủ điều kiện bị GC thu hồi? Gọi `System.gc()` có ép GC chạy ngay không?
Object đủ điều kiện thu hồi khi không còn đường đi tới nó từ GC root nào. GC root gồm: biến local trên stack của thread đang sống, static field, tham chiếu từ JNI, và chính các thread đang chạy. Đây là reachability, không phải…
- `synchronized` và `ReentrantLock` khác nhau thế nào? Khi nào chọn cái nào?
Cả hai đều đảm bảo loại trừ lẫn nhau và đều reentrant. Khác ở mức độ điều khiển. synchronized ReentrantLock --------- Nhả lock tự động khi ra khỏi khối phải unlock() trong finally Thử lấy lock không tryLock(), tryLock(timeout) Chờ có thể huỷ không lockInterruptibly()…
- Lock ở mức instance và lock ở mức class (`static synchronized`) khác nhau thế nào?
Khác ở object nào đang giữ monitor. - Method instance synchronized → khoá trên this. Mỗi instance một lock riêng. - Method static synchronized → khoá trên đối tượng Counter.class. Một lock duy nhất cho toàn bộ class, dùng chung giữa mọi instance. Hệ quả…
- Làm thế nào để dừng một thread đang chạy? Vì sao `Thread.stop()` bị loại bỏ?
Java không có cách dừng cưỡng bức an toàn. Cơ chế chính thức là hợp tác (cooperative): gửi tín hiệu, thread tự thoát ở điểm nó chọn. Thread.stop() bị deprecate từ lâu và nay ném UnsupportedOperationException vì nó nhả toàn bộ monitor mà thread đang…
- Chọn số thread cho thread pool thế nào? Task CPU-bound và IO-bound khác nhau ra sao?
Xuất phát từ tỉ lệ thời gian chờ trên thời gian tính toán của task, công thức tham chiếu của Brian Goetz: - Ncpu = Runtime.getRuntime().availableProcessors() - Ucpu = mức sử dụng CPU mục tiêu (0..1) - W/C = thời gian chờ / thời gian…
- `ThreadPoolExecutor` có những tham số nào? Vì sao nhiều nơi khuyên không dùng `Executors.newFixedThreadPool()`?
Tham số chính: corePoolSize, maximumPoolSize, keepAliveTime, workQueue, threadFactory, RejectedExecutionHandler. Thứ tự xử lý một task mới hay bị hiểu sai: 1. Đang chạy < corePoolSize → tạo thread mới. 2. Đủ core rồi → đẩy vào workQueue. 3. Queue đầy → mới tạo thêm thread…
- `thenApply`, `thenCompose`, `thenCombine` khác nhau thế nào? Callback chạy trên thread nào?
Ba toán tử ghép khác nhau ở kiểu (signature) của hàm truyền vào: - thenApply(Function<T, U) — biến đổi kết quả đồng bộ. Giống map. - thenCompose(Function<T, CompletionStage<U) — hàm trả về một future khác, kết quả được làm phẳng. Giống flatMap. Dùng thenApply ở…
- Metaspace là gì? Khác PermGen thế nào và khi nào gặp `OutOfMemoryError: Metaspace`?
Metaspace là vùng chứa metadata của class (cấu trúc class, method, constant pool đã phân giải), thay cho PermGen từ Java 8 (JEP 122). PermGen (≤ Java 7) Metaspace (Java 8+) --------- Vị trí nằm trong heap native memory, ngoài heap Kích thước cố định…
- Vì sao double-checked locking không có `volatile` là sai? Java Memory Model liên quan thế nào?
- `ConcurrentHashMap` đảm bảo thread-safe bằng cách nào? Vì sao `if (!map.containsKey(k)) map.put(k, v)` vẫn sai?
- `ThreadLocal` gây rò rỉ bộ nhớ khi dùng với thread pool như thế nào? Vì sao phải gọi `remove()`?
- CAS hoạt động thế nào trong `AtomicInteger`? ABA problem là gì và khi nào nên dùng `LongAdder`?
- Pinning trong virtual thread (Java 21) là gì? Vì sao không nên pool virtual thread?