消息队列高手课
李玥
美团高级技术专家
52199 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 42 讲
进阶篇 (21讲)
消息队列高手课
15
15
1.0x
00:00/00:00
登录|注册

12 | 序列化与反序列化:如何通过网络传输结构化的数据?

字节长度优化
高性能
Hessian
Kryo
XML
JSON
信息密度
速度
复杂度
可读性
专用实现
通用实现
考虑因素
为何需要序列化和反序列化
选择序列化实现
节省内存空间
文件保存
网络传输
内存中的二进制数据
实现
用途
结构化数据
字节流
二进制流
面试考察
深入理解消息队列
提升代码能力
思考题
序列化与反序列化
数据传输形式
目的
序列化与反序列化

该思维导图由 AI 生成,仅供参考

你好,我是李玥。
最近有一些同学留言说,感觉这几节课讲的内容和消息关系不大。这里我解释一下,因为我们课程其中的一个目的,是让同学们不仅会使用消息队列,还可以通过对消息队列的学习,在代码能力上有一个提升,具备“造轮子”的能力。这样,你对消息队列的理解才能足够的深入,而不只是浮于表面。如果你细心可能也会发现,很多大厂在面试时,提到消息队列的问题,也不会仅仅局限在消息队列的使用上,他更多的会考察“你为什么这么实现”。
所以在进阶篇的上半部分,我会把开发一个消息队列需要用到的一些底层的关键技术给大家讲解清楚,然后我们再来一起分析消息队列的源代码。
在上节课中,我们解决了如何实现高性能的网络传输的问题。那是不是程序之间就可以通信了呢?这里面还有一些问题需要解决。
我们知道,在 TCP 的连接上,它传输数据的基本形式就是二进制流,也就是一段一段的 1 和 0。在一般编程语言或者网络框架提供的 API 中,传输数据的基本形式是字节,也就是 Byte。一个字节就是 8 个二进制位,8 个 Bit,所以在这里,二进制流和字节流本质上是一样的。
那对于我们编写的程序来说,它需要通过网络传输的数据是什么形式的呢?是结构化的数据,比如,一条命令、一段文本或者是一条消息。对应到我们写的代码中,这些结构化的数据是什么?这些都可以用一个类(Class)或者一个结构体(Struct)来表示。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

