java基础面试题(四)

Mysql

  1. 索引的基本原理  

索引是用来快速寻找特定的记录;把无序的数据变成有序的查询

  1. 把创建索引的列数据进行排序

  1. 对排序结果生成倒排表

  1. 在倒排表的内容上拼接上地址链

  1. 在查询时,先拿到倒排表内容,再取出地址链,最后拿到数据

  1. 聚簇索引和非聚簇索引的区别

聚簇索引:进数据与索引放在一起,找到索引也找到了数据

非聚簇索引:将数据与索引分开存放,索引结构的叶子节点指向了数据的位置,通过位置找到数据

区别:

  1. 查询聚簇索引可以直接获取数据,非聚簇索引需要二次查询

  1. 聚簇索引适合范围查询  ,非聚簇索引适合排序

  1. mysql索引的结构,各自的优劣

索引的数据结构与具体的存储引擎有关。比较常用的是Hash索引和B+树索引;

Hash索引: 采用一定的hash算法,把键值换算成新的hash;等值查询,那么hash索引有明显优势,前提是健值都是唯一的,如果健值不唯一,那就需要先找到健的位置,然后再扫描链表,找到对应的值;范围查询,hash索引就不好用了

B+树索引:关键字检索效率比较平均;常规检索,从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动,而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高

  1. 索引的设计原则

查询更快,占用空间更少

  1. 适合出现在where子句中的列,或者连接子句中指定的列

  1. 基数较小的列,索引效果差,不需建

  1. 不要过度索引。索引需要磁盘空间

  1. 定义为外键的列一定要建立索引

  1. 频繁更新的字段不适合建立索引

  1. 对于查询涉及少,重复值较多的列不建立索引

  1. 定义为text、image、bit之类的数据类型不建立索引

  1. 事务的基本特性和隔离原则

基本特性(ACID):

原子性:事务的最小执行单位,不允许分隔。确保动作要么全部完成,要么不完成

一致性:执行事务前后数据保持一致,多个事务对同一个数据的读取结果是相同的

隔离性:一个事务的修改在最终提交前,对其他事务是不可见的

持久性:一个事务被提交后,所做的修改永久保存在数据库中

隔离原则:

读未提交:可能会读取到其他事务未提交的数据,也叫脏读

读已提交(oracle):只会读取已提交的事务,两次读取的结果不一致,叫做不可重复读

可重复读(mysql):每次读取的数据都是一致的,但有可能会出现幻读

可串行化:一般不使用,会给每行加锁,会导致大量超时和锁竞争的问题

  1. 如何对mysql进行分库分表?多大数据需要进行分库分表?分库分表的方式和分片策略有哪些?分库分表后SQl的执行顺序是怎样的?

什么是分库分表:当数据量过大时,查询速度降低。为提升效率,将一个表中的数据分散到多个数据库的多个表中。

常用分库分表工具:MyCat、ShardingSphere

数据分片方式:

垂直分片:从业务角度将不同的表拆分到不同的库中,能解决数据库数据文件过大的问题,但不能从根本上解决查询问题。

水平分片:从数据角度将一个表中的数据拆分到不同的库或者表中,这样可以从根本上解决数据量过大造成的查询效率低的问题。

分片策略:

  1. 取余:均匀存放数据,但扩容非常麻烦

  1. 按照范围:比较好扩容,但数据分布不够均匀

  1. 按照时间:比较容易将热点数据区分

  1. 按照枚举值:例如按地区分片

  1. 按照目标字段前缀指定分区:自定义业务规则分片

水平分片从理论上突破了单机数据量处理的瓶颈,并且拓展自由,是分库分表的标准解决方案

阿里开发手册建议:一个表的数据超过500万或者数据文件达到2G(业务开始前,提前预估3年业务量)

分库分表后执行流程(ShardingSphere):

sql解析->查询优化->sql路由->sql改写->sql执行->结果归并

分库分表问题:

跨库查询、跨库排序、分布式事务、公共表、主键重复......

  1. mysql的主从同步原理

主从同步:当主库的数据发生改变时,变化会实时同步到从库;

主从同步好处:

水平拓展数据库的能力

容错、高可用

数据备份

