想做乐观锁 level
获赞
17
粉丝
9
关注
7
看过 TA
259
门头沟学院
2027
Java
IP属地:山东
且视他人之疑目如盏盏鬼火,大胆地去走你的夜路。
私信
关注
08-16 22:28
门头沟学院 Java
put添加元素的流程1 首先会去借助哈希值计算桶索引的值,运算函数为(n-1)&hash值进行与计算。:计算哈希值,jdk7之前是直接引用哈希值计算,而jdk8开始则借助哈希扰动的算法,原理呢就是将原哈希值向右移动16位,异或运算哈希值,将高位哈希值与地位哈希值都可以很好的参与到计算当中,减少哈希冲突的概率2 判断该桶索引位置是否为空,如果为空直接进行存放Node节点。如果不为空,需要遍历链表或者红黑树,去判断是否存在相同的key,如果不同则插入,相同则覆盖。:8开始为尾插,8之前为头插(多线程扩容可能会导致链表出现死循环的问题)插入新节点后3对数组的元素进行计数,当数组当中的元素数量大于负载因子与容量的乘积时,会触发扩容机制,两倍的扩容速度,扩容过程当中存在对元素桶索引的重新分配问题:在jdk7之前会使用(2n-1)&hash重新算一遍桶索引的位置(n为原数组长度):但是在jdk8开始,将(2n-1)&hash进行拆分,拆成(n-1)&hash+n&hash=原索引位置+n&hash,在判断过程当中呢,实现对n&hash的计算即可,判断计算是否为零,为零则保留原索引,不为零则在原索引的基础之上加上旧数组长度,接着移动就简单了,将原先的链表拆分为两个临时链表,后续直接一次性挂载即可。4判断是否需要树化,先判断链表长度,在链表长度达到8的条件下,判断数组长度是否达到64,达到就将链表树化,没达到64就以2倍的速度进行扩容。
如果再来一次,你还会选择...
0 点赞 评论 收藏
分享
08-15 22:06
门头沟学院 Java
查看18道真题和解析
0 点赞 评论 收藏
分享
08-13 21:43
已编辑
门头沟学院 Java
但是被发现没有完整实现怎么办?大家 帮我看看。实现秒杀以及一人一单的策略:1:Redis层面的分布式锁首先将分布式锁的粒度降低,将用户Id与商品Id进行绑定,借助LUA脚本(原子性),先判断是否存在购买标识(幂等性1),没买过就去尝试获取分布式锁,获取成功之后然后再次判断是否存在购买标识,再判断库存是否足够,最后再扣减库存,两次判断减少锁竞争的消耗2:数据库层面的数据修改第一种:开启事务,对数据库的数据进行修改,扣减库存以及添加用户的购买记录,然后在Redis中添加唯一标识可以借助Set进行存储,也可以借助string进行存储。string结构可以实现更加精准的存储,可以存储相关的任务状态,比如已完成,未完成,完成中,同时还可以对过期时间进行单独指定,但是呢,当海量数据下会造成高频的内存碎片,与集群跨槽访问开销Set结构可以以更加高效的查询效率去实现检索判断,约为string的30%,但是呢,无法存储任务状态,存在大Key问题,以及对过期时间只能全局Set的设定无法单个元素的设定。第二种:RabbitMQ提高并发能力(幂等性,可靠性的保证)如果说需要想提高并发能力,可以借助RabbitMQ去异步将数据同步数据库,只在Redis去执行业务的决策,此时RabbitMQ当中只是去对数据进行修改,可以保证最终的一致性,无法保证全局的一致性。1 保证幂等性2,将用户id与商品id创建唯一索引或者唯一约束,避免重复消费添加,添加失败导致事务回退2 保证幂等性3,创建全局唯一Id,可以在Redis业务决策结束后生成,后续与用户id商品id一起传入RabbitMQ,当消息被消费者正常消费后,将唯一id存储到Set当中,消费者消费前对判断Set当中是否存在这个唯一标识id,存在代表以及消费过不存在则未消费过或者将这唯一id借助string类型进行存储,消费者消费前判断string是否可以获取成功,成功则代表已经消费过,不成功则未消费3:定时任务进行校验最后还可以借助xxl-job对Redis数据与数据库数据进行校验改进:1 Redis 持久化与高可用: 需要配置 RDB+AOF 和 Redis Sentinel/Cluster 防止数据丢失和服务中断。2 冷启动/预热: 秒杀开始前,需要将商品库存和必要信息加载到 Redis。
我的AI电子员工
0 点赞 评论 收藏
分享

创作者周榜

更多
关注他的用户也关注了:
牛客网
牛客网在线编程
牛客网题解
牛客企业服务