成为优秀码农的十二项自我修养
1.研究数据结构
计算机科学家Niklaus Wirth曾经有过一个著名论断:“数据结构+算法=程序”。可见,数据结构是计算机程序的基础,它们就像构造房屋的砖头一样。实际上,数据结构决定了程序将如何快速有效地解决问题。一旦使用了正确的数据结构,您的程序方案会变得既简单,又省时。
那么,我们该如何研究数据结构呢?
- 首先,选择一本好书,以理解并掌握有关如何设计和执行数据结构。在此,我推荐Narasimha Karumanchi撰写的《轻松实现数据结构和算法》(Data Structures and Algorithms Made Easy,https://amzn.to/34DxomJ)一书。这是C/C++版本的,您也可以通过链接:https://amzn.to/2NZ3W4E,找到其对应的Java版本。
- 其次,尝试从头开始实现一些数据结构,例如:列表、堆栈和队列。您不仅可以深刻地理解到它们的工作原理,而且还能够通过“重新发明”这些数据结构来提高编程的技能。
- 第三,试用那些由自己常用的编程语言所提供的内置数据结构(如果是Java,则对应的是Collections框架)。例如:使用不同的列表,通过索引来快速访问各种元素;将集合用于元素的随机排列;使用队列进行producer-consumer的处理等。
- 第四,在编写代码之前,请认真思考并选择出最适合于解决问题的数据结构。当然,您不必重复造轮子,请尽量利用当前编程语言所提供的现有数据结构。
2.学习算法
如果说数据结构抽象出了问题的输入和输出的话,那么算法则决定了系统该如何解决问题。优秀的程序员一般都能善于使用经过实际检验的算法、并编写出新的算法。
由于算法不仅需要良好的逻辑思维,而且需要一定的数学能力,因此它是编程中最难学习的部分之一。如果您能够灵活运用自己擅长的各种算法,那么您将很容易从编程人群中脱颖而出。
不过,好消息是:您不必从头开始发明各种算法,只需要学习和使用那些经过实际检验的实用算法便可。我建议您至少对如下基本算法有一定的了解:排序(快速排序、合并排序等),二进制搜索,递归,图检索,greedy,密码学相关基础知识,以及复杂的big O表示法。
那么,我们应该如何学习算法呢?除了上述提到的数据结构书籍之外,我建议您通过选读《算法简介》(Introduction to Algorithms,https://amzn.to/2NWOoyw)一书,以获取相关的概念,并从头开始实现那些热门的算法。通常,您可以试着通过自行编程来模拟算法的运作原理。例如,您可以编写一个程序,以可视化的方式显示快速排序算法的工作方式。籍此,您不但可以学到许多相关概念,并且能够大幅提高自己的编码技能。
3.研究设计模式
虽说编程就是为问题寻找的某种解决方案,但是方案本身也可能会面临各种问题与挑战。例如,我们往往需要更好的性能、更灵活的设计、更可靠的体系结构、更少的错误、以及更少的潜在瓶颈。因此,设计模式是解决在软件设计中各种常见问题的一种行之有效的解决方法。
要成为一名优秀的程序员,您应该能够将恰当的设计模式应用到程序的技术实现上。那么我们应该如何学习设计模式呢?在此,我建议您从著名的设计类书籍:《设计模式:可重用的面向对象软件的要素(C/C ++实现)》(Design Patterns: Elements of Reusable Object-Oriented Software,https://amzn.to/2Q6B2Cy)入手。如果您经常使用的是Java的话,我建议您阅读《深入浅出设计模式》(Head First Design Patterns,https://amzn.to/2LtXu44)。通过学习,您可以迅速地掌握各种基础的设计模式,其中包括factory、builder、strategy、command、template、facade、visitor、singleton。
当然,这是一个反复的过程,您只有通过阅读案例,研究设计模式,编写各种代码,测试不同的模式,才能真正理解并自信地将自己的设计模式应用到程序之中。
4.读书
您会坚持每年阅读几本编程书籍吗?如果您的答案是少于三本的话,那么您该适当地反省一下了。毕竟,那些优秀的程序员都会表现出对新知识的如饥似渴。因此,我建议您每年至少阅读五本书。这些书籍不但是过往经验的集合,而且能够拓宽您的视野,帮助您更快地获取新知,以及向您展示如何以正确的方式实现软件与产品的功能。
那么,我们应该阅读哪些书籍呢?我推荐您从如下的必读书目开始:
- 程序员修炼之道(The Pragmatic Programmer,https://amzn.to/2Q6NUso)
- 代码大全(Code Complete,https://amzn.to/2IhRA4f)
- 程序员职业规划之道(The Passionate Programmer,https://amzn.to/2NXF0uz)
- 软件工艺(Software Craftmanship,https://amzn.to/2Lv7kTv)
而对于Java编程爱好者而言,《Java 高效编程》(Effective Java,https://amzn.to/2Q82yzr)也是必读书目。择日不如撞日,咱们现在就开始规划一年内需要阅读的书籍吧。
不过,您在阅读时请记住如下两点:
- 不必从头到尾地读一本书。这样您可能没有足够的时间和耐心。请试着采用一种明智的方式:首先只阅读您需要的内容,然后在有时间的情况下阅读其他的部分。例如,如果您需要应用Strategy模式,则应当重点阅读涉及到该模式的章节;而如果您需要编写servlet,则请关注servlet的相关章节。
- 请认真做好笔记与练习,好脑筋不如烂笔头,这样会加深您的阅读印象与效果。
5.阅读各种博客与杂志
众所周知:为了留存和吸引读者,博客总是比书籍要更新得多。您可以在自己的细分市场与领域中找到一个权威性的博客或网站,坚持阅读那里您所感兴趣的各种帖子。例如:您可以通过每周阅读一篇新文章的方式,让自己与当今快速变化的技术保持更新。
在此,我会推荐DZone.com网站,这是一个最初为Java开发人员构建的社区。如今,它已成为了网络中最大的软件专业人员的交流社区之一。您可以在DZone上找到从Java到Javascript,从Web开发到敏捷(Agile)方法,从大数据到云计算等,几乎所有类别的技术实用文章、见解和建议。
此外,您也可以订阅自己相关领域的传统或电子杂志。例如:对于Java而言,我建议您阅读由Oracle发行的双月刊Java Magazine(https://www.oracle.com/technetwork/java/javamagazine/index.html),它涉及到了Java技术管理的方方面面。
6.使用单元测试
在编程项目中,您可能听说过“先写测试,后写代码”的说法。我们需要将普通的需求转换为非常具体的测试用例,然后编写代码,以实现业务逻辑,并确保它们能够通过所有的测试。因此,我们应当通过编写代码,来测试每个程序的类,以及每个类的方法。
在编程界,大家普遍采用的是单元测试的方法。其好处包括:能够及早地发现问题,促进代码的更改与重构,简化各种集成测试,为系统提供实时的文档等方面。
单元测试直接导致了测试驱动开发(Test Driven Development,TDD)方法的出现。如今,TDD已被许多程序员运用到了多种编程语言中。
那么,我们应该如何学习单元测试呢?我建议您阅读《单元测试的艺术》(The Art of Unit Testing,https://amzn.to/2NbbiCG)一书。它是有关单元测试与TDD方面极好的书籍。
而对于Java而言,由于JUnit是Java开发中非常受欢迎的测试框架之一,因此您可以从《Junit教程:设置、编写与运行Java单元测试》(JUnit Tutorial: Setting Up, Writing, and Running Java Unit Tests,https://dzone.com/articles/junit-tutorial-setting-up-writing-and-running-java-1)开始。可以说,如果您从未使用过任何单元测试框架的话,那么您势必缺少了软件开发环节中的一项有力工具。
7.参与自由项目
以兼职或全职的方式参与自由项目,以提高编程的技能,是成为一名优秀程序员的快捷方法之一。简而言之,自由项目意味着您可以在线查找项目,通过远程工作的方式获得在线的报酬。更棒的是,您可以选择自己喜欢的项目类型,例如:PC端、Web应用、移动应用、设计、编程、测试、乃至某些硬件项目。这些都可以让您在各个领域积累并拓展自己的编程经验,提升面对挑战的能力。
相比公司里的那些循规蹈矩的项目,自由项目虽然显得更丰富、更精彩。但是,成为一名自由职业者可一点也不轻松。自由职业的市场往往充满了激烈的竞争,您要面对成千上万个其他自由职业者的争抢与挑战。因此,我强烈建议您最好在保留当前工作的前提下,逐渐参与或领取自由项目。
那么我们应该如何当一名自由职业者,开展自由项目呢?我建议您去访问Freelancer.com网站。它是网络上最大的自由职业市场之一,您可以在其中找到几乎任何种类的工作。自2009年以来,我持续参加了该网站上的各类项目,目前已完成了142个项目,平均评分为4.8/5。当然,我从中也积累了丰富的编程经验。
8.做编外项目
如果您不喜欢做自由项目的话,那么可以通过接手一些有趣的小项目,来打发空闲的时间。处理此类项目可帮助您提高各个阶段的编程技能,其中包括:编码、测试、设计、文档编制、以及部署等方面。与您在公司参与到的主要工作相比,这些编外项目向您提供了软件开发的整个过程,而不仅仅是编码这一个阶段。
那么我们应该如何参与编外项目呢?常言道:不积跬步,无以至千里。我的建议是“从小开始”。由于一开始您并没有足够的资源与经验,因此最好不要马上开展大型的项目。另外,您需要管理好自己的时间,一般以两到三个月内完成一个项目为宜。
9.参加编程比赛
也许这是激发您自己成为一名优秀程序员的最具挑战性的方式。为了参加比赛,您必须投入大量的时间和资源,并高度重视具体的开发环节,但是这对于提高您整体的编程技能是大有好处的。
请记住:重要的不是获奖,而是在比赛中的成长。我曾经参加了几次移动应用和桌面端游戏的竞赛,虽然并未获得任何奖励,但是我承认自己在努力保证按时提交程序作品的时候,已经学到了不少的东西。
当然,您也可以尝试一些著名的编程竞赛,例如:微软的Imagine Cup(https://www.imaginecup.com/);由IBM赞助的ACM-ICPC(https://icpc.baylor.edu/),以及TopCoder(https://www.topcoder.com/)。前两个是面向学生的,而最后一个则是面向所有程序员的。另外,您还可以寻找并参与本国、本地区、乃至本公司举办的各类竞赛。不要担心自己是否拥有足够的经验,大胆注册,一切随缘!
10.进行规范性审查
代码审查工作应当定期在项目团队中开展。您既可以对他人的代码进行规范性审查,也可以让其他程序员来审查您的代码。一系列的审查工作,不但能够规范大家编写程序代码的习惯,而且有助于团队成员之间相互学习、取长补短。
我建议您使用Sonar Qube(https://www.sonarqube.org/)之类的代码分析工具。此工具可扫描整个代码库,并根据各种代码的质量标准生成详细的报告。一般而言,您需要持续修复代码中的问题,直到该工具不再出现“红色报警”为止。当然,某些代码分析工具还能够与您的IDE(如,Eclipse或NetBeans)很好地集成在一起,使得代码的检查过程更加顺畅自然。
11.阅读代码
与检查代码不同的是,我们也需要花时间去认真阅读其他程序员写出的代码。通过这一过程,您将学到更多的东西。正所谓:“一千个人心中有一千个哈姆雷特”,面对同样的软件需求,不同的编程专家会编写出截然不同的代码解决方案。只要您能够潜下心来仔细阅读,就能收获到各种设计上的创新和编程上的经验。
对于Java用户而言,我建议您阅读Java Collections框架(https://www.codejava.net/java-core/collections)的源代码。您可以在JDK的安装目录下,通过src.zip文件找到它。当然,您也可以试着去阅读诸如Spring、Hibernate、以及Struts等流行框架的源代码。
12.开展与编程相关的教学
常言道:“最好的学习方法是进行教学”。您可以通过录制视频、撰写文章、创作书籍、甚至是组织编程课程等形式,以帮助其他人学习编程。通常情况下,单纯的编程目的是为了使程序代码能够“起作用”,而您在准备教学的过程中,往往会学习研究那些与目标课程主题相关的所有内容。“教学相长”就是这个道理。
在此,我强烈建议您选择一种最适合自己的教学方式。例如:在创建自己的网站--CodeJava.net(https://www.codejava.net/)和Java Youtube(https://www.youtube.com/codejava)频道之前,我曾经持续为一些编程网站编写了各种各样的Java教程。而且,我还在Udemy上开设过一些Java课程。