字节跳动暑期后端一面(移动OS部门)

字节跳动 · 后端开发实习生 · 一面 · 2026-03

面试题目

基本情况

  • 部门:移动 OS
  • 面试时长:约1小时

自我介绍与项目

  1. 自我介绍
  2. 介绍一段实习经历
    • 用的都是 Java 开发,字节内部大部分是 Go,转语言学习大概需要多久?
    • 实习时间安排?
    • 深挖实习项目细节

MySQL

  1. MySQL 聚簇索引与非聚簇索引的区别是什么?
  2. MySQL 事务隔离级别有哪些?
  3. 可重复读(RR)解决了什么问题?
  4. 间隙锁是什么,发挥什么作用?
  5. MySQL 的 int 占几个字节,bigint 占几个字节?
  6. utf8 编码下,varchar(20) 最多放几个字符?
  7. int(11) 是什么意思?
  8. 如何解决大数据量下的深分页问题?

Redis

  1. Redis 在项目中主要起什么作用?
  2. Redis 热 key 可能会出现什么问题,如何解决?
  3. Redis 常见数据结构,分别有什么作用?
    • zset 为什么可以做排行榜?
    • zset 底层跳表是什么结构,是如何根据 score 排序的?

网络

  1. 项目中都是单体部署的吗?
  2. 小程序端发送请求到服务端的完整过程(网络链路)?
  3. TCP 三次握手的过程,为什么需要三次?

消息队列

  1. 有用过消息队列吗?

手写题

SQL题: 有员工表 e,部门字段 d,查询部门人数多于 50 的部门。

SELECT d FROM e GROUP BY d HAVING COUNT(*) > 50;

算法题: [LeetCode 131] 分割回文串(回溯)

  • 思路:回溯枚举所有分割方式,判断每段是否为回文串(双指针头尾遍历)
  • 追问:判断回文串的时间复杂度?能否优化?(面试官引导方向为动态规划预处理)

参考解析

MySQL 聚簇索引 vs 非聚簇索引

  • 聚簇索引:叶子节点直接存储完整行数据,InnoDB 默认主键为聚簇索引,一张表只能有一个。
  • 非聚簇索引(二级索引):叶子节点存储主键值,查询非索引列时需要回表到聚簇索引再查一次。
  • 覆盖索引可避免回表,是常见优化手段。

事务隔离级别

级别脏读不可重复读幻读
读未提交
读已提交
可重复读(默认)部分解决
串行化
  • InnoDB 在 RR 级别通过 MVCC + 间隙锁 基本解决幻读。

间隙锁(Gap Lock)

  • 锁定索引记录之间的间隙,防止其他事务在该范围内插入新记录,从而防止幻读。
  • 只在 RR 及以上隔离级别生效,范围查询时自动加间隙锁。
  • Next-Key Lock = 行锁 + 间隙锁,是 InnoDB 防幻读的核心机制。

int(11) 的含义

  • 括号内的数字是显示宽度,与存储大小无关,int 始终占 4 字节。
  • 显示宽度配合 ZEROFILL 使用,不足位数补零。
  • MySQL 8.0.17 起已废弃整数类型的显示宽度属性。

深分页优化

  • 问题根因LIMIT 100000, 10 会扫描并丢弃前 10 万行,效率极低。
  • 方案1 - 子查询/延迟关联:先用覆盖索引查出主键,再 JOIN 取完整数据。
    SELECT * FROM t JOIN (SELECT id FROM t ORDER BY id LIMIT 100000,10) tmp USING(id);
  • 方案2 - 游标分页:记录上一页最后一条的 id,用 WHERE id > last_id LIMIT 10,适合顺序翻页。
  • 方案3:业务上限制最大分页深度,超深分页引导用户搜索。

Redis 热 key 问题

  • 问题:单个 key 请求量过大,集中打到同一节点,造成该节点 CPU/带宽瓶颈,甚至宕机。
  • 解决方案
    1. 本地缓存:在应用层用 Caffeine/Guava 缓存热 key,减少 Redis 请求。
    2. key 拆分:将热 key 复制为 key_0~key_N,随机读取分散压力。
    3. 读写分离:扩展 Redis 只读副本分摊读流量。

zset 跳表结构

  • 跳表是多层链表,底层包含所有节点,上层为索引层(按概率抽取)。
  • 每个节点存储 scoremember,所有节点按 score 升序排列
  • 查找时从最高层开始,逐层向右跳跃,时间复杂度 O(log N)。
  • zset 支持按 score 范围查询、排名查询,天然适合排行榜场景。

分割回文串 - 判断回文串优化

  • 面试官引导的优化方向:DP 预处理所有子串是否为回文串,时间 O(n²),之后回溯时 O(1) 查询,避免每次双指针 O(n)。
    # 预处理 dp[i][j] 表示 s[i..j] 是否为回文
    dp[i][j] = (s[i] == s[j]) and dp[i+1][j-1]
  • 总体时间复杂度:O(n · 2ⁿ),预处理不改变回溯部分的指数复杂度,但常数更优。