面试题答案
一键面试Serializable接口的应用场景
- 对象持久化:将对象保存到文件中,以便在后续程序运行时能够重新读取并恢复对象状态。例如,保存用户配置信息、游戏进度等。
- 网络传输:在不同Java虚拟机(JVM)之间通过网络传递对象。比如,在分布式系统中,将对象从一个节点发送到另一个节点。
实现Serializable接口示例
import java.io.Serializable;
class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
在上述代码中,Employee
类实现了Serializable
接口,serialVersionUID
是一个版本号,用于在反序列化时验证序列化对象的版本兼容性。
安全问题及应对措施
- 安全问题:
- 敏感信息泄露:如果对象中包含敏感信息(如密码、信用卡号等),在序列化和反序列化过程中,这些信息可能会被恶意获取。
- 反序列化漏洞:恶意攻击者可以构造恶意的序列化数据,通过反序列化操作执行任意代码,这是一种严重的安全威胁,比如常见的Java反序列化漏洞(如CVE - 2015 - 5254等)。
- 应对措施:
- 不序列化敏感信息:对于敏感信息,不将其作为类的成员变量进行序列化。可以在需要时通过其他安全的方式获取(如从安全的配置文件中读取)。
- 验证反序列化数据:在反序列化之前,对输入的序列化数据进行严格验证,确保数据来源可靠。可以使用白名单机制,只允许特定来源的序列化数据进行反序列化。
- 自定义反序列化方法:通过实现
readObject
方法,并在方法内部进行数据验证和安全性检查,确保反序列化过程的安全性。例如:
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
// 验证数据
if (name == null || age < 0) {
throw new InvalidObjectException("Invalid data");
}
}