学习仿牛客网社区项目

代码&资源

各章节总结
第一章
第二章
第三章
第四章
第五章
第六章
第七章
第八章

争取让每个知识点都有链接可点

项目总结

在这里插入图片描述

Spring Boot:降低项目核心组件开发难度

Spring:核心技术

其他组件:

  • Spring Email:发邮件
  • Interceptor:拦截器,拦截请求
  • Advice:通知,用于统一记录日志,结合AOP来看
  • AOP:面向切面,主要用于记录业务层日志
  • Transaction:事务模块
  • Redis:提供高性能存储的k-v数据库,五种数据结构
  • MyBatis:一种持久层框架,与数据库交互
  • Kafka:生产者消费者模式,处理系统通知
  • Elasticsearch:一种搜索引擎,以索引方式存储数据
  • Quartz:进行任务调度
  • Caffeine:管理本地缓存

网站架构图

在这里插入图片描述

  • 客户端:浏览器或APP

  • Nginx:对服务器做反向代理,多个服务器时可负载均衡

  • CDN:第三方缓存服务器,部署在各地,提高性能

  • Server:本地服务器

  • DB:数据库,读写分离

  • Redis:实现二级缓存,先访问本地缓存,没有的话访问Redis,还没有访问DB

  • Kafka:消息队列,控制生产者消费者速率

  • Elasticsearch:搜索引擎

  • 文件:文件服务器

HR关注的问题:性能、可靠性、安全性

研究透一个 比 明白两个 更好

常见面试题

MySQL

  1. 存储引擎

    • InnoDB:支持事务
  2. 事务

    • 事务的特性:原子性、一致性、隔离性、持久性
    • 事务的隔离性
      • 并发异常:第一类丢失更新、第二类丢失更新、脏读、不可重复读、幻读
      • 隔离级别:Read Uncommitted、 Read Committed、 Repeatable Read、 Serializable
    • Spring事务管理
      • 声明式事务
      • 编程式事务
    • 范围

      • 表级锁:开销小、加锁快,发生锁冲突的概率高、并发度低,不会出现死锁。
      • 行级锁(InnoDB):开销大、加锁慢,发生锁冲突的概率低、并发度高,会出现死锁。
    • 类型

      • 共享锁(S):行级,读取一行

      • 排他锁(X):行级,更新一行

      • 意向共享锁(IS):表级,准备加共享锁

      • 意向排他锁(IX):表级,准备加排他锁

在这里插入图片描述

 - 间隙锁(NK):行级,使用范围条件时,对此时范围内不存在的记录加锁。一是为了防止幻读,二是为了满足恢复和复制的需要。
  • 加锁

    • 数据查询语句DQL(SELECT),操纵DML(INSECT,DELECT,UPDATE),定义DDL(CREATE),控制DCL(GRANT
    • 增加行级锁之前,自动加意向锁
    • 在执行DML之前,InnoDB自动加排他锁
    • 执行DQL,默认不加锁
  • 死锁

  • 场景描述

在这里插入图片描述

此种情况若事务1执行一半,同时事务2执行一半,二者分别对ID=1和ID=2的数据加了X锁,导致后面的命令无法执行,陷入死循环。

  • 解决方案
    InnoDB自动检测这种情况,将一个事务回滚,另一个事务继续执行;

    设置超时等待参数

  • 避免死锁

    首先,当不同的业务访问多个表时,约定相同的顺序访问这些表;

    之后,当访问批量数据时,约定线程以相同的顺序访问数据;

    如果要更新记录,应直接申请X锁,而不是S锁再转换X锁。

  1. 索引

    • B+Tree
      • 数据分块存储,每一块称为一页;
      • 所有的值都是按顺序存储的,并且每一个叶子到根的距离相同;
      • 非叶节点存储数据的边界,叶子节点存储指向数据行的指针;
      • 通过边界缩小查找的范围,从而避免全局扫描,加快查找速度。

Redis

  1. 数据类型

在这里插入图片描述

值有七种数据类型

  1. 过期策略

    • 将过期的key放在一个独立的字典里,不会立刻删除。因为每一个key都删除效率太低。
    • 惰性删除:当客户端访问key时,检查是否过期,过期则删除;
    • 定期扫描:默认每秒扫描10次。
      • 先从字典中随机选择20个key;
      • 删除其中过期的key;
      • 若删除的比例超过25%,则重新执行一轮
  2. 淘汰策略

    • 当内存超出最大限制时,需要淘汰一些数据腾出空间
    • 两种主流策略:淘汰剩余寿命(TTL)最短的;淘汰访问次数最少的(近似LRU算法)
    • 近似LRU算法:每个key维护一个时间戳,淘汰时随机选择5个key,淘汰最旧的key。如果还超,就继续淘汰。
  3. 缓存穿透

    • 查询根本不存在的数据,缓存里肯定没有,只能提交给数据库查询。这种请求一多,数据库负载过大就崩了。
    • 解决方案:
      • 在数据库未查询到,给客户端返回空值的同时,将空值存入缓存。下次访问直接返回空。
      • 在缓存层之前设置布隆过滤器,将所有key存入,若请求无效的key,直接过滤。
  4. 缓存击穿

    • 访问量很大的数据,在缓存失效瞬间,大量请求涌入存储层。
    • 解决方案:
      • 在一个线程访问时加互斥锁,其他线程等待。访问结束,缓存中已有数据,其他线程访问缓存即可。
      • 设置永不过期,物理上
      • 设置逻辑过期时间,当发现一个value逻辑过期,使用一个单独的线程重建缓存,逻辑上
  5. 缓存雪崩

    • 缓存击穿的升级版。有大量的热门缓存,同时失效。或缓存服务器宕机。
    • 解决方案:
      • 避免同时过期,附加一个随机数
      • 构建高可用的Redis缓存
      • 构建多级缓存,本地缓存
      • 启用限流和降级措施,对数据库限流,服务降级
  6. 分布式锁

    • 分布式部署中,经常将数据读到内存,修改后返回给数据库。但这一操作可能被多个进程同时进行,读和写不是原子操作,需要加锁
    • 基本原理:
      • 同步锁:在多个线程都能访问到的地方,做一个标记,标记该数据的访问权限
      • 分布式锁:在多个进程都能访问到的地方,做一个标记,标记该数据的访问权限
    • 实现方式:
      • 基于数据库实现分布式锁
      • 基于Redis实现分布式锁
      • 基于Zookeeper实现分布式锁
    • Redis实现锁的原则
      • 独享。在任一时刻,只有一个客户端持有锁
      • 无死锁。即使持有锁的客户端崩溃或网络被分裂,锁依然可以被获取
      • 容错。只要Redis大部分节点活着,客户端就可以获取和释放锁

Spring

  1. Spring IoC

在这里插入图片描述

  1. Spring AOP
    在这里插入图片描述

  2. Spring MVC

在这里插入图片描述

  • 调度顺序:
    • 客户端发送请求给调度程序(DispatcherServlet)
    • DS调度HandlerMapping组件,HM将Adapter返回给DS
    • HM调用HandlerAdapter组件,获取其中的Controller,将模型数据和视图返回给DS
    • DS调用视图解析器(ViewResolver),将ModelAndView发给它
    • VR根据此找到对应的模板引擎,由模板引擎做为客户端做渲染
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