面试重点难点


JVM内存模型

对象一定存在堆里面吗

成员变量(类中的变量)一定在堆中分配,局部变量(方法中的变量)中,如果是基本类型,则在栈中分配,如果是引用类型,需要满足一下三点:方法调用频次高,是热点代码;通过逃逸分析判断该对象不能从方法(线程)中逃逸,也就是不会被其他线程使用;同时该对象(聚合量)可以被标量替换

泛型有什么作用

  1. 作用在类上,一般该类是作为容器使用,例如List,如果没有泛型,则可以存储不同类型的对象,取出使用的时候就需要进行类型的强转,可能出现类型转换异常;如果使用泛型对其进行限制,编译器就会对存入的对象类型进行检查,保证存入和取出时成员类型的一致,同时也避免了强转可能造成的不安全性

  2. 作用在方法上一般是为了实现方法的复用

explain怎么用

system > const > eq_ref > ref > range > index > all;[MySQL高级](一) EXPLAIN用法和结果分析mysql explain王洪玉的博客-CSDN博客

索引失效的情况

  1. 语句中有OR,则所有where条件中的字段都建有索引才会走索引,否则全表扫描

  2. like条件中%在前,如果这个字段有索引,且只查询这个字段,则走索引,如果查询的还有其他字段,则会回表,不走索引

  3. 字符串类型的字段作为查询条件时一定要带引号,否则会造成索引失效

  4. 索引列参与计算或是使用了函数,则索引会失效

  5. not in ,not exist.

  6. 违背最左匹配原则

  7. 索引失效的情况及解决(超详细)_zyy_demon的博客-CSDN博客

建立索引的原则

  1. 优先选择唯一性索引

  2. 为经常需要查询、排序、分组和联合操作的字段建立索引

  3. 避免创建非必要的索引

  4. 尽量使用数据量少的索引

  5. 最左前缀匹配原则,非常重要的原则。

  6. 尽量选择区分度高的列作为索引。

  7. 索引列不能参与计算,保持列“干净”。

  8. 尽量的扩展索引,不要新建索引。

  9. 当单个索引字段查询数据很多,区分度都不是很大时,则需要考虑建立联合索引来提高查询效率

LEFT JOIN与RIGHT JOIN的区别

  1. left join:以左表为主,能查到左表中所有数据和右表中相关联的数据,关联不到的的返回null

  2. right join:以右表为主,能查到右表所有数据以及左表中相关联的数据,关联不到的设为null

  3. inner join:返回的是两个表的交集

COUNT(1)、COUNT(*)、COUNT(字段)的区别

COUNT(*)=COUNT(1)>COUNT(字段),MyISAM中会直接把表的总行数单独记录下来供COUNT(*)查询,而InnoDB则会在扫表的时候选择最小的索引来降低成本。COUNT(字段)要进行全表扫描,判断指定字段的值是否为NULL,不为NULL则累加。

MySQL死锁

多条事务争夺资源过程中相互等待对方释放锁,若无外力作用,可能会持续等待下去。可使用show engine innodb status查找发生死锁的语句,定位程序中的位置

RocketMQ顺序消息

发送方发消息的时候使用MessageQueueSelected,让消息指定参数对对列数量取模,保证同一类型的数据发送到同一队列,此时数据在同一队列中是有序地,消费者则使用MessageListenerOrderly,他能保证同一个队列只会被同一个线程消费,然有多个消费者的情况下,此时只是实现了分区有序,若要全局有序,只需保证发消息时直接指定将所有消息发送到一个队列中即可,在MessageQueueSelected不进行取模操作,直接指定对列号,然这种情况会造成系统吞吐量大大降低,需谨慎

Redisson分布式锁的特点

  1. 使用Lua脚本写key以及设置过期时间,保证此操作的原子性

  2. 使用UUID+线程ID作为value,保证不同线程使用同一把锁时value不同,避免某个线程释放其他线程的锁

  3. 使用看门狗机制,单独拉出来一条线程用于监视加锁的线程是否执行完毕,没有完的话就延长锁的生存时间,避免方法执行时间大于锁的过期时间时锁被异常释放

线程池参数详解

Spring

Java常用集合容器

秒杀系统设计要点

  1. 前端页面静态化

  2. 前端页面防抖,防止连点

  3. NGINX和网关进行限流,防刷子

  4. 商品库存提前放入Redis,使用Redis原子操作扣减库存

  5. 库存扣减成功则发送MQ消息,生成订单

Mysql千万级数据快速分页查询方案

通过主键索引进行过滤,快速定位到指定数据

Mysql去重

查询结果去重主要是用distinct或group by关键字

删除重复数据可是使用inner join,自己与自己关联,关联条件是重复字段及ID较大者

eg:delete a.* from user_info as a inner join user_info as b on a.name = b.name and a.sex = b.sex and a.age = b.age and a.id > b.id;

支付异常处理

BigDecimal注意事项

  1. 直接使用构造函数传入双精度的数会造成精度丢失,因为双精度的数在计算机中本身就是无法表示的

  2. 比较两个BigDecimal值的大小,equals会比较精度,需要注意;建议使用compareTo方法

  3. toString方法会使用科学计数法,建议使用toPlainString

@Primary与@Qualifier

@Qualifier可与@Autowired搭配使用,可指定注入Bean的名称,@Primary放在相同类型的Bean其中一个上,注入时会优先注入他