1168 words
6 minutes
我花了三天时间排查一个Bug,结果发现是键盘坏了

这是一篇关于过度自信的故事。我以为自己是高级程序员,结果输给了20块钱的键盘。

问题出现#

上周,我在重构一个老项目。

代码逻辑很简单:用户输入密码,系统验证,返回结果。

但我遇到了一个诡异的问题:

输入正确的密码,提示”密码错误”。

第一轮排查:代码逻辑#

第一反应:我的验证逻辑写错了。

检查了半小时:

  • 密码哈希算法正确
  • 盐值正确
  • 数据库查询正确
  • 字符串比较用了equals,没有用==

看起来都没问题。

添加日志,打印输入的密码和数据库的密码:

logger.info("输入: {}", inputPassword);
logger.info("数据库: {}", dbPassword);
logger.info("是否相等: {}", inputPassword.equals(dbPassword));

日志输出:

输入: mypassword123
数据库: mypassword123
是否相等: false

???

明明一样,为什么equals返回false?

第二轮排查:字符编码#

怀疑是编码问题,有隐藏字符。

检查字符串长度:

logger.info("输入长度: {}", inputPassword.length());
logger.info("数据库长度: {}", dbPassword.length());

输出:都是13。

转成byte看:

logger.info("输入bytes: {}", Arrays.toString(inputPassword.getBytes()));
logger.info("数据库bytes: {}", Arrays.toString(dbPassword.getBytes()));

仔细对比,发现第4个byte不一样:

  • 输入:109, 121, 112, 97, ... (a是97)
  • 数据库:109, 121, 112, 64, ... (@是64)

等等,我输入的是mypassword123,第四个字符是a,怎么变成@了?

第三轮排查:键盘问题#

我突然意识到:可能是我键盘的问题。

打开记事本,按下”a”键——输出”@”

按下”s”键——输出”#”

按下”d”键——输出”$”

…我的键盘Shift键卡住了。

真相大白#

Shift键一直处于按下状态,所以我输入的所有小写字母都变成了对应的上档符号:

  • a → @
  • s → #
  • d → $

我以为我输入的是mypassword123,实际上输入的是myP@$$word!23(虽然键盘映射不完全准确,但确实是乱码)。

自我怀疑的三小时#

发现真相后,我坐在椅子上发了三小时呆。

不是因为解决了问题而开心,而是对自己产生深深的怀疑:

为什么花了三天才发现?

错误一:过度相信代码#

我默认”代码没问题,问题一定在别的地方”。

但实际上,我应该先验证输入是否真的如我预期。

错误二:复杂化问题#

我查了:

  • 字符编码(UTF-8、GBK)
  • 哈希算法实现
  • JVM字符串常量池
  • 数据库字符集

就是没查最简单的:键盘是否正常。

错误三:忽视常识#

当”a”变成”@“时,我应该立即想到Shift键。

但因为过于专注代码,忽视了物理世界的常识。

同事的反应#

我把这个故事讲给同事听。

A:“哈哈哈哈哈”

B:“我也遇到过类似的事,最后发现是键盘布局变成了法语”

C:“排查三天算好的,我有一次查了一周,最后发现是显示器线松了”

D:“这叫’过度调试’,程序员职业病”

经验教训#

1. 验证输入#

在排查复杂问题前,先确认基础:

  • 输入真的是你想象的那样吗?
  • 输出真的是你看到的那样吗?
  • 最简单的情况排除了吗?

2. 从简单到复杂#

排查顺序应该是:

  1. 硬件/物理层(键盘、网线、显示器)
  2. 环境层(配置、权限、依赖版本)
  3. 代码层(逻辑、算法)

我反着来了,所以浪费了时间。

3. 保持常识#

不要因为写代码而脱离现实世界。

  • 程序不运行?看看电脑有没有开机
  • 网页打不开?看看网线插没插
  • 输入不对?看看键盘是不是坏了

这些听起来很蠢,但真的会发生。

4. 接受自己会犯蠢#

每个程序员都有过”低级错误”的经历:

  • 花半天找Bug,发现是少了个分号
  • 调三天性能,发现代码没部署
  • 查一周内存泄漏,发现是日志打印太多

这不是能力问题,是人就会犯错。

重要的是,从这些经历中学习,建立更系统的排查思路。

后续#

我换了个键盘,200块的机械键盘。

不是因为20块的键盘不好用,而是想给自己一个教训:

不要让你的工具成为你的瓶颈。

另外,我在工位贴了一张便利贴:

“遇到问题,先检查最简单的情况。”

以及:

“你没那么聪明,也没那么蠢。”


如果你也有类似经历,欢迎分享。我们一起在低级错误中成长。