字节国际支付后端一面
2026年4月1日 面试面经整理1. 自我介绍Q:首先,你先做个简单的自我介绍吧。A:面试官你好,****。2. MySQL 事务特性与 MVCCQ:在 MySQL 这个数据库里,你来描述一下事务的几个特性,然后你了解它的实现原理大概是怎么样?A:事务的特性是 ACID,就是持久性、一致性、隔...
字数: 5201 | 语雀原文
2026年4月1日
面试面经整理
1. 自我介绍
Q:首先,你先做个简单的自我介绍吧。
A: 面试官你好,****。
2. MySQL 事务特性与 MVCC
Q:在 MySQL 这个数据库里,你来描述一下事务的几个特性,然后你了解它的实现原理大概是怎么样?
A: 事务的特性是 ACID,就是持久性、一致性、隔离性,还有原子性。
它是基于 MVCC 去实现的。MVCC 主要是用来……这部分有点忘了。
3. MySQL 锁
Q:你知道 MySQL 里有哪些锁吗?
A: MySQL 的锁,比如说有表锁,还有行锁。如果按照读和写来说,它有读锁、写锁。
读锁的话,就是我在查询的时候给它加一个读锁,读锁之间是可以共享的。但是写锁的话,写锁加上之后,写锁和写锁之间是不能共享的。写锁上了之后,是可以上读锁的,大概是这样一个情况。
Q:常见的一些写锁,有哪些语句会用到这个写锁?
A:
写锁的话,比如说我在 select 后面加 for update,还有比如说我直接 update,它都会上一个写锁。
它主要是用来防止并发情况下事务出现的几个问题,比如脏读之类的问题。
4. 脏读与隔离级别
Q:脏读是怎么理解的?脏读是通过什么解决的?
A: 脏读主要就是,比如说我开启一个事务的时候,读到了其他事务还没有提交的数据,就会读到一个脏数据。
因为那个事务可能最后没有提交,或者回滚了,那么就会读到这样一个脏数据,这个叫脏读。
通过加锁可以在我开启一个事务的时候,让它加锁,让其他数据读不到它未提交的数据。
如果说我这个事务未提交,那么我读到的是加锁之前的一个快照,也就是快照读,就可以防止读到脏数据。
Q:不同的隔离级别会有哪些不同的快照吗?在生成一致性视图的时候。
A: 主要是在读已提交和可重复读这两个,它们的 Read View 不太一样,生成的时机不太一样。
在读已提交的情况下,每次 select 都会生成一次 Read View。
在可重复读的时候,在事务里面,第一次 select 的时候才生成它的 Read View,之后都是用前面的同一个,不会再去生成。
这两个情况不太一样。
Q:前面的同一个是指在什么实际上?
A: 就是在第一次的时候生成了之后,都会用第一次生成的这个 Read View,防止我重复读它的数据不一致的情况。
5. 死锁
Q:如果 MySQL 里有死锁的话,会怎么解决?
A: 死锁的解决这一部分我不太了解,但是我知道操作系统的死锁是怎么解决的。
Q:那操作系统这一块怎么解决呢?
A: 操作系统出现死锁,主要有 4 个特点。只要是死锁,它就一定会满足 4 个特点。
首先资源必须是非共享的,然后没抢到就需要等待,还有会出现循环等待。还有资源不可抢占。
只要我从其中一个特点入手,防止它有这样的特点产生,那么它就不会产生死锁。
防止死锁可以预防它出现,或者在出现的时候及时制止。
Q:出现之后的制止一般会怎么制止呢?
A: 出现后制止的话,比如说可以直接释放相应的资源。不过这样可能会导致任务已经执行了很长时间,但是还没结果,直接释放会导致进度全部清零。我主要知道这一点。
Q:有了解银行家算法吗?
A: 银行家算法有了解,它主要是避免死锁。
各个线程在申请资源的时候,银行家算法会进行合理预判,看这个资源分配是否会出现死锁。如果出现了,就不会按照它们的申请进行分配。
Q:如果你在 Java 或者开发里面避免死锁问题,一般会怎么考虑?
A: 在开发中避免死锁的话,我可能会考虑锁不要长时间持有不释放。
还有避免持有一个资源后,又想申请另一个资源,也就是占了很多资源然后一直不释放的情况。
还可以设计一个层级锁。比如说获取第二把锁的时候,需要在持有第一把锁的情况下才可以获取。这样可以防止其他锁占有我想要的那把锁,就可以防止死锁产生。
6. MySQL 索引
Q:MySQL 里有哪些常见的索引?大概它们的使用场景是怎么样?
A: 索引有不同的分类。
如果按数据结构分类,我比较了解的是哈希索引,还有 B+ 树索引。
还有其他分类,比如聚簇索引和非聚簇索引。
还有按照类型来看,比如主键索引、联合索引之类的。分类不同,会有不同的索引。
Q:B 树和 B+ 树做索引的比较有什么区别?
A: B 树和 B+ 树的主要区别是,B 树的非叶子节点也存数据。
B+ 树的话,非叶子节点只做索引,不存数据,只在叶子节点存数据。
这样的区别会造成在做范围搜索、排序的时候,B 树的 IO 开销会比较大,因为它需要去不同地方遍历。
如果是 B+ 树做范围或者排序的话,直接在叶子节点找相应范围,速度会更快,IO 开销会比较小。
所以 MySQL 主要用 B+ 树索引。
7. 最左前缀原则
Q:你了解最左前缀原则吗?加索引的时候。
A: 有了解。最左前缀主要出现在联合索引中。
我在设置联合索引的时候,它是有顺序的。最左前缀主要就是需要按照从左到右出现的索引顺序进行搜索。
如果没有满足,比如缺少了第一个索引,只加了第二个、第三个,那么索引会失效,导致全表扫描,IO 开销和效率都会比较低。
需要满足最左前缀原则,才能合理使用索引。
Q:如果现在有 A、B、C 依次做了一个索引,我用 A 和 B 来查,能命中这个索引吗?
A: ABC 三个索引,用 A 和 B 去查,是可以用到部分的。
它会用到索引,但是效率上可能会比 ABC 全查稍微慢一点。
Q:我要用 A 和 C 来查它的时候,能命中吗?
A: 它应该还是会用到部分的,因为 A 是满足的。其实这部分不太记得了。
8. 索引失效
Q:什么时候索引会失效?
A: 像刚刚说的,没有满足最左前缀原则。
还有一种情况是拿索引直接做一些运算。
还有如果索引发生了隐式转换,那么索引会失效。
我主要了解这几个。
9. MySQL 主从同步
Q:有大概了解 MySQL 主从同步的过程吗?
A: MySQL 主从同步,因为我分布式没怎么做,所以这部分不太清楚。
10. Redis 分布式锁
Q:Redis 怎么做分布式锁?
A: 分布式锁我之前做过的场景,就是在 Redis 里面用 Java 的 Redisson 这个依赖去做,直接加锁。我主要了解这一块。
Q:它有哪些机制,你有没有了解?
A: 我比较清楚的是看门狗机制,会自动续锁。
看门狗机制默认好像是 30 分钟,然后大概每 10 分钟做一次续锁操作,防止分布式锁过期。
如果锁过期了,可能其他资源就会去占用。
11. Redis 持久化
Q:你了解 Redis 怎么做持久化吗?
A: Redis 持久化主要有两种。
一种是 RDB,定期去做持久化。
一种是 AOF,每次操作都会添加到 AOF 文件末尾,每次操作都要记录。
Q:具体的话,它俩会怎么搭配使用吗?
A: 这一块不是很清楚,我主要知道这两个的差别。
12. Redis 集群
Q:Redis 集群实现了解吗?
A: 因为没做过分布式,所以大致了解一些。
比如说有主从、哨兵,还有集群这三个。
Q:这种集群的扩容大概是怎么做的,了解吗?
A: 这部分没有了解多少。
13. Redis 跳表
Q:了解 Redis 跳表这个数据结构吗?
A: 跳表有大致了解,但是不是很深。
它是在链表基础上实现的。
我主要知道通过跳表可以让 ZSet 取数据达到 O(1) 的时间复杂度,速度很快。其他不是很清楚。
14. Redis 大 Key / 大 Value
Q:大的 key 或者大的 value 会有什么问题吗?
A: Redis 的大 key 和大 value,这一部分没有考虑过。
可能会导致内存占用比较多,这部分不是很清楚。
15. HTTP 和 HTTPS
Q:知道 HTTP 和 HTTPS 的区别吗?
A: 知道。HTTPS 主要是在 HTTP 之上,有一个非对称加密,可以让数据不再是明文传输,而是经过加密,让数据传输更安全。
Q:有了解 HTTPS 连接的过程吗?
A: 它是在 TCP 三次握手之上,有一个 TLS 加密通道的建立。
这部分建立主要是发一些公告之类的信息,还有发证书过去,会做证书校验之类的,然后建立加密的安全通道。
16. TCP 可靠传输
Q:TCP 做可靠数据传输,有哪些机制来保证这个事情?
A: 可靠数据传输,我比较了解的是它的窗口,窗口会逐渐增加,还有等待时间也是逐渐增加。
我主要知道这些机制。
还有会校验序列号之类的。
比如 client 和 server,发送过去的时候要带上序列号,另一个需要对序列号加一。这样可以确保双方的信息处理没问题,也可以准确接收到信息。
17. Linux 进程地址空间
Q:有了解 Linux 进程的地址空间吗?
A: 这部分不是很了解。
18. 进程和线程
Q:进程和线程的区别了解吗?
A: 进程就是把一个程序放到内存里面,然后执行起来,它是一个动态的概念。
线程是进程的调度最小单位。
一个进程可以分很多个线程,线程里面又可以执行相应的操作。
19. 协程 / 虚拟线程
Q:你有了解过协程的概念吗?
A: 协程有一些了解。
Java JDK 21 出了虚拟线程,有点类似于协程的概念。
协程主要是多条协程可以对应操作系统里面少量的线程,可以减少操作系统做线程调度的开销。
Q:它和操作系统线程最显著的区别是什么?
A: 这一块不是很了解。
我猜可能是协程之间切换的开销会小一些。
因为它没有经过操作系统内核层。平时线程操作需要切换到内核态,做数据互通之类的操作。
协程没有经过那一层,所以开销会更小一些。
Q:协程运算是否需要加锁?
A: 这部分不是很了解。
20. 海量日志 Top100 高频词设计题
Q:某个搜索引擎每天可能产生百亿级别用户搜索词日志,如果想设计一个可行方案,高效统计每天热度最高的 100 个词,有什么思路?
A: 用户会进行搜索,我需要统计搜索词哪些频度最高。
如果用户量比较大,日志很大,我只取一部分,也能一定程度反映出用户搜索频度排名。
比如用户都喜欢搜手机,那么就算只取前面十万条,大概率也是排在前面或者第一。
所以我可以只取一部分去排序。
读日志的时候逐行读,读到一部分就可以,提取关键词做排序。
Q:如果日志很大,一台电脑内存 loading 不住,但是可以有很多台小机器处理完整日志,想要明确的最热 100 个词,这种条件下怎么做?
A: 如果有很多台机器,可以分配给这些机器。
一个文件可以切成很多个小份,这些小份通过这些机器做运算,得到每台机器的排名。
最后再汇总,汇总出来之后做总的加和,然后再做总排名,这样会比较全。
Q:如果只让你求一个小文件的前 100 个最热词汇,你会用什么排序?
A: 首先先经过计数。
如果要高效取到前 100,我可能考虑用快排,因为快排可以取前 100 个比较高频的。
或者用堆排,构造一个大顶堆,然后弹出前 100 个,可以得到前 100 个高频。
这两个我觉得效率会更好一些。
Q:分日志的时候,你会怎么考虑把日志分散?
A: 机器比较多,可以指定一台机器做扫描分发工作。
按批次分,比如第一批、第二批。第一批扫一部分,分发到一台机器,再扫第二份,分发到另一台机器。
还可以用负载均衡策略,如果一些机器算完了,可以再分发给它继续计算。
每次计算的时候返回相应排序结果给我,我拿到之后做处理、加和之类的操作。
Q:怎么保证同一个词是在一个机器上处理的?如果同一个单词分到两个机器上,统计次数是不是就丢了?怎么保证同一个词就在一个机器上全部统计出来?
A: 我懂了。
可以专门扫一类,或者专门扫几类,给一个机器做计算。
我前面的策略是分批次,比如有 200 条,取前 10 条分给一个机器,再取第 11 到 20 条给第二个机器。
其实它不会出现次数加多的情况。
21. 算法题:滑动窗口最大值
Q:给一个整数数组,有一个大小为 K 的滑动窗口,从数组最左端滑到最右端。每次窗口里有 K 个数字,每次向右滑一位,返回每一次滑动窗口中的最大值。要求时间复杂度 O(n),空间复杂度 O(n)。先聊思路,再实现。
A: 我觉得可以用一个优先队列。
优先队列可以在保持一个队列的情况下,因为窗口固定大小,每次进出的时候维护最大值,就可以完成这个要求,也可以算出结果。
Q:大概是什么样的流程?每一次新放进去会有什么变化?
A: 假设窗口已经满了,每次移动的时候,有一个元素会滑出去。
每次进来一个数据,可以判断队列里面的元素是不是比它大。如果没有它大,就没有必要保留,因为它不是最大值。
我可以直接把那些元素删掉,把这个新元素放到队列里。
在出窗口的时候,判断队头是不是当前要出的那个数。因为它可能之前已经被压掉了。如果是的话,再弹出;如果不是,说明之前已经被压掉,就不用操作。
这样可以维护这个优先队列的最值情况。
Q:你怎么 O(1) 时间找到队列里的最大值?
A: 我在新增加一个数据的时候,如果队尾数据比我要新加的数据小,就直接把小的删掉。
这样的话,队头可以保证一定是最大的。
出队的时候,如果队头和原先要出队的元素不一致,说明它之前已经被压掉了,就不用出队。
Q:队头什么时候会出队?
A: 队头出队的话,就是它本来是最大的,之前加的数据都没有它大,它不会被压掉。
如果它滑出窗口了,就直接出队。
如果队头出队了,后面队列第二个元素就会成为最大值,因为之前已经维护了大小关系。
Q:你先实现一下,然后把三个 case 做测试。
A: 我先做一个简单的。
代码实现过程中,我设计了一个队列:
push的时候,从队尾删除比当前元素小的元素;- 然后把当前元素加入队尾;
max的时候取队头;pop的时候,如果队头等于要滑出的元素,就弹出队头。 第一个 case 没问题。
第二个 case:[2,3,4,2,6,2,5,1],结果是 4,4,6,6,6,5,没问题。
第三个 case:[9,10,9,-7,-3,8,2,-6],K 是 5,结果是 10,10,9,8,也没问题。
22. 反问阶段
Q:最后一个环节,你有什么想问我的吗?
A: 我想问一下,像我们做 Java 的,如果在国际支付里面,可以参加到一些什么业务?
面试官回答: 我们整个项目的语言都是 Go,可能需要转语言。
A: 转语言我觉得不是很大的问题。因为 Go 和 Java 都是做开发,而且都可能涉及高并发相关,我觉得应该没有太大问题。
然后我想问一下,团队里面 AI 工具使用率是不是挺高的?
面试官回答: 目前来说也是大家都在探索加实践的阶段。
A: 比如像 Claude Code、Cursor 之类的 AI Agent 工具,现在应该都在鼓励使用,是吧?
面试官回答: 有自己开源的,也有 Trae 这些 IDE 里集成的,用法不太一样。
A: 好的,各有各的用法。
我还有最后一个问题,后续有没有什么发展建议?
面试官回答: 这个我确实给不出来。
A: 没事,那我没有问题了。