按照《审死官》里的读法,标题可以读着:答复:我不会圈圈圈,仍然可以叉叉叉。圈圈叉叉并不特指某个东西,而是一个通配符。代表诸如:我不懂COM原理,仍然调用COM组件。我不懂数据结构,仍然可以写程序。我记不得常用API,仍然照样用IDE。如此等等。
我是个爱好和平的人,不喜欢和别人口诛笔伐,几乎从来没有写过主动攻击别人的文章。亚里斯多德说,我爱更老师,更爱真理。让我套用为,我爱和平,更爱真理。若只是为了一已之私利,我不会写这篇文章的。这里阐明一些个人认为正确的观点,想和所有有兴趣的朋友讨论一下。但就事论事,不要进行人身攻击,没有必要引发一场口水战。
那些朋友说的也是事实,这不懂某些知识,确实仍然可以做相关的工作。这让我想起一个小故事:记得上大二时,认识了一位开家电维修店的教授,我想跟他学电器维修。他同意了,条件是要我坚持看两年时间的电路图。我找了一本长虹电视机的电路图,看了几天,发现太难了,两周过去了,一个也没看明白。
我找到那位教授,说,为什么要看电路图,小学生连欧姆都不知道是什么,更别说看懂电路图了,他们为什么也可以修家电?你不想教我就算了,干嘛要让我看两年时间的电路图。教授回答说,小学生能和教授相比吗?对小学生来说,书上有的案例,他可以修,与案例有一点差别,他就摸不着头脑了。而教授,对电器里面电路清清楚楚,不管是哪里坏了,什么现象,把几个关键点的电压电流一量,就找到问题的根源了。
用Window当然不需要了解操作系统原理,用浏览器当然不需要明白文档对象模型,把excel嵌入到word里也不需要知道OLE,用PhotoShop的人不需要熟悉图形学,用VS 2005的人不需要精通编译原理。这没有错,对用户而言,他们不需要知道他们不必知道的东西,这是用户友好性,值得提倡。而作为一个软件工程师,你应该明白操作系统原理,应该了解编译原理,应该熟悉相关的东西。
我不想说别人浮躁,我自己也很浮躁,说别人浮躁只是五十步笑百步而已,这个年头谁不浮躁呢? 但从实用的观点来说,不知道某些知识,并不值得引以自豪。理论有没有用,要不要弄清楚某个原理,要不要记住最常用的API。这都是仁者见仁,智者见智的问题。后面列举一些的个人经验,合则取之。
从毕业后到现在,我一直带在身边的书,只有一本数据结构。前前后后,为了学习的目的,我把里面大部分数据结构和算法写过三遍,这还不包括工作中零零散散写过的。开始是只是为了熟悉其原理,后来开始想怎么把代码写得更优雅一点,组织得更合理一些。这反反复复耗了我大量业余时间,事实证明这些时间没有白费。后来的经验告诉我,差不多所有程序,都是由这些基本算法和数据结构组合起来的。对这些基本算法和数据结构掌握得比较扎实,不但自己写程序可以更快,阅读别人的程序也更容易。如果你还坚持说,不懂数据结构仍然可以写程序。我会说,你永远没有别人写得快,没有别人写得好,程序没有别人的快,没有别人的稳定。
后来我又花了不少时间去学习设计模式。设计模式不是时髦,而是实用的东西,绝不止几个概念而已。我不但认真的读完了那本书,为了实践,总是找机会去用它们,那怕只是自己写个小程序,也不忘与设计模式挂钩。现在再看那些程序,或许有些丑陋,但正是那些练习让我熟练的掌握了设计模式。如今我再也不会动则就用设计模式了,因为我知道了什么地方该用,什么地方不该用。回想起来,设计模式在很多地方它帮我的大忙。如果你还在说,不懂设计模式,仍然可以写程序了。我只能替你感到惋惜,这么好的东西,你却固执的视而不见。
以前公司一个产品是基于Apache的,我只是负责维护mod_proxy模块。我的任务是修改它,让它支持HTTPS。不去研究apache的架构,不去阅读其它部分的代码,我仍然可以完成的这个任务。但我利用大量业余时间去研究apache的架构,去阅读HTTP协议,我明白了它的并发模式,明白了它的配置机制,明白了它的模块加载机制,明白了它的LOG机制,明白了作为一个服务器的基本架构。这对于完成自己的任务是有帮助的,更重要的是从中学到的知识,对后来的工作也有帮助。刚到深圳时,在新一家公司,我的第一个任务是开发一个自动编译服务器,整个过程都是自动化的,还是支持多用户排队编译。与apache相比,这自然是小菜了,包括需求分析、设计编码和用户手册,不到十天时间就搞掂了。
有段时间我维护html tidy,那本是w3开发的一个小工具,功能是用来修复HTML网页中的错误,并输出到一个XHTML文件。它相当于一个HTML语言解析器,用到编译原理的知识。而我对编译原理了解不多,如果凑合着修改BUG,问题也不大。我还是选择了学习编译原理,至少花了半年业余时间学习相关理论,自己又写了几个微型语言的解释器,感觉自己成半个编译原理专家。我发现这些知识非常有用,特别是状态机,对于字符串处理非常方便。又利用编译原理写过一些代码产生器,用它们来产生那些类似而又不同的代码,为我节省了大量的时间。如果当初我固执的认为理论没有用,一定错过了这样一件强大的武器,那是多么可惜的事情啊。
我维护过一个XMLTransformer,它的功能是调用xerces的函数把XML和XSLT文件解析成DOMTree,然后调用xalan的函数把这两颗DOMTree转换成一个HTML文件。其实只要知道xerces的接口,不明白xerces的内部工作机制,完全可以胜任自己的工作。我还是花了不少时间去研究xerces的代码,此时我还没有看过《设计模式》,看了SAX解析器的代码,我明白了Builder模式,后来屡试不爽,用这种方式,我写一个解析apache配置文件的模块,一个解析INI配置文件的模块,一个解析XML配置文件的模块,还有一个LRC歌词解析器。你看,时间没有白费吗。
有段时间老大让我去写microwindow的控件测试程序,我花了不少时间去研究microwindow的实现,明白了它消息机制,明白了各个控件的实现机制,记住了各个控件的风格、消息、通知,总结出它们的规律,写了一个通用的测试程序。不但提前完成了那个任务,这对于后来我用win32 SDK写程序帮助也很大。因为熟悉常用的控件和API,编程速度大为提高,出错几率也大为降低。
我也曾去研究过Wine的代码,主要是想知道COM的实现原理,这完全是为了满足我的好奇心。看似无关紧要的知识,也后来竟然派上了大用场。为了简化进程间通信机制,我们在一个嵌入式系统中,实现一套进程间通信机制,大大简化了进程间的过程调用,成为那个平台的基本架构之一。同样是因为兴趣,我研究了gdb和ptrace的实现,学习到的知识也在后来的工作中派上了用场。
还有很多这样的例子,说这些无意炫耀自己,我只想说明这样一个事实:书到用时方恨少。很多知识,知道比不知道好,知道了至少就多一种选择,甚至可能在你意想不到的时候派上用场。
作为程序员,固执的不去学习,或者因为门户之见而把自己限于一个小范围,个人认为不是明智之举。一句话,知道它们,我们可能做得更好,不知道它们,决不可能做得更好!