# 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

1. **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.
        
2. **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

3. **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.
        
4. **Câu hỏi**: Làm thế nào để lấy đối tượng `Class` của một lớp cụ thể?
    
    * **Trả lời**: Có ba cách để lấy đối tượng `Class`:
        
        ```java
        Class<?> clazz1 = MyClass.class;
        Class<?> clazz2 = new MyClass().getClass();
        Class<?> clazz3 = Class.forName("com.example.MyClass");
        ```
        

#### Class Modifiers

5. **Câu hỏi**: `Class` trong 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ủa `Class` trả về các modifiers dưới dạng một số nguyên. Bạn có thể sử dụng `Modifier` class để kiểm tra các modifiers:
        
        ```java
        Class<?> clazz = MyClass.class;
        int modifiers = clazz.getModifiers();
        boolean isPublic = Modifier.isPublic(modifiers);
        ```
        
6. **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**:
        
        ```java
        Class<?> clazz = MyClass.class;
        boolean isInterface = clazz.isInterface();
        boolean isAbstract = Modifier.isAbstract(clazz.getModifiers());
        ```
        

#### Instantiation using Reflection

7. **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**:
        
        ```java
        Class<?> clazz = MyClass.class;
        MyClass obj = (MyClass) clazz.getDeclaredConstructor().newInstance();
        ```
        
8. **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**:
        
        ```java
        Class<?> clazz = MyClass.class;
        Method method = clazz.getDeclaredMethod("privateMethod");
        method.setAccessible(true);
        method.invoke(obj);
        ```
        

#### Classloaders

9. **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.
        
10. **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/ext` hoặ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

11. **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.
        
12. **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`](http://java.io)`.Serializable` để có thể được serializable. Interface này không có phương thức nào cần triển khai.
        
13. **Câu hỏi**: Hãy giải thích ý nghĩa của `serialVersionUID` trong Serialization.
    
    * **Trả lời**: `serialVersionUID` là 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ếu `serialVersionUID` của lớp đã được serializable và lớp mới khác nhau, sẽ xảy ra lỗi `InvalidClassException`.
        
14. **Câu hỏi**: Hãy cho ví dụ về việc Serialization một đối tượng.
    
    * **Trả lời**:
        
        ```java
        FileOutputStream fileOut = new FileOutputStream("object.ser");
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        out.writeObject(myObject);
        out.close();
        fileOut.close();
        ```
        
15. **Câu hỏi**: Hãy cho ví dụ về việc Deserialization một đối tượng.
    
    * **Trả lời**:
        
        ```java
        FileInputStream fileIn = new FileInputStream("object.ser");
        ObjectInputStream in = new ObjectInputStream(fileIn);
        MyClass myObject = (MyClass) in.readObject();
        in.close();
        fileIn.close();
        ```
        

#### More on Serialization

16. **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 `NotSerializableException` trong quá trình Serialization. Để tránh điều này, bạn có thể đánh dấu trường đó là `transient`.
        
17. **Câu hỏi**: Từ khóa `transient` có 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.
        
18. **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 `writeObject` và `readObject` trong lớp của bạn.
        
        ```java
        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
        }
        ```
        
19. **Câu hỏi**: Externalizable là gì và sự khác biệt giữa Externalizable và Serializable?
    
    * **Trả lời**: `Externalizable` là một interface con của `Serializable`, yêu cầu bạn triển khai các phương thức `writeExternal` và `readExternal`. Sự khác biệt là `Externalizable` cung cấp toàn quyền kiểm soát quá trình Serialization và Deserialization, trong khi `Serializable` chỉ cần khai báo lớp để có thể serializable.
        
20. **Câu hỏi**: Hãy cho ví dụ về việc triển khai interface Externalizable.
    
    * **Trả lời**:
        
        ```java
        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.
