2010年3月31日星期三

随便写写一些经验吧 ZZ from mitbbs

1
先声明下,我的经验有点局限于少数几个大公司的software engineer的职位,如果你是想找local中小公司/startup或者非software engineer工作,就随便看看了。

大致的背景是,本科物理,物理Phd读了两年quit掉phd(phd期间的研究是做fabrication的,跟CS完全无关),转行读EECS,还是在同一个学校(学校很普通,专业排名30-40几)。主要是觉得CS好找工作吧,我自己也比较喜欢这个,有一定的编程功底。我不知道从长远看这个决定如何,但是短期内看还是正确的决定了。
说说CS相关的背景吧:尽管我是物理出身,本科C和数据结构还是学的不错的,学过些基本的数据库但是忘干净了,微机原理汇编什么的也学过,学过一点的数值方法计算模拟的东西,大一参加过校内的ACM选拔赛入围不过没继续下去了,本科给几个实验室打工写过一些小软件(跟实验仪器通讯和数据采集处理)。不过来美国后就没怎么写过程序了。

可能有人要笑,你这个连OS,compiler,network都没学过的外行,也没有真正的软件开发经历不懂OOD不懂Software engineering,也没有个擅长的领域比如machine learning什么的。确实,没学过这些东西还是给我很大的困难,去年秋天还是花了不少的精力去自学OS和上internet的课。后来也花了一些精力了解了一下software engineering和OOD,但是还是自己觉得这方面欠缺很多。

去年4月正式决定转行到CS,4-9月期间认真把C++ Primer学习了好几遍,算法书CLRS看了一两遍,算是为找工作打下了些基础。大概去年秋天正式加入找工作的大队伍,开始混迹于本版。


先搜集整理一下以前已经写过发过的东西,免得做重复功:

在本版初来匝道时发的询问贴,写了自己的背景:
http://www.mitbbs.com/article_t/JobHunting/31438767.html

去年9月参加过一次程序比赛,后来证明对找工作还是有用的:
http://www.mitbbs.com/article_t/JobHunting/31434477.html

第一次Google onsite完后写的面经:
http://www.mitbbs.com/article/JobHunting/31494979_3.html

第二次Google onsite完后写的面经:
http://www.mitbbs.com/article_t/JobHunting/31510877.html

微软校园面经:
http://www.mitbbs.com/article/JobHunting/31494989_3.html

网上逛到的老美的面经的blog: 其实碰到还有很多的其他的面经没有记下来,大家可以多去搜,网上还是有不少老美在自己blog写面经的,别光局限于买买提看面经:
http://www.mitbbs.com/article/JobHunting/31517887.html

做的一个好玩的梦:
http://www.mitbbs.com/article/JobHunting/31517443_3.html

Amazon电面面经:
http://www.mitbbs.com/article/JobHunting/31502227_3.html (1面)
http://www.mitbbs.com/article/JobHunting/31520671_3.html (2面)

我blog上以前总结的一些题目的日志:
http://www.mitbbs.com/article/JobHunting/31502229_3.html
http://www.mitbbs.com/article/JobHunting/31502231_3.html
http://www.mitbbs.com/article/JobHunting/31502237_3.html
http://www.mitbbs.com/article/JobHunting/31502251_3.html

关于算法书(CLRS)上的内容跟面试的关系,个人意见:
http://www.mitbbs.com/article/JobHunting/31526973_3.html
http://www.mitbbs.com/article/JobHunting/31527013_3.html (课外内容)

额外的一些内容:

DP: 刘汝佳的算法竞赛书里面讲DP那部分很适合于进阶;MIT有一个网页上面专门有一些不错的DP题和solution

suffix tree: 这个了解一些我觉得还是有帮助

trees: 什么AVL, Red-black-tree, dsw算法,B tree, B+ tree, K-D tree(spatial partition), R-tree,都可以了解一下

hashing: extensible hashing/linear hashing (dynamic hashing) multi-level hashing (grace hashing) etc

