1995年的資深工程師,和你談談如何進階

自我介紹

網絡ID:杭城小劉,城市:顧名思義,人在杭州。1995年出生,本科畢業,現在是一名 iOS 資深工程師。興趣愛好廣泛:乒乓球、美食、電影、健身、山地車、養了2只布偶貓(Simba & Bella)、養花。技術領域:iOS、Web 前端,寫過 Node、PHP 後端服務、寫過爬蟲、研究過反爬蟲技術方案。在成長的路上…

工程師生涯的兩三事

剛畢業開始還是一名普通的 iOS 工程師,做的東西一般是跟着 TL 開會討論需求,完了自己腦補技術細節,完了編碼、UI 還原、測試、發佈、維護。在第一家公司做開發的時候,某次和一個後端工程師對接口遇到問題,人家說“別跟我說接口有問題。你跟我說是什麼樣的問題?我需要參數”。然後初生牛犢(小菜鳥)就把 Xcode 下面的 Debug 信息截圖發出去,被人懟,說我需要網絡的具體參數,Request、Reponse 信息。當時很尷尬,我在想封裝好的網絡框架,我一個個下斷點 Debug 截圖給你嗎。後來才知道有 Charles 這麼個抓包工具,簡單搞了搞 Charles 之後就將截圖 Request、Response 信息給他了,這樣他沒話說了,老老實實改了接口 Bug。當時他問我 Request、Response 的時候真的超尷尬,我說你等我半小時,我找好發給你。(😂 Too young, too simple)。

第一次看到 Charles 有那種看到仙女一樣的感覺,因爲它不只是可以抓包看 HTTP、HTTPS 的網絡請求,還可以模擬數據、篡改網絡請求信息、篡改網絡返回的信息、模擬弱網環境、接口壓力測試(類似於 Load Runner)、還可以隔山打牛(Map Remote:請求域名 A 下的接口 a 卻重定向到域名 B 下的接口 b)。功能非常多,讓我愛上了它,順道寫了一篇文章

另一個有趣的事情是慢慢在公司有了起色,自己鑽研進步了很多。在做的東西 iOS Native + Hybrid 模式的應用,因爲在校實驗室期間有 web 前端經驗,所以在公司經常設計 JS 與 Native(iOS、Android)的通信機制、Hybrid 的能力等等,Debug 的時候經常踩坑,比如 Android 瀏覽器訪問 localStorage 需要開啓權限、某些低版本的 Android 不支持 ES6 寫法(Vue、React等工程自動引入 Babel 打包構建的工程是轉換過的。之前的老工程直接寫 ES6,則低版本瀏覽器不支持)。還有一些 CSS 在 iOS、Android 兩端表現不一致。因爲公司和別的上市公司合作項目,成立了微信羣,我們公司對外輸出 SDK,由於另一名同事解決不了。直接跟我說“劉哥,上吧”。由於經常解決疑難雜症,導致對面那個公司的項目經理,問我要不要跳槽,讓我去他們公司工作 😂

優秀工程師如何進階

說到工程師,肯定要談如何進階。那麼我作爲一個剛畢業不久,從 普通工程師 -> 高級工程師 -> 資深工程師,談經驗不敢當,說說個人的心路歷程吧。

首先剛踏入職場,你必須完成從學生到職場的轉換,這個轉換不是說換個地方做事就行了,而是態度和觀念需要改變。學生時代在校不管是課程作業還是畢設、或者學校實驗室的那些東西,現在看看都很 low(排除一些高端院校的頂級實驗室項目)。

遇到項目,你要認真分析、思考、編碼。完了之後想想有沒有優化空間、代碼規範。代碼寫多了,可以自定義自己的工作流快捷鍵

很多人強調沒時間去學習,說什麼白天在工作,下班後可能要回家路上花費時間、吃晚飯、然後累了一天可能要想着健身、娛樂下。一天除非睡覺、吃飯時間你有多少時間?所以我覺得學習和工作不是互斥的事件,你需要矯正態度,工作中的每個需求都是一次學習進階和檢驗的過程,別人給了需求,你需要系統設計、架構設計、思考需要幾個類、每個類負責什麼行爲、屬性,對外暴露什麼接口,類與類如何通信、如何低耦合、高內聚、可拓展?Unit test 設計等等問題都要考慮清楚。剩下就是編碼實現了,這個時候考慮的就是一行行代碼如何書寫,才符合團隊規範、業界規範、代碼如何分組、如何做到自解釋、代碼註釋等等都需要做到極致。完成後跑單元測試、最後集成測試。提交給測試工程師的項目個人至少保證 90% 的測試 case 通過,ut 覆蓋率至少 90%。關於測試也有一堆經驗,等後期我會出文章講講。

