1. 程式人生 > >《Web全棧工程師的自我修養》讀書筆記 《Web全棧工程師的自我修養》讀書筆記

《Web全棧工程師的自我修養》讀書筆記 《Web全棧工程師的自我修養》讀書筆記

《Web全棧工程師的自我修養》讀書筆記

 

【宣告】

歡迎轉載,但請保留文章原始出處→_→

生命壹號:http://www.cnblogs.com/smyhvae/

文章來源:http://www.cnblogs.com/smyhvae/p/5243181.html

【正文】

豆瓣連結:https://book.douban.com/subject/26598045/

【目錄】

  • 01 什麼是全棧工程師
  • 02 如何成為全棧工程師
  • 03 從學生到工程師
  • 04 野生程式設計師的故事
  • 05 工程師事業指南
  • 06 全棧工程師眼中的HTTP
  • 07 高效能網站的關鍵:快取
  • 08 大前端

什麼是全棧工程師

全棧工程師(Full-Stack Engineer):一個能處理資料庫、伺服器、系統工程和客戶端的所有工作的工程師。根據專案的不同,客戶需要的可能是移動棧、Web棧,或者原生應用程式棧。

全棧:表示為了完成一個專案,所需要的一系列技術的集合。應該從能力和思維方式兩方面,來判定一個人是否是一個合格的全棧工程師。簡單來說*全棧工程師就是可以獨立完成一個產品的人。

1、Web開發流程

大中型網際網路公司的產品研發流水線:產品設計-->互動設計-->視覺設計-->前端開發、後臺開發-->測試-->釋出。

產品經理:產品經理其實是對一個產品負根本責任的管理者。他通常的工作包括制訂產品規劃、協調多方資源、把控產品方向和質量細節,等等。有時候,他會從頭策劃一個新的產品,而更多的時候,他是在優化已有產品的一個部分。總之,在流水線中,產品經理需要從策劃跟進到釋出,是一個非常重要的角色。

使用者研究員:使用者研究員的工作是研究使用者行為,有時候他會從巨集觀的角度分析資料,有時候也從微觀的角度分解使用者場景,有時候會召集一些使用者專門來訪談,或者觀察使用者對產品的使用情況。從輸出品的角度來說,使用者研究員一般輸出使用者研究報告來交付給產品經理和互動設計師,作為產品設計的目標參考。
互動設計師:互動設計師常被簡稱為“互動”。他與視覺設計師最大的區別是,互動設計師更多著眼於如何優化使用者介面的資訊分佈和操作流程。互動設計師的輸出品一般是描述使用者與網站“互動”過程的流程圖,以及描述頁面資訊結構的線框圖。輸出的線框圖會交付給視覺設計師。

視覺設計師:在細分互動設計師和視覺設計師的大公司,視覺設計師根據互動設計師輸出的線框圖來做一些潤色和設計,輸出最終的產品視覺稿之後將視覺稿交付給前端工程師。在一些不細分互動設計師和視覺設計師的小公司,二者被統稱為“設計師”,他們的職責就是負責整個使用者介面的設計。

前端工程師:產品視覺稿在得到產品經理和互動設計師等多方確認之後,會交給前端工程師,由前端工程師製作頁面,實現視覺稿以及互動功能。從頭銜上的變化就可以看出,這時候才真正開始編碼。前端工程師需要非常熟悉HTML、CSS和JavaScript,以及效能、語義化、多瀏覽器相容、SEO、自動化工具等廣泛的知識。

後臺工程師:使用伺服器程式語言,進行伺服器功能的開發。在程式語言的選擇上,很多公司都會出於團隊已有成員的知識儲備、程式設計師的供給量或者語言效能方面來進行選擇。在這一方面,後臺語言的選擇是相對自由的一件事,不像前端工程師,為了頁面相容性,必須使用HTML和CSS。如果關注各大公司招聘資訊的話,您就會了解,不同公司使用不同的後臺語言,比如傳統的C#和C++、Java、PHP,或者新潮的RoR和Python。小公司的後臺工程師除了負責功能開發,可能還會負責伺服器的配置和除錯、資料庫的配置和管理等工作。在大公司,這些工作會分別委派給後臺工程師、運維工程師、資料庫管理員(DBA)等崗位。

運維工程師:運維工程師是跟伺服器打交道的人,他會關注伺服器的效能、壓力、成本和安全等資訊。

測試工程師:顧名思義,測試工程師保證產品的可用性,即使在小公司,這一職位也是不可或缺的。

備註:在專案管理中,經常會用到甘特圖。甘特圖(Gantt Chart)是柱狀圖的一種,顯示專案、子專案、進度以及其他與時間相關的系統的進展情況。

2、技術的發展

提到全棧技術,不得不提一個代表性的全棧框架——MEAN,它是MongoDB-Express-AngularJs-Node.js的縮寫,是從資料庫、伺服器到前端頁面的一個完整技術棧。

MongoDB是一個面向文件的、NoSQL型別的資料庫。MongoDB顛覆了傳統的基於表的資料儲存方式,而採取了類似JSON的文件結構來儲存資料,因而它在儲存資料時可以更加靈活。

Express是一個Node.js框架,可以建立靈活的Web服務,比如單頁面應用程式、多頁面應用程式和混合型App。

AngularJS是一個開源的JavaScript框架,由Google和開源社群共同維護,它用來建立單頁面應用程式。它的目標是使用model-view-controller模式來規範Web應用程式,讓開發和測試富互動的單頁面應用程式變得更加輕鬆。

Node.js是一個執行在伺服器端的JavaScript執行環境,它的底層是基於Chrome的JavaScript執行環境——V8引擎。Node.js可以作為伺服器端語言,用來建立快速、可擴充套件的應用程式。Node.js也可以在本機執行,做一些本地操作,比如加速本地開發流程,或者實現一鍵釋出。

MEAN可以說是傳統的LAMP方案的有力競爭者。因為從伺服器端到頁面端都採用同樣的語言(JavaScript)和同樣的架構模式(MVC),所以一個擅長JavaScript的工程師可以兼顧前後端的開發,並且前端模板程式碼和後臺模板程式碼是可以複用的。

3、提供PaaS服務的平臺越來越多

隨著Web技術的發展和開源社群的積極努力,有很多公司提供便宜又方便的一條龍服務,可以解決獨立開發者的大量麻煩。

比如Amazon提供的PaaS(Platform as a Service,平臺即服務),就可以讓創業公司的開發者省去架設和維護伺服器的麻煩。

而GitHub在2012年獲得了一億美元融資,也可以看出市場對程式碼託管市場的信心。可以預期,未來可能會出現越來越多為開發者提供服務的公司。以後,小公司也可以用更低廉的價格獲得世界級的IT服務支援,毫無疑問,更多的IT服務將託管在第三方的伺服器上。

VPS(Virtual Private Server,虛擬專用伺服器)是把一臺物理伺服器虛擬成多個虛擬專用伺服器的服務。每個VPS都可分配獨立的公網IP地址,執行獨立的作業系統,擁有獨立的磁碟空間、記憶體、CPU資源、程序和系統配置,模擬出“獨佔”使用計算資源的體驗。

