zoukankan      html  css  js  c++  java
  • 查漏补缺之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 这是滴滴的饶大佬写的,从非常底层的角度分析的,建议预留整块时间来看。

  • 相关阅读:
    Java实现 LeetCode 69 x的平方根
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 66 加一
    Java实现 LeetCode 66 加一
    CxSkinButton按钮皮肤类
  • 原文地址:https://www.cnblogs.com/yudidi/p/12152839.html
Copyright © 2011-2022 走看看