【編者按】StackOverflow是一個(gè)IT技術(shù)問(wèn)答網(wǎng)站,用戶(hù)可以在網(wǎng)站上提交和回答問(wèn)題。當(dāng)下的StackOverflow已擁有400萬(wàn)個(gè)用戶(hù),4000萬(wàn)個(gè)回答,月PV5.6億,世界排行第54。然而值得關(guān)注的是,支撐他們網(wǎng)站的全部服務(wù)器只有25臺(tái),并且都保持著非常低的資源使用率,這是一場(chǎng)高有效性、負(fù)載均衡、緩存、數(shù)據(jù)庫(kù)、搜索及高效代碼上的較量。近日,High Scalability創(chuàng)始人Todd Hoff根據(jù)Marco Cecconi的演講視頻“ The architecture of StackOverflow”以及Nick Craver的博文“ What it takes to run Stack Overflow”總結(jié)了StackOverflow的成功原因。
以下為譯文
意料之中,也是意料之外,Stack Overflow仍然重度使用著微軟的產(chǎn)品。他們認(rèn)為既然微軟的基礎(chǔ)設(shè)施可以滿(mǎn)足需求,又足夠便宜,那么沒(méi)有什么理由去做根本上的改變。而在需要的地方,他們同樣使用了Linux。究其根本,一切都是為了性能。
另一個(gè)值得關(guān)注的地方是,Stack Overflow仍然使用著縱向擴(kuò)展策略,沒(méi)有使用云。他們使用了384GB的內(nèi)存和2TB的SSD來(lái)支撐SQL Servers,如果使用AWS的話(huà),花費(fèi)可想而知。沒(méi)有使用云的另一個(gè)原因是Stack Overflow認(rèn)為云會(huì)一定程度上的降低性能,同時(shí)也會(huì)給優(yōu)化和排查系統(tǒng)問(wèn)題增加難度。此外,他們的架構(gòu)也并不需要橫向擴(kuò)展。峰值期間是橫向擴(kuò)展的殺手級(jí)應(yīng)用場(chǎng)景,然而他們有著豐富的系統(tǒng)調(diào)整經(jīng)驗(yàn)去應(yīng)對(duì)。該公司仍然堅(jiān)持著Jeff Atwood的名言——硬件永遠(yuǎn)比程序員便宜。
Marco Ceccon曾提到,在談及系統(tǒng)時(shí),有一件事情必須首先弄明白——需要解決問(wèn)題的類(lèi)型。首先,從簡(jiǎn)單方面著手,StackExchange究竟是用來(lái)做什么的——首先是一些主題,然后圍繞這些主題建立社區(qū),最后就形成了這個(gè)令人敬佩的問(wèn)答網(wǎng)站。
其次則是規(guī)模相關(guān)。StackExchange在飛速增長(zhǎng),需要處理大量的數(shù)據(jù)傳輸,那么這些都是如何完成的,特別是只使用了25臺(tái)服務(wù)器,下面一起追根揭底:
狀態(tài)
StackExchange擁有110個(gè)站點(diǎn),以每個(gè)月3到4個(gè)的速度增長(zhǎng)。
400萬(wàn)用戶(hù)
800萬(wàn)問(wèn)題
4000萬(wàn)答案
世界排名54位
每年增長(zhǎng)100%
月PV 5.6億萬(wàn)
大多數(shù)工作日期間峰值為2600到3000請(qǐng)求每秒,作為一個(gè)編程相關(guān)網(wǎng)站,一般情況下工作日的請(qǐng)求都會(huì)高于周末
25臺(tái)服務(wù)器
SSD中儲(chǔ)存了2TB的SQL數(shù)據(jù)
每個(gè)web server都配置了2個(gè)320G的SSD,使用RAID 1
每個(gè)ElasticSearch主機(jī)都配備了300GB的機(jī)械硬盤(pán),同時(shí)也使用了SSD
Stack Overflow的讀寫(xiě)比是40:60
DB Server的平均CPU利用率是10%
11個(gè)web server,使用IIS
2個(gè)負(fù)載均衡器,1個(gè)活躍,使用HAProxy
4個(gè)活躍的數(shù)據(jù)庫(kù)節(jié)點(diǎn),使用MS SQL
3臺(tái)實(shí)現(xiàn)了tag engine的應(yīng)用程序服務(wù)器,所有搜索都通過(guò)tag
3臺(tái)服務(wù)器通過(guò)ElasticSearch做搜索
2臺(tái)使用了Redis的服務(wù)器支撐分布式緩存和消息
2臺(tái)Networks(Nexus 5596 + Fabric Extenders)
2 Cisco 5525-X ASAs
2 Cisco 3945 Routers
主要服務(wù)Stack Exchange API的2個(gè)只讀SQL Servers
VM用于部署、域控制器、監(jiān)控、運(yùn)維數(shù)據(jù)庫(kù)等場(chǎng)合
平臺(tái)
ElasticSearch
Redis
HAProxy
MS SQL
Opserver
TeamCity
Jil——Fast .NET JSON Serializer,建立在Sigil之上
Dapper——微型的ORM
UI
UI擁有一個(gè)信息收件箱,用于新徽章獲得、用戶(hù)發(fā)送信息、重大事件發(fā)生時(shí)的信息收取,使用WebSockets實(shí)現(xiàn),并通過(guò)Redis支撐。
搜索箱通過(guò) ElasticSearch 實(shí)現(xiàn),使用了一個(gè)REST接口。
因?yàn)橛脩?hù)提出問(wèn)題的頻率很高,因此很難顯示最新問(wèn)題,每秒都會(huì)有新的問(wèn)題產(chǎn)生,從而這里需要開(kāi)發(fā)一個(gè)關(guān)注用戶(hù)行為模式的算法,只給用戶(hù)顯示感興趣的問(wèn)題。它使用了基于Tag的復(fù)雜查詢(xún),這也是開(kāi)發(fā)獨(dú)立Tag Engine的原因。
服務(wù)器端模板用于生成頁(yè)面。
服務(wù)器
25臺(tái)服務(wù)器并沒(méi)有滿(mǎn)載,CPU使用率并不高,單計(jì)算SO(Stack Overflow)只需要5臺(tái)服務(wù)器。
數(shù)據(jù)庫(kù)服務(wù)器資源利用率在10%左右,除下執(zhí)行備份時(shí)。
為什么會(huì)這么低?因?yàn)閿?shù)據(jù)庫(kù)服務(wù)器足足擁有384GB內(nèi)存,同時(shí)web server的CPU利用率也只有10%-15%。
縱向擴(kuò)展還沒(méi)有遇到瓶頸。通常情況下,如此流量使用橫向擴(kuò)展大約需要100到300臺(tái)服務(wù)器。
簡(jiǎn)單的系統(tǒng)?;?Net,只用了9個(gè)項(xiàng)目,其他系統(tǒng)可能需要100個(gè)。之所以使用這么少系統(tǒng)是為了追求極限的編譯速度,這點(diǎn)需要從系統(tǒng)開(kāi)始時(shí)就進(jìn)行規(guī)劃,每臺(tái)服務(wù)器的編譯時(shí)間大約是10秒。
11萬(wàn)行代碼,對(duì)比流量來(lái)說(shuō)非常少。
使用這種極簡(jiǎn)的方式主要基于幾個(gè)原因。首先,不需要太多測(cè)試,因?yàn)镸eta.stackoverflow本來(lái)就是一個(gè)問(wèn)題和bug討論社區(qū)。其次,Meta.stackoverflow還是一個(gè)軟件的測(cè)試網(wǎng)站,如果用戶(hù)發(fā)現(xiàn)問(wèn)題的話(huà),往往會(huì)提出并給予解決方案。
紐約數(shù)據(jù)中心使用的是Windows 2012,已經(jīng)向2012 R2升級(jí)(Oregon已經(jīng)完成了升級(jí)),Linux系統(tǒng)使用的是Centos 6.4。
SSD
默認(rèn)使用的是Intel 330(Web層等)
Intel 520用于中間層寫(xiě)入,比如Elastic Search
數(shù)據(jù)層使用Intel 710和S3700
系統(tǒng)同時(shí)使用了RAID 1和RAID 10(任何4+以上的磁盤(pán)都使用RAID 10)。不畏懼故障發(fā)生,即使生產(chǎn)環(huán)境中使用了上千塊2.5英寸SSD,還沒(méi)碰到過(guò)一塊失敗的情景。每個(gè)模型都使用了1個(gè)以上的備件,多個(gè)磁盤(pán)發(fā)生故障的情景不在考慮之中。
ElasticSearch在SSD上表現(xiàn)的異常出色,因?yàn)镾O writes/re-indexes的操作非常頻繁。
SSD改變了搜索的使用方式。因?yàn)殒i的問(wèn)題,Luncene.net并不能支撐SO的并發(fā)負(fù)載,因此他們轉(zhuǎn)向了ElasticSearch。在全SSD環(huán)境下,并不需要圍繞Binary Reader建立鎖。
高可用性
異地備份——主數(shù)據(jù)中心位于紐約,備份數(shù)據(jù)中心在Oregon。
Redis有兩個(gè)從節(jié)點(diǎn),SQL有2個(gè)備份,Tag Engine有3個(gè)節(jié)點(diǎn),elastic有3個(gè)節(jié)點(diǎn),冗余一切,并在兩個(gè)數(shù)據(jù)中心同時(shí)存在。
Nginx是用于SSL,終止SSL時(shí)轉(zhuǎn)換使用HAProxy。
并不是主從所有,一些臨時(shí)的數(shù)據(jù)只會(huì)放到緩存中
所有HTTP流量發(fā)送只占總流量的77%,還存在Oregon數(shù)據(jù)中心的備份及一些其他的VPN流量。這些流量主要由SQL和Redis備份產(chǎn)生。
數(shù)據(jù)庫(kù)
MS SQL Server
Stack Exchange為每個(gè)網(wǎng)站都設(shè)置了數(shù)據(jù)庫(kù),因此Stack Overflow有一個(gè)、Server Fault有一個(gè),以此類(lèi)推。
在紐約的主數(shù)據(jù)中心,每個(gè)集群通常都使用1主和1只讀備份的配置,同時(shí)還會(huì)在Oregon數(shù)據(jù)中心也設(shè)置一個(gè)備份。如果是運(yùn)行的是Oregon集群,那么兩個(gè)在紐約數(shù)據(jù)中心的備份都會(huì)是只讀和同步的。
為其他內(nèi)容準(zhǔn)備的數(shù)據(jù)庫(kù)。這里還存在一個(gè)“網(wǎng)絡(luò)范圍”的數(shù)據(jù)庫(kù),用于儲(chǔ)存登陸憑證和聚合數(shù)據(jù)(大部分是stackexchange.com用戶(hù)文件或者API)。
Careers Stack Overflow、stackexchange.com和Area 51等都擁有自己獨(dú)立的數(shù)據(jù)庫(kù)模式。
模式的變化需要同時(shí)提供給所有站點(diǎn)的數(shù)據(jù)庫(kù),它們需要向下兼容,舉個(gè)例子,如果需要重命名一個(gè)列,那么將非常麻煩,這里需要進(jìn)行多個(gè)操作:增加一個(gè)新列,添加作用在兩個(gè)列上的代碼,給新列寫(xiě)數(shù)據(jù),改變代碼讓新列有效,移除舊列。
并不需要分片,所有事情通過(guò)索引來(lái)解決,而且數(shù)據(jù)體積也沒(méi)那么大。如果有filtered indexes需求,那么為什么不更高效的進(jìn)行?常見(jiàn)模式只在DeletionDate = Null上做索引,其他則通過(guò)為枚舉指定類(lèi)型。每項(xiàng)votes都設(shè)置了1個(gè)表,比如一張表給post votes,1張表給comment votes。大部分的頁(yè)面都可以實(shí)時(shí)渲染,只為匿名用戶(hù)緩存,因此,不存在緩存更新,只有重查詢(xún)。
Scores是非規(guī)范化的,因此需要經(jīng)常查詢(xún)。它只包含IDs和dates,post votes表格當(dāng)下大約有56454478行,使用索引,大部分的查詢(xún)都可以在數(shù)毫秒內(nèi)完成。
Tag Engine是完全獨(dú)立的,這就意味著核心功能并不依賴(lài)任何外部應(yīng)用程序。它是一個(gè)巨大的內(nèi)存結(jié)構(gòu)數(shù)組結(jié)構(gòu),專(zhuān)為SO用例優(yōu)化,并為重負(fù)載組合進(jìn)行預(yù)計(jì)算。Tag Engine是個(gè)簡(jiǎn)單的windows服務(wù),冗余的運(yùn)行在多個(gè)主機(jī)上。CPU使用率基本上保持在2-5%,3個(gè)主機(jī)專(zhuān)門(mén)用于冗余,不負(fù)責(zé)任何負(fù)載。如果所有主機(jī)同時(shí)發(fā)生故障,網(wǎng)絡(luò)服務(wù)器將把Tag Engine加載到內(nèi)存中持續(xù)運(yùn)行。
關(guān)于Dapper無(wú)編譯器校驗(yàn)查詢(xún)與傳統(tǒng)ORM的對(duì)比。使用編譯器有很多好處,但在運(yùn)行時(shí)仍然會(huì)存在fundamental disconnect問(wèn)題。同時(shí)更重要的是,由于生成nasty SQL,通常情況還需要去尋找原始代碼,而Query Hint和parameterization控制等能力的缺乏更讓查詢(xún)優(yōu)化變得復(fù)雜。
編碼
流程
大部分程序員都是遠(yuǎn)程工作,自己選擇編碼地點(diǎn)
編譯非???/p>
然后運(yùn)行少量的測(cè)試
一旦編譯成功,代碼即轉(zhuǎn)移至開(kāi)發(fā)交付準(zhǔn)備服務(wù)器
通過(guò)功能開(kāi)關(guān)隱藏新功能
在相同硬件上作為其他站點(diǎn)測(cè)試運(yùn)行
然后轉(zhuǎn)移至Meta.stackoverflow測(cè)試,每天有上千個(gè)程序員在使用,一個(gè)很好的測(cè)試環(huán)境
如果通過(guò)則上線(xiàn),在更廣大的社區(qū)進(jìn)行測(cè)試
大量使用靜態(tài)類(lèi)和方法,為了更簡(jiǎn)單及更好的性能
編碼過(guò)程非常簡(jiǎn)單,因?yàn)閺?fù)雜的部分被打包到庫(kù)里,這些庫(kù)被開(kāi)源和維護(hù)。.Net 項(xiàng)目數(shù)量很低,因?yàn)槭褂昧松鐓^(qū)共享的部分代碼。
開(kāi)發(fā)者同時(shí)使用2到3個(gè)顯示器,多個(gè)屏幕可以顯著提高生產(chǎn)效率。
緩存
緩存一切
5個(gè)等級(jí)的緩存
1級(jí)是網(wǎng)絡(luò)級(jí)緩存,緩存在瀏覽器、CDN以及代理服務(wù)器中。
2級(jí)由.Net框架 HttpRuntime.Cache完成,在每臺(tái)服務(wù)器的內(nèi)存中。
3級(jí)Redis,分布式內(nèi)存鍵值存儲(chǔ),在多個(gè)支撐同一個(gè)站點(diǎn)的服務(wù)器上共享緩存項(xiàng)。
4級(jí)SQL Server Cache,整個(gè)數(shù)據(jù)庫(kù),所有數(shù)據(jù)都被放到內(nèi)存中。
5級(jí)SSD。通常只在SQL Server預(yù)熱后才生效。
舉個(gè)例子,每個(gè)幫助頁(yè)面都進(jìn)行了緩存,訪(fǎng)問(wèn)一個(gè)頁(yè)面的代碼非常簡(jiǎn)單:
使用了靜態(tài)的方法和類(lèi)。從OOP角度來(lái)看確實(shí)很糟,但是非??觳⒂欣诤?jiǎn)潔編碼。
緩存由Redis和Dapper支撐,一個(gè)微型ORM
為了解決垃圾收集問(wèn)題,模板中1個(gè)類(lèi)只使用1個(gè)副本,被建立和保存在緩存中。監(jiān)測(cè)一切,包括GC操。據(jù)統(tǒng)計(jì)顯示,間接層增加GC壓力達(dá)到了某個(gè)程度時(shí)會(huì)顯著的降低性能。
CDN Hit 。鑒于查詢(xún)字符串基于文件內(nèi)容進(jìn)行哈希,只在有新建立時(shí)才會(huì)被再次取出。每天3000萬(wàn)到5000萬(wàn)Hit,帶寬大約為300GB到600GB。
CDN不是用來(lái)應(yīng)對(duì)CPU或I/O負(fù)載,而是幫助用戶(hù)更快的獲得答案
部署
每天5次部署,不去建立過(guò)大的應(yīng)用。主要因?yàn)?/p>
可以直接的監(jiān)視性能
盡可能最小化建立,可以工作才是重點(diǎn)
產(chǎn)品建立后再通過(guò)強(qiáng)大的腳本拷貝到各個(gè)網(wǎng)頁(yè)層,每個(gè)服務(wù)器的步驟是:
通過(guò)POST通知HAProxy下架某臺(tái)服務(wù)器
延遲IIS結(jié)束現(xiàn)有請(qǐng)求(大約5秒)
停止網(wǎng)站(通過(guò)同一個(gè)PSSession結(jié)束所有下游)
Robocopy文件
開(kāi)啟網(wǎng)站
通過(guò)另一個(gè)POST做HAProxy Re-enable
幾乎所有部署都是通過(guò)puppet或DSC,升級(jí)通常只是大幅度調(diào)整RAID陣列并通過(guò)PXE boot安裝,這樣做非??焖?。
協(xié)作
團(tuán)隊(duì)
SRE (System Reliability Engineering):5人
Core Dev(Q&A site)6-7人
Core Dev Mobile:6人
Careers團(tuán)隊(duì)專(zhuān)門(mén)負(fù)責(zé)SO Careers產(chǎn)品開(kāi)發(fā):7人
Devops和開(kāi)發(fā)者結(jié)合的非常緊密
團(tuán)隊(duì)間變化很大
大部分員工遠(yuǎn)程工作
辦公室主要用于銷(xiāo)售,Denver和London除外
一切平等,些許偏向紐約工作者,因?yàn)槊鎸?duì)面有助于工作交流,但是在線(xiàn)工作影響也并不大
對(duì)比可以在同一個(gè)辦公室辦公,他們更偏向熱愛(ài)產(chǎn)品及有才華的工程師,他們可以很好的衡量利弊
許多人因?yàn)榧彝ザx擇遠(yuǎn)程工作,紐約是不錯(cuò),但是生活并不寬松
辦公室設(shè)立在曼哈頓,那是個(gè)人才的誕生地。數(shù)據(jù)中心不能太偏,因?yàn)榻?jīng)常會(huì)涉及升級(jí)
打造一個(gè)強(qiáng)大團(tuán)隊(duì),偏愛(ài)極客。早期的微軟就聚集了大量極客,因此他們征服了整個(gè)世界
Stack Overflow社區(qū)也是個(gè)招聘的地點(diǎn),他們?cè)谀菍ふ覠釔?ài)編碼、樂(lè)于助人及熱愛(ài)交流的人才。
編制預(yù)算
預(yù)算是項(xiàng)目的基礎(chǔ)。錢(qián)只花在為新項(xiàng)目建立基礎(chǔ)設(shè)施上,如此低利用率的 web server還是3年前數(shù)據(jù)中心建立時(shí)購(gòu)入。
測(cè)試
快速迭代和遺棄
許多測(cè)試都是發(fā)布隊(duì)伍完成的。開(kāi)發(fā)擁有一個(gè)同樣的SQL服務(wù)器,并且運(yùn)行在相同的Web層,因此性能測(cè)試并不會(huì)糟糕。
非常少的測(cè)試。Stack Overflow并沒(méi)有進(jìn)行太多的單元測(cè)試,因?yàn)樗麄兪褂昧舜罅康撵o態(tài)代碼,還有一個(gè)非?;钴S的社區(qū)。
基礎(chǔ)設(shè)施改變。鑒于所有東西都有雙份,所以每個(gè)舊配置都有備份,并使用了一個(gè)快速故障恢復(fù)機(jī)制。比如,keepalived可以在負(fù)載均衡器中快速回退。
對(duì)比定期維護(hù),他們更愿意依賴(lài)冗余系統(tǒng)。SQL備份用一個(gè)專(zhuān)門(mén)的服務(wù)器進(jìn)行測(cè)試,只為了可以重存儲(chǔ)。計(jì)劃做每?jī)蓚€(gè)月一次的全數(shù)據(jù)中心故障恢復(fù),或者使用完全只讀的第二數(shù)據(jù)中心。
每次新功能發(fā)布都做單元測(cè)試、集成測(cè)試盒UI測(cè)試,這就意味著可以預(yù)知輸入的產(chǎn)品功能測(cè)試后就會(huì)推送到孵化網(wǎng)站,即meta.stackexchange(原meta.stackoverflow)。
監(jiān)視/日志
當(dāng)下正在考慮使用http://logstash.net/做日志管理,目前使用了一個(gè)專(zhuān)門(mén)的服務(wù)將syslog UDP傳輸?shù)絊QL數(shù)據(jù)庫(kù)中。網(wǎng)頁(yè)中為計(jì)時(shí)添加header,這樣就可以通過(guò)HAProxy來(lái)捕獲并且融合到syslog傳輸中。
Opserver和Realog用于顯示測(cè)量結(jié)果。Realog是一個(gè)日志展示系統(tǒng),由Kyle Brandt和Matt Jibson使用Go建立。
日志通過(guò)HAProxy負(fù)載均衡器借助syslog完成,而不是IIS,因?yàn)槠涔δ鼙菼IS更豐富。
關(guān)于云
還是老生常談,硬件永遠(yuǎn)比開(kāi)發(fā)者和有效率的代碼便宜?;谀就靶?yīng),速度肯定受限于某個(gè)短板,現(xiàn)有的云服務(wù)基本上都存在容量和性能限制。
如果從開(kāi)始就使用云來(lái)建設(shè)SO說(shuō)不定也會(huì)達(dá)到現(xiàn)在的水準(zhǔn)。但毫無(wú)疑問(wèn)的是,如果達(dá)到同樣的性能,使用云的成本將遠(yuǎn)遠(yuǎn)高于自建數(shù)據(jù)中心。
性能至上
StackOverflow是個(gè)重度的性能控,主頁(yè)加載的時(shí)間永遠(yuǎn)控制在50毫秒內(nèi),當(dāng)下的響應(yīng)時(shí)間是28毫秒。
程序員熱衷于降低頁(yè)面加載時(shí)間以及提高用戶(hù)體驗(yàn)。
每個(gè)獨(dú)立的網(wǎng)絡(luò)提交都予以計(jì)時(shí)和記錄,這種計(jì)量可以弄清楚提升性能需要修改的地方。
如此低資源利用率的主要原因就是高效的代碼。web server的CPU平均利用率在5%到15%之間,內(nèi)存使用為15.5 GB,網(wǎng)絡(luò)傳輸在20 Mb/s到40 Mb/s。SQL服務(wù)器的CPU使用率在5%到10%之間,內(nèi)存使用是365GB,網(wǎng)絡(luò)傳輸為100 Mb/s到200 Mb/s。這可以帶來(lái)3個(gè)好處:給升級(jí)留下很大的空間;在嚴(yán)重錯(cuò)誤發(fā)生時(shí)可以保持服務(wù)可用;在需要時(shí)可以快速回檔。
學(xué)到的知識(shí)
1. 為什么使用MS產(chǎn)品的同時(shí)還使用Redis?什么好用用什么,不要做無(wú)必要的系統(tǒng)之爭(zhēng),比如C#在Windows機(jī)器上運(yùn)行最好,我們使用IIS;Redis在*nix機(jī)器上可以得到充分發(fā)揮,我們使用*nix。
2. Overkill即策略。平常的利用率并不能代表什么,當(dāng)某些特定的事情發(fā)生時(shí),比如備份、重建等完全可以將資源使用拉滿(mǎn)。
3. 堅(jiān)固的SSD。所有數(shù)據(jù)庫(kù)都建立在SSD之上,這樣可以獲得0延時(shí)。
4.了解你的讀寫(xiě)負(fù)載。
5. 高效的代碼意味著更少的主機(jī)。只有新項(xiàng)目上線(xiàn)時(shí)才會(huì)因?yàn)樘厥庑枨笤黾佑布?,通常情況下是添加內(nèi)存,但在此之外,高效的代碼就意味著0硬件添加。所以經(jīng)常只討論兩個(gè)問(wèn)題:為存儲(chǔ)增加新的SSD;為新項(xiàng)目增加硬件。
6. 不要害怕定制化。SO在Tag上使用復(fù)雜查詢(xún),因此專(zhuān)門(mén)開(kāi)發(fā)了所需的Tag Engine。
7.只做必須做的事情。之所以不需要測(cè)試是因?yàn)橛幸粋€(gè)活躍的社區(qū)支撐,比如,開(kāi)發(fā)者不用擔(dān)心出現(xiàn)“Square Wheel”效應(yīng),如果開(kāi)發(fā)者可以制作一個(gè)更更輕量級(jí)的組件,那就替代吧。
8. 注重硬件知識(shí),比如IL。一些代碼使用IL而不是C#。聚焦SQL查詢(xún)計(jì)劃。使用web server的內(nèi)存轉(zhuǎn)儲(chǔ)究竟做了些什么。探索,比如為什么一個(gè)split會(huì)產(chǎn)生2GB的垃圾。
9. 切勿官僚作風(fēng)。總有一些新的工具是你需要的,比如,一個(gè)編輯器,新版本的Visual Studio,降低提升過(guò)程中的一切阻力。
10. 垃圾回收驅(qū)動(dòng)編程。SO在減少垃圾回收成本上做了很多努力,跳過(guò)類(lèi)似TDD的實(shí)踐,避免抽象層,使用靜態(tài)方法。雖然極端,但是確實(shí)打造出非常高效的代碼。
11. 高效代碼的價(jià)值遠(yuǎn)遠(yuǎn)超出你想象,它可以讓硬件跑的更快,降低資源使用,切記讓代碼更容易被程序員理解。