Try   HackMD

軟體工程工作日常

tags: 自學計劃 學習資源

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

心法

  • 持續學習是剛性要求
  • 職業遍佈全行業
  • 工程師特色
    • 非常簡單的人
    • 喜歡偷懶的人
    • 嚴謹 持續改善 追求極致
    • 熱衷於創新
  • 一個成就感驅動的職業
  • 35歲門檻
    • 創始人
      • 為公司帶來資源,吸引人才,帶來經濟與社會效益
      • 帶動團隊,能夠自驅位公司和團隊制定方向與實施計畫,解決問題,推動計畫落地
      • 創新優化 現有東西提出小而美的創新和優化 並推動執行
      • 前瞻能力 行應變化 技術潮流 思考行業與公司未來 做好準備
      • 抓重點:簡化 標準化 = 規模化 平台話
    • 貢獻者
      • 中層 做事熱情 推動工作進展
      • 探路能力: 只要方向沒問題 沒有路也能探出路來
      • 貢獻方法: 在實行中提出更好 更簡單的方法與創意
      • 解決難題: 方法總比問題多 帶團隊解決一切問題
      • 提高標準: 能夠不斷發現不足 隬補不足 解決問題 提高標準
    • 行家 Expert 對做的事情很有經驗 能正確判斷與決策
      • 降低成本 時間 金錢 人力 物力
      • 提高效率
      • 防火能力
    • 按部就班做事的人 要避免成為這樣的人

四大台階

  1. 新手
    • 明確執行上級交付任務
    • 必學入門語言:Python, JavaScript
    • 正式入門語言:Java
    • 工具:Git, VSCode IDE,英文
  2. 進階
    • 給問題 -> 方案
    • 一個問題 需要把具體問題 抽象 拆解 獨立設計解決方案
  3. 高手 30%
    • 架構師 (系統, 外部, 內部 技術 多維度綜合考量)
  4. 大神 1%
    • 權威 你的東西 可以解決另外的問題 創新領域
  • 去一家技術驅動的公司
  • 公司要做的事情是否是技術未來趨勢
  • 優先選擇在未來航道上那些快速發展的公司
  • 技術文化為主導的公司
  • 找到自己適合的路線
  • 特長,興趣,方法,勤奮

開發流程

規範

​​​​我的代碼 你能改 工作效率才會高 協同沒有障礙
​​​​一個公司不斷提升標準 才能做出更好的東西 與用戶體驗 更強競爭力

編碼規範

推薦書

  • Code Complete
  • 重構 改善既有代碼設計
  • 程式員修煉之道
    • 命名規則
    • 副檔名
    • 單元測試
    • 即使沒有規範也得自我要求

設計規範 ( API 接口設計規範最為關鍵 )

生產規範 CI/CD, DevOps, 人月神話,持續交付發布可靠的軟件的系統方法

自動化 高度水平擴展的基礎

優化代碼: 好代碼沒有止境
初級:可讀
中級:可擴展
高級:可重用

方法:

  1. 設計模式
  2. 函數編成
  3. DSL
  4. 狀態機
  5. 插件

好理解的代碼

  • 乾淨的接口
  • 方便使用者的 使用者想到的問題你都預先想到了
  • 有註解與文檔都講清楚 就不會太差

註解

  • 描述用途
  • 如何使用
  • 範例

編碼原則

  • 避免再造輪子
  • 單一職責 - 把複雜問題簡單化 模塊化 降低問題的複雜度 不斷覆用
  • 高內聚 低耦合
  • 開閉原則 - 內部行為 封閉 互不依賴 但可擴展
  • 重點是要解決什麼問題
  • KISS - Keep It Simple, Stupid

拆分任務

原則

  • 接到任務後,先做任務分解,把大任務拆成小任務
  • 可以幫你理清問題的思路
  • 簡化問題的複雜度

技巧

  1. 抓重點, 去掉部必要的 留下必須要做的 找到任務骨幹
  2. 按照單一職責原則對任務進行拆解, 列出功能
  3. 每個功能對應小程序或模塊 最後拼裝起來

讀代碼

什麼是好代碼

  1. 被反覆使用的代碼
  2. 穿越時間的代碼 - 10, 15年都沒被淘汰
  3. 好呼叫調用的代碼

好代碼的特點

  • 清晰,明確,易用,自帶使用說明
  • 非常高效
  • 通用性很高,可擴展
  • 自帶風格

代碼與說明文檔的差異

  • 代碼:What, How, Detail
  • 文檔:What, How, Why

快速提升能力途徑

  • 跟著高手牛人一起解題
  • 和優秀的人一起工作
  • 軟體工程師是一群特別愛分享的人, 所以只要你想學, 總能找到提升自己的路徑

進階篇

不再只是執行,而是要更多發會創造性,獨立設計和優化,在團隊裡不再止於埋首於完成自己的事情,而是要做好一個項目從頭到尾的把控,協調內外部的合作關係;
在學習上不再止於跟別人學,而是內項精進,搭建起自己的知識體系

需要能力

  • 獨立設計
  • 設計規劃
  • 實現需求

需求分析

  • 避免 X-Y問題:要真正確定真正要解決的問題是什麼,不要單方面只解決技術問題 通病 沒搞清楚問題核心以為此技術可以解決 弄錯了重點
  • 明確模糊不清的問題
    • 設定邊界條件:金額大一點?多大?數值?
    • 關注不可預期性:太多時間花在可預期的事情上 忽略忘了處理例外狀況

學會謀篇佈局:
需求-> 程序實現 -> 模塊拆解 -> 組合搭配 -> 思考總結 -> 獨立思考 -> 科學的解決方案

規劃程式架構

  • 圍繞著要解的的核心問題展開
  • 架構大小依照要解決的問題要恰當
  • 設計需要抽象的能力
    • 過程抽象:把問題拆解成一個個 API
    • 數據抽象

原型設計

PM 依照用戶面向設計打樣 沒有代碼 只是一個簡單的演示 讓一些模糊的問題變清楚

  • 最難解決的問題做起 及早發現問題 節省開發時間 評估 解決
  • 當下如果技術難以突破 解決 整個項目建議往後放 不必繼續浪費時間
  • 重點是好的 API 接口的設計 前後多想幾步

架構設計

面向開發人員 施工藍圖 抽象和分解 流程圖 模塊組成 之間的邏輯關係

  • 分而治之 把任務拆分個模組
    • 高內聚
    • 低耦合
  • 考慮異常與極限情況
    • 斷線 斷電 等
    • 最大乘載能力

技術調研

尋找最優解決方案
和讀代碼的能力也有正相關
分析優缺點,結合場景才有效(問題本身)

項目管裡

開發模式

  1. 瀑布式
  2. 敏捷式
  3. 班車式 - 避免延期

驗證效果 - A/B test 用數據說話

上線

做好監控(閉環 test case - env - monitor - bug - fix)與
壓測(承受10被以上的壓力)

團隊合作

外部溝通

  • 告訴業務,不要把技術當作需求解決方 這樣只會得到被動的技術團隊
  • 要把技術當作解決問題的參與方, 技術的主觀動能就會被調動起來
  • 不要把需求直接丟給技術,而是要告訴技術團隊真正想要解決的核心問題是什麼?
  • 我們面臨的所有問題都不只是單純的技術問題,大家一起努力,才能從根本上解決問題 滿足客戶的需求
  • 只有技術知道如何與業務溝通,才能把需求實現好

內部溝通 (前, 中, 後台)

平衡雙方的想法與痛點
前台是 1 中後台 團隊就是後面的 0 要圍繞著 1 去建設 去創造價值
去解決前台的需求與通點, 前台提供有價值的服務 取的平衡

