「卷」有理論依據(jù):海勒姆定律—Go又是怎么卷的
大家好,我是站長(zhǎng) polarisxu。
對(duì)開發(fā)人員來說,其實(shí)也是有不少定律或原則的,只是很多人可能經(jīng)歷了,但不知道原來是這么個(gè)定律。
「內(nèi)卷」這個(gè)詞很流行,幾乎滲透到每一個(gè)角落:
- 幼兒園小朋友都學(xué)一年級(jí)知識(shí)了,你家的不學(xué),一年級(jí)跟不上。。。
- 小學(xué)生就各種課外輔導(dǎo)班,你不報(bào)班,也沒人一起玩,讓他看電子產(chǎn)品?
- 面試造火箭,工作擰螺絲的現(xiàn)象更加嚴(yán)重。。。
- 公眾號(hào)各種卷:標(biāo)題、內(nèi)容等,卷王之王都出現(xiàn)了。。。
- 。。。
想起一個(gè)段子:「面試滴滴司機(jī)」,對(duì)話過程大概是這樣的。(來源網(wǎng)絡(luò),如有雷同,純屬巧合)
看你簡(jiǎn)歷,你已經(jīng)有八年的開車經(jīng)驗(yàn),咱們聊一聊從你按下汽車點(diǎn)火按鈕后,汽車發(fā)生的一系列的動(dòng)作。
答:
1)按下按鈕后0.5秒,車輛完成電路自檢。2)按下1秒后,啟動(dòng)機(jī)馬達(dá)的電路被接通,帶動(dòng)馬達(dá)高速運(yùn)轉(zhuǎn),馬達(dá)轉(zhuǎn)子帶動(dòng)發(fā)動(dòng)機(jī)飛輪運(yùn)動(dòng),汽車發(fā)動(dòng)機(jī)在轟鳴聲中啟動(dòng)。3)油門踏板控制著發(fā)動(dòng)機(jī)進(jìn)氣門(亦稱作節(jié)氣門)的開合角度。油門踩得越深,進(jìn)氣門開合角度就越大,進(jìn)氣量也就越大。4)然后,火花塞適時(shí)點(diǎn)火,引燃可燃?xì)庑纬?ldquo;爆燃”,巨大的沖擊力使得活塞進(jìn)行運(yùn)動(dòng)。每分鐘這樣的“爆燃”會(huì)發(fā)生幾百上千次?;钊倪\(yùn)動(dòng)帶動(dòng)發(fā)動(dòng)機(jī)曲軸飛速旋轉(zhuǎn)。發(fā)動(dòng)機(jī)轉(zhuǎn)速的,就是每分鐘內(nèi)曲軸旋轉(zhuǎn)的圈數(shù)。5)氣缸活塞在封閉爆燃的推動(dòng)下往復(fù)運(yùn)動(dòng),產(chǎn)生連續(xù)不斷的動(dòng)力。
至此,發(fā)動(dòng)機(jī)順利完成啟動(dòng),掛好檔位踩油門,轉(zhuǎn)速和車速逐步攀升,我們可以出發(fā)啦!
面試官接著問:
嗯,那有在之前的工作中,做過啟動(dòng)優(yōu)化嗎?盡量減少發(fā)動(dòng)的時(shí)間,提高用戶體驗(yàn)。
。。。
是不是卷的飛起?!
01 海勒姆定律
在程序設(shè)計(jì)中,接口和實(shí)現(xiàn)是很重要的兩部分。通常在一個(gè)系統(tǒng)里面,接口就是一個(gè)與系統(tǒng)交互的抽象,比如汽車的方向盤和油門,剎車這些(我們通過這些來控制汽車,與汽車交互),而實(shí)現(xiàn)則是這個(gè)系統(tǒng)工作的一種方式,比如汽車的輪子和引擎(汽車實(shí)際是通過這些來工作的)。區(qū)分接口和實(shí)現(xiàn)的好處是非常明顯的,當(dāng)一個(gè)系統(tǒng)快速迭代,變得越來越復(fù)雜和難以理解的時(shí)候,抽象能非常好的幫助我們管理這些復(fù)雜性。
可見,一個(gè)接口在理論上需要清晰的將系統(tǒng)的使用者和該系統(tǒng)的實(shí)現(xiàn)隔離開。汽車系統(tǒng)是如此,其他系統(tǒng)也是如此。雖然設(shè)計(jì)者很努力,但現(xiàn)實(shí)往往是殘酷的,當(dāng)這個(gè)系統(tǒng)開始逐漸膨脹,一些用戶開始依賴一些通過接口暴露出的內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),「內(nèi)卷」開始。。。
幾年前,Google 的一名工程師,Hyrum(海勒姆)觀察指出:
當(dāng) API 有足夠多的用戶時(shí),你在合同中的承諾已不重要:你系統(tǒng)的所有可觀察行為都將被某些人所依賴。
這也叫做「隱式接口定律」。
也就是說,當(dāng)你的 API 有足夠多的用戶時(shí),API 的所有行為(包括那些未囊括在公共說明中的一部分)最終都會(huì)被其他人所依賴。一個(gè)簡(jiǎn)單的例子是 API 的響應(yīng)時(shí)間這種非功能性因素;還有一個(gè)更微妙的例子是:用戶使用正則表達(dá)式匹配錯(cuò)誤提示來判斷 API 的錯(cuò)誤類型,即使 API 文檔中沒有任何關(guān)于錯(cuò)誤提示的內(nèi)容,而是指導(dǎo)用戶應(yīng)該使用相應(yīng)的錯(cuò)誤代碼。一些用戶依然會(huì)使用錯(cuò)誤提示內(nèi)容(而非錯(cuò)誤代碼),這種情況下變更 API 錯(cuò)誤提示信息,實(shí)際上會(huì)破壞 API 的使用。
俗稱:不按套路出牌。
02 該定律在 Go 中的體現(xiàn)
隨著使用 Go 的人越來越多,大家超越 Go 規(guī)范,不滿足于 Go 公開的 API,「卷入」其內(nèi)部實(shí)現(xiàn)了。你會(huì)寫 Go 代碼,寫過大型項(xiàng)目可能都不夠,你必須得符合「海勒姆定律」,挖挖 GMP、GC 等 runtime 很多實(shí)現(xiàn)細(xì)節(jié)。
雖然 Go 官方一直在避免大家陷入實(shí)現(xiàn)細(xì)節(jié),依賴實(shí)現(xiàn)細(xì)節(jié),但還是擋不住「愛學(xué)習(xí)」的人們。比如 Go 中的 map 是無序的,但某個(gè)版本的實(shí)現(xiàn),用戶測(cè)試輸出,咦,發(fā)現(xiàn)是有序的。。。然后依賴它。Go 官方「一怒之下」,故意打亂順序。
再比如一個(gè)包中多個(gè)文件的初始化順序,規(guī)范并沒有進(jìn)行約定。但目前官方的實(shí)現(xiàn)是按照文件名順序初始化的,于是很可能就有面試題,并且多半答案就說是文件名順序,因?yàn)楝F(xiàn)在是這么實(shí)現(xiàn)的,源碼在那擺著呢。。。
再比如,Go 中 slice 的擴(kuò)容,太多太多文章解釋,擴(kuò)容的規(guī)則是怎么樣的,1.5 倍?2 倍?規(guī)范并沒有對(duì)此做約定。而且 Go 不同版本的實(shí)現(xiàn)還經(jīng)常變。用好 slice 貌似基本不能滿足要求,你必須得知道它怎么擴(kuò)容的,每次擴(kuò)容增加多少?這跟開車需要知道發(fā)動(dòng)機(jī)原理似乎沒啥區(qū)別~
還有很多很多例子,歡迎留言!
03 對(duì)我們有何啟發(fā)
在實(shí)際工作中,我們一方面要盡量設(shè)計(jì)好接口,將接口和實(shí)現(xiàn)隔離,但同時(shí)也要留意隱式接口問題。特別是對(duì)外提供服務(wù)(包括公司的基礎(chǔ)部門,對(duì)其他部門提供服務(wù)),要求我們?cè)跇?gòu)建和維護(hù)復(fù)雜系統(tǒng)的時(shí)候思考的更全面一點(diǎn)。我們需要意識(shí)到,隱示接口會(huì)限制我們系統(tǒng)的設(shè)計(jì)和發(fā)展。雖然隱式接口理論上不是你的鍋,但使用者不會(huì)這么認(rèn)為。
所以,「卷」有了理論依據(jù)。谷歌很多年前就用理論證明了「卷」的普遍存在,卷的有理有據(jù),你還能不倦嗎???
04 參考
海勒姆定律:https://www.hyrumslaw.com/
本文轉(zhuǎn)載自微信公眾號(hào)「polarisxu」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系polarisxu公眾號(hào)。