3.6 KiB
3.6 KiB
tags, create time
| tags | create time | ||||
|---|---|---|---|---|---|
|
2026-06-07 14:30 |
反射面试题 🔮
概述
本文件涵盖 Go 反射的 4 道高频面试题,涉及反射概念、实现原理和实际应用场景。反射是 Go 的高级特性,理解它对于深入掌握标准库(如 encoding/json)的工作原理至关重要。
关联笔记
- hzh/GolangStar/Go语言进阶/反射 — 反射详细讲解
- hzh/GolangStar/Go语言基础/Go语言接口 — 反射与 Interface 的关系
- hzh/GolangStar/Go面试题库/Interface面试题 — eface/iface 底层结构
正文
Q1:什么是反射? 🟢简单
参考答案
反射是指计算机程序在运行时可以访问、检测和修改自身状态或行为的一种能力。
[!tip] 💡 通俗理解 "反射就是程序在运行的时候能够'观察'并且修改自己的行为。"就像一个人能在镜子中看到自己并做出调整一样。
Q2:Go 语言如何实现反射? 🟡中等
[!question] ❓ 思考一下 Go 的变量在编译期有确定的类型,但 interface{} 可以存储任意类型。reflect 是怎么从 interface{} 中还原出类型的?
参考答案
Go 反射通过 interface -> reflect.Type + reflect.Value 实现:
具体类型变量 → 赋值给 interface{} → reflect.TypeOf()/ValueOf() → 提取类型信息和数据
当将具体类型变量赋值给接口时,Go 会把类型信息和数据地址都存入接口变量。reflect 包通过 TypeOf 和 ValueOf 读取这些信息,完成运行时动态访问。
[!note] 📝 核心考点 反射的本质:接口存储了类型信息 + 数据指针,reflect 把它们解包出来。这依赖于之前学过的 eface 结构。
[!info] 🔗 延伸阅读
- hzh/GolangStar/Go语言原理/interface原理 — eface 的内部结构
- hzh/GolangStar/Go语言进阶/反射 — TypeOf / Kind / setXX 权限
Q3:Go 语言中的反射应用有哪些? 🟢简单
参考答案
| 应用 | 说明 |
|---|---|
| JSON 序列化 | encoding/json 通过反射获取结构体字段信息 |
| ORM 框架 | GORM 通过反射分析 struct tag 生成 SQL |
| Web 框架参数绑定 | Gin ShouldBind 自动将 HTTP 参数映射到结构体 |
| 配置文件解析 | Viper 用反射将配置映射到结构体 |
| RPC 调用 | gRPC 通过反射实现服务注册和方法调用 |
| 测试框架 | 自动发现和执行测试用例 |
[!tip] 💡 面试技巧 "几乎 Go 标准库中所有处理"未知类型"的地方都用到了反射。最典型的例子就是 json.Marshal——你传给它任何结构体,它都能正确序列化。"
Q4:如何比较两个对象完全相同? 🟢简单
参考答案
| 方法 | 适用场景 | 说明 |
|---|---|---|
reflect.DeepEqual |
复合类型深度比较 | 递归比较所有字段和元素 |
== 操作符 |
基本类型、数组、可比较结构体 | 编译期保证安全 |
| 自定义 Equal 方法 | 业务语义相等 | 性能最好,符合业务逻辑 |
// reflect.DeepEqual 深度比较
reflect.DeepEqual(obj1, obj2)
// 注意:slice、map、function 不能用 == 比较
[!warning] ⚠️ 高频陷阱
reflect.DeepEqual虽然方便,但在性能敏感的场景下不如自定义 Equal 方法。对于用户对象等,建议只比较关键字段(如 ID)。