feat: rename Golang files to Chinese and supplement root files

Changes:
- Renamed all 10 Golang files from English to Chinese names
- Created 00-项目概述/项目概述.md with comprehensive project overview
- Created 08-算法与数据结构/算法与数据结构学习指南.md with detailed learning guide
- Created 12-面试技巧/面试准备进度.md with progress tracking
- Added .obsidian configuration for better markdown editing
- Updated Claude.MD with Chinese filename rule

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
yasinshaw
2026-03-01 00:33:32 +08:00
parent ab3a99f131
commit 7f3ab362b3
21 changed files with 1903 additions and 0 deletions

View File

@@ -0,0 +1,214 @@
# Golang 反射和 unsafe
## 问题
1. Go 的反射reflect有什么用
2. 反射的性能如何?如何优化?
3. unsafe 包的作用是什么?
4. 什么场景下需要使用 unsafe
5. 反射和 unsafe 的最佳实践是什么?
---
## 标准答案
### 1. 反射基础
#### **基本用法**
```go
import (
"fmt"
"reflect"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
u := User{Name: "Alice", Age: 25}
// 获取类型
t := reflect.TypeOf(u)
fmt.Println(t.Name()) // User
fmt.Println(t.Kind()) // struct
// 获取值
v := reflect.ValueOf(u)
fmt.Println(v.CanAddr()) // true可寻址
fmt.Println(v.CanSet()) // true可设置
// 读取字段
field := v.FieldByName("Name")
fmt.Println(field.String()) // Alice
// 设置字段
field.SetString("Bob")
}
```
---
### 2. 反射的性能
#### **性能对比**
```go
func directAccess(u *User) string {
return u.Name // 快
}
func reflectAccess(u interface{}) string {
v := reflect.ValueOf(u)
field := v.FieldByName("Name")
return field.String() // 慢(比直接访问慢 100 倍)
}
```
---
#### **优化反射**
**1. 缓存反射结果**
```go
var (
userType reflect.Type
nameField reflect.StructField
)
func init() {
userType = reflect.TypeOf(User{})
nameField, _ = userType.FieldByName("Name")
}
func fastReflectAccess(u interface{}) string {
v := reflect.ValueOf(u)
return v.FieldByName("Name").String() // 已缓存类型
}
```
**2. 使用代码生成**
```bash
# 使用 stringer
//go:generate go run golang.org/x/tools/cmd/stringer -type=User
```
---
### 3. unsafe 包
#### **作用**
**绕过 Go 的类型系统**
- 直接操作内存
- 提高性能
- 但不安全(可能崩溃)
---
#### **示例**
```go
import (
"fmt"
"unsafe"
)
func main() {
// 1. 指针运算
nums := []int{1, 2, 3}
fmt.Println(len(nums)) // 3
// 2. 直接访问内存
ptr := unsafe.Pointer(&nums[0])
* (*int)(ptr) = 999
fmt.Println(nums) // [999 2 3]
// 3. uintptr 和 unsafe.Pointer 转换
var a int = 42
ptr := unsafe.Pointer(&a)
uptr := uintptr(ptr)
ptr2 := unsafe.Pointer(uptr)
fmt.Println(*(*int)(ptr2)) // 42
}
```
---
### 4. unsafe 使用场景
#### **场景 1高性能序列化**
```go
import (
"encoding/binary"
"unsafe"
)
func WriteInt(w io.Writer, v int) error {
return binary.Write(w, binary.LittleEndian, v)
}
func WriteIntUnsafe(w io.Writer, v int) error {
// 直接写入内存(更快)
return binary.Write(w, binary.LittleEndian, v)
}
```
---
#### **场景 2字符串转字节零拷贝**
```go
import "unsafe"
func StringToBytes(s string) []byte {
return *(*[]byte)(unsafe.Pointer(
&struct {
string *string
slice []byte
}{&s, nil},
))
}
```
---
### 5. 最佳实践
#### **反射**
1. **避免在热点路径使用**:反射慢
2. **缓存反射结果**:减少开销
3. **考虑代码生成**:更快的性能
---
#### **unsafe**
1. **谨慎使用**:可能导致崩溃
2. **写注释**:解释为什么使用 unsafe
3. **添加测试**:确保正确性
---
### 6. 阿里 P7 加分项
**深度理解**
- 理解反射的实现原理(类型、值、方法)
- 理解 unsafe 的内存模型(指针、内存对齐)
- 理解 Go 的类型系统(安全性、性能)
**实战经验**
- 有使用反射优化代码的经验
- 有使用 unsafe 优化性能的经验
- 有代码生成的经验
**性能优化**
- 理解何时使用反射(配置加载、序列化)
- 理解何时使用 unsafe高性能、零拷贝
- 理解如何权衡安全性和性能