查漏补缺之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\n", 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 这是滴滴的饶大佬写的,从非常底层的角度分析的,建议预留整块时间来看。

posted @   sicnu-yudidi  阅读(217)  评论(0)    收藏  举报
编辑推荐:
· 当数据爆炸遇上SQL Server:优化策略全链路解析
· 记录一次线上问题排查:JDK序列化问题
· 微服务之间有哪些调用方式?
· 记一次SQL隐式转换导致精度丢失问题的排查
· dotnet 9 通过 AppHostRelativeDotNet 指定自定义的运行时路径
阅读排行:
· 一个基于 C# Unity 开发的金庸群侠传 3D 版,直呼牛逼!
· SQL Server 2025 中的改进
· 向商界大佬一样管理技术工作 - 以团队换将+技术重构为例
· 用c#从头写一个AI agent,实现企业内部自然语言数据统计分析(三)--一个综合的例子
· DeepSeek+Coze实战:如何从0到1打造一个热点监控智能体
点击右上角即可分享
微信分享提示