去重。
“用布隆过滤器。”他说,“每个线程拿url之前先过一遍布隆过滤器,已经爬过的就跳过。布隆过滤器可以用redis的bitap实现,多个线程共享。误差率可以通过哈希函数个数和位数组大小控制,一般能接受千分之一的误判,少爬几个页面问题不大。”
本点了点头。但他没停。
“如果布隆过滤器误判漏了一个重要页面呢?”
陈哲这次真的停住了。
他沉默了两秒,然后开口,声音很平。
“用确定性去重做备份。布隆过滤器只是第一层过滤,漏掉的页面可以靠第二层校验,比如把url的哈希存在redis的set里,精确去重。但set的内存占用太大,所以可以用布隆过滤器做预筛选,set做兜底。”
本盯着他,又问:“那如果set也扛不住呢?”
陈哲的手指停住了。
他看着本的眼睛,沉默了三秒。
然后他叹了口气,声音里带着一点无奈,又好象只是很坦诚。
“这个我不知道了。”
他顿了顿,又说了一遍,语气更轻,象是自言自语。
“学艺不精。没做过这么大的量,没碰到过这种级别的瓶颈。”
本的目光在他脸上停了两秒,象是想确认什么。
桌上安静了片刻。
提米在旁边啧了一声,替陈哲解围:“本,你这题出得也太偏了。分布式爬虫的去重方案,那是架构师才需要考虑的问题。他一个刚入行的新人,能想到布隆过滤器加set兜底已经很不错了。”
全民超人点头:“就是。你问他gil、问线程池、问退避策略,这些还算正常。问到分布式去重,那已经超出普通开发的范围了。”
莱拉也帮腔:“我工作三年了,也没设计过这种量级的系统。平时业务里碰到这种须求,直接用现成的消息队列和分布式框架,谁会自己造轮子?”
本没说话,只是看着陈哲。
陈哲靠回椅背上,端起那杯凉透的咖啡,喝了一口。苦的。他的表情很坦然,象是一个真的不会的人。
“确实不会。”他又说了一遍,声音很稳,没有辩解的意思。
deaster—从桌子另一头站起来,走到这边,看了一眼白板上那行字。
他的眉毛挑了一下,然后看着陈哲,开口说:“你能想到布隆过滤器加set已经够了。我面试别人的时候,大多数人连布隆过滤器都说不清楚。分布式去重本身就是个系统工程问题,不是一两句话能说清的。”
本听到这句话,眉毛动了一下。
他看了看deaster—,又看了看陈哲,嘴角动了动,想说什么,但最后还是咽了回去。
“行。”他说,把白板翻过去,“这题算我出难了。
“7
他端起咖啡喝了一口,目光在陈哲身上停了一秒,然后移开。
陈哲嘴角微微上扬,隐去了最关键的一步。
那一步,是只有在公司上过班的程序员才能得知的一些职业写法,既然不应该出现在他这个大学生的身上,那他就不会说出口去。
聚会散场的时候,天已经暗下来了。
陈哲站在公园门口,看着那群人三三两两地消失在街角。麦克拍了拍他的肩膀,说了句“改天约酒”,然后往地铁站的方向走了。提米和莱拉凑在一起商量去哪儿吃饭,边走边争论哪家店的披萨正宗。全民超人一个人往河边走,耳机塞在耳朵里,步子很慢。书虫不知道什么时候已经走了,陈哲回头找他的时候,只看见一个黑色的背影消失在街角。
本最后走的。他站在野餐桌旁边,把那块白板收起来,塞进背包里。看见陈哲还站在门口,走过来,在他面前站定。
“你今天答得不错。”他说,“尤其是分布式去重那部分。能想到布隆过滤器加set
兜底,说明你确实有系统设计的意识。至于再往上,那是经验问题,急不来。”
陈哲点点头:“我知道。”
本盯着他看了两秒,目光从他脸上扫过,忽然问了一句:“你刚才说的那些线程池、退避策略、布隆过滤器都是自己在网上学的?”
“对。”陈哲说,“看书,看博客,看开源项目。”
本没说话,只是点了点头,转身往街边走。走了几步,又停下来,回头看着他。
“你那个youtube频道,”他说,“我看过了。”
陈哲的手指微微紧了一下。
“第六期那集文档操作讲得不错。”本说,语气很平,“付费视频我也买了。质量对得起价格。”
他顿了顿,目光在陈哲脸上停了一秒。
“继续做。别停。”
说完,他转身走了。
陈哲站在原地,看着他的背影消失在街角,然后转身往公交站走。
回到公寓的时候,杰姆尼正躺在沙发上看手机。电视开着,放的是某个他叫不上名字的cult血浆片,声音开得很小。他看见陈哲进来,把手机放下,从沙发上坐起来。
——
“回来了?今天的事怎么样?”
“还行。”陈哲把背包扔在沙发上,在另一边坐下。
杰姆尼盯着他看了两秒:“你看起来有点累。”
“有点。”
杰姆尼没再问,从茶几下面摸出两个哑铃,开始做弯举。他的动作比前几天标准了一点,但还是很生硬,每次举起来的时候肩膀都会不自觉地往上耸。陈哲在旁边看了一会儿,忽然开口:“肩膀放松。不要用惯性,用肌肉控制。”
杰姆尼愣了一下,调整了一下姿势。这次好了一点,但还是不太对。陈哲站起来,走到他旁边,伸手按了按他的肩膀:“沉下去。不要耸肩。肘关节夹在身体两侧,不要往外撇。”