十月的华清,银杏叶开始变黄。
苏念的大学生活进入了正轨——上课、写代码、开发”易转”平台,三点一线。
“易转”的开发进度比预期快。苏念负责后端和核心架构,方晓薇学得很快,已经能独立完成前端页面了,周雨桐负责数据库设计和测试。
三个人配合默契,像一个小型的开发团队。
但苏念发现了一个问题——”易转”的数据库查询速度太慢了。
随着测试数据量的增加,商品搜索功能的响应时间从零点几秒飙升到了三四秒。对于一个校园平台来说,这个速度勉强能用,但苏念的强迫症不允许她交付一个”勉强能用”的产品。
“是索引的问题。”苏念盯着数据库的查询志,皱着眉,”商品表的搜索字段没有建索引,每次查询都是全表扫描。”
“那建个索引不就行了?”方晓薇说。
“没那么简单。搜索功能涉及多个字段的模糊匹配——商品名称、描述、分类——单字段索引解决不了问题,需要全文索引。但MySQL的全文索引对中文支持很差。”
苏念揉了揉太阳。
这个问题她前世遇到过无数次。中文全文搜索一直是个老大难问题,直到后来有了Elasticsearch这类专业的搜索引擎才算彻底解决。但2006年,Elasticsearch还没出生呢。
她需要自己想办法。
苏念打开记事本,开始设计一个简易的中文分词+倒排索引方案。
思路很清晰:先把商品名称和描述进行中文分词,然后建立倒排索引表,搜索的时候先查倒排索引再回表查数据。
这个方案在2006年算是相当超前的——大多数网站还在用LIKE ‘%关键词%’这种暴力搜索。
苏念写了两个小时,把分词模块和倒排索引的核心代码写完了。但在测试的时候,她发现了一个棘手的bug——分词结果有重复,导致索引表膨胀,查询反而更慢了。
她盯着代码看了半个小时,没找到问题。
“我去图书馆查点资料。”苏念合上笔记本电脑,背起书包出了门。
——
图书馆三楼,计算机类书架区。
苏念找了一本关于信息检索的教材,坐在角落里翻看。
翻了十几页,她忽然感觉有人在看她。
抬头一看——顾衍坐在对面的桌子上,面前摊着一本厚厚的算法书,但眼睛却在偷偷看她这边。
四目相对。
顾衍像被电击了一样,猛地低下头,耳朵瞬间红透。
苏念忍住笑,站起来走了过去。
“顾衍。”
“嗯。”他的声音小得像蚊子。
“你在看什么书?”
“《算法导论》。”
“哪一章?”
“红黑树。”
苏念拉开椅子,在他对面坐下。顾衍的身体明显僵了一下,但没有躲开。
“我有个技术问题想请教你。”苏念开门见山。
顾衍抬起头,眼神里的紧张少了一些,多了一丝好奇。
技术问题,是他的舒适区。
苏念简单描述了”易转”平台的搜索性能问题,以及她设计的分词+倒排索引方案。
顾衍听完,沉默了十几秒。
然后他拿过苏念的笔记本,翻到一页空白处,开始画图。
他画了一个倒排索引的数据结构示意图,然后在旁边写了几行伪代码。
“你的分词结果有重复,是因为你没有对分词结果做去重和归一化。”他的声音很轻,但逻辑清晰,”比如’二手笔记本’和’笔记本电脑’,分词后都会产生’笔记本’这个词,但你的索引表里会存两条记录,指向不同的文档。查询的时候需要合并去重,你大概漏了这一步。”
苏念看着他画的图,恍然大悟。
对,她漏了查询结果的合并去重。
这个bug她盯了半个小时没找到,顾衍听了一遍描述就定位了。
“你说得对。”苏念由衷地说,”谢谢。”
顾衍的耳朵又红了:”不……不客气。”
他把笔记本推回去,低头继续看他的《算法导论》。
苏念没有立刻走,而是看了一眼他的书——书页上密密麻麻地写满了笔记,字迹工整但很小,像是怕被人看到一样。
“你的笔记写得很详细。”苏念说。
“嗯。”
“但你的代码从来不写注释。”
顾衍的手顿了一下。
“书是给自己看的,所以写笔记。代码是给机器跑的,所以不需要注释。”
苏念靠在椅背上,看着他。
“代码不只是给机器跑的。代码也是给人看的——给你的队友看,给未来的维护者看,给半年后忘了这段逻辑的你自己看。”
顾衍沉默了。
“你知道吗,有句话说’代码写出来是给人读的,只是顺便能被机器执行’。”苏念说,”你的代码逻辑很好,但可读性差。就像一本没有目录、没有章节标题的书——内容可能很精彩,但读者翻开就想合上。”
顾衍低着头,不说话。
苏念以为自己说重了,正想缓和一下气氛,顾衍忽然开口了。
“你说得对。”
他的声音很轻,但很认真。
“我以前觉得注释是多余的,因为我自己能看懂。但你说的’给别人看’……我没想过。”
他抬起头,看着苏念的眼睛——这是他们认识以来,顾衍第一次主动与她对视。
“我会改的。”
苏念愣了一下,然后笑了。
“好。我等着看你的注释。”
——
第二天,苏念打开”易转”的代码仓库,发现多了一次提交。
提交者:顾衍。
她不记得给过顾衍代码仓库的地址——大概是他自己找到的,”易转”的代码托管在学校的FTP服务器上,计算机系的学生都能访问。
苏念打开提交记录,看了看改动内容。
顾衍改了她的数据库查询模块。
原来的查询语句被替换成了一个优化过的版本,使用了子查询和临时表,查询速度提升了大约十倍。
而且——
每一行代码都有注释。
不是那种敷衍的”//查询数据库”式注释,而是详细解释了为什么要这样写、这样写的好处是什么、有什么潜在的风险。
苏念看着那些注释,愣了好一会儿。
然后她注意到,在代码的最后一行,有一条注释:
`
// 优化了查询性能,希望对你的有帮助。——顾衍
`
苏念盯着这行字看了十秒。
然后她笑了。
这个人,不会当面说”我想帮你”,但会默默地改你的代码,然后在注释里留一句话。
社恐的浪漫,大概就是这样的吧。
苏念打开编辑器,在顾衍的注释下面加了一行:
`
// 收到。查询速度确实快了很多。谢谢。另外,你的注释写得不错,继续保持。——苏念
`
保存,提交。
她靠在椅背上,看着屏幕,嘴角的弧度怎么都压不下去。
方晓薇凑过来看了一眼:”念念,你在笑什么?”
“没什么。”苏念关掉编辑器,”在看一段写得很好的注释。”
“注释有什么好笑的?”
“你不懂。”苏念站起来,伸了个懒腰,”有些注释,比情书还好看。”
方晓薇一脸问号。
苏念没有解释,拿起书包去上课了。
走在路上,她忍不住又想起了那行注释。
顾衍啊顾衍。
你用代码跟我说话,比你用嘴说话流畅多了。
不过没关系。
我看得懂代码。