项目库
课程 & 毕设Amazon · 软件开发工程师 · 2022

为数据库课写的一个带预写日志(WAL)的迷你键值存储

分享者:J. Okafor · 前 Amazon 应届软件工程师

分享者在 Amazon 应届生面试环节讲的就是这个项目,后来拿到了 offer。

走进这场面试

4 个当年真实追问 · 1 个 hard · 约 12 分钟

答完每一题,才翻开当事人当年的接法。

他们当时是怎么讲的

我给一门系统课做了个单机键值存储,结果它在面试里变成了半小时关于持久性权衡的深聊——因为我很坦白地讲了它哪里会崩。

展开全文

这是我本科数据库课的期末项目。作业要求用 Java 写一个持久化的键值存储,评分标准很看重崩溃恢复。预写日志(WAL)那部分是我自己做的;另外两个队友负责 B 树索引和命令行界面。我这块的活儿是:每次 put/delete 先追加写到日志文件,再动内存里的 map,启动时重放日志。我把 fsync 搞定了,这样写到一半被 kill -9 也不会丢已提交的数据。它崩的地方在于:日志会一直无限增长,因为我压根没写压缩(compaction)和检查点(checkpointing),所以日志一大,重启就慢。我们大概就两周时间,所以我砍掉了检查点,直接在 README 里把它记成一个已知的限制。这东西从来没被真正用过,就是拿去评了个分而已。面试里我一上来就把话说在前头,先讲『这是个课程项目,这块是我负责的』,然后走了一遍持久性的链路。面试官一直追问:如果机器正好在 fsync 过程中挂了会怎么样,我只能当场推理撕裂写(torn write)的情况,而不是假装我早就处理好了。

当年真实被问到的

带我走一遍一次 put 到底发生了什么,从调用一直到数据真正落盘。

中等

如果进程在写一条日志记录写到一半时崩了,会怎么样?

困难

哪部分是你做的,哪部分是队友做的?

简单

以你现在的认知,你会最先改哪里?

中等