Go语言并发编程完全指南-进阶版

Go语言并发编程完全指南

目录

  1. 并发概述
  2. Goroutine
  3. Channel
  4. Sync
  5. Select
  6. Context
  7. 定时器
  8. 协程池
  9. 反射
  10. 泛型

1. 并发概述

1.1 并发vs并行

go 复制代码
// 并发(Concurrency): 同时处理多个任务的能力
// - 在单核CPU上,通过时间片轮转
// - 任务交替执行,看起来像同时进行
// - 关注的是结构和设计

// 并行(Parallelism): 同时执行多个任务的能力
// - 在多核CPU上,真正的同时执行
// - 多个任务在不同的CPU核心上运行
// - 关注的是执行效率

// 比喻:
// 并发:一个咖啡师同时处理多个订单(接单、制作、交付交替进行)
// 并行:多个咖啡师各自处理不同的订单(真正同时进行)

1.2 Go的并发模型

Go采用CSP(Communicating Sequential Processes)模型:

go 复制代码
// CSP核心理念:
// "不要通过共享内存来通信,而应该通过通信来共享内存"
// Don't communicate by sharing memory; share memory by communicating.

// 传统方式:共享内存 + 锁
var counter int
var mu sync.Mutex

func increment() {
    mu.Lock()
    counter++
    mu.Unlock()
}

// Go方式:通过channel通信
func worker(ch chan int) {
    for val := range ch {
        // 处理数据
        fmt.Println(val)
    }
}

ch := make(chan int)
go worker(ch)
ch <- 42  // 发送数据

1.3 并发的优势和挑战

go 复制代码
// ✅ 并发的优势
// 1. 提高程序响应性
// 2. 更好地利用多核CPU
// 3. 处理I/O密集型任务更高效
// 4. 简化某些问题的解决方案

// ⚠️ 并发的挑战
// 1. 数据竞争(Race Condition)
// 2. 死锁(Deadlock)
// 3. 活锁(Livelock)
// 4. 资源耗尽

// 检测数据竞争
// go run -race main.go
// go test -race

1.4 并发编程的基本原则

go 复制代码
// 1. 避免共享状态
// ✅ 好:通过channel传递数据
func processData(data chan string) {
    for d := range data {
        // 处理d,无需担心其他goroutine
    }
}

// 2. 最小化临界区
// ✅ 好:锁的范围尽可能小
func (c *Counter) Increment() {
    c.mu.Lock()
    c.value++  // 只保护需要的部分
    c.mu.Unlock()
}

// 3. 使用正确的同步原语
// - Channel: 用于数据传递和同步
// - Mutex: 用于保护共享状态
// - WaitGroup: 用于等待goroutine完成
// - Context: 用于取消和超时控制

// 4. 避免goroutine泄漏
// ✅ 好:确保goroutine能够退出
func worker(ctx context.Context, data chan int) {
    for {
        select {
        case d := <-data:
            // 处理数据
        case <-ctx.Done():
            return  // 收到取消信号,退出
        }
    }
}

2. Goroutine

2.1 创建和使用Goroutine

go 复制代码
package main

import (
    "fmt"
    "time"
)

// 普通函数
func sayHello() {
    fmt.Println("Hello from goroutine")
}

func main() {
    // 方式1:启动命名函数
    go sayHello()
    
    // 方式2:启动匿名函数
    go func() {
        fmt.Println("Anonymous goroutine")
    }()
    
    // 方式3:带参数的goroutine
    go func(msg string) {
        fmt.Println(msg)
    }("Hello with parameter")
    
    // 主goroutine等待(否则程序会立即退出)
    time.Sleep(time.Second)
}

2.2 Goroutine的生命周期

go 复制代码
import (
    "fmt"
    "runtime"
    "sync"
)

func main() {
    // 查看当前goroutine数量
    fmt.Println("Goroutines:", runtime.NumGoroutine())  // 1
    
    var wg sync.WaitGroup
    
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            fmt.Printf("Goroutine %d started\n", id)
            time.Sleep(time.Millisecond * 100)
            fmt.Printf("Goroutine %d finished\n", id)
        }(i)
    }
    
    fmt.Println("Goroutines:", runtime.NumGoroutine())  // 11 (主 + 10个worker)
    
    wg.Wait()  // 等待所有goroutine完成
    fmt.Println("All goroutines finished")
    fmt.Println("Goroutines:", runtime.NumGoroutine())  // 1
}

2.3 Goroutine调度

go 复制代码
import "runtime"

func main() {
    // 获取CPU核心数
    numCPU := runtime.NumCPU()
    fmt.Println("CPU cores:", numCPU)
    
    // 设置最大可同时使用的CPU核心数
    runtime.GOMAXPROCS(numCPU)
    
    // 主动让出CPU时间片
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println("Goroutine 1:", i)
            runtime.Gosched()  // 让出CPU
        }
    }()
    
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println("Goroutine 2:", i)
            runtime.Gosched()
        }
    }()
    
    time.Sleep(time.Second)
}

2.4 Goroutine通信模式

go 复制代码
// 1. 单向数据流
func producer(ch chan<- int) {  // 只写channel
    for i := 0; i < 5; i++ {
        ch <- i
    }
    close(ch)
}

func consumer(ch <-chan int) {  // 只读channel
    for val := range ch {
        fmt.Println("Received:", val)
    }
}

func main() {
    ch := make(chan int)
    go producer(ch)
    consumer(ch)
}

// 2. 扇出模式(Fan-out): 一个生产者,多个消费者
func fanOut() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)
    
    // 生产者
    go func() {
        for i := 0; i < 100; i++ {
            jobs <- i
        }
        close(jobs)
    }()
    
    // 多个worker
    var wg sync.WaitGroup
    for w := 0; w < 3; w++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()
            for job := range jobs {
                results <- job * 2
            }
        }(w)
    }
    
    // 关闭结果channel
    go func() {
        wg.Wait()
        close(results)
    }()
    
    // 收集结果
    for result := range results {
        fmt.Println(result)
    }
}

// 3. 扇入模式(Fan-in): 多个生产者,一个消费者
func fanIn(inputs ...<-chan int) <-chan int {
    out := make(chan int)
    var wg sync.WaitGroup
    
    // 为每个input启动一个goroutine
    for _, input := range inputs {
        wg.Add(1)
        go func(ch <-chan int) {
            defer wg.Done()
            for val := range ch {
                out <- val
            }
        }(input)
    }
    
    // 等待所有输入完成后关闭输出
    go func() {
        wg.Wait()
        close(out)
    }()
    
    return out
}

2.5 Goroutine错误处理

go 复制代码
// 使用channel传递错误
func worker(id int) (int, error) {
    if id < 0 {
        return 0, fmt.Errorf("invalid id: %d", id)
    }
    return id * 2, nil
}

type Result struct {
    Value int
    Err   error
}

func main() {
    jobs := []int{1, 2, -3, 4, 5}
    results := make(chan Result, len(jobs))
    
    // 启动workers
    for _, job := range jobs {
        go func(j int) {
            val, err := worker(j)
            results <- Result{Value: val, Err: err}
        }(job)
    }
    
    // 收集结果
    for i := 0; i < len(jobs); i++ {
        result := <-results
        if result.Err != nil {
            fmt.Println("Error:", result.Err)
        } else {
            fmt.Println("Result:", result.Value)
        }
    }
}

// 使用errgroup
import "golang.org/x/sync/errgroup"

func processWithErrGroup() error {
    g := new(errgroup.Group)
    
    // 添加多个任务
    for i := 0; i < 5; i++ {
        i := i  // 捕获循环变量
        g.Go(func() error {
            if i == 3 {
                return fmt.Errorf("task %d failed", i)
            }
            fmt.Printf("Task %d completed\n", i)
            return nil
        })
    }
    
    // 等待所有任务完成,返回第一个错误
    return g.Wait()
}

2.6 Goroutine泄漏防范

go 复制代码
// ❌ 常见的goroutine泄漏

// 1. Channel永远阻塞
func leak1() {
    ch := make(chan int)
    go func() {
        val := <-ch  // 永远阻塞,goroutine泄漏
        fmt.Println(val)
    }()
    // 忘记发送数据或关闭channel
}

// 2. 死循环没有退出条件
func leak2() {
    go func() {
        for {
            // 永远运行,无法退出
            doSomething()
        }
    }()
}

// ✅ 正确的做法

// 1. 使用context控制生命周期
func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            return  // 收到取消信号,退出
        default:
            doWork()
        }
    }
}

// 2. 使用done channel
func workerWithDone(done <-chan struct{}) {
    for {
        select {
        case <-done:
            return
        default:
            doWork()
        }
    }
}

// 3. 使用带缓冲的channel避免阻塞
func processRequest(req Request) Response {
    // 使用带缓冲的channel
    ch := make(chan Response, 1)
    
    go func() {
        ch <- handleRequest(req)
    }()
    
    select {
    case resp := <-ch:
        return resp
    case <-time.After(time.Second):
        return Response{Error: "timeout"}
        // goroutine会完成并发送到channel,不会泄漏
    }
}

3. Channel

3.1 Channel基础

go 复制代码
// 创建channel
ch1 := make(chan int)           // 无缓冲channel
ch2 := make(chan int, 10)       // 带缓冲channel
ch3 := make(chan string, 5)     // 字符串channel

// 发送和接收
ch1 <- 42        // 发送值到channel
value := <-ch1   // 从channel接收值

// 关闭channel
close(ch1)

// 检查channel是否关闭
value, ok := <-ch1
if !ok {
    fmt.Println("Channel closed")
}

// 单向channel
var sendOnly chan<- int = ch1   // 只能发送
var recvOnly <-chan int = ch1   // 只能接收

3.2 无缓冲vs有缓冲Channel

go 复制代码
// 无缓冲channel: 同步通信
func unbuffered() {
    ch := make(chan int)
    
    go func() {
        fmt.Println("Sending...")
        ch <- 42  // 阻塞,直到有接收者
        fmt.Println("Sent!")
    }()
    
    time.Sleep(time.Second)
    fmt.Println("Receiving...")
    val := <-ch  // 阻塞,直到有发送者
    fmt.Println("Received:", val)
}
// 输出:
// Sending...
// (1秒后)
// Receiving...
// Sent!
// Received: 42

// 有缓冲channel: 异步通信
func buffered() {
    ch := make(chan int, 2)
    
    ch <- 1  // 不阻塞
    ch <- 2  // 不阻塞
    // ch <- 3  // 阻塞,缓冲区满
    
    fmt.Println(<-ch)  // 1
    fmt.Println(<-ch)  // 2
    
    // 查看channel状态
    fmt.Println("Length:", len(ch))  // 0
    fmt.Println("Capacity:", cap(ch))  // 2
}

3.3 Channel使用模式

go 复制代码
// 1. 信号通知
func signalPattern() {
    done := make(chan struct{})  // 空struct不占内存
    
    go func() {
        fmt.Println("Working...")
        time.Sleep(time.Second)
        close(done)  // 发送信号
    }()
    
    <-done  // 等待信号
    fmt.Println("Done!")
}

// 2. 管道模式(Pipeline)
func pipeline() {
    // 阶段1: 生成数据
    gen := func(nums ...int) <-chan int {
        out := make(chan int)
        go func() {
            for _, n := range nums {
                out <- n
            }
            close(out)
        }()
        return out
    }
    
    // 阶段2: 平方
    sq := func(in <-chan int) <-chan int {
        out := make(chan int)
        go func() {
            for n := range in {
                out <- n * n
            }
            close(out)
        }()
        return out
    }
    
    // 阶段3: 求和
    sum := func(in <-chan int) int {
        total := 0
        for n := range in {
            total += n
        }
        return total
    }
    
    // 连接管道
    nums := gen(1, 2, 3, 4)
    squares := sq(nums)
    result := sum(squares)
    fmt.Println(result)  // 30 (1+4+9+16)
}

// 3. 超时模式
func timeoutPattern() {
    ch := make(chan string, 1)
    
    go func() {
        time.Sleep(2 * time.Second)
        ch <- "result"
    }()
    
    select {
    case res := <-ch:
        fmt.Println(res)
    case <-time.After(1 * time.Second):
        fmt.Println("Timeout!")
    }
}

// 4. Future模式
type Future struct {
    result chan string
}

func (f *Future) Get() string {
    return <-f.result
}

func asyncCall() *Future {
    future := &Future{
        result: make(chan string, 1),
    }
    
    go func() {
        // 模拟耗时操作
        time.Sleep(time.Second)
        future.result <- "Result"
    }()
    
    return future
}

func futurePattern() {
    future := asyncCall()
    
    // 做其他事情...
    fmt.Println("Doing other work...")
    
    // 需要结果时获取
    result := future.Get()
    fmt.Println(result)
}

// 5. 工作池模式
func workerPool() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)
    
    // 启动3个worker
    for w := 1; w <= 3; w++ {
        go func(id int) {
            for job := range jobs {
                fmt.Printf("Worker %d processing job %d\n", id, job)
                results <- job * 2
            }
        }(w)
    }
    
    // 发送任务
    for j := 1; j <= 9; j++ {
        jobs <- j
    }
    close(jobs)
    
    // 收集结果
    for r := 1; r <= 9; r++ {
        <-results
    }
}

3.4 Channel的关闭和范围遍历

go 复制代码
// 关闭channel的规则
func closeRules() {
    ch := make(chan int, 3)
    
    // ✅ 发送者负责关闭channel
    go func() {
        for i := 0; i < 5; i++ {
            ch <- i
        }
        close(ch)  // 发送完毕后关闭
    }()
    
    // ✅ 使用range遍历,自动处理关闭
    for val := range ch {
        fmt.Println(val)
    }
    
    // ❌ 向已关闭的channel发送会panic
    // ch <- 10  // panic: send on closed channel
    
    // ✅ 从已关闭的channel接收会立即返回零值
    val, ok := <-ch
    fmt.Println(val, ok)  // 0 false
    
    // ❌ 关闭已关闭的channel会panic
    // close(ch)  // panic: close of closed channel
    
    // ❌ 关闭nil channel会panic
    // var ch2 chan int
    // close(ch2)  // panic: close of nil channel
}

// 检查channel是否关闭
func checkClosed() {
    ch := make(chan int, 1)
    ch <- 42
    close(ch)
    
    // 方法1: 使用ok检查
    if val, ok := <-ch; ok {
        fmt.Println("Received:", val)
    } else {
        fmt.Println("Channel closed")
    }
    
    // 方法2: 使用range(推荐)
    ch2 := make(chan int, 3)
    go func() {
        for i := 0; i < 3; i++ {
            ch2 <- i
        }
        close(ch2)
    }()
    
    for val := range ch2 {
        fmt.Println(val)
    }
}

3.5 nil Channel的行为

go 复制代码
func nilChannel() {
    var ch chan int  // nil channel
    
    // ❌ 发送到nil channel永远阻塞
    // ch <- 1  // 永久阻塞
    
    // ❌ 从nil channel接收永远阻塞
    // val := <-ch  // 永久阻塞
    
    // ✅ nil channel在select中很有用
    var ch1, ch2 chan int
    
    select {
    case <-ch1:
        // 永远不会执行
    case <-ch2:
        // 永远不会执行
    default:
        fmt.Println("No channel ready")
    }
    
    // 实际应用:延迟初始化
type Config struct {
    once sync.Once
    data map[string]string
}

func (c *Config) Load() {
    c.once.Do(func() {
        fmt.Println("Loading config...")
        c.data = make(map[string]string)
        // 从文件或数据库加载配置
        c.data["key"] = "value"
    })
}

func (c *Config) Get(key string) string {
    c.Load()  // 确保已加载
    return c.data[key]
}

4.5 Cond(条件变量)

go 复制代码
// Cond用于等待/通知机制
type Queue struct {
    mu    sync.Mutex
    cond  *sync.Cond
    items []int
}

func NewQueue() *Queue {
    q := &Queue{
        items: make([]int, 0),
    }
    q.cond = sync.NewCond(&q.mu)
    return q
}

func (q *Queue) Enqueue(item int) {
    q.mu.Lock()
    defer q.mu.Unlock()
    
    q.items = append(q.items, item)
    q.cond.Signal()  // 唤醒一个等待的goroutine
    // q.cond.Broadcast()  // 唤醒所有等待的goroutine
}

func (q *Queue) Dequeue() int {
    q.mu.Lock()
    defer q.mu.Unlock()
    
    for len(q.items) == 0 {
        q.cond.Wait()  // 等待信号
    }
    
    item := q.items[0]
    q.items = q.items[1:]
    return item
}

func condExample() {
    queue := NewQueue()
    
    // 消费者
    go func() {
        for i := 0; i < 10; i++ {
            item := queue.Dequeue()
            fmt.Println("Dequeued:", item)
        }
    }()
    
    // 生产者
    time.Sleep(time.Second)
    for i := 0; i < 10; i++ {
        queue.Enqueue(i)
        time.Sleep(time.Millisecond * 100)
    }
}

4.6 Map(并发安全的Map)

go 复制代码
import "sync"

// sync.Map适用于读多写少的场景
func syncMapExample() {
    var m sync.Map
    
    // 存储
    m.Store("key1", "value1")
    m.Store("key2", "value2")
    
    // 加载
    if val, ok := m.Load("key1"); ok {
        fmt.Println("Found:", val)
    }
    
    // 加载或存储(原子操作)
    actual, loaded := m.LoadOrStore("key3", "value3")
    fmt.Println("Actual:", actual, "Loaded:", loaded)
    
    // 删除
    m.Delete("key1")
    
    // 遍历
    m.Range(func(key, value interface{}) bool {
        fmt.Printf("%s: %s\n", key, value)
        return true  // 返回false停止遍历
    })
    
    // 加载并删除
    if val, ok := m.LoadAndDelete("key2"); ok {
        fmt.Println("Deleted:", val)
    }
}

// 自定义类型安全的并发Map
type SafeMap[K comparable, V any] struct {
    mu   sync.RWMutex
    data map[K]V
}

func NewSafeMap[K comparable, V any]() *SafeMap[K, V] {
    return &SafeMap[K, V]{
        data: make(map[K]V),
    }
}

func (m *SafeMap[K, V]) Set(key K, value V) {
    m.mu.Lock()
    defer m.mu.Unlock()
    m.data[key] = value
}

func (m *SafeMap[K, V]) Get(key K) (V, bool) {
    m.mu.RLock()
    defer m.mu.RUnlock()
    val, ok := m.data[key]
    return val, ok
}

func (m *SafeMap[K, V]) Delete(key K) {
    m.mu.Lock()
    defer m.mu.Unlock()
    delete(m.data, key)
}

4.7 Pool(对象池)

go 复制代码
import "sync"

// Pool用于复用临时对象,减少GC压力
func poolExample() {
    // 创建对象池
    pool := &sync.Pool{
        New: func() interface{} {
            fmt.Println("Creating new buffer")
            return new(bytes.Buffer)
        },
    }
    
    // 获取对象
    buffer := pool.Get().(*bytes.Buffer)
    buffer.WriteString("Hello, World!")
    fmt.Println(buffer.String())
    
    // 重置并归还
    buffer.Reset()
    pool.Put(buffer)
    
    // 再次获取(可能是刚才归还的)
    buffer2 := pool.Get().(*bytes.Buffer)
    fmt.Println("Buffer empty:", buffer2.Len() == 0)
    pool.Put(buffer2)
}

// 实际应用:HTTP响应缓存
var responsePool = sync.Pool{
    New: func() interface{} {
        return &Response{
            Headers: make(map[string]string),
        }
    },
}

type Response struct {
    Status  int
    Body    string
    Headers map[string]string
}

func handleRequest(req Request) *Response {
    resp := responsePool.Get().(*Response)
    
    // 使用response
    resp.Status = 200
    resp.Body = "OK"
    
    return resp
}

func releaseResponse(resp *Response) {
    // 重置状态
    resp.Status = 0
    resp.Body = ""
    for k := range resp.Headers {
        delete(resp.Headers, k)
    }
    
    responsePool.Put(resp)
}

4.8 Atomic(原子操作)

go 复制代码
import "sync/atomic"

// 原子操作比Mutex更轻量
type AtomicCounter struct {
    value int64
}

func (c *AtomicCounter) Increment() {
    atomic.AddInt64(&c.value, 1)
}

func (c *AtomicCounter) Decrement() {
    atomic.AddInt64(&c.value, -1)
}

func (c *AtomicCounter) Value() int64 {
    return atomic.LoadInt64(&c.value)
}

func (c *AtomicCounter) Set(value int64) {
    atomic.StoreInt64(&c.value, value)
}

func (c *AtomicCounter) CompareAndSwap(old, new int64) bool {
    return atomic.CompareAndSwapInt64(&c.value, old, new)
}

func atomicExample() {
    counter := &AtomicCounter{}
    var wg sync.WaitGroup
    
    // 并发增加
    for i := 0; i < 1000; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            counter.Increment()
        }()
    }
    
    wg.Wait()
    fmt.Println("Final value:", counter.Value())  // 1000
}

// 原子操作的其他类型
func atomicTypes() {
    // int32/int64
    var i32 int32
    atomic.AddInt32(&i32, 1)
    
    var i64 int64
    atomic.AddInt64(&i64, 1)
    
    // uint32/uint64
    var u32 uint32
    atomic.AddUint32(&u32, 1)
    
    // uintptr
    var ptr uintptr
    atomic.AddUintptr(&ptr, 1)
    
    // Value (任意类型)
    var v atomic.Value
    v.Store("hello")
    fmt.Println(v.Load())  // hello
}

// 原子操作的应用:无锁队列
type LockFreeQueue struct {
    head unsafe.Pointer
    tail unsafe.Pointer
}

type node struct {
    value interface{}
    next  unsafe.Pointer
}

func NewLockFreeQueue() *LockFreeQueue {
    n := unsafe.Pointer(&node{})
    return &LockFreeQueue{
        head: n,
        tail: n,
    }
}

func (q *LockFreeQueue) Enqueue(value interface{}) {
    n := &node{value: value}
    for {
        tail := atomic.LoadPointer(&q.tail)
        next := atomic.LoadPointer(&(*node)(tail).next)
        
        if tail == atomic.LoadPointer(&q.tail) {
            if next == nil {
                if atomic.CompareAndSwapPointer(&(*node)(tail).next, next, unsafe.Pointer(n)) {
                    atomic.CompareAndSwapPointer(&q.tail, tail, unsafe.Pointer(n))
                    return
                }
            } else {
                atomic.CompareAndSwapPointer(&q.tail, tail, next)
            }
        }
    }
}

5. Select

5.1 Select基础

go 复制代码
// select用于多路复用channel操作
func selectBasic() {
    ch1 := make(chan string)
    ch2 := make(chan string)
    
    go func() {
        time.Sleep(1 * time.Second)
        ch1 <- "from ch1"
    }()
    
    go func() {
        time.Sleep(2 * time.Second)
        ch2 <- "from ch2"
    }()
    
    // select会执行第一个就绪的case
    select {
    case msg1 := <-ch1:
        fmt.Println(msg1)
    case msg2 := <-ch2:
        fmt.Println(msg2)
    }
    // 输出: from ch1 (因为ch1先就绪)
}

5.2 Select with Default

go 复制代码
// default case立即执行(非阻塞)
func selectDefault() {
    ch := make(chan int, 1)
    
    // 非阻塞发送
    select {
    case ch <- 42:
        fmt.Println("Sent")
    default:
        fmt.Println("Channel full")
    }
    
    // 非阻塞接收
    select {
    case val := <-ch:
        fmt.Println("Received:", val)
    default:
        fmt.Println("Channel empty")
    }
}

// 实际应用:非阻塞检查
func tryReceive(ch <-chan int) (int, bool) {
    select {
    case val := <-ch:
        return val, true
    default:
        return 0, false
    }
}

func trySend(ch chan<- int, val int) bool {
    select {
    case ch <- val:
        return true
    default:
        return false
    }
}

5.3 Select超时模式

go 复制代码
// 超时控制
func selectTimeout() {
    ch := make(chan string)
    
    go func() {
        time.Sleep(2 * time.Second)
        ch <- "result"
    }()
    
    select {
    case res := <-ch:
        fmt.Println("Got:", res)
    case <-time.After(1 * time.Second):
        fmt.Println("Timeout!")
    }
}

// 心跳检测
func heartbeat() {
    heartbeatCh := make(chan struct{})
    
    // 模拟心跳
    go func() {
        ticker := time.NewTicker(500 * time.Millisecond)
        defer ticker.Stop()
        for range ticker.C {
            heartbeatCh <- struct{}{}
        }
    }()
    
    // 监控心跳
    timeout := time.After(2 * time.Second)
    for {
        select {
        case <-heartbeatCh:
            fmt.Println("Heartbeat received")
        case <-timeout:
            fmt.Println("Heartbeat timeout!")
            return
        }
    }
}

5.4 Select多通道监听

go 复制代码
// 同时监听多个channel
func selectMultiple() {
    done := make(chan struct{})
    ch1 := make(chan int)
    ch2 := make(chan string)
    ch3 := make(chan bool)
    
    // 启动多个goroutine
    go func() {
        for i := 0; i < 5; i++ {
            ch1 <- i
            time.Sleep(100 * time.Millisecond)
        }
    }()
    
    go func() {
        for i := 0; i < 3; i++ {
            ch2 <- fmt.Sprintf("msg%d", i)
            time.Sleep(150 * time.Millisecond)
        }
    }()
    
    go func() {
        time.Sleep(500 * time.Millisecond)
        ch3 <- true
    }()
    
    // 监听所有channel
    go func() {
        time.Sleep(1 * time.Second)
        close(done)
    }()
    
    for {
        select {
        case num := <-ch1:
            fmt.Println("Int:", num)
        case msg := <-ch2:
            fmt.Println("String:", msg)
        case flag := <-ch3:
            fmt.Println("Bool:", flag)
        case <-done:
            fmt.Println("Done!")
            return
        }
    }
}

5.5 Select动态case

go 复制代码
// 动态启用/禁用case
func selectDynamic() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    
    // 发送数据
    go func() {
        for i := 0; i < 10; i++ {
            ch1 <- i
            time.Sleep(100 * time.Millisecond)
        }
        close(ch1)
    }()
    
    go func() {
        for i := 0; i < 10; i++ {
            ch2 <- i * 10
            time.Sleep(100 * time.Millisecond)
        }
        close(ch2)
    }()
    
    // 动态选择
    for ch1 != nil || ch2 != nil {
        select {
        case val, ok := <-ch1:
            if !ok {
                ch1 = nil  // 禁用ch1的case
                fmt.Println("ch1 closed")
            } else {
                fmt.Println("ch1:", val)
            }
        case val, ok := <-ch2:
            if !ok {
                ch2 = nil  // 禁用ch2的case
                fmt.Println("ch2 closed")
            } else {
                fmt.Println("ch2:", val)
            }
        }
    }
}

5.6 Select优先级

go 复制代码
// select的case是随机选择的,没有优先级
// 如果需要优先级,需要手动实现
func selectPriority() {
    highPriority := make(chan int)
    lowPriority := make(chan int)
    done := make(chan struct{})
    
    go func() {
        time.Sleep(500 * time.Millisecond)
        close(done)
    }()
    
    go func() {
        for i := 0; i < 5; i++ {
            highPriority <- i
            time.Sleep(50 * time.Millisecond)
        }
    }()
    
    go func() {
        for i := 0; i < 10; i++ {
            lowPriority <- i * 10
            time.Sleep(50 * time.Millisecond)
        }
    }()
    
    for {
        select {
        case <-done:
            return
        case val := <-highPriority:
            fmt.Println("High:", val)
        default:
            // 只有高优先级channel没有数据时才检查低优先级
            select {
            case val := <-lowPriority:
                fmt.Println("Low:", val)
            default:
                time.Sleep(10 * time.Millisecond)
            }
        }
    }
}

5.7 Select常见模式

go 复制代码
// 1. 退出模式
func quitPattern() {
    quit := make(chan struct{})
    data := make(chan int)
    
    go func() {
        for {
            select {
            case d := <-data:
                fmt.Println("Processing:", d)
            case <-quit:
                fmt.Println("Quitting...")
                return
            }
        }
    }()
    
    for i := 0; i < 5; i++ {
        data <- i
    }
    
    close(quit)
    time.Sleep(100 * time.Millisecond)
}

