序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。

沙海 2021年6月16日12:13:54Java评论34字数 3896阅读12分59秒阅读模式
摘要

序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。 点击关注 ? Java面试那些事儿

序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。

点击关注 ? Java面试那些事儿 文章源自JAVA秀-https://www.javaxiu.com/32675.html

收录于话题文章源自JAVA秀-https://www.javaxiu.com/32675.html

#Java面试那些事儿文章源自JAVA秀-https://www.javaxiu.com/32675.html

174个文章源自JAVA秀-https://www.javaxiu.com/32675.html

大家好,我是D哥点击关注下方公众号,Java面试资料 都在这里

文章源自JAVA秀-https://www.javaxiu.com/32675.html

来源:https://my.oschina.net/xiaolei123/blog/3085607文章源自JAVA秀-https://www.javaxiu.com/32675.html

# 介绍

文章源自JAVA秀-https://www.javaxiu.com/32675.html

ProtoBuf 是google团队开发的用于高效存储和读取结构化数据的工具。什么是结构化数据呢,正如字面上表达的,就是带有一定结构的数据。比如电话簿上有很多记录数据,每条记录包含姓名、ID、邮件、电话等,这种结构重复出现。文章源自JAVA秀-https://www.javaxiu.com/32675.html

# 同类

文章源自JAVA秀-https://www.javaxiu.com/32675.html

XML、JSON 也可以用来存储此类结构化数据,但是使用ProtoBuf表示的数据能更加高效,并且将数据压缩得更小。文章源自JAVA秀-https://www.javaxiu.com/32675.html

文章源自JAVA秀-https://www.javaxiu.com/32675.html

# 原理

文章源自JAVA秀-https://www.javaxiu.com/32675.html

ProtoBuf 是通过ProtoBuf编译器将与编程语言无关的特有的 .proto 后缀的数据结构文件编译成各个编程语言(Java,C/C++,Python)专用的类文件,然后通过Google提供的各个编程语言的支持库lib即可调用API。(关于proto结构体怎么编写,可自行查阅文档)文章源自JAVA秀-https://www.javaxiu.com/32675.html

文章源自JAVA秀-https://www.javaxiu.com/32675.html

# ProtoBuf编译器安装

文章源自JAVA秀-https://www.javaxiu.com/32675.html

Mac : brew install protobuf文章源自JAVA秀-https://www.javaxiu.com/32675.html

# 举个例子

文章源自JAVA秀-https://www.javaxiu.com/32675.html

1.先创建一个proto文件

文章源自JAVA秀-https://www.javaxiu.com/32675.html

