Java 后端面试题汇总
Java 面试 About 6,025 words开场
- 自我介绍
- 掌握的技术栈
- 最近一个项目的架构和技术栈
- 近期做的项目
- 有什么亮点
- 有什么值得改进
Java 基础
- 面向对象有几大特性
Java
中有没有多继承(interface
)
JDK
新特性Java8
CompletableFuture
Lambda
Java9
- 模块化
String
底层由char[]
变为byte[]
Java10
- 类型推断:
var
关键字
- 类型推断:
Java11
JFR
HttpClient
Java15
ZGC
(Java11
开始预览)record
类(Java13
开始预览)- 文本块(
Java13
开始预览) - 禁用、弃用偏向锁
Java17
sealed
密封类(Java15
开始预览)
Java19
Virutal Thread
虚拟线程(开始预览)
hashCode
与equals
- 哪些地方用到了
HashMap key
是对象时switch string
时
- 哪些地方用到了
Java Collections
中的接口和实现类ArrayList
与LinkedList
区别List
集合去重HashSet
实现原理HashMap
实现原理final
关键字final
修饰的类有哪些(String
)- 匿名内部类引用局部变量,需要注意什么(必须
final
修饰) - 为什么匿名内部类引用外部局部变量必须要加
final
关键字 - 为什么匿名内部类引用外部局部变量不用加
final
也不报错
finally
- 什么时候执行
finally
代码块 - 什么时候不会执行
finally
代码块(问这个问题基本就是找茬)- 未进入
try
代码块:if
条件未进入、在try
之前return
、在try
之前异常 try
代码块中死循环try
代码块中退出虚拟机System.exit(0)
- 守护线程
run
方法中的finally
可能因为main
方法执行结束被终止而等不到执行
- 未进入
- 什么时候执行
StringBuffer
和StringBuilder
Java
反射优化- 类加载机制
- 类加载时,如何修改类(
Java Agent
)
- 类加载时,如何修改类(
多线程与并发
sleep
和wait
区别- 线程的几种状态
- 守护线程和非守护线程的区别
Thread
的join
方法的作用- 线程安全的集合类
CopyOnWriteArrayList
CopyOnWriteArraySet
ConcurrentHashMap
ConcurrentSkipListMap
ConcurrentSkipListSet
- 单机版的限流
ConcurrentHashMap
->computeIfAbsent()
方法。
- 如何停止一个线程
volatile
关键字- 可见性
- 有序性
- 什么情况下会发生指令重排序
- 不能保证原子性
- 懒汉式单例中,双重加锁为什么还要
volatile
- 如何保证原子性
- 创建线程池主要参数
- 何时创建非核心线程
- 核心线程中出现了异常,会怎么样
Java
中线程安全的类AtomicInteger
LongAdder
ConcurrentHashMap
/CopyOnWriteArrayList
实现原理ThreadLocal
- 注意事项
Thread.sleep(0)
作用
锁
JDK
中一共有几种锁synchronized
ReentrantLock
公平锁与非公平锁ReentrantReadWriteLock
读写锁StampedLock
读写锁,乐观锁CAS
自定义自旋锁- 如何避免
ABA
问题(AtomicStampReference
)
- 如何避免
ReentrantLock
公平锁与非公平锁实现上的区别synchronized
ReentrantLock
与synchronized
区别synchronized
重量级锁能否退化- 瞬时高并发接口使用哪个
- 什么场景会导致死锁
- 简述
AQS
AQS
实现类ReentrantLock
CountDownLatch
,原理CyclicBarrier
Semaphore
LockSupport
JVM
Java
启动时命令行参数有哪些Java
命令行启动参数添加的几种方式- 直接指定:
java -jar -Xmx50m
Dockerfile
:CMD
、Enrerpoint
Kubernetes
:Deployment
- 环境变量:
JDK_JAVA_OPTIONS
(仅对java
命令生效)、JAVA_TOOL_OPTIONS
(java
/javac
/jshell
等)
- 直接指定:
- 如何指定启动参数
- 语法糖
- 增强
for
循环原理- 数值
- 集合
- 自动拆装箱
- 增强
- 使用过哪些诊断工具
JFR
:Java Flight Recorder
VisualVM
Arthas
jstack
jstat
jmap
jcmd
- 一个
Java
进程中的内存组成 - 如何排查
Java
进程内存占用过高问题top
查看RSS
常驻内存和VIRT
虚拟内存pmap
查看内存映射NMT
查看内存组成jconsole
查看堆外内存
- 了解过
NMT
吗,如何查看- 各个分类代表什么意思
- 内存最有可能出现问题的在哪个分类
GC
- 哪些对象可以作为
GC Root
Java
中的引用类型有哪些(强、软、弱、虚、引用队列)- 垃圾回收器的种类
Serial
CMS
G1
ZGC
Shenandoah
Java 11
默认垃圾回收器CPU > 1 && RAM > 2G
:G1GC
CPU = 1 || RAM < 2G
:SerialGC
JVM
如何使用垃圾回收器- 说一下
SafePoint
设计模式
- 六大原则
- 单一职责:一个类和方法只作一件事
- 里氏替换:多态,之类可扩展父类
- 依赖倒置:细节依赖抽象,下层依赖上层
- 接口隔离:建立单一接口
- 迪米特原则:最少知道,降低耦合
- 开闭原则:抽象架构,扩展实现
Spring
设计模式- 单例模式(但不是
Bean
的单例) - 工厂模式
- 责任链模式(拦截器,过滤器)
- 适配器模式(
Adapter
)
- 单例模式(但不是
OAuth2
- 简单说下
OAuth2
OAuth2
有几种授权模式- 授权码模式流程是怎么样的
- 普通授权码模式安全吗?如何保证安全(
PKCE
) - 设备码模式流程是怎么样的
OAuth2
与OIDC
区别和联系OIDC
中的scope
有哪些offline_access
的作用
- 什么是
Client
,什么是ResourceServer
AccessToken
、RefreshToken
、IDToken
的区别和关联User
退出后如何通知服务端(BackChannel Logout
)- 退出登录后
Token
如何做失效处理 - 了解过
Keycloak
吗?简单说下他有几个概念 Spring Security
如何实现的OAuth2
Spring Security
原理
Spring
实战
- 如果设置服务端超时时间
- 服务端超时后是否会继续执行业务逻辑
ControllerAdvice
如何捕获Error
级别错误,如StackOverflowError
、NoClassDefFoundError
Spring
常用注解@RequestMapping
@ResponseBody
@RequestBody
Filter
和Interceptor
区别- 作用域
Spring
如何解析HTTP
报文信息(HttpMessageConverters
)Spring
中注入的几种方式,Spring
推荐哪种注入方式@Resource
@Autowired
- 构建函数注入
Spring
不用@Autowired
、@Resource
能否注入对象Spring Boot
配置优先级Spring Boot
路径匹配规则Spring Boot
优雅停机- 如何自定义
spring boot starter
- 如何排除
spring boot starter
中加载的配置 @Conditional
使用与原理Spring Boot
镜像分层构建- 优点
- 原理
- 如果设置服务端超时时间
原理
Spring Security
原理Authentication
Filter
中注入AuthenticationToken
Authorization
AuthenticationProvider
校验AuthenticationToken
- 校验
access
方法中实现的逻辑(如:permitAll
、authenticated
、自定义逻辑)
Spring
大量使用反射,效率会变低吗Spring
中的IOC
步骤Spring
中的AOP
Spring Bean
- 对象是单例还是多例
- 注册过程
- 定义包含哪些(
BeanDefinition
) - 生命周期
Spring
三级缓存Spring
循环依赖Spring
循环依赖能否用二级缓存SpringMVC
流程Spring Boot
特性Spring Boot
启动流程Spring Boot
自动配置原理Spring Boot
Jar
包启动原理
事务
Spring
传播Spring
事务原理Spring
事务失效Spring
事务中有远程调用如何处理- 事务隔离级别
MySQL
- 锁
- 乐观锁与悲观锁的实现
- 如何解决幻读(间隙锁,不是
MVCC
) - 意向锁
- 行锁/记录锁
- 间隙锁
Next-Key
锁
- 索引
- 聚集索引和非聚集索引(
Cluster Index
、Non Cluster Index
) - 覆盖索引
- 索引条件下推
- 聚集索引和非聚集索引(
SQL
- 数据库表的设计规范:三范式
select *
与select id
区别- 如何定位
SQL
需要优化及如何优化- 慢
SQL
EXPLAIN
- 聚集索引
Cluster Index
非聚集索引Non-Cluster Index
- 覆盖索引
exist in
区别- 索引条件下推
- 慢
- 索引失效的情况
- 模糊索引,头部模糊如何走索引
- 成绩表:学生名字,学科,成绩。
- 找出所有学科成绩大于等于
90
分的学生名字 - 获取总分最高的前三名(
sum -> group by name fetch first 3 rows
) - 获取单科成绩最高的前三名(
rank() over(partition by subject order by score desc) -> rank <= 3
)
- 找出所有学科成绩大于等于
- 删除重复数据保留最新一条数据
Redis
- 常用的数据类型
zset
实现原理(skiplist
)
- 数据淘汰策略
noeviction
:默认策略,不淘汰,如果内存已满,添加数据是报错。allkeys-lru
:在所有键中,选取最近最少使用的数据抛弃。volatile-lru
:在设置了过期时间的所有键中,选取最近最少使用的数据抛弃。allkeys-random
:在所有键中,随机抛弃。volatile-random
:在设置了过期时间的所有键,随机抛弃。volatile-ttl
:在设置了过期时间的所有键,抛弃存活时间最短的数据。
- 如何持久化
RDB
和AOF
优缺点- 如何选择
- 单线程为什么这么快
6.0
版本后为什么改为多线程
bigkey
查询大key
命令redis-cli --bigkeys -i 0.1
hotkey
查询热点数据命令- 必须使用
LFU
淘汰策略 redis-cli --hotkeys -i 0.1
- 必须使用
hash tag
作用(将key
存在同一物理节点上的slot
上,减少查询)- 缓存雪崩
- 缓存击穿
- 缓存与数据库双写不一致
- 线上禁用哪些命令
keys
flushall
flushdb
MQ
- 为什么要使用队列
- 使用场景是哪些
RabbitMQ
集群模式,优缺点RabbitMQ
分发模式- 路由方式是怎么样的
- 如何保证消息不丢失
- 如何避免消息重复投递和重复消费
分布式
- 如何保证接口幂等
- 限流算法
- 计数器(固定窗口):
Redis incr
- 滑动窗口:
Redis zset
- 漏桶
- 令牌桶:
Guava RateLimiter
- 计数器(固定窗口):
- 分布式定时任务和普通定时任务有什么区别
- 分布式锁
- 基于数据库
- 基于
Redis
- 基于
Zookeeper
- 分布式
Session
Session
粘滞- 共享
Session
Redis
MongoDB
- 数据库
- 分布式事务
- 本地消息表
Ali Seata
- 最终一致性
MQ
- 高并发时,服务如何扩容
- 新增实例,配置到负载均衡
Kubernetes
调整Deployment
的replicas
参数- 使用
Kubernetes
的HPA
控制器,动态扩缩容
- 负载均衡策略
ip hash
url hash
weight
权重- 轮询
- 什么是流量染色
- 基于流量染色可以实现什么
- 灰度发布
- 蓝绿部署
- 泳道隔离
- 基于流量染色可以实现什么
- 全链路追踪
HTTP Header
添加TraceId
Slf4j
的MDC
机制及原理(ThreadLocal
)- 能否在子线程中使用
压测
- 是否做过压测
- 使用什么工具
- 压测的步骤
JVM
参数GC
调优
Kubernetes
Pod
控制器有哪几种Deployment
常用设置replicas
副本数pod
的属性,探针probe
- 设置配置(环境变量
envFrom
)ConfigMap
Secrets
- 如何查看
namespace
下所有pod
的日志 - 如何远程
Debug
一个Java
应用- 添加
command
参数,暴露5005
端口,port-forward
端口 - 使用
Telepresence
网络代理,直接本地调试,注意断点类型
- 添加
- 如何简化本地开发
Telepresence
kt-connect
nocalhost
- 如何使用
Helm Chart
架构
- 日常职责是什么
- 如何做技术选型?
- 需求分析
- 技术调研
- 方案规划
- 代码落地
- 服务限流有哪些算法
- 数据同步有哪些方式
- 高并发和高性能的区别和联系
- 高并发:访问数量
- 高性能:访问响应时间
- 如何设计高可用
- 如何设计高扩展
- 如何
JVM
调优 - 如何复用及重构
- 如何防止重放攻击
- 如何做大文件上传下载
CAP
定理Consistency
:一致性Availability
:可用性Partition tolerance
:分区容错性
BASE
理论Basically Available
:基本可用Soft-state
:软状态Eventually consistent
:最终一致性
系统设计
- 订单号生成规则
综合考察
- 软件开发的全生命周期,开发流程
- 独立工作能力
- 需求分析
- 详细设计
- 模块划分(微服务)
- 编码实现(用到哪些组件、依赖)
- 自测及交付流程(
Review
、CI
、CD
)
Views: 1,623 · Posted: 2022-09-13
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...