1942年,几名统计学家走进盟军情报部门的会议室,把一叠序号记录拍在桌上。他们不看间谍报告,不听截获的无线电,只做了一件事:数数。数的是从战场上缴获或击毁的德国坦克上铭刻的序列号。这些号码整齐划一地打在了变速箱、底盘、负重轮上——德国人的工程强迫症,意外变成了一封情报信。
盟军当时的估算方式听着靠谱:安插间谍、拦截通信、加上经验丰富的推测。推出来的数字是每月大约生产1500辆坦克。但统计学家的算术推翻了整个判断。他们观察到,在缴获的坦克中,看到的最高序列号是m,总共看到了k辆。他们给出的总产量估算值是一个简洁到近乎狡猾的公式:N ≈ m + (m / k) − 1。
直觉是这样工作的:你手上最大的那个数字,告诉你已经摸到了多靠近天花板;而你手上总共有多少个数字,告诉你这个“靠近”有多可信。序列号之间的空缺,正好替你估算出那些还没见过的坦克。这就像只翻了几页书,就能猜出整本书的页码——只要页码是连续印上去的。
1942年的某个具体月份里,间谍给出的数字是1500辆上下,统计学家只靠缴获序列号和这个公式,给出的答案是327辆。战后德国生产记录被找到,真实的月产量是342。间谍错了一千多辆,这群做算术的错了15辆。换句话说,连续号码本身就会泄露规模,所有看到过一小段序列号的人,都有能力反推出整体存量。
这个教训被刻进情报工作的底层逻辑:顺序编号就是天线,向外广播着你的数量。我每次看到类似 /users/1042 的网址,脑子里自动跳出来的就是那些坦克的齿轮箱编号。
把地图从二战挪到今天的后端开发,几乎每个数据库都在兢兢业业地扮演德国装甲师的角色。你创建一个PostgreSQL 表,主键用 serial 自增整数,因为那是默认选项,排序好看,用着顺手。用户1是你,2是你的联合创始人,3是你妈妈,一切完美。然后你搭建了个人主页,路由就是 /users/3。上线。从这一刻起,你同时也上线了一台序列号发报机。
竞争对手、无聊的青少年、记者,任何有个浏览器的人,都可以像当年的统计学家一样操作。今天注册一个账号,拿到 ID 等于 4317;等一周,换一个邮箱再注册,拿到 ID 等于 4981。做一次减法:4981 减去 4317,就是你这周的注册量——664个新用户。对方没有入侵任何系统,没有破解任何接口,只是读了你随手摊在URL里的序列号。你的增长数据被读走了,就像盟军读走坦克齿轮箱上的编号一样安静。
这就是“德国坦克问题”在现代互联网的投影。自增ID不只是个技术习惯,更是一个默认开启的信息广播频道。它把用户量、业务增速、甚至某些活动的参与人数,都打包成精心排列的数字,发给每一个愿意做算术的人。UUID 不是过度设计,而是关掉这条旧情报频道的开关。
热门跟贴