4、一專多長

我跟一位行業專家討論過全棧工程師的話題,他不是很贊同全棧工程師這個方向。他認為,工程師應該有專精的技能和目標,如果初學者貪圖大而全,反而樣樣不精。我理解他的擔心,如果一個工程師沒有堅實的基礎(比如專業理論知識,對常用設計模式的理解,或者特定職業的基礎知識),那麼瞭解的非本專業技能越多,越容易迷失。

所以我認為,全棧工程師首先要“一專多長”。一專多長的意思是,工程師首先有一個專精的方向,在這個方向上足夠精通之後(高階工程師級別),以此為突破點去學習更多的知識,增加自己的長處。如果還沒有獲得某個方向上足夠深入的理解,就不要囫圇吞棗地去學習其他領域的知識。

有些知識需要時間的積累,並不是快速閱讀就可以掌握的。“全棧工程師”這個名詞可能會引起讀者的誤解。勿在浮沙築高臺,“全棧”是一個長期積累的過程,是專精型工程師在不斷解決問題的過程中積累知識和經驗所形成的能力,而不是一蹴而就的過程。

5、解決問題,而不是醉心技術

公司存在的意義就是解決問題,公司要解決使用者的問題,而員工要解決公司的問題。

公司的問題可能是降低成本、擴大使用者群、增加成交量、優化效能,等等。不同的問題優先順序不一樣,投入同樣的時間,有的專案能為公司增加上百萬的收入,而有的專案卻只能增加幾萬。

網際網路領域發展很快,問題的優先順序永遠都是在動態變化的,所以團隊往往每半年或者三個月就要回顧一下當前形勢,並制定新的工作計劃。如果新計劃不是您擅長的,怎麼辦?您應該馬上開始學習新的技術,這就是我說的關注問題,而不是醉心技術

高階工程師可以選擇往上下游去擴充套件自己的能力,並承擔更多的責任,給公司帶來更大的收益,也給自己帶來更大的成長空間。程式設計師在小公司裡主動去承擔更多責任,自己跟公司都會獲得相應的成長。在自由職業市場,全棧工程師是最閃耀的明星。全棧工程師還是天生的創業者。

延伸閱讀:

  • 《黑客與畫家》(美)保羅·格雷厄姆,人民郵電出版社
  • 《專業主義》(日)大前研一,中信出版社

如何成為全棧工程師

1、先精後廣,一專多長

推薦採用“先精後廣,一專多長”的流程來學習:先在一個特定的方向上有比較深入的鑽研,然後再將學習目標漸漸推廣開來。比如先從前端方向入手,掌握了基本的HTML、CSS、JavaScript之後,不要轉頭向伺服器端語言或者App方向發展,而是深入到效能優化、SEO、多種框架、響應式頁面等前端細節中去。經過一到兩年的深入研究之後,再去學習其他方向。

採用這種方式來學習,不光可以觸類旁通、舉一反三,還讓我們學習得更快,而且循序漸進更符合一般人的職業生涯發展。

騰訊社交使用者體驗設計部招聘前端開發,要求如下:

  • 本科以上學歷。
  • 兩年以上工作經驗。
  • 精通HTML、CSS、JavaScript等前端相關技術,熟悉W3C網頁標準。
  • 熟悉至少一種後臺語言的開發機制(如Java、C++等)。
  • 有一定架構能力和演算法能力,有良好編碼規範。
  • 良好的學習能力、溝通能力,追求完美,有工作激情,能在較大強度下工作。
  • 熱愛網際網路,喜歡研究各種網際網路技術者更好

有的競爭者提到他很擅長頁面效能優化、響應式、頁面渲染效率,有的寫過JavaScript框架……你需要在招聘要求的方向上以200%的能力來得到這個職位。

2、圍繞商業目標

老闆僱用一個員工,不是因為他能寫程式,而是因為他能幫助自己賺錢。

我喜歡這樣的態度:對未來有自己的方向,但也知道自己沒法看得太清晰。對商業和市場有想法,而且自己也有足夠的技術能力和自信向未來前進

記住,當您只有一把錘子,您看什麼都是釘子。而如果您痴迷於工具,反而看不到問題所在。因此,要先看看有哪些問題需要解決,然後再補充您的工具箱。永遠從商業目標的角度來決定學習哪些東西,而不是純粹為了鍛鍊技術能力而去學習。

3、使用者是誰

這裡的“使用者”仍然是一個廣義的定義:所有您為之服務的人。

4、大巧若拙

大巧若拙:指真正聰明的人,不會顯露自己,反面從表面看好像還很笨拙。使用者體驗不只是介面和互動這樣可以直觀感受的東西,還包括一些隱藏在使用者介面背後的細節和規範
就像冰山,露出水面的部分只佔整個冰山的1/9,使用者看到的只是顯露出來的部分。背後的部分一般使用者是看不到的:比如使用者研究,用研團隊會通過調查,輸出一些使用者畫像,影響整個產品的功能方向、設計風格;還有設計規範,設計團隊在設計產品的一開始制定了規範之後,新增加的功能和頁面都必須遵循已有的設計規範,這樣整個產品是統一的,能夠給使用者專業的感覺。

我如果開創一個公司需要招聘“全棧工程師”,我要求的三個能力:一專多長關注商業目標關注使用者體驗

延伸閱讀:

  • 《重來:更為簡單有效的商業思維》 (美) 賈森·弗裡德 / (丹) 戴維·海涅邁爾·漢森,中信出版社
  • 《精益創業》(美) 埃裡克·萊斯,中信出版社

從學生到工程師

前端工程師要有一個基本常識,那就是結構、表現和行為要分離。具體解釋如下:

  • 網站的內容使用語義化的HTML標籤,而不摻雜任何表現和邏輯;
  • 網站樣式表現用CSS來描述,既能在多個頁面之間複用,也可以根據不同使用者來分別定義外觀;
  • 頁面行為邏輯用JavaScript來實現,這樣保證瀏覽器在禁用JavaScript的時候,頁面也能正常渲染和使用。

崗位優先於公司,即使在一個很好的公司裡面,如果只是做著自己不喜歡也不擅長的工作,那能有什麼前途呢。

其實我的設計知識僅限於自學,來自於一本書——《寫給大家看的設計書》。這本書非常入門,但是淺顯易懂,既有設計理念,也有實際操作,到現在為止我反覆看了3遍以上。

我理解了書裡說的設計四大原則對齊、對比、距離和重複。雖然我基本沒有設計經驗,只會一些基本的Photoshop操作,但我理解了這幾個原則,每次看到好的設計和差的設計時,都能有所感悟。如果不理解,可能我只能用“上流”“高階”“簡約”這樣空泛的詞彙來描述設計。關於設計原則,我在後面的章節中會單獨提到。

