猛批烂书 程序员面试宝典 下
在上篇中,我有提到过,我自己在面试和被面试上都有一定经验,既然把这本宝典批的一无是处(它确实一无是处),不破不立,我也谈谈我认为程序员工作的一些注意事项,希望能对找工作的同学有所帮助吧!
你应该做程序员这份工作吗?
说实话,IT这棵平衡二叉树上,有很多不应该做程序员的人栖息在上面——不过好消息是,其他行业也一样,而且比例差不多。
当你大学快要从计算机学院或者其他的学院毕业开始找工作的时候,请先考虑一下:你应该做什么工作?这个问题需要你和家长、老师、师兄师姐、业界同行多多交流,和你自己多多思考。但是我想我可以在这个问题上帮助一下你:是否应该做程序员?(在另外一个问题上,我想我可以替你回答:是否应该买程序员面试宝典这本书?当然不!)
首先,对于爱好编程的人——那没什么好犹豫的,来吧,根节点就在你面前,快顺着根节点爬上IT这棵二叉树吧!爱好不是你说爱好就爱好的,对于爱好的鉴别,我觉得忙总给出的办法很好:看看你是否能拿着平均工资或者平均工资以下的水平从事一件事十年。对于在校大学生,可能对平均工资没有太多概念,那么换个说法:如果你纯粹出于自由意愿,在编程和玩你最喜欢的游戏之间,选择了编程,那么十有八九,你是爱好编程的。对于这样的情况,即使你不是计算机专业毕业的(甚至你是学文科的),我也建议你从事程序员这份工作,因为你拥有最大的优势:爱好。有了这个,一切艰辛对你来说都不在话下,只管爬上这棵二叉树做一头程序猿,总有一天所有的叶子节点都会属于你的!
话说,爱好计算机确实是一个比较有优势的东西,你既满足了自己的兴趣,又能养家糊口。要知道,这世界上很多爱好是根本不能挣到钱的。如果你是计算机专业的学生,但是你又爱好其他的行业,那么我也鼓励你从事自己的爱好(其实你也经常这样鼓励自己吧?),不要犹豫,至少你有爱好。大部分的同学,可能并没有明确的爱好,所以才会有那么多人在找工作上如此纠结吧。
如果你没有明确的爱好,家族也没有给你提供很好的替代,那么,作为一个计算机专业的学生,从事计算机相关行业是比较好的,毕竟这是你的专业。但是计算机相关专业,不仅仅是程序员,还有售前支持、售后支持、投标、工程、销售……选择是很广的,比如说你比较擅长和人打交道,在回家的火车上经常很快就能和邻座的旅客谈得来,那么销售应该是很好的选择。一个比较好的办法是直接去IT公司的招聘网站,找他们的职位要求,看看哪些是和你的特长符合的。如果最后什么也没有找到,那么至少程序员还是一个可以接受的选择,你并不是无奈的选择了这份职业,它是你的专业,也可以让你养家糊口。
不得不提的一句是,如果你不是这个专业,不爱好编程,那么千万不要妄想或者听信一些培训机构的忽悠,为了挣钱而进入这个行业。千万不要进入,不仅挣不到钱,还会很痛苦。网上抱怨程序员生活凄惨的帖子,一半以上都是这样的人发的。
总结一下,如果你爱好,那么千万不要犹豫;如果没有其他的有力条件,那么选择你的专业好了,这是一个稳妥的选择。刚刚毕业的学生,很少有能一下就选对自己的工作的,在自己的专业工作,至少给自己留出了足够的缓冲。除此以外的情况,恐怕都不适合做程序员。
苦练内功
如果你把做程序员作为工作的话,那么,在找工作以前先要做好准备。
在程序员面试宝典里面,列出了很多面试题,似乎给你一个印象:我只要把面试可能遇到的题目做一遍,通过笔试面试就可以了?实不相瞒,这纯属痴心妄想。面试官看完笔试以后还要面试,面试的时候很可能会问你:解题的思路;有没有做过什么实习或者课程设计?做了什么?……做面试的人,往往都是工作至少两三年的老骨头,面对毕业生要看出他/她有多牛未必可以(有这么牛的),但是要看出来水平是不是很菜,真是轻而易举。
基本上,如果你大学课程学的中规中矩,专业课很认真的去学了,作业和课程设计也都是自己做的,能用至少一种编程语言写出堆排序(或者快速排序),那么找一份工作已经足够了,可以跳过此章节。否则的话,那就参考一下下面的意见,准备吃点苦头。
静下心来,好好准备。你可能需要至少一个月,每天十二个小时以上投入。
目标:基本掌握一种编程语言,理解递归算法,能够按照算法写出堆排序。
语言:就用你以前课程上学的那种语言(不外乎C/C++/Java),如果没学过,选C。
教材:语言方面,尽量用你们上课用的教材,如果很多人都对原来的教材不满意,那么C++可以用C++Primer;C可以用谭浩强的C教材;Java不了解,有人推荐Think in Java,但是我觉得这本书太大块头了,实在没得选,就找美国教材的中译本,不要超过500页为宜。
算法和数据结构方面,就用严蔚敏的数据结构,C语言版即可,对于学C++和学Java的人,看C程序应该没问题。不要用外国教材,严蔚敏老师的教材是最合适的。
语言学习:先学习语言,从第一章开始基本上一页不拉的看,书上的例题和练习题要一定一道不少的编程写出来,看书一个小时,对应编程的时间应该不少于三个小时。如果你选的是C语言教材,那么就一页不也漏掉的看完,因为C语言本身东西不多,教材也不会太厚,如果这样你还要跳过一些东西,那么不客气的说一句,快毕业了还不能写出像样的程序原因也很清楚了。对于C++或者Java教材,一方面语言本身的东西很多,另外这样的书,往往会介绍一些应用相关的东西,所以可以适当的忽略一些章节,一般都是后面的。不可以忽略的是:与语言本身相关的(介绍顺序、选择、循环结构的,介绍类、运算符等关键字相关的,介绍文件操作的,介绍流的)、介绍多态的、介绍继承的、介绍封装的;可以忽略的是:介绍应用的,比如C++图像编程,MFC库(现在了应该没了),或者java一些架构的(这个深入以后应该了解的)。遇到不懂的问题,好好思考,不要走神,自己想不出来,就调试一下,单步跟踪,还不行,就在网上搜索一下,注意,如果搜着问题就跑到了论坛上灌水,那么灌水时间是算在十二个小时以外的。
好像很笨的办法,不过也就是这样,自古华山一条路。等你把这本书基本上每一页都看完,每一题都做完,一个月应该过去二十天了,你也应该能写一点不涉及算法的简单程序了(至少可以写求阶乘的程序了)。不过,每一页基本看完,是个可以完成的任务,但是每一题都作为,没有了基本,就比较难了,往往会遇到有些题目你苦思冥想了五分钟还是找不出答案,于是跳过去……然后遇到更多更难的题目。这怎么办?我不是你的老师不能去教你,即使你的老师也不会教你一道题目怎么做,但是我有一个很有效的办法:
做不出来不吃饭,继续想,去网上搜(但是不要求助),至少饿一顿,饿到觉得眼花为止(这说明你已经尽力了),然后去网上求助(比如CSDN),去做下一道。就是要给自己施加一点以前没有的压力,不然怎么能做出以前做不出的事情?
数据结构的学习:在完成语言的学习以后,就可以开始学习数据结构了。严蔚敏老师的教材讲的是比较清楚的,内容对于一个学期来说很合适,但是对于剩下的十天时间,是不够的,所以后面的红黑树、平衡二叉树,或者其他名字更古怪的数据结构(迪杰克拉斯算法……贪婪算法……)就别打算在这十天里看了。这些内容,是你必须看和做的:链表、各种链表、数组、查找、排序、各种排序、二叉树、二叉树的各种遍历方法,这些内容可能在书里占了一半左右,这次是一页不拉的要看完,编程也要一道不拉的写完。数据结构看书如果一个小时,编程可能也是一个小时左右,因为数据结构更多的是要你思考和理解:为什么是这样?这样有什么好处?有什么坏处?怎么在程序中实现这个数据结构?在你看书的时候,一定要带着这四个问题去拷问每一个数据结构。
学习数据结构的时候,遇到不懂的问题,一定要多思考,不要在网上搜索或者求助。我个人感觉,语言上的东西,知其然就可以了,就会用,是比较简单的,当然怎么应用就是应用之妙存乎一心,需要知其所以然,不过这也不会在你应聘的时候考察;然而数据结构往往是参杂了算法的,必须理解,必须知其然更要知其所以然,不然就是白学,所以在不懂的问题面前,一定要认真思索多动脑筋,写成程序,调试、看变量、看程序流程,想为什么。一遍不行两遍,两遍不行死编,挨个左移一位就行了。
需要着重强调的,是递归。在计算机的二进制世界,法师和麻瓜的区别就是递归,掌握了所有的编程语言但是不懂递归,只不过是一个买到了所有的魔法原料但是不知道怎么配的大款麻瓜。所以在学习数据结构的时候,一定要理解汉诺塔、堆排序、二叉树的前中后序遍历等典型递归算法,最好能做到把递归算法改成非递归——当你做到这一步,刚刚进入魔法学校名人堂的丹尼斯校长(Dennis Ritchie)会悄悄的为你别上一枚麻瓜们永远看不到的光荣徽章。
然而对递归的理解,不是那么容易,以我个人看法是只能靠你自己去领悟,认真的多看几遍严蔚敏老师的教材里相关的内容,好好思考和领悟。也许可以分成这样三个步骤:第一步,是知道典型的递归算法是怎么个流程,而且能自己比葫芦画瓢的写出来;第二部,要理解递归算法的工作机制,知道递归结束条件是什么、能根据递归初始条件算出会递归多少次、能给出任意一次递归的初始条件和流程;最后,能自己用递归的思想解决问题,并且转化为非递归算法。
最后要说的是,如果你在学习结束了还不能理解递归,不要着急。递归本身不是一个人类的概念,而是计算机的概念,所以我们作为人类中的一员,要理解递归的思想绝对不是一件容易的事情,要用递归的思想解决问题,更是困难的。现在不理解没关系,记住它,在以后的工作中,或者以后有时间了,把严蔚敏老师的书找出来,翻出相关的章节继续。而且不理解递归也不会对你找工作产生太大影响,说实话即使工作以后,用到递归的机会也不多——但是每一次用到递归的机会,都是你让你的头知道,你与众不同应该涨工资的机会。
考核:经过一个月以后,或者一个半月两个月,都有可能,你对编程有概念了,可以写稍微复杂的程序,能够在完全独立的情况下编程实现链表排序和最简单的查找、最简单的排序。这真的是最低要求,如果达不到,请重来一个月,并检讨上个月是不是每天十二个小时以上。最高要求是:1、你能把任意一个递归算法改成非递归;2、对于C++/Java的要理解多态。
寻找目标
对于刚刚毕业的同学来说,去一家有规模有口碑的大单位是最好的选择,在这里锻炼两三年以后,就有了一定的积累,无论是留在公司继续发展/跳槽到一个创业公司闯荡一把/甚至自己出来单干,都是正当时。但是进入这样的公司,相对来说要求也是比较高,而且可能和很多同学的自身优势是有点脱节,因为都是在学校里面学习的,那时候怎么能知道公司什么要求?这样的公司往往要求比较高,要打进去的话不能名校毕业最好也要211985,最好专业课成绩拿得出去,有过硬的项目经历或者实习经历最好,这样你的简历就可以通过筛选;在编程语言上就不是能用就行,而是需要有比较高的语言掌控能力,另外就是算法和数据结构功底扎实,能根据比较复杂的算法写出时间空间效率比较高的程序,这样才能通过笔试面试。这样的公司,就直接去它的官方网站上找招聘,凡是和自己能力搭边的职位要求,就投一个简历过去,别管是不是校园招聘。
不过,即使你自认能力远远达不到,也要把简历投给这些公司,如果能参加笔试面试,通过了那是中奖,没通过,也见识一下世面,好知道自己应该怎么努力。
次一等的选择,是成立有那么一段时间,主营业务是软件的其他公司,可能没什么名气,不开招聘会你都不知道,但是这样的公司能成立几年,也必然有一定积累比较规范,进去了也能学到不少东西。这样的公司可能就是要在招聘会或者一些同学朋友之间知道了,毕竟名气不大,进入以后职业发展的机会可能会少一些,毕竟公司的规模就是这样的,但是相对来说公司里面牛人不会那么多,如果肯钻研,冒尖的机会相对更大。
再次一等选择,是刚刚成立的软件公司,多少这里是做你的专业,即便是刚刚成立,也是有些牛人的,不然怎么成立公司?就是刚刚成立,可能没有什么积累,但是他们往往很缺人,要求相对低一些,而且在这样的公司机会也多,比较锻炼人。另外,就是一些主营业务不是软件,但是有IT部门,自己维护系统的,这样的也可以考虑。
如果实在没有办法了,就去软件外包公司吧。外包公司,真的是没有选择的时候才可以去,他们的要求是最低的待遇也是最低的给你的前景同样是最低的。只要你能“可以写稍微复杂的程序,能够在完全独立的情况下编程实现链表排序和最简单的查找、最简单的排序。”,各大外包公司随你挑。一方面在外包公司做的东西不固定,没有发展;另外一方面,外包就是尽力压低成本,不仅压低现在的待遇,也压低你未来的发展。所以,在外包公司如果不能向上发展进入管理层开始带一个小组(其实已经脱离技术路线了),那么在有了一定工作经验以后,有其他选择了就能跳则跳——注意,不要又跳到一个外包公司。
需要强调的一点是,不要仅仅看着学校发布的招聘信息和各大招聘会的信息,这样守株待兔效率太低了。对于你向往的公司,打上门去!到它的官方网站上找招聘信息,别管是社招还是校园招聘,只要能和你的能力搭上边,就投过去。很多找工作的同学,似乎都忽略了这一点,要知道,用人单位只管你能不能达到要求,才不关心你是不是学生呢,只要不是童工就行。
百尺竿头,更近一步
当你根据自己的实力,确定了目标以后,就要在你已有的基础上,更加有针对性的做一些提高了。
一般来说,面试的时候,公司要考察你的技术能力,一般是这样的顺序:编程的基本能力 - 简单的算法和数据结构 - 对编程语言比较全面的掌握,包括一些常用的细节 - 比较复杂的数据结构和写出尽量高效算法的能力 - 对编程语言的机制是否了解,可能涉及到一些编译原理 - 变态的算法和数据结构。对应届生,一般没有考察设计能力的,而且这种能力,绝对不是三个月半年能提高的,除非大量实际编码经验,所以在这里我就不提设计方面了(这方面我也没有做老师的资格)。
对于编程的基本能力,就是循环、选择这样的结构是否会用,简单的算法和数据结构呢,也就是二分法能不能写出来之类,如果你按照前面的步骤准备了一个月,即使之前纯属白脖,这个水平是一定能达到的。但是不要满足于此,这只是最低水平,只能去各大外包公司和非常缺人的小公司拿一份最低的薪水天天做近似重复性的工作。一定要百尺竿头,更进一步。
“ 对编程语言比较全面的掌握,包括一些常用的细节”,是说对你用的编程语言,不仅仅能写出符合逻辑的程序,而且知道怎么写是好的,怎么写是不好的,应该怎么写,不应该怎么写,是知其然的标准。比如用C++语言知道i++和++i的区别,写了一个类里面有自己申请的内存,知道要写拷贝构造函数、赋值函数和析构函数,使用STL的时候知道vector的内存是连续的所以中间插入一个数据可能比较慢等等。达到这样的要求,基本上写程序就不用人操心了,不会犯低级错误。找工作的时候可以去一个正规一点的公司,运气好,还能进入一家同学们耳熟能详的公司。要达到这样的水平,是属于肯下功夫就能做到的事情。
“对编程语言的机制是否了解,可能涉及到一些编译原理”,就是一个比较高的要求了,是知其所以然的标准。C/C++这样的,就需要你能看到代码以后,知道背后的机制,比如虚函数,是怎么实现的,一维数组二维数组一重指针二重指针之间怎么回事儿,用STL的时候不仅仅知道vector的内存是连续分配,而且知道在vector变大的时候是怎么扩充内存,甚至看到一些代码的时候知道对应的汇编应该是什么,比如if-else和switch-case,有没有可能不太一样?等等。对于Java这样的语言,可能不太关注底层,但是我了解也不多,就我看法,应该是对Java的常用架构有比较深入的认识,不仅仅知道怎么用,还应该知道怎么实现。这样的要求并不是孔乙己回字的四种写法,而是有实际意义的。当你做到知其所以然,就不会对编程中遇到的奇怪现象感到奇怪了,往往能迅速的找到错误的原因;写程序的时候,也能写出高效的程序;对于已有代码,可以优化它的时间和空间效率。要达到这样的水平,没有点天分或者爱好,是不容易的。
“ 对编程语言的机制是否了解,可能涉及到一些编译原理”,对应届生来说就是妖怪级的要求了。这个只能可遇不可求,我感觉只有真心喜欢的人才会下功夫这样做。一般来说,也没哪个公司会面试应届生的时候这样考察,更不是毕业前突击三个月半年就能做到的,就我体会而言,只有真心喜欢计算机这个行业的人,工作了一段时间(或者读研而且专业相关)才会做到这些。所以,这个也不是咱们百尺竿头更进一步的目标。
对于算法和数据结构的考察,比重应该和语言差不多或者更多,但是因为算法和数据结构不是那么容易就提高上来的,是必须大量做题(对,做题)和编程,对悟性和理解能力有一定要求,因为本文的主要目的是介绍怎么比较快的提高应对面试水平找到工作,所以就不做详细介绍了。一般来说,严蔚敏的教材,拿到期末考试80分,能够做到按照算法写出程序,就不错了,如果能理解递归并且把任意一个递归改成非递归的形式,那就相当好了,更猛烈一点,参加过ACM大赛甚至斩将夺旗的,请受小可一拜。
前面说了那么长各种水平应该如何,还举例子,是为了让你对自己目前的水平和你在未来两三个月里可以达到的水平有一个客观的认识,这对你找工作是很有帮助的,所谓知己知彼么。下面,就介绍一下“更进一步”的具体方法。
首先是编程语言上,这个是比较容易提高,没什么诀窍,一本好书,多多练习而已。好书自然是越多越好,但是这里只要一本,也是考虑到要毕业的同学们时间上恐怕承担不起,一本好书花上两三个月时间,连练习带读书,无论中英文都是可以搞定的。练习没什么说的,好好把书里面的习题做完,例程也自己写一遍。好书呢,C语言就不用说了,K&R是永远的经典;C++比较多,我个人最推荐The C++ Programming Language,英文版(可以下载到电子版),这本书的英语写的非常舒服,倒是中文版翻译的反而有点晦涩,我就是用这本书学的C++,亲身体会很有收获;另外一个选择是C++Primary,这本书的优点是中文版翻译的还不错,就是太厚啦;如果还有时间和精力,可以看看
“Effective C++ / More Effective C++ / Effective STL”——这是我从别人的书单里抄来的,他还提到了Inside the C++ Object Model、Exceptional C++ / More Exceptional C++,这几个就算了,你要连这个也看完了,让面试官情何以堪呢? Java我不了解,就我自己学习的感觉,还是Thinking in Java最好,也是推荐英文本。
……恩,就这些了,关键是选对好书,然后认真练习,如果能再投入两三个月的功夫,完全可以让你的水平更进一步。基本上可以达到各大公司随便进的地步。另外,不要对英文书有畏惧感,坚持读下去,收获会很多的,中文版的书实在是翻译的太烂。我本人的英语水平一般,当时学TCPL的时候,平均一天七十页,包括读书和练习,我练习编程的时间是比较多的。
只有在你对自己的编程语言提高以后还有精力和时间,我才建议你在算法和数据结构上专门的投入时间。因为一方面,在一开始的训练里,你应该已经有了基本的算法和数据结构能力;另外一方面,这方面的提高是没有可能在短时间里提高上去的,只有长时间的学习这一个办法。在这方面的练习,基本上还是以严蔚敏的教材为准,可以把里面的各种算法和数据结构都好好研究一下,比较经典的如迪杰克拉斯、哈夫曼树、平衡二叉树,比较变态如字符串kmp查找等等,但是不要把精力放在记忆算法的步骤上,而是考虑怎么实现这些算法?怎么高效的实现这些算法?为什么这些算法这样设计?对于数据结构,主要是理解一个数据结构怎么用和怎么实现上。
算法和数据结构的关键,就是理解,而不是记忆,这也是难以在短时间提高的原因。比较起来,语言上的东西么,记忆的也不算多,倒是有很多要知道,而且也要理解,但是这个理解的深度就没有算法和数据结构深了。
准备简历
在完成了前期的准备以后,又找好了目标,就开始准备简历吧。
参加面试
[原文在百度空间已经关闭]
标签集合/Tag clouds
C++
Symbain
轻松汇编
算法
论文学习
资治通鉴
Delphi
编程之美
Poco
MFC
Linux
IFC
知乎
汇编
数据分析
交叉编译
poco
j2me
android
XML
Java
DTD
飞信
零宽断言
诺基亚
联系人
编程
真值表
池西木
正则表达式
多线程
命令行
优化
stream
configure
cmake
VIM
UiAutomator
TDD
Symbian
Sqlite
SourceInsight
Python
MPAndroidChart
Kotlin
Flutter
Dokka
Chatgpt