// 2. 超时重试模式
func timeoutRetry() error {
    maxRetries := 3
    timeout := time.Second
    
    for i := 0; i < maxRetries; i++ {
        result := make(chan error, 1)
        
        go func() {
            result <- doWork()
        }()
        
        select {
        case err := <-result:
            if err == nil {
                return nil
            }
            fmt.Printf("Attempt %d failed: %v\n", i+1, err)
        case <-time.After(timeout):
            fmt.Printf("Attempt %d timeout\n", i+1)
        }
        
        timeout *= 2  // 指数退避
    }
    
    return fmt.Errorf("all retries failed")
}

// 3. 合并多个channel
func mergeChannels(channels ...<-chan int) <-chan int {
    out := make(chan int)
    var wg sync.WaitGroup
    
    // 为每个channel启动一个goroutine
    for _, ch := range channels {
        wg.Add(1)
        go func(c <-chan int) {
            defer wg.Done()
            for val := range c {
                out <- val
            }
        }(ch)
    }
    
    // 等待所有channel关闭后关闭输出
    go func() {
        wg.Wait()
        close(out)
    }()
    
    return out
}

// 4. 取第一个响应
func firstResponse() string {
    ch1 := query("server1")
    ch2 := query("server2")
    ch3 := query("server3")
    
    select {
    case resp := <-ch1:
        return resp
    case resp := <-ch2:
        return resp
    case resp := <-ch3:
        return resp
    case <-time.After(time.Second):
        return "timeout"
    }
}

func query(server string) <-chan string {
    ch := make(chan string, 1)
    go func() {
        time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
        ch <- fmt.Sprintf("response from %s", server)
    }()
    return ch
}

6. Context

6.1 Context基础

go 复制代码
import "context"

// Context用于传递请求范围的值、取消信号、截止时间
func contextBasic() {
    // 1. 创建根context
    ctx := context.Background()  // 永不取消
    ctx = context.TODO()         // 待定,不确定用哪个
    
    // 2. WithCancel: 可取消的context
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()  // 确保资源释放
    
    go func() {
        <-ctx.Done()
        fmt.Println("Context cancelled:", ctx.Err())
    }()
    
    time.Sleep(100 * time.Millisecond)
    cancel()  // 取消context
    time.Sleep(100 * time.Millisecond)
}

6.2 WithTimeout和WithDeadline

go 复制代码
// WithTimeout: 超时自动取消
func contextTimeout() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()
    
    select {
    case <-time.After(3 * time.Second):
        fmt.Println("Operation completed")
    case <-ctx.Done():
        fmt.Println("Timeout:", ctx.Err())  // context deadline exceeded
    }
}

// WithDeadline: 指定截止时间
func contextDeadline() {
    deadline := time.Now().Add(2 * time.Second)
    ctx, cancel := context.WithDeadline(context.Background(), deadline)
    defer cancel()
    
    select {
    case <-time.After(3 * time.Second):
        fmt.Println("Operation completed")
    case <-ctx.Done():
        fmt.Println("Deadline exceeded:", ctx.Err())
    }
}

// 实际应用:HTTP请求超时
func fetchWithTimeout(url string, timeout time.Duration) error {
    ctx, cancel := context.WithTimeout(context.Background(), timeout)
    defer cancel()
    
    req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
    if err != nil {
        return err
    }
    
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()
    
    // 处理响应...
    return nil
}

6.3 WithValue传递值

go 复制代码
type contextKey string

const (
    userIDKey    contextKey = "userID"
    requestIDKey contextKey = "requestID"
)

// WithValue: 传递请求范围的值
func contextValue() {
    // 设置值
    ctx := context.WithValue(context.Background(), userIDKey, "user123")
    ctx = context.WithValue(ctx, requestIDKey, "req456")
    
    // 获取值
    processRequest(ctx)
}

func processRequest(ctx context.Context) {
    userID, ok := ctx.Value(userIDKey).(string)
    if ok {
        fmt.Println("User ID:", userID)
    }
    
    requestID := ctx.Value(requestIDKey)
    fmt.Println("Request ID:", requestID)
}

// ⚠️ Context.Value使用注意事项
// 1. 只用于请求范围的数据
// 2. 不要存储可选参数
// 3. 类型安全:使用自定义类型作为key
// 4. 不要存储大量数据

// ✅ 好的用法:传递用户身份、请求ID、认证token
// ❌ 不好的用法:传递函数参数、配置选项

6.4 Context传播

go 复制代码
// Context应该在调用链中传递
func operation(ctx context.Context) error {
    // 检查是否已取消
    if err := ctx.Err(); err != nil {
        return err
    }
    
    // 继续传递context
    return subOperation(ctx)
}

