【超详细讲解】什么是序列化和反序列化?
在实际项目开发中,“序列化(Serialization)”和“反序列化(Deserialization)”几乎无处不在。
但很多刚入门的同学,对它们的理解还停留在“转成字符串、传来传去”这么简单的层面。
其实,序列化的作用、原理、选择不同序列化协议的考量、安全风险、性能优化,每一个点都值得深入探讨!
一、什么是序列化(Serialization)?
序列化是将对象的状态转换为可存储或可传输格式的过程。
对象在内存中一般以特定的数据结构(指针、引用、哈希表、链表等)存在,直接传输内存数据是不可靠的(不同机器架构不同、数据对齐不同、指针无意义等问题)。
所以我们需要将对象转换成连续的字节流(或标准格式的文本),使得:
- 可以写入磁盘文件
- 可以通过网络发送到远端
- 可以被其他进程或设备正确解析
简单来说,序列化是让数据“离开内存,去旅行”的必备装备。
举个直观的例子
C++中的一个对象:
struct User { std::string name; int age; }; User u{"Alice", 24};序列化后,可能得到这样一段JSON字符串:
{"name": "Alice", "age": 24}或者变成一段二进制流,比如:
[0x05][Alice][0x18]二、什么是反序列化(Deserialization)?
反序列化就是序列化的逆过程。
把收到的字节流或文本格式数据,还原成内存中的对象或数据结构,供程序继续操作。
比如:
- 从磁盘读取一段JSON数据
- 解析网络收到的一段Protobuf消息
- 把Redis里缓存的对象取出来恢复成原始对象
这些都是反序列化的应用。
三、为什么需要序列化?
我们来列一下常见场景:
| 应用场景 | 为什么需要序列化 |
|---|---|
| 网络通信 | TCP/UDP传输的数据必须是字节流,无法直接传对象 |
| 本地持久化 | 把程序状态保存到磁盘,下次能恢复 |
| 跨平台数据交换 | 不同系统、不同语言之间必须用标准格式 |
| 缓存系统 | Redis、Memcached存的是序列化后的对象 |
| 消息队列 | Kafka、RabbitMQ里的消息通常也是经过序列化的 |
| RPC调用 | gRPC、Thrift调用远端服务需要将请求和响应序列化 |
没有序列化,现代分布式系统、微服务体系几乎无法正常运作!
四、常见的序列化格式对比
不同场景适合不同的序列化格式,常见的几种包括:
| 格式 | 优点 | 缺点 | 典型应用 |
|---|---|---|---|
| JSON | 人类可读、跨平台、广泛支持 | 体积大、解析慢 | 前后端接口、配置文件 |
| XML | 结构复杂、可扩展性好 | 体积更大、解析更慢 | SOAP服务、老系统 |
| Protobuf | 体积小、速度快、强类型定义 | 不易读、需要提前定义proto文件 | gRPC、分布式系统内部通信 |
| MessagePack | 比JSON小、解析快 | 不如Protobuf精简 | 移动端、缓存系统 |
| FlatBuffers | 零拷贝、超高速访问 | 使用复杂、生成文件较大 | 游戏开发、大量实时数据场景 |
| Avro | 支持Schema进化(动态变化) | 较重 | 大数据(Hadoop生态) |
▶简单总结:
- 传给人看的用 JSON
- 高性能通信用 Protobuf
- 体积敏感场景用 MessagePack/FlatBuffers
- 大数据流用 Avro
五、序列化底层是怎么做的?
不同协议实现不一样,但总体过程类似:
序列化过程:
- 遍历对象的各个成员
- 把成员名和值按照某种规则编码
- 将编码结果组织成二进制流或文本格式
反序列化过程:
- 按照协议解析字节流或文本
- 提取字段信息
- 重新创建对象并赋值
比如 Protobuf 就是通过 proto 文件定义消息结构,在序列化时将字段编号、数据值压缩成紧凑的二进制格式。
六、序列化/反序列化常见坑
版本兼容问题
- 加字段、删字段时,旧版本客户端可能崩溃!
- 解决方案:设计支持“向前兼容”和“向后兼容”的协议(比如 Protobuf 就支持)
性能瓶颈
- 大对象频繁序列化/反序列化,CPU和内存开销大
- 解决方案:缓存序列化结果、优化协议选择
安全风险
- 反序列化时如果处理不当,可能被黑客注入恶意数据(反序列化漏洞)
- 解决方案:只信任可信源数据、限制反序列化对象类型
浮点数精度问题
- JSON等文本协议保存浮点数时可能丢失精度
指针、引用、共享对象问题
- C++等语言中的裸指针、智能指针需要特别小心处理
七、实际工程中应该怎么做?
▶选好序列化协议
- 轻量级API通信选JSON
- 高性能微服务内部通信选Protobuf
- 超高频、大量小数据可以考虑FlatBuffers
▶优化性能
- 尽量复用对象
- 预先分配好内存
- 批量处理而不是逐条处理
▶注意安全问题
- 不要反序列化不可信来源的数据
- 限制反序列化类的白名单
- 检查数据大小、结构合理性
八、总结
序列化和反序列化是现代系统数据流动的桥梁。
- 序列化让数据可以跨内存、跨进程、跨机器传递;
- 反序列化让数据回到可以操作的对象状态;
- 正确、合理、安全地使用它们,是开发可靠系统的基础技能。
学习资料
知识库由360智榜样学习中心独家打造出品,旨在帮助网络安全从业者或兴趣爱好者零基础快速入门提升实战能力,熟练掌握基础攻防到深度对抗。
从零到精通完整闭环:基础攻防→渗透测试→应急响应→CTF实战,5大模块200+课时,比大学教材更贴近企业实战!”
- 涵盖渗透测试案例分析与实战技巧,直接对应面试真题;
- 包含CTF竞赛基础与HW行动攻防对抗实录,丰富你的简历项目经验;
- 深入十大安全漏洞与利用技巧,掌握这些高阶技能,实战SRC挖洞赚钱。
🎁实战教学,专属靶场:掌握这些高阶技能,谈薪更有底气。无论你是找渗透测试岗还是安全服务岗,这些项目都是加分项。
👇扫描下方图片,补齐实战短板,拿下心仪Offer: