Slice 面试题

1. slice 底层结构是怎样的?

slice 底层数据其实也是数组,slice 是对数组的封装,它描述一个数组的片段。slice 实际上是一个结构体,包含三个字段:

  • 长度
  • 容量
  • 指向底层数组的指针
1
2
3
4
5
type slice struct {
array unsafe.Pointer // 指向底层数组的指针
len int // slice 的长度
cap int // slice 的容量
}

slice 底层结构

2. slice 的扩容机制是怎样的?

1.17 及以前

  1. 如果期望容量大于当前容量的两倍就会使用期望容量
  2. 如果当前切片的容量小于 1024 就会将容量翻倍
  3. 如果当前切片的容量大于等于 1024 就会每次增加 25% 的容量,直到新容量大于期望容量

1.18及以后

引入了新的扩容规则:当原 slice 容量(oldcap)小于 256 的时候,新 slice (newcap)容量为原来的 2 倍;原 slice 容量超过 256,新 slice 容量 newcap = oldcap + (oldcap + 3*256) / 4

3. 从一个切片截取出另一个切片,修改新切片的值会影响原来的切片内容吗?

如果新切片没有触发扩容,则修改切片会影响原切片

如果触发了扩容,则不会影响原切片

4. slice 作为函数参数传递,会改变原 slice 吗?

当 slice 作为函数参数时,因为会拷贝一份新的 slice 作为实参,所以原来的 slice 结构并不会被函数中的操作改变,也就是说,slice 其实是一个结构体,包含了三个成员:len,cap,array 并不会变化。

但是需要注意的是,尽管 slice 结构不会变,但是其底层数组的数据如果有修改的话,则会发生变化。若传的是 slice 的指针,则原 slice 结构会变,底层数组的数据也会变。


参考资料: