java-springboot、mybatis、redis相关面试题

2023-11-11

SpringBoot部分

相比Spring,Spring Boot有哪些优点

Springboot是一个基于spring的框架,对spring做了大量简化,使开发流程更快,更高效

它大量简化maven依赖,管理了大量的基础依赖

基于注解配置(JavaConfig),无需xml配置

内嵌Tomcat,部署流程简单

打包和部署更加灵活,允许独立运行

SpringBoot如何做全局异常处理

可以使用@ControllerAdvice注解,编写一个全局异常处理类,再自定义一个方法使用@ExceptionHandler来捕获具体的异常并作相应的处理

通常情况下后台向前台返回结果时,会把结果封装成包含有错误码,错误信息以及数据本身的json数据,因此我们可以使用自定义异常类,自定义枚举错误码,在捕获全局异常后,向前台返回一个包含错误码的信息

@SpringBootApplication注解的含义

@SpringBootApplication是SprnigBoot项目的核心注解,目的是开启自动配置,并表示该类为主启动类。它包含三个子标签

  • @ComponentScan注解:开启ioc自动扫描注解,默认扫描当前包及其子包中@Controller,@Service等,并把这些bean加载到ioc器中
  • @EnableAutoConfiguration注解:启用springboot自动配置,自动所有扫描classpath目录下面所有jar中的spring.factories文件实现配置类批量注册
  • @SpringBootConfiguration注解:标志该类为springboot配置类

spring-boot-starter-parent的作用

这是SpringBoot的父工程,它的作用是帮我们管理了很多的基础jar包,同时它继承了spring-boot-dependencies,在spring-boot-dependencies项目中通过<dependencyManagement>管理了大量的依赖,同时通过<properties>维护了这些依赖的版本号

但是在项目中,还需要通过<dependencies> 去导入具体的依赖才能使用

spring-boot-starter-web的作用

此项目是Springboot和Springmvc整个的jar包,构建了web项目的基本环境,集成了日志,tomcat,springmvc,json支持等等

SpringBoot中如何读取配置

方式一:使用@Value读取配置文件

方式二:使用@ConfigurationProperties读取配置文件

SpringBoot中日志的level有哪些

日志级别从低到高分别为:

TRACE < DEBUG <INFO <WARN < ERROR

如果设置为 WARN,则低于 WARN 的信息都不会输出

Spring中默认使用INFO级别输出到控制台

SpringBoot中如何管理事务

事务(transaction)是指业务逻辑上对数据库进行的一系列持久化操作,要么全部成功,要么全部失败。

在Springboot中,可以通过xml配置和注解配置

xml方式通过配置DataSourceTransactionManager和transactionManager实现

注解方式配置通过在主启动类上加上@EnableTransactionManagement开启事务管理器,在具体的实现层service类上加上@Transactional 实现事务

SpringBoot自动配置原理

在启动类上我们会打上: @SpringBootApplication 注解,它是一个组合标签,包括:

  • SpringBootConfuration ,本质是一个 Configuration ,代表Spring的配置类。
  • IOC自动扫描的注解 ,ComponentScan 会去扫描类上是否有:@Component ,@Respository ,@Service @Controller ,如果有,就会把这个类自动注册到Spring容器中。
  • EnableAutoConfiguration :就是启动SpringBoot自动配置的注解

在 @EnableAutoConfiguration 注解中,注册了一个选择器,其中有一个方法会去返回很多的自动配置的的全限定名,这些类会自动注册到Spring容器中,

那它是怎么去找到这些所谓的自动配置类的呢?

他会通过Spring的SPI接口,也就是通过一个SpringFactoryLoader去扫描 classpath中的所有的jar包中的 MET-INF/spring.factories 中的自动配置类,比如: DispatchServlert就对应了DispatchServlertAutoConfiguration自动配置类 , 它通过@Bean+方法的方式注册了一个 DispatchServlert 到Spring容器中了

SpringBoot启动流程

1.开启秒表计时

2.starting监听器,

3.处理应用参数

4.加载环境对象

5.打印横幅

6.创建Spring容器对象:AnnotationConfigApplicationContext

7.容器刷新的前置工作

8.刷新容器 ,这里会执行spring的ioc属性容器的refrsh方法,Bean的加载,初始化等都在这个里面,Tomcat的启动也在这个方法里面。

9.刷新容器后置工作

10.秒表停止

11.started事件

12.调用runner

13.running.listeners.

Mybatis部分

MyBatis中${}取值和#{}取值的区别

{}能够防止SQL注入,因为底层使用PreparedStatement对象,预编译,性能较高

${}不能防止SQL注入,因为底层使用Statement对象,不会预编译而是拼接字符串,性能较低

能使用#{}时尽量使用#{},如果需要动态传入表名或者字段名需要用 {}

MyBatis关联查询中,延迟加载和饥饿加载的区别

延迟加载,是先从单表查询,需要使用关联数据的时候才发起关联查询,不用的时候不查询关联的数据,又叫懒加载,饥饿加载,是在查询时将关联的数据立即查询出来加载进内存,不管用不用

MyBatis对象关联查询和集合关联查询怎么做

单个关联对象用associate ,适用于多对一的关联查询,使用javaType来定义实体类型,集合用collection,适用于一对多的关联查询,使用ofType来定义集合的泛型类型

MyBatis一级缓存和二级缓存的区别

缓存,是指将从数据库查询出的数据存放在缓存中,下次使用相同查询时不必再从数据库查询,而是直接从缓存中读取,从而减轻数据库查询的压力,提高性能

mybaits中的一级缓存,是SqlSession级别,默认开启,使用同一个SqlSession发送相同的SQL时命中;它的生命周期和SqlSession一致,当调用SqlSession.close()方法时会释放缓存

mybatis中的二级缓存,是namespace级别,默认不开启,执行同一个namespace的相同statement,发送相同的SQL时命中;它的生命周期是程序结束

当SQL中执行了update()、delete()、insert()操作,则缓存中的数据都会清空

MyBaits的Mapper接口没有实现类为社么可以用@Autowired直接注入

动态代理,赋值给mapper接口引用的对象其实是一个代理对象,这个代理对象是由 JDK 动态代理创建的。在解析mapper的时候,mybatis会通过java反射,获取到接口所有的方法

当调用接口中方法时,将通过接口全限定名+方法名对应找到映射文件中namespace和id匹配的sql,然后将执行结果返回

在MyBatis如何动态修改SQL

使用Mybatis的拦截器可以做到

MyBatis的动态SQL标签有哪些?

if标签:条件判断

choose、when、otherwise标签:选择结构,类似java中的switch

trim标签:对包含的内容加上前缀,后缀

where标签:主要是用来简化SQL语句中where条件判断的,能智能的处理and or,不必担心多余导致语法错误

foreach标签:遍历元素

Mybatis的mapper如何传递多个参数

方式一,可以使用map进行传参,SQL中使用map的key来引用取值

方式二,可以在SQL中使用#{param1},#{param2}...来引用取值,它是根据mapper接口对应方法中形参的顺序进行匹配的,不管接口方法的参数名字叫个啥,SQL都只能使用param1,param2,等来取值

方式三,可以使用@Param注解,给mapper接口方法的参数命名,在SQL中直接使用取的名字来引用

Mybatis,关联对象查询,使用嵌套子查询和JOIN连表有什么区别

嵌套子查询,指的是在查询一个主对象的时候,使用单表查询,在resultmap中额外发送一个子sql查询关联对象,然后映射给主对象

连表join查询,指的是查询一个主对象的时候,使用join连表的方式把主对象和关联对象的数据一次性查出来,用resultmap映射结果

他们的区别,join连表查询只发一条sql就能把数据查询出来,嵌套子查询会有一个n+1的问题,就是说如果主查询出来n条数据,那么会额外发送n条子sql去查询对应的关联对象,加上主查询那1次,也就是n+1次,因此它的性能相对较低的,一般我们会使用join连表查询

为什么要使用连接池

