Go 基础面试题, Go 语言 slice 的 len,cap 和共享及扩容机制是什么?
Go 基础面试题, Go 语言 slice 的 len,cap 和共享及扩容机制是什么?
QA
Step 1
Q:: Go 语言中 slice 的 len 和 cap 分别代表什么?
A:: 在 Go 语言中,slice 是一种动态数组。slice 的 len 表示当前 slice 中元素的个数,cap 表示 slice 底层数组的容量。len 只能用于获取当前 slice 的长度,而 cap 用于获取 slice 最大可以容纳的元素个数而不需要重新分配内存。
Step 2
Q:: Go 语言中 slice 的共享机制是怎样的?
A:: 在 Go 语言中,多个 slice 可以共享同一个底层数组。这意味着修改一个 slice 的内容可能会影响到其他共享同一个底层数组的 slice。例如,如果你从一个 slice 创建了一个新 slice,那么这两个 slice 可能共享同一个底层数组,因此对其中一个 slice 的修改会反映在另一个 slice 中。
Step 3
Q:: Go 语言中 slice 的扩容机制是什么?
A:: 当 Go 语言中的 slice 达到其容量上限时,如果需要继续添加元素,Go 会自动扩容。扩容的具体策略是创建一个新的、容量更大的底层数组,并将旧 slice 的内容复制到新的底层数组中。通常情况下,如果当前 slice 的容量小于 1024,Go 会将容量翻倍扩展;如果容量超过 1024,则会以原容量的 1/4
进行扩展。
Step 4
Q:: 如何避免 slice 扩容导致的性能问题?
A:: 为了避免 slice 扩容带来的性能开销,在创建 slice 时可以预先指定一个合理的容量(cap),这样可以减少扩容时的内存复制操作,提升性能。对于大数据量处理的场景,尽量避免频繁的 slice 扩容,合理估计和分配 slice 的初始容量非常重要。
Step 5
Q:: slice 和数组在 Go 语言中的区别是什么?
A:: 数组是固定长度的,长度是数组类型的一部分,因此数组的长度一旦定义便无法改变。而 slice 是一种动态的、大小可变的数组抽象。数组可以直接用作 slice 的底层结构,但 slice 的长度可以变化,且 slice 的操作更加灵活和高效。