你们相信这是十几年的程序员写的代码吗?!

2025 年 8 月 8 日
 honkew

最近遇到个事想和大家分享一下。 我们业务最近出了一个 bug

我这边通过同事的接口获取快递面单 pdf 具体流程是 [包裹号] -> [资源 ID ] -> [快递面单 pdf ]

也就是说: 拿着包裹号请求接口,拿到资源 ID 再用资源 ID 请求下载地址,获取 PDF

然后发现奇怪的事情,包裹 A 和 包裹 B 获取到的快递面单串了,下载下来是一样的单号 资源 ID res_id 是 32 位数,相同一秒获取到的 pdf 就是一样的,猜测是采用 md5(time()) 这种方式命名文件

然后和 同事 A 反馈了该问题,同事 A 反应已经修复 接下来一段时间还是出现这种问题会导致仓库发错货

老板问我咋回事,我又去查日志发现同一时间 res_id 还是会一样的,这次精度有所提升不是秒了,大概精确到后面两位的样子

然后和老板说了一下,是因为资源 id 还是一样的 这里他还改了一下运单文件在他服务器上的保存的命名方式,这个改动压根解决不了这个问题 然后同事 A 说他已经改了,没问题的,你不应该请求速度这么快 我直接整个大无语

然后开会 我说建议使用 sha1(运单号) 的方式生产资源 id ,或者使用 UUID ,还没有说完直接反驳 说不安全巴拉巴拉,不安全可以 accessToken 验证啊,外部访问不到不就可以了 然后又说改算法耗费服务器性能巴拉巴拉的,老板又好声好气的让他想办法改一下 最后他改了,改成 md5(microtime(true))

然后今天又又又出现这个 bug 了,老板又跑过来问我,我已经要疯了 这个问题前前后后几个月都没有弄好

同事 A 是那种反驳性型人格,而且比较自大那种,我快待不下去了

18462 次点击
所在节点    程序员
140 条回复
lifeintools
2025 年 8 月 8 日
@evan1 你简直是个天才
ben1iu
2025 年 8 月 8 日
这和工作十几年没关系 这可能是不到一年的经验 重复用了 十几年 实际有效经验一年都没有吧
DinnyXu
2025 年 8 月 8 日
我给你一个思路:首先你已经知道问题的根本原因了,你就要去做大量的验证,大量的测试和复现,因为大家都是干程序的,数据是不会骗人的,你也不用在那生气,也不用为这点小事烦心,为什么我说是小事,因为这些还远没有到勾心斗角的地步,一般这种狂的人你必须要用实际数据来说话,因为我以前也遇到过,我说他错了,他就是不信,我做了一些大量的数据反复验证,反复比对结果,一次给他整服气,以后好生给我说话
xloger
2025 年 8 月 8 日
@MuSeCanYang doge 我不会的东西就是不安全的
doyel
2025 年 8 月 8 日
照例说按以前服务器的并发能力,我直接经常 Timestamp 直接拼串用,只要再接个业务 id 或者其他什么标识,同一个业务 ID 被毫秒级请求到的可能性已经接近于 0 了

当然用 uuid 也可以,但是对于输出来说,之前的方法有先天的优势,文件名排序
lysShub
2025 年 8 月 8 日
@Mithril 他这问题不是原始数据相同了吗?要是原始数据不重复,这个问题基本永远不会被发现
unco020511
2025 年 8 月 8 日
uuid 即可
tianzhiya
2025 年 8 月 8 日
@DinnyXu 他都说了“没问题的,你不应该请求速度这么快”,验证出来后估计他也是这说法
polotou
2025 年 8 月 8 日
知道问题在他那 还找你 这才是问题 [老板又好声好气的让他想办法改一下 最后他改了] 难道是小舅子?
way2create
2025 年 8 月 8 日
按你说的这么离谱,这感觉已经不是单纯的技术能力问题了,纯属人脑子态度有问题,退一万步就算这个人初次使用的时候不会不懂没考虑到不在乎,那出问题但凡是个正常人也很快能修复。

虽然不是说什么都要用 uuid ,但也要考虑使用场景的,这 md5(time())明显不符合这种使用场景,而且重复了还会导致这样的后果是更逆天,太迷惑了
DinnyXu
2025 年 8 月 8 日
@tianzhiya 他说了没问题,那为什么老板还要找啊,2 边人对质一下,当面给他戳穿,如果他还要说没问题,那就在老板面前说清楚,如果再出现问题,就喊老板找他
DinnyXu
2025 年 8 月 8 日
@tianzhiya 对付无赖的人,拿出数据验证只是第一步,让更多人知道他是无赖,会打击他嚣张的心理,次数多了以后他的置信度就会降低,后面也不敢再过于狂妄
Dora112233
2025 年 8 月 8 日
又菜又犟
JKeita
2025 年 8 月 8 日
让你老板把他开了呗,还能怎么办,都造成公司损失了还不开
ryd994
2025 年 8 月 8 日
他在重新发明 UUID 。然后试图用伪•snowflake 算法来实现 UUID 。
这个场景用 UUID 没毛病。性能不是问题,你们一天也就这么点快递,远没有到 UUID 会碰撞的量。也没有单调递增的要求(何况 hash 时间戳也没有单调递增)

说完技术问题,再说行政问题。你没必要和他争。他的代码他负责没毛病。你要铁证如山摆在老板面前,而且留下书面证据,保证他的锅扣在他自己头上。剩下的就是你老板的问题了。公司不是你开的,有什么业务损失是公司的事,公司怪罪下来是你老板的事。反正没你什么事。你做好给你分配的事情就好了。
Greendays
2025 年 8 月 8 日
话说这种情况直接拿包裹号来做资源 ID 不就可以了?包裹号不会重复的吧?
sampeng
2025 年 8 月 8 日
尊重他人命运 放下助人情节。。你们相信这是一个工作 n 年人都没意识到的问题???

最多说 1 次,第二次爱改不改,又不是我写的代码。老板问就是代码不是我写的,问题没出我这。除非我是 leader 或者项目负责人,那是另一回事。
Geon97
2025 年 8 月 8 日
老板知道是他负责的不是你负责的,也给他建议了,不听就随便吧 反正和你没关系
ryd994
2025 年 8 月 8 日
@honkew #14 时间戳比随机数省性能。对超高性能的系统来说,用时间戳没毛病。但是他这是邯郸学步,因为:
1. 我上面说过了,你们这点并发度还没到需要这个的程度。
2. 高性能时间戳也不是用 clock time 。读 clock time 同样非常耗性能,因为 syscall 至少需要一次上下文切换。高性能时间戳用的是 CPU 内部计数器 TSC 。这是一个从开机开始计算的单调递增数字,和现实时刻没有对应关系,只保证时长正确。
3. md5 的性能开销就更加没边了,和伪随机数比还指不定哪个快一点。random 函数用的是系统默认随机数源,拿到的是参杂真随机熵的伪随机数。对于外部系统来说足够安全了。而且现代 CPU 还自带熵源,也会被掺杂进去。总的来说是足够随机了。
真随机源也有,但是除了密码学应用,一般的情况不需要。
Maiiiiii
2025 年 8 月 8 日
@lixining #28 同一个 ts 的并发请求就重复了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/1150932

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX