面试题答案
一键面试在Go语言中,从性能和资源利用角度考虑,当预估一个Map会存储1000个键值对时,建议将其初始容量设置为1250左右。
原因如下:
- 负载因子:Go语言的Map在负载因子达到6.5时会进行扩容。负载因子 = 元素数量 / 桶(bucket)数量。如果初始容量设置过小,随着元素的不断添加,Map很快就会达到负载因子的阈值从而触发扩容。扩容操作会涉及到内存的重新分配和数据的重新拷贝,这会带来较大的性能开销。
- 空间占用:如果初始容量设置过大,虽然减少了扩容次数,但会造成额外的内存浪费。因为在初始化Map时,会根据容量分配一定数量的桶。当元素数量远小于桶的数量时,就会造成空间的浪费。
为了避免频繁扩容并减少不必要的空间浪费,按照负载因子6.5来计算,要存储1000个键值对,需要的桶数量约为1000 / 6.5 ≈ 153.85。由于Go语言中Map的容量必须是2的幂次方,向上取最接近的2的幂次方值为256。但考虑到实际情况,一般会在计算值的基础上适当增加一些冗余,设置为1250左右较为合适。这样既不会因容量过小频繁扩容,也不会因容量过大浪费过多内存。
示例代码如下:
package main
import "fmt"
func main() {
// 初始容量设置为1250
myMap := make(map[string]int, 1250)
for i := 0; i < 1000; i++ {
key := fmt.Sprintf("key%d", i)
myMap[key] = i
}
fmt.Println(len(myMap))
}