对数据库的操作都需要取得连接,使用完都需要关闭连接,如果每次操作需要打开关闭连接,这样系统性能很低下。连接池就可以动态的管理这些连接的申请,使用和释放,我们操作数据库只需要在连接池里获取连接,使用完放回连接池,这样大大节省了内存,提高效率。

数据库连接池的原理主要分为三部分

  • 第一,连接池的建立,在系统初始化时建立几个连接对象以便使用。
  • 第二,连接池的管理,客户请求连接数据库时,首先查看连接池中是否有空闲连接,如果有直接分配,如果没有就等待,直到超出最大等待时间,抛出异常
  • 第三,连接池的关闭,当系统关闭时,连接池中所有连接关闭

Redis部分

讲一下你理解的Redis,为什么Redis很快

Redis是一种高性能的,开源的,C语言编写的非关系型数据库,可以对关系型数据库起到补充作用,同时支持持久化,可以将数据同步保存到磁盘

说Redis很快是相对于关系型数据库如mysql来说的,主要有以下因素

  • 第一,数据结构简单,所以速度快
  • 第二,直接在内存中读写数据,所以速度快
  • 第三,采用多路IO复用模型,减少网络IO的时间消耗,避免大量的无用操作,所以速度快
  • 第四,单线程避免了线程切换和上下文切换产生的消耗,所以速度快

你常用的Redis的数据存储结构有哪些,他们的使用场景分别是什么

Redis存储形式是键值对,支持value形式包括String,List,Set,ZSet,Hash。

String可以用作缓存,计数器,防攻击,验证码、登录过期等,List可以用来做队列,秒杀等,Set可以用来去重

Redis每种存储结构说 4 个命令吧

1.String

  • set key value 设置值
  • get key 取值
  • mset key value key value... 设置多个值
  • mget key key 获取多个值
  • incr key 将key中的值自增1
  • decre key 将key中的值自减1

2.List

  • lpush key value value... 从最左边设置值
  • rpush key value value... 从最右边设置值
  • lrange key start stop 查询key中指定区间的元素
  • lpop key 移出并返回key中最左边的元素
  • rpop key 移出并返回key中最右边的元素

3.Set

  • sadd key value value 添加元素
  • smembers key 返回集合key中的所有元素
  • srem key member 删除集合key中member元素
  • scard key 查询集合key中的元素数量

4.ZSet

  • zadd key score value (score value)... 添加元素
  • zcard key 查询集合key中元素数量
  • zcount key min max 返回有序集合key中score 在min和max之间的元素
  • zrange key start stop 返回有序集合key中索引在start和stop之间的元素

5.Hash

  • hset key field value 添加元素
  • hget key field 获取key集合中field键对应的值
  • hmset key field value (field value)... 添加元素并批量添加子键值对
  • hmget key field field 获取key集合中所有的子键值对

你们项目是怎么用Redis的

使用的是Springboot整合的redis,主要用来解决前后端分离后前后端会话问题,以及验证码的问题

怎么防止Redis宕机数据丢失问题

通过对Redis持久化,把内存中的数据和命令,保存一份到磁盘中做备份,当Redis发生宕机,重启服务器的时候,会从磁盘重新加载备份的数据,从而解决数据丢失问题

Redis持久化是什么?有几种方式

将内存中的数据备份到磁盘的过程,就叫作持久化

Redis持久化主要有两种方式,RDB和AOF,可以通过修改redis.conf进行配置

RDB是记录数据快照,而AOF是记录写命令的

Redis有了AOF持久化为什么还要RDB?

AOF和RDB各有所长

  • RDB是记录数据快照,它的优点是只产生一个持久化文件,体积相对较小,启动恢复速度快,备份方便,它的缺点是没办法做到数据百分百不丢失,因为它是每隔一定时间保存一次
  • AOF是记录写命令,它的优点是格式清晰,容易理解,数据更安全,采用append模式即使持久化过程中宕机,也不影响已经保存的数据,它的缺点是文件体积较大,恢复速度慢

根据实际需要来选择,通常二者可以结合来使用

Redis内存不够了怎么办?

方式一:增加物理内存

方式二:使用淘汰策略,删掉一些老旧数据

方式三:集群

