面试题答案
一键面试- 底层数组类型对append操作行为的影响
- 容量不足时的内存重新分配:
- 当切片的底层数组容量不足以容纳新添加的元素时,Go语言会重新分配内存。具体来说,会分配一个新的更大的底层数组。新数组的大小通常是原数组容量的两倍(如果原容量小于1024),如果原容量大于或等于1024,则新容量会增加原容量的1/4。
- 例如,假设有一个切片
s := make([]int, 0, 5)
,此时底层数组容量为5。当执行s = append(s, 1, 2, 3, 4, 5, 6)
时,由于要添加6个元素,而原容量为5,容量不足。这时会重新分配内存,新的底层数组容量可能变为10(原容量5小于1024,变为原容量的2倍)。
- 数据复制:
- 内存重新分配后,Go会将原底层数组中的数据复制到新的底层数组中,然后再将新添加的元素追加到新数组的末尾。接着,切片会指向这个新的底层数组。
- 以上面的例子,先将原
s
中的数据复制到新的容量为10的底层数组,再把6
追加到新数组末尾,s
此时指向新的底层数组。
- 容量不足时的内存重新分配:
- 不同类型切片在append时的表现差异举例
- 整数类型切片:
package main
import (
"fmt"
)
func main() {
intSlice := make([]int, 0, 5)
intSlice = append(intSlice, 1, 2, 3, 4, 5, 6)
fmt.Println(intSlice)
}
在这个例子中,intSlice
是 int
类型的切片,一开始容量为5,添加6个元素导致容量不足,重新分配内存,最后输出 [1 2 3 4 5 6]
。
- 结构体类型切片:
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
personSlice := make([]Person, 0, 2)
p1 := Person{"Alice", 25}
p2 := Person{"Bob", 30}
p3 := Person{"Charlie", 35}
personSlice = append(personSlice, p1, p2, p3)
fmt.Println(personSlice)
}
这里 personSlice
是 Person
结构体类型的切片,初始容量为2,添加3个 Person
结构体实例导致容量不足,重新分配内存,最后输出 [{Alice 25} {Bob 30} {Charlie 35}]
。其append行为和整数类型切片类似,都是在容量不足时重新分配内存并复制数据,只是复制的数据是结构体实例。