func subOperation(ctx context.Context) error {
    select {
    case <-time.After(time.Second):
        // 模拟工作
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

// 实际示例:数据库查询
func queryDatabase(ctx context.Context, query string) error {
    // 创建带超时的子context
    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()
    
    // 执行查询
    resultCh := make(chan error, 1)
    go func() {
        // 模拟数据库查询
        time.Sleep(2 * time.Second)
        resultCh <- nil
    }()
    
    select {
    case err := <-resultCh:
        return err
    case <-ctx.Done():
        return fmt.Errorf("query cancelled: %w", ctx.Err())
    }
}

6.5 Context最佳实践

go 复制代码
// 1. Context作为第一个参数
func Process(ctx context.Context, data string) error {
    // ✅ 正确
}

func ProcessBad(data string, ctx context.Context) error {
    // ❌ 错误:context应该是第一个参数
}

// 2. 不要存储Context
type Server struct {
    ctx context.Context  // ❌ 不要这样做
}

// ✅ 正确:在函数调用时传递
func (s *Server) HandleRequest(ctx context.Context) {}

// 3. Context链式传递
func handler(ctx context.Context) error {
    // 创建子context
    ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
    defer cancel()
    
    // 传递给下游
    return process(ctx)
}

func process(ctx context.Context) error {
    // 继续传递
    return save(ctx)
}

func save(ctx context.Context) error {
    select {
    case <-time.After(time.Second):
        return nil
    case <-ctx.Done():
        return ctx.Err()
    }
}

// 4. 优雅关闭
func gracefulShutdown() {
    ctx, cancel := context.WithCancel(context.Background())
    
    // 启动服务
    go func() {
        server := &http.Server{Addr: ":8080"}
        
        // 监听关闭信号
        <-ctx.Done()
        
        // 给服务5秒时间关闭
        shutdownCtx, shutdownCancel := context.WithTimeout(
            context.Background(), 
            5*time.Second,
        )
        defer shutdownCancel()
        
        if err := server.Shutdown(shutdownCtx); err != nil {
            log.Printf("Server shutdown error: %v", err)
        }
    }()
    
    // 等待中断信号
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
    <-sigCh
    
    fmt.Println("Shutting down...")
    cancel()
    time.Sleep(6 * time.Second)
}

6.6 Context实战案例

go 复制代码
// 案例1: 并发HTTP请求与超时控制
func fetchMultipleURLs(urls []string, timeout time.Duration) []string {
    ctx, cancel := context.WithTimeout(context.Background(), timeout)
    defer cancel()
    
    resultCh := make(chan string, len(urls))
    var wg sync.WaitGroup
    
    for _, url := range urls {
        wg.Add(1)
        go func(u string) {
            defer wg.Done()
            
            req, _ := http.NewRequestWithContext(ctx, "GET", u, nil)
            resp, err := http.DefaultClient.Do(req)
            
            if err != nil {
                resultCh <- fmt.Sprintf("%s: error - %v", u, err)
                return
            }
            defer resp.Body.Close()
            
            resultCh <- fmt.Sprintf("%s: status %d", u, resp.StatusCode)
        }(url)
    }
    
    go func() {
        wg.Wait()
        close(resultCh)
    }()
    
    var results []string
    for result := range resultCh {
        results = append(results, result)
    }
    
    return results
}

// 案例2: 级联取消
func cascadingCancel() {
    parentCtx, parentCancel := context.WithCancel(context.Background())
    defer parentCancel()
    
    // 子context 1
    child1Ctx, child1Cancel := context.WithCancel(parentCtx)
    defer child1Cancel()
    
    // 子context 2
    child2Ctx, child2Cancel := context.WithTimeout(parentCtx, 5*time.Second)
    defer child2Cancel()
    
    // 启动workers
    go worker(child1Ctx, "Worker 1")
    go worker(child2Ctx, "Worker 2")
    
    time.Sleep(2 * time.Second)
    parentCancel()  // 取消父context,所有子context也被取消
    time.Sleep(time.Second)
}

func worker(ctx context.Context, name string) {
    for {
        select {
        case <-ctx.Done():
            fmt.Printf("%s stopped: %v\n", name, ctx.Err())
            return
        case <-time.After(500 * time.Millisecond):
            fmt.Printf("%s working...\n", name)
        }
    }
}

// 案例3: 数据库事务与Context
func transactionWithContext(ctx context.Context, db *sql.DB) error {
    tx, err := db.BeginTx(ctx, nil)
    if err != nil {
        return err
    }
    defer tx.Rollback()
    
    // 执行多个操作
    if err := insertUser(ctx, tx, "Alice"); err != nil {
        return err
    }
    
    if err := insertOrder(ctx, tx, 123); err != nil {
        return err
    }
    
    // 提交事务
    return tx.Commit()
}

func insertUser(ctx context.Context, tx *sql.Tx, name string) error {
    _, err := tx.ExecContext(ctx, "INSERT INTO users (name) VALUES (?)", name)
    return err
}

7. 定时器

7.1 Timer(一次性定时器)

go 复制代码
import "time"

// Timer在指定时间后触发一次
func timerBasic() {
    timer := time.NewTimer(2 * time.Second)
    
    fmt.Println("Timer started")
    <-timer.C  // 等待定时器触发
    fmt.Println("Timer fired!")
}

// 取消Timer
func timerCancel() {
    timer := time.NewTimer(5 * time.Second)
    
    go func() {
        <-timer.C
        fmt.Println("Timer fired")
    }()
    
    // 2秒后取消
    time.Sleep(2 * time.Second)
    if timer.Stop() {
        fmt.Println("Timer cancelled")
    }
}

// 重置Timer
func timerReset() {
    timer := time.NewTimer(1 * time.Second)
    
    go func() {
        for {
            <-timer.C
            fmt.Println("Timer fired:", time.Now())
        }
    }()
    
    time.Sleep(1500 * time.Millisecond)
    timer.Reset(1 * time.Second)  // 重置定时器
    
    time.Sleep(2 * time.Second)
}

// After: 简化的Timer
func afterExample() {
    select {
    case <-time.After(1 * time.Second):
        fmt.Println("Timeout!")
    }
}

7.2 Ticker(周期性定时器)

go 复制代码
// Ticker周期性触发
func tickerBasic() {
    ticker := time.NewTicker(500 * time.Millisecond)
    defer ticker.Stop()  // 必须停止,否则泄漏
    
    count := 0
    for {
        <-ticker.C
        count++
        fmt.Println("Tick", count)
        
        if count >= 5 {
            break
        }
    }
}

// Ticker与select
func tickerSelect() {
    ticker := time.NewTicker(500 * time.Millisecond)
    defer ticker.Stop()
    
    done := make(chan bool)
    
    go func() {
        time.Sleep(3 * time.Second)
        done <- true
    }()
    
    for {
        select {
        case <-ticker.C:
            fmt.Println("Tick at", time.Now())
        case <-done:
            fmt.Println("Done!")
            return
        }
    }
}

// Tick: 简化的Ticker(不能停止)
func tickExample() {
    c := time.Tick(1 * time.Second)
    
    for i := 0; i < 3; i++ {
        <-c
        fmt.Println("Tick")
    }
    // 注意:无法停止,会导致goroutine泄漏
}

7.3 定时器应用场景

go 复制代码
// 1. 心跳检测
func heartbeatMonitor() {
    heartbeat := make(chan struct{})
    
    // 模拟心跳发送
    go func() {
        ticker := time.NewTicker(1 * time.Second)
        defer ticker.Stop()
        
        for range ticker.C {
            heartbeat <- struct{}{}
        }
    }()
    
    // 监控心跳
    ticker := time.NewTicker(3 * time.Second)
    defer ticker.Stop()
    
    for {
        select {
        case <-heartbeat:
            fmt.Println("Heartbeat received")
        case <-ticker.C:
            fmt.Println("Heartbeat timeout!")
            return
        }
    }
}

// 2. 限流器
type RateLimiter struct {
    ticker *time.Ticker
    bucket chan struct{}
}

func NewRateLimiter(rate int, burst int) *RateLimiter {
    rl := &RateLimiter{
        ticker: time.NewTicker(time.Second / time.Duration(rate)),
        bucket: make(chan struct{}, burst),
    }
    
    // 初始填充
    for i := 0; i < burst; i++ {
        rl.bucket <- struct{}{}
    }
    
    // 定期补充令牌
    go func() {
        for range rl.ticker.C {
            select {
            case rl.bucket <- struct{}{}:
            default:
            }
        }
    }()
    
    return rl
}

func (rl *RateLimiter) Allow() bool {
    select {
    case <-rl.bucket:
        return true
    default:
        return false
    }
}

func (rl *RateLimiter) Wait() {
    <-rl.bucket
}

func (rl *RateLimiter) Stop() {
    rl.ticker.Stop()
}

// 使用限流器
func rateLimiterExample() {
    limiter := NewRateLimiter(2, 5)  // 每秒2个请求,最大突发5个
    defer limiter.Stop()
    
    for i := 0; i < 10; i++ {
        if limiter.Allow() {
            fmt.Printf("Request %d: allowed\n", i)
        } else {
            fmt.Printf("Request %d: blocked\n", i)
        }
        time.Sleep(200 * time.Millisecond)
    }
}

// 3. 超时重试
func retryWithTimeout(fn func() error, maxRetries int, timeout time.Duration) error {
    timer := time.NewTimer(timeout)
    defer timer.Stop()
    
    for i := 0; i < maxRetries; i++ {
        errCh := make(chan error, 1)
        
        go func() {
            errCh <- fn()
        }()
        
        select {
        case err := <-errCh:
            if err == nil {
                return nil
            }
            fmt.Printf("Attempt %d failed: %v\n", i+1, err)
        case <-timer.C:
            return fmt.Errorf("timeout after %v", timeout)
        }
        
        // 等待后重试
        time.Sleep(time.Second * time.Duration(i+1))
    }
    
    return fmt.Errorf("max retries exceeded")
}

// 4. 定时任务调度
type Scheduler struct {
    tasks map[string]*time.Ticker
    mu    sync.Mutex
}

func NewScheduler() *Scheduler {
    return &Scheduler{
        tasks: make(map[string]*time.Ticker),
    }
}

func (s *Scheduler) Schedule(name string, interval time.Duration, fn func()) {
    s.mu.Lock()
    defer s.mu.Unlock()
    
    // 停止已存在的任务
    if ticker, ok := s.tasks[name]; ok {
        ticker.Stop()
    }
    
    // 创建新任务
    ticker := time.NewTicker(interval)
    s.tasks[name] = ticker
    
    go func() {
        for range ticker.C {
            fn()
        }
    }()
}

func (s *Scheduler) Cancel(name string) {
    s.mu.Lock()
    defer s.mu.Unlock()
    
    if ticker, ok := s.tasks[name]; ok {
        ticker.Stop()
        delete(s.tasks, name)
    }
}

func (s *Scheduler) StopAll() {
    s.mu.Lock()
    defer s.mu.Unlock()
    
    for _, ticker := range s.tasks {
        ticker.Stop()
    }
    s.tasks = make(map[string]*time.Ticker)
}

// 使用调度器
func schedulerExample() {
    scheduler := NewScheduler()
    defer scheduler.StopAll()
    
    // 每秒执行
    scheduler.Schedule("task1", time.Second, func() {
        fmt.Println("Task 1 executed at", time.Now())
    })
    
    // 每2秒执行
    scheduler.Schedule("task2", 2*time.Second, func() {
        fmt.Println("Task 2 executed at", time.Now())
    })
    
    time.Sleep(5 * time.Second)
    scheduler.Cancel("task1")
    time.Sleep(3 * time.Second)
}

// 5. 延迟队列
type DelayQueue struct {
    items chan *delayedItem
}

type delayedItem struct {
    value interface{}
    delay time.Duration
}

func NewDelayQueue() *DelayQueue {
    dq := &DelayQueue{
        items: make(chan *delayedItem, 100),
    }
    
    go dq.process()
    return dq
}

func (dq *DelayQueue) Push(value interface{}, delay time.Duration) {
    dq.items <- &delayedItem{
        value: value,
        delay: delay,
    }
}

func (dq *DelayQueue) process() {
    for item := range dq.items {
        go func(i *delayedItem) {
            time.Sleep(i.delay)
            fmt.Printf("Processing: %v\n", i.value)
        }(item)
    }
}

8. 协程池

8.1 简单的协程池

go 复制代码
// 固定大小的worker池
type WorkerPool struct {
    tasks   chan func()
    workers int
}

func NewWorkerPool(workers int) *WorkerPool {
    pool := &WorkerPool{
        tasks:   make(chan func(), 100),
        workers: workers,
    }
    
    pool.start()
    return pool
}

func (p *WorkerPool) start() {
    for i := 0; i < p.workers; i++ {
        go func(workerID int) {
            for task := range p.tasks {
                fmt.Printf("Worker %d executing task\n", workerID)
                task()
            }
        }(i)
    }
}

func (p *WorkerPool) Submit(task func()) {
    p.tasks <- task
}

func (p *WorkerPool) Close() {
    close(p.tasks)
}

// 使用worker池
func workerPoolExample() {
    pool := NewWorkerPool(3)
    defer pool.Close()
    
    for i := 0; i < 10; i++ {
        id := i
        pool.Submit(func() {
            fmt.Printf("Task %d processing\n", id)
            time.Sleep(time.Second)
        })
    }
    
    time.Sleep(5 * time.Second)
}

8.2 带结果的协程池

go 复制代码
type Task struct {
    ID  int
    Job func() interface{}
}

type Result struct {
    TaskID int
    Value  interface{}
    Err    error
}

type ResultPool struct {
    tasks   chan Task
    results chan Result
    workers int
    wg      sync.WaitGroup
}

func NewResultPool(workers int) *ResultPool {
    pool := &ResultPool{
        tasks:   make(chan Task, 100),
        results: make(chan Result, 100),
        workers: workers,
    }
    
    for i := 0; i < workers; i++ {
        pool.wg.Add(1)
        go pool.worker()
    }
    
    return pool
}

func (p *ResultPool) worker() {
    defer p.wg.Done()
    
    for task := range p.tasks {
        result := Result{TaskID: task.ID}
        
        // 捕获panic
        func() {
            defer func() {
                if r := recover(); r != nil {
                    result.Err = fmt.Errorf("panic: %v", r)
                }
            }()
            
            result.Value = task.Job()
        }()
        
        p.results <- result
    }
}

func (p *ResultPool) Submit(task Task) {
    p.tasks <- task
}

func (p *ResultPool) Results() <-chan Result {
    return p.results
}

func (p *ResultPool) Close() {
    close(p.tasks)
    p.wg.Wait()
    close(p.results)
}

// 使用
func resultPoolExample() {
    pool := NewResultPool(5)
    
    // 提交任务
    go func() {
        for i := 0; i < 20; i++ {
            id := i
            pool.Submit(Task{
                ID: id,
                Job: func() interface{} {
                    time.Sleep(time.Millisecond * 100)
                    return id * 2
                },
            })
        }
        pool.Close()
    }()
    
    // 收集结果
    for result := range pool.Results() {
        if result.Err != nil {
            fmt.Printf("Task %d error: %v\n", result.TaskID, result.Err)
        } else {
            fmt.Printf("Task %d result: %v\n", result.TaskID, result.Value)
        }
    }
}

8.3 动态协程池

go 复制代码
type DynamicPool struct {
    tasks       chan func()
    minWorkers  int
    maxWorkers  int
    workerCount int32
    mu          sync.Mutex
}

func NewDynamicPool(min, max int) *DynamicPool {
    pool := &DynamicPool{
        tasks:      make(chan func(), 100),
        minWorkers: min,
        maxWorkers: max,
    }
    
    // 启动最小数量的worker
    for i := 0; i < min; i++ {
        pool.addWorker()
    }
    
    // 监控任务队列
    go pool.monitor()
    
    return pool
}

func (p *DynamicPool) addWorker() {
    atomic.AddInt32(&p.workerCount, 1)
    
    go func() {
        defer atomic.AddInt32(&p.workerCount, -1)
        
        for task := range p.tasks {
            task()
        }
    }()
}

func (p *DynamicPool) monitor() {
    ticker := time.NewTicker(time.Second)
    defer ticker.Stop()
    
    for range ticker.C {
        taskCount := len(p.tasks)
        workerCount := int(atomic.LoadInt32(&p.workerCount))
        
        // 任务堆积,增加worker
        if taskCount > workerCount && workerCount < p.maxWorkers {
            p.addWorker()
            fmt.Printf("Added worker, total: %d\n", workerCount+1)
        }
        
        // 任务少,减少worker(通过超时机制自然减少)
    }
}

func (p *DynamicPool) Submit(task func()) {
    p.tasks <- task
}

func (p *DynamicPool) Close() {
    close(p.tasks)
}

8.4 高级协程池(ants库风格)

go 复制代码
type Pool struct {
    capacity int32
    running  int32
    workers  []*Worker
    release  chan struct{}
    lock     sync.Locker
    cond     *sync.Cond
    once     sync.Once
}

type Worker struct {
    pool     *Pool
    task     chan func()
    recycled time.Time
}

func NewPool(size int) *Pool {
    p := &Pool{
        capacity: int32(size),
        release:  make(chan struct{}),
        lock:     new(sync.Mutex),
    }
    p.cond = sync.NewCond(p.lock)
    
    return p
}

func (p *Pool) Submit(task func()) error {
    if atomic.LoadInt32(&p.running) >= p.capacity {
        return fmt.Errorf("pool is full")
    }
    
    w := p.getWorker()
    w.task <- task
    
    return nil
}

func (p *Pool) getWorker() *Worker {
    p.lock.Lock()
    defer p.lock.Unlock()
    
    // 尝试复用worker
    n := len(p.workers)
    if n > 0 {
        w := p.workers[n-1]
        p.workers = p.workers[:n-1]
        return w
    }
    
    // 创建新worker
    atomic.AddInt32(&p.running, 1)
    return p.createWorker()
}

func (p *Pool) createWorker() *Worker {
    w := &Worker{
        pool: p,
        task: make(chan func(), 1),
    }
    
    go func() {
        for {
            select {
            case t := <-w.task:
                if t == nil {
                    atomic.AddInt32(&p.running, -1)
                    return
                }
                t()
                p.revertWorker(w)
            case <-p.release:
                return
            }
        }
    }()
    
    return w
}

func (p *Pool) revertWorker(w *Worker) {
    p.lock.Lock()
    w.recycled = time.Now()
    p.workers = append(p.workers, w)
    p.cond.Signal()
    p.lock.Unlock()
}

func (p *Pool) Release() {
    p.once.Do(func() {
        close(p.release)
        p.lock.Lock()
        for _, w := range p.workers {
            w.task <- nil
        }
        p.workers = nil
        p.lock.Unlock()
    })
}

8.5 协程池最佳实践

go 复制代码
// 1. 根据CPU核心数设置池大小
func optimalPoolSize() int {
    // CPU密集型任务
    cpuBound := runtime.NumCPU()
    
    // I/O密集型任务
    ioBound := runtime.NumCPU() * 2
    
    return ioBound
}

// 2. 优雅关闭
type GracefulPool struct {
    tasks   chan func()
    workers int
    wg      sync.WaitGroup
    once    sync.Once
}

func NewGracefulPool(workers int) *GracefulPool {
    pool := &GracefulPool{
        tasks:   make(chan func()),
        workers: workers,
    }
    
    for i := 0; i < workers; i++ {
        pool.wg.Add(1)
        go pool.worker()
    }
    
    return pool
}

func (p *GracefulPool) worker() {
    defer p.wg.Done()
    
    for task := range p.tasks {
        task()
    }
}

func (p *GracefulPool) Submit(task func()) {
    p.tasks <- task
}

func (p *GracefulPool) Shutdown() {
    p.once.Do(func() {
        close(p.tasks)
        p.wg.Wait()
    })
}

// 3. 错误处理
type SafePool struct {
    tasks chan func() error
    errs  chan error
}

func NewSafePool(workers int) *SafePool {
    pool := &SafePool{
        tasks: make(chan func() error),
        errs:  make(chan error, workers),
    }
    
    for i := 0; i < workers; i++ {
        go func() {
            for task := range pool.tasks {
                if err := task(); err != nil {
                    pool.errs <- err
                }
            }
        }()
    }
    
    return pool
}

9. 反射

9.1 反射基础

go 复制代码
import "reflect"

// 反射允许程序检查和操作自身结构
func reflectionBasic() {
    var x float64 = 3.4
    
    // 获取类型
    t := reflect.TypeOf(x)
    fmt.Println("Type:", t)      // float64
    fmt.Println("Kind:", t.Kind()) // float64
    
    // 获取值
    v := reflect.ValueOf(x)
    fmt.Println("Value:", v)          // 3.4
    fmt.Println("Type:", v.Type())    // float64
    fmt.Println("Kind:", v.Kind())    // float64
    fmt.Println("Float:", v.Float())  // 3.4
}

9.2 反射修改值

go 复制代码
func reflectionModify() {
    var x float64 = 3.4
    
    v := reflect.ValueOf(&x)  // 必须传指针
    v = v.Elem()              // 获取指针指向的值
    
    if v.CanSet() {
        v.SetFloat(7.1)
    }
    
    fmt.Println(x)  // 7.1
}

// 修改结构体字段
type Person struct {
    Name string
    Age  int
}

func modifyStruct() {
    p := Person{Name: "Alice", Age: 30}
    
    v := reflect.ValueOf(&p).Elem()
    
    // 修改Name字段
    nameField := v.FieldByName("Name")
    if nameField.CanSet() {
        nameField.SetString("Bob")
    }
    
    // 修改Age字段
    ageField := v.FieldByName("Age")
    if ageField.CanSet() {
        ageField.SetInt(35)
    }
    
    fmt.Println(p)  // {Bob 35}
}

9.3 反射检查结构体

go 复制代码
type User struct {
    ID   int    `json:"id" db:"user_id"`
    Name string `json:"name" db:"user_name"`
    age  int    // 私有字段
}

func inspectStruct() {
    u := User{ID: 1, Name: "Alice", age: 30}
    
    t := reflect.TypeOf(u)
    v := reflect.ValueOf(u)
    
    fmt.Println("Type:", t.Name())
    fmt.Println("Number of fields:", t.NumField())
    
    // 遍历字段
    for i := 0; i < t.NumField(); i++ {
        field := t.Field(i)
        value := v.Field(i)
        
        fmt.Printf("Field: %s, Type: %s, Value: %v\n",
            field.Name,
            field.Type,
            value.Interface())
        
        // 获取标签
        if tag := field.Tag.Get("json"); tag != "" {
            fmt.Printf("  JSON tag: %s\n", tag)
        }
        if tag := field.Tag.Get("db"); tag != "" {
            fmt.Printf("  DB tag: %s\n", tag)
        }
    }
}

9.4 反射调用方法

go 复制代码
type Calculator struct{}

func (c Calculator) Add(a, b int) int {
    return a + b
}

func (c Calculator) Multiply(a, b int) int {
    return a * b
}

func callMethod() {
    calc := Calculator{}
    v := reflect.ValueOf(calc)
    
    // 调用Add方法
    method := v.MethodByName("Add")
    args := []reflect.Value{
        reflect.ValueOf(10),
        reflect.ValueOf(20),
    }
    results := method.Call(args)
    
    fmt.Println("Result:", results[0].Int())  // 30
}

// 动态调用任意方法
func dynamicCall(obj interface{}, methodName string, args ...interface{}) ([]interface{}, error) {
    v := reflect.ValueOf(obj)
    method := v.MethodByName(methodName)
    
    if !method.IsValid() {
        return nil, fmt.Errorf("method %s not found", methodName)
    }
    
    // 转换参数
    in := make([]reflect.Value, len(args))
    for i, arg := range args {
        in[i] = reflect.ValueOf(arg)
    }
    
    // 调用方法
    results := method.Call(in)
    
    // 转换返回值
    out := make([]interface{}, len(results))
    for i, result := range results {
        out[i] = result.Interface()
    }
    
    return out, nil
}

func dynamicCallExample() {
    calc := Calculator{}
    
    result, err := dynamicCall(calc, "Add", 10, 20)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Println("Result:", result[0])  // 30
}

9.5 反射创建实例

go 复制代码
// 通过类型创建实例
func createInstance() {
    // 获取类型
    var u User
    t := reflect.TypeOf(u)
    
    // 创建新实例
    v := reflect.New(t)  // 返回指针
    elem := v.Elem()
    
    // 设置字段
    elem.Field(0).SetInt(123)
    elem.Field(1).SetString("Dynamic User")
    
    // 转换回原类型
    newUser := v.Interface().(*User)
    fmt.Println(*newUser)  // {123 Dynamic User 0}
}

// 通过字符串创建类型
var typeRegistry = map[string]reflect.Type{
    "User": reflect.TypeOf(User{}),
    "Person": reflect.TypeOf(Person{}),
}

func createByName(typeName string) interface{} {
    t, ok := typeRegistry[typeName]
    if !ok {
        return nil
    }
    
    v := reflect.New(t).Elem()
    return v.Interface()
}

9.6 反射实战应用

go 复制代码
// 1. JSON序列化/反序列化
func structToMap(obj interface{}) map[string]interface{} {
    result := make(map[string]interface{})
    
    v := reflect.ValueOf(obj)
    if v.Kind() == reflect.Ptr {
        v = v.Elem()
    }
    
    t := v.Type()
    for i := 0; i < v.NumField(); i++ {
        field := t.Field(i)
        value := v.Field(i)
        
        // 只处理导出的字段
        if field.PkgPath != "" {
            continue
        }
        
        // 获取JSON标签
        tag := field.Tag.Get("json")
        if tag == "-" {
            continue
        }
        
        name := field.Name
        if tag != "" {
            name = tag
        }
        
        result[name] = value.Interface()
    }
    
    return result
}

// 2. 深拷贝
func deepCopy(src interface{}) interface{} {
    if src == nil {
        return nil
    }
    
    original := reflect.ValueOf(src)
    cpy := reflect.New(original.Type()).Elem()
    copyRecursive(original, cpy)
    
    return cpy.Interface()
}

func copyRecursive(src, dst reflect.Value) {
    switch src.Kind() {
    case reflect.Ptr:
        if !src.IsNil() {
            dst.Set(reflect.New(src.Elem().Type()))
            copyRecursive(src.Elem(), dst.Elem())
        }
    case reflect.Struct:
        for i := 0; i < src.NumField(); i++ {
            if dst.Field(i).CanSet() {
                copyRecursive(src.Field(i), dst.Field(i))
            }
        }
    case reflect.Slice:
        if !src.IsNil() {
            dst.Set(reflect.MakeSlice(src.Type(), src.Len(), src.Cap()))
            for i := 0; i < src.Len(); i++ {
                copyRecursive(src.Index(i), dst.Index(i))
            }
        }
    case reflect.Map:
        if !src.IsNil() {
            dst.Set(reflect.MakeMap(src.Type()))
            for _, key := range src.MapKeys() {
                originalValue := src.MapIndex(key)
                copyValue := reflect.New(originalValue.Type()).Elem()
                copyRecursive(originalValue, copyValue)
                dst.SetMapIndex(key, copyValue)
            }
        }
    default:
        dst.Set(src)
    }
}

// 3. 验证器
type Validator struct {
    validators map[string]func(interface{}) error
}

func NewValidator() *Validator {
    return &Validator{
        validators: map[string]func(interface{}) error{
            "required": func(v interface{}) error {
                if reflect.ValueOf(v).IsZero() {
                    return fmt.Errorf("field is required")
                }
                return nil
            },
            "min": func(v interface{}) error {
                // 实现最小值检查
                return nil
            },
        },
    }
}

func (v *Validator) Validate(obj interface{}) error {
    val := reflect.ValueOf(obj)
    if val.Kind() == reflect.Ptr {
        val = val.Elem()
    }
    
    typ := val.Type()
    for i := 0; i < val.NumField(); i++ {
        field := typ.Field(i)
        value := val.Field(i)
        
        // 解析validate标签
        tag := field.Tag.Get("validate")
        if tag == "" {
            continue
        }
        
        // 执行验证
        if validator, ok := v.validators[tag]; ok {
            if err := validator(value.Interface()); err != nil {
                return fmt.Errorf("field %s: %w", field.Name, err)
            }
        }
    }
    
    return nil
}

// 4. ORM映射
func scanRow(rows *sql.Rows, dest interface{}) error {
    destv := reflect.ValueOf(dest)
    if destv.Kind() != reflect.Ptr {
        return fmt.Errorf("dest must be a pointer")
    }
    
    elem := destv.Elem()
    if elem.Kind() != reflect.Struct {
        return fmt.Errorf("dest must be a struct pointer")
    }
    
    columns, err := rows.Columns()
    if err != nil {
        return err
    }
    
    values := make([]interface{}, len(columns))
    for i := range values {
        values[i] = new(interface{})
    }
    
    if err := rows.Scan(values...); err != nil {
        return err
    }
    
    for i, col := range columns {
        field := elem.FieldByName(col)
        if field.IsValid() && field.CanSet() {
            val := reflect.ValueOf(values[i]).Elem().Interface()
            field.Set(reflect.ValueOf(val))
        }
    }
    
    return nil
}

9.7 反射的性能和注意事项

go 复制代码
// ⚠️ 反射的性能开销

// 基准测试对比
func BenchmarkDirect(b *testing.B) {
    u := User{ID: 1, Name: "Alice"}
    for i := 0; i < b.N; i++ {
        _ = u.ID
        _ = u.Name
    }
}

func BenchmarkReflection(b *testing.B) {
    u := User{ID: 1, Name: "Alice"}
    v := reflect.ValueOf(u)
    for i := 0; i < b.N; i++ {
        _ = v.Field(0).Int()
        _ = v.Field(1).String()
    }
}
// 反射慢10-100倍

// ✅ 反射的最佳实践
// 1. 只在必要时使用反射
// 2. 缓存反射结果
var typeCache sync.Map

func getType(obj interface{}) reflect.Type {
    key := reflect.TypeOf(obj)
    if t, ok := typeCache.Load(key); ok {
        return t.(reflect.Type)
    }
    
    t := reflect.TypeOf(obj)
    typeCache.Store(key, t)
    return t
}

// 3. 避免在循环中使用反射
// ❌ 不好
for i := 0; i < 1000; i++ {
    t := reflect.TypeOf(obj)  // 重复反射
}

// ✅ 好
t := reflect.TypeOf(obj)
for i := 0; i < 1000; i++ {
    // 使用缓存的类型
}

// 4. 类型断言优于反射
// ❌ 不好
v := reflect.ValueOf(obj)
if v.Kind() == reflect.Int {
    val := v.Int()
}

// ✅ 好
if val, ok := obj.(int); ok {
    // 使用val
}

10. 泛型

10.1 泛型基础(Go 1.18+)

go 复制代码
// 泛型函数
func Print[T any](value T) {
    fmt.Println(value)
}

func printExample() {
    Print[int](42)
    Print[string]("hello")
    Print(3.14)  // 类型推断
}

// 多类型参数
func Pair[T, U any](first T, second U) (T, U) {
    return first, second
}

func pairExample() {
    a, b := Pair(1, "hello")
    fmt.Println(a, b)  // 1 hello
}

10.2 类型约束

go 复制代码
// 使用comparable约束(可比较类型)
func Equal[T comparable](a, b T) bool {
    return a == b
}

func equalExample() {
    fmt.Println(Equal(1, 1))        // true
    fmt.Println(Equal("a", "b"))    // false
    // fmt.Println(Equal([]int{}, []int{}))  // 编译错误:slice不可比较
}

// 自定义约束
type Number interface {
    int | int64 | float64
}

func Add[T Number](a, b T) T {
    return a + b
}

func addExample() {
    fmt.Println(Add(1, 2))          // 3
    fmt.Println(Add(1.5, 2.3))      // 3.8
    // fmt.Println(Add("a", "b"))   // 编译错误
}

// 近似约束(允许自定义类型)
type Numeric interface {
    ~int | ~int64 | ~float64
}

type MyInt int

func Sum[T Numeric](nums []T) T {
    var total T
    for _, num := range nums {
        total += num
    }
    return total
}

func sumExample() {
    ints := []int{1, 2, 3}
    fmt.Println(Sum(ints))  // 6
    
    myInts := []MyInt{1, 2, 3}
    fmt.Println(Sum(myInts))  // 6
}

10.3 泛型类型

go 复制代码
// 泛型结构体
type Stack[T any] struct {
    items []T
}

func NewStack[T any]() *Stack[T] {
    return &Stack[T]{
        items: make([]T, 0),
    }
}

func (s *Stack[T]) Push(item T) {
    s.items = append(s.items, item)
}

func (s *Stack[T]) Pop() (T, bool) {
    if len(s.items) == 0 {
        var zero T
        return zero, false
    }
    
    item := s.items[len(s.items)-1]
    s.items = s.items[:len(s.items)-1]
    return item, true
}

func (s *Stack[T]) IsEmpty() bool {
    return len(s.items) == 0
}

func stackExample() {
    // 整数栈
    intStack := NewStack[int]()
    intStack.Push(1)
    intStack.Push(2)
    val, ok := intStack.Pop()
    fmt.Println(val, ok)  // 2 true
    
    // 字符串栈
    strStack := NewStack[string]()
    strStack.Push("hello")
    strStack.Push("world")
}

// 泛型Map
type SafeMap[K comparable, V any] struct {
    mu   sync.RWMutex
    data map[K]V
}

func NewSafeMap[K comparable, V any]() *SafeMap[K, V] {
    return &SafeMap[K, V]{
        data: make(map[K]V),
    }
}

func (m *SafeMap[K, V]) Set(key K, value V) {
    m.mu.Lock()
    defer m.mu.Unlock()
    m.data[key] = value
}

func (m *SafeMap[K, V]) Get(key K) (V, bool) {
    m.mu.RLock()
    defer m.mu.RUnlock()
    val, ok := m.data[key]
    return val, ok
}

func (m *SafeMap[K, V]) Delete(key K) {
    m.mu.Lock()
    defer m.mu.Unlock()
    delete(m.data, key)
}

10.4 泛型函数实战

go 复制代码
// 1. 泛型切片操作
func Map[T, U any](slice []T, fn func(T) U) []U {
    result := make([]U, len(slice))
    for i, v := range slice {
        result[i] = fn(v)
    }
    return result
}

func Filter[T any](slice []T, fn func(T) bool) []T {
    result := make([]T, 0)
    for _, v := range slice {
        if fn(v) {
            result = append(result, v)
        }
    }
    return result
}

func Reduce[T, U any](slice []T, initial U, fn func(U, T) U) U {
    result := initial
    for _, v := range slice {
        result = fn(result, v)
    }
    return result
}

func sliceOpsExample() {
    nums := []int{1, 2, 3, 4, 5}
    
    // Map: 每个元素乘2
    doubled := Map(nums, func(n int) int {
        return n * 2
    })
    fmt.Println(doubled)  // [2 4 6 8 10]
    
    // Filter: 筛选偶数
    evens := Filter(nums, func(n int) bool {
        return n%2 == 0
    })
    fmt.Println(evens)  // [2 4]
    
    // Reduce: 求和
    sum := Reduce(nums, 0, func(acc, n int) int {
        return acc + n
    })
    fmt.Println(sum)  // 15
}

// 2. 泛型排序
func Sort[T any](slice []T, less func(a, b T) bool) {
    n := len(slice)
    for i := 0; i < n-1; i++ {
        for j := 0; j < n-i-1; j++ {
            if less(slice[j+1], slice[j]) {
                slice[j], slice[j+1] = slice[j+1], slice[j]
            }
        }
    }
}

func sortExample() {
    nums := []int{5, 2, 8, 1, 9}
    Sort(nums, func(a, b int) bool {
        return a < b
    })
    fmt.Println(nums)  // [1 2 5 8 9]
    
    type Person struct {
        Name string
        Age  int
    }
    
    people := []Person{
        {"Alice", 30},
        {"Bob", 25},
        {"Charlie", 35},
    }
    
    Sort(people, func(a, b Person) bool {
        return a.Age < b.Age
    })
    fmt.Println(people)
}

// 3. 泛型链表
type Node[T any] struct {
    Value T
    Next  *Node[T]
}

type LinkedList[T any] struct {
    Head *Node[T]
}

func (l *LinkedList[T]) Add(value T) {
    node := &Node[T]{Value: value}
    if l.Head == nil {
        l.Head = node
        return
    }
    
    current := l.Head
    for current.Next != nil {
        current = current.Next
    }
    current.Next = node
}

func (l *LinkedList[T]) ForEach(fn func(T)) {
    current := l.Head
    for current != nil {
        fn(current.Value)
        current = current.Next
    }
}

// 4. 泛型Option类型
type Option[T any] struct {
    value *T
}

func Some[T any](value T) Option[T] {
    return Option[T]{value: &value}
}

func None[T any]() Option[T] {
    return Option[T]{value: nil}
}

func (o Option[T]) IsSome() bool {
    return o.value != nil
}

func (o Option[T]) IsNone() bool {
    return o.value == nil
}

func (o Option[T]) Unwrap() T {
    if o.value == nil {
        panic("unwrap on None")
    }
    return *o.value
}

func (o Option[T]) UnwrapOr(defaultValue T) T {
    if o.value == nil {
        return defaultValue
    }
    return *o.value
}

func optionExample() {
    some := Some(42)
    fmt.Println(some.Unwrap())  // 42
    
    none := None[int]()
    fmt.Println(none.UnwrapOr(0))  // 0
}

// 5. 泛型Result类型
type Result[T any] struct {
    value *T
    err   error
}

func Ok[T any](value T) Result[T] {
    return Result[T]{value: &value}
}

func Err[T any](err error) Result[T] {
    return Result[T]{err: err}
}

func (r Result[T]) IsOk() bool {
    return r.err == nil
}

func (r Result[T]) IsErr() bool {
    return r.err != nil
}

func (r Result[T]) Unwrap() (T, error) {
    if r.err != nil {
        var zero T
        return zero, r.err
    }
    return *r.value, nil
}

10.5 泛型接口

go 复制代码
// 泛型接口
type Container[T any] interface {
    Add(item T)
    Get(index int) (T, bool)
    Size() int
}

// 实现泛型接口
type ArrayList[T any] struct {
    items []T
}

func (a *ArrayList[T]) Add(item T) {
    a.items = append(a.items, item)
}

func (a *ArrayList[T]) Get(index int) (T, bool) {
    if index < 0 || index >= len(a.items) {
        var zero T
        return zero, false
    }
    return a.items[index], true
}

func (a *ArrayList[T]) Size() int {
    return len(a.items)
}

// 使用泛型接口
func ProcessContainer[T any](c Container[T], items []T) {
    for _, item := range items {
        c.Add(item)
    }
    fmt.Println("Container size:", c.Size())
}

10.6 泛型的限制和最佳实践

go 复制代码
// ⚠️ 泛型的限制

// 1. 不能用于方法的类型参数
type MyStruct struct{}

// ❌ 不支持
// func (m MyStruct) Method[T any](value T) {}

// ✅ 可以用于类型的方法
type MyGenericStruct[T any] struct {
    value T
}

func (m MyGenericStruct[T]) GetValue() T {
    return m.value
}

// 2. 类型参数不能用于类型断言或类型switch
func process[T any](value T) {
    // ❌ 不支持
    // switch value.(type) { ... }
    
    // ✅ 使用反射
    v := reflect.ValueOf(value)
    switch v.Kind() {
    case reflect.Int:
        // ...
    }
}

// ✅ 泛型最佳实践

// 1. 优先使用接口而非泛型
// 如果现有接口满足需求,使用接口
func ProcessReader(r io.Reader) {}  // ✅ 好

// 只有需要保留类型信息时才用泛型
func Transform[T any](items []T, fn func(T) T) []T {  // ✅ 好
    // 保留了T的类型信息
}

// 2. 约束应该尽可能宽松
// ❌ 过于严格
type IntOnly interface {
    int
}

// ✅ 更灵活
type Number interface {
    ~int | ~int64 | ~float64
}

// 3. 避免过度泛型化
// ❌ 不必要的泛型
func Add[T int](a, b T) T {
    return a + b
}

// ✅ 简单函数不需要泛型
func Add(a, b int) int {
    return a + b
}

// 4. 泛型命名规范
// 单个类型参数:T, U, V
// 特定含义:K(Key), V(Value), E(Element)
type Map[K comparable, V any] struct {
    data map[K]V
}

总结

本指南全面覆盖了Go语言并发编程的核心知识:

📚 核心概念

  1. 并发模型:理解并发vs并行,掌握CSP模型
  2. Goroutine:轻量级线程的创建、调度和管理
  3. Channel:Go并发的核心通信机制
  4. 同步原语:Mutex、RWMutex、WaitGroup、Once等
  5. Select:优雅的多路复用
  6. Context:请求范围的控制和取消
  7. 定时器:Timer和Ticker的实战应用
  8. 协程池:高效的goroutine管理
  9. 反射:运行时类型操作
  10. 泛型:类型安全的代码复用

🎯 关键要点

  • 通信优于共享:用channel传递数据
  • 避免泄漏:确保goroutine能够退出
  • 正确同步:选择合适的同步原语
  • 优雅关闭:使用Context控制生命周期
  • 性能优化:协程池、对象池、原子操作
  • 类型安全:善用泛型提高代码质量

💡 最佳实践

  1. 始终考虑goroutine的退出机制
  2. 使用Context传递取消信号
  3. Channel的发送者负责关闭
  4. 避免在循环中启动无限goroutine
  5. 使用select处理超时和取消
  6. 反射谨慎使用,注意性能
  7. 泛型用于需要类型安全的场景
相关推荐
风象南3 小时前
我把大脑开源给了AI
人工智能·后端
橙序员小站8 小时前
Agent Skill 是什么?一文讲透 Agent Skill 的设计与实现
前端·后端
怒放吧德德8 小时前
Netty 4.2 入门指南:从概念到第一个程序
java·后端·netty
雨中飘荡的记忆9 小时前
大流量下库存扣减的数据库瓶颈:Redis分片缓存解决方案
java·redis·后端
开心就好202510 小时前
UniApp开发应用多平台上架全流程:H5小程序iOS和Android
后端·ios
悟空码字11 小时前
告别“屎山代码”:AI 代码整洁器让老项目重获新生
后端·aigc·ai编程
小码哥_常11 小时前
大厂不宠@Transactional,背后藏着啥秘密?
后端
奋斗小强11 小时前
内存危机突围战:从原理辨析到线上实战,彻底搞懂 OOM 与内存泄漏
后端
小码哥_常11 小时前
Spring Boot接口防抖秘籍:告别“手抖”,守护数据一致性
后端
心之语歌12 小时前
基于注解+拦截器的API动态路由实现方案
java·后端