实现:在主库机器上,主从同步事件会被写到特殊的log文件中;在从库机器上,从库读取主从同步事件,并根据读取的事件变化,在从库上做对应的更改

  1. Myisam和Innodb的区别
  1. Innodb索引是聚簇索引,Myisam索引是非聚簇索引

  1. Innodb的主键索引叶子节点存储着行数据,因此主键索引很高效;Myisam的主键索引叶子节点存储着行数据地址

  1. Innodb非主键索引的叶子节点存储的是主键和其他带索引的列数据

  1. mysql中索引类型及对数据库的性能的影响

主键:特殊的唯一索引,一张表中只有一个

唯一索引:保证数据的唯一性

普通索引:允许被索引的数据列包含重复的值

索引可以极大地提高数据的查询速度,提高系统的性能;但是删除、新增、修改的速度会降低;每一个索引都要占用物理空间。

  1. Explain语句结果中各个字段分表表示什么

id:语句中每出现一次select,就会分配一个唯一id,某些子查询会被优化成join,id就会一致

select_type:select关键字对应的查询类型

table:表名

partitions:匹配的分区信息

type:针对单表的查询方式(全表扫描、索引)

possible_keys:可能用到的索引

key:实际用到的索引

key_len:实际用到的索引长度

ref:当使用索引查询时,与索引列进行值匹配的对象信息

rows:读取的记录条数

filtered:表过滤后的剩余记录百分比

Extra:额外信息

  1. 索引覆盖是什么

执行sql时,当前sql所需要查询出来的字段数据在索引对应的B+树中都包含了,不需要再去找,直接返回结果。

  1. 最左前缀原则是什么

最左优先,在创建索引时,最频繁的一列放在最左侧

  1. Innodb是如何实现事务的
  1. Innodb收到语句,根据条件查询数据所在页,并缓存在Buffer Pool中

  1. 执行修改语句,修改Buffer Pool数据

  1. 针对修改语句生成一个

  1. B树和B+树的区别,为什么Mysql使用B+树

B树:节点排序、一个节点可以存多个元素,多个元素也排序了

B+树:拥有B树的特点、叶子节点之间有指针、非叶子节点在叶子节点上有冗余,并且排好序

Mysql索引使用B+树,索引为了加快查询,而B+树在叶子节点上存储所有元素并且进行排序可以提高查询速度

  1. mysql锁的类型有哪些
  1. 行锁:指锁住表的某一行或多行,其他事务访问时,被锁住的行不能访问,其他正常

  1. 表锁:指锁住整个表,其他请求只能读,不能写;直到读锁释放,才能写入

  1. 死锁:多个进程在执行过程中,争夺资源造成相互等待,无法继续执行

  1. 乐观锁:假设数据不会冲突,所以在数据提交更新时才会检测,如果冲突则返回错误信息

  1. 悲观锁:当对数据库中一条数据修改时,为了避免被其他人修改,直接加锁,防止并发

  1. 共享锁:当数据加上锁后,其他事务只能读锁,而不能加写锁;直到所有读锁释放完毕,才能加写锁

  1. 排它锁:当一个事务为数据加上写锁时,其他请求不能再加任何锁,直到该锁释放

  1. Mysql慢查询该如何优化?
  1. 检查是否走了索引,如果没有则优化sql利用索引

  1. 检查是否用了最优索引

  1. 检查字段是否都是必须的,是否查询了过多字段,查出多于数据

  1. 检查是否需要分库、分表

  1. 检查数据库配置,是否需要增加资源

  1. mysql中有哪些索引?
  1. 主键索引:数据列不允许重复,不允许为null,一个表只能有一个

  1. 唯一索引:数据列不允许重复,允许为null,一个表允许多个列创建唯一索引

  1. 普通索引:基本的索引类型,没有唯一性的限制,允许为NULL值

  1. mysql哪些情况下会造成索引的失效
  1. 非最左匹配(以最左的为起点字段查询可以使用联合索引,否则不能使用联合索引)

  1. 错误模糊查询(只有右模糊查询才能触发索引)

  1. 列运算(索引列使用了运算)

  1. 使用函数(索引列使用函数)

  1. 类型转换(字段为字符串类型,但是传入int类型,索引失效)

  1. 使用is not null

  1. 使用(!=或<>)

  1. 索引列使用了or

  1. 主键和唯一索引的区别
  1. 主键索引不允许为null,且唯一;唯一索引允许为null,允许多个列创建唯一索引

  1. 主键一定会创建一个唯一索引,有唯一索引的列不一定为主键

  1. 主键索引只能有一个,但可以有多个唯一索引

  1. 主键可以被其他表引为外键,唯一索引不行

  1. 主键的执行顺序要高于唯一索引

  1. 主键是约束,但唯一索引是索引

  1. MyISAM索引与InnoDB索引的区别?
  1. InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引

  1. InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效

  1. MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。

    d.InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会