你们Redis用在哪些业务上?用的什么存储结构

主要用做缓存,比如:验证码,分类缓存,数据字典缓存,权限数据缓存,登录信息缓存等。

String类型的存储结构用的比较多,并且使用了Json格式进行序列化。

淘汰策略有哪些?你们用的哪种

  • volatile-lru :从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
  • volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
  • volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
  • allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
  • allkeys-random:从数据集中任意选择数据淘汰
  • no-enviction:不使用淘汰

Redis事务和Mysql事务的区别

Mysql的事务是基于日志,记录修改数据前后的状态来实现的,而Redis的事务是基于队列实现的

Mysql中的事务满足原子性:即一组操作要么同时成功,要么同时失败,

Redis中的事务不满足原子性,即一组操作中某些命令执行失败了,其他操作不会回滚

因此对于比较重要的数据,应该存放在mysql中

使用Redis如何实现消息广播

Redis是使用发布订阅来实现广播的

订阅者通过 SUBSCRIBE channel命令订阅某个频道 , 发布者通过 PUBLISH channel message向该频道发布消息,该频道的所有订阅者都可以收到消息

为什么要使用Redis做缓存

一个字,快。

缓存它指的是将数据库的数据同步到内存中,客户端获取数据直接从内存中获取。由于内存读写速度大于磁盘,而使用缓存能减少磁盘读取,大大提高查询性能。

我们一般会将经常查询的,不会经常改变的热点数据,保存到缓存中,提高响应速度

缓存的执行流程

1.客户端发起查询请求

2.判断缓存中是否有数据

  • 如果有,直接返回
  • 如果没有,就从数据库查询,再把数据同步到缓存

3.返回数据给客户端

你们怎么保证Redis和Mysql的一致性

我们在代码中控制,如果数据库做是写操作,直接把redis中的对应数据删除,下次查询数据会重新写入缓存。

我们的业务对一致性要求不是很高,因此采用了先操作mysql,后删除redis。在写数据库和删除缓存行代码之间如果有查询请求依然会查询到Redis中的老数据,但是这种情况非常极端,而且我们的业务也能容忍这种短暂的脏数据。

我还知道其他方案,比如延迟双删 , 监听Mysql事务日志自动同步Redis等。

SpringCache常用注解

@EnableCaching:打在主启动类上,开启缓存功能

@Cacheable:打在方法上,表示该方法会开启缓存,打在类上,表示类中所有的方法都开启缓存,方法的返回值会自动写入缓存。如果缓存中已经有数据,方法将不会被调用,而是拿着缓存数据直接返回给客户端。

@CacheEvict:搭载类或者方法上,会将缓存清除

@CachePut:更新缓存

@Caching:组合操作,要应用于方法的多个缓存操作

@CacheConfig:打在类上,共享的一些常见缓存设置

了解缓存击穿,穿透,雪崩吗?怎么处理?

缓存击穿:缓存中没有,数据库中有的数据,由于某种原因比如缓存过期了,同时并发用户特别多,一时间都往数据库中读取数据

  • 解决方案:加互斥锁,只能允许一个线程访问数据库,然后其他线程就可以往内存中拿

缓存穿透:客户端频繁请求一个缓存和数据库中都没有数据,导致数据库压力大。

  • 解决方案:布隆过滤器来判断数据库中有没有这个key

缓存雪崩:缓存重启,或者大量key失效,导致大量并发打到数据库

  • 解决方案:为key设置不同的过期时间

Redis的主从有什么优点,和缺点?

优点是读写分离,分担了读的压力,同时能起到备份作用,防止数据丢失

缺点是不能分担写的压力,主的单点故障没有解决,存储没有得到扩容

解释一下Redis的哨兵模式。哨兵的不足?

当主服务器中断服务后,可以将一个从服务器升级为主服务器 ,以便继续提供服务

哨兵就是用来监控主从服务器,实现故障恢复功能的。它会不断的检查主服务器和从服务器的健康状态,当某个服务器出现问题时,可以向管理员发起通知。如果主服务器不可用时,会自动选择一个从服务器作为新的主服务器,并让其他的从服务器从新的主服务器复制数据

