第二十三章 論道

投票推薦 加入書籤 小說報錯

  陳哲跟著站起來,目光掃過那群人。

  走在最前面的是一個三十多歲的白人男性,個子不高,穿一件洗得發白的藍色衛衣,頭髮有點長,扎了個小揪在腦後。他手裡拿著一個保溫杯,杯身上印著紐約的logo,邊緣的漆已經磕掉了好幾塊。

  「麥克!」那人走近,伸出手和麥克擊了個掌,「好久不見。」

  「群主。」麥克笑著指了指旁邊的陳哲,「這是陳,新來的,我拉進群的。」

  群主的目光落在陳哲身上,從上到下掃了一眼,然後伸出手。

  「歡迎。叫我本就行。群主是大家開玩笑叫的。」

  陳哲握住他的手。本的手掌很厚,指腹有繭,不知道是敲鍵盤留下的還是別的什麼。

  「陳哲。」

  「中國人?」本問。

  「對。」

  本點點頭,沒再多問。他轉身朝後面那群人招了招手:「都過來吧,找個地方坐。」

  一群人往長椅那邊移動,有人坐下,有人靠在欄杆上,有人乾脆坐在草坪上。陳哲粗略數了數,加上他和麥克,一共十二個人。

  本清了清嗓子。

  「今天叫大家出來,沒什么正事,」他說,「就是最近群里太安靜了,想讓大家見見面,聊聊天。都是幹這行的,平時對著屏幕,也該出來透透氣。」

  有人笑了一聲。

  本從口袋裡掏出一個筆記本,翻了翻。

  「先介紹一下自己吧。從我開始。本,做YouTube的,頻道叫『碼農日記』,主要講後端和資料庫。幹了五年,還在干。」

  他把筆記本遞給旁邊的人。

  那是個非裔女生,二十多歲,厚嘴唇,戴一副圓框眼鏡,扎著馬尾。她接過筆記本,看了一眼,然後抬起頭。

  「萊拉,群里的『愛來自冒險家協會』,是一家遊戲公司的程式設計師。」

  隨後是一個重度近視鏡的華人男子,淡淡地說:「書蟲。」

  此外均是一群美國白人。

  陳哲的目光也在這群拘謹的成年社畜之間游移。

  美國高級程式設計師中黃種人和白種人的數量大約各占一半,但是在目前這種低端局裡,白人還是占了巨大優勢的,畢竟是本土主要民族。

  陳哲看向群組暱稱為書蟲的華人男子,而對方的眼鏡上起著霧,也看不清對方的表情。

  現場除了自己和對方,還有那個叫萊拉的黑人女生以外,其他人的手裡都拿著一部高端牌子的筆記本電腦,諸如MacBook Pro、戴爾、ROG、Razer、LG gram系列。

  陳哲不動聲色地抖了抖自己的背包,裡面那台老式的二手ThinkPad聯想,看上去倒是和這些人有點格格不入了。

  不過好在陳哲擁有Lv2的計算機技術。

  筆記本繼續傳。

  「湯姆,後端,主要寫Go。」

  「莎拉,前端,目前在自由職業。」

  「戴夫,DevOps,最近在搞K8s。」

  ……

  不久,十二個人介紹完,本拍了拍手。

  「行,都認識了。接下來自由活動,想聊技術的聊技術,想聊八卦的聊八卦。十二點的時候我請大家喝咖啡,樓下有家店不錯。」

  本說。

  人群散開,三三兩兩地聚成幾堆。

  陳哲站在原地,目光掃過四周。陽光已經徹底升起來了,河面上的碎金晃得人眼睛發酸。遠處有幾隻海鷗在盤旋,叫聲尖銳,像是在爭奪什麼。

  他注意到那個叫書蟲的華人男子獨自站在欄杆邊,背對著人群,望著河面。眼鏡上的霧氣已經散了,但他沒有要加入任何一個小團體的意思。

  陳哲想了想,沒有走過去。

  「陳,對吧?」

  一個聲音從旁邊傳來。

  陳哲轉頭,看見那個叫湯姆的白人男生走過來,手裡拿著一台MacBook Pro,屏幕還亮著。

  「對。」

  陳哲整理了一下自己的襯衣,說。


  湯姆點了點頭,在他旁邊的欄杆上靠下來。

  「我也是社區大學出來的,」他說,「皇后區的拉瓜迪亞社區學院。轉了學,最後在紐約城市大學畢的業。」

  他頓了頓,笑了笑。

  「這條路走得通,就是慢一點。」

  陳哲沒說話。

  開盒!

  陳哲從來沒有透露過自己的身份,但是遇到有心之人,就是直接開了。

  「改天得消除一下行蹤了……」

  陳哲眸光深思,對於程式設計師來說,想要套取到他人的信息是一件容易事。就算是那些專精於網際網路人肉搜索的青少年,在這方面愛好也敵不過興趣。

  就在這時,湯姆的聲音又傳來。

  「你現在寫什麼語言?」

  「Python。」陳哲答。

  湯姆頷首,目光落在河面上。

  「Python挺好入門的,」他說,「不過後端的話,遲早得學Go或者Java。看你以後想走什麼方向。」

  陳哲剛要開口,身後傳來本的拍手聲。

  「都過來一下!」

  人群重新聚攏。本站在中間,手裡不知從哪掏出一塊白板,大概A3紙大小,上面貼著一張紙,紙上寫著一行字。

  陳哲走近了才看清那行字是什麼。

  「設計一個URL短連結服務」

  本把白板舉高了點,讓所有人都能看見。

  「來,玩個遊戲。」他說,語氣裡帶著一點興奮,「這玩意兒大家都不陌生吧?短連結服務,Bitly那種。給你一個長URL,生成一個短碼,訪問短碼的時候重定向到原地址。」

  他頓了頓,目光掃過人群。

  「規則很簡單:每個人三分鐘時間,想一下怎麼設計。可以討論,也可以自己想。三分鐘之後,每個人輪流說自己的思路。」

  有人笑了一聲:「面試來了。」

  本也笑了:「面試?沒意思。這是遊戲,隨便聊。誰說得有意思,我請他喝咖啡——不是樓下那種,是正經的第三波咖啡。」

  「更何況,這種事我們之前的聚會也做過,不是嗎?」本嘴角上揚。

  人群里響起幾聲口哨。

  陳哲站在原地,目光落在那行字上。

  URL短連結服務。

  簡單來說,URL短連結服務就是一種將冗長的網址(URL)轉換為簡短地址的工具。當用戶點擊短連結時,會被自動重定向到原始的長網址。

  這東西他見過,用過,但從來沒想過怎麼設計。

  三分鐘。

  他開始想。

  ……

  最開始想到的是最簡單的,一個資料庫表,兩個欄位,長URL和短碼。用戶提交長URL,生成一個隨機字符串,存進去。訪問的時候查一下,重定向。

  但這樣太簡單了。隨機字符串碰撞怎麼辦?重複的URL要不要復用同一個短碼?訪問量大的時候資料庫扛得住嗎?

  過了半分鐘,他想到了哈希。把長URL用MD5或者SHA256哈希一下,取前幾位作為短碼。但哈希衝突怎麼辦?再加個鹽?還是用布隆過濾器先判斷一下?

  隨後,陳哲想到了緩存。

  高頻訪問的短碼可以放Redis里,不用每次都查資料庫。但緩存失效怎麼辦?緩存雪崩怎麼辦?

  再接著,他想到了分布式。如果服務做大了,單機扛不住,得用分布式ID生成器。雪花算法?還是用資料庫自增ID然後取模?

  一分鐘,他想到了更多。

  短碼過期怎麼辦?自定義短碼怎麼支持?統計點擊量怎麼實現?防攻擊怎麼搞?

  ……

  三分鐘到。

  本的拍手聲把陳哲從思考里拉出來。

  「行,時間到。」本說,「誰先來?」

  人群安靜了一秒。

  「我來吧。」

  說話的是湯姆。他往前站了一步,清了清嗓子。


  「最簡單的設計:一張表,id自增,長URL欄位,短碼欄位。短碼可以用id的62進位表示,0-9a-zA-Z,一共62個字符。id從100000開始,保證至少六位短碼。」

  他頓了頓。

  「優點是簡單,不會衝突。缺點是自增id容易被遍歷,可以加個隨機偏移量。訪問量大的時候加緩存,Redis存熱點數據。如果要做大,分庫分表,按短碼哈希分片。」

  他的語氣中充斥著自信,毫無疑問這是個比較優越的答卷。

  本點了點頭,沒評價。

  「下一個。」

  萊拉站出來。

  「我會用哈希。長URL做MD5,取前六位。如果衝突了,加個鹽重新哈希,或者用布穀鳥哈希的思路。優點是短碼隨機,不容易被猜。缺點是要處理衝突,性能稍微差點。」

  本還是點了點頭。

  「下一個。」

  接下來幾個人輪流發言,思路都大同小異——資料庫、哈希、緩存、分片。有人提到了用NoSQL,有人提到了用消息隊列做異步統計,有人提到了用CDN加速。

  陳哲一直不語。

  本的視線最後落在他身上。

  「陳,你呢?」

  所有人的目光都轉過來。

  陳哲沉默了兩秒。

  「我想到的跟大家不太一樣。」他說。

  本的眉毛挑了一下。

  「你可以說來聽聽。」

  陳哲往前走了一步,站在白板旁邊。

  「大家說的都是存儲和查詢的邏輯,我換個角度——成本。」

  他頓了頓。

  「短連結服務最燒錢的是什麼?不是伺服器,不是資料庫,是流量。每次訪問都要302重定向,每次重定向都是一次HTTP請求。如果服務做大了,每天幾億次訪問,光是流量錢就能燒破產。」

  人群安靜下來。

  「所以我會在重定向之前加一層CDN。」陳哲繼續說,「短碼的訪問路徑先走CDN,如果CDN有緩存,直接返回重定向響應,不回源。緩存時間可以設長一點,比如24小時。這樣99%的流量都被CDN扛住了,源站只需要處理緩存未命中的請求。」

  本的眉頭微皺。

  陳哲繼續。

  「然後是短碼生成。大家說的哈希和自增id都有問題——哈希有衝突,自增id太規律。我會用預生成的方式:啟動一個服務,提前生成一批短碼放在隊列里。用戶來的時候,直接從隊列里取一個分配出去。」

  「這樣生成短碼和分配短碼解耦了。生成服務可以用雪花算法保證全局唯一,分配服務只需要從隊列里pop。就算分配服務掛了,隊列里的短碼還能頂一陣……」

  「然後是資料庫。短碼和長URL的映射關係可以存MySQL,但高頻訪問的短碼要放Redis。如果要做大,可以按短碼前綴分片,比如0開頭的放一組,1開頭的放另一組。」

  「最後是監控。每個短碼的訪問量要統計,但不能影響主流程。可以用消息隊列,異步寫日誌,然後離線分析。」

  他說完了。

  人群安靜了幾秒。

  本盯著他,表情有點奇怪。

  麥克站在人群後面,手裡的咖啡杯停在半空中,眼睛瞪得比剛才大了一圈。

  「你……」麥克張了張嘴,像是想說什麼,但又咽了回去。

  湯姆第一個開口。

  「CDN那層,」他皺著眉,「重定向響應能緩存嗎?」

  「能。」陳哲說,「302重定向也是HTTP響應,只要設置Cache-Control頭,CDN就會緩存。用戶訪問短碼的時候,CDN直接返回302,連源站都不碰。」

  湯姆沉默了兩秒,然後點了點頭。

  萊拉在旁邊喃喃自語:「預生成隊列……這個思路倒是第一次聽說。」

  本的眉頭舒展開來。

  他盯著陳哲看了幾秒,然後笑了。

  「有意思。」


  他把白板放下,拿起保溫杯喝了一口。

  「你在哪家公司實習過?」

  「沒實習過。」陳哲說。

  本愣了一下。

  「那你在哪幹過?」

  「無可奉告。」

  本的表情有點微妙。他把保溫杯放下,目光在陳哲身上轉了一圈,最後落在那台老舊的ThinkPad上。

  沉默了兩秒。

  「行。」本說,「我記住了。」

  他沒再多說什麼,轉身朝人群揮了揮手:「走吧,喝咖啡去。樓下那家店不錯,我請。」

  人群開始往出口移動。有人還在小聲討論剛才那個設計,有人已經開始聊別的話題。

  陳哲站在原地,沒動。

  麥克走過來,在他旁邊站定。

  「小子,你……」麥克的聲音壓得很低,「你從哪學的這些?」

  陳哲看了他一眼。

  「網上。」

  麥克盯著他看了幾秒,然後搖了搖頭。

  「我拉你進群的時候還以為你是個萌新,」他低聲說,「結果你他媽是個扮豬吃老虎的。」

  陳哲沒說話。

  麥克拍了拍他的肩膀。

  「走吧,喝咖啡去。」

  ……

  Pier 57樓下有一家叫「Blue Bottle」的咖啡店,藍白相間的招牌,門口排著七八個人。本帶著一群人走過去,直接推門進了店裡——他顯然是熟客,店員看見他,點了點頭,指了指角落裡的幾張空桌子。

  十幾個人分散坐下。本去櫃檯點單,回來的時候手裡拿著一沓小票,一張一張分給在座的人。

  「自己點的自己拿。」他說。

  陳哲拿到的是美式,黑咖啡,不加糖不加奶。他端起來喝了一口,苦的,但能接受。

  萊拉坐在他旁邊,手裡拿的是一杯拿鐵,奶泡上面畫著一顆心。她盯著那顆心看了兩秒,然後用勺背把它攪散了。

  「Hello?陳哲。你那個設計,」她忽然開口,「預生成隊列那個思路,是從哪學的?」

  陳哲轉頭看她,思索了一會兒:「學校競賽。」

  萊拉沉默了兩秒,然後點點頭,沒再追問。

  對面坐著書蟲。

  那個華人男子從剛才開始就一直沒說話,只是坐在角落裡,面前放著一杯冷萃,冰塊已經化了一半,他沒動。他的眼鏡片上又起了霧,不知道是咖啡的熱氣還是別的什麼。

  陳哲的目光落在他身上。

  書蟲似乎感覺到了什麼,抬起頭。

  兩個人的目光在空中碰了一下。

  書蟲沒說話,低下頭,繼續盯著那杯冷萃。

  陳哲收回目光。

  本端著一杯拿鐵走過來,在陳哲旁邊坐下。

  「你那個設計,」他說,語氣比剛才輕鬆了一點,「說實話,有點出乎我意料。」

  陳哲沒說話。

  「CDN那層,」本繼續說,「一般新人想不到。預生成隊列那個,更不是新手能想到的。」

  他頓了頓,喝了一口咖啡。

  「你真沒實習過?」

  「沒。」

  本盯著他看了幾秒,然後笑了。

  「行,我不問了。」

  他站起來,朝其他人揮了揮手。

  「一點鐘我還得去剪視頻,先走了。你們聊。」

  他走了。

  人群漸漸散開。有人起身去櫃檯續杯,有人走到門外抽菸,有人湊在一起聊技術。陳哲坐在原位,盯著杯子裡黑乎乎的液體,腦子裡不知道在想什麼。

  麥克走過來,在他旁邊坐下。

  「感覺怎麼樣?」

  陳哲想了想。

  「還行。」

  麥克笑了笑。

  「本那人對新人一般不怎麼上心,」他說,「但他剛才多看了你幾眼。這是好事。」


  陳哲點點頭,沒說話。

  窗外,陽光照在哈德遜河上,波光粼粼。一艘卡其色觀光船慢悠悠地駛過,船上的人很小,看不清在幹什麼。

  「下午有什麼安排?」麥克問。

  「回去。」陳哲說,「寫代碼。」

  麥克點點頭,站起來。

  「行,那我也不留你了。群里聊。」

  他拍了拍陳哲的肩膀,轉身走了。

  陳哲抿了一口咖啡,這咖啡是藍瓶咖啡的一類,以精品單一產地咖啡豆和新鮮烘焙著稱。

  陳哲實際上回去是不可能寫代碼的。

  畢竟他其實根本不是程式設計師。

  他倒也沒有在這裡留多久,二手ThinkPad放在背包里沒拿出來過,回頭換乘了幾次紐約地鐵,就回了布魯克林區。

章節目錄