写在 2022 年末的字节跳动面试复盘

背景

朋友经常跟我说要注意大环境,多看看身边优秀的人活得怎么样,不是说总要比来比去,但是也不能沉溺在舒适圈里,所以偶尔,偶尔会有一些跳出合同跟新球队聊聊加盟的想法。当然,想法在过去很长一段时间都只是想法,直到秋天的几轮裁员,心里才跟自己说:要不面面看?

然而现实很残酷,下半年(特别是 Q4)通常都是电商的发力时间段,让本就不充裕的准备时间更是捉襟见肘,直到面试前两周,征询了一些朋友的建议,决定开摆,看看日常的积累能抵多少的八股文。

面试

由于快到年末了,大家都很忙,所以 HR 微信约了下班后的一面时间。

一面(1 小时 20 分钟)

  • 自我介绍
  • 追踪完整的推广链路(进行分佣)是怎么做的呢?
  • 推广的链接里面会带用户的信息吗?
  • 短链接是自己做的吗,具体是怎么映射长链和跳转的?
  • 这个推广的提成是按照订单维度来算的吗?
  • 这种模式会存在商家作弊吗?
  • 这个短链的长度是固定的吗,是怎么设计的?
  • 跳转的时候用的是 301 还是 302 跳转?为什么?
  • 短链数据为什么从 TiDB 迁移到 MySQL?
  • 短链迁移到 MySQL 做的分库分表依据是什么?
  • 双写的时候怎么保证 TiDB 和 MySQL 数据一致?
  • 短链有典型的冷热数据特点,怎么处理的?
  • 实时核对系统是怎么做的呢?
  • 如果两个系统间的链路太长,数据变更时间很长或者数据丢了,那核对系统要以哪边的数据为准(去修改另一个系统)呢?
  • OpenTracing 这个是基架做的吗,为什么业务团队也要去搭呢?
  • 加入了这么多上报会不会对性能有影响?
  • Tracing 有一定的采样率,如果调用链路中某个服务有报错,它并不一定能被采样到。怎样能使报错的调用都被采样到呢?
  • binlog 有哪几种模式?
  • 为什么需要不同模式?
  • 主机房执行了一个事务,同步到从机房,它的事务性能保证吗?
  • 什么是覆盖索引?
    • 如果一个查询能从某个索引的 B+ 树上拿到所有的数据不需要回表等操作,这个索引就称为这个查询的覆盖索引;
  • 了解索引下推吗?什么情况下会下推到引擎去处理?
    • 通过某个索引没办法按顺序地覆盖所有的查询条件,但是仍然可以利用索引内存在的字段(尽管不是有序的,需要扫描)去进一步过滤;
    • 举例:idx(a,b,c,d),查询条件为 a=? and b=? and d=?,发生下推减少回表数量;
  • 什么场景下索引会失效?
    • 场景有很多,但是如果我是一个引擎,我关注的不是什么情况会失效,而是走什么路径所花费的随机 I/O 和顺序 I/O 最少,如果走某个索引花费的随机 I/O 比从聚簇索引(顺序)查(成本)都还要高,那还不如直接去全表扫描;
    • 典型例子:捞超过全表 30% 的数据;
  • 有没有具体一点的例子?
    • 还是刚刚提到的例子,比如说我要按照 update_time 去做范围查询,捞很多的数据,即使 update_time 有索引,也会选择全表扫描;
  • WHERE id NOT IN (?, ?, ?) 会走索引吗?
    • 还是要看成本;
    • 举例:id 字段只包含 3 个值,1、2、3,3 只有几行,而 1、2 各有 100w 行,如果查询条件是 NOT IN (1, 2) 会走索引,如果查询条件是 NOT IN (3) 不会走索引;
  • Redis 使用的过程中有碰到过一些热 Key、大 Key 的问题吗?
    • 有,能自行定位到的都业务自行处理了;
    • 如果不知道是哪个 Key 导致的,则 rdbdump 导出之后做(离线)分析,看看哪个 Key(哪些 Key 前缀)占的空间特别大,再将他们做哈希、打散等处理;
  • rdb 导出会不会太慢了,比如说里面有一两亿的数据,里面会包含了一些大 Key,怎么样更快找出来?
    • 数据导出会从从节点上导出,不会很慢;
    • 如果觉得导出还是太慢,可以看看 Redis 是否有提供什么命令直接找,印象中有命令能找出 Value 大于特定值的 Key;
  • 如果有一些热点 Key,比如某个链接被明星分享了,访问就会很频繁,怎么办?
    • Redis 存放的就该是热点数据,所以觉得这个应该是服务它的使用场景的;
    • 如果热点数据里面的 Value 太大了,因为它是单线程操作的,可能会导致一些压力,可以尝试使用 Redis 6 的多线程来缓解网络 I/O 上的压力;
  • 如果定位到了热 Key 之后怎么防止它把单个节点打爆呢?
    • 减少 Value 的体积然后用 Redis 做索引,把实际的内容放到其他存储去;
    • (答非所问)
  • 用 RAND(5) 实现 RAND(7)?
    • 眼熟,但是不会;
  • A 和 B 从一堆棋子中轮流取,每次需要取走 1-5 个棋子,A 先取,如何必胜?
    • 眼熟,讨论了一会;
  • 翻转链表中的第 m 至 n 的节点
    • 不难;

