面试问题记录4.6

又整理了一些面试遇到的问题,有一些待继续解决

sql语句的效率较低,如何排查(explain工具)

慢查询:在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL。会被记录到MySQL的慢查询日志
可以通过 slow_query_log 标志位置 true,将慢查询日志的记录动作开启
得到执行较慢的sql语句列表后,使用 explain 工具进行分析:

explain 待分析的SQL语句

会得到如下的一个执行结果:
在这里插入图片描述
在其中,会展示本条sql语句执行过程的相关信息,比较需要关注的如:
· key:表示 sql 语句命中的索引,如图 key = PRIMARY 表示命中了主键索引;若为NULL,则表示没有命中索引,使用了全表扫描;
· rows:表示执行过程扫描的条目数量,一定程度上可以反应执行时间,扫描条目对于执行时间的影响很大
(虽然创建索引对于查找可以有帮助,但并非所有命中了索引的查找都会很快,所以也需要关注 rows 参数反应的扫描条目数量)

InnoDB 上限 64TB 是为什么

InnoDB 的页号是一个 32bit 的 int 类型,一个页的大小是 16kb
所以总大小:2^32 * 16kb = 2^2*16 * 2^30kb = 64TB

是否看过MySQL中的锁机制的底层源码

性能划分:乐观锁、悲观锁
乐观锁:如 CAS
悲观锁:必须加锁,开销较大,如:for update

操作类型划分:读锁(共享锁)、写锁(排他锁)
读锁(共享锁):针对同一条目,读操作可以同时进行,但任何事务都不能进行
写锁(排他锁):获取排他锁的事务可进行读写操作。获取到写锁的事务未完成之前,会阻塞其他事务获取写锁或读锁。

粒度划分:行锁、页锁、表锁
行锁
定义:只对当前正在操作的条目进行加锁
方法:共享锁和排他锁
特点:大大减少数据库操作冲突;加锁粒度最小,开销大;有可能会出现死锁的情况,出现死锁的解决办法就是必须有一方事务回滚或者同时回滚;

页锁
定义:行锁和表锁的一种折衷做法,对当前正在操作条目相邻的一段数据进行加锁
特点:数据库操作冲突不至于过多,加锁开销也不至于过大

表锁
定义:表示当前的操作对整张表加锁
方法:元数据锁(Metadata Lock,MDL)、表锁
特点:发生锁冲突的概率很大;资源开销较少;不会出现死锁的情况
元数据锁:一种读写锁,读操作不互斥,读写、写操作之间互斥,写锁优先级 > 读锁优先级,事务结束才会释放

Bean生命周期

核心生命周期:实例化 —— 属性赋值 —— 初始化 —— 销毁
可以理解为如下:
1、BeanDefinition 的解析,注册,合并
2、Bean 实例化,此时还没有调用构造函数生成对象
3、Bean 属性赋值,查找 @Autowired 和 @Value 标注的方法或属性,进行依赖注入
4、Bean 初始化,已经生成 bean,进行属性赋值
5、Bean销毁,此时并不会触发 gc

AOP的理解

即面向切面编程,作为面向对象的一种补充,将与业务无关的公共行为和逻辑进行抽取和封装,作为一个可重用的模块,该模块即“切面”
经典实现:AspectJ
场景:日志记录,性能统计,安全控制,事务处理,异常处理等
作用:减少重复代码,降低模块间的耦合度,提高可维护性。
【待补充】

拦截器与过滤器的区别、使用

原理:
过滤器:基于回调函数;
拦截器:基于 Java 反射机制(动态代理)。

使用范围:
过滤器:Servlet 规范,需要实现 javax.servlet.Filter 接口,由 Servlet 容器管理,依赖 Tomcat 等容器;
拦截器:Spring 组件,定义在 org.springframework.web.servlet 包下,由 Spring 容器管理,所以有更加丰富的生命周期处理方法,细粒度,且能够使用 Spring 中的资源,不依赖 Tomcat 等容器。

触发时机:
过滤器:Tomcat 容器与 Servlet 之间触发;
拦截器:Servlet 与 Controller 之间触发。

执行顺序:
过滤前——拦截前——action执行——拦截后——过滤后

桶排序

应用场景:
数据量大、整体数值范围已知、分布较均匀
以大量学生的成绩(0~100)排序为例。

排序算法:
设定桶的数量,一般按均匀划分,如将成绩划分为10个桶,分别存放的成绩区间为:0-10、11-20、…、91-100;
排序时,将当前成绩划分到所属的桶,将属于一个桶的数值用链表存储;
当有新的数值来到该桶,使用插入排序维护链表的排序关系;
最后将每个桶的数据按链表顺序取出,即可得到整体的排序结果。

特点:
感觉桶排序类似于插入排序,区别在于先将待排数据划分为小的数据集,再分别进行插入排序。是一种空间换时间,来降低时间复杂度的感觉
时间复杂度最好可以接近 O(N)
空间复杂度差不多在 O(N)
算法比较稳定

Full GC 什么情况触发

1、老年区空间不足;
2、Young GC的时候,若之前每次晋升到老年代的平均大小 > 老年代的剩余空间,会触发;
3、System.gc();
4、分配大对象,会直接进入老年区,若空间不足会触发

是否看过concurrent类底层代码、是否看过Java锁机制的底层代码

和锁的种类与底层实现有关,了解不多,只回答了这些
CAS 自旋,未竞争到则让出 CPU 时间片
synchronized 加锁,底层实现未知
【其余待补充】

大树递归会出现的问题

栈溢出
解决方法上,考虑进行更换,更换决策如:LRU、FIFO等

线程安全

在多线程执行计算机程序的时候,需要同步机制保证各个线程能够正确执行自己的逻辑,不会出现线程安全问题。

同步机制,即保证操作的原子性,可以利用锁机制、系统自带的原子操作、机器指令,如CAS。锁、synchronized 需要操作系统进行裁决,开销较大;CAS 原子操作在 CPU 级进行裁决,开销更小。

synchronized修饰不同类型:
非静态同步方法:锁住的是当前实例;
静态同步方法:锁住的是该类的Class对象;
静态代码块:锁住的是synchronized关键字后面括号内的对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值