message.proto文章源自JAVA秀-https://www.javaxiu.com/32675.html

    syntax = "proto3";message Person {int32 id = 1;string name = 2;repeated Phone phone = 4;enum PhoneType {MOBILE = 0;HOME = 1;WORK = 2; }message Phone {string number = 1;PhoneType type = 2; }}
    文章源自JAVA秀-https://www.javaxiu.com/32675.html

    2. 创建一个Java项目

    文章源自JAVA秀-https://www.javaxiu.com/32675.html

    并且将proto文件放置 src/main/proto 文件夹下文章源自JAVA秀-https://www.javaxiu.com/32675.html

    文章源自JAVA秀-https://www.javaxiu.com/32675.html

    3. 编译proto文件至Java版本

    文章源自JAVA秀-https://www.javaxiu.com/32675.html

    用命令行 cd 到 src/main 目录下文章源自JAVA秀-https://www.javaxiu.com/32675.html

    文章源自JAVA秀-https://www.javaxiu.com/32675.html

    终端执行命令 : protoc --java_out=./java ./proto/*.proto文章源自JAVA秀-https://www.javaxiu.com/32675.html

    文章源自JAVA秀-https://www.javaxiu.com/32675.html

    会发现,在你的src/main/java 里已经生成里对应的Java类文章源自JAVA秀-https://www.javaxiu.com/32675.html

    文章源自JAVA秀-https://www.javaxiu.com/32675.html

    4. 依赖Java版本的ProtoBuf支持库

    文章源自JAVA秀-https://www.javaxiu.com/32675.html

    这里只举一个用Gradle使用依赖的栗子文章源自JAVA秀-https://www.javaxiu.com/32675.html

      implementation'com.google.protobuf:protobuf-java:3.9.1'
      文章源自JAVA秀-https://www.javaxiu.com/32675.html

      5. 将Java对象转为ProtoBuf数据

        Message.Person.Phone.Builder phoneBuilder = Message.Person.Phone.newBuilder();Message.Person.Phone phone1 = phoneBuilder .setNumber("100860") .setType(Message.Person.PhoneType.HOME) .build();Message.Person.Phone phone2 = phoneBuilder .setNumber("100100") .setType(Message.Person.PhoneType.MOBILE) .build();Message.Person.Builder personBuilder = Message.Person.newBuilder();personBuilder.setId(1994);personBuilder.setName("XIAOLEI");personBuilder.addPhone(phone1);personBuilder.addPhone(phone2);Message.Person person = personBuilder.build();long old = System.currentTimeMillis();byte[] buff = person.toByteArray();System.out.println("ProtoBuf 编码耗时:" + (System.currentTimeMillis() - old));System.out.println(Arrays.toString(buff));System.out.println("ProtoBuf 数据长度:" + buff.length);
        文章源自JAVA秀-https://www.javaxiu.com/32675.html

        6. 将ProtoBuf数据,转换回Java对象

          System.out.println("-开始解码-");old = System.currentTimeMillis();Message.Person personOut = Message.Person.parseFrom(buff);System.out.println("ProtoBuf 解码耗时:" + (System.currentTimeMillis() - old));System.out.printf("Id:%d, Name:%s\n", personOut.getId(), personOut.getName());List<Message.Person.Phone> phoneList = personOut.getPhoneList();for (Message.Person.Phone phone : phoneList){ System.out.printf("手机号:%s (%s)\n", phone.getNumber(), phone.getType());}
          文章源自JAVA秀-https://www.javaxiu.com/32675.html

          # 比较

          文章源自JAVA秀-https://www.javaxiu.com/32675.html

          为了能体现ProtoBuf的优势,我写了同样结构体的Java类,并且将Java对象转换成JSON数据,来与ProtoBuf进行比较。JSON编译库使用Google提供的GSON库,JSON的部分代码就不贴出来了,直接展示结果文章源自JAVA秀-https://www.javaxiu.com/32675.html

          文章源自JAVA秀-https://www.javaxiu.com/32675.html

          # 比较结果结果

          文章源自JAVA秀-https://www.javaxiu.com/32675.html

          运行 1 次文章源自JAVA秀-https://www.javaxiu.com/32675.html

            【JSON 开始编码 】JSON编码1次,耗时:22msJSON数据长度:106-开始解码-JSON解码1次,耗时:1ms【ProtoBuf 开始编码 】ProtoBuf编码1次,耗时:32msProtoBuf数据长度:34-开始解码-ProtoBuf解码1次,耗时:3ms
            文章源自JAVA秀-https://www.javaxiu.com/32675.html

            运行 10 次文章源自JAVA秀-https://www.javaxiu.com/32675.html

              【JSON 开始编码 】JSON编码10次,耗时:22msJSON数据长度:106-开始解码-JSON解码10次,耗时:4ms【ProtoBuf 开始编码 】ProtoBuf编码10次,耗时:29msProtoBuf数据长度:34-开始解码-ProtoBuf解码10次,耗时:3ms
              文章源自JAVA秀-https://www.javaxiu.com/32675.html

              运行 100 次文章源自JAVA秀-https://www.javaxiu.com/32675.html

                【JSON 开始编码 】JSON编码100次,耗时:32msJSON数据长度:106-开始解码-JSON解码100次,耗时:8ms【ProtoBuf 开始编码 】ProtoBuf编码100次,耗时:31msProtoBuf数据长度:34-开始解码-ProtoBuf解码100次,耗时:4ms
                文章源自JAVA秀-https://www.javaxiu.com/32675.html

                运行 1000 次文章源自JAVA秀-https://www.javaxiu.com/32675.html

                  【JSON 开始编码 】JSON编码1000次,耗时:39msJSON数据长度:106-开始解码-JSON解码1000次,耗时:21ms【ProtoBuf 开始编码 】ProtoBuf编码1000次,耗时:37msProtoBuf数据长度:34-开始解码-ProtoBuf解码1000次,耗时:8ms
                  文章源自JAVA秀-https://www.javaxiu.com/32675.html

                  运行 1万 次文章源自JAVA秀-https://www.javaxiu.com/32675.html

                    【JSON 开始编码 】JSON编码10000次,耗时:126msJSON数据长度:106-开始解码-JSON解码10000次,耗时:93ms【ProtoBuf 开始编码 】ProtoBuf编码10000次,耗时:49msProtoBuf数据长度:34-开始解码-ProtoBuf解码10000次,耗时:23ms
                    文章源自JAVA秀-https://www.javaxiu.com/32675.html

                    运行 10万 次文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      【JSON 开始编码 】JSON编码100000次,耗时:248msJSON数据长度:106-开始解码-JSON解码100000次,耗时:180ms【ProtoBuf 开始编码 】ProtoBuf编码100000次,耗时:51msProtoBuf数据长度:34-开始解码-ProtoBuf解码100000次,耗时:58ms
                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      # 总结

                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      编解码性能

                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      上述栗子只是简单的采样,实际上据我的实验发现文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      • 次数在1千以下,ProtoBuf 的编码与解码性能,都与JSON不相上下,甚至还有比JSON差的趋势。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      • 次数在2千以上,ProtoBuf的编码解码性能,都比JSON高出很多。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      • 次数在10万以上,ProtoBuf的编解码性能就很明显了,远远高出JSON的性能。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      内存占用

                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      ProtoBuf的内存34,而JSON到达106 ,ProtoBuf的内存占用只有JSON的1/3.文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      # 结尾

                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      其实这次实验有很多可待优化的地方,就算是这种粗略的测试,也能看出来ProtoBuf的优势。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      # 兼容

                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      新增字段

                      文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      • 在proto文件中新增 nickname 字段文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      • 生成Java文件文章源自JAVA秀-https://www.javaxiu.com/32675.html

                      • 用老proto字节数组数据,转换成对象文章源自JAVA秀-https://www.javaxiu.com/32675.html

                        Id:1994, Name:XIAOLEI手机号:100860 (HOME)手机号:100100 (MOBILE)getNickname=
                        文章源自JAVA秀-https://www.javaxiu.com/32675.html

                        结果,是可以转换成功。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                        文章源自JAVA秀-https://www.javaxiu.com/32675.html

                        删除字段

                        文章源自JAVA秀-https://www.javaxiu.com/32675.html

                        • 在proto文件中删除 name 字段文章源自JAVA秀-https://www.javaxiu.com/32675.html

                        • 生成Java文件文章源自JAVA秀-https://www.javaxiu.com/32675.html

                        • 用老proto字节数组数据,转换成对象文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          Id:1994, Name:null手机号:100860 (HOME)手机号:100100 (MOBILE)
                          文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          结果,是可以转换成功。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。技术交流群序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          有不少同学问D哥,大厂面试官到底喜欢问什么?想进大厂镀金。因此,D哥特意邀请了华为、腾讯、阿里的朋友进群,与大家一起交流经验,增长技术。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          有兴趣入群的同学,可长按扫描下方二维码,一定要备注:城市+昵称+技术方向,根据格式备注,可更快被通过且邀请进群。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          ▲长按扫描文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。热门推荐文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。序列化到底有啥用?为啥所有的系统都离不开它?有点懵。。文章源自JAVA秀-https://www.javaxiu.com/32675.html

                          文章源自JAVA秀-https://www.javaxiu.com/32675.html
                          继续阅读
                          速蛙云 - 极致体验,强烈推荐!!!购买套餐就免费送各大视频网站会员!快速稳定、独家福利社、流媒体稳定解锁!速度快,全球上网、视频、游戏加速、独立IP均支持!基础套餐性价比很高!这里不多说,我一直正在使用,推荐购买:https://www.javaxiu.com/59919.html
                          weinxin
                          资源分享QQ群
                          本站是JAVA秀团队的技术分享社区, 会经常分享资源和教程; 分享的时代, 请别再沉默!
                          沙海
                          匿名

                          发表评论

                          匿名网友 填写信息

                          :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

                          确定