面试题总结

*** 索引失效情况

1 字段添加函数、计算操作
2 数字隐式转换 如varchar不加单引号的话可能会自动转换为int型
3 不等查询
4 当全表扫描用时少于索引用时[一般查询数据大于总量的30%的时候就会不走索引了]
5 like 以%开头
6 联合索引没有遵循最左原则
7 or 联合查询字段没有全部建立索引
8 在索引列上使用 IS NULL 或 IS NOT NULL操作

*** 事务传播情况

1 PROPAGATION_REQUIRED 如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。

2 PROPAGATION_SUPPORTS 如果存在一个事务,则支持当前事务。如果没有事务则以非事务运行。

3 PROPAGATION_MANDATORY 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。

4 PROPAGATION_REQUIRES_NEW 它会开启一个新的事务。如果一个事务已经存在,则先将这个存在的事务挂起。

5 PROPAGATION_NOT_SUPPORTED 总是非事务地执行,并挂起任何存在的事务。

6 PROPAGATION_NEVER 总是非事务地执行,如果存在一个活动事务,则抛出异常。

7 PROPAGATION_NESTED 外层事务失败会回滚内外层所有事务 内层事务失败即PROPAGATION_NESTED 事务失败 则只回滚内层事务
如果单独调用PROPAGATION_NESTED 方法,则按REQUIRED 第一种事务传播方式 执行

有 支持 没有 开启

有 支持 没有 没有

有 支持 没有 异常

直接开启 有 挂起

直接以非事务运行 有 挂起

直接以非事务运行 有 异常

*** 事务不受控制情况

编程式事务 在代码中显式的编写事务代码 缺点代码侵入严重

声明式事务 spring注解

1 如果你的数据库引擎不支持事务,再怎么使用事务注解也是没用的,就像MySQL的MyISAM引擎是没有事务的。

2 没有被spring管理的类 即使方法中使用了事务注解@Transactional 也是不被控制的

3 方法不是public的 因为jdk代理和cglib代理都无法代理private 方法 可以开启 AspectJ 代理模式

*** springboot常用注解

@springbootApplication

@Configuration

@EnableAutoConfiguration

@ComponentScan

*** select count(*) 和 select count(字段) 区别

count(字段) 不包含NULL

count(*)

  • MYISAM mysql进行了优化效率很高 MyISAM做了一个简单的优化,把表的总行数单独记录下来,
    如果执行count(*)时可以直接返回,前提是不能有where条件。MyISAM是表级锁,不会有并发的行操作,所以查到的结果是准确的。
  • InnoDB中索引分为聚簇索引(主键索引)和非聚簇索引(非主键索引),聚簇索引的叶子节点中保存的是整行记录,
    而非聚簇索引的叶子节点中保存的是该行记录的主键的值。MySQL会优先选择最小的非聚簇索引来扫表。
  • COUNT(1) 和 count(*) 优化是一样的

*** IO多路复用

*** JVM垃圾回收器都有哪些

  • 判断对象是否为垃圾的算法:a> 引用计数 【循环引用问题】 b> 可达分析

  • 垃圾回收算法:

    a> 标记清除 容易产生内存碎片

    b> 复制算法 对内存空间的使用做出了高昂的代价 opying算法的效率跟存活对象的数目多少有很大的关系,如果存活对象很多,那么Copying算法的效率将会大大降低

    c> 标记整理 完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存

    d> 分代收集 分为新生代和老年代 新生代分为1个Eden区 和 2个相同大小Surviver 新生代采用复制算法 eden和一个surviver 复制到另一个空闲的surviver中

             老年代采用 标记-整理 算法
    
  • 垃圾回收器:

-------------------------------↓↓↓↓以上为新生代回收器↓↓↓↓----------------------------------------

a> serial收集器 最基本发展时间最长 单线程 工作时其他全部运行代码停止 采用复制算法 

b> ParNew收集器 是serial收集器的多线程版本 工作时其他全部运行代码停止 复制算法

c> Parallel Scavenge 收集器 自动调节内存参数 达到吞吐量的最优 复制算法

-------------------------------↑↑↑↑以上为新生代回收器↑↑↑↑----------------------------------------