個人學習和工作的時候注意積累和歸納總結,梳理自己的技術棧和知識體系,等下次學到了新的東西塞到體系裏面對應的地方去。最後你的知識系統會越來越完善。

工程師強調幾個方面:

  • 專業能力是第一要素。你的專業能力決定你是否具有不可代替行和價值。
  • 軟技能決定你的廣度和效率:比如查找知識的能力、快速定位問題的能力、快捷鍵的熟練程度、自己的 WorkFlow、代碼規範程度、爲團隊打造工程化的程度。比如我經常翻牆查找資料,公司的網絡和自己家裏的網絡都可以翻牆查找資料。使用 iterm2 自己制定了很多 iOS、Web 相關的快捷鍵、這將顯著提高工作效率、一天提高1分鐘,一年下來就不少的時間節約(如果想看我的快捷鍵或者 WorkFlow 可以在評論區留言)。團隊的代碼規範在前端開發中有 ESLint 集合業界的 js 規範比如 airbnb 或者標準的。iOS 這端我使用 shell 腳本開發了一套團隊的代碼規範,最後還有一套 shell 腳本檢測全局工程的代碼規範,最後會生成報表用瀏覽器自動打開。
  • 不要過分追求框架等表層東西,要思考原理。很多人初學前端會糾結用 Vue、React、Angular哪個?我覺得沒必要,你首先需要打好基礎功,基礎功好了,框架就很好學習了。框架一般做的事情是在現狀的基礎上做了封裝,讓你很方便的做某些事情,或者使用一些設計模式或者先進一些的開發方式(比如單向數據流、虛擬 Dom、組件化等)。這些東西爲什麼誕生?還不是傳統的命令式編程效率太低、操作 DOM 成本太高了,複雜邏輯的頁面維護很複雜嗎?因爲是命令式編程,所以你需要思考每一步步驟,以及中間產生的狀態變量,告訴計算機如何處理具體邏輯,導致代碼量太大,維護不方便。響應式編程 + 虛擬 DOM + 單向數據流催生了類 React 的前端框架。比如我之前就看過 Vue 的關鍵邏輯的源代碼,看過 React 的 Redux 的源代碼。
  • 你的水平高了你關心的技術點應該就是業界的研究方向了,比如多端融合能力。你會看到現在的 Flutter、React Native、Hybrid 他們不是沒有關係的,而是一步步演進升級。電商公司(其他業務不再舉例)業務經常變、運營活動經常變,傳統的開發方式需要發佈、審覈、上線,iOS 這裏尤其負責,審覈嚴格,隨意這樣的流程不能滿足,早期的 Hybyrid 就是這樣誕生的,Native 提供基礎能力,JS 寫業務邏輯和 UI操作,但是這樣很零散,比如 UI 操作,JS 需要一個 UI,Native 就需要事先註冊號或者提供好這樣的能力。React Native 解決了這個問題,JSX 的方式寫業務,操作數據,setState 做 diff 算法計算出需要更新的虛擬 DOM,在移動端這樣的虛擬 DOM 就可以和 Native UI 組件進行綁定,這樣就可以有 Native UI 能力。JS 寫業務,Native 捕獲事件回調給 JS,然後操作數據,繼續 setState。這樣還不錯,但是在低端手機上會卡頓,其中一個問題就是不同語言(JS、native語言)之間通信效率比較低,Flutter 誕生了,Dart 誕生就是爲了解決 JS 的缺點。Google 自己的 skia 渲染引擎封裝了 OpenGL 接口,所以不需要 Native 提供 UI 能力,Dart 使用聲明式寫 UI、Skia 去渲染看上去還不錯,所以一開始國內的鹹魚團隊就在跟進 Flutter,現在阿里 all in Flutter。

經驗分享

大多數人喜歡碎片化時間閱讀一些文章或者自己感興趣的技術博文。比如你在上下班路上、點餐等飯時間看幾個公衆號技術文章,很多人會大致瀏覽完。我覺得這樣不如不讀,或者收效甚微。因爲腦子只有印象的話,看完的文章過半年後問,肯定一問三不知了。與其多篇文章大致瀏覽,不如精讀一篇文章,並動手實踐每個技術點和細節。必要時做好博文記錄最後總結輸出。

另外對於每個技術不要停留在會用(我稱之爲 api 資深工程師)而是知道這個 api 背後的原理,設計模式、設計的優缺點。比如 iOS 領域著名的 WKWebView 很多人知道 NSURLProtocol 可以攔截其他的網絡請求卻攔截不到它裏面 post 的 body 內容。你查看了 webkit 源代碼之後就知道 WKWebView 官方宣傳快,是說自身做的事情少了,很多任務比如網絡是新開了一個獨立線程去處理,所以獨立線程處理網絡完了通過 IPC 的方式將 post 的 body 通過壓縮然後 IPC 給 WKWebView 這會非常消耗資源,所以系統索性不給你傳遞了。

