【Java面试】序列化

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录


在这里先说一下什么是序列化以及为什么需要序列化
序列化机制可以将对象转换成字节序列这些字节序列可以保存在磁盘上也可以在网络中传输并允许程序将这些字节序列再次恢复成原来的对象。其中对象的序列化Serialize是指将一个Java对象写入IO流中对象的反序列化Deserialize则是指从IO流中恢复该Java对象。

若对象要支持序列化机制则它的类需要实现Serializable接口该接口是一个标记接口它没有提供任何方法只是标明该类是可以序列化的Java的很多类已经实现了Serializable接口如包装类、String、Date等。

若要实现序列化则需要使用对象流ObjectInputStream和ObjectOutputStream。其中在序列化时需要调用ObjectOutputStream对象的writeObject()方法以输出对象序列。在反序列化时需要调用ObjectInputStream对象的readObject()方法将对象序列恢复为对象。

		ObjectOutputStream oos = new ObjectOutputStream(new 
	 	FileOutputStream(new File("D://desktop//1.jpg")));
        oos.writeObject("123");
        ObjectInputStream ois = new ObjectInputStream(new 
        FileInputStream(new File("D://desktop//1.jpg")));
        Object o = ois.readObject();
        System.out.println(o);

说说你对序列化的理解

面试官说说你对Java序列化的理解
我之所以需要序列化是为了解决网络通信过程中对象传输的一个问题。也就是说如何把当前JVM进程中的对象跨网络传输到另一个JVM进程中进行恢复。
我而序列化就是把内存中的对象转换为字节流以便用来实现存储和传输。
我而反序列化就是把根据文件或者网络上传输过来的对象字节流根据字节流里面的对象描述信息和状态重新构建一个新的对象。
我序列化的前提是为了保证通信双方对于对象的可识别性 所以很多时候我们会先把对象转换为通用的解析格式比如JSONXML然后再把他们转换为字节流进行传输。从而实现跨平台或者跨语言的一种可识别性。
我目前序列化的开源技术常用的有JSON,XMLAvro等。
我但是实际那个序列化技术更加合适一般需要考虑一下几个因素
我1序列化的数据大小因为数据大小会影响传输性能。
我2序列化的性能序列化耗时太长会影响业务性能。
我3是否支持跨平台或者跨语言。
我4技术的成熟度越成熟的方案使用的公司越多也就越稳定。
面试官行下一题。

Serializable接口为什么需要定义serialVersionUID变量

serialVersionUID代表序列化的版本通过定义类的序列化版本在反序列化时只要对象中所存的版本和当前类的版本一致就允许做恢复数据的操作否则将会抛出序列化版本不一致的错误。

如果不定义序列化版本在反序列化时可能出现冲突的情况例如

  1. 创建该类的实例并将这个实例序列化保存在磁盘上

  2. 升级这个类例如增加、删除、修改这个类的成员变量

  3. 反序列化该类的实例即从磁盘上恢复修改之前保存的数据。

在第3步恢复数据的时候当前的类已经和序列化的数据的格式产生了冲突可能会发生各种意想不到的问题。增加了序列化版本之后在这种情况下则可以抛出异常以提示这种矛盾的存在提高数据的安全性。

​ 需要注意的是如果没有显示定义serialVersionUID则JVM会根据类的信息自动计算出它的值如果升级前后类的内容发生了变化该值的计算结果通常就不同这会导致反序列化的失败。所以最好在打算序列化的类中显示地定义serialVersionUID这样即便在序列化后它对应的类被修改了由于版本号是一致的所以该对象依然可以被正确的反序列化。

​ 如果类的修改会导致反序列化失败则应该为此类分配新的serialVersionUID那么对类的哪些内容进行修改会导致反序列化失败呢

  • 如果修改类时只是修改了方法则反序列化不受影响。
  • 如果修改类时只是修改了静态变量则反序列化不受影响。
  • 如果修改类时改变了实例变量则可能导致反序列化失败。

除了Java自带的序列化之外你还了解哪些序列化工具

  • JSON目前使用比较频繁的格式化数据工具简单直观可读性好有jacksongsonfastjson等等比较优秀的JSON解析工具的表现还是比较好的有些json解析工具甚至速度超过了一些二进制的序列化方式。

  • Thrift是Facebook开源提供的一个高性能轻量级RPC服务框架其产生正是为了满足当前大数据量、分布式、跨语言、跨平台数据通讯的需求。 但是Thrift并不仅仅是序列化协议而是一个RPC框架。 相对于JSON和XML而言Thrift在空间开销和解析性能上有了比较大的提升对于对性能要求比较高的分布式系统它是一个优秀的RPC解决方案。但是由于Thrift的序列化被嵌入到Thrift框架里面 Thrift框架本身并没有透出序列化和反序列化接口这导致其很难和其他传输层协议共同使用例如HTTP。

  • Avro提供两种序列化格式即JSON格式或者Binary格式。Binary格式在空间开销和解析性能方面可以和Protobuf媲美 JSON格式方便测试阶段的调试。 Avro支持的数据类型非常丰富包括C++语言里面的union类型。Avro支持JSON格式的IDL和类似于Thrift和Protobuf的IDL实验阶段这两者之间可以互转。Schema可以在传输数据的同时发送加上JSON的自我描述属性这使得Avro非常适合动态类型语言。 Avro在做文件持久化的时候一般会和Schema一起存储所以Avro序列化文件自身具有自我描述属性所以非常适合于做Hive、Pig和MapReduce的持久化数据格式。对于不同版本的Schema在进行RPC调用的时候服务端和客户端可以在握手阶段对Schema进行互相确认大大提高了最终的数据解析速度。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java