----------------------------------------

2.
想写的东西很乱,想总结点什么出来也理不清楚思路,还是按着时间顺序讲讲吧,顺带
着用画外音做点总结发点感想:

去年4月份开始因为还不急着找工作投简历什么的,规划着先把找工作的基础打牢(画外
音,规划好时间计划很重要,尤其是对于刚刚开始找工作的同学,如果因为准备不够充
分而fail一个不错的面试机会还是很可惜的),C++ primer 4th edition我是读了2遍,
后来9-10月又读了一遍。事实上后来证明了,C++上花的精力有点过多了,我甚至把所
有的章节全部总结了一遍,连什么所有操作符的precedence都背下来了。而我主要找工
作的几个公司都不太注重考察C++语言细节,只涉及到了virtual function
polymorphism等比较重要的概念。这里要提一点,我之所以那么花功夫啃C++细节,因
为我以前听说找工作需要做不少关于C++语言的测试题,尽管我的面试中并没有考到这
些细节,但是啃了下来还是觉得挺有收获的。

找大公司的software engineer工作,算法肯定是大头了。我自己过去比较喜欢算法,
暑假努力把CLRS啃了一遍,有点走马观花,倒回来再看第二遍的时候就觉得很有收获了
。这个是一定要下工夫啃的,这个是内功,做题目和练coding是外功,内外兼修才能有
真正的提高,呵呵。把各种数据结构和算法思想掌握熟了,思考题目的时候你才能
brain storm,才能有比较好的解题灵感和直觉。

说说关于google codejam:
不过我暑假看算法书的时候,一点coding都没练,我想着还早,等先看完,下学期再慢
慢来练coding。当时我的计划是秋天试试找工作碰碰运气,找个summer intern什么的
,没有奢望能够直接就找到full time的工作。8月底的时候逛某个bbs,看到一个公告
说9月有一个google codejam的程序比赛,我心想我背景那么差,如果能参加个比赛什
么的,或许能往简历上添一笔,看了一些往年的题目都觉得比较难做起来也是很有趣的
。你要说我真有什么优点的话,这个就算是了,很喜欢problem solving,很enjoy思考
的过程。练了两个多星期去参加codejam当然也没能走多远了,在第二轮中就挂了。但
是这个过程我现在回忆起来,还是受益匪浅的,因为一来把僵化的脑子“激活”了一下
,也扩宽了一点解题的思路,二来写的code都远比面试题复杂很多,虽然那是coding还
很粗糙生硬,但是逼着自己练习了一把,对后面的coding练习也是很有帮助的,第三就
是后来能网投拿到google的面试,除开google扩招的因素,我觉得这个codejam经历还
是起了很大的作用。codejam每年9月都有,立志今年秋天找工作也想去google的朋友,
我强烈推荐你们参加今年9月的比赛。

9月和10月,我也花了不少精力补自己欠缺的一些东西,比如操作系统什么的。10月学
校有careerfair,要来的公司不多,不过有微软。这里想说一下,微软的校园面试是非
常好的机会,题目不难,拿到onsite的几率比较大,认真准备onsite拿到offer的几率
也不小。很巧的是,MS这次来学校的代表里面有一个是很nice的中国人也是本校校友,
是几个朋友的朋友,当时知道这个消息很激动,认真准备了一下简历,careerfair上跟
他聊了聊,把简历递给了他,虽然中间有些曲折(见下一段),不过最后顺利拿到MS校园
面试机会,也还是很感谢那位朋友。(画外音,这是我第一次体会到,朋友熟人的帮忙
有多重要)。

