黑马点评大总结

8.2.1 短信登录

  • 首先是用户提交手机号,后端将生成的验证码以及用户信息存入session中,用户登录时进行拦截并从session中拿出来信息校验,并把用户信息存入ThreadLocal中
  • session共享问题:每个tomcat有自己的一份session,分布式、微服务下有多个tomcat实例,之间的session无法共享
  • 解决: 负载均衡器通过特定算法如IP哈西,保证同一用户的请求始终路由到同一服务器。(失去负载均衡的灵活性)session复制,所有服务器同步session变更。(带宽消耗大)集中存储,将会话数据存储在外部,如redis客户端存储。(安全性挑战)
  • 采用后端生成token存入redis,前端请求头携带token校验身份 方案,并通过两层拦截器解决token刷新TTL问题(背景是有些页面不要求登录即可访问),先拦截所有请求判断token有无,有则刷新并存信息与ThreadLocal,后拦截特殊路径判断是否登录(ThreadLocal中是否有用户信息),有则放行,无则拦截显示请登录 8.2.2 商户缓存
  • 查询逻辑:先查询缓存再查询数据库再写入缓存(背景:老查询数据库,压力很大)
  • 缓存更新策略有内存淘汰、超时剔除、主动更新
  • 缓存双写一致性问题:数据源来自于数据库,数据库发生变化时也要更新缓存
  • 采用先更新数据库再删除缓存的方案,但仍有问题:多线程环境下可能出现缓存正好过期去查询数据库得到旧值,更新操作完成并删除缓存(空缓存)然后旧值被写入(极小概率)
  • 解决: 设置较短的TTL,减少缓存与数据库不一致的时间窗口将策略改为 延迟双删策略
  • 引入缓存提高查询性能,必然会引出一系列问题,上面的缓存双写一致性问题为其一,其二就是缓存穿透问题,若查询本就不存在的数据,每次都会打到数据库上,增加压力
  • 解决: 缓存特殊值:查询数据库后返回特定值比如defaultNull并设置ttl写入缓存,所有命中缓存后增加判断value值一逻辑操作。问题:只能应对正常业务问题,不能应对黑客使用大量不同的key进行攻击问题(还是会全部打到数据库上)布隆过滤器:本质是BitMap+多个Hash函数,将所有有效key存入bitmap,挡在redis前多一次判断。问题:由于其特性(hash冲突问题)导致存在误判(有的不一定有,但无的一定没有)
  • 当大量缓存key同时失效或者redis突然宕机就,导致大量请求打到数据库,造成缓存雪崩
  • 解决: 给不同的Key的TTL添加随机值利用redis集群提高服务的可用性给缓存业务添加降级限流策略给业务添加多级缓存
  • 当一个高并发访问的key突然失效(热门商户),无数的请求打到数据库,造成了缓存击穿问题
  • 解决: 加互斥锁:缓存未命中则加分布式锁(set nx ex)如果失败则进行方法休眠+递归重试,成功则去查询数据库并写入缓存后释放锁。问题1:递归容易造成OOM,改为休眠+自旋重试。问题2:其他线程在重试,当缓存写好锁被释放后,又进行抢锁,改为双检加锁(在自旋过程中尝试去命中缓存),锁被释放后自旋的线程也无需在抢锁。缺点:死锁问题,且只能串行执行,性能受影响逻辑过期:缓存击穿问题主要是key的TTL到了,不设置TTL,而是吧TTL设置到value中,通过逻辑判断是否过期。重新封装一个类包含过期时间以及Object数据。判断过期后获取互斥锁(保证异步任务只提交一次),将查询数据库写入缓存的操作提交给异步线程处理(串行处理也可以)。返回过期数据。缺点:其他线程返回的是脏数据(已经过期的)总结:方案1是串行,执行加锁保证只有一个线程去查询数据库,方案2是异步执行,加锁保证查数据库写入缓存的操作只被执行一次,且先返回已经过期的数据问题:只要加分布式锁(set nx ex)就需要考虑业务未执行完锁超时过期问题,但此处业务是查询以及写入逻辑,即使锁过期导致其他线程获取锁进入逻辑,无非就是多了个线程执行缓存重建操作,但在删除锁时可能会出现张冠李戴的问题(DEL命令即使key不存在也会返回成功),无伤大雅。如果是扣减库存之类的操作就会出现超卖现象,是不允许的,需要增加watchdog。 8.2.3 优惠券秒杀
  • 全局唯一ID:规律性不能太明显,受单表数据量的限制。应当满足 唯一性、高可用、高性能、递增性、安全性。由符号位0+时间戳31bit+序列号32bit(秒内的计数器,支持每秒产生2^32个不同ID)
  • 下单业务逻辑:提交优惠券id - 查询信息 - 判断是否在活动期间 - 库存是否充足 - 扣减库存 - 创建订单
  • 超卖问题: 直接扣减库存在高并发情况下会导致超卖问题。解决:加悲观锁(太重);加乐观锁(CAS):执行sql时多一个库存容量判断是否大于0
  • 一人一单问题:在判断库存后增加 - 根据优惠券id+用户id判断是否已经下过单
  • 问题:多线程下(用户多次点击)可能同时判断出未下单,然后执行下单逻辑造成一人多单
  • 解决:加synchronized锁(判断是否已经购买+下单逻辑)保证只有一个线程执行下单逻辑,加到方法上,锁的粒度太粗,改为在代码块上加锁,用intern()方法从常量池中拿用户数据加锁,因为直接用userId的话不是同一个对象,每个线程都有自己的ThreadLocal,其中的用户信息对象是分别new的,不唯一。问题:方法被spring事务控制,如果在方法内部加锁,可能导致方法事务还没有提交,但是锁已经释放的问题(锁在方法结束时释放,但事务可能还未提交。其他线程可能读取到未提交的数据(脏读),或者覆盖未提交的修改。)
  • 通过加锁可以解决在单机情况下的一人一单安全问题,但是在集群模式(分布式)下还会有超卖问题(用户连多次点击被负载均衡到不同的服务上)
  • 解决:换用分布式锁,在判断完库存充足之后,执行逻辑前先创建锁key,这里以userId作为key(保证该用户的多次请求对应一个分布式锁)。加锁后通过代理对象执行接下来的方法(一人一单判断+扣减库存+创建订单),因为该方法加了@Transactional注解,一个非事务方法调用事务方法,事务不会生效。
  • 问题:若持有锁的线程在执行逻辑时阻塞了,导致锁超时提前释放,这时候其他线程(该用户的相同请求)就会持有锁执行后面逻辑,可能造成超卖问题。(也会出现误删问题,但不是本质问题,重点还是逻辑被执行了多次)
  • 解决:(锁误删解决,属于辅助方案),在获取锁时UUID+ThreadID作为value,在unlock()的时候判断value值是否为自己的锁。问题:unlock的逻辑不是原子的,极端情况下还是会出现误删情况,使用Lua脚本保证逻辑的原子性。(注意:解决误删问题并不能解决超卖问题,这个方案解决的是次要问题-误删锁,属于辅助手段,要想解决这里的超时释放问题得用watchdog机制)
  • 当下分布式锁:需要给锁续期解决超时释放问题,锁不可重入,主从一致性
  • 解决:Redisson中的RedLock 可重入原理:底层Hash结构+Lua脚本实现,大key标识锁是否存在,小key标识锁被那个线程持有重试原理:抢锁过程中,通过tryAcquire进行抢锁,先判锁是否存在,再判断是否属于当前线程watchdog原理:在获取锁后开启一个后台线程监控锁的ttl,超过三分之一后重置TTL 8.2.4 秒杀优化
  • 问题:当前逻辑全是串行执行
  • 解决:将部分逻辑单独提出来,异步执行,在判断用户可以下单后直接返回给用户成功,由后台完成剩下的下单操作,将判断逻辑放入redis中,库存是否足够、是否为一人一单,相应的信息存入redis中,判断后开启异步 queue 难点1:如何在reids中判断,将商品库存信息以及用户下单信息(set集合)提前存入,有库存以及set集合中没有该用户则说明可以下单。基于Lua脚本实现资格判断保证原子性,将订单id返回给前端难点2:如何知道最后下单是否成,将优惠券id和用户id封装后存入阻塞队列 开启独立线程不断从阻塞队列中获取信息实现异步下单逻辑
  • 问题:阻塞队列在JVM内存中,容易OOM;JVM挂了数据订单数据全没了
  • 解决:MQ 基于List的MQ:只支持单消费者,无法避免信息丢失(内存占用多时内存淘汰机制可能淘汰List中的数据,持久化没法保证数据100%持久),使用LPOP/RPOP命令消费消息后,消息立即从队列移除基于Stream的MQ:增加消费者组,生产可用 8.2.5 探店点赞
  • 对于其他用户发的博客可以进行点赞,开始逻辑为 直接数据库+1
  • 问题:用户可以无限点赞,应当为点赞/取消且点赞按钮高亮显示
  • 解决:增加isLike属性,标志是否被当前用户点赞;使用redis set集合判断是否点赞过,key为Blog,value为userId
  • 问题:检查Redis后到执行数据库更新之间存在时间窗口,可能导致多个请求同时通过检查,造成重复更新。
  • 点赞排行榜,显示出最早点赞的几名用户(如TOP5),有唯一性又具备有序性的 zset集合 以时间戳为score存入用户信息 8.2.6 好友关注
  • 一张tb_follow表标示关注信息,根据前端传来的id直接更新数据库保存关系信息
  • 增加共同关注功能需要求交集,利用set集合,存储用户的关注列表,userId作为key,然后用set集合的api求共同关注的用户id,关注则先存入数据库再更新redis,取关则先删除数据库再删除redis
  • 发动态时提醒粉丝,使用 Feed流 完成推送功能,采用TimeLine模式
  • 拉模式:查看时拉去所有Blog然后排序展示
  • 推模式:博主发送Blog时将信息推送给所有粉丝,就是我们在保存完探店笔记后,获得到当前博主的粉丝,然后把数据推送到粉丝的 redis 中去
  • 推拉结合:推送给活跃用户,普通用户拉取
  • 问题:因为数据是不断变化的,传统分页会导致展示重复的数据
  • 解决:Feed流的滚动分页 8.2.7 附近商户
  • redis使用GEO结构存储商家的经纬度以及店铺id,以店铺的typeId为key,将对应的商铺信息存入value 8.2.8 用户签到
  • 直接用数据表记录数据量太大
  • 解决:使用bitmap中的0,1来记录用户的签到情况
  • 吧年和月作为bitMap的key,每次签到把当天对应bitmap位置上的下标从0变为1
  • 获取某月的bitmap数据(十进制展示),与1进行与运算看看此位是否为1,从而进行签到统计(签到总数、连续签到)
