go-Go语言实战_阅读笔记

go-Go语言实战_阅读笔记


slice 详解

  • 切片大小 在 64 位架构的机器上,一个切片需要 24 字节的内存:指针字段需要 8 字节,长度和容量 字段分别需要 8 字节, 由于与切片关联的数据包含在底层数组里,不属于切片本身,所以将切片 复制到任意函数的时候,对底层数组大小都不会有影响。复制时只会复制切片本身,不会涉及底 层数组 (4.2.5 在函数间传递切片)

有/无 缓冲通道

参考: go-性能优化profiler.md 中的 记一次 goroutine 定位及解决

1
2
chValid := make(chan bool) // 无缓冲
chValid := make(chan bool, 1) // 缓冲为 1
  • 无缓冲的 chan 会阻塞 往 chan 里丢数据的 goroutineA, 只有 chan 被消费了 goroutineA 才能继续往下跑

    1
    2
    3
    4
    5
    6
    7
    8
    chValid := make(chan bool)
    go func() { // goroutineA
    defer fmt.Println("--- handshake defer")
    time.Sleep(time.Second * 4)
    chValid <- false
    }()

    // <-chValid 如果不消费, goroutineA 将一直阻塞
  • 有缓冲的 chan, 只要当 缓冲区 满了之后才会阻塞

    1
    2
    3
    4
    5
    6
    7
    8
    chValid := make(chan bool, 1)
    go func() { // goroutineA
    defer fmt.Println("--- handshake defer")
    time.Sleep(time.Second * 4)
    chValid <- false
    }()

    // <-chValid 不消费, goroutineA 也不会阻塞

    所以这种原理可以用于 go 的并发量控制, 通过指定 chan 的缓冲区大小来控制 go 并发数量


单元测试/基准测试