`

程序员的成长从开窍开始

阅读更多

想找份用jsp做网站的web2.0的公司,谁能帮我啊,QQ:64738479,可以联系我。

 

原文:程序员的成长从开窍开始

最近,有两位Google Maps API的初学者向我请教他们按照最简单例子写的程序为什么不能正常的运行。

其中一位用GTalk跟我交流,我仔细了看了他的代码,没看出问题,把代码保存在本地,打开Firefox的错误控制台,用Firefox打开他的页面。出错的那一行被清晰的显示出来,我再仔细端详那句话,原来有两个应该是英文逗号的地方,写上了中文逗号。

另一位,在我的论坛跟我交流他的Google Maps API中遇到的问题,我看他代码的时候也没有马上发现问题。然而,同样在用Firefox打开后,问题很明显的找到了,原来是一个方法openInfoWindow被他写成OpenInfoWindow了。

在我帮助别人解决的程序调试问题中,这是非常常见的。人人都可能打出中文逗号,人人都可能把大小写写错。但是在我帮助他们解决问题以后,他们总是感慨的说,谢谢我解决了这个问题,这个问题困扰了他们几个小时,甚至是几天。

这其实并不是只有初学者才会遇到的问题,我还帮助过些有非常丰富经验的工程师解决问题,有时候问题仅仅出自某个参数没有传递进来,或者是拼接字符串的时候少些了一个冒号,或者是拼接地址的时候漏掉了http:。我甚至帮助一些人调试一些我根本不懂的语言的程序,因为多半出现的问题,都和语言特性无关,不是程序员写错了字符,就是写错了逻辑,或者是错误理解了一个函数。

出问题是正常的,写程序是一个复杂的边思考边打字的过程,笔误和一时糊涂都是难以避免的。程序员一般把这种问题叫做低级问题,因为这类问题跟你的智商完全无关,任何人都可能犯。

但是,问题在于,有时候即使是很优秀的程序员,也会被一个低级错误困扰,可能会几天都解决不了。所以,关键在于,如何找到问题。

遇到问题的时候:

  1. 不要怨天怨地。出了问题,当然有可能是系统的bug,API的问题,但是那些几率往往比你犯低级错误的几率要低多了,先从自己身上找原因,是不是自己写错了。
  2. 要掌握工具。最低限度你要会写Log,最好是Log和调试器结合。好 的工具可以大大的提高效率。以前有人跟我说,Dll不能调试,我发现可以;有人说多线程不能调试,我发现可以;有人说COM不能调试,我发现可以;有人说 IE插件不能调试,我发现可以;有人说OE插件不能调试,我发现也可以。当然,你确实会遇到不能调试的时候,当年我们做东芝芯片的嵌入程序,一个组都没有 一个仿真器和调试器,但是至少可以用Log嘛,无非是麻烦点。
  3. 分析问题要有逻辑。遇到问题可以先把所有的可能性都列出来,然后一个一个分析,肯定能找到原因的。
  4. 要学会隔离问题。问题涉及到的代码越多,越难以理解,问题越难以解决。遇到这样的情况,可以利用Log或者调试器,一行代码一行代码的给它们洗清嫌疑,这样很快你就可以找到出问题的地方。如果代码特别长,程序特别复杂,可以用二分法来做,效率很高。
  5. 千万不要懒惰,不要事事求别人。一次复杂的调试过程就像一部侦探剧,如果你有非常好的逻辑性,那这部剧的主角就是福尔摩斯,剧情一定非常精彩。我说这个是有巨大风险的,说真的我帮人调东西挺上瘾的,很有意思。但是我还是要告诉大家,一次高难度的调试之后,你的满足感绝对不亚于写了一个伟大的程序。
要想不遇到问题,写代码的时候:
  1. 要对写出来的代码负责。我很佩服那些写代码写100行都不执行一次的 高手,如果他们最后不被低级错误困扰的话我就更加的佩服了。我写程序几乎是写一行两行就要执行一次,每句话我都要确保执行效果跟我的预期一致。没错这样写的时候 可能慢一些,但是调试的时候很轻松,我可以很简单的确定哪些代码绝对没有问题。所以我写代码整体速度比一般人高。很多人学习新东西的时候喜欢把例子抄一遍,运行一下,改改,再运行。我喜欢一句一句的抄例子,抄一句两句执行一次,这样可以把例子透彻的理解,而且很难会遇到出现了问题找不到原因的时候。
  2. 函数体功能块不要过长。我认为我的智商并不高,我很难接受一个程序的一个函数体或者一个功能块超越3屏(当然逻辑真的有那么复杂除外,你会发现越是简单的逻辑越是容易被人写的冗长)。很多人对面向对象耳熟能详,对封装继承看起来驾轻就熟。但是动不动就写出来个函数体超长的程序。这就像写本书从头到尾不点句号一样,会累死读者的。自己看的时候,估计也会被累的喘不过来气。这是我对基础教育的微词所在,他们连教会学生写函数都没教会,虽然表面上他们连面向对象这么高深的东西都教。
  3. 缩进要对。这点很重要,虽然大部分语言不是像Python那样用缩进来决定逻辑块的位置,但是人看到缩进的时候,总是会以为这些缩进位置跟逻辑相关。尤其是在有大量的ifelse或者for循环等等的嵌套逻辑的时候,如果缩进错了,可能会直接让人把程序的逻辑读错。所以我拿到别人的代码,第一件事情就是整理缩进。我见过一些比较优秀的页面工程师,他们会在div结束的位置用注释写上这个div的id,这样层级关系就一目了然了。
  4. 不断重构。随着程序的不断修改,有些部分会不断的增长,原来看着清晰的架构可能因为问题的复杂而慢慢模糊,也可能被修正bug的权宜之计弄的面目全非。不信你找一个经过多次修改的程序看看,是不是满目疮痍,是不是都很难认出是你自己的作品了。这在多人参与的项目中更加严重,每个人有不同的代码风格,经过多次杂交后,你肯定认不出你的代码是骡子是马,还是四不像了。随着程序的慢慢成长,原来有些函数体会慢慢膨胀,需要拆分;有些原来简单的功能块四处都需要,应该被提炼成函数或者方法,等等。现在不重构,未来等到代码复杂到无法控制的时候,重构的工作就会变得更加困难。我见过最强的案例是,一个几千行的电子辞典配套联机软件,经过无数次的改版,变成了一个几乎无法维护的主窗体的cpp有1万8千行的怪物。最后经过复杂的重构,才变成一个出新版本只需要新增一个驱动程序的可以维护的几千行的程序。这个故事详见:一个具体项目的重构(一)一个具体项目的重构(二)一个具体项目的重构(三)
分享到:
评论
20 楼 魔力猫咪 2008-02-01  
chengren 写道
魔力猫咪 写道

还有我一次被派去帮另一个项目组(他们组一个人辞职了,人手不足)。先是在辞职那位的基础上加功能。结果我因为重构被项目经理教训了。他说这些代码是在他的指导下写的,能正常运行,我不该动(其实那位只是写了一半,而且他留下的代码结构比较乱,我那天没干别的,就清理旧代码了,不然没法干)。不但没写新东西,还把老东西改坏了(其实是我还没重构完。而且我以前没接触这些业务逻辑,重构当然难免有些错误)。郁闷。然后是在一个超级恶心的工作流上写东西。那是我第一次因为开发平台太恶心想辞职。我都不知道该怎么形容开发的别扭。好在一星期就离开了。
面向对象、重构。这些东西有些人平时叫得很响。公司老说程序员应该买《重构》。但是我重构了反而嫌我多事。光说不干。

如果你还没有熟悉这些业务逻辑,你重构的基础是什么?


当然是首先读代码。然后找到觉得需要重构的地方,稍微修改一点,然后测试。其实重构是了解系统很好的办法。不搞清楚原来人写的都是什么东西,怎么继续加功能?不要以为我是在动整个架构。我主要是把表现层的几个action的内部做了重构(典型的伪三层,业务很多写在action里了,但是好在只是相对比较简单的CRUD)。把一些混乱的操作封装到私有方法、删除一些没用的临时变量,页面上调整一下,规范一些标签。其实就是这些。主要是没有单元测试,启动一次服务器要好几分钟(破机器),所以干得很慢(我对用MOCK模拟容器这方面不太了解)。延误主要是因为发现了很多BUG,修复BUG和重构一起干了。项目经理因此认为我重构整理代码,对冒犯了他的权威。到了晚上才肯听我解释,打打哈哈过去了。
19 楼 fkpwolf 2008-01-27  
女的也一样啊
18 楼 chen 2008-01-27  
chen 写道
个人觉得还是很不错的文章了,虽然自己工作的时间还不算长,但是在写代码的时候经常回遇到lz说道的问题自己写了一大堆的代码直到最后运行的时候才发现了错误,这样反过来查找一般都是很耗费时间的.
个人觉得天生和后天的影响都是有的.实际的经验往往是关键.

个人感觉性格在调试的时候也有很大的影响,前两天工作的时候帮同事运行一个使用unix shell启动的服务器脚本,程序报出在同级命令下的需要的一个脚本没有找到,ls了一下发现是有的.那这样的错误很明显是PATH中没有加当前目录造成的.所以让他导入一下.
结果那个人就开始说什么这两个shell是调用关系,你到底懂不懂?是直接运行的?
人往往被自己蒙住了双眼.
无奈也......
17 楼 chen 2008-01-27  
个人觉得还是很不错的文章了,虽然自己工作的时间还不算长,但是在写代码的时候经常回遇到lz说道的问题自己写了一大堆的代码直到最后运行的时候才发现了错误,这样反过来查找一般都是很耗费时间的.
个人觉得天生和后天的影响都是有的.实际的经验往往是关键.
16 楼 lot1 2008-01-26  
既有天生,也有后天吧,做多了,自然生出来了。
15 楼 xmx0632 2008-01-25  
记得我的第一个hibernate程序因为.hbm.xml文件因为文件编码问题在文件开头藏了个隐藏的字符搞了2天...郁闷之极啊
14 楼 王三 2008-01-25  
以前确实碰到过楼主所说的一些情况,程序里就是少个分号而已,不注意,累得很惨才找到原因.
13 楼 akane 2008-01-25  
从作者个人的角度局部的列举了一些看法,感觉说的不是很准确。有毛病可挑呵呵。
12 楼 chengren 2008-01-25  
魔力猫咪 写道

还有我一次被派去帮另一个项目组(他们组一个人辞职了,人手不足)。先是在辞职那位的基础上加功能。结果我因为重构被项目经理教训了。他说这些代码是在他的指导下写的,能正常运行,我不该动(其实那位只是写了一半,而且他留下的代码结构比较乱,我那天没干别的,就清理旧代码了,不然没法干)。不但没写新东西,还把老东西改坏了(其实是我还没重构完。而且我以前没接触这些业务逻辑,重构当然难免有些错误)。郁闷。然后是在一个超级恶心的工作流上写东西。那是我第一次因为开发平台太恶心想辞职。我都不知道该怎么形容开发的别扭。好在一星期就离开了。
面向对象、重构。这些东西有些人平时叫得很响。公司老说程序员应该买《重构》。但是我重构了反而嫌我多事。光说不干。

如果你还没有熟悉这些业务逻辑,你重构的基础是什么?
11 楼 t0uch 2008-01-25  
我倒是觉得
人都是后天培养出来的

天生,只是某些人安慰自己的话
10 楼 netpcc 2008-01-25  
抛出异常的爱 写道
花花公子 写道
开窍嘛,敏捷开发的基本重量级的书还是要看的。《重构》、《测试驱动开发》、《敏捷软件开发:模式、原则和实践》,还有《极限编程:拥抱变化》

要是光看看书就开窍了为什么现在招不进会干活的人?
不干活是不会开窍的.

我觉得开窍这种事很大程度上是天生的。
9 楼 lordhong 2008-01-25  
5年修外功,5年修内功,10年起内外兼修
8 楼 抛出异常的爱 2008-01-24  
花花公子 写道
开窍嘛,敏捷开发的基本重量级的书还是要看的。《重构》、《测试驱动开发》、《敏捷软件开发:模式、原则和实践》,还有《极限编程:拥抱变化》

要是光看看书就开窍了为什么现在招不进会干活的人?
不干活是不会开窍的.
7 楼 花花公子 2008-01-24  
开窍嘛,敏捷开发的基本重量级的书还是要看的。《重构》、《测试驱动开发》、《敏捷软件开发:模式、原则和实践》,还有《解析极限编程:拥抱变化》
6 楼 庄表伟 2008-01-24  
这是一篇非常非常好的心得总结。

至于netpcc的看法,我觉得还是开发方法的问题,如果一个程序完全编译一次要半天,那么,你在给他加功能的时候,就应该先在外面写好、调试好这个功能,然后再并进去。

首先确保这个功能在独立的情况,能够正常工作,然后再解决集成起来后产生的问题。

这也是隔离变化的一种方法。不可能都直接在主程序上做开发,那样风险太大了。

如果是只能对整个项目全部编译,才能够做开发,那么就说明这个项目在一开始的时候,架构就出问题了。

每次写一两行,就运行一次,特别适合掌握与理解新技术的时候,这一点,我也很有体会的。
5 楼 xyz20003 2008-01-24  
神仙啊,要是写代码的人都会写log,都有逻辑思维,我就不用这么累了。

昨天还被totodo说我们教程没有竞争力,技术层次太低,没有原创性的东西,今天依然被无数的初级问题缠住手脚,希望年后能找到一个愿意做在线支持的合伙人,把我解放出来,那才有可能去好好研究研究ext内部和高级应用。

~不过要是大家都有学习能力,还没有惰性的话,我们也就没经济来源了,矛盾中。
4 楼 netpcc 2008-01-24  
<div class='quote_title'>zfms 写道</div><div class='quote_div'><ol><li>我写程序几乎是写一行两行就要执行一次,每句话我都要确保执行效果跟我的预期一致。没错这样写的时候 可能慢一些,但是调试的时候很轻松,我可以很简单的确定哪些代码绝对没有问题。所以我写代码整体速度比一般人高。</li></ol></div><p>这是非常低效的做法。正确的做法是编写单元测试。尤其是对于C++程序。</p><p>1. 我以前参加的C++项目完全编译一次要半天,增量编译也要5分钟左右。这么搞的话,一天干不了多少活,大部分时间都在喝茶了。</p><p>2. 当改变了某些代码后,很可能影响到其他部分,而你不可能再在调试器里把每一行代码再手工check一边。应该用单元测试来确保模块的行为和预期是一致的。一次性写200-300行代码再编译调试绝对没有问题。</p>
3 楼 魔力猫咪 2008-01-24  
的确如此。很多时候只是少写了一句话或者错写了一个字符。结果很多天都找不到问题。
重构大家说得多做得少。我重构过一个一个页面树的生成Action。重构前好几百行代码,无数晦涩重复的语句。可以让任何一个人望而却步。经过重构后,代码量缩少至少40%。主结构清晰,各方法职责明确。可惜时间太紧很多地方耦合比较严重。不然可以更加优雅。删掉了大篇的重复代码。真不知道当时那位怎么写出来的。

还有我一次被派去帮另一个项目组(他们组一个人辞职了,人手不足)。先是在辞职那位的基础上加功能。结果我因为重构被项目经理教训了。他说这些代码是在他的指导下写的,能正常运行,我不该动(其实那位只是写了一半,而且他留下的代码结构比较乱,我那天没干别的,就清理旧代码了,不然没法干)。不但没写新东西,还把老东西改坏了(其实是我还没重构完。而且我以前没接触这些业务逻辑,重构当然难免有些错误)。郁闷。然后是在一个超级恶心的工作流上写东西。那是我第一次因为开发平台太恶心想辞职。我都不知道该怎么形容开发的别扭。好在一星期就离开了。
面向对象、重构。这些东西有些人平时叫得很响。公司老说程序员应该买《重构》。但是我重构了反而嫌我多事。光说不干。
2 楼 抛出异常的爱 2008-01-24  
引用
出问题是正常的,写程序是一个复杂的边思考边打字的过程,笔误和一时糊涂都是难以避免的。程序员一般把这种问题叫做低级问题,因为这类问题跟你的智商完全无关,任何人都可能犯。


一般这个叫RPWT
特别是你发现只有RP好的人才可以发现这种问题的答案
1 楼 GaoYang 2008-01-24  
这篇文章看过,感觉很不错~~~

相关推荐

Global site tag (gtag.js) - Google Analytics