-------------------------------↓↓↓↓以上为新生代回收器↓↓↓↓----------------------------------------

d> Serial Old 收集器 单线程 工作在老年代 使用标记-整理 算法 


e> Parallel Old 多线程收集器 标记-整理 算法 

f> CMS收集器 并发收集、低停顿。先使用标记-清除算法 多少次后为了避免内存碎片 再使用复制算法

-------------------------------↑↑↑↑以上为新生代回收器↑↑↑↑----------------------------------------

`
g> G1收集器

	g.1> G1能充分利用多CPU、多核环境下的硬件优势,使用多个CPU来缩短Stop-The-World停顿时间
	
	g.2> 其他收集器的工作范围是整个新生代或者老年代、G1收集器的工作范围是整个Java堆


    JAVA 11 包含一个全新的垃圾收集器--ZGC,它由Oracle开发,承诺在数TB的堆上具有非常低的暂停时间。 JAVA 11 默认垃圾回收器是G1

*** JVM 内存模型

  • 程序计数器 线程私有 每个线程都有会有个程序计数器内存 记录着当前要执行的代码行号
  • 栈 每个方法在执行的时候也会创建一个栈帧,存储每个方法的局部变量 方法返回地址等
  • 堆 被所有线程共享的一块内存区域,在虚拟机启动的时候创建,用于存放对象实例
  • 方法区 被所有方法线程共享的一块内存区域。用于存储已经被虚拟机加载的类信息,常量,静态变量等。
  • 本地方法栈 线程私有 存放本地方法

*** mybatis ${}和#{}的区别

  • ${}是字符串拼接,不但’’ 条件查询时 字符串类型 需要手动拼接’'没有sql预编译 可以sql注入

  • #{}是占位符,自动添加’’ 执行语句经过预编译 可以防止sql注入

  • 查询语句表名为参数时和 order by字段为参数时 必须用${}传递

  • 不论是单个参数,还是多个参数,一律都建议使用注解@Param("")

*** redis 数据类型

string list set hash sort

*** 线程同步的几种方法

  • synchronized、volatile、原子类【CAS】、lock、容器类、【concurrentHashmap】、ThreadLocal

  • synchronized 锁升级
    1 无锁 锁对象初始化时 是无锁状态
    2 偏向锁 只有一个线程执行加锁代码 此时当前加锁对象的mark world中存储为偏向锁信息
    3 轻量级锁 多个线程执行加锁代码 但在每个线程执行加锁代码时 从没有发生过竞争 导致另一个线程自旋
    4 重量级锁 多个线程执行加锁代码 并出现线程自旋超时 就会升级为重量级锁

    锁只会自动升级 不会也不能降级

  • volatile 保证内存可见性 但不能保证原子性,保证指令重排序的一致性

  • 原子类 AtomicInteger等底层原理为 CAS 原子类会有ABA问题 可以用AtomicStampedReference 解决

  • 如果是 JDK8,推荐使用 LongAdder 对象,比 AtomicLong 性能更好(减少乐观锁的重试次数)。
    使用AtomicLong时,在高并发下大量线程会同时去竞争更新同一个原子变量,但是由于同时只有一个线程的CAS会成功,
    所以其他线程会不断尝试自旋尝试CAS操作,这会浪费不少的CPU资源。而LongAdder可以概括成这样:内部核心数据value分离成一个数组(Cell),
    每个线程访问时,通过哈希等算法映射到其中一个数字进行计数,而最终的计数结果,则为这个数组的求和累加。简单来说就是将一个值分散成多个值,
    在并发的时候就可以分散压力,性能有所提高。

*** class文件装配过程

  • 加载 --> 连接 --> 初始化

         |  |
       |      |
     |          |
    

    验证–>准备–>解析

1> 加载

 将class字节码加载到jvm中 主动加载和被动加载  
 
 主动加载 : new、反射、初始化子类必先初始化父类 没动加载 不会执行初始化 子类调用父类的变量、final常量不会初始化

2> 连接

 2.1> 验证 : 格式检验【魔数、版本、长度检验】

 2.2> 准备 : 为类分配空间 变量设置为初始值 final常量初始化完成

 2.3> 解析 : 解析阶段的任务就是将类、接口、字段和方法的符号引用转为直接引用

3> 初始化

 初始化阶段的重要工作是执行类的初始化方法 它是由类静态成员的赋值语句以及static语句块合并产生的。父类的static块先于子类的static块

*** 类加载器分类和加载范围

  • 根类加载器 加载rt包下的class

  • 扩展类加载器 加载ext包下的class

  • 系统类加载器 加载用户写的class classpath下的class

  • JVM的类加载机制主要有如下3种

    1> 全盘负责制 所谓全盘负责,就是当一个类加载器负责加载某个Class时,该Class所依赖和引用其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入。

    2> 双亲委派 则是先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类

    3> 缓存机制。缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区中搜寻该Class,

    只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓冲区中。

    这就是为什么修改了Class后,必须重新启动JVM,程序所做的修改才会生效的原因

*** 为什么MyISAM比Innodb引擎查询快

  • MyISAM 插入、修改、删除没有事务 不需要维护行锁,不需要维护redo、undo log

  • MyISAM 索引记录的事数据地址引用 InnoDB 普通索引记录的是主键 需要二次回表查询

  • MyISAM 只会缓存索引不会缓存数据

  • MyISAM 索引开启了压缩索引【前缀压缩】 单位页查询数据更多 默认只压缩字符串 压缩索引的倒序扫描会更慢

*** Innodb引擎和MyISAM 引擎 存储文件分别是什么

  • Innodb 存储包含两个 frm文件【表空间】 IBD文件【主键和数据结合的聚簇索引】

  • MyISAM 包含三个文件 frm【表空间】 MYI [索引文件] MYD [数据文件]

*** mysql explain 分析过程

共10个分析项

  • id id值越大越先执行 相同值 按从上到下执行顺序

  • select_type

    1> simple 不带union或子查询的查询

    2> PRIMARY(子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY)

    3> UNION(UNION中的第二个或后面的SELECT语句)

    4> SUBQUERY(子查询中的第一个SELECT,结果不依赖于外部查询)

    5> DERIVED(派生表的SELECT, FROM子句的子查询)

  • table

    显示这一步所访问数据库中表名称(显示这一行的数据是关于哪张表的),有时不是真实的表名字,可能是简称,例如上面的e,d,也可能是第几步执行的结果的简称

  • partitions

    使用分区的哪部分

  • type

    下面的类型 从上到下性能越来越好

    1> ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

    2> index: Full Index Scan,index与ALL区别为index类型只遍历索引树

    3> range:只检索给定范围的行,使用一个索引来选择行

    4> ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

    5> eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,

    就是多表连接中使用primary key或者 unique key作为关联条件

    6> const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,

    system是const类型的特例,当查询的表只有一行的情况下,使用system

    7> NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

  • possible_keys

    指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,

    但不一定被查询使用(该查询可以利用的索引,如果没有任何索引显示 null)

  • key

    key列显示MySQL实际决定使用的键(索引),必然包含在possible_keys中

    如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

  • key_len

    表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,

    即key_len是根据表定义计算而得,不是通过表内检索出的)。不损失精确性的情况下,长度越短越好

  • ref

    列与索引的比较,表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

  • rows

    估算出结果集行数,表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数

  • Extra

    该列包含MySQL解决查询的详细信息,有以下几种情况:

    Using where:不用读取表中所有信息,仅通过索引就可以获取所需数据,这发生在对表的全部的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤

    Using temporary:表示MySQL需要使用临时表来存储结果集,常见于排序和分组查询,常见 group by ; order by

    Using filesort:当Query中包含 order by 操作,而且无法利用索引完成的排序操作称为“文件排序”

    Using join buffer:强调了在获取连接条件时没有使用索引,并且需要连接缓冲区来存储中间结果。如果出现了这个值,那应该注意,根据查询的具体情况可能需要添加索引来改进能。

• EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况

• EXPLAIN不考虑各种Cache

• EXPLAIN不能显示MySQL在执行查询时所作的优化工作

• 部分统计信息是估算的,并非精确值

• EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值