JAVA项目【仿牛客网面试总结】【分章节】

1

什么是Maven?

一个大型的 Web 项目,需要依赖很多第三方类库,不同 Jar 包之间还有复杂的依赖关系;这时,Maven 出现了,我们只需要告诉它需要的 Jar 包,它会帮我们自动下载并管理它们。
Maven就是这样一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。

Maven的核心思想?

约定大于配置。Maven会约定一些规则,不能违反,比如项目的目录结构。

Spring

什么是Spring?

Spring是一个轻量级的容器(框架),如果加上定语:
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。

Spring全家桶的组成?

Spring Framework:Spring的核心;
Spring Boot:构建项目,可以用它快速开发单个微服务;
Spring Cloud:协调微服务,可以将一个大项目拆分成多个小项目分而治之;
Spring Cloud Data Flow:连接数据源,集成多个平台数据。
再深入到Spring Framework

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LQbN1ZYO-1685417610806)(C:\Users\DoubleC\Desktop\小白要找工作\images\image-20230530090328053.png)]

Spring由二十多个小模块组成,下面只列举这个项目中用到的技术栈。

  • Core Container(核心容器)
    • 控制反转(IoC)
  • Data Access(数据访问)
    • Spring MyBatis
  • Web(Web开发)
    • Spring MVC
  • Data Integration(数据集成)
    • Email:发邮件
    • Scheduling:定时任务
    • AMQP:消息队列
    • Security:安全控制

什么是IoC?

控制反转(IoC)是一种管理对象 Bean 的设计思想,它将手动创建 Bean 对象的权力交给 Spring 框架。这样我们在创建对象时就只需要添加相应的注解或配置文件,而不用考虑如何创建它。
它的优点:降低耦合,我们在将Bean对象交给容器管理时,需要对象的定义和配置文件,各对象之间的关系在配置文件中声明,不会直接产生耦合。
依赖注入(DI):是IoC的实现方式;
IoC容器(IoC Container):是依赖注入的关键。本质上是一个工厂,数据结构是Map。

IoC 容器控制了对象,主要控制了外部资源获取。反转则是由容器来帮忙创建及注入依赖对象

有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活

对象Bean如何使用?

Bean常见的四种注解:
@Controller
@Repository
@Service
@Component
如何使用Bean:
使用依赖注入:@AutoWired

Spring MVC

为什么要引入Spring MVC?

在早期 Web 开发中,控制层、业务层和数据访问层均交给 JSP 或 Java Bean 处理,这样做的弊端:

  • JSP和Java Bean严重耦合;Java和Html耦合;
  • 技术人员除了需要 Java 知识,还需要前端技术栈才可以工作;
  • 前端依赖后端,后端依赖前端,工作效率很低;
  • 代码复用性差;

什么是Spring MVC?

  • M 代表模型(Model):模型就是数据,如:dao , bean
  • V 代表视图(View):视图用于展示数据,如:网页,JSP
  • C 代表控制器(Controller):控制器用于接收用户请求,将不同的数据展现在不同的视图上。

Spring MVC的架构?

MVC 三者都属于该表现层。(controller、service、dao)
补充一个小知识点:模板引擎Thymeleaf:用于生成动态Html。

项目开发顺序!

了解了MVC的基本原理,大概的开发顺序就跃然纸上。
开发顺序与调用顺序相反,这个很好理解,因为后面的依赖前面的。
Dao -> Service -> Controller

  • entity:开发属性名;
  • Dao:写接口,定义方法头;
  • Mapper:写配置文件.xml,实现接口,Bean对象生成;
  • MapperTests:添加AutoWired注解注入Mapper,测试Bean;
  • service:添加Service注解,还要添加AutoWired注解注入Mapper,开发业务代码,根据不同逻辑返回值,将返回值交给controller;
  • controller:添加Controller注解,同样要注入Mapper,根据service传过来的不同返回值处理请求,将查询到的数据通过model传给模板;
  • .html:模板就是html文件,将数据渲染为视图View展示给用户。

