Java Mysql数据库面试题(一)


前言

最新的 Java 面试题,技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linux…等等,会持续更新。

如果对老铁有帮助,帮忙免费点个赞,谢谢你的发财手!

1、CHAR 和 VARCHAR 的区别?

  • 1.char 表示是固定长度的,varchar表示是长度可变的;
  • 2.char如果插入的长度小于定义长度时,则用空格填充;varchar小于定义长度时,就按实际长度存储;
  • 3.char最多能存放255(2的8次方)个字符,和编码无关,varchar最多能存放65532(2的16次方)个字符。

2、Mysql锁有哪些,如何理解 ?

在数据库中如果有多个事务同时操作同一数据,如果不加锁就可能导致数据不一致。

按锁粒度分类:

  • 1.⾏锁:锁某⾏数据,锁粒度最⼩,并发度⾼,但可能会出现死锁,是基于索引实现的;
  • 2.表锁:锁整张表,锁粒度最⼤,并发度低,但不会出现死锁;
  • 3.间隙锁:锁的是⼀个区间,锁粒度和并发都介于二者之间。

按读写分类:

  • 1.共享锁(读锁):是一个事务并发读取某一行记录所需要持有的锁,比如select … in share mode;
  • 2.排他锁(写锁):是一个事务并发更新或删除某一行记录所需要持有的锁,比如select … for update
  • 3.自增锁:是一种特殊的表级锁,主要用于事务中自增主键id;

3、什么是MVCC多版本并发控制?

通俗的讲,MVCC指的是维持一个数据的多个版本,使得读写操作没有冲突,从而提高数据库的读写性能;
它是通过乐观锁来实现的,主要依赖3个模块:隐藏字段、undo log、Read View;对于使用 InnoDB 存储引擎的表来说,它都包含两个必要的隐藏字段:事务id(trx_id)和回滚指针(roll_pointer);
底层原理是这样的:

  • 1.在事务A中修改某条数据,数据库会先对它加排它锁;
  • 2.然后把该条数据拷贝到undo log中,作为副本,用于回滚;
  • 3.拷贝完成后,就修改该条数据,并且修改事务id为当前事务的id,回滚指针指向副本的记录;
  • 4.然后提交事务,释放锁。

4、简述InnoDB和MyISAM的区别:

  • 1.InnoDB⽀持事务,MyISAM不支持事务;
  • 2.InnoDB⽀持表锁和行锁,MyISAM只⽀持表锁(每次操作都是对整个表加锁);
  • 3.InnoDB的叶子节点存储是行数据,MyISAM存储的是磁盘地址(相当于回表);
  • 4.InnoDB的索引和数据是在1个文件中(xxx.ibd),MyISAM的索引和数据是分开的2个文件(xxx.myi和xxx.myd),索引存储的是数据文件的磁盘地址。
    相同点:都是在mysql安装目录下的data目录,为每个数据库都建了同名的文件夹,里面保存了每张表的结构和数据,表结构是存储在xxx.frm文件。

5、MySQL 索引类型:

1、按照功能分类,索引主要有四种:

  • 1.普通索引:可以包含多个字段(联合/复合索引),可以同时存在多个普通索引;
  • 2.唯一性索引:在普通索引的基础上增加了数据唯一性的约束,可以包含null值;
  • 3.主键索引:在唯一性索引的基础上又增加了不为空的约束,但只能有一个主键索引。
  • 4.全文索引:很少在 MySQL 中用,一般用在ES(分布式文档数据库),只有字段的数据类型为CHAR、VARCHAR和TEXT才可以建立全文索引。

2、按照物理存储分类,索引可以分为两大类

  • 1.聚集(聚簇)索引:只能有一个,默认是以主键创建的索引,索引和行数据是在一起的,叶子节点存储的是行数据,行数据的排列顺序和索引的排列顺序一致,所以查询效率快;
  • 2.非聚集(聚簇)索引:可以有多个,是以非主键创建的索引,索引和行数据是分开的,叶子节点存储的是主键值,如果再根据主键值去主键索引里查询数据,这个过程就是所谓的回表(也称为二级索引或者辅助索引)。

