Recruiter主动联系的,我也没怎么准备,就随便面面。最后没面过。
电面
题目是设计一个stack, 同时可以读取并弹出最大值。弹出最大值的时候,stack里其他的元素不受影响,相当于强行从stack中间去掉一个元素。
面试官给的是Java的一个类,但是我习惯用Python面试,就手动把Java的代码改写成了Python. 这个题目用Python不好写。用Java写的话,大致应该是用链表来实现stack, 同时用heap/priority queue记录最大值,heap里存的是指针。数据入栈/出栈的时候同时更新heap。弹出最大值的时候从heap里移除,并且从stack里也移除。
我用Python七七八八写了一个版本。LinkedIn用的是Coderpad, 不能现场运行代码,跟面试官讲讲思路就结束了。面试官估计人比较好,就给了过。
Virtual Onsite
第一轮 SRE troubleshooting
面试官是两个大胡子白人大叔。给了一个虚拟主机的IP地址,SSH进去,调试一个web app. 有三个问题,每解决一个需要在UI上填写oncall日志。具体细节记不太清了,不过问题基本都在一个systemd的unit文件里,需要会用journalctl看系统日志,用systemctl管理服务。这轮我应该做得比较好。
第二轮 算法
国人面试官。题目是一个一维数组,表示海岸线,1表示陆地,0表示海洋。另一个长度相同的数组,对应于海岸线数组,每个元素表示把对应位置的海洋改造成陆地的费用。如果已经是陆地了,费用就是0. 还有一个参数是总的budget. 题目问的是,在预算限制下,如何改造海洋,可以使连续的陆地最长。比如,
land = [0, 1, 1, 0, 0, 1, 1, 0]
cost = [3, 0, 0, 2, 1, 0, 0, 5]
budget = 3
那么结果就是6, 方法是把下标为3和4的两个位置改造成陆地。
一开始我想得有些复杂,后来经过面试官一些提示以后写了一个应该是对的版本。就是用two pointers, 快指针先不断尝试把海洋改造成陆地,同时扣除相应的cost, 直到budget不够了,就移动慢指针,撤销之前的改造操作,并且把cost加回来。一路上记录当前操作下最长的陆地的长度。扫完一遍就能得到结果。
第三轮 Behavior
面试官是白人大叔。主要问的点是作为staff engineer, 怎么delegate, 怎么培养手下的junior, 怎么scale自己。
第四轮 Tools Coding
这个貌似是SRE特有的面试。面试官是国人大叔带了一个白人小弟。国人大叔英语不太好,沟通上有点小问题。问了两个题目。
第一个是OOD设计一个CI/CD系统的数据结构。包括build, deploy等各种对象。一开始我没太懂,以为是要设计完整的实现,后来才发现只要设计一个base class, 里面包含execute, getStatus就行了。然后还需要处理一个context的变量,我也不知道是应该把context存在类里面,还是每次调用execute的时候传进去。
第二个问题是算法题,给出一个软件的依赖关系,dependency graph, 以及一个package的名字,计算出这个package直接或者间接依赖的所有package的名字。比如
dependency = {'foo': ['bar', 'baz'], 'bar': ['baz'], 'baz': []}
package = 'foo'
那么输出就是
['bar', 'baz']
我一开始就直接用BFS实现了一个简单的版本。但是后来我问有没有circular dependency, 他说有的。如果遇到的话,要输出哪个package开始循环了。这个在BFS的基础上不太好改,瞎试了一通没成功。后来面试官提示要不要用DFS写。就匆匆忙忙写了一个DFS的版本,但是时间不够go over一遍了。
加面
估计是两轮coding不够solid, 就重新安排了加面两轮。
第一轮 算法
面试官是操着一口英式英语的大爷,是做network infra的。上来就跟我聊简历聊项目聊半天,还说他不喜欢面这种算法题,他自己都不熟练。但是因为公司规定必须按照某个标准打分,所以就只能面一下了。题目是Word Ladder, 差不多就是原题。但是因为我好多年没刷题了,早就不记得细节了。七七八八写了一个差不多的版本,反正也不能现场跑。写完以后大爷又跟我聊了好久各种network infra, DNS之类的东西。
第二轮 Tools Coding
这轮体验非常差,是一个视频都不开的印度人面试官,全程无交流。而且好多次我问他问题,他都mute了,等了一会儿才打开麦克风回复。同样是两道题。
第一题是LeetCode 1882 Process Tasks Using Servers, 怎奈我上次刷题的时候LeetCode还不到一千道题目,所有序号大于1000的我都没刷过。正确的解法要用两个heap,一个存available的server, 另一个存busy server. 我只用了一个heap. 没写出来。
第二题似乎没在LeetCode上出现过类似的。输入输出是这样的
Input:
M = 4, N = 4
apps = [ [1, 2], [2, 3, 4], [3], [1] ]
connections = [ [1, 2], [2, 3], [3, 4] ]
durability = [10, 8, 12]
K = 9
Output:
[1, 3]
题目意思是,有一些application, 运行在一些server上。apps
里存的是每个server上的app ID. 比如第一个server上跑了app 1和app 2. 同一个app可以有多个组件跑在不同的server上,比如app 1就同时跑在server 0和server 3上。connection
数组是这些server之间的网络连接。比如server 1和server 2之间有连接。durability
是每个连接的耐久度。发生地震的时候,耐久度小于K
的连接会中断。问题问的是,计算出地震以后会挂掉的app的IDs.挂掉的定义是,同一个app ID的多个组件所在的servers之间的连接如果中断了,就算挂掉。
我的做法是先用邻接表存图,然后计算出每个app ID所有组件之间的path, 然后在计算地震以后断掉的连接会影响到哪些path. 不过后来一直卡在如果两个组件之间有多个path应该怎么处理的问题上。最后时间来不及,也没写完。
感觉面这种传统大公司还是要刷题的,基本上就是面标准的LeetCode风格的题目,不像startup更注重实际经验。
太强了,我何时才可以有staff level的面试呀!