校園招聘是很多大公司很喜歡的一個人才渠道,因為比起社會招聘的應聘者,畢業生更加有空杯心態、更正能量、更有激情,雖然缺少經驗,但是經過一兩年的培訓也能很快成為團隊骨幹。而如果是本身有專案經驗的畢業生,或者是在GitHub上有知名作品、知名部落格、去過其他大公司實習的畢業生,那就更加搶手了。至於大學考試成績,影響不大。
社會招聘的目標是有經驗者,招聘時間沒有校園招聘那麼固定,隨時都可能有職位空缺,但是每次放出的名額不會很多。而且這時候會根據招聘崗位,有針對性地考核應聘者的專業能力與綜合能力,導致社招的競爭是非常激烈的。
相對而言,我認為校園招聘的門檻並不高,重要的是找對方法。如果您的學校不是頂級,您的成績不是學霸,那就要走不尋常的道路。

1、獲得面試機會

無論您是名牌大學的高材生,還是自學成才的專科生,在製作第一份簡歷的時候,我有這樣幾個建議:

  • 首先確定自己的求職意向,針對特定意向填寫您的簡歷。
  • 如果您想表達出自己的創意,不要使用各大招聘網站提供的簡歷模版。
  • 把簡歷傳送到真正在招人的企業主管那裡。

舉一個例子,作為程式設計師和設計師,作品是排名最高的訊號。在著名開源專案中貢獻程式碼,說明您有能力閱讀和編寫好的程式碼,這是公司直接需要的技能。此外,這還能說明您有能力與他人協作:開原始碼總是需要協作的。開源專案還能表明您對新鮮事物有熱情,表明您也許英語能力不錯,有查閱文件的能力……一個開源專案需要的精力也許不會特別多,但它的加分點可就非常多了,簡直是一箭N雕!

為什麼要把簡歷傳送到真正招人的企業主管那裡?因為HR沒有能力辨別技術能力的高低,他只能根據學歷、分數等硬指標來篩選。所以一些技術能力優秀但是分數不高的同學可能就很遺憾地失去了面試機會。

2、實習

實習能提升自己的實踐能力,可以認為是從學生到社會人士的一個身份過渡。建議:

  • 記住團隊裡的每一個人
  • 有任何問題,主動問導師
  • 主動介紹自己,告訴大家自己是新人,請多關照
  • 每週發郵件記錄心得總結、經驗教訓、學習成長
  • 實習結束時,用郵件總結所有專案,給出交接文件,並向大家致謝

延伸閱讀:

  • 《程式設計之美:微軟技術面試心得》《程式設計之美》小組,電子工業出版社

野生程式設計師的故事

野生程式設計師是指僅憑對計算機開發的興趣進入這個行業,從前端到後臺一手包攬,但各方面能力都不精通的人。野生程式設計師有很強大的單兵作戰能力,但是在編入“正規軍”之後,可能會不適應新的做事方法。

1、Web效能優化

  • 壓縮原始碼和圖片

JavaScript檔案原始碼可以採用混淆壓縮的方式,CSS檔案原始碼進行普通壓縮,JPG圖片可以根據具體質量來壓縮為50%到70%,PNG可以使用一些開源壓縮軟體來壓縮,比如24色變成8色、去掉一些PNG格式資訊等。

  • 選擇合適的圖片格式

如果圖片顏色數較多就使用JPG格式,如果圖片顏色數較少就使用PNG格式,如果能夠通過伺服器端判斷瀏覽器支援WebP,那麼就使用WebP格式和SVG格式。

  • 合併靜態資源

包括CSS、JavaScript和小圖片,減少HTTP請求。

  • 開啟伺服器端的Gzip壓縮

這對文字資源非常有效,對圖片資源則沒那麼大的壓縮比率。

  • 使用CDN

或者一些公開庫使用第三方提供的靜態資源地址(比如jQuery、normalize.css)。一方面增加併發下載量,另一方面能夠和其他網站共享快取。

  • 延長靜態資源快取時間

這樣,頻繁訪問網站的訪客就能夠更快地訪問。不過,這裡要通過修改檔名的方式,確保在資源更新的時候,使用者會拉取到最新的內容。

  • 把CSS放在頁面頭部,把JavaScript放在頁面底部

這樣就不會阻塞頁面渲染,讓頁面出現長時間的空白。

備註:每一個條目都可以進一步深層挖掘下去。Web效能優化分為伺服器端和瀏覽器端兩個方面。

此外,由於中文的歧義性,Web效能優化這個詞既可以解讀成頁面載入速度(Page Speed)的優化,也可以解讀成頁面渲染效能(Page Performance)的優化。或者是二者的集合。所以,應聘者如果能在這個問題上多做一些分析,會有很高的加分。但是如果你在網路效能方面的研究只是淺嘗輒止,停留在壓縮資源方面,這說明你還沒有足夠理解HTTP協議本身。

關於網路效能和HTTP協議,作為大公司的前端工程師是非常看重的,因為每一個頁面都會有億萬使用者訪問量,任何一點對伺服器頻寬壓力都會積少成多,最終造成很大的成本。關於這方面的技術詳解,我在後面會有一篇單獨的文章來分析。

2、知易行難

我問一個面試者:“關於伺服器端MVC架構的技術實現,您是怎樣理解的?”他說:“是資料模型、檢視、控制器的分離。”

我更進一步問道:“這種架構方式有什麼好處?您在專案中是如何應用這一架構的?”他回答說:“MVC的架構方式會讓專案可維護性更高,所有涉及介面的程式碼都在檢視(View)裡面,所有涉及核心邏輯的程式碼都在模型(Model)裡面,URL路由之類的程式碼都在控制器(Controller)裡面。我在專案中使用了MVC架構的PHP框架——CodeIgniter。”

我一邊開啟他的網站,一邊繼續跟他電話溝通。當看到網站的CSS程式碼都直接內嵌在HTML頭部的時候,我忍不住問他:“為什麼您的網站的CSS程式碼都內嵌在HTML裡面呢,是使用自動化工具合併進去的嗎?”他支支吾吾地說:“因為在本地除錯的時候,CSS檔案修改經常不生效,所以就直接在HTML裡面改了,這樣比較快。”

好吧,我想這是一個典型的“知易行難”的開發者,他知道採用MVC架構的專案的可維護性更高,可是在分離樣式與結構上面還沒有達到最基本的要求,甚至把CSS寫在HTML中。至於他說的在本地環境上發現CSS檔案經常快取,可能要看看本地伺服器的快取設定是否有問題,然後再做除錯。稍微瞭解一點HTTP的瀏覽器端快取,這就不是難事了。我更欣賞在開發流程上花工夫去理解和優化的應聘者,而不是馬馬虎虎,只是以完成需求為目標的人。

3、什麼是“野生程式設計師”

野生程式設計師”:就是沒有計算機基礎知識和相關教育經歷,靠著對計算機開發的興趣進入這個行業,雖然知識面比較廣,但是各方面都一知半解的開發者。

這幾年我從一個求職者,轉變成一個招聘者,有一個感受就是,中國高等教育與市場需求不接軌。學校不瞭解市場究竟需要什麼樣的人才,其設立的課程和技術往往比市場技術現狀落後了5年以上。我在大學學習用ASP建站,但是現在已經幾乎沒有人用ASP建站了。一個直接的後果是,很多高校畢業生不能滿足企業的要求。