序列化与反序列化是在网络传输结构化数据中至关重要的概念。本文首先解释了序列化和反序列化的概念,以及它们在网络传输和文件保存中的作用。随后,文章讨论了选择合适的序列化实现的因素,包括易于阅读、实现复杂度、序列化和反序列化速度以及信息密度。常见的序列化实现如JSON、XML、Protobuf、Kryo等也被提及,并指出了它们各自的特点和适用场景。此外,专用的序列化方法也被介绍,以提高序列化性能和减小序列化后的字节长度。最后,作者建议在大多数情况下选择高性能的通用序列化框架,如JSON,以满足需求,但在需要超高性能或带宽有限的情况下,可以考虑使用专用的序列化方法。文章总结了选择序列化实现时需要综合考虑的因素,并为读者提供了在不同情况下选择合适序列化实现的建议。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《消息队列高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(57)

  • 最新
  • 精选
  • 👻 小二
    尝试回答一下问题: 内存里存的东西,不通用, 不同系统, 不同语言的组织可能都是不一样的, 而且还存在很多引用, 指针,并不是直接数据块。 序列化, 反序列化, 其实是约定一种标准吧, 大家都按这个标准去弄, 就能跨平台 , 跨语言。

    作者回复: 这个总结好,简单明确,赞!

    2019-08-20
    238
  • ly
    个人对今天的内容进行简单的描述: 1. 序列化:是一种规则,它定义了数据表达的规则; 2. 反序列化:依靠给定的规则,还原数据。 3. 今天的问题: 内存中的对象数据应该具有语言独特性,例如表达相同业务的User对象(id/name/age字段),Java和PHP在内存中的数据格式应该不一样的,如果直接用内存中的数据,可能会造成语言不通。通常两个服务之间没有严格要求语言必须一致,只要对序列化的数据格式进行了协商,任何2个语言直接都可以进行序列化传输、接收。

    作者回复: 👍👍👍

    2019-08-19
    25
  • 课后思考及问题 1:课后,你可以想一下这个问题:在内存里存放的任何数据,它最基础的存储单元也是二进制比特,也就是说,我们应用程序操作的对象,它在内存中也是使用二进制存储的,既然都是二进制,为什么不能直接把内存中,对象对应的二进制数据直接通过网络发送出去,或者保存在文件中呢?为什么还需要序列化和反序列化呢? 非常赞,老师的这个问题太经典了,可以拓宽认知边界。 具有细节,我不清楚,不过大概知道原因,比如: 1-1:JAVA说01表示TRUE,PHP说01表示我是世界上最好的语言 1-2:Mac说01表示1,Windows说10表示1 1-3:虽然0/1在计算机的世界里,可以组合表示万事万物,比如:文字、图片、音频、视频、数据、指令等等,但是不同的语言、操作系统、硬件体系并没有被一个唯一的皇帝统一,他们的标准和存储方式都是有差异性的。所以,字符集有N多种就是这样,同样一个字符0在不同王国有不同的含义。 2:看了老师的讲解,感觉自己也能自定义一个序列化和反序列化的框架,可能性能、通用性待优化。我的问题是,如果我想自己实现一个这样的框架,该怎么思考才能实现的更好?Jd自研的是怎么思考的?或者换个问法,老师在自研时是怎么考虑和设计的,有什么坑没?性能如何?关键想知道怎么自研的?

    作者回复: 近期会发一个加餐来解答你的问题。

    2019-08-23
    2
    8
  • 星愿
    Jmq用的啥序列化框架呢

    作者回复: 和其它的MQ的实现是类似的,自身的命令用的专用序列化,消息本身如何序列化是由业务代码决定的。

    2019-10-21
    3
    7
  • oscarwin
    虽然都是二进制的数据,但是序列化的二进制数据是通过一定的协议将数据字段进行拼接。第一个优势是:不同的语言都可以遵循这种协议进行解析,实现了跨语言。第二个优势是:这种数据可以直接持久化到磁盘,从磁盘读取后也可以通过这个协议解析出来。如果是内存中的数据不能直接存盘的,直接存盘后再读出来我们根本无法辨识这是个什么数据。

    作者回复: 👍

    2019-08-19
    2
    6
  • 梵高
    老师,您好。咨询一个问题,序列化与反序列化是如何实现跨语言的。例如,服务端是java实现的,请求端是php的

    作者回复: 其实序列化和反序列化是无所谓“跨语言”问题的。 序列化之后的数据,就是一段二进制数据,只要知道序列化的规则,用任何语言都可以反序列化。 如果是跨语言来传递对象,需要注意的就是不同语言之间数据类型的对应问题,特别是数据类型的长度和高低位问题。

    2020-06-01
    5
  • 淡定的、王先森
    想问下老师,在项目开发中,什么时候需要显式的实现对象的序列化,或者用到序列化?感觉日常开发中并没有涉及,或者应用的框架给做了我并没有察觉到? 大多数项目都是怎么设计序列化的呢?请老师提示或指教下,不胜感激

    作者回复: 你在使用消息队列的时候,发消息之前就需要对消息进行序列化,收到消息再反序列化。 可能你日常发送的都是String类型的消息,没有意识到? 比如,你要通过消息发送一个有结构的对象到对端,就需要把这个对象序列化。

    2019-10-27
    3
  • 深藏Blue
    老师好,寻求个帮助。我遇到个这样的需求:一个c/s的架构应用,需要实现client之间的点对点数据通信以及群组通信 实际上就是一个即时通讯应用 由于没有即时通讯相关的经验 还请老师能够指导一下。其中的数据传输使用MQ转发 还是基于netty自定义?自己两种方式都琢磨了一下,基于MQ的话,topic tag会很多 只要涉及一端client 操作(比如:打开某个界面)需要同步到其他client的话 就需要对topic进行生产以及订阅消费。 第二就是基于netty自定义,这种情况下c端和s端都要定义一个类似servlet或者springmvc里面的dispatcher根据相关参数分发到具体的业务方法。这方面我是小白,还请老师以及知道的朋友给予指点

    作者回复: 一般来说,即时通信类系统并不适合用消息队列来实现。很多即时通讯软件都是使用一些P2P技术,数据直接点对点传输,不经过服务端转发的。

    2019-08-18
    2
  • 游弋云端
    需要面临的问题: 1、网络字节序与主机字节序问题,业务要感知和处理大小端问题; 2、平台差异,各平台对基本数据类型的长度定义不一致、结构体对齐策略不一致,无法实现平台兼容; 3、连续内存问题,一个对象可能引用,指向其他对象,指针就是一个地址,传输后在另外的设备上是无效值; 如果解决这些问题了,也变相的实现了自己的序列化框架了。
    2019-08-17
    1
    58
  • a、
    1.因为应用程序里的对象,除了属性和属性值以外,还有一些其他的信息,比如jdk编译的版本,类的全限定名,类继承的父类和实现的接口等信息。如果服务端是jdk1.8编译的对象,发给客户端,客户端用的是jdk1.7,肯定会报错。 2.这些其他的信息是多余的,传输中会增加网络负担
    2019-08-17
    23
收起评论
显示
设置
留言
57
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部