哨兵也是主从模式,没有解决写的压力,只减轻了读的压力,而且存储也得不到扩容

Redis的cluster集群怎么存储数据的?

Redis Cluster集群采用哈希槽 (hash slot)的方式来分配的。它默认分配了16384个槽位,当我们set一个key 时,会用CRC16算法得到所属的槽位,然后将这个key 分到对应区间的节点上

什么情况下Redis集群不可用?

Redis Cluster有一个容错机制,如果半数以上的主节点与故障节点通信都超时了,就会认为该节点故障了,自动触发故障转移操作,故障节点对应的从节点升级为主节点。

但是如果某个主节点挂了,又没有从节点可以使用,那么整个Redis集群就不可用了、

Redis存储结构底层有没有了解?什么是SDS

简单动态字符串,是Redis自己封装的字符串结构。它记录了字节数组buf,字节数组中用到的字节数len,以及未使用的字节数free。

  • 为了解决二进制安全问题,定义了len来表示已有字符串长度
  • 为了防止缓冲区溢出,在分配内存的时候做了预留空间free
  • 内存惰性释放,多余的内存加入free做预留,优化了内存频繁分配
  • 针对不同的String长度定制了不同的SDS结构

Redis如何模拟队列和栈,用什么命令

list控制同一边进,同一边出就是栈;list控制一边进,另一边出就是队列

Redis存储单个对象怎么存,存储对象集合怎么存

单个对象可以使用String,也可以使用hash

集合对象可以使用hash,以便可以快速的通过field来取值

你们Redis用来做什么?使用的什么结构?

登录信息login,使用的是String结构存储

手机验证码code,使用的是String结构

课程分类course_type ,使用的是String结构

购物车保存,使用的是Hash结构

感谢阅读,由于篇幅有限以上面经资料博主已经整理打包好了,这些知识点的导图和问题的答案详解的PDF文档都可以免费分享给大家,点赞收藏文章后,私信【资料】免费领取!

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java-springboot、mybatis、redis相关面试题 的相关文章

