2014年1月7日Google实习电面

作者详细记录了在Google两轮电面中的经历,包括问题解答、面试官对话以及对算法优化和空间复杂度的深入探讨。在第二轮面试中,面对大规模数据排序和质数生成等问题,作者不仅分享了解题思路,还反思了代码实现的效率和优化空间。通过面试过程的回顾,作者展示了在大数据处理和算法设计方面的思考与成长。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Google两轮电面,两个面试官都根据我的背景聊了下big data。

第一轮相谈甚欢,就问了我一个题目:
给K个排好序的链表,总长度为N,求如何合并成一个排好序的总链表。

我先谈了谈直接设K个指针从每个表头开始扫,每次将k个数中的最小数加入总链表。然后我说这个显然没效率的,O(K*N)复杂度。
然后我说应该可以用分治法搞,两两merge,复杂度为O(logK*N)。

之后他问我虽然分治法快,但是相比第一种方法,有什么缺点。
我犹豫了下,感觉没发现什么缺点,然后想歪了,在想是不是不好并行,不够scalable?但是想了下感觉应该不是,然后就随口用疑问的口吻丢出一句“space?”。美国人真nice,直接兴奋的告诉我对啦!就是space,然后一串bulabula...


他之后说让我选一个方法实现。我觉得要实现肯定得实现更有效的啦。
我写了一段代码,他没发现bug,我还发现了一个小bug补上了,原来是忘记考虑输入为null的情况了。他说这个无所谓,我汗,感觉还没我严谨。

之后问我,那你有没有什么方法减小空间的开销。
我觉得这个很简单,直接问输入可以修改不?他表示ok。我就说,那我merge两个链表的时候直接修改两个链表结构,做成in place merge不就行了么,无需额外空间开销。他觉得这个方法可以,不过见我代码是java写的,表示in place merge在java中可不好实现哦,然后又bulabula一串,重点是虽然不好实现,但是仍然可以实现。我看他说得那么兴奋,瀑布汗啊。。。我本身就觉得这个问题分治法开销本来就不大,要是我用c++或者按照LeetCode的ListNode定义,我本来就打算做成in place merge的,只不过他给我定义好接口了,用java API写就没写成in place的。这也是在他问我缺点的时候我疑惑的原因。


第二面听声音是个年纪比较大的人,一开始还跟我讨论校园文化,说他女儿对我校的鼓号队感兴趣,汗哪。。。

第一个问题是个经典问题,问给你millions of documents,如何sort这些string。之前还问我map reduce里sorting是怎么实现的。
我就说数据这么大,用外排序呗,分成一个block一个block的排序,然后in place合并。他问了又些细节,我虽然见过这个问题,但是没有想得那么深入,感觉他对有些细节问题的回答不太满意。
他还问了一个问题,说如果输出的数据也要分块的话,你是如何进行分块操作的。我当时随口一说,可以对每个string加一个data field叫size,做成类似于prefix sum的东西,不过这样肯定不够高效。
他说嗯,这个可以吧,没让我多想。不过事后想了下,发现这个问题太简单了,之前自己还在project中实现过对文本文件的partition。就是先等长划分,然后再调整划分点的位置即可,通过寻找类似于'\0'这样的字符就可以了。后悔死了,不过也怪他没给我时间多想,直接转到下个问题了。

第二个问题让我打印出质数。
我问打印多少或者到哪个数为止,他说不停打印就是了,感觉就是一股老子就是要让cpu飞转的气势。。。
这种数学类问题我完全没有准备,没什么思路,就先从没效率的方法开始说,对于每个数i,检查前面从2到i-1是否存在一个数能够把它除尽。
后来稍微想了下,说与其存储之前所有从2到i-1的数,还不如存这些数最后分解的因子,毕竟之前遇到的因子肯定比之前遇到的数要少得多。
我再想了想,实在想不出什么好方法,就补充道应该可以有数学方法,给出什么复杂的数学公式搞定吧,不过我是学cs的,实在不知道额。他表示同意,说是有数学方法可以解决,不过他自己也看不懂,不要紧。
这样我就放心了,然后他说那你就coding吧。

我的coding虽然没什么大的bug,但是代码有些多余的分析,他看了表示疑惑,觉得不够精简,因为我一开始对每个合数都不停的让之前的因子去除它,直到它不能再被除尽位置。如果剩下的值不为1,就把剩下的值作为新的因子,加入到所遇到的因子列表中。后来发现我忽略了一个重要的问题,每个所遇到的因子,必定为之前遇到过的质数,所以这里的一个不断做除法的循环是完全没必要的。我之后精简了code,他觉得好多了。不过我觉得我的表现他应该不是特别满意吧,毕竟一开始代码不简洁也不高效。

之后他问我如果一直这样循环下去,会有什么后果。我就说cpu一直飞速运行,直到内存溢出,因为内存是不可能存储下所有因子的。

他接着问有没有什么方法让循环持续时间更长,找到更多的质数。
我说那就把这些因子分块写到硬盘上,然后每次遍历所有因子的时候按一个block一个block的来。
他说能不能写下code,我就纳闷,不就加一个for循环么。我直接加了个for each语句。
他看了下,说不高效,这样每次检查一个数是不是质数,都会遍历所有的block,disk io开销太大。
我没听懂意思,以为说我写for each的时候需要预先载入所有的block,我连忙说不是的,这些block是链表形式链接的,把for each语句改成了链表形式的遍历。
他还是不满意,毕竟我没抓住重点。他说你应该把函数接口变下,输入的数据不应该是一个数,而是一个block的数。
我恍然大悟,然后连忙接过话,说这个学过,本质就是编译器课里对嵌套循环的优化嘛,把多层循环分块,提高data locality。然后解释说我以为他是让我在降低time complexity上再下功夫,没想到是让我注重算法复杂度里常数因子的开销啊。他虽然表示同意,但是感觉这个人也许是年纪大的关系,没第一个人活泼,语气很低沉,给我感觉我的表现有些糟糕。

个人感觉第一面挺顺利的,第二面表现有些不佳。看造化吧,发个面经求bless~
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值