反问环节

  • 团队里面大约有多少个仓库、部署了多少服务(大致规模)?
  • 这些项目会做单元测试吗,或者说平时的自测、代码质量保障是通过什么方式做的?
    • 工具类的库会写单测;
    • 自动化测试会由流量回放平台,QA 执行常用的用例;
  • 整个流量回放都是 QA 负责的吗?
    • 后端需要在代码里面做配合;
  • 一个业务迭代版本是怎么安排时间发布的呢,比如说是每周固定发布还是说测试完成后的几天发布?
    • 按双月来排期,产品拟定优先级, 研发扣除 oncall 等时间分配任务;
  • oncall 那周安排多少时间精力做 oncall 和其它问题?
    • 80% 时间在 oncall,剩下的时间会看情况修复一下线上和其他的小问题;
  • 前面很多问题都没有答对,面试官的建议?

第二天收到 HR 的电话约了二面时间。

二面(1 小时 5 分钟)

  • 说一下短链接业务的背景、上下文?
  • 为什么要用短链接,短链接到底解决什么问题?
  • 有没有看过这些短链带来的点击或者成交量有多少?
  • 造成到达率只有 50% 不到(商品页浏览数/短链点击数)原因是什么呢?
  • 项目的机房部署是怎么样的?
  • 东南亚到美洲的机房时延大概是多少?
  • 项目如果跨机房部署,会遇到什么技术问题呢?
  • 在项目中是主导设计还是主力开发?
  • 这个系统是你从 0 到 1 做起来的吗?
  • 能说一下项目的系统架构吗?
  • 短链从用户分享、短链生成到用户点击在系统里面的工作过程?
  • 301 跟 302 跳转有什么区别,具体会发生什么事情?
  • 301 或 302,以及还有一种链接不会发生变化的跳转,具体在 HTTP 协议中是什么命令?
  • 在做短链系统里面哪些地方是技术难点?
    • 短链 ID 如何设计;
    • 短链系统是流量入口,因此重点关注高可用;
    • 访问数据实时和离线的分析;
  • 分库分表是怎么做的,为什么需要分库分表?
    • 数据增长较快;
    • 单点的访问模式,保持较小的 B+ 树有利于访问性能;
  • 数据增长快,为什么不考虑冷热数据分离,定期归档?
  • 业务场景里面不太可能有统计,实际上都是 KV 查询,压力应该不大,需要分表吗?
  • TiDB 迁移到 MySQL 后耗时大幅降低是做了什么优化?
  • 这种场景里面写入耗时长可否容忍?
  • 在这个大量 KV 数据读写的场景,为什么不考虑直接使用 KV 存储或者 Redis 来支撑?
  • 为何不考虑数据仓库提供 HBase 来支持读写,节约掉 MySQL / KV 存储同步到数仓的过程?
  • 能说一下 LevelDB 的存储结构吗?
  • 实现 Redis 跳跃表
  • 为什么考虑换工作?
  • 未来 4 年的规划?

反问环节

  • 在字节的技术人对于公司的基础架构的满意程度如何?
    • 该有的都有;
  • 外出参加技术会议、交流在字节里机会是否丰富?
  • 前面很多问题都没有答对,面试官的建议?