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 // 继续遍历
	})
}
