一个假空格引发的惨案

2018-12-24

面试时不是有一个常问的问题是“你解决过什么比较难的bug”吗,或者是“有没有什么让你印象深刻的bug”。说实话这么多年了自己感觉是解决了一些棘手的bug, 但是真要一段时间之后想再提起来并给别人讲明白,还真不是那么容易。

原因嘛

  1. 坦白说很多后来解决的bug最后证明并不是多么高精尖,不太值得一提,提出来反倒会让面试官觉得小题大做

  2. 时间过去太久了,解决了就解决了,不一会儿就投入到新的bug中了,老bug除非再次遇到,不然还真一下子想不起来

第一点其实也不完全对,因为很多时候事实证明解决方法并不复杂,甚至是程序员自己犯了低级错误,不过查找错误的过程以及排查的思维路径却很重要, 正确的分析思路也是非常值得一提的。 就像那个流传甚广的故事:

打一个孔只收你一块钱,告诉你在哪里打孔收你1万块钱

第二点嘛,反正自己记性越来越差了,还是老实点写下来吧,权当是个总结,练习下语言组织能力。

Postman里面是好的,但是线上环境却报错

今天就遇到一个非常诡异的案例:同样的接口,同样的参数,在postman里都是正常工作,但是在线上环境里却死活报错。

原因可以初步确定是两种请求之间有细微的差别,但是

  • 肉眼看瞎了也看不出什么区别
  • 把整个请求保存成text放在diff的工具里对比也对比不出什么不同
  • 甚至把可疑的请求参数都从线上拷贝了一份到postman里

依然在postman里无法重现。到底是哪里造成了这种不同呢?

没办法,只能老老实实在后台接口的代码里给每一步可疑的地方加日志,部署,再看。

终于发现:

Bearer eyJhbGciOiJkaXIiLCJlbmMi

后台收到上面的字符串后split空格,然后居然得到数组size是1!就是说那个看似的空格其实并不是空格。

OK, 不是空格那它是什么呢?把上面有问题的这段string拷贝到postman里再试,好的,Ctrl+C还是不会搞小动作的,问题重现了。问题的来源就是在这段字符串里。

那么把这串字符的unicode code point打印出来:

image

好了,那个“空格”是一个假空格,代码是160而不是32,它显示成空格只是找不到对应的字符而已。(唉,那个假空格不是我传的呀,给别人擦屁股了)

结论

  1. 直接引用定义好的常量更好,手动输入总会难免出错

  2. 平时可以写一些debug级别的日志在代码里面,查错的时候直接打开debug级别就行了,省得急忙临时再添加一遍


-----本文采用创作共用版权 CC BY-NC-ND/2.5/CN 许可协议,转载请注明出处。

本博评论系统由Disqus提供