我的智商逐年递增 第250章

  “十万乘十万,那是一百亿个数据点,你算过这要占多大内存吗?服务器当场就得炸。”

  “楚戈。”

  陈拙在电话这头轻笑了一声。

  “你在现实里,有十万个朋友吗?”

  “没有,我连十个都没有。”

  楚戈老老实实地回答。

  “正常人都没有。”

  陈拙说。

  “所以,这个矩阵里百分之九十九点九九的值,都是0,这是一个极度稀疏的稀疏矩阵。”

  楚戈拿着笔的手指猛地一紧。

  “在内存里,你不需要存那一百亿个点,你只需要存那些是1的坐标就行了。”

  陈拙继续往下说。

  “这就是个简单的坐标映射,接下来,你想找好友的好友,也就是二度人脉,在数学上怎么表达?”

  楚戈的脑子转得飞快,那些大一学过,后来又被他忘得差不多的线性代数知识,突然像闪电一样劈开了他脑子里的混沌。

  “矩阵乘法。”

  楚戈脱口而出。

  “A乘以A,A的平方。”

  “对。”

  陈拙站起身,走到茶几倒了杯温水。

  “A的平方,矩阵里值不为零的地方,就是二度人脉,A的立方,就是三度人脉。”

  楚戈看着泡面盖子,圆珠笔在上面无意识地画着圈,呼吸变得急促起来。

  “但是矩阵相乘的计算量太大了,尤其是高阶乘法,CPU还是吃不消。”

  楚戈提出了最核心的问题。

  “那是你太贪心了,你想一次性算出所有人的关系网络。”

  陈拙喝了口水,润了润嗓子。

  “服务器不需要知道所有人认识谁,服务器只需要回答当前登录的那个用户的请求,所以,你不需要做矩阵和矩阵的乘法。”

  陈拙的声音变得有些轻,但在楚戈耳朵里却像是一声炸雷。

  “当前登录的用户,不是一个矩阵,他是一个向量。”

  陈拙给出了最后的解法。

  “一个只有他自己那个位置是1,其余全是0的向量,你拿这个一维向量,去乘那个稀疏矩阵,乘一次,得出他的直接好友向量,再拿结果去乘一次矩阵,得出二度好友。”

  陈拙顿了顿,补了一句。

  “向量乘稀疏矩阵,时间复杂度是O(N),就算他有一万度的人脉,计算机做这种一维数组的乘法,连一毫秒都用不了。”

  网吧里,楚戈嘴里的糖已经咬干净了。

  咬到了糖棍被硌了一下牙,他才猛地反应过来,一把将糖棍甩在地上。

  他的眼睛死死盯着面前那张沾着红油的泡面纸盖。

  上面写着两行有些凌乱的公式。

  困扰了京城那个初创团队整整半个月,被几个清华计算机系的高材生视为无解硬件瓶颈的数据库死锁问题。

  在这个十二岁男孩嘴里,被几句最基础的线性代数概念,直接降维打击成了碎渣。

  “我懂了。”

  楚戈的声音有些发抖。

  “抛弃数据库的关系查询,把所有的关系表抽出来,在内存里维护一个稀疏矩阵,所有的查询,全部在内存里做向量相乘,算出结果后,再拿用户ID去数据库里提头像和名字。”

  “对。”

  陈拙应了一声。

  “但是有个问题。”

  楚戈的程序员思维迅速抓住了漏洞。

  “A认识B,B认识C,C又认识A,这在图论里是个环,如果向量一直乘下去,会不会无限循环,把算力耗死?”

  “楚戈。”

  陈拙在电话那头叹了口气,语气里带着点无奈。

  “这是工程问题,不是数学证明题,向量乘出来的结果里,凡是数值大于0的,你顺手用个哈希表把ID记下来,下次乘的时候遇到已经记过的,直接跳过不就行了。”

  陈拙轻轻摇了摇头。

  “你是个写代码的,别指望数学公式连你拉屎用几格纸都算清楚,用点你程序员的常识好吗?”

  楚戈听着电话里那点调侃,突然咧开嘴乐了。

  “行,哥哥我承你这个情了,这回算我欠你的。”

  楚戈把那张泡面盖子折了两下,小心翼翼地塞进贴身的口袋里。

  “过完年回科大,我请你吃一个月的食堂小炒,先挂了,我得赶紧把这个底层的内存守护进程写出来。”

  没等陈拙说话,电话里传来了嘟嘟嘟的忙音。

  陈拙放下话筒,摇了摇头,嘴角带着一抹笑意。

  他转过身,走向厨房去拿碗筷,准备吃晚饭。

  ……

  距离泽阳市一千多公里外的京城。

  中关村附近的一栋破旧居民楼里。

  屋子里没开灯,只有三四台显示器散发着惨白的光,窗外偶尔闪过几道绚烂的烟花,照亮了满地的烟头和吃剩的外卖盒。

  汪兴裹着一件棉服,整个人窝在电脑椅里,双眼布满血丝,死死盯着屏幕上的后台日志。

  他们想在这个互联网的荒蛮时代,做一个真正意义上的实名制校园社交网站,点子是极好的,几个汪兴甚至已经靠着PPT拉到了一笔几十万的天使投资。

  但是技术瓶颈卡死了他们。

  明天就是大年初三,投资人要求看一个承载五百人同时在线的系统Demo。

  汪兴已经三天没合眼了。

  只要并发量一上来,好友的好友这个核心功能的数据库查询,就会像雪崩一样拖垮整个系统。

  屏幕右下角的MSN图标突然跳动了起来。

  汪兴布满血丝的眼睛动了一下,握着鼠标点开。

  是楚戈,那个远在徽州,被他拉来当免费技术外援的科大变态黑客。

  “老楚,别费劲了。”

  汪兴敲了一行字发过去,手指有些僵硬。

  “我们试了加缓存,试了建索引,没用,关系型数据库处理不了这种多级网状查询,硬件扛不住。”

  几秒钟后,楚戈发过来一个压缩包。

  只有不到20KB。

  紧接着,楚戈的消息弹了出来。

  “把你们之前的关系查询代码全删了,把这个C语言写的守护进程挂在服务器后台。”

  汪兴愣了一下。

  “这是什么?”

  “一个内存级别的稀疏矩阵相乘工具。”

  楚戈的回复很简单。

  “你只要把你们的关系表导出一份纯文本塞给它,以后所有的好友查询,不用过数据库,直接发指令给这个进程,它在内存里算完,把好友ID数组返回给你。”

  汪兴看着那段话,有些摸不着头脑。

  但他现在已经走投无路了,死马当活马医。

  他接收了文件,解压,把源代码拖进编译器,粗略地扫了一眼。

  这一看,汪兴的冷汗哗的一下就下来了。

  代码极其精简,没有任何数据库连接的库文件,全是底层的内存指针操作和几个他看不太懂的一维数组循环相乘。

  里面没有一条SQL语句。

  汪兴深吸了一口气,把编译好的执行文件挂到了测试服务器的后台,然后把几万条测试用的关系数据塞了进去。

  进程悄无声息地启动了,占用内存不到五十兆。

  “跑个压测。”

  汪兴转头,对旁边另一个已经困得东倒西歪的王惠文喊了一声。

  王惠文迷迷糊糊地揉了揉眼睛,在键盘上敲下了一行压测指令。

  “模拟五百个并发请求,三级好友深度查询。”

  王惠文敲完回车。

  “兴哥,准备重启服务器吧,估计还是三秒钟崩......”

  话还没说完,王惠文的声音卡在了喉咙里。

  压测工具的进度条并没有像之前那样死死卡住,而是以一种肉眼几乎无法捕捉的速度,瞬间刷满。

  满屏的绿色。

  汪兴猛地坐直了身体,椅子发出不堪重负的嘎吱声。

  他死死盯着压测结果的汇总数据。

  请求完成数:500。

  失败数:0。

  平均响应时间:3毫秒。

  汪兴觉得自己眼花了,他转头看了一眼服务器的系统资源监控。

  在刚才压测的一瞬间,CPU的使用率仅仅跳动了一下,到了8%,然后又迅速回落到了1%。

  服务器连风扇都没来得及加速转动,查询就已经结束了。

  屋子里安静得只能听到机箱微弱的蜂鸣声。

  “兴哥......”

  旁边的王惠文咽了口唾沫,指着屏幕的手都在抖。

  “这什么情况?数据库没转?”

  “没有过数据库。”

  汪兴的声音变得沙哑,他死死盯着刚才那段C代码,终于看明白了里面那可怕的数学逻辑。

  这不是在查数据。

  这是在内存里,直接对整个用户关系网进行数学维度的降维计算。

  汪兴的手指有些发麻,他切回MSN的聊天窗口,手速极快地敲字,甚至连打了好几个错别字都顾不上改。

  “老楚!这底层逻辑是谁写的?!”

  汪兴连续发了三个抖动窗口。

  “这他妈是纯粹的图论和高阶线性代数!直接把数据库的活儿抽给CPU内存做矢量计算了!”