很多场景下我们都会用到数据结构map来存储数据。map有两种,有序的和无序的。我们在使用时要根据我们的场景来选用,比如交易所的订单的存储,因为需要根据提交时间和价格来撮合,就需要用有序的来存储。
1、无序的map就是hash map
2、有序的map一般用红黑树来实现
golang内置的map就是hash map,如果你需要有序的话参考红黑树实现的map treemap。
是否只有内建类型来作为map的key的呢?虽然我们一直这么做,什么类型可以作为key。
1、数据类型可以比较
2、数据类型是静态的,可以被求值
bool、整数、浮点数、复数、字符串、指针、Channel、接口都是可比较的,包含可比较元素的 struct 和数组也是可比较的,slice、map、函数值都是不可比较的。
使用map时都会犯的两个错误。
1、使用未初始化的map
2、panic,程序运行时会有检查,运行时检测到程序在并发读写触发会panic
map是线程不安全的,如果在并发环境中使用,需要加锁。
1、RWMutex 官方实例
2、高效锁,减少锁的粒度和锁的时间,将map数据分片,将一把锁分成几把锁,每个锁控制一个分片 分片锁
3、内置的线程安全map sync.map
sync.map 实现:
空间换时间。通过冗余的两个数据结构(只读的 read 字段、可写的 dirty),来减少加锁对性能的影响。对只读字段(read)的操作不需要加锁
字段的更新和删除都会先读取read字段的数据,如果read字段存在此不用加锁直接更新,如果不存在需要查看dirity,不存在需要插入值,需要加锁影响并发