忒修斯之船?这是什么东西?它和 “程序难做” 有什么关系? 我相信大多数人看到这个题目都会有以上的疑问。“程序难做” 很好理解,程序员往往都拼尽全力了在工作了,结果还是不让人满意,这事竟然是经常发生。很多人认为,问题出在程序员身上,他们听不懂人话,又不善于与人打交道。不过在我看来,“忒修斯之船” 才是程序难做的重要原因呢。 说起 “忒修斯之船”,这是个古老的哲学问题。 一艘在海上航行了几百年的船,被不间断地维修和替换部件。只要一块木板腐烂了,它就会被替换掉,以此类推,直到所有的功能部件都不是最开始的那些了。 问题是,最终产生的这艘船是否还是原来的那艘特修斯之船,还是一艘完全不同的船?如果不是原来的船,那么在什么时候它不再是原来的船了? 哲学家托马斯·霍布斯后来对此进来了延伸,如果用特修斯之船上取下来的老部件来重新建造一艘新的船,那么两艘船中哪艘才是真正的特修斯之船? 几百年来,哲学家们为这个 “同一性如何判断” 的问题争论不休,谁也没法彻底说服对方。 不过对普通人来说,终极意义上 “怎么分辨一艘船”,这样的问题应该留给哲学去讨论,在现实生活里,大家都不会迷糊。如果你看过《基督山伯爵》,会记得 “法老号” 货船重返马赛港的情节。大家都认为那就是 “法老号”,唯有对基督山伯爵(爱德蒙·唐泰斯)例外——当然,这并不妨碍其它所有人认为这还是 “法老号”,也不妨碍一切的一切按照 “这是法老号” 继续进行下去。 不过,如果你和程序员谈需求,就得小心了。“那艘船就是法老号”,这对你来说一定是显而易见无需论证的。但程序员一定要问:怎么认定 “那艘船” 呢?是看它的船长?还是船厂的编号?还是船上的某块木板?…… 你被问得烦了,随便想了想,船头的木板应该是不会替换的,于是说:对,就用船头这块木板来识别。 好,无数的悲剧就此发生了。 用注册时填写的用户名来识别用户,本来没问题,不巧用户一开始不注意,用户名里包含了手机号会泄露隐私,于是强烈要求更改用户名,结果改了之后之前属于这个客户的信息全都对不上了; 货品的 SKU(唯一标识)里包含了所在仓库的代号,本来没问题,结果生意做大了要求调仓,但是 SKU 和新的仓库代码起冲突,货物出了 A 仓库进不去 B 仓库; 具体的操作人员反馈问题,你去找程序员,他说 “你当时就是这么定的呀”,于是你跳起教来大喊:你就不会动动脑子吗?我说什么就是什么?你为什么不想想我说的到底是什么意思? 于是问题又绕回来,怎么在程序的世界里构建人的认知呢?普通人到底怎么认定 “这艘船” 就是 “那艘船” 呢?哪怕船上的木板都换了个遍,它竟然还是原来 “那艘船”?就好像表中的某一行,所有的字段都变了,它竟然还是 “原来那一行”? 推而广之。怎么认定 “一个人” 呢?靠名字显然不行,靠相貌也有问题(怕整容),身份证号同样不靠谱(改身份证号,一个人有多个身份证也不少见)……现在有了克隆技术,克隆出的人连 DNA 都一样,怎么分辨? 其实程序员是有办法的,就是用没有任何意义的文字来标识(比如自增 ID),在程序的世界里基于这些标识来构建联系。这些没有任何意义的文字标识,就是日常沟通中所说的 “那个”。依靠 “那个”,现实世界和程序世界就能对应上了,即便船上的每块木板都换了,数据库里这行记录的所有字段都变了,“那个” 还是不变的,普通人也正是这样认为的。程序员应该谨记:虽然 “那个” 是现实中说不清道不明的概念,但在程序的世界里,“那个” 不能缺少。 前段时间我和七牛云存储的道哥(李道兵)谈起软件开发中的各种问题,道哥说:血泪的教训,也是基础的规则,就是不要用任何有业务意义的字段来做 ID。这个 “没有任何意义的字段” 是什么?其实就是我们潜意识里 “那艘” 忒修斯之船。
编者按:很多人认为,程序难做的问题出在程序员身上。不过在作者看来,“忒修斯之船” 才是程序难做的重要原因。本文作者余晟,原文来自其个人微信公众号 余晟以为(ID: yurii-says)