與此同時,中國網際網路市場蓬勃發展,特別是移動網際網路的發力,讓中國跳過“WAP時代”,直接進入“App時代”。市場的熱錢都投入到網際網路行業,“BAT”等大公司不斷擴張,創業公司也如雨後春筍,整個市場對軟體工程師的需求缺口巨大,所以很多公司在招人的時候,沒法招聘到“專業”的計算機專業畢業生。

在美國,因為教育與市場穩定發展了很多年,供求關係相對平衡,計算機相關專業本科已經成為基本要求。舉例而言,美國的矽谷公司(如Google)絕大部分前端開發招聘崗位都有一個最低要求——本科學歷,計算機相關專業。

相比而言,從中國的大公司(如騰訊)的招聘網站上可以看出,有一些前端開發崗位沒有對學歷的要求,也有一些要求“本科及以上學歷”,少數才會要求“本科學歷,計算機相關專業”。我們的團隊中就有一些成員是大專學歷。許多企業在招聘的時候往往放鬆了對學歷的要求,只看重專案和經驗,而不看重學歷。這是一件好事,代表市場在高等教育的規模和質量都跟不上市場要求的情況下,給予更多有興趣和能力的年輕人進入IT領域的機會,也填補了人才市場的空缺。

美國矽谷,是世界網際網路公司的中心,是所有求職者夢寐以求的聖地。在最開始,矽谷之所以名字當中有一個“矽”字,是因為當地企業多數是從事加工製造高濃度矽的半導體行業和電腦工業。隨後,網際網路公司和軟體公司漸漸取代傳統的硬體公司,讓矽谷獲得了新的生命,但矽谷這個名字保留了下來。在矽谷從誕生到發展壯大的整個生命週期中,斯坦福大學起到了很大的作用,我認為稱之為矽谷的母親也不為過。

在中國,由於政策、環境、歷史原因,還有大學教育投入上的差異,導致大學在整個網際網路發展中起的作用沒那麼大。中美兩國IT人才市場供求關係上的這些差別,也反映在整個行業文化中。

一個直觀的反映就是軟體工程師的“草根”化。其實很多軟體工程師的收入都很高,處於中上層水平,相比金融行業的白領也毫不遜色,但是一談起程式設計師,大家的印象還是“一年四季的T恤(在行業展會上免費拿的)牛仔褲,平時也喜歡宅在家裡,不會像同樣收入的金融白領,平時愛好聽歌劇打高爾夫球”。這種差異一方面是外部人士對軟體工程師職業的偏見,另一方面也是程式設計師行業的自黑習慣。在招聘時崗位要求就已經放到最低:不要求學歷、上班不要求著裝、上下班時間靈活,這樣才好更方便地招聘。而金融行業有意識地塑造一種“精英”文化,從學歷就設定高門檻,即使有些工作根本不需要那麼高的學歷。

回到畢業生的話題,很多跨專業的學生髮現自己興趣在網際網路和計算機方向的時候,就開始了自學之路,基本上學習方式有這樣幾種:

:在計算機圖書領域,技術難度跟圖書銷量是成反比的,從標籤教起的HTML/CSS基礎書籍賣得最好,其次是關於JavaScript和jQuery的書,Angular和Node.js之類的就沒那麼暢銷了。

