转自计算机学院一个offer大神的面经:潜心修炼,厚积薄发


1.先看书,后实践

        首先感谢一年前的自己所下的正确的决定:阅读《算法导论》《UNIX环境高级编程》《UNIX网络编程(卷一)》,那时还没想的这么远,只是觉得算法很重要,而我的基础又太薄弱,亟需重整。在整个准备的过程中,基本就是读书与实践的结合。假期时曾有高中同学问我,你找工作怎么准备的呢?我答,在看书啊。于是同学吐槽:你们专业真好,好好看书就能找到工作。当然,其实只看书是不够的,作为工科,必须动手实践,更具体的说,是写代码。仅仅实践也不够,还要及时总结,对我来说就是写博客,地址附在全文最后。
    下面对这一阶段看过的书和阅读方法进行介绍。我在整个准备过程中将每天完成了什么任务进行了一个记录,因此大家不要太惊讶于我对某些时间细节的了解程度。


《算法导论》(CLRS)
    CLRS是从去年7月30日开始读,时快时慢地到11月30日才搞定。第一遍读的时候顺便把书上几乎所有的伪代码在Linux下用C语言实现了一遍(不含NP问题、快速傅立叶变换这种明显没必要掌握的算法,像Graham Scan这种需要具体输入而不便于测试的算法也没有实现),把各个算法原理进行了解,大部分的证明过程只求看懂不求能独立完成推导,习题基本跳过。这样做实属一举多得:既掌握了算法,也练习了C语言,还熟悉了Linux及vim的操作,并提升了不少代码除错的能力。至于习题,由于难度不小,不建议第一遍就做,比较耽误时间。大部分的课后算法设计题我都是后来单独做的,而且是做其他题的时候重新翻CLRS相应章节发现,居然是原题。
今年5月13日到5月29日期间又重读了一遍,重点是动态规划部分。此时对C语言运用能力又有了新的提升,重写并完善了一部分以前写的CLRS的代码,同时对部分习题做了些补充。
在此期间CLRS就成为了本参考手册,每当想不起来一些算法细节或者是正确性原因时,我总习惯于去翻阅它,常备三本:中文纸质版(第二版)、中文电子版(第二版)、英文电子版(第三版)。中间发生了个有趣的故事:我在读CLRS中文版某一章节时感觉似乎有个错误,翻阅英文版上是一样的,于是抱着试一试的心理给书上提供的反馈邮箱发了一封信,没想到四位联合作者之一真的回复了我邮件,并告诉我是我理解有误。这个经历对我某次面试有所加分,具体就不透露了。

《UNIX环境高级编程》(APUE)
        搞Linux的必读书籍,不过是之前看的,当时也算通读,并且和项目相关;找工作期间主要当工具书翻。结合从我院著名的Linux内核课程上学到的东西,把底层实现机制和上层API了然于胸,Linux编程还有啥好怕的?

《UNIX网络编程(卷一)》(UNPv1)
        既然有志于Linux下的网络编程,此书怎可不看?研一的时候有个课程叫做“Linux网络编程”,当时就在上课之余把书上的TCP、UDP模型写写练练。今年的3月6日至4月1日期间又完全重读和重写了一遍,不过之前毕竟有基础,这次就比较快,而且是有选择的写,比如什么SCTP、广播多播、IPv6这些就无视掉了。此书的重点是各种socket API、TCP状态转换、几种常用TCP/UDP的C/S架构。当然,像netstate用法、ping的编写、I/O复用(此书没有讲解kqueue和epoll,很遗憾)、通信异常、名字转换、守护进程、非阻塞I/O、C/S设计范式这些我也实践过,收获同样不少。

《C程序设计语言》(俗称K&R,书名英文首字母缩写TCPL)
        一本看完之后你就想把之前学校用的C语言教材扔掉的书,C语言书籍中经典中的经典,被尊为“C圣经”。虽然本科时在课堂上学过C语言,但学的之水,可以说仅仅是HelloWorld和了解各种关键字的程度。由于找工作的语言方向定为C/C++,而且主要是C,当然必须捧着经典好好重学一遍。说起来也挺有意思,当初大三的时候就是这本书激发了我的编程兴趣,那时借来同学的书如饥似渴地读了一遍,然后又买了一本中文版收藏,毕业时不知所踪,于是此时又买了一本英文版。其实技术类书籍我建议时间富裕的同学最好读英文版,一方面是中文版的翻译质量参差不齐,读起来有时甚至不如英文版;另一方面是搞IT,英语是一项必备技能,既然有这个练习机会,何乐而不为?当然一开始可能很痛苦,当你习惯了这些术语时也就没什么了。再不济,至少读中文版的时候备一份英文版,在看了半天中文版看不懂时进行查阅。
        这算是第二次通读了,从4月26日到5月4日,五一期间仍保持一天一章的速度。读的时候,会看到不少以前一知半解的东西,是个非常好的实践机会。不过有的课后习题编码量比较大,请自行斟酌。读完后,收获的不仅仅是C语言的运用能力,还是C语言的使用思想和全局观。另外有一个意外收获:这本书上讲了如何模拟malloc的实现。今年9月时,我在从川大坐地铁回来的路上又快速回顾了一遍。

《C语言参考手册》(简称CARM)
        K&R虽好,毕竟与目前的C语言标准相差太远,并且一些细节仍然没有提及。CARM是一个非常好的补充,能了解到较新的C99标准(最新的标准已经是C11了),和不少便捷用法(比如,运行时才确定大小的数组)并运用到实践中。不过有K&R建立起的C语言的完整知识体系结构在,这本书看的飞起,5月6日到5月10日就连看带练地搞定第一部分,第二部分常用C库函数进行简单了解(当然,常用的输入输出函数、内存管理函数、字符串函数还是要细看的),后面是同样作为一本方便的速查手册放在手边。

《Essential C++》
        短小精悍的C++指导书籍,我对于C++的准备基本只靠这本书来完成。当然,每次面试我都要强调:我主要使用的是C,C++用的并不多,因此也没遇到几个C++的问题,即使遇到了也能比较好的解决。
        不过这书看上去不厚,但读起来对于我来说实在吃力,毕竟之前只在课堂上学过,基本没什么实践经历。本以为两天能读完,结果从4月15日读到了4月21日,抛去当时腾讯实习生面试的1天准备和1天面试,也是预期的两倍。但是感觉很值,通过阅读和编码,C++能力精进了不少,对容器、泛型、面向对象有所掌握。不过后来对《Effective C++》的阅读就是事倍功半了,毕竟实践还是太少,那些建议也看不出什么门道。

《编程精粹:编写高质量C语言代码》(Writing Solid Code)
        这本书对我的影响意义也是非常大:它告诉了我实际的商用代码编写与我们平时写的小demo究竟有什么不同。这是一本告诉你如何提高编码质量、减少bug的书,非常棒的实践指导,其思想不仅仅适用于C语言,而且篇幅也不多,二百来页,值得一读。毕竟,高质量代码不仅是工作中必须的,而且能够体现在笔试面试过程中的纸上写代码环节。我利用5月29日到6月1日这段时间进行了精读和消化。

《程序设计实践》(The Practise of Programming)
        另外一本从实践角度出发的书,上面一些代码值得一练。6月3日到6月8日和《编程珠玑》穿插着读的。

《编程珠玑》与《编程珠玑(续)》
        《编程珠玑》有点容易误导人的地方是:前三章很难,导致不少人刚看了一点就望而却步,直接弃掉。其实耐着性子也能看完,这本书也是相当精炼,短短的篇幅涵盖了算法、数据结构、编码、测试、调优等等多方面的内容。我对这本书的使用是对于正文问题,先想自己的解法,然后与作者的进行比较;每章习题基本全做、能编码的全部编码;耐心地总结成系列博文以供查阅,虽然花了不少时间,算上续作一共20天左右,但也挺值得的。
    《编程珠玑(续)》呢,和原作主题重合度比较高,不如前者。具体就不细谈了

《编程之美》
        要进行充分准备,这本书是绕不过的。如果说CLRS这样的算法基础是内功,那么《编程之美》便是外功,没有一定的内功是驾驭不了它的。当然,此书难度不低。不过个人感觉此书缺点不少,比如代码一致性,而且有的问题解释的并不是很清楚。好在此书名气甚大,网络上相关讨论丰富,想弄明白并不是难事。
        书中问题按照难度分为三个星级,序中提到:一星,不用查资料,20分钟内完成;二星,可以在40分钟内完成;三星,需要查阅一些资料,在60分钟内完成。按照这个标准练习便是,一开始我也被虐的很惨,到了后面,渐渐地摸到门道,学会了如何形成解题思路,渐渐开始能在给定时间内形成解答了。这是你看完题直接看答案所不能收获的。更近一步地,是在纸上形成代码,并在电脑上调通,非常好的练习。(不过不是每一道题都适合编码)
        事后统计一下,这本书大概也花了20天的时间,同时对一些问题进行了完善的总结。

《剑指Offer》
        另一本笔试面试习题集,整体难度低于《编程之美》,但是这本书有个优点:它是由职场老油条所写,作者从Autodesk跳槽到MS,又从MS跳槽到Cisco,其代码中的变量、函数命名非常规范,并写了异常处理,还提供了大量相应的测试用例,读后既能练习算法,又能提高编码和调试能力,一举两得。
        不过有了《算法导论》《编程珠玑》《编程之美》的积累,这本书上不少重复题目,另一些题目思路几乎是信手拈来,只花了4天就读完了,其中大半还是在放假回家的火车上读的,现在想想也觉得不可思议。这本书我进行的实际编码就比较少了,只对一些容易出错、复杂的问题做了实现。

《程序员面试宝典》
    当题库看看还行,解答质量堪忧,还是自己探寻答案吧。

《编程原本》(Elements of Programming)
        当消遣读的,没有太投入,证明简单看了看,习题也没做,写了篇书评,各位自行斟酌
《算法设计手册》(The Algorithm Design Manual,简称ADM)
        其实各位可能会奇怪,CLRS都看了,还看这个干什么?当然,论数学严谨程度,CLRS比ADM强多了,但是ADM的最大优点就是把CLRS没有细讲的回溯法讲得十分清楚,而且后面章节会对一些常见问题在不同条件下的针对性解法进行分析。还有,ADM的课后习题部分Interview Problems很有含金量。换个角度学学算法没什么不好,这是又一本直接读英文原版的书。

《CareerCup》150题
        看着本书的时候,发现重复度很高,算是一个对之前算法学习的检验吧。


        读完这些书并实践和总结以后,我的算法、Linux网络编程、C语言细节与运用能力与半年前相比已经有了一个飞跃,大部分算法笔试面试题很容易形成思路,并且能在纸上保持良好的编程习惯和防御性编程的运用,通过笔试也不是什么难事了。

2. 边实践,边读书
        只读上面提到的书籍确实能过笔试,与本科生不同,作为一个研究生,面试官还是很看重项目经历的。更准确地说,是和应聘职位相关的项目经历。从这里可以考察你对技术的钻研能力和解决实际问题的能力。之前也说过教研室的大部分项目与我的应聘方向——互联网——契合度不高,因此必须给自己开小灶。
        好在网络上各种开源项目不少,参加也不是难事,只怕挑花了眼。根据应聘方向,dariusdong大神建议我去开发一个基于Nginx的服务器,原因在于,Nginx性能优秀、功能较多、较为轻量级故源码不是特别多、目前对它的源码分析的书籍也比较全面,并且使用C实现的,与我的擅长语言契合度很高。当然,我这里就不算是参加开源项目了,而是基于开源软件做一个自己的应用。当时就选择了一个切入点,搞了一段时间,不仅仅把功能实现了,还根据一些书籍以及网络上的指导读了不少源码,从这个开源软件的处理框架、实现机制中学了不少优秀的设计思想,还练习了Linux下C开发,进一步地熟悉了Linux的机制和网络编程的细节,这个经历为我的面试环节加分不少。当然我不是让大家都去搞Nginx,而是根据应聘职位、个人喜好、擅长语言,有针对性地做一些应用级别的东西,参与开源项目或者基于开源项目搞开发均可,不要把自己的编程经历仅仅局限在写几个小规模数百行的测试程序上面。
        除了这个开源项目,之前在实验室做了个和网络相关的项目,又恰好是师兄当年的毕设,于是我便留了一份师兄的毕设草稿,并且花了一些时间把我负责的部分仔细回顾了一遍。面试时问项目的问题时,必须对自己所做了如指掌,包括实现、优化等等,而做优化的过程更重要。

你可能感兴趣的:(转自计算机学院一个offer大神的面经:潜心修炼,厚积薄发)