Spring Boot

什么是Spring Boot?

一个Java Web的开发框架,和Spring MVC类似。但其实Spring Boot也不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架
演化过程:J2EE -> Spring -> Spring Boot

Spring Boot的核心思想?
约定大于配置。默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。

Spring Boot的优势?

  • 为所有Spring开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化Web项目
  • 没有冗余代码生成和XML配置的要求
  • 调试技巧

响应状态码有哪些?

  • 2开头:成功响应;
  • 3开头:重定向,向浏览器返回需要再次访问的地址,浏览器再次访问。重定向的作用:使用一种低耦合的方式实现功能的跳转;
  • 4开头:客户端响应失败;
  • 5开头:服务器已经接收请求,但响应失败

如何调试?

先打印日志,分析;
如果还是不行,根据响应状态码定位是客户端还是服务端的问题,确定之后打断点Debug。

Git

  • commit、push、pull是什么意思?
  • commit:提交到本地数据库;
  • push:同步到远程数据库;
  • pull:将服务器的代码拉取到本地;
  • update:pull时如果发现代码冲突,会弹出一个解决冲突的窗口,在这里解决;

Git 回退的三种类型?

  • mixed:为默认值,等同于git reset。将文件回退到工作区,此时会保留工作区中的文件,但会丢弃暂存区中的文件;
  • soft:将文件回退到暂存区,此时会保留工作区和暂存区中的文件;
  • hard:将文件回退到修改前,此时会丢弃工作区和暂存区中的文件;

2

注册

如何实现注册功能?

  1. 将注册信息发给服务器;
  2. 服务器发送邮件给注册时的邮箱;
  3. 用户点击激活链接完成注册。

会话管理

HTTP协议的特点?

HTTP是无状态的:一个浏览器向一个服务器发送的请求都是独立的,服务器记不住浏览器的状态;使用Cookies可以创建有状态的会话。

解法一:Cookies

服务器发送给浏览器并保存在本地的一小块数据,浏览器下一次向同一服务器发送请求时携带它给服务器,服务器根据Cookies迅速查找,找到该用户的活动记录。
在这里插入图片描述

解法二:Session

session

在服务端记录客户端信息,只需要传送 session 的 id ,提高安全性,但增加了服务端的内存压力。

拦截器

什么是拦截器?

Interceptor,用于拦截不合理的请求。比如:没登录,但想通过输入网址访问信息页面,当然不行了!

Spring加载项目时,会按默认顺序将这些拦截器注册进来,将来的调用顺序就是这个注册顺序。当然,对于自定义的拦截器,你可以定义它的注册顺序。

三个重要方法?

  1. preHandle():在调用Controller方法或获取静态资源前被调用(静态资源包括html、js等)。
  2. postHandle():在调用Controller方法或获取静态资源后,但是视图还没有被渲染前调用。
  3. afterCompletion():在视图渲染后进行调用,主要用来清除资源。

参考文章

拦截器在项目中的应用?

  1. 拦截登录请求

    • 自定义登录需要的注解
    • preHandle()方法判断是否有置顶注解,没有则拦截
  2. 拦截登录凭证

    • preHandle()
      

      方法:

      • 从Cookie中获取凭证ticket
      • 根据凭证查询用户,将用户信息放入在本次请求中
      • 构建用户认证的结果,并存入SecurityContext,以便于Security进行授权
    • postHandle()
      

      方法:

      • 将用户信息添加到modelAndView中
    • afterCompletion()
      

      方法:

      • 释放资源

补充:常用快捷键

ctrl + Shift + F 全局查找

ctrl + Shift + N 查找类

3

过滤敏感词

Java原生API的缺点?

Java自带的原生API也可以实现过滤敏感词,但若遇到大篇幅文章,replace方法性能就太低了。
故使用前缀树方法,此方法用空间换时间,以消耗内存为代价。

过滤敏感词的基本原理?

  1. 用到三个指针,第一个指针指向树的结点,根节点为空。如下图:
    在这里插入图片描述
  2. 用两个指针遍历字符串,上面的为begin,下面的为position。begin先移动,同时树指针检查root的子节点,若二者匹配则树指针指向子节点position++;若二者没有匹配则begin++position++。直到position遍历完整个字符串(相比begin遍历完整个字符串更节约性能一点)。最终begin~position即为敏感词,用“**”替换。

特点:begin只进不退,position以当前begin为起点,来回跳动。

在这里插入图片描述

  1. StringBuilder是一个类,用来拼接字符串,这里我们用作存储结果字符串。

在这里插入图片描述

异步请求

什么是异步请求?

整个网页不刷新,访问服务器,得到数据后返回给网页,局部刷新。实现异步请求的技术叫AJAX。网页能够将增量更新呈现在页面上。

什么是AJAX?

AJAX指异步的json和xml技术,不是一门新的语言,而是使用现有技术的新方法。项目中帖子发布成功/失败的提示使用该技术。

事务管理

什么是事务?

事务是由N步数据库操作序列组成的逻辑执行单元,这一系列操作要么全执行,要么全放弃执行。即一旦开始,必须全部执行完。

常见的并发异常有哪些?

详细解释

  • 第一类丢失更新:某一个事务回滚,会导致另一个事务已更新的数据丢失。
  • 第二类丢失更新:某一个事务提交,会导致另一个事务已更新的数据丢失。
  • 脏读:某一个事务读取了另一个事务未提交的数据。
  • 不可重复读:某一个事务对同一个数据前后读取的结果不一致。
  • 幻读:某一个事务对同一个表前后查询的行数不一致。

常见的隔离级别有哪些?

  • Read Uncommitted:读取未提交的数据。
  • Read Committed:读取已提交的数据。
  • Repeatable Read:可重复读。
  • Serializable:串行化。
    在这里插入图片描述

事务的实现机制有哪些?

  1. 悲观锁(数据库)

    • 共享锁(S锁):事务A对某数据加了共享锁,其他事务只能加共享锁,不能加排他锁。(只读不写)
    • 排他锁(X锁):事务A对某数据加了排他锁,其他事务不能加共享锁,也不能加排他锁。(不读不写)
  2. 乐观锁(自定义)

    更新前检查版本号/时间戳,若未变化则更新,否则取消本次更新。

统一捕获异常

怎样实现统一捕获异常?

服务器的三层结构中,错误会层层向上传递,所以只需要在表现层(controller)统一处理错误即可。
在Spring Boot的项目某一路径下,加上对应的错误页面,发生错误时会自动跳转。

AOP

什么是AOP?

面向切面编程,是一种编程思想,是对OOP(面向对象编程)的补充。将业务模块共同调用的逻辑封装起来,降低耦合,可以进一步提高编程效率。如下图:右上角为系统组件,这些组件横跨了多个业务组件,像切开它们一样(面向切面)。
在这里插入图片描述

AOP的常用术语有哪些?

我们只需要编写Aspect封装组件的代码,通过Weaving(织入)到目标代码的连接点(Jionpoint)进行控制。
切点(Pointcut)控制织入的具体位置;
通知(Advice)控制织入的具体逻辑。
在这里插入图片描述

什么是Spring AOP?

Spring AOP本质上基于动态代理,当要代理的对象实现了某接口,会使用JDK动态代理,在运行时通过创建接口的代理实例,织入代码。当要代理的对象没有实现接口,则使用Cglib技术(编译时增强),通过子类代理织入代码。

怎样实现统一记录日志?

本项目中,将aspect织入所有业务模块,通过这段代码,实现统一记录日志。
在这里插入图片描述

4

Redis

什么是NoSQL?

在我们日常的Java Web开发中,一旦涉及大数据量的需求,只使用数据库来保存数据的系统会因为面向磁盘,磁盘读/写速度比较慢的问题而存在严重的性能弊端。这时就需要引入NoSQL技术,它是一种基于内存的数据库,并且提供一定的持久化功能。

