面试题
基础
1. java如何实现线程安全?
同步代码块
同步方法
2. CAS是什么,如何解决ABA问题?
使用AtomicStampedReference类,AtomicMarkableReference类
3. AtomicInteger的原理?
AtomicInteger内部声明了一个volatile修饰的变量value用来保存实际值
函数中调用了Unsafe函数的getAndAddInt方法
4. 可重入锁是什么,非可重入锁又是什么?
可重入锁:在同一个线程中,可以重复获取同一个锁,不会造成死锁
非可重入锁:在同一个线程中,获取锁的次数大于1,会造成死锁
5. 生产者消费者问题,一个长度100的buffer,10个生产线程,10个消费线程?
使用BlockingQueue实现生产者消费者问题,BlockingQueue有四种实现方式,分别是ArrayBlockingQueue,LinkedBlockingQueue,SynchronousQueue,PriorityBlockingQueue
ArrayBlockingQueue:基于数组实现的有界阻塞队列,容量大小是固定的,生产者线程和消费者线程都需要等待
SynchronousQueue:不存储元素的阻塞队列,每个插入操作必须等待一个相应的删除操作,反之亦然,容量大小是无限的
LinkedBlockingQueue:基于链表实现的有界阻塞队列,容量大小是可配置的,生产者线程和消费者线程都需要等待
PriorityBlockingQueue:基于优先级堆实现的无界阻塞队列,容量大小是无限的
6. Spring,AOP是什么,IOC是什么?
Spring是一个轻量级的Java开发框架,它提供了IOC和AOP功能,IOC是控制反转,AOP是面向切面编程,通过配置的方式,可以将一些通用的功能模块化,从而实现代码的重用,提高代码的可维护性
IOC是Spring的核心概念,它通过依赖注入(DI)来实现对象的创建和依赖关系的管理,通过配置的方式,将对象之间的依赖关系进行解耦,从而实现松耦合的设计
AOP是面向切面编程的一种技术,通过配置的方式,可以将一些通用的功能模块化,从而实现代码的重用,提高代码的可维护性
Spring的核心思想是“约定优于配置”,通过配置的方式,可以实现对象的创建,依赖关系的管理,以及一些通用的功能的模块化,从而实现松耦合的设计
7. 什么是Spring Boot,它有什么优点?
Spring Boot是一个快速开发的脚手架,它简化了Spring应用的初始搭建以及开发过程,提供了各种开箱即用的功能模块,使得开发人员可以更专注于业务逻辑的开发,提高开发效率
Spring Boot的优点:
快速启动:Spring Boot通过内嵌的Tomcat或Jetty等服务器,可以快速启动应用,无需部署war包
内置Tomcat/Jetty:Spring Boot内置了Tomcat和Jetty服务器,无需安装额外的服务器软件
无需XML配置:Spring Boot使用Java配置,不需要编写复杂的XML文件
自动配置:Spring Boot会根据应用所需的依赖来自动配置Spring,从而简化了Spring的配置
无代码生成:Spring Boot使用注解来代替XML配置,可以使得配置更加简单,无需编写大量的代码
内置监控:Spring Boot提供了Actuator模块,可以对应用进行实时的监控,如查看应用的健康状态,查看应用的统计数据,查看应用的日志等
8. TCP三次握手的过程,重发报文的过程
9. TCP和UDP的区别
10. MySQL的事务特性,事务隔离级别,分别解决什么问题
11. 间隙锁是什么,具体什么时候会加锁
12. java里的锁,有哪几种?
13. ReentrantLock有哪些特性?可重入是如何实现的?
MySQL面试题
1. 什么是 CTE?什么场景用递归 CTE?
- CTE(公共表达式):临时结果集,让 SQL 更清晰。
- 递归 CTE:专门查询树形结构、层级结构。
场景:
部门树、菜单树、地区树、评论树、BOM 结构。
2. 写一个递归查询部门树(最高级到最低级)
表:dept(id, name, parent_id)
1 | WITH RECURSIVE dept_tree AS ( |
3.如何查看 MySQL 执行计划?看哪些关键字段?
1 | EXPLAIN SELECT ... |
重点看:
- type:最好是 const /ref/range,最差 ALL(全表扫描)
- key:是否命中索引
- rows:扫描行数越少越好
- Extra:不要出现 Using filesort、Using temporary
4.Using filesort 是什么?怎么优化?
- 表示排序没有用到索引,MySQL 在内存 / 磁盘排序。
- 优化:
- 给 ORDER BY 字段建索引
- 避免 SELECT *
- 避免大结果集排序
5. 一条 SQL 很慢,你怎么排查?
- 看是否全表扫描(EXPLAIN type: ALL)
- 看是否没走索引
- 看是否有Using filesort / Using temporary
- 看联表是否小表驱动大表
- 看是否数据量太大,需要分页 / 分库分表
- 看是否锁等待
6. 索引失效的常见原因?
- 索引列使用函数:
YEAR(create_time) - 隐式类型转换:
varchar字段用数字查询 - 模糊查询以
%开头 - OR 条件中有非索引列
- 联合索引不满足最左前缀原则
7. MySQL 锁等待是什么原因?
- 一个事务持有锁,另一个事务等待锁释放,造成阻塞。
- 常见:
- 事务过大、执行时间太长
- 没加索引,导致行锁变表锁
- 热点行更新(秒杀、库存)
8. 如何优化锁等待?
- 给更新条件加索引,避免行锁变表锁
- 事务拆小,快开快提交
- 避免更新热点行
- 降低隔离级别(RC 比 RR 锁压力小)
- 避免长事务、避免在事务中做外部调用
9. 如何定位线上慢查询?
- 开启慢查询日志(slow_query_log)
- 用
show processlist看耗时 SQL - 用
EXPLAIN分析执行计划 - 优化索引、优化 SQL 逻辑、拆大事务
10. 联表查询优化原则?
- 小表驱动大表
- 关联字段必须建索引
- 只查需要的字段,不要 SELECT *
- 尽量用 INNER JOIN 代替 LEFT JOIN(如可行)
- 避免大结果集,必须分页