Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

3Justice/hmdp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

9 Commits

Repository files navigation

黑马点评

学习记录

11.25

  1. 完成了项目的文件设置,以及前后端,数据库环境的配置
  2. redis的客户端jedis和pool的配置和使用,spring data redis的使用
  3. redis的自动和手动序列化和反序列化
  4. 实现手机号检验,登录检验功能,正则表达式,基于session
  5. 集群的session共享问题,利用redis解决
  6. 多个拦截器组合,刷新token的拦截所有请求,注册拦截指定操作,指定执行顺序

11.26

  1. 用redis实现商品商户缓存
  2. 缓存穿透:缓存空对象(可能短期不一致)、布隆过滤器(保证缓存和数据库至少有一个存在)
  3. 缓存雪崩:同一时段内大量的缓存key同时失效,或者redis服务宕机,导致大量请求到数据库
    解决方法:给不同的key的TTL添加随机值,利用redis集群提高可用性,多级缓存,降级限流
  4. 缓存击穿:热点key问题,高并发访问并且缓存重建业务较复杂的key失效,数据库收到巨大冲击
    解决方法:互斥锁,一致性,等待时间长;逻辑过期:创建新线程,旧线程无需等待,性能好,不保证一致性,额外内存
  5. 根据业务实现获取锁和解锁的代码,例如在redis中获取锁的代码是尝试赋值,解锁的代码是删除值
  6. 线程wait、sleep、join需要捕获InterruptedException e,抛出RuntimeException(e)
  7. 面向对象中,组合优于继承,多写一层组合属性
  8. 封装缓存模板
  9. 写一个处理查询的类,之中包含正常查询和解决缓存击穿、穿透问题的查询,再封装处理各种事件的模板
  10. 优惠券功能,全局id生成器,自增id有规律性太明显,受单表数据量限制等问题
    解决方法:在分布式系统下用来生成全局唯一id,高可用,高性能,安全性。利用自增和拼接,1位符号位,31位时间戳,32位序列号
    场景题:如果订单量太大,每天的订单继续拼接一个当天的日期字符串,保证数据容量足够; 把时间戳和序列号结合成最终的数字:利用位运算
    全局唯一id生成策略:UUID,redis自增,雪花算法;redis:每天一个时间戳,时间戳+序列号
  11. 优惠券业务:先判断时间和库存的合理性,再扣减库存,写入数据库
    额外问题:超卖问题, 加锁,悲观锁即每次数据操作都加锁,乐观锁只有更新时才判断数据是否被修改过
    实现乐观锁:版本号法,数据修改之前先判断版本号是否相等,数据修改之后修改版本号
    CAS法:用原变量代替版本,先比较是否变化再去修改数据,具体的判断条件需要根据业务确定
  12. 一人一单,创建订单前先根据用户id和优惠券id查询是否已经买过,但是多线程还是会出现问题
    此时需要用悲观锁来执行,单独对用户id加锁,注意锁要放在事务外面,否则会因为事务没提交导致错误
    在其他类内部调用方法时,需要加上AopContext.currentProxy()获取代理对象来实现增强,比如事务。需要添加依赖和注解
  13. 集群模式下由于多个JVM中的多个锁,仍然会导致线程出现问题,无法互斥

11.27

  1. 在集群模式下,需要利用锁监视器;分布式锁,满足分布式系统或集群模式下多进程可见并且互斥的锁
    常用实现方式:mysql(本身的互斥锁),redis(setnx),zookeeper(节点的唯一性和有序性)
  2. Redis的实现方式,获取锁:set lock thread1 NX EX TIME,释放锁:DEL KEY
  3. 包装类型到基本类型的类型互换,需要做一个自动拆箱,可能会出错,需要用equals方法来判断是否相等
  4. redis锁的极端情况,业务出现阻塞,锁超时释放,被其他线程占有,但是业务完成时会误删其他线程的锁
    解决方法:获取锁时存入线程标识(UUID),释放锁时先获取锁中的线程标识,判断与当前线程是否一致,一致再释放
    还需要满足判断和释放锁两个操作是原子性的,Lua脚本实现,在脚本中编写多条redis,一次性实现
    需要新建一个redis脚本对象,设置脚本的位置和返回的数据类型,再把redis的操作改为执行脚本
  5. 利用setnx的问题,不可重入:同一个线程无法多次获取同一把锁;不可重试:获取锁失败一次就不可重试
    超时释放:如果业务执行耗时太长,导致安全隐患;主从一致性:
  6. Redisson,分布式锁的框架,引入依赖,配置客户端,设置ip和密码,直接使用
  7. Redisson可重入锁,设置一个锁计数器,如果重入,计数器加一,业务结束计数器减一,计数器不为0时重置锁的有效期,继续执行业务
  8. 分布式锁优化,可重入锁,用hash结构记录线程id和重入次数,可重试锁,利用信号量和pubsub实现等待,唤醒的重试机制
    超时续约:利用watchdog,每隔一段时间,重置超时时间
  9. 分布式锁主从一致性问题:把原来的主从关系都变成独立的节点,再在其中设置主从关系;创建联锁
    Redisson的multiLock,多个独立的redis节点,必须所有节点都获取重入锁,才算成功
  10. 秒杀步骤:判断购买资格(时间,库存),扣减库存(互斥锁),创建订单(互斥锁);优化思想:把读操作和写操作分离
    把读操作的数据缓存到redis,优化时间,新建线程完成写操作
    库存用string缓存库存,一人一单用set缓存用户id,如果抢购成功,将信息放进阻塞队列,创建订单用异步操作完成,用一个线程池执行阻塞队列的任务
  11. redis基于list结构模拟消息队列,双向队列实现消息进出,优点:使用另外的内存,不受JVM内存上限,数据持久化保证数据安全,消息有序性。 缺点:无法比卖你消息丢失,只支持单消费者
  12. redis基于PubSub的消息队列,发布订阅,可支持多个消费者;优点:支持多生产多消费;缺点:不支持数据持久化,无法避免消息丢失,消息堆积有上限,超出时数据丢失
  13. redis基于Stream的消息队列,优点:消息可回溯,一个消息可以被多个消费者读取,可以阻塞读取;缺点:会消息漏读
  14. 基于Stream的消息队列-消费者组,将多个消费者划分到一个组中,监听同一个队列;
    优点:消息分流,加速处理,消息标示,确保不漏消息,消息确认,处理完成后发送ACK确认,至少被消费一次
  15. 基于Stream的消息队列实现异步秒杀,将信息加入消息队列,用一个线程来执行
  16. 点赞功能,点赞的数量存储在数据库,点赞的人员名单存储在redis缓存set,保证一人只能点赞一次;
    点赞排行榜,实现展现最先点赞的前几名,利用redis消息队列
  17. 关注取关功能,数据库保存一个状态即可。共同关注功能,需要先把关注放到set中,用redis的set数据结构的求交集功能
  18. 关注推送,feed流,内容匹配用户;TimeLine模式:不做内容筛选,按照时间排序,内容多,有噪音;智能排序模式:根据兴趣推送
    feed流实现方案:拉模式(读扩散),推模式(写扩散),推拉模式,生产消息之后直接推送给消费者。
  19. 关注推送功能,基于redis的list消息队列实现
  20. 滚动分页查询功能,利用redis的查询功能,指定上一次的最小时间戳和偏移量
  21. 附近商户功能,GEO数据结构,存储地理坐标,可以自动实现半径内的范围查询
  22. 用户签到,BitMap数据,二进制字符串实现统计一个月每天的签到情况
  23. 统计签到情况,连续签到天数:从最后一次签到开始往前找第一个未签到的数量;所有签到数:统计所有区域;从后往前遍历每一个:与1做与运算,能得到最后一个bit位;
  24. UV统计,独立访客量;PV统计,页面访问量;HyperLogLog概率算法,基于String,错误率极低,用于统计大量的数据

About

黑马点评完整学习记录

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

AltStyle によって変換されたページ (->オリジナル) /