非常高效

redis

  1.  Redis主要消耗什么物理资源?

内存

  1. 单线程为什么快
  1. 纯内存操作

  1. 核心是基于非阻塞的IO多路复用机制

  1. 避免了多线程的频繁上下文切换带来的性能问题

  1. 简述redis事务实现

一组按顺序执行的命令集合;事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

实现:

事务开始

命令入队

事务队列

执行事务

  1. redis主从复制的原理

数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器;

好处:

  1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式

  1. 故障恢复:如果master宕掉了,使用哨兵模式,可以提升一个 slave 作为新的 master,进而实现故障转移,实现高可用

  1. 负载均衡:可以轻易地实现横向扩展,实现读写分离

流程:

slave服务器连接到master服务器,便开始进行数据同步

master服务器收到psync命令之后,开始执行bgsave命令生成RDB快照文件并使用缓存区记录此后执行的所有写命令

master服务器bgsave执行完之后,就会向所有Slava服务器发送快照文件,并在发送期间继续在缓冲区内记录被执行的写命令。

slave服务器收到RDB快照文件后,会将接收到的数据写入磁盘,然后清空所有旧数据,在从本地磁盘载入收到的快照到内存中,同时基于旧的数据版本对外提供服务。

master服务器发送完RDB快照文件之后,便开始向slave服务器发送缓冲区中的写命令。

slave服务器完成对快照的载入,开始接受命令请求,并执行来自主服务器缓冲区的写命令;

如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF。

5.Redis有哪些数据结构?分别有哪些典型的应用场景?

String:字符串;计数器、分布式id

hash:哈希;存储对象

List:列表;消息流数据

Set:集合;共同关注、点赞

ZSet:有序集合;排行榜

  1. Redis分布式锁是如何实现的?

分布式锁,即分布式系统中的锁,解决了分布式系统中控制共享资源访问的问题;

  1. 基于set命令的分布式锁;

  1. 基于setnx、get、getset的分布式锁

  1. 基于RedLock的分布式锁

  1. 基于Redisson看门狗的分布式锁

  1. 如何解决 Redis 的并发竞争 Key 问题

Redis 的并发竞争 Key 的问题也就是多个系统同时对一个 key 进行操作

解决方案:

  1. 乐观锁:适用于大家一起抢着改同一个key,对修改顺序没有要求的场景,使用watch命令来实现

  1. 分布式锁:在业务层进行控制,操作 redis 之前,先去申请一个分布式锁,拿到锁的才能操作

  1. 时间戳:写入时保存一个时间戳,写入前先比较自己的时间戳是不是早于现有记录的时间戳,如果早于,就不写入

  1. 消息队列:在并发量很大的情况下,可以通过消息队列进行串行化处理

  1. redis集群方案

主从模式:使用一个redis实例作为主机,其余的实例作为备份机,主机和从机的数据完全一致,主机支持数据的写入和读取等各项操作,而从机则只支持与主机数据的同步和读取

优缺点:

  1. 一个主节点可以同步多个从节点

  1. 主节点自动将数据同步到从节点,可以进行读写分离

  1. 主从之间的同步是以非阻塞的方式进行的,同步期间,客户端仍然可以提交查询或更新请求

  1. 不具备自动容错与恢复功能

  1. 难以支持在线扩容

哨兵模式:Redis集群站哨的,一旦发现问题能做出相应的应对处理;监控主节点、从节点是否正常运行当主节点出现故障时,能自动将一个从节点转换为主节点(大哥挂了,选一个小弟上位)多个哨兵可以监控同一个Redis,哨兵之间也会自动监控

Redis Cluster模式:Cluster采用无中心结构,客户端与redis节点直连,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

  1. 缓存雪崩、缓存穿透、缓存击穿,如何解决

缓存雪崩:缓存同一时间大面积失效,所有请求落在数据库上