6、explain查看执行计划:

  • type:访问类型,性能:system > const > eq_ref > ref > range > index > ALL;
    **system、const:**表示通过索引一次就查询到了相关记录;
    **eq_ref:**表示使用了唯一索引,每个索引对应一条记录;
    **ref:**表示使用了非唯一性索引,一般出现在关联查询中;
    **range:**表示使用了索引进行范围查询, 一般在where语句中出现between、< 、>、in;
    **index:**表示扫描了全表的索引,从索引中获取数据;
    **ALL:**表示扫描了全表的数据,从硬盘中获取数据,需要优化。
  • key:表示查询时真正使用到的索引,如果没有用到索引,就是NULL;
  • rows:表示查询的行数;
  • extra:查询的详细信息:
    **using index:**表示使用了覆盖索引(联合索引字段包含了需要查询的列),避免回表查询;
    **using filesort(文件排序):**表示无法利用索引完成排序,比如联合索引不满足最左匹配原则;
    **using temporary:**表示使用了临时表保存中间结果,常见于排序和分组查询;
    **Using where:**表示使用了where条件过滤。

7、MySQL Update是行锁还是表锁?

  • 行锁:如果where条件包含了索引列, 并且只更新一条数据;
  • 表锁:如果where条件中不包含索引列;
  • 间隙锁:如果对索引区间的数据进行查询或者修改。

8、Mysql和Redis/ES实现数据同步方式?

  • 1.同步双写:在写入 MySQL时,直接也同步往Redis/ES里写一份数据;
    缺点是代码耦合度高,影响性能;
  • 2.异步双写:通过MQ中间件实现数据同步;
  • 3.定时任务:定时的去数据库根据修改时间读取数据写入Redis/ES;
    缺点是实时性比较差,影响性能;
  • 4.数据订阅:通过监控Mysql的binLog文件,实现数据同步;比如alibaba的canal组件和Flink CDC。

9、交叉连接、内连接、外连接的区别?

  • 交叉连接(JOIN):又叫笛卡尔积,它是指不使用任何条件,直接将一个表的所有记录和另一个表中的所有记录一一匹配;
  • 内连接(INNER JOIN):是指有条件的交叉连接,根据某个条件筛选出符合条件的记录,不符合条件的记录不会查询出来;
  • 外连接分为左LEFT JOIN(右)RIGHT JOIN连接:左(右)表为主表,左(右)表中符合条件的记录都会查询出来,对于那些在右(左)表中没有匹配的记录,字段值以NULL来填充。

10、SQL 语言包括哪几部分?每部分都有哪些操作关键字?

SQL语言主要包括数据定义(DDL)、数据操纵(DML)、数据查询(DQL)和数据控制(DCL)四个部分。

  • 数据定义:create Table、alter Table、drop Table;
  • 数据操纵:insert、update、delete;
  • 数据控制:grant(向用户授予权限)、revoke(收回已经授予用户的权限);
  • 数据查询:select、where、order by、group by和having。

11、Mysql和ES数据同步方案?

  • 1.同步双写:是指把数据保存到数据库时,同步将数据写入到ES中;
    缺点是会影响主库的性能。
  • 2.异步双写:通过第三方中间件比如Rocket MQ,异步将数据写入到ES中;
  • 3.定时任务:定时任务是指在固定的时间点或时间间隔内将主库中的数据同步到备库中
    数据订阅:通过监听mysql的bin log日志,把数据同步到ES中,比如Flink cdc、alibaba的canal组件。

12、B+树和B树的对比?

  • 1.由于B+树在非叶子结点上不存储真正的数据,只当做索引使用,因此每个节点能够存放更多的key,减少树的层数,从而减少和磁盘的I/O交互次数。
  • 2.B+树的叶子结点都是前后相连的,所以便于区间查找和搜索,时间复杂度是O(log n)。

13、谈一谈你对 MySQL 性能优化的理解:

