测试在程序里留些bug,让后继的维护代码的程序员能做点有意思的事。精心设计的bug是无迹可寻的,而且谁也不知道它啥时候会冒出来。要做到这一点,最简单的办法的就是不要测试代码。 永不测试 永远不要测试负责处理错误、当机或操作系统故障的任何代码。反正这些代码永远也不会执行,只会拖累你的测试。还有,你怎么可能测试处理磁盘错误、文件读取错误、操作系统崩溃这些类型的事件呢?为啥你要用特别不稳定的计算机或者用测试脚手架来模拟这样的环境?现代化的硬件永远不会崩溃,谁还愿意写一些仅仅用于测试的代码?这一点也不好玩。万一将来出了事用户抱怨,你就怪到操作系统或者硬件头上。他们永远不会知道真相的。
永远不要做性能测试 嘿,如果软件运行不够快,只要告诉客户买个更快的机器就行了。如果你真的做了性能测试,你可能会发现一个瓶颈,这会导致修改算法,然后导致整个产品要重新设计。谁想要这种结果?而且,在客户那边发现性能问题意味着你可以免费到外地旅游。你只要备好护照和最新照片就行了。
永远不要写任何测试用例 永远不要做代码覆盖率或路径覆盖率测试。自动化测试是给那些窝囊废用的。搞清楚哪些特性占到你的例程使用率的90%,然后把90%的测试用在这些路径上。毕竟说起来,这种方法可能只测试到了大约你代码的60%,这样你就节省了40%的测试工作。这能帮助你赶上项目后端的进度。等到有人发现所有这些漂亮的“市场特性”不能正常工作的时候,你早就跑路了。一些有名的大软件公司就是这样测试代码的,所以你也应该这样做。如果因为某种原因你还没走,那就接着看下一节。
测试是给懦夫用的 勇敢的程序员会跳过这个步骤。太多程序员害怕他们的老板,害怕丢掉工作,害怕客户的投诉邮件,害怕遭到起诉。这种恐惧心理麻痹了行动,降低了生产率。有科学研究成果表明,取消测试阶段意味着经理有把握能提前确定交付时间,这对于规划流程显然是有利的。消除了恐惧心理,创新和实验之花就随之绽放。程序员的角色是生产代码,调试工作完全可以由技术支持和遗留代码维护组通力合作来进行。 如果我们对自己的编程能力有充分信心,那么测试就没有必要了。如果我们逻辑地看待这个问题,随便一个傻瓜都能认识到测试根本都不是为了解决技术问题,相反,它是一种感性的信心问题。针对这种缺乏信心的问题,更有效的解决办法就是完全取消测试,送我们的程序员去参加自信心培训课程。毕竟说起来,如果我们选择做测试,那么我们就要测试每个程序的变更,但其实我们只需要送程序员去一次建立自信的培训课就行了。很显然这么做的成本收益是相当可观的。 编程语言的选择计算机语言正在逐步进化,变得更加傻瓜化。使用最新的语言算什么好汉?尽可能坚持使用你会用的最老的语言,先考虑用穿孔纸带,不行就用汇编,再不行用FORTRAN 或者 COBOL,再不行就用C 还有 BASIC,实在不行再用 C++。 FORTRAN 用 FORTRAN 写所有的代码。如果老板问你为啥,你可以回答说有很多它非常有用的库,你用了可以节约时间。不过,用 FORTRAN 写出可维护代码的概率是0,所以,要达到不可维护代码编程指南里的要求就容易多了。
用 ASM 把所有的通用工具函数都转成汇编程序。
用 QBASIC 所有重要的库函数都要用 QBASIC 写,然后再写个汇编的封包程序来处理 large 到 medium 的内存模型映射。
内联汇编 在你的代码里混杂一些内联的汇编程序,这样很好玩。这年头几乎没人懂汇编程序了。只要放几行汇编代码就能让维护代码的程序员望而却步。
宏汇编调用C 如果你有个汇编模块被C调用,那就尽可能经常从汇编模块再去调用C,即使只是出于微不足道的用途,另外要充分利用 goto, bcc 和其他炫目的汇编秘籍。 与他人共事之道老板才是真行家 如果你的老板认为他20年的 FORTRAN 编程经验对于现代软件开发具有很高的指导价值,你务必严格采纳他的所有建议。投桃报李,你的老板也会信任你。这会对你的职业发展有利。你还会从他那里学到很多搞乱程序代码的新方法。
颠覆技术支持 确保代码中到处是bug的有效方法是永远不要让维护代码的程序员知道它们。这需要颠覆技术支持工作。永远不接电话。使用自动语音答复“感谢拨打技术支持热线。需要人工服务请按1,或在嘀声后留言。”,请求帮助的电子邮件必须忽略,不要给它分配服务追踪号。对任何问题的标准答复是“我估计你的账户被锁定了,有权限帮你恢复的人现在不在。”
沉默是金 永远不要对下一个危机保持警觉。如果你预见到某个问题可能会在一个固定时间爆发,摧毁西半球的全部生命,不要公开讨论它。不要告诉朋友、同事或其他你认识的有本事的人。在任何情况下都不要发表任何可能暗示到这种新的威胁的内容。只发送一篇正常优先级的、语焉不详的备忘录给管理层,保护自己免遭秋后算账。如果可能的话,把这篇稀里糊涂的信息作为另外一个更紧急的业务问题的附件。这样就可以心安理得地休息了,你知道将来你被强制提前退休之后一段时间,他们又会求着你回来,并给你对数级增长的时薪!
每月一书俱乐部 加入一个计算机每月一书俱乐部。选择那些看上去忙着写书不可能有时间真的去写代码的作者。去书店里找一些有很多图表但是没有代码例子的书。浏览一下这些书,从中学会一些迂腐拗口的术语,用它们就能唬住那些自以为是的维护代码的程序员。你的代码肯定会给他留下深刻印象。如果人们连你写的术语都理解不了,他们一定会认为你非常聪明,你的算法非常深奥。不要在你的算法说明里作任何朴素的类比。 自立门户你一直想写系统级的代码。现在机会来了。忽略标准库, 编写你自己的标准,这将会是你简历中的一大亮点。 推出你自己的 BNF 范式 总是用你自创的、独一无二的、无文档的BNF范式记录你的命令语法。永远不要提供一套带注解的例子(合法命令和非法命令之类)来解释你的语法体系。那样会显得完全缺乏学术严谨性。确保没有明显的方式来区分终结符和中间符号。永远不要用字体、颜色、大小写和其他任何视觉提示帮助读者分辨它们。在你的 BNF 范式用和命令语言本身完全一样的标点符号,这样读者就永远无法分清一段 (…), [...], {…} 或 “…” 到底是你在命令行里真正输入的,还是想提示在你的BNF 范式里哪个语法元素是必需的、可重复的、或可选的。不管怎么样,如果他们太笨,搞不清你的BNF 范式的变化,就没资格使用你的程序。
推出你自己的内存分配 地球人儿都知道,调试动态存储是复杂和费时的。与其逐个类去确认它没有内存溢出,还不如自创一套存储分配机制呢。其实它无非是从一大片内存中 malloc 一块空间而已。用不着释放内存,让用户定期重启动系统,这样不就清除了堆么。重启之后系统需要追踪的就那么一点东西,比起解决所有的内存泄露简单得不知道到哪里去了!而且,只要用户记得定期重启系统,他们也永远不会遇到堆空间不足的问题。一旦系统被部署,你很难想象他们还能改变这个策略。 其他杂七杂八的招如果你给某人一段程序,你会让他困惑一天;如果你教他们如何编程,你会让他困惑一辈子。 — Anonymous 不要重编译 让我们从一条可能是有史以来最友好的技巧开始:把代码编译成可执行文件。如果它能用,就在源代码里做一两个微小的改动 — 每个模块都照此办理。但是不要费劲巴拉地再编译一次了。 你可以留着等以后有空而且需要调试的时候再说。多年以后,等可怜的维护代码的程序员更改了代码之后发现出错了,他会有一种错觉,觉得这些肯定是他自己最近修改的。这样你就能让他毫无头绪地忙碌很长时间。 挫败调试工具 对于试图用行调试工具追踪来看懂你的代码的人,简单的一招就能让他狼狈不堪,那就是把每一行代码都写得很长。特别要把 then 语句 和 if 语句放在同一行里。他们无法设置断点。他们也无法分清在看的分支是哪个 if 里的。 公制和美制 在工程方面有两种编码方式。一种是把所有输入都转换为公制(米制)计量单位,然后在输出的时候自己换算回各种民用计量单位。另一种是从头到尾都保持各种计量单位混合在一起。总是选择第二种方式,这就是美国之道! 持续改进 要持续不懈地改进。要常常对你的代码做出“改进”,并强迫用户经常升级 — 毕竟没人愿意用一个过时的版本嘛。即便他们觉得他们对现有的程序满意了,想想看,如果他们看到你又“完善“了它,他们会多么开心啊!不要告诉任何人版本之间的差别,除非你被逼无奈 — 毕竟,为什么要告诉他们本来永远也不会注意到的一些bug呢? “关于” ”关于“一栏应该只包含程序名、程序员姓名和一份用法律用语写的版权声明。理想情况下,它还应该链接到几 MB 的代码,产生有趣的动画效果。但是,里边永远不要包含程序用途的描述、它的版本号、或最新代码修改日期、或获取更新的网站地址、或作者的email地址等。这样,所有的用户很快就会运行在各种不同的版本上,在安装N+1版之前就试图安装N+2版。 变更 在两个版本之间,你能做的变更自然是多多益善。你不会希望用户年复一年地面对同一套老的接口或用户界面,这样会很无聊。最后,如果你能在用户不注意的情况下做出这些变更,那就更好了 — 这会让他们保持警惕,戒骄戒躁。 无需技能 写无法维护代码不需要多高的技术水平。喊破嗓子不如甩开膀子,不管三七二十一开始写代码就行了。记住,管理层还在按代码行数考核生产率,即使以后这些代码里的大部分都得删掉。 只带一把锤子 一招鲜吃遍天,会干什么就吆喝什么,轻装前进。如果你手头只有一把锤子,那么所有的问题都是钉子。 规范体系 有可能的话,忽略当前你的项目所用语言和环境中被普罗大众所接受的编程规范。比如,编写基于MFC 的应用时,就坚持使用STL 编码风格。 翻转通常的 True False 惯例 把常用的 true 和 false 的定义反过来用。这一招听起来平淡无奇,但是往往收获奇效。你可以先藏好下面的定义: 1 2 | #define TRUE 0
#define FALSE 1
|
把这个定义深深地藏在代码中某个没人会再去看的文件里不易被发现的地方,然后让程序做下面这样的比较 1 2 | if ( var == TRUE )
if ( var != FALSE )
|
某些人肯定会迫不及待地跳出来“修正”这种明显的冗余,并且在其他地方照着常规去使用变量var: 还有一招是为 TRUE 和 FALSE赋予相同的值,虽然大部分人可能会看穿这种骗局。给它们分别赋值 1 和 2 或者 -1 和 0 是让他们瞎忙乎的方式里更精巧的,而且这样做看起来也不失对他们的尊重。你在Java 里也可以用这一招,定义一个叫 TRUE 的静态常量。在这种情况下,其他程序员更有可能怀疑你干的不是好事,因为Java里已经有了内建的标识符 true。 第三方库 在你的项目里引入功能强大的第三方库,然后不要用它们。潜规则就是这样,虽然你对这些工具仍然一无所知,却可以在你简历的“其他工具”一节中写上这些没用过的库。 不要用库 假装不知道有些库已经直接在你的开发工具中引入了。如果你用VC++编程,忽略MFC 或 STL 的存在,手工编写所有字符串和数组的实现;这样有助于保持你玩指针技术的高水平,并自动阻止任何扩展代码功能的企图。 创建一套Build顺序 把这套顺序规则做得非常晦涩,让维护者根本无法编译任何他的修改代码。秘密保留 SmartJ ,它会让 make脚本形同废物。类似地,偷偷地定义一个 javac 类,让它和编译程序同名。说到大招,那就是编写和维护一个定制的小程序,在程序里找到需要编译的文件,然后通过直接调用 sun.tools.javac.Main 编译类来进行编译。 Make 的更多玩法 用一个 makefile-generated-batch-file 批处理文件从多个目录复制源文件,文件之间的覆盖规则在文档中是没有的。这样,无需任何炫酷的源代码控制系统,就能实现代码分支,并阻止你的后继者弄清哪个版本的 DoUsefulWork() 才是他需要修改的那个。
|