面试知识点整理
目录
- 一面
- 1. 请你做一个简单的自我介绍
- 2. 介绍以下你做过的比较有挑战的项目(项目架构/你的职责/遇到的最大挑战)
- 3. 技术
- Elasticsearch
- Kafka
- Java
- Spring
- Mybatis
- 数据库
- 分布式事务
- K8s
- 分布式锁
- 二面
一面
1. 请你做一个简单的自我介绍
面试官您好...把自己每一段工作经历都说清楚,讲清楚自己的技术栈
2. 介绍以下你做过的比较有挑战的项目(项目架构/你的职责/遇到的最大挑战)
微服务架构,全栈,实现二级缓存...
3. 技术
Elasticsearch
如何设计一个搜索接口?
用ES实现
什么是分词器?
分词器是ES里面用于处理文本数据的核心组件,他将原始文本转换成时候搜索的术语或者标记
ES硬盘存储不够如何处理
1. 增加节点或磁盘
2. 数据管理优化 - 冷热数据分离
3. 索引设置中启用压缩
4. 将旧数据归档在云对象存储空间
5. 数据精简策略 - 清除不必要数据
Kafka
Kafka 宕机了之后怎么重启?
1. 检查 kafka和zookeeper的日志文件
2. 预处理措施 - 停止相关服务和备份关键文件
3. 分步骤重启 - 先启动zookeeper,再重启 kafka
Kafka和Zookeeper连接有问题如何处理?
1. 检查Zookeeper集群状态和Kafka配置
2. 检查是不是常见的连接超时问题和会话过期问题,如果是的话就修改配置延长修改时间
MQ堆积消息太多如何处理?
原因主要有三种:消费者处理能力不足,分区分配不均,生产者突然发送大量消息
解决方案:临时扩容消费者,消费者使用多线程消费,生产者限流
如何防止消息丢失?
生产者:重要信息使用同步方式发送,如果发送异常把数据存到数据库/记录到重试队列
Broker端:配置副本和持久化机制
消费端:正确提交位移,并且消费端进行幂等设计
如何防止消息的重复消费?
1. 根本原因:生产者重试机制/消费者位移提交出错/消费组再平衡导致分区重新分配
2. 解决方法:启动幂等生产者/为每条消息添加唯一id/broker端设置事务支持/消费端设置幂等
如何做到顺序消费?
1. 生产端相同业务消息只能进入同一个分区
2. Broker端创建topic时合理设置分区数
3. 服务端单个消费者实例只消费一个分区
如何实现延迟队列?
1. Kafka本身没有内置的延迟队列,可以通过创建不同延迟级别的Topic实现延迟队列
2. 使用 Redis Sort Set实现
Kafka如何做到单机上百万的高吞吐量?
页面缓存技术
磁盘顺序写
零拷贝技术
Java
堆、栈、方法区这些配置有了解过吗?
# 初始堆大小(默认物理内存1/64)
-Xms512m# 最大堆大小(默认物理内存1/4)
-Xmx4g# 新生代大小
-Xmn256m# 老年代与新生代比例(默认2:1)
-XX:NewRatio=2# Eden与Survivor区比例(默认8:1:1)
-XX:SurvivorRatio=8
说一说不同jdk版本的主要区别(jdk8,jdk11,jdk17,jdk21)
语法上:jdk17有密封类和文本块
性能优化上:jdk17里面ZGC正式可用,jdk21有协程[2014] JDK 8 (Lambda) ↓
[2018] JDK 11 (var/ZGC) ↓
[2021] JDK 17 (Sealed/Text Blocks) ↓
[2023] JDK 21 (Virtual Threads)
JVM里面垃圾收集器CMS和G1的区别
1. 收集算法不同
CMS是标记清除算法,工作流程:初始标记(STW)并发标记重新标记(STW)并发清除并发重置
G1(标记-整理算法),工作流程:初始标记(STW)并发标记最终标记(STW)筛选回收(STW)2. 内存管理方式不同
CMS:
[Eden][Survivor][Survivor] | [Old Generation]
固定比例(如-XX:NewRatio=2)
G1:
[Region1][Region2]...[RegionN]
每个Region大小一致(1-32MB,-XX:G1HeapRegionSize)
可扮演Eden/Survivor/Old/Humongous角色
HashMap、HashTable、ConcurrentHashMap的区别
HashMap: 线程不安全,底层使用数组+链表/红黑树实现 (jdk8+)
HashTable: value不能为空,否则会报错,所有方法使用synchronized包装
ConsurrentHashMap: 分段锁优化(jdk8 - Node数组+CAS+synchronized)
HashMap里面为什么用红黑树不用其他的数据结构,比如二叉树?
普通二叉树会退化成链表
Java里面实现多线程的方式有哪些?
继承Thread类
实现Runnable接口
实现Callable接口
使用Java线程池主要有哪几个参数?这些参数的使用方法?等待队列有哪几种类型?线程池处理流程?
corePoolSize int 核心线程数,线程池长期维持的线程数量 5
maximumPoolSize int 最大线程数,线程池允许创建的最大线程数量 10
keepAliveTime long 空闲线程存活时间(非核心线程空闲超过此时间将被回收) 60(秒)
unit TimeUnit keepAliveTime的时间单位 TimeUnit.SECONDS
workQueue BlockingQueue<Runnable> 任务队列,用于保存等待执行的任务 new LinkedBlockingQueue()
threadFactory ThreadFactory 线程工厂,用于创建新线程 Executors.defaultThreadFactory()
handler RejectedExecutionHandler 拒绝策略,当线程池和队列都满时的处理策略
在你过往的项目经验里面有什么并发场景?
理赔场景:发生自然灾害有大量客户理赔
描述一下 Java 里面锁的升级和降级
锁升级:无锁 → 偏向锁 → 轻量级锁 → 重量级锁
锁降级:需要开发者显式控制(仅ReadWriteLock支持)
Spring
请简述Spring的生命周期
1. 实例化(Instantiation)通过构造函数或工厂方法创建Bean实例此时对象属性均为默认值(null/0/false)2. 属性赋值(Population of Properties)依赖注入(@Autowired/@Value等)设置Bean属性值3. 初始化(Initialization)调用BeanNameAware.setBeanName()调用BeanFactoryAware.setBeanFactory()调用ApplicationContextAware.setApplicationContext()执行@PostConstruct标注的方法调用InitializingBean.afterPropertiesSet()执行自定义init-method4. 使用期(In Service)Bean完全初始化,可供应用程序使用5. 销毁(Destruction)调用@PreDestroy标注的方法调用DisposableBean.destroy()执行自定义destroy-method
Spring AOP的实现原理,AOP是在Bean的生命周期的哪个阶段实现的,如何实现Bean的按需加载?
1. AOP是基于动态代理实现,如果目标类实现了接口就用jdk动态代理,如果没有实现接口就用CG Lib做动态代理
2. Spring AOP 的织入发生在 Bean 生命周期的 初始化后阶段 A[实例化Bean] --> B[属性注入]B --> C[执行BeanPostProcessor前置处理]C --> D[初始化回调]D --> E[执行BeanPostProcessor后置处理]E --> F[AOP代理创建]F --> G[Bean准备就绪]
3. 使用 @Lazy注解或者@Conditional 注解实现按需加载
如何使用AOP实现常见的限流算法
计数器算法(固定窗口)
滑动窗口
漏桶算法
令牌桶算法
Spring事务的传播机制( A事务嵌套异步B事务,B事务执行失败A事务会回滚吗)
1. Spring定义了7种事务传播行为,通过@Transactional(propagation = Propagation.XXX)指定:
传播行为类型 说明
REQUIRED(默认) 如果当前存在事务,则加入该事务;如果不存在,则新建一个事务
SUPPORTS 如果当前存在事务,则加入该事务;如果不存在,则以非事务方式运行
MANDATORY 必须在一个已有的事务中执行,否则抛出异常
REQUIRES_NEW 新建一个独立事务,如果当前存在事务,则挂起当前事务
NOT_SUPPORTED 以非事务方式执行,如果当前存在事务,则挂起当前事务
NEVER 以非事务方式执行,如果当前存在事务,则抛出异常
NESTED 如果当前存在事务,则在嵌套事务内执行;否则新建一个事务(Savepoint机制)2. 不会自动回滚
Spring Data JPA的N+1问题和审计问题如何解决?
1. N+1 问题是指当查询主实体时,Hibernate/JPA 会先执行 1 次查询获取主实体列表,然后对每个主实体关联的子集合执行 N 次查询。
使用 JOIN FETCH
2. 审计字段问题: 审计字段(如创建时间、修改时间)不更新
使用@Modifying注解
Mybatis
Mybatis的Mapper是如何注册成Bean的?
Spring->>MapperScanner: @MapperScan触发扫描MapperScanner->>MapperScanner: 扫描指定包路径MapperScanner->>MapperScanner: 为每个Mapper接口生成BeanDefinitionMapperScanner->>BeanFactory: 注册Mapper接口的BeanDefinitionBeanFactory-->>Spring: 完成Bean注册
数据库
SQL优化做过吗?加索引的原理是什么?
1. SQL优化问题
不用 Select *
小表驱动大表
用连接查询代替子查询
提升group by的效率(group by 后面使用的字段是否加了索引)
批量操作把循环一条一条插入改成一条SQL插入所有数据
使用 limit
使用union all不用union
join的表不宜过多2. 加索引的原理
B+树
针对一条SQL查询有什么方式可以减少回表操作?
1. 索引覆盖(Covering Index)
当查询的所有字段都包含在索引中时,引擎可以直接使用索引返回数据,无需回表。
2. 使用聚簇索引(主键查询)
直接主键查询/优化为两步查询(避免回表)
3. 索引条件下推 (MySQL 5.6+特性)
4. 使用物化视图(Materialized Views)
5. 使用函数索引(MySQL 8.0+)
虚拟列+索引
能否讲一下数据库的隔离级别?
数据库隔离级别是事务ACID特性中的"I"(Isolation)的具体实现,它定义了事务之间的可见性规则,用于平衡并发性能与数据一致性读未提交 (Read Uncommitted) 可能 可能 可能 无锁优化,直接读取最新数据
读已提交 (Read Committed) 不可能 可能 可能 快照读(MVCC)或行锁(写时加锁)
可重复读 (Repeatable Read) 不可能 不可能 可能* MySQL InnoDB: 事务开始时创建一致性视图;Oracle: 使用块级多版本
串行化 (Serializable) 不可能 不可能 不可能
数据库的mvcc原理是什么
MVCC通过维护数据的多个版本,实现:读不阻塞写:读取操作不需要加锁写不阻塞读:写入操作不会阻塞读取操作非阻塞并发:读写操作可以同时进行
现在一张表里面有上千万的数据量,如何进行优化?
短期优化方案:给所有字段都加上索引
中期优化方案:把旧数据归档
长期优化方案: 分库分表
分布式事务
分布式系统中如何保证数据的一致性,分布式事务常见的解决方案是什么?
刚性事务:
2PC
3PC柔性事务:
TCC
Saga
消息队列
AT
K8s
你可以讲一下k8s的整体架构吗?
架构设计遵循控制平面(Control Plane) + 工作节点(Worker Node)的分布式模式,核心目标是自动化容器的部署、扩展和管理。以下是其整体架构的详细说明:
控制平面(Control Plane):
API Server(kube-apiserver)作用:集群的唯一入口,所有内部/外部请求(如kubectl)都通过RESTful API与API Server交互。特点:无状态,可水平扩展;负责认证、授权、请求校验,并将状态持久化到etcd。
etcd作用:分布式键值存储数据库,保存集群的所有配置数据和状态(如Pod、Service等资源信息)。特点:高可用、强一致性,是集群状态的“唯一真相源”。
Scheduler(kube-scheduler)作用:监视未调度的Pod,根据资源需求、亲和性等规则将其绑定到合适的工作节点。调度策略:考虑CPU/内存、节点标签、污点(Taint)等。
Controller Manager(kube-controller-manager)作用:运行一系列控制器(Controller),确保集群实际状态与期望状态一致。核心控制器:Node Controller(监控节点状态)Replication Controller(维护Pod副本数)Endpoints Controller(维护Service与Pod的映射)其他(如Deployment、DaemonSet控制器等)。
工作节点(Worker Node):
工作节点负责运行容器化应用,每个节点包含以下组件:
核心组件kubelet作用:节点上的“代理”,与API Server通信,管理本节点的Pod生命周期(如创建/删除容器)。职责:监控容器健康状态、挂载存储卷、执行Pod的启动/停止命令。kube-proxy作用:维护节点上的网络规则(如iptables/IPVS),实现Service的负载均衡和流量路由。功能:将Service的虚拟IP映射到后端Pod。容器运行时(Container Runtime)作用:实际运行容器的引擎(如containerd、CRI-O、Docker)。标准:遵循K8s的CRI(容器运行时接口)规范。
K8s里面一个应用是如何部署到K8s集群里面的,从Control plane到kube proxy的完整流程能讲一下吗?
1. 用户提交部署请求(kubectl/YAML)
2. 控制平面处理请求
- API Server 接收请求
- Controller Manager 监听到变化
- Scheduler 分配节点
3. 工作节点执行部署
- kubelet 监听到任务
- kube-proxy 配置网络规则---API Server → etcd(存储资源定义)↓
Deployment Controller → 创建ReplicaSet → 创建Pod定义↓
Scheduler → 绑定Pod到Node → etcd↓
目标Node的kubelet → 启动容器 → 上报状态↓
kube-proxy → 配置Service的iptables/IPVS规则↓
流量通过Service到达Pod
分布式锁
你在项目里面用到分布式锁的场景是什么,如何创建一个分布式锁?
应用场景:防止重复操作/资源独占访问/避免并发冲突/数据一致性保证
实现方式:基于redis实现/基于zookeeper实现/基于数据库实现
最佳实践:设置合理超时时间/实现锁续期机制/保证释放锁的原子性/避免惊群效应/考虑可重入性
二面
项目经验
你如果遇到一个user报告的production case 问题,应该如何处理?
查production log,然后在 dev/sit/uat 复现问题,可以复现就解决问题,进行代码fix。如果测试场不能复现就去申请权限到production复现,如果在production复现不了,就去申请Defect暂时不能fix的请求
职业发展
你怎么看待tech lead这个岗位,tech主要需要做哪些事情?
1. 技术领导与架构设计
2. 团队管理与技术指导
3. 项目管理与交付
4. 技术前瞻与创新
你怎么看待项目的合规问题?
立项阶段:合规风险评估(法律法规)
需求分析:使用隐私保护设计
技术设计:日志审计方案/第三方组件审查
开发测试阶段:敏感数据处理
上线运营阶段:持续合规监控