一.redis热点面试题
1.redis的五种数据类型及常见的使用场景
string(字符串) 它能够存储任何形式的数据,包括字符串、图片、视频等,允许单个字符类型的最大容量为512MB,一般常用在需要计数的场景
list(列表) Redis 的 list 的实现为一个 双向链表,即可以支持反向查找和遍历,更方便操 。发布与订阅或者说消息队列
hash(字典) 常用在系统中对象数据的存储。电商网站购物车的设计与实现。
为了区别与Redis中的键值对的称呼,hash中的键称为field,hash(字典) 是由field和关联的value组成的map,其中field和value都是字符串类型。
set(集合) 需要存放的数据不能重复以及需要获取多个数据源交集和并集等场景,共同喜爱,共同粉丝等场景
zset(有序集合) 需要对数据根据某个权重进行排序的场景。比如在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息。会员短期体验之过期失效
2.redis常见的持久化机制
RDB 指定的时间间隔能对你的数据进行快照存储,实际过程是fork主进程得到子进程,子进程共享主进程的内存数据。先将数据集合写入临时文件、写入成功后,再替换之前的文件,整个数据库只有一个dump.rdb文件,方便持久化
AOF:每一个收到的写命令都通过write函数追加到文件中,AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF。可以定期对aof文件进行重写,达到压缩目的
AOF文件比RDB 更新频率高,优先使用AOF还原数据,如果两个都配了,优先加载AOF
3.缓存雪崩、缓存穿透、缓存击穿
缓存雪崩是指在同一时间内由于大量的缓存失效,导致大量原本应该去访问缓存的请求都去查询数据库,而对数据库的cpu和内存造成巨大的压力,严重的可能导致数据库宕机
解决方案:
1.设置不同的失效时间,在缓存进行失效时间设置的时候,从某个适当的值域中随机一个时间作为失效时间即可
2.请求加锁,对于并发量不是很大的应用,使用请求加锁排队的方案防止过多请求数据库
缓存穿透是指查询一个一定不存在的数据,由于缓存时不命中就从数据库查询,查不到就不写入数据库中,导致这个不存在的数据每次请求都会去数据库查看,引起缓存穿透
解决方案:
1.非法请求的限制,因此在 API 入口处我们要判断求请求参数是否合理,请求参数是否含有非法值、请求字段是否存在,如果判断出是恶意请求就直接返回错误,避免进一步访问缓存和数据库
2.对查询结果为空的情况下,也进行缓存,该缓存的key设计短点
3.通过布隆过滤器过滤一个一定不存在的key,避免对底层系统带来查询的压力
缓存击穿:
如果缓存中的某个热点数据过期了,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮,这就是缓存击穿的问题
解决方案:
互斥锁方案,保证同一时间只有一个业务线程更新缓存,未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。
不给热点数据设置过期时间,由后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间
1.先更新数据库再删除缓存
2.采用延时双删策略:在写库前后都进行删除缓存操作,并且设置合理的超时时间
3.基于订阅binlog的同步机制(可以采用canal),一步更新缓存
5.Redis过期删除策略惰性删除:只有当访问一个key时候,才会判断该key是否已经过期,过期才清理
定期删除:每一段时间,会扫描一定数量的数据库expires字典中的key,并清理其中已经过期的key
可以通过修改配置文件 redis.conf 的 hz 选项来调整这个次数:
Redis中同时使用了惰性过期和定时过期两种过期策略
6.Redis淘汰策略当使用的内存大于 maxmemory 时,就会触发 Redis 主动淘汰内存方式,在 redis.conf 配置文件中,可以设置 maxmemory-policy 来设置内存淘汰方式:比如:maxmemory-policy noeviction
常见的淘汰策略:
volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰;
volatile-ttl:从已设置过期时间的数据集中移除即将过期的 key (minor TTL);
volatile-random:从已设置过期时间的数据集中任意选择数据淘汰 ;
allkeys-random:无差别的随机移除;
allkeys-lru:从数据集合中挑选最近最少使用的数据淘汰
noeviction:不移除任何 key,只是返回一个写错误 ,默认选项,一般不会选用。
redis有三种集群模式:主从模式、哨兵模式、分片集群模式
生产上常用分片集群方案
使用分片集群可以解决上述问题,分片集群特征:
1、集群中有多个master,每个master保存不同数据 每个master都可以有多个slave节点 。
2、master之间通过ping监测彼此健康状态 客户端请求可以访问集群任意节点,最终都会被转发到正确节点
3、redis-cluster把所有的物理节点都映射到0-16383的slot上,集群负责维护每个节点上数据slot的分配。
8.简述全量同步的流程1.slave节点请求增量同步
2.master节点判断replid(简述全量同步的流程),发现不一致,拒绝增量同步
3.master将完整内存数据生成RDB,发送RDB到slave ,slave清空本地数据,加载master的RDB
4.master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave
5.slave执行接收到的命令,保持与master之间的同步
mysql热点面试题
1.联合索引是什么?为什么需要注意联合索引中的顺序?什么是最左前缀匹配原则
MySQL可以使用多个字段同时建立一个索引,叫做联合索引.在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引.
最左前缀匹配原则,mysql会⼀直向右匹配直到遇到范围查询(>、<、between、like)就停⽌匹配。
⽐如a=3 and b=4 and c>5 and d=6如果建⽴(a,b,c,d)顺序的索引,d是⽤不到索引的,如果建⽴(a,b,d,c)的索引则都可以⽤到,a,b,d的顺序可以任意调整。
=和in可以乱序,⽐如a=1 and b=2 and c=3建⽴(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识
事务基本特性:原子性(一个事务中的操作要么全部成功,要么全部失败) 、
一致性(数据库总是从一个一致性状态转换成另外一个一致性的状态)、
隔离性(事务在最终提交前、对其它事务时不可见的)、持久性
mysql的隔离级别是在mysql.ini中配置的,常见配置:
未提交读(READ UNCOMMITTED) 可能引起脏读、不可重复读、幻读
已提交读(READ COMMITTED) 可能引起不可重复读、幻读
可重复读(REPEATABLE READ() 可能引起幻读
可串行化(SERIALIZABLE)
多事务的并发进行一般会造成以下几个问题
脏读: A事务读取到了B事务未提交的内容,而B事务后面进行了回滚.
不可重复读: 当设置A事务只能读取B事务已经提交的部分,会造成在A事务内的两次查询,结果竟然不一样,因为在此期间B事务进行了提交操作.
幻读: A事务读取了一个范围的内容,而同时B事务在此期间插入了一条数据.造成"幻觉".
3.如何对mysql进行优化-
数据查询过慢一般是索引问题,可能是因为选错索引,也可能是因为查询的行数太多。
-
客户端和数据库连接数过小,会限制sql的查询并发数,增大连接数可以提升速度。
-
innodb里会有一层内存buffer pool用于提升查询速度,命中率一般>99%,如果低于这个值,可以考虑增大buffer pool的大小,这样也可以提升速度。
索引相关的问题,一般能用explain命令帮助分析。通过它能看到用了哪些索引,大概会扫描多少行之类的信息
1.合理的利用覆盖索引和最左前缀匹配原则优化,减少回表查询 当explain的输出结果extra字段为using index ,能触发索引的覆盖
2.不用索引或者用的索引不符合我们预期这件事经常发生,索引失效的场景有很多,比如用了不等号,隐式转换等,比如id_no字段类型为varchar,但在SQL语句中使用了int类型,导致全表扫描。
3.有些sql,用explain命令看,明明是走索引的,但还是很慢,可能是索引中匹配到的数据太大,这时候需要关注的是explain里的rows字段了
4.实际开发中有些情况比较特殊,比如有些数据库表一开始数据量小,索引少,执行sql时,确实使用了符合你预期的索引。但随时时间边长,开发的人变多了,数据量也变大了,甚至还可能会加入一些其他重复多余的索引,就有可能出现用着用着,用到了不符合你预期的其他索引了。从而导致查询突然变慢。可以通过force index指定索引
如:SELECt * FROM roles FORCE INDEX (`idx_user_role`) where username='nacos'
4.聚簇索引和非聚簇索引、innoDB和MylSM聚簇索引将数据存储和索引放到了一块,并且是按照一定的顺序组织的,找到索引也就找到了数据
非聚簇索引,叶子节点不存储数据,存储的是数据行的地址
innoDB中一定有主键,主键一定是聚簇索引(索引的数据域存储了数据本身),辅助索引的数据域存储了主键的值,因此从辅助索引查找数据,先通过辅助索引找到主键值,再访问数据本身,支持事务,支持外键,支持行锁定,不存储总行数
mylsm使用的是非聚簇索引,索引文件的数据域存储指向数据文件的指针。辅助索引和主索引基本一致,但是辅助索引不能保证唯一性,不支持事务,不支持外键,不支持行锁定
4.mysql索引类型及对数据库性能的影响
1:普通索引:MySQL中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值,纯粹为了查询数据更快一 点。
2:唯一索引:索引列中的值必须是唯一的,但是允许为空值。
3:主键索引:是一种特殊的唯一索引,不允许有空值。(主键约束,就是一个主键索引)。
4:组合索引:在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀集合
可以加大数据的检索速度,使用优化隐藏器,提高系统性能
但是会减低插入删除更新的速度,额外占用物理空间
5.主键索引与唯一索引的区别:1. 主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。
2. 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。
3. 唯一性索引列允许空值,而主键列不允许为空值。
4. 主键索引在创建时,已经默认为非空值+ 唯一索引了。
5. 一个表最多只能创建一个主键索引,但可以创建多个唯一索引。
6. 主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。
7. 主键可以被其他表引用为外键,而唯一索引不能。
适合做索引
1、适合索引的列是出现在where子句的列
2、基数较小的表,索引较差的表,没必要建立索引
3、使用短索引,如果对长字符串列表进行索引,应该指定一个前缀长度
4、不要过度索引
5、有外键的数据列一定要建立索引
不适合做索引
1、更新频繁的字段不适合做索引
2、不能有效区分数据的列不适合做索引
3、尽量扩展索引,不要新建索引
4、对于查询中很少出现的列,重复比较多的列不适合建立索引
5、对于text、image的数据类型的列不要建立索引
7.MySQL 索引失效的场景!1、在联合索引的场景下,查询条件不满足最左匹配原则
2、索引列参与了运算,会导致全表扫描,索引失效。
3.、索引列参与了函数处理,会导致全表扫描,索引失效。
4 、参数类型与字段类型不匹配,导致类型发生了隐式转换,索引失效。
5 、模糊查询时(like语句),模糊匹配的占位符位于条件的首部。
6、查询条件使用or关键字,其中一个字段没有创建索引,则会导致整个查询语句索引失效;or两边为“>”和“<”范围查询时,索引失效。
7、两列数据做比较,即便两列都创建了索引,索引也会失效。
8、查询条件使用is null时正常走索引,使用is not null时,不走索引。
9、查询条件使用not in时,如果是主键则走索引,如果是普通索引,则索引失效。
10、当查询条件为大于等于、in等范围查询时,根据查询结果占全表数据比例的不同,优化器有可能会放弃索引,进行全表扫描。
8.如何查看mysql执行计划执行计划就是sql的执行查询的顺序,以及如何使用索引查询,返回的结果集的行数
EXPLAIN SELECt * from A where X=? and Y=?
1. id :是一个有顺序的编号,是查询的顺序号,有几个 select 就显示几行。id的顺序是按 select 出现
的顺序增长的。id列的值越大执行优先级越高越先执行,id列的值相同则从上往下执行,id列的值为
NULL最后执行
2.type:优化sql的重要字段,也是我们判断sql性能和优化程度重要指标。他的取值类型范围:
const:通过索引一次命中,匹配一行数据
system: 表中只有一行记录,相当于系统表;
eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配
ref: 非唯一性索引扫描,返回匹配某个值的所有
range: 只检索给定范围的行,使用一个索引来选择行,一般用于between、<、>;
index: 只遍历索引树;
ALL: 表示全表扫描,这个类型的查询是性能最差的查询之一。 那么基本就是随着表的数量增多, 执行效率越慢。
执行效率:
ALL < index < range< ref < eq_ref < const < system。最好是避免ALL和index
3.key:此字段是 mysql 在当前查询时所真正使用到的索引。 他是possible_keys的子集
4.extra
using filesort :表示 mysql 对结果集进行外部排序,不能通过索引顺序达到排序效果。一般有
using filesort : 都建议优化去掉,因为这样的查询 cpu 资源消耗大,延时大。
using index: 覆盖索引扫描,表示查询在索引树中就可查找所需数据,不用扫描表数据文件,往
往说明性能不错。
using temporary:查询有使用临时表, 一般出现于排序, 分组和多表 join 的情况, 查询效率不
高,建议优化。
using where :sql使用了where过滤,效率较高。
5.rows:mysql 查询优化器根据统计信息,估算该sql返回结果集需要扫描读取的行数,这个值相关重要,索引优化之后,扫描读取的行数越多,说明索引设置不对,或者字段传入的类型之类的问题,说明要优化空间越大
9.Mysql主从同步原理
1.当 master 主服务器上的数据发生改变时,则将其改变写入二进制事件日志文件中(bin-log⽇志)
2.salve 从服务器会在一定时间间隔内对 master 主服务器上的二进制日志进行探测,探测其是否发生过改变,如果探测到 master 主服务器的二进制事件日志发生了改变,则开始一个 I/O Thread 请求 master 二进制事件日志
3.同时 master 主服务器为每个 I/O Thread 启动一个dump Thread,用于向其发送二进制事件日志
4.slave 从服务器将接收到的二进制事件日志保存至自己本地的中继日志文件中(relay log)
5.salve 从服务器将启动 SQL Thread 从中继日志中读取二进制日志,在本地重放,使得其数据和主服务器保持一致;
最后 I/O Thread 和 SQL Thread 将进入睡眠状态,等待下一次被唤醒
注意:主从复制的过程会有很小的延迟,基本没有影响,主从节点使用binlog+position偏移量来定位主从同步的位置,当从节点保存其已经接受到的偏移量,如果从节点发生宕机重启,则会自动从position的位置发起同步
什么是rabbitmq、使用RabbitMQ有什么好处、rabbitmq应用的场景
rabbitmq有哪些重要的组件
如何确保消息不丢失
消息怎么路由?
如何避免消息重复投递或重复消费
rabbitmq死信队列和延迟队列
rabbitmq镜像队列机制
在并发情况下,elasticsearch 如何保持读写一致
elasticsearch 中倒排索引是什么
描述一下elasticsearch搜索的过程
elasticsearch 了解多少,说说你们公司 es 的集群架构,索引数据大小,分片有多少,以及一些调优手段 。
springmvc工作流程
说说aop和ioc原理
分布式id生成方案
分布式锁解决方案
分布式事务解决方案
如何实现接口的幂等性
双亲委派模型
jvm垃圾回收机制
springboot常见注解
为什么用线程池、解释下线程池参数、线程池拒绝策略
简述下线程池处理流程
cpu占用率100%怎么解决
线程数过多怎么解决
ArrayList和LinkedList区别
Java面向对象三大特性
常见的设计模式
Springcloud 使用了哪些组件