全部评论
整体基本没有结构,我觉着一步一步思考是连贯的是没有太多结构的,总之挨着看下来肯定会有收获的
8 回复 分享
发布于 05-06 22:44 河南
可以很全
4 回复 分享
发布于 05-09 15:33 上海
3 回复 分享
发布于 05-06 14:31 广东
牛逼,辛苦了
2 回复 分享
发布于 05-22 00:21 吉林
谢谢佬
1 回复 分享
发布于 05-29 21:34 北京
m
1 回复 分享
发布于 05-29 17:06 江苏
mark学习
1 回复 分享
发布于 05-28 15:35 江西
请问记这些面试够了吗
1 回复 分享
发布于 05-16 17:15 美国
想问一下大家 本人力扣能力 自我感觉良好 项目经历很差 视频速过了黑马点评 而且面试的过程中 感觉面试官基本上都是出手撕 所以侥幸通过 hr电话口头offer 想问一下大家实习过程中 如果项目这些不懂 会被辞退嘛
1 回复 分享
发布于 05-10 15:02 江苏
mark
点赞 回复 分享
发布于 11-22 18:09 北京
mark学习
点赞 回复 分享
发布于 09-28 16:04 湖北
mark学习
点赞 回复 分享
发布于 09-06 12:45 江苏
mark学习
点赞 回复 分享
发布于 09-02 22:04 广东
mark
点赞 回复 分享
发布于 07-20 14:37 浙江
mark学习
点赞 回复 分享
发布于 07-13 16:00 江西
辛苦了!太厉害了
点赞 回复 分享
发布于 07-12 16:04 江苏
mark
点赞 回复 分享
发布于 07-03 14:24 湖北
mark
点赞 回复 分享
发布于 06-24 08:58 辽宁
mark学习
点赞 回复 分享
发布于 06-07 23:25 河北
接好运
点赞 回复 分享
发布于 06-02 13:42 河南

相关推荐

我其实不是一个有写日记习惯的人,正经人谁写日记啊,但是这一个月前前后后面了得有将近十场,感悟良多,也是从今年开始下定决心转码,感觉收获了不少,觉得有必要记录一下。OK让我们梳理一下我找工作的时间线,我的bg是2本9硕非科班理科相关,真正意义上的找工作开始是在保研完之后的那个12月份。2023.12这个时间点可以说是挺关键的,10月份刚保研完,11月份和几个一起保研的好朋友去重庆、青岛玩了很久,天天吃吃喝喝,12月突然一下子觉得没有事情干了。这时候的我手上捏了两篇已发表论文(主要贡献来自我室友),全是跟基础数学推导相关的,一篇二作一篇四作,还是花了点功夫的,这些成果让我收获了一等奖学金和科技奖学金,多么的意气风发。但这些成果也让我知道,我本身没啥数学天赋,我不喜欢搞基础数学,我也不喜欢推导公式,我想做点应用相关的。所以12月我主要做了两件事:①提前加入了毕设老师的课题组,方向是深度学习的卷积模型压缩。在课题组我也认识了不少师兄师姐,了解到了其中一个师姐找了大厂数据分析相关的岗位。②了解到具体的数分岗位,我也着手准备我的简历,妄图去大厂窥探一翻。这时候我都想笑那时候的自己,简历上写了自己的科研项目和数学建模比赛获奖,现在想来,这些东西大厂应该无hr在意吧。所以准备简历找工作的结果就是四处碰壁,boss上怎么也投了两三百份吧,真的是0约面。2024.033月份的时候,非正式的进了某家银行的分行体验一下(这个时候其实已经锚定了未来就是想进大厂或者去银行躺平),实则一个月只有500的餐补,干的也都是打杂的活。就干了一个月,说是实习其实更像去别的城市旅游体验。这段时间已经断了找大厂实习的念想,全力搞我的毕设。2024.06我对待毕设还算上心,指导老师也非常尊重我,也有一些师兄师姐的指导,做深度学习实验的经费也有的报销,还有每个月的劳务费(尽管我是本科生)。指导老师也找到我,希望我继续稍微完善一下毕设,做论文投出去。那时候的我已经开始畅想我的研究生生涯了,我或许天真的以为,导师都是这样的;我现在能发一篇论文(虽然可能只能发个C会),那我读研好好搞岂不是能发个A会B会(闹麻了),或许读研之后我可以走算法这条路?到了这个节点,我手上可以说捏了三篇论文,优秀毕业生也拿了,充满了对未来的期望,接着就好好享受我的毕业时光了。2024.10进入新的学校读研也有一个月了,10月也可以说是个转折点。这一个月的时光,让我对研究生生活和导师有了一定了解,毕竟我师兄师姐都很好,什么也都跟我谈了,没有拖着我浪费时间。①先说导师,只能说唉,唯一的好处可能就是不怎么来学校,让我有机会可以偷偷实习。其他的缺点,真的是什么都占了,跟我本科导师完全两个极端。有些骚操作大家甚至难以感同身受,我都觉得它是个伪人。②读研生涯绕不开研一的课程,有些人可能会说别学生思维了直接逃课呗。事实是你不逃老师都会挂你。有些理科专业的老师,我真的难以评价,似乎沉浸在自己的数学艺术里无法自拔了(就喜欢炫技,实则出了大学无人在意你捣鼓那坨构思数学公式),我们以后又不是都搞科研,能挂这么多人搞出上一届的教学事故也是没谁了。我举个例子,上一届师兄总评60多几乎拿了一等奖学金(前25%)。所以我还能怎样,老老实实学习呗。其实现在也想穿越回去给自己两个大耳瓜子,还是没有下定决心转码,那时候课余时间都用来打游戏了,没有学习计算机相关的知识。2025.05时间跳转到今年五月,终于甩掉了学校里这些构思课程。我继续开始修改简历准备投实习。这时候也挺天真的,因为本科毕设已经投出去了,我简历上就写了这个深度学习的项目和本科的科研项目。觉着靠这个深度学习的项目能找着一个数分实习。好在投了两三百份确实有约面的:①滴滴:投了数分实则约了数开的岗位,手撕甩了一道非hot100的,至今让我还有一些阴影。没过。②某知名德企:有点大病,因为之前有实习生没满6个月跑了,面试对我充满了猜忌,一直在问我能不能满6个月相关的问题。我真的很烦这种疑神疑鬼的女面试官。③科大讯飞:钱少,也不知道为啥没过一面。以上除了滴滴都没开摄像头,感觉像随便招个人进去当sqlboy,一点尊重都没有,我感觉数分这个岗位,真的或许不太适合我。这段时间还有值得一提的就是打开了黑马学完了sql相关的。2025.07在经历了上述三面之后,并且其实约面率太低了,了解到数分hc不多(本科两段大厂实习的师姐也没找到大厂正职工作),下定决心转开发了。7.16第一次打开了黑马开始学习java基础。2025.08学完Java基础在家玩了20天,又懈怠了2025.09学完了JavaWeb和Linux相关,黑马点评也开始进展了一半.2025.10国庆去川西玩了一周,回来继续学完了黑马点评,刷完了一遍hot100。八股简单过了一遍。这个时候已经蠢蠢欲动打算开始投简历了,不过简历上就一个黑马点评,投了半天后端依旧无人约面。这时候知道有两个师兄找到了后端的工作(不过他们研一就开始准备了),遂请他们吃了一顿饭,沟通的结果是,先学微服务,然后可以试着投投测开相关的岗位。2025.11黑马的天机学堂在10月底也是正式开源了,我干脆就照着这个学微服务了,也学了ES相关的基础,了解到了Nacos,Git怎么拉代码合并分支相关的知识,还算有点收获。最终简历是黑马点评+天机学堂。照道理来讲应该有后端约面了,事实结果是大部分的后端都懒得看我的简历一眼,我的学历和项目应该都差不多了,我不知道今年后端又卷到了什么新高度还是我单纯运气太差?听了学长的投了测开相关的岗位,只能说这个岗位缺口还是挺大的,猛猛约面(最起码积累了点实战经验了,也让我有了一点信心)。2025.11.24  度小满测开一面,场景题盛宴,初出茅庐丝毫不了解,输的很惨。2025.11.24 19:00  百度测开一面,常规八股,本来因为度小满都摆烂了没看hot100,但是测开手撕比较简单没想到硬撕撕出来了。进入二面2025.11.28 百度测开二面,常规八股,由于没有复习sql跟更新和删除相关的语句,算法因为不知道要导包(面试官也全程没开摄像头,一点提醒都无,后面发现这个问题还是别的面试官提醒我的)没运行出来,遂挂。2025.12.01  字节测开一面,纯kpi面。后面又陆陆续续面了两家的一二面(包括百度的另一个部门),到现在还在泡池子,都是测开,也不说挂了没,问就是还在横向对比。希望下周能接到一个好的结果。其实我现在也是测开和后端一起投,但是就是后端没得约面,测开猛猛约。腾讯投后端被客户端捞了,面完感觉现在自己八股还停留在一些表面,但是应付测开已经绰绰有余了。2025.12.21今天是冬至,面了这么多次,还得应付组里科研的压力,最近想了很多。我目前八股和项目笼统大概都能答上来,hot100和其他高频中等简单题已经没问题了,其他的还有待加强。场景题和项目了解的还不够深入,需要进一步深化。另外一个就是可能有人觉得我这学历去卷测开浪费了,其实几年前的风向不是9硕去卷后端都算浪费吗,其实我个人倒是无所谓的,我也没那么喜欢写代码,只是想找个吃饭的工作。但真的觉得这四五个月中,学习到了不少。我身边一直缺少这样志同道合的人,感觉一直都是自己在摸索,不断地碰壁再复盘,哪怕手撕要自己导包这事也是最近才醒悟过来,走了不少弯路。最后就这样吧,测开要我我也就去了,能去后端也行。实在找不到我就搞搞科研准备暑期了,主打一个随意摆烂。希望大家最后都能葡萄丰收。
求一个offer_T...:前辈一起加油,找工作好难
重来一次,你会对开始求职...
点赞 评论 收藏
分享
评论
151
865
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务