120 lines
2.7 KiB
Go
120 lines
2.7 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"sync"
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println("=== 1. Slice 扩容机制 ===")
|
||
demoSliceGrowth()
|
||
|
||
fmt.Println("\n=== 2. Slice 深拷贝 vs 浅拷贝 ===")
|
||
demoSliceCopy()
|
||
|
||
fmt.Println("\n=== 3. Map 基本使用 ===")
|
||
demoMapUsage()
|
||
|
||
fmt.Println("\n=== 4. Map 并发写风险(会 panic!)===")
|
||
// ⚠️ 下面这行默认注释掉,避免程序崩溃
|
||
// demoUnsafeConcurrentMap()
|
||
|
||
fmt.Println("\n=== 5. 安全的并发 map(sync.Map)===")
|
||
demoSafeConcurrentMap()
|
||
}
|
||
|
||
// 1. 演示 slice 扩容机制
|
||
func demoSliceGrowth() {
|
||
var s []int
|
||
fmt.Printf("初始: len=%d, cap=%d, addr=%p\n", len(s), cap(s), s)
|
||
|
||
for i := 0; i < 10; i++ {
|
||
s = append(s, i)
|
||
fmt.Printf("append %d: len=%d, cap=%d, addr=%p\n", i, len(s), cap(s), s)
|
||
}
|
||
// 观察:当容量不足时,底层数组会重新分配,地址改变
|
||
}
|
||
|
||
// 2. 深拷贝 vs 浅拷贝
|
||
func demoSliceCopy() {
|
||
original := []int{1, 2, 3, 4, 5}
|
||
shallow := original // 浅拷贝:共享底层数组
|
||
deep := make([]int, len(original))
|
||
copy(deep, original) // 深拷贝:独立底层数组
|
||
|
||
fmt.Println("修改前:")
|
||
fmt.Println("original:", original)
|
||
fmt.Println("shallow :", shallow)
|
||
fmt.Println("deep :", deep)
|
||
|
||
// 修改原 slice
|
||
original[0] = 999
|
||
|
||
fmt.Println("\n修改 original[0] = 999 后:")
|
||
fmt.Println("original:", original) // [999, 2, 3, 4, 5]
|
||
fmt.Println("shallow :", shallow) // [999, 2, 3, 4, 5] ← 被影响!
|
||
fmt.Println("deep :", deep) // [1, 2, 3, 4, 5] ← 不受影响
|
||
}
|
||
|
||
// 3. Map 基本使用
|
||
func demoMapUsage() {
|
||
m := make(map[string]int)
|
||
m["apple"] = 5
|
||
m["banana"] = 3
|
||
|
||
fmt.Println("map 内容:", m)
|
||
fmt.Println("apple 数量:", m["apple"])
|
||
|
||
// 检查 key 是否存在
|
||
if count, ok := m["orange"]; ok {
|
||
fmt.Println("orange 存在,数量:", count)
|
||
} else {
|
||
fmt.Println("orange 不存在")
|
||
}
|
||
|
||
// 删除 key
|
||
delete(m, "apple")
|
||
fmt.Println("删除 apple 后:", m)
|
||
}
|
||
|
||
// 4. 不安全的并发 map 写入(会导致 panic)
|
||
func demoUnsafeConcurrentMap() {
|
||
m := make(map[int]int)
|
||
var wg sync.WaitGroup
|
||
|
||
for i := 0; i < 100; i++ {
|
||
wg.Add(1)
|
||
go func(key int) {
|
||
defer wg.Done()
|
||
m[key] = key * 10 // 并发写 → fatal error: concurrent map writes
|
||
}(i)
|
||
}
|
||
|
||
wg.Wait()
|
||
fmt.Println("unsafe map done (should not reach here)")
|
||
}
|
||
|
||
// 5. 使用 sync.Map 实现安全并发
|
||
func demoSafeConcurrentMap() {
|
||
var sm sync.Map
|
||
var wg sync.WaitGroup
|
||
|
||
for i := 0; i < 100; i++ {
|
||
wg.Add(1)
|
||
go func(key int) {
|
||
defer wg.Done()
|
||
sm.Store(key, key*10)
|
||
}(i)
|
||
}
|
||
|
||
wg.Wait()
|
||
|
||
// 读取部分值验证
|
||
sm.Range(func(key, value any) bool {
|
||
if key.(int) < 5 { // 只打印前几个
|
||
fmt.Printf("key=%v, value=%v\n", key, value)
|
||
}
|
||
return true // 继续遍历
|
||
})
|
||
}
|