大概 bg 是 2 本 9 硕,方向是存储/db,之前在一家初创实习过,其他的 bg 和一般的鸡架选手差不多。

海投与选择

起因是对在学校的生活不太满意,感觉生命就在一行行 LaTex 中凋零。加上刚好组里刚好有一些合作,就索性想再回工业界看看,不料被阿里云 hr 光速挂了简历,遂道心破碎开始海投,投过的加上联系的大概有:

  • PingCAP:曾经的梦中情司,投的时候内核没 hc 了,转到后端但也因为背景不太 match 挂掉了
  • 小红书:RedStore 对象存储,简历挂,说是背景不 match(推测是简历上全是 Rust,没有 C++ 相关的内容)
  • 小红书:对象存储索引开发,RedStore 挂简历之后被捞过来了一面,感觉不缺人,泡了两周池子挂掉了
  • 字节:TikTok 的性能优化部门,在 Boss 上被主动问了,索性就面一下了
  • 百度:分布式文件系统部门,找 J 神内推了,不过百度年底会盘点 hc,一直没 hc,戏剧性的是在入职当天才终于有了 hc
  • 阿里云:挂完简历之后最后还是被捞起来了 可能又是因为年底的原因,各家 hc 不多(感觉是投太早了,各家三月陆陆续续才开始暑期,不得不说今年形式看起来是真好啊),最终收获的 offer只有字节和阿里云以及前司的续约。考虑到今后的发展,最终还是选择了阿里云这边,拒掉了字节和前司的续约,开始了杭漂生活。 想了很多,写了很多,最后也删了很多,最后就留下了一些碎碎念。

碎碎念

前几个月在学校一度有些emo,感觉自己每天干的活并没有什么意义。从去年搞完fast的rebuttal后,基本上也再也没写过什么代码了,后续处理camera ready和新的投稿,在三个月的时间里,几乎只有在和Latex打交道。从入学之后,生活逐渐从过程驱动转变成了成果驱动,在干活的时候想的也是尽快搞完投出去,中了就如释重负了。虽然也出了一些成果,但是很难说我享受这个过程,也很难说学到了什么。有时候也会被问起想不想读博,或者被说起有一篇A不读博可惜了,但是当我真正的反问自己,“这真是我想要的吗”,“我真的享受这个过程吗”,得到的答案也往往是否定的,因此我想我最终的归宿大概还是工业界吧。可能是我对科研祛魅了,也有可能是我长久以来始终是偏工程角度的思考问题。长久以来,我觉得我做的不错的是coding部分,我也比较享受系统实现,但目前看来,系统实现和实验只是科研的一环,还是不那么重要的一环,有一种没有实现自己价值的感觉,让我相当郁闷。 读研之后,让我感受到的最大的不同是,读研有一种很诡异的自主感,为什么说诡异呢,在本科的时候,一切都是为了自己,我可以开足马力997都无所谓,哪天累了就给自己放个假。但现在不同的是,形成了一种能者多劳,越能越劳的状况,反而有点主动变被动了,开始被项目推着往前走,变成了“能干活就有干不完的活”,其他的一些人反而清闲自在。当然项目做好了也有对自己的提升,但是明显也有一些绷不住的dirty work。作为最底层的科研牛马,国内硕士的现状大抵如此,一个人也无力去改变什么,只能在深夜敲击键盘来发泄心中的郁闷。 来到这边之后,由于是RI,做的内容也便research一些。但相比于在学校所做的工作基本上只有修改论文把故事讲好。在这边的工作还是更加有自驱力和成就感。工作内容目前没有参与实际工程开发,大概是有一个探索性质的需求,自己做一些各方面的调研与实现,虽然也免不了被一些陈年屎山恶心,但是在一个具体的场景下,去发现问题,解决问题还是开心很多。捡起了荒废已久的c++,也找回了消失已久的技术热情。在学校时慢慢地就形成了一种自我保护机制,干活留一点劲,剩下一点时间给自己,但很不幸,这一部分留给自己的时间没有好好利用,大多都拿来摸鱼了。来这边之后也没理由继续摆下去了,希望能像P5里的那首歌那样,Life will change吧。

面经

最后放一些面经,希望能帮到一些人:

小红书

IO 与系统

  • 介绍一下 pwrite 的整个流程
  • 顺序读场景下 direct io 和 buffer io 性能对比分析
  • page cache 的 prefetch 机制有了解吗,page cache 的大小是由谁决定的
  • 数据拷贝过程,从磁盘到 cpu 的 L1 cache
  • 异步 io 用过吗
  • 同步 io 的情况下,cpu 的使用情况,介绍一下 DMA
  • io_uring 相比 aio 性能好在哪里,主要是哪方面减少了开销
  • io_uring 的 polling 模式和 SPDK 比较
  • 说一下项目中的性能测试部分,SSD 中的 cache 会对性能产生影响吗,这一块是怎么处理的

存储引擎

  • 介绍一下 B+Tree 和 LSM-Tree
  • B+Tree 并发控制,介绍一下 latch crabbing
  • 二者各自的读写放大情况
  • LSM-Tree 的 delete 操作,墓碑什么时候能被删除
  • 大量的 delete 对性能的影响,解决方案
  • 说一下 LSM-Tree 的 KV 分离,KV 分离的负面影响,有什么解决方案
  • KV 分离导致 scan 性能下降的问题,目前学术界有什么解决的方案
  • RocksDB 的 WriteBatch,如何保证原子性,项目当中又是如何保证原子性的
  • RocksDB 的一致性读,memtable 当中如何保证一致性读

分布式

  • Raft 大论文中的 PreVote
  • Raft 需要持久化的信息,voteFor 丢失会怎么样
  • joint consensus

C++

  • std::move
  • C++ shared_ptr 的线程安全是怎么实现的
  • 介绍一下内存序都有哪些,对于 release-acquire,happens-before 是如何建立的

算法

  • 二分搜索数的范围

TikTok

一面

  • 自我介绍
  • 实习中最有收获的部分
  • 介绍一下 prepared statement 的实现方式和流程
  • SQL engine 是怎么实现的
  • 介绍一下 AST、Logical Plan、Physical Plan 之间的联系和总的生成过程
  • explain 命令是如何实现的
  • Rust 内存管理,介绍一下所有权的机制
  • 从内存分配的角度介绍一下 Rust 的所有权,包括栈/堆相关的内容
  • 说一下 Box
  • Rust 并发,async/await 关键字的意义和机制
  • 比较一下 Rust 的协程和 gorountine
  • 协程为什么轻量
  • 有栈协程和无栈协程的区别
  • 如何排查一个系统的性能,Rust 业务中发现有 cpu 打不上去的情况,如何分析和定位问题
  • 介绍一下 LevelDB
  • 说一下 LevelDB 的 trade-off
  • SST 的结构
  • 读写放大和解决方式
  • LevelDB 的整个写入流程
  • 题:Leetcode 复制随机链表

二面

开始是在聊实习,主要还是在围绕性能优化在聊,因为部门主要是做性能优化的,而且实习也有很多工作是性能优化相关。

  • 介绍一下实习工作
  • 为什么从 C++ 切到 Rust
  • Rust 为什么内存安全
  • 优化工作中涉及到了锁,锁的实际开销是夺少
  • 都有哪几种锁
  • 锁和原子变量的区别
  • 进程间通信方法
  • SQL 中 join 的意义是什么,说一下
  • MySQL 的 B+Tree
  • 网络模型
  • 熟悉的数据结构和算法
  • C++ weak_ptr
  • 题:两个栈模拟队列
  • 场景题:用户怎么获取附近的网约车位置

三面

实习
  • 介绍一下都做了哪些工作
  • 时序数据库主要针对什么场景,系统的架构是什么样的
  • 为什么采取列式存储,优势是什么,列式存储怎么完成按行读取,列式的统计信息,类 LSM 架构怎么做 compaction
  • 介绍一下 prepared statement
  • 乱序数据处理的方案,merge reader 的实现,ts 有重叠下的统计信息会怎么样
八股
  • Redis 了解吗(不了解)
  • fork 和 copy on write
  • a = fork(), b = fork(), print(a, b)
  • 介绍一下内核态
  • context switch 的开销
  • 刚才提到了 kernel bypass,举个例子?(说了 SPDK,又让简单介绍一下)
  • nlogn 的排序算法
  • 链表情况下,归并排序的时间复杂度是什么
  • 题:单链表归并排序