MST

星途 面试题库

面试题:自定义Java序列化与反序列化的优化

假设你需要对一个复杂的Java对象进行序列化和反序列化,该对象包含大量的数据以及一些特殊的属性(例如敏感信息),要求你自定义序列化和反序列化过程以优化性能并确保敏感信息的安全,你会如何设计和实现?请详细描述实现思路和关键代码片段。
35.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 实现 Externalizable 接口:通过实现该接口,我们可以完全控制对象的序列化和反序列化过程。
  2. 性能优化
    • 对于大量数据,只序列化必要的数据部分,跳过不必要的属性,减少序列化的数据量。
    • 考虑使用更高效的二进制格式(如 ByteBuffer)来处理数据的读写。
  3. 敏感信息安全
    • 在序列化时,对敏感信息进行加密处理,如使用 AES 等加密算法。
    • 在反序列化时,对加密后的敏感信息进行解密。

关键代码片段

  1. 定义复杂Java对象并实现 Externalizable 接口
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class ComplexObject implements Externalizable {
    private String nonSensitiveData;
    private String sensitiveData;

    // 构造函数(必须有无参构造函数)
    public ComplexObject() {}

    public ComplexObject(String nonSensitiveData, String sensitiveData) {
        this.nonSensitiveData = nonSensitiveData;
        this.sensitiveData = sensitiveData;
    }

    // 序列化方法
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeUTF(nonSensitiveData);
        // 加密敏感信息
        String encryptedSensitiveData = encrypt(sensitiveData);
        out.writeUTF(encryptedSensitiveData);
    }

    // 反序列化方法
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        nonSensitiveData = in.readUTF();
        String encryptedSensitiveData = in.readUTF();
        // 解密敏感信息
        sensitiveData = decrypt(encryptedSensitiveData);
    }

    // 加密方法
    private String encrypt(String data) {
        try {
            String key = "yourSecretKey123"; // 16字节密钥
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(data.getBytes());
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 解密方法
    private String decrypt(String encryptedData) {
        try {
            String key = "yourSecretKey123";
            SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
            byte[] decryptedBytes = cipher.doFinal(decodedBytes);
            return new String(decryptedBytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
  1. 测试序列化和反序列化
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Main {
    public static void main(String[] args) {
        ComplexObject obj = new ComplexObject("non - sensitive info", "sensitive info");
        try {
            // 序列化
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("complexObject.ser"));
            oos.writeObject(obj);
            oos.close();

            // 反序列化
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("complexObject.ser"));
            ComplexObject deserializedObj = (ComplexObject) ois.readObject();
            ois.close();

            System.out.println("Deserialized non - sensitive data: " + deserializedObj.nonSensitiveData);
            System.out.println("Deserialized sensitive data: " + deserializedObj.sensitiveData);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}