Reflection và Serialization
Dưới đây là 20 câu hỏi phỏng vấn Java tập trung vào các chủ đề về Reflection và Serialization bao gồm Introduction, java.lang.Class, Class Modifiers, Instantiation using Reflection, Classloaders, và Serialization.
Reflection
Introduction
Câu hỏi: Reflection là gì trong Java và tại sao nó quan trọng?
- Trả lời: Reflection là một tính năng của Java cho phép kiểm tra và thao tác với các lớp, phương thức, và các trường tại runtime. Nó quan trọng vì cung cấp khả năng tạo đối tượng, gọi phương thức, và truy cập các trường mà không cần biết trước kiểu tại thời điểm biên dịch.
Câu hỏi: Reflection có những hạn chế và nguy cơ nào?
- Trả lời: Reflection có thể gây ra các vấn đề về hiệu suất vì thao tác với metadata tại runtime. Nó cũng có thể phá vỡ tính an toàn kiểu (type safety) và bảo mật của ứng dụng, và gây khó khăn cho việc tối ưu hóa của JVM.
java.lang.Class
Câu hỏi:
java.lang.Classđại diện cho điều gì trong Java?- Trả lời:
java.lang.Classđại diện cho một lớp hoặc interface tại runtime, chứa thông tin về cấu trúc của lớp hoặc interface như các phương thức, trường, constructors, và các modifiers.
- Trả lời:
Câu hỏi: Làm thế nào để lấy đối tượng
Classcủa một lớp cụ thể?Trả lời: Có ba cách để lấy đối tượng
Class:Class<?> clazz1 = MyClass.class; Class<?> clazz2 = new MyClass().getClass(); Class<?> clazz3 = Class.forName("com.example.MyClass");
Class Modifiers
Câu hỏi:
Classtrong Reflection cung cấp các phương thức nào để lấy modifiers của một lớp? Hãy cho ví dụ.Trả lời: Phương thức
getModifiers()củaClasstrả về các modifiers dưới dạng một số nguyên. Bạn có thể sử dụngModifierclass để kiểm tra các modifiers:Class<?> clazz = MyClass.class; int modifiers = clazz.getModifiers(); boolean isPublic = Modifier.isPublic(modifiers);
Câu hỏi: Làm thế nào để kiểm tra một lớp có phải là interface hoặc abstract class bằng Reflection?
Trả lời:
Class<?> clazz = MyClass.class; boolean isInterface = clazz.isInterface(); boolean isAbstract = Modifier.isAbstract(clazz.getModifiers());
Instantiation using Reflection
Câu hỏi: Làm thế nào để tạo một đối tượng của một lớp bằng cách sử dụng Reflection?
Trả lời:
Class<?> clazz = MyClass.class; MyClass obj = (MyClass) clazz.getDeclaredConstructor().newInstance();
Câu hỏi: Làm thế nào để gọi một phương thức không công khai (private) bằng Reflection?
Trả lời:
Class<?> clazz = MyClass.class; Method method = clazz.getDeclaredMethod("privateMethod"); method.setAccessible(true); method.invoke(obj);
Classloaders
Câu hỏi: ClassLoader là gì và tại sao nó quan trọng?
- Trả lời: ClassLoader là thành phần chịu trách nhiệm tải các lớp vào JVM. Nó quan trọng vì quản lý các classpath, cho phép tải động các lớp và hỗ trợ việc tạo ra các ứng dụng plugin và module.
Câu hỏi: Hãy giải thích sự khác biệt giữa các loại ClassLoader: Bootstrap, Extension, và Application ClassLoader.
Trả lời:
Bootstrap ClassLoader: Tải các lớp cốt lõi của Java (JDK), ví dụ như
java.lang.Extension ClassLoader: Tải các lớp từ thư mục
lib/exthoặc thư mục mở rộng của JVM.Application ClassLoader: Tải các lớp từ classpath của ứng dụng, thường là các thư viện và mã nguồn của ứng dụng.
Serialization
Basics
Câu hỏi: Serialization là gì trong Java và tại sao nó được sử dụng?
- Trả lời: Serialization là quá trình chuyển đổi trạng thái của một đối tượng thành một chuỗi byte để lưu trữ hoặc truyền qua mạng. Nó được sử dụng để lưu trữ đối tượng vào tệp hoặc truyền đối tượng qua mạng giữa các JVM.
Câu hỏi: Làm thế nào để một lớp có thể được serializable?
- Trả lời: Một lớp phải implement interface
java.io.Serializableđể có thể được serializable. Interface này không có phương thức nào cần triển khai.
- Trả lời: Một lớp phải implement interface
Câu hỏi: Hãy giải thích ý nghĩa của
serialVersionUIDtrong Serialization.- Trả lời:
serialVersionUIDlà một ID duy nhất được sử dụng để xác định phiên bản của lớp trong quá trình Serialization và Deserialization. NếuserialVersionUIDcủa lớp đã được serializable và lớp mới khác nhau, sẽ xảy ra lỗiInvalidClassException.
- Trả lời:
Câu hỏi: Hãy cho ví dụ về việc Serialization một đối tượng.
Trả lời:
FileOutputStream fileOut = new FileOutputStream("object.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(myObject); out.close(); fileOut.close();
Câu hỏi: Hãy cho ví dụ về việc Deserialization một đối tượng.
Trả lời:
FileInputStream fileIn = new FileInputStream("object.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); MyClass myObject = (MyClass) in.readObject(); in.close(); fileIn.close();
More on Serialization
Câu hỏi: Điều gì xảy ra nếu một lớp có tham chiếu đến một đối tượng không serializable?
- Trả lời: Nếu một lớp có tham chiếu đến một đối tượng không serializable, sẽ xảy ra
NotSerializableExceptiontrong quá trình Serialization. Để tránh điều này, bạn có thể đánh dấu trường đó làtransient.
- Trả lời: Nếu một lớp có tham chiếu đến một đối tượng không serializable, sẽ xảy ra
Câu hỏi: Từ khóa
transientcó vai trò gì trong Serialization?- Trả lời: Từ khóa
transientđược sử dụng để đánh dấu các trường không nên được serializable. Các trường này sẽ không được ghi vào luồng byte trong quá trình Serialization.
- Trả lời: Từ khóa
Câu hỏi: Làm thế nào để tùy chỉnh quá trình Serialization cho một đối tượng?
Trả lời: Bạn có thể tùy chỉnh quá trình Serialization bằng cách triển khai các phương thức
writeObjectvàreadObjecttrong lớp của bạn.private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); // Tùy chỉnh thêm } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); // Tùy chỉnh thêm }
Câu hỏi: Externalizable là gì và sự khác biệt giữa Externalizable và Serializable?
- Trả lời:
Externalizablelà một interface con củaSerializable, yêu cầu bạn triển khai các phương thứcwriteExternalvàreadExternal. Sự khác biệt làExternalizablecung cấp toàn quyền kiểm soát quá trình Serialization và Deserialization, trong khiSerializablechỉ cần khai báo lớp để có thể serializable.
- Trả lời:
Câu hỏi: Hãy cho ví dụ về việc triển khai interface Externalizable.
Trả lời:
public class MyClass implements Externalizable { private String name; private int age; public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(name); out.writeInt(age); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); age = in.readInt(); } }
Những câu hỏi này sẽ giúp đánh giá kiến thức của ứng viên về các khía cạnh quan trọng của Reflection và Serialization trong Java.