【聲明】css
歡迎轉載,但請保留文章原始出處→_→html
生命壹號:http://www.cnblogs.com/smyhvae/前端
文章來源:http://www.cnblogs.com/smyhvae/p/5243181.htmlgit
【正文】程序員
豆瓣連接:https://book.douban.com/subject/26598045/
github
【目錄】web
全棧工程師(Full-Stack Engineer):一個能處理數據庫、服務器、系統工程和客戶端的全部工做的工程師。根據項目的不一樣,客戶須要的多是移動棧、Web棧,或者原生應用程序棧。
面試
全棧:表示爲了完成一個項目,所須要的一系列技術的集合。應該從能力和思惟方式兩方面,來斷定一我的是不是一個合格的全棧工程師。簡單來講*全棧工程師就是能夠獨立完成一個產品的人。算法
大中型互聯網公司的產品研發流水線:產品設計-->交互設計-->視覺設計-->前端開發、後臺開發-->測試-->發佈。數據庫
產品經理:產品經理實際上是對一個產品負根本責任的管理者。他一般的工做包括制訂產品規劃、協調多方資源、把控產品方向和質量細節,等等。有時候,他會從頭策劃一個新的產品,而更多的時候,他是在優化已有產品的一個部分。總之,在流水線中,產品經理須要從策劃跟進到發佈,是一個很是重要的角色。
用戶研究員:用戶研究員的工做是研究用戶行爲,有時候他會從宏觀的角度分析數據,有時候也從微觀的角度分解用戶場景,有時候會召集一些用戶專門來訪談,或者觀察用戶對產品的使用狀況。從輸出品的角度來講,用戶研究員通常輸出用戶研究報告來交付給產品經理和交互設計師,做爲產品設計的目標參考。
交互設計師:交互設計師常被簡稱爲「交互」。他與視覺設計師最大的區別是,交互設計師更多着眼於如何優化用戶界面的信息分佈和操做流程。交互設計師的輸出品通常是描述用戶與網站「交互」過程的流程圖,以及描述頁面信息結構的線框圖。輸出的線框圖會交付給視覺設計師。
視覺設計師:在細分交互設計師和視覺設計師的大公司,視覺設計師根據交互設計師輸出的線框圖來作一些潤色和設計,輸出最終的產品視覺稿以後將視覺稿交付給前端工程師。在一些不細分交互設計師和視覺設計師的小公司,兩者被統稱爲「設計師」,他們的職責就是負責整個用戶界面的設計。
前端工程師:產品視覺稿在獲得產品經理和交互設計師等多方確認以後,會交給前端工程師,由前端工程師製做頁面,實現視覺稿以及交互功能。從頭銜上的變化就能夠看出,這時候才真正開始編碼。前端工程師須要很是熟悉HTML、CSS和JavaScript,以及性能、語義化、多瀏覽器兼容、SEO、自動化工具等普遍的知識。
後臺工程師:使用服務器編程語言,進行服務器功能的開發。在編程語言的選擇上,不少公司都會出於團隊已有成員的知識儲備、程序員的供給量或者語言性能方面來進行選擇。在這一方面,後臺語言的選擇是相對自由的一件事,不像前端工程師,爲了頁面兼容性,必須使用HTML和CSS。若是關注各大公司招聘信息的話,您就會了解,不一樣公司使用不一樣的後臺語言,好比傳統的C#和C++、Java、PHP,或者新潮的RoR和Python。小公司的後臺工程師除了負責功能開發,可能還會負責服務器的配置和調試、數據庫的配置和管理等工做。在大公司,這些工做會分別委派給後臺工程師、運維工程師、數據庫管理員(DBA)等崗位。
運維工程師:運維工程師是跟服務器打交道的人,他會關注服務器的性能、壓力、成本和安全等信息。
測試工程師:顧名思義,測試工程師保證產品的可用性,即便在小公司,這一職位也是不可或缺的。
備註:在項目管理中,常常會用到甘特圖。甘特圖(Gantt Chart)是柱狀圖的一種,顯示項目、子項目、進度以及其餘與時間相關的系統的進展狀況。
提到全棧技術,不得不提一個表明性的全棧框架——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的工程師能夠兼顧先後端的開發,而且前端模板代碼和後臺模板代碼是能夠複用的。
隨着Web技術的發展和開源社區的積極努力,有不少公司提供便宜又方便的一條龍服務,能夠解決獨立開發者的大量麻煩。
好比Amazon提供的PaaS(Platform as a Service,平臺即服務),就可讓創業公司的開發者省去架設和維護服務器的麻煩。
而GitHub在2012年得到了一億美圓融資,也能夠看出市場對代碼託管市場的信心。能夠預期,將來可能會出現愈來愈多爲開發者提供服務的公司。之後,小公司也能夠用更低廉的價格得到世界級的IT服務支持,毫無疑問,更多的IT服務將託管在第三方的服務器上。
VPS(Virtual Private Server,虛擬專用服務器)是把一臺物理服務器虛擬成多個虛擬專用服務器的服務。每一個VPS均可分配獨立的公網IP地址,運行獨立的操做系統,擁有獨立的磁盤空間、內存、CPU資源、進程和系統配置,模擬出「獨佔」使用計算資源的體驗。
我跟一位行業專家討論過全棧工程師的話題,他不是很贊同全棧工程師這個方向。他認爲,工程師應該有專精的技能和目標,若是初學者貪圖大而全,反而樣樣不精。我理解他的擔憂,若是一個工程師沒有堅實的基礎(好比專業理論知識,對經常使用設計模式的理解,或者特定職業的基礎知識),那麼瞭解的非本專業技能越多,越容易迷失。
因此我認爲,全棧工程師首先要「一專多長」。一專多長的意思是,工程師首先有一個專精的方向,在這個方向上足夠精通以後(高級工程師級別),以此爲突破點去學習更多的知識,增長本身的長處。若是尚未得到某個方向上足夠深刻的理解,就不要囫圇吞棗地去學習其餘領域的知識。
有些知識須要時間的積累,並非快速閱讀就能夠掌握的。「全棧工程師」這個名詞可能會引發讀者的誤解。勿在浮沙築高臺,「全棧」是一個長期積累的過程,是專精型工程師在不斷解決問題的過程當中積累知識和經驗所造成的能力,而不是一蹴而就的過程。
公司存在的意義就是解決問題,公司要解決用戶的問題,而員工要解決公司的問題。
公司的問題多是下降成本、擴大用戶羣、增長成交量、優化性能,等等。不一樣的問題優先級不同,投入一樣的時間,有的項目能爲公司增長上百萬的收入,而有的項目卻只能增長几萬。
互聯網領域發展很快,問題的優先級永遠都是在動態變化的,因此團隊每每每半年或者三個月就要回顧一下當前形勢,並制定新的工做計劃。若是新計劃不是您擅長的,怎麼辦?您應該立刻開始學習新的技術,這就是我說的關注問題,而不是醉心技術。
高級工程師能夠選擇往上下游去擴展本身的能力,並承擔更多的責任,給公司帶來更大的收益,也給本身帶來更大的成長空間。程序員在小公司裏主動去承擔更多責任,本身跟公司都會得到相應的成長。在自由職業市場,全棧工程師是最閃耀的明星。全棧工程師仍是天生的創業者。
延伸閱讀:
推薦採用「先精後廣,一專多長」的流程來學習:先在一個特定的方向上有比較深刻的鑽研,而後再將學習目標漸漸推廣開來。好比先從前端方向入手,掌握了基本的HTML、CSS、JavaScript以後,不要轉頭向服務器端語言或者App方向發展,而是深刻到性能優化、SEO、多種框架、響應式頁面等前端細節中去。通過一到兩年的深刻研究以後,再去學習其餘方向。
採用這種方式來學習,不光能夠舉一反三、觸類旁通,還讓咱們學習得更快,並且按部就班更符合通常人的職業生涯發展。
騰訊社交用戶體驗設計部招聘前端開發,要求以下:
有的競爭者提到他很擅長頁面性能優化、響應式、頁面渲染效率,有的寫過JavaScript框架……你須要在招聘要求的方向上以200%的能力來獲得這個職位。
老闆僱用一個員工,不是由於他能寫程序,而是由於他能幫助本身賺錢。
我喜歡這樣的態度:對將來有本身的方向,但也知道本身無法看得太清晰。對商業和市場有想法,並且本身也有足夠的技術能力和自信向將來前進。
記住,當您只有一把錘子,您看什麼都是釘子。而若是您癡迷於工具,反而看不到問題所在。所以,要先看看有哪些問題須要解決,而後再補充您的工具箱。永遠從商業目標的角度來決定學習哪些東西,而不是純粹爲了鍛鍊技術能力而去學習。
這裏的「用戶」仍然是一個廣義的定義:全部您爲之服務的人。
大巧若拙:指真正聰明的人,不會顯露本身,反面從表面看好像還很笨拙。用戶體驗不僅是界面和交互這樣能夠直觀感覺的東西,還包括一些隱藏在用戶界面背後的細節和規範。
就像冰山,露出水面的部分只佔整個冰山的1/9,用戶看到的只是顯露出來的部分。背後的部分通常用戶是看不到的:好比用戶研究,用研團隊會經過調查,輸出一些用戶畫像,影響整個產品的功能方向、設計風格;還有設計規範,設計團隊在設計產品的一開始制定了規範以後,新增長的功能和頁面都必須遵循已有的設計規範,這樣整個產品是統一的,可以給用戶專業的感受。
我若是開創一個公司須要招聘「全棧工程師」,我要求的三個能力:一專多長、關注商業目標、關注用戶體驗。
延伸閱讀:
前端工程師要有一個基本常識,那就是結構、表現和行爲要分離。具體解釋以下:
崗位優先於公司,即便在一個很好的公司裏面,若是隻是作着本身不喜歡也不擅長的工做,那能有什麼前途呢。
其實個人設計知識僅限於自學,來自於一本書——《寫給你們看的設計書》。這本書很是入門,可是淺顯易懂,既有設計理念,也有實際操做,到如今爲止我反覆看了3遍以上。
我理解了書裏說的設計四大原則:對齊、對比、距離和重複。雖然我基本沒有設計經驗,只會一些基本的Photoshop操做,但我理解了這幾個原則,每次看到好的設計和差的設計時,都能有所感悟。若是不理解,可能我只能用「上流」「高端」「簡約」這樣空泛的詞彙來描述設計。關於設計原則,我在後面的章節中會單獨提到。
校園招聘是不少大公司很喜歡的一我的才渠道,由於比起社會招聘的應聘者,畢業生更加有空杯心態、更正能量、更有激情,雖然缺乏經驗,可是通過一兩年的培訓也能很快成爲團隊骨幹。而若是是自己有項目經驗的畢業生,或者是在GitHub上有知名做品、知名博客、去過其餘大公司實習的畢業生,那就更加搶手了。至於大學考試成績,影響不大。
社會招聘的目標是有經驗者,招聘時間沒有校園招聘那麼固定,隨時均可能有職位空缺,可是每次放出的名額不會不少。並且這時候會根據招聘崗位,有針對性地考覈應聘者的專業能力與綜合能力,致使社招的競爭是很是激烈的。
相對而言,我認爲校園招聘的門檻並不高,重要的是找對方法。若是您的學校不是頂級,您的成績不是學霸,那就要走不尋常的道路。
不管您是名牌大學的高材生,仍是自學成才的專科生,在製做第一份簡歷的時候,我有這樣幾個建議:
舉一個例子,做爲程序員和設計師,做品是排名最高的信號。在著名開源項目中貢獻代碼,說明您有能力閱讀和編寫好的代碼,這是公司直接須要的技能。此外,這還能說明您有能力與他人協做:開源代碼老是須要協做的。開源項目還能代表您對新鮮事物有熱情,代表您也許英語能力不錯,有查閱文檔的能力……一個開源項目須要的精力也許不會特別多,但它的加分點可就很是多了,簡直是一箭N雕!
爲何要把簡歷發送到真正招人的企業主管那裏?由於HR沒有能力辨別技術能力的高低,他只能根據學歷、分數等硬指標來篩選。因此一些技術能力優秀可是分數不高的同窗可能就很遺憾地失去了面試機會。
實習能提高本身的實踐能力,能夠認爲是從學生到社會人士的一個身份過渡。建議:
延伸閱讀:
野生程序員是指僅憑對計算機開發的興趣進入這個行業,從前端到後臺一手包攬,但各方面能力都不精通的人。野生程序員有很強大的單兵做戰能力,可是在編入「正規軍」以後,可能會不適應新的作事方法。
JavaScript文件源代碼能夠採用混淆壓縮的方式,CSS文件源代碼進行普通壓縮,JPG圖片能夠根據具體質量來壓縮爲50%到70%,PNG能夠使用一些開源壓縮軟件來壓縮,好比24色變成8色、去掉一些PNG格式信息等。
若是圖片顏色數較多就使用JPG格式,若是圖片顏色數較少就使用PNG格式,若是可以經過服務器端判斷瀏覽器支持WebP,那麼就使用WebP格式和SVG格式。
包括CSS、JavaScript和小圖片,減小HTTP請求。
這對文本資源很是有效,對圖片資源則沒那麼大的壓縮比率。
或者一些公開庫使用第三方提供的靜態資源地址(好比jQuery、normalize.css)。一方面增長併發下載量,另外一方面可以和其餘網站共享緩存。
這樣,頻繁訪問網站的訪客就可以更快地訪問。不過,這裏要經過修改文件名的方式,確保在資源更新的時候,用戶會拉取到最新的內容。
這樣就不會阻塞頁面渲染,讓頁面出現長時間的空白。
備註:每個條目均可以進一步深層挖掘下去。Web性能優化分爲服務器端和瀏覽器端兩個方面。
此外,因爲中文的歧義性,Web性能優化這個詞既能夠解讀成頁面加載速度(Page Speed)的優化,也能夠解讀成頁面渲染性能(Page Performance)的優化。或者是兩者的集合。因此,應聘者若是能在這個問題上多作一些分析,會有很高的加分。可是若是你在網絡性能方面的研究只是淺嘗輒止,停留在壓縮資源方面,這說明你尚未足夠理解HTTP協議自己。
關於網絡性能和HTTP協議,做爲大公司的前端工程師是很是看重的,由於每個頁面都會有億萬用戶訪問量,任何一點對服務器帶寬壓力都會聚沙成塔,最終形成很大的成本。關於這方面的技術詳解,我在後面會有一篇單獨的文章來分析。
我問一個面試者:「關於服務器端MVC架構的技術實現,您是怎樣理解的?」他說:「是數據模型、視圖、控制器的分離。」
我更進一步問道:「這種架構方式有什麼好處?您在項目中是如何應用這一架構的?」他回答說:「MVC的架構方式會讓項目可維護性更高,全部涉及界面的代碼都在視圖(View)裏面,全部涉及核心邏輯的代碼都在模型(Model)裏面,URL路由之類的代碼都在控制器(Controller)裏面。我在項目中使用了MVC架構的PHP框架——CodeIgniter。」
我一邊打開他的網站,一邊繼續跟他電話溝通。當看到網站的CSS代碼都直接內嵌在HTML頭部的時候,我忍不住問他:「爲何您的網站的CSS代碼都內嵌在HTML裏面呢,是使用自動化工具合併進去的嗎?」他支支吾吾地說:「由於在本地調試的時候,CSS文件修改常常不生效,因此就直接在HTML裏面改了,這樣比較快。」
好吧,我想這是一個典型的「知易行難」的開發者,他知道採用MVC架構的項目的可維護性更高,但是在分離樣式與結構上面尚未達到最基本的要求,甚至把CSS寫在HTML中。至於他說的在本地環境上發現CSS文件常常緩存,可能要看看本地服務器的緩存設置是否有問題,而後再作調試。稍微瞭解一點HTTP的瀏覽器端緩存,這就不是難事了。我更欣賞在開發流程上花工夫去理解和優化的應聘者,而不是馬馬虎虎,只是以完成需求爲目標的人。
「野生程序員」:就是沒有計算機基礎知識和相關教育經歷,靠着對計算機開發的興趣進入這個行業,雖然知識面比較廣,可是各方面都只知其一;不知其二的開發者。
這幾年我從一個求職者,轉變成一個招聘者,有一個感覺就是,中國高等教育與市場需求不接軌。學校不瞭解市場究竟須要什麼樣的人才,其設立的課程和技術每每比市場技術現狀落後了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/)等。我在讀大學的時候,Google Reader尚未永久關閉,那時候我很喜歡用RSS來關注這些站點的更新狀況。Google Reader下線後,就基本上廢棄了RSS閱讀的習慣,轉而用一些社交網站來追蹤更新狀況,可是有時仍是會淹沒在大量無用的信息裏面。
社團:學校的網站社團也孕育了許多能力很強的開發者,社團通過歷屆的傳幫帶,技術有所積累,好比師兄會教師弟用Sublime編輯器,這就比還在用Dreamweaver的同窗更有優點。此外,學校社團有一些定點客戶,好比學校教務處、周邊商戶,因此有更多的實戰經驗,在畢業時做品集也豐富了很多。
由於有這樣一些自學渠道,因此不必定只有計算機專業畢業的學生纔有機會進入互聯網行業。畢業以後,這些計算機愛好者進入不一樣的工做崗位,不一樣的是,有些進入大公司,有些進入小公司。這二者的成長軌跡每每會不太同樣。
若是你是畢業生,這種狀況下我仍是建議選擇大公司,由於會選擇創業公司的人每每有本身的主見,已經接受創業公司的邀請去工做了,不會去發帖詢問你們的意見。固然這是開玩笑,真正的緣由是,在大公司的頭兩年,是從學生到職場人士的一個轉變,您可能會從大平臺學習到一些規範的流程方法,養成一些足以影響您一輩子的習慣,認識更多的能對您職場有幫助的人脈。
大公司能給你的有:
每一個公司都有倒閉的可能,可是,顯然大公司比小公司的風險低多了。若是您的風險承受能力較低,那麼不得不考慮這個因素。
在大公司,對代碼質量和一致性的要求很高,因此通常在最終發佈前會有代碼審查(Code Review)流程和項目總結會等。若是您完成了一個任務,可是沒有采用最佳實踐,只是hack了一下,那麼其餘同事可能都會指出您的問題,而且要求您改正以後再提交。小公司或者創業公司人力比較緊張,在他們看來,快速實現和上線,比優雅地上線更重要,因此對於一些最佳實踐類的問題,只能睜一隻眼閉一隻眼啦。
大公司專業分工很細,並且有更多技術溝通和沉澱的氛圍,因此容易讓人在垂直專精的技術方向有足夠的發展。在小公司更能鍛鍊技術的廣度,深度上缺少鍛鍊的環境。可是其實兩者的利弊,都是外界的,技術人員的我的成長除了工做時間的鍛鍊,還要靠下班後的時間,外界只是給予一個環境或者機會。
一樣是作一個網站,服務少數用戶量和服務海量用戶量時須要考慮的事情是徹底不一樣的。小網站遇到的問題,大網站必定遇到過,而大網站遇到的問題,小網站就不必定遇到過了。當一個網站發展到業內最強時,它的問題沒有人遇到過,這時候就不能凡事問百度、Google或Stack Overflow了,而要本身去探索解決方案。
硬技能是指每一個職位須要的專業技能,軟技能則是通用的技能,好比溝通、影響力、項目管理和演講等。越是大公司,越是看重影響力,因此會有不少培訓教您如何提升影響力。
我在面試一些來自小公司的應聘者時,就發現他平時的工做中,周邊環境不多有分享和沉澱的習慣。沉澱和總結是很重要的,在騰訊,設計師作完一次設計定稿以後,就會把設計的思路,包括總體的設計風格、設計規範和色彩的肯定等都總結成一封郵件或者PPT,發送給部門同事。每一個人都要有意識地維護本身的做品集,它在半年一次的考覈、晉升面試甚至之後的跳槽中都很是有用。可是小公司的設計師不太會總結我的做品集,時間緊急是一方面緣由,另外一個主要緣由是環境不須要他這樣作,所以就缺少了這方面的鍛鍊。
每一年都有很多人從大公司離職去創業,這是很是天然的事情。對於大公司出來的人來講,以前積累的人脈資源這時候會起到很大的做用,好比創業期間的一些合做機會或者資源的互利,等等。萬一創業失敗,也不會很慘,由於您以前接觸的人脈能夠給您提供工做機會。但若是您剛畢業就選擇創業,創業失敗以後沒有人能給您提供工做機會。
其實大公司能給予畢業生最大的優點,就是提供一個心智培育的土壤。以前參加面試官培訓的時候,我大概瞭解過公司招聘一個畢業生投入的成本。從校園招聘,到安排面試官面試候選人,再到封閉培訓和一些課程培訓,再給一段時間熟悉項目,最後3個月試用期後可能還要淘汰掉一些。若是把成本平攤到每個人身上,這些投入要一年才能收回來。而小公司不會有這麼大的耐心去培育一個新人。若是沒有足夠的時間去學習和成長,可能在一兩年後,員工的能力也比較全面,可是樣樣都不精通,也說不清楚本身的目標是什麼,因而就變成了「野生程序員」。
綜合來說,在大公司中,從硬技能到軟技能都會有不少經驗豐富的前輩可以教您,您會在大平臺上學習到不少東西。工做幾年以後,員工的選擇也不少,要麼走技術路線繼續發展下去,作高級工程師;要麼學習管理和領導力;要麼出去創業。
因此,個人我的建議是,從畢業生本身前途發展的角度來看,先加入一家上市大公司是個不錯的選擇。
延伸閱讀:
我曾讀過一本有意思的書,《您就是極客》,副標題是「軟件開發人員生存指南」。其中第二章專門講軟件工程師事業的3個關鍵詞:技術、成長和聲望。前面的文章裏已經講了技術和成長,如今咱們來談談聲望。
做品集(portfolio),是指您我的的項目和做品的集合,一份精心準備的做品集比簡歷更能說服人。
我很重視做品集,一方面體如今我很在乎維護本身的做品集,另外一方面我也很喜歡面試的時候看到應聘者有本身的做品集。除了工做上安排的項目,我更在乎一些課外項目,由於它展現了您的興趣和熱情所在。
從某種程度上來說,重視展現項目這種態度確實會對編程的純粹性有所腐蝕(若是您編程自己只是爲了本身的興趣),您編寫一個項目的動機可能會從純粹爲了好玩,變成獲取收益。可是在這個商業化的市場裏,對方(高效地)獲得了您的信息,您獲得了您應有的評價,這對雙方是互利的。
對於程序員來講,成本最低的一種做品展現方式就是把本身的代碼發佈到GitHub上。
名爲「Open Source (Almoset) Everything」的一篇文章中,有這樣一句話:「If you do it right, open sourcing code is great advertising for you and your company.」若是使用得當,開源代碼是您和您的公司最好的廣告。
另外,將代碼開源,你們看到的是項目功能,而不是代碼技巧。若是不是本身須要,沒有人會閒得幫其餘人優化代碼。若是您的想法夠好,那麼就會收穫來自社區的感謝、幫助,以及您應有的聲望。
順便提一下,若是您是擅長設計和編程的全棧工程師,而且對本身的設計能力很是有自信,那麼一樣推薦Dribbble。Dribbble是設計師的舞臺,它的社交性讓您的做品很容易傳播和收穫「贊」。若是是能夠實際預覽的頁面,您能夠在貼上設計稿以後,在下面留下站點的實際地址。
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%以上。
若是做品集有一些動態生成的內容的話,能夠選擇本身架設服務器並綁定域名,VPS就是不錯的選擇。VPS成本比GitHub Pages高,由於須要付費和配置環境,可是最終跟GitHub Pages的效果是相似的。
最後我想說的是,任何做品集都須要有一個重點。若是您想重點突出本身某個技能的深度,能夠針對這個技能列出大量做品、項目、專欄或者本身的書。若是想突出技能的廣度,光列出您的技能集是不能說服人的,還要在本身的GitHub上提交各類使用相關技能的項目。若是自由開發者想招攬一些客戶的話,漂亮的過往項目是最重要的。
做品集不必定是嚴謹而無趣的,曾經有一個前端開發者就將本身的做品集用一個HTML5遊戲包裝起來,讓人印象很是深入。
看到這裏,您也許會說,有一些社交網絡能夠直接生成相關的做品集,好比LinkedIn、about.me等。但個人觀點是,既然身爲一個全棧工程師,那麼花一點時間作一些特別的東西會更有趣,不是嗎?
經過 about.me能夠生成本身的做品集,截圖來自about.me。
經過社會化媒體,樹立起我的的品牌,即便不拿名片出去,也有人知道本身,這纔是應該努力的方向。有人說過,「人到三十,不要去找工做,要讓工做來找本身」,大概也是這個意思。
HTTP,是Web工程師天天打交道最多的一個基本協議。不少工做流程、性能優化都圍繞HTTP協議來進行,可是咱們對HTTP的理解是否全面呢?若是前端工程師和後臺工程師坐在一塊兒玩捉鬼遊戲,他們對HTTP的描述可能會大相徑庭,從這兩個角色的視角看過去,HTTP呈現出大相徑庭的形態。
超文本傳輸協議(HyperText Transfer Protocol,HTTP)是互聯網上應用最爲普遍的一種網絡協議。設計HTTP的最初目的是提供一種發佈和接收HTML頁面的方法。
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/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的基本知識,咱們來分別看看前端工程師和後臺工程師分別是怎樣看待這個最熟悉的小夥伴的。
前端工程師的職責之一是,讓網站又快又好地展示在用戶的瀏覽器中。
從這個角度來講,對HTTP的理解是這樣的:打開HttpWatch,而後隨意訪問一個網站,HttpWatch會按照瀏覽器請求的次序,列出打開這個網站的時候發生的請求細節。包括以下內容:
經過查看站點的HTTP請求信息,能夠獲得不少優化信息。每個前端工程師都知道的基本優化方法是:儘可能減小同一域下的HTTP請求數,以及儘可能減小每個資源的體積。(經過Chrome開發者工具中的PageSpeed工具,能夠快速得到關於站點性能優化的建議)
備註1:HttpWatch是一個瀏覽器插件,它能夠用來檢測頁面中全部HTTP請求。相似的工具還有Fiddler,或者各類現代瀏覽器的開發者工具中的「網絡」標籤頁
備註2:gzip是一種開源的數據壓縮算法,其中g表明免費的意思(gratis)。HTTP/1.1協議容許客戶端選擇要求從服務器下載壓縮內容,gzip是絕大多數客戶端和服務器都支持的壓縮算法,它在壓縮文本文件(好比HTML、CSS、JavaScript)時壓縮效果很好。
瀏覽器經常限定了對同一域名發起的併發鏈接數的上限。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資源的請求耗時,我想說明兩個細節:
若是沒有設置gzip,下載這個CSS文件會須要好幾倍的時間。
前端工程師對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是Distributed Denial of Service的縮寫,DDoS攻擊翻譯成中文就是「分佈式拒絕服務」攻擊。
簡單來講,就是黑客入侵併控制了大量用戶的計算機(俗稱「肉雞」),而後在這些計算機上安裝了DDoS攻擊軟件。咱們知道瀏覽器做爲一種「善意」的客戶端,限制了HTTP併發鏈接數。可是DDoS就沒有這樣的道德準則,每個DDoS攻擊客戶端均可以自由設置TCP/IP併發鏈接數,而且鏈接上服務器以後,它不會立刻斷開鏈接,而是保持這個鏈接一段時間,直到同時鏈接的數量大於最大鏈接數,才斷開以前的鏈接。
就這樣,攻擊者經過海量的請求,讓目標服務器癱瘓,沒法響應正常的用戶請求,以此達到攻擊的效果。
對於這樣的攻擊,幾乎沒有什麼特別好的防禦方法。除了增長帶寬和提升服務器能同時接納的客戶數,另外一種方法就是讓首頁靜態化。DDoS攻擊者喜歡攻擊的頁面通常是會對數據庫進行寫操做的頁面,這樣的頁面沒法靜態化,服務器更容易宕機。DDoS攻擊者通常不會攻擊靜態化的頁面或者圖片,由於靜態資源對服務器壓力小,並且可以部署在CDN上。
這裏介紹的只是最簡單的TCP/IP攻擊,而DDoS是一個概稱,具體來講,有各類攻擊方式,好比CC攻擊、SYN攻擊、NTP攻擊、TCP攻擊和DNS攻擊等。
前端跟後端在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說過:計算機科學中最無奈的兩件事是緩存失效和命名。這是多是由於,複雜性理論方面的難題,可能最終仍是有解的。而緩存失效是分佈式系統中最多見,也幾乎沒有最優解決方案的難題。
緩存對於站點性能起到舉足輕重的做用,不少時候,優化算法和壓縮圖片帶來的優化效果可能遠遠不如優化緩存。
計算機系統中的緩存有這樣幾種功效:(以圖書爲例)
下面我來談談在一個Web站點中,它的數據流從服務器端到瀏覽器端,哪些地方能夠使用緩存來優化。
對於一些計算量大的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,也就是禁用查詢緩存。
設置查詢緩存的類型,可選的值有如下這三種:
具體的設置方法不是咱們討論的重點,重點是要了解適合設置查詢緩存的場景。由於每一次select查詢的結果都會被緩存起來,若是數據庫數據沒有發生變化(沒有運行INSERT/UPDATE/DELETE/MERGE等操做的話,數據庫就不會變化),下一次查詢就會直接從緩存裏返回數據。可是若是數據庫發生了變化,那麼全部與該表有關的查詢緩存所有失效。
因此,對於查詢操做遠遠多於修改操做的數據庫,開啓數據庫查詢緩存是頗有益的;可是對於修改操做不少的數據庫,因爲緩存常常會失效,就起不到加速的效果。不只如此,因爲數據庫要花費時間寫緩存,因此實際上速度更慢了。
這個問題就是「緩存命中率不高」,因此配置緩存以後第一件事就是查詢命中率,若是命中率低,不如不作緩存。
這裏須要注意的是,兩次SQL文本必須徹底相同。若是先後兩次查詢使用了不一樣的查詢條件,就會從新查詢。如第一次查詢時沒有輸入where條件語句,後來發現數據量過多,因而利用where條件過濾查詢的結果,此時即便最後的查詢結果是相同的,系統仍然是從數據文件中獲取數據,而不是從緩存結果中。再如,select後面所使用的字段名稱也必須是相同的。若是查詢語句中有一個字段名稱不一樣,或者先後兩次查詢所使用的字段數量不一樣,都會被系統認爲是不一樣的SQL語句,須要從新解析並查詢。
MySQL的自帶緩存有一個問題,它的緩存池大小是在MySQL所在服務器上開闢,能使用的內存空間是有限的。在比較大型的網站中,緩存就不夠用了,這時候須要使用服務器集羣來實現數據庫緩存。
memcached應運而生,它是一個高性能分佈式內存對象緩存系統,用於減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。memcached能夠與數據庫查詢緩存配合使用,查詢流程以下圖所示。
您也許發現了數據庫查詢緩存的一個設計原則:其緩存失效設計是很粗糙的。只要某個表發生了更新操做,全部對這個表的查詢都會失效。這是爲了保證數據的時效性而下降了數據的命中率。
memcached通常查詢流程:
memcached的緩存失效與此不一樣,它採用的是按時間來過時的設計。memcached至關於應用程序和數據庫之間的中間層,經過網絡API設置和調用。memcached儲存的是名值對,並且設置了一個過時時間,只要過時時間沒有到,應用程序就會從memcached中獲取數據。這時候即便發生了數據庫更新操做,緩存的查詢結果也仍然是以前保存的舊數據,直到設置的時間過時。這樣提升了緩存的性能,帶來的影響就是,數據多是「不新鮮」的。
memcached支持集羣,並且有諸多優勢,因此能夠有效利用多臺機器的內存,提升命中率。
若是您使用WordPress,那麼開啓memcached是很簡單的。在服務器安裝好memcached後,再去WordPress的插件列表裏,搜索cache或memcached之類的關鍵詞,能夠找到不少相關的插件。根聽說明安裝好這些插件後,通常就能夠無縫銜接緩存軟件和WordPress了。
可是memcached也不是老是那麼有效,由於若是隻有一臺服務器,就用不到它的服務器集羣的優點,反而讓系統更慢。
除了能夠將數據庫查詢結果緩存在內存中,還能夠將被頻繁造訪的數據緩存在文件中。文件I/O比起內存有如下幾個好處:
可是文件緩存沒有內存緩存快,只能做爲內存緩存的補充,在獲取數據時,先從最快的地方讀取,若是沒有就繼續日後找。查找優先級爲:內存緩存→文件緩存→數據庫。
PHP框架CodeIgniter的數據庫緩存類,容許您把數據庫查詢結果保存在文本文件中,以減小數據庫訪問。
若是激活了CodeIgniter的緩存特性,那麼在某頁面首次被加載時,數據庫查詢的結果對象將會被序列化,並保存在服務器的文本文件中。而此頁面再次被加載時,緩存文件將會替代數據庫查詢。如此,在被緩存的頁面中,您的數據庫使用率會降至零。
只有讀類型查詢會被緩存,由於只有這種查詢會產生結果集。 而寫類型查詢,由於不會產生結果集,故緩存系統不對之進行緩存。
緩存文件不會過時,除非您刪掉它,不然任何被緩存了的查詢會一直存在。緩存系統容許您按頁面清除,或把全部緩存都清除掉。通常來講,您能夠在某些事件(好比向數據庫添加了數據)發生時用特定的函數來清除緩存。
有兩種靜態化的方法,其中一種是相似WordPress的靜態化插件,安裝很簡單,每次有新文章就自動生成靜態頁面。這種方法仍是將數據保存在數據庫中,只是會讀取數據庫以後生成一些靜態頁。
這一種方法的原理跟文件緩存很類似。靜態化頁面以後,服務器每次接收到對這個頁面的請求,都會直接給出這個頁面的靜態文件,因此就省略了後臺運算和數據庫查詢。優勢是能大大加快訪問速度,同時減輕服務器處理大量請求的運算壓力。在前面咱們也說過,由於靜態化的頁面對服務器的壓力小,能有效承擔巨大的訪問量,因此還能抵禦DDoS攻擊。
另外一種方法就是直接拋棄數據庫。好比有一些博客做者會用Jekyll系統來寫博客,將整個博客站點靜態化。徹底拋棄數據庫的好處是,能夠將生成的靜態網頁直接託管在靜態資源站點,好比GitHub Pages或者Amazon S3,而不用操心數據庫服務器的問題,不光整個系統穩定不少,費用上也更加低廉(GitHub更是徹底免費的,並且提交Markdown源代碼後可讓它在服務器端生成站點)。
對於徹底靜態化的站點,能夠採用第三方插件來支持用戶生成內容。好比Disqus就是一個第三方的評論插件,經過JavaScript代碼插入到靜態頁中。用戶的評論數據都儲存在Disqus的服務器上,對咱們是透明的,很方便。
值得一提的是,咱們從URL是沒法判斷後臺是否真正靜態化的。對於一個URL爲/blog/index.html的頁面,也有多是PHP頁面經過UrlRewrite來改寫的。經過Apache或者Nginx能夠將一個對靜態資源的請求(index.html)轉給一個動態應用程序(好比PHP)來處理。
前面說的緩存都是發生在服務器端的,適用的狀況是那些服務器性能爲主要瓶頸的場合,經過緩存來將一個長的計算時間跳過,起到提升性能的做用。而當瀏覽器訪問一個站點的時候,網絡鏈接是主要瓶頸,咱們能夠經過設置瀏覽器緩存來跳過HTTP請求。
若是在瀏覽器設置緩存,一般有兩個主要做用。
對於瀏覽器來講,如何緩存一個資源是服務器端制定的策略,本身只是根據服務器的「指令」來執行而已。服務器的「指令」就是前面介紹過的HTTPS頭。
服務器經過對每一個資源的HTTP響應頭設置屬性和值,來發出本身的緩存指令。主要會有兩種緩存指令,咱們以一個圖片image.png爲例。
對於一個普通的請求,服務器可能會說:「您拿着這個資源吧,直到2020年您都別再向我要了。」
Expires: Thu, 15 Apr 2020 20:00:00 GMT
那麼瀏覽器若是再次命中對這個資源的需求,就不會再去發起HTTP請求,而是直接從緩存(在硬盤中)讀取。
200(from cache)
這種緩存是最快的,由於沒有任何HTTP請求發生。當用戶須要這個資源,瀏覽器就直接從緩存中讀取,再也不須要詢問服務器端的意見(服務器端甚至不知道您在瀏覽image.png)。因此HttpWatch是推薦對全部的靜態資源都設置Expires。
對於一些有可能過時的請求,服務器可能會比較慎重地說:「您拿着這個資源吧,這個資源上次修改時間是2014年3月1日,若是用戶要用,您就問問我改變了沒,或者直到2014年12月31日文件自動過時。」
Last-Modified: Tue, 01 Mar 2015 03:42:36 GMT
那麼瀏覽器若是在2015年3月10日訪問了image.png,就會將這個圖緩存在硬盤中。過了幾天,瀏覽器又命中了對這個資源的需求,就會發起一個HTTP請求。
在HTTPS頭中,瀏覽器問:「我這裏有個image.png,它的最後修改時間是2015年3月1日,如今用戶又要了,您那個文件有過更新沒?」
If-Modified-Since: Tue, 01 Mar 2015 03:42:36 GMT
服務器若是回答:「沒更新,您直接用吧。」這個回答中就不須要帶上請求的文件體了,只用一個HTTPS頭表示文件未更新便可。304就是這句話的代號,表明資源未修改的意思。
304
另外一種狀況是,image.png後來更新過了,服務器就會說:「更新過了,我如今給您一個新的圖片。」而後就正常返回請求文件(200),而且把整個圖片做爲HTTP正文發送給瀏覽器。
經過這種緩存方式,不管資源是否發生了更新,仍然至少會發生一來一去HTTPS頭的傳輸和接收,因此速度比不上Expires。
從服務器端的角度來看,有時候咱們並不但願對靜態資源的請求中大部分都返回304。由於這可能說明咱們的不少用戶都在頻繁訪問站點,並且咱們的資源不多更新,就好像它們一直問「資源修改了嗎?」,咱們一直回答「沒有修改」。這裏能夠使用Expires來設置過時時間,這樣它們就不會「煩咱們」了。對於服務器管理員來講,保持304爲一個合理的比例便可。咱們能夠經過查看服務器的log,查看304響應與200響應的比例,來作出一個合理的緩存策略。
表徵性狀態傳輸(Representational State Transfer,REST)是Roy Fielding博士在2000年發表的博士論文中提出來的一種軟件架構風格。
目前,在3種主流的Web服務實現方案中,由於REST模式最簡潔,也能合理地利用HTTP操做的語義,因此愈來愈多的Web服務開始採用REST風格設計和實現。好比,Amazon.com提供接近REST風格的Web服務進行圖書查找。
Restful 的目的是定義如何正確地使用Web標準,優雅地使用HTTP自己的特性。原則上是對資源、集合、服務(URL)、get、post、put、delete(操做)的合理使用。
舉例來講,若是請求一個資源,可是服務器上沒有這個資源,這時候就應該對HTTPS頭設置404,而不是設置200。
其實Expires跟Last-Modified已經能知足咱們絕大多數需求了,可是HTTP1.1又新增了一個屬性Cache-Control,它的功能跟Expires相似,不過有更多的選項。
Expires的值是一個日期,表示某日期以前都再也不詢問。
Cache-Control的值是:max-age=7776000,max-age的單位是秒,從瀏覽器接收到文件以後開始計時。
若是您不知道怎麼判斷,就只用Expires,或者(爲了兼容某些老客戶端)同時設置Expires和Last-Modified。
若是topMenu.js設置了Expires直到2020年都不過時,那麼怎麼讓客戶端知道咱們修改了topMenu.js呢?
答案是修改Query String。按照規範,Query String是URL中的一個部分,好比http://server/program/path/?query_string問號後面的字符串就是Query String。
按照HTTP規範,若是修改了請求資源的Query String,就應該被視爲一個新的文件。
這個Query String能夠被服務器端CGI或者應用程序理解,並且能夠設置多個名值對(好比?foo=1&bar=2)。與緩存相關的一點是,若是Query String發生了改變,則被視爲URL發生了改變。這時候,瀏覽器會認爲這是一個新的資源。而對於服務器而言,若是有CGI或者應用程序捕捉或處理Query String,就會去處理,若是沒有,就簡單地忽略Query String,直接返回資源。
下面是推薦的瀏覽器緩存設置最佳實踐:
服務器端能夠設置緩存規則,告訴瀏覽器應該如何遵循和實現,但在服務器不能掌控的地方也許會出現一些意外:
所謂緩存被擠出,是由於瀏覽器的緩存空間是有限的,全部網站但願緩存的文件都塞在用戶硬盤,造成一個先進先出的隊列。因此即便設置了20年的緩存時間,也基本上不能保證有那麼久的生命期,而會在某一個時間點被其餘網站設置的緩存擠出硬盤。並且用戶也有可能主動清除瀏覽器緩存,某些系統清理軟件也可能清理瀏覽器緩存。這一點無可厚非,咱們從技術層面上也沒法解決,大不了讓用戶從新加載一下資源就行了。
第二個問題是,用戶的寬帶運營商爲了提升速度,可能會在本身某節點服務器上緩存您的文件(好比style.css?v1),好處是當用戶請求這個文件的時候,運營商無需來您的服務器上請求文件,而本身直接就給出了。
問題來了,若是您的Query String更新了(style.css?v2),按照HTTP規範,這理應被視爲一個新的文件,可是運營商仍然可能會拿本身節點的緩存,而不是遵循規範。有點可惡對不對?這就是咱們在用戶量極大的狀況下偵測到的狀況,雖不太常見,可是有可能發生。因此,爲了保證更新的文件下發到全部的用戶,咱們會使用更增強硬的方法:修改文件名,而不是僅僅修改Query String。
這種流程比較複雜,須要同時修改文件名和引用它的文檔裏的文件名。在QQ空間,咱們使用自動化的方式來生成新文件名並修改HTML中的引用。
修改資源的文件名,比修改後綴更可靠:
結合上面的分析,這是QQ空間靜態資源在瀏覽器端使用的緩存策略:
以上就是在Web棧流程中比較常見的緩存方面的問題。緩存可否得到性能增益,取決於不少因素。一些因素是關於您的服務器壓力、數據庫使用狀況和提供的服務類型;另外一些因素是關於您的用戶如何訪問您的網站,以及他們的網絡環境。咱們做爲工程師,只能不斷優化和調整策略,往更優的方向去優化。
延伸閱讀:
整體來說,在計算機程序和系統中,「前端」(front-end)做用於採集和顯示信息,「後端」(back-end)進行處理。Web應用程序和桌面應用程序的界面樣式、視覺呈現、用戶交互屬於前端。
咱們最多見的Web棧中靠近用戶輸入的那一部分,也就是靠近瀏覽器的部分,屬於前端的範疇。具體來講,瀏覽器中發生的一切和服務器中涉及輸入輸出的這一部分,都屬於前端工程師的工做職責。
前端工程師主要使用的語言是HTML、CSS和JavaScript,有時候會寫一些服務器的頁面模板語言(好比PHP)。
從2010年直到今天,可以明顯感覺到的一點是,前端發展到今天,已經發生了很大的變化。
在2010年,前端開發崗位必須掌握的一項能力是對IE6和IE7的兼容性。工程師須要手動把圖片拼接成CSS貼圖,CSS也不經壓縮就發佈出去。漸漸地,IE用戶愈來愈少,因此,咱們如今已經不把IE7如下的瀏覽器兼容性做爲招聘要求。不過因爲移動設備的爆炸性增加,如今前端開發崗位開始要求有移動端頁面開發的經驗,或者熟悉響應式頁面開發。Grunt等發佈流程的成熟,也讓前端工程師免除了不少枯燥的工做。
總之,變化一直都在發生,這是一個須要終身學習的行業。不誇張地說,若是我一個月沒有關注行業動態,就會發現本身已經錯過了不少新技術。
前端工程師須要涉及的知識面比較廣,我大概對個人我的偏好作一下梳理。
在招聘初級工程師的時候,我通常會考察應聘者對如下知識的掌握程度:
招聘中級工程師時,我通常考察應聘者對如下知識的掌握程度:
對高級工程師,除了上面的考察點之外,還會問這些方面的經驗:
越接近高級工程師,越考察對某個點的本質理解,以及在項目和團隊中的引導做用,而不是對某工具的使用經驗。對於上面的這些技術方向,我不會在本章中一一介紹,一個緣由是篇幅所限,另外一個緣由是有一些方向並不僅是前端工程師會遇到,而是跟後臺工程師的知識體系相通。好比代碼質量、規範、單元測試、性能、版本管理……對於這些話題,會在單獨的章節中詳細說明。
不一樣於某些「難於上手、難於精通」的職業,前端這一崗位就像暴雪公司的遊戲設計同樣:「易於上手、難於精通」。
舉例而言,HTML的全稱是超文本標記語言,超文本的意思是說,比起咱們在記事本中寫的普通文本多了一些語義化的信息,好比連接、加粗和標題等。標記語言更加簡單,就是用一些標籤把普通文本標記起來。標記語言沒有邏輯,只是描述性的標籤,因此算不上是程序語言。程序語言有的循環判斷等邏輯,HTML都沒有。這就是它易於上手的地方。
這是一段最簡單的HTML代碼,但它也是一個完整的頁面:
<!DOCTYPE html> <html> <head> <title>Page Title</title> </head> <body> <p>Hello World!</p> </body> </html>
可是HTML又很難。前端工程師對照設計稿還原出頁面以後,還要考慮機器是如何理解這個頁面的。對於用戶而言,視覺上加大加粗就是一個標題;可是對於機器,好比搜索引擎或者盲人使用的讀屏軟件,是否能理解它是一句標題?這須要咱們使用語義化的標籤。
有的時候,爲了完美地實現設計稿還原,一個視覺上看上去像一個下拉選擇器的輸入框,咱們會使用a或者span標籤加上一些隱藏的列表模塊來實現。當用戶點擊標籤的時候,就用JavaScript讓隱藏的列表模塊滑出來。
使用這種方法,咱們能夠快速地建立出在各瀏覽器中表現一致的按鈕,並且能夠輕鬆地自定義樣式,免受各類bug困擾,但同時這種「黑」科技也帶來了可訪問性問題。具體來說,如何讓盲人知道這是一個下拉選擇器?這時候能夠使用role屬性來加強這個文檔對象模型(DDM)的語義。這須要咱們瞭解WAI-ARIA的知識。
HTML雖然是比較嚴格和簡單的語言,但有時在寫代碼和閱讀代碼的時候效率比較低。John Gruber爲了改變這種現狀,在2004年發明了一種純文本格式語法Markdown13。這種語法的目標是「提供一種讀起來簡單,寫起來也簡單的語法,而且若是您樂意的話,也能夠隨時轉化成合法的HTML」。
不少書就是使用Markdown語言來編寫的。它比Word更好用的地方是,寫做者無需關注字號和樣式,只須要設置「一級標題」「二級標題」「三級標題」「加粗」「引用」等語義便可。具體的樣式能夠在美編階段統一調整。更美好的是,它不會產生任何無心義的標籤,而Word常常產生無心義的標籤。
Markdown比HTML更易讀易寫,可是瀏覽器是不會渲染的,那麼就必須進行Markdown到HTML的轉化。開發者能夠選擇兩種轉化方式。一種是在開發環境把Markdown轉化成HTML,再發布到服務器上,或者直接由服務器自動轉化成HTML文件(Jekyll支持這兩種轉化方式),總之瀏覽器獲得的已是一個正常的HTML頁面了。
第二種方式是把包含Markdown代碼的HTML頁面發佈到服務器上,而後當瀏覽器下載HTML頁面以後,頁面中的JavaScript代碼開始把Markdown解析成對應的HTML代碼。通常推薦第一種方式,由於不依賴瀏覽器端的JavaScript運行,可用性更好,也對SEO更有幫助。
有些在線工具能夠實時把Markdown轉化成HTML,好比markdownlivepreview.com。
也有人想出另外一種方法,發明了zen-coding來加快前端工程師的編碼速度。zen-coding如今更名爲emmet,在各大編輯器中都有插件。
前端技術的「易於上手」致使它在某些技術人員那裏不受待見。他們認爲HTML與CSS根本都不是程序語言,甚至認爲JavaScript是一種功能不全的玩具型語言。因此直到我幾年前畢業的時候,大學都沒有前端相關的課程和專業。而市場對前端工程師的需求又很大,學校的輸出跟市場的要求沒有對接上,因此每每出現學生找不到工做,公司又招不到人的現狀。
我並非建議直接開設「前端開發」專業,由於前端開發也是軟件開發的一個分支,與服務器開發和其餘軟件開發共享一些基礎課程,是全部工程師都須要學習的,好比項目管理、數據庫、軟件開發流程和C++等。個人建議是,在大三或者大四的方向課程設計上,或者選修課設計上增長與時俱進的前端開發課程,使用業界最新的編程語言去教學,這樣對畢業生、對用人單位都是好事。
框架(framework)和庫(library)的區別是什麼?其實這兩個詞在不一樣的語境下,有時候是能夠相互替代的。可是嚴格來講,框架應該是比庫更普遍的概念。
一個庫是一系列對象、方法等代碼,您的應用程序能夠把這個庫「連接」進來。這個庫起到了重用代碼的做用,爲您省下了重寫這部分代碼的工做量。
而一個框架是一個軟件系統中可重用的一部分。它可能包含子程序、庫、膠水語言、圖片等一些「資源」,這些資源一塊兒組成了軟件項目。框架不像庫,可能包含多種語言,某些功能可能經過API的方式讓主程序調用。
因此框架是一個更加靈活和寬鬆的名詞,在具體的情景中,它可能指一個庫、多個庫、腳本代碼,或者多個可單獨運行的子程序的集合。
之前端來舉例,jQuery就是一個庫。jQuery是純粹的JavaScript代碼,它的目標是使用更少的代碼處理DOM相關操做。當咱們使用jQuery時,至關於引入了新的對象和方法,能夠利用jQuery定義的代碼,不須要重寫這部分功能。
而Sencha公司的ExtJS是一個框架。首先ExtJS不只包含JavaScript代碼,還包含了CSS和圖片。其次它的功能是方便開發者搭建可交互的Web應用程序,裏面有一些完整功能的模塊,好比繪製可交互的圖表。因此ExtJS是一個框架。
做爲一個前端工程師,面對的框架和庫層出不窮,很容易陷入迷茫,到底應該使用哪一種?一個常見的誤區是,存在某個強大的「終極方案」,能夠解決一切Web應用程序開發的問題。常常有一些人請我推薦一些好用的前端框架,我不知道如何回答。
每一年都會有不少新的框架發佈,它們的做者並非無聊想要新寫一個框架,而是爲了解決一個新的問題。好比jQuery的優點在於方便地操做Web界面(DOM)。而Angular並非「更好的jQuery」,而是提出一種新的解決問題的思路:經過數據綁定,讓開發者直接修改數據模型,而不用關心界面(DOM)更新。GASP庫發現jQuery動畫慢的問題,就重點優化JavaScript動畫部分,它號稱動畫速度比jQuery快20倍,並且能開啓硬件加速,在某些狀況下比CSS動畫性能還要好。
所以,不要迷信大框架,有時候越是有名的框架,越須要知足更多人的需求,會封裝不少您可能不須要的資源進去。對於您來講,可能只須要一小部分功能,可是引入了一個龐大的庫。我經常看到,在某些人的簡單的我的博客中引入了一些龐然大物,可是其實沒有必要。這對應聘者來講,是減分的。
在出現一些熱門框架時,建議開發者先去了解框架的建立初衷,合理使用,而不是盲目收集。
咱們知道前端的領域很廣,因此有些大公司對它進行了更進一步的細分,好比騰訊的兩個職位「前端工程師」和「UI工程師(UI Engineer)」。
在國外,UI工程師是一個比較普及的崗位。以Google爲例,一個叫Front End Software Engineer,屬於軟件工程部,另外一個叫UX Engineer, Front End,有點相似Front End下的一個子項,屬於用戶體驗設計部。
從使用語言的角度來分,UI工程師只負責HTML/CSS,前端工程師只負責JavaScript,這是一種簡化問題的解釋方法。但我認爲這兩種職位的區分的重點並非兩者語言不同,而是責任和關注點不同。UI工程師更關注視覺上和交互上的體驗,而前端工程師更關注邏輯和數據方面的體驗,兩者是上下游合做的關係。
同時雙方的工做也有一些交集,好比UI工程師也會負責一些交互或者動畫相關的JavaScript,前端工程師也要熟悉HTML標籤才能用JavaScript去操做。雙方都必須對對方的知識有足夠的理解,合做才能進行下去。兩種職位的目標是一致的:給用戶提供更好的體驗。
騰訊的UI工程師曾經叫「網頁重構工程師」。這個名稱來自一本頗有名的牀頭技術雜文書《網站重構》(Designing with Web Standards),做者是世界上最有名的網站設計師之一,Zeldman,J.(澤爾德曼)。這本書的主要觀點是,用Web標準來「重構」您的網站,而不要用之前的非標準的方式來作網站。
用一個我我的不太喜歡的大白話來講就是:不要用table標籤佈局,而要用DIV+CSS。我不喜歡這句話的緣由是它不嚴謹,容易在糾正一個過往的錯誤的時候「用力過猛」。矯枉過正的後果是,如今有一些人只要看到table標籤就以爲是非語義化的,喜歡用DIV搞定一切。可是table並不邪惡。table用做數據表格的時候,是很是正確的。有些人在佈局這一用途上用DIV幹掉了table,卻開始對DIV上癮。
2003年《Designing with Web Standards》出版以前,全世界的設計師尚未Web標準的理念,都在用table標籤佈局,由於table可讓頁面規整。這本書普及了Web標準的理念,在那以後,設計師開始使用語義化的HTML和靈活的CSS來設計頁面。2005年此書中文版出版後,也帶來了全新的Web標準的理念。我第一次看這本書是2009年,那時我還在讀大三,讀完這本書以後幾個月就簽約到了騰訊ISD部門,職位是「網站重構工程師」,因此我對這本書有特別的感情。備註:簡歷中不要出現「DIV+CSS」這樣的字眼,會減分;也不要出現Dreamweaver,由於Dreamweaver是老式的「所見即所得」編輯器的表明。
不說遠了,《網站重構》這本書的中文名是一個意譯,代表在用Web標準來設計的過程當中,咱們要推倒之前的網站,「重構」一個新的網站。這也是「重構」這個詞原本的意思——從新構造咱們的代碼。可是這個詞被用在了一個但願能推動Web標準的職位上,給網站重構工程師這個職位帶來了額外的風險:含糊不清。可能有人會認爲這個職位一天到晚都在重寫代碼吧。這本書的譯者之一王宗義在知乎上說:
「我是翻譯《網站重構》一書的譯者之一,當時咱們3個譯者各自起了不一樣的名字,這個名字是我起的,由於譯者3我的中我是作程序開發的,借用了軟件開發中的著名書籍《Refactoring》的中文翻譯《重構》來影射當時國內網站須要用相似的方式來改變網站底層的本質。當時咱們幾個也有爭議,不過阿捷和dodo最終接受了個人想法。就是沒想到後來居然可以成爲Web前端的一個重要詞彙。」
除了對崗位名字和職責的困惑,還有一個我經常被問到的問題是「重構只會HTML和CSS,有什麼前途?」
個人回答是,首先重構不該該只會HTML和CSS。在前面「知識體系」一節中的全部知識點,重構工程師都須要瞭解和熟悉。特別是在性能、動畫、SEO、可用性和移動等方面要有本身的優點。
不過,爲了更好地跟國際接軌,同時避免「網頁重構」與「代碼重構」的混淆,咱們在2015年推進了職位改名的行動,如今咱們已經正式改名爲「UI工程師」。
對於UI工程師來講,UI開發的平臺可能不會一直是瀏覽器,還有多是原生App。備註:你們都喜歡把它讀成「誒批批」,就像一個縮寫。但App不是一個縮寫,而是對Application簡寫,因此正確地讀法是[æp]。
iOS跟Android上的軟件跟桌面軟件,或者服務器端軟件同樣,都叫Application。不過因爲蘋果App Store的普及,加上中國全部作移動端軟件的團隊的推廣,如今你們都默認App就是指手機端上軟件。本書遵循約定俗成的規範,提到App時,就是指智能手機上的軟件。
App的市場在短短几年時間內就從無到有,它的發展速度比傳統互聯網要快得多。就像最開始的網站只須要一個開發者,而如今須要不少工程師合力合做,App開發也在經歷這樣的變化。
傳統的iOS開發流程是這樣的:首先,設計師設計完PSD稿,作好標註,切出各類狀態的圖片,交給開發人員;其次,開發人員拿到各類切片,根據標註設計稿和切片,實現界面以及邏輯功能的開發。
從工程質量和進度角度講,有這樣幾個問題:
由於一個工程師要同時完成界面和邏輯的部分,因此兩者只能按隊列進行,須要較長的開發週期。若是發生了設計或者邏輯的變動,則會須要更多的時間去修改。
一我的去實現一個模塊的時候,代碼中不免會出現耦合比較強的狀況,沒有很好地MVC分離,關於視圖的代碼跟關於控制器的代碼都混在一塊兒,這爲後期的修改帶來了隱患。
由於設計師與開發人員之間經過標註和切片來溝通,可是標註自己就很不可靠,一個標註了全部間距的設計稿每每並非咱們須要的,工程師須要的是一些常量,以及當界面發生變化時的「規律」。
傳統的工程師在邏輯、健壯和成本上有很是敏銳的把控能力,可是在UI開發和用戶體驗方面的經驗就略差一些。好比,標註了按鈕與按鈕之間的距離是20px並沒有太大參考性,由於按鈕周圍可能會有空白區域。若是開發人員迷信標註上的數字,在代碼中直接寫標註的數字,成品就會和設計稿效果出現很大的誤差。並且因爲設計師和開發人員之間溝通不順暢、開發時間緊急和代碼耦合的問題,致使設計還原的質量低。
在時間緊急時,工程師更注重性能問題和數據邏輯是否正確,而不太關注「按鈕尺寸是否正確」這樣的問題。
因此我但願推動的流程是從Web開發中借鑑經驗,讓咱們本來擅長用戶體驗的Web UI工程師來進行App UI開發,而原來的App開發人員負責除了UI以外的部分。優化以後的整個流程大概是這樣的:
理想狀態下,這個方案能解決上面的全部問題。不過有些同窗可能會內心犯嘀咕,Android原生App開發須要有Java的知識,iOS開發須要熟悉Objective-C或者Swift語言,這些都不在前端工程師的技能樹裏面,如何能承擔這部分的工做?
這就是我下一章要講的:向移動端轉型。
延伸閱讀:
持續更新...
想學習代碼以外的軟技能?不妨關注個人微信公衆號:生命團隊(id:vitateam
)。
掃一掃,你將發現另外一個全新的世界,而這將是一場美麗的意外: