只有累積,沒有奇蹟

2021年2月20日 星期六

[筆記] 商業思維學院 - 技術工作者的商業思維 課程心得

前言
在 2020 年底報名了由 Gipi 創辦的 商業思維學院 課程,希望自己不管是在管理或是視野上可以有所提升,在 2021.1月參加學院中技術工作者的商業思維主題講座筆記,Gipi 院長邀請好朋友 91 分享技術工作者如何創造商業思維,討論內容如下
技術人的商業思維
職涯發展與相關技能養成
如何有效學習(輸入),並產生商業價值(輸出)
這篇是根據該主題講座整理的筆記,整個簡報分為三部分
  • Job (大事記) : 職涯在那些公司服務過,為甚麼會選擇這些工作,在這份工作擔任什麼樣的職務跟角色? 。
  • Work (創造連結) : 在這些工作之外做了甚麼樣額外的嘗試 ? 例如出書、講課、社群活動。
  • Career (技術變現) : 這些事情如何影響我職涯的選擇。
每個人的職涯路線可能不一樣,透過分享可以讓聽到的人有一些不一樣的想法,可以學到對自己有幫助的部分。以下圖片為小弟聽完整場分享後整理的懶人包

大事記
所做的每一件事情,分享在當時的 context 底下為什麼會做出這樣的決定,與決定背後考量因素有那些,如何達到自己所設定的目標
  • 叡揚 : 基本功,奠下基礎 2009 MVP Start
  • Yahoo : 對做交易型系統最有興趣,像是電商或是銀行;評估 > 職涯剛開始,未來發展最廣,文化 open (雖然薪水最低,視野會放到 global
  • 東森信息 : 前面兩份工作累積的技能與能量,都在這份工作有機會發揮也有很多導入跟改變的機會,艱鉅的挑戰也相對大
  • Odd-e : 喜歡 training 與顧問,先從自己熱愛的事情出發並想辦法變現 (商業思維),給自己一年的時間嘗試看看養不養的活自己,嘗試之後看起來活的還不錯

創造連結
在工作以外的部分 91 也做了蠻多有趣的嘗試,在業界比較獨特與不可取代性的競爭優勢可以用一句話行形容
91 = Agile x Dev (敏捷搭配開發)
  • 社群是寶貴資源與優質連結的所在地,並將所學到的知識回饋給社群;
  • 並持續地從2008年開始將技術知識整理成文章放在點部落至今,透過參加鐵人賽撰寫技術系列文強迫自己成長
  • 成立 FB 粉絲專業,將看到有興趣的題目分享自己的觀點與想法,如果討論串內容是有大家有興趣的會在整理成技術文章

技術變現
從 YAHOO 開始進行一些嘗試,從書籍的校稿到在 Modern Web 擔任講師,以及在 Skilltree 開始授課,在 YAHOO 的第二年 52 周每周都會在公司內部 host 一場教育訓練,也透過這個嘗試讓自己知道很適合做教育訓練 (天職),從內部的教育訓練到在 meeting up 擔任講師,再到公開課程的教育訓練,這些嘗試都是由淺到深有相關聯,可以持續累積能量到大幅變線的部分,到後來有機會加入 Odd-e 團隊並開始決定自己出來做,擔任多間公司顧問與公開培訓的課程。

職涯成長
從 JOB > WORK > CAREER > Value 是什麼 才變演變成現在的 91

JOB
  • 時間最貴 :
    • 節省老闆的時間 : 老闆的薪水是最貴的,他的一分鐘成本跟你的一分鐘公司付出成本差多少,如果可以讓老闆節省這些時間,就是替公司賺錢;同時也可以證明你有能力做這些事情,老闆不用花這些時間在你身上,他也可以去做更重要的事情。
    • 節省團隊的時間 : 舉例來說團隊中有十個成員,你如果可以做一些事情來節省團隊的時間,這樣就有9份的戰力,也就是提供9倍的價值
    • 用時間賺時間 : 時間是用錢買不到的,怎麼樣讓自己有更多的時間,像是自動化、買工具、上課進修技能的提升
  • 角色 : 技術人員不管在公司擔任什麼腳色,都不要被公司綁死。要持續的接觸外面的世界,因為外面的世界(技術)變化得很快,因此 91 在選擇工作時重視的是公司是否鼓勵員工進修,在學習後再回饋給公司讓團隊更強
  • 溝通 : 不管在哪份工作或是擔任甚麼職位,與主管的溝通是即時且透明的,會在問題發生的第一 時間告知主管,拆解問題並提供合適的解決方案來解決。並且持續同步主管的期望與自己的成果,否則做得再好主管也不知道(Value First)

Work
很多事情都要嘗試過才知道什麼是真愛,就像小朋友一樣會讓他上很多才藝班目的就是為了讓他找到喜歡的東西(事物),當找到幾個有愛的領域可以嘗試將他產生綜效進行變現,91 舉自己作為例子,一開始是從開發程式語言(C#)奠定基礎,喜歡架構設計與教育訓練可以在團隊中擔任 Team Lead 或 Tech Lead 帶團隊前進,對敏捷開發與極限編成有興趣,這些面向就是市場最需要的各種角色。有些人只知道理論沒有太多實務經驗,可能沒有辦法將想法落地;或是有這些實務經驗但不太會教人(培訓),怎麼樣讓自己有不可取代性與價值,這也是綜效與變現很重要的一點。

Career
  • 選擇 : 91 也分享在選擇工作時自己會看重的是成長 > 績效,原因是成長是伴隨著職涯(Career)走,績效是跟著 Job 走,很多 KPI 跟 Goal 可能是公司的目標但不一定可以對個人成長帶來幫助,例如將 SVN 換成 GIT,可能是公司的目標但不一定可以為自己帶來持續累積的能量與學到東西 (雜事)。為了不要為 KPI 工作,在挑下一份工作時會選擇三年內都不加薪也願意去,因為選擇的工作有想學的東西,再談薪水時會把三年內要加薪的幅度都灌進去,從不同的角度看在下一份工作自己還缺少什麼,哪裡需要加強與精進的地方,而不是為了 KPI 是為了自己職涯而工作。
  • 目標 : 建議在選擇工作時怎麼樣突破職涯薪水的天花板,而不是只看當下那一份工作的收入,在每一份工作做的選擇跟嘗試跟投資自己都是重要
  • 權威 : 用成果來描述你自己,成果是所有職涯的累積(JOB + WORK),持續地的用 JOB 與 WORK 輸出成果,讓你不用講別人也知道你的能力、工作態度、擅長的領域與可以解決甚麼樣的問題,當你今天想換個跑道時,就會有人(老闆)主動的跟你接洽談希望你解決新公司甚麼樣的問題,可能只是簡單吃個飯省去 interview 的過程不用準備履歷,把準備履歷 push 的形式換成 pull 省下準備履歷的時間,技術能力基本上是一翻兩瞪眼,成果就是最好的履歷,另外也是要看戰功、口碑與可信的推薦。
Value
  • 初心 : 擇己所愛,不要忘記自己的初衷
  • 人脈 : 一句話來說就是可以幫上多少人。如果其他人有問題,自己有沒有能力可以幫助別人,與學員與企業客戶建立連結,並透過觀察與分析市場來得知那些公司有問題。
  • 自由 : 當你是權威,就可以做自己 不委屈

職涯覆盤
這一 part 主要目的是希望聽完這兩小時的分享後,盤點自己有哪些地方可以額外創造商業價值,真正喜歡的東西是什麼以及如何變現 ? 變現的部分不一定是錢,可能是對工作有累加的幫助、可能是影響力…etc,希望的是聽完後從自己出發做技能盤點,在這邊 91 列了幾個問題希望我們可以思考一下
我目前用來創造商業價值的主要依據為何?
我真正感到熱愛的技能、工作、喜好、專業是哪些?
如何從我熱愛的領域變現或創造商業價值?
誰會需要這樣的商業價值?為什麼要選擇我?
哪些熱愛的領域交集,能產生綜效或獨特商業價值?
還有哪些需求或商機,需要哪些領域交集才能達成?
如何養成能解決別人問題的能力,並讓人知道?
怎麼發現他人有這樣的需求與問題?
怎麼讓他們願意選擇我,接受我的幫助?
經過今天的課程分享之後學員們如何提高自己曝光的管道,可能是 blog、facebook,也要思考在曝光時自己跟別人相比,可以有哪一些不一樣的地方;在建立連結時可以從哪裡地方或角度著手;嘗試去變現

個人的職涯覆盤 (2021.2.23 更新)
Q : 我目前用來創造商業價值的主要依據為何?
實現 PM 與需求單位提出的需求
建置技術團隊
規劃與導入合適的流程與規範
優化既有產品架構與技術問題
Q : 我真正感到熱愛的技能、工作、喜好、專業是哪些?
喜歡將技術實現並解決問題的過程
將研究新技術或上課內容整理成技術文章
研究高流量與高併發架構設計
Q : 如何從我熱愛的領域變現或創造商業價值?
持續的輸出技術文章,對自己要求文章品質提高自己能力
參與外部技術社群與課程,吸收消化後帶給 Team Member
Q : 誰會需要這樣的商業價值?為什麼要選擇我?
透過文章內容與解決問題的分析過程,讓公司或同事知道自己具備解決問題的能力
想要創造願意分享氛圍的(未來)團隊
Q : 哪些熱愛的領域交集,能產生綜效或獨特商業價值?
利用自己過去的開發經驗(10y+),與擔任過不同的角色(SA + PM),當遇到問題時可以用更多角度來思考並提出解決方案
Q : 還有哪些需求或商機,需要哪些領域交集才能達成?
Cloud Service & Arch Design : 隨著雲端服務技術逐漸的成熟,雲端化在未來可能會是一個趨勢,學習或其中一個雲端解決方案的基本知識,與在雲端上設計 Application 要注意那些細節是個重要的環節
容器化 : 應用程式容器化(dockerize)
Q : 如何養成能解決別人問題的能力,並讓人知道?
要有解決問題與識別(釐清)問題的能力,才可以有效並正確的解決別人的問題。
讓人知道可以透過技術部落格的分享、IT 鐵人賽分享系列文章,或是在 fb 技術社團、技術的 LINE 群組、公司同事在每天 Daily 報告時觀察別人遇到什麼問題,這些雷是否有踩過,自己是否有能力可以協助幫忙並提供好的解決方案。
Q : 怎麼發現他人有這樣的需求與問題?
在技術論壇或是社群看有那些常見的問題,這些問題是否容易被解決
Q : 怎麼讓他們願意選擇我,接受我的幫助?
加強自己解決問題的能力、建立良好的形象與人脈的建立
曝光部分自己過去有做過一些小嘗試,將部落格中的文章與 Sample Code 系統與結構性的整理成電子書放在 Github 上,提供有需要或是剛入門的人下載與增加連結,雖然測試結果後效果普普(28 stars) 但整理的過程自己覺得挺好玩的。

推薦書籍
最後也分享一些覺得不錯的書(跟工作無關),推薦給大家
  • 做個有梗的人 : 怎麼樣做嘗試
  • 低谷 : 自由工作者 怎麼樣在市場生存下來,有幫助
  • 刻意練習 、點子都是偷來的 : 與學習比較相關
  • 動機 : 在團隊要推行一些改革,ex : 導入敏捷、單元測試,可以參考這本書
  • 學生為什麼不喜歡上學 : 裡面有些學習的理論。適合想當 training 的人參考


心得
    自己在新手村時從點部落的文章知道 91 大神,之後都陸續有在 follow 91 的文章與粉專,從文章或過去交流過程大多都是以技術的角度出發進行深入的討論,在這次主題中與過去不一樣的 91分享自己職涯中工作時遇到的挑戰,或是工作外進行了甚麼樣的嘗試與機會,以及不同階段設定的目標與其背後的目的,接著在技術領域有系統、有目的性的持續輸出,累積自己的成果與影響力並嘗試創造不同的連結,將其成果變現的過程。在兩個半小時的精彩分享中,學到很多不一樣的觀點與啟發,尤其是不為 KPI 為自己的職涯發展做事的想法,讓我有很深的感觸。
    「想成為大神,必須知道他們腦袋在想甚麼」,思考自己與業界成功人士想法上的差異,透過學習與模仿方式找到適合自己的方法,就像灌籃高手裡面的兩萬球特訓一樣(好宅),安西教練向櫻木說「你應該好好看著流川的姿勢,盡可能的模仿他,然後用3倍的訓練量練習,才有可能超越他。」,突破自己目前的天花板達到下一個境界,幫助到更多需要幫助的人。
    在最後的 Q&A 階段 91 也毫不保留的解答學員所提出的問題,擔任主持人的 Gipi 也會提出自己的觀點與看法,兩位(Gipix91)擔任多間企業的顧問都有相當豐富的實戰經驗輪流回答問題,這些可能都是在外面少有的機會(有的話也是不便宜...),自己覺得相當的值回票價 ! 也許願學院之後可以有更多機會參加類似的主題講座,可以學到(偷學)到更多不一樣的觀點與知識。

如果你對商業思維學院有興趣,可以點選 >>>> 這裡



Q&A
Q : 會建議目前只專注在.Net的開發者跨出去嗎?或者會建議持續深耕在.Net?
Q : 看 91 在 FB 上提到去客戶公司支援的故事,都可以快速的經由與員工溝通中就知道該如何執行,這是如何掌握這方面的訊息與支援要處理的問題?

2020年10月3日 星期六

[筆記] 《知行》: 技術人的管理之路

前言
這一篇是紀錄閱讀 《知行》: 技術人的管理之路 的讀書筆記,這本書是參加 TGONetwork 所舉辦的 TGONext - TGONetworks 導師計畫 成果發表會導師 Taien 所贈送的,能夠拿到導師所贈送的書自己也有點意外(當天上台分享時蠻掉漆 XD)。這半年來工作上寫 Code 的時間越來越少花很多時間都在與團隊同仁溝通,在規劃新項目或是簡報時不是那麼的流暢(得心應手)似乎總覺得少了什麼,因此決定靜下心來好好的把導師所贈送的書了解一番,才不會枉對導師對我的期待(自以為?)。這篇文章僅介紹第一章節 : 管理路口的徬徨,整理可能當開發者要轉換成技術管理職可能會遇到的一些問題,其中若是自己有理解不正確的地方是錯誤的部分歡迎各位管理大神一同討論或給予指導

工程師發展路徑
在書的一開始,作者提到過去有一群從 2005 年開始工作的工程師好友們,在某次聚會中整理這些好友目前的職務可以分為幾大類 (作者為大陸人,書中內容可能會因為場景或是地區不同有所差異)
技術類 : 架構師、技術專家
管理類 : 技術管理者、職業經理人
創業類 : 創辦人、技術合作者
顧問類 : 投資顧問、管理顧問
可能隨著能力的提升可以做的事情越來越多,提升架構能力後轉為架構師;或是專案管理及帶團隊能力越來越強,逐漸轉為技術管理者;有很好的想法想要做自己的一番事業,成為創業公司的技術合夥人;書中提到特點之一是 10 年後堅持做技術比例的只剩 20% 左右 (沒有一定,最自己而言做自己最喜歡與認同的角色即可)。不管是走上述哪一條路,有些基本能力可能會是通用的,像是規劃、帶人、管理、溝通及執行能力,也可以說是環繞著技術與管理這兩條路在走,只是不同職務所面臨與擔負的責任不同。

我到底要不要做管理
作者常常被工程師問到我適不適合做管理?您對我有甚麼建議,作者則會反問工程師幾個問題
做管理對您來說意味什麼? 您覺得它能給您帶來什麼
希望可以透過此問題來讓提問者去了解到做管理的初衷,而非直接透過回答的方式取得答案;如何審視管理對您來說是不是真愛呢,可以透過三個問題幫自己做判斷
您是否認同做管理的價值 ? 
您是否對管理充滿熱情 ? 並享受這些工作呢 
您是否看中在管理方面的成長呢 ?
管理與技術的挑戰不一樣,常常會需要接觸很多雜事像是面試、團隊溝通、規劃流程、與主管匯報、資源協調與績效評估等各式各樣的管理工作,與開發工作相較之下項目較多且較為雜亂,可能也很難從中獲得成就感與價值,如果不認為管理是有價值的可能較難持久下去,可能會有覺得寫代碼較為單純的念頭出現。但從另一個角度來思考,過去在開發可能只要做好主管交辦的項目即可,但轉做管理為了要帶領整個團隊前進,就須思考上級、同一層單位、下級各方面的期待與訴求,要求自己用更全面的角度來思考問題的解決方式,這些挑戰也會替您帶來成長,成就感與影響力。

我要不要轉回去做技術
俗語說《人窮則反本》,當人們遇到挫折就會想回到老路上。作者提到在訪談的 2/3 的新技術經理,都有類似的擔心跟問題,問題像是做了管理之後沒時間寫Code,覺得離本行越來越遠;不知道在管理與技術中如何取得平衡,兩者兼顧;管理工作瑣碎,技術越來越少接觸覺得心虛;因為技術人員常常會專心在代碼或是某些技術上,但對於職業生涯思考方向算是被動,可能不是主動的或是被動推到經理的位置上,過去沒有經驗且可能對管理沒有深入的了解,初期在不熟悉的情況下可能感到慌張或焦慮;或是覺得 技術才是自己的根本,在面對上述問題,作者提到親自寫代碼是很好的實現方式,但作為管理者必須要掌握更多的技術,快速判斷該如何搭配使用,所以必須有更高效的學習方式,建議如下
建立你的學習機制 : 思考團隊內可以建立甚麼樣的學習機制,可以借助團隊的力量提升技術判斷力,也讓團隊能力提升。
請教專家 : 借助平台找到該領域專家大神進行請教,能成為某領域高手都有深厚的知識累積,且能用簡單精準的說明讓人容易明白與了解。
共創 : 對於知識型工作者來說,和大家共創所收穫的成功,比自己埋頭思考高效許多。
如果您對技術充滿著熱情,目標是成為一位優秀的架構師的話,做管理所累積的能力是完全可以遷移到架構師上,在管理上所具備的全局視野、規劃能力、結果導向、專案規畫及溝通與協調能力,這些都是優秀的架構師必須具備的條件之一。其次,不管是做技術管理或是架構師角色,看事情的角度都必須從 High Level 的角度來思考,建議如下
從目標出發看待技術 : 目標明確,才可以選擇最佳的技術方案,做出最合理的技術決策。
從評估角度看待技術 : 必須清楚了解技術方案是透過哪一些維度來評估好壞優劣,當技術問題暴露出來時會造成甚麼影響,損失的邊界為何 ? 
從依靠自己技術到借助大家的技術 : 要熟悉團隊每位成員的技術情況,知道誰可以勝任做什麼事,適合做什麼,借助大家的技術去做事
即便做不好也不是沒有回頭路,在轉作技術管理者時離技術很近,如果嘗試下來認為管理工作確實不是自己想要的(天命),那麼回頭繼續做工程師是幾乎沒有門檻的,但前提是自己必須先全力以赴的去嘗試一段時間,盡全力的去做一件事之後才不會有遺憾,才可以知道自己到底適不適合做技術管理的工作。

如何保持技術競爭力
如何保持技術競爭力是自己最感興趣的議題,在轉型技術管理者之後,自己可以支配與寫代碼的時間會越來越少(最近感觸很深阿),書中提到當你的角色從《技術實現者》轉變為《技術管理者》時,與技術的關係就發生了變化,過去開發者對技術的追求可能是以《技術實現者》的角度出發,但現在是轉變為技術管理者的角色,對於技術能力這詞也就悄悄的開始轉變,應該以技術應用者的角度出發,技術評估能力變得為其重要,要關心與思考的是 why & what,也就是要不要做這件事以及這是件什麼事情?並在綜合評估之後做出決策與判斷。
那麼如何精進技術判斷力就會是一個重要議題,作者提到技術評估有以下三個維度

維度一 : 技術項目結果評估
在決策要不要做一個事情時,需要回答三個問題
這究竟是件什麼事情
希望得到的結果是什麼
要用什麼角度/維度衡量結果,從那些技術指標去驗收結果
有個目標與希望預期得到的結果,才可以有始有終的做出準確的判斷與正確的決策,舉例來說
  • 可能為了要提升服務穩定性,去調整服務架構
  • 可能為了提升數據的準確性,去改寫技術數據的收集流程
  • 可能為了提升系統效能指標,去調整數據庫效能讀寫模組
像是希望提升系統性能,如何衡量結果是否有提升? 要用甚麼技術指標來進行衡量? 如果結果無法衡量的話,我們如何判斷這件事是做得好或是不好,因此,技術管理對於技術項目結果的評估能力最為重要。

維度二 : 技術可行性評估
可行性有兩層涵義,分別是 能不能做值不值得
  • 能不能做 : 是指有沒有能力做到,這是能力問題
  • 值不值得 : 是指能力允許,全力投入之後的結果是否是值得的(效益),這是選擇問題
在不懂技術管理的管理者一般提問的是 能不能做,有經驗的技術管理者與資深工程師則考慮的是值不值得,另外還需要考慮成本與收益部分。 那麼通常的技術項目,都有哪些成本需要考慮的呢
投入的資源成本
技術維護的成本
- 技術選型成本
- 技術升級成本
- 問題盤查成本
- 代碼維護成本
機會成本
協作成本

維度三 : 技術風險評估
技術風險評估也叫技術風險判斷,也就是有哪些技術風險需要未雨綢繆,該技術方案帶來最大的損失的可能性是什麼,以及在甚麼情況下會發生。舉例來說,為了降低 DB Loading 可能會加上像是 Redis 的 cache 機制,在使用時可能要思考當快取發生異常時,快取 Server 重啟因為沒有對應的快取資料,這時請求全部都跑去訪問資料庫,可能會造成快取雪崩或是快取穿透的狀況發生,這時候的解決方案或是甚麼 ? 要如何防範以及團隊同仁要如何解決,這些都可能是上線後可能會遇到的問題。風險評估考驗技術管理者的技術經驗與風險意識,經驗越豐富則對風險的判斷也就越敏銳。去拓展技術視野與技術判斷力常見方式如下
建立技術學習機制
專項技術調研項目化
與技術專家交流
聽取工作匯報
另外,你不是一個人在戰鬥,因此風險評估上也需要借助團隊的技術力量做出準確判斷,並非只靠技術管理者的技術判斷力,能從周圍人群學到多少訊息與資訊,而不是在靠自學。
核心是在如何提升技術實現的能力,轉變為提升技術判斷力與技術評估能力,有些管理者擔心自己一旦不是團隊技術能力最強的人,會因此有團隊成員不服氣,但從另外一個角度來看,管理者的職責是帶領團隊高效的交付高質量的產品與系統上,隨著年紀的增長,團隊中比你優秀的人才會越來越多,是一種好的現象,如果多年之後你依然是團隊裡技術最強的一員,可能不是一個好的現象。

...To Be Contined

心得
這篇文章僅介紹第一章節 : 管理路口的徬徨的部分,擔任開發人員也有10年的時間,其實在最近幾份工作主管都有建議可以嘗試往技術管理的路前進,但由於自己認為技術能力還尚未到一定的水準所以都不小心選擇逃避帶過,趁這個中秋連假期把該有的基本知識給惡補一下,光閱讀第一個章節就感觸蠻深的,提到過去自己很多深藏在心中已久的問題,其中也提到在不懂的知識下要找專業人員求助,這也讓我想到與前主管常提到的人脈的重要性,平常就需要累積人脈與研討會會認識一些技術愛好者,當你工作遇到問題時就會透過這種方式向大神們請教相關問題,當然態度方面是很重要的(別人也不是一定要回答你,回答問題也是需要時間成本),因此這點也是需要格外注意,雖然書還沒完全看完但已經有不少幫助,希望日後還有時間可以繼續下去。

參考
《知行》: 技術人的管理之路

2020年9月9日 星期三

[Architecture] The 12 factor App 筆記

前言
最近在與同事一起規劃新系統的架構,在整理相關文件時想起參加前公司 Techday 由新加坡同事提起的 The Twelve-Factor App 方法論,提出此方法論的作者參與了超過一百個專案開發與部署,並透過 Heroku 平台見證了數十萬個應用程式的開發運作以及擴展的過程,整理了在 SaaS (Software as a Service) 開發時需要理想的實踐標準,方法論主要內容如下

Use declarative formats for setup automation, to minimize time and cost for new developers joining the project;
Have a clean contract with the underlying operating system, offering maximum portability between execution environments;
Are suitable for deployment on modern cloud platforms, obviating the need for servers and systems administration;
Minimize divergence between development and production, enabling continuous deployment for maximum agility;
And can scale up without significant changes to tooling, architecture, or development practices.
其中提到此方法論是不限定語言與後端服務開發的應用程式,因此這篇文章就來介紹關於 12 個方法論的一些重點項目,若有理解錯誤或是異常的地方歡迎隨時提出討論。

介紹
【文不如圖,圖不如表】再多的文字都比不上一張清晰的圖讓人容易了解,因此在一開始先 PO 出在網路上找到有關 12 factors 的小抄表,讓有興趣的朋友對於整個方法論有更清楚的 overview
接著,再來逐一介紹每個方法論的內容 備註 : Puppeteer 是 Playwright 的前身,其 API 與核心概念都很相似。

Codebase
一份基准代码(Codebase),多份部署(Deploy)
  • 使用版本控制系統來控管代碼,像是 Git、Subversion 等常見的版本控管工具
  • 一份用來追蹤代碼所有異動版本的數據庫被稱為 代碼庫 (code repository, code repo, repo)
  • 基準代碼指的就是這一份代碼庫,如果是 Git 分布式版本控制系統,基準代碼就是最上游的代碼庫。
  • 基準代碼與應用(Aplication) 是保持一對一的關係。
  • 在不同的環境會對應到同一份代碼庫,每個部署可能會使用到不同的版本

Dependencies
清楚的定義依賴關係(Dependency)
  • 應用程序不會隱式依賴系統級的類別庫,透過依賴清單清楚定義所有依賴項目
  • 透過依賴隔離工具來確保不會調用不存在的項目,此做法在 Production 與測試環境皆是如此
  • 為新的開發者簡化環境配置的流程,只需要透過建構指令 (build command) 即可安裝其依賴項目,即可開始工作
  • 舉例來說,在 Ruby/Bundler 就是透過 bundle install

Config
將 Config 定義在環境變數中
  • 代碼(Code)與配置(Config)嚴格分離
  • Config 在不同環境分別各自定義,代碼是一致的
  • 推薦將應用程式的配置定義在環境變數中 (Env vars, env)
  • 環境變數可以很方便的在不同環境修改,不用異動到代碼 (Code)與語言也無關
  • 舉例來說,與第三方介接時所需要的 Token,在與 DB 建立連線時需要的連線字串 Connection string

Backing Service
將後端服務(Backing Service)視為附加資源

  • 應用程式(Application)不會區別本地或是第三方服務
  • 對它來說兩者都是附加的資源,透過某個 url 或配置的服務定位 (locator/credentials) 來取得數據
  • 也可以在不用異動代碼的情況下,將本地 MySql 資料庫換成第三方服務(ex:Amaxon RDS)
  • 每個不同的後端服務都是一份資源(resource),這些資源與其附屬的部署保持鬆耦合(loose coupling)的關係

Build, release, run
嚴格分離建構與運行

  • 嚴格區分構建,發布,運行這三個步驟
  • 直接修改運行中的代碼是非常不可取的行為
  • 每次發布都要對應到唯一個發布ID,例如可以使用發布時的時間戳記 2020-09-10 22:33:44
  • 發布的版本一但發布就不能修改,任何代碼的變動都應該產新的版本
  • 備註 : 小弟公司是使用 Git commit 的 hash 值,方便盤查

Processes
使用一個或多個無狀態的 Process 運行
  • Application 的 Process 應該是無狀態且不能共享的(share-nothing),
  • 任何像是需要持久化的數據都要存在後端服務中,像是數據庫
  • 一些互聯網系統過度依賴於 session (sticky sessions),這在 12-Factor 是極力反對的,
  • Session 數據應該保持在像是 Memcached 或是 Redis 有帶過期時間的緩存中

Port binding
通過端口綁定( Port binding )來提供服務
  • 通過端口綁定(Port binding)來提供服務,並監聽發送至該 Port 的請求
  • 不僅限於 HTTP 服務

Concurrency
使用 Process Model 進行 Scale Out

  • Processes are a first class citizen
  • 開發人員可以運用 Unix process model for running servuce daemons,將不同的工作分配給不同的類型 (Process Type)
  • 舉例來說,HTTP 請求可以交給 Web 進城來處理;常駐的後台則交由 worker 來負責
  • Process 應該 stateless 和無分享的,方便進行擴充

Disposability
通過快速啟動和優雅關機,實現穩健性最大化
  • Processes 是可以瞬間開啟或是停止,易處理的 (disposable)
  • 追求最小啟動時間,理想狀態當輸入啟動指令到等待請求應該只需要很短的時間
  • 更快的啟動時間提供敏捷的發布與擴展,容易將 Process 容易的搬移到新的物理機器上
  • 收到終止信號(SIGTERM)就會優雅的終止,也就是停止監聽服務的 Port 拒絕所有的請求然後退出

Dev/prod parity
盡可能保持開發/測試/正式環境相同
  • 想做到持續部署應該縮小本地與線上的差異
  • 縮小時間差異:開發人員可以幾小時,甚至幾分鐘就部署代碼。
  • 縮小人員差異:開發人員不只要編寫代碼,更應該密切參與部署過程以及代碼在線上的表現。
  • 縮小工具差異:盡量保證開發環境以及線上環境的一致性。
  • 開發人員應該反對在不同環境使用不同的後端服務,降低使用上的差異以及突然出現的不相容問題

Logs
把日志當作事件流
  • 應用程式不應該煩惱 logs 存放位置,統一使用 stdout 直接輸出
  • 這些事件流可以輸出至文件,或是在終端實現觀察的
  • 輸出流可以發送到 Splunk 諸如此類的日誌索引及分析系統

Admin processes
後台管理任務當作一次性運行
  • 開發人員有可能會執行一次性的管理或是維護的一次性任務
  • 執行資料轉換
  • 執行控制台(REPL Shell)
  • 一次性管理程序應該使用相同的環境,並使用相同的程式碼跟配置


感想
以上針對 The 12 Factor 做了基本簡單的介紹,但在實務上某些部份可能實現的難度較高,舉例來說像是 Dev/Prod 環境要一致的要求,現實上可能會遇的問題是開發環境的 Server 已經包含 feature A,但在未驗證完全的情況下可能會也不會更新到正式環境;每一個原則都是開發與運維同仁在開發時需要注意的部分,日後有機會設計新架構或是既有系統調整時可以做為參考的準則之一,以上如果有不清楚的地方歡迎一起討論,謝謝 !

參考
12 factor

2020年8月12日 星期三

[NETCore] 使用 BenchmarkDotNet 測試程式碼效能

前言
在開發或是 POC 時為了記錄代碼程式執行的時間,都會採用在代碼上加上  stopWatch  紀錄花費時間,使用方式不外乎就是 new Stopwatch、Start、Stop、Reset、ElapsedMilliseconds,以詳細記錄代碼所花費的時間,接下來為了要顯示在 console 上可能還要針對 log 在輸出內容做簡單排版方便記錄,最近發現上述惱人的事情都可以使用  BenchmarkDotNet  套件來幫你完成,不僅可以完成上述提到的事情,還會自動將結果輸出成 report html 檔案,並會記錄執行時的 Runtime 版本與硬體資訊,這篇就針對 benchmarkDotNet 做簡單的介紹與說明若有問題或是有更推薦的工具歡迎提出一起討論或是給予指導。

BenchmarkDotNet 安裝
套件支援下列項目
  • Runtimes: Full .NET Framework (4.6+), .NET Core (2.0+), Mono, CoreRT
  • OS: Windows, Linux, MacOS
  • Languages: C#, F#, VB
Manage Nuget Package 安裝
Step 1 : 在 Visual Studio IDE 按下快捷鍵  Ctrl + Q ,滑鼠指標會移到右上角搜尋框輸入 nuget 按下 enter
Step 2 : 在搜尋框輸入 benchmarkDotNet,點擊 Install
由於此套件要下載的 dll 很多因此等待時間會比較長,接著就是無止境的下一步

Package Manager Console 安裝
不愛 GUI 介面的人可以選擇輸入以下指令進行安裝 
Install-Package BenchmarkDotNet -Version 0.11.4

使用方式
接著參考官網的範例(沒梗)比較 C# 裡 MD5 和 SHA256 兩個方法在新增特定筆數時,哪一個會花費比較少的時間完成(效能)會比較好,也順便練習在 Benchmarkdotnet 套件是如何實作及 Report 內容是如何呈現,新增一個 Console 專案為 BenchmarkDotnet,並在專案中加入下列代碼
using System;
using System.Security.Cryptography;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

namespace benchmarkLab
{
    class Program
    {
        static void Main(string[] args)
        {
            var summary = BenchmarkRunner.Run<Md5VsSha256>();
            Console.ReadKey();
        }
    }

    public class Md5VsSha256
    {
        private const int N = 10000;
        private readonly byte[] data;

        private readonly SHA256 sha256 = SHA256.Create();
        private readonly MD5 md5 = MD5.Create();

        public Md5VsSha256()
        {
            data = new byte[N];
            new Random(42).NextBytes(data);
        }

        [Benchmark]
        public byte[] Sha256() => sha256.ComputeHash(data);

        [Benchmark]
        public byte[] Md5() => md5.ComputeHash(data);
    }
}

程式說明
  • Md5VsSha256 類別 : 產生 Md5 與 sha256 方法上加上  Benchmark  attribute
  • Main 類別 : 使用  BenchmarkRunner.Ren<T>  T是你要驗證的 classname
  • 下一步將執行方式改為  Release  ,如果你的Visual Studio 有開啟 Just my code 也會提示你關閉此功能
    按下 Ctrl + F5 執行專案,接著可以觀察到 Benchmark 開始針對 release 資料夾底下 projectName.exe 檔案執行測試,並列出測試環境的 runtime 與 framework 資訊
    測試跑完之後我們直接看結果 
    // * Summary *
    
    BenchmarkDotNet=v0.11.4, OS=Windows 10.0.17763.379 (1809/October2018Update/Redstone5)
    Intel Core i7-8550U CPU 1.80GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
      [Host]     : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3324.0
      DefaultJob : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3324.0
    
    
    | Method |      Mean |     Error |    StdDev |
    |------- |----------:|----------:|----------:|
    | Sha256 | 151.71 us | 1.2058 us | 0.9414 us |
    |    Md5 |  30.46 us | 0.6038 us | 0.5930 us |
    
    // * Hints *
    Outliers
      Md5VsSha256.Sha256: Default -> 3 outliers were removed
      Md5VsSha256.Md5: Default    -> 2 outliers were removed, 3 outliers were detected
    
    // * Legends *
      Mean   : Arithmetic mean of all measurements
      Error  : Half of 99.9% confidence interval
      StdDev : Standard deviation of all measurements
      1 us   : 1 Microsecond (0.000001 sec)
    
    // ***** BenchmarkRunner: End *****
    // ** Remained 0 benchmark(s) to run **
    Run time: 00:00:39 (39.09 sec), executed benchmarks: 2
    
    Global total time: 00:00:45 (45.68 sec), executed benchmarks: 2
    // * Artifacts cleanup *
    從報告中可以看出來,執行時間 sha256 為 151.71 us 與 md5 的 30.46 us 較久,1 us : 1 Microsecond (0.000001 sec),因此可以判定在 .Net Framework 環境下 md5 比 sha256 來的快 

    Report
    前面有提到案下執行後,會針對專案 release 資料夾底下 backmarklab.exe 檔案執行測試,測試完畢後除了會 console 出測試結果之外,如果注意 console 內容來可以發現內容有提到結果輸出成 report,輸出路徑在  release\BenchmarkDotNet.Artifacts\results  目錄底下,如下圖所示
    // * Export *
    BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report.csv
    BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report-github.md
    BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report.html
    Repost 提供三種呈現方式,分別是 : csv、html 與 html,都記錄測試時間結果還有環境變數資訊
    HTML 呈現方式
    MD 呈現方式

    設定環境變數 - Job

    剛剛的測試數據證明了在 .NET Framework 下是 Md5 比 sha256 快,但如果今天程式是執行在 .NET Core 環境下是否還是一樣呢 ? 在一開始有提到,benchmarkdotnet 支援 .Net Framework 與 .NET Core 以及 mono,可以執行一次同時確認多個環境變數,舉例來說想同時驗證 .NET Framework、.NET Core 環境,只需要在 attribute 上加上  [clrJob]  與  coreJob  ,如下範例
    [ClrJob, CoreJob]
    public class Md5VsSha256
    可以看到輸出結果多了 clr 部分,但是其結果卻是 NA,這時需要開啟專案 csproj 檔案,調整下列內容
    詳細可以參考官網常見問題 : 傳送門
    <TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
    <PlatformTarget>AnyCPU</PlatformTarget>
    
    重新執行一次,可以發現 .NET Framework 與 .NET Core 數據有正常呈現
    加入了在 .NET Core 環境測試,從結果來看 md5 速度上還是優於 sha256,另外在測試時建議將測試環境不要用到的程式關閉,避免影響到測試時的效能,才可以更呈現結果更為準確。

    GitHub Sample Code 傳送門 :  BenchmarkDotNet Lab

    感想
    透過以上簡單的應用可以看出來 Banchmarkdotnet 不僅可以協助測試,還可以將測試數據輸出成報表呈現,只需要在測試的類別上加上 [Benchmark] 即可,並在測試時考慮到 cold start & warm state、手動調整執行次數與執行時 GC 資訊,相關文件與更多的功能都可以在官網看到,想了解更多的朋友去 benchmarkdotnet.org 尋寶吧 ! 
      參考
      benchmarkdotnet
      使用 BenchmarkDotnet 测试代码性能

      Copyright © m@rcus 學習筆記 | Powered by Blogger

      Design by Anders Noren | Blogger Theme by NewBloggerThemes.com