Netapp On-site Interview

在入职了两个多月之后我才发现我当时面试的内容居然没有记录下来,而且有意思的是,在我入职之后我们组面试的若干senior level的人的面试问题都和我当时的差不多,只是会更深入。所以,我要趁着自己还记得这些问题是什么赶紧记录下来。

面试的itinerary是从早上9:45到晚上4:15,先是2个小时的coding exercise,然后45分钟的lunch time,然后45分钟一轮总共4轮,再最后是45分钟的wrap up。

Coding Exercise

早上提前到了10分钟,去了个卫生间镇定了一下,然后就进门去打了个招呼就被带去接水然后关小屋开始面试了。先是大概问了我一下背景,然后问我是否comfortable with java coding,我说没问题,反正和C#没差多少。然后就是coding exercise正题了,要求我在两个小时内写一个Log Merger。Log是server来的log,每一行内容都是一条单独的事件,且都是固定的时间戳 - Log Level - Log正文格式,在一个固定路径的文件夹下放着。debug用的log文件只有10个,每个500K往上,要求考虑比如100个log每个10M以上且机器的memory被限定在1G左右的情况。最终merge的结果要将所有的log事件按时间顺序升序排列,没有secondory sorting要求。给我的机器可以联网可以查API,然后面试我的人就走了。

这个问题的思路其实也不算难,首先考虑限制条件,就是memory不够的问题,所以一个必然不可取的方式就是把所有的文件全读入memory然后按时间戳排序,而一个必须要展现出来考虑到的点就是如何使用固定的memory。当然我也是好查了一阵Java的File IO都怎么搞,并搞了个内部类处理每一条log,然后因为时间不太够就先搞了一个无视memory的版本出来work。写了一个多小时以后面试官回来我们又过了一遍code,并讨论了一下如果100个文件的话应该是用一个长度为100的数组放文件指针,每个读一行,再另搞一个priority queue来不停地处理那100条log,这样就能保证占用的memory不至于超标。

午饭with manager

中午饭是我未来(也就是现在)的boss带我逛了一下这个楼,去楼里的cafe随便买了点东西吃吃聊聊,各种behavior,互相问了一些比较关注的问题。总的来说很轻松。

第一轮

饭后回来第一轮来的面试官我之前查是一个葡萄牙人,入职了之后才知道是我们这边level最高的MTS 6。。。先是简单且quick的询问比较印象深刻or最酷的项目内容,然后问了一个OO的基础概念问题,并对我完全不熟所以瞎写的答案表示我需要好好学习一下,就问我第二个白板coding问题了:

假设有一个函数可以做rest api call并返回一个json,其中带有几个有nested关系的attribute,给我一个函数的signature,让我把它的内容补完。

具体的attribute是什么我记不住了,反正通过分析可以得知,其实就是个BFS,只是因为rest api call得到的json会返回一些已经访问过的内容,所以还需要一个单独的hashmap来保存已经检查过的node防止重复搜索。写完之后面试官进来和我过了一遍code,表示嗯应该是work的,然后问我这是个tree吧?我说嗯。这是个Depth First吧?我说啥,不对啊,Breadth啊?又问我两次这应该是Depth吧,最后来了一句You are right, i’m kidding, it’s breadth,我。。。然后让我问了若干问题就over了。

第二轮

似乎第一轮花的时间长了点,加上面我的三哥有点其他的事情,所以他来的时候就说我们这轮可能会很短,然后也是简单问了一下我的背景就开始白板了,具体内容参考这里

第三轮

第三轮来的是之前给我做phone screen的三哥,套路和前几位一样是简单的back ground然后就是白板题。问题很简单,merge两个排好序的数组,具体参考leetcode不多说。写完之后开始让我写一些test case,我也是第一次遇到要写test case的问题,就看着code写了一些,觉得差不多之后三哥向我指出有一部分的code所写的条件没有被完全覆盖,告诉我这叫code coverage,于是赶紧补上。然后让我问了若干问题也到时间了,感觉问题也不算大。

第四轮

第四轮的面试官也是简单地问了问背景,就给我讲解了一下java 8里新引入的stream()和lambda特性,然后开始白板。问题大意是,假设如果我们有一个collection,每一个album还是一个collection,然后我们要挑出其中长度大于60s的track,给了我用双层loop的写法,然后给了我几个lambda相关的api,让我写成lambda形式。

因为C#里我也是经常用linq,所以这个也不难,加上面试官对于api的解释其实已经给了很强的提示,所以很快就出来了,于是就开始进入drill down的环节。

首先问我觉得这两种写法在性能上是否有差距,我个人觉得可能不会有太大,如果真的有的话也是双层loop的可能会由于JVM的优化而更快一些?这么猜的。

然后又问我,那lambda这种stream的写法我认为有什么优点,我说这东西其实主要在于好distribute做parallel computation,然后拿出当年搞超级计算机的时候的经历扯了一下,表示双层loop的写法也可以,但是写起来太痛苦了,而且缺少通用性,不同的条件要进行不同的tuning来达到最好的效果。

接着再问我既然这个如此便利那我是否同意应该无条件地多进行streaming,我说那必然不是,distributed computation本质上就是用更多的computation node来换时间,但是这个换也不是无消耗的,controller和所有node进行通信的时候也是有overhead的,所以要考虑这个trade-off,不能无条件地搞啊。面试官表示ok,然后也是让我问了问就over了。

Wrap up

最后又是和manager 1对1,问了我对于自己今天表现的评价,我也是如实对答表示下午刚回来有点差,后来还可以。又问了问期望的薪水和福利啦,能入职的最早的时间啦,其他一些乱七八糟的,再对我进行了一圈安利就愉快地结束了。

后来

后来我就拿到offer了,从HR给我发邮件约电话到最后入职差不多4周,其中一周多还是等背景调查公司的结果什么的。

经验教训

  • 对自己的简历要滚瓜烂熟,知道哪些细节没在上面但是可以拿出来说
  • 广泛涉猎是有帮助的,比如我这种从C#入门靠超级计算机和LU分解的论文毕业的
  • 刷题很重要,尤其是经典算法的代码骨架一定要熟悉
  • 生产环境中的问题会有诸多限制,这些也是challenge,一定要多想想

以上。

17-08-30
@Imperial Village