K.I.S.S---Keep IT Simple,Stupid!    人生苦短,我用Python

JSON 的序列化(Serialization) 和反序列化(Deserialization)

 
分类: 问答 2025年5月30日
简介:JSON 序列化与反序列化在系统层面的实现涉及多个关键环节,核心是数据结构 ↔ 字节流的转换过程。

核心概念 

  1. 序列化 将程序中的对象 → 转换为 JSON 字符串 将中文翻译成英语
  2.  反序列化 将 JSON 字符串 → 还原为程序中的对象 将英语翻译回中文

为什么需要转换? 程序内存中的对象无法直接存储或传输,JSON 字符串是通用的文本格式,适用于:

  • 网络传输(HTTP 请求/响应)
  • 文件存储(.json 配置文件)
  • 跨语言数据交换(Python ↔ Java)

 

1. 序列化(Serialization)的系统层面实现

序列化是将内存中的数据结构(如对象、数组)转换为JSON格式的字符串表示。以下是系统层面的实现过程:

核心步骤

  1. 数据结构遍历
    • 语言运行时(如JavaScript的V8引擎)会遍历输入数据结构(如对象或数组)。
    • 对于对象,运行时递归访问每个键值对;对于数组,遍历每个元素。
    • 实现上通常使用深度优先搜索(DFS)或类似算法来处理嵌套结构。
  2. 类型转换
    • 运行时根据JSON规范,将数据类型映射为JSON支持的类型:
      • 基本类型:字符串、数字、布尔值、null直接转换为对应的JSON表示。
      • 对象:转为键值对,用{}包裹,键强制转为字符串(加双引号)。
      • 数组:转为用[]包裹的列表。
      • 不支持的类型(如JavaScript中的undefined、函数、Symbol)被忽略或转为null,具体取决于语言实现。
    • 例如,JavaScript的JSON.stringify()会调用对象的toJSON方法(如果存在)或直接处理其属性。
  3. 字符串构建
    • 运行时动态分配内存,创建一个字符串缓冲区(buffer)来存储生成的JSON字符串。
    • 键值对、数组元素等按JSON语法规则(双引号、逗号、冒号等)逐一拼接。
    • 为优化性能,可能使用高效的字符串拼接算法(如StringBuilder在Java中,或V8引擎中的字符串缓冲区管理)。
  4. 编码处理
    • 字符串值中的特殊字符(如\n、双引号、Unicode字符)会被转义(如\uXXXX)。
    • 确保输出符合UTF-8编码(JSON标准要求),以支持跨平台传输。
  5. 内存管理
    • 序列化过程中,临时对象和缓冲区由运行时的垃圾回收器(Garbage Collector, GC)管理。
    • 例如,V8引擎会在序列化完成后回收中间生成的临时字符串或对象。

 

2. 反序列化(Deserialization)的系统层面实现

反序列化是将JSON字符串解析为内存中的数据结构(如对象、数组)。以下是实现原理:

核心步骤

  1. 词法分析(Lexing)
    • 运行时将JSON字符串分解为令牌(tokens),如{、}、字符串、数字等。
    • 通常使用状态机或正则表达式驱动的词法分析器。
    • 例如,V8引擎的JSONParser会扫描字符串,识别JSON语法元素。
  2. 语法分析(Parsing)
    • 根据JSON语法规则(基于ECMA-404标准),构建抽象语法树(AST)或直接构造数据结构。
    • 使用递归下降解析器(Recursive Descent Parser)或类似算法,验证语法正确性。
    • 若遇到非法JSON(如缺少双引号、错误的逗号),抛出解析错误(如JavaScript的SyntaxError)。
  3. 对象/数组构造
    • 解析器根据AST在内存中分配对象或数组:
      • 对象:分配键值对,键存储为字符串,值根据类型分配(如数字、布尔值等)。
      • 数组:分配连续内存(如JavaScript的Array对象),存储解析后的元素。
    • 在JavaScript中,V8引擎使用JSObject和JSArray来表示解析结果。
  4. 类型转换
    • JSON字符串中的值被转换为目标语言的原生类型:
      • 字符串:存储为语言的字符串对象(UTF-8或UTF-16,视实现而定)。
      • 数字:转为整数或浮点数(如JavaScript的Number)。
      • 布尔值/null:直接映射到语言的true、false或null。
    • 特殊字符(如\uXXXX)被解码为实际的Unicode字符。
  5. 内存管理
    • 解析器动态分配内存以存储对象和数组,垃圾回收器管理这些内存。
    • 为优化性能,可能预分配内存块(如V8的FixedArray)以减少碎片化。

实际系统工作流

Web API 请求处理示例:

  1. 客户端:JSON.stringify() → 内存对象转字节流

  2. HTTP 传输:TCP/IP 分片传输 JSON 字节

  3. 服务端:Nginx 接收 → 内核缓冲区 → 应用层

  4. 服务端解析:SIMD 加速词法分析 → 构建 AST → 反射创建对象

  5. 业务处理:操作内存对象

  6. 响应:反向序列化过程


总结:系统层核心要点

  1. 转换本质:结构化数据 ↔ 线性字节流的双向转换

  2. 关键阶段

    • 序列化:递归遍历 + 类型编码

    • 反序列化:词法分析 → 语法解析 → 内存构建

  3. 性能核心:减少内存复制 + 并行处理

  4. 安全基石:深度限制 + 输入验证

  5. 现代优化:SIMD/JIT/零拷贝三大技术

深度思考:JSON 处理本质是时间与空间的权衡—— 内存换速度(缓存字符串)或 CPU 换内存(流式处理)。现代解析器通过 SIMD 和 JIT 实现二者兼得。




注:当前文章会不定期进行更新。如果您对本文有更好的建议,有新资料推荐, 可以点击: 欢迎分享优秀网站
这个位置将来会放广告

我想等网站访问量多了,在这个位置放个广告。网站纯公益,但是用爱发电服务器也要钱啊 ----------狂奔的小蜗牛