面试题答案
一键面试内存地址变化
当Go语言的切片发生扩容时,底层数组的内存地址可能会发生变化。如果当前切片的容量不足以容纳新的元素,Go语言会分配一块新的内存,新的底层数组将会存储在这块新的内存上,因此底层数组的内存地址会改变。
数据迁移
切片扩容时,原底层数组的数据会迁移到新的底层数组中。Go语言会将原底层数组中的所有元素逐个复制到新的底层数组对应的位置上,以保证数据的连续性和一致性。
举例说明
package main
import (
"fmt"
)
func main() {
// 初始化一个切片,初始容量为5
s := make([]int, 0, 5)
// 获取切片的底层数组的指针
oldPtr := &s[0]
// 添加元素,当添加第6个元素时会触发扩容
for i := 0; i < 6; i++ {
s = append(s, i)
}
// 获取扩容后切片的底层数组的指针
newPtr := &s[0]
if oldPtr != newPtr {
fmt.Println("底层数组内存地址发生变化")
} else {
fmt.Println("底层数组内存地址未发生变化")
}
// 验证数据是否正确迁移
for i, v := range s {
fmt.Printf("s[%d] = %d\n", i, v)
}
}
在上述示例中,当向初始容量为5的切片 s
中添加第6个元素时,切片会发生扩容。通过比较扩容前后底层数组的指针 oldPtr
和 newPtr
可知内存地址发生了变化。并且通过遍历切片验证了数据正确迁移。