網際網路:得益於全世界都在網際網路上共享的資源,現在的學習者有了更多的選擇,比如關於Web開發基礎教學的W3CSchool,還有海量的技術部落格。我個人喜歡訂閱一些英文大站,比如Smashing Magazine(http://www.smashingmagazine.com/)、tuts+(http://tutsplus.com/)等。我在讀大學的時候,GoogleReader還沒有永久關閉,那時候我很喜歡用RSS來關注這些站點的更新情況。Google Reader下線後,就基本上廢棄了RSS閱讀的習慣,轉而用一些社交網站來追蹤更新情況,但是有時還是會淹沒在大量無用的資訊裡面。

社團:學校的網站社團也孕育了許多能力很強的開發者,社團經過歷屆的傳幫帶,技術有所積累,比如師兄會教師弟用Sublime編輯器,這就比還在用Dreamweaver的同學更有優勢。此外,學校社團有一些定點客戶,比如學校教務處、周邊商戶,所以有更多的實戰經驗,在畢業時作品集也豐富了不少。

因為有這樣一些自學渠道,所以不一定只有計算機專業畢業的學生才有機會進入網際網路行業。畢業之後,這些計算機愛好者進入不同的工作崗位,不同的是,有些進入大公司,有些進入小公司。這兩者的成長軌跡往往會不太一樣。

4、大公司還是創業公司

如果你是畢業生,這種情況下我還是建議選擇大公司,因為會選擇創業公司的人往往有自己的主見,已經接受創業公司的邀請去工作了,不會去發帖詢問大家的意見。當然這是開玩笑,真正的原因是,在大公司的頭兩年,是從學生到職場人士的一個轉變,您可能會從大平臺學習到一些規範的流程方法,養成一些足以影響您一生的習慣,認識更多的能對您職場有幫助的人脈

大公司能給你的有:

  • 較小的風險

每個公司都有倒閉的可能,但是,顯然大公司比小公司的風險低多了。如果您的風險承受能力較低,那麼不得不考慮這個因素。

  • 技術最佳實踐

在大公司,對程式碼質量和一致性的要求很高,所以一般在最終釋出前會有程式碼審查(Code Review)流程和專案總結會等。如果您完成了一個任務,但是沒有采用最佳實踐,只是hack了一下,那麼其他同事可能都會指出您的問題,並且要求您改正之後再提交。小公司或者創業公司人力比較緊張,在他們看來,快速實現和上線,比優雅地上線更重要,所以對於一些最佳實踐類的問題,只能睜一隻眼閉一隻眼啦。

  • 垂直專精的技能

大公司專業分工很細,而且有更多技術溝通和沉澱的氛圍,所以容易讓人在垂直專精的技術方向有足夠的發展。在小公司更能鍛鍊技術的廣度,深度上缺乏鍛鍊的環境。但是其實二者的利弊,都是外界的,技術人員的個人成長除了工作時間的鍛鍊,還要靠下班後的時間,外界只是給予一個環境或者機會。

  • 服務海量使用者的經驗

同樣是做一個網站,服務少數使用者量和服務海量使用者量時需要考慮的事情是完全不同的。小網站遇到的問題,大網站一定遇到過,而大網站遇到的問題,小網站就不一定遇到過了。當一個網站發展到業內最強時,它的問題沒有人遇到過,這時候就不能凡事問百度、Google或Stack Overflow了,而要自己去探索解決方案。

  • 軟技能

硬技能是指每個職位需要的專業技能,軟技能則是通用的技能,比如溝通、影響力、專案管理和演講等。越是大公司,越是看重影響力,所以會有很多培訓教您如何提高影響力。

我在面試一些來自小公司的應聘者時,就發現他平時的工作中,周邊環境很少有分享和沉澱的習慣。沉澱和總結是很重要的,在騰訊,設計師做完一次設計定稿之後,就會把設計的思路,包括整體的設計風格、設計規範和色彩的確定等都總結成一封郵件或者PPT,傳送給部門同事。每個人都要有意識地維護自己的作品集,它在半年一次的考核、晉升面試甚至以後的跳槽中都非常有用。但是小公司的設計師不太會總結個人作品集,時間緊急是一方面原因,另一個主要原因是環境不需要他這樣做,因此就缺乏了這方面的鍛鍊。

  • 人脈

每年都有不少人從大公司離職去創業,這是非常自然的事情。對於大公司出來的人來說,之前積累的人脈資源這時候會起到很大的作用,比如創業期間的一些合作機會或者資源的互利,等等。萬一創業失敗,也不會很慘,因為您之前接觸的人脈可以給您提供工作機會。但如果您剛畢業就選擇創業,創業失敗之後沒有人能給您提供工作機會。

  • 心態

其實大公司能給予畢業生最大的優勢,就是提供一個心智培育的土壤。之前參加面試官培訓的時候,我大概瞭解過公司招聘一個畢業生投入的成本。從校園招聘,到安排面試官面試候選人,再到封閉培訓和一些課程培訓,再給一段時間熟悉專案,最後3個月試用期後可能還要淘汰掉一些。如果把成本平攤到每一個人身上,這些投入要一年才能收回來。而小公司不會有這麼大的耐心去培育一個新人。如果沒有足夠的時間去學習和成長,可能在一兩年後,員工的能力也比較全面,但是樣樣都不精通,也說不清楚自己的目標是什麼,於是就變成了“野生程式設計師”。

綜合來講,在大公司中,從硬技能到軟技能都會有很多經驗豐富的前輩能夠教您,您會在大平臺上學習到很多東西。工作幾年之後,員工的選擇也很多,要麼走技術路線繼續發展下去,做高階工程師;要麼學習管理和領導力;要麼出去創業。

所以,我的個人建議是,從畢業生自己前途發展的角度來看,先加入一家上市大公司是個不錯的選擇。

延伸閱讀:

  • 《打造Facebook》王淮, 印刷工業出版社

工程師事業指南

我曾讀過一本有意思的書,《您就是極客》,副標題是“軟體開發人員生存指南”。其中第二章專門講軟體工程師事業的3個關鍵詞:技術、成長和聲望。前面的文章裡已經講了技術和成長,現在我們來談談聲望。

1、重視作品集

作品集(portfolio),是指您個人的專案和作品的集合,一份精心準備的作品集比簡歷更能說服人。

我很重視作品集,一方面體現在我很在意維護自己的作品集,另一方面我也很喜歡面試的時候看到應聘者有自己的作品集。除了工作上安排的專案,我更在意一些課外專案,因為它展示了您的興趣和熱情所在。

從某種程度上來講,重視展示專案這種態度確實會對程式設計的純粹性有所腐蝕(如果您程式設計本身只是為了自己的興趣),您編寫一個專案的動機可能會從純粹為了好玩,變成獲取收益。但是在這個商業化的市場裡,對方(高效地)得到了您的資訊,您得到了您應有的評價,這對雙方是互利的。

對於程式設計師來說,成本最低的一種作品展示方式就是把自己的程式碼釋出到GitHub上。

名為“Open Source (Almoset) Everything”的一篇文章中,有這樣一句話:“If you do it right, open sourcing code is great advertising for you and your company.”如果使用得當,開原始碼是您和您的公司最好的廣告

另外,將程式碼開源,大家看到的是專案功能,而不是程式碼技巧。如果不是自己需要,沒有人會閒得幫其他人優化程式碼。如果您的想法夠好,那麼就會收穫來自社群的感謝、幫助,以及您應有的聲望。

順便提一下,如果您是擅長設計和程式設計的全棧工程師,並且對自己的設計能力非常有自信,那麼同樣推薦Dribbble。Dribbble是設計師的舞臺,它的社交性讓您的作品很容易傳播和收穫“贊”。如果是可以實際預覽的頁面,您可以在貼上設計稿之後,在下面留下站點的實際地址。

2、我想推薦的第二種方案是靜態頁(比如GitHub Pages)

GitHub Pages是GitHub在程式碼託管之外額外提供的一個非常方便的功能,它允許您建立一個gh-pages的分支(如果是使用者或者專案的主頁,就是master分支),然後向其中提交靜態資源,包括HTML、CSS、JavaScript和圖片,然後就可以通過username.github.io來訪問。

我的個人部落格就是建立在GitHub Pages上,因為我的使用者名稱是yuguo,所以對應的域名是http://yuguo.github.io/ 。如果您訪問的話,會跳轉到http://yuguo.us/,因為GitHub提供免費域名繫結功能,這簡直是業界良心,所以我綁定了自己的私人域名。

GitHub Pages的初衷是為您的專案提供一個簡單的介紹頁,它提供了一些固定的模板。在GitHub網頁上直接選擇這些模板,就會在您的某個專案中建立一個gh-pages分支,並且允許您在網頁上使用Markdown格式直接編輯index.html的內容。所以在那個時代,所有的GitHub Pages的設計都侷限於GitHub官方提供的幾套預設模板。

後來,Jekyll改變了遊戲規則。Jekyll是一個使用Ruby編寫的部落格站點編譯軟體,通過命令列來操作。使用者只需要編寫Markdown格式的內容“原始檔”,就能快速編譯出一個完整的靜態網站。技術的發展總會帶來新的應用場景,GitHub Pages與Jekyll結合在一起,發生了美妙的化學反應。現在只需要把Jekyll的日誌原始碼Markdown推送到GitHub Pages站點,就能生成一個編譯後的靜態頁。

Jekyll讓您可以利用簡單的幾行程式碼,就新建一個站點框架。

GitHub Pages支援Jekyll編譯之後,使用者只需推送原始碼到GitHub,GitHub Pages就能自動編譯。二者產生了奇妙的化學反應,GitHub Pages的靈活性變得無限大,越來越多的開發者使用GitHub託管部落格,而作品集也是一種非常適合Jekyll生成的專案。

除了Jekyll這種部落格編譯器以外,還有一些專門的靜態站點編譯器,比如Dexy。與Jekyll不同的是,Dexy更擅長產品站點和文件的編譯,比如可以直接引用某程式碼檔案到HTML中。Dexy不被GitHub原生支援,所以您可以在本地編譯出完整的靜態頁面之後,把生成的站點推送到GitHub Pages。

經常有人問我部落格託管在哪個伺服器,我會告訴他們託管在GitHub Pages,雖然速度不是特別快,但是很穩定,可用性可以保證在99.99%以上。

3、突出重點

如果作品集有一些動態生成的內容的話,可以選擇自己架設伺服器並繫結域名,VPS就是不錯的選擇。VPS成本比GitHub Pages高,因為需要付費和配置環境,但是最終跟GitHub Pages的效果是類似的。

最後我想說的是,任何作品集都需要有一個重點。如果您想重點突出自己某個技能的深度,可以針對這個技能列出大量作品、專案、專欄或者自己的書。如果想突出技能的廣度,光列出您的技能集是不能說服人的,還要在自己的GitHub上提交各種使用相關技能的專案。如果自由開發者想招攬一些客戶的話,漂亮的過往專案是最重要的。

作品集不一定是嚴謹而無趣的,曾經有一個前端開發者就將自己的作品集用一個HTML5遊戲包裝起來,讓人印象非常深刻。

看到這裡,您也許會說,有一些社交網路可以直接生成相關的作品集,比如LinkedIn、about.me等。但我的觀點是,既然身為一個全棧工程師,那麼花一點時間做一些特別的東西會更有趣,不是嗎?

通過 about.me可以生成自己的作品集,截圖來自about.me。

通過社會化媒體,樹立起個人的品牌,即使不拿名片出去,也有人知道自己,這才是應該努力的方向。有人說過,“人到三十,不要去找工作,要讓工作來找自己”,大概也是這個意思。

全棧工程師眼中的HTTP

HTTP,是Web工程師每天打交道最多的一個基本協議。很多工作流程、效能優化都圍繞HTTP協議來進行,但是我們對HTTP的理解是否全面呢?如果前端工程師和後臺工程師坐在一起玩捉鬼遊戲,他們對HTTP的描述可能會截然不同,從這兩個角色的視角看過去,HTTP呈現出截然不同的形態。

1、HTTP簡介

超文字傳輸協議(HyperText Transfer Protocol,HTTP)是網際網路上應用最為廣泛的一種網路協議。設計HTTP的最初目的是提供一種釋出和接收HTML頁面的方法。

OSI七層模型:

OSI模型義了整個世界計算機相互連線的標準,總共分為7層,其中最上層(也就是第7層)就是應用層,HTTP、HTTPS、FTP、TELNET、SSH、SMTP和POP3都屬於應用層。這是軟體工程師最關心的一層。

OSI模型越靠近底層,就越接近硬體。在HTTP協議中,並沒有規定必須使用它或它支援的層。事實上,HTTP可以在任何網際網路協議或其他網路上實現。HTTP假定其下層協議提供可靠的傳輸,因此,任何能夠提供這種保證的協議都可以被其使用,也就是其在TCP/IP協議族使用TCP作為其傳輸層。


備註:開放式系統互聯通訊參考模型(Open System Interconnection Reference Model),簡稱為OSI模型(OSI model)

關於HTTP版本:

HTTP已經演化出了很多版本,它們中的大部分都是向下相容的。客戶端在請求的開始告訴伺服器它採用的協議版本號,而後者則在響應中採用相同或者更早的協議版本。

當前應用最廣泛的HTTP版本為HTTP/1.1,它自從1999年釋出以來,距寫作本書時已有16年的時間。比起HTTP/1,它增加了幾個重要特性,比如快取處理(在下一章介紹)和持續連線,以及其他一些效能優化。

2015年2月,HTTP/2正式釋出。新的HTTP版本有一些重大更新,除了一如既往地向下相容HTTP/1以外,還有一些優化,比如減小網路傳輸延遲,並簡化伺服器向瀏覽器傳輸內容的過程。主流的伺服器(Apache、Nginx等)和瀏覽器(Firefox、Chrome、Safari以及iOS和Android的瀏覽器等)的最新版都已經支援HTTP/2,剩下的就需要網站管理員把伺服器升級到最新版了。

例子:

下面是一個HTTP客戶端與伺服器之間會話的例子,運行於www.google.com,埠80。

客戶端首先發出請求:

GET / HTTP/1.1
Host:www.google.com

上方第一行指定方法、資源路徑、協議版本。當然這是一個簡化後的例子,實際請求中還會有當前Google登入賬戶的cookie、HTTPS頭、瀏覽器接受何種型別的壓縮格式和UA程式碼等。備註:使用者代理(User-Agent),是指一串字元,表明了當前使用者使用什麼樣的代理在訪問站點。瀏覽器是最常見的一種使用者代理)