解决:

缓存数据过期时间设置随机,防止同一时间大面积过期

给每个缓存增加标记,记录缓存是否失效,如果失效,则更新数缓存

缓存预热

互斥锁

缓存穿透:缓存和数据库中都没有数据,所有请求都落在数据库上

解决:

接口层增加校验,如用户鉴权校验,id做基础校验

从缓存取不到的数据,在数据库中也没有取到,可以将value设为null

布隆过滤器,将所有数据存到bitmap中,不存在数据会被拦截掉

缓存击穿:同一条数据,缓存中没有,数据库中有,但由于访问并发量大,造成数据库压力大

解决:

设置热点数据永远不过期

加互斥锁,互斥锁缓存预热

  1. Redis和Mysql如何保证数据一致

延迟双删:先删除redis数据,再更新mysql,延迟几百毫秒,再删除redis数据;

  1. 什么是事务?

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行

  1. redis的持久化机制

持久化机制:redis数据都是存储在内存中,为了避免数据丢失,需要将数据以某种形式从内存中保存到硬盘中,重启时利用持久化数据恢复。

RDB(快照):指定时间间隔将数据进行快照存储,重启时读取文件来恢复数据

触发方式:

  1. 配置文件

  1. 执行save命令(同步操作命令)

  1. 执行bgsave命令(对save命令的优化,异步操作)

  1. 执行shutdown命令(客户端执行命令)

  1. 执行filshall命令(这个命令就相当于删库跑路)

AOF(日志文件):记录每次对服务器的操作,当服务器重启重新执行这些命令恢复原始数据

aof持久化方式redis是默认不开启的,我们可以通过配置文件开启aof持久化方式(appendonly的值默认为no,改为yes)

  1. Redis如何设置key的过期时间

redis作为缓存存储的时候,一般都要设置过期时间,否则垃圾数据会占用大量的内存

分开设置:先设置值,再设置时间(非原子操作,极端情况下会出现问题);

合并设置:一条命令设置过期时间和值(推荐)

  1. redis内存用完了会发生什么?

跟redis的内存回收策略有关,默认是当内存用完写入数据报错

回收策略:

  1. 使用LRU(最近最少使用)策略移除key,只针对过期key

  1. 使用LRU(最近最少使用)策略移除key,针对所有的key

  1. 使用LRU(最近最不常使用)策略移除key,只针对过期key

  1. 使用LRU(最近最不常使用)策略移除key,针对所有的key

  1. 随机移除一个key

  1. 随机移除一个过期key

  1. 移除过期时间最少的key,即将要过期的key

  1. 不移除key,写入时返回error

  1. Redis过期键的删除机制

惰性过期:当访问key时,检查是否过期,过期则删除;最大化节约cpu,但对内存不友好;极端情况下出现大量过期key未被访问,会占用大量内存

定期过期:每隔一段时间扫描一定数量的key,并清除已过期的key;通过调整扫描时间间隔和扫描耗时,可以让cpu和内存达到最优的平衡效果

15.Redis集群会有写操作丢失吗?为什么?

Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作

Redis集群之间是采用异步复制的

Redis集群最大节点个数是16384个

Redis集群目前无法做数据库选择,默认在0数据库

16.Redis常见性能问题和解决方案?
  1. 主节点不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化

  1. 如果数据比较关键,某个从节点开启AOF备份数据,策略为每秒同步一次

  1. 为了主从复制的速度和连接的稳定性,主从节点最好在同一个局域网内

  1. 尽量避免在压力较大的主库上增加从库

  1. 为了主节点的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,主节点挂了,可以立马启用Slave1做主节点,其他不变

17.Redis死锁情况,如何避免死锁

发生条件:

  1. 互斥,共享资源只能被一个线程占用

  1. 占有线程,等待其他被占有线程

  1. 其他线程不能强行抢占线程资源

  1. 循环等待

解决:

  1. 使用事务时,尽量缩短事务的逻辑处理过程,及早提交或回滚事务

  1. 设置死锁超时参数为合理范围,超过时间,自动放弃本次操作,避免进程悬挂

  1. 优化程序,检查并避免死锁现象出现

  1. 对所有的脚本和程序都要仔细测试

  1. 所有的程序都要有错误处理

你可能感兴趣的:(java,面试,jvm)