随机推荐

  • Java常用包9

    下面列出了Java常用包 可以查找该包下面的常用类 可以查看该类的常用方法使用源码 模块 项目数 1 rx functions 有 21 个常用类 2 org springframework beans factory config 有 3
  • 20060217: 联合国的人权报告毫无根据?

    那你美国的人权报告就有根据了 环球时报 引用的不是 中韩观点 而是事实 转载于 https www cnblogs com yidinghe archive 2006 02 17 332220 html
  • 前端 h5实现自带浏览器支付功能

    前端需要做的 这里使用vue 中的 mixin 第一步获取订单号 调用后端的接口获取订单号 第二步 调用后端的接口 后端给返回一个url地址 然后打开这个地址 这个地址是调用微信支付的地址 打开即调用 这里使用decodeURICompon
  • Nginx配置origin限制跨域请求

    Nginx需要修复一个安全漏洞 这个需要根据客户端传递的请求头中的Origin值 进行安全的跨站策略配置 目的是对非法的origin直接返回403错误页面 配置如下 1 在http中定义一个通过map指令 定义跨域规则并返回是否合法 htt
  • SQL中的替换函数replace()使用

    语法REPLACE string expression string pattern string replacement 参数string expression 要搜索的字符串表达式 string expression 可以是字符或二进制
  • 【大数据分析与挖掘】挖掘建模之关联分析

    文章目录 一 关联规则 1 1 常用的关联规则算法 1 2 Apriori算法介绍 1 2 1 关联规则与频繁项集 1 2 2 Apriori算法的思想与性质 1 2 3 Apriori算法的实现的两个过程 1 2 4 Apriori算法的
  • PicGo+阿里云Oss图床

    首先说一下我为什么使用阿里云 我之前是用gitee做图床 后面被限制了 图片也访问不了 阿里云这个5块钱可以用半年 还是很便宜的 主要不会突然见不能用 文章目录 PicGo下载 阿里云Oss图床的配置 PicGo下载 PicGo2 3 0
  • Linux:查看进程+杀死进程

    查看进程 ps 查看所有进程状态 ps aux 参数 a 显示所有进程 包括其他用户的进程 u 用户以及其他详细信息 x 显示没有控制终端的进程 查看本用户的进程及其状态 ps u 状态 1 R 运行 表示进程正在运行或在允许队列中等待 2
  • Leetcode 704 二分查找

    Leetcode 704 二分查找 题目描述 给定一个 n 个元素有序的 升序 整型数组 nums 和一个目标值 target 写一个函数搜索 nums 中的 target 如果目标值存在返回下标 否则返回 1 示例1 输入 nums 1
  • Pr零基础入门指南笔记二-----------(粗剪、精剪、导出视频)

    目录 1 粗 精剪辑步骤 2 粗剪详细步骤 1 预览和挑选素材 2 调整素材顺序 3 精确修建素材 4 添加背景音乐 3 导出视频 干货 PR零基础入门指南第三集 10分钟学会PR基本剪辑 剪辑步骤 快捷操作大分享 哔哩哔哩 bilibil
  • 版本发布规范

    版本发布命名规范 版本命名规范 软件版本号有四部分组成 第一部分为主版本号 第二部分为次版本号 第三部分为修订版本号 第四部分为日期版本号加希腊字母版本号 希腊字母版本号共有五种 分别为base alpha beta RC release
  • Unity Shader初学——《Unity Shader入门摘要》

    由于项目需要加上本人兴趣 所以开始学习shader相关知识 主要参考冯乐乐的 Unity Shader入门摘要 作者的博客在此 https blog csdn net candycat1992 作者的个人网站 http candycat19
  • 【论文笔记】ICNet:用于无监督医学图像配准的逆一致性模型

    本文是文章 Inverse Consistent Deep Networks for Unsupervised Deformable Image Registration 的阅读笔记 过去基于学习的配准方法忽略了图像之间转换的逆一致性 并且
  • 计算机系统实验六:程序的链接

    参考教材 计算机系统基础 第二版 袁春风 机械工业出版社 参考慕课 计算机系统基础 四 编程与调试实践 https www icourse163 org learn NJU 1449521162 计算机系统实验导航 实验一 环境安装 htt
  • 2 ELK收集nginx的json格式日志

    为了便于利用 ELK日志平台收集展示 Nginx 的日志 可以将 Nginx 的日志改成 json 的格式 https www jianshu com p b6ba259777e7 1 修改nginx配置文件 root db01 vim e
  • TCP/IP(TCP传输控制协议)

    1 基本知识 TCP 协议的作用是 保证数据通信的完整性和可靠性 防止丢包 可靠地协议 面向连接的协议 TCP和UDP在传输层 TCP 是以太网协议和 IP 协议的上层协议 也是应用层协议的下层协议 以太网协议解决了局域网的点对点通信 IP
  • Internet Explorer 无法打开Internet站点 http://xxxxx 已终止操作

    在开发中也遇到这个情况 原因可能是因为程中 在IE下 当页面还没有加载完全时 如果正在执行的JS代码中含有使用了 document createElement的话 很容易引起页面加载失败 导致提示 internet explore 无法打开
  • Linux操作系统之线程创建

    文章目录 一 了解线程 二 线程的创建 一 了解线程 什么是线程 线程是进程内部的一条执行路径或执行序列 二 线程的创建 pthread creat 创建线程 pthread exit 只退出当前线程 pthread join 等待线程结束
  • matlab绘制奈奎图,matlab画奈奎斯特图

    基于matlab 的时域奈奎斯特定理验证课题名称 利用 matlab 检验采样定理 学院 计通学院 专业班级 通信 1402 2016 年 6 月 设计目的 1 掌握 matlab 的一些应用 奈奎斯特图和波特图解释 物理 自然科学 专业资
  • java-springboot、mybatis、redis相关面试题

    SpringBoot部分 相比Spring Spring Boot有哪些优点 Springboot是一个基于spring的框架 对spring做了大量简化 使开发流程更快 更高效 它大量简化maven依赖 管理了大量的基础依赖 基于注解配置