这里有个小故事,10月投了MS的校园面试,mitbbs上有个网友帮递了amazon的简历,过
生日前一天网投了google,但是,很不幸的是,amazon的简历石沉大海,google等了一
周也毫无音讯,MS on campus interview application的状态突然变成了NOT Invited!
毫无疑问,那是我最黑暗最痛苦的日子!那时候是彻底的绝望了,觉得找到工作跟mm
团聚的日子遥遥无期,很痛苦很无可奈何,觉得自己背景差,活了二十多年什么都不会
没有一技之长...但我要说的是,咬牙,咬牙撑下去,命运总能触底反弹。当然努力攒
rp也很重要,做一个nice的人,做一个懂得感恩懂得回报的人,做一个努力帮助别人的
人,上天是会眷顾的。

未完待续,接下来开始具体的讲讲准备technical面试的经历

------------------------------------------

3.

上次写累了,最近一直太忙,今天也是抽空写写就当调剂一下写project报告的烦闷。

没看过前两篇的同学可以参考:
http://www.mitbbs.com/article_t0/JobHunting/31530927.html
http://www.mitbbs.com/article_t0/JobHunting/31531005.html

这次想具体写点准备算法题目和练coding这两个方面的。

第一个阶段:编程语言基础。C++的话把Primer啃个几遍,要肯花时间和精力,这里就不多说了。可能有人觉得,我天天写C++写几年了,还用看 primer吗。我觉得这个就仁者见仁了,看你对语言到底有多熟了,看你到底有多少信心了。至少我觉得看primer之前我也会写code,但是看了几遍后,写code信心增加了很多,不用有诸如用法语法等方面的担忧。

第二个阶段:数据结构和算法基础。CLRS看几遍,找SWE/SDE这类工作的人把算法学好应该是默认要求了吧,这个就像是你招一个学物理的人要求他量子力学学扎实一样...

第三个阶段:编程的基础练习。这个其实应该是配合第二个阶段的,一边看算法,一边练习把所有的数据结构写一遍,把所有的不是特别复杂的算法写一遍,不要看书上的伪码,自己在白板上画画草图然后看着写。要写完整的,可以运行的code,写完后想想如何测试,一般刚开始练的时候多半是bug频出的,尽量多找找 bug,多反思一下吸取教训。btw,有的公司,比如微软,dev懂得一些测试的知识(黑盒白盒,stress,load, equivanlenc partition, spec-driven testing等等等)肯定是有加分的,了解一些常见的错误/bug也利于你避免犯这些错误。

中间插入说一段关于练coding我个人的看法:写完后多反思多修改。我觉得这个是提高的关键。多想想有没有没考虑完善的情况,有没有bug,有没有很冗余的地方,有没有能节省一些空间时间的地方,有没有可以优化code看上去更简洁干净,比如若干个if else,能不能想办法找个等效的更简洁的branch的写法,比如某一段code重复出现那么可以移出去作为一个函数来调用,再细下去可以到某一两句指令的优化,比如++ -- 跟while放在一起怎么用看着会更简洁。这样慢慢的养好了良好的风格,面试的时候就能直接写出漂亮的code来。今年的形势还不错,一些大公司算法题的难度感觉逐渐的降低了,那么简单的题目你如何取胜?就靠熟练简洁漂亮bug free的coding。

第四个阶段:开始做面试题。你可以随机的大量的做,也可以按topic来做,这个随便你。我想重复说一点我以前说过的话,就是多思考。一个题目你做出来了,不代表你做对了;你做对了,不代表你做的最优;你做的最优了,不代表你coding完美;你coding完美了,不代表你速度足够快;你做的又快又好了,你觉得行了吧?NO,还应该继续想想,这个题目的思路是怎么想到的,精华思想是什么,利用了什么特殊的题目条件/性质/数据结构/tricky的算法等等,你是如何用problem solving skills来找到思路的,你如何present你的思路。然后就是分析性能,看看能不能有其他的做法,能不能搞点时间空间的tradeoff,如果你是面试官你会怎么变化一下题目,如何加一些条件,或者让你想想还有没有别的解法。大家千万别觉得,靠,不就一个破题目嘛,变着花样来考,不就是“茴”的四种写法,有啥意思。错了,这是锻炼自己思维的灵活/广度和发散的能力,功利一点说对面试很有好处,高调一点说对你一生都有好处。其实人脑子就是个机器,多锻炼跑起来才smooth,举个例子我最近一两个多月没怎么做新题了,感觉脑子又开始钝了...

