程序开发观点杂谈
1. 思想与概念很重要
最近开始发现计算机科学思想与概念越来越重要了,这不是过时的说教。当你使用 Java JDK时,如果不懂优先级队列的概念,可能就弄不明白PriorityQueue的行为;如果不懂哈希表的机理,也无法写出好的 equals和 hashCode的方法,更不可能用好HashMap;如果不了解阻塞I/0和非阻塞I/0的概念,读 I/0包的API文档时也会云里雾里;如果不弄懂同步、并发的原理和方法,也不可能写出正确的多线程程序。还有,WeakReference,如果不能理解垃圾回收机的原理,也闹不明白这个东西是干什么用的。 虽然经常做的是编程工作,计算机科学的思想、概念却无处不在;如果阅读源码或API文档遇到阻碍,很可能是相关的思想、概念不甚明了,需要好好补一下。
2. 学习要分主次有侧重点,掌握重要的部分
学习应该有侧重点,重点掌握影响编程工作或对编程有助益的部分,而其他的部分则作为知识背景了解即可,在工作需要时再进行深入理解。比如I/0部分,重点要掌握I/0流、缓冲、阻塞/非阻塞、同步/异步这些概念及其在编程中的应用,而I/0设备特性、读写命令、磁盘调度这些东西属于内部实现的细节,如果不专门做I/0设备、驱动程序开发这样的工作,则大概了解一下就可以了。
总之,学习任何一样技术,最好能先有个整体的了解,提取出重要的部分进行研习。所谓重要的部分,是针对具体工作角色而言,比如程序员,需要学习的是计算机系统、语言、应用框架等提供给程序员的抽象,而不是其本身的所有细节。推荐阅读:《深入理解计算机系统》("Computer System: a Programmer's Perspective ")。
3. 编写可靠可信赖的代码
请停下来。多审视一下写过的代码,能够让它更可靠更值得信赖吗?能够让它运行更好吗?能够让它更加安全吗?在这方面的知识和技能的积累,同样能够让自己的视野更加广阔,也是一种前进。以写出可靠可信赖的程序为要;不要贪多,要求精。多掌握一些系统可靠、安全性的知识;从系统整体上去把握开发活动。
编程时,要多动脑写避免bug的程序,多花点时间测试和进行程序验证,使用成熟的算法;每走一次捷径,懒一分钟,可能会花1个小时甚至1天来补偿。
4. 编程的两个信念
万事皆有因果。在出现程序错误时,要坚信一定是什么地方出错了。即便不是软件逻辑错误,也可能是硬件一时“喘不过气”来。每一个错误,都是通向新知的机会,搞清楚背后的缘故。多做对比实验(在其它机器上运行相同的拷贝)、在任何值得怀疑的地方插入打印语句,查看结果是否如预期、耐心推敲,逐渐缩小排查范围,直到最终查个水落石出。
思从深而行从简。这句话是从一位读者对《编程珠玑》的评论借用而来的,我觉得非常贴切。一定不要急着下手去编程,将问题分析透彻,将实现方案规划到比较成熟的地步, 先做什么,然后怎么做,如何去做每一步, 每一步有什么关键点、难点,采用什么方法和技术去解决,在脑子里想清楚或者与别人讨论,就像计算机一样,绝大多数事情都可以分解为一系列的微小指令来完成。思从深而行从简,真言也。
5. 编程语言: 程序员的随身兵器
在看电影时,通常会发现那些高手都会有适合自己的奇奇怪怪的兵器,长枪、短剑、双截棍、方天戟等。类比而言,编程语言就是程序员的随身兵器。不同的兵器有不同的擅长领域。那到底应该选择哪一种呢?我个人觉得,先确定想从事的领域, 然后选择最适合该领域的语言进行学习和应用。最好,面向过程语言、面向对象语言、函数型语言、系统脚本语言、浏览器语言各掌握一种,比如C/Java/Lisp/python/Javascript. 此外,熟悉尽可能多的语言也是很有助益的。
6. 程序员的技术成长路线
根据《软件工艺》的说法(我是比较认同的), 程序员可以分为三个阶段:学徒,小工,专家。
学徒:主要是学会编程。掌握一些专业基础知识(主要是数据结构、算法、操作系统、数据库、计算机网络),学会一门语言,使用一些框架做一些小型的项目,养成良好的程序设计习惯和素养。推荐书籍:《编程珠玑》和《程序设计实践》。这两本书都是教会人如何更好地编程,而不是简单地敲入代码。
小工:主要是提高编程技艺,研习软件设计与应用架构。这一阶段,通过真实的项目开发,磨炼更好的编程技艺,养成良好的开发习惯;同时,要注意多多研习软件设计、应用架构的思想,了解系统性能、可靠性等更高层面的知识,积累经验。小工阶段通过熟悉和掌握各种框架的思想精髓,最终达到不依赖框架的地步。推荐:《程序员修炼之道:从小工到专家》
专家:主要是利用已有的知识和经验进行软件项目的开发、管理和咨询,并不断从中汲取教训。专家阶段应当不再依赖于任何应用框架,能够根据具体的业务需求选择合适的框架或者自己设计一个,即“无招胜有招”的境界。一旦达到专家阶段,后面的故事应该看各人造化了。
7. 如何成为专家: 做好职业积累工作
[1] 平时写小程序时,尽量在设计上做更多细致考虑,做到实用化,并编写良好的文档;心中总是想着将要读程序的人。
[2] 见到好的源代码,就摘录下来,做一个简单实用的知识/代码管理系统。
[3] 在开发过程中遇到的错误及解决方案,详细地加以记录,或写成博客与更多人分享;
[4] 好的设计思想、技术,详细加以记录,或写成博客与更多人分享。
[5] 积累业务知识,乐于同客户交流和沟通。
[6] 谦和有礼,永远怀着空杯心态。
8. 做好文档化工作: 程序与文档,其实就是一对孪生兄弟,不可偏心。
程序员,从表面字义上理解,似乎能够编写好程序就足够了;实则不然。耐心、细致地做好繁琐的文档化工作,其实也是大有裨益的。
一个程序员在他一生的编程开发工作中,必然会遇到很多很多的问题及解决方案,如果不加以详细记录,那么,就很容易重蹈覆辙,或者做许多重复工作。此外,别人做好的工作,也非常值得借鉴;因此,好的程序员应当做好这些文档化工作,将自己和别人的工作都详细地加以记录,以备后用。这些是程序员极其重要的职业财富之一。
10. 每周末抽出时间关心别人的工作,关注社会热点问题
不能埋头只顾自己的事情。每周末抽出时间来关心别人的工作。在论坛里回答问题,关注开源项目的进展,关注好友的动向,关注社会热点问题,关注各行业领域的动态资讯等,给自己一个宏观的非技术性的视角。
11. 开发与学习
程序员职业生涯中做得最多的一件事就是开发。而在开发的过程中,必然伴随着更多的学习。如何协调开发和学习的关系呢?
①开发的时候,尽量熟悉和选择经过严格测试的已有库、软件包、构件等来完成开发任务,避免做重复的事情,提高开发效率和软件质量;学习的时候,则要尽量重新发明轮子,弄清内部原理和机制,同时也可获得创造的乐趣。例如, Java 应用程序中要使用哈希表时,应该直接使用HashMap等已有类,而在学习时,则要弄清楚内部的原理与实现(貌似是红黑树),并写出自己的实现;
② 在学习基本原理机制和选择应用框架进行开发之间存在一个脱节:如何应用所学到的基本原理机制呢?答案是:理解应用框架,增强学习力和洞察力。如果基础积累扎实,那么,第一二遍时就应该能够学会使用框架;第三遍就该是钻研框架源码的时间了。框架都是浮云,必须能够以不变应万变。在钻研框架源码的过程中,一个必不可缺的技能就是阅读已有代码的技能,从别人的工作中获益。
③ 永远都只是思想和技术。思想是如何做事的指南,技术是具体的代码实现。没有思想,技术会迷路;没有技术,思想只是空中楼阁。学习一样东西,首先要掌握其思想和工作机制,然后,采用代表不同视角的典型代表语言去实现它。
12. 程序与软件
程序是小而美的,彼此可以互相协作,共同完成更复杂的任务;程序只要完成自己的事情就足够了;通过细致地设计和实现,严谨地验证和彻底的测试,可以获得可靠可信赖的程序单元模块;
软件通常是庞大的,必须仔细规划模块之间的关联和交互。如果不能有效地整合各种程序单元模块,即便各个模块经过仔细的实现,也可能导致笨重臃肿的软件,费时费力。而且,软件开发常常涉及到难以用技术进行衡量的人员沟通、行政管理、以及成本、进度等因素,因此,比程序开发更为复杂。
13. 编码与程序设计
我更偏爱“程序设计”的说法。程序是用来设计的,不是纯粹的编码。在编码之前,你可以有足够的时间进行纯粹的思考和求精,深思熟虑,在吃饭时,在睡觉时,在走路时,在闭目凝神时,在一切可以停下来腾出空思考的时刻。程序员应当能够“通过纯粹的思考来预见结果,而不是依赖显示结果来判断程序的正确性”。把自己当成一个程序设计师来看待吧,学习作为这样一种角色所应当了解和掌握的知识、技能和素养。
14. 程序员的六件利器
问题分析与估算 ; 数据结构 ; 算法设计 ; 设计模式 ; 正则表达式 ; 并发编程。
15. 在纸上写代码做设计
成为一名优秀的程序员的基本要素有两个:扎实的专业基础和敏捷缜密的思维,而在纸上写代码特别有助于训练缜密的思维和设计能力。
在纸上写代码做设计有三个益处: 1. 集中注意力;2. 在纸上非常有助于做设计;3. 尽可能地远离电脑辐射。
在纸上主要是适用于做设计和编写重要的模块函数。
16. 思想先行
有所舍, 方有所成; 不以得喜, 不因失悲。最重要的是持之以恒, 可持续发展。一个程序员首先应当拥有丰富自由的思想;有了思想在先,你才能在计算机上文思泉涌,下笔千言。少上网多读书,有空就静心读书、锻炼身体、与人交流。