面试题答案
一键面试- 切片容量变化机制:
- 初始时,
slice1 := make([]int, 0, 5)
,其长度为0,容量为5。 - 当向切片中添加元素时,若当前长度小于容量,直接在已有空间添加元素,容量不变。例如,添加第1个到第5个元素时,容量始终为5。
- 当添加第6个元素时,由于当前长度(5)等于容量(5),切片需要扩容。Go语言中,切片扩容时新容量一般为旧容量的2倍(如果旧容量小于1024)。所以此时新容量变为10,切片会重新分配内存空间,将原来的5个元素复制到新的内存地址,然后再添加第6个元素。
- 如果旧容量大于等于1024,新容量会变为旧容量的1.25倍。
- 初始时,
- 对切片边界情况的影响:
- 当切片扩容重新分配内存时,其底层数组的地址发生改变。
- 由于Go语言中切片是基于底层数组的,切片的边界(长度和容量)也会相应改变。新的长度为原长度加1,新的容量根据上述规则计算。
- 若多个切片共享同一个底层数组,当其中一个切片扩容导致底层数组重新分配时,其他切片可能会受到影响,它们的内容可能不再是预期的。
- 潜在问题及避免方法:
- 潜在问题:
- 内存拷贝开销:扩容时需要将旧元素复制到新的内存空间,数据量较大时会有性能问题。
- 数据一致性问题:如果多个切片共享底层数组,扩容导致底层数组变化,可能破坏其他切片的数据一致性。
- 避免方法:
- 预分配容量:如果提前知道大概需要存储的元素数量,可以在创建切片时预分配足够的容量,减少扩容次数。例如,如果预计要存储100个元素,可以
slice1 := make([]int, 0, 100)
。 - 独立切片:尽量避免多个切片共享同一个底层数组,特别是在可能发生扩容的情况下。如果需要,可以通过
copy
函数创建一个新的独立切片。例如,slice2 := make([]int, len(slice1))
,然后copy(slice2, slice1)
。
- 预分配容量:如果提前知道大概需要存储的元素数量,可以在创建切片时预分配足够的容量,减少扩容次数。例如,如果预计要存储100个元素,可以
- 潜在问题: