1. WeakHashMap là gì?
WeakHashMap là một triển khai của giao diện Map
trong Java, trong đó các khóa (keys) được giữ bằng weak references (tham chiếu yếu). Điều này có nghĩa là nếu không còn bất kỳ tham chiếu mạnh nào (strong references) trỏ đến một khóa cụ thể, thì khóa và cặp khóa-giá trị tương ứng có thể bị thu gom rác (garbage collected) ngay cả khi nó vẫn tồn tại trong WeakHashMap. Điều này khác với các Map thông thường, như HashMap
, nơi các khóa không bị thu gom cho đến khi chúng bị xóa thủ công.
2. Các đặc điểm chính của WeakHashMap
2.1 Weak References (Tham chiếu yếu)
- Các khóa trong
WeakHashMap
được giữ bằng các tham chiếu yếu có nghĩa là bộ dọn rác (Garbage Collector – GC) có thể thu gom các mục của Map nếu không có tham chiếu mạnh nào trỏ đến khóa. - Khi khóa bị GC thu gom, cặp khóa-giá trị đó sẽ bị xóa khỏi WeakHashMap một cách tự động.
2.2 Garbage Collection
WeakHashMap giúp ngăn ngừa rò rỉ bộ nhớ (memory leaks) vì nó cho phép thu gom các mục khi khóa không còn được sử dụng ở bất kỳ đâu khác trong ứng dụng.
2.3 Ứng dụng
WeakHashMap thường được sử dụng khi bạn muốn lưu trữ các đối tượng tạm thời và không muốn chúng làm ảnh hưởng đến hiệu suất bộ nhớ bằng cách không để lại các tham chiếu mạnh, ví dụ như cache hoặc bộ nhớ đệm.
– Ví dụ:
import java.util.WeakHashMap; public class App { public static void main(String[] args) { WeakHashMap<String, String> weakMap = new WeakHashMap<>(); // Tạo một đối tượng khóa và thêm nó vào WeakHashMap String key1 = new String("Key1"); String value1 = "Value1"; weakMap.put(key1, value1); // Tạo một đối tượng khác và thêm vào WeakHashMap String key2 = new String("Key2"); String value2 = "Value2"; weakMap.put(key2, value2); // In WeakHashMap trước khi GC thu gom System.out.println("Before GC: " + weakMap); // Loại bỏ tham chiếu mạnh đến key1 key1 = null; // Yêu cầu bộ dọn rác chạy System.gc(); // Đợi một thời gian để GC hoàn thành try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // In WeakHashMap sau khi GC có thể đã thu gom key1 System.out.println("After GC: " + weakMap); } }
– Kết quả:
Before GC: {Key1=Value1, Key2=Value2} After GC: {Key2=Value2}
Trong ví dụ này, khi bộ dọn rác chạy, key1
sẽ bị thu gom vì không còn tham chiếu mạnh nào trỏ tới nó. Sau đó, mục chứa key1
sẽ tự động bị loại khỏi WeakHashMap.
3. Khi nào nên sử dụng WeakHashMap?
- Cache tạm thời: WeakHashMap thường được sử dụng cho các cấu trúc lưu trữ tạm thời, ví dụ như cache, nơi bạn không muốn các đối tượng không còn được sử dụng nữa làm tốn bộ nhớ.
- Khi muốn tránh rò rỉ bộ nhớ: Khi bạn lưu trữ các đối tượng phụ thuộc vào sự tồn tại của các đối tượng khác và không muốn giữ chúng lại sau khi các đối tượng gốc bị hủy bỏ.
4. Câu hỏi phỏng vấn WeakHashMap
1. WeakHashMap là gì và đặc điểm nổi bật của nó là gì?
Trả lời:
WeakHashMap
là một triển khai của giao diện Map
trong Java, trong đó các khóa được lưu trữ dưới dạng WeakReference
. Điều này có nghĩa là khi không còn bất kỳ tham chiếu mạnh (strong reference) nào tới một khóa trong WeakHashMap
thì khóa và giá trị của nó sẽ có thể bị thu gom bởi Garbage Collector. Điểm nổi bật là WeakHashMap
giúp quản lý bộ nhớ hiệu quả hơn khi cần lưu trữ tạm thời.
2. WeakHashMap khác gì so với HashMap?
Trả lời:
Trong HashMap
, các khóa được lưu trữ dưới dạng tham chiếu mạnh, nên sẽ không bị thu gom rác cho đến khi bị xóa thủ công. Trong WeakHashMap
, các khóa là tham chiếu yếu, cho phép thu gom rác tự động khi không còn tham chiếu mạnh nào tới khóa. Điều này giúp tránh các tình trạng rò rỉ bộ nhớ (memory leak).
3. WeakReference là gì và tại sao WeakHashMap lại dùng nó cho các khóa?
Trả lời:
WeakReference
là một loại tham chiếu yếu, cho phép đối tượng được thu gom rác khi không còn bất kỳ tham chiếu mạnh nào đến nó. WeakHashMap
sử dụng WeakReference
cho khóa để cho phép Garbage Collector xóa các mục trong Map
khi khóa của chúng không còn được tham chiếu ở nơi khác, giúp giải phóng bộ nhớ.
4. Khi nào nên sử dụng WeakHashMap?
Trả lời:
WeakHashMap
phù hợp để lưu trữ các dữ liệu tạm thời, ví dụ như cache, nơi không cần giữ mạnh các khóa và muốn tự động xóa các mục khi không còn tham chiếu đến khóa. Điều này giúp giải phóng bộ nhớ hiệu quả và tránh rò rỉ bộ nhớ.
5. WeakHashMap có thread-safe không? Cách sử dụng WeakHashMap an toàn trong môi trường đa luồng?
Trả lời:
WeakHashMap
không phải là thread-safe. Để sử dụng WeakHashMap
trong môi trường đa luồng, cần đồng bộ hóa WeakHashMap
bằng cách tự quản lý các phần truy cập hoặc sử dụng Collections.synchronizedMap(new WeakHashMap<>())
để tạo một WeakHashMap
đồng bộ.
6. Điều gì sẽ xảy ra với mục nhập (entry) trong WeakHashMap khi khóa của nó bị thu gom rác?
Trả lời:
Khi khóa của một mục trong WeakHashMap
bị thu gom bởi Garbage Collector, mục đó sẽ tự động bị loại bỏ khỏi Map
. Lần truy cập tiếp theo vào mục đó sẽ không tìm thấy khóa, vì cả khóa và giá trị của nó đã bị loại bỏ.
7. WeakHashMap có cho phép khóa hoặc giá trị là null không?
Trả lời:
WeakHashMap
cho phép cả khóa và giá trị là null
. Tuy nhiên, chỉ nên dùng null
cho các giá trị vì nếu đặt null
làm khóa, WeakHashMap
sẽ không thể quản lý được khóa này theo dạng tham chiếu yếu.
8. Làm thế nào để kiểm tra các mục đã bị xóa trong WeakHashMap sau khi Garbage Collection diễn ra?
Trả lời:
WeakHashMap
không cung cấp trực tiếp thông tin về các mục đã bị xóa. Tuy nhiên, có thể kiểm tra số lượng mục bằng size()
hoặc sử dụng entrySet()
, keySet()
và values()
để xem lại các mục còn lại trong Map
sau khi Garbage Collection.
9. WeakHashMap có thể dùng làm cache được không? Nếu có, ưu và nhược điểm là gì?
Trả lời:
WeakHashMap
có thể dùng làm cache khi không cần giữ các mục cố định. Ưu điểm là giúp giảm thiểu rò rỉ bộ nhớ, vì các mục không cần thiết sẽ tự động bị loại bỏ. Nhược điểm là các mục có thể bị xóa bất cứ khi nào nếu không còn tham chiếu mạnh, điều này có thể không phù hợp với các ứng dụng cần dữ liệu cache ổn định hơn.
10. Các phương thức nào của WeakHashMap là đặc trưng hoặc khác biệt so với HashMap?
Trả lời:
Hầu hết các phương thức trong WeakHashMap
giống với HashMap
. Điểm khác biệt chính là cách WeakHashMap
xử lý các khóa. WeakHashMap
không có phương thức mới đặc biệt nào nhưng cách hoạt động của nó với các khóa dạng WeakReference
là điều khác biệt chính.
Dạ ah ơi, ngoài những video anh làm và web này. ah có khoá học về java core không ạ ?.
A dạy một khoá thôi e ạ, khoá core hơi ít người học với cả a cũng không khoái dạy core lém nhưng mà a sẽ ra video cho ae học nhé