做题的过程中多总结,我了解到的版上一些下了苦功夫准备认真总结充分的同学们最后都拿到了理想的offer。遇上不熟悉的topic,可以专门花些时间来学习一下,因为有的课外的东西或许面试会涉及到,有的时候你能说出一些课外的算法/数据结构/技术什么的,往往还是会给面试官留下好印象的。

总结有几个层次,我觉得,最底层是对单个的题目做总结,往上一层是对一类的topic/一类解题的思想/技巧/strategy做总结,再往上走就是对 problem solving skill的总结和提高。不过最后的一层,往往更多的是自己的体会/心得/感觉,而不是很容易能写在纸上的一条一条的东西。

另外就是我比较反对就题论题的背solution。我觉得背solution不如去理解它,理解它不如去想它是怎么来的,继续去挖掘里面的解题的思路策略的经验。当你积累了丰富的思路和策略的经验的时候,而不是背住了一大堆具体的solution,这样你在解决新的问题的时候,往往能有很好的直觉,或者是能够通过brain storm找到解决问题的方法。

当你写code已经比较熟练后可以拿面试题目来对着空气模拟面试,买个白板或者去学校的空教室,我个人很喜欢白板,最主要的原因是觉得白板非常适合画草图来演示思路,然后可以参考着草图写code,很方便,唯一不喜欢白板的地方就是不能保存写过的东西以及不方便写复杂的东西,呵呵。多练练解说做题思路和一边写code一边解说,加上熟悉和适应白板coding的感觉,对面试都是很有好处的。

照顾一下新人,回答一个问题:哪里找面试题?第一就是careercup(电子书和/或网站上的题目),第二就是mitbbs jobhunting版(精华区+关注并参与版面每日讨论)。另外有些网站也有面试题(不过我觉得careercup + mitbbs够用了):
http://www.thecareerplus.com/
http://www.spellscroll.com/
http://everything2.com/title/hard+interview+questions
http://interviewcyclopedia.blogspot.com/
http://dev.fyicenter.com/Interview-Questions/
虽然版上经常有重复的题目和讨论,参与解答讨论题目的人有老手高手也有新人菜鸟,但是我还是想多鼓励大家积极参与讨论。其实版上潜水的人相当多,我发过些资料联系我的都是几百个ID,但是日常在版上讨论的就那么几个ID。参加讨论,如果你的想法解法很好,起到了帮助别人的作用,如果你的想法有问题,大家给你指出也起到了纠正和提高的作用。另外一方面,你如果很活跃的话,或许能有版上前辈推荐你去面试的机会。我想我工作几年后也会抽空来看看,遇到水平不错的活跃ID也会推荐,这样自己也有机会拿referral bonus,双赢的事情。

想不到再写些什么了,最后稍微谈谈behavior/态度的问题吧。behavior问题list很容易找到,很多也是经典问题,software公司一般也不会问太刁钻的,一般就是些常见的一两个问题。专门花个半天一天时间根据自己情况好好思考一下,这个用心去准备没有人准不好的。其实我倒是觉得,怎么回答其实也就是口头上的东西,面试中behavior真正体现在你的举手投足之间,你的表情,语气,措辞,跟面试官的交流沟通。最简单的一招就是多笑,当然我说的是多微笑,不是傻笑!微笑给人亲和的感觉。有的人长相比较凶巴巴更要注意。另外就是,越是看面试官脸色不太好的时候,越是要面带微笑。另外就是从内心里尊敬面试官,不管面试官是不是想恶意刁难你还是你觉得面试官水平不如你,要骂要发泄怨气憋着留在面完了。说穿了,behavior的考察就是面试官面试完后对你给个评价:do I want to work with this person?

最后总结一句话,努力认真去准备,一定能有回报,祝大家好运!

没有评论:

发表评论