MySQL 的性能优化我认为可以分为3个方面:

  • 1、硬件方面的优化
    从硬件方面来说,影响MySQL性能因素主要是CPU,可用内存大小,磁盘读写速度等
  • 2、架构设计方面的优化:
    1).搭建MySQL主从集群,可以保证服务的高可用性
    2).读写分离设计,可以使用Mycat数据库中间件
    3).使用缓存服务器,把热点数据缓存到Redis、Mongodb等
  • 3、SQL执行方面的优化
    1).慢SQL的分析,可以通过mysqldumpslow命令 (-t 10 {$PATH}/slow-log)和慢查询日志工具(pt-query-digest)来分析;
    2).执行计划分析,针对慢SQL,我们可以使用explain + sql语句,可重点关注type(连接类型),key(实际使用的索引), rows(扫描出的行数)等字段
    3).资源开销分析,使用show profile工具,可以得到SQL执行过程中的,CPU开销,内存开销, IO开销,默认情况下,show profile是关闭的。

14、如何优化 sql语句?

优化sql语句最主要的就是优化索引,要避免让索引失效,以下是索引失效的情况:

  • 1.对索引列使用函数,mod取余,concat拼接,reverse颠倒顺序,round四舍五入;
  • 2.对索引列进行运算:加减乘除;
  • 3.索引列隐式类型转换,索引列是int,传的字符;
  • 4.联合索引不满足最左匹配原则;
  • 5.模糊查询like以%开头,索引失效;
  • 6.范围条件右边的列索引失效;
  • 7.使用了不等于(!= 或者<>)。

15、主键和候选键有什么区别?

表格的每一行都由主键唯一标识,一个表只有一个主键。
候选键可以被指定为主键,并且可以用于任何外键引用。

16、myisamchk 是用来做什么的?

它用来压缩 MyISAM 表,减少了磁盘或内存的使用。

17、MyISAM Static 和 MyISAM Dynamic 有什么区别?

  • MyISAM静态表的所有字段有固定宽度;
  • MyISAM动态表将具有像 TEXT,BLOB 等字段,以适应不同长度的数据类型。
  • MyISAM 静态表在受损情况下更容易恢复。

18、如果一个表有一列定义为 TIMESTAMP,将发生什么?

每当行被更改时,时间戳字段将获取当前时间戳。

19、列设置为AUTO INCREMENT时,如果在表中达到最大值,会发生什么情况?

Mysql 的自增主键默认是 int 类型,4 个字节,一个字节 8 位,第1位是符号位,最大值就是(2^31)-1;如果自增主键达到最大值,再插入数据就会报错。

20、怎样才能找出最后一次插入时分配了哪个自动增量?

LAST_INSERT_ID()将返回由Auto_increment分配的最后一个值,并且不需要指定表。

21、LIKE 声明中的%和_是什么意思?

%对应于 0 个或更多字符,_只是 LIKE 语句中的一个字符。

22、如何在 Unix 和 MySQL 时间戳之间进行转换?

  • UNIX_TIMESTAMP 是从 MySQL 时间戳转换为 Unix 时间戳的命令。
  • FROM_UNIXTIME 是从 Unix 时间戳转换为 MySQL 时间戳的命令。

23、列对比运算符是什么?

在 SELECT 语句的列比较中使用=,<>,<=,<,> =,>,<<,>>,<=>,AND, OR 或LIKE 运算符。

24、BLOB 和 TEXT 有什么区别?

blob主要用于存储二进制大对象,例如可以存储图片,音视频等文件,最大65KB,不过数据库并不适合直接存储图片,如果有大量存储图片的需求,请使用对象存储服务或文件存储服务,数据库中只存储图片路径;
text类型同 char、varchar 类似,都可用于存储字符串,如果遇到长文本字符串,可以使用 text 类型。
不同点:

  • 1.text对大小写不敏感,而blob排序和比较对大小写敏感;
  • 2.text需要指定字符集,blob无需字符集校验。
  • 3.text只能储存纯文本文件,blob可以储存图片。

25、MySQL_fetch_array 和 MySQL_fetch_object 的区别是什么?

  • MySQL_fetch_array:将结果行作为关联数组或来自数据库的常规数组返回。
  • MySQL_fetch_object:从数据库返回结果行作为对象返回。

总结

都已经看到这里啦,赶紧收藏起来,祝您工作顺心,生活愉快!

  • 21
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值