7月16日(實習的第一天)
看公司前端的代碼規范;了解AngularJS;了解Less;看項目代碼。
項目“明鏡”介紹:一兩年前就開始做了,是做公安機關的生意,需求是實現公安執法辦案的精細化、信息化。其中的前端部分要兼容IE8,所以要用AngularJS(1.2)。
7月17日
學菜鳥教程上的AngularJS教程;了解RequireJS;聽上級講解項目代碼;看項目代碼;了解Nginx等代理服務器。
7月18日
看項目代碼;了解MVVM;看《JavaScript高級程序設計》(以下簡稱紅寶書)。
7月19日
看紅寶書;學菜鳥教程上的AngularJS教程;向庭哥(同事)請教AngularJs;聽后端講解需求,觀摩學習庭哥根據需求寫架構;了解Bootstrap;學習Less;了解(反向)代理服務器。
7月20日
學菜鳥教程上的AngularJS教程;看紅寶書;做IFE(百度前端技術學院)的任務;了解設計模式,如工廠模式、構造函數模式、原型模式、構造函數和原型的組合模式、單例模式。
7月21日(周六 在校)
看紅寶書;學習在VS Code中用Git。
7月23日
閱讀項目代碼;了解jQuery;了解CDN。
7月24日
在菜鳥教程學習jQuery;閱讀項目代碼;在AngularJs中文網學習AngularJs;學習JSON和Ajax(通過看紅寶書)。
7月25日
在菜鳥教程學習jQuery;看紅寶書;寫案管運維系統的服務器管理的靜態頁面;學習在VS Code中用.less文件生成.css文件; 了解懶加載/按需加載(Load On Demand);閱讀項目代碼。
另外,被直接上級——雪連姐——訓了一頓,感觸良多,受益匪淺,現記錄交談內容以備忘:
姐:你負責的項目做得怎樣了?
我:庭哥(雪連姐很忙,於是就讓庭哥直接帶我)說沒有原型和接口,我們就做不了,我們要等產品經理和后端分別做好原型和接口后才能開始做。所以,我這些天都是在看項目代碼(項目代碼中用到了好多我不會的技術,於是我經常放下項目代碼,而去專門學習那些技術,比如AngularJS、RequireJS、Less、JSON、jQuery、Ajax,既會通過看網上的教程也會通過看紙質書)。
姐:那你代碼看得怎樣了?
我:我現在把index.html文件看完了,然后看了一個demo(雪連姐寫了幾個demo幫助新人上手項目),而各個文件夾或文件之間的關系我還是搞不太懂(因為我總是放下項目代碼去學項目用到的技術,所以看得慢)。
姐:你能獨自完成一個模塊了嗎?
我:(我懷疑不能,但沒好意思直接說)今天上午庭哥讓我照着他寫的一個模塊,寫一個幾乎一模一樣的出來,我覺得挺簡單的,就是copycopycopy,十幾二十分鍾就寫好了。
姐:你知道你做的這個項目的需求嗎?
(當時后端在給庭哥講需求時我也在旁邊聽了,但是他講的只是其中一個模塊的需求,不是整個項目的需求,我連這個項目到底是要做什么都不是很清楚,我把我知道的那一點說給了雪連姐聽。)
(姐聽了后,把整個項目給我介紹了一遍。)
姐:你對自己工作的期望是什么?
我:趕緊上手項目,多做項目,盡可能多地為公司創造價值以報知遇之恩。
姐:嗯。可是你連項目代碼都沒看懂,這樣你真正做項目的時候就會做得很慢。另外,你在上班時間不要看書了,幾個上級都跟我表達了對你上班時間看書的不滿。
我:項目代碼用到了我好多不會的技術,我經常要放下代碼去學這些技術,所以看項目代碼的進度慢。我看書是為了……(被打斷,我是想說是為了能看懂項目代碼)
姐:是為了你自己,但公司不是做慈善的,招你來的目的不是讓你學習,更何況,公司還付你工資。公司招你是為了讓你創造價值的。
我:我看書也是看項目中用到的技術,不看書我看不懂項目代碼啊。
姐:你這樣不行,在項目中遇到問題時應該去找直接的解決方案,事后再系統地鞏固相關知識,否則項目交付就會因你被延后。就算你真的要看書,你也應該晚上看,而不是在上班時間看。
(我覺得有道理)
我:我看項目代碼時遇到問題了會先自己想辦法解決,實在不行了我就記下來,攢到一大堆后就去請教庭哥。
姐:你這樣不對。
我:難道我要一遇到解決不了的問題就去請教庭哥嗎?
姐:……
姐:除了剛才說到的你這些問題,還有一點就是,你太被動了,你只是坐在那等原型、等接口,等着別人告訴你該怎么做。
我:我也想趕緊做項目,可是庭哥都說了,沒有原型和接口做不了。
姐:你不應該只是做技術的。沒有原型,那你可以自己分析項目需求,自己想原型應該是怎樣的,然后去找產品經理跟進;沒有接口,那你可以去找后端協商接口是怎樣的,然后前后端開發就可以同時進行,而不是等后端把接口寫好給你后你才開始寫前端。總之,你不應該等着別人告訴你該怎么做。
我:(沉吟了一會兒)也就是說人人都是產品經理咯?
姐:你能這么想很好。我覺得你之前在約束自己,我們這里很自由,你有想法就完全可以自己去找相關的人溝通。你的上升空間很大,公司招你進來是覺得你值得培養。我們希望你能從全局的角度來看一個項目,並且能提出自己的想法。否則會發生這種情況:如果產品經理給你的原型或者后端給你的接口不合理,而你不知道,結果你還是根據不合理的方案來做,做到最后才發現不對,然后全部推倒,重新做。
我:嗯……我之前確實只是想着我只要做好技術、完成好被分配到的任務就好了。
姐:那你覺得你今后該怎么做?
我:還是要看項目代碼。
姐:為什么是看項目代碼?
我:需求方面,我會再去問下庭哥,如果還不夠,就叫庭哥和我一起去找后端。看項目代碼不止要弄懂其中用到的技術,也要搞清楚整個項目的結構。
姐(起身走人):那就說到這里吧。
(這時,我其實很想問她我到底具體該怎么做,但擔心會讓她覺得我還是想別人告訴我該怎么做,就沒問了)
7月26日
研究運維系統;看項目代碼。
7月27日
學習angular-ui-router的用法。
7月28日(周六 在校)
看紅寶書。
7月29日(周日 在校)
看紅寶書;看《JavaScript語言精粹》(以下簡稱蝴蝶書)
7月30日
寫運維管理系統的版本中心的區域服務列表。在這個過程中學到了:使用Bootstrap的彈框(Modal,模態框);使用Less(只用到了嵌套)。
7月31日
改運維管理系統的版本中心的區域服務列表。在這個過程中學到了:配置、重啟nginx(命令行重啟不行就用任務管理器結束再啟動);使用restangular(實現Ajax);使用WdatePiker(日期插件);通過在代碼中插入debugger來添加斷點輔助調試;使用Layer插件實現“loading”提示。
和超哥(我的直接上級的直接上級)、超哥的朋友(也是同事,職位也比我高)進行了一次從火車站檢票機設計開始的交談,其中發生了兩件令我非常震撼的事,再次讓我堅定了“我要努力工作”的信念:
一、超哥對我說“你是來學習的,不管以什么方式,你都要盡可能多地學習”。而之前我聽別人(包括HR和我的直接上級)說過不下一次,實習生不能抱着來學習的態度來實習,公司不是做慈善的,公司給實習生付工資是要實習生為公司創造價值的。而超哥竟然這么對我說,我非常感動。
二、超哥的朋友是在我和超哥剛開始交談時來的,然后就在一旁聽,時不時也參與討論、發表自己的見解,這種情況持續了——保守估計,至少半小時,我懷疑可能有1小時。我當時也沒多想超哥的朋友為什么這么做,直到我和超哥交談完,他才表明了自己的來意——他是找超哥有事的!我震驚了——他竟然沒有打斷我一個實習生和我的直接上級的直接上級的交談,而在旁邊等我們交談結束等了那么久!
8月1日
寫運維管理系統的版本中心的區域服務列表。在這個過程中學到了:使用Postman測試前后端間的接口能不能調用;在瀏覽器的F12中查看XHR的情況;谷歌瀏覽器的F12中可設置自動清除緩存以實現刷新就能更新JS文件而不用重開新窗口(HTML和CSS文件有時可能還是需要手動清緩存才能更新);前后端聯合開發(協商數據格式)。
寫運維管理系統的版本中心的服務包管理列表、鏡像管理列表、數據庫腳本管理列表、區域服務注冊。
8月2日
統計部門的網口信息(打雜)。
寫區域服務注冊;寫系統服務自檢;寫終端控件自檢。在這個過程中學到了:在F12中更改樣式可以實時地看到效果。
8月3日
對新增區域服務注冊的區域信息的接口;改平板狀態測試並對接口;寫新增區域服務注冊的服務器及服務器注冊。在這個過程中學到了:jQ對象用不了JS對象的方法和屬性,反之亦然;AngularJS的表達式可以用在元素的屬性中;AngularJS要使用原生JS的事件對象(常用e表示)是通過往在HTML里的事件監聽器傳入$event實現的;jQ對象的方法有:hasClass()、parent()、prev()、attr()、text()、val()、append()、addClass()、removeClass()、children()(參數可以是CSS選擇器)、remove(),jQ對象的屬性有length。
8月4日(周六 在校)
看蝴蝶書。
8月5日(周日 在校)
看蝴蝶書,計划秋招。
8月6日
新增區域服務注冊的服務器及服務器注冊的頁面開發。在這個過程中學到了:動態生成的元素的事件不會被監聽,要用$compile,但是應盡量避免用了AngularJS還要操縱DOM;$(JS對象)可以把原生JS對象轉為jQ對象。
看完了蝴蝶書。
8月7日
新增區域服務注冊的頁面開發。在這個過程中學到了:有時不是沒有跑進去函數,而是跑進去了但函數內的代碼沒有“明顯”的效果(可用debugger判斷);AngularJS的臟檢查;雖然我是前端,但也要了解業務(頁面的需求、作用和目的),否則就會像今天一樣,花了大量時間寫頁面后才發現寫錯了、要大改。
8月8日
區域服務列表的頁面開發和對接。在這個過程中學到了:如果有一行JS代碼報錯了,那之后的JS代碼都不會執行;AngularJS頁面傳參的方法之一是用ui-router的$state.go接口,跳轉后的頁面獲取傳參要用$stateParams,注意同時要給路由的url添加上參數;刷新是重新請求當前頁面,如果沒有回到當前頁面,那就是回到當前頁面后立刻又跳轉到了其它頁面;別忘了Ajax一般是異步的,所以在一個用了Ajax的http請求的語句后立刻打印返回結果是打印不出東西的;$index是ng-repeat循環的序號;訪問對象的屬性時如果屬性不存在,並不會自動創建;控制台的錯誤提示提供了跳轉到錯誤代碼的鏈接,雖然可能它可能隱藏在一堆鏈接之中;AngularJS關心的是數據而不是DOM,所以想要操縱DOM還是要通過原生JS或jQ;用谷歌瀏覽器的插件展示JSON;AngularJs的核心是數據模型(MVC的M或MVVM的M),所以無論做什么,都要想着通過數據模型實現,記住,M變了,則V就會自動更新(C中除了事件之類的東西,都只會在頁面初始化的時候執行);在for循環中聲明循環長度反而比不聲明更慢,原因可能是現代瀏覽器已緩存了終止條件(指像arr.length這樣的東西),因為相同的原因,循環的減值迭代對性能可能甚至有害無益。
另外,我還向后端提出了改善接口以優化性能的方法(把多個http請求改成了1個http請求)。
8月9日
區域服務列表的頁面開發和對接。在這個過程中學到了:刪除數組非頭尾的元素用splice;||的左操作數如果為null(為undefined不行)則返回右操作數;AngularJS的表達式里不能空格;可用ipconfig命令在cmd查ip信息;ng-class;Edge瀏覽器的F12中有些神奇的標識符行為怪異,比如c(與b和d的行為都不同);利用JSON的兩個方法可以實現深復制;跳出多重循環可通過多聲明變量記錄是否跳出內層循環來實現;由事件造成的兩種狀態之間的切換,可以通過設置一個變量,然后每次觸發事件時根據這個變量的值執行對應的操作並更改變量。
服務中心的頁面開發。
8月10日
區域服務列表的頁面開發;服務自檢的頁面開發;公共組件的樣式更新。
進一步了解模塊化開發;進一步了解單頁面應用(寫代碼時注意單頁面應用的相對路徑是相對什么)。
8月11日(在校)
進一步了解RequireJS。模塊:將程序分解成離散功能塊(discrete chunks of functionality),並稱之為模塊。每個模塊具有比完整程序更小的接觸面,使得校驗、調試、測試輕而易舉。 精心編寫的模塊提供了可靠的抽象和封裝界限,使得應用程序中每個模塊都具有條理清楚的設計和明確的目的。模塊的優點:可維護性、避免命名沖突、代碼復用。AMD(異步模塊定義)規定模塊必須采用特定的define()函數來定義。RequireJS可以避免加載js文件時網頁失去響應(因為js文件阻塞瀏覽器渲染),還可以輕松實現依賴管理。我了解js模塊是從立即執行函數開始的,但實際上業界采用的模塊化方案,卻並非是一個一個由IIFE+閉包形成的集群,而是用AMD或ES6模塊等模塊化實現。原因可能有這兩個,一、閉包的性能問題。二、當模塊增多的時候,需要解決模塊間的依賴管理問題。requirejs和angular都有模塊管理,但兩個概念又不一致:requirejs模塊管理,不單單是代碼模塊化,還提供了模塊加載的功能;angular模塊管理,更在乎的是代碼邏輯上的模塊化,避免全局變量污染,並不提供js文件層面的加載功能;作為邏輯模塊管理,其實用requirejs的模塊管理就夠了,所以除了angular原生的controller、service外,業務相關的公用庫,用requirejs吧。
了解webpack。webpack是一個構建工具(模塊打包器),能做到requirejs能做到的模塊化開發,而且webpack和requirejs一樣,也支持AMD,但還能做更多,比如打包/優化性能(通過減少http請求來提高網頁響應速度)。很難配置,但一勞永逸。
了解node.js。node.js是一個javascript運行環境,能讓javascript脫離瀏覽器而在服務端運行,可以用來開發web服務端。node.js有非阻塞式 I/O、事件驅動的特性。前端開發和node.js開發, 兩者間除了js是重合的以外, 其它技能互相之間完全沒有關系。如果你要建一個社交網站,你的好友會隨時推送新的狀態,然后你的新鮮事會實時自動刷新。要達成這個需求,我們需要讓用戶一直與服務器保持一個有效連接。目前最簡單的實現方法,就是讓用戶和服務器之間保持長輪詢(long polling)。HTTP請求不是持續的連接,你請求一次,服務器響應一次,然后就完了。長輪訓是一種利用HTTP模擬持續連接的技巧。具體來說,只要頁面載入了,不管你需不需要服務器給你響應信息,你都會給服務器發一個Ajax請求。這個請求不同於一般的Ajax請求,服務器不會直接給你返回信息,而是它要等着,直到服務器覺得該給你發信息了,它才會響應。比如,你的好友發了一條新鮮事,服務器就會把這個新鮮事當做響應發給你的瀏覽器,然后你的瀏覽器就刷新頁面了。瀏覽器收到響應刷新完之后,再發送一條新的請求給服務器,這個請求依然不會立即被響應。於是就開始重復以上步驟。利用這個方法,可以讓瀏覽器始終保持等待響應的狀態。雖然以上過程依然只有非持續的HTTP參與,但是我們模擬出了一個看似持續的連接狀態。我們再看傳統的服務器(比如Apache)。每次一個新用戶連到你的網站上,你的服務器就得開一個連接。每個連接都需要占一個進程,這些進程大部分時間都是閑着的(比如等着你好友發新鮮事,等好友發完才給用戶響應信息。或者等着數據庫返回查詢結果什么的)。雖然這些進程閑着,但是照樣占用內存。這意味着,如果用戶連接數的增長到一定規模,你服務器沒准就要耗光內存直接癱了。這種情況怎么解決?解決方法就是剛才上邊說的:非阻塞和事件驅動。下一代瀏覽器很快就要采用WebSocket技術了,從而長輪詢也會消失。在Web開發里,Node.js這種類型的技術只會變得越來越重要。
看IFE的閱讀材料(Promise、適配器模式、橋接模式、觀察者模式(發布訂閱模式))。
8月13日
寫路由;新增服務包的頁面開發和對接。遇到的問題:一個有上傳文件功能的表單,要實現用戶點擊表單的保存時,第一步先把文件上傳到一個接口,並拿到返回的信息,第二步把返回的信息和表單的其余信息發給另一個接口。最初的設想是用一個<form>專門上傳文件,但這樣做存在一個問題:上傳文件后頁面會跳轉。為了解決這個問題,我引入一個對用戶隱藏的<iframe>作為子頁面,使跳轉后的頁面指向這個<iframe>,這樣就避免了父頁面的跳轉。但這樣又引入了一個新問題:子頁面和父頁面之間垮了域。所以,盡管在父頁面能拿到子頁面這“整個的東西”,但卻幾乎無法訪問其中的屬性和方法,這樣我就難以取到上傳文件后返回的數據(因為返回的數據在子頁面里)。后來雖然我了解到或許可以使用HTML5的postMessage方法實現父子頁面的跨域通信,但我還是決定換種思路,用插件。下班了,明天試試。
8月14日
新增服務包的頁面開發和對接。遇到的問題:打算用jQuery.form解決昨天的問題。我本來以為jQuery.form可以解決跨域的問題,后來發現它只能解決上傳文件后頁面會跳轉的問題(即實現異步上傳文件),跨域的問題要用nginx來解決。nginx解決跨域的原理:既然瀏覽器不能跨域,那就讓瀏覽器訪問同源的url,然后讓nginx拿着這個url去找要跨的域,即nginx相當於一個中介。
XSS利用的是用戶對指定網站的信任,CSRF 利用的是網站對用戶網頁瀏覽器的信任。用JS在控制台打印特殊字符要用反斜杠轉義。
8月15日
服務包管理列表的對接。
服務包版本管理列表(運維)的頁面開發和對接。
鏡像管理列表的對接。
新增鏡像的頁面開發和對接。
8月16日
服務包版本管理列表(運維)、鏡像版本管理列表(運維)的頁面開發和對接。
平板狀態測試的頁面開發和對接。
8月17日(實習的最后一天)
服務包版本管理列表(運維)、鏡像版本管理列表(運維)的頁面開發和對接。在這個過程中學到了:UI Bootstrap的模態框傳參。