帶着這個疑問看看 Chrome for iOS 的開源項目(至於爲什麼會看它?因爲個人研究多端融合能力、Chrome 這樣的瀏覽器如何渲染處理等流程感興趣所以看的),看到它裏面在用 post 傳 body。納悶了,和 webkit2 源代碼不一致。這些現象等都是需要深入纔可以理解的。當你遇到一個問題發現網上找不到資料或者資料比較少的時候你就算對這個問題的研究比較深入了。

此外,不管做產品還是技術都不要湊合,必須要做到極致或者最好。上面說的反爬蟲技術是我在公司擔任 iOS 工程師的時候做的。當時進去一個月寫完一個 App,追到 Android 進度。然後不滿足於進度,在此基礎上做到的一些優化、且通過抓包方式進行業務測試的時候找到了 Android 和服務端的一些 Bug,最後還發現安全性較低,在此基礎上,做了 HTTPS + 證書驗證 +RSA 證書校驗、AES 數據加密,做到了 App 被別人抓包馬上就斷掉鏈接。假如技術再高明些看到請求信息也是加密過的(不是 HTTPS 自己的加密,是自定義的加密)和防重放策略。

之後鑑於公司的網站太落後,用 Vue 進行重寫,再做了安全升級等工作,這樣總經理看到個人能力,擔任小公司大前端負責人的崗位。這階段的成長也蠻快的
然後換工作,也是一樣,嚴格要求自己,半年時間做了無痕埋點、組件化、模塊化、Hybrid 能力提升、商城業務模塊開發等等,從高級工程師升級爲資深工程師。個人目標2年後成爲技術專家。

很多人會去問有沒有較好的學習資料是什麼?我覺得如果有人回答除官方文檔之外的答案,那麼這個人本身就不夠專業。在我看來官方文檔是設計者(最熟悉技術細節的人)寫出的註釋和說明。那麼肯定是最佳實踐。舉個例子 Objective-C 裏面對 NSDictionary 進行處理成 JSON 字符串,解析的結果是會帶空格和換行符的,但是服務端恰好如果對空格和換行敏感的話,那麼你們的邏輯就會和預期的不一致。看看下面的代碼。

NSJSONWritingSortedKeys(兼容性)、NSJSONWritingPrettyPrinted (換行符)
NSDictionary *dict = @{@"name": @"lbp"};
NSData *json = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding];

很多人轉換後可能會去做字符串處理,正則替換空格和換行符。稍微好一些的可能會看到官方的在 iOS11 推出一個新的枚舉值 NSJSONWritingSortedKeys。那麼就是判斷當前系統小於 11 則字符串替換,否則就使用新的參數。如果你仔細看官方文檔,上面說的非常仔細。看看下面的官方說明。

Generate JSON data from a Foundation object. If the object will not produce valid JSON then an exception will be thrown. Setting the NSJSONWritingPrettyPrinted option will generate JSON with whitespace designed to make the output more readable. If that option is not set, the most compact possible JSON will be generated. If an error occurs, the error parameter will be set and the return value will be nil. The resulting data is a encoded in UTF-8.

另外,越來越覺得架構設計對於架構組同學來說是非常重要的。

爲什麼?假設你一個需求,預期10天時間;前期架構設計、類的設計、Uint Test 設計估計7天,到時候編碼開發2天完成。

這麼做的好處很多,比如:

  • 除非是非常優秀,不然腦子想的再前面到真正開發的時候發現有出入,coding 完發現和前期方案設計不一樣。所以建議用流程圖、UML圖、技術架構圖、UT 也一樣,設計個表格,這樣等到時候編碼也就是 coding 的工作了,將圖翻譯成代碼
  • 後期和別人討論或者溝通或者 CTO 進行 code review 的時候不需要一行行看代碼。你將相關的架構圖、流程圖、UML 圖給他看看。他再看看一些關鍵邏輯的 UT,保證輸入輸出正確,一般來說這樣就夠了
  • 軟件項目管理也一樣,確定好關鍵時間節點、甘特圖、確定干係人、kick-of meeting、定期碰頭等

程序員這個工作怎麼樣?

個人是很喜歡程序員這個工種的。做事情純粹些、且培養了不斷學習思考的能力和習慣。不斷學習和思考是每個行業都需要的基本素養,所以看到事情本質、不斷學習、不斷進階就是人生常態吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章