Trong lĩnh vực phát triển phần mềm, Java vẫn luôn là một ngôn ngữ nền tảng, được sử dụng rộng rãi để xây dựng các ứng dụng mạnh mẽ và có khả năng mở rộng. Đối với các nhà phát triển có 10 năm kinh nghiệm, các cuộc phỏng vấn Java có thể là một bài kiểm tra nghiêm ngặt về cả kỹ năng kỹ thuật và khả năng áp dụng những kỹ năng này trong các tình huống thực tế. Bài viết này nhằm mục đích cung cấp một hướng dẫn đầy đủ về các câu hỏi và câu trả lời phỏng vấn Java, được thiết kế riêng cho các ứng viên có 10 năm kinh nghiệm.
Dưới đây là danh sách 46 câu hỏi phỏng vấn Java dành cho người có nhiều kinh nghiệm, cùng với câu trả lời chi tiết. Những câu hỏi này bao gồm các chủ đề nâng cao trong Java, concurrency, hiệu suất, mẫu thiết kế và hơn thế nữa. Các bạn có thể tham khảo.
1. Những tính năng mới được giới thiệu trong Java 8 là gì?
Trả lời: Các tính năng chính của Java 8 bao gồm:
- Biểu thức Lambda: Cho phép lập trình hàm bằng cách truyền các phương thức làm đối số.
- API luồng: Cung cấp cách tiếp cận chức năng để xử lý chuỗi các phần tử.
- Phương thức mặc định: Phương thức giao diện với triển khai mặc định.
- Optional: Tránh các tham chiếu null.
- Tham chiếu phương thức: Tham chiếu đến các phương thức bằng cách sử dụng ::.
- Giao diện chức năng: Một giao diện chỉ có một phương thức trừu tượng (ví dụ: Runnable).
- Công cụ Nashorn JavaScript: Tích hợp công cụ JavaScript.
2. Sự khác biệt giữa Callable
và Runnable
là gì?
Trả lời:
Runnable
không trả về kết quả hoặc đưa ra các ngoại lệ đã kiểm tra, trong khi Callable trả về kết quả và có thể đưa ra các ngoại lệ đã kiểm tra.Callable
được sử dụng với các trình thực thi có thể trả về Future.
3. Giải thích Mô hình bộ nhớ Java (JMM)
Trả lời: Mô hình bộ nhớ Java xác định cách các luồng tương tác thông qua bộ nhớ và nó đảm bảo khả năng hiển thị và thứ tự của các biến giữa các luồng. JMM đảm bảo:
- Khả năng hiển thị: Những thay đổi được thực hiện bởi một luồng có thể nhìn thấy đối với các luồng khác.
- Mối quan hệ xảy ra trước: Đảm bảo rằng các lần ghi bộ nhớ của một luồng có thể nhìn thấy đối với luồng khác.
4. Biến volatile trong Java là gì và khi nào bạn sử dụng nó?
Trả lời:
Một biến volatile đảm bảo rằng giá trị của biến được đọc từ bộ nhớ chính chứ không phải từ bộ nhớ cache cục bộ của luồng. Nó được sử dụng để đảm bảo khả năng hiển thị của các thay đổi trên các luồng cho các cờ đơn giản, bộ đếm, v.v., nhưng không đảm bảo tính nguyên tử.
5. Từ khóa synchronized
hoạt động như thế nào trong Java?
Trả lời:
synchronized
đảm bảo loại trừ lẫn nhau, tức là, chỉ một luồng có thể truy cập một khối mã hoặc phương thức tại một thời điểm. Nó cũng thiết lập mối quan hệ xảy ra trước, đảm bảo khả năng hiển thị của các thay đổi trong các biến được thực hiện bởi một luồng cho các luồng khác. Nó có thể được áp dụng ở cấp độ phương thức hoặc khối.
6. Sự khác biệt giữa HashMap
và ConcurrentHashMap
là gì?
Trả lời:
HashMap
không an toàn cho luồng và có thể dẫn đến dữ liệu không nhất quán khi được sửa đổi bởi nhiều luồng.ConcurrentHashMap
an toàn cho luồng, sử dụng cơ chế khóa phân đoạn (trong Java 7) hoặc cơ chế dựa trên CAS (trong Java 8) để cho phép các bản cập nhật đồng thời mà không cần khóa toàn bộ map.
7. Giải thích API Stream
của Java được giới thiệu trong Java 8
Trả lời:
API Stream được sử dụng để xử lý các tập hợp đối tượng theo cách khai báo. Nó hỗ trợ các hoạt động như map
, filter
, reduce
và được thiết kế để hoạt động trên chuỗi các phần tử (luồng), hỗ trợ cả thực thi tuần tự và song song.
8. Thu gom rác hoạt động như thế nào trong Java?
Trả lời:
Bộ thu gom rác của Java tự động thu hồi bộ nhớ bằng cách loại bỏ các đối tượng không còn được tham chiếu. Có nhiều loại bộ thu gom rác khác nhau:
- Serial GC: Đơn luồng.
- Parallel GC: Nhiều luồng được sử dụng để thu gom rác.
- CMS (Concurrent Mark-Sweep) GC: Tập trung vào việc giảm thiểu thời gian tạm dừng.
- G1 GC: Chia heap thành các vùng và hoạt động để cân bằng việc thu hồi bộ nhớ với hiệu suất.
9. Sự khác biệt giữa tham chiếu mạnh, yếu, mềm và ảo trong Java là gì?
Trả lời:
- Tham chiếu mạnh: Loại mặc định, các đối tượng không đủ điều kiện cho GC miễn là một tham chiếu mạnh tồn tại.
- Tham chiếu yếu: Các đối tượng có thể được GC thu hồi nếu chỉ tồn tại các tham chiếu yếu.
- Tham chiếu mềm: Tương tự như tham chiếu yếu nhưng khoan dung hơn, GC sẽ thu thập chúng nếu cần bộ nhớ.
- Tham chiếu ảo: Được sử dụng để thực hiện một số dọn dẹp trước GC, chỉ được truy cập thông qua ReferenceQueue.
10. Sự khác biệt giữa ReentrantLock
và synchronized
là gì?
Trả lời:
ReentrantLock
cung cấp các tính năng nâng cao như hết thời gian chờ để đạt được khóa, khả năng kiểm tra xem khóa có được giữ hay không và chính sách công bằng.synchronized
đơn giản hơn nhưng không cung cấp sự linh hoạt như vậy.
11. Khung Fork/Join trong Java là gì?
Trả lời:
Khung Fork/Join được giới thiệu trong Java 7 được thiết kế để xử lý song song. Nó cho phép chia các tác vụ thành các tác vụ con nhỏ hơn (fork
) và kết hợp các kết quả (join
). Nó được tối ưu hóa cho các thuật toán chia để trị.
12. Sự khác biệt giữa ngoại lệ đã kiểm tra và chưa kiểm tra là gì?
Trả lời:
- Ngoại lệ đã kiểm tra: Đây là những ngoại lệ được kiểm tra tại thời điểm biên dịch (ví dụ:
IOException
). Bạn phải xử lý hoặc khai báo chúng. - Ngoại lệ chưa kiểm tra: Đây là những ngoại lệ được kiểm tra trong thời gian chạy (ví dụ:
NullPointerException
). Chúng có thể được xử lý nhưng không được thi hành.
13. Mục đích của final
, finally
và finalize
là gì?
Trả lời:
- final: Từ khóa được sử dụng để khai báo các hằng số, các phương thức không thay đổi hoặc để ngăn chặn kế thừa.
- finally: Một khối được thực thi bất kể ngoại lệ nào trong try-catch.
- finalize: Một phương thức được GC gọi trước khi một đối tượng bị thu gom rác.
14. Sự khác biệt giữa Comparable
và Comparator
là gì?
Trả lời:
Comparable
xác định một thứ tự tự nhiên cho các đối tượng (ví dụ: phương thức compareTo trong cùng một lớp).Comparator
cho phép xác định nhiều cách sắp xếp các đối tượng và nằm ngoài đối tượng (ví dụ: phương thức compare trong một lớp riêng biệt).
15. ThreadLocal
trong Java là gì?
Trả lời:
ThreadLocal
cung cấp cho mỗi luồng biến được khởi tạo độc lập riêng của nó. Nó giúp cô lập luồng, đặc biệt hữu ích trong việc duy trì ngữ cảnh phiên hoặc giao dịch của người dùng.
16. Giải thích thuật ngữ "bất biến". Làm cách nào để bạn có thể tạo một lớp bất biến trong Java?
Trả lời: Tính bất biến có nghĩa là một khi một đối tượng được tạo, nó không thể bị thay đổi. Để tạo một lớp bất biến:
- Khai báo lớp là
final
. - Tạo tất cả các trường
private final
. - Không cung cấp bất kỳ setter nào.
- Đảm bảo rằng các phương thức không hiển thị các đối tượng có thể thay đổi (ví dụ: bằng cách trả về các bản sao sâu).
17. Giải thích cách diễn đạt khóa được kiểm tra kép trong mẫu Singleton
Trả lời: Khóa được kiểm tra kép đảm bảo rằng một thể hiện Singleton chỉ được tạo một lần và an toàn cho luồng. Cách diễn đạt là:
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; }
}
18. Giải thích các phương thức wait()
, notify()
và notifyAll()
trong Java
Trả lời: Các phương thức này được sử dụng để giao tiếp giữa các luồng:
- wait(): Một luồng giải phóng khóa và đợi cho đến khi được thông báo.
- notify(): Đánh thức một luồng đang đợi.
- notifyAll(): Đánh thức tất cả các luồng đang đợi.
19. Phản xạ Java là gì?
Trả lời:
Phản xạ cho phép mã Java kiểm tra và thao tác các lớp, trường, phương thức và hàm tạo trong thời gian chạy. Nó được sử dụng để tạo khung, gỡ lỗi và thử nghiệm. Tuy nhiên, nó có ý nghĩa về hiệu suất và bảo mật.
20. Giải thích thuật ngữ "deadlock" và cách ngăn chặn nó
Trả lời:
Deadlock xảy ra khi hai hay nhiều luồng đang đợi lẫn nhau để giải phóng tài nguyên, dẫn đến việc đợi vô hạn. Các chiến lược ngăn chặn bao gồm:
- Tránh các phụ thuộc tuần hoàn.
- Sử dụng thứ tự khóa.
- Sử dụng
tryLock()
với thời gian chờ.
21. Giải thích khái niệm mô hình bộ nhớ Java và cách thức nó liên quan đến tính đồng thời
Trả lời:
Mô hình Bộ nhớ Java (JMM) định nghĩa cách máy ảo Java (JVM) hoạt động với bộ nhớ của máy tính. Nó chỉ định cách thức và thời điểm các luồng khác nhau có thể thấy các giá trị được ghi vào các biến được chia sẻ bởi các luồng khác và cách đồng bộ hóa quyền truy cập vào các biến được chia sẻ. Các khái niệm chính bao gồm mối quan hệ xảy ra trước, từ khóa volatile và rào cản bộ nhớ.
22. Mô tả sự khác biệt giữa CompletableFuture và Future. CompletableFuture tăng cường lập trình không đồng bộ trong Java như thế nào?
Trả lời:
CompletableFuture mở rộng giao diện Future và cung cấp một cách mạnh mẽ và linh hoạt hơn để xử lý các tính toán không đồng bộ. Không giống như Future, CompletableFuture cho phép xâu chuỗi các hoạt động không đồng bộ, kết hợp nhiều future và xử lý ngoại lệ một cách uyển chuyển hơn. Nó cũng cung cấp một cách để tự hoàn thành future, làm cho nó hữu ích cho các tình huống mà kết quả có thể đến từ nhiều nguồn.
23. Thu gom rác hoạt động như thế nào trong Java? Giải thích các thuật toán GC khác nhau và cách điều chỉnh hiệu suất GC
Trả lời:
Thu gom rác trong Java tự động giải phóng bộ nhớ bằng cách loại bỏ các đối tượng không còn được tiếp cận. Các thuật toán GC phổ biến bao gồm:
- Serial GC
- Parallel GC
- Concurrent Mark Sweep (CMS)
- G1 (Garbage First)
ZGC (Z Garbage Collector) Việc điều chỉnh liên quan đến việc điều chỉnh kích thước heap, chọn thuật toán GC thích hợp và tinh chỉnh các tham số GC dựa trên nhu cầu của ứng dụng và số liệu hiệu suất.
24. Giải thích khái niệm phản xạ trong Java. Các trường hợp sử dụng và nhược điểm tiềm ẩn của nó là gì?
Trả lời:
Phản xạ cho phép kiểm tra hoặc sửa đổi hành vi thời gian chạy của các ứng dụng đang chạy trong JVM. Nó có thể được sử dụng để:
- Kiểm tra các lớp, giao diện, trường và phương thức trong thời gian chạy
- Khởi tạo các đối tượng và gọi các phương thức một cách linh hoạt
Truy cập và sửa đổi các trường và phương thức riêng tư Nhược điểm bao gồm giảm hiệu suất, hạn chế bảo mật và khả năng phá vỡ tính đóng gói.
25. Rò rỉ bộ nhớ Java là gì? Làm cách nào bạn có thể xác định và khắc phục rò rỉ bộ nhớ trong ứng dụng Java?
Trả lời:
Rò rỉ bộ nhớ Java xảy ra khi các đối tượng không còn được ứng dụng sử dụng nhưng vẫn được tham chiếu, ngăn chặn quá trình thu gom rác. Các phương pháp xác định bao gồm:
- Sử dụng các công cụ lược tả (ví dụ: VisualVM, JProfiler)
- Phân tích kết xuất heap
Giám sát việc sử dụng bộ nhớ theo thời gian Khắc phục thường liên quan đến việc tìm và loại bỏ các tham chiếu đối tượng không cần thiết, thường là trong các trường tĩnh, bộ nhớ cache hoặc các tài nguyên được quản lý sai.
26. Java agent là gì? Làm cách nào chúng có thể được sử dụng để giám sát ứng dụng và thiết bị đo đạc?
Trả lời:
Java agent là các chương trình có thể gán hoặc sửa đổi mã byte Java trong thời gian chạy. Chúng có thể được sử dụng cho:
- Giám sát hiệu suất
- Ghi nhật ký
- Gỡ lỗi
Lập hồ sơ Java agent thường được triển khai bằng cách tạo một lớp có phương thức premain hoặc agentmain và đóng gói nó dưới dạng tệp JAR với các mục kê khai thích hợp.
27. Giải thích mối quan hệ xảy ra trước của Mô hình bộ nhớ Java và tầm quan trọng của nó trong lập trình đồng thời
Trả lời:
Mối quan hệ xảy ra trước trong Mô hình Bộ nhớ Java xác định thứ tự một phần của các hành động của chương trình, đảm bảo rằng các hoạt động bộ nhớ trong một luồng được luồng khác quan sát chính xác. Điều này rất quan trọng để viết các chương trình đồng thời chính xác, vì nó đảm bảo khả năng hiển thị của các thay đổi trên các luồng mà không cần đồng bộ hóa quá mức.
28. Đặc tả Reactive Streams trong Java là gì? Nó liên quan như thế nào đến API Flow Java 9?
Trả lời:
Reactive Streams là một đặc tả để xử lý luồng không đồng bộ với áp suất ngược không chặn. API Flow Java 9 là triển khai tiêu chuẩn của đặc tả này, cung cấp các giao diện như Publisher, Subscriber và Subscription. Nó cho phép xây dựng các ứng dụng phản ứng, có khả năng mở rộng có thể xử lý áp suất ngược một cách hiệu quả.
29. Giải thích khái niệm tham chiếu phương thức trong Java 8+. Chúng liên quan như thế nào đến biểu thức lambda?
Trả lời:
Tham chiếu phương thức là các ký hiệu viết tắt của biểu thức lambda để gọi các phương thức. Chúng có thể được sử dụng để tham chiếu đến các phương thức tĩnh, phương thức cá thể hoặc hàm tạo. Có bốn loại:
- Tham chiếu đến một phương thức tĩnh
- Tham chiếu đến một phương thức cá thể của một đối tượng cụ thể
- Tham chiếu đến một phương thức cá thể của một đối tượng tùy ý thuộc một loại cụ thể
- Tham chiếu đến một hàm tạo Chúng cung cấp một cách dễ đọc và ngắn gọn hơn để thể hiện các biểu thức lambda đơn giản.
30. Sự khác biệt giữa các lớp trừu tượng và giao diện trong Java 8 trở lên là gì?
Trả lời: Sự khác biệt chính bao gồm:
- Các lớp trừu tượng có thể có trạng thái, giao diện thì không (ngoại trừ các trường tĩnh cuối cùng)
- Một lớp chỉ có thể mở rộng một lớp trừu tượng nhưng triển khai nhiều giao diện
- Các lớp trừu tượng có thể có hàm tạo, giao diện thì không
- Giao diện có thể có các phương thức mặc định và tĩnh (kể từ Java 8)
Giao diện có thể có các phương thức riêng tư (kể từ Java 9) Hãy chọn các lớp trừu tượng khi bạn muốn chia sẻ mã giữa một số lớp có liên quan chặt chẽ. Sử dụng giao diện để xác định hợp đồng cho một tập hợp các lớp để triển khai, đặc biệt là khi các lớp này không liên quan chặt chẽ.
31. Mô tả bộ thu gom rác theo thế hệ (G1). Nó khác với các thuật toán GC khác như thế nào?
Trả lời: G1 là bộ thu gom rác theo kiểu máy chủ được thiết kế cho các máy đa xử lý có bộ nhớ lớn. Các tính năng chính:
- Các giai đoạn đồng thời và song song
- Nén gia tăng
- Thời gian tạm dừng có thể dự đoán được
Bố cục heap dựa trên vùng Nó khác với các thuật toán khác bởi khả năng ưu tiên thu gom rác trong các khu vực của heap có khả năng thu hồi nhiều dung lượng nhất, do đó có tên là “Garbage-First”.
32. Thiết bị đo đạc mã byte là gì? Làm cách nào nó có thể được sử dụng để nâng cao hiệu suất ứng dụng hoặc thêm chức năng?
Trả lời:
Thiết bị đo đạc mã byte là quá trình sửa đổi mã byte Java sau khi nó đã được biên dịch. Nó có thể được sử dụng để:
- Thêm mã ghi nhật ký hoặc giám sát
- Triển khai các tính năng lập trình hướng khía cạnh
- Tối ưu hóa hiệu suất bằng cách sửa đổi mã đã biên dịch
- Thêm kiểm tra bảo mật hoặc thực thi chính sách Các công cụ như ASM, Javassist hoặc ByteBuddy có thể được sử dụng để thiết bị đo đạc mã byte.
33. Giải thích khái niệm rò rỉ mềm trong Java và cách chúng khác với rò rỉ bộ nhớ truyền thống.
Trả lời:
Rò rỉ mềm xảy ra khi các đối tượng không được thu gom rác mặc dù không thực sự cần thiết cho ứng dụng. Không giống như rò rỉ bộ nhớ truyền thống, các đối tượng trong rò rỉ mềm có thể được thu gom rác nếu áp lực bộ nhớ tăng lên. Các nguyên nhân phổ biến bao gồm bộ nhớ cache hoặc nhóm quá cỡ. Chúng có thể được giải quyết bằng cách sử dụng tham chiếu yếu hoặc chính sách loại eviction dựa trên thời gian trong bộ nhớ cache.
34. Hệ thống mô-đun Java (được giới thiệu trong Java 9) cải thiện việc phát triển và triển khai ứng dụng như thế nào?
Trả lời: Hệ thống mô-đun Java:
- Cải thiện tính đóng gói bằng cách cho phép khai báo rõ ràng các API công khai
- Giảm JAR hell và các vấn đề về đường dẫn lớp
- Cho phép tạo ra các thời gian chạy nhỏ hơn, hiệu quả hơn với jlink
- Cải thiện bảo mật bằng cách giảm bề mặt tấn công
- Nâng cao hiệu suất thông qua việc tổ chức các gói tốt hơn
35. Sự khác biệt giữa các từ khóa volatile và synchronized trong Java là gì?
Trả lời:
- volatile đảm bảo khả năng hiển thị của các thay đổi đối với các biến trên các luồng, nhưng không cung cấp tính nguyên tử
- synchronized cung cấp cả khả năng hiển thị và tính nguyên tử, nhưng với chi phí hiệu suất cao hơn
- volatile ở cấp độ trường, synchronized có thể được áp dụng cho các phương thức hoặc khối
- volatile không gây ra tranh chấp luồng, synchronized có thể
36. Giải thích khái niệm CompletionStage trong Java. Làm cách nào nó nâng cao lập trình không đồng bộ?
Trả lời: CompletionStage đại diện cho một giai đoạn của một phép tính có thể không đồng bộ. Nó cho phép:
- Xâu chuỗi các hoạt động không đồng bộ
- Kết hợp kết quả từ nhiều phép tính không đồng bộ
- Xử lý ngoại lệ trong các luồng không đồng bộ
Biến đổi kết quả một cách không đồng bộ Nó cung cấp một mô hình linh hoạt và mạnh mẽ hơn cho lập trình không đồng bộ so với các đối tượng Future đơn giản.
37. Các phương pháp hay nhất để triển khai các phương thức hashCode() và equals() trong Java là gì?
Trả lời: Các phương pháp hay nhất bao gồm:
- Nếu bạn ghi đè equals(), bạn phải ghi đè hashCode()
- equals() phải nhất quán (nhiều lần gọi phải trả về cùng một kết quả)
- equals() phải đối xứng (a.equals(b) phải trả về giống như b.equals(a))
- hashCode() nên sử dụng các trường giống như equals()
- Cân nhắc sử dụng Objects.hash() để tạo mã băm
- Đối với các đối tượng có thể thay đổi, chỉ sử dụng các trường không dự kiến sẽ thay đổi
38. Mô tả tính năng Luồng ảo Java (được giới thiệu trong Java 19 dưới dạng bản xem trước). Nó khác với các luồng nền tảng như thế nào?
Trả lời:
Luồng ảo là các luồng nhẹ, rẻ tiền để tạo và duy trì. Sự khác biệt chính:
- Được quản lý bởi JVM, không phải hệ điều hành
- Có thể hỗ trợ hàng triệu luồng đồng thời
- Sử dụng một ngăn xếp nhỏ và phát triển / thu nhỏ khi cần thiết
Tự động nhường quyền khi bị chặn trên các hoạt động I/O Chúng cho phép một mô hình lập trình đơn giản hơn cho các ứng dụng đồng thời, đặc biệt là những ứng dụng có nhiều hoạt động I/O đồng thời.
39. Sự khác biệt giữa các phương thức tĩnh và mặc định trong giao diện là gì? Khi nào bạn sẽ chọn cái này hơn cái kia?
Trả lời:
- Các phương thức tĩnh thuộc về giao diện, không phải các lớp triển khai
- Các phương thức mặc định được kế thừa bởi các lớp triển khai
- Các phương thức tĩnh không thể bị ghi đè, các phương thức mặc định có thể
- Sử dụng các phương thức tĩnh cho các hàm tiện ích liên quan đến giao diện
- Sử dụng các phương thức mặc định để thêm các phương thức mới vào giao diện mà không phá vỡ các triển khai hiện có
40. Giải thích khái niệm bộ nhớ ngoài heap trong Java. Các trường hợp sử dụng của nó là gì và làm cách nào nó có thể được quản lý?
Trả lời: Bộ nhớ ngoài heap đề cập đến bộ nhớ được cấp phát bên ngoài heap Java. Các trường hợp sử dụng bao gồm:
- Tập dữ liệu lớn có thể gây ra chi phí GC quá mức nếu được lưu trữ trên heap
- Các tệp được ánh xạ bộ nhớ
Bộ đệm trực tiếp cho I/O hiệu suất cao Nó có thể được quản lý bằng cách sử dụng các thư viện như ByteBuffer hoặc các thư viện ngoài heap chuyên dụng. Cần phải cẩn thận để giải phóng bộ nhớ này theo cách thủ công khi không còn cần thiết nữa.
41. Mô tả Trình ghi chuyến bay Java (JFR) và Kiểm soát nhiệm vụ Java (JMC). Làm cách nào chúng có thể được sử dụng để phân tích hiệu suất và khắc phục sự cố?
Trả lời: JFR là một khung thu thập sự kiện và lập hồ sơ được tích hợp trong JVM. JMC là một công cụ đồ họa để phân tích dữ liệu JFR. Cùng nhau, chúng cung cấp:
- Lập hồ sơ chi phí thấp
- Số liệu hiệu suất chi tiết
- Phân tích luồng
- Phát hiện rò rỉ bộ nhớ
Phân tích hành vi GC Chúng là những công cụ mạnh mẽ để xác định nút thắt cổ chai về hiệu suất và phân tích các sự cố sản xuất với tác động tối thiểu.
42. Lớp CompletableFuture
trong Java là gì?
Trả lời:
CompletableFuture
là một phần của gói java.util.concurrent
và đại diện cho một kết quả trong tương lai của một phép tính không đồng bộ. Nó hỗ trợ các hoạt động kết hợp như thenApply
, thenCombine
và thenAccept
để xâu chuỗi các tác vụ mà không chặn các luồng.
43. JavaAgent
là gì? Nó được sử dụng như thế nào?
Trả lời:
Java Agent là một công cụ đặc biệt có thể sửa đổi mã byte trong thời gian chạy hoặc trước khi một lớp được tải. Nó thường được sử dụng trong các công cụ giám sát, lập hồ sơ và lập trình hướng khía cạnh. Các tác nhân được chỉ định bằng cách sử dụng cờ -javaagent
.
44. Giải thích vai trò của Phaser
trong Java
Trả lời:
Phaser
là một công cụ hỗ trợ đồng bộ hóa cho phép các luồng đợi những luồng khác ở một giai đoạn hoặc bước cụ thể trong một tác vụ. Không giống như CountDownLatch
hoặc CyclicBarrier
, nó hỗ trợ phối hợp giai đoạn linh hoạt hơn và đăng ký / hủy đăng ký luồng động.
45. java.lang.instrument
là gì và nó liên quan như thế nào đến JVM?
Trả lời:
Gói java.lang.instrument
cung cấp API để sửa đổi hành vi của lớp trong thời gian chạy bằng cách sử dụng các tác nhân. Nó có thể xác định lại các lớp, thu thập thông tin lập hồ sơ và được sử dụng nhiều trong các công cụ thiết bị đo đạc và giám sát.
46. Giải thích khái niệm WeakHashMap
của Java
Trả lời:
WeakHashMap
sử dụng tham chiếu yếu cho các khóa, có nghĩa là nếu một khóa không còn được tham chiếu ở nơi khác, nó sẽ đủ điều kiện để thu gom rác, ngay cả khi nó vẫn còn trong bản đồ. Nó hữu ích trong trường hợp bạn muốn hành vi giống như bộ đệm mà không ngăn chặn quá trình thu gom rác.
Những câu hỏi này được thiết kế để bao quát một loạt các chủ đề, đảm bảo rằng các ứng viên được kiểm tra về các khía cạnh nâng cao của Java, bao gồm đồng thời, quản lý bộ nhớ, mẫu thiết kế và các tính năng mới hơn của Java.