相关面试题
- map的底层实现原理
- 为什么遍历map是无序的?
- 如何实现有序遍历map?
- 为什么Go map是非线程安全的?
- 线程安全的map如何实现?
- Go sync.map 和原生 map 谁的性能好,为什么?
- 为什么 Go map 的负载因子是 6.5?
- map扩容策略是什么?
1、map默认是并发不安全的,原因如下:
Go 官方团队在经过了长时间的讨论后,认为 Go map 更应适配典型使用场景(不需要从多个 goroutine 中进行安全访问),而不是为了小部分情况(并发访问),导致大部分程序付出加锁代价(性能),所以决定了不支持并发安全。
2、如果想实现map线程安全,有两种方式:
mapsync.RWMutex
sync.Map
sync.Map是用读写分离实现的,其思想是空间换时间。和map+RWLock的实现方式相比,它做了一些优化:可以无锁访问read map,而且会优先操作read map,倘若只操作read map就可以满足要求(增删改查遍历),那就不用去操作write map(它的读写都要加锁),所以在某些特定场景中它发生锁竞争的频率会远远小于map+RWLock的实现方式。
总结
- map是引用类型
- map遍历是无序的
- map是非线程安全的
- map的哈希冲突解决方式是链表法
- map的扩容不是一定会新增空间,也有可能是只是做了内存整理
- map的迁移是逐步进行的,在每次赋值时,会做至少一次迁移工作
- map中删除key,有可能导致出现很多空的kv,这会导致迁移操作,如果可以避免,尽量避免