佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > 全球最大問答社區(qū)網(wǎng)站Quora開發(fā)的主要技術(shù)與經(jīng)驗(yàn)

全球最大問答社區(qū)網(wǎng)站Quora開發(fā)的主要技術(shù)與經(jīng)驗(yàn)

熱門標(biāo)簽:百度競價(jià)排名 網(wǎng)站排名優(yōu)化 呼叫中心市場需求 AI電銷 地方門戶網(wǎng)站 Linux服務(wù)器 服務(wù)外包 鐵路電話系統(tǒng)

首先來看一下Quora網(wǎng)站開發(fā)主要利用到的技術(shù):

Web層與CMS

HAProxy作為前端負(fù)載均衡服務(wù)器,反向代理服務(wù)器是Nginx,Nginx后面則是Pylons(Pylons + Paste),承擔(dān)動態(tài)Web請求。

Webnode2與LiveNode這兩個(gè)內(nèi)部系統(tǒng)承擔(dān)創(chuàng)建、管理內(nèi)容的重任,Webnode2生成HTML、CSS與JavaScript,并且與LiveNode輕度耦合。LiveNode的作用用以顯示W(wǎng)eb頁面內(nèi)容。用Python、C++與JavaScript寫的。特別提到用到了jQuery與Cython。LiveNode有可能開源。

為什么用Python?

前面已經(jīng)提到了一些Python相關(guān)的技術(shù)組件。有意思的是從Facebook出來的團(tuán)隊(duì)居然用Python作為主要開發(fā)語言。Quora對此有所解釋:Facebook選擇PHP也并非是最佳選擇,而是有歷史原因。Quora技術(shù)團(tuán)隊(duì)在考察了多個(gè)語言之后選擇的Python,當(dāng)然理由有一大堆,總體看來,并非很激進(jìn)。

通信處理

后端通信使用的是Facebook開源出來的Thrift,除了開發(fā)接口簡單之外,可能更為熟悉也是一個(gè)因素吧:)Comet服務(wù)器使用的是Tornado,用以處理Long polling以及Push 更新(不知道知乎用的什么?),Tornado是前FriendFeed技術(shù)團(tuán)隊(duì)開源的產(chǎn)品。

實(shí)時(shí)搜索

因?yàn)镾phinx不能滿足實(shí)時(shí)性方面的要求,Quora啟用了自己開發(fā)的搜索引擎,只使用了Thrift與Python Unicode庫,此外沒有用別的。Quora的搜索比較特別,因?yàn)橐獙斎雰?nèi)容做關(guān)聯(lián)并且要做有效提示,所以需要提供更好的前綴索引(Prefix indexing)功能。

Quora搜索的實(shí)現(xiàn)還是挺有技術(shù)含量的,對后端的查詢請求壓力也不小(或許當(dāng)前的并發(fā)請求量還沒那么大)。對這個(gè)場景,做相關(guān)開發(fā)的朋友不妨仔細(xì)研究一下。如果大體框架類似,那么決定最后生出的因素很可能是那些細(xì)節(jié)。

數(shù)據(jù)持久層

大量使用MySQL作為存儲方案,Memcached作Cache層。沒有使用當(dāng)前比較火爆的NoSQL相關(guān)產(chǎn)品。Quora這樣做有自己的理由,用戶量級沒有達(dá)到百萬的SNS站點(diǎn)完全沒必要用NoSQL的東西?;蛟S以后Quora也會啟用。

創(chuàng)始人查理·奇弗(Charlie Cheever)與亞當(dāng)·德安杰洛(Adam D'Angelo)之前都在Facebook,所以,Quora的技術(shù)還真有不少Facebook的基因。Quora的團(tuán)隊(duì)規(guī)模并不大,做技術(shù)的估計(jì)十余人而已,這么緊湊的團(tuán)隊(duì)利用了這么多的技術(shù)與產(chǎn)品,可見很多人都是多面手了。這是國內(nèi)技術(shù)團(tuán)隊(duì)需要向國外同行學(xué)習(xí)的地方。

Quora 的技術(shù)管理經(jīng)驗(yàn):

Quora 的代碼質(zhì)量四項(xiàng)原則

1. 閱讀和理解代碼應(yīng)該是簡單的 —— 開發(fā)者讀代碼的時(shí)間遠(yuǎn)遠(yuǎn)大于寫代碼的時(shí)間。因此Quora應(yīng)該盡量使代碼簡潔易懂,盡管寫出那樣的代碼可能會需要比原來更長的時(shí)間。

2. 不同部分的代碼應(yīng)該有不同的質(zhì)量要求 —— 不同部分的代碼對于長期開發(fā)帶來的影響是不一樣的,因?yàn)樗鼈冇胁煌纳芷?、影響范圍、被破壞的可能性、破壞后帶來的后果大小,以及debug的難度??傮w來說,不同的代碼對于產(chǎn)品迭代的速度的影響是不同的,因此對所有代碼都一視同仁顯然不是最佳選擇。

3. 維護(hù)代碼質(zhì)量的成本是可以減少的 —— 開發(fā)自動化,更易用的開發(fā)工具,更好的流程,以及更好的開發(fā)者都能夠減少維護(hù)代碼質(zhì)量的成本。

4. 整個(gè)代碼庫應(yīng)有一致性 —— 整個(gè)代碼庫的一致性是很重要的,盡管這意味著某些局部代碼可能并沒有用最佳的方法去寫。一個(gè)缺乏一致性的代碼庫會使閱讀,理解(參加第1點(diǎn)),后續(xù)功能添加,和使用自動化工具來改進(jìn)代碼都更加困難。

接下來,我將介紹一些在開發(fā)過程中 Quora 遵循著四項(xiàng)原則的具體方法。

代碼提交后的互相審查(Code Review)

如果代碼庫中有代碼變動,Quora會從 6 方面來同行審查 —— 正確性(correctness)、代碼封裝(privacy)、 性能(performance)、架構(gòu)(architecture)、可重用性(reusability)、代碼風(fēng)格(style)。閱讀代碼是代碼審查中不可或缺的一環(huán),因此實(shí)施代碼審查制度對于增加代碼可讀性也無疑是有利的。

但不幸的是,代碼審查也會拖慢開發(fā)進(jìn)程。例如代碼提交前的互相審查這個(gè)業(yè)界常規(guī),代碼在被提交到代碼庫之前必須由同伴審閱并由作者完成改進(jìn)。每輪審查可能會持續(xù)兩天,然后常常有兩到三輪審閱,這意味著代碼作者會經(jīng)常將浪費(fèi)大半個(gè)星期在代碼審閱的工作上。

在 Quora,Quora并不進(jìn)行代碼提交前的審查。即,代碼會先上線,然后才由某些同事來進(jìn)行審閱。為了讓你對Quora的工作規(guī)模有個(gè)概念,昨天Quora有48個(gè)開發(fā)者總共進(jìn)行了 187 次代碼提交(commit)。Quora認(rèn)為代碼后審閱是一項(xiàng)很好的舉措,因?yàn)樗岄_發(fā)者們從不必要的代碼審閱的牢籠中解放出來,可以先去完成其它的工作。這樣,審閱者們也可以挑他們方便的時(shí)候來閱讀這些代碼,以免被別人催促著完成這項(xiàng)工作。Quora的流程希望Quora在一周內(nèi)完成代碼審閱工作就可以了,但Quora大多數(shù)都會在  1  至  2  天內(nèi)進(jìn)行審閱。這個(gè)“一周”的長度是在仔細(xì)討論后定下的 —— 它既長到足夠?qū)忛喺邆冏杂砂才艑忛啎r(shí)間,也短到可以及時(shí)阻止低質(zhì)量代碼可能帶來的,被其他人閱讀并使用的后果。實(shí)際操作中,Quora也考慮到了許多開發(fā)者會有一個(gè)以“星期”為周期而安排的工作時(shí)間表。

