4945 字
约 16 分钟
1
字节国际支付后端一面

字节国际支付后端一面

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: 没事,那我没有问题了。

字节国际支付后端一面
http://www.clxhxhhr.top/posts/813/
作者
clxstart
发布于
2026-09-18
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。