前天做了一个梦

梦见的场景有点像我在沈阳老家对面的体育场后面,我在拿着一个步枪,周围是变异了的怪物,像僵尸。我在消灭他们。开始还没什么问题,后来发现我的武器不好使了,这时出现了一个科学家,像007里的那个科学家,给了银弹,我一试第一个僵尸,不错干掉了,第二个就不行了。回头一看科学家也被僵尸干掉了。没办法我只能跑,跑到一个房子后面发现这里没有僵尸,地上是鸡蛋液,原来僵尸怕鸡蛋。开始用鸡蛋,也是头几个还行,后来就没用了。只能在跑,这是发现一个人,他说这些僵尸是他造出来的,他可以给我一种能力,去消灭怪兽,但是,他必须要制造出另外一批怪兽,这些怪兽是不惧怕那种能力的……

后来我醒后,想了好久,我们就是在这样的前进,走一步,跌倒爬起,再跌倒,再爬起,解决一个问题,然后遇到更困难的问题。虽然这是无止境的,但是却说明我们在进步,影响圈在扩大。还有世上没有银弹,有时臭鸡蛋要比银弹管用,关键看用在哪里。

Advertisements

[转]主题:写给我的团队成员(一)——什么是BUG?

原文:http://www.javaeye.com/topic/241569

—–引用—–

我知道你们都很忙。忙得连给代码写注释的时间都没有,哪有时间做总结呢?还是我来替大家做一些总结吧。我最近会找时间写一系列的短文,在email给你们的同时会发送到你们常去的JavaEye上。如果你抽空看看,对你和我们团队都有好处。今天我写了第一篇。

