最近在往外投简历, 心想拿着两年LLVM的经验投SDE多少有点委屈, 索性看了看有没有做compiler的我还能用得上, Nvidia, AMD, Intel就都看了。 最后Nvidia看起来最猛, 第一天投简历第二天约面试, 刚刚收到下一轮面试邀请。
面试的老哥是在Nvidia待了12年的老哥了, 口音有点印度/中亚感觉, 估计应该是入职以后的team leader。 以下是聊天经过。
开头先介绍了一下他们组是做什么的。 大致上就是中间层代码优化(IR Optimization), 底层代码优化有做芯片的一帮人,上层应用有cuda及其他(其实是除了cuda其他应用我都没听说过也没记下来…)。 大概说了五分钟。
然后我花十分钟说了下我简历上过去两个LLVM相关的项目具体做的是什么。 他也不太关心我除开LLVM的贡献, 更多是关心我具体用LLVM写了啥。
之后就是一些琐碎的问题, 可以看出来面试官并没有抱着一个要考倒我的心态, 而是一步步在摸索我什么知道什么不知道, 对不知道的东西也会耐心的指导一下(墙裂好评。
“你对LLVM的熟悉程度怎么样”。 对前端clang那边了解不多,中间层(IR)做过很多工作也读了一些代码, 后端代码生成只是读了些代码和文档没有上过手。
那你有没有读过LLVM IR的文档, 这个我读过。
那你知不知道getelementptr
这个指令, 我给他解释了一遍, 也说了一下我之前一个项目是怎么用的这个指令。
进一步问你知不知道什么是inbound
,我说这个我不知道。
他解释说getelementptr
本质上只是帮你算一个index,参数给的不好的话可以算出任何奇怪的结果, inbound
修饰保证了算出来的结果不会出界。
“你一般用什么编译器”, LLVM
“有没有读过optimization的代码”, 无,但是我知道工作原理
“你知道哪些optimization”, 这个地方聊的比较多。 常数替换, Loop unrolling, function inline, 代码序替换 然后深入问了loop unrolling和function inline的motivation。 这个除了说减少jump以外我还真不熟, 他就举了个例子, 如果函数参数是常数就可以移除一部分branch然后做inline。
你上过哪些编译原理的课。 我说我本科修了编译原理, 前端从finite automata,Lexical analysis, 到pushdown automata, parser; 类型系统semantic analysis都讲了。 中间代码生成,后端优化讲了但是比较浅。 (其实我可以吹一下本科把斯坦福哪个COOL compiler从头到尾写了一遍, 但是这个属于远古历史没有太大讲的必要我估计) 然后研究生在Davis修了Programming languages(ECS 240), 更多是讲CFG,DFG;静态分析,代码优化的。 老哥听我一大摞说了这么多估计是我都熟也就没继续问下去
问我C/C++怎么样。 这话真把我问怂了, 千把行也不是没有写过, 但是远没有Rust来的舒心, 我就说C++还行吧, 不敢说bug free, 反正能写能debug 那C呢, 我说这个我行, C++就是有太多不读文档都不知道哪来的隐式语义。 老哥会心一笑, 被坑过的都懂
然后问了点C/C++的基础。
这部分我是真的菜。
先是两个struct的size, 第一个我倒是说出来了, 第二个不知道怎么脑子抽的说了个5, 然后面试官问我那我给一个Dummy2[2]
尺寸是多少吗, 意识到了自己的错误。
struct Dummy1 {
char c;
int i;
}
struct Dummy2 {
int i;
char c;
}
啥是多态,这个我倒是答出来了; 进一步问我有没有静态多态(static polymorphism), 我想了想你说的别是函数重载把? 他说是。
最后算是一个应用题。 说你写了个编译器, 编译了一个30个文件的应用, 结果应用炸了, 怎么debug。 我说先用正常编译器看看, 如果应用也炸了那就和我编译器无关。 否则就前后端分离测试, 我编译一个IR给LLVM的后端;然后用LLVM编出来的IR给我的后端就知道bug在前端后端了。 我说实际上我上次遇到类似的问题就是这么debug的。
面试官说可能我的前端输出没问题,但是和LLVM不一样, 实际上问题在后端。 我说这个不应该,但是我是假设了前端结果一致,这个假设其实没有道理的。 他说搞优化的日常就是前端结果不一样,debug半天是后端的锅, 这里看起来还是我经验不足。
这个时候其实预约的45分钟就到了, 但是我问的几个问题愣是聊到了一个小时。