..

go map 为什么这么设计?

go map for 循环为什么是无序的?

下面的示例代码,每次输出的结果大概率是不一样的。

func TestDemo(t *testing.T) {

	m := make(map[int32]string)
	m[0] = "a"
	m[1] = "b"
	m[2] = "c"
	m[3] = "d"
	m[4] = "e"

	for k, v := range m {
		fmt.Printf("K: %d, V: %s \n", k, v)
	}
}

博主不会告诉你的是,这里面深层次的原因是:Hyrum’s Law 海勒姆定律。 给大忙人的一句话概括解释是:你暴露什么API无所谓,只要你的实现是可探查的,别人就会依赖你实现而不是接口 这里map的语义就是无序的 但是之前的版本在某些情况下 map是有序的,开发人员就会依赖这个,面试官就会考这个,为了打破这一点,map在实现的时候,通过随机起始key,来达到无序。

go map bucket桶的size为什么是8?

golang 中的 map 底层实现由 hmap,维护着若干个 bucket 数组,通常每个 bucket 保存着 8 组 kv 对,如果超过 8 个 (发生 hash 冲突时),会在 extra 字段结构体中的 overflow ,使用链地址法一直扩展下去。 这个和java hashmap linkarray超过8个会树化的原因是一样的。 可以参考java hashmap的注释。 https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/util/HashMap.java 从中可以看到这里深层次的原因是:泊松分布。 我粗浅的理解:这是一个统计学上的概念,也就是说大多数情况hash 冲突超过8次的概率很低了。当然在go里面是key的前8个bits冲突 java hashmap中给出的数据

     * 0:    0.60653066
     * 1:    0.30326533
     * 2:    0.07581633
     * 3:    0.01263606
     * 4:    0.00157952
     * 5:    0.00015795
     * 6:    0.00001316
     * 7:    0.00000094
     * 8:    0.00000006

Creative Commons License