来源:本笔记总结来自抖音的程序员K哥的《面试辅导》系列,我会给他点赞的,支持开放和共享精神,只会用于帮助自己和他人学习提高
抖音_程序员K哥的《面试辅导》系列笔记总结
- 面试题1:讲一下MySQL索引底层结构是什么?
- 面试题2:什么是回表?
- 面试题3:说一下项目中接触过的分库分表实际场景?
- 面试题11:说一下对高并发的理解
- 面试题12:线上如何处理高并发场景问题?
- 面试题14:线程池核心参数有哪些?
- 面试题15:线程提交任务的流程是什么?
- 面试题16:线程池里的任务如果在执行时抛出异常怎么办?
- 面试题17:核心线程和非核心线程的区别是什么?
- 面试题18:问一下常见的Linux命令
- 面试题19:如果有多条命令同时执行,怎么保证执行的原子性?
- 面试题20:什么是缓存穿透和解决方案
- 面试题23:一个变量Integer i,10个线程同时加1万次,最后结果是多少?
- 面试题24:MySQL事务的二阶段提交是什么?
- 面试题25:为什么MySQL要redo log?为什么不是直接写在磁盘上呢?
- 面试题26:说一下MySQL的隔离级别
- 面试题27:说一下MySQL解决了幻读的问题吗?
- 面试题28:MVCC知道吗?怎么实现的?
- 面试题29:Java中的集合类有哪些?
- 面试题30:HashMap线程安全吗?
- 面试题31:String,StringBuilder,StringBuffer的区别是什么?
- 面试题32:MySQL索引的底层数据结构有哪些?
- 面试题33:哈希索引的特点是什么?时间复杂度多少?
- 面试题34:索引失效的场景有哪些?
- 面试题35:为什么使用不等于符号会导致索引失效?
- 面试题36:聊一下通讯协议和网络分层
- 面试题37:说一下HTTP和GRPC协议之间有什么区别?
面试题1:讲一下MySQL索引底层结构是什么?
MySQL索引的底层数据结构是B+树
用B+树而不是用B树的原因是,B+ 树数据都存在叶子节点
好处有:
1.效率高
2.层高低减少IO查询次数,提高查询效率
3.叶子节点之间有链表链接,这种数据结构特别适合做范围查询
面试题2:什么是回表?
数据库首先会通过索引查找带索引的字段,但如果查到非索引字段需要再去主表中查对应字段,这个过程就是“回表”。
回表的工作原理
1.查询:用户发起一个查询,数据库优化器决定使用某个索引来加速查询。
2. 索引查找:系统首先在索引中查找满足条件的记录,索引通常只包含一部分列(如主键和部分索引列)。
3. 回表:由于索引中不包含查询所需的所有列,系统会根据索引中找到的记录位置,再去主数据表中检索完整的记录。
回表代价:回表往往会导致性能下降,因为它需要额外的读操作。
优化方法:为了减少回表,可以在索引中包含所有查询所需的字段,称为“覆盖索引”。这样,数据库只需访问索引,而不需要回到主表。
面试题3:说一下项目中接触过的分库分表实际场景?
比如某个业务节点主表,先做一个垂直切分:一个是主表,一个是状态表
因为主表数据量大且大部分数据基本是不变的
状态表是因为状态流转的比较多,增加和修改比较多
热点数据单独拆分作为一张表可以显著提高数据库的性能瓶颈
面试题11:说一下对高并发的理解
高并发考验一个服务瞬时间对大量并发请求的处理能力
核心参数有两个:QPS和TPS
第一个参数是QPS,QPS是每秒钟可以承担的请求数量
第二个参数是TPS,TPS是每秒能处理的事务数量
一般一个事务会包含多个请求,就是TPS会比QPS会小一点
面试题12:线上如何处理高并发场景问题?
事前:考虑代码和架构层的设计,包括批量处理,异步处理和缓存处理的选择
事中:简历完善的监控报警机制和响应措施
事后:线上事故的事后复盘,思考还可以做哪些优化
面试题14:线程池核心参数有哪些?
有七个
核心线程数
最大线程数
空闲时间
时间单位
工作队列
线程工厂
拒绝策略
面试题15:线程提交任务的流程是什么?
三个容器
先把任务提交到核心线程里
如果核心线程数达到上限,提交到等待队列
如果等待队列也满了,如果是有界队列会扩张线程池数量扩张直到达到最大线程数
面试题16:线程池里的任务如果在执行时抛出异常怎么办?
一:给调用方感知到
二:出现异常的线程没有被处理,则这个线程会被回收掉,线程工厂再生产个新线程
面试题17:核心线程和非核心线程的区别是什么?
本质区别是线程创建时间早晚的关系
核心线程是参数设置的常态线程,并没有做底层区分
面试题18:问一下常见的Linux命令
进入指定文件夹 cd
创建文件 touch
创建文件夹 mkdir
查询定时日志 tail -f
查看历是日志 grep 管道符号
启动jar包,后台运行指定打印日志到指定文件 nohup java-jar jar包名字 > 日志文件名 &
查询CPU或内存使用情况 top或free
查询端口占用 lsof -i
查询网络连接 ping
打包解压缩包 jar -cvf jar -xvf 或者 tar -cvf tar -xvf
面试题19:如果有多条命令同时执行,怎么保证执行的原子性?
可以用Lua脚本
面试题20:什么是缓存穿透和解决方案
场景是大量的qps请求过来,造成缓存效果不够理想,把数据库压垮的情况
解决方案:
1.对恶意请求进行过滤,可以加一个白名单,用户的风控校验
2.加锁限制,尽量同一时刻较少线程可以去数据库查询,其他线程等待
面试题23:一个变量Integer i,10个线程同时加1万次,最后结果是多少?
最后结果:小于等于10万
因为加1的操作不是原子性的,其实执行了三个步骤:
1.CPU高速缓存会从主存中把这个数据拿出来
2.继续一个加1操作
3.然后把这个数据返回更新到主存中
这三步不是原子性操作,可能有并发问题,最后可能导致这个数少加了,所以结果是可能小于等于10万
面试题24:MySQL事务的二阶段提交是什么?
先从一条sql的执行流程说起,
最开始先写一个buffer Pool,就是MySQL的内存缓存
第二个写undo log,是我们一个事务的数据版本链
第三个会到一个数据的两阶段提交操作
会先写redo log(重做日志)做一个事务的预处理
再写bin log(二进制日志)
等bin log写完之后再进行一个redo log的事务二阶段提交
面试题25:为什么MySQL要redo log?为什么不是直接写在磁盘上呢?
因为数据是随机分布在磁盘上的,磁盘的随机写效率是很低的
而redo log是一个顺序写的物理日志,所以它的效率是很高的
顺序写的会比随机写的效率高几百倍
面试题26:说一下MySQL的隔离级别
4个 读未提交,读已提交,可重复读,序列化
读未提交的问题是脏读
读已提交的问题是不可重复读
可重复读的问题是幻读,虚读的问题
序列化的问题是效率太低了
面试题27:说一下MySQL解决了幻读的问题吗?
MySQL在可重复度的隔离级别下实现了快照读,解决了幻读的问题
在可重复读隔离级别下,MySQL 中的间隙锁是通过如下方式实现的:
间隙锁:当事务 A 查询某个范围的数据时,MySQL 会对该范围内的间隙加锁,防止其他事务在该范围内插入新记录。这意味着即使其他事务尝试插入数据,事务 A 的查询结果也不会受到影响。
下一键锁(Next-Key Locking):MySQL 在执行范围查询时,通常会对每个行记录及其前面的间隙加锁,这种方式称为下一键锁。这种锁定机制有效防止了幻读的发生。
MySQL 通过使用可重复读隔离级别和 MVCC 机制,结合间隙锁等技术,有效地解决了幻读问题
面试题28:MVCC知道吗?怎么实现的?
MVCC是分版本并发控制 最关键的点是read-view 读视图
读视图的4个关键核心参数是:
1.当前最大事务ID
2.当前最大的已经提交的事务ID
3.当前活跃的事务列表
4.当前的事务ID
通过read-view读视图和undo log事务的版本链进行一个对比
然后选择需要读取的数据,这就是MVCC的机制
使用MVCC可以让读操作不需要加锁,从而提高并发性。在这种机制下,每个事务会读取自己版本的数据,确保读取到的是最新提交的版本
面试题29:Java中的集合类有哪些?
一个是Collection,分为List和Set
一个是Map,分为 HashMap,HashTable,TreeMap,ConcurrentHashMap
ArrayList底层是动态数组,JDK8后底层是数组+链表+红黑树,有索引下标适合查询
LinkedList底层是双向链表,适合增删修改操作
面试题30:HashMap线程安全吗?
不
并发使用会出现一个fail-fast机制,也就是并发修改异常
可以用HashMap:底层是加Synchronized,效率较低,JDK8有锁优化,锁消除锁粗化和锁升级
可以用ConcurrentHashMap,底层是乐观锁+Synchronized来保证线程安全
面试题31:String,StringBuilder,StringBuffer的区别是什么?
String是不可变类,每次修改会不断创建新的对象
有两个缺点:1.效率低 2.消耗内存大
StringBuilder是对String使用场景的优化,底层支持动态字符串修改
StringBuffer是对StringBuilder的优化,底层加Synchronized锁同步机制来支持字符串并发修改
面试题32:MySQL索引的底层数据结构有哪些?
最常见的是B+树和哈希表
面试题33:哈希索引的特点是什么?时间复杂度多少?
哈希索引特点是键值对存储,Key-Value
最快时间复杂度是O(1),平均是O(logn)
面试题34:索引失效的场景有哪些?
左模糊查询%like,where里使用函数,使用or,用不等于符号
面试题35:为什么使用不等于符号会导致索引失效?
MySQL优化器会进行过滤,如果用不等于过滤出来的数据量比较少
MySQL优化器会觉得使用索引还不如直接全表扫描
在explain执行计划上体现出来的就是索引失效
但更准确的说法是MySQL优化器自主进行了底层的查询优化
面试题36:聊一下通讯协议和网络分层
通讯协议是数据交互的规范
比如收发数据的双方定好一些编解码规则然后进行网络传输
比如TCPIP协议
TCPIP协议分为四层:
1.应用层:指定具体传输协议和格式比如HTTP,高性能GRPC和Dubbo协议
2.传输层:定位到具体端口号,进行主机进程间通信,更具体的定位
3.网络层:对物理地址进一步抽象和聚合,每个计算机都用MAC地址
4.数据链路层:解决物理层面寻址的问题,通过光纤进行0和1数据传输
OSI协议:7层
1.应用层 2.表示层 3.会话层 4.传输层 5.网络层 6.数据链路层 7.物理层
为什么要进行分层设计?
分层设计可以划分各层职责和解耦
底层细节对上层屏蔽,上层不用了解底层细节和变化
面试题37:说一下HTTP和GRPC协议之间有什么区别?
相同点是:这两个都是应用层的传输协议
HTTP 1.0 是文本协议,可读性高,但效率低
GRPC基于HTTP 2.0 是一个二进制协议,可读性低,但传输效率十分高
效率高的原因有两个:
1.传输的是二进制数据
2.提前定义了一个二进制序列化(protobuf)文件,接口提供方和调用方公用这一份文件,
我们可以提前知道数据顺序和字段的业务含义,按照之前约定去处理数据就好,节省了很多描述数据的空间