精华内容
下载资源
问答
  • 关于类的序列化,下列说法哪些是正确的:答案在文末 A. 类的序列化与serialVersionUID毫无关系。 B. 如果完全不兼容升级,不需要修改serialVersionUID值。 C. POJO类的serialVersionUID不一致会编译出错。 D. POJO...

    关于类的序列化,下列说法哪些是正确的:答案在文末

    • A. 类的序列化与serialVersionUID毫无关系。
    • B. 如果完全不兼容升级,不需要修改serialVersionUID值。
    • C. POJO类的serialVersionUID不一致会编译出错。
    • D. POJO类的serialVersionUID不一致会抛出序列化运行时异常。

    多选 通过集合A.subList()获取子集合B,下列说法哪些是正确的:答案在文末

    • A. 返回的集合B没有实现Serializable接口,不能被序列化,所以不能应用于RPC场景。
    • B. 在B集合中添加某个元素,那么A集合也会添加进去此元素。
    • C. 集合A中元素的修改不会影响到集合B的任何操作。
    • D. 对A元素个数的修改,会导致集合B的遍历产生ConcurrentModificationException 异常。

    多选 关于应用与数据库之间的操作,下列哪些说法符合《阿里巴巴Java开发手册》:答案在文末

    • A. 对外提供一个大而全的接口进行POJO的update更新,这样比较省事,省代码。
    • B. 使用事务回滚的地方需要考虑各方面的回滚方案,包括缓存回滚、搜索引擎回滚、消息补偿、统计修正等。
    • C. 应用服务器与数据库之间是短连接。
    • D. 应用服务器与数据库之间是长连接。

    多选 关于分页查询,下列哪些说法符合《阿里巴巴Java开发手册》:答案在文末

    • A. 分页查询,当统计的count为0时,应该直接返回,不要再执行分页查询语句。
    • B. iBATIS自带的queryForList(String statementName,int start,int size)分页接口有性能隐患,不允许使用。
    • C. 定义明确的sql查询语句,通过传入参数start和size来实现分页逻辑。
    • D. 可使用存储过程写分页逻辑,提高效率。

    多选 关于checked/unchecked exception,下列哪些说法是正确的:答案在文末

    • A. 继承java.lang.Error的类属于checked exception。
    • B. checked异常继承java.lang.Exception类。
    • C. unchecked异常继承java.lang.RuntimeException类。
    • D. NullPointerException,IllegalArgumentException属于unchecked exception。

    公众号有 600 道题库,答案,持续更新中

    关注公众号:回复关键词:“考试题” 获取全部答案

    展开全文
  • 关于序列化和反序列化是一个老生常谈的问题,在这里概述一下较为容易理解的内容。 备注:红色为重点 一、定义以及相关概念 基于OSI七层协议模型:  互联网的产生带来了机器间通讯的需求,而互联通讯的双方...

    关于序列化和反序列化是一个老生常谈的问题,在这里概述一下较为容易理解的内容。

    备注:红色为重点

    一、定义以及相关概念

    1. 基于OSI七层协议模型:

      互联网的产生带来了机器间通讯的需求,而互联通讯的双方需要采用约定的协议,序列化和反序列化属于通讯协议的一部分。通讯协议往往采用分层模型,不同模型每层的功能定义以及颗粒度不同,例如:TCP/IP协议是一个四层协议,而OSI模型却是七层协议模型。在OSI七层协议模型中展现层(Presentation Layer)的主要功能是把应用层的对象转换成一段连续的二进制串,或者反过来,把二进制串转换成应用层的对象--这两个功能就是序列化和反序列化。一般而言,TCP/IP协议的应用层对应与OSI七层协议模型的应用层,展示层和会话层,所以序列化协议属于TCP/IP协议应用层的一部分。

    • 序列化: 将数据结构或对象转换成二进制串的过程
    • 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程

    2.另一种说法:

    序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

    二、序列化协议特性(部分)

    可调试性/可读性

      序列化和反序列化的数据正确性和业务正确性的调试往往需要很长的时间,良好的调试机制会大大提高开发效率。序列化后的二进制串往往不具备人眼可读性,为了验证序列化结果的正确性,写入方不得同时撰写反序列化程序,或提供一个查询平台--这比较费时;另一方面,如果读取方未能成功实现反序列化,这将给问题查找带来了很大的挑战--难以定位是由于自身的反序列化程序的bug所导致还是由于写入方序列化后的错误数据所导致。对于跨公司间的调试,由于以下原因,问题会显得更严重:
      第一、支持不到位,跨公司调试在问题出现后可能得不到及时的支持,这大大延长了调试周期。
      第二、访问限制,调试阶段的查询平台未必对外公开,这增加了读取方的验证难度。

      如果序列化后的数据人眼可读,这将大大提高调试效率, XML和JSON就具有人眼可读的优点。

    性能

      性能包括两个方面,时间复杂度和空间复杂度:
      第一、空间开销(Verbosity), 序列化需要在原有的数据上加上描述字段,以为反序列化解析之用。如果序列化过程引入的额外开销过高,可能会导致过大的网络,磁盘等各方面的压力。对于海量分布式存储系统,数据量往往以TB为单位,巨大的的额外空间开销意味着高昂的成本。
      第二、时间开销(Complexity),复杂的序列化协议会导致较长的解析时间,这可能会使得序列化和反序列化阶段成为整个系统的瓶颈。

    三、几种常见的序列化和反序列化协议

    当下比较流行的序列化协议,包括XML、JSON、Protobuf、Thrift和Avro。

    关于上面的几种协议的相关知识可用在文章末尾的参考文章中学习或通过其他途径进行学习。

    四、问答

    Q:为什么一会儿说序列化是将将数据结构或对象转换成二进制串的过程,一会儿又说序列化是将对象的状态信息转换为可以存储或传输的形式的过程?

    A:其实,进行序列化的目的是为了跨机器,跨语言进行数据传输,最后还可能进行存储,而且被序列化后的数据结构或对象是否具有人眼可读可读性也是一个方面。在C#中,主要有BinaryFormatter、SoapFormatter、XmlSerializer以及Newtonsoft.Json中的JsonConvert这几种类型提供序列化功能。例如BinaryFormatter是将数据结构或对象序列化为二进制串(byte[]),不具备人眼可读性,数据正确性和业务正确性的调试往往需要很长的时间。相反如果将数据结构或对象序列化为Xml或Json,既满足了需求,又提升了可读性。

    Q:该怎样选择序列化协议?

    A:根据具体需求以及解析性能、空间开销等进行选择。例如:

    JSON在很多应用场景中可以替代XML,更简洁并且解析速度更快。典型应用场景包括:
      1、公司之间传输数据量相对小,实时性要求相对低(例如秒级别)的服务。
      2、基于Web browser的Ajax请求。
      3、由于JSON具有非常强的前后兼容性,对于接口经常发生变化,并对可调式性要求高的场景,例如Mobile app与服务端的通讯。
      4、由于JSON的典型应用场景是JSON+HTTP,适合跨防火墙访问。

    参考:http://kb.cnblogs.com/page/515982/

    转载于:https://www.cnblogs.com/muran/p/6817195.html

    展开全文
  • 序列化和反序列化的底层实现原理是什么?

    万次阅读 多人点赞 2018-04-07 13:53:41
    序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列化和反序列化的,就可能不知所措了!遥记当年也被问...

    序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列化和反序列化的,就可能不知所措了!遥记当年也被问了这一个问题,自信满满的说了一大堆,什么是序列化、什么是反序列化、什么场景的时候才会用到等,然后面试官说:那你能说一下序列化和反序列化底层是如何实现的吗?一脸懵逼,然后回家等通知!

    一、基本概念

    1、什么是序列化和反序列化

    (1)Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程;

    (2)**序列化:**对象序列化的最主要的用处就是在传递和保存对象的时候,保证对象的完整性和可传递性。序列化是把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。序列化后的字节流保存了Java对象的状态以及相关的描述信息。序列化机制的核心作用就是对象状态的保存与重建。

    (3)**反序列化:**客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。

    (4)本质上讲,序列化就是把实体对象状态按照一定的格式写入到有序字节流,反序列化就是从有序字节流重建对象,恢复对象状态。

    2、为什么需要序列化与反序列化

    我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。

    那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的!如何做到呢?这就需要Java序列化与反序列化了!

    换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。

    当我们明晰了为什么需要Java序列化和反序列化后,我们很自然地会想Java序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。

    总的来说可以归结为以下几点:

    (1)永久性保存对象,保存对象的字节序列到本地文件或者数据库中;
    (2)通过序列化以字节流的形式使对象在网络中进行传递和接收;
    (3)通过序列化在进程间传递对象;

    3、序列化算法一般会按步骤做如下事情:

    (1)将对象实例相关的类元数据输出。
    (2)递归地输出类的超类描述直到不再有超类。
    (3)类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。
    (4)从上至下递归输出实例的数据

    二、Java如何实现序列化和反序列化

    1、JDK类库中序列化和反序列化API

    (1)java.io.ObjectOutputStream:表示对象输出流;

    它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中;

    (2)java.io.ObjectInputStream:表示对象输入流;

    它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回;

    2、实现序列化的要求

    只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常!

    3、实现Java对象序列化与反序列化的方法

    假定一个User类,它的对象需要序列化,可以有如下三种方法:

    (1)若User类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化

    ObjectOutputStream采用默认的序列化方式,对User对象的非transient的实例变量进行序列化。
    ObjcetInputStream采用默认的反序列化方式,对对User对象的非transient的实例变量进行反序列化。

    (2)若User类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。

    ObjectOutputStream调用User对象的writeObject(ObjectOutputStream out)的方法进行序列化。
    ObjectInputStream会调用User对象的readObject(ObjectInputStream in)的方法进行反序列化。

    (3)若User类实现了Externalnalizable接口,且User类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。

    ObjectOutputStream调用User对象的writeExternal(ObjectOutput out))的方法进行序列化。
    ObjectInputStream会调用User对象的readExternal(ObjectInput in)的方法进行反序列化。

    4、JDK类库中序列化的步骤

    步骤一:创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:

    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\object.out"));
    

    步骤二:通过对象输出流的writeObject()方法写对象:

    oos.writeObject(new User("xuliugen", "123456", "male"));
    

    5、JDK类库中反序列化的步骤

    步骤一:创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:

    ObjectInputStream ois= new ObjectInputStream(new FileInputStream("object.out"));
    

    步骤二:通过对象输出流的readObject()方法读取对象:

    User user = (User) ois.readObject();
    

    说明:为了正确读取数据,完成反序列化,必须保证向对象输出流写对象的顺序与从对象输入流中读对象的顺序一致。

    6、序列化和反序列化的示例

    为了更好地理解Java序列化与反序列化,举一个简单的示例如下:

    public class SerialDemo {
    
        public static void main(String[] args) throws IOException, ClassNotFoundException {
    	    //序列化
            FileOutputStream fos = new FileOutputStream("object.out");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            User user1 = new User("xuliugen", "123456", "male");
            oos.writeObject(user1);
            oos.flush();
            oos.close();
    		//反序列化
            FileInputStream fis = new FileInputStream("object.out");
            ObjectInputStream ois = new ObjectInputStream(fis);
            User user2 = (User) ois.readObject();
            System.out.println(user2.getUserName()+ " " + 
    	        user2.getPassword() + " " + user2.getSex());
            //反序列化的输出结果为:xuliugen 123456 male
        }
    }
    
    public class User implements Serializable {
        private String userName;
        private String password;
        private String sex;
        //全参构造方法、get和set方法省略
    }
    
    

    object.out文件如下(使用UltraEdit打开):

    这里写图片描述

    注:上图中0000000h-000000c0h表示行号;0-f表示列;行后面的文字表示对这行16进制的解释;对上述字节码所表述的内容感兴趣的可以对照相关的资料,查阅一下每一个字符代表的含义,这里不在探讨!

    类似于我们Java代码编译之后的.class文件,每一个字符都代表一定的含义。序列化和反序列化的过程就是生成和解析上述字符的过程!

    序列化图示:

    这里写图片描述

    反序列化图示:

    这里写图片描述

    三、相关注意事项

    1、序列化时,只对对象的状态进行保存,而不管对象的方法;

    2、当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;

    3、当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

    4、并非所有的对象都可以序列化,至于为什么不可以,有很多原因了,比如:

    • 安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行RMI传输等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的;

    • 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分配,而且,也是没有必要这样实现;

    5、声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态,transient代表对象的临时数据。

    6、序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。为它赋予明确的值。显式地定义serialVersionUID有两种用途:

    • 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;

    • 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。

    7、Java有很多基础类已经实现了serializable接口,比如String,Vector等。但是也有一些没有实现serializable接口的;

    8、如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存!这是能用序列化解决深拷贝的重要原因;

    四、总结

    看到这里,可能已经让我们很满足了,毕竟已经知道了我们平时使用的序列化和反序列化是如何进行操作的,Java给我们提供了哪些接口可供使用,也比我们最初知道的简单的什么是序列化、反序列化以及作用多了很多!后续内容我们也会不断在讨论和更新!


    参考文章:

    1、https://zhidao.baidu.com/question/688891250408618484.html
    2、https://blog.csdn.net/morethinkmoretry/article/details/5929345
    3、https://www.jianshu.com/p/edcf7bd2c085
    4、https://blog.csdn.net/xiaocaidexuexibiji/article/details/22692097

    在这里插入图片描述

    【视频福利】2T免费学习视频,搜索或扫描上述二维码关注微信公众号:Java后端技术(ID: JavaITWork)回复:1024,即可免费获取!内含SSM、Spring全家桶、微服务、MySQL、MyCat、集群、分布式、中间件、Linux、网络、多线程,Jenkins、Nexus、Docker、ELK等等免费学习视频,持续更新!

    展开全文
  • 彻底理解序列化和反序列化

    千次阅读 2020-01-16 13:27:54
    目录 摘要 简介 一、定义以及相关概念 数据结构、对象与二进制串 二、序列化协议特性 通用性 强健性/鲁棒性 可调试性/可读性 ...三、序列化和反序列化的组件 序列化组件与数据库访问组件...

    https://tech.meituan.com/2015/02/26/serialization-vs-deserialization.html

    目录

    摘要

    简介

    一、定义以及相关概念

    数据结构、对象与二进制串

    二、序列化协议特性

    通用性

    强健性/鲁棒性

    可调试性/可读性

    性能

    可扩展性/兼容性

    安全性/访问限制

    三、序列化和反序列化的组件

    序列化组件与数据库访问组件的对比

    四、几种常见的序列化和反序列化协议

    一个例子

    XML&SOAP

    Thrift

    Protobuf

    Avro

    五、Benchmark以及选型建议

    Benchmark

    选型建议

    参考文献:


    摘要

    序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中;另一方面,它们会以其他更容易理解的概念出现,例如加密、持久化。然而,序列化和反序列化的选型却是系统设计或重构一个重要的环节,在分布式、大数据量系统设计里面更为显著。恰当的序列化协议不仅可以提高系统的通用性、强健性、安全性、优化系统性能,而且会让系统更加易于调试、便于扩展。本文从多个角度去分析和讲解“序列化和反序列化”,并对比了当前流行的几种序列化协议,期望对读者做序列化选型有所帮助。

    简介

    文章作者服务于美团推荐与个性化组,该组致力于为美团用户提供每天billion级别的高质量个性化推荐以及排序服务。从Terabyte级别的用户行为数据,到Gigabyte级别的Deal/Poi数据;从对实时性要求毫秒以内的用户实时地理位置数据,到定期后台job数据,推荐与重排序系统需要多种类型的数据服务。推荐与重排序系统客户包括各种内部服务、美团客户端、美团网站。为了提供高质量的数据服务,为了实现与上下游各系统进行良好的对接,序列化和反序列化的选型往往是我们做系统设计的一个重要考虑因素。

    本文内容按如下方式组织:

    • 第一部分给出了序列化和反序列化的定义,以及其在通讯协议中所处的位置。
    • 第二部分从使用者的角度探讨了序列化协议的一些特性。
    • 第三部分描述在具体的实施过程中典型的序列化组件,并与数据库组建进行了类比。
    • 第四部分分别讲解了目前常见的几种序列化协议的特性,应用场景,并对相关组件进行举例。
    • 最后一部分,基于各种协议的特性,以及相关benchmark数据,给出了作者的技术选型建议。

    一、定义以及相关概念

    互联网的产生带来了机器间通讯的需求,而互联通讯的双方需要采用约定的协议,序列化和反序列化属于通讯协议的一部分。通讯协议往往采用分层模型,不同模型每层的功能定义以及颗粒度不同,例如:TCP/IP协议是一个四层协议,而OSI模型却是七层协议模型。在OSI七层协议模型中展现层(Presentation Layer)的主要功能是把应用层的对象转换成一段连续的二进制串,或者反过来,把二进制串转换成应用层的对象–这两个功能就是序列化和反序列化。一般而言,TCP/IP协议的应用层对应与OSI七层协议模型的应用层,展示层和会话层,所以序列化协议属于TCP/IP协议应用层的一部分。本文对序列化协议的讲解主要基于OSI七层协议模型。

    • 序列化: 将数据结构或对象转换成二进制串的过程
    • 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程

    数据结构、对象与二进制串

    不同的计算机语言中,数据结构,对象以及二进制串的表示方式并不相同。

    数据结构和对象:对于类似Java这种完全面向对象的语言,工程师所操作的一切都是对象(Object),来自于类的实例化。在Java语言中最接近数据结构的概念,就是POJO(Plain Old Java Object)或者Javabean--那些只有setter/getter方法的类。而在C++这种半面向对象的语言中,数据结构和struct对应,对象和class对应。

    二进制串:序列化所生成的二进制串指的是存储在内存中的一块数据。C++语言具有内存操作符,所以二进制串的概念容易理解,例如,C++语言的字符串可以直接被传输层使用,因为其本质上就是以’\0’结尾的存储在内存中的二进制串。在Java语言里面,二进制串的概念容易和String混淆。实际上String 是Java的一等公民,是一种特殊对象(Object)。对于跨语言间的通讯,序列化后的数据当然不能是某种语言的特殊数据类型。二进制串在Java里面所指的是byte[],byte是Java的8中原生数据类型之一(Primitive data types)。

    二、序列化协议特性

    每种序列化协议都有优点和缺点,它们在设计之初有自己独特的应用场景。在系统设计的过程中,需要考虑序列化需求的方方面面,综合对比各种序列化协议的特性,最终给出一个折衷的方案。

    通用性

    通用性有两个层面的意义:

    第一、技术层面,序列化协议是否支持跨平台、跨语言。如果不支持,在技术层面上的通用性就大大降低了。

    第二、流行程度,序列化和反序列化需要多方参与,很少人使用的协议往往意味着昂贵的学习成本;另一方面,流行度低的协议,往往缺乏稳定而成熟的跨语言、跨平台的公共包。

    强健性/鲁棒性

    以下两个方面的原因会导致协议不够强健:

    第一、成熟度不够,一个协议从制定到实施,到最后成熟往往是一个漫长的阶段。协议的强健性依赖于大量而全面的测试,对于致力于提供高质量服务的系统,采用处于测试阶段的序列化协议会带来很高的风险。

    第二、语言/平台的不公平性。为了支持跨语言、跨平台的功能,序列化协议的制定者需要做大量的工作;但是,当所支持的语言或者平台之间存在难以调和的特性的时候,协议制定者需要做一个艰难的决定–支持更多人使用的语言/平台,亦或支持更多的语言/平台而放弃某个特性。当协议的制定者决定为某种语言或平台提供更多支持的时候,对于使用者而言,协议的强健性就被牺牲了。

    可调试性/可读性

    序列化和反序列化的数据正确性和业务正确性的调试往往需要很长的时间,良好的调试机制会大大提高开发效率。序列化后的二进制串往往不具备人眼可读性,为了验证序列化结果的正确性,写入方不得同时撰写反序列化程序,或提供一个查询平台–这比较费时;另一方面,如果读取方未能成功实现反序列化,这将给问题查找带来了很大的挑战–难以定位是由于自身的反序列化程序的bug所导致还是由于写入方序列化后的错误数据所导致。对于跨公司间的调试,由于以下原因,问题会显得更严重:

    第一、支持不到位,跨公司调试在问题出现后可能得不到及时的支持,这大大延长了调试周期。

    第二、访问限制,调试阶段的查询平台未必对外公开,这增加了读取方的验证难度。

    如果序列化后的数据人眼可读,这将大大提高调试效率, XML和JSON就具有人眼可读的优点。

    性能

    性能包括两个方面,时间复杂度和空间复杂度:

    第一、空间开销(Verbosity), 序列化需要在原有的数据上加上描述字段,以为反序列化解析之用。如果序列化过程引入的额外开销过高,可能会导致过大的网络,磁盘等各方面的压力。对于海量分布式存储系统,数据量往往以TB为单位,巨大的的额外空间开销意味着高昂的成本。

    第二、时间开销(Complexity),复杂的序列化协议会导致较长的解析时间,这可能会使得序列化和反序列化阶段成为整个系统的瓶颈。

    可扩展性/兼容性

    移动互联时代,业务系统需求的更新周期变得更快,新的需求不断涌现,而老的系统还是需要继续维护。如果序列化协议具有良好的可扩展性,支持自动增加新的业务字段,而不影响老的服务,这将大大提供系统的灵活度。

    安全性/访问限制

    在序列化选型的过程中,安全性的考虑往往发生在跨局域网访问的场景。当通讯发生在公司之间或者跨机房的时候,出于安全的考虑,对于跨局域网的访问往往被限制为基于HTTP/HTTPS的80和443端口。如果使用的序列化协议没有兼容而成熟的HTTP传输层框架支持,可能会导致以下三种结果之一:

    第一、因为访问限制而降低服务可用性。 第二、被迫重新实现安全协议而导致实施成本大大提高。 第三、开放更多的防火墙端口和协议访问,而牺牲安全性。

    三、序列化和反序列化的组件

    典型的序列化和反序列化过程往往需要如下组件:

    • IDL(Interface description language)文件:参与通讯的各方需要对通讯的内容需要做相关的约定(Specifications)。为了建立一个与语言和平台无关的约定,这个约定需要采用与具体开发语言、平台无关的语言来进行描述。这种语言被称为接口描述语言(IDL),采用IDL撰写的协议约定称之为IDL文件。
    • IDL Compiler:IDL文件中约定的内容为了在各语言和平台可见,需要有一个编译器,将IDL文件转换成各语言对应的动态库。
    • Stub/Skeleton Lib:负责序列化和反序列化的工作代码。Stub是一段部署在分布式系统客户端的代码,一方面接收应用层的参数,并对其序列化后通过底层协议栈发送到服务端,另一方面接收服务端序列化后的结果数据,反序列化后交给客户端应用层;Skeleton部署在服务端,其功能与Stub相反,从传输层接收序列化参数,反序列化后交给服务端应用层,并将应用层的执行结果序列化后最终传送给客户端Stub。
    • Client/Server:指的是应用层程序代码,他们面对的是IDL所生存的特定语言的class或struct。
    • 底层协议栈和互联网:序列化之后的数据通过底层的传输层、网络层、链路层以及物理层协议转换成数字信号在互联网中传递。

    序列化组件与数据库访问组件的对比

    数据库访问对于很多工程师来说相对熟悉,所用到的组件也相对容易理解。下表类比了序列化过程中用到的部分组件和数据库访问组件的对应关系,以便于大家更好的把握序列化相关组件的概念。

    序列化组件数据库组件说明
    IDLDDL用于建表或者模型的语言
    DL fileDB Schema表创建文件或模型文件
    Stub/Skeleton libO/R mapping将class和Table或者数据模型进行映射

     

    四、几种常见的序列化和反序列化协议

    互联网早期的序列化协议主要有COM和CORBA。

    COM主要用于Windows平台,并没有真正实现跨平台,另外COM的序列化的原理利用了编译器中虚表,使得其学习成本巨大(想一下这个场景, 工程师需要是简单的序列化协议,但却要先掌握语言编译器)。由于序列化的数据与编译器紧耦合,扩展属性非常麻烦。

    CORBA是早期比较好的实现了跨平台,跨语言的序列化协议。COBRA的主要问题是参与方过多带来的版本过多,版本之间兼容性较差,以及使用复杂晦涩。这些政治经济,技术实现以及早期设计不成熟的问题,最终导致COBRA的渐渐消亡。J2SE 1.3之后的版本提供了基于CORBA协议的RMI-IIOP技术,这使得Java开发者可以采用纯粹的Java语言进行CORBA的开发。

    这里主要介绍和对比几种当下比较流行的序列化协议,包括XML、JSON、Protobuf、Thrift和Avro。

    一个例子

    如前所述,序列化和反序列化的出现往往晦涩而隐蔽,与其他概念之间往往相互包容。为了更好了让大家理解序列化和反序列化的相关概念在每种协议里面的具体实现,我们将一个例子穿插在各种序列化协议讲解中。在该例子中,我们希望将一个用户信息在多个系统里面进行传递;在应用层,如果采用Java语言,所面对的类对象如下所示:

    class Address
    {
        private String city;
        private String postcode;
        private String street;
    }
    public class UserInfo
    {
        private Integer userid;
        private String name;
        private List<Address> address;
    }
    

    XML&SOAP

    XML是一种常用的序列化和反序列化协议,具有跨机器,跨语言等优点。 XML历史悠久,其1.0版本早在1998年就形成标准,并被广泛使用至今。XML的最初产生目标是对互联网文档(Document)进行标记,所以它的设计理念中就包含了对于人和机器都具备可读性。 但是,当这种标记文档的设计被用来序列化对象的时候,就显得冗长而复杂(Verbose and Complex)。 XML本质上是一种描述语言,并且具有自我描述(Self-describing)的属性,所以XML自身就被用于XML序列化的IDL。 标准的XML描述格式有两种:DTD(Document Type Definition)和XSD(XML Schema Definition)。作为一种人眼可读(Human-readable)的描述语言,XML被广泛使用在配置文件中,例如O/R mapping、 Spring Bean Configuration File 等。

    SOAP(Simple Object Access protocol) 是一种被广泛应用的,基于XML为序列化和反序列化协议的结构化消息传递协议。SOAP在互联网影响如此大,以至于我们给基于SOAP的解决方案一个特定的名称–Web service。SOAP虽然可以支持多种传输层协议,不过SOAP最常见的使用方式还是XML+HTTP。SOAP协议的主要接口描述语言(IDL)是WSDL(Web Service Description Language)。SOAP具有安全、可扩展、跨语言、跨平台并支持多种传输层协议。如果不考虑跨平台和跨语言的需求,XML的在某些语言里面具有非常简单易用的序列化使用方法,无需IDL文件和第三方编译器, 例如Java+XStream。

    自我描述与递归

    SOAP是一种采用XML进行序列化和反序列化的协议,它的IDL是WSDL. 而WSDL的描述文件是XSD,而XSD自身是一种XML文件。 这里产生了一种有趣的在数学上称之为“递归”的问题,这种现象往往发生在一些具有自我属性(Self-description)的事物上。

    IDL文件举例

    采用WSDL描述上述用户基本信息的例子如下:

    <xsd:complexType name='Address'>
         <xsd:attribute name='city' type='xsd:string' />
         <xsd:attribute name='postcode' type='xsd:string' />
         <xsd:attribute name='street' type='xsd:string' />
    </xsd:complexType>
    <xsd:complexType name='UserInfo'>
         <xsd:sequence>
         <xsd:element name='address' type='tns:Address'/>
         <xsd:element name='address1' type='tns:Address'/> 
         </xsd:sequence>
         <xsd:attribute name='userid' type='xsd:int' />
         <xsd:attribute name='name' type='xsd:string' /> 
    </xsd:complexType>
    

    典型应用场景和非应用场景

    SOAP协议具有广泛的群众基础,基于HTTP的传输协议使得其在穿越防火墙时具有良好安全特性,XML所具有的人眼可读(Human-readable)特性使得其具有出众的可调试性,互联网带宽的日益剧增也大大弥补了其空间开销大(Verbose)的缺点。对于在公司之间传输数据量相对小或者实时性要求相对低(例如秒级别)的服务是一个好的选择。

    由于XML的额外空间开销大,序列化之后的数据量剧增,对于数据量巨大序列持久化应用常景,这意味着巨大的内存和磁盘开销,不太适合XML。另外,XML的序列化和反序列化的空间和时间开销都比较大,对于对性能要求在ms级别的服务,不推荐使用。WSDL虽然具备了描述对象的能力,SOAP的S代表的也是simple,但是SOAP的使用绝对不简单。对于习惯于面向对象编程的用户,WSDL文件不直观。

    JSON(Javascript Object Notation)

    JSON起源于弱类型语言Javascript, 它的产生来自于一种称之为”Associative array”的概念,其本质是就是采用”Attribute-value”的方式来描述对象。实际上在Javascript和PHP等弱类型语言中,类的描述方式就是Associative array。JSON的如下优点,使得它快速成为最广泛使用的序列化协议之一:

    1、这种Associative array格式非常符合工程师对对象的理解。

    2、它保持了XML的人眼可读(Human-readable)的优点

    3、相对于XML而言,序列化后的数据更加简洁。 来自于的以下链接的研究表明:XML所产生序列化之后文件的大小接近JSON的两倍。http://www.codeproject.com/Articles/604720/JSON-vs-XML-Some-hard-numbers-about-verbosity 。

    4、它具备Javascript的先天性支持,所以被广泛应用于Web browser的应用常景中,是Ajax的事实标准协议。

    5、与XML相比,其协议比较简单,解析速度比较快。

    6、松散的Associative array使得其具有良好的可扩展性和兼容性。

    IDL悖论

    JSON实在是太简单了,或者说太像各种语言里面的类了,所以采用JSON进行序列化不需要IDL。这实在是太神奇了,存在一种天然的序列化协议,自身就实现了跨语言和跨平台。然而事实没有那么神奇,之所以产生这种假象,来自于两个原因:

    第一、Associative array在弱类型语言里面就是类的概念,在PHP和Javascript里面Associative array就是其class的实际实现方式,所以在这些弱类型语言里面,JSON得到了非常良好的支持。

    第二、IDL的目的是撰写IDL文件,而IDL文件被IDL Compiler编译后能够产生一些代码(Stub/Skeleton),而这些代码是真正负责相应的序列化和反序列化工作的组件。 但是由于Associative array和一般语言里面的class太像了,他们之间形成了一一对应关系,这就使得我们可以采用一套标准的代码进行相应的转化。对于自身支持Associative array的弱类型语言,语言自身就具备操作JSON序列化后的数据的能力;对于Java这强类型语言,可以采用反射的方式统一解决,例如Google提供的Gson。

    典型应用场景和非应用场景

    JSON在很多应用场景中可以替代XML,更简洁并且解析速度更快。典型应用场景包括:

    1、公司之间传输数据量相对小,实时性要求相对低(例如秒级别)的服务。

    2、基于Web browser的Ajax请求。

    3、由于JSON具有非常强的前后兼容性,对于接口经常发生变化,并对可调式性要求高的场景,例如Mobile app与服务端的通讯。

    4、由于JSON的典型应用场景是JSON+HTTP,适合跨防火墙访问。

    总的来说,采用JSON进行序列化的额外空间开销比较大,对于大数据量服务或持久化,这意味着巨大的内存和磁盘开销,这种场景不适合。没有统一可用的IDL降低了对参与方的约束,实际操作中往往只能采用文档方式来进行约定,这可能会给调试带来一些不便,延长开发周期。 由于JSON在一些语言中的序列化和反序列化需要采用反射机制,所以在性能要求为ms级别,不建议使用。

    IDL文件举例

    以下是UserInfo序列化之后的一个例子:

    {"userid":1,
     "name":"messi",
     "address":[{
         "city":"北京",
         "postcode":"1000000",
         "street":"wangjingdonglu"
     }]
    }

    Thrift

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

    典型应用场景和非应用场景

    对于需求为高性能,分布式的RPC服务,Thrift是一个优秀的解决方案。它支持众多语言和丰富的数据类型,并对于数据字段的增删具有较强的兼容性。所以非常适用于作为公司内部的面向服务构建(SOA)的标准RPC框架。

    不过Thrift的文档相对比较缺乏,目前使用的群众基础相对较少。另外由于其Server是基于自身的Socket服务,所以在跨防火墙访问时,安全是一个顾虑,所以在公司间进行通讯时需要谨慎。 另外Thrift序列化之后的数据是Binary数组,不具有可读性,调试代码时相对困难。最后,由于Thrift的序列化和框架紧耦合,无法支持向持久层直接读写数据,所以不适合做数据持久化序列化协议。

    IDL文件举例

    struct Address
    { 
        1: required string city;
        2: optional string postcode;
        3: optional string street;
    } 
    struct UserInfo
    { 
        1: required string userid;
        2: required i32 name;
        3: optional list<Address> address;
    }
    

     

    Protobuf

    Protobuf具备了优秀的序列化协议的所需的众多典型特征:

    1、标准的IDL和IDL编译器,这使得其对工程师非常友好。

    2、序列化数据非常简洁,紧凑,与XML相比,其序列化之后的数据量约为1/3到1/10。

    3、解析速度非常快,比对应的XML快约20-100倍。

    4、提供了非常友好的动态库,使用非常简介,反序列化只需要一行代码。

    Protobuf是一个纯粹的展示层协议,可以和各种传输层协议一起使用;Protobuf的文档也非常完善。 但是由于Protobuf产生于Google,所以目前其仅仅支持Java、C++、Python三种语言。另外Protobuf支持的数据类型相对较少,不支持常量类型。由于其设计的理念是纯粹的展现层协议(Presentation Layer),目前并没有一个专门支持Protobuf的RPC框架

    典型应用场景和非应用场景

    Protobuf具有广泛的用户基础,空间开销小以及高解析性能是其亮点,非常适合于公司内部的对性能要求高的RPC调用。由于Protobuf提供了标准的IDL以及对应的编译器,其IDL文件是参与各方的非常强的业务约束,另外,Protobuf与传输层无关,采用HTTP具有良好的跨防火墙的访问属性,所以Protobuf也适用于公司间对性能要求比较高的场景。由于其解析性能高,序列化后数据量相对少,非常适合应用层对象的持久化场景。

    它的主要问题在于其所支持的语言相对较少,另外由于没有绑定的标准底层传输层协议,在公司间进行传输层协议的调试工作相对麻烦。

    IDL文件举例

    message Address
    {
    	required string city=1;
        	optional string postcode=2;
        	optional string street=3;
    }
    message UserInfo
    {
    	required string userid=1;
    	required string name=2;
    	repeated Address address=3;
    }
    

     

    Avro

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

    典型应用场景和非应用场景

    Avro解析性能高并且序列化之后的数据非常简洁,比较适合于高性能的序列化服务。

    由于Avro目前非JSON格式的IDL处于实验阶段,而JSON格式的IDL对于习惯于静态类型语言的工程师来说不直观。

    IDL文件举例

    protocol Userservice {
      record Address {
       string city;
       string postcode;
       string street;
      }  
      record UserInfo {
       string name;
       int userid;
       array<Address> address = [];
      }
    } 
    

    essess所对应的JSON Schema格式如下:

    {
      "protocol" : "Userservice",
      "namespace" : "org.apache.avro.ipc.specific",
      "version" : "1.0.5",
      "types" : [ {
        "type" : "record",
        "name" : "Address",
        "fields" : [ {
          "name" : "city",
          "type" : "string"
        }, {
          "name" : "postcode",
          "type" : "string"
        }, {
          "name" : "street",
          "type" : "string"
        } ]
      }, {
        "type" : "record",
        "name" : "UserInfo",
        "fields" : [ {
          "name" : "name",
          "type" : "string"
        }, {
          "name" : "userid",
          "type" : "int"
        }, {
          "name" : "address",
          "type" : {
            "type" : "array",
            "items" : "Address"
          },
          "default" : [ ]
        } ]
      } ],
      "messages" : { }
    }
    
    

    五、Benchmark以及选型建议

    Benchmark

    以下数据来自https://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

    解析性能

    序列化之空间开销

    从上图可得出如下结论:

    1、XML序列化(Xstream)无论在性能和简洁性上比较差。

    2、Thrift与Protobuf相比在时空开销方面都有一定的劣势。

    3、Protobuf和Avro在两方面表现都非常优越。

    选型建议

    以上描述的五种序列化和反序列化协议都各自具有相应的特点,适用于不同的场景:

    1、对于公司间的系统调用,如果性能要求在100ms以上的服务,基于XML的SOAP协议是一个值得考虑的方案。

    2、基于Web browser的Ajax,以及Mobile app与服务端之间的通讯,JSON协议是首选。对于性能要求不太高,或者以动态类型语言为主,或者传输数据载荷很小的的运用场景,JSON也是非常不错的选择。

    3、对于调试环境比较恶劣的场景,采用JSON或XML能够极大的提高调试效率,降低系统开发成本。

    4、当对性能和简洁性有极高要求的场景,Protobuf,Thrift,Avro之间具有一定的竞争关系

    5、对于T级别的数据的持久化应用场景,Protobuf和Avro是首要选择。如果持久化后的数据存储在Hadoop子项目里,Avro会是更好的选择。

    6、由于Avro的设计理念偏向于动态类型语言,对于动态语言为主的应用场景,Avro是更好的选择。

    7、对于持久层非Hadoop项目,以静态类型语言为主的应用场景,Protobuf会更符合静态类型语言工程师的开发习惯。

    8、如果需要提供一个完整的RPC解决方案,Thrift是一个好的选择。

    9、如果序列化之后需要支持不同的传输层协议,或者需要跨防火墙访问的高性能场景,Protobuf可以优先考虑。

    参考文献:

    展开全文
  • RPC之对象序列化/反序列化

    千次阅读 2020-04-14 20:40:30
    从传统的单体服务到现在的分布式服务,微服务截然已经成为主流。RPC作为微服务最重要的核心模块之一,也越来越受到关注...服务调用方(consumer)将数据序列化打包通过网络模块传给服务提供方(provider)。provider...
  • java序列化错误

    2019-04-08 17:58:52
    1.在BaseEntity中添加一个瞬时态属性,启动访问首页保错 解决方案: redis的问题,我把信息放到redis里面,重启项目后就出现了这样的情况。...把redis服务关闭或者清空后再登录就好了。......
  • 本文展示通过序列化将自定义数据结构序列化到硬盘文件中,再从文件反序列出来还原数据信息。 Qt中序列化与反序列化 Qt中使用QDataStream类实现对象序列化序列化: QFile file("file.rx"); //定义文件路径 ...
  • 序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列化和反序列化的,就可能不知所措了!遥记当年也被问...
  • 序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列化和反序列化的,就可能不知所措了!遥记当年也被问...
  • Jackson实现xml序列化和反序列化

    千次阅读 2019-08-23 18:25:32
    Jackson实现xml序列化和反序列化 本文介绍Jackson 2.X中提供的xml序列化功能。仅介绍基本操作,不涉及复杂和自定义功能。 1. XmlMapper对象 XmlMapper是Jackson 2.x中提供我们实现xml序列化的主要类,因此首先需要...
  • 于是,我们需要对自己写的类进行序列化的操作机会变少了。 但,若我们对序列化有了了解,总是对于理解一些问题有帮助的。(其中序列化三个字可以换成任何技术) 今天要说的就是下面这个东西 static final long ...
  • Unity 中XML序列化和反序列化

    千次阅读 2017-09-20 20:37:56
    **序列化名词解释:序列化是将对象状态转换为可保持或传输的格式的过程。 与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。这就是序列化的意义所在。**XML序列化的...
  • 序列化和反序列化

    2016-01-07 14:51:57
    序列化和反序列化 作者刘丁 发布于 2015年5月7日 | 3 讨论 简介 文章作者服务于美团推荐与个性化组,该组致力于为美团用户提供每天billion级别的高质量个性化推荐以及排序服务。从Terabyte级别的用户行为...
  • 一、基本概念 1、什么是序列化和反序列化 (1)Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程;...序列化后的字节流保存了Java对象的状态以及相关的描述...
  • 几种常用序列化和反序列化方法

    千次阅读 2019-12-30 21:48:38
    序列化和反序列化几乎是工程师们每天都要面对的事情,但是要精确掌握这两个概念并不容易:一方面,它们往往作为框架的一部分出现而湮没在框架之中;另一方面,它们会以其他更容易理解的概念出现,例如加密、持久化。...
  • 前言:何为序列化序列化就是一种处理对象流的机制,即将对象的内容流化,将数据分解成字节流,以便存储在文件中或用于在网络中传输,用的最多的场景就是在多个进程之间进行数据通信。实现序列化只需让要实现的实体...
  • 使用FlatBuffers序列化数据

    千次阅读 2019-08-27 13:40:44
    序列化 简介 序列化主要用于需要持久化或通过网络传输的应用中。 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。...
  • 一、序列化和反序列化的概念  把对象转换为字节序列的过程称为对象的序列化。  把字节序列恢复为对象的过程称为对象的反序列化。  对象的序列化主要有两种用途:  1) 把对象的字节序列永久地保存到硬盘上,...
  • 人们可能有多种原因想要使用自定义序列化而不是依赖Java的默认序列化。 最常见的原因之一是为了提高性能,但是编写自定义序列化的另一个原因是不支持默认序列化机制。 具体来说,如本博文所述,自定义序列化可用于...
  • 序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列化和反序列化的,就可能不知所措了!遥记当年也被问...
  • 数据序列化和反序列化 支持RPC通信 1.为什么要进行序列化 可以通过Java的原生序列化来理解,我们经常用到Java的Serializable接口,主要是因为 网络传输数据需要做序列化 将数据做持久化需要做序列化 2.序列化的...
  • C++之序列化

    2020-07-10 17:37:17
    文章目录序列化和反序列化JSONMessagePackProtoBuffer 小结: JSON 是纯文本,容易阅读,方便编辑,适用性最广; MessagePack 是二进制,小巧高效,在开源界接受程度比较高; ProtoBuffer 是工业级的数据格式,注重...
  • 0 前言 全是干货的技术殿堂 文章收录在我的 GitHub 仓库,欢迎Star/fork: ...Java序列化是指把Java对象保存为二进制字节码的过程,Java反序列化是指把二进制码重新转换成Java对象的过程。 那么为什么需要序列...
  • 前言 现实需求 每种编程语言都有自己的...把内存中的各种数据类型的数据保存到本地磁盘持久 数据格式 如果要将一个系统内的数据通过网络传输给其它系统或者客户端,我们通常都需要先把这些数据转化为字符或字符...
  • java序列化中的自定义方法 在Java中通过默认序列化写和读的方法是有比较大的风险的,Java允许我们通过编写writeObject、readObject、writeReplace、readresolve、readObjectNoData等方法,来实现Java的自定义序列化...
  • Java序列化关于Serializable的解释

    千次阅读 2016-05-02 15:36:44
     Serializable接口 标记类可以被序列化(ObjectOutputStream)和反序列化(ObjectInputStream) 暴露了类的内存代表二进制数据,private的属性域不安全。默认的序列化将Object的Class name, non-tranient fields ...
  • 序列化和反序列化作为Java里一个较为基础的知识点,大家心里也有那么几句要说的,但我相信很多小伙伴掌握的也就是那么几句而已,如果再深究问一下Java如何实现序列化和反序列化的,就可能不知所措了!遥记当年也被问...
  • JAVA中序列化和反序列化中的静态成员问题

    千次阅读 多人点赞 2015-11-22 14:13:25
    JAVA的序列化和反序列化中的静态成员问题  关于这个标题的内容是面试笔试中比较常见的考题,大家跟随我的博客一起来学习下这个过程。  JAVA中的序列化和反序列化主要用于: (1)将对象或者异常等写入文件,...
  • 很多商业项目用到数据库、内存映射文件和普通文件来完成项目中的序列化处理的需求,但是这些方法很少会依靠于Java序列化。本文也不是用来解释序列化的,而是一起来看看面试中有关序列化的问题,这些问题你很有可能不...
  • 序列化是指把对象转换为字节序列的过程,我们称之为对象的序列化,就是把内存中的这些对象变成一连串的字节(bytes)描述的过程,也就是把一个对象,保存到一个持久的文件中,而ObjectOutputStream 类就是用来做这个事...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 157,000
精华内容 62,800
关键字:

关于序列化描述正确的是