學習

打牢基礎,以不變應萬變
提升內功修養,解耦,提升代碼重用度
基礎是抽象和歸納 形成進一步的推論 抓住原理 舉一反三

  1. 程式語言 基本語法 函式庫 編成(同步 異步), 編程規範, 設計模式
  2. 系統原理: 計算機系統 操作系統 網路協議 數據庫原理
  3. 中間件:消息陣列 緩衝系統 網關代理 調度系統
  4. 理論知識:算法和數據庫 數據酷範式 網路七層 分佈式系統

搭建系統 - 知識數系統學習

  • 用好知識樹:有系統地學習
  • 探索知識緣由:知道為什麼 不要硬背
  • 掌握方法與套路:學習不是為了找答案,而是為了找到方法

主動學習 提高你的學習效率

高手修養

  • 需要有融會貫通的能力 - 做技術決策不只要解決當下問題 還要思考後幾年會發生的事 未來發展方向的預判
  • 對現有系統重新佈局 - 清楚自己做什麼 不做什麼 解決什麼問題 不解決什麼問題
  • 要在一個複雜系統裡做預判與取捨 做不好這些 難以成為高手

技術職或管理職?

技術:特定的技術領域作深入的探討與研究 不涉及管理的工作
管理:側重統籌團隊完成一個個研發項目 離技術研究工作比較遠

高手 架構師

  • 前瞻能力:現在這樣 以及未來會朝什麼樣的方向演進
    要看到未來趨勢 對未來預判 做技術選型
    - 要有知識的廣度 多交流
    - 跨行業的交流
  • 取捨能力
    • 明確目標: A, B, C 方案 選擇最適合目標 系統簡單 可控充
    • 學會預測 哪個方案更優

主要工作

  • 攻克難題 :技術難題要自己去找 提升自己
      1. 整個行業公司發展方向
      1. 跟目前工作相關 需要繼續學習的領域 沒有通用的解決方法 保持一個好心態 要有戰勝困難的信心 也要有接受失敗的準備
      1. 嘗試不同方案 想方設法嘗試不同方案是最重要的
  • 技術決策
    • 這項技術是否要解決大問題
    • 是否有想像空間
    • 大公司撐腰
    • 好的技術社群
    • 殺手級應用
    • 歷經十年以上
  • 代碼評審
    • 可讀性
    • 維護性
    • 知識共享目的
    • 做出來 vs 做漂亮
    • 幫助團隊賦能
    • 不是為了找 bug 挑毛病
    • 為了 可讀性 可維護性 可重用性 程序邏輯對應需求及設計
    • 不要等做完 才做 code review
      如何做
      • 設計 是否精心設計適合系統
      • 功能 是否符合開發者意圖
      • 複雜 是否可以更簡潔 其他開發人員好接手 理解
      • 測試 是否經過正確設計良好自動化測試
      • 命名 變數 類別 方法 名命原則
      • 註解 清晰有效
      • 風格 遵循 谷歌代碼風格
      • 文檔 是否同步更新文檔

帶團隊心法

  1. 業務上給下屬指導
  2. 拆解任務 組織團隊完成目標
  3. 日常管理工作

實力服眾 - 工程師寧願被 lead不願被 manage
技術得足夠牛
要按耐住 克服和適應 要做好思想轉變 :之前想的都是讓自己變得更好 現在你要做的是怎樣讓其他人更好 怎樣讓圖隊更好

善於說服 - 相對於下命令 還是要講道理
面試 可查一個人的能力 基本素質與能力 系統設計 代碼結構化 找關鍵問題 拆解 設計
員工激勵 讓工程師有成就感
做好人才佈局
關注長期目標 哪些事情值得長期投入 做了之後可以產生規模化效應
平衡需䲡: 判斷緊急與重要 做出平衡
協同機制:保持公開透明的信息協同 鼓勵大家把自己做的東西工具化 開源化 讓所有人都能看到和使用就很重要
團隊合作:一加一大於二
合作共贏:找到利益共同點 有目標地推進 合作就會順暢很多

行業大神

丹尼斯,李奇 C語言之父 保持簡潔

林納斯 托瓦茲 Linux 之父 只是為了好玩 開源

及多 范羅 Python 允許不完美 保持開放

測試

做測試比寫程式還要難得多,因為做測試考驗的是一個人全面思考的能力
建議

  1. 做測試最好的方式不是用人工,而是寫代碼
  2. 想做好測試, 先訓練自己全面思考的能力
  • 單元測試 - 白盒測試
    • 確認所有零件模組是否都正常
    • 離問題最近的地方
  • 功能測試 - 黑盒測試
    • 模塊組合在一起後,確保功能都正常
    • 不關心具體怎麼實現, 把軟件當成一個黑盒來進行測試
  • 整合測試
    • 和周遭環境 系統上運行測試
    • 維運 測試
  • 非功能測試
    • 性能,安全,穩定,破壞,容錯,可用,靈活性測試
  • 回歸測試
    • 以前做過的測試或犯過的錯再測試一次

軟體工程師對於測試幾個重要觀念

  1. 測試要自己做, 不能讓用戶成為你的測試工程師
  2. 除了測試基本輸入以外,還要努力構想更多的邊界條件
  3. 測試接口定義的程式語意,而不是當前實現的具體行為
    * API 注重是 what, 實現注重的是 how 是細節
    * input -> output 才能確定與預期,中間過程怎麼實現非此測試的重點
  4. 對於重要模塊,編寫的時候就要做到基本性能測試
  5. 對於交付以後出現的問題與bug,要構建相對應的測試程序並提交代碼,保證以後回歸測試可以自動運行此項測試

Bug

  • 很多公司,新人進來做的第一件事,就是修 Bug
  • 考驗新人的分析思考能力
  • 很可能改錯一個 Bug 導致更大的問題
  • 像偵探一樣發現問題
    • 好 Bug: 容易覆現的問題,只有局部邏輯錯誤
    • 壞 Bug: 難覆現, 不知道問題核心
      • 多線程, 並行程序, 隨機算法, 分布式

定位 Bug

  • 模擬 Bug 場景
  • 二分法
  • 檢驗工具
  • 極限測試
  • 小黃鴨調適法(找個聽眾 梳理程式邏輯與流程)
  • 做推論,立假設,做實驗,排除

修復

  • 梳理整體設計
  • 理解代碼
  • 保證你的修改不會影響到其他部分

重構:

  1. 看整體:最終運行的情況
  2. 改細節:不只改Bug還可優化結構 讓代碼更易於理解 更安全
  3. Review: 提交前找其他人一起 review 是否完善 是否有其他建議

解決問題後:要吸取經驗教訓, 將來不再類似的問題上犯錯 養成好的習慣(例如:初始值)

簡單並不簡單

有時候有人會說 系統太簡單 覺得一個系統要有多華麗才是好系統,應該沒有遭遇過複雜代來的辛酸,

有些人從來沒有接觸過什麼龐大的系統,設計的東西使用者也不多,當然不知道簡單就是美,也不知道設計的第一個原則就是 KISS ( Keep It Simple and Stupid )

能夠大規模運作的系統,使用者方便上線,才是王道

很多系統的資料庫、不同軟硬體作業介面、加上網路錯綜複雜的關係,實際上相當複雜。
介面清楚方便,使用者進入的門檻低,是相當重要的關鍵。

尤其在大規模施行的時候,正常運作,沒有什麼重大問題,這是非常重要的關鍵

簡單才是最重要的特點,看起來簡單,其實一點也不簡單,能夠用100行寫完的程式,千萬不要寫成101行,執行的程序和步驟也是同樣的道理。

借力使力不費力,讓舊生意有新方法