2024年java面试--mysql(5)

系列文章目录

  1. 2024年java面试(一)–spring篇
  2. 2024年java面试(二)–spring篇
  3. 2024年java面试(三)–spring篇
  4. 2024年java面试(四)–spring篇
  5. 2024年java面试–集合篇
  6. 2024年java面试–redis(1)
  7. 2024年java面试–redis(2)


MySQL有哪些锁

基于粒度:

  • 表级锁:对整张表加锁,粒度大并发小
  • 行级锁:对行加锁,粒度小并发大
  • 间隙锁:间隙锁,锁住表的一个区间,间隙锁之间不会冲突只在可重复读下才生效,解决了幻读

基于属性:

  • 共享锁:又称读锁,一个事务为表加了读锁,其它事务只能加读锁,不能加写锁
  • 排他锁:又称写锁,一个事务加写锁之后,其他事务不能再加任何锁,避免脏读问题

$和#

#占位符的特点

  1. MyBatis处理 #{ } 占位符,使用的 JDBC 对象是PreparedStatement 对象,执行sql语句的效率更高。
  2. 使用PreparedStatement 对象,能够避免 sql 注入,使得sql语句的执行更加安全。
  3. #{ } 常常作为列值使用,位于sql语句中等号的右侧;#{ } 位置的值与数据类型是相关的。

$占位符的特点

  1. MyBatis处理 ${ } 占位符,使用的 JDBC 对象是 Statement 对象,执行sql语句的效率相对于 #{ } 占位符要更低。
  2. ${ } 占位符的值,使用的是字符串连接的方式,有 sql 注入的风险,同时也存在代码安全的问题。
  3. ${ } 占位符中的数据是原模原样的,不会区分数据类型。
  4. 占位符常用作表名或列名,这里推荐在能保证数据安全的情况下使用{ } 占位符常用作表名或列名,这里推荐在能保证数据安全的情况下使用 占位符常用作表名或列名,这里推荐在能保证数据安全的情况下使用{ }。

数据库三范式具体是什么

第—范式:每个列都不可以再拆分。

第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。

第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。

Mysql内连接、左连接、右连接的区别

内连接取量表交集部分,左连接取左表全部右表匹部分,右连接取右表全部坐表匹部分

where和having的区别?

where是约束声明,having是过滤声明,where早于having执行,并且where不可以使用聚合函数,having可以

char和varchar的区别

char是不可变的,最大长度为255,varchar是可变的字符串,最大长度为2^16

InnoDB 什么情况下会产生死锁

事务1已经获取数据A的写锁,想要去获取数据B的写锁,然后事务2获取了B的写锁,想要去获取A的写锁,相互等待形成死锁。 mysql解决死锁的机制有两个:1.等待, 直到超时 2.发起死锁检测,主动回滚一条事务 死锁检测的原理是构建一个以事务为顶点、 锁为边的有向图, 判断有向图是否存在环, 存在即有死锁。

MySQL 删除自增 id,随后重启 MySQL 服务,再插入数据,自增 id 会从几开始?

innodb 引擎:
MySQL8.0前,下次自增会取表中最大 id + 1。原理是最大id会记录在内存中,重启之后会重新读取表中最大的id
MySQL8.0后,仍从删除数据 id 后算起。原理是它将最大id记录在redolog里了
myisam:
自增的 id 都从删除数据 id 后算起。原理是它将最大id记录到数据文件里了

MySQL插入百万级的数据如何优化?

(1)一次sql插入多条数据,可以减少写redolog日志和binlog日志的io次数(sql是有长度限制的,但可以调整)
(2)保证数据按照索引进行有序插入
(3)可以分表后多线程插入

Mybatis 中一级缓存与二级缓存

1.MyBatis的缓存分为一级缓存和 二级缓存。

一级缓存是SqlSession级别的缓存,默认开启。

二级缓存是NameSpace级别(Mapper)的缓存,多个SqlSession可以共享,使用时需要进行配置开启。

2.缓存的查找顺序:二级缓存 => 一级缓存 => 数据库

简述Mybatis的动态SQL,列出常用的6个标签及作用

动态SQL是MyBatis的强大特性之一 基于功能强大的OGNL表达式。
动态SQL主要是来解决查询条件不确定的情况,在程序运行期间,根据提交的条件动态的完成查询
常用的标签:

<if> : 进行条件的判断

<where>:在<if>判断后的SQL语句前面添加WHERE关键字,并处理SQL语句开始位置的AND 或者OR的问题

<trim>:可以在SQL语句前后进行添加指定字符 或者去掉指定字符.

<set>: 主要用于修改操作时出现的逗号问题

<choose> <when> <otherwise>:类似于java中的switch语句.在所有的条件中选择其一

<foreach>:迭代操作,批量操作

Select 语句完整的执行顺序

(1)from 子句组装来自不同数据源的数据;
(2)where 子句基于指定的条件对记录行进行筛选;
(3)group by 子句将数据划分为多个分组;
(4)使用聚集函数进行计算;
(5)使用 having 子句筛选分组;
(6)计算所有的表达式;
(7)select 的字段;
(8)使用order by 对结果集进行排序。

如何保证接口的幂等性

  1. 根据状态机很多时候业务表是有状态的,比如订单表中有:1-下单、2-已支付、3-完成、4-撤销等状态。如果这些状态的值是有规律的,按照业务节点正好是从小到大,我们就能通过它来保证接口的幂等性。假如id=123的订单状态是已支付,现在要变成完成状态。update order set status=3 where id=123 and status=2;第一次请求时,该订单的状态是已支付,值是2,所以该update语句可以正常更新数据,sql执行结果的影响行数是1,订单状态变成了3。后面有相同的请求过来,再执行相同的sql时,由于订单状态变成了3,再用status=2作为条件,无法查询出需要更新的数据,所以最终sql执行结果的影响行数是0,即不会真正的更新数据。但为了保证接口幂等性,影响行数是0时,接口也可以直接返回成功。
    具体步骤:
    1 用户通过浏览器发起请求,服务端收集数据。
    2 根据id和当前状态作为条件,更新成下一个状态
    3 判断操作影响行数,如果影响了1行,说明当前操作成功,可以进行其他数据操作。
    4 如果影响了0行,说明是重复请求,直接返回成功。

  2. 获取token
    除了上述方案之外,还有最后一种使用token的方案。该方案跟之前的所有方案都有点不一样,需要两次请求才能完成一次业务操作。
    第一次请求获取token
    第二次请求带着这个token,完成业务操作。
    具体步骤:
    1 用户访问页面时,浏览器自动发起获取token请求。
    2 服务端生成token,保存到redis中,然后返回给浏览器。
    3 用户通过浏览器发起请求时,携带该token。
    4 在redis中查询该token是否存在,如果不存在,说明是第一次请求,做则后续的数据操作。
    5 如果存在,说明是重复请求,则直接返回成功。
    6 在redis中token会在过期时间之后,被自动删除。

猜你喜欢

转载自blog.csdn.net/weixin_43228814/article/details/132890143
今日推荐