##一个大一学生有关未来规划的疑问及答复 【来信】 周老师: 您好! 我是山东大学计算机科学与技术学院的大一新生,自从选择了这个专业以后,经常需要看别人的技术博客来学习知识,看到您的博客后十分敬佩,您这种工作勤奋又乐于帮助他人解决疑惑的精神实在是令人敬仰。 学生有个关于大学学习方向的问题,想了很久,但是还不是很清晰。一直想给您写信咨询,但又怕耽误您的工作,在这里先谢谢您能为我看这封信了。 首先介绍一下我的情况。 1)我大学四年的目标:不读研究生,直接去Microsoft、Google、BAT其中之一的一家公司做软件开发工程师。我通过搜索和浏览这几个公司的招聘信息发现,这几家公司该职位的共同需求是:有深厚的数据结构与算法知识基础、精通C++/Java语言、有项目经历、竞赛获奖的优先。 2)我现在的状态是:学业成绩位居上游,从去年开学到现在一直在从事ACM竞赛,目前已经刷完了《算法竞赛入门经典》上的200来道题目,对竞赛中的主流题目都有了一个大体的认识,但是越来越感到ACM竞赛的力不从心(高中从未搞过竞赛)。目前正在学习严蔚敏的《数据结构》。性格较内向。 我想请您帮我指点的问题是: 1.我是否应该退出ACM竞赛? 对于这个问题,我思考了很久,我的想法是这样的: a)我搞ACM的目的其一是为了拿奖牌,希望这样在求职的时候能为我的简历增添一点分量。 **那么请问如果我的简历上没有任何ACM获奖的经历,但是有奖学金和项目经历+山大985、211的牌子,以您的经验来说,大公司是否会给我一个笔试的机会?** b)随着刷的题目越来越多,逐渐感觉到要想ACM获大奖(金牌及以上)我必须几乎将全部的时间都用来刷题目,但是我的目标是成为一名优秀的软件开发工程师,这样的话,对ACM的过度投入势必会影响我的其余工程能力的提升,同时影响自己其他知识的学习。诸如:操作系统、数据库、计算机原理都是构建完整的计算机知识体系所必需的知识。 **请问根据您的经验来看,想成为优秀的软件开发工程师但是却将大量时间投入到编程竞赛中是否不正确?是否有点偏科?** c)参加ACM的另一个目的是是学好数据结构与算法,但是研究了一下笔试面试题目后发现竞赛中常用的数据结构在求职时很少用到,并且如果仅仅为了学好数据结构与算法根本没有必要刷ACM题目,个人感觉多读好书、多敲代码实践,刷LeetCode+看《编程之美》、《编程珠玑》等等牛的书就够了。 **以上是我关于ACM竞赛的看法,还请您提出建议与批评。** 2.为了得到目标公司的职位,数据结构与算法知识到底要学到什么程度? 我认为就是达到能熟练做出名企招聘题目的程度,暂时的规划如下 1)第一阶段:知识学习阶段(2015年3月——大二上学期结束) 读完《数据结构C语言版》、《Algorithm Design 》、《Algorithm》、《Introduction to Algorithms 》等等牛的书并总结写笔记(只看书学不会的,必须得自己大量地敲代码才能熟练掌握),做对应知识点的5道LeetCode题目来熟练巩固所学的知识。 2) 第二阶段:真题训练总结、找实习准备阶段(大三上学期中间——大三上学期寒假结束) 一方面不断复习第一阶段的笔记,真正熟练掌握;另一方面,做程序员笔试面试考的数据结构与算法的题目+阅读《编程之美》、《编程珠玑》、《程序员面试宝典》等等笔试面试指导类的书籍并总结查漏补缺。目标是大三下学期的时候参加名企的实习生招聘能拿到理想公司的实习offer,然后好好表现争取能够直接转正。 **请问根据您的经验来说我的任务安排的合理吗?恳请您提出意见与批评。** 3.我应该专攻Java还是C++? 从网上了解到的Java工程师的需求最大,但是有的统计数据也显示C++的工程师薪资最高,这不知道哪个更好?我的C++/java学的目前的只能算是入门,希望能提前想好专攻什么语言,在以后的学习过程中能有所侧重的去学习。 **我看的很多人写的面经,都提到好像C++/C是必考的知识是吗?那么就算专攻Java,《C++ Primer》、《Imperfect C++》、《C与指针》等等牛的C/C++方面的书也要看吗?恳请您提出意见与批评。** 4.我应该什么时候开始专门学习某一种编程语言? 现在正在学习数据结构,感觉数据结构与算法的实现与语言的特性关系不大,主要是思想正确都能实现,因此,我感觉学习数据结构和算法的过程中对语言的学习并没有太大的帮助,只是熟悉基本的语法而已,而想精通一种语言要大量阅读相关的书籍+大量敲代码实践。因此,我想在做项目的同时加深对某一种编程语言的学习。也就是说,先主攻数据结构与算法,然后同时专攻编程语言+项目开发。 **您感觉这样安排合理吗?我想以此为依据来调整学习的进度。恳请您提出建议与批评。** 5.怎样权衡学习基础学科知识与学习技术的关系? 我从网上查阅了这方面的观点。一部分人认为:项目开发用不到数据结构与算法等等学科基础知识,只需要熟悉类库并会调用就行了;另一部分人认为:数据结构与算法是“内功”,而流行的技术是“外功”,从长远的角度来说,只有内功扎实,才能在软件开发这条路上走得更远,如果内功不好,那么永远只是在堆砌API,不会成为优秀的工程师的。就是说,数据结构与算法等等学科基础知识决定一个开发人员走多远,会不会开发用的技术决定开发人员能不能开发。 **请问根据您的经验,您感觉怎样认识这个问题呢?怎样权衡学习基础学科知识与学习技术的关系呢?从找工作的角度来说,我应该怎样分配这两方面学习的时间呢?或者说这两个方面我应该分别达到什么样的要求呢?** 6.我应该在什么时候参与一个团队进行项目的开发? 大一上学期的时候我进入了一个做安卓开发的团队,但是那时候痴迷于ACM竞赛,于是就退出了。 **因为我想大四出去实习,希望能在我出去实习之前有一个能拿的出手的项目,您感觉我什么时候去搞项目的开发比较合适呢?得用多少时间才能把自己做项目这方面的能力提升上来,能做出自己拿手的项目?现在想的是大二上结束后就开始做。恳请您提出宝贵的意见与批评。** 7.从找到好工作的角度来说,我除了有硬功夫(真正掌握知识)外,有哪些很重要的软实力要培养呢? 我是个比较内向的人,不爱与人交流,本想着上了大学能够锻炼一下自己的各方面能力,比如说交际能力、合作能力、领导能力等等软实力,但是随着学习的深入,发现要想达到名企的招聘要求(有深厚的数据结构与算法知识基础、精通C++/Java语言、有项目经历、竞赛获奖),自己要学的知识非常多,自己还没读的好书籍非常多,感觉自己在培养专业硬能力这一方面都必须全力以赴,现在我每天除了睡觉吃饭外的其余时间就是在自习室里学习知识。 **我现在担心的就是如果我的专业技术能力达到了招聘的要求,但是会不会因为在面试中因为沟通能力、交际能力、应变能力不好而与理想的offer失之交臂呢?感觉时间真的是不够用的。您感觉那些面试能力在找工作前多准备多训练一下能行吗?怎么样权衡培养软实力与硬实力的关系呢?恳请您能给予指导。** 学生的计划性比较强,感觉明确目标以后,应该尽快的明确达到目标的阶段与方法,因此问题比较多。但我绝不是那种“想得太多,做的很少”的人,每个阶段的计划我都会细分到每一天去全力完成。 以上是我的疑惑与自己对疑惑的思考,深知自己的知识浅薄,眼光见识短浅,因此对一些问题的看法不免有些功利与“天真”,十分希望您能结合自己的经验与经历对我的疑惑与看法提出建议与批评。 学生深知自己对于如何进入IT龙头企业、如何在校期间培养自己的工程开发能力、如何成为一名综合素质优秀的IT精英知之甚少,在这里十分希望您能够结合您的经验与经历对学生还没想到的地方做一些补充与指点。 再次感谢您能抽时间看着封信件,祝您生活快乐,工作顺利,事业有成。   此致 敬礼                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      山东大学计算机专业学生                                                                                                                                                                XXX                                                                                                                                                                2015年3月27日   【答复】 你好! 首先要感谢你的来信,你是至今为止,我收到的读者来信中写得最详细的。 从你的字里行间中,我感觉到你是一个对未来有着明确规划、有着殷切期盼的人,而且,你的思维很清晰,行动的目的性也很强,相信你是一个很有前途的学生。 作为过来人,我深知在大学里面,像你这样的学生是很少的,因此,我才更加感觉到你这般勤于思考、不断进取的精神的难能可贵。由于你提的问题比较多,涉及到的面比较的广,我也只能从自身的经验出发给出回复,不一定都正确,请认真参考。 **1.是否应该退出ACM竞赛?** **a) 那么请问如果我的简历上没有任何ACM获奖的经历,但是有奖学金和项目经历+山大985、211的牌子,以您的经验来说,大公司是否会给我一个笔试的机会?** 周:大公司给笔试的标准是应聘者的简历与岗位要求的契合度高,因此,并不是说你有获奖经历、项目经历,抑或是名校出身就一定行的。举个例子,如果一个岗位要求你会数据库,而你的简历上面写的精通C++,并且有很多获奖的经历,那也可能会被淘汰掉。因此,你要根据心仪的岗位来安排自己的学习,不要盲目追求一些很光鲜的东西。 b) **请问根据您的经验来看,想成为优秀的软件开发工程师但是却将大量时间投入到编程竞赛中是否不正确?是否有点偏科?** 周:我认为,一个优秀的软件开发工程师需要具备以下素质:1)专业知识牢靠;2)学习能力强;3)动手能力强;4)善于沟通交流;5)乐于分享。也就是说,“优秀”是一个综合素质,编程能力强的人不见得就是一个优秀的软件开发工程师。因此,除了编程之外,你在学校里面还要注重其它方面的学习。 c) **以上是我关于ACM竞赛的看法,还请您提出建议与批评。** 周:我本人没有参加过ACM竞赛,但参加过其它的竞赛。总的说来,竞赛的目的与我们平时学习的目的是不一样的。一般说来,竞赛的持续时间不长,参与的目的是为了获奖,而平时的学习却是一个长期的过程。要想把专业基础打牢,靠参加竞赛是远远不够的,还是要注意平时的学习,要日积月累。要想学好数据结构与算法,最可行的办法就是多看好书、多编写代码、多总结、多分享。   **2.为了得到目标公司的职位,数据结构与算法知识到底要学到什么程度?** **请问根据您的经验来说我的任务安排的合理吗?恳请您提出意见与批评。** 周:我对在校学生的建议就是利用大一大二的时间把专业基础课学好,多看点书,并培养自己动手实践的习惯。等到了高年级(如大三)的时候,再考虑专攻某一方面或实习的事情。你这两个阶段的安排还是比较合理,但要制定好计划,并遵照执行。   **3.应该专攻Java还是C++?** **我看的很多人写的面经,都提到好像C++/C是必考的知识是吗?那么就算专攻Java,《C++ Primer》、《Imperfect C++》、《C与指针》等等牛的C/C++方面的书也要看吗?恳请您提出意见与批评。** 周:作为在校学生,其实你无法确定未来自己要从事哪方面的工作。即使你确定未来要做Java开发,那么C++还是要学的。在实际的软件研发工作中,有时候某个任务用这种语言编写较好,而另一个任务又要换一种语言来做。因此,在学校的时候,尽量做到多学几种语言(不限于Java和C++),但比较熟练的语言尽量不要超过两种。   **4.应该什么时候开始专门学习某一种编程语言?** **您感觉这样安排合理吗?我想以此为依据来调整学习的进度。恳请您提出建议与批评。** 周:数据结构确实与编程语言的关联性较小,但如果你用某种语言来实现数据结构,可以同时学到编程语言和数据结构。你想先主攻数据结构与算法,然后同时专攻编程语言+项目开发,这样是不合理的。在学习数据结构与算法的同时,你也要学习编程语言,用学到的编程语言来实现数据结构或算法。在你有一定的基础之后,再从事项目开发。另外,在学校,基本上没有专门学习某一种编程语言这种说法,因为你要学习不止一种编程语言。   **5.怎样权衡学习基础学科知识与学习技术的关系?** **请问根据您的经验,您感觉怎样认识这个问题呢?怎样权衡学习基础学科知识与学习技术的关系呢?从找工作的角度来说,我应该怎样分配这两方面学习的时间呢?或者说这两个方面我应该分别达到什么样的要求呢?** 周:我赞成数据结构与算法是“内功”,而流行的技术是“外功”这种说法。现在的IT技术日新月异,新技术层出不穷,而基本的原理是不会变的。如果你只是为了追逐流行的技术,那这样做是很累的。数据结构与算法永远不过时,计算机底层知识永远不过时,各种好的学习习惯永远不过时。大学四年是最好的打基础的时光,你一定要将专业基础学好,在重点打基础的时候,你也可以关注一下当今流行的技术,做到不落伍。在找工作的时候,也以考查应聘者的基础为主。建议你把80%的学习时间拿来打基础,20%的时间拿来学习技术。   **6.应该在什么时候参与一个团队进行项目的开发?** **因为我想大四出去实习,希望能在我出去实习之前有一个能拿的出手的项目,您感觉我什么时候去搞项目的开发比较合适呢?得用多少时间才能把自己做项目这方面的能力提升上来,能做出自己拿手的项目?现在想的是大二上结束后就开始做。恳请您提出宝贵的意见与批评。** 周:我建议大三的时候再参与一个团队进行项目的开发。因为前两年你的主要任务是把专业基础打好,尽量不要分心。提升做项目这方面的能力不是一朝一夕的事情,只有通过长期的锻炼和实践才行。也就是说,一个人的漫长的职业道路会不断培养这个人的做项目的能力。做项目的功利性不能太强,尽量做出能够解决实际问题的东西,否则就成了为做项目而做项目了。 **7.从找到好工作的角度来说,我除了有硬功夫(真正掌握知识)外,有哪些很重要的软实力要培养呢?** **我现在担心的就是如果我的专业技术能力达到了招聘的要求,但是会不会因为在面试中因为沟通能力、交际能力、应变能力不好而与理想的offer失之交臂呢?感觉时间真的是不够用的。您感觉那些面试能力在找工作前多准备多训练一下能行吗?怎么样权衡培养软实力与硬实力的关系呢?恳请您能给予指导。** 周:一个软件工程师需要具备以下能力:1) 硬能力。包括:专业能力(学校里面的课程主要是培养这个)、业务能力(包括编写代码和文档的能力等)等。2) 软能力:包括:分析解决问题的能力、与人沟通交流的能力、承受压力的能力、自我调节的能力等。你就要在学校里面注意培养以上两种能力。具体而言,除了学习专业知识、动手编写程序、做项目之外,你还要多与人沟通、多参与团队活动,建议你参加一些社团活动,以此来培养自己的“软能力”。“软能力”的培养是潜移默化的,不会立竿见影。另外,建议你不要做一个大学里面的“苦行僧”,要享受大学生活的方方面面。   我的以上建议,请参考。在大一的时候,你就有如此详实的规划,相信你的未来是可期的。但为了实现自己的目标,你一定要脚踏实地,要学到真正的本领,要多向周围的优秀人物学习,多总结和分享。在此,建议你阅读李开复老师写给大学生的七封信及贺利坚老师的《逆袭大学—传给IT学子的正能量》一书。 最后,愿大学生活为你插上腾飞的翅膀,愿你的大学生活精彩无比!     周兆熊 2015年3月28日       (本人微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)