面试题答案
一键面试扩容策略分析
- 源码位置:在Go语言的
src/runtime/slice.go
源码文件中定义了切片的相关操作。对于append
操作引发的扩容逻辑在growslice
函数中。 - 扩容规则:
- 当原切片的容量小于1024时,如果新的元素个数超过原容量的一倍,则新容量变为原容量的2倍。例如,原容量为10,长度为5,当追加元素使得长度超过10(原容量的一倍)时,新容量变为20。
- 当原切片的容量大于等于1024时,新容量会变为原容量的1.25倍。比如原容量为1024,新容量变为1024 * 1.25 = 1280。
- 此外,新容量还需要保证能够容纳新的元素,即新容量要大于等于所需的元素个数。
对性能的影响
- 优点:
- 空间利用率较高:在容量较小时翻倍增长,在容量较大时按1.25倍增长,这样既避免了频繁扩容(如果每次只增加少量容量,会导致频繁内存分配和数据复制),又不会一次性分配过多内存造成浪费。例如在数据量增长较小时,翻倍扩容能快速满足需求且不会分配过多冗余空间。
- 减少内存碎片:相对较大的扩容步长,减少了频繁小内存块分配和释放产生的内存碎片,提升了内存管理效率。
- 缺点:
- 可能造成内存浪费:扩容时可能会分配比实际需求更多的内存,尤其是在数据增长较为平缓的情况下。例如,数据只是缓慢增长,但是按照翻倍或者1.25倍扩容,会有一部分内存暂时闲置。
- 数据复制开销:扩容时需要将原切片的数据复制到新的内存空间,当数据量较大时,这个复制操作会带来一定的性能开销,影响程序的运行效率。