伺服器隨之應答:

HTTP/1.1 200 OK
Content-Length: 3059
Server: GWS/2.0 Date: Mon, 20 Apr 2015 20:30:45 GMT Content-Type: text/html Cache-control: private Set-cookie: PREF=ID=73d4aef52e57bae9:TM=1042253044:LM=1042253044:S= SMCc_HRPCQiqy X9j; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com Connection: keep-alive

上方程式碼中,在這一串HTTPS頭之後,會緊跟著一個空行,然後是HTML格式的文字組成的Google主頁。

介紹完關於HTTP的基本知識,我們來分別看看前端工程師和後臺工程師分別是怎樣看待這個最熟悉的小夥伴的。

2、前端視角

前端工程師的職責之一是,讓網站又快又好地展現在使用者的瀏覽器中。

從這個角度來說,對HTTP的理解是這樣的:開啟HttpWatch,然後隨意訪問一個網站,HttpWatch會按照瀏覽器請求的次序,列出開啟這個網站的時候發生的請求細節。包括如下內容:

  • 發出的請求列表。
  • 每個請求的開始時間。
  • 每個請求從開始到結束花費的時間。
  • 每個請求的型別(比如是文字、CSS、JS,還是圖片或者字型等)。
  • 每個請求的狀態碼(比如是200、還是from cache、304、404等)。
  • 每個請求產生的流量消耗。
  • 每個請求gzip壓縮前的體積,以及在本地gzip解壓後的體積。

通過檢視站點的HTTP請求資訊,可以得到很多優化資訊。每一個前端工程師都知道的基本優化方法是:儘量減少同一域下的HTTP請求數,以及儘量減少每一個資源的體積。(通過Chrome開發者工具中的PageSpeed工具,可以快速獲得關於站點效能優化的建議)

備註1:HttpWatch是一個瀏覽器外掛,它可以用來檢測頁面中所有HTTP請求。類似的工具還有Fiddler,或者各種現代瀏覽器的開發者工具中的“網路”標籤頁

備註2:gzip是一種開源的資料壓縮演算法,其中g代表免費的意思(gratis)。HTTP/1.1協議允許客戶端選擇要求從伺服器下載壓縮內容,gzip是絕大多數客戶端和伺服器都支援的壓縮演算法,它在壓縮文字檔案(比如HTML、CSS、JavaScript)時壓縮效果很好。

儘量減少同一域下的HTTP請求數:

瀏覽器常常限定了對同一域名發起的併發連線數的上限。IE6/7和Firefox2的設計規則是,同時只能對一個域名發起兩個併發連線。新版本的各種瀏覽器普遍把這一上限設定為4至8個。如果瀏覽器需要對某個域進行更多的連線,則需要在用完了當前連線之後,重複使用或者重新建立TCP連線。

QQ空間的CSS貼圖由程式自動生成,保證最佳的圖片質量、最合理的圖片擺放和最小的體積。

