Skip to content

Commit 9dad8fb

Browse files
committed
Update serialization.md
1 parent 9561dd3 commit 9dad8fb

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

docs/java/basis/serialization.md

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ tag:
99

1010
### 什么是序列化?什么是反序列化?
1111

12-
如果我们需要持久化Java对象比如将Java对象保存在文件中,或者在网络传输Java对象,这些场景都需要用到序列化。
12+
如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。
1313

1414
简单来说:
1515

1616
- **序列化**: 将数据结构或对象转换成二进制字节流的过程
1717
- **反序列化**:将在序列化过程中所生成的二进制字节流的过程转换成数据结构或者对象的过程
1818

19-
对于Java这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而class 对应的是对象类型。
19+
对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。
2020

2121
维基百科是如是介绍序列化的:
2222

@@ -30,11 +30,11 @@ tag:
3030

3131
### 实际开发中有哪些用到序列化和反序列化的场景?
3232

33-
1. 对象在进行网络传输(比如远程方法调用RPC的时候)之前需要先被序列化,接收到序列化的对象之后需要再进行反序列化;
33+
1. 对象在进行网络传输(比如远程方法调用 RPC 的时候)之前需要先被序列化,接收到序列化的对象之后需要再进行反序列化;
3434
2. 将对象存储到文件中的时候需要进行序列化,将对象从文件中读取出来需要进行反序列化。
3535
3. 将对象存储到缓存数据库(如 Redis)时需要用到序列化,将对象从缓存数据库中读取出来需要反序列化。
3636

37-
### 序列化协议对应于TCP/IP 4层模型的哪一层
37+
### 序列化协议对应于 TCP/IP 4 层模型的哪一层
3838

3939
我们知道网络通信的双方必须要采用和遵守相同的协议。TCP/IP 四层模型是下面这样的,序列化协议属于哪一层呢?
4040

@@ -45,17 +45,17 @@ tag:
4545

4646
![TCP/IP 4层模型](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2020-8/6ecb84cd-4227-4c7b-a2e8-b77054604400-20200802201216504.png)
4747

48-
如上图所示,OSI七层协议模型中,表示层做的事情主要就是对应用层的用户数据进行处理转换为二进制流。反过来的话,就是将二进制流转换成应用层的用户数据。这不就对应的是序列化和反序列化么?
48+
如上图所示,OSI 七层协议模型中,表示层做的事情主要就是对应用层的用户数据进行处理转换为二进制流。反过来的话,就是将二进制流转换成应用层的用户数据。这不就对应的是序列化和反序列化么?
4949

50-
因为,OSI七层协议模型中的应用层、表示层和会话层对应的都是TCP/IP 四层模型中的应用层,所以序列化协议属于TCP/IP协议应用层的一部分
50+
因为,OSI 七层协议模型中的应用层、表示层和会话层对应的都是 TCP/IP 四层模型中的应用层,所以序列化协议属于 TCP/IP 协议应用层的一部分
5151

5252
## 常见序列化协议对比
5353

54-
JDK自带的序列化方式一般不会用 ,因为序列化效率低并且部分版本有安全漏洞。比较常用的序列化协议有 hessian、kyro、protostuff。
54+
JDK 自带的序列化方式一般不会用 ,因为序列化效率低并且部分版本有安全漏洞。比较常用的序列化协议有 hessian、kyro、protostuff。
5555

56-
下面提到的都是基于二进制的序列化协议,像 JSON 和 XML这种属于文本类序列化方式。虽然 JSON 和 XML可读性比较好,但是性能较差,一般不会选择。
56+
下面提到的都是基于二进制的序列化协议,像 JSON 和 XML 这种属于文本类序列化方式。虽然 JSON 和 XML 可读性比较好,但是性能较差,一般不会选择。
5757

58-
### JDK自带的序列化方式
58+
### JDK 自带的序列化方式
5959

6060
JDK 自带的序列化,只需实现 `java.io.Serializable`接口即可。
6161

@@ -76,7 +76,7 @@ public class RpcRequest implements Serializable {
7676
}
7777
```
7878

79-
> 序列化号 serialVersionUID 属于版本控制的作用。序列化的时候serialVersionUID也会被写入二级制序列,当反序列化时会检查serialVersionUID是否和当前类的serialVersionUID一致。如果serialVersionUID不一致则会抛出 `InvalidClassException` 异常。强烈推荐每个序列化类都手动指定其 `serialVersionUID`,如果不手动指定,那么编译器会动态生成默认的序列化号
79+
> 序列化号 serialVersionUID 属于版本控制的作用。序列化的时候 serialVersionUID 也会被写入二级制序列,当反序列化时会检查 serialVersionUID 是否和当前类的 serialVersionUID 一致。如果 serialVersionUID 不一致则会抛出 `InvalidClassException` 异常。强烈推荐每个序列化类都手动指定其 `serialVersionUID`,如果不手动指定,那么编译器会动态生成默认的序列化号
8080
8181
我们很少或者说几乎不会直接使用这个序列化方式,主要原因有两个:
8282

@@ -85,11 +85,11 @@ public class RpcRequest implements Serializable {
8585

8686
### Kryo
8787

88-
Kryo是一个高性能的序列化/反序列化工具,由于其变长存储特性并使用了字节码生成机制,拥有较高的运行速度和较小的字节码体积。
88+
Kryo 是一个高性能的序列化/反序列化工具,由于其变长存储特性并使用了字节码生成机制,拥有较高的运行速度和较小的字节码体积。
8989

90-
另外,Kryo 已经是一种非常成熟的序列化实现了,已经在Twitter、Groupon、Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用。
90+
另外,Kryo 已经是一种非常成熟的序列化实现了,已经在 Twitter、Groupon、Yahoo 以及多个著名开源项目(如 Hive、Storm)中广泛的使用。
9191

92-
[guide-rpc-framework](https://github.com/Snailclimb/guide-rpc-framework) 就是使用的 kyro 进行序列化,序列化和反序列化相关的代码如下:
92+
[guide-rpc-framework](https://github.com/Snailclimb/guide-rpc-framework) 就是使用的 kyro 进行序列化,序列化和反序列化相关的代码如下:
9393

9494
```java
9595
/**
@@ -146,15 +146,15 @@ Github 地址:[https://github.com/EsotericSoftware/kryo](https://github.com/Es
146146

147147
### Protobuf
148148

149-
Protobuf出自于Google,性能还比较优秀,也支持多种语言,同时还是跨平台的。就是在使用中过于繁琐,因为你需要自己定义 IDL 文件和生成对应的序列化代码。这样虽然不然灵活,但是,另一方面导致protobuf没有序列化漏洞的风险。
149+
Protobuf 出自于 Google,性能还比较优秀,也支持多种语言,同时还是跨平台的。就是在使用中过于繁琐,因为你需要自己定义 IDL 文件和生成对应的序列化代码。这样虽然不然灵活,但是,另一方面导致 protobuf 没有序列化漏洞的风险。
150150

151-
> Protobuf包含序列化格式的定义、各种语言的库以及一个IDL编译器。正常情况下你需要定义proto文件,然后使用IDL编译器编译成你需要的语言
151+
> Protobuf 包含序列化格式的定义、各种语言的库以及一个 IDL 编译器。正常情况下你需要定义 proto 文件,然后使用 IDL 编译器编译成你需要的语言
152152
153153
一个简单的 proto 文件如下:
154154

155155
```protobuf
156156
// protobuf的版本
157-
syntax = "proto3";
157+
syntax = "proto3";
158158
// SearchRequest会被编译成不同的编程语言的相应对象,比如Java中的class、Go中的struct
159159
message Person {
160160
//string类型字段
@@ -164,36 +164,35 @@ message Person {
164164
}
165165
```
166166

167-
Github地址[https://github.com/protocolbuffers/protobuf](https://github.com/protocolbuffers/protobuf)
167+
Github 地址[https://github.com/protocolbuffers/protobuf](https://github.com/protocolbuffers/protobuf)
168168

169169
### ProtoStuff
170170

171-
由于Protobuf的易用性,它的哥哥 Protostuff 诞生了。
171+
由于 Protobuf 的易用性,它的哥哥 Protostuff 诞生了。
172172

173-
protostuff 基于Google protobuf,但是提供了更多的功能和更简易的用法。虽然更加易用,但是不代表 ProtoStuff 性能更差。
173+
protostuff 基于 Google protobuf,但是提供了更多的功能和更简易的用法。虽然更加易用,但是不代表 ProtoStuff 性能更差。
174174

175-
Gihub地址[https://github.com/protostuff/protostuff](https://github.com/protostuff/protostuff)
175+
Github 地址[https://github.com/protostuff/protostuff](https://github.com/protostuff/protostuff)
176176

177177
### hession
178178

179-
hessian 是一个轻量级的,自定义描述的二进制RPC协议。hessian是一个比较老的序列化实现了,并且同样也是跨语言的。
179+
hessian 是一个轻量级的,自定义描述的二进制 RPC 协议。hessian 是一个比较老的序列化实现了,并且同样也是跨语言的。
180180

181181
![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2020-8/8613ec4c-bde5-47bf-897e-99e0f90b9fa3.png)
182182

183-
dubbo RPC默认启用的序列化方式是 hession2 ,但是,Dubbo对hessian2进行了修改,不过大体结构还是差不多。
183+
dubbo RPC 默认启用的序列化方式是 hession2 ,但是,Dubbo 对 hessian2 进行了修改,不过大体结构还是差不多。
184184

185185
### 总结
186186

187-
Kryo 是专门针对Java语言序列化方式并且性能非常好,如果你的应用是专门针对Java语言的话可以考虑使用,并且 Dubbo 官网的一篇文章中提到说推荐使用 Kryo 作为生产环境的序列化方式。(文章地址:[https://dubbo.apache.org/zh/docs/v2.7/user/references/protocol/rest/](https://dubbo.apache.org/zh/docs/v2.7/user/references/protocol/rest/))
187+
Kryo 是专门针对 Java 语言序列化方式并且性能非常好,如果你的应用是专门针对 Java 语言的话可以考虑使用,并且 Dubbo 官网的一篇文章中提到说推荐使用 Kryo 作为生产环境的序列化方式。(文章地址:[https://dubbo.apache.org/zh/docs/v2.7/user/references/protocol/rest/](https://dubbo.apache.org/zh/docs/v2.7/user/references/protocol/rest/))
188188

189189
![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2020-8/569e541a-22b2-4846-aa07-0ad479f07440.png)
190190

191-
像Protobuf、 ProtoStuff、hession这类都是跨语言的序列化方式,如果有跨语言需求的话可以考虑使用。
191+
像 Protobuf、 ProtoStuff、hession 这类都是跨语言的序列化方式,如果有跨语言需求的话可以考虑使用。
192192

193193
除了我上面介绍到的序列化方式的话,还有像 Thrift,Avro 这些。
194194

195195
## 其他推荐阅读
196196

197197
- 美团技术团队-序列化和反序列化:[https://tech.meituan.com/2015/02/26/serialization-vs-deserialization.html](https://tech.meituan.com/2015/02/26/serialization-vs-deserialization.html)
198-
- 在Dubbo中使用高效的Java序列化(Kryo和FST): [https://dubbo.apache.org/zh-cn/docs/user/serialization.html](https://dubbo.apache.org/zh-cn/docs/user/serialization.html)
199-
198+
- 在 Dubbo 中使用高效的 Java 序列化(Kryo 和 FST): [https://dubbo.apache.org/zh-cn/docs/user/serialization.html](https://dubbo.apache.org/zh-cn/docs/user/serialization.html)

0 commit comments

Comments
 (0)