为什么引入Redis?

在日常对数据库的访问中,读操作的次数远超写操作,比例大概在 1:9 到 3:7,如果每次都去数据库读数据,性能太低。
所以我们将一些常用数据存储在内存中,读写速度快。同时Redis可以将数据以快照或日志的形式存储在硬盘上,从而保证安全性。

哪些数据适合放入缓存?

同时满足以下三个条件:

  1. 常用
  2. 读操作远多于写
  3. 数据量小

什么是Redis?

Redis是一款基于键值对的NoSQL数据库。管理缓存中的数据。可以存储键和五种不同数据类型的映射。其中,键必须是字符串类型,值可以是:字符串、哈希散列表、列表(栈与队列均可)、无序集合、有序集合。

项目中Redis的作用?

存储验证码、登录凭证、用户信息。

MyBatis

找了半天,在项目里看不到它的身影,原来在dao层定义接口,用xml文件实现mapper,就是用到了它。

什么是MyBatis?

是一款持久层框架

什么是持久化?

持久化是将数据在瞬时状态与持久状态相互转换的机制。

如:将缓存数据存入数据库,文件IO

为什么要引入持久化?

  1. 内存中数据一旦断电就会丢失,需要保证数据的可用性
  2. 将数据存入内存成本高,维护难度大

为什么要使用MyBatis?

  1. 数据存取。帮助我们将数据存入数据库和从数据库中取出数据
  2. 代码复用。使用框架可以避免每次连接数据库、取出数据的封装等一系列冗余操作,提高代码复用性
  3. 解耦。通过dao层将sql与业务逻辑分离

5

消息队列

什么是阻塞队列?

在这里插入图片描述
阻塞队列,一种内部进行加锁控制的队列,它是线程安全的。当队列满时,生产者生产被阻塞;当队列空时,消费者消费被阻塞。

为什么要使用消息队列?

在这里插入图片描述
如图,12306购票系统,在将买票业务呈现在用户面前之前,使用一个消息队列,用于控制消息入队和出队的速度。如果没有它,把全部数据存入数据库,系统肯定要崩!

什么是消息队列?

消息队列(MQ),是一种消息中间件,同时也是一种更高性能的阻塞队列。通过topic对数据进行分类,支持多个业务的多组数据。

消息队列的分类?

MQ分为两种:

  1. P2P : peer to peer
    在这里插入图片描述
    该模式中,一条数据只能被一个消费者消费,消费后即出队。
  2. Pub/Sub : 发布与订阅
    在这里插入图片描述
    该模式中,一条数据可以被多个消费者消费,数据存在某个位置,消费者按索引获取。

Kafka

什么是Kafka?

kafka 是一个分布式的基于消息的发布-订阅的消息队列,已经不只是消息队列的功能了。

应用:消息系统、日志采集、用户行为追踪、流式处理。

Kafka有哪些特点?

高吞吐量:处理TB级数据;
消息持久化:存储在硬盘中,顺序读写,性能高于随机读写内存;
高可靠性:分布式部署;
高拓展性:添加服务器很容易。

Push or Pull?

面试官问到了这个问题,做个记录
producer使用push模式发布消息,consumer使用pull模式消费消息。push是被动的,pull是主动的。
push模式的目标是尽可能快地处理消息,producer可以这样,但consumer需要考虑后续处理消息的能力,如果速率过快可能会导致服务器拒绝服务或网络拥塞。所以主动pull显然更适合。

Kafka的常用术语?

broker:kafka服务器;
Zookeeper:用于管理集群的中间件;
Topic:主题,生产者发布消息到该位置;
Partition:分区,将Topic分为多个区,便于管理;
Offset:各分区内的索引,消费者消费消息要用到。

Kafka的启动命令?

启动zookeeper

bin\windows\zookeeper-server-start.bat config\zookeeper.properties
1

