翻譯 :鄒永勝程序員
歡迎訪問網易雲社區,瞭解更多網易技術產品運營經驗。 正則表達式
互聯網上有一個很關鍵的部分,你天天都依賴於它,它處於TCP協議中,它是互聯網的基本組成部分之一。
TCP協議是可信賴的傳輸層協議。這就意味着你採用TCP去發送數據,不會存在數據混亂或丟失的狀況。
咱們平常中的不少事情都在使用TCP協議,例如瀏覽網頁或者發送郵件。每一封郵件可以穩定的到達正是因爲TCP的可靠性。儘管其中有許多垃圾郵件。
做爲比較,另一個不可靠的傳輸數據的協議稱爲 `IP`。沒有人可以保證你發送的數據可以達到,即便到達了,數據也許已經混亂了。若是你採用IP協議去發送一批數據,若是隻有一半數據到達了,千萬別驚訝。即便是達到的數據中,也不能保證數據正確。
可是有個神奇現象:TCP是在IP協議之上的,TCP有義務採用一種不可信賴的方式去傳輸數據。
爲了解釋這個神奇的現象,在真實的世界中以道德的角度來思考這個問題:
想象咱們要從百老匯運送一批演員到好萊塢,咱們採用汽車運輸的方式,橫跨幾個州。運輸過程當中,有些車輛墜毀了,可憐的演員就這樣掛了。有些演員或醉酒、剪了頭髮、紋了鼻子等,形象變化了,以致於好萊塢再也不接受他們演出。與此同時,因爲每輛車的行駛路線不一樣,致使每一個演員的到達時間不同。如今假設有一種服務叫作好萊塢速遞,它能快速安全有序的運送演員到好萊塢,每一個演員的到達順序和出發順序完美地保持一致。神奇的部分在於好萊塢速運除了把演員塞進車裏,而後橫跨幾個州運輸外,沒有其餘辦法運輸。好萊塢速運會檢驗每一個演員確保是否無缺無損的到達,若是出現問題,就會請求總部,從新下發送一個與損壞的那個演員如出一轍的演員過來。若是到達後演員順序出錯,速運公司會從新給他們排序。若是有不明飛行物撞擊損壞了內華達州的道路,那麼全部的運輸車輛都會從新選擇亞利桑那州的道路。當到達目的地後,速運公司不會告知加州的好萊塢導演們中途發生了什麼,對於導演來說,他的演員們僅僅是比以前慢一點而已,至於中午的UFO撞擊事件他們壓根不知道。
也就是說,TCP的神奇之處就是計算機科學家們喜歡稱之爲抽象的東西:掩蓋複雜的流程達到簡化的目的。事實證實,不少計算機編程都是由抽象構成的。什麼是字符串庫?這是一種使計算機能像操縱數字同樣容易操做字符串的方法。什麼是文件系統?這是一種僞裝硬盤驅動器不是一堆能夠在特定位置存儲二進制數據位的旋轉磁盤,而是一個文件夾內文件夾的分層系統,其中包含單個文件,這些文件又由一個或多個字節串組成。
回到以前的TCP。早些時候,爲了簡單起見,我撒了個小謊,有些人如今耳中已經涌出了怒氣,由於謊話使得你瘋狂。以前我說TCP保證你的消息會到達。 實際上並不是如此。 若是您的寵物蛇將鏈接計算機之間的網線咬斷了,那麼沒有任何IP數據包能夠經過,天然經過TCP方式傳輸的任何數據都到達不了,天然你的消息沒法到達。 與此同時若是公司中的系統管理員懲罰你,將你的網絡分配到一條過載的集線器上,只有部分IP數據包可以經過,儘管此時TCP能夠工做,可是一切都會變得很是慢。
這就是我所稱作的*抽象漏洞(leaky abstraction)*。TCP嘗試在一條極不穩定的網絡線路上提供穩定的服務,可是因爲網路漏洞的限制,致使這種抽象並不能平穩的保護你的數據。這僅僅是我爲了闡述抽象漏洞所闡述的一個例子:
> 某種意義上任何有意義的抽象都是由漏洞的
> - All non-trivial abstractions, to some degree, are leaky.
抽象失敗。有時比較少,有時卻不少。有存在漏洞的。有出錯的。當你有抽象的時候,漏洞總會。下面是一些例子。
- 有時就像在大型二維數組上迭代,純水平、垂直方向操做可能具備徹底不一樣的性能,單純的一個方向所產生的錯誤可能會大於操做另一個方向。即便程序員僞裝他們擁有一個大的平面地址空間(實際上也是真是內存的一個抽象),當出現錯誤時,肯定的物理空間提取數據比其餘空間更耗時。
- SQL語言旨在抽象出查詢數據庫所需的過程性步驟,而只容許您定義所需的內容,並讓數據庫肯定查詢數據庫的過程性步驟。但在某些狀況下,某些SQL查詢比其餘等價查詢查詢慢數千倍。一個著名的例子是,即便結果集相同,若是指定「where a=b and b=c and a=c」,那麼一些SQL服務器的速度要比只指定「where a=b and b=c」快得多。你沒必要關心程序,只須要規範。可是有時候抽象會泄露並致使糟糕的性能,你須要跳出查詢計劃分析器,研究它作錯了什麼,並找出如何使查詢運行得更快。
- 即便像NFS和SMB這樣的網絡庫容許您將遠程機器上的文件「看成本地的」來對待,但有時鏈接變得很是慢或中斷,文件中止工做就像本地同樣,而且做爲程序員,你必須編寫代碼來處理這個問題。「遠程文件與本地文件相同」的抽象就泄露。這裏是UNIX系統管理員的一個具體例子。若是您將用戶的主目錄放在NFS掛載的驅動器上(一個抽象),而且你的用戶建立.forward文件以將其全部電子郵件轉發到其餘地方(另外一個抽象),此時NFS服務器在新電子郵件到達時關閉,則不會轉發消息,由於.forward文件找不到。抽象中的漏洞實際上引發了一些消息被拋棄。
- C++字符串類應該讓你以爲字符串是一流的數據。他們試圖抽象出字符串並讓你其表現像整數同樣簡單。幾乎全部C++字符串類都重載+運算符,所以能夠編寫S+「bar」來鏈接。可是你知道嗎?無論他們怎麼努力,在地球上沒有C++字符串類,可讓你鍵入「foo」+「bar」,由於C++中的字符串文字老是char *,歷來沒有字符串。抽象出現了一個漏洞,語言不容許你插入。(有趣的是,隨着時間的推移,C++演進的歷史能夠被描述爲試圖在字符串抽象中插入漏洞的歷史。爲何他們不能只給語言添加一個本地字符串類)
- 下雨的時候你不能開得那麼快,儘管你的車有擋風玻璃的雨刷、前燈、車頂和加熱器,這些都是起到保護你的做用,讓你不要擔憂下雨的事實,可是你仍舊得擔憂水上滑行。在英國,有時雨很大,你看不見前面很遠的地方,因此在雨中須要放慢速度,由於天氣永遠不可能徹底被抽象出來,由於抽象法則有漏洞。
抽象漏洞法則有問題的一個緣由是,抽象並無真正簡化咱們的生活。當我培訓某人成爲C++程序員時,若是我歷來沒有教過他們關於字符型指針和指針算法的話,而是能直接進入STL字符串,那就很好了。可是有一天他們會編寫字符串拼接的時候,「foo」+「bar」,真正奇怪的事情就會發生,不管如何,我必須停下來教他們關於字符指針的全部知識。或者有一天,他們沒法調用具備具備OUT LPTSTR參數的Windows API函數,直到他們瞭解了char*、指針、Unicode、wchar_t、TCHAR頭文件。
在向某人教授COM編程時,若是我能教他們如何使用Visual Studio嚮導和全部代碼生成特性就行了,可是若是出了什麼問題,他們就不知道爲何以及怎麼調試它、修復它。所以我要教他們全部關於IUnknown、CLSID、ProgIDS...,天哪,還有好多細節要講!
在教授有關ASP.NET編程的知識時,若是我能教給他們,他們能夠雙擊一些東西,而後在用戶單擊這些東西時編寫在服務器上運行的代碼,那就太好了。可是實際上,ASP.NET抽象了編寫HTML代碼以處理對超連接(<a>)的單擊事件和處理對按鈕的點擊的具體細節。問題:ASP.NET設計者須要隱藏的細節是,沒法從HTML的超連接提交表單。他們的作法是,經過編寫幾行JavaScript並將之附加到超連接來實現這一點。很明顯,會有抽象的漏洞,若是最終端用戶禁用了JavaScript,ASP.NET應用程序就不能正常工做,而且若是程序員不理解ASP.NET在這個行爲背後抽象了什麼,他們就不會知道什麼地方出錯了。
抽象漏洞法則意味着,每當有人提出一個全新的使人眼花繚亂的代碼生成工具,它使咱們工做變得高效,您就會聽到不少人說「首先學習如何手動完成,而後使用自動化工具來節省時間。代碼生成工具就是人們嘗試去抽象一些工做,進行包裝。這僅僅可以節省咱們的工做時間,卻不能節省咱們的學習成本。
矛盾的是全部的這些都意味着,編程工具變得愈來愈高級,愈來愈抽象,可是這使得咱們成爲一個熟練的程序員變得更加困難。
在我第一次微軟實習期間,我編寫了在Macintosh上運行的字符串庫。一個典型的任務:編寫一個Strcat版本,執行結果會返回指向新字符串結尾的指針。幾行C代碼。這是正確的作法,這些是從K&R(一本關於C語言的很薄的書)中學習的。
今天,爲了在CityDesk工做,我須要去了解Visual Basic、COM、ATL、C++、InnoSetup、Internet Explorer內部結構、正則表達式、DOM、HTML、CSS和XML。
十年前,咱們可能已經想象到,新的編程範式將使編程變得更容易。事實上,這些年來咱們建立的抽象確實使得咱們處理軟件開發中的複雜性變得簡單,這些複雜性在10或15年前咱們沒必要處理,好比GUI編程和網絡編程。雖然這些很優秀的工具,像現代的面向對象的編程範式,讓咱們快速完成許多工做。可是忽然有一天咱們發現一個問題,是該種範式的抽象漏洞,修復它須要2周。而且當你須要僱傭一個程序員來使用VB編程時,很明顯VB程序員是不夠的,由於每次發現VB抽象漏洞時,他們都會徹底陷入焦慮中。
抽象法則正在拖累咱們。
本文章翻譯自 Joel Spolsky 的 [The Law of Leaky Abstractions](https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/) 算法
免費領取驗證碼、內容安全、短信發送、直播點播體驗包及雲服務器等套餐
數據庫
更多網易技術、產品、運營經驗分享請點擊。 編程
相關文章:
【推薦】 6月第5周業務風控關注 | 《網絡安全等級保護條例(徵求意見稿)》本週正式發佈
【推薦】 如何讓你產品的用戶擁有一流的上傳體驗
【推薦】 網易寶系統架構之我見:高可用篇
數組