转自: javaeye.com
我知道你们都很忙。忙得连给代码写注释的时间都没有,哪有时间做总结呢?还是我来替大家做一些总结吧。我最近会找时间写一系列的短文,在email给你们的同时会发送到你们常去的JavaEye上。如果你抽空看看,对你和我们团队都有好处。今天我写了第一篇。
写给我的团队成员(一)—— 什么是BUG?
什么是BUG?每个写过代码或者使用过软件的人似乎都知道它是什么。然而,我们的很多工作年限有限的开发人员总是简单认为:程序跑通了,自己测了N遍了就 很少有BUG了。这是个危险的观念,没有理解深刻这一点的人会在自己的进步过中走很多弯路。更会给产品和团队带来各种大大小小的危机。
对抗BUG是我们程序员永恒的主题,要在这场战斗中获胜,首先要做到“知己知彼”——什么是BUG?
现在,我们来一起把BUG分为以下几个种类,你在Coding的时候要随时随地的想到这些:
- 最最普通的BUG。
我实在缺乏用语言来给这类BUG下定义的能力,因此你现在能够识别,这就是BUG的东西,应该可以归属于这一类。
- 编译不通过。 你可以认为这是最简单的BUG,根本不需要特别考虑,如果编译不过,Eclipse会在设计时给你个红XX 来提示的。但是,在下面的情况中,你可能看不到红XX,但BUG依然存在。
- spring的xml。缺省的eclipse可不会在design time时给任何检查。你写错一个字母,都会让你无法运行。跟业务逻辑相关的依赖关系,更别指望eclipse替你找出来。
- jsp中引用的java代码。不用我解释了吧,大家可能都有体验。至少我目前还没找到完全可靠的jsp plugin 可以帮助 eclipse来随时随地找出jsp中的代码错误。(除非你把上千个jsp文件都关闭并重新打开一遍)。
- 业务逻辑实现错误。 这就不需要过多赘述了。地球人都知道。
- 缺乏必要的事务。 在99.9%的“开发时”,事务不是必须的。在仅挨着的两条insert语句执行的瞬间,出现系统失效的可能性微乎其微。然而,一旦进入了生产环境,用“ 事务”来保持你要进行的这个action的完整性就显得非常重要了。当然,并不是所有的业务逻辑步骤都需要用事务来保护,况且让容器帮你你管理事务也是一 种懒惰但有效的做法,但与此同时自己去考虑一下“这里如果没有事务,我是否安全?“的问题,对你的进步更有好处。
- 团队使用的基本库出错。 不要认为团队自己开发的基本类库是100%正确的,轻信不完善的API的思想是大量顽固BUG的藏身之处。团队自己生产的代码还在不断的完善和发展,毕竟 咱们积累的这些”精华“与外面OpenSource的东西(而他们同样有BUG)相比,还差懂得远呢。我丝毫不怀疑里面存在超过100个算法缺陷和200 个不安全的使用方式。因此,不要”拿起来就用“,而要”三思而后行“。
- 性能陷阱。 为了尽快实现业务逻辑。我们在第一次编码的时候往往不先考虑性能问题。这个想法不算太错误,但这个想法不能太过分。特别是涉及到一些”性能敏感”的代码 段,比如我们产品中多处涉及到的Tcp Server的内核。这些部件的代码1天可能遭受几百万次的访问,瞬时绝对并发100是最正常的情况。因此0.1秒的性能损失,也会带来 100x0.1=10秒的性能损耗。10秒,足以使一个TCP Server达到实际“不可用”的严重程度!10行马虎的代码,可能毁掉客户对我们团队辛苦生产的100万代码的信任。切记!切记!
- 安全隐患。 某些安全隐患在我们刚开始写实验性的代码时往往可以忽略,但绝不能忘记。你必须在这个产品进入到下一阶段的时候加上必要的安全检查代码和与安全相关的逻辑验证代码。回忆一下,你是否忽略了下面的工作:
- http session检查。 尽管我们可以用框架来保证这一点。但你还是要检视一下,是否在某些功能的实现上,你确实忘记它了。
- 参数类型校验。 当你把一个'a'传递到servlet用Internet.parse()来处理的时候,你是否考虑了可能出现的异常情况。等等此类。
- NullException。 特别注意,千万不要让NullException出现在jsp中,否则你很难在系统部署后排查错误。在你第一次编写jsp代码时,你就必须考虑你所使用的对象或者属性是否可能为Null。
- Anti-flood。 最容易被初级程序员忽略的要点之一。因为这个bug永远不会出现在你的eclipse开发运行环境里。也往往被功能测试组的人忽略。但一旦存在这个隐患,一个最菜的Hacker用最普通的teardrop也会让你tear drop。
- 线程安全。 永远不要忘记,你的代码需要在一个多线程的环境中运行,随时随地都有可能出现并发的情况。你的产生的临时文件名是否用uuid来避免重名了?你的静态(或单态)变量是否线程安全。你是否忘记将spring里定义的bean设置为scope=prototype?
- 忘记删除临时文件。 在上传文件、生成验证图片、生成缩略图的时候,你都可能用到临时文件。你是否在使用完毕后及时的删除了它?你是否考虑过在发生异常后,仍然安全的删除了这 个文件?特别需要指出的是,我们在编码阶段的测试时,很难发现遗漏临时文件清理的工作。单在系统上线运行后,大量滞留在目录下的过期临时文件将用光客户的 服务器磁盘空间,降低系统IO的性能。
- 极不友好的UI操作。 极不友好的UI操作同样是严重的BUG。比如:
- 当用户提交表单的时候可能填写了错误格式的信息,而你的程序再提示错误,重新显示表单的时候清除了用户已经填写的数据。这对你的软件的使用者来说是极其恼火的体验,对于创造这个代码的您来说则是一种耻辱。
- 另一种“极不友好的UI操作“可能发生在这种情况——你必须跟测试人员解释——他体验到这次系统出错的原因是他(测试人员)操作的步骤或顺序不正 确。天那,这是噩梦,不仅是用户的噩梦,也是你的噩梦。如果你坚持你的做法没错,我将决定在系统上线后,把你的手机和家里的电话号码做为HELP放在你创 造的界面的显著位置呈现给使用它的80万用户。
编程,乐趣何在?
1. 什么是软件开发?
软件最基本的目标是让计算机硬件(运算/存储/输入输出)按照人们预想的规则来工作。我们又管软件叫程序,软件工程师定制编写一个“顺序、序列”,机器就按照这个序列来执行。软件开发,就是这个定制编写序列的过程。
2. 原本的乐趣:挑战和控制欲
解数学题,是
很多理科学生都很喜欢的一项活动。特别是在高中时期,证明出一道立体几何或者在模拟考试中第一个交卷儿都是非常令人羡慕的,虚荣心和满足感也会随之飘飘
然。同时,多数中学的老师和一些大学老师,喜欢把软件开发归于数学的范畴。按这个推理,喜欢数学的都应该喜欢编程。但事实并非如此。
无论男性还是女性,我们都有控制的欲望。在控制不了“人”这种活物的情况下,能够控制一台机器让他按照我们的意愿来运行,会带来极大的快感。我30多岁了还喜欢玩遥控汽车,但一直羞于去玩具店购买,直到我儿子2岁以后。玩跑车,用手臂和脚尖控制一台400马力的怒吼的发动机当然更加过瘾,但显然太昂贵了。编程则可能是达到这一目标最廉价又最冠冕堂皇的一种方式。而且编程这种活动似乎在发挥创造力和满足自我陶醉心理上有更大的空间。同样,现在的情况也非如此,越来越多的程序员开始不喜欢他的职业了。
3. 为什么软件开发越来越无趣?
3.1. 首先,软件开发并不是数学
我们在学校的时候,那些老师们把软件开发归于数学的范畴,这没错,但过于狭隘。在30年前数学或许是软件的80%,但今天我们更倾向于把软件开发称为“工程”。工程与数学是不同的范畴,尽管在工程中我们会用到数学,但并不是全部,而且在软件工业的逐步发展的过程中,由于行业的分工进一步细化,数学的应用在软件工程中的比例越来越小。
算法是数学在编程中最基基本的一种表现方式,但在80%的软件开发项目数百万行代码中,能真正让你去思考“算法”的部分寥寥无几。来自于“解题”的快感,自然无从寻觅。没有挑战,哪来成就感?
3.2. 第二,软件工程技术的发展,限制了施展的空间
计 算机给程序员提供了一个广阔的思维空间,但计算机工业则根据自己的发展需求将这个空间切分成非常细小的片断。位于产业链上游和技术前沿的厂商、团体和个人 通过中间件产品(如数据库、应用服务器)、开发工具、设计理念、框架、宣传等方式则各自独占了软件技术链上最“有趣”的一部分。多数现代程序员,则随流进 入其它一个一个狭小的片断中。那些所谓技术含量较低的管理软件(广义的业务软件)领域,更是集中了大多数的从业者。
平台、数据库、应用服务器、开发工具、现代软件设计理念、软件框架、技术宣传,这些产品和理念在推动软件工业成熟和发展的同时,一方面在宏观上提高了整个行业的生产率,降低了技术门槛,吸引了更多的从业者;另一方面则在微观上剥夺了多数程序员享受编程乐趣的环境。你应用EJB或者SSH(struts/spring/hibernate)开发项目的过程中,由衷地体会到编程的乐趣了吗?我反正没有。
3.3. 第三,VB、PHP和Java
C语言是有趣的,因为它是“计算机科学”发展的产物。
Python和Ruby是有趣的,因为它是“天才”的产物。
Delphi是有趣的,因为他是史上“最优美的结构化编程教学语言Pascal”的延伸。
与之不同的是多数的资深程序员认为VB/PHP和Java是无趣的——
PHP是快速WEB生产需求催化的产物。VB和Java则是软件工程发展的产物。
当“编程”遇上“快速生产”和“工程”的时候,乐趣就开始退化了。然而与乐趣无关的是,他们三个却成为了现代软件工业中最成功的三把斧头。一把能快速的砍出一个WEB论坛;一把能跨速的砍出Client界面;一把则通过理念、框架、规范、中间件等等等等,使得软件开发更加模式化和规范化,令软件行业向大规模工业化生产方式向前迈进了一大步。
VB、PHP和Java本身都是成功的,而陷于三者的程序员则多半难以成功。我们现在常常赞赏地说:XX技术XX框架让程序员更关注于业务逻辑。我们在享受他们所带来的便捷的同时,也正在慢慢丧失程序员的天性——创造力。
4. 寻找新乐趣之旅
我们不能选择放弃,那么就让我们开始去寻找新的乐趣吧!
4.1.创新:用户UI体验的乐趣
与20年前不同,当年的软件更接近“底层”,而今天我们所开发的软件则更多地接近用户的感官和操作。把成就感从底层的挖掘移向UI层的体验,显得顺理成章。
同时,当今的UI技术和硬件渲染能力非20年前可比。以我们目前接触最多的WEB应用为例,最为普通的HTML/CSS/Ajax/JS/Flex等技术为我们提供了全所未有界面表现能力。我一直坚信优秀的用户体验是成功的一半。最近几年的Web创新很多都集中在表现方式上,如Ajax和Flex。
一些小型的用户体验提升方式已经普及到了“标配”的程度。比如,5年前如果你在一个Web表单中输入了错误的数据,必须在提交后的下一个页面中被提示出错;而今天不能在Input框的右边提供实时交验信息的界面则是令人恼火的经历。
在UI上的创新远不止这些。在Ajax和Flash令界面表现的丰富程度达到VB/Delphi望尘莫及的今天,我们追捧着gmail,研究着google map,效仿着flickr,甚至崇拜着fins的GT Grid。一旦有人能够向UI体验发出挑战性的创新,就会给开发者赢来众多赞赏的目光和追随者的效仿,伴随而来的是开发人员极大的快乐。
4.2. 探险:扒开“框架”的乐趣
使用Hibernete谈不上乐趣,至少是乐趣有限。但如果你扒开Hibernate的代码,跟着作者的思路在数十万行代码迷宫中探险的时候,当你拨开一层层迷雾,为一段思路一行程序一种理念一个技巧而拍案叫绝的时候,你可能会得到前所未有的乐趣:
这种乐趣可能,
来自于“发现”的惊喜,
来自于“理解”的激动,
来自于“学习”的充实,
来自于“顿悟”的爽快!
来自于“英雄所见略同”的自豪感!
在咱们软件圈儿,大师用书说话,大侠则用代码说话。“书上得来终觉浅,绝知此事要躬行”。转进大侠的代码里去吧,那里有无穷的乐趣等着我们。
4.3. 拓展:扩展眼界的乐趣
我一直鼓励身边共事的开发人员多学习一些编程语言,不一定在工作中用,但起码能够见识一下另一种思维方式。这不仅能扩宽眼界,我们更能从中体会到这个职业的乐趣。
出于管理上的效率和能力,5年来我们的团队一直以Java为主,但从编程艺术的角度,我不喜欢Java。尽管我早就开始认识到软件跟艺术风马牛不相及,但有时还会以这种欺骗自己的方式自我陶醉一把。
我不喜欢Java的原因是,这种一无是处而又无处不在的编程语言养成了我的惰性,让我在工作中找不到去触碰和学习Python和Ruby的“官方”理由。
有幸的是在过去的1年里我经历的三件事情重新点燃了我学习新的编成语言的激情:
* 12个月前,我因项目需要花费了整整1个月的时间钻研Javascript。
* 5个月前,我因项目需要重新拾回了C语言(之前我已经4年没碰过make了)。
* 一星期前的一天,我无聊到把JE的Ruby论坛里的精华良好帖全部看了一遍。
试试吧,多学一种,我们一起学。
4.4.协作:大制作的乐趣
大师令我们敬仰,大侠令我们敬畏。那些底层的、抽象地、框架性的、被称为无法重造得更好的轮子的作品,似乎只与他们有缘,给我100个脑袋,我也没有信心去挑战他们的领域。那么,好吧,没骨气就没骨气了,我们还有我们取得成就感的办法——协作。
钢琴王子的独奏固然经典,气势磅礴的交响乐同样能博得喝彩。跟交响乐一样,软件工程演奏的关键同样是配合。
大制作的软件产品是任何独行侠无法完成的,一个人的精力有限兴趣狭隘,不可能达到面面俱到,也懒于照顾上至UI体验下至数据库优化的每一个细节。这正是我等发挥的乐园。
然而我不得不承认,在从树上的猴子进化到键盘前的你我他的过程中,“协作”是我们退化得最迅速的优良品质。
如何在协作中取得成就感,获得乐趣,正是我们现在不断尝试和孜孜追求的东西,它需要我们共同的努力。