Files
cs-note/hzh/GolangStar/Go面试题库/反射面试题.md
T

98 lines
3.6 KiB
Markdown
Raw Normal View History

2026-06-07 11:08:10 +08:00
---
2026-06-07 12:14:39 +08:00
tags: [go, golang, interview, reflection-questions]
create time: 2026-06-07 14:30
2026-06-07 11:08:10 +08:00
---
2026-06-07 12:14:39 +08:00
# 反射面试题 🔮
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 概述
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
本文件涵盖 Go 反射的 4 道高频面试题,涉及反射概念、实现原理和实际应用场景。反射是 Go 的高级特性,理解它对于深入掌握标准库(如 encoding/json)的工作原理至关重要。
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 关联笔记
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
- [[hzh/GolangStar/Go语言进阶/反射]] — 反射详细讲解
- [[hzh/GolangStar/Go语言基础/Go语言接口]] — 反射与 Interface 的关系
- [[hzh/GolangStar/Go面试题库/Interface面试题]] — eface/iface 底层结构
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 正文
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
### Q1:什么是反射? 🟢简单
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 参考答案
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
反射是指计算机程序在**运行时**可以访问、检测和修改自身状态或行为的一种能力。
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
> [!tip] 💡 通俗理解
> "反射就是程序在运行的时候能够'观察'并且修改自己的行为。"就像一个人能在镜子中看到自己并做出调整一样。
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
---
### 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 方法 | 业务语义相等 | 性能最好,符合业务逻辑 |
```go
// reflect.DeepEqual 深度比较
reflect.DeepEqual(obj1, obj2)
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
// 注意:slice、map、function 不能用 == 比较
```
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
> [!warning] ⚠️ 高频陷阱
> `reflect.DeepEqual` 虽然方便,但在性能敏感的场景下不如自定义 Equal 方法。对于用户对象等,建议只比较关键字段(如 ID)。
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
## 关联笔记
2026-06-07 11:08:10 +08:00
2026-06-07 12:14:39 +08:00
- [[hzh/GolangStar/Go语言进阶/反射]]
- [[hzh/GolangStar/Go语言基础/Go语言接口]]
- [[hzh/GolangStar/Go面试题库/Interface面试题]]