Serde 面试专题
Serde 面试的核心不是会写 #[derive],而是能否说明类型侧、格式侧、数据模型和生命周期如何解耦。
先给答案:Serde 面试的核心不是会写 [derive],而是能否说明类型侧、格式侧、数据模型和生命周期如何解耦
Section titled “先给答案:Serde 面试的核心不是会写 [derive],而是能否说明类型侧、格式侧、数据模型和生命周期如何解耦”Serde 面试的核心不是会写 [derive],而是能否说明类型侧、格式侧、数据模型和生命周期如何解耦。 正文沿“1. Serde 为什么不是 JSON 库 -> 2. 为什么适配复杂度是 N+M -> 3. 序列化和反序列化为什么方向相反”展开:先确认入口和状态归属,再跟踪控制流或数据流的推进,最后落到对外可观察的结果。
主要失效边界集中在“untagged enum 为什么慢且错误信息差、借用反序列化失败怎么排查”这些场景。它们破坏的是容量、顺序、并发或生命周期前提;排查时应先确认状态是否仍由正确对象持有,再核对推进条件和清理路径。
1. Serde 为什么不是 JSON 库
Section titled “1. Serde 为什么不是 JSON 库”Serde 定义类型与格式交互的 trait;JSON parser/writer 在 serde_json。类型实现 Serialize/Deserialize,格式实现 Serializer/Deserializer。
2. 为什么适配复杂度是 N+M
Section titled “2. 为什么适配复杂度是 N+M”N 种数据类型只实现统一数据模型,M 种格式也只实现统一数据模型,不需要每个类型直接适配每个格式。入口:ser/mod.rs:234、:355、de/mod.rs:554、:945。
3. 序列化和反序列化为什么方向相反
Section titled “3. 序列化和反序列化为什么方向相反”序列化时值知道自身结构,主动调用 Serializer;反序列化时格式掌握输入游标,目标类型提供 Visitor,由格式边解析边驱动构造。
4. 为什么 Serializer 有多个复合关联类型
Section titled “4. 为什么 Serializer 有多个复合关联类型”seq、tuple、map、struct 的格式状态不同。关联类型让格式返回具体零分配 builder,并在 end 时收口,而不是统一装箱。
5. Visitor 与 MapAccess 怎么合作
Section titled “5. Visitor 与 MapAccess 怎么合作”Visitor 的 visit_map 接收 MapAccess,循环 next_key_seed / next_value_seed,检查重复和缺失字段后构造目标。源码:de/mod.rs:1837-1970。
6. 'de 是什么
Section titled “6. 'de 是什么”它表示 Deserializer 可借出的输入数据生命周期。visit_borrowed_str(&'de str) 能让结果引用原输入;DeserializeOwned 则要求结果不借用任何特定输入。
7. derive 是反射吗
Section titled “7. derive 是反射吗”不是。serde_derive 在编译期读取 syn AST,生成普通 trait impl。运行时没有字段反射表。入口:serde_derive/src/ser.rs:13、de.rs:25。
8. untagged enum 为什么慢且错误信息差
Section titled “8. untagged enum 为什么慢且错误信息差”通常先把输入读成 Content,再按变体顺序反复尝试反序列化;失败上下文被多个候选合并。源码:de/enum_untagged.rs:46-47。
9. deserialize_any 为什么不适合所有格式
Section titled “9. deserialize_any 为什么不适合所有格式”非自描述二进制格式无法从裸字节判断目标类型,必须由目标调用 deserialize_u32、deserialize_tuple 等 typed method。
10. Serde 的零成本是什么意思
Section titled “10. Serde 的零成本是什么意思”trait 胶水通过泛型、关联类型和单态化通常可被内联,不强制动态分派或中间 Value;不代表字符串解码、容器分配、untagged 回溯没有成本。
11. 借用反序列化失败怎么排查
Section titled “11. 借用反序列化失败怎么排查”Deserializer 是否支持 borrowed visitor -> 输入 buffer 是否活得够久 -> 字符串是否有转义需要解码 -> 上层 API 是否要求 DeserializeOwned -> 字段属性是否走 Content 中间层12. 一句话总结 Serde
Section titled “12. 一句话总结 Serde”Serde 用格式无关数据模型连接 Rust 类型与数据格式,用 Serializer 的静态状态对象完成写出,用 Deserializer+Visitor 流式构造值,再由 derive 在编译期生成大多数胶水代码。