Quora能實(shí)施代碼提交后審閱這項(xiàng)舉措,也是因?yàn)镼uora對 Quora 的每個(gè)開發(fā)者都加以信任,畢竟Quora只雇傭最好的開發(fā)者,也給予了他們最好的工具和最用心的培訓(xùn)。這也促使Quora寫下一些很好的測試來達(dá)到很高的代碼覆蓋率,這讓Quora在任何代碼審閱之前都可以自己檢閱代碼的正確性。除此以外,Quora使用 Phabricator 這個(gè)非常棒,配置自由度也相當(dāng)高的代碼審查工具。Quora對 Phabricator 這個(gè)工具做了一些修改,讓它能更好的為Quora提交后審查的流程服務(wù)。例如,Quora寫了一個(gè)命令行工具來幫助大家上線代碼并要求審閱。這個(gè)工具會讓開發(fā)者在不對之前的提交進(jìn)行任何修改的同時(shí)讓 Phabricator 的 diff 能夠正確運(yùn)行。

說了這么多,Quora對不同種類的改動有著不同的審閱要求。如果新代碼有可能會造成嚴(yán)重的后果,并且修復(fù)起來很難的話,Quora會要求對它進(jìn)行提交前審查,而不是常規(guī)的提交后審查。比如:

1. 涉及與用戶隱私和匿名相關(guān)的代碼;
2. 涉及了與一個(gè)核心抽象類有關(guān)的代碼,因?yàn)楹芏嗥渌a可能基于它;
3. 涉及了可能會造成宕機(jī)的底層代碼;
提交前還是提交后要求審查,這也跟開發(fā)者的謹(jǐn)慎程度有關(guān)。如果任何開發(fā)者想要在提交代碼前要求代碼審查,以此來獲得一些建議或意見的話,他們完全有這么做的自由 —— 盡管這很少發(fā)生。

把代碼審閱發(fā)給正確的人

為了使代碼審查進(jìn)行得順利,新代碼應(yīng)該由對于這個(gè)改變有著充分的認(rèn)知的人來審查。如果代碼是由將會維護(hù)這些代碼的人負(fù)責(zé)那就更好了,顯然他們將會有很充分的理由和動機(jī),來使代碼長期的可用性達(dá)到最佳。

Quora寫了一個(gè)簡單的系統(tǒng),讓開發(fā)者們可以簡單地表名模塊/目錄級別的代碼歸屬,它們只需要在文件的開頭加一個(gè)元標(biāo)簽就可以了。例如:

__reviewer__ = ‘vanessa, kornel’

如果有個(gè)提交(commit)會改變某個(gè)文件的話,這個(gè)系統(tǒng)會讀取這個(gè)標(biāo)簽,這個(gè)標(biāo)簽里標(biāo)明的開發(fā)者會被自動添加到這個(gè) commit 的審閱者名單里。除此以外,Quora也有其它的關(guān)于代碼審閱者的規(guī)則,例如對于所有設(shè)置了 A/B 測試的 commit,都會有一個(gè)數(shù)據(jù)分析師——如果原來沒有的話——被自動加到審閱名單里。事實(shí)上,Quora的工具也可以很簡單地添加其它的關(guān)于代碼審閱人的規(guī)則。例如,如果Quora想的話,可以把新雇員的所有 commit 都發(fā)送給他們的導(dǎo)師。

有一個(gè)智能的審閱分發(fā)系統(tǒng),把代碼審閱發(fā)送給正確的人,減少了開發(fā)者們尋找代碼審閱者的煩惱,并確保能找到最適合的人來審閱每一份代碼。

測試

測試是開發(fā)流程中很重要的一環(huán)。Quora寫了很多單元測試、功能測試、UI 測試來達(dá)到高代碼覆蓋率。有一個(gè)完整的單元測試,可以讓開發(fā)者快速平行地完成新代碼,而不必?fù)?dān)心破壞掉已有的功能。Quora花了很多時(shí)間來制作Quora的測試框架(基于 nosetests ),目標(biāo)是簡單、快速、易用,使寫測試的工作量盡可能低。

Quora也開發(fā)了許多自動化測試的工具。正如之前一篇探討Quora持續(xù)部署系統(tǒng)的文章所講的一樣,Quora所有的代碼在上線之前都在一個(gè)中心服務(wù)器上完成測試。這個(gè)測試服務(wù)器有著高并行的特性,因此即使跑完Quora所有的測試也只需要不到5分鐘。這么快速的系統(tǒng)就是為了鼓勵(lì)開發(fā)者們盡可能多地寫測試和進(jìn)行測試。Quora有一個(gè)叫“本地測試(test-local)”的工具,來自動找到和執(zhí)行和新增代碼有關(guān)的測試。為了更好地使用這個(gè)工具,Quora的測試必須要模塊化(這也在一個(gè)測試失敗了的情況下,幫助開發(fā)者們快速找到bug并修復(fù))。為了確保這個(gè)目的和一些其它的關(guān)于測試代碼的重要性質(zhì),Quora有一份描述測試代碼書寫規(guī)范的共享文件。這些原則在代碼審閱時(shí)被嚴(yán)格執(zhí)行。

和代碼審閱類似,Quora對于不同種類的改動有不同的測試標(biāo)準(zhǔn)。如果新改動有可能帶來嚴(yán)重后果和修復(fù)成本的話,Quora會要求更高的代碼覆蓋率。

所有的這些加在一起,使Quora寫測試的意義最大化,以此減少長期的開發(fā)成本。

代碼質(zhì)量指導(dǎo)

Quora非常熱衷于共享代碼質(zhì)量指導(dǎo),這幫助Quora:

1. 更好地培訓(xùn)新來的開發(fā)者;
2. 更好地在整個(gè)團(tuán)隊(duì)里共享Quora的經(jīng)驗(yàn)和智慧;
3. 設(shè)立共同的標(biāo)準(zhǔn)來提高代碼庫的一致性;
4. 減少開發(fā)和審閱環(huán)節(jié)的工作量。例如,在每個(gè)審閱中都討論一下每行代碼是80個(gè)還是100個(gè)字符是沒意義的。Quora可以就討論這個(gè)問題一次,然后在所有今后的代碼中都使用這個(gè)標(biāo)準(zhǔn)。
除了每種語言自身的語句規(guī)范之外,Quora也有更抽象的一些代碼規(guī)范,例如關(guān)于如何寫出好的測試或是如何架構(gòu)代碼模塊,來幫助減少代碼的閱讀時(shí)間。這些規(guī)范并不是一成不變的。在Quora逐漸對各種權(quán)衡有了更深的理解的過程中,Quora也會改變這些規(guī)范來達(dá)到利益最大化。Quora也有大型代碼重構(gòu)的工具(部分是諸如例如 codemod 之類的開源工具,其它的是Quora自己開發(fā)的),以在Quora改變了某項(xiàng)規(guī)范之后回過頭去重構(gòu)所有的舊代碼。

整頓舊代碼

一個(gè)快速前進(jìn)的團(tuán)隊(duì)會嘗試很多新事物,自然而然,它們之中某些很好,而某些則不盡如人意。因此,一個(gè)快速前進(jìn)的公司的代碼庫里肯定會有很多沉淀下來的糟粕,即那些實(shí)際上大家不再使用,卻留在那里使許多事情變得更復(fù)雜的代碼。清楚這些糟粕,保持代碼庫的簡潔,也會提高開發(fā)速度。
Quora定期組織“整頓周(Cleanup weeks)”來清除這些糟粕。在這些整頓周里,一些指定團(tuán)隊(duì)——有時(shí)也會是整個(gè)公司——把所有的時(shí)間都花在清楚那些不用的舊代碼上。這些定期活動減少了大家在“常規(guī)工作”和“整頓工作”中切換所需花費(fèi)的時(shí)間和精力,也讓整頓舊代碼變得更為有趣,帶來更多的社交價(jià)值。

部分代碼比其它的更加容易整頓,當(dāng)然也有部分代碼,整頓起來會對開發(fā)速度有極大的影響。為了最好地利用大家整頓舊代碼的時(shí)間,Quora會基于清除它們所需耗費(fèi)的時(shí)間,和清除后它們對開發(fā)速度帶來的影響,對各個(gè)代碼模塊的整頓優(yōu)先級進(jìn)行排序。

代碼查錯(cuò)與優(yōu)化(Linting)

人們很容易低估偶爾不遵循代碼語言規(guī)范(例如代碼注釋或每行代碼的長度)的后果,但這些后果是會疊加起來的。確實(shí),時(shí)時(shí)記得并遵循很多規(guī)范是很惱人的,特別是規(guī)范越來越多的時(shí)候。因此,Quora并不驚訝,很多開發(fā)者并不準(zhǔn)備遵循這些規(guī)范。

Quora開發(fā)了一個(gè)公司內(nèi)部代碼查錯(cuò)和優(yōu)化的工具,叫做 qlint,來減少達(dá)成這一目標(biāo)的工作量。Qlint 是基于 flake8 和 pylint開發(fā)的智能小工具,能識別文本結(jié)構(gòu)和抽象語法樹(AST)。這個(gè)工具讓Quora未來往里面添加新的代碼規(guī)則變得很容易。例如,Quora規(guī)定在Python里所有private的變量都必須在變量名前加下劃線,因而Quora在 qlint 里加了這一條規(guī)則來查找所有不符合這一規(guī)范的代碼。

Quora把 qlint 整合進(jìn)了許多其它開發(fā)工具,因此開發(fā)者們不必特別來關(guān)注 qlint 指出的各項(xiàng)問題。對于剛剛起步的開發(fā)者們,Quora把 qlint 整合進(jìn)了最流行的一些編輯器,例如 Vim、Emacs 和 Sublime,并在開發(fā)者違反了代碼規(guī)范的時(shí)候提供可視化的提示。Qlint 也整合在了提交代碼的流程里,并在任何人想要提交代碼的時(shí)候以一種互動化的方式運(yùn)行。事實(shí)上,取決于 commit 具體違反了哪條規(guī)則,這個(gè)工具甚至可能阻止代碼部署。Quora也把Quora的代碼規(guī)范文檔整合在了這個(gè)工具里,因此開發(fā)者每違反一條規(guī)則,qlint 都會給出一個(gè)鏈接指向文檔里的那個(gè)規(guī)則條目。Quora的 Phabricator 也被配置成使用qlint。這樣,由于所有的錯(cuò)誤都由 qlint 以可視化的方式指出了,代碼審閱變得更為簡單。
所有這些改進(jìn)都提高了Quora代碼庫的一致性,并使Quora能夠以最小的成本提高代碼質(zhì)量。

總結(jié)

就像這篇文章中指出的那樣,Quora 十分嚴(yán)謹(jǐn)認(rèn)真地對待代碼質(zhì)量。Quora對待這個(gè)問題很腳踏實(shí)地。Quora設(shè)計(jì)并開發(fā)了各種工具、系統(tǒng)和流程,來保持并增強(qiáng)Quora長期的開發(fā)效率。在Quora此時(shí)達(dá)到良好平衡的同時(shí),Quora的團(tuán)隊(duì)也在不斷地?cái)U(kuò)大和成長,因此Quora自信地認(rèn)為,未來還將開發(fā)出更多地工具和系統(tǒng)。

標(biāo)簽:湘潭 崇左 蘭州 黃山 銅川 湖南 衡水 仙桃

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《全球最大問答社區(qū)網(wǎng)站Quora開發(fā)的主要技術(shù)與經(jīng)驗(yàn)》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    仁寿县| 清河县| 兴业县| 巴塘县| 华蓥市| 鄂州市| 淮安市| 陇南市| 渭南市| 万载县| 昔阳县| 甘泉县| 尚志市| 漳州市| 渭南市| 大庆市| 田林县| 仁寿县| 门源| 响水县| 建宁县| 桂阳县| 遂溪县| 罗定市| 清水县| 嘉黎县| 建宁县| 辽中县| 博野县| 金平| 綦江县| 南华县| 舞钢市| 茂名市| 偏关县| 吴川市| 九江市| 白玉县| 慈溪市| 都匀市| 疏勒县|