由於瀏覽器針對資源的域名限制併發連線數,而不是針對瀏覽器位址列中的頁面域名,所以很多靜態資源可以放在其他域名下(不同的子域名也被認為是不同的域名)。如果您只有一臺伺服器,可以把這些不同的域名同時指向一個IP,也就提高了對這臺伺服器的併發連線數限制(不過要小心伺服器壓力過大)。

把靜態資源放在非主域名下,這種做法除了可以增加瀏覽器併發,還有一個好處是,減少HTTP請求中攜帶的不必要的cookie資料。cookie是某些網站為了辨別使用者身份而儲存在使用者瀏覽器中的資料。cookie的作用域是整個域名,也就是說如果某個cookie存放在google.com域名下,那麼對於google.com域名下的所有HTTP請求頭都會帶上cookie資料。如果Google把所有的資源都放在google.com下,那麼所有資源的請求都會帶上cookie資料。對於靜態資源來說,這是毫無必要的,因為這對頻寬和連結速度都造成了影響。所以我們一般把靜態資源放在單獨的域名下。

除此之外,前端工程師經常做的優化是合併同一域名下的資源,比如把多個CSS合併為一個CSS,或者將圖片組合為CSS貼圖(這種做法被稱為sprite image)。

還有一些優化建議是省掉不必要的HTTP請求,比如內嵌小型CSS、內嵌小型JavaScript、設定快取,以及減少重定向。這些做法雖然各不相同,但是如果瞭解HTTP請求的過程,就知道這些優化方法的最終目的都是最大化利用有限的請求數。

儘量減少每一個資源的體積:

我們不光要限制請求數,還要儘量減少每一個資源的體積。因為資源的體積越大,在傳輸中消耗的流量就越多,等待時間也越久。

在面試應聘者的時候,我會問的一個基礎題目是“常用的圖片格式有哪些,它們的使用場景是什麼”。如果能選擇合適的圖片格式,就能夠用更小的體積,達到更好的顯示效果。對圖片格式的敏感,能反映出工程師對頻寬和速度的不懈追求。

此外,對於比較大的文字資源,必須開啟gzip壓縮。因為gzip對於含有重複“單詞”的文字檔案,壓縮率非常高,能有效提高傳輸過程。

對於一個CSS資源的請求耗時,我想說明兩個細節:

  • 這個CSS資源請求的體積是36.4KB(這是gzip壓縮過的體積),解壓縮之後,CSS內容實際上是263KB,可以算出壓縮後體積是原來的13.8%。
  • 整個連線的建立花費了30%的時間,發出請求到等待收到第一個位元組回覆花費了20%的時間,下載CSS資源的內容花費了50%的時間。

如果沒有設定gzip,下載這個CSS檔案會需要好幾倍的時間。

3、後臺視角

前端工程師對HTTP的關注點在於儘量減少同一域下的HTTP請求數,以及儘量減少每一個資源的體積。與之不同,後臺工程師對於HTTP的關注在於讓伺服器儘快響應請求,以及減少請求對伺服器的開銷。

後臺工程師知道,瀏覽器限定對某個域的併發連線數,很大程度上是瀏覽器對伺服器的一種保護行為。瀏覽器作為一種善意的客戶端,為了保護伺服器不被大量的併發請求弄得崩潰,才限定了對同一個域的最大併發連線數。而一些“惡意”的客戶端,比如一些下載軟體,它作為一個HTTP協議客戶端,不考慮到伺服器的壓力,而發起大量的併發請求(雖然使用者感覺到下載速度很快),但是由於它違反了規則,所以經常被伺服器端“防範”和遮蔽。

那麼為什麼伺服器對併發請求數這麼敏感?

雖然伺服器的多個程序看上去是在同時執行,但是對於單核CPU的架構來說,實際上是計算機系統同一段時間內,以程序的形式,將多個程式載入到儲存器中,並藉由時間共享,以在一個處理器上表現出同時執行的感覺。由於在作業系統中,生成程序、銷燬程序、程序間切換都很消耗CPU和記憶體,因此當負載高時,效能會明顯降低。

提高伺服器的請求處理能力:

在早期系統中(如Linux 2.4以前),程序是基本運作單位。在支援執行緒的系統(Linux2.6)中,執行緒才是基本的運作單位,而程序只是執行緒的容器。由於執行緒開銷明顯小於程序,而且部分資源還可以共享,因此效率較高。

Apache是市場份額最大的伺服器,超過50%的網站執行在Apache上。Apache 通過模組化的設計來適應各種環境,其中一個模組叫做多處理模組(MPM),專門用來處理多請求的情況。Apache安裝在不同系統上的時候會呼叫不同的預設MPM,我們不用關心具體的細節,只需要瞭解Unix上預設的MPM是prefork。為了優化,我們可以改成worker模式。

prefork和worker模式的最大區別就是,prefork的一個程序維持一個連線,而worker的一個執行緒維持一個連線。所以prefork更穩定但記憶體消耗也更大,worker沒有那麼穩定,因為很多連線的執行緒共享一個程序,當一個執行緒崩潰的時候,整個程序和所有執行緒一起死掉。但是worker的記憶體使用要比prefork低得多,所以很適合用在高HTTP請求的伺服器上。

近年來Nginx越來越受到市場的青睞。在高連線併發的情況下,Nginx是Apache伺服器不錯的替代品或者補充:一方面是Nginx更加輕量級,佔用更少的資源和記憶體;另一方面是Nginx 處理請求是非同步非阻塞的,而Apache 則是阻塞型的,在高併發下Nginx 能保持低資源、低消耗和高效能。

由於Apache和Nginx各有所長,所以經常的搭配是Nginx處理前端併發,Apache處理後臺請求。

值得一提的是,新秀Node.js也是採用基於事件的非同步非阻塞方式處理請求,所以在處理高併發請求上有天然的優勢。

DDoS攻擊:

DDoS是Distributed Denial of Service的縮寫,DDoS攻擊翻譯成中文就是“分散式拒絕服務”攻擊。

簡單來說,就是黑客入侵併控制了大量使用者的計算機(俗稱“肉雞”),然後在這些計算機上安裝了DDoS攻擊軟體。我們知道瀏覽器作為一種“善意”的客戶端,限制了HTTP併發連線數。但是DDoS就沒有這樣的道德準則,每一個DDoS攻擊客戶端都可以自由設定TCP/IP併發連線數,並且連線上伺服器之後,它不會馬上斷開連線,而是保持這個連線一段時間,直到同時連線的數量大於最大連線數,才斷開之前的連線。

就這樣,攻擊者通過海量的請求,讓目標伺服器癱瘓,無法響應正常的使用者請求,以此達到攻擊的效果。

對於這樣的攻擊,幾乎沒有什麼特別好的防護方法。除了增加頻寬和提高伺服器能同時接納的客戶數,另一種方法就是讓首頁靜態化。DDoS攻擊者喜歡攻擊的頁面一般是會對資料庫進行寫操作的頁面,這樣的頁面無法靜態化,伺服器更容易宕機。DDoS攻擊者一般不會攻擊靜態化的頁面或者圖片,因為靜態資源對伺服器壓力小,而且能夠部署在CDN上。

