今天偶尔翻出了大一时候使用的谭浩强《C语言程序设计习题集和上机指导》,发现里面的代码格式真的不敢恭维。原来我们就是看着这些书本来学习成长过来的,当然,他的《c语言程序设计》我觉得还很不错的,大一的时候,就是这本书带领我进入了程序设计的世界。这里我想强调的是,在学习编程的过程中,如果能阅读一些高质量的代码,那将是非常有益的。而高质量代码的一个最基本的特征,就是有非常规范的代码格式。
有人可能觉得,代码格式有什么重要性,只要程序逻辑正确即可---这是典型的初级人员的特征。在实际软件开发中坚持规范的代码格式,可以让你非常认真严谨地对待每一行代码,对待每一个变量、每一行语句、每一个函数、类等等的程序构件,这种认真的一丝不苟的精神,是一个优秀的程序员的最基本特征,它可以使你避免很多潜在的犯错,并且使得程序的可读性大大增强,让别人读你的代码不仅不是一种痛苦,而且是一种享受----这正是我阅读Berkeley DB的代码时候的感觉。不是我为我们的产品吹牛,事实上,优美的让人赏心悦目的代码是诸如Apache, Berkeley DB, Linux等等无数优秀开源软件的共同特征,阅读这类代码,常常是我有一种相见恨晚的感觉----为什么大一大二学编程的时候,没有看这些项目的代码呢?即使当时没有全部看完或全部看懂,也会让我有一种熏陶和感染,对我的程序设计能力有很大的提高!
学习编程语言,和学习人类自然语言非常类似,要多读多写。不同是,编程语言不必听和说,并且要简单而规范的多,所以学习起来容易得多。想要成为一个编程高手,就和想要成为一个优秀的作家类似,首要的任务就是深刻地理解和掌握你的语言,它是你表达思想、描述解决问题的方法的工具。而要想深刻掌握一门编程语言,就需要阅读大量优秀的同语言代码,学习别人使用这门语言的方法和技巧、对各种语言构造的用法、编程范式、程序设计思想等等。同时伴随着自己的实践 ---写代码,解决一些实际问题,把你在阅读优秀代码中领悟到的应用到自己的程序设计当中去。这种良好的经过实践验证有效的使用语言的习惯和方法,会成为你的宝贵财富,是你的技术能力的重要组成部分,你会少犯很多错,少走很多弯路,少浪费很多个本可以呼呼大睡的通宵去调试你那充满bug的代码!
学习编程,要边学边用。程序设计是一个实践性非常强的工作,如果你没有写过一行代码,而是把c++语言规范倒背如流,你也未必能写出优秀的软件,你极可能成为赵括之流,只能纸上谈兵。当你把C++语言规范倒背如流的时候,你就好象手中拿到一件超级无敌武器,你知道它有多少种炮管、每种炮管每秒钟能发射多少枚炮弹,每种炮弹的出口速度、射程、这件武器最高时速是多少,续航有多远等等,你也知道如何启动它,加速、减速、刹车、瞄准、发射等等,但是在实际战场上面当你前方一千米处出现大量可疑的移动物体的时候,你该怎么办?要发射呢还是先观察,发射会暴露自身目标,更何况可能是己方人员或者一群动物等;但是如果不抓紧时机发射炮弹粉碎那些可能是敌人的物体,你可能会被敌人炸成碎片。归根结底,你只知道这件武器的各种技术性能,但是并不会用它解决实际问题。要知道,无论哪个职业,你从事这个职业就是要解决实际当中的问题,这样你才能创造价值。
所以,学习程序设计,就要学会如何使用你学习的语言来解决实际问题,并且是在解决实际问题的过程中,逐渐加深对语言的理解和应用能力。比如,C++ 的泛型编程支持,我以前只涉及到使用STL类库,使用其中的容器和算法,所以对于缺省类模板参数、成员函数模板、成员函数模板重载、部分特化等等的机制,虽然在书本上看到过,但是觉得不容易理解掌握和熟练运用,所以翻完书本之后,也基本上忘记了。而当我不得不使用这些语言机制来解决实际问题的时候,我需要在实际用例下使用这些机制,于是很容易理解他们的用法、用途、以及限制。如果你不面临解决实际问题,你永远不知道,在一大堆类模板中有复杂的继承关系时,同时这个类树中又有大量虚函数以及虚函数重载的时候,会发生什么问题,如何解决;或者为什么STL的类库当中,有很多traits类,而它们的代码又是那么简单而统一,等等。这些复杂的机制和技术,我在这里不屑提及,因为如果你不需要解决实际问题,你根本没必要知道它们,与其花时间记住它们,你不如看一场电影;而当你有解决问题的实际需求的时候,你会不得不查资料,搜网络,分析如何用C++的各种强大功能解决你的问题,达到你的目的等等,于是你自然对这些机制会很理解。
通过上面的文字,我想强调的是,实践对于学习程序设计太重要了!! 不仅如此,实践对于学习其他的学问、其他的“科学和技术”也是极其重要的。以前我常常想:为什么欧美的科技实力总是比我们强呢,难道他们就比我们聪明? 为什么我们总是落后呢?现在我知道了,他们实践的机会、实践的意识非常强,他们的政府、NPO、高校、科研机构、企业都在不失时机的创作实践机会给科研人员,虽然有不少资金投入是浪费了,但是他们学到了经验和教训,而更多的项目成功了,获得了巨大的回报;而近二十年,我国相当一部分决策者妄想要走捷径,用市场换技术,犯了相当大的错误。如果我们自己不去解决实际问题,即使人家把技术资料放在你的案头,你也还是比人家落后,因为这个技术你也还是没有掌握!所以到现在,我们的先进飞机、汽车、发动机等等的制造技术,还是比国外前沿落后很多。遗憾的是,现在的高校计算机教育,对实践的重视程度还远远不够!学习程序设计、数据结构等课程,日常编程练习题加上一个像样的大作业就算是全部实践了,而诸如操作系统、数据库等课程,有几个学校会组织学生分组开发一个微型的操作系统或者数据库呢?
既然实践很重要,那么怎么实践呢?特别是,在你的计算机教师不那么重视实践的时候,在你没人指导的时候。首先,你可以下载我上面所说的开源项目的源代码,和文档。先阅读使用文档,安装软件并且使用它,做到能够熟练使用基本功能。然后阅读附带的开发者文档(如果你研究Linux,你会有更大量的资源,有很多源代码分析之类的书籍),同时在文档帮助下阅读代码,研究这个软件的设计思想、使用语言工具的方法、使用各种数据结构和算法的方法等等;同时你可以到这类开源项目的论坛(几乎都有,我没见过例外),向开发者提出问题。或者有相关的学习论坛,上面也有很多高手,回答你的问题。当你对这个产品的源代码有较多理解的时候,你可以试着给它增加些新功能(它们的论坛上常常有功能请求),或者更改已有功能的实现(根据对性能的抱怨或者错误报告)或者修改它的bug,等等。对于一个大三大四的本科生,研究Linux还是太大了些,操作系统方面你可以研究一些小型、微型的系统,比如Minix, ecos之类;数据库你可以研究Sqlite, Berkeley DB等。如果多个人分组研究系统的各个部分,把结果、经验、技术信息记录下来共享,并且在有了一定基础之后,试着加入自己的想法---别怕犯错---那么一个学期的学习之后,你对操作系统、数据库的原理一定会认识的更加深入和细致,而不是一些粗浅的概念。通过这样加强实践的学习,我想你对计算机软件技术会有深刻的理解和应用能力。另外,诸如Sourceforge, google code上面有不少开源项目,你可以组织几个同学创建这样一个项目来完成它,哪怕完全模仿上面已有项目的设计目标也行,这也是一个极好的锻炼的机会。
遗憾的是,本人也是在后来才认识到了上面所说,而不是在本科学习期间就这样做了,所以走了不少弯路,经验很多,教训也很多。所以,当我认识到这些的重要性之后,我觉得分享给未来的同行是非常值得的,希望对你有所帮助。