还记得以前本站的那一篇“编程好难啊”吗,那是一篇众程序员调侃程序新手的文章,有恶搞的成分在里面。今天要和大家说的这个事没有一些恶搞和调侃的意思,是比较严肃的话题,你一定可以从中收获一些东西。这个话题来自StackOverflow上的一个问题——Cycle in Family Tree Software,这个程序员问了下面这个问题:

我是一个写家族族谱软件的程序员(我用的是C++和Qt),这个软件基本上没有什么问题,直到有一天有个用户报告了一个bug。这个问题是这样的——我这个用户和他女儿生了两个孩子

于是,我程序员的一些断言和硬性条件导致程序报错,因为我的程序在处理这个关系的时候,其发现X即是Y的爸爸,又是Y的爷爷,所以只能报错。

请问,在不需要移除我的断言和数据验证的情况下,我怎么才能解决这个问题

看到这里,请重点阅读一下下面的两点:

  • 如果你看到这里开始兴奋了,请你为你阴暗的心理去面壁反省10分钟,因为这是一个很技术的问题。
  • 如果你开始陷入了深深的思考如何解决这个问题,那么你绝对是一个合格的程序员,因为你已陷入技术已经很深了,有点呆了。

我在前面说过,“这个是一个严肃的话题,你可以从中收获一些东西”,当然,我并不希望你来收获乱伦的知识和心得,酷壳是一个技术博客,应该是收获技术方面的东西。

从技术的角度上来说,这是我们经常在设计软件时犯的错误——

1)作了错误的假设(Assumption)

Assumption是软件设计的重大天敌,Assumption的动词Assume意为Ass u me – Ass you and me 。你的假设做得越多,你的设计就越不靠谱。这里的假设是——我们以为family tree是一个tree,其实并不是tree。Assumption是魔鬼

还有一些经典的Assumption如下所示

  • 最著名的就是那个y2k臭虫。
  • 不要以为没有2月30日,在瑞典1712年有2月30日
  • 一分钟有60秒?闰秒呢?
  • 双胞胎的生日是同一天吗?
  • 双胞胎的父亲是同一个?
  • 性别只有男和女?
  • 婚姻只能是异性? 关于这一点,推荐一篇强文——Gay marriage: the database engineering perspective (同性婚姻:数据库工程)

2)没有认真分析用户案例(Use Case)

在设计软件时,我们需要考虑各种各样的用户案例,比如如下的东西:

  • 私生子的问题
  • 一夫多妻或一妻多夫,同父异母,同母异父
  • 就算一夫多妻制违反法律,也会有离异再婚的情况
  • 同性恋的问题,虽然不能繁衍,但可以领养。
  • 换妻活动
  • 各种乱伦关系——这种东西那个民族都不少,尤其是古时候,比如:
    • 先后嫁了两个人其是父子关系(昭君)
    • 达尔文同学和他的表妹,爱因斯坦的二婚是和他的表姐,埃及艳后嫁了她的弟弟,……
    • 顺治同学娶了四个老婆,这四个人还是一家人:姑姑,侄女,妹妹,女儿。(参看这里
    • 刘邦同学的母后干出来的事,相当变态(参看这里
    • 中国古代的“扒灰老” (类似于楼主那个问题的Use Case)

不想再列下去了,人类真TMD恶心,有点要吐了

——————————为了缓解一下恶心的气氛,请允许我插入一个搞笑短文——————————

一位自杀者在他的遗书里讲述了他自杀的原因,听起来实在让人头痛。遗书这样写道:“我和一个寡妇结了婚,她有一个已成年的女儿,我父亲跟我妻子带过来的女儿结了婚。所以我父亲就成了我的女婿,女儿就成了我的后母,我管父亲叫爸爸,而我父亲也管我叫爸爸;我女儿管我叫爸爸,但我却管她叫妈妈;我还得管我妻子叫姥姥,因为她是我后母的母亲。不久我女儿,也就是我后母生了一个儿子,他是我同父异母的弟弟,他也得管我叫姥爷,因为他也是我的外孙。后来我妻子,也就是我姥姥生了一个儿子,他是我后母的弟弟,我是他的外甥,所以儿子管我叫爸爸,我管儿子叫舅舅。另外我是我妻子,也就是我姥姥的外孙,同时也是我姥姥的丈夫,所已我也是我的外祖父。又因为我妻子是我的外祖母,我的儿子,也就是我的舅舅是我的弟弟和我女儿的弟弟,所以我……我的天哪,这么复杂的关系实在让我伤透了脑筋,我只有一死才能得以解脱……”

————————————————————————插入完毕————————————————————

看完上面这个短文,不知道你是否和我一样,觉得这么一个简单的程序将是如此难做啊。另外,我决定在下一次的面试中让应聘者来设计Family Tree的程序

我又说多了,现在还是让我们回到技术上来。除了上面那几个观点,我在回复中还看到了如入一些有意思的回复:

  • “我的软件没有bug,是你的生活有bug”——让我想到了程序员惯用的借口
  • “算法中不应该加太多的限制,限制多了反而让算法不灵活。”
  • “移除断言,并不代表就不出错,对于这种rare case,我们最好给一个Warning提醒用户,让用户确认确实是这样的。”
  • “关于解决这个问题,移除那个断言,如果显示上会有问题的话,那就复制一下有不同关系的人就可以了”
  • “你真的应该想想你的软件的价值是什么?市场在哪里?你真的要照顾这样的用户吗?”

挺好的,相信你对软件开发又学到了一些东西。

(转载时请勿用于商业目的,并请注明作者和出处)