前言
我的故事,你的故事
这是一本我希望自己在大学就能看到的一本书。在我读大学的时候,跟很多同学一样也走过不少弯路:艰难地啃着计算机必修课,被里面的指针和对象搞的晕头转向,对i++和++i区别死活不理解,为操作系统的调度策略而抓狂,很难对专业书产生兴趣,只是想着去应付考试和学分。当我们毕业后,虽然有了计算机学位和实际工作经历,但其实还是不知道最想得到什么。我当时心中有个情节,就是希望能去最好的公司,比如Google,因为听说那里面都是最聪明的人,有着最好的待遇和福利,做着最有影响力的事情。当我鼓起勇气去尝试的时候,我失败了,并且要进入6个月的冷藏期(失去在一段时期内继续面试的机会)。而我发现当时的面试表现是那么的稚嫩和糟糕,我开始懊恼,开始反省,开始重新准备,这样才有了我下一个面试机会和其他的Offer。当然如果一切可以重新再来,我可以更有自信更好地发挥我的能力,也许当时的理想公司就会给我Offer。
有些朋友会认为只要能混过面试,拿到工作之后有的是时间可以继续学习。这话听起来有道理,但我在这里给出一个反例:我记得多年前第一份实习的任务是对某个大型应用程序进行性能测试。我不知道如何创建一个用户界面,然后随意定义文本字段、菜单和按钮。我不知道如何用线程来思考,我错误调用整个缓存和线程池。我也不知道如何去做代码维护,并且没有单元测试和编写基本的文档,最后我还是写了几千行的Java代码,这是个无法维护的巨大的类。而如果我在工作之前多一些积累和看一些代码,或许不会那么尴尬。
也有些同学说面试中只会考没有用的算法,这跟工作没有任何直接关系。我同意工作中大多数情况是不会用到复杂的算法的,但如果你没有过硬的基本功,在面对一些新情况的时候,你就很难举一反三,灵活运用了。我记得我在第一家公司第一个项目是在一个新城市中增加新的排序选项来选择上市的所有租房。这是一个紧急任务,上司希望我尽快熟悉代码库,我当时也顶着压力,做到了一周上线。不久后,我就在总裁面前演示:我看着他点击了某个区的房源,选择了新的排序选项,结果花了几分钟去加载页面。我之前也验证过应该没问题,平常只需要几秒钟的时间。我当时满头大汗,真是搞砸了。那天晚上,我思考了很久才想通。我选择的新代码做两个数据库调用需要遍历其中的每一个,它需要的n * log n比较的次数,而对于那个区域,其中大约有n =1000个房源,那么大约要2万次数据库调用才能完成一个页面加载。当然,知道了原因,优化起来就简单了,通过调用缓冲,把数据切成更小块,做数据量的控制,最后性能提高了100倍,所以说系统优化是离不开算法和扎实计算机基本功的。
其实每个工程师都讨厌Bug、代码不整洁、性能太差、用户界面不人性化等,这些都是一些技术细节,是可以慢慢体会和提高,总能找到答案去改进的。但在工作中,我应该学习和使用什么样的技术?为什么要自动化测试?如何搭建一个产品,看起来比较靠谱?我怎么去选择一份工作?如果我在一家大公司工作,如何跳槽到创业公司?我如何谈判取得更多的薪金或奖金?什么是股票激励?这些问题倒是更棘手,我也会在第1章给出一些介绍和辅助工具。
回看我走过的一路艰辛,我尝试反思学到了什么,我发现其中大部分经验都来自痛苦的反复试验的结果。当我意识到成千上万的面试者或者IT开发人员正在经历同样的试错,犯同样的错误,我觉得应该做一些更有意义的事情:这本书就是一个工具。诚然,有些教训只能从在自己的错误中学习,但我希望本书能够帮助你从别人的经验中获得通向成功的捷径。
现状
俗话说凡事要“顺势而为”,找工作亦是如此。现如今,借助手机网络带宽的快速提升以及移动互联网的概念,原先在PC平台才能开展的服务一下被冠上了“移动”二字。在手机上使用服务和计算机上使用服务,在本质上并没有太大区别,但关键在于手机更具有“私密性”和“便携性”,大大增加了客户粘性和使用时间,进而会对服务提供商产生更大的依赖性。
在中国,互联网公司中百度、腾讯、阿里巴巴“三架马车”分别把持搜索、社交游戏和电商平台三大主战场,互相竞争。而硅谷更是百花齐放:Apple、Google、Microsoft致力于打造自己的生态圈,完成硬件、软件、服务的闭环;而Facebook、Twitter、LinkedIn等为代表的社交平台也迅速通过巨大的用户群体完成“圈地运动”,将管辖区域内的用户导向各个实体商户;更有Uber、Airbnb等新兴公司,致力于通过移动互联网思维改变人们的实际生活。
相比于2000年左右的互联网泡沫,这次的计算机高潮来势更为凶猛:不单单提供资讯、门户、电邮等虚拟线上服务,而是直接破坏性地侵入传统行业,以更高的效率改变原有行业。这就是为什么许多新兴科技企业号称是技术公司,但实际上提供着传统行业的服务。当前的趋势也会逼迫着传统公司作出改变,引入更多计算机人才,利用云计算、机器学习等新手段与新兴公司竞争。最简单的例子如Wal-Mart Labs,它以一个科技智囊的角色隶属于Wal-Mart,通过计算机技术分析,优化Wal-Mart的营运效率。金融、银行、地产、石油、制造、电子硬件等各个行业也纷纷引入计算机技术,大大创造了从业人员的工作机会。
这样的趋势对你我有什么影响?人才需求的极速扩张意味着找工作难度降低,并且待遇也是水涨船高。举例来说,在美国,硕士毕业加入Apple、Google、Facebook等公司起薪至少10万美元,外加股票期权。更不要说加入最火的创业公司,三四年后一旦上市就可以提前退休,或者把工作作为兴趣。在国内,阿里巴巴上市也造就了成百上千个千万富翁,即使是上市前一两年刚加入的新人,也拿到了100万人民币左右的股权。
如果说这些职位难度太高,对于你遥不可及,或者需要很长的准备时间,那也许对于上面的文字你只会一笑而过。但是,如果告诉你通过正确的方式,做好面试准备,上面所说的职位触手可及,是不是听起来更有吸引力了呢?事实就是,由于软件工程师的职业特性、面试要求及局限性,以及市场需求等因素,程序员求职是一种比较具有应试性、相对容易找到门道的简单职业道路。不乏相关或不那么相关专业的毕业生通过半年到一年的努力拿到理想的IT行业的相关工作的事例,由此可见,挑战不在于“能”和“不能”,而是如何通过正确的方法、迅速地赶上潮流分一杯羹。
目的
本书的目的并不在于代替课本教材,系统性地讲授计算机技术,而是作为一本工具书,创建一个实际的、可操作的面试方法论教程,提供一条快速熟悉技术面试题目的捷径,并且针对不同类型的题目,归纳总结解题方法。
程序员面试是对于面试者计算机知识的全面检测,因此,关于计算机诸如网络、操作系统、编译器、算法和数据结构等各个领域的系统性学习不可或缺。但是考虑到面试的局限性,诸如时间限制,面试官对于面试者的熟悉程度等,在白板(或者白纸)上写程序解决一些算法问题成为面试官较为青睐的方法之一。由于该面试方法比较机械,相对容易准备,也最适合总结一些方法论,所以本书的目的就在于传授白板写代码的准备技巧,帮助大家通过面试。在本书中,我们将会遇到的题目、技术,都是来自于我们实际面试过的一些炙手可热的硅谷公司和我们自己作为面试官的一些心得和宝贵经验。正如参加GRE考试一样,关于考试技巧的书籍并不能让一个完全不懂英语的人通过考试,但是可以使得英语基础合格的人如虎添翼,大大增加通过考试的几率。这就是本书的全部意义所在。
特色
市面上关于程序员面试的参考书也不少,但是我们认为这些书的关键问题在于它们大多是教你“怎么做”,但很少涉及“为什么这么做”。于是,读者往往会觉得书中的解法十分精妙,但是在面试的时候完全想不起来用哪种方法解决问题。其根本原因在于,这些参考书代替你做了最关键的一步:判断用什么方法解决当前的问题。
本书遵从大多数面试参考书的构成方式,结合实例,按照常见的数据结构、算法以及计算机基础知识进行章节划分,但是,本书着眼于如何进行“模式识别”,通过分析为什么这个问题被划分到这个章节,来教大家如何判断实际面试问题的类型,并且顺水推舟地得出解决问题的方法。每一章的“知识要点”介绍章节涉及的相关知识点,回顾通常出现在教材中的重点内容;“模式识别”给出一些实例,帮助大家总结解决相关问题的常见方法,并且通过分析问题中的关键信息,教授大家如何从题目中得到关于题型分类以及解题方法的蜘丝马迹。
本书收集的题目部分来自互联网上分享的面试经验、在线编程网站leetcode,以及面试参考资料Cracking the Coding Interview和Element of Programming Interview。如果你认真准备过面试,可能会对题目有似曾相识的感觉。但本书的关键不是教会你做一道题目,而是教会分析题目、解决题目的方法,从而学会解一类题目。具体的题目不是关键,从题目到方法的思维过程,是本书努力想传达的重点;最后,“工具箱”部分给出该章涉及的C++/Java类,它们的常见函数及使用方法,还提供一些标准库函数,以及相关参考资料或扩展阅读。
如果你有志于投身到滚滚的IT互联网浪潮中,无论你是一个学生,还是初级程序员,不论你以后是定位于架构师还是项目经理,你都需要一块敲门砖,那么这本书就是为你量身定做的。作为有着在国内外创业公司和一线公司经历的过来人,我们希望本书能给你职业生涯上添砖加瓦,帮助大家到达理想的彼岸。
最后,我们特别感谢Ruthia百忙之中抽空帮助设计封面。正如封面中锤子所象征的那样,每个人都需要付出持之以恒的努力才能获得成绩,在此与读者共勉。
由于水平有限,编写过程中难免产生疏漏。如果在阅读本书的过程中你有任何建议和问题,请联系我们:UltimateGuideToCodingInterview@gmail.com。