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

fantasticbaby發表於2019-09-05

自我介紹

網路ID:杭城小劉,城市:顧名思義,人在杭州。1995年出生,本科畢業,現在是一名 iOS 資深工程師。興趣愛好廣泛:乒乓球、美食、電影、健身、山地車、寵物(貓、金魚)、養花。技術領域:iOS、Web 前端,寫過 Node、PHP 後端服務、寫過爬蟲、研究過反爬蟲技術方案(在 sf 上發表過文章,獲贊 148: https://segmentfault.com/a/11...)。現在年薪 35w 吧,在成長的路上...

工程師生涯的兩三事

剛畢業開始還是一名普通的 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)。功能非常多,讓我愛上了它,順道寫了一篇文章(https://segmentfault.com/a/11...)。

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

優秀工程師如何進階

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

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

遇到專案,你要認真分析、思考、編碼。完了之後想想有沒有優化空間、程式碼規範(https://github.com/FantasticL...。程式碼寫多了,可以自定義自己的工作流(https://github.com/FantasticL... 和快捷鍵(https://github.com/FantasticL...)。

很多人強調沒時間去學習,說什麼白天在工作,下班後可能要回家路上花費時間、吃晚飯、然後累了一天可能要想著健身、娛樂下。一天除非睡覺、吃飯時間你有多少時間?所以我覺得學習和工作不是互斥的事件,你需要矯正態度,工作中的每個需求都是一次學習進階和檢驗的過程,別人給了需求,你需要系統設計、架構設計、思考需要幾個類、每個類負責什麼行為、屬性,對外暴露什麼介面,類與類如何通訊、如何低耦合、高內聚、可擴充?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、定期碰頭等

程式設計師這個工作怎麼樣?

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

中秋節月餅?

馬上到中秋節了,祝願各位學弟學妹、同行們中秋節快樂、心想事成、步步高昇。
月餅我喜歡吃蛋黃口味的,哈哈、榨菜鮮肉也不錯哈。

本文參與了 SegmentFault思否徵文「一起分享你的故事」,歡迎正在閱讀的你也加入,分享你的故事。

相關文章