启动server

bin\windows\kafka-server-start.bat config\server.properties
1

创建topic

kafka-topics.bat --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test
1

查看Topic

kafka-topics.bat --list --bootstrap-server localhost:9092
1

生产者生产数据

kafka-console-producer.bat --broker-list localhost:9092 --topic test
1

消费者消费数据

kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic test --from-beginning
1

在项目哪里用到了Kafka?

当有点赞,评论,关注、发帖、删帖请求时,Producer发布消息。
当队列中有消息时,Consumer主动消费消息。
一直很纳闷,EventConsumer这个类里的方法,在项目任何地方都没被调用,它是怎么执行的?原来是Kafka一直监听信道,一有消息就主动pull了
在这里插入图片描述

6

Elasticsearch

搜索引擎的原理是什么?

终于有人把Elasticsearch原理讲透了!

建立倒排索引(反向索引):

将通过诗名找诗句,转化为 -> 先通过关键词找诗名,再找出诗句

这就是百度,谷歌的搜索原理,通过关键词找帖子标题,再点进去看详情。

什么是Elasticsearch?

  1. 一个分布式的、Restful风格的搜索引擎。
  2. 支持对各种类型的数据的检索。
  3. 搜索速度快,可以提供实时的搜索服务。
  4. 便于水平拓展,每秒可以处理PB级海量数据。

Elasticsearch术语有哪些?

与Mysql对应:左边是Elasticsearch术语

版本6.0以前:索引 -> 数据库,类型 -> 表,文档 -> 行,字段 -> 列

版本7.0以后:索引 -> 表,文档 -> 行,字段 -> 列

文档一般是JSON类型,存储一行数据

如何在Elasticsearch中建立索引?

Elasticsearch 把操作都封装成了 HTTP 的 API,我们只需给 Elasticsearch 发送 HTTP 请求

所以只要学习Elasticsearch 的HTTP API就行

怎样保证高可用?

Elasticsearch 是主从架构,会对数据进行切分,每一个分片保存多个副本,放在不同节点上。

建立索引的请求先发给master,master建立索引后将状态同步到slave

应用场景?

一个典型应用就是 ELK 日志分析系统。e用于搜索,l用于采集,k用于可视化。这个系统可以将多台服务器的日志汇总在一起,通过Elasticsearch搜索,还能接入实时计算和实时报警功能。

项目中的作用?

将帖子保存至Elasticsearch服务器
从Elasticsearch服务器搜索帖子

7

Spring Security

什么是Spring Security?

参考文章

Spring Security是一款强大的身份验证和访问控制框架。提供了完善的认证机制和方法级的授权功能

它的核心是一组过滤器链,不同的功能经由不同的过滤器。

为什么京东下单和付款不需要重复登录?

这里就要引入一个概念:单点登录

就是在一个多应用系统中,只要在其中一个系统上登录之后,不需要在其它系统上登录也可以访问其内容。举个例子,京东那么复杂的系统肯定不会是单体结构,必然是微服务架构,比如订单功能是一个系统,交易是一个系统…那么我在下订单的时候登录了,付钱难道还需要再登录一次吗,如果是这样,用户体验也太差了吧。实现的流程就是我在下单的时候系统发现我没登录就让我登录,登录完了之后系统返回给我一个Token,就类似于身份证的东西;然后我想去付钱的时候就把Token再传到交易系统中,然后交易系统验证一下Token就知道是谁了,就不需要再让我登录一次。

img

什么是Token?

上面提到的Token就是JWT(JSON Web Token),是一种用于通信双方之间传递安全信息的简洁的、URL安全的表述性声明规范。一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

黑客伪造Token怎么办?

JWT在加密解密的时候会用到同一个密钥,这将会带来一个弊端,如果被黑客知道了密钥的内容,那么他就可以去伪造Token了。所以为了安全,我们可以使用非对称加密算法RSA

创建两个密钥,公钥和私钥。公钥公开,私钥私有。用公钥加密报文,只能通过私钥解密报文,这样就算报文被截获,也无法破译。

在项目中的应用?

  1. 三种用户类型:用户,管理员,版主。将主要界面授权给三者;置顶和加精授权给版主;删帖和访问数据页面授权给管理员。权限不够时设置提醒。
  2. 在拦截器中编写用户身份认证的逻辑,并存入SecurityContext,以便于Security进行授权

CSRF攻击

什么是CSRF攻击?

病毒网站窃取浏览器的cookie,获取用户凭证ticket,用其模拟用户向服务器提交表单,从而获利。
在这里插入图片描述

攻击的应对方法?

服务器发送tocken给浏览器,再次收到请求后检查tocken,此信息病毒网站无法获取。
在这里插入图片描述

Quartz

什么是Quartz?

我们系统中创建了 N 个任务,每个任务都有指定的时间进行执行,而这种多任务的执行策略就是任务调度。

Quartz是一款开源的“任务调度库”

Quartz的体系结构是什么?

一是执行的任务,二是触发器(可以理解为设置闹钟),三是调度器。连在一起就是我们使用调度器将任务和触发器绑定在一起执行,以达到在指定的时间点执行或循环执行任务。

参考文章1

参考文章2

在这里插入图片描述

  1. 任务 Job

我们想要调度的任务都必须实现org.quartz.job接口,然后实现接口中定义的execute()方法即可

  1. 触发器 Trigger

Trigger 作为执行任务的调度器。我们如果想要凌晨1点执行备份数据的任务,那么 Trigger 就会设置凌晨1点执行该任务。

  1. 调度器 Scheduler

Scheduler 为任务的调度器,它会将任务 Job 及触发器 Trigger 整合起来,负责基于 Trigger 设定的时间来执行 Job

Quartz在项目中的应用?

用于更新帖子分数,用Elasticsearch进行搜索时,该分数作为一个排序字段。计算方法:加精75,评论10,点赞2

循环执行任务,每五分钟执行一次。

Caffeine

什么是Caffeine?

Caffeine是一款本地缓存组件,Redis是一款分布式缓存组件,项目中两个都用到了,二者并不冲突。Caffeine基于LRU算法实现,设置多种缓存策略。

为什么要使用Caffeine?

Redis是分布式的,需要网络开销,本地缓存不用。对于一些秒杀系统或数据量小的缓存,用Caffeine。

项目中的应用?

将帖子列表和帖子总数放入本地缓存

Nginx

8分钟带你深入浅出搞懂Nginx

什么是Nginx?

Nginx是一款轻量级的Web服务器、反向代理服务器,内存占用少,启动快,高并发。

什么是正向代理?

终于有人把正向代理和反向代理解释的明明白白了!

一般情况下,我们通过内网无法访问github,这时需要连接VPN(虚拟专用网络)再进行访问,这个过程是正向代理。

代理的对象是客户端,代理过程对服务器透明。

作用:

  1. 突破访问限制
  2. 提高访问速度
  3. 隐藏客户端真实IP

什么是反向代理?

客户端访问的是,拥有真正服务器部分信息的代理服务器。

代理的对象是服务器端,代理过程对客户端透明。

  1. 隐藏服务器真实IP
  2. 负载均衡
  3. 提高访问速度
  4. 提供安全保障

项目中的应用?

在java后端代码中并未体现

CDN

什么是CDN?

到底什么是CDN?

内容分发网络。将目标服务器的资源分发到世界各地,距离用户群体更近,提高了访问速度。

CDN与镜像有什么区别?

镜像是对完整内容的复制,CDN是智能化缓存部分内容。

8

项目总结

在这里插入图片描述

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):行级,使用范围条件时,对此时范围内不存在的记录加锁。一是为了防止幻读,二是为了满足恢复和复制的需要。
1
  • 加锁
    • 数据查询语句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根据此找到对应的模板引擎,由模板引擎做为客户端做渲染
  • 5
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值