這裡介紹的只是最簡單的TCP/IP攻擊,而DDoS是一個概稱,具體來說,有各種攻擊方式,比如CC攻擊、SYN攻擊、NTP攻擊、TCP攻擊和DNS攻擊等。

3、BigPipe:

前端跟後端在HTTP上也能有交集,BigPipe就是一個例子。

現有的HTTP資料請求流程是:客戶端建立連線,伺服器同意連線,客戶端發起請求,伺服器返回資料,客戶端接受並處理資料。這個處理流程有兩個問題。

上圖中是現有的阻塞模型,黃色代表伺服器生成頁面,白色代表網路傳輸,紫色代表瀏覽器渲染頁面。

第一,HTTP協議的底層是TCP/IP,而TCP/IP規定3次握手才建立一次連線。每一個新增的請求都要重新建立TCP/IP連線,從而消耗伺服器的資源,並且浪費連線時間。對於幾種不同的伺服器程式(Apache、Nginx和Node.js等),所消耗的記憶體和CPU資源也不太一樣,但是新的連線無法避免,沒有從本質上解決問題。

第二個問題是,在現有的阻塞模型中,伺服器計算生成頁面需要時間。等伺服器完全生成好整個頁面,才開始網路傳輸,網路傳輸也需要時間。整個頁面都完全傳輸到瀏覽器中之後,在瀏覽器中最後渲染還是需要時間。三者是阻塞式的,每一個環節都在等上一個環節100%完成才開始。頁面作為一個整體,需要完整地經歷3個階段才能出現在瀏覽器中,效率很低。

BigPipe是Facebook公司科學家Changhao Jiang發明的一種非阻塞式模型,這種模型能完美解決上面的兩個問題。

通俗來解釋,BigPipe首先把HTML頁面分為很多部分,然後在伺服器和瀏覽器之間建立一條管道(BigPipe就是“大管道”的意思),HTML的不同部分可以源源不斷地從伺服器傳輸到瀏覽器。BigPipe首先輸送的內容是框架性HTML結構,這個框架結構可能會定義每個Pagelet模組的位置和寬高,但是這些pagelet都是空的,就像只有鋼筋混泥土骨架的毛坯房。

BigPipe頁面的渲染流程:

伺服器傳輸完框架性HTML結構之後,對瀏覽器說:“我這個請求還沒結束,我們保持這個連線不要斷開,不過您可以先用我給您的這部分來渲染。”

所以瀏覽器就開始渲染這個“不完整的HTML”,毛坯房頁面很快出現在使用者眼前,具體的頁面模組都顯示“正在載入”。

接下來管道里源源不斷地傳輸過來很多模組,這時候最開始載入在伺服器中的JS程式碼開始工作,它會負責把每一個模組依次渲染到頁面上。

在使用者的感知上,頁面非常快地出現在眼前,但是所有的模組都顯示正在載入中,然後主要的區域(比如重要的使用者動態)優先出現,接下來是logo、邊欄和各種掛件等。

為什麼BigPipe能夠讓伺服器對瀏覽器說“我這個請求還沒結束,我們保持這個連線不要斷開”呢?答案是HTTP1.1的分塊傳輸編碼。

HTTP 1.1引入分塊傳輸編碼,允許伺服器為動態生成的內容維持HTTP持久連結。如果一個HTTP訊息(請求訊息或應答訊息)的Transfer-Encoding訊息頭的值為chunked,那麼訊息體由數量不確定的塊組成——也就是說想傳送多少塊就傳送多少塊——並以最後一個大小為0的塊為結束。

實現這個架構需要深刻理解HTTP 1.1的規則,而且要有前端的知識。在我看來,這就是一個極佳的全棧工程師改變世界的例子。

截止寫書時,Chrome、Safari和Opera已經支援HTTP/2並預設開啟,它允許伺服器向瀏覽器“推送”內容。也就是說,返回的條目數可以比請求的條目數多,這樣伺服器可以在一開始就推送所有它認為瀏覽器“應該需要”的資源,而不需要瀏覽器接受並解析完HTML頁面才開始請求下載CSS、JavaScript等。而且,後面的請求可以複用之前已經建立的底層連線。

延伸閱讀
1.《圖解HTTP》(日)上野宣,人民郵電出版社
2.《高效能網站建設進階指南》(美)Steve Souders,電子工業出版社

高效能網站的關鍵:快取

Phil Karlton說過:電腦科學中最無奈的兩件事是快取失效和命名。這是可能是因為,複雜性理論方面的難題,可能最終還是有解的。而快取失效是分散式系統中最常見,也幾乎沒有最優解決方案的難題。

快取對於站點效能起到舉足輕重的作用,很多時候,優化演算法和壓縮圖片帶來的優化效果可能遠遠不如優化快取。

計算機系統中的快取有這樣幾種功效:(以圖書為例)

  • 儲存頻繁訪問的資料(這裡的資料是圖書)。
  • 記憶體快取減少磁碟I/O(不用到6樓去找書)。
  • 儲存耗時的操作,以便下次使用(找書和整理書是耗時的操作)。

下面我來談談在一個Web站點中,它的資料流從伺服器端到瀏覽器端,哪些地方可以使用快取來優化。

1、伺服器快取

對於一些計算量大的Web服務、伺服器記憶體或CPU等效能不好,或者像一些獨立開發者跟其他人共享虛擬伺服器(因此只能得到部分記憶體和CPU)的時候,伺服器的計算時間可能佔整個頁面響應時間的很大一部分。這種情況下,優化伺服器端的快取就尤為重要了。

基本的資料庫查詢快取:

我們從伺服器到客戶端,依次來講解快取的作用,首先從資料庫開始。

對於大型網站來說,資料庫裡的資料量往往是非常大的,而對於資料的查詢又是比較耗時的操作,所以我們可以開啟MySQL查詢快取來提高速度,並且減少系統壓力。MySQL預設不開啟查詢快取,但我們可以通過修改MySQL安裝目錄中的my.ini來設定查詢快取。設定的時候可以根據實際情況配置緩衝區大小、單個查詢的緩衝區大小等。

我們從伺服器到客戶端,依次來講解快取的作用,首先從資料庫開始。
對於大型網站來說,資料庫裡的資料量往往是非常大的,而對於資料的查詢又是比較耗時的操作,所以我們可以開啟MySQL查詢快取來提高速度,並且減少系統壓力。MySQL預設不開啟查詢快取,但我們可以通過修改MySQL安裝目錄中的my.ini來設定查詢快取。設定的時候可以根據實際情況配置緩衝區大小、單個查詢的緩衝區大小等。

如果您希望優化MySQL伺服器的查詢效能和速度,可以在MySQL配置中增加這兩項:

query_cache_size=SIZE
query_cache_type=OPTION

上方第一行中,SIZE是指為查詢快取開闢多大的空間。預設是0,也就是禁用查詢快取。

設定查詢快取的型別,可選的值有以下這三種: