hashmap是什么
- hashmap是map的实现类,
- 1、HashMap 在 Java 7 中使用的是 “数组 + 链表”,发生散列冲突的键值对会用头插法添加到单链表中;
- 2、HashMap 在 Java 8 中使用的是 “数组 + 链表 + 红黑树”,发生散列冲突的键值对会用尾插法添加到单链表中。如果链表的长度大于 8 会将链表树化为红黑树。
下标怎么计算
将key通过特定的hash算法进行取余,按照数组的长度-1来取余,这样这个数就永远比数组小,这样就不会越界
使用hashmap应该注意什么
- hashmap不能用于多线程,因为没有线程锁保护,
- 数组默认初始化是16,假如已经确认了只存两个数据,那就没必要默认16了,改成2即可,初始化大小为2
- 检查hashmap的类型key是integer类型还是对象类型,如果是对象类型就需要查看业务对象里的属性
是否都需要算hash,如果不需要的话记得重写hashcode和equals(根据业务需求判断是否需要重写hashcode和equals)
- 不能多线程put,但是可以多线程get,写不能用多线程,读可以随便用多线程
为什么用数组和链表
集合了数组的优点和链表的优点,数组在查询的时候比链表快,链表在插入的时候速度快(修改上一个数和下一个数的指向即可)
为什么数组比链表快
因为数组没有寻址操作,数组在内存中的排列方式是连续的
而链表存的是下一个数据的内存地址,他存的是一个指针,他要去找下一个数据的话需要去寻址,去根据内存地址去找在哪一块
map和hashmap有什么区别
这两个写法有什么区别
- hashmap类型调用的是hashmap类,在hashmap里重写的方法这个map可以调用到
- map类型是调用的map接口,接口里只有固定的方法,所以map1只能调用map固定的几个方法
key如果是list类型,那怎么求hash
在hashmap的源码中,key和val是泛型,意思是所有类型,不管key是什么只要是class定义的都有hashcode方法,
如果让11,22和22,11是相等的,让你做你会怎么来做
答:排序,先排序,如果这两个结果都是一样的,那肯定是一样的
redis
redis常用的数据结构
string,hash,list,set,SorteSet,Geospatial,BloomFilter(布隆过滤器)
Geospatial:后来新加的,地理位置的缩写,可以表示一个区域的二维坐标,常用在地图等软件用来计算距离最近的门店
BloomFilter(布隆过滤器):支持海量数据场景下,判断元素是否存在
缓存雪崩和缓存穿透
- 雪崩:多个key同一时刻,同时失效
(假如有1w个key同时失效,那这1w个数据量会打到数据库,数据库撑不住,这就是雪崩)
- 穿透:如果id都是数字,但是传进来的都是字母,这样永远不能命中缓存,相当于传过去了,很容易被黑客利用,
怎么解决雪崩和穿透
- 雪崩在架构层面避免,redis不让他同时失效,失效10%是可以接受的,让他10%的用户可以访问,需要架构层面做好规划,每个key在什么时候过期,过期时长是多少做好规划(架构层面解决,做好合理的规划时间)
- 穿透:可以用BloomFiter布隆过滤器,海量数据下判断元素是否存在,在访问redis之前 先访问布隆过滤器,(布隆过滤器是将所有的key都存在里面),查看要访问的元素的key在布隆过滤器是否存在,如果不存在的话就将请求打回(说非法请求或参数有误)
redis分布式锁
redis是单线程,使用时先用setnx获取锁,获取时要注意锁的释放,因为获取锁的过程中服务可能宕机了,这个锁一直在这,就会形成死锁,所以最好设置一个过期时间,在设置的时间里,可能还没修改完这个锁就到期了,这个也有个实现,就是在redisson里通过看门狗机制给锁自动续期,在获取锁的过程中没有处理完这个数据,他就会延长这个时间,等修改完成之后在按照时间释放掉锁