• 查漏补缺之slice


    interviewer:说一说slice
    interviewee: 主要包括以下几点

    1. slice and array
    2. slice的底层数据结构
    3. length和capacity
      切片的capacity的计算规则
    4. 扩容
    5. Reslicing
    6. SliceHeader: slice的运行时表示
    7. 可以指定capacity的reslicing

    1. slice and array

    slice的底层存储是array,而slice只是描述底层数组的某个片段的范围,并不会实际存储数据。

    2. slice的底层数据结构

    A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment).

    3. length和capacity

    某个切片的capacity的计算规则

    某个切片的capacity = 底层数组的cap - 该切片的prt指针在底层数组中的位置

    参考附录[Re-slicing slices in Golang]

    4. 扩容

    • 小于1024个元素时,2倍增长; >=1024个元素时,1.25倍增长。

    这个结论是不完全正确的,没有考虑到字节对齐,具体请参考附录[深度解密Go语言之Slice]

    5. Reslicing

    5.1 Reslicing的几个简单例子
    5.2 Reslicnig过程中,length和capacity的变化 [手绘笔记]

    6. SliceHeader: slice的运行时表示

    https://play.golang.org/p/aKSZlVGGTpL

    package main
    
    import (
    	"fmt"
    	"reflect"
    	"unsafe"
    )
    
    func main() {
    	a := []byte{1, 2, 3}
    	// cut slice
    	printSlice("a", a)
    	printSlice("a[0:]", a[0:])
    	printSlice("a[1:]", a[1:])
    	// extend slice from a[:1] to a[1:2]
    	printSlice("a[:0]", a[:0])
    	printSlice("a[:0][:2]", a[:0][:2]) // 最开始我不理解,为什么a[:0]有0个元素,却可从中取出2个元素,后来知道了extend slice操作后才理解.
    	printSlice("a[:2]", a[:2]) 
    }
    
    func printSlice(s string, arr []byte) {
    	sliceHeader := (*reflect.SliceHeader)((unsafe.Pointer(&arr)))
    	fmt.Printf("%s %+v %v
    ", s, sliceHeader, arr)
    }
    // output 4251681-4251680 = 1byte,说明底层数组的prt指针指向了下一个byte.
    //a &{Data:4251680 Len:3 Cap:3} [1 2 3]
    //a[0:] &{Data:4251680 Len:3 Cap:3} [1 2 3]
    //a[1:] &{Data:4251681 Len:2 Cap:2} [2 3]
    //a[:0] &{Data:4251680 Len:0 Cap:3} []
    //a[:0][:2] &{Data:4251680 Len:2 Cap:3} [1 2]
    //a[:2] &{Data:4251680 Len:2 Cap:3} [1 2] // 可以看出a[:0][:2]和a[:2]的结果是一样的.
    

    7.可以指定capacity的reslicing

    slice[low : high : max],具体参考[Re-slicing slices in Golang回答2] 和 [Slice expressions,Full slice expressions]

    参考资料

    Re-slicing slices in Golang

    [Re-slicing slices in Golang回答2] (https://stackoverflow.com/a/18911267/7689674)

    Slice expressions,Full slice expressions

    Go Slices: usage and internals

    深度解密Go语言之Slice 这是滴滴的饶大佬写的,从非常底层的角度分析的,建议预留整块时间来看。

  • 相关阅读:
    LINX中的各种alloc
    Enea LINX代码分析之二(ECM_RX)
    Enea LINX代码分析之一
    看代码和写代码还是很不同的
    sctp bind
    sockaddr和sockaddr_in
    pthread条件变量
    System V IPV & Posix IPC(摘自Unix网络编程卷2)
    [宽度优先搜索] FZU-2150 Fire Game
    [字符哈希] POJ 3094 Quicksum
  • 原文地址:https://www.cnblogs.com/yudidi/p/12152839.html
Copyright © 2020-2023  润新知