今天是这个迭代的最后一周。本来这个迭代工作交付还是比较顺利的,除了个别几个联调的需求,大家都在收尾解bug了。

我最后一个bug是一个多语问题,有一个奇怪的情况是我配置了五百多个多语,但是只有其中一组,共5个多语有问题:其它文字在切换语言后都能换过来,只有这些文字还是中文。

可是这并不应该呀?因为我那么多多语,配置的时候都不是手动操作的,肯定是通过程序生成后批量导入的。出问题的这一组多语,无论是输入源——同一组元数据的描述,还是程序——被用来生产所有的多语key,其逻辑是相同的。

多语的key生成规则也很简单,就是产生一组类似A.B.C.{D}的key,其中的D来自元数据的描述。而且我从我导入的文件里找到有关的key,拿到多语平台里,也能找到到。这么奇怪的事情,我前后查了一个小时,做了多次尝试,仍然不得头脑。最后拉上元数据,多语平台的同事一起研究了一下午,大家都没有发现问题在哪里。

但是排查过程中有个奇怪的情况引起了我的注意。有一位同事尝试重新拼凑了问题的多语key,到多语平台里搜索,完全搜不到。嗯?我这里都是正常的啊,我把key发给其他同事,导入的文件也发给其他同事,大家都能搜到。应该是这个同事自己拼凑的时候打错了字母了吧?

但是恰好就是这段搜不到的key才让大家找到了真正的问题。有问题的同事将key发到群里,大家发现key跟多语平台里的key的字母完全一样。有经验的人应该立刻能发现问题了,那就是key里带有不可见的零宽字符。于是我们用getBytes分析,发现问题字符串里A.B.C.后多了三个字符,0xe2808d。这个字符在Unicode代码里是一个emoji符号,但是它表示的是零宽的连接符。什么意思呢?就是它显示的时候会将前后的emoji表情连起来,但是它单独出现的时候,是没有宽度的。比如,👨👩👦中间用这个零宽的字符间隔开,就是👨‍👩‍👦。其它emoji也可以用这个字符连接起来,但是效果并不像这三个头像那么神奇,可以合并成一个等宽的emoji表情(这个效果取决于大家设备对emoji的支持,至少在Windows11上效果比较好)。

这个连接符是怎么来的呢?原来是有人编辑文档的时候不小心粘贴进去了这个字符,并且由于它不可见,因此我写程序的时候也不慎粘贴到代码里,被生成了这一组有问题的key的生成。

最后编辑好文档,重新生成key导入,bug解决。一下午也就随着bug消失了。