6-1 HashMap和CurrentHashMap的区别是什么?
HashMap和ConcurrentHashMap都是Java中常用的哈希表实现,它们之间有几个主要的区别。
线程安全性:HashMap是非线程安全的,而ConcurrentHashMap是线程安全的。在多线程环境下,如果多个线程同时对HashMap进行修改,可能导致数据不一致的问题。而ConcurrentHashMap通过一些线程安全的机制来保证多线程并发修改时的数据一致性。
性能:在多线程环境中,ConcurrentHashMap的性能通常比HashMap更好,因为它允许多个线程同时读取和修改Map而不需要额外的同步操作。
迭代器的一致性:在HashMap的迭代过程中,如果其他线程对HashMap进行了修改,可能会导致ConcurrentModificationException异常。而ConcurrentHashMap在迭代过程中,不会抛出该异常,它采用了一种弱一致性的迭代器策略,可以保证迭代器能够遍历到一开始的快照信息,但可能会遗漏一些修改后的元素。
综上所述,HashMap适用于单线程环境下,不需要考虑并发安全性的场景,而ConcurrentHashMap适用于多线程环境下需要进行并发安全操作的场景
6-2CurrentHashMap底层结构在1.7和1.8有什么不同?
在1.7和1.8版本中,ConcurrentHashMap的底层结构有较大的改变。
1.7版本采用了分段锁(Segment)的设计,将整个数据结构分成多个小的Segment,每个Segment拥有自己的锁。
1.8版本中,采用了更加高效的无锁算法,并引入了更细粒度的锁机制,利用CAS操作来实现并发安全性,从而提高了并发性能。
6-3 假设你有一批历史积分数据要存储,数量在kw条左右 存入mysql 你的方案是什么
对于数据库的海量储存,我们的方案其实有很多,常见的有:分区,分表,分库,和搭建集群
我们可以采用分表和分库的方式来完成数据库的海量储存。
我们可以使用水平分表来对数据进行拆分,根据数据量的大小和查询模式,来进行分表,也可以按照时间范围进行分表,比如按年份或月份进行分表,以减少单表数据量。
分库是指将一个大型数据库中的数据按照一定的规则分散存储到多个独立的数据库实例中的过程。通过将数据分散存储到多个数据库实例中,可以分担单一数据库实例的负载压力,提高系统的并发处理能力和数据访问速度。
以上就是我的解决方案了
6-4 请你说一说你的排行榜功能是如何实现的
在我的项目中排行榜又分为,实时榜单,和历史榜单,这些都是基于客户积分实现排名的。
由于实时榜单的查询量是非常大的,我们把数据保存到了Redis中去,使用了Redis中的ZSet结构因为,ZSet中多了一个权重参数score,元素会按照score来进行排序,非常适用与排行榜
而历史排行榜他的访问量并不是很高,但是数据量还是很大,我们选择把他存入到Mysql中保存,但是为了防止单表数据量过多,我们选择使用了分表的方案,把一个赛季放到一张表里,这样的话我们就可以根据key查询一张表即可,
以上就是排行榜功能的实现,
6-5 历史赛季积分是如何生成的
历史赛季的积分生成主要分为三个核心步骤,主要就是把我们Redis中的数据来保存到Mysql数据库中去
- 创建一张历史赛季表,用来存储Redis中的数据。
- 从Redis中将数据保存到Mysql中对应的赛季表,实现榜单的数据持久化。
- 删除Redis中历史赛季的数据。
由于这三个操作不适合人为经常操作。我们把上面三个任务应该设置为定时任务,我们使用xxl-job来进行定时操作,并且还要把这三个给配置了任务调度为(任务链)的形式,确保他们从上往下依次执行