5月28日 03:52

YAML 和 JSON 有什么区别?如何选择?

YAML 和 JSON 都是数据序列化格式,核心区别在于设计目标不同:YAML 追求人类可读,JSON 追求机器解析效率。YAML 用缩进表示层级,支持注释、多行字符串、对象引用(&/*)和更丰富的数据类型(日期、二进制等);JSON 用大括号和方括号表示结构,语法严格但不支持注释,数据类型只有字符串、数字、布尔、null、对象和数组六种。选择依据很简单:需要人手写和阅读的用 YAML(配置文件、CI/CD、K8s 清单),需要机器快速解析和跨系统传输的用 JSON(API 响应、日志、数据存储)。性能上 JSON 解析速度通常是 YAML 的 5-10 倍,因为 YAML 规范复杂(1.2 规范 80+ 页),解析器要做更多推断。兼容性方面,YAML 是 JSON 的超集——合法的 JSON 一定是合法的 YAML,反过来不行。

追问

YAML 解析为什么比 JSON 慢那么多?

YAML 规范支持大量隐式类型推断(比如 true/false/yes/no 都能识别为布尔值)、锚点和别名、多文档流等特性,解析器必须处理这些边界情况。JSON 只有 6 种数据类型,语法规则简单到可以用一个状态机完整描述,解析路径几乎是确定性的。实际项目中 YAML 解析耗时通常是 JSON 的 5-10 倍,配置文件体积大的时候差距更明显。

YAML 的缩进坑踩过吗?

踩过。最常见的是 Tab 和空格混用——YAML 只允许空格缩进,混入一个 Tab 就会报解析错误,而且报错信息往往指向错误的行号。另一个坑是冒号后面没加空格,key:value 在 YAML 里不会被识别为键值对,必须写成 key: value。还有布尔值陷阱:yes/no/on/off 在 YAML 1.1 里会被解析为 true/false,如果你本意是字符串,得加引号。Kubernetes 和 CI/CD 配置里这些问题特别容易踩。

项目里有没有 YAML 和 JSON 混用的场景?

有。Spring Boot 项目里 application.yml 写配置,但外部化配置覆盖时用环境变量或 JSON 格式的配置中心下发;CI/CD 流水线的触发配置是 JSON(比如 GitHub webhook payload),但流水线定义文件是 YAML。还有些工具支持两种格式互转,比如 yq 处理 YAML、jq 处理 JSON,管道组合着用。

YAML 的锚点和别名实际用在哪?

Kubernetes 的 ConfigMap 和 Secret 复用场景。用 & 定义一个锚点,后面用 * 引用,避免同一份配置写多遍。比如多个 Deployment 引用同一个环境变量块:

yaml
common-env: &common-env DB_HOST: db.example.com DB_PORT: "5432" deployment-a: env: *common-env deployment-b: env: *common-env

不过不是所有 YAML 解析器都支持锚点,Docker Compose 支持但有些轻量解析器不支持,用之前先确认。

什么时候 JSON 反而比 YAML 更适合做配置文件?

配置需要程序生成和修改的场景。比如 VS Code 的 settings.json——由扩展程序读写,JSON 格式方便序列化/反序列化,不需要注释(注释需求可以通过 _$comment 之类的字段变通解决)。还有需要严格 Schema 校验的场景,JSON Schema 生态比 YAML 的校验工具成熟得多,AJV 等库能做编译时校验,出错了能精确定位到行和字段。

标签:YAML