当前位置: 首页 > backend >正文

【超详细讲解】什么是序列化和反序列化?

目录

一、什么是序列化(Serialization)?

举个直观的例子

二、什么是反序列化(Deserialization)?

三、为什么需要序列化?

四、常见的序列化格式对比

五、序列化底层是怎么做的?

序列化过程:

反序列化过程:

六、序列化/反序列化常见坑

七、实际工程中应该怎么做?

八、总结

在实际项目开发中,“序列化(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

五、序列化底层是怎么做的?

不同协议实现不一样,但总体过程类似:

序列化过程:

  1. 遍历对象的各个成员

  2. 把成员名和值按照某种规则编码

  3. 将编码结果组织成二进制流或文本格式

反序列化过程:

  1. 按照协议解析字节流或文本

  2. 提取字段信息

  3. 重新创建对象并赋值

比如 Protobuf 就是通过 proto 文件定义消息结构,在序列化时将字段编号、数据值压缩成紧凑的二进制格式。

六、序列化/反序列化常见坑

  1. 版本兼容问题

    • 加字段、删字段时,旧版本客户端可能崩溃!

    • 解决方案:设计支持“向前兼容”和“向后兼容”的协议(比如 Protobuf 就支持)

  2. 性能瓶颈

    • 大对象频繁序列化/反序列化,CPU和内存开销大

    • 解决方案:缓存序列化结果、优化协议选择

  3. 安全风险

    • 反序列化时如果处理不当,可能被黑客注入恶意数据(反序列化漏洞

    • 解决方案:只信任可信源数据、限制反序列化对象类型

  4. 浮点数精度问题

    • JSON等文本协议保存浮点数时可能丢失精度

  5. 指针、引用、共享对象问题

    • C++等语言中的裸指针、智能指针需要特别小心处理

七、实际工程中应该怎么做?

选好序列化协议

  • 轻量级API通信选JSON

  • 高性能微服务内部通信选Protobuf

  • 超高频、大量小数据可以考虑FlatBuffers

优化性能

  • 尽量复用对象

  • 预先分配好内存

  • 批量处理而不是逐条处理

注意安全问题

  • 不要反序列化不可信来源的数据

  • 限制反序列化类的白名单

  • 检查数据大小、结构合理性

八、总结

序列化和反序列化是现代系统数据流动的桥梁。

  • 序列化让数据可以跨内存、跨进程、跨机器传递;

  • 反序列化让数据回到可以操作的对象状态;

  • 正确、合理、安全地使用它们,是开发可靠系统的基础技能。

http://www.xdnf.cn/news/2796.html

相关文章:

  • Elastic Platform 8.18 和 9.0:ES|QL Lookup Joins 功能现已推出,Lucene 10!
  • STM32 USB配置详解
  • 使用多线程快速向Excel中快速插入一万条数据案例
  • UDP协议详解+代码演示
  • 品融天猫代运营服务内容详解:专业化体系驱动品牌增长
  • Spring Boot 3与JDK 8环境下的单元测试实践指南
  • QT中的多线程
  • 驱动开发硬核特训 │ Day 23(下篇): i.MX8MP LCDIFv3 驱动中的 Regulator 系统全解
  • KML文件转shp并保留关键字段
  • 擦除整片flash后,程序下载到单片机,单片机不运行
  • Android Kotlin ViewModel 错误处理:最佳 Toast 提示方案详解
  • java 使用 POI 为 word 文档自动生成书签
  • 热扩散测试要求不起火、不爆炸,电动汽车电池新国标GB38031-2025将于2026年7月实施
  • 驱动开发硬核特训 │ 深度解析 fixed regulator 驱动与 regulator_ops
  • 在uni-app中使用Painter生成小程序海报
  • Linux基础IO
  • RFID智能书架:图书馆数字化转型的新核心技术
  • 使用vue3 脚手架创建项目
  • 【AI Weekly】AI前沿热点周刊(4.21~4.27)
  • 考研408-计算机组成原理冲刺考点(1-3章)
  • 状态模式 (State Pattern)
  • Ubuntu安装SRS流媒体服务
  • [实战] IRIG-B协议详解及Verilog实现(完整代码)
  • 第十三节:实战与工程化高频题-TypeScript集成要点
  • 香港科技大学广州|智能交通学域博士招生宣讲会—电子科技大学
  • css网格布局Grid
  • 在服务器中,搭建FusionCompute,实现集群管理
  • Qt/C++面试【速通笔记五】—子线程与GUI线程安全交互
  • AWS PrivateLink vs Lattice:深度解析两大网络服务的异同
  • 恰好边数限制的最短路(边的数量很大)