写给我的团队成员(一)—— 什么是BUG?

      什么是BUG?每个写过代码或者使用过软件的人似乎都知道它是什么。然而,我们的很多工作年限有限的开发人员总是简单认为:程序跑通了,自己测了N遍了就很少有BUG了。这是个危险的观念,没有理解深刻这一点的人会在自己的进步过中走很多弯路。更会给产品和团队带来各种大大小小的危机。

      对抗BUG是我们程序员永恒的主题,要在这场战斗中获胜,首先要做到“知己知彼”——什么是BUG?

      现在,我们来一起把BUG分为以下几个种类,你在Coding的时候要随时随地的想到这些:

  • 最最普通的BUG。 我实在缺乏用语言来给这类BUG下定义的能力,因此你现在能够识别,这就是BUG的东西,应该可以归属于这一类。
  • 编译不通过。 你可以认为这是最简单的BUG,根本不需要特别考虑,如果编译不过,Eclipse会在设计时给你个红XX 来提示的。但是,在下面的情况中,你可能看不到红XX,但BUG依然存在。
  1. spring的xml。缺省的eclipse可不会在design time时给任何检查。你写错一个字母,都会让你无法运行。跟业务逻辑相关的依赖关系,更别指望eclipse替你找出来。
  2. jsp中引用的java代码。不用我解释了吧,大家可能都有体验。至少我目前还没找到完全可靠的jsp plugin 可以帮助 eclipse来随时随地找出jsp中的代码错误。(除非你把上千个jsp文件都关闭并重新打开一遍)。
  • 业务逻辑实现错误。 这就不需要过多赘述了。地球人都知道。
  • 缺乏必要的事务。 在99.9%的“开发时”,事务不是必须的。在仅挨着的两条insert语句执行的瞬间,出现系统失效的可能性微乎其微。然而,一旦进入了生产环境,用“事务”来保持你要进行的这个action的完整性就显得非常重要了。当然,并不是所有的业务逻辑步骤都需要用事务来保护,况且让容器帮你你管理事务也是一种懒惰但有效的做法,但与此同时自己去考虑一下“这里如果没有事务,我是否安全?“的问题,对你的进步更有好处。
  • 团队使用的基本库出错。 不要认为团队自己开发的基本类库是100%正确的,轻信不完善的API的思想是大量顽固BUG的藏身之处。团队自己生产的代码还在不断的完善和发展,毕竟咱们积累的这些”精华“与外面OpenSource的东西(而他们同样有BUG)相比,还差懂得远呢。我丝毫不怀疑里面存在超过100个算法缺陷和200个不安全的使用方式。因此,不要”拿起来就用“,而要”三思而后行“。
  • 性能陷阱。 为了尽快实现业务逻辑。我们在第一次编码的时候往往不先考虑性能问题。这个想法不算太错误,但这个想法不能太过分。特别是涉及到一些”性能敏感”的代码段,比如我们产品中多处涉及到的Tcp Server的内核。这些部件的代码1天可能遭受几百万次的访问,瞬时绝对并发100是最正常的情况。因此0.1秒的性能损失,也会带来100×0.1=10秒的性能损耗。10秒,足以使一个TCP Server达到实际“不可用”的严重程度!10行马虎的代码,可能毁掉客户对我们团队辛苦生产的100万代码的信任。切记!切记!
  • 安全隐患。 某些安全隐患在我们刚开始写实验性的代码时往往可以忽略,但绝不能忘记。你必须在这个产品进入到下一阶段的时候加上必要的安全检查代码和与安全相关的逻辑验证代码。回忆一下,你是否忽略了下面的工作:
  1. http session检查。 尽管我们可以用框架来保证这一点。但你还是要检视一下,是否在某些功能的实现上,你确实忘记它了。
  2. 参数类型校验。 当你把一个’a’传递到servlet用Internet.parse()来处理的时候,你是否考虑了可能出现的异常情况。等等此类。
  3. NullException。 特别注意,千万不要让NullException出现在jsp中,否则你很难在系统部署后排查错误。在你第一次编写jsp代码时,你就必须考虑你所使用的对象或者属性是否可能为Null。
  4. Anti-flood。 最容易被初级程序员忽略的要点之一。因为这个bug永远不会出现在你的eclipse开发运行环境里。也往往被功能测试组的人忽略。但一旦存在这个隐患,一个最菜的Hacker用最普通的teardrop也会让你tear drop。
  • 线程安全。 永远不要忘记,你的代码需要在一个多线程的环境中运行,随时随地都有可能出现并发的情况。你的产生的临时文件名是否用uuid来避免重名了?你的静态(或单态)变量是否线程安全。你是否忘记将spring里定义的bean设置为scope=prototype?
  • 忘记删除临时文件。 在上传文件、生成验证图片、生成缩略图的时候,你都可能用到临时文件。你是否在使用完毕后及时的删除了它?你是否考虑过在发生异常后,仍然安全的删除了这个文件?特别需要指出的是,我们在编码阶段的测试时,很难发现遗漏临时文件清理的工作。单在系统上线运行后,大量滞留在目录下的过期临时文件将用光客户的服务器磁盘空间,降低系统IO的性能。
  • 极不友好的UI操作。 极不友好的UI操作同样是严重的BUG。比如:
  1. 当用户提交表单的时候可能填写了错误格式的信息,而你的程序再提示错误,重新显示表单的时候清除了用户已经填写的数据。这对你的软件的使用者来说是极其恼火的体验,对于创造这个代码的您来说则是一种耻辱。
  2. 另一种“极不友好的UI操作“可能发生在这种情况——你必须跟测试人员解释——他体验到这次系统出错的原因是他(测试人员)操作的步骤或顺序不正确。天那,这是噩梦,不仅是用户的噩梦,也是你的噩梦。如果你坚持你的做法没错,我将决定在系统上线后,把你的手机和家里的电话号码做为HELP放在你创造的界面的显著位置呈现给使用它的80万用户。

……

儿子刚刚给我倒了杯咖啡端倒了书房里,从味道上判断,他在厨房里误把味精当白糖给我放了很多。但无论如何他是在讨好我去陪他玩了。那么,这次就写到这里吧。