跳到主要内容
Java 大厂实习面试高频技术题汇总与解析 | 极客日志
Java java 算法
Java 大厂实习面试高频技术题汇总与解析 Java 大厂实习面试涵盖 MySQL 事务机制、SQL 优化、Nacos 注册中心原理、RocketMQ 持久化、WebSocket 通信、HTTP 连接管理、HashMap 底层实现、缓存一致性策略、数据库隔离级别、缓存击穿穿透雪崩解决方案、Redis 库存扣减、线程 sleep 与 wait 区别、RabbitMQ 消息可靠性与顺序性、LeetCode 算法合并链表、Redis 主从复制、数据结构应用场景、Linux 日志与端口命令、Java 异常体系及 HTTPS 加密流程。内容提供具体代码示例与核心原理解析,帮助求职者掌握核心技术点。
KernelLab 发布于 2026/3/25 更新于 2026/4/25 2 浏览1. MySQL 事务机制(阿里巴巴)
它确保了一组数据库操作要么全部成功执行,要么全部失败回滚。
事务特性:
原子性 :把多个操作打包成一个整体。(要么全都做,要么都不做)
一致性 :事务执行前后,数据库从一个一致状态转换到另一个一致状态,数据完整性约束不被破坏。
隔离性 :多个事务并发执行时,彼此的操作互不干扰,每个事务都感觉不到其他事务的存在。
持久性 :事务一旦提交,其修改会永久保存到数据库中,即使系统崩溃也不会丢失。
2. 有做过 SQL 优化的实现么(阿里巴巴)
优化联表查询,使用 JOIN
SELECT name FROM users WHERE id IN (SELECT user_id FROM orders WHERE status = 1 );
SELECT u.name FROM users u JOIN orders o ON u.id = o.user_id WHERE o.status = 1 ;
避免使用 SELECT *,只查询自己需要的字段
SELECT * FROM users WHERE age > 30 ;
SELECT id, name, email FROM users WHERE age > 30 ;
为 WHERE、JOIN、ORDER BY 字段建立索引
CREATE INDEX idx_user_age users(age);
INDEX idx_orders_user_id orders(user_id);
INDEX idx_articles_create_time articles(create_time);
ON
CREATE
ON
CREATE
ON
3. Nacos 底层是如何实现注册中心功能的(阿里巴巴) 其底层实现核心围绕服务注册、服务发现、健康检查三大核心功能展开。
服务提供者启动时,通过 Nacos 客户端向 Nacos Server 发送注册请求,携带服务名、IP、端口、权重、健康检查参数等元数据。Nacos Server 接收到请求后,将服务信息存储在内存注册表中。
服务消费者启动时 :主动从 Nacos Server 拉取目标服务的实例列表,并缓存到本地。
服务变更时 :Nacos Server 主动推送变更通知给消费者(减少轮询开销),消费者收到通知后再主动拉取最新实例列表。
Nacos Server 会定期向服务实例发送健康检查请求,若实例连续失败,则标记为不健康,暂时从可用实例列表中移除;也可以是服务实例定期向 Nacos Server 发送健康心跳包。
4. RocketMQ 如何持久化(阿里巴巴) RocketMQ 实现持久化依靠交换器的持久化、队列的持久化和消息的持久化。
5. 介绍一下 WebSocket(阿里巴巴) WebSocket 是一种协议,用于在客户端和服务器之间建立持久的双向通信连接,广泛应用于需要实时数据交换的应用程序。
持久连接 :一旦建立连接,客户端和服务器保持长期通信状态,无需频繁创建和关闭连接。
双向通信 :服务器可以主动向客户端推送数据,客户端也可以随时向服务器发送数据,打破了 HTTP 中只能由客户端发起请求的限制。
低开销 :连接建立后,数据传输时无需携带大量 HTTP 头部信息,减少带宽消耗。
6. 如何判断是 HTTP 长连接还是短连接,怎么设置长连接(阿里巴巴) 在 HTTP 协议中,长连接和短连接的核心区别在于一次 TCP 连接是否可以被多次 HTTP 请求复用,可以通过协议版本和请求头字段来判断。
HTTP/1.0 :默认是短连接。
HTTP/1.1 :默认是长连接。
通过查看响应头中 Connection,可以查看是什么连接,如果没有则按照默认值处理。
设置长连接,即改变响应头中的 Connection 字段。
7. HashMap 的实现原理(快手) HashMap 的底层结构是数组(桶数组)+ 链表 + 红黑树的组合。
首先对键的 hashcode 进行高低位异或,混合高低位信息,减少哈希冲突(因为哈希表的下标是通过哈希值 & (数组长度 - 1) 计算的,如果只用低位,高位未参与,导致冲突可能性高)。
然后对桶索引进行计算(哈希值 & (数组长度 - 1),等价于哈希值 % 数组长度,此处使用位运算是因为哈希表对性能要求很高)。需要保证桶数组的长度必须是 2 的幂次方(创建哈希表时会处理传入参数,使得桶数组长度一定是 2 的幂次方且大于等于传入参数)。
插入数据时采取链表 + 红黑树的组合结构解决哈希冲突,并通过扩容机制优化插入查找效率。
插入键值对 :如果桶为空,直接在该桶插入新节点;如果非空,若桶中是红黑树,按红黑树规则插入;若桶中是链表,遍历链表,找到相等的键则覆盖值,否则插入链表尾部。插入后若链表长度≥8,将链表转为红黑树。
扩容判断 :若元素总数超过阈值(capacity * loadFactor,负载因子默认 0.75),则执行扩容操作,桶数组长度扩容为原来的 2 倍,并重新计算所有键的索引。
查询键值对 :计算键的哈希值和桶索引,若桶中是红黑树,按红黑树规则查询;若桶中是链表,遍历链表查找相等的键,返回对应值(未找到则返回 null)。
对比 JDK 1.7,JDK 1.8 进行了一些改变 :首先扩容的时候,JDK 1.8 对扩容进行了优化,通过 (e.hash & oldCap) 判断节点是否需要迁移到新桶,减少重哈希开销;其次在插入键值对的时候,JDK 1.7 采取头插法,而 JDK 1.8 采用的是尾插法,这样做的好处是可以避免多线程扩容死循环。
8. HashMap 承载的元素越来越少,什么时候会退化成链表,为什么两者设置的这个值不对称(快手) 当 HashMap 中红黑树的节点数≤6 时,会退化为链表。
两者阈值设置不对称(8→树、6→链)是为了临界防抖动——避免节点数在阈值附近波动时(如 7→8→7)导致链表与红黑树频繁转换,减少性能开销。
9. MySQL 和 Redis 的一致性怎么保证的(快手)
读取数据时,先查 Redis;若 Redis 有数据,直接返回。
若 Redis 无数据,查 MySQL,将结果写入 Redis 后返回。
更新数据时,先更新 MySQL,再删除 Redis 中的旧缓存(而非直接更新 Redis)。
关键原因:删除缓存可避免'更新 MySQL 和更新 Redis'的原子性问题,后续读取时会自动从 MySQL 加载新数据到 Redis,实现最终一致。
获取分布式锁,确保同一时间只有一个线程操作该数据。
开启 MySQL 事务,更新 MySQL 数据。
事务提交成功后,立即更新或删除 Redis 缓存。
释放分布式锁。
关键原因:分布式锁避免了并发更新导致的'数据覆盖'问题,MySQL 事务确保了数据更新的可靠性,两者结合实现强一致。
10. 数据库有哪些隔离级别,默认的隔离级别是什么(快手)
读未提交 :一个事务可以读取另一个事务未提交的数据,一致性最低。
读已提交 :一个事务只能读取另一个事务已提交的数据,避免脏读。
可重复读 :同一事务内多次读取同一数据,结果始终一致,避免不可重复读。
串行化 :事务完全串行执行,避免所有并发问题,一致性最高。
MySQL :默认隔离级别是可重复读。
SQL Server :默认隔离级别是读已提交。
脏读 :事务 A 修改了数据但未提交,事务 B 读取了该未提交数据,之后事务 A 回滚,事务 B 读取的是无效数据。
不可重复读 :事务 A 内多次读取同一数据,事务 B 在期间修改并提交了该数据,导致事务 A 多次读取结果不一致。
幻读 :事务 A 内多次执行同一查询(如统计记录数),事务 B 在期间插入/删除了符合条件的记录,导致事务 A 多次查询结果行数不一致。
11. 缓存击穿、穿透、雪崩如何解决(快手)
缓存击穿 :某个热点 Key 失效,请求穿透到 DB。
缓存穿透 :请求不存在的 Key,持续穿透到 DB。
缓存雪崩 :大量 Key 同时过期 / Redis 宕机,请求全量穿透。
缓存穿透 :
使用布隆过滤器先判定 key 是否存在,再真正查询。
针对数据库上也不存在的 key,也存储到 Redis 中,比如 value 就随便设成"",避免后续频繁访问数据库。
缓存雪崩 :不给 key 设置过期时间或者设置过期时间的时候添加随机时间因子。
缓存击穿 :热点 key 永不过期。
布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,核心作用是快速判断'一个元素是否存在于集合中',能有效解决缓存穿透问题,但存在极小的'假阳性'(误判元素存在),且不支持删除操作。
12. 当 Redis 作为库存存储也扛不住大量请求时,如何处理?(快手) 1. 使用 Redis 集群,提高承载能力(横向扩容 + 读写分离)
分片部署 :每个节点只存储部分商品的库存,分散单节点压力。
读写分离 :读操作走从节点,写操作走主节点。
2. 限流 :前端限流,网关(nginx, gateway)限流,使用 MQ 进行流量控制。
3. 熔断降级 :用 Sentinel (哨兵) 监控 Redis 的响应时间(如连续 5 次超时),触发熔断。
读请求:直接返回本地缓存的旧值。
写请求:将扣减请求暂存到本地队列(如内存队列),Redis 恢复后异步同步。
13. sleep 和 wait 区别(阿里巴巴)
使用前提 :sleep 无需持有锁;wait 必须拥有当前对象的锁。
对锁影响 :sleep 不会释放当前持有的锁(若持有锁,仍保持);wait 会主动释放持有的对象锁,让其他线程可获取该锁。
唤醒方式 :sleep 时间到后自动唤醒;或被 interrupt() 中断;wait 需被其他线程调用 notify() 唤醒;或等待超时;或被 interrupt() 中断。
用途 :sleep 目的是用来阻塞线程;wait 目的是为了等待其他线程唤醒的。
14. RabbitMQ 是如何保证消息不丢失的(快手)
生产者到 RabbitMQ 服务器 :开启发送方确认(confirm 模式保证生产者->exchange 和 return 模式保证 exchange->queue)。
中间件 MQ 保存消息 :持久性(队列持久性,交换器持久性,消息持久性),确保发生故障重启后消息不丢失。
消息消费环节 :确保消息被正确处理不丢失。
消息确认机制 :关闭自动确认,使用手动确认,并配置消息重试次数与死信队列。
死信 (dead message) 简单理解就是因为种种原因,无法被消费的信息,就是死信。有死信,自然就有死信队列。当消息在一个队列中变成死信之后,它能被重新发送到另一个交换器中,这个交换器就是 DLX (Dead Letter Exchange),绑定 DLX 的队列,就称为死信队列 (Dead Letter Queue,简称 DLQ)。
消息被拒绝(Basic.Reject/Basic.Nack),并且设置 requeue 参数为 false。
消息过期。
队列达到最大长度。
消息重试:将死信消息重新发送到原队列或另一个队列进行重试处理。(配合 TTL 特性可以实现延迟队列的效果(有瑕疵))
消息丢弃:直接丢弃这些无法处理的消息,以避免它们占用系统资源。
日志收集:将死信消息作为日志收集起来,用于后续分析和问题定位。
15. 算法题:LeetCode 23 合并两个升序链表(快手) 这道题乍一看去挺简单的,还是 LeetCode 原题。
如果你是第一次做这道题你或许会想到像 21. 合并两个有序链表 这道题,首先想着用暴力的方法去俩俩合并,但是如果我们仔细一想,似乎这样的话,时间复杂度有点高了,我们每次都要对 k 个链表进行比较,时间复杂度是 O(k^2*n),所以我们想着去优化一下算法,我们可以想到使用优先级队列(堆),然后排小根堆的方式,将每次最小的节点取出,然后将节点的下一个存入。
16. 讲一下 Redis replication 的原理(快手二面) Redis Replication(主从复制)通过将主节点(Master)的数据同步到从节点(Slave),实现数据冗余备份和读请求分流。
主节点(Master) :接收写请求,负责将数据同步到从节点;可同时拥有多个从节点。
从节点(Slave) :只读节点,不处理写请求(默认配置)。
保存主节点(master)的信息 (ip 地址,端口号)。
当从节点发现存在新的主节点后 ,会尝试与主节点建立基于 TCP 的网络连接(验证读写功能是否正常)。
同步数据集 :对于首次建立复制的场景,主节点会把当前持有的所有数据全部发送给从节点,这步操作基本是耗时最长的,所以又划分成两种情况:全量同步和部分同步。
命令持续复制 :当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把命令发送给从节点,从节点执行修改命令,保证主从数据的一致性。
17. Redis 的哪些数据结构是你比较了解的,可以应用到哪些场景(快手)
String(字符串) :应用:缓存热点数据,分布式锁,计数器。
Hash(哈希) :[key field value],应用:存储对象数据,购物车。
List(列表) :应用:消息队列。
Set(集合) :应用:去重,社交场景 - 共同好友/共同关注,抖音推荐。
ZSet(有序集合) :应用:排行榜,延迟任务。
18. 讲一讲 SQL 优化,加了索引之后还很慢会是什么原因,扫描非常多行会 (快手) SQL 加了索引后仍很慢,且扫描行数多,核心原因是索引未被有效使用或索引设计不合理。
索引列参与函数/表达式运算。
索引列使用不等于(!=、<>)、NOT IN、IS NOT NULL。
索引选择性差(索引列重复值多)。
索引列是大字段(如 TEXT、VARCHAR (2000))。
19. RabbitMQ 如何在业务中保证消息的顺序消息 (快手二面) RabbitMQ 的顺序性分为局部顺序性和全局顺序性。
全局顺序性很难保障而且使用场景很少,我们可以使用连续的序号和消费者缓冲区来实现,通过序号在消费者缓冲区来排列实现有序。
那么局部有序就比较好保障,我们可以使用单队列单消费者 + 分区消费解决。
基础方案:单队列单消费者 —— RabbitMQ 原生保障局部有序
RabbitMQ 的单个队列天然具备 FIFO(先进先出)特性:生产者向队列发送消息时,消息会按发送顺序依次存入队列;消费者从队列获取消息时,会按队列存储顺序依次消费(默认 prefetch=1 时,处理完一条再取下一条)。
优化方案:分区消费 —— 用'ID 分组'提升吞吐量,本质仍是单队列单消费者
例:用 userID % 3 将用户消息分为 3 组,userID=1、4、7 的消息路由到队列 Q1,userID=2、5、8 的路由到 Q2,userID=3、6、9 的路由到 Q3。
为 Q1、Q2、Q3 分别分配一个消费者(或一个单线程消费池),每个消费者只处理对应队列的消息。
20. Linux 查看日志的命令(快手二面)
-i:忽略大小写(如搜索 "Error" 和 "error" 都匹配)。
-n:显示匹配行的行号。
-v:反向匹配(显示不包含该字符串的行)。
例如,在 app.log 中搜索包含 "error" 的行。
grep "error" app.log
grep -in "error" app.log
用 tail -f 实时跟踪日志文件,同时用 grep 筛选特定内容(如实时监控错误日志):
tail -f app.log | grep "ERROR"
tail -f app.log | grep -i "error"
21. Linux 找某个端口被哪个服务占用的命令(快手二面) netstat -tuln | grep 3306
22. 了解 Java 中异常的哪些子类(快手)
IOException
SQLException
ClassNotFoundException
受检查异常(文件读写异常,sql 语句异常,类不存在异常)。
NullPointerException
IndexOutOfBoundsException
ArithmeticException
运行时异常(空指针异常,数组越界异常,算数异常)。
23. 操作数据库有关的异常(快手)
sql 语句语法错误异常
数据库连接失败异常
违反数据库约束异常
数据类型不匹配或数据超出范围异常
24. redis 的 decr 操作(快手) Redis 的 DECR 命令用于对存储在指定键的数值进行原子性减 1 操作,若键不存在则先初始化为 0 再减 1,返回操作后的结果。它是 Redis 中用于实现'计数器递减''库存扣减'等场景的核心命令,具有原子性(线程安全)和高性能的特点。
25. https 的底层工作原理(字节跳动)
https 和 http 的区别是什么
加密的整个流程
HTTPS 也是一个应用层协议。是在 HTTP 协议的基础上引入了一个加密层 (和 HTTP 的区别)。
加密就是把明文 (要传输的信息) 进行一系列变换,生成密文。解密就是把密文再进行一系列变换,还原成明文。
对称加密 :加密和解密依赖同一把密钥。
非对称加密 :加密和解密依赖一对关联但不同的密钥。
服务器收到请求后,将其数字证书发送给客户端。数字证书包含服务器的公钥和由可信的证书颁发机构(CA)签名的信息。
验证证书的完整性和签名:使用 CA 的公钥验证证书的签名,确保证书没有被篡改。
检查证书的有效期:确认证书在有效期内。
验证证书的颁发机构:确认 CA 是受信任的机构。
检查证书吊销状态:通过证书吊销列表(CRL)或在线证书状态协议(OCSP)检查证书是否被吊销。
如果证书验证通过,客户端会生成一个随机的对称密钥(也称为会话密钥),用于加密会话中的数据。客户端使用服务器的公钥加密这个会话密钥,并发送给服务器。
服务器使用其私钥解密会话密钥。此时,客户端和服务器都持有相同的对称密钥,用于加密和解密后续通信中的数据。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online