<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Potioneer&#39;s Essays</title>
    <link>//william-yeh.net/</link>
    <description>Recent content on Potioneer&#39;s Essays</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-TW</language>
    <lastBuildDate>Thu, 30 Apr 2026 20:00:00 +0800</lastBuildDate>
    
        <atom:link href="//william-yeh.net/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Prompt 寫了卻還是不穩：用三組實驗看完成判定該放在哪裡</title>
      <link>//william-yeh.net/post/2026/04/genai-multi-steps-experiment/</link>
      <pubDate>Thu, 30 Apr 2026 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2026/04/genai-multi-steps-experiment/</guid>
      
        <description>&lt;p&gt;上一篇文章〈&lt;a href=&#34;//william-yeh.net/post/2026/04/genai-multi-steps/&#34;&gt;Prompt 已經寫很細了，Workflow 為什麼還是不穩？&lt;/a&gt;〉談到，多步驟 agent workflow 常見的三種失靈：過早開始、假性完成、未驗證即結案。這三種現象，最後都會回到同一個控制問題：&lt;strong&gt;「完成」到底由誰判定。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;當 workflow 的成敗開始取決於真實狀態、工具結果或驗證條件時，只把完成條件寫在 prompt 裡，通常是不夠的，得交給 prompt 以外的機制。&lt;/p&gt;
&lt;p&gt;口說無憑。這篇文章想用一組小實驗看一件事：&lt;strong&gt;同一個任務、同一份 prompt，如果把「完成判定」放在不同位置，false completion 會怎麼變化？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我選了一個很小、但實務上很常遇到的任務：整理技術文章的註腳。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/04/genai-multi-steps-experiment.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/04/genai-multi-steps-experiment.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;實驗任務&#34;&gt;實驗任務&lt;/h2&gt;
&lt;h3 id=&#34;註腳重排要怎麼算完成&#34;&gt;註腳重排要怎麼算完成&lt;/h3&gt;
&lt;p&gt;我在寫技術文章時，常會用註腳標出參考文獻。不過在定稿前，正文和參考文獻常常會反覆調整；一來一回之後，正文引用順序和文末定義順序很容易亂掉，也常會出現缺漏或重複。手動修不難，但很煩。&lt;/p&gt;
&lt;p&gt;例如下面這篇短文：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;這是第一段。[^3]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;這是第二段。[^1]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;這是第三段。[^4]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[^1]: 第一個註腳。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[^2]: 這個註腳沒有被引用。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[^3]: 第三個註腳。&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;這裡至少有三個錯誤：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正文引用順序錯亂：數字大的 &lt;code&gt;[^3]&lt;/code&gt; 不該出現在 &lt;code&gt;[^1]&lt;/code&gt; 前面。&lt;/li&gt;
&lt;li&gt;有引用但沒有定義：正文標了 &lt;code&gt;[^4]&lt;/code&gt;，文末沒有對應的 &lt;code&gt;[^4]:&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;有定義但沒有引用：文末有 &lt;code&gt;[^2]:&lt;/code&gt;，正文沒有用到 &lt;code&gt;[^2]&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整理後應該變成這樣：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;這是第一段。[^1]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;這是第二段。[^2]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;這是第三段。[^3]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[^1]: 第三個註腳。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[^2]: 第一個註腳。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[^3]: 這個註腳有引用但沒有定義。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;!-- 已移除未引用的註腳：
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;-&lt;/span&gt; 這個註腳沒有被引用。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;「把文件改到好」，實際上要處理很多細節；但「有沒有改好」相對起來比較好判斷。&lt;/p&gt;
&lt;p&gt;只要寫一個 checker 小工具，檢查有引用但沒有定義、有定義但沒有引用、重複定義、引用順序與定義順序，最後回傳：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;pass&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;或：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-jsonc&#34; data-lang=&#34;jsonc&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;pass&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;missing_definitions&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;4&amp;#34;&lt;/span&gt;],     &lt;span style=&#34;color:#75715e&#34;&gt;// 有引用但沒有定義
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;unused_definitions&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2&amp;#34;&lt;/span&gt;],      &lt;span style=&#34;color:#75715e&#34;&gt;// 有定義但沒有引用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;&amp;#34;reference_order_errors&amp;#34;&lt;/span&gt;: [&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;...&lt;/span&gt;]   &lt;span style=&#34;color:#75715e&#34;&gt;// 引用或定義順序錯誤
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;這個 checker 不需要很複雜（甚至可能只到 LeetCode 的 easy 程度）。有了它，Markdown 到底有沒有修好，就不必靠模型自己說了算。它就是這次實驗的外部判定者。&lt;/p&gt;
&lt;h3 id=&#34;測試資料&#34;&gt;測試資料&lt;/h3&gt;
&lt;p&gt;實驗還需要一組合適的測試資料。&lt;/p&gt;
&lt;p&gt;我準備了 10 份測資，刻意涵蓋幾種常見錯誤：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;#&lt;/th&gt;
          &lt;th&gt;缺陷&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_01&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;引用順序錯亂、有引用無定義、有定義無引用&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_02&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;重複定義&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_03&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;定義區順序錯亂&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_04&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;多個缺漏定義&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_05&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;多餘的未使用定義&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_06&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;非連續編號&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_07&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;同一 footnote 多次引用（已合法，無須修改）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_08&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;正文無 ref，殘留 def&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_09&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;含 URL 的 def，引用順序錯亂&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;case_10&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;混合缺陷（亂序、重複、缺漏、未使用）&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;修改前與修改後的對照表，可見&lt;a href=&#34;https://github.com/William-Yeh/multi-step-completion-experiment&#34;&gt;實驗 repo&lt;/a&gt; 的 &lt;a href=&#34;https://github.com/William-Yeh/multi-step-completion-experiment/blob/main/docs/cases.md&#34;&gt;docs/cases.md&lt;/a&gt; 文件。&lt;/p&gt;
&lt;p&gt;其中三個 case 特別值得一提。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;case_07&lt;/code&gt; 是對照組。&lt;/strong&gt; 它原本就是合法的，正確回應是不改。模型如果為了交差多動一刀，checker 會抓到。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;case_10&lt;/code&gt; 是混合題。&lt;/strong&gt; 亂序、重複、缺漏、未使用四種缺陷同時存在，模型得把整套修正策略都做對才會過關。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;case_06&lt;/code&gt; 最能看出問題。&lt;/strong&gt; 技術上來說 Markdown 不要求註腳一定連續編號，甚至不用數字也可以，所以 &lt;code&gt;[^1]&lt;/code&gt; 後面接 &lt;code&gt;[^3]&lt;/code&gt; 不必然算錯；但這次實驗的 checker 規則更嚴，要求重新排成連續編號，因為這才比較符合一般讀者的直覺。&lt;/p&gt;
&lt;h2 id=&#34;實驗設計&#34;&gt;實驗設計&lt;/h2&gt;
&lt;p&gt;這三組實驗的主體 prompt 完全相同，只改一件事：completion gate 放在哪裡。&lt;/p&gt;
&lt;h3 id=&#34;控制變因&#34;&gt;控制變因&lt;/h3&gt;
&lt;p&gt;要把文件改到好，不只是改一輪編號，而是一組相互依賴的步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;重新整理正文裡的註腳引用。&lt;/li&gt;
&lt;li&gt;確認每個引用都有對應的定義。&lt;/li&gt;
&lt;li&gt;移除沒有被引用的註腳定義。&lt;/li&gt;
&lt;li&gt;避免重複定義。&lt;/li&gt;
&lt;li&gt;讓正文引用順序與定義順序一致。&lt;/li&gt;
&lt;li&gt;最後確認通過檢查，才算完成。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這些步驟在三組實驗裡都相同。&lt;/p&gt;
&lt;h3 id=&#34;操縱變因completion-gate-放在哪裡&#34;&gt;操縱變因：completion gate 放在哪裡&lt;/h3&gt;
&lt;p&gt;這次要測的是：當完成條件已經寫成外部 checker 的規則時，模型會不會真的照那個規則走，還是最後仍然用自己的語言判讀來放行。&lt;/p&gt;
&lt;p&gt;三組實驗如下：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;實驗&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;呼叫 tool？&lt;/th&gt;
          &lt;th style=&#34;text-align: center&#34;&gt;read back？&lt;/th&gt;
          &lt;th&gt;完成判定放在哪裡？&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;實驗一：&lt;!-- raw HTML omitted --&gt;&lt;code&gt;prompt_only&lt;/code&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;否&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;否&lt;/td&gt;
          &lt;td&gt;模型自我宣告&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;實驗二：&lt;!-- raw HTML omitted --&gt;&lt;code&gt;tool_no_readback&lt;/code&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;是&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;否&lt;/td&gt;
          &lt;td&gt;模型知道工具被呼叫，但不知道結果&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;實驗三：&lt;!-- raw HTML omitted --&gt;&lt;code&gt;tool_with_readback&lt;/code&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;是&lt;/td&gt;
          &lt;td style=&#34;text-align: center&#34;&gt;是&lt;/td&gt;
          &lt;td&gt;checker result + gate&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;實驗一最單純：只給模型 prompt，不准呼叫 checker。模型只能自己檢查自己。&lt;/p&gt;
&lt;p&gt;實驗二刻意只做半套：模型必須呼叫 checker，但 checker 只回傳 &lt;code&gt;accepted/run_id&lt;/code&gt;，不回傳真正的 pass/fail。這組對照，是想測試一個常見的假說：把任務拆成幾個 phase，要求模型每做完一段就輸出一個 marker、summary 或 artifact，流程是不是就比較不容易亂掉。&lt;/p&gt;
&lt;p&gt;這種做法在互動式使用裡確實有幫助，因為中間輸出讓人看得見流程，也比較容易人工介入。但在這個實驗裡，重點不只是「有沒有留下東西」，而是那個東西有沒有真的被拿來判斷完成與否。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tool_no_readback&lt;/code&gt; 測的就是這個差別。它有呼叫外部工具，也有拿到一些無關痛癢的周邊資訊；但真正關鍵的 pass/fail 沒有回到流程裡。最後仍然是由模型自己決定能不能宣告 completed。&lt;/p&gt;
&lt;p&gt;實驗三才是真的把 completion gate 移出去：模型必須呼叫 checker、讀回完整結果，再依照 pass/fail 決定能不能宣告 completed。&lt;code&gt;pass=false&lt;/code&gt; 就得修正後重跑，&lt;code&gt;pass=true&lt;/code&gt; 才能放行。&lt;/p&gt;
&lt;p&gt;同一個任務裡，差別就在這裡：完成判定有沒有真的離開語言層。&lt;/p&gt;
&lt;h2 id=&#34;實驗結果&#34;&gt;實驗結果&lt;/h2&gt;
&lt;p&gt;實驗使用本機已登入的 Claude Code CLI 與 Codex CLI 執行。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;3 個 experiments * 10 個 cases，每個 case 都在獨立 workspace 中執行，最後由評分器 (grader) 呼叫 checker 判定結果。&lt;/p&gt;
&lt;p&gt;以下是兩家旗艦款模型的結果。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/04/genai-multi-steps-demo.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/04/genai-multi-steps-demo.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h3 id=&#34;claude-code-cli-的實驗結果&#34;&gt;Claude Code CLI 的實驗結果&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Experiment&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;Actual Pass&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;False Completion&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;Tool Called&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;Readback Used&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;prompt_only&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;6&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;tool_no_readback&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;10&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;tool_with_readback&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;10&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;10&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;prompt_only&lt;/code&gt; 出現 40% false completion。10 個 case 裡有 4 個是 AI 宣稱 completed，但最終 checker 判失敗；失敗的是 &lt;code&gt;case_05&lt;/code&gt;、&lt;code&gt;case_06&lt;/code&gt;、&lt;code&gt;case_08&lt;/code&gt;、&lt;code&gt;case_10&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;到了 &lt;code&gt;tool_no_readback&lt;/code&gt;，Claude 又多失敗一個 &lt;code&gt;case_01&lt;/code&gt;，false completion 升到 50%。模型確實有呼叫 checker，但沒有讀回真正的檢查結果；這次呼叫不只沒幫上忙，還讓 &lt;code&gt;case_01&lt;/code&gt; 偏移成 false completion。&lt;/p&gt;
&lt;p&gt;到了 &lt;code&gt;tool_with_readback&lt;/code&gt;，Claude 100% 通過，false completion 降到 0。就這組任務來看，只讓模型「有呼叫工具」不夠；checker 結果真的成為 gate，才有差別。&lt;/p&gt;
&lt;h3 id=&#34;codex-cli-的實驗結果&#34;&gt;Codex CLI 的實驗結果&lt;/h3&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Experiment&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;Actual Pass&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;False Completion&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;Tool Called&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;Readback Used&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;prompt_only&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;tool_no_readback&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;10&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;tool_with_readback&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;0&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;10&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;10&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Codex 在 &lt;code&gt;prompt_only&lt;/code&gt; 跑出 7 / 3（actual pass / false completion）的結果；失敗的 3 個 case 是 &lt;code&gt;case_05&lt;/code&gt;、&lt;code&gt;case_08&lt;/code&gt;、&lt;code&gt;case_10&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;到了 &lt;code&gt;tool_no_readback&lt;/code&gt;，Codex 仍然是 7 / 3，但失敗的 case 換了：&lt;code&gt;case_10&lt;/code&gt; 這次過了，改成 &lt;code&gt;case_06&lt;/code&gt; 失敗。也就是說，call tool 這個動作對行為有些微影響，但沒有提升完成判定的可信度。&lt;/p&gt;
&lt;p&gt;跟 Claude 對照也看得到類似現象：Claude 在 &lt;code&gt;prompt_only&lt;/code&gt; 失敗 4 個 case，到 &lt;code&gt;tool_no_readback&lt;/code&gt; 又多失敗一個 &lt;code&gt;case_01&lt;/code&gt;。兩個 agent 的偏移方向不一樣，但有一點相同：沒有 readback 時，false completion 都還在；接上 readback gate 後，兩邊都變成 10/10。&lt;/p&gt;
&lt;p&gt;這不是在評比語言模型，也不是說所有 agent 都會跑出完全一樣的數字。但至少在這組任務上，有個很明顯的趨勢：只要「完成」的判定還留在模型自述裡，就容易遇到假性完成；一旦移交給外部 checker，結果就明顯收斂。&lt;/p&gt;
&lt;h3 id=&#34;case_06模型把局部合理的解釋當成完成&#34;&gt;&lt;code&gt;case_06&lt;/code&gt;：模型把局部合理的解釋當成完成&lt;/h3&gt;
&lt;p&gt;我用 &lt;code&gt;case_06&lt;/code&gt; 來說明 &lt;code&gt;prompt_only&lt;/code&gt; 的盲區：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;第一段。[^1]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;第二段。[^3]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[^1]: 第一個註腳。
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[^3]: 第三個註腳。&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;從 Markdown 規格的角度看，這份文件的 ref 和 def 是完整配對的：兩個 ref 都有對應 def、沒有 unused def，也沒有重複定義；只是編號不連續，跳過了 &lt;code&gt;[^2]&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Claude 在 &lt;code&gt;prompt_only&lt;/code&gt; 模式下讀完後，在 notes 裡留下這樣的判斷：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Input has no defects in any of the five recognised categories (&lt;code&gt;missing_definitions&lt;/code&gt;, &lt;code&gt;unused_definitions&lt;/code&gt;, &lt;code&gt;duplicate_definitions&lt;/code&gt;, &lt;code&gt;reference_order_errors&lt;/code&gt;, &lt;code&gt;definition_order_errors&lt;/code&gt;). The label gap between 1 and 3 is not itself a defect — &lt;strong&gt;footnote labels are identifiers, not sequence positions&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以它保留原文，直接宣告 completed。&lt;/p&gt;
&lt;p&gt;這個判讀其實是有道理的。就 Markdown 規格來說，footnote label 確實比較像 identifier，不一定代表順序位置。問題在於：這次實驗的 checker 規則更嚴，要求註腳重新排成連續編號。&lt;/p&gt;
&lt;p&gt;同樣的 &lt;code&gt;case_06&lt;/code&gt;，但 Codex 在 &lt;code&gt;prompt_only&lt;/code&gt; 模式下反而會把 &lt;code&gt;[^1]/[^3]&lt;/code&gt; 改成 &lt;code&gt;[^1]/[^2]&lt;/code&gt;，順利過關。也就是說，同一個任務、同一份 prompt，兩個 agent 在邊界條件上做出了不同解釋。&lt;/p&gt;
&lt;p&gt;這正是 &lt;code&gt;prompt_only&lt;/code&gt; 脆弱的地方。當「到底要不要修」本身就是一個判斷題，而判斷依據又散在 prompt 各處時，模型很容易找到一條對自己比較寬鬆的解釋路徑，然後把那個局部合理的解釋，當成整個 workflow 裡的完成判定。&lt;/p&gt;
&lt;p&gt;至於 &lt;code&gt;tool_with_readback&lt;/code&gt; 這做法，其實沒有讓模型突然更懂 Markdown；它只是把放行權從語言模型身上移走。若 checker 說 &lt;code&gt;pass=false&lt;/code&gt;，流程就不能結案；得一直修到 &lt;code&gt;pass=true&lt;/code&gt; 為止。&lt;/p&gt;
&lt;h2 id=&#34;邊界條件本機小模型-qwen3-系列&#34;&gt;邊界條件：本機小模型 (Qwen3 系列)&lt;/h2&gt;
&lt;p&gt;我再用兩個 Qwen3 系列模型重做這組實驗：Qwen3:8b (general dense)，以及 2026/02 發布的下一代 Qwen3.5-9B (hybrid 架構)，把 Claude Code CLI 直接接到本機 Ollama。&lt;/p&gt;
&lt;p&gt;兩個模型的工具呼叫能力都沒問題。但放進 Claude Code 整套 harness 去跑實驗，結果兩個模型都沒有任何一次真實的呼叫工具，失敗方式也完全不同。&lt;/p&gt;
&lt;p&gt;在 Qwen3:8b 的實驗裡，每一個 case 都是 agent failure。不只是「沒寫檔」，也根本沒有真的呼叫任何工具。模型自己把整套 readback 流程都在想像中「演」完了，它甚至從 prompt 路徑裡抓到 workspace 名稱的字串，順手填進 &lt;code&gt;run_id&lt;/code&gt; 欄位。夠聰明吧！&lt;/p&gt;
&lt;p&gt;8B 失敗的原因是「決策被淹沒」。當 prompt 長到一個程度、工具選項多到一個程度，模型會跳過 tool-use 那個分支，直接退化成「產出一段&lt;strong&gt;看起來像答案&lt;/strong&gt;的文字」就交差。能力沒消失，只是被擠出有效 attention 的範圍。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 從假性完成的角度看，這個結果其實比 Claude/Codex 的 30–50% 還糟：表面看像 100% 通過 (vacuous pass)，實際上 100% 沒做事。&lt;/p&gt;
&lt;p&gt;至於 Qwen3.5-9B，inference 真的有在跑，只是 token 產出速率崩潰到實務上完全不可用——Claude Code 這樣的 harness，對它來說太重了。本來是「能呼叫工具」，最後變成「來不及呼叫工具」。&lt;/p&gt;
&lt;p&gt;兩個模型都顯示：能力（模型支援 tool call）和行為（模型在這個 harness 下實際發 tool call）是兩件事——一邊是「決策被淹沒」、另一邊是「throughput 崩潰」，結果都沒觸發 completion gate。&lt;/p&gt;
&lt;p&gt;因此，gate 是必要條件，但若要真的有效，還得確保&lt;strong&gt;模型在當時的負荷之下，還會（並且來得及）去碰它&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;結語&#34;&gt;結語&lt;/h2&gt;
&lt;p&gt;這組實驗主要在表明：在同一個任務、同一份 prompt 下，改 completion gate 的位置，假性完成的發生率就會跟著變動。&lt;/p&gt;
&lt;p&gt;以這次的註腳重排任務來說，當 workflow 的成敗開始取決於真實狀態、工具結果、驗證通過或錯誤恢復時，如果 completion gate 只停留在語言層，假性完成率高達 30–50%；當 completion gate 真正搬到外面的 checker，假性完成率則降到 0%。&lt;/p&gt;
&lt;p&gt;這篇測的是一個有明確 checker、錯誤類型清楚、完成條件可外部檢查的任務，不是嚴格的 model benchmark。但結果已經夠直接了：&lt;strong&gt;Prompt engineering 可以改善表達與引導，但不會自動把控制責任做到位。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;流程設計上，除了要把控制責任移出去，還得確認那個閘門在實際負荷下真的有人敲——&lt;strong&gt;沒人敲的閘門，跟沒有閘門差不多&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;這就是 Claude 和 Codex 對這些失敗 case 給的提醒。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;這裡選擇 Claude Code CLI 與 Codex CLI，而不是直接呼叫 LLM API，主要是因為本文要觀察的是比較接近實務使用的 agent workflow：它們會讀檔、寫檔、跑命令，也比較容易暴露「完成判定放在哪裡」這類控制問題。因此，這次只比較 agent CLI 在多步驟任務中的 workflow 行為。缺點是結果會受模型版本、權限設定與工作目錄狀態影響，所以比較適合把它當成 workflow control demo 來看。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;順帶一提，在 Qwen3.5 出現之前，Ollama 建議跟 Claude Code 搭配的 Qwen3 模型，並不是 &lt;code&gt;Qwen3:8b&lt;/code&gt;，而是 &lt;code&gt;qwen3-coder&lt;/code&gt;（30B-A3B MoE，agentic 後訓練變體）。Alibaba 並沒有提供小 dense 的 coder 版本——這個產品決策本身就間接承認：要在 agentic harness 裡可靠觸發 tool-use，光只有「模型支援 function calling」還不夠，還要相應的後訓練配上夠大的決策容量。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Prompt 已經寫很細了，Workflow 為什麼還是不穩？</title>
      <link>//william-yeh.net/post/2026/04/genai-multi-steps/</link>
      <pubDate>Sun, 19 Apr 2026 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2026/04/genai-multi-steps/</guid>
      
        <description>&lt;p&gt;在使用 ChatGPT MyGPT 這類工具時，常會碰到這種情況：明明已經把步驟一、二、三寫得很清楚，甚至快寫到八千字長度上限，它還是不一定照順序做，也不一定會把前一步做完才往下走。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 結果，流程不會自己穩定推進，而是使用者得一路追著它跑，不斷補盯、補問、補救。&lt;/p&gt;
&lt;p&gt;把 prompt 寫成 pseudo code 是否就能自動解決呢？&lt;/p&gt;
&lt;p&gt;Pseudo code 形式的提示，的確可能改善步驟描述、問題分解與推理表現；&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 把部份子工作移交給外部程式處理，也可能讓某些環節更穩（這也是 agent skills 推薦的技巧）。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; 但這多半只是局部的改善。&lt;/p&gt;
&lt;p&gt;反觀某些工具，處理長串流程的穩定度會明顯高於單靠 prompt 的系統。以 Claude Code 為例，它做一長串動作時，常會在中途停下來，檢查某一步有沒有成立，再決定要不要往下一步走。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這給了我們一個暗示，某些原本放在 prompt 裡的責任，其實應該移交給外部控制機制。&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這篇文章要談的，就是在多步驟 workflow 下，責任該怎麼重新分配。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/04/genai-multi-steps.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/04/genai-multi-steps.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;workflow-常見的失靈情況&#34;&gt;Workflow 常見的失靈情況&lt;/h2&gt;
&lt;p&gt;多步驟 workflow 常見的失靈，不是 agent 完全沒做事，而是某一步其實還沒達到可以進入下一步的條件，流程卻已經先往下走了。&lt;/p&gt;
&lt;p&gt;先看清楚有哪些失靈型態，才不會把所有問題都模糊地歸成「模型不穩」，最後又走回修 prompt 措辭的老路。&lt;/p&gt;
&lt;h3 id=&#34;前一階段還沒做完後一階段就先開始&#34;&gt;前一階段還沒做完，後一階段就先開始&lt;/h3&gt;
&lt;p&gt;很多 workflow 有明確前後順序，前一階段是否真的完成，會直接影響後一階段能不能開始。&lt;/p&gt;
&lt;p&gt;問題是，就算 prompt 裡特別提醒「請照順序做」，agent 仍然很容易在前一段只做了一部分時就先往下走，或者把局部進展誤判成整體完成。表面上看起來流程順順地走，實際上是在偷渡。&lt;/p&gt;
&lt;p&gt;解決這類問題的關鍵，是要有&lt;strong&gt;階段切換門檻&lt;/strong&gt;：前一階段到底要滿足什麼條件，才可以切換到下一個階段。譬如說，若 workflow 要先完成資訊蒐集、列出受影響檔案、完成某個 patch，或確認某個工具結果，這些條件就得變成可檢查的切換條件。Prompt Chaining &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; 若少了這一環，後續步驟很容易過早展開。&lt;/p&gt;
&lt;p&gt;只要 workflow 的階段切換開始依賴外部可檢查的完成條件，責任就不能只留在語言敘述層。&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;說是已經做了但其實並沒有&#34;&gt;說是已經做了，但其實並沒有&lt;/h3&gt;
&lt;p&gt;模型很容易把打算做的事、以為做過的事，或上一輪口頭描述過的事，直接當成已經發生的結果。這時流程雖然還在跑，但一樣是在偷渡。&lt;/p&gt;
&lt;p&gt;解決這類問題的關鍵，是&lt;strong&gt;把實際結果納入流程判斷&lt;/strong&gt;，而不是繼續相信 agent 的口頭自述。只要有工具在執行，workflow 的真實狀態就不只在 token 裡，也在檔案、命令輸出、測試結果、資料寫入狀態與其他可讀取的執行結果裡，甚至包成 sandbox。&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt; Claude Code 這類工具之所以看起來比較會在中途調整，背後也是根據外部是否有實際結果來判斷，而不是只照著一開始的語言規劃一路往前衝。&lt;sup id=&#34;fnref1:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;不能只看模型上一輪說了什麼，要看它做了沒。&lt;/p&gt;
&lt;h3 id=&#34;驗證還沒通過系統就先算完成&#34;&gt;驗證還沒通過，系統就先算完成&lt;/h3&gt;
&lt;p&gt;很多 workflow 不只要求產生內容，還要求它通過測試、比對、檢查、資料讀取或其他形式的驗證。&lt;/p&gt;
&lt;p&gt;問題是，模型很容易把「答案已產生」直接當成「工作已完成」。內容也許已經生成，但還沒通過驗證，流程卻已經先宣布結案。&lt;/p&gt;
&lt;p&gt;解決這類問題的關鍵，就是把驗證機制真正實作出來，確實併入完成條件的一部分。&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt; Prompt 可以要求「驗證通過才能算完成」，但如果系統沒有把驗證變成真正的完成條件與放行門檻，這句話就只是許願，算不上控制。&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;問題其實都落在完成的判定&#34;&gt;問題其實都落在「完成的判定」&lt;/h3&gt;
&lt;p&gt;我把以上情況整理成一張表：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;常見情況&lt;/th&gt;
          &lt;th&gt;缺的是什麼&lt;/th&gt;
          &lt;th&gt;最小控制焦點&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;前一階段還沒完成，後一階段卻已經開始&lt;/td&gt;
          &lt;td&gt;階段切換門檻&lt;/td&gt;
          &lt;td&gt;先確認前一步是否真的成立&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;說是已經做了，但其實並沒有&lt;/td&gt;
          &lt;td&gt;以實際結果判斷&lt;/td&gt;
          &lt;td&gt;先確認工具結果，再判斷下一步&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;驗證還沒通過，流程已先把這一步視為完成&lt;/td&gt;
          &lt;td&gt;完成條件&lt;/td&gt;
          &lt;td&gt;先分清「有產出」與「已完成」&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;這些情況表面上不同，骨子裡其實都在問同一件事：流程往下走之前，系統到底根據什麼來判定這一步已經完成，判定它已經可以繼續往下走？&lt;/p&gt;
&lt;h2 id=&#34;prompt-的極限到哪裡系統的責任就從哪裡開始&#34;&gt;Prompt 的極限到哪裡，系統的責任就從哪裡開始&lt;/h2&gt;
&lt;p&gt;既然已經知道，把 prompt 寫得更像 SOP 有其極限，接下來就要問：哪些責任仍適合留在語言層，哪些責任其實已經需要外部承接。&lt;/p&gt;
&lt;p&gt;對多步驟 workflow 來說，prompt 最擅長處理的，仍然是&lt;strong&gt;流程說明&lt;/strong&gt;：任務怎麼展開、各階段如何安排、要留下哪些中間產物、哪些不確定性要揭露、輸出格式與角色邊界是什麼。這些要求會直接影響 agent 怎麼走。&lt;/p&gt;
&lt;p&gt;所以 prompt 通常負責這些事（這也是所謂「prompt 模板」常見的套路）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;任務意圖與角色界定&lt;/li&gt;
&lt;li&gt;階段順序與作業程序&lt;/li&gt;
&lt;li&gt;中間產物與輸出格式&lt;/li&gt;
&lt;li&gt;需要揭露的不確定性與限制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但只要 workflow 開始依賴下面這些能力，責任通常就不能只留在 prompt：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;持有真實狀態&lt;/li&gt;
&lt;li&gt;判定某一步是否已完成&lt;/li&gt;
&lt;li&gt;在條件未滿足時擋下後續步驟&lt;/li&gt;
&lt;li&gt;接住高風險副作用&lt;/li&gt;
&lt;li&gt;提供 retry、resume、rollback 與 audit&lt;/li&gt;
&lt;li&gt;持續量測控制是否退化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;換句話說，prompt 負責把流程講清楚；至於完成條件、階段切換條件、工具結果怎麼確認、流程卡住時怎麼處理、失敗後怎麼恢復，則比較接近系統該接手的部分。&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這樣拆的好處是：不會把所有問題都塞回 prompt，也不會把所有任務都誤判成一定要上到很重的外部系統。&lt;/p&gt;
&lt;h2 id=&#34;什麼情況需要把控制交給外部機制&#34;&gt;什麼情況需要把控制交給外部機制&lt;/h2&gt;
&lt;p&gt;談到這裡，我們可以歸納出，哪些要求值得外移，又該外移到什麼程度。&lt;/p&gt;
&lt;p&gt;可以先看 workflow 的成敗，是否已經明顯依賴以下幾種能力：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;若 workflow 需要……&lt;/th&gt;
          &lt;th&gt;就不能只靠……&lt;/th&gt;
          &lt;th&gt;至少需要……&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;前一步完成後才可切換&lt;/td&gt;
          &lt;td&gt;prompt 提醒「照順序做」&lt;/td&gt;
          &lt;td&gt;可檢查的階段切換門檻&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;根據真實執行結果判斷下一步&lt;/td&gt;
          &lt;td&gt;模型口頭自述&lt;/td&gt;
          &lt;td&gt;確認工具結果，並納入判斷&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;驗證成立才算完成&lt;/td&gt;
          &lt;td&gt;單方面宣告完成&lt;/td&gt;
          &lt;td&gt;明確的完成條件&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;發生錯誤後恢復流程&lt;/td&gt;
          &lt;td&gt;人工臨時補救&lt;/td&gt;
          &lt;td&gt;retry / resume / rollback&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;持續判斷控制是否退化&lt;/td&gt;
          &lt;td&gt;單次案例觀察&lt;/td&gt;
          &lt;td&gt;traces / evals / regression checks&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;只要遇到這幾種情況，相關控制責任通常就值得外移。像驗證是否成立、workflow 是否退化這類問題，已經需要可量測的 eval、trace 或 grader 來承接。像 retry、resume、rollback 這類恢復能力，則更明顯屬於系統層機制，而不是單靠語言承諾。&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;相反地，若任務流程短、狀態依賴弱、錯誤成本低、副作用小，而且完成與否主要還是取決於文字品質、結構清楚或分析完整度，prompt 往往仍然是成本效益最高的主要承接方式。這種情況下，把要求留在 prompt，再配合適度的格式約束與中間產物揭露，通常就夠了。&lt;/p&gt;
&lt;p&gt;不是每一個多步驟任務，都值得為了少量風險加上一整套外部控制。畢竟很多團隊真正需要的，未必是很重的 agent platform。常常只需要一層很薄的外層包裝，把幾件事真正接住。&lt;/p&gt;
&lt;p&gt;所以判斷要不要外移，看的不是流程有幾步，也不是 prompt 已經寫了多長，而是：&lt;strong&gt;「完成」這件事，是不是已經需要由語言以外的東西來決定。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;結論&#34;&gt;結論&lt;/h2&gt;
&lt;p&gt;步驟明明已經寫清楚了，agent 還是不照著做，很多時候不是因為 prompt 還不夠細，而是 workflow 已經進入另一種責任分配：怎麼才算完成、什麼時候才能往下走、工具結果要不要納入判斷、驗證是否成立、失敗後果由誰接住，這些都不能只靠語言承諾支撐。&lt;/p&gt;
&lt;p&gt;多步驟 workflow 要穩，關鍵不是再把 prompt 步驟寫得很細，甚至改寫成 pseudo code，而是先分清楚：&lt;strong&gt;某一步算不算完成，最後由誰判定。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;下一次遇到問題時，先不要急著把 prompt 再寫長一倍。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Xinyi Chen et al., &amp;ldquo;&lt;a href=&#34;https://arxiv.org/abs/2406.19999&#34;&gt;The SIFo Benchmark: Investigating the Sequential Instruction Following Ability of Large Language Models&lt;/a&gt;&amp;rdquo; (2024). 這裡主要用來支撐本文的較窄主張：多步驟 sequential instruction following 的失敗是可量測的常見現象。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Iok Tong Lei et al., &amp;ldquo;&lt;a href=&#34;https://arxiv.org/abs/2305.11461&#34;&gt;Hint of Pseudo Code (HoPC): Programmatic Prompting Improves Reasoning&lt;/a&gt;&amp;rdquo;. 這裡主要用來支撐本文的較窄主張：pseudo-code 形式的提示，可能改善局部步驟表達、問題分解與推理表現；但它不直接支撐多步驟 agent workflow 在整體控制上的穩定性。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Wenhu Chen et al., &amp;ldquo;&lt;a href=&#34;https://arxiv.org/abs/2211.12588&#34;&gt;Program of Thoughts Prompting: Disentangling Computation from Reasoning for Numerical Reasoning Tasks&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：把部分計算工作外部化，交給程式執行或解譯器處理，可以降低模型把推理與計算混在同一段生成裡的負擔。這裡只支撐「部分工作可外部化承接」這個較窄主張，不直接支撐一般性的 workflow 控制結論。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Anthropic, &amp;ldquo;&lt;a href=&#34;https://code.claude.com/docs/en/how-claude-code-works&#34;&gt;How Claude Code works&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：Claude Code 在工具使用、檔案編輯與命令執行之後，會根據新取得的結果持續更新後續行動；也就是說，後續步驟會受執行結果影響，而不是只依賴先前的語言規劃。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Anthropic, &amp;ldquo;&lt;a href=&#34;https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents&#34;&gt;Effective harnesses for long-running agents&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：長時間執行的 agent application，通常需要外層 harness 來承接任務切換、artifact 傳遞、可恢復進度與執行環境互動，而不是只靠 prompt 在語言層維持流程。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Anthropic, &amp;ldquo;&lt;a href=&#34;https://www.anthropic.com/research/building-effective-agents&#34;&gt;Building Effective Agents&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：Anthropic 把 prompt chaining、routing、parallelization、orchestrator-workers、evaluator-optimizer 等整理成 workflow patterns，而不是只把 agent 問題理解成單輪 prompt 技巧。&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;OpenAI Developers, &amp;ldquo;&lt;a href=&#34;https://developers.openai.com/api/docs/guides/agents-sdk&#34;&gt;Agents SDK&lt;/a&gt;&amp;rdquo; &amp;amp; &amp;ldquo;&lt;a href=&#34;https://developers.openai.com/api/docs/guides/agent-builder&#34;&gt;Agent Builder&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：官方文件直接碰到 orchestration、results and state、tool use、workflow 組裝、multi-step work 與 runtime control。&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;OpenAI Developers, &amp;ldquo;&lt;a href=&#34;https://developers.openai.com/blog/sandbox-agents&#34;&gt;Sandbox agents&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：sandbox agents 把 orchestration 與 execution 分離，並提供容器化 execution environment、files、commands、snapshots 與 memory。&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;OpenAI Developers, &amp;ldquo;&lt;a href=&#34;https://developers.openai.com/blog/eval-skills&#34;&gt;Testing Agent Skills Systematically with Evals&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：evals 不應只看最終答案，而應系統性測試 workflow、skills 與 traces。&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;OpenAI Developers, &amp;ldquo;&lt;a href=&#34;https://developers.openai.com/api/docs/guides/agent-evals&#34;&gt;Evaluate agent workflows&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：evaluation runs、graders、datasets 與 traces 可用來量測 workflow 本身，而不只量測最終答案。&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;OpenAI, &amp;ldquo;&lt;a href=&#34;https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/&#34;&gt;A practical guide to building AI agents&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：OpenAI 把 orchestration、tools、guardrails、human review、memory / state 等放在 agent 系統設計的討論範圍內。&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;Anthropic, &amp;ldquo;&lt;a href=&#34;https://code.claude.com/docs/en/checkpointing&#34;&gt;Checkpointing&lt;/a&gt;&amp;rdquo;. 這裡主要支撐的是：Claude Code 提供 checkpointing 機制，可 rewind code、fork conversation，或同時處理兩者。這裡主要用來支撐 rollback / resume 需要系統層能力，而不是單靠語言承諾。&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>AI 時代，該怎麼選程式語言？</title>
      <link>//william-yeh.net/post/2026/04/genai-pl/</link>
      <pubDate>Sun, 12 Apr 2026 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2026/04/genai-pl/</guid>
      
        <description>&lt;p&gt;在許多系統開發與工程教育脈絡中，C/C++ 曾長期佔據核心位置。後來主流答案逐漸分散，Java、C#、Python、TypeScript、Go 各自崛起，也都一度被期待成為下一個中心。&lt;/p&gt;
&lt;p&gt;到了 LLM 時代，這個問題又被拿出來重問一次。從 agent、harness 與同類工具在 TypeScript、Python、Rust 等不同生態中並行發展、彼此競逐，就看得出這仍是秦失其鹿，天下共逐之的局面。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;但如果問題還停在「哪門程式語言最好」，最後多半只會得到一份偏好清單。語言模型對某種語言、生態與框架是否熟悉，當然會影響起稿速度與初稿品質；可是在「生成結果不能直接被信任」的前提下，技術選型真正該看的，是依風險分層，選擇最能支撐驗證與收斂的程式語言 × 驗證鏈組合。&lt;/p&gt;
&lt;p&gt;這不是一篇語言排名文；這是一篇重新定義選型判準的文章。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/04/genai-pl.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/04/genai-pl.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;判準驗證回饋&#34;&gt;判準：驗證回饋&lt;/h2&gt;
&lt;p&gt;我會把判準拆成三個面向：&lt;strong&gt;約束顯性化、錯誤可診斷性、修正迴圈成本。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第一，是&lt;strong&gt;約束顯性化&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;系統裡真正重要的規則，有沒有被寫出來？這不只包括型別、介面、可空值與錯誤處理，也包括更高一層的架構約束：依賴方向是否受控制、重要邊界是否清楚、副作用出口是否外露、哪些規則能放在哪裡，是否已經被寫進 repo、測試與工具鏈，而不是只留在人腦與團隊默契裡。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;關鍵約束沒有顯性化，語言模型就很容易補出一段表面合理、實際上已經穿透邊界的程式碼。&lt;/p&gt;
&lt;p&gt;第二，是&lt;strong&gt;錯誤可診斷性&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;問題能不能提早暴露？暴露之後，位置夠不夠局部？錯誤訊息是否足夠讓人與語言模型採取下一步？有些失敗是編譯器指出型別不吻合；有些失敗是測試、靜態分析或架構規則檢查指出邊界被穿透；也有些失敗要等整段功能都跑歪之後，才以模糊症狀浮出來。前兩種通常比較容易進入修正流程；最後一種很容易把人和語言模型一起拖進猜測循環。&lt;/p&gt;
&lt;p&gt;第三，是&lt;strong&gt;修正迴圈成本&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;從發現問題到修掉問題，這條路有多短、多穩、多能反覆？有些語言和工具鏈把回饋收得很緊：一存檔，型別錯誤、lint、測試、靜態分析就一起往前推。有些情境則要靠團隊自己把這條鏈補起來：寫測試、補 sandbox、整理 fixture、把規格拆細。這不一定是壞事，但如果修正迴圈太長、太散、太仰賴人腦維持，生成帶來的速度最後很可能會被問題分流成本吃掉。&lt;/p&gt;
&lt;p&gt;對 AI 協作來說，程式語言的價值，很大一部分就落在這裡。實際效果通常不是由語法表面決定，而是由它背後那整套工程鏈決定：型別系統、編譯器、靜態分析、測試、sandbox、CI、架構規則、review 習慣，以及團隊是否真的把這些機制接起來。&lt;/p&gt;
&lt;p&gt;現有研究也大致支持這個方向。像 RUSTASSISTANT 這類研究顯示，當語言模型拿到更明確、較局部、可行動的編譯器錯誤訊號時，自動修正的表現確實可能明顯改善。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; 另一類研究則指出，自動化回饋迴圈有機會改善 LLM 產出的可修正性與整體收斂能力。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這些材料還不夠弄出一份跨語言的總排名，但已經足夠支持一個實務判斷：&lt;strong&gt;AI 協作的重點，不在模型先吐出什麼，而在系統後面會怎麼承接。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;typescript應用層的顯性契約&#34;&gt;TypeScript：應用層的顯性契約&lt;/h2&gt;
&lt;p&gt;TypeScript 很適合放在應用層，因為它擅長把原本留在人腦裡的假設寫進程式裡。&lt;/p&gt;
&lt;p&gt;應用層系統最麻煩的地方，不是語法，而是資料長什麼樣子、API 回傳什麼、哪個欄位可能是 &lt;code&gt;null&lt;/code&gt;、重構之後哪些地方會一起受影響。TypeScript 的強項，就是把這些原本靠默契維持的東西，寫成編輯器與工具鏈也看得懂的契約。&lt;/p&gt;
&lt;p&gt;型別、介面、函式簽名、nullable 邊界，會把一部分原本隱含的假設直接前移；一旦這些假設被寫出來，回饋也比較容易來得早，而且夠局部。型別不吻合、介面沒對齊、重構後遺漏哪個使用點，往往在編輯器&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; 或編譯階段就已經浮出來。對人和語言模型來說，這種錯誤比執行期才浮現的模糊故障更容易處理。TypeScript 官方對自己的定位也很坦白：就是要成為 JavaScript 的 static type checker。&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這不代表用了 TypeScript 就能自動保證商業邏輯一定會正確。它真正做的，是把許多原本靠人腦維持的假設，改成比較穩定的工程訊號。對 AI 協作來說，這很重要，畢竟語言模型最常出錯的地方，不是完全不會寫，而是把邊界寫鬆、把例外漏掉，或把幾個看似相近的型別混成同一件事。&lt;/p&gt;
&lt;p&gt;它改善得最明顯的，其實是&lt;strong&gt;重構診斷鏈&lt;/strong&gt;。改動一個型別定義、調整一個介面、收斂一個資料結構，哪些地方會一起受影響，通常可以更快浮出來。這不只幫助人類開發者，也讓語言模型生成的修改比較容易被局部檢查。&lt;/p&gt;
&lt;p&gt;所以在複雜、壽命長、多人協作、需要反覆重構的產品系統裡，TypeScript 很自然會成為 AI 協作的預設選項。&lt;/p&gt;
&lt;h2 id=&#34;python探索層與後補驗證&#34;&gt;Python：探索層與後補驗證&lt;/h2&gt;
&lt;p&gt;Python 很適合探索層。&lt;/p&gt;
&lt;p&gt;資料清洗、notebook 探索、模型實驗、工作流編排、自動化腳本、內部工具，這些工作追求的往往不是一開始就把邊界封死，而是先把想法試出來，再決定哪些約束值得前移。Python 在這一層一直很有位置，不只是因為語言模型熟，也因為它背後本來就長出了一整套成熟的探索式工作流。&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;它的代價也很清楚。很多問題不會自己提早跳出來，而是要等到執行、測試、整合，甚至真實資料流進來之後，才逐步暴露。這在探索階段未必是問題；但當系統開始長大、模組開始互相依賴、邊界開始固定，延後暴露的成本就會愈來愈高。&lt;/p&gt;
&lt;p&gt;所以 Python 的重點，是驗證鏈通常要靠開發者主動補齊。型別工具當然重要，但它們多半屬於後補工程，而不是預設前置約束。系統一旦開始工程化，type hints、mypy、pyright 這些工具就很有價值。它們不能把 Python 變成 TypeScript 那種強制契約環境，但確實能把一部分原本留到執行時才知道的問題，往前拉到提交之前。&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;迭代式自我修正機制也值得注意。像 Self-Refine 的研究顯示，透過同一語言模型反覆生成批評並改寫輸出，的確可以改善部分程式相關任務的結果。&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt; 少了編譯期強護欄時，這類反覆回饋的機制就更重要。&lt;/p&gt;
&lt;p&gt;對 Python 可以先下個簡單判斷：它適合探索層，但不適合長期停在鬆散狀態。任務一旦開始收斂，驗證鏈、型別工具、測試與自動化修正機制都得補上。&lt;/p&gt;
&lt;h2 id=&#34;rust核心區的前置約束&#34;&gt;Rust：核心區的前置約束&lt;/h2&gt;
&lt;p&gt;Rust 很適合放在核心區，因為它把更多高成本錯誤推到執行之前。&lt;/p&gt;
&lt;p&gt;所有權、借用、顯式錯誤處理、記憶體安全，加上接近 C++ 的性能，讓 Rust 很適合放在那些真正承受不起錯的地方：系統邊界、效能瓶頸、安全敏感模組、工具鏈核心。像 Hugging Face &lt;a href=&#34;https://github.com/huggingface/tokenizers&#34;&gt;Tokenizers&lt;/a&gt; 與 &lt;a href=&#34;https://github.com/huggingface/candle&#34;&gt;Candle&lt;/a&gt; 這類專案，都把 Rust 放在很核心的位置。&lt;/p&gt;
&lt;p&gt;從驗證回饋的角度看，Rust 最重要的地方，在於它替生成式協作加上了一個強度很高的前置驗證入口。語言模型可以先產生草稿，但草稿要放進系統前，必須先通過型別、所有權、生命週期與錯誤處理這些約束。這會帶來三個效果：約束更早顯性化、程式本體層的大量錯誤可以提早被局部定位，也有一部分問題根本進不到執行期。&lt;/p&gt;
&lt;p&gt;不過 Rust 能使得上力的，主要還是那些已經被形式化、並寫進語言與程式結構裡的約束；它不會自動替你驗證產品規格、流程例外與商業判準。折扣規則算得對不對、權限邏輯是否符合產品政策、某個狀態組合在真實業務上是否合法，這些問題通常活在需求、文件、流程與領域知識裡，不會完整地活在型別系統裡。&lt;/p&gt;
&lt;p&gt;這也是 Rust 的代價。探索階段未必要固定下來的結構問題，它卻要求你更早面對：資料怎麼流、邊界怎麼切、資源由誰持有、錯誤怎麼往上拋。有些錯誤很局部，修起來很快；但有些錯誤暴露的其實不是語法細節，而是資料流、API 邊界或狀態設計本身還沒有收斂。&lt;/p&gt;
&lt;p&gt;所以 Rust 很適合那些已經開始收斂、值得把約束前移的核心任務，卻不一定適合探索層。LLM 確實降低了採用 Rust 的門檻，但 Rust 最好的位置，仍然比較像在核心層。&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;go平台層的穩定節奏&#34;&gt;Go：平台層的穩定節奏&lt;/h2&gt;
&lt;p&gt;Go 的強項不花俏，就是穩。&lt;/p&gt;
&lt;p&gt;它的優勢不在最強的護欄，也不在最大的探索彈性，而在一套簡潔、收斂、低負擔的預設模式。對 AI 協作而言，這通常代表偏航空間更小、程式風格較一致，以及修正成本較可控制。&lt;/p&gt;
&lt;p&gt;Go 從一開始就不是為語法炫技設計的。Go at Google 那篇文章講得很直接：這門程式語言的目標，是減少大型軟體開發中的遲滯與笨重感，而且它是為那些要寫、讀、除錯與維護大型系統的人設計的。&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt; 這也讓 Go 的優勢比較像一組工程取向明確的選擇：語言表面積小、工具鏈單純、編譯快速、標準函式庫完整。Go 社群自己的年度調查，也持續把簡潔、可維護與穩定工具鏈列為很主要的使用理由。&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;放進前面的框架來看，Go 的強項比較像是把日常工作流收得很緊。&lt;code&gt;go&lt;/code&gt; 命令把 build、test、fmt、fix 收在同一套官方工具鏈裡&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;；語法與慣例也長期維持在相對收斂的範圍內。官方長期重視 &lt;code&gt;gofmt&lt;/code&gt;、idiomatic code 與 code review 慣例 &lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt;，讓大家可放心：團隊與語言模型共同操作同一份程式碼時，比較不容易一路寫歪。&lt;/p&gt;
&lt;p&gt;雖然不像 Rust 那樣把很多高成本錯誤前推到最前面，但也不容易把系統帶向過度抽象、過度分散、難以追蹤的狀態。對 CLI、基礎設施、平台工程與後端服務這類工作來說，Go 往往比表面上看起來更耐用。&lt;/p&gt;
&lt;h2 id=&#34;分層設計&#34;&gt;分層設計&lt;/h2&gt;
&lt;p&gt;把前面的判準落實到實務面，重點就在於，要在不同風險區，放上不同強度、不同時點的驗證機制，也就是分層設計。這裡有三個核心問題：&lt;/p&gt;
&lt;p&gt;第一，這一層最承受不起的是什麼：速度慢、重構痛、部署複雜，還是安全、效能與可靠性風險？&lt;/p&gt;
&lt;p&gt;第二，這一層最需要哪種驗證：型別、編譯器、靜態分析、測試、sandbox，還是高密度的人類 review？&lt;/p&gt;
&lt;p&gt;第三，這一層的關鍵知識主要活在哪裡：活在程式語言本身、框架慣例、repo 結構與架構規則、文件、團隊的隱形知識，還是 CI 與基礎設施流程裡？&lt;/p&gt;
&lt;p&gt;這三個問題想清楚，程式語言選型的討論才不會停留在偏好清單。&lt;/p&gt;
&lt;p&gt;探索層，Python 仍然很自然。它適合拿來確認方向、讓資料露出形狀、把流程跑通；但當任務開始收斂，就應補上型別註記、靜態檢查、測試與自動化驗證鏈，而不是讓探索式寫法一路帶到後期。&lt;/p&gt;
&lt;p&gt;應用層，TypeScript 的優勢在顯性型別、重構能力、多人協作與長期維護。當系統最怕的是隱含假設太多、邊界鬆動、改一處壞三處時，它常會是 AI 輔助產品開發很自然的預設選項之一。&lt;/p&gt;
&lt;p&gt;核心區，最值得把約束前移。當錯誤代價高到不能留在後面處理，Rust 的型別、ownership 與編譯期驗證就特別有價值。它不必成為全面預設，但很適合放在真正關鍵的地方。&lt;/p&gt;
&lt;p&gt;平台層，很多時候追求的是一致性、簡潔性、可讀性、快編譯與低樣板。Go 不一定最華麗，但常常能提供低負擔、低偏航、易維護的工程條件。對許多團隊來說，這種穩健性比語言敘事的戲劇性更有用。&lt;/p&gt;
&lt;p&gt;補充一點，大型企業後端往往不是從零選程式語言，而是在既有堆疊、IDE、生態、人才結構與組織流程裡持續演化。從這個角度看，Java 與 C# 的問題不只是適不適合 AI 協作，而是它們原本就已經在許多團隊中形成穩定的收斂條件。若團隊已有深厚的累積，沒有必要為了語言選型的抽象論點而另起爐灶。&lt;sup id=&#34;fnref:15&#34;&gt;&lt;a href=&#34;#fn:15&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;程式語言選擇走到這裡，比較像架構設計，而不再只是口味問題。&lt;/p&gt;
&lt;h2 id=&#34;尚未定論的部分&#34;&gt;尚未定論的部分&lt;/h2&gt;
&lt;p&gt;有幾件事，現在還不能把結論講死。&lt;/p&gt;
&lt;p&gt;第一，&lt;strong&gt;驗證回饋&lt;/strong&gt;這個方向大致成立；但不同程式語言在人類問題分流成本、修正效率與整體收斂速度上的差異，到底有多大，仍然缺夠乾淨的全面性證據。現在比較多的是局部研究、特定任務或特定工具鏈的結果；它們能支持方向，還不足以直接推出一份放諸各場景皆準的程式語言排名。&lt;/p&gt;
&lt;p&gt;第二，&lt;strong&gt;前置護欄&lt;/strong&gt;的價值很真實，但護欄愈強，不代表整體開發一定愈有效率。像 Rust 這類程式語言，確實能把很多錯誤提早暴露，但提早暴露不等於提早解決。有些錯誤是局部修正，有些則會牽動資料流、API 邊界與設計本身。程式語言提供的驗證強度，不能單獨和整體生產力畫上等號；還得放回任務型態、團隊能力與系統成熟度裡一起看。&lt;/p&gt;
&lt;p&gt;第三，程式語言本身從來不是全部。CI 有沒有真的接起來、測試與 sandbox 有沒有成形、團隊有沒有能力 review 產出、關鍵規格有沒有被整理成語言模型與工具都吃得下的形式，這些都會直接改變選型最後的實際收益。其中特別值得單獨點名的是 agentic 工作流裡的上下文管理：長上下文不是免費的。現有研究顯示，模型對於長串輸入中，位於中段的關鍵資訊，利用能力會明顯下降。情境變長，不代表使用品質會穩定提升。&lt;sup id=&#34;fnref:16&#34;&gt;&lt;a href=&#34;#fn:16&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;所以，在生成愈來愈便宜的前提下，程式語言選擇真正該優先服務的，還是驗證與收斂，而不只是起稿速度。&lt;/p&gt;
&lt;h2 id=&#34;結語&#34;&gt;結語&lt;/h2&gt;
&lt;p&gt;LLM 讓生成變便宜之後，型別、編譯器、測試、靜態分析、清楚的系統邊界、可被工具檢查的架構規則、可 review 的程式碼，都變得更加重要。&lt;/p&gt;
&lt;p&gt;AI 時代的語言選型，最終選擇仍應由任務收斂程度、團隊成熟度、既有系統與工具鏈條件共同決定。重點還是&lt;strong&gt;把高成本錯誤提前到團隊還處理得起的位置&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;這有點像走山路。差別不在誰起步快，而在於你是走到彎路之前就知道路線偏了，還是衝到後面才發現整段路都走錯。好的語言與驗證鏈，價值就在這裡：讓錯誤早點露出來，修正還來得及。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Claude Code 是用 TypeScript 寫的；程式碼外洩事件之後，有人用 Python 復刻了一份核心 &lt;a href=&#34;https://github.com/HKUDS/OpenHarness&#34;&gt;OpenHarness&lt;/a&gt;；&lt;a href=&#34;https://github.com/openclaw/openclaw&#34;&gt;OpenClaw&lt;/a&gt; 是用 TypeScript 寫的，也有人用 Rust 復刻了一份更緊實的 &lt;a href=&#34;https://github.com/zeroclaw-labs/zeroclaw&#34;&gt;ZeroClaw&lt;/a&gt;。這些例子主要用來說明：agent 類工具的語言生態仍在快速競逐中，尚未收斂成單一主流答案。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;關於 LLM / agent 情境下，為什麼軟體架構的價值在於把邊界、依賴方向、驗證入口與治理規則外露成可被人與工具使用的訊號，可參考我稍早的一篇文章：〈&lt;a href=&#34;//william-yeh.net/post/2026/03/genai-revisit-arch/&#34;&gt;LLM 時代，傳統軟體架構該重新檢查了&lt;/a&gt;〉。這裡主要用來補強本文較窄的主張：約束顯性化不只發生在型別層，也發生在架構與治理層。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Rust 工具鏈原本就有接近 lint auto-fix 的能力，例如 &lt;code&gt;cargo clippy --fix&lt;/code&gt;；Microsoft &amp;ldquo;&lt;a href=&#34;https://www.microsoft.com/en-us/research/wp-content/uploads/2024/08/paper.pdf&#34;&gt;RUSTASSISTANT: Using LLMs to Fix Compilation Errors in Rust Code&lt;/a&gt;&amp;rdquo; 研究顯示，當語言模型接收到 Rust 編譯器提供的明確錯誤訊號後，自動修正的準確度有機會提高。這裡主要支撐的是：清楚、局部、可行動的錯誤回饋，確實有助於程式修正收斂。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Ravin Ravi et al., &amp;ldquo;&lt;a href=&#34;https://arxiv.org/abs/2603.23613&#34;&gt;LLMLOOP: Improving LLM-Generated Code and Tests through Automated Iterative Feedback Loops&lt;/a&gt;&amp;quot;，IEEE ICSME 2025，arXiv:2603.23613。這裡主要支撐的是：自動化回饋迴圈，確實有機會改善 LLM 產出的可修正性與整體收斂能力。更一般化的護欄框架，可另參〈&lt;a href=&#34;//william-yeh.net/post/2026/03/genai-guardrail/&#34;&gt;GenAI 的工程護欄是什麼？&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;TypeScript 是編輯器友好的語言；&lt;a href=&#34;https://microsoft.github.io/language-server-protocol/&#34;&gt;LSP (Language Server Protocol)&lt;/a&gt; 最初就是為了改善 TypeScript 與 VS Code 的開發體驗而發展出來的。這裡主要支撐的是：TypeScript 的回饋機制不只存在於編譯階段，也深度嵌進日常編輯與重構流程。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;TypeScript Handbook 中的 &amp;ldquo;&lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/intro.html&#34;&gt;The goal of TypeScript is to be a static typechecker for JavaScript programs&lt;/a&gt;&amp;quot;。這裡主要支撐的是：TypeScript 的官方定位，本來就把靜態檢查視為核心價值，而不只是較好寫的 JavaScript。&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;Python 在探索層的優勢，不只來自語言本身，也來自它與互動式計算、資料處理、模型實驗工具長期扣合。Jupyter 文件 &amp;ldquo;&lt;a href=&#34;https://docs.jupyter.org/en/latest/what_is_jupyter.html&#34;&gt;What is Jupyter?&lt;/a&gt;&amp;rdquo; 直接把 notebook 描述為結合程式碼、文字、資料與視覺化的共享文件；TensorFlow 官方文件 &amp;ldquo;&lt;a href=&#34;https://www.tensorflow.org/about&#34;&gt;TensorFlow Overview&lt;/a&gt;&amp;rdquo; 強調 eager execution 與原型設計、快速除錯的關係；&lt;a href=&#34;https://pytorch.org/projects/pytorch/&#34;&gt;PyTorch&lt;/a&gt; 則明確強調其 Pythonic design 與從研究原型走向生產部署的連續性。這裡主要支撐的是：Python 生態確實長出了一套成熟的探索與實驗工作流。&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://mypy.readthedocs.io/&#34;&gt;mypy&lt;/a&gt; 是 Python 社群成熟的靜態型別檢查工具；&lt;a href=&#34;https://microsoft.github.io/pyright/&#34;&gt;Pyright&lt;/a&gt; 是 Microsoft 開發的 Python 靜態型別檢查工具，也是 VS Code 裡 Pylance 的核心引擎。這裡主要支撐的是：Python 的驗證鏈可以靠後補工具逐步補強，而不必完全停留在動態語言的預設狀態。&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;Aman Madaan et al., &amp;ldquo;&lt;a href=&#34;https://arxiv.org/abs/2303.17651&#34;&gt;Self-Refine: Iterative Refinement with Self-Feedback&lt;/a&gt;&amp;quot;，arXiv:2303.17651，2023。這裡主要支撐的是：反覆回饋機制，確實有機會改善部分程式相關任務的輸出；但它不直接證明任何單一程式語言因此已具充分的工程化驗證優勢。&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;Rust 官方文件 &amp;ldquo;&lt;a href=&#34;https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html&#34;&gt;What is Ownership?&lt;/a&gt;&amp;rdquo; 明確把 ownership 描述為一套不依賴垃圾回收、仍能提供記憶體安全保證的機制；Go 官方 &amp;ldquo;&lt;a href=&#34;https://go.dev/doc/gc-guide&#34;&gt;A Guide to the Go Garbage Collector&lt;/a&gt;&amp;rdquo; 則說明標準工具鏈包含追蹤式垃圾回收器，並持續針對 GC 成本與效能調校。現有材料足以支撐「清楚的編譯器錯誤回饋有助於語言模型修正 Rust 程式」這個較窄判斷；但本文目前不把 Rust ownership / borrow 與 Go 垃圾回收在 LLM 協作下的整體收斂效果，當成已有定論的比較結論。&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;Rob Pike，&amp;quot;&lt;a href=&#34;https://go.dev/talks/2012/splash.article&#34;&gt;Go at Google: Language Design in the Service of Software Engineering&lt;/a&gt;&amp;quot;。這裡主要支撐的是：Go 的原始設計取向，本來就不是語法炫技，而是大型軟體工程中的可讀、可維護與低負擔開發。&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;Go 官方 &lt;a href=&#34;https://go.dev/blog/survey2025-results&#34;&gt;&lt;em&gt;2025 Go Developer Survey Results&lt;/em&gt;&lt;/a&gt; 指出，2025 年調查共有 5,379 名 Go 開發者回覆。這裡主要用來支撐一個較窄判斷：Go 使用者長期重視簡潔、可維護與穩定工具鏈。&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;Go 官方文件 &amp;ldquo;&lt;a href=&#34;https://pkg.go.dev/cmd/go&#34;&gt;&lt;code&gt;cmd/go&lt;/code&gt;&lt;/a&gt;&amp;rdquo; 直接把 &lt;code&gt;go&lt;/code&gt; 描述為「管理 Go 原始碼的工具」；而同一套標準工具鏈內建 &lt;code&gt;build&lt;/code&gt;、&lt;code&gt;test&lt;/code&gt;、&lt;code&gt;fmt&lt;/code&gt;、&lt;code&gt;fix&lt;/code&gt; 等命令。這裡主要支撐的是：Go 的日常工程流程，本來就傾向收得較緊。&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;Go 官方長期把風格一致性與 idiomatic code 視為可維護性的一部分。&lt;a href=&#34;https://go.dev/blog/gofmt&#34;&gt;gofmt&lt;/a&gt;、&lt;a href=&#34;https://go.dev/doc/effective_go&#34;&gt;&lt;em&gt;Effective Go&lt;/em&gt;&lt;/a&gt; 與 &amp;ldquo;&lt;a href=&#34;https://go.dev/wiki/CodeReviewComments&#34;&gt;Go Code Review Comments&lt;/a&gt;&amp;rdquo; 都可支撐「Go 的語法與慣例相對收斂」這個判斷。&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:15&#34;&gt;
&lt;p&gt;這則註腳主要補充一個較窄判斷：大型企業後端的程式語言選型，很多時候不是從零開始，而是在既有技術堆疊、工具鏈、生態系、人才結構與組織流程裡持續演化。Spring Boot 官方的 &lt;a href=&#34;https://docs.spring.io/spring-boot/index.html&#34;&gt;&lt;em&gt;Spring Boot Documentation&lt;/em&gt;&lt;/a&gt;、.NET 官方的 &amp;ldquo;&lt;a href=&#34;https://dotnet.microsoft.com/en-us/learn/dotnet/what-is-dotnet&#34;&gt;What is .NET?&lt;/a&gt;&amp;rdquo; 與 Oracle 官方的 &lt;a href=&#34;https://docs.oracle.com/en/java/javase/&#34;&gt;&lt;em&gt;Java Documentation&lt;/em&gt;&lt;/a&gt; 都足以支撐這個判斷。&amp;#160;&lt;a href=&#34;#fnref:15&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:16&#34;&gt;
&lt;p&gt;Nelson F. Liu et al., “&lt;a href=&#34;https://direct.mit.edu/tacl/article/doi/10.1162/tacl_a_00638/119630/Lost-in-the-Middle-How-Language-Models-Use-Long&#34;&gt;Lost in the Middle: How Language Models Use Long Contexts&lt;/a&gt;”，TACL 2024。這裡主要支撐的是：長上下文不是免費的；當關鍵資訊落在中段時，模型的利用能力可能明顯下降。更完整的工作流層面討論，可另參〈&lt;a href=&#34;//william-yeh.net/post/2026/03/genai-se-level-up/&#34;&gt;AI 會寫程式之後，軟體工程真正變貴的是什麼&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:16&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>GenAI 的工程護欄是什麼？—— 把規矩寫成工具鏈會執行的限制</title>
      <link>//william-yeh.net/post/2026/03/genai-guardrail/</link>
      <pubDate>Sat, 28 Mar 2026 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2026/03/genai-guardrail/</guid>
      
        <description>&lt;p&gt;Vibe coding 時，LLM 並不真的「聽話」。很多人因此去找更強的咒語，想拴住這匹脫韁的野馬。&lt;/p&gt;
&lt;p&gt;但 prompt 裡寫一句「請遵守 Hexagonal Architecture」，效果其實很有限。它比較像在工地口頭交代一句「請按圖施工」：有提醒，沒有保證。最後沒歪掉，很多時候也不是因為工人真的照做，而是旁邊還有人在監工。&lt;/p&gt;
&lt;p&gt;你真的相信 AI 會乖乖聽勸嗎？&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;工程上真正有約束力的規矩，不能只停在說明、默契或設計哲學。它得能被系統檢查；必要時，能拒絕、阻斷，甚至直接讓流程停下來。&lt;/p&gt;
&lt;p&gt;所以，談 LLM 時代的工程護欄，先抓住一個判準就夠了：&lt;strong&gt;這條規矩能不能被機器檢查，並在必要時改變系統的下一步。&lt;/strong&gt;&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/03/genai-guardrail.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/03/genai-guardrail.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;一先分清鷹架驗證器與護欄&#34;&gt;一、先分清鷹架、驗證器與護欄&lt;/h2&gt;
&lt;p&gt;談工程護欄時，最容易混在一起的，其實是三種不同功能的東西：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;鷹架 (scaffold)&lt;/strong&gt;：幫語言模型比較容易走在對的方向上。它提高做對的機率，減少誤解與偏航，但不能保證出錯時一定攔得住。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;驗證器 (verifier)&lt;/strong&gt;：回答「這份產出有沒有過關」的機制，例如測試、型別檢查、靜態分析器、形式驗證器。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;護欄 (guardrail)&lt;/strong&gt;：當語言模型做錯、做偏、做越界的事情時，能阻止它繼續往下走的機制。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;差別的關鍵，在於：&lt;strong&gt;檢查結果能不能改變系統的下一步。&lt;/strong&gt; 很多時候，護欄不是另一種神祕工具，而是把驗證器接進流程控制之後扮演的角色。測試如果只是存在於 repository 裡，它提供的是訊號；一旦接進 CI，成為合併或部署的阻斷條件，它才同時成為護欄。&lt;/p&gt;
&lt;p&gt;像 Design by Contract、Specification by Example、static analysis、property-based testing、sandbox、deployment gate、人工批准，放進來看都會更清楚：有些是在幫你對齊，有些在幫你檢查，有些則真的會把下一步擋下來。&lt;/p&gt;
&lt;p&gt;到了 LLM 時代，重要的不是把這些名字講得更完整，而是把重要約束盡量往可檢查、可判定、可阻斷的一端推。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;二spec-與架構原則在做什麼&#34;&gt;二、Spec 與架構原則在做什麼&lt;/h2&gt;
&lt;p&gt;Spec 和架構原則都能提供約束，但它們處理的不是同一件事。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://martinfowler.com/articles/exploring-gen-ai/sdd-3-tools.html&#34;&gt;Spec-driven development (SDD)&lt;/a&gt; 處理的是&lt;strong&gt;對齊&lt;/strong&gt;。它把需求、變更、設計、任務與實作串成同一條工作鏈，讓人和 AI 協作時，不必只靠聊天上下文去維持一致。較強版本的 SDD，會把 spec 提升成 source of truth，往下展開 plan、tasks，甚至進一步驅動 implementation。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; 較輕版本的 SDD，則是在 code 之前先固定一層持續存在的 spec，讓需求、變更與實作之間有穩定的承接點。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;它的價值不在於把文件寫得更厚，而在於後續實作、驗證與變更追蹤都能對著同一組座標工作。規格一旦能持續存在、被引用、被對照，後面的檢查就不是從零開始。這能減少上下文漂移，也能降低人和語言模型各講各話的機率。&lt;/p&gt;
&lt;p&gt;架構原則處理的，則是&lt;strong&gt;邊界&lt;/strong&gt;。它固定依賴方向、責任分配與模組之間的接觸方式，避免修改時一路穿透整個系統。&lt;/p&gt;
&lt;p&gt;像「domain 不應依賴 infrastructure」、「application service 不應直接碰 UI adapter」、「core module 不得 import vendor SDK」這類規則，如果只存在於設計文件、團隊默契或 code review comment 裡，主要仍是在幫人理解系統。把它們寫成依賴規則、匯入限制、architecture lint、架構測試與 CI 阻斷條件之後，邊界才真的固定下來。像 &lt;a href=&#34;https://www.archunit.org/&#34;&gt;ArchUnit&lt;/a&gt; 這類工具做的，就是把依賴方向、分層限制與循環依賴寫成可自動執行、一有違規就 fail 的規則。&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Spec 固定的是座標；架構原則固定的是邊界。兩者都很重要，但它們做的都還是同一類事：&lt;strong&gt;讓系統比較不容易歪掉。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;三真正握著-pass--fail-的是驗證器&#34;&gt;三、真正握著 pass / fail 的，是驗證器&lt;/h2&gt;
&lt;p&gt;到了產出這一層，真正決定過不過關的，通常還是型別系統、schema、assertions、static analysis、property-based testing、design by contract、formal verification 這類能給出硬性判定的機制。它們檢查某個性質成不成立；不成立，就直接給出 fail signal。接進自動化流程之後，也最容易變成真正的護欄。&lt;/p&gt;
&lt;p&gt;語言模型可以幫忙讀工具輸出、整理告警、推測可能原因，但還不適合坐在正式裁決者的位置上。近年的 benchmark 顯示，LLM 在某些程式語意推理任務上確實進步了；但碰到更深層、多步驟的靜態分析推理，表現仍然不穩。比較保守的工程結論是：現階段，語言模型可以協助 static analysis workflow，但還不能把它當成正式 static analyzer 的替代品。&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;至於 LLM-as-reviewer，比較適合放在&lt;strong&gt;初步快篩&lt;/strong&gt;的位置。它能幫忙擴大檢查面，例如指出明顯臭味、補測試點子、列出可能漏掉的邊界情況，或整理其他工具的輸出。最近也有研究指出，它能讓檢查更聚焦、更少幻覺。&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; 這些都有價值，但它的位置仍然是初步快篩，不是最後仲裁。&lt;/p&gt;
&lt;p&gt;不過這裡還有一層更容易被忽略的問題。驗證器的強度，不只要看用的是哪個框架，也得看規則是誰寫的。以 property-based testing 為例，如果 property 是人先定義好，再交給框架展開大量案例，它仍然是很強的驗證器；但如果連 property 都交給 LLM 自己發明，就會有球員兼裁判的問題：它測的到底是原本預期的行為，還是自己最容易實現的性質？上游若把 property 的定義權一併交出去，驗證強度就可能被偷換。&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;換到 property-based testing、design by contract 和 formal verification，也還是同一件事。語言模型可以協助補測試、補契約條件&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;、整理驗證器回饋、加速迭代修正；但最後握著裁決權的，仍然是 verifier。&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;四當-agent-能行動護欄就得前移&#34;&gt;四、當 agent 能行動，護欄就得前移&lt;/h2&gt;
&lt;p&gt;不過，事情一旦從「產出」走到「行動」，風險模型就變了。&lt;/p&gt;
&lt;p&gt;如果 agent 只會補全程式碼，失誤大多還停留在寫錯；如果 agent 還能讀寫檔案、改設定、跑腳本、觸發部署，甚至反覆自我修補，失誤就變成做錯事。前者主要看驗證，後者則要先看權限。&lt;/p&gt;
&lt;p&gt;所以，前面幾節談的那些編譯期、測試期、驗證期約束，到了這裡都還不夠。agent 一旦有了工具權限，真正重要的防線就會往前移到執行邊界本身。此時要管的，不只是它寫得對不對，而是它能不能碰、可以碰到哪裡、出了事是否留痕、哪一步需要停下來等人批准。&lt;/p&gt;
&lt;p&gt;這時真正重要的護欄，就是權限範圍控管、沙箱隔離、稽核記錄、速率限制、部署批准，以及其他執行期的限制條件。&lt;/p&gt;
&lt;p&gt;Agent 一旦從「生成建議」走到「執行動作」，問題就不再只是怎麼驗證產出，而是：&lt;strong&gt;哪些限制必須在它動手之前就先寫硬。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;五哪些規矩值得寫硬&#34;&gt;五、哪些規矩值得寫硬&lt;/h2&gt;
&lt;p&gt;到了這裡，問題已經不是要不要再多一些原則，而是：&lt;strong&gt;哪些限制如果不寫硬，代價會高到不能接受。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;判斷這件事，我會先看四個面向：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;錯誤代價&lt;/strong&gt;：出錯的成本高不高。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行動權限&lt;/strong&gt;：agent 的行為會不會直接改變外部世界。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;審計需求&lt;/strong&gt;：事後需不需要清楚追溯，誰在什麼條件下放行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一致性成本&lt;/strong&gt;：這條規矩如果只靠默契，能不能跨人員、跨時間穩定維持。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這四個維度上的壓力越大，這條規矩就越不適合只留在文件、會議紀錄或 code review comment 裡，越應該被翻成測試、schema、lint rule、approval gate 或權限控制。&lt;/p&gt;
&lt;p&gt;反過來說，如果錯誤代價低、行動權限小、審計需求弱，而且團隊本來就能穩定維持一致，那它可能就不需要被工具鏈執法。留在慣例、review 或較弱的規格層，很多時候就夠了。&lt;/p&gt;
&lt;p&gt;所以，真正要問的不是規矩能不能寫硬，而是：&lt;strong&gt;它值不值得被寫硬。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這裡還是要小心另一個問題。當規矩大量轉成可由機器裁決的限制，很容易出現新的激勵錯置：大家開始為了過關而寫測試，為了通過檢查而補 schema，最後得到的未必是更好的工程品質，而可能只是更僵硬的流程。&lt;/p&gt;
&lt;p&gt;護欄不是越多越好。好的護欄，是把高代價風險卡住，同時不要把系統變成只會通關的官僚機器。&lt;/p&gt;
&lt;h2 id=&#34;結論&#34;&gt;結論&lt;/h2&gt;
&lt;p&gt;所以真正要問的，往往不是這條規矩寫了沒有，而是當它出了事，有沒有機制真的在監工。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;關於大語言模型 nondeterministic 的問題，詳見〈&lt;a href=&#34;//william-yeh.net/post/2026/03/genai-se-level-up/&#34;&gt;AI 會寫程式之後，軟體工程真正變貴的是什麼&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;本文主張：對 LLM 而言，穩定的約束力主要來自外部、可機器檢查、且可嵌入流程阻斷的機制，而不是語言模型是否「理解規矩」。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;參考 &lt;a href=&#34;https://github.com/github/spec-kit&#34;&gt;Spec Kit&lt;/a&gt; 對 Spec-Driven Development 的自我定義與 workflow 說明：specification 不再只是 scaffolding，而是變成 executable source，能沿著 constitution → specification → planning → tasks → implementation 的鏈條依序往下執行。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;參考 &lt;a href=&#34;https://github.com/Fission-AI/OpenSpec&#34;&gt;OpenSpec&lt;/a&gt; 的 README、concepts 與 getting started 文件：OpenSpec 強調 &lt;em&gt;fluid not rigid&lt;/em&gt;、&lt;em&gt;iterative not waterfall&lt;/em&gt;，以 &lt;code&gt;specs/&lt;/code&gt; 作為 current behavior 的 source of truth，以 &lt;code&gt;changes/&lt;/code&gt; 保存每次 change 的 &lt;code&gt;proposal.md&lt;/code&gt;、delta specs、&lt;code&gt;design.md&lt;/code&gt;、&lt;code&gt;tasks.md&lt;/code&gt;，並沿著 proposal → specs → design → tasks → implement 的順序推進。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;根據 &lt;a href=&#34;https://www.archunit.org/&#34;&gt;ArchUnit&lt;/a&gt; 官方使用手冊的說法，ArchUnit 可檢查 package/class 依賴、layer、slice 與循環依賴，並以一般 Java 單元測試框架自動執行 architecture 與 coding rules。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://arxiv.org/abs/2507.05269&#34;&gt;CoRe benchmark&lt;/a&gt; 專門評估 LLM 在靜態分析型程式語意推理上的能力；結果顯示，模型雖能處理部分任務，但在更深層、多步驟的語意推理上仍有明顯限制。本文據此採取較保守的工程判斷：現階段不宜把 LLM 視為正式 static analyzer 的替代品。&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://arxiv.org/abs/2512.17540&#34;&gt;SGCR (specification-grounded code review)&lt;/a&gt; 的核心主張是把 code review 建立在明確、人工撰寫的規格上，以提升回饋的相關性與可信度；這支持較保守的結論：spec-grounded review 值得投入，但現階段更適合放在初步快篩，而非最後仲裁者的位置。&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;許多由 LLM 產生的測試程式，常常有球員兼裁判的問題。最明顯的例子，就是濫用 mock 湊出綠燈通過的假象。因此，在 &amp;ldquo;&lt;a href=&#34;https://arxiv.org/abs/2506.18315v1&#34;&gt;Use Property-Based Testing to Bridge LLM Code Generation and Validation&lt;/a&gt;&amp;rdquo; 這份研究中，也承認由 LLM 產生 property，是他們這份研究的弱點之一。&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;&amp;ldquo;&lt;a href=&#34;https://arxiv.org/abs/2510.12702&#34;&gt;Beyond Postconditions&lt;/a&gt;&amp;rdquo; 這篇研究關注的是：LLM 能不能從程式或既有規格中推導出可供自動驗證使用的 formal contracts，而且範圍不只限於傳統 postconditions。它的價值在於「協助起草與補全契約條件」：能幫忙加快 formal specification 的建構，但不等於模型已經可以取代 verifier 來正式裁決。&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://arxiv.org/abs/2509.22908&#34;&gt;Vericoding benchmark&lt;/a&gt; 與 Faria 等人的 &lt;a href=&#34;https://arxiv.org/abs/2601.12845&#34;&gt;Dafny annotation&lt;/a&gt; 研究都支持同一件事：當流程採用「生成 → verifier 檢查 → 回饋 → 再生成」時，真正掌握裁決權的仍是驗證器 (verifier)，而不是語言模型本身。&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>當 Agile 遇見 AI：變與不變</title>
      <link>//william-yeh.net/post/2026/03/genai-revisit-scrum/</link>
      <pubDate>Wed, 25 Mar 2026 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2026/03/genai-revisit-scrum/</guid>
      
        <description>&lt;p&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;Scrum Guide&lt;/a&gt; 問世至今已經超過 15 年。到了 GenAI 與 coding agents 時代，Scrum 算不算過時？&lt;/p&gt;
&lt;p&gt;我覺得，這個問題不能只用「過不過時」來看。真正值得看的是：當 AI 已經能查 repo、寫 ticket、開 PR、跑測試之後，Agile 裡哪些工作真的被改寫了，哪些其實沒有。&lt;/p&gt;
&lt;p&gt;現在很多團隊碰到的情況，不是工作自動做完了，而是塞車的位置換了。&lt;/p&gt;
&lt;p&gt;你讓 agent 跑了一整晚。隔天早上，GitHub 上可能已經躺著幾個待 review 的 PR、兩三種看起來都說得通的重構方向、一些測試全綠燈卻仍讓人隱隱不安的修改，外加幾個碰了系統邊界卻未必自知的變更。 OpenClaw（龍蝦）作者 Peter Steinberger 也提過，自己曾讓系統跑上數小時，甚至隔夜處理重構；他甚至認為 “prompt requests” 也會變成新的日常。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這裡真正變快的，是程式碼產出。沒有一起變快的，則是審查、驗收、風險辨識、責任承擔和後續決策。表面上看起來像是寫得更快，實際上常常只是把瓶頸往後推。&lt;/p&gt;
&lt;p&gt;瓶頸既然換了位置，接下來要重看的，就不只是 Scrum 還在不在，而是整個協作方式要怎麼調整。譬如說，很多原本得靠人類口頭交換的內容，現在可以先由機器整理、摘要、比對、補齊，甚至先展開幾種可能方案。&lt;/p&gt;
&lt;p&gt;很多人在正式會議前，本來就會先和 AI 討論，再把整理過的結論帶進會議。既然這件事早就在發生，那差別往往只剩下：團隊要不要正式承認它。說穿了，就是要不要把那隻早就在場外跑著的龍蝦，正式接進協作流程裡。&lt;/p&gt;
&lt;p&gt;我甚至還有個瘋狂的想法。何不開一個視窗，接上麥克風與喇叭，邀請這位 AI 本尊直接進來會議現場，說不定反而更有效率，也更有火花呢。&lt;/p&gt;
&lt;p&gt;還有哪些需要調整的呢？&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/03/genai-revisit-scrum.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/03/genai-revisit-scrum.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;先變薄的部分&#34;&gt;先變薄的部分&lt;/h2&gt;
&lt;h3 id=&#34;daily-scrum從同步到排除障礙&#34;&gt;Daily Scrum：從同步到排除障礙&lt;/h3&gt;
&lt;p&gt;Daily 最容易先變形，因為它最常被實作成站會、報進度、同步阻礙。若 AI 已經能自動整理昨天的 commit、ticket 狀態、PR 變化、CI 結果、風險訊號與依賴狀況，很多原本要靠人輪流講一遍的資訊，自然可以退出例行會議。&lt;/p&gt;
&lt;p&gt;Daily 之後會更像一個更窄、更直接的介面。平時以非同步更新為主，必要時再同步排除障礙與重新對焦 Sprint Goal。它還是有用，只是用途會收斂得更清楚。&lt;/p&gt;
&lt;h3 id=&#34;planning--refinementagent-會先進來&#34;&gt;Planning / Refinement：agent 會先進來&lt;/h3&gt;
&lt;p&gt;Planning 和 Refinement 會很早被改寫，因為這兩個環節本來就有大量前期整理與方案展開的工作。&lt;/p&gt;
&lt;p&gt;Agent 可以先整理 repo 現況、歷史 issue、相依模組、潛在技術債、風險、限制條件與驗收線索，也可以先把問題空間攤開：列出幾種可能方向、補上 edge cases、模擬不同 stakeholder 的質疑，或把一句模糊需求推成幾版可比較的 backlog candidates。&lt;/p&gt;
&lt;p&gt;這會直接改變會議本身的重心。以前團隊常常花很多時間把資料湊齊、把可能性從零展開；現在更可能直接從幾個已經展開的選項開始討論。AI 在這裡的價值，不只是幫忙整理答案，而是先把問題空間、方案空間和限制空間攤到桌上。&lt;/p&gt;
&lt;p&gt;但這也立刻放大 artifact 品質的問題。若 backlog item 寫得模糊、驗收條件不清、優先順序背後沒有說明清楚的價值假設，agent 只會更快放大原有的模糊。AI 可以幫忙展開選項，卻不能替代產品與工程團隊對於「為什麼現在做、做到哪裡算足夠、哪種風險不能接受」的共同判斷。&lt;/p&gt;
&lt;p&gt;所以到了 AI 時代，Planning / Refinement 的價值不會縮水，只是重心會往前移。人不再主要負責把資料從零湊齊，而是負責設邊界、做取捨、定優先順序。&lt;/p&gt;
&lt;h3 id=&#34;review準備工作能外包判斷不能&#34;&gt;Review：準備工作能外包，判斷不能&lt;/h3&gt;
&lt;p&gt;Review 很適合由 agent 深度前置支援。它可以先整理 demo 重點、摘要變更、用數據展示品質趨勢、風險列表，甚至預測 stakeholder 可能會問什麼。&lt;/p&gt;
&lt;p&gt;但 Review 的核心工作還是看完成果之後，團隊要不要調整後續方向。資訊展示可以大幅前置自動化；價值判斷、取捨與 adaptation 仍然要由人承擔。&lt;/p&gt;
&lt;h3 id=&#34;sprint-本身時間盒會重估&#34;&gt;Sprint 本身：時間盒會重估&lt;/h3&gt;
&lt;p&gt;AI 明顯壓縮了實作與局部驗證時間，如果 Sprint 仍然固定在兩週或更長的週期，當然會開始顯得肥厚。某些團隊會把 Sprint 縮短，自動化程度高、跨團隊依賴程度低的團隊，甚至可能轉向更接近 Kanban 那種持續流動的節奏。&lt;/p&gt;
&lt;p&gt;接下來要重新看的，是什麼節奏最適合吸收風險、整合回饋、維持責任鏈。在高合規、高風險、跨職能協作密集的環境裡，時間盒仍然可能很有用；只是到了 AI 時代，它不必再理所當然地綁定某一個固定長度。&lt;/p&gt;
&lt;h2 id=&#34;反而變更硬的部分&#34;&gt;反而變更硬的部分&lt;/h2&gt;
&lt;h3 id=&#34;retrospective更重要也更脆弱&#34;&gt;Retrospective：更重要，也更脆弱&lt;/h3&gt;
&lt;p&gt;如果說 Daily、Planning、Refinement、Review 有些部分會被 AI 削薄，那麼 Retrospective 則可能會往另一個方向走：它會變得更重要。&lt;/p&gt;
&lt;p&gt;Retro 處理的是團隊診斷、坦白與集體學習。這裡最關鍵的東西不是效率，而是心理安全、信任，以及組織能不能把一次失敗轉成下一輪行動。&lt;/p&gt;
&lt;p&gt;同樣一句話「這次卡住，其實是因為我不敢太早提反對意見」，在純人類的 retro 裡，也許有人會講；但如果現場多了一個在記錄、歸因、評估，甚至長期留痕的 agent，這句話就很可能消失。不是因為 AI 一定會懲罰誰，而是因為人會重新計算：這句話說出去之後，會怎麼被理解、保存、引用或放大。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;所以，如果 retrospective 還要有診斷價值，團隊就得很清楚地界定 AI 在裡面的角色。它可以幫忙整理議題、歸納模式、追蹤 action items；但只要它強化了監看感、記錄感或績效聯想，retro 最有價值的那部分就會先破壞掉。&lt;/p&gt;
&lt;h3 id=&#34;artifacts要給人也要給機器用&#34;&gt;Artifacts：要給人，也要給機器用&lt;/h3&gt;
&lt;p&gt;比起只盯著 Scrum 的 events，我更在意另一件事：artifacts 在 AI 時代會比以前更重要，而且得重寫。&lt;/p&gt;
&lt;p&gt;Scrum Guide 一直強調 artifacts 的角色，是讓工作與價值具備透明性。Agent 普遍介入之後，artifact 不再只是給人看的共識載體，也會變成人機協作的介面。Backlog item、acceptance criteria、Definition of Done、測試規格、architecture decision record、runbook、incident template——這些文件如果還只是寫到「人類大概懂」，對 agent 來說通常就不夠。&lt;/p&gt;
&lt;p&gt;AI 時代，好的 artifacts 通常得同時滿足三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;讓人能理解為什麼要做。&lt;/li&gt;
&lt;li&gt;讓機器能可靠地執行或協助執行。&lt;/li&gt;
&lt;li&gt;讓責任可以在事後被追溯。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Artifacts 精度直接決定產出品質，因此，很多過去被嫌文件太笨重的東西，之後可能會以另一種形式回歸。&lt;/p&gt;
&lt;p&gt;這裡說的回歸，指的是另一類 artifacts：輕量、可持續修訂、直接服務於協作、生成、驗收與追溯。它們會跟著 sprint 推進而演化，會貼著程式碼、測試、部署與實際決策一起更新，也會持續接受回饋修正。這種文件更像高精度介面，負責讓人與 agent 在同一組邊界條件下工作。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;Agile Manifesto&lt;/a&gt; 裡那句 &lt;em&gt;working software over comprehensive documentation&lt;/em&gt;，放到今天依然成立。關鍵不在於文件多或少，而在於它有沒有直接服務於 working software。只要文件仍然貼近交付、能被持續修訂、能幫助團隊更快收斂到可驗收的結果，它就還在敏捷的精神之內。&lt;/p&gt;
&lt;p&gt;從傳統產品實務看，這其實並不陌生。很多團隊早就會用 &lt;a href=&#34;https://xp123.com/invest-in-good-stories-and-smart-tasks/&#34;&gt;INVEST&lt;/a&gt; 來檢查 user story 是否至少夠獨立、可協商、有價值、可估、夠小且可驗證。這些要求在 AI 時代沒有失效，反而更像最低門檻。差別在於：過去一則 story 只要寫到讓人類團隊大致能接手，常常就能往下做；現在若連 agent 都要參與展開、拆分、測試與實作準備，那 backlog 就得再往前一步，寫到目標、非目標、限制條件、驗收方法與 sign-off 都足夠明確。&lt;/p&gt;
&lt;p&gt;舉個最簡單的例子。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;壞寫法：&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;作為使用者，我希望登入更快。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這句對 PM 或工程師也許還能繼續聊，但對 agent 來說，邊界幾乎是空的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;好寫法：&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;目標&lt;/strong&gt;：將登入頁可互動時間降低 30%。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;非目標&lt;/strong&gt;：不改動身份驗證供應商。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;限制&lt;/strong&gt;：不得影響現有風控規則。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;驗收&lt;/strong&gt;：iOS 與 Web 端在指定設備與網路條件下達成 X 指標；由產品經理與前端負責人共同 sign-off。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同樣是一個 backlog item，後者才提供了真正可用的人機介面：目標是什麼、邊界在哪裡、什麼算完成、誰負責最後收件。寫得夠清楚，AI 才幫得上忙，幫忙拆工作、產生測試、準備 PR。&lt;/p&gt;
&lt;h3 id=&#34;責任鏈與工程護欄生成越快越要卡住&#34;&gt;責任鏈與工程護欄：生成越快，越要卡住&lt;/h3&gt;
&lt;p&gt;不少人對 AI 的第一直覺，是既然寫程式變便宜，那很多流程大概都能省掉。這種想像只對了一半。&lt;/p&gt;
&lt;p&gt;AI 的確讓某些執行工作變便宜了，但它完全沒有削弱 accountability。事情如果上線出錯，最後還是得有人承擔；需求如果方向錯了，還是得有人為取捨負責；安全性、法遵、效能和使用者體驗，也不會因為程式碼是 agent 幫忙寫的，就自動退到後面。&lt;/p&gt;
&lt;p&gt;接下來真正要被重構的，是整條責任鏈：誰定義任務、誰設邊界、誰接收產出、誰有權否決、誰來為結果簽名。這些問題沒先講清楚，只把 agent 接進流程，最後通常不會更敏捷，只會更快地製造混亂。&lt;/p&gt;
&lt;p&gt;工程護欄也會一起變硬。程式碼生成量一旦上來，不可能靠線性增加人工 review、每個人更辛苦地看更多東西來搞定。最後撐得住的，是那些能把品質判斷前移、自動化、制度化的做法：持續整合、快速測試、明確的 Definition of Done、嚴格的 code review gate、穩定的 observability、必要時的 evals，以及對產線風險有感知的 release discipline。&lt;/p&gt;
&lt;p&gt;從這個角度看，XP 裡那些常被嫌麻煩、嫌慢、嫌太講究的實踐，在 AI 時代反而更像必要基礎設施。原因不在於它們很傳統，而在於它們能承接高速生成之後帶來的品質壓力。 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;別把判斷力一起外包&#34;&gt;別把判斷力一起外包&lt;/h2&gt;
&lt;p&gt;AI 的介入，還引出另一個更根本的問題：當執行越來越便宜，我們怎麼避免把判斷力一起外包出去。&lt;/p&gt;
&lt;p&gt;這裡說的判斷力，不是抽象的道德說教，而是幾種很具體的能力：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;看出哪裡不對勁的能力。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在多個看起來都合理的方案裡做取捨的能力。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;在壓力下願意為結果簽名負責的能力。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果一個團隊長期把 AI 當成「先幫我做完，我再大致看一下」的工具，被侵蝕的往往不只是「寫程式」這一項技能，而是對錯誤的敏感度、對邊界的感知、對系統後果的直覺，以及在不完整資訊下做判斷的肌肉。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;更麻煩的是，這件事未必會以很戲劇化的方式發生。多數時候，它不是讓人突然完全不會做，而是讓人慢慢失去深入理解的動機。表面上每件事都做得更快，實際上團隊可能越來越依賴一套自己不完全理解、也不太知道怎麼挑戰的生成流程。最後留下來的，不是高效，而是脆弱。&lt;/p&gt;
&lt;p&gt;所以我不太接受那種把 AI 對團隊的影響簡化成「速度提升」的說法。速度當然重要。真正決定團隊長期能力的，還是判斷、責任與學習能不能一起跟上。&lt;/p&gt;
&lt;h2 id=&#34;結語agile-沒有過時介面在變&#34;&gt;結語：Agile 沒有過時，介面在變&lt;/h2&gt;
&lt;p&gt;Scrum 未必過時。現在鬆動的，是建立在人類同步成本上的那一層介面。&lt;/p&gt;
&lt;p&gt;接下來要進一步重構的，是人、機器與責任之間的介面。&lt;/p&gt;
&lt;p&gt;流程會被改寫，但判斷、責任和學習不會消失，只會加重。&lt;/p&gt;
&lt;hr&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;OpenClaw 作者 Peter Steinberger 在接受 &lt;a href=&#34;https://lexfridman.com/peter-steinberger/&#34;&gt;Lex Fridman Podcast #491&lt;/a&gt; 訪談時提到，讓系統處理重構，可能會跑上數小時，甚至隔夜，也提到 review pull request，甚至 “prompt request” 會變成他日常工作的一部分。這很適合拿來說明：當 agent 讓產出暴增時，人類瓶頸常常會被推向 review 與判斷。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;這裡的推論應該寫得保守一點。&lt;a href=&#34;https://www.jstor.org/stable/2666999?origin=JSTOR-pdf&#34;&gt;Edmondson (1999)&lt;/a&gt; 與 &lt;a href=&#34;https://rework.withgoogle.com/intl/en/guides/understanding-team-effectiveness&#34;&gt;Google re:Work&lt;/a&gt; 所談的心理安全，確實都支持「人要在團隊裡敢說真話，必須感到不會因提出疑問、異議或錯誤而受到懲罰」這件事。&lt;a href=&#34;https://partnershiponai.org/psychological-safety-in-the-ai-workplace-with-the-apa/&#34;&gt;Partnership on AI&lt;/a&gt; 與 &lt;a href=&#34;https://www.apa.org/pubs/reports/work-in-america/2024/psychological-safety&#34;&gt;APA&lt;/a&gt; 的材料也指出，當 AI 被用來強化監看、侵入隱私，或讓人感到自己正被持續觀察時，心理安全可能受損。&lt;a href=&#34;https://www.frontiersin.org/journals/behavioral-economics/articles/10.3389/frbhe.2025.1647057/full&#34;&gt;Dorner 與 Fellner-Röhling (2025)&lt;/a&gt; 的研究則更直接涉及信任與自動化控制，而不是 retro 場景本身。把這些材料放進 retrospective 的脈絡，只能支撐一個較保守的判斷：&lt;strong&gt;一旦 retro 帶出強烈的監看感、記錄感或評價感，團隊的坦白程度很可能下降。&lt;/strong&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;請參考我在〈&lt;a href=&#34;//william-yeh.net/post/2026/03/genai-se-level-up/&#34;&gt;AI 會寫程式之後，軟體工程真正變貴的是什麼&lt;/a&gt;〉一文做的探討。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;這裡我同樣刻意寫得保守。關於 AI 是否會侵蝕學習與理解，Anthropic 2026 年的一項研究 “&lt;a href=&#34;https://www.anthropic.com/research/AI-assistance-coding-skills&#34;&gt;How AI Assistance Impacts the Formation of Coding Skills&lt;/a&gt;” 發現，接受 AI 協助的學習者，在剛做過的概念測驗上分數較低；但長期的 deskilling 與組織後果，目前仍缺少更長時間尺度的直接證據。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>LLM 時代，傳統軟體架構該重新檢查了</title>
      <link>//william-yeh.net/post/2026/03/genai-revisit-arch/</link>
      <pubDate>Sat, 21 Mar 2026 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2026/03/genai-revisit-arch/</guid>
      
        <description>&lt;p&gt;&lt;a href=&#34;https://github.com/openclaw/openclaw&#34;&gt;OpenClaw&lt;/a&gt; 作者 Peter Steinberger 接受 36Kr Europe 訪談時提到，多數程式碼其實很無聊，很多時候做的只是把一種資料形狀轉成另一種。這不是他真正關心的事。 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這句話有點刺耳，但也把一件事講得很坦白：很多工程安排用久了，就會從成本與取捨，慢慢變成預設，變成僵化的教條，沒有人過問它是否還有價值。&lt;/p&gt;
&lt;p&gt;現在 LLM 與 coding agent 已經開始直接參與 repo 級搜尋、修改與驗證。很多原本被視為理所當然的做法，也該再檢查一次。分層是不是還在隔離風險，抽象是不是還在縮小修改半徑，某些 interface、mapper 和轉發層，到底在承擔工作，還是只是在延續習慣。&lt;/p&gt;
&lt;p&gt;以前這些東西就算有點多、有點繞，通常也還撐得過去。工程師會靠經驗補上下文，靠默契避開麻煩，再把額外成本默默吞下來。&lt;/p&gt;
&lt;p&gt;但 agent 介入之後，很多原本人類可以硬撐過去的地方，會直接變成搜尋成本、理解成本，最後讓修改失去準頭。&lt;/p&gt;
&lt;p&gt;這篇想處理的問題很直接：今天系統裡哪些結構還在管理複雜性，哪些只是在維持形式？&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/03/genai-revisit-arch.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/03/genai-revisit-arch.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;一先把問題拆開&#34;&gt;一、先把問題拆開&lt;/h2&gt;
&lt;p&gt;很多關於「LLM 會不會淘汰傳統架構」的討論，常常一開始就把不同層次的東西攪在一起。clean architecture、hexagonal architecture、DDD、DI、repository pattern、DTO、adapter、use case、presenter，通通被包成同一團：要嘛一起捍衛，要嘛一起否定。&lt;/p&gt;
&lt;p&gt;這樣談，很容易失焦。&lt;/p&gt;
&lt;p&gt;至少有三個層次，應該先拆開。&lt;/p&gt;
&lt;p&gt;第一層是&lt;strong&gt;架構原則&lt;/strong&gt;。依賴方向要受控制，核心規則要和外部機制分開，重要邊界要清楚，關鍵規則要能被測試。當年 Uncle Bob 談 clean architecture，核心是 dependency rule&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;；Alistair Cockburn 談 hexagonal architecture，重點是 inside 與 outside 的不對稱&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;；DDD 裡的 bounded context，關心的則是模型適用的邊界，以及語言一致性應該維持到什麼範圍。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;第二層是&lt;strong&gt;工程樣板&lt;/strong&gt;。DTO、adapter、repository interface、output port、presenter、mapper，都屬於這一層。它們不是原則本身，而是某些團隊在特定條件下慣用的一組工程安排。Martin Fowler 當初談 dependency injection (DI)，重點放在 configuration 與 use 的分離；不是要你替每個類別都先鋪好抽象層。&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;第三層是&lt;strong&gt;治理需求&lt;/strong&gt;。這一層真正關心的，不是你有幾個資料夾、幾個介面，而是系統怎麼控制依賴、分配責任、限制變更外溢，並在長期演化中把語意與成本都維持在可控範圍內。&lt;/p&gt;
&lt;p&gt;這個拆法很重要。很多團隊死守的，其實不是第一層的原則，而是第二層那整套早已模板化的工程安排。手段用久了，會慢慢被當成信仰；原本該被追問的東西，也就變成預設。&lt;/p&gt;
&lt;p&gt;所以今天要做的，不是宣布第二層全部過時，也不是替任何一派背書，而是把它放回可被檢查的位置：&lt;strong&gt;這個樣板，現在到底在做什麼工作？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;它有沒有縮小修改範圍？有沒有讓規則與副作用的邊界更清楚？有沒有改善測試、型別檢查、替換成本，或跨 context 的語意翻譯？&lt;/p&gt;
&lt;p&gt;答不出來，它就比較像儀式。答得出來，它就是在承擔治理任務。&lt;/p&gt;
&lt;p&gt;很多爭論之所以一直失焦，不是因為立場差太遠，而是這三層太常混在一起談。&lt;/p&gt;
&lt;h2 id=&#34;二先問它在保護什麼&#34;&gt;二、先問它在保護什麼&lt;/h2&gt;
&lt;p&gt;人們常說「傳統架構過於虛胖，會被 LLM 淘汰」，但如果去看主流 enterprise 平台的官方文件，其實很少有人真的主張把那些模式全面鋪滿。&lt;/p&gt;
&lt;p&gt;沒有人認真說過：所有系統都應該全面採用 clean architecture、DDD 或 CQRS。更沒有人說：你應該一開始就把 repository、port、presenter、mapper 全部鋪好，再來寫功能。&lt;/p&gt;
&lt;p&gt;主流平台的說法，反而一直都比某些工程圈子務實。&lt;/p&gt;
&lt;p&gt;Microsoft 在 .NET microservices 文件裡談 DDD 與 CQRS 時講得很清楚：這些模式主要適合複雜商業規則、複雜子系統與高演化壓力的情境，而不是所有服務的預設配置。&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; 在更細的 persistence layer 文件裡，它甚至直接寫明：對許多 CRUD 型微服務來說，直接使用 EF &lt;code&gt;DbContext&lt;/code&gt; 往往就是最簡單的做法；自訂 repository 的價值，則主要出現在需要解耦、模擬資料存取或提升測試隔離的較複雜情境。&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; Azure Architecture Center 對 CQRS 的態度也差不多：讀寫負載不對稱、效能與安全要求不同，或流程本身較複雜時，CQRS 有它的價值；但在基本 CRUD、簡單領域模型或 CRUD 式 UI 的情境下，就未必合適。&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;AWS 對 anti-corruption layer 的說法也很直接。它不是讓系統「看起來比較有架構」，而是拿來翻譯不同系統之間的 domain semantics，避免上游 bounded context 的概念直接污染下游。尤其當遺留系統不可改、上下游語義不同，或不同團隊無法同步調整時，這類結構承擔的是整合風險與業務中斷風險。&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這幾份文件其實都在說同一件事：企業軟體架構的正當性，不來自名詞，而來自它是否真的在承擔治理任務。你為抽象與分層付出的成本，到底有沒有換到對應的治理能力。&lt;/p&gt;
&lt;p&gt;這裡說的治理，不只是風險控制，也包括廣義的策略對齊、營運成本、效能壓力、跨團隊責任分配，以及系統在長期演化時的健康程度。&lt;/p&gt;
&lt;p&gt;所以要問的從來不是「要不要架構」，而是：&lt;strong&gt;這個架構到底在保護什麼。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一個只有單表 CRUD 的微服務，如果 repository、port、presenter、mapper 層層硬塞上去，最後真正穩定不變的，很可能只是樣板，不是邊界。&lt;/p&gt;
&lt;p&gt;反過來說，一個真的需要隔離外部系統語意、控制商業規則演化、或讓多團隊協作互不污染的系統，那些結構就可能真的在做事。&lt;/p&gt;
&lt;p&gt;差別不在名字，而在它有沒有承擔工作。&lt;/p&gt;
&lt;h2 id=&#34;三repo-也需要重新檢查&#34;&gt;三、repo 也需要重新檢查&lt;/h2&gt;
&lt;p&gt;大型系統反覆觸礁的，還是那幾個老問題：依賴控制、變更隔離、測試支撐、替換成本、跨團隊協作、責任歸屬，以及語意邊界的維護。&lt;/p&gt;
&lt;p&gt;這些問題不會因為 LLM 變強就自動消失。但 LLM 的確改變了這些結構被檢查、被使用的方式，也改變了人們質疑它們的理由。&lt;/p&gt;
&lt;p&gt;過去，軟體架構主要是在服務人類開發者：讓人看得懂、改得動、測得出、交接得了。現在在 LLM 時代，還多了 coding agent 參與，甚至可能同時有多個 agent。既有的 repo 結構，是否也能好好服務這些 agent？它是否足夠清楚，讓工具能穩定定位、導航、修改與驗證？&lt;/p&gt;
&lt;p&gt;近年已經有一些 repository-level benchmark 提供線索。這裡要先分清楚：哪些是 benchmark 直接告訴我們的，哪些只是根據結果提出的合理推論。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SWE-bench&lt;/strong&gt; 關注的是：LLM 能不能在真實的開源 repo 裡，根據 issue 描述，自動找到相關程式碼、做出修改，最後通過測試。這篇研究當時發現，最佳商業語言模型也只能解掉 1.96%，搭配較好的搜尋策略後，表現才提升到 4.8%。&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;後來的 &lt;strong&gt;SWE-bench Pro&lt;/strong&gt; 難度更高，任務設計也更接近企業中需橫跨數日、長時程處理 issue 的情境。論文分析顯示，任務複雜度、檔案數量與脈絡線索等因素，甚至連程式語言都會影響效果。&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RepoBench&lt;/strong&gt; 則把 repository-level 能力拆得更細。它不是直接模擬解 issue，而是把能力拆成 retrieval、completion 與 pipeline 三部分，觀察語言模型能不能在跨檔案、跨模組的情境下，先找到真正相關的片段，再補出合理的後續程式。它提供的重要線索是：跨檔案脈絡的供給，確實有助於提升表現。&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;把這些材料放在一起，還不足以得出「某一派架構已被證明普遍勝出」的結論。眼前比較站得住腳的說法，反而更樸素：repo 級工作的難點，高度集中在&lt;strong&gt;定位、檢索、跨檔案關聯與驗證&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;凡是能讓相關脈絡更容易被命中、讓修改範圍更容易收斂、讓驗證點更早浮現的結構，就更值得留下。&lt;/p&gt;
&lt;p&gt;所以問題不是「LLM 要不要架構」，而是：什麼樣的結構，能讓人與 agent 都更容易動手，而且不容易把系統改壞。&lt;/p&gt;
&lt;h2 id=&#34;四先看好不好動手&#34;&gt;四、先看好不好動手&lt;/h2&gt;
&lt;h3 id=&#34;不要先看流派&#34;&gt;不要先看流派&lt;/h3&gt;
&lt;p&gt;如果前一節的判斷成立，那接下來更值得處理的，就不是哪一派在理念上更完整，而是更務實地看：在真實 repo 裡，哪一種結構能用更少的間接層，換來更高的可定位性、可修改性與可驗證性。&lt;/p&gt;
&lt;p&gt;把抽象名詞先拿掉。真正會拖慢人與 agent 的，通常是幾件很具體的事：改一條規則時，要穿過幾層；找那條規則時，要繞多少地方；改完之後，又能不能立刻知道該驗證哪裡。&lt;/p&gt;
&lt;p&gt;至少可以看四個判準。&lt;/p&gt;
&lt;p&gt;第一，是&lt;strong&gt;修改半徑&lt;/strong&gt;，但最好拆成兩半看。&lt;/p&gt;
&lt;p&gt;一個是&lt;strong&gt;耦合半徑&lt;/strong&gt;：為了完成一個需求，實際必須修改多少檔案、多少模組、多少層。這主要是架構問題。&lt;/p&gt;
&lt;p&gt;另一個是&lt;strong&gt;發現半徑&lt;/strong&gt;：人類或 agent 需要先走過多少地方，才知道真正該改哪裡。這往往牽涉到命名、目錄、型別、測試入口、工具提示與文件表達。&lt;/p&gt;
&lt;p&gt;這兩件事很容易被混在一起，也就很容易誤判。系統如果耦合過深，該做的是重整依賴關係與責任分配；系統如果本來切分得還可以，只是訊號太亂，那麼該優先處理的，反而是命名、測試入口、型別邊界與機器可讀的規則。&lt;/p&gt;
&lt;p&gt;第二，是&lt;strong&gt;副作用邊界是否清楚&lt;/strong&gt;。哪些地方在做純規則運算，哪些地方在碰資料庫、檔案系統、網路等外部依賴，哪些地方涉及時間、併發與平行處理，是否一眼就看得出來？&lt;/p&gt;
&lt;p&gt;第三，是&lt;strong&gt;局部驗證是否容易&lt;/strong&gt;。改完一段規則後，能不能快速知道該跑哪些測試、哪些靜態檢查、哪些整合路徑？&lt;/p&gt;
&lt;p&gt;第四，是&lt;strong&gt;控制流與資料流是否可追蹤&lt;/strong&gt;。如果流程被拆成一長串介面轉發、隱式注入，或分散在太多抽象層裡，再整齊的分層，也不一定比較好動手。&lt;/p&gt;
&lt;p&gt;舉個簡單的例子。同樣是改一條商業規則，有的系統要層層穿越 controller、use case、output port、presenter、mapper、repository，才碰得到真正的規則；有的系統則能在同一個 feature 目錄下，直接定位到核心邏輯、測試與副作用出口。問題不在誰比較正統，而在誰的修改半徑、發現半徑與驗證成本更低。&lt;/p&gt;
&lt;p&gt;要先看判準，再看流派。&lt;/p&gt;
&lt;p&gt;Vlad Khononov 在 &lt;em&gt;Balancing Coupling in Software Design&lt;/em&gt; &lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt; 提出的平衡耦合模型，也很適合拿來對照。他把耦合性展開成&lt;strong&gt;整合強度&lt;/strong&gt;、&lt;strong&gt;距離&lt;/strong&gt;、&lt;strong&gt;變動性&lt;/strong&gt;三個維度。把這套模型外推到 agent 場景，看的其實也是幾件事：某個結構有沒有降低跨邊界的共享知識，減少真正需要同時理解的知識量；有沒有縮短找到正確修改點與驗證點的距離；有沒有把高耦合留在較低變動、相對穩定的區域，而不是和高變動區域綁在一起。&lt;/p&gt;
&lt;p&gt;如果答不出來，那些抽象就很可能只是把形式堆得更整齊，沒有讓系統更容易演化。&lt;/p&gt;
&lt;h3 id=&#34;還得看看-agent-守不守得住&#34;&gt;還得看看 agent 守不守得住&lt;/h3&gt;
&lt;p&gt;在這組判準下，函數式陣營偏愛的 functional core / imperative shell (FCIS) 結構 &lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt;，確實值得重新拿出來看。它吸引人的地方在於：在規則明確、I/O 可外推的模組裡，純核心與副作用外殼的分離，會帶來更清楚的副作用邊界、更低的交叉依賴，以及更容易的局部驗證。Google Testing Blog 近年的實務倡議，也大致沿著這條線支持 FCIS 在測試經濟性上的好處。&lt;sup id=&#34;fnref:15&#34;&gt;&lt;a href=&#34;#fn:15&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;但我也得老實說，到目前為止，FCIS 對 agent 的吸引力，主要仍來自理論上的可追蹤性、邊界清晰度與測試經濟性。這假說很有吸引力，但還缺少直接的 repository-level 證據；目前也還沒有 benchmark 能直接比較 functional core、layered enterprise pattern、hexagonal 或 vertical slice 之間的 agent 表現差異。&lt;/p&gt;
&lt;p&gt;更現實的是，repo 的既有結構，不一定會被 LLM 老實遵守。&lt;/p&gt;
&lt;p&gt;目前已有一些初步研究。例如有一項 2025 年的 pilot study，要求 LLM 撰寫微服務，並明確指定必須遵守 hexagonal 架構，同時刻意加入容易誘導它抄捷徑的任務條件。結果顯示，不同模型在維持架構一致性上的表現差異很大。&lt;sup id=&#34;fnref:16&#34;&gt;&lt;a href=&#34;#fn:16&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;16&lt;/a&gt;&lt;/sup&gt; 但這類結果目前仍多屬小樣本、特定任務設定下的觀察，還不足以形成一般性結論。&lt;/p&gt;
&lt;p&gt;這至少提醒我們：名詞喊得再響，LLM 也未必理會。&lt;/p&gt;
&lt;p&gt;所以關鍵恐怕不只在架構標籤本身，而在於這些結構有沒有以夠清楚的方式外露出來，讓 agent 能穩定辨認、導航與遵守。&lt;/p&gt;
&lt;p&gt;這也讓我想到 Uncle Bob 常說的「會尖叫的架構」(screaming architecture)。&lt;/p&gt;
&lt;h2 id=&#34;五問題常出在架構沒外露&#34;&gt;五、問題常出在架構沒外露&lt;/h2&gt;
&lt;h3 id=&#34;不外露就等於不存在&#34;&gt;不外露，就等於不存在&lt;/h3&gt;
&lt;p&gt;這裡最常見的誤判，是把 agent 在大型 codebase 裡的失手，直接歸咎到傳統架構頭上。&lt;/p&gt;
&lt;p&gt;這個判斷太快了。&lt;/p&gt;
&lt;p&gt;很多團隊的真實情況，其實不是沒有邊界，而是邊界只存在於資深工程師腦中；不是沒有規則，而是規則沒有穩定外露成命名、目錄、型別、測試、CI 與工具可讀的訊號。&lt;/p&gt;
&lt;p&gt;對人類來說，那叫默契；對 agent 來說，那叫缺席。&lt;/p&gt;
&lt;p&gt;所以重點不是拿「機器可讀的結構」去取代「架構風格」。兩者本來就不在同一個層次上。比較準確的說法是：機器可讀的結構，是 agent 能不能動手的戰術前提；整體架構，則是這些修改能不能長期維持健康的策略背景。&lt;/p&gt;
&lt;h3 id=&#34;文件不是答案&#34;&gt;文件不是答案&lt;/h3&gt;
&lt;p&gt;但這裡也要小心：不要把「機器可讀」直接理解成「多放幾份給 agent 看的說明文件」。&lt;/p&gt;
&lt;p&gt;近來關於 context files 與 &lt;code&gt;AGENTS.md&lt;/code&gt; 的研究提醒我們：這類檔案不是放了就有效，也不是零成本。有一項 2026 年跨越多種 coding agents 與語言模型的研究指出，context files 會傾向降低任務成功率，卻同時拉高推論成本 20% 以上；研究者最後的建議不是「多寫一點」，而是：&lt;strong&gt;如果要寫，就只保留最少必要要求。&lt;/strong&gt;&lt;sup id=&#34;fnref:17&#34;&gt;&lt;a href=&#34;#fn:17&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;17&lt;/a&gt;&lt;/sup&gt; 另一項同年的研究則聚焦效率面，觀察 &lt;code&gt;AGENTS.md&lt;/code&gt; 對 runtime 與 token 用量的影響；它顯示這類檔案在某些設定下可能改善執行效率，但也正因此更提醒我們：&lt;code&gt;AGENTS.md&lt;/code&gt; 並不是萬靈丹。&lt;sup id=&#34;fnref:18&#34;&gt;&lt;a href=&#34;#fn:18&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;18&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;穩定的高訊號，依靠的還是架構可見性：型別邊界、可自動檢查的依賴規則、清楚的測試入口、可信的命名約定，以及能直接落進 CI 與工具流程的約束。不是多一份摘要式文件就夠了。&lt;/p&gt;
&lt;p&gt;沒有訊號還不打緊，靠著夠強的推理模型也許還能稍微補回來；更麻煩的是&lt;strong&gt;錯誤訊號&lt;/strong&gt;。過期的命名規則、和實作不一致的邊界文件、失真的 &lt;code&gt;AGENTS.md&lt;/code&gt;，往往比完全沒有文件更糟。不只缺資訊，還會給出錯誤的自信。&lt;/p&gt;
&lt;p&gt;架構如果沒有外露到能被人與 agent 穩定依循的程度，問題就還在。&lt;/p&gt;
&lt;h2 id=&#34;六架構還得為自己辯護&#34;&gt;六、架構還得為自己辯護&lt;/h2&gt;
&lt;p&gt;不是所有抽象都有用。有些抽象真的在保護系統，有些只是讓團隊覺得這樣看起來比較像一套完整的方法。&lt;/p&gt;
&lt;p&gt;到了 LLM 時代，架構不再只是拿來說服資深工程師，也得讓 agent 用得上。&lt;/p&gt;
&lt;p&gt;真正有用的結構，不管面對的是人還是機器，要求其實差不多：它要能把治理價值講清楚，訊號雜訊比要夠高，也要容易被檢查、導航與驗證。否則，即使名字再完整、分層再好看，也很難說它真的在處理複雜性。&lt;/p&gt;
&lt;p&gt;最後還是回到同一個判斷：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你現在留下的這些結構，到底是在承受複雜性，還是在替形式續命？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;未來真正推動軟體架構變化的，也許不是哪一派理論贏了，而是大量 coding agent 在 repo 裡反覆動手之後，哪些結構真的撐得住，哪些撐不住，會慢慢變得很清楚。&lt;/p&gt;
&lt;p&gt;或許 coding agent 突然湧現出自己的架構審美觀——就像 AlphaGo 讓人重新理解圍棋一樣。&lt;/p&gt;
&lt;p&gt;但在那之前，眼前比較實際的問題還是這個：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你留下來的東西，有沒有在做事？&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;36Kr Europe, “&lt;a href=&#34;https://eu.36kr.com/en/p/3715300300468617&#34;&gt;The Rise of a New King on GitHub: How was OpenClaw Developed?&lt;/a&gt;,” March 9, 2026.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Robert C. Martin, “&lt;a href=&#34;https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html&#34;&gt;Clean Architecture&lt;/a&gt;,” &lt;em&gt;The Clean Code Blog&lt;/em&gt;, August 13, 2012.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Alistair Cockburn, “&lt;a href=&#34;https://alistair.cockburn.us/hexagonal-architecture&#34;&gt;Hexagonal Architecture&lt;/a&gt;,” 2005.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Eric Evans, &lt;a href=&#34;https://www.amazon.com/dp/0321125215&#34;&gt;&lt;em&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software&lt;/em&gt;&lt;/a&gt;, 1st ed. (Boston: Addison-Wesley, 2003), ISBN-13: 978-0321125217, ISBN-10: 0321125215.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Martin Fowler, “&lt;a href=&#34;https://martinfowler.com/articles/injection.html&#34;&gt;Inversion of Control Containers and the Dependency Injection Pattern&lt;/a&gt;,” &lt;em&gt;MartinFowler.com&lt;/em&gt;, January 2004.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Microsoft Learn, “&lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/&#34;&gt;Tackling Business Complexity in a Microservice with DDD and CQRS Patterns&lt;/a&gt;,” February 28, 2023.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;Microsoft Learn, “&lt;a href=&#34;https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-implementation-entity-framework-core&#34;&gt;Implementing the Infrastructure Persistence Layer with Entity Framework Core&lt;/a&gt;,” February 28, 2023.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;Microsoft Learn, “&lt;a href=&#34;https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs&#34;&gt;CQRS Pattern&lt;/a&gt;,” &lt;em&gt;Azure Architecture Center&lt;/em&gt;, February 21, 2025.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;AWS Prescriptive Guidance, “&lt;a href=&#34;https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/acl.html&#34;&gt;Anti-corruption Layer Pattern&lt;/a&gt;”.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;Carlos E. Jimenez et al., &lt;a href=&#34;https://arxiv.org/abs/2310.06770&#34;&gt;&lt;em&gt;SWE-bench: Can Language Models Resolve Real-World GitHub Issues?&lt;/em&gt;&lt;/a&gt; (arXiv, 2023).&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;Xiang Deng et al., &lt;a href=&#34;https://arxiv.org/abs/2509.16941&#34;&gt;&lt;em&gt;SWE-Bench Pro: Can AI Agents Solve Long-Horizon Software Engineering Tasks?&lt;/em&gt;&lt;/a&gt; (arXiv, 2025).&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;Tianyang Liu, Canwen Xu, and Julian McAuley, &lt;a href=&#34;https://arxiv.org/abs/2306.03091&#34;&gt;&lt;em&gt;RepoBench: Benchmarking Repository-Level Code Auto-Completion Systems&lt;/em&gt;&lt;/a&gt; (ICLR 2024, 2024).&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;Vlad Khononov, &lt;a href=&#34;https://coupling.dev/&#34;&gt;&lt;em&gt;Balancing Coupling in Software Design&lt;/em&gt;&lt;/a&gt;, (Boston: Addison-Wesley, 2024), ISBN-10: 0137353480.&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;Gary Bernhardt, “&lt;a href=&#34;https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell&#34;&gt;Functional Core, Imperative Shell&lt;/a&gt;,” &lt;em&gt;Destroy All Software&lt;/em&gt;, July 12, 2012.&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:15&#34;&gt;
&lt;p&gt;Arham Jain, “&lt;a href=&#34;https://testing.googleblog.com/2025/10/simplify-your-code-functional-core.html&#34;&gt;Simplify Your Code: Functional Core, Imperative Shell&lt;/a&gt;,” &lt;em&gt;Google Testing Blog&lt;/em&gt;, October 20, 2025.&amp;#160;&lt;a href=&#34;#fnref:15&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:16&#34;&gt;
&lt;p&gt;Tyler Slater, &lt;a href=&#34;https://arxiv.org/abs/2512.04273&#34;&gt;&lt;em&gt;Quantitative Analysis of Technical Debt and Pattern Violation in Large Language Model Architectures&lt;/em&gt;&lt;/a&gt; (arXiv, 2025).&amp;#160;&lt;a href=&#34;#fnref:16&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:17&#34;&gt;
&lt;p&gt;Thibaud Gloaguen et al., &lt;a href=&#34;https://arxiv.org/abs/2602.11988&#34;&gt;&lt;em&gt;Evaluating AGENTS.md: Are Repository-Level Context Files Helpful for Coding Agents?&lt;/em&gt;&lt;/a&gt; (arXiv, 2026).&amp;#160;&lt;a href=&#34;#fnref:17&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:18&#34;&gt;
&lt;p&gt;Jai Lal Lulla et al., &lt;a href=&#34;https://arxiv.org/abs/2601.20404&#34;&gt;&lt;em&gt;On the Impact of AGENTS.md Files on the Efficiency of AI Coding Agents&lt;/em&gt;&lt;/a&gt; (arXiv, 2026).&amp;#160;&lt;a href=&#34;#fnref:18&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>AI 會寫程式之後，軟體工程真正變貴的是什麼</title>
      <link>//william-yeh.net/post/2026/03/genai-se-level-up/</link>
      <pubDate>Mon, 16 Mar 2026 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2026/03/genai-se-level-up/</guid>
      
        <description>&lt;p&gt;很多人會把這一輪 AI 寫程式的進展，直接講成「語言模型正在取代軟體工程師」，甚至進一步講成「語言模型正在取代軟體工程」。&lt;/p&gt;
&lt;p&gt;這樣講不算全錯，但沒有對準焦點。軟體工程沒有消失，變的是成本最高的地方不一樣了。過去 SDLC 昂貴的部分，常常落在寫程式、處理低階細節、人工重構。現在語言模型可以很快產生候選實作，原本集中在實作端的成本，就開始往別的地方移。用高德拉特的 Theory of Constraints 來看，這其實就是瓶頸轉移。&lt;/p&gt;
&lt;p&gt;接下來比較值得看的，不是軟體工程還在不在，而是瓶頸轉去哪裡了。那些新的瓶頸，比以前好處理，還是更難處理？&lt;/p&gt;
&lt;p&gt;軟體工程的典範確實在變，但工程紀律沒有因此結束。比較貼近現況的說法是：抽象層往上拉了，驗證負擔在重分配，治理形式也得跟著調整。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/03/genai-se-level-up.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/03/genai-se-level-up.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;一llm-不是編譯器&#34;&gt;一、LLM 不是編譯器&lt;/h2&gt;
&lt;p&gt;軟體工程史上反覆出現的一個主題，是抽象層持續上升。&lt;/p&gt;
&lt;p&gt;早期程式設計高度依賴機器碼與組合語言，人類必須直接處理硬體細節、暫存器配置與控制流程。高階語言與編譯器出現後，很多低階安排不再需要手動處理，工程師的注意力才逐步從「指令怎麼排」轉向「邏輯怎麼表達」。寫法變方便，人機分工也跟著重組。&lt;/p&gt;
&lt;p&gt;從這個角度看，今天的 LLM 編程確實像新一輪抽象層提升。人類不再只寫語法層級的指令，而是更常用自然語言、規格、測試與約束來描述意圖，再由語言模型生成候選實作。意圖導向、規格導向的開發方式，現在又開始變得可行，不是因為理念突然變新，而是因為工具終於比較撐得住了。&lt;/p&gt;
&lt;p&gt;但這個歷史類比只能拿來說明方向，還不能直接往下推論。很多人講到這裡，很快就會接一句：既然高階語言取代了低階語言，今天 LLM 也會像編譯器一樣，成為新的工程基礎設施。&lt;/p&gt;
&lt;p&gt;這個推論太快了。&lt;/p&gt;
&lt;p&gt;編譯器之所以能成為工程基底，關鍵不只是它很強，而是它可預期：同樣的合法輸入，在同樣條件下，應該得到語意一致的輸出。&lt;/p&gt;
&lt;p&gt;所以這個類比真正有用的地方，只是在提醒你：抽象層又往上升了一層。把它再往前推成「LLM 已經等同於編譯器」，就走過頭了。這裡最重要的差異其實很簡單：&lt;strong&gt;編譯器可以默認信任，LLM 不行。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;二語意層的不確定性&#34;&gt;二、語意層的不確定性&lt;/h2&gt;
&lt;p&gt;有一種常見說法是，現代系統本來就充滿不確定性：快取未命中、垃圾回收時機、JIT 最佳化、多執行緒交錯，哪一個不是非決定性的？既然工程師早就習慣跟這些東西共處，那麼 LLM 的不穩定，看起來也只是另一種可管理的系統特性。&lt;/p&gt;
&lt;p&gt;這種說法最大的問題，是沒有分清楚不確定性發生在哪一層。&lt;/p&gt;
&lt;p&gt;傳統系統的非決定性，大多發生在執行路徑、資源調度與效能表現層面；在設計得當的前提下，系統的語意正確性仍可透過型別系統、同步模型、測試與形式方法加以分析與約束。LLM 的不穩定，則更常直接出現在&lt;strong&gt;語意建構本身&lt;/strong&gt;：同樣一個提示，可能對應不同的實作策略、不同的邊界條件假設、不同的錯誤處理方式，甚至引入安全弱點、違反隱含限制，或偏離原始需求。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這不是單純「跑法有點抖」，而是你拿到的東西本身就可能已經換了意思。&lt;/p&gt;
&lt;p&gt;但也不能因為這樣，就滑到另一個極端，好像 LLM 完全不可工程化。那也不對。在任務範圍受限、提示結構清楚、工具介面穩定、測試充分的條件下，的確可以明顯收斂語言模型的輸出。Anthropic 對 workflow 與 agent 的區分，本身就在提醒一件事：工程上真正重要的，是&lt;strong&gt;你授予了多少自主性，又用什麼外部機制把這種自主性框住。&lt;/strong&gt;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;比較準確的理解方式，是把 LLM 當成候選實作產生器，再用規格、測試、權限與審計把它包起來。它可以很強，但不能裸奔。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;三ai-擅長封閉問題&#34;&gt;三、AI 擅長封閉問題&lt;/h2&gt;
&lt;p&gt;要理解 AI 為什麼能在某些問題上表現驚人，最好的科普材料其實不一定是寫程式，而是下棋。&lt;/p&gt;
&lt;p&gt;2016 年，AlphaGo 贏了頂尖棋士李世乭，固然很了不起；更重要的是，它讓很多人第一次很具體地看到：只要規則固定、目標清楚、勝負可判定，而且系統可以大量自我對弈，AI 就能在封閉問題裡快速逼近甚至超過人類。圍棋雖然複雜，但它仍然是一個封閉世界：棋盤有限，合法動作明確，輸贏標準預先給定。這種問題的難，主要是搜尋空間巨大，不是目標函數模糊。AlphaGo 與後續 AlphaGo Zero 的關鍵，就是把策略學習、價值評估與搜尋結合起來，再透過大量自我對弈持續優化。&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;幾年後，AlphaDev 把相近的邏輯帶進程式世界。它把「尋找更好的小型排序程式」表述成一個可搜尋的問題：每一步都是組合更好的指令序列，目標函數也相對明確，例如正確性與效能。也因為目標清楚、評估穩定、搜尋空間可封裝，AlphaDev 才能在某些小型排序問題上找到優於既有人類基準的方案。&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這裡真正值得抓住的，不是「AI 很強」這個空話，而是它在&lt;strong&gt;規則封閉、回饋明確、可大量試錯&lt;/strong&gt;的任務裡，確實特別能發揮搜尋能力。&lt;/p&gt;
&lt;p&gt;也正因如此，這條路線不能直接外推到一般企業軟體工程。企業工程面對的，通常不是單一而乾淨的目標函數，而是一組彼此牴觸的要求：可維護性、模組邊界、法規遵循、事故可追溯性、部署風險、團隊交接成本、長期總持有成本。這些維度很難壓成一個簡單分數。局部效能最優，也不等於系統治理最優。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不同層級的問題，適合不同程度的自動化。&lt;/strong&gt; AI 未必能接管所有工程決策。&lt;/p&gt;
&lt;h2 id=&#34;四審查重心轉移&#34;&gt;四、審查重心轉移&lt;/h2&gt;
&lt;p&gt;代理式工作流真正帶來的衝擊，在於它把一個原本就存在的問題放大了：當語言模型生成候選實作的速度，遠快於人工閱讀速度，傳統以逐行 diff 為核心的審查方式，開始很難擴展。&lt;/p&gt;
&lt;p&gt;近年來，部分開發者與團隊開始嘗試更激進的工作流：人類主要提供需求、規格與目標，語言模型或代理則負責撰寫程式碼、執行測試、修復錯誤，甚至在一定範圍內自動迭代。&lt;/p&gt;
&lt;p&gt;這類工作流裡，OpenClaw 作者 Peter Steinberger 算是很有代表性的一個例子。他讓語言模型在帶有工具、上下文與回合控制的環境裡，自己跑完一段工作流。這時候，人類審查的焦點就可能從逐行閱讀程式碼，轉向評估需求表述是否清楚、系統意圖是否被正確理解、代理執行路徑是否合理、測試結果是否可信，以及最終行為是否真的滿足目標。&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這裡最容易出現的誤解，是把「不 review code」聽成「不再審查」。比較準確的說法是：&lt;strong&gt;審查沒有消失，只是審查的對象在改變。&lt;/strong&gt; 當 AI 可以在短時間內產生大量候選實作時，人類很難再用原本的方式逐行追蹤每一段程式；比較務實的方向，是把更多信任建立在規格、測試、靜態分析、語意差異辨識與執行證據上，而不是只建立在肉眼閱讀程式文字上。&lt;/p&gt;
&lt;p&gt;不過，OpenClaw 或 Steinberger 都不能直接拿來當成普遍結論。它們更像壓力測試：不代表所有團隊明天都要照這樣工作，但它們會提前把未來工程可能遇到的結構性問題推到檯面上。這些案例真正有價值的地方，不在於證明「所有團隊都會變成這樣」，而在於它們先把一些原本還不夠明顯的成本，暴露出來。&lt;/p&gt;
&lt;p&gt;更值得注意的是，不同團隊在實作代理式流程時，最後常會收斂到一個很務實的原則：&lt;strong&gt;先把能確定、能驗證、能回退的部分做好，再去談更高程度的自治。&lt;/strong&gt; Anthropic 在與多個團隊合作建置 agent 的經驗中，也反覆看到這個傾向。比較穩的系統，往往不是一開始就追求「讓語言模型自己決定一切」，而是先把任務切清楚、把工具介面縮小、把失敗後的回收方式設計好，再視情況逐步放寬模型可自行決定的範圍。&lt;sup id=&#34;fnref1:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這不只是「先從簡單開始」這種老話，而是在提醒你代理式工程的成本函數：&lt;strong&gt;自主性不是免費的。&lt;/strong&gt; 每多給語言模型一層循環控制、多一個外部工具、多一次可自行決策的機會，就同步抬高觀測、驗證、審計與回溯的要求。成熟不是把 agent 權限一次拉滿，而是知道哪些判斷可以交給語言模型，哪些邊界必須牢牢握在人類手上。&lt;/p&gt;
&lt;p&gt;工程師沒有突然失業。但未來高價值的審查能力，未必還是看得出每一行 code 怎麼寫；更可能是看得出這套系統的規格是否清楚、證據是否充分、風險是否被控制、責任是否能被追溯。&lt;/p&gt;
&lt;h2 id=&#34;五規格開始卡住&#34;&gt;五、規格開始卡住&lt;/h2&gt;
&lt;p&gt;如果開發越來越依賴對話、提示與逐步澄清，那麼上下文管理就不再只是使用技巧，而會變成真正的工程問題。&lt;/p&gt;
&lt;p&gt;原因不複雜。多輪代理式互動，不是把同一句話反覆重講，而是不斷增加限制、修正假設、引用先前輸出、放棄失敗路徑。系統不只要記住內容，還要知道哪些前提已經失效，哪些推論應該撤回，哪些局部探索不應污染全局。&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;語言模型不是因為「對話變長」才突然變笨，而是它在多輪互動裡，常常不擅長處理自己先前留下來的推論痕跡。一旦早期對問題的理解有偏差，後面的回合就很容易不是重新定義問題，而是在錯的前提上繼續修修補補。Laban 等人的研究，可以把它看成對這個現象的系統化描述：對話越長，真正危險的往往不是記不住資訊，而是放不掉先前已經形成的錯誤解釋。&lt;sup id=&#34;fnref1:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;也因如此，後來像 Context Branching 這類做法才開始變得有意思。它重點不在把 prompt 包裝得更花，而是把「探索不同解法」這件事，從一條連續對話，改成可分支、可切換、可捨棄的工作流。&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt; 這其實是在把版本控制的觀念搬進規格管理：不是所有嘗試都值得留在主線，也不是每一次失敗都應該污染後續推理。&lt;/p&gt;
&lt;p&gt;所以這裡的限制，不只出現在單次生成的正確率，也出現在規格如何隨著回合演化、修正與隔離。未來更重要的能力，可能不是把 prompt 問得更長，而是&lt;strong&gt;把探索過程切得更乾淨。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;六測試開始立法&#34;&gt;六、測試開始立法&lt;/h2&gt;
&lt;p&gt;如果 LLM 與代理式系統開始承擔更多實作、重構與局部迭代工作，那麼測試策略就不能只是沿用舊習慣，而得重新回答一個問題：&lt;strong&gt;測試的作用，到底只是查錯，還是同時在規定 AI 可以怎麼改、不能怎麼改。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;要談這個問題，得先把經典的兩個測試流派講清楚。&lt;/p&gt;
&lt;p&gt;所謂 &lt;strong&gt;Detroit school&lt;/strong&gt;，也常被稱為 &lt;strong&gt;Chicago school&lt;/strong&gt; 或 &lt;strong&gt;classicist TDD&lt;/strong&gt;，核心想法是：測試應盡量從系統的外部行為與狀態變化來驗證，而不是過度關注物件之間的互動細節。這一派通常偏好經過真實組合的物件，較少使用 mock；只要功能完成後，系統狀態正確、輸出正確、公開介面行為正確，那麼內部到底怎麼協作，不一定需要在測試裡寫死。它的好處，是測試通常比較耐重構；只要外部契約沒變，內部實作可以持續調整。&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;相對地，&lt;strong&gt;London school&lt;/strong&gt;，也就是常說的 &lt;strong&gt;mockist TDD&lt;/strong&gt;，更強調從物件協作與互動設計出發。這一派常採取 outside-in 的開發方式：先從外部需求開始，逐層往內設計物件之間如何分工，並在過程中大量使用 mock 驗證「誰應該呼叫誰、何時呼叫、帶什麼參數」。這種做法的優點，是它會提早暴露設計問題。當你在寫測試時，就得先把各個元件如何互動講清楚，很多模糊的責任分配也會被迫提前釐清。因此，London school 的支持者常認為，測試不只是驗證工具，也是設計工具。&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;壓縮成一句話，Detroit / Chicago school 關心的是：&lt;strong&gt;最後系統有沒有做對事。&lt;/strong&gt; London school 關心的是：&lt;strong&gt;系統是不是用預期的協作方式做對事。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這裡沒有誰天然比較高級。它們對應的是兩種不同的風險感知。&lt;/p&gt;
&lt;p&gt;如果你最擔心的是重構成本、測試脆弱性、內部設計被過早綁死，那你通常會更偏向 Detroit。因為它保留了較大的內部實作自由，只要外部結果沒變，系統就能繼續演化。&lt;/p&gt;
&lt;p&gt;如果你最擔心的是依賴邊界不清、責任分工混亂、元件互動失控，那你通常會更偏向 London。因為它要求你把協作契約提前講清楚，藉由 mock 讓設計更早成形。&lt;/p&gt;
&lt;p&gt;問題在於，到了 AI 參與開發的場景，這兩派的權重會變。&lt;/p&gt;
&lt;p&gt;在代理式重構或生成場景中，語言模型很可能會調整控制流程、替換內部實作、重新切分模組，甚至用一種人類原本沒想到的方式達成同樣的外部行為。如果這時候測試過度綁定方法呼叫次序、參數傳遞路徑與物件互動細節，那麼很多本來有效、甚至更好的重構，都可能被測試判定為失敗。換句話說，&lt;strong&gt;過度 London 化的測試，在 AI 場景裡特別容易把設計選擇誤寫成功能規格。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這也是為什麼 AI 時代值得重看這場舊爭論。問題已經不只是「哪一派比較優雅」，而是「哪一種測試更能分清楚：什麼是系統真正不能變的東西，什麼只是暫時的實作路徑。」&lt;/p&gt;
&lt;p&gt;我會把它拆成三層來看。&lt;/p&gt;
&lt;p&gt;第一層，對於 AI 需要自由探索、自由重構的區域，測試應更接近 Detroit school 的精神。盡量用公開 API、可觀察狀態、整體行為與高階不變量來定義正確性，不要太早把內部協作方式寫死。這一層的目的，是替語言模型保留足夠的搜尋空間，讓它能在不破壞外部契約的前提下，自主改進實作。&lt;/p&gt;
&lt;p&gt;第二層，對於那些真的不能亂動的區域，例如對外協定、錯誤處理流程、安全檢查、高成本依賴呼叫、金流與審計事件，London school 的精神仍然有價值。此時我們在意的本來就不只是結果對不對，也在意它是否以正確、可追溯、可受控的方式發生。這時互動測試不是多餘，而是在保護關鍵邊界。&lt;/p&gt;
&lt;p&gt;第三層，是傳統 TDD 爭論比較少正面處理、但在 AI 場景中特別重要的一件事：&lt;strong&gt;測試不只要檢查答案，還要提供足夠抽象的驗證標準。&lt;/strong&gt; 只靠單一輸入對單一輸出的例子，對人類手寫程式有時還勉強夠用；但對於生成式系統來說，這種驗證往往太窄，容易讓語言模型學會的是「迎合測試」，不是「滿足規格」。也因此，property-based testing 這類方法會變得更重要，因為它驗證的不是個別樣本，而是程式在一整類情境下是否維持某些不變條件。&lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;所以，比起問 Detroit 還是 London 哪個對，更值得問的是：哪些測試在保護真正的外部契約？哪些測試其實只是把歷史實作的偶然性誤寫成規格？哪些互動細節真的是安全或合規要求？哪些地方其實應該交給語言模型自由重構？&lt;/p&gt;
&lt;p&gt;AI 時代比較合理的方向，不是在 Detroit 和 London 之間二選一，而是把不同測試放回各自最適合的層級。對可自由重構的內部邏輯，優先保護外部結果與高階不變量；對不能出錯的依賴互動、權限流向與副作用，再用更嚴格的互動驗證去守邊界；至於生成式系統特有的風險，則再往上補一層，用 property-based 或 differential testing 去檢查「不同實作是否其實破壞了同一個規格」。&lt;sup id=&#34;fnref:15&#34;&gt;&lt;a href=&#34;#fn:15&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;測試不再只是查錯工具，也越來越像一套治理語言：一方面給模型留出探索空間，另一方面清楚告訴它，哪裡可以動，哪裡不能動。&lt;/p&gt;
&lt;h2 id=&#34;七clean-code-變了&#34;&gt;七、Clean Code 變了&lt;/h2&gt;
&lt;p&gt;關於 clean code，過去最常見的說法是：它能降低人類工程師的理解成本，讓維護、交接與重構變得比較容易。到了 LLM 參與開發的時代，這套論述還得再往前推一步。問題已經不只是「人看不看得懂」，而是：&lt;strong&gt;語言模型能不能穩定理解你給它的程式。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;對人類來說，命名差一點、函式大一點，也許還能硬讀；對語言模型來說，這些東西會直接改變它如何切分問題、辨認模式、推測哪裡是主幹、哪裡只是雜訊。&lt;/p&gt;
&lt;p&gt;這裡很容易被低估的一點是，對語言模型來說，程式碼不只是執行對象，同時也是上下文材料。模型得根據這些材料去推斷命名意圖、模組邊界、控制流程與可重用模式。程式越雜亂，語言模型越難分辨什麼是核心結構，什麼只是歷史殘留；越容易把偶然寫法誤判成必要約束，把局部噪音誤當成系統規律。到了這個階段，clean code 的意義就變了：它不只是讓人比較好維護，也是在&lt;strong&gt;替語言模型降低語意負擔&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;這件事真的可能有差嗎？&lt;/p&gt;
&lt;p&gt;Jain 等人的研究把它變成一個可以測量的假設：如果不急著增加資料量，而是先改善程式碼本身的可讀性與結構性，語言模型會不會學得更穩？&lt;sup id=&#34;fnref:16&#34;&gt;&lt;a href=&#34;#fn:16&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;16&lt;/a&gt;&lt;/sup&gt; 他們不是先去改演算法，而是改善&lt;strong&gt;語言模型接觸這段程式時看到的認知表面&lt;/strong&gt;：命名更有語意、結構更容易分段理解、高階步驟更容易被看見。&lt;/p&gt;
&lt;p&gt;結果也很直接：在程式生成任務上，資料整理得更好，確實能帶來可觀提升；甚至在某些設定下，少量但較乾淨的資料，會比大量但混亂的資料更有價值。這對工程實務很重要，因為它提醒了一件常被忽略的事：在 AI 時代，很多時候真正拉開差距的，不是你餵了模型多少東西，而是你餵進去的材料到底有多容易被正確理解。&lt;/p&gt;
&lt;p&gt;這個發現替 clean code 補上了一個新的經驗支持，也改變了我們對工程價值的理解。過去談工程紀律，常常像是在談一種道德要求：今天命名清楚、模組分明，未來團隊比較好維護。這當然成立。但在 AI 時代，這些做法不只服務未來的人，也立刻服務當下的語言模型。你把程式整理得越清楚，模型越容易在比較小的語意空間裡工作；上下文噪音越少，生成越穩；結構越清楚，幻覺風險和誤解成本就越低。也就是說，傳統工程紀律沒有因 AI 而過時，反而第一次在「機器可理解性」上得到很直接的操作性理由。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在 LLM 時代，乾淨程式碼正在從人類維護性的美德，變成語言模型可生成性的基礎設施。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;下一次再談 clean code，不只問「這樣別人看不看得懂」，也要多問一句：&lt;strong&gt;這樣的結構，語言模型能不能穩定理解、穩定延續、穩定驗證。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這不是審美問題。這是生成條件問題。&lt;/p&gt;
&lt;h2 id=&#34;八可治理的程式碼&#34;&gt;八、可治理的程式碼&lt;/h2&gt;
&lt;p&gt;一旦接受前面的判斷，工程問題就會改寫成另一句話：&lt;strong&gt;不是能不能生成 code，而是能不能生成可被安全吸收、可被驗證、可被審計的 code。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這至少有三層要求。&lt;/p&gt;
&lt;p&gt;第一層是&lt;strong&gt;執行隔離&lt;/strong&gt;。未經驗證的 AI 輸出，不應直接跑在高權限、真實資料或可對外互動的環境中。候選實作的執行，本身就是安全決策，不只是開發便利功能。&lt;sup id=&#34;fnref:17&#34;&gt;&lt;a href=&#34;#fn:17&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;17&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;第二層是&lt;strong&gt;語意審查與變更理解&lt;/strong&gt;。當產出速度遠超過人工閱讀速度，人類不可能只靠文字 diff 理解變更影響。未來的審查機制勢必更依賴語意差異分析、結構化重構辨識、靜態檢查與契約違反提示，讓人類把注意力放在真正改變業務邏輯、權限流向與風險邊界的地方。&lt;sup id=&#34;fnref:18&#34;&gt;&lt;a href=&#34;#fn:18&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;18&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;第三層是&lt;strong&gt;高保證驗證&lt;/strong&gt;。對多數一般系統來說，單元測試、整合測試與模擬環境，已足夠吸收大部分風險；但在安全關鍵、金流、基礎設施與高合規場景，這些往往不夠。這時更形式化的狀態建模、語言模型檢查與規格驗證方法，就可能變成必備品。&lt;sup id=&#34;fnref:19&#34;&gt;&lt;a href=&#34;#fn:19&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;19&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這些要求最後都指向同一件事：&lt;strong&gt;生成加速了，但驗證不會因此自動變簡單。很多時候，它只會變得更重要。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;九樂觀主義的邊界&#34;&gt;九、樂觀主義的邊界&lt;/h2&gt;
&lt;p&gt;坊間流傳很多樂觀派說法。像「AI 明天就會取代工程師」這種口號，其實不必太認真。真正需要認真回應的，是它比較強的版本：真實軟體工程 benchmark 確實在快速進步，代理式 coding 也正在逼近大規模可用門檻。&lt;/p&gt;
&lt;p&gt;的確，以 Copilot 的實驗來看，生成式工具已經能在受控任務中帶來明顯的速度提升。&lt;sup id=&#34;fnref:20&#34;&gt;&lt;a href=&#34;#fn:20&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;20&lt;/a&gt;&lt;/sup&gt; 從 SWE-bench 這類更貼近真實 issue resolution 的 benchmark 來看，代理式 coding 也確實跨過了早期那種只能做玩具題的階段。&lt;sup id=&#34;fnref:21&#34;&gt;&lt;a href=&#34;#fn:21&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;21&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;但也正因為能力上升得夠快，benchmark 本身開始暴露另一層問題。OpenAI 在 2026 年不再把 SWE-bench Verified 視為前沿能力的好指標，不是因為它不重要了，而是因為語言模型越接近高分，測試設計缺陷、資料污染與任務定義模糊，就越會主導最後的評估結果。&lt;sup id=&#34;fnref:22&#34;&gt;&lt;a href=&#34;#fn:22&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;22&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;所以，這不只是捷報，也是一份壓力測試報告。當語言模型還不夠強，大家關心的是它會不會做；一旦語言模型開始會做，真正決定結果能不能信任的，反而是測試有沒有設計好、規格有沒有寫清楚、驗證有沒有跟上。&lt;/p&gt;
&lt;p&gt;與其說「工程快要不重要了」，不如說：&lt;strong&gt;當語言模型更強時，規格、測試與 benchmark 設計反而變得更重要。&lt;/strong&gt; 能力上來之後，先暴露出來的不是工程退場，而是驗證與治理的缺口被照得更亮。&lt;/p&gt;
&lt;p&gt;你的治理能力，有跟著一起升上來嗎？這才是更值得擔心的事。&lt;/p&gt;
&lt;h2 id=&#34;結論&#34;&gt;結論&lt;/h2&gt;
&lt;p&gt;從組合語言走到 C 語言，人類並沒有完全放手，而是把約束搬到更高的抽象層級：結構化程式設計、模組化、型別系統。這些約束不是拿來限制編譯器，而是確保人類在必要時仍然能理解和控制系統。&lt;/p&gt;
&lt;p&gt;LLM 時代的轉折其實很像。&lt;strong&gt;把邊界限縮到可掌握的顆粒度&lt;/strong&gt; 這個原則沒有消失，只是往上移了：從「人類要看懂每一行程式碼」，移到「人類要看懂每一個模組的意圖與契約」，再移到「人類要看懂系統的架構決策與約束框架」。&lt;/p&gt;
&lt;p&gt;所以現在真正該問的，不是「AI 會不會取代程式設計」。比較重要的是：規格由誰定義，結果由誰驗證，權限由誰控制，後果由誰承擔。&lt;/p&gt;
&lt;p&gt;這幾件事沒有設計好，語言模型越強，風險只會越大。
這幾件事設計好了，語言模型越強，工程收益才可能真的放大。&lt;/p&gt;
&lt;p&gt;至於將來是否會出現像 AlphaGo 那樣徹底超越人類認知的時刻？也許會。但在那之前，我們需要以歷史為師，在新的抽象層級上，重新建立一套人類能夠理解和掌控的約束體系。那套約束體系的名字，可能叫做 harness、validation loop、architectural guardrails，而不是 structured programming 和 SOLID。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Liu, Fang, et al. &lt;a href=&#34;https://arxiv.org/abs/2404.00971&#34;&gt;“Exploring and Evaluating Hallucinations in LLM-Powered Code Generation.”&lt;/a&gt; 2024.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Zhang, Ziyao, et al. &lt;a href=&#34;https://arxiv.org/abs/2409.20550&#34;&gt;“LLM Hallucinations in Practical Code Generation: Phenomena, Mechanism, and Mitigation.”&lt;/a&gt; 2024.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Anthropic. &lt;a href=&#34;https://www.anthropic.com/engineering/building-effective-agents&#34;&gt;“Building Effective AI Agents.”&lt;/a&gt; 2024/2025.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Shavit, Yonadav, et al. &lt;a href=&#34;https://cdn.openai.com/papers/practices-for-governing-agentic-ai-systems.pdf&#34;&gt;&lt;em&gt;Practices for Governing Agentic AI Systems&lt;/em&gt;&lt;/a&gt;. OpenAI, 2023.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Google DeepMind. &lt;a href=&#34;https://storage.googleapis.com/deepmind-media/DeepMind.com/Blog/updating-the-frontier-safety-framework/Frontier%20Safety%20Framework%202.0%20%281%29.pdf&#34;&gt;&lt;em&gt;Frontier Safety Framework 2.0&lt;/em&gt;&lt;/a&gt;, 2025.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;Silver, David, et al. &lt;a href=&#34;https://www.nature.com/articles/nature16961&#34;&gt;“Mastering the game of Go with deep neural networks and tree search.”&lt;/a&gt; &lt;em&gt;Nature&lt;/em&gt; 529 (2016): 484–489.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;Silver, David, et al. &lt;a href=&#34;https://www.nature.com/articles/nature24270&#34;&gt;“Mastering the game of Go without human knowledge.”&lt;/a&gt; &lt;em&gt;Nature&lt;/em&gt; 550 (2017): 354–359.&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;Mankowitz, Daniel J., et al. &lt;a href=&#34;https://www.nature.com/articles/s41586-023-06004-9&#34;&gt;“Faster Sorting Algorithms Discovered Using Deep Reinforcement Learning.”&lt;/a&gt; &lt;em&gt;Nature&lt;/em&gt; 618 (2023): 257–263.&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;Steinberger, Peter. &lt;a href=&#34;https://steipete.me/posts/2025/shipping-at-inference-speed&#34;&gt;“Shipping at Inference-Speed.”&lt;/a&gt; 2025.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;Laban, Philippe, C.-S. Wu, et al. &lt;a href=&#34;https://arxiv.org/abs/2505.06120&#34;&gt;“LLMs Get Lost In Multi-Turn Conversation.”&lt;/a&gt; 2025.&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;Nanjundappa, Bhargav Chickmagalur, and Spandan Maaheshwari. &lt;a href=&#34;https://arxiv.org/abs/2512.13914&#34;&gt;“Context Branching for LLM Conversations: A Version Control Approach to Exploratory Programming.”&lt;/a&gt; 2025.&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;Fowler, Martin. &lt;a href=&#34;https://martinfowler.com/articles/mocksArentStubs.html&#34;&gt;“Mocks Aren’t Stubs.”&lt;/a&gt; 2007.&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;Freeman, Steve, and Nat Pryce. &lt;a href=&#34;https://amazon.com/dp/0321503627&#34;&gt;&lt;em&gt;Growing Object-Oriented Software, Guided by Tests&lt;/em&gt;&lt;/a&gt;. Addison-Wesley, 2009.&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;He, Lehan, et al. &lt;a href=&#34;https://arxiv.org/abs/2506.18315&#34;&gt;“Use Property-Based Testing to Bridge LLM Code Generation and Validation.”&lt;/a&gt; 2025.&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:15&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://arxiv.org/html/2410.04249v3&#34;&gt;“Differential Testing with LLMs using Natural Language Specifications and Code Artifacts.”&lt;/a&gt; 2025.&amp;#160;&lt;a href=&#34;#fnref:15&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:16&#34;&gt;
&lt;p&gt;Jain, Naman, et al. &lt;a href=&#34;https://arxiv.org/abs/2311.14904&#34;&gt;“LLM-Assisted Code Cleaning For Training Accurate Code Generators.”&lt;/a&gt; 2023 / ICLR 2024.&amp;#160;&lt;a href=&#34;#fnref:16&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:17&#34;&gt;
&lt;p&gt;Perrone, Giuseppe, et al. &lt;a href=&#34;https://arxiv.org/abs/2407.12297&#34;&gt;“WebAssembly and Security: A Review.”&lt;/a&gt; 2024.&amp;#160;&lt;a href=&#34;#fnref:17&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:18&#34;&gt;
&lt;p&gt;Tsantalis, Nikolaos, Ameya Ketkar, and Danny Dig. &lt;a href=&#34;https://www.computer.org/csdl/journal/ts/2022/03/09136878/1liqhds60s8&#34;&gt;“RefactoringMiner 2.0.”&lt;/a&gt; &lt;em&gt;IEEE Transactions on Software Engineering&lt;/em&gt; 48, no. 3 (2022): 930–950.&amp;#160;&lt;a href=&#34;#fnref:18&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:19&#34;&gt;
&lt;p&gt;Lamport, Leslie. &lt;a href=&#34;https://lamport.azurewebsites.net/tla/book-02-08-08.pdf&#34;&gt;&lt;em&gt;Specifying Systems: The TLA+ Language and Tools for Hardware and Software Engineers&lt;/em&gt;&lt;/a&gt;. Addison-Wesley, 2003.&amp;#160;&lt;a href=&#34;#fnref:19&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:20&#34;&gt;
&lt;p&gt;Peng, Sida, et al. &lt;a href=&#34;https://arxiv.org/abs/2302.06590&#34;&gt;“The Impact of AI on Developer Productivity: Evidence from GitHub Copilot.”&lt;/a&gt; 2023.&amp;#160;&lt;a href=&#34;#fnref:20&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:21&#34;&gt;
&lt;p&gt;SWE-bench. &lt;a href=&#34;https://www.swebench.com/&#34;&gt;Official Leaderboards&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:21&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:22&#34;&gt;
&lt;p&gt;OpenAI. &lt;a href=&#34;https://openai.com/index/why-we-no-longer-evaluate-swe-bench-verified/&#34;&gt;“Why SWE-bench Verified no longer measures frontier coding capabilities.”&lt;/a&gt; 2026.&amp;#160;&lt;a href=&#34;#fnref:22&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>AI 會取代多少員工？企業真正面對的是約束條件</title>
      <link>//william-yeh.net/post/2026/03/genai-replacement-ratio/</link>
      <pubDate>Wed, 11 Mar 2026 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2026/03/genai-replacement-ratio/</guid>
      
        <description>&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    這篇要問的事
    
  &lt;/summary&gt;
  &lt;blockquote&gt;
&lt;p&gt;如果公司導入 AI，真正值得問的問題不是「AI 會不會搶走工作」，而是：在成本不增加、產出不下降的前提下，企業到底有多大空間縮減人力？而這個答案，又會因為 AI 是「菁英放大器」還是「技能拉平器」而明顯不同。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;/details&gt;

&lt;p&gt;幾個月前，我在社群媒體看到一張裁員通知書的截圖。底下有一行說明：「公司說是因為導入 AI 工具，現有的人力已經足夠應付產出需求。」&lt;/p&gt;
&lt;p&gt;這類貼文底下很快就會吵成一團。有人說 AI 終於開始搶工作了；有人說這根本是景氣問題，不要什麼都怪 AI；也有人說，這只是管理層找的藉口。&lt;/p&gt;
&lt;p&gt;如果把問題問得精確一點，真正值得分析的，其實不是口號式的「AI 會不會取代人類工作」，而是更窄、也更接近企業實際決策的問題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果公司導入 AI，並且希望用它減少一部分人力，那麼這個人力縮減比例，在理論上有沒有上限或下限？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這篇想做的，就是先用一個盡量簡單的模型，把這件事的骨架抽出來。&lt;/p&gt;
&lt;p&gt;先講在前面：這不是現實世界的完整描述。企業不只在乎成本和產出，還會在乎品質、風險、交期、客戶體驗、組織摩擦、法規責任，以及不同職位之間的互補關係。這裡只是先把問題縮到最基本的形式，看看哪些力量會一起限制企業的人力調整空間。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2026/03/ai-and-jobs.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2026/03/ai-and-jobs.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;先把企業面對的條件寫清楚&#34;&gt;先把企業面對的條件寫清楚&lt;/h2&gt;
&lt;p&gt;假設一家公司原本有 $L$ 位員工。&lt;/p&gt;
&lt;p&gt;隨著分析顆粒度不同，這個 $L$ 也可以理解成某個部門或團隊的人數，方法完全一樣。只是為了說明方便，這裡先用「整家公司」做分析單位。&lt;/p&gt;
&lt;p&gt;現在，公司決定導入 AI。導入之後，我們先考慮一個最簡單的情境：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有一部分員工被裁減&lt;/li&gt;
&lt;li&gt;剩下來的員工都搭配 AI 工具工作&lt;/li&gt;
&lt;li&gt;公司至少希望滿足兩件事：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;總成本不能增加&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;總有效產出不能下降&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這裡的「有效產出」，你可以把它想像成餐廳的出餐量，但不是只看做出了幾道菜，而是把速度、品質、退餐率、客訴等因素都折算進去，用一個可以加總的指標來衡量。這當然是很強的假設，但如果不先這樣做，問題就很難寫成清楚的模型。&lt;/p&gt;
&lt;p&gt;另外，這裡談的也不是嚴格意義上的「AI 直接替代率」，而是更保守地去問：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在導入 AI 之後，若公司希望同時滿足成本不升、產出不降，它&lt;strong&gt;可行的&lt;/strong&gt;人力縮減比例是多少？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;把這個比例記成 $\rho$，其中 $0 \le \rho \le 1$。下限 0 代表「一個都不裁」，上限 1 代表「一個都不留」。&lt;/p&gt;
&lt;h3 id=&#34;幾個基本變數&#34;&gt;幾個基本變數&lt;/h3&gt;
&lt;p&gt;再多定義幾個符號：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;變數&lt;/th&gt;
          &lt;th style=&#34;text-align: right&#34;&gt;符號&lt;/th&gt;
          &lt;th&gt;意義&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;原始員工人數&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;$L$&lt;/td&gt;
          &lt;td&gt;公司導入 AI 前的總雇用人數&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;員工平均月成本&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;$w$&lt;/td&gt;
          &lt;td&gt;每位員工平均月薪資成本&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;AI 月成本&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;$C_{ai}$&lt;/td&gt;
          &lt;td&gt;每位留任員工平均分攤到的 AI 月成本&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;人力縮減比例&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;$\rho$&lt;/td&gt;
          &lt;td&gt;導入 AI 後的人力縮減比例&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;員工平均有效產出&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;$q$&lt;/td&gt;
          &lt;td&gt;每位員工每單位時間的有效產出&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;AI 生產力提升率&lt;/td&gt;
          &lt;td style=&#34;text-align: right&#34;&gt;$\phi$&lt;/td&gt;
          &lt;td&gt;AI 讓每位留任員工產出提高的比例，$\phi \ge 0$&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;這裡有一個重要設定：我把 $C_{ai}$ 寫成「每位留任員工平均分攤到的 AI 成本」。也就是說，下面的模型考慮的是一種特定情境：AI 的使用成本，大致會隨著留任員工數增加，或至少可以等價攤分到每位留任員工身上。&lt;/p&gt;
&lt;p&gt;在這個設定裡：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原本公司有 $L$ 人&lt;/li&gt;
&lt;li&gt;導入 AI 後，裁減比例是 $\rho$&lt;/li&gt;
&lt;li&gt;所以留下來的人數是 $(1-\rho)L$&lt;/li&gt;
&lt;li&gt;每位留任員工都搭配 AI，因此每人多一筆 $C_{ai}$ 成本&lt;/li&gt;
&lt;li&gt;同時，AI 讓每位留任員工的有效產出變成原本的 $1+\phi$ 倍&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;現實裡，AI 成本也可能包含固定成本，例如算力硬體、模型微調、資料清洗、流程整合等。若把固定成本也放進來，企業對「是否需要更大幅度調整人力」的計算會再變一層。下面先不處理那種情況，而是專注在這個較乾淨的邊際成本版本。&lt;/p&gt;
&lt;h2 id=&#34;可行區間成本與產出兩道約束&#34;&gt;可行區間：成本與產出兩道約束&lt;/h2&gt;
&lt;p&gt;很多人談「AI 會取代多少工作」時，心裡其實只有一種力量：技術有多強、AI 能替代多少任務。&lt;/p&gt;
&lt;p&gt;但在這個模型裡，人力縮減比例不是只受一個方向限制，而是同時被兩道約束夾住：一邊來自成本，一邊來自產出。先看成本，再看產出。&lt;/p&gt;
&lt;h3 id=&#34;成本約束至少要省下多少人力&#34;&gt;成本約束：至少要省下多少人力&lt;/h3&gt;
&lt;p&gt;導入 AI 之前，公司的總成本就是所有人的薪資總和：&lt;/p&gt;
$$
Lw
$$&lt;p&gt;導入 AI 之後，員工數變成 $(1-\rho)L$，而且每位留任員工除了薪資 $w$ 之外，還多了一筆 AI 成本 $C_{ai}$，所以導入後的總成本是：&lt;/p&gt;
$$
(1-\rho)L(w+C_{ai})
$$&lt;p&gt;如果公司要求「導入 AI 後，總成本不能增加」，那就必須滿足：&lt;/p&gt;
$$
Lw \ge (1-\rho)L(w+C_{ai})
$$&lt;p&gt;整理之後可得：&lt;/p&gt;
$$
\frac{C_{ai}}{w+C_{ai}} \le \rho
$$&lt;p&gt;也就是說，在這個模型裡，人力縮減比例 $\rho$ 有一個下限：&lt;/p&gt;
$$
\rho_{\min}=\frac{C_{ai}}{w+C_{ai}}
$$&lt;p&gt;這條式子真正說的，不是「企業一定偏好裁員」，也不是「AI 越貴，公司就一定越想裁人」。它說的是更窄、但很關鍵的一件事：&lt;strong&gt;如果企業已經決定讓留任員工普遍使用 AI，且又要求總成本不能增加，那至少得縮減到某個比例，帳面上才站得住。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;直覺上：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果人工很貴、AI 相對便宜，只要裁掉少少一部分人，就足以把新增的 AI 成本打平&lt;/li&gt;
&lt;li&gt;如果 AI 很貴、人工相對沒那麼貴，那麼企業就得裁掉更多人，才有辦法讓總成本不增加&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;假設每位留任員工平均分攤到的 AI 月成本為 $C_{ai}=6k$ 新台幣，員工平均月成本設為 $w=60k$ 新台幣，那麼&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
$$
\frac{C_{ai}}{w+C_{ai}}
$$&lt;p&gt;大約會是 9%。意思只是：在這個簡化模型裡，如果企業想讓多數留任員工都用上這套工具，至少得省下差不多這個量級的人力成本，帳才打得平。&lt;/p&gt;
&lt;p&gt;但這個下限只告訴你「要省到多少」，&lt;strong&gt;沒有告訴你會裁誰&lt;/strong&gt;。現實裡可能是裁員，也可能是遇缺不補、縮編某些團隊、把部分工作外包，或把人力移去新的流程與驗證環節（此文後面會探討這一點）。&lt;/p&gt;
&lt;h3 id=&#34;產出約束人力最多能縮到哪裡&#34;&gt;產出約束：人力最多能縮到哪裡&lt;/h3&gt;
&lt;p&gt;再來看產出。這一步會把人力縮減比例的另一端也釘住：&lt;strong&gt;AI 再強，也只能讓企業縮編到某個範圍；超過那個範圍，總產出就會掉下來。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;導入 AI 之前，公司的總有效產出是：&lt;/p&gt;
$$
Lq
$$&lt;p&gt;導入 AI 之後，雖然只剩下 $(1-\rho)L$ 位員工，但每位留任員工的有效產出變成 $1+\phi$ 倍，所以總有效產出會變成：&lt;/p&gt;
$$
(1-\rho)Lq(1+\phi)
$$&lt;p&gt;如果公司要求「導入 AI 後，總有效產出不能下降」，就必須滿足：&lt;/p&gt;
$$
Lq \le (1-\rho)Lq(1+\phi)
$$&lt;p&gt;整理之後得到：&lt;/p&gt;
$$
\rho \le \frac{\phi}{1+\phi}
$$&lt;p&gt;也就是說，在這個模型裡，人力縮減比例有一個上限：&lt;/p&gt;
$$
\rho_{\max}=\frac{\phi}{1+\phi}
$$&lt;p&gt;$\phi$ 越大，人力縮減比例的上限越高；$\phi$ 越小，人力縮減比例的上限越低。&lt;/p&gt;
&lt;p&gt;這條式子在說的其實很簡單：你不能只因為「AI 很強」這個印象，就直接決定要裁多少人。你得看它到底能不能撐住原本的有效產出。&lt;/p&gt;
&lt;p&gt;因為你裁掉的人越多，就越需要靠留下來的人把缺口補回去。而這個補缺能力，不靠想像，只靠 $\phi$ 所代表的有效產出提升。&lt;/p&gt;
&lt;h3 id=&#34;先決條件增益要蓋過成本&#34;&gt;先決條件：增益要蓋過成本&lt;/h3&gt;
&lt;p&gt;前面兩條不等式要同時成立，所以 $\rho$ 必須滿足：&lt;/p&gt;
$$
\frac{C_{ai}}{w+C_{ai}} \le \rho \le \frac{\phi}{1+\phi}
$$&lt;p&gt;這條式子告訴我們，在這個模型裡，人力縮減比例不是想設多高就設多高，而是被夾在一個可行區間裡：左邊是成本條件給出的下限，右邊是產出條件給出的上限。&lt;/p&gt;
&lt;p&gt;如果左邊比右邊還大，就代表這個可行區間根本不存在。也就是說，想要「導入 AI」並同時達成「成本不升、產出不降」這件事，在這個模型裡沒有可行解。&lt;/p&gt;
&lt;p&gt;所以，還會再多出一個先決條件：&lt;/p&gt;
$$
\frac{C_{ai}}{w+C_{ai}} \le \frac{\phi}{1+\phi}
$$&lt;p&gt;化簡之後得到：&lt;/p&gt;
$$
\phi \ge \frac{C_{ai}}{w}
$$&lt;p&gt;這條式子，其實才是整件事最值得記住的地方。&lt;/p&gt;
&lt;p&gt;它說的是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AI 帶來的生產力提升，至少要大於它相對於人工成本的負擔，整件事才有可行空間。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這比很多新聞標題更接近企業真正在面對的問題。真正的核心，不是抽象地問「AI 會不會取代人」，而是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AI 的效能／成本比，能不能支撐「人力調整」這件事成立？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果不能，技術再炫，企業也未必埋單。
如果可以，那就算 AI 還遠不到「完全替代人」的程度，企業也可能開始認真重算自己的人力配置。&lt;/p&gt;
&lt;h2 id=&#34;平均員工模型到這裡就不夠了&#34;&gt;平均員工模型，到這裡就不夠了&lt;/h2&gt;
&lt;p&gt;到這裡為止，我們得到的是平均模型的結論；但真正接近現實的問題，從這裡才開始。因為企業不是面對一群平均員工，而是在不同類型的人之間，重新分配 AI、預算與人力。&lt;/p&gt;
&lt;p&gt;前面一直用同一組 $w$、$q$、$\phi$ 去描述整家公司：每個人的薪資差不多、產出差不多、AI 帶來的增益也差不多。這樣做的好處，是可以把問題寫得很乾淨；限制也很明顯：它還沒有碰到企業真正麻煩的地方。&lt;/p&gt;
&lt;h3 id=&#34;從平均模型到異質員工&#34;&gt;從平均模型到異質員工&lt;/h3&gt;
&lt;p&gt;一個公司裡，不同職位的差異至少有四種：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;薪資不同&lt;/li&gt;
&lt;li&gt;產出形式不同&lt;/li&gt;
&lt;li&gt;AI 可放大的程度不同&lt;/li&gt;
&lt;li&gt;被替代或被保留的可能性不同&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果要把模型往現實再推一步，就得把員工拆成不同類型，用下標 $i$ 表示。也就是說，不同職位各自有自己的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;薪資 $w_i$&lt;/li&gt;
&lt;li&gt;產出 $q_i$&lt;/li&gt;
&lt;li&gt;AI 增益 $\phi_i$&lt;/li&gt;
&lt;li&gt;人力縮減比例 $\rho_i$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這時候，公司的約束條件就不再是一條平均式，而會變成加總：&lt;/p&gt;
$$
\sum_i (1-\rho_i)L_i(w_i+C_{ai,i}) \le \sum_i L_i w_i
$$$$
\sum_i (1-\rho_i)L_i q_i(1+\phi_i) \ge \sum_i L_i q_i
$$&lt;p&gt;一旦寫成這樣，問題的性質就變了。&lt;/p&gt;
&lt;p&gt;前面的平均模型，問的是：整體而言，人力縮減比例有沒有上下界；但異質員工模型問的則是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;公司會把縮減幅度放在哪些職位？又會把 AI 資源優先配給哪些人？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不過，這裡要先把推論邊界講清楚。&lt;strong&gt;接下來不是要解完整的異質員工最適化問題。&lt;/strong&gt; 如果真的要解那個問題，還得額外指定企業的目標函數、不同職位之間的互補關係、品質門檻，以及哪些工作可以互相替代。&lt;/p&gt;
&lt;p&gt;下面要做的，是比較靜態地看：&lt;strong&gt;如果 AI 增益和薪資之間呈現不同關係，縮減壓力大致會往哪裡移動。&lt;/strong&gt; 這不是完整求解，但足以幫我們看出兩種很不一樣的組織方向。&lt;/p&gt;
&lt;p&gt;另外，這裡的薪資 $w_i$，也只是職位複雜度、責任密度與市場稀缺性的粗略代理，不等於能力本身。&lt;/p&gt;
&lt;h3 id=&#34;情境一菁英放大器&#34;&gt;情境一：菁英放大器&lt;/h3&gt;
&lt;p&gt;第一種情境是：AI 比較像一個「菁英放大器」——薪資越高、位置越關鍵的職位，本來就在做更複雜、更高槓桿的工作，因此 AI 對他的生產力提升也越大。&lt;/p&gt;
&lt;p&gt;如果把這個想法寫成一個簡單的線性假設，可以設：&lt;/p&gt;
$$
w = k\phi, \qquad k&gt;0
$$&lt;p&gt;也就是薪資越高的職位，AI 對它的放大效果也越強。&lt;/p&gt;
&lt;p&gt;把這個關係代回原本的區間：&lt;/p&gt;
$$
\frac{C_{ai}}{w+C_{ai}} \le \rho \le \frac{\phi}{1+\phi}
$$&lt;p&gt;不等式會變成：&lt;/p&gt;
$$
\frac{C_{ai}}{k\phi + C_{ai}} \le \rho \le \frac{\phi}{1+\phi}
$$&lt;p&gt;這代表當 $\phi$ 變大時，右邊的上限會上升，而左邊的下限會下降。換句話說，人力縮減比例的&lt;strong&gt;可行區間會被拉開&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;直覺上，這意味著：如果某些高薪職位剛好也是 AI 最能放大的職位，那麼企業在這些職位周圍做人力與工具配置調整的空間，理論上會變大。&lt;/p&gt;
&lt;p&gt;這裡比較穩妥的推論，不是「高薪者一定更安全」或「高薪者一定更危險」，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;某些高槓桿職位更可能成為 AI 投資的優先節點&lt;/li&gt;
&lt;li&gt;一旦這些節點的覆蓋範圍被放大，周邊部分工作的位置壓力可能跟著上升&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重點不在 AI 能做多少事，而在於它是否能在某些關鍵職位上形成足夠大的邊際增益。若答案是肯定的，可以推想企業較可能朝資源集中、節點化配置的方向調整；但這仍然只是組織推論，不是單靠這個簡化模型就能完全證出的結論。&lt;/p&gt;
&lt;h3 id=&#34;情境二技能拉平器&#34;&gt;情境二：技能拉平器&lt;/h3&gt;
&lt;p&gt;也有另一種完全不同的可能：AI 比較像一個「技能拉平器」——幫助最大的不是原本最強的人，而是原本較弱、較初階的人。&lt;/p&gt;
&lt;p&gt;2023 年，哈佛商學院與 BCG 合作的研究發現 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;：使用 AI 的顧問中，原本表現低於平均的人，生產力提升了 43%；而原本表現高於平均的人，只提升了 17%。&lt;/p&gt;
&lt;p&gt;這個結果至少提供了一個很強的線索：在某些任務環境下，AI 的效果可能比較像是在&lt;strong&gt;補強低於平均者&lt;/strong&gt;，而不只是放大原本最強的人。換句話說，資深員工本來就接近較高的人類表現水準，因此 AI 對他們的邊際補強未必那麼大；反而是初階員工，可能因為 AI 的輔助，快速從原本不穩定的狀態，被拉到接近可用的水準。&lt;/p&gt;
&lt;p&gt;如果把這個想法寫成一個簡化的線性假設，可以設：&lt;/p&gt;
$$
\phi = \frac{k}{w}, \qquad k&gt;0
$$&lt;p&gt;也就是薪資越低的職位，AI 帶來的生產力提升率越高。這裡的 $k$，可以理解成 AI 的「補強能力」：$k$ 越大，代表 AI 越能把較低技能者快速拉近可用水準。&lt;/p&gt;
&lt;p&gt;把這個關係代回替代率區間：&lt;/p&gt;
$$
\frac{C_{ai}}{w+C_{ai}} \le \rho \le \frac{k}{w+k}
$$&lt;p&gt;這會給出一個和前面幾乎相反的故事。&lt;/p&gt;
&lt;p&gt;對高薪、資深職位來說，當 $w$ 很大時，左邊的成本下限會趨近於 0，但更關鍵的是，右邊的產出上限 $\frac{k}{w+k}$ 也會趨近於 0。這代表在這個假設下，高薪資深職位的&lt;strong&gt;人力縮減空間&lt;/strong&gt;會顯著變小。企業如果想大幅裁撤這類人力，會更容易碰到產出下降的約束。&lt;/p&gt;
&lt;p&gt;相對地，對低薪、初階職位來說，當 $w$ 很小時，右邊的上限會快速逼近 1。這表示這些職位周圍的&lt;strong&gt;人力配置空間&lt;/strong&gt;會變得很大：企業既可能選擇用較少的人力、搭配 AI 維持原本產出，也可能反過來保留更多初階人力，利用 AI 把他們快速補到可用水準。&lt;/p&gt;
&lt;p&gt;光靠這個模型，還無法斷定哪一種策略一定會發生；但至少可以看出，&lt;strong&gt;壓力更可能先集中在初階職位周圍的配置方式，而不是直接集中在資深職位本身。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更有意思的是，在這個情境下重新檢視可行條件：&lt;/p&gt;
$$
\frac{C_{ai}}{w+C_{ai}} \le \frac{k}{w+k}
$$&lt;p&gt;化簡之後會得到：&lt;/p&gt;
$$
C_{ai} \le k
$$&lt;p&gt;工資 $w$ 竟然被消掉了。&lt;/p&gt;
&lt;p&gt;這代表，在這個很特定的假設下，導入 AI 的可行性不再直接取決於工資高低，而更取決於 AI 的底層補強能力 $k$，能不能蓋過它本身的成本 $C_{ai}$。&lt;/p&gt;
&lt;p&gt;如果 AI 真的是一種技能拉平器，那企業在意的就不再只是「人工貴不貴」，而會更接近這個問題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AI 到底能不能把原本沒那麼強的人，快速補到足夠有用的水準？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;同樣是導入-ai重整邏輯並不一樣&#34;&gt;同樣是導入 AI，重整邏輯並不一樣&lt;/h3&gt;
&lt;p&gt;把前面兩個情境放在一起看，差別就很清楚。&lt;/p&gt;
&lt;p&gt;如果 AI 比較像是菁英放大器，那它傾向擴大既有差異：原本就位在關鍵節點的人，被進一步放大，企業會更關心怎麼把工具集中到乘數效應最大的地方。&lt;/p&gt;
&lt;p&gt;如果 AI 比較像是技能拉平器，那它傾向壓縮既有差異：原本較弱的人被快速拉到可用水準，企業思考的重點就會從「把最強者再放大」轉成「如何重排團隊分工與梯隊結構」。&lt;/p&gt;
&lt;p&gt;所以，這兩種情境雖然都可能導向人力調整，但背後的組織邏輯其實不一樣：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前者比較像：&lt;strong&gt;把關鍵節點再放大&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;後者比較像：&lt;strong&gt;把原本較弱的人補到可用&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;真正重要的差別，不在於「誰一定會被裁」，而在於：&lt;strong&gt;AI 的增益，究竟是在放大既有優勢，還是在改寫能力分布。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不過，若把這個問題再往真實辦公室裡推一步，就會發現「技能拉平器」這條路徑還有另一層現實摩擦。數學上，它看起來給了企業更大的人力重整空間；但管理上，這個空間未必能被無摩擦地兌現。&lt;/p&gt;
&lt;h2 id=&#34;模型外的四種現實阻力&#34;&gt;模型外的四種現實阻力&lt;/h2&gt;
&lt;p&gt;如果只看前面的式子，「技能拉平器」這個情境會給企業一個很強的直覺：既然 AI 對初階人力的補強特別大，那麼企業似乎就有更大的空間，去重整初階與資深人力的比例。&lt;/p&gt;
&lt;p&gt;但把這個故事往現實再推一步，麻煩往往才真正開始。&lt;/p&gt;
&lt;p&gt;模型裡的「有效產出」雖然可以寫成一個乾淨的 $q$，但現實世界裡，企業要的從來不只是數量，還包括品質、判斷、自我校正能力，以及出錯時誰能發現、誰要負責。&lt;/p&gt;
&lt;p&gt;換句話說，前面的式子給的是一個&lt;strong&gt;可行區間的上限感&lt;/strong&gt;；一旦把管理摩擦放回來，真正可兌現的空間，通常只會更小，不會更大。&lt;/p&gt;
&lt;h3 id=&#34;品質門檻&#34;&gt;品質門檻&lt;/h3&gt;
&lt;p&gt;技能拉平器最容易讓人產生一種直覺：如果 AI 能把原本只有 50 分的人拉到 80 分，那麼企業就可以用更多「80 分的人」去取代少數「95 分的人」。&lt;/p&gt;
&lt;p&gt;但這件事未必成立。&lt;/p&gt;
&lt;p&gt;因為很多工作不是只要「差不多可用」就行，而是必須跨過某個品質門檻。對這些任務來說，80 分和 95 分不是線性差距，而是兩種不同性質的能力。例如底層系統架構設計、高風險決策、關鍵法務與合規判斷、涉及大量例外情境的專案協調，或錯誤代價極高的醫療、金融與安全場景。在這些地方，AI 把初階員工快速補到「看起來夠用」，不代表企業就真的得到了可託付的高品質人力。&lt;/p&gt;
&lt;p&gt;夠用不等於可託付，產出增加也不等於判斷力增加。這是「技能被拉近」和「責任能被轉移」之間最容易被忽略的一段距離。&lt;/p&gt;
&lt;h3 id=&#34;驗證成本&#34;&gt;驗證成本&lt;/h3&gt;
&lt;p&gt;模型裡的 $C_{ai}$ 看起來像工具成本。但現實裡還有一種常被低估的成本：驗證成本。&lt;/p&gt;
&lt;p&gt;初階員工在 AI 幫助下，的確可以更快產出程式碼、報告、簡報、分析與文件；但資深員工未必會因此更輕鬆，反而可能要花更多時間審查內容是否正確、檢查推理是否偷渡漏洞、修正 AI 生成的低階錯誤，甚至承擔最終交付的責任，控管幻覺、合規與聲譽風險。&lt;/p&gt;
&lt;p&gt;以軟體開發為例，junior 在 AI 協助下可以更快交出可執行的程式碼，但 senior 可能得花更多時間 review 架構一致性、邊界條件與安全問題。以顧問或分析工作來看，初稿速度變快，不代表最後判斷也能一樣快地放心交出去。&lt;/p&gt;
&lt;p&gt;這時候，AI 對初階人力的高增益，未必是純粹增加了有效產出，也可能只是把大量工時，從「生產」轉移成「檢查」與「收尾」。這是前端看不太到、但往往更昂貴的管理成本。&lt;/p&gt;
&lt;h3 id=&#34;人才梯隊&#34;&gt;人才梯隊&lt;/h3&gt;
&lt;p&gt;前面的模型本質上是一張靜態快照。它問的是：在當下這一刻，企業能不能在成本不升、產出不降的前提下，縮減一部分人力。&lt;/p&gt;
&lt;p&gt;但真實企業不是活在快照裡，而是活在時間裡。這正是技能拉平器最容易被低估的地方。&lt;/p&gt;
&lt;p&gt;如果企業看到的是：少數初階人力加上 AI，就能完成原本更多人才能完成的工作，那短期內它確實可能選擇大幅壓縮初階職位。但問題是，初階職位不只是當期產出單位，它同時也是未來資深人力的來源。&lt;/p&gt;
&lt;p&gt;很多行業裡，真正值錢的判斷力不是在課堂上養成的，而是在大量低難度、低風險、可犯錯的任務裡慢慢累積起來的。如果這些任務被 AI 吃掉，或這些位置被企業過度裁掉，那新人就會失去學習曲線，企業也會慢慢削弱自己的學徒制。&lt;/p&gt;
&lt;p&gt;所以，若把時間維度放進來，$\rho$ 就不再只是當期的人力縮減比例，而會影響企業未來的人才再生產能力。今天看似合理的縮編，幾年後可能變成資深人力斷層。&lt;/p&gt;
&lt;h3 id=&#34;市場競爭&#34;&gt;市場競爭&lt;/h3&gt;
&lt;p&gt;還有一個更外層、但也很現實的問題。&lt;/p&gt;
&lt;p&gt;如果 AI 真的是一種技能拉平器，不只是幫到了你，也同樣幫到了你的競爭對手，那麼它壓縮的就不只是公司內部的能力差距，也可能是整個市場裡的能力差距。&lt;/p&gt;
&lt;p&gt;當大家都能靠 AI 更快做出 80 分的東西，80 分本身就可能不再稀缺。&lt;/p&gt;
&lt;p&gt;此時，企業導入 AI，未必只是為了裁員省錢，更可能是為了要在更激烈的商品化競爭中存活下來。企業關心的，也就不再只是「總產出能不能不下降」，而可能變成：如果市場價格會因為能力拉平而下滑，我是不是必須讓產出成長得更快，甚至走出新的差異化路線，才能守住原本的利潤？&lt;/p&gt;
&lt;p&gt;這已經超出前面那個簡單模型能處理的範圍了，但它提醒我們一件事：AI 若真的在壓縮能力差距，最後改變的可能不只是人力結構，而是整個市場的競爭方式。&lt;/p&gt;
&lt;h2 id=&#34;當-ai-變強變便宜&#34;&gt;當 AI 變強、變便宜&lt;/h2&gt;
&lt;p&gt;綜合以上分析，可以得到一個相對穩健的結論：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;隨著 AI 變強，也就是 $\phi$ 上升，人力縮減比例的上限 $\frac{\phi}{1+\phi}$ 會上升。意思是：從產出角度來看，企業理論上可以承受更高的人力縮減比例。&lt;/li&gt;
&lt;li&gt;隨著 AI 變便宜，也就是 $C_{ai}$ 下降，人力縮減比例的下限 $\frac{C_{ai}}{w+C_{ai}}$ 會下降。意思是：從成本角度來看，導入 AI 這件事更容易成立。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，單就這個模型來看，AI 支持企業做人力調整的條件，理論上確實會越來越容易成立。&lt;/p&gt;
&lt;p&gt;但不能過度延伸。畢竟「調整空間變大」不等於「企業一定會大裁員」。企業也可能把 AI 用來擴大產出、降低價格、擴張市場，或者把人力移去新的流程、驗證、協作與管理工作。&lt;/p&gt;
&lt;p&gt;所以更精確的說法是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AI 越強、越便宜，企業用 AI 支持人力重配的條件越容易成立；但它最終走向縮編、擴編還是重組，取決於更完整的商業情境。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;結語回到約束條件與人力配置&#34;&gt;結語：回到約束條件與人力配置&lt;/h2&gt;
&lt;p&gt;回到最早那則裁員貼文，該問的其實不是「AI 到底有沒有搶工作」，而是：在這家公司裡，AI 是否真的讓「成本不升、產出不降」的人力重整變得可行。&lt;/p&gt;
&lt;p&gt;這也是本文想說的重點。AI 是否會導致人力縮減，不能只看技術展示，也不能只看新聞標題，而要看它能不能同時通過層層約束：工具成本撐不撐得住，產出守不守得住，而它的增益，究竟落在哪些人身上。&lt;/p&gt;
&lt;p&gt;一旦離開平均員工的世界，問題就不再只是 AI 強不強，而是它到底在放大既有優勢，還是在改寫能力分布。前者可能把組織推向更集中的節點配置，後者則可能帶來另一種重整邏輯，同時引進新的驗證成本、梯隊風險與管理負擔。&lt;/p&gt;
&lt;p&gt;所以，下一次再看到「AI 導致裁員」這種說法，先別急著下判斷。先問：它是否真的有可行區間？它省下的是成本，還是只是把成本換了位置？&lt;/p&gt;
&lt;h2 id=&#34;全文圖解&#34;&gt;全文圖解&lt;/h2&gt;
&lt;pre class=&#34;mermaid&#34;&gt;
  flowchart TD
    A[企業考慮導入 AI] --&amp;gt; B[基本問題：是否存在可行的人力縮減區間？]
    B --&amp;gt; C{是否滿足可行條件？&amp;lt;br/&amp;gt;φ ≥ C_ai / w}
    C -- 否 --&amp;gt; D[沒有可行解&amp;lt;br/&amp;gt;在此模型下，無法同時滿足：&amp;lt;br/&amp;gt;1. 總成本不增加&amp;lt;br/&amp;gt;2. 總有效產出不下降]
    D --&amp;gt; D1[結論：&amp;lt;br/&amp;gt;AI 可用，不代表足以支撐「減人又不傷產出」]
    C -- 是 --&amp;gt; E[存在可行區間]
    E --&amp;gt; E1[&amp;#34;人力縮減比例 ρ 必須落在：&amp;lt;br/&amp;gt;C_ai / (w + C_ai) ≤ ρ ≤ φ / (1 + φ)&amp;#34;]
    E1 --&amp;gt; F[&amp;#34;離開平均員工之後：&amp;lt;br/&amp;gt;AI 的增益會先落在哪些職位？&amp;#34;]
    F --&amp;gt; G[情境一：菁英放大器&amp;lt;br/&amp;gt;w ∝ φ]
    F --&amp;gt; H[情境二：技能拉平器&amp;lt;br/&amp;gt;φ ∝ 1 / w]
    G --&amp;gt; G1[高薪 / 高槓桿職位&amp;lt;br/&amp;gt;AI 增益更大]
    G1 --&amp;gt; G2[效果：&amp;lt;br/&amp;gt;局部可行配置空間拉大]
    G2 --&amp;gt; G3[可能推論：&amp;lt;br/&amp;gt;AI 投資更集中在關鍵節點]
    G2 --&amp;gt; G4[周邊部分工作&amp;lt;br/&amp;gt;位置壓力可能上升]
    H --&amp;gt; H1[低薪 / 初階職位&amp;lt;br/&amp;gt;AI 增益更大]
    H1 --&amp;gt; H2[效果：&amp;lt;br/&amp;gt;初階職位周圍的人力配置空間變大]
    H2 --&amp;gt; H3[可能結果 A：&amp;lt;br/&amp;gt;用更少初階人力 + AI 維持原產出]
    H2 --&amp;gt; H4[可能結果 B：&amp;lt;br/&amp;gt;保留更多初階人力，&amp;lt;br/&amp;gt;靠 AI 快速補到可用水準]
    H2 --&amp;gt; H5[額外條件：&amp;lt;br/&amp;gt;可行性更取決於 C_ai ≤ k]
    H2 --&amp;gt; I[但現實裡還有管理摩擦]
    I --&amp;gt; I1[品質門檻]
    I --&amp;gt; I2[驗證成本]
    I --&amp;gt; I3[人才梯隊]
    I --&amp;gt; I4[市場競爭]
    G4 --&amp;gt; Z[總結：&amp;lt;br/&amp;gt;AI 不只是「會不會取代人」&amp;lt;br/&amp;gt;而是會如何改寫企業的約束條件與人力配置]
    I4 --&amp;gt; Z
&lt;/pre&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;此處僅為示意估算。$C_{ai}=6k$ 新台幣，是根據 2026 年 3 月現行公告牌價，參照 Anthropic 的 Claude Max 20x 個人網頁版訂閱方案月費 US$200 粗略換算而來；實際成本仍會受匯率、稅額、地區計價與企業採購方式影響。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;哈佛商學院與 BCG 在 2023 年合作的研究報告 &amp;ldquo;&lt;a href=&#34;https://www.hbs.edu/faculty/Pages/item.aspx?num=64700&#34;&gt;Navigating the Jagged Technological Frontier&lt;/a&gt;&amp;rdquo; 說，&amp;ldquo;Consultants across the skills distribution benefited significantly from having AI augmentation, with those below the average performance threshold increasing by 43% and those above increasing by 17% compared to their own scores.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>AI 會寫程式，還要參與系統分析嗎？</title>
      <link>//william-yeh.net/post/2025/02/sa-with-genai/</link>
      <pubDate>Sat, 08 Feb 2025 18:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2025/02/sa-with-genai/</guid>
      
        <description>&lt;p&gt;傳統上，複雜的軟體專案，除了程式設計師之外，還會搭配系統設計師，甚至系統分析師，確保領域知識及商業邏輯都有朝對的方向前進。&lt;/p&gt;
&lt;p&gt;生成式 AI 既然會寫程式，下一個問題就是：它也會做系統分析嗎？&lt;/p&gt;
&lt;p&gt;理論上來說，應該是的。畢竟我們在&lt;a href=&#34;//william-yeh.net/post/2025/02/codegen-with-genai/&#34;&gt;前一篇文章&lt;/a&gt;都親眼看過，AI 既然能理解規格、潤飾需求、撰寫程式碼，甚至生成測試案例，那麼系統分析 (SA) 和系統設計 (SD) 這類「中間產物」，確實也難不倒它。畢竟，系統分析本質上就是資訊的整理、建模與推理，而這些都是 AI 擅長的領域。&lt;/p&gt;
&lt;p&gt;我認為，SA/SD 也應該納入 AI 協作。尤其是從 SA/SD 擅長的建模角度，能夠協助我們及早確認領域知識及商業邏輯，檢查需求規格是否有矛盾、遺漏或模稜兩可的地方，甚至提出改善建議，幫助系統分析師更快定位問題，減少後期開發的返工成本。譬如說，透過 AI 生成的狀態轉移圖，也有助於規劃黑箱測試，提高測試覆蓋率，進而提升系統的穩定性與可靠性。&lt;/p&gt;
&lt;p&gt;接下來就是現實問題了：讓 AI 產生的狀態圖，真的比人工畫得更好嗎？能省多少時間？&lt;/p&gt;
&lt;p&gt;這就要實測了！現在，就讓我們拿&lt;a href=&#34;//william-yeh.net/post/2025/02/codegen-with-genai/&#34;&gt;前一篇文章&lt;/a&gt;的規格作為引子，看看 AI 生成的狀態圖表現如何吧！&lt;/p&gt;
&lt;h2 id=&#34;狀況一過於窮舉&#34;&gt;狀況一：過於窮舉&lt;/h2&gt;
&lt;p&gt;提示詞 #1：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Generate a UML-style state diagram for the game.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;吐出的狀態圖，細節可能每次都有些不同，以下是較常見的版本：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/fsm-1.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/fsm-1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;嚴格說起來，這份狀態圖並不符合 UML 格式⋯⋯但我暫時不挑剔這一點，等最後一步再來處理。&lt;/p&gt;
&lt;p&gt;這份狀態圖，把所有可能的狀態都窮舉了，應該很合乎測試狂人的胃口。不過，窮舉得太過於累贅，很難消化。若不予以抽象化，很難進一步發展出程式。&lt;/p&gt;
&lt;h2 id=&#34;狀況二濃縮過度&#34;&gt;狀況二：濃縮過度&lt;/h2&gt;
&lt;p&gt;我們請 GenAI 整頓一下，在不影響正確性的前提下，將過於累贅的狀態精簡濃縮一遍：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Is it possible to reduce the states without compromising correctness or clarity?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;吐出的狀態圖，細節可能每次都有些不同，我挑出其中一個版本來聊聊：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/fsm-2.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/fsm-2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;有了這份濃縮過的狀態圖，就比較容易一眼看出問題。最大的問題就是，有兩個紅色箭頭的地方濃縮過頭了，誤把 2-0 及 0-2 比分判定為比賽結束。&lt;/p&gt;
&lt;h2 id=&#34;基本合格的狀態圖&#34;&gt;基本合格的狀態圖&lt;/h2&gt;
&lt;p&gt;我請 GenAI 修正三個地方：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Three issues need to be addressed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The “Px leads by 2 points” transition is too vague. Does it account for cases like 2-0 or 0-2?&lt;/li&gt;
&lt;li&gt;The two &amp;ldquo;Game Start&amp;rdquo; transitions should be merged into one.&lt;/li&gt;
&lt;li&gt;Add an initial state for the 0-0 (&amp;ldquo;Love-Love&amp;rdquo;) score.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;如此這般調整，通常我們很快就可以得到比較滿意的狀態圖，既清晰，又正確：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/fsm-3.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/fsm-3.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;轉換成機器可讀的版本&#34;&gt;轉換成機器可讀的版本&lt;/h2&gt;
&lt;p&gt;既然好不容易生出清晰正確的狀態圖，我們應該把圖形轉成像是 &lt;a href=&#34;https://plantuml.com/en/&#34;&gt;PlantUML&lt;/a&gt; 這種可程式化的文字表述形式，以預留後續應用的可能性。&lt;/p&gt;
&lt;p&gt;提示詞：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Proceed to represent the state diagram using PlantUML syntax.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我們會得到這樣的狀態圖規格文字：&lt;/p&gt;

&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    PlantUML 格式的狀態圖
    
  &lt;/summary&gt;
  &lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@startuml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[*] --&amp;gt; LoveLove : Game Start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LoveLove --&amp;gt; Score : P1 or P2 Scores
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score --&amp;gt; Score : Regular Scoring
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score --&amp;gt; Deuce : Both &amp;gt;= 3 &amp;amp; Equal
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Deuce --&amp;gt; AdvantageP1 : P1 Scores
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Deuce --&amp;gt; AdvantageP2 : P2 Scores
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score --&amp;gt; WinP1 : P1 &amp;gt;= 4 &amp;amp; Lead &amp;gt;= 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Score --&amp;gt; WinP2 : P2 &amp;gt;= 4 &amp;amp; Lead &amp;gt;= 2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AdvantageP1 --&amp;gt; WinP1 : P1 Scores
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AdvantageP2 --&amp;gt; WinP2 : P2 Scores
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AdvantageP1 --&amp;gt; Deuce : P2 Scores
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;AdvantageP2 --&amp;gt; Deuce : P1 Scores
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WinP1 --&amp;gt; [*]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;WinP2 --&amp;gt; [*]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@enduml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/details&gt;

&lt;p&gt;這份狀態圖以及 PlantUML 規格文字，很值得放進系統分析文件，甚至規格書。&lt;/p&gt;
&lt;p&gt;不過，如果你有潔癖，希望狀態圖要合乎正統的 UML 規定，可以把上面的文字丟到&lt;a href=&#34;https://www.plantuml.com/plantuml/uml/&#34;&gt;PlantUML 軟體&lt;/a&gt;去產生完全合乎標準的 UML 狀態圖：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/fsm-4.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/fsm-4.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;系統分析的再思&#34;&gt;系統分析的再思&lt;/h2&gt;
&lt;p&gt;許多威力強大的機器學習與人工智慧技術，本質上是黑箱的，可觀測性與可解釋性，一直是技術發展與推廣的大挑戰。&lt;/p&gt;
&lt;p&gt;對於 GenAI 神兵利器，許多人只在程式碼的層次與 GenAI 對話，畢竟光速產生程式的快感，很難不上癮。&lt;/p&gt;
&lt;p&gt;系統分析？很抱歉，這是光速領域，沒有預留座位。&lt;/p&gt;
&lt;p&gt;但我還是想要稍微保守一點，寧可慢一點。在前段的規格、中段的系統分析與設計、後段的測試驗收，與 GenAI 多一點協作，在中間產物身上，多留下一些可觀測、可解釋的線索，並力求可以穩定再現。&lt;/p&gt;
&lt;p&gt;畢竟，順向工程比較容易，逆向工程比較困難。如我前一篇文章〈&lt;a href=&#34;//william-yeh.net/post/2025/02/codegen-with-genai/&#34;&gt;當 AI 會寫程式，程式碼會變得即寫即棄嗎？&lt;/a&gt;〉所說，程式碼之所以會變得可以即寫即棄，是因為我們用更有效率的方式，將「可用的軟體」的內涵，轉寫到「詳盡的文件」裡面，讓它成為更有意義的 “ground truth”。&lt;/p&gt;
&lt;p&gt;在與 GenAI 協作時，別忘了「詳盡的文件」也是協作的重點。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>當 AI 會寫程式，程式碼會變得即寫即棄嗎？</title>
      <link>//william-yeh.net/post/2025/02/codegen-with-genai/</link>
      <pubDate>Fri, 07 Feb 2025 18:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2025/02/codegen-with-genai/</guid>
      
        <description>&lt;p&gt;人類從事的領域，不斷被生成式 AI (GenAI) 入侵。&lt;/p&gt;
&lt;p&gt;社群媒體上，早就充斥一大堆「AI 體」的文案圖案，現在就連程式設計領域也開始淪陷。像 Google 執行長就透露：「在 Google，超過 1/4 的新程式碼已經是先由 AI 生成，再讓程式設計師去複審與確認。」&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 而 GitHub 執行長更大膽預言 80% 的程式碼都將會由 GenAI 生成。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;也就是說，以前，程式設計師得親手撰寫大部分的程式碼；現在則開始挪出一段時間去跟 GenAI 對話：調教提示詞 (prompt)、審核生成的程式碼、確認正確性，如此反覆進行好幾個回合。&lt;/p&gt;
&lt;p&gt;GenAI 進展神速。如果某一天進展到，只要提示詞下得夠精準，第一次生出來的程式碼幾乎就合格過關了，是否也就意謂著，程式設計師的專業訓練及工作重點，將會更轉向 ⑴ 鑽研提示工程、⑵ 審核生成的程式碼這兩條路線發展？換句話說，將會更朝向 ⑴ 前段的需求規格、⑵ 後段的測試驗收這兩條路線？&lt;/p&gt;
&lt;p&gt;如果頭尾兩端（需求規格與測試驗收）都由人來看守定義，中間步驟（撰寫程式碼）改由 GenAI 來操刀，是否也就意謂著，程式碼會變成像是可拋棄的東西，反正隨時都可以叫 GenAI 再生出一份出來？甚至當 GenAI 能力升級之後，又能夠生出比拋棄掉的還要更好的程式碼？&lt;/p&gt;
&lt;p&gt;聽起來可能有點兒瘋狂。可是如果以上屬實，那麼，&lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;敏捷四大宣言&lt;/a&gt;之一「&lt;strong&gt;可用的軟體&lt;/strong&gt; 重於 &lt;strong&gt;詳盡的文件&lt;/strong&gt;」，在 GenAI 時代是否依然成立，可能都值得再重新評估檢討。&lt;/p&gt;
&lt;p&gt;為此，我在 ChatGPT 4o 進行一系列小小的實驗。試試看當 GenAI 收到前段的需求規格之後，能夠生出什麼樣的程式碼以及測試驗收案例；緊接著會與 GenAI 協作調教頭尾兩端（需求規格與測試驗收），再看看 GenAI 重新生出來的程式碼，會有什麼不同。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/work-with-genai.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/work-with-genai.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;實驗素材&#34;&gt;實驗素材&lt;/h2&gt;
&lt;p&gt;我選用 TDD 社群常見的 Tennis Kata 作為實驗素材。
為了怕 GenAI 早已被餵食過 Tennis Kata，想也不想就直接吐出記憶中的標準答案，也就是所謂的「資料記憶」問題，我稍加修改 Samman Technical Coaching 提供的 &lt;a href=&#34;https://sammancoaching.org/kata_descriptions/tennis.html&#34;&gt;Tennis Kata 版本&lt;/a&gt;。微調過的文字如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The rule of the 2-player game &amp;ldquo;Sinnet&amp;rdquo; is summarized below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A game is won by the first player to have won at least four points in total and at least two points more than the opponent.&lt;/li&gt;
&lt;li&gt;The running score of each game is described in a manner peculiar to this: scores from zero to three points are described as “Love”, “Fifteen”, “Thirty”, and “Forty” respectively.&lt;/li&gt;
&lt;li&gt;If at least three points have been scored by each player, and the scores are equal, the score is “Deuce”.&lt;/li&gt;
&lt;li&gt;If at least three points have been scored by each side and a player has one more point than his opponent, the score of the game is “Advantage” for the player in the lead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;為了進一步消除資料記憶的疑慮，我也故意翻譯成中文（儘管在 ChatGPT 大神面前，這麼做未必真的有用，哈）：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;以下是二人遊戲 &amp;ldquo;Sinnet&amp;rdquo; 的規則：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;遊戲由首先贏得至少四分，且比對手多至少兩分的玩家獲勝。&lt;/li&gt;
&lt;li&gt;每局的進行得分以一種特殊的方式描述：從零到三分分別描述為 “Love”、 “Fifteen”、 “Thirty” 和 “Forty”。&lt;/li&gt;
&lt;li&gt;如果每位玩家至少得了三分，且比分相同，則比分為 “Deuce”。&lt;/li&gt;
&lt;li&gt;如果每方至少得了三分，且有一名玩家比對手多一分，則領先玩家的比分為 “Advantage”。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;接下來的前幾個實驗，都會以這段文字作為對話的開始，姑且就把它叫做「&lt;strong&gt;初始規格/v1&lt;/strong&gt;」吧。不過，GenAI 有一些隨機性的行為，不一定每次都會得到一樣的結果，我會挑出較具代表性的來探討。&lt;/p&gt;
&lt;p&gt;系列實驗如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;🅐 基礎實驗：①給初始規格/v1 ❯ ②生成程式及測試&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🅑 調整規格：①給初始規格/v1 ❯ ③調整規格/v2 ❯ ④生成程式及測試&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🅒 可執行的規格：①給初始規格/v1 ❯ ③調整規格/v2 ❯ ④生成程式及測試 ❯ ⑤將測試納入規格/v3&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🅓 測試驅動：⑥根據規格/v3 重新生成程式，並予以測試檢驗&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🅔 逆向工程：⑥根據規格/v3 重新生成程式，並予以測試檢驗 ❯ ⑦逆向工程規格/v4&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有些實驗之間有先後關係，有些實驗需要開啟新的對話：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/flow-all.png&#34; alt=&#34;整體實驗流程&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/flow-all.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;整體實驗流程&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;實驗基礎實驗&#34;&gt;實驗🅐、基礎實驗&lt;/h2&gt;
&lt;p&gt;先從最基礎的實驗開始，直接叫 GenAI 根據我們給的初始規格，生成程式及測試。&lt;/p&gt;
&lt;p&gt;基礎的實驗步驟如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;①給初始規格/v1&lt;/li&gt;
&lt;li&gt;②生成程式及測試&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/flow-a.png&#34; alt=&#34;實驗🅐流程&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/flow-a.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗🅐流程&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;既然要叫 GenAI 生成測試，就順便叫它用比較好的方式來做：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.amazon.com/dp/1617290084&#34;&gt;&lt;em&gt;Specification by Example&lt;/em&gt;&lt;/a&gt; 提到的 BDD (behavior driven design)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.amazon.com/dp/1633439933&#34;&gt;&lt;em&gt;Effective Software Testing&lt;/em&gt;&lt;/a&gt; 提到的 spec-based &amp;amp; property-based testing 角度以及 AAA (arrange-act-assert) 手法。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;提示詞②如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Now, implement a Python program to display the current game score.  Also, create specification-based tests using BDD-style and property-based testing. Each test case should follow the Arrange-Act-Assert (AAA) pattern, ensuring that only one AAA scenario is included per test case. Place Gherkin descriptions at the beginning of each test case using a docstring, annotation, or function name. Ensure these tests cover normal scenarios as well as edge cases, focusing on boundaries, partitions, and input dependencies.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;吐出的主體程式碼，細節可能每次都有些不同，以下是較常見的版本：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/code-a1.png&#34; alt=&#34;提示詞②產生的主體程式碼&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/code-a1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;提示詞②產生的主體程式碼&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;主體程式碼看起來滿樸素的，程式邏輯大體上也是圍繞在初始規格的直接翻譯。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;吐出的測試案例，每次的差異就比較大了，以下是其中一個版本：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/code-a2.png&#34; alt=&#34;提示詞②產生的測試&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/code-a2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;提示詞②產生的測試&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;形式上 OK，只是我認為還有些缺失：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;對於 deuce 的比分，常常只測到 3-3 的情況，沒有進一步嘗試 4-4、5-5 甚至更多。這應該是 property-based testing 的強項。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 arrange 及 act 階段，常常少了交錯得分的劇情，譬如說像是 0-0 ❯ 1-0 ❯ 2-0 ❯ 2-1 ❯ 3-1 ❯ 3-2 ❯ 3-3 (deuce) ❯ 3-4 ❯ 4-4 (deuce) 這種緊張的情節。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Property-based testing 有點偷懶。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;實驗調整規格&#34;&gt;實驗🅑、調整規格&lt;/h2&gt;
&lt;p&gt;我們一開始給的初始規格/v1，可能未必是最好的。這一次，讓我們邀請 AI 對我們提出疑問，一起協力把初始規格調整成較清晰、無歧義的內容，再拿這份調整過的規格去生成程式與測試。&lt;/p&gt;
&lt;p&gt;調整規格的實驗步驟如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;①給初始規格/v1&lt;/li&gt;
&lt;li&gt;③調整規格/v2&lt;/li&gt;
&lt;li&gt;④生成程式及測試&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/flow-b.png&#34; alt=&#34;實驗🅑流程&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/flow-b.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗🅑流程&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;提示詞③如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Now, you can ask me questions about the previous specification to clarify its meaning and remove any ambiguity. If you don&amp;rsquo;t have any questions, please proceed to rephrase the specification for better clarity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;有時候，GenAI 的確會與我一來一往對話，請我釐清一些細節。&lt;/p&gt;
&lt;p&gt;最後，我收到一份更清晰易懂的規格（就把它叫做「規格/v2」吧）：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sinnet Game Rules&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Winning the Game&lt;/strong&gt;: A player wins by reaching at least four points and leading their opponent by at least two points.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scoring System&lt;/strong&gt;: Points are described using specific terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;0 points → “Love”&lt;/li&gt;
&lt;li&gt;1 point → “Fifteen”&lt;/li&gt;
&lt;li&gt;2 points → “Thirty”&lt;/li&gt;
&lt;li&gt;3 points → “Forty”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deuce&lt;/strong&gt;: If both players have at least three points and are tied, the score is called “Deuce.”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Advantage&lt;/strong&gt;: If both players have at least three points, and one player leads by a single point, their score is called “Advantage.”&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;接下來，讓我們根據這份調整過的 規格/v2，試試看 GenAI 有什麼不一樣的產出？&lt;/p&gt;
&lt;p&gt;提示詞④如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Based on the rephrased specification, implement a Python program to display the current game score.
Also create specification-based tests using BDD-style and property-based testing. Each test case should follow the Arrange-Act-Assert (AAA) pattern, ensuring that only one AAA scenario is included per test case. Place Gherkin descriptions at the beginning of each test case using a docstring, annotation, or function name. Ensure these tests cover normal scenarios as well as edge cases, focusing on boundaries, partitions, and input dependencies.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;吐出的主體程式碼，細節可能每次都有些不同，以下是較常見的版本：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/code-b1.png&#34; alt=&#34;提示詞④產生的主體程式碼&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/code-b1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;提示詞④產生的主體程式碼&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;或許要歸功於調整後的 規則/v2 較清晰易懂，程式邏輯也隨之變得更清晰易懂。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;有時候我不滿意生成的測試案例，會叫它再做一次，加強測試涵蓋率。譬如說，如果它只考慮到 3-3 這個 deuce 情況，我也會叫它再多想一下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Have you considered that deuce can also occur at 4-4, 5-5, and beyond? This appears to be a strong candidate for property-based testing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這階段，我建議要跟 GenAI 多聊幾次，先一起弄出令人滿意的測試集，以作為下一個實驗的基礎。&lt;/p&gt;
&lt;p&gt;以下是其中一個版本：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/code-b2.png&#34; alt=&#34;提示詞④產生的測試&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/code-b2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;提示詞④產生的測試&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;看起來還不錯。我們可以繼續往下進行最關鍵的實驗了。&lt;/p&gt;
&lt;h2 id=&#34;實驗可執行的規格&#34;&gt;實驗🅒、可執行的規格&lt;/h2&gt;
&lt;p&gt;在前一個實驗中，我們和 GenAI 一起調整出較清晰易讀的 規格/v2，也一起調整出較周全的測試集。以敏捷開發陣營的最佳實踐來說，好的測試集，其實是可以逆向反饋到規格的，也就是所謂的「&lt;strong&gt;可執行的規格&lt;/strong&gt;」(&lt;strong&gt;executable specification&lt;/strong&gt;)。現在，我們就來弄出一份這樣的「規格/v3」吧。&lt;/p&gt;
&lt;p&gt;「可執行的規格」實驗步驟如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;①給初始規格/v1&lt;/li&gt;
&lt;li&gt;③調整規格/v2&lt;/li&gt;
&lt;li&gt;④生成程式及測試&lt;/li&gt;
&lt;li&gt;⑤將測試納入規格/v3 ◄ 承上步驟，從這裡開始。&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/flow-c.png&#34; alt=&#34;實驗🅒流程&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/flow-c.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗🅒流程&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;接續前一個實驗累積的測試集，讓我們請 GenAI 幫我們逆向轉譯為 Gherkin 形式的規格。&lt;/p&gt;
&lt;p&gt;提示詞⑤如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Now, incorporate the newly generated tests (including property-based tests) into the specification under a section titled &amp;ldquo;Validation Scenarios,&amp;rdquo; expressed in Gherkin format. This will make the specification more comprehensive and allow it to function as an &amp;ldquo;executable specification.&amp;rdquo; Finally, add the test codes in an appendix section titled &amp;ldquo;Tests.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最後會孵化出這樣的「規格/v3」：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sinnet Game Specification&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;▋ GAME RULES&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Winning the Game&lt;/strong&gt;: A player wins by reaching at least four points and leading their opponent by at least two points.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Scoring System&lt;/strong&gt;: Points are described using specific terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;0 points → “Love”&lt;/li&gt;
&lt;li&gt;1 point → “Fifteen”&lt;/li&gt;
&lt;li&gt;2 points → “Thirty”&lt;/li&gt;
&lt;li&gt;3 points → “Forty”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deuce&lt;/strong&gt;: If both players have at least three points and are tied, the score is called “Deuce.”&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Advantage&lt;/strong&gt;: If both players have at least three points, and one player leads by a single point, their score is called “Advantage.”&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;▋ VALIDATION SCENARIOS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Normal Gameplay Scenarios&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Scenario: Initial game score is &amp;ldquo;Love - Love&amp;rdquo;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given a new game has started&lt;/li&gt;
&lt;li&gt;When no player has scored&lt;/li&gt;
&lt;li&gt;Then the score should be &amp;ldquo;Love - Love&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scenario: A player scores first&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given a new game has started&lt;/li&gt;
&lt;li&gt;When a player scores once&lt;/li&gt;
&lt;li&gt;Then the score should reflect the correct score for that player&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scenario: A player gains advantage&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given both players have scored at least three times&lt;/li&gt;
&lt;li&gt;When a player scores once more&lt;/li&gt;
&lt;li&gt;Then the score should be &amp;ldquo;Advantage&amp;rdquo; for that player&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scenario: A player wins the game&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given a player has three points and the other player has less than three points&lt;/li&gt;
&lt;li&gt;When the player scores the winning point&lt;/li&gt;
&lt;li&gt;Then the player should be declared the winner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scenario: A player wins after having advantage&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given a player has advantage&lt;/li&gt;
&lt;li&gt;When the player scores one more point&lt;/li&gt;
&lt;li&gt;Then the player should be declared the winner&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scenario: A player gains advantage from deuce&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given the score is deuce&lt;/li&gt;
&lt;li&gt;When a player scores a point&lt;/li&gt;
&lt;li&gt;Then the score should be &amp;ldquo;Advantage&amp;rdquo; for that player&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Edge Cases and Property-Based Testing&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Scenario: Deuce occurs at 3-3, 4-4, 5-5, and beyond&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given both players have the same score of at least 3 points&lt;/li&gt;
&lt;li&gt;When the scores are equal&lt;/li&gt;
&lt;li&gt;Then the score should be &amp;ldquo;Deuce&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Property-Based Test: Deuce should occur at 3-3, 4-4, 5-5, and beyond&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Given both players have at least 3 points and the same score&lt;/li&gt;
&lt;li&gt;When the scores are equal&lt;/li&gt;
&lt;li&gt;Then the score should be &amp;ldquo;Deuce&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;▋ APPENDIX: TESTS&lt;/strong&gt;
[測試規格如下]

&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    Python 版的測試規格
    
  &lt;/summary&gt;
  &lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; pytest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; hypothesis &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; given, strategies &lt;span style=&#34;color:#66d9ef&#34;&gt;as&lt;/span&gt; st
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_initial_score&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Scenario: Initial game score is &amp;#34;Love - Love&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Given a new game has started
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    When no player has scored
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Then the score should be &amp;#34;Love - Love&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; SinnetGame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;score() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Love - Love&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_player1_scores_once&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Scenario: Player 1 scores first
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Given a new game has started
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    When Player 1 scores once
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Then the score should be &amp;#34;Fifteen - Love&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; SinnetGame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;score() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Fifteen - Love&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_deuce_extended&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Scenario: Deuce occurs at 3-3, 4-4, 5-5, and beyond
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Given both players have the same score of at least 3 points
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    When the scores are equal
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Then the score should be &amp;#34;Deuce&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; score &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; SinnetGame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;scores &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [score, score]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;score() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Deuce&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_advantage_player1&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Scenario: Player 1 gains advantage
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Given both players have scored at least three times
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    When Player 1 scores once more
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Then the score should be &amp;#34;Advantage Player 1&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; SinnetGame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; _ &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;score() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Advantage Player 1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_player1_wins&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Scenario: Player 1 wins the game
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Given Player 1 has three points and Player 2 has less than three points
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    When Player 1 scores the winning point
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Then Player 1 should be declared the winner
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; SinnetGame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; _ &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;score() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Player 1 wins&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_transition_from_advantage_to_win&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Scenario: Player 1 wins after having advantage
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Given Player 1 has advantage
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    When Player 1 scores one more point
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Then Player 1 should be declared the winner
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; SinnetGame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; _ &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;score() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Player 1 wins&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_transition_from_deuce_to_advantage&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Scenario: Player 2 gains advantage from deuce
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Given the score is deuce
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    When Player 2 scores a point
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Then the score should be &amp;#34;Advantage Player 2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; SinnetGame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; _ &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;player_scores(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;score() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Advantage Player 2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;@given&lt;/span&gt;(st&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;integers(min_value&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;, max_value&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;test_deuce_property_based&lt;/span&gt;(score):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Property-based test: Deuce should occur at 3-3, 4-4, 5-5, and beyond
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Given both players have at least 3 points and the same score
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    When the scores are equal
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    Then the score should be &amp;#34;Deuce&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; SinnetGame()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;scores &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [score, score]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;assert&lt;/span&gt; game&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;score() &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Deuce&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/details&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這份「規格/v3」，不僅有規格文章，還有測試集，又臭又長，要是換成是我自己一個人來寫，我多半沒這個耐心。&lt;/p&gt;
&lt;p&gt;你可能會懷疑：比起之前的「初始規格/v1」及「調整規格/v2」，這份孵化出來的「規格/v3」是否真的有獨到之處？&lt;/p&gt;
&lt;p&gt;且讓我們繼續看下去。&lt;/p&gt;
&lt;h2 id=&#34;實驗測試驅動&#34;&gt;實驗🅓、測試驅動&lt;/h2&gt;
&lt;p&gt;在前一個實驗中，我們和 GenAI 一起孵化出「可執行的規格」。現在，我們就來根據這份「規格/v3」開啟全新的對話，叫 GenAI 重新生成程式，並根據「規格/v3」附錄的測試集予以測試檢驗。&lt;/p&gt;
&lt;p&gt;且讓我們評估看看究竟值不值得如此大費周章。&lt;/p&gt;
&lt;p&gt;測試驅動的實驗步驟如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;①給初始規格/v1 ❯ ③調整規格/v2 ❯ ④生成程式及測試 ❯ ⑤將測試納入規格/v3 ◄ 之前的步驟&lt;/li&gt;
&lt;li&gt;⑥根據規格/v3 重新生成程式，並予以測試檢驗 ◄ 現在的步驟&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;請 GenAI 開啟全新的對話，用這份熱騰騰的「規格/v3」重新生成程式。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/flow-d.png&#34; alt=&#34;實驗🅓流程&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/flow-d.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗🅓流程&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;提示詞⑥如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Now, generate a Python program based on the following specification. [貼上 規格/v3 全文]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;吐出的主體程式碼，細節可能每次都有些不同，以下是較常見的版本：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/code-d1.png&#34; alt=&#34;提示詞⑥產生的主體程式碼&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/code-d1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;提示詞⑥產生的主體程式碼&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;GenAI 有隨機性行為，未必每次都會比根據之前兩份規格（初始規格/v1 及 調整規格/v2）產生的程式表現得更好，但至少這是可以通過測試的。萬一通不過測試，大可叫 GenAI 去 debug。這就是我們之前與 AI 協作，努力調教頭尾兩端（需求規格與測試驗收）的好處。只要向 AI 指出這項錯誤，它就會乖乖認錯，並且自動 debug。&lt;/p&gt;
&lt;p&gt;只要程式是正確的，隨時都可以叫 GenAI 去重構，重構到滿意為止，如此即可兼顧正確性與各種內在品質標準。&lt;/p&gt;
&lt;p&gt;這就是當初在「規格/v3」埋下「可執行的規格」伏筆的好處。&lt;/p&gt;
&lt;h2 id=&#34;實驗逆向工程&#34;&gt;實驗🅔、逆向工程&lt;/h2&gt;
&lt;p&gt;敏捷宣言說：「&lt;strong&gt;可用的軟體&lt;/strong&gt; 重於 &lt;strong&gt;詳盡的文件&lt;/strong&gt;」。我們想看看，GenAI 是否真的能夠從「可用的軟體」逆向工程出「詳盡的文件」，讓我們評估兩者究竟誰比較重要，誰可以當成 “ground truth”。&lt;/p&gt;
&lt;p&gt;逆向工程的實驗步驟如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⑥根據規格/v3 重新生成程式，並予以測試檢驗 ◄ 之前的步驟&lt;/li&gt;
&lt;li&gt;⑦逆向工程規格/v4 ◄ 現在的步驟&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2025/02/flow-e.png&#34; alt=&#34;實驗🅔流程&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2025/02/flow-e.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗🅔流程&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;請 GenAI 開啟全新的對話，拿前一個實驗的程式碼及測試，請它設法轉譯成人類的語言。&lt;/p&gt;
&lt;p&gt;提示詞⑦如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Generate a specification based on the following Python code and tests. The specification should include two sections: 1. Sinnet Game Rules – Clearly structured and expressed in natural language. 2. Validation Scenarios – Presented in Gherkin format.  [附上主體程式碼及測試]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我驚訝的發現，GenAI 劈頭就給我這麼一句話：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Sinnet Game is a simplified scoring system inspired by tennis. The objective is for a player to win by reaching at least four points and having a two-point lead over the opponent.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;看起來，可能是程式碼寫得太好了，測試寫得太好了，變數及函式名稱取得太好了，註解寫得太好了，讓 GenAI 有足夠的線索察覺到，這和現實世界的網球規則高度雷同。&lt;/p&gt;
&lt;p&gt;這也證明了，清晰易懂的程式碼，不僅讓人類舒服，連 GenAI 也受益。&lt;/p&gt;
&lt;h2 id=&#34;敏捷的再思&#34;&gt;敏捷的再思&lt;/h2&gt;
&lt;p&gt;同樣的武器，在高手與菜鳥手上，能玩出的花樣自然會有高低落差之別。&lt;/p&gt;
&lt;p&gt;儘管高手是草木竹石均可為劍的；但善用好的武器，能讓我們付出較少的精力，就做出近似高手的表現。&lt;/p&gt;
&lt;p&gt;怎麼樣善用 GenAI 這項神兵利器？&lt;/p&gt;
&lt;p&gt;前面幾個實驗中，儘管 GenAI 看起來非常厲害，但是別忘了，我所下的提示詞，其實已經將人類在程式設計領域的經驗高度濃縮進去。缺少這些知識，未必能夠和 GenAI 一來一往充分協作出好的成果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Executable specification 很重要。&lt;/li&gt;
&lt;li&gt;Specification-based testing 很重要。&lt;/li&gt;
&lt;li&gt;Property-based testing 很重要。&lt;/li&gt;
&lt;li&gt;AAA (arrange-act-assert) 很重要。&lt;/li&gt;
&lt;li&gt;Refactoring 很重要。&lt;/li&gt;
&lt;li&gt;Shift-left 很重要。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些，其實都是敏捷開發領域一向重視的實踐。&lt;/p&gt;
&lt;p&gt;因此，在 GenAI 時代，就算敏捷四大宣言之一「&lt;strong&gt;可用的軟體&lt;/strong&gt; 重於 &lt;strong&gt;詳盡的文件&lt;/strong&gt;」未必依然成立，但那也是因為藉由 GenAI 之力，我們終於可以把「可用的軟體」的內涵，用更有效率的方式轉寫到「詳盡的文件」裡面，讓它成為更有意義的 “ground truth”。&lt;/p&gt;
&lt;p&gt;不是因為敏捷宣言過時了，而是 GenAI 成全了敏捷宣言。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;根據 Google CEO 在 &lt;a href=&#34;https://blog.google/inside-google/message-ceo/alphabet-earnings-q3-2024/&#34;&gt;(2024) Q3 earnings call: CEO’s remarks&lt;/a&gt; 的說法：“Today, more than a quarter of all new code at Google is generated by AI, then reviewed and accepted by engineers. This helps our engineers do more and move faster.”&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;GitHub CEO 在 2023 年中一場&lt;a href=&#34;https://www.freethink.com/robots-ai/github-copilot&#34;&gt;專訪&lt;/a&gt;時，大膽預言：“Sooner than later, 80% of the code is going to be written by Copilot.”&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>務實的長期主義路線——《多團隊高效協作密技》推薦序</title>
      <link>//william-yeh.net/post/2024/08/less-book-review/</link>
      <pubDate>Wed, 28 Aug 2024 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2024/08/less-book-review/</guid>
      
        <description>&lt;p&gt;「敏捷」這概念，台灣很晚才起步。&lt;/p&gt;
&lt;p&gt;儘管敏捷宣言 (&lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;&lt;em&gt;The Agile Manifesto&lt;/em&gt;&lt;/a&gt;) 早在 2001 年就問世，可是在台灣，如果以 &lt;a href=&#34;https://agile3uncles.com/&#34;&gt;David Ko&lt;/a&gt; 在 2014 年首次舉辦的 Agile Tour Taipei 活動作為開端，「敏捷」開始成為台灣業界的話題，大概也不過十年。&lt;/p&gt;
&lt;p&gt;於是，在國外早已經百家爭鳴的「大規模敏捷」流派（連 SAFe 都出到 6.0 版了呢），在台灣，直到近年才零零星星有人談到這議題。&lt;/p&gt;
&lt;p&gt;大規模敏捷的各家流派，多半是從 Scrum 之類的原型出發。但 LeSS 與眾不同的是，它非常謹慎自制，避免在規模化過程中引進無謂的複雜。&lt;/p&gt;
&lt;p&gt;就如同《&lt;a href=&#34;https://www.tenlong.com.tw/products/9786263339514&#34;&gt;多團隊高效協作密技&lt;/a&gt;》所說：「&lt;strong&gt;規模化，不是角色變多、流程變複雜，而是協作方式的改變&lt;/strong&gt;。LeSS 的導入，難處都不在 LeSS 的流程，而是在&lt;strong&gt;環境&lt;/strong&gt;與&lt;strong&gt;人&lt;/strong&gt;的不配合。」因此，想學習 LeSS，重點不要只放在流程上，應該更留意探討這些協作、環境、人的議題。這才是形塑 LeSS 的關鍵驅力。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:10em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2024/08/less-book-david.jpg&#34; alt=&#34;《多團隊高效協作密技：大規模敏捷開發方法 Large Scale Scrum 簡單學》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2024/08/less-book-david.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《多團隊高效協作密技：大規模敏捷開發方法 Large Scale Scrum 簡單學》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;初次接觸 LeSS 的人，常會對於 LeSS 某些違反直覺之處感到不解。譬如說，one product backlog 已經夠另類了，「讓團隊主動向利害關係人釐清需求」衝擊一般人對於 PO 的 R&amp;amp;R 認知，「最大化團隊之間的同步相依性」更是激進。&lt;/p&gt;
&lt;p&gt;帶著這些疑惑，2017 年我在江湖人稱「大師兄」&lt;a href=&#34;https://less.works/profiles/yi-lv&#34;&gt;呂毅&lt;/a&gt;的 LeSS 課堂上，親身體驗 LeSS 的解題思路：運用系統思考方法，剖析不同措施各自的短期與長期效應。如此思辯推演下來，就能瞭解 LeSS 如此主張的用意。&lt;/p&gt;
&lt;p&gt;LeSS 走的是&lt;strong&gt;務實的長期主義路線&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;LeSS 還有另一個與眾不同的地方。它並不是單純只站在管理者及管顧的角度，而是從第一線開發者的實踐視角，用數百個小實驗來支持 LeSS 的主張。&lt;/p&gt;
&lt;p&gt;實踐心得很重要，畢竟「敏捷」是一種較仰賴經驗主義的路線，較難有定於一尊的情況。有了實踐的脈絡，能讓我們知道，哪些是 must have，哪些是 nice to have。更重要的是，每一項實踐手法背後的 why 是什麼，以及，當面臨不同的現實限制，還有什麼替代方案可以嘗試。像《&lt;a href=&#34;https://www.tenlong.com.tw/products/9786263339514&#34;&gt;多團隊高效協作密技&lt;/a&gt;》第十章在談 LeSS 的「最大化團隊之間的同步相依性」主張時，不只是用系統思考的道理來分析，還提出超過 10 種方法來促進這件事情的效果。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這本書有很多小故事、小實踐、小心法，即使不是跑大規模敏捷，即使不是跑 LeSS，也都相當有參考價值。它們背後都是有深刻的系統思考與具體的實驗佐證。&lt;/p&gt;
&lt;p&gt;我很享受閱讀這本書，願你也能享受此樂趣。&lt;/p&gt;
&lt;p&gt; 　 　 　 　 　 　—— 敏捷魔藥師　葉秉哲 (William Yeh)　2024-08-28&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>換個 Design for Ops 的腦袋——《SRE 工作現場直擊》推薦序</title>
      <link>//william-yeh.net/post/2024/08/sre-story-review/</link>
      <pubDate>Wed, 14 Aug 2024 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2024/08/sre-story-review/</guid>
      
        <description>&lt;p&gt;全球都在享用 Google 首屈一指的線上服務群，但直到他們在 2016 年出版了 &lt;a href=&#34;https://sre.google/books/&#34;&gt;&lt;em&gt;Site Reliability Engineering&lt;/em&gt;&lt;/a&gt; 一書，世人才第一次全面認識到該如何支持這種深度廣度的系統維運。&lt;/p&gt;
&lt;p&gt;全球性線上服務系統，規模與複雜度遽增，只靠傳統的人力或獸力是無法長久維運下去的。面對這問題，擁有第一流軟體研發能量的 Google，大膽拋開傳統作法，改從一個獨特的提問出發：「如果我們賦予軟體研發工程師一個任務，讓他們有機會從頭去設計維運系統，那會是什麼模樣？」&lt;/p&gt;
&lt;p&gt;更進一步的提問是：「如果我們限制他們最多只能投入 50% 的時間在維運上，那會是怎麼樣的工作方式？」&lt;/p&gt;
&lt;p&gt;從這角度出發，便是目前我們現在看到的 SRE。&lt;/p&gt;
&lt;p&gt;  &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;SRE 的日常，一部分是演繹法，試圖以堅實的軟體工程技術出發，去解決傳統維運僅靠人力獸力導致的低效與無趣。於是乎，我們看到許多從 SRE 角度發展出來的觀念、原則、流程與實踐。&lt;/p&gt;
&lt;p&gt;SRE 的日常，另一部分則是歸納法，試圖從一次次棘手難堪的出包事件出發，透過鍥而不捨的毅力與求知慾，將系統改善得更強韌。要做到這一點並不容易，「不咎責文化」更是重要的土壤。&lt;/p&gt;
&lt;p&gt;演繹法的 SRE 資料已經很多了，說教意味濃厚的甚至帶給人距離感；歸納法的 SRE 資料則非常稀少。這也是《&lt;a href=&#34;https://www.tenlong.com.tw/products/9786263339347&#34;&gt;SRE 工作現場直擊&lt;/a&gt;》這本書令人驚艷之處：接地氣的實務案例，彷彿在看一本故事書。尤其對於曾經身處同一產業的我來說，字字句句真的都是 SRE 血淚心得。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:10em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2024/08/book-sre-examples.jpg&#34; alt=&#34;《SRE 工作現場直擊》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2024/08/book-sre-examples.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《SRE 工作現場直擊》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;我鼓勵你，邊看這本書，邊設想：換做是你，會如何面對這些事件？又會如何以 SRE 角度去改善系統，以避免問題、及早偵測問題、讓系統用最有效率的方式復歸？&lt;/p&gt;
&lt;p&gt;好好思考這些，design for ops，將提高你的系統架構實力。&lt;/p&gt;
&lt;p&gt; 　 　 　 　 　 　—— 敏捷魔藥師　葉秉哲 (William Yeh)　2024-08-14&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>從系統思考角度談 DevOps 三步工作法</title>
      <link>//william-yeh.net/post/2024/07/dissecting-devops-via-systems-thinking/</link>
      <pubDate>Thu, 11 Jul 2024 16:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2024/07/dissecting-devops-via-systems-thinking/</guid>
      
        <description>&lt;p&gt;今天在 &lt;a href=&#34;https://devopsdays.tw/2024/&#34;&gt;DevOpsDays Taipei 2024&lt;/a&gt; 給了一場 Keynote Speech：【從系統思考角度談 DevOps 三步工作法】。
​
事情的緣由是這樣的。&lt;/p&gt;
&lt;p&gt;艦長想在 &lt;a href=&#34;https://devopsdays.tw/2024/&#34;&gt;DevOpsDays Taipei 2024&lt;/a&gt; 繼續開設廣受好評的新手村、入門班系列。經過討論，我決定仿照之前在 DevOpsDays Taipei &lt;a href=&#34;//william-yeh.net/post/2018/09/thinking-weight-training/&#34;&gt;2018&lt;/a&gt; &amp;amp; &lt;a href=&#34;//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/&#34;&gt;2021&lt;/a&gt; 的路線，繼續以「系統思考」角度去剖析 DevOps 相關的組織文化與管理議題。&lt;/p&gt;
&lt;p&gt;我自己有一個關於演講的內規天條：演講，不只是輸出，也希望每次都有新的挑戰。因此，對於這次的演講主題【從系統思考角度談 DevOps 三步工作法】，我給自己下的挑戰是：我不要用較為人知曉的 CLD (&lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;causal loop diagram&lt;/a&gt;)，我要挑戰更難的 SFD (&lt;a href=&#34;https://thesystemsthinker.com/step-by-step-stocks-and-flows-improving-the-rigor-of-your-thinking/&#34;&gt;stock and flow diagram&lt;/a&gt;)。&lt;/p&gt;
&lt;p&gt;改用 SFD 倒不是為了量化塑模，而是因為它能夠更嚴謹的思考「變數」。正好這幾年台灣也開始流行起存量、增量的詞彙 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，我想，不妨跟風蹭一點熱度。&lt;/p&gt;
&lt;p&gt;這只是一開始的起心動念。但後來越來越覺得，SFD 雖然表面上比 CLD 多了些東西，但實際上卻比較容易詮釋。因此，我這次就把 SFD 定位在嚴謹的分析，接著再透過 CLD 予以簡化與抽象：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2024/07/sfd-to-cld.png&#34; alt=&#34;先 SFD 再 CLD&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2024/07/sfd-to-cld.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;先 SFD 再 CLD&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這次的嘗試，算是有達到當初設定的挑戰目標。以後還有機會的話，我會再挑戰用簡單的方式動態展示量化塑模。&lt;/p&gt;
&lt;p&gt;▶︎ 投影片：&lt;a href=&#34;https://speakerdeck.com/williamyeh/cong-xi-tong-si-kao-jiao-du-tan-devops-san-bu-gong-zuo-fa&#34;&gt;從系統思考角度談 DevOps 三步工作法&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系統思考工作坊 - 系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 【系統思考的四堂課】&lt;a href=&#34;//william-yeh.net/post/2018/06/sys-thinking-workshop/&#34;&gt;緣起&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 第一場公開班課後回覆：&lt;a href=&#34;//william-yeh.net/post/2018/09/thinking-weight-training/&#34;&gt;思維的重量訓練&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/&#34;&gt;從系統思考角度讀《獨角獸專案》&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;➍ 從系統思考角度談 DevOps 三步工作法&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;像劉潤的書《&lt;a href=&#34;https://www.books.com.tw/products/0010902849&#34;&gt;商業洞察力&lt;/a&gt;》、汪志謙的線上課程《&lt;a href=&#34;https://sat.cool/course/74&#34;&gt;峰值體驗 2：關鍵時刻的洞察與落地&lt;/a&gt;》，都有觸及到存量與增量的觀念，但也只是稍微引用了一點觀念，探討得並不全面。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>咬文嚼字的必要性（二）：階段性的預期成果設定</title>
      <link>//william-yeh.net/post/2024/02/outcome-sentence-patterns/</link>
      <pubDate>Tue, 13 Feb 2024 21:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2024/02/outcome-sentence-patterns/</guid>
      
        <description>&lt;p&gt;不管是專案管理領域還是目標管理領域，「階段性的預期成果設定」都是很重要的基本動作。&lt;/p&gt;
&lt;p&gt;不過，多年下來，我常常看到怪怪的，但又說不上來哪裡不對勁的例子。因此，我想找找是否有建議的寫法，甚至句型，作為團隊的共同語言。&lt;/p&gt;
&lt;p&gt;此文針對 ① 專案管理領域的 milestone 與 ② 目標管理領域的 key result 兩方面來探討。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2024/02/goal-setting.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2024/02/goal-setting.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;專案管理領域的-milestone&#34;&gt;專案管理領域的 Milestone&lt;/h2&gt;
&lt;p&gt;Milestone 是很常被設錯的東西。部份原因是對於「milestone 到底是什麼、作用是什麼」有了錯誤的認知。&lt;/p&gt;
&lt;h3 id=&#34;milestone-是什麼&#34;&gt;Milestone 是什麼？&lt;/h3&gt;
&lt;p&gt;如果你用慣了專案管理軟體，在你的印象中，milestone 或許只是一個「duration 為 0」的 activity/task &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 。如果從這個角度來看，milestone 應該會是帶有動詞屬性的行為——或許可稱之為「瞬間行為」。但是，根據 &lt;a href=&#34;https://www.amazon.com/dp/1628256648&#34;&gt;PMBOK 第七版&lt;/a&gt;的說法，milestone 其實並不是一個帶有動詞屬性的行為，反而比較像是個偏向名詞屬性的「可見事物」：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Milestone. A significant &lt;strong&gt;point&lt;/strong&gt; or &lt;strong&gt;event&lt;/strong&gt; in a project, program, or portfolio.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;PMI 網站的文章 &amp;ldquo;&lt;a href=&#34;https://www.pmi.org/learning/library/milestone-different-planning-approach-7635&#34;&gt;Milestone planning &amp;ndash; a different planning approach&lt;/a&gt;&amp;rdquo; 則指出：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A milestone anticipates what the project is supposed to achieve at a pre-set date. It should describe a &lt;strong&gt;desired state&lt;/strong&gt; of affairs, a &lt;strong&gt;desired future situation&lt;/strong&gt;. A milestone should describe &lt;strong&gt;what we want to achieve&lt;/strong&gt;; when we get there, that&amp;rsquo;s the event.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;milestone-的作用是什麼&#34;&gt;Milestone 的作用是什麼？&lt;/h3&gt;
&lt;p&gt;簡單的說，milestone 是分而治之的控制點。再引述 &amp;ldquo;Milestone planning &amp;ndash; a different planning approach&amp;rdquo;  一文的說法：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Milestones are also &lt;strong&gt;control stations&lt;/strong&gt; in the project, an opportunity for stakeholders to assure themselves that the project is moving in the right direction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;好的-milestone-該有什麼特性&#34;&gt;好的 milestone 該有什麼特性？&lt;/h3&gt;
&lt;p&gt;根據李君婷老師【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/70&#34;&gt;510 專案監管的系統思考與規則設計&lt;/a&gt;】的課程講義，好的 milestone 應該要有三個特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;精簡，清楚。&lt;/li&gt;
&lt;li&gt;足以代表專案關鍵。&lt;/li&gt;
&lt;li&gt;可被具體檢核。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;ldquo;Milestone planning &amp;ndash; a different planning approach&amp;rdquo; 一文也說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The way a milestone is formulated should allow us to determine whether the &lt;strong&gt;desired state&lt;/strong&gt; has been &lt;strong&gt;achieved&lt;/strong&gt; or not.&lt;/p&gt;
&lt;p&gt;It is relatively simple to say whether a milestone has been reached if it is an &lt;strong&gt;actual object&lt;/strong&gt;, something we can &lt;strong&gt;inspect&lt;/strong&gt; and &lt;strong&gt;verify&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;milestone-可能的句型&#34;&gt;Milestone 可能的句型？&lt;/h3&gt;
&lt;p&gt;雖然我比較少看到有人直接建議 milestone 的句型，但從上述的探討，不難歸納出一些方向：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Actual object.&lt;/li&gt;
&lt;li&gt;Desired state.&lt;/li&gt;
&lt;li&gt;Inspectable &amp;amp; verifiable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rita Mulcahy 在 &lt;a href=&#34;https://www.amazon.com/dp/1932735658&#34;&gt;&lt;em&gt;PMP Exam Prep&lt;/em&gt;&lt;/a&gt; 一書也舉了一些例子：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remember that milestones have no duration; they are simply the &lt;strong&gt;completion of activities&lt;/strong&gt;. Milestones may include &amp;ldquo;requirements are &lt;strong&gt;complete&lt;/strong&gt;&amp;rdquo; or &amp;ldquo;design is &lt;strong&gt;finished&lt;/strong&gt;&amp;rdquo;&amp;hellip;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因此，我個人喜歡借用 &lt;a href=&#34;https://www.eventstorming.com/&#34;&gt;event storming&lt;/a&gt; 圈子對於 &amp;ldquo;event&amp;rdquo; 的建議句型：「事件的內容，用 past tense (過去式) 描述」。&lt;/p&gt;
&lt;p&gt;應用到 milestone 身上，可選用「過去式」或「現在完成式」句型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;英文加 -ed&lt;/strong&gt;。譬如：xx% migrated, yy% done, zzz approved.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中文加「已」&lt;/strong&gt;。譬如：xxx 已完成、yyy 已測試、zzz 已驗收。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;okr-的-key-result&#34;&gt;OKR 的 &amp;ldquo;Key Result&amp;rdquo;&lt;/h2&gt;
&lt;h3 id=&#34;key-result-是什麼&#34;&gt;Key Result 是什麼？&lt;/h3&gt;
&lt;p&gt;OKR 原典《&lt;a href=&#34;https://www.books.com.tw/products/0010813170&#34;&gt;OKR：做最重要的事 (Measure What Matters)&lt;/a&gt;》是如此介紹 O 與 KR 的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「目標」就是我們想達成的&lt;strong&gt;事&lt;/strong&gt;，不多也不少。&lt;/p&gt;
&lt;p&gt;「關鍵結果」界定 &lt;strong&gt;目標的標準&lt;/strong&gt; ，並且監控我們 &lt;strong&gt;「如何」達成&lt;/strong&gt; 。有效的關鍵結果不僅明確，而且有時限，是進取但又可行的。最重要的是，它們是可測量也可驗證的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;key-result-的作用是什麼&#34;&gt;Key Result 的作用是什麼？&lt;/h3&gt;
&lt;p&gt;《OKR：做最重要的事》如此說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;目標設計和運用得當，可以防範模糊不清的思想，以及執行時的含混摸魚。&lt;/p&gt;
&lt;p&gt;關鍵結果的要求只有「已滿足」或「未滿足」兩種可能，中間沒有灰色地帶或存疑的餘地。到了指定的期限（通常是一季結束時），我們就宣佈關鍵結果是否已達成。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;好的-key-result-該有什麼特性&#34;&gt;好的 Key Result 該有什麼特性？&lt;/h3&gt;
&lt;p&gt;《OKR：做最重要的事》如此說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;目標必然是重要、具體和行動導向的，最好還能激勵人心。&lt;/p&gt;
&lt;p&gt;關鍵結果必須可以測量，而且，最後也只要用看的，完全不必提出任何理由，證明自己是否做到了。達成？還是沒達成？答案很簡單，不需要下判斷就能回答。&lt;/p&gt;
&lt;p&gt;必須含有完成工作的證據。這種證據必須可取得、可信和容易發現。&lt;/p&gt;
&lt;p&gt;編寫關鍵結果時，務必做到一件事：每一項關鍵結果都百分百達成，目標也就百分百達成。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;key-result-可能的句型&#34;&gt;Key Result 可能的句型？&lt;/h3&gt;
&lt;p&gt;原始的《OKR：做最重要的事》論述中，似乎並沒有強調 O 與 KR 的句型。我只在此書附錄看到這麼一句最接近的話：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;關鍵結果代表 &lt;strong&gt;「如何」(How)&lt;/strong&gt; ，應該要表達 &lt;strong&gt;可衡量的里程碑&lt;/strong&gt; 。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這句話點出兩個核心元素：方法、里程碑。&lt;/p&gt;
&lt;p&gt;後來管顧圈加入推廣 OKR 運動，才漸漸發展出一些較具規範性的寫法，但似乎尚未形成集體的共識。不過，從他們的 OKR 論述中，常常看到「里程碑型」這種 KR 類型 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。 因此，我個人很喜歡沿用前面探討過的「Milestone 句型」做為 KR 的句型骨幹。&lt;/p&gt;
&lt;p&gt;如果還要更細膩一點，不妨將「如何」(How) 也放進 KR 句型當中。譬如說，李君婷老師【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/95&#34;&gt;512 目標管理與團隊績效：統整 OKR 與 KPI 的有效實務&lt;/a&gt;】的課程講義，及《&lt;a href=&#34;https://www.books.com.tw/products/0010833361&#34;&gt;OKRs 執行力：華人實踐版&lt;/a&gt;》一書，都不約而同介紹過以下這種三合一寫法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 xxx 日期之前，透過 yyy 方法，完成 zzz 成果。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以此句型為基礎，你可以再添加量化元素進去：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 xxx 日期之前，透過 yyy 方法，達到 zzz% 成果。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以把量化元素的起點與終點也寫進去：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 xxx 日期之前，透過 yyy 方法，將 zzz 指標從 aaa 推進到 bbb。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你也可以添加「資源運用」元素進去，就變成很有 OGSM 的味道：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 xxx 日期之前，運用 yyy 資源，完成 zzz 成果。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;運用之妙，存乎一心。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上就是我個人慣用的 milestone 與 key result 句型。請掌握此基本句型，展現出內行氣。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【咬文嚼字的必要性】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2018/01/precise-expression/&#34;&gt;咬文嚼字的必要性（一）：用句型輔助思考&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 咬文嚼字的必要性（二）：階段性的預期成果設定&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/04/passphrase-at-work/&#34;&gt;請珍惜你們學到的通關密語&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;許多專案管理軟體都是透過「把 activity/task 的 duration 設為 0」的方式來標記 milestone。像 &lt;a href=&#34;https://support.microsoft.com/en-gb/office/add-a-milestone-583be27b-1659-4a7a-a047-e9b9cb6a4834&#34;&gt;Microsoft Project&lt;/a&gt;、&lt;a href=&#34;https://community.smartsheet.com/discussion/101507/how-can-i-get-smartsheet-to-show-zero-days-for-milestone-with-zero-days-duration&#34;&gt;Smartsheet&lt;/a&gt;、&lt;a href=&#34;https://www.projectplan365.com/training/lesson-2-create-milestones/&#34;&gt;Project Plan 365&lt;/a&gt;。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;像《&lt;a href=&#34;https://www.books.com.tw/products/0010817208&#34;&gt;執行 OKR，帶出強團隊&lt;/a&gt;》就將 OKR 分成基線型、正向度量型、負向度量型、範圍型、里程碑型五大類，而《&lt;a href=&#34;https://www.books.com.tw/products/0010833361&#34;&gt;OKRs 執行力：華人實踐版&lt;/a&gt;》也將 OKR 分成比率型、數量型、里程碑型、主觀型四大類。由此可見，「里程碑型」都是很被看重的一種 KR 類型。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>從私校角度看新課綱</title>
      <link>//william-yeh.net/post/2024/01/k7-k12/</link>
      <pubDate>Sat, 20 Jan 2024 18:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2024/01/k7-k12/</guid>
      
        <description>&lt;p&gt;屢次教改，課綱演進至今，許多人認為補習班與私校是受益者。&lt;/p&gt;
&lt;p&gt;補習班的說法可能不易判斷真偽，而私校畢竟受到教育當局的監管程度較高，說法應較可信。譬如說，私校定期呈報教育當局的「學校課程計畫」報告書，就可看出從教師角度出發的論述。&lt;/p&gt;
&lt;p&gt;我選了兩份報告：〈&lt;a href=&#34;https://www.chjhs.tp.edu.tw/dispUploadBox/pic/20230908132514559.pdf&#34;&gt;臺北市靜心國民中學 112 學年度學校課程計畫&lt;/a&gt;〉（以下簡稱「靜」）與〈&lt;a href=&#34;https://drive.google.com/file/d/1eVi8Yp9t8wuhbYy5YJHiq0_dl9vPoQUF/view?usp=sharing&#34;&gt;臺北市私立復興實驗高級中學國中部 112 學年度學校課程計畫&lt;/a&gt;〉（以下簡稱「復」），一窺私校眼中新課綱時代的教與學。&lt;/p&gt;
&lt;p&gt;看完之後，只能用這幅 ChatGPT 生成的圖來形容自己的所見：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2024/01/high-school.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2024/01/high-school.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;以下是一些重點摘要。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;學生素質&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;學生入學採抽籤方式，生源素質不一。 (復 p.4)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;學生語文能力&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;學生的資訊媒體能力隨著一屆更勝一屆，但是語文能力卻恰好相反。 (靜 p.39)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;學子於聆聽與閱讀過程中的訊息擷取能力，是教師們在教學現場的一大考驗。因此，要培養出學子的省思批判能力是一條漫長且艱辛的路程。 (靜 p.43)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;隨著時代演進，學子的資訊能力每一屆都在提升，然而學子的語文能力卻是逐屆下滑，對於因應中學當具備的語文基本能力略顯不足。學子的成語、名言錦句與文言文識讀能力亦為不足。於資訊應用的世代，學子書寫能力也是考驗教師的項目之一。 (靜 p.45)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;學生的英文程度落差明顯加劇，不同層次英文程度的學生，老師比以往要花更大的心力在推動學生的學習。如何提升精進班學生的學習動機是也是老師要再多努力的地方。 (靜 p.39)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;本校雖有高逹 80% 以上的學生英文會考逹到精熟級，但相較之下低成就的學生更是倍感壓力，挫折感更大，學生年級越高，英語程度差異越大。 (靜 p.626)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;教學時數&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;因基本課堂時數偏少，教師思考如何以最少時數發揮教學最大效益，進行有效率的教學是一大考驗。 (靜 p.41)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;課綱刪減的內容&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;(社會) 新課綱的教科書中內容大幅度修改單元活動設計，而基本練習仍偏重知識應用，而教師採取的教學方式更需強化分析、評鑑、創造能力的培養，是一大挑戰。 (靜 p.41)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(自然) 課綱內容已刪除許多原有的公式及概念，但為求知識的完整性，老師們仍會盡可能地補充，因此在完整性與時間兩者間該如何取得平衡，有很大的問題存在。 (靜 p.41)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;課綱新增的內容與趨勢&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;閱讀素養當中的跨領域試題的命題不易，得需借助其他領域夥伴的專業素養共備。然學校教師負擔較大，雖說教師們多願意發展此議題，但仍屬不易。 (靜 p.43)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;尋找新穎且適切的主題難度提高，老師必須隨時注意生活周遭素材。 (靜 p.44)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;跨領域之社群較難有共同不排課的時間。 (復 p.34)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;資訊科技不斷的進步，讓課程需要因應學生能力及生活習慣做出滾動式的修正，但在設計過程中亦會擔心追求新科技的同時沒有把基礎打好，在內容新舊設計的平衡上是不小的挑戰。 (靜 p.44)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;各科因跨領域與多元學習，造成學生作業量大增，使學生負擔加重。 (復 p.34)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;教師的負擔&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;部分教師兼任行政工作，需兼顧教學及行政，壓力較大，降低教師兼行政意願。 (復 p.5)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;本校國文老師多有兼職導師或行政職，且教師負擔繁重，因此推動各項活動時，有時難以盡善盡美，開發新教材亦有困窘之處。本校自然領域教師多兼任導師或行政職，且任教課種多，課務及任務負擔繁重，增加備課難度。 (靜 p.39 &amp;amp; p.41)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;因學校老師課程負擔較大，很難找到共同時間可以討論。 (靜 p.44)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;因應領域特色重點工作及各項課程教學評量等，若僅限於領域時間實難確切執行共備。教師需仰賴課餘時間自發互動以利課程教學活動發展與評量研討等事項之研議。 (靜 p.39)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;教師承受較大壓力。公立學校教師負擔較輕、退休制度較完善，老師可能流失至公立學校。 (復 p.5)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;每學年外師流動性高，以致教學課程品質不穩定。 (復 p.34)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;家長心態&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;部分學生及家長還是希望學習成效快速回歸到學期成績，而質疑許多非與考試直接相關的活動學習。且教師有進度上的壓力，實施上會有些許困難。 (靜 p.49)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;部分家長對教學及學校政策意見較分歧，學校需積極耐心溝通。 (復 p.5)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;部分家長觀念仍偏重學生智育表現。少部分家長過度關心學校事務，干預教學。 (復 p.5)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;部分家長不願學生被貼標籤，以致於未能取得特教身分，進而接受特教服務。 (復 p.5)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2024-03-17 補充
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;這幾天是許多私中考試的日子。今年情況比較特殊，媒體對此議題做了更多報導及評論。以下列出幾則：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2024-03-17: &lt;a href=&#34;https://udn.com/news/story/7323/7836448&#34;&gt;龍寶寶上國中！北市畢業生多 2 千人，國中最多增 60 班&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2024-03-16: &lt;a href=&#34;https://news.pts.org.tw/article/685694&#34;&gt;龍年及校安等因素，雙北私校招生更熱門&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2024-03-16: &lt;a href=&#34;https://fb.watch/qSoyBJpr2Y/&#34;&gt;龍年、課綱、割頸案，私中報名人數暴增&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2024-03-15: &lt;a href=&#34;https://udn.com/news/story/6898/7833165&#34;&gt;搶進私中窄門今年更難，家長嘆：比頂大還難考&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2024-03-16: &lt;a href=&#34;https://udn.com/news/story/6898/7834696&#34;&gt;冷眼集／公立體制崩壞，將孩子推向私中&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2024-03-16: &lt;a href=&#34;https://udn.com/news/story/6898/7834693&#34;&gt;私中入學管道：北部獨鍾考招，中部改辦營隊&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2024-01-02: &lt;a href=&#34;https://www.taisounds.com/news/content/116/100103&#34;&gt;【教改僵局2-1】連公校老師小孩也去私中，升學主義下「教學正常化」反成枷鎖&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>2023 個人回顧</title>
      <link>//william-yeh.net/post/2023/12/2023-retrospective/</link>
      <pubDate>Tue, 12 Dec 2023 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/12/2023-retrospective/</guid>
      
        <description>&lt;p&gt;原本以為前幾年的冒險已經夠精彩了，沒想到今年更加刺激，簡直就是甘迺迪的登月大計。&lt;/p&gt;
&lt;p&gt;到了年終，又開始要做個總回顧，再對來年許願。去除一些不便揭露的事情，以下是簡單的回顧。&lt;/p&gt;
&lt;h2 id=&#34;補血課程&#34;&gt;補血課程&lt;/h2&gt;
&lt;p&gt;這一年，因為時間因素，我上的多半是線上課程。其中，除了專業領域的 &lt;a href=&#34;//william-yeh.net/post/2023/04/gcp-on-coursera/&#34;&gt;Coursera 上面的 GCP 課程&lt;/a&gt;之外，收穫最大的，就是這兩門啟點文化的課：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.koob.com.tw/online/tk11&#34;&gt;【全方位職涯思維】深職你的未來，佈局理想人生&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.koob.com.tw/online/tk13&#34;&gt;【讓夢想著地】勇敢迎接改變，陪你生涯轉彎不孤單&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我在 &lt;a href=&#34;//william-yeh.net/post/2019/12/2019-retrospective/&#34;&gt;2019 個人回顧文&lt;/a&gt;曾經提過，對於線上課程，真正 100% 完課，且不時還會回頭複習的，就是他們的課。&lt;/p&gt;
&lt;p&gt;今年，個人遇到重大難題與抉擇。這兩門課，打破我許多迷思成見，協助我釐清主觀與客觀情勢，我才有辦法根據錦囊，規劃一系列行動策略：吞下去，並存，找到「那附近」，焊接軌道，翻越必要的山路，永不回頭。&lt;/p&gt;
&lt;p&gt;我很感激這兩門課仍然常常回聽複習的課。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/12/looking-forward.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/12/looking-forward.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;公開演講及授課&#34;&gt;公開演講及授課&lt;/h2&gt;
&lt;p&gt;今年，身處重大轉換期，已經無法恣意 跑趴 出沒 社群活動，只參加一場線上的小座談：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=32Y2CyiQs_8&#34;&gt;時間盒 vs 工作流&lt;/a&gt; (2023-11-11)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這場小座談，源自〈&lt;a href=&#34;//william-yeh.net/post/2023/10/criticism-about-timebox/&#34;&gt;Timebox 是死胡同嗎？&lt;/a&gt;〉一文涉及的討論，我再把沒講完的想法另外寫一篇〈&lt;a href=&#34;//william-yeh.net/post/2023/11/why-decomposition-matters/&#34;&gt;變動的時代，為什麼工作分解技能更是必備？&lt;/a&gt;〉作為補充。&lt;/p&gt;
&lt;p&gt;如果你對 Scrum vs Kanban 議題感興趣，不妨參考一下。&lt;/p&gt;
&lt;h2 id=&#34;不同的世界&#34;&gt;不同的世界&lt;/h2&gt;
&lt;p&gt;看了《&lt;a href=&#34;https://www.imdb.com/title/tt9419884/&#34;&gt;奇異博士２：失控的多重宇宙&lt;/a&gt;》之後，我對片尾一段對話格外有感：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/12/are-you-happy.png&#34; alt=&#34;Are you happy?  -- Quote: Doctor Strange in the Multiverse of Madness&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/12/are-you-happy.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Are you happy?  -- Quote: Doctor Strange in the Multiverse of Madness&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;「拯救世界」是我想要的，但我可不想落得像 Doctor Strange 那樣感慨「原本以為拯救世界會獲得幸福⋯⋯並沒有。」&lt;/p&gt;
&lt;p&gt;長考數月，終於做了一個決定：我要去一個既能拯救世界，又能得到 happy 的舞台。&lt;/p&gt;
&lt;p&gt;抱著朝聖的心情，前往很不一樣的世界：製造業。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;為什麼是製造業？&lt;/p&gt;
&lt;p&gt;我的管理初體驗，大半淵源都來自於此領域的論述。像高德拉特《&lt;a href=&#34;https://williampjyeh.notion.site/1887e85000de40d7aa80b0f04725f4bf&#34;&gt;目標&lt;/a&gt;》＆《&lt;a href=&#34;https://williampjyeh.notion.site/d179401d81ab42f79f74ca490ef1318a&#34;&gt;絕不是靠運氣&lt;/a&gt;》都是製造業場景，像《&lt;a href=&#34;https://williampjyeh.notion.site/ab699ecc3ace4c2e994d5142d9ef186f&#34;&gt;精實革命&lt;/a&gt;》則是汽車製造業。我一直從這裡取經，應用到軟體研發領域，心中不免也很好奇：這些被我轉化過來的理念，它們的原始樣貌，究竟是否真的如書本所陳述的那樣，是否真的如我所以為的那樣？&lt;/p&gt;
&lt;p&gt;製造業的世界，很強調量化管理，交期＆品質兩方面也都不能退讓，這對於帶著濃厚自組織、自管理、經驗主義、試錯空間、人本色彩的 Agile &amp;amp; DevOps 來說，真的適用嗎？&lt;/p&gt;
&lt;p&gt;這些疑問，只有親自朝聖，才能夠一窺究竟。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;當來自矽谷和全世界的頂尖科技，遇上半導體創新和高度製造紀律，彼此交會將帶來什麼樣的火花？這是非常令人振奮的時刻。&lt;/p&gt;
&lt;p&gt;      &amp;mdash; Quote: CIO Chris &lt;a href=&#34;https://www.ithome.com.tw/news/149124&#34;&gt;https://www.ithome.com.tw/news/149124&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;為了迎接這份大轉變，我認真複習了一些素材，尤其是畢業生的論述。像彭建文的課程【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/105&#34;&gt;工程師的職涯經營指南&lt;/a&gt;】、書籍《&lt;a href=&#34;https://williampjyeh.notion.site/cf34fbb4327f4c0596ab8b0dfb4e0f2d&#34;&gt;思維的良率&lt;/a&gt;》&amp;amp;《&lt;a href=&#34;https://williampjyeh.notion.site/82464b60686148448cf029a1854293ed&#34;&gt;思維的製程&lt;/a&gt;》，像郝旭烈的書籍《&lt;a href=&#34;https://williampjyeh.notion.site/0592c1c875ac4d0e80860dde5c03c2b6&#34;&gt;贏在邏輯思考力：玩一場擴張邊界的遊戲&lt;/a&gt;》＆《&lt;a href=&#34;https://williampjyeh.notion.site/dc2a29274dbb46c59db58958e8092b3c&#34;&gt;專案管理：玩一場從不確定到確定的遊戲&lt;/a&gt;》，都對於我融入這特殊的高績效文化，有很大的幫助。&lt;/p&gt;
&lt;p&gt;半年以來，感觸非常多，姑且談談最深的三點。&lt;/p&gt;
&lt;p&gt;其一、持續改善的文化。就像彭建文在這篇 &lt;a href=&#34;https://pinshuoi.com/9813/&#34;&gt;CIT 文章&lt;/a&gt;所講：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;CIT 代表「Continual Improvement Team」，這個團隊的目的是改善公司的體質，增進公司的競爭力。CIT 活動已經在公司內推行了 20 多年，是一個有系統且能持續不斷改善的活動機制。不論是同部門或跨部門，遇到問題都可以組成 CIT 團隊，共同解決問題。&lt;/p&gt;
&lt;p&gt;CIT 需要時間，很難在短期內看到效果。許多台灣企業希望達到短期效益，較不注重這種無形的東西。當公司全面形成持續改善的文化，團隊解決問題的能力就會不斷提升，整個組織的競爭力也會形成很大的競爭優勢，帶來驚人的效益。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;突然發覺，身處有持續改善文化的地方，不必躲躲藏藏做這些事，是多麼難得。在一間公司理所當然的事，在其他公司就未必了。&lt;/p&gt;
&lt;p&gt;其二、這是個極度講究邏輯的地方。就像&lt;a href=&#34;https://www.cw.com.tw/article/5126589&#34;&gt;這篇文章&lt;/a&gt;所說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其實系統設計必有其邏輯，因此在 xxx 工作，「邏輯」十分重要，只要了解整個程序跟系統的前後邏輯，並把握好基本原則，便能順利適應這樣的工作型態。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;即使領域知識仍有不足，但憑藉清晰思路的基本功，可以逐漸找到能夠貢獻洞見的地方。畢竟，系統是人設計的，作業程序是人設計的，問題也多半是人弄出來的；背後的邏輯脈絡，是非常重要的切入點。&lt;/p&gt;
&lt;p&gt;邏輯，是個看似樸素無華，卻值得用心操練的基本功。&lt;/p&gt;
&lt;p&gt;其三、我很驚喜的發現，過去數年刻意自我要求的本質修練，真的「可以用在世界級的舞台上」。&lt;/p&gt;
&lt;p&gt;去年搞的一堆導讀會及課程，到頭來收穫最大的還是自己。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/12/appliable.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/12/appliable.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;卡片盒筆記法&#34;&gt;卡片盒筆記法&lt;/h2&gt;
&lt;p&gt;為了迎接全新的挑戰，也正好這兩年以來&lt;a href=&#34;https://readingoutpost.com/2-years-of-zettelkasten/&#34;&gt;卡片盒筆記法&lt;/a&gt; (Zettelkasten) 蔚為風潮，我便順勢升級自己行之有年的筆記系統。&lt;/p&gt;
&lt;p&gt;我主要參考了 XDite《&lt;a href=&#34;https://williampjyeh.notion.site/fe64416e49764104b56c1a2db7d70f6d&#34;&gt;打造超人筆記&lt;/a&gt;》及朱騏《&lt;a href=&#34;https://williampjyeh.notion.site/d687fbd8766b44cbaf5c8150d64abffd&#34;&gt;知識複利筆記術&lt;/a&gt;》所載之法，並運用在 Obsidian 及 RemNote 上。&lt;/p&gt;
&lt;p&gt;RemNote 是個滿有趣的軟體。它走的是類似 Roam 及 Logseq 的路線，如果你沒玩過這類軟體，網路上也有許多網紅錄製的教學影片，尤其是 penolopie 的示範，解除了我許多使用上的疑惑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/dHQxq7xOks4&#34;&gt;https://youtu.be/dHQxq7xOks4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/UX_sAokbUHk&#34;&gt;https://youtu.be/UX_sAokbUHk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/-o9ePucEonU&#34;&gt;https://youtu.be/-o9ePucEonU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/dEty1ryv6R8&#34;&gt;https://youtu.be/dEty1ryv6R8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RemNote 的 &amp;ldquo;&lt;a href=&#34;https://help.remnote.com/en/articles/6030778-universal-descriptors&#34;&gt;universal descriptor&lt;/a&gt;&amp;rdquo; 設計更是令人驚艷。這陣子我嘗試重度使用這功能，發現筆記摘要的品質及深度都截然不同了。再搭配內建的閃示卡功能，連記憶都更加固著。&lt;/p&gt;
&lt;p&gt;值此，不禁感嘆：以前怎麼都在用土法來煉鋼呀。&lt;/p&gt;
&lt;p&gt;認真用 RemNote &amp;amp; Obsidian 實踐卡片盒筆記法一個多月，再重讀《&lt;a href=&#34;https://williampjyeh.notion.site/03810b34083948459a55740b9b6c32a8&#34;&gt;卡片盒筆記&lt;/a&gt;》原典，就讀得出味道了。&lt;/p&gt;
&lt;p&gt;有些書就是要先去實作一下，踩雷，困而思之習之，方能體悟。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/12/zettelkasten.jpg&#34; alt=&#34;Zettelkasten&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/12/zettelkasten.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Zettelkasten&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;2024-許願&#34;&gt;2024 許願&lt;/h2&gt;
&lt;p&gt;2024 年，希望自己能做到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;專題式的系列講座。&lt;/li&gt;
&lt;li&gt;Coach 值得 coach 的人。&lt;/li&gt;
&lt;li&gt;繼續更深度的本質修練。&lt;/li&gt;
&lt;li&gt;繼續增進商務英語聽說能力。&lt;/li&gt;
&lt;li&gt;開放冒險選項。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就醬。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>如何衡量敏捷對於軟體研發效能的利益？</title>
      <link>//william-yeh.net/post/2023/12/dev-metrics/</link>
      <pubDate>Sun, 03 Dec 2023 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/12/dev-metrics/</guid>
      
        <description>&lt;p&gt;面對敏捷或 DevOps 藥方，病人可能帶著各種不同的動機而來，但終歸都會提出同樣的疑問：我怎麼知道敏捷有沒有效？怎麼衡量成效？&lt;/p&gt;
&lt;p&gt;這問題，可能在導入之後的某個時刻會問，但更有可能像戰國時代梁惠王那樣，才剛第一次接見孟子，居然劈頭就問：「叟，不遠千里而來，亦將有以利吾國乎？」&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/12/mencius-dialogue.png&#34; alt=&#34;孟子見梁惠王&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/12/mencius-dialogue.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;孟子見梁惠王&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;對這議題，常有兩種極端的反應。&lt;/p&gt;
&lt;p&gt;如果你像孟子一樣，一開頭就企圖曉以大義： &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;總經理呀，何必一開頭就談「衡量成效利益」呢？你更應該看重的是「內涵與精神」呀！&lt;/p&gt;
&lt;p&gt;如果總經理成天想著「對我們的公司有什麼可衡量的成效」，主管成天想著「對我們部門有什麼可衡量的成效」，員工成天想著「對我個人有什麼可衡量的成效」，上下各自算計著成效利益，整間公司就很危險了！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;只怕你會像孟子一樣，很快就離開這個國家了。&lt;/p&gt;
&lt;p&gt;輕蔑指標固然不可取，但另一個極端「指標狂人」也很可怕。&lt;/p&gt;
&lt;p&gt;近年來「數位轉型」蔚為顯學，延燒到傳統產業，甚至連傳統管理顧問機構也來湊熱鬧。於是乎，世界就多了更多指標，更多成熟度衡量，更多培訓、證照、鑑定標章——更多所謂的「商機」。&lt;/p&gt;
&lt;p&gt;這世界不缺指標，缺的是能引領有效行動的指標。若不懂軟體研發的獨特性，就會訂出沒有行動意義的落後指標，或是沒有合理因果證據的偽指標。就像 Bryan Finster 在 “&lt;a href=&#34;https://bdfinst.medium.com/5-minute-devops-mckinsey-gets-developer-productivity-wrong-573b57cd6f6a&#34;&gt;5 Minute DevOps: McKinsey Gets Developer Productivity Wrong&lt;/a&gt;” 一文對於某管顧公司近日端出的  “Developer Productivity” framework 所做的批評：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The real problem is that too many in management don’t understand the work they manage. Management can understand the &lt;strong&gt;intricacies of software engineering&lt;/strong&gt; if they become leaders and study the work they manage. Not all managers are leaders. Some simply want a framework to hold people accountable.&lt;/p&gt;
&lt;p&gt;Those who do understand tend to &lt;strong&gt;measure the right things&lt;/strong&gt;. The one thing McKinsey doesn’t do with this framework is help fix this problem. They are making it worse.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;那麼，軟體研發活動有什麼獨特性？正確的衡量角度又是什麼？Daniel Terhorst-North 的 “&lt;a href=&#34;https://dannorth.net/mckinsey-review/&#34;&gt;McKinsey Developer Productivity Review&lt;/a&gt;” 一文說得好：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Software development is a collaborative, generative enterprise, and we can easily measure the effectiveness of a team, and more importantly how this is trending over time, using &lt;strong&gt;&lt;strong&gt;Theory of Constraints&lt;/strong&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;strong&gt;flow-based metrics&lt;/strong&gt;&lt;/strong&gt; like &lt;strong&gt;&lt;strong&gt;lead time&lt;/strong&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;strong&gt;throughput&lt;/strong&gt;&lt;/strong&gt;. Take a look at the work of Eliyahu Goldratt and Donald Reinertsen for a deeper understanding of these. An organisation like McKinsey endorsing these approaches would be a great help to the industry.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這段話點出幾個關鍵：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;團隊 vs 個人&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;縱貫研究 vs 橫斷研究&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Theory of constraints &amp;amp; lean thinking&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Flow, lead time &amp;amp; throughput&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我們就從這些角度來切入，尤其是 “flow” 角度。&lt;/p&gt;
&lt;h2 id=&#34;從-flow-角度看軟體研發效能的本質指標&#34;&gt;從 Flow 角度看軟體研發效能的本質指標&lt;/h2&gt;
&lt;p&gt;我喜歡用以下這五個主要的 flow 指標來整體衡量軟體研發效能：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/12/dev-efficiency.png&#34; alt=&#34;軟體研發效能五大指標&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/12/dev-efficiency.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;軟體研發效能五大指標&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;為了對於「軟體研發效能」得出較全面的 flow 視角，我結合幾個信度效度兼具、又不複雜的論述：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SRE 的 &lt;a href=&#34;https://sre.google/sre-book/monitoring-distributed-systems/&#34;&gt;4 golden signal&lt;/a&gt;: latency, traffic, errors, saturation。&lt;/li&gt;
&lt;li&gt;Scrum 之父 Ken &amp;amp; Jeff 在《&lt;a href=&#34;https://williampjyeh.notion.site/Scrum-00d22ec98ca847d49f62b63d10667049&#34;&gt;告別瀑布，擁抱 Scrum&lt;/a&gt;》第 7 章提出的主要指標：productivity, quality, value。&lt;/li&gt;
&lt;li&gt;Theory of Constraints 提到的 bottleneck/constraints 及 throughput。&lt;/li&gt;
&lt;li&gt;Lean 提到的 lead time。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它們之間的對應關係是：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Flow ▼&lt;/th&gt;
          &lt;th&gt;SRE&lt;/th&gt;
          &lt;th&gt;Ken&amp;amp;Jeff 2012&lt;/th&gt;
          &lt;th&gt;Theory of Constraints&lt;/th&gt;
          &lt;th&gt;Lean&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Traffic&lt;/td&gt;
          &lt;td&gt;Traffic&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;Pull&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Saturation&lt;/td&gt;
          &lt;td&gt;Saturation&lt;/td&gt;
          &lt;td&gt;Productivity&lt;/td&gt;
          &lt;td&gt;Bottleneck; Constraints&lt;/td&gt;
          &lt;td&gt;WIP&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Lead time&lt;/td&gt;
          &lt;td&gt;Latency&lt;/td&gt;
          &lt;td&gt;Productivity&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Throughput&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;Value&lt;/td&gt;
          &lt;td&gt;Throughput&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Quality&lt;/td&gt;
          &lt;td&gt;Error&lt;/td&gt;
          &lt;td&gt;Quality&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;五個指標，儘管數量不多，但很容易展開成更細部的指標。譬如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Traffic 可往下展開成 product backlog 管理、dual track、definition of ready 等指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Saturation 可往下展開成 velocity、queue length、WIP、cycle time、interrupt 等指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lead time 可往下展開成 value stream、MTTR 等指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Throughput 可往下展開成 value points、cumulative flow diagram、deployment frequency、feedback 等指標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quality 可往下展開成 code complexity、change failure rate、rework rate 等指標。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這五個指標以簡馭繁，很好用。&lt;/p&gt;
&lt;p&gt;我通常會從這五大指標出發，蒐集初始資料，形成假設，求證，並佐以 Theory of Constraints 分析，找到關鍵 constraints，用&lt;a href=&#34;https://www.tocinstitute.org/five-focusing-steps.html&#34;&gt;聚焦五步驟&lt;/a&gt;界定優先順序，再去探討解決方案。&lt;/p&gt;
&lt;h2 id=&#34;從-gsm-角度看敏捷能解決什麼問題&#34;&gt;從 GSM 角度看敏捷能解決什麼問題&lt;/h2&gt;
&lt;p&gt;這五個指標，儘管是偏向落後指標，但很容易展開成可行動的領先指標。&lt;/p&gt;
&lt;p&gt;當然啦，在展開成領先指標之前，最好還是先回到最原始的動機：之所以會想尋求敏捷或 DevOps 這帖藥方，一開始的痛點及原因究竟是什麼？&lt;/p&gt;
&lt;p&gt;界定好「待解決問題」之後，我建議根據《&lt;a href=&#34;https://www.tenlong.com.tw/products/9786263242630&#34;&gt;Google 的軟體工程之道&lt;/a&gt;》所介紹的 &lt;strong&gt;GSM process&lt;/strong&gt;，一步步找出合適的領先指標：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;：期望當問題解決之後，能夠達到什麼樣的目標狀態？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Signal&lt;/strong&gt;：有什麼明顯的信號，可以告訴我們說：目標已經達到了？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Measurement&lt;/strong&gt;：對於上述信號，有什麼明顯的量測值，或是具有預測效度的量測值？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最後，則是透過 GSM 規劃出行動策略：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Task&lt;/strong&gt;：從 Goals 找出能夠提升 Metrics 的 Tasks，而不是直接從 Metrics 找出 Task。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;價值&#34;&gt;價值&lt;/h2&gt;
&lt;p&gt;最近看到 Howie 對五年前的老話題有感而發：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/12/howie-revisit.png&#34; alt=&#34;孟子見梁惠王&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/12/howie-revisit.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;孟子見梁惠王&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;經過了五年的歷練，我的&lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;回答&lt;/a&gt;還是一樣，但更多了一份篤定：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TL;DR　對於「價值」是否有增益。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;回頭看看當初導入敏捷的痛點及原因，找出起初認定（或誤認）的價值是什麼。尤其是：這所謂的「價值」，是否可追溯至&lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;敏捷宣言&lt;/a&gt;或 &lt;a href=&#34;https://modernagile.org/&#34;&gt;Modern Agile&lt;/a&gt; 四層面。若追溯不了，或許一開始就投錯藥方了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;導入敏捷後，是否在敏捷宣言或 Modern Agile 四層面有所進展。進而檢討：這些進展，是否有對應到當初導入敏捷的痛點及原因。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;希望這份關於五大軟體研發效能指標的分析，有助於你用敏捷解決正確的問題，並用正確的方式衡量成效。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      「判準與指標」系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2018/10/methodology-and-criteria/&#34;&gt;軟體開發，除了方法論，還有⋯⋯&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/10/agile-criteria/&#34;&gt;敏捷的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2018/11/lean-startup-criteria/&#34;&gt;Lean Startup 的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ 如何衡量敏捷對於軟體研發效能的利益？&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;這段孟子與梁惠王的對話，原文是：「王何必曰利？亦有仁義而已矣！王曰『何以利吾國』，大夫曰『何以利吾家』，士庶人曰『何以利吾身』，上下交征利，而國危矣！」&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>變動的時代，為什麼工作分解技能更是必備？</title>
      <link>//william-yeh.net/post/2023/11/why-decomposition-matters/</link>
      <pubDate>Tue, 14 Nov 2023 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/11/why-decomposition-matters/</guid>
      
        <description>&lt;p&gt;很多人認為，在變動較少的舊時代 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，一次到位的工作規劃、工作分解是必備技能，但是到了現在這個變動頻仍、朝令夕改、隕石滿天飛的時代，做再多工作分解的規劃只是不切實際的浪費。&lt;/p&gt;
&lt;p&gt;你怎麼看？&lt;/p&gt;
&lt;p&gt;我反而認為，正是因為變動頻仍，就更需要及早進行工作分解。只不過這種工作分解，不是舊時代那種一次到位的無差別分解，而是要能夠區分近光燈與遠光燈的不同層次，也就是敏捷陣營所講究的 &amp;ldquo;&lt;a href=&#34;https://scrumbook.org.datasenter.no/value-stream/product-backlog/granularity-gradient.html&#34;&gt;granularity gradient&lt;/a&gt;&amp;quot;。&lt;/p&gt;
&lt;p&gt;這個論點，我曾在去年的兩場導讀會，透過兩本書，作為公司內推動敏捷轉型的心態導正。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 最近我發現，這類誤解仍然普遍存在於敏捷轉型的業界，因此特地將去年那兩場導讀會的觀點稍作整理，誌於此文。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/11/pomodoro-timer.png&#34; alt=&#34;Generated by ChatGPT4 &amp;#43; DALL·E 3&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/11/pomodoro-timer.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Generated by ChatGPT4 &amp;#43; DALL·E 3&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;少量多樣現象與影響&#34;&gt;少量多樣現象與影響&lt;/h2&gt;
&lt;p&gt;這個時代，「少量多樣」已是既成事實。在時間與事情上的「專注」，似乎越來越是奢求。&lt;/p&gt;
&lt;p&gt;在職場上，我們越來越難擁有一整段專屬於個人的時間去專心做一件事。我們總是不時被打斷，不時有插單進來，這些時機與事情的正當性似乎也很難被質疑。隨著職位升高，這現象似乎也隨之加劇。&lt;/p&gt;
&lt;p&gt;放大到團隊，甚至公司組織，亦然。隨著業務規模擴大，利害關係人數量及種類越來越多，這現象似乎也隨之加劇。&lt;/p&gt;
&lt;p&gt;少量多樣的新現實，對習慣大批量做事的個人而言，不容易進入「心流」(flow)：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這是一個現實的問題，尤其我們在職場與家庭裡面，都免不了會被打斷的工作狀態。這時候，我們是要堅持自己一定非要有三、四個小時的完整時間才能進入心流狀態，才能完成工作？還是我們必須想一個工作方式，可以適應這種必須被打斷，一定會分段完成的工作呢？&lt;/p&gt;
&lt;p&gt;&amp;mdash; From: 《&lt;a href=&#34;https://www.playpcesor.com/2020/05/2020-new-book.html&#34;&gt;時間管理的 30 道難題&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;對習慣大批量行事的組織而言，則會牽動到即時生產、換模換線的作業方式、甚至商業模式的巨變，可謂之「灰犀牛」衝擊：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;大多數的灰犀牛可能早在三個月前、兩年前就已經存在且默默進逼，是我們故意疏忽、固執己見、視若無睹。對食品業來說，消費市場走向「少量多樣」就是一頭兩噸重的灰犀牛，因為過去汽車業走過、科技電子業走過，食品業又怎能避免？&lt;/p&gt;
&lt;p&gt;&amp;mdash; From: 《&lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;總括來說，「少量多樣」帶來效率及效能的挑戰，對於人類是 context switch，對於機器設備則是換線換模。反之，若是能夠克服這一點，就能因應少量多樣的時代趨勢，化危機為轉機，成為個人及企業的競爭優勢。&lt;/p&gt;
&lt;p&gt;機器設備非我所長，相關的人機料法環細節，請參閱《&lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;》。 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; 接下來我只繼續探討人類的 context switch 課題。&lt;/p&gt;
&lt;h2 id=&#34;少量多樣的關鍵課題&#34;&gt;少量多樣的關鍵課題&lt;/h2&gt;
&lt;p&gt;對人類來說，過度 context switch 會增加暖機以求進入狀況的時間比例，也會損耗心智注意力，阻礙心流形成。&lt;/p&gt;
&lt;p&gt;讓我們先接受一個事實吧：context switch 是無法完全逃避的現實。那麼，接下來的關鍵課題就是：如何做好 context switch 的準備，以降低暖機的佔比，減少心智注意力的損耗。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.playpcesor.com/2020/05/2020-new-book.html&#34;&gt;時間管理的 30 道難題&lt;/a&gt;》第 4.5 節對這課題有很深刻的洞見：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們應該要把工作方式設計成「可以被打斷」的工作流程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;想像一下：如果工作流程被設計成本質上就是「可以被打斷」（我不想太激進的說「歡迎被打斷」或「擁抱被打斷」），也就是說，如果在這新的工作流程裡，context switch 既不會過度增加暖機佔比，也不會過度損耗我們的心智注意力，那該有多好！&lt;/p&gt;
&lt;p&gt;要怎麼做到？可分為兩個層面。&lt;/p&gt;
&lt;p&gt;在個人修練層面，運用近年流行的「番茄鐘工作法」來練習短時間專注。&lt;/p&gt;
&lt;p&gt;在工作設計層面，則是作者的招牌主張「子彈行動清單」：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們應該要把工作方式設計成「可以被打斷」的工作流程——&lt;strong&gt;讓工作本身拆解成行動清單&lt;/strong&gt;。這樣一來，任何時候被打斷，我會知道接下來下一個可以進行的步驟是什麼，以及前面做完了什麼步驟任務，不再是一個模糊成一團的任務。&lt;/p&gt;
&lt;p&gt;可以分段成行動清單，其實可以幫助我們更快進入心流。因為如果一個任務，我不知道它明確的步驟是什麼，不知道怎麼開始，不知道這個步驟的下一個步驟是什麼，腦袋會一直在煩惱，一直在焦慮，一直在思考，一直在做確認。這時候我們大腦負擔很多決策選擇，特別容易疲勞、容易混亂。於是，我反而需要花更多時間去進入心流。&lt;/p&gt;
&lt;p&gt;如果這個任務，我可以拆解出行動清單，我看到非常明確的步驟，那我的注意力就可以非常專注在下一個步驟就好。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;有趣的是，儘管作者的「子彈行動清單」是在講個人的時間管理，並不是在講 Scrum 的 Sprint Planning，但精神及步驟卻若合符節，所以我很喜歡引用《&lt;a href=&#34;https://www.playpcesor.com/2020/05/2020-new-book.html&#34;&gt;時間管理的 30 道難題&lt;/a&gt;》第 3 章作為我的敏捷工作坊培訓素材。&lt;/p&gt;
&lt;p&gt;因此，總結來說，面對 context switch 的關鍵做法是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;短時間專注：以個人來說，就是「番茄鐘工作法」；以 Scrum 來說，就是習慣 Sprint 週期內五大活動的節奏。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;「可以被打斷」的工作流程：以個人或團隊來說，就是將工作分解至可行動的清單。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;事前做好工作分解，幫助我們面對 context switch，更有餘裕應付插單。&lt;/p&gt;
&lt;h2 id=&#34;延伸的好處&#34;&gt;延伸的好處&lt;/h2&gt;
&lt;p&gt;把工作方式設計成「可以被打斷」的工作流程，不僅消極的可以避免被 context switch 拖累，甚至還可以積極的善用這項優勢。譬如說，在少量多樣時代，有機會達到 Lean 所追求的「平準化」目標狀態，在市場波動時仍能保有較佳的資源調度能力：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;將每日所需生產量的落差予以平均，謀求生產量的變動縮小。&lt;/p&gt;
&lt;p&gt;&amp;mdash; From: 《&lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「平準化」不只是在汽車業、科技電子業、食品業有用，在知識工作場景也很管用。譬如說 Ailin 最近在〈&lt;a href=&#34;https://docs.google.com/presentation/d/1wG3DP8YHkxYhfO6YdnsKER3o4AXvHrkVS1aMk2aUIRI/&#34;&gt;識別出遠距團隊的 bad smell&lt;/a&gt;〉演講中提到，遠距團隊協作時，將任務分解成容易 multiplex 運作的形式，較能因應非同步的工作型態，也有較佳的依存關係：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/11/async-workflow.png&#34; alt=&#34;From: Ailin〈識別出遠距團隊的 bad smell〉&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/11/async-workflow.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;From: Ailin〈識別出遠距團隊的 bad smell〉&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;「平準化」是非常敏捷的目標狀態，這也呼應了我在〈&lt;a href=&#34;//william-yeh.net/post/2023/10/criticism-about-timebox/&#34;&gt;Timebox 是死胡同嗎？&lt;/a&gt;〉一文的論點。以「少量多樣」方式運作的團隊越多，工作分解得越落實，彼此之間的 dependency 就越有機會迅速解決，這樣才大規模敏捷得起來：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;granularity 愈小，也愈有將它 fit in 到相關團隊 upcoming sprints 的可能性；尤其當對方團隊也是 short timebox 風格，就更容易 fit in 進去——這是 opportunity。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;所以，在這變動的時代，工作分解技能不僅是個人必備，更是敏捷團隊必備的工作基因。在實踐敏捷時，千萬不要輕忽這個基本功。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【敏捷的工作分解方法】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2016/10/one-week-sprint/&#34;&gt;One-Week Sprint 的節奏&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/10/agile-milestone/&#34;&gt;事情做一半，等於沒完成：淺談敏捷的里程碑設定&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;以「蜘蛛法」拆分過於龐大的 User Story&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/08/story-to-tasks/&#34;&gt;很簡單的 Story，也要拆分出 Tasks 嗎？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ 變動的時代，為什麼工作分解技能更是必備？&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;其實舊時代並不是變動較少，而是舊時代想不出比較好的方法去處理變動，於是就只能祭出種種禁止變動的規定：合約、契約、規格書。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;請見【&lt;a href=&#34;//william-yeh.net/post/2022/08/career-reading-club-2/&#34;&gt;職涯躍升書系導讀會，Part 2：高效團隊的工作方法&lt;/a&gt;】。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;》提到：「對於製造端來說，就出現幾項重點要克服：①產線小批生產的效率，②換線速度、清機速度，③新產品的品質良品條件，④生管對庫存的掌握度。」&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Agile Success Recipes: Example Agendas for Efficient Scrum Ceremonies</title>
      <link>//william-yeh.net/post/2023/11/scrum-events-agenda/</link>
      <pubDate>Fri, 03 Nov 2023 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/11/scrum-events-agenda/</guid>
      
        <description>&lt;p&gt;If you&amp;rsquo;re new to leading Scrum events, knowing what to do can be tough. Having a set agenda can make things easier for you and your team. It helps everyone know what to expect.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve got my own agendas that work for me, but it&amp;rsquo;s a good idea to get different takes. Why not ask ChatGPT to suggest some? The examples you&amp;rsquo;ll see here came from ChatGPT 4 and were adapted by me. Use them as a guide and tweak them to fit what your team needs.&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/11/scrum-events.png&#34; alt=&#34;Generated by ChatGPT4 &amp;#43; DALL·E 3&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/11/scrum-events.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Generated by ChatGPT4 &amp;#43; DALL·E 3&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;planning&#34;&gt;Planning&lt;/h2&gt;
&lt;p&gt;A Scrum Planning Meeting is an essential event in the Sprint cycle, where the team collaborates to define what can be delivered in the upcoming sprint and how that work will be achieved. Here&amp;rsquo;s a detailed agenda for a 2-hour Scrum Planning Meeting:&lt;/p&gt;
&lt;h3 id=&#34;-sprint-goals-setting&#34;&gt;① Sprint Goals Setting&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To define the overarching goals of the upcoming sprint.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Product Owner presents the top items in the product backlog.&lt;/li&gt;
&lt;li&gt;Team discusses how these items contribute to the product goal.&lt;/li&gt;
&lt;li&gt;Team collaborates to formulate Sprint Goals that align with the Product Goal.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: Defined Sprint Goals that are agreed upon by the team.&lt;/p&gt;
&lt;h3 id=&#34;-backlog-refinement-and-prioritization&#34;&gt;② Backlog Refinement and Prioritization&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 30 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To refine and prioritize the backlog items that can help achieve the Sprint Goals.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Product Owner discusses the priority of backlog items.&lt;/li&gt;
&lt;li&gt;Developers asks clarifying questions and discusses dependencies.&lt;/li&gt;
&lt;li&gt;Team collectively decides on the items to bring into the Sprint, based on priority and capacity.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A prioritized list of backlog items for the Sprint.&lt;/p&gt;
&lt;h3 id=&#34;-task-identification&#34;&gt;③ Task Identification&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 30 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To break down backlog items into actionable tasks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For each backlog item, the team discusses what needs to be done and its Acceptance Criteria.&lt;/li&gt;
&lt;li&gt;Developers volunteer for tasks or tasks are assigned based on expertise.&lt;/li&gt;
&lt;li&gt;Each task is estimated (usually in hours).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A list of detailed tasks with initial estimates and assignees.&lt;/p&gt;
&lt;h3 id=&#34;-sprint-capacity-planning&#34;&gt;④ Sprint Capacity Planning&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 20 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To confirm the team&amp;rsquo;s capacity and ensure the Sprint is realistic.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Each team member discusses their availability and potential impediments.&lt;/li&gt;
&lt;li&gt;Team evaluates historical velocity and capacity for the new sprint.&lt;/li&gt;
&lt;li&gt;Adjust the Sprint backlog, if necessary, based on capacity discussions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: An adjusted Sprint backlog that matches the team’s capacity.&lt;/p&gt;
&lt;h3 id=&#34;-risk-identification-and-mitigation&#34;&gt;⑤ Risk Identification and Mitigation&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To identify potential risks and plan for mitigation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brainstorming possible risks that could impact the Sprint.&lt;/li&gt;
&lt;li&gt;Discussion of risk severity and probability.&lt;/li&gt;
&lt;li&gt;Development of a basic risk mitigation strategy for the highest priority risks.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A list of identified risks with a basic mitigation plan.&lt;/p&gt;
&lt;h3 id=&#34;-definition-of-done-dod-review&#34;&gt;⑥ Definition of Done (DoD) Review&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 10 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To ensure everyone has a clear understanding of what &amp;ldquo;Done&amp;rdquo; means for a Sprint item.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Review the Definition of Done criteria.&lt;/li&gt;
&lt;li&gt;Discuss any updates needed to the DoD based on previous sprint retrospectives.&lt;/li&gt;
&lt;li&gt;Confirm everyone&amp;rsquo;s understanding and agreement.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A confirmed Definition of Done for the current Sprint.&lt;/p&gt;
&lt;h3 id=&#34;-closing-and-commitment&#34;&gt;⑦ Closing and Commitment&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 10 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To finalize the plan and obtain commitment from each team member.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Recap the Sprint Goals, Sprint backlog, risks, and DoD.&lt;/li&gt;
&lt;li&gt;Each team member verbally commits to the Sprint and their respective tasks.&lt;/li&gt;
&lt;li&gt;Address any final concerns or questions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: The team&amp;rsquo;s commitment to the Sprint Plan and clarity on the next steps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Total Duration&lt;/strong&gt;: 2 hours&lt;/p&gt;
&lt;p&gt;By the end of this meeting, the Scrum team should have a clear understanding of what they are aiming to achieve in the upcoming sprint, a plan for how to get there, and a commitment to the sprint objectives. The meeting&amp;rsquo;s success is contingent on active participation from all team members and clear communication from the Product Owner and the Scrum Master.&lt;/p&gt;
&lt;h2 id=&#34;product-backlog-refinement&#34;&gt;Product Backlog Refinement&lt;/h2&gt;
&lt;p&gt;A Product Backlog Refinement (PBR) meeting is where the Scrum Team reviews items on the Product Backlog to ensure they are appropriately prioritized and detailed enough for future sprints. Here&amp;rsquo;s an agenda for a 2-hour Product Backlog Refinement meeting:&lt;/p&gt;
&lt;h3 id=&#34;-review-of-current-backlog-status&#34;&gt;① Review of Current Backlog Status&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To give the team an overview of the current state of the Product Backlog.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Product Owner provides a quick recap of the current priorities.&lt;/li&gt;
&lt;li&gt;Quick review of the progress made since the last refinement session.&lt;/li&gt;
&lt;li&gt;Highlight any new market/customer insights that may impact the backlog.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: Shared understanding of the starting point for refinement.&lt;/p&gt;
&lt;h3 id=&#34;-high-priority-items-deep-dive&#34;&gt;② High-Priority Items Deep Dive&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 40 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To discuss and refine the highest-priority backlog items.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Product Owner presents the top items needing refinement.&lt;/li&gt;
&lt;li&gt;Developers discuss each item&amp;rsquo;s requirements, asking questions for clarification.&lt;/li&gt;
&lt;li&gt;Refinement of Acceptance Criteria for each item.&lt;/li&gt;
&lt;li&gt;Preliminary estimation of effort if ready for estimation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: Refined high-priority backlog items with clear Acceptance Criteria.&lt;/p&gt;
&lt;h3 id=&#34;-estimation-session&#34;&gt;③ Estimation Session&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 30 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To estimate the effort required for the refined backlog items.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Quick review of estimation techniques (e.g., story points, T-shirt sizes).&lt;/li&gt;
&lt;li&gt;Team engages in estimating effort using chosen technique (e.g., Planning Poker).&lt;/li&gt;
&lt;li&gt;Discussion and agreement on estimates; re-estimation if needed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: Estimated efforts for the refined backlog items.&lt;/p&gt;
&lt;h3 id=&#34;-mid-to-low-priority-items-review&#34;&gt;④ Mid-to-Low Priority Items Review&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 20 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To assess and refine mid-to-low priority items for future sprints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Briefly review each item and decide whether it should stay in the backlog.&lt;/li&gt;
&lt;li&gt;Update or provide a rough estimation of the items based on new insights.&lt;/li&gt;
&lt;li&gt;Re-prioritize items, if necessary, based on the team&amp;rsquo;s discussions.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: An updated and re-prioritized mid-to-low priority backlog segment.&lt;/p&gt;
&lt;h3 id=&#34;-story-splitting-and-dependency-analysis&#34;&gt;⑤ Story Splitting and Dependency Analysis&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To break down complex items and identify dependencies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identify large user stories that can be split into smaller, more manageable ones.&lt;/li&gt;
&lt;li&gt;Discuss and document any dependencies between backlog items.&lt;/li&gt;
&lt;li&gt;Agree on an approach for handling identified dependencies.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A list of smaller user stories and a map of item dependencies.&lt;/p&gt;
&lt;h3 id=&#34;-backlog-health-check-and-clean-up&#34;&gt;⑥ Backlog Health Check and Clean-up&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To remove or update outdated items and ensure the backlog remains relevant and manageable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Review low-priority items for relevance and potential removal.&lt;/li&gt;
&lt;li&gt;Discuss any items that haven&amp;rsquo;t moved in a long time (backlog stagnation).&lt;/li&gt;
&lt;li&gt;Decide on next steps for each outdated item (e.g., keep, transform, or remove).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A refined and clean backlog free from outdated or irrelevant items.&lt;/p&gt;
&lt;h3 id=&#34;-wrap-up-and-action-items&#34;&gt;⑦ Wrap-up and Action Items&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To summarize the session and outline next steps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Recap the decisions made during the session.&lt;/li&gt;
&lt;li&gt;Assign any action items for further clarification or research.&lt;/li&gt;
&lt;li&gt;Confirm the date for the next refinement session.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A clear set of action items and a timeline for completion.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Total Duration&lt;/strong&gt;: 2 hours&lt;/p&gt;
&lt;p&gt;The purpose of this meeting is to ensure that the Product Backlog is continuously updated to reflect the project&amp;rsquo;s current needs and to prepare for upcoming Sprint Planning. It&amp;rsquo;s important for the Product Owner to facilitate the meeting, with the Scrum Master ensuring that the team stays on track and that each item on the agenda is given adequate time for discussion.&lt;/p&gt;
&lt;h2 id=&#34;review&#34;&gt;Review&lt;/h2&gt;
&lt;p&gt;The Sprint Review meeting is held at the end of each Sprint to inspect the increment and adapt the Product Backlog if needed. Here’s an agenda for a 1-hour Sprint Review meeting:&lt;/p&gt;
&lt;h3 id=&#34;-sprint-overview&#34;&gt;① Sprint Overview&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 5 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To provide a quick recap of the Sprint goals and context for the work completed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Scrum Master or Product Owner summarizes the goals and main objectives of the Sprint.&lt;/li&gt;
&lt;li&gt;A brief overview of the Sprint deliverables is provided.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A clear context for stakeholders and the team about what was intended for the Sprint.&lt;/p&gt;
&lt;h3 id=&#34;-demonstration-of-done-work&#34;&gt;② Demonstration of Done Work&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 25 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To showcase the work that has been completed during the Sprint.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Developers&lt;/span&gt;
 presents the completed work and how it meets the “Definition of Done”.&lt;/li&gt;
&lt;li&gt;Stakeholders are given the opportunity to see the product increment in action.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A demonstrated increment of the product that is potentially shippable.&lt;/p&gt;
&lt;h3 id=&#34;-product-backlog-review-and-adaptation&#34;&gt;③ Product Backlog Review and Adaptation&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 10 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To discuss changes in the Product Backlog based on the Sprint&amp;rsquo;s outcomes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Product Owner discusses the current state of the Product Backlog and any changes due to the Sprint.&lt;/li&gt;
&lt;li&gt;A brief review of upcoming items on the backlog is made.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: An updated Product Backlog that reflects the outcomes of the Sprint and any new information.&lt;/p&gt;
&lt;h3 id=&#34;-stakeholder-feedback-and-discussion&#34;&gt;④ Stakeholder Feedback and Discussion&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To receive feedback from stakeholders and discuss what is next.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stakeholders provide feedback on the increment and discuss additional needs or changes.&lt;/li&gt;
&lt;li&gt;Open discussion between the team and stakeholders to understand the feedback&amp;rsquo;s implications.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: Valuable feedback from stakeholders that can be turned into actionable backlog items.&lt;/p&gt;
&lt;h3 id=&#34;-wrap-up-and-closing&#34;&gt;⑤ Wrap-Up and Closing&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 5 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To conclude the meeting, summarize the outcomes, and discuss next steps.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Summarize the feedback and key points from the demonstration.&lt;/li&gt;
&lt;li&gt;Agree on any immediate action items or follow-up meetings if necessary.&lt;/li&gt;
&lt;li&gt;The Scrum Master ensures everyone is clear about the outcomes of the Review.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A clear conclusion to the Sprint Review, with agreed-upon action items and follow-ups.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Total Duration&lt;/strong&gt;: 1 hour&lt;/p&gt;
&lt;p&gt;In the Sprint Review, the focus is on collaboration and feedback. It is not a one-sided presentation but an interactive session involving the Scrum Team and stakeholders. The goal is to provide a platform for open communication, foster transparency, and create a shared understanding of where the product is and where it is headed. The Scrum Master facilitates the event to ensure it is productive and stays within the timebox.&lt;/p&gt;
&lt;h2 id=&#34;retrospective&#34;&gt;Retrospective&lt;/h2&gt;
&lt;p&gt;The Sprint Retrospective is an opportunity for the Scrum Team to inspect itself and create a plan for improvements to be enacted during the next Sprint. Here&amp;rsquo;s an agenda for a structured 1-hour Sprint Retrospective:&lt;/p&gt;
&lt;h3 id=&#34;-setting-the-stage&#34;&gt;① Setting the Stage&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 5 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To establish a focus for the Retrospective and ensure that everyone is mentally prepared to engage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The Scrum Master opens the meeting with a brief introduction and objectives of the Retrospective.&lt;/li&gt;
&lt;li&gt;A short icebreaker or check-in to get the team comfortable sharing their thoughts.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A team that is ready to engage in open and honest discussion.&lt;/p&gt;
&lt;h3 id=&#34;-gather-data&#34;&gt;② Gather Data&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To create a shared picture of what happened during the Sprint from different perspectives.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Team members list highlights and lowlights of the Sprint, noting achievements and challenges.&lt;/li&gt;
&lt;li&gt;Use of timelines, histograms, or sprint burndown charts to visualize the Sprint data.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: An overview of the Sprint&amp;rsquo;s events, data, and emotional journey.&lt;/p&gt;
&lt;h3 id=&#34;-generate-insights&#34;&gt;③ Generate Insights&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To understand the &amp;lsquo;why&amp;rsquo; behind successes and challenges.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Discussion around the gathered data to identify patterns and root causes of issues.&lt;/li&gt;
&lt;li&gt;Use techniques like &amp;lsquo;5 Whys&amp;rsquo; or &amp;lsquo;Fishbone diagram&amp;rsquo; to explore causes and effects.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: Identified key areas of improvement and reasons behind the Sprint&amp;rsquo;s dynamics.&lt;/p&gt;
&lt;h3 id=&#34;-decide-what-to-do&#34;&gt;④ Decide What to Do&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 15 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To agree on actionable commitments that address the identified improvements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Brainstorm potential solutions or improvements.&lt;/li&gt;
&lt;li&gt;Prioritize the ideas and decide on a manageable number of items to take action on.&lt;/li&gt;
&lt;li&gt;Formulate action items with clear owners and deadlines.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: A list of actionable improvements for the next Sprint with defined responsibilities.&lt;/p&gt;
&lt;h3 id=&#34;-closing-the-retrospective&#34;&gt;⑤ Closing the Retrospective&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Length&lt;/strong&gt;: 10 minutes&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: To summarize the meeting and ensure a clear way forward.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Review the agreed-upon action items and ensure everyone is clear on their next steps.&lt;/li&gt;
&lt;li&gt;Quick roundtable for each member to express their feelings about the Retrospective.&lt;/li&gt;
&lt;li&gt;The Scrum Master thanks the team, possibly with some motivational closing words.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: Confirmation of the Retrospective&amp;rsquo;s action plan and team buy-in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Total Duration&lt;/strong&gt;: 1 hour&lt;/p&gt;
&lt;p&gt;The Retrospective should foster an atmosphere of transparency and trust, encouraging all team members to share their views constructively. It&amp;rsquo;s important to focus on continuous improvement and not on placing blame. The Scrum Master’s role is to facilitate this process, ensuring the meeting remains positive and productive.&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;As we wrap up this guide on Scrum ceremonies, remember that the agendas and examples provided are starting points—tools to be refined as you grow in your role and as your team evolves. Embrace the flexibility of Scrum, and don&amp;rsquo;t shy away from customizing these frameworks to better fit the unique rhythms of your team&amp;rsquo;s workflow. Your journey as a Scrum Master is about facilitating progress and fostering collaboration, and with these tailored agendas, you&amp;rsquo;re well-equipped to steer your team towards continuous improvement and success. Keep iterating, keep learning, and most importantly, keep your team engaged. Here&amp;rsquo;s to the productive sprints ahead!&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      &amp;#39;Essence of Scrum&amp;#39; Series
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2020/07/pbr-in-a-nutshell/&#34;&gt;Product Backlog Refinement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2020/08/daily-scrum-in-a-nutshell/&#34;&gt;Daily Scrum&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-planning-in-a-nutshell/&#34;&gt;Sprint Planning&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-review-in-a-nutshell/&#34;&gt;Sprint Review&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ Agile Success Recipes: Example Agendas for Efficient Scrum Ceremonies&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>[Code Review 碎碎念] 簡化巢狀條件判斷式</title>
      <link>//william-yeh.net/post/2023/10/nested-conditional/</link>
      <pubDate>Thu, 12 Oct 2023 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/10/nested-conditional/</guid>
      
        <description>&lt;p&gt;讀別人的程式是一件苦差事，不僅需要具備對應的領域知識，也得了解對方的程式書寫邏輯與風格。因此，為了讓程式碼容易被人理解，整潔程式碼是必須持續精進的技藝。&lt;/p&gt;
&lt;p&gt;在 code review 進行實質審查之前，我喜歡先做一點點形式審查，尤其是某些 code smell，臭味暴風半徑大到甚至連領域知識的外行人都聞得到。&lt;/p&gt;
&lt;p&gt;我很常遇到不必要的巢狀迴圈或條件判斷式。經驗告訴我，除非真的是要設計出什麼高大尚的演算法或者刷題，否則，這有相當大的機率是需要進一步 refactor 的。&lt;/p&gt;
&lt;p&gt;像以下這段程式，即使我故意把領域知識相關細節用 &lt;code&gt;conditionXX&lt;/code&gt; 馬賽克掉了，你還是可以明顯聞到 bad smell：迴圈 + 條件判斷式，ABCDEF 深達 6 層，你能夠很快捕捉到箇中邏輯嗎？&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# condition placeholders&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;condition1 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; condition2 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; condition3 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; condition4 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; condition5 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; condition6 &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;lambda&lt;/span&gt; x : &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;data &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;# area code -&amp;gt; city name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { &lt;span style=&#34;color:#ae81ff&#34;&gt;201&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Jersey City&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;206&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Seattle&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { &lt;span style=&#34;color:#ae81ff&#34;&gt;212&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;New York&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;213&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Los Angeles&amp;#39;&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { &lt;span style=&#34;color:#ae81ff&#34;&gt;226&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;London&amp;#39;&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;236&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;Vancouver&amp;#39;&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;demo1&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; item &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; data:    &lt;span style=&#34;color:#75715e&#34;&gt;# A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition1(item):    &lt;span style=&#34;color:#75715e&#34;&gt;# B1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; pair &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; item&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;items():  &lt;span style=&#34;color:#75715e&#34;&gt;# C&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                print(pair)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition2(pair):      &lt;span style=&#34;color:#75715e&#34;&gt;# D&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition3(pair):     &lt;span style=&#34;color:#75715e&#34;&gt;# E&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition4(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# F1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 1&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; condition5(pair):  &lt;span style=&#34;color:#75715e&#34;&gt;# F2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 2&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:    &lt;span style=&#34;color:#75715e&#34;&gt;# B2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 3&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;再往下看之前，請先自己嘗試 refactor 看看。&lt;/p&gt;
&lt;h2 id=&#34;頭重腳輕&#34;&gt;頭重腳輕&lt;/h2&gt;
&lt;p&gt;通常我會先針對頭重腳輕的 if-else 開刀。&lt;/p&gt;
&lt;p&gt;頭重腳輕的 if-else 有什麼問題呢？請試著將以下的程式讀到第 4 行，然後稍作暫停：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt;:     &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition1(item):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;02&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;03&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;04&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# many lines of code... (頭重)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;05&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;06&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;07&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;:     &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;21&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# only 1 line of code (腳輕)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;此刻，儘管你才讀到第 4 行，但應該會有個懸念：「究竟 if 的另一隻腳 else 會是什麼？」可是你要一直往下讀到第 20 行，謎底才會揭曉。&lt;/p&gt;
&lt;p&gt;這種懸念，有個心理學名詞：Zeigarnik effect（常譯為齊加尼克效應、蔡加尼克效應）。&lt;/p&gt;
&lt;p&gt;這種懸念，會增加我們的認知負荷，瓜分我們的專注力————閱讀程式碼，是最需要專注力的。&lt;/p&gt;
&lt;p&gt;如果換個順序，頭輕腳重，就可以盡早排除懸念，因為懸念早在你讀到第 3 行就已結束：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;01&lt;/span&gt;:     &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; condition1(item):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;02&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# only 1 line of code (頭輕)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;03&lt;/span&gt;:     &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;04&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;05&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;06&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# many lines of code... (腳重)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;07&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;08&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;09&lt;/span&gt;:         &lt;span style=&#34;color:#75715e&#34;&gt;# ...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;將這一招套用在本文一開頭的範例程式，可以改寫成：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;demo2&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; item &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; data:    &lt;span style=&#34;color:#75715e&#34;&gt;# A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; condition1(item):    &lt;span style=&#34;color:#75715e&#34;&gt;# B1 + B2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 3&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; pair &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; item&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;items():   &lt;span style=&#34;color:#75715e&#34;&gt;# C&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(pair)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition2(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# D&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition3(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# E&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition4(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# F1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 1&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; condition5(pair):  &lt;span style=&#34;color:#75715e&#34;&gt;# F2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 2&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;這一招，在 &lt;a href=&#34;https://martinfowler.com/books/refactoring.html&#34;&gt;&lt;em&gt;Refactoring&lt;/em&gt;&lt;/a&gt; 書中叫做 &amp;ldquo;Replace Nested Conditional with Guard Clauses&amp;rdquo;。 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;整併&#34;&gt;整併&lt;/h2&gt;
&lt;p&gt;連續的巢狀 if，往往給讀者一種「這裡一定藏著很複雜的邏輯」的感覺————或者錯覺。如有可能，應該嘗試用 and 及 or 加以整併。&lt;/p&gt;
&lt;p&gt;像前面的範例程式，如果繼續將 condition2 &amp;amp; condition3 整併，巢狀深度降低了，是不是更易讀呢？&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;demo3&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; item &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; data:    &lt;span style=&#34;color:#75715e&#34;&gt;# A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; condition1(item):    &lt;span style=&#34;color:#75715e&#34;&gt;# B1 + B2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 3&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; pair &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; item&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;items():   &lt;span style=&#34;color:#75715e&#34;&gt;# C&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(pair)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition2(pair) &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; condition3(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# D + E&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition4(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# F1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 1&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; condition5(pair):  &lt;span style=&#34;color:#75715e&#34;&gt;# F2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 2&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;如果行有餘力，甚至還可以替整併起來的條件判斷式取個有意義的名字（function 或 lambda 或 method），程式碼就更具有自我詮釋的功能：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python3&#34; data-lang=&#34;python3&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;demo4&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; item &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; data:    &lt;span style=&#34;color:#75715e&#34;&gt;# A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; condition1(item):    &lt;span style=&#34;color:#75715e&#34;&gt;# B1 + B2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 3&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; pair &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; item&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;items():   &lt;span style=&#34;color:#75715e&#34;&gt;# C&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(pair)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition6(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# D + E&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition4(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# F1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 1&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; condition5(pair):  &lt;span style=&#34;color:#75715e&#34;&gt;# F2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 2&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;這一招，在 &lt;a href=&#34;https://martinfowler.com/books/refactoring.html&#34;&gt;&lt;em&gt;Refactoring&lt;/em&gt;&lt;/a&gt; 書中叫做 &amp;ldquo;Consolidate Conditional Expression&amp;rdquo;。 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Refactor 到這裡，如果你還不滿意，還可以再套用一次 &amp;ldquo;Replace Nested Conditional with Guard Clauses&amp;rdquo; 手法：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;demo5&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; item &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; data:    &lt;span style=&#34;color:#75715e&#34;&gt;# A&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; condition1(item):    &lt;span style=&#34;color:#75715e&#34;&gt;# B1 + B2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 3&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; pair &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; item&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;items():   &lt;span style=&#34;color:#75715e&#34;&gt;# C&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            print(pair)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; condition6(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# D + E&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; condition4(pair):    &lt;span style=&#34;color:#75715e&#34;&gt;# F1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 1&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; condition5(pair):  &lt;span style=&#34;color:#75715e&#34;&gt;# F2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                print(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;CASE 2&amp;#39;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;需不需要做到這地步？&lt;/p&gt;
&lt;p&gt;看情況。反正整段程式的邏輯結構已經很清晰易讀了，&lt;a href=&#34;https://en.wikipedia.org/wiki/Cyclomatic_complexity&#34;&gt;cyclomatic complexity&lt;/a&gt; 也已經降得很低了：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% radon cc -s demo.py
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;demo.py
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    F 11:0 demo1 - B &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    F 26:0 demo2 - B &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    F 42:0 demo3 - B &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;8&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    F 57:0 demo4 - B &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;7&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    F 72:0 demo5 - B &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;7&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;chatgpt-怎麼說&#34;&gt;ChatGPT 怎麼說&lt;/h2&gt;
&lt;p&gt;聽說 ChatGPT 都快要取代程式設計師了，我們就來看看 ChatGPT 會怎麼 refactor 第一段程式。&lt;/p&gt;
&lt;p&gt;Prompt: &lt;code&gt;Refactor the following Python code with less nested structure.&lt;/code&gt;&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/10/refactor-with-chatgpt.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/10/refactor-with-chatgpt.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;大體上方向是對的，只是在 condition3 ~ condition5 的地方疑似因為 Python 縮排判斷錯誤。&lt;/p&gt;
&lt;p&gt;嗯，大家真的要加油了，不要輸給 ChatGPT 呀。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;如果你手邊沒有 &lt;a href=&#34;https://martinfowler.com/books/refactoring.html&#34;&gt;&lt;em&gt;Refactoring&lt;/em&gt;&lt;/a&gt;  這本書，可參考以下兩篇文章學習 &amp;ldquo;Replace Nested Conditional with Guard Clauses&amp;rdquo; 手法：&lt;a href=&#34;https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html&#34;&gt;文章 1&lt;/a&gt; &amp;amp; &lt;a href=&#34;https://refactoring.guru/replace-nested-conditional-with-guard-clauses&#34;&gt;文章 2&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;如果你手邊沒有 &lt;a href=&#34;https://martinfowler.com/books/refactoring.html&#34;&gt;&lt;em&gt;Refactoring&lt;/em&gt;&lt;/a&gt;  這本書，可參考以下兩篇文章學習 &amp;ldquo;Consolidate Conditional Expression&amp;rdquo; 手法：&lt;a href=&#34;https://refactoring.com/catalog/consolidateConditionalExpression.html&#34;&gt;文章 1&lt;/a&gt; &amp;amp; &lt;a href=&#34;https://refactoring.guru/consolidate-conditional-expression&#34;&gt;文章 2&lt;/a&gt;。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Timebox 是死胡同嗎？</title>
      <link>//william-yeh.net/post/2023/10/criticism-about-timebox/</link>
      <pubDate>Tue, 10 Oct 2023 10:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/10/criticism-about-timebox/</guid>
      
        <description>&lt;p&gt;許多敏捷手法都奠基於 timebox。那麼，為什麼有人會認為 timebox 路線是死胡同呢？有此論點的人，偏偏又是敏捷圈的重量級人物呢。&lt;/p&gt;
&lt;p&gt;看板方法之父 David J. Anderson 在新書 &lt;a href=&#34;https://www.amazon.com/dp/1960442074&#34;&gt;&lt;em&gt;Discovering Kanban&lt;/em&gt;&lt;/a&gt; 第 15 章對於 Scrum 之類基於 timebox 的方法有頗露骨的批評（光從標題 &amp;ldquo;The Tyranny of the Ever-Decreasing Timebox&amp;rdquo; 就看得出來）。正好好友 Derek 在 〈&lt;a href=&#34;https://medium.com/agile-coffee/discovering-kanban-18d9b2ac9be2&#34;&gt;《Discovering Kanban》心得：Scrum 可能沒有你想像的那麼美好&lt;/a&gt;〉一文整理了這一章的摘要與閱讀心得，在網路上也引發一些討論 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，我便趁此機會細讀這一章。&lt;/p&gt;
&lt;p&gt;這一章論點非常深刻。但讀著讀著，總覺得作者道出的結論 &amp;ldquo;time-constrained sprints are an evolutionary cul-de-sac, a dead end&amp;rdquo;，與我直接或間接所知的業界實踐現況，並不相符。我猜想：會不會是某個推論環節出了些問題？&lt;/p&gt;
&lt;p&gt;因此，我嘗試用系統思考角度去梳理相關論述。我試圖用更清晰的因果關係秀出 timebox 路線被點名的痛點，以及常見的因應之道。至於這痛點是否真的已被解決了，則留待讀者思考，不在此文的探討範圍。&lt;/p&gt;
&lt;h2 id=&#34;目標相同途徑各異&#34;&gt;目標相同，途徑各異&lt;/h2&gt;
&lt;p&gt;首先，David J. Anderson 是贊同 small batch 小批量的。他明確指出小批量的三大優點：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;the advantages of smaller batches—&lt;strong&gt;higher quality&lt;/strong&gt;, &lt;strong&gt;more frequent interaction&lt;/strong&gt; between customers and the delivery organization, and potential gains from &lt;strong&gt;earlier delivery&lt;/strong&gt; of valuable work (also known as the avoidance of opportunity cost of delay)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;他接著指出，欲達小批量的目標，有兩種常見的途徑，一個是 timebox，另一個是 WIP limit：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are two ways to constrain the batch size of work: &lt;strong&gt;Constraining the amount of time&lt;/strong&gt; available to do the work, resulting in scoping to small numbers of requests that can be completed in the given time; or simply &lt;strong&gt;constraining the number of work items&lt;/strong&gt;, constraining the size of the batch of requests, also known as WIP constraints.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;此處姑且小結一下，David J. Anderson 是贊同 small batch 的（至少在整本書我還沒找到反對的段落），但主張透過 WIP limit 的方式達到小批量，反對透過 timebox 的方式達到小批量。&lt;/p&gt;
&lt;p&gt;他認為 timebox 劣於 WIP 的地方是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This switch from a time constraint to a WIP constraint free you from the tyranny of the timebox and it&amp;rsquo;s three dysfunctions of &lt;strong&gt;upfront analysis&lt;/strong&gt;, &lt;strong&gt;excessive and costly estimation&lt;/strong&gt;, and &lt;strong&gt;heavy-weight dependency management&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;接下來我們就來看看他反對 timebox 的理由。&lt;/p&gt;
&lt;h2 id=&#34;timebox-會浪費力氣在削足適履上&#34;&gt;Timebox 會浪費力氣在削足適履上？&lt;/h2&gt;
&lt;p&gt;David J. Anderson 認為，timebox 愈短，就愈是需要花力氣在 backlog item 的事前分析上，以「削足適履」進去 timebox：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;smaller timeboxes create three types of pressure that are often difficult to cope with and adjust to: First, smaller batches require an ever more detailed approach to requirements analysis and development—the need to write ever more fine-grained user stories that can be completed within the smaller time window. Second, an ever more accurate approach to estimation is needed so that a realistic commitment can be made; with smaller time windows, greater precision is required in estimation.&lt;/p&gt;
&lt;p&gt;The shorter the time box, the more upfront effort is required to estimate whether the work will fit into the available time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這段話的確指出了一部份實質存在的驅動力量，但並非全部。實務上，如果 Scrum 做得夠確實，在經驗主義的引領下，timebox 會逐漸趨於穩定態：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/10/cld-1.png&#34; alt=&#34;Timebox 會趨於平衡迴路&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/10/cld-1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Timebox 會趨於平衡迴路&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;因此，如果還需要做過多的 up-front estimation，那一定是做錯了 Scrum Planning &amp;amp; Refinement。&lt;/p&gt;
&lt;p&gt;David J. Anderson 又進一步評論道：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;there is still, after twenty-plus years of Agile, little or no solid guidance on writing fine-grained, consistently small user stories.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這與我直接或間接所知的業界實踐現況，並不完全相符。至少我看到許多成功運用 Mike Cohn 大師提出的 &lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;SPIDR 法&lt;/a&gt;的例子。&lt;/p&gt;
&lt;h2 id=&#34;timebox-會鼓勵低交付價值&#34;&gt;Timebox 會鼓勵低交付價值？&lt;/h2&gt;
&lt;p&gt;David J. Anderson 認為，timebox 愈短，就只能交付出被削足適履出來的小碎片，這是難以被用戶察覺到交付價值的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;small-scale requirements may not be meaningful to the customer—they may not enable value. This means that if one small requirement has a peer relationship to others, they all must be delivered together in order to release value.&lt;/p&gt;
&lt;p&gt;This type of breakdown defeats the purpose of the ever-smaller timeboxes and creates a false sense of agility when, in fact, customer value and quality are not improving; perhaps even the opposite is true.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這段話的確指出了一部份實質存在的驅動力量，但並非全部。實務上，如果 Scrum 做得夠確實，在 Scrum Planning 及 Review 時，用戶有充分機會了解如此拆解的目的，並實質參與拆解的活動。因此，在經驗主義的引領下，timebox 與交付價值之間會逐漸趨於穩定態：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/10/cld-2.png&#34; alt=&#34;Timebox 與交付價值之間會趨於平衡迴路&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/10/cld-2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Timebox 與交付價值之間會趨於平衡迴路&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;事實上，從上圖可知，不只是 timebox，就連 David J. Anderson 認可的「小批量」也一樣會面臨「低交付價值」的挑戰。因此，Kanban 的淵源——Lean 陣營，即使主張小批量、one-piece flow，但對於 batch size 是否可以無限制壓縮到最小，也是持保留態度的。像《&lt;a href=&#34;https://williampjyeh.notion.site/6901e548c40c4389bf8919a74d2a1efd&#34;&gt;流的傳承&lt;/a&gt;》就提到，大野耐一主張 batch size ≥ 5。&lt;/p&gt;
&lt;h2 id=&#34;timebox-會讓-dependency-更惡化&#34;&gt;Timebox 會讓 Dependency 更惡化？&lt;/h2&gt;
&lt;p&gt;David J. Anderson 認為，timebox 愈短，dependency 造成 sprint fail 的機率也隨之增加：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What if a story in our sprint backlog gets blocked because of a dependency? That might prevent it from completing on time. Hence, the shorter the sprint timebox, the greater the need to identify dependencies up front.&lt;/p&gt;
&lt;p&gt;Fine-grained requirements analysis coupled to short timeboxed sprints introduces a dependency management problem to Agile methodologies. If a piece of work will be affected by dependencies, such dependencies need to be tracked and managed between teams and multiple sprint backlogs and potentially across sprint boundaries.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這段話的確指出了一部份實質存在的驅動力量，但並非全部。假設 dependency 條件不變，timebox 愈短，一點點的 dependency 擾動帶來的影響的確可能較大——這是 threat。可是相對的，granularity 愈小，也愈有將它 fit in 到相關團隊 upcoming sprints 的可能性；尤其當對方團隊也是 short timebox 風格，就更容易 fit in 進去——這是 opportunity。 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Threat 與 opportunity，一加一減，綜合起來的效應是好是壞，還很難說。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/10/cld-3.png&#34; alt=&#34;Granuality 與 dependency 的關係是？&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/10/cld-3.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Granuality 與 dependency 的關係是？&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;實務上，如果 Scrum 做得夠確實，在跨團隊 Refinement &amp;amp; Planning 時，已經有辨識、拆解、對齊、協調 dependency 的事情在檯面上或檯面下發生了，而且不只是消極地為了處理 dependency，更是積極地處理交付價值。&lt;/p&gt;
&lt;p&gt;事實上，這也是各家各派大規模 Scrum 框架最核心的挑戰與賣點。至於這議題是否真的已被解決了，則留待讀者思考，不在此文的探討範圍。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/10/cld-final.png&#34; alt=&#34;timebox 的 CLD 全圖&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/10/cld-final.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;timebox 的 CLD 全圖&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;kanban-又是怎麼處理-dependency-的&#34;&gt;Kanban 又是怎麼處理 dependency 的？&lt;/h2&gt;
&lt;p&gt;David J. Anderson  也承認 dependency 是個普遍現象，他也沒有神奇魔法可以讓 Kanban 免於 dependency：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dependencies are a fact of life in all but very small-scale software development or mediocre development done by largely dilettante generalists.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kanban 又是怎麼處理 dependency 的呢？從以下文字可以歸結出 global transparency 及 learning to coordinate/cooperate 這兩個方向：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Let dependencies happen as you discover them, create &lt;strong&gt;visibility&lt;/strong&gt; onto them, and actively track them. Use a service-oriented approach and define workflow kanban boards (and systems) that &lt;strong&gt;encourage cooperation&lt;/strong&gt; across functions. Don’t reorganize into cross-functional teams or attempt to design out dependencies from your product architecture; instead, start where you are and &lt;strong&gt;learn&lt;/strong&gt; to be proficient at &lt;strong&gt;coordinating&lt;/strong&gt; shared services.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這段主張，我的理解是，服務導向的看板，通常會是更縱向 end to end，也更橫向 cross functional。如果做得確實，理論上 dependency 會更早浮現，也更早讓縱向橫向的人一起面對，一起 ad hoc 處理或是 systematically 處理。&lt;/p&gt;
&lt;p&gt;看到這裡，心中不禁想到：timebox 路線不也是如此嗎？&lt;/p&gt;
&lt;h2 id=&#34;個人總結&#34;&gt;個人總結&lt;/h2&gt;
&lt;p&gt;至此，我個人認為，timebox 與 WIP limit 兩種途徑，長期的目標狀態「小批量」其實很類似，只是選擇的途徑不同，造成哪個要先關注、哪個可以等到成熟度提升之後自然就會去關注的不同優先順序。&lt;/p&gt;
&lt;p&gt;兩者的差異並沒有想像中的大，雙方只是切入的角度不同，但核心要素是很接近的；尤其是繼續精進時，會發現共同點越來越多，相互取經是司空見慣。&lt;/p&gt;
&lt;p&gt;所以我在課程中，總愛用《&lt;a href=&#34;https://zh.wikipedia.org/zh-tw/%E7%A5%9E%E4%B9%8B%E9%9B%AB&#34;&gt;神之雫&lt;/a&gt;》的最終章來比喻兩者的關係。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Derek 這篇文章，在 Facebook 引發一些討論，請見 &lt;a href=&#34;https://www.facebook.com/agilederek/posts/pfbid02YF8yCiY1oUUNnFkeRZgKzfmLVLSd3wBjKqFTC8tVrRkFE1mxhDQAWtKsZqEM4Z8nl&#34;&gt;link 1&lt;/a&gt; &amp;amp; &lt;a href=&#34;https://www.facebook.com/william.yeh/posts/pfbid034juT78DsgHtSYHjKnJ3uEcgXqU8KNSqh24th6ep1nYTXDgnyix8KMF4HjGDb2Z5Al&#34;&gt;link 2&lt;/a&gt;。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;關於這議題，我在後續的文章〈&lt;a href=&#34;//william-yeh.net/post/2023/11/why-decomposition-matters/&#34;&gt;變動的時代，為什麼工作分解技能更是必備？&lt;/a&gt;〉有更深入的探討。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>從 Code Review 的小事看到大事</title>
      <link>//william-yeh.net/post/2023/09/on-code-review/</link>
      <pubDate>Wed, 13 Sep 2023 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/09/on-code-review/</guid>
      
        <description>&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;我很喜歡 Java 大師 &lt;a href=&#34;https://en.wikipedia.org/wiki/Joshua_Bloch&#34;&gt;Joshua Bloch&lt;/a&gt; 在《&lt;a href=&#34;https://williampjyeh.notion.site/d265b736b05f42d885ef40bb0a48786f&#34;&gt;編程的頂尖對話&lt;/a&gt;》所說的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;即使是想把一個很小的程式寫對也是非常難的。&lt;/p&gt;
&lt;p&gt;認為自己程式沒有 bug 就是在愚弄自己。程式肯定有 bug，（只是）多數情況下，程式裡的 bug 夠少，足以使其完成任務。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;是的，100% 正確的程式或許很難達成，或許連定義起來都很困難，但我們還是得努力趨近它，讓我們工作更有成就感，更有信心能夠交付價值，也更少因不慎流出去的瑕疵而疲於奔命。&lt;/p&gt;
&lt;p&gt;Joshua Bloch 緊接著又說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;既然寫正確的程式那麼困難，我們就應該盡力取得幫助。所以，能減少 bug 的所有東西都是好的。這就是我是靜態型別和靜態分析的信徒的原因。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;是的，我們需要動員許多力量，取得許多幫助，才能夠趨近於正確的程式。可動員的許多力量當中，無疑的 code review 是重要的基礎，可惜的是，許多團隊連這基礎都還有諸多可改善之處，這也限縮了團隊能進一步發揮的價值。&lt;/p&gt;
&lt;p&gt;Code review 乍看之下是小事，但若認真探討起來還真是不小。在我多年輔導各種成熟度團隊的經驗中，有六個基於 code review 以及衍生出來的議題可深入探討：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;基本信念：品質來自正確地做事&lt;/li&gt;
&lt;li&gt;掌握基本功與領域知識&lt;/li&gt;
&lt;li&gt;凝聚團隊公約的共識&lt;/li&gt;
&lt;li&gt;嘗試更好的協同理解技巧&lt;/li&gt;
&lt;li&gt;讓進步看得見&lt;/li&gt;
&lt;li&gt;支持長久研發的措施&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你所在的團隊已經啟動 Scrum 或 Kanban 研發流程，恭喜你，你們已經有很好的流程基礎可在這六大議題上面精進，只需要正確實施（玩真的！）你們所採用的敏捷流程。文中我會大量連結到 Scrum 及 Kanban 的要素。請確實「守」你們該守的流程，不要驟然「破」或「離」。&lt;/p&gt;
&lt;p&gt;全文很長，如果你是現役的程式設計師，可先讀①②以瞭解 engineering disciplines；如果你是 team lead，可先讀③④以瞭解團隊動力；如果你是管理層，可先讀⑤⑥，尤其是⑤關於管理面的施力點。&lt;/p&gt;
&lt;h2 id=&#34;-基本信念品質來自正確地做事&#34;&gt;① 基本信念：品質來自正確地做事&lt;/h2&gt;
&lt;p&gt;Code review，甚至任何一種 review，都源自一個單純的理由：多一個人來確保品質。&lt;/p&gt;
&lt;p&gt;品質是計畫、設計和內建而來的，不是靠檢驗出來的。換言之，品質來自正確地做事。&lt;/p&gt;
&lt;p&gt;怎樣才叫做「正確地做事」？&lt;/p&gt;
&lt;p&gt;談「正確地做事」之前，先確定我們擁有共同的基本信念。&lt;/p&gt;
&lt;h3 id=&#34;collective-ownership&#34;&gt;Collective ownership&lt;/h3&gt;
&lt;p&gt;Odd-e 三位專家在 2023-08-31 晚上有一場很精彩的 webinar【高效 Scrum 團隊所需的能力】。在 &lt;a href=&#34;https://www.youtube.com/watch?v=13clptdw6J8&amp;amp;t=3816s&#34;&gt;1h:03m:36s&lt;/a&gt; 聊到「工程能力」時，有一句語重心長的話：「所有跟 eXtreme Programming 相關的工程能力都很重要。」&lt;/p&gt;
&lt;p&gt;eXtreme Programming (XP) 第一版與第二版提到許多工程實踐，此刻我想特別點出 &amp;ldquo;&lt;a href=&#34;http://extremeprogramming.org/rules/collective.html&#34;&gt;collective ownership&lt;/a&gt;&amp;rdquo; 這一條：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Collective Ownership encourages everyone to contribute new ideas to all segments of the project. No one person becomes a bottleneck for changes.&lt;/p&gt;
&lt;p&gt;In practice collective ownership is actually more reliable than putting a single person in charge of watching specific classes. Especially since a person may leave the project at any time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;積極面來說，collective ownership 可善用集體智慧提升設計品質，可促成知識共享，消極面則可降低公車指數 (bus factor)。 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;萬一連 &amp;ldquo;collective ownership&amp;rdquo; 都不是團隊想要追求的境界，或許這個團隊從一開始的組成階段 (team forming) 就有問題了；我建議，解決了之後，再談以下的議題吧。否則，連「共同持有」的心態都沒有，還有什麼動機要去 review 別人的 code 呢？&lt;/p&gt;
&lt;h3 id=&#34;four-eyes-principle&#34;&gt;Four-eyes principle&lt;/h3&gt;
&lt;p&gt;Code review 的出發點很單純：多一個人來確保品質，也就是說「不要只靠自己的兩隻眼睛，要再加上別人的兩隻眼睛，總共要用四隻眼睛來確保品質。」&lt;/p&gt;
&lt;p&gt;Four-eyes principle 雖然既古老又原始，但管用，因此就連&lt;a href=&#34;https://unido.org/overview/member-states/change-management/faq/what-four-eyes-principle&#34;&gt;聯合國&lt;/a&gt;及&lt;a href=&#34;https://cros-legacy.ec.europa.eu/content/four-eyes-principle_en&#34;&gt;歐盟&lt;/a&gt;這麼先進的國際性組織都仍在使用。&lt;/p&gt;
&lt;p&gt;再引述一次 Joshua Block 的話：「既然寫正確的程式那麼困難，我們就應該盡力取得幫助。」&lt;/p&gt;
&lt;p&gt;就算我們不想時時刻刻都像 XP 主張的 pair programming（甚至更激進的 mob programming），但至少在關鍵時刻，尤其是在 design review 及 code review 的時刻，就該好好善用這種原始方式取得幫助。&lt;/p&gt;
&lt;p&gt;每當有「現在可不可以暫時跳過 four eyes？」的衝動，或許該換個角度思考「現在有沒有方法讓 four eyes 更有效率且不犧牲品質？」&lt;/p&gt;
&lt;h3 id=&#34;working-backwards&#34;&gt;Working backwards&lt;/h3&gt;
&lt;p&gt;「逆向工作法」或「以終為始」是很有威力的心法。用在敏捷開發上，就是熟知的 user story &amp;ldquo;&lt;a href=&#34;https://agileforall.com/new-to-agile-invest-in-good-user-stories&#34;&gt;INVEST&lt;/a&gt;&amp;rdquo; 原則當中的 V (Valuable) 及 T (Testable)：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Valuable - 品質的起頭：這個 user story 是為了交付什麼價值？是為了誰？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Testable - 品質的末端：該怎麼確定這個 user story 已經做完了 (done)？該怎麼驗收？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;雖然前面曾提到「品質不是靠檢驗出來的」，但若能在一開頭就設想末端的檢驗標準，甚至設計出可讓將來更容易確實檢驗的結構，就是「內建品質」的精神——這就是敏捷實踐者常講的 &amp;ldquo;acceptance criteria&amp;rdquo; 及 &amp;ldquo;test-driven/behavior-driven design&amp;rdquo; 的用意。&lt;/p&gt;
&lt;p&gt;Code review 就是讓 four eyes 共同檢視 Valuable 及 Testable 的好時機，喔，不，甚至早在 Sprint Planning 或 Refinement 時就應該來 review 了——現在不是流行凡事都要 &amp;ldquo;shift left&amp;rdquo; 嗎？&lt;/p&gt;
&lt;h3 id=&#34;品質不是白吃的午餐&#34;&gt;品質不是白吃的午餐&lt;/h3&gt;
&lt;p&gt;品質是計畫、設計和內建而來的。&lt;/p&gt;
&lt;p&gt;計畫與設計出內建品質，是需要時間、精力、技能的。孕育出 collective ownership、four eyes、working backwards 的意識及紀律，也是需要時間、精力、技能的。&lt;/p&gt;
&lt;p&gt;畢竟品質不是白吃的午餐。&lt;/p&gt;
&lt;p&gt;在推銷這些進步理念時，讓團隊想像藉由「追求高品質」將會帶來的效益，或是以具體事證呈現因為「漠視低品質」而正在且將會持續深陷的痛苦泥淖，讓團隊做出選擇，願意投資時間、精力、技能在品質改進上。&lt;/p&gt;
&lt;p&gt;你能舉出「不好好進行 code review」最終會引發的災難嗎？這樣的災難是大家願意承擔的嗎？用這個來鞏固大家願意投資在品質上面的動機吧。&lt;/p&gt;
&lt;h2 id=&#34;-掌握基本功與領域知識&#34;&gt;② 掌握基本功與領域知識&lt;/h2&gt;
&lt;p&gt;不可諱言，code review 要做得好，不是大聲嚷嚷精神喊話就會自動美夢成真，是需要自我提升能力的，尤其是研發基本功與領域知識。&lt;/p&gt;
&lt;p&gt;不過，以下提到的這些能力，就算不談 code review，也是工程師本來就該自我提升的。&lt;/p&gt;
&lt;p&gt;所以，結論是：請把它們當成是必修課吧，這會讓你成為更稱職的軟體研發工程師。&lt;/p&gt;
&lt;h3 id=&#34;clean-code&#34;&gt;Clean code&lt;/h3&gt;
&lt;p&gt;Turing Award 得主 &lt;a href=&#34;https://en.wikipedia.org/wiki/Tony_Hoare&#34;&gt;C.A.R. Hoare&lt;/a&gt; 有一段經典名言：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are two ways of constructing a software design: One way is to make it so simple that there are &lt;em&gt;obviously&lt;/em&gt; no deficiencies, and the other way is to make it so complicated that there are no &lt;em&gt;obvious&lt;/em&gt; deficiencies. The first method is far more difficult.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;單純到「顯然沒有缺陷」 vs. 複雜到「沒有明顯的缺陷」，你願意選擇哪一種？&lt;/p&gt;
&lt;p&gt;寫出 clean code，可說是程式設計師的職業道德。坊間早有 clean code 及 refactoring 相關的經典書籍，網路上也有一大堆相關文章，請花點時間自我充實吧。&lt;/p&gt;
&lt;h3 id=&#34;guideline&#34;&gt;Guideline&lt;/h3&gt;
&lt;p&gt;除了 clean code 技能之外，我們還需要一些讓程式變得更好的 code review 指導方針。&lt;/p&gt;
&lt;p&gt;讓我們向 Google 取經吧 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。Google 在 &amp;ldquo;&lt;a href=&#34;https://google.github.io/eng-practices/review/reviewer/looking-for.html&#34;&gt;What to look for in a code review&lt;/a&gt;&amp;rdquo; 一文建議了一些 review 的重點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Design&lt;/li&gt;
&lt;li&gt;Functionality&lt;/li&gt;
&lt;li&gt;Complexity&lt;/li&gt;
&lt;li&gt;Tests&lt;/li&gt;
&lt;li&gt;Naming&lt;/li&gt;
&lt;li&gt;Comments&lt;/li&gt;
&lt;li&gt;Style&lt;/li&gt;
&lt;li&gt;Consistency&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Every line&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Good things&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/999d5b9d126a4da39db13eaa401d6ab3&#34;&gt;軟體測試實務：業界成功案例與高效實踐（第一冊）&lt;/a&gt;》第四章也建議了一些 code review 的重點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否有明顯的邏輯錯誤？&lt;/li&gt;
&lt;li&gt;有無遵循既有的程式碼編寫規範？&lt;/li&gt;
&lt;li&gt;邏輯的測試保護足夠嗎？&lt;/li&gt;
&lt;li&gt;有完整實現需求嗎？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果是在 DevOps 合一的團隊，甚至還會 review 一些 design for observability 的要點。以上都很值得放在團隊的 Definition of Done 或 PR/MR template。&lt;/p&gt;
&lt;p&gt;注意事項洋洋灑灑，每當有「現在可不可以暫時跳過？」的衝動時，或許該換個角度自問：「此刻若不好好 review 這些地方，我能承擔抄捷徑的後果嗎？」&lt;/p&gt;
&lt;h3 id=&#34;small-batch&#34;&gt;Small batch&lt;/h3&gt;
&lt;p&gt;敏捷陣營推崇小批量開發：小批量的東西容易估算，容易寫，容易理解，容易測試，容易部署，容易取得回饋，容易歸因。&lt;/p&gt;
&lt;p&gt;DevOps 陣營也推崇小批量。Google 在 &amp;ldquo;&lt;a href=&#34;https://cloud.google.com/architecture/devops/devops-process-working-in-small-batches&#34;&gt;DevOps process: Working in small batches&lt;/a&gt;&amp;rdquo; 一文說道：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Working in small batches is one of a set of capabilities that drive higher software delivery and organizational performance. These capabilities were discovered by the DORA State of DevOps research program, an independent, academically rigorous investigation into the practices and capabilities that drive high performance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果不是因為技術問題無法小批量提交 PR/MR，而是因為上游的 backlog item 就是如此大，或許團隊可以嘗試在 Sprint Planning 或 Refinement 時套用 &lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;SPIDR 法&lt;/a&gt;來拆解過大的 backlog item。&lt;/p&gt;
&lt;h3 id=&#34;domain-knowledge&#34;&gt;Domain knowledge&lt;/h3&gt;
&lt;p&gt;如果身處教育資源不那麼完備的團隊，想要養成領域知識，得自助加上人助：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;自助：盡量回到學生時期的好學心態，並盡量掌握有效率的學習方法。尤其是近年來流行的卡片盒筆記法，很值得一試。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;人助：尋求協助，並設法將學到的東西反饋到團隊的公共資產：文件、簡報、錄影、自動化測試，造福你的左右鄰兵，也造福後人。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;context&#34;&gt;Context&lt;/h3&gt;
&lt;p&gt;即使有了領域知識，但論及理解需求，又是另外一回事了。&lt;/p&gt;
&lt;p&gt;理解需求，除了老生常談的敏感度、傾聽與提問技巧之外，敏捷圈發展出來的 &lt;a href=&#34;https://gojko.net/books/specification-by-example/&#34;&gt;Specification by Example&lt;/a&gt; 技術，很值得大家嘗試。&lt;/p&gt;
&lt;p&gt;而且，既然都已經口頭問出來這些實例了，何妨順便用驗收測試予以固化？&lt;/p&gt;
&lt;h3 id=&#34;config&#34;&gt;Config&lt;/h3&gt;
&lt;p&gt;現代軟體不能只顧好核心業務邏輯，還得處理全球化、客製化、混合雲、多租戶等外圍需求，要能透過 feature flag 動態即時切換，甚至還要能讓用戶自助服務。&lt;/p&gt;
&lt;p&gt;組態管理比以往重要許多，複雜度不亞於程式碼管理，有時甚至超過。&lt;/p&gt;
&lt;p&gt;程式碼的管理，有 git flow、GitHub flow、GitLab flow 等流行的作法，那麼，組態管理呢？&lt;/p&gt;
&lt;p&gt;對於 legacy 系統，盤點既有組態，給予合適的現狀描述，至少是第一步。考古之餘，別忘了反饋到團隊的公共資產上。&lt;/p&gt;
&lt;h2 id=&#34;-凝聚團隊公約的共識&#34;&gt;③ 凝聚團隊公約的共識&lt;/h2&gt;
&lt;p&gt;Code review 是兩個人之間的活動，一個是 reviewer，另一個是 reviewee。喔，其實更常見的情況是，reviewer 要寫成複數 &amp;ldquo;reviewers&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;Code review 不只是兩個人之間的活動，更是團隊的活動。&lt;/p&gt;
&lt;p&gt;Marcus Buckingham 在〈&lt;a href=&#34;https://www.hbrtaiwan.com/special-topics/18933/power-of-hidden-team&#34;&gt;隱藏版團隊力量大 (Power of Hidden Teams)&lt;/a&gt;〉一文提到團隊的力量 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;大多數工作實際上都是團隊進行的工作。團隊是你工作經驗的現實。你的責任似乎連結到其他人的責任；你的長處似乎能與其他人的長處互補；你的左右都有人幫你留意，讓你保持自信，對你的工作給予回應，分享你對「好」的想法，在你看起來快要承受不住時伸出援手，並在你陷入困境時給予意見。這種團隊體驗的品質，正是你工作體驗的品質。&lt;/p&gt;
&lt;p&gt;你的團隊體驗會促進很多事情：你在工作時的生產力；你在工作時是否感到快樂；你有多少創意、創新和復原力；以及你選擇留在公司多久。換句話說，在你的工作上，優秀的團隊和團隊合作不是「有了也不錯」的事物，而是必須要擁有。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;現代軟體研發是一個群體的事業， &lt;del&gt;有人就有江湖&lt;/del&gt;  有人就有協作的議題。Code review 既然是團隊的活動，免不了也會有 &lt;del&gt;江湖的議題&lt;/del&gt; 協作的議題。&lt;/p&gt;
&lt;p&gt;若你的團隊已經啟動 Scrum，以下都是很值得在 retrospective 充分探討的好議題，讓團隊公約成為團隊協作的助力。&lt;/p&gt;
&lt;h3 id=&#34;過與不及的拿捏&#34;&gt;過與不及的拿捏&lt;/h3&gt;
&lt;p&gt;Code review 的尺度，該鬆還是該緊？&lt;/p&gt;
&lt;p&gt;「太鬆」當然並非我們樂見，但「太緊」呢？&lt;/p&gt;
&lt;p&gt;如果團隊對於鬆與緊的尺度難以達到共識，不妨聽聽看 Google 怎麼說。&lt;/p&gt;
&lt;p&gt;Google 在 &amp;ldquo;&lt;a href=&#34;https://google.github.io/eng-practices/review/reviewer/looking-for.html&#34;&gt;What to look for in a code review&lt;/a&gt;&amp;rdquo; 一文提出他們認為最起碼的品質標準是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Don&amp;rsquo;t accept CLs (change lists) that degrade the code health of the system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在業界，我們常暱稱它是「童子軍規則」(The Boy Scout Rule)：「離開營地前，讓營地比使用前更加乾淨。Always leave the campground cleaner than you found it.」&lt;/p&gt;
&lt;p&gt;至於尺度太緊的問題，Google 在 &amp;ldquo;&lt;a href=&#34;https://google.github.io/eng-practices/review/reviewer/standard.html&#34;&gt;The Standard of code review&lt;/a&gt;&amp;rdquo; 一文提出他們的看法：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In general, reviewers should favor approving a CL once it is in a state where it definitely improves the overall code health of the system being worked on, even if the CL isn&amp;rsquo;t perfect.  That is &lt;em&gt;the&lt;/em&gt; senior principle among all of the code review guidelines.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;儘管 Google 是菁英薈萃之地，但關於這一點倒是滿務實的，不會追求完美主義。&lt;/p&gt;
&lt;h3 id=&#34;cadence&#34;&gt;Cadence&lt;/h3&gt;
&lt;p&gt;很多人怕 code review 會打斷別人的工作節奏，也怕自己的節奏被打斷。因此我常常看到看板上面擠壓許多有待 review 的 PR/MR，我輔導過的團隊，也幾乎都會在 retrospective 提出這項熱門議題。&lt;/p&gt;
&lt;p&gt;聽聽看 Google 怎麼說。&amp;quot;&lt;a href=&#34;https://google.github.io/eng-practices/review/reviewer/speed.html&#34;&gt;Speed of Code Reviews&lt;/a&gt;&amp;quot; 一文主張：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you are not in the middle of a focused task, you should do a code review shortly after it comes in.  One business day is the maximum time it should take to respond to a code review request.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可見 Google 很務實地將焦點放在 flow 上面：若無特殊理由，要以團隊目標為重。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/999d5b9d126a4da39db13eaa401d6ab3&#34;&gt;軟體測試實務：業界成功案例與高效實踐（第一冊）&lt;/a&gt;》第四章則提出團隊一起 code review 的常見做法，以避免個別人士零零星星被打斷：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;除了找另一個團隊成員協助 code review 外，在多數團隊成員不熟悉相關程式碼時，我們也會有 mob code review，去加強知識擴散的效果。&lt;/p&gt;
&lt;p&gt;鑑於此種需要專心投入的特質，有些團隊會直接定時進行 mob code review（例如：每日 daily meeting 之後或是下班之前），以避免當前工作被打斷。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;大家可以參考這些業界常見的做法，改善自己團隊的 code review 節奏。&lt;/p&gt;
&lt;h3 id=&#34;process&#34;&gt;Process&lt;/h3&gt;
&lt;p&gt;敏捷路線不太鼓勵過多 top-down 的流程約束，更希望團隊基於經驗主義自行湧現出合適的流程。我鼓勵團隊挑選感興趣的部份實踐看看，並在 retrospective 充分反思。&lt;/p&gt;
&lt;p&gt;如果你是走 Scrum 路線，請善用 Definition of Done 作為品質共識。像《&lt;a href=&#34;https://williampjyeh.notion.site/999d5b9d126a4da39db13eaa401d6ab3&#34;&gt;軟體測試實務：業界成功案例與高效實踐（第一冊）&lt;/a&gt;》第四章就提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;有些團隊甚至在他們的實體或 Jira 的 Scrum board 上，將 code review 強制設為必需通過的一個階段，未 code review 過的任務就不算完成。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;列入 Definition of Done 還有一個好處：code review 就不再是隱藏成本，而是正大光明的 task，需要被規劃，需要被估點，也需要認真投入。&lt;/p&gt;
&lt;p&gt;如果你是走 Kanban 路線，可考慮新增一個名叫 &amp;ldquo;code review&amp;rdquo; 的 column，並設下 WIP 及 policy。接下來，你會驚訝地發現 code review 的 flow 是多麼順暢⋯⋯或是不順暢。請善用 Kanban 視覺化的威力。&lt;/p&gt;
&lt;h2 id=&#34;-嘗試更好的協同理解技巧&#34;&gt;④ 嘗試更好的協同理解技巧&lt;/h2&gt;
&lt;p&gt;在理想世界中，我們程式要實作的任務很單純，所需的背景知識大家都有，程式碼寫得清晰易懂，PR/MR 也充分交代 reviewer 需注意的事項。這種情況下，reviewer 或許只需要動動眼、動動滑鼠、動動腦，就能善盡 code review 責任。&lt;/p&gt;
&lt;p&gt;理想世界不常發生，是吧？&lt;/p&gt;
&lt;p&gt;真實世界中，要實作的任務不那麼單純，所需的背景知識不見得大家都有，程式碼埋藏一些神祕邏輯，如果我們繼續仰賴低頻寬的程式碼溝通方式，會讓 reviewer 只能根據眼前所見的浮面資訊進行浮面的 review，最終只能算是表面工夫的 review，輸出低品質的程式。&lt;/p&gt;
&lt;p&gt;因此，整個團隊都需要學習更好的協同理解技巧：放大溝通頻寬，尋求深度資訊。&lt;/p&gt;
&lt;h3 id=&#34;放大溝通頻寬&#34;&gt;放大溝通頻寬&lt;/h3&gt;
&lt;p&gt;一對一的溝通頻寬太低了，有必要的話，集體一起 code review 吧。&lt;/p&gt;
&lt;p&gt;程式碼的溝通頻寬太低了，大家可以善用嘴巴，善用白板、螢幕（如果你們坐在附近）、投影機（如果需要多人一起看）、遠距會議軟體（如果是異地辦公的團隊）。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/999d5b9d126a4da39db13eaa401d6ab3&#34;&gt;軟體測試實務：業界成功案例與高效實踐（第一冊）&lt;/a&gt;》第四章就介紹過這種大絕招：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;除了找另一個團隊成員協助 code review 外，在多數團隊成員不熟悉相關程式碼時，我們也會有 mob code review，去加強知識擴散的效果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果連這種大絕招都無效，或許團隊成員彼此落差實在太大，需要長期治療。&lt;/p&gt;
&lt;h3 id=&#34;尋求深度資訊&#34;&gt;尋求深度資訊&lt;/h3&gt;
&lt;p&gt;避免 reviewer 只能根據浮面資訊進行浮面的 review，團隊需要提供更多深度資訊以協助 reviewer。&lt;/p&gt;
&lt;p&gt;我從 &amp;ldquo;&lt;a href=&#34;https://axolo.co/blog/part-3-github-pull-request-template&#34;&gt;GitHub pull request template&lt;/a&gt;&amp;rdquo; 摘錄一些有助於 code review 的資訊，可做為大家的出發點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ticket number and link&lt;/li&gt;
&lt;li&gt;How has this been tested?
&lt;ul&gt;
&lt;li&gt;Please describe the tests that you ran to verify your design. Provide instructions so we can &lt;em&gt;reproduce&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Please also list any relevant details for your test configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Checklist:
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; I have &lt;em&gt;commented&lt;/em&gt; my code, particularly in hard-to-understand areas&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; I have made corresponding changes to the &lt;em&gt;documentation&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; I have added tests that &lt;em&gt;prove&lt;/em&gt; my fix is effective or that my feature works&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; New and existing &lt;em&gt;unit tests&lt;/em&gt; pass locally with my changes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Screenshots (if appropriate)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我還曾經身處於有這種內規的團隊：「沒看到 unit test 的報表，就不予以 code review。」很硬！但那卻是我非常享受程式設計的一段經歷。&lt;/p&gt;
&lt;h2 id=&#34;-讓進步看得見&#34;&gt;⑤ 讓進步看得見&lt;/h2&gt;
&lt;p&gt;Code review 的目的，是善用集體智慧提升設計品質，促成知識共享，讓我們工作更有成就感，更有信心能夠交付價值，也更少因不慎流出去的瑕疵而疲於奔命。&lt;/p&gt;
&lt;p&gt;直接的效益是：提升品質，降低風險，間接的效益是：提升團隊的長期生產力，進而縮短上市時間，提升客戶滿意度。&lt;/p&gt;
&lt;p&gt;這些效益都是偏向企業內部流程的構面，甚至是學習與成長的構面，偏向落後指標，且都不容易直接衡量。若以系統思考角度來說，這些效益有很明顯的滯延現象，短期內甚至還可能不利，急功近利的人，很容易因此落入「捨本逐末」(shifting the burden) 及「目標侵蝕」(eroding goals) 的陷阱。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/09/code-review-cld.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/09/code-review-cld.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;認清根本解具有滯延現象，且選擇正面對決之後，才能接下去探討如何衡量成效。&lt;/p&gt;
&lt;p&gt;這篇從 code review 出發的文章，一路看到這裡，大家應該很清楚，對於提升品質、降低風險、提升團隊生產力⋯⋯這些我們想要的成效，code review 只是手法之一，單獨只有這一個手法是無益的，勢必得搭配衍生的配套措施。因此，code review 的成效也不宜單獨看待，需連同其他配套措施一起衡量才比較實際。&lt;/p&gt;
&lt;p&gt;不同的團隊，成熟度各異，管理者需要正視不同的現況，擬定不同的改進措施、衡量方式及目標狀態，並且要分階段。&lt;/p&gt;
&lt;p&gt;譬如說，以領先指標來看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;推動 collective ownership 的同時，可嘗試衡量 Scrum 五大活動參與度、PR 參與度、Sprint Backlog Items 分工多元性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;推動 working backwards 的同時，可嘗試衡量 Sprint Backlog Items 的 acceptance test 完備度、design for observability 完備度、test 涵蓋率。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;推動 clean code 的同時，可嘗試衡量原始碼品質指標，並搭載於 CI 系統。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以落後指標來看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;關注 flow cadence 的同時，可嘗試衡量看板的 cumulative flow diagram。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;關注最終交付品質的同時，可嘗試衡量 change failure rate——這正好是 DORA (DevOps Research and Assessment) 四大指標其中之一。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最後，即使我們已經盡其所能把關品質，但很不幸 defect 仍然流了出去造成影響，亡羊補牢之餘，我們也需要關注 regression test 是否落實：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;針對已流出去造成影響的 defect，可嘗試衡量 regression test 涵蓋率。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;-支持長久研發的措施&#34;&gt;⑥ 支持長久研發的措施&lt;/h2&gt;
&lt;p&gt;個人具備正確的品質基本信念，掌握了基本功與領域知識，團隊擁有公約共識，也掌握了更好的協同理解技巧，接下來就是這個大哉問了：周圍的環境，是否可以促成 code review 及相關的關鍵行為？&lt;/p&gt;
&lt;h3 id=&#34;事&#34;&gt;事&lt;/h3&gt;
&lt;p&gt;品質不是白吃的午餐，計畫與設計出內建品質，是需要時間、精力、技能的。&lt;/p&gt;
&lt;p&gt;如果整個團隊已經開始嘗試用更好的方法進行 code review 及相關活動，但仍然受阻於事情太多、時間太少，或許這就要回到 Product Backlog Items 的基本問題了。請團隊試著問問自己幾個問題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;即使可能有複數個上游來源，但團隊是否最後只會有一份透明化的 Product Backlog？&lt;/li&gt;
&lt;li&gt;團隊是認真看待 Product Backlog 的嗎？&lt;/li&gt;
&lt;li&gt;PO 是根據什麼原則管理 Product Backlog 的？&lt;/li&gt;
&lt;li&gt;團隊 Sprint Planning 及 Refinement 是如何進行的？&lt;/li&gt;
&lt;li&gt;品質、flow 相關議題在 Retrospective 裡面是如何被討論的？&lt;/li&gt;
&lt;li&gt;Retrospective 是玩真的嗎？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;思考過一輪，應該可以更好的區隔出：究竟是外面的問題，還是自己的問題。針對前者，再去尋求協助。&lt;/p&gt;
&lt;h3 id=&#34;物&#34;&gt;物&lt;/h3&gt;
&lt;p&gt;想讓 PR/MR template 所要求的種種事項具體發揮效用，需要自動化環境的支持，尤其是與 CI/CD 高度連動的環境。&lt;/p&gt;
&lt;p&gt;這是得持續投入的基礎建設，沒有捷徑。&lt;/p&gt;
&lt;h3 id=&#34;人&#34;&gt;人&lt;/h3&gt;
&lt;p&gt;Code review 及相關的配套措施，需要有一定的技術能力。&lt;/p&gt;
&lt;p&gt;大規模敏捷框架 LeSS 在探討 &amp;ldquo;&lt;a href=&#34;https://less.works/less/technical-excellence&#34;&gt;technical excellence&lt;/a&gt;&amp;rdquo; 時，有一段語重心長的話：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There is no magic to them, most people are able to learn them. However, most people are &lt;em&gt;not&lt;/em&gt; aware of these after they graduated from university and hence, your organization &lt;strong&gt;will&lt;/strong&gt; need to invest in these, usually via coaching.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;簡單的說，自立自強固然可行，但若有好的前輩或教練親自帶領，將會事半功倍。&lt;/p&gt;
&lt;p&gt;這就是團隊裡資深同仁的責任了。我期許你們能在③④提到的種種團隊協作活動中，以身作則，起示範作用。把整個團隊的水平提升到某個地步，有團隊整體戰力當你的後盾，也才能夠發揮更大的價值。&lt;/p&gt;
&lt;h2 id=&#34;結語&#34;&gt;結語&lt;/h2&gt;
&lt;p&gt;品質改善具有滯延現象，需要正確思路與堅定決心，才能避免捨本逐末與目標侵蝕的陷阱。&lt;/p&gt;
&lt;p&gt;本文探討從 code review 出發並衍生出來的六大議題，也建議一些可供個人、團隊、組織開始嘗試推動的事項。&lt;/p&gt;
&lt;p&gt;提升品質，不必然意味著降低研發效率。讓我們持續學習與探索如何聰明地做事。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;關於「公車指數」(bus factor)，可參考以下兩篇文章：〈&lt;a href=&#34;https://blog.yveslin.com/2015/11/24/measure-sustainability-bus-factor/&#34;&gt;少一個差很多：算算團隊的公車指數&lt;/a&gt;〉、〈&lt;a href=&#34;https://agile.ithome.com.tw/2022/news-page/271&#34;&gt;你的團隊「合作無間」嗎？嘗試用「公車指數」衡量現況吧！&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;建議大家讀讀 Google 公開的 &lt;a href=&#34;https://github.com/google/eng-practices&#34;&gt;&lt;em&gt;Google Engineering Practices Documentation&lt;/em&gt;&lt;/a&gt;，最近也有保哥的&lt;a href=&#34;https://eng-practices.gh.miniasp.com&#34;&gt;中譯版&lt;/a&gt; 。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;如果你無法閱讀全文，也可收聽這一集 podcast：〈&lt;a href=&#34;https://podcasts.google.com/feed/aHR0cHM6Ly9mZWVkcy5zb3VuZG9uLmZtL3BvZGNhc3RzLzQxNDAzM2IzLTkwNmQtNGI4YS04MDM0LWNiOTM1NzBiNjc5NS54bWw/episode/YjgyOTQ1YjYtYTdiOS00N2I3LTg5OTMtZmE5NTU4NzVlMDM5?ep=14&#34;&gt;員工投入程度來自&amp;hellip; 這個隱藏因素，你發現了嗎？&lt;/a&gt;〉&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;關於 DORA 四大指標，可參考 &amp;ldquo;&lt;a href=&#34;https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance&#34;&gt;Are you an Elite DevOps performer? Find out with the Four Key Project&lt;/a&gt;&amp;rdquo; 一文，更詳細的說明，請參考《&lt;a href=&#34;https://findbook.com.tw/9789863126959&#34;&gt;Accelerate：精益軟體與 DevOps 背後的科學&lt;/a&gt;》一書。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>很簡單的 Story，也要拆分出 Tasks 嗎？</title>
      <link>//william-yeh.net/post/2023/08/story-to-tasks/</link>
      <pubDate>Sat, 26 Aug 2023 18:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/08/story-to-tasks/</guid>
      
        <description>&lt;p&gt;Scrum 已經夠精簡了，但很多人還是因為嫌麻煩、省時間，就省略原本預定該做的事情。&lt;/p&gt;
&lt;p&gt;雖然在 2020 之前的 &lt;a href=&#34;https://scrumguides.org&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 並沒有規定 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Planning&lt;/span&gt;
 要分為 Part 1 &amp;amp; Part 2 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，但這可說是 Scrum 圈公認的最佳實踐。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;如果團隊已經成熟到能以自己的方式把 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Planning&lt;/span&gt;
 做好做滿，其實也未必非得硬性劃分 Part 1 &amp;amp; Part 2（畢竟 Scrum 推崇基於經驗主義的自組織、自管理）。最怕的是，不明白劃分 Part 1 &amp;amp; Part 2 的好處，不明白 Part 2 的重點及產出，甚至單純只因「嫌麻煩」、「省時間」，就省略原本預定該在 Part 2 進行的活動，往往會導致 sprint 進行途中出現種種問題。&lt;/p&gt;
&lt;p&gt;很多問題，追根究柢，就是當初沒有認真進行 Part 2。&lt;/p&gt;
&lt;p&gt;在 Part 2 中，有一個重要的步驟是將 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Backlog Items&lt;/span&gt;
 拆分出較小、較具體的 tasks &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;  ——常被團隊輕看的步驟。我姑且不搬出專案管理的大道理 &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; ，純粹以 Scrum 日常經驗來反思「很簡單的 story，也要拆分出 tasks 嗎？」這個提問。&lt;/p&gt;
&lt;h2 id=&#34;對自己避免低估&#34;&gt;對自己：避免低估&lt;/h2&gt;
&lt;p&gt;工程師常會低估 story 所需耗費的時間資源。可能是刻意低估（迎合上意、打腫臉充胖子⋯⋯），也可能是不自覺的低估。前者當然不可取，後者雖然是無心之舉，但仍會造成 sprint fail 的風險，若無法道德勸說大家警覺，就得訴諸制度流程來避免。&lt;/p&gt;
&lt;p&gt;將 story 拆分出較小、較具體的 tasks，其實就是&lt;strong&gt;切換至一個較為深入的視角來審視 story 的執行計畫&lt;/strong&gt;。拆分出來的 tasks，不僅可當成 checklist 避免自己掛一漏萬，更可忠實反映 story 的複雜度——我常常看到團隊在真正嘗試將 story 拆分出好多張 tasks 便利貼之後，才回頭修改當初對於 story 的估點，而且往往是增加點數。&lt;/p&gt;
&lt;p&gt;我很喜歡 Mike Cohn 大師在 &lt;a href=&#34;https://www.amazon.com/dp/0321205685&#34;&gt;&lt;em&gt;User Stories Applied&lt;/em&gt;&lt;/a&gt; 所舉的 &amp;ldquo;Everything takes four hours&amp;rdquo; 例子：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In one episode the husband is being pestered by his wife to go shopping for a couch. She insists the trip will take only an hour. He tells her that “Everything in the world takes four hours. You gotta go there, you gotta do whatever, eat, talk about where you should have eaten, and then come home. That&amp;rsquo;s four hours minimum.”&lt;/p&gt;
&lt;p&gt;This isn’t a bad rule of thumb for software development and is
a perfect example of how projects get in trouble when they
don’t distinguish between ideal time and elapsed time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你堅持「這個 story 很簡單，根本不必浪費時間拆分出 tasks」，那麼，請想想 &amp;ldquo;Everything takes four hours&amp;rdquo; 這句話。&lt;/p&gt;
&lt;h2 id=&#34;對團隊製造流動感&#34;&gt;對團隊：製造流動感&lt;/h2&gt;
&lt;p&gt;讓 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Daily Scrum&lt;/span&gt;
 無趣的方法有很多，常見的病徵是：某一張卡片，日復一日就是一直停留在某一欄 (column)，沒有前進。&lt;/p&gt;
&lt;p&gt;某Ａ問：「這張卡片，停留在這一欄好像已經好幾天了⋯⋯請問它怎麼了？」&lt;/p&gt;
&lt;p&gt;答：「啊，就是還在進行中，還沒做完呀。」&lt;/p&gt;
&lt;p&gt;某Ｂ問：「好幾天都一直停留在這裡，我怎麼知道它到底有沒有任何進展呀？」&lt;/p&gt;
&lt;p&gt;答：「啊，就是還在進行中呀⋯⋯你懷疑我喔？」&lt;/p&gt;
&lt;p&gt;團隊需要製造任務的流動感，以區隔「沒有流動的幻覺」與「真實的 blocker」兩種情況。&lt;/p&gt;
&lt;p&gt;Scrum 的團隊未必會採用 Kanban 陣營的做法，但 Kanban 的 flow 觀念及視覺化手法很值得 Scrum 團隊借鏡。將 story 拆分出較小、較具體的 tasks，其實就是&lt;strong&gt;切換至一個較具流動感的視角來審視 story 的執行狀況&lt;/strong&gt;。當你憑著每一天每一天 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Daily Scrum&lt;/span&gt;
 的視覺印象，懷疑某張 story 似乎停滯不前，或是憑著 burndown chart &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; 的量化資料，懷疑整個 sprint 似乎偏離理想斜線，那麼，在進入「blocker 問題解決模式」之前，請先試著檢查看看當初 tasks 拆分是否確實。&lt;/p&gt;
&lt;p&gt;怎樣才能夠拆分出具有「流動感」的 tasks 呢？請參考我在〈&lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座‧閱讀材料&lt;/a&gt;〉文末的建議：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;努力將 task 切到不超過 2 個工作天的程度。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;當-tasks-已經變成無趣的例行公事時&#34;&gt;當 Tasks 已經變成無趣的例行公事時&lt;/h2&gt;
&lt;p&gt;Ｃ問：「萬一我們每次將 story 拆分出來的 tasks 都長得一模一樣，還有必要浪費這些時間嗎？」&lt;/p&gt;
&lt;p&gt;我：「請舉例。」&lt;/p&gt;
&lt;p&gt;Ｃ：「就拿這一張 Story F 來說吧，我們會拆出這幾張 tasks：(1) Design Logic，(2) Design Schema，(3) Coding，(4) PR，(5) Deploy。」&lt;/p&gt;
&lt;p&gt;Ｃ：「對其他那幾張 Story G、H、I 來說，其實也都是一樣的手順。每次都要同樣的複製貼上複製貼上，滿浪費青春的⋯⋯」&lt;/p&gt;
&lt;p&gt;如果團隊面對的產品，真的如同這位Ｃ所說，在 tasks 層次的手順幾乎已經了無新意，那麼，在不犧牲前面講的「對自己：避免低估」及「對團隊：製造流動感」兩大好處的前提下，我會建議團隊：或許可試著將樸素的 Scrum task board 轉換成較精緻的 Kanban board，把例行手順變成 Kanban column。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;「很簡單的 Story，也要拆分出 Tasks 嗎？」&lt;/p&gt;
&lt;p&gt;你認為呢？&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【敏捷的工作分解方法】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2016/10/one-week-sprint/&#34;&gt;One-Week Sprint 的節奏&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/10/agile-milestone/&#34;&gt;事情做一半，等於沒完成：淺談敏捷的里程碑設定&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;以「蜘蛛法」拆分過於龐大的 User Story&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ 很簡單的 Story，也要拆分出 Tasks 嗎？&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/11/why-decomposition-matters/&#34;&gt;變動的時代，為什麼工作分解技能更是必備？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;以前的 &lt;a href=&#34;https://scrumguides.org&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 對於 Sprint Planning 執行細節著墨不多。但 2020 版的新內容，開始強調「將 SBI 拆分出 work items」這環節，圈點出 3 個核心主題：Why、What、How，只是並沒有道出 Part 1～3 之類的「步驟」、「流程」字眼。儘管如此，Scrum 陣營還是愛用習之有年的 Part 1 &amp;amp; Part 2 字眼來劃分 Sprint Planning 的階段，本篇文章亦遵照此一慣例。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;對於 Sprint Planning 是否要分成兩部曲，請參考 Teddy 的文章〈&lt;a href=&#34;https://teddy-chen-tw.blogspot.com/2014/11/sprint-planning-meeting.html&#34;&gt;談談 Sprint Planning Meeting&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;像 &lt;a href=&#34;https://less.works/less/framework/sprint-planning-one&#34;&gt;LeSS&lt;/a&gt; 就說：&amp;quot;&lt;em&gt;Sprint Planning Two focuses on creating a &lt;strong&gt;plan of work&lt;/strong&gt; to get to &amp;lsquo;done&amp;rsquo; for each item. The items and &lt;strong&gt;plan of action or tasks&lt;/strong&gt; comprise the Sprint Backlog.&lt;/em&gt;&amp;quot;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;如果想從更宏觀的角度看待「工作分解」，請參考〈&lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座‧閱讀材料&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Scrum 陣營常見的 burndown chart 有兩種，請參考〈  &lt;a href=&#34;https://medium.com/%E6%96%87%E6%80%9D%E4%B8%8D%E8%97%8F%E7%A7%81/%E6%96%87%E6%80%9D%E4%B8%8D%E8%97%8F%E7%A7%81-%E7%87%83%E7%9B%A1%E5%9C%96%E7%B0%A1%E5%96%AE%E8%AA%AA-29628f3570be&#34;&gt;燃盡圖 (Burndown) 簡單說&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>敏捷的工作分解方法</title>
      <link>//william-yeh.net/series/agile-decomposition/</link>
      <pubDate>Sat, 26 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>//william-yeh.net/series/agile-decomposition/</guid>
      
        <description>&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2016/10/one-week-sprint/&#34;&gt;One-Week Sprint 的節奏&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2022/10/agile-milestone/&#34;&gt;事情做一半，等於沒完成：淺談敏捷的里程碑設定&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;以「蜘蛛法」拆分過於龐大的 User Story&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2023/08/story-to-tasks/&#34;&gt;很簡單的 Story，也要拆分出 Tasks 嗎？&lt;/a&gt;&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>透過自己的雙手，掌握那不變的容器技術核心——《Docker 實戰 6 堂課》推薦序</title>
      <link>//william-yeh.net/post/2023/08/docker-labs-review/</link>
      <pubDate>Sat, 19 Aug 2023 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/08/docker-labs-review/</guid>
      
        <description>&lt;p&gt;我在 2015 年～2017 年間，開了 8 次【&lt;a href=&#34;https://william-yeh.github.io/docker-workshop/&#34;&gt;Docker 建置實戰講堂&lt;/a&gt;】一日課程。在那個大眾對於 Docker 還矇矇懂懂的年代，我就堅持不用貌似較簡便的 Docker Desktop，而是大膽採用 Vagrant + VirtualBox 作為統一的授課環境，讓學員儘早習慣在 Linux 平台上探索 Docker 的底層與應用。&lt;/p&gt;
&lt;p&gt;所以，當我在 2022 年 iThome 鐵人賽看到小賴的參賽作品【&lt;a href=&#34;https://ithelp.ithome.com.tw/users/20151857/ironman/5419&#34;&gt;那些關於 docker 你知道與不知道的事&lt;/a&gt;】中，是以 AWS EC2 的 Ubuntu instance 作為實作環境，現在更出版新書《&lt;a href=&#34;https://www.tenlong.com.tw/products/9786263335769&#34;&gt;Docker 實戰 6 堂課：56 個實驗動手做，掌握 Linux 容器核心技術&lt;/a&gt;》，就非常高興。畢竟，從最擬真的角度切入，才能夠透過自己的雙手，掌握那不變的容器技術核心。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/08/docker-labs-book.jpg&#34; alt=&#34;《Docker 實戰 6 堂課：56 個實驗動手做，掌握 Linux 容器核心技術》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/08/docker-labs-book.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《Docker 實戰 6 堂課：56 個實驗動手做，掌握 Linux 容器核心技術》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;很多人會問：現在都已經是 Kubernetes 當道的年代，我們還需要學習落伍的 Docker 嗎？還需要用這麼刻苦的方法學習落伍的 Docker 嗎？&lt;/p&gt;
&lt;p&gt;既然 Kubernetes 正當紅，我們就從功利一點的角度來看這議題吧。Kubernetes 的三大認證考試 (&lt;a href=&#34;https://training.linuxfoundation.org/certification/certified-kubernetes-administrator-cka/&#34;&gt;CKA&lt;/a&gt;, &lt;a href=&#34;https://training.linuxfoundation.org/certification/certified-kubernetes-application-developer-ckad/&#34;&gt;CKAD&lt;/a&gt;, &lt;a href=&#34;https://training.linuxfoundation.org/certification/certified-kubernetes-security-specialist/&#34;&gt;CKS&lt;/a&gt;) 中，不乏一堆上機實境題；如果你不懂得容器的底層技術：process、layer、namespace、network，將很難在現場上機時迅速精準排除問題——而且是用最傳統的終端機命令列方式進行。&lt;/p&gt;
&lt;p&gt;既然這麼當紅的 Kubernetes 都要求你必須熟練這麼刻苦的方式，那麼，你為什麼不先從較單純的 Docker 容器環境下手呢？&lt;/p&gt;
&lt;p&gt;小賴這本書有三大特點：底層知識，動手實驗，熱血工程魂。&lt;/p&gt;
&lt;h2 id=&#34;特色一-底層知識&#34;&gt;特色一 ：底層知識&lt;/h2&gt;
&lt;p&gt;容器世界有許多神奇的特效，尤其是不同對象、不同層次的「資源隔離性」。透過本書，你可以親自看到 process、layer、namespace、network 這些磚頭是如何一步步撐起容器的華廈。&lt;/p&gt;
&lt;p&gt;掌握這些「資源隔離性」的基礎知識，將來再看到 Kubernetes 的種種設計，必有會心一笑的熟悉感。&lt;/p&gt;
&lt;h2 id=&#34;特色二動手實驗&#34;&gt;特色二：動手實驗&lt;/h2&gt;
&lt;p&gt;底層知識很枯燥，甚至抽象。透過動手實作，能具體看到這些要素活生生運作起來，而不是一堆死板板要你生吞硬背的理論。&lt;/p&gt;
&lt;p&gt;作者以 AWS EC2 的 Linux instance 作為實驗環境，比起多數人採用 Windows 或 Mac 的 Docker Desktop 作為實驗環境，更能忠實反映容器的
行為及底層狀況。更重要的是，及早領略在這種環境之下的操作及除錯經驗，未來在真實生產環境之下的操作、性能調教、除錯任務，自然駕輕就熟。&lt;/p&gt;
&lt;p&gt;正如小賴所說：「親自動手做實驗與觀察，應該是工程師最基本的素養。」&lt;/p&gt;
&lt;h2 id=&#34;特色三熱血工程魂&#34;&gt;特色三：熱血工程魂&lt;/h2&gt;
&lt;p&gt;由 Docker 起頭，至 Kubernetes 發揚光大，容器生態圈的技術，雖然貌似複雜，但藉由生態圈的卓越工藝，已經將複雜技術下放到凡間，只要你有心，都可以在本機端或雲端建置出堪用的實驗環境供你探索。&lt;/p&gt;
&lt;p&gt;剩下的問題就是：你是否保有熱血工程魂？&lt;/p&gt;
&lt;p&gt;我很喜歡小賴講的這段話：「那種『知道更多了』的感覺，根本就是工程師的鴉片，讓人難以抵抗。」&lt;/p&gt;
&lt;p&gt;容器生態圈蓬勃發展，我們更需要小賴這本書，帶我們透過自己的雙手，掌握那不變的容器技術核心。希望大家藉由這本書，拾起熱血工程魂，重視底層知識，樂於動手實驗，在容器世界游刃有餘。&lt;/p&gt;
&lt;p&gt; 　 　 　 　 　 　—— 敏捷魔藥師　葉秉哲 (William Yeh)　2023-08-19&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>書籍／課程推薦</title>
      <link>//william-yeh.net/series/book-review/</link>
      <pubDate>Sat, 19 Aug 2023 00:00:00 +0000</pubDate>
      
      <guid>//william-yeh.net/series/book-review/</guid>
      
        <description>&lt;h2 id=&#34;敏捷&#34;&gt;敏捷&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2021/03/agile-inspired-by-yves/&#34;&gt;被 Yves 啟發的敏捷轉型之旅&lt;/a&gt;   ——  《敏捷管理生存指南：不是快，而是適者生存》推薦文&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2022/04/yves-agile-course/&#34;&gt;經理人視角的敏捷通識課&lt;/a&gt;   ——  【高效產出：突破資源限制的敏捷管理術】推薦文&lt;/p&gt;
&lt;h2 id=&#34;管理&#34;&gt;管理&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2021/02/the-managers-path-review/&#34;&gt;軟體研發者的隨身職涯教練&lt;/a&gt;   ——  《經理人之道》推薦序&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/10/unicorn-project-review/&#34;&gt;值得你看門道的好書&lt;/a&gt;   ——  《獨角獸專案》推薦序&lt;/p&gt;
&lt;h2 id=&#34;技術&#34;&gt;技術&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2023/08/docker-labs-review/&#34;&gt;透過自己的雙手，掌握那不變的容器技術核心&lt;/a&gt;   ——  《Docker 實戰 6 堂課》推薦序&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/09/learning-gitlab-review/&#34;&gt;讓 GitLab 成為數位轉型的重要推手&lt;/a&gt;   ——  《和艦長一起 30 天玩轉 GitLab》推薦序&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2024/08/sre-story-review/&#34;&gt;換個 Design for Ops 的腦袋&lt;/a&gt;   ——   《SRE 工作現場直擊》推薦序&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>Coursera 上面的 GCP 課程</title>
      <link>//william-yeh.net/post/2023/04/gcp-on-coursera/</link>
      <pubDate>Tue, 25 Apr 2023 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/04/gcp-on-coursera/</guid>
      
        <description>&lt;p&gt;為了在公司內推動 GCP 認證考試，必須先推動大家勤修 GCP 課程；為了推動大家勤修 GCP 課程，我得先帶頭示範。因此，我最近在 Coursera 修了許多 GCP 認證考試相關課程 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，感觸很深：就算不考照，用這些課程補完一些知識，還是很值得的。&lt;/p&gt;
&lt;p&gt;這些課程深度與廣度兼具，又有搭配實作演習，有系統地吸收，會比雜亂搜尋文件的碎片化學習來得踏實。&lt;/p&gt;
&lt;p&gt;即使以俗氣的 C/P 值角度來說，這些課程也是物超所值的。像以下這門放在 Coursera 的課：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.coursera.org/learn/gcp-big-data-ml-fundamentals&#34;&gt;Google Cloud Big Data and Machine Learning Fundamentals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大家知道嗎？這樣的課，用同樣的 Google 原廠教材，改用國語發音 live 授課，在外頭可是喊價超過一萬元新台幣的。&lt;/p&gt;
&lt;p&gt;我根據自己這些日子勤修課程的小經驗，推薦幾門有廣度有深度的課，讓想要對雲端環境有更廣更深認識的人參考。我大致將這些課程分類如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;非技術的通識類&lt;/li&gt;
&lt;li&gt;GCP 技術：共通核心&lt;/li&gt;
&lt;li&gt;GCP 技術：K8s&lt;/li&gt;
&lt;li&gt;Dev&lt;/li&gt;
&lt;li&gt;DevOps &amp;amp; SRE&lt;/li&gt;
&lt;li&gt;ML &amp;amp; Big Data&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;非技術的通識類&#34;&gt;非技術的通識類&lt;/h2&gt;
&lt;p&gt;這類課程比較軟性，適合讓非技術底子出身的人也有機會體會雲端帶來的可能性。非技術人擁有雲端的基礎認知，與技術人的對話也才能更同調。&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/professional-certificates/google-cloud-digital-leader-training&#34;&gt;&lt;strong&gt;Google Cloud Digital Leader Training Professional Certificate&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Digital Transformation with Google Cloud&lt;/li&gt;
&lt;li&gt;Innovating with Data and Google Cloud&lt;/li&gt;
&lt;li&gt;Infrastructure and Application Modernization with Google Cloud&lt;/li&gt;
&lt;li&gt;Understanding Google Cloud Security and Operations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/professional-certificates/google-cloud-digital-leader-training&#34;&gt;&lt;strong&gt;Digital Transformation Using AI/ML with Google Cloud&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&#34;https://coursera.org/share/20a040029a6495882fec864d0cb59d0b&#34;&gt;秀肌肉&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Business Transformation with Google Cloud&lt;/li&gt;
&lt;li&gt;Infrastructure and Application Modernization with Google Cloud&lt;/li&gt;
&lt;li&gt;Managing Machine Learning Projects with Google Cloud&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其中，像 &lt;a href=&#34;https://www.coursera.org/learn/machine-learning-business-professionals&#34;&gt;Managing Machine Learning Projects with Google Cloud&lt;/a&gt; 這門課提到最適合 ML 發揮的領域，是 &amp;ldquo;Challenging &amp;amp; Clear&amp;rdquo; 的問題：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/04/ml-challenging-clear.png&#34; alt=&#34;最適合 ML 發揮的領域&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/04/ml-challenging-clear.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;最適合 ML 發揮的領域&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這是不是與最近因為 ChatGPT 而颳起的 prompt engineering 風潮，有異曲同工之妙呢？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/specializations/organizational-change-and-culture-for-adopting-google-cloud&#34;&gt;&lt;strong&gt;Organizational Change and Culture for Adopting Google Cloud Specialization&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&#34;https://coursera.org/share/d9a8867368088f1124c00a43ace5bb5d&#34;&gt;秀肌肉&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Business Transformation with Google Cloud&lt;/li&gt;
&lt;li&gt;Infrastructure and Application Modernization with Google Cloud&lt;/li&gt;
&lt;li&gt;Managing Change when Moving to Google Cloud&lt;/li&gt;
&lt;li&gt;Developing a Google SRE Culture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;看到 Google 居然把 &lt;a href=&#34;https://www.coursera.org/learn/developing-a-google-sre-culture&#34;&gt;Developing a Google SRE Culture&lt;/a&gt; 招牌課程放到這裡，可見 Google 有多重視推廣 SRE 這理念了。&lt;/p&gt;
&lt;h2 id=&#34;gcp-技術共通核心&#34;&gt;GCP 技術：共通核心&lt;/h2&gt;
&lt;p&gt;這類課程比較枯燥，但這是技術基礎，再枯燥也得撐過去。而且這類課程，是後續許多專項課程 (specialization) 都會涵蓋到的共同基礎，打好基礎，很容易繼續擴增廣度。&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/specializations/gcp-architecture&#34;&gt;&lt;strong&gt;Architecting with Google Compute Engine Specialization&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&#34;https://coursera.org/share/1a296ded15249add2a56a65eaaaf7986&#34;&gt;秀肌肉&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reliable Google Cloud Infrastructure: Design and Process&lt;/li&gt;
&lt;li&gt;Elastic Google Cloud Infrastructure: Scaling and Automation&lt;/li&gt;
&lt;li&gt;Google Cloud Fundamentals: Core Infrastructure&lt;/li&gt;
&lt;li&gt;Essential Google Cloud Infrastructure: Core Services&lt;/li&gt;
&lt;li&gt;Essential Google Cloud Infrastructure: Foundation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;雖然此專項課程宣稱 &amp;ldquo;this program will also provide sample questions similar to those on the exam&amp;rdquo;，但好像未必有 100% 涵蓋到 &amp;ldquo;Associate Cloud Engineer&amp;rdquo; 應考前該知道的細節。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/professional-certificates/cloud-engineering-gcp&#34;&gt;&lt;strong&gt;Preparing for Google Cloud Certification: Cloud Engineer&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&#34;https://coursera.org/share/f4bb77ea225fca9a4ef289498a7f0059&#34;&gt;秀肌肉&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Elastic Google Cloud Infrastructure: Scaling and Automation&lt;/li&gt;
&lt;li&gt;Google Cloud Fundamentals: Core Infrastructure&lt;/li&gt;
&lt;li&gt;Architecting with Google Kubernetes Engine: Foundations&lt;/li&gt;
&lt;li&gt;Essential Google Cloud Infrastructure: Core Services&lt;/li&gt;
&lt;li&gt;Essential Google Cloud Infrastructure: Foundation&lt;/li&gt;
&lt;li&gt;Preparing for Your Associate Cloud Engineer Journey&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/professional-certificates/gcp-cloud-architect&#34;&gt;&lt;strong&gt;Preparing for Google Cloud Certification: Cloud Architect Professional Certificate&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Cloud Fundamentals: Core Infrastructure&lt;/li&gt;
&lt;li&gt;Essential Google Cloud Infrastructure: Foundation&lt;/li&gt;
&lt;li&gt;Essential Google Cloud Infrastructure: Core Services&lt;/li&gt;
&lt;li&gt;Elastic Google Cloud Infrastructure: Scaling and Automation&lt;/li&gt;
&lt;li&gt;Reliable Google Cloud Infrastructure: Design and Process&lt;/li&gt;
&lt;li&gt;Architecting with Google Kubernetes Engine: Foundations&lt;/li&gt;
&lt;li&gt;Preparing for your Professional Cloud Architect Journey&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;三大系列洋洋灑灑，狀似龐大，但其實課程重疊度極高，就當成是一再複習加深印象吧。&lt;/p&gt;
&lt;h2 id=&#34;gcp-技術k8s&#34;&gt;GCP 技術：K8s&lt;/h2&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/specializations/architecting-google-kubernetes-engine&#34;&gt;&lt;strong&gt;Architecting with Google Kubernetes Engine Specialization&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&#34;https://coursera.org/share/3cba9fb951afdfae0ddb671c176c2a0d&#34;&gt;秀肌肉&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Cloud Fundamentals: Core Infrastructure&lt;/li&gt;
&lt;li&gt;Architecting with Google Kubernetes Engine: Foundations&lt;/li&gt;
&lt;li&gt;Architecting with Google Kubernetes Engine: Workloads&lt;/li&gt;
&lt;li&gt;Architecting with Google Kubernetes Engine: Production&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這專項課程，與 Udemy 三門 CKA/CKAD/CKS 認證考試課程相比，還算實用，可互補。&lt;/p&gt;
&lt;h2 id=&#34;dev&#34;&gt;Dev&lt;/h2&gt;
&lt;p&gt;很多課程似乎都鎖定在 serverless 方案，因此，先把這張圖記下來（引述自 &lt;a href=&#34;https://www.coursera.org/learn/application-development-with-cloud-run&#34;&gt;Application Development with Cloud Run&lt;/a&gt; 課程）：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/04/gcp-serverless-landscape.png&#34; alt=&#34;GCP 的 serverless 方案&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/04/gcp-serverless-landscape.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;GCP 的 serverless 方案&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/professional-certificates/google-cloud-developer&#34;&gt;&lt;strong&gt;Preparing for Google Cloud Certification: Cloud Developer&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&#34;https://coursera.org/share/aefc965bd4bdeee46b1fd906d1f93158&#34;&gt;秀肌肉&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Securing and Integrating Components of your Application&lt;/li&gt;
&lt;li&gt;Getting Started with Google Kubernetes Engine&lt;/li&gt;
&lt;li&gt;Application Development with Cloud Run&lt;/li&gt;
&lt;li&gt;App Deployment, Debugging, and Performance&lt;/li&gt;
&lt;li&gt;Google Cloud Fundamentals: Core Infrastructure&lt;/li&gt;
&lt;li&gt;Getting Started With Application Development&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比較令我驚訝的是，最後一門課 &lt;a href=&#34;https://www.coursera.org/learn/getting-started-app-development&#34;&gt;Getting Started With Application Development&lt;/a&gt; 花了很多篇幅在講 Cloud Run，尤其是講它的 networking &amp;amp; security 設定，卻讓人覺得這個 serverless 方案沒有想像中那麼無腦即可使用。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.coursera.org/learn/developing-applications-with-cloud-functions-on-google-cloud&#34;&gt;&lt;strong&gt;Developing Applications with Cloud Functions on Google Cloud&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;身為 GCP serverless 另一員大將 Cloud Functions，值得好好掌握。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.coursera.org/learn/service-orchestration-and-choreography-on-google-cloud&#34;&gt;&lt;strong&gt;Service Orchestration and Choreography on Google Cloud&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;難得在 GCP 課程上看到這主題，很值得照著他的範例把玩一遍。&lt;/p&gt;
&lt;h2 id=&#34;devops--sre&#34;&gt;DevOps &amp;amp; SRE&lt;/h2&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/professional-certificates/sre-devops-engineer-google-cloud&#34;&gt;&lt;strong&gt;Preparing for Google Cloud Certification: Cloud DevOps Engineer&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&#34;https://coursera.org/share/1df5d38f0baf4cc84d1a48d5c23df7ac&#34;&gt;秀肌肉&lt;/a&gt;)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Logging, Monitoring and Observability in Google Cloud&lt;/li&gt;
&lt;li&gt;Reliable Google Cloud Infrastructure: Design and Process&lt;/li&gt;
&lt;li&gt;Getting Started with Google Kubernetes Engine&lt;/li&gt;
&lt;li&gt;Google Cloud Fundamentals: Core Infrastructure&lt;/li&gt;
&lt;li&gt;Developing a Google SRE Culture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.coursera.org/learn/site-reliability-engineering-slos&#34;&gt;&lt;strong&gt;Site Reliability Engineering: Measuring and Managing Reliability&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這門課滿特別的，把 SRE 的 SLI/SLO 講得很仔細。譬如說，面對複雜系統，是否該臚列很多很多的 SLI？課程如是說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You should aim to only have &lt;strong&gt;one to three SLIs&lt;/strong&gt; covering each user journey, even if your system and user journeys are relatively complex.


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/04/sli-numbers.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/04/sli-numbers.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

​&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我發現，在 OKR &amp;amp; OGSM 講究的精簡指標觀念，在 SRE 裡面也是。
​
所以，不要以為落落長的指標才是好的。&lt;/p&gt;
&lt;h2 id=&#34;ml--big-data&#34;&gt;ML &amp;amp; Big Data&lt;/h2&gt;
&lt;p&gt;這系列重頭戲，我還在苦苦追趕，請恕我此刻暫時無法寫出什麼心得。 :)&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/specializations/gcp-data-machine-learning&#34;&gt;&lt;strong&gt;Data Engineering, Big Data, and Machine Learning on GCP Specialization&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Cloud Big Data and Machine Learning Fundamentals&lt;/li&gt;
&lt;li&gt;Modernizing Data Lakes and Data Warehouses with Google Cloud&lt;/li&gt;
&lt;li&gt;Building Batch Data Pipelines on Google Cloud&lt;/li&gt;
&lt;li&gt;Building Resilient Streaming Analytics Systems on Google Cloud&lt;/li&gt;
&lt;li&gt;Smart Analytics, Machine Learning, and AI on Google Cloud&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/specializations/machine-learning-tensorflow-gcp&#34;&gt;&lt;strong&gt;Machine Learning on Google Cloud Specialization&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How Google does Machine Learning&lt;/li&gt;
&lt;li&gt;Launching into Machine Learning&lt;/li&gt;
&lt;li&gt;TensorFlow on Google Cloud&lt;/li&gt;
&lt;li&gt;Feature Engineering&lt;/li&gt;
&lt;li&gt;Machine Learning in the Enterprise&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其中，像 &lt;a href=&#34;https://www.coursera.org/learn/google-machine-learning?specialization=machine-learning-tensorflow-gcp&#34;&gt;How Google does Machine Learning&lt;/a&gt; 這門課提到的 &amp;ldquo;Responsible AI Development&amp;rdquo; 議題，值此生成式 AI (AIGC) 火熱的時刻，讀起來格外有感。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/specializations/advanced-machine-learning-tensorflow-gcp&#34;&gt;&lt;strong&gt;Advanced Machine Learning on Google Cloud Specialization&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Production Machine Learning Systems&lt;/li&gt;
&lt;li&gt;Computer Vision Fundamentals with Google Cloud&lt;/li&gt;
&lt;li&gt;Natural Language Processing on Google Cloud&lt;/li&gt;
&lt;li&gt;Recommendation Systems on Google Cloud&lt;/li&gt;
&lt;li&gt;Machine Learning in the Enterprise&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系列／&lt;a href=&#34;https://www.coursera.org/specializations/customer-experience-gcp&#34;&gt;&lt;strong&gt;Customer Experiences with Contact Center AI - Dialogflow ES Specialization&lt;/strong&gt;&lt;/a&gt; &amp;amp; &lt;a href=&#34;https://www.coursera.org/specializations/customer-experiences-with-contact-center-ai-dialogflow-cx#courses&#34;&gt;&lt;strong&gt;Customer Experiences with Contact Center AI - Dialogflow CX Specialization&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;把玩一下聊天機器人吧。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上就是我個人偏食的菜單，希望給大家一些啟發，好好善用這個深度與廣度兼具的大補帖吧。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;對 GCP 認證考試相關課程感興趣的，可參考 &amp;ldquo;&lt;a href=&#34;https://www.coursera.org/articles/google-cloud-certification&#34;&gt;Google Cloud Certification: 2023 Guide&lt;/a&gt;&amp;rdquo; 一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Distroless Image 牛刀小試</title>
      <link>//william-yeh.net/post/2023/02/distroless-image/</link>
      <pubDate>Wed, 15 Feb 2023 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/02/distroless-image/</guid>
      
        <description>&lt;p&gt;距離上次重度探討「極簡化容器」已經快六年多了&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。這議題，以前可能只是某些人技術上的興趣，現在則可能是必要。&lt;/p&gt;
&lt;p&gt;原因是：Docker Inc 的一些措施，讓人不得不慎重考慮替代方案。&lt;/p&gt;
&lt;h2 id=&#34;搬家的必要&#34;&gt;搬家的必要&lt;/h2&gt;
&lt;p&gt;這陣子容器世界起了不少變化，除了眾所周知的「Docker Desktop 要收費了」規定 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，另一個較少被提及影響是 Docker Hub 的緊縮政策：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Image CI 緊縮：Docker Hub 取消免費用戶的 automated builds 功能。 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Image pull 緊縮：Docker Hub 開始對未付費者施以較嚴格的限流措施。 &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;於是，未付費的人，不僅在使用 Docker Hub 時會受到管制，還會波及產製 image 的 CI pipeline，不時會遇到這樣的 &amp;ldquo;toomanyrequests&amp;rdquo; 限流警告：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/ratelimit.png&#34; alt=&#34;Docker Hub 的 toomanyrequests 限流警告&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/ratelimit.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Docker Hub 的 toomanyrequests 限流警告&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;要避開這限制，治標方法是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;架設 image proxy。 &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;註冊 Docker Hub 帳號，將帳密寫進 CI pipeline 裡，以獲得稍微寬鬆一點點的 rate limit 門檻。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;治本方法，則得從兩方面著手：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Image 要從 Docker Hub 搬遷到 ghcr.io 之類的地方。&lt;/li&gt;
&lt;li&gt;直接引用的 base image(s) 也必須從 Docker Hub 換成 gcr.io 或 ghcr.io 之類的地方。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;其中 (1) 很簡單，只要會 CI pipeline 即可辦到，像 GitHub Action 就有許多現成的元件可用。&lt;/p&gt;
&lt;p&gt;至於 (2) 則比較麻煩。當然啦，對於玩過「極簡化容器」技術的人來說，這也只是小事一樁。&lt;/p&gt;
&lt;h2 id=&#34;distroless-image&#34;&gt;Distroless image&lt;/h2&gt;
&lt;p&gt;以前玩 minimal image 的人，是以 &lt;a href=&#34;https://hub.docker.com/_/alpine&#34;&gt;alpine&lt;/a&gt; 系列為大宗，只要不介意背後用的是 &lt;a href=&#34;https://en.wikipedia.org/wiki/Musl&#34;&gt;musl libc&lt;/a&gt;，這可以產生非常 &amp;ldquo;minimal&amp;rdquo; 的 image。近來 Google 的 &lt;a href=&#34;https://github.com/GoogleContainerTools/distroless&#34;&gt;&amp;ldquo;distroless&amp;rdquo; images&lt;/a&gt; 則提供 glibc 偏好者的另一種選擇，儘管它不算是 &amp;ldquo;minimal&amp;rdquo;，但也稱得上是 &amp;ldquo;small-enough&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;曾經我也是追求 minimal docker image 的一族 &lt;sup id=&#34;fnref1:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，現在我只求 small-enough 就好。畢竟對大多數應用場景來說，像以下這兩個 image，一個約 8 MB，一個約 29 MB，差異其實是可以忽略不計的：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Image&lt;/th&gt;
          &lt;th&gt;Size (MB)&lt;/th&gt;
          &lt;th&gt;Base&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;docker.io/williamyeh/wrk:4.0.2&lt;/td&gt;
          &lt;td&gt;8.347&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://hub.docker.com/_/alpine&#34;&gt;alpine3&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;ghcr.io/william-yeh/wrk:4.2.0&lt;/td&gt;
          &lt;td&gt;28.76&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/GoogleContainerTools/distroless&#34;&gt;gcr.io/distroless/cc-debian11&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/image-layers.png&#34; alt=&#34;兩種 image 的 layers&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/image-layers.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;兩種 image 的 layers&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;可是，若以資安角度來看，8.347 MB 的 image 被挑出許多漏洞，這很顛覆「alpine 又小又安全」的既定印象：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/alpine-security.png&#34; alt=&#34;以 Alpine 的 musl 生態系產製的 image 被偵測出許多資安漏洞&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/alpine-security.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;以 Alpine 的 musl 生態系產製的 image 被偵測出許多資安漏洞&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;反觀 28.76 MB 的 image 卻比較安全，這也很顛覆「glibc 系列不安全」的既定印象：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/distroless-security.png&#34; alt=&#34;以 Debian 的 glibc 生態系產製的 image 資安漏洞反而較少&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/distroless-security.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;以 Debian 的 glibc 生態系產製的 image 資安漏洞反而較少&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;因此，我會建議，對大多數應用程式來說，選擇 Google 的 &lt;a href=&#34;https://github.com/GoogleContainerTools/distroless&#34;&gt;distroless 路線&lt;/a&gt;，可以省下許多與 alpine 相容性搏鬥的精力，又可以享受到許多好處：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有 Google 在維護。&lt;/li&gt;
&lt;li&gt;Base image 的所在地 gcr.io 沒有限流問題。&lt;/li&gt;
&lt;li&gt;透過 multi-stage builds 機制，沿用既有工具鏈即可輕鬆製作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;對於 distroless 感興趣的，請參考 &amp;ldquo;&lt;a href=&#34;https://iximiuz.com/en/posts/containers-distroless-images/&#34;&gt;What&amp;rsquo;s Inside Of a Distroless Container Image: Taking a Deeper Look&lt;/a&gt;&amp;rdquo; 這篇文章。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;詳見〈&lt;a href=&#34;//william-yeh.net/post/2016/08/why-minimal-docker-images/&#34;&gt;為什麼要追求極簡化的 Docker image？&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Docker Desktop 新規定：只要公司超過 250 人，或是年營收超過美金千萬，就必須付費。根據 &lt;a href=&#34;https://www.docker.com/pricing/faq/&#34;&gt;Docker FAQs&lt;/a&gt; 文件所載：&amp;ldquo;Docker Desktop requires a paid, per-user subscription for organizations with more than 250 employees or more than $10 million in annual revenue per our terms of service. [..] The updated terms for Docker Desktop were effective August 31, 2021, with a grace period until January 31, 2022.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;根據 Docker Hub &amp;ldquo;&lt;a href=&#34;https://docs.docker.com/docker-hub/builds/&#34;&gt;Set up Automated Builds&lt;/a&gt;&amp;rdquo; 文件所載：&amp;ldquo;The Automated Builds feature is available for Docker Pro, Team, and Business users. Upgrade now to automatically build and push your images.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;根據 Docker Hub &amp;ldquo;&lt;a href=&#34;https://docs.docker.com/docker-hub/download-rate-limit/&#34;&gt;Download rate limit&lt;/a&gt;&amp;rdquo; 文件所載：&amp;ldquo;For anonymous users, the rate limit is set to 100 pulls per 6 hours per IP address. For authenticated users, it’s 200 pulls per 6 hour period. Users with a paid Docker subscription get up to 5000 pulls per day.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;其實有規模的組織，本來就應該自行架設 image proxy，以做好 artifact management。對這主題感興趣的，請參考 &amp;ldquo;&lt;a href=&#34;https://ranchergovernment.com/blog/mitigate-the-docker-dilemma-with-a-proxy-cache&#34;&gt;Mitigate the Docker Dilemma with a Proxy Cache&lt;/a&gt;&amp;rdquo; 一文。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>WSL Image 匯出與匯入</title>
      <link>//william-yeh.net/post/2023/02/wsl-image/</link>
      <pubDate>Thu, 09 Feb 2023 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/02/wsl-image/</guid>
      
        <description>&lt;p&gt;經過一番辛苦調教，總算把 WSL 調整成可推廣到團隊使用的地步。下一步就是要輸出成 WSL 公版。&lt;/p&gt;
&lt;p&gt;謹以此文記錄匯出與匯入 WSL 映像檔的步驟與除雷經驗。&lt;/p&gt;
&lt;h2 id=&#34;前置作業查看已安裝的軟體清單&#34;&gt;前置作業：查看已安裝的軟體清單&lt;/h2&gt;
&lt;p&gt;在匯出成公版之前，先查看已安裝了哪些軟體：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# 查看已用 apt install 安裝了哪些軟體
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% apt list --installed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# 查看已用 brew install 安裝了哪些軟體
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% brew list
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# 查看手動下載安裝了哪些軟體
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% ls -al /usr/local/bin&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;前置作業清理內容&#34;&gt;前置作業：清理內容&lt;/h2&gt;
&lt;p&gt;在匯出成公版之前，記得先清理一下機敏資料。譬如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;檢視一下 &lt;code&gt;~/.ssh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;檢視一下 &lt;code&gt;~/.kube&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;檢視一下 &lt;code&gt;~/.gitconfig&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;檢視一下其他重要的 &lt;a href=&#34;https://dotfiles.github.io/&#34;&gt;dotfiles&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也記得清理一下足跡：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;清理一下 &lt;code&gt;~/.*_history&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;清理一下 &lt;code&gt;/var/log&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;前置作業預設登入用戶&#34;&gt;前置作業：預設登入用戶&lt;/h2&gt;
&lt;p&gt;踩雷經驗：匯出再匯入 WSL 映像檔之後，再登入的身分會是 root。&lt;/p&gt;
&lt;p&gt;為了避免此事發生，請在匯出映像檔之前，先編輯 WSL 設定檔 &lt;code&gt;/etc/wsl.conf&lt;/code&gt; 如下：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[user]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;預設的登入帳號名稱&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;匯出映像檔&#34;&gt;匯出映像檔&lt;/h2&gt;
&lt;p&gt;先在 PowerShell 查看一下現在系統裡有哪些 WSL 設置：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wsl -l -v
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  NAME            STATE           VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* Ubuntu          Running         2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Ubuntu-22.04    Stopped         2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;假設 &lt;code&gt;Ubuntu&lt;/code&gt; 就是我們想要匯出的標的，請輸入以下命令：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 停止 &amp;#34;Ubuntu&amp;#34; 個體&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wsl -t Ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 將 &amp;#34;Ubuntu&amp;#34; 個體匯出至 &amp;#34;my-image.vhdx&amp;#34; 映像檔&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wsl  --export Ubuntu  --vhd my-image.vhdx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;映像檔可能很大。建議對它產生一份 hash，以供比對。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;匯入映像檔&#34;&gt;匯入映像檔&lt;/h2&gt;
&lt;p&gt;假設我們想從 &lt;code&gt;my-image.vhdx&lt;/code&gt; 映像檔匯入到一個名為 &lt;code&gt;dev&lt;/code&gt; 的 WSL 個體，請輸入以下指令：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# 將 &amp;#34;my-image.vhdx&amp;#34; 映像檔匯入到名為 &amp;#34;dev&amp;#34; 的 WSL 個體，
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# 並在 C:\WslDisk 建立虛擬硬碟
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wsl --import dev  C:\WslDisk  my-image.vhdx  --vhd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# 看看是否匯入成功
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wsl -l -v
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  NAME            STATE           VERSION
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;* Ubuntu          Stopped         2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  dev             Stopped         2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Ubuntu-22.04    Stopped         2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;你在 Windows Terminal 應該可以看到多了一個名為 &lt;code&gt;dev&lt;/code&gt; 的終端機選項：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/wsl-image-added.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/wsl-image-added.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;測試&#34;&gt;測試&lt;/h2&gt;
&lt;p&gt;既然是要給研發團隊用的公版，自然要登入看看是否一切正常。就以這陣子在實驗的 Laravel Sail 環境為例 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/558746&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/558746.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果有問題，就得卸載這份有瑕疵的 WSL 個體，回到源頭繼續修改：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 停止 &amp;#34;dev&amp;#34; 個體&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wsl -t dev
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 卸載 &amp;#34;dev&amp;#34; 個體&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wsl --unregister dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;如果還有預設登入帳號的問題&#34;&gt;如果還有預設登入帳號的問題&lt;/h2&gt;
&lt;p&gt;在前置作業時，曾經透過 WSL 設定檔 &lt;code&gt;/etc/wsl.conf&lt;/code&gt; 避免預設登入帳號變成 root 的問題。如果此法無效，請根據&lt;a href=&#34;https://superuser.com/a/1566031&#34;&gt;這份建議&lt;/a&gt;，用 Windows 登錄編輯程式 &lt;code&gt;regedit.exe&lt;/code&gt; 去修改 Windows registry：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Key&lt;/strong&gt;: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{某一個}&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Name&lt;/strong&gt;: &lt;code&gt;DefaultUid&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt;: 請切換成「十進位數字」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data&lt;/strong&gt;: 請設成 &lt;code&gt;1000&lt;/code&gt; （十進位數字）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;萬一還無效，請參考 &amp;ldquo;&lt;a href=&#34;https://superuser.com/questions/1566022/how-to-set-default-user-for-manually-installed-wsl-distro&#34;&gt;How to set default user for manually installed WSL distro?&lt;/a&gt;&amp;rdquo; 一文的討論。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;在 Windows 可透過 &lt;code&gt;certutil&lt;/code&gt; 或 &lt;code&gt;Get-FileHash&lt;/code&gt; 指令取得檔案的 hash 值。詳見 &amp;ldquo;&lt;a href=&#34;https://www.nextofwindows.com/5-ways-to-generate-and-verify-md5-sha-checksum-of-any-file-in-windows-10&#34;&gt;5 Ways to Generate and Verify MD5 SHA Checksum of Any File in Windows 10&lt;/a&gt;&amp;rdquo; 一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;詳見〈&lt;a href=&#34;//william-yeh.net/post/2023/02/podman-laravel-sail/&#34;&gt;用 Podman 執行 Laravel + Sail&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>用 Podman 執行 Laravel &#43; Sail</title>
      <link>//william-yeh.net/post/2023/02/podman-laravel-sail/</link>
      <pubDate>Tue, 07 Feb 2023 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/02/podman-laravel-sail/</guid>
      
        <description>&lt;p&gt;從 Docker Desktop 換到 Podman &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; ，開始需要處理某些相容性問題。有些問題不見得是 Podman 的錯，但既然遇到了，就順手記錄一下除雷經驗。&lt;/p&gt;
&lt;p&gt;此文記錄一下在 Podman 執行 Laravel 9 欽定開發環境 &lt;a href=&#34;https://laravel.com/docs/9.x/sail&#34;&gt;Sail&lt;/a&gt; 的步驟。&lt;/p&gt;
&lt;h2 id=&#34;前置作業安裝-podman&#34;&gt;前置作業：安裝 Podman&lt;/h2&gt;
&lt;p&gt;如果你是 Linux 用戶，請依照 &lt;a href=&#34;https://podman.io/getting-started/installation#installing-on-linux&#34;&gt;Podman 官方文件&lt;/a&gt;所載步驟安裝 Podman。&lt;/p&gt;
&lt;p&gt;如果你是 Windows 用戶，請根據〈&lt;a href=&#34;//william-yeh.net/post/2023/02/wsl2-podman-k3s/&#34;&gt;WSL2 + Podman + K3s 組合技&lt;/a&gt;〉一文安裝 WSL2 + Podman。&lt;/p&gt;
&lt;p&gt;如果你是 Mac 用戶，請先用 &lt;code&gt;brew install podman&lt;/code&gt; 來安裝。但據說 multipass + Podman 方案更好，我會再找時間實驗。&lt;/p&gt;
&lt;h2 id=&#34;前置作業podman-daemon-mode&#34;&gt;前置作業：Podman daemon mode&lt;/h2&gt;
&lt;p&gt;Laravel 的 Sail 需要用到 Docker Compose，而且它的 docker-compose.yml 又寫得⋯⋯很需要是以 daemon mode 運作的 container engine。&lt;/p&gt;
&lt;p&gt;所以，請根據〈&lt;a href=&#34;//william-yeh.net/post/2023/02/podman-tips/#daemon-mode&#34;&gt;Podman Tips&lt;/a&gt;〉一文的步驟，啟動一個 daemon mode 的 Podman。&lt;/p&gt;
&lt;h2 id=&#34;前置作業解決-composer-連線問題&#34;&gt;前置作業：解決 Composer 連線問題&lt;/h2&gt;
&lt;p&gt;有些人在透過 Composer 安裝套件的過程中，會出現 repo.packagist.org 連線 timeout 的問題：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;curl error 28 while downloading https://repo.packagist.org/packages.json:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    Connection timed out after 10000 milliseconds&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;請參考&lt;a href=&#34;https://github.com/composer/packagist/issues/950#issuecomment-424913225&#34;&gt;這篇解法&lt;/a&gt;，將 repo.packagist.org 的 IPv4 位址直接寫死到 &lt;code&gt;/etc/hosts&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% dig +short repo.packagist.org
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% echo &amp;#34;`dig +short repo.packagist.org` repo.packagist.org&amp;#34; &amp;gt;&amp;gt; /etc/hosts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;如果你是身處 WSL2 環境，也請順便編輯一下 WSL 的設定檔 &lt;code&gt;/etc/wsl.conf&lt;/code&gt; 以避免設定消失：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[network]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Disable auto-gen /etc/hosts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;generateHosts&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;安裝-sail&#34;&gt;安裝 Sail&lt;/h2&gt;
&lt;p&gt;請依照 &lt;a href=&#34;https://laravel.com/docs/9.x/installation#getting-started-on-linux&#34;&gt;Laravel 官方文件&lt;/a&gt;所載步驟，安裝一整套 PHP + Composer + Laravel + Sail + blah blah blah 本地開發環境，也順便建立一個名為 &amp;ldquo;example-app&amp;rdquo; 的新專案：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% curl -s &amp;#34;https://laravel.build/example-app&amp;#34; | bash&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;修改-sail-產生的專案設定&#34;&gt;修改 Sail 產生的專案設定&lt;/h2&gt;
&lt;p&gt;透過 Laravel + Sail 產生的專案，預設會跑在 port 80。我建議修改到其他 unprivileged port 以減少問題。&lt;/p&gt;
&lt;p&gt;請在專案的 &lt;code&gt;.env&lt;/code&gt; 檔案添加這一行：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;APP_PORT=3001&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;透過 Laravel + Sail 產生的專案，&lt;code&gt;storage&lt;/code&gt; 目錄可能會有存取權限的問題。請參考&lt;a href=&#34;https://stackoverflow.com/a/67511101/714426&#34;&gt;這篇解法&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% chmod o+w ./storage/ -R&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;或是保守一點：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% chmod o+w ./storage/logs/       -R
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% chmod o+w ./framework/cache/    -R
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% chmod o+w ./framework/sessions/ -R
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% chmod o+w ./framework/views/    -R&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;執行-sail&#34;&gt;執行 Sail&lt;/h2&gt;
&lt;p&gt;請依照 &lt;a href=&#34;https://laravel.com/docs/9.x/installation#getting-started-on-linux&#34;&gt;Laravel 官方文件&lt;/a&gt;所載步驟，執行 &amp;ldquo;example-app&amp;rdquo; 專案：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% cd example-app
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% ./vendor/bin/sail up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;如果一切順利，可以用瀏覽器看到 http://localhost:3001/ 順利執行：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/laravel-screenshot.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/laravel-screenshot.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;也順便看看整個 Laravel 產生的本地開發環境含有哪些東西：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/laravel-process.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/laravel-process.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;僅以這篇文章示範，只要懂得排雷，Podman 足以勝任 Docker Desktop 的角色。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;詳見〈&lt;a href=&#34;//william-yeh.net/post/2023/02/wsl2-podman-k3s/&#34;&gt;WSL2 + Podman + K3s 組合技&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Podman Tips</title>
      <link>//william-yeh.net/post/2023/02/podman-tips/</link>
      <pubDate>Tue, 07 Feb 2023 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/02/podman-tips/</guid>
      
        <description>&lt;p&gt;從 Docker Desktop 換成 Podman，有些習慣必須做些小調整。此文記錄一些常用的小技巧。&lt;/p&gt;
&lt;h2 id=&#34;image-tree&#34;&gt;Image tree&lt;/h2&gt;
&lt;p&gt;很久很久以前，我們可以用 &lt;code&gt;docker images --tree&lt;/code&gt; 來看 &lt;a href=&#34;https://docs.docker.com/storage/storagedriver/#images-and-layers&#34;&gt;image layer&lt;/a&gt; 的層次關係。此功能選項被後來某一版 Docker 廢除了，於是就有一些替代方案來做這件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/justone/dockviz&#34;&gt;dockviz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/wagoodman/dive&#34;&gt;dive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/TomasTomecek/sen&#34;&gt;sen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可惜的是，這些工具都假設現在是處於「有一個 daemon 跑在 &lt;code&gt;DOCKER_HOST&lt;/code&gt;」的環境（畢竟這是 Docker 的老規矩）。如果我們不想為此而刻意以 daemon 模式啟動 Podman，可透過 Podman 的 &lt;a href=&#34;https://docs.podman.io/en/latest/markdown/podman-image-tree.1.html&#34;&gt;image tree 指令&lt;/a&gt;來檢視 image：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% podman image tree python:3.9.16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;daemon-mode&#34;&gt;Daemon mode&lt;/h2&gt;
&lt;p&gt;儘管 daemonless 的好處很多，但很多舊世界的工具，會假設現在是處於「有一個 container engine daemon 跑在 &lt;code&gt;DOCKER_HOST&lt;/code&gt;」的環境。因此，有時候我們得故意讓 Podman 以 daemon mode 運行。&lt;/p&gt;
&lt;h3 id=&#34;臨時性實驗&#34;&gt;臨時性實驗&lt;/h3&gt;
&lt;p&gt;我們先啟動一個 rootless Podman process：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% podman system service -t 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;另開一個終端機視窗，設置 &lt;code&gt;DOCKER_HOST&lt;/code&gt; 環境變數：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% podman info --format={{&amp;#34;.Host.RemoteSocket.Path&amp;#34;}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% export DOCKER_HOST=unix://$(podman info --format={{&amp;#34;.Host.RemoteSocket.Path&amp;#34;}})&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;現在，我們可以在這個終端機實驗看看那些舊世界的工具是否可以正常運作。就以前面提到的 &lt;a href=&#34;https://github.com/wagoodman/dive&#34;&gt;dive&lt;/a&gt; 為例吧！&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% dive python:3.9.16&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h3 id=&#34;便利性設置&#34;&gt;便利性設置&lt;/h3&gt;
&lt;p&gt;如果一切正常，我們可以寫一個 &lt;code&gt;/usr/local/bin/start-podman-service.sh&lt;/code&gt; 程式以簡化啟用流程：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;FILE=/var/run/docker.sock
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;if [ ! -f &amp;#34;$FILE&amp;#34; ]; then
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sudo ln -s /run/user/$(id -u)/podman/podman.sock $FILE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo &amp;#34;Starting podman as server... Ctrl-C to stop.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec podman system service -t 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;在不需要時，按下 &lt;code&gt;Ctrl&lt;/code&gt;+&lt;code&gt;C&lt;/code&gt; 即可關閉，非常方便。&lt;/p&gt;
&lt;h3 id=&#34;持久性設置&#34;&gt;持久性設置&lt;/h3&gt;
&lt;p&gt;如果你想透過 systemd 來管理，請參考 K3d 團隊提供的 &lt;a href=&#34;https://k3d.io/v5.4.7/usage/advanced/podman/&#34;&gt;Using Podman instead of Docker&lt;/a&gt; 這篇文章。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>WSL2 &#43; Podman &#43; K3s 組合技</title>
      <link>//william-yeh.net/post/2023/02/wsl2-podman-k3s/</link>
      <pubDate>Mon, 06 Feb 2023 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2023/02/wsl2-podman-k3s/</guid>
      
        <description>&lt;p&gt;距離上次重度使用 WSL 已經快四年了。四年來 WSL 世界起了一些變化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;WSL 已經演進到第二版。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以前還會為了要搭配 &lt;a href=&#34;//william-yeh.net/post/2019/03/wsl-cmder-zsh/&#34;&gt;Cmder&lt;/a&gt; 或者 &lt;a href=&#34;//william-yeh.net/post/2019/04/wsltty-tmux/&#34;&gt;WSLtty&lt;/a&gt; 而大費周章，現在則被 &lt;a href=&#34;https://learn.microsoft.com/zh-tw/windows/terminal/&#34;&gt;Windows Terminal&lt;/a&gt; 解決了大部分問題，使用體驗也開始接近 Mac 的 iTerm2。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;容器世界也起了很大的變化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Docker Desktop 新規定：只要公司超過 250 人，或是年營收超過美金千萬，就必須付費。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Docker Hub 也開始對未付費者施以較嚴格的限流措施。 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes 從 1.24 起停止支援 dockershim。 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;RedHat 釋出的 &lt;a href=&#34;https://podman.io/&#34;&gt;Podman&lt;/a&gt;，挾其完全免費、daemonless、rootless、pod 的特性，開始吸引對 Docker 起異心的人。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，我也趁此機會更新這方面的資訊，以免費的組合技，在 Windows 上盡量復刻 Mac 的容器體驗：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;以 WSL 2 與 IDE 的整合，兼顧命令列與 GUI 體驗。&lt;/li&gt;
&lt;li&gt;以 Podman 取代 Docker Desktop 的 container engine。&lt;/li&gt;
&lt;li&gt;以 K3s 取代 Docker Desktop 的 Kubernetes。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;註：如果不想以 WSL 2 為工作環境 (1)，單純只想要一個 Desktop Desktop 替代方案 (2 + 3) 的人，可以直接選用 &lt;a href=&#34;https://rancherdesktop.io/&#34;&gt;Rancher Desktop&lt;/a&gt;，就不必往下看了。&lt;/p&gt;
&lt;h2 id=&#34;wsl-2&#34;&gt;WSL 2&lt;/h2&gt;
&lt;p&gt;請依照保哥的文章〈&lt;a href=&#34;https://blog.miniasp.com/post/2022/11/25/Useful-tool-WSL-1-0&#34;&gt;介紹好用工具：從 Microsoft Store 安裝 WSL 1.0 版&lt;/a&gt;〉進行以下步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;更新 Windows 版本（譬如說，Windows 10 請更新至 &lt;code&gt;22H2&lt;/code&gt; 以上，並確定套用過  &lt;a href=&#34;https://support.microsoft.com/en-us/topic/november-15-2022-kb5020030-os-builds-19042-2311-19043-2311-19044-2311-and-19045-2311-preview-237a9048-f853-4e29-a3a2-62efdbea95e2?WT.mc_id=DT-MVP-4015686&#34;&gt;KB5020030&lt;/a&gt; patch）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安裝 WSL。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;更新 WSL 版本：&lt;code&gt;wsl --update&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查看 WSL 版本：&lt;code&gt;wsl --version&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果一切順利，應該會看到類似以下的畫面：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/wsl-version.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/wsl-version.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;請確定 WSL 版本是 1.0.3.0 以上，否則接下來可能會遇到一堆稀奇古怪的問題。 &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;接下來，請繼續透過 WSL 安裝 Linux：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;安裝一個 Linux distribution。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第一次執行 WSL，並設定 Linux 的帳號密碼。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;建議編輯一下 WSL 的設定檔 &lt;code&gt;/etc/wsl.conf&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[boot]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;systemd&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[network]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Disable auto-gen /etc/resolv.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;generateResolvConf&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Disable auto-gen /etc/hosts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# @see https://github.com/composer/packagist/issues/950#issuecomment-424913225&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;generateHosts&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;如果要避免 WSL 占用過多系統資源，可編輯 Windows 的 &lt;code&gt;$env:USERPROFILE\.wslconfig&lt;/code&gt; 檔案如下：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;[wsl2]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;memory&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;4GB&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;processors&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;如果要讓 Windows 慣用的 IDE 能夠與 WSL 合作順暢，請參考相關的設定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;VS Code 需要安裝 &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl&#34;&gt;WSL extension&lt;/a&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;JetBrains 的工具，各有對應的文件說明，像 &lt;a href=&#34;https://www.jetbrains.com/help/go/how-to-use-wsl-development-environment-in-product.html&#34;&gt;GoLand 可直接使用&lt;/a&gt;，PHPStorm 則需透過 &lt;a href=&#34;https://www.jetbrains.com/help/phpstorm/configuring-remote-interpreters.html&#34;&gt;PHP remote interpreters&lt;/a&gt; plugin。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;zsh--oh-my-zsh--homebrew&#34;&gt;Zsh + Oh My ZSH + Homebrew&lt;/h2&gt;
&lt;p&gt;在 WSL 中安裝 zsh 及 oh-my-zsh：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo apt-get install zsh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sh -c &amp;#34;$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;將 zsh 設為內定 shell：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% chsh -s $(which zsh)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;如果你的 zsh theme 含有許多特殊的符號字元，請順便安裝 &lt;a href=&#34;https://github.com/powerline/fonts&#34;&gt;Powerline&lt;/a&gt; 系列字型。&lt;/p&gt;
&lt;p&gt;Mac 族群一向愛用 &lt;a href=&#34;https://brew.sh/&#34;&gt;Homebrew&lt;/a&gt;。既然它也搬到 Linux 世界了，就來安裝吧！&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo apt-get install build-essential curl file git
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sh -c &amp;#34;$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% # 請記得要遵照安裝畫面出現的步驟做最後的設定！&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;podman&#34;&gt;Podman&lt;/h2&gt;
&lt;p&gt;透過 WSL 安裝好 Linux 之後，其實我們大可在裡面安裝純粹的 Docker Engine](&lt;a href=&#34;https://docs.docker.com/engine/install/&#34;&gt;https://docs.docker.com/engine/install/&lt;/a&gt;)，即過去俗稱的 &lt;a href=&#34;https://github.com/docker/docker-ce&#34;&gt;CE 版 (community edition)&lt;/a&gt; 或 Moby，它採用 Apache License 2.0 授權，不會有 Docker Desktop 的收費問題。&lt;/p&gt;
&lt;p&gt;不過，我還是想玩玩具有 daemonless &amp;amp; rootless 特性的替代方案：Podman。&lt;/p&gt;
&lt;h3 id=&#34;安裝&#34;&gt;安裝&lt;/h3&gt;
&lt;p&gt;請依照 &lt;a href=&#34;https://podman.io/getting-started/installation#installing-on-linux&#34;&gt;Podman 官方文件&lt;/a&gt;所載步驟安裝 Podman。譬如說，如果 WSL 的 distribution 是 Ubuntu 22.04.1 LTS，可如此安裝：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo apt -y install podman&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;或是直接透過 Homebrew 安裝。好處是容易更新版本，缺點是安裝較慢：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo apt install uidmap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% brew install podman&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h3 id=&#34;設定&#34;&gt;設定&lt;/h3&gt;
&lt;p&gt;Podman 是 daemonless + rootless 的架構。如果你希望讓 container 能夠自由綁定 port 80 以利本地開發，可以考慮在 &lt;code&gt;/etc/sysctl.conf&lt;/code&gt; 添加設定：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;net.ipv4.ip_unprivileged_port_start=80&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;還有一個選擇性步驟。如果你希望讓 image 不會被綁在 &lt;code&gt;docker.io/library/&lt;/code&gt; 這個預設的 registry，可以考慮在 &lt;code&gt;/etc/containers/registries.conf&lt;/code&gt; 添加設定 &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; ：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;unqualified-search-registries=[
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;registry.access.redhat.com&amp;#34;, &amp;#34;registry.fedoraproject.org&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;quay.io&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;gcr.io&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;ghcr.io&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;#34;docker.io&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h3 id=&#34;便利性&#34;&gt;便利性&lt;/h3&gt;
&lt;p&gt;為了讓 Podman 能盡量沿用過往 Docker 的使用習慣，建議在 &lt;code&gt;$HOME/.bashrc&lt;/code&gt; 添加 alias：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;alias docker=&amp;#39;podman&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;如果遇到 alias 也無法避開的問題，建議索性放一個 &lt;code&gt;/usr/local/bin/docker&lt;/code&gt; 檔案：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec podman &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$@&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;podman-play-kube&#34;&gt;Podman play kube&lt;/h2&gt;
&lt;p&gt;Podman 有一個介於 Docker 與 Kubernetes 之間的功能：pod。如果懂得善用，在許多情況下可以取代 Docker Compose，也做為邁向 Kubernetes 的踏腳石。&lt;/p&gt;
&lt;p&gt;譬如說，如果我們稍加修改 Kubernetes 官網的 pod 範例 &lt;a href=&#34;https://kubernetes.io/docs/concepts/workloads/pods/#using-pods&#34;&gt;simple-pod.yaml&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;apiVersion&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;kind&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Pod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;metadata&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;nginx-pod&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;spec&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;containers&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;nginx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;image&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;docker.io/library/nginx:1.14.2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - &lt;span style=&#34;color:#f92672&#34;&gt;containerPort&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;hostPort&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;     &lt;span style=&#34;color:#75715e&#34;&gt;# add this line&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;接下來就可用 &lt;code&gt;podman play kube&lt;/code&gt; 指令在 WSL 啟用這個 &lt;code&gt;nginx-pod&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo podman play kube simple-pod.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;如果一切順利，就可以在 WSL 裡面看到 nginx pod 成功執行：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% podman pod ps
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;POD ID        NAME        STATUS      CREATED            INFRA ID      # OF CONTAINERS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;46be4ed3a73f  nginx-pod   Degraded    About an hour ago  93d658fa1939  2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% wget -O - localhost:8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;也可以在 Windows host 用瀏覽器看到 nginx 順利執行：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/nginx-welcome.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/nginx-welcome.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;podman-compose&#34;&gt;Podman Compose&lt;/h2&gt;
&lt;p&gt;Kubernetes 生態圈有一大堆媲美 Docker Compose 便利性的工具（譬如我愛用的 &lt;a href=&#34;https://skaffold.dev/&#34;&gt;Skaffold&lt;/a&gt;）。不過，如果你實在太想念 Docker Compose，有兩種做法：&lt;/p&gt;
&lt;p&gt;➀ 可直接沿用舊的 Docker Compose，但是需要將 Podman 啟動成 daemon &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; 。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/docker/compose&#34;&gt;Docker Compose&lt;/a&gt; 的安裝方法：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo curl -SL https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo chmod +x /usr/local/bin/docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;➁ 如果不需顧及相容性，不妨試試 Podman 陣營端出的替代品 &lt;a href=&#34;https://github.com/containers/podman-compose&#34;&gt;Podman Compose&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;對於 Podman Compose 感興趣的，請參考以下文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://phoenixnap.com/kb/podman-compose&#34;&gt;Podman Compose - Managing Containers&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.redhat.com/sysadmin/podman-compose-docker-compose&#34;&gt;Podman Compose or Docker Compose: Which should you use in Podman?&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;k3s&#34;&gt;K3s&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://k3s.io/&#34;&gt;K3s&lt;/a&gt; 是由 Rancher Labs 貢獻給 CNCF 的輕量級 Kubernetes 開源方案，很適合應用程式開發者使用，作為 Docker Desktop 內建 Kubernetes 的替代方案。&lt;/p&gt;
&lt;p&gt;請依照 &lt;a href=&#34;https://docs.k3s.io/installation/configuration&#34;&gt;K3s 官方文件&lt;/a&gt;所載步驟安裝： &lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% curl -sfL https://get.k3s.io | K3S_KUBECONFIG_MODE=&amp;#34;644&amp;#34; sh -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;為了讓其他 Kubernetes 相關工具順利運作，建議在 &lt;code&gt;$HOME/.bashrc&lt;/code&gt; 添加 &lt;code&gt;KUBECONFIG&lt;/code&gt; 環境變數：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export KUBECONFIG=&amp;#34;~/.kube/config:/etc/rancher/k3s/k3s.yaml&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;k9s&#34;&gt;K9s&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://k9scli.io/&#34;&gt;K9s&lt;/a&gt; 是很方便的 Kubernetes 終端機工具，請依照官方文件所載步驟安裝：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% brew install derailed/k9s/k9s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;現在，我們可以用 &lt;code&gt;k9s&lt;/code&gt; 指令查看剛剛安裝好的最陽春的 K3s 環境到底跑了哪些東西：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/k9s-screenshot.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/k9s-screenshot.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;全部看一遍&#34;&gt;全部看一遍&lt;/h2&gt;
&lt;p&gt;截至目前為止，我們安裝好了 Podman 及 K3s，也利用 Podman 啟動一個 nginx pod。現在，讓我們看看整個 WSL 系統的 process tree：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2023/02/all-screenshot.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2023/02/all-screenshot.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;整個 process tree 非常扁平，是不是跟以前 Docker Desktop 的版本很不一樣呢？&lt;/p&gt;
&lt;p&gt;希望這篇文章，能夠讓你更放心擺脫 Docker Desktop。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;根據 &lt;a href=&#34;https://www.docker.com/pricing/faq/&#34;&gt;Docker FAQs&lt;/a&gt; 文件所載：&amp;ldquo;Docker Desktop requires a paid, per-user subscription for organizations with more than 250 employees or more than $10 million in annual revenue per our terms of service. [..] The updated terms for Docker Desktop were effective August 31, 2021, with a grace period until January 31, 2022.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;根據 Docker Hub &lt;a href=&#34;https://docs.docker.com/docker-hub/download-rate-limit/&#34;&gt;Download rate limit&lt;/a&gt; 文件所載：&amp;ldquo;For anonymous users, the rate limit is set to 100 pulls per 6 hours per IP address. For authenticated users, it’s 200 pulls per 6 hour period. Users with a paid Docker subscription get up to 5000 pulls per day.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;關於 Kubernetes 1.24 停止支援 dockershim 的始末，請見 &lt;a href=&#34;https://kubernetes.io/blog/2022/02/17/dockershim-faq/&#34;&gt;Updated: Dockershim Removal FAQ&lt;/a&gt; 這份文件。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;譬如說在 &amp;ldquo;&lt;a href=&#34;https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/#how-can-you-get-systemd-on-your-machine&#34;&gt;Systemd support is now available in WSL!&lt;/a&gt;&amp;rdquo; 一文就提到，如果 WSL 版本過舊，甚至連 Linux systemd 功能都會有問題。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;關於 &lt;code&gt;registries.conf&lt;/code&gt; 的更多設定內容，請見 &lt;a href=&#34;https://www.redhat.com/sysadmin/manage-container-registries&#34;&gt;How to manage Linux container registries&lt;/a&gt; 一文。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;關於將 Podman 以 daemon mode 運作的具體步驟，請參考〈&lt;a href=&#34;//william-yeh.net/post/2023/02/podman-tips/#daemon-mode&#34;&gt;Podman Tips&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;大部份的人會依照 &lt;a href=&#34;https://k3s.io/&#34;&gt;K3s 首頁&lt;/a&gt;所載的步驟 &lt;code&gt;curl -sfL https://get.k3s.io | sh -&lt;/code&gt; 來安裝 K3s，但這樣安裝好的 K3s 常會需要動用 &lt;code&gt;sudo&lt;/code&gt; 才能執行相關指令。我認為，與其事後再用 &lt;a href=&#34;https://0to1.nl/post/k3s-kubectl-permission/&#34;&gt;k3s permission denied when using kubectl&lt;/a&gt; 所介紹的方法調整設定，不如從一開始就以不需動用 &lt;code&gt;sudo&lt;/code&gt; 的方式安裝。&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>2022 個人回顧</title>
      <link>//william-yeh.net/post/2022/12/2022-retrospective/</link>
      <pubDate>Sun, 18 Dec 2022 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/12/2022-retrospective/</guid>
      
        <description>&lt;p&gt;去年年終&lt;a href=&#34;//william-yeh.net/post/2021/12/2021-retrospective/&#34;&gt;回顧文&lt;/a&gt;中，我曾半戲謔說道：自己好像都在消費之前外商經驗的戰備存糧。&lt;/p&gt;
&lt;p&gt;今年，這份感受更加明顯，甚至連台商新創經驗都動用到了。&lt;/p&gt;
&lt;p&gt;到了年終，又開始要做個總回顧，再對來年許願。去除一些不便揭露的事情，以下是簡單的回顧。&lt;/p&gt;
&lt;h2 id=&#34;補血課程&#34;&gt;補血課程&lt;/h2&gt;
&lt;p&gt;這一年，由於 COVID-19 因素，參加的實體或線上 Live 課程，就只有這兩場：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scrumoholics.com/&#34;&gt;Team Kanban Practitioner&lt;/a&gt;：由我邀請老師來授課的。原本我只是安排給其他主管同仁去上課，後來索性自己也加入共學，後續的跟進措施較能落實。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TTT 二日課程：由公司舉辦的。原本我打算安排給其他種子教師同仁去上課，後來索性自己也加入共學，不僅後續的跟進措施較能落實，也藉此自我補齊相關基礎——畢竟自己在 2018 年上的【&lt;a href=&#34;//william-yeh.net/post/2018/04/board-game-creation/&#34;&gt;體驗式課程的遊戲設計與操作實務&lt;/a&gt;】三日課程，可說是一下子就跳級到進階版了，我想回頭再親身體驗一下基礎版。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/12/2022-12-14_TTT.jpg&#34; alt=&#34;TTT 試教 (2022-12-14)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/12/2022-12-14_TTT.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;TTT 試教 (2022-12-14)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;公開演講及授課&#34;&gt;公開演講及授課&lt;/h2&gt;
&lt;p&gt;今年，由於 COVID-19 因素，再加上自覺已經過了能夠恣意 &lt;del&gt;跑趴&lt;/del&gt; 出沒 社群活動的人生階段，婉拒許多邀約，只接了一場公開工作坊：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://agile.ithome.com.tw/2022/workshop-page/1090&#34;&gt;敏捷轉型：目標管理工作坊&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/12/agile-metrics.jpg&#34; alt=&#34;敏捷轉型：目標管理工作坊 (2022-08-31)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/12/agile-metrics.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;敏捷轉型：目標管理工作坊 (2022-08-31)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;反之，如果是在公司的上班時間、用公司的場地舉辦活動，安排起來較有餘裕，也就順勢辦了好幾場。像我的招牌課程【Agile Workshop / 敏捷原理與團隊塑造】及後續跟進的種種專題工作坊，次數已經難以計算。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/12/agile-workshop-8hr.jpg&#34; alt=&#34;Agile Workshop 一日版&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/12/agile-workshop-8hr.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Agile Workshop 一日版&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;關於我的 Agile Workshop，除了當年某個&lt;a href=&#34;https://www.accupass.com/event/1807260907551870930205&#34;&gt;公開班&lt;/a&gt;可以開出豪邁的二日版，後來都只能客製化組裝出一日版。好在經過多年錘鍊，已經模組化到能夠彈性端出 1 hr、2 hrs、4 hrs、8 hrs、12 hrs、16 hrs 不同套餐，能將 Impact Mapping、Kanban、Scrum 都實彈演練到一個地步，積木玩到了，電影也看到了。&lt;/p&gt;
&lt;p&gt;順便推出一個 20 分鐘快速介紹 Scrum 的影片，以後就可以叫學員先看完影片再來上課：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/1_zwSqYUlYc?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;內部導讀會&#34;&gt;內部導讀會&lt;/h2&gt;
&lt;p&gt;去年年終&lt;a href=&#34;//william-yeh.net/post/2021/12/2021-retrospective/&#34;&gt;回顧文&lt;/a&gt;中，我曾許願要「每個月辦一場 2hr 導讀會」。&lt;/p&gt;
&lt;p&gt;原本只是一個單純的動機：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我開始每個月一次，每次兩小時的【&lt;a href=&#34;//william-yeh.net/post/2022/06/career-reading-club-1/&#34;&gt;職涯躍升書系導讀會&lt;/a&gt;】，讓公司同仁自由報名，希望藉由這種草根性的軟性活動，另闢一條 bottom-up 的改革路徑。畢竟，深遠持久的影響，不能少掉「喚醒基層意識」這環節。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我也想藉此機會刻意練習「金字塔原理」一整年（是的，我以金字塔原理來進行每一場導讀會）。&lt;/p&gt;
&lt;p&gt;沒想到才舉辦了一次，就遇到疫情攪局，分流上班，活動得移往線上進行，大大考驗我線上引導活動的能力。為此，努力師法福哥【&lt;a href=&#34;https://hahow.in/courses/5ed70db89afae672fd4a07c9/&#34;&gt;線上教學防疫補給包&lt;/a&gt;】及 &lt;a href=&#34;https://www.bobpikegroup.com/miro-miro-on-the-wall&#34;&gt;Miro-Miro on the Wall&lt;/a&gt; webinar 的經驗，順利完成了好幾場，甚至連《&lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;》介紹的「Personal History Exercise」如此心理層面的活動都能夠在線上進行，讓我鬆了一口氣，私房工具箱又增添一項利器。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/12/dysfunction-workshop.jpg&#34; alt=&#34;《克服團隊領導的五大障礙》導讀會&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/12/dysfunction-workshop.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《克服團隊領導的五大障礙》導讀會&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;一整年下來，不知不覺也導讀了這麼多本：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865027896&#34;&gt;經理人之道&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://williampjyeh.notion.site/cd42e217271d454aac9411b0c6fc84c7&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://williampjyeh.notion.site/1a6d4482e2bb42329d85624c214c91fb&#34;&gt;不懂這些，別想加薪&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010819665&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.playpcesor.com/2020/05/2020-new-book.html&#34;&gt;時間管理的 30 道難題&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;薩提爾教練模式&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://williampjyeh.notion.site/b299b20f381643c9b7b0caaba1d12f44&#34;&gt;為什麼上班這麼累？其實是你心累&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://williampjyeh.notion.site/QBQ-30-89b7f2e8006e41afa8953f238ff26441&#34;&gt;QBQ！問題背後的問題&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://williampjyeh.notion.site/99f7c1cb5ef84873bf294916a03715a0&#34;&gt;當責，從停止抱怨開始&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;每重讀一次，形同再次自我療癒了一次。畢竟，改革者、先行者是孤獨的。&lt;/p&gt;
&lt;p&gt;或許會被認為我在散發所謂的「有毒思想」，但只要看到還有一些人能被啟發思考，那就值得了。&lt;/p&gt;
&lt;h2 id=&#34;內部培訓主管的修練&#34;&gt;內部培訓：主管的修練&lt;/h2&gt;
&lt;p&gt;我很愛用「讀書會」這一招，甚至把它當成另一種培訓形式。像當年我在Ｇ公司辦的【&lt;a href=&#34;//william-yeh.net/post/2018/12/practice-of-managers/&#34;&gt;主管的修練／讀書會&lt;/a&gt;】就是這樣進行的。&lt;/p&gt;
&lt;p&gt;這陣子我又祭出這一招，舉辦七次內部培訓：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;俗話說，小孩子的成長不能等。&lt;/p&gt;
&lt;p&gt;同樣的，主管梯隊的成長也不能等。&lt;/p&gt;
&lt;p&gt;因為不能等，所以，我就主動起個頭吧。&lt;/p&gt;
&lt;p&gt;我將於九月開辦【&lt;strong&gt;主管的修練&lt;/strong&gt;】課程，總共七堂，每次 2 小時。課程將探討初階中階主管的六大課題：領導與管理思維、參與式決策、人才管理教育和支持、溝通與衝突化解、團隊績效的考核標準、團隊文化和核心信念。&lt;/p&gt;
&lt;p&gt;因為是我起的頭，所以，請容我任性地設下【主管的修練】課程的總規定：&lt;/p&gt;
&lt;p&gt;① 課程以&lt;strong&gt;個案研討&lt;/strong&gt;形式為主，有大量&lt;strong&gt;課堂討論&lt;/strong&gt;，學員需要依照進度先行閱讀&lt;strong&gt;指定讀物&lt;/strong&gt;。能配合的，再考慮參加。&lt;/p&gt;
&lt;p&gt;② 有些個案討論有&lt;strong&gt;隱私性&lt;/strong&gt;考量，為促成&lt;strong&gt;坦誠討論&lt;/strong&gt;，參與者需宣誓對現場討論內容&lt;strong&gt;保密&lt;/strong&gt; (咦)。&lt;/p&gt;
&lt;p&gt;如果你無法配合這些規定，請不要勉強參加，請選擇你能夠接受的其他培訓機會。&lt;/p&gt;
&lt;p&gt;為了維持課程品質，此課程人數上限為 24。&lt;/p&gt;
&lt;p&gt;如果課程反應不錯，明年還會擇期再開新梯次，所以這次向隅者不必擔心。如果課程反應不佳，就不值得再開新的梯次，所以這次向隅者也沒什麼損失。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我也將每堂課一開頭的導讀部份錄影下來，以後再舉辦時，時間就可以節省下來，直接進入互動討論環節，畢竟這才是最精華的部份——這門課有趣的地方，就是思辨：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/S90KVeg6YzA?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;有同事笑著說：跟著我的這一年，是他脫離學生身分之後，讀書最密集的時光。&lt;/p&gt;
&lt;p&gt;這也是我舉辦這些活動背後想要傳達的訊息：要多讀書，看看外面世界；離開穴居人的世界，成為現代人。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/12/feedback-mgmt-training.jpg&#34; alt=&#34;【主管的修練】部份回饋。&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/12/feedback-mgmt-training.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;【主管的修練】部份回饋。&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;內部-memo&#34;&gt;內部 Memo&lt;/h2&gt;
&lt;p&gt;忙碌的一年，除了動嘴動手的活動之外，我也寫了許多內部 memo，最高紀錄一週寫了三篇，可惜多半都不能在此刻對外公開。能公開的只有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2022/04/passphrase-at-work/&#34;&gt;請珍惜你們學到的通關密語&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2022/05/need-for-unit-testing/&#34;&gt;很簡單的東西，也要單元測試嗎？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2022/07/prj-kickoff/&#34;&gt;專案 Kick-off meeting 的前置作業&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2022/08/present-for-upper-mgmt/&#34;&gt;請掌握「對高層簡報」的技術及習慣&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2022/08/stakeholder-transparency/&#34;&gt;專案管理／專案組合管理當中，不必然需要公開透明的地方&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2022/10/on-user-stories/&#34;&gt;User Story 釋疑：真的要遵守嗎？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2022/10/agile-milestone/&#34;&gt;事情做一半，等於沒完成：淺談敏捷的里程碑設定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;以「蜘蛛法」拆分過於龐大的 User Story&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重要的事情，似乎還是免不了要 over communication，不能冀望看一次或聽一次就明白。寫下來，有助於一再端出來複習覆述。畢竟 Ray Dalio 在《&lt;a href=&#34;https://williampjyeh.notion.site/4ad6cebb5215432497d51a9165060a11&#34;&gt;原則&lt;/a&gt;》說過：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;要知道，幾乎所有「眼前情況」都只是「情景再現」。找出是哪一種「&lt;strong&gt;情景&lt;/strong&gt;」，然後應用深思熟慮的&lt;strong&gt;原則&lt;/strong&gt;加以處理，這將讓你大量減少必須決定的數量，並引領你做出更好的決定。&lt;/p&gt;
&lt;p&gt;你若是不斷以這種方式思考，就會成為一個卓越的&lt;strong&gt;有原則思考者&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我打趣說：一年來寫的內部 memo，將來搞不好可以集結出書。&lt;/p&gt;
&lt;h2 id=&#34;邀請專家進行教育訓練&#34;&gt;邀請專家進行教育訓練&lt;/h2&gt;
&lt;p&gt;改革者、先行者是孤獨的。&lt;/p&gt;
&lt;p&gt;只是一味苦口婆心勸說大家放下成見、擁抱改變、試著與世界潮流同步，會被認為只是一己的固執偏見。因此，我邀請外面世界的先進過來現身說法，讓局中人驚覺：這個書呆子說的話是真的，外面世界真的就是這樣運作的。&lt;/p&gt;
&lt;p&gt;邀請專家的專題講座計有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;遠距工作的甘苦談與訣竅 (by Ailin Liou)&lt;/li&gt;
&lt;li&gt;敏捷組織下之人才培育 (by Tess Fang)&lt;/li&gt;
&lt;li&gt;17Live SRE 從無到有心法 (by Sammy Lin)&lt;/li&gt;
&lt;li&gt;MaiCoin SRE 演進經驗分享 (by Smalltown)&lt;/li&gt;
&lt;li&gt;Titansoft 的 Craftsmanship 精進之旅 (by Eviler)&lt;/li&gt;
&lt;li&gt;那些年我們做過的 DevOps Pipeline (by 艦長)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;邀請專家的實體或線上課程計有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git 版本控管實戰：新手進階篇 (by 保哥)&lt;/li&gt;
&lt;li&gt;專案管理第一次就上手 (by Rex)&lt;/li&gt;
&lt;li&gt;如何寫出人人有共識的需求：範例描述需求篇 (by David Ko)&lt;/li&gt;
&lt;li&gt;ES6 + React (by 龍哥、奶綠茶)&lt;/li&gt;
&lt;li&gt;Team Kanban Practitioner (by 柳丁)&lt;/li&gt;
&lt;li&gt;單元測試 (by 某低調大神)&lt;/li&gt;
&lt;li&gt;GCP Onboarding Courses&lt;/li&gt;
&lt;li&gt;產品數據分析與關鍵指標設計 (by Hans)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;感謝許多業界朋友賣我面子，尤其是在疫情期間仍然排除萬難給予精彩的分享，在此獻上敬意。&lt;/p&gt;
&lt;h2 id=&#34;外面的世界&#34;&gt;外面的世界&lt;/h2&gt;
&lt;p&gt;2022 這一整年回顧起來，我好像花了極大精力在傳教佈道：用課程、導讀會、文章，甚至到了有點雞婆的地步。&lt;/p&gt;
&lt;p&gt;巧合的是，這正好與我所屬教會的 2022 年度命名相暗合：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「主的靈在我身上，因為祂用膏膏我，叫我傳福音給貧窮的人，差遣我報告被擄的得釋放，瞎眼的得看見，叫那受壓制的得自由。」 (&lt;a href=&#34;https://cnbible.com/luke/4-18.htm&#34;&gt;路 4:18&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;傳教佈道，需要傻勁。&lt;/p&gt;
&lt;p&gt;以我來說吧，每次聽到有人漠視外面世界的先進們熬煉了一、二十年才得出的進步觀念，就會想到《海賊王》裡蒙布朗・諾蘭德的這段話：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/12/montblanc-norland.jpg&#34; alt=&#34;From: One Piece, Vol. 31, Episode 289&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/12/montblanc-norland.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;From: One Piece, Vol. 31, Episode 289&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;外面的世界當然不見得是好的，不見得是匹配的，也不見得永遠是對的；不過，就如同我在某篇 memo 所說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們不是預言家，無法鐵口直斷像「&lt;strong&gt;在 VUCA 時代，feature team 優於 component team&lt;/strong&gt;」這種觀點的壽命究竟有多長，不過，如果我們的智慧，沒有&lt;a href=&#34;https://zh.m.wikipedia.org/zh-tw/%E5%9C%8B%E9%9A%9B%E5%B0%88%E6%A1%88%E7%AE%A1%E7%90%86%E5%AD%B8%E6%9C%83&#34;&gt;國際專案管理學會&lt;/a&gt; (&lt;a href=&#34;https://www.pmi.org/&#34;&gt;PMI&lt;/a&gt;) 高，沒有大型敏捷框架 &lt;a href=&#34;https://less.works/&#34;&gt;LeSS&lt;/a&gt; 高，沒有 &lt;a href=&#34;https://www.tenlong.com.tw/products/9789865020941&#34;&gt;DevOps 大師&lt;/a&gt;高，那麼，試著放下舊的成見，試著瞭解一下 feature team 的論述，試著與世界潮流同步吧——尤其在我們還沒有與世界潮流碰撞的實力與實績。&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/12/less.jpg&#34; alt=&#34;Scrum 培訓：全局觀 (2022-11-17)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/12/less.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Scrum 培訓：全局觀 (2022-11-17)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;早一點與世界接軌，早一點主動與世界接軌，總比被迫與世界接軌來得從容——我們非要等到&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E9%BB%91%E8%88%B9%E4%BE%86%E8%88%AA&#34;&gt;黑船來航&lt;/a&gt;才痛定思痛進行&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E6%98%8E%E6%B2%BB%E7%BB%B4%E6%96%B0&#34;&gt;明治維新&lt;/a&gt;嗎？&lt;/p&gt;
&lt;h2 id=&#34;未央歌&#34;&gt;未央歌&lt;/h2&gt;
&lt;p&gt;記得年初自己 OGSM 的 O 是這麽寫的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;建設 Focus, Flow, Joy 的研發環境，以支持企業目標。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;計劃趕不上變化。只能把缺憾還諸天地。&lt;/p&gt;
&lt;h2 id=&#34;2023-許願&#34;&gt;2023 許願&lt;/h2&gt;
&lt;p&gt;2023 年，希望自己能做到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;del&gt;每個月辦一場 2hr 導讀會&lt;/del&gt; 換個形式，進行專題式的系列講座。&lt;/li&gt;
&lt;li&gt;繼續更深度的本質修練。&lt;/li&gt;
&lt;li&gt;繼續增進商務英語聽說能力。&lt;/li&gt;
&lt;li&gt;開放冒險選項。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就醬。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:10em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/12/poster-scrum-girls.jpg&#34; alt=&#34;Poster - Agile Girls&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/12/poster-scrum-girls.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Poster - Agile Girls&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>職涯躍升書系導讀會，Part 3：職場心理：觀點、期待、渴望</title>
      <link>//william-yeh.net/post/2022/11/career-reading-club-3/</link>
      <pubDate>Tue, 29 Nov 2022 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/11/career-reading-club-3/</guid>
      
        <description>&lt;p&gt;2022 年一月起，我開始每個月一次，每次兩小時的【職涯躍升書系導讀會】。&lt;a href=&#34;//william-yeh.net/post/2022/06/career-reading-club-1/&#34;&gt;前六個月&lt;/a&gt;著眼於喚醒個人及團隊的成長意識，接下來&lt;a href=&#34;//william-yeh.net/post/2022/08/career-reading-club-2/&#34;&gt;兩個月&lt;/a&gt;著眼於高效團隊的工作方法，最近三個月則著眼於心理層面，尤其是觀點、期待、渴望。&lt;/p&gt;
&lt;p&gt;這三個月的選書如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;① &lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;薩提爾教練模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;② &lt;a href=&#34;https://williampjyeh.notion.site/b299b20f381643c9b7b0caaba1d12f44&#34;&gt;為什麼上班這麼累？其實是你心累&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;③ 兩本與 Accountability 有關的書：&lt;a href=&#34;https://williampjyeh.notion.site/QBQ-30-89b7f2e8006e41afa8953f238ff26441&#34;&gt;QBQ&lt;/a&gt; ＆ &lt;a href=&#34;https://williampjyeh.notion.site/99f7c1cb5ef84873bf294916a03715a0&#34;&gt;當責&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/11/career-reading-club-3.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/11/career-reading-club-3.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;以下列出這三場導讀會的介紹文案。&lt;/p&gt;
&lt;h2 id=&#34;薩提爾教練模式&#34;&gt;薩提爾教練模式&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;回顧過去，我認為，對我個人職涯影響最大的書籍有三，其一是形塑我職涯升級打怪路線圖的書《&lt;a href=&#34;https://williampjyeh.notion.site/cd42e217271d454aac9411b0c6fc84c7&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;》（已於 2022/02 導讀會探討過），其二是我的管理啟蒙書《&lt;a href=&#34;https://www.books.com.tw/products/0010938955&#34;&gt;目標&lt;/a&gt;》，其三則是這次要介紹的書《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;薩提爾教練模式&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;薩提爾教練模式&lt;/a&gt;》影響我的地方有三。&lt;/p&gt;
&lt;p&gt;① &lt;strong&gt;心理學&lt;/strong&gt;。職場是由「人」構成的，對「人」瞭解愈透徹，愈能在職場這樣的賽局中游刃有餘或趨吉避凶。&lt;/p&gt;
&lt;p&gt;這本書早在 2015 年就很有創意地（可能也是全球首創）將家族治療領域赫赫有名的&lt;strong&gt;薩提爾&lt;/strong&gt; (&lt;strong&gt;Satir&lt;/strong&gt;) 方法轉化運用到職場領域，是既前衛又前瞻的混搭。被這本書啟蒙之後，促使我 2017 年親自去上了整整九天的&lt;a href=&#34;//william-yeh.net/post/2017/04/satir-workshop/&#34;&gt;薩提爾方法培訓&lt;/a&gt;，在許多層面徹底改變了我。&lt;/p&gt;
&lt;p&gt;談職場心理的書很多，但從薩提爾如此深層的角度切入，此書可說是濫觴。之後，陸陸續續在許皓宜、周慕姿、錢慧如、汪士瑋等人的職場書籍或課程中，就開始看到這種混搭的例子。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;② &lt;strong&gt;引導&lt;/strong&gt;。團隊是由「人」緊密構成的，對於協作需求愈高的團隊（尤其是 Scrum），愈需要對於&lt;strong&gt;團體動力&lt;/strong&gt;的深刻瞭解，才能夠在適當的時機、以適當的力度去引導團隊。&lt;/p&gt;
&lt;p&gt;透過這本書提到的薩提爾模式，有助於辨識團體動力，辨識可用來引導團隊的施力點：感受、觀點、期待、渴望——這些都是 Scrum retrospective meeting 的私房法寶。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;③ &lt;strong&gt;教練&lt;/strong&gt;。如同我在〈&lt;a href=&#34;//william-yeh.net/post/2021/12/2021-retrospective/&#34;&gt;2021 個人回顧&lt;/a&gt;〉一文的感慨：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「有人教導基本動作嗎？」&lt;/p&gt;
&lt;p&gt;「每個人都各打各的，完全不團結。」&lt;/p&gt;
&lt;p&gt;「球隊的教練到底在搞什麼？」&lt;/p&gt;
&lt;p&gt;其實，中高階主管也極需要 coaching。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;薩提爾教練模式&lt;/a&gt;》這本書，就是極佳的教練指引。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;如果你也認為，在職場上，有需要在&lt;strong&gt;心理學&lt;/strong&gt;、&lt;strong&gt;引導&lt;/strong&gt;、&lt;strong&gt;教練&lt;/strong&gt;這三方面精進，邀請你好好讀讀《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;薩提爾教練模式&lt;/a&gt;》這本書。&lt;/p&gt;
&lt;h2 id=&#34;為什麼上班這麼累其實是你心累&#34;&gt;為什麼上班這麼累？其實是你心累&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;繼九月份導讀會選書《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;薩提爾教練模式&lt;/a&gt;》之後，我決定十月份再度選擇一本職場心理學的書與大家分享：許皓宜的《&lt;a href=&#34;https://williampjyeh.notion.site/b299b20f381643c9b7b0caaba1d12f44&#34;&gt;為什麼上班這麼累？其實是你心累&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;為什麼連續兩次都要與心理學有關呢？因為在過去數個月以來，旁觀同仁之間的大小內外碰撞，普遍出現一個阿德勒式的感慨：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;所有煩惱，都是人際關係的煩惱。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;此外，在八月及九月《&lt;a href=&#34;https://www.playpcesor.com/2020/05/2020-new-book.html&#34;&gt;時間管理的 30 道難題&lt;/a&gt;》及《&lt;a href=&#34;https://williampjyeh.notion.site/2db1e5a9b9d84b9aa4be8250bb6717b2&#34;&gt;領導的黃金法則&lt;/a&gt;》這兩本書的討論現場，也都出現一個普遍的靈魂叩問：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我不知道我真正要的是什麼。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這些靈魂叩問，恐怕不是訴諸催眠式的激勵，或心靈雞湯式的轉念，就能夠得到解答。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;面對這些問題，許皓宜老師在《&lt;a href=&#34;https://williampjyeh.notion.site/b299b20f381643c9b7b0caaba1d12f44&#34;&gt;為什麼上班這麼累？其實是你心累&lt;/a&gt;》書中的分析是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;為何工作這麼累？其實不是工作本身的問題，而是我們的心「&lt;strong&gt;迷路&lt;/strong&gt;」了的問題。換句話說，那種「疲累」的感覺，與其說是「工作」帶給我們的，不如說是「心態」（心的狀態）影響我們的。&lt;/p&gt;
&lt;p&gt;請容我用此刻對心理學的理解來描述「累」的意義：它是一種心靈的呼喚，告訴我們得要停下腳步（不是停下工作），去看看自己&lt;strong&gt;內在空間&lt;/strong&gt;受到什麼擠壓。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這本書，用十一個角度，帶讀者重新回到自己的內心，自己的工作初心，甚至面對自己的內在小孩，與他對話。&lt;/p&gt;
&lt;p&gt;這本書，有大約三十幾則故事，很好讀。也請你在閱讀之前，試著打開塵封已久的真心去讀，讓薩提爾、榮格、阿德勒、佛洛伊德，幫你重塑心理資本 (psychological capital)。&lt;/p&gt;
&lt;p&gt;你有多久沒有找個靜謐的所在，打開塵封已久的真心呢？&lt;/p&gt;
&lt;p&gt;試試看吧。&lt;/p&gt;
&lt;h2 id=&#34;兩本與-accountability-有關的書&#34;&gt;兩本與 Accountability 有關的書&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;自從去年十一月來到這裡，我常常必須提醒自己，要用另外一種方法對自己說話。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;面對工程議題，我不能一直抱怨說：「都什麼年代了，這裡的人怎麼如此亂用 Git 呀？」&lt;/p&gt;
&lt;p&gt;我必須停下來，試著對自己發問：「是的，現況糟透了。&lt;strong&gt;我還能做些什麼，以取得我想要的成果？&lt;/strong&gt;」&lt;/p&gt;
&lt;p&gt;面對這問句，我開始發想：「最佳做法，是請專家來上課。」&lt;/p&gt;
&lt;p&gt;不過，疫情期間，怎麼請專家來上課？&lt;/p&gt;
&lt;p&gt;面對這問題，我不能一直抱怨說：「因為疫情攪局，沒辦法找專家來教大家 Git，因此，以 Git 為樞紐的 DevOps 起手式，乃至於後續種種的 CI/CD 大構想，也只能延到疫情降溫之後再說了。」&lt;/p&gt;
&lt;p&gt;我必須停下來，試著再一次對自己發問：「是的，現況糟透了。&lt;strong&gt;我還能做些什麼，以取得我想要的成果？&lt;/strong&gt;」&lt;/p&gt;
&lt;p&gt;面對這問句，我開始發想：「是否可以請專家進行線上教學？就算效果可能不如實體課程，但總是往前推進了一步，勝於原地踏步。」&lt;/p&gt;
&lt;p&gt;於是，我與保哥通話，也才有之後三個梯次的 Git 線上教學，在 2022 年三月，終於讓 Git 變成整個技術部同仁的共同工程語言。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;面對專案管理議題，我不能一直抱怨說：「都什麼年代了，這裡的人怎麼如此亂用 WBS 呀？怎麼都不好好分析利害關係人呀？怎麼都不談談風險呀？怎麼都只會報流水帳，一點都不會專業地做進度追蹤與回報呀？」&lt;/p&gt;
&lt;p&gt;我必須停下來，試著對自己發問：「是的，現況糟透了。那麼，&lt;strong&gt;我現在還能夠做些什麼？&lt;/strong&gt;」&lt;/p&gt;
&lt;p&gt;面對這問句，我開始發想：「最佳做法，是請專家來上課。」&lt;/p&gt;
&lt;p&gt;不過，疫情期間，怎麼請專家來上課？&lt;/p&gt;
&lt;p&gt;面對這問題，我不能一直抱怨說：「因為疫情攪局，沒辦法找專家來教大家正確的專案管理入門觀念，因此，以 WBS 為樞紐的專案管理起手式，乃至於後續種種的敏捷大構想，也只能延到疫情降溫之後再說了。」&lt;/p&gt;
&lt;p&gt;我必須停下來，試著再一次對自己發問：「是的，現況糟透了。那麼，&lt;strong&gt;我現在還能夠做些什麼？&lt;/strong&gt;」&lt;/p&gt;
&lt;p&gt;面對這問句，我開始發想：「是否可以請專家進行線上教學？就算效果可能不如實體課程，但總是往前推進了一步，勝於原地踏步。」&lt;/p&gt;
&lt;p&gt;於是，我與大人學聯繫，在線上進行課程對焦討論，也才有之後兩個梯次的【專案管理第一次就上手】線上教學，在 2022 年四月，終於讓「專案管理問題清單」變成整個技術部資深同仁的共同語言。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上第一組問句，出自《&lt;a href=&#34;https://williampjyeh.notion.site/99f7c1cb5ef84873bf294916a03715a0&#34;&gt;當責，從停止抱怨開始&lt;/a&gt;》，第二組問句，出自《&lt;a href=&#34;https://williampjyeh.notion.site/QBQ-30-89b7f2e8006e41afa8953f238ff26441&#34;&gt;QBQ！問題背後的問題&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/99f7c1cb5ef84873bf294916a03715a0&#34;&gt;當責，從停止抱怨開始&lt;/a&gt;》說，不要一直停在水平線下 (below the line) 的被害者循環 (victim cycle)。《&lt;a href=&#34;https://williampjyeh.notion.site/QBQ-30-89b7f2e8006e41afa8953f238ff26441&#34;&gt;QBQ！問題背後的問題&lt;/a&gt;》說，每個人都有自由做出更好的決定，並且為自己的決定負責，不要一直抱持受害者心態 (victim thinking)。&lt;/p&gt;
&lt;p&gt;這兩本書介紹的一些 &lt;strong&gt;power questions&lt;/strong&gt;，可以替薩提爾冰山模型當中「&lt;strong&gt;觀點&lt;/strong&gt;」與「&lt;strong&gt;期待&lt;/strong&gt;」環節擴增更多的探索選項，也是很好用的教練對話觸媒。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/99f7c1cb5ef84873bf294916a03715a0&#34;&gt;當責，從停止抱怨開始&lt;/a&gt;》這本書對應的訓練課程 &lt;a href=&#34;https://doortraining.com/virtual-solutions/accountability-builder/&#34;&gt;Accountability Builder&lt;/a&gt;，是我待過的某一家公司「主管兩年培訓計畫」的必修課程；《&lt;a href=&#34;https://williampjyeh.notion.site/QBQ-30-89b7f2e8006e41afa8953f238ff26441&#34;&gt;QBQ！問題背後的問題&lt;/a&gt;》則是我待過的另一家公司新人訓練的必備讀物。&lt;/p&gt;
&lt;p&gt;我不能一直抱怨說：「都什麼節骨眼了，這裡的人怎麼這麼沒有 accountability 心態呀？也沒有對應的培訓課程？」&lt;/p&gt;
&lt;p&gt;我必須停下來，試著對自己發問：「是的，現況糟透了。那麼，&lt;strong&gt;我現在還能夠做些什麼？&lt;/strong&gt;」&lt;/p&gt;
&lt;p&gt;於是，就有了這一場導讀會，一次兩本。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;希望大家藉由這兩本書，辨識自己何時落在水平線下，走出受害者循環，走上當責步驟 SOSD：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;See It 正視現實&lt;/li&gt;
&lt;li&gt;Own It 承擔責任&lt;/li&gt;
&lt;li&gt;Solve It 解決問題&lt;/li&gt;
&lt;li&gt;Do It 著手完成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;願這當責步驟成為我們大家的共同語言。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【職涯躍升書系導讀會】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ Part 1: &lt;a href=&#34;//william-yeh.net/post/2022/06/career-reading-club-1/&#34;&gt;喚醒個人及團隊的成長意識&lt;/a&gt; (計 6 冊)&lt;/p&gt;
&lt;p&gt;❷ Part 2: &lt;a href=&#34;//william-yeh.net/post/2022/08/career-reading-club-2/&#34;&gt;高效團隊的工作方法&lt;/a&gt; (計 2 冊)&lt;/p&gt;
&lt;p&gt;❸ Part 3: 職場心理：觀點、期待、渴望 (計 3 冊)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>職涯躍升書系導讀會</title>
      <link>//william-yeh.net/series/career-reading-club/</link>
      <pubDate>Tue, 29 Nov 2022 00:00:00 +0000</pubDate>
      
      <guid>//william-yeh.net/series/career-reading-club/</guid>
      
        <description>&lt;p&gt;❶ Part 1: &lt;a href=&#34;//william-yeh.net/post/2022/06/career-reading-club-1/&#34;&gt;喚醒個人及團隊的成長意識&lt;/a&gt; (計 6 冊)&lt;/p&gt;
&lt;p&gt;❷ Part 2: &lt;a href=&#34;//william-yeh.net/post/2022/08/career-reading-club-2/&#34;&gt;高效團隊的工作方法&lt;/a&gt; (計 2 冊)&lt;/p&gt;
&lt;p&gt;❸ Part 3: &lt;a href=&#34;//william-yeh.net/post/2022/11/career-reading-club-3/&#34;&gt;職場心理：觀點、期待、渴望&lt;/a&gt; (計 3 冊)&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>以「蜘蛛法」拆分過於龐大的 User Story</title>
      <link>//william-yeh.net/post/2022/11/spidr/</link>
      <pubDate>Tue, 01 Nov 2022 17:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/11/spidr/</guid>
      
        <description>&lt;p&gt;（改寫自公司內部 memo）&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Hi all guys,&lt;/p&gt;
&lt;p&gt;剛從傳統瀑布式專案管理風格轉換到敏捷風格的團隊，最常遇到第二個卡關之處是：如何將 User Story 拆分到足以在一個 sprint 內完成的顆粒度？&lt;/p&gt;
&lt;p&gt;如果玩過我帶的「在幾分鐘以內出門」(&amp;ldquo;get out of the door in a few minutes&amp;rdquo;) 活動 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，或許可藉由喚起這段活動的體驗來得到拆分大故事的靈感。如果還想進一步知道更具體的步驟，我推薦大家試試 Mike Cohn 大師提出的 &lt;a href=&#34;https://www.mountaingoatsoftware.com/exclusive/spidr-poster-download&#34;&gt;SPIDR 法&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;SPIDR 是 Spikes, Paths, Interfaces, Data, Rules 的頭字語，音近 &amp;ldquo;spider&amp;rdquo; 蜘蛛，可以戲稱為「蜘蛛法」。它指導我們從五個角度嘗試拆分過於龐大的 User Story：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Spikes&lt;/strong&gt;: 拆分出探索性、實驗性的先遣任務。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Paths&lt;/strong&gt;: 拆分出不同的使用路徑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interfaces&lt;/strong&gt;: 拆分出不同的介面、軟體、設備、環境。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data&lt;/strong&gt;: 拆分出不同的資料來源或類型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rules&lt;/strong&gt;: 拆分出不同鬆緊程度的商業邏輯。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;就以這個龐大的 User Story 為例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As a 商家，I want to 在既有的商家後台，以不同的商品分類或時間區間來檢視我家商品的種種銷售數據圖表，so that I can 對銷售行為作更即時的調整。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這麼大的 User Story，很難放在一個 sprint 裡面實現。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我們可以試著用 SPIDR 當中的 &amp;ldquo;Spikes&amp;rdquo; 角度來拆分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As a 商家，I want to 在既有的商家後台，先針對&lt;strong&gt;人工餵入的 1,000 筆假資料&lt;/strong&gt;，試試看能否&lt;strong&gt;把整個流程串起來&lt;/strong&gt;，以不同的商品分類或時間區間來檢視我家商品的種種銷售數據圖表，so that I can 確定這對我想從事的「對銷售行為作更即時的調整」會有幫助。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我們可以試著用 SPIDR 當中的 &amp;ldquo;Paths&amp;rdquo; 角度來拆分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As a 商家，I want to 在既有的商家後台，以不同的&lt;strong&gt;商品分類&lt;/strong&gt;來檢視我家商品的種種銷售數據圖表，so that I can 對銷售行為作更即時的調整。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As a 商家，I want to 在既有的商家後台，以不同的&lt;strong&gt;時間區間&lt;/strong&gt;來檢視我家商品的種種銷售數據圖表，so that I can 對銷售行為作更即時的調整。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我們可以試著用 SPIDR 當中的 &amp;ldquo;Interfaces&amp;rdquo; 角度來拆分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As a 商家，I want to 在&lt;strong&gt;試算表檔案&lt;/strong&gt;中，以不同的商品分類或時間區間來檢視我家商品的種種銷售數據圖表，so that I can 對銷售行為作更即時的調整。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我們可以試著用 SPIDR 當中的 &amp;ldquo;Data&amp;rdquo; 角度來拆分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As a 商家，I want to 在既有的商家後台，針對 &lt;strong&gt;3C 商品&lt;/strong&gt;來檢視&lt;strong&gt;銷售直方圖&lt;/strong&gt;，so that I can 對銷售行為作更即時的調整。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As a 商家，I want to 在既有的商家後台，針對 &lt;strong&gt;3C 商品&lt;/strong&gt;來檢視&lt;strong&gt;訪客 PV&lt;/strong&gt;，so that I can 對銷售行為作更即時的調整。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As a 商家，I want to 在既有的商家後台，針對&lt;strong&gt;日用品&lt;/strong&gt;來檢視&lt;strong&gt;成交率&lt;/strong&gt;，so that I can 對銷售行為作更即時的調整。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我們可以試著用 SPIDR 當中的 &amp;ldquo;Rules&amp;rdquo; 角度來拆分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;As a 商家，I want to 在既有的商家後台，以&lt;strong&gt;日&lt;/strong&gt;為單位來檢視我家商品的種種銷售數據圖表，so that I can 對銷售行為作更即時的調整。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As a 商家，I want to 在既有的商家後台，以&lt;strong&gt;周&lt;/strong&gt;為單位來檢視我家商品的種種銷售數據圖表，so that I can 對銷售行為作更即時的調整。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;As a 商家，I want to 在既有的商家後台，以「商品分類」及「時間區間」&lt;strong&gt;複合條件&lt;/strong&gt;來檢視我家商品的種種銷售數據圖表，so that I can 對銷售行為作更即時的調整。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;透過 SPIDR 蜘蛛法，我們一下子就得到這麼多拆分大故事的切入點。前後對照一下，是不是覺得這些細分的 User Stories 變得更具體更有把握了呢？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以我的經驗來說，把 SPIDR 法練熟，足以應付大多數情況。如果你還想嘗試更多方法，請讀讀我 &lt;em&gt;N&lt;/em&gt; 年前寫的〈&lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;〉一文。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【敏捷的工作分解方法】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2016/10/one-week-sprint/&#34;&gt;One-Week Sprint 的節奏&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/10/agile-milestone/&#34;&gt;事情做一半，等於沒完成：淺談敏捷的里程碑設定&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ 以「蜘蛛法」拆分過於龐大的 User Story&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/08/story-to-tasks/&#34;&gt;很簡單的 Story，也要拆分出 Tasks 嗎？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/11/why-decomposition-matters/&#34;&gt;變動的時代，為什麼工作分解技能更是必備？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;「在幾分鐘以內出門」(&amp;ldquo;get out of the door in a few minutes&amp;rdquo;) 是出自 &lt;em&gt;&lt;a href=&#34;https://williampjyeh.notion.site/2eeb7794966b440c8856cc6fe8927658&#34;&gt;User Story Mapping&lt;/a&gt;&lt;/em&gt; 第五章的經典活動。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>事情做一半，等於沒完成：淺談敏捷的里程碑設定</title>
      <link>//william-yeh.net/post/2022/10/agile-milestone/</link>
      <pubDate>Mon, 31 Oct 2022 17:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/10/agile-milestone/</guid>
      
        <description>&lt;p&gt;（改寫自公司內部 memo）&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Hi all guys,&lt;/p&gt;
&lt;p&gt;剛從傳統瀑布式專案管理風格轉換到敏捷風格的團隊，最常遇到第一個卡關之處是：如何以敏捷的角度設定里程碑？&lt;/p&gt;
&lt;p&gt;最近在協助兩個 Scrum teams 進行 Sprint Planning 時，我都會用以下角度提出挑戰性提問：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能否將 User Stories &lt;strong&gt;拆分&lt;/strong&gt;到：可以在一個 sprint 結束時，端出&lt;strong&gt;利害關係人&lt;/strong&gt;可以據以給出&lt;strong&gt;建設性回饋&lt;/strong&gt;的 &lt;strong&gt;end-to-end 成果&lt;/strong&gt;？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這需要創意，需要練習，需要提升規劃能力，需要提升工程能力，需要時時用挑戰性提問提醒自己。但或許更重要的是：大家需要打從心裡認清且認同這樣做的理由。&lt;/p&gt;
&lt;p&gt;理由之一是：精實生產。&lt;/p&gt;
&lt;h2 id=&#34;七大浪費&#34;&gt;七大浪費&lt;/h2&gt;
&lt;p&gt;7/22 舉辦過的&lt;a href=&#34;//william-yeh.net/post/2022/08/career-reading-club-2/#豐田精實管理的翻轉獲利秘密&#34;&gt;《豐田精實管理的翻轉獲利秘密》導讀會&lt;/a&gt;有介紹過，馳名世界的豐田生產 (Toyota Production System) 當中有一個基本信念：「&lt;strong&gt;降低浪費，就能提升效率。&lt;/strong&gt;」另一本書《&lt;a href=&#34;https://williampjyeh.notion.site/fc98b324a0c7482f82d3a639f8b10282&#34;&gt;豐田物語&lt;/a&gt;》也如是說：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/10/muda.jpg&#34; alt=&#34;From: 《豐田物語》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/10/muda.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;From: 《豐田物語》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;豐田生產會從降低七大浪費著手：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inventory&lt;/strong&gt;：庫存、在製品。以軟體研發而言，規格書、wireframe、schema、test case⋯⋯任何無法真正迅速 go to production 轉換成實質價值的中間產物，都是 inventory。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Waiting&lt;/strong&gt;：等待。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Defects&lt;/strong&gt;：不良品。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Over-production&lt;/strong&gt;：過量生產。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Motion&lt;/strong&gt;：動作。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transportation&lt;/strong&gt;：搬運。以軟體研發而言，「人的 transportation」就是換手、接棒、工作交接，「物的 transportation」就是工單傳遞、簽呈傳遞、規格書傳遞、契約書傳遞。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Over-processing&lt;/strong&gt;：過度加工。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這七大浪費當中，有幾點可以直接對應到敏捷的里程碑設定心法，值得我們時時拿來作為挑戰性提問，時時自我提醒：我們在 Sprint Planning 所規劃的里程碑、進程、作法，是否一不小心就會出現以下幾種浪費？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inventory&lt;/strong&gt;：在 Sprint Review 當場可以端得出來的成果，真的都是可以 on production 的東西嗎？抑或只是一個又一個的在製品，徒然製造一堆 inventory？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Waiting&lt;/strong&gt;：在 Sprint Backlog Items 的每一個細分的 tasks，彼此之間是否有無謂的 waiting 或 dependency？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Transportation&lt;/strong&gt;：在 Sprint Backlog Items 的每一個細分的 tasks，彼此之間是否有無謂的「人」與「物」（在製品）的 transportation？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;若出現無法立即轉換成實質價值的浪費，就該針對這些 User Stories 再予以拆分，或是對執行方式再予以重組——這是我們該發揮創意、練習、提升規劃能力、提升工程能力的地方。&lt;/p&gt;
&lt;p&gt;「降低浪費，就能提升效率。」&lt;/p&gt;
&lt;h2 id=&#34;已完成&#34;&gt;「已完成」&lt;/h2&gt;
&lt;p&gt;最後，我再摘錄 Scrum 之父 Jeff Sutherland 在《&lt;a href=&#34;https://williampjyeh.notion.site/Scrum-0e354b6be58b4977bdd1c99993e79d57&#34;&gt;Scrum：用一半的時間做兩倍的事&lt;/a&gt;》第五章〈浪費是一種罪〉的相關內容作為補充。關鍵句在此：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在每一輪或是每段衝刺，團隊都要努力完成幾件事，但是「&lt;strong&gt;已完成&lt;/strong&gt;」意謂著&lt;strong&gt;能提供給客戶使用的完整功能&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果你有大批有價值的資源綁在沒有&lt;strong&gt;傳遞出價值&lt;/strong&gt;的東西上，這些資源就無法用來做其他的事。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在 Sprint Planning 或是在設定專案里程碑時，請時時記得上面的提醒。&lt;/p&gt;
&lt;p&gt;當大家致力於「降低浪費」的自我要求，同時也就等於開始實踐 &lt;a href=&#34;https://agilemanifesto.org/principles.html&#34;&gt;Agile Manifesto 背後的十二原則&lt;/a&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;原則一：Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;原則三：Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;原則七：Working software is the primary measure of progress.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;原則八：Agile processes promote sustainable development. The sponsors, developers, and users should be able to maintain a constant pace indefinitely.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;原則十：Simplicity&amp;ndash;the art of maximizing the amount of work not done&amp;ndash;is essential.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大家加油！&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【敏捷的工作分解方法】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2016/10/one-week-sprint/&#34;&gt;One-Week Sprint 的節奏&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ 事情做一半，等於沒完成：淺談敏捷的里程碑設定&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;以「蜘蛛法」拆分過於龐大的 User Story&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/08/story-to-tasks/&#34;&gt;很簡單的 Story，也要拆分出 Tasks 嗎？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/11/why-decomposition-matters/&#34;&gt;變動的時代，為什麼工作分解技能更是必備？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>User Story 釋疑：真的要遵守嗎？</title>
      <link>//william-yeh.net/post/2022/10/on-user-stories/</link>
      <pubDate>Sat, 08 Oct 2022 10:30:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/10/on-user-stories/</guid>
      
        <description>&lt;p&gt;（改寫自公司內部 memo）&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Hi all guys,&lt;/p&gt;
&lt;p&gt;最近我會對有意導入 Scrum 的任務小組個別進行一整天的 Agile Workshop。這些小組都有一項課前作業：請先準備團隊在三個月以內會進行的 User Stories 清單／陳述。&lt;/p&gt;
&lt;p&gt;眾所周知，user story 有一個經典句型：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;As a&lt;/strong&gt; {XXX user persona}, &lt;strong&gt;I want to&lt;/strong&gt; {do YYY} &lt;strong&gt;so that&lt;/strong&gt; {ZZZ result or benefit}.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;有同仁問道：有些 user story 不容易以「&amp;ldquo;user&amp;rdquo; 視角」來寫。怎麼辦？真的要這麼嚴格遵守 user story 格式嗎？&lt;/p&gt;
&lt;p&gt;譬如說，以下兩個 autocomplete 任務，要怎麼轉寫成 user story？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Autocomplete 要能承受 100 rps。&lt;/li&gt;
&lt;li&gt;Autocomplete 要優先置入廣告關鍵字。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我的建議是：如果能夠，就盡量努力嘗試；如果不能勉強，就不要勉強。&lt;/p&gt;
&lt;p&gt;我先從後者講起。&lt;/p&gt;
&lt;h2 id=&#34;如果不能勉強就不要勉強&#34;&gt;如果不能勉強，就不要勉強&lt;/h2&gt;
&lt;p&gt;Story 有很多種，&amp;ldquo;user story&amp;rdquo; 只是其中一種。就連大師 Mike Cohn 在 &lt;a href=&#34;https://www.tenlong.com.tw/products/9789864347995&#34;&gt;&lt;em&gt;User Stories Applied&lt;/em&gt;&lt;/a&gt; 也承認：「產品 backlog 中，有面向客戶的任務，也有技術類的任務。」&lt;/p&gt;
&lt;p&gt;事實上，整篇 &lt;a href=&#34;https://scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 文件都沒有提及 &amp;ldquo;user story&amp;rdquo; 一詞，甚至連 &amp;ldquo;story&amp;rdquo; 一詞都沒有。所以 Scrum.org 有一篇文章 &amp;ldquo;&lt;a href=&#34;https://www.scrum.org/resources/blog/myth-4-scrum-product-backlog-has-consist-out-user-stories&#34;&gt;Myth 4: In Scrum, the Product Backlog has to consist out of User Stories&lt;/a&gt;&amp;rdquo; 主張在 backlog 中放入 technical tasks 是完全正常的，大師 Roman Pichler 在 &amp;ldquo;&lt;a href=&#34;https://www.romanpichler.com/blog/10-tips-writing-good-user-stories/&#34;&gt;10 Tips for Writing Good User Stories&lt;/a&gt;&amp;rdquo; 一文也說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;User stories are not good for capturing technical requirements. If you need to describe what an architectural element like a component or service should do, then write &lt;strong&gt;technical stories&lt;/strong&gt; or—which is my preference—use a modeling language like UML.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;簡言之，如果將它轉寫成 user 視角的 story 真的有困難，那麼，不一定非得死守著 &amp;ldquo;user story&amp;rdquo; 這種視角。&lt;/p&gt;
&lt;h2 id=&#34;如果能夠就盡量努力嘗試&#34;&gt;如果能夠，就盡量努力嘗試&lt;/h2&gt;
&lt;p&gt;不過，如果你堅持用 &amp;ldquo;user&amp;rdquo; 視角來寫 user story，會有更大的收穫。&lt;/p&gt;
&lt;p&gt;這是有根據的。&lt;/p&gt;
&lt;p&gt;從企業管理觀點來看，彼得．杜拉克在 &lt;a href=&#34;https://williampjyeh.notion.site/cab89225cde14229a7d1000fdea58475&#34;&gt;&lt;em&gt;The Practice of Management&lt;/em&gt;&lt;/a&gt; 開宗明義提到：「關於企業的目的，只有一個正確而有效的定義：『&lt;strong&gt;創造顧客&lt;/strong&gt;』(&lt;strong&gt;create&lt;/strong&gt; and &lt;strong&gt;keep&lt;/strong&gt; a customer)。企業是什麼，是由顧客來決定的。」&lt;/p&gt;
&lt;p&gt;從敏捷觀點來看，&lt;a href=&#34;https://williampjyeh.notion.site/2eeb7794966b440c8856cc6fe8927658&#34;&gt;&lt;em&gt;User Story Mapping&lt;/em&gt;&lt;/a&gt; 提到：「我們要量測的是你建造的東西對人們達成目標的方式產生什麼&lt;strong&gt;影響&lt;/strong&gt;。先針對具體的商業目標、客戶和使用者，然後是他們的目標排定優先順序，最後才針對功能。你的任務不是實現需求，而是改變世界。」&lt;/p&gt;
&lt;p&gt;綜上所述，如果你能夠盡量以 &amp;ldquo;user&amp;rdquo; 視角來審視這些 story 對於他們達成目標的方式產生什麼影響，相較於僅以單一視角（獲利？利潤？）魯莽地提出需求、設計功能，你會有更周全的思考、更多樣的替代選項。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/10/create-and-keep-customers.jpg&#34; alt=&#34;From: The Practice of Management&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/10/create-and-keep-customers.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;From: The Practice of Management&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;上週有上過 Hans【產品數據分析與關鍵指標設計】課程的同仁，不妨回想一下老師提醒的「從&lt;strong&gt;商業&lt;/strong&gt;與&lt;strong&gt;用戶&lt;/strong&gt;的角度去做解讀」心法。沒上過的，請在我的 Agile Workshop 玩一場 Impact Mapping 變形版，就會知道了。&lt;/p&gt;
&lt;p&gt;有了這種觀念，再讀大師 Mike Cohn 在 &lt;a href=&#34;https://www.tenlong.com.tw/products/9789864347995&#34;&gt;&lt;em&gt;User Stories Applied&lt;/em&gt;&lt;/a&gt; 所主張的「&lt;strong&gt;切蛋糕&lt;/strong&gt;」口訣，就順理成章了：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;優秀用戶故事準則：每個故事都提供某種程度的完整 end-to-end 功能，稱之為「&lt;strong&gt;切蛋糕&lt;/strong&gt;」(slicing the cake)。儘管不十分完美，即使只提供部分功能，但只要發布的功能可以跑，就可以放心地把應用程式發布給用戶使用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;該怎麼改寫&#34;&gt;該怎麼改寫？&lt;/h2&gt;
&lt;p&gt;理論說完了，回到現實：一開頭列的兩個 autocomplete 任務，要怎麼轉寫成 user story？&lt;/p&gt;
&lt;p&gt;⓵ Autocomplete 要能承受 100 rps。&lt;/p&gt;
&lt;p&gt;先以工程角度來評估這項 non-functional requirement (NFR)。如果並不難實現，那麼，就不必特別為它另寫一張獨立的 story，直接將它填寫到正常 story 裡面的「驗收條件」一欄即可。&lt;/p&gt;
&lt;p&gt;如果仍待進一步評估，那就用一張 &amp;ldquo;&lt;strong&gt;As a&lt;/strong&gt; service owner, &lt;strong&gt;I want to&lt;/strong&gt; make sure that&amp;hellip;&amp;rdquo; 這種風格的 user story 去陳述，或者乾脆撇開形式，直接用 technical story 去陳述這項純工程純技術的任務即可，不必役於物。&lt;/p&gt;
&lt;p&gt;⓶ Autocomplete 要優先置入廣告關鍵字。&lt;/p&gt;
&lt;p&gt;我們可以試著用一些 power questions 來輔助思考。&lt;/p&gt;
&lt;p&gt;譬如說，將彼得．杜拉克的名言「企業是什麼，是由顧客來決定的」改編一下，請試著回答：「&lt;strong&gt;在顧客眼中，這功能是什麼？&lt;/strong&gt;」&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;As a&lt;/strong&gt; search service user, &lt;strong&gt;I want to&lt;/strong&gt; see keyword suggestions prioritized by advertising spending when I use the autocomplete feature &lt;strong&gt;so that&lt;/strong&gt; I can&amp;hellip; &lt;em&gt;{achieve what?}&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;萬一寫到這裡就寫不下去了，那麼，此刻，或許該暫停一下，用 &lt;a href=&#34;https://williampjyeh.notion.site/2eeb7794966b440c8856cc6fe8927658&#34;&gt;&lt;em&gt;User Story Mapping&lt;/em&gt;&lt;/a&gt; 的名言思考一下：「&lt;strong&gt;你建造的東西，對人們達成目標的方式產生什麼影響？&lt;/strong&gt;」&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;As a&lt;/strong&gt; search service user, &lt;strong&gt;I want to&lt;/strong&gt; see keyword suggestions prioritized by advertising spending when I use the autocomplete feature &lt;strong&gt;so that&lt;/strong&gt; I can&amp;hellip; &lt;em&gt;{get an awesome impact or&amp;hellip; awful impact?}&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;萬一又寫不下去了，那麼，請改用 Impact Mapping 的角度去反思：這功能若實現了，誰會是這功能的受益者，以及⋯⋯潛在的受害者？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;As a&lt;/strong&gt; buyers of digital advertising inventory, &lt;strong&gt;I want to&lt;/strong&gt; increase ad exposure to users&amp;rsquo; autocomplete journey &lt;strong&gt;so that&lt;/strong&gt; &amp;hellip;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;As a&lt;/strong&gt; search service user, &lt;strong&gt;I want to&lt;/strong&gt; &amp;hellip;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一旦嘗試從這幾個 user 視角去改寫 story，你會發現，原本的「Autocomplete 要優先置入廣告關鍵字」任務陳述有多麼粗糙。&lt;/p&gt;
&lt;h2 id=&#34;你可以嘗試的-power-questions&#34;&gt;你可以嘗試的 Power Questions&lt;/h2&gt;
&lt;p&gt;限制帶來自由。如有可能，請盡可能嘗試用正統的 User Story 來審視你的任務。&lt;/p&gt;
&lt;p&gt;也請盡量試著用一些 power questions 來輔助思考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;「在顧客眼中，這功能是什麼？」&lt;/li&gt;
&lt;li&gt;「你建造的東西，對人們達成目標的方式產生什麼影響？」&lt;/li&gt;
&lt;li&gt;「是否可以像『切蛋糕』那樣寫用戶故事？」&lt;/li&gt;
&lt;/ul&gt;</description>
      
    </item>
    
    <item>
      <title>職涯躍升書系導讀會，Part 2：高效團隊的工作方法</title>
      <link>//william-yeh.net/post/2022/08/career-reading-club-2/</link>
      <pubDate>Sat, 20 Aug 2022 10:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/08/career-reading-club-2/</guid>
      
        <description>&lt;p&gt;2022 年一月起，我開始每個月一次，每次兩小時的【職涯躍升書系導讀會】。&lt;a href=&#34;//william-yeh.net/post/2022/06/career-reading-club-1/&#34;&gt;前六個月&lt;/a&gt;著眼於&lt;strong&gt;喚醒個人及團隊的成長意識&lt;/strong&gt;，接下來兩個月則著眼於&lt;strong&gt;高效團隊的工作方法&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;這兩個月的導讀會，都鎖定在 Agile 相關書籍上——儘管單純從書籍名稱上面都看不出來會與「敏捷」有關。選書如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;① &lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;② &lt;a href=&#34;https://www.playpcesor.com/2020/05/2020-new-book.html&#34;&gt;時間管理的 30 道難題&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/08/career-reading-club-2.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/08/career-reading-club-2.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;以下列出這兩場導讀會的介紹文案。&lt;/p&gt;
&lt;h2 id=&#34;豐田精實管理的翻轉獲利秘密&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;最近一些同仁開始上 Kanban 課程，我想，也該是時候引介大家讀一讀這類書籍了。&lt;/p&gt;
&lt;p&gt;接下來兩次導讀會，都會鎖定在 Agile 相關書籍上——儘管單純從書籍名稱上面都看不出來會與「敏捷」有關。&lt;/p&gt;
&lt;p&gt;首先登場的是《&lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;原諒我又要講古了。記得 2016 年我密謀在Ｇ公司推動 &lt;a href=&#34;https://www.slideshare.net/williamyeh/devops-to-agile-transformation&#34;&gt;Agile &amp;amp; DevOps 轉型&lt;/a&gt;之前，私底下先做了一些思想溯源。畢竟，身為 INTJ，智性上的滿足是不容妥協的——我不滿足於只是「守」著使用手冊般的 &amp;ldquo;thou shalt&amp;hellip;&amp;rdquo; 敘述，我還需要知道背後的原理及演變歷史。&lt;/p&gt;
&lt;p&gt;眾所周知，Agile &amp;amp; DevOps 其中一支重要源頭是 Toyota 引以為傲的「&lt;strong&gt;Lean 精實思想&lt;/strong&gt;」。因此，當年我從《&lt;a href=&#34;https://www.books.com.tw/products/0010662172&#34;&gt;精實革命&lt;/a&gt;》、《&lt;a href=&#34;https://www.taaze.tw/products/11100684280.html&#34;&gt;流的傳承&lt;/a&gt;》、《&lt;a href=&#34;https://www.taaze.tw/products/11100227775.html&#34;&gt;豐田形學&lt;/a&gt;》、《&lt;a href=&#34;https://www.taaze.tw/products/11100131112.html&#34;&gt;學習觀察&lt;/a&gt;》這幾本書消化吸收 Lean 思想，雖然費力，但對於 Agile &amp;amp; DevOps 背後的原理更了然於心，也更能面對現實世界的變化球。畢竟，即使我們不嚷嚷著要推動 Agile &amp;amp; DevOps，但 Lean 思想的核心要點，仍然是非常具有普遍性的，值得精熟。&lt;/p&gt;
&lt;p&gt;再功利一點講，許多人對於 Agile 的想像是「&lt;a href=&#34;https://www.books.com.tw/products/0010785434&#34;&gt;用一半的時間做兩倍的事&lt;/a&gt;」，問題是，真的有這麼神效嗎？關於這問題，我引述憲哥在《&lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;》推薦序所說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;精實管理，是提升效率的顯學。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，如果導入敏捷的初衷是「&lt;a href=&#34;https://www.books.com.tw/products/0010785434&#34;&gt;用一半的時間做兩倍的事&lt;/a&gt;」，那麼，從「精實思想」這一源頭切入，或許更能直接符合期待——但我可沒說這會比較容易。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Lean 思想雖然具有普遍性，但某些地方卻是反直覺的，需要以實際活動或模擬活動去體驗（記得嗎？我的【敏捷原理與團隊塑造】工作坊，就有一個這樣的小活動）。我也一直試圖尋找更淺易的 Lean 思想入門書，作為課後跟進的輔助讀物。&lt;/p&gt;
&lt;p&gt;多年後終於找到了。江守智這本《&lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;》，儘管不是針對軟體研發產業，但如果你慧眼獨具，自然會發現「雖世殊事異，所以興懷，其致一也」。正如此書第 53 頁所說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「&lt;strong&gt;轉化&lt;/strong&gt;」是過去十年內我在顧問生涯中所獲得的最重要能力。因為隨著看的企業越多，就會發現大家所在乎所努力的方向其實都很相似。因此，如果說要向標竿學習，那麼這些績優企業如何應對這些&lt;strong&gt;通則性問題&lt;/strong&gt;，就是一個值得參考的地方。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我甚至可以說：好好吸收並轉化這本書所詮釋的 Lean，將可讓 Agile 的執行更有底氣，而不致淪為花拳繡腿。&lt;/p&gt;
&lt;h2 id=&#34;時間管理的-30-道難題&#34;&gt;時間管理的 30 道難題&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;七月八月的兩次導讀會，都鎖定在 Agile 相關書籍上——儘管單純從書籍名稱上面都看不出來會與「敏捷」有關。&lt;/p&gt;
&lt;p&gt;兩個月，兩本書，分別對應到當前敏捷的兩大門派：Kanban 與 Scrum。&lt;/p&gt;
&lt;p&gt;七月份導讀會的選書《&lt;a href=&#34;https://williampjyeh.notion.site/d8a843cbc9c148989e6489625b6fb34d&#34;&gt;豐田精實管理的翻轉獲利秘密&lt;/a&gt;》談的是 Kanban 背後的「&lt;strong&gt;Lean 精實思想&lt;/strong&gt;」，八月份導讀會的選書《&lt;a href=&#34;https://www.playpcesor.com/2020/05/2020-new-book.html&#34;&gt;時間管理的 30 道難題&lt;/a&gt;》則在探討個人的&lt;strong&gt;時間管理&lt;/strong&gt;，以及（根據相同的原理）團隊的時間管理：目標選擇術、子彈行動力、時間掌控權、流程改進法——有慧眼的人會看出，其實這與 Scrum 的 4+1 活動，雷同程度極高。&lt;/p&gt;
&lt;p&gt;Scrum 之所以常被戲稱為「&lt;a href=&#34;https://teddy-chen-tw.blogspot.com/2014/10/blog-post_24.html&#34;&gt;照妖鏡&lt;/a&gt;」的原因是，它如實照見出團隊工作流程、技能、默契的盲點（這是 Scrum 經驗主義三支柱當中的 &lt;strong&gt;transparency&lt;/strong&gt;），以及團隊是否有&lt;strong&gt;勇氣&lt;/strong&gt;（這是 Scrum 五大核心價值觀之一）面對事實去進行持續改善（這是 Scrum 經驗主義三支柱當中的 &lt;strong&gt;adaptation&lt;/strong&gt;）。&lt;/p&gt;
&lt;p&gt;Scrum 團隊若拒絕面對殘酷的真相，半途而廢比例是非常高的。所以有的經典說「大道以多歧亡羊，學者以多方喪生」，有的經典說「你們要從窄門進去；因為通向滅亡的門是大的，路是寬的，從那裡進去的人也多。」&lt;/p&gt;
&lt;p&gt;假使團隊真的有勇氣走向持續改善的道路，那麼，該朝什麼方向改善呢？&lt;/p&gt;
&lt;p&gt;我認為，《&lt;a href=&#34;https://www.playpcesor.com/2020/05/2020-new-book.html&#34;&gt;時間管理的 30 道難題&lt;/a&gt;》這本書探討的個人的時間管理，以及（根據相同的原理）團隊的時間管理，是非常好的起點。跑 Scrum 的人，從這本書必會找到許多改善團隊運作的線索——這是 Scrum 4+1 活動的基本功。&lt;/p&gt;
&lt;p&gt;就算你不跑 Scrum，這本書也一樣能夠改善個人的工作效能——這是專業工作者的職場基本功。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【職涯躍升書系導讀會】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ Part 1: &lt;a href=&#34;//william-yeh.net/post/2022/06/career-reading-club-1/&#34;&gt;喚醒個人及團隊的成長意識&lt;/a&gt; (計 6 冊)&lt;/p&gt;
&lt;p&gt;❷ Part 2: 高效團隊的工作方法 (計 2 冊)&lt;/p&gt;
&lt;p&gt;❸ Part 3: &lt;a href=&#34;//william-yeh.net/post/2022/11/career-reading-club-3/&#34;&gt;職場心理：觀點、期待、渴望&lt;/a&gt; (計 3 冊)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>請掌握「對高層簡報」的技術及習慣</title>
      <link>//william-yeh.net/post/2022/08/present-for-upper-mgmt/</link>
      <pubDate>Thu, 04 Aug 2022 19:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/08/present-for-upper-mgmt/</guid>
      
        <description>&lt;p&gt;（改寫自公司內部 memo）&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Dear all guys,&lt;/p&gt;
&lt;p&gt;最近協助一些同仁潤飾簡報，尤其是對高層的簡報，有一個常見的問題，值得特別為文給大家一點建議。&lt;/p&gt;
&lt;p&gt;我們在三月份&lt;a href=&#34;//william-yeh.net/post/2022/06/career-reading-club-1/&#34;&gt;導讀會&lt;/a&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010681486&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》就已經探討過，對高層的寫作與簡報，要盡量掌握「&lt;strong&gt;金字塔原理&lt;/strong&gt;」：結論先行，論證隨後。&lt;/p&gt;
&lt;p&gt;鑑於有些人沒參加這場導讀會，以下僅說明三大重點：① 一般的溝通原理，② 對高層的溝通原理，③ 對高層的溝通方法。&lt;/p&gt;
&lt;h2 id=&#34;一般的溝通原理&#34;&gt;一般的溝通原理&lt;/h2&gt;
&lt;p&gt;一般的寫作與簡報，高效人士會 &lt;strong&gt;working backwards&lt;/strong&gt;，先從這個自我提問開始：「我&lt;strong&gt;期望&lt;/strong&gt;在這一場溝通之後，能夠得到的&lt;strong&gt;效果&lt;/strong&gt;或&lt;strong&gt;反應&lt;/strong&gt;是什麼？」&lt;/p&gt;
&lt;p&gt;在三月份導讀會中，我曾引述《&lt;a href=&#34;https://www.books.com.tw/products/0010928450&#34;&gt;邏輯思考的技術&lt;/a&gt;》的概念圖，將「期望得到的反應」分成三種：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;理解&lt;/li&gt;
&lt;li&gt;決策的結果、意見、建議等回饋&lt;/li&gt;
&lt;li&gt;行動&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不同的期望，會影響整份寫作與簡報的動線及力道。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/08/comm-flow.jpg&#34; alt=&#34;“溝通的基本原理&amp;#34;&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/08/comm-flow.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;“溝通的基本原理&amp;#34;&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;對高層的溝通原理&#34;&gt;對高層的溝通原理&lt;/h2&gt;
&lt;p&gt;對高層的寫作與簡報，除了依循前述的一般溝通原理之外，還需要對於「高層」這種生物有某種理解，才能投其所好。&lt;/p&gt;
&lt;p&gt;「高層」這種生物，是怎麼樣的生物？&lt;/p&gt;
&lt;p&gt;在《&lt;a href=&#34;https://www.books.com.tw/products/0010681486&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》書中是這麼說的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你可能聽過或學過許多演講技巧，例如要有令人難忘的開場白、要有力量甚至誇張的手勢、要說故事、要有抑揚頓挫的音調等，這些演講技巧都很好，可是當面對高階主管進行&lt;strong&gt;有時間壓力&lt;/strong&gt;的高層決策會議時，卻極有可能毀了這場簡報，因為這一群聽眾十分特殊，所以簡報內容、表達方式與吸引方式，都要不同於一般的簡報。&lt;/p&gt;
&lt;p&gt;他們通常習慣&lt;strong&gt;掌控全局&lt;/strong&gt;、&lt;strong&gt;缺乏耐心&lt;/strong&gt;，&lt;strong&gt;咄咄逼人&lt;/strong&gt;又令人恐懼。簡單說，他們是一群極度不容易對付的聽眾！&lt;/p&gt;
&lt;p&gt;因此對高層簡報必須大幅減少一堆平常演講的花招，而要展現&lt;strong&gt;迅速清晰簡潔&lt;/strong&gt;的資訊，以利進行&lt;strong&gt;決策&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;換言之，如果你能夠在高層面前展現出 ①&lt;strong&gt;重點摘要&lt;/strong&gt;，②&lt;strong&gt;下一步行動&lt;/strong&gt;，③&lt;strong&gt;請示&lt;/strong&gt; 這三方面的&lt;strong&gt;組織力&lt;/strong&gt;及&lt;strong&gt;表達力&lt;/strong&gt;，不僅是體貼這種日理萬機的生物，更是在這種生物面前留下專業的印象——你應該明白這意味著什麼。&lt;/p&gt;
&lt;h2 id=&#34;對高層的溝通方法&#34;&gt;對高層的溝通方法&lt;/h2&gt;
&lt;p&gt;第一招，就如同《&lt;a href=&#34;https://www.books.com.tw/products/0010681486&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》書中所說的：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/08/presentation-for-upper-mgmt.jpg&#34; alt=&#34;Source: 《不懂這些，別想加薪》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/08/presentation-for-upper-mgmt.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: 《不懂這些，別想加薪》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;第二招，就是我在導讀會介紹過的「&lt;strong&gt;金字塔原理&lt;/strong&gt;」：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/08/pyramid-principle.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/08/pyramid-principle.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;金字塔原理，是工作者邁向專業形象的敲門磚試金石。如有可能，請大家多多自我要求，必會有所得。就像我在導讀會引述勝間和代的說法：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/08/no-logic.jpg&#34; alt=&#34;Source: 《新・知識生產術》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/08/no-logic.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: 《新・知識生產術》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;如果還想認真學習金字塔原理，請見&lt;a href=&#34;//william-yeh.net/post/2022/05/learn-from-consulting-firms/#進階篇金字塔原理&#34;&gt;此書單&lt;/a&gt;。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>專案管理／專案組合管理當中，不必然需要公開透明的地方</title>
      <link>//william-yeh.net/post/2022/08/stakeholder-transparency/</link>
      <pubDate>Mon, 01 Aug 2022 17:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/08/stakeholder-transparency/</guid>
      
        <description>&lt;p&gt;（改寫自公司內部 memo）&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;（Target audience: 有「專案管理」職責的人）&lt;/p&gt;
&lt;p&gt;Hi all,&lt;/p&gt;
&lt;p&gt;隨著愈來愈多人開始運用專案管理課堂上學到的技術來工作，帶來更高的透明度，更成熟的專業度，欣慰之餘，我也針對其中一件事「透明度」提出一點小提醒。&lt;/p&gt;
&lt;p&gt;理想情況下，組織應該要追求專案的透明度——除非有特殊理由。&lt;/p&gt;
&lt;p&gt;譬如說，Rex 老師在課堂上就提醒過：「&lt;a href=&#34;https://en.wikipedia.org/wiki/Stakeholder_analysis&#34;&gt;利害關係人矩陣&lt;/a&gt;」不必然需要對外公開透明。試想：如果某一位利害關係人看到自己被歸在 &amp;ldquo;High Interest but Low Power&amp;rdquo; 象限，會作何感想？&lt;/p&gt;
&lt;p&gt;Rita Mulcahy 在 &lt;a href=&#34;https://www.amazon.com/dp/1932735658&#34;&gt;&lt;em&gt;PMP Exam Prep&lt;/em&gt;&lt;/a&gt; 書中也如此提醒：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/08/rita-on-stakeholders.png&#34; alt=&#34;Source: PMP Exam Prep by Rita Mulcahy&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/08/rita-on-stakeholders.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: PMP Exam Prep by Rita Mulcahy&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;另一個例子，是專案組合管理 (project portfolio management)。&lt;/p&gt;
&lt;p&gt;我們會根據某些質化或量化角度替專案組合做評估與分級。如果整個組織已經有公認成熟的量化評估方法（尤其是有 PMO 編制的組織），那就是走公開透明的路線；否則，可能會用簡單的質化方式，像是&lt;a href=&#34;https://en.wikipedia.org/wiki/Time_management#The_Eisenhower_Method&#34;&gt;艾森豪矩陣&lt;/a&gt;之類的二軸工具予以初步分級。&lt;/p&gt;
&lt;p&gt;此時，請小心拿捏：這種二軸評估矩陣是否真的需要公開透明。試想：如果某一位利害關係人看到自己的專案被歸在 &amp;ldquo;Not Important&amp;rdquo; 或是 &amp;ldquo;Not Urgent&amp;rdquo; 的象限，會作何感想？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;小總結：有些專案管理／專案組合管理資訊，可能只能在專案團隊內部揭露。不是為了隱瞞，而是為了妥善管理利害關係人。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>專案 Kick-off meeting 的前置作業</title>
      <link>//william-yeh.net/post/2022/07/prj-kickoff/</link>
      <pubDate>Mon, 11 Jul 2022 15:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/07/prj-kickoff/</guid>
      
        <description>&lt;p&gt;（改寫自公司內部 memo）&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;（Target audience: 上過【專案管理第一次就上手】的同仁）&lt;/p&gt;
&lt;p&gt;很高興看到二月及四月上過【專案管理第一次就上手】的同仁們，開始在工作上運用課堂所學，尤其是「&lt;strong&gt;專案管理問題清單&lt;/strong&gt;」開始被廣泛運用在大大小小專案的 kick-off meeting 上面，這是非常好的現象。&lt;/p&gt;
&lt;p&gt;這份 memo，我針對 &lt;strong&gt;kick-off meeting&lt;/strong&gt; 的定位及前置作業多做一些補充，算是這陣子貼身觀察的小小心得。&lt;/p&gt;
&lt;h2 id=&#34;定位&#34;&gt;定位&lt;/h2&gt;
&lt;p&gt;關於 Kick-off meeting 的&lt;strong&gt;定位&lt;/strong&gt;，Rex 老師在課堂上有提過：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/07/kick-off-meeting.png&#34; alt=&#34;Source: 【專案管理第一次就上手】by Rex Feng&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/07/kick-off-meeting.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: 【專案管理第一次就上手】by Rex Feng&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;接下來的問題就是：要怎麼做，才能夠「&lt;strong&gt;獲得大家支持&lt;/strong&gt;」？畢竟，光是在會議現場「公告天下專案即將啟動」，並不必然會順水推舟達到「獲得大家支持」的結果。&lt;/p&gt;
&lt;p&gt;我認為，關鍵就在於「&lt;strong&gt;事前的利害關係人管理&lt;/strong&gt;」。&lt;/p&gt;
&lt;p&gt;請注意，這句話有兩個重點：「&lt;strong&gt;利害關係人管理&lt;/strong&gt;」以及「&lt;strong&gt;事前&lt;/strong&gt;」，更進一步說，這涉及到 &lt;strong&gt;WHEN&lt;/strong&gt; (事前) 與 &lt;strong&gt;DO WHAT&lt;/strong&gt; (管理) 兩個議題。&lt;/p&gt;
&lt;h2 id=&#34;when&#34;&gt;WHEN&lt;/h2&gt;
&lt;p&gt;既然提到「kick-off meeting 必須在『事前』先做一些事」，那麼，kick-off meeting 的時機點，會是在專案管理生命週期（亦即「五大流程群組」：initiating、planning、executing、monitoring and controlling、closing）的什麼時機進行，才算是最恰當的？&lt;/p&gt;
&lt;p&gt;以 &lt;a href=&#34;https://www.amazon.com/dp/1628251840&#34;&gt;&lt;em&gt;The PMBOK Guide&lt;/em&gt; 6/e&lt;/a&gt; 而言，kick-off meeting 是擺在「Planning 結束」 ←→ 「Execution 開始」這個中間地帶：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/07/pmbok6-kickoff.png&#34; alt=&#34;Source: The PMBOK Guide, 6/e&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/07/pmbok6-kickoff.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: The PMBOK Guide, 6/e&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;do-what&#34;&gt;DO WHAT&lt;/h2&gt;
&lt;p&gt;既然 kick-off meeting 是落在「Planning 結束」 ←→ 「Execution 開始」這個時間點，那麼，以下這幾個活動，應該都已經進行到某個完成度了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scope
&lt;ul&gt;
&lt;li&gt;Collect Requirements&lt;/li&gt;
&lt;li&gt;Define Scope&lt;/li&gt;
&lt;li&gt;Create WBS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stakeholder
&lt;ul&gt;
&lt;li&gt;Plan Stakeholder Engagement&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Communication
&lt;ul&gt;
&lt;li&gt;Plan Communications Management&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;總而言之，理論上，「利害關係人管理」應該早在 kick-off meeting 之前就已經做到某個程度了。&lt;/p&gt;
&lt;h2 id=&#34;那麼kick-off-meeting-本身都在做什麼&#34;&gt;那麼，kick-off meeting 本身都在做什麼？&lt;/h2&gt;
&lt;p&gt;Kick-off meeting 之前居然要做這麼多事情，那麼，kick-off meeting 本身還要做什麼？&lt;/p&gt;
&lt;p&gt;Rita Mulcahy 在 &lt;a href=&#34;https://www.amazon.com/dp/1932735658&#34;&gt;&lt;em&gt;PMP Exam Prep&lt;/em&gt;&lt;/a&gt; 書中說得好：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/07/rita-kickoff.png&#34; alt=&#34;Source: PMP Exam Prep by Rita Mulcahy&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/07/rita-kickoff.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: PMP Exam Prep by Rita Mulcahy&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;事前準備若做得好，kick-off meeting 多半的時間，是在 &amp;ldquo;review&amp;rdquo; 會議前就規劃出來的 project plan（縱然這可能只是一份仍待 rolling wave planning 的版本），做些最後的對齊與釐清，然後，拍板定案。&lt;/p&gt;
&lt;h2 id=&#34;no-surprise&#34;&gt;No Surprise&lt;/h2&gt;
&lt;p&gt;理論上，kick-off meeting 現場，應該不會有太多的 &amp;ldquo;surprise!&amp;rdquo; 發生，更多的是一種儀式，一種畫押。&lt;/p&gt;
&lt;p&gt;如果當場會有過多的 &amp;ldquo;surprise!&amp;quot;，那就代表事前準備仍有疏漏。&lt;/p&gt;
&lt;p&gt;所以君婷老師在〈&lt;a href=&#34;https://www.projectup.net/article/view/id/16626&#34;&gt;老闆心，海底針：我該如何錨定老闆的目標？&lt;/a&gt;〉這篇文章就提醒過：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在某些有規模的專案當中，&lt;strong&gt;「定出專案的目標」本身就是一個專案前的專案&lt;/strong&gt;，而且是個非常重要的專案，請用看待一個「正式專案」，態度嚴謹看待之，而你必須先取得這個專案的結果（目標）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果真的要 fast tracking 抄捷徑，那就得承擔對應的風險。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;願大家在專案管理路上繼續精進，讓我們的工作進展得更順利，朝向 Rex 老師所講的「諸葛亮」境界邁進。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>職涯躍升書系導讀會，Part 1：喚醒個人及團隊的成長意識</title>
      <link>//william-yeh.net/post/2022/06/career-reading-club-1/</link>
      <pubDate>Fri, 17 Jun 2022 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/06/career-reading-club-1/</guid>
      
        <description>&lt;p&gt;2022 年一月起，我開始每個月一次，每次兩小時的【職涯躍升書系導讀會】，讓公司同仁自由報名，希望藉由這種草根性的軟性活動，另闢一條 bottom-up 的改革路徑。畢竟，深遠持久的影響，不能少掉「喚醒基層意識」這環節。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/reading-club-photo.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/reading-club-photo.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;前六個月的選書如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;個人層面，喚醒個人成長意識&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;① &lt;a href=&#34;https://www.tenlong.com.tw/products/9789865027896&#34;&gt;經理人之道&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;② &lt;a href=&#34;https://williampjyeh.notion.site/cd42e217271d454aac9411b0c6fc84c7&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;③ &lt;a href=&#34;https://williampjyeh.notion.site/1a6d4482e2bb42329d85624c214c91fb&#34;&gt;不懂這些，別想加薪&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;團隊層面，喚醒團隊成長意識&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;④ &lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑤ &lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑥ &lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下列出這六場導讀會的介紹文案。&lt;/p&gt;
&lt;h2 id=&#34;經理人之道&#34;&gt;經理人之道&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;活動名稱&lt;/strong&gt;：《經理人之道》導讀會&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;時間&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;導讀人&lt;/strong&gt;：William Yeh&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;目標聽眾&lt;/strong&gt;：技術領域的初階主管、地下主管、工頭、組頭，以及有志於在一兩年內成為上述身分的人。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;活動進行方式&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;活動前：請先自行讀完《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865027896&#34;&gt;經理人之道&lt;/a&gt;》至少第 1～6 章。&lt;/li&gt;
&lt;li&gt;活動中：導讀、討論、Q&amp;amp;A。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;參考資料&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我寫的推薦序：&lt;a href=&#34;//william-yeh.net/post/2021/02/the-managers-path-review/&#34;&gt;軟體研發者的隨身職涯教練&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;三年後你的工作還在嗎&#34;&gt;三年後，你的工作還在嗎？&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;2014 年初，我以 architect 身分加入Ｇ公司。當時我對於 individual contributor (IC) 路線能走到什麼地步，仍然充滿疑惑，身邊也沒有 mentor 可以解惑。&lt;/p&gt;
&lt;p&gt;幸運的是，我在 2014 年 8 月就入手《&lt;a href=&#34;https://williampjyeh.notion.site/cd42e217271d454aac9411b0c6fc84c7&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;》這本剛出爐的新書。這本書的觀念，徹底重塑了我的認知，成為我私房的職涯祕笈。甚至當我數年後成為主管，我還自掏腰包送給屬下一人一本，以重塑整個部門的意識（有圖為證）：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/3-years-jobs.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/3-years-jobs.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;值此歲初重新檢視與訂定個人年度計畫的時機，我大力推薦用這本書伴你度過農曆新年。&lt;/p&gt;
&lt;h2 id=&#34;不懂這些別想加薪&#34;&gt;不懂這些，別想加薪&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;為了離開舒適圈，看看外面的世界，我去外商圈打滾了一陣子，儘管我的英語聽說能力並不算好。&lt;/p&gt;
&lt;p&gt;在外商，異國異地 con-call 開會，讀不到共時性的空氣，已經是一種低情境的溝通了，使用英語，更是嚴重限縮語言表達力的頻寬。低情境、低頻寬，是我面對的第一個困境。&lt;/p&gt;
&lt;p&gt;我更發現，為了突破低情境低頻寬的禁錮，不只簡報風格，不只溝通風格，甚至連更基本的職場思維也得轉變。我得盡快尋得具體的方法，從頭練習職場基本功——我需要學會在低情境、低頻寬處境下更簡潔、更高效的風格，這風格還得具有某種跨文化、跨語言的通用性。&lt;/p&gt;
&lt;p&gt;後來，我拿出早已躺在書架上好幾年的這本書，重新蹲馬步：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/1a6d4482e2bb42329d85624c214c91fb&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不要被狀似聳動的書名騙了。這本內容扎實的書，不僅是表格，不僅是話術，更是&lt;strong&gt;職場思考&lt;/strong&gt;的基本功。&lt;/p&gt;
&lt;p&gt;照著這本書刻意練習幾個月，某些核心要點甚至還刻意默寫默背起來。沒有 mentor/coach 在側，自承進步緩慢，卻已經開始敏銳看到許多身邊的反例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;口語陳述冗長，聽不到重點&lt;/li&gt;
&lt;li&gt;簡報層次錯綜，看不到結構&lt;/li&gt;
&lt;li&gt;簡報資料蕪雜，看不到牛肉&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;當我照著書中第一堂課「一分鐘口頭報告」的兩份表格自我操練，也照著第六堂課及第十一堂課介紹的兩種不同的簡報情境重塑自己的簡報思路之後，這類反例在我眼中就顯得粒粒分明。&lt;/p&gt;
&lt;p&gt;看得到問題，察覺到不足，喚起意識，才容易催生改善的行動。&lt;/p&gt;
&lt;p&gt;如果你也想重頭練習我所謂的&lt;strong&gt;職場基本功&lt;/strong&gt;，我邀請你，照著以下步驟進行：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;開始閱讀《&lt;a href=&#34;https://williampjyeh.notion.site/1a6d4482e2bb42329d85624c214c91fb&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》這本書。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;拿出隨身筆記本，開始敏銳&lt;strong&gt;觀察&lt;/strong&gt;你身邊發生的這些具體事件，並&lt;strong&gt;記錄&lt;/strong&gt;下來。在下次導讀會時，秀出你所記錄的這些事件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;口語陳述冗長，聽不到重點&lt;/li&gt;
&lt;li&gt;簡報層次錯綜，看不到結構&lt;/li&gt;
&lt;li&gt;簡報資料蕪雜，看不到牛肉&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;記錄之餘，請進一步思考：如果換成《&lt;a href=&#34;https://williampjyeh.notion.site/1a6d4482e2bb42329d85624c214c91fb&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》這本書教的方法，應該怎麼調整？&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;另外，這本書第七堂課介紹「DISC 個性分類」，我也在 Scrum 團隊提過幾次。我建議大家可以先做一下附件的小測驗，我們在導讀會現場會聊聊這個東西。&lt;/p&gt;
&lt;h2 id=&#34;獨角獸專案&#34;&gt;獨角獸專案&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;近十年，軟體研發界有兩大類重要思潮。在技術面，有大數據、機器學習、immutable infrastructure、微服務、容器、函式編程、資料流水線等；在流程面，則有敏捷開發、DevOps、自助服務、混亂工程、精實 UX 等。這些思潮，有些是新發明，有些則是文藝復興，甚至是跨界學習而來。&lt;/p&gt;
&lt;p&gt;因此，當我 2021 年底答應要來這裡時，雖然早有心理準備，但實際進來看到這邊的&lt;strong&gt;軟體技術&lt;/strong&gt;及&lt;strong&gt;行事流程&lt;/strong&gt;，與外界所謂「業界標準配備」差距甚大，仍然嚇了一跳。&lt;/p&gt;
&lt;p&gt;當然啦，這也是我來這裡第一年的重要目標之一：「Raise the bar for 各職能工作者，至少要對齊業界水平」。&lt;/p&gt;
&lt;p&gt;業界水平是什麼模樣？大體上，就像《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》這本小說所描繪的那樣。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;在這小說中，你可以看到在「無極限零件公司」這樣年營業額 40 億美元的製造商暨零售商中，行銷企劃部門、軟體研發部門、服務維運部門彼此爭功諉過的寫實場景。你會看到故事主角梅克辛如何在穀倉泥淖中獨自展開她的「英雄之旅」，與地下反抗軍合作，導入先進的軟體研發思潮。正當一切似乎漸入佳境時，居然還有一條懸疑支線在背後悄悄醞釀⋯⋯高潮迭起，頗有潛力改編成劇情片。&lt;/p&gt;
&lt;p&gt;如果你是愛看熱鬧的小說族，你會喜歡它的。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;當然啦，內行看門道。這本奇書，並不止於小說，而是真正可以照表操課的。&lt;/p&gt;
&lt;p&gt;在參加導讀會之前，我建議大家依照「速讀」及「精讀」兩階段依序進行：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;速讀階段：速讀完《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》至少一遍，先享受高潮起伏的劇情，並熟悉人物與關係。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;精讀階段：挑出書中所有與「&lt;strong&gt;系統與組織的五大理念&lt;/strong&gt;」有關的段落，越多越好。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我自己的做法是：每讀到一個有關的地方，就用書籤標註（善用不同顏色的標籤更好）。如下圖：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/unicorn-project.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/unicorn-project.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;以上，請務必在導讀會之前確實完成。導讀會時，我們會以此為基礎，玩一場我在 &lt;a href=&#34;https://devopsdays.tw/2021/workshop-page/212&#34;&gt;DevOpsDays Taipei 2021&lt;/a&gt; 帶的工作坊。我們將以「系統思考」角度，帶你分析書中倡議的「&lt;strong&gt;五大理念&lt;/strong&gt;」，你將會得到有助於形塑適合 IT 滋長企業文化的施力線索。&lt;/p&gt;
&lt;h2 id=&#34;amazon-的人為什麼這麼厲害&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;我自認有一點點文青的基因。像詹先生寫《&lt;a href=&#34;https://www.books.com.tw/products/0010099824&#34;&gt;創意人&lt;/a&gt;》及《&lt;a href=&#34;https://www.books.com.tw/products/0010065180&#34;&gt;城市人&lt;/a&gt;》，企劃的《&lt;a href=&#34;https://www.books.com.tw/products/0010414925&#34;&gt;謀殺專門店&lt;/a&gt;》，創辦的【明日報】，都是我小時候愛讀的東西。&lt;/p&gt;
&lt;p&gt;因此，當 2021 年 10 月初 Ｓ君 &amp;amp; Ｃ君 與我接洽，我是充滿驚喜的。當時我心想，有機會在曾經引領台灣網路圈不斷創新的Ｐ集團底下服務，應該是非常光榮的事。&lt;/p&gt;
&lt;p&gt;是的，在我學生時期，Ｐ的確是台灣網路圈的創新火車頭。&lt;/p&gt;
&lt;p&gt;不過，當我進來之後，我很驚訝地發現，Ｐ與我學生時期的印象已經大大不同了。就如我在上一次《獨角獸專案》導讀會的文案所說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;當我 2021 年底答應要來這裡時，雖然早有心理準備，但實際進來看到這邊的&lt;strong&gt;軟體技術&lt;/strong&gt;及&lt;strong&gt;行事流程&lt;/strong&gt;，與外界所謂「業界標準配備」的差距甚大，仍然嚇了一跳。&lt;/p&gt;
&lt;p&gt;當然啦，這也是我來這裡第一年的重要目標之一：「Raise the bar for 各職能工作者，至少要對齊業界水平」。&lt;/p&gt;
&lt;p&gt;業界水平是什麼模樣？大體上，就像《獨角獸專案》這本小說所描繪的那樣。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;《獨角獸專案》描繪的是「&lt;strong&gt;軟體技術&lt;/strong&gt;及&lt;strong&gt;行事流程&lt;/strong&gt;」的業界水平，至於「&lt;strong&gt;專業主義&lt;/strong&gt;及&lt;strong&gt;企業文化&lt;/strong&gt;」的業界水平，我打算透過《&lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;》這本書來與大家一同探討。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;》這本書所描繪的，其實不只是 Amazon 一家公司的狀況，其實不只是電商龍頭的狀況，更是許多一流外商的共同水平。&lt;/p&gt;
&lt;p&gt;我期待大家能好好吸收這本書所勾勒的「&lt;strong&gt;專業主義&lt;/strong&gt;及&lt;strong&gt;企業文化&lt;/strong&gt;」，我也會如此要求大家，追上業界水平，成為專業的工作團隊。&lt;/p&gt;
&lt;h2 id=&#34;克服團隊領導的五大障礙&#34;&gt;克服團隊領導的五大障礙&lt;/h2&gt;
&lt;p&gt;Dear all,&lt;/p&gt;
&lt;p&gt;四月五月導讀會的選書當中，《獨角獸專案》描繪的是「&lt;strong&gt;軟體技術&lt;/strong&gt;及&lt;strong&gt;行事流程&lt;/strong&gt;」的業界水平，《Amazon 的人為什麼這麼厲害？》描繪的是「&lt;strong&gt;專業主義&lt;/strong&gt;及&lt;strong&gt;企業文化&lt;/strong&gt;」的業界水平。接下來六月份的導讀會，我打算藉由《&lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;》這本書，談談「&lt;strong&gt;績優團隊&lt;/strong&gt;」的業界水平。&lt;/p&gt;
&lt;p&gt;記得自己第一次認真思考「&lt;strong&gt;績優團隊&lt;/strong&gt;」這件事，且把這件事視為己任，是在 2015 年閱讀《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789864765867&#34;&gt;鳳凰專案&lt;/a&gt;》這本書的時候（記得嗎？這是《獨角獸專案》的前作）。我也注意到故事中 CEO 史蒂夫在第 18 章中運用了《&lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;》所介紹的「&lt;strong&gt;個人歷史演練&lt;/strong&gt; (&lt;strong&gt;personal history exercise&lt;/strong&gt;)」來重塑團隊，擊節讚嘆於峰迴路轉的劇情之餘，不免也心生疑竇：這一招真的有那麼神嗎？&lt;/p&gt;
&lt;p&gt;因此，我入手了《&lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;》這本書，也根據這本書介紹的方法，用在團隊集體塑造上，用在新人 onboarding 上，也用在個人 1:1 上，可說是我的私房法寶。&lt;/p&gt;
&lt;p&gt;這本書的部份重點，可參考以下幾篇文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://negotowin.blogspot.com/2017/05/blog-post_31.html&#34;&gt;「一個人走的快，一群人走的遠」，但為何有些團隊就是走不遠？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://negotowin.blogspot.com/2017/06/2gabcd.html&#34;&gt;從 2G 到 ABCD：想要讓團隊走得更快又更遠？先看看建立信任的兩大目標及四項指標&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://negotowin.blogspot.com/2017/06/blog-post_7.html&#34;&gt;讓團隊走得更快又更遠第二招：用建設性衝突打造更強的團隊戰力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://negotowin.blogspot.com/2017/06/grow.html&#34;&gt;讓團隊走得更快又更遠第三招：結合 GROW 模式的勇於許下承諾&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://negotowin.blogspot.com/2017/06/blog-post_30.html&#34;&gt;讓團隊走得更快又更遠第四招：塑造當責文化之前，你該知道規避責任者的四大類型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://negotowin.blogspot.com/2017/07/blog-post_10.html&#34;&gt;讓團隊走得更快又更遠番外篇：從負責到當責的塑造當責文化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://negotowin.blogspot.com/2017/07/34.html&#34;&gt;讓團隊走得更快又更遠第五招：學會重視成果的 3 個階段和 4 種對象&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你對這幾篇文章頗有共鳴，想進一步學習具體做法，或是也想再一次從商業小說角度看看「績優團隊」的樣貌，那麼，極力推薦你讀一讀《&lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;》這本書，並且嘗試運用書中介紹的方法。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這次導讀會，請在參加之前，先自行做一下 pp.226～227 的【團隊評估】。&lt;/p&gt;
&lt;p&gt;還有，這次導讀會，會有一點噁心。在此先預告一下。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【職涯躍升書系導讀會】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ Part 1: 喚醒個人及團隊的成長意識 (計 6 冊)&lt;/p&gt;
&lt;p&gt;❷ Part 2: &lt;a href=&#34;//william-yeh.net/post/2022/08/career-reading-club-2/&#34;&gt;高效團隊的工作方法&lt;/a&gt; (計 2 冊)&lt;/p&gt;
&lt;p&gt;❸ Part 3: &lt;a href=&#34;//william-yeh.net/post/2022/11/career-reading-club-3/&#34;&gt;職場心理：觀點、期待、渴望&lt;/a&gt; (計 3 冊)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>圖表，要有重點訊息</title>
      <link>//william-yeh.net/post/2022/06/one-msg-per-slide/</link>
      <pubDate>Thu, 09 Jun 2022 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/06/one-msg-per-slide/</guid>
      
        <description>&lt;p&gt;月前看到君婷老師提的這則&lt;a href=&#34;https://www.facebook.com/elva.lee.752/posts/5372125532799861&#34;&gt;重大發現&lt;/a&gt;：「當你沒辦法 convince 對方的時候，那就想辦法 confuse 他。」&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/elva-20220505.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/elva-20220505.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;對於「塞一大堆無關緊要，但看起來好像很認真整理過的資料」這件事，我是感同身受的——尤其是職場的會議簡報。&lt;/p&gt;
&lt;p&gt;職場的會議簡報，下焉者，塞一大堆原始數據；中焉者，把數據整理為樸素的統計圖表；上焉者，會針對圖表的洞見予以錘鍊。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 上焉者的境界，可能需要一段時間訓練與即時回饋，恐非短期可奏效；但我發現，只要掌握一個&lt;strong&gt;逆向工作法&lt;/strong&gt;的小訣竅，就能找到改善中焉者表現的線索。&lt;/p&gt;
&lt;h2 id=&#34;金字塔原理的-so-what-觀點&#34;&gt;金字塔原理的 &amp;ldquo;so what?&amp;rdquo; 觀點&lt;/h2&gt;
&lt;p&gt;記得第一次看到這個訣竅，是從 Barbara Minto《&lt;a href=&#34;https://www.books.com.tw/products/0010645634&#34;&gt;金字塔原理&lt;/a&gt;》書中學來的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;先決定你想要利用圖表回答的問題，&lt;strong&gt;將答案當作標題&lt;/strong&gt;，然後選擇最適合的圖表格式來呈現該論點。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;務必確定圖表的標題直接表達它的內容&lt;/strong&gt;。標題可以是一個完整的句子，或是包含動詞的一句片語，這麼做讓你可以&lt;strong&gt;核對&lt;/strong&gt;圖表帶給觀眾的視覺印象是否符合你希望表達的內容。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同樣出自麥肯錫人、同樣在談金字塔原理的另一本書《&lt;a href=&#34;https://www.books.com.tw/products/0010928450&#34;&gt;邏輯思考的技術&lt;/a&gt;》，第四章舉了一個具體例子：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/logic-example.jpg&#34; alt=&#34;Source: 《邏輯思考的技術》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/logic-example.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: 《邏輯思考的技術》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這份圖表，只有把數據整理為樸素的時序表格及初級分類，但對讀者來說，如果未經解說，其實很難一眼看出作者為什麼要秀出這份表格：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;即使觀察相同的東西，由於觀察者有興趣或關心的事情不同，很可能會得出不同的 &amp;ldquo;so what?” 內容。&lt;/p&gt;
&lt;p&gt;不要以為「只要看到圖，應該就一目瞭然了」，因為那樣會變成把 &amp;ldquo;so what?” 全權交由接收者解釋。不可以認為「看了就會懂」而放任不管，&lt;strong&gt;明確表示出「總之，從這裡我們可以看出什麼」&lt;/strong&gt;，是非常重要的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這份圖表，缺少明確的 &amp;ldquo;so what?&amp;rdquo; 線索，充其量只是落於「中焉者」層次。&lt;/p&gt;
&lt;p&gt;因此，《&lt;a href=&#34;https://www.taaze.tw/products/11100687763.html&#34;&gt;麥肯錫新人培訓 7 堂課&lt;/a&gt;》的第七課，就明確提出以下這種「&lt;strong&gt;一張圖表、一個訊息&lt;/strong&gt;」範本供新人依循 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，內容包括「一個經過徹底調查，將所有資料&lt;strong&gt;結晶化&lt;/strong&gt;後的訊息，以及一張簡單表示相關情報的圖表」：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/one-message.jpg&#34; alt=&#34;Source: 《麥肯錫新人培訓 7 堂課》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/one-message.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: 《麥肯錫新人培訓 7 堂課》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;事先逆向思考這張圖表想傳達的 &amp;ldquo;so what?&amp;rdquo; 關鍵訊息是什麼，然後明確揭露在大標題或小標題上。我發現，只要掌握這個小訣竅，就有助於引導自己接下來該朝什麼方向去加工錘鍊，好讓圖表能夠支持這段 &amp;ldquo;so what?&amp;rdquo; 關鍵訊息。&lt;/p&gt;
&lt;h2 id=&#34;簡報大師的觀點&#34;&gt;簡報大師的觀點&lt;/h2&gt;
&lt;p&gt;以上都是麥肯錫人的觀點。那麼，簡報大師，尤其是視覺簡報大師、敘事簡報大師的觀點呢？就請 Nancy Duarte 及 Brent Dykes 兩位大師現身說法吧。&lt;/p&gt;
&lt;p&gt;Nancy Duarte 在《&lt;a href=&#34;https://www.books.com.tw/products/0010885500&#34;&gt;矽谷簡報女王用數據說出好故事&lt;/a&gt;》第六章，將圖表簡報頁面的標題再細分成「圖表標題」與「研究心得」兩部份，並主張：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;圖表標題要合乎&lt;strong&gt;事實&lt;/strong&gt;，保持&lt;strong&gt;中性&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;研究心得則是&lt;strong&gt;敘述&lt;/strong&gt;，從圖表中你得到的&lt;strong&gt;見解&lt;/strong&gt;，支持你如何看待數據呈現的&lt;strong&gt;問題&lt;/strong&gt;或&lt;strong&gt;機會&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/datastory.jpg&#34; alt=&#34;Source: 《矽谷簡報女王用數據說出好故事》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/datastory.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: 《矽谷簡報女王用數據說出好故事》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Brent Dykes 在《&lt;a href=&#34;https://www.books.com.tw/products/0010920682&#34;&gt;資料故事時代&lt;/a&gt;》第八章，主張要善用「解釋性」的標題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們常在圖表上寫&lt;strong&gt;描述性&lt;/strong&gt;的標題，而不是&lt;strong&gt;解釋性&lt;/strong&gt;的標題，因此浪費了那個寶貴的空間。&lt;/p&gt;
&lt;p&gt;你用資料講述故事時，必須把握機會，利用標題來&lt;strong&gt;強調每個圖像的重點&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/data-storytelling.jpg&#34; alt=&#34;Source: 《資料故事時代》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/data-storytelling.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: 《資料故事時代》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;看起來，兩位簡報大師的觀點，都與金字塔原理的 &amp;ldquo;so what?&amp;rdquo; 觀點相吻合。&lt;/p&gt;
&lt;h2 id=&#34;資料中立性的觀點&#34;&gt;資料中立性的觀點？&lt;/h2&gt;
&lt;p&gt;有些人可能認為，資料，就該是客觀中性的存在，應該讓樸素的統計圖表直出，讓數字自己跳出來說話，不該滲雜人為的誘導。&lt;/p&gt;
&lt;p&gt;真的是這樣嗎？&lt;/p&gt;
&lt;p&gt;資料固然不能造假，統計圖表也不能刻意施以歪曲事實的加工，但這不意味著我們就要棄守主觀詮釋的權力——這不是客觀理性，而是怠惰。&lt;/p&gt;
&lt;p&gt;尤其是職場的會議簡報。&lt;/p&gt;
&lt;p&gt;對於資料中立性議題，《&lt;a href=&#34;https://www.books.com.tw/products/0010792433&#34;&gt;２軸思考&lt;/a&gt;》說得好：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;工作上有大成就的人，其資料一定會加上自己的意見，或說偏見。製作資料時，一定要避免完全交由對方判斷而絲毫不滲入自己的意見。&lt;/p&gt;
&lt;p&gt;相反地，當自己是資訊接受者，就必須冷靜判斷，避免被這樣的「偏見」迷惑。&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/06/two-axes.jpg&#34; alt=&#34;Source: 《２軸思考》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/06/two-axes.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Source: 《２軸思考》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這也不禁讓我聯想到洪震宇在《&lt;a href=&#34;https://www.books.com.tw/products/0010846006&#34;&gt;精準寫作&lt;/a&gt;》提出的「魚骨寫作法」觀點。雖然不是針對資料圖表，但中心思想一樣適用：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我從學員的魚骨寫作練習發現，大家並不習慣這種&lt;strong&gt;逆向思考&lt;/strong&gt;的寫作方法。學員說，要想清楚再寫，是一大挑戰，因為&lt;strong&gt;沒有勇氣第一句就破題，總喜歡鋪陳迂迴。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;問題在於過去的寫作慣性：❶ 喜歡把重點、主題&lt;strong&gt;藏&lt;/strong&gt;在段落中，&lt;strong&gt;似乎怕人一眼看穿&lt;/strong&gt;。❷ 想法不聚焦，邊寫邊想、邊想邊寫；寫完後，沒有仔細消化想法，到底要呈現什麼主題？&lt;strong&gt;沒想法，就端不出魚頭句。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;或許，端得出想法，有勇氣破題，不僅是寫作，同樣也是職場會議簡報該學的功課吧。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;我講的不是 TED 或 keynote speech 那種簡報。忙碌的職場人士，並不需要時時刻刻追求加工到資訊圖表 (infographic) 等級，因此，我並不把「上焉者」標準設定到這個層次。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;當我還是職場新鮮人時，好像沒有人教過我要這麼做⋯⋯唉。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>很簡單的東西，也要單元測試嗎？</title>
      <link>//william-yeh.net/post/2022/05/need-for-unit-testing/</link>
      <pubDate>Tue, 24 May 2022 12:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/05/need-for-unit-testing/</guid>
      
        <description>&lt;p&gt;（改寫自公司內部 memo）&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Hi all engineers,&lt;/p&gt;
&lt;p&gt;上完一整天單元測試課程之後，有同事問我：「有沒有標準來決定要不要寫單元測試？」&lt;/p&gt;
&lt;p&gt;剛讀完劉潤《&lt;a href=&#34;https://www.books.com.tw/products/0010919211&#34;&gt;底層邏輯&lt;/a&gt;》的我，對於這類疑似「注射器」的問句格外敏感。雖然我可以瀟灑引述 &lt;a href=&#34;https://www.tenlong.com.tw/products/9789864344000&#34;&gt;&lt;em&gt;Working Effectively with Legacy Code&lt;/em&gt;&lt;/a&gt; 的說法「我毫無疑問地將『遺留程式碼』定義為『&lt;strong&gt;沒有編寫測試的程式碼&lt;/strong&gt;』」：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;沒有編寫測試的程式碼是糟糕的程式碼——不管我們多麼細心地編寫它們，不管它們有多漂亮、物件導向或封裝良好。有了測試，我們就能夠迅速、可驗證地修改程式碼的行為。沒有測試，我們就不知道修改後的程式碼，實際上是變得更好還是更糟。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但當下我還是決定先展開一場對話。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我：「我一時想不出來有沒有合適的標準，但我有一個簡單的 gut feeling 來判斷：如果我沒有把握證明這段程式碼會表現出該有的行為，那麼我就應該考慮替它加一段測試，用測試來表現出這段程式碼的確忠實表現出該有的行為，&lt;strong&gt;讓測試來說話&lt;/strong&gt;。」&lt;/p&gt;
&lt;p&gt;同事：「即使是很簡單的程式碼，也需要加單元測試嗎？這會不會太麻煩了？」&lt;/p&gt;
&lt;p&gt;我心中頓時浮現一個聲音：“如果你有 &lt;strong&gt;TDD (test-driven design)&lt;/strong&gt; 的觀念或紀律，就不會有此一問了。再簡單的程式碼，都會測試先行——何況，簡單的程式碼，對應的單元測試會很難嗎？如果很難很繁雜，那麼，或許這程式碼本身並沒有當初想像中那麼簡單。”&lt;/p&gt;
&lt;p&gt;但當下我還是決定繼續對話，先不要說教⋯⋯&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我：「能不能舉一個『簡單的程式碼』的例子？」&lt;/p&gt;
&lt;p&gt;同事：「就像某一個 function，它會先檢查輸入的日期格式，如果格式不是 &lt;code&gt;yyyy/mm/dd&lt;/code&gt; 就會失敗；如果格式對了，就會繼續往下做正事⋯⋯」&lt;/p&gt;
&lt;p&gt;我：「且慢，你所說的『如果格式不對，就會失敗』這句話，所謂的『失敗』是指什麼？」&lt;/p&gt;
&lt;p&gt;同事：「啊⋯⋯就是失敗呀！」&lt;/p&gt;
&lt;p&gt;我：「讓我們用程式語言的角度來講。你所謂的『失敗』，是指 return false 呢，還是 throw exception？」&lt;/p&gt;
&lt;p&gt;同事：「嗯，以這個例子來說，是 throw exception。」&lt;/p&gt;
&lt;p&gt;我：「好的，那麼，你怎麼證明，在遇到錯誤的日期格式時，你的程式碼真的會 throw exception？」&lt;/p&gt;
&lt;p&gt;同事靜默中⋯⋯&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我：「在談論寫不寫單元測試時，我想稍微區分一下問題，究竟是 ❶ 不會寫，或者是 ❷ 懶得寫？」&lt;/p&gt;
&lt;p&gt;我：「就以這一個例子來說，你知道該怎麼單元測試嗎？」&lt;/p&gt;
&lt;p&gt;同事靜默中⋯⋯&lt;/p&gt;
&lt;p&gt;我：「目前的主流單元測試框架，都有 &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.testtools.unittesting.assert.throwsexception&#34;&gt;Assert.ThrowsException&lt;/a&gt; 或 &lt;a href=&#34;https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.testtools.unittesting.assert.throwsexceptionasync&#34;&gt;Assert.ThrowsExceptionAsync&lt;/a&gt; 之類的設施去處理 exception，所以『❶ 不會寫』就不成立了。只剩下一個問題：『❷ 懶得寫』。」&lt;/p&gt;
&lt;p&gt;我：「你會在這段 function 一開頭的 doc comment 陳述說：『如果日期格式錯誤，會 throw XXX exception』嗎？」&lt;/p&gt;
&lt;p&gt;同事：「會。」&lt;/p&gt;
&lt;p&gt;（他大概不敢當面說不會，因為我兩個月前才寫過一篇內部 memo 講 &amp;ldquo;doc comment&amp;rdquo; 這件事。）&lt;/p&gt;
&lt;p&gt;我：「針對 throw exception 這個行為，既然你都已經花時間寫程式了，也都已經花時間寫 doc comment 了，為什麼不順手寫一小段單元測試來證明你的程式碼與 doc comment 是&lt;strong&gt;對齊&lt;/strong&gt;的，&lt;strong&gt;讓測試來說話&lt;/strong&gt;？」&lt;/p&gt;
&lt;p&gt;同事靜默中⋯⋯&lt;/p&gt;
&lt;p&gt;我：「而且，你寫的程式，不只是給現在的你自己看，不只是給 code reviewers 看，也會給幾個月後、甚至一兩年後接手維護的其他人看。萬一有一天，別人沒注意到『日期格式』這件事就改寫這段程式碼，你的程式又沒有單元測試的保護，你會不會擔心對方把你的程式改壞了？」&lt;/p&gt;
&lt;p&gt;同事靜默中⋯⋯&lt;/p&gt;
&lt;p&gt;我：「所以在單元測試課堂的開場致詞中，我強調：『&lt;strong&gt;單元測試是程式設計師的職業道德&lt;/strong&gt;』，就是這個意思。」&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;最後，請容我引述《&lt;a href=&#34;https://www.tenlong.com.tw/products/9787115467768&#34;&gt;修改軟件的藝術 (&lt;em&gt;Beyond Legacy Code&lt;/em&gt;)&lt;/a&gt;》裡面的金句：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在編寫程式碼之後才編寫測試，往往會發現程式碼難以測試，需要大量的清理來讓其可以測試，這可能會成為一個大工程。最好是一開始就編寫出&lt;strong&gt;可測試的程式碼&lt;/strong&gt;，而編寫可測試程式碼的最好方式是&lt;strong&gt;先編寫測試&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;沒法進行測試，則說明我有些設計問題需要重新進行思考。&lt;/p&gt;
&lt;p&gt;應該假設測試集是對整個用戶故事的完整定義。如果沒有用測試來描述一個行為，那麼這個行為很可能是錯的。&lt;strong&gt;任何沒有在測試集中體現的行為，都被視為不存在&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;測試集不僅驗證行為，而且描述行為。&lt;strong&gt;用測試描述行為，從而建立活的文檔&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;（PS. 以上情節，是根據實際對話加油添醋改編而成，請勿對號入座。）&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>推動改變的評估流程</title>
      <link>//william-yeh.net/post/2022/05/evaluation-process-for-changes/</link>
      <pubDate>Mon, 16 May 2022 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/05/evaluation-process-for-changes/</guid>
      
        <description>&lt;p&gt;在發出內部 memo 〈&lt;a href=&#34;//william-yeh.net/post/2022/04/passphrase-at-work/&#34;&gt;請珍惜你們學到的通關密語&lt;/a&gt;〉之後，收到這樣的來信：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;上周假日也花了點時間，將您從去年 11 月起寫給大家的每一封信都讀了一遍，雖然還不是全部內容都完全吸收和理解，但仍然覺得受益匪淺，真的非常感謝您願意無私的分享您過去許多很棒的經驗和想法。&lt;/p&gt;
&lt;p&gt;我很喜歡您用「通關密語」來形容這些語彙，突然覺得他們不再是死板板的方法論，而像是賦予了它們魔力，雖然不至於天真到認為知道這些詞彙和正確的應用，就能馬上變成具有超能力的 superman，但至少能讓我在規劃專案時更自信和從容。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;溢美之詞就摘錄到此。以下是正題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;同時，我雖然也很認同這些詞彙確實是「通關密語」，畢竟清楚和正確的定義可以有效減少許多溝通時的落差和模糊地帶，更快的凝聚共識，但前提是和具有同為專業的人溝通，我想這也是您迫切希望大家能盡快建立起這些基本常識的原因吧~&lt;/p&gt;
&lt;p&gt;但經驗豐富如您，一定也有許多，甚至是多數時候，都是在和沒有這些基本常識的人溝通吧！過去我就有許多這樣的經驗，不管面對公司主管或是面對客戶時，要求我產出一個四不像等情況。&lt;/p&gt;
&lt;p&gt;通常這種時候我的作法會是，不再堅持使用這些專業詞彙，而是解釋我產出的每個圖表的目的、用途和邏輯，但不幸的是還是有很多時候是無法被理解的，通常結局就是我需要照著對方的邏輯和方法，做出一個我自己無法認同的東西，但因為這才是利害關係人們可以接受的作法，所以為了可以溝通和讓專案順利進行，我還是會做。&lt;/p&gt;
&lt;p&gt;所以很想問問 William 您是否有類似的經驗呢？那您是怎麼面對和解決的呢?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這是大哉問。&lt;/p&gt;
&lt;p&gt;大體上，我會根據幾個角度迅速評估一下這整件事。&lt;/p&gt;
&lt;h2 id=&#34;-值不值得推動改變&#34;&gt;❶ 值不值得推動改變？&lt;/h2&gt;
&lt;p&gt;我常用 Impact Effort Matrix &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 這種簡易的兩軸思考工具，迅速定位這項改變是否值得。橫坐標是「可付諸實現的速度」，縱座標是「效益、影響」。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/05/impact-effort-matrix.jpg&#34; alt=&#34;Impact Effort Matrix&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/05/impact-effort-matrix.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Impact Effort Matrix&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;從圖上來看，若想推動的改變恰巧落在「1 號」位置，那就太幸運了，投資報酬率最高。萬一沒那麼幸運，落在「7 號」位置呢？&lt;/p&gt;
&lt;p&gt;引述《&lt;a href=&#34;https://www.amazon.cn/dp/B087M3LK7P&#34;&gt;麥肯錫＆波士頓解決問題方法和創造價值技巧&lt;/a&gt;》的精闢見解：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;確實，以「1 號」著手是正確的。&lt;/p&gt;
&lt;p&gt;那麼，「7 號」就被永久棄之不顧了嗎？並不是那樣的，「7 號」的建構化還做得不夠，還是一個大塊。所以，要花費時間把它再進一步細化，重新做成「1 號」那樣的小塊。這樣問題就容易解答了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;把這個擱置的「7 號」建構化為「1 號」，就是諮詢顧問展現本領的地方了。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果 Benefit/Impact 夠大，才值得進一步往下評估予以細化的 Effort。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;就以推動敏捷為例。「在導入敏捷的初期階段，首要焦點應放在 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Team&lt;/span&gt;
、&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Owner&lt;/span&gt;
 及 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Organization&lt;/span&gt;
 三者。」&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 可是，萬一組織現況無法在這三方面大刀闊斧改變呢？或者表面上似乎做了調整，但其實骨子裡的結構並沒有調整多少，又該如何是好？&lt;/p&gt;
&lt;p&gt;此刻，就需要暫時退後一步，設法把這個「7 號」的大塊任務細化到「1 號」這種層次——這也就是〈&lt;a href=&#34;//william-yeh.net/post/2022/03/prof-common-vocabulary/&#34;&gt;敏捷啟航的專業基礎：共同語彙&lt;/a&gt;〉一文的立論。&lt;/p&gt;
&lt;h2 id=&#34;-用-fogg-behavior-model--評估-effort&#34;&gt;❷ 用 Fogg Behavior Model  評估 Effort&lt;/h2&gt;
&lt;p&gt;我常用 &lt;a href=&#34;https://behaviormodel.org/&#34;&gt;Fogg Behavior Model&lt;/a&gt;: B = MAP 評估可能的 Effort。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;▶︎&lt;/strong&gt; &lt;strong&gt;Motivation&lt;/strong&gt;：當事人是否有改變的&lt;strong&gt;動機&lt;/strong&gt;？&lt;/p&gt;
&lt;p&gt;簡單一點的情況，我會用「洞」與「痛」、笨問題法則（為什麼非得如此如此⋯⋯）來判斷。 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;複雜一點的情況，我會用 TOC 抵制變革層次來判斷。 &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;▶︎&lt;/strong&gt; &lt;strong&gt;Ability&lt;/strong&gt;：當事人是否有改變的&lt;strong&gt;能力&lt;/strong&gt;？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;▶︎&lt;/strong&gt; &lt;strong&gt;Prompt&lt;/strong&gt;：當事人是否遇到推動改變的&lt;strong&gt;臨門一腳&lt;/strong&gt;？&lt;/p&gt;
&lt;p&gt;我常用「三不四人」來判斷：不舒服、不甘於、不能停、人背叛、人出現、人離開、人不理。 &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;B = MAP 具體的運用方法很多。對於當事人越了解，越能發掘洞見，找出有創意的方法。譬如說：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Motivation 可以訴諸權力關係，可以訴諸外部壓力，可以訴諸同儕壓力。&lt;/li&gt;
&lt;li&gt;Ability 可以訴諸教育訓練，可以訴諸教練手法，可以訴諸新陳代謝。&lt;/li&gt;
&lt;li&gt;Prompt 通常要訴諸善用局勢或創造局勢，或者⋯⋯機緣巧合的運氣。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就以推動敏捷為例。想推動敏捷，要改變的事情太多了，我會視情況，分階段推動具體的敏捷實踐措施。&lt;/p&gt;
&lt;p&gt;譬如說，剛嘗試 Scrum 的團隊，常會對我沒有主動帶領 Planning Poker 活動感到不解。我的觀點是，Planning Poker 要發揮效果，不至於淪為玩一玩而已，得先經過一番練習；練習要到位，卻可能會佔用過多時間。&lt;/p&gt;
&lt;p&gt;我的做法是，在初期，我寧可先對「工作透明化」這件事著墨。畢竟，「工作透明化」是 Benefit/Impact 非常大的，Motivation 是很強烈的，而 Planning Poker 則未必。所以，在裁適敏捷方法時，我會優先處理工作透明化，並多方製造 Prompt 的局勢；至於 Planning Poker 則看情況。&lt;/p&gt;
&lt;h2 id=&#34;-在這件事情上我有多少的主導權&#34;&gt;❸ 在這件事情上，我有多少的主導權？&lt;/h2&gt;
&lt;p&gt;主導權越高，就越不需要費神在 Effort 上。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/French_and_Raven%27s_bases_of_power&#34;&gt;French and Raven (1965)&lt;/a&gt; 將權力來源分為六種：強制權 (coercive power)、酬賞權 (reward power)、參照權 (referent power)、法職權 (legitimate power)、專家權 (expert power)、資訊權 (informational power)。平時善於經營權力基礎的深度及廣度，才容易推動改變。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上就是我快速評估推動改變的可能性及施力點的大致流程。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/&#34;&gt;改變的框架&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/12/process-and-metrics/&#34;&gt;改變／改革：流程與衡量指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ 推動改變的評估流程&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Impact Effort Matrix 又名 Benefit Effort Matrix、PICK Matrix，詳見這段&lt;a href=&#34;https://www.youtube.com/watch?v=ODr-xd8LsDI&#34;&gt;影片&lt;/a&gt;。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;出自〈&lt;a href=&#34;//william-yeh.net/post/2022/03/prof-common-vocabulary/&#34;&gt;敏捷啟航的專業基礎：共同語彙&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;「洞」與「痛」、笨問題法則，出自裘凱宇《&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;過好人生學&lt;/a&gt;》。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;TOC 抵制變革層次，詳見〈&lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/#限制理論的改變框架&#34;&gt;改變的框架&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;「三不四人」出自憲哥《&lt;a href=&#34;https://www.books.com.tw/products/0010752512&#34;&gt;人生準備 40% 就衝了！：超乎常人的目標執行力&lt;/a&gt;》。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>「改變」系列</title>
      <link>//william-yeh.net/series/change-series/</link>
      <pubDate>Mon, 16 May 2022 00:00:00 +0000</pubDate>
      
      <guid>//william-yeh.net/series/change-series/</guid>
      
        <description>&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/&#34;&gt;改變的框架&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/12/process-and-metrics/&#34;&gt;改變／改革：流程與衡量指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2022/05/evaluation-process-for-changes/&#34;&gt;推動改變的評估流程&lt;/a&gt;&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>向頂尖管顧公司學習的書</title>
      <link>//william-yeh.net/post/2022/05/learn-from-consulting-firms/</link>
      <pubDate>Sun, 08 May 2022 15:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/05/learn-from-consulting-firms/</guid>
      
        <description>&lt;p&gt;好友進了台灣前百大公司，最近有感而發：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;請問與麥肯錫有關的書籍，你會推薦哪些？&lt;/p&gt;
&lt;p&gt;在這間公司辛苦摸索幾個月，我才意識到，大家在使用的術語都來自麥肯錫。譬如：MECE、Story Line、論述 (Issue)⋯⋯等等。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;突然被洽詢這問題，其實有點心虛，畢竟我沒待過麥肯錫這類頂尖的管理顧問公司，不太有資格回答。不過，既然自己去年曾經系統閱讀過相關書籍（見〈&lt;a href=&#34;//william-yeh.net/post/2021/12/2021-retrospective/#問題解決的系統閱讀之旅&#34;&gt;2021 個人回顧&lt;/a&gt;〉一文），半年以來也一直運用書本裡的方法來推動改革，對於這些方法算是小有心得，因此，野人獻曝一下也無妨。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/05/problem-solving-books.jpg&#34; alt=&#34;「問題分析與解決」書單&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/05/problem-solving-books.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;「問題分析與解決」書單&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;朋友問的是「與麥肯錫有關的書籍」，如果範圍稍微擴大一點，連「與 BCG 有關的書籍」也納入，那麼，值得一讀的多產作者就有勝間和代、高杉尚孝、大嶋祥譽、內田和成、安宅和人⋯⋯等人。&lt;/p&gt;
&lt;p&gt;為了聚焦，我只挑選對「非以顧問為業」的初階至中階職場人士都能受益的書籍。&lt;/p&gt;
&lt;p&gt;註：以下書籍，有些可能要去圖書館找。&lt;/p&gt;
&lt;h2 id=&#34;入門篇職場基本功&#34;&gt;入門篇：職場基本功&lt;/h2&gt;
&lt;p&gt;文章開頭提到的 MECE、Story Line、論述 (Issue)⋯⋯等等，這幾本書都有提到，我甚至認為這幾本書所觸及的內容應該成為職場的通識教育。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大嶋祥譽：《&lt;a href=&#34;https://www.taaze.tw/products/11100741262.html&#34;&gt;麥肯錫精英最重視的 39 個工作習慣&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;大嶋祥譽：《&lt;a href=&#34;https://www.taaze.tw/products/11100687763.html&#34;&gt;麥肯錫新人培訓 7 堂課&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;高杉尚孝：《&lt;a href=&#34;https://www.books.com.tw/products/0010799231&#34;&gt;麥肯錫寫作技術與邏輯思考&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;安宅和人：《&lt;a href=&#34;https://www.books.com.tw/products/0010819191&#34;&gt;議題思考&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;進階篇思考框架&#34;&gt;進階篇：思考框架&lt;/h2&gt;
&lt;p&gt;市面上談思考框架的書很多，百科類的也不少，與其貪多嚼不爛，不如先確實吸收麥肯錫專家們萃取出來的精華。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大嶋祥譽：《&lt;a href=&#34;https://www.books.com.tw/products/0010679873&#34;&gt;麥肯錫新人邏輯思考 5 堂課&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;大嶋祥譽：《&lt;a href=&#34;https://www.books.com.tw/products/0010902799&#34;&gt;麥肯錫思考模型活用法&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;勝間和代：《&lt;a href=&#34;https://www.taaze.tw/products/11100153609.html&#34;&gt;新・知識生產術&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;高杉尚孝：《&lt;a href=&#34;https://www.books.com.tw/products/0010811194&#34;&gt;麥肯錫問題分析與解決技巧&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;進階篇金字塔原理&#34;&gt;進階篇：金字塔原理&lt;/h2&gt;
&lt;p&gt;以上書籍消化完畢後，若行有餘力意猶未盡，不妨啃一啃這幾本深度探討「金字塔原理」的書。不過，在此得先提醒你一個可能的副作用：日後當你遇到不符合「金字塔原理」的商業文書或簡報，極可能感到很不耐煩——「金字塔原理」一上身，可能就回不去了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Barbara Minto：《&lt;a href=&#34;https://www.books.com.tw/products/0010645634&#34;&gt;金字塔原理&lt;/a&gt;》(原理篇 + Workbook)&lt;/li&gt;
&lt;li&gt;照屋華子、岡田惠子：《&lt;a href=&#34;https://www.books.com.tw/products/0010928450&#34;&gt;邏輯思考的技術&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;進階篇顧問法寶&#34;&gt;進階篇：顧問法寶&lt;/h2&gt;
&lt;p&gt;即使不是身處管理顧問業，但他們的宏觀視角是很值得學習的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;名和高司：《&lt;a href=&#34;https://www.amazon.cn/dp/B087M3LK7P&#34;&gt;麥肯錫＆波士頓解決問題方法和創造價值技巧&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;徐瑞廷、黃菁媺：《&lt;a href=&#34;https://www.books.com.tw/products/0010901147&#34;&gt;BCG 問題解決力：一生受用的策略顧問思考法&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;大嶋祥譽：《&lt;a href=&#34;https://www.books.com.tw/products/0010809693&#34;&gt;麥肯錫精準提問術&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;</description>
      
    </item>
    
    <item>
      <title>請珍惜你們學到的通關密語</title>
      <link>//william-yeh.net/post/2022/04/passphrase-at-work/</link>
      <pubDate>Fri, 29 Apr 2022 17:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/04/passphrase-at-work/</guid>
      
        <description>&lt;p&gt;（改寫自公司內部 memo）&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Dear all 夥伴，&lt;/p&gt;
&lt;p&gt;過去三個月，我根據自己的職場經驗，以及我對大家的專業要求，安排許多課程及講座。從一系列 1:1 訪談中得知，不只是主管們動了起來，連小夥伴也開始試著實踐。我很欣慰。&lt;/p&gt;
&lt;p&gt;譬如說，送你們這群中階主管及資深工作者去接受專案管理培訓之後，我終於可以在大大小小會議上公然用專案管理語彙進行詢問與討論了，不必拐彎抹角替這些對我來說已經是「&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%BF%AB%E6%80%9D%E6%85%A2%E6%83%B3&#34;&gt;系統一&lt;/a&gt;」的管理切入點逐一解釋或比喻。&lt;/p&gt;
&lt;p&gt;The bar has been raised，這才像專業場域。&lt;/p&gt;
&lt;p&gt;有些人對我說，上了這些課程，他們才知道原來這些共同語彙是專業工作所必備的。只是也不免好奇：對於這些語彙，真的有必要那麼咬文嚼字嗎？&lt;/p&gt;
&lt;p&gt;譬如說，專案管理課堂上，老師一再強調表述形式：WBS 要以「&lt;strong&gt;名詞&lt;/strong&gt;、&lt;strong&gt;交付物&lt;/strong&gt;」表述，里程碑要以「&lt;strong&gt;時刻&lt;/strong&gt;、&lt;strong&gt;完成&lt;/strong&gt;」表述，任務要以「&lt;strong&gt;動詞&lt;/strong&gt;」表述。SBE 課堂上，老師也強調以「&lt;strong&gt;Given-When-Then 句型&lt;/strong&gt;」表述的需求。同仁們發現，不只是課堂演練時老師會要求這些細節，課程結束後，在工作上我也會繼續要求，故有此一問。&lt;/p&gt;
&lt;p&gt;我的觀點是，請把它們當成是專業領域的「通關密語」看待。理由有三。&lt;/p&gt;
&lt;h2 id=&#34;請試著培養英語文法意識&#34;&gt;請試著培養英語文法意識&lt;/h2&gt;
&lt;p&gt;企業講師 Lisa Lai 曾說：目前通行的管理理論及方法，多半來自美國。&lt;/p&gt;
&lt;p&gt;確實有道理。信手拈來幾個例子：科學管理之父泰勒 (&lt;a href=&#34;https://en.wikipedia.org/wiki/Frederick_Winslow_Taylor&#34;&gt;Taylor&lt;/a&gt;)，美國人；現代管理學之父&lt;a href=&#34;https://en.wikipedia.org/wiki/Peter_Drucker&#34;&gt;彼得．杜拉克&lt;/a&gt;，在美國成名；六標準差方法，源自美國；平衡計分卡，源自美國；OKR 之父 &lt;a href=&#34;https://en.wikipedia.org/wiki/John_Doerr&#34;&gt;John Doerr&lt;/a&gt;，美國人；OKR 思想源自 &lt;a href=&#34;https://en.wikipedia.org/wiki/Andrew_Grove&#34;&gt;Andrew Grove&lt;/a&gt;，成年即定居美國；專案管理學會 &lt;a href=&#34;https://www.pmi.org/&#34;&gt;PMI&lt;/a&gt;，總部在美國；Scrum 之父 Ken Schwaber 及 Jeff Sutherland，美國人。&lt;/p&gt;
&lt;p&gt;主流的管理理論及方法，幾乎很難沒有美國的蹤跡。語言是思想的重要載具，英語又可算是專業領域的世界語，因此，他們所發展出來的管理工具或思考工具，帶有濃厚的英語文法色彩也就不足為奇。 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;與中文相比，英語是個文法意識較嚴謹的語言，詞類時態語態形式分明。因此，在運用英語世界發展出來的工具時，請試著將頭腦切換至同一頻道，運用起來比較順暢，也更顯得內行——你是個與國際思維接軌的專業工作者。&lt;/p&gt;
&lt;h2 id=&#34;請展現內行氣&#34;&gt;請展現內行氣&lt;/h2&gt;
&lt;p&gt;勝間和代在《&lt;a href=&#34;https://www.books.com.tw/products/0010434249&#34;&gt;新．知識生產術&lt;/a&gt;》曾說過自己剛到麥肯錫工作時發生的慘痛經歷：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;對麥肯錫人來說，沒有遵循金字塔結構和 MECE 的文章，就等同於「外行人在閒聊」。於是，我的提案在格式階段就已經不被接受，更不用說是內容了。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2022/04/no-logic.jpg&#34; alt=&#34;「外行人在閒聊」&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2022/04/no-logic.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;「外行人在閒聊」&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;同理，未以「&lt;strong&gt;名詞&lt;/strong&gt;、&lt;strong&gt;交付物&lt;/strong&gt;」表述的 WBS、未以「&lt;strong&gt;時刻&lt;/strong&gt;、&lt;strong&gt;完成&lt;/strong&gt;」表述的里程碑、未以「&lt;strong&gt;動詞&lt;/strong&gt;」表述的任務，看在受過專業訓練的人眼中，就等同於「外行人在閒聊」。&lt;/p&gt;
&lt;p&gt;請大家展現「內行氣」。&lt;/p&gt;
&lt;h2 id=&#34;守破離&#34;&gt;守破離&lt;/h2&gt;
&lt;p&gt;學習新的事物，面對新的規範，不習慣是正常的，尤其又涉及用字遣詞。&lt;/p&gt;
&lt;p&gt;日本劍道素有「守、破、離」三個學習階段，金庸小說《神鵰俠侶》也提到劍魔獨孤求敗的武學造詣可分為幾個階段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;「凌厲剛猛，無堅不摧，弱冠前以之與河朔羣雄爭鋒。」&lt;/li&gt;
&lt;li&gt;「重劍無鋒，大巧不工。四十歲前恃之橫行天下。」&lt;/li&gt;
&lt;li&gt;「四十歲後，不滯於物，草木竹石均可為劍。自此精修，漸進於無劍勝有劍之境。」&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你還處於「守」這個階段，請堅持下去，把這個階段的要求操練純熟，變成自己的「系統一」。時機成熟了，再談「破」或是「離」。切忌好高騖遠自作聰明揠苗助長。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;對我來說，這些共同語彙，可說是專業領域的「通關密語」，使用得當，能夠展現「內行氣」。&lt;/p&gt;
&lt;p&gt;請珍惜你們學到的通關密語，並反覆在工作上下意識練習與實踐。&lt;/p&gt;
&lt;p&gt;如果你們還想知道更多專業的通關密語，我三月份導讀會的選書：功夫老師的《&lt;a href=&#34;https://www.books.com.tw/products/0010681486&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》是個不錯的起點。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【咬文嚼字的必要性】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2018/01/precise-expression/&#34;&gt;咬文嚼字的必要性（一）：用句型輔助思考&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2024/02/outcome-sentence-patterns/&#34;&gt;咬文嚼字的必要性（二）：階段性的預期成果設定&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ 請珍惜你們學到的通關密語&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;歐美系的思考框架或準則，很喜歡用「句型」式的步驟來引導思考，且多半都很注重文法的合式。我四年前的舊文〈&lt;a href=&#34;//william-yeh.net/post/2018/01/precise-expression/&#34;&gt;咬文嚼字的必要性（一）：用句型輔助思考&lt;/a&gt;〉就列了許多例子。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>經理人視角的敏捷通識課</title>
      <link>//william-yeh.net/post/2022/04/yves-agile-course/</link>
      <pubDate>Sat, 16 Apr 2022 18:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/04/yves-agile-course/</guid>
      
        <description>&lt;p&gt;[課程推薦文] &lt;strong&gt;&lt;a href=&#34;https://www.cwlearning.com.tw/course-set/109&#34;&gt;高效產出：突破資源限制的敏捷管理術&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;在商業世界，「敏捷」又變成流行語了。許多人風聞敏捷兩大流派 Scrum 及 Kanban 勾勒出來的美麗新世界，聽起來也頭頭是道，便以為敏捷轉型是輕而易舉、隨插即用、立竿見影的事。&lt;/p&gt;
&lt;p&gt;不過，真實世界不必然會像宣傳的那麼單純。等到真正開始嘗試時，遇到已知或未知的障礙，才開始懷疑人生，心生退轉。「敏捷轉型」這條路，怎麼走起來並沒有那麼敏捷呀？&lt;/p&gt;
&lt;p&gt;其實，「敏捷」這道處方未必有錯，錯的可能是病患未先接受過合適的衛教。&lt;/p&gt;
&lt;p&gt;坊間的敏捷衛教多半是由顧問、教練、證照供應商所提供，內容專業度是有的，但多半只呈現出乙方觀點，缺少甲方的第一人稱視角，尤其是切身之痛的視角。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;乙方觀點是：「你應該如何如何如何，不應該如何如何如何  (Thou shall&amp;hellip; Thou shall not&amp;hellip;)。」&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;甲方視角是：「你說得倒輕鬆。你又不是我，你不了解我的兩難與無奈。」&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不對等的視角，衛教效果有限，難怪甲方容易心生退轉。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;為了平衡，除了敏捷宣傳品或培訓教材之外，我們還需要另一種敏捷通識課，以第一人稱的經理人角度現身說法，告訴我們踏上敏捷轉型之旅之前，必須要先做好哪些心理建設。&lt;/p&gt;
&lt;p&gt;Yves 身為跨國企業經營者，帶領公司敏捷轉型，成為台灣、甚至東南亞的敏捷標竿企業。由他親自開講的這門敏捷通識課【&lt;a href=&#34;https://www.cwlearning.com.tw/course-set/109&#34;&gt;高效產出：突破資源限制的敏捷管理術&lt;/a&gt;】，格外具有說服力。畢竟這些內容，都是企業經營者親自神農嚐百草之後淬煉出來的精華，都是實證有效的作法。&lt;/p&gt;
&lt;p&gt;這門敏捷通識課，鎖定三個必須具備的認知：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;敏捷核心觀念與流程&lt;/strong&gt;。Yves 從 Scrum 及 Kanban 擷取最精華的觀念及流程，用傳統經理人也領會得了的方式講解。這 50 分鐘的內容，既可作為敏捷的先導知識，亦可作為經理人日後的提醒：勿因阻礙而忘卻敏捷導入的初衷。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;敏捷之旅的關卡&lt;/strong&gt;。Yves 從實務中挑選敏捷之旅的五大關卡：主管權力、角色分工、團隊決策、僵化思維、與市場脫節，以 40 分鐘逐一提供對應的處方，有些處方甚至不是一般敏捷教材會談到的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自管理的軟性修練&lt;/strong&gt;。任何轉型都需要考慮人性層面，轉型到對於「人性」格外細膩的敏捷世界更是如此，我們甚至可以說，絕大多數的敏捷轉型失敗，追根究柢就是對於「人性」議題的無意識或無能力。Yves 以公司經營者的切身經驗，提煉出「IMPACT 影響力」六字訣：I Message、Mindfulness、Positive Language、Active Listening、Curiosity Question、Target Alignment。我誠懇建議，有心推動敏捷轉型的經理人，應該認真聆聽這 50 分鐘的內容，並有耐心將它推廣並內化到整個組織裡，由經理人帶頭改變，才容易風行草偃。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;身為敏捷推手，我過去曾從 Yves 身上學習許多。我敢保證，這門線上課，絕對是值得常常拿出來溫習的敏捷通識課。&lt;/p&gt;
&lt;p&gt;如果你也想吸收 Yves 以企業經理人視角親自開講的敏捷通識課【&lt;a href=&#34;https://www.cwlearning.com.tw/course-set/109&#34;&gt;高效產出：突破資源限制的敏捷管理術&lt;/a&gt;】，現在到 2022-04-30 之前，你可以用以下優惠碼，享有更優惠的價格（早鳥優惠，再折價 300 元）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;課程：【&lt;a href=&#34;https://www.cwlearning.com.tw/course-set/109&#34;&gt;高效產出：突破資源限制的敏捷管理術&lt;/a&gt;】&lt;/li&gt;
&lt;li&gt;課程網址：&lt;a href=&#34;https://www.cwlearning.com.tw/course-set/109&#34;&gt;https://www.cwlearning.com.tw/course-set/109&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;優惠碼：&lt;code&gt;william300&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;優惠期限：2022-04-30&lt;/li&gt;
&lt;/ul&gt;</description>
      
    </item>
    
    <item>
      <title>敏捷啟航的專業基礎：共同語彙</title>
      <link>//william-yeh.net/post/2022/03/prof-common-vocabulary/</link>
      <pubDate>Sat, 05 Mar 2022 14:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2022/03/prof-common-vocabulary/</guid>
      
        <description>&lt;p&gt;LeSS 的 &amp;ldquo;&lt;a href=&#34;https://less.works/less/structure/scrummaster.html#ScrumMasterfocus&#34;&gt;Scrum Master focus over time&lt;/a&gt;&amp;rdquo; 一文主張，在導入敏捷的初期階段，首要焦點應放在 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Team&lt;/span&gt;
、&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Owner&lt;/span&gt;
 及 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Organization&lt;/span&gt;
 三者。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/scrum-master-focus-over-time.png&#34; alt=&#34;Scrum Master focus over time (from LeSS)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/scrum-master-focus-over-time.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Scrum Master focus over time (from LeSS)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;如果借用&lt;a href=&#34;https://www.mckinsey.com/business-functions/strategy-and-corporate-finance/our-insights/enduring-ideas-the-7-s-framework&#34;&gt;麥肯錫 7S 模型&lt;/a&gt;來分析這些初期的施力重點，不難發現，&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Organization&lt;/span&gt;
 的施力點大致可直接對應到 7S 的結構 (Structure) &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; ，至於 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Team&lt;/span&gt;
 及 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Owner&lt;/span&gt;
 的施力點，則是對應到 7S 的風格 (Style)、技能 (Skills)，甚至是共同價值觀 (Shared Values)。&lt;/p&gt;
&lt;p&gt;前者屬於硬性要素，較易理解，也較易實施；後者屬於軟性要素，較抽象，也不易立竿見影——這是敏捷啟航時需要面對的模糊題。&lt;/p&gt;
&lt;p&gt;面對軟性要素，除了像【敏捷原理與團隊塑造】工作坊這種典型的起手式，我發現，要促成根本改變，還得致力於「&lt;strong&gt;建立共同語彙&lt;/strong&gt;」。我還更進一步發現，這些共同語彙，不只是敏捷轉型需要，就算不談敏捷轉型，也一樣需要——這應該是各職能工作者都該有的專業基礎。&lt;/p&gt;
&lt;p&gt;其中，我最看重且亟需建立的共同語彙有三：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;5W1H&lt;/li&gt;
&lt;li&gt;WBS &amp;amp; MECE&lt;/li&gt;
&lt;li&gt;Working backwards collaboratively&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;5w1h&#34;&gt;5W1H&lt;/h2&gt;
&lt;p&gt;很多人視 5W1H 為過氣的老調。有趣的是，日本人對於經典的 5W1H 似乎情有獨鍾，出了幾本專書：《&lt;a href=&#34;https://www.books.com.tw/products/0010826002&#34;&gt;5W1H 超強思考術：你的所有問題，都可以靠 5W1H 解決！&lt;/a&gt;》、《&lt;a href=&#34;https://www.books.com.tw/products/0010840745&#34;&gt;5W1H 經典思考法：容易獲得成果的人都在用&lt;/a&gt;》。&lt;/p&gt;
&lt;p&gt;5W1H 不只是表面上「人事時地物」這麼單純的事項羅列，&lt;strong&gt;以事實為基礎&lt;/strong&gt;的行事態度才是它更深層的意涵。如果套用麥肯錫常用的「天空、下雨、雨傘」比喻，如果連「天空」這個事實層次都無法精準陳述，後續「下雨」的推論詮釋或是「雨傘」的行動決策，都是刻舟求劍。&lt;/p&gt;
&lt;p&gt;對敏捷的影響：若行事態度不以事實為基礎，等於是推翻了 Scrum 經驗主義三支柱當中的「檢視性 (&lt;a href=&#34;https://scrumguides.org/scrum-guide.html#inspection&#34;&gt;inspection&lt;/a&gt;)」，就別奢望能夠正確發揮 Scrum 的功效。&lt;/p&gt;
&lt;h2 id=&#34;wbs--mece&#34;&gt;WBS &amp;amp; MECE&lt;/h2&gt;
&lt;p&gt;工作分解 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; ，是專業工作者的基本功。磨練工作分解的技術，不管是 &lt;a href=&#34;https://en.wikipedia.org/wiki/Work_breakdown_structure&#34;&gt;WBS&lt;/a&gt; 形式還是 &lt;a href=&#34;https://en.wikipedia.org/wiki/MECE_principle&#34;&gt;MECE&lt;/a&gt; 意識，都能促成更專業的工作品質。&lt;/p&gt;
&lt;p&gt;對敏捷的影響：儘管敏捷並不講究在一開頭就進行鉅細彌遺的工作分解，但這並不代表敏捷就不需要工作分解技能了。此技能若不精熟，&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Planning&lt;/span&gt;
 或 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Refinement&lt;/span&gt;
 等活動很快就會卡關。&lt;/p&gt;
&lt;h2 id=&#34;working-backwards-collaboratively&#34;&gt;Working backwards collaboratively&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.amazon.com/dp/1250267595&#34;&gt;Working backwards&lt;/a&gt; 一詞，近年來因 Amazon 而聲名大噪，但這觀念其實相當古老。至少當我們還在學生時期，都懂得所謂的「逆推法」解題祕訣：面對數學證明題，有時候可以嘗試從待證明的結果往回推導個幾步；面對閱讀測驗，較有效率的做法，往往是先快速掃描後面的提問及選項，而不是傻傻地先閱讀冗長的文本。&lt;/p&gt;
&lt;p&gt;迷宮，未必非得從入口出發；從出口往回倒著走，可能更容易破關。&lt;/p&gt;
&lt;p&gt;Working backwards 是學生的法寶，只可惜到了職場，只有一流高效人士才懂得重拾這個絕招。像在專案管理領域中，WBS 就是最典型的 working backwards 應用：從「最終交付物」出發的分解結構 (a &lt;strong&gt;deliverable-oriented&lt;/strong&gt; hierarchical decomposition)。&lt;/p&gt;
&lt;p&gt;一流高效人士不只是懂得 working backwards，更懂得 working backwards &lt;strong&gt;collaboratively&lt;/strong&gt;。專案管理名著 &lt;a href=&#34;https://www.amazon.com/dp/0470177128&#34;&gt;&lt;em&gt;Work Breakdown Structures: The Foundation for Project Management Excellence&lt;/em&gt;&lt;/a&gt; 就說，WBS 不是 PM 一個人悶著頭生出來的，而是靠整個團隊的力量集結完成：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Who owns the WBS, who should be involved in developing it, who keeps it up to date? The answer to each of these is the &lt;strong&gt;project manager&lt;/strong&gt; and the &lt;strong&gt;project team&lt;/strong&gt;. [&amp;hellip;] who is responsible for the upkeep of the WBS? This is the responsibility of &lt;strong&gt;the entire project team&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不靠整個團隊的力量，很難做到 WBS 所講究的 “100% rule”。&lt;/p&gt;
&lt;p&gt;對敏捷的影響：不具備 working backwards collaboratively 的心態及技藝，就只是表面功夫的敏捷。就以敏捷圈常見的 &lt;a href=&#34;https://en.wikipedia.org/wiki/User_story&#34;&gt;user story&lt;/a&gt; 及 &lt;a href=&#34;https://en.wikipedia.org/wiki/Specification_by_example&#34;&gt;SBE&lt;/a&gt; 手法為例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;User story：經典句型 &amp;ldquo;&lt;a href=&#34;https://www.mountaingoatsoftware.com/blog/advantages-of-the-as-a-user-i-want-user-story-template&#34;&gt;who + what + why&lt;/a&gt;&amp;rdquo; 及 acceptance criteria 就是 working backwards，&lt;a href=&#34;https://www.agilealliance.org/glossary/three-cs/&#34;&gt;3C 要素&lt;/a&gt;當中的 &amp;ldquo;conversation&amp;rdquo; 就是 working collaboratively。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SBE：經典句型 “&lt;a href=&#34;https://martinfowler.com/bliki/GivenWhenThen.html&#34;&gt;given-when-then&lt;/a&gt;&amp;quot; 就是 working backwards，&lt;a href=&#34;https://www.agilealliance.org/glossary/three-amigos/&#34;&gt;3 amigos 活動&lt;/a&gt;就是 working collaboratively。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;交叉訓練&#34;&gt;交叉訓練&lt;/h2&gt;
&lt;p&gt;5W1H、WBS &amp;amp; MECE、working backwards collaboratively 這些共同語彙，不只是敏捷轉型需要，就算不談敏捷轉型，也一樣需要——這應該是各職能工作者都該有的專業基礎。&lt;/p&gt;
&lt;p&gt;檯面上沒有單一課程能深度涵蓋這三種語彙。我只好打組合牌，透過幾種課程的交叉訓練，從不同角度冶煉出這三種語彙的交集，再以我的【&lt;a href=&#34;//william-yeh.net/post/2022/06/career-reading-club-1/&#34;&gt;職涯躍升書系導讀會&lt;/a&gt;】做為佐料來提味：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;Git&lt;/th&gt;
          &lt;th&gt;專案管理入門&lt;/th&gt;
          &lt;th&gt;SBE&lt;/th&gt;
          &lt;th&gt;TDD&lt;/th&gt;
          &lt;th&gt;遠距工作講座&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;5W1H&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;WBS &amp;amp; MECE&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Working backwards&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Working collaboratively&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✓&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;教育訓練效果不彰，很多時候是因為：​❶ 主管自己都沒上過，❷ 沒有人致力於把它變成組織內的共同語彙，❸ 沒有人有 coaching 的意識與行動。​如此這般，就淪為徒具形式，船過水無痕。&lt;/p&gt;
&lt;p&gt;透過交叉訓練，應用場景自然而然擴大起來，再搭配正確的 coaching 意識與行動，將更有機會成為真正實質意義上的「共同語彙」。&lt;/p&gt;
&lt;h2 id=&#34;整土&#34;&gt;整土&lt;/h2&gt;
&lt;p&gt;這些共同語彙一旦真正建立起來，許多 Scrum 元素就顯得理所當然。&lt;/p&gt;
&lt;p&gt;Scrum 跑不順，不見得是 Scrum 的錯。畢竟 Scrum 是個篇幅 20 頁的擴大機，原本的天籟會增益，反之——噪音亦然。&lt;/p&gt;
&lt;p&gt;Scrum 懷璧其罪很久了。&lt;/p&gt;
&lt;p&gt;在敏捷啟航之前，花點時間處理這些軟性要素，在組織中種下這些共同語彙，把硬土、淺土、雜土整理成好土，整理成易於滋養敏捷的環境吧。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      Scrum master 培訓系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2021/03/train-new-scrum-master/&#34;&gt;如何訓練一個新的 Scrum master？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/09/deliberate-practice-for-agile/&#34;&gt;敏捷之途無他，刻意練習而已矣！&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2021/07/revisit-psm1/&#34;&gt;Scrum 認證模擬測驗的兩項啟發&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ 敏捷啟航的專業基礎：共同語彙&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;即使 Kanban 方法是傳説中一開始對既有組織結構衝擊最小，且明文宣稱 “Start with what you do now“ 及 “Initially, respect current processes, roles, responsibilities, and job titles”，但根據 &lt;a href=&#34;https://www.amazon.com/dp/0985305193&#34;&gt;&lt;em&gt;Kanban from the Inside&lt;/em&gt;&lt;/a&gt; 一書的說法，Kanban 最輕量的導入手法 “The Sustainability Agenda” 當中，就包含 ① Visualize, ④ Make Policies Explicit, ⑤ Implement Feedback Loops 這三項 Transparency 實踐手法——說實話，這未必是小小的衝擊！如果借用&lt;a href=&#34;https://www.mckinsey.com/business-functions/strategy-and-corporate-finance/our-insights/enduring-ideas-the-7-s-framework&#34;&gt;麥肯錫 7S 模型&lt;/a&gt;來分析這些初期的施力重點，可說是從 7S 的體制 (Systems) 這項硬性要素及風格 (Style) 這項軟性要素切入。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;請參考〈&lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Scrum master 培訓系列</title>
      <link>//william-yeh.net/series/scrum-master-training/</link>
      <pubDate>Sat, 05 Mar 2022 00:00:00 +0000</pubDate>
      
      <guid>//william-yeh.net/series/scrum-master-training/</guid>
      
        <description>&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2021/03/train-new-scrum-master/&#34;&gt;如何訓練一個新的 Scrum master？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/09/deliberate-practice-for-agile/&#34;&gt;敏捷之途無他，刻意練習而已矣！&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2021/07/revisit-psm1/&#34;&gt;Scrum 認證模擬測驗的兩項啟發&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2022/03/prof-common-vocabulary/&#34;&gt;敏捷啟航的專業基礎：共同語彙&lt;/a&gt;&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>2021 個人回顧</title>
      <link>//william-yeh.net/post/2021/12/2021-retrospective/</link>
      <pubDate>Tue, 28 Dec 2021 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2021/12/2021-retrospective/</guid>
      
        <description>&lt;p&gt;年初，從外商被挖腳到台商；年末，又再被挖腳到另一間台商。&lt;/p&gt;
&lt;p&gt;我常笑著說：今年，好像都在消費我在 &lt;a href=&#34;//william-yeh.net/post/2019/12/2019-retrospective/&#34;&gt;2019&lt;/a&gt;～&lt;a href=&#34;//william-yeh.net/post/2020/12/2020-retrospective/&#34;&gt;2020&lt;/a&gt; 年間外商經驗的戰備存糧。&lt;/p&gt;
&lt;p&gt;到了年終，又開始要做個總回顧，再對來年許願。去除一些不便揭露的事情，以下是簡單的回顧。&lt;/p&gt;
&lt;h2 id=&#34;補血課程&#34;&gt;補血課程&lt;/h2&gt;
&lt;p&gt;這一年，由於 COVID-19 因素，參加的實體課程，就只有公司舉辦的這兩場內訓，而且都是國外課程的中文化版本，很值得推薦：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.harment.com/trainShow-21-26-133-19.html&#34;&gt;勁道領導 (Fierce Conversations)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://doortraining.com/virtual-solutions/accountability-builder/&#34;&gt;Accountability Builder&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這一年，我上的多半是線上課程。我漸漸不追求 100% 完課，反而視為書本之外的另一種素材，只要其中某些片段能夠引為己用，就算值得。畢竟，我們都不見得需要 100% 讀完一整本書，為什麼我們需要把一門線上課 100% 上完？&lt;/p&gt;
&lt;p&gt;就以我今年重點修練科目「金字塔原理」為例，除了書本之外，在 Bryan 的《&lt;a href=&#34;https://shop.darencademy.com/product/view/id/98&#34;&gt;知識型商品的文案寫作課&lt;/a&gt;》線上課程也聽到了 26 分鐘的相關內容，在張敏敏的《&lt;a href=&#34;https://www.dada-master.com/lesson/91&#34;&gt;敏捷溝通力&lt;/a&gt;》線上課程也有 14 分鐘，里茲螞蟻《&lt;a href=&#34;https://vclass.voicetube.com/classes/leedsmayi-communication&#34;&gt;三步驟邁向進階英文口說&lt;/a&gt;》更是到處都是這種論述結構。有機會從更多角度去看這主題，滿有趣的。&lt;/p&gt;
&lt;p&gt;我不追求 100% 完課。話雖如此，但當七月初收到 Udemy 這樣的通知，還是小小虛榮了一下。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/12/udemy-statistics.jpg&#34; alt=&#34;Udemy 超過 8 小時&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/12/udemy-statistics.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Udemy 超過 8 小時&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;演講及授課&#34;&gt;演講及授課&lt;/h2&gt;
&lt;p&gt;今年，由於 COVID-19 因素，再加上自覺已經過了能夠恣意 &lt;del&gt;跑趴&lt;/del&gt; 出沒 社群活動的人生階段，婉拒許多邀約，只接了一場公開工作坊：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/&#34;&gt;從系統思考角度讀《獨角獸專案》&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;反之，如果是在公司的上班時間、用公司的場地舉辦活動，安排起來較有餘裕，也就順勢辦了好幾場：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在Ｋ公司內部 Agile Guild 舉辦一場【&lt;a href=&#34;//william-yeh.net/post/2021/07/revisit-psm1/&#34;&gt;Scrum WHAT &amp;amp; WHY 討論：以 Scrum 認證模擬測驗為素材&lt;/a&gt;】小活動&lt;/li&gt;
&lt;li&gt;在Ｋ集團內部讀書會舉辦一場【&lt;a href=&#34;//william-yeh.net/post/2021/02/the-managers-path-review/&#34;&gt;《經理人之道》&lt;/a&gt;導讀會】&lt;/li&gt;
&lt;li&gt;在Ｐ集團內部舉辦兩場【Agile Workshop / 敏捷原理與團隊塑造】工作坊&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/12/agile-workshop-20211210.png&#34; alt=&#34;Agile Workshop @ PChome&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/12/agile-workshop-20211210.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Agile Workshop @ PChome&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這次 Agile Workshop 算是初步成功將 &lt;a href=&#34;https://shop.darencademy.com/product/view/id/95&#34;&gt;OKR&lt;/a&gt;、&lt;a href=&#34;https://www.books.com.tw/products/0010855790&#34;&gt;OGSM&lt;/a&gt;、JTBD 部份精華融合到 impact mapping 當中了。也算了卻一樁塵封三年的心願。&lt;/p&gt;
&lt;p&gt;尤其當我看到某團隊在上完課之後，自組織弄出這樣的 Scrum 空間，內心感動難以言喻。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/12/sprint-0.jpg&#34; alt=&#34;某團隊的 Sprint 0 環境&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/12/sprint-0.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;某團隊的 Sprint 0 環境&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;問題解決的系統閱讀之旅&#34;&gt;問題解決的系統閱讀之旅&lt;/h2&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2021/03/train-new-scrum-master/&#34;&gt;如何訓練一個新的 Scrum master？&lt;/a&gt;〉一文曾提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;視團隊狀況及他的信心指數，我會開始逐步請他主持某些 Scrum 會議。&lt;/p&gt;
&lt;p&gt;至於 retrospective 則可能是最具挑戰性的。這階段，能否搭配更即時更精準的事後回饋，甚至事前就進行沙盤推演，是成敗關鍵。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在我自己的 Agile Workshop 中，第二日原本就有一個名為「retrospective 進階篇」的單元。不過，隨著經驗累積，深感有重新設計的必要。因此，我默默展開一場「問題分析與解決」的系統閱讀之旅。&lt;/p&gt;
&lt;p&gt;老書新書讀完一輪，思維相互碰撞，漸漸忘記原本的動機「訓練 Scrum master」，轉而鑽研到更深層的課題去了。此中有真意，欲辨已忘言。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/12/problem-solving-books.jpg&#34; alt=&#34;「問題分析與解決」書單&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/12/problem-solving-books.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;「問題分析與解決」書單&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這堆書籍當中，我對於其中兩類格外有感。&lt;/p&gt;
&lt;p&gt;① 當了一陣子幕僚，總算比較看得懂溫老的書《&lt;a href=&#34;https://www.books.com.tw/products/0010711585&#34;&gt;顧問成功的祕密&lt;/a&gt;》。引述一段君婷老師的精闢評論：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/12/consultant-comment.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/12/consultant-comment.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;溫老的書狀似戲謔，但這陣子周遊列國的經歷告訴我，這是真的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;顧問第一法則：不管客戶怎麼跟你說，一定有問題。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;顧問第二法則：無論問題乍看之下如何，問題一定出在人身上。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;顧問第四法則：如果別人沒有雇用你，千萬不要去解決他們的問題。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;費雪基本原則：你現在適應得愈好，你的適應性就變得愈差。「顧問是比較不能適應目前的一種人，這使得他們的適應性比較強。」&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;② 像《&lt;a href=&#34;https://www.books.com.tw/products/0010645634&#34;&gt;金字塔原理&lt;/a&gt;》這種經典還是該用力啃一啃。畢竟，金字塔原理的牛肉，可不只有 &lt;a href=&#34;https://wiki.mbalib.com/zh-tw/MECE%E5%88%86%E6%9E%90%E6%B3%95&#34;&gt;MECE&lt;/a&gt; 及 why so/so what 而已，許多洞見都被稀釋書籍草草帶過。&lt;/p&gt;
&lt;p&gt;認真啃了這類書籍，刻意練習須臾，驚覺勝間和代在《&lt;a href=&#34;https://www.taaze.tw/products/11100153609.html&#34;&gt;新．知識生產術&lt;/a&gt;》預告過的副作用真的也上身了。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/12/no-logic.jpg&#34; alt=&#34;「外行人在閒聊」&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/12/no-logic.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;「外行人在閒聊」&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;周遊列國其致一也&#34;&gt;周遊列國，其致一也&lt;/h2&gt;
&lt;p&gt;這幾年在職場上周遊列國的經歷，讓我對王羲之《&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E8%98%AD%E4%BA%AD%E9%9B%86%E5%BA%8F&#34;&gt;蘭亭集序&lt;/a&gt;》這句話格外有感：「雖世殊事異，所以興懷，其致一也。」&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:10em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/12/same-feeling.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/12/same-feeling.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;不同的是，國家、產業、公司、產品線、團隊、制度、文化、技能。&lt;/p&gt;
&lt;p&gt;相同的是，「不管客戶怎麼跟你說，一定有問題」及「無論問題乍看之下如何，問題一定出在人身上」這兩大顧問法則，不斷上演。&lt;/p&gt;
&lt;p&gt;相同的是，系統思考呈現出來的系統基模，也不斷現蹤。&lt;/p&gt;
&lt;p&gt;很寫實的是，我在兩屆 &lt;a href=&#34;https://devopsdays.tw/&#34;&gt;DevOpsDays Taipei&lt;/a&gt; 帶的兩場系統思考工作坊，推演出來的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD&lt;/a&gt;，無心插柳，在日後周遊列國的旅程中都親眼目睹：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;我在 2018 年根據《&lt;a href=&#34;https://www.books.com.tw/products/0010819137&#34;&gt;The DevOps Handbook 中文版&lt;/a&gt;》第七章設計的&lt;a href=&#34;//william-yeh.net/post/2018/09/thinking-weight-training/&#34;&gt;系統思考工作坊&lt;/a&gt;，描繪出來的&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype#Fixes_that_fail&#34;&gt;飲鴆止渴&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype#Limits_to_growth&#34;&gt;成長上限&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype#Shifting_the_burden&#34;&gt;捨本逐末&lt;/a&gt;動態結構，簡直就是某公司某團隊的寫照。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我在今年根據《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》設計的&lt;a href=&#34;//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/&#34;&gt;系統思考工作坊&lt;/a&gt;，描繪出來的&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype#Shifting_the_burden&#34;&gt;捨本逐末&lt;/a&gt;動態結構，簡直就是某公司的寫照。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;系統思考這門直探本質的技藝，很值得好好掌握。&lt;/p&gt;
&lt;p&gt;也很慶幸看到這些年周遊列國的經歷及探索沒有白費，若干本質逐漸結晶固化下來。&lt;/p&gt;
&lt;p&gt;吉卜林：「僅知英國的人，如何能知道英國呢？」&lt;/p&gt;
&lt;h2 id=&#34;教練的必要&#34;&gt;教練的必要&lt;/h2&gt;
&lt;p&gt;周遊列國也讓我看到：敏捷不起來，很多時候是因為輕忽技術實踐，甚至漠視。&lt;/p&gt;
&lt;p&gt;就像《&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E7%81%8C%E7%AF%AE%E9%AB%98%E6%89%8B&#34;&gt;灌籃高手&lt;/a&gt;》安西教練的犀利質問：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「有人教導基本動作嗎？」&lt;/p&gt;
&lt;p&gt;「每個人都各打各的，完全不團結。」&lt;/p&gt;
&lt;p&gt;「球隊的教練到底在搞什麼？」&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/12/basic-training.png&#34; alt=&#34;「基本動作」&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/12/basic-training.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;「基本動作」&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;我也漸漸體會到：其實，中高階主管也極需要 coaching。&lt;/p&gt;
&lt;p&gt;我甚至懷疑：他們當年真的上過他們現在要初階主管接受過的培訓嗎？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;沒有人做，就由我來起個頭吧。誰叫我現在的職稱有一個 &amp;ldquo;agile coach&amp;rdquo; 字眼呢？&lt;/p&gt;
&lt;p&gt;技術面的培訓，已經逐步規劃與執行。&lt;/p&gt;
&lt;p&gt;至於非技術面的培訓，一部份打算以導讀會的形式進行。目前的戰備存糧計有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2021/02/the-managers-path-review/&#34;&gt;經理人之道&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://williampjyeh.notion.site/cd42e217271d454aac9411b0c6fc84c7&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2020/10/unicorn-project-review/&#34;&gt;獨角獸專案&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010721292&#34;&gt;左思右想&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010865668&#34;&gt;高產出的本事&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;勝間和代 or 麥肯錫系列的某本書&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;薩提爾教練模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://williampjyeh.notion.site/eeb5d579610b40128755a17adf983c51&#34;&gt;給力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⋯⋯&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;給自己一個 2022 的小挑戰，也算是刻意練習「金字塔原理」12 回合 (是的，我以金字塔原理來進行每一場導讀會)。&lt;/p&gt;
&lt;h2 id=&#34;2022-許願&#34;&gt;2022 許願&lt;/h2&gt;
&lt;p&gt;2022 年，希望自己能做到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每個月辦一場 2hr 導讀會。&lt;/li&gt;
&lt;li&gt;繼續更深度的本質修練。&lt;/li&gt;
&lt;li&gt;繼續增進商務英語聽說能力。&lt;/li&gt;
&lt;li&gt;開放冒險選項。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就醬。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Scrum 認證模擬測驗的兩項啟發</title>
      <link>//william-yeh.net/post/2021/07/revisit-psm1/</link>
      <pubDate>Sun, 11 Jul 2021 16:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2021/07/revisit-psm1/</guid>
      
        <description>&lt;p&gt;公司內 agile guild 定期聚會輪到我來主持了。這次我打算帶一場「Scrum WHAT &amp;amp; WHY 討論：以 Scrum 認證模擬測驗為素材」的小活動。&lt;/p&gt;
&lt;p&gt;理論上來說，「Scrum WHAT &amp;amp; WHY」的終極答案應該是來自 &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt;，不過，這份輕薄短小的文件就像成文法典法條，不易引發實務聯想。反之，Scrum 認證模擬測驗可說是非常好的 Scrum 靈魂拷問材料，尤其是對略有實務經驗的人來說，內容可說是拳拳到肉，足以激盪小組討論的火花。若只以功利角度看待，就太可惜了。&lt;/p&gt;
&lt;p&gt;有圖為證：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/07/psm1-feedback.png&#34; alt=&#34;2021-07-21 活動迴響&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/07/psm1-feedback.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;2021-07-21 活動迴響&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&#34;https://www.scrum.org/professional-scrum-certifications&#34;&gt;Scrum.org 系統的證照&lt;/a&gt;是永久有效的。儘管自己早在 2018 年就有 &lt;a href=&#34;https://www.scrum.org/user/437709&#34;&gt;PSM 1 證照&lt;/a&gt;，卻也想趁此機會再檢驗一下自己對於 Scrum 的認識。因此，上網找了一份免費的、有針對 &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2020 版做過更新的「&lt;a href=&#34;https://www.thescrummaster.co.uk/assessments/professional-scrum-master-i-psm-i-practice-assessment/&#34;&gt;PSM 1 模擬測驗&lt;/a&gt;」，40 道題目，限時 30 分鐘，份量為正式測驗的一半。&lt;/p&gt;
&lt;p&gt;結果還頗令人欣慰。和三年前相比，這次讀題變快，思考更少，分數也提高了（儘管這並非官方提供的模擬題） —— 或許也跟去年自己整理過一系列 &lt;a href=&#34;//william-yeh.net/post/2020/07/pbr-in-a-nutshell/&#34;&gt;&lt;em&gt;Essence of Scrum&lt;/em&gt;&lt;/a&gt; 文章有關吧。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/07/psm1-sim-test.png&#34; alt=&#34;PSM 1 模擬測驗&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/07/psm1-sim-test.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;PSM 1 模擬測驗&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;答錯的題目中，有兩題滿有意思的，值得特別探討。&lt;/p&gt;
&lt;p&gt;警告：以下有雷。如果你也打算去嘗試這份「&lt;a href=&#34;https://www.thescrummaster.co.uk/assessments/professional-scrum-master-i-psm-i-practice-assessment/&#34;&gt;PSM 1 模擬測驗&lt;/a&gt;」，請先去考一考，考完了再回來讀本文。&lt;/p&gt;
&lt;h2 id=&#34;sprint-goal&#34;&gt;Sprint Goal&lt;/h2&gt;
&lt;p&gt;這一題是關於 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Goal&lt;/span&gt;
 的：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/07/psm1-q34.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/07/psm1-q34.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;請先思考幾秒鐘：你認為答案會是什麼？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;讓我們看看 &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 怎麼說。2017 版是如此描述 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Sprint Goal is an objective set for the Sprint that can be met through the implementation of Product Backlog.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2020 版則是如此描述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Sprint Goal is the single objective for the Sprint.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;從 &amp;ldquo;an objective&amp;rdquo; 字眼替換成 &amp;ldquo;the single objective&amp;rdquo;，可看出背後想要強調的意涵。&lt;/p&gt;
&lt;p&gt;因此，面對這題，在作答時，原本我還想把 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Goal&lt;/span&gt;
 標準放寬，結果就是⋯⋯&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/07/psm1-sprint-goal.png&#34; alt=&#34;PSM 1 模擬測驗：Goal&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/07/psm1-sprint-goal.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;PSM 1 模擬測驗：Goal&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;PSM 可是非常強調原汁原味的，在核心理念上毫不妥協。&lt;/p&gt;
&lt;h2 id=&#34;scrum-master-as-a-management-role&#34;&gt;Scrum master as a management role&lt;/h2&gt;
&lt;p&gt;這一題是關於 management 的：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/07/psm1-q33.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/07/psm1-q33.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;請先思考幾秒鐘：你認為答案會是什麼？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;讓我們看看 &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 怎麼說。2017 版對於 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
 及 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Master&lt;/span&gt;
 的描述是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum Teams are self-organizing and cross-functional.&lt;/p&gt;
&lt;p&gt;The Scrum Master is a servant-leader for the Scrum Team. The Scrum Master is responsible for promoting and supporting Scrum as defined in the Scrum Guide.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2020 版則是如此描述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(Scrum Teams) are also self-managing, meaning they internally decide who does what, when, and how.&lt;/p&gt;
&lt;p&gt;Scrum Masters are true leaders who serve the Scrum Team and the larger organization. The Scrum Master is accountable for establishing Scrum as defined in the Scrum Guide. The Scrum Master is accountable for the Scrum Team’s effectiveness.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;從 “self-organizing” 字眼替換成 “self-managing”，從 “servant-leader” 字眼替換成 “true leaders”，從 “responsible” 字眼替換成 “accountable”，可看出背後想要強調的意涵。&lt;/p&gt;
&lt;p&gt;看了以上論述，你認為這題的答案會是什麼？&lt;/p&gt;
&lt;p&gt;在作答時，原本我還想比照一般 agile 陣營或多或少有點輕視管理陣營的傾向或潛規則，選個貌似政治正確的答案，結果就是⋯⋯&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/07/psm1-sm-management.png&#34; alt=&#34;PSM 1 模擬測驗：management&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/07/psm1-sm-management.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;PSM 1 模擬測驗：management&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;PSM 可是非常強調 &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Master&lt;/span&gt;
 崇高價值的，在核心理念上毫不妥協。&lt;/p&gt;
&lt;p&gt;關於這議題，我認為 LeSS 的 &lt;a href=&#34;https://less.works/less/management/role-of-manager&#34;&gt;Role of Manager&lt;/a&gt; 論述得相當精闢，尤其是以下這張圖，清楚標示出 Scrum master 的 &amp;ldquo;manager&amp;rdquo; 幅度，值得一讀：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/07/less-role-responsibilities.png&#34; alt=&#34;Role of Manager (LeSS perspective)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/07/less-role-responsibilities.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Role of Manager (LeSS perspective)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;值得精讀的文獻&#34;&gt;值得精讀的文獻&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2020 版真的很值得精讀，細細體會它如何將敏捷的「本質」闡述得更精準。&lt;/p&gt;
&lt;p&gt;建議你：做完「&lt;a href=&#34;https://www.thescrummaster.co.uk/assessments/professional-scrum-master-i-psm-i-practice-assessment/&#34;&gt;PSM 1 模擬測驗&lt;/a&gt;」後，請確實檢討一次：針對每一題，盡量從 &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 找出佐證或反證的根據。如此一來，你會更貼近 Scrum 的靈魂。&lt;/p&gt;
&lt;p&gt;更建議 Scrum master：請試著在你的團隊中舉辦幾次這類的討論活動。若引導得當，你們會在饒富趣味的觀點辯論中，逐漸凝聚團隊運作的共識。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      Scrum master 培訓系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2021/03/train-new-scrum-master/&#34;&gt;如何訓練一個新的 Scrum master？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/09/deliberate-practice-for-agile/&#34;&gt;敏捷之途無他，刻意練習而已矣！&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ Scrum 認證模擬測驗的兩項啟發&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2022/03/prof-common-vocabulary/&#34;&gt;敏捷啟航的專業基礎：共同語彙&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>企業能否吸引專業人士？看這 14 點。</title>
      <link>//william-yeh.net/post/2021/07/ic-needs/</link>
      <pubDate>Tue, 06 Jul 2021 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2021/07/ic-needs/</guid>
      
        <description>&lt;p&gt;時代不斷進步，競爭日益激烈，專業工作者的門檻也愈來愈高。我們對 individual contributor 專業能力的期待是高的，相對的，這群人的自我意識自然也不低。&lt;/p&gt;
&lt;p&gt;企業挑人才，人才也挑企業。&lt;/p&gt;
&lt;p&gt;問題來了：企業能否吸引專業人士？&lt;/p&gt;
&lt;p&gt;我從兩本書，摘錄出個人比較心儀的優勢導向、人本導向觀點。&lt;/p&gt;
&lt;h2 id=&#34;巴金漢如是說&#34;&gt;巴金漢如是說&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.marcusbuckingham.com/&#34;&gt;Marcus Buckingham&lt;/a&gt; 常發表領導力與人力發展的獨到見解，是我相當佩服的人。像他在 2017 年領袖高峰會演講 &lt;a href=&#34;https://globalleadership.org/videos/leading-others/reinventing-performance-management-2&#34;&gt;&lt;em&gt;Reinventing Performance Management&lt;/em&gt;&lt;/a&gt; 提出的架構，就是我團隊領導的圭臬，以前我還將它製成卡片，用於 one on one 的引導或教練活動。&lt;/p&gt;
&lt;p&gt;他 2019 年的書《&lt;a href=&#34;https://www.books.com.tw/products/0010832091&#34;&gt;關於工作的 9 大謊言&lt;/a&gt;》滿有意思的，可說是對他過往相關論述的總整理。不管你對他熟不熟悉，請先瀏覽作者提出的「九大謊言」清單，思考一下你該如何反駁？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;謊言＃1　人們在意他們為哪家公司工作&lt;/li&gt;
&lt;li&gt;謊言＃2　最佳計畫致勝&lt;/li&gt;
&lt;li&gt;謊言＃3　第一流的公司把目標層層下達&lt;/li&gt;
&lt;li&gt;謊言＃4　最優秀的人才是通才&lt;/li&gt;
&lt;li&gt;謊言＃5　人們需要反饋&lt;/li&gt;
&lt;li&gt;謊言＃6　人們能夠可靠評量他人&lt;/li&gt;
&lt;li&gt;謊言＃7　人們具有潛力&lt;/li&gt;
&lt;li&gt;謊言＃8　工作與生活平衡最重要&lt;/li&gt;
&lt;li&gt;謊言＃9　領導力是一種東西&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;「謊言」？乍看之下頗為聳動。若進一步研讀作者提出的大規模實證資料，就能理解「真相」論述的理由：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;編號&lt;/th&gt;
          &lt;th&gt;謊言　　　　　　　　　　　　&lt;/th&gt;
          &lt;th&gt;真相&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;＃1&lt;/td&gt;
          &lt;td&gt;人們在意他們為哪家公司工作&lt;/td&gt;
          &lt;td&gt;人們或許在意自己在哪家公司工作，一旦入職之後，他們關心的是屬於哪支&lt;strong&gt;團隊&lt;/strong&gt;。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;＃2&lt;/td&gt;
          &lt;td&gt;最佳計畫致勝&lt;/td&gt;
          &lt;td&gt;最佳&lt;strong&gt;情報&lt;/strong&gt;致勝：即時協調你的團隊，重度倚賴每個團隊成員有根據的詳細情報。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;＃3&lt;/td&gt;
          &lt;td&gt;第一流的公司把目標層層下達&lt;/td&gt;
          &lt;td&gt;第一流的公司不是把&lt;strong&gt;目標&lt;/strong&gt;層層下達，而是把&lt;strong&gt;意義&lt;/strong&gt;層層下達。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;＃4　&lt;/td&gt;
          &lt;td&gt;最優秀的人才是通才&lt;/td&gt;
          &lt;td&gt;第一個事實：職能是無法評量的。第二個事實：對任何職業或活動的高效能表現所做的研究顯示，卓越其實是&lt;strong&gt;個人獨特性&lt;/strong&gt; (&lt;strong&gt;idiosyncrasy&lt;/strong&gt;) 使然。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;＃5　&lt;/td&gt;
          &lt;td&gt;人們需要反饋&lt;/td&gt;
          &lt;td&gt;人們需要的不是反饋，而是「&lt;strong&gt;關注&lt;/strong&gt;」，而且是關注他們做得最好的事情。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;＃6&lt;/td&gt;
          &lt;td&gt;人們能夠可靠評量他人&lt;/td&gt;
          &lt;td&gt;雖然人們無法可靠評量他人，但能夠可靠評量&lt;strong&gt;自己的體驗&lt;/strong&gt;。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;＃7&lt;/td&gt;
          &lt;td&gt;人們具有潛力&lt;/td&gt;
          &lt;td&gt;「人們有潛力」這個概念並不正確，或者，更確切地說，沒有助益；真相是：人們有&lt;strong&gt;動能&lt;/strong&gt;。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;＃8&lt;/td&gt;
          &lt;td&gt;工作與生活平衡最重要&lt;/td&gt;
          &lt;td&gt;最重要的，不是追求工作與生活的平衡，最重要的是找到工作中的喜愛、你的熱情所在。&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;＃9&lt;/td&gt;
          &lt;td&gt;領導力是一種東西&lt;/td&gt;
          &lt;td&gt;領導力不是一種東西，因為它無法被可靠評量；&lt;strong&gt;追隨&lt;/strong&gt;是一種東西，因為它能夠被可靠評量。一個人是否為領導者，唯一的決定因子是有沒有人追隨。&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;從這份「謊言 vs 真相」清單，可看出 Marcus Buckingham 的論述是優勢導向、人本導向。&lt;/p&gt;
&lt;h2 id=&#34;杜拉克如是說&#34;&gt;杜拉克如是說&lt;/h2&gt;
&lt;p&gt;談到優勢導向、人本導向，不由得想起《&lt;a href=&#34;https://www.books.com.tw/products/0010858309&#34;&gt;彼得・杜拉克的管理聖經&lt;/a&gt;》(&lt;a href=&#34;https://www.amazon.com/dp/0060878975&#34;&gt;&lt;em&gt;The Practice of Management&lt;/em&gt;&lt;/a&gt;) 早在 1954 年就對於 individual contributor 的特殊需求，提出獨到的觀點：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/07/needs-of-professional-employee.jpg&#34; alt=&#34;From: The Practice of Management, Peter Drucker (1954)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/07/needs-of-professional-employee.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;From: The Practice of Management, Peter Drucker (1954)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;大師如是說：&lt;/p&gt;
&lt;p&gt;一、專業性職務的目標，必須是專業上的目標。儘可能為專業人員提供經理人的願景，讓他們了解專業工作對於企業整體的影響，因此他們可以自己想清楚怎麼做才能為公司帶來最大的貢獻。&lt;/p&gt;
&lt;p&gt;二、優秀的專業人員往往不是傑出的管理人才。原因不見得在於專業人員寧可獨自工作，而是他們通常很厭煩行政作業。優秀的專業人員往往對行政管理人員缺乏敬意，他欽佩的是在專業領域中表現比他優秀的人。&lt;/p&gt;
&lt;p&gt;企業需要的是為個別貢獻者提供一條與管理職位平行的升遷管道。這些新升遷機會的聲望、重要性和地位應該和傳統管理職位沒有兩樣。&lt;/p&gt;
&lt;p&gt;三、我們必須肯定專業人員對公司的貢獻絕對不遜於經理人的貢獻。&lt;/p&gt;
&lt;p&gt;四、公司應該對專業人員提出許多要求，絕對不接受、也不寬容拙劣和平庸的表現。但是，究竟專業人員如何完成工作，則必須交由他自行負責，也自行決定。專業人員的上司應該有能力協助、教導、指引屬下，他和專業人員的關係應該好像大學的資深教授與年輕教授之間的關係，而不是從屬關係。企業需要給予稀有而寶貴的專業人才 —— 能啟發同事的教師，充分的肯定、地位和獎勵。&lt;/p&gt;
&lt;p&gt;五、專業人才需要在企業內外都獲得專業上的肯定。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;從這 9 + 5 點，大概可以粗略勾勒出專業人士心之所向的關鍵因素。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>服務事故處理的系統思考</title>
      <link>//william-yeh.net/post/2021/04/cld-for-service-incident/</link>
      <pubDate>Mon, 05 Apr 2021 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2021/04/cld-for-service-incident/</guid>
      
        <description>&lt;p&gt;集團內 Agile CoP 定期聚會，最近都在團練「&lt;a href=&#34;https://wiki.mbalib.com/zh-tw/%E8%A1%8C%E5%8A%A8%E5%AD%A6%E4%B9%A0%E6%B3%95&#34;&gt;行動學習 (action learning)&lt;/a&gt;」。&lt;/p&gt;
&lt;p&gt;行動學習十分殊勝。多元探詢角度居然能夠同時並存，對我來說，在參加之前委實難以想像。&lt;/p&gt;
&lt;p&gt;我參加了兩次，上次我選擇的提問切入點 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 是「問題重塑」，這次刻意換成「系統思考」來練練。&lt;/p&gt;
&lt;p&gt;某團員提出一則個案讓大家探討：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;P0 事件令人疲於奔命，大家也認同軟體服務系統 Op-friendly 很重要。問題是：應該由誰去推動？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一看這敘述，內心小劇場就開始了：我超想換回上次的「問題重塑」切入點呀！不過，轉念一想，「系統思考」也是能夠重塑問題的⋯⋯&lt;/p&gt;
&lt;p&gt;於是，藉由團員夥伴們從各個角度提問，我漸漸系統思考出一些端倪（並偷偷夾帶一些問題重塑）。接下來，就要帶著這份初期假設去小步行動了。&lt;/p&gt;
&lt;p&gt;具體細節不便在此公開揭露，我就改用有些局部類似的場景：《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》第 11 章的故事情節當例子吧。&lt;/p&gt;
&lt;h2 id=&#34;規則&#34;&gt;規則&lt;/h2&gt;
&lt;p&gt;《獨角獸專案》主角梅克辛很納悶：為什麼她一直陷在工單的無窮迴圈？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;是我們一手造成的。我們制定了一系列規定，強調 QA 從開發部門分離出來的必要性，你懂的，以便保護業務不受那些瘋狂、無所顧忌的開發人員波及。每一年，我們都用任何出了差錯的事作為名堂，制定更多的規則來『提升開發人員的問責性』，然而只讓效率更加緩慢。&lt;/p&gt;
&lt;p&gt;常聽人們說 IT 是整個組織的神經樞紐。但出於某種原因，企業卻容忍他們的中樞神經逐漸退化，好比多發性硬化症擾亂了大腦內部與在身體間流動的資訊流一樣。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;若改用系統思考 &lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD&lt;/a&gt; 圖來表達，這是企圖利用「制定更多規則」來達到平衡迴路：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/04/cld-1-regulation.png&#34; alt=&#34;CLD Part 1：制定規則的平衡迴路&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/04/cld-1-regulation.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;CLD Part 1：制定規則的平衡迴路&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;規定，初衷是好的；可是，過度的規定，會反噬系統研發。&lt;/p&gt;
&lt;p&gt;就像《獨角獸專案》第 8 章所描述的情景：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第三理念的對立面是堅持程序合規性和 TWWADI 的人，你們懂吧，『The Way We&amp;rsquo;ve Always Done It.（這是我們一貫的做法）』。無數的規則、條例、流程、程序、批准和階段門檻，隨時都有新的規則出現，為了防止最近的災難再度發生。&lt;/p&gt;
&lt;p&gt;嚴格的專案計畫、不靈活的採購流程、強勢的架構審查委員會、不頻繁的發布時程、冗長的審核流程、嚴格的職責分離⋯⋯你們對程序合規性一定深有體會。&lt;/p&gt;
&lt;p&gt;每一項都增加了我們所做的每一件事的協調成本，也推高了延遲成本。再加上決策所在和工作執行地之間的距離不斷擴大，我們交付的成果品質每下愈況。正如戴明大師 (W. Edwards Demming) 的觀察，『一個壞系統將次次擊潰所有好人。』&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;用系統思考 &lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD&lt;/a&gt; 圖來表達，這是「制定更多規則」所產生的惡化增強迴路：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/04/cld-2-depression.png&#34; alt=&#34;CLD Part 2：制定規則的惡化增強迴路&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/04/cld-2-depression.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;CLD Part 2：制定規則的惡化增強迴路&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;欲證實是否真有如上圖所預測的惡化增強迴路，可沿著增強迴路觀察關鍵變數的增長趨勢：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Restrictions on Dev&lt;/li&gt;
&lt;li&gt;Dev&amp;rsquo;s willingness to cooperate and contribute&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;捨本逐末系統基模&#34;&gt;捨本逐末系統基模&lt;/h2&gt;
&lt;p&gt;上圖，像極了&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype#Shifting_the_burden&#34;&gt;捨本逐末 (shifting the burden)&lt;/a&gt; 系統基模的「症狀解」及「副作用」部分：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/04/shifting_the_burden.png&#34; alt=&#34;捨本逐末 (shifting the burden) 系統基模 (摘自 Wikipedia)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/04/shifting_the_burden.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;捨本逐末 (shifting the burden) 系統基模 (摘自 Wikipedia)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;既然如此，我們就來補上「根本解」，把整幅拼圖完成：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/04/cld-3-devops.png&#34; alt=&#34;CLD Part 3：以整體價值流思考的平衡迴路&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/04/cld-3-devops.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;CLD Part 3：以整體價值流思考的平衡迴路&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這塊拼圖，也正是 DevOps 運動講究的整體價值流思考。&lt;/p&gt;
&lt;h2 id=&#34;適合的特質&#34;&gt;適合的特質&lt;/h2&gt;
&lt;p&gt;剩下的問題是：這塊拼圖，該由誰來拼？&lt;/p&gt;
&lt;p&gt;無疑的，在《獨角獸專案》故事中，適合推動這些改變的人，就是紅衫軍。&lt;/p&gt;
&lt;p&gt;讓我們試著不要只鎖定在特定的單一英雄人物身上，而是試著重塑問題，改問：紅衫軍有什麼特質？&lt;/p&gt;
&lt;p&gt;《獨角獸專案》第 5 章，如此形容紅衫軍：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;對鳳凰專案的大多數人來說，營運部只代表在另一頭接收任務工單的人。他們是所有人的抱怨對象。但是，庫爾特和這群烏合之眾顯然有截然不同的工作之道，他們用非正式的方法繞過正常的組織溝通管道。&lt;/p&gt;
&lt;p&gt;梅克辛非常興奮。她對這個團隊一直致力完成的事以及自己被選來幫忙這件事，發自內心感到驚艷。我終於找到屬於我的部落了，她心想。這就是經營人脈的意義所在——你可以集結一群充滿動力的人來解決一個大問題，儘管這個組合人選和官方組織架構圖一點關係也沒有。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第 5 章，如此形容梅克辛：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;梅克辛，你為了破解鳳凰專案軟體版本的努力成果讓我們很驚艷。我們對你所展現的技術和社交技巧深感敬畏，你成功地找出了幾乎所有的環境要素，這件事需要驚人毅力、專注，還有永不妥協的態度！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第 12 章，如此形容香儂：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;梅克辛欣賞香儂盡量把握任何機會讓人們站在同一陣線。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;第 17 章，如此形容比爾與梅克辛：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;許多企業認識了&lt;a href=&#34;https://hbr.org/2007/07/to-succeed-in-the-long-term-focus-on-the-middle-term&#34;&gt;三層面理論&lt;/a&gt;，還是無法好好地投資新一代創新事務。換句話說，他們在核心業務投資不足，因為他們被脈絡業務綁架了。脈絡業務管理不善是一流企業的罩門。被脈絡業務耽誤的公司沒有辦法專心推動核心業務。&lt;/p&gt;
&lt;p&gt;的確有一條改造公司的策略，但它需要近乎苛刻的專注與堅持。&lt;/p&gt;
&lt;p&gt;最適合管理脈絡業務就是比爾和梅克辛這樣的人。這絕非易事。你需要一個真正了解公司業務的人，能夠不屈不撓地在全公司上下推動標準化，把組織的最佳利益視為第一位，清楚科技的運用時機與分寸。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;但願以上這些摘錄的段落，足以給任何有志推動改變的有志之士一些啟發。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;行動學習三要素 &lt;em&gt;L&lt;/em&gt; = &lt;em&gt;P&lt;/em&gt; + &lt;em&gt;Q&lt;/em&gt; + &lt;em&gt;R&lt;/em&gt;，當中的 &lt;em&gt;L&lt;/em&gt; 為 learning，&lt;em&gt;P&lt;/em&gt; 為 programmed knowledge，&lt;em&gt;Q&lt;/em&gt; 為 questioning，&lt;em&gt;R&lt;/em&gt; 為 reflection。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>被 Yves 啟發的敏捷轉型之旅</title>
      <link>//william-yeh.net/post/2021/03/agile-inspired-by-yves/</link>
      <pubDate>Wed, 31 Mar 2021 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2021/03/agile-inspired-by-yves/</guid>
      
        <description>&lt;p&gt;（2021-06-16 補記）
在 Yves 臉書看到《&lt;a href=&#34;https://www.books.com.tw/products/0010896844&#34;&gt;敏捷管理生存指南：不是快，而是適者生存&lt;/a&gt;》這本書終於要上市的&lt;a href=&#34;https://www.facebook.com/yves.lin888/posts/10159360045030751&#34;&gt;消息&lt;/a&gt;，非常振奮。僅以此文，紀念當年 Yves &lt;a href=&#34;https://blog.yveslin.com/&#34;&gt;部落格&lt;/a&gt;文章給我的種種啟示。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/03/book-agile-mgmt-survival-guide.jpg&#34; alt=&#34;《敏捷管理生存指南：不是快，而是適者生存》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/03/book-agile-mgmt-survival-guide.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《敏捷管理生存指南：不是快，而是適者生存》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;起頭&#34;&gt;起頭&lt;/h2&gt;
&lt;p&gt;2016 年七月，剛升上 Gogolook 的部門主管，也不容我再迴避一個埋藏已久的內心交戰：公司再這樣下去是不行的，朝敏捷的方式轉型才有出路。可是「轉型」二字談何容易，「敏捷轉型」更涉及深層的心智模式，匹夫之勇是行不通的，非長期抗戰不為功。&lt;/p&gt;
&lt;p&gt;我需要一份&lt;strong&gt;地圖&lt;/strong&gt;，告訴我敏捷轉型的航道上可能有哪些冰山或暗礁。就算還不知道該如何排除剷平，至少知道該如何趨避。&lt;/p&gt;
&lt;p&gt;幸運的是，此刻 Yves 剛出爐的〈&lt;a href=&#34;https://funevo.com/2016/09/25/%E8%AE%8A%E6%95%8F%E6%8D%B7%E7%9A%84%E9%98%BB%E7%A4%99-%E5%9C%98%E9%9A%8A%E5%85%B1%E5%89%B5%E6%B3%95%E5%AF%A6%E5%81%9A/&#34;&gt;找出組織無法變敏捷的阻礙 – 團隊共創法實做&lt;/a&gt;〉部落格文章，恰如一場及時雨。文章不僅整理出敏捷轉型常見的 12 項阻礙，更進一步將它們分成三大類型，並開出三帖藥方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;人員或組織的慣性&lt;/strong&gt; → 解決慣性的方法就是一直動，平衡日常營運與變革，控制前進的腳步，從走路、小碎步、健走慢慢加速到需要的節奏。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;主事者的重視程度&lt;/strong&gt; → 權力越集中的組織越有可能大幅改變組織架構與資源投注，否則就得組織扁平化，採用自組織模式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;人員沒有能力或知識&lt;/strong&gt; → 給資源學習，給空間運用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;綜合考慮之後，我選擇在自己有直接職位權影響力的團隊內，打破慣性，亦步亦趨植入 Scrum 相關知識與實踐。這個小團隊的成功，便成為日後在公司內進一步擴大敏捷施行範圍的指標性個案。&lt;/p&gt;
&lt;p&gt;我很感激 Yves 這篇文章的啟示。&lt;/p&gt;
&lt;h2 id=&#34;遊戲&#34;&gt;遊戲&lt;/h2&gt;
&lt;p&gt;敏捷實施一小陣子，很快就會觸碰到一個迴避不了的衝突點：自組織、自管理要到什麼程度，才不是淪為玩假的敏捷？&lt;/p&gt;
&lt;p&gt;隔壁團隊嘗試跑了 Kanban 一陣子，遇到這類問題，找我討論。&lt;/p&gt;
&lt;p&gt;我知道這問題應該被解決，但該如何解決？當時的我並沒有頭緒，更何況這是隔壁的團隊，是我沒有直接職位權影響力的團隊。&lt;/p&gt;
&lt;p&gt;我又向 Yves 的部落格取經。幸運的是，Yves 稍早在〈&lt;a href=&#34;https://funevo.com/2016/06/30/delegation-poker/&#34;&gt;自己來做到死！ – 玩授權撲克來學主管如何授權&lt;/a&gt;〉這篇文章裡就點出一個關鍵，也介紹一個有趣的工具：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;當主管在考慮工作的授權時，不應該問自己「要不要授權？」，而要問自己「要如何授權？」&lt;/p&gt;
&lt;p&gt;因為跟自組織一樣，授權不是 0 跟 1 二選一，而是程度多寡的差異。授權撲克（Delegation Poker）就是幫助我們思考「要如何授權？」的一個好工具。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這麼有趣的工具，令人躍躍欲試。於是，我開始密謀在公司月會時，帶這個團隊公開玩一場「授權撲克」遊戲，既解決他們的問題，也試圖在寓教於樂氣氛中對全公司傳達「某些不一樣的事正在發生」的訊號。&lt;/p&gt;
&lt;p&gt;我大致上是根據 Yves 文章介紹的玩法，微調成更像 planning poker 的方式，讓團隊公開探討幾項活動的授權等級：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Refine PBI&lt;/li&gt;
&lt;li&gt;Select SBI&lt;/li&gt;
&lt;li&gt;Estimate SBI&lt;/li&gt;
&lt;li&gt;Freeze spec&lt;/li&gt;
&lt;li&gt;Unfreeze spec&lt;/li&gt;
&lt;li&gt;Allow fast lane during sprint&lt;/li&gt;
&lt;li&gt;Manage tech debt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;（也感謝 Yves 慷慨贈我幾盒鈦坦科技設計的授權撲克。）&lt;/p&gt;
&lt;p&gt;這場公開活動，不僅達到預計的效果，也讓我更敢公開進行一些非傳統的引導活動。&lt;/p&gt;
&lt;h2 id=&#34;空間&#34;&gt;空間&lt;/h2&gt;
&lt;p&gt;2017 上半年，公司人數成長到空間不敷使用，打算再租下另一層辦公室。&lt;/p&gt;
&lt;p&gt;國內外敏捷先驅的經驗告訴我們，合適的&lt;strong&gt;實體空間&lt;/strong&gt;，能夠催化敏捷的成效。因此，這是千載難逢的大好機會，可以從頭開始把空間塑造成可滋養敏捷成長的模樣。&lt;/p&gt;
&lt;p&gt;事情就是這麼湊巧。這一年來，每當我遇到相關的疑惑、需要相關的參考對象，Yves 就是會這麼湊巧的與我的敏捷探索之路產生交集。&lt;/p&gt;
&lt;p&gt;此刻，Yves 所在的鈦坦科技也正在搬遷他們的台北辦公室，葉千綸設計師更在 3 月 30 日晚間公開分享&lt;a href=&#34;https://www.youtube.com/watch?v=kvYySCNsydE&#34;&gt;新辦公室的設計理念&lt;/a&gt;。於是，我們去取經，並設法將一些有趣的元素帶回來。&lt;/p&gt;
&lt;p&gt;後來，與業界交流敏捷轉型甘苦談，才赫然發現，封閉的實體空間，對台灣軟體研發圈子的傷害有多大。我們真的很幸運，能在推動敏捷轉型的初期，就有可師法的對象，讓實體空間不致成為敏捷的阻力。&lt;/p&gt;
&lt;p&gt;人的問題已經夠麻煩了，如果連空間都是麻煩製造者，怎麼能苛責敏捷轉型不順利？&lt;/p&gt;
&lt;h2 id=&#34;引導&#34;&gt;引導&lt;/h2&gt;
&lt;p&gt;知識性的 Scrum 課程很多，但&lt;strong&gt;軟技能&lt;/strong&gt;卻很少直接在 Scrum 課程中傳授。&lt;/p&gt;
&lt;p&gt;這麼說或許並不公平，畢竟 Scrum 只是具體而微的框架，不是包山包海的滿漢全席，骨肉還是需要由其他地方填補。&lt;/p&gt;
&lt;p&gt;什麼才是 Scrum 需要搭配的軟技能？&lt;/p&gt;
&lt;p&gt;Yves 的〈&lt;a href=&#34;https://funevo.com/2016/08/12/agile-scrum-needs-facilitation/&#34;&gt;敏捷 X 引導 – 讓 Scrum 團隊自組織的具體方法&lt;/a&gt;〉部落格文章點出一個關鍵：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum 架構裡有那麼多的溝通在發生，沒有人可以真正控制事情的進行，主管需要學習其他的領導方式。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;於是，我開始從這篇文章中按圖索驥，尋找與溝通、領導、引導相關的軟技能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;焦點討論法 (Focused Conversation, ORID)&lt;/li&gt;
&lt;li&gt;團隊共創法 (Consensus Workshop)&lt;/li&gt;
&lt;li&gt;開放空間會議 (Open Space Technology)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些引導技能，水很深，我沒能全盤掌握，但已經夠讓我在公司內推動不少敏捷變革措施。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;一路以來，從 Yves 的文章受益匪淺。現在，欣見 Yves 將多年心得整理成有系統的專書《&lt;a href=&#34;https://www.books.com.tw/products/0010896844&#34;&gt;敏捷管理生存指南：不是快，而是適者生存&lt;/a&gt;》，相信更能幫助尚在摸索的芸芸眾生。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/03/book-agile-mgmt-survival-guide.jpg&#34; alt=&#34;《敏捷管理生存指南：不是快，而是適者生存》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/03/book-agile-mgmt-survival-guide.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《敏捷管理生存指南：不是快，而是適者生存》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt; 　 　 　 　 　 　—— 敏捷魔藥師　葉秉哲 (William Yeh)　2021-03-31&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>從系統思考角度讀《獨角獸專案》</title>
      <link>//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/</link>
      <pubDate>Sun, 28 Mar 2021 16:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/</guid>
      
        <description>&lt;p&gt;&lt;strong&gt;活動名稱&lt;/strong&gt;：從系統思考角度讀《獨角獸專案》&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;時間&lt;/strong&gt;：2021-11-24 (三) / 13:30&amp;ndash;15:00 (因疫情影響延期舉辦)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;會議&lt;/strong&gt;：&lt;a href=&#34;https://devopsdays.tw/&#34;&gt;DevOpsDays Taipei 2021&lt;/a&gt; 的 &lt;a href=&#34;https://devopsdays.tw/2021/workshop-page/212&#34;&gt;603 會議室&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;課程簡介&#34;&gt;課程簡介&lt;/h2&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》是本寫實刻劃軟體研發者日常甘苦的商業小說，但內行看門道，這本奇書，並不止於小說，而是真正可以照表操課的，以敏捷的 IT 能力驅動並翻轉整間公司的競爭力。&lt;/p&gt;
&lt;p&gt;我在本書&lt;a href=&#34;//william-yeh.net/post/2020/10/unicorn-project-review/&#34;&gt;推薦序&lt;/a&gt;也曾如此建議：『請以「&lt;strong&gt;系統與組織的五大理念&lt;/strong&gt;」觀點細讀，從頭分析故事的人事時地物及&lt;strong&gt;因果關係&lt;/strong&gt;。經此一番&lt;strong&gt;系統思考&lt;/strong&gt;，比起許多愛談高大上理念的敏捷、DevOps、數位轉型書籍，你將會有更深刻具體的領悟。』&lt;/p&gt;
&lt;p&gt;問題是：如何系統思考？如何照表操課？&lt;/p&gt;
&lt;p&gt;這場 90 分鐘的迷你工作坊，將以「系統思考」角度，帶你分析書中倡議的「五大理念」，你將會得到有助於形塑適合 IT 滋長企業文化的施力線索。&lt;/p&gt;
&lt;h2 id=&#34;目標聽眾&#34;&gt;目標聽眾&lt;/h2&gt;
&lt;p&gt;已有《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》一書，想從中擷取可行洞見的人。&lt;/p&gt;
&lt;p&gt;程度分級 ★☆☆ (通識)：介紹新知給尚未具備或僅具備少許該領域知識的人，也包含非技術議題。&lt;/p&gt;
&lt;h2 id=&#34;聽眾收穫&#34;&gt;聽眾收穫&lt;/h2&gt;
&lt;p&gt;認識高效能研發團隊的核心特質，以及促成這些特質的關鍵施力點。&lt;/p&gt;
&lt;h2 id=&#34;注意事項&#34;&gt;注意事項&lt;/h2&gt;
&lt;h3 id=&#34;學員需知&#34;&gt;學員需知&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;上課前，請先完成「課前作業」（後詳）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;上課時，請攜帶「課前作業」及《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》一書。建議攜帶繁體中文版，以備隨時照頁數檢索。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;課前作業&#34;&gt;課前作業&lt;/h2&gt;
&lt;p&gt;根據學員不同的狀況，我將課前作業分成兩部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;必備作業：所有人都務必在課前確實完成。&lt;/li&gt;
&lt;li&gt;選配作業：行有餘力，請在課前盡量做。做得越多，課堂上就越輕鬆。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;必備作業&#34;&gt;必備作業&lt;/h3&gt;
&lt;p&gt;請依照「速讀」及「精讀」兩階段依序進行：&lt;/p&gt;
&lt;p&gt;➊ 速讀階段：速讀完《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》至少一遍，先享受高潮起伏的劇情，並熟悉人物與關係。&lt;/p&gt;
&lt;p&gt;➋ 精讀階段：挑出書中所有與「&lt;strong&gt;系統與組織的五大理念&lt;/strong&gt;」有關的段落，越多越好。&lt;/p&gt;
&lt;p&gt;我自己的做法是：每讀到一個有關的地方，就用書籤標註。如下圖：&lt;/p&gt;

   &lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
   &lt;div class=&#34;box&#34;&gt;
   &lt;figure  itemprop=&#34;associatedMedia&#34;
     itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
     style=&#34;max-width:30em&#34; &gt;
       &lt;div class=&#34;img&#34;&gt;
         &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/03/unicorn-project-bookmark.jpg&#34; alt=&#34;用書籤標註五大理念的例子&#34;/&gt;
       &lt;/div&gt;
       &lt;a href=&#34;//william-yeh.net/img/2021/03/unicorn-project-bookmark.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
         &lt;figcaption&gt;
             &lt;p&gt;用書籤標註五大理念的例子&lt;/p&gt;
         &lt;/figcaption&gt;
     &lt;/figure&gt;
   &lt;/div&gt;

&lt;p&gt;一點小建議：請善用不同顏色的標籤，或是可寫字的標籤，以便檢索。&lt;/p&gt;
&lt;p&gt;以上請務必在課前確實完成。&lt;/p&gt;
&lt;h3 id=&#34;選配作業&#34;&gt;選配作業&lt;/h3&gt;
&lt;p&gt;若行有餘力，請針對前面挑出的「&lt;strong&gt;五大理念&lt;/strong&gt;」段落，分析其中的因果關係。&lt;/p&gt;
&lt;p&gt;就以《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》第七章為例，埃瑞克在對紅衫軍成員侃侃而談第一理念「簡潔性和區域性 (locality and simplicity)」時，有個段落提到「程式碼區域性與組織區域性」：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/03/unicorn-project-crt-example.jpg&#34; alt=&#34;因果關係例子：《獨角獸專案》第七章&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/03/unicorn-project-crt-example.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;因果關係例子：《獨角獸專案》第七章&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;讓我們先以「因果關係」角度直接翻譯這段文字吧。初期，你可能會解讀出三組因果關係：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/03/unicorn-project-crt-part1.png&#34; alt=&#34;因果關係 Part 1：直接翻譯&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/03/unicorn-project-crt-part1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;因果關係 Part 1：直接翻譯&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這三組因果關係貌似彼此獨立。若再仔細檢視，你可能會發現彼此之間並不是毫無關聯，而是可以辨識出一些共同結構或模式：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/03/unicorn-project-crt-part2.png&#34; alt=&#34;因果關係 Part 2：找出共同模式&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/03/unicorn-project-crt-part2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;因果關係 Part 2：找出共同模式&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;最後，再進一步以「系統思考」常見的「增強迴路」角度來檢視，我們可以合理腦補上「正確歸因」與「錯誤歸因」兩項元素，統整出一份較完整的因果關係圖：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/03/unicorn-project-crt-part3.png&#34; alt=&#34;因果關係 Part 3：增強迴路&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/03/unicorn-project-crt-part3.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;因果關係 Part 3：增強迴路&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;因果關係圖一旦推導到這種地步，施力線索也就昭然若揭。&lt;/p&gt;
&lt;p&gt;這就是「系統思考」的威力。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這份「選配」作業，請盡可能在課前多做一些。課前做得越多，課堂上你就會越輕鬆。&lt;/p&gt;
&lt;p&gt;做不出來的，也別擔心，課堂上會以分組方式進行，有隊友會與你一齊破關。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      《獨角獸專案》系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2020/10/unicorn-project-review/&#34;&gt;值得你看門道的好書——《獨角獸專案》推薦序&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 從系統思考角度讀《獨角獸專案》&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系統思考工作坊 - 系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 【系統思考的四堂課】&lt;a href=&#34;//william-yeh.net/post/2018/06/sys-thinking-workshop/&#34;&gt;緣起&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 第一場公開班課後回覆：&lt;a href=&#34;//william-yeh.net/post/2018/09/thinking-weight-training/&#34;&gt;思維的重量訓練&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ 從系統思考角度讀《獨角獸專案》&lt;/p&gt;
&lt;p&gt;➍ &lt;a href=&#34;//william-yeh.net/post/2024/07/dissecting-devops-via-systems-thinking/&#34;&gt;從系統思考角度談 DevOps 三步工作法&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>「系統思考工作坊」系列</title>
      <link>//william-yeh.net/series/systhinking-series/</link>
      <pubDate>Sun, 28 Mar 2021 00:00:00 +0000</pubDate>
      
      <guid>//william-yeh.net/series/systhinking-series/</guid>
      
        <description>&lt;p&gt;【系統思考的四堂課】&lt;a href=&#34;//william-yeh.net/post/2018/06/sys-thinking-workshop/&#34;&gt;緣起&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;第一場公開班課後回覆：&lt;a href=&#34;//william-yeh.net/post/2018/09/thinking-weight-training/&#34;&gt;思維的重量訓練&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/&#34;&gt;從系統思考角度讀《獨角獸專案》&lt;/a&gt;&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>如何訓練一個新的 Scrum master？</title>
      <link>//william-yeh.net/post/2021/03/train-new-scrum-master/</link>
      <pubDate>Wed, 17 Mar 2021 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2021/03/train-new-scrum-master/</guid>
      
        <description>&lt;p&gt;今天在公司內 agile guild 定期聚會中，討論到一個有趣的議題：​&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「如何訓練一個新的 Scrum master？」​&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;邊寫便利貼，邊回想自己過往經驗，也試圖歸納統整一些層次。&lt;/p&gt;
&lt;p&gt;寫完，講完，驚覺：這跟憲哥在《&lt;a href=&#34;https://www.books.com.tw/products/0010699844&#34;&gt;教出好幫手&lt;/a&gt;》提出的 OJT 步驟、福哥在《&lt;a href=&#34;https://www.books.com.tw/products/0010810862&#34;&gt;教學的技術&lt;/a&gt;》提出的演練法，結構極為相似。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;我的方法是分成三大階段。&lt;/p&gt;
&lt;h2 id=&#34;-教學&#34;&gt;➊ 教學&lt;/h2&gt;
&lt;p&gt;這位待培養的 Scrum master 置身的團隊，可能已經有跑一些 Scrum 了，也可能根本就是 Scrum 沙漠。不管是哪一種情況，在第一階段的重點是：先求對 Scrum 有個概括不偏斜的理解（但尚不須深度理解每一個細節），搭建正確穩固的鷹架。&lt;/p&gt;
&lt;p&gt;最省事的，就是直接送去上課。當然啦，要慎選老師，不能選只顧著考證照的。&lt;/p&gt;
&lt;p&gt;其次，就是靠自己，根據實際需要，針對特定議題，設計相關的體驗式迷你工作坊。&lt;/p&gt;
&lt;p&gt;這階段，類似憲哥福哥講的「我說給你聽」。&lt;/p&gt;
&lt;h2 id=&#34;-觀察員筆記&#34;&gt;➋ 觀察員筆記&lt;/h2&gt;
&lt;p&gt;鷹架搭好了，我就會請他準備「觀察員筆記」。&lt;/p&gt;
&lt;p&gt;在團隊中，儘管他檯面上的身分還是 product owner 或 developer，但要開始適度切出一個「觀察員」的分靈體，觀察我是怎麼扮演 Scrum master 的角色。&lt;/p&gt;
&lt;p&gt;觀察，即時筆記，並在定期 1 on 1 場合提出來釋疑或討論。我甚至還會鼓勵並協助他們去觀察其他團隊，接觸不同的運作風格，比較，辯證，並逐漸勾勒想像出他們屬意的風格。&lt;/p&gt;
&lt;p&gt;這階段，類似憲哥福哥講的「我做給你看」。&lt;/p&gt;
&lt;h2 id=&#34;-登場&#34;&gt;➌ 登場&lt;/h2&gt;
&lt;p&gt;視團隊狀況及他的信心指數，我會開始逐步請他主持某些 Scrum 會議。&lt;/p&gt;
&lt;p&gt;Daily Scrum 及 sprint review 通常是可以最早開始嘗試的，至於 retrospective 則可能是最具挑戰性的。這階段，能否搭配更即時更精準的事後回饋，甚至事前就進行沙盤推演，是成敗關鍵。&lt;/p&gt;
&lt;p&gt;這階段，類似憲哥福哥講的「讓你做做看」。&lt;/p&gt;
&lt;h2 id=&#34;creditability&#34;&gt;Creditability&lt;/h2&gt;
&lt;p&gt;為什麼要如此大費周章？Scrum 三支柱不是有一條 &amp;ldquo;adaptation&amp;rdquo; 嗎？Scrum 不是講究 &amp;ldquo;courage&amp;rdquo; 核心價值嗎？為什麼不放膽讓他從經驗中學習？&lt;/p&gt;
&lt;p&gt;可能是我對於「Scrum master 的 &lt;strong&gt;creditability&lt;/strong&gt;」很注重吧，非常小心維護 Scrum master 見習生在團隊中的 creditability。畢竟，歪樓的 Scrum 太多太多了，Scrum 被外行人誤解已經是家常便飯。對於 Scrum master 這個常被外行人誤解的角色，我的期許是：經營好第一印象，不要曝於坐實錯誤第一印象的風險——那會導致改革的倒退。&lt;/p&gt;
&lt;p&gt;更嚴重的是：如果置身的是一個對 Scrum 懷有戒心的組織，這極可能嚴重摧毀 Scrum master 見習生好不容易萌芽的浩然之氣。就像孟子所說：「我善養吾浩然之氣⋯⋯其為氣也，至大至剛，以直養而無害，則塞於天地之間。其為氣也，配義與道；無是，餒也。」&lt;/p&gt;
&lt;p&gt;我寧可大費周章，以直養而無害。慢一點，比較快。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;一些個人經驗的整理，供大家參考。也願各位新的 Scrum master 都能找出自己的風格。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      Scrum master 培訓系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 如何訓練一個新的 Scrum master？&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/09/deliberate-practice-for-agile/&#34;&gt;敏捷之途無他，刻意練習而已矣！&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2021/07/revisit-psm1/&#34;&gt;Scrum 認證模擬測驗的兩項啟發&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2022/03/prof-common-vocabulary/&#34;&gt;敏捷啟航的專業基礎：共同語彙&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;憲哥福哥的 PESOS 作法是：&lt;strong&gt;P&lt;/strong&gt; 學習前準備 → &lt;strong&gt;E&lt;/strong&gt; 解釋：我說給你聽 → &lt;strong&gt;S&lt;/strong&gt; 示範：我做給你看 → &lt;strong&gt;O&lt;/strong&gt; 演練：讓你做做看 → &lt;strong&gt;S&lt;/strong&gt; 成效追蹤。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>軟體研發者的隨身職涯教練——《經理人之道》推薦序</title>
      <link>//william-yeh.net/post/2021/02/the-managers-path-review/</link>
      <pubDate>Sun, 21 Feb 2021 16:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2021/02/the-managers-path-review/</guid>
      
        <description>&lt;p&gt;研究所時期，身為實驗室的師兄，我必須帶領學弟妹完成各種公民營機構的合作計畫案。那是我第一次接觸到「領導技術團隊」這件事——這件學校不會教的事。&lt;/p&gt;
&lt;p&gt;後來，在新創圈打滾，陸續經歷了小工頭、技術負責人、部門主管等身分轉變，甚至也有機會從事跨部門、跨團隊的 Scrum master 及變革推動者。資歷增加，守備範圍不斷擴大，一路走來，跌跌撞撞在所難免。遇到挫折時，不免自問：這真的是我想走的路嗎？我不能只當單純的&lt;strong&gt;個別貢獻者&lt;/strong&gt; (&lt;strong&gt;individual contributor&lt;/strong&gt;) 就好了嗎？&lt;/p&gt;
&lt;p&gt;沒有 mentor 在身邊，得向書籍求教。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;書架上不乏經理人職涯發展的忠告。針對&lt;strong&gt;經理人&lt;/strong&gt;與&lt;strong&gt;個別貢獻者&lt;/strong&gt;兩種職涯路線的分野，《&lt;a href=&#34;https://www.books.com.tw/products/0010858309&#34;&gt;彼得・杜拉克的管理聖經&lt;/a&gt;》(&lt;a href=&#34;https://www.amazon.com/dp/0060878975&#34;&gt;&lt;em&gt;The Practice of Management&lt;/em&gt;&lt;/a&gt;) 如是說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;專業人員和經理人一樣，同時肩負「工作」和「團隊運作」的責任。差別：&lt;strong&gt;經理人&lt;/strong&gt;必須為成果負責，因此他必須為別人的工作負責。&lt;strong&gt;個別專業貢獻者&lt;/strong&gt;無論採取單獨工作方式，或是團隊的一分子，也為成果負責，但只為自己的工作成果負責。唯有當其他人了解他的工作成果，並且能運用他的工作成果時，他的工作才能發揮功效。&lt;/p&gt;
&lt;p&gt;但是，優秀的專業人員往往不是傑出的管理人才。原因不見得在於專業人員寧可獨自工作，而是他們通常很厭煩行政作業。優秀的專業人員往往對行政管理人員缺乏敬意，他欽佩的是在專業領域中表現比他優秀的人。&lt;/p&gt;
&lt;p&gt;企業需要的是為個別貢獻者提供一條與管理職位平行的升遷管道。這些新升遷機會的聲望、重要性和地位應該和傳統管理職位沒有兩樣。專業人員的上司應該有能力協助、教導、指引屬下，他和專業人員的關係應該好像大學的資深教授與年輕教授之間的關係，而不是從屬關係。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至於經理人路線，針對&lt;strong&gt;一般領域的經理人&lt;/strong&gt;，《&lt;a href=&#34;https://www.books.com.tw/products/0010515462&#34;&gt;經理人的一天：明茲伯格談管理&lt;/a&gt;》(&lt;a href=&#34;https://www.amazon.com/Managing-Henry-Mintzberg/dp/1605098744&#34;&gt;&lt;em&gt;Managing&lt;/em&gt;&lt;/a&gt;) 如此提醒：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;只會&lt;strong&gt;溝通&lt;/strong&gt;的管理者，從來不會完成任何事情；只會&lt;strong&gt;行動&lt;/strong&gt;的管理者，最後是一人包辦所有事物；只在乎&lt;strong&gt;掌控&lt;/strong&gt;的管理者，可能下面只剩一些唯命是從的馬屁精。&lt;/p&gt;
&lt;p&gt;有效的管理者不會在各個角色之間保持完美的平衡，他們雖然無法忽視某些角色，但可以偏向其中幾個角色。管理工作的關鍵在於，把管理的所有面向融入這種動態平衡中。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;進一步，針對&lt;strong&gt;技術領域的經理人&lt;/strong&gt;，《&lt;a href=&#34;https://www.books.com.tw/products/0010467750&#34;&gt;領導者，該想什麼？&lt;/a&gt;》(&lt;a href=&#34;https://www.amazon.com/Becoming-Technical-Leader-Problem-Solving-Approach/dp/0932633021&#34;&gt;&lt;em&gt;Becoming a Technical Leader&lt;/em&gt;&lt;/a&gt;) 提出犀利的拷問：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我能一面當領導者，一面繼續提升我的技術能力嗎？一個毫無技術背景的人，有可能在技術界成為領導者嗎？一旦成為領導者，我必須犧牲多少技術專業能力？我能得到多少回報？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;諸位大師所言極是。不過，資質駑鈍如我，難以直接將如此泛化的建議轉換到軟體技術領域。畢竟在我們這個領域裡，技術深度與廣度皆日新月異，技術選型更迭頻繁，更講究組織扁平以迅速應變，因此，過去那些針對一般領域、甚至一般技術領域的職涯分化發展通則，未必能夠不假思索直接套用到軟體技術領域。&lt;/p&gt;
&lt;p&gt;我更期待看到具體建議，而且是專門針對我們這個軟體技術領域而提出的具體建議：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;軟體研發者，在不同的職涯階段，對於&lt;strong&gt;溝通&lt;/strong&gt;、&lt;strong&gt;行動&lt;/strong&gt;、&lt;strong&gt;掌控&lt;/strong&gt;三個面向，各該保持哪一種動態平衡狀態？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;軟體研發者，在不同的職涯階段，對於軟體技術能力，該追求或維持到什麼程度？又該如何做到？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;軟體研發者，面對「經理人」與「個別貢獻者」兩條路線，是否只能二選一？是否都是單行道？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這類疑惑，沒有 mentor 在身邊，實在難以解決。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;因此，當我看到 &lt;a href=&#34;https://en.wikipedia.org/wiki/Camille_Fournier&#34;&gt;Camille Fournier&lt;/a&gt; 寫的《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865027896&#34;&gt;經理人之道：技術領袖航向成長與改變的參考指南&lt;/a&gt;》(&lt;a href=&#34;https://www.amazon.com/Managers-Path-Leaders-Navigating-Growth/dp/1491973897&#34;&gt;&lt;em&gt;The Manager&amp;rsquo;s Path&lt;/em&gt;&lt;/a&gt;) 這本書，以她從軟體工程師開始，一路做到 CTO，甚至避險基金公司常務董事的豐富經驗，直言不諱道出具體觀點，不禁擊節讚嘆。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這不是一本廣泛適用所有人的管理學書籍，而是一本專門寫給&lt;strong&gt;工程經理&lt;/strong&gt;的工具書。工程管理是一門技術學科，而不是僅僅一套帶人心法。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2021/02/the-managers-path.jpg&#34; alt=&#34;《經理人之道：技術領袖航向成長與改變的參考指南》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2021/02/the-managers-path.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《經理人之道：技術領袖航向成長與改變的參考指南》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;譬如說，對於尚處於非正式的技術負責人 (team lead) 階段，她建議要專注在：透徹瞭解架構、注重團隊精神、領導技術決策、溝通。到了更正式的工程經理 (engineering manager) 階段，她建議，除了必須增進人員管理技能，萬萬不可忘記繼續維持技術敏銳度：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;從我的經驗來看，絕大多數工程部門管理的挑戰都在「工程」與「管理」的交集處。人事管理不容易，我不會低估處理人際關係的挑戰，而這些與人打交道的能力在各行業都吃得開。&lt;/p&gt;
&lt;p&gt;然而，工程部門管理的挑戰並不僅止於人員管理的面向。我們管理的是一群技術人員，且我們之中大多數人來自技術專家的職位。我決不會建議非技術專業背景人員管理工程部門！在技術上長年累積的專業有助於獲得團隊的信任，並幫助你領導團隊做出高效決策。當你努力成為一名成功的工程主管，不要低估技術能力的價值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;點出「維持技術敏銳」的重要性之後，她也建議初階技術主管可以這麼做：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;當然，你要學會平衡的藝術。當你轉換跑道到管理職時，維持技術敏銳可能是一項艱鉅挑戰。然而，在管理團隊的這個階段，假如你不再維持對程式碼的敏銳度，你將面臨在職涯發展中過早和技術脫節的風險。雖然你日後打算走管理職，但這也不代表你應該放棄技術責任。事實上，我在關於 Engineering Lead 的職位描述中特別提過，我希望這個職位的經理還要負責交付小功能並修復 bug。&lt;/p&gt;
&lt;p&gt;可悲的是，某些公司實際上並沒有開出「有一點時間開發程式碼的經理」的職缺。我的建議是繼續維持對技術的敏銳度，直到你真的認為自己夠懂程式碼和系統設計等領域，再決定你是否想轉換到管理職。一旦和程式碼說了再見，重新回到程式碼的懷抱將格外困難。更有甚者，假如你過早與技術脫節，你可能因為技術專業積累的不足，而無法朝更高的管理階層邁進，最終只能止步於中階主管職。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;對於逐漸昇到類似工程總監位子的人，她也提出具體建議以盡可能維持技術敏銳度：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;幸運的是，對我們來說，還有幾個不需要碰大量程式碼的辦法幫助我們保持手感。對於二級審核人員來說，程式碼審查就是個好方法。假如你更親力親為地建立系統，請繼續關注這些系統，因為你會比大多數人更能牢記技術細節，可以透過程式碼審查和提問來幫助為這個系統工作的工程師。&lt;/p&gt;
&lt;p&gt;最後，即使你不大算寫太多 code，我也強烈建議你每週至少有一個完整的半天時間，不要安排任何會議或其他工作，專注在一些富有創造性的追求，比如撰寫關於技術的部落格文章、準備科技大會的演講內容，或者參與一個開源專案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;針對軟體技術領域，「經理人」與「個別貢獻者」兩條路線的取捨，她的觀點是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一定要記得你有權利更換職涯跑道。人們通常會在某個時候嘗試管理職，然後發現他們不喜歡當主管，兜兜轉轉回歸技術職位。走上管理職，你不是不能回頭，但記得睜大眼睛去嘗試。每個職位角色都有各自的優缺點，自己親自去感受最適合你的那一種。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;她也建議如何引導下屬對「經理人」與「個別貢獻者」兩條路線進行探索：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在人們夠格被升職到資深工程師或更高的職等之前，鼓勵他們累積管理或指導經驗。對於大多數公司來說，管理職和技術職的分岔點應該是人們開始展現&lt;strong&gt;領導力&lt;/strong&gt;的階段，無論這個領導力是管理人員還是設計軟體。即便人們負責設計軟體，也會面對人與人之間的互動與需求；出類拔萃的資深個人貢獻者也知道如何管理專案和指導團隊中佔比更多的菜鳥／初階工程師。你可以考慮將&lt;strong&gt;指導經驗&lt;/strong&gt;作為資深個人貢獻者的升職條件。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上是我從書中信手捻來的幾則精闢見解，書中還有更多精彩內容待你發掘。&lt;/p&gt;
&lt;p&gt;我認為，身為軟體研發從業人員，只要你不是自雇者，只要你想在軟體研發組織內，統合團隊力量做一番大事，都值得細讀此書，把此書當作軟體研發者的隨身職涯教練：覆盤總結自身經驗，解決當下問題，凝聚團隊，培訓優秀下屬，並替未來道路預做準備。&lt;/p&gt;
&lt;p&gt;這將是能陪伴你很久的一本書。&lt;/p&gt;
&lt;p&gt; 　 　 　 　 　 　—— 敏捷魔藥師　葉秉哲 (William Yeh)　2021-02-21&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>2020 個人回顧</title>
      <link>//william-yeh.net/post/2020/12/2020-retrospective/</link>
      <pubDate>Sat, 26 Dec 2020 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/12/2020-retrospective/</guid>
      
        <description>&lt;p&gt;年初，再多跨出舒適圈一步，換到另外一間外商。&lt;/p&gt;
&lt;p&gt;如果說 &lt;a href=&#34;//william-yeh.net/post/2018/12/2018-retrospective/&#34;&gt;2018&lt;/a&gt; 是收攝靜觀的一年，&lt;a href=&#34;//william-yeh.net/post/2019/12/2019-retrospective/&#34;&gt;2019&lt;/a&gt; 是驚滔駭浪的一年，那麼，2020 算是兩者兼具。&lt;/p&gt;
&lt;p&gt;到了年終，又開始要做個總回顧，再對來年許願。去除一些不便揭露的事情，以下是簡單的回顧。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/national-forest.jpg&#34; alt=&#34;翠峰湖 (2020-08-13)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/national-forest.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;翠峰湖 (2020-08-13)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;補血課程&#34;&gt;補血課程&lt;/h2&gt;
&lt;p&gt;這一年，由於 COVID-19 因素，參加的實體課程，就只有這一場，而且還是首發場：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://shop.darencademy.com/product/view/id/95&#34;&gt;512 / 目標管理與團隊績效 – 統整 OKR 與 KPI 的有效實務&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我曾於 2018 年 Q4 在執掌部門內試行導入 OKR。對於這個我只起了個頭，但遺憾因為換公司而沒能一路帶著它發展下去的大膽嘗試，一直持續關注，希望能有機會吸收專家的實際導入經驗。&lt;/p&gt;
&lt;p&gt;彼得・杜拉克在 &lt;a href=&#34;https://www.amazon.com/dp/0060878975&#34;&gt;&lt;em&gt;The Practice of Management&lt;/em&gt;&lt;/a&gt; 揭示：「企業管理，也就是目標管理。」&lt;/p&gt;
&lt;p&gt;君婷老師的這堂 OKR + KPI 首發課程，雖然表面上是在談目標管理，但卻讓我一直聯想到：這簡直就是&lt;strong&gt;迷你版的企業管理課&lt;/strong&gt;！&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/course-512.jpg&#34; alt=&#34;512 / 目標管理與團隊績效 – 統整 OKR 與 KPI 的有效實務&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/course-512.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;512 / 目標管理與團隊績效 – 統整 OKR 與 KPI 的有效實務&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這次課堂上，一方面得以更專注觀摩老師是如何處理某些理論與在地實務的兩難議題，更能不時抽出神來，俯視反思某些平日已經隱隱約約觸及到，但並未徹底認真系統化對待的選擇。&lt;/p&gt;
&lt;p&gt;譬如說，individual contributor 與 manager 的分野。經過這堂課的洗禮，我認為，&lt;strong&gt;目標管理&lt;/strong&gt;能力，大概就是兩路線最大的試金石吧。&lt;/p&gt;
&lt;p&gt;課堂上也再次讓我反思另一個觀點：企業的本質，就是&lt;strong&gt;傳話遊戲&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;OKR 有許多精巧的設計，但若不明本質，很容易被無視。&lt;/p&gt;
&lt;p&gt;只套上 OKR 形式外殼而忘了時時心繫著本質，是刻舟求劍緣木求魚。本質，很重要。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/telephone-game.jpg&#34; alt=&#34;出自《轉職必勝班》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/telephone-game.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;出自《轉職必勝班》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;上完這門超值的課，萌生重讀目標管理之父彼得・杜拉克開山之作 &lt;a href=&#34;https://www.amazon.com/dp/0060878975&#34;&gt;&lt;em&gt;The Practice of Management&lt;/em&gt;&lt;/a&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 的念頭，以求打通任督二脈。1954 年的書，就看到許多 OKR 核心元素，理念闡述也比現今許多 OKR 書籍更深刻。有人文底蘊，相對與現今管顧業流行的食譜式風格。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在企業中，經理人並不會自動自發追求共同目標。相反的，企業在本質上包含了三種誤導經理人的重要因素。&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/common-goals.jpg&#34; alt=&#34;The Practice of Management&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/common-goals.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;The Practice of Management&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;1954 年的書，半世紀之後，居然仍能精準地針砭職場。果然是從本質出發的管理學開山之作。&lt;/p&gt;
&lt;p&gt;學苟之本，書架上那四、五本曾經捧讀再三的 OKR 專書，瞬間皆為註腳。&lt;/p&gt;
&lt;h2 id=&#34;演講及授課&#34;&gt;演講及授課&lt;/h2&gt;
&lt;p&gt;今年，由於 COVID-19 因素，再加上自覺已經過了能夠恣意 &lt;del&gt;跑趴&lt;/del&gt; 出沒 社群活動的人生階段，婉拒許多邀約，只接了一場公開演講，以及一場公部門的 3 小時延長版：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gRPC：更高效的微服務介面
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.slideshare.net/williamyeh/agile-transition-a-toc-perspective&#34;&gt;30 分鐘版&lt;/a&gt; @ 台灣雲端大會 2020&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://speakerdeck.com/williamyeh/grpc-geng-gao-xiao-de-wei-fu-wu-jie-mian&#34;&gt;3 小時版&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;淡出這類活動，另一個更重要的原因是：以下這些思考與探索，佔據我更多心力。&lt;/p&gt;
&lt;h2 id=&#34;敏捷本質的再思&#34;&gt;敏捷本質的再思&lt;/h2&gt;
&lt;p&gt;去年，我曾針對敏捷基本功進行一些&lt;a href=&#34;//william-yeh.net/post/2019/12/2019-retrospective/#敏捷基本功&#34;&gt;反思&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;今年年初來到的這間外商，極度重視文字溝通，也有些常態性在家遠距工作的同仁，再加上 COVID-19 攪局，種種因素加總在一起，我素來習以為常不疑有他的敏捷作法，遭遇未曾預料的崩解危機。&lt;/p&gt;
&lt;p&gt;譬如說，我常常反思：原本就很奉行 &lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;Agile Manifesto&lt;/a&gt; 四大總綱的團隊，會比較容易適應遠距工作模式呢，還是相反？&lt;/p&gt;
&lt;p&gt;就以 &amp;ldquo;Individuals and interactions &lt;em&gt;over processes and tools&lt;/em&gt;&amp;rdquo; 這種推崇高頻寬溝通、甚至連空氣都讀得出來的敏捷第一總綱而言，一旦碰到「遠距工作模式」，豈不是被迫降級到 over 的右邊？就以 &amp;ldquo;Working software &lt;em&gt;over comprehensive documentation&lt;/em&gt;&amp;rdquo; 及 &amp;ldquo;Customer collaboration &lt;em&gt;over contract negotiation&lt;/em&gt;&amp;rdquo; 第二、第三總綱而言，一旦碰到「文檔驅動」，豈不是被迫降級到 over 的右邊？&lt;/p&gt;
&lt;p&gt;（倒退的反模式？）&lt;/p&gt;
&lt;p&gt;凡此總總，算是浸潤 agile 多年的我，不得不開始反思的文化衝擊。&lt;/p&gt;
&lt;p&gt;我必須再次解構敏捷，剝離表象，更抓緊本質。&lt;/p&gt;
&lt;p&gt;漸漸地，我提煉出某些更核心的元素，整理成 &amp;lsquo;Essence of Scrum&amp;rsquo; 系列（未完，待續）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/07/pbr-in-a-nutshell/&#34;&gt;Product Backlog Refinement&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/08/daily-scrum-in-a-nutshell/&#34;&gt;Daily Scrum&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-planning-in-a-nutshell/&#34;&gt;Sprint Planning&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-review-in-a-nutshell/&#34;&gt;Sprint Review&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;後來，&lt;a href=&#34;https://scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 在 2020 年 11 月的改版中，有許多地方滿符合我萃取與補充強調的地方，所見略同，深感欣慰。&lt;/p&gt;
&lt;p&gt;核心本質釐清了，還得設想配套。&lt;/p&gt;
&lt;h2 id=&#34;敏捷本質的配套&#34;&gt;敏捷本質的配套&lt;/h2&gt;
&lt;p&gt;Scrum 是很細緻的輕量級框架。輕量，但細緻。&lt;/p&gt;
&lt;p&gt;就像精煉過的套路定石，精煉到外行人嫌它粗糙。常常要實際運用了，卡住了，與其他方法碰撞了，才恍然大悟：原來 Scrum 之所以要這樣設計，是這個原因呀；之所以行不通玩不下去，原來是自己這邊功力有待提升呀。&lt;/p&gt;
&lt;p&gt;Scrum 是一面照妖鏡，顯影出自身不足。&lt;/p&gt;
&lt;p&gt;什麼樣的功力需要提升呢？&lt;/p&gt;
&lt;p&gt;專業領域的技術功力自不在話下，畢竟此乃專業品質之根基；至於與專業領域技術無直接相關的層面，則是常被忽略的重點。&lt;/p&gt;
&lt;p&gt;我發現，電腦玩物站長 Esor 寫的《&lt;a href=&#34;https://www.books.com.tw/products/0010857669&#34;&gt;時間管理的 30 道難題&lt;/a&gt;》，正是一枚火石，可與 Scrum 碰撞出火花。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;時間管理的書很多，但難得看到像這一本深刻觸及本質的好書。&lt;/p&gt;
&lt;p&gt;譬如說，本書第四章探討任務分解、短時間專注等時間管理手段。可是，看到暢談「短時間專注」原理的這一頁，不禁聯想到：Scrum 講究的 sprint cadence 不也是如此嗎？如果像 waterfall 信徒那樣誤把 Scrum 當成只知不斷爆肝短衝，不適合長期抗戰，那也太小覷 Scrum 了，更是不理解「短時間專注的節奏跟頻率」的真義。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/25minutes.jpg&#34; alt=&#34;《時間管理的 30 道難題》 p.150&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/25minutes.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《時間管理的 30 道難題》 p.150&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;第二章，簡直就是在講敏捷法的本質。&lt;/p&gt;
&lt;p&gt;雖沒明講，但內行人一看就知道帶有 impact mapping 及 sprint planning 的共通精神。儘管這本書針對的是「個人」的時間管理，請試想：如果每個個人都具備如此思維，一旦放大至「團隊」的規模，豈不是水到渠成？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;時間管理要思考的，不是如何把更多看似重要的目標排入待辦清單。時間管理要思考的，是如何「把事情完成得很重要」。&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/book-time-mgmt-30.jpg&#34; alt=&#34;《時間管理的 30 道難題》第二章&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/book-time-mgmt-30.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《時間管理的 30 道難題》第二章&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010857669&#34;&gt;時間管理的 30 道難題&lt;/a&gt;》真是一本奇書。不僅可與 Scrum 碰撞出火花，也看到許多可與【&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;過好人生學&lt;/a&gt;】&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 相呼應之處：創造結果的能力、路徑依賴⋯⋯。&lt;/p&gt;
&lt;p&gt;私心認為，想導入敏捷的團隊，甚至想導入遠距敏捷的團隊，都該先接受像這本書這種層面的培訓，提升這類與專業領域技術無直接相關的基本功。如此配套，精煉過的 Scrum 套路定石，方可為我們所用，方可從容應付更多樣化的現實限制，避免受迫性或非受迫性失誤。&lt;/p&gt;
&lt;h2 id=&#34;從運動看教練的本質&#34;&gt;從運動看教練的本質&lt;/h2&gt;
&lt;p&gt;今年淡出 &lt;del&gt;跑趴&lt;/del&gt; 社群活動，更能陪伴小孩。&lt;/p&gt;
&lt;p&gt;享親子之樂之餘，陪小孩走一遭，自己也會持續變強。&lt;/p&gt;
&lt;p&gt;圍棋如此，桌球亦然。如今，很能體會《&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E6%A3%8B%E9%AD%82&#34;&gt;棋靈王&lt;/a&gt;》佐為的心境：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;佐為：「變強的人，是我。」&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/stronger.jpg&#34; alt=&#34;出自《棋靈王》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/stronger.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;出自《棋靈王》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這半年，涉獵許多桌球領域的教學資源，乃至更一般性的運動教練心法 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;，居然體會出一些運動之外的共通道理。&lt;/p&gt;
&lt;p&gt;譬如說，《&lt;a href=&#34;https://www.books.com.tw/products/0010814225&#34;&gt;心志教練&lt;/a&gt;》反對浮誇取向，堅持貫徹簡單的根基：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;簡單並不代表容易，而且通常越簡單越能達到目標。&lt;/p&gt;
&lt;p&gt;很不幸地，目前許多狂人都在傳遞無意義的資訊，更糟的是，都用漂亮的糖衣來包裹。千萬不要成為這些騙子眼中的肥羊呀。&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/simplicity.jpg&#34; alt=&#34;《心志教練》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/simplicity.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《心志教練》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;譬如說，我很欣賞的馬凱旋教練，極強調基本功。他主張不要太早追逐炫目的花招，反而應該進行帶有要求的基本練習——枯燥，卻是後發先至。像以下幾段教學影片，不時可看到他苦口婆心，甚至帶點嚴厲的斥責：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/ib_UuzuGOJE?t=527&#34;&gt;乒乓球直板横打练什么？怎么练？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/OMdS0GZeSvs?t=13&#34;&gt;如何接力量很大的球&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=276&#34;&gt;正手击球总是找不到点，应该怎么办？&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;其中，〈&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=276&#34;&gt;正手击球总是找不到点，应该怎么办？&lt;/a&gt;〉這段教學影片太精彩了，充滿一堆智慧語錄。不管你懂不懂桌球，請跟著我從 &lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=276&#34;&gt;4:36&lt;/a&gt; 開始聽訓吧！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=330&#34;&gt;5:30&lt;/a&gt; / 自個兒練⋯⋯我教六歲的孩子，三分鐘就會。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=373&#34;&gt;6:13&lt;/a&gt; / 為什麼要看著球引拍呢？從一般角度上說，咱們一般的球，沒有來不及的，只有你錯誤的動作結構，你才來不及。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=406&#34;&gt;6:46&lt;/a&gt; / 從開始的&lt;strong&gt;慢速&lt;/strong&gt;開始，你得把那個&lt;strong&gt;節奏&lt;/strong&gt;找著。你慢的球都沒節奏，你怎麼打呀？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=457&#34;&gt;7:37&lt;/a&gt; / 不是說這有什麼複雜，是你的方法不對。成年人打球有個最大的問題：急性子嘛，第三分鐘會打了吧，第四分鐘就想發力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=487&#34;&gt;8:07&lt;/a&gt; / 我不是說讓大家伙兒跟著我們業餘體育學校六歲孩子一樣那麼練，但是你們要明白他們為什麼要那麼練。儘管孩子還小，但是它包含著最樸實的道理：①動作要穩定，②節奏要穩，③必須有回合。你沒回合，那動作的穩定性從哪兒來呢？ [&amp;hellip;] 那一定是從定點來的，一定是從單一速度來的，肯定是這樣。所以說，成年人學打球，你們別圖快。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=572&#34;&gt;9:32&lt;/a&gt; / 會打球的人，好看，動作協調，觀念是什麼呢？①放鬆，②動作成比例。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/NILdR-n0UCY?t=626&#34;&gt;10:26&lt;/a&gt; / 你記著：兵乓球，好的技術，一定是簡單的。好動作是舒服的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些桌球訓練語錄，像極了技術領域的 kata 與 dojo，觸及許多 coaching 本質，甚至在運動、技術以外的領域也可見到。&lt;/p&gt;
&lt;p&gt;原理，原則，果然具有跨領域的共通性。令人聯想劉大任在《強悍而美麗》如此形容 &lt;a href=&#34;https://en.wikipedia.org/wiki/Pete_Sampras&#34;&gt;山普拉斯 (Pete Sampras)&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;看山普拉斯打球，你似乎可以看到這麼一種信息：在這個世界上，你就愛一種東西，你就在你愛的這個東西裡把自己練到完美，練到無懈可擊。&lt;/p&gt;
&lt;p&gt;你因此尋得滿足，此外的一切其實無足輕重。就這樣，你變得堅強，足以抵抗不時傾巢而來的寂寞；你變得勇敢，你學會拒絕周遭的喧嘩與熱鬧；你學會簡單而嚴肅，你形成一種風格，唯你獨有。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;是的，簡單而嚴肅。訓練的本質，教練的本質，就是如此。&lt;/p&gt;
&lt;p&gt;我似乎也該回到自己的原點，當年那個啟迪我步上征途的原點。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/origin.jpg&#34; alt=&#34;出自《琴之森》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/origin.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;出自《琴之森》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;亂曰&#34;&gt;亂曰&lt;/h2&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
不沾水的理智線
　　空想多想。
　泅水吧，撲通
求生意志領你向何方
憑誰問

　　認知邊界不斷衝撞
　　我舞影凌亂
　獨酌，敬
這一年
像極了愛情&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/12/poem.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/12/poem.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;2021-許願&#34;&gt;2021 許願&lt;/h2&gt;
&lt;p&gt;2021 年，希望自己能做到：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;繼續在信仰裡聆聽與順服。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;繼續更深度的本質修練。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;繼續增進商務英語聽說能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;開放冒險選項。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就醬。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;彼得・杜拉克 &lt;a href=&#34;https://www.amazon.com/dp/0060878975&#34;&gt;&lt;em&gt;The Practice of Management&lt;/em&gt;&lt;/a&gt; 這本經典著作，2020 年有新的繁體中譯本：《&lt;a href=&#34;https://www.books.com.tw/products/0010858309&#34;&gt;彼得‧杜拉克的管理聖經&lt;/a&gt;》。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2019/12/2019-retrospective/#補血課程&#34;&gt;2019 個人回顧&lt;/a&gt;〉曾大力推薦裘凱宇老師【&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;過好人生學&lt;/a&gt;】這門線上課程。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;這半年來在桌球方面的探索，詳見〈&lt;a href=&#34;//william-yeh.net/post/2020/10/reverse-penhold-backhand/&#34;&gt;直拍橫打兩個月心得小記&lt;/a&gt;〉及〈&lt;a href=&#34;//william-yeh.net/post/2020/11/tt-coaches/&#34;&gt;教練與選手之間&lt;/a&gt;〉兩篇文章。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>教練與選手之間</title>
      <link>//william-yeh.net/post/2020/11/tt-coaches/</link>
      <pubDate>Tue, 03 Nov 2020 22:30:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/11/tt-coaches/</guid>
      
        <description>&lt;p&gt;近來敏捷同溫層流行學習「教練」技能。&lt;/p&gt;
&lt;p&gt;至於我，由於這兩個月以來開始自學桌球的「&lt;a href=&#34;//william-yeh.net/post/2020/10/reverse-penhold-backhand/&#34;&gt;直拍橫打&lt;/a&gt;」技術，關注的重點，自然是「教練」觀念的源頭——&lt;strong&gt;運動&lt;/strong&gt;領域了。&lt;/p&gt;
&lt;p&gt;在尋找相關資訊的過程中，王楠、張怡寧、劉國梁、馬琳⋯⋯當年耳熟能詳的名字不時出現在電腦螢幕前。如今，拜網路之賜，我們有機會從相關訪談中，一窺這些名將當年在役時期，與教練之間、與隊友之間的心路歷程。&lt;/p&gt;
&lt;h2 id=&#34;王楠&#34;&gt;王楠&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E7%8E%8B%E6%A5%A0&#34;&gt;王楠&lt;/a&gt;職業生涯共獲得 24 個世界冠軍。在這段專訪中，談到她與&lt;a href=&#34;https://www.pingpangwang.com/forum.php?mod=viewthread&amp;amp;tid=115402&#34;&gt;曾傳強&lt;/a&gt;教練的師徒情誼，尤其是曾教練幾番語重心長的「汗水跟淚水的一段歷史」評語：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/IFqPzr_Fv20?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;另一段專訪，則道盡運動員異於常人的心理掙扎：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/w4mqCs2W_pY?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;張怡寧&#34;&gt;張怡寧&lt;/h2&gt;
&lt;p&gt;外號「大魔王」的&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%BC%A0%E6%80%A1%E5%AE%81&#34;&gt;張怡寧&lt;/a&gt;，職業生涯共獲得 19 個世界冠軍。她在專訪中多次提到&lt;a href=&#34;https://baike.baidu.com/item/%E6%9D%8E%E9%9A%BC&#34;&gt;李隼&lt;/a&gt;教練對她的影響：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/7Efq3G33sR4?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;劉國梁&#34;&gt;劉國梁&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%88%98%E5%9B%BD%E6%A2%81&#34;&gt;劉國梁&lt;/a&gt;，是第一個成功以直拍橫打技術在世界舞台取得佳績的桌球選手，職業生涯共獲得 11 個世界冠軍。他在專訪中提到自己從頂尖運動員轉換成教練身份時，成功與失敗的內心轉折：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/kenn0Pg0G_I?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;有這些經歷，才成就了日後強大的總教練「劉胖」：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/EEznQmAwzZQ?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/7ZGq_nJwEPo?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;馬琳&#34;&gt;馬琳&lt;/h2&gt;
&lt;p&gt;終於輪到我的私淑對象&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E9%A9%AC%E7%90%B3&#34;&gt;馬琳&lt;/a&gt;了。在這段專訪中，馬琳與&lt;a href=&#34;https://baike.baidu.com/item/%E5%90%B4%E6%95%AC%E5%B9%B3&#34;&gt;吳敬平&lt;/a&gt;教練之間的信任關係，令人動容：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/y0lWogcWaDM?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;於是，我們才有機會一再看到神乎其技的馬琳：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/k26r5iH2wxc?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;福原愛&#34;&gt;福原愛&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E7%A6%8F%E5%8E%9F%E7%88%B1&#34;&gt;福原愛&lt;/a&gt;，從三歲九個月起，在媽媽兼教練的帶領下，開始了又哭又笑的桌球旅程：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/nbkIysoHbKk?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;在這段專訪中，也特別提起與&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%BC%B5%E8%8E%89%E6%A2%93&#34;&gt;湯媛媛&lt;/a&gt;教練亦師亦友的關係，以及與偶像&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E7%8E%8B%E6%A5%A0&#34;&gt;王楠&lt;/a&gt;搭檔雙打的點滴：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/DN5QWf7y9mY?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h2 id=&#34;心志教練&#34;&gt;心志教練&lt;/h2&gt;
&lt;p&gt;隨著這些桌球選手的專訪，回味許多精彩賽事，更對於源自運動領域的「教練」一詞，有更嚴肅的體會。&lt;/p&gt;
&lt;p&gt;心理素質的洞察與操練，是頂尖教練最突出的能力。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;心志教練，最重要的就是被信任。&lt;/p&gt;
&lt;p&gt;      —— Brett Bartholomew《&lt;a href=&#34;https://www.books.com.tw/products/0010814225&#34;&gt;心志教練&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我們人生中，有多少機會能遇到如此這般的「教練」？&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>直拍橫打兩個月心得小記</title>
      <link>//william-yeh.net/post/2020/10/reverse-penhold-backhand/</link>
      <pubDate>Sun, 25 Oct 2020 10:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/10/reverse-penhold-backhand/</guid>
      
        <description>&lt;h2 id=&#34;緣起&#34;&gt;緣起&lt;/h2&gt;
&lt;p&gt;哥哥正式學桌球一年半載了，妹妹暑假時也開始正式上課。身為爸爸，為了避免太早被孩子們追上，除了找空檔與這群有上課的對打，也偷偷思索進步之道。&lt;/p&gt;
&lt;p&gt;有一次，忘了帶自己的日直球拍去，又遇到有人邀約對打，便借教練的橫拍一用。突然發現，儘管我是直拍握法，但這橫拍打起來卻十分順手。&lt;/p&gt;
&lt;p&gt;這擊球感實在難以忘懷。思之數日，突發奇想：既然想換球拍，索性嘗試看看中直、&lt;a href=&#34;https://baike.baidu.com/item/%E7%9B%B4%E6%8B%8D%E6%A8%AA%E6%89%93&#34;&gt;直拍橫打&lt;/a&gt;？&lt;/p&gt;
&lt;p&gt;於是，中年，改變一下揮拍習慣。從日直換成⋯⋯&lt;/p&gt;
&lt;p&gt;用了三十多年的日直，現在才發現，更適合自己的，居然是圓拍短柄的中直。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/10/paddle-compare.jpg&#34; alt=&#34;從日直換成中直&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/10/paddle-compare.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;從日直換成中直&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;如切如磋如琢如磨&#34;&gt;如切如磋，如琢如磨&lt;/h2&gt;
&lt;p&gt;直拍，比橫拍難。&lt;/p&gt;
&lt;p&gt;握法難，就連球拍也難養。&lt;/p&gt;
&lt;p&gt;玩直拍，總讓人想到《&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%B0%8F%E7%8E%8B%E5%AD%90&#34;&gt;小王子&lt;/a&gt;》這段經典對話：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;小王子說：「什麼叫『&lt;strong&gt;馴養&lt;/strong&gt;』？」&lt;/p&gt;
&lt;p&gt;「這是件被遺忘的事。」狐狸說：「馴養就是『&lt;strong&gt;建立關係&lt;/strong&gt;⋯⋯』」&lt;/p&gt;
&lt;p&gt;「建立關係？」&lt;/p&gt;
&lt;p&gt;狐狸說：「不錯。對我來說，你只不過是個小孩，跟其他成千成萬的小孩沒有分別，我不需要你，你也一樣不需要我。我對於你也只不過是一隻狐狸，跟成千成萬其他的狐狸一模一樣。但是，假如你馴養我，我們就彼此互相需要。你對於我將是世界上唯一的，我對於你也將是世界上唯一的⋯⋯」&lt;/p&gt;
&lt;p&gt;「一個人只要認識他馴養的東西就好。」狐狸說：「很多人不再有時間去認識東西。但是因為商人並不賣朋友，所以很多人沒有朋友。假如你想得到一位朋友，那麼就馴養我吧！」&lt;/p&gt;
&lt;p&gt;「我該怎麼做？」小王子問。&lt;/p&gt;
&lt;p&gt;狐狸回答說：「你該很有耐心。你先坐得離我遠一點，像這樣，坐在草地上。我就拿眼角看你，你不要說話。語言是誤會的泉源。但是，每天你可以坐近我一點⋯⋯」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;直拍，像極了這種「馴養」關係。得很有耐心，每次打完後，用砂紙小磨一點點⋯⋯漸漸地，馴養，合手。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/10/paddle-closeup-1.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/10/paddle-closeup-1.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;



&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/10/paddle-closeup-2.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/10/paddle-closeup-2.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;為了反手位的豎拍角度，拍柄反面也得額外處理：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/10/paddle-closeup-3.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/10/paddle-closeup-3.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;照著幾則 YouTube 教學調整拍柄，總算可以稍微在實戰中順手使出幾次有效的直拍橫打。&lt;/p&gt;
&lt;h2 id=&#34;回不去了&#34;&gt;回不去了&lt;/h2&gt;
&lt;p&gt;桌球真的是對於手感極度敏感的運動。才短短兩個月，已經不太適應以前的日直手感了。&lt;/p&gt;
&lt;p&gt;用了三十多年的日直，現在才發現，更適合自己的，居然是圓拍短柄的中直。&lt;/p&gt;
&lt;p&gt;有所變，有所不變。&lt;/p&gt;
&lt;p&gt;不變的是，依然鍾愛大芯軟彈的手感。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/10/paddle-use.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/10/paddle-use.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;



&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/10/paddle.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/10/paddle.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;直拍橫打入門教學影片&#34;&gt;直拍橫打入門教學影片&lt;/h2&gt;
&lt;p&gt;在台灣，直拍橫打的教練不常見。&lt;/p&gt;
&lt;p&gt;所幸有 YouTube。&lt;/p&gt;
&lt;h3 id=&#34;基本概念&#34;&gt;基本概念&lt;/h3&gt;
&lt;p&gt;反手位的處理，是直拍橫打與傳統日直的主要不同：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/sv5EP3U1BrE?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;戰術觀念也要跟著改變：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/Velentyqy3g?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;唐瑤說明直拍橫打技術的發展現況：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/ON91nJgyF9A?start=1390?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h3 id=&#34;握拍法&#34;&gt;握拍法&lt;/h3&gt;
&lt;p&gt;直拍是很個人化的。因此，直拍橫打的握拍法，也和傳統直拍一樣，存在不同的說法。&lt;/p&gt;
&lt;p&gt;我不是專業人士，只能博採眾議，多方嘗試，再逐漸調整出適合自己的方式。&lt;/p&gt;
&lt;p&gt;以下就列出幾個我參考過的。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;首先，談到直拍橫打，自然不能略過這項技術霸主——王皓的現身說法：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/iTfdz1dNFh8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;乒乓网的《&lt;a href=&#34;https://www.pingpangwang.com/qmxpp-0-0-0-0-0-0-0-2-0-1.html&#34;&gt;全民学乒乓直拍篇&lt;/a&gt;》，算是我看到最細膩的握拍解說。其中，第 1.1 集說明直拍打磨的重點：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/39pzXcpEoXo?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;第 1.3 集解說「正手利」與「反手利」握拍方式的利弊：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/Q08Sm-uiGqk?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;乒乓网「&lt;a href=&#34;https://www.youtube.com/watch?v=4HbnKEMKSRc&#34;&gt;濕父&lt;/a&gt;」郭云鹏的這兩段影片解說也很細膩。第一段：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/WotfSrZDL5s?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;第二段，解說最基本的拍型控制：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/NAxbMZtuVoA?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;唐瑤的這兩段解說也很仔細。第一段：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/oLlVar_XFwk?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;第二段：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/UqG26qFSG7c?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;可再參考看看吴迪的解說：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/raTtRt09YcA?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;也可參考鄒陽的解說：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/qrPsxtH0mhY?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h3 id=&#34;基礎功夫先練推擋撞擊&#34;&gt;基礎功夫，先練推擋撞擊&lt;/h3&gt;
&lt;p&gt;可先看唐瑤的解說：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/6kQSPYOZZr8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;郭焱有一系列很棒的教學影片，值得仔細觀摩。第一段影片，主張「先練擊打，再練摩擦」的順序：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/AsH37NOXeNc?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;第二段，提醒直拍橫打初學者，要先學會穩定控制手指及手腕：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/WeZPeAjgP98?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;可再參考看看吴迪的解說：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/tn-58hMY9BI?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;也可參考廖教練的解說：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/z8GKwV5AK1g?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;也可參考鄒陽的解說：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/Wpr07cU1baQ?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;最後，看看馬凱旋兩段糾正問題的影片。第一段：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/ib_UuzuGOJE?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;第二段：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/JDDLwfg8S9Q?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;h3 id=&#34;進階功夫加強力量與摩擦&#34;&gt;進階功夫，加強力量與摩擦&lt;/h3&gt;
&lt;p&gt;郭焱解說加強摩擦的方式與判斷擊球點：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/O4JAZZkwTxg?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;馮元瀚解釋銜接動作的姿勢與重心要點：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/_VQ9BjtMii8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;「濕父」解說調節拍面與距離，以加強力量的技術：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/FtL35YGT3ek?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;「濕父」糾正引拍與發力的問題：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/b0mGcP8iURM?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;馬凱旋糾正出檯球的引拍與發力問題：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/75rK1CmNjh4?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;光是這些影片，就足以讓初學者認真揣摩好一陣子。&lt;/p&gt;
&lt;h2 id=&#34;桌球反彈板&#34;&gt;桌球反彈板&lt;/h2&gt;
&lt;p&gt;沒有教練指導，又沒有對練者，光看影片，學得了直拍橫打嗎？&lt;/p&gt;
&lt;p&gt;此時，不妨善用「濕父」代言的&lt;a href=&#34;https://www.youtube.com/playlist?list=PL0DA6jASDSbqeMJBjdRlNQTJJRp6XZthQ&#34;&gt;反彈板&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在辦公室裡放一塊反彈板，有事沒事就練上幾分鐘，當作公餘的伸展放鬆。對這反彈板，得有主動發力的意識，才能夠來來回回好幾趟。如此發力，約十分鐘，就開始出汗了。&lt;/p&gt;
&lt;p&gt;對我來說，正手位不難，當作暖身。暖身後，就開始磨練直拍橫打的反手位。每次不求多，但求不間斷。一兩個禮拜下來，漸漸掌握到拍面調節與擊球力道，也漸漸能夠簡單地一來一回好幾趟，頗有成就感。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/10/bouncing-board.jpg&#34; alt=&#34;桌球反彈板&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/10/bouncing-board.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;桌球反彈板&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上就是這兩個月以來自練直拍橫打的心得。&lt;/p&gt;
&lt;p&gt;桌球是少數幾個對場地要求不高，從四歲到九十歲都可以樂在其中的運動。從細膩到粗獷的多變風格，更是迷人。時值中年，還有機會能夠重拾學齡期練球的樂趣，也算難得。僅以此文做個小紀錄。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>值得你看門道的好書——《獨角獸專案》推薦序</title>
      <link>//william-yeh.net/post/2020/10/unicorn-project-review/</link>
      <pubDate>Sat, 03 Oct 2020 10:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/10/unicorn-project-review/</guid>
      
        <description>&lt;p&gt;2011 年 8 月，瀏覽器之父 &lt;a href=&#34;https://en.wikipedia.org/wiki/Marc_Andreessen&#34;&gt;Marc Andreessen&lt;/a&gt; 曾在華爾街日報&lt;a href=&#34;https://online.wsj.com/article/SB10001424053111903480904576512250915629460.html&#34;&gt;評論&lt;/a&gt;道：「軟體正在蠶食整個世界」(software is eating the world)。&lt;/p&gt;
&lt;p&gt;接下來這十年，果然如他所預言，世界徹底被軟體顛覆。各行業，如果不對軟體研發的重要思潮保持關注，就無法善用科技力量站在競爭力的最前線。&lt;/p&gt;
&lt;p&gt;近十年，軟體研發界有兩大類重要思潮。在技術面，有大數據、機器學習、immutable infrastructure、微服務、容器、函式編程、資料流水線等；在流程面，則有敏捷開發、DevOps、自助服務、混亂工程、精實 UX 等。這些思潮，有些是新發明，有些則是文藝復興，甚至是跨界學習而來。&lt;/p&gt;
&lt;p&gt;這些思潮，不只是純軟體界在乎，就連《&lt;a href=&#34;https://itrevolution.com/the-unicorn-project/&#34;&gt;獨角獸專案&lt;/a&gt;》這本小說的場景設定：汽車零件製造商暨零售商，影響一樣深遠。畢竟「軟體正在蠶食整個世界」。&lt;/p&gt;
&lt;p&gt;某方面來說，《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865026653&#34;&gt;獨角獸專案&lt;/a&gt;》這本書，可謂 2010～2020 這個波瀾壯闊時代軟體研發界的具體縮影。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:15em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/10/the-unicorn-project.png&#34; alt=&#34;獨角獸專案 (The Unicorn Project)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/10/the-unicorn-project.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;獨角獸專案 (The Unicorn Project)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;在這小說中，你可以看到在「無極限零件公司」這樣年營業額 40 億美元的製造商暨零售商中，行銷企劃部門、軟體研發部門、服務維運部門彼此爭功諉過的寫實場景。你會看到故事主角梅克辛如何在穀倉泥淖中獨自展開她的「英雄之旅」，與地下反抗軍合作，導入先進的軟體研發思潮。正當一切似乎漸入佳境時，居然還有一條懸疑支線在背後悄悄醞釀⋯⋯高潮迭起，頗有潛力改編成劇情片。&lt;/p&gt;
&lt;p&gt;如果你是愛看熱鬧的小說族，你會喜歡它的。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;如果你是非技術人，「軟體正在蠶食整個世界」，於公於私，免不了必須與組織內外的技術人打交道。因此，這本書請不要走馬看花。請設身處地多讀幾次，增長同理心，瞭解這群愛說外星語的「外星人」的日常，有助於你和諧推動工作任務。尤其是新產品上線前的兵荒馬亂局面，請不吝對這群外星人多給些關愛的行動。&lt;/p&gt;
&lt;p&gt;如果你是第一線的軟體研發者，這本寫實刻劃日常甘苦的書，能點燃或重燃你的熱情，像故事主角梅克辛及反抗軍一樣，用技術改變世界，至少改變公司。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;當然啦，內行看門道。這本奇書，並不止於小說，而是真正可以照表操課的。&lt;/p&gt;
&lt;p&gt;如果你是技術經理人，在對劇情發展擊節讚歎之餘，不妨換位思考：換作是我，會如何決定優先順序？會如何設定領先指標？會如何協調目標衝突的相關部門？會如何兼顧近憂與遠慮？如何形塑適合 IT 滋長的企業文化？如何處理外部利害關係人的財務表現壓力？&lt;/p&gt;
&lt;p&gt;在前一部姊妹作《&lt;a href=&#34;https://itrevolution.com/the-phoenix-project/&#34;&gt;鳳凰專案&lt;/a&gt;》中，神祕人物埃瑞克教導了&lt;a href=&#34;https://itrevolution.com/the-three-ways-principles-underpinning-devops/&#34;&gt;&lt;strong&gt;三步工作法&lt;/strong&gt;&lt;/a&gt;、&lt;strong&gt;四大類工作&lt;/strong&gt;，引導無極限零件公司的維運團隊走出裁撤危機，成為 IT 敏捷力的堅強後盾。如今，在這本《獨角獸專案》裡，埃瑞克以另一個神祕的碼頭酒吧酒保身分亮相，教導了企業經營的&lt;strong&gt;三層面&lt;/strong&gt;、&lt;strong&gt;四大區域顧客群&lt;/strong&gt;、系統與組織的&lt;a href=&#34;https://itrevolution.com/five-ideals-of-devops/&#34;&gt;&lt;strong&gt;五大理念&lt;/strong&gt;&lt;/a&gt;，引導無極限零件公司的研發團隊站在企業視角，以敏捷的 IT 能力驅動並翻轉整間公司的競爭力。&lt;/p&gt;
&lt;p&gt;一言以蔽之，本書鎖定在敏捷性，尤其是企業敏捷性。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這麼精彩的書，只讀一遍是不夠的。&lt;/p&gt;
&lt;p&gt;我鼓勵讀者們，第一遍看熱鬧，第二遍看門道。第一遍速讀，先享受高潮起伏的劇情，並熟悉人物與關係。第二遍重讀時，請以「&lt;strong&gt;核心業務&lt;/strong&gt;與&lt;strong&gt;脈絡業務&lt;/strong&gt;」及「系統與組織的&lt;strong&gt;五大理念&lt;/strong&gt;」兩種觀點細讀，從頭分析故事的人事時地物及因果關係。經此一番系統思考，比起許多愛談高大上理念的敏捷、DevOps、數位轉型書籍，你將會有更深刻具體的領悟。&lt;/p&gt;
&lt;p&gt;橫看成嶺側成峰，願你能從中獲益。&lt;/p&gt;
&lt;p&gt; 　 　 　 　 　 　—— 敏捷魔藥師　葉秉哲 (William Yeh)　2020-10-03&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      《獨角獸專案》系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 值得你看門道的好書——《獨角獸專案》推薦序&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/&#34;&gt;從系統思考角度讀《獨角獸專案》&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>推薦序：讓 GitLab 成為數位轉型的重要推手</title>
      <link>//william-yeh.net/post/2020/09/learning-gitlab-review/</link>
      <pubDate>Mon, 28 Sep 2020 14:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/09/learning-gitlab-review/</guid>
      
        <description>&lt;p&gt;「如今的 GitLab 已經不是單純的 Git service，而是具備完整 workflow 的 DevOps platform。」&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;2019 年，我因爲工作需要，得開始研究 GitLab 某些功能。巧合的是，當時我也正擔任「&lt;a href=&#34;https://ithelp.ithome.com.tw/2020ironman&#34;&gt;第 11 屆 iT 邦幫忙鐵人賽&lt;/a&gt;」評審，就在陳正瑋【&lt;a href=&#34;https://ithelp.ithome.com.tw/users/20120986/ironman/2733&#34;&gt;和艦長一起 30 天玩轉 GitLab&lt;/a&gt;】參賽文章中，學到我所需要知道的一切。&lt;/p&gt;
&lt;p&gt;後來，陳正瑋的這系列文章不負眾望，榮獲 DevOps 組冠軍。&lt;/p&gt;
&lt;p&gt;頒獎典禮上，我鼓勵陳正瑋將這系列文章整理修潤，成為華文世界第一本 GitLab 專書。畢竟，我實在想不到有誰能夠比鐵人賽冠軍、GitLab 官方認證的 “GitLab Hero” 更適合做這件事的人。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:15em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/09/learning-gitlab.jpg&#34; alt=&#34;和艦長一起 30 天玩轉 GitLab&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/09/learning-gitlab.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;和艦長一起 30 天玩轉 GitLab&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&#34;https://chengweichen.com/&#34;&gt;陳正瑋&lt;/a&gt;，在業界暱稱為「&lt;strong&gt;艦長&lt;/strong&gt;」。早在 2015 年，那個台灣對於 DevOps 還懞懞懂懂的年代，正瑋與一群熱血份子就率先成立 &lt;a href=&#34;https://devopstw.club/&#34;&gt;DevOps Taiwan 社群&lt;/a&gt;，舉辦 Meetup 及數屆 DevOpsDays Taipei 大會，對於推廣 DevOps 觀念及技術，有難以磨滅的貢獻。因此，他也一直被起鬨「支持正瑋無限期連任 DevOps Taiwan 社群組織者」。&lt;/p&gt;
&lt;p&gt;有技術，有熱情，由他來詮釋 DevOps，我們是充滿信心的。&lt;/p&gt;
&lt;p&gt;在這本《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789864345311&#34;&gt;和艦長一起 30 天玩轉 GitLab&lt;/a&gt;》書中，你並不會看到他一股腦推銷 GitLab 功能，而是不斷為文提醒讀者反思：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我們真的需要這功能嗎？&lt;/li&gt;
&lt;li&gt;我們真的準備好要進入這麼一個深不見底、看不到盡頭的技術坑嗎？&lt;/li&gt;
&lt;li&gt;天有不測風雲，萬一 CI/CD 自動化系統出了問題，我們真的有手動處理的備案嗎？&lt;/li&gt;
&lt;li&gt;我們真的有在做「持續整合」嗎？還是只是部分的「工作自動化」？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;畢竟，如同正瑋一再提醒的：「DevOps 涉及&lt;strong&gt;文化&lt;/strong&gt;、&lt;strong&gt;實踐方法&lt;/strong&gt;及&lt;strong&gt;工具&lt;/strong&gt;，企業組織必須從這三個層面多管齊下，才有機會成功實踐 DevOps。」這本書是起點，不是終點，希望大家除了學會 GitLab 這麼優異的 DevOps platform 之外，更能深刻探討 DevOps 背後的文化及實踐方法，讓 GitLab 成為數位轉型的重要推手。&lt;/p&gt;
&lt;p&gt;  　   —— 敏捷魔藥師　葉秉哲 (William Yeh)&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>從系統思考角度讀《目標》：第一～三章</title>
      <link>//william-yeh.net/post/2020/09/systhinking-goal-ch01-03/</link>
      <pubDate>Sun, 13 Sep 2020 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/09/systhinking-goal-ch01-03/</guid>
      
        <description>&lt;h2 id=&#34;緣起&#34;&gt;緣起&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Eliyahu_M._Goldratt&#34;&gt;高德拉特&lt;/a&gt;系列著作是我的管理啟蒙書，《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》更是每隔一陣子就會重讀的經典。&lt;/p&gt;
&lt;p&gt;這次，我打算以系統思考 (systems thinking) 角度重讀。尤其是以我在【&lt;a href=&#34;//william-yeh.net/post/2018/06/sys-thinking-workshop/&#34;&gt;系統思考的四堂課&lt;/a&gt;】提出的「&lt;strong&gt;SLR·CPI 法&lt;/strong&gt;」來逐步分析。&lt;/p&gt;
&lt;p&gt;土井英司在《&lt;a href=&#34;http://www.books.com.tw/products/0010762830&#34;&gt;一流的人讀書，都在哪裡畫線？&lt;/a&gt;》點出箇中訣竅：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;世上的一切都有「原因」與「結果」，線要畫在原因上，而非結果上。只要掌握這個基礎，就能在書中畫出很好的線。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;用土井英司這種方法重啃經典，燒腦，進度慢，但在腦中結晶的速度卻快多了。&lt;/p&gt;
&lt;p&gt;我也發現，小說體裁絲毫不減《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》這本書值得劃線的區域，反而能提供更多脈絡。&lt;/p&gt;
&lt;p&gt;就先從第一～三章開始吧。&lt;/p&gt;
&lt;h2 id=&#34;current-reality-tree-crt&#34;&gt;Current Reality Tree (CRT)&lt;/h2&gt;
&lt;p&gt;《目標》第一～三章主要在描述故事主角羅哥 (Alex Rogo) 所負責的工廠、以及所隸屬的事業部，目前正遭遇的困境。&lt;/p&gt;
&lt;p&gt;根據敘事及對話，再略加推演，可繪出初步的 CRT。為了方便查考，括號中列出對應的《目標》中譯本頁碼。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/09/crt-ch1-3.png&#34; alt=&#34;《目標》§1--§3 Current Reality Tree&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/09/crt-ch1-3.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《目標》§1--§3 Current Reality Tree&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;causal-loop-diagram-cld&#34;&gt;Causal Loop Diagram (CLD)&lt;/h2&gt;
&lt;p&gt;進一步萃取本質，可發現，此處至少出現了兩個&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype&#34;&gt;系統基模&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;第一個是「飲鴆止渴」(&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype#Fixes_that_fail&#34;&gt;fixes that fail&lt;/a&gt;)，症狀解反而會回頭加劇問題：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/09/cld-ch1-3-part1.png&#34; alt=&#34;《目標》§1--§3 Causal Loop Diagram (Part 1)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/09/cld-ch1-3-part1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《目標》§1--§3 Causal Loop Diagram (Part 1)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;第二個是「捨本逐末」(&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype#Shifting_the_burden&#34;&gt;shifting the burden&lt;/a&gt;)，症狀解反而會侵蝕實施根本解的能力：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/09/cld-ch1-3-part2.png&#34; alt=&#34;《目標》§1--§3 Causal Loop Diagram (Part 2)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/09/cld-ch1-3-part2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《目標》§1--§3 Causal Loop Diagram (Part 2)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;合併起來，這就是《目標》第一～三章所述困境的本質：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/09/cld-ch1-3-all.png&#34; alt=&#34;《目標》§1--§3 Causal Loop Diagram (All)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/09/cld-ch1-3-all.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《目標》§1--§3 Causal Loop Diagram (All)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;poogi-聚焦五步驟&#34;&gt;POOGI 聚焦五步驟&lt;/h2&gt;
&lt;p&gt;故事中羅哥的上司：事業部副總裁皮區 (Bill Peach)，雖然一出場就幫了個倒忙，但不以人廢言，有段教訓羅哥的話值得深思：「你已經有足夠的人手了！看在老天的分上，看看你們的效率！你還有很多改進的空間。先證明給我看你可以有效運用現有人力，否則就別哭訴人手不夠！」&lt;/p&gt;
&lt;p&gt;這還滿符合 &lt;a href=&#34;https://www.tocinstitute.org/five-focusing-steps.html&#34;&gt;POOGI&lt;/a&gt; 的起手式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Identify 確認瓶頸／限制／制約因素：「有效運用現有人力」的能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Exploit 決定如何充分運用瓶頸／限制／制約因素：「先證明給我看你可以有效運用現有人力」。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;其實，在第二章的喃喃自語中，主角羅哥已經開始隱隱觸及本質議題了，只是還沒站在適當的視角。所幸，神秘人物鐘納 (Jonah) 即將在《目標》第四章登場，藉由不斷質疑最根本的商業思維，引導羅哥去大膽質疑系統思考點出的本質議題。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      從系統思考角度讀《目標》 - 系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;REFERENCES&lt;/p&gt;
&lt;p&gt;　🅐 &lt;a href=&#34;https://en.wikipedia.org/wiki/Current_reality_tree_%28theory_of_constraints%29&#34;&gt;&lt;strong&gt;Current reality tree&lt;/strong&gt;&lt;/a&gt; (&lt;strong&gt;CRT&lt;/strong&gt;) and &lt;a href=&#34;https://www.tocinstitute.org/five-focusing-steps.html&#34;&gt;&lt;strong&gt;POOGI&lt;/strong&gt;&lt;/a&gt; are from the field of &lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;TOC&lt;/a&gt;&amp;rsquo;s &lt;a href=&#34;https://en.wikipedia.org/wiki/Thinking_processes_%28theory_of_constraints%29&#34;&gt;thinking processes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　🅑 &lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;&lt;strong&gt;Causal loop diagram&lt;/strong&gt;&lt;/a&gt; (&lt;strong&gt;CLD&lt;/strong&gt;) is from the field of &lt;a href=&#34;https://en.wikipedia.org/wiki/System_dynamics&#34;&gt;system dynamics&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ARTICLES&lt;/p&gt;
&lt;p&gt;　❶ 第一～三章&lt;/p&gt;
&lt;p&gt;　❷ 第四章 (TODO)&lt;/p&gt;
&lt;p&gt;　❸ TODO&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Essence of Scrum</title>
      <link>//william-yeh.net/series/essence-of-scrum/</link>
      <pubDate>Thu, 20 Aug 2020 00:00:00 +0000</pubDate>
      
      <guid>//william-yeh.net/series/essence-of-scrum/</guid>
      
        <description>&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/07/pbr-in-a-nutshell/&#34;&gt;Essence of Scrum: Product Backlog Refinement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/08/daily-scrum-in-a-nutshell/&#34;&gt;Essence of Scrum: Daily Scrum&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-planning-in-a-nutshell/&#34;&gt;Essence of Scrum: Sprint Planning&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-review-in-a-nutshell/&#34;&gt;Essence of Scrum: Sprint Review&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2023/11/scrum-events-agenda/&#34;&gt;Agile Success Recipes: Example Agendas for Efficient Scrum Ceremonies&lt;/a&gt;&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>Essence of Scrum: Sprint Review</title>
      <link>//william-yeh.net/post/2020/08/sprint-review-in-a-nutshell/</link>
      <pubDate>Thu, 20 Aug 2020 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/08/sprint-review-in-a-nutshell/</guid>
      
        <description>&lt;p&gt;This article discusses the essence of &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Review&lt;/span&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;in-a-nutshell&#34;&gt;In a nutshell&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sprint Review&lt;/strong&gt; is a time-boxed&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; event in which the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
 and invited stakeholders inspect what has been &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Done&lt;/span&gt;
 with respect to the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
, gain insight into values, and adapt business strategy if necessary.&lt;/p&gt;
&lt;h2 id=&#34;output&#34;&gt;Output&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An adapted &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog&lt;/span&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;An adapted business strategy and roadmap&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Celebration&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;input&#34;&gt;Input&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Increment&lt;/span&gt;
&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Backlog&lt;/span&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Feedback from real-world customers and markets&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tools-and-techniques&#34;&gt;Tools and Techniques&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Self-managing instead of being conducted solely by &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Master&lt;/span&gt;
, &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Owner&lt;/span&gt;
, or dedicated persons&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encouraging a focus on the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 rather than individual &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Backlog Items&lt;/span&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encouraging a focus on the learning rather than just checking off &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Backlog Items&lt;/span&gt;
.&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diverge-converge meeting pattern&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      &amp;#39;Essence of Scrum&amp;#39; Series
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2020/07/pbr-in-a-nutshell/&#34;&gt;Product Backlog Refinement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2020/08/daily-scrum-in-a-nutshell/&#34;&gt;Daily Scrum&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-planning-in-a-nutshell/&#34;&gt;Sprint Planning&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ Sprint Review&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/11/scrum-events-agenda/&#34;&gt;Agile Success Recipes: Example Agendas for Efficient Scrum Ceremonies&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--info&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2020-11-24 Memo
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;The series of articles have been updated according to the 2020 revision of &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; (published on Nov 2020).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;The &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Review&lt;/span&gt;
 is intended to be an opportunity for learning, not a formal product launch presentation.      &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2017 says that &lt;em&gt;&amp;ldquo;This is an informal meeting, not a status meeting, and the presentation of the Increment is intended to elicit feedback and foster collaboration. [&amp;hellip;] The Scrum Master teaches everyone involved to keep it within the time-box.&amp;rdquo;&lt;/em&gt;     &lt;em&gt;&lt;a href=&#34;https://scrumbook.org/&#34;&gt;A Scrum Book&lt;/a&gt;&lt;/em&gt; even emphasizes that &lt;em&gt;&amp;lsquo;The event should be time-boxed to a maximum of three hours. The focus is on assessing the product. The Development Team should not spend more than about 30 minutes specifically preparing for this event. Too often a team will prop up the product with temporary supporting structures to make it work well for the Sprint Review, or will spend time trying to “impress” the stakeholders with a sophisticated presentation. There is very little opportunity to be convincing here: the product stands on its own. The team demonstrates the product in an environment approximating that of an end user, without any special “demo support,” and without any props that could make the product appear better than it is. A good rule of thumb is: No PowerPoint® (unless your product is PowerPoint).&amp;rsquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2020 says that in the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Review&lt;/span&gt;
, &lt;em&gt;&amp;ldquo;During the event, the Scrum Team and stakeholders review what was accomplished in the Sprint and what has changed in their environment. Based on this information, attendees collaborate on what to do next. [&amp;hellip;] The Sprint Review is a working session and the Scrum Team should avoid limiting it to a presentation.&amp;rdquo;&lt;/em&gt;      &lt;em&gt;&lt;a href=&#34;https://scrumbook.org/&#34;&gt;A Scrum Book&lt;/a&gt;&lt;/em&gt; says that &lt;em&gt;&amp;ldquo;It is good for the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Owner&lt;/span&gt;
 to adopt a vulnerable posture and to hear whether the team endorses and trusts the decisions and directions by which he or she is directing the team, particularly with respect to the product direction and dealing with technical debt and product quality. This helps reinforce the Community of Trust.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumbook.org/&#34;&gt;A Scrum Book&lt;/a&gt;&lt;/em&gt; suggests that &lt;em&gt;&amp;ldquo;A Sprint Review is an opportunity for the team to reflect on their accomplishments during the past Sprint, which contributes to growth in Product Pride. A Sprint Review can be a form of celebration if the team reaches a particularly noteworthy goal, or just for the sake of celebrating now and then. A company in Finland would occasionally have a Sprint Review in a sauna, with good food and drink, going late into the evening. The event covered the perfunctory agenda items but the real focus was for the team to celebrate its work together. (Thanks to Jukka Järvelä for this story!).&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; uses the term &amp;ldquo;&lt;a href=&#34;https://www.scrumguides.org/scrum-guide.html#artifacts-increment&#34;&gt;&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Increment&lt;/span&gt;
&lt;/a&gt;&amp;rdquo; to refer to &lt;em&gt;&amp;ldquo;the sum of all the Product Backlog items completed during a Sprint and the value of the increments of all previous Sprints.&amp;rdquo;&lt;/em&gt;     To be more precise, &lt;em&gt;&lt;a href=&#34;https://scrumbook.org/&#34;&gt;A Scrum Book&lt;/a&gt;&lt;/em&gt; uses the term &amp;ldquo;&lt;a href=&#34;https://scrumbook.org.datasenter.no/value-stream/regular-product-increment.html&#34;&gt;&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Regular Product Increment&lt;/span&gt;
&lt;/a&gt;&amp;rdquo;, and  &lt;a href=&#34;https://less.works/&#34;&gt;LeSS&lt;/a&gt; uses the term &amp;ldquo;&lt;a href=&#34;https://less.works/less/framework/potentially-shippable-product-increment&#34;&gt;&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Potentially Shippable Product Increment&lt;/span&gt;
&lt;/a&gt;&amp;rdquo; (often abbreviated as &amp;ldquo;PSPI&amp;rdquo;).&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://www.amazon.com/dp/1492033510&#34;&gt;Agile for Everybody&lt;/a&gt;&lt;/em&gt; says that &lt;em&gt;&amp;lsquo;One of the many ways that organizational leaders often accidentally undermine Agile principles is to continue asking only company-centric questions, such as “Are we on time and on budget?” and “Has your manager approved this?” as opposed to customer-centric questions, such as “How do our customers feel about this change to the product?” One immediate and powerful sign that you’re on the right track is that leaders are asking customer-centric questions or, even better, referring directly to customer quotes and insights.&amp;rsquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2020 says that &lt;em&gt;&amp;ldquo;The &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Review&lt;/span&gt;
 is a working session and the Scrum Team should avoid limiting it to a presentation.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://less.works/&#34;&gt;LeSS&lt;/a&gt; advocates the &amp;ldquo;Inspect-Adapt and &lt;em&gt;not&lt;/em&gt; Inspect-Accept&amp;rdquo; concept: &lt;em&gt;&amp;ldquo;The most common mistake in a Sprint Review is to focus on the Product Owner accepting items from the teams. This is a misunderstanding of the purpose of the Sprint Review and moves it away from &lt;a href=&#34;https://less.works/less/principles/empirical-process-control.html&#34;&gt;empirical process control&lt;/a&gt; towards finding blame. The Sprint Review is an opportunity for everyone to collaborate about the product.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://less.works/&#34;&gt;LeSS&lt;/a&gt; advocates a bazaar-style Sprint Review: &lt;em&gt;&amp;ldquo;The Sprint Review is best conducted using a diverge-converge meeting pattern. During the diverge periods, use a bazaar. This is analogous to a science fair: A large room has multiple areas, each staffed by team representatives, where the items developed by a team are shown and discussed. Stakeholders visit areas of interest. During the converge periods, stakeholders summarize their opinions from the bazaar. A subset of items may be inspected on a common computer projector during this time, also.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>Essence of Scrum: Sprint Planning</title>
      <link>//william-yeh.net/post/2020/08/sprint-planning-in-a-nutshell/</link>
      <pubDate>Sun, 09 Aug 2020 13:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/08/sprint-planning-in-a-nutshell/</guid>
      
        <description>&lt;p&gt;This article discusses the essence of &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Planning&lt;/span&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;in-a-nutshell&#34;&gt;In a nutshell&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sprint Planning&lt;/strong&gt; is a time-boxed&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; event in which the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
 defines the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 and makes a feasible plan for the goal, to the best knowledge, information and belief of the team.&lt;/p&gt;
&lt;h2 id=&#34;output&#34;&gt;Output&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A feasible plan for achieving the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Backlog Items&lt;/span&gt;
 with the property of &lt;strong&gt;INVEST&lt;/strong&gt; (Independent, Negotiable, Valuable, Estimable, Small, Testable)&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A coherent &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and expectation for the outcome to be seen at &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Review&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;input&#34;&gt;Input&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Strategy breakdown (e.g., product roadmap, &lt;a href=&#34;https://www.whatmatters.com/faqs/okr-meaning-definition-example/&#34;&gt;OKR&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/OGSM&#34;&gt;OGSM&lt;/a&gt;, &lt;a href=&#34;https://www.impactmapping.org/&#34;&gt;impact mapping&lt;/a&gt;, &lt;a href=&#34;https://www.jpattonassociates.com/user-story-mapping/&#34;&gt;user story mapping&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog&lt;/span&gt;
 that has been refined during &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog Refinement&lt;/span&gt;
 and adapted during previous &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Review&lt;/span&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Action items created during previous &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Retrospective&lt;/span&gt;
&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Influences&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The top &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog Items&lt;/span&gt;
 meet the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Definition of Ready&lt;/span&gt;
 criteria&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; defined and evolved by the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tools-and-techniques&#34;&gt;Tools and Techniques&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Short-term strategic planning statements in brief&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Judgment to &lt;strong&gt;balance&lt;/strong&gt; a variety of needs and goals&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;, especially &amp;ldquo;whole product focus&amp;rdquo;&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt; and technical excellence&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Logical approach to ordering items&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Logical approach to breaking down items&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Estimation in proper granularity&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encouraging a focus on the team rather than individuals.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Two parts planning&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SPIDR (Spike, Paths, Interfaces, Data, and Rules)&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt; (should be used in &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog Refinement&lt;/span&gt;
 as well)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Techniques for enabling specification&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt; (should be used in &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog Refinement&lt;/span&gt;
 as well)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Visualized &lt;a href=&#34;https://scrumbook.org/value-stream/information-radiator.html&#34;&gt;information radiators&lt;/a&gt; (e.g., Scrum board, Kanban board).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Self-managing instead of being conducted solely by &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Master&lt;/span&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encouraging participative decision-making in proposal and ordering of &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Backlog Items&lt;/span&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2017/07/sprint-planning-as-negotiation/&#34;&gt;以談判角度看 Sprint Planning (Sprint Planning: A Negotiation Perspective)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      &amp;#39;Essence of Scrum&amp;#39; Series
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2020/07/pbr-in-a-nutshell/&#34;&gt;Product Backlog Refinement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2020/08/daily-scrum-in-a-nutshell/&#34;&gt;Daily Scrum&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ Sprint Planning&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-review-in-a-nutshell/&#34;&gt;Sprint Review&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/11/scrum-events-agenda/&#34;&gt;Agile Success Recipes: Example Agendas for Efficient Scrum Ceremonies&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--info&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2020-11-24 Memo
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;The series of articles have been updated according to the 2020 revision of &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; (published on Nov 2020).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; says that &lt;em&gt;&amp;ldquo;Sprint Planning is time-boxed to a maximum of eight hours for a one-month Sprint. For shorter Sprints, the event is usually shorter. [&amp;hellip;] The Scrum Master teaches the Scrum Team to keep it within the time-box.&amp;rdquo;&lt;/em&gt;      &lt;em&gt;&lt;a href=&#34;https://scrumbook.org/&#34;&gt;A Scrum Book&lt;/a&gt;&lt;/em&gt; suggests that &lt;em&gt;&amp;ldquo;It is important that Sprint Planning allow time for enough design to create a well-understood Sprint Backlog. But the planning should be time-boxed. A rule of thumb is that the event should take no more than four hours for a two-week Sprint and proportionally less for shorter Sprints. If it takes longer, it takes longer—but seek kaizen opportunities to reduce the amount of time to plan and to correspondingly increase the time spent on building product.&amp;rdquo;&lt;/em&gt;     &lt;a href=&#34;http://teddy-chen-tw.blogspot.com/&#34;&gt;Teddy Chen&lt;/a&gt; advocates in &lt;a href=&#34;http://teddy-chen-tw.blogspot.com/2012/01/scrum-6sprint-planning-meeting.html&#34;&gt;his article&lt;/a&gt; sticking to the timebox to avoid the &amp;ldquo;big up-front design&amp;rdquo; symptom.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.agilealliance.org/glossary/invest/&#34;&gt;Agile Alliance&lt;/a&gt; says that &lt;em&gt;&amp;ldquo;The acronym INVEST helps to remember a widely accepted set of criteria, or checklist, to assess the quality of a user story.&amp;rdquo;&lt;/em&gt;      Read Bob Hartman&amp;rsquo;s article &amp;ldquo;&lt;a href=&#34;https://agileforall.com/new-to-agile-invest-in-good-user-stories/&#34;&gt;New to agile? INVEST in good user stories&lt;/a&gt;&amp;rdquo; for more info.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Scrum works better when it is considered an enabling engine toward a coherent goal rather than just a collection of work packages by chance.      &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2020 version says that &lt;em&gt;&amp;ldquo;the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 also creates coherence and focus, encouraging the Scrum Team to work together rather than on separate initiatives.&amp;rdquo;&lt;/em&gt;     &lt;em&gt;&lt;a href=&#34;https://scrumbook.org/&#34;&gt;A Scrum Book&lt;/a&gt;&lt;/em&gt; says that &lt;em&gt;&amp;ldquo;The Scrum Team can use the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 to frame the selection of PBIs for the Sprint but in some sense the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 is more important even than the sum of the individual PBIs.&amp;rdquo;&lt;/em&gt;     Roman Pichler says in his article &amp;ldquo;&lt;a href=&#34;https://www.romanpichler.com/blog/sprint-goal-template/&#34;&gt;A Template for formulating great sprint goals&lt;/a&gt;&amp;rdquo; that &lt;em&gt;&amp;ldquo;your sprint goal should differ from your user stories. The goal explains the why it is a good idea to carry out the sprint an implement the stories. The user stories enable you to reach the goal. It’s a common mistake to confuse the two.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2017 puts more emphasis on the follow-up actions for &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Retrospective&lt;/span&gt;
: &lt;em&gt;&amp;ldquo;To ensure continuous improvement, it (the Sprint Backlog) includes at least one high priority way in which the team works, identified in the previous Retrospective meeting&amp;rdquo;&lt;/em&gt; (p.16).    In 2020 version it is expressed in a more relaxed tone: &lt;em&gt;&amp;ldquo;The Scrum Team identifies the most helpful changes to improve its effectiveness. The most impactful improvements are addressed as soon as possible. They may even be added to the Sprint Backlog for the next Sprint.&amp;rdquo;&lt;/em&gt;     &lt;a href=&#34;https://www.linkedin.com/in/emersonmills&#34;&gt;Emerson Mills&lt;/a&gt; suggested in his &lt;a href=&#34;http://teddy-chen-tw.blogspot.com/2012/10/certified-scrummaster.html&#34;&gt;CSM class&lt;/a&gt; putting these identified technical improvements into &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Planning&lt;/span&gt;
 Part 2 (source: “&lt;a href=&#34;http://teddy-chen-tw.blogspot.com/2012/12/certified-scrummaster1.html&#34;&gt;我在第二次 Certified ScrumMaster 課程學到的事（1）&lt;/a&gt;”.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2017 says that &lt;em&gt;&amp;ldquo;Each Sprint may be considered a project with no more than a one-month horizon&amp;rdquo;&lt;/em&gt; (p.9).  In this regard, a sprint cannot be immune from influences discussed in the &lt;a href=&#34;https://www.pmi.org/pmbok-guide-standards&#34;&gt;&lt;em&gt;PMBOK Guide&lt;/em&gt;&lt;/a&gt;, such as enterprise environmental factors and organizational process assets.&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://scrumbook.org/value-stream/product-backlog/definition-of-ready.html&#34;&gt;Definition of Ready&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Peter_Drucker&#34;&gt;Peter Drucker&lt;/a&gt; emphasized in his book &lt;a href=&#34;https://www.amazon.com/dp/0060878975&#34;&gt;&lt;em&gt;The Practice of Management&lt;/em&gt;&lt;/a&gt; (pp. 62-63, 87) that &lt;em&gt;&amp;ldquo;To manage a business is to balance a variety of needs and goals. This requires judgment. The search for the one objective is essentially a search for a magic formula that will make judgment unnecessary. But the attempt to replace judgment by formula is always irrational; all that can be done is to make judgment possible by narrowing its range and the available alternatives, giving it clear focus, a sound foundation in facts and reliable measurements of the effects and validity of actions and decisions. And this, by the very nature of business enterprise, requires multiple objectives. [&amp;hellip;] Yet, there is no formula for doing the job. Each business requires its own balance—and it may require a different balance at different times.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;The definition of &amp;ldquo;product&amp;rdquo; by the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
 has also defined what is in scope and what is by default out of scope for the team. For example, what parts of Ops should be handled by the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
?    LeSS advocates a &lt;a href=&#34;https://less.works/less/framework/product&#34;&gt;broader product definition&lt;/a&gt; and a “&lt;a href=&#34;https://less.works/less/principles/whole-product-focus&#34;&gt;whole product focus&lt;/a&gt;” point of view: &lt;em&gt;&amp;ldquo;Whenever there is a choice to optimize a team output or the whole product, we always chose the whole product. [&amp;hellip;] In many large product development groups, getting everyone to focus on the whole product instead of their individual parts/tasks/specialization is one of the hardest parts of scaling Scrum. Always keep a whole product focus, keep reminding everyone there is no value in separate parts or half-working parts.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;&amp;ldquo;&lt;a href=&#34;https://agilemanifesto.org/principles.html&#34;&gt;Principles behind the Agile Manifesto&lt;/a&gt;&amp;rdquo; emphasizes that &lt;em&gt;“Continuous attention to technical excellence and good design enhances agility.”&lt;/em&gt; LeSS identifies several areas of &lt;a href=&#34;https://less.works/less/technical-excellence/index&#34;&gt;technical excellence&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scrumalliance.org/community/profile/mikecohn&#34;&gt;Mike Cohn&lt;/a&gt; discusses different levels of estimation activities in his article &amp;ldquo;&lt;a href=&#34;https://www.mountaingoatsoftware.com/blog/why-agile-teams-should-estimate-at-two-different-levels&#34;&gt;Why Agile Teams Should Estimate at Two Different Levels&lt;/a&gt;.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;It is common to divide the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Planning&lt;/span&gt;
 into 2 parts. Here is a good quote from &lt;a href=&#34;https://less.works/less/framework/sprint-planning-one&#34;&gt;LeSS&lt;/a&gt;: &lt;em&gt;&amp;quot;&lt;strong&gt;Sprint Planning One&lt;/strong&gt; focuses on selection of ready items from those offered by the Product Owner, wrapping up lingering questions, and definition of the Sprint Goal. &lt;strong&gt;Sprint Planning Two&lt;/strong&gt; focuses on creating a plan of work to get to ‘done’ for each item. The items and plan of action or tasks comprise the Sprint Backlog.&amp;quot;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scrumalliance.org/community/profile/mikecohn&#34;&gt;Mike Cohn&lt;/a&gt; proposed the SPIDR approach (spike, paths, interfaces, data, and rules) for breaking down user stories. Watch the &amp;ldquo;&lt;a href=&#34;https://www.mountaingoatsoftware.com/exclusive/spidr-video&#34;&gt;Stop Wasting Time Splitting Stories&lt;/a&gt;&amp;rdquo; video for more details.&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://scrumbook.org/value-stream/product-backlog/enabling-specification.html&#34;&gt;Enabling specification&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>Blackbox Exporter 小記</title>
      <link>//william-yeh.net/post/2020/08/blackbox-exporter/</link>
      <pubDate>Fri, 07 Aug 2020 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/08/blackbox-exporter/</guid>
      
        <description>&lt;p&gt;在用 &lt;a href=&#34;https://prometheus.io/&#34;&gt;Prometheus&lt;/a&gt; + &lt;a href=&#34;https://grafana.com/&#34;&gt;Grafana&lt;/a&gt; 監控自家服務的同時，我們也會想用同一套系統去監控第三方服務。&lt;/p&gt;
&lt;p&gt;本文介紹一個好用的 Prometheus 官方工具：&lt;a href=&#34;https://github.com/prometheus/blackbox_exporter&#34;&gt;Blackbox exporter&lt;/a&gt;，可以省下手刻 curl 腳本的工夫。我也順便介紹一些踩過的雷。&lt;/p&gt;
&lt;h2 id=&#34;健康狀況的揭露方式&#34;&gt;健康狀況的揭露方式&lt;/h2&gt;
&lt;p&gt;第三方服務的健康狀況，有不同的自我揭露方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;API：像 Google Cloud 有提供 &lt;a href=&#34;https://status.cloud.google.com/incidents.json&#34;&gt;json endpoint&lt;/a&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Feed：像 AWS 有提供 &lt;a href=&#34;https://status.aws.amazon.com/&#34;&gt;RSS feed&lt;/a&gt;，Google Cloud 有 &lt;a href=&#34;https://status.cloud.google.com/feed.atom&#34;&gt;RSS feed&lt;/a&gt;，Stripe 有 &lt;a href=&#34;https://twitter.com/stripestatus&#34;&gt;Twitter @stripestatus&lt;/a&gt; 及 &lt;a href=&#34;https://status.stripe.com/current/atom.xml&#34;&gt;RSS feed&lt;/a&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;網頁：像 AWS 有提供 &lt;a href=&#34;https://status.aws.amazon.com/&#34;&gt;Service Health Dashboard&lt;/a&gt; 網頁，Google Cloud 有 &lt;a href=&#34;https://status.cloud.google.com/&#34;&gt;Status Dashboard&lt;/a&gt; 網頁，Stripe 有 &lt;a href=&#34;https://status.stripe.com/&#34;&gt;System Status&lt;/a&gt; 網頁。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;統包服務：像 &lt;a href=&#34;https://www.pingdom.com/&#34;&gt;Pingdom&lt;/a&gt;、&lt;a href=&#34;https://downdetector.sg/&#34;&gt;Downdetector&lt;/a&gt; 可以一站通吃想監控的第三方服務群。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不完全揭露。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;針對這些林林總總的揭露方式，&lt;a href=&#34;https://github.com/prometheus/blackbox_exporter&#34;&gt;Blackbox exporter&lt;/a&gt; 提供幾種 &lt;a href=&#34;https://github.com/prometheus/blackbox_exporter/blob/master/CONFIGURATION.md&#34;&gt;prober&lt;/a&gt;：http_probe、
tcp_probe、dns_probe、icmp_probe，即使面對「不完全揭露」自身健康狀況的第三方服務，還是可以在某些程度上間接採集他們的健康狀況，只要你留意這個「採集」的舉動沒有副作用。&lt;/p&gt;
&lt;h2 id=&#34;blackbox-exporter-分工架構&#34;&gt;Blackbox exporter 分工架構&lt;/h2&gt;
&lt;p&gt;在 &lt;a href=&#34;https://prometheus.io/&#34;&gt;Prometheus&lt;/a&gt; 微服務架構中，是讓各種 exporter 先去 probe 各自責任區內的 metrics，再讓 Prometheus 透過 HTTP 去 scrape 這些 exporter 採集到的 metrics。&lt;/p&gt;
&lt;p&gt;基於這個分工體系，&lt;a href=&#34;https://github.com/prometheus/blackbox_exporter&#34;&gt;Blackbox exporter&lt;/a&gt; 負責去 probe 第三方服務的健康狀況，再提供一個 &lt;code&gt;/probe&lt;/code&gt; 介面讓 Prometheus 去蒐集匯總 metrics。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/08/blackbox-exporter-architecture.png&#34; alt=&#34;Blackbox exporter 分工架構&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/08/blackbox-exporter-architecture.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Blackbox exporter 分工架構&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;所以，一開始，我們會先試著寫好 &lt;code&gt;blackbox.yml&lt;/code&gt; 設定檔，先測試 Blackbox exporter 能正常運作，之後才去串接 Prometheus。&lt;/p&gt;
&lt;h2 id=&#34;blackbox-exporter-初體驗&#34;&gt;Blackbox exporter 初體驗&lt;/h2&gt;
&lt;p&gt;官方提供的&lt;a href=&#34;https://github.com/prometheus/blackbox_exporter/blob/master/blackbox.yml&#34;&gt;陽春版 &lt;code&gt;blackbox.yml&lt;/code&gt; 設定檔&lt;/a&gt;展示了一些常見的 blackbox exporter 模組 (module)，很適合初次上手之用：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# https://github.com/prometheus/blackbox_exporter/blob/master/blackbox.yml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;modules&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;http_2xx&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;prober&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;http&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;http_post_2xx&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;prober&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;http&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;http&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;method&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;POST&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;其中，最常用的應該是 http_2xx 模組了。如果你只需要用到這模組，可以不必準備 &lt;code&gt;blackbox.yml&lt;/code&gt; 設定檔。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我們可以先&lt;a href=&#34;https://github.com/prometheus/blackbox_exporter/releases&#34;&gt;下載&lt;/a&gt;並啟動 Blackbox exporter:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./blackbox_exporter&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;預設情況下，Blackbox exporter 會透過 port 9115 提供探測服務。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;現在，讓我們透過 Blackbox exporter 內建的 http_2xx 模組，探測 github.com 的健康狀況：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ curl &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;localhost:9115/probe?target=github.com&amp;amp;module=http_2xx&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;或是乾脆省略掉預設的 http_2xx 模組名稱：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ curl &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;localhost:9115/probe?target=github.com&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    透過 Blackbox exporter 探測 github.com 的輸出結果
    
  &lt;/summary&gt;
  &lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_dns_lookup_time_seconds Returns the time taken for probe dns lookup in seconds
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_dns_lookup_time_seconds gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_dns_lookup_time_seconds 0.057117535
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_duration_seconds Returns how long the probe took to complete in seconds
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_duration_seconds gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_duration_seconds 1.833592006
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_failed_due_to_regex Indicates if probe failed due to regex
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_failed_due_to_regex gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_failed_due_to_regex 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_content_length Length of http content response
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_content_length gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_content_length -1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_duration_seconds Duration of http request by phase, summed over all redirects
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_duration_seconds gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;connect&amp;#34;} 0.425883281
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;processing&amp;#34;} 0.433015322
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;resolve&amp;#34;} 0.086735632
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;tls&amp;#34;} 0.443000784
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;transfer&amp;#34;} 0.663546262
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_redirects The number of redirects
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_redirects gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_redirects 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_ssl Indicates if SSL was used for the final redirect
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_ssl gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_ssl 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_status_code Response HTTP status code
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_status_code gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_status_code 200
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_uncompressed_body_length Length of uncompressed response body
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_uncompressed_body_length gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_uncompressed_body_length 137503
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_version Returns the version of HTTP of the probe response
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_version gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_version 1.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ip_addr_hash Specifies the hash of IP address. It&amp;#39;s useful to detect if the IP address changes.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ip_addr_hash gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ip_addr_hash 2.436894991e+09
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ip_protocol gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ip_protocol 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ssl_earliest_cert_expiry Returns earliest SSL cert expiry in unixtime
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ssl_earliest_cert_expiry gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ssl_earliest_cert_expiry 1.652184e+09
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ssl_last_chain_expiry_timestamp_seconds Returns last SSL chain expiry in timestamp seconds
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ssl_last_chain_expiry_timestamp_seconds gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ssl_last_chain_expiry_timestamp_seconds 1.652184e+09
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_success Displays whether or not the probe was a success
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_success gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_success 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_tls_version_info Contains the TLS version used
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_tls_version_info gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_tls_version_info{version=&amp;#34;TLS 1.3&amp;#34;} 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;~ % curl &amp;#39;localhost:9115/probe?target=github.com&amp;amp;module=http_2xx&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_dns_lookup_time_seconds Returns the time taken for probe dns lookup in seconds
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_dns_lookup_time_seconds gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_dns_lookup_time_seconds 0.025288617
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_duration_seconds Returns how long the probe took to complete in seconds
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_duration_seconds gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_duration_seconds 1.776282033
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_failed_due_to_regex Indicates if probe failed due to regex
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_failed_due_to_regex gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_failed_due_to_regex 0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_content_length Length of http content response
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_content_length gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_content_length -1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_duration_seconds Duration of http request by phase, summed over all redirects
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_duration_seconds gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;connect&amp;#34;} 0.414948208
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;processing&amp;#34;} 0.42066351300000004
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;resolve&amp;#34;} 0.038381098
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;tls&amp;#34;} 0.465243547
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_duration_seconds{phase=&amp;#34;transfer&amp;#34;} 0.65392713
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_redirects The number of redirects
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_redirects gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_redirects 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_ssl Indicates if SSL was used for the final redirect
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_ssl gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_ssl 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_status_code Response HTTP status code
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_status_code gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_status_code 200
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_uncompressed_body_length Length of uncompressed response body
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_uncompressed_body_length gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_uncompressed_body_length 137509
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_http_version Returns the version of HTTP of the probe response
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_http_version gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_http_version 1.1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ip_addr_hash Specifies the hash of IP address. It&amp;#39;s useful to detect if the IP address changes.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ip_addr_hash gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ip_addr_hash 1.664977422e+09
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ip_protocol gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ip_protocol 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ssl_earliest_cert_expiry Returns earliest SSL cert expiry in unixtime
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ssl_earliest_cert_expiry gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ssl_earliest_cert_expiry 1.652184e+09
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ssl_last_chain_expiry_timestamp_seconds Returns last SSL chain expiry in timestamp seconds
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ssl_last_chain_expiry_timestamp_seconds gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ssl_last_chain_expiry_timestamp_seconds 1.652184e+09
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_success Displays whether or not the probe was a success
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_success gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_success 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_tls_version_info Contains the TLS version used
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_tls_version_info gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_tls_version_info{version=&amp;#34;TLS 1.3&amp;#34;} 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/details&gt;

&lt;p&gt;大部分情況下，我們只需要看其中的 &lt;code&gt;probe_success&lt;/code&gt; 這項 gauge 指標：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_success Displays whether or not the probe was a success
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_success gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_success 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;請用 Blackbox exporter 去戳戳看其他網站吧。&lt;/p&gt;
&lt;h2 id=&#34;ipv6ipv4-問題&#34;&gt;IPv6/IPv4 問題&lt;/h2&gt;
&lt;p&gt;如果用 Blackbox exporter 去探測 google.com，會得到很奇怪的結果：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ curl &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;localhost:9115/probe?target=google.com&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;略&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# TYPE probe_ip_protocol gauge&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ip_protocol &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# HELP probe_success Displays whether or not the probe was a success&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# TYPE probe_success gauge&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_success &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;打開 debug 模式查查看：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ curl &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;localhost:9115/probe?target=google.com&amp;amp;debug=true&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Logs &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; the probe:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ts&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2020-08-07T07:42:43.560461Z caller&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;main.go:304 module&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http_2xx target&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;google.com level&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;info msg&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Beginning probe&amp;#34;&lt;/span&gt; probe&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http timeout_seconds&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;119.5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ts&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2020-08-07T07:42:43.561257Z caller&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http.go:323 module&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http_2xx target&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;google.com level&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;info msg&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Resolving target address&amp;#34;&lt;/span&gt; ip_protocol&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;ip6
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ts&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2020-08-07T07:42:43.573101Z caller&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http.go:323 module&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http_2xx target&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;google.com level&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;info msg&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Resolved target address&amp;#34;&lt;/span&gt; ip&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2404:6800:4008:801::200e
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ts&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2020-08-07T07:42:43.57317Z caller&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;client.go:252 module&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http_2xx target&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;google.com level&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;info msg&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Making HTTP request&amp;#34;&lt;/span&gt; url&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http://&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;2404:6800:4008:801::200e&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; host&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;google.com
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ts&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;2020-08-07T07:42:43.573276Z caller&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;main.go:119 module&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;http_2xx target&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;google.com level&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;error msg&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Error for HTTP request&amp;#34;&lt;/span&gt; err&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Get \&amp;#34;http://[2404:6800:4008:801::200e]\&amp;#34;: dial tcp [2404:6800:4008:801::200e]:80: connect: no route to host&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;略&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;從上面的 log 可看到，Blackbox exporter 試圖透過 IPv6 連線到 google.com，導致錯誤。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Prometheus 核心成員 Brian Brazil 在 &amp;ldquo;&lt;a href=&#34;https://www.robustperception.io/checking-for-http-200s-with-the-blackbox-exporter&#34;&gt;Checking for HTTP 200s with the Blackbox Exporter&lt;/a&gt;&amp;rdquo; 文章說明這問題的原因及解法：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You may see a surprising failure if you don&amp;rsquo;t have a working IPv6 setup, as the Blackbox exporter will prefer an IPv6 address if one is returned by DNS.&lt;/p&gt;
&lt;p&gt;You can adjust this behaviour by adding &lt;code&gt;preferred_ip_protocol: &amp;quot;ip4&amp;quot;&lt;/code&gt; to the module&amp;rsquo;s configuration.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，我會在 &lt;code&gt;blackbox.yml&lt;/code&gt; 設定檔當中，增加另一個模組，取一個好記的名字：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;modules&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;# module: expect http_2xx, with ip4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;http_2xx_with_ip4&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;prober&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;http&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;timeout&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;5s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;http&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;preferred_ip_protocol&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ip4&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;#...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;然後，重啟 Blackbox exporter，記得要餵給它新的設定檔：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./blackbox_exporter --config.file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;./blackbox.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;這次，讓我們改用新增的模組去探測 google.com：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ curl &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;localhost:9115/probe?target=google.com&amp;amp;module=http_2xx_with_ip4&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;這次，總算可以看到正常的 &lt;code&gt;probe_success&lt;/code&gt; 了：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_ip_protocol gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_ip_protocol 4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# HELP probe_success Displays whether or not the probe was a success
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# TYPE probe_success gauge
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;probe_success 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;auth&#34;&gt;Auth&lt;/h2&gt;
&lt;p&gt;某些第三方服務的 HTTP 端點需要夾帶 auth 相關欄位。&lt;/p&gt;
&lt;p&gt;像 &lt;a href=&#34;https://stripe.com/docs/api/authentication?lang=curl&#34;&gt;Stripe API 文件&lt;/a&gt;就說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Authentication to the API is performed via HTTP Basic Auth. Provide your API key as the basic auth username value. You do not need to provide a password.&lt;/p&gt;
&lt;p&gt;If you need to authenticate via bearer auth (e.g., for a cross-origin request), use &lt;code&gt;-H &amp;quot;Authorization: Bearer sk_test_4eC39HqLyjWDarjtT1zdp7dc&amp;quot;&lt;/code&gt; instead of &lt;code&gt;-u sk_test_4eC39HqLyjWDarjtT1zdp7dc&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;那麼，這段 auth 資訊該放到 &lt;code&gt;prometheus.yml&lt;/code&gt; 還是 &lt;code&gt;blackbox.yml&lt;/code&gt; 設定檔？畢竟與 basic_auth 相關的設定內容，在 &lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config&#34;&gt;Prometheus 設定文件&lt;/a&gt;及 &lt;a href=&#34;https://github.com/prometheus/blackbox_exporter/blob/master/CONFIGURATION.md#http_probe&#34;&gt;Blackbox exporter 設定文件&lt;/a&gt;都出現過。&lt;/p&gt;
&lt;p&gt;動手實驗看看吧！&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;實驗程式放在 &lt;a href=&#34;https://github.com/William-Yeh/blackbox-exporter-demo&#34;&gt;https://github.com/William-Yeh/blackbox-exporter-demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;實驗所需環境：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker 19.03.12 以上。&lt;/li&gt;
&lt;li&gt;Docker Compose 1.26.2 以上。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我設計了兩個 Prometheus job，分別對應到兩種不同的 basic_auth 擺放位置：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Prometheus Job&lt;/th&gt;
          &lt;th&gt;prometheus.yml&lt;/th&gt;
          &lt;th&gt;blackbox.yml&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/blackbox-exporter-demo/blob/04cbedfd1b3c035bead29d0b8ecedbbfe137ddac/prometheus.yml#L46&#34;&gt;stripe-healthcheck&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;✓ &lt;a href=&#34;https://github.com/William-Yeh/blackbox-exporter-demo/blob/04cbedfd1b3c035bead29d0b8ecedbbfe137ddac/blackbox.yml#L24-L25&#34;&gt;basic_auth&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/blackbox-exporter-demo/blob/04cbedfd1b3c035bead29d0b8ecedbbfe137ddac/prometheus.yml#L63&#34;&gt;stripe-healthcheck-wrong-config&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;✓ &lt;a href=&#34;https://github.com/William-Yeh/blackbox-exporter-demo/blob/04cbedfd1b3c035bead29d0b8ecedbbfe137ddac/prometheus.yml#L68-L69&#34;&gt;basic_auth&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一切準備就緒，來試試看哪一種寫法才是對的吧。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;請用 Docker Compose 執行：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ docker-compose up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;請用瀏覽器打開 &lt;a href=&#34;http://localhost:9090/&#34;&gt;http://localhost:9090/&lt;/a&gt; 進入 Prometheus 儀表板：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/08/blackbox-exporter-screenshot.png&#34; alt=&#34;用 Prometheus 觀看 Blackbox exporter 採集到的內容&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/08/blackbox-exporter-screenshot.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;用 Prometheus 觀看 Blackbox exporter 採集到的內容&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;事實證明，&lt;a href=&#34;https://github.com/William-Yeh/blackbox-exporter-demo/blob/04cbedfd1b3c035bead29d0b8ecedbbfe137ddac/prometheus.yml#L63&#34;&gt;stripe-healthcheck-wrong-config&lt;/a&gt; 這一組的寫法是錯誤的，要學 &lt;a href=&#34;https://github.com/William-Yeh/blackbox-exporter-demo/blob/04cbedfd1b3c035bead29d0b8ecedbbfe137ddac/prometheus.yml#L46&#34;&gt;stripe-healthcheck&lt;/a&gt; 這一組將 basic_auth 擺到 &lt;a href=&#34;https://github.com/William-Yeh/blackbox-exporter-demo/blob/04cbedfd1b3c035bead29d0b8ecedbbfe137ddac/blackbox.yml#L24-L25&#34;&gt;blackbox.yml&lt;/a&gt; 裡面才對。&lt;/p&gt;
&lt;p&gt;這是我踩過的雷。&lt;/p&gt;
&lt;h2 id=&#34;參考資料&#34;&gt;參考資料&lt;/h2&gt;
&lt;p&gt;Blackbox exporter 並不難，麻煩的是要找到好範例&lt;del&gt;來偷抄&lt;/del&gt;。&lt;/p&gt;
&lt;p&gt;關於 Blackbox exporter 的部份：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;設定檔說明：&lt;a href=&#34;https://github.com/prometheus/blackbox_exporter/blob/master/CONFIGURATION.md&#34;&gt;Blackbox exporter configuration&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;較完整的&lt;a href=&#34;https://github.com/prometheus/blackbox_exporter/blob/master/example.yml&#34;&gt;設定檔範例&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;關於 Prometheus 的部份：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://prometheus.io/docs/guides/multi-target-exporter/&#34;&gt;Understanding and using the multi-target exporter pattern&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;整體 &lt;a href=&#34;https://prometheus.io/docs/prometheus/latest/configuration/configuration/&#34;&gt;Configuration&lt;/a&gt; 說明&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      
    </item>
    
    <item>
      <title>Essence of Scrum: Daily Scrum</title>
      <link>//william-yeh.net/post/2020/08/daily-scrum-in-a-nutshell/</link>
      <pubDate>Sun, 02 Aug 2020 16:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/08/daily-scrum-in-a-nutshell/</guid>
      
        <description>&lt;p&gt;This article discusses the essence of &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Daily Scrum&lt;/span&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;in-a-nutshell&#34;&gt;In a nutshell&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Daily Scrum&lt;/strong&gt; is a time-boxed daily event in which the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Developers&lt;/span&gt;
 gather together to quickly inspect current performance and to identify necessary actions in order to increase the confidence in achieving the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;output&#34;&gt;Output&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Updated confidence in the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 supported by evidence.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Updated plans, if necessary, for achieving the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;input&#34;&gt;Input&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Up-to-date &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint&lt;/span&gt;
 performance status supported by evidence.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tools-and-techniques&#34;&gt;Tools and Techniques&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Time-box facilitation techniques.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Goal-oriented inquiry.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; I suggest iterating based on &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Backlog Items&lt;/span&gt;
 instead of persons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To brief what the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Developers&lt;/span&gt;
 have moved toward the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 since the last &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Daily Scrum&lt;/span&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To brief what the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Developers&lt;/span&gt;
 plan to do toward the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
 today.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To identify potential risks that affect the ability to achieve the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint Goal&lt;/span&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encouraging a focus on the team rather than individuals.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Visualized &lt;a href=&#34;https://scrumbook.org/value-stream/information-radiator.html&#34;&gt;information radiators&lt;/a&gt; (e.g., Scrum board, Kanban board).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Self-managing instead of being conducted solely by &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Master&lt;/span&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      &amp;#39;Essence of Scrum&amp;#39; Series
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2020/07/pbr-in-a-nutshell/&#34;&gt;Product Backlog Refinement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ Daily Scrum&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-planning-in-a-nutshell/&#34;&gt;Sprint Planning&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-review-in-a-nutshell/&#34;&gt;Sprint Review&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/11/scrum-events-agenda/&#34;&gt;Agile Success Recipes: Example Agendas for Efficient Scrum Ceremonies&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--info&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2020-11-24 Memo
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;The series of articles have been updated according to the 2020 revision of &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; (published on Nov 2020).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;The &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Daily Scrum&lt;/span&gt;
 is typically time-boxed to avoid diving into implementation details.  &lt;em&gt;&lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; even defines it as &amp;ldquo;a &lt;strong&gt;15-minute&lt;/strong&gt; time-boxed event.&amp;rdquo; &lt;em&gt;&lt;a href=&#34;https://scrumbook.org/&#34;&gt;A Scrum Book: The Spirit of the Game&lt;/a&gt;&lt;/em&gt; also suggests that &lt;em&gt;&amp;ldquo;this meeting is for replanning and decision-making, not for problem-solving. Strictly time-box the meeting to keep focus on the daily plan and to avoid robbing time from development.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Traditionally &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Daily Scrum&lt;/span&gt;
 is for each person to take turns to speak up the &amp;ldquo;&lt;a href=&#34;https://www.agilealliance.org/glossary/three-qs&#34;&gt;three questions&lt;/a&gt;&amp;rdquo;. For example, &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2013 version said that &lt;em&gt;&amp;ldquo;During the meeting, the Development Team members explain: [&amp;hellip;]&amp;rdquo;&lt;/em&gt; This may imply micro-management, however.      In 2017 version it was rephrased in a less prescriptive style as &lt;em&gt;&amp;ldquo;Some Development Teams will use questions, some will be more discussion based. Here is an example of what might be used: [&amp;hellip;].&amp;rdquo;&lt;/em&gt;      In 2020 version it was even simplified further as &lt;em&gt;&amp;ldquo;The Developers can select whatever structure and techniques they want, as long as their Daily Scrum focuses on progress toward the Sprint Goal and produces an actionable plan for the next day of work.&amp;rdquo;&lt;/em&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>Essence of Scrum: Product Backlog Refinement</title>
      <link>//william-yeh.net/post/2020/07/pbr-in-a-nutshell/</link>
      <pubDate>Wed, 29 Jul 2020 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/07/pbr-in-a-nutshell/</guid>
      
        <description>&lt;h2 id=&#34;preface-of-the-series&#34;&gt;Preface of the series&lt;/h2&gt;
&lt;p&gt;The series of &amp;ldquo;Essence of Scrum&amp;rdquo; articles tries to identify the essence of Scrum elements (e.g., events and artifacts) so that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;the core can be understood without much effort.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the feeling overwhelmed can be reduced.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;the gradual adoption is more possible.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My selection and elaboration of &amp;ldquo;essence&amp;rdquo; is very subjective. Follow the advice at your own risk.&lt;/p&gt;
&lt;p&gt;Main references for the whole series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; by Ken Schwaber and Jeff Sutherland&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://scrumbook.org/&#34;&gt;A Scrum Book: The Spirit of the Game&lt;/a&gt;&lt;/em&gt; by Jeff Sutherland, James O. Coplien, et al.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;Manifesto for Agile Software Development&lt;/a&gt; and &lt;a href=&#34;https://agilemanifesto.org/principles.html&#34;&gt;Principles behind the Agile Manifesto&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;del&gt;&lt;em&gt;&lt;a href=&#34;https://www.scrumstudy.com/sbokguide&#34;&gt;A Guide to the Scrum Body of Knowledge (SBOK® Guide)&lt;/a&gt;&lt;/em&gt;&lt;/del&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://less.works/less/framework/index&#34;&gt;LeSS Framework&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;The first article discusses the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog Refinement&lt;/span&gt;
 (PBR).&lt;/p&gt;
&lt;h2 id=&#34;in-a-nutshell&#34;&gt;In a nutshell&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Product backlog refinement (PBR)&lt;/strong&gt; is a Scrum event in which the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
 properly &lt;strong&gt;orders&lt;/strong&gt; and &lt;strong&gt;breaks down&lt;/strong&gt; &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog&lt;/span&gt;
 so that the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Developers&lt;/span&gt;
 feel confident enough about the top &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog Items&lt;/span&gt;
 to take them into a &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Sprint&lt;/span&gt;
.&lt;/p&gt;
&lt;h2 id=&#34;output&#34;&gt;Output&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog&lt;/span&gt;
 that is both &lt;strong&gt;ordered&lt;/strong&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and &lt;strong&gt;granularity gradient&lt;/strong&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Is ordered according to product roadmap and expectations of stakeholders.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Is granularity gradient according to confidence of the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog&lt;/span&gt;
 that has the property of &lt;strong&gt;ODDE&lt;/strong&gt; (ordered, dynamic, detailed appropriate, and estimated)&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The top &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog Items&lt;/span&gt;
 meet the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Definition of Ready&lt;/span&gt;
 criteria&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; defined and evolved by the &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Scrum Team&lt;/span&gt;
.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;input&#34;&gt;Input&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Strategy breakdown (e.g., product roadmap, &lt;a href=&#34;https://www.whatmatters.com/faqs/okr-meaning-definition-example/&#34;&gt;OKR&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/OGSM&#34;&gt;OGSM&lt;/a&gt;, &lt;a href=&#34;https://www.impactmapping.org/&#34;&gt;impact mapping&lt;/a&gt;, &lt;a href=&#34;https://www.jpattonassociates.com/user-story-mapping/&#34;&gt;user story mapping&lt;/a&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog&lt;/span&gt;
 that is roughly ordered according to product roadmap and expectations of stakeholders.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tools-and-techniques&#34;&gt;Tools and Techniques&lt;/h2&gt;
&lt;p&gt;Essential:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Short-term strategic planning statements in brief&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Logical approach to ordering items&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Logical approach to breaking down items&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Estimation in proper granularity&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SPIDR (Spike, Paths, Interfaces, Data, and Rules)&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Techniques for enabling specification&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Encouraging participative decision-making in proposal and ordering of &lt;span style=&#34;font-variant: small-caps;&#34;&gt;Product Backlog Items&lt;/span&gt;
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2018/02/impact-mapping-as-participatory-decision-making/&#34;&gt;以 impact mapping 進行參與式決策 (Impact Mapping as Participatory Decision Making)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      &amp;#39;Essence of Scrum&amp;#39; Series
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ Product Backlog Refinement&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2020/08/daily-scrum-in-a-nutshell/&#34;&gt;Daily Scrum&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-planning-in-a-nutshell/&#34;&gt;Sprint Planning&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2020/08/sprint-review-in-a-nutshell/&#34;&gt;Sprint Review&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/11/scrum-events-agenda/&#34;&gt;Agile Success Recipes: Example Agendas for Efficient Scrum Ceremonies&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--info&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2020-11-24 Memo
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;The series of articles have been updated according to the 2020 revision of &lt;em&gt;&lt;a href=&#34;https://scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; (published on Nov 2020).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&amp;ldquo;Priority&amp;rdquo; is the term used in the &lt;em&gt;&lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;Scrum Guide&lt;/a&gt;&lt;/em&gt; 2010: &lt;em&gt;&amp;ldquo;Product Backlog is sorted in order of priority&amp;rdquo;&lt;/em&gt; (p.6).    But the term was changed to &amp;ldquo;order&amp;rdquo; in 2011: &lt;em&gt;&amp;ldquo;Product Backlog management includes: [&amp;hellip;] Ordering the items in the Product Backlog to best achieve goals and missions&amp;rdquo;&lt;/em&gt; (p.5).    See the article &amp;ldquo;&lt;a href=&#34;https://www.scrum.org/resources/ordered-not-prioritized&#34;&gt;Ordered Not Prioritized&lt;/a&gt;&amp;rdquo; for more details.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;The Scrum Guide&lt;/a&gt;&lt;/em&gt; 2017 says: &lt;em&gt;&amp;ldquo;Higher ordered Product Backlog items are usually clearer and more detailed than lower ordered ones. More precise estimates are made based on the greater clarity and increased detail; the lower the order, the less detail&amp;rdquo;&lt;/em&gt; (p.15).      See &amp;ldquo;&lt;a href=&#34;https://scrumbook.org.datasenter.no/value-stream/product-backlog/granularity-gradient.html&#34;&gt;Granularity Gradient&lt;/a&gt;&amp;rdquo; for more details.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scrumalliance.org/community/profile/dteng&#34;&gt;Daniel Teng&lt;/a&gt; proposed the ODDE properties (ordered, dynamic, detailed appropriate, and estimated) for product backlog. See the article &amp;ldquo;&lt;a href=&#34;http://www.danielteng.com/2014/06/27/odde-product-backlog/&#34;&gt;ODDE 的 Product Backlog&lt;/a&gt;&amp;rdquo; (in Chinese) for more details.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://scrumbook.org/value-stream/product-backlog/definition-of-ready.html&#34;&gt;Definition of Ready&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scrumalliance.org/community/profile/mikecohn&#34;&gt;Mike Cohn&lt;/a&gt; discusses different levels of estimation activities in his article &amp;ldquo;&lt;a href=&#34;https://www.mountaingoatsoftware.com/blog/why-agile-teams-should-estimate-at-two-different-levels&#34;&gt;Why Agile Teams Should Estimate at Two Different Levels&lt;/a&gt;.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scrumalliance.org/community/profile/mikecohn&#34;&gt;Mike Cohn&lt;/a&gt; proposed the SPIDR approach (spike, paths, interfaces, data, and rules) for breaking down user stories. Watch the &amp;ldquo;&lt;a href=&#34;https://www.mountaingoatsoftware.com/exclusive/spidr-video&#34;&gt;Stop Wasting Time Splitting Stories&lt;/a&gt;&amp;rdquo; video for more details.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://scrumbook.org/value-stream/product-backlog/enabling-specification.html&#34;&gt;Enabling specification&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Go Best Practices</title>
      <link>//william-yeh.net/post/2020/07/golang-best-practices/</link>
      <pubDate>Fri, 10 Jul 2020 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/07/golang-best-practices/</guid>
      
        <description>&lt;p&gt;今年一月，換到一家以 Go 為主力語言的公司。&lt;/p&gt;
&lt;p&gt;習慣了 Java 紀律，一碰到 Go 的自由奔放，不禁想尋求一些 best practices 與 patterns。&lt;/p&gt;
&lt;p&gt;以前我曾蒐集過一份 Go Best Practices 清單。浸潤 Go 半年後，再回頭看這些內容，當初不甚明瞭之處，竟然也懂了許多。便想重新整理一次，並加上個人的短評。&lt;/p&gt;
&lt;h2 id=&#34;語言基礎&#34;&gt;語言基礎&lt;/h2&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://golang.org/doc/effective_go.html&#34;&gt;&lt;strong&gt;Effective Go&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;自從 1991 年 &lt;a href=&#34;https://www.amazon.com/dp/0321334876&#34;&gt;&lt;em&gt;Effective C++&lt;/em&gt;&lt;/a&gt; 橫空出世，以後任何書敢冠上 &amp;ldquo;Effective&amp;rdquo; 之名，幾乎都是重量級的保證。&lt;/p&gt;
&lt;p&gt;“&lt;a href=&#34;https://golang.org/doc/effective_go.html&#34;&gt;Effective Go&lt;/a&gt;” 這份文件，雖然篇幅還沒充實到足以成為一本書，但內容名副其實，原汁原味道出 Go 的核心風格，是非常好的入門補充讀物。&lt;/p&gt;
&lt;h2 id=&#34;package-命名與組織&#34;&gt;Package 命名與組織&lt;/h2&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://rakyll.org/style-packages/&#34;&gt;&lt;strong&gt;Style guideline for Go packages&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;這篇短文可以幫助你學會「正統」的 Go package 風格。&lt;/p&gt;
&lt;h2 id=&#34;中小規模的程式結構&#34;&gt;中小規模的程式結構&lt;/h2&gt;
&lt;p&gt;知名輕量級框架 &lt;a href=&#34;https://gokit.io/&#34;&gt;Go kit&lt;/a&gt; 作者 &lt;a href=&#34;https://github.com/peterbourgon&#34;&gt;Peter Bourgon&lt;/a&gt; 分享過許多實務經驗，其中這兩篇文章很值得一讀：&lt;/p&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://peter.bourgon.org/go-best-practices-2016/&#34;&gt;&lt;strong&gt;Go best practices, six years in&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://peter.bourgon.org/go-for-industrial-programming/&#34;&gt;&lt;strong&gt;Go for Industrial Programming&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;或許是因為我們公司自建的 Go 微服務框架 &lt;a href=&#34;https://github.com/carousell/Orion&#34;&gt;Orion&lt;/a&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，骨幹結構非常接近 Go kit，所以我對這兩篇文章非常有感。&lt;/p&gt;
&lt;h2 id=&#34;專案佈局&#34;&gt;專案佈局&lt;/h2&gt;
&lt;p&gt;其他程式語言的經驗愈多，愈容易把 ~~~不良習慣~~~ 不搭配的習慣帶進 Go 來，尤其是專案佈局風格。&lt;/p&gt;
&lt;p&gt;在 Go 裡，通常最簡單的專案佈局方式是：你選用哪一個主框架，就遵照著它建議的佈局。&lt;/p&gt;
&lt;p&gt;不過，如果用的是像 &lt;a href=&#34;https://github.com/gin-gonic/gin&#34;&gt;Gin&lt;/a&gt; 這種超輕量的迷你框架，或者根本沒有套用任何框架，那麼，以下這一篇文章、一份範例，是很好的起點：&lt;/p&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1&#34;&gt;&lt;strong&gt;Standard Package Layout&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://github.com/golang-standards/project-layout&#34;&gt;&lt;strong&gt;Standard Go Project Layout&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;即使你信仰 &lt;a href=&#34;https://en.wikipedia.org/wiki/Domain-driven_design&#34;&gt;DDD (domain driven design)&lt;/a&gt; 或 &lt;a href=&#34;https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html&#34;&gt;clean architecture&lt;/a&gt; 路線，也盡量不要不假思索將其他語言的實踐風格直接照搬過來——你會寫出很醜陋的 Go 程式。&lt;/p&gt;
&lt;h2 id=&#34;design-patterns&#34;&gt;Design Patterns&lt;/h2&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://crazybber.github.io/awesome-patterns/&#34;&gt;&lt;strong&gt;awesome-patterns&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;熟悉 design patterns 的人，可從這裡得到用 Go 實作的靈感。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;關於 Orion，詳見〈&lt;a href=&#34;https://medium.com/carousell-insider/%E5%9C%A8%E6%97%8B%E8%BD%89%E6%8B%8D%E8%B3%A3-carousell-%E4%B8%80%E5%B9%B4%E7%9C%8B%E5%88%B0%E7%9A%84%E5%BE%8C%E7%AB%AF%E6%9E%B6%E6%A7%8B-%E6%8C%91%E6%88%B0%E8%88%87%E7%94%9F%E6%B4%BB-a0a12ef90cc0#bd44&#34;&gt;在旋轉拍賣 Carousell 一年看到的後端架構、挑戰與生活&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Travis CI 虛擬機的地雷</title>
      <link>//william-yeh.net/post/2020/07/travisci-hacks/</link>
      <pubDate>Thu, 09 Jul 2020 23:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/07/travisci-hacks/</guid>
      
        <description>&lt;p&gt;我算是 &lt;a href=&#34;https://travis-ci.org/&#34;&gt;Travis CI&lt;/a&gt; 的老用戶了。&lt;/p&gt;
&lt;p&gt;以前 Travis CI 很慢，對 Docker 不友善，又很難 debug，讓我一度將重心轉移到後起之秀 &lt;a href=&#34;https://circleci.com/&#34;&gt;CircleCI&lt;/a&gt;。後來 Travis CI 向 CircleCI 看齊，讓我們能夠 ssh 進去虛擬機 debug，兩者的差距已經逐漸縮小。所以，我自己的重要專案，總是盡量同時掛上 Travis CI 及 CircleCI，讓 CI pipeline 的核心在某種程度上也能盡量 reproducible 不被 lock in。&lt;/p&gt;
&lt;p&gt;Travis CI 也提供許多常見的程式語言及伺服器軟體，以方便做 CI 測試。我個人的習慣是，盡量不去使用這些功能，而是直接用 Docker 或 Docker Compose 來組裝，以降低對於 Travis CI 的依賴（尤其我還要兼顧 CircleCI）。&lt;/p&gt;
&lt;p&gt;不過，如果是與人合作的專案，就得顧及其他人的習慣。我在使用 Travis CI 提供的伺服器軟體 Postgres、Cassandra、RabbitMQ 時，遇到一些雷，特地記錄下來，供有類似困擾的人參考。&lt;/p&gt;
&lt;h2 id=&#34;虛擬機版本&#34;&gt;虛擬機版本&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;.travis.yml&lt;/code&gt; 檔案裡面可以指定 CI 虛擬機的 Ubuntu 版本&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。若不特別指定，以現在（2020 年七月）來說，預設版本會是 Ubuntu 16.04 LTS，代號為 &lt;strong&gt;Xenial&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我遇到一些專案，&lt;code&gt;.travis.yml&lt;/code&gt; 指定的是代號為 &lt;strong&gt;Trusty&lt;/strong&gt; 的 Ubuntu 14.04 LTS。由於 Trusty 的官方保固期限已於 2019-04 到期&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，理論上來說，至少應該要升級到 2021-04 才到期的 Xenial 版，才比較安全。&lt;/p&gt;
&lt;p&gt;事情並沒想像中那麼簡單。&lt;/p&gt;
&lt;p&gt;我以兩個 repo 來示範：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;使用 Trusty 虛擬機的專案：&lt;a href=&#34;https://github.com/William-Yeh/test-travisci-trusty&#34;&gt;test-travisci-trusty&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用 Xenial 虛擬機的專案：&lt;a href=&#34;https://github.com/William-Yeh/test-travisci-xenial&#34;&gt;test-travisci-xenial&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;譬如說，在原本使用 Trusty 的專案中跑得好好的 &lt;a href=&#34;https://github.com/William-Yeh/test-travisci-trusty/blob/master/.travis.yml&#34;&gt;.travis.yml 檔&lt;/a&gt;，如果不假思索直接&lt;a href=&#34;https://github.com/William-Yeh/test-travisci-xenial/tree/0.1&#34;&gt;照搬&lt;/a&gt;到使用 Xenial 的專案，一下子就&lt;a href=&#34;https://travis-ci.org/github/William-Yeh/test-travisci-xenial/builds/706399580&#34;&gt;卡住&lt;/a&gt;了：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/07/travisci-failure.png&#34; alt=&#34;Travis CI Xenial 噴出錯誤&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/07/travisci-failure.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Travis CI Xenial 噴出錯誤&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;非常詭異。反覆實驗，總算找出需要修改的三個地方。&lt;/p&gt;
&lt;h2 id=&#34;postgres&#34;&gt;Postgres&lt;/h2&gt;
&lt;p&gt;使用 Trusty 虛擬機時，照著 Travis CI 官方指南及問題排除文件，我們可以順利安裝不同版本的 Postgres：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;官方指南：&lt;a href=&#34;https://docs.travis-ci.com/user/database-setup/#using-a-different-postgresql-version&#34;&gt;Setting up Databases and Services - Using a different PostgreSQL Version&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Authentication 問題：&lt;a href=&#34;https://github.com/travis-ci/travis-ci/issues/9624&#34;&gt;Issue #9624&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;換成 Xenial 虛擬機時，不知為何，Postgres 的 port 居然靜悄悄地換成了 5432，而且沒有文件直接明講。&lt;/p&gt;
&lt;p&gt;解決之道很簡單，直接修改相對應的變數：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/07/diff-postgres.png&#34; alt=&#34;Postgres 修改之處&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/07/diff-postgres.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Postgres 修改之處&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;你也可以直接點選&lt;a href=&#34;https://www.diffchecker.com/186oQ7pu&#34;&gt;這裡&lt;/a&gt;剪貼相關的設定內容。&lt;/p&gt;
&lt;h2 id=&#34;cassandra&#34;&gt;Cassandra&lt;/h2&gt;
&lt;p&gt;使用 Trusty 虛擬機時，照著 Travis CI 官方指南，我們可以順利安裝不同版本的 Cassandra：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;官方指南：&lt;a href=&#34;https://docs.travis-ci.com/user/database-setup/#cassandra&#34;&gt;Setting up Databases and Services - Cassandra&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;換成 Xenial 虛擬機時，不知為何，Cassandra 不再是 Travis CI 直接提供的資料庫了，而且沒有文件直接明講。&lt;/p&gt;
&lt;p&gt;解決之道是自力救濟，自己下載，自己安裝&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/07/diff-cassandra.png&#34; alt=&#34;Cassandra 修改之處&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/07/diff-cassandra.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Cassandra 修改之處&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;你也可以直接點選&lt;a href=&#34;https://www.diffchecker.com/T3Xyacxp&#34;&gt;這裡&lt;/a&gt;剪貼相關的設定內容。&lt;/p&gt;
&lt;h2 id=&#34;rabbitmq&#34;&gt;RabbitMQ&lt;/h2&gt;
&lt;p&gt;使用 Trusty 虛擬機時，照著 Travis CI 官方指南及 Stack Overflow 問答庫，我們可以順利安裝 RabbitMQ 以及常用的 rabbitmqadmin 設定工具：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;官方指南：&lt;a href=&#34;https://docs.travis-ci.com/user/database-setup/#rabbitmq&#34;&gt;Setting up Databases and Services - RabbitMQ&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stack Overflow 問答：&lt;a href=&#34;https://stackoverflow.com/q/52107517/714426&#34;&gt;Declaring rabbitmq exchanges in travis build setup&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;換成 Xenial 虛擬機時，這次官方文件總算有特別提醒對應的修改&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;。可惜 Travis CI 只做了一半，忘了啟動常見的 &lt;a href=&#34;https://www.rabbitmq.com/management.html&#34;&gt;RabbitMQ Management Plugin&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;解決之道是自力救濟，自己開啟：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/07/diff-rabbitmq.png&#34; alt=&#34;Cassandra 修改之處&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/07/diff-rabbitmq.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Cassandra 修改之處&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;你也可以直接點選&lt;a href=&#34;https://www.diffchecker.com/fp9mOgUx&#34;&gt;這裡&lt;/a&gt;剪貼相關的設定內容。&lt;/p&gt;
&lt;h2 id=&#34;結語&#34;&gt;結語&lt;/h2&gt;
&lt;p&gt;代號為 Xenial 的 Ubuntu 16.04，官方保固期將於 2021-04 到期，若升級到代號為 Bionic，官方保固期到 2023-04 的 Ubuntu 18.04，免不了又要經歷一輪類似的修改。&lt;/p&gt;
&lt;p&gt;據我目前初步測試，Travis CI 的 Bionic 虛擬機會遇到更多雷（難怪 Travis CI 目前仍然預設為 Xenial）。如果沒有其他考量，我還是強烈建議，直接用 Docker 或 Docker Compose 去設定 CI 所需動用的程式語言及伺服器軟體，以降低對於 Travis CI 的依賴，甚至預留轉換至 &lt;a href=&#34;https://circleci.com/&#34;&gt;CircleCI&lt;/a&gt; 或 &lt;a href=&#34;https://github.com/features/actions&#34;&gt;GitHub Actions&lt;/a&gt; 的彈性。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Travis CI 支援許多虛擬機，完整列表請見 &amp;ldquo;&lt;a href=&#34;https://docs.travis-ci.com/user/reference/overview/&#34;&gt;Build Environment Overview&lt;/a&gt;&amp;rdquo; 一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;在 &lt;a href=&#34;https://en.wikipedia.org/wiki/Ubuntu_version_history&#34;&gt;Ubuntu version history&lt;/a&gt; 文件中，詳列了 Ubuntu 各版本代號及官方保固期限。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;我參考 &lt;a href=&#34;https://github.com/aio-libs/aiocassandra&#34;&gt;aiocassandra 專案&lt;/a&gt;的設定，將 Cassandra 安裝在 Travis CI 的 Xenial 虛擬機上：https://github.com/aio-libs/aiocassandra/blob/master/.travis.yml&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;可能也是在官方論壇收到 &amp;ldquo;&lt;a href=&#34;https://travis-ci.community/t/rabbitmq-on-xenial/1827&#34;&gt;RabbitMQ on Xenial&lt;/a&gt;&amp;rdquo; 這則提問，Travis CI 才會把這一段解法放進官方文件吧。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Jira Board Hacks</title>
      <link>//william-yeh.net/post/2020/06/jira-board-hacks/</link>
      <pubDate>Sat, 06 Jun 2020 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/06/jira-board-hacks/</guid>
      
        <description>&lt;h2 id=&#34;實體看板&#34;&gt;實體看板&lt;/h2&gt;
&lt;p&gt;在導入 Scrum 時，我偏好實體看板。&lt;/p&gt;
&lt;p&gt;實體看板容易 zoom in/out，利於適時切換俯瞰與細節視角，不需過度的數字管理。&lt;/p&gt;
&lt;p&gt;實體看板的空間共時性，容易塑造團隊的一體感。&lt;/p&gt;
&lt;p&gt;實體看板彈性大，能以最小成本，讓團隊在敏捷路上不斷嘗試與調整。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/06/physical-kanban.png&#34; alt=&#34;實體看板&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/06/physical-kanban.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實體看板&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;不過，在重視數字管理的組織，或是有 remote 成員存在的組織，恐怕不得不面對數位化電子看板的存在。輕量級的如 &lt;a href=&#34;https://trello.com/&#34;&gt;Trello&lt;/a&gt;，重量級的如 &lt;a href=&#34;https://www.atlassian.com/software/jira&#34;&gt;Jira&lt;/a&gt;，不管並存抑或取代，都得學著與之共舞。&lt;/p&gt;
&lt;p&gt;說實在的，為了迎合管理視角，電子看板犧牲許多實體敏捷性。萬一真的不能不採用，我們還是得學著發揮它的優點，並設法降低它的負面影響。&lt;/p&gt;
&lt;p&gt;以下我會介紹幾個小技巧，讓我過去一個禮拜在透過 Jira 引導 daily stand-up 時，找回部份實體看板的手感。&lt;/p&gt;
&lt;h2 id=&#34;jira-的泳道縮放&#34;&gt;Jira 的泳道縮放&lt;/h2&gt;
&lt;p&gt;Daily stand-up 一開始，我習慣先站在更全局的角度鳥瞰：將卡片全都收縮起來，只留下泳道 (swimlane)。畢竟，與 sprint goal 最直接對應的，是 swimlane，而非個別卡片。&lt;/p&gt;
&lt;p&gt;我會先用 Jira 熱鍵 &lt;code&gt;z&lt;/code&gt; 隱藏側邊欄，用 Jira 熱鍵 &lt;code&gt;-&lt;/code&gt; 收縮泳道：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/06/jira-board-collapse.png&#34; alt=&#34;Jira 看板，泳道視角&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/06/jira-board-collapse.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Jira 看板，泳道視角&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;接下來，再逐一展開個別泳道來進行探討：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/06/jira-swimlane-one.png&#34; alt=&#34;Jira 看板，泳道局部展開&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/06/jira-swimlane-one.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Jira 看板，泳道局部展開&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;jira-的全局卡片視角&#34;&gt;Jira 的全局卡片視角&lt;/h2&gt;
&lt;p&gt;為了迎合管理視角，Jira 的每一張卡片，塞了非常多資訊：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/06/jira-card.png&#34; alt=&#34;Jira card&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/06/jira-card.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Jira card&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這其實並不算是問題——如果單獨只看一張、兩張卡片的話。&lt;/p&gt;
&lt;p&gt;聽出我的弦外之音了嗎？&lt;/p&gt;
&lt;p&gt;問題在於：若將所有卡片全都陳列在看板上，會發現，卡片佔用的總面積，與實際展現出來有意義的資訊總量，不符合比例原則。&lt;/p&gt;
&lt;p&gt;個別卡片已經太佔空間了，更糟糕的是，能夠擺放卡片的看板區域，也被別人偷偷霸佔。&lt;/p&gt;
&lt;p&gt;以我的 13.3 英吋螢幕為例。寶貴的螢幕可視區域中，最上面是一堆置頂區域：先是一排選單，再來是好幾排大標題，接下來才輪到一排看板的進度欄。經過這一輪置頂空間爭奪戰，1/5 空間被吃掉了，剩下來的看板空間，能夠在同一頁完整秀出來的卡片，最多只有 12 張；想看更多，只得往下捲動：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/06/jira-board-before.png&#34; alt=&#34;手術前的 Jira 看板，空間利用率甚低。&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/06/jira-board-before.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;手術前的 Jira 看板，空間利用率甚低。&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;需要一直捲動的看板，如何給人全局觀？&lt;/p&gt;
&lt;p&gt;簡言之，Jira 缺少許多軟體常見的 &amp;ldquo;Zen mode&amp;rdquo; 或 &amp;ldquo;Presentation mode&amp;rdquo;。我希望，當卡片太多時（我知道這是 bad smell 啦⋯⋯），能夠一鍵隱藏不必要的置頂區域，隱藏不必要的卡片欄位，譬如說，只秀出卡片標題。&lt;/p&gt;
&lt;p&gt;用&lt;a href=&#34;https://violentmonkey.github.io/&#34;&gt;暴力猴&lt;/a&gt;之類的東西就辦得到。我寫了一隻簡單的 userscript：&lt;a href=&#34;https://greasyfork.org/en/scripts/404806-atlassian-jira-cleaner-rapid-board&#34;&gt;Atlassian JIRA - Cleaner Rapid Board&lt;/a&gt;，透過它，只要一鍵（預設為 &lt;code&gt;Ctrl&lt;/code&gt;-&lt;code&gt;H&lt;/code&gt;），就能切換成較清爽的全局視角：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/06/jira-board-after.png&#34; alt=&#34;手術後的 Jira 看板，空間利用率提高了。&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/06/jira-board-after.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;手術後的 Jira 看板，空間利用率提高了。&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;如此一來，寶貴的螢幕可視區域，只放絕對必要的資訊，就能多擺幾張卡片（是的，是的，我知道這是 bad smell 啦⋯⋯）。&lt;/p&gt;
&lt;p&gt;不過，Jira 本身已經夠笨重了，甚至連 Jira 本身的熱鍵都會不時失效；若再搭配像暴力猴這類 script 式外掛，可能會不夠穩定。如果你想要穩定一點的方案，或者不想透過熱鍵切換，只想一勞永逸眼不見為淨，不妨考慮改用 &lt;a href=&#34;https://userstyles.org/&#34;&gt;Stylish&lt;/a&gt; 之類的東西，自動套用：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-css&#34; data-lang=&#34;css&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* For horizontal headers */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; .&lt;span style=&#34;color:#a6e22e&#34;&gt;css-e2mdyo&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; #ghx-header {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;display&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;none&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;!important&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* For card fields */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;section&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ghx-extra-fields&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ghx-row&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;ghx-highlighted-field&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;display&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;none&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;!important&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;jira-的聚焦卡片視角&#34;&gt;Jira 的聚焦卡片視角&lt;/h2&gt;
&lt;p&gt;在 daily stand-up 進行時，常常需要讓大家知道「我們現在正在討論某一張卡片」。&lt;/p&gt;
&lt;p&gt;在 Jira 裡，我們可以對某一張卡片原地拖曳一下下，就會有類似的視覺聚焦效果：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/06/jira-focus-by-drag.png&#34; alt=&#34;原地拖曳卡片&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/06/jira-focus-by-drag.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;原地拖曳卡片&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;不過，視覺效果還有很大的改善空間，而且⋯⋯需要一直維持拖曳狀態，手指頭會累。&lt;/p&gt;
&lt;p&gt;你可以改用素有「簡報神器」之稱的 &lt;a href=&#34;https://www.logitech.com/zh-tw/product/spotlight-presentation-remote&#34;&gt;Logitech SPOTLIGHT&lt;/a&gt; 的聚光燈特效。視覺效果一流，但缺點一樣是手指頭需要一直按著簡報器按鈕，聚光燈會晃動，大拇指會疲累。你也可以試著用我以前在〈&lt;a href=&#34;//william-yeh.net/post/2016/08/presenter-tools/&#34;&gt;簡報者的小工具&lt;/a&gt;〉一文介紹過的 &lt;a href=&#34;https://boinx.com/mousepose/&#34;&gt;Mouseposé&lt;/a&gt; 軟體，手指頭就不必一直按著不放，聚光燈也會穩穩的固定不動：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/06/jira-focus-by-mousepose.png&#34; alt=&#34;透過 Mouseposé 聚焦特定卡片&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/06/jira-focus-by-mousepose.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;透過 Mouseposé 聚焦特定卡片&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;總結&#34;&gt;總結&lt;/h2&gt;
&lt;p&gt;電子看板犧牲許多實體敏捷性。&lt;/p&gt;
&lt;p&gt;本文介紹幾則 Jira 電子看板的小技巧，有些是 Jira 本身就有提供的，有些則是透過其他軟體輔助：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;善用 Jira 熱鍵 &lt;code&gt;z&lt;/code&gt; 及 &lt;code&gt;-&lt;/code&gt; 縮放泳道。你也可以從 &lt;code&gt;?&lt;/code&gt; 當中嘗試看看有沒有更多適合自己風格的熱鍵。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;善用&lt;a href=&#34;https://violentmonkey.github.io/&#34;&gt;暴力猴&lt;/a&gt;或 &lt;a href=&#34;https://userstyles.org/&#34;&gt;Stylish&lt;/a&gt; 整頓出全局卡片視角。你可以從我寫的 &lt;a href=&#34;https://greasyfork.org/en/scripts/404806-atlassian-jira-cleaner-rapid-board&#34;&gt;Atlassian JIRA - Cleaner Rapid Board&lt;/a&gt; 當出發點，修改成適合自己的版本。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;善用 &lt;a href=&#34;https://boinx.com/mousepose/&#34;&gt;Mouseposé&lt;/a&gt; 聚焦單一卡片。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;希望透過這些工具，加上適度的引導技巧，能夠更接近實體看板的手感。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>gRPC 測試工具</title>
      <link>//william-yeh.net/post/2020/04/grpc-testing-tools/</link>
      <pubDate>Tue, 14 Apr 2020 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/04/grpc-testing-tools/</guid>
      
        <description>&lt;p&gt;RESTful API 時代，我們有許多簡單好用的測試工具：有酷炫的 &lt;a href=&#34;https://www.postman.com/&#34;&gt;Postman&lt;/a&gt;，有命令列控愛用的 &lt;a href=&#34;https://httpie.org/&#34;&gt;HTTPie&lt;/a&gt;，當然也有硬漢必備的萬用瑞士刀 &lt;a href=&#34;https://curl.haxx.se/&#34;&gt;curl&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;那麼，gRPC 呢？&lt;/p&gt;
&lt;p&gt;這篇文章介紹兩個好用的小工具：&lt;a href=&#34;https://github.com/fullstorydev/grpcurl&#34;&gt;gRPCurl&lt;/a&gt; 及 &lt;a href=&#34;https://github.com/bojand/ghz&#34;&gt;ghz&lt;/a&gt;，一個是輸入輸出介面測試工具，另一個是壓測工具，也順便介紹一些簡化測試的技巧。&lt;/p&gt;
&lt;h2 id=&#34;待測程式&#34;&gt;待測程式&lt;/h2&gt;
&lt;p&gt;待測程式放在 &lt;a href=&#34;https://github.com/William-Yeh/grpcurl-and-ghz-demo&#34;&gt;https://github.com/William-Yeh/grpcurl-and-ghz-demo&lt;/a&gt;&lt;/p&gt;

&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    檔案簡介：
    
  &lt;/summary&gt;
  

&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── README.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── build.sh                 ← 編譯命令
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── go.mod
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── go.sum
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── out                      ← 編譯後的可執行檔
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── server
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── server-new
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── routeguide               ← gRPC 介面定義；原封不動取自 &amp;#34;gRPC-Go&amp;#34; 專案
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── route_guide.pb.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── route_guide.proto
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── server                   ← server 程式；原封不動取自 &amp;#34;gRPC-Go&amp;#34; 專案
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── server.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── server-new               ← 由我修改過的新版 server 程式
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── server-new.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── testdata.dat             ← 給 gRPCurl 的測試資料
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── testdata.json            ← 給 ghz 的測試資料&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;



&lt;/details&gt;

&lt;p&gt;為了方便起見，我挑選 &amp;ldquo;&lt;a href=&#34;https://github.com/grpc/grpc-go&#34;&gt;gRPC-Go&lt;/a&gt;&amp;rdquo; 專案裡面的 &amp;ldquo;&lt;a href=&#34;https://github.com/grpc/grpc-go/tree/master/examples/route_guide&#34;&gt;the route guide server and client&lt;/a&gt;&amp;rdquo; 範例做為待測程式。&lt;/p&gt;
&lt;p&gt;這隻 server 程式透過 gRPC 提供 &lt;code&gt;RouteGuide&lt;/code&gt; 服務，我們這次只會測試其中的 &lt;code&gt;RecordRoute&lt;/code&gt; 呼叫。以下是從 gRPC 介面定義檔 &lt;a href=&#34;https://github.com/William-Yeh/grpcurl-and-ghz-demo/blob/master/routeguide/route_guide.proto&#34;&gt;&lt;code&gt;route_guide.proto&lt;/code&gt;&lt;/a&gt; 摘錄我們會用到的部份：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-proto&#34; data-lang=&#34;proto&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;package&lt;/span&gt; routeguide;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;service&lt;/span&gt; RouteGuide {&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// A client-to-server streaming RPC.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// Accepts a stream of Points on a route being traversed, returning a
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#75715e&#34;&gt;// RouteSummary when traversal is completed.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;rpc&lt;/span&gt; RecordRoute(stream Point) &lt;span style=&#34;color:#66d9ef&#34;&gt;returns&lt;/span&gt; (RouteSummary) {}&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;message&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Point&lt;/span&gt; {&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt; latitude &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt; longitude &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;message&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;RouteSummary&lt;/span&gt; {&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt; point_count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt; feature_count &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt; distance &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;int32&lt;/span&gt; elapsed_time &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;//...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;我也針對 server 程式小改三個地方，弄出另一個 server-new 程式：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ diff  server/server.go  server-new/server-new.go
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;42a43
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; 	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;google.golang.org/grpc/reflection&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;55c56
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt; 	port       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; flag.Int&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;port&amp;#34;&lt;/span&gt;, 10000, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;The server port&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; 	port       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; flag.Int&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;port&amp;#34;&lt;/span&gt;, 20000, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;The server port&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;243a245,248
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; 	// Register reflection service on gRPC server.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt; 	reflection.Register&lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;grpcServer&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;簡單來說，新舊兩版的差別是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;舊版 server 的 gRPC port = 10000，新版 server-new 則是 20000。&lt;/li&gt;
&lt;li&gt;新版 server-new 支援 &lt;a href=&#34;https://github.com/grpc/grpc/blob/master/doc/server-reflection.md&#34;&gt;server reflection&lt;/a&gt; 功能。稍後會再說明這是什麼。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;實驗環境&#34;&gt;實驗環境&lt;/h2&gt;
&lt;p&gt;實驗所需環境：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go 1.14 以上。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/fullstorydev/grpcurl&#34;&gt;gRPCurl&lt;/a&gt; 1.5.0 以上。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bojand/ghz&#34;&gt;ghz&lt;/a&gt; 0.51.0 以上。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;先來編譯程式：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./build.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;成功後，會在 &lt;code&gt;out&lt;/code&gt; 目錄拿到兩份執行檔：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;out/server&lt;/code&gt;：原封不動來自 &amp;ldquo;gRPC-Go&amp;rdquo; 專案的 server 程式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;out/server-new&lt;/code&gt;：由我小小修改過的新程式。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;進行實驗時，建議將你的終端機配置成這樣：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/04/grpcurl-demo-layout.png&#34; alt=&#34;終端機建議配置&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/04/grpcurl-demo-layout.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;終端機建議配置&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;然後，請分別啟動 &lt;code&gt;out/server&lt;/code&gt; 及 &lt;code&gt;out/server-new&lt;/code&gt; 程式：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 舊程式，跑在 10000 port&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ out/server
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 新程式，跑在 20000 port&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ out/server-new&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;一切就緒，準備要來測試它們了。&lt;/p&gt;
&lt;h2 id=&#34;實驗一搭配-proto-檔&#34;&gt;實驗一：搭配 proto 檔&lt;/h2&gt;
&lt;p&gt;先針對舊版的 server 來實驗。&lt;/p&gt;
&lt;h3 id=&#34;grpcurl&#34;&gt;gRPCurl&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/fullstorydev/grpcurl&#34;&gt;gRPCurl&lt;/a&gt;，顧名思義，是在向硬漢必備的萬用瑞士刀 &lt;a href=&#34;https://curl.haxx.se/&#34;&gt;curl&lt;/a&gt; 致敬。不妨將它視為 gRPC 版的 curl。&lt;/p&gt;
&lt;p&gt;gRPCurl 使用上最主要的差別是，因應 gRPC 的特性，必須餵給它 proto 檔案，才會知道該如何封裝訊息格式。&lt;/p&gt;
&lt;p&gt;譬如說，我們可將 proto 檔案的路徑寫在 &lt;code&gt;-import-path&lt;/code&gt; 中、將 proto 檔案名稱寫在 &lt;code&gt;-proto&lt;/code&gt; 中、將參數寫在 &lt;code&gt;-d&lt;/code&gt; 中，再呼叫 server 的遠端程序：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grpcurl -plaintext  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -d &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;{&amp;#34;latitude&amp;#34;:-460000000,&amp;#34;longitude&amp;#34;:-1160000000} {&amp;#34;latitude&amp;#34;:720000000,&amp;#34;longitude&amp;#34;:-540000000}&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -import-path ./routeguide        &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -proto       route_guide.proto   &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    127.0.0.1:10000                  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    routeguide.RouteGuide.RecordRoute
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pointCount&amp;#34;&lt;/span&gt;: 2,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;distance&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;13975745&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;我們也可將事先備妥的資料檔餵給 gRPCurl。像是含有 100 筆資料的 &lt;code&gt;testdata.dat&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grpcurl -plaintext -d &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;@&amp;#39;&lt;/span&gt;            &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -import-path ./routeguide          &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -proto       route_guide.proto     &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    127.0.0.1:10000                    &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    routeguide.RouteGuide.RecordRoute  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt; testdata.dat
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pointCount&amp;#34;&lt;/span&gt;: 100,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;distance&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1003784333&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;ghz&#34;&gt;ghz&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/bojand/ghz&#34;&gt;ghz&lt;/a&gt; 壓測工具，是這麼自我介紹的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Simple gRPC benchmarking and load testing tool inspired by &lt;a href=&#34;https://github.com/rakyll/hey/&#34;&gt;hey&lt;/a&gt; and &lt;a href=&#34;https://github.com/fullstorydev/grpcurl&#34;&gt;grpcurl&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，從命令列參數及統計結果上，都可看出它們的影響。&lt;/p&gt;
&lt;p&gt;譬如說，我們可將 proto 檔案的路徑寫在 &lt;code&gt;--import-path&lt;/code&gt; 中、將 proto 檔案名稱寫在 &lt;code&gt;--proto&lt;/code&gt; 中、將參數寫在 &lt;code&gt;--data&lt;/code&gt; 中，再呼叫 server 的遠端程序：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ghz --insecure  -z 20s  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      --data &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;[{&amp;#34;latitude&amp;#34;:-460000000,&amp;#34;longitude&amp;#34;:-1160000000},{&amp;#34;latitude&amp;#34;:720000000,&amp;#34;longitude&amp;#34;:-540000000}]&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      --import-paths ./routeguide         &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      --proto        route_guide.proto    &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      --call routeguide.RouteGuide.RecordRoute  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      127.0.0.1:10000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    壓測 20 秒，結果如下：
    
  &lt;/summary&gt;
  

&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Summary:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Count:        548082
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Total:        20.00 s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Slowest:      50.36 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Fastest:      0.12 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Average:      1.74 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Requests/sec: 27403.72
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Response time histogram:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.123 [1]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  5.147 [543463]        |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  10.170 [4297] |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  15.194 [271]  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  20.217 [8]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  25.241 [3]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  30.264 [1]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  35.288 [0]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  40.311 [0]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  45.335 [0]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  50.358 [1]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Latency distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  10 % in 0.90 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  25 % in 1.21 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  50 % in 1.58 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  75 % in 2.04 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  90 % in 2.66 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  95 % in 3.24 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  99 % in 4.93 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status code distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [Canceled]      33 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [Unavailable]   4 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [OK]            548045 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Error distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [33]   rpc error: code = Canceled desc = grpc: the client connection is closing
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [4]    rpc error: code = Unavailable desc = transport is closing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;



&lt;/details&gt;

&lt;p&gt;同樣的，我們也可將事先備妥的資料檔餵給 ghz。像是含有 100 筆資料的 &lt;code&gt;testdata.json&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ghz --insecure --data&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;@  -z 20s  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      --import-paths ./routeguide         &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      --proto        route_guide.proto    &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      --call routeguide.RouteGuide.RecordRoute  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      127.0.0.1:10000  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt; testdata.json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    壓測 20 秒，結果如下：
    
  &lt;/summary&gt;
  

&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Summary:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Count:        788680
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Total:        20.00 s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Slowest:      28.02 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Fastest:      0.13 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Average:      1.23 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Requests/sec: 39432.62
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Response time histogram:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.126 [1]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  2.915 [772021]        |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  5.705 [15003] |∎
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  8.495 [1000]  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  11.285 [458]  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  14.074 [95]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  16.864 [10]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  19.654 [12]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  22.444 [3]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  25.233 [5]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  28.023 [40]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Latency distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  10 % in 0.65 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  25 % in 0.86 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  50 % in 1.11 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  75 % in 1.42 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  90 % in 1.88 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  95 % in 2.30 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  99 % in 3.57 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status code distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [OK]         788648 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [Canceled]   32 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Error distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [32]   rpc error: code = Canceled desc = grpc: the client connection is closing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;



&lt;/details&gt;

&lt;h2 id=&#34;實驗二不需搭配-proto-檔&#34;&gt;實驗二：不需搭配 proto 檔&lt;/h2&gt;
&lt;p&gt;使用前，每次都要先備妥待測程式的 proto 檔，其實也滿麻煩的。萬一複雜的 proto 檔案又去 import 其他 proto 檔 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，可能就得條列一堆 &lt;code&gt;-import-path&lt;/code&gt; 或 &lt;code&gt;--import-path&lt;/code&gt; 命令列參數給 gRPCurl 及 ghz。&lt;/p&gt;
&lt;p&gt;有沒有省力一點的方法？&lt;/p&gt;
&lt;p&gt;有的，就是透過 &lt;a href=&#34;https://github.com/grpc/grpc/blob/master/doc/server-reflection.md&#34;&gt;server reflection&lt;/a&gt; 功能。&lt;/p&gt;
&lt;h3 id=&#34;server-reflection&#34;&gt;Server reflection&lt;/h3&gt;
&lt;p&gt;我以這次的範例程式 server-new 為例，說明如何加上 server reflection 功能。&lt;/p&gt;
&lt;p&gt;首先，請加上 &lt;a href=&#34;https://pkg.go.dev/google.golang.org/grpc/reflection?tab=doc&#34;&gt;&lt;code&gt;google.golang.org/grpc/reflection&lt;/code&gt;&lt;/a&gt; 套件：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;google.golang.org/grpc/reflection&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;接著，在 &lt;code&gt;grpcServer.Serve&lt;/code&gt; 之前，呼叫 &lt;code&gt;reflection.Register&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;grpcServer&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;grpc&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;NewServer&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;opts&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;...&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Register reflection service on gRPC server.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;reflection&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Register&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;grpcServer&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;grpcServer&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Serve&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;lis&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;只需要這兩個步驟，你的 gRPC 程式本身就具有 server reflection 功能，對方不再需要 proto 檔案就能直接進行遠端呼叫。&lt;/p&gt;
&lt;p&gt;針對新版的 server-new 來實驗看看吧。&lt;/p&gt;
&lt;h3 id=&#34;grpcurl-1&#34;&gt;gRPCurl&lt;/h3&gt;
&lt;p&gt;我們可用 &lt;code&gt;list&lt;/code&gt; 指令查詢 server-new 提供哪些服務：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grpcurl -plaintext  127.0.0.1:20000  list
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grpc.reflection.v1alpha.ServerReflection
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;routeguide.RouteGuide&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;可用 &lt;code&gt;describe&lt;/code&gt; 指令查詢 server-new 提供服務的介面：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grpcurl -plaintext  127.0.0.1:20000  describe
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;grpc.reflection.v1alpha.ServerReflection is a service:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service ServerReflection &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rpc ServerReflectionInfo &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; stream .grpc.reflection.v1alpha.ServerReflectionRequest &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; returns &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; stream .grpc.reflection.v1alpha.ServerReflectionResponse &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;routeguide.RouteGuide is a service:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;service RouteGuide &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rpc GetFeature &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; .routeguide.Point &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; returns &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; .routeguide.Feature &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rpc ListFeatures &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; .routeguide.Rectangle &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; returns &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; stream .routeguide.Feature &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rpc RecordRoute &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; stream .routeguide.Point &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; returns &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; .routeguide.RouteSummary &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rpc RouteChat &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; stream .routeguide.RouteNote &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; returns &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt; stream .routeguide.RouteNote &lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;可用 &lt;code&gt;describe&lt;/code&gt; 指令進一步查詢某參數的具體格式：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grpcurl -plaintext  127.0.0.1:20000  describe .routeguide.Point
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;routeguide.Point is a message:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;message Point &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  int32 latitude &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 1;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  int32 longitude &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 2;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;可看出，gRPCurl 不需要 proto 檔案，就能直接向 server-new 查詢遠端呼叫所需知道的介面細節。&lt;/p&gt;
&lt;p&gt;最後，讓我們將含有 100 筆資料的 &lt;code&gt;testdata.dat&lt;/code&gt; 餵給 gRPCurl 來測測看：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ grpcurl -plaintext -d &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;@&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    127.0.0.1:20000         &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    routeguide.RouteGuide.RecordRoute  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt; testdata.dat
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;pointCount&amp;#34;&lt;/span&gt;: 100,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;distance&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;1003784333&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;有了 server reflection 功能，是不是方便多了？如果你有權修改原始程式，這是值得好好考慮的，可讓測試工作輕鬆一點。&lt;/p&gt;
&lt;p&gt;當然啦，你可以考慮在 production 環境&lt;strong&gt;關掉&lt;/strong&gt;這功能；但在測試環境中，這真的很方便。&lt;/p&gt;
&lt;h3 id=&#34;ghz-1&#34;&gt;ghz&lt;/h3&gt;
&lt;p&gt;儘管 server reflection 通常不會在 production 環境啟用，不過我還是很好奇：server reflection 對執行效率的影響有多少？尤其是涉及 marshalling。&lt;/p&gt;
&lt;p&gt;用 ghz 試試看吧！&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ghz --insecure --data&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;@  -z 20s  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      --call routeguide.RouteGuide.RecordRoute  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      127.0.0.1:20000  &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt; testdata.json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    壓測 20 秒，結果如下：
    
  &lt;/summary&gt;
  

&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Summary:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Count:        826524
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Total:        20.00 s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Slowest:      19.79 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Fastest:      0.12 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Average:      1.17 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Requests/sec: 41317.73
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Response time histogram:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.118 [1]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  2.085 [776730]        |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  4.052 [45892] |∎∎
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  6.019 [3018]  |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  7.986 [550]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  9.953 [112]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  11.920 [74]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  13.887 [51]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  15.854 [37]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  17.821 [17]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  19.788 [1]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Latency distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  10 % in 0.62 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  25 % in 0.82 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  50 % in 1.06 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  75 % in 1.36 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  90 % in 1.80 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  95 % in 2.20 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  99 % in 3.38 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status code distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [OK]            826483 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [Canceled]      40 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [Unavailable]   1 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Error distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [40]   rpc error: code = Canceled desc = grpc: the client connection is closing
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [1]    rpc error: code = Unavailable desc = transport is closing&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;



&lt;/details&gt;

&lt;p&gt;雖然這還不算非常嚴謹的實驗，但可看出，&lt;strong&gt;沒有&lt;/strong&gt; server reflection 功能的 server 版本，與&lt;strong&gt;有&lt;/strong&gt;此功能的 server-new 版本，執行效率沒有顯著差異。&lt;/p&gt;
&lt;p&gt;因此，server reflection 功能，值得嘗試。&lt;/p&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結&lt;/h2&gt;
&lt;p&gt;本篇文章，介紹兩個好用的 gRPC 測試小工具：輸入輸出介面測試工具 &lt;a href=&#34;https://github.com/fullstorydev/grpcurl&#34;&gt;gRPCurl&lt;/a&gt;，以及壓測工具 &lt;a href=&#34;https://github.com/bojand/ghz&#34;&gt;ghz&lt;/a&gt;。最後並推薦 &lt;a href=&#34;https://github.com/grpc/grpc/blob/master/doc/server-reflection.md&#34;&gt;server reflection&lt;/a&gt; 功能來簡化 gRPC 測試工作。&lt;/p&gt;
&lt;p&gt;ghz 也有 web 介面，目前是 beta 狀態。有興趣的，請去 &lt;a href=&#34;https://ghz.sh/&#34;&gt;ghz 官網&lt;/a&gt;看看。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Proto 檔案也可以 import 其他 proto 檔。詳見 &lt;a href=&#34;https://developers.google.com/protocol-buffers/docs/proto3#importing-definitions&#34;&gt;https://developers.google.com/protocol-buffers/docs/proto3#importing-definitions&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>gRPC Load Balancing in Kubernetes</title>
      <link>//william-yeh.net/post/2020/03/grpc-load-balancing/</link>
      <pubDate>Mon, 30 Mar 2020 22:30:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/03/grpc-load-balancing/</guid>
      
        <description>&lt;p&gt;Kubernetes 有個很方便的地方：只要修改 deployment 的 &lt;code&gt;spec.replicas&lt;/code&gt; 數字，就能橫向擴展 pod，以應付更大的流量負載需求。&lt;/p&gt;
&lt;p&gt;這一招，對於 stateless 的 HTTP 服務很管用，也是 Kubernetes 入門教學愛用的例子。但是，對於 &lt;a href=&#34;https://grpc.io/&#34;&gt;gRPC&lt;/a&gt; 呢？&lt;/p&gt;
&lt;p&gt;gRPC 是以 &lt;a href=&#34;https://en.wikipedia.org/wiki/HTTP/2&#34;&gt;HTTP/2&lt;/a&gt; 作為傳輸協定，而 HTTP/2 的特點是持久連線：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;One connection per origin&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;all HTTP/2 connections are persistent, and only one connection per origin is required, which offers numerous performance benefits.     &amp;ndash; &lt;a href=&#34;https://developers.google.com/web/fundamentals/performance/http2&#34;&gt;Introduction to HTTP/2&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;既然 gRPC 會盡可能維持既有連線，不會傻傻地一直斷線與重連，那麼，當 Kubernetes 橫向擴展 pod 了，gRPC 流量是否也能順便平均分散到新長出來的 pod 身上，還是死咬著原本的連線不放？&lt;/p&gt;
&lt;p&gt;做個簡單的實驗吧。&lt;/p&gt;
&lt;h2 id=&#34;實驗環境&#34;&gt;實驗環境&lt;/h2&gt;
&lt;p&gt;實驗程式放在 &lt;a href=&#34;https://github.com/William-Yeh/grpc-lb&#34;&gt;https://github.com/William-Yeh/grpc-lb&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;實驗所需環境：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go 1.14 以上。&lt;/li&gt;
&lt;li&gt;Kubernetes 1.14 以上。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://skaffold.dev/&#34;&gt;Skaffold&lt;/a&gt; 1.6.0 以上。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://linkerd.io/&#34;&gt;Linkerd&lt;/a&gt; 2.7.0 以上。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;實驗進行之前，請先編譯所需的執行檔及容器映像檔：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Generate native binaries in `out` directory: &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./build.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Generate Docker images:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;skaffold build&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;會產生以下程式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;執行檔 &lt;code&gt;out/server&lt;/code&gt; &amp;amp; 映像檔 &lt;code&gt;addr-server&lt;/code&gt;：接收 HTTP 及 gRPC 連線，傳回自己的 IP 位址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;執行檔 &lt;code&gt;client-http&lt;/code&gt; &amp;amp; 映像檔 &lt;code&gt;addr-client-http&lt;/code&gt;：透過 HTTP 查詢 server 位址。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;執行檔 &lt;code&gt;client-grpc&lt;/code&gt; &amp;amp; 映像檔 &lt;code&gt;addr-client-grpc&lt;/code&gt;：透過 gRPC 查詢 server 位址。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;實驗一純-kubernetes-模式&#34;&gt;實驗一：純 Kubernetes 模式&lt;/h2&gt;
&lt;p&gt;首先實驗看看，若 server 程式跑在 Kubernetes 裡，除了 HTTP 流量會自動負載均衡之外，是否 gRPC 流量也享有同等待遇。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/demo-1.png&#34; alt=&#34;實驗一：純 K8s 模式的佈局&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/demo-1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗一：純 K8s 模式的佈局&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;為了方便一眼看出整體狀況，請將終端機面板配置如下：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/demo-k8s-1.png&#34; alt=&#34;實驗一：終端機建議配置&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/demo-k8s-1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗一：終端機建議配置&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;請依照以下步驟進行實驗：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;建立 &lt;code&gt;grpc-lb&lt;/code&gt; namespace：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl create ns grpc-lb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;grpc-lb&lt;/code&gt; 裡執行 server，此時 &lt;code&gt;spec.replicas&lt;/code&gt; 為 &lt;code&gt;1&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;skaffold dev  -n grpc-lb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;執行 client-http，透過 HTTP 連線到 server：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;out/client-http  http://127.0.0.1:30080/addr&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;執行 client-grpc，透過 gRPC 連線到 server：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;out/client-grpc  localhost:30051&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因為現在 server pod 只有一個，所以 client-http 及 client-grpc 都只會連線到同一個 IP 位址（即此例的 &lt;code&gt;10.1.0.8&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;現在，讓我們把 server pod 的 &lt;code&gt;spec.replicas&lt;/code&gt; 數字擴展成 &lt;code&gt;5&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl scale -n grpc-lb &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  --replicas&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;  deployment/addr-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;如下圖所示，當 server pod 數目從 1 變成 5，Kubernetes 的確開始將 HTTP 流量平均分配到 5 個 pods 身上（即此例的 &lt;code&gt;10.1.0.8&lt;/code&gt; ～ &lt;code&gt;10.1.0.12&lt;/code&gt;）。可是 gRPC 流量卻仍然綁在舊的那一個 pod 身上（即此例的 &lt;code&gt;10.1.0.8&lt;/code&gt;）。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/demo-k8s-2.png&#34; alt=&#34;實驗一：gRPC 流量並未平均分配&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/demo-k8s-2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗一：gRPC 流量並未平均分配&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;可見，Kubernetes 並沒有對 gRPC 進行負載均衡。&lt;/p&gt;
&lt;p&gt;為什麼？&lt;/p&gt;
&lt;h2 id=&#34;l4-vs-l7-負載均衡&#34;&gt;L4 vs L7 負載均衡&lt;/h2&gt;
&lt;p&gt;根據 &amp;ldquo;&lt;a href=&#34;https://blog.nobugware.com/post/2019/kubernetes_mesh_network_load_balancing_grpc_services/&#34;&gt;gRPC Load Balancing inside Kubernetes&lt;/a&gt;&amp;rdquo; 一文所述，Kubernetes 原生的負載均衡機制，是建立在 L4：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you create a Service in Kubernetes, it creates a &lt;strong&gt;layer 4&lt;/strong&gt; proxy and load balance connections to your pods using iptables, the service endpoint is one IP and a port hiding your real pods.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因此，對於不具備真正持久連線的 HTTP 來說，Kubernetes 原生的 L4 負載均衡機制足以應付 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;；但是，對於真正具有持久連線的 gRPC，L4 就行不通了。&lt;/p&gt;
&lt;p&gt;文中列出三種解決方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Client 端的負載均衡：叫 client 維持一個 gRPC connection pool，主動與每一個 gRPC server pods 都維持連線。缺點是：必須修改 client 程式碼，也暴露 server pods 的一些內部細節。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes edge 端的負載均衡：透過 ingress 之類的機制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes service mesh：透過 sidecar 之類的機制。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;為了簡單起見，我參考 Kubernetes 官網文章 &amp;ldquo;&lt;a href=&#34;https://kubernetes.io/blog/2018/11/07/grpc-load-balancing-on-kubernetes-without-tears/&#34;&gt;gRPC Load Balancing on Kubernetes without Tears&lt;/a&gt;&amp;rdquo; 的做法，用 Linkerd 2 這個 service mesh 方案來實驗。 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;實驗二service-mesh-模式&#34;&gt;實驗二：Service mesh 模式&lt;/h2&gt;
&lt;p&gt;根據 Linkerd 官網 &lt;a href=&#34;https://linkerd.io/2/faq/#whats-the-difference-between-linkerd-1x-and-2x&#34;&gt;FAQ&lt;/a&gt; 所述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Linkerd 1.x is built on the “Twitter stack”: Finagle, Netty, Scala, and the JVM.&lt;/p&gt;
&lt;p&gt;Linkerd 2.x is built in Rust and Go. It is significantly faster and lighter weight than 1.x, but currently only supports Kubernetes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Linkerd 2 比前一版有長足的進步，又是 &lt;a href=&#34;https://smi-spec.io/&#34;&gt;SMI&lt;/a&gt; 陣營的一員，頗值得一試。&lt;/p&gt;
&lt;h3 id=&#34;linkerd-前置作業&#34;&gt;Linkerd 前置作業&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;安裝 Linkerd 2 到現行的 Kubernetes cluster：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Install&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;linkerd install | kubectl apply -f -
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# Check&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;linkerd check&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;先刪掉舊的 &lt;code&gt;grpc-lb&lt;/code&gt; namespace:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl delete ns grpc-lb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;建立新的 &lt;code&gt;grpc-lb&lt;/code&gt; namespace，並注入 Linkerd：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl apply -f ns.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;檢查一下 &lt;code&gt;grpc-lb&lt;/code&gt; namespace 的 data plane 是否正常：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;linkerd -n grpc-lb check --proxy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我們把 &lt;code&gt;grpc-lb&lt;/code&gt; namespace 圈成一塊 service mesh 疆域。如果一切順利，在 &lt;code&gt;grpc-lb&lt;/code&gt; namespace 裡面的東西，會自動被 Linkerd 接管——包括 gRPC 負載均衡。&lt;/p&gt;
&lt;h3 id=&#34;replicas--1&#34;&gt;Replicas = 1&lt;/h3&gt;
&lt;p&gt;首先實驗看看，若我們將 addr-client-grpc 與 server 都放在 service mesh 疆域內，兩者間的 gRPC 流量是否會自動負載均衡。我也保留一份舊的 client-grpc 故意「&lt;strong&gt;不&lt;/strong&gt;」讓它跑在 Kubernetes 裡面，作為對照組。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/demo-2.png&#34; alt=&#34;實驗二：K8s service mesh 模式的佈局&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/demo-2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗二：K8s service mesh 模式的佈局&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;為了方便一眼看出整體狀況，請將終端機面板配置如下：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/demo-mesh-1.png&#34; alt=&#34;實驗二：終端機建議配置&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/demo-mesh-1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗二：終端機建議配置&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;請依照以下步驟進行實驗：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;移掉 &lt;code&gt;skaffold.yaml&lt;/code&gt; 這一行的註解符號：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;deploy&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;kubectl&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;manifests&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#ae81ff&#34;&gt;server.yml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#75715e&#34;&gt;#- client-grpc.yml  ← 請讓這一行生效！&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 &lt;code&gt;grpc-lb&lt;/code&gt; namespace 裡執行 addr-client-grpc 及 server，此時 server 的 &lt;code&gt;spec.replicas&lt;/code&gt; 為 &lt;code&gt;1&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;skaffold dev  -n grpc-lb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;等前一個步驟跑到穩定狀態之後，在 Kubernetes 外面也執行一份舊的 client-grpc 作為對照組：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;out/client-grpc  localhost:30051&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;此時，因為 server pod 只有一個，所以，位於 service mesh 疆域內的 addr-client-grpc 及疆域外的 client-grpc 都只會連線到同一個 IP 位址（即此例的 &lt;code&gt;10.1.0.71&lt;/code&gt;）。&lt;/p&gt;
&lt;h3 id=&#34;replicas--5&#34;&gt;Replicas = 5&lt;/h3&gt;
&lt;p&gt;一切就緒，讓我們把 server pod 的 &lt;code&gt;spec.replicas&lt;/code&gt; 數字擴展成 &lt;code&gt;5&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl scale -n grpc-lb &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  --replicas&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;  deployment/addr-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;如下圖所示，當 server pod 數目從 1 變成 5，Kubernetes 的確開始將 service mesh 疆域內 addr-client-grpc 產生的 gRPC 流量平均分配到 5 個 pods 身上（即此例的 &lt;code&gt;10.1.0.71&lt;/code&gt; ～ &lt;code&gt;10.1.0.75&lt;/code&gt;）。可是「&lt;strong&gt;不&lt;/strong&gt;」位於 service mesh 疆域的 client-grpc 產生的 gRPC 流量，就仍然綁在舊的那一個 pod 身上（即此例的 &lt;code&gt;10.1.0.71&lt;/code&gt;）。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/demo-mesh-2.png&#34; alt=&#34;實驗二：gRPC 流量分配狀況&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/demo-mesh-2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗二：gRPC 流量分配狀況&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h3 id=&#34;linkerd-儀表板&#34;&gt;Linkerd 儀表板&lt;/h3&gt;
&lt;p&gt;讓我們看看酷炫一點的東西吧！請用以下命令打開 Linkerd 儀表板：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;linkerd dashboard &amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;請切換到 &lt;code&gt;grpc-lb&lt;/code&gt; namespace，觀察三個角色之間的網路互連架構，並檢視一些效率指標。如下圖所示，Linkerd 2.7.0 對於 gRPC load balancing 的表現很不錯，即使打開 mesh sidecar，P99 latency 也仍然壓在 10ms 左右的水準：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/dashboard-1.png&#34; alt=&#34;實驗二：Topology&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/dashboard-1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗二：Topology&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;從下圖也可以看到 5 個 server pods 都有輪流服務到 addr-client-grpc。其中，最後一個 pod 比較可憐，湊巧服務到獨佔連線的外部 client-grpc：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/dashboard-2.png&#34; alt=&#34;實驗二：gRPC 負載均衡的數據&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/dashboard-2.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;實驗二：gRPC 負載均衡的數據&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;  &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;簡單的實驗，示範在 Kubernetes 裡，可以透過 service mesh 替 gRPC 加上負載均衡機制。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;嚴格來說，HTTP/1.1 的 keep alive 機制，或多或少會影響到 Kubernetes 的負載均衡效果。不過正如&lt;a href=&#34;https://en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1&#34;&gt;維基百科&lt;/a&gt;所說，許多 Web server 本來就會針對 HTTP 設定較短的 timeout 以避免副作用。若真的要在 Web 上進行持久連線，一般都會建議改走 &lt;a href=&#34;https://en.wikipedia.org/wiki/WebSocket&#34;&gt;WebSocket&lt;/a&gt; 路線。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;有在玩 &lt;a href=&#34;https://istio.io/&#34;&gt;Istio&lt;/a&gt; 的朋友，可以參考〈&lt;a href=&#34;https://medium.com/getamis/istio-%E5%9F%BA%E7%A4%8E-grpc-%E8%B2%A0%E8%BC%89%E5%9D%87%E8%A1%A1-d4be0d49ee07&#34;&gt;Istio 基礎 — gRPC 負載均衡&lt;/a&gt;〉一文的做法。不過，比較起來，Istio 設定上會比 Linkerd 複雜。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Idempotency Key：原理與實測</title>
      <link>//william-yeh.net/post/2020/03/idempotency-key-test/</link>
      <pubDate>Tue, 10 Mar 2020 23:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/03/idempotency-key-test/</guid>
      
        <description>&lt;p&gt;最近幾年，在微服務打滾的人，不時會遇到神祕的 &amp;ldquo;idempotency key&amp;rdquo; 字眼。本文爬梳 idempotency key 的技術背景，探討運作流程，並分析資料庫的實作選項。&lt;/p&gt;
&lt;h2 id=&#34;idempotency-冪等性&#34;&gt;Idempotency 冪等性&lt;/h2&gt;
&lt;p&gt;在 API 服務中，常常需要留意 idempotency（冪等性）。&lt;/p&gt;
&lt;p&gt;名詞：idempotency，形容詞：idempotent。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Idempotency&amp;rdquo; 這字眼源自數學。維基百科是這麼解釋 &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Idempotence#Idempotent_functions&#34;&gt;idempotent function&lt;/a&gt;&amp;rdquo; 的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;idempotent elements are the functions &lt;em&gt;f&lt;/em&gt;: &lt;em&gt;E&lt;/em&gt; → &lt;em&gt;E&lt;/em&gt; [&amp;hellip;] such that for all &lt;em&gt;x&lt;/em&gt; in &lt;em&gt;E&lt;/em&gt;, &lt;em&gt;f&lt;/em&gt;(&lt;em&gt;f&lt;/em&gt;(&lt;em&gt;x&lt;/em&gt;)) = &lt;em&gt;f&lt;/em&gt;(&lt;em&gt;x&lt;/em&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果套用到電腦界 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，idempotency 性質可以詮釋成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;f&lt;/em&gt;：可以是 function 或是 API endpoint。&lt;/li&gt;
&lt;li&gt;&lt;em&gt;x&lt;/em&gt;：可以是 argument 或是 API header &amp;amp; payload。&lt;/li&gt;
&lt;li&gt;如果 &lt;em&gt;f&lt;/em&gt; 是 idempotent，就代表：對 &lt;em&gt;f&lt;/em&gt;(&lt;em&gt;x&lt;/em&gt;) 執行 1 次產生的效果，與執行 &lt;em&gt;N&lt;/em&gt; 次產生的效果，完全一樣。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;譬如說，如果有一個管理商品庫存的服務：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Item&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; {&lt;span style=&#34;color:#75715e&#34;&gt;/*...*/&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;ItemInventory&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;interface&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;GetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Item&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;       &lt;span style=&#34;color:#75715e&#34;&gt;// 查詢庫存量   &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;SetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Item&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;// 設定庫存量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;DecreaseQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Item&lt;/span&gt;)      &lt;span style=&#34;color:#75715e&#34;&gt;// 庫存量減一&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;那麼，像以下這些動作，呼叫 1 次的效果，與呼叫 &lt;em&gt;N&lt;/em&gt; 次的效果一樣，即可稱為是 idempotent：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;var&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 查詢庫存量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 設定庫存量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; = &lt;span style=&#34;color:#ae81ff&#34;&gt;100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;反之，像以下這些動作，呼叫 1 次的效果，與呼叫 &lt;em&gt;N&lt;/em&gt; 次的效果會&lt;strong&gt;不一樣&lt;/strong&gt;，即可稱為是 non-idempotent：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/*...*/&lt;/span&gt;                              &lt;span style=&#34;color:#75715e&#34;&gt;// 起初庫存量為 100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;DecreaseQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)     &lt;span style=&#34;color:#75715e&#34;&gt;// 庫存量會變成 99&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;DecreaseQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)     &lt;span style=&#34;color:#75715e&#34;&gt;// 庫存量會變成 98&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;DecreaseQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)     &lt;span style=&#34;color:#75715e&#34;&gt;// 庫存量會變成 97&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;non-idempotent-操作有必要存在嗎&#34;&gt;Non-idempotent 操作有必要存在嗎？&lt;/h2&gt;
&lt;p&gt;在 &lt;a href=&#34;https://en.wikipedia.org/wiki/Functional_programming&#34;&gt;functional programming&lt;/a&gt; 思潮下，immutability 及 idempotency 似乎才是政治正確之舉。&lt;/p&gt;
&lt;p&gt;Non-idempotent 的操作，真的有必要存在嗎？&lt;/p&gt;
&lt;p&gt;譬如說，即使沒有 non-idempotent 的 &lt;code&gt;DecreaseQuantity&lt;/code&gt;，我們仍可透過 idempotent 的 &lt;code&gt;SetQuantity&lt;/code&gt; 來達到一樣的效果：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; = &lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)       &lt;span style=&#34;color:#75715e&#34;&gt;// 起初庫存量為 100&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;numTarget&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;numTarget&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;// 庫存量會變成 99&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;numTarget&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;--&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;numTarget&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;// 庫存量會變成 98&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;numTarget&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;--&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;numTarget&lt;/span&gt;)  &lt;span style=&#34;color:#75715e&#34;&gt;// 庫存量會變成 97&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;如此一來，是否真的沒有必要再留下 non-idempotent 的 &lt;code&gt;DecreaseQuantity&lt;/code&gt;？至少有兩件事需要思考：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;語意層面的改變。原本 &lt;code&gt;DecreaseQuantity&lt;/code&gt; 的簽名，並沒有「庫存量」這一欄，也就是說，client 並不需要知道「目前庫存量」，即可進行「庫存量減一」。如果改寫成 &lt;code&gt;SetQuantity&lt;/code&gt; 版本，簽名不同，多了「庫存量」欄位，換句話說，原本不必知道的「庫存量」內容，現在就必須透露出來了——這改變了原本「庫存量減一」的操作語意。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;同步問題。同一時間，萬一有別人也在透過這個新方法改動「庫存量」，就會發生 race condition。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因此，某些時候，non-idempotency 可能無法完全迴避。&lt;/p&gt;
&lt;h2 id=&#34;http-的-idempotency-規範&#34;&gt;HTTP 的 idempotency 規範&lt;/h2&gt;
&lt;p&gt;HTTP 對於 idempotency 有一些規範。像 HTTP/1.1 的規格書 &lt;a href=&#34;https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.2&#34;&gt;§9.1.2&lt;/a&gt; 就指出：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Methods can also have the property of &amp;ldquo;idempotence&amp;rdquo; in that (aside from error or expiration issues) the side-effects of &lt;em&gt;N&lt;/em&gt; &amp;gt; 0 identical requests is the same as for a single request. The methods &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;HEAD&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt; and &lt;code&gt;DELETE&lt;/code&gt; share this property. Also, the methods &lt;code&gt;OPTIONS&lt;/code&gt; and &lt;code&gt;TRACE&lt;/code&gt; SHOULD NOT have side effects, and so are inherently idempotent.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://tools.ietf.org/html/rfc5789&#34;&gt;RFC 5789&lt;/a&gt; 也提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;PATCH&lt;/code&gt; is neither safe nor idempotent as defined by &lt;a href=&#34;https://tools.ietf.org/html/rfc2616&#34;&gt;RFC2616&lt;/a&gt;, Section 9.1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，綜合來說，在 HTTP 的標準規範當中，只有 &lt;code&gt;POST&lt;/code&gt; 及 &lt;code&gt;PATCH&lt;/code&gt; 不是 idempotent。&lt;/p&gt;
&lt;p&gt;對這些 HTTP 細節感興趣的，請參考 ihower 的〈&lt;a href=&#34;https://ihower.tw/blog/archives/6483&#34;&gt;HTTP Verbs：談 POST, PUT 和 PATCH 的應用&lt;/a&gt;〉一文。&lt;/p&gt;
&lt;h2 id=&#34;web-api-的-idempotency-問題&#34;&gt;Web API 的 idempotency 問題&lt;/h2&gt;
&lt;p&gt;前面的 Go 程式碼講的是 in process 場景。環境單純，沒有太多失敗、重試的未知狀況，不會有太大的 idempotency 問題。如果換成 out of process 場景，環境不再單純，網路環境不可靠，另一頭的通訊對象也不見得是穩定的，失敗、重試的未知狀況勢必增加，idempotency 就變成不得不去正視的議題。&lt;/p&gt;
&lt;p&gt;譬如說，如果把管理商品庫存服務實作成 RESTful API：&lt;/p&gt;

&lt;details&gt;
  &lt;summary style=&#34;background-color:#f5f5f5;border:1px solid #ccc;padding:5px;&#34;&gt;
    Go &amp;#43; Gin 實作的 RESTful API 例子
    
  &lt;/summary&gt;
  &lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;github.com/gin-gonic/gin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;strconv&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;router&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;gin&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Default&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// 查詢庫存量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;router&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GET&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/inventory/quantity/:item_id&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;gin&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Context&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt; &lt;span style=&#34;color:#960050;background-color:#1e0010&#34;&gt;：&lt;/span&gt;= &lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;GetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// 設定庫存量&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;router&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;PUT&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/inventory/quantity/:item_id&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;gin&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Context&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;_&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;:=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;strconv&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Atoi&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;PostForm&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;num&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;SetQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;num&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// 庫存量減一&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;router&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;POST&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/inventory/quantity/:item_id/dec&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#66d9ef&#34;&gt;func&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;c&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;gin&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Context&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#a6e22e&#34;&gt;inventory&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;DecreaseQuantity&lt;/span&gt;(&lt;span style=&#34;color:#a6e22e&#34;&gt;item&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#75715e&#34;&gt;///&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#a6e22e&#34;&gt;router&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;Run&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/details&gt;

&lt;p&gt;對於原本就是 idempotent 的 &lt;code&gt;GetQuantity&lt;/code&gt; 和 &lt;code&gt;SetQuantity&lt;/code&gt; 操作來說，換成 RESTful 版本並沒什麼問題。像以下這個例子中，Client 在 🅐 步驟向 Server 呼叫 query quantity 操作時，只要該資料沒被別人改動到，這個 🅐 步驟不管重試多少次，得到的結果都會是一樣的。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/restapi-idempotent.png&#34; alt=&#34;Idempotent API operations&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/restapi-idempotent.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Idempotent API operations&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;但是，對於原本就是 non-idempotent 的 &lt;code&gt;DecreaseQuantity&lt;/code&gt; 操作來說，一遇到失敗、重試的未知狀況就麻煩了。像以下這個例子中，Client 在 🅑 步驟向 Server 呼叫 decrease quantity 操作時，Server 及 DB 都完成了各自的任務，可惜當 Server 在回傳結果給 Client 時，因為網路不穩定而漏失訊息。&lt;/p&gt;
&lt;p&gt;Client 不會知道 🅑 背後涉及的各個環節究竟完成了多少，只會以為 🅑 步驟沒有生效，便主動以 🅑’ 步驟重試一次。Server 並不知道這個 🅑’ 只是個美麗的誤會，只能忠實地再執行一次 &lt;code&gt;DecreaseQuantity&lt;/code&gt; 操作。於是，&lt;code&gt;DecreaseQuantity&lt;/code&gt; 這個 non-idempotent 操作，就被錯誤地重複使用，造成錯誤的結果。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/restapi-nonidempotent.png&#34; alt=&#34;Non-idempotent API operations&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/restapi-nonidempotent.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Non-idempotent API operations&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這也是為什麼我們在一些沒有仔細處理 idempotency 的交易網站上，會看到這類警語：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;交易進行中，請勿按下【重新載入此頁】按鈕，以避免重複扣款。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也就是說，他們認為，倘若因為電腦或網路不穩定而頻頻手動重試，從而導致的任何不良後果，都是使用者不聽勸告的錯。&lt;/p&gt;
&lt;h2 id=&#34;向-tcp-取經&#34;&gt;向 TCP 取經&lt;/h2&gt;
&lt;p&gt;在不穩定的分散式系統中，對於 non-idempotent 的操作，該如何避免重試所引發的問題？&lt;/p&gt;
&lt;p&gt;不妨師法 TCP 吧，畢竟它算是在不可靠的 IP 傳輸環境中進行可靠傳輸的老祖宗了。&lt;/p&gt;
&lt;p&gt;每一個 TCP segment 的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure&#34;&gt;header&lt;/a&gt; 都帶有一個&lt;strong&gt;序列號&lt;/strong&gt; (&lt;strong&gt;seq&lt;/strong&gt;)，透過它，TCP 通訊的雙方，得以在不可靠的環境中，處理連線建立、流量控制、連線關閉等議題。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 就以 TCP 的 3-way handshake 機制為例，雙方藉由 seq 來溝通是否成功地傳送與接收訊息：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/tcp-3way-handshake.png&#34; alt=&#34;TCP 3-way handshake&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/tcp-3way-handshake.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;TCP 3-way handshake&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;我們來分析 🅒 🅓 🅔 這幾種訊息丟失的狀況。&lt;/p&gt;
&lt;p&gt;如果 🅒 訊息在中途就丟失了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;那麼，Server 自然不會送出 🅓。&lt;/li&gt;
&lt;li&gt;既然 Client 遲遲沒收到 🅓，也就會繼續重試 🅒 (seq=&lt;em&gt;x&lt;/em&gt;)。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果 🅒 訊息成功送給 Server 了，但 🅓 訊息卻在中途就丟失了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;既然 Client 遲遲沒收到 🅓，就會繼續重試 🅒 (seq=&lt;em&gt;x&lt;/em&gt;)。&lt;/li&gt;
&lt;li&gt;Server 在收到 🅒 時，會根據 seq=&lt;em&gt;x&lt;/em&gt; 得知這是重複的訊息。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果 🅔 訊息在中途就丟失了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;既然 Server 遲遲沒收到 🅔，就會繼續重試 🅓 (seq=&lt;em&gt;y&lt;/em&gt;)。&lt;/li&gt;
&lt;li&gt;Client 在收到 🅓 時，會根據 seq=&lt;em&gt;y&lt;/em&gt; 得知這是重複的訊息。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根據以上分析，我們可從 TCP 偷學一個祕訣：只要在 request 附上一個&lt;strong&gt;識別碼&lt;/strong&gt;，就能讓通訊雙方偵測出失敗重試的情況，以採取對應的措施。&lt;/p&gt;
&lt;p&gt;這就是 TCP 在 layer 4 進行的可靠傳輸措施。&lt;/p&gt;
&lt;h2 id=&#34;識別碼由誰來產生&#34;&gt;識別碼，由誰來產生？&lt;/h2&gt;
&lt;p&gt;這一招，不僅在 layer 4 行之有年，在 layer 7 也一樣管用。&lt;/p&gt;
&lt;p&gt;接下來的問題是：識別碼，由誰來產生？由 request 的接收方，還是發起方？&lt;/p&gt;
&lt;p&gt;識別碼可以由 request 接收方：server 產生。像 &lt;a href=&#34;https://www.amazon.com/dp/0596801688/138-6991958-6648417&#34;&gt;&lt;em&gt;Restful Web Services Cookbook&lt;/em&gt;&lt;/a&gt; §10.8 &amp;amp; §10.9 就建議，針對 non-idempotent 的操作，server 可先產生 &lt;a href=&#34;https://en.wikipedia.org/wiki/Cryptographic_nonce&#34;&gt;nonce&lt;/a&gt; 當作識別碼，將它當成參數添加到服務的 URI 上面，再請 client 透過這個加過料的 URI 來操作 server 的服務。&lt;/p&gt;
&lt;p&gt;也有人把識別碼的生成責任交給 request 發起方：client 來做。像 Stripe 官方提供的 &lt;a href=&#34;https://github.com/stripe/stripe-ruby/blob/1a20c2476d35d80e411e5a692727ed5438614d66/lib/stripe/stripe_client.rb#L747&#34;&gt;StripeClient 程式庫&lt;/a&gt;，針對 &lt;code&gt;POST&lt;/code&gt; 及 &lt;code&gt;DELETE&lt;/code&gt; 類型的操作，會先在 client 這邊產生 uuid v4 當作識別碼，將它添加到 HTTP header 中（此例為 &lt;code&gt;Idempotency-Key&lt;/code&gt;），再傳給 server：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-ruby&#34; data-lang=&#34;ruby&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# It is only safe to retry network failures on post and delete&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# requests if we add an Idempotency-Key header&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;%&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;post delete&lt;span style=&#34;color:#f92672&#34;&gt;].&lt;/span&gt;include?(method) &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;Stripe&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;max_network_retries &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    headers&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Idempotency-Key&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;||=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;SecureRandom&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;uuid
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;簡單的概念，近年來較新的服務，尤其是與金流或電子商務有關的，似乎也很流行這種 “idempotency key” 手法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adyen: &lt;a href=&#34;https://docs.adyen.com/development-resources/api-idempotency&#34;&gt;API idempotency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Airbnb: &lt;a href=&#34;https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bb&#34;&gt;Avoiding Double Payments in a Distributed Payments System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Square: &lt;a href=&#34;https://developer.squareup.com/docs/working-with-apis/idempotency&#34;&gt;Working with APIs: Idempotency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Stitch Fix: &lt;a href=&#34;https://multithreaded.stitchfix.com/blog/2017/06/26/patterns-of-soa-idempotency-key/&#34;&gt;Patterns of Service-oriented Architecture: Idempotency Key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Stripe：&lt;a href=&#34;https://stripe.com/docs/api/idempotent_requests&#34;&gt;API Reference: Idempotent Requests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;概念很簡單，卻有個來歷不明的酷炫名詞 “&lt;a href=&#34;https://stripe.com/blog/idempotency&#34;&gt;idempotency key&lt;/a&gt;”。根據 Stripe 工程師 &lt;a href=&#34;https://twitter.com/brandur&#34;&gt;Brandur Leach&lt;/a&gt; 在 &amp;ldquo;&lt;a href=&#34;https://brandur.org/idempotency-keys&#34;&gt;Implementing Stripe-like Idempotency Keys in Postgres&lt;/a&gt;&amp;rdquo; 一文所說，這名詞是 Stripe 發明的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An &lt;strong&gt;idempotency key&lt;/strong&gt; is a unique value that’s generated by a client and sent to an API along with a request. The server stores the key to use for bookkeeping the status of that request on its end. If a request should fail partway through, the client retries with the &lt;em&gt;same&lt;/em&gt; idempotency key value, and the server uses it to look up the request’s state and continue from where it left off. &lt;strong&gt;The name “idempotency key” comes from Stripe’s API.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在沒有進一步翻案證據之前，暫時姑且接受「這是 Stripe 發明的」的說法吧。&lt;/p&gt;
&lt;h2 id=&#34;idempotency-key-的生成&#34;&gt;Idempotency key 的生成&lt;/h2&gt;
&lt;p&gt;理論上，任何機制，只要在合理範圍內具有唯一性，就能用來產生 idempotency key。&lt;/p&gt;
&lt;p&gt;但實務上，在實作 idempotency key 時，可能還需要考慮幾個議題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;由資料庫自動產生，還是由程式邏輯層產生？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;純亂數，還是單調遞增？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;資料庫能夠自動替我們產生單調遞增序號。只要將 idempotency key 宣告成 MySQL 的 &lt;a href=&#34;https://dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html&#34;&gt;&lt;code&gt;auto_increment&lt;/code&gt;&lt;/a&gt; 或 PostgreSQL 的 &lt;a href=&#34;https://www.postgresql.org/docs/current/datatype-numeric.html#DATATYPE-SERIAL&#34;&gt;&lt;code&gt;serial&lt;/code&gt;&lt;/a&gt; 之類的資料型態，再搭配像 MySQL 的 &lt;a href=&#34;https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_last-insert-id&#34;&gt;&lt;code&gt;last_insert_id()&lt;/code&gt;&lt;/a&gt; 或 PostgreSQL 的 &lt;a href=&#34;https://www.postgresql.org/docs/current/sql-insert.html&#34;&gt;&lt;code&gt;insert returning&lt;/code&gt;&lt;/a&gt; 之類的查詢語法，即可一次搞定 idempotency key 生成與儲存。&lt;/p&gt;
&lt;p&gt;乍看之下很方便，不過，如果資料庫有分庫分表，就需要再額外處理，才能確保序號的唯一性。另一個或許更嚴重的缺點是，從架構潔癖的角度來看，違反了 &lt;a href=&#34;https://www.tenlong.com.tw/products/9789864342945&#34;&gt;clean architecture&lt;/a&gt; 的分層原則與相依原則：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;資料庫是個細節，我們將這些東西放在外頭，在那邊它們不會有什麼危害。&lt;/p&gt;
&lt;p&gt;資料庫不是資料模型。資料庫是一塊軟體，是提供對於資料存取的工具。它是一個低層級的細節——是一種機制。一名好的架構師，不會允許底層機制污染系統的架構。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同樣有架構潔癖的 DDD，也不喜歡過於仰賴資料庫機制，像 &lt;a href=&#34;https://www.amazon.com/dp/0321834577/ref=cm_sw_r_tw_dp_U_x_gp2zEbQ9DT5BB&#34;&gt;&lt;em&gt;Implementing Domain-Driven Design&lt;/em&gt;&lt;/a&gt; 的 §5.2 就直接建議大家將序號產生機制放在 Repository 層。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;如果要改由程式邏輯層產生 idempotency key，可能會直接套用 &lt;a href=&#34;https://en.wikipedia.org/wiki/Universally_unique_identifier&#34;&gt;uuid&lt;/a&gt;，甚至訴諸 &lt;a href=&#34;https://developer.twitter.com/en/docs/basics/twitter-ids&#34;&gt;Snowflake&lt;/a&gt;、&lt;a href=&#34;https://github.com/sony/sonyflake&#34;&gt;Sonyflake&lt;/a&gt;、&lt;a href=&#34;https://tech.meituan.com/2017/04/21/mt-leaf.html&#34;&gt;Leaf&lt;/a&gt; 這類分散式 ID 服務。不依賴資料庫，彈性大，也符合架構潔癖。&lt;/p&gt;
&lt;p&gt;不依賴資料庫，符合了架構潔癖，是否會因此犧牲了資料庫的效能？接下來我們就來探討這議題。&lt;/p&gt;
&lt;h2 id=&#34;idempotency-key-的儲存&#34;&gt;Idempotency key 的儲存&lt;/h2&gt;
&lt;p&gt;透過程式邏輯產生的 id，可粗分為三大類：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;純亂數：像 &lt;a href=&#34;https://www.uuidtools.com/uuid-versions-explained#version-4&#34;&gt;uuid v4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;局部單調遞增：像 &lt;a href=&#34;https://www.uuidtools.com/uuid-versions-explained#version-1&#34;&gt;uuid v1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;全域單調遞增：像 &lt;a href=&#34;https://developer.twitter.com/en/docs/basics/twitter-ids&#34;&gt;Snowflake&lt;/a&gt;、&lt;a href=&#34;https://github.com/sony/sonyflake&#34;&gt;Sonyflake&lt;/a&gt;、&lt;a href=&#34;https://tech.meituan.com/2017/04/21/mt-leaf.html&#34;&gt;Leaf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些 idempotency key 該如何儲存，才可與資料庫內建的單調遞增序號一較高下？&lt;/p&gt;
&lt;p&gt;理論上來說，在目前資料庫系統主流的 &lt;a href=&#34;https://en.wikipedia.org/wiki/B%2B_tree&#34;&gt;B+ tree&lt;/a&gt; 索引結構下，單調遞增的數值，會比純亂數來得有效率。因此，若不計資料欄位大小差異，三者的存取效率，理論上應該會是 Snowflake &amp;gt; uuid v1 &amp;gt; uuid v4。&lt;/p&gt;
&lt;p&gt;不過，我對於 PostgreSQL 提供的 &lt;a href=&#34;https://www.postgresql.org/docs/current/datatype-uuid.html&#34;&gt;uuid 資料型態&lt;/a&gt;格外感興趣：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PostgreSQL provides storage and comparison functions for UUIDs, but the core database does not include any function for generating UUIDs, because no single algorithm is well suited for every application.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;從 PostgreSQL 原始碼 &lt;a href=&#34;https://github.com/postgres/postgres/blob/0a42a2e9ce8481a024d085f2cc526a366db8df59/src/include/utils/uuid.h#L17-L23&#34;&gt;uuid.h&lt;/a&gt; 及 &lt;a href=&#34;https://github.com/postgres/postgres/blob/master/src/backend/utils/adt/uuid.c&#34;&gt;uuid.c&lt;/a&gt; 來看，骨子裡是用 16 bytes 字元陣列來實作：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* uuid size in bytes */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define UUID_LEN 16
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;pg_uuid_t&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;unsigned&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; data[UUID_LEN];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;} &lt;span style=&#34;color:#66d9ef&#34;&gt;pg_uuid_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* internal uuid compare function */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;static&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;uuid_internal_cmp&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;pg_uuid_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;arg1, &lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;pg_uuid_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;arg2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;memcmp&lt;/span&gt;(arg1&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;data, arg2&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;data, UUID_LEN);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;/* hash index support */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Datum
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;uuid_hash&lt;/span&gt;(PG_FUNCTION_ARGS)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;pg_uuid_t&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;key &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;PG_GETARG_UUID_P&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;hash_any&lt;/span&gt;(key&lt;span style=&#34;color:#f92672&#34;&gt;-&amp;gt;&lt;/span&gt;data, UUID_LEN);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;對於 uuid 的存取性能，PostgreSQL 似乎是有備而來胸有成竹。&lt;/p&gt;
&lt;p&gt;因此，我針對 PostgreSQL 的 &lt;code&gt;uuid&lt;/code&gt; 資料型態，分別實驗「亂數」與「遞增數值」存取效率，順便也拿 &lt;code&gt;bigint&lt;/code&gt; 做對照組，看看這些排列組合，哪一種比較適合 idempotency key 用途：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Idempotency Key 類型&lt;/th&gt;
          &lt;th&gt;演算法&lt;/th&gt;
          &lt;th&gt;資料大小 (bytes)&lt;/th&gt;
          &lt;th&gt;PostgreSQL 資料型態&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;亂數&lt;/td&gt;
          &lt;td&gt;uuid v4&lt;/td&gt;
          &lt;td&gt;16&lt;/td&gt;
          &lt;td&gt;uuid&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;遞增數值&lt;/td&gt;
          &lt;td&gt;uuid v1&lt;/td&gt;
          &lt;td&gt;16&lt;/td&gt;
          &lt;td&gt;uuid&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;遞增數值&lt;/td&gt;
          &lt;td&gt;Snowflake&lt;/td&gt;
          &lt;td&gt;8&lt;/td&gt;
          &lt;td&gt;bigint&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;針對這些排列組合，我進行三組實驗：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;寫入 &lt;em&gt;N&lt;/em&gt; 筆資料：InsertUuidV1、InsertUuidV4、InsertSnowflake&lt;/li&gt;
&lt;li&gt;隨機存取 10% 資料，無 DB cache：SelectUuidV1/clean、InsertUuidV4/clean、InsertSnowflake/clean&lt;/li&gt;
&lt;li&gt;隨機存取 10% 資料，有 DB cache：SelectUuidV1/cache、InsertUuidV4/cache、InsertSnowflake/cache&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;實驗程式放在 &lt;a href=&#34;https://github.com/William-Yeh/idempotency-key-test&#34;&gt;https://github.com/William-Yeh/idempotency-key-test&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我的實驗環境：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MacBook Pro&lt;/li&gt;
&lt;li&gt;CPU: 2.8 GHz 四核心Intel Core i7&lt;/li&gt;
&lt;li&gt;Go: 1.14&lt;/li&gt;
&lt;li&gt;PostgreSQL: 12.2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;首先牛刀小試一下，實驗 10 萬筆資料：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/items-100k.png&#34; alt=&#34;Test with N=100k&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/items-100k.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Test with N=100k&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;乍看之下，三種 idempotency key 資料類型，彼此性能差異並不大。數量級分別是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;寫入 &lt;em&gt;N&lt;/em&gt; 筆資料：每秒能處理約 5*10³ 筆操作。&lt;/li&gt;
&lt;li&gt;隨機存取 10% 資料，無 DB cache：每秒能處理約 5*10⁴ 筆操作。&lt;/li&gt;
&lt;li&gt;隨機存取 10% 資料，有 DB cache：每秒能處理約 8*10⁴ 筆操作。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;放大十倍試試看，實驗 100 萬筆資料：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/items-1m.png&#34; alt=&#34;Test with N=1m&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/items-1m.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Test with N=1m&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;最後，實驗 300 萬筆資料，順便看看三種 idempotency key 資料類型佔用的索引空間：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2020/03/items-3m.png&#34; alt=&#34;Test with N=3m&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2020/03/items-3m.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Test with N=3m&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;執行速度差異不大。至於索引結構，則是 uuid v1 顯著偏高，而 uuid v4 與 snowflake 無太大差異。&lt;/p&gt;
&lt;p&gt;綜合以上實驗，PostgreSQL 的 &lt;code&gt;uuid&lt;/code&gt; 效能十分優異，足堪大任。我建議：如果你的 idempotency key 想要是亂數，可以直接把 uuid v4 存在 &lt;code&gt;uuid&lt;/code&gt; 欄位中；如果你的 idempotency key 想要是單調遞增數值，不妨考慮把 snowflake 存在 &lt;code&gt;bigint&lt;/code&gt; 欄位中。&lt;/p&gt;
&lt;p&gt;如果你用的是其他資料庫系統，此處的建議不見得適用，請自行實驗。&lt;/p&gt;
&lt;h2 id=&#34;致謝&#34;&gt;致謝&lt;/h2&gt;
&lt;p&gt;實驗設計過程中，從 Carousell 同事得到許多建議，特此致謝。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://careers.carousell.com/&#34;&gt;We&amp;rsquo;re hiring!&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;嚴格來說，電腦領域講的 &amp;ldquo;idempotency&amp;rdquo;，已經與數學領域講的 &amp;ldquo;idempotency&amp;rdquo; 不盡相同了，可說是一種假借。詳情請見維基百科的說明： &lt;a href=&#34;https://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning&#34;&gt;https://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;對於 TCP 序列號機制感興趣的，可參考鄭中勝寫的三篇介紹文章：〈&lt;a href=&#34;https://notfalse.net/26/tcp-seq&#34;&gt;TCP 序列號 (Sequence Number, SEQ)&lt;/a&gt;〉、〈&lt;a href=&#34;https://notfalse.net/7/three-way-handshake&#34;&gt;TCP 三向交握 (Three-way Handshake)&lt;/a&gt;〉、〈&lt;a href=&#34;https://notfalse.net/24/tcp-flow-control&#34;&gt;TCP 流量控制 (Flow Control)&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;在 DDD 中，id 生成機制很適合放在 Repository 層。如果你沒有 &lt;a href=&#34;https://www.amazon.com/dp/0321834577/ref=cm_sw_r_tw_dp_U_x_gp2zEbQ9DT5BB&#34;&gt;&lt;em&gt;Implementing Domain-Driven Design&lt;/em&gt;&lt;/a&gt; 這本書，也可以參考劉鳳軒寫的〈&lt;a href=&#34;https://ithelp.ithome.com.tw/articles/10223150&#34;&gt;DDD 戰術設計：Entity 概念與實作&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>求職，別忘了突出你的亮點</title>
      <link>//william-yeh.net/post/2020/01/career-spotlight/</link>
      <pubDate>Wed, 08 Jan 2020 22:30:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2020/01/career-spotlight/</guid>
      
        <description>&lt;p&gt;在網路上看到 Joe 喟然&lt;a href=&#34;https://www.facebook.com/story.php?story_fbid=3000276969985335&amp;amp;id=100000091845448&#34;&gt;嘆曰&lt;/a&gt;：「今天重要功課：仔細看過明天 20 位&lt;a href=&#34;https://shop.darencademy.com/product/view/id/30&#34;&gt;履歷課&lt;/a&gt;同學的履歷以及繳交的功課。說起來這堂課好像是我們最耗能的一堂課，完全是做功德的一堂課。」&lt;/p&gt;
&lt;p&gt;我，身為履歷表價值鏈另一端的面試官，也很能瞭解這番滋味。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;近年來，履歷教戰守則廣傳，有專書，甚至還有專門課程。理論上，「不懂得 &lt;del&gt;包裝美化履歷&lt;/del&gt; 正確呈現履歷」的低級錯誤應該會越來越少見——其實不然。驚訝的是，即使是獵頭轉來的履歷也常無法倖免，真不知該怎麼說了。&lt;/p&gt;
&lt;p&gt;遇到比較多的反例，是沒有&lt;strong&gt;亮點&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;年資不必然是亮點&#34;&gt;年資，不必然是亮點&lt;/h2&gt;
&lt;p&gt;先破除一個迷思：年資，不必然是忠誠，不必然是專注，不必然是匠人精神。一言以蔽之，不必然是亮點。&lt;/p&gt;
&lt;p&gt;猶記 2016 年擔任軟體工程師面試官時，看著其中某一份履歷，我寫下如此感觸：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;收到一份履歷，他在某接案公司待了 &lt;em&gt;N&lt;/em&gt; 年。&lt;/p&gt;
&lt;p&gt;很可惜。在我眼中，這只值兩年呀。&lt;/p&gt;
&lt;p&gt;對接案公司無不敬之意。但是，字裡行間，實在看不出反駁我對他「只有兩年的工作經驗，只不過重複了 &lt;em&gt;N&lt;/em&gt; 年」認知錯誤的理由。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其實，多年以來，每一段面試高峰期都會出現同樣的觀察與感觸——看不出求職者的亮點，尤其是與職務相關的亮點，遑論職涯層次的亮點。&lt;/p&gt;
&lt;p&gt;書面的履歷表也就罷了。更麻煩的是，怕誤判，約來面試，試著口頭引導一下，都不見得引導得出來。&lt;/p&gt;
&lt;p&gt;面試官當下的任務，是替用人單位選才，而不是當應徵者的職涯諮詢者。&lt;/p&gt;
&lt;p&gt;請自己先正確表述你的亮點，而不是徒留年資流水帳。&lt;/p&gt;
&lt;h2 id=&#34;成長性&#34;&gt;成長性&lt;/h2&gt;
&lt;p&gt;不同企業、不同職種，側重的亮點或許不盡相同。&lt;/p&gt;
&lt;p&gt;在我所處的軟體研發領域，「成長性」是非常重要的。除非某職缺有立即上戰場的急迫性，否則，我會側重在求職者的成長性，包括硬技能成長性及軟技能成長性；有時候，成長性甚至會重於即戰力。&lt;/p&gt;
&lt;p&gt;什麼樣的成長性才稱得上是亮點？&lt;/p&gt;
&lt;p&gt;且讓我套用裘凱宇老師在【&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;過好人生學&lt;/a&gt;】課程所講的「&lt;a href=&#34;https://youtu.be/-EHOn0UxMys&#34;&gt;站位／靶位&lt;/a&gt;」概念來分析：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;固定站位：在單一領域，發展到學徒、創造、達人的哪一個階段？&lt;/li&gt;
&lt;li&gt;固定靶位：在單一領域，持續創造了什麼成果？&lt;/li&gt;
&lt;li&gt;固定站位，不固定靶位：多元發展&lt;/li&gt;
&lt;li&gt;不固定站位，固定靶位：跨界創意&lt;/li&gt;
&lt;li&gt;不固定站位，不固定靶位：多元發展 ＋ 跨界創意&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;站位／靶位的固定與否，是個人的主觀選擇（或被動的被選擇）；不過，不管是屬於哪一種排列組合，請試著客觀回顧履歷一遍，能否據以勾勒出某些清晰的移動路徑？&lt;/p&gt;
&lt;p&gt;成長性，從這路徑就看得出來了。&lt;/p&gt;
&lt;p&gt;你，是一直在打怪升級成長 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，是在死守四行倉庫，還是&lt;a href=&#34;https://www.darencademy.com/article/view/id/15393&#34;&gt;在宇宙漂流&lt;/a&gt;？&lt;/p&gt;
&lt;h2 id=&#34;敏銳於遊戲規則&#34;&gt;敏銳於遊戲規則&lt;/h2&gt;
&lt;p&gt;履歷，畢竟是對既有產品（「個人」）既成事實的推銷；說句老實話，不免有為時已晚的風險。更可靠的，應該是在走到這田地之前，就下意識讓自己在站位／靶位兩方面都逐漸成長。&lt;/p&gt;
&lt;p&gt;成長，不是臨時抱佛腳一蹴可幾，更不是刻舟求劍緣木求魚。&lt;/p&gt;
&lt;p&gt;成長，需要敏銳於職場的遊戲規則。&lt;/p&gt;
&lt;p&gt;其一：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其實，每一個位子都有可能發光發熱，重點仍在於是否有自覺進行「&lt;strong&gt;換位思考&lt;/strong&gt;」及「&lt;strong&gt;系統思考&lt;/strong&gt;」。&lt;/p&gt;
&lt;p&gt;有自覺，你的一年工作經驗，就有別人 &lt;em&gt;N&lt;/em&gt; 年的價值；反之，你的 &lt;em&gt;N&lt;/em&gt; 年工作經驗，就只有一年的價值。&lt;/p&gt;
&lt;p&gt;   &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/766813695070449664&#34;&gt;2016-08-20 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其二：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不是在大公司就一定學得深，不是在新創就一定學得廣。&lt;/p&gt;
&lt;p&gt;重點仍在於自己。在於「自己有沒有系統思考及換位思考的自覺及行動」。&lt;/p&gt;
&lt;p&gt;在於&lt;strong&gt;專業態度&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;「專業技能」固然重要，但是，能夠讓自己從流水帳的制式履歷表欄位中脫穎而出的，終究是「專業態度」。很準。只要針對每一份履歷表，個別客製化追問一兩次，幾乎就能分辨出哪些人有下意識追求「專業態度」的成長。&lt;/p&gt;
&lt;p&gt;&amp;mdash; Quote: 〈&lt;a href=&#34;//william-yeh.net/post/2016/07/professional-attitude/&#34;&gt;專業態度的養成&lt;/a&gt;〉&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其三：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;許多事情，跟你身在大公司還是小公司是低度相關的。&lt;strong&gt;心智框架&lt;/strong&gt;，是要靠自己主動觀察、取經、思考的。&lt;/p&gt;
&lt;p&gt;   &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/765158230364344320&#34;&gt;2016-08-15 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;成長，是下意識的選擇，是用持續的意志去磨銳遊戲規則的基本功：換位思考、系統思考、專業態度、心智框架。&lt;/p&gt;
&lt;h2 id=&#34;求人找亮點&#34;&gt;求人找亮點？&lt;/h2&gt;
&lt;p&gt;大環境長期低薪，促使許多人尋求更多元的選項。就連「副業」這個老詞彙，居然也孳生「斜槓」這個聽起來更新潮、也更容易炒作的詞彙。職涯、生涯的重定位，一時之間蔚為風潮。&lt;/p&gt;
&lt;p&gt;是真需求也好，是炒作起來的需求也好，有需求，就有供給。於是乎，坊間有了《&lt;a href=&#34;https://www.books.com.tw/products/0010733134&#34;&gt;做自己的生命設計師&lt;/a&gt;》這樣的書，有了所謂【設計你的人生】工作坊，甚至像 S 姐在〈&lt;a href=&#34;https://betweengos.com/career-job-development-transformation/&#34;&gt;默默的，你認知的這些工作都已轉型&lt;/a&gt;〉所說，開始有了 &amp;ldquo;career coach&amp;rdquo; 這樣的新興職業。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;打著 &amp;ldquo;career coach&amp;rdquo; 名號的，在這一兩年，真的如雨後春筍（尤其是在 FB &amp;amp; LinkedIn）。&lt;/p&gt;
&lt;p&gt;多試試，無妨；但，請慎選建議。畢竟，自稱 &amp;ldquo;coach&amp;rdquo; 者，並不總是 coach。&lt;/p&gt;
&lt;h2 id=&#34;正派的推薦&#34;&gt;正派的推薦&lt;/h2&gt;
&lt;p&gt;其實我真的很鼓勵求職者，在丟出履歷、赴約面試之前，先讀讀一些正派的相關書籍，或尋求正派的諮詢者。畢竟，不是每位面試官都想在緊湊的當下順便兼任求職諮詢。&lt;/p&gt;
&lt;p&gt;面試官很累的，別奢想他們都是&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%8D%9E%E5%92%8C&#34;&gt;卞和&lt;/a&gt;。請自己打磨出你的亮點。&lt;/p&gt;
&lt;p&gt;四處征戰的應徵者也是很累的，我知道。所以，請不要奢想你是當下就能七步成詩感動天地的&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E6%9B%B9%E6%A4%8D&#34;&gt;曹植&lt;/a&gt;，請事先就打磨出你的亮點。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;之所以會強調「正派」二字，是因為⋯⋯在某些書上看到一些耍小聰明的招數。說實在的，那些小聰明，請不要秀出來～～&lt;/p&gt;
&lt;h3 id=&#34;書籍&#34;&gt;書籍&lt;/h3&gt;
&lt;p&gt;推薦這幾本正派的書。不管是身為面試者還是被面試者，我都從中獲得許多啟發：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010779401&#34;&gt;但願你因工作而閃亮&lt;/a&gt;》&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010843696&#34;&gt;2030 轉職地圖&lt;/a&gt;》&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;《&lt;a href=&#34;http://www.books.com.tw/products/0010641668&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;》&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;《&lt;a href=&#34;http://www.books.com.tw/products/0010733434&#34;&gt;工作愈換愈好，得有這些本事&lt;/a&gt;》&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;《&lt;a href=&#34;http://www.books.com.tw/products/0010446102&#34;&gt;轉職必勝班&lt;/a&gt;》&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;對外商或國際化環境感興趣的，除了《&lt;a href=&#34;https://www.books.com.tw/products/0010843696&#34;&gt;2030 轉職地圖&lt;/a&gt;》之外，可再參考以下這本：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010834465&#34;&gt;外商、大企業求職秘笈&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至於暗黑一點的，就不公開列了。&lt;/p&gt;
&lt;h3 id=&#34;實體課程&#34;&gt;實體課程&lt;/h3&gt;
&lt;p&gt;［Disclaimer］以下列的課程，我都沒上過，也沒拿工商服務費，我的信心，純粹根據他們過往發表極有洞見的內容而來。請自行判斷察驗。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;大人學：&lt;a href=&#34;https://shop.darencademy.com/product/view/id/30&#34;&gt;A103 / 履歷優化與個人品牌重塑&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;獵頭的日常 (Lynn)：&lt;a href=&#34;https://lihi1.com/qFb72/0105fbpost&#34;&gt;完備你的履歷轉職力&lt;/a&gt;、&lt;a href=&#34;https://lihi1.com/sEKiE/0105fbpost&#34;&gt;提升你的面試潛勝率&lt;/a&gt;、&lt;a href=&#34;https://lihi1.com/9sGg6/0105fbpost&#34;&gt;專屬你的優勢說明書&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至於暗黑一點的，就不公開列了。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;詳見〈&lt;a href=&#34;//william-yeh.net/post/2019/12/tech-interview/&#34;&gt;技術面試的小觀點&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;詳見〈&lt;a href=&#34;//william-yeh.net/post/2016/12/game-frame/&#34;&gt;打怪升級路線圖&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;獵頭 S 姐甚至說：「有點沮喪，因為 LinkedIn 都找得到以下這些位置，但在 104 卻用手指頭算得出來，但為什麼大家還是要瘋狂依賴 104？」&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>2019 個人回顧</title>
      <link>//william-yeh.net/post/2019/12/2019-retrospective/</link>
      <pubDate>Thu, 26 Dec 2019 23:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/12/2019-retrospective/</guid>
      
        <description>&lt;p&gt;年初，告別服務五年的單位，走出舒適圈，歸零，重啟。&lt;/p&gt;
&lt;p&gt;如果說 &lt;a href=&#34;//william-yeh.net/post/2018/12/2018-retrospective/&#34;&gt;2018&lt;/a&gt; 是收攝靜觀的一年，那麼，2019 可謂驚滔駭浪了。做對了一些事，也犯下許多蠢事。&lt;/p&gt;
&lt;p&gt;到了年終，又開始要做個總回顧，再對來年許願。去除一些不便揭露的事情，以下是簡單的回顧。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/ippo.jpg&#34; alt=&#34;鷹村對幕之內畫的那條線，我要踏過去了。&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/ippo.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;鷹村對幕之內畫的那條線，我要踏過去了。&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;補血課程&#34;&gt;補血課程&lt;/h2&gt;
&lt;p&gt;這一年，由於時間問題，參加的補血課程大幅減少。只能精選再精選。&lt;/p&gt;
&lt;p&gt;實體課程中，收穫最大的，就屬這場暌違多年經典課程的復刻版：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://shop.darencademy.com/product/view/id/78&#34;&gt;201a / 專案管理個案實戰 - 利害關係人與需求管理&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;若要用一句話來描述它，我會說，這是一門&lt;strong&gt;回歸本質&lt;/strong&gt;的課。畢竟，專案的起點，就是&lt;strong&gt;目標&lt;/strong&gt;與&lt;strong&gt;限制&lt;/strong&gt;；而左右目標與限制的最大因素，就是&lt;strong&gt;利害關係人&lt;/strong&gt;與&lt;strong&gt;需求管理&lt;/strong&gt;。擒賊不擒王，後續的種種規劃執行手法只是徒然在失焦的漩渦中打轉。&lt;/p&gt;
&lt;p&gt;個案攻防一如往常的燒腦，彷彿把過去幾年幾門課的核心都橫向統整了一輪：&lt;a href=&#34;https://shop.darencademy.com/product/view/id/1&#34;&gt;101&lt;/a&gt;、&lt;a href=&#34;https://shop.darencademy.com/product/view/id/28&#34;&gt;A101&lt;/a&gt;、&lt;a href=&#34;https://shop.darencademy.com/product/view/id/13&#34;&gt;302&lt;/a&gt;、&lt;a href=&#34;https://shop.darencademy.com/product/view/id/70&#34;&gt;510&lt;/a&gt;⋯⋯覆盤檢討，照見許多這陣子刻意練習，但還沒到位之處。&lt;/p&gt;
&lt;p&gt;充電，重新得到力量。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/201a.jpg&#34; alt=&#34;201a / 利害關係人與需求管理&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/201a.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;201a / 利害關係人與需求管理&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;除了實體課程，我也嘗試了一些線上課程。不過，截至目前為止，真正 100% 完課，且不時還會回頭複習的，就只有裘凱宇老師的這門課：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;【過好人生學】除了熱情，你更需要知道的事&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;裘凱宇老師主辦的實體講座我參加過幾次了，也有幾本他的書，對他開的線上課程，我是充滿信心的。&lt;a href=&#34;https://youtu.be/-EHOn0UxMys&#34;&gt;試聽&lt;/a&gt; 30 分鐘，很快就決定參加。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/-EHOn0UxMys?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;難得有這一系列我不忍心 1.25 倍速快轉的中文音頻。在通勤的捷運車廂，裘老師溫暖療癒的嗓音，猶如及時雨，撫慰了我徬徨的心。&lt;/p&gt;
&lt;p&gt;隨著課程進行，我開始正視自己三個老毛病：熱情症候群、堅持妄想症、理想偏執狂，更老老實實照著課程練習，重新扎根四個關鍵能力：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;創造結果&lt;/strong&gt;的能力：聚焦、優化、反饋&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;建立生態圈&lt;/strong&gt;的能力：學徒、創造、達人&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;做決定&lt;/strong&gt;的能力：期望值、預想最差結果、正確歸因、時間軸思考&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;創造意義&lt;/strong&gt;的能力：解決問題、迎向挑戰、投入行動&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;將近 4 小時的線上音頻課程，猶如一場觀念重塑之旅，對職場生涯本質再一次深思與探索，對我幫助極大。&lt;/p&gt;
&lt;h2 id=&#34;脫敏&#34;&gt;脫敏&lt;/h2&gt;
&lt;p&gt;2019 年，到了一間素有敏捷標竿之名的外商。&lt;/p&gt;
&lt;p&gt;首當其衝的難關，不是敏捷文化，是商務英語。&lt;/p&gt;
&lt;p&gt;聽與說，向來是我的罩門。尤其是遠距 con-call，通訊品質變數叢生，少了現場白板輔助，純以赤裸裸的聽力應付南腔北調，令人不寒而慄。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.linkedin.com/in/jill-chang-89753817/&#34;&gt;張瀞仁 (Jill)&lt;/a&gt; 在《&lt;a href=&#34;https://www.books.com.tw/products/0010794006&#34;&gt;安靜是種超能力&lt;/a&gt;》提到：內向者的&lt;strong&gt;能量&lt;/strong&gt;較易耗盡，需要妥善管理能量。我則是有另一番新體悟：與外國人隔空對話，也是很耗能量的～～～&lt;/p&gt;
&lt;p&gt;能量，要如何保護？&lt;/p&gt;
&lt;p&gt;我從 Jill 書中看到 &amp;ldquo;&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E7%B3%BB%E7%BB%9F%E8%84%B1%E6%95%8F%E6%B3%95&#34;&gt;desensitization&lt;/a&gt;&amp;rdquo; 這個看起來很管用的點子：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;脫敏&lt;/strong&gt;是不斷地讓自己暴露在恐懼的事物前，讓大腦中的杏仁核逐漸降低敏感度（譬如讓有懼高症的人常常爬高梯），當然，過程中必須仔細控制恐懼程度。或許光用想的就很可怕，但只要跨出第一步，其他就會漸漸好轉。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我得盡快尋找具體的方法，脫敏自己對於 con-call in English 的恐懼；而且，要先聚焦，精準地脫敏對於技術領域商務英語的 con-call 恐懼。&lt;/p&gt;
&lt;p&gt;首先，鎖定這四本核心教材：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clare: 《&lt;a href=&#34;https://www.books.com.tw/products/0010635304&#34;&gt;商務英語的祕密&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;Clare: 《&lt;a href=&#34;https://www.books.com.tw/products/0010747532&#34;&gt;商務英文大解密&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;Quentin Brand: 《&lt;a href=&#34;http://www.betamedia.com.tw/book.aspx?no=1707&amp;amp;bno=8130&#34;&gt;愈忙愈要學 100 個商業動詞&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;Quentin Brand: 《&lt;a href=&#34;http://www.betamedia.com.tw/book.aspx?no=1704&amp;amp;bno=8144&#34;&gt;愈忙愈要學英文：大家開會說英文&lt;/a&gt;》&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;尤其是 &lt;a href=&#34;http://clarehsu0724.blogspot.com/&#34;&gt;Clare&lt;/a&gt; 介紹的&lt;a href=&#34;http://clarehsu0724.blogspot.com/p/blog-page_1930.html&#34;&gt;綜效式商英學習法&lt;/a&gt;及&lt;a href=&#34;http://clarehsu0724.blogspot.com/p/blog-page_23.html&#34;&gt;自學商英教材&lt;/a&gt;，乍看之下很蠢，就是傻傻的跟述 (&lt;strong&gt;shadow&lt;/strong&gt;)、朗誦 (&lt;strong&gt;recite&lt;/strong&gt;)、聽寫 (&lt;strong&gt;dictate&lt;/strong&gt;)。&lt;/p&gt;
&lt;p&gt;這方法，十幾年前張嘉倩的書有講，郭岱宗的書有講，現在 Clare 的書還是這麼講。而且這方法也非常吻合裘凱宇老師【&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;過好人生學&lt;/a&gt;】課程所講的「建立學習反饋機制」要點：小時段、小行為、小實驗、小挑戰。&lt;/p&gt;
&lt;p&gt;似拙，實巧。&lt;/p&gt;
&lt;p&gt;這麼多人都這麼講了。十年前，我當耳邊風；我再不照著做，再過十年，還是會怨嘆一直原地踏步。傻得願意相信，就對了。&lt;/p&gt;
&lt;p&gt;於是，我就這樣老老實實地進行英聽特訓。光是第一周，就感受到在「脫敏」方面有一點效果，大受鼓舞。&lt;/p&gt;
&lt;p&gt;要持續下去。&lt;/p&gt;
&lt;h2 id=&#34;回歸基本功&#34;&gt;回歸基本功&lt;/h2&gt;
&lt;p&gt;在外商，異國異地 con-call 開會，已經是一種低情境的溝通了 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，使用英語，更是嚴重限縮表達力的頻寬。低情境、低頻寬，顛覆我多年的認知。&lt;/p&gt;
&lt;p&gt;簡報尤然。我過去慣常的簡報模式，高度仰賴口語埋哏與鋪陳，快慢交錯的視覺節奏更是拿手好戲。可惜的是，以現在自己的英語口語程度，其實很難支撐得起駕馭得了這種簡報風格。&lt;/p&gt;
&lt;p&gt;記得自己簡報風格的轉變關鍵，第一是&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E9%AB%98%E6%A9%8B%E6%B5%81%E7%B0%A1%E5%A0%B1%E6%B3%95&#34;&gt;高橋流&lt;/a&gt;，第二是 &lt;a href=&#34;https://prezi.com/&#34;&gt;Prezi&lt;/a&gt;，第三是 &lt;a href=&#34;https://en.wikipedia.org/wiki/Keynote_%28presentation_software%29&#34;&gt;Keynote&lt;/a&gt;。現在，好像遇到第四個轉捩點了。投影片好像應該要更瘦身、更樸素才是⋯⋯&lt;/p&gt;
&lt;p&gt;我更發現，為了突破低情境低頻寬的禁錮，不只簡報風格，不只溝通風格，甚至連更基本的職場思維也要轉變。套句裘凱宇老師【&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;過好人生學&lt;/a&gt;】課程所講的，我需要踏實走一次「學徒」階段。我得盡快尋得具體的方法，從頭練習職場基本功——我需要學習在低情境、低頻寬處境下更簡潔、更高效的風格，還得具有某種跨文化的通用性。&lt;/p&gt;
&lt;p&gt;最後，我鎖定這兩本，重新蹲馬步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;功夫老師：《&lt;a href=&#34;https://www.books.com.tw/products/0010681486&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010811943&#34;&gt;埃森哲顧問教你６堂回報的話術&lt;/a&gt;》&lt;/li&gt;
&lt;/ol&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/job-basics.jpg&#34; alt=&#34;蹲馬步的書：職場基本功&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/job-basics.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;蹲馬步的書：職場基本功&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;不要被狀似聳動的書名騙了。這兩本書作者都有管顧背景，內容扎實，且相呼應之處甚多。讀到後來，發現，這不僅是話術，更是&lt;strong&gt;職場思考&lt;/strong&gt;的基本功。&lt;/p&gt;
&lt;p&gt;譬如說，《&lt;a href=&#34;https://www.books.com.tw/products/0010681486&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》介紹的「一分鐘口頭報告」要點，就跟《&lt;a href=&#34;https://www.books.com.tw/products/0010811943&#34;&gt;埃森哲顧問教你６堂回報的話術&lt;/a&gt;》介紹的「自我主導說明」形式非常相似。既然英雄所見略同，原理沒問題，就老老實實照著功夫老師交代的方式來做：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;接下來便是要勤於練習並運用。你可以將「一分鐘工作進度口頭報告表」和「一分鐘問題現況口頭報告表」兩個表格列印出來隨身攜帶，未來要向主管報告前，依表格中的方式和提醒進行思考，在一分鐘內精準又明快的做好口頭報告。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;有時我也會切換成英文來練習：特地從商英教父 Quentin Brand 幾本書尋找對應的罐頭 set phrases，偷學一些得體的應對方法。&lt;/p&gt;
&lt;p&gt;如此刻意練習幾個月。沒有 mentor/coach 在側，自承進步緩慢，卻已經開始敏銳看到許多反例的問題。值此，不禁想起《神雕俠侶》中甫遭斷臂之禍，卻別有一番奇遇的楊過：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如此練劍數日，楊過提著重劍時手上已不如先前沉重，擊刺揮掠，漸感得心應手。同時越來越覺以前所學劍術變化太繁，花巧太多，想到獨孤求敗在青石上所留「&lt;strong&gt;重劍無鋒，大巧不工&lt;/strong&gt;」八字，其中境界，遠勝世上諸般最巧妙的劍招。他一面和神雕搏擊，一面凝思劍招的去勢回路，但覺越是平平無奇的劍招，對方越難抗禦。比如挺劍直刺，只要勁力強猛，威力遠比玉女劍法等變幻奇妙的劍招更大。&lt;/p&gt;
&lt;p&gt;當晚他竟不安睡，在水中悟得了許多順刺、逆擊、橫削、倒劈的劍理，到這時方始大悟，以此使劍，真是無堅不摧，劍上何必有鋒？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;是的，「重劍無鋒，大巧不工」。&lt;/p&gt;
&lt;h2 id=&#34;本質練習&#34;&gt;本質練習&lt;/h2&gt;
&lt;p&gt;楊過有神雕幫忙練劍，我沒有。只好私底下設計一些練劍方法與儀式。&lt;/p&gt;
&lt;p&gt;譬如說，《&lt;a href=&#34;https://www.books.com.tw/products/0010811943&#34;&gt;埃森哲顧問教你６堂回報的話術&lt;/a&gt;》提出兩則思考要點：&lt;strong&gt;具體化&lt;/strong&gt; (&lt;strong&gt;crystallize&lt;/strong&gt;) 及&lt;strong&gt;概述&lt;/strong&gt; (&lt;strong&gt;summarize&lt;/strong&gt;)。拿我熟悉的議題小試須臾，驚覺：我以為我知道，但其實我不知道。&lt;/p&gt;
&lt;p&gt;該向幾年前的自己看齊，重拾學徒之心，對這些我以為我知道的東西從頭演繹一番。&lt;/p&gt;
&lt;p&gt;因此，我在筆記軟體開設【本質練習】專區，不敢說每天，但至少常常拿來重整精煉自己所知的事物。譬如說，以下是我對某些 agile/devops/arch 議題的私房詮釋（這只是截至目前的版本）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Agile 本質簡述：一種以高速、高頻率 PDCA 循環的角度，處理複雜問題的態度及方法。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cloud native 本質簡述：An architectural style designed around elasticity and anti-fragility in a massive dynamic environment.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Container 本質簡述：一種將 異質性 應用程式 &amp;amp; 相依執行環境 予以統一封裝 的高效率單位與機制 (An efficient packaging unit and mechanism for heterogeneous apps and dependent environment)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DevOps 本質簡述：Engineering practices &amp;amp; culture to glue dev &amp;amp; ops to evolve a high performing team.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes 本質簡述：大規模 微服務容器 自動化調度 的產業標準平臺 (An industry standard platform for orchestrating containerized microservices at scale)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Microservices 本質簡述：「單一職責介面」與「去中心化」的架構設計風格 (An architecture style based on SRP interface and decentralization)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scrum 本質簡述：一種經驗主義式的敏捷實踐流程，擅長高強度操練經驗曲線 (An agile process based on empiricism to train experience curve in a high-intensity style)。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我也常常用心智圖來鋪陳這些具體化的本質概述。近來更體會到，以前一直把心智圖用錯了——心智圖，不是拿來讀的，是拿來畫的。&lt;/p&gt;
&lt;p&gt;如此練劍數月，體會到難以言喻的好處。這種本質修練，應該會一直持續下去吧。&lt;/p&gt;
&lt;h2 id=&#34;敏捷基本功&#34;&gt;敏捷基本功&lt;/h2&gt;
&lt;p&gt;手持玄鐵重劍，為之四顧，躊躇滿志，忍不住對所見所聞臧否巷議。&lt;/p&gt;
&lt;p&gt;譬如說，看到一些敏捷心靈雞湯文章說要換位思考、要 QBQ，就忍不住提出修正觀點：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;QBQ 和同理心，誤用，或是無限上綱使用，很容易被歸為資方的洗腦工具。&lt;/p&gt;
&lt;p&gt;越來越覺得，欠缺 QBQ，不全然是當事人自己不正面思考、不當責的問題，常常也是結構面造成的。譬如：&lt;a href=&#34;//william-yeh.net/post/2019/01/scrum-good-to-great/#heading4&#34;&gt;刺蝟原則&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;沒有刺蝟原則，就很難要求 ownership，也就更難要求 QBQ 或同理心。所以，一路溯源，就跟管理界的老生常談搭上線了。&lt;/p&gt;
&lt;p&gt;現在，我逐漸傾向：怪罪敏捷之前，先反思：是不是連核心的管理與領導思路都歪掉了呢？或許，那才是基本功呀。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;譬如說，看到君婷老師〈&lt;a href=&#34;https://www.projectup.net/article/view/id/16580&#34;&gt;為什麼團隊總是對目標無感？&lt;/a&gt;〉一文提到：「你的團隊有多麼目標導向，取決於你有多強大的讓團隊精準&lt;strong&gt;理解並聚焦目標&lt;/strong&gt;能力，這需要練習，更需要準備。」就忍不住附和：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這，真的是談 KPI 或更潮的 OKR 之前，就該先磨練的基本功。&lt;/p&gt;
&lt;p&gt;基本功沒到位，空談許多炫酷潮詞，是枉然的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;譬如說，看到君婷老師〈&lt;a href=&#34;https://www.projectup.net/article/view/id/16587&#34;&gt;到底是誰殺了敏捷？&lt;/a&gt;〉一文提到：「相信組織在導入敏捷前，一定花了許多時間與精力說服老闆、克服文化、組織重建、團隊成熟度的問題，但開始正式 run 敏捷之後，卻忘了最重要的&lt;strong&gt;利害關係人&lt;/strong&gt;，其心中最要緊的&lt;strong&gt;價值&lt;/strong&gt;。」又忍不住附和：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;熊熊想到去年發表的那張&lt;a href=&#34;https://www.slideshare.net/williamyeh/agile-transition-a-toc-perspective&#34;&gt;敏捷導入 CLD&lt;/a&gt; &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;起手式，很重要。看懂局與勢，很重要。&lt;/p&gt;
&lt;p&gt;多多回到基本原理，勤練基本功吧。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;什麼是敏捷的起手式？&lt;/p&gt;
&lt;p&gt;像前面擷取的三段短評，其實說穿了，就是老掉牙的 5W1H 當中的 Why + What + Who，就是本篇年度回顧文章一開頭提到的&lt;strong&gt;目標&lt;/strong&gt;與&lt;strong&gt;利害關係人&lt;/strong&gt;兩大要素，敏捷圈甚至早已發展出慣用的 impact mapping 引導手法呢（所以，我的招牌課程【敏捷原理與團隊塑造】第一天下午就是以 impact mapping 進行個案研討）。你，在敏捷鳴槍起跑前，有整個團隊跑過一輪 impact mapping 來對焦嗎？&lt;/p&gt;
&lt;p&gt;起手式，很重要。&lt;/p&gt;
&lt;p&gt;像這樣在研討會、在社群聚會、在網路採集田野故事，匪夷所思的「敏捷怪現狀」屢見不鮮，卻也多半都能夠以根本原理來解釋。&lt;/p&gt;
&lt;p&gt;根本原理，不會因為是老掉牙的老調而不再重要。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;（速成班不會講的事）&lt;/p&gt;
&lt;p&gt;敏捷失敗，有人怪罪沒有全部跑過規定的 4(+1) 會議，有人怪罪 top down 導入，有人怪罪 bottom up 導入，有人怪罪插單太多，有人怪罪沒有專職 Scrum master，有人怪罪顧問只會嘴砲，有人怪罪文化劣根性或國情不合⋯⋯&lt;/p&gt;
&lt;p&gt;真可謂「幸福的敏捷都是相似的，不幸的敏捷則各有各的不幸」呀！&lt;/p&gt;
&lt;p&gt;儘管 Scrum 不見得才是最好最適的，但是，田野觀察到業界對於 Scrum 誤解之深，就覺得 Scrum 被玩爛被汙名化，良有已也。&lt;/p&gt;
&lt;p&gt;形式與本質都歪得很嚴重。更慘的是，在「守」的階段，賴以捍衛形式與本質的 Scrum master，依然是稀缺資源。&lt;/p&gt;
&lt;p&gt;我置身一間素有敏捷標竿之名的外商，得以就近觀察某個新人過半的新產品團隊。我發現，即使有極為優秀的 Scrum master 近乎全程坐鎮，都還需要好幾個 sprints 才看到內化的持續改善跡象，委實難以想像沒有正知見坐鎮的 Scrum，會歪樓到什麼地步。&lt;/p&gt;
&lt;p&gt;（守、破、離）&lt;/p&gt;
&lt;p&gt;很慶幸自己走過了那些迷惘掙扎期。&lt;/p&gt;
&lt;p&gt;試著回到單純的根本原理吧。網路上、文獻上到處都可以找到一些正派的根本原理：&lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;Agile Manifesto&lt;/a&gt;、&lt;a href=&#34;https://scrumguides.org/scrum-guide.html#theory&#34;&gt;Scrum 3 pillars&lt;/a&gt;、&lt;a href=&#34;https://www.scrum.org/resources/blog/5-scrum-values-take-center-stage&#34;&gt;Scrum 5 values&lt;/a&gt;、&lt;a href=&#34;http://modernagile.org/&#34;&gt;Modern Agile&lt;/a&gt;、&lt;a href=&#34;https://less.works/less/principles/systems-thinking.html&#34;&gt;systems thinking&lt;/a&gt;&amp;hellip; 請從任何一組根本原理來審視你們的工作，誠實地。&lt;/p&gt;
&lt;p&gt;撇開會議、流程、看板、便利貼、組織、角色等外在形式，回到根本原理，會發現，很多原理是相通的。很多基本原理或基本功，若不扎實，再多新潮的技法，也只是浮沙築高塔。&lt;/p&gt;
&lt;p&gt;請撇開外在形式，先拿【&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;過好人生學&lt;/a&gt;】課程所講的兩種「優化」思維來重新審視你敏捷之旅的本質吧——洞與痛、笨問題法則：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;洞：你的敏捷之旅，是為了獲得什麼利益？&lt;/li&gt;
&lt;li&gt;痛：你的敏捷之旅，是為了解除什麼痛苦？&lt;/li&gt;
&lt;li&gt;笨問題法則：為什麼一定得如此？如果不這麼做，會怎麼樣？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;「有不得機得勢處，其病必於腰腿求之。」&lt;/p&gt;
&lt;h2 id=&#34;技術基本功&#34;&gt;技術基本功&lt;/h2&gt;
&lt;p&gt;在敏捷成熟度低的地方，挑戰的是變革管理能力。反之，則是基本功的扎實程度。&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/scrum-master-focus-over-time.png&#34; alt=&#34;Scrum Master focus over time (from LeSS)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/scrum-master-focus-over-time.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Scrum Master focus over time (from LeSS)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;2019 年，於公於私，我個人的技術主場都是 &lt;a href=&#34;https://kubernetes.io/&#34;&gt;Kubernetes&lt;/a&gt;。追逐 K8s 最新進展，降低 K8s 導入門檻，實驗 K8s 詭譎之處，寫了幾篇文章，帶了幾場 K8s 工作坊 &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;，給了幾場演講⋯⋯可說一整年都在與 K8s 為伍。&lt;/p&gt;
&lt;p&gt;熱鬧的外在，內在卻開始感到某種空虛與不安。&lt;/p&gt;
&lt;p&gt;K8s，固然是在 DevOps 與 cloud native 相關領域集其大成的霸主，站在巨人肩膀上，乍看之下可增加一甲子功力。不過，讓我們誠實一點吧：你的功力，真的因此而徒增一甲子了嗎？&lt;/p&gt;
&lt;p&gt;譬如說，K8s 發明人之一 &lt;a href=&#34;https://www.linkedin.com/in/brendan-burns-487aa590/&#34;&gt;Brendan Burns&lt;/a&gt; 寫了一本有趣的小書《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789865020774&#34;&gt;分散式系統設計：可擴展、可靠服務的樣式和範例&lt;/a&gt;》，大量運用 K8s 示範現代分散式系統中重要的泛用模式，是非常精要的 K8s 應用指南。那麼，試問：K8s 用了好一陣子的你，能夠像 Brendan Burns 這樣在 cloud native 領域將 K8s 揮灑自如嗎？&lt;/p&gt;
&lt;p&gt;如果不能，那麼，問題出在哪裡呢？&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/piano.jpg&#34; alt=&#34;外行與內行的差別 (from 琴之森 Vol 16)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/piano.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;外行與內行的差別 (from 琴之森 Vol 16)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;雖然我們常說：不要重複造輪子，但這並不代表，我們連造輪子的能力都不去操練。&lt;/p&gt;
&lt;p&gt;與其一直沈迷於熱鬧的 DevOps toolchains，不如回頭重新蹲馬步，回歸扎實的技術本質。&lt;/p&gt;
&lt;p&gt;「重劍無鋒，大巧不工。」&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:40em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/arch-books.jpg&#34; alt=&#34;蹲馬步的書：軟體架構&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/arch-books.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;蹲馬步的書：軟體架構&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;似乎不只我有這種想法。我在這次 &lt;a href=&#34;https://ithelp.ithome.com.tw/2020ironman/reward&#34;&gt;iT 邦幫忙鐵人賽&lt;/a&gt;評審感言中寫下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這一屆鐵人賽，我提出一則令人欣喜的整體觀察：更多人開始回歸基本功。像〈&lt;a href=&#34;https://ithelp.ithome.com.tw/users/20089358/ironman/2559&#34;&gt;從 0 至 1 盡可能的建立一個好的系統&lt;/a&gt;〉、〈&lt;a href=&#34;https://ithelp.ithome.com.tw/users/20121042/ironman/2792&#34;&gt;在分散的世界中保持一致&lt;/a&gt;〉、〈&lt;a href=&#34;https://ithelp.ithome.com.tw/users/20111997/ironman/2730&#34;&gt;Think in Domain-Driven Design&lt;/a&gt;〉這三篇得獎作品，都是值得好好學習的架構設計教材，連我都從中獲益甚多。&lt;/p&gt;
&lt;p&gt;我期待大家在研讀這些精彩作品時，也請試著和他們一樣回歸基本功。每讀懂一個小議題，請自己試著重現作者的思路，自行推導，自行寫程式印證，把基本功重新磨練一次。&lt;/p&gt;
&lt;p&gt;這樣子，才不辜負這些作者嘔心瀝血隔空授藝與傳功呀！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;洋洋灑灑一堆蹲馬步的書，份量沉重，將是我 2020 的功課。套句裘凱宇老師【&lt;a href=&#34;https://www.koob.com.tw/online/A579F23266cCC488Caa7&#34;&gt;過好人生學&lt;/a&gt;】課程所講的，重新扎根在這領域「建立生態圈的能力」。&lt;/p&gt;
&lt;h2 id=&#34;信仰基本功&#34;&gt;信仰基本功&lt;/h2&gt;
&lt;p&gt;再來是私領域了。&lt;/p&gt;
&lt;p&gt;2019 下半年，經歷了許多實質意義與象徵意義的生老病死，彷彿度過了好幾年。&lt;/p&gt;
&lt;p&gt;不過，卻也豐豐富富經歷到我所信的神是真的。&lt;/p&gt;
&lt;p&gt;藉著重新修練禱告的功課，帶領我走出曠野。一幕幕猶如連續劇的異象，橫跨數月，令人讚嘆與敬畏。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:15em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/pray-books.jpg&#34; alt=&#34;蹲馬步的書：禱告&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/pray-books.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;蹲馬步的書：禱告&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;在禱告中，一句句經文，猶如活水，湧流不已：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;以別神代替耶和華的，他們的愁苦必加增。(&lt;a href=&#34;https://cnbible.com/psalms/16-4.htm&#34;&gt;詩 16:4&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我們的大祭司並不是不能同情我們的軟弱。(&lt;a href=&#34;https://cnbible.com/hebrews/4-15.htm&#34;&gt;希 4:15&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你們看天空的飛鳥：牠們不撒種，不收割，也不收進倉裡，你們的天父尚且養活牠們；難道你們不比牠們更寶貴嗎？所以不要憂慮，說：「我們該吃甚麼？喝甚麼？穿甚麼？」這些都是教外人所尋求的，你們的天父原知道你們需要這一切。你們要先求他的國和他的義，這一切都必加給你們。所以不要為明天憂慮，因為明天自有明天的憂慮，一天的難處一天當就夠了。 (&lt;a href=&#34;https://cnbible.com/matthew/6-26.htm&#34;&gt;馬 6:26&lt;/a&gt;, 31-34)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這種屬靈經驗，得親身經歷；一旦親身經歷，就再也回不去了。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/religion-growth.jpg&#34; alt=&#34;「不論你信主的時間有多久，都應感受到被更新、改變、鼓舞和激勵。」&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/religion-growth.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;「不論你信主的時間有多久，都應感受到被更新、改變、鼓舞和激勵。」&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;傾聽神的聲音，順服，活出旨意中的命定——這是人生信仰的基本功。&lt;/p&gt;
&lt;p&gt;在這 Xmas 賜平安意念之日，也該為明年做某些決定了。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/hardest-decision.jpg&#34; alt=&#34;最困難的抉擇&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/hardest-decision.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;最困難的抉擇&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;2020-許願&#34;&gt;2020 許願&lt;/h2&gt;
&lt;p&gt;2020 年，希望自己能做到：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;繼續在信仰裡聆聽與順服。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;繼續更深度的本質修練。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;繼續增進商務英語聽說能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;走出蟄伏期。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;開放冒險選項。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就醬。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;艾琳．梅爾 (Erin Meyer) &lt;a href=&#34;https://www.hbrtaiwan.com/article_content_AR0002707.html&#34;&gt;說&lt;/a&gt;：「在低語境文化中，良好的溝通是精準、簡單、明確和清楚的，以表面意義來了解訊息，也認同應該為了釐清而重說一次，以書面陳述訊息的情況也一樣。在高語境文化中，溝通是複雜、微妙和多層次的，訊息通常是隱含而不直接明說，較少以書面形式提出，大多是開放供人解讀，至於怎麼解讀，要看對言外之意的領悟而定。」她在《&lt;a href=&#34;https://www.books.com.tw/products/0010771747&#34;&gt;文化地圖&lt;/a&gt;》書中，針對八個面向的文化量表，有更詳盡的分析：高情境 vs 低情境、直接否定回應 vs 間接否定回應、原理優先 vs 應用優先、平權式 vs 階級、共識 vs 由上而下、任務導向 vs 關係導向、對峙 vs 避免對峙、線性時間 vs 彈性時間。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;今年我也交互參考重讀了好幾次劉恭甫（功夫老師）兩本後續的書：《&lt;a href=&#34;https://www.books.com.tw/products/0010721292&#34;&gt;左思右想：36 堂有效解決工作難題的創新思考&lt;/a&gt;》及《&lt;a href=&#34;https://www.books.com.tw/products/0010775968&#34;&gt;Ｘ計畫：打造人生黃金交叉線的轉機與關鍵&lt;/a&gt;》，獲益良多。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;詳見我於 Agile Summit 2018 發表的演講：〈&lt;a href=&#34;https://www.slideshare.net/williamyeh/agile-transition-a-toc-perspective&#34;&gt;從限制理論角度談敏捷導入階段&lt;/a&gt;〉&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;很多人視 5W1H 為過氣的老調。有趣的是，日本人對於經典的 5W1H 似乎情有獨鍾，出了幾本專書：《&lt;a href=&#34;https://www.books.com.tw/products/0010826002&#34;&gt;5W1H 超強思考術：你的所有問題，都可以靠 5W1H 解決！&lt;/a&gt;》、《&lt;a href=&#34;https://www.books.com.tw/products/0010840745&#34;&gt;5W1H 經典思考法：容易獲得成果的人都在用&lt;/a&gt;》。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;引述 LeSS 的 &amp;ldquo;&lt;a href=&#34;https://less.works/less/structure/scrummaster.html#ScrumMasterfocus&#34;&gt;Scrum Master focus over time&lt;/a&gt;&amp;rdquo; 觀點：&amp;ldquo;LeSS adoptions often involve large codebases with lots of archaic and messy legacy code; applying modern practices on them is challenging. The focus on development practices stays high as it will only become harder and harder to improve the teams even further.&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;2019 年，我帶了幾場【給 RD 的 Kubernetes 初體驗】工作坊，有 &lt;a href=&#34;https://github.com/William-Yeh/workshop-k8s201908&#34;&gt;GKE 版本&lt;/a&gt;，也有 &lt;a href=&#34;https://github.com/William-Yeh/workshop-k8s201909-eks&#34;&gt;EKS 版本&lt;/a&gt;。&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>技術面試的小觀點</title>
      <link>//william-yeh.net/post/2019/12/tech-interview/</link>
      <pubDate>Wed, 04 Dec 2019 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/12/tech-interview/</guid>
      
        <description>&lt;p&gt;年底，人才流動的旺季。&lt;/p&gt;
&lt;p&gt;這陣子，經手一堆履歷，更面試超過十場，深深覺得，若多一點人懂得&lt;strong&gt;面試&lt;/strong&gt;的遊戲規則，甚至更廣義的&lt;strong&gt;職場&lt;/strong&gt;遊戲規則，將是賓主盡歡的美事。&lt;/p&gt;
&lt;p&gt;Bryan &lt;a href=&#34;https://www.facebook.com/bryan.yao.1/posts/2666223613434413&#34;&gt;說得好&lt;/a&gt;：「求職過程投入越多，越能理解這個遊戲規則，也對自己的目標更清晰！」&lt;/p&gt;
&lt;p&gt;我們或許都沒有前衛到像 Netflix《&lt;a href=&#34;https://www.books.com.tw/products/0010796709&#34;&gt;給力&lt;/a&gt;》那樣「鼓勵員工經常去面試別家公司的工作」，但說實話，多一些面試與被面試的經歷，的確能夠更掌握遊戲規則，也會衝擊到自己原先的浪漫幻想，降低美麗的錯誤，將自己導向更務實的定位。&lt;/p&gt;
&lt;p&gt;面試與被面試都經歷過不少的我，想針對這陣子的所見所聞，分享一些個人的觀點。&lt;/p&gt;
&lt;h2 id=&#34;刷題&#34;&gt;刷題&lt;/h2&gt;
&lt;p&gt;以前我對刷題之舉是很不屑一顧的。總覺得這不是每位軟體工程師都需要去嘗試的。&lt;/p&gt;
&lt;p&gt;不過，就如同程天縱在〈&lt;a href=&#34;https://tuna.press/?p=9978&#34;&gt;自己爬上巨人的肩膀：踏入職場的艱辛旅程&lt;/a&gt;〉一文對美國軟體研發界的觀察：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在十年前的 2009 年，只要會寫軟體，甚至不需要經驗，學校一畢業就可以很容易的找到工作。&lt;/p&gt;
&lt;p&gt;但近十年來，大量中國和印度的留學生來到了美國，專攻互聯網、軟體開發、算法、人工智慧、大數據分析、雲計算等等領域，使得就業競爭越發激烈。尤其川普總統上任以後，緊縮了綠卡和移民的名額，導致美國留學申請的門檻更加提高了。&lt;/p&gt;
&lt;p&gt;因此，過去簡單的、走形式的面試問題和技術測試，難度就越來越高了；尤其網路和社群的普及，考過的題目立刻被分享在網上。因此，各個徵才企業就不斷的更新題庫、甚至提高難度。於是，&lt;a href=&#34;https://leetcode.com/&#34;&gt;LeetCode&lt;/a&gt; 網站上的題目，幾乎都是要去面試的軟體工程師必「做」、必「背」的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;典型的滾雪球軍備競賽，正增強迴路。&lt;/p&gt;
&lt;p&gt;甚至像&lt;a href=&#34;https://crossing.cw.com.tw/blogTopic.action?id=1095&amp;amp;nid=10739&#34;&gt;這篇文章&lt;/a&gt;所說，不只是近期內打算求職的人會去刷題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如今在矽谷的每一天，這個「刷題例行工作」，更是許多不論資深或資淺的工程師，在上班時間外的「必做功課」之一。&lt;/p&gt;
&lt;p&gt;每天利用時間刷題，連續這樣刷上幾個月到一兩年，在矽谷是司空見慣的：最近我有兩個同事離職去了 Uber，他們在此之前分別刷了一年和整整兩年的考古題目；另一位同事刷了半年的題，進了 Amazon。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這就是美國軟體研發重鎮的遊戲規則。&lt;/p&gt;
&lt;p&gt;台灣，雖然還沒有發展出如此激烈的競爭態勢，但相對低薪太久了，優秀人才思遷外流，精明外商也在台設置研發據點就地搶人，導致刷題風氣也開始在某些小圈子裡盛行。像這次 &lt;a href=&#34;https://ithelp.ithome.com.tw/2020ironman/reward&#34;&gt;iT 邦幫忙鐵人賽&lt;/a&gt;就有兩位以 LeetCode 為主題的得獎者，其中一位甚至還在別處開設&lt;a href=&#34;https://hiskio.com/courses/319&#34;&gt;線上課程&lt;/a&gt;教人 LeetCode 解題呢。&lt;/p&gt;
&lt;p&gt;當然啦，刷題網站不只可拿來操練演算法，據我所知，同溫層當中也有些人拿這類刷題素材做為 TDD kata。最有名的例子就是 &lt;a href=&#34;https://dotblogs.com.tw/hatelove/series/1?qq=LeetCode%2520%E7%B7%B4%E5%8A%9F%E6%88%BF&#34;&gt;91&lt;/a&gt; 了。&lt;/p&gt;
&lt;p&gt;因此，我開始修正對於刷題網站的觀點。我會視情況，用兩種解題心態來看待它們：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Kata 心態。借用刷題素材，熟悉新的程式語言及標準程式庫，或是磨練 TDD 之類的技法。此時的重點在於「型」的固化與內化，不在於演算法的錙銖必較，因此，要有「可能暫時過不了刷題評分系統」的心理準備。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;演算法複雜度優化心態。我建議，盡量自我要求，不要驟然追求速解，該用類似 &lt;a href=&#34;https://www.amazon.com/dp/069111966X&#34;&gt;&lt;em&gt;How to Solve It&lt;/em&gt;&lt;/a&gt; 或 &lt;a href=&#34;https://www.amazon.com/dp/0201120372&#34;&gt;&lt;em&gt;Introduction to Algorithms: A Creative Approach&lt;/em&gt;&lt;/a&gt; 之類的逐步推演思路，有系統地闡述，才能鍛鍊出通用的解題思路，不至於淪為「背解法」。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;（似乎該拿來練一下了⋯⋯）&lt;/p&gt;
&lt;h2 id=&#34;kata-心態&#34;&gt;Kata 心態&lt;/h2&gt;
&lt;p&gt;Kata 心態，不只是拿來面對刷題素材，更應該拿來用在更廣泛的地方。&lt;/p&gt;
&lt;p&gt;尤其是軟體架構。&lt;/p&gt;
&lt;p&gt;雖然我們常說：不要重複造輪子，但這並不代表，我們連造輪子的能力都不去操練。&lt;/p&gt;
&lt;p&gt;譬如說，當你學到分散式系統、微服務架構時，會不會試著甩開別人包得好好的現成框架，改而像 &lt;a href=&#34;https://columns.chicken-house.net/&#34;&gt;Andrew&lt;/a&gt; 那樣自我練習，從頭開始構築方案？ &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;有興趣的話，趁這次機會，用簡化過的 POC 環境來練習看看吧！POC 的好處是你可以專注在問題本身，盡可能地排除其他環境或是框架帶來的干擾，讓你專心地思考問題本身該怎麼解決。也只有 POC，你才能有機會觀察到實際測試的統計數據與評分，讓你比較與改善的過程可以更加科學。  &lt;!-- raw HTML omitted --&gt;     &amp;mdash; 〈&lt;a href=&#34;https://columns.chicken-house.net/2019/08/30/scheduling-practices/&#34;&gt;後端工程師必備: 排程任務的處理機制練習&lt;/a&gt;〉&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;譬如說，當你學到最近當紅的 DDD 及 clean architecture，會不會試著甩開別人包得好好的現成框架，改而像這次 &lt;a href=&#34;https://ithelp.ithome.com.tw/2020ironman/reward&#34;&gt;iT 邦幫忙鐵人賽&lt;/a&gt;的優選作品〈&lt;a href=&#34;https://ithelp.ithome.com.tw/users/20111997/ironman/2730&#34;&gt;Think in Domain-Driven Design&lt;/a&gt;〉那樣，試著從頭開始構築方案？&lt;/p&gt;
&lt;p&gt;造輪子的能力，是否曾經刻苦磨練過，在面談時很難隱藏。&lt;/p&gt;
&lt;p&gt;身體學會的，誰也帶不走。&lt;/p&gt;
&lt;h2 id=&#34;行為面談&#34;&gt;行為面談&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;行為面談法&lt;/strong&gt; (behavioral interview) 是許多招募專家推薦的面談策略，搭配 &lt;strong&gt;STAR&lt;/strong&gt; (situation, task, action, result) 問題設計，可以挖掘到很深的層次。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;行為面談，對於「被面談者」來說，挑戰性自不在話下；但是，對於「面試官」來說，也不是很輕鬆的差事。事前的設計要花時間，甚至得客製化；就連面談當下的引導、追溯與記錄，甚至事後的歸納整理與評斷，都非常費神。&lt;/p&gt;
&lt;p&gt;這一直困擾著我。&lt;/p&gt;
&lt;p&gt;所幸，後來受到《&lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;》的啟發，對行為面談法多了些把握。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;》作者佐藤將之是日本亞馬遜創始成員，服務了 15 年。他的現身說法，應該頗具代表性。&lt;/p&gt;
&lt;p&gt;本書試著以 Amazon 角度，回答一個關鍵問題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;到了面試的時候，面試官會注意應徵者的哪些特質呢？&lt;/p&gt;
&lt;p&gt;用一句話來說，就是對象是否具備「&lt;strong&gt;我們的領導力準則&lt;/strong&gt;」(&lt;a href=&#34;https://www.aboutamazon.com/working-at-amazon/our-leadership-principles&#34;&gt;our leadership principles; OLP&lt;/a&gt;) 特質。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很多企業的 vision/mission/values 是寫給華爾街看的。漂亮的話人人會說，怎麼知道是不是玩真的？&lt;/p&gt;
&lt;p&gt;Amazon 的做法很有趣：在面試當中察驗。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/olp14.jpg&#34; alt=&#34;Amazon 14 OLP&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/olp14.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Amazon 14 OLP&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;》解釋 OLP 在面試時扮演吃重的角色：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OLP 也會實際在面試時採用。對亞馬遜來說，徵才面試的目的，是深入探究面試者在過去的工作過程中如何發現 OLP。換句話說，亞馬遜不會只看技能或成績，還會看面試者是否能加速亞馬遜的成長，而重要的判斷基準就是這套領導力準則。&lt;/p&gt;
&lt;p&gt;第一關面試會由招募經理進行，人事部也會視情況面試。⋯⋯&lt;/p&gt;
&lt;p&gt;負責第二關的面試官，都會事先從招聘經理那裡收到以下請託：「一對一面試時，希望特別針對這個重點提問。」這個重點也是 OLP 中的其中一項。面試官在詳閱履歷表後，便會依照事前收到的要求，思考要發問的問題，與應徵者一對一面試。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;具體的 OLP 提問方式，其實就跟行為面談法的精神相同：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;亞馬遜的招聘面試非常注重&lt;strong&gt;邏輯&lt;/strong&gt;，應該有不少應徵者在面試過程中覺得「被追問到底」。這是因為在面試過程中，面試官必須&lt;strong&gt;具體&lt;/strong&gt;的詢問「基於什麼樣的想法，做了什麼事，如何成功的⋯⋯」，並將其&lt;strong&gt;記錄&lt;/strong&gt;下來。&lt;/p&gt;
&lt;p&gt;不問「這是⋯⋯？」或「是否⋯⋯？」等封閉式問句，而是用 &lt;strong&gt;5W1H&lt;/strong&gt; 來提問。&lt;/p&gt;
&lt;p&gt;經常有應徵者在履歷表上過度誇耀自己的實績，這時若能深入發掘：「如何思考，並具體採取了什麼行動？」就能不被對方的職稱所動搖，看出應徵者的實力。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我從這本書學到，要把行為面談法連繫到企業的核心價值觀。&lt;/p&gt;
&lt;p&gt;更重要的是，要自己融會出一套，與核心價值聯繫起來的 STAR 架構，不管是面試還是被面試。&lt;/p&gt;
&lt;p&gt;譬如說，針對技術領域，我自己發展出一套容易操作的探索察驗程序，並聯想《復仇者聯盟》與四顆無限寶石的情節，以便記憶：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/12/stones.png&#34; alt=&#34;Stones&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/12/stones.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Stones&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這需要操練。&lt;/p&gt;
&lt;h2 id=&#34;以-devops-領域為例&#34;&gt;以 DevOps 領域為例&lt;/h2&gt;
&lt;p&gt;口說無憑，就以最近在 DevOps 社群看到的話題為例吧。&lt;/p&gt;
&lt;p&gt;在&lt;a href=&#34;https://www.facebook.com/groups/DevOpsTaiwan/permalink/2566212293465801/&#34;&gt;「請問各位在面試 DevOps Engineer 都會問什麼問題」討論串&lt;/a&gt;當中，Rick Hwang 提出一則很好的示範：「你過去的經驗，通常用哪一種部署策略？考慮哪些因素？為什麼？怎麼實踐？」不難看出，這已經算是很接近 STAR 精神的行為面談。&lt;/p&gt;
&lt;p&gt;我也來稍微示範一下，如何將行為面談法連繫到企業的核心價值觀。&lt;/p&gt;
&lt;p&gt;如果我們想聯繫上 OLP 核心價值，該怎麼問呢？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;顧客至上：「你過去的經驗，通常用哪一種部署策略？是給哪些人用的？他們對此有什麼看法？你有嘗試過推動其他更好的部署策略嗎？他們對此又有什麼看法？過程中遇到哪些困難？你是如何克服的？」&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;創新與簡化：「新的部署策略，哪些地方比以前方便，哪些地方反而比以前複雜？當他們抱怨時，你是如何進一步克服這問題的？」&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;刨根問底：「如果要進行混合雲與多雲的部署，你會怎麼做？」視情況，這議題可以挖得很深很深⋯⋯&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果我們想聯繫上 DevOps 核心價值，該怎麼運用《復仇者聯盟》四顆無限寶石的口訣來提問呢？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Reality：「你過去的經驗，通常用哪一種部署策略？」視現場互動情況，再以 5W1H 角度去蒐集具體事實：what? why? why not? for who? with who? when? how? &amp;hellip;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Space：「以你所知，還有哪些部署策略是業界流行的？你為什麼不採用它們？以你所知，在部署策略上，未來的趨勢是？你對它們的評論是？」&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Time：「假設有一個像 xxx 這樣的個案，你會如何導入剛剛提到的 yyy 部署策略？」&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mind：「這種導入過程，需要哪些人配合？你會如何說服他們配合？」&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;運用之妙，存乎一心。這需要操練。&lt;/p&gt;
&lt;h2 id=&#34;馬拉松&#34;&gt;馬拉松&lt;/h2&gt;
&lt;p&gt;程天縱在〈&lt;a href=&#34;https://tuna.press/?p=9978&#34;&gt;自己爬上巨人的肩膀：踏入職場的艱辛旅程&lt;/a&gt;〉一文提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在美國最夢幻的僱主就是「FLAG」四家企業：Facebook 、LinkedIn、Amazon、Google。這四家企業招聘軟體工程師都非常慎重，進入門檻也都非常的高。&lt;/p&gt;
&lt;p&gt;這些公司的面試，都要經過四、五輪的電話面試、線上技術測試、視訊面試和測驗，最糟糕的是，時間拖得非常長，前後有長到兩、三個月的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010811254&#34;&gt;Amazon 的人為什麼這麼厲害？&lt;/a&gt;》也自嘲：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;人力仲介業界常說亞馬遜的招聘面試會「搞死仲介」，因為他們向亞馬遜推薦的人才都很難被錄用，所以常會抱怨：「已經不知道該推薦誰才好了」。只不過，我們的想法是「寧缺勿濫」，內部有招聘優秀人才的基本思維及穩健機制。&lt;/p&gt;
&lt;p&gt;第一關面試會由招聘經理進行。⋯⋯&lt;/p&gt;
&lt;p&gt;第二關面試可以說很有亞馬遜的風格。首先是人數，最多會從公司內部召集五名面試官，皆為其他部門的管理者階層。這群面試官之中，肯定會包含一位稱為「抬桿者」(bar raiser)  &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; 的人物。第二關面試也是一對一，每次約 40~45 分鐘，最多要進行五場。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我並不盲目鼓吹這種過五關斬六將的風格。不過，如果你遇到這樣的機會，請把握，如果這是值得的。&lt;/p&gt;
&lt;p&gt;請保持向著標竿直跑的勇氣與耐心吧。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;對於軟體架構 kata 感興趣的，請拿 Andrew 的【&lt;a href=&#34;https://columns.chicken-house.net/categories/#%E7%B3%BB%E5%88%97%E6%96%87%E7%AB%A0:%20%E6%9E%B6%E6%A7%8B%E9%9D%A2%E8%A9%A6%E9%A1%8C&#34;&gt;架構面試題&lt;/a&gt;】系列文章來挑戰看看吧！&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;對於&lt;strong&gt;行為面談法&lt;/strong&gt; (behavioral interview) 感興趣的，可讀讀知名獵頭 Lynn 所寫的〈&lt;a href=&#34;http://www.lynncareers.com/2017/09/behavioralinterview.html&#34;&gt;【面試的藝術】行為面試，現正進行中&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;「抬桿者」(bar raiser) 是 Amazon 很獨特的用人思維。請參考〈&lt;a href=&#34;https://bookzone.cwgv.com.tw/topic/details/6007&#34;&gt;亞馬遜如何挑選人才？&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Volume Resizing Mechanism in Kubernetes</title>
      <link>//william-yeh.net/post/2019/07/k8s-vol-resizing/</link>
      <pubDate>Wed, 31 Jul 2019 13:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/07/k8s-vol-resizing/</guid>
      
        <description>&lt;p&gt;Non-stop storage scaling (vertical or horizontal scaling) is essential in a data-intensive system, database servers in particular.&lt;/p&gt;
&lt;p&gt;Is it possible in Kubernetes?&lt;/p&gt;
&lt;p&gt;In Kubernetes v1.11 the &lt;em&gt;persistent volume expansion&lt;/em&gt; feature is being promoted to beta and enabled by default.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; There is also a nontrivial real-world use case for this: &lt;a href=&#34;https://strimzi.io/&#34;&gt;Strimzi Kafka operator&lt;/a&gt;. Strimzi merely builds on top of existing Kubernetes &lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/storage-classes/&#34;&gt;storage class&lt;/a&gt; mechanism to grow the storage of Kafka cluster.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; Therefore, the volume resizing feature is not exclusively available for Strimzi and Kafka. You can put this feature into your own application as long as you learn the mechanism.&lt;/p&gt;
&lt;p&gt;To get a concrete knowledge of the volume resizing, I&amp;rsquo;ve conducted a simple experiment on GCP and GKE. The experiment tries to answer the following questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Does volume resizing really work in Kubernetes?&lt;/li&gt;
&lt;li&gt;Is the resizing process non-stop?&lt;/li&gt;
&lt;li&gt;Are data still persistent after resizing?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All experiment materials are available in the &lt;a href=&#34;https://github.com/William-Yeh/vol-resize&#34;&gt;vol-resize&lt;/a&gt; repo, for your convenience.&lt;/p&gt;
&lt;h2 id=&#34;about-the-sample-app&#34;&gt;About the sample app&lt;/h2&gt;
&lt;p&gt;A sample app &lt;a href=&#34;https://github.com/William-Yeh/vol-resize/blob/master/voltest.sh&#34;&gt;voltest.sh&lt;/a&gt; will be used for the whole experiment.&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; It displays the size of available disk spaces in the specified mount point (as the 1st argument), and also records the data continuously in the specified output file (as the 2nd argument; default to &lt;code&gt;&amp;quot;data&amp;quot;&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how it works. Assume that we are in the &lt;code&gt;/home&lt;/code&gt; directory, with available disk space about 4.5 GB:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% pwd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/home
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% df -h
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Filesystem      Size  Used Avail Use% Mounted on
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;overlay          41G   32G  8.2G  80% /
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmpfs            64M     0   64M   0% /dev
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmpfs           848M     0  848M   0% /sys/fs/cgroup
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/dev/sda1        41G   32G  8.2G  80% /root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/dev/sdb1       4.8G   38M  4.5G   1% /home
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;overlayfs       1.0M  160K  864K  16% /etc/ssh/keys
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;shm              64M     0   64M   0% /dev/shm
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;overlayfs       1.0M  160K  864K  16% /etc/ssh/ssh_host_dsa_key
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmpfs           848M  736K  847M   1% /run/metrics
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;tmpfs           848M     0  848M   0% /run/google/devshell&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;At first run, it shows the space of current directory and records them continuously in the &lt;code&gt;data&lt;/code&gt; file within the same directory:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% docker run -it  -v $(pwd):/mnt  williamyeh/voltest  /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---&amp;gt; Checking /mnt/data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;5 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;6 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;7 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;8 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;9 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;10 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;11 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;12 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;^C
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;%&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Interrupt the execution at 12 on purpose, and run again. You&amp;rsquo;ll see that it picks up the last serial number 12 and continues counting:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% docker run -it  -v $(pwd):/mnt  williamyeh/voltest  /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---&amp;gt; Checking /mnt/data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;14 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;15 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;16 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;17 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;18 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;19 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;20 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;21 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;22 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;23 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;^C
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;%&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Now the &lt;code&gt;data&lt;/code&gt; file should have 23 lines of records:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% cat data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;5 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;6 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;7 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;8 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;9 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;10 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;11 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;12 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;14 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;15 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;16 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;17 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;18 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;19 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;20 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;21 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;22 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;23 : 4.5G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;%&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;In the following experiment we&amp;rsquo;ll use the app and the data file to answer the 3 questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Does volume resizing really work in Kubernetes?&lt;/em&gt; Just inspect the disk spaces it displays.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Is the resizing process non-stop?&lt;/em&gt; Just inspect the screen output.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Are data still persistent after resizing?&lt;/em&gt; Just inspect the content of data file.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ready?&lt;/p&gt;
&lt;h2 id=&#34;experiment-part-1-initial-size&#34;&gt;Experiment part 1: initial size&lt;/h2&gt;
&lt;p&gt;The experiment is conducted on GCP and GKE. However, it should apply to other cloud Kubernetes platforms as well, with minor modification.&lt;/p&gt;
&lt;p&gt;➊ Clone the experiment repo to your workspace or Cloud Shell:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% git clone https://github.com/William-Yeh/vol-resize.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;➋ Prepare a Kubernetes cluster in GKE.&lt;/p&gt;
&lt;p&gt;➌ Create a 20GB persistent disk named &lt;code&gt;voltest&lt;/code&gt;.  For example, the following command will create such a persistent disk in the us-central1-a zone:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% gcloud compute disks create         \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --size=20GB --zone=us-central1-a  \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    voltest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Check if the underlying persistent disk is created:&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/07/pd-20gb.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/07/pd-20gb.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;➍ We need a storage class with &lt;code&gt;allowVolumeExpansion&lt;/code&gt; enabled. The manifest file &lt;a href=&#34;https://github.com/William-Yeh/vol-resize/blob/master/expansion-ss.yml&#34;&gt;expansion-ss.yml&lt;/a&gt; is provided as follows:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apiVersion: storage.k8s.io/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind: StorageClass
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name: expansion
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;parameters:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  type: pd-standard
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;provisioner: kubernetes.io/gce-pd
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;allowVolumeExpansion: true
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reclaimPolicy: Delete&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Create a storage class &lt;code&gt;expansion&lt;/code&gt; for this:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl apply -f expansion-ss.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;➎ We need a PV manifest file &lt;a href=&#34;https://github.com/William-Yeh/vol-resize/blob/master/voltest-pv.yml&#34;&gt;voltest-pv.yml&lt;/a&gt; to associate it with the existing persistent disk just created before:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apiVersion: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind: PersistentVolume
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name: voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  storageClassName: &amp;#34;expansion&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  accessModes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - ReadWriteOnce
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  capacity:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    storage: 20Gi
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  gcePersistentDisk:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    pdName: voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fsType: ext4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Create the persistent volume &lt;code&gt;voltest&lt;/code&gt; now:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl apply -f voltest-pv.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;persistentvolume/voltest created
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl get pv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;voltest   20Gi       RWO            Retain           Available           expansion               8s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Note that the &lt;code&gt;voltest&lt;/code&gt; PV is in &amp;ldquo;Available&amp;rdquo; status.&lt;/p&gt;
&lt;p&gt;➏ We need a PVC manifest file &lt;a href=&#34;https://github.com/William-Yeh/vol-resize/blob/master/voltest-pvc.yml&#34;&gt;voltest-pvc.yml&lt;/a&gt; to claim the PV:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apiVersion: v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind: PersistentVolumeClaim
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name: voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  volumeName: voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  storageClassName: &amp;#34;expansion&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  accessModes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - ReadWriteOnce
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  resources:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    requests:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      storage: 20Gi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Claim the persistent volume now:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl apply -f voltest-pvc.yml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;persistentvolumeclaim/voltest created
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl get pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME      STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;voltest   Bound    voltest   20Gi       RWO            expansion      11s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl get pv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;voltest   20Gi       RWO            Retain           Bound    default/voltest   expansion               13m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Note that the &lt;code&gt;voltest&lt;/code&gt; PV/PVC pair is in &amp;ldquo;Bound&amp;rdquo; status.&lt;/p&gt;
&lt;p&gt;➐ We need a manifest file &lt;a href=&#34;https://github.com/William-Yeh/vol-resize/blob/master/voltest-app.yml&#34;&gt;voltest-app.yml&lt;/a&gt; for our sample app to access the PV/PVC:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apiVersion: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind: Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  replicas: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  template:   # pod definition
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    spec:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      containers:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - name: voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          image: williamyeh/voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          volumeMounts:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            - mountPath: &amp;#34;/mnt&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;              name: voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      volumes:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        - name: voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          persistentVolumeClaim:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            claimName: voltest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Invoke the sample app now:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl apply -f voltest-app.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Open another terminal pane to watch the logs continuously:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl logs -f deployment/voltest
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---&amp;gt; Checking /mnt/data
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;1 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;2 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;3 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;4 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;5 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;6 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;7 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;8 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;9 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;10 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;11 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;12 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Quite familiar output. Everything works fine.&lt;/p&gt;
&lt;p&gt;Keep the logs running. We&amp;rsquo;ll see it again and again.&lt;/p&gt;
&lt;h2 id=&#34;experiment-part-2-resizing&#34;&gt;Experiment part 2: resizing&lt;/h2&gt;
&lt;p&gt;Now we&amp;rsquo;re about to resize the volume.&lt;/p&gt;
&lt;p&gt;➊ Edit the &lt;code&gt;voltest&lt;/code&gt; PVC:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl edit pvc/voltest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;➋ Change the value of &lt;code&gt;spec.resources.requests.storage&lt;/code&gt; from &lt;code&gt;20Gi&lt;/code&gt; to &lt;code&gt;100Gi&lt;/code&gt;. Save, and exit.&lt;/p&gt;
&lt;p&gt;➌ Check if the logs are still being generated, and the content of the logs.&lt;/p&gt;
&lt;p&gt;➍ Check the size of underlying persistent disk. It should be expanded to 100 GB now.&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/07/pd-100gb.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/07/pd-100gb.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;➎ Check if the PV/PVC are both expanded:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl get pv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;voltest   100Gi      RWO            Retain           Bound    default/voltest   expansion               45m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl get pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME      STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;voltest   Bound    voltest   20Gi       RWO            expansion      32m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;PV is expanded to 100 GB, but PVC not yet. In other words, &lt;em&gt;block storage volume&lt;/em&gt; is expanded, but &lt;em&gt;file system&lt;/em&gt; is not yet. The reason is described in the “&lt;a href=&#34;https://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/&#34;&gt;Resizing Persistent Volumes using Kubernetes&lt;/a&gt;” article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&amp;ldquo;Once underlying volume has been expanded by the storage provider, then the PersistentVolume object will reflect the updated size and the PVC will have the &lt;code&gt;FileSystemResizePending&lt;/code&gt; condition.&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&amp;ldquo;File system expansion must be triggered by terminating the pod using the volume [&amp;hellip;] then pod that uses the PVC can be restarted to finish file system resizing on the node.&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For now the question &lt;em&gt;&amp;ldquo;2. Is the resizing process non-stop?&amp;rdquo;&lt;/em&gt; should be obviously answered. Let&amp;rsquo;s move on to handle the &lt;code&gt;FileSystemResizePending&lt;/code&gt; condition by restarting the related pods.&lt;/p&gt;
&lt;h2 id=&#34;experiment-part-3-restart-the-pod&#34;&gt;Experiment part 3: restart the pod&lt;/h2&gt;
&lt;p&gt;➊ Kill the pod, and let deployment restart a new pod for us (&lt;code&gt;replicas=1&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl get pods
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                      READY   STATUS    RESTARTS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;voltest-d88ff8c49-66wk2   1/1     Running   0          23m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl delete pod voltest-d88ff8c49-66wk2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;➋ Watch the logs! Our sample app will see the &lt;em&gt;file system expansion&lt;/em&gt; progress on the fly:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13465 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13466 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13467 : 20G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13468 : 24G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13469 : 30G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13470 : 30G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13471 : 30G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13472 : 30G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13473 : 30G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13474 : 42G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13475 : 77G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13476 : 99G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13477 : 99G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13478 : 99G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13479 : 99G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13480 : 99G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13481 : 99G
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;13482 : 99G&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;➌ Check if the PV/PVC are both expanded:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl get pv
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;voltest   100Gi      RWO            Retain           Bound    default/voltest   expansion               57m
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl get pvc
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME      STATUS   VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;voltest   Bound    voltest   100Gi      RWO            expansion      44m&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;For now the remaining questions &lt;em&gt;“1. Does volume resizing really work in Kubernetes?”&lt;/em&gt; and &lt;em&gt;“3. Are data still persistent after resizing?”&lt;/em&gt; should be obviously answered.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;As can be seen in this experiment, all you have to do to grow the PV/PVC are:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Preparation&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Use Kubernetes ≥ 1.11.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Set &lt;code&gt;allowVolumeExpansion: true&lt;/code&gt; for your &lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/storage-classes/&#34;&gt;storage class&lt;/a&gt;, and choose an appropriate underlying &lt;a href=&#34;https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes&#34;&gt;provisioner&lt;/a&gt; (storage provider).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use the storage class in your PV and PVC.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Expansion&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Increase the PVC &lt;code&gt;spec.resources.requests.storage&lt;/code&gt; value.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Restart the related pods.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kubernetes 1.11 also introduces an alpha feature called &lt;em&gt;online file system expansion&lt;/em&gt;. You can track its progress in the Kubernetes CSI Developer Documentation &amp;ldquo;&lt;a href=&#34;https://kubernetes-csi.github.io/docs/volume-expansion.html&#34;&gt;Volume Expansion&lt;/a&gt;&amp;rdquo;.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;You may use the volume resizing feature since Kubernetes 1.11. Read the article published by kubernetes.io in more detail: “&lt;a href=&#34;https://kubernetes.io/blog/2018/07/12/resizing-persistent-volumes-using-kubernetes/&#34;&gt;Resizing Persistent Volumes using Kubernetes&lt;/a&gt;”.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;To know more about how Strimzi implements the volume resizing for Kafka, read these articles: “&lt;a href=&#34;https://strimzi.io/2019/07/08/persistent-storage-improvements.html&#34;&gt;Persistent storage improvements&lt;/a&gt;” and “&lt;a href=&#34;https://strimzi.io/2019/02/28/resizing-persistent-volumes.html&#34;&gt;Resizing persistent volumes with Strimzi&lt;/a&gt;”.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;The Docker image for this &lt;a href=&#34;https://github.com/William-Yeh/vol-resize/blob/master/voltest.sh&#34;&gt;voltest.sh&lt;/a&gt; app is available in &lt;code&gt;williamyeh/voltest&lt;/code&gt; for your convenience.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>CKAD (Certified Kubernetes Application Developer) 相關資料</title>
      <link>//william-yeh.net/post/2019/07/ckad-materials/</link>
      <pubDate>Thu, 11 Jul 2019 17:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/07/ckad-materials/</guid>
      
        <description>&lt;p&gt;Linux Foundation 旗下的 &lt;a href=&#34;https://www.cncf.io/&#34;&gt;CNCF (Cloud Native Computing Foundation)&lt;/a&gt; 提供兩個與 Kubernetes 相關的個人技術檢定：偏維運的 &lt;a href=&#34;https://www.cncf.io/certification/cka/&#34;&gt;CKA (Certified Kubernetes Administrator)&lt;/a&gt;，以及偏研發的 &lt;a href=&#34;https://www.cncf.io/certification/ckad/&#34;&gt;CKAD (Certified Kubernetes Application Developer)&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;其中，CKAD 與我關注的範圍、與我設計的工作坊最接近，便想進一步瞭解它的細節。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:15em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/07/kubernetes-ckad-color.png&#34; alt=&#34;CKAD logo&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/07/kubernetes-ckad-color.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;CKAD logo&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;根據官方資料，CKAD 的 &lt;a href=&#34;https://github.com/cncf/curriculum&#34;&gt;curriculum&lt;/a&gt; 只有列出檢定考試的主題與比例，並沒有列出具體的應考讀物。目前看到最接近「欽定本」地位的 CKAD 檢定準備教材，就屬 Linux Foundation 製作的 &lt;a href=&#34;https://training.linuxfoundation.org/training/kubernetes-for-developers/&#34;&gt;LDF259&lt;/a&gt; 線上課程了——全長 35 小時，$299 美金。&lt;/p&gt;
&lt;p&gt;不過，是否還有其他選擇？&lt;/p&gt;
&lt;h2 id=&#34;實惠的線上課程&#34;&gt;實惠的線上課程&lt;/h2&gt;
&lt;p&gt;我在 Udemy 找到一份新台幣 $390 的線上課程 &lt;a href=&#34;https://www.udemy.com/course/certified-kubernetes-application-developer/&#34;&gt;Kubernetes Certified Application Developer (CKAD) with Tests&lt;/a&gt;。花十幾分鐘試過它的預覽單元，發現它的內容很扎實，實作練習也很活潑，應該滿適合從實作中學習的人，從過程中發現不足之處，再去找相關資料補強。&lt;/p&gt;
&lt;p&gt;即使我對 Kubernetes 已經有一定的掌握程度，也有設計實作教材的能力，但我還是喜歡以它作為配套。&lt;/p&gt;
&lt;p&gt;這會是我的 CKAD 首推材料。我建議，即使不購買這份教材，也請花十幾分鐘把它的預覽單元全都走過一遍。&lt;/p&gt;
&lt;h2 id=&#34;牛刀小試&#34;&gt;牛刀小試&lt;/h2&gt;
&lt;p&gt;根據 &lt;a href=&#34;https://training.linuxfoundation.org/go/cka-ckad-candidate-handbook&#34;&gt;CKAD 線上考試規定&lt;/a&gt;，應考時，不能使用紙張或數位筆記軟體 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。因此，這場檢定，很大幅度在考核肌肉記憶，以及 &lt;a href=&#34;https://kubernetes.io/docs/&#34;&gt;kubernetes.io/docs/&lt;/a&gt; 官方文件查找能力。&lt;/p&gt;
&lt;p&gt;既然遊戲規則訂成這樣，我們就該先體驗一下這有多麼殘酷。呵。&lt;/p&gt;
&lt;p&gt;我建議，如果你曾經有過一點點 Kubernetes 經驗，此刻，請先去 &lt;a href=&#34;https://github.com/dgkanatsios/CKAD-exercises&#34;&gt;dgkanatsios/CKAD-exercises&lt;/a&gt; 挑戰看看你的肌肉記憶。儘管這不是官方釋出的模擬試題，但牛刀小試一番，接受洗禮，或是打擊，總是好的。&lt;/p&gt;
&lt;h2 id=&#34;官方文件&#34;&gt;官方文件&lt;/h2&gt;
&lt;p&gt;經過以上的洗禮，知道自己不足之處，就可以開始啟動特訓之旅。&lt;/p&gt;
&lt;p&gt;根據 &lt;a href=&#34;https://training.linuxfoundation.org/go/cka-ckad-candidate-handbook&#34;&gt;CKAD 線上考試規定&lt;/a&gt;，應考時，你不能向 Google 求助；你能用瀏覽器查找的文件，只有 Kubernetes 官方文件 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;因此，請盡快熟悉以下幾個限定的參考資料來源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/docs/&#34;&gt;https://kubernetes.io/docs/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/kubernetes/&#34;&gt;https://github.com/kubernetes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kubernetes.io/blog/&#34;&gt;https://kubernetes.io/blog/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也請從現在開始自我要求，不論在其他任何地方看到的資料，都請務必回到以上官方欽定的參考資料所在地，逐一找出可與之對應的關鍵字、章節、語法規格、範例。&lt;/p&gt;
&lt;p&gt;這是 CKAD 應考時，你唯一的浮木舟。即使你並未志在 CKAD，這仍然是很好的習慣。&lt;/p&gt;
&lt;h2 id=&#34;前人經驗&#34;&gt;前人經驗&lt;/h2&gt;
&lt;p&gt;有了以上的心理建設，接下來，就可以用健康心態欣賞一下前人的經驗：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://ottodeng.io/post/ckad-exam/&#34;&gt;CKAD Exam&lt;/a&gt; on Jul 9, 2018.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/@ikaboubi/my-feedback-about-cka-and-ckad-e82a35585fe9&#34;&gt;My Feedback about CKA and CKAD&lt;/a&gt; on Jun 4, 2018.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/chotot/tips-tricks-to-pass-certified-kubernetes-application-developer-ckad-exam-67c9e1b32e6e&#34;&gt;Tips to pass Certified Kubernetes Application Developer (CKAD) exam&lt;/a&gt; on Dec 15, 2018.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;感謝你花了幾分鐘，讀完由一位沒參加過 CKAD 的人所整理的這篇文章。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://training.linuxfoundation.org/go/cka-ckad-candidate-handbook&#34;&gt;CKA/CKAD Candidate Handbook&lt;/a&gt; v1.20 提到：“The following resources are forbidden during the exam: Use of devices other than the exam desktop; Notes;  Documentation; Notepads (other than what’s provided within the exam browser tab); Course manuals [&amp;hellip;]”&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://training.linuxfoundation.org/go/cka-ckad-candidate-handbook&#34;&gt;CKA/CKAD Candidate Handbook&lt;/a&gt; v1.20 提到：“You are permitted to use your Chrome or Chromium browser to open one additional tab in order to access assets at &lt;a href=&#34;https://kubernetes.io/docs/&#34;&gt;https://kubernetes.io/docs/&lt;/a&gt; and its subdomain, &lt;a href=&#34;https://github.com/kubernetes/&#34;&gt;https://github.com/kubernetes/&lt;/a&gt; and its subdomains, or &lt;a href=&#34;https://kubernetes.io/blog/&#34;&gt;https://kubernetes.io/blog/&lt;/a&gt;. No other tabs may be opened and no other sites may be navigated to. The allowed sites above may contain links that point to external sites. It is the responsibility of the candidate not to click on any links that cause them to navigate to a domain that is not allowed.”&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Docker File Permissions on Windows</title>
      <link>//william-yeh.net/post/2019/06/docker-file-permissions/</link>
      <pubDate>Mon, 24 Jun 2019 12:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/06/docker-file-permissions/</guid>
      
        <description>&lt;p&gt;Currently Linux containers are still more popular than Windows containers. And Windows users often need to use Linux containers even from their Windows computers.&lt;/p&gt;
&lt;p&gt;Recently I&amp;rsquo;ve found something very strange about Linux-style file permissions when the Docker images are built from Windows hosts.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; Therefore, I&amp;rsquo;ve conducted a suite of test cases to investigate whether file permissions are preserved with Docker &amp;amp; &lt;a href=&#34;https://skaffold.dev/&#34;&gt;Skaffold&lt;/a&gt; toolchains. All experiment materials are available in the &lt;a href=&#34;https://github.com/William-Yeh/container-chmod&#34;&gt;container-chmod&lt;/a&gt; repo.&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% git clone https://github.com/William-Yeh/container-chmod.git&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;experiment-setting&#34;&gt;Experiment setting&lt;/h2&gt;
&lt;p&gt;The experiments are composed of a few files with typical Unix-style file permissions:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── skaffold.yaml
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── src
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── Dockerfile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── file-644.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── script-755.sh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rw-r--r-- 1 william  70 Jun 24 17:01 Dockerfile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rw-r--r-- 1 william  57 Jun 24 15:17 file-644.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rwxr-xr-x 1 william  84 Jun 24 15:19 script-755.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;We will use two ways to build the Linux-container images:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;To build image with &lt;code&gt;docker build&lt;/code&gt; command (Docker Engine 18.09.2).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To build image with &lt;code&gt;skaffold build&lt;/code&gt; command (Skaffold v0.32.0).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And we&amp;rsquo;ll conduct the experiments in the following environment settings:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Host&lt;/th&gt;
          &lt;th&gt;Built w/ Docker CLI&lt;/th&gt;
          &lt;th&gt;Built w/ Skaffold (WSL version)&lt;/th&gt;
          &lt;th&gt;Built w/ Skaffold (host version)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS&lt;/td&gt;
          &lt;td&gt;➊&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
          &lt;td&gt;➋&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;WSL + Docker Desktop for Windows&lt;/td&gt;
          &lt;td&gt;③&lt;/td&gt;
          &lt;td&gt;➍&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Windows&lt;/td&gt;
          &lt;td&gt;⑤&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
          &lt;td&gt;⑹&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Will all experiments display the correct file permissions?&lt;/p&gt;
&lt;h2 id=&#34;macos--&#34;&gt;macOS: ➊ ➋&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s begin with macOS, which acts as the control group.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/253423&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/253423.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Perfect! All Unix-style file permissions are set correctly.&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 20                                                                        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxr-xr-x    1 root     root          4096 Jun 24 22:30 .                      
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxr-xr-x    1 root     root          4096 Jun 24 22:30 ..                     
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rw-r--r--    1 root     root            70 Jun 24 22:18 Dockerfile             
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rw-r--r--    1 root     root            57 Jun 24 22:18 file-644.txt           
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rwxr-xr-x    1 root     root            84 Jun 24 22:18 script-755.sh          &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;wsl--&#34;&gt;WSL: ③ ➍&lt;/h2&gt;
&lt;p&gt;On Windows, my preference is to use WSL to connect to Docker Desktop for Windows.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;  Will this combination work well with Unix-style file permissions?&lt;/p&gt;
&lt;p&gt;Below are experiments conducted on WSL:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/253450&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/253450.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As shown in this demo, the ➍ skaffold experiment works quite well on WSL. The ③ docker-cli experiment works, though not the best-possible Unix-style file permissions:&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have &lt;code&gt;&#39;-rwxr-xr-x&#39;&lt;/code&gt; permissions. It is recommended to double check and reset permissions for sensitive files and directories.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;pure-windows--&#34;&gt;Pure Windows: ⑤ ⑹&lt;/h2&gt;
&lt;p&gt;What if a Windows user sticks with pure-Windows toolchains, i.e., use traditional Command Prompt (cmd) to connect to Docker Desktop for Windows?&lt;/p&gt;
&lt;p&gt;The ⑤ docker-cli experiment shows the same result as in previous ③ &lt;code&gt;&#39;-rwxr-xr-x&#39;&lt;/code&gt; permission:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:\&amp;gt; docker run -it test-docker                                           
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;File permission (script-755.sh) should be: 755  rwxr-xr-x              
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 20                                                               
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxr-xr-x    1 root     root          4096 Jun 25 03:45 .             
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxr-xr-x    1 root     root          4096 Jun 25 03:45 ..            
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rwxr-xr-x    1 root     root            70 Jun 25 03:44 Dockerfile    
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rwxr-xr-x    1 root     root            57 Jun 24 08:03 file-644.txt  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rwxr-xr-x    1 root     root            84 Jun 24 08:03 script-755.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;However, the ⑹ skaffold experiment shows the &lt;em&gt;worst&lt;/em&gt; result:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:\&amp;gt; skaffold-windows-amd64.exe build
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Generating tags...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; - test-skaffold -&amp;gt; test-skaffold:dbe377c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Tags generated in 228.0023ms
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Starting build...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Found [docker-for-desktop] context, using local docker daemon.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Building [test-skaffold]...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sending build context to Docker daemon  4.096kB
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Step 1/4 : FROM alpine:3.9.4
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:\&amp;gt; docker run -it 25997136449a
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;docker: Error response from daemon: OCI runtime create failed: container_linux.go:344:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;starting container process caused &amp;#34;exec: \&amp;#34;/app/script-755.sh\&amp;#34;: permission denied&amp;#34;: unknown.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:\&amp;gt; docker run -it 25997136449a  ls -al
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 20
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxr-xr-x    1 root     root          4096 Jun 25 03:51 .
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxr-xr-x    1 root     root          4096 Jun 25 03:53 ..
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rw-rw-rw-    1 root     root            70 Jun 25 03:44 Dockerfile
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rw-rw-rw-    1 root     root            57 Jun 24 08:03 file-644.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-rw-rw-rw-    1 root     root            84 Jun 24 08:03 script-755.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;As shown in the demo, Skaffold blindly sets all the file permissions as &lt;code&gt;&#39;-rw-rw-rw-&#39;&lt;/code&gt;, eliminating the &lt;code&gt;&#39;x&#39;&lt;/code&gt; permission required for the &lt;code&gt;script-755.sh&lt;/code&gt; script file.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Different Unix-style file permissions will be generated in the Docker images when building Linux containers with different combination of host operating systems, docker cli, and Skaffold toolchains:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Host&lt;/th&gt;
          &lt;th&gt;Built w/ Docker CLI&lt;/th&gt;
          &lt;th&gt;Built w/ Skaffold (WSL version)&lt;/th&gt;
          &lt;th&gt;Built w/ Skaffold (host version)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;macOS&lt;/td&gt;
          &lt;td&gt;➊&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
          &lt;td&gt;➋&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;WSL + Docker Desktop for Windows&lt;/td&gt;
          &lt;td&gt;③&lt;/td&gt;
          &lt;td&gt;➍&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Windows&lt;/td&gt;
          &lt;td&gt;⑤&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
          &lt;td&gt;⑹&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Results:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Best results: ➊ ➋ ➍&lt;/li&gt;
&lt;li&gt;Acceptable results: ③ ⑤&lt;/li&gt;
&lt;li&gt;Unacceptable results: ⑹&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My suggestions for building Linux images are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If your applications require adequate file permissions (especially the &lt;code&gt;&#39;x&#39;&lt;/code&gt;) and you cannot completely control the build toolchains to use, be sure to modify your &lt;code&gt;Dockerfile&lt;/code&gt; accordingly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you can control the whole toolchains to use (e.g., in the CI/CD pipeline), stick with the Linux ones.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;There is also an issue about this in Skaffold: &lt;a href=&#34;https://github.com/GoogleContainerTools/skaffold/issues/1470&#34;&gt;Issue #1470: Permission denied through skaffold&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;See my article “&lt;a href=&#34;//william-yeh.net/post/2019/03/wsl-cmder-zsh/&#34;&gt;在 Windows 上復刻 Mac 使用習慣&lt;/a&gt;”.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;See &lt;a href=&#34;https://github.com/moby/moby/issues/20397#issuecomment-185471832&#34;&gt;thaJeztah&amp;rsquo;s comment on GitHub&lt;/a&gt; about this.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Auto-Reload from ConfigMap</title>
      <link>//william-yeh.net/post/2019/06/autoreload-from-configmap/</link>
      <pubDate>Mon, 17 Jun 2019 17:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/06/autoreload-from-configmap/</guid>
      
        <description>&lt;p&gt;My previous article &amp;ldquo;&lt;a href=&#34;//william-yeh.net/post/2019/06/inotify-in-containers/&#34;&gt;Inotify in Containers&lt;/a&gt;&amp;rdquo; has demonstrated that when ConfigMap is mounted as directories, any changes in the ConfigMap will propagate to related pods, and can be detected with &lt;code&gt;inotify&lt;/code&gt;-like APIs.&lt;/p&gt;
&lt;p&gt;A follow-up question might be: what should a well-behaved application react to this trigger accordingly? What if it&amp;rsquo;s a ill-designed application?&lt;/p&gt;
&lt;p&gt;To clarify this I&amp;rsquo;ve conducted a series of experiments for 3 possible configmap-reloading  strategies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Built-in auto-reloading apps&lt;/li&gt;
&lt;li&gt;External signals&lt;/li&gt;
&lt;li&gt;Pod rollout&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In this article I&amp;rsquo;m going to explain the experiments and preliminary findings.  All experiment materials are available in the &lt;a href=&#34;https://github.com/William-Yeh/configmap-auto-reload&#34;&gt;configmap-auto-reload&lt;/a&gt; repo.&lt;/p&gt;
&lt;h2 id=&#34;built-in-auto-reloading-apps&#34;&gt;Built-in auto-reloading apps&lt;/h2&gt;
&lt;p&gt;Some applications (e.g., &lt;a href=&#34;https://traefik.io/&#34;&gt;Traefik&lt;/a&gt;) are smart enough to gracefully reload themselves whenever they detect any configuration changes without downtime.  Will this work with Kubernetes ConfigMap?&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://github.com/William-Yeh/configmap-auto-reload/tree/master/traefik-example&#34;&gt;traefik-example&lt;/a&gt; demo:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/251179&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/251179.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Perfect!  Traefik auto-reloads itself as long as you correctly mount the &lt;code&gt;traefik-config&lt;/code&gt; ConfigMap as &lt;code&gt;/etc/traefik/&lt;/code&gt; directory for the pod.  Here&amp;rsquo;s the related &lt;a href=&#34;https://github.com/William-Yeh/configmap-auto-reload/blob/master/traefik-example/traefik-config.yml#L11-L13&#34;&gt;code snippet&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[file]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;watch = true
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;directory = &amp;#34;/etc/traefik/&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;external-signals&#34;&gt;External signals&lt;/h2&gt;
&lt;p&gt;Some applications can &lt;em&gt;reload&lt;/em&gt; configurations; but not &lt;em&gt;auto-reload&lt;/em&gt;. Instead, they reload their configurations when they are &lt;em&gt;told&lt;/em&gt; to do so.  For example, when Nginx receives a &lt;code&gt;HUP&lt;/code&gt; signal (&lt;code&gt;nginx -s reload&lt;/code&gt;) &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and when Apache HTTP Server receives a &lt;code&gt;HUP&lt;/code&gt; signal (&lt;code&gt;apache -k restart&lt;/code&gt;) or &lt;code&gt;USR1&lt;/code&gt; signal (&lt;code&gt;apache -k graceful&lt;/code&gt;) &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, they will reload new configurations without downtime.&lt;/p&gt;
&lt;p&gt;Who should be the &lt;code&gt;HUP&lt;/code&gt; signal sender in Kubernetes?&lt;/p&gt;
&lt;p&gt;Before Docker and Kubernetes rule the world, there were plenty of such tools, e.g., &lt;a href=&#34;https://github.com/rvoicilas/inotify-tools&#34;&gt;inotify-tools&lt;/a&gt; and &lt;a href=&#34;https://github.com/kimmobrunfeldt/chokidar-cli&#34;&gt;Chokidar cli&lt;/a&gt;.  People used them to watch for changes in specified directories and to invoke dedicated actions accordingly (including sending signals, of course).&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/06/inotifywait.png&#34; alt=&#34;Combo trick: Inotifywait &amp;#43; Nginx&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/06/inotifywait.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Combo trick: Inotifywait &amp;#43; Nginx&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Will this combo trick work with Kubernetes ConfigMap?&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://github.com/William-Yeh/configmap-auto-reload/tree/master/inotifywait-example&#34;&gt;inotifywait-example&lt;/a&gt; demo:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/251666&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/251666.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Good!  Inotifywait detects the changes and sends &lt;code&gt;HUP&lt;/code&gt; signals to Nginx as long as you correctly mount the &lt;code&gt;nginx-config&lt;/code&gt; ConfigMap as &lt;code&gt;/etc/nginx/&lt;/code&gt; directory for the pod.  Here&amp;rsquo;s the related &lt;a href=&#34;https://github.com/William-Yeh/configmap-auto-reload/blob/master/inotifywait-example/watch-nginx.sh#L13-L22&#34;&gt;code snippet&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;if [[ &amp;#34;$(inotifywatch -e modify,create,delete,move -t 15 /etc/nginx/ 2&amp;gt;&amp;amp;1)&amp;#34; =~ filename ]]; then
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    echo &amp;#34;Try to verify updated nginx config...&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    nginx -t
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    if [ $? -ne 0 ]; then
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo &amp;#34;ERROR: New configuration is invalid!!&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    else
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo &amp;#34;Reloading nginx with new config...&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        nginx -s reload
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fi
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fi;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;DISCLAIMER: it&amp;rsquo;s just for demo; not a robust implementation. For more examples, see &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;CAUTION: it is against the best practice of &amp;ldquo;one process per container&amp;rdquo; policy.&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;  If you really want to use this combo trick, try to model it as &amp;ldquo;multiple containers within a single pod.&amp;rdquo;&lt;/p&gt;
&lt;h2 id=&#34;pod-rollout&#34;&gt;Pod rollout&lt;/h2&gt;
&lt;p&gt;Some applications do not have any configuration reloading mechanism. What should we do? Maybe the only reasonable way is to rollout their running instances, and just spawn new ones with the new configurations.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/stakater/Reloader&#34;&gt;Reloader&lt;/a&gt; is a generic solution for Kubernetes. With the help of it, pods can be restarted whenever related ConfigMap has changed.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;https://github.com/William-Yeh/configmap-auto-reload/tree/master/reloader-example&#34;&gt;reloader-example&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/251670&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/251670.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Perfect!  Nginx pods get rolling updated by Reloader as long as you annotate the Nginx deployment with &lt;code&gt;configmap.reloader.stakater.com/reload&lt;/code&gt;.  Here&amp;rsquo;s the related &lt;a href=&#34;https://github.com/William-Yeh/configmap-auto-reload/blob/master/reloader-example/nginx-service.yml#L25-L26&#34;&gt;code snippet&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;apiVersion: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kind: Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name: nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  annotations:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    configmap.reloader.stakater.com/reload: &amp;#34;nginx-config&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If your application is smart enough to gracefully reload itself whenever it detects any configuration changes, it continues working well with ConfigMap in Kubernetes.&lt;/p&gt;
&lt;p&gt;If not so smart, an easier approach is to use automatic tools (e.g., &lt;a href=&#34;https://github.com/stakater/Reloader&#34;&gt;Reloader&lt;/a&gt;) to rolling update related pods.&lt;/p&gt;
&lt;p&gt;I will not recommend the watch+signal approach (e.g., &lt;a href=&#34;https://github.com/rvoicilas/inotify-tools&#34;&gt;inotify-tools&lt;/a&gt;). It is prone to error and zombie processes.&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      Series of Articles
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2019/06/inotify-in-containers/&#34;&gt;Inotify in Containers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2019/06/containers-and-env/&#34;&gt;Containers and Environment Variables&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;➌ Auto-Reload from ConfigMap&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Nginx official document: &lt;a href=&#34;http://nginx.org/en/docs/control.html&#34;&gt;Controlling nginx&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Apache official document: &lt;a href=&#34;https://httpd.apache.org/docs/2.4/stopping.html&#34;&gt;Stopping and Restarting Apache HTTP Server&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;An implementation worth studying: &lt;a href=&#34;https://github.com/rosskukulinski/nginx-kubernetes-reload&#34;&gt;https://github.com/rosskukulinski/nginx-kubernetes-reload&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Q&amp;amp;A in Stack Overflow: &lt;a href=&#34;https://stackoverflow.com/questions/41031170/nginx-reload-configuration-best-practice&#34;&gt;Nginx Reload Configuration Best Practice&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/telephone/nginx-watch&#34;&gt;https://github.com/telephone/nginx-watch&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://cloud.google.com/solutions/best-practices-for-building-containers&#34;&gt;Best practices for building containers&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>Containers and Environment Variables</title>
      <link>//william-yeh.net/post/2019/06/containers-and-env/</link>
      <pubDate>Mon, 17 Jun 2019 14:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/06/containers-and-env/</guid>
      
        <description>&lt;p&gt;My previous article &amp;ldquo;&lt;a href=&#34;//william-yeh.net/post/2019/06/inotify-in-containers/&#34;&gt;Inotify in Containers&lt;/a&gt;&amp;rdquo; has demonstrated that when ConfigMap is mounted as &lt;em&gt;directories&lt;/em&gt;, any changes in the ConfigMap will propagate to related pods.&lt;/p&gt;
&lt;p&gt;A follow-up question might be: what if the ConfigMap is mounted as &lt;em&gt;environment variables&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;Some said that the answer is NO in Kubernetes&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;; even in the old Docker world&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.  Therefore, I&amp;rsquo;d like to begin with a simple experiment to try to answer the question: After a container starts, will it see any changes of environment variables?&lt;/p&gt;
&lt;p&gt;The experiment material is available at &lt;a href=&#34;https://github.com/William-Yeh/container-and-env&#34;&gt;https://github.com/William-Yeh/container-and-env&lt;/a&gt; , and here&amp;rsquo;s a simple demo:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/252073&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/252073.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is obvious in the demo that the changes of environment variables will not affect already-running processes inside the containers &amp;mdash; let alone pods in the Kubernetes world.&lt;/p&gt;
&lt;p&gt;To simply put, if you want ConfigMap to propagate its changes to related pods, mount the ConfigMap as &lt;em&gt;directories&lt;/em&gt;, not &lt;em&gt;environment variables&lt;/em&gt;.&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      Series of Articles
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2019/06/inotify-in-containers/&#34;&gt;Inotify in Containers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ Containers and Environment Variables&lt;/p&gt;
&lt;p&gt;➌ &lt;a href=&#34;//william-yeh.net/post/2019/06/autoreload-from-configmap/&#34;&gt;Auto-Reload from ConfigMap&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;An analysis of ConfigMap hot-reload can be found in the article by Jimmy Song: “&lt;a href=&#34;https://jimmysong.io/kubernetes-handbook/concepts/configmap-hot-update.html&#34;&gt;ConfigMap 的热更新&lt;/a&gt;”.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;A good Q&amp;amp;A in Stack Overflow: &lt;a href=&#34;https://stackoverflow.com/a/54412751/714426&#34;&gt;Reload configuration when env variable has changed&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>Inotify in Containers</title>
      <link>//william-yeh.net/post/2019/06/inotify-in-containers/</link>
      <pubDate>Mon, 10 Jun 2019 18:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/06/inotify-in-containers/</guid>
      
        <description>&lt;p&gt;It is usually necessary to watch for any changes in file systems, both in development and in production modes. For example, in the development mode &lt;a href=&#34;https://webpack.js.org/&#34;&gt;Webpack&lt;/a&gt; can watch files and recompile whenever they change; in the production mode &lt;a href=&#34;https://github.com/hashicorp/consul-template&#34;&gt;Consul Template&lt;/a&gt; can watch runtime configs and invoke specific applications whenever they change.&lt;/p&gt;
&lt;p&gt;These are well-known scenarios in traditional pre-container world.  How about the container world? Do they behave the same in the new container world?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve occasionally found that something behave differently in the container world. To clarify this I&amp;rsquo;ve conducted a series of experiments. In this article I&amp;rsquo;m going to explain the experiments and preliminary findings.  All experiment materials are available in the &lt;a href=&#34;https://github.com/William-Yeh/fswatch&#34;&gt;fswatch&lt;/a&gt; repo.&lt;/p&gt;
&lt;h2 id=&#34;experiment-setting&#34;&gt;Experiment setting&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve divided the experiments into 4 groups.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Group A (experiment 1 to 3) is the traditional native mode: run native apps in their native host operating systems, respectively. This is considered as the control group.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Group B (experiment 4 to 6) is the Linux container mode: run the same containerized Linux app in 3 different host operating systems.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Group C (experiment 7) is the Windows container mode: run the containerized Windows app in the Windows operating system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Group D (experiment 8) is the Kubernetes mode: run the containerized Linux app in Kubernetes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Host OS&lt;/th&gt;
          &lt;th&gt;App run as&lt;!-- raw HTML omitted --&gt;native app&lt;/th&gt;
          &lt;th&gt;App run as&lt;!-- raw HTML omitted --&gt;Linux Container&lt;/th&gt;
          &lt;th&gt;App run as&lt;!-- raw HTML omitted --&gt;Windows Container&lt;/th&gt;
          &lt;th&gt;‖&lt;/th&gt;
          &lt;th&gt;App run in&lt;!-- raw HTML omitted --&gt;K8s (Linux Container)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Linux&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/fswatch/tree/master/test-matrix/1_native_linux&#34;&gt;1&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/4_host_linux_container_linux&#34;&gt;4&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
          &lt;td&gt;‖&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/8_k8s_linux&#34;&gt;8&lt;/a&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Mac&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/fswatch/tree/master/test-matrix/2_native_mac&#34;&gt;2&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/5_host_mac_container_linux&#34;&gt;5&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;N/A&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Windows&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/3_native_win&#34;&gt;3&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/6_host_win_container_linux&#34;&gt;6&lt;/a&gt; (LCOW)&lt;/td&gt;
          &lt;td&gt;&lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/7_host_win_container_win&#34;&gt;7&lt;/a&gt; (WCOW)&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;group-a-native-mode&#34;&gt;Group A: native mode&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start with the native mode as the control group. We&amp;rsquo;ll see how it works in the traditional world of Linux, Mac, and Windows.&lt;/p&gt;
&lt;p&gt;To make life easier, I&amp;rsquo;m using the &lt;a href=&#34;https://github.com/fsnotify/fsnotify&#34;&gt;fsnotify&lt;/a&gt; library to unify a variety of underlying operating system APIs (e.g., &lt;a href=&#34;https://en.wikipedia.org/wiki/Inotify&#34;&gt;&lt;code&gt;inotify&lt;/code&gt;&lt;/a&gt; in Linux, &lt;a href=&#34;https://en.wikipedia.org/wiki/Kqueue&#34;&gt;&lt;code&gt;kqueue&lt;/code&gt;&lt;/a&gt; in macOS, and &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readdirectorychangesw&#34;&gt;&lt;code&gt;ReadDirectoryChangesW&lt;/code&gt;&lt;/a&gt; in Windows).  Statically-linked binaries for the 3 platforms are generated with the Go compiler 1.12.5:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2,943,200 (bytes) &lt;code&gt;fswatch-linux-x86_64&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;2,861,360 (bytes) &lt;code&gt;fswatch-mac&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;2,914,304 (bytes) &lt;code&gt;fswatch-x86_64.exe&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These experiments are easy to try by yourself. Take experiment &lt;a href=&#34;https://github.com/William-Yeh/fswatch/tree/master/test-matrix/1_native_linux&#34;&gt;1&lt;/a&gt; &amp;ldquo;run native Linux app in Linux host OS&amp;rdquo; for example:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/250732&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/250732.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In this group, changes in the file system can be tracked successfully by their native API mechanisms, respectively.&lt;/p&gt;
&lt;h2 id=&#34;group-b-and-c-container-mode&#34;&gt;Group B and C: container mode&lt;/h2&gt;
&lt;p&gt;Containers make things a little bit complicated.&lt;/p&gt;
&lt;p&gt;TL;DR: &lt;em&gt;The LCOW version doesn&amp;rsquo;t work well.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When there&amp;rsquo;s a mismatch between host OS and container, &lt;code&gt;inotify&lt;/code&gt; may not work well.&lt;/p&gt;
&lt;p&gt;Take experiment &lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/6_host_win_container_linux&#34;&gt;6&lt;/a&gt; (LCOW) &amp;ldquo;run containerized Linux app in Windows host OS&amp;rdquo; for example. The &lt;a href=&#34;https://docs.docker.com/docker-for-windows/troubleshoot/#inotify-on-shared-drives-does-not-work&#34;&gt;document&lt;/a&gt; for Docker Desktop for Windows has a warning for us:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Inotify on shared drives does not work&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Currently, &lt;code&gt;inotify&lt;/code&gt; does not work on Docker Desktop for Windows. This becomes evident, for example, when an application needs to read/write to a container across a mounted drive. Instead of relying on filesystem &lt;code&gt;inotify&lt;/code&gt;, we recommend using polling features for your framework or programming language.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For Windows users, &lt;code&gt;inotify&lt;/code&gt; works well in the WCOW mode (experiment &lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/7_host_win_container_win&#34;&gt;7&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;On the other hand, Mac users are luckier.  Docker Desktop for Mac doesn&amp;rsquo;t have much trouble here (experiment &lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/5_host_mac_container_linux&#34;&gt;5&lt;/a&gt;) thanks to excellent implementation of &lt;strong&gt;osxfs&lt;/strong&gt;.  See &amp;ldquo;&lt;a href=&#34;https://docs.docker.com/docker-for-mac/osxfs/&#34;&gt;File system sharing (osxfs)&lt;/a&gt;&amp;rdquo; and &amp;ldquo;&lt;a href=&#34;https://docs.docker.com/docker-for-mac/osxfs-caching/&#34;&gt;Performance tuning for volume mounts (shared filesystems)&lt;/a&gt;&amp;rdquo; articles for more information.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;File system events&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Most &lt;code&gt;inotify&lt;/code&gt; events are supported in bind mounts, and likely &lt;code&gt;dnotify&lt;/code&gt; and &lt;code&gt;fanotify&lt;/code&gt; (though they have not been tested) are also supported. This means that file system events from macOS are sent into containers and trigger any listening processes there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;group-d-k8s-mode&#34;&gt;Group D: K8s mode&lt;/h2&gt;
&lt;p&gt;How about Kubernetes?  Does &lt;code&gt;inotify&lt;/code&gt; work well with the ConfigMap?&lt;/p&gt;
&lt;p&gt;Below is the demo for experiment &lt;a href=&#34;https://github.com/William-Yeh/fswatch/blob/master/test-matrix/8_k8s_linux&#34;&gt;8&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/250736&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/250736.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see in this demo, any changes in the ConfigMap will propagate to related pods in a couple of seconds, and &lt;code&gt;inotify&lt;/code&gt; will detect this event as well. &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h3 id=&#34;caution-about-symbolic-links&#34;&gt;Caution about symbolic links&lt;/h3&gt;
&lt;p&gt;In such situation, however, you should use &lt;code&gt;inotify&lt;/code&gt; to watch for &lt;em&gt;directories&lt;/em&gt; instead of merely for &lt;em&gt;files&lt;/em&gt;.  It is because Kubernetes may use symbolic links to point to versioned ConfigMap volumes, and &lt;code&gt;inotify&lt;/code&gt; doesn&amp;rsquo;t work well with such symbolic links. &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s retry the demo, but this time we&amp;rsquo;ll focus on the directory layout from the pod&amp;rsquo;s point of view.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://asciinema.org/a/251141&#34;&gt;&lt;img src=&#34;https://asciinema.org/a/251141.svg&#34; alt=&#34;asciicast&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The demo from &lt;a href=&#34;https://asciinema.org/a/251141?t=0:38&#34;&gt;0:38&lt;/a&gt; to 1:55 shows the directory layout from the pod&amp;rsquo;s point of view:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/mnt/site # ls -al
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;total 12
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxrwxrwx    3 root  root   4096 Jun 12 06:19 .
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxr-xr-x    1 root  root   4096 Jun 12 06:19 ..
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;drwxr-xr-x    2 root  root   4096 Jun 12 06:19 ..2019_06_12_06_19_15.187277003
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx    1 root  root     31 Jun 12 06:19 ..data -&amp;gt; ..2019_06_12_06_19_15.187277003
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lrwxrwxrwx    1 root  root     15 Jun 12 06:19 main.css -&amp;gt; ..data/main.css&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;Simply put, things go well if you&amp;rsquo;re inside the pod and watch for &lt;code&gt;/mnt/site&lt;/code&gt; directory, but may not go well if you try to watch for a specific file &lt;code&gt;/mnt/site/main.css&lt;/code&gt; since it is internally a symbolic link managed by Kubernetes.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;inotify&lt;/code&gt; mechanism works in the container and Kubernetes world, except for the LCOW case.&lt;/p&gt;
&lt;p&gt;If such a feature is needed in the LCOW setting, maybe you have to seek another workaround workflow; e.g., put &lt;code&gt;inotify&lt;/code&gt; mechanism outside the container, and propagate the event explicitly into the containers if any.  This is exactly what &lt;a href=&#34;https://skaffold.dev/&#34;&gt;Skaffold&lt;/a&gt; is doing.&lt;/p&gt;
&lt;p&gt;Also note that &lt;code&gt;inotify&lt;/code&gt; works better when ConfigMap is mounted as directories, rather than as merely files.&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      Series of Articles
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ Inotify in Containers&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2019/06/containers-and-env/&#34;&gt;Containers and Environment Variables&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;➌ &lt;a href=&#34;//william-yeh.net/post/2019/06/autoreload-from-configmap/&#34;&gt;Auto-Reload from ConfigMap&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Another analysis of ConfigMap hot-reload can be found in the article by Jimmy Song: “&lt;a href=&#34;https://jimmysong.io/kubernetes-handbook/concepts/configmap-hot-update.html&#34;&gt;ConfigMap 的热更新&lt;/a&gt;”.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://stackoverflow.com/questions/28769503/use-inotify-to-watch-a-file-with-multiple-symlinks&#34;&gt;Use INotify to watch a file with multiple symlinks&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>Kubernetes 的入門認知與導入策略</title>
      <link>//william-yeh.net/post/2019/05/k8s-lab/</link>
      <pubDate>Fri, 17 May 2019 12:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/05/k8s-lab/</guid>
      
        <description>&lt;p&gt;前天我在 &lt;a href=&#34;https://cloudsummit.ithome.com.tw/2019/lab.html#0001&#34;&gt;2019 台灣雲端大會&lt;/a&gt;帶了兩個場次，一個是現場實作場次，一個是經驗分享演講：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Lab / &lt;a href=&#34;https://github.com/William-Yeh/workshop-cloud2019&#34;&gt;給 RD 的 Kubernetes 初體驗&lt;/a&gt; (90 minutes)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Speech / &lt;a href=&#34;https://www.slideshare.net/williamyeh/when-dotnetmeetskubernetes-145557464&#34;&gt;當 .NET 遇到 Kubernetes&lt;/a&gt; (30 minutes)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;兩個場次，一言以蔽之，都圍繞在 Kubernetes 的入門認知與導入策略上。&lt;/p&gt;
&lt;h2 id=&#34;以問題解決角度看-kubernetes-導入&#34;&gt;以「問題解決」角度看 Kubernetes 導入&lt;/h2&gt;
&lt;p&gt;〈&lt;a href=&#34;https://www.slideshare.net/williamyeh/when-dotnetmeetskubernetes-145557464&#34;&gt;當 .NET 遇到 Kubernetes&lt;/a&gt;〉這場演講，是以「問題解決」的角度，探討導入 Kubernetes 的困難與策略，尤其是針對 .NET 族群。&lt;/p&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/145557464&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;
&lt;p&gt;整場演講的脈絡如下：&lt;/p&gt;
&lt;p&gt;① 為什麼要導入 Kubernetes？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我們的現況是什麼？&lt;/li&gt;
&lt;li&gt;外面的世界已經是什麼樣子？&lt;/li&gt;
&lt;li&gt;不正視差距，會有什麼影響？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;② 為什麼還 &lt;strong&gt;不&lt;/strong&gt; 導入 Kubernetes？&lt;/p&gt;
&lt;p&gt;我嘗試用&lt;a href=&#34;https://www.behaviormodel.org/&#34;&gt;法格行為模型&lt;/a&gt; (B=MAP) 來歸類問題原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;M&lt;/strong&gt;otivation / 我們真的認識 Kubernetes 真實的利益是什麼嗎？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;bility / 正確認識技術核心、外在因素、內在因素，才能正確評估我們的技術能力是否已經提升到足以擁抱 Kubernetes 的地步。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P&lt;/strong&gt;rompt / 是否有臨門一腳的驅動力？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;③ 有什麼建議的導入選項？&lt;/p&gt;
&lt;p&gt;我發現 Prajakta Joshi 的演講 &amp;ldquo;&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=NET206&#34;&gt;Strategies for Bringing Kubernetes, Istio, Traffic Director, and Envoy to Brownfield with Walmart, Google, Tetrate&lt;/a&gt;&amp;rdquo; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 已經給了很好的建議。因此，我引述她的論點，建議大家可以採用兩種路徑：(a) Container first and mesh next，(b) Mesh first and container next。&lt;/p&gt;
&lt;p&gt;我這場演講有開放錄影。等上線了，我會再補上連結。&lt;/p&gt;
&lt;h2 id=&#34;rd-也需要略懂-kubernetes&#34;&gt;RD 也需要略懂 Kubernetes&lt;/h2&gt;
&lt;p&gt;Kubernetes 是目前雲端環境的顯學。可是，傳統的程式，並不是原封不動搬上去，就能夠自動享受 Kubernetes 所宣稱的種種好處。新的環境，不僅需要新的 Ops 思維，也需要新的 Dev 思維。&lt;/p&gt;
&lt;p&gt;我設計〈&lt;a href=&#34;https://github.com/William-Yeh/workshop-cloud2019&#34;&gt;給 RD 的 Kubernetes 初體驗&lt;/a&gt;〉工作坊，嘗試以一個半小時的時間，從軟體研發者的角度，探討軟體的設計該做哪些最起碼的改變，並從實作中體驗 Kubernetes 引進的新觀念及新效益。&lt;/p&gt;
&lt;p&gt;我希望能夠讓學員從實例中體驗，傳統 web 應用程式在搬上 Kubernetes 時，可能會經歷哪些架構面的調整，才能享受新架構的效益。&lt;/p&gt;
&lt;p&gt;我試圖不只是 demo，也不只是讓大家能無腦照著做，還試圖進行一些觀念講解。短短一個半小時，野心太大，只好割捨原本已經準備好的 API Gateway 例子 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，集中在以下課題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;容器化&lt;/li&gt;
&lt;li&gt;微服務&lt;/li&gt;
&lt;li&gt;組態管理&lt;/li&gt;
&lt;li&gt;多重環境管理：本機端與雲端（以 GKE 為例）&lt;/li&gt;
&lt;/ul&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/145761572&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/William-Yeh/workshop-cloud2019&#34;&gt;範例程式&lt;/a&gt;也以疊代演進的形式，逐步添加 Kubernetes 功能，呼應〈&lt;a href=&#34;https://www.slideshare.net/williamyeh/when-dotnetmeetskubernetes-145557464&#34;&gt;當 .NET 遇到 Kubernetes&lt;/a&gt;〉演講所提出的 &amp;ldquo;Container first and mesh next&amp;rdquo; 導入策略。&lt;/p&gt;
&lt;p&gt;Container:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;1.0: Extracted from Microsoft Docs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2.0: Dockerize the app with simple Dockerfile and docker-compose.yml.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.0: Separate frontend and backend into 2 distinct containers.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kubernetes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;4.0: Support Kubernetes (locally).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;4.1: Use Kubernetes dashboard.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;5.0: Support ConfigMap and naming convention.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cloud（感謝&lt;a href=&#34;https://tw.linkedin.com/in/ericsk&#34;&gt;上官林傑&lt;/a&gt;大力支援 Google Cloud 的 redeem coupon）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;6.0: Support Kubernetes on the cloud (GKE for example).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;7.0: Support canary release.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可惜，一個半小時的時間還是太短了，最後面 30 分鐘其實是在趕進度，跳過了一些原本應該仔細講解的環節（譬如：ConfigMap、label &amp;amp; selector、ephemeral vs static external IP 的區分⋯⋯）。我再考慮另外找個社群的場子，辦一次較完整的 workshop 吧。完整的，應該會需要 2.5～3 小時。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2019-06-16 補充
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;一個月後，應 &lt;a href=&#34;https://www.meetup.com/GCPUG-Taipei/events/261797460/&#34;&gt;GCPUG Taipei&lt;/a&gt; 之邀，我辦了一場 3+1 小時的 Workshop，&lt;a href=&#34;https://www.slideshare.net/williamyeh/rd-kubernetes-gcpug-2019-06/&#34;&gt;投影片&lt;/a&gt;及&lt;a href=&#34;https://github.com/William-Yeh/workshop-gcpug201906/&#34;&gt;實作範例&lt;/a&gt;都有更新。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;希望這一場演講，一場實作工作坊，對大家有助益。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2019/04/next19-istio/&#34;&gt;Next ’19 的 Istio 場次重點摘要&lt;/a&gt;〉一文中，有介紹 Prajakta Joshi 在 Google Cloud Next ’19 另一場精彩的演講。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;關於 Kubernetes 的 API gateway，請參考〈&lt;a href=&#34;//william-yeh.net/post/2019/03/ingress-vs-ambassador/&#34;&gt;Nginx Ingress 與 Ambassador 簡易性能比較&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Next &#39;19 的 Istio 場次重點摘要</title>
      <link>//william-yeh.net/post/2019/04/next19-istio/</link>
      <pubDate>Fri, 19 Apr 2019 23:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/04/next19-istio/</guid>
      
        <description>&lt;p&gt;四月 9&amp;ndash;11 日去舊金山參加 Google Cloud 的 &lt;a href=&#34;https://cloud.withgoogle.com/next/sf/&#34;&gt;Next ’19&lt;/a&gt; 大會，收穫頗大。&lt;/p&gt;
&lt;p&gt;這場大會，同一時段就有近 30 場專題演講同時進行，議程滿滿，勢必得做取捨。基於工作需要及個人興趣，我主要選擇與容器相關的場次：service mesh、Windows containers、混合雲、資安實務。&lt;/p&gt;
&lt;p&gt;我發現，光是這些場次，就得花很大力氣去消化、實驗與應用。&lt;/p&gt;
&lt;p&gt;我們這些所謂的「台港團」會在 GCPUG Taipei 舉辦一場&lt;a href=&#34;https://www.meetup.com/GCPUG-Taipei/events/260555968/&#34;&gt;分享會&lt;/a&gt;。因為自己不克參加，便以這篇文章，針對我鎖定的核心議題：Istio，做一番重點摘要，以饗讀者。&lt;/p&gt;
&lt;p&gt;以下內容，不完全按照 Next ’19 的議程時間順序，而是依照我主觀的排列。&lt;/p&gt;
&lt;p&gt;看完後，對於 Istio 應該就有不錯的全面認知了。&lt;/p&gt;
&lt;h2 id=&#34;漸進式導入-istio&#34;&gt;漸進式導入 Istio&lt;/h2&gt;
&lt;p&gt;很有意思的演講，很適合作為 Istio 入門。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/0cgTHQFXYPQ?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=HYB102&#34;&gt;Incrementally Adopting Istio&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/0cgTHQFXYPQ?t=3m20s&#34;&gt;3:20&lt;/a&gt; - 微服務面臨的挑戰。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/0cgTHQFXYPQ?t=6m18s&#34;&gt;6:18&lt;/a&gt; - Istio 的 control plane 三大元件，就是設計來一一對應這些問題的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/0cgTHQFXYPQ?t=10m38s&#34;&gt;10:38&lt;/a&gt; - Istio 的 telemetry 機制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/0cgTHQFXYPQ?t=11m42s&#34;&gt;11:42&lt;/a&gt; - Istio 的 traffic 管理機制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/0cgTHQFXYPQ?t=15m10s&#34;&gt;15:10&lt;/a&gt; - Istio 的 security 機制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/0cgTHQFXYPQ?t=16m27s&#34;&gt;16:27&lt;/a&gt; - 在 GKE 安裝 Istio 的方法及使用建議。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/0cgTHQFXYPQ?t=19m11s&#34;&gt;19:11&lt;/a&gt; - 接下來就是一系列的漸進式示範。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;istio-的-traffic宏觀角度&#34;&gt;Istio 的 Traffic：宏觀角度&lt;/h2&gt;
&lt;p&gt;在 Istio + Envoy 體系中，是透過 control plane 的 Pilot 元件及 xDS 協定，去管理 data plane 的 Envoy 網路流量。&lt;/p&gt;
&lt;p&gt;以此為基礎，Google Cloud 推出 &lt;a href=&#34;https://cloud.google.com/traffic-director/&#34;&gt;Traffic Director&lt;/a&gt; 服務，用統一的 control plane、透過同樣的 xDSv2 API，去管理 GCP 能觸及的 GKE、GCE，甚至自建的 Kubernetes cluster；也藉此處理 GCP 之專屬特性。&lt;/p&gt;
&lt;p&gt;某種意義上，可以把 Traffic Director 視為將 Istio 的 Pilot 元件託管給 Google Cloud。&lt;/p&gt;
&lt;p&gt;這場演講，儘管旨在&lt;del&gt;廣告&lt;/del&gt;宣傳 Google 自家的 Traffic Director 服務，但講員之一 Prajakta Joshi 非常厲害，對於一般性的 service mesh 觀念也介紹得非常生動。&lt;/p&gt;
&lt;p&gt;這一場值得全程觀看。我僅摘錄部分重點。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/FUITCYMCEhU?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=NET207&#34;&gt;Traffic Director and Envoy-Based L7 ILB for Production-Grade Service Mesh and Istio&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=1m21s&#34;&gt;1:21&lt;/a&gt; - 很中肯的觀點：將 service mesh 視為 “&lt;strong&gt;SDN for services&lt;/strong&gt;”。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=4m45s&#34;&gt;4:45&lt;/a&gt; - Istio 簡介。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=5m48s&#34;&gt;5:48&lt;/a&gt; - 介紹 Istio 的 Pilot 流量管理議題。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=5m48s&#34;&gt;6:40&lt;/a&gt; - 正式介紹 Traffic Director。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=14m45s&#34;&gt;14:45&lt;/a&gt; - Live demo: global load balancing。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=23m45s&#34;&gt;23:45&lt;/a&gt; - 介紹 service mesh 流量控制的特色：“&lt;strong&gt;change traffic flow without changing code&lt;/strong&gt;”，以及 traffic splitting、traffic steering、fault injection、mirroring (shadowing)、load balancing、circuit breaking、outlier detection 等高檔特性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=29m39s&#34;&gt;29:39&lt;/a&gt; - Live demo: traffic splitting。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=35m37s&#34;&gt;35:37&lt;/a&gt; - 預告 Traffic Director 的產品路線圖。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FUITCYMCEhU?t=42m56s&#34;&gt;42:56&lt;/a&gt; - 某客戶的 monolith 階段性轉型經驗。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;講員 Prajakta Joshi 另一場演講 &amp;ldquo;&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=NET206&#34;&gt;Strategies for Bringing Kubernetes, Istio, Traffic Director, and Envoy to Brownfield with Walmart, Google, Tetrate&lt;/a&gt;&amp;rdquo; 也很棒，可惜並未釋出投影片及錄影。精彩內容，就留在我的手機相簿裡面啦。&lt;/p&gt;
&lt;h2 id=&#34;istio-的-traffic實踐角度&#34;&gt;Istio 的 Traffic：實踐角度&lt;/h2&gt;
&lt;p&gt;我聽了 Megan O&amp;rsquo;Keefe 兩場硬底子的演講。&lt;/p&gt;
&lt;p&gt;第一場演講，以大量實例現場展示 Istio 的 traffic rules。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/7cINRP0BFY8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=HYB201&#34;&gt;Istio in Production: Day 2 Traffic Routing&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=2m18s&#34;&gt;2:18&lt;/a&gt; - Istio 與 Envoy 簡介。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=9m13s&#34;&gt;9:13&lt;/a&gt; - Live demo: rollout。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=13m45s&#34;&gt;13:45&lt;/a&gt; - Live demo: content-based routing。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=16m48s&#34;&gt;16:48&lt;/a&gt; - Live demo: circuit breaking。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=20m46s&#34;&gt;20:46&lt;/a&gt; - Live demo: chaos testing。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=24m48s&#34;&gt;24:48&lt;/a&gt; - Live demo: ingress and egress。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=36m26s&#34;&gt;36:26&lt;/a&gt; - Istio 1.1 現況。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=37m18s&#34;&gt;37:18&lt;/a&gt; - Istio 導入建議：“&lt;strong&gt;start slow and incrementally&lt;/strong&gt;”。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7cINRP0BFY8?t=38m36s&#34;&gt;38:36&lt;/a&gt; - Istio 還能夠做什麼？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第二場演講，就更硬碰硬的處理 Istio 每天都可能遇到的幾個實踐問題，以及如何查找問題、解決問題的過程。三段 live demo，涵蓋 Istio control plane 的三大元件：Pilot、Mixer、Citadel，非常扎實。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/FbYBO7Pi2d8?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=HYB303&#34;&gt;Debugging Istio: How to Fix a Broken Service Mesh&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FbYBO7Pi2d8?t=0m35s&#34;&gt;0:35&lt;/a&gt; - Service mesh 是要解決甚麼問題？Istio 的 control plane 就是設計來一一對應這些問題的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FbYBO7Pi2d8?t=2m54s&#34;&gt;2:54&lt;/a&gt; - 可是，Istio 又會連帶引入哪些複雜度？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FbYBO7Pi2d8?t=4m46s&#34;&gt;4:46&lt;/a&gt; - Live demo: traffic management.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FbYBO7Pi2d8?t=20m47s&#34;&gt;20:47&lt;/a&gt; - Live demo: telemetry.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FbYBO7Pi2d8?t=27m58s&#34;&gt;27:58&lt;/a&gt; - Live demo: security.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/FbYBO7Pi2d8?t=44m23s&#34;&gt;44:23&lt;/a&gt; - 除錯工具推薦清單。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這兩場 Megan O&amp;rsquo;Keefe 的演講，雖然硬底子，卻十分具體，可操作性高，值得全程觀看。&lt;/p&gt;
&lt;h2 id=&#34;從-sre-角度看-istio&#34;&gt;從 SRE 角度看 Istio&lt;/h2&gt;
&lt;p&gt;這一場，只能說，非常非常非常精彩。&lt;/p&gt;
&lt;p&gt;對於讀過 Google 的 &lt;a href=&#34;https://landing.google.com/sre/books/&#34;&gt;&lt;em&gt;SRE&lt;/em&gt;&lt;/a&gt; 一書的人來說，看到 SLO、error budget 之類的觀念，居然可以在 Istio 上面如此實現，真是大開眼界。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/AKh8uuVCpFI?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=HYB309&#34;&gt;Understanding SLOs and Error Budgets With Istio&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/AKh8uuVCpFI?t=1m40s&#34;&gt;1:40&lt;/a&gt; - SLI/SLO/SLA 基本觀念。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/AKh8uuVCpFI?t=7m41s&#34;&gt;7:41&lt;/a&gt; - &amp;ldquo;uptime&amp;rdquo; 的新觀點。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/AKh8uuVCpFI?t=9m04s&#34;&gt;9:04&lt;/a&gt; - 將 error budget 視為 “&lt;strong&gt;amount of SLOs you can spend&lt;/strong&gt;”。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/AKh8uuVCpFI?t=13m49s&#34;&gt;13:49&lt;/a&gt; - Live demo!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/AKh8uuVCpFI?t=28m02s&#34;&gt;28:02&lt;/a&gt; - 客戶證言：Schlumberger 公司。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;把-vm-也帶進-service-mesh&#34;&gt;把 VM 也帶進 Service Mesh&lt;/h2&gt;
&lt;p&gt;Service mesh 並不是容器的專利；古老的 VM 其實也可以納入治理體系。&lt;/p&gt;
&lt;p&gt;透過 Istio 的 &lt;a href=&#34;https://istio.io/docs/setup/kubernetes/additional-setup/mesh-expansion/&#34;&gt;&lt;strong&gt;mesh expansion&lt;/strong&gt;&lt;/a&gt; 機制，VM 只要安裝 node agent 及 Envoy proxy，即可登記為 Kubernetes/Istio cluster 的 &lt;a href=&#34;https://istio.io/docs/reference/config/networking/v1alpha3/service-entry/&#34;&gt;service entry&lt;/a&gt; 資源，進行 service discovery 等互動。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/2czElo8a7FM?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=HYB308&#34;&gt;Istio Service Mesh for VM Native&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/2czElo8a7FM?t=8m0s&#34;&gt;8:00&lt;/a&gt; - 介紹 Istio 的 mesh expansion 機制。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/2czElo8a7FM?t=11m04s&#34;&gt;11:04&lt;/a&gt; - 具體步驟。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/2czElo8a7FM?t=13m23s&#34;&gt;13:23&lt;/a&gt; - Live demo!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;windows-containers&#34;&gt;Windows Containers&lt;/h2&gt;
&lt;p&gt;自從 3 月底 Kubernetes 1.14 宣布正式支援 Windows 之後&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，我就很期待到 Next ’19 現場眼見為憑。&lt;/p&gt;
&lt;p&gt;這一場值得全程觀看。我僅摘錄部分重點。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/C4kW9uLmefU?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=HYB108&#34;&gt;Windows Containers in Google Kubernetes Engine&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/C4kW9uLmefU?t=7m50s&#34;&gt;7:50&lt;/a&gt; - &amp;ldquo;I have a dream&amp;hellip;&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/C4kW9uLmefU?t=12m15s&#34;&gt;12:15&lt;/a&gt; - Windows host OS and base image requirements&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/C4kW9uLmefU?t=17m23s&#34;&gt;17:23&lt;/a&gt; - Which to containerize?&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/C4kW9uLmefU?t=22m14s&#34;&gt;22:14&lt;/a&gt; - Kubernetes 1.14 stable supports Windows containers and Windows Server 2019&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/C4kW9uLmefU?t=25m44s&#34;&gt;25:44&lt;/a&gt; - Limitations for Windows containers (for now)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/C4kW9uLmefU?t=28m16s&#34;&gt;28:16&lt;/a&gt; - GKE &amp;ldquo;is working on supporting Windows containers&amp;rdquo; (preview now)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/C4kW9uLmefU?t=30m40s&#34;&gt;30:40&lt;/a&gt; - Live demo!&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://youtu.be/C4kW9uLmefU?t=37m0s&#34;&gt;37:00&lt;/a&gt; - Early Access Program (EAP)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;api-視角&#34;&gt;API 視角&lt;/h2&gt;
&lt;p&gt;不管你想在容器化、微服務、service mesh 路線走到多遠，「API 管理」一直都是需要持續關注的一環。&lt;/p&gt;
&lt;p&gt;針對這議題，Next ’19 是以 &lt;a href=&#34;https://cloud.google.com/apigee/&#34;&gt;Apigee&lt;/a&gt; 為主軸&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，分別介紹 Apigee 如何與 service mesh 和 serverless 技術搭配運用。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/IblDMVwSSk4?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=HYB319&#34;&gt;APIs, Microservices, and the Service Mesh&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/IblDMVwSSk4?t=3m21s&#34;&gt;3:21&lt;/a&gt; - 介紹 mTLS。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/IblDMVwSSk4?t=7m06s&#34;&gt;7:06&lt;/a&gt; - 用 Istio 在 control plane 層次確保 mTLS 之類的 policy。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/IblDMVwSSk4?t=12m47s&#34;&gt;12:47&lt;/a&gt; - 介紹 service mesh 時代的 API 管理架構。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/IblDMVwSSk4?t=33m09s&#34;&gt;33:09&lt;/a&gt; - 什麼時候才需要 service mesh？&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/7fcpwM-8qPo?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;【演講】&lt;a href=&#34;https://cloud.withgoogle.com/next/sf/sessions?session=SVR102&#34;&gt;API Management for Serverless and Multi-Cloud&lt;/a&gt;&lt;!-- raw HTML omitted --&gt;
【重點摘要】&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7fcpwM-8qPo?t=13m35s&#34;&gt;13:35&lt;/a&gt; - 示範 Cloud Run 與 Apigee。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/7fcpwM-8qPo?t=24m15s&#34;&gt;24:15&lt;/a&gt; - 示範 Cloud Functions 與 Apigee。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這麼多乾貨，值得花點力氣好好消化。&lt;/p&gt;
&lt;h2 id=&#34;投影片&#34;&gt;投影片&lt;/h2&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2019-07-02 補充
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;兩個月後，應 GCPUG Taipei 之邀，我還是在 &lt;a href=&#34;https://www.meetup.com/GCPUG-Taipei/events/262584153/&#34;&gt;Meetup #48&lt;/a&gt; 給了一場分享。投影片在此：&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement/&#34;&gt;Kubernetes 1.14: Production-level support for Windows Nodes, Kubectl Updates, Persistent Local Volumes GA&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Apigee 於 2016 年被 Google 併購。詳見〈&lt;a href=&#34;https://www.ithome.com.tw/news/108342&#34;&gt;Google 以 6.25 億美元收購 Apigee，強化 API 管理服務&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>在 WSL 裡使用 Ansible &#43; Vagrant</title>
      <link>//william-yeh.net/post/2019/04/wsl-ansible-vagrant/</link>
      <pubDate>Thu, 18 Apr 2019 23:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/04/wsl-ansible-vagrant/</guid>
      
        <description>&lt;p&gt;既然要開始在 Windows 上沿用 Mac 及 Unix 的命令列工具習慣&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，免不了要處理 &lt;a href=&#34;https://github.com/ansible/ansible&#34;&gt;Ansible&lt;/a&gt; 及 &lt;a href=&#34;https://www.vagrantup.com/&#34;&gt;Vagrant&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;雖然這兩個軟體都有對應的 Windows 版本，但據我以前的經驗，卡卡的，有許多小地雷；畢竟這些發跡自泛 Unix 家族的軟體，不是那麼容易無縫移植到對命令列不友善的 Windows 家族。&lt;/p&gt;
&lt;p&gt;如今 Windows 已經有 &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/&#34;&gt;WSL (Windows Subsystem for Linux)&lt;/a&gt; 機制，是否可以更無痛享用 Ansible 及 Vagrant 呢？&lt;/p&gt;
&lt;p&gt;可以的。&lt;/p&gt;
&lt;p&gt;大體而言，我們會兵分二路：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;在 Windows 上，會安裝 &lt;a href=&#34;https://www.virtualbox.org/&#34;&gt;VirtualBox&lt;/a&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 WSL 上，會安裝 &lt;a href=&#34;https://www.vagrantup.com/&#34;&gt;Vagrant&lt;/a&gt; 及 &lt;a href=&#34;https://github.com/ansible/ansible&#34;&gt;Ansible&lt;/a&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;虛擬機選項一virtualbox&#34;&gt;虛擬機選項一：VirtualBox&lt;/h2&gt;
&lt;p&gt;用慣 Mac 或 Linux 的人，可能會想沿用 &lt;a href=&#34;https://www.virtualbox.org/&#34;&gt;VirtualBox&lt;/a&gt; 虛擬機軟體。畢竟 VirtualBox 是同屬開源生態系的一員，和其他開源軟體的相容性最高。&lt;/p&gt;
&lt;p&gt;你可以直接去官方網站&lt;a href=&#34;https://www.virtualbox.org/wiki/Downloads&#34;&gt;下載&lt;/a&gt;安裝檔（VirtualBox 本體，以及 VirtualBox Extension Pack），或是直接透過 Chocolatey 套件管理工具來&lt;a href=&#34;https://chocolatey.org/packages/virtualbox&#34;&gt;安裝&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:\&amp;gt; choco install virtualbox&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;安裝完後，還有一關要克服。&lt;/p&gt;
&lt;p&gt;一般來說，在同一個 host OS 上，同一時間，只能有一個底層虛擬機制存在（除非有像「巢狀虛擬化」之類的黑魔法……吧？）。因此，VirtualBox 無法與 Windows 官方欽定的 Hyper-V 機制同時並存，一山不容二虎&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;如果決定要使用 VirtualBox，請用管理者權限執行以下命令，暫時關閉 Hyper-V 功能&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:&amp;gt; dism.exe /Online /Disable-Feature:Microsoft-Hyper-V
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:&amp;gt; bcdedit /set hypervisorlaunchtype off&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;這麼做的缺點是：由於 Docker Desktop for Windows 會用到 Hyper-V 機制，所以，關閉了 Hyper-V，等於是關閉了 Docker Desktop 的使用權。如果稍後還想使用 Docker Desktop，就得手動恢復 Hyper-V 功能：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:&amp;gt; dism.exe /Online /Enable-Feature:Microsoft-Hyper-V-All
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:&amp;gt; bcdedit /set hypervisorlaunchtype auto&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;你可能需要在 Hyper-V 與 VirtualBox 模式之間來回切換，也需要重新開機。&lt;/p&gt;
&lt;h2 id=&#34;虛擬機選項二hyper-v&#34;&gt;虛擬機選項二：Hyper-V&lt;/h2&gt;
&lt;p&gt;在 Windows 上面玩 VirtualBox 這麼麻煩，換成 Hyper-V 會不會比較省事？&lt;/p&gt;
&lt;p&gt;很可惜，我在 &amp;ldquo;Hyper-V Administrators&amp;rdquo; 這一關觸礁了。嘗試一些可能的解法&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;，都無效。&lt;/p&gt;
&lt;p&gt;真的有需要時，再回來研究吧。&lt;/p&gt;
&lt;h2 id=&#34;vagrant&#34;&gt;Vagrant&lt;/h2&gt;
&lt;p&gt;直接比照 Linux 安裝 Vagrant 的方法。&lt;/p&gt;
&lt;p&gt;請在 WSL 底下，直接去官方網站&lt;a href=&#34;https://www.vagrantup.com/downloads.html&#34;&gt;下載&lt;/a&gt;安裝檔，或是用 Apt 之類的套件管理系統來安裝。&lt;/p&gt;
&lt;p&gt;安裝完畢，請根據官方網站的&lt;a href=&#34;https://www.vagrantup.com/docs/other/wsl.html&#34;&gt;建議&lt;/a&gt;設定環境變數。尤其是 &lt;code&gt;VAGRANT_WSL_ENABLE_WINDOWS_ACCESS&lt;/code&gt; 這一項：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS=&amp;#34;1&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;ansible&#34;&gt;Ansible&lt;/h2&gt;
&lt;p&gt;直接比照 Linux 安裝 Ansible 的方法。&lt;/p&gt;
&lt;p&gt;請在 WSL 底下，照著官方網站的&lt;a href=&#34;https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-the-control-machine&#34;&gt;安裝步驟&lt;/a&gt;來執行。譬如說，在 Debian/Ubuntu 系列下，可以用 Apt 套件管理系統來安裝。&lt;/p&gt;
&lt;h2 id=&#34;ansible--vagrant&#34;&gt;Ansible + Vagrant&lt;/h2&gt;
&lt;p&gt;現在，試試看把 Ansible 和 Vagrant 結合起來！&lt;/p&gt;
&lt;p&gt;先準備好 &lt;code&gt;Vagrantfile&lt;/code&gt; 檔案：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-ruby&#34; data-lang=&#34;ruby&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;Vagrant&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;configure(&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;) &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;config&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  config&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;vm&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;box &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;bento/ubuntu-18.04&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  config&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;vm&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;network &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;forwarded_port&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;guest&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;80&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;host&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;8080&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  config&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;vm&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;provision &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ansible&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;ansible&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     ansible&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;compatibility_mode &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;2.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#75715e&#34;&gt;#ansible.verbose = &amp;#34;vvv&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     ansible&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;playbook &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;playbook.yml&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     ansible&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;become &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;還有 Ansible 的 &lt;code&gt;playbook.yml&lt;/code&gt; 檔案：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;hosts&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;all&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;become&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;tasks&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;install nginx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;apt&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;name=nginx state=present update_cache=yes&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;試著啟動看看：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% vagrant up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;如果一切順利，你可以在 &lt;code&gt;http://localhost:8080/&lt;/code&gt; 看到 Nginx 歡迎畫面。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;在 Docker + Kubernetes 時代，用到 Ansible 的機會愈來愈少了，Vagrant 更是如此；不過，保有這種工具，在處理還來不及跟上腳步的舊系統仍然很管用。因此，花一點功夫湊出堪用的組合，希望能有順手的 WSL 環境。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;這段故事，詳見〈&lt;a href=&#34;//william-yeh.net/post/2019/03/wsl-cmder-zsh/&#34;&gt;在 Windows 上復刻 Mac 使用習慣&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;技術上來說，Hyper-V 是屬於 type-1 hypervisor，VirtualBox 是屬於 type-2 hypervisor。詳見維基百科 &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Hypervisor&#34;&gt;Hypervisor&lt;/a&gt;&amp;rdquo; 條目。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;在 Windows 上關閉 Hyper-V 機制，請參考以下文章：“&lt;a href=&#34;https://www.sysprobs.com/solved-vt-x-is-not-available-verr-vmx-no-vmx-in-windows-10-virtualbox&#34;&gt;(Solved) VT-x is Not Available (verr_vmx_no_vmx) in Windows 10 – but Available for Oracle VirtualBox&lt;/a&gt;”、〈&lt;a href=&#34;https://blog.csdn.net/imilano/article/details/83038682&#34;&gt;Win10 10月更新 VirtualBox VT-x is not available (VERR_VMX_NO_VMX). 解决&lt;/a&gt;〉、“&lt;a href=&#34;https://forums.virtualbox.org/viewtopic.php?f=38&amp;amp;t=89791&#34;&gt;[Solved] VT-x is not available (VERR_VMX_NO_VMX)&lt;/a&gt;”。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;當 Vagrant 在使用 Hyper-V 時，會出現 &amp;ldquo;Hyper-V Administrators&amp;rdquo; 權限問題。我嘗試以下幾篇文章，可惜仍未解決：“&lt;a href=&#34;https://github.com/hashicorp/vagrant/issues/4503&#34;&gt;Vagrant issue #378&lt;/a&gt;”、“&lt;a href=&#34;https://blogs.msdn.microsoft.com/virtual_pc_guy/2014/06/11/allowing-non-administrators-to-control-hyper-vupdated/&#34;&gt;Allowing non-Administrators to control Hyper-V–Updated&lt;/a&gt;”、“&lt;a href=&#34;https://dev.to/nicolus/getting-homestead-to-play-nice-with-hyper-v-4202&#34;&gt;Getting Homestead to play nice with Hyper-V&lt;/a&gt;”。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>WSLtty &#43; tmux 組合技</title>
      <link>//william-yeh.net/post/2019/04/wsltty-tmux/</link>
      <pubDate>Wed, 17 Apr 2019 22:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/04/wsltty-tmux/</guid>
      
        <description>&lt;p&gt;在 Windows 10 上面使用 WSL 已經一個月了&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。小狀況也就罷了，但 &lt;a href=&#34;https://cmder.net/&#34;&gt;Cmder&lt;/a&gt; 不夠穩定的顯示邏輯卻最讓我頭痛，在視窗尺寸變化時，無法正確處理字元位置。更令人費解的是，即使是其他狀似更華麗（也更耗資源）的替代方案，也仍然有這些問題&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;既然酷炫的終端機競品問題多多，乾脆回歸極簡的 WSLtty&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;，並混搭 tmux&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; 來彌補。可惜，畢竟是組合技，無法完全複製 Mac 的 iTerm2 使用經驗。&lt;/p&gt;
&lt;p&gt;此事古難全。&lt;/p&gt;
&lt;h2 id=&#34;wsltty-剪貼簿&#34;&gt;WSLtty 剪貼簿&lt;/h2&gt;
&lt;p&gt;在 X Window 或 Mac 的終端機，只要按下滑鼠右鍵就能夠 paste 文字。如果在 WSLtty 上也想這麼玩，請在 &lt;code&gt;%APPDATA%\wsltty\config&lt;/code&gt; 設定檔加上這一行：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RightClickAction=paste&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;tmux-與-zsh&#34;&gt;Tmux 與 zsh&lt;/h2&gt;
&lt;p&gt;啟動 tmux 時，似乎並不會根據 &lt;code&gt;/etc/passwd&lt;/code&gt; 的資訊來喚起自訂的 shell，而是一律喚起 bash。&lt;/p&gt;
&lt;p&gt;解決方法是，在 &lt;code&gt;~/.tmux.conf&lt;/code&gt; 加上這一行：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set-option -g default-shell /bin/zsh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;tmux-的-pane&#34;&gt;Tmux 的 pane&lt;/h2&gt;
&lt;p&gt;用慣 iTerm2 的我，對 tmux 的 pane 功能不太習慣。&lt;/p&gt;
&lt;p&gt;譬如說，在 tmux 新增 pane 或 window 時，不會自動帶入目前的目錄 &lt;code&gt;$PWD&lt;/code&gt;，而是一律帶入 &lt;code&gt;$HOME&lt;/code&gt;，很不方便。Tmux 預設的組合鍵 &lt;code&gt;&amp;lt;prefix&amp;gt; %&lt;/code&gt; 及 &lt;code&gt;&amp;lt;prefix&amp;gt; &amp;quot;&lt;/code&gt; 難記又難按，也很令人頭痛。&lt;/p&gt;
&lt;p&gt;因此，我綜合多人的做法&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;，解決目錄問題，換成好記好按的組合鍵，更可用方向鍵來切換 pane：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Create new window (tab) with current path
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;unbind c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bind -n M-t new-window -c &amp;#39;#{pane_current_path}&amp;#39;  # mimic for iTerm2 habit
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Split panes with current path
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# @see https://unix.stackexchange.com/a/247449
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;unbind &amp;#39;&amp;#34;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;unbind &amp;#39;%&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bind -n M-d split-window -h -c &amp;#39;#{pane_current_path}&amp;#39;  # Split panes horizontal
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bind -n M-D split-window -v -c &amp;#39;#{pane_current_path}&amp;#39;  # Split panes vertically
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Switch panes using Alt-arrow without prefix
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bind -n M-Left  select-pane -L
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bind -n M-Right select-pane -R
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bind -n M-Up    select-pane -U
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bind -n M-Down  select-pane -D&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;h2 id=&#34;tmux-plugin-manager&#34;&gt;Tmux Plugin Manager&lt;/h2&gt;
&lt;p&gt;Tmux 設定太多了，就有人寫了外掛管理系統 &lt;a href=&#34;https://github.com/tmux-plugins/tpm&#34;&gt;Tmux Plugin Manager&lt;/a&gt;。雖然目前我還用不到，但還是先安裝，以備不時之需。&lt;/p&gt;
&lt;p&gt;首先，下載 TPM：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;將以下幾行加到 &lt;code&gt;.tmux.conf&lt;/code&gt; 最後面：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# List of plugins
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -g @plugin &amp;#39;tmux-plugins/tpm&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -g @plugin &amp;#39;tmux-plugins/tmux-sensible&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Initialize TMUX plugin manager
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# (keep this line at the very bottom of tmux.conf)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;run -b &amp;#39;~/.tmux/plugins/tpm/tpm&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Tmux 還有很多高段的功能，以後有需要再研究吧。&lt;/p&gt;
&lt;p&gt;如此這般拼湊起來，雖然還不能完全複刻 Mac 的 iTerm2 使用經驗，但也已經算是可以接受了。當然啦，私心還是希望 Cmder 或 Hyper 能夠好好解決顯示問題，就不必動用 tmux 了。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;這段故事，詳見〈&lt;a href=&#34;//william-yeh.net/post/2019/03/wsl-cmder-zsh/&#34;&gt;在 Windows 上復刻 Mac 使用習慣&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;關於其他更華麗，卻也更耗資源的 Windows 終端機方案，可參考這幾篇介紹文章：〈&lt;a href=&#34;https://github.com/spencerwooo/dowww&#34;&gt;在 Windows 上面用 WSL 优雅开发&lt;/a&gt;〉、“&lt;a href=&#34;https://nickjanetakis.com/blog/conemu-vs-hyper-vs-terminus-vs-mobaxterm-terminator-vs-ubuntu-wsl&#34;&gt;ConEmu vs Hyper vs Terminus vs MobaXTerm Terminator vs Ubuntu WSL&lt;/a&gt;”。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;關於 &lt;a href=&#34;https://github.com/mintty/wsltty&#34;&gt;WSLtty&lt;/a&gt;，可參考保哥的〈&lt;a href=&#34;https://blog.miniasp.com/post/2019/02/09/Useful-tool-WSLtty-Mintty-as-a-terminal-for-WSL&#34;&gt;介紹好用工具：WSLtty (Mintty as a terminal for WSL)&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;關於 &lt;a href=&#34;https://github.com/tmux/tmux&#34;&gt;tmux&lt;/a&gt;，可參考這幾篇介紹文章：〈&lt;a href=&#34;https://5xruby.tw/posts/tmux/&#34;&gt;tmux ，不只是 terminal multiplexer&lt;/a&gt;〉、〈&lt;a href=&#34;https://andyyou.github.io/2017/11/27/tmux-notes/&#34;&gt;tmux 快速入門筆記&lt;/a&gt;〉、〈&lt;a href=&#34;https://larrylu.blog/tmux-33a24e595fbc&#34;&gt;終端機 session 管理神器 — tmux&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Shubham 提供的&lt;a href=&#34;https://unix.stackexchange.com/a/247449&#34;&gt;做法&lt;/a&gt;，可讓新開的 pane 及 window 保持在目前所在的目錄。Ham Vocke 的&lt;a href=&#34;https://www.hamvocke.com/blog/a-guide-to-customizing-your-tmux-conf/&#34;&gt;文章&lt;/a&gt;也介紹幾種有趣的 tmux 設定。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>給 RD 的 Kubernetes 初體驗</title>
      <link>//william-yeh.net/courses/k8s-workship-cloudsummit2019/</link>
      <pubDate>Tue, 02 Apr 2019 16:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/courses/k8s-workship-cloudsummit2019/</guid>
      
        <description>&lt;p&gt;&lt;strong&gt;活動名稱&lt;/strong&gt;：給 RD 的 Kubernetes 初體驗&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;時間&lt;/strong&gt;：2019-05-15 (三) / 11:00&amp;ndash;12:30&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;會議&lt;/strong&gt;：&lt;a href=&#34;https://cloudsummit.ithome.com.tw/2019/lab.html#0001&#34;&gt;台灣雲端大會 (Cloud Edge Summit 2019)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;課程簡介&#34;&gt;課程簡介&lt;/h2&gt;
&lt;p&gt;Kubernetes 是目前雲端環境的顯學。可是，傳統的程式，並不是原封不動搬上去，就能夠自動享受 Kubernetes 所宣稱的種種好處。&lt;/p&gt;
&lt;p&gt;新的環境，不僅需要新的 Ops 思維，也需要新的 Dev 思維。我們將以一個半小時的時間，從軟體研發者的角度，探討軟體的設計該做哪些最起碼的改變，從實作中體驗 Kubernetes 引進的新觀念及新效益。&lt;/p&gt;
&lt;h2 id=&#34;課程目標&#34;&gt;課程目標&lt;/h2&gt;
&lt;p&gt;從實例中體驗，傳統 web 應用程式在搬上 Kubernetes 時，可能會經歷哪些架構面的調整，才能享受新架構的效益：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;容器化&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;微服務&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;組態管理&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;API gateway&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多重環境管理：本機端與雲端（以 GKE 為例）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;課程架構&#34;&gt;課程架構&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;主題&lt;/th&gt;
          &lt;th&gt;內容簡介&lt;/th&gt;
          &lt;th&gt;類型&lt;/th&gt;
          &lt;th&gt;時間(分)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;1. 基本觀念&lt;/td&gt;
          &lt;td&gt;快速介紹 Kubernetes 基本觀念&lt;/td&gt;
          &lt;td&gt;簡報介紹&lt;/td&gt;
          &lt;td&gt;10&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2. 本機端實作&lt;/td&gt;
          &lt;td&gt;移植 web 軟體至本機端 Kubernetes&lt;/td&gt;
          &lt;td&gt;實機操作&lt;/td&gt;
          &lt;td&gt;50&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;3. 雲端實作&lt;/td&gt;
          &lt;td&gt;將 Kubernetes 成果送上雲端&lt;/td&gt;
          &lt;td&gt;實機操作&lt;/td&gt;
          &lt;td&gt;20&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;4. 總結&lt;/td&gt;
          &lt;td&gt;Kubernetes 微服務要點總結&lt;/td&gt;
          &lt;td&gt;簡報介紹&lt;/td&gt;
          &lt;td&gt;10&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;注意事項&#34;&gt;注意事項&lt;/h2&gt;
&lt;h3 id=&#34;學員能力要求&#34;&gt;學員能力要求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;須具備簡單的 Web 前後端觀念。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;須具備 Docker、Docker Compose、git 基本操作能力。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;學員需知&#34;&gt;學員需知&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;請先在自備筆電中安裝 &lt;a href=&#34;https://www.docker.com/products/docker-desktop&#34;&gt;Docker Desktop&lt;/a&gt;，並開啟其中的 Kubernetes 功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;本課程有一部分實作活動會使用 Google Kubernetes Engine (GKE) 及 Container Registry (GCR) 服務。為了讓現場體驗活動順暢，請學員事先申請好 &lt;a href=&#34;https://cloud.google.com/&#34;&gt;Google Cloud Platform&lt;/a&gt; 帳號，並自主練習約 45 分鐘的 “&lt;a href=&#34;https://www.qwiklabs.com/focuses/2794?parent=catalog&#34;&gt;A Tour of Qwiklabs and the Google Cloud Platform&lt;/a&gt;” 免費活動，確保你在來到活動現場之前，就已熟悉 &lt;a href=&#34;https://cloud.google.com/shell/&#34;&gt;Google Cloud Shell&lt;/a&gt; 的操作環境。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;本實機操作課程由【Google Developers 贊助】。如果你是第一次用 GCP account 或還在 Free Trial 期間內，請繼續用 Free Trial 來操作；如果你已經是正式的 account，活動現場將提供你足夠額度的 coupon 來使用。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
      
    </item>
    
    <item>
      <title>Nginx Ingress 與 Ambassador 簡易性能比較</title>
      <link>//william-yeh.net/post/2019/03/ingress-vs-ambassador/</link>
      <pubDate>Fri, 29 Mar 2019 23:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/03/ingress-vs-ambassador/</guid>
      
        <description>&lt;p&gt;API gateway 是微服務環境，甚至 service mesh 的要角 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;在 Kubernetes 上面，API gateway 選項眾多。有像 HAProxy 及 Nginx 這些石器時代老傢伙跨足過來，也有打從一開始就走 cloud native 路線的後起之秀。&lt;/p&gt;
&lt;p&gt;該如何選擇？&lt;/p&gt;
&lt;p&gt;根據 Steven Acreman 寫的 &lt;a href=&#34;https://kubedex.com/ingress/&#34;&gt;Ingress 評比文章&lt;/a&gt;的看法：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The safest choice is &lt;a href=&#34;https://kubernetes.github.io/ingress-nginx/&#34;&gt;ingress-nginx&lt;/a&gt;&lt;/em&gt;. This is the one that most people use and it’s extremely reliable. Before you begin I’d recommend you read this blog to get ahead of some of the problems you may encounter.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;My vote for the coolest ingress definitely goes to &lt;a href=&#34;https://www.getambassador.io/&#34;&gt;Ambassador&lt;/a&gt;.&lt;/em&gt;  If you’re just running standard http based micro services and fancy living on the bleeding edge then you should definitely get Istio, Ambassador and Jaeger setup as a proof of concept.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;進一步研讀 Ambassador 相關資料 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，發現他們鎖定的 service mesh 路線很合我的胃口，站在 &lt;a href=&#34;https://www.envoyproxy.io/&#34;&gt;Envoy&lt;/a&gt; 巨人肩膀上更是聰明。不過，理論歸理論，我想親自試試看現在的 Ambassador 是否堪當大任？&lt;/p&gt;
&lt;p&gt;初步，我只先拿 &lt;a href=&#34;https://kubernetes.github.io/ingress-nginx/&#34;&gt;ingress-nginx&lt;/a&gt; 這個所謂的 “the safest choice” 作簡單的性能比較。將來有機會再進行更徹底的 chaos monkey 測試。&lt;/p&gt;
&lt;h2 id=&#34;實驗環境&#34;&gt;實驗環境&lt;/h2&gt;
&lt;p&gt;為了簡化實驗步驟，我直接採用 Google Cloud Platform 的 &lt;a href=&#34;https://cloud.google.com/kubernetes-engine/&#34;&gt;GKE&lt;/a&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Kubernetes 版本：1.11.7-gke.12&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Node：2 台 &lt;a href=&#34;https://cloud.google.com/compute/docs/machine-types#standard_machine_types&#34;&gt;n1-standard-1&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我選用的標靶軟體是 &lt;a href=&#34;https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/tree/master/hello-app&#34;&gt;hello-app&lt;/a&gt;，分別用以下兩種 API gateway 來對外提供服務介面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Nginx ingress 版本：0.23.0&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ambassador 版本：0.52.0&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最後，我利用 &lt;a href=&#34;https://github.com/William-Yeh/docker-boom&#34;&gt;boom&lt;/a&gt; 進行簡單的壓力測試。&lt;/p&gt;
&lt;h2 id=&#34;nginx-ingress&#34;&gt;Nginx ingress&lt;/h2&gt;
&lt;p&gt;為了簡單起見，我直接套用以下這份 Qwiklabs 的全部步驟：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.qwiklabs.com/focuses/872?parent=catalog&#34;&gt;GSP181 - NGINX Ingress Controller on Google Kubernetes Engine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;照著做完後，Nginx ingress 會在 GKE 開放一個公開的 http 服務存取點。&lt;/p&gt;
&lt;p&gt;我們可以先用 &lt;code&gt;kubectl get services&lt;/code&gt; 查看 API gateway 的 public IP 位址。假設是 &lt;code&gt;35.222.12.84&lt;/code&gt; 的話，這個服務路徑則是 &lt;code&gt;http://35.222.12.84/hello/&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;ambassador&#34;&gt;Ambassador&lt;/h2&gt;
&lt;p&gt;首先，仿造前面的 Qwiklabs 步驟，在 GKE 上建立起相同規模的 k8s cluster。也執行一份 &lt;a href=&#34;https://gist.githubusercontent.com/William-Yeh/0aab709e450b4442614ef87b0250260b/raw/daba0ba7e6b5561ec9af51a3ea020c79e572e34e/hello-app-service.yaml&#34;&gt;hello-app service&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;為了安裝 Ambassador，我們需要開啟 GKE 權限：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl create clusterrolebinding my-cluster-admin-binding  \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --clusterrole=cluster-admin  \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    --user=$(gcloud info --format=&amp;#34;value(config.account)&amp;#34;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;接下來，就是正常的 Ambassador 安裝步驟：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl create -f http://bit.ly/2UmsPuE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;此刻，我們終於可以透過 Ambassador，替 hello-app 設定 API gateway 規則：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% kubectl create -f https://bit.ly/2YyZzjO&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;照著做完後，Ambassador 會在 GKE 開放一個公開的 http 服務存取點。&lt;/p&gt;
&lt;p&gt;我們可以先用 &lt;code&gt;kubectl get services&lt;/code&gt; 查看 API gateway 的 public IP 位址。假設是 &lt;code&gt;35.224.99.169&lt;/code&gt; 的話，這個服務路徑則是 &lt;code&gt;http://35.224.99.169/hello2/&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;簡單的壓測&#34;&gt;簡單的壓測&lt;/h2&gt;
&lt;p&gt;為了簡單起見，我在 GCP 的 &lt;a href=&#34;https://cloud.google.com/shell/?hl=zh-tw&#34;&gt;Cloud Shell&lt;/a&gt; 進行壓測。我會對 Nginx ingress 及 Ambassador 兩種情況，各送出一萬個 API 存取要求。&lt;/p&gt;
&lt;p&gt;針對 Nginx ingress 的情況進行測試：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% docker run --rm  williamyeh/boom  \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -n 10000 -c 100  http://35.222.12.84/hello/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Summary:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Total:        16.2312 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Slowest:      0.3252 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Fastest:      0.1568 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Average:      0.1616 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Requests/sec: 616.0963
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Total data:   660000 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Size/request: 66 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status code distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [200] 10000 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Response time histogram:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.157 [1]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.174 [9803]  |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.190 [96]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.207 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.224 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.241 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.258 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.275 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.292 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.308 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.325 [100]   |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Latency distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  10% in 0.1576 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  25% in 0.1583 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  50% in 0.1593 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  75% in 0.1608 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  90% in 0.1632 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  95% in 0.1661 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  99% in 0.3152 secs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;針對 Ambassador 的情況進行測試：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% docker run --rm  williamyeh/boom  \
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    -n 10000 -c 100  http://35.224.99.169/hello2/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Summary:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Total:        16.8132 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Slowest:      0.3857 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Fastest:      0.1571 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Average:      0.1662 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Requests/sec: 594.7715
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Total data:   660000 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Size/request: 66 bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Status code distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [200] 10000 responses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Response time histogram:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.157 [1]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.180 [9595]  |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.203 [304]   |∎
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.226 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.249 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.271 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.294 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.317 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.340 [0]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.363 [8]     |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  0.386 [92]    |
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Latency distribution:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  10% in 0.1596 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  25% in 0.1607 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  50% in 0.1623 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  75% in 0.1656 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  90% in 0.1717 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  95% in 0.1786 secs
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  99% in 0.3596 secs&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;儘管不夠嚴謹，但仍可以約略看出 Ambassador 的性能已經逼近 Nginx ingress。以才兩歲半的 Envoy &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;、才滿兩歲的 Ambassador &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; 來說，已經很不容易了。&lt;/p&gt;
&lt;p&gt;這是一個值得開始嘗試的好物。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;對於 API gateway 來龍去脈感興趣的，可參考 Ricky 的文章〈&lt;a href=&#34;https://rickhw.github.io/2018/01/24/AWS/Study-Notes-Overview-API-Gateway/&#34;&gt;Overview API Gateway&lt;/a&gt;〉、Andrew 的文章〈&lt;a href=&#34;https://columns.chicken-house.net/2017/07/11/microservice8-case-study-p3/&#34;&gt;架構師觀點 - 轉移到微服務架構的經驗分享 (Part 3)&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;對於 Ambassador 早期發展歷程感興趣的，可參考他們寫的這兩篇文章：“&lt;a href=&#34;https://medium.com/@datawire/building-ambassador-an-open-source-api-gateway-on-kubernetes-and-envoy-33637a9fa6f8&#34;&gt;Building Ambassador, an Open Source API Gateway on Kubernetes and Envoy&lt;/a&gt;” 及 “&lt;a href=&#34;https://blog.getambassador.io/kubernetes-ingress-nodeport-load-balancers-and-ingress-controllers-6e29f1c44f2d&#34;&gt;Kubernetes Ingress 101: NodePort, Load Balancers, and Ingress Controllers&lt;/a&gt;”。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Envoy &lt;a href=&#34;https://github.com/envoyproxy/envoy/tree/v1.0.0&#34;&gt;1.0.0 版&lt;/a&gt;發布日期為 2016 年 9 月。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Ambassador &lt;a href=&#34;https://github.com/datawire/ambassador/blob/master/CHANGELOG.md&#34;&gt;0.1.3 版&lt;/a&gt;發布日期為 2017 年 3 月。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>在 Windows 上復刻 Mac 使用習慣</title>
      <link>//william-yeh.net/post/2019/03/wsl-cmder-zsh/</link>
      <pubDate>Thu, 14 Mar 2019 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/03/wsl-cmder-zsh/</guid>
      
        <description>&lt;p&gt;改用 Mac 已經六年了。現在要再回頭碰 Windows，還真有點不習慣。&lt;/p&gt;
&lt;p&gt;這年頭，許多軟體其實都有 Mac 及 Windows 版了：Chrome、Firefox、Slack、Evernote、Dropbox、VSCode……最大的差別，應該是終端機命令列工具。&lt;/p&gt;
&lt;p&gt;上古時代，需要靠 &lt;a href=&#34;https://www.cygwin.com/&#34;&gt;Cygwin&lt;/a&gt; 或 &lt;a href=&#34;http://www.mingw.org/&#34;&gt;MinGW&lt;/a&gt; 方案，才能勉強湊出一點點 Unix 的命令列感覺，但地雷超級多，難以作為嚴肅用途。後來，到了 2015 年，從保哥那邊知道有 &lt;a href=&#34;https://cmder.net/&#34;&gt;Cmder&lt;/a&gt; 這個好物 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，微軟又於 2016 年推出 &lt;a href=&#34;https://docs.microsoft.com/en-us/windows/wsl/&#34;&gt;WSL (Windows Subsystem for Linux)&lt;/a&gt; 機制，Windows 這邊似乎出現曙光，對 Unix 命令列愛好者展現出久違的吸引力。&lt;/p&gt;
&lt;p&gt;為了在 Windows 10 上面復刻我的 Mac 的體驗：&lt;a href=&#34;https://www.iterm2.com/&#34;&gt;iTerm2&lt;/a&gt; + &lt;a href=&#34;https://www.zsh.org/&#34;&gt;Zsh&lt;/a&gt; + &lt;a href=&#34;https://ohmyz.sh/&#34;&gt;Oh My ZSH&lt;/a&gt;，我試了幾天，把步驟整理如下。&lt;/p&gt;
&lt;h2 id=&#34;wsl&#34;&gt;WSL&lt;/h2&gt;
&lt;p&gt;請根據保哥的文章〈&lt;a href=&#34;https://blog.miniasp.com/post/2019/02/01/Useful-tool-WSL-Windows-Subsystem-for-Linux&#34;&gt;介紹好用工具：WSL (Windows Subsystem for Linux)&lt;/a&gt;〉進行以下步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;安裝 WSL。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安裝一個 Linux distribution。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第一次執行 WSL，並設定 Linux 的帳號密碼。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;zsh--oh-my-zsh&#34;&gt;Zsh + Oh My ZSH&lt;/h2&gt;
&lt;p&gt;在 WSL 中安裝 zsh 及 oh-my-zsh：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo apt-get install zsh
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo sh -c &amp;#34;$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;將 zsh 設為內定 shell：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% chsh -s $(which zsh)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;如果你的 zsh theme 含有許多特殊的符號字元，請順便安裝 &lt;a href=&#34;https://github.com/powerline/fonts&#34;&gt;Powerline&lt;/a&gt; 系列字型。&lt;/p&gt;
&lt;h2 id=&#34;cmder&#34;&gt;Cmder&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://cmder.net/&#34;&gt;Cmder&lt;/a&gt; 有「完整版」及「迷你版」兩種安裝方式。有了 WSL 之後，msysgit 可以退場，因此，我們只需安裝 Cmder 迷你版。&lt;/p&gt;
&lt;p&gt;用 Chocolatey 套件管理工具安裝比較簡單：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C:\&amp;gt; choco install cmdermini&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;細節請見 &lt;a href=&#34;https://chocolatey.org/packages/cmdermini&#34;&gt;https://chocolatey.org/packages/cmdermini&lt;/a&gt; 。&lt;/p&gt;
&lt;h2 id=&#34;整合-cmder-與-wsl&#34;&gt;整合 Cmder 與 WSL&lt;/h2&gt;
&lt;p&gt;為了讓 Cmder 以 WSL + Zsh 模式啟動，我們需要新增一個 Cmder 的 &amp;ldquo;Startup / Tasks&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;譬如說，我們可新增一個名叫 &lt;code&gt;{WSL::zsh}&lt;/code&gt; 的 task，將 command 寫成：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;set &amp;#34;PATH=%ConEmuBaseDirShort%\wsl;%PATH%&amp;#34; &amp;amp; %ConEmuBaseDirShort%\conemu-cyg-64.exe --wsl -C~ -cur_console:p:t:&amp;#34;zsh&amp;#34; -t zsh -l&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/03/cmder-wsl-zsh.png&#34; alt=&#34;新增 Cmder 啟動設定&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/03/cmder-wsl-zsh.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;新增 Cmder 啟動設定&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;存檔完畢，以後只要以 &lt;code&gt;{WSL::zsh}&lt;/code&gt; 模式啟動，Cmder 就會自動套用 WSL + zsh 組態。&lt;/p&gt;
&lt;p&gt;進一步的設定細節，請參考 &lt;a href=&#34;https://conemu.github.io/en/BashOnWindows.html&#34;&gt;https://conemu.github.io/en/BashOnWindows.html&lt;/a&gt; 一文。&lt;/p&gt;
&lt;h2 id=&#34;設定-cmder-熱鍵&#34;&gt;設定 Cmder 熱鍵&lt;/h2&gt;
&lt;p&gt;為了復刻出類似 Mac + iTerm2 的使用習慣，我會花一些時間調整 Cmder 熱鍵設定。請參考保哥的文章〈&lt;a href=&#34;https://blog.miniasp.com/post/2015/09/27/Useful-tool-Cmder&#34;&gt;介紹好用工具：Cmder (具有 Linux 溫度的 Windows 命令提示字元工具)&lt;/a&gt;〉進行熱鍵設定。&lt;/p&gt;
&lt;p&gt;在 Windows 與 WSL 之間進行複製貼上的剪貼簿操作時，常會遇到換行問題。此時我也會順便將 Ctrl-V 組合鍵的 “Paste mode #2” 設定成  “Multi lines” &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/03/cmder-paste.png&#34; alt=&#34;調整 Cmder 剪貼簿的換行處理方式&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/03/cmder-paste.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;調整 Cmder 剪貼簿的換行處理方式&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;檔案系統&#34;&gt;檔案系統&lt;/h2&gt;
&lt;p&gt;我習慣將 Windows 的 D: 作為文件儲存專用區。&lt;/p&gt;
&lt;p&gt;預設情況下，WSL 會將 D: 掛載在 &lt;code&gt;/mnt/d&lt;/code&gt;，檔案系統則是 DrvFs：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% mount -l
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rootfs on / type lxfs (rw,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /dev type tmpfs (rw,noatime,mode=755)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;proc on /proc type proc (rw,nosuid,nodev,noexec,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;devpts on /dev/pts type devpts (rw,nosuid,noexec,noatime,gid=5,mode=620)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /run type tmpfs (rw,nosuid,noexec,noatime,mode=755)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /run/lock type tmpfs (rw,nosuid,nodev,noexec,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /run/shm type tmpfs (rw,nosuid,nodev,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /run/user type tmpfs (rw,nosuid,nodev,noexec,noatime,mode=755) binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;D: on /mnt/d type drvfs (rw,noatime,uid=1000,gid=1000,case=off)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C: on /mnt/c type drvfs (rw,noatime,uid=1000,gid=1000,case=off)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;不過，因為某些複雜的原因 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;，我們必須重新設定 &lt;code&gt;/mnt/d&lt;/code&gt; 的 mount 參數，才能讓 Linux 的檔案讀寫權限正常運作。&lt;/p&gt;
&lt;p&gt;我們先卸載 &lt;code&gt;/mnt/d&lt;/code&gt;，再用夾帶 &lt;code&gt;metadata&lt;/code&gt; 的方式重新掛載它：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo umount /mnt/d
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo mount -t drvfs D: /mnt/d -o metadata,uid=1000,gid=1000,umask=22,fmask=111&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;先查看是否成功:&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% mount -l
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rootfs on / type lxfs (rw,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /dev type tmpfs (rw,noatime,mode=755)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;proc on /proc type proc (rw,nosuid,nodev,noexec,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;devpts on /dev/pts type devpts (rw,nosuid,noexec,noatime,gid=5,mode=620)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /run type tmpfs (rw,nosuid,noexec,noatime,mode=755)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /run/lock type tmpfs (rw,nosuid,nodev,noexec,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /run/shm type tmpfs (rw,nosuid,nodev,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;none on /run/user type tmpfs (rw,nosuid,nodev,noexec,noatime,mode=755) binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noatime)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;D: on /mnt/d type drvfs (rw,relatime,uid=1000,gid=1000,umask=22,fmask=111,metadata,case=off)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;C: on /mnt/c type drvfs (rw,noatime,uid=1000,gid=1000,case=off)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;如果成功了，請記得將這設定寫進 &lt;code&gt;/etc/fstab&lt;/code&gt; 裡面，下次 WSL 啟動時就會自動生效：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;

  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;

  
  &lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;D: /mnt/d drvfs rw,relatime,uid=1000,gid=1000,metadata,umask=22,fmask=111 0 0&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id=&#34;docker-與-kubernetes&#34;&gt;Docker 與 Kubernetes&lt;/h2&gt;
&lt;p&gt;雖然保哥的文章推薦在 WSL 裡的 Linux 再安裝一份 Docker engine &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;，但我比較傾向&lt;strong&gt;不要&lt;/strong&gt;。我比較傾向共用既有資源，讓 WSL 直接連接到 Docker Desktop for Windows 身上。畢竟，在同一台電腦上，要維護兩套 Docker engine，太累了。&lt;/p&gt;
&lt;p&gt;我參考上官林傑的文章〈&lt;a href=&#34;https://medium.com/@ericsk/%E5%9C%A8-windows-subsystem-for-linux-wsl-%E4%B8%8B%E4%BD%BF%E7%94%A8-windows-%E4%B8%8A%E7%9A%84-docker-engine-8dc0040ca240&#34;&gt;在 Windows Subsystem for Linux (WSL) 下使用 Windows 上的 Docker Engine&lt;/a&gt;〉，做好必要的設定，但省略文中提到的 alias 步驟（稍後會說明為什麼）。簡單來說，請先進行這三步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;打開 Docker Desktop for Windows 的 &amp;ldquo;Expose daemon on tcp://localhost:2375 without TLS.&amp;rdquo; 選項。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 WSL 裡設定 &lt;code&gt;DOCKER_HOST&lt;/code&gt; 環境變數：&lt;!-- raw HTML omitted --&gt;
&lt;code&gt;export DOCKER_HOST=&amp;quot;tcp://localhost:2375&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在 WSL 裡 &lt;code&gt;sudo visudo&lt;/code&gt; 以下環境變數：&lt;!-- raw HTML omitted --&gt;
&lt;code&gt;Defaults env_keep += &amp;quot;DOCKER_HOST&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;上述文章建議透過 &lt;code&gt;alias docker=docker.exe&lt;/code&gt; 的方式來使用 Docker Desktop for Windows 的 docker client。不過，這些 alias 未必都能在 script 中展開 &lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; ——有鬆綁的方法，但我不喜歡破例。我比較傾向在 WSL 裡用簡單的 wrapper script 來處理。&lt;/p&gt;
&lt;p&gt;首先是 &lt;code&gt;/usr/local/bin/docker&lt;/code&gt; 檔案：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# allow WSL to have access to Docker Desktop for Windows
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec  &amp;#34;/mnt/c/Program Files/Docker/Docker/resources/bin/docker.exe&amp;#34;  &amp;#34;$@&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;其次是 &lt;code&gt;/usr/local/bin/docker-compose&lt;/code&gt; 檔案：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# allow WSL to have access to Docker Desktop for Windows
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;exec  &amp;#34;/mnt/c/Program Files/Docker/Docker/resources/bin/docker-compose.exe&amp;#34;  &amp;#34;$@&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;別忘記打開它們的 &lt;code&gt;&#39;x&#39;&lt;/code&gt; 權限：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% sudo chmod a+x  /usr/local/bin/docker  /usr/local/bin/docker-compose&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;也別忘了，要將 Windows 上面的 Kubernetes 設定連接過來：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;% ln -s /mnt/c/Users/xxx/.kube/config ~/.kube/config&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;好了，現在已經復刻一部分 Mac 的使用習慣了。是該要好好享受一下這種混血環境了。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2019-04-17 後續發展
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;使用了一個月，不太能夠忍受 Cmder 不夠穩定的顯示邏輯：在視窗尺寸變化時，無法正確處理字元位置。因此，我改用〈&lt;a href=&#34;//william-yeh.net/post/2019/04/wsltty-tmux/&#34;&gt;WSLtty + tmux 組合技&lt;/a&gt;〉。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2023-02-06 後續發展
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;四年來 WSL 與容器世界都起了一些變化，本文有些內容已經不敷使用。請改用〈&lt;a href=&#34;//william-yeh.net/post/2023/02/wsl2-podman-k3s/&#34;&gt;WSL2 + Podman + K3s 組合技&lt;/a&gt;〉。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;保哥於 2015 年九月舉辦過【&lt;a href=&#34;https://www.accupass.com/event/1509231111031581814500&#34;&gt;打造一個具有 Linux 溫度的 Windows 命令提示字元工具&lt;/a&gt;】線上講座，也寫了〈&lt;a href=&#34;https://blog.miniasp.com/post/2015/09/27/Useful-tool-Cmder&#34;&gt;介紹好用工具：Cmder&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Cmder 的剪貼簿設定細節，請見 &lt;a href=&#34;https://conemu.github.io/en/SettingsPaste.html&#34;&gt;https://conemu.github.io/en/SettingsPaste.html&lt;/a&gt; 。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;關於 WSL DrvFs 的 metadata 權限設定細節，請參考這三篇文章：“&lt;a href=&#34;https://blogs.msdn.microsoft.com/commandline/2018/01/12/chmod-chown-wsl-improvements/&#34;&gt;Chmod/Chown WSL Improvements&lt;/a&gt;”、“&lt;a href=&#34;https://www.brianketelsen.com/going-overboard-with-wsl-metadata/&#34;&gt;Going Overboard with WSL metadata&lt;/a&gt;”、〈&lt;a href=&#34;https://segmentfault.com/a/1190000016677670&#34;&gt;WSL 配置指北：打造 Windows 最强命令行&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;保哥的文章〈&lt;a href=&#34;https://blog.miniasp.com/post/2018/06/15/My-Windows-Subsystem-for-Linux-WSL-Setup-2018&#34;&gt;我的 Windows Subsystem for Linux (WSL) 終極開發人員配置 - 2018 版&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Bash 的行為是：“Aliases are not expanded when the shell is not interactive, unless…”，請參考 “&lt;a href=&#34;https://unix.stackexchange.com/questions/1496/why-doesnt-my-bash-script-recognize-aliases&#34;&gt;Why doesn&amp;rsquo;t my Bash script recognize aliases?&lt;/a&gt;” 這類文章。&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Kubernetes Best Practices 資料</title>
      <link>//william-yeh.net/post/2019/02/k8s-best-practice/</link>
      <pubDate>Mon, 25 Feb 2019 12:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/02/k8s-best-practice/</guid>
      
        <description>&lt;p&gt;Kubernetes 演化速度令人驚訝。彈性之大，令人聯想到當年  Perl 圈子奉為圭臬的 &lt;a href=&#34;https://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it&#34;&gt;TIMTOWTDI&lt;/a&gt; 口號。&lt;/p&gt;
&lt;p&gt;選擇過多也會帶來問題。發展到某個階段，也該適時沈澱收斂出較佳的實務建議準則。&lt;/p&gt;
&lt;p&gt;因此，我稍微搜尋一下相關資料，作為參考。&lt;/p&gt;
&lt;p&gt;（這應該會是一份需要常常更新的文件）&lt;/p&gt;
&lt;h2 id=&#34;整體建議&#34;&gt;整體建議&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://dzone.com/articles/top-5-kubernetes-best-practices-from-sandeep-dines&#34;&gt;Top 5 Kubernetes Best Practices From Sandeep Dinesh (Google)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.slideshare.net/BillLiu31/kubernetes-best-practices&#34;&gt;Kubernetes best practices&lt;/a&gt; by Bill Liu&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/78464702&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://medium.com/google-cloud/kubernetes-best-practices-8d5cd03446e2&#34;&gt;Kubernetes Best Practices&lt;/a&gt; by Daz Wilkin&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.openshift.com/kubernetes-application-operator-basics/&#34;&gt;Kubernetes Application Operator Basics&lt;/a&gt; by Michael Hausenblas&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;資源設定建議&#34;&gt;資源設定建議&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://kubernetes.io/docs/concepts/configuration/overview/&#34;&gt;Configuration Best Practices&lt;/a&gt; by Kubernetes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.replex.io/blog/9-best-practices-and-examples-for-working-with-kubernetes-labels&#34;&gt;9 Best Practices and Examples for Working with Kubernetes Labels&lt;/a&gt; by Hasham Haider&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/&#34;&gt;Recommended Labels&lt;/a&gt; by Kubernetes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://kubernetes.io/blog/2016/08/kubernetes-namespaces-use-cases-insights/&#34;&gt;Kubernetes Namespaces: use cases and insights&lt;/a&gt; by Mike Altarace &amp;amp; Daz Wilkin&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;套件管理建議&#34;&gt;套件管理建議&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://helm.sh/docs/chart_best_practices/&#34;&gt;The Chart Best Practices Guide&lt;/a&gt; by Helm&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;資安建議&#34;&gt;資安建議&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://dev.to/petermbenjamin/kubernetes-security-best-practices-hlk&#34;&gt;Kubernetes Security Best-Practices&lt;/a&gt; by Peter Benjamin&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.cncf.io/blog/2019/01/14/9-kubernetes-security-best-practices-everyone-must-follow/&#34;&gt;9 Kubernetes Security Best Practices Everyone Must Follow&lt;/a&gt; by CNCF&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://rancher.com/blog/2019/2019-01-17-101-more-kubernetes-security-best-practices/&#34;&gt;101 More Security Best Practices for Kubernetes&lt;/a&gt; by Adrian Goins&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      
    </item>
    
    <item>
      <title>技術領導者微培訓</title>
      <link>//william-yeh.net/post/2019/01/tech-leader-reading/</link>
      <pubDate>Sat, 19 Jan 2019 10:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/01/tech-leader-reading/</guid>
      
        <description>&lt;p&gt;最近，我們研發組織有幅度不算小的變動，某些技術人會被要求承擔更多的技術領導責任。&lt;/p&gt;
&lt;p&gt;不過，正如&lt;a href=&#34;https://en.wikipedia.org/wiki/Gerald_Weinberg&#34;&gt;溫伯格&lt;/a&gt;大師在《&lt;a href=&#34;https://www.books.com.tw/products/0010467750&#34;&gt;領導者，該想什麼？&lt;/a&gt;》所說，技術人常會面臨天人交戰：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;儘管學校教育告訴我說，每一個好公民都應該負起領導責任，但痛苦經歷讓我害怕擔任任何領導者的角色。我學會盡可能推卻成為領導者的機會。面對領導的問題，我常假裝它是不存在的。為保證我永遠不會涉及到需要運用領導技能的場合，我選擇電腦軟體作為我的職業。&lt;/p&gt;
&lt;p&gt;事情發展非我所願。每當我在所負責的技術性工作上有出色表現時，同事就知道要對我更加尊敬，似乎把我當成他們的領導者。沒有人勉強我當領導者，是我自己陷入這樣一個矛盾的情境。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;為了讓過渡階段更順暢，雖然我在這裡只剩下很短的時間能夠幫忙了，但還是想略盡棉薄之力。&lt;/p&gt;
&lt;p&gt;以下是我的【技術領導者微培訓】企劃案。&lt;/p&gt;
&lt;h2 id=&#34;培訓目標&#34;&gt;培訓目標&lt;/h2&gt;
&lt;p&gt;引述《&lt;a href=&#34;https://www.books.com.tw/products/0010467750&#34;&gt;領導者，該想什麼？&lt;/a&gt;》第一章的列表，只要你對以下課題感到疑惑，這本書、這門課，對你應該都會有些幫助：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;領導者真的那麼愚蠢嗎？有時他們的確給人那種印象嗎？&lt;/li&gt;
&lt;li&gt;我能成為領導者，但不要像一般領導者那樣嗎？&lt;/li&gt;
&lt;li&gt;我能一面當領導者，一面繼續提升我的技術能力嗎？&lt;/li&gt;
&lt;li&gt;一個毫無技術背景的人，有可能在技術界成為領導者嗎？&lt;/li&gt;
&lt;li&gt;一旦成為領導者，我必須犧牲多少技術專業能力？&lt;/li&gt;
&lt;li&gt;我能得到多少回報？&lt;/li&gt;
&lt;li&gt;如果我是領導者，我需要擺出上司架式，對屬下頤指氣使嗎？&lt;/li&gt;
&lt;li&gt;我能藉由讀書習得領導技能嗎？&lt;/li&gt;
&lt;li&gt;我還可以從何處學習成為領導者呢？&lt;/li&gt;
&lt;li&gt;為何人們視我為領導者，而我卻不認為自己是領導者呢？&lt;/li&gt;
&lt;li&gt;為何我自認為很能幹，人們卻不把我當成領導者呢？&lt;/li&gt;
&lt;li&gt;倘若我不想承擔領導責任，又如何？&lt;/li&gt;
&lt;li&gt;到底什麼是領導？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這本書、這門課，沒辦法讓你一夕之間脫胎換骨，但能給你經過證實可行的方向。能獲得多少，端看你認真投入的程度、誠實面對自己的態度、敏銳觀察及切實反思的職場人紀律。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果他們的態度不夠嚴謹，那麼我建議他們做的任何事情，都是在浪費我的時間。 (p. 122)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/01/tech-leader-book.png&#34; alt=&#34;Becoming a Technical Leader&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/01/tech-leader-book.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Becoming a Technical Leader&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;進度&#34;&gt;進度&lt;/h2&gt;
&lt;p&gt;請依照指定進度，先自行&lt;strong&gt;想辦法&lt;/strong&gt;閱讀指定讀物《&lt;a href=&#34;https://www.books.com.tw/products/0010467750&#34;&gt;領導者，該想什麼？&lt;/a&gt;》，並填寫學習單。&lt;/p&gt;
&lt;h3 id=&#34;第一週領導概說&#34;&gt;第一週／領導概說&lt;/h3&gt;
&lt;p&gt;閱讀進度：第一章～第五章。&lt;/p&gt;
&lt;p&gt;學習單：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;準備一張清單，列舉說明哪些情境因為你的出現，使得他人的生產力因而「提升」。請準備另一張清單，列舉說明哪些情境因為你的出現，使得他人的生產力因而「下降」。你能找出這兩類情境的差異之處，並能分辨出它們的特色嗎？列出這張清單，能讓你更認識自己，及更認識讓你獲得授權的環境嗎？ (pp. 41&amp;ndash;42)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根據前一個問題所準備的兩張清單內容來看，你是所屬團體的&lt;strong&gt;資產&lt;/strong&gt;還是&lt;strong&gt;負債&lt;/strong&gt;？ (p. 42)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你帶一組人做事，用什麼方法促使成員從不同角度檢討目前執行情形？獨自一人做事時，你又用什麼方法自我檢討？有任何途徑可幫助你改善目前自我檢討的方法嗎？ (p. 68)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下一次帶一組人執行任務，列出你在行使領導技能時所做的所有事情。若未能列出至少十件事，請你再做一遍該任務，一直做到為了完成一個任務，至少要做十件有助於領導的事。列出此份清單後，試著將它們依&lt;strong&gt;瞭解問題&lt;/strong&gt;、&lt;strong&gt;控制點子的流通&lt;/strong&gt;、&lt;strong&gt;維持品質&lt;/strong&gt;分門別類。分類後，能看得出你的領導風格傾向於其中一類嗎？你做的哪些事無法歸類到這三類？ (p. 68)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你多久沒有登上一個新的&lt;strong&gt;高原期&lt;/strong&gt;了？你還在享受目前位於高原期的好日子嗎？為順利攀登下一個高原期，你做了哪些準備？ (p. 82)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你上一次針對職業生涯做重大改變，到現在有多久的時間了？在整個過程中，令你印象最深刻的事情或感受是什麼？ (p. 97)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;最近一次你熟識的人做了重大職業改變，你的反應為何？你有沒有藉此機會想到自身處境？ (p. 97)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;第二週創新&#34;&gt;第二週／創新&lt;/h3&gt;
&lt;p&gt;閱讀進度：第六章～第九章。&lt;/p&gt;
&lt;p&gt;學習單：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;至少閱讀一本你所景仰人物的自傳。在日記裡寫下該自傳中最讓你感到驚訝的事，以及最讓你感動的情節。 (p. 129)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你想出很多點子，後來怎麼樣了？大多數都實現了嗎？有多少點子因為創新程度不夠而胎死腹中？有多少點子因為環境不支援而被迫消失？領導不當或領導能力不足，是你犯該錯誤的主因嗎？何種訓練有助於提升你在上述案例行使領導技能的品質？ (改編合併自 p. 140 &amp;amp; p. 141)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你是否讓成功的事實變成繼續前進的絆腳石？如果你超越了目前的成就，哪些東西會跟著改變？你會怎麼做？ (p. 156)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你記得職業生涯中最淒慘的一段經歷嗎？你難以承受的是什麼？你如何從人生的最低潮走出來？你學到了什麼功課？再遇到人生低潮時，你會用不同方式處理嗎？ (p. 156)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;和他人打交道時，他們瞭解你的動機嗎？你希望他們瞭解你的動機嗎？你如何確認他們是否瞭解你的動機？ (p. 156)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;畫出你的&lt;strong&gt;事業線&lt;/strong&gt;。可能的話，找一位或多位朋友分享你的經歷，和他們討論你的人生起伏。記得將事業線延伸到未來。設想它是一部電影或一部小說，你會取什麼樣的名字？你希望由何人擔任這部電影的主角？ (p. 156)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;第三週動機&#34;&gt;第三週／動機&lt;/h3&gt;
&lt;p&gt;閱讀進度：第十章～第十五章。&lt;/p&gt;
&lt;p&gt;學習單：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;試著回想你最近做過的一些蠢事。別人發現你做了那些蠢事，你作何反應？在追求攀登職涯高峰的過程中，你的&lt;strong&gt;自我防禦心理&lt;/strong&gt;越來越重或越來越輕？對於你採取的自我防禦作為，你如何處置它們？ (p. 174)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你曾否將事務置於人之上，現在你後悔了？你曾否將人置於事務之上，現在你後悔了？ (p. 187)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;玩遊戲的時候，你對得分較有興趣，還是對遊戲本身較有興趣？玩團隊遊戲的時候，你對團隊的得分較在意？還是對自己的得分較在意？這兩種心態，如何影響你貢獻力量於團隊，對於團隊成績有何影響？如果是團隊工作呢？ (p. 225)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你是否曾在某團隊中毫無貢獻？當你察覺到這一點時，你的感受是什麼？ (p. 239)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;回憶最近一次你進行&lt;strong&gt;力量交易&lt;/strong&gt;遭逢失敗的事例。你從這次交易中學到什麼？你能否以現在的新觀點從那件事再學習？ (p. 239)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;哪些在你內心運作的事，你努力不顯現於外？你知道其中運作的情形嗎？如果你將這些精力用在別處，結果將如何？ (p. 239)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;第四週組織&#34;&gt;第四週／組織&lt;/h3&gt;
&lt;p&gt;閱讀進度：第十六章～第十九章。&lt;/p&gt;
&lt;p&gt;學習單：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在目前的工作環境裡，你擁有幾種不同的力量？你如何將這些力量轉換為更有效用的型態？你如何運用轉換得來的力量？ (p. 252)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果你在團隊中擔任決策者，你如何判知自己表現良好？你是否紀錄決策內容，並在事後檢視？你是否詢問團隊成員，這項決策對他們有何影響？如果你沒問，原因是什麼？ (p. 264)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你是否因組織缺乏效率受獎勵？或給予缺乏效率的組織獎勵？你能否創造一個相反的工作環境？ (p. 273)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;列一張清單，寫出你可以&lt;strong&gt;觀察&lt;/strong&gt;並&lt;strong&gt;實驗&lt;/strong&gt;組織運作的各個機會。再列一張清單，寫出你可以觀察並實驗，但你未加以利用的各個機會。你能否從第二張清單中挑出一個項目，找出未利用的原因，然後清除？ (p. 284)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;回想一下你是否有下述經驗：全力以赴的時候，卻被認為沒有盡力。當時你有何感受？你是否為自己辯護？結果如何？ (p. 285)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;回想某次，你認為某人沒有做出貢獻的情況。你是否能解讀為，在那種情況下，他已經盡力而為？當時那個人試圖解決什麼問題？下次再發生類似狀況時，你能否找出原因？ (p. 285)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;第五週轉變&#34;&gt;第五週／轉變&lt;/h3&gt;
&lt;p&gt;閱讀進度：第二十章～第二十四章。&lt;/p&gt;
&lt;p&gt;學習單：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;上次新主管上任時，你首先注意到他哪一點？你花多少時間才信任這位新主管？他的哪一項動作獲得你的信任？哪一項動作減少你的信任？你積極和新主管配合，還是奮力和新主管作對？為什麼？ (p. 299)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果你預先知道你將接受某項考驗，你的情緒反應如何？如果你突然發現自己將接受考驗，你的情緒反應又是如何？兩者有何不同？是否有可以相互借鏡之處？ (p. 311)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你的工作環境是否有持續發生的衝突？你能否想出三種改變&lt;strong&gt;組織&lt;/strong&gt;的方式，以避免這些衝突？或是三種改變&lt;strong&gt;人際關係&lt;/strong&gt;的方式？哪一種型態適合你發揮長處？哪一種型態你運作起來較順手？ (p. 311)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你能否舉出三位同事，能給予你技術能力方面的指導？如果你想不出來，你為什麼還在這家公司上班？如果你有三位老師，你如何善用這項資源？ (p. 321)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;這一年來，你參加過哪些課程、讀過哪些書？這些對於你的技術能力和領導能力有何助益？你從中是否能學得更多？未來一年，你計畫參加哪些課程、讀哪些書？你應該做哪些事前準備，以獲益更多？ (p. 322)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;你能否忍受無所事事的時間？你是否有時間審視你的周遭，審視你自己，以找出沒有更多時間的原因？為什麼沒有充裕的時間？如果確實沒有時間，請停止閱讀，開始檢討。 (p. 331)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;檢視你的&lt;strong&gt;個人支援網絡&lt;/strong&gt;的成員名單。哪些人你願意維持良好關係，以繼續獲得支援？這份名單在哪個部分顯得不足，必須加以補強？ (p. 343)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;上課前&#34;&gt;上課前&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;瀏覽學習單。&lt;/li&gt;
&lt;li&gt;速讀：每一份指定讀物，請在不超過 2 小時之內速讀完畢第一次。&lt;/li&gt;
&lt;li&gt;填寫學習單。&lt;/li&gt;
&lt;li&gt;如有時間，可再回頭重讀細讀內容。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;上課時&#34;&gt;上課時&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;攜帶學習單。&lt;/li&gt;
&lt;li&gt;以 &lt;a href=&#34;http://www.liberatingstructures.com/&#34;&gt;liberating structures&lt;/a&gt; 及互動討論方式，進行個案研討。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;有些個案討論有隱私性考量，為促成坦誠討論，參與者需宣誓對現場討論內容保密 (咦)。&lt;/p&gt;
&lt;h2 id=&#34;全部課程結束後&#34;&gt;全部課程結束後&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;從頭再看一次過去寫的學習單。這陣子，你有什麼改變了嗎？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;從《&lt;a href=&#34;https://www.books.com.tw/products/0010467750&#34;&gt;領導者，該想什麼？&lt;/a&gt;》書中不時可看出，&lt;a href=&#34;https://en.wikipedia.org/wiki/Gerald_Weinberg&#34;&gt;溫伯格&lt;/a&gt;受到&lt;a href=&#34;https://en.wikipedia.org/wiki/Virginia_Satir&#34;&gt;薩提爾&lt;/a&gt;的影響很深。請再讀讀《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;激發員工潛力的薩提爾教練模式&lt;/a&gt;》及《&lt;a href=&#34;https://www.books.com.tw/products/0010770522&#34;&gt;薩提爾的對話練習&lt;/a&gt;》兩本書，以進一步了解如何在職場上運用薩提爾模式。或者，直接去上薩提爾課程吧！&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      
    </item>
    
    <item>
      <title>年假可讀的軟體領域輕讀物</title>
      <link>//william-yeh.net/post/2019/01/soft-reading-list/</link>
      <pubDate>Thu, 17 Jan 2019 15:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/01/soft-reading-list/</guid>
      
        <description>&lt;p&gt;中午時，非 RD 的同事請我推薦適合泛軟體產業從業人員的五份輕讀物，可在春節連續假期時好好補血。&lt;/p&gt;
&lt;p&gt;年假，自然不方便啃太過於生硬艱澀、理論宏偉的讀物。我挑選這五份輕讀物：四本書，一組網路系列文章。敘事風格親切，高潮迭起，應該可以帶來不少啟發。&lt;/p&gt;
&lt;h2 id=&#34;it-實境小說&#34;&gt;IT 實境小說&lt;/h2&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010765203&#34;&gt;鳳凰專案&lt;/a&gt;》，體會一下研發、維運、行銷、安控、財務等部門相互掣肘的慘劇，以及如何以 DevOps「三步工作法」來解決的戲劇性發展。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你還沒有達到解決專案可交付成果、故障處理、審計合規等問題所需要的那種對工作的理解程度。在你對工作的內涵有更好的理解之前，任何關於控制工作的討論都會讓你茫然無措。正所謂：夏蟲不可語冰。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;敏捷神話&#34;&gt;敏捷神話&lt;/h2&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010785434&#34;&gt;Scrum：用一半的時間做兩倍的事&lt;/a&gt;》，不要被聳動的書名騙了，這是本不吹牛不浮誇的好書。這本由 Scrum 發明人之一 Jeff Sutherland 所寫的書，揭露 Scrum 發展過程中的軼事。讀了之後，你會領會更多 Scrum 規則背後的精神。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我在書中提及，Scrum 源自於豐田生產系統，以及空戰的 OODA 循環。你會在接下來的內容中看到，從開發價格實惠、每加侖汽油能跑一百哩的車子，到協助美國聯邦調查局 (FBI) 建立 21 世紀的資料庫系統，任何東西都可以用 Scrum 來打造。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;跨出框架需要練習&#34;&gt;跨出框架，需要練習&lt;/h2&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010789923&#34;&gt;Pepper 開發者從 0 到 1 的創新工作法&lt;/a&gt;》，讓不是創業家、自由工作者、研究者的平凡上班族，也能習得具體的創新做法。你可以看到開發出 &lt;a href=&#34;https://zh.wikipedia.org/wiki/Pepper_%28%E6%A9%9F%E5%99%A8%E4%BA%BA%29&#34;&gt;Pepper&lt;/a&gt; 人型機器人的 &lt;a href=&#34;https://www.linkedin.com/in/kanamehayashi&#34;&gt;Kaname Hayashi&lt;/a&gt;，是如何有紀律地自我要求刻意練習。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;從 0 到 1 需要的不是「才能」，而是「練習」。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;外國月亮&#34;&gt;外國月亮&lt;/h2&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010796709&#34;&gt;給力&lt;/a&gt;》，軟體／媒體科技業巨頭 Netflix 獨一無二的企業文化，但不要驟下「國情不合」的結論。多讀幾次，試著感受適度的低情境 (low context)、直接否定 (direct negative feedback)、平權式領導 (egalitarian) 風格有什麼殊勝之處。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;留住員工、使員工高度投入的方法，應該是招募對此計劃興趣濃厚、且傾向在同一工作待上很長時間的人才，而不是靠著提供他們四種加味水及設置員工睡眠艙來留住他們。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;是技術也是藝術&#34;&gt;是技術，也是藝術&lt;/h2&gt;
&lt;p&gt;這原本是&lt;a href=&#34;//william-yeh.net/post/2018/12/practice-of-managers/&#34;&gt;【主管的修練】讀書會&lt;/a&gt;的輔助讀物，但單獨抽出來閱讀，也行。&lt;/p&gt;
&lt;p&gt;系列文 / 專案管理的藝術&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⓪ &lt;a href=&#34;https://www.projectup.net/article/view/id/260&#34;&gt;決策的平衡點&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;① &lt;a href=&#34;https://www.projectup.net/article/view/id/259&#34;&gt;拉高視野、見林但不見樹&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;② &lt;a href=&#34;https://www.projectup.net/article/view/id/258&#34;&gt;平衡需求、但別想討好所有人&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;③ &lt;a href=&#34;https://www.projectup.net/article/view/id/256&#34;&gt;重點掌握、如何抓大放小&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;④ &lt;a href=&#34;https://www.projectup.net/article/view/id/255&#34;&gt;主動發現、弭禍於無形之中&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑤ &lt;a href=&#34;https://www.projectup.net/article/view/id/253&#34;&gt;醜話先說，對事但不對人&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑥ &lt;a href=&#34;https://www.projectup.net/article/view/id/251&#34;&gt;品質管制、追求標準、一致、與穩定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑦ &lt;a href=&#34;https://www.projectup.net/article/view/id/69&#34;&gt;降低流言、合適的訊息分享&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑧ &lt;a href=&#34;https://www.projectup.net/article/view/id/68&#34;&gt;沒有英雄、人員培育與接班計畫&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑨ &lt;a href=&#34;https://www.projectup.net/article/view/id/67&#34;&gt;避免發散、一切都跟收斂有關&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑩ &lt;a href=&#34;https://www.projectup.net/article/view/id/65&#34;&gt;歷史借鏡、能重複應用的才有價值&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;過完年，再來一場討論會吧。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      補充
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;好友 &lt;a href=&#34;https://www.facebook.com/91agile/&#34;&gt;91 (Joey)&lt;/a&gt; 隨後也發表了另一份春節期間的推薦讀物。分成三大類：① 輕讀物，② 重一點，需要系列性連串看完的書，③ 想趁著連假，消化一下大部頭的書。&lt;/p&gt;
&lt;p&gt;意者，請去看看那份&lt;a href=&#34;https://www.facebook.com/91agile/posts/1110269312481019&#34;&gt;清單&lt;/a&gt;。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>Scrum 與《從 A 到 A&#43;》</title>
      <link>//william-yeh.net/post/2019/01/scrum-good-to-great/</link>
      <pubDate>Fri, 11 Jan 2019 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/01/scrum-good-to-great/</guid>
      
        <description>&lt;p&gt;最近重新溫習近二十年的老書《&lt;a href=&#34;https://www.books.com.tw/products/0010202911&#34;&gt;從 A 到 A+&lt;/a&gt;》，啟發頗多。&lt;/p&gt;
&lt;p&gt;《從 A 到 A+》作者們的實證研究方法很嚴謹 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。他們從 1965～1995 年名列 Fortune 500 的企業名單中，挑選「十五年累計股票報酬率」超越股市整體表現三倍以上，且不受產業循環影響的企業，研究這些績優公司從「優秀」到「卓越」的關鍵因素。最後，作者們提出「&lt;a href=&#34;https://www.jimcollins.com/concepts/the-flywheel.html&#34;&gt;飛輪效應&lt;/a&gt;」來統一解釋他們的發現：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/01/flywheel.jpg&#34; alt=&#34;飛輪效應&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/01/flywheel.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;飛輪效應&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;某方面來說，軟體研發圈講究的 Scrum，還滿符合《從 A 到 A+》所講的飛輪效應。&lt;/p&gt;
&lt;h2 id=&#34;飛輪的比喻&#34;&gt;飛輪的比喻&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》第八章如此說明飛輪的比喻：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;無論最後的結果是多麽戲劇化，「從優秀到卓越」的轉型過程都絕非一蹴可幾。優秀公司躍升為卓越企業，靠的是累積的努力——腳踏實地一步一步，一個行動接著一個行動，一個決定接著一個決定，一圈接著一圈的轉動飛輪，點點滴滴累積起來，終於達到了持久不墜的非凡績效。&lt;/p&gt;
&lt;p&gt;「從優秀到卓越」的公司，和對照公司一樣，都會面臨華爾街要求短期績效的壓力。然而和對照公司不同的是，在壓力下，「從優秀到卓越」的公司仍然有足夠的&lt;strong&gt;耐性&lt;/strong&gt;和&lt;strong&gt;紀律&lt;/strong&gt;遵循先厚植實力、再突飛猛進的飛輪模式。最後，他們終能展現驚人的績效，即使照著華爾街的標準來看，都非常成功。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這，是不是跟 Scrum 嚴守五事件 (sprint, sprint planning, daily scrum, sprint review, sprint retrospective)、三產物 (product backlog, sprint backlog, increment) 的紀律，有異曲同工之妙呢？&lt;/p&gt;
&lt;h2 id=&#34;第五級領導&#34;&gt;第五級領導&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》第二章如此說明「第五級領導」的特色：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第五級領導人具備了雙重特質：宅心仁厚，但意志堅定；謙沖為懷，但勇敢無畏。&lt;/p&gt;
&lt;p&gt;所有「從優秀到卓越」的公司，在蛻變期都出現了第五級領導人，而對照公司卻普遍缺乏。由於第五級領導人的概念違背了傳統智慧——公司變革必須仰賴備受矚目的救星來推動，務必請切記，第五級領導人是實證研究的發現，而不是空談得到的觀念。&lt;/p&gt;
&lt;p&gt;最大的諷刺是，通常一個人能夠位高權重，是因為他積極進取，野心勃勃，這卻和第五級領導所要求的謙虛性格背道而馳。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這，是不是跟 Scrum master 所講究的「僕人式領導」、product owner 講究的「為 product backlog 當責」，有異曲同工之妙呢？&lt;/p&gt;
&lt;h2 id=&#34;找對人&#34;&gt;找對人&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》第三章如此說明「先找對人，再決定要做什麼」的觀念：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;推動優秀公司邁向卓越的企業領導人，並非先找出巴士該往哪裡開，然後要員工把車子開過去。他們反而先找對人上車（要求不適合的人下車），接下來才弄清楚車子該往哪個方向開。&lt;/p&gt;
&lt;p&gt;第一，如果你先思考「該找什麼人」，而不是「該做什麼」，將比較容易因應瞬息萬變的世界。其次，如果你找對了人上車，根本就不太需要操心激勵員工和管理員工的問題。第三，如果找錯了人，就算你找到了正確的方向都沒用。&lt;/p&gt;
&lt;p&gt;卓越公司的領導人通常都了解，成長的最大瓶頸不在於市場、技術、競爭或產品，「能不能延攬到適合的人才，並且留住人才」的重要性凌駕於這一切。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;《從 A 到 A+》的後記，甚至如此主張：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;放寬「用對人」的定義，多關注這個人性格上的優點，不要太強調專業知識。他們可以學習技能，獲得知識，但是卻無法透過學習，培養出適合組織的基本人格特質。&lt;/p&gt;
&lt;p&gt;應該善用景氣不好的時候，多方延攬卓越的人才，即使當時你腦中還沒有想到適當的職位。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這，讓我聯想到 &lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 主張的五大價值觀：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;當 Scrum Team 體現和活化承擔 (commitment)、勇氣 (courage)、專注 (focus)、開放 (openness) 和尊重 (respect) 這五種價值觀時，Scrum 的三根支柱：透明性 (transparency)、檢視性 (inspection)、調適性 (adaptation) 就會出現並幫助大家建立信任。隨著 Scrum Team 成員從事 Scrum 角色、活動和產出物的過程中，他們就會學習和探索這些價值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;若不幸找到錯的人，這五大價值觀是否能夠很快灌輸在他們身上呢？&lt;/p&gt;
&lt;h2 id=&#34;真實與透明&#34;&gt;真實與透明&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》第四章如此說明「面對殘酷現實，但決不喪失信心」的觀念：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;領導力和願景有關，但是領導力也和創造能聽到真話和面對現實的環境有關。&lt;/p&gt;
&lt;p&gt;如果你是很有領袖魅力的強人，應該花時間好好想一想，領袖魅力是資產，也是負債。你性格上的優點也可能埋下了問題的種子，員工會自動過濾資訊，不讓你接觸到殘酷的真相。你仍然可以克服領袖魅力帶來的問題，但是必須有充分的自覺，長期投注心力注意這個問題。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這，是不是跟 Scrum 的 sprint review 及 sprint retrospective 所講究的重點，有異曲同工之妙呢？&lt;/p&gt;
&lt;h2 id=&#34;刺蝟原則&#34;&gt;刺蝟原則&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》第五章主張：「從優秀躍升到卓越，必須對於三個互相交集的圓圈有深入的理解，並且把這種理解轉化為單純而清楚的概念」：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/01/hedgehog-principle.jpg&#34; alt=&#34;刺蝟原則&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/01/hedgehog-principle.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;刺蝟原則&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;「從優秀到卓越」的公司比較像刺蝟——單純、憨厚，只懂得「一件大事」，但卻能一以貫之。對照公司則比較像狐狸——詭計多端、行動敏捷，懂得許多事情，但卻前後矛盾，缺乏一致性。&lt;/p&gt;
&lt;p&gt;「從優秀到卓越」的公司，平均要花四年的時間，才能釐清他們的刺蝟原則。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在較微觀的尺度來說，這，是不是跟 Scrum 的 product goal 與 sprint goal，有異曲同工之妙呢？&lt;/p&gt;
&lt;h2 id=&#34;紀律&#34;&gt;紀律&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》第六章主張「企業應該建立起一種文化，讓員工能在三個圓圈中採取有紀律的行動，堅守刺蝟原則」：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/01/discipline.jpg&#34; alt=&#34;紀律&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/01/discipline.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;紀律&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;自由、責任、紀律，凡此種種，是不是跟 Scrum 的「自組織文化」與紀律，有異曲同工之妙呢？&lt;/p&gt;
&lt;h2 id=&#34;科技&#34;&gt;科技&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》第七章主張要以合宜態度面對科技：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「從優秀到卓越」公司的領導人，都有一股發自內心的創造性驅動力，因為渴望追求卓越而追求卓越；至於表現平平的公司，領導人背後的驅動力通常只是害怕落後。&lt;/p&gt;
&lt;p&gt;「從優秀到卓越」的背後驅動力，絕不是恐懼。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這，是不是跟 Scrum 的 DoD (definition of done) 品質紀律，甚至&lt;a href=&#34;https://agilemanifesto.org/principles.html&#34;&gt;敏捷原則&lt;/a&gt;第九條 &amp;ldquo;Continuous attention to technical excellence and good design enhances agility.&amp;rdquo; 所揭櫫的重點，有異曲同工之妙呢？&lt;/p&gt;
&lt;h2 id=&#34;按部就班&#34;&gt;按部就班&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》的後記，在回答「我應該從什麼地方開始做起？」問題時，如此提醒：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;首先，熟讀所有的發現。切記，不能單靠其中任何一項發現來造就卓越的企業，你必須把它當成一體，照著我們的架構，按部就班一一實施整套做法。&lt;/p&gt;
&lt;p&gt;本書循序漸進的陳述架構，正好符合我們所觀察到的企業做法和步驟，因此，本書的結構就是你們的最佳指南。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這，是不是跟 Scrum 兩位發明人在《&lt;a href=&#34;https://www.books.com.tw/products/0010647604&#34;&gt;告別瀑布，擁抱敏捷&lt;/a&gt;》所提的警告，有異曲同工之妙呢？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum 不是可以被隨意修改，來迎合既有企業文化的流程，反而是應該調整企業文化來適應 Scrum。&lt;/p&gt;
&lt;p&gt;如果沒有用 Scrum 來建立敏捷、透明的開發環境，那隱藏的問題將會一直留在企業內損害企業的利益。那就失去了使用 Scrum 最主要的好處。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;持續的改進&#34;&gt;持續的改進&lt;/h2&gt;
&lt;p&gt;《從 A 到 A+》第八章在談到飛輪效應時，有這麼一段語重心長的觀察：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「從優秀到卓越」的公司，比較不喜歡在八字還沒有一撇的時候，就對外大肆宣揚偉大的目標。他們只是開始轉動飛輪——先深入了解，然後採取具體行動，一步接著一步，一圈接著一圈。等到飛輪慢慢累積了龐大的動能之後，他們才抬起頭來說：「嘿，如果我們一直這樣推動下去，沒有理由達不到目標。」&lt;/p&gt;
&lt;p&gt;我們發現，當有了適當的條件時，員工的投入、團結、激勵和變革等問題，都自然會迎刃而解，完全不是問題。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這麼美好的飛輪，要啟動，關鍵在於「有了適當的條件」。&lt;/p&gt;
&lt;p&gt;如果從 Scrum 角度來看，你認為，什麼是所謂的「適當的條件」呢？這是值得你我深思的大哉問。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010202911&#34;&gt;從 A 到 A+&lt;/a&gt;》附錄一說明作者們採取的研究方法及篩選過程：①根據 1965～1995 年 Fortune 500 名單，從所有美國公司中選出 1,435 家公司，②根據平均複合投資人報酬率，從 1,435 家公司到 126 家公司，③根據累積股票報酬率，訂出 11 則淘汰標準，從 126 家公司到 19 家公司。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>你要一直打野戰嗎？</title>
      <link>//william-yeh.net/post/2019/01/field-battle-only/</link>
      <pubDate>Thu, 03 Jan 2019 13:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2019/01/field-battle-only/</guid>
      
        <description>&lt;p&gt;去年十二月，接連把超讚的兩本書讀完。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010802878&#34;&gt;什麼才是經營最難的事&lt;/a&gt;》較偏草創期的戰鬥智慧，《&lt;a href=&#34;https://www.books.com.tw/products/0010796709&#34;&gt;給力&lt;/a&gt;》較偏成長期的經營智慧。兩種規模，兩種思維，激盪我許多想法。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/01/powerful-and-hard-things.jpg&#34; alt=&#34;兩種極端的好書&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/01/powerful-and-hard-things.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;兩種極端的好書&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;不同的生存階段，不同的公司地位，需要的手法會不同。&lt;/p&gt;
&lt;p&gt;但這並非截然二分。像《&lt;a href=&#34;https://www.books.com.tw/products/0010802878&#34;&gt;什麼才是經營最難的事&lt;/a&gt;》第七章，儘管強調戰時執行長與平時執行長的對比 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，卻也說：「平時執行長重視員工培訓，以員工成就感與職涯發展為己任。戰時執行長也重視員工訓練，以免大家在戰場淪為砲灰。」&lt;/p&gt;
&lt;p&gt;有些事，不分平時戰時，都需要顧及到的。&lt;/p&gt;
&lt;p&gt;所以，當我看到朋友 &lt;a href=&#34;https://medium.com/@vincekuoyu&#34;&gt;Vince&lt;/a&gt; 最近引述《&lt;a href=&#34;https://www.books.com.tw/products/0010802878&#34;&gt;什麼才是經營最難的事&lt;/a&gt;》第七章的一段話，很有感觸：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2019/01/wartime-ceo.png&#34; alt=&#34;戰時執行長&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2019/01/wartime-ceo.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;戰時執行長&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這段話，讓我聯想到金庸。&lt;/p&gt;
&lt;h2 id=&#34;岳飛不讀兵書&#34;&gt;岳飛不讀兵書？&lt;/h2&gt;
&lt;p&gt;金庸小說《&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%B0%84%E9%B5%B0%E8%8B%B1%E9%9B%84%E5%82%B3&#34;&gt;射鵰英雄傳&lt;/a&gt;》第三十六回，提到岳飛對於兵法的獨特見解：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;岳飛少年時只喜野戰，上司宗澤說道：「爾勇智才藝，古良將不能過。然好野戰，非萬全計。」因授以布陣之法。岳飛說道：「陣而後戰，兵法之常。運用之妙，存乎一心。」宗澤對他的話也頗為首肯。但岳飛後來征伐既多，也知執泥舊法固然不可，但以陣法教將練卒，再施之於戰場，亦大有制勝克敵之功。這番經過也都記在《武穆遺書》之中。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;當然啦，《武穆遺書》云云，只是金庸在小說中杜撰的。那麼，真實的歷史呢？&lt;/p&gt;
&lt;p&gt;看看《宋史》吧！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;戰開德、曹州皆有功，澤大奇之，曰：「爾勇智才藝，古良將不能過，然好野戰，非萬全計。」因授以陣圖。飛曰：「陣而後戰，兵法之常，運用之妙，存乎一心。」澤是其言。&lt;/p&gt;
&lt;p&gt;    &amp;mdash; 《宋史》&lt;a href=&#34;https://zh.wikisource.org/zh-hant/%E5%AE%8B%E5%8F%B2/%E5%8D%B7365&#34;&gt;卷365&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;乍看之下，成年之後的岳飛，似乎只擅長野戰，輕視兵書佈陣之法；但《宋史》也記載年少時岳飛的另一面：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;人少負氣節，沈厚寡言，家貧力學，尤好《左氏春秋》、孫吳兵法。生有神力，未冠，挽弓三百斤，弩八石。學射於周同，盡其術，能左右射。&lt;/p&gt;
&lt;p&gt;    &amp;mdash; 《宋史》&lt;a href=&#34;https://zh.wikisource.org/zh-hant/%E5%AE%8B%E5%8F%B2/%E5%8D%B7365&#34;&gt;卷365&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可見，相關經典，他早就讀過了，甚至可說是讀通了——在實踐中融會貫通。&lt;/p&gt;
&lt;p&gt;融會「常」與「變」，才有資格講「運用之妙，存乎一心」。&lt;/p&gt;
&lt;p&gt;一代大將如此，你我呢？&lt;/p&gt;
&lt;h2 id=&#34;短線與長線&#34;&gt;短線與長線&lt;/h2&gt;
&lt;p&gt;Bryan 新文章〈&lt;a href=&#34;https://www.projectup.net/article/view/id/16556&#34;&gt;會賺錢就是好公司？賺錢公司其實有兩種，你現在待的是哪一種？&lt;/a&gt;〉也提到一則妙喻：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;小米雷軍有句名言：「站在風口上，豬都會飛。」而更多時候，馬雲這段話讓人更有感：「豬碰上風也會飛，但風過去摔死的還是豬！」（最近大陸的豬還真可憐～）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;儘管《&lt;a href=&#34;https://www.books.com.tw/products/0010802878&#34;&gt;什麼才是經營最難的事&lt;/a&gt;》較偏草創期的戰鬥智慧，但也非常強調長線的重要性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;公司要激勵優秀人才，莫過於有個&lt;strong&gt;重大使命&lt;/strong&gt;，凌駕在員工個人野心之上。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有偉大的&lt;strong&gt;產品願景&lt;/strong&gt;，固然需要輔以各項指標確實執行，但如果誤把指標當願景，再努力也達不到目標。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;看路不看牆&lt;/strong&gt;。賽車新手剛開始必學的一課是：以每小時兩百哩的車速行經彎道時，不能想著不要撞牆，而要專心在路面。心中只有牆，就會撞牆；心中只有路，就會沿著路面走。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以，你想當只會打野戰、只會搭順風火箭的人嗎？&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010802878&#34;&gt;什麼才是經營最難的事&lt;/a&gt;》第七章，將執行長分成平時執行長 (peacetime CEO) 與戰時執行長 (wartime CEO) 兩種類型。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>【主管的修練】讀書會</title>
      <link>//william-yeh.net/post/2018/12/practice-of-managers/</link>
      <pubDate>Mon, 24 Dec 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/12/practice-of-managers/</guid>
      
        <description>&lt;p&gt;稍早草擬的〈&lt;a href=&#34;//william-yeh.net/post/2018/11/succession-planning/&#34;&gt;接班人計畫&lt;/a&gt;〉偏向一對一的培訓。&lt;/p&gt;
&lt;p&gt;若是一對多呢？&lt;/p&gt;
&lt;p&gt;於是乎，就有了這份企劃：【主管的修練】讀書會。&lt;/p&gt;
&lt;p&gt;這一部分是模仿《&lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2014940760328&#34;&gt;利潤的故事&lt;/a&gt;》的做法 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，尤其是&lt;a href=&#34;https://wiki.mbalib.com/zh-tw/%E8%A9%B9%E5%A7%86%E6%96%AF%C2%B7%E9%9F%A6%E4%BC%AF%C2%B7%E6%89%AC&#34;&gt;楊傑美&lt;/a&gt;的「前端載入」方法。但我還融入剛學到的 &lt;a href=&#34;http://www.liberatingstructures.com/&#34;&gt;liberating structures&lt;/a&gt; 等技巧 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。改成速讀 + 互動討論的形式，應該既緊湊又有趣吧。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/front-end-loading.jpg&#34; alt=&#34;「前端載入」&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/front-end-loading.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;「前端載入」&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;以下是企劃內容。&lt;/p&gt;
&lt;h2 id=&#34;簡介&#34;&gt;簡介&lt;/h2&gt;
&lt;p&gt;探討初階中階主管的六大課題：① 領導與管理思維、② 參與式決策、③ 人才管理教育和支持、④ 溝通與衝突化解、⑤ 團隊績效的考核標準、⑥ 團隊文化和核心信念 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;課程以&lt;strong&gt;個案研討&lt;/strong&gt;形式為主，有大量&lt;strong&gt;課堂討論&lt;/strong&gt;，學員需要依照進度先行閱讀&lt;strong&gt;指定讀物&lt;/strong&gt;。能配合的，再考慮參加。&lt;/p&gt;
&lt;h2 id=&#34;適合對象&#34;&gt;適合對象&lt;/h2&gt;
&lt;p&gt;已經是，或有志於在職涯中成為主管者。&lt;/p&gt;
&lt;h2 id=&#34;進度&#34;&gt;進度&lt;/h2&gt;
&lt;p&gt;請依照指定進度，先自行&lt;strong&gt;想辦法&lt;/strong&gt;閱讀以下指定讀物。&lt;/p&gt;
&lt;h3 id=&#34;第一週領導&#34;&gt;第一週／領導&lt;/h3&gt;
&lt;p&gt;主要讀物：《&lt;a href=&#34;https://www.books.com.tw/products/0010445840&#34;&gt;領導，不需要頭銜&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;輔助讀物：〈&lt;a href=&#34;https://www.projectup.net/article/view/id/2457&#34;&gt;太多領導，太少管理&lt;/a&gt;〉，算是對《領導，不需要頭銜》pp. 78-81 的平衡報導。&lt;/p&gt;
&lt;h3 id=&#34;第二週管理&#34;&gt;第二週／管理&lt;/h3&gt;
&lt;p&gt;主要讀物：《&lt;a href=&#34;https://www.books.com.tw/products/0010641668&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;輔助讀物：系列文 / 專案管理的藝術&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⓪ &lt;a href=&#34;https://www.projectup.net/article/view/id/260&#34;&gt;決策的平衡點&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;① &lt;a href=&#34;https://www.projectup.net/article/view/id/259&#34;&gt;拉高視野、見林但不見樹&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;② &lt;a href=&#34;https://www.projectup.net/article/view/id/258&#34;&gt;平衡需求、但別想討好所有人&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;③ &lt;a href=&#34;https://www.projectup.net/article/view/id/256&#34;&gt;重點掌握、如何抓大放小&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;④ &lt;a href=&#34;https://www.projectup.net/article/view/id/255&#34;&gt;主動發現、弭禍於無形之中&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑥ &lt;a href=&#34;https://www.projectup.net/article/view/id/251&#34;&gt;品質管制、追求標準、一致、與穩定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑨ &lt;a href=&#34;https://www.projectup.net/article/view/id/67&#34;&gt;避免發散、一切都跟收斂有關&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;第三週管理&#34;&gt;第三週／管理&lt;/h3&gt;
&lt;p&gt;主要讀物：《&lt;a href=&#34;https://www.books.com.tw/products/0010805719&#34;&gt;可複製的領導力&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;輔助讀物：系列文 / 專案管理的藝術&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⑤ &lt;a href=&#34;https://www.projectup.net/article/view/id/253&#34;&gt;醜話先說，對事但不對人&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;⑦ &lt;a href=&#34;https://www.projectup.net/article/view/id/69&#34;&gt;降低流言、合適的訊息分享&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;第四週參與式決策&#34;&gt;第四週／參與式決策&lt;/h3&gt;
&lt;p&gt;主要讀物：《&lt;a href=&#34;https://www.taaze.tw/sing.html?pid=11100243769&#34;&gt;誰說我們不能一起做決定&lt;/a&gt;》 ＆ 《&lt;a href=&#34;https://funevo.com/2018/06/15/%E8%AE%8A%E9%9D%A9%E9%A0%98%E5%B0%8E%E8%80%85%E4%BC%81%E6%A5%AD%E6%95%8F%E6%8D%B7%E8%BD%89%E5%9E%8B%E6%8C%87%E5%8D%97/&#34;&gt;原來你才是絆腳石&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;輔助讀物：系列文 / Titansoft 的經驗談&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;引導：&lt;a href=&#34;https://funevo.com/2016/08/12/agile-scrum-needs-facilitation/&#34;&gt;敏捷 X 引導 – 讓 Scrum 團隊自組織的具體方法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;開放空間 #1：&lt;a href=&#34;https://funevo.com/2016/06/25/first-open-space-technology-in-titansoft/&#34;&gt;如魔術般的神奇空間 – 公司內舉辦開放空間會議初體驗&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;開放空間 #2：&lt;a href=&#34;https://funevo.com/2016/09/29/second-open-space-technology-in-titansoft/&#34;&gt;一回生、兩回熟 – 公司內開放空間會議第二彈&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;深度匯談 #1：&lt;a href=&#34;https://funevo.com/2015/10/29/ica%E6%B7%B1%E5%BA%A6%E5%8C%AF%E8%AB%87%E8%AA%B2%E7%A8%8B%E5%BF%83%E5%BE%97-dialogue/&#34;&gt;冒點險讓關係更緊密 – ICA 引導技術之深度匯談課程心得&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;深度匯談 #2：&lt;a href=&#34;https://funevo.com/2016/08/03/%E5%85%AC%E5%8F%B8%E7%B5%84%E7%B9%94%E5%85%A7%E8%88%89%E8%BE%A6%E6%B7%B1%E5%BA%A6%E5%8C%AF%E8%AB%87%E5%BC%95%E5%B0%8E%E8%AA%B2%E7%A8%8B/&#34;&gt;再探深度匯談 – 在公司組織內舉辦引導課程&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;第五週人才管理教育和支持&#34;&gt;第五週／人才管理教育和支持&lt;/h3&gt;
&lt;p&gt;主要讀物：《&lt;a href=&#34;https://www.books.com.tw/products/0010730316&#34;&gt;別讓績效管理毀了你的團隊&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;輔助讀物：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MJ老師〈我的 OKR Action Note 使用技巧說明〉&lt;a href=&#34;http://financemj.com/5782&#34;&gt;文章&lt;/a&gt;及&lt;a href=&#34;https://www.facebook.com/MJ1095/posts/10157115155824625&#34;&gt;影片&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010482108&#34;&gt;下一步，成功&lt;/a&gt;》第二章。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.hbrtaiwan.com/article_content_AR0003066.html&#34;&gt;績效管理再進化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.managertoday.com.tw/articles/view/56451&#34;&gt;想讓組織變敏捷，導入 Scrum 工作法只是開始！人資還該做的 2 件事&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;第六週團隊文化和核心信念&#34;&gt;第六週／團隊文化和核心信念&lt;/h3&gt;
&lt;p&gt;主要讀物：《&lt;a href=&#34;https://www.books.com.tw/products/0010796709&#34;&gt;給力&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;輔助讀物：系列文 / 專案管理的藝術&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⑧ &lt;a href=&#34;https://www.projectup.net/article/view/id/68&#34;&gt;沒有英雄、人員培育與接班計畫&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;輔助讀物：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010482108&#34;&gt;下一步，成功&lt;/a&gt;》第四章。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.hbrtaiwan.com/article_content_AR0006825.html&#34;&gt;如何管理比你聰明的人&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;第七週總結&#34;&gt;第七週／總結&lt;/h3&gt;
&lt;p&gt;主要讀物：《&lt;a href=&#34;https://www.books.com.tw/products/0010782941&#34;&gt;原則&lt;/a&gt;》第一部分 ＆ &lt;a href=&#34;https://tw.voicetube.com/videos/70025&#34;&gt;&lt;em&gt;Principles For Success&lt;/em&gt; 影片&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;輔助讀物：系列文 / 專案管理的藝術&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⑩ &lt;a href=&#34;https://www.projectup.net/article/view/id/65&#34;&gt;歷史借鏡、能重複應用的才有價值&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;上課前&#34;&gt;上課前&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;瀏覽學習單。&lt;/li&gt;
&lt;li&gt;速讀：每一份指定讀物，請在不超過 2 小時之內速讀完畢第一次。&lt;/li&gt;
&lt;li&gt;填寫學習單，頁數不夠請自行增印。&lt;/li&gt;
&lt;li&gt;如有時間，可再回頭重讀、細讀內容。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;上課時&#34;&gt;上課時&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;攜帶學習單。&lt;/li&gt;
&lt;li&gt;以 &lt;a href=&#34;http://www.liberatingstructures.com/&#34;&gt;liberating structures&lt;/a&gt; 及互動討論方式，進行個案研討。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;有些個案討論有隱私性考量，為促成坦誠討論，參與者需宣誓對現場討論內容保密 (咦)。&lt;/p&gt;
&lt;h2 id=&#34;全部課程結束後&#34;&gt;全部課程結束後&lt;/h2&gt;
&lt;p&gt;讀一讀 Andrew Grove 的《&lt;a href=&#34;https://www.books.com.tw/products/0010816790&#34;&gt;葛洛夫給經理人的第一課&lt;/a&gt;》。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;關於《&lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2014940760328&#34;&gt;利潤的故事&lt;/a&gt;》這本書，我在〈&lt;a href=&#34;//william-yeh.net/post/2018/12/2018-retrospective/&#34;&gt;2018 個人回顧&lt;/a&gt;〉一文有更詳細的介紹。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;我是在 Scrum.org 在台北舉辦的 &lt;a href=&#34;https://www.eventbrite.co.uk/e/scrumon-tickets-51310998578&#34;&gt;ScrumOn&lt;/a&gt; 活動中，第一次體驗有趣的 &lt;a href=&#34;http://www.liberatingstructures.com/&#34;&gt;liberating structures&lt;/a&gt; 技巧。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;這六大主題的界定，其中有五項是參考【&lt;a href=&#34;https://www.knack.com.tw/Event/ManagerSkill&#34;&gt;帶人的技術&lt;/a&gt;】線上課程的廣告文案。他們的文案列了五點：①建立成長型管理思維和觀念，②學會高素質人才管理、教育和支持，③檢視團隊內溝通與衝突化解方法，④評估團隊績效的適用考核標準，⑤樹立超強團隊文化和核心信念。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>2018 個人回顧</title>
      <link>//william-yeh.net/post/2018/12/2018-retrospective/</link>
      <pubDate>Thu, 20 Dec 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/12/2018-retrospective/</guid>
      
        <description>&lt;p&gt;到了年終，又開始要做個總回顧，再對來年許願。&lt;/p&gt;
&lt;p&gt;如果說 &lt;a href=&#34;https://school.soft-arch.net/blog/6676/2016-retrospective&#34;&gt;2016&lt;/a&gt; 和 &lt;a href=&#34;https://school.soft-arch.net/blog/13083/2017-retrospective&#34;&gt;2017&lt;/a&gt; 都是華麗冒險年，那麼，2018 對我來說，是收攝靜觀的一年。&lt;/p&gt;
&lt;p&gt;去除一些不便揭露的事情，以下是簡單的回顧。&lt;/p&gt;
&lt;h2 id=&#34;補血課程&#34;&gt;補血課程&lt;/h2&gt;
&lt;p&gt;這一年，由於財務及時間問題，參加的補血課程大幅減少。只能精選再精選。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://jackyliu.net/experience-gamification-class-design-training-course/&#34;&gt;體驗式課程的遊戲設計與操作實務&lt;/a&gt; (&lt;a href=&#34;//william-yeh.net/post/2018/04/board-game-creation/&#34;&gt;心得&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://shop.darencademy.com/product/view/id/70&#34;&gt;510 / 專案監管的系統思考及 KPI 設計攻防&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這兩門課，都是後座力十足，不管是觀念上還是實務上。後面都會提到。&lt;/p&gt;
&lt;p&gt;至於專題演講及研討會，參加的場次就多了，不及備載。&lt;/p&gt;
&lt;p&gt;其中悸動最深的，就屬 &lt;a href=&#34;https://en.wikipedia.org/wiki/Maria_Gomori&#34;&gt;Maria Gomori&lt;/a&gt; 的【&lt;a href=&#34;http://www.shiuhli.org.tw/class/class_detail.jsp?cp_id=CP1518514359291&#34;&gt;大師對談：在關係中重生－從糾纏到滋養&lt;/a&gt;】講座了。能親炙高齡 98 的國寶級大師，多麼難得的機緣呀！&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/maria-gomori.jpg&#34; alt=&#34;Maria Gomori, 2018-05-06, Taipei&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/maria-gomori.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Maria Gomori, 2018-05-06, Taipei&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這麼難得的機緣，說什麼，都得買第一排搖滾區的座位。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/listen-to-maria-gomori.jpg&#34; alt=&#34;第一排搖滾區&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/listen-to-maria-gomori.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;第一排搖滾區&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;坐在第一排，近距離觀察許多互動細節，驚喜發現，去年我在三梯次薩提爾培訓課程學到的 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，果然與 Maria Gomori 大師是一脈相承的。一整天的活動，彷彿一場總複習。&lt;/p&gt;
&lt;p&gt;而且是大師親自帶領的總複習。超值！&lt;/p&gt;
&lt;h2 id=&#34;演講及授課&#34;&gt;演講及授課&lt;/h2&gt;
&lt;p&gt;今年，演講次數也大幅減少：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.slideshare.net/williamyeh/agile-transition-a-toc-perspective&#34;&gt;從限制理論角度談敏捷導入階段&lt;/a&gt; (@ Agile Summit 2018)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;取而代之的，是授課及工作坊：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;系統思考的四堂課 (@ &lt;a href=&#34;//william-yeh.net/post/2018/06/sys-thinking-workshop/&#34;&gt;公司內訓&lt;/a&gt; &amp;amp; &lt;a href=&#34;//william-yeh.net/post/2018/09/thinking-weight-training/&#34;&gt;DevOpsDays Taipei 2018&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SBE 的四堂課 (@ 公司內訓)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;敏捷原理與團隊塑造・二日精修版 (&lt;a href=&#34;//william-yeh.net/post/2018/09/deliberate-practice-for-agile/&#34;&gt;給學員的話&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/12/agile-measurement/&#34;&gt;為了精準估算，你必須付出什麼代價？&lt;/a&gt; (@ Agile Tour Kaohsiung 2018)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;自從受過【&lt;a href=&#34;//william-yeh.net/post/2018/04/board-game-creation/&#34;&gt;體驗式課程的遊戲設計與操作實務&lt;/a&gt;】的洗禮，又讀過《&lt;a href=&#34;https://www.books.com.tw/products/0010752714&#34;&gt;刻意練習&lt;/a&gt;》及《&lt;a href=&#34;https://www.taaze.tw/products/11100227775.html&#34;&gt;豐田形學&lt;/a&gt;》，我越來越喜歡工作坊這種「微培訓」形式。明年應該也會繼續這樣子吧。&lt;/p&gt;
&lt;h2 id=&#34;量化之旅&#34;&gt;量化之旅&lt;/h2&gt;
&lt;p&gt;「精進量化技能」被我在 2017 年底列入&lt;a href=&#34;https://school.soft-arch.net/blog/13083/2017-retrospective&#34;&gt;來年許願項目&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;到了今年七月，因緣際會之下，參加了君婷老師這場開腦洞的首發課程。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/510-kpi-course.jpg&#34; alt=&#34;510 / 專案監管的系統思考及 KPI 設計攻防&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/510-kpi-course.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;510 / 專案監管的系統思考及 KPI 設計攻防&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這是專案管理課程。像「milestone 重於 WBS」的觀念，之前只是隱隱約約感覺到；但在課堂上被專家一語道破，我就更放心了。還有許許多多內容，都讓我可以融入到慣用的敏捷模型中。畢竟，人性是普遍的，箇中蘊含的系統動力也是普遍的。&lt;/p&gt;
&lt;p&gt;後來，我持續探索〈&lt;a href=&#34;//william-yeh.net/post/2018/11/agile-pmo/&#34;&gt;Agile PMO&lt;/a&gt;〉、〈&lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;〉、〈&lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;〉、〈&lt;a href=&#34;//william-yeh.net/post/2018/12/process-and-metrics/&#34;&gt;改變／改革：流程與衡量指標&lt;/a&gt;〉等議題，都是發軔自此課程的啟發。&lt;/p&gt;
&lt;p&gt;但這不僅僅是專案管理課程，更是開眼的「數字」教育。之後，再看其他涉及量化管理／公司治理的書，都格外有感：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/510-kpi-course-effect.png&#34; alt=&#34;對數字開始懷疑&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/510-kpi-course-effect.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;對數字開始懷疑&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;的確是打通任督二脈的補血課程！&lt;/p&gt;
&lt;h2 id=&#34;等比級數的推坑力&#34;&gt;等比級數的推坑力&lt;/h2&gt;
&lt;p&gt;要「精進量化技能」，免不了要更認識獲利模式。&lt;/p&gt;
&lt;p&gt;對工程背景的我來說，這是大工程。因此，我選擇用「系統閱讀」的方式去建構這方面的基本知識。&lt;/p&gt;
&lt;p&gt;起點是《&lt;a href=&#34;http://www.books.com.tw/products/0010473958&#34;&gt;10 年後會留在書架上的 100 本書&lt;/a&gt;》&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 。按圖索驥，挑選勝間和代的《&lt;a href=&#34;https://www.books.com.tw/products/0010474528&#34;&gt;創造利潤的方程式&lt;/a&gt;》來讀。這真是扎實建構思維模型的好書。讀完一次花了一整個禮拜，需要沉澱。改天還真想把這本書的精髓畫成 CLD 呢。&lt;/p&gt;
&lt;p&gt;事情還沒結束。&lt;/p&gt;
&lt;p&gt;勝間和代還推坑了另一本奇書《&lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2014940760328&#34;&gt;利潤的故事&lt;/a&gt;》 (&lt;a href=&#34;https://www.amazon.com/dp/0446692271/&#34;&gt;&lt;em&gt;The Art of Profitability&lt;/em&gt;&lt;/a&gt;)。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/the-art-of-profitability.jpg&#34; alt=&#34;創造利潤的方程式&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/the-art-of-profitability.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;創造利潤的方程式&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;拙作《創造利潤的方程式》的反面可說就是《利潤的故事》這種書。我是在「如果弄成只有一種利潤模型，會如何呢？」的想法之下，寫了那本書的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這就引起我的好奇心了：能夠讓勝間和代專門寫一本書來 &lt;del&gt;打對台&lt;/del&gt; 對比的，想必是不簡單的對手。&lt;/p&gt;
&lt;p&gt;果真如此。&lt;/p&gt;
&lt;p&gt;《利潤的故事》體裁雖然是商業小說，有趣，但不是本容易徹底消化的書。作者還特別提醒：不能讀得太快。得有耐心，照著書中的步調，乖乖寫作業（是的！有作業！）。更可怕的是，這本書居然也是個書坑，幾乎每一份作業，都順道規定一兩本指定讀物——簡直是等比級數的推坑力。&lt;/p&gt;
&lt;p&gt;既然《利潤的故事》也暗中運用系統閱讀的方法來安排章節及作業順序，既然我也下定決心要系統閱讀這議題，那麼，就乖乖的照著最右邊這本大書坑，按圖索驥吧。&lt;/p&gt;
&lt;p&gt;自己手邊只有老版本的《&lt;a href=&#34;https://www.books.com.tw/products/0010759410&#34;&gt;十倍速時代&lt;/a&gt;》與《&lt;a href=&#34;https://www.books.com.tw/products/0010590883&#34;&gt;愛因斯坦的夢&lt;/a&gt;》，靠著 TAAZE 才補上一些拼圖——但還是不齊。等簡體書及原文書到齊，再合拍一張吧。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/profitability-books.jpg&#34; alt=&#34;《利潤的故事》及推坑的叢書&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/profitability-books.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《利潤的故事》及推坑的叢書&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;《&lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2014940760328&#34;&gt;利潤的故事&lt;/a&gt;》推坑書單如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010264438&#34;&gt;洞悉大師亞當斯&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0990790916&#34;&gt;&lt;em&gt;Obvious Adams&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;燃燒的權力 / &lt;a href=&#34;https://www.amazon.com/dp/1559723351/&#34;&gt;&lt;em&gt;Power to Burn&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://sanmin.com.tw/Product/index/004047596&#34;&gt;數盲&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0679726012/&#34;&gt;&lt;em&gt;Innumeracy&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010759410&#34;&gt;十倍速時代&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0385483821/&#34;&gt;&lt;em&gt;Only the Paranoid Survive&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010450016&#34;&gt;創意的生成&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/1434102750/&#34;&gt;&lt;em&gt;A Technique for Producing Ideas&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010590883&#34;&gt;愛因斯坦的夢&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/140007780X/&#34;&gt;&lt;em&gt;Einstein&amp;rsquo;s Dreams&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;艾西莫夫論太空 / &lt;a href=&#34;https://www.amazon.com/dp/051727924X/&#34;&gt;&lt;em&gt;Asimov On Astronomy&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010791866&#34;&gt;富甲天下&lt;/a&gt; (新版) / &lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2024990010069&#34;&gt;天下第一店&lt;/a&gt; (舊版) / &lt;a href=&#34;https://www.amazon.com/dp/0385468474/&#34;&gt;&lt;em&gt;Sam Walton: Made in America: My Story&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2014940421779&#34;&gt;獲利寶典&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0812933044/&#34;&gt;&lt;em&gt;The Profit Zone&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://sanmin.com.tw/Product/index/005170987&#34;&gt;一個廣告人的自白&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/190491537X/&#34;&gt;&lt;em&gt;Confessions of an Advertising Man&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://sanmin.com.tw/Product/index/004045819&#34;&gt;奧格威談廣告&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/039472903X/&#34;&gt;&lt;em&gt;Ogilvy on Advertising&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;閱讀初步 / &lt;a href=&#34;https://www.amazon.com/dp/0811218937/&#34;&gt;&lt;em&gt;ABC of Reading&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;孫子兵法&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010064462&#34;&gt;Starbucks 咖啡王國傳奇&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0786883561/&#34;&gt;&lt;em&gt;Pour Your Heart Into It&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010131327&#34;&gt;永恆的價值&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/1681841649/&#34;&gt;&lt;em&gt;Of Permanent Value&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;典範 / &lt;a href=&#34;https://www.amazon.com/dp/0887306470/&#34;&gt;&lt;em&gt;Paradigms&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010137157&#34;&gt;利潤模式&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0812931181/&#34;&gt;&lt;em&gt;Profit Patterns&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2014940657314&#34;&gt;創造新財富&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0875846327/&#34;&gt;&lt;em&gt;Value Migration&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;羅素的制勝法則 / &lt;a href=&#34;https://www.amazon.com/dp/0525945989/&#34;&gt;&lt;em&gt;Russell Rules&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;力量之泉 / &lt;a href=&#34;https://www.amazon.com/dp/0262534290/&#34;&gt;&lt;em&gt;Sources of Power&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010137625&#34;&gt;數位革命&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0679762906/&#34;&gt;&lt;em&gt;Being Digital&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.books.com.tw/products/0010190543&#34;&gt;他們的數位化經營策略&lt;/a&gt; / &lt;a href=&#34;https://www.amazon.com/dp/0609607707/&#34;&gt;&lt;em&gt;How Digital Is Your Business?&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;洋洋灑灑，這就是我這兩個月以來沈重的閱讀清單呀。&lt;/p&gt;
&lt;p&gt;雖然沈重，但，浸潤在這種「藝術的學習」境界，也挺過癮的。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/levels-of-learning.jpg&#34; alt=&#34;學習，有五種層次 -- 《利潤的故事》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/levels-of-learning.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;學習，有五種層次 -- 《利潤的故事》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;收攝靜觀&#34;&gt;收攝靜觀&lt;/h2&gt;
&lt;p&gt;十二月，特地安排兩件事，讓自己有收攝靜觀的機會。&lt;/p&gt;
&lt;p&gt;距離上次親自玩 &lt;a href=&#34;https://zh.wikipedia.org/wiki/%E6%A8%82%E9%AB%98%E8%AA%8D%E7%9C%9F%E7%8E%A9&#34;&gt;LSP&lt;/a&gt; 也已經一年半了。正巧好友 Sam 要舉辦一場【&lt;a href=&#34;https://www.accupass.com/event/1811220930071664437086&#34;&gt;策略會議引導・樂高認真玩&lt;/a&gt;】，趕緊報名參加。&lt;/p&gt;
&lt;p&gt;年終，給自己一個沉澱的時間與空間。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/lsp-artwork.jpg&#34; alt=&#34;我的 LSP 作品之一 (2018-12-12)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/lsp-artwork.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;我的 LSP 作品之一 (2018-12-12)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;本週二，應好友之邀，去現場看看真正的 &amp;ldquo;scrum&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;身為 Scrum Master，沒親眼去現場看橄欖球，像話嗎？呵。年末，總是要熱血一下。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/rugby-game.png&#34; alt=&#34;2018 亞洲 U19 青年橄欖球錦標賽&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/rugby-game.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;2018 亞洲 U19 青年橄欖球錦標賽&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;從這兩場高強度的賽事中，領悟到不少 Scrum，甚至團隊經營的點點滴滴：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;衝刺，再衝刺&lt;/li&gt;
&lt;li&gt;傳球&lt;/li&gt;
&lt;li&gt;佈陣&lt;/li&gt;
&lt;li&gt;局部最佳化&lt;/li&gt;
&lt;li&gt;後勤&lt;/li&gt;
&lt;li&gt;目標&lt;/li&gt;
&lt;li&gt;Ａ咖&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Try&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Swarm&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Baseline&lt;/li&gt;
&lt;li&gt;Pivot&lt;/li&gt;
&lt;li&gt;餘裕&lt;/li&gt;
&lt;li&gt;下一步&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;太多太多聯想與感想。也不禁令我思考起自己的下一步。&lt;/p&gt;
&lt;h2 id=&#34;2019-許願&#34;&gt;2019 許願&lt;/h2&gt;
&lt;p&gt;2019 年，希望自己能做到：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;繼續更深度的 BOSA 探索與實踐。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;繼續精進量化技能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;正式正視與深化教練技能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重讀一次福爾摩斯（這是這兩年遺憾沒能做到的）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;增進商務英語聽說能力。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;開放冒險選項。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就醬。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;我在 2017 年上了三梯次為期九天的薩提爾培訓課程。相關心得請見〈&lt;a href=&#34;//william-yeh.net/post/2017/04/satir-workshop/&#34;&gt;六日薩提爾體驗&lt;/a&gt;〉及〈&lt;a href=&#34;//william-yeh.net/post/2017/08/facilitator-mindset/&#34;&gt;引導者，要懂心理&lt;/a&gt;〉這兩篇文章。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2016/08/reading-vs-extensive-reading/&#34;&gt;精讀 vs 泛讀&lt;/a&gt;〉一文中，有提到《&lt;a href=&#34;https://www.books.com.tw/products/0010473958&#34;&gt;10 年後會留在書架上的 100 本書&lt;/a&gt;》這本書。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>為了精準估算，你必須付出什麼代價？</title>
      <link>//william-yeh.net/post/2018/12/agile-measurement/</link>
      <pubDate>Wed, 19 Dec 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/12/agile-measurement/</guid>
      
        <description>&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/dilbert-measurement.jpg&#34; alt=&#34;開場對話&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/dilbert-measurement.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;開場對話&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;研發團隊，常會被問到一個問題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「請問一下，這個Ａ功能，大概要多久才能完成？」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這個問題，不會因為你跑的是敏捷，就自動免疫。那麼，身為經過敏捷思維洗禮的人，該如何做出合宜的應對？&lt;/p&gt;
&lt;p&gt;我在 &lt;a href=&#34;https://agilekaohsiung.kktix.cc/events/agiletourkaohsiung2018&#34;&gt;Agile Tour Kaohsiung 2018&lt;/a&gt; 開辦一場 2.5 小時的工作坊，帶領大家親自體驗這個議題。&lt;/p&gt;
&lt;p&gt;不過，這個題材的背後，其實還有三段故事。&lt;/p&gt;
&lt;p&gt;故事，要從一年半前講起。&lt;/p&gt;
&lt;h2 id=&#34;第一段故事結構化流程&#34;&gt;第一段故事：結構化流程&lt;/h2&gt;
&lt;p&gt;一年半前，我曾提過一個心願：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我想用&lt;strong&gt;結構化的 Sprint Planning 流程&lt;/strong&gt;，讓錨定效應、以關係為中心、目的型談判自然發生，讓參與其中的人，逐漸在刻意不遮掩的建設性衝突中，潛移默化。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這個心願，即使我今年已經將自己的招牌課程【敏捷原理與團隊塑造】進化到二日版 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，也都還未能夠實現。要完整實現，恐怕得擴充至二天半，甚至三日版。&lt;/p&gt;
&lt;p&gt;這是一個小缺憾。&lt;/p&gt;
&lt;p&gt;年底正好有個在 &lt;a href=&#34;https://agilekaohsiung.kktix.cc/events/agiletourkaohsiung2018&#34;&gt;Agile Tour Kaohsiung 2018&lt;/a&gt; 舉辦工作坊的機會，我就來小試一下心中設想的「結構化的 Sprint Planning 流程」，以後再看看有沒有機會將這次經驗併入招牌課程。&lt;/p&gt;
&lt;h2 id=&#34;第二段故事衡量&#34;&gt;第二段故事：衡量&lt;/h2&gt;
&lt;p&gt;設計工作坊，要先定義好最核心的體驗內容。&lt;/p&gt;
&lt;p&gt;Sprint planning，或者 release planning，都有一個共同議題：&lt;strong&gt;衡量&lt;/strong&gt;。正好這陣子我一直在研究這類衡量、指標等相關議題 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;，便將工作坊的題目訂為【為了精準估算，你必須付出什麼代價？】。&lt;/p&gt;
&lt;p&gt;核心的體驗內容決定好了，體驗的動線，則以《&lt;a href=&#34;https://www.books.com.tw/products/0010622743&#34;&gt;如何衡量萬事萬物&lt;/a&gt;》這本書做為參考標的。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/how-to-measure-anything.jpg&#34; alt=&#34;如何衡量萬事萬物&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/how-to-measure-anything.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;如何衡量萬事萬物&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;第一次看到這本書名，是在《&lt;a href=&#34;https://www.books.com.tw/products/0010738675&#34;&gt;精實企業&lt;/a&gt;》及《&lt;a href=&#34;https://www.books.com.tw/products/0010580487&#34;&gt;精實執行&lt;/a&gt;》。能同時被這兩本經典引述，想必非泛泛之書。&lt;/p&gt;
&lt;p&gt;當時只覺得可以從中借用到一些衡量妙法，像是&lt;a href=&#34;https://en.wikipedia.org/wiki/Fermi_problem&#34;&gt;費米推論&lt;/a&gt;之類的。萬萬沒想到，這簡直是改變三觀的奇書。恰好又跟我這陣子在系統閱讀的主軸相吻合，讀來可說是點頭如搗蒜。&lt;/p&gt;
&lt;p&gt;看懂這本書，內化並實踐，有助於從根本解決一些盤根錯節的敏捷持久落地的企業面難題。&lt;/p&gt;
&lt;p&gt;初步啃完這本奇書，就花了我好幾天，累積起來共十七個小時。十七小時的心得，在短短的 2.5 小時的工作坊是無法盡數展現出來的，我只能先揀選一個雖粗淺但稱得上是全貌的流程，作為工作坊的體驗主動線。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/aie-flow.png&#34; alt=&#34;AIE 通用衡量方法&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/aie-flow.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;AIE 通用衡量方法&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;第三段故事pdca&#34;&gt;第三段故事：PDCA&lt;/h2&gt;
&lt;p&gt;核心的體驗內容決定好了，體驗的動線也決定好了，就剩下體驗的劇本了。&lt;/p&gt;
&lt;p&gt;既然要辦的是工作坊，重點自然不是說教，而是體驗，而且是能成為肌肉記憶的體驗。&lt;/p&gt;
&lt;p&gt;這一點比較簡單。自從經過【&lt;a href=&#34;https://jackyliu.net/experience-gamification-class-design-training-course/&#34;&gt;體驗式課程的遊戲設計與操作實務&lt;/a&gt;】的洗禮 &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;，我將招牌課程【敏捷原理與團隊塑造】調整成「&lt;strong&gt;高速高頻率 PDCA 循環&lt;/strong&gt;」的風格，廣受好評，已成為自己的拿手招術。&lt;/p&gt;
&lt;p&gt;因此，我決定這次的工作坊，也比照辦理。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/speech-1215.png&#34; alt=&#34;高速高頻率 PDCA 循環&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/speech-1215.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;高速高頻率 PDCA 循環&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;在敏捷世界裡，不管是 sprint planning 還是 release planning，都很強調全員參與。因此，我的工作坊劇本也設計成要全員參與，以反應真實情況：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在這兩個半小時的體驗活動中，我會用真實案例的改編版本，帶大家體驗 Sprint Planning 及 Backlog Refinement 的核心要素。不管你是 PO、PM、UX、RD、QA，都能從活動中親自體認到，我們到底有沒有必要追求精準的估算？以及，萬一真的有必要，我們又該做什麼樣的準備？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;分組方法有很多，有安全穩當的，也有刺激難以掌控的。當天在 &lt;a href=&#34;https://agilekaohsiung.kktix.cc/events/agiletourkaohsiung2018&#34;&gt;Agile Tour Kaohsiung 2018&lt;/a&gt; 活動現場，看到大家非常專業，便臨時起意，將現場人士分成三大組：Scrum Master 組、PO 組、developer 組。&lt;/p&gt;
&lt;p&gt;非常冒險的決定。但，敏捷，本來就是要冒必要的險嘛！&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/measurement-groups.png&#34; alt=&#34;分組&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/measurement-groups.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;分組&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;整場 2.5 小時的活動，有笑聲，有&lt;del&gt;吵架聲&lt;/del&gt;激辯聲（過程中一度擦出火花），也有嚴肅的制憲大會——像極了真實的職場情境：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/process-meeting.png&#34; alt=&#34;流程會議&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/process-meeting.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;流程會議&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;感謝超強的參與者，尤其是始料未及的 Scrum Master 組，讓我這場首發的工作坊，得到超出我預期的效果／笑果。&lt;/p&gt;
&lt;p&gt;「&lt;strong&gt;高速高頻率 PDCA 循環&lt;/strong&gt;」風格，在這 2.5 小時中，應該算是嚴格貫徹了。&lt;/p&gt;
&lt;h2 id=&#34;未央歌&#34;&gt;未央歌&lt;/h2&gt;
&lt;p&gt;一年半前許下的心願「&lt;strong&gt;結構化的 Sprint Planning 流程&lt;/strong&gt;」，這次 2.5 小時的工作坊，大約實現了六成。&lt;/p&gt;
&lt;p&gt;要完全實現，全程可能要 3 小時。&lt;/p&gt;
&lt;p&gt;在改版成功之前，先貼出這場 2.5 小時 Workshop 可公開的部分。&lt;/p&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/125954954&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;
&lt;p&gt;下一步呢？請靜待吧。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2017/07/sprint-planning-as-negotiation/&#34;&gt;以談判角度看 Sprint Planning&lt;/a&gt;〉文章中，談到我對高品質的 Sprint Planning 有著不一樣的願景。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;今年我將自己的招牌課程【敏捷原理與團隊塑造】升級成【二日精修版】，承載更多我想傳達的核心理念。最近剛結束的公開班是 &lt;a href=&#34;https://www.accupass.com/event/1807260907551870930205&#34;&gt;2018-09-13～09-14&lt;/a&gt; 這一梯次，課後感想文&lt;a href=&#34;//william-yeh.net/post/2018/09/deliberate-practice-for-agile/&#34;&gt;在此&lt;/a&gt;。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;這陣子研究衡量、指標等相關議題，相關心得請見〈&lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;〉、〈&lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;〉、〈&lt;a href=&#34;//william-yeh.net/post/2018/12/process-and-metrics/&#34;&gt;改變／改革：流程與衡量指標&lt;/a&gt;〉等文。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;詳見〈&lt;a href=&#34;//william-yeh.net/post/2018/04/board-game-creation/&#34;&gt;三週生出一款新桌遊，一段奇幻旅程&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>改變／改革：流程與衡量指標</title>
      <link>//william-yeh.net/post/2018/12/process-and-metrics/</link>
      <pubDate>Fri, 07 Dec 2018 13:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/12/process-and-metrics/</guid>
      
        <description>&lt;p&gt;改革，很不容易；摧毀改革，卻很簡單。知名的&lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/&#34;&gt;改革框架&lt;/a&gt;，莫不注重改革的&lt;strong&gt;整合&lt;/strong&gt;與&lt;strong&gt;固化&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;敏捷亦然。像這篇文章〈&lt;a href=&#34;https://mp.weixin.qq.com/s/p8pDpC80iOMSY28SWSeZyg&#34;&gt;慢慢的，公司内敏捷的热度就退了&amp;hellip;..&lt;/a&gt;〉就訴說一則可悲的故事：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我並沒有告訴他們具體要怎樣做，只給了他們一些理論上的指導，然後他們就開始集思廣益，動手佈置。這其中展現出來的主動思考能力、自組織能力和執行力，讓我不由得暗地裡豎起大拇指。基於這樣良好的基礎，他們的敏捷過程推進的也非常順利，我輔導了他們 3 個月左右，他們已經熟練的掌握了一些實踐方法，加上本身已經具備的自組織能力和執行力，似乎繼續做下去，就可以達到不錯的成熟度。&lt;/p&gt;
&lt;p&gt;然而時隔一年後，我偶然路過他們的辦公區，才發現一切並沒有照著「理所當然」發展，而是都恢復了原樣。&lt;/p&gt;
&lt;p&gt;團隊成員坐在各自的工位上埋頭工作，他們不再聚集在白板前。專案經理每週一將工作分配好，並定期檢查狀態。工作區氣氛嚴肅而沉悶，一個似乎是 Leader 的人大聲訓斥著員工，指責他反覆犯同樣的錯誤。&lt;/p&gt;
&lt;p&gt;似乎，敏捷從未來過。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如何確保改革的&lt;strong&gt;整合&lt;/strong&gt;與&lt;strong&gt;固化&lt;/strong&gt;，而不只是曇花一現？&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Eliyahu_M._Goldratt&#34;&gt;高德拉特&lt;/a&gt;的《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》裡頭藏有這問題的答案，藏在兩處很少被人提到的橋段。&lt;/p&gt;
&lt;h2 id=&#34;偏執執著的伏筆&#34;&gt;偏執、執著的伏筆&lt;/h2&gt;
&lt;p&gt;在書中，主角羅哥 (Alex Rogo) &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 是優尼公司白靈頓鎮的工廠廠長。他與工廠財務長劉梧 (Lou)、生產經理唐納凡 (Bob Donovan) 等人，努力拯救工廠的經營危機。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/rogo-and-others.png&#34; alt=&#34;羅哥、劉梧、唐納凡 (From: The Goal)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/rogo-and-others.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;羅哥、劉梧、唐納凡 (From: The Goal)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;經過一番奮鬥，終於立下了顯赫戰功，主角羅哥在升官執掌三個工廠的事業部之前，認真反思過去三個月跌跌撞撞的過程，試圖歸納出可複製的成功因素。他們在《目標》第 32～40 章進行多場機鋒對話，&lt;a href=&#34;https://www.tocinstitute.org/five-focusing-steps.html&#34;&gt;聚焦五步驟&lt;/a&gt;就是在這思辨交鋒過程中總結出來的。&lt;/p&gt;
&lt;p&gt;不過，鮮為人知的是，這幾章還隱藏一個重要的改革訣竅，埋在一段獨白與一段對話中：&lt;/p&gt;
&lt;p&gt;❶ 在第 40 章，羅哥有一段內心獨白：「唐納凡說得對，劉梧對&lt;strong&gt;衡量指標&lt;/strong&gt;簡直有一種偏執。」這是第一個哏。&lt;/p&gt;
&lt;p&gt;❷ 在第 36 章，羅哥對唐納凡說了一句話：「假如劉梧對&lt;strong&gt;衡量指標&lt;/strong&gt;很執著，那麼你（唐納凡）一定是對&lt;strong&gt;流程&lt;/strong&gt;很執著了。」這是第二個哏。&lt;/p&gt;
&lt;p&gt;你能體會為什麼高德拉特會刻意埋這兩個所謂偏執、執著的伏筆嗎？我也是不斷反思改革的成與敗，才漸漸體會到這伏筆的精妙。&lt;/p&gt;
&lt;h2 id=&#34;敏捷固化的軌跡&#34;&gt;敏捷固化的軌跡&lt;/h2&gt;
&lt;p&gt;改變／改革要固化，需要辨識出流程與衡量指標。&lt;/p&gt;
&lt;p&gt;如果單以《目標》來說，&lt;strong&gt;流程&lt;/strong&gt;是指&lt;a href=&#34;https://www.tocinstitute.org/five-focusing-steps.html&#34;&gt;聚焦五步驟&lt;/a&gt;，&lt;strong&gt;衡量指標&lt;/strong&gt;是指 &lt;a href=&#34;https://en.wikipedia.org/wiki/Throughput_accounting&#34;&gt;T, I, OE&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;敏捷轉型，既然是一種改變／改革，也會遵循類似的軌跡。就以前面那篇&lt;a href=&#34;https://mp.weixin.qq.com/s/p8pDpC80iOMSY28SWSeZyg&#34;&gt;文章&lt;/a&gt;最後提出三點「想讓改變不再是一陣風」建議來說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;改變考核機制，在改變的初期調低原有 KPI 指標，增加對輔助工具（敏捷、精益或其他方法）的使用情況的考核。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在改變過程中，發現對組織有益的流程，要加入到 KPI 中，變為日常考核的一部分。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;給所有好的「動因」以正向的反饋，即使結果看起來沒那麼炫目。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;這三點建議，正好與《目標》第 32～40 章的&lt;strong&gt;流程&lt;/strong&gt;與&lt;strong&gt;衡量指標&lt;/strong&gt;兩大伏筆相互呼應。&lt;/p&gt;
&lt;p&gt;看到這裡，不禁對埋哏的高德拉特肅然起敬。《目標》第 32～40 章，真的值得用思辨的大腦多讀幾遍。&lt;/p&gt;
&lt;p&gt;好的商業小說，需要對等的識讀力。&lt;/p&gt;
&lt;h2 id=&#34;結語&#34;&gt;結語&lt;/h2&gt;
&lt;p&gt;改變／改革要固化，需要內外兼修。其中，流程與衡量指標，是關鍵的硬性要素。因此，除了擘劃&lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/&#34;&gt;改變的框架&lt;/a&gt;，別忘了也要設置適當的衡量指標。&lt;/p&gt;
&lt;p&gt;衡量指標是兩面刃，要謹慎，尤其是均衡感。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 掌握到均衡感，將能促進改變／改革的固化。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/&#34;&gt;改變的框架&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 改變／改革：流程與衡量指標&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/05/evaluation-process-for-changes/&#34;&gt;推動改變的評估流程&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》主角 Alex Rogo 的中譯名，原本是「羅哥」，但 2021 的譯本卻改譯為「羅戈」。我個人較偏好舊譯。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;針對衡量指標的均衡感，請參考我的兩篇文章：〈&lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;〉與〈&lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>Scrum 沒有明說的事：休耕期</title>
      <link>//william-yeh.net/post/2018/12/fallow/</link>
      <pubDate>Tue, 04 Dec 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/12/fallow/</guid>
      
        <description>&lt;p&gt;Scrum 的官方白皮書 &lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 非常輕薄短小（像 &lt;a href=&#34;https://scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-US.pdf&#34;&gt;Nov 2017 版&lt;/a&gt;只有 19 頁），它的理念是：只制定最核心的原則、價值、角色、活動、產出物，其餘的則交給團隊根據經驗主義 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 去調適出最適合自己的細節。&lt;/p&gt;
&lt;p&gt;想當然爾，有很多事，Scrum 並沒有明說。&lt;/p&gt;
&lt;p&gt;那麼，沒有明說的事，就不需要做、就不能做了嗎？做了，就違反 Scrum 嗎？&lt;/p&gt;
&lt;p&gt;這是許多奉 &lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 為圭臬的人，常有的盲點。&lt;/p&gt;
&lt;h2 id=&#34;scrum-沒有所謂的暫停&#34;&gt;Scrum 沒有所謂的「暫停」？&lt;/h2&gt;
&lt;p&gt;譬如說，有人對 sprint 這種百米賽跑的壓力提出&lt;a href=&#34;https://www.facebook.com/groups/179345672472/permalink/10156062491697473/&#34;&gt;疑問&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Run scrum 一陣子了，有感覺到一些跟傳統軟體開發專案不一樣的&lt;strong&gt;壓力&lt;/strong&gt;。以前這種方式對 team member 來說，會有&lt;strong&gt;淡季&lt;/strong&gt;跟&lt;strong&gt;旺季&lt;/strong&gt;的差別，所以大家比較好安排自己的休假，或者在淡季的時候安排一些 researching、training 的工作。&lt;/p&gt;
&lt;p&gt;現在 run scrum 覺得每個 sprint 壓力都好大，每個 sprint 都好趕，都剛剛好在最後一刻達到 sprint goal。大家也會因為齊步走的關係，所以都不太好意思請長一點的假。以前一年可能最多面臨四次 milestone review 的壓力，現在是至少每四週都會面臨一次這種壓力，Scrum guide 又說 sprint 開始以後就是一個 sprint 接一個下去，中間不會有間斷，但我們真的好想暫停 0.5 個 sprint 讓大家喘口氣。&lt;/p&gt;
&lt;p&gt;前輩們都怎麼處理休假問題跟這種持續性壓力的問題呢？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Scrum 真的沒有「暫停」這件事嗎？&lt;/p&gt;
&lt;p&gt;首先，回到 &lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 原始文本，看看它是怎麼說的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Sprint&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sprints have consistent durations throughout a development effort. A new Sprint starts immediately after the conclusion of the previous Sprint.&lt;/p&gt;
&lt;p&gt;Sprint 長度在整個開發過程中都是固定的，前一個
Sprint 結束後，下一個新的 Sprint 立刻接著開始。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果只以形式主義來說，這些 sprints 的確好像是一棒接著一棒，棒棒相傳，不漏接，無止息——沒有假期。&lt;/p&gt;
&lt;p&gt;再進一步思考 sprint 這個載具的原始目的——即所謂 &lt;strong&gt;sprint goal&lt;/strong&gt;，就可發現，goal 的意義，是由我們 Scrum team 來賦予的。就連 &lt;em&gt;The Scrum Guide&lt;/em&gt; 都叫你要保持彈性，不要形式主義：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Each Sprint may be considered a project with no more than a one-month horizon. Like projects, Sprints are used to &lt;strong&gt;accomplish something&lt;/strong&gt;. Each Sprint has a &lt;strong&gt;goal&lt;/strong&gt; of what is to be built, a design and &lt;strong&gt;flexible plan&lt;/strong&gt; that will guide building it, the work, and the resultant product increment.&lt;/p&gt;
&lt;p&gt;每個 Sprint 可視為一個不超過一個月的專案，如同其他專案一般，Sprint 是用來完成某些事情的。每個 Sprint 有著要打造些什麼的目標，而由一份設計和有&lt;strong&gt;彈性&lt;/strong&gt;的計畫來引導其打造的過程、工作與最後的產品 Increment。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sprint goal 的意義，是由我們 Scrum team 來賦予的。&lt;/p&gt;
&lt;p&gt;問題是，你想賦予什麼意義呢？&lt;/p&gt;
&lt;p&gt;譬如說，市場探索，可不可以是一種 sprint goal 呢？用戶研究，可不可以是一種 sprint goal 呢？五日 &lt;a href=&#34;https://www.gv.com/sprint/&#34;&gt;design sprint&lt;/a&gt;，可不可以是一種 sprint goal 呢？&lt;/p&gt;
&lt;p&gt;甚至有點離經叛道的講：恢復元氣，能不能算是一種 sprint goal 呢？&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/sprint-rest.png&#34; alt=&#34;地力需要恢復，人力也是。&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/sprint-rest.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;地力需要恢復，人力也是。&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;休耕期&#34;&gt;休耕期&lt;/h2&gt;
&lt;p&gt;恢復軟體本身的元氣，有一個更正式的名詞——&lt;strong&gt;休耕期&lt;/strong&gt; (fallow)。&lt;/p&gt;
&lt;p&gt;在《&lt;a href=&#34;https://www.books.com.tw/products/0010511808&#34;&gt;編程的頂尖對話&lt;/a&gt;》中，大神 Douglas Crockford 如此解釋軟體研發領域的&lt;strong&gt;休耕期&lt;/strong&gt;觀點： &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/fallow.jpg&#34; alt=&#34;軟體研發的休耕期&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/fallow.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;軟體研發的休耕期&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;「一般來說，團隊應該知道什麼時候合適（進行這種清理程式碼、重寫的事）」，大神 Douglas Crockford 毫不客氣挑明地講：「管理層很難看到這一點⋯⋯管理層很久之後才會發現。」&lt;/p&gt;
&lt;p&gt;如果沒有這種特地保留起來的休耕期，那麼，重構、技術債的議題，幾乎註定會一直被推遲到比馬里亞納海溝還更低的順位。這將嚴重破壞 Scrum 的基石：&lt;a href=&#34;//william-yeh.net/post/2018/10/agile-criteria/#scrum-的判準&#34;&gt;PSPI&lt;/a&gt; &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;敏捷陣營也有人呼應這種想法。像 Toronto Agile Conference 2017 有一場演講 “&lt;a href=&#34;https://www.youtube.com/watch?v=iJoLe0fnWKc&amp;amp;feature=youtu.be&amp;amp;t=54m2s&#34;&gt;Technical Debt Is a Systemic Problem, Not A Personal Failing&lt;/a&gt;”，用的是 &amp;ldquo;technical-debt sprints&amp;rdquo; 一詞，還畫出 CLD 呢：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/12/td-sprints.png&#34; alt=&#34;Technical-Debt Stories and Sprints&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/12/td-sprints.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Technical-Debt Stories and Sprints&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;「休耕期」觀念，不是出於傳統的 Scrum 論述，&lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 也沒講，你認為它有違反 Scrum 嗎？&lt;/p&gt;
&lt;h2 id=&#34;如何做&#34;&gt;如何做？&lt;/h2&gt;
&lt;p&gt;那麼，該如何踏出第一步呢？或者更敏感地講：誰該去在貓脖子上掛鈴鐺？&lt;/p&gt;
&lt;p&gt;大神 Douglas Crockford 說：「團隊應該知道什麼時候合適，管理層很久之後才會發現。」&lt;/p&gt;
&lt;p&gt;所以，請先自問：你們有規律地跑 retrospective 嗎？在團隊層次，甚至在更大的組織層次？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2018-12-21 補充
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;我參加 Scrum.org 在台北舉辦的 &lt;a href=&#34;https://www.eventbrite.co.uk/e/scrumon-tickets-51310998578&#34;&gt;#ScrumOn&lt;/a&gt; 活動。經過六十分鐘 &lt;a href=&#34;https://www.scrum.org/professional-scrum-master-i-certification&#34;&gt;PSM I&lt;/a&gt; 洗禮，以及敏捷專家學會 Percy 的推坑，特地去查閱 &lt;a href=&#34;https://www.scrum.org/resources/nexus-guide&#34;&gt;&lt;em&gt;Nexus Guide&lt;/em&gt;&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;發現，裡面正好有特地提到技術債議題。特地摘錄於此：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;軟體開發必須在&lt;strong&gt;技術債&lt;/strong&gt;變得讓 Nexus 不可接受前，找出並解析依賴關係。若缺乏透明度，不可能有效指引 Nexus 有效地將風險最小化並將價值最大化。&lt;/p&gt;
&lt;p&gt;Software must be developed so that dependencies are detected and resolved before &lt;strong&gt;technical debt&lt;/strong&gt; becomes unacceptable to the Nexus. A lack of complete transparency will make it impossible to guide a Nexus effectively to minimize risk and maximize value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 說：「Scrum 是立基於經驗導向的流程控制理論 (empirical process control theory)，或是經驗主義。經驗主義立論於知識來自於經驗和依照已知的資訊來下判斷。Scrum 使用疊代和逐步 increment 的方式，來最大化可預測性和控制風險。」&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Douglas Crockford 在 CUSEC 2010 Keynote - &lt;a href=&#34;https://blogs.msdn.microsoft.com/cdndevs/2010/02/06/cusec-2010-keynote-douglas-crockford-the-software-crisis/&#34;&gt;The Software Crisis&lt;/a&gt; 這場演講主張：&amp;lsquo;Perhaps we should take advice from Exodus: &amp;ldquo;Plant and harvest crops for six years, but let the land rest and lie fallow during the seventh year.&amp;rdquo; Maybe do six sprints where you add new features, but on the seventh sprint, don’t add new features at all.&amp;rsquo;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;我個人認為，Scrum 的判準，就在於 increment，以及能否在各個疊代過程中，捍衛並精進這個 increment 的整全狀態。詳見〈&lt;a href=&#34;//william-yeh.net/post/2018/10/agile-criteria/&#34;&gt;敏捷的判準&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>為什麼 LeSS 這麼迷人，可是總是輸給 SAFe？</title>
      <link>//william-yeh.net/post/2018/11/why-safe-over-less/</link>
      <pubDate>Fri, 30 Nov 2018 15:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/11/why-safe-over-less/</guid>
      
        <description>&lt;p&gt;在一篇 &lt;a href=&#34;https://medium.com/@wangtrying/%E9%80%99%E6%98%AF%E5%80%8B%E5%B0%8D%E8%A9%B1%E7%B4%80%E9%8C%84-ebca3a63bbde&#34;&gt;Terry &amp;amp; Ruddy 對話紀錄&lt;/a&gt;中，看到一系列有趣的 &lt;a href=&#34;https://less.works/&#34;&gt;LeSS&lt;/a&gt; vs. &lt;a href=&#34;https://www.scaledagileframework.com/&#34;&gt;SAFe&lt;/a&gt; 討論：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「為什麼 &lt;a href=&#34;https://less.works/&#34;&gt;LeSS&lt;/a&gt; 這麼迷人，可是總是輸給 &lt;a href=&#34;https://www.scaledagileframework.com/&#34;&gt;SAFe&lt;/a&gt;？」&lt;/p&gt;
&lt;p&gt;「SAFe 是敏捷跟辦公室政治作出了完美的妥協（應該吧？），所以大家比較 Buy-in 吧。」&lt;/p&gt;
&lt;p&gt;「可是 LeSS 乾淨啊，所有會 Scrum 的人讀到 LeSS 都會喜歡啊。」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;正好這陣子也在思考這議題，便忍不住狗尾續貂一下。我只從「控制權」角度補充一則觀察。&lt;/p&gt;
&lt;h2 id=&#34;less&#34;&gt;LeSS&lt;/h2&gt;
&lt;p&gt;LeSS 直接就在名字表明它的「乾淨」立場，它就是崇尚 “less is more”、“&lt;a href=&#34;https://less.works/less/principles/more-with-less.html&#34;&gt;more with less&lt;/a&gt;” 哲學的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LeSS can be viewed as a &lt;em&gt;scaling&lt;/em&gt; framework for product development, but can also be viewed as a &lt;em&gt;descaling&lt;/em&gt; framework for organizations.&lt;/p&gt;
&lt;p&gt;    &amp;mdash; LeSS / Principles / &lt;a href=&#34;https://less.works/less/principles/more-with-less.html&#34;&gt;More with LeSS&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;崇尚 less 結構，也崇尚 less 控制與監管。LeSS 主張「支持，而非控制」：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The managers’ frame of mind must be &lt;strong&gt;support&lt;/strong&gt;, not &lt;strong&gt;control&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Management support from the person(s) who has the organizational authority to make structural changes in your group&amp;mdash;usually the head of your product group. This support must be&amp;hellip; &lt;strong&gt;supporting&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;True volunteering is a powerful way of engaging peoples’ minds and hearts. It’s underused, probably due to the feeling of &lt;strong&gt;loss of control&lt;/strong&gt; by managers. But for people in teams it feels empowering.&lt;/p&gt;
&lt;p&gt;    &amp;mdash; LeSS / Adoption / &lt;a href=&#34;https://less.works/less/adoption/three-principles.html&#34;&gt;Three Principles&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這些「支持，而非控制」的傾向，可直接上溯至敏捷思維的源頭——2001 年揭櫫的敏捷根本原則「&lt;strong&gt;自組織團隊&lt;/strong&gt;」：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The best architectures, requirements, and designs
emerge from &lt;strong&gt;self-organizing teams&lt;/strong&gt;.
最佳的架構、需求與設計皆來自於能自我組織的團隊。&lt;/p&gt;
&lt;p&gt;    &amp;mdash; &lt;a href=&#34;https://agilemanifesto.org/principles.html&#34;&gt;Principles behind the Agile Manifesto&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以前面那則&lt;a href=&#34;https://medium.com/@wangtrying/%E9%80%99%E6%98%AF%E5%80%8B%E5%B0%8D%E8%A9%B1%E7%B4%80%E9%8C%84-ebca3a63bbde&#34;&gt;對話紀錄&lt;/a&gt;評論道「可是 LeSS 乾淨啊」。&lt;/p&gt;
&lt;h2 id=&#34;safe&#34;&gt;SAFe&lt;/h2&gt;
&lt;p&gt;從這角度來看，SAFe 的「自組織團隊」程度就比較偏低了。&lt;/p&gt;
&lt;p&gt;在 SAFe 的 &lt;a href=&#34;https://www.scaledagileframework.com/value-stream-coordination/&#34;&gt;value stream coordination&lt;/a&gt; 體系之下，有結構化的&lt;strong&gt;敏捷發布火車&lt;/strong&gt; (&lt;a href=&#34;https://www.scaledagileframework.com/agile-release-train/&#34;&gt;agile release train&lt;/a&gt;; ART)，有與之搭配的一系列結構化機制；以及⋯⋯專屬角色。&lt;/p&gt;
&lt;p&gt;儘管 SAFe 第九原則是 “&lt;a href=&#34;https://www.scaledagileframework.com/decentralize-decision-making/&#34;&gt;decentralize decision-making&lt;/a&gt;”，但是，從這些專屬機制與角色的配置來看，監管與控制的程度，SAFe 顯然較對傳統組織的胃口：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/safe-product-and-solution-mgmt.png&#34; alt=&#34;Product and Solution Management (from SAFe)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/safe-product-and-solution-mgmt.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Product and Solution Management (from SAFe)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;沒有明言的事&#34;&gt;沒有明言的事&lt;/h2&gt;
&lt;p&gt;沒有明講的，不代表就不會存在。&lt;/p&gt;
&lt;p&gt;Scrum 規模一但擴大，就必定會需要某種程度的&lt;strong&gt;協調&lt;/strong&gt;與&lt;strong&gt;對齊&lt;/strong&gt;。SAFe 和 LeSS 都不否認這些事情的存在，差別在因應的態度、處理的方式。&lt;/p&gt;
&lt;p&gt;SAFe 認為，要主動定義這些&lt;strong&gt;控制&lt;/strong&gt;機制：新角色、新決策小組、新節奏。&lt;/p&gt;
&lt;p&gt;LeSS 認為，more with less，不須大動干戈引進新角色、新決策小組、新節奏。既有的 Scrum 三角色直接沿用，只要原班人馬再組成 &lt;a href=&#34;https://less.works/less/less-huge/area-product-owner.html&#34;&gt;product owner team&lt;/a&gt; 即可（頂多再有個 &lt;a href=&#34;https://less.works/less/structure/organizational-structure.html&#34;&gt;head of product group&lt;/a&gt; 做為組織結構上的管理者）。&lt;/p&gt;
&lt;p&gt;對於「控制權」不同的態度，決定了不同的導入方式。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;SAFe 和 LeSS 孰優孰劣，我沒有資格論斷。至少你可以從「控制權」角度，重新思考本文開頭的提問：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「為什麼 &lt;a href=&#34;https://less.works/&#34;&gt;LeSS&lt;/a&gt; 這麼迷人，可是總是輸給 &lt;a href=&#34;https://www.scaledagileframework.com/&#34;&gt;SAFe&lt;/a&gt;？」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以及，換作是你，會做什麼選擇。&lt;/p&gt;
&lt;p&gt;以及，你的選擇，還需要哪些配套措施（文章開頭引述的&lt;a href=&#34;https://medium.com/@wangtrying/%E9%80%99%E6%98%AF%E5%80%8B%E5%B0%8D%E8%A9%B1%E7%B4%80%E9%8C%84-ebca3a63bbde&#34;&gt;對話紀錄&lt;/a&gt;中，已經有提示了）。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>「從 Ops 角度看 DevOps」的感想</title>
      <link>//william-yeh.net/post/2018/11/opsdev-talk-18/</link>
      <pubDate>Wed, 28 Nov 2018 23:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/11/opsdev-talk-18/</guid>
      
        <description>&lt;p&gt;在台灣（或許在其他地方也是），DevOps 的話語權，很大幅度都被 Dev 一方把持。我們很少聽到 Ops 一方的說法。&lt;/p&gt;
&lt;p&gt;成功的改革，需要兼顧各方利益者的需求及痛點。隨著 DevOps 守備範圍日益擴大，這種失衡狀態必須改變。&lt;/p&gt;
&lt;p&gt;今晚參加 &lt;a href=&#34;https://www.facebook.com/DevOpsTaiwan/&#34;&gt;DevOps Taiwan 社群&lt;/a&gt;舉辦的講座：【&lt;a href=&#34;https://devops.kktix.cc/events/meetup17-opsdev&#34;&gt;從 Ops 角度看 DevOps&lt;/a&gt;】，聽聽&lt;a href=&#34;https://www.facebook.com/roberthu.tw&#34;&gt;胡士亮 (Robert Hu)&lt;/a&gt; 從正統 Ops 角度來詮釋 DevOps，甚至 OpsDev，收穫頗大。&lt;/p&gt;
&lt;p&gt;聽知識，聽心得，也聽熱情與願景。&lt;/p&gt;
&lt;p&gt;也更確定自己設想的方向，是符合正統 Ops 下一步思維的：&lt;a href=&#34;https://dzone.com/articles/predictive-analytics-in-devops-applications-and-be&#34;&gt;predictive analysis&lt;/a&gt; &amp;amp; &lt;a href=&#34;https://www.bmc.com/blogs/what-is-aiops/&#34;&gt;AIOps&lt;/a&gt;。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/opsdev-recap.jpg&#34; alt=&#34;OpsDev recap (from Robert Hu)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/opsdev-recap.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;OpsDev recap (from Robert Hu)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這場講座印象最深的觀念是：同一件事情，在某些時候，由 Dev 下手較好；在某些時候，卻是由 Ops 下手較好。所以，手握 Dev 及 Ops 雙邊武器，就有較大的選擇彈性。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/devops-vs-opsdev.jpg&#34; alt=&#34;DevOps vs. OpsDev (from Robert Hu)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/devops-vs-opsdev.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;DevOps vs. OpsDev (from Robert Hu)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這就讓我想到，以前搞 microservices 時，如果不透過 &lt;a href=&#34;https://netflix.github.io/&#34;&gt;NetflixOSS&lt;/a&gt; 之類的 Dev 黑魔法，就很難做出那些瞠目結舌的機制。而現在，透過 &lt;a href=&#34;https://kubernetes.io/&#34;&gt;Kubernetes&lt;/a&gt; + &lt;a href=&#34;https://istio.io/&#34;&gt;Istio&lt;/a&gt; 之類的 nonintrusive Ops 黑魔法（或者更精準地說：&lt;a href=&#34;http://www.servicemesher.com/awesome-servicemesh/&#34;&gt;service mesh&lt;/a&gt;），就不必改變 Dev 的 coding 習慣。&lt;/p&gt;
&lt;p&gt;譬如說：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://martinfowler.com/bliki/CircuitBreaker.html&#34;&gt;Circuit breaker&lt;/a&gt;：過去要靠 Java &lt;a href=&#34;https://martinfowler.com/bliki/CircuitBreaker.html&#34;&gt;Hystrix&lt;/a&gt;、C# &lt;a href=&#34;https://github.com/App-vNext/Polly&#34;&gt;Polly&lt;/a&gt;、Python &lt;a href=&#34;https://github.com/danielfm/pybreaker&#34;&gt;PyBreaker&lt;/a&gt; 這些程式語言程式庫的層次才能做到，現在，直接交給 &lt;a href=&#34;https://istio.io/docs/tasks/traffic-management/circuit-breaking/&#34;&gt;Istio&lt;/a&gt; 即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://microservices.io/patterns/observability/distributed-tracing.html&#34;&gt;Distributed tracing&lt;/a&gt;：過去要靠 Java &lt;a href=&#34;https://github.com/openzipkin/zipkin&#34;&gt;Zipkin&lt;/a&gt;、Java/C#/Python/etc &lt;a href=&#34;https://opentracing.io/&#34;&gt;OpenTracing&lt;/a&gt; 這些程式語言程式庫的層次才能做到，現在，直接交給 &lt;a href=&#34;https://istio.io/docs/tasks/telemetry/distributed-tracing/&#34;&gt;Istio&lt;/a&gt; 即可。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這也意味著，好好掌握新一代的 Ops 技術，會促進內部協作，也會大幅拉大與競爭對手的差距——那些仍活在舊時代的 infra 對手們。&lt;/p&gt;
&lt;p&gt;時代在進步，現在 Ops 已經不是只能拿冷兵器作戰的小步兵了，而是手持核武的將士——自我升級的鑰匙，在你手裡。&lt;/p&gt;
&lt;p&gt;小小的感想。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;再次感謝 &lt;a href=&#34;https://www.facebook.com/roberthu.tw&#34;&gt;Robert Hu&lt;/a&gt; 這麼精彩的分享！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;//www.slideshare.net/roberthutw/ops-devops-devops-from-ops-perspective&#34;&gt;從 Ops 角度看 DevOps&lt;/a&gt;&lt;/strong&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/124278498&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2018-11-29 補充
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;剛剛看完一場 live online training “&lt;a href=&#34;https://www.safaribooksonline.com/live-training/courses/istio-on-kubernetes-enter-the-service-mesh/0636920221357/&#34;&gt;Istio on Kubernetes: Enter the Service Mesh&lt;/a&gt;”，其中有一段話說得好，可作為文章的註腳：&lt;/p&gt;
&lt;p&gt;“The first generation of microservices was primarily shaped by &lt;a href=&#34;https://netflix.github.io/&#34;&gt;Netflix OSS&lt;/a&gt; and leveraged by numerous &lt;a href=&#34;https://spring.io/projects/spring-cloud&#34;&gt;Spring Cloud&lt;/a&gt; annotations sprinkled all throughout your business logic. The next generation of cloud native apps and microservices will leverage &lt;strong&gt;sidecars&lt;/strong&gt; and a &lt;strong&gt;service mesh&lt;/strong&gt;.”&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>「判準與指標」系列</title>
      <link>//william-yeh.net/series/criteria-series/</link>
      <pubDate>Wed, 28 Nov 2018 00:00:00 +0000</pubDate>
      
      <guid>//william-yeh.net/series/criteria-series/</guid>
      
        <description>&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/10/methodology-and-criteria/&#34;&gt;軟體開發，除了方法論，還有⋯⋯&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/10/agile-criteria/&#34;&gt;敏捷的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/11/lean-startup-criteria/&#34;&gt;Lean Startup 的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2023/12/dev-metrics/&#34;&gt;如何衡量敏捷對於軟體研發效能的利益？&lt;/a&gt;&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>DevOps 的價值與指標</title>
      <link>//william-yeh.net/post/2018/11/devops-value/</link>
      <pubDate>Wed, 28 Nov 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/11/devops-value/</guid>
      
        <description>&lt;p&gt;看完〈&lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;〉之後，很自然的會進一步追問：「那麼，什麼才是 DevOps 圈子所認定的價值，以及對應的指標，尤其是領先指標？」&lt;/p&gt;
&lt;p&gt;這問題其實比較容易回答。畢竟，相較於兄弟領域 agile，控制與監管，原本就是 DevOps 不可分割的一部分。&lt;/p&gt;
&lt;p&gt;再者，DevOps 的價值主張也非常明確具體。根據 SEI 提出的 DevOps 操作型定義：&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps is a set of practices intended to reduce the &lt;strong&gt;time&lt;/strong&gt; between committing a change to a system and the change being placed into normal production, while ensuring high &lt;strong&gt;quality&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因此，時間與品質，就是 DevOps 所認定的價值。&lt;/p&gt;
&lt;p&gt;剩下來的疑問就是：指標？&lt;/p&gt;
&lt;p&gt;來看看兩份經典的說法吧。&lt;/p&gt;
&lt;h2 id=&#34;技術價值流&#34;&gt;技術價值流&lt;/h2&gt;
&lt;p&gt;DevOps 巨著 &lt;a href=&#34;https://www.tenlong.com.tw/products/9787115480170&#34;&gt;&lt;em&gt;The DevOps Handbook&lt;/em&gt;&lt;/a&gt; 第一章，定義技術價值流 (technology value stream) 為：「把業務構想轉化為向客戶交付價值的、由技術驅動的服務所需要的流程。」&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;價值流始於工程師（包括開發、QA、IT 維運和資訊安全人員）向版本控制系統提交了一個變更，止於變更成功地在生產環境中運行，為客戶提供價值，並產生有效的反饋和監控資訊。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;由此觀之，DevOps 的指標，必定會緊扣在技術價值流的環節身上。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/devops-value-stream.png&#34; alt=&#34;DevOps value stream (from: Lean Enterprise, p.139)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/devops-value-stream.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;DevOps value stream (from: Lean Enterprise, p.139)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;此書第一章，根據精實原則，提出三項 DevOps 衡量指標：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;前置時間 (lead time)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;處理時間 (process time)，以及所佔的比例。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;返工指標 (percent complete and accurate)。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;此書第六章，進一步建議要合理設置流程改進的優先級：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;為了積極管理技術債務，要確保至少把 20% 的開發和維運時間投入到重構、自動化工作、架構優化以及非功能需求上。&lt;/p&gt;
&lt;p&gt;如果組織不願意支付這「20% 的税」，那麼技術債務將會最終惡化到靠近所有可用資源的程度。&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/invisible-value.png&#34; alt=&#34;將 20% 時間用於創造用戶不可見的正面價值&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/invisible-value.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;將 20% 時間用於創造用戶不可見的正面價值&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;請思考一下，這些算是領先指標，還是落後指標？與「賺錢」之間有強烈的因果關係嗎？&lt;/p&gt;
&lt;h2 id=&#34;高績效組織&#34;&gt;高績效組織&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://itrevolution.com/devops-research/&#34;&gt;DevOps 年度報告&lt;/a&gt;一直是 DevOps 領域的重頭戲。在 2018 年的報告 &lt;a href=&#34;https://cloudplatformonline.com/2018-state-of-devops.html&#34;&gt;&lt;em&gt;Accelerate: State of DevOps 2018&lt;/em&gt;&lt;/a&gt; 中 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;，從全球近兩千位專業人士的調查中，歸納出五個關鍵的&lt;strong&gt;軟體交付與維運效能&lt;/strong&gt; (software delivery and operational performance; SDO performance) 層面，以及對應的指標：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;部署頻率 (deployment frequency)&lt;/li&gt;
&lt;li&gt;變更的前置時間 (change lead time)&lt;/li&gt;
&lt;li&gt;服務恢復時間 (MTTR)&lt;/li&gt;
&lt;li&gt;變更失敗率 (change fail rate)&lt;/li&gt;
&lt;li&gt;可用性 (availability)&lt;/li&gt;
&lt;/ol&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/sdo-performance.png&#34; alt=&#34;高績效組織的 SDO 效能指標&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/sdo-performance.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;高績效組織的 SDO 效能指標&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;請思考一下，這些算是領先指標，還是落後指標？與「賺錢」之間有強烈的因果關係嗎？&lt;/p&gt;
&lt;h2 id=&#34;均衡感&#34;&gt;均衡感&lt;/h2&gt;
&lt;p&gt;和&lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷&lt;/a&gt;一樣，DevOps 也在追求一種巧妙的均衡感。不僅著眼於百米衝刺的短期成效，更著眼於馬拉松的長期績效。&lt;/p&gt;
&lt;p&gt;一言以蔽之：在團隊中，如果看不到這種均衡感，那麼，鐵定不是 DevOps。&lt;/p&gt;
&lt;p&gt;所以，在談要不要 DevOps 之前，務必誠實自問：這種均衡感，是你想追求的嗎？&lt;/p&gt;
&lt;p&gt;若回答「是」，再試著找出這種均衡感的領先指標吧。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      「判準與指標」系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2018/10/methodology-and-criteria/&#34;&gt;軟體開發，除了方法論，還有⋯⋯&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/10/agile-criteria/&#34;&gt;敏捷的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2018/11/lean-startup-criteria/&#34;&gt;Lean Startup 的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ DevOps 的價值與指標&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/12/dev-metrics/&#34;&gt;如何衡量敏捷對於軟體研發效能的利益？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;SEI 提出的 DevOps 操作型定義，可視為一種狹義的 DevOps 定義。詳見〈&lt;a href=&#34;//william-yeh.net/post/2016/01/devops-goals-in-a-nutshell/&#34;&gt;一句話囊括 DevOps 的目標&lt;/a&gt;〉一文。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;返工指標 (percent complete and accuracy)，在 &lt;a href=&#34;https://www.tenlong.com.tw/products/9787115480170&#34;&gt;&lt;em&gt;The DevOps Handbook&lt;/em&gt;&lt;/a&gt; 書中寫成 &lt;code&gt;%C/A&lt;/code&gt; 符號，但在更廣大的 lean 社群中更常用 &lt;code&gt;%C&amp;amp;A&lt;/code&gt; 符號（像 TKMG 維護的 &lt;a href=&#34;https://www.ksmartin.com/lean-terminology/#p&#34;&gt;Lean 術語表&lt;/a&gt;）。個人認為，後者比較妥當。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;這份年度報告，也有簡體中文譯版：〈&lt;a href=&#34;https://mp.weixin.qq.com/s/F5_XZ1G1PrmpNsQKdKwRSQ&#34;&gt;2018 全球 DevOps 现状报告&lt;/a&gt;〉。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>敏捷的價值與指標</title>
      <link>//william-yeh.net/post/2018/11/agile-value/</link>
      <pubDate>Tue, 27 Nov 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/11/agile-value/</guid>
      
        <description>&lt;p&gt;同溫層朋友提出一則有趣的&lt;a href=&#34;https://www.facebook.com/groups/179345672472/permalink/10156092663467473/&#34;&gt;提問&lt;/a&gt;：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/agile-value-post.png&#34; alt=&#34;如何衡量敏捷的成效？ by Howie Yu (2018-11-23)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/agile-value-post.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;如何衡量敏捷的成效？ by Howie Yu (2018-11-23)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;從該討論串，以及後續追加的其他&lt;a href=&#34;https://www.facebook.com/groups/179345672472/permalink/10156096944827473/&#34;&gt;討論&lt;/a&gt;看來，「賺錢」算是簡潔扼要又難以反駁的「成效」衡量標準。畢竟，這是商業世界。&lt;/p&gt;
&lt;p&gt;只不過，「賺錢」畢竟已經是落後指標了，有流程改善意識的人，應該要更關注領先指標。&lt;/p&gt;
&lt;p&gt;「錢」是很重要的價值，但「窮得只剩下錢」不該是軟體研發所追求的價值。&lt;/p&gt;
&lt;p&gt;因此，當時我給的簡短&lt;a href=&#34;https://www.facebook.com/groups/179345672472/permalink/10156092663467473/?comment_id=10156092774837473&amp;amp;comment_tracking=%7B%22tn%22%3A%22R6%22%7D&#34;&gt;回答&lt;/a&gt;是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;TL;DR　對於「價值」是否有增益。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;回頭看看當初導入敏捷的痛點及原因，找出起初認定（或誤認）的價值是什麼。尤其是：這所謂的「價值」，是否可追溯至&lt;a href=&#34;https://agilemanifesto.org/&#34;&gt;敏捷宣言&lt;/a&gt;或 &lt;a href=&#34;https://modernagile.org/&#34;&gt;Modern Agile&lt;/a&gt; 四層面。若追溯不了，或許一開始就投錯藥方了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;導入敏捷後，是否在敏捷宣言或 Modern Agile 四層面有所進展。進而檢討：這些進展，是否有對應到當初導入敏捷的痛點及原因。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;在導入敏捷之初，或者說，在評估是否要導入敏捷之初，其實應該早就握有一票沈痾清單了。這份沈痾清單，就是大家最在意、最想要增益的「價值」。&lt;/p&gt;
&lt;p&gt;沈痾清單，初期常會以「落後指標」形式來界定；但這還不夠。對於大家最在意的一些落後指標，還需要更進一步，研究出具有強烈因果關係的「領先指標」，才能夠發揮高槓桿的改善。&lt;/p&gt;
&lt;p&gt;什麼才是敏捷圈子所認定的價值，以及對應的指標，尤其是領先指標？&lt;/p&gt;
&lt;p&gt;來看看三本經典的說法吧。&lt;/p&gt;
&lt;h2 id=&#34;敏捷專案儀表板&#34;&gt;敏捷專案儀表板&lt;/h2&gt;
&lt;p&gt;Scrum 發明人 &lt;a href=&#34;https://www.linkedin.com/in/jeffsutherland&#34;&gt;Jeff Sutherland&lt;/a&gt; 及 &lt;a href=&#34;https://kenschwaber.wordpress.com/&#34;&gt;Ken Schwaber&lt;/a&gt; 合著一本小書《&lt;a href=&#34;https://williampjyeh.notion.site/Scrum-00d22ec98ca847d49f62b63d10667049&#34;&gt;告別瀑布，擁抱 Scrum&lt;/a&gt;》，第七章介紹敏捷工作室可採用的評估指標，用來「追蹤和改進專案績效，建置專案和管理報告，追蹤專案歷史，反映目前趨勢，評估工作室的成本和獲利，以此來確定是否需要擴張或縮小工作室」：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/scrum-studio-dashboard.png&#34; alt=&#34;Scrum studio dashboard&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/scrum-studio-dashboard.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Scrum studio dashboard&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;生產效率 (Productivity)：利用特定數量的資金，所完成的業務功能的單位個數。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;品質 (Quality)：軟體缺陷個數。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;價值 (Value)：軟體開發中，投資的每一塊錢，為組織創造價值的效率（用百分比表示）。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;請思考一下，這些算是領先指標，還是落後指標？與「賺錢」之間有強烈的因果關係嗎？&lt;/p&gt;
&lt;h2 id=&#34;衡量敏捷的成功&#34;&gt;衡量敏捷的成功&lt;/h2&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.tenlong.com.tw/products/9787121264528&#34;&gt;洞悉敏捷&lt;/a&gt;》第八章，介紹四個度量維度，作為衡量敏捷效能的框架：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;快速性 (do it fast)：生產力、回應性 (responsiveness)。&lt;/li&gt;
&lt;li&gt;正確性 (do it right)：品質、客戶滿意度。&lt;/li&gt;
&lt;li&gt;及時性 (do it on time)：可預測的交付節奏。&lt;/li&gt;
&lt;li&gt;持續性 (keep doing it)：員工滿意度。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;請思考一下，這些算是領先指標，還是落後指標？與「賺錢」之間有強烈的因果關係嗎？&lt;/p&gt;
&lt;h2 id=&#34;敏捷輪盤&#34;&gt;敏捷輪盤&lt;/h2&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789864343263&#34;&gt;The Great ScrumMaster 中文版&lt;/a&gt;》第六章很懇切地提醒：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在開始改變你們的工作方式之前，先搞清楚變革原因會是個好主意，不要只是因為它是個新潮的東西就開始著手去做。&lt;/p&gt;
&lt;p&gt;你們目前的強項有哪些？瓶頸是什麼？你期望的結果是什麼？如果這些期望不夠高、不夠好，那麼或許你還沒準備好面對變革。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本章接著介紹 12 個度量維度，幫助我們判斷現在是否為變革的好時機：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/agile-wheel.jpg&#34; alt=&#34;敏捷輪盤 (Agile Wheel)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/agile-wheel.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;敏捷輪盤 (Agile Wheel)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;書中將這個「敏捷輪盤」視為團隊共識的探詢工具，我則進一步將它視為敏捷效能的指標：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;上市時間。&lt;/li&gt;
&lt;li&gt;客戶滿意度。&lt;/li&gt;
&lt;li&gt;從客戶取得的回饋。&lt;/li&gt;
&lt;li&gt;交付的可預期性。&lt;/li&gt;
&lt;li&gt;團隊健康。&lt;/li&gt;
&lt;li&gt;團隊合作。&lt;/li&gt;
&lt;li&gt;與他人的溝通。&lt;/li&gt;
&lt;li&gt;效率。&lt;/li&gt;
&lt;li&gt;生產力。&lt;/li&gt;
&lt;li&gt;品質。&lt;/li&gt;
&lt;li&gt;持續改善。&lt;/li&gt;
&lt;li&gt;對改革的反應。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;請思考一下，這些算是領先指標，還是落後指標？與「賺錢」之間有強烈的因果關係嗎？&lt;/p&gt;
&lt;h2 id=&#34;價值&#34;&gt;價值&lt;/h2&gt;
&lt;p&gt;看了三本經典條列的 &lt;em&gt;N&lt;/em&gt; 項敏捷的度量指標，可以回頭審視文章開頭的大哉問了。&lt;/p&gt;
&lt;p&gt;敏捷，對於「&lt;strong&gt;價值&lt;/strong&gt;」是否有增益？&lt;/p&gt;
&lt;p&gt;但在試著回答這問題之前，請先試著釐清一個核心議題：&lt;strong&gt;什麼才是敏捷圈子所認定的「價值」？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你嘗試將《&lt;a href=&#34;https://www.books.com.tw/products/0010647604&#34;&gt;告別瀑布，擁抱 Scrum&lt;/a&gt;》、《&lt;a href=&#34;https://www.tenlong.com.tw/products/9787121264528&#34;&gt;洞悉敏捷&lt;/a&gt;》、《&lt;a href=&#34;https://www.tenlong.com.tw/products/9789864343263&#34;&gt;The Great ScrumMaster 中文版&lt;/a&gt;》列的 3 + 4 + 12 項價值指標分類，不難看出，敏捷，不僅著眼於百米衝刺的短期成效，更著眼於馬拉松的長期績效。&lt;/p&gt;
&lt;p&gt;敏捷，是一種巧妙的均衡感。&lt;/p&gt;
&lt;p&gt;這種均衡感，約略可對應到 &lt;a href=&#34;http://modernagile.org/&#34;&gt;Modern Agile&lt;/a&gt; 四層面：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make People Awesome&lt;/li&gt;
&lt;li&gt;Make Safety a Prerequisite&lt;/li&gt;
&lt;li&gt;Experiment &amp;amp; Learn Rapidly&lt;/li&gt;
&lt;li&gt;Deliver Value Continuously&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這種均衡感，也像極了《&lt;a href=&#34;https://www.books.com.tw/products/0010780648&#34;&gt;投資前的精準判讀&lt;/a&gt;》提出的&lt;strong&gt;永續事業模型&lt;/strong&gt; (model of a sustainable business)。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;一言以蔽之：在團隊中，如果看不到這種均衡感，那麼，鐵定不是敏捷。&lt;/p&gt;
&lt;p&gt;所以，在談要不要敏捷之前，務必誠實自問：這種均衡感，是你想追求的嗎？&lt;/p&gt;
&lt;p&gt;若回答「是」，再試著找出這種均衡感的領先指標吧。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      「判準與指標」系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2018/10/methodology-and-criteria/&#34;&gt;軟體開發，除了方法論，還有⋯⋯&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/10/agile-criteria/&#34;&gt;敏捷的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2018/11/lean-startup-criteria/&#34;&gt;Lean Startup 的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ 敏捷的價值與指標&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/12/dev-metrics/&#34;&gt;如何衡量敏捷對於軟體研發效能的利益？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/11/peak-at-enterprise-value/&#34;&gt;從小提問看企業價值&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>Agile PMO</title>
      <link>//william-yeh.net/post/2018/11/agile-pmo/</link>
      <pubDate>Thu, 15 Nov 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/11/agile-pmo/</guid>
      
        <description>&lt;p&gt;&amp;ldquo;Project&amp;rdquo; 一詞，儼然成為 agile 及 DevOps 圈子的禁語。&lt;/p&gt;
&lt;p&gt;譬如說，敏捷祖師爺 Martin Fowler 的網站有一篇 &amp;ldquo;&lt;a href=&#34;https://martinfowler.com/articles/products-over-projects.html&#34;&gt;Products Over Projects&lt;/a&gt;&amp;rdquo; 文章，DevOps 巨著 &lt;a href=&#34;https://www.tenlong.com.tw/products/9787115480170&#34;&gt;&lt;em&gt;The DevOps Handbook&lt;/em&gt;&lt;/a&gt; 第 7.7 節的篇名叫做〈投資於服務和產品，而非專案〉。最近甚至還有一本新書，直接取名叫做 &lt;a href=&#34;https://itrevolution.com/book/project-to-product/&#34;&gt;&lt;em&gt;Project to Product&lt;/em&gt;&lt;/a&gt; 叫人棄暗投明呢。&lt;/p&gt;
&lt;p&gt;見微知著。這個圈子，褒 product，貶 project，是政治正確的常模。 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;這個圈子，對於 &amp;ldquo;project&amp;rdquo; 反感，對於素來予人控制與監管印象的 &amp;ldquo;PMO&amp;rdquo; (Project Management Office，專案管理辦公室) &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 就更反感了。&lt;/p&gt;
&lt;p&gt;但 PMO 真的與敏捷水火不容嗎？&lt;/p&gt;
&lt;h2 id=&#34;敏捷陣營的聲音&#34;&gt;敏捷陣營的聲音&lt;/h2&gt;
&lt;p&gt;聽聽看 Scrum 領域三位大神的說法吧。&lt;/p&gt;
&lt;p&gt;頭兩位大神 &lt;a href=&#34;https://www.linkedin.com/in/jeffsutherland&#34;&gt;Jeff Sutherland&lt;/a&gt; 及 &lt;a href=&#34;https://kenschwaber.wordpress.com/&#34;&gt;Ken Schwaber&lt;/a&gt; 是 Scrum 發明人。他們合著一本小書《&lt;a href=&#34;https://www.books.com.tw/products/0010647604&#34;&gt;告別瀑布，擁抱 Scrum&lt;/a&gt;》，言簡意賅，完全是務實的經驗談。附錄Ｃ〈企業級敏捷攻略〉專門探討敏捷擴展的議題，難得看到兩位老爹發表與其他基本教義派不同的接地氣觀點。其中對於 &amp;ldquo;project&amp;rdquo; 的看法是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum 避免使用傳統的「類」瀑布式的專案&lt;strong&gt;計畫&lt;/strong&gt;，但是策略性的日常&lt;strong&gt;專案管理&lt;/strong&gt;的本質是堅定不移的。高級成員需要觀察每個團隊各自的 iteration 和發佈計畫，才能全面的評估整個專案所處的狀態。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;他們也進一步闡述遠光燈的觀點：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum 是追求「近期可能性的藝術」，而不是詳細預測未來 6 到 12 個 sprints 內應該交付什麼的黑色藝術。但隨著團隊的擴大和增加，為了未來較遙遠的 sprint 做額外嚴謹的分析，將有助於避免日後需要對架構做過多的重構。為了能將系統架構未來可能的演變方向看得更清楚，進行額外的發布計畫也是合適的。因此，sprint 計畫會議中，可以「看看過去的幾個 sprint」，也可以進行一些「萬一」(what-if) 的計畫，如此將能夠協助團隊權衡產品待辦清單，並向發起者傳達一個更合理的願景和產品路線圖。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ken Schwaber 創立的 &lt;a href=&#34;https://www.scrum.org&#34;&gt;Scrum.org&lt;/a&gt; 培訓機構，也刊登過一篇 &amp;ldquo;&lt;a href=&#34;https://www.scrum.org/resources/blog/agile-pmo&#34;&gt;The Agile PMO&lt;/a&gt;&amp;rdquo; 文章，說明他們對於 PMO 並未排斥。&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;第三位大神 &lt;a href=&#34;https://www.scrumalliance.org/community/profile/mikecohn&#34;&gt;Mike Cohn&lt;/a&gt;，是 CSM/CSPO/CST 等認證的主辦機構 &lt;a href=&#34;https://www.scrumalliance.org/&#34;&gt;Scrum Alliance&lt;/a&gt; 的共同創辦人，著作等身，都是敏捷領域的經典 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;。最近也在他的機構 Mountain Goat Software 開辦很精彩的 &lt;a href=&#34;http://learn.mountaingoatsoftware.com/better-user-stories/&#34;&gt;&lt;em&gt;Better User Stories&lt;/em&gt;&lt;/a&gt; 線上課程，是非常活躍的 Scrum 培訓師。&lt;/p&gt;
&lt;p&gt;在敏捷領域，Mike Cohn 雖然是祖師爺等級的人物，但不是基本教義派。譬如說，雖然 &amp;ldquo;project&amp;rdquo; 一詞儼然成為這圈子的禁語，但他可不這麼認為：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Projects provide a planning horizon that is longer than a sprint&amp;mdash;typically in the range of two to six months. This “definite beginning and end” that is focused on a “unique product, service or result” encourages product owners to select truly important things to work on rather than whatever some customer or salesperson screamed about yesterday.&lt;/p&gt;
&lt;p&gt;I always encourage product owners and their teams to identify a milestone they are working toward that is longer than a single sprint.&lt;/p&gt;
&lt;p&gt;Projects remain a useful construct. They provide a motivation to accomplish something grander than could be done in a single iteration.&lt;/p&gt;
&lt;p&gt;  &amp;mdash; “&lt;a href=&#34;https://www.mountaingoatsoftware.com/blog/is-it-time-to-stop-thinking-about-projects&#34;&gt;Is It Time to Stop Thinking about Projects?&lt;/a&gt;”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;畢竟 milestone 這種&lt;strong&gt;策略控制點&lt;/strong&gt;的設置與控制，原本就是專案管理知識體系的擅長之處。&lt;/p&gt;
&lt;p&gt;他甚至鼓勵將傳統上 &lt;a href=&#34;https://www.pmi.org/pmbok-guide-standards&#34;&gt;PMBOK&lt;/a&gt; 重視的某些活動，引進敏捷開發的節奏中：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Becoming agile does not mean we need to throw out everything we&amp;rsquo;ve learned over the past 100 or so years of doing project management. Some things&amp;mdash;project kickoff meetings included&amp;mdash;remain valuable.&lt;/p&gt;
&lt;p&gt;Risk management is not formally defined as part of agile frameworks like Scrum. And that’s understandable as a lot of risks do go away (or get exposed) with the short iterations common to agile. But there are still projects that benefit from lightweight but explicit risk management. I suggested starting that during the kickoff meeting.&lt;/p&gt;
&lt;p&gt;  &amp;mdash; “&lt;a href=&#34;https://www.mountaingoatsoftware.com/blog/advice-on-conducting-agile-project-kickoff-meetings&#34;&gt;Advice on Conducting Agile Project Kickoff Meetings&lt;/a&gt;”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;三位大師的論述，像極了《&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E7%A5%9E%E9%B5%B0%E4%BF%A0%E4%BE%B6&#34;&gt;神鵰俠侶&lt;/a&gt;》中「不滯於物，草木竹石均可為劍」的境界，大師風範，令人佩服。&lt;/p&gt;
&lt;h2 id=&#34;pmo-陣營的聲音&#34;&gt;PMO 陣營的聲音&lt;/h2&gt;
&lt;p&gt;也來聽聽看 PMO 領域的說法吧。&lt;/p&gt;
&lt;p&gt;PMO 並不是像敏捷基本教義派陣營口中那麼僵化守舊的。像 2013 年《&lt;a href=&#34;https://www.books.com.tw/products/CN11396791&#34;&gt;業務驅動的 PMO 最佳實踐&lt;/a&gt;》一書主張，有&lt;strong&gt;成熟敏銳度&lt;/strong&gt; (maturity acumen) 的 PMO，需要根據專案類型與管理方法兩個維度，將組織層級的專案管理分成四個象限，並以宏觀視野統籌處理：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/org-pm-quadrant.jpg&#34; alt=&#34;組織範圍的專案管理&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/org-pm-quadrant.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;組織範圍的專案管理&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;至於最正宗的專案管理國際組織 &lt;a href=&#34;https://www.pmi.org/&#34;&gt;PMI&lt;/a&gt; 是怎麼想的呢？&lt;/p&gt;
&lt;p&gt;在 &amp;ldquo;&lt;a href=&#34;https://www.pmi.org/learning/library/pmo-agile-transformation-6063&#34;&gt;An agile PMO transformation&lt;/a&gt;&amp;rdquo; 一文中，列舉 &amp;ldquo;agile PMO&amp;rdquo; 的「八要八不要」，並且主張：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For many organizations, using the words “PMO” and “agile” in the same sentence could be considered an oxymoron. It may come as a surprise to expect the PMO to lead the agile transformation, but we think that &lt;em&gt;for organizations to reach the full potential of the approaches outlined in this update, such as managing the enterprise-level portfolio and creating stable teams, the PMO will need to be engaged and lead the way.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If PMOs are ready and willing to transform, they can greatly influence the success of their organization&amp;rsquo;s agile transformation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可見，狀似傳統僵化的 PMO，其實也已經正視敏捷變革。因此，我們不時可看到新名詞 &amp;ldquo;agile PMO&amp;rdquo; 出現，連管顧公司也湊熱鬧湊出一個 &amp;ldquo;Lean-Agile PMO&amp;rdquo; 呢。&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;正名&#34;&gt;正名？&lt;/h2&gt;
&lt;p&gt;敏捷陣營常會對 &amp;ldquo;agile PMO&amp;rdquo; 一詞嗤之以鼻，認為只是換湯不換藥。&lt;/p&gt;
&lt;p&gt;因此，Mike Cohn 挑明地說，為了避免困擾，不妨考慮換個名字：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A project management office (PMO) that is engaged in and supportive of transitioning to Scrum can be a tremendous boon.&lt;/p&gt;
&lt;p&gt;Many PMOs choose to rename themselves to better match their revised role. Though there is no one standard name, I have heard these most frequently: &lt;em&gt;Scrum center of excellence&lt;/em&gt;, &lt;em&gt;Scrum competence center&lt;/em&gt;, &lt;em&gt;Scrum office&lt;/em&gt;, and &lt;em&gt;development support&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Many people have become cynical and suspicious of name changes and of well-crafted names. That cynicism will be directed at the PMO if it is renamed but remains otherwise unchanged. So, whatever it&amp;rsquo;s called, the PMO that supported the organization&amp;rsquo;s sequential development process will need to change more than just its name to succeed with Scrum.&lt;/p&gt;
&lt;p&gt;  &amp;mdash; “&lt;a href=&#34;https://www.mountaingoatsoftware.com/articles/the-roles-of-the-project-management-office-in-scrum&#34;&gt;The Roles of the Project Management Office in Scrum&lt;/a&gt;”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;PMI 在 &lt;a href=&#34;https://www.pmi.org/pmbok-guide-standards/practice-guides/agile&#34;&gt;&lt;em&gt;Agile Practice Guide&lt;/em&gt;&lt;/a&gt; 第六章也提及 “&lt;strong&gt;center of excellence&lt;/strong&gt;” 一詞：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Some organizations have been transforming their PMOs into agile centers of excellence&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至於崇尚極簡作風的 LeSS 陣營，則主張廢棄 &amp;ldquo;project&amp;rdquo; 或 &amp;ldquo;office&amp;rdquo; 字眼，改用 &amp;ldquo;Head of Product Group&amp;rdquo; 概念，以及 &amp;ldquo;&lt;a href=&#34;https://less.works/less/management/go-see.html&#34;&gt;Go See&lt;/a&gt;&amp;rdquo; 管理：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;No project/program organization or project/program management office (PMO). No support groups such as configuration management, continuous integration support, or “quality and process”.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Head of the Product Group&lt;/strong&gt; — Most LeSS organizations still have managers including a “head of product group.” They support the teams by Go See and help them remove obstacles and improve. LeSS organizations don’t have matrix structures and there are no “dotted-line” managers.&lt;/p&gt;
&lt;p&gt;“Head of Product Group” is called differently in different organization, here we mean the hierarchical manager of all the teams.&lt;/p&gt;
&lt;p&gt;  &amp;mdash; LeSS &lt;a href=&#34;https://less.works/less/structure/organizational-structure.html&#34;&gt;Organizational Structure&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;看了這麼多論點，你認為 &amp;ldquo;agile PMO&amp;rdquo; 是噱頭嗎？&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;儘管敏捷圈子普遍褒 product 而貶 project，但有趣的是，&lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; 對於 sprint 卻有這種類比：“Each Sprint may be considered a &lt;strong&gt;project&lt;/strong&gt; with no more than a one-month horizon 每個 Sprint 可視為一個不超過一個月的&lt;strong&gt;專案&lt;/strong&gt;。”&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;想在五分鐘之內快速了解 PMO 是什麼東西，可讀讀 Joe 寫的這篇文章：&lt;a href=&#34;https://www.projectup.net/article/view/id/9&#34;&gt;What is PMO&lt;/a&gt;。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Mike Cohn 在敏捷領域的名作：&lt;a href=&#34;https://www.amazon.com/gp/product/0321205685/&#34;&gt;&lt;em&gt;User Stories Applied: For Agile Software Development&lt;/em&gt;&lt;/a&gt; (2004)、&lt;a href=&#34;https://www.amazon.com/dp/0131479415&#34;&gt;&lt;em&gt;Agile Estimating and Planning&lt;/em&gt;&lt;/a&gt; (2005)、&lt;a href=&#34;https://www.amazon.com/gp/product/0321579364/&#34;&gt;&lt;em&gt;Succeeding with Agile: Software Development Using Scrum&lt;/em&gt;&lt;/a&gt; (2009)。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.forbes.com/sites/forbesfinancecouncil/2018/06/13/the-many-benefits-of-an-agile-pmo-what-you-should-know/&#34;&gt;The Many Benefits Of An Agile PMO: What You Should Know&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>接班人計畫</title>
      <link>//william-yeh.net/post/2018/11/succession-planning/</link>
      <pubDate>Thu, 08 Nov 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/11/succession-planning/</guid>
      
        <description>&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/the-nigmatic-1068159-unsplash.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/the-nigmatic-1068159-unsplash.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;彼得・杜拉克説：經理人的基本任務，除了平衡長短期的需要外，最重要的就是培養下一代的經理人。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;諾爾・提區説：成功組織會贏，贏在它的領導人不斷栽培組織上下每個層級的其他領導人。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;其實我很早就在默默做這件事了。畢竟以長遠來看，&lt;strong&gt;堅實的中階主管層，決定一個組織能走得多久多遠&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;就像&lt;a href=&#34;https://www.jianshu.com/p/dc2f701c166e&#34;&gt;此文&lt;/a&gt;所說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;只要组织内部没有足够数量的领导，一个庞大的组织是无法在短时间内发生改变的。国家也好，大企业也罢，要想进行改革，需要的不是一个具备卓越能力的明星领袖，而是具备领导能力的人超过一定的数量。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;想要「具備領導能力的人，超過一定的數量」，是需要佈局的。&lt;/p&gt;
&lt;h2 id=&#34;佈局&#34;&gt;佈局&lt;/h2&gt;
&lt;p&gt;我 2017 年初就開始佈局了，先從共同語言開始&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;（2017 年）三月，自掏腰包，拿《&lt;a href=&#34;https://www.books.com.tw/products/0010641668&#34;&gt;三年後，你的工作還在嗎&lt;/a&gt;》及〈&lt;a href=&#34;http://drapplehuang.blogspot.com/2017/03/blog-post_23.html&#34;&gt;沒了名片你還剩下什麼？新書發表演講筆記&lt;/a&gt;〉當部門內的讀書會材料，激發大家的工匠魂及總管魂。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;非正式調查，大家對其中的〈&lt;a href=&#34;https://www.darencademy.com/article/view/id/15058&#34;&gt;職場自由之道：第一天就為離開做好準備&lt;/a&gt;〉觀點最有感——很合乎我的預期。&lt;/p&gt;
&lt;p&gt;共同語言有了，之後再推動一些事情，就名正言順多了。&lt;/p&gt;
&lt;p&gt;最近規模比較大的，是在部門內舉辦第一場 Open Space Technology (OST；開放空間會議) ，提煉大家對於 2019 年的部門願景：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/gogolook-server-ost.png&#34; alt=&#34;部門 OST 活動，一隅 (2018-10-19)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/gogolook-server-ost.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;部門 OST 活動，一隅 (2018-10-19)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;從活動過程及結論中，可看出某些人在心態上已經做好承接更大責任的準備。因此，我可以更積極進行這件事了。&lt;/p&gt;
&lt;p&gt;俗氣一點講，是副手計畫；吊書袋的講法，是接班人計畫 (succession planning)。&lt;/p&gt;
&lt;h2 id=&#34;一對一關懷式指導&#34;&gt;「一對一關懷式指導」&lt;/h2&gt;
&lt;p&gt;我所崇敬的作家 Marcus Buckingham 在 &lt;a href=&#34;https://www.willowcreek.com/events/leadership/2017-Domestic-A/&#34;&gt;2017 領導力研習會 (Global Leadership Summit)&lt;/a&gt; 給的【重塑績效管理】演講中&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;，提出很簡單卻很有效的 &amp;ldquo;frequent strengths-based check-ins&amp;rdquo; 建議：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/strength-checkins.jpg&#34; alt=&#34;frequent strengths-based check-ins&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/strength-checkins.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;frequent strengths-based check-ins&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;There is one silver bullet that forms the foundation of a great team: frequent strengths-based check-ins about near-term future work. Every week. One-on-One.&lt;/p&gt;
&lt;p&gt;In the one-on-one, managers should ask just two questions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What are your priorities for the week?&lt;/li&gt;
&lt;li&gt;How can I help?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;One year is made up of 52 little sprints. Your job is to make sure sprint #37 is as energized and focused as sprint #1.&lt;/p&gt;
&lt;p&gt;This is not feedback. There is all sorts of research that shows we go into “fight-or-flight mode” in the face of feedback. People don’t want feedback; they want attention and coaching.&lt;/p&gt;
&lt;p&gt;Leaders should not manage more people than they can honestly have a one-on-one check-in every week. This is leadership.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我想，這種近身的教練模式，正是接班人計畫所需要的落地作法。&lt;/p&gt;
&lt;h2 id=&#34;材料&#34;&gt;材料&lt;/h2&gt;
&lt;p&gt;華倫・班尼斯在《&lt;a href=&#34;https://www.books.com.tw/products/0010445840&#34;&gt;領導，不需要頭銜&lt;/a&gt;》說道：「領導課程只能教你技巧，無法傳授&lt;strong&gt;個性&lt;/strong&gt;或&lt;strong&gt;眼光&lt;/strong&gt;。」&lt;/p&gt;
&lt;p&gt;這也是接班人培訓困難之處。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/leadership-self-pace.jpg&#34; alt=&#34;領導者：個性和眼光&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/leadership-self-pace.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;領導者：個性和眼光&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;原本是想直接套用現成的《&lt;a href=&#34;https://www.knack.com.tw/Event/ManagerSkill&#34;&gt;帶人的技術 │ 新手主管的必殺訣竅&lt;/a&gt;》線上課程內容。但稍微研究了一下，這線上課程比較適合自學，不太適合近身的教練模式——除非搭配適當的補充材料。&lt;/p&gt;
&lt;p&gt;因此，我還是回到自己慣用的方式：指定讀物，個案研討，行動，回饋。&lt;/p&gt;
&lt;p&gt;培育對象是中階主管，所以我只選擇簡單易讀的，不那麼高大上的材料。&lt;/p&gt;
&lt;h4 id=&#34;基本職涯觀念&#34;&gt;基本職涯觀念&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010641668&#34;&gt;三年後，你的工作還在嗎&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;工具箱&#34;&gt;工具箱&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010681486&#34;&gt;不懂這些，別想加薪&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;領導&#34;&gt;領導&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010445840&#34;&gt;領導，不需要頭銜&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;指導&#34;&gt;指導&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010699844&#34;&gt;教出好幫手&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;問題解決&#34;&gt;問題解決&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010675840&#34;&gt;破解問題的技術&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;會議&#34;&gt;會議&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;繁體版《&lt;a href=&#34;https://www.taaze.tw/sing.html?pid=11100243769&#34;&gt;誰說我們不能一起做決定&lt;/a&gt;》(2/e)&lt;/li&gt;
&lt;li&gt;簡體版《&lt;a href=&#34;http://www.sanmin.com.tw/product/index/005689892&#34;&gt;結構化研討：參與式決策操作手冊&lt;/a&gt;》(3/e)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;溝通協調&#34;&gt;溝通協調&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;二日課程：【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/28&#34;&gt;A101 職場大人學 - 職場人際關係與優勢策略&lt;/a&gt;】&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;規劃力&#34;&gt;規劃力&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;一日課程：【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/1&#34;&gt;101 / 專案管理一日特訓班&lt;/a&gt;】&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;至於具體的培訓議題順序，則還在研究。或許也不是獨自研究就能成形的，應該要與接班人共同議定吧。&lt;/p&gt;
&lt;p&gt;嗯，就這麼辦。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;Photo credit: &lt;a href=&#34;https://unsplash.com/photos/Y4kw_G_xhsQ&#34;&gt;https://unsplash.com/photos/Y4kw_G_xhsQ&lt;/a&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2018-12-24 後續發展
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;我又另外企劃了一對多形式的〈&lt;a href=&#34;//william-yeh.net/post/2018/12/practice-of-managers/&#34;&gt;【主管的修練】讀書會&lt;/a&gt;〉。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;〈&lt;a href=&#34;https://www.hbrtaiwan.com/article_content_AR0000924.html&#34;&gt;人才培育與傳承的策略思維&lt;/a&gt;〉，哈佛商業評論・中文版，2008 年 10 月號。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.managertoday.com.tw/columns/view/55866&#34;&gt;「接班人」培育計畫，該有的正確觀念&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://school.soft-arch.net/blog/8494/poogi-by-questions&#34;&gt;以提問角度看 TOC 聚焦五步驟&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://treymcclain.com/gls-17-buckingham/&#34;&gt;Session notes&lt;/a&gt; of GLS 2017: Session 5 – &lt;em&gt;Reinventing Performance Management&lt;/em&gt; by Marcus Buckingham.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>從小提問看企業價值</title>
      <link>//william-yeh.net/post/2018/11/peak-at-enterprise-value/</link>
      <pubDate>Fri, 02 Nov 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/11/peak-at-enterprise-value/</guid>
      
        <description>&lt;p&gt;如何選人？&lt;/p&gt;
&lt;p&gt;我有一篇舊文〈&lt;a href=&#34;//william-yeh.net/post/2016/07/professional-attitude/&#34;&gt;專業態度的養成&lt;/a&gt;〉是針對中低階領域的提問重點；善用這些切入點，可挖掘出人才潛力股。這也是年度績效面談時，我會提問的重點之一。&lt;/p&gt;
&lt;p&gt;那麼，中高階領域呢？如何選領導者，選團隊，或者更廣泛一點講：如何選公司？&lt;/p&gt;
&lt;p&gt;我有兩個私房切入點，剛好是兩本書教我的。&lt;/p&gt;
&lt;h2 id=&#34;改變的角度&#34;&gt;改變的角度&lt;/h2&gt;
&lt;p&gt;第一本書是《&lt;a href=&#34;https://bookzone.cwgv.com.tw/books/details/BCB313&#34;&gt;關鍵領導九十天&lt;/a&gt;》。這是我每隔幾個月就會重溫的書。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/first-90-days.jpg&#34; alt=&#34;關鍵領導 90 天&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/first-90-days.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關鍵領導 90 天&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;改變，是中高階人士常會面對，甚至需要主導的議題。此書提出一套「STARS 模式」來分析所處的改善／改變／改革局勢，其中「界定你的學習程序」工具很實用：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;為了使你在學習上的投資獲得最高的報酬，就必須從眼前大量的資訊中，有效地汲取可行的洞見，才能集中力量，營造收集資訊、分析、假設、測試的良性循環。&lt;/p&gt;
&lt;p&gt;你該如何收集初期的引導問題清單？首先，要針對過去、現在、未來提出問題。事情為何會那麼做？那樣做的理由，今天是否仍站得住腳？狀況是否改變，是否未來該有不同的做法？以下針對這三方面，提供了問題範例。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以這套引導問題清單為基礎，再混搭下一本書的模型，可營造出絕佳的說故事時間。圍繞這類事例，正是了解這位領導者，這團隊，或者更廣泛一點講：這間公司的絕佳切入點。&lt;/p&gt;
&lt;h2 id=&#34;永續的角度&#34;&gt;永續的角度&lt;/h2&gt;
&lt;p&gt;第二本書是《&lt;a href=&#34;https://www.books.com.tw/products/0010780648&#34;&gt;投資前的精準判讀&lt;/a&gt;》。畢竟，針對領導者、團隊，甚至公司的價值判定洞見，誰能像價值投資教父華倫・巴菲特那樣經得起考驗呢？&lt;/p&gt;
&lt;p&gt;《投資前的精準判讀》歸納巴菲特的洞見，提出一個很重要的羅盤：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/sustainable-business-model.jpg&#34; alt=&#34;永續事業模型 (model of a sustainable business)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/sustainable-business-model.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;永續事業模型 (model of a sustainable business)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這個&lt;strong&gt;永續事業模型&lt;/strong&gt; (model of a sustainable business)，連指數型基金之父 Jack Bogle 都稱許道：「這張圖像哥白尼一樣，顯示了太陽真正的位置。」&lt;/p&gt;
&lt;p&gt;有時候，連企業掌舵者也未必很清楚知道這一點，遑論各層級的負責人。&lt;/p&gt;
&lt;p&gt;搞懂這個，搞懂這間企業對這事業模型的立場，再談推動改善／改變／改革吧。你所推動的事情，若不和這間企業自己的永續事業模型對齊，你只是努力地在當另一個唐吉訶德。&lt;/p&gt;
&lt;p&gt;更極端的是，如果這間企業根本沒有自己的「永續」想法，那麼，你連唐吉訶德都不必去當了，直接跳船吧。畢竟，孫子兵法說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;故校之以計，而索其情。曰：主孰有道，將孰有能，天地孰得，法令孰行，兵眾孰強，士卒孰練，賞罰孰明，吾以此知勝負矣。將聽吾計，用之必勝，留之；將不聽吾計，用之必敗，去之。&lt;/p&gt;
&lt;p&gt;夫未戰而廟算勝者，得算多也；未戰而廟算不勝者，得算少也。多算勝，少算不勝，而況無算乎！吾以此觀之，勝負見矣。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;尋找線索&#34;&gt;尋找線索&lt;/h2&gt;
&lt;p&gt;《投資前的精準判讀》的模型及分析角度很有用。&lt;/p&gt;
&lt;p&gt;這本書教我們如何從對話或各種一手資訊中尋找線索：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/culture-clue.jpg&#34; alt=&#34;尋找文化線索&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/culture-clue.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;尋找文化線索&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;也教我們如何從對話或各種一手資訊所體現的溝通風格中，洞悉難以言說的深層事物：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/comm-style.jpg&#34; alt=&#34;溝通風格&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/comm-style.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;溝通風格&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;好書像寶藏，看你怎麼轉化運用。&lt;/p&gt;
&lt;p&gt;譬如說，面談時，不要盡是在瑣碎的事情上面打轉。試著用具體的實例，探出深層的永續事業層面，這才是重點。&lt;/p&gt;
&lt;p&gt;譬如說，專案計畫書、產品路線圖、impact map、product backlog，亦可用這些角度去測出背後的永續事業理念；或者⋯⋯沒有永續可言的理念。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;兩本有趣的私房書，給大家參考。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Lean Startup 的判準</title>
      <link>//william-yeh.net/post/2018/11/lean-startup-criteria/</link>
      <pubDate>Thu, 01 Nov 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/11/lean-startup-criteria/</guid>
      
        <description>&lt;p&gt;《商業周刊》第 1615 期，有一篇總編輯的話〈&lt;a href=&#34;https://www.businessweekly.com.tw/magazine/Article_mag_page.aspx?id=68134&#34;&gt;拖鞋戰法，先做了再修！&lt;/a&gt;〉：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;網路時代的敏捷開發法，強調「先做了再修改」，中心思想不是「預測」(predict)，而是「順應」(adapt)，讓市場告訴你如何改變。因此「先做出可用、但不完美的產品」後，直接拿到市場測試，根據顧客意見，再回頭修改，反覆這個循環，直到產品上市。&lt;/p&gt;
&lt;p&gt;在快時代下，過去強調「凡事先想透徹」的戰法出現破綻，步伐顯得沉重，而「先做了再改」的敏捷戰法則相對靈活。講到這裡，快低頭看看，你穿的是皮鞋還是拖鞋？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這下子 PO/PdM 可高興了，拿此文所謂「拖鞋戰法」當立論基礎，向團隊臃腫的 Scrum/Kanban DoD 磨刀霍霍。這也在&lt;a href=&#34;https://www.facebook.com/groups/179345672472/&#34;&gt;台灣 Scrum 社群&lt;/a&gt;引發熱烈&lt;a href=&#34;https://www.facebook.com/groups/179345672472/permalink/10156032174387473/&#34;&gt;討論&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;我留的評論是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其實，這仍然是方法論&lt;strong&gt;判準&lt;/strong&gt;的老問題。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;敏捷有許多流派，不是只有 Scrum 才叫正宗，不是只有 Kanban 才叫適用。&lt;/p&gt;
&lt;p&gt;某些 PO 心中所想的，其實既不是 Scrum 也不是 Kanban，而是 lean startup（精實創業）——儘管他們自己也不知道。&lt;/p&gt;
&lt;p&gt;選錯方法論，選錯判準，自然扞格不入。&lt;/p&gt;
&lt;p&gt;先搞清楚 PO 內心真正要的方法論，搞清楚這方法論背後的世界觀，搞清楚判準，才能進行&lt;del&gt;攻防&lt;/del&gt;對話。&lt;/p&gt;
&lt;h2 id=&#34;lean-startup-的源流&#34;&gt;Lean Startup 的源流&lt;/h2&gt;
&lt;p&gt;Lean startup 路線，比較正式的起源，據 Steve Blank 在哈佛商業評論〈&lt;a href=&#34;https://www.hbrtaiwan.com/article_content_AR0002324.html&#34;&gt;精實創業改變全世界&lt;/a&gt;〉所述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;2004 年，我投資一家由艾瑞克．萊斯 (Eric Ries) 和威爾．哈維 (Will Harvey) 成立的新創公司，並提出一個但書，我堅持他們必須上我的課，我才會投資。&lt;/p&gt;
&lt;p&gt;艾瑞克很快就發現，科技產業傳統採行的「瀑布式開發法」那種線性開發方式，應該改為反覆修正、敏捷回應的開發方式。艾瑞克也看出這套新創業準則，與大家耳熟能詳的、豐田「精實生產」系統之間的共同點，因此，將這套結合顧客開發與敏捷反應的方法稱為「精實創業」。&lt;/p&gt;
&lt;p&gt;這些工具因為一連串的暢銷書，而逐漸廣為人知。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2011 年，Eric Ries 總結自身及他人經驗，出版《&lt;a href=&#34;https://www.books.com.tw/products/0010768288&#34;&gt;精實創業&lt;/a&gt;》一書，替這種路線正式定調。身為教父，他也策展了一系列經典之作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010580487&#34;&gt;精實執行&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010753559&#34;&gt;快成長時代&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.tenlong.com.tw/products/9787115405319&#34;&gt;精益客戶開發&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/CN11206479&#34;&gt;精益數據分析&lt;/a&gt;》&lt;/li&gt;
&lt;li&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010756527&#34;&gt;精實 UX 設計&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lean startup 理念貌似常識，但若真的要有正確不偏頗的理解，這些輕薄短小的書都是必備讀物，勿等閒視之。&lt;/p&gt;
&lt;h2 id=&#34;lean-startup-的判準&#34;&gt;Lean Startup 的判準&lt;/h2&gt;
&lt;p&gt;Lean startup 在執行時，的確常會與 Scrum 或 Kanban 混搭。像《&lt;a href=&#34;https://www.books.com.tw/products/0010580487&#34;&gt;精實執行&lt;/a&gt;》第二版第 13 章如此建議：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;控制你的功能管線，限制同時間被處理的功能數量，並且僅於你已驗證過所部署之功能具有正面或負面的影響之後（亦即，產生經驗學習），才著手處理新功能。進行這項工作的好方法，就是運用 Kanban。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但在方法論層面，仍然該有所區辨，尤其會涉及到接下來要談的嚴肅話題：判準。&lt;/p&gt;
&lt;p&gt;Lean startup 理念貌似常識，但真正核心的判準，未必都被清楚地認知。&lt;/p&gt;
&lt;p&gt;我個人認為，lean startup 的判準，就是 Ash Maurya 在《&lt;a href=&#34;https://www.books.com.tw/products/0010580487&#34;&gt;精實執行&lt;/a&gt;》書中所勾勒的三大風險、四大階段。如果以 Ash Maurya 發明的精實畫布 (lean canvas) 攤開來看：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/11/lean-startup-risk.jpg&#34; alt=&#34;《精實執行》有系統地消除三大風險&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/11/lean-startup-risk.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《精實執行》有系統地消除三大風險&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;三大風險、四大階段，彼此的判讀基準如下：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;階段&lt;/th&gt;
          &lt;th&gt;產品風險&lt;/th&gt;
          &lt;th&gt;顧客風險&lt;/th&gt;
          &lt;th&gt;市場風險&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;⓵瞭解問題&lt;/td&gt;
          &lt;td&gt;你在解決什麼問題？&lt;/td&gt;
          &lt;td&gt;競爭對手是誰？&lt;/td&gt;
          &lt;td&gt;誰感到痛苦？&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;⓶定義解決方案&lt;/td&gt;
          &lt;td&gt;誰感到痛苦？&lt;/td&gt;
          &lt;td&gt;你將如何解決這些問題？&lt;/td&gt;
          &lt;td&gt;定價模型為何？&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;⓷定性驗證&lt;/td&gt;
          &lt;td&gt;這項產品有什麼令人無法抗拒的地方嗎？&lt;/td&gt;
          &lt;td&gt;你有足夠的顧客嗎？&lt;/td&gt;
          &lt;td&gt;價格合適嗎？&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;⓸定量驗證&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;至於 lean canvas 的各個空格，該如何制訂質性與量化的指標，就得量身定做了。&lt;/p&gt;
&lt;p&gt;看到這裡，你認為本文開頭所提到的「拖鞋戰法」，是落在 lean startup 哪一個格子呢？&lt;/p&gt;
&lt;h3 id=&#34;合乎現實嗎&#34;&gt;合乎現實嗎？&lt;/h3&gt;
&lt;p&gt;要走 lean startup 路線，就要弄清楚 lean startup 的判準，並致力於判準的實踐品質，這是將方法論落地實施的重要關鍵。&lt;/p&gt;
&lt;p&gt;問題是：這個判準，合乎現實嗎？更進一步的問題是：是怎樣的世界觀，才會催生如此的判準？&lt;/p&gt;
&lt;p&gt;Lean startup 的世界觀就是，我們對萬事萬物的認知，充斥仍待驗證的粗糙假設。能用最少的投入成本，降低最多的不確定性，就是最好的學習。&lt;/p&gt;
&lt;p&gt;認清這個判準，以及這個判準背後代表的方法論及世界觀，有助於你成為高性價比的策略執行家。&lt;/p&gt;
&lt;p&gt;或許更重要的是，你支持這種方法論，卻又得與一知半解者合作，你就應該在這些判準的層次上，盡一切努力守護這些判準的認知與實踐品質，並最大化這些判準的價值能見度。&lt;/p&gt;
&lt;p&gt;在判準的層次動工，比各自表述的爭辯更有力。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      「判準與指標」系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2018/10/methodology-and-criteria/&#34;&gt;軟體開發，除了方法論，還有⋯⋯&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/10/agile-criteria/&#34;&gt;敏捷的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ Lean Startup 的判準&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/12/dev-metrics/&#34;&gt;如何衡量敏捷對於軟體研發效能的利益？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>敏捷的判準</title>
      <link>//william-yeh.net/post/2018/10/agile-criteria/</link>
      <pubDate>Wed, 31 Oct 2018 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/10/agile-criteria/</guid>
      
        <description>&lt;p&gt;今年暑假，我第一次去台中的國美館，參觀 &lt;a href=&#34;https://www.ntmofa.gov.tw/information_1078_86836.html&#34;&gt;2018 年全國美術展&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;這年度盛會，分成油畫、水彩、版畫、水墨等十大類。大開眼界之餘，也不禁有個奇想：為什麼要分這麼多類別來競賽？為什麼不選出一個跨十大類別的首獎，就像武林盟主一樣？&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/nBlph7Vp92E?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;很外行吧！畢竟，油畫的美感判準，與版畫的美感判準、攝影的美感判準，本來就有很大不同，不能草率化約在同一把尺來衡量高下境界。&lt;/p&gt;
&lt;p&gt;把照片拍得像油畫，就能夠贏過油畫嗎？&lt;/p&gt;
&lt;p&gt;我們有選擇美術媒材的自由。一旦擇定媒材，就要正視及尊重該媒材的運用手法、該媒材營造的世界觀，以及該媒材表現境界的判準。&lt;/p&gt;
&lt;p&gt;軟體開發，亦然。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;//william-yeh.net/post/2018/10/methodology-and-criteria/&#34;&gt;前一篇文章&lt;/a&gt;初步提到&lt;strong&gt;方法論&lt;/strong&gt;與&lt;strong&gt;判準&lt;/strong&gt;之間的關係，這一篇文章，就來繼續探討幾種常見軟體研發方法的判準。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「多元典範的軟體開發取向」認為：我們可以視問題的性質，採取瀑布或敏捷軟體開發典範。&lt;/p&gt;
&lt;p&gt;然而，採取某種典範，不但要說明自己的&lt;strong&gt;方法論立場&lt;/strong&gt;，而且要採用該一典範的&lt;strong&gt;方法論判準&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;瀑布方法的判準&#34;&gt;瀑布方法的判準&lt;/h2&gt;
&lt;p&gt;敏捷三叔公 David Ko 在〈&lt;a href=&#34;http://kojenchieh.pixnet.net/blog/post/465054452-%E5%8E%9F%E4%BE%86%E7%80%91%E5%B8%83%E8%80%81%E7%A5%96%E6%98%AF%E6%83%B3%E5%81%9A%E6%95%8F%E6%8D%B7%E5%95%8A&#34;&gt;原來瀑布老祖是想做敏捷啊&lt;/a&gt;〉考古文章中指出，瀑布式開發始祖 Winston W. Royce 在 1970 年發表的&lt;a href=&#34;https://dl.acm.org/citation.cfm?id=41801&#34;&gt;會議論文&lt;/a&gt;中，總共提出兩種想法，一種是後來被世人普遍稱為&lt;del&gt;萬惡的&lt;/del&gt; waterfall 的版本，另一種則是帶些更務實風格的修正版。&lt;/p&gt;
&lt;p&gt;兩種想法，背後的核心觀念，其實都是 &lt;a href=&#34;https://www.pmi.org/learning/library/phase-gate-processes-promising-complex-547&#34;&gt;phase gate&lt;/a&gt; 或 &lt;a href=&#34;https://wiki.mbalib.com/zh-tw/%E9%97%A8%E5%BE%84%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F&#34;&gt;stage gate&lt;/a&gt; 的 &amp;ldquo;&lt;strong&gt;gate&lt;/strong&gt;&amp;rdquo; 機制：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/10/royce-1970.png&#34; alt=&#34;Royce 1970 - Managing the development of large software systems: concepts and techniques&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/10/royce-1970.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Royce 1970 - Managing the development of large software systems: concepts and techniques&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;以上圖來說，圓圈圈的部分，就是在各個階段 (phase/stage) 負責把關的守門員：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;PSR: Preliminary Software Review&lt;/li&gt;
&lt;li&gt;CSR: Critical Software Review&lt;/li&gt;
&lt;li&gt;FSAR: Final Software Acceptance Review&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這就是瀑布方法論的判準。&lt;/p&gt;
&lt;h3 id=&#34;合乎現實嗎&#34;&gt;合乎現實嗎？&lt;/h3&gt;
&lt;p&gt;要走 waterfall 路線，就要弄清楚 waterfall 的判準，並致力於判準的實踐品質，這是將方法論落地實施的重要關鍵。&lt;/p&gt;
&lt;p&gt;問題是：這個判準，合乎現實嗎？更進一步的問題是：是怎樣的世界觀，才會催生如此的判準？&lt;/p&gt;
&lt;p&gt;Waterfall 的世界觀就是，萬事萬物，都有一個自然的、可預測的線性執行順序。在這些自然的線性順序當中，會有一些關鍵的控制點，或者像《&lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2014940760328&#34;&gt;利潤的故事&lt;/a&gt;》所用的「地景的控制點」妙喻：「有些地方，就是比其他地方重要」。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/10/control-point.jpg&#34; alt=&#34;地景的控制點&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/10/control-point.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;地景的控制點&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這些「地景的控制點」，就是瀑布方法 phase gate 判準之所在。&lt;/p&gt;
&lt;p&gt;不可否認，的確有人在這種方法論、世界觀、判準底下活得很好。認清這個判準，以及這個判準背後代表的方法論及世界觀，有助於你和這類人種互動。&lt;/p&gt;
&lt;p&gt;或許更重要的是，你不同意這種方法論，卻又得與這類人種合作，你就應該在這些判準的層次上，&lt;del&gt;挑戰&lt;/del&gt;關心對方對這些判準的認知與實踐品質。&lt;/p&gt;
&lt;p&gt;在判準的層次動工，比各自表述的爭辯更有力。&lt;/p&gt;
&lt;h2 id=&#34;scrum-的判準&#34;&gt;Scrum 的判準&lt;/h2&gt;
&lt;p&gt;儘管 Scrum 是很精簡的框架，但真正核心的判準，未必都被清楚地認知。&lt;/p&gt;
&lt;p&gt;我個人認為，Scrum 的判準，就在於 &lt;strong&gt;increment&lt;/strong&gt;，或者更具體一點講：&lt;strong&gt;PSPI&lt;/strong&gt; (potentially shippable product increment)。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.scrumguides.org/&#34;&gt;&lt;em&gt;The Scrum Guide&lt;/em&gt;&lt;/a&gt; (2017 版) 說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum 使用疊代和逐步 increment 的方式，來最大化可預測性和控制風險。&lt;/p&gt;
&lt;p&gt;在 Sprint 結束時，increment 是一種可檢視，完成的工作實體，並可支持經驗主義。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;簡言之，Scrum 是以 increment 作為載具、「地景的控制點」，藉以反映出透明性、檢視性、調適性這三大主張，藉以最大化可預測性及控制風險。&lt;/p&gt;
&lt;p&gt;並不是隨隨便便任何一個軟體中間狀態都夠資格稱為 &amp;ldquo;increment&amp;rdquo;，而是有標準的。Scrum 是很精簡的框架，將這標準交由團隊來定義 (DoD; definition of done)，但能否嚴守這個承諾共識，決定了 Scrum 實踐的成敗：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum Teams 用疊代和逐步 increment 的方式交付產品，將回饋的機會最大化。用逐步
increment 的方式交付「完成」的產品，可以確保一直提供一個潛在可用的產品版本。&lt;/p&gt;
&lt;p&gt;真正執行的人員和檢視 increment 成果的人員，需要對「完成」之定義，有一個共同的認知。&lt;/p&gt;
&lt;p&gt;在 Sprint 的最後，新的 increment 必須是「完成」的，這意味著它必須是可用的狀態，並符合 Scrum Team 對於「完成」之定義。&lt;/p&gt;
&lt;p&gt;在 Sprint 過程中，對於品質的目標不可以降低。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;簡言之，Scrum 的判準，就在於 increment 的定義，以及能否在各個疊代過程中，捍衛並精進這個 increment 的整全狀態。&lt;/p&gt;
&lt;h3 id=&#34;合乎現實嗎-1&#34;&gt;合乎現實嗎？&lt;/h3&gt;
&lt;p&gt;要走 Scrum 路線，就要弄清楚 Scrum 的判準，並致力於判準的實踐品質，這是將方法論落地實施的重要關鍵。&lt;/p&gt;
&lt;p&gt;問題是：這個判準，合乎現實嗎？更進一步的問題是：是怎樣的世界觀，才會催生如此的判準？&lt;/p&gt;
&lt;p&gt;Scrum 的世界觀就是，萬事萬物，都有一個自然的生物成長順序。或嬰兒，或幼童，或成年，在每一個當下，必然都是整全的生命個體。&lt;/p&gt;
&lt;p&gt;認清這個判準，以及這個判準背後代表的方法論及世界觀，有助於你與其他物種分別為聖。&lt;/p&gt;
&lt;p&gt;或許更重要的是，你支持這種方法論，卻又得與反對者合作，你就應該在這些判準的層次上，盡一切努力守護這些判準的認知與實踐品質，並最大化這些判準的價值能見度。&lt;/p&gt;
&lt;p&gt;在判準的層次動工，比各自表述的爭辯更有力。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2019-02-11 補充
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;Mike Cohn 在新文章 &lt;a href=&#34;https://www.mountaingoatsoftware.com/blog/why-agile-teams-put-so-much-emphasis-on-being-done-each-iteration&#34;&gt;&lt;em&gt;Why Agile Teams Put So Much Emphasis on Being Done Each Iteration&lt;/em&gt;&lt;/a&gt; 中，對這論點做了更詳細的說明。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h2 id=&#34;kanban-的判準&#34;&gt;Kanban 的判準&lt;/h2&gt;
&lt;p&gt;Kanban 是極度精簡的框架，甚至連「框架」都不太能夠稱得上。因此，他的判準很容易辨識，也很容易衡量，那就是 Kanban 的核心規則：拉動系統 (pull)、WIP 限制。&lt;/p&gt;
&lt;p&gt;問題是：這個判準，合乎現實嗎？更進一步的問題是：是怎樣的世界觀，才會催生如此的判準？&lt;/p&gt;
&lt;p&gt;Kanban 的世界觀就是，萬事萬物，都有一個自然的流動順序。我們所該做的，就是讓這流動，以小批量的方式，毫無阻礙地順流而下。&lt;/p&gt;
&lt;p&gt;認清這個判準，以及這個判準背後代表的方法論及世界觀，有助於你掌握這個「入門毒藥」(gateway drug) &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 的殊勝之處，以及⋯⋯潛在的問題。 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;或許更重要的是，你支持這種方法論，卻又得與反對者或不可知論者合作，你就應該在這些判準的層次上，盡一切努力守護這些判準的認知與實踐品質，並最大化這些判準的價值能見度。&lt;/p&gt;
&lt;p&gt;在判準的層次動工，比各自表述的爭辯更有力。&lt;/p&gt;
&lt;h2 id=&#34;善用判準作為施力點&#34;&gt;善用判準作為施力點&lt;/h2&gt;
&lt;p&gt;判準，是將方法論落地實施的重要關鍵，也是方法論歧見的槓桿解。&lt;/p&gt;
&lt;p&gt;畢竟，方法論，甚至背後的世界觀，不是那麼容易就撼動得了。&lt;/p&gt;
&lt;p&gt;試問：你對自己採用的軟體開發方法論，了解它的判準嗎？&lt;/p&gt;
&lt;p&gt;試問：你對其他人採用的不一樣的軟體開發方法論，也了解它的判準嗎？&lt;/p&gt;
&lt;p&gt;理解別人的判準，善用判準作為施力點，在判準的層次動工，比起辯論不同方法論之間的優劣，更有建設性，也更能推動事情的前進。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      「判準與指標」系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2018/10/methodology-and-criteria/&#34;&gt;軟體開發，除了方法論，還有⋯⋯&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 敏捷的判準&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2018/11/lean-startup-criteria/&#34;&gt;Lean Startup 的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/12/dev-metrics/&#34;&gt;如何衡量敏捷對於軟體研發效能的利益？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://kojenchieh.pixnet.net/blog/post/386166536-%E7%9C%8B%E6%9D%BF%E6%98%AF%E5%85%A5%E9%96%80%E6%AF%92%E8%97%A5-%28gateway-drug%29&#34;&gt;看板是入門毒藥 (gateway drug)&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;http://teddy-chen-tw.blogspot.com/2017/06/blog-post_21.html&#34;&gt;為什麼看板方法適合控制與能力文化？&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>軟體開發，除了方法論，還有⋯⋯</title>
      <link>//william-yeh.net/post/2018/10/methodology-and-criteria/</link>
      <pubDate>Thu, 25 Oct 2018 12:22:16 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/10/methodology-and-criteria/</guid>
      
        <description>&lt;p&gt;在某些人眼中，「敏捷」是狂熱份子聚集的邪教。&lt;/p&gt;
&lt;p&gt;或許是被困在守舊勢力太久了，敏捷信徒不只有改變世界的熱情，更有捨我其誰的急迫感。不過，在傳播理念或推動改變時，若操之過急，忽略對方所處的情境、歷史及歷程，就很難有建設性對話。在這守舊勢力龐大的世界，自然很容易陣亡。&lt;/p&gt;
&lt;p&gt;但這還只是表象。歧見，單靠對話仍不足以化解，更需要在方法論層次達到理解，方可進退有據。&lt;/p&gt;
&lt;p&gt;尤其在看過《&lt;a href=&#34;https://www.books.com.tw/products/0010791756&#34;&gt;社會科學的理路&lt;/a&gt;》之後，我領悟到一些根源問題及槓桿解。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/10/social-sci.jpg&#34; alt=&#34;圖一　《社會科學的理路》第一版 (2001) 及第四版 (2018)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/10/social-sci.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;圖一　《社會科學的理路》第一版 (2001) 及第四版 (2018)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;方法論形塑世界觀&#34;&gt;方法論形塑世界觀&lt;/h2&gt;
&lt;p&gt;我們都在採用&lt;strong&gt;方法論&lt;/strong&gt;，不管我們自覺或不自覺。&lt;/p&gt;
&lt;p&gt;瀑布模型是一種方法論，敏捷是一種方法論，Scrum 及 Kanban 則是敏捷方法論底下更具體的實踐作法。&lt;/p&gt;
&lt;p&gt;為什麼會決定採取某一種方法論？原因可能很多，本文不予探討。本文想談的是，採取某一種方法論，就會逐漸被該方法論所形塑的&lt;strong&gt;世界觀&lt;/strong&gt;所包圍，以及接下來的連鎖效應——不管我們自覺或不自覺。&lt;/p&gt;
&lt;p&gt;論到方法論及世界觀，我想要引述《&lt;a href=&#34;https://www.books.com.tw/products/0010791756&#34;&gt;社會科學的理路&lt;/a&gt;》的見解。&lt;/p&gt;
&lt;p&gt;本書作者黃光國教授，是台灣社會心理學界的大老。他花了將近十年的工夫寫成本書第一版 (2001 年)，析論二十世紀發展出來的五種科學哲學主要典範之間的關聯。退休後推出的第四版 (2018 年)，將原本具有歷史意義的第一章整個抽換掉，很可惜，所以我仍然留著第一版。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010791756&#34;&gt;社會科學的理路&lt;/a&gt;》，從科學哲學角度指出：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/10/paradigm.jpg&#34; alt=&#34;圖二　方法論與世界觀&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/10/paradigm.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;圖二　方法論與世界觀&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;看起來有點抽象，讓我們從「軟體開發流程」的角度來照樣造句，就會茅塞頓開：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;任何一種&lt;strong&gt;軟體開發流程&lt;/strong&gt;所主張的「&lt;strong&gt;本體論／認識論／方法論&lt;/strong&gt;」，構成了該一開發流程的「&lt;strong&gt;世界觀&lt;/strong&gt;」，它在性質上是一種&lt;strong&gt;形而上學的預設&lt;/strong&gt;，是由軟體開發團隊的&lt;strong&gt;基本信念&lt;/strong&gt;所決定的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一個&lt;strong&gt;軟體開發者&lt;/strong&gt;，對於方法論的回答，必然會受到其「本體論／認識論」立場的&lt;strong&gt;限制&lt;/strong&gt;，而不能隨意選擇。當他決定採用某種方法論的時候，他也必須同時接受其「本體論／認識論」&lt;strong&gt;預設&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以，採取瀑布模式的人，採取敏捷模式的人，兩群人的世界觀，以及信念、預設，是非常不一樣的。&lt;/p&gt;
&lt;p&gt;想合作，或是想進一步改變對方，就得先認清這一點：你們的對話，是不同世界觀的對話。&lt;/p&gt;
&lt;h2 id=&#34;方法論之外還有判準&#34;&gt;方法論之外，還有判準&lt;/h2&gt;
&lt;p&gt;瀑布模型是一種方法論，敏捷是一種方法論。&lt;/p&gt;
&lt;p&gt;不同方法論，有優劣之別嗎？&lt;/p&gt;
&lt;p&gt;或許有吧。但更常見的事實是：不同方法論，各有擅長的場域。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010791756&#34;&gt;社會科學的理路&lt;/a&gt;》第一版的第一章，從科學哲學角度指出：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/10/paradigm-criteria.jpg&#34; alt=&#34;圖三　典範的判準&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/10/paradigm-criteria.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;圖三　典範的判準&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;文中點出很重要的觀念：「&lt;strong&gt;判準&lt;/strong&gt;」。&lt;/p&gt;
&lt;p&gt;看起來有點抽象，讓我們再從「軟體開發流程」的角度來照樣造句吧！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;我是贊同「敏捷運動」的。然而，我卻認為：「敏捷／不敏捷」不能夠作為軟體開發流程好壞的&lt;strong&gt;判準&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我主張的「多元典範的軟體開發取向」認為：我們可以視問題的性質，採取瀑布或敏捷軟體開發典範。然而，採取某種典範，不但要說明自己的&lt;strong&gt;方法論立場&lt;/strong&gt;，而且要採用該一典範的&lt;strong&gt;方法論判準&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在我看來，軟體開發而沒有判準，是非常不可思議之事。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;判準，是將方法論落地實施的重要關鍵，也是方法論歧見的槓桿解。&lt;/p&gt;
&lt;p&gt;試問：你對自己採用的軟體開發方法論，了解它的判準嗎？&lt;/p&gt;
&lt;p&gt;試問：你對其他人採用的不一樣的軟體開發方法論，也了解它的判準嗎？&lt;/p&gt;
&lt;p&gt;先賣個關子。下一篇文章，再分別針對瀑布與敏捷取向，談談我所認為的方法論判準。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      「判準與指標」系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 軟體開發，除了方法論，還有⋯⋯&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/10/agile-criteria/&#34;&gt;敏捷的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2018/11/lean-startup-criteria/&#34;&gt;Lean Startup 的判準&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2018/11/agile-value/&#34;&gt;敏捷的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2018/11/devops-value/&#34;&gt;DevOps 的價值與指標&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/12/dev-metrics/&#34;&gt;如何衡量敏捷對於軟體研發效能的利益？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>敏捷之途無他，刻意練習而已矣！</title>
      <link>//william-yeh.net/post/2018/09/deliberate-practice-for-agile/</link>
      <pubDate>Wed, 19 Sep 2018 23:25:01 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/09/deliberate-practice-for-agile/</guid>
      
        <description>&lt;p&gt;親愛的學員們：&lt;/p&gt;
&lt;p&gt;感謝你們 9/13 ＆ 9/14，一起共度充滿歡笑的&lt;a href=&#34;https://www.accupass.com/event/1807260907551870930205&#34;&gt;兩日&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;課堂上，我多次提醒：請大家回去之後，要持續刻意練習；自練，對練，都好。&lt;/p&gt;
&lt;p&gt;你可能會有疑問：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;要刻意練習什麼？&lt;/li&gt;
&lt;li&gt;要如何刻意練習？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;怕細節沒講清楚，我用這篇文章來補充吧。而且，就用我們在課堂上玩過好幾次的 impact mapping 來展開這議題吧（你看，我這不也是一種刻意練習嗎？）。&lt;/p&gt;
&lt;h2 id=&#34;goal&#34;&gt;Goal&lt;/h2&gt;
&lt;p&gt;這番刻意練習的總目標是：成為更好的 Scrum master，引領團隊達成他們被賦予的商業目標。&lt;/p&gt;
&lt;h2 id=&#34;actors&#34;&gt;Actors&lt;/h2&gt;
&lt;p&gt;Scrum master 有多種樣貌。&lt;/p&gt;
&lt;p&gt;在 &lt;a href=&#34;https://greatscrummaster.com/&#34;&gt;&lt;em&gt;The Great ScrumMaster&lt;/em&gt;&lt;/a&gt; 書中提到 Scrum master 的核心能力有：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/09/sm-core-competency.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/09/sm-core-competency.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;心態模式則有：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/09/sm-mindset.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/09/sm-mindset.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;在 &amp;ldquo;&lt;a href=&#34;https://www.scrum.org/resources/blog/evolution-scrum-master&#34;&gt;Evolution of the Scrum Master&lt;/a&gt;&amp;rdquo; 文章中提到 Scrum master 的升級路線：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/09/sm-levels.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/09/sm-levels.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;在 &amp;ldquo;&lt;a href=&#34;https://www.scrum.org/resources/8-stances-scrum-master&#34;&gt;The 8 Stances of a Scrum Master&lt;/a&gt;&amp;rdquo; 及 &amp;ldquo;&lt;a href=&#34;https://medium.com/the-liberators/myth-the-scrum-master-is-a-junior-agile-coach-9defb2dd6def&#34;&gt;Myth: The Scrum Master is a Junior Agile Coach&lt;/a&gt;&amp;rdquo; 文章中列出 Scrum master 的八種姿態：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Servant leader&lt;/li&gt;
&lt;li&gt;Coach&lt;/li&gt;
&lt;li&gt;Facilitator&lt;/li&gt;
&lt;li&gt;Teacher&lt;/li&gt;
&lt;li&gt;Mentor&lt;/li&gt;
&lt;li&gt;Manager&lt;/li&gt;
&lt;li&gt;Impediment remover&lt;/li&gt;
&lt;li&gt;Change agent&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這是窮舉不盡的。短短兩天的課堂，我只講解其中極為重要的三項，並在 Q&amp;amp;A 時淺淺帶到第四項：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Teacher&lt;/strong&gt;：教學輔導與分享經驗。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Facilitator&lt;/strong&gt;：掌控討論流程，確保會議如質進行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coach&lt;/strong&gt;：成員個人的成長，團隊的自組織、責任感與所有權。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Change agent&lt;/strong&gt;：在組織的各個層面，引領影響變革。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;單以這幾項來說，就已經很難樣樣到位了。&lt;/p&gt;
&lt;p&gt;所以，需要刻意練習。&lt;/p&gt;
&lt;h2 id=&#34;impact&#34;&gt;Impact&lt;/h2&gt;
&lt;h3 id=&#34;-teacher&#34;&gt;◉ Teacher&lt;/h3&gt;
&lt;p&gt;身為敏捷原理與實踐的專家，越能夠傳道授業解惑，就越能有效達成前述的總目標。&lt;/p&gt;
&lt;p&gt;整整兩天課程，你們已經親自體會到敏捷圈的 &amp;ldquo;teacher&amp;rdquo; 是何等樣貌了。&lt;/p&gt;
&lt;p&gt;正如&lt;a href=&#34;https://medium.com/@linchi/%E6%95%8F%E6%8D%B7%E5%8E%9F%E7%90%86%E8%88%87%E5%9C%98%E9%9A%8A%E5%A1%91%E9%80%A0-%E8%AA%B2%E7%A8%8B%E5%BF%83%E5%BE%97-ade6fd4080b3&#34;&gt;學員 LinChi 所說&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;兩天的課程學到不少東西，透過遊戲反映現實工作的情況。有時用說的不一定有說服力，做中學的震撼比較大。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果你覺得這種 &amp;ldquo;teacher&amp;rdquo; 樣貌的效果極好，那麼，回去面對自家團隊時，也會想試試看嗎？&lt;/p&gt;
&lt;p&gt;這就需要刻意練習。&lt;/p&gt;
&lt;p&gt;刻意練習的素材，可先從 &lt;a href=&#34;https://www.books.com.tw/products/0010763045&#34;&gt;&lt;em&gt;Kanban in Action&lt;/em&gt;&lt;/a&gt; 第 13 章下手。先模仿，照表操課，謹守「高頻 PDCA 循環」心法，日後你自然會湧現改編及創造的點子。或者，去上課，直接&lt;a href=&#34;//william-yeh.net/post/2018/04/board-game-creation/&#34;&gt;向第一流明師取經&lt;/a&gt;吧。&lt;/p&gt;
&lt;h3 id=&#34;-facilitator&#34;&gt;◉ Facilitator&lt;/h3&gt;
&lt;p&gt;許多人被不良職場習氣禁錮了，渾然忘記自己才是職涯的主人。身為敏捷精神的守護者，若是越懂得提供機會讓團隊成員&lt;strong&gt;自發湧現&lt;/strong&gt;觀點，就越能夠孵育高效的自組織團隊，就越能有效達成前述的總目標。&lt;/p&gt;
&lt;p&gt;記得嗎？在 1、2、3、7 這幾個單元中，我一直提醒：「這些寫在白板及便利貼上面的種種絕妙點子，完全都是你們大家自己想出來講出來的喔！我完全沒有主動教導你們喔！」這就是引導的魔力。&lt;/p&gt;
&lt;p&gt;請試著回憶，整整兩天，我用了多少次 ORID 這個極度基礎的回顧手法？你也可以試著拆解我是如何用 impact mapping 這個貌似簡單的框架，橫跨兩日，貫串 4、8、9 這幾個單元。&lt;/p&gt;
&lt;p&gt;如果你覺得這種 &amp;ldquo;facilitator&amp;rdquo; 樣貌的效果極好，那麼，回去面對自家團隊時，也會想試試看嗎？&lt;/p&gt;
&lt;p&gt;這也需要刻意練習。&lt;/p&gt;
&lt;p&gt;刻意練習的指引，可先從繁體版《&lt;a href=&#34;https://williampjyeh.notion.site/bab7091e6f5c42d59797fdb1bfd5422f&#34;&gt;誰說我們不能一起做決定&lt;/a&gt;》(2/e) 或簡體版《&lt;a href=&#34;https://www.sanmin.com.tw/product/index/005689892&#34;&gt;結構化研討：參與式決策操作手冊&lt;/a&gt;》(3/e) 下手，打好引導的基本功。接著，請翻閱 4、5、8、9、10 單元的講義，常常揣摩哪一個框架可以適用於當下的引導情境。也請多多觀摩體驗好的流程設計（譬如 &lt;a href=&#34;https://www.books.com.tw/products/0010722447&#34;&gt;Design Sprint&lt;/a&gt;），模仿，拆解，日後你自然會湧現改編及創造的點子。&lt;/p&gt;
&lt;h3 id=&#34;-coach&#34;&gt;◉ Coach&lt;/h3&gt;
&lt;p&gt;敏捷原理，說穿了，很單純，也很合理；但落地實施起來為何總是卡卡的？&lt;/p&gt;
&lt;p&gt;正如&lt;a href=&#34;https://www.facebook.com/motics/posts/10214334378726324&#34;&gt;學員 SamLi 所說&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;關於敏捷與團隊相關的書目很多，但是能夠在自身的職場運用自如，可謂是知易行難。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很多時候，單純的「知」還不夠，還需要「行」的反覆淬鍊，甚至成為肌肉記憶。這就需要動用教練法。&lt;/p&gt;
&lt;p&gt;身為團隊專屬的指導者，若是越懂得利用近距離&lt;strong&gt;即時指導&lt;/strong&gt;的機會，持續提供客製化培訓，就越能夠鍛鍊出高效的自組織團隊，也就越能有效達成前述的總目標。&lt;/p&gt;
&lt;p&gt;教練法，是個高明的技藝。&lt;/p&gt;
&lt;p&gt;記得嗎？在 5、8、9、10 這幾個單元，我額外加重比例在主動示範及積極矯正上。原本構想是要以&lt;a href=&#34;https://gamestorming.com/fishbowl/&#34;&gt;金魚缸手法&lt;/a&gt;，讓大家現場充分對練，也充分觀察。可惜課堂時間有限，無法完全照原本的構想進行，這就需要你們回去後刻意練習了。&lt;/p&gt;
&lt;p&gt;教練法，我自己也還在探索，僅提供三本書給你們參考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;激發員工潛力的薩提爾教練模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.taaze.tw/products/11100227775.html&#34;&gt;豐田形學&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://williampjyeh.notion.site/15fc87da0c2e48f1bfb5e3d518cd8cbc&#34;&gt;比賽，從心開始&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-to-do-next&#34;&gt;What to Do Next?&lt;/h2&gt;
&lt;p&gt;如果你所在的場域，有專家等級的 mentor，那麼，恭喜你。&lt;/p&gt;
&lt;p&gt;如果沒有呢？&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010752714&#34;&gt;刻意練習&lt;/a&gt;》給了很棒的建議：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;若想進步，就得為自己創造機會。若沒有老師，就得自己設計一套練習活動。 (pp. 206&amp;ndash;207)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;先找出頂尖專家，弄清楚他們做了些什麼才能如此成功，接著發展出讓自己可以做到那些事的訓練技巧。 (p.148)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;想在沒有老師的情況下有效練習一項技能，建議記住三個重點：專注投入、意見回饋、解決問題。將技能分成可以有效重複練習和分析的幾個部分，確定弱點何在，並找出解決方法。 (p.209)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;私下揣摩。敏銳觀察。&lt;/p&gt;
&lt;p&gt;私下練習。&lt;/p&gt;
&lt;p&gt;同好對練。&lt;/p&gt;
&lt;p&gt;參與社群。&lt;/p&gt;
&lt;p&gt;找時機實際發揮。&lt;/p&gt;
&lt;p&gt;有心的你，一定找得出適合你的刻意練習方法。並且在過程中，逐步發展出你的風格。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在這個世界上，你就愛一種東西，你就在你愛的這個東西裡把自己練到完美，練到無懈可擊，你因此尋得滿足，此外的一切其實無足輕重。你變得堅強，足以抵抗不時傾巢而來的寂寞，你變得勇敢，你學會拒絕周遭的喧譁與熱鬧，你學會簡單而嚴肅，你形成一種風格，唯你獨有。&lt;/p&gt;
&lt;p&gt;  &amp;mdash; Quote: 劉大任，《&lt;a href=&#34;https://www.books.com.tw/products/0010025396&#34;&gt;強悍而美麗&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;加油吧！&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      Scrum master 培訓系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2021/03/train-new-scrum-master/&#34;&gt;如何訓練一個新的 Scrum master？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 敏捷之途無他，刻意練習而已矣！&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2021/07/revisit-psm1/&#34;&gt;Scrum 認證模擬測驗的兩項啟發&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2022/03/prof-common-vocabulary/&#34;&gt;敏捷啟航的專業基礎：共同語彙&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>思維的重量訓練</title>
      <link>//william-yeh.net/post/2018/09/thinking-weight-training/</link>
      <pubDate>Tue, 04 Sep 2018 11:30:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/09/thinking-weight-training/</guid>
      
        <description>&lt;p&gt;上週五【&lt;a href=&#34;https://devopsdays.tw/2018/workshop.html&#34;&gt;系統思考的四堂課・DevOps 特別版&lt;/a&gt;】，表定 7 小時，延長賽到 7.5 小時，感謝首梯公開班同學的熱情參與，共度刺激的一天。&lt;/p&gt;
&lt;p&gt;課後仍持續收到提問，我挑選幾則統一回覆。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/09/systhinking-workshop-2018-08-31.jpg&#34; alt=&#34;【系統思考的四堂課・DevOps 特別版】2018-08-31 課堂實況&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/09/systhinking-workshop-2018-08-31.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;【系統思考的四堂課・DevOps 特別版】2018-08-31 課堂實況&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;有學員問道：「為什麼課前作業會挑選這麼難的題目？」&lt;/p&gt;
&lt;p&gt;我承認，這兩份課前作業，有難度；但這難度是必要的。要有這樣的挑戰強度，才能反襯系統思考的威力。否則，簡簡單單就能破解的作業，為什麼還要花金錢花時間前來上課呢？&lt;/p&gt;
&lt;p&gt;好吧，說正經的。要有這樣的挑戰強度，才能先將各位的&lt;strong&gt;思維肌肉&lt;/strong&gt;稍微鍛鍊一下，負重訓練到能夠跟得上課程現場的思辨強度。&lt;/p&gt;
&lt;p&gt;這門課，原本在我公司裡面是分成四個禮拜，每次 1.5 小時；個案研討素材，得以在四個禮拜的自發性小組討論活動去分散腦力負荷。現在，變成公開班，一整天 7 小時，腦力挑戰嚴峻。所以，把個案研討素材提前到正式上課前就讓大家咀嚼思考，課堂進行才會有效率。&lt;/p&gt;
&lt;p&gt;（儘管如此，份量仍然沈重到哀鴻遍野。所以，第二梯公開班，我可能會拆成兩個半天舉行，一週 4 小時，隔週上。）&lt;/p&gt;
&lt;p&gt;這種鍛鍊思維肌肉的方法，不是我發明的。大師在《&lt;a href=&#34;https://www.books.com.tw/products/0010697445&#34;&gt;司徒賢達談個案教學&lt;/a&gt;》p.191 如此解釋「長個案」與「短個案」的選擇標準：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;缺乏工作經驗的人，應該用心研讀長個案，然後在複雜的情況下練習整合與重組資料、發掘問題，並依據資料分析的結果採取行動。此一程序對「練功」效果極好。&lt;/p&gt;
&lt;p&gt;短個案的使用者，必須從有限的文字中進行許多邏輯推演，因此對個案中管理議題或產業相關的「互補知識」必須相當豐富，比較適合有經驗的中高階經理人。使用短個案的前提是：學員本來功力就有一定水準，而且由於必要的推論多，可以利用討論把他們的寶貴經驗萃取出來，尤其對忙碌的在職學員更是如此。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;感謝大師背書。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;有學員問道：「為什麼你的系統思考方法，要分&lt;strong&gt;因果關係圖&lt;/strong&gt;與 &lt;strong&gt;CLD&lt;/strong&gt; 兩部曲？」&lt;/p&gt;
&lt;p&gt;其實這是限制理論暨豐田方法的專家稲垣公夫在《&lt;a href=&#34;http://www.books.com.tw/products/0010759729&#34;&gt;深思快想&lt;/a&gt;》這本奇書當中首先提出的，突破了我過去的盲點（詳見&lt;a href=&#34;//william-yeh.net/post/2018/06/sys-thinking-workshop/&#34;&gt;這篇文章&lt;/a&gt;），便將這實施觀點納入我的系統思考 &lt;strong&gt;SLR·CPI&lt;/strong&gt; 方法論中。&lt;/p&gt;
&lt;p&gt;如同我在講義上提到的，如果你骨骼精奇，天生就是練武奇才，或許可以一開始就直接從 CLD 切入。可惜，我發現，很多人基本功不太扎實，容易犯下過度簡化、倒果為因等&lt;strong&gt;邏輯謬誤&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;CLD 是很犀利的工具，但也容易誤用，淪為替既有結論背書的橡皮圖章。&lt;/p&gt;
&lt;p&gt;「有不得機得勢處，其病必於腰腿求之。」要提高系統思考的品質，還是得講究&lt;strong&gt;理則&lt;/strong&gt;的起手式才是。否則，畫出的 CLD 再犀利，一堆就倒，有什麼用？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;有學員問道：「該怎樣從因果關係圖當中抽取 CLD 的&lt;strong&gt;變數&lt;/strong&gt;／&lt;strong&gt;變項&lt;/strong&gt;？」&lt;/p&gt;
&lt;p&gt;對初學者，我建議：大量觀摩精選範例。&lt;/p&gt;
&lt;p&gt;鋪陳一次因果陳述，自己畫一次 CLD，對照範例，看圖說故事，檢討。休息一兩天，再覆盤。如此刻意練習一陣子，你會抓到 CLD 變數／變項的感覺。&lt;/p&gt;
&lt;p&gt;當然啦，《&lt;a href=&#34;https://www.books.com.tw/products/0010584669&#34;&gt;第五項修練 Ⅱ・實踐篇&lt;/a&gt;》及《&lt;a href=&#34;http://www.books.com.tw/products/0010759729&#34;&gt;深思快想&lt;/a&gt;》也各有建議的手法，不妨一試。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;有學員問道：「這方法似乎只能用來分析問題現況與原因，但似乎不能用來尋找解法？」&lt;/p&gt;
&lt;p&gt;某方面來說，的確如此。但進一步來說，精準找到客觀局勢與根本原因，是否有助於激發你尋找槓桿解的專注力及創意呢？&lt;/p&gt;
&lt;p&gt;再度借用大師的論點吧。《&lt;a href=&#34;https://www.books.com.tw/products/0010697445&#34;&gt;司徒賢達談個案教學&lt;/a&gt;》p.23 將狹義知識分成三大類：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;結構性知識：各種變項間的「因果關係」，以及這些因果關係背後的理由、影響因果的因素等。&lt;/li&gt;
&lt;li&gt;行動的程序性知能：採取行動、制定決策原則、研判下一步的知識與能力。&lt;/li&gt;
&lt;li&gt;診斷的程序性知能：針對現象找出原因的知能。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;套用這種分類，系統思考主要隸屬於「結構性知識」與「診斷的程序性知能」這兩大類。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010697445&#34;&gt;司徒賢達談個案教學&lt;/a&gt;》p.293 進一步說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;決策過程中的重要作法「找出前提、驗證前提」。&lt;/p&gt;
&lt;p&gt;知識庫中「資訊」和「解決方案」的存量，通常遠多於「結構性知識」。然而當面對特定問題時，有時雖然想得到的可能解決方案很多，但未必知道應該如何選取；所掌握的資訊也很豐富，但未必知道哪些資訊才對解決此一問題最具有關鍵性。這時，在決策過程中常用到的「找出各方案的前提，再來驗證前提」的思考過程，就可以幫助方案的選擇。&lt;/p&gt;
&lt;p&gt;在此一決策分析過程中，方案的提出相當仰賴知識庫中所擁有的「解決方案」；而「找出前提」則要靠知識庫中「因果關係」或結構性知識去了解分別在哪些情況下，哪個方案更能達到預期的目標。因此，想得出來的方案要夠多、夠合理，才有得比較；而強大的「結構性知識」則可以推斷這些方案的可行性分別建立在哪些前提上。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;套用這種觀點，系統思考可協助你建構扎實的「結構性知識」，並在「驗證前提」方面替你提出的解決方案把關。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上是針對【&lt;a href=&#34;https://devopsdays.tw/2018/workshop.html&#34;&gt;系統思考的四堂課・DevOps 特別版&lt;/a&gt;】首梯公開班同學的提問，予以統一回覆。更多學員的心得分享，請見 &lt;a href=&#34;http://bit.ly/2MMtAdG&#34;&gt;1&lt;/a&gt;, &lt;a href=&#34;http://bit.ly/2NOqcv2&#34;&gt;2&lt;/a&gt;, &lt;a href=&#34;http://bit.ly/2oBvZti&#34;&gt;3&lt;/a&gt;, &lt;a href=&#34;http://bit.ly/2PAb9WF&#34;&gt;4&lt;/a&gt;, &lt;a href=&#34;http://bit.ly/2Q2bToa&#34;&gt;5&lt;/a&gt;, &lt;a href=&#34;http://bit.ly/2wDxpb2&#34;&gt;6&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系統思考工作坊 - 系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 【系統思考的四堂課】&lt;a href=&#34;//william-yeh.net/post/2018/06/sys-thinking-workshop/&#34;&gt;緣起&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 第一場公開班課後回覆：思維的重量訓練&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/&#34;&gt;從系統思考角度讀《獨角獸專案》&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;➍ &lt;a href=&#34;//william-yeh.net/post/2024/07/dissecting-devops-via-systems-thinking/&#34;&gt;從系統思考角度談 DevOps 三步工作法&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>系統思考的四堂課</title>
      <link>//william-yeh.net/post/2018/06/sys-thinking-workshop/</link>
      <pubDate>Thu, 21 Jun 2018 23:26:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/06/sys-thinking-workshop/</guid>
      
        <description>&lt;p&gt;過去四週，我在公司內帶了一系列【&lt;strong&gt;系統思考的四堂課&lt;/strong&gt;】。本文回顧整件事的來龍去脈，為自己做個紀錄及紀念。&lt;/p&gt;
&lt;h2 id=&#34;緣起&#34;&gt;緣起&lt;/h2&gt;
&lt;h3 id=&#34;其一&#34;&gt;其一&lt;/h3&gt;
&lt;p&gt;過去兩年，我分別以&lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;限制理論&lt;/a&gt;的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Thinking_processes_%28theory_of_constraints%29&#34;&gt;thinking processes&lt;/a&gt;（思維程序；思考方式）及系統動力學 (&lt;a href=&#34;https://en.wikipedia.org/wiki/System_dynamics&#34;&gt;system dynamics&lt;/a&gt;) 兩大思維角度，給了幾場 DevOps 及 Docker 的演講（見 &lt;a href=&#34;//william-yeh.net/post/2016/08/devops-a-toc-perspective/&#34;&gt;文章 1&lt;/a&gt;、&lt;a href=&#34;https://school.soft-arch.net/blog/268878/embrace-docker&#34;&gt;文章 2&lt;/a&gt;、&lt;a href=&#34;//william-yeh.net/post/2017/10/devops-a-system-dynamics-perspective/&#34;&gt;文章 3&lt;/a&gt;）。過程中，觀察到一些有趣的事：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DDD 要說故事，&lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD&lt;/a&gt; 要說故事，&lt;a href=&#34;https://en.wikipedia.org/wiki/Current_reality_tree_%28theory_of_constraints%29&#34;&gt;CRT&lt;/a&gt; 要說故事，user journey 要說故事，簡報要說故事。&lt;/p&gt;
&lt;p&gt;凡事都要有說故事的能力。&lt;/p&gt;
&lt;p&gt;&amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/857385983406350337&#34;&gt;2017-04-27 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;突然發現，&lt;a href=&#34;https://en.wikipedia.org/wiki/System_dynamics&#34;&gt;系統思考&lt;/a&gt;的&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype&#34;&gt;系統基模&lt;/a&gt;中，大半都是雙裂結構；這恰巧與 TOC 的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Evaporating_Cloud&#34;&gt;Evaporating Cloud&lt;/a&gt; 有許多相互呼應之處。&lt;/p&gt;
&lt;p&gt;&amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/887000401140105216&#34;&gt;2017-07-18 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我隱約察覺到，來自&lt;a href=&#34;https://en.wikipedia.org/wiki/System_dynamics&#34;&gt;系統思考&lt;/a&gt;陣營的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD&lt;/a&gt; 與來自&lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;限制理論&lt;/a&gt;陣營的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Current_reality_tree_%28theory_of_constraints%29&#34;&gt;CRT&lt;/a&gt;，兩者有種深層的相似性。&lt;/p&gt;
&lt;h3 id=&#34;其二&#34;&gt;其二&lt;/h3&gt;
&lt;p&gt;後來，在某個場合，&lt;a href=&#34;https://ruddyblog.wordpress.com/&#34;&gt;Ruddy 老師&lt;/a&gt;向我拋出一則有趣的提問：「為什麼高德拉特發展出 &lt;a href=&#34;https://en.wikipedia.org/wiki/Current_reality_tree_%28theory_of_constraints%29&#34;&gt;CRT&lt;/a&gt; 這種方法，而不直接採用現成的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD&lt;/a&gt;？」&lt;/p&gt;
&lt;p&gt;我答不出來。頂多只是憑直覺喃喃自語：「或許是比較容易溝通吧！」&lt;/p&gt;
&lt;h3 id=&#34;其三&#34;&gt;其三&lt;/h3&gt;
&lt;p&gt;某一天，在《&lt;a href=&#34;https://www.amazon.cn/%E6%8A%89%E6%8B%A9-%E8%89%BE%E5%88%A9%C2%B7%E9%AB%98%E5%BE%B7%E6%8B%89%E7%89%B9/dp/B006006M6U&#34;&gt;抉擇&lt;/a&gt;》第 209 頁巧遇一張 CLD。果然高德拉特也懂 CLD，只是選擇不常用它。&lt;/p&gt;
&lt;p&gt;「或許是 CRT 比 CLD 容易溝通吧！」&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這類思緒，不時湧出，甚至開始浮現一些狂想：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;認真思考將 CLD 與 CRT &amp;amp; FRT 混用，或在某種程度上融合的可能性。&lt;/p&gt;
&lt;p&gt;&amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/857248865396826113&#34;&gt;2017-04-26 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;有難度的狂想。當時的我，還想不出具體的方法融合。&lt;/p&gt;
&lt;h2 id=&#34;突破&#34;&gt;突破&lt;/h2&gt;
&lt;p&gt;直到今年四月，在稲垣公夫《&lt;a href=&#34;http://www.books.com.tw/products/0010759729&#34;&gt;深思快想&lt;/a&gt;》這本奇書看到一線曙光：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/06/two-maps.jpg&#34; alt=&#34;《深思快想》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/06/two-maps.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《深思快想》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;不愧是限制理論暨豐田方法的專家，早我一步（好吧，早我好幾步）整合好 &lt;a href=&#34;https://en.wikipedia.org/wiki/Current_reality_tree_%28theory_of_constraints%29&#34;&gt;CRT&lt;/a&gt; + &lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD&lt;/a&gt; 了。&lt;/p&gt;
&lt;p&gt;站在巨人的肩膀上，我可以省點力氣了？&lt;/p&gt;
&lt;p&gt;沒這麼簡單。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;稲垣公夫語重心長提醒：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「思考的深度」與「專業性程度」互不相干。也就是說，有人使用極艱深的專業知識，卻用淺薄的方式思考；有人則深入思考身邊人盡皆知的常識。&lt;/p&gt;
&lt;p&gt;想鍛鍊深入思考的能力，與其只偶爾仔細思考困難的問題，不如養成經常對日常事務深思熟慮的習慣。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;勝間和代在《&lt;a href=&#34;http://www.books.com.tw/products/0010457479&#34;&gt;培養商業腦的七種組織力&lt;/a&gt;》也提醒過一樣的事：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不斷進行切入重點來養成思考方式，雖看似繞遠路，其實就是最快的捷徑。沒有辦法養成邏輯思考的人，單純的原因就在於質量的不足而已。可以的話，希望各位持續進行幾年的時間來培養這個習慣。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不照著鍛鍊，不會化成自己的血肉。&lt;/p&gt;
&lt;p&gt;既然兩位都這麼說，我就乖乖照著做吧！&lt;/p&gt;
&lt;h2 id=&#34;刻意練習&#34;&gt;刻意練習&lt;/h2&gt;
&lt;p&gt;我挑選兩個案例來刻意練習。一是不太熟悉的，以當期的科技島讀&lt;a href=&#34;https://daodu.tech/04-27-2018-ep-13-crane-machine-reveals-retail-future&#34;&gt;夾娃娃機&lt;/a&gt;文章為案例；一是非常熟悉的，以現在服務的公司當案例，總結這四年工作上看遍的成敗點滴，了卻一樁長年心願。&lt;/p&gt;
&lt;p&gt;兩個案例，仗著過往的 CRT 及 CLD 功底，個別繪出草圖並不難；但若進一步要求兩者的內在一致性，也費了好幾天功夫。&lt;/p&gt;
&lt;p&gt;很有成就感。&lt;/p&gt;
&lt;p&gt;既然都做到這地步，孤芳自賞太可惜了，索性拿這份商業模式分析圖找上我們家 CEO，用 CRT + CLD 連續技講了一遍，檢驗我的分析是否正確。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;之後，持續刻意練習 CRT + CLD，漸漸生出效果，更快就能勾勒出具有內在一致性的初版。&lt;/p&gt;
&lt;p&gt;以這種角度來閱讀文本，對文本的鑑賞標準在不知不覺中提高，也更能體會《&lt;a href=&#34;http://www.books.com.tw/products/0010762830&#34;&gt;一流的人讀書，都在哪裡畫線？&lt;/a&gt;》點出的訣竅：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/06/draw-a-line.jpg&#34; alt=&#34;《一流的人讀書，都在哪裡畫線？》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/06/draw-a-line.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《一流的人讀書，都在哪裡畫線？》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;用這種態度，何止是在書上畫線，連優質的網路分析文章也盡在狩獵範圍之內。&lt;/p&gt;
&lt;p&gt;譬如說，面對&lt;a href=&#34;https://www.inside.com.tw/article/13190-pchome-pk-shopee-2&#34;&gt;詹宏志的演講&lt;/a&gt;，不會讀的人，只會酸他太晚才知道所謂「資本的力量」；會讀的人，就會看到其中的系統基模，以及可引為己用之處。&lt;/p&gt;
&lt;p&gt;這才是深刻的閱讀層次。&lt;/p&gt;
&lt;h2 id=&#34;開講&#34;&gt;開講&lt;/h2&gt;
&lt;p&gt;今年二月，我在公司內部群組推薦好友 Taco 開的&lt;a href=&#34;https://www.accupass.com/event/1802130203009217521890&#34;&gt;系統思考工作坊&lt;/a&gt;，幾位好學的同事前來打探，令我竊喜：公司內總算有人對這主題感興趣了。&lt;/p&gt;
&lt;p&gt;這一天，我等了好久。&lt;/p&gt;
&lt;p&gt;也正是時候。正值自己在「系統思考」及「&lt;a href=&#34;//william-yeh.net/post/2018/04/board-game-creation/&#34;&gt;教學培訓&lt;/a&gt;」兩方面都有突破，便尋思：何不結合兩者，設計符合自己想法的教案，主動分享這方面的新體悟？&lt;/p&gt;
&lt;p&gt;就用系統思考的方法來教系統思考吧。&lt;/p&gt;
&lt;p&gt;算是一種 self-contained feedback loop？ (笑)&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;於是，在公司內自動請纓開辦【系統思考的四堂課】。一周一堂 90 分鐘，正好一個月結束。&lt;/p&gt;
&lt;p&gt;課程公告：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;正如我帶讀書會及工作坊的風格，會以個案研討形式為主，有大量課堂討論及回家作業。回家作業大概需要花一個小時。能配合的，再考慮參加。&lt;/p&gt;
&lt;p&gt;人數上限：12。&lt;/p&gt;
&lt;p&gt;Agenda:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;課前作業 - 中等收入陷阱&lt;/li&gt;
&lt;li&gt;Week 1 (5/31 四) - 系統思考簡介、因果分析&lt;/li&gt;
&lt;li&gt;Week 2 (6/07 四) - 系統動力學&lt;/li&gt;
&lt;li&gt;Week 3 (6/14 四) - 系統基模&lt;/li&gt;
&lt;li&gt;Week 4 (6/21 四) - 應用：Large-scale Scrum 或商業模式分析&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;場地所限，設下人數上限。結果，還是有人拜託超收。 (笑)&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/06/2018-05-31-sys-thinking-workshop.jpg&#34; alt=&#34;【系統思考的四堂課】第一梯次&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/06/2018-05-31-sys-thinking-workshop.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;【系統思考的四堂課】第一梯次&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;為了這四堂課，努力策劃主題內容，梳理系統思考的具體步驟。最花功夫的是案例。要切題，又要多元，更要有相當程度的表面複雜性，才能對比映襯出系統思考的簡潔與犀利。&lt;/p&gt;
&lt;p&gt;沒有單一書籍符合上述所有需求。所以，兩個月以來，重讀許多書籍，萃取精華。&lt;/p&gt;
&lt;p&gt;系統思考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010759729&#34;&gt;深思快想&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010784000&#34;&gt;第五項修練&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010747160&#34;&gt;系統思考&lt;/a&gt; (&lt;em&gt;Systems One&lt;/em&gt; 中譯本)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010702990&#34;&gt;系統思考&lt;/a&gt; (&lt;em&gt;Thinking in Systems: A Primer&lt;/em&gt; 中譯本)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010728251&#34;&gt;問題可以一次解決&lt;/a&gt;（舊版：問題不能拆開來看）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;思維模式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010643983&#34;&gt;窮查理的普通常識&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010457479&#34;&gt;培養商業腦的七種組織力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010721292&#34;&gt;左思右想&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010762830&#34;&gt;一流的人讀書，都在哪裡畫線？&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;成長心態：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010775968&#34;&gt;X計畫：打造人生黃金交叉線的轉機與關鍵&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010752714&#34;&gt;刻意練習&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;走過一輪，提煉出可適用於 CRT 及 CLD 兩種系統思考層次的大一統方法，並將六大步驟湊出頭字詞，命名為「&lt;strong&gt;&lt;!-- raw HTML omitted --&gt;SLR·CPI 法&lt;!-- raw HTML omitted --&gt;&lt;/strong&gt;」：SLR 是單眼相機，CPI 是消費者物價指數，夠好記吧！&lt;/p&gt;
&lt;p&gt;教第一堂課的感想是，活動設計上，要再補強 &lt;a href=&#34;http://www.dbrmfg.co.nz/Thinking%20Process%20Categories%20of%20Legitimate%20Reservation.htm&#34;&gt;CLR (categories of legitimate reservations)&lt;/a&gt; 的部分，或者，從社會科學的研究方法中取材相關內容。畢竟，「理則思考」是台灣高等教育上嚴重缺失的一環。&lt;/p&gt;
&lt;p&gt;教第二堂課的感想是：真的需要現場手繪，並搭配 &lt;a href=&#34;https://ncase.me/loopy/&#34;&gt;LOOPY&lt;/a&gt; 推導。&lt;/p&gt;
&lt;p&gt;教到第三堂課時，把之前課堂上分析過的種種大案例全部再拿出來對照，也順便類比到公司現況，讓大家現場立即體驗到彼得・聖吉說的「&lt;strong&gt;熟習系統基模，是組織開始將系統觀點應用於實務的第一步&lt;/strong&gt;」箇中深意。&lt;/p&gt;
&lt;p&gt;誰說《&lt;a href=&#34;http://www.books.com.tw/products/0010784000&#34;&gt;第五項修練&lt;/a&gt;》是沒有用的老書呢？&lt;/p&gt;
&lt;p&gt;教第四堂課時，火力全開，為【系統思考的四堂課】給了場算是高潮的完結，也鬆了一口氣。&lt;/p&gt;
&lt;h2 id=&#34;為人也為己&#34;&gt;為人，也為己&lt;/h2&gt;
&lt;p&gt;在公司內開這門課，長遠目標是推動並深化學習型組織，中期目標是為日後的 LeSS 鋪路，短期目標則是強化質性思考的能力。&lt;/p&gt;
&lt;p&gt;畢竟，從「中等收入陷阱」案例的系統思考分析中，兩種競爭力取向的動力昭然若揭。為了推動高端循環，質性思考是關鍵能力。質性路線比量化路線更抽象，更虛無飄渺，更難有適切的判準，常常都是淪為事後諸葛。所以，更需要在這方面刻意練習，及早提升這方面的素養。&lt;/p&gt;
&lt;p&gt;為別人，也為了自己。&lt;/p&gt;
&lt;p&gt;某方面來說，我現在對別人做的許多事，部分是為了 &lt;em&gt;N&lt;/em&gt; 年前沒能從（缺席的）mentor 那邊得到的我而做的。&lt;/p&gt;
&lt;p&gt;某種角度來說，也算是一種與內在小孩的對話。&lt;/p&gt;
&lt;p&gt;譬如說，我真想給當年的自己，看這段窮查理的話：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/06/thinking-model.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/06/thinking-model.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;並且帶著他逐步分析出這樣的 CLD：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/06/thinking-model-cld.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/06/thinking-model-cld.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;有這樣的 mentor，今天的我，又會是怎麼樣的一個人呢？&lt;/p&gt;
&lt;p&gt;沒有這樣的 mentor，就只能靠自己了。&lt;/p&gt;
&lt;p&gt;文末，一點小雜感。人生如夢，一尊還酹江月。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;     &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系統思考工作坊 - 系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 【系統思考的四堂課】緣起&lt;/p&gt;
&lt;p&gt;❷ 第一場公開班課後回覆：&lt;a href=&#34;//william-yeh.net/post/2018/09/thinking-weight-training/&#34;&gt;思維的重量訓練&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2021/03/sys-thinking-unicorn-project/&#34;&gt;從系統思考角度讀《獨角獸專案》&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;➍ &lt;a href=&#34;//william-yeh.net/post/2024/07/dissecting-devops-via-systems-thinking/&#34;&gt;從系統思考角度談 DevOps 三步工作法&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>三週生出一款新桌遊，一段奇幻旅程</title>
      <link>//william-yeh.net/post/2018/04/board-game-creation/</link>
      <pubDate>Thu, 26 Apr 2018 11:36:45 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/04/board-game-creation/</guid>
      
        <description>&lt;p&gt;這款新桌遊，從四週前動念，歷經一次小實驗，一次高裝檢，到前天第一次對外正式啟用，現在總算可以慢慢寫它的誕生歷程了。&lt;/p&gt;
&lt;h2 id=&#34;對模擬遊戲的四大疑惑&#34;&gt;對模擬遊戲的四大疑惑&lt;/h2&gt;
&lt;p&gt;學生時代從《&lt;a href=&#34;https://www.books.com.tw/products/0010832070&#34;&gt;第五項修練&lt;/a&gt;》讀到&lt;a href=&#34;https://en.wikipedia.org/wiki/Beer_distribution_game&#34;&gt;啤酒遊戲 (Beer Game)&lt;/a&gt;，就對規則簡單但意義深遠的模擬遊戲，心嚮往之。&lt;/p&gt;
&lt;p&gt;但直到近幾年，才真正有機會親炙它們。&lt;/p&gt;
&lt;p&gt;我在【&lt;a href=&#34;http://www.toc-cga.org/learning_activity_one_tc.aspx?laid=20160616104116&#34;&gt;TOC企業變革之路・體驗工作坊&lt;/a&gt;】玩了啤酒遊戲、在 &lt;a href=&#34;https://www.accupass.com/event/1608300930162091222458&#34;&gt;Agile Tour Hsinchu 2016&lt;/a&gt; 玩了 &lt;a href=&#34;https://agilebistro.com/getkanban/&#34;&gt;getKanban&lt;/a&gt;、在 &lt;a href=&#34;//william-yeh.net/post/2017/03/cspo/&#34;&gt;CSPO 課堂&lt;/a&gt;玩了 &lt;a href=&#34;https://www.agilebelgium.be/businessvaluegame/&#34;&gt;Business Value Game&lt;/a&gt;，儘管各有收穫，但心中卻也一直有個疑惑：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;啤酒遊戲、getKanban、Business Value Game，為了教育意義，好像牌卡順序都是事先設計好的？&lt;/p&gt;
&lt;p&gt;      &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/928959597079011328&#34;&gt;2017-11-10 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;刻意安排事件卡的出現順序或參數，比較容易控制某些障礙一定會在某些時刻被觸發，遊戲設計者想推銷的某些破關密技也一定會管用——畢竟，全部都是事先計算好的。動機良善。只不過，這也會削弱教育意義的&lt;strong&gt;效度&lt;/strong&gt;：這遊戲想傳達的理念或破關密技，會不會只適用在像這種刻意安排好的事件排列組合及參數設定上？&lt;/p&gt;
&lt;p&gt;真實的人生，不會只有這麼一套巧合的劇本。&lt;/p&gt;
&lt;p&gt;第二個疑惑是，這類模擬遊戲，雖然已針對現實做簡化，但仍然非常緊貼該課題所處的領域。動機良善。只不過，這也會削弱跨領域應用的&lt;strong&gt;彈性&lt;/strong&gt;。譬如說，非軟體研發領域的人，若無視 getKanban 或 Business Value Game 卡牌上一堆軟體研發流程、角色、狀況、參數，甚至短空長多的瓶頸升級招數，也能在遊戲中領悟箇中深意嗎？&lt;/p&gt;
&lt;p&gt;尤其是我的【敏捷原理與團隊塑造】招牌課程，最初是設定給 IT 領域，但後來漸漸有非 IT 領域的企業內訓需求，甚至非營利組織也來邀約，我必須認真處理這問題，尋找或設計更合適的模擬活動。&lt;/p&gt;
&lt;p&gt;第三個疑惑是，這類模擬遊戲，雖然已針對現實做簡化，但規則仍然複雜，不管是遊戲規則還是計分板規則。&lt;/p&gt;
&lt;p&gt;像啤酒遊戲，主體規則非常簡單，但遊戲過程須紀錄編製的統計圖表可就令人咋舌：遊戲記錄表、庫存／缺貨圖表、需求預測圖表、出貨記錄表、訂貨記錄表、長鞭效應分析圖。鑑於計分板規則也是遊戲體驗過程的一部分，甚至是最容易出錯的一環，綜合來說，我不認為啤酒遊戲是簡單的。就算搬到電腦上玩，我也不認為啤酒遊戲是簡單的。&lt;/p&gt;
&lt;p&gt;至於其他遊戲，有的是牌面資訊複雜，有的是流程複雜，有的是角色分工複雜，都需要詳讀使用說明書。&lt;/p&gt;
&lt;p&gt;規則複雜，連帶產生第四個疑惑是，這類遊戲，有可能 plug and play 融入一個小時的教學單元之中嗎？這算是個人主觀的偏好，希望盡量將活動模組化，比較容易單獨施行，或視情況需要，與其他不同的活動模組混搭編排。&lt;/p&gt;
&lt;p&gt;因此，後來陸續問世的 &lt;a href=&#34;https://www.benihi.com/en/products/uxinthejungle&#34;&gt;UX in the Jungle&lt;/a&gt; 或&lt;a href=&#34;https://lab.howie.tw/2017/09/the-phoenix-project-workshop.html&#34;&gt;鳳凰項目沙盤推演&lt;/a&gt;，顯然是定位在更大規模的商業模擬，顯然沒有同時處理這四大疑點，我就沒有親自去體驗了。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我一直在尋找，甚至想設計出符合以下特性的模擬活動：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;簡單的規則。&lt;/li&gt;
&lt;li&gt;抽象化場景。&lt;/li&gt;
&lt;li&gt;隨機事件。&lt;/li&gt;
&lt;li&gt;多重策略，多重結局。&lt;/li&gt;
&lt;li&gt;可在一個小時內，搞定規則解說、試玩、正式玩、檢討的基本款循環。&lt;/li&gt;
&lt;li&gt;只要調整設定，即可擴充至更長的體驗時間。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這想法，一直埋藏在心中。直到有一天⋯⋯&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/04/tweet-20180324.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/04/tweet-20180324.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

  &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/977565728248184832&#34;&gt;2018-03-24 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;解套的契機，就是參加了【&lt;a href=&#34;https://jackyliu.net/experience-gamification-class-design-training-course/&#34;&gt;體驗式課程的遊戲設計與操作實務&lt;/a&gt;】三天課程，而且是在第一天就出現了靈感。&lt;/p&gt;
&lt;h2 id=&#34;三大明師現身說法&#34;&gt;三大明師現身說法&lt;/h2&gt;
&lt;p&gt;這門匯集三大明師運課精華的合體課程，早在 2017 年首發課程消息一出，我就躍躍欲試。畢竟，我上過一堆 Bryan &amp;amp; Joe 的課，深知這種課程設計的魅力及成效；我也從&lt;a href=&#34;https://jackyliu.net/&#34;&gt;功夫老師（劉恭甫）&lt;/a&gt;的書，尤其是《&lt;a href=&#34;https://www.books.com.tw/products/0010721292&#34;&gt;左思右想&lt;/a&gt;》這本神作，學到許多實用的思考框架。三大明師黃金組合，再加上一堆神級人物搶著當首發課的學員（請見【一談就贏・鄭志豪】的這篇&lt;a href=&#34;https://negotowin.blogspot.tw/2017/04/blog-post_9.html&#34;&gt;文章&lt;/a&gt;），著實令人心動。&lt;/p&gt;
&lt;p&gt;只可惜首發的 TTT 課程，與另一個我也很想上的&lt;a href=&#34;//william-yeh.net/post/2017/04/satir-workshop/&#34;&gt;薩提爾課程&lt;/a&gt;衝堂，只好暫緩。&lt;/p&gt;
&lt;p&gt;就這樣過了一年。終於排除萬難，上這堂今年對我來說最重要的三天課程了。&lt;/p&gt;
&lt;p&gt;果然滿是第一線明師替課程注入靈魂的乾貨。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/04/gamification-ttt.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/04/gamification-ttt.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;頭兩天課程，老師現身說法，演示並拆解數種體驗式課程的訣竅：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;團康&lt;/li&gt;
&lt;li&gt;一頁紙&lt;/li&gt;
&lt;li&gt;架構地圖&lt;/li&gt;
&lt;li&gt;模擬活動&lt;/li&gt;
&lt;li&gt;卡牌活動&lt;/li&gt;
&lt;li&gt;桌遊&lt;/li&gt;
&lt;li&gt;角色扮演&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些形式，我都曾在課程或會議引導場合嘗試帶領過，但全都是自學：從書本學方法、從明師運課過程逆向工程些許訣竅、從自己的土炮經驗中反思調整而來，自認不到位之處仍多。這次，有系統的重新學習體驗式課程的理論及訣竅，見識第一流明師的頂級風格——原來，體驗式課程可以執行得如此細緻！&lt;/p&gt;
&lt;p&gt;我也常在課堂上立即刺激出更多想法。&lt;/p&gt;
&lt;p&gt;譬如說，某個我極具把握，也在公司內及公司外真槍實彈執行過四次的一小時活動【積木拼圖】，原本以為已經夠好了。沒想到經過這兩天洗禮，還能刺激我想出更有趣的調味料。翌日，在公司現學現賣印證所學，果真有加分效果！更讓緊接著要處理非常敏感且尖銳的 retrospective meeting，超出預期的成功。&lt;/p&gt;
&lt;p&gt;取法乎上，果然有必要。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;課堂上，老師大方演示並無私拆解各自拿手的招牌課程單元，對於上過許多課的我來說，不時有意外的驚喜。&lt;/p&gt;
&lt;p&gt;譬如說，睽違兩年，再玩一次&lt;a href=&#34;//william-yeh.net/post/2016/04/learn-process-mgmt-by-game/&#34;&gt;小火車&lt;/a&gt;，依然有感。再聽 Joe 拆解幕後的機制，更是徹底體會「障礙」與「斷點」的奧秘。&lt;/p&gt;
&lt;p&gt;譬如說，在某個角色扮演案例中飾演觀察員，很慶幸發現自己半年前的&lt;a href=&#34;//william-yeh.net/post/2017/10/experiencing-negotiation/&#34;&gt;談判課&lt;/a&gt;沒有白學，很快就察覺雙方卡關之處。也算是意外的成果檢驗吧。&lt;/p&gt;
&lt;h2 id=&#34;三週生出一款新桌遊&#34;&gt;三週生出一款新桌遊&lt;/h2&gt;
&lt;p&gt;這門課，頭兩天是老師們的現身說法。兩三週之後，同學們會再回來齊聚一堂，活用兩日所學，逐一端出自己設計的課程，讓老師及其他同學體驗與點評。&lt;/p&gt;
&lt;p&gt;就如同【一談就贏・鄭志豪】的這篇&lt;a href=&#34;https://negotowin.blogspot.tw/2017/04/blog-post_9.html&#34;&gt;文章&lt;/a&gt;所說，如果拿自己既有的教案交差，那就太犯規了。我們真的在這期間，絞盡腦汁研發出全新的單元。樸拙在所難免，但交由專家點評，才是讓自己更快速進步的捷徑。若只端出已經錘鍊過的東西，就喪失從明師身上挖寶的尚好機會。&lt;/p&gt;
&lt;p&gt;對我來說，儘管課程第一天就開始有一些零零星星的靈感浮現，但仍歷經一整個禮拜的發散探索，才慢慢收斂出幾個較可行的方案。譬如說，從以下這份用 TTSS 角度發想的一部分概念草圖，可約略看出設計探索的軌跡：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/04/game-draft.jpg&#34; alt=&#34;桌遊草圖&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/04/game-draft.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;桌遊草圖&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;繼續細部設計約一個禮拜，邀請七位熱心同事幫忙試玩。當時來不及做投影片，只能先手繪分鏡圖來解釋故事及規則（這也算是一種 minimum viable product 吧）：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/04/game-rule.jpg&#34; alt=&#34;桌遊規則&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/04/game-rule.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;桌遊規則&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;公司同事太強大了。桌遊試車一小時，馬上對困擾我很久的機率設計，給出很實質的改善建議。也激發我新的靈感，可將此桌遊規則微調，彈性擴充成 1 小時，甚至 1.5 小時的版本。&lt;/p&gt;
&lt;p&gt;經此實驗，主軸確定了，便放心在成果總驗收日端出來請各位老師同學點評。非常感謝大家現場給予的回饋，從主題設定、規則、學習成效，甚至控場細節，都讓我收穫滿滿。&lt;/p&gt;
&lt;p&gt;同時，還親身體驗到其他同學端出的寶貝：人際溝通、簡體字教學、物流機制、正向思考、物理治療、牙齒修磨、乳房腫瘤治療、馬蓋先、急診室體驗，這一天，簡直是夢幻的滿漢全席！眼界大開，學到許多日後可參酌運用的手法。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/04/fb-post-jacky.jpg&#34; alt=&#34;Comment from Jacky Liu&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/04/fb-post-jacky.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Comment from Jacky Liu&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;很幸運的，我的這款【先遣小姑嘗】桌遊，得到了【&lt;a href=&#34;https://jackyliu.net/experience-gamification-class-design-training-course/&#34;&gt;體驗式課程的遊戲設計與操作實務&lt;/a&gt;】第四梯次的「最佳教育設計獎」：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/04/best-board-award.jpg&#34; alt=&#34;最佳教育設計獎&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/04/best-board-award.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;最佳教育設計獎&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這些經驗及修正意見，讓我稍後在某營造業龍頭進行【敏捷原理與團隊塑造】企業內訓時，效果超出預期。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/04/agile-workshop-pic.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/04/agile-workshop-pic.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這段旅程，很刺激，很燒腦，也讓我對於「&lt;a href=&#34;https://www.facebook.com/photo.php?fbid=1479401428739571&#34;&gt;一線老師有各自不同注入靈魂的做法&lt;/a&gt;」這件事，不再感到虛無飄渺。&lt;/p&gt;
&lt;p&gt;感謝 Bryan、Joe、功夫老師及同梯學伴，共度這奇幻旅程。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>以 impact mapping 進行參與式決策</title>
      <link>//william-yeh.net/post/2018/02/impact-mapping-as-participatory-decision-making/</link>
      <pubDate>Fri, 23 Feb 2018 10:54:14 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/02/impact-mapping-as-participatory-decision-making/</guid>
      
        <description>&lt;p&gt;我在半年前〈&lt;a href=&#34;//william-yeh.net/post/2017/07/sprint-planning-as-negotiation/&#34;&gt;以談判角度看 Sprint Planning&lt;/a&gt;〉一文曾提過：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;只要是我有權主導的 Sprint Planning，都會先花些時間請 PO 重新展開 &lt;a href=&#34;https://www.impactmapping.org/&#34;&gt;Impact Mapping&lt;/a&gt; 及 &lt;a href=&#34;https://www.taaze.tw/products/11100816208.html&#34;&gt;&lt;em&gt;Scaling Lean&lt;/em&gt;&lt;/a&gt; 的內容，尤其是還沒有穩定扎實 Product Backlog Refinement 的團隊。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;欲達我心目中的理想境界，需要先讓團隊成員練習一兩次 impact mapping，才能在正式上戰場時，更有效產出高品質的 impact map。&lt;/p&gt;
&lt;p&gt;就連 PO 本身也需要練習。尤其是沒有「參與式決策」習慣的 PO，對於這類方法，常以自身專業角度提出質疑：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/02/tweet-20180115.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/02/tweet-20180115.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

  &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/952916827864121345&#34;&gt;2018-01-15 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;畢竟，就如《&lt;a href=&#34;https://www.books.com.tw/products/0010768288&#34;&gt;精實創業&lt;/a&gt;》提醒的，傳統 PO 或 PdM 養成過程中，並不會特別被鼓勵用這種方法做事：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這項改革與人們一直以來在企業中被灌輸的認知，或企業領導人一直以來所學的知識是相違背的。&lt;/p&gt;
&lt;p&gt;真正的問題在於企業領導人及中層管理幹部。有許多企業領導人當年成功，是因為他們擅於分析，他們自認是分析家，應當為公司做企劃分析、為公司的未來訂定計畫。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因此，對於這類型的 PO，需要在平日就善於伺機提問，甚至需要以更高的標準去要求，才能讓他們看到 impact map 的價值，甚至「參與式決策」過程的必要性。畢竟，少了「參與式決策」的助力，敏捷之旅會更崎嶇。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;

&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/02/tweet-20180206.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/02/tweet-20180206.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

  &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/960832625765056512&#34;&gt;2018-02-06 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;培訓&#34;&gt;培訓&lt;/h2&gt;
&lt;p&gt;2018 年初，終於等到時機成熟，有機會對某團隊大膽試行，朝向我心目中理想境界前進一步。&lt;/p&gt;
&lt;p&gt;首先，是培訓。&lt;/p&gt;
&lt;p&gt;我先利用三次機會（包括&lt;a href=&#34;https://www.facebook.com/agilecafetw/photos/a.257860514746546.1073741828.253766155155982/280899942442603/?type=3&#34;&gt;【敏捷原理與團隊塑造】第二梯次&lt;/a&gt;），小規模試行各 1.5 小時的「Impact Mapping + MVP 迷你工作坊」。&lt;/p&gt;
&lt;p&gt;我也趁這三次的施教機會，實驗一些個案研討手法及引導句型。&lt;/p&gt;
&lt;p&gt;以前在非正式引介 impact mapping 的過程中，我發現許多人對 “impact” 這一層最不容易掌握訣竅。雖然 impact mapping 有原版的建議句型 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; ，但我覺得操作起來還不太足夠。因此，我嘗試納入周碩倫老師在【&lt;a href=&#34;https://www.accupass.com/event/1712070820421025016543&#34;&gt;創新的用途理論導讀會&lt;/a&gt;】介紹的&lt;strong&gt;用途&lt;/strong&gt;及&lt;strong&gt;需求&lt;/strong&gt;觀點，讓 “impact” 這一層更容易引導出來。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/02/jtod-20180119.jpg&#34; alt=&#34;創新的用途理論導讀會 by 周碩倫&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/02/jtod-20180119.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;創新的用途理論導讀會 by 周碩倫&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;lean-canvas&#34;&gt;Lean Canvas&lt;/h2&gt;
&lt;p&gt;在帶整個團隊玩真槍實彈的 impact mapping 會議之前，我通常會請 PO 先私下繳交一份 impact mapping 作業給我看——這應該算是 PO 的基本功。&lt;/p&gt;
&lt;p&gt;原本是要這樣的。不過，對 PO，應該要有更高標準的要求吧！甫經一天 &lt;a href=&#34;https://www.accupass.com/event/1801300331034013938600&#34;&gt;Lean Startup&lt;/a&gt; 課堂洗禮的我，突然萌生一個瘋狂的念頭：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;

&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/02/tweet-20180214.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/02/tweet-20180214.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

  &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/963571298260598784&#34;&gt;2018-02-14 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;畢竟，先認真做好 lean canvas，就有一個堅實的基礎再往下展開成 impact map：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lean canvas 的 revenue streams 及 key metrics，約略對應到 impact map 的 goal (WHY)。&lt;/li&gt;
&lt;li&gt;Lean canvas 的 customer segments，可對應到 impact map 的 actor (WHO)。&lt;/li&gt;
&lt;li&gt;Lean canvas 的 unique value proposition，約略對應到 impact map 的 impact (HOW)。&lt;/li&gt;
&lt;li&gt;Lean canvas 的 solution，約略對應到 impact map 的 deliverable (WHAT)。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我請 PO 暫時先不必管 lean canvas 的 channels 及 cost structure 欄位，至於其他七個欄位，都建議 PO 先獨自整理到某個程度，比較有助於當場對團隊產出的 impact mapping 進行有建設性的補充。&lt;/p&gt;
&lt;p&gt;於是，這位可憐的 PO，春節假期一直在做我給的 lean canvas 作業⋯⋯ 🤣&lt;/p&gt;
&lt;h2 id=&#34;impact-mapping-議程設計&#34;&gt;Impact Mapping 議程設計&lt;/h2&gt;
&lt;p&gt;團隊培訓完了，PO 也獨自做完 lean canvas 了，接下來就是真槍實彈的 impact mapping 會議。&lt;/p&gt;
&lt;p&gt;我沒有完全照著 &lt;a href=&#34;https://www.impactmapping.org/book.html&#34;&gt;&lt;em&gt;Impact Mapping&lt;/em&gt;&lt;/a&gt; 書中建議的程序，而是根據 &lt;a href=&#34;https://williampjyeh.notion.site/bab7091e6f5c42d59797fdb1bfd5422f&#34;&gt;&lt;em&gt;Facilitator&amp;rsquo;s Guide to Participatory Decision-Making&lt;/em&gt;&lt;/a&gt; 書中提到的鑽石模型 (diamond model) 及串組式流程設計 (string)，再穿插 &lt;em&gt;&lt;a href=&#34;https://www.kingstone.com.tw/book/book_page.asp?kmcode=2014713451712&#34;&gt;Gamestorming&lt;/a&gt;&lt;/em&gt; 書中介紹的一些小技巧（像 &lt;a href=&#34;http://gamestorming.com/brainwriting/&#34;&gt;brainwriting&lt;/a&gt; 的小變形），讓整個活動有層次，有節奏，且讓每個人的想法都有機會呈現與碰撞。&lt;/p&gt;
&lt;p&gt;注重「參與式決策」的過程，也注重產出的結果。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;理想上，這樣的活動，我認為要三個小時，甚至四個小時，才會達到高品質的 WHAT 層次。如果只有兩小時，可能只能做到中等品質的 HOW 層次。不過，一連進行四小時（即使是分成上午及下午各半場），對引導者本人來說是小事，但其他人的專注力可能通不過這樣的考驗。&lt;/p&gt;
&lt;p&gt;下次再帶這樣的活動，我應該會設計成 Part 1 (Goal → WHO → HOW) 及 Part 2 (HOW → WHAT → iterative 總結) ，分兩天進行。也會多穿插些提示引導問句及迷你思考框架，以更有效率校準水平。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2018/01/precise-expression/&#34;&gt;咬文嚼字的必要性（一）：用句型輔助思考&lt;/a&gt;〉文中曾提過 impact mapping 有一個原版的建議句型。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>咬文嚼字的必要性（一）：用句型輔助思考</title>
      <link>//william-yeh.net/post/2018/01/precise-expression/</link>
      <pubDate>Thu, 04 Jan 2018 14:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2018/01/precise-expression/</guid>
      
        <description>&lt;p&gt;前同事 Peter Su 提出他在荷蘭工作的&lt;a href=&#34;https://www.facebook.com/suppi.su.1/posts/1804748106224850&#34;&gt;觀察&lt;/a&gt;：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/01/petersu-on-fx.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/01/petersu-on-fx.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;貼文短短，卻已提到幾則重點：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;準則&lt;/li&gt;
&lt;li&gt;思考框架&lt;/li&gt;
&lt;li&gt;句型&lt;/li&gt;
&lt;li&gt;參考範例&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;儘管自己還沒有在國外工作過，但成天浸潤在外文書籍，也感同身受。&lt;/p&gt;
&lt;p&gt;關於「思考框架」這一點，我在〈&lt;a href=&#34;//william-yeh.net/post/2017/09/thinking-framework-practice/&#34;&gt;思考框架的刻意練習&lt;/a&gt;〉一文提過自己的看法。現在這篇文章，我想繼續談談「句型」這一點。&lt;/p&gt;
&lt;h2 id=&#34;用句型輔助思考&#34;&gt;用句型輔助思考&lt;/h2&gt;
&lt;p&gt;歐美系的思考框架或準則，很喜歡用「句型」式的步驟來引導思考。&lt;/p&gt;
&lt;p&gt;譬如說，在軟體研發領域常用的 &lt;a href=&#34;https://www.mountaingoatsoftware.com/agile/user-stories&#34;&gt;user story&lt;/a&gt;，本身就有一個經典句型：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;As a&lt;/strong&gt; &amp;lt;&lt;em&gt;type of user&lt;/em&gt;&amp;gt;, &lt;strong&gt;I want&lt;/strong&gt; &amp;lt;&lt;em&gt;some goal&lt;/em&gt;&amp;gt; &lt;strong&gt;so that&lt;/strong&gt; &amp;lt;&lt;em&gt;some reason&lt;/em&gt;&amp;gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;另一個似乎開始引人注目的 &lt;a href=&#34;https://jtbd.info/&#34;&gt;JTBD (jobs to be done)&lt;/a&gt; 也有一個經典的 job story 句型：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;When&lt;/strong&gt; &amp;lt;&lt;em&gt;situation&lt;/em&gt;&amp;gt;, &lt;strong&gt;I want&lt;/strong&gt; &amp;lt;&lt;em&gt;motivation&lt;/em&gt;&amp;gt; &lt;strong&gt;so I can&lt;/strong&gt; &amp;lt;&lt;em&gt;expected outcome&lt;/em&gt;&amp;gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在 &lt;em&gt;&lt;a href=&#34;https://www.impactmapping.org/book.html&#34;&gt;Impact Mapping&lt;/a&gt;&lt;/em&gt; 書中，Gojko Adzic 建議使用以下句型來開展 actor 及 behavior impact 的關係：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;lt;&lt;em&gt;The actor&lt;/em&gt;&amp;gt; &lt;strong&gt;can help us to achieve&lt;/strong&gt; &amp;lt;&lt;em&gt;some goal&lt;/em&gt;&amp;gt; &lt;strong&gt;by&lt;/strong&gt; &amp;lt;&lt;em&gt;behave&lt;/em&gt;&amp;gt; &lt;strong&gt;faster/better&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;&lt;em&gt;The actor&lt;/em&gt;&amp;gt; &lt;strong&gt;can obstruct us from achieving&lt;/strong&gt; &amp;lt;&lt;em&gt;some goal&lt;/em&gt;&amp;gt; &lt;strong&gt;by&lt;/strong&gt; &amp;lt;&lt;em&gt;behave&lt;/em&gt;&amp;gt; &lt;strong&gt;slower/worse&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在 &lt;em&gt;&lt;a href=&#34;http://www.books.com.tw/products/0010644283&#34;&gt;Specification by Example&lt;/a&gt;&lt;/em&gt; 書中，Gojko Adzic 建議使用以下 &lt;a href=&#34;https://github.com/cucumber/cucumber/wiki/Gherkin&#34;&gt;Gherkin&lt;/a&gt; 句型來制定實例化需求：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Given&lt;/strong&gt; &amp;lt;&lt;em&gt;a precondition&lt;/em&gt;&amp;gt; &lt;strong&gt;when&lt;/strong&gt; &amp;lt;&lt;em&gt;an action happens&lt;/em&gt;&amp;gt; &lt;strong&gt;then&lt;/strong&gt; &amp;lt;&lt;em&gt;the following post-conditions should be satisfied&lt;/em&gt;&amp;gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在&lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;限制理論&lt;/a&gt;的&lt;a href=&#34;https://en.wikipedia.org/wiki/Evaporating_Cloud&#34;&gt;衝突圖（疑雲圖）&lt;/a&gt;中，針對 B→A、C→A、D→B、D′→C 四個邏輯關聯及假設，Jelena Fedurko 提出一些邏輯檢驗句型，甚至還主張要「大聲唸出來」呢：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In order to&lt;/strong&gt; &amp;lt;&lt;em&gt;left clause&lt;/em&gt;&amp;gt; &lt;strong&gt;we must&lt;/strong&gt; &amp;lt;&lt;em&gt;right clause&lt;/em&gt;&amp;gt; &lt;strong&gt;because&lt;/strong&gt; &amp;lt;&lt;em&gt;assumption&lt;/em&gt;&amp;gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;前面示範的都是短句，但句型也可能很長。像大師 Geoffrey Moore 就提過很長的 value proposition 句型：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;For&lt;/strong&gt; &amp;lt;&lt;em&gt;bulls-eye customer&lt;/em&gt;&amp;gt; &lt;strong&gt;who&lt;/strong&gt; &amp;lt;&lt;em&gt;key purchase motivation insight&lt;/em&gt;&amp;gt; &lt;strong&gt;our product is a&lt;/strong&gt; &amp;lt;&lt;em&gt;in customer language&lt;/em&gt;&amp;gt; &lt;strong&gt;that&lt;/strong&gt; &amp;lt;&lt;em&gt;key benefit&lt;/em&gt;&amp;gt;.
&lt;strong&gt;Unlike&lt;/strong&gt; &amp;lt;&lt;em&gt;key competitors&lt;/em&gt;&amp;gt; &lt;strong&gt;ours&lt;/strong&gt; &amp;lt;&lt;em&gt;key differentiators&lt;/em&gt;&amp;gt; &lt;strong&gt;at a price&lt;/strong&gt; &amp;lt;&lt;em&gt;than competitors&lt;/em&gt;&amp;gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;句型，讓初學者容易依循上手，但蜜月期總有結束之日。若只追求表面句型的合式，而不進一步認真雕琢句子內容，輕則無法發揮此思考框架的威力，重則誤用。&lt;/p&gt;
&lt;p&gt;因此，有志之士，對於這些句型背後的填空之處，尤其是命名，會吹毛求疵到咬文嚼字的地步。&lt;/p&gt;
&lt;p&gt;不明就裡的人會納悶：「真的有必要這樣嗎？」&lt;/p&gt;
&lt;p&gt;來看幾個例子吧。&lt;/p&gt;
&lt;h2 id=&#34;團隊共創法&#34;&gt;團隊共創法&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://kojenchieh.pixnet.net/blog/post/442862228-%E5%88%A9%E7%94%A8%E5%9C%98%E9%9A%8A%E5%85%B1%E5%89%B5%E6%B3%95%E4%BE%86%E9%81%94%E6%88%90%E5%85%B1%E8%AD%98&#34;&gt;團隊共創法&lt;/a&gt; (consensus workshop method) 當中，第四步驟是命名。&lt;/p&gt;
&lt;p&gt;命名，也是有箇中眉角的。&lt;/p&gt;
&lt;p&gt;Yves 在〈&lt;a href=&#34;https://funevo.com/2016/09/25/%E8%AE%8A%E6%95%8F%E6%8D%B7%E7%9A%84%E9%98%BB%E7%A4%99-%E5%9C%98%E9%9A%8A%E5%85%B1%E5%89%B5%E6%B3%95%E5%AF%A6%E5%81%9A/&#34;&gt;找出組織無法變敏捷的阻礙 – 團隊共創法實做&lt;/a&gt;〉一文提到「&lt;strong&gt;移除『缺乏』，讓命名更貼近核心&lt;/strong&gt;」的訣竅：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在 ICA 的課程中學到，如果阻礙是含有『缺乏』的字眼，如不夠、太少等，代表這只是表象或症狀，需要花些時間去挖掘更深層的造成原因。所以我嘗試以我的觀點再往深入去發掘，讓字面上沒有『缺乏』的字眼。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你覺得，這是吹毛求疵咬文嚼字嗎？&lt;/p&gt;
&lt;h2 id=&#34;專案管理&#34;&gt;專案管理&lt;/h2&gt;
&lt;p&gt;在專案管理領域，WBS 及 activity（或稱 task）兩者，很常被人混為一談。&lt;/p&gt;
&lt;p&gt;以 PMI 的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Project_Management_Body_of_Knowledge&#34;&gt;PMBOK&lt;/a&gt; 體系而言，WBS 是屬於 scope management 知識領域，activity 則是屬於 schedule management 知識領域。一靜，一動。&lt;/p&gt;
&lt;p&gt;本質不同，表述形式自然不應相同。&lt;/p&gt;
&lt;p&gt;關於 WBS，在 &lt;em&gt;PMBOK Guide&lt;/em&gt; 4th 如是說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Work Breakdown Structure (WBS)&lt;/strong&gt; [Output/Input]. A deliverable-oriented hierarchical decomposition of the work to be executed by the project team to accomplish the project objectives and create the required deliverables. It organizes and defines the total scope of the project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;雖然到了 &lt;em&gt;PMBOK Guide&lt;/em&gt; 5th 及 6th，此定義都略作調整，刪掉 &amp;ldquo;deliverable-oriented&amp;rdquo; 字眼：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Work Breakdown Structure (WBS).&lt;/strong&gt; A hierarchical decomposition of the total scope of work to be carried out by the project team to accomplish the project objectives and create the required deliverables.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但大體上，WBS 的表述形式，仍是以「名詞」或「名詞片語」為主。&lt;/p&gt;
&lt;p&gt;至於 activity，在 &lt;em&gt;PMBOK Guide&lt;/em&gt; 6th 如是說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Define Activities is the process of identifying and documenting the specific actions to be performed to produce the project deliverables. [&amp;hellip;] Activities represent the effort needed to complete a work package. The Define Activities process defines the final outputs as activities rather than deliverables, as done in the Create WBS process.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很明顯的，activity 的表述形式，是以「動詞字句」為主。&lt;/p&gt;
&lt;h2 id=&#34;實例化需求&#34;&gt;實例化需求&lt;/h2&gt;
&lt;p&gt;實例化需求 (&lt;a href=&#34;https://en.wikipedia.org/wiki/Specification_by_example&#34;&gt;specification by example&lt;/a&gt;; SBE) 也是個易學難精的技藝。所幸新書 &lt;em&gt;&lt;a href=&#34;https://www.amazon.com/dp/1617294101/ref=cm_sw_r_tw_dp_U_x_eYXtAbG1TVHSA&#34;&gt;Writing Great Specifications: Using Specification by Example and Gherkin&lt;/a&gt;&lt;/em&gt; 適時出現，站在巨人的肩膀上，擔起 “Gherkin Manual of Style” 的責任。&lt;/p&gt;
&lt;p&gt;先摘錄整體風格的建議：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don’t write scenarios about the UI. Write about business outcomes. Nobody cares about the UI; they care if they can get their job done.&lt;/li&gt;
&lt;li&gt;Keep your scenarios at an abstraction level that allows you to aim for as few &lt;strong&gt;Given&lt;/strong&gt;s, &lt;strong&gt;When&lt;/strong&gt;s, and &lt;strong&gt;Then&lt;/strong&gt;s as possible without sacrificing readability.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;再摘錄針對「Given/When/Then」的個別建議。某些建議，甚至咬文嚼字到「語態」及「時態」等文法層次：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don’t phrase &lt;strong&gt;Given&lt;/strong&gt;s as actions. Use passive voice in past tense, or phrase each &lt;strong&gt;Given&lt;/strong&gt; as a list of things that need to happen before the actors can move the action forward.&lt;/li&gt;
&lt;li&gt;Aim for one &lt;strong&gt;When&lt;/strong&gt; keyword per scenario.&lt;/li&gt;
&lt;li&gt;User tasks take place in the present and should be phrased in active voice to differentiate them from contexts and outcomes.&lt;/li&gt;
&lt;li&gt;User tasks should allow actors to proceed to &lt;strong&gt;Then&lt;/strong&gt;s. If a &lt;strong&gt;When&lt;/strong&gt; needs additional clarification, it’s merely a user action.&lt;/li&gt;
&lt;li&gt;To facilitate outside-in development, use the following template to phrase most of your &lt;strong&gt;Then&lt;/strong&gt;s: &lt;em&gt;&lt;!-- raw HTML omitted --&gt;&lt;/em&gt; &lt;strong&gt;should be able to&lt;/strong&gt; &lt;em&gt;&lt;!-- raw HTML omitted --&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這些風格建議，對於實際帶過 &lt;a href=&#34;https://school.soft-arch.net/blog/1207517/most-successful-sbe-team&#34;&gt;SBE workshop&lt;/a&gt; 的人，可說心有戚戚焉。&lt;/p&gt;
&lt;h2 id=&#34;限制理論&#34;&gt;限制理論&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;限制理論&lt;/a&gt;對於清晰思考的要求非常高，&lt;a href=&#34;https://en.wikipedia.org/wiki/Thinking_processes_%28theory_of_constraints%29&#34;&gt;thinking processes (TP)&lt;/a&gt; 更是如此。&lt;/p&gt;
&lt;p&gt;就拿只有五個框框、五個箭頭的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Evaporating_Cloud&#34;&gt;evaporating cloud&lt;/a&gt;（衝突圖、疑雲圖）來說吧。如果單論表面形式，可能已經是最簡單最簡潔的了——但也沒那麼單純。&lt;/p&gt;
&lt;p&gt;Jelena Fedurko 在《&lt;a href=&#34;https://www.amazon.cn/dp/B06WP6DNN7&#34;&gt;撥雲見日&lt;/a&gt;》一書如是說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;絕大多數的疑雲圖之所以無效，原因是寫圖的人不理解正確、精確地遣詞用字的重要性。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;摘錄幾則「正確精準的遣詞用字」建議：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每個框內的陳述，應該是一個簡單的句子，沒有任何因果字眼，如「因為、因此、由於、為了」等。&lt;/li&gt;
&lt;li&gt;目標 A、需求 B、需求 C 是正面陳述。不要使用「不、非、否」之類的文字。&lt;/li&gt;
&lt;li&gt;每個框內的陳述，都應該包含一個動詞。&lt;/li&gt;
&lt;li&gt;B 和 C 的內容，是需求而不是行動（描述因為重複發生的動作，如：確保、維持、提供、支持、預防或避免等，而形成的持續狀態）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;書中還有更多嚴謹的建構及檢驗步驟，值得認真練習。&lt;/p&gt;
&lt;h2 id=&#34;系統思考&#34;&gt;系統思考&lt;/h2&gt;
&lt;p&gt;系統思考／&lt;a href=&#34;https://en.wikipedia.org/wiki/System_dynamics&#34;&gt;系統動力學&lt;/a&gt;領域常用工具有二：&lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD (causal loop diagram)&lt;/a&gt; 及 &lt;a href=&#34;https://en.wikipedia.org/wiki/Stock_and_flow&#34;&gt;SFD (stock and flow diagram)&lt;/a&gt;。其中，SFD 涉及兩種量化元素的類型：存量 (stock) 及流量 (flow)，門檻較高 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; ，因此多數人會改由較簡單的 CLD 入門。但這也意味著，這些人不一定具備該有的「變量」敏銳度。&lt;/p&gt;
&lt;p&gt;對「變量」不敏銳，會反映在錯誤命名上。難怪 &lt;a href=&#34;https://www.amazon.com/dp/185788311X&#34;&gt;&lt;em&gt;Seeing the Forest for the Trees&lt;/em&gt;&lt;/a&gt; 一書特別提醒，在 CLD 中請堅持以「名詞」形式來表述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RULE 5: USE NOUNS, NOT VERBS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If you look at all the causal loop diagrams in this book, you will find that &lt;em&gt;every&lt;/em&gt; item is a &lt;strong&gt;noun&lt;/strong&gt; or a &lt;strong&gt;noun phrase&lt;/strong&gt;, rather than a verb or a verb phrase.&lt;/p&gt;
&lt;p&gt;There is often a tendency to express the appropriate action as a verb (hire or fire) rather than as a noun equivalent (hiring or firing). If you can keep to nouns, even here, so emphasizing the action itself, you will find that your causal loop diagrams are clearer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;書中也提醒，不要將「增加」或「減少」之類的字眼偷渡進來，那等於是越俎代庖：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RULE 6: DON’T USE TERMS SUCH AS “INCREASE IN” OR “DECREASE IN”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When drawing causal loop diagrams you will inevitably be tempted to include these two phrases in your descriptions.&lt;/p&gt;
&lt;p&gt;However strong the temptation, resist it. That’s what the arrows are for, especially the &lt;em&gt;S&lt;/em&gt;s and the &lt;em&gt;O&lt;/em&gt;s.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;此書的「CLD 十二條黃金法則」，值得仔細體會：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2018/01/cld-golden-rules.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2018/01/cld-golden-rules.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;結語&#34;&gt;結語&lt;/h2&gt;
&lt;p&gt;予豈咬文嚼字哉？予不得已也。&lt;/p&gt;
&lt;p&gt;為了充分發揮思考框架的威力，請暫時不要當差不多先生吧。&lt;/p&gt;
&lt;p&gt;畢竟，嘗試深度掌握某些知識體系，先蹲後跳，後發先至，是划算的投資。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【咬文嚼字的必要性】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 咬文嚼字的必要性（一）：用句型輔助思考&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2024/02/outcome-sentence-patterns/&#34;&gt;咬文嚼字的必要性（二）：階段性的預期成果設定&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/04/passphrase-at-work/&#34;&gt;請珍惜你們學到的通關密語&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;就連系統思考經典入門小書 &lt;a href=&#34;http://www.books.com.tw/products/0010747160&#34;&gt;&lt;em&gt;Systems One&lt;/em&gt;&lt;/a&gt; 作者 Draper L. Kauffman Jr. 也自承：『常有人要求我將本書「升級」為一本正式介紹系統動態的書籍，尤其是將關鍵的「存量－流量」概念放進書中。當我一開始規劃本書前身的授課教材時，也曾嘗試向我十年級學生解釋「存量－流量」圖示及模型，但我失敗了。不到一半的學生在學習後仍記得其中有用的部分，因此我忍痛將此刪除。    我不想搞砸既有的成功基礎。本書在此領域已經被成功定位為「介紹系統思維最簡單的一本書」。增加長度或複雜度可能對某些應用有幫助，但也會降低對其他人的協助。我不確定改寫後，是否還能像現在這樣廣為大眾所接受。』    大師都如此說了，可見 SFD 門檻之高。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>從系統思考看 DevOps</title>
      <link>//william-yeh.net/post/2017/10/devops-a-system-dynamics-perspective/</link>
      <pubDate>Sun, 29 Oct 2017 11:40:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2017/10/devops-a-system-dynamics-perspective/</guid>
      
        <description>&lt;p&gt;自從去年在〈&lt;a href=&#34;//william-yeh.net/post/2016/05/devops-a-lean-perspective/&#34;&gt;有了 Agile，為什麼還要有 DevOps？&lt;/a&gt;〉及〈&lt;a href=&#34;//william-yeh.net/post/2016/08/devops-a-toc-perspective/&#34;&gt;從限制理論看 DevOps&lt;/a&gt;〉兩場演講中，分別以 lean thinking 及 theory of constraints (TOC) 兩個角度探討 DevOps 之後，心中一直有個願望：想再從「&lt;a href=&#34;https://en.wikipedia.org/wiki/System_dynamics&#34;&gt;系統思考&lt;/a&gt;」角度探討 DevOps。&lt;/p&gt;
&lt;p&gt;畢竟，「系統思考」算是名門正派，「學習型組織」更是我從研究所時代就心嚮往之的目標。當時買的《&lt;a href=&#34;http://www.books.com.tw/products/0010009556&#34;&gt;第五項修練&lt;/a&gt;》第一版，還一直在我的書架上最尊榮的位置呢。&lt;/p&gt;
&lt;p&gt;不過，想將它應用到 DevOps 場域上，我還不太有把握。畢竟系統思考的重要思維工具 &lt;a href=&#34;https://en.wikipedia.org/wiki/Causal_loop_diagram&#34;&gt;CLD (causal loop diagram)&lt;/a&gt;，比一般因果推理的思維工具，多了變量 (variable) 及時間滯延 (delay) 觀念，燒腦程度更甚於 TOC 的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Current_reality_tree_%28theory_of_constraints%29&#34;&gt;CRT (current reality tree)&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;想法，就這麼擱置了。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;直到今年初，接連聽了&lt;a href=&#34;https://blog.odd-e.com/yilv/&#34;&gt;呂毅&lt;/a&gt;老師一場演講（&lt;a href=&#34;https://www.accupass.com/event/1702051415281771146556&#34;&gt;在組織教練中看見系統性模式&lt;/a&gt;）及兩天 LeSS 課程，被老師用 CLD 貫串全場的氣勢，以及推廣系統思考的熱情所感動，決定回到初衷，勇於接受挑戰。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/10/yilv-cld-speech.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/10/yilv-cld-speech.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;於是，重拾《&lt;a href=&#34;http://www.books.com.tw/products/0010009556&#34;&gt;第五項修練&lt;/a&gt;》，重新咀嚼&lt;a href=&#34;https://en.wikipedia.org/wiki/System_archetype&#34;&gt;系統基模&lt;/a&gt;，研究如何以淺顯的方式解釋 CLD。我也嘗試搭配 &lt;a href=&#34;http://ncase.me/loopy/&#34;&gt;LOOPY&lt;/a&gt; 這個有趣的軟體，降低 CLD 學習門檻。最後，從 DevOps 中挑選熱門的話題 microservices 作為箭靶，以增進實用性。萬事俱備，結果就是以下的演講。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/10/2017-10-26-devops-speech.jpg&#34; alt=&#34;DevOps Taiwan Meetup #8 (2017-10-26)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/10/2017-10-26-devops-speech.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;DevOps Taiwan Meetup #8 (2017-10-26)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DevOps Taiwan Meetup #8 (2017-10-26).&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;從系統思考看 DevOps：以 microservices 為例&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;活動簡介：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;台灣第一次舉辦的 DevOpsDays Taipei，涵蓋許多精彩的文化與技術議題。&lt;/p&gt;
&lt;p&gt;大會中，許多講者不約而同提到「系統思考」的概念，這是什麼？許多講者也提到 microservices 的重要性，但為什麼許多人想導入，卻鍛羽而歸？&lt;/p&gt;
&lt;p&gt;此演講以系統思考的 causal loop diagram 角度，探討 microservices 常見的導入誤區：意外的敵人 (accidental adversaries) 及捨本逐末 (shifting the burden) ，並根據系統基模角度提出對應的槓桿解。&lt;/p&gt;
&lt;p&gt;希望你聽了之後，能夠初步掌握系統思考的切入點，也對於 microservices 導入，多了一分把握。&lt;/p&gt;
&lt;p&gt;提醒：建議先複習一下 Andrew Wu 在【DevOps Taiwan Meetup #4 (2017/02/22) ／ &lt;a href=&#34;https://devops.kktix.cc/events/meetup4-cm-tools-96091c-b7dd89&#34;&gt;這一夜讓我們來聊聊 Microservices&lt;/a&gt;】的內容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://goo.gl/Drfeiw&#34;&gt;投影片 @ Slideshare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://goo.gl/zXkESo&#34;&gt;部落格文章&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;投影片：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;https://www.slideshare.net/williamyeh/devops-system-dynamics-perspective&#34;&gt;從系統思考看 DevOps：以 microservices 為例&lt;/a&gt;&lt;/strong&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/81199835&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;實況錄影：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/zMeA3CjOi60?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;這場演講，開宗明義就說了：只探討「動態性複雜」，不探討「細節性複雜」。因此，刻意不著重在 microservices 技術細節。正好現場有兩位深富 microservices 實務經驗的高手，就順便 cue 他們幫忙回答技術提問。&lt;/p&gt;
&lt;p&gt;感謝 andrew 幫忙回答&lt;a href=&#34;https://www.facebook.com/andrew.blog.0928/posts/510669392641677&#34;&gt;資料儲存問題&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;交易處理是 RDBMS 強項，不過 RDBMS 先天就跟 microservices 不大搭，分散式的環境下要有別的處理方式。&lt;/p&gt;
&lt;p&gt;非交易的資料可透過 Message Queue 等等非同步的方式來達成最終的一致性。如果範圍切割得夠小，也許你仍然可以在單一服務內繼續用 RDBMS 的交易控制。如果交易被迫得被分散在兩個服務之間，那麼分散式交易的機制就必須確實實作（例如 2 phase commit 之類的技巧）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;感謝 jini 幫忙回答 &lt;a href=&#34;https://www.facebook.com/jakarta99/posts/10155786498304719&#34;&gt;transaction 問題&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;但在金融交易時，若該 domain object 一定要在同一個 transaction context 時，那麼該服務就不該被切割。此外，有某些狀況也許可以切割，類似客戶與訂單的關係，這部份就可以用 async 加上 status 來處理，甚至有一個 batch 來 review 最終一致性。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;最後，希望這種「系統思考」角度，對大家在導入 DevOps 的過程中，有些許幫助。更進一步，朝向學習型組織邁進。&lt;/p&gt;
&lt;p&gt;演講最後推薦的幾本書，別忘了要去看喔！&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>你曾經變成你自己最糟糕的一面嗎？</title>
      <link>//william-yeh.net/post/2017/10/experiencing-negotiation/</link>
      <pubDate>Tue, 03 Oct 2017 21:28:27 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2017/10/experiencing-negotiation/</guid>
      
        <description>&lt;p&gt;湯姆・漢克與梅格・萊恩主演的《&lt;a href=&#34;https://www.imdb.com/title/tt0128853/&#34;&gt;電子情書&lt;/a&gt;》中，有一段台詞：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do you ever feel you&amp;rsquo;ve become the worst version of yourself? That a Pandora&amp;rsquo;s box of all the secret, hateful parts - your arrogance, your spite, your condescension - has sprung open? Someone upsets you and instead of smiling and moving on, you zing them. &amp;ldquo;Hello, it&amp;rsquo;s Mr Nasty.&amp;rdquo; I&amp;rsquo;m sure you have no idea what I&amp;rsquo;m talking about.&lt;/p&gt;
&lt;p&gt;妳曾經變成妳自己最糟糕的一面嗎？那就是一個裝有所有的恨意、輕蔑跟降尊紆貴的潘朵拉盒子被打開。有人讓你感到不悅，但是你沒有選擇離開，反而用毒舌回敬。「哈囉，惡毒的人來了。」我相信妳一定不知道我在說什麼⋯⋯&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;高壓情境下，的確會做出異於平日的舉動。&lt;/p&gt;
&lt;p&gt;在 Joe 的【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/13&#34;&gt;302 專案的談判與協商&lt;/a&gt;】課堂上，我就這麼扎扎實實體驗到了。&lt;/p&gt;
&lt;h2 id=&#34;案例&#34;&gt;案例&lt;/h2&gt;
&lt;p&gt;我在最近〈&lt;a href=&#34;//william-yeh.net/post/2017/07/sprint-planning-as-negotiation/&#34;&gt;以談判角度看 Sprint Planning&lt;/a&gt;〉及〈&lt;a href=&#34;//william-yeh.net/post/2017/08/facilitator-mindset/&#34;&gt;引導者，要懂心理&lt;/a&gt;〉兩篇文章都提到自己的感觸：談判思維，對於專案及團隊引導是有幫助的。因此，我刻意不選擇一般類型的談判課，而是先挑針對&lt;strong&gt;專案情境&lt;/strong&gt;而設計的談判課。&lt;/p&gt;
&lt;p&gt;專案情境？首選自然是 Joe &amp;amp; Bryan 金字招牌，沒有第二。&lt;/p&gt;
&lt;p&gt;【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/13&#34;&gt;302 專案的談判與協商&lt;/a&gt;】是一門體驗課程，三個案例，六種角色，從刀刀見血的分組攻防戰中，親自品嚐箇中酸甜苦辣。&lt;/p&gt;
&lt;p&gt;三個案例，一個很和平的談成了，一個很激烈的破局了，一個稍帶激昂的談成了。&lt;/p&gt;
&lt;p&gt;讓我反思最多的，是破局。&lt;/p&gt;
&lt;h2 id=&#34;習慣&#34;&gt;習慣&lt;/h2&gt;
&lt;p&gt;這個案例，儘管應該是我最熟悉的，但在高壓情境中，竟然渾然忘記平日的我，一定會為了促成事情發生而儘早揭露某些關鍵資訊；反而陷入一種被遊戲規則設計好的陷阱（尤其是績效指標），糾結，直到最後關頭才驚覺，但局面已經難以挽回，對方亦無台階可下，可算破局。&lt;/p&gt;
&lt;p&gt;我忘了在這種情境中，自己的角色不重要，最重要的目標應該是＿＿＿＿。&lt;/p&gt;
&lt;p&gt;在高壓情境下，在誤判 ZOPA 時，連自以為無比自然的「做事習慣」都會被無情解體了，那麼，這真的已經變成自己的「做事習慣」嗎？更遑論其他從書裡、文章裡、課程講義裡、老師口頭提示的，但尚未充分整合融會進來的觀念及技巧。&lt;/p&gt;
&lt;p&gt;果然還需要常保反思警醒之心。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/10/nego-course-worksheet.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/10/nego-course-worksheet.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;另一個有趣的案例，讓我在一個安全的實驗室放膽演一回，演一個我幾乎不曾公開展現過的特質。我很享受這個過程，也發現：適度使用，的確有效果。這也令我換位思考：下一回，當我在真實人生遇到這樣的對手，是否也能冷靜地看透 position 背後的 needs？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「要求」(position) 是假的，「需求」(needs) 才是真的。所謂談判，就是一場「發覺對方需求」的遊戲。 &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;    &amp;mdash; 《&lt;a href=&#34;https://www.eslite.com/product/1001124182577726&#34;&gt;價值談判&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;選項&#34;&gt;選項&lt;/h2&gt;
&lt;p&gt;在隊友的交叉掩護下，仍有餘裕的小空檔，我便刻意實驗一些從其他書上看過的技法。有些如預期般有效，有些則否。頓時體會到，那些技巧，既非沒用，亦非絕對有用，而是要審時度勢，拿捏出手輕重及順序。最需要的，不是死啃理論、案例、框架、SOP，而是要在拳拳到肉的體驗中，在安全的挫折中，打破慣性，得到體悟：永遠有其他意想不到的選項。&lt;/p&gt;
&lt;p&gt;畢竟，正如 Joe 所說：「今天，我能坐在談判桌上，代表我仍然有優勢之處。」&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/10/nego-prepare.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/10/nego-prepare.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;視角&#34;&gt;視角&lt;/h2&gt;
&lt;p&gt;上完課隔天，立刻發現，面對高壓情境，居然比以前更能泰然處之。甚至還能夠切換廣角鏡、標準鏡、望遠鏡，從較多面向去盤算該如何出牌，或是打 pass。&lt;/p&gt;
&lt;p&gt;簡單的說，自己的出牌選項變多了。&lt;/p&gt;
&lt;p&gt;很感謝 Joe 在喉嚨不適的情況下，仍然用心帶領這麼一場難忘的談判體驗。收穫的，不只是談判，不只是職場關係的優勢策略，更是對自我冰山的高強度體檢。&lt;/p&gt;
&lt;p&gt;很值得的冒險！&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>思考框架的刻意練習</title>
      <link>//william-yeh.net/post/2017/09/thinking-framework-practice/</link>
      <pubDate>Fri, 22 Sep 2017 11:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2017/09/thinking-framework-practice/</guid>
      
        <description>&lt;h2 id=&#34;思考框架&#34;&gt;思考框架&lt;/h2&gt;
&lt;p&gt;我自認是個思考框架控。&lt;/p&gt;
&lt;p&gt;學生時代只是不自覺就這麼做了。但後來被勝間和代《&lt;a href=&#34;https://www.books.com.tw/products/0010434249&#34;&gt;新・知識生產術&lt;/a&gt;》洗腦，我就開始下意識蒐集並應用。&lt;/p&gt;
&lt;p&gt;過度依賴既定框架是不好的 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，但是，看到連鼓吹思考框架甚力的勝間和代也曾有此疑問，且給出一份建議，我就放心了。她在《&lt;a href=&#34;https://www.books.com.tw/products/0010457479&#34;&gt;培養商業腦的７種組織力&lt;/a&gt;》書中是這麼說的：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/09/folk-new-fx.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/09/folk-new-fx.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;另一位我很崇拜的憲哥（謝文憲），在書籍中也一再重申：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;養成持續且大量的閱讀習慣，是每個人成長，成為一個咖的必經過程。找到案例、找到一個比你更好的架構，來印證你觀點的重要時刻。&lt;/p&gt;
&lt;p&gt;  &amp;mdash; Quote: 《&lt;a href=&#34;https://www.books.com.tw/products/0010752512&#34;&gt;人生準備 40% 就衝了&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;某次演講，更是一針見血當頭棒喝：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/09/on-theory.png&#34; alt=&#34;謝文憲演講&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/09/on-theory.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;謝文憲演講&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;刻意練習&#34;&gt;刻意練習&lt;/h2&gt;
&lt;p&gt;既然這兩位私淑對象都如此說，我就決定，做事不要只訴諸本能，要刻意練習，提升到理論層面。畢竟：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;

&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/09/tweet-20170726.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/09/tweet-20170726.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

  &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/889983697797001216&#34;&gt;2017-07-26 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同時，不只是對自己，連演講及引導場合，我也刻意朝這方向鋪陳。（所以，你會發現，近年來，我的演講內容，常會夾帶些理論框架⋯⋯）&lt;/p&gt;
&lt;p&gt;漸漸的，開始能夠體會勝間和代所說「從現有的組織架構創造出新的組織架構」的箇中深意。譬如說，我在帶領【&lt;a href=&#34;//william-yeh.net/post/2017/08/facilitator-mindset/#引導者讀書會&#34;&gt;引導者讀書會&lt;/a&gt;】時，不知不覺就將鑽石模型 (diamond model) 與薩提爾冰山模型結合起來。也在本周兩個場合突發奇想，將《&lt;a href=&#34;https://www.eslite.com/product/1001114561006441&#34;&gt;關鍵對立&lt;/a&gt;》提出的「影響因素源頭模型」與《&lt;a href=&#34;https://www.eslite.com/product/1001122732478446&#34;&gt;鉤癮效應&lt;/a&gt;》提到的「法格行為模型 (&lt;a href=&#34;https://www.behaviormodel.org/&#34;&gt;Fogg Behavior Model&lt;/a&gt;)」結合起來，從新的角度分析《&lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;》的模型。&lt;/p&gt;
&lt;p&gt;謎之音：簡直是模型大亂鬥。&lt;/p&gt;
&lt;p&gt;這麼做，不僅是智性的體操，不僅是一種擴充求解空間的方法，也是一種沈澱反思的過程。&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010752714&#34;&gt;刻意練習&lt;/a&gt;》說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;刻意練習，只在跨出舒適圈後才能奏效，需要學生不斷嘗試去突破現階段的技能水準。這意味著幾乎得傾盡全力，所以往往不會太有樂趣。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「傾盡全力」這一點，我是承認的；但「不會太有樂趣」這一點，我倒不這麼認為——這可是非常有趣呀！&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010752714&#34;&gt;刻意練習&lt;/a&gt;》又說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;刻意練習，幾乎等於加強或調整先前習得的技能，必須著重該技能的特定面向，努力改善。隨著時間過去，這一步一步的改善，最終會打造出專家級表現。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「專家級表現」這一點我還不敢苛求；但至少會朝著劉大任在《&lt;a href=&#34;https://www.books.com.tw/products/0010025396&#34;&gt;強悍而美麗&lt;/a&gt;》描述的境界邁進：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在這個世界上，你就愛一種東西，你就在你愛的這個東西裡把自己練到完美，練到無懈可擊。&lt;/p&gt;
&lt;p&gt;你因此尋得滿足，此外的一切其實無足輕重。就這樣，你變得堅強，足以抵抗不時傾巢而來的寂寞；你變得勇敢，你學會拒絕周遭的喧嘩與熱鬧；你學會簡單而嚴肅，你形成一種風格，唯你獨有。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;是的，形成一種風格，唯你獨有。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;像《&lt;a href=&#34;https://www.eslite.com/product/1001124272036603&#34;&gt;精準明確思考術&lt;/a&gt;》或《&lt;a href=&#34;https://www.books.com.tw/products/0010482895&#34;&gt;超神速全腦學習法&lt;/a&gt;》都一再警告依賴既定框架的陷阱：思考怠惰。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>引導者，要懂心理：薩提爾之旅後記</title>
      <link>//william-yeh.net/post/2017/08/facilitator-mindset/</link>
      <pubDate>Wed, 02 Aug 2017 15:11:04 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2017/08/facilitator-mindset/</guid>
      
        <description>&lt;h2 id=&#34;前情提要&#34;&gt;前情提要&lt;/h2&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2017/04/satir-workshop/&#34;&gt;六日薩提爾體驗&lt;/a&gt;〉一文曾提到：「私心認為，現階段的自己最需要的，並非那些直接就派得上用場的各式各樣的引導技巧，而是可能沒辦法直接就派得上用場的&lt;strong&gt;薩提爾&lt;/strong&gt;心法。」因此，繼三月、四月參加陳桂芳老師帶領的 3+3 天薩提爾之旅之後，六月底，我又再接再厲，再上三天。&lt;/p&gt;
&lt;p&gt;基礎篇＋應用篇＋助人篇，整整湊滿了九天。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-1.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-1.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這次【助人篇：薩提爾自助助人進階工作坊】三天的課程，心得很難寫。因為，體會都在身體裡，在呼吸裡，在內在冰山中。&lt;/p&gt;
&lt;p&gt;能寫下來的重點，大概只有兩句話：「&lt;strong&gt;和諧而專注的跟隨歷程對話&lt;/strong&gt;」及「&lt;strong&gt;跟隨內在歷程，而不是事件或故事線&lt;/strong&gt;」吧。&lt;/p&gt;
&lt;p&gt;感謝老師、助教小老師、學習夥伴。這九天的冒險旅程，將是我很大的滋養與資源。接下來能做的，大概就是借用從 Joe 那邊學到的&lt;a href=&#34;//william-yeh.net/post/2017/05/self-change/&#34;&gt;方法&lt;/a&gt;，刻意練習，自我改變。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-2.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-2.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;引導者讀書會&#34;&gt;引導者讀書會&lt;/h2&gt;
&lt;p&gt;刻意練習的機會【引導者讀書會】自動找上門。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 帶著帶著，不知不覺竟也累積了五場。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-3.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-3.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;既然名為「讀書會」，就有主要讀物及補充讀物。不過，照本宣科不是我的風格。我刻意實驗一些創意混搭手法，尤其是剛學完九天的薩提爾模式。&lt;/p&gt;
&lt;p&gt;譬如說，用在破冰上。&lt;/p&gt;
&lt;p&gt;讓破冰不只是嘻嘻哈哈的團康，而是&lt;strong&gt;藉著「直接切入正題」來破冰&lt;/strong&gt;，一直是我努力揣摩、刻意練習的手法。我曾在六月中旬【Agile Workshop / 敏捷原理與團隊塑造】課程中小試過一次，反應不錯，因此，我在這讀書會的第一場活動，就是以略帶懸疑的風格，用薩提爾的冰山模型來破冰 + 腦力激盪：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-4.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-4.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這還是第一回破冰，暖場成分居多。下一回的中心議題，就更深入破這個「冰」了：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-5.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-5.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;後來，更將 &lt;em&gt;&lt;a href=&#34;https://www.amazon.com/dp/1118404955&#34;&gt;Facilitator&amp;rsquo;s Guide to Participatory Decision-Making&lt;/a&gt;&lt;/em&gt; 書中提到的鑽石模型 (diamond model) 與薩提爾冰山模型相結合，協助大家從理性及感性兩層面，充分體認團體決策的動態。&lt;/p&gt;
&lt;p&gt;這種手法，「歷程提問」的界線控制是一大挑戰。若能謹守「&lt;strong&gt;歷程，而非內容&lt;/strong&gt;」的心法，的確能帶出不一樣的品質。&lt;/p&gt;
&lt;p&gt;冰山提問，是需要刻意練習的。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;跨界取經&#34;&gt;跨界取經&lt;/h2&gt;
&lt;p&gt;重要的觀念，不會只有一本書提到，也不會只有一個領域提到。&lt;/p&gt;
&lt;p&gt;雖然我不太想把【引導者讀書會】引導到談判領域 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; ，但是，某些祕訣，在《&lt;a href=&#34;https://www.taaze.tw/sing.html?pid=11100243769&#34;&gt;誰說我們不能一起做決定&lt;/a&gt;》及《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;激發員工潛力的薩提爾教練模式&lt;/a&gt;》中反覆提到，在《&lt;a href=&#34;https://www.books.com.tw/products/0010725672&#34;&gt;FBI 協商談判術&lt;/a&gt;》及《&lt;a href=&#34;https://www.books.com.tw/products/0010650242&#34;&gt;再也沒有難談的事&lt;/a&gt;》也反覆提到。既然理無專在，我就來混搭吧！&lt;/p&gt;
&lt;p&gt;譬如說，我就出了這麼一份作業：用右邊兩本書的內容，評註圈點左邊書籍提到的談判案例。刺激吧！&lt;/p&gt;
&lt;p&gt;這就是跨界的鉤子。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-6.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-6.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;引導者要懂心理&#34;&gt;引導者，要懂心理&lt;/h2&gt;
&lt;p&gt;整個過程，我充分體會到薩提爾模式的威力。可以說，沒有之前那九天薩提爾之旅的扎實訓練，我不可能看到這一層景緻。&lt;/p&gt;
&lt;p&gt;不知不覺中，好像走出一條連自己都料想不到的蹊徑。&lt;/p&gt;
&lt;p&gt;幸好我一開始選擇的課，就是溯源的 Satir 課，而不是限縮在職場領域的應用。猶記當時的&lt;a href=&#34;//william-yeh.net/post/2017/04/satir-workshop/&#34;&gt;出發點&lt;/a&gt;是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;既然要上課，就要上源頭的。儘管我是從陳茂雄的《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;激發員工潛力的薩提爾教練模式&lt;/a&gt;》一書開始接觸到薩提爾模式，但是，我不想把經驗限縮於職場場域——那是很可惜的事。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;任性且大膽，誤打誤撞的幸運。&lt;/p&gt;
&lt;p&gt;溯源的好處是，掌握系統全貌，掌握核心關鍵。就以三月底我剛踏進【薩提爾課程．基礎篇】教室的第一天來說吧，原始動機的確是針對別人；但一兩天後就發現，到頭來還是得反諸自己。不反諸自己，成效有限，很快就會卡住。&lt;/p&gt;
&lt;p&gt;《論語．憲問》說：「古之學者為己，今之學者為人。」&lt;/p&gt;
&lt;p&gt;不可否認的，這九天都在不斷挑戰自己的舒適區，衝擊頗大。不過，引導者本來就要像治療師那樣，隨時認真檢視及測試自己的風格。像《&lt;a href=&#34;https://www.eslite.com/product/1001133212384855&#34;&gt;米紐慶的家族治療百寶袋&lt;/a&gt;》所說：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-7.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/08/facilitator-mindset-7.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;溯源的另一個好處是，只要再加把勁，我可以轉化運用在許多領域。像這五場【引導者讀書會】，核心法寶其實就是 Satir 冰山歷程。&lt;/p&gt;
&lt;p&gt;也熊熊想到：這讀書會一直辦下去，好像順便就可以拿來開另一場【新手小主管讀書會】，或是作為 Scrum Master 引導技能養成班了⋯⋯&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      薩提爾課程 - 系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2017/04/satir-workshop/&#34;&gt;六日薩提爾體驗&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 引導者，要懂心理&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2017/07/sprint-planning-as-negotiation/&#34;&gt;以談判角度看 Sprint Planning&lt;/a&gt;〉一文曾提到，「最近在公司內部，受同事之邀，一連主持了幾場【引導者讀書會】，每次一小時。一邊帶，一邊也趁機系統化沈澱反思自己一路以來的土法煉鋼心得。」&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;活動前，自己先惡補《&lt;a href=&#34;https://www.anobii.com/books/sha-wei-ya-mo-shi-bing-shan-li-cheng-ti-wen-fan-li/0188354df37606bd79&#34;&gt;沙維雅模式冰山歷程提問範例&lt;/a&gt;》的相關內容，自評，當場在「歷程提問」的界線控制上，約有 70分 吧。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;畢竟，在談判領域，我還很嫩，書也沒讀通，不能誤人子弟自曝其短。所以，我十月份要去拜師學藝。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>以談判角度看 Sprint Planning</title>
      <link>//william-yeh.net/post/2017/07/sprint-planning-as-negotiation/</link>
      <pubDate>Thu, 27 Jul 2017 12:18:03 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2017/07/sprint-planning-as-negotiation/</guid>
      
        <description>&lt;p&gt;自從去年 Q3 個人的 &lt;a href=&#34;//william-yeh.net/post/2016/10/one-week-sprint/&#34;&gt;Scrum 首航&lt;/a&gt;開始，讓我壓力最大的，並不是主持 Retrospective，而是 Sprint Planning。上完 &lt;a href=&#34;//william-yeh.net/post/2017/03/cspo/&#34;&gt;CSPO 課程&lt;/a&gt;後，更是對高品質的 Sprint Planning 有著不一樣的願景。&lt;/p&gt;
&lt;p&gt;研發團隊需要再教育，PO 又何嘗不是呢？&lt;/p&gt;
&lt;p&gt;只是，不同的 PO 有不同的團隊領導風格，大多數個性鮮明的 PO 也不是那麼容易被改變。這就有待 Scrum Master 善用軟技巧去適時引導。&lt;/p&gt;
&lt;p&gt;其中，最立竿見影直接見效的，就是會議引導技術。&lt;/p&gt;
&lt;p&gt;最近在公司內部，受同事之邀，一連主持了幾場【&lt;a href=&#34;//william-yeh.net/post/2017/08/facilitator-mindset/#引導者讀書會&#34;&gt;引導者讀書會&lt;/a&gt;】，每次一小時。一邊帶，一邊也趁機系統化沈澱反思自己一路以來的土法煉鋼心得。&lt;/p&gt;
&lt;h2 id=&#34;談判&#34;&gt;談判？&lt;/h2&gt;
&lt;p&gt;在反思、設計、取材的過程中，偶然發現，《&lt;a href=&#34;https://www.eslite.com/product/1001124182577726&#34;&gt;價值談判&lt;/a&gt;》這本有趣的小書，還滿適合想要改善 Sprint Planning 的人讀讀。&lt;/p&gt;
&lt;p&gt;尤其是 PO 及 Scrum Master。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:10em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/07/value-nego.jpg&#34; alt=&#34;《價值談判》&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/07/value-nego.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;《價值談判》&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;雖然我不太想把 Sprint Planning 直接定位成一種「談判」，尤其是涉及「權力」的談判；但不可否認的，Sprint Planning 過程中，本來就有很多談判的元素在裡面。&lt;/p&gt;
&lt;p&gt;工具是中性的，看你怎麼運用。&lt;/p&gt;
&lt;p&gt;既然連「一談就贏」談判名師／明師都&lt;a href=&#34;https://negotowin.blogspot.tw/2017/05/blog-post_12.html&#34;&gt;認可&lt;/a&gt;這本書，我相信單以「談判」角度來說，這本書是可信的。那麼，下一個問題就是，這本書真的適合給 Sprint Planning 參考嗎？&lt;/p&gt;
&lt;p&gt;且讓我摘錄幾段吧！&lt;/p&gt;
&lt;h2 id=&#34;錨定效應&#34;&gt;錨定效應&lt;/h2&gt;
&lt;p&gt;我常引用《&lt;a href=&#34;https://www.books.com.tw/products/0010921383&#34;&gt;執行力的修練&lt;/a&gt;》的四大紀律框架來指導敏捷開發活動。其中，紀律一「鎖定極重要目標」也正是 Sprint Planning 的起手式。&lt;/p&gt;
&lt;p&gt;《價值談判》也有許多與此類似的論述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「&lt;strong&gt;要求&lt;/strong&gt;」(&lt;strong&gt;position&lt;/strong&gt;) 是假的，「&lt;strong&gt;需求&lt;/strong&gt;」(&lt;strong&gt;needs&lt;/strong&gt;) 才是真的。&lt;/p&gt;
&lt;p&gt;所謂談判，就是一場「&lt;strong&gt;發覺對方需求&lt;/strong&gt;」的遊戲。如果你是以「我能得到什麼」為思考的出發點，這場談判絕對很難成功；記得要先從「我和對方認為的重要價值是什麼」、「如何滿足這些價值」開始思考，談判品質會在彼此專注於「價值」時得到提升。&lt;/p&gt;
&lt;p&gt;所謂談判，最終只是一場「認知鬥爭」，先將對方的認知拉到對我自己有利的標準點上，再來開始談判。善用錨定效應。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，只要是我有權主導的 Sprint Planning，都會先花些時間請 PO 重新展開 &lt;a href=&#34;https://www.impactmapping.org/&#34;&gt;Impact Mapping&lt;/a&gt; 及 &lt;a href=&#34;https://www.taaze.tw/products/11100816208.html&#34;&gt;&lt;em&gt;Scaling Lean&lt;/em&gt;&lt;/a&gt; 的內容，尤其是還沒有穩定扎實 Product Backlog Refinement 的團隊。&lt;/p&gt;
&lt;h2 id=&#34;什麼才是贏&#34;&gt;什麼才是「贏」？&lt;/h2&gt;
&lt;p&gt;如果沒有妥善經營共識，Sprint Planning 往往淪為 PO vs 團隊之間的拉鋸戰。一方認為「加功能」才是贏，另一方認為「清技術債」才是贏，彼此據理力爭；但殘酷的現實是，最後主導權往往都落在有職位權的那一方。&lt;/p&gt;
&lt;p&gt;這是真的「贏」嗎？&lt;/p&gt;
&lt;p&gt;《價值談判》是這麼說的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;世上所有談判，大致可分為兩類，一種是以&lt;strong&gt;關係&lt;/strong&gt;為中心，另一種則是以&lt;strong&gt;利益&lt;/strong&gt;為中心。真正卓越的談判家，是能夠將原本以利益為中心的談判對象，轉換成以關係為中心。&lt;/p&gt;
&lt;p&gt;回想你目前的談判對象，未來是否還需要碰面往來？如果需要，你們之間就會以關係為中心進行談判，在這樣的談判中，比起短期經濟利益，信任和評價等這種會有長久影響的價值更為重要。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果要以「關係」為中心，就不能草率了事，要花心思：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;各位認為社內協商容易或社外協商容易呢？&lt;/p&gt;
&lt;p&gt;大部分人會認為社內協商比較困難，為什麼？我想應該是因為&lt;strong&gt;錯誤的信任&lt;/strong&gt;所導致，像是「你應該知道我在想什麼」的氛圍。因此社內員工只會越來越用「無理要求」來強迫對方接受，而不再用邏輯與根據來說服對方。&lt;/p&gt;
&lt;p&gt;為了能有效談判，記得要拋下「你應該知道我在想什麼」這種毫無根據的錯誤信任，並以&lt;strong&gt;邏輯&lt;/strong&gt;與&lt;strong&gt;根據&lt;/strong&gt;填補空缺才行。&lt;/p&gt;
&lt;p&gt;卓越的談判家，會在讓步時提出充分的邏輯與根據，好讓對方覺得這份讓步是有價值的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這些，都是慣常 command-and-control 的老派 PO 必須調整的，也是 Scrum Master 必須適時引導的。&lt;/p&gt;
&lt;h2 id=&#34;雙人舞&#34;&gt;雙人舞&lt;/h2&gt;
&lt;p&gt;其實，好的 Sprint Planning，不只是 PO 的責任，團隊成員也是。團隊成員不只是接案，也在提案，所以，也需要學習（或被引導）正確的協商方法。&lt;/p&gt;
&lt;p&gt;畢竟，正如《價值談判》所說，「談判就像在跳雙人舞」：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;談判，其實就是一種表達方式、一套邏輯，不論要談什麼內容，營造能使對方開口的氛圍很重要。&lt;/p&gt;
&lt;p&gt;在談判桌上，不要因為對方沒有採納我的提案而感到失望或憤怒，卓越的談判家只會投注更多心力在如何讓自己的提案更出色。&lt;/p&gt;
&lt;p&gt;如果雙方都是談判專家，彼此能夠交換的條件就會越多，等於是更容易創造出創意對策。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;結構先行&#34;&gt;結構先行&lt;/h2&gt;
&lt;p&gt;回到本文開頭的起心動念。&lt;/p&gt;
&lt;p&gt;最近在公司內部，受同事之邀，一連主持了幾場【&lt;a href=&#34;//william-yeh.net/post/2017/08/facilitator-mindset/#引導者讀書會&#34;&gt;引導者讀書會&lt;/a&gt;】，每次一小時。一邊帶，一邊也趁機系統化沈澱反思自己一路以來的土法煉鋼心得。&lt;/p&gt;
&lt;p&gt;突然有個感觸：好像應該開始總結這十個月以來，穿梭數個團隊帶領 Sprint Planning 的所見所聞，以 &lt;em&gt;&lt;a href=&#34;https://williampjyeh.notion.site/bab7091e6f5c42d59797fdb1bfd5422f&#34;&gt;Facilitator&amp;rsquo;s Guide to Participatory Decision-Making&lt;/a&gt;&lt;/em&gt; 書中提到的鑽石模型 (diamond model) 及串組式流程設計 (string) 加以精鍊。&lt;/p&gt;
&lt;p&gt;我想用結構化的 Sprint Planning 流程，讓錨定效應、以關係為中心、目的型談判自然發生，讓參與其中的人，逐漸在刻意不遮掩的建設性衝突中，潛移默化。&lt;/p&gt;
&lt;p&gt;不過，我這種流程設計，對於資淺 PO 來說，應該是備感壓力吧。呵呵。畢竟，這高度考驗著說故事能力 (story telling) 及參與式決策的開放心態 (participatory decision-making)。可是，少了這些，怎能算是合格的廿一世紀 PO 呢？&lt;/p&gt;
&lt;p&gt;我們家的 CEO 接受這樣的挑戰了，那麼，你呢？&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/07/planning-20170710.jpg&#34; alt=&#34;Sprint Planning&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/07/planning-20170710.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Sprint Planning&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>自我改變，起點不是先挑戰意志力</title>
      <link>//william-yeh.net/post/2017/05/self-change/</link>
      <pubDate>Tue, 16 May 2017 22:44:42 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2017/05/self-change/</guid>
      
        <description>&lt;p&gt;一看到 Joe 多年後重開【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/85&#34;&gt;大人學講座04 : 有效自我改變的系統化做法&lt;/a&gt;】，二話不說，立刻報名。&lt;/p&gt;
&lt;p&gt;為什麼這麼有信心呢？&lt;/p&gt;
&lt;p&gt;原因之一，已經上過好幾次 Joe 的課程，尤其是與這主題風格類似的【&lt;a href=&#34;//william-yeh.net/post/2016/08/lifetime-keywords/&#34;&gt;別總是直球對決&lt;/a&gt;】。我很清楚這類課程的系統性及實用性。&lt;/p&gt;
&lt;p&gt;原因之二，看了 Joe 的幾篇文章，意猶未盡，想看看多年後重開的加長版講座，又有什麼新的體悟？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://darencademy.com/article/view/id/11242&#34;&gt;如何才能真正的自我改變 (一) ：改變的步驟、以及最難的一點&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://darencademy.com/article/view/id/11487&#34;&gt;如何才能真正的自我改變 (二) ：大部分人其實不知道自己要甚麼&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://darencademy.com/article/view/id/12535&#34;&gt;如何才能真正的自我改變 (三) ：了解你手上的籌碼有甚麼&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://darencademy.com/article/view/id/15791&#34;&gt;為何我們很難改變周圍那些愛抱怨的朋友？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://darencademy.com/article/view/id/16420&#34;&gt;怎麼才能有效安撫找你抱怨的朋友？&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;原因之三，儘管課程文案特別提醒「&lt;strong&gt;不適合的對象&lt;/strong&gt;：嘗試想改變別人者。改變的關鍵首重於自身的覺醒。所以若你是想聽完後去影響身邊人 (小孩、朋友) 的，我覺得幫助會有限喔，所以就請別浪費錢了。」但反骨的我，還是想嚐嚐看有沒有一些幫助。&lt;/p&gt;
&lt;p&gt;答案是：有！&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/05/self-change-1.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/05/self-change-1.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;基於不破梗不爆雷原則，不便直接透露五糾結、五方向、五表單的內容，我只徵引一些最有感的類似觀點，作為呼應。&lt;/p&gt;
&lt;h2 id=&#34;很多人並沒打算玩真的&#34;&gt;很多人並沒打算玩真的&lt;/h2&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/05/self-change-2.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/05/self-change-2.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Joe 說：「『不做為』本身也是一種作為；不要到了被迫改變時才改變。」&lt;/p&gt;
&lt;p&gt;這跟《&lt;a href=&#34;https://www.books.com.tw/products/0010729881&#34;&gt;大人學選擇&lt;/a&gt;》 pp. 265&amp;ndash;266 說的「及時的責任」一樣：「大部分的人更該擔心的，是不選擇，眼睜睜地看著狀況越來越惡化，如同溫水煮青蛙般的『慢性選擇消失問題』。」&lt;/p&gt;
&lt;h2 id=&#34;所有選擇都有代價&#34;&gt;所有選擇都有代價&lt;/h2&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/05/self-change-3.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/05/self-change-3.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Joe 說：「請先盤點思考：我願意犧牲什麼？」&lt;/p&gt;
&lt;p&gt;這跟《&lt;a href=&#34;https://www.books.com.tw/products/0010729881&#34;&gt;大人學選擇&lt;/a&gt;》 pp. 19&amp;ndash;20 說的「原則四：預想最壞的情況會怎麼樣，並預作準備」道理一樣：「當你連最壞的狀況都想過一輪時，代表你對這項選擇也做好了全方位的規劃。後續執行時的順暢度，其實也會跟著大幅提升。」&lt;/p&gt;
&lt;h2 id=&#34;意志會耗盡&#34;&gt;意志會耗盡&lt;/h2&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/05/self-change-4.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/05/self-change-4.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;市面上一堆《&lt;a href=&#34;https://www.books.com.tw/products/0010326543&#34;&gt;先別急著吃棉花糖&lt;/a&gt;》、《&lt;a href=&#34;https://www.books.com.tw/products/0010555281&#34;&gt;輕鬆駕馭意志力&lt;/a&gt;》、《&lt;a href=&#34;https://www.books.com.tw/products/0010867931&#34;&gt;恆毅力&lt;/a&gt;》書籍，不斷鼓吹並販賣「提升意志力」的秘方。不過，Joe 的這句話，有如當頭棒喝：「意志力就像電池，是有限資源。」&lt;/p&gt;
&lt;p&gt;的確，日常生活的種種重要／不重要、急迫／不急迫的事，在在都在消耗我們的意志力。我們該選擇對抗天性，還是選擇順從天性？&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/05/self-change-5.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/05/self-change-5.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Joe 說：「最好的忍耐，是不忍耐；最好的判斷，是不判斷。」&lt;/p&gt;
&lt;p&gt;聽到這裡，突然領悟到許多專案管理方法，之所以講究以簡馭繁，就是這個道理。像 Scrum 限縮 Sprint Backlog，就是為了避免面臨無盡的選擇、插單的誘惑、父子騎驢的判斷，白白消耗團隊的意志力。&lt;/p&gt;
&lt;p&gt;意志力，是有限資源，請好好保護它，請善用它滿格的黃金時刻。&lt;/p&gt;
&lt;h2 id=&#34;不叫我們遇見試探&#34;&gt;不叫我們遇見試探&lt;/h2&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/05/self-change-6.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/05/self-change-6.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;論語泰伯篇：「危邦不入，亂邦不居。」&lt;/p&gt;
&lt;p&gt;新約主禱文：「不叫我們遇見（陷入）試探。」&lt;/p&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010780469&#34;&gt;你要如何衡量你的人生？&lt;/a&gt;》 pp. 242&amp;ndash;244 說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;百分之百的堅持，要比百分之九十八來得容易。&lt;/p&gt;
&lt;p&gt;我發覺要抗拒「就這麼一次，下不為例」的誘惑，其實是我這一生最大的決定。為什麼？因為人生總有許許多多的情況要你妥協，讓你有「身不由己」之感，然而只要出現一次「下不為例」，總會再出現另一個「下不為例」。萬一我這次跨越界線，往後就會不斷出界。如果你不越界，個人道德界線的力量將非常強大。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這道理，對個人適用，對團隊適用，對組織一樣適用。&lt;/p&gt;
&lt;p&gt;由此也可看出為什麼 Scrum 發明人在《&lt;a href=&#34;https://www.books.com.tw/products/0010647604&#34;&gt;告別瀑布，擁抱敏捷&lt;/a&gt;》書中苦口婆心說出一段貌似專制頑固的論調：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scrum 不是可以被隨意修改來迎合既有企業文化的流程，反而是應該調整企業文化來適應 Scrum。&lt;/p&gt;
&lt;p&gt;在 Scrum 中，阻礙軟體開發方式的文化障礙將無所遁形。如果沒有用 Scrum 來建立敏捷、透明的開發環境，那隱藏的問題將會一直留在企業內損害企業的利益，那就失去了使用 Scrum 最主要的好處。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kanban 的 WIP 設計，是一種隔絕誘惑的方法。Scrum 的 sprint timebox 設計，也是一種隔絕誘惑的方法。&lt;/p&gt;
&lt;p&gt;請設計聰明的隔絕誘惑、逃離誘惑的方法。&lt;/p&gt;
&lt;h2 id=&#34;內心的自動導航機制&#34;&gt;內心的自動導航機制&lt;/h2&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/05/self-change-7.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/05/self-change-7.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Joe 引述《&lt;a href=&#34;http://www.books.com.tw/products/0010560033&#34;&gt;為什麼我們這樣生活，那樣工作？&lt;/a&gt;》書中提出的「習慣迴路」理論，提供一些破除舊習慣、養成新習慣的自動導航機制，讓「心中善良而任性的小孩」可以整合對齊。&lt;/p&gt;
&lt;p&gt;Joe 說：「習慣不能改，只能覆蓋。」&lt;/p&gt;
&lt;p&gt;不過，整個誘因建構三部曲「提示」→「行為」→「期待獎勵」當中，起手式「提示」的關鍵，仍在於自我察覺力。看起來，就像任何觸及心靈的手法，「自我察覺力」仍是非常重要的鍛鍊。&lt;/p&gt;
&lt;h2 id=&#34;兩個月的作業&#34;&gt;兩個月的作業&lt;/h2&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/05/self-change-8.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/05/self-change-8.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這是一門值得好好沈澱，對自己許下承諾的課。&lt;/p&gt;
&lt;p&gt;希望兩個月後回頭來看，能在某些地方邁入良性的自動導航系統。在自己身上，在家人身上，在團隊身上。&lt;/p&gt;
&lt;p&gt;「做自我的改變，跟買 3C 產品一樣，早買早享受！」&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>六日薩提爾體驗</title>
      <link>//william-yeh.net/post/2017/04/satir-workshop/</link>
      <pubDate>Wed, 19 Apr 2017 16:14:28 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2017/04/satir-workshop/</guid>
      
        <description>&lt;p&gt;在團隊帶領時，總是會遇到許多需要訴諸軟技巧的時刻，尤其是&lt;strong&gt;引導&lt;/strong&gt; (&lt;strong&gt;facilitation&lt;/strong&gt;)。&lt;/p&gt;
&lt;p&gt;雖然上了一些課，閱讀一些書籍，也親自實驗帶了一些引導活動（過程請見〈&lt;a href=&#34;http://school.soft-arch.net/blog/362540/2016-retrospective&#34;&gt;2016 個人回顧&lt;/a&gt;〉及〈&lt;a href=&#34;http://school.soft-arch.net/blog/379078/appreciative-inquiry&#34;&gt;欣賞式探詢&lt;/a&gt;〉文章），但總覺得少了一塊很重要的成分。&lt;/p&gt;
&lt;p&gt;一塊說不上來的成分。&lt;/p&gt;
&lt;p&gt;同溫層族人常會推薦 &lt;a href=&#34;https://sites.google.com/site/icataiw/courses-and-activities&#34;&gt;ICA Taiwan 的課&lt;/a&gt;（像 David Ko 的這篇&lt;a href=&#34;https://kojenchieh.pixnet.net/blog/post/448165655-ica-taiwan-%E4%B8%8A%E8%AA%B2%E5%BF%83%E5%BE%97%E6%84%9F%E6%83%B3&#34;&gt;推坑文&lt;/a&gt;及 Yves Lin 的這篇&lt;a href=&#34;https://funevo.com/2015/07/07/scrum-master-job-facilitation-gong-zuo-yin-dao/&#34;&gt;推坑文&lt;/a&gt;），但私心認為，現階段的自己最需要的，並非那些直接就派得上用場的各式各樣的引導技巧，而是可能沒辦法直接就派得上用場的&lt;strong&gt;薩提爾&lt;/strong&gt;心法。&lt;/p&gt;
&lt;h2 id=&#34;why-satir&#34;&gt;Why Satir?&lt;/h2&gt;
&lt;p&gt;組織，其實和個人一樣，都有行為、應對姿態，都有感受、感受的感受、觀點，也都有期待、渴望，甚至自我——都有各層次的&lt;strong&gt;冰山&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;冰山如此，改變歷程亦如此。還沒如實看到冰山：自己的冰山、別人的冰山，就奢談馬斯洛層級、變革管理、引導或領導，似乎有點太跳躍了。&lt;/p&gt;
&lt;p&gt;我想認真學習如何探索冰山。我在〈&lt;a href=&#34;http://school.soft-arch.net/blog/362540/2016-retrospective&#34;&gt;2016 個人回顧&lt;/a&gt;〉一文也預告過，我想上體驗課程，親自體會箇中幽微之處。&lt;/p&gt;
&lt;p&gt;既然要上課，就要上源頭的。儘管我是從陳茂雄的《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;激發員工潛力的薩提爾教練模式&lt;/a&gt;》一書開始接觸到薩提爾模式，但是，我不想把經驗限縮於職場場域——那是很可惜的事。&lt;/p&gt;
&lt;p&gt;因此，我參加陳桂芳老師在&lt;a href=&#34;https://www.shiuhli.org.tw/&#34;&gt;旭立文教&lt;/a&gt;帶領的 3+3 天薩提爾之旅。&lt;/p&gt;
&lt;p&gt;異常充實超值的六天。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/04/satir-workshop-1.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/04/satir-workshop-1.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;引導&#34;&gt;引導&lt;/h2&gt;
&lt;p&gt;此行主要目的並非觀課，但是職業病使然，不自覺就會側面觀察：第一天，一群陌生人，該如何破冰，讓大家逐漸充分敞開，而且是敞開幽微敏感的內心？&lt;/p&gt;
&lt;p&gt;超神奇的，能一下子就把四十人充分混搭到充分對談的地步！&lt;/p&gt;
&lt;p&gt;中間肯定是有技巧的，可是，一切的觸媒仍在於「&lt;strong&gt;與人接觸&lt;/strong&gt;」。&lt;/p&gt;
&lt;p&gt;這正是薩提爾模式美妙之處，充滿安全及信賴的接觸情境。&lt;/p&gt;
&lt;h2 id=&#34;不怕千招會就怕一招精&#34;&gt;不怕千招會，就怕一招精&lt;/h2&gt;
&lt;p&gt;教室走廊有一幅掛圖，清楚展示薩提爾手法的豐富性：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/04/satir-workshop-2.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/04/satir-workshop-2.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;說實在的，來上課前，心中的確抱著一絲期待，期待能夠盡量體驗到越多手法越好，滿足好奇心。&lt;/p&gt;
&lt;p&gt;可是，老師其實並沒有急於把每一招都展示出來，而是保持彈性，依循現場的情境與動力，仔細帶出特定手法的幽微細節：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;基礎篇的三天，我們體驗了生存姿態、冰山、家庭雕塑、一致性溝通。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;應用篇的三天，再加入家庭圖、影響輪、內在資源。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果純粹以帳面上的數量來說，六天課程，體驗了七大手法。但事實上，貫串所有活動的最核心手法，就是&lt;strong&gt;冰山&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;冰山，可說是知己、知人，與己和、與人和的重要關鍵。&lt;/p&gt;
&lt;p&gt;六天課程，一次次的個案分析演練，某種意義上，算是專注把「冰山」這一招練到銘印心坎的程度。回頭反思，這也算是繞開我當初表層的「期待」，直接訴諸更底層的「渴望」。&lt;/p&gt;
&lt;p&gt;也算是一種「未滿足的期待」的轉化吧。&lt;/p&gt;
&lt;h2 id=&#34;雕塑&#34;&gt;雕塑&lt;/h2&gt;
&lt;p&gt;以前在看相關書籍時，就對薩提爾招牌的「&lt;strong&gt;雕塑&lt;/strong&gt;」手法十分好奇。但也不禁懷疑：真有那麼神奇嗎？&lt;/p&gt;
&lt;p&gt;真的要親臨現場，才能體會到雕塑的震撼。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:10em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/04/satir-workshop-3.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/04/satir-workshop-3.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;現場學員，活生生的第一手家庭雕塑，令人戰慄。&lt;/p&gt;
&lt;p&gt;沒想到，原生家庭的影響，居然如此深遠。四種生存姿態，真的就像系統思考領域所講的系統基模，在許多個案中反覆出現。&lt;/p&gt;
&lt;p&gt;案頭一堆薩提爾個案書，果然是真的，雕塑過程的現場動力，果然也是真的。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/04/satir-workshop-4.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/04/satir-workshop-4.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;



&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/04/satir-workshop-5.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/04/satir-workshop-5.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;望著雕塑，望著冰山，著力點要放在哪裡，會自然浮現出來。也深深體會到，每個人都有多種應對的選擇，不要被環境命定論自我設限了。&lt;/p&gt;
&lt;p&gt;老師的結語：「一致性溝通，本身就是一項冒險。選擇在你自己。」&lt;/p&gt;
&lt;h2 id=&#34;自己的冰山&#34;&gt;自己的冰山&lt;/h2&gt;
&lt;p&gt;第五天，有一項課後作業：畫自己的家庭圖及影響輪。&lt;/p&gt;
&lt;p&gt;當下還無異狀。但下課返家途中，莫名有一股說不出來的悶悶抑鬱感。這才驚覺：18歲之前 vs 18歲之後的冰山，挖呀挖，好像觸碰到某個一直不敢直接承認的脆弱之處。也算是⋯⋯嗯，隱藏得連自己都看不太到。&lt;/p&gt;
&lt;p&gt;或許正如 Maria Gomori 在《&lt;a href=&#34;https://www.books.com.tw/products/0010433582&#34;&gt;心靈的淬鍊&lt;/a&gt;》所說：「雕塑可能在主角身上引發不同於平常的意識狀態 (altered state)。」&lt;/p&gt;
&lt;p&gt;悶悶狀態長達六個小時。睡前趕緊寫冰山筆記，隔天課堂小組分享，才得到些許紓解。&lt;/p&gt;
&lt;p&gt;也對自己做了個重要的選擇。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;一連串家庭圖、影響輪、內在資源轉化下來，有種能量充滿的感覺——不靠催眠也做得到。&lt;/p&gt;
&lt;p&gt;過程中也才發現，自己的冰山居然有這麼多隱而未現的東西。自己如此，遑論別人了。難怪薩提爾手法中，不斷強調帶著偵探帽，要邀請，要核對求證。&lt;/p&gt;
&lt;p&gt;六日薩提爾體驗，看別人雕塑及冰山的同時，其實也在看自己。幸虧走了這一遭，打通了閱讀之「腦」到體驗之「心」的路徑。&lt;/p&gt;
&lt;h2 id=&#34;身體學會的誰也拿不走&#34;&gt;身體學會的，誰也拿不走&lt;/h2&gt;
&lt;p&gt;經過整整六天的薩提爾洗禮，回頭看這些書，尤其是裡面的個案及雕塑過程，點頭如搗蒜。&lt;/p&gt;
&lt;p&gt;像《&lt;a href=&#34;https://www.books.com.tw/products/0010405288&#34;&gt;薩提爾成長模式的應用&lt;/a&gt;》前言有一句話：「重點不是口述出來的 “問題” 或 “故事線”，而是案主做了些什麼，來回應他們眼中的 “問題”。」以前會理所當然的一眼瞄過去，現在，則是浮現出栩栩如生的雕塑角色的立體圖像，演將出來，共舞，共鳴。&lt;/p&gt;
&lt;p&gt;回頭看陳茂雄的《&lt;a href=&#34;https://williampjyeh.notion.site/3e31bb4af3d74007bc0e522e268019c0&#34;&gt;激發員工潛力的薩提爾教練模式&lt;/a&gt;》，突然發現，許多以前標注的想要記憶的重點，似乎不太需要主動去記憶了。果然，身體學會的，誰也拿不走。這就是體驗式課程的威力。&lt;/p&gt;
&lt;p&gt;就連與薩提爾模式無關的《&lt;a href=&#34;https://www.books.com.tw/products/0010647956&#34;&gt;克服團隊領導的五大障礙&lt;/a&gt;》，再回頭看，就完全理解作者的施力點是在哪裡了。&lt;/p&gt;
&lt;p&gt;果然，上課，就要上溯源的。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;不僅書本看得更懂了，言談舉止也受到影響。&lt;/p&gt;
&lt;p&gt;回到工作崗位 facilitate 團隊時，回到家庭面對柴米油鹽醬醋茶時，居然也有一點點 桂芳老師 的習慣用語、引導提示語上身（只是⋯⋯稍微再陽剛一點點，哈）。&lt;/p&gt;
&lt;p&gt;對於團隊的耐心也提升了。像在 Sprint Planning 時，面對某個可預見的失敗，我居然會刻意不介入。有時候，要讓當事人用肉身感受到痛，激發底層的期待，甚至渴望，才有撼動觀點或規條的機會。畢竟，在可控制的風險下，不介入混亂的發生，也是薩提爾改變歷程中，鬆動觀點，賦予當事人自覺、擔起選擇責任的重要觸媒。&lt;/p&gt;
&lt;p&gt;我也察覺到自己慣用的 &lt;a href=&#34;https://kojenchieh.pixnet.net/blog/post/443600072-orid%E7%A2%8E%E7%A2%8E%E5%BF%B5-%283%29-%E7%84%A6%E9%BB%9E%E8%A8%8E%E8%AB%96%E6%B3%95%E9%87%8D%E9%BB%9E%E6%95%B4%E7%90%86&#34;&gt;ORID&lt;/a&gt; 引導手法中，似乎只觸及到行為、感受、觀點層次。有機會的話，想嘗試再下探一兩層。嗯，是挑戰，但值得一試。&lt;/p&gt;
&lt;h2 id=&#34;實體課程要的是什麼&#34;&gt;實體課程要的是什麼？&lt;/h2&gt;
&lt;p&gt;親炙這些一流的體驗式課程，後遺症是，想腰斬一些自認難以做到這種境界的演講及課程了。從文字圖像及影片就吸收得了的內容，似乎也不值得輪到我來講了。&lt;/p&gt;
&lt;p&gt;在這個書籍、文章、教學視頻、線上課程，甚至 webinar 直播充斥的年代，實體課程還能夠吸引得了人，就是要提供獨特的互動經驗：講者與學員之間的互動，甚至學員彼此之間的協作互動。&lt;/p&gt;
&lt;p&gt;這一年來深深的體會。&lt;/p&gt;
&lt;p&gt;給自己立的期許是：演講及課程，要做到不只撼動到行為及觀點層次，更要下探期待及渴望。&lt;/p&gt;
&lt;p&gt;自我期許，要精熟三項道具：便利貼，卡片，樂高積木。&lt;/p&gt;
&lt;p&gt;自認目前較接近預期境界的，只有近日即將公告的【&lt;a href=&#34;http://get.soft-arch.net/agile-workshop/&#34;&gt;敏捷原理與團隊塑造&lt;/a&gt;】吧。&lt;/p&gt;
&lt;h2 id=&#34;交融&#34;&gt;交融&lt;/h2&gt;
&lt;p&gt;一年前的自我期許：「&lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/&#34;&gt;左腦高德拉特，右腦薩提爾&lt;/a&gt;」，如今兩者總算開始加速融合。&lt;/p&gt;
&lt;p&gt;相隔三週，接連上了六天薩提爾體驗課，突然想從網路問答中撤退。面對面時，連別人的冰山都不見得探索得到，遑論網路上？別再與世界爭辯了，把能量放在活生生的與人接觸吧。&lt;/p&gt;
&lt;p&gt;三天基礎篇、三天應用篇的薩提爾之旅，很深沉的觸動與悸動。如果你也想體會一下知己、知人，與己和、與人和，就給自己一個冒險的機會吧！&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/04/satir-workshop-6.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/04/satir-workshop-6.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;
&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      薩提爾課程 - 系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 六日薩提爾體驗&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2017/08/facilitator-mindset/&#34;&gt;引導者，要懂心理&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>CSPO，超越收據的收穫</title>
      <link>//william-yeh.net/post/2017/03/cspo/</link>
      <pubDate>Wed, 08 Mar 2017 14:52:29 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2017/03/cspo/</guid>
      
        <description>&lt;h2 id=&#34;為什麼要去上-scrum-認證課程&#34;&gt;為什麼要去上 Scrum 認證課程？&lt;/h2&gt;
&lt;p&gt;去年 Q4 起，在有限的職權範圍內，小規模試行敏捷轉型。一路走來，自認在 Scrum 這一塊還有很多不足之處，想親炙這領域的先行者，以印證自己摸索的心得，並解決思考及實踐上的盲點。&lt;/p&gt;
&lt;p&gt;上課，是一條捷徑。&lt;/p&gt;
&lt;p&gt;因此，看到 Terry Wang 的〈&lt;a href=&#34;https://wangterryonagile.blogspot.tw/2016/11/scrum-alliance-certificate.html&#34;&gt;Scrum Alliance 的 certificate&lt;/a&gt;〉一文，我開始對 Scrum 認證課程感興趣。&lt;/p&gt;
&lt;p&gt;證照（「收據」）不是目的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;其實認證只是一份收據，他不會幫你加薪，不要為了拿而拿。&lt;/p&gt;
&lt;p&gt;收據真的只是其次，這些課程都是世界級的，滿滿的都是知識，只是看每個人能拿多少回家。&lt;/p&gt;
&lt;p&gt;再次強調，認證只是收據，不要為了拿而拿，是為了去跟大師學習。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至於那些所謂的「收據」，我倒是不需要了。反正又不是自己要開課教人考證照。&lt;/p&gt;
&lt;h2 id=&#34;為什麼要去上-cspo-課程&#34;&gt;為什麼要去上 CSPO 課程？&lt;/h2&gt;
&lt;p&gt;那麼，接下來的問題是：要去上哪一門課呢？CSM？CSPO？CSD？&lt;/p&gt;
&lt;p&gt;Terry 的文章，讓我嚇了一跳：我完完全全誤會了，原來 CSD 比 CSM 及 CSPO 還難拿到呀。&lt;/p&gt;
&lt;p&gt;原本以為，像 Scrum Master 這種帶點 coach 性質的人，養成教育應該更難才是。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;撇開其他因素，純以自己的需求來評估。&lt;/p&gt;
&lt;p&gt;身為一個技術人，CSM 或 CSD 似乎是首選？&lt;/p&gt;
&lt;p&gt;但是，突然覺得，現階段的自己，好像比較需要去上 CSPO 的課，才能用 PO 的語言去 facilitate PO。&lt;/p&gt;
&lt;p&gt;至於 to facilitate/coach developer 一事，本來就是自己的守備區，也一直在做了。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;其實，在軟體研發這一行，developer 畢竟是第一線執行者，很容易就吸收 PMP 的 planning/executing/monitoring/controlling 觀念（但對於繁文縟節則敬而遠之），或 Scrum 及 Kanban 這種輕量級的風格。&lt;/p&gt;
&lt;p&gt;反倒是 PO，擅長的是發想願景，不見得擅長執行面。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/03/tweet-20170105.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/03/tweet-20170105.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

  &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/817019005059796992&#34;&gt;2017-01-05 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;難怪有兩種 PM：PdM (product manager) &amp;amp; PjM (project manager)。&lt;/p&gt;
&lt;p&gt;畢竟，個別來看，單單在「行腳商人」及「總管」這兩個圈圈裡努力奮鬥，都不見得做得到位了，遑論 PdM 及 PjM 跨界合體，身兼兩者之長。&lt;/p&gt;
&lt;p&gt;職場生涯中，我就親眼看到一大堆沒有 PjM 觀念的 PdM 把優秀工程師逼走的血淋淋實例。尤其是根本就沒有 CSPO 心態的 PdM。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;教育 PO，比教育 developer 難。&lt;/p&gt;
&lt;p&gt;你覺得賈伯斯是容易被教育的嗎？&lt;/p&gt;
&lt;p&gt;所以，我才要去上 CSPO 課⋯⋯&lt;/p&gt;
&lt;p&gt;如果只從 Scrum Master 角度出發，想去 facilitate PO，小缺點就是，會只被當成 project manager。優先序一出現衝突狀況，會被質疑沒有 product manager 或 portfolio manager 的高度。&lt;/p&gt;
&lt;p&gt;因此，對於那些沒有 PMP 也沒有 Scrum 也沒有 Kanban 觀念的 PO，先換位思考，用他們的語言說話，（或許）才比較容易 facilitate 他們。&lt;/p&gt;
&lt;h2 id=&#34;換位思考&#34;&gt;換位思考&lt;/h2&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/03/cspo-members.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/03/cspo-members.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;上 &lt;a href=&#34;https://www.scrumalliance.org/community/profile/ylv&#34;&gt;呂毅&lt;/a&gt; 老師的 CSPO 課程，最大的體悟是「強制換位思考」。尤其是 &lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%91%A8%E5%93%88%E9%87%8C%E7%AA%97&#34;&gt;Johari Window&lt;/a&gt;，是很有必要的。&lt;/p&gt;
&lt;p&gt;「Sprint review 的重點，不是 demo working software。」這一金句，也真的是顛覆我的成見。&lt;/p&gt;
&lt;p&gt;“Learning” 的確是整個 sprint 從頭到尾都一直在持續發生的，尤其是想當然爾全程都積極參與的 Scrum Master 及 developers。只是，該 &amp;ldquo;learning&amp;rdquo; 的，可不止這些人，而是所有 stakeholders。而且，某些 stakeholders 只會在某些 event 才有較高機率有義務出席——sprint review 就是這樣的表定 event。&lt;/p&gt;
&lt;p&gt;所以，對這些有義務出席 sprint review 的 stakeholders 來說，出席這個 event 的&lt;strong&gt;重點&lt;/strong&gt;是什麼？&lt;/p&gt;
&lt;p&gt;大概就是朝這個方向思考吧。甚至，整個 sprint 過程中，PO 也應該以此作為首要關注點，不要微管理。&lt;/p&gt;
&lt;p&gt;果然還是需要換位思考。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/03/cspo-worksheet.jpg&#34; alt=&#34;Worksheet in CSPO course&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/03/cspo-worksheet.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Worksheet in CSPO course&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;po-真的有自覺嗎&#34;&gt;PO 真的有自覺嗎？&lt;/h2&gt;
&lt;p&gt;現場觀察，及老師回憶，來上 CSPO 課的，的確以工程師居多。&lt;/p&gt;
&lt;p&gt;所以，可以想見，兩天醍醐灌頂後，回到工作場域，許多沒有職位權的人，將面對極大的不匹配及無力感。&lt;/p&gt;
&lt;p&gt;所以，權位以外的影響力，真的很重要。&lt;/p&gt;
&lt;p&gt;所以，憲哥的書，華倫班尼斯的書，大人學的課，請多多自我預備吧。這是當場我給同學們的小小建議。&lt;/p&gt;
&lt;p&gt;否則，找機會讓遠來牧師去貴公司講道吧。畢竟，耶穌說：「我實在告訴你們：沒有先知在自己家鄉被人悅納的。」&lt;/p&gt;
&lt;h2 id=&#34;跨界拼圖&#34;&gt;跨界拼圖&lt;/h2&gt;
&lt;p&gt;人生首張&lt;a href=&#34;https://www.scrumalliance.org/community/profile/pyeh2&#34;&gt;證照&lt;/a&gt;，當生日禮物。&lt;/p&gt;
&lt;p&gt;而且，某種意義上，也算小小的跨界。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2017/03/cspo-certificate.jpg&#34; alt=&#34;CSPO Certificate&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2017/03/cspo-certificate.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;CSPO Certificate&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;上完課之後的感想是：果然應該要來上 CSPO 課，拼圖才完整。&lt;/p&gt;
&lt;p&gt;也成功推坑幾位同事，擴大盟友。&lt;/p&gt;
&lt;p&gt;更令我開心的是，超強的同事，已經開始運用這兩天上課學到的東西了。&lt;/p&gt;
&lt;p&gt;被 CSPO 課程洗腦後，再看一些沒有用 &lt;a href=&#34;https://www.impactmapping.org/&#34;&gt;Impact Mapping&lt;/a&gt; 結構表述的產品藍圖，就覺得層次不足，漏洞百出。&lt;/p&gt;
&lt;p&gt;重點是層次，不是形式。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;上了兩天 CSPO 課，與一些已經浸潤於 Scrum 協作環境的大江南北英雄英雌共同演練，心中真是無限感觸。&lt;/p&gt;
&lt;p&gt;我是努力用理性推導，小步試行（還從許多其他領域偷渡觀點及作法），別人卻是早已像呼吸一樣，相忘於江湖。&lt;/p&gt;
&lt;p&gt;感覺很像當年，我是去學習 PMP 觀念，別人則是去複習他們早就每天都在做的事。&lt;/p&gt;
&lt;p&gt;這就是差距。&lt;/p&gt;
&lt;p&gt;這差距，就要靠軟功夫及硬功夫去彌補了。&lt;/p&gt;
&lt;h2 id=&#34;不能逃避的責任&#34;&gt;不能逃避的責任&lt;/h2&gt;
&lt;p&gt;現在完全能夠體會 Terry 說的「假如你真的有興趣，去上課，拿到了收據，我認為你對台灣的軟體產業有一份責任，你需要把台灣的軟體產業變得更好，因為你是先知先覺者。」&lt;/p&gt;
&lt;p&gt;這是我們的責任。&lt;/p&gt;
&lt;p&gt;說好了要一起變強。加油吧！&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>打怪升級路線圖</title>
      <link>//william-yeh.net/post/2016/12/game-frame/</link>
      <pubDate>Tue, 27 Dec 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/12/game-frame/</guid>
      
        <description>&lt;h2 id=&#34;遊戲化&#34;&gt;遊戲化&lt;/h2&gt;
&lt;p&gt;我第一次看到將「遊戲化」概念運用到職場上的點子，是在《&lt;a href=&#34;http://www.books.com.tw/products/0010548535&#34;&gt;加入遊戲因子，解決各種問題&lt;/a&gt;》這本有趣的書：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/12/game-frame.jpg&#34; alt=&#34;遊戲的十個組成要素&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/12/game-frame.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;遊戲的十個組成要素&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;第二次看到將「遊戲化」概念運用到職場上的點子，是在《&lt;a href=&#34;http://www.books.com.tw/products/0010641668&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;》書中看到的「&lt;a href=&#34;http://career.1111.com.tw/careerroute/intro.aspx&#34;&gt;職能路線圖&lt;/a&gt;」，猶如 RPG 遊戲的打怪升級路線，從等級 1 一路打到等級 11：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/12/career-route.jpg&#34; alt=&#34;職能路線圖&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/12/career-route.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;職能路線圖&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;第三次看到將「遊戲化」概念運用到職場上的點子，是在 Bryan 的【&lt;a href=&#34;//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/&#34;&gt;A101 職場大人學：職場人際關係與優勢策略&lt;/a&gt;】課堂上，學到如何巧妙運用新世代的特質來設計遊戲規則：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/12/comm-with-younger.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/12/comm-with-younger.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;還有那張所謂的「集點卡」：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/12/a101-career.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/12/a101-career.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;與「遊戲化」三度接觸後，儘管我還沒參加 Bryan 的【&lt;a href=&#34;https://www.darencademy.com/activity/view/id/16426&#34;&gt;大人學講座09：用遊戲思維規劃你的職涯策略&lt;/a&gt;】，但也已經激發出許多可以派得上用場的想法了。&lt;/p&gt;
&lt;p&gt;其中一個想法，簡單來說，就是準備一份「&lt;strong&gt;打怪升級路線圖&lt;/strong&gt;」。&lt;/p&gt;
&lt;h2 id=&#34;個人與團隊&#34;&gt;個人與團隊&lt;/h2&gt;
&lt;p&gt;打怪升級路線圖，好處多多。&lt;/p&gt;
&lt;p&gt;第一個好處，當然是針對自己，檢視自己在工匠、總管、行腳商人這三大屬性中，還要打什麼怪、練什麼功、衝什麼裝備。&lt;/p&gt;
&lt;p&gt;第二個好處，是在團隊領導上。&lt;/p&gt;
&lt;p&gt;正如《&lt;a href=&#34;http://www.books.com.tw/products/0010641668&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;》書中提到的：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/12/team-radar.jpg&#34; alt=&#34;團隊現況雷達圖&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/12/team-radar.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;團隊現況雷達圖&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;雖然我的職責範圍是帶領工程團隊，理應只需顧好「工匠」路線，但正如我在〈&lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;〉一文闡述的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;專業工作者，除了精進本職學能之外，我認為，還需要致力掌握適當的工作分解／拆解技能。&lt;/p&gt;
&lt;p&gt;工作分解／拆解，並不只是專案經理的責任，而是實際執行者也必須參與的。這也是專業工作者的責任區。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;老實說，敏捷開發追求的「自組織團隊」境界，對工程師的要求是很高的。身為工程團隊的主管，很有必要擬定一份「打怪升級路線圖」，界定各職等該有的專業技能及專業態度，團隊才有方向感，也才有人資層面的操作依據。&lt;/p&gt;
&lt;p&gt;萬事起頭難。該如何草擬這麼一份「打怪升級路線圖」呢？&lt;/p&gt;
&lt;p&gt;以軟體研發領域來說，其實有一個滿簡單的切入點。&lt;/p&gt;
&lt;p&gt;先把整個 Scrum cycle 跑完時，每個環節各需要哪些能力及態度，統統列出來，再慢慢去分組歸類。其實，這就已經將一位「工匠」的專業技能及專業態度，都大致涵蓋進來了。&lt;/p&gt;
&lt;p&gt;就以專業技能為例，Scrum 的 &amp;ldquo;definition of done&amp;rdquo; 就是一個不錯的出發點。請想一想，在整個 Scrum cycle 當中，你對每一個職等的人，各有什麼 definition of done 的期許？&lt;/p&gt;
&lt;p&gt;如果你是認真看待每一個職務、職能、職等，你一定找得出一些評估角度。而且，不必強求第一次就訂得完美。&lt;/p&gt;
&lt;p&gt;我這幾天就是用 Scrum + DevOps life cycle 的角度，再搭配參考《&lt;a href=&#34;http://www.books.com.tw/products/0010641668&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;》的「職能路線圖」及「知覺價值」，彙整出一份研發部門的「打怪升級路線圖」。&lt;/p&gt;
&lt;h2 id=&#34;招聘&#34;&gt;招聘&lt;/h2&gt;
&lt;p&gt;「打怪升級路線圖」第三個好處，是在招聘上。&lt;/p&gt;
&lt;p&gt;既然我們對內，都期許團隊有如此水準了，理應有資格以此標準來挑選未來可能共事的人才。&lt;/p&gt;
&lt;p&gt;當然啦，面試現場，我不會真的把這張表格攤開來，請君入甕對號入座。&lt;/p&gt;
&lt;p&gt;我用&lt;strong&gt;情境題&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我會出一些面試前就請對方作答的申論題，問他們對於敝公司產品或服務的看法：好的、可以再改善的、不好的。並針對某幾點提出企劃，說明如果錄取後，可以怎麼協助改善。當然啦，這只是企劃，不是要對方事必躬親；我們招聘的是工程師，他大可選擇只從工程角度提出企劃。&lt;/p&gt;
&lt;p&gt;這種問題，可看出他們做了多少功課，有沒有獨立見解，有沒有 WBS 工作拆解能力。&lt;/p&gt;
&lt;p&gt;反正，就算面試前不問，我也會在面試時問。但，臨場才要對方思考，那就更困難了。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;有人質疑：只是要招聘工程師，出這種題目，會不會太誇張了？&lt;/p&gt;
&lt;p&gt;其實這類問題，其他部門在甄選大三大四實習生時就廣為運用了。我拿來用在招聘正職員工身上，應不為過。&lt;/p&gt;
&lt;p&gt;畢竟，我們不是大公司，沒有本錢只請小螺絲釘；要選既有能力又有熱情，有潛力可以獨當一面的多能技術人。我們也不是需要研發高檔演算法的公司，所以，技術能力，到一個合理地步就夠了。反而是更根本的態度，會決定我們能不能放心把任務交給他。&lt;/p&gt;
&lt;p&gt;尤其是敏捷開發，更是有這種要求。&lt;/p&gt;
&lt;p&gt;所以，先想想自己團隊需要什麼樣的人吧。不同的出發點，會導致不同的面試策略。&lt;/p&gt;
&lt;p&gt;何況，也不是每一題都要作答到滿分。都滿分的話，那就是&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E7%94%98%E9%81%93%E5%A4%AB&#34;&gt;白袍巫師&lt;/a&gt;等級了。&lt;/p&gt;
&lt;h2 id=&#34;進階情境題&#34;&gt;進階情境題&lt;/h2&gt;
&lt;p&gt;最近我也從 &lt;a href=&#34;http://www.books.com.tw/products/0010731512&#34;&gt;appreciative inquiry&lt;/a&gt; 學到一些有趣的探詢角度，搭配心中的「打怪升級路線圖」，面試真的簡單多了。當然啦，那又是另一段故事了⋯⋯&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/12/appreciative-inquiry.jpg&#34; alt=&#34;欣賞式探詢例子&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/12/appreciative-inquiry.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;欣賞式探詢例子&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;種種情境題，目的都是設法蒐集足夠的線索，以在「打怪升級路線圖」給予適當定位。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上簡單介紹最近體會出來的三個「打怪升級路線圖」用途，供大家參考。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>工作分解講座・閱讀材料</title>
      <link>//william-yeh.net/post/2016/11/decomposition-reading-list/</link>
      <pubDate>Wed, 30 Nov 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/11/decomposition-reading-list/</guid>
      
        <description>&lt;h2 id=&#34;緣起&#34;&gt;緣起&lt;/h2&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2016/10/one-week-sprint/&#34;&gt;One-Week Sprint 的節奏&lt;/a&gt;〉一文提到個人的「迷你版 Scrum」首航經驗：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;第一個 sprint 順利達標，儘管變數層出不窮。&lt;/p&gt;
&lt;p&gt;萬萬沒想到第一次嘗試帶 Scrum，而且是「1 舊人 + 2 新人」的高風險組合，就很有機會實現。除了天時地利人和的配合，&lt;strong&gt;事先認真的 WBS 分析&lt;/strong&gt;，應是重要因素。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;後來幾個 sprints，大體上也都順利達到 due-date performance。回顧經驗，我仍然認為「事先認真的 WBS 分析」是重要因素。&lt;/p&gt;
&lt;p&gt;所以，當我想將成功經驗推廣到其他專案上面，有一個重要的前置作業，就是灌輸全員 &lt;strong&gt;decomposition 意識&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;要以「WBS + activity」為單位，還是以「user story + task」為單位，我並沒有強制規定（也不是現階段的重點）。但其中的 decomposition 意識，則必須確實掌握。&lt;/p&gt;
&lt;p&gt;因此，第一步，我先召集大家玩一次〈&lt;a href=&#34;//william-yeh.net/post/2016/11/toc-bottleneck-principles/&#34;&gt;TOC 瓶頸處理九大原則&lt;/a&gt;〉，從樂高遊戲中學習；接下來的第二步，嗯，又是我「讀書會」招數派上用場的時機了。&lt;/p&gt;
&lt;p&gt;讀書會的進行方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;活動前：各自閱讀指定材料。&lt;/li&gt;
&lt;li&gt;活動中：搭配 workshop 演練案例，而且是以公司真實的專案為實例，不僅具體，又能直接連結每個人的工作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;這種訓練是很重要的。畢竟，連自己經手過的專案都分解／拆解不出來了，還談什麼後續的 planning poker 呢？&lt;/p&gt;
&lt;p&gt;真實專案 workshop 我打算分兩回合進行。以下僅列出可以公開釋出的閱讀材料，給大家參考。&lt;/p&gt;
&lt;h2 id=&#34;part-i--基本觀念&#34;&gt;Part I / 基本觀念&lt;/h2&gt;
&lt;p&gt;專業工作者，除了精進本職學能之外，我認為，還需要致力掌握適當的工作分解／拆解技能。&lt;/p&gt;
&lt;p&gt;工作分解／拆解，並不只是專案經理的責任，而是實際執行者也必須參與的。這也是專業工作者的責任區。&lt;/p&gt;
&lt;p&gt;這不是我個人的偏見，而是連 &lt;a href=&#34;https://en.wikipedia.org/wiki/Project_Management_Body_of_Knowledge&#34;&gt;PMBOK&lt;/a&gt; 5/e 都如是說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The project manager, &lt;strong&gt;in collaboration with the project team&lt;/strong&gt;, then determines the final decomposition of the project scope into the discrete work packages that will be used to effectively manage the work of the project. (§5.4.2.2)&lt;/p&gt;
&lt;p&gt;Each work package within the WBS is decomposed into the activities required to produce the work package deliverables. &lt;strong&gt;Involving team members&lt;/strong&gt; in the decomposition can lead to better and more accurate results. (§6.2.2.1)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;首先，請先讀讀以下這篇文章，初步了解 WBS (work breakdown structure; 工作分解結構) 的基本觀念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.projectup.net/article/view/id/11609&#34;&gt;PM 的牛肉在哪裡？再談 WBS&lt;/a&gt; (by Bryan)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有餘力的話，可再選讀：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.projectup.net/article/view/id/302&#34;&gt;掌握工作的第一項工具 - WBS 初探&lt;/a&gt; (by Joe)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.projectup.net/article/view/id/305&#34;&gt;專案範疇管理與 WBS 再探&lt;/a&gt; (by Joe)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.projectup.net/article/view/id/306&#34;&gt;交付標的 vs 工作&lt;/a&gt; (by Joe)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;小提醒：「工作分解結構」觀念，不管是古典的 PMP，還是近代流行的 agile、Scrum、Kanban，其實大原則是相通的。讀這幾篇文章時，請留意幾個重點：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Deliverable (用&lt;strong&gt;名詞&lt;/strong&gt;表述) 與 activity (用&lt;strong&gt;動詞片語&lt;/strong&gt;表述) 的劃分。&lt;/li&gt;
&lt;li&gt;逆向拆解。&lt;/li&gt;
&lt;li&gt;100% Rule。&lt;/li&gt;
&lt;li&gt;麥肯錫的 &lt;a href=&#34;http://wiki.mbalib.com/zh-tw/MECE%E5%88%86%E6%9E%90%E6%B3%95&#34;&gt;MECE 原則&lt;/a&gt;（Mutually Exclusive, Collectively Exhaustive），也就是說，WBS 拆解要做到「彼此獨立、毫無遺漏」。此處，「毫無遺漏」是首要重點。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;part-ii--軟體界的工作分解&#34;&gt;Part II / 軟體界的工作分解&lt;/h2&gt;
&lt;p&gt;軟體研發領域，也需要工作分解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href=&#34;https://www.amazon.com/dp/0133853624/ref=cm_sw_r_tw_dp_x_0YceybZM4KKN9&#34;&gt;The Scrum Field Guide&lt;/a&gt;&lt;/em&gt;, Chapter 12: &amp;ldquo;Decomposing Stories and Tasks&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;請留意文章中這句話：“Our sprint length wasn’t the problem. Our ability to decompose work was.” 請思考背後的論述。&lt;/p&gt;
&lt;h2 id=&#34;part-iii--好的-user-story-原則&#34;&gt;Part III / 好的 User Story 原則&lt;/h2&gt;
&lt;p&gt;INVEST 原則簡介&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《&lt;a href=&#34;https://williampjyeh.notion.site/Scrum-0e354b6be58b4977bdd1c99993e79d57&#34;&gt;Scrum：用一半的時間做兩倍的事&lt;/a&gt;》第六章&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;INVEST 原則細說 (by Bill Wake)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;總論: &lt;a href=&#34;http://xp123.com/articles/invest-in-good-stories-and-smart-tasks/&#34;&gt;INVEST in Good Stories, and SMART Tasks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;分論:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://xp123.com/articles/independent-stories-in-the-invest-model/&#34;&gt;&lt;strong&gt;I&lt;/strong&gt;ndependent Stories in the INVEST Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://xp123.com/articles/negotiable-stories-in-the-invest-model/&#34;&gt;&lt;strong&gt;N&lt;/strong&gt;egotiable Stories in the INVEST Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://xp123.com/articles/valuable-stories-in-the-invest-model/&#34;&gt;&lt;strong&gt;V&lt;/strong&gt;aluable Stories in the INVEST Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://xp123.com/articles/estimable-stories-in-the-invest-model/&#34;&gt;&lt;strong&gt;E&lt;/strong&gt;stimable Stories in the INVEST Model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://xp123.com/articles/small-scalable-stories-in-the-invest-model/&#34;&gt;&lt;strong&gt;S&lt;/strong&gt;mall – &lt;strong&gt;S&lt;/strong&gt;calable – Stories in the INVEST Model&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;part-iv--user-story-拆解術&#34;&gt;Part IV / User Story 拆解術&lt;/h2&gt;
&lt;p&gt;一般建議：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;文章: &lt;a href=&#34;https://www.humanizingwork.com/the-humanizing-work-guide-to-splitting-user-stories/&#34;&gt;The Humanizing Work Guide to Splitting User Stories&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;文章: &lt;a href=&#34;https://blogs.itemis.com/en/spidr-five-simple-techniques-for-a-perfectly-split-user-story&#34;&gt;SPIDR – five simple techniques for a perfectly split user story&lt;/a&gt; &amp;amp; &lt;a href=&#34;https://www.mountaingoatsoftware.com/exclusive/spidr-poster-download&#34;&gt;掛圖&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;針對 workflow 的拆解建議：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.mountaingoatsoftware.com/blog/five-story-splitting-mistakes-and-how-to-stop-making-them&#34;&gt;Five Story-Splitting Mistakes and How to Stop Making Them&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;part-v--切到多細&#34;&gt;Part V / 切到多細？&lt;/h2&gt;
&lt;p&gt;User story 及 task 要切到多細，並沒有標準答案。不過，我還是蒐集一下專家們給的建議。&lt;/p&gt;
&lt;p&gt;Scrum 共同發明人 Ken Schwaber 在 &lt;em&gt;&lt;a href=&#34;https://www.amazon.com/dp/0130676349/ref=cm_sw_r_tw_dp_x_6qMpyb2GGAJ2J&#34;&gt;Agile Software Development with Scrum&lt;/a&gt;&lt;/em&gt; 書中建議：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Tasks should have enough detail so that &lt;strong&gt;each task takes roughly four to sixteen hours to finish&lt;/strong&gt;.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://www.amazon.com/dp/B008NAKA5O/ref=cm_sw_r_tw_dp_x_vsMpybSZC8YZY&#34;&gt;Essential Scrum&lt;/a&gt;&lt;/em&gt; 第 19 章建議：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Teams that take this approach typically follow a helpful rule of breaking down tasks so that &lt;strong&gt;no one task is more than eight hours of effort, although some might be a bit larger&lt;/strong&gt;. At this level of granularity the team has a good idea of what really needs to be done and whether it can accomplish those tasks in the time it has available.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://www.amazon.com/dp/0133853624/ref=cm_sw_r_tw_dp_x_0YceybZM4KKN9&#34;&gt;The Scrum Field Guide&lt;/a&gt;&lt;/em&gt; 第 12 章則建議：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Follow the rule that &lt;strong&gt;tasks should be completed in no more than two days&lt;/strong&gt;.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;個人經驗是，努力將 task 切到&lt;strong&gt;不超過 2 個工作天&lt;/strong&gt;的程度，能有效降低專案的不確定性及風險。&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【敏捷的工作分解方法】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2016/10/one-week-sprint/&#34;&gt;One-Week Sprint 的節奏&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 工作分解講座・閱讀材料&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/10/agile-milestone/&#34;&gt;事情做一半，等於沒完成：淺談敏捷的里程碑設定&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;以「蜘蛛法」拆分過於龐大的 User Story&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/08/story-to-tasks/&#34;&gt;很簡單的 Story，也要拆分出 Tasks 嗎？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/11/why-decomposition-matters/&#34;&gt;變動的時代，為什麼工作分解技能更是必備？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>TOC 瓶頸處理九大原則</title>
      <link>//william-yeh.net/post/2016/11/toc-bottleneck-principles/</link>
      <pubDate>Mon, 14 Nov 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/11/toc-bottleneck-principles/</guid>
      
        <description>&lt;p&gt;高德拉特初試啼聲之作《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》，最為人津津樂道的，不外乎是「&lt;a href=&#34;https://www.projectup.net/article/view/id/3124&#34;&gt;聚焦五步驟&lt;/a&gt;」（又稱 &lt;a href=&#34;http://www.tocinstitute.org/five-focusing-steps.html&#34;&gt;POOGI&lt;/a&gt;）及「&lt;a href=&#34;http://wiki.mbalib.com/zh-tw/%E9%BC%93-%E7%BC%93%E5%86%B2-%E7%BB%B3%E6%B3%95&#34;&gt;鼓-緩衝-繩&lt;/a&gt;」(Drum-Buffer-Rope; DBR)。&lt;/p&gt;
&lt;p&gt;此兩者都是流程，都是可立即實施的方法。&lt;/p&gt;
&lt;p&gt;不過，在進入流程之前，有沒有更基本的&lt;strong&gt;現象觀察&lt;/strong&gt;及&lt;strong&gt;原則歸納&lt;/strong&gt;，可讓我們在運用這些流程時，更具方向感，不易走偏？畢竟，不懂原理，貿然盲目依循流程，並不會增加成功機率，反而可能因為不明就裡，不知變通，導致無法排除障礙，進而放棄整套方法。&lt;/p&gt;
&lt;h2 id=&#34;尋找原則&#34;&gt;尋找原則&lt;/h2&gt;
&lt;p&gt;高德拉特在《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》書中，曾藉由鐘納 (Jonah) 之口，對主角羅哥 (Rogo) 說出：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;事實上，為了說明瓶頸和非瓶頸之間的關係以及應該如何管理工廠，我擬定了&lt;strong&gt;九個原則&lt;/strong&gt;。
&amp;mdash; Quote: 《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》 p.222&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可惜的是，翻遍全書，我始終找不到像 1、2、3 這樣清楚條列出來的九原則。連用「原則」關鍵字去搜尋，都湊不滿九個數字。&lt;/p&gt;
&lt;p&gt;因為找不到具體的條列清單，我只能獨自揣測，列出我所以為的「瓶頸處理九大原則」。列出來後，再拿來複習 TOC 體系的聚焦五步驟、DBR、關鍵鏈，甚至非屬 TOC 體系的 Kanban、Scrum、DevOps，都有耳目一新之感。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;本週六我將會在 &lt;a href=&#34;https://www.accupass.com/event/1608300930162091222458&#34;&gt;Agile Tour Hsinchu 2016&lt;/a&gt; 給一場演講〈瓶頸處理九大原則〉。內容有點硬，為了調和，我將源自《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》書中針對 &lt;a href=&#34;http://www.investopedia.com/terms/m/make-to-order.asp&#34;&gt;MTO&lt;/a&gt;/&lt;a href=&#34;http://www.investopedia.com/terms/m/make-to-assemble.asp&#34;&gt;MTA&lt;/a&gt; 而設計的瓶頸遊戲，改編成專案導向環境。一小時的演講，時間有限，這次只能先玩個十分鐘的初級版。&lt;/p&gt;
&lt;p&gt;因為以後還有機會帶人玩這遊戲的進階版，為了避免破梗，影響日後其他人從遊戲中學習的效果，這場演講的投影片就不公開了。如果反應不錯，以後還有的是機會；如果效果不好，那⋯⋯也不值得公開了。&lt;/p&gt;
&lt;p&gt;投影片可以不公開，但「瓶頸處理九大原則」倒是很值得公開。以下僅就《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》中譯版的頁碼順序，列出我所揣測的「瓶頸處理九大原則」，供大家參考。&lt;/p&gt;
&lt;p&gt;仔細揣摩這源自「依存關係」與「統計波動」兩大現象的九大原則，可深化對許多事物的看法。&lt;/p&gt;
&lt;h2 id=&#34;瓶頸處理九大原則&#34;&gt;瓶頸處理九大原則&lt;/h2&gt;
&lt;p&gt;➊ 每個人時時刻刻都在工作的工廠，是非常沒有效率的工廠。 (p.132)&lt;/p&gt;
&lt;p&gt;➋ 我們根本不應該試圖平衡產能，我們反而需要多餘的產能。要平衡流量，而不是產能。 (p.222, p.405)&lt;/p&gt;
&lt;p&gt;➌ 瓶頸不一定很壞，或很好，瓶頸只是你們所要面對的現實罷了。找到瓶頸在哪裡之後，你們必須利用瓶頸來控制通過系統和進入市場的流量。 (p.223)&lt;/p&gt;
&lt;p&gt;➍ 怎麼樣會浪費掉瓶頸的時間呢？其中一個方法就是讓瓶頸在休息時間停工；另外一個方法就是讓瓶頸處理不良的零件，或是讓零件在後來的作業中，因為工人的疏忽或是流程控制馬虎而產生瑕疵；第三個浪費瓶頸時間的方法，就是讓瓶頸處理你們不需要的零件。⋯⋯應該事先就淘汰不良的零件，確定瓶頸只處理沒有問題的零件。 (p.250, pp.253–254)&lt;/p&gt;
&lt;p&gt;➎ 工廠的產能，就等於瓶頸的產能。假如瓶頸損失一小時的生產時間，就等於整個系統損失了一小時。 (p.252, p.363)&lt;/p&gt;
&lt;p&gt;➏ 要如何充分運用瓶頸呢？有兩個主要的原則：首先，絕對不可以浪費瓶頸的時間，應該讓瓶頸只處理對「今天」的有效產出有所貢獻的零件。另外一個方法是，減輕瓶頸的負擔，把部分工作移交給非瓶頸的生產資源。 (pp.253–254)&lt;/p&gt;
&lt;p&gt;➐ 非瓶頸資源的利用程度，並不是完全由其生產潛力來決定，而是由系統中的其他制約因素來決定。 (p.329, p.405)&lt;/p&gt;
&lt;p&gt;➑ 對於通過瓶頸的零件而言，排隊占了大半的時間，因為零件會在瓶頸前面大排長龍，等待瓶頸處理。對於只通過非瓶頸的零件而言，等候則占據了大半的時間，因為它們為了等待從瓶頸來的零件，只好在裝配部前面守候。也就是說，不管在哪一種狀況下，瓶頸都掌控了零件在工廠耗費的時間；換句話說，瓶頸控制了存貨和有效產出。 (p.362, p.406)&lt;/p&gt;
&lt;p&gt;➒ 在非瓶頸設備省下的每個小時都是虛幻的。⋯⋯我們絕對不可以試圖把系統中的每一種資源都發揮到極致。追求局部效益的系統，絕對不是好的系統，而是非常沒有效率的系統。 (p.364, p.406)&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;   &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;(2016-11-19 補充) 應觀眾要求，我將遊戲內容去掉，釋出精簡版投影片，供大家參考。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;//www.slideshare.net/williamyeh/ss-69296400&#34;&gt;瓶頸處理九原則 (精簡版)&lt;/a&gt;&lt;/strong&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/69296400&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h2 id=&#34;後續延伸活動&#34;&gt;後續延伸活動&lt;/h2&gt;
&lt;p&gt;(2017-02-08 補充) 於 Agile Meetup Taipei 發表兩小時加長版：【&lt;a href=&#34;https://www.accupass.com/event/1701170809018766960730&#34;&gt;從限制理論看敏捷開發&lt;/a&gt;】。&lt;/p&gt;
&lt;p&gt;(2017-03-06 補充) 已擴充為四小時的企業內訓版：【敏捷開發與團隊塑造】。意者內洽。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>One-Week Sprint 的節奏</title>
      <link>//william-yeh.net/post/2016/10/one-week-sprint/</link>
      <pubDate>Wed, 26 Oct 2016 00:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/10/one-week-sprint/</guid>
      
        <description>&lt;p&gt;我曾在 iThome 的 &lt;a href=&#34;https://www.ithome.com.tw/tech/88496&#34;&gt;2012 年度必看好書&lt;/a&gt;中，推薦 &lt;em&gt;The Scrum Field Guide&lt;/em&gt;（當年還是&lt;a href=&#34;https://www.amazon.com/dp/0321554159/ref=cm_sw_r_tw_dp_x_-XceybJ2QN98P&#34;&gt;第一版&lt;/a&gt;，現在則有&lt;a href=&#34;https://www.amazon.com/dp/0133853624/ref=cm_sw_r_tw_dp_x_0YceybZM4KKN9&#34;&gt;第二版&lt;/a&gt;了）。當年看這本書時，還沒置身 Scrum 團隊的經驗，純粹是為了未來做準備，所以，對書中講的種種招數，只能默記在心，等待實務印證。&lt;/p&gt;
&lt;p&gt;整本書非常精彩，但最讓我印象深刻的，就是駭人聽聞的 “one-week sprint&amp;quot; 論調：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/10/one-week-sprint.png&#34; alt=&#34;From: The Scrum Field Guide&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/10/one-week-sprint.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;From: The Scrum Field Guide&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;儘管當時不甚理解箇中用意，但我是好學生，一直把 &amp;ldquo;one-week sprint&amp;rdquo; 當成心嚮往之的標竿，日後也不時把所見所聞拿來對照思考。&lt;/p&gt;
&lt;p&gt;日後在職涯接觸了更多流程思維：由 Toyota 引領風潮的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Lean_manufacturing&#34;&gt;Lean Production&lt;/a&gt; 及 &lt;a href=&#34;https://en.wikipedia.org/wiki/Just-in-time_manufacturing&#34;&gt;JIT&lt;/a&gt;、高德拉特的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;TOC&lt;/a&gt;，都強調從 &amp;ldquo;&lt;strong&gt;flow&lt;/strong&gt;&amp;rdquo; 來分析系統。浸潤日久，就比較能理解 &amp;ldquo;one-week sprint&amp;rdquo; 的緣由。這也滿符合大多數地球人的時間感：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你應該建立&lt;strong&gt;工作節奏&lt;/strong&gt;，好讓每個人都容易掌握自己在一段時間內能夠完成多少事，而最後的成果通常會讓他們自己感到訝異。&lt;/p&gt;
&lt;p&gt;    &amp;mdash; Quote: 《&lt;a href=&#34;https://williampjyeh.notion.site/Scrum-0e354b6be58b4977bdd1c99993e79d57&#34;&gt;Scrum：用一半的時間做兩倍的事&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;良善的立意，仍然要有充分的前提佈局及配套措施；不是嘴巴喊喊「我們要搞 one-week sprint」就真的能夠 one-week（天下哪有這麼簡單的事～～～）。&lt;/p&gt;
&lt;p&gt;那麼，&amp;ldquo;one-week sprint&amp;rdquo; 能實現的前提是什麼？&lt;/p&gt;
&lt;p&gt;從最近我第一次實踐 Scrum 的過程中，我發現，答案其實就在 &lt;em&gt;The Scrum Field Guide&lt;/em&gt; 的那一頁。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Decomposition&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;時機&#34;&gt;時機&lt;/h2&gt;
&lt;p&gt;先講講背景故事。&lt;/p&gt;
&lt;p&gt;敝公司的大節奏是以季 (quarter) 為單位。十月份是 Q4 的開始，所以各產品、專案都於此刻開始提出本季的計畫。此為其一。&lt;/p&gt;
&lt;p&gt;我所隸屬的某產品專案，十月中旬，有兩位新人報到並分配到此專案下，此為其二。&lt;/p&gt;
&lt;p&gt;不巧的是，這產品專案，十一月一日，有一位工程師要請增產報國假，所以，要趁著十月份，將工作交接給那兩位新人，此為其三。&lt;/p&gt;
&lt;p&gt;因此，單以十月份來說，在這種「1 位準備交接的舊人 + 2 新人」的高風險組合，要是我不儘早作出較周密的調度規劃，屆時一定慘兮兮。&lt;/p&gt;
&lt;p&gt;以我本身較熟悉的 PMP 訓練、&lt;a href=&#34;https://shop.darencademy.com/product/view/id/1&#34;&gt;101 專案管理一日特訓班&lt;/a&gt;、&lt;a href=&#34;https://shop.darencademy.com/product/view/id/2&#34;&gt;102 流程設計與跨部門溝通&lt;/a&gt;、&lt;a href=&#34;https://shop.darencademy.com/product/view/id/5&#34;&gt;106 動態排程基礎&lt;/a&gt;等課程，都強調 WBS、work package、activity 的層次拆解，critical path 的辨識，以及 milestone 的設置。所以，我打算以自己較有把握的專案管理手法切入，先規劃為期 3 weeks 的 WBS + activities，並每隔一週設一個 milestone。&lt;/p&gt;
&lt;p&gt;思之於此，突然靈機一動：這不正與 &lt;em&gt;The Scrum Field Guide&lt;/em&gt; 的那一頁講的兩大要點「&lt;strong&gt;decomposition&lt;/strong&gt; 與 &lt;strong&gt;one-week sprint&lt;/strong&gt;」若合符節嗎？差別只在於，我原本是以專案管理圈慣用的 &amp;ldquo;deliverable&amp;rdquo; 字眼作為表述單位，而不是以敏捷圈慣用的 &amp;ldquo;user story&amp;rdquo; 字眼；但兩者在 task/activity 層次則是類似的，而且，我也的確將 task/activity 切得夠細了，細到符合 &lt;em&gt;The Scrum Field Guide&lt;/em&gt; 的建議：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Follow the rule that tasks should be completed in no more than two days.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;那麼，現在，我到底要用傳統的專案管理手法來執行這高風險任務，還是⋯⋯&lt;/p&gt;
&lt;p&gt;進而一想：反正我本來就想找機會試行 Scrum 或 Kanban，那麼，擇日不如撞日，何不趁此機會，來一次個人的 Scrum (subset) 首航？&lt;/p&gt;
&lt;p&gt;⋯⋯而且，就一口氣挑戰看看 one-week sprint 吧？&lt;/p&gt;
&lt;h2 id=&#34;盤算&#34;&gt;盤算&lt;/h2&gt;
&lt;p&gt;挑戰之前，還是要先秤秤自己以及團隊有幾兩重。&lt;/p&gt;
&lt;p&gt;兩位新人是我面試的，一位是我研究所學弟，一位出自台灣某敏捷開發聖地的實驗室，對他們的背景及能力，有某種程度的信心。&lt;/p&gt;
&lt;p&gt;至於我自己，要感謝稍早&lt;a href=&#34;https://kojenchieh.pixnet.net/blog&#34;&gt;敏捷三叔公 David Ko&lt;/a&gt; 發起的這個活動，讓我蒐集到一些阻力清單：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://kojenchieh.pixnet.net/blog/post/452519402-%E7%95%B6%E6%95%8F%E6%8D%B7%E9%81%87%E4%B8%8A%E5%BC%95%E5%B0%8E%EF%BC%9A-%E5%9C%A8%E9%A0%98%E5%B0%8E%E5%9C%98%E9%9A%8A%E8%AE%8A%E9%9D%A9%E9%81%AD%E9%81%87%E4%BB%80%E9%BA%BC&#34;&gt;當敏捷遇上引導：在領導團隊變革遭遇什麼困難&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://funevo.com/2016/09/25/%E8%AE%8A%E6%95%8F%E6%8D%B7%E7%9A%84%E9%98%BB%E7%A4%99-%E5%9C%98%E9%9A%8A%E5%85%B1%E5%89%B5%E6%B3%95%E5%AF%A6%E5%81%9A/&#34;&gt;找出組織無法變敏捷的阻礙 – 團隊共創法實做&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有了這份清單，配上 &lt;em&gt;&lt;a href=&#34;https://www.amazon.com/dp/1574441957/ref=cm_sw_r_tw_dp_x_G7leybA7ST83J&#34;&gt;Project Management in the First Lane: Applying the Theory of Constraints&lt;/a&gt;&lt;/em&gt; 第五章的 &lt;a href=&#34;http://school.soft-arch.net/blog/325427/generic-proj-crt&#34;&gt;CRT 圖&lt;/a&gt;，有助於我設想些應對措施，才比較敢挑選戰場來試驗。&lt;/p&gt;
&lt;p&gt;接下來，就隨時抱著開放心態，見招拆招嘍～～～&lt;/p&gt;
&lt;h2 id=&#34;工具&#34;&gt;工具&lt;/h2&gt;
&lt;p&gt;我用兩份專案管理工具。&lt;/p&gt;
&lt;p&gt;第一份是只給自己看的 Microsoft Project 文件，用來掌握全貌。或許是受到 PMP 訓練的影響，即使現在是跑 (a subset of) Scrum，又是首航，還是覺得要有這種東西，看到 3 個 sprints 的 WBS、work package、activities、critical path 才安心。&lt;/p&gt;
&lt;p&gt;另一份是給團隊成員看的 Google Spreadsheet，主要是在 daily Scrum 時，用 Kanban 之類易懂的視覺化媒介，讓團隊全體一起溝通工作進展及阻礙。&lt;/p&gt;
&lt;p&gt;調整實驗了幾天，還是覺得秀出我在 &lt;a href=&#34;https://shop.darencademy.com/product/view/id/1&#34;&gt;101 專案管理一日特訓班&lt;/a&gt;學到的 &amp;ldquo;JB Big Table&amp;rdquo; 給團隊成員看，不僅比正統的 Kanban 更容易有&lt;strong&gt;全局觀&lt;/strong&gt;，尤其是&lt;strong&gt;層次&lt;/strong&gt;及&lt;strong&gt;時間感&lt;/strong&gt;，就連 Kanban 素來講究的 WIP 也都內建其中。&lt;/p&gt;
&lt;p&gt;&amp;ldquo;JB Big Table&amp;rdquo; 真的很管用，儘管這次我也只有用上一小部分。&lt;/p&gt;
&lt;h2 id=&#34;反思&#34;&gt;反思&lt;/h2&gt;
&lt;p&gt;一週後，第一個 sprint 順利達標，儘管變數層出不窮。&lt;/p&gt;
&lt;p&gt;萬萬沒想到第一次嘗試帶 Scrum，而且是「1 舊人 + 2 新人」的高風險組合，就很有機會實現。除了天時地利人和的配合，&lt;strong&gt;事先認真的 WBS 分析&lt;/strong&gt;，應是重要因素。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The Scrum Field Guide&lt;/em&gt; 說的是真的！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Your problem isn&amp;rsquo;t your &lt;strong&gt;sprint length&lt;/strong&gt;. You need to improve your &lt;strong&gt;task decomposition&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也順便速記幾則初步的檢討反思：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;理解精神真的很重要。理解了，才知道該如何遵守規則，或許更重要的是，知道為何及如何違反規則。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;One-week sprint 對於「聚焦」的要求更高，真的更該集中鎖定在要徑上。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;儘管只有 one-week sprint，但已經出現《&lt;a href=&#34;https://www.books.com.tw/products/0010196021&#34;&gt;關鍵鏈&lt;/a&gt;》點出的「資源爭奪」問題了。在第一個 sprint 中我沒有處理得很好，但在第二個 sprint 中，我採用 &lt;a href=&#34;https://www.projectup.net/article/view/id/3124&#34;&gt;TOC 聚焦五步驟&lt;/a&gt;中的第二步 &amp;ldquo;exploit&amp;rdquo; 及第三步 &amp;ldquo;subordinate&amp;rdquo; 來處理。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;身處專案導向的矩陣型組織，初步的觀察體會：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;資源主管，如果有敏捷的正知見，滿適合當照顧小羊的 Scrum master。&lt;/li&gt;
&lt;li&gt;PO 的確不適合身兼 Scrum master，會有難以排解的利害衝突。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;某個層次來說，選擇了 Scrum、選擇了 DevOps，甚至廣義一點來說，選擇了 lean、選擇了 TOC，就要有心理準備：這些流程或方法論，都有「持續改善」的機制在裡面，都要求你的 commitment。沒有這種心理準備，往往就是無法移除障礙的原因。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;One-week sprint 固然痛快，但我在《&lt;a href=&#34;https://williampjyeh.notion.site/b299b20f381643c9b7b0caaba1d12f44&#34;&gt;為什麼上班這麼累？其實是你心累&lt;/a&gt;》看到一則警語：「因急迫性所產生的高效率，其實也是一種心理上的成癮。」所以，要注意何時該踩剎車。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;許多議題，我也還沒有答案。但是，抱持開放心態，與團隊一同探索，應是一大樂事吧！&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      2022-10-31 補充
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;原理上，Scrum 並沒規定 sprint 週期是幾天。坊間多半認為，在還不知道團隊能量、產品複雜度、外部依賴性等情況下，以 2 weeks sprint 做為&lt;strong&gt;試行的起點&lt;/strong&gt;，是滿中庸的選擇。&lt;/p&gt;
&lt;p&gt;我自己則是：在自己有把握緊密參與的情況下，我會直接以 one week sprint 做為起點，但預期第一個 sprint review 會無法 100% done，以此曝露團隊該改進之處：規劃面、技術面、協作面⋯⋯。&lt;/p&gt;
&lt;p&gt;當然啦，若某團隊真的要走 one-week sprint 路線，利害關係人也必須理解如此行的理由及限制：每個 sprint 交付物的 “increment” (增量)，真的就只是 one-week 能夠產出的合理規模——這需要教育。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      【敏捷的工作分解方法】系列
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ One-Week Sprint 的節奏&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2016/11/decomposition-reading-list/&#34;&gt;工作分解講座・閱讀材料&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/10/agile-milestone/&#34;&gt;事情做一半，等於沒完成：淺談敏捷的里程碑設定&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❹ &lt;a href=&#34;//william-yeh.net/post/2022/11/spidr/&#34;&gt;以「蜘蛛法」拆分過於龐大的 User Story&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❺ &lt;a href=&#34;//william-yeh.net/post/2023/08/story-to-tasks/&#34;&gt;很簡單的 Story，也要拆分出 Tasks 嗎？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❻ &lt;a href=&#34;//william-yeh.net/post/2023/11/why-decomposition-matters/&#34;&gt;變動的時代，為什麼工作分解技能更是必備？&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>平凡人求生之道：別總是直球對決</title>
      <link>//william-yeh.net/post/2016/08/lifetime-keywords/</link>
      <pubDate>Mon, 29 Aug 2016 07:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/lifetime-keywords/</guid>
      
        <description>&lt;p&gt;我們的人生，都走了許多冤枉路。回頭來看，總是希望能有系統化的方法，及早認清局勢，預作準備，以求更無懼於永不停歇的變局。&lt;/p&gt;
&lt;p&gt;這是我常常在尋覓的思維方法。&lt;/p&gt;
&lt;p&gt;雖然 Joe 在【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/66&#34;&gt;大人學講座12：別總是直球對決：人生難題的系統思考法&lt;/a&gt;】的文案自謙：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Joe，因為從小就不是功課好的學生、甚至在求學過程自國小開始就深覺不適應。所以很早他就理解，如果只是跟著大部分人走的道路，自己很可能毫無競爭力並終將一事無成。所以成長過程，一直就在思考並探索自己還有甚麼別的選擇？有沒有辦法避開人多的路線，而另闢蹊徑？&lt;/p&gt;
&lt;p&gt;透過 6 段故事、搭配 30 個人生關鍵字，讓你提升策略思考力、讓你更有能力面對後續的每個人生挑戰！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但許多時候，健步如飛、如履平地的天才，不見得容易被平凡人仿效；平凡人所跌的跤，及之後逆轉勝的經驗，反而更具參考價值。&lt;/p&gt;
&lt;p&gt;Joe，就有這麼值得參考的逆轉勝故事。&lt;/p&gt;
&lt;p&gt;當年的「平凡人 Joe」，已經變成「不平凡的 Joe」。箇中心路歷程，及面對種種困境、選擇的取捨標準，是我想好好觀摩體會的。加上身為 J&amp;amp;B 的鐵粉，自然不想錯過這晉升大人的重要思路。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/s012-joe.jpg&#34; alt=&#34;S012 - 別總是直球對決&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/s012-joe.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;S012 - 別總是直球對決&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;
整整三個小時的講座，環繞在這 30 個關鍵字：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-0.png&#34; alt=&#34;30 個關鍵字&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-0.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;30 個關鍵字&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;
其中，前三個關鍵字，讓天真爛漫的生涯學童，及早面對沒有標準答案的現實世界。正確的認知，才能進一步激發跳出框架的動力：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-1-3.png&#34; alt=&#34;關鍵字 1~3&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-1-3.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關鍵字 1~3&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;
接下來四個關鍵字，讓我重溫之前在【&lt;a href=&#34;//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/&#34;&gt;A101 職場大人學：職場人際關係與優勢策略&lt;/a&gt;】課堂上受到的洗禮：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-4-7.png&#34; alt=&#34;關鍵字 4~7&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-4-7.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關鍵字 4~7&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;
接下來五個關鍵字，重點濃縮了 Joe &amp;amp; Bryan 在許多文章及課程一再強調的「認清局勢」觀點：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-8-12.png&#34; alt=&#34;關鍵字 8~12&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-8-12.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關鍵字 8~12&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;
接下來三個關鍵字，讓我回想起 Bryan 那仍令人回味不已的【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/57&#34;&gt;大人學講座03 : 尋找天賦與熱情的系統化做法&lt;/a&gt;】（我要回去複習一下 Bryan 講的「礦場主人的矩陣」了）：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-13-15.png&#34; alt=&#34;關鍵字 13~15&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-13-15.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關鍵字 13~15&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;
接下來四個關鍵字，很像《&lt;a href=&#34;http://www.books.com.tw/products/0010641668?loc=P_asb_001&#34;&gt;三年後，你的工作還在嗎？&lt;/a&gt;》的重點濃縮：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-16-19.png&#34; alt=&#34;關鍵字 16~19&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-16-19.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關鍵字 16~19&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;
接下來六個關鍵字，對我來說，是很重的當頭棒喝。多少次我們都陷在競逐的潮流裡，忘卻某些似拙實巧的道理？有些事，欲速則不達呀！&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-20-25.png&#34; alt=&#34;關鍵字 20~25&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-20-25.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關鍵字 20~25&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;
聽著這五段 Joe 從小到大的故事，提煉出來的 25 個關鍵字，可能會誤以為這只是心靈雞湯（不過，就算是心靈雞湯，也是熬了四十年的原汁原味上等雞湯喔）。不過，更神奇的是，Joe 緊接著用第六段故事，現身說法，證明這 25 個關鍵字，不只是用在個人生涯成長，居然還可以用來搶下一個大型的系統導入案！&lt;/p&gt;
&lt;p&gt;真是太不可思議了！這豈不正像周星馳電影《食神》裡面的摺凳一樣嗎？「好摺凳！摺凳的奧妙之處，它可以藏在民居之中，隨手可得，還可以坐著它來隱藏殺機，就算被警察抓了也告不了你，真不愧為七大武器之首！」&lt;/p&gt;
&lt;p&gt;這摺凳，和我之前看的 Joe &amp;amp; Bryan 部落格文章、專書、大人學及專案管理課程，相互呼應，容易消化。心中更隱隱覺得，這與我這陣子研究取材的「變革」主題，有許多可相互參酌之處。好的心智框架，委實妙用無窮。&lt;/p&gt;
&lt;p&gt;這 25 枚關鍵字，我收下了。&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;最後五個關鍵字，是整段講座的總結。看似單純，甚至古板蠢笨，但卻是非常踏實的人生哲學，寧靜而致遠。&lt;/p&gt;
&lt;p&gt;尤其是最後一個關鍵字，一秀出來，所有的人都驚呆了：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-26-30.png&#34; alt=&#34;關鍵字 26~30&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/lifetime-keywords-26-30.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關鍵字 26~30&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;如果直接把這個字端出來，大概百分之兩百的觀眾都會當場大喊：「我又不是來這裡聽心海羅盤的⋯⋯」。不過，花了 180 分鐘，聽了六段故事，蒐集了 30 個「別總是直球對決」的關鍵字，就會覺得這是肺腑之言。沒有置身現場，很難體會這種久違的感動。&lt;/p&gt;
&lt;p&gt;回頭來看，這 30 個關鍵字，的確都是從「心存善念」為出發點，沒有什麼鑽營算計他人的成分，的的確確都是王道、正道。&lt;/p&gt;
&lt;p&gt;我們有多久沒有相信單純的「善」的力量，而競逐於鑽營取巧？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;收下這 30 枚關鍵字，以後遇到自己或他人的人生難題，我會回想這六段故事裡面的主人翁 Joe，是如何痛苦掙扎、如何認清局勢、如何壯士斷腕、如何砍掉重練、如何潛龍勿用利見大人終日乾乾，相信一定能夠喚起沈睡已久的變化球、慢速球、伸卡球、曲球。&lt;/p&gt;
&lt;p&gt;人生，除了「直球對決」之外，其實還有更好的選擇呀。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>為什麼要追求極簡化的 Docker image？</title>
      <link>//william-yeh.net/post/2016/08/why-minimal-docker-images/</link>
      <pubDate>Sat, 27 Aug 2016 20:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/why-minimal-docker-images/</guid>
      
        <description>&lt;p&gt;今早〈&lt;a href=&#34;//william-yeh.net/post/2016/08/halfblood-docker/&#34;&gt;從 Ansible 到 Docker：混血模式&lt;/a&gt;〉演講過後，有人在聊天室提問：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;請問為什麼要追求最小化的 Docker image？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;記得去年我在 &lt;a href=&#34;https://www.meetup.com/Docker-Taipei/&#34;&gt;Docker Taipei 社群&lt;/a&gt;主講〈&lt;a href=&#34;https://william-yeh.github.io/docker-mini/&#34;&gt;追求極簡化 Docker image 之路&lt;/a&gt;〉的時候，曾如此開場：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;部分原因是「純技術性的探討」。&lt;/p&gt;
&lt;p&gt;經過這番探討，對 Docker 底層機制會掌握得更深刻，有助於更善用 Docker，也很自然會理解 Docker 與 VM 的明顯差別在哪裡。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這是極度保守的理由。因為在當時，「極簡化 Docker」的實施手法不方便，地雷又多，投入成本高於獲得的效益。因此，除非為了純技術性的探討（技術狂的浪漫？），否則似乎不太值得鼓吹。&lt;/p&gt;
&lt;p&gt;一年後的今天，「極簡化 Docker」的實施手法已經更成熟了，我們也看到更多官方的 Docker image 也額外提供以 &lt;a href=&#34;https://hub.docker.com/_/alpine&#34;&gt;Alpine&lt;/a&gt; 為 base image 的選項。對於這議題，不再能單純用「技術者的狂熱」來看待。&lt;/p&gt;
&lt;p&gt;一年後的今天，有更多好的理由。&lt;/p&gt;
&lt;p&gt;我就在此簡答一下，追求極簡化 Docker image，除了技術性的狂熱之外，還有什麼實質上的好處？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;其一、在某些受限的硬體資源（如：儲存空間、網路頻寬），不佳的軟體執行環境（如：&lt;a href=&#34;https://docs.docker.com/storage/storagedriver/select-storage-driver/&#34;&gt;layered file system&lt;/a&gt; 實作品質不佳），精簡的 image 是很有吸引力的。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;其二、越大的 image，隱含的黑盒子越多，資安風險也越高。&lt;/p&gt;
&lt;p&gt;口說無憑，請用 &lt;a href=&#34;https://www.aquasec.com/news/blog-peekr-free-security-scanner-just-got-upgraded/&#34;&gt;Peekr&lt;/a&gt; 針對幾個常見的 base image 做一番安全掃描：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/peekr-scan.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/peekr-scan.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;看得出來哪一個的資安風險較大、哪一個較小了嗎？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;其三、如果你用的是傳統世界的 host OS，而不是像 CoreOS、Rancher 這類所謂的 &amp;ldquo;&lt;a href=&#34;https://www.ithome.com.tw/news/95756&#34;&gt;container OS&lt;/a&gt;&amp;quot;，那麼，base image 與 host OS 可能會有一大堆重複的東西，這也是一種浪費。&lt;/p&gt;
&lt;p&gt;寶貴的 Docker image，應該只放與 app 直接相關的東西；為什麼還要塞一大堆和 host OS 重複、且和 app 沒有直接關係的東西呢？&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;簡單給三個思考的方向，供大家參考。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>從 Ansible 到 Docker：混血模式</title>
      <link>//william-yeh.net/post/2016/08/halfblood-docker/</link>
      <pubDate>Sat, 27 Aug 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/halfblood-docker/</guid>
      
        <description>&lt;p&gt;2015 年 4 月我在 &lt;a href=&#34;https://www.meetup.com/Docker-Taipei/&#34;&gt;Docker Taipei 社群&lt;/a&gt;講了一場〈&lt;a href=&#34;https://william-yeh.github.io/docker-mini/&#34;&gt;追求極簡化 Docker image 之路&lt;/a&gt;〉。一年後，在「極簡化 Docker」這條路上，另一條途徑 Alpine Linux 開始嶄露頭角——不必像過去那麼蠻幹，地雷減少，流程優勢顯著，品質上也不見得遜於長期被 glibc 把持的傳統體系。&lt;/p&gt;
&lt;p&gt;我嘗試用這種手法重整過去的東西，結果還不算太差。因此，一直希望能有機會再給一場類似【追求極簡化 Docker image 之路，Part 2】的演講。&lt;/p&gt;
&lt;p&gt;此外，由於自己持續在使用 Ansible 來處理組態設定事宜，持續維護近 20 個 Ansible Galaxy 開源 roles，也開講了五場【&lt;a href=&#34;https://devopssummit.ithome.com.tw/workshop/ansible/&#34;&gt;Ansible Workshop&lt;/a&gt;】訓練課程，很自然的，我會常常拿 Ansible 與 Docker 並列，思考兩者的定位、運用時機，甚至未來走向；有時甚至靈光一閃，浮現一些 Ansible＋Docker 的組合技。&lt;/p&gt;
&lt;p&gt;這就是今天在 &lt;a href=&#34;https://community-open-camp.azurewebsites.net/&#34;&gt;Community Open Camp&lt;/a&gt; 這場演講【從 Ansible 到 Docker：混血模式】的由來。&lt;/p&gt;
&lt;h2 id=&#34;特色&#34;&gt;特色&lt;/h2&gt;
&lt;p&gt;用這種手法，可以在很大程度上，維持你既有的 Ansible playbook 資產，再加上一些針對 Docker 獨有特性而微調的部分，就可以用最小的力氣，產出三種層次的 image，從肥到瘦依序是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;統包的 Docker image（含：OS runtime、Ansible、應用軟體本體）。&lt;/li&gt;
&lt;li&gt;稍稍瘦身過的 Docker image（含：OS runtime、應用軟體本體，不含 Ansible）。&lt;/li&gt;
&lt;li&gt;極度瘦身的 Docker image（只含 Alpine Linux runtime 及應用軟體本體）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以常見的兩個 client 軟體（wrk、boom）、兩個 server 軟體（nginx、json-server）為例，照著流程做到最後一步，得到的結果是：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/halfblood-docker-example.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/halfblood-docker-example.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這種混血手法，提供給有需要在 Docker 及 non-Docker 兩者來回穿梭的工程師參考。&lt;/p&gt;
&lt;h2 id=&#34;提醒&#34;&gt;提醒&lt;/h2&gt;
&lt;p&gt;最後，不管你要不要採用 Docker，不管你的 Docker 是局部導入還是全面導入，請記得兩件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;“Infrastructure as Code” mindset，永遠要銘記在心。&lt;/li&gt;
&lt;li&gt;Plan B 永遠是必須考慮的。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這樣，你就可以用比較健康的心態，去面對、評估、嘗試新的技術。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt; &lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;演講投影片：&lt;/p&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/65362893&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://channel9.msdn.com/Events/Community-Open-Camp/Community-Open-Camp-2016/ComOpenCamp003&#34;&gt;演講錄影&lt;/a&gt;，擺在 Channel 9 上。&lt;/p&gt;
&lt;p&gt;▷ &lt;a href=&#34;https://github.com/William-Yeh/build-docker-with-ansible&#34;&gt;演講範例程式碼&lt;/a&gt;，擺在 GitHub 上，請搭配服用。&lt;/p&gt;
&lt;p&gt;▷ 後續文章：〈&lt;a href=&#34;//william-yeh.net/post/2016/08/why-minimal-docker-images/&#34;&gt;為什麼要追求極簡化的 Docker image？&lt;/a&gt;〉&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>簡報者的小工具</title>
      <link>//william-yeh.net/post/2016/08/presenter-tools/</link>
      <pubDate>Mon, 22 Aug 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/presenter-tools/</guid>
      
        <description>&lt;p&gt;自從去年一月看了 ihower 的〈&lt;a href=&#34;https://ihower.tw/blog/archives/8075&#34;&gt;講個秘訣：技術簡報的好用工具&lt;/a&gt;〉之後，我才想到，身為 Mac 用戶，我好像太疏於好好整頓自己的電腦，讓我在簡報時更順暢。於是，經過一番嘗試，我也建構出自己的工具組合。&lt;/p&gt;
&lt;p&gt;後來，在演講或講課時，總會遇到有人問道：「william，你是用怎麼弄出 xxx 效果的？」每次簡報，屢試不爽；乾脆自己整理一篇文章好了。&lt;/p&gt;
&lt;p&gt;註：此文只列出我最常用的工具，更完整的，請見 ihower 的〈&lt;a href=&#34;https://ihower.tw/blog/archives/8075&#34;&gt;講個秘訣：技術簡報的好用工具&lt;/a&gt;〉。&lt;/p&gt;
&lt;h2 id=&#34;布幕&#34;&gt;布幕&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://itunes.apple.com/us/app/desktop-curtain/id414088151?mt=12&#34;&gt;Desktop Curtain&lt;/a&gt;，像舞台的暗紅色簾幕一樣，把雜七雜八的背景遮住，留下乾淨的背景給前景主角發揮。簡報時，我都會用這軟體把不相干的電腦桌面圖示遮起來，讓投影出來的畫面更乾淨，也有助於錄出更具專業感的影片。&lt;/p&gt;
&lt;p&gt;實例：〈&lt;a href=&#34;http://school.soft-arch.net/courses/vm-for-devops/lectures/683503&#34;&gt;第二式：Life cycle - 開機、登入登出、關機 (18:20)&lt;/a&gt;〉這段影片，就用了這款 Desktop Curtain 軟體，讓 live demo 畫面更乾淨。&lt;/p&gt;
&lt;h2 id=&#34;聚光燈&#34;&gt;聚光燈&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://boinx.com/mousepose/&#34;&gt;Mouseposé&lt;/a&gt;，像舞台的聚光燈一樣，把聚光燈打在想凸顯的地方，不重要的地方則弄暗。這軟體也能夠將你按的按鍵放大顯示出來，讓大家方便照著輸入；不過我比較少用到這一招。&lt;/p&gt;
&lt;p&gt;實例：〈&lt;a href=&#34;//william-yeh.net/post/2016/08/devops-a-toc-perspective/&#34;&gt;從限制理論看 DevOps&lt;/a&gt;〉演講第 47 分鐘開始，就用了這款 Mouseposé 軟體，讓大家容易聚焦在當下的重點區域。&lt;/p&gt;
&lt;h2 id=&#34;放大鏡&#34;&gt;放大鏡&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://www.zoomitapp.com/&#34;&gt;Zoom It&lt;/a&gt;，其實是我在 Windows 時代就很愛用的軟體。像放大鏡一樣，局部放大重點區域。&lt;/p&gt;
&lt;p&gt;實例：呃，暫時還沒有錄影。因為這一招，我比較常用在時間較長的課堂上，不常用在時間緊湊的演講。改天如果我會直接在演講會場，赤裸裸秀出 GitHub 或 Sublime Text 的程式片段，或許就會順便錄下來做記錄吧。&lt;/p&gt;
&lt;h2 id=&#34;倒數計時器&#34;&gt;倒數計時器&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://itunes.apple.com/tw/app/alinof-timer/id512464723?mt=12&#34;&gt;Alinof Timer&lt;/a&gt;，在進行某些限時活動，或中場休息時，有這個東西，很好用。&lt;/p&gt;
&lt;p&gt;實例：〈&lt;a href=&#34;//william-yeh.net/post/2016/05/devops-a-lean-perspective/&#34;&gt;有了 Agile，為什麼還要有 DevOps？&lt;/a&gt;〉演講第 28 分鐘開始，就用了這款 Alinof Timer，作為倒數計時之用。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以上僅列出四個我在簡報時最常用的工具，給大家參考。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>從限制理論看 DevOps</title>
      <link>//william-yeh.net/post/2016/08/devops-a-toc-perspective/</link>
      <pubDate>Wed, 17 Aug 2016 23:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/devops-a-toc-perspective/</guid>
      
        <description>&lt;p&gt;自從寫了〈&lt;a href=&#34;//william-yeh.net/post/2016/03/origin-of-devops-elements/&#34;&gt;DevOps 核心元素的考古溯源&lt;/a&gt;〉一文，我就很想找個機會，好好闡釋 DevOps 的重要源頭：&lt;strong&gt;Lean Thinking&lt;/strong&gt;。這個願望，在五月初那次兩個小時的〈&lt;a href=&#34;//william-yeh.net/post/2016/05/devops-a-lean-perspective/&#34;&gt;有了 Agile，為什麼還要有 DevOps？&lt;/a&gt;〉演講中實現了。&lt;/p&gt;
&lt;p&gt;不過私底下，還有另一個更大的野心：我想從 &lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;TOC (Theory of Constraints)&lt;/a&gt;（常譯為&lt;strong&gt;限制理論&lt;/strong&gt;或&lt;strong&gt;制約理論&lt;/strong&gt;）的角度，好好審視或詮釋一下 DevOps。&lt;/p&gt;
&lt;p&gt;原因之一，這陣子一直浸潤在 TOC 世界中，不知不覺就會拿 TOC 心智框架來檢視萬物。有文為證：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2016/04/learn-from-plant-mgmt/&#34;&gt;向工廠管理致敬&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2016/04/learn-process-mgmt-by-game/&#34;&gt;向遊戲學習&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/&#34;&gt;轉大人，Part 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/&#34;&gt;改變的框架&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;//william-yeh.net/post/2016/08/back-to-the-origin/&#34;&gt;請循其本&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;原因之二，DevOps 領域的經典 &lt;a href=&#34;http://www.amazon.com/dp/0988262592/ref=cm_sw_r_tw_dp_a4p3wb0PSYY97&#34;&gt;&lt;em&gt;The Phoenix Project&lt;/em&gt;&lt;/a&gt;（中譯本《&lt;a href=&#34;https://www.books.com.tw/products/0010765203&#34;&gt;鳳凰專案&lt;/a&gt;》）大力推崇 TOC，小說情節中也藉由神秘人物 Erik 之口，直接大辣辣地引用 TOC 方法來解決種種 DevOps 問題——甚至 Erik 還叫主角 Bill 去好好研讀《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》呢。我想，掌握 TOC，對於掌握 DevOps 應該很有幫助。 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;TOC，最為人所知的，就是在《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》一書所闡釋的「&lt;a href=&#34;https://www.projectup.net/article/view/id/3124&#34;&gt;聚焦五步驟&lt;/a&gt;」(five focusing steps)。許多人甚至以為聚焦五步驟就是 TOC 的全貌。&lt;/p&gt;
&lt;p&gt;不過，在整個 TOC 的知識體系中，更大的寶藏，其實是 &lt;a href=&#34;https://en.wikipedia.org/wiki/Thinking_processes_%28theory_of_constraints%29&#34;&gt;Thinking Processes&lt;/a&gt;（思維程序；思考方式）。這是高德拉特為了回答《目標》書末揭櫫的三個大哉問，逐漸發展出來的系統化方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What to change (應該改變哪些事情)&lt;/li&gt;
&lt;li&gt;To What to change (要朝什麼方向改變)&lt;/li&gt;
&lt;li&gt;How to cause the change (要如何改變)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可惜的是，深刻掌握 Thinking Processes 並不太容易（尤其是沒有名師指導之下）。難怪 &lt;a href=&#34;http://www.amazon.com/dp/0988262592/ref=cm_sw_r_tw_dp_a4p3wb0PSYY97&#34;&gt;&lt;em&gt;The Phoenix Project&lt;/em&gt;&lt;/a&gt; 如此評論：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In Dr. Goldratt&amp;rsquo;s following book, &lt;a href=&#34;https://www.amazon.com/dp/0884271153&#34;&gt;&lt;em&gt;It&amp;rsquo;s Not Luck&lt;/em&gt;&lt;/a&gt;, he describes what he called the Thinking Processes, which is a &lt;strong&gt;fantastic&lt;/strong&gt; (but somewhat &lt;strong&gt;inaccessible&lt;/strong&gt; and often very &lt;strong&gt;slow&lt;/strong&gt;) methodology of identifying core, chronic conflicts, capturing the current reality, describing the desired future reality, and various planning techniques to increase the likelihood of getting there successfully.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;甚至就連高德拉特在《&lt;a href=&#34;http://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》書中，也藉由主角羅哥之口，承認有此一困難：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你需要的是：對主題的&lt;strong&gt;直覺&lt;/strong&gt;，及有&lt;strong&gt;毅力&lt;/strong&gt;去執行這套思維方法中的&lt;strong&gt;細緻步驟&lt;/strong&gt;。不是時間的問題，而是如何讓自己&lt;strong&gt;投入&lt;/strong&gt;及&lt;strong&gt;執行&lt;/strong&gt;的問題。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不過，欲速則不達，有時我們還是得 &amp;ldquo;slow down to speed up&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;尤其是面對深層的糾結。抄捷徑，總有一天要還的。&lt;/p&gt;
&lt;h2 id=&#34;挑戰&#34;&gt;挑戰&lt;/h2&gt;
&lt;p&gt;我想拿 DevOps 做實驗，挑戰看看高德拉特的四項宣稱，在 DevOps 領域裡是否依然合用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;我們不應該假設經理人疏忽或無能，應該假設他們陷入一個&lt;strong&gt;衝突&lt;/strong&gt;中，以致於無法正確地經營公司。  《&lt;a href=&#34;https://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》p.204&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;人們的腦力沒有問題，錯就錯在人們&lt;strong&gt;對現實的認知&lt;/strong&gt;；最大的障礙是，人們視現實為極端複雜，而實際上是&lt;strong&gt;簡單&lt;/strong&gt;得出奇。對複雜性的崇拜，是完全錯誤的。  《&lt;a href=&#34;https://www.amazon.com/dp/B014HV1W5O&#34;&gt;抉擇&lt;/a&gt;》p.10&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;任何情況的背後，其實只有一或兩個&lt;strong&gt;核心問題&lt;/strong&gt;，造成其他不良效應。  《&lt;a href=&#34;https://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》p.124&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我們要找出來、並且解決的是&lt;strong&gt;核心問題&lt;/strong&gt;，不是引致一、兩個不良效應，而是引致所有不良效應的核心問題。  《&lt;a href=&#34;https://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》p.220&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;赫然發現，超誇張的，光是用 CRT，就能初步推導出現在已被視為「DevOps 常識」的 &lt;a href=&#34;https://blog.devopsguys.com/2014/04/17/the-secret-of-devops-success-isnt-in-the-it-literature-yet/&#34;&gt;CALMS&lt;/a&gt; 及 &amp;ldquo;&lt;a href=&#34;http://itrevolution.com/the-three-ways-principles-underpinning-devops/&#34;&gt;The Three Ways&lt;/a&gt;&amp;quot;。而且，DevOps 的核心衝突，果然就出現在 CRT 的下方。&lt;/p&gt;
&lt;p&gt;偉大的高德拉特博士是對的！&lt;/p&gt;
&lt;p&gt;整個推導過程的確燒腦，橫跨了好幾天，也正如高德拉特在《絕不是靠運氣》所預告的「你需要的是：對主題的&lt;strong&gt;直覺&lt;/strong&gt;，及有&lt;strong&gt;毅力&lt;/strong&gt;去執行這套思維方法中的&lt;strong&gt;細緻步驟&lt;/strong&gt;。不是時間的問題，而是如何讓自己&lt;strong&gt;投入&lt;/strong&gt;及&lt;strong&gt;執行&lt;/strong&gt;的問題。」&lt;/p&gt;
&lt;p&gt;但值得。這次練習，讓我掌握了一項犀利的武器。&lt;/p&gt;
&lt;h2 id=&#34;發表&#34;&gt;發表&lt;/h2&gt;
&lt;p&gt;整個推導過程，我曾在 &lt;a href=&#34;http://devopssummit.ithome.com.tw/&#34;&gt;DevOps Summit 2016&lt;/a&gt; 以〈&lt;a href=&#34;http://www.slideshare.net/williamyeh/devops-63711710&#34;&gt;從限制理論看 DevOps&lt;/a&gt;〉為題發表過一次，今晚於 &lt;a href=&#34;http://devops.kktix.cc/events/meetup2-toc-flow&#34;&gt;DevOps Taiwan Meetup #2&lt;/a&gt; 再發表一次加長版。希望對於推廣 TOC 式的思考方式，以及解決一些 DevOps 難題，有一些幫助。&lt;/p&gt;
&lt;p&gt;溫馨小提醒：我推導出來的結論，與你推導的結論，可能不盡相同；這是正常的。尤其這次為了聚焦在 DevOps 論述，CRT 還遺留一些沒有再繼續往下深究的因果關係（如：各自為政、無誘因、失敗代價高、曾失敗過、惰性），真要再往下深究，有很大比例會碰觸到《目標》、《絕不是靠運氣》、《關鍵鏈》一再點出的核心問題：局部成本觀，甚至還會碰觸到《&lt;a href=&#34;https://www.amazon.com/dp/B014HV1W5O&#34;&gt;抉擇&lt;/a&gt;》談到的「清晰思考四大障礙」。那又是另一個大哉問了⋯⋯&lt;/p&gt;
&lt;p&gt;請把重點放在過程，體驗一下，用這一套「&lt;strong&gt;可以幫忙建構及溝通常識的思維方法&lt;/strong&gt;」，藉以「&lt;strong&gt;激發、專注及審視你的直覺&lt;/strong&gt;」是何滋味。&lt;/p&gt;
&lt;p&gt;最後，謹以高德拉特《&lt;a href=&#34;https://www.books.com.tw/products/0010588050&#34;&gt;仍然不足夠&lt;/a&gt;》的某句話，彼此互勉：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你覺得它是「常識」，千萬別忽視它，相反的，要實行它。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;上個月在 DevOps Summit 2016 發表的投影片：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;//www.slideshare.net/williamyeh/devops-63711710&#34;&gt;從限制理論看 DevOps&lt;/a&gt;&lt;/strong&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/63711710&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;今晚在 DevOps Taiwan Meetup #2 的錄影檔：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/C5mZp-SDbXw?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;感謝主辦人陳正瑋精彩的&lt;a href=&#34;http://blog.chengweichen.com/2016/08/devops-taiwan-meetup-2.html&#34;&gt;現場記實&lt;/a&gt;，這段話，精準點出我想傳達的意旨：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這場分享個人覺得值得多次回味，對於沒有接觸過高德拉特及 TOC 的人來說，應該是一個很好的魚餌，能讓人稍微一窺這些理論工具並非只是空談，吸引你更深入的了解認識它，甚至學習運用它。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;演講提到的幾則工商服務連結：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;[課程] &lt;a href=&#34;http://teddysoft.tw/courses/agile-box-01/&#34;&gt;瓶頸遊戲：運用五步驟聚焦法持續改善流程&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[演講預告] &lt;a href=&#34;http://containersummit.ithome.com.tw/&#34;&gt;Docker 導入：障礙與對策&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;箇中原委，我在〈&lt;a href=&#34;//william-yeh.net/post/2016/06/phoenix-proj-titles/&#34;&gt;鳳凰項目・私房標題&lt;/a&gt;〉一文中有介紹過。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
      
    </item>
    
    <item>
      <title>練字與程式設計</title>
      <link>//william-yeh.net/post/2016/08/on-handwriting/</link>
      <pubDate>Wed, 10 Aug 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/on-handwriting/</guid>
      
        <description>&lt;h2 id=&#34;參考線&#34;&gt;參考線&lt;/h2&gt;
&lt;p&gt;最近常常需要利用便利貼或紙筆思考。看了看筆跡，覺得⋯⋯呃，該開始重新練字了。&lt;/p&gt;
&lt;p&gt;現在市面上看得到的範例及風格，比起只有張炳煌《硬筆書法》的當年，實在是進步太多太多了。&lt;/p&gt;
&lt;p&gt;這是硬筆書法的文藝復興嗎？&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:15em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/writing-books.jpg&#34; alt=&#34;練字的書&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/writing-books.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;練字的書&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;最近也常常趁思考的空檔，拿出紙張，甚至用自製的「斜十字格」A4 紙張，信手寫些字句。&lt;/p&gt;
&lt;p&gt;其中一個感想是：硬筆書法，練字，還是用鋼筆比較舒服呀。&lt;/p&gt;
&lt;p&gt;另一個感想是：格子或參考線，真的有差。&lt;/p&gt;
&lt;p&gt;譬如說，同樣是信手寫寫高德拉特《&lt;a href=&#34;https://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》的名言錦句，也花了差不多的時間書寫，結果卻明顯有別（只是信手寫寫，就請別挑剔寫得不好看了唄）：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/writing-sample.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/writing-sample.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;我稍微反思了一下。&lt;/p&gt;
&lt;p&gt;如果紙上有格子或參考線，我在書寫時，隱隱會有一種微弱的意識（應該還稱不上是「潛意識」吧，或許可稱「弱意識」？）放在筆畫間架上。反之，沒有格子或參考線，我似乎要很刻意分神去留意筆畫間架，才有辦法維持起碼的行氣走勢。&lt;/p&gt;
&lt;p&gt;格子或參考線，似乎不會對我帶來額外的認知負荷或注意力過載——是因為我已經習慣了它的存在嗎？&lt;/p&gt;
&lt;p&gt;這讓我聯想到程式設計。&lt;/p&gt;
&lt;h2 id=&#34;紀律&#34;&gt;紀律&lt;/h2&gt;
&lt;p&gt;我很喜歡引述 Joshua Bloch 在《&lt;a href=&#34;http://www.books.com.tw/products/0010511808&#34;&gt;編程的頂尖對話&lt;/a&gt;》(&lt;em&gt;Coders at Work&lt;/em&gt;) 提到的觀點：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;既然寫正確的程式那麼難，我們就應該盡力取得幫助。所以，能減少 bug 的所有東西都是好的。&lt;/p&gt;
&lt;p&gt;因此，我是靜態型別和靜態分析的信徒：任何可以減少某個特定類別 bug 的東西都是好的，任何可以讓程式師的工作更輕鬆的東西都是好的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;對他來說，靜態型別、靜態分析，就是一種格子或參考線。&lt;/p&gt;
&lt;p&gt;同一本書中，Simon Peyton Jones 也說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;函數式程式設計從根本上允許你建構更為健壯的結構，建構易於理解、測試和推論的框架。&lt;/p&gt;
&lt;p&gt;你的材料越結實，你的注意力就越有可能放到大規模的架構上，而不是細節的地方。但是這也會讓我們更加雄心勃勃，建構一個更大的結構，直到達到極限，達到這個結構幾乎要坍塌而又不倒的程度。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bernie Cosell 則說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;寫程式時必須讓它可測試。讓程式可測試的唯一途徑是在你動手寫第一行程式之前，務必仔細考慮。&lt;/p&gt;
&lt;p&gt;對那些有效工作的阻塞點、判斷提示點和測試點，你不可能再去改造。如果你急等著程式工作，請一開始就把事情做對。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我發現，這些強者，都善於及早把「注意力」這項稀有資源擺在他們認為日後可能會是瓶頸、缺陷、重工之處。因此，他們不避諱限制與規條，反而擁抱限制與規條。&lt;/p&gt;
&lt;p&gt;一種很有紀律的擁抱。&lt;/p&gt;
&lt;h2 id=&#34;原則&#34;&gt;原則&lt;/h2&gt;
&lt;p&gt;硬筆書法，有些書會很努力（盡責？）條列一堆建議事項。像侯信永《&lt;a href=&#34;http://www.books.com.tw/products/0010709943&#34;&gt;美字基本功&lt;/a&gt;》就引用被清朝同治皇帝譽為「字聖」的黃自元彙整的「&lt;a href=&#34;https://zh.wikipedia.org/wiki/%E6%A5%B7%E6%9B%B8%E4%B9%9D%E5%8D%81%E4%BA%8C%E6%B3%95&#34;&gt;間架結構九十二法&lt;/a&gt;」，用九十二個字示範好的運筆原則。&lt;/p&gt;
&lt;p&gt;不過，除非真的心無旁騖，專心致志練字，否則，九十二條，說實在的，要完全內化，可能真的要有很大的意志力。&lt;/p&gt;
&lt;p&gt;反觀《&lt;a href=&#34;http://www.books.com.tw/products/0010712250&#34;&gt;丹硯式習字法&lt;/a&gt;》只提出極度精簡的九個基本要訣：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;古代書法家務求完美，舉起例子來鉅細靡遺。最知名的例子便是清朝書家黃自元，他在整理楷書結構之後，提出了九十二種結構法則。九十二個！仔細是仔細，不過我想九十二個學完也得花上好多時間吧！&lt;/p&gt;
&lt;p&gt;我過去教學的對象是小學生，我也會教他們一些篩選過的黃自元楷書結構九十二法，但不會一開始就教。初學投籃的人要先學會把球穩穩地扔出去，不是一開始就來個投籃的二十個要訣。&lt;/p&gt;
&lt;p&gt;我一直相信一件事：習寫鋼筆字（硬筆字）追求「結構的穩定」永遠都是最優先順位。先穩下了結構，之後練習書法才有依據。這是因為硬筆先天在筆畫粗細的變化上不如軟筆，況且有了穩定的結構做後盾，筆法才有揮灑的空間。&lt;/p&gt;
&lt;p&gt;Less is more. 這本書的特色是：相較於把所有的細節都寫出來，我花心思在「去掉」很多東西。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同樣的，李彧的《&lt;a href=&#34;http://www.books.com.tw/products/0010716789?loc=P_asv_003&#34;&gt;美字進化論&lt;/a&gt;》雖然列出 800 個示範字，但關於運筆要領，則濃縮成「五度」╳「八畫」。&lt;/p&gt;
&lt;p&gt;我發現，像這種極簡但鞭辟入裡直指人心的原則，易學，易記，更容易內化，變成不知不覺的格子或參考線。&lt;/p&gt;
&lt;p&gt;這又讓我聯想到程式設計。&lt;/p&gt;
&lt;h2 id=&#34;指導方針&#34;&gt;指導方針&lt;/h2&gt;
&lt;p&gt;我發現，過去浸潤一堆程式設計規條：coding style、&lt;a href=&#34;http://martinfowler.com/books/refactoring.html&#34;&gt;refactoring&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Design_Patterns&#34;&gt;GoF design patterns&lt;/a&gt;⋯⋯很有用，也打下很穩的根基。不過，到了現在，真正還在平日意識得到的，大概僅剩 &lt;a href=&#34;https://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29&#34;&gt;SOLID&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Don%27t_repeat_yourself&#34;&gt;DRY&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/GRASP_%28object-oriented_design%29&#34;&gt;GRASP&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/KISS_principle&#34;&gt;KISS&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Separation_of_concerns&#34;&gt;SoC&lt;/a&gt; 這類更原則性的指導方針。&lt;/p&gt;
&lt;p&gt;精簡的指導原則，不見得易學（畢竟這些是濃縮到不能再濃縮的實務精華），但易記，更容易內化。&lt;/p&gt;
&lt;p&gt;另一個好處，就如我在〈&lt;a href=&#34;//william-yeh.net/post/2016/08/back-to-the-origin/&#34;&gt;請循其本&lt;/a&gt;〉一文提到的，也很容易轉化成有效提問。&lt;/p&gt;
&lt;p&gt;「注意力」是稀有資源，我們要努力保護它，尤其是在從事「程式設計」這種高度精密的心智運動時。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;謎之音：練字，雖小道，亦有可觀者也！&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>演算法也有不神祕的一面（下集）</title>
      <link>//william-yeh.net/post/2016/08/on-algorithm-myth/</link>
      <pubDate>Tue, 09 Aug 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/on-algorithm-myth/</guid>
      
        <description>&lt;p&gt;記得高中時，建中電研社社刊有一則笑話：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果&lt;a href=&#34;https://en.wikipedia.org/wiki/Carl_Friedrich_Gauss&#34;&gt;高斯 (Gauss)&lt;/a&gt; 小學時就學程式設計，他可能就懶得發明&lt;a href=&#34;https://en.wikipedia.org/wiki/Arithmetic_progression&#34;&gt;等差級數&lt;/a&gt;公式了，他會直接坐在電腦前，輸入：&lt;/p&gt;
&lt;p&gt;sum := 0&lt;br&gt;
for i := 1 to 100 do&lt;br&gt;
　　　sum := sum + i&lt;br&gt;
end for&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;雖然是笑話一則，但也很貼切點出 algorithm（演算法；演算法則）的最原始用途：提供另一種解決數學題目的方法。&lt;/p&gt;
&lt;p&gt;在前一篇文章〈&lt;a href=&#34;//william-yeh.net/post/2016/08/on-computational-thinking/&#34;&gt;運算思維其實一點也不神祕&lt;/a&gt;〉中，我曾提到「運算思維，目前公認有四大核心」，其中尤以第四核心最特別：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;嚴格來說，運算思維與其他領域（非 &lt;a href=&#34;https://en.wikipedia.org/wiki/Science,_technology,_engineering,_and_mathematics&#34;&gt;STEM&lt;/a&gt; 領域尤然）最大分野，就是演算法 (algorithm) 了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;現在，我們就來簡單看一看這個所謂的「最大分野」吧。&lt;/p&gt;
&lt;h2 id=&#34;歷史&#34;&gt;歷史&lt;/h2&gt;
&lt;p&gt;先談點嚴肅的歷史。沒興趣的人，可以跳過。&lt;/p&gt;
&lt;p&gt;任何計算機概論教科書，都會提到現代通用型 computer（電腦、計算機）的一個直接源頭，是 18 世紀數學家 &lt;a href=&#34;https://en.wikipedia.org/wiki/Charles_Babbage&#34;&gt;Charles Babbage&lt;/a&gt; 製作的&lt;a href=&#34;https://en.wikipedia.org/wiki/Difference_engine&#34;&gt;差分機&lt;/a&gt;、構思的&lt;a href=&#34;https://en.wikipedia.org/wiki/Analytical_Engine&#34;&gt;分析機&lt;/a&gt;。這種機械式的自動計算儀器，之所以能夠 &amp;ldquo;let it go&amp;rdquo; 放手讓它埋頭苦幹，背後的必要條件，就是我們人類要先將演算步驟不含糊地條列出來。精準，嚴密，一點瑕疵都不行。&lt;/p&gt;
&lt;p&gt;此處的「演算步驟」，其實就是 algorithm。&lt;/p&gt;
&lt;p&gt;Algorithm 最古可追溯至&lt;a href=&#34;https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&#34;&gt;質數的篩法&lt;/a&gt;，可說是流著貴族的血液呢。後來一堆長除法、輾轉相除法、因數分解，都是 algorithm 的具體實例。&lt;/p&gt;
&lt;p&gt;這麼說，algorithm 只是附庸於數學底下的「機械性計算」層次？&lt;/p&gt;
&lt;p&gt;其實不然。近代比較正視 algorithm 價值、予以扶正地位的，要算是 19 世紀末開始的一系列數學革命，像 1900 年德國數學家希爾伯特提出的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Hilbert%27s_problems&#34;&gt;23 道難題&lt;/a&gt;，希望替數學建立起一套公理化體系＋形式化自動推導證明機制，以正本清源解決 19 世紀末開始出現的一堆撼動古典數學根基的&lt;a href=&#34;https://en.wikipedia.org/wiki/Non-Euclidean_geometry&#34;&gt;非歐幾何&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Georg_Cantor#Paradoxes_of_set_theory&#34;&gt;集合悖論&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Russell%27s_paradox&#34;&gt;邏輯悖論&lt;/a&gt;。雖然這種夢想被著名的&lt;a href=&#34;https://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems&#34;&gt;哥爾德不完備定理&lt;/a&gt;粉碎，但也從根本提升整個 algorithm 的理論地位，不再只是單純的「計算」而已。摘錄一段維基百科對這段歷史轉折的&lt;a href=&#34;https://en.wikipedia.org/wiki/Algorithm&#34;&gt;說明&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The concept of &lt;em&gt;algorithm&lt;/em&gt; has existed for centuries; however, a partial formalization of what would become the modern &lt;em&gt;algorithm&lt;/em&gt; began with attempts to solve the &lt;a href=&#34;https://en.wikipedia.org/wiki/Entscheidungsproblem&#34; title=&#34;Entscheidungsproblem&#34;&gt;Entscheidungsproblem&lt;/a&gt; (the &amp;ldquo;decision problem&amp;rdquo;) posed by &lt;a href=&#34;https://en.wikipedia.org/wiki/David_Hilbert&#34; title=&#34;David Hilbert&#34;&gt;David Hilbert&lt;/a&gt; in 1928. Subsequent formalizations were framed as attempts to define &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Effective_calculability&#34; title=&#34;Effective calculability&#34;&gt;effective calculability&lt;/a&gt;&amp;rdquo; or &amp;ldquo;effective method&amp;rdquo;; those formalizations included the &lt;a href=&#34;https://en.wikipedia.org/wiki/Kurt_G%C3%B6del&#34; title=&#34;Kurt Gödel&#34;&gt;Gödel&lt;/a&gt;–&lt;a href=&#34;https://en.wikipedia.org/wiki/Jacques_Herbrand&#34; title=&#34;Jacques Herbrand&#34;&gt;Herbrand&lt;/a&gt;–&lt;a href=&#34;https://en.wikipedia.org/wiki/Stephen_Cole_Kleene&#34; title=&#34;Stephen Cole Kleene&#34;&gt;Kleene&lt;/a&gt; &lt;a href=&#34;https://en.wikipedia.org/wiki/Recursion_%28computer_science%29&#34; title=&#34;Recursion (computer science)&#34;&gt;recursive functions&lt;/a&gt; of 1930, 1934 and 1935, &lt;a href=&#34;https://en.wikipedia.org/wiki/Alonzo_Church&#34; title=&#34;Alonzo Church&#34;&gt;Alonzo Church&lt;/a&gt;&amp;rsquo;s &lt;a href=&#34;https://en.wikipedia.org/wiki/Lambda_calculus&#34; title=&#34;Lambda calculus&#34;&gt;lambda calculus&lt;/a&gt; of 1936, &lt;a href=&#34;https://en.wikipedia.org/wiki/Emil_Post&#34; title=&#34;Emil Post&#34;&gt;Emil Post&lt;/a&gt;&amp;rsquo;s &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Formulation_1&#34; title=&#34;Formulation 1&#34;&gt;Formulation 1&lt;/a&gt;&amp;rdquo; of 1936, and &lt;a href=&#34;https://en.wikipedia.org/wiki/Alan_Turing&#34; title=&#34;Alan Turing&#34;&gt;Alan Turing&lt;/a&gt;&amp;rsquo;s &lt;a href=&#34;https://en.wikipedia.org/wiki/Turing_machines&#34; title=&#34;Turing machines&#34;&gt;Turing machines&lt;/a&gt; of 1936–7 and 1939. Giving a formal definition of algorithms, corresponding to the intuitive notion, remains a challenging problem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這就是前面我講的「嚴格來說，運算思維與其他領域（非 &lt;a href=&#34;https://en.wikipedia.org/wiki/Science,_technology,_engineering,_and_mathematics&#34;&gt;STEM&lt;/a&gt; 領域尤然）最大分野，就是演算法 (algorithm) 了。」&lt;/p&gt;
&lt;p&gt;所以，不要以為資訊系成天都只有在做「寫寫程式」這種連早慧的小學生都會的事呀。&lt;/p&gt;
&lt;p&gt;（謎之音：維基百科短短的一段話，卻數盡當年 algorithms、formal languages 課程中令人生畏的高等議題呀。）&lt;/p&gt;
&lt;h2 id=&#34;白話版解釋&#34;&gt;白話版解釋&lt;/h2&gt;
&lt;p&gt;當然啦，大家現在常在講的 &amp;ldquo;computational thinking&amp;rdquo;，講「運算思維」，多半沒有觸及這麼深的理論層次。&lt;/p&gt;
&lt;p&gt;如果不要扯到這麼遠，回到比較貼近一般人的角度，能不能具體講講 algorithm 是什麼，in plain English？&lt;/p&gt;
&lt;p&gt;經典教科書 &lt;a href=&#34;https://mitpress.mit.edu/books/introduction-algorithms&#34;&gt;&lt;em&gt;Introduction to Algorithms&lt;/em&gt;&lt;/a&gt; 給了一份十分親民的解釋：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Informally, an &lt;strong&gt;algorithm&lt;/strong&gt; is any well-defined computational procedure that takes some value, or set of values, as &lt;strong&gt;input&lt;/strong&gt; and produces some value, or set of values, as &lt;strong&gt;output&lt;/strong&gt;. An algorithm is thus a sequence of computational steps that transform the input into the output.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;維基百科也給了一段親民的&lt;a href=&#34;https://en.wikipedia.org/wiki/Algorithm&#34;&gt;開場白&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In mathematics and computer science, an &lt;strong&gt;algorithm&lt;/strong&gt; is a self-contained step-by-step set of operations to be performed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;關鍵字：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;well-defined computational procedure&lt;/li&gt;
&lt;li&gt;a sequence of computational steps&lt;/li&gt;
&lt;li&gt;self-contained step-by-step set of operations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以，如果用很粗淺的白話角度來看 algorithm，就是：根據明確給定的指示，一步步執行的有限步驟集合；自給自足，不假外求。&lt;/p&gt;
&lt;p&gt;一點也不神秘吧？&lt;/p&gt;
&lt;p&gt;當然啦，要再深究的話，即使是上面這段非常非常粗淺的親民說法，也是有很多值得進一步提問的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;怎樣的指示 (computational step/procedure/operation) 才叫做明確 (well-defined)？&lt;/li&gt;
&lt;li&gt;怎樣才叫做自給自足 (self-contained)？&lt;/li&gt;
&lt;li&gt;怎樣才叫做一步步執行 (step by step)？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不斷追問，就能追問出其他領域（非 STEM 領域尤然）不太探討的深層議題了，但是，我知道你不想再回頭看到太理論的論述⋯⋯姑且就此打住。&lt;/p&gt;
&lt;h2 id=&#34;心法&#34;&gt;心法&lt;/h2&gt;
&lt;p&gt;看了 algorithm 的俗民版操作型定義之後，進一步思考：algorithm 的目的是什麼？&lt;/p&gt;
&lt;p&gt;冼鏡光在《&lt;a href=&#34;http://www.books.com.tw/products/0010488984&#34;&gt;名題精選百則&lt;/a&gt;》提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;從某個角度來看，計算機科學都是在為寫作程式服務：吸收各行各業，各個不同科目、範疇而來的問題，分析那些問題，並且可能的話，找出一個「高效率」的演算法來解決問題。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;各行各業的問題，變化萬千，所以，單以直覺來想像，解決手法一定也是五花八門。&lt;/p&gt;
&lt;p&gt;是的，只要翻開任何一本演算法經典級教科書的目錄，一定會震懾於演算法的數量。&lt;/p&gt;
&lt;p&gt;不過，這些書也告訴我們，繁多花招之餘，還是有一些獨孤九劍等級的「破xx式」。&lt;/p&gt;
&lt;p&gt;像 CLR 白皮書 &lt;a href=&#34;https://mitpress.mit.edu/books/introduction-algorithms&#34;&gt;&lt;em&gt;Introduction to Algorithms&lt;/em&gt;&lt;/a&gt; 就將 &amp;ldquo;Divide and Conquer&amp;rdquo;（分而治之）及 recursion（遞迴、遞歸）列為重要的基礎心法，而 &lt;a href=&#34;https://www.amazon.com/Introduction-Algorithms-Creative-Udi-Manber/dp/0201120372&#34;&gt;&lt;em&gt;Introduction to Algorithms: A Creative Approach&lt;/em&gt;&lt;/a&gt; 一書甚至將 &amp;ldquo;Design of Algorithms by Induction&amp;rdquo; 這種數學歸納法、遞迴法視為最值得深刻掌握的通用心法。&lt;/p&gt;
&lt;p&gt;所以，分而治之、遞迴，是 algorithm 的重要核心。不能說是全部，但至少是重要的關鍵。&lt;/p&gt;
&lt;h2 id=&#34;實例&#34;&gt;實例&lt;/h2&gt;
&lt;p&gt;以文章開頭的等差級數為例，如果用&lt;strong&gt;分而治之&lt;/strong&gt;觀念來思考，該怎麼做呢？&lt;/p&gt;
&lt;p&gt;我們可能會先把 1+2+3+&amp;hellip;+100 的大問題，拆成 1+2+3 這種較容易處理的小問題，之後再利用加法的結合律去合併出最終答案。因此，先針對 1+2+3 這個小問題來思考：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sum := 0&lt;br&gt;
sum := sum + 1&lt;br&gt;
sum := sum + 2&lt;br&gt;
sum := sum + 3&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果懂得觀察箇中的&lt;strong&gt;模式&lt;/strong&gt;、&lt;strong&gt;規律&lt;/strong&gt;：「啊，不就只是一直把 1 加上去，把 2 加上去，把 3 加上去嘛！」，就會用初級的迴圈改寫成：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sum := 0&lt;br&gt;
for i := 1 to 3 do&lt;br&gt;
　　sum := sum + i&lt;br&gt;
end for&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;懂得寫到這一步，基本上，1+2+3+&amp;hellip;+100 就不是難事了。&lt;/p&gt;
&lt;p&gt;如果沒在數學課堂上睡著，學過&lt;a href=&#34;https://en.wikipedia.org/wiki/Mathematical_induction&#34;&gt;數學歸納法&lt;/a&gt;，會發現，這簡直就是天生的&lt;strong&gt;遞迴&lt;/strong&gt;應用：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;function sigma(n) :=&lt;br&gt;
if (n &amp;lt;= 1) return 1;&lt;br&gt;
else return n + sigma(n - 1);&lt;br&gt;
end function&lt;/p&gt;
&lt;p&gt;sum := sigma(100)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，小結一下：&lt;strong&gt;分而治之&lt;/strong&gt;、&lt;strong&gt;遞迴&lt;/strong&gt;、觀察尋求&lt;strong&gt;模式&lt;/strong&gt;及&lt;strong&gt;規律&lt;/strong&gt;，是 algorithm 的重要核心。不能說是全部，但至少是重要的關鍵。&lt;/p&gt;
&lt;h2 id=&#34;四大核心&#34;&gt;四大核心&lt;/h2&gt;
&lt;p&gt;咦，「分而治之」、「遞迴」、「模式及規律」，好熟悉的字眼⋯⋯豈不正與運算思維的另外三大核心相呼應嗎？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;呼應 &lt;strong&gt;decomposition&lt;/strong&gt; 原則：分而治之的第一階段，就是在對原始問題進行拆解、分解，變成容易解決的次問題，或是在過程中容易尋求規律。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;呼應 &lt;strong&gt;pattern recognition&lt;/strong&gt; 原則：遞迴，就是在針對初步切分的小問題，嘗試識別模式、尋求規律，以形成模式假說。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;呼應 &lt;strong&gt;abstraction&lt;/strong&gt; 原則：遞迴，就是將原始問題提升至抽象層次，在抽象層次解決。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以，運算思維的前三核心（decomposition、pattern recognition、abstraction），是第四核心 (algorithm) 的重要基礎。而我前一篇文章〈&lt;a href=&#34;//william-yeh.net/post/2016/08/on-computational-thinking/&#34;&gt;運算思維其實一點也不神祕&lt;/a&gt;〉就在申論：前三核心的能力，本來就是語文課程及數學課程就該好好培養的，並不是只有程式設計課程才能培養。&lt;/p&gt;
&lt;p&gt;只不過，現今的語文課程及數學課程，花太多精力在搞背誦、蒐集解題花招，而沒有踏實聚焦在王道的議題探索及解題思維上，導致 literacy capability 及 problem solving 能力都不足。&lt;/p&gt;
&lt;p&gt;這種貧乏的基礎，能夠進一步灌輸 computational thinking 嗎？&lt;/p&gt;
&lt;h2 id=&#34;總結&#34;&gt;總結&lt;/h2&gt;
&lt;p&gt;可以做個大總結了。&lt;/p&gt;
&lt;p&gt;運算思維 (computational thinking)，目前公認的四大核心是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Decomposition：拆解、分解。&lt;/li&gt;
&lt;li&gt;Pattern recognition：模式識別、規律尋求。&lt;/li&gt;
&lt;li&gt;Abstraction：抽象化。&lt;/li&gt;
&lt;li&gt;Algorithms：演算法、演算法則。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這些核心能力，都不盡然只有在程式設計課程才能培養。即使是與其他領域最大分野：algorithm，也有相當大的比例是奠基在前三項基本功。&lt;/p&gt;
&lt;p&gt;君子務本，本立而道生。你看得出來基礎教育該著重在哪一個「本」了嗎？&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ &lt;a href=&#34;//william-yeh.net/post/2016/08/on-computational-thinking/&#34;&gt;運算思維其實一點也不神祕（上集）&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;❷ 演算法也有不神祕的一面（下集）&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>運算思維其實一點也不神祕（上集）</title>
      <link>//william-yeh.net/post/2016/08/on-computational-thinking/</link>
      <pubDate>Mon, 08 Aug 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/on-computational-thinking/</guid>
      
        <description>&lt;p&gt;遠見雜誌 2016/04 的專題〈&lt;a href=&#34;http://store.gvm.com.tw/article_content_30968.html&#34;&gt;22 億人玩程式，擁抱跨界力&lt;/a&gt;〉一連數篇專文，提到許多驚人的趨勢：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/coding-trends.jpg&#34; alt=&#34;程式設計的趨勢&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/coding-trends.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;程式設計的趨勢&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;因此，如〈&lt;a href=&#34;https://www.facebook.com/notes/shih-hao-hung/%E8%B3%87%E8%A8%8A%E7%A7%91%E6%8A%80%E6%95%99%E8%82%B2%E8%AA%B2%E7%B6%B1%E5%88%B6%E8%A8%82%E8%88%87%E5%BE%8C%E7%BA%8C%E7%99%BC%E5%B1%95/1220387071325766&#34;&gt;資訊科技教育、課綱制訂與後續發展&lt;/a&gt;〉一文所述，台灣當局也動了起來。&lt;/p&gt;
&lt;p&gt;不過，我們的政府，除了不落人後的心態，南橘北枳的習氣也叫人擔心。&lt;/p&gt;
&lt;p&gt;我就忍不住調侃：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;很快的，市面上就會有給國中生的程式設計補習班了。&lt;/p&gt;
&lt;p&gt;⋯⋯其實現在早就有給國小的 Lego Scratch 才藝班⋯⋯&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;許多有志之士紛紛為文。像蘇文鈺教授在〈&lt;a href=&#34;http://www.bnext.com.tw/article/view/id/38362&#34;&gt;資訊科學納入大學通識課程，可能嗎？&lt;/a&gt;〉提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我恐怕，跟著美國人的教育政策，學到的若只是皮毛，最後還是一樣補習班或才藝班滿天飛，孩子們多了更多東西要補，豈不悲哀？但是，衡諸過去的台灣經驗，只要列入課綱，考試要考，升學必須，利之所趨，豈有不大補特補呢？家長觀念不改，教育單位政策不能慎重，恐怕台灣的競爭力會每下愈況啊！&lt;/p&gt;
&lt;p&gt;為什麼我說過我怕資訊科學被納入通識課程呢？原因就在此，我們太擅長把一樣東西當作教條，「廣泛」施行，從教學效率上來看，這沒什麼錯，但是這卻會違反資訊作為「科學」二字的含義。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;洪士灝教授也&lt;a href=&#34;https://www.facebook.com/shihhaohung/posts/1065348180174336&#34;&gt;為文&lt;/a&gt;提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這是目前教育上常見到共同問題，所以我不希望在資訊教育中教得太複雜，希望多一些實作類的專題，讓學生多些自由發揮的空間，也就是所謂的 project-based learning 的概念。同時，還希望利用資訊教育，把其他學科的東西帶進來活用，培養跨領域的概念。&lt;/p&gt;
&lt;p&gt;這是國外大學當前在推所謂的「&lt;strong&gt;基石&lt;/strong&gt;（&lt;strong&gt;cornerstone&lt;/strong&gt;）課程」的概念，資訊系不見得要和傳統課程那樣按部就班由程式語言學起，然後是演算法、物件導向、自動機、系統程式、作業系統、計算機結構等等，而是先告訴學生資訊技術可以解決哪些有趣的問題，以及如何實際利用工具解決問題，再告訴他們裡面有哪些複雜的問題會在以後哪些課程中教到。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;另一篇文章〈&lt;a href=&#34;https://vocus.cc/tuna/5c18831338053485a15d19ac&#34;&gt;資訊通識教育與計算思維怎麼教？&lt;/a&gt;〉也提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;會寫程式不代表一定懂計算思維，反過來說，懂運算思維不見得會寫好程式。所以，我並不是說不要教程式設計，而是不希望過於強調程式設計，因而框限了學習內容和未來的發展性。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在這類較中肯的意見中，&lt;strong&gt;運算思維 (computational thinking)&lt;/strong&gt; 是個反覆出現的關鍵詞。&lt;/p&gt;
&lt;h2 id=&#34;四大核心&#34;&gt;四大核心&lt;/h2&gt;
&lt;p&gt;「運算思維」，聽起來既神祕，又抽象。滿容易震懾外行人的。&lt;/p&gt;
&lt;p&gt;其實並沒有太神祕複雜。網路搜尋一下，很容易找到解釋：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wikipedia 條目：&lt;a href=&#34;https://en.wikipedia.org/wiki/Computational_thinking&#34;&gt;Computational thinking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;某程式設計學苑介紹文：&lt;a href=&#34;http://blog.orangeapple.tw/posts/what-is-computational-thinking/&#34;&gt;程式初學者的失落之鑰 – “Computational Thinking”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kids Coding Studio 介紹文：&lt;a href=&#34;http://www.kidscoding.tw/2016/06/blog-post.html&#34;&gt;什麼是運算思維？如何培養運算思維？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;某教室介紹文：&lt;a href=&#34;http://www.erichuang.com/370963385326684/computational_thinking&#34;&gt;程式設計 ⇒ 運算思維 ⇒ 數位素養&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;從這些資訊中，可看到目前公認的運算思維四大核心是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Decomposition：拆解、分解。&lt;/li&gt;
&lt;li&gt;Pattern recognition：模式識別、規律尋求。&lt;/li&gt;
&lt;li&gt;Abstraction：抽象化。&lt;/li&gt;
&lt;li&gt;Algorithms：演算法、演算法則。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;近親&#34;&gt;近親&lt;/h2&gt;
&lt;p&gt;其實「運算思維」沒有太神祕複雜，也不全然是計算機領域的專利。像 decomposition 原則，在專案管理領域的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Work_breakdown_structure&#34;&gt;WBS&lt;/a&gt;、企劃寫作的 &lt;a href=&#34;http://wiki.mbalib.com/wiki/MECE%E5%88%86%E6%9E%90%E6%B3%95&#34;&gt;MECE&lt;/a&gt;，都有類似的觀念；像 pattern recognition 原則，是任何解題活動都會運用的歸納法及假設法；像 abstraction 原則，更是所有系統化學問一致強調的心法。&lt;/p&gt;
&lt;p&gt;其實「運算思維」沒有太神祕複雜，甚至在近親的數學領域也都有，像經典級的 &lt;a href=&#34;https://en.wikipedia.org/wiki/How_to_Solve_It&#34;&gt;&lt;em&gt;How to Solve It&lt;/em&gt;&lt;/a&gt;（中譯本：《&lt;a href=&#34;https://www.books.com.tw/products/0010786452&#34;&gt;怎樣解題&lt;/a&gt;》），或是像《&lt;a href=&#34;http://www.books.com.tw/products/0010708574&#34;&gt;德國一流大學教你數學家的 22 個思考工具&lt;/a&gt;》這本，都有許多論述。&lt;/p&gt;
&lt;p&gt;以 George Pólya 的經典 &lt;a href=&#34;https://en.wikipedia.org/wiki/How_to_Solve_It&#34;&gt;&lt;em&gt;How to Solve It&lt;/em&gt;&lt;/a&gt; 為例，它的「啟發術小辭典」列了這些解題思維：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Analogy&lt;/li&gt;
&lt;li&gt;Generalization&lt;/li&gt;
&lt;li&gt;Induction&lt;/li&gt;
&lt;li&gt;Variation of the Problem&lt;/li&gt;
&lt;li&gt;Auxiliary Problem (subproblem/subgoal)&lt;/li&gt;
&lt;li&gt;Pattern recognition&lt;/li&gt;
&lt;li&gt;Pattern matching&lt;/li&gt;
&lt;li&gt;Reduction&lt;/li&gt;
&lt;li&gt;Specialization&lt;/li&gt;
&lt;li&gt;Decomposing and Recombining (Divide and conquer)&lt;/li&gt;
&lt;li&gt;Working backward&lt;/li&gt;
&lt;li&gt;Draw a Figure&lt;/li&gt;
&lt;li&gt;Auxiliary Elements (extension)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你看，是不是早已把現在很潮的「運算思維」四大核心涵蓋在內了？&lt;/p&gt;
&lt;p&gt;再以《&lt;a href=&#34;http://www.books.com.tw/products/0010708574&#34;&gt;德國一流大學教你數學家的 22 個思考工具&lt;/a&gt;》列的 22 項法寶為例：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;類比原則&lt;/li&gt;
&lt;li&gt;富比尼原理&lt;/li&gt;
&lt;li&gt;奇偶原理&lt;/li&gt;
&lt;li&gt;狄利克雷原理&lt;/li&gt;
&lt;li&gt;排容原理&lt;/li&gt;
&lt;li&gt;相反原則&lt;/li&gt;
&lt;li&gt;歸納原則&lt;/li&gt;
&lt;li&gt;一般化原則&lt;/li&gt;
&lt;li&gt;特殊化原則&lt;/li&gt;
&lt;li&gt;變化原則&lt;/li&gt;
&lt;li&gt;不變性原理&lt;/li&gt;
&lt;li&gt;單向變化原則&lt;/li&gt;
&lt;li&gt;無窮遞減法則&lt;/li&gt;
&lt;li&gt;對稱原理&lt;/li&gt;
&lt;li&gt;極值原理&lt;/li&gt;
&lt;li&gt;遞迴原理&lt;/li&gt;
&lt;li&gt;步步逼近原則&lt;/li&gt;
&lt;li&gt;著色原理&lt;/li&gt;
&lt;li&gt;隨機化原則&lt;/li&gt;
&lt;li&gt;轉換觀點原則&lt;/li&gt;
&lt;li&gt;模組化原則&lt;/li&gt;
&lt;li&gt;蠻力原則&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你看，是不是在實踐層次，也和現在很潮的「運算思維」四大核心高度呼應？&lt;/p&gt;
&lt;p&gt;所以，數學教育好好落實，其實也已經在打穩「運算思維」的基礎。&lt;/p&gt;
&lt;p&gt;只是傳統數學教學被炫麗解題花招綁架了，導致數學教育失靈。&lt;/p&gt;
&lt;p&gt;只要第一線教育現場不重視根本思維，那麼，再多一個程式設計課，就會提升下一代素質嗎……？&lt;/p&gt;
&lt;h2 id=&#34;最大分野&#34;&gt;最大分野&lt;/h2&gt;
&lt;p&gt;運算思維，目前公認有四大核心。&lt;/p&gt;
&lt;p&gt;嚴格來說，運算思維與其他領域（非 &lt;a href=&#34;https://en.wikipedia.org/wiki/Science,_technology,_engineering,_and_mathematics&#34;&gt;STEM&lt;/a&gt; 領域尤然）最大分野，就是 algorithm（演算法）了。&lt;/p&gt;
&lt;p&gt;不過，這又是&lt;a href=&#34;//william-yeh.net/post/2016/08/on-algorithm-myth/&#34;&gt;另一篇長文&lt;/a&gt;才能探討的了。&lt;/p&gt;
&lt;p&gt;（其實小學數學的長除法、輾轉相除法、因數分解，就是一種演算法⋯⋯）&lt;/p&gt;
&lt;h2 id=&#34;語文素養&#34;&gt;語文素養&lt;/h2&gt;
&lt;p&gt;最近，為了教小孩數學解題思維，重拾高中時代指定讀物 &lt;a href=&#34;https://en.wikipedia.org/wiki/How_to_Solve_It&#34;&gt;&lt;em&gt;How to Solve It&lt;/em&gt;&lt;/a&gt;（當年我用的是張憶壽教授的譯本，而不是現在市面上通行的&lt;a href=&#34;https://www.books.com.tw/products/0010786452&#34;&gt;天下文化譯本&lt;/a&gt;），尋求好的引導方法。&lt;/p&gt;
&lt;p&gt;突然發現，這本奇書，何止數學會用到，語文的 literacy capability、電腦的 computational thinking，也都會用到這本書的思維心法。&lt;/p&gt;
&lt;p&gt;談數學的書，也會重視 literacy capability？會不會扯太遠了？&lt;/p&gt;
&lt;p&gt;證據在此，請看看以下的解題提示表，不折不扣的 literacy capability 應用：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/how-to-solve-it-hints.jpg&#34; alt=&#34;How to Solve It 解題提示表&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/how-to-solve-it-hints.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;How to Solve It 解題提示表&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這本書也提倡：在解題的各個環節，要善加運用所謂的「啟發式問句」自我提問。譬如說，在「了解問題」方面，可以如此提問：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What are you asked to find or show?&lt;/li&gt;
&lt;li&gt;Can you restate the problem in your own words?&lt;/li&gt;
&lt;li&gt;Can you think of a picture or a diagram that might help you understand the problem?&lt;/li&gt;
&lt;li&gt;Is there enough information to enable you to find a solution?&lt;/li&gt;
&lt;li&gt;Do you understand all the words used in stating the problem?&lt;/li&gt;
&lt;li&gt;Do you need to ask a question to get the answer?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;看出來了嗎？像語文學習的 literacy capability，像《&lt;a href=&#34;http://www.books.com.tw/products/0010226097&#34;&gt;如何閱讀一本書&lt;/a&gt;》講的「&lt;a href=&#34;//william-yeh.net/post/2016/08/reading-vs-extensive-reading/&#34;&gt;主動閱讀&lt;/a&gt;」，不也正是要主動思索探究這類問題嗎？&lt;/p&gt;
&lt;p&gt;許多領域，核心原則是共通的。&lt;/p&gt;
&lt;p&gt;學苟知本，六經皆我註腳。&lt;/p&gt;
&lt;h2 id=&#34;底子&#34;&gt;底子&lt;/h2&gt;
&lt;p&gt;其實，好好把語文及數學的底子打好，更重要。&lt;/p&gt;
&lt;p&gt;不過，不是成天搞背誦、蒐集解題花招，而是踏實聚焦在 &lt;a href=&#34;https://en.wikipedia.org/wiki/How_to_Solve_It&#34;&gt;&lt;em&gt;How to Solve It&lt;/em&gt;&lt;/a&gt; 這類王道的議題探索及解題思維上。&lt;/p&gt;
&lt;p&gt;解題思維穩了，以後要進軍其他範疇，都容易許多。否則，再多的科目，再多的考試，也只是花拳繡腿。&lt;/p&gt;
&lt;p&gt;（謎之音：連修辭格都要背誦的語文教育，是什麼樣的語文教育呀⋯⋯）&lt;/p&gt;
&lt;h2 id=&#34;真的準備好了嗎&#34;&gt;真的準備好了嗎？&lt;/h2&gt;
&lt;p&gt;搜尋，排序，陣列，不是不能教，而是看怎麼教。&lt;/p&gt;
&lt;p&gt;如果用冼鏡光當年 &lt;em&gt;PC Magazine&lt;/em&gt; 連載文章所用的引導方法，或是我愛用的既有知識或現實世界類比方法，其實是辦得到的。像當年我教大學生迴圈時，就是用國中數學的等差級數、等比級數為引子。先備知識，是很重要的學習遷移資源。&lt;/p&gt;
&lt;p&gt;數學教育好好落實，其實也已經在打穩「運算思維」的基礎。只是傳統數學教學被炫麗解題花招綁架了，導致數學教育失靈。&lt;/p&gt;
&lt;p&gt;只要第一線教育現場不重視根本思維，那麼，再多一個程式設計課，就會提升下一代素質嗎⋯⋯？&lt;/p&gt;
&lt;p&gt;切記洪教授諄諄提醒的：「不要教太難、教學時間要足夠、課程要設計好、師資要準備好，要做的話就要有充分的資源來做，不然會做不好。」&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 運算思維其實一點也不神祕（上集）&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2016/08/on-algorithm-myth/&#34;&gt;演算法也有不神祕的一面（下集）&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>精讀 vs 泛讀</title>
      <link>//william-yeh.net/post/2016/08/reading-vs-extensive-reading/</link>
      <pubDate>Tue, 02 Aug 2016 23:30:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/reading-vs-extensive-reading/</guid>
      
        <description>&lt;p&gt;每隔一陣子，就有「精讀」與「泛讀」孰優孰劣之辯論。&lt;/p&gt;
&lt;p&gt;其實，就像陳年經典《&lt;a href=&#34;http://www.books.com.tw/products/0010226097&#34;&gt;如何閱讀一本書&lt;/a&gt;》所說，兩種技巧都很需要：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;閱讀的速度並非只有單一的一種，重點在如何讀出&lt;strong&gt;不同的速度感&lt;/strong&gt;，知道在閱讀某種讀物時該用什麼樣的速度。&lt;/p&gt;
&lt;p&gt;更好的秘方是：在閱讀一本書的時候，&lt;strong&gt;慢不該慢到不值得，快不該快到有損於滿足與理解。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;快或慢，端看閱讀的當下，自我定位是在哪一層次：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;基礎閱讀 (elementary reading)&lt;/li&gt;
&lt;li&gt;檢視閱讀 (inspectional reading)、系統化略讀 (skimming systematically)&lt;/li&gt;
&lt;li&gt;分析閱讀 (analytical reading)&lt;/li&gt;
&lt;li&gt;主題閱讀 (syntopical reading)、比較閱讀 (comparative reading)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;此書主張，主動的讀者，至少要掌握到「檢視閱讀」的層次：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;檢視閱讀永遠是充滿&lt;strong&gt;主動&lt;/strong&gt;的，那是需要努力，而非毫不費力的閱讀。&lt;/p&gt;
&lt;p&gt;只要是超越「基礎閱讀」的層次，閱讀的藝術，就是要&lt;strong&gt;以適當的順序，提出適當的問題&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;提出什麼問題呢？至少有四個主要問題：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;整體來說，這本書到底在談些什麼？&lt;/li&gt;
&lt;li&gt;作者細部說了什麼，怎麼說的？&lt;/li&gt;
&lt;li&gt;這本書說得有道理嗎？是全部有道理，還是部分有道理？&lt;/li&gt;
&lt;li&gt;這本書跟你有什麼關係？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;《如何閱讀一本書》這本 1940 年初版、1972 年增訂再版的陳年經典，的確配得「經典」之名。這些論述，不正是後來許許多多讀書方法的書籍反覆闡釋的閱讀角度嗎？&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/on-reading.jpg&#34; alt=&#34;書籍閱讀法的書單&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/on-reading.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;書籍閱讀法的書單&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;泛讀&#34;&gt;泛讀&lt;/h2&gt;
&lt;p&gt;十倍速時代，資訊大爆炸。近年來，泛讀的聲勢高漲，不乏重量級人士站台背書。&lt;/p&gt;
&lt;p&gt;像 Zen大 在〈&lt;a href=&#34;https://zen1976.com/post-1367640680/&#34;&gt;讀書真的重質不重量嗎？&lt;/a&gt;〉提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;精讀派的朋友總是愛說，讀書重質不重量，但沒有量的累積，其實質變是發生不了的，因為你用來理解書中知識的基本能力都不具備！&lt;/p&gt;
&lt;p&gt;舉個例子好了，要讀懂海德格或胡賽爾，得先讀多少東西當預備知識？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;他甚至還開了一門「&lt;a href=&#34;https://zen1976.com/post-1360633850/&#34;&gt;超快速讀書法：教你一年輕鬆讀完三百本書&lt;/a&gt;」公開班呢！&lt;/p&gt;
&lt;h3 id=&#34;泛讀流派&#34;&gt;泛讀流派&lt;/h3&gt;
&lt;p&gt;泛讀也有許多流派。&lt;/p&gt;
&lt;p&gt;傳統的速讀派，最核心的技術就是革除默唸、眼腦直映。這是與傳統語文教育大相逕庭（如果稱不上「牴觸」的話）的方法。記得國中的我，被廣告吸引，主動報名楊氏速讀。一個暑假，換得終身受用的技能，很值得。&lt;/p&gt;
&lt;p&gt;體會到實用性，我也一直持續關注新的泛讀流派。我發現，許多泛讀流派都以《&lt;a href=&#34;http://www.books.com.tw/products/0010226097&#34;&gt;如何閱讀一本書&lt;/a&gt;》的「主題閱讀」為目標，但實施過程則改以「檢視閱讀」、「系統化略讀」之類的手法為之。以本田直之《&lt;a href=&#34;http://www.books.com.tw/products/0010378503&#34;&gt;槓桿閱讀術&lt;/a&gt;》為例：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;本書所強調的是「&lt;strong&gt;累積效果&lt;/strong&gt;」。在我常光顧的書店裡，據說一個月重新排列上架的商業類新書超過五百本。當然，也有大量之前出版過的舊書刊。雖然要追上全部的書籍，是不可能的，但是，靠著讀幾本同樣主題的書籍，常常從新書中取得資訊，你就&lt;strong&gt;漸漸&lt;/strong&gt;能掌握各種作者的想法。從這樣的過程中，你將會選出適合自己的讀物，這也是多讀的優點所在。&lt;/p&gt;
&lt;p&gt;你一旦這麼想，縱然對於現在所讀的書的內容還不能融會貫通，但這些內容的&lt;strong&gt;累積&lt;/strong&gt;會變成你的個人資產。接著，可自由運用的時間逐漸增加，最後得到一百倍的回報，並和你的「金融資產」增加連結在一起。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也有像神田昌典、勝間和代等人大力提倡的，乍看之下頗為詭異的「&lt;a href=&#34;http://www.books.com.tw/products/0010560460&#34;&gt;影像閱讀法&lt;/a&gt;」。因為太詭異了，甚至有點違反直覺，值得獨立挑出來談。&lt;/p&gt;
&lt;h3 id=&#34;影像閱讀法&#34;&gt;影像閱讀法&lt;/h3&gt;
&lt;p&gt;Paul R. Scheele 研發的影像閱讀法 (&lt;a href=&#34;https://www.amazon.com/dp/0925480681/ref=cm_sw_r_tw_dp_x_3HA5yb4M62972&#34;&gt;Photo Reading&lt;/a&gt;)，訴求是：我們可以像照相機一樣，將任何讀物內容快速地攝入腦袋中。&lt;/p&gt;
&lt;p&gt;前提是，請遵照影像閱讀法的五大步驟：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/photo-reading.jpg&#34; alt=&#34;影像閱讀法的五大步驟&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/photo-reading.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;影像閱讀法的五大步驟&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;即使你不信這一整套方法，也可以只把它當成工具箱，擇優取用。譬如說，我雖然並未練出所謂的「懸頁」、「軟視」、「攝像焦點」狀態，但其他技巧，卻是十分受用。&lt;/p&gt;
&lt;p&gt;就我有限的經驗來說，影像閱讀法的&lt;strong&gt;提問&lt;/strong&gt;及&lt;strong&gt;活化&lt;/strong&gt;方法很管用：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;用影像閱讀看選擇的書。在閱讀之前，一定要明確說出&lt;strong&gt;目的&lt;/strong&gt;。閱讀之後，請進行結束時的&lt;strong&gt;自我肯定&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;優秀的閱讀者總是會抱持著&lt;strong&gt;目的意識&lt;/strong&gt;，&lt;strong&gt;向作者提出問題&lt;/strong&gt;，而且在閱讀時保持高度的&lt;strong&gt;精神集中&lt;/strong&gt;。「精神集中」是積極閱讀者的必要條件。&lt;/p&gt;
&lt;p&gt;要誘導腦部把新的技能反映在行動上。型態療法的治療師把它稱為「&lt;strong&gt;意想遊戲&lt;/strong&gt;」，也就是在心裡面模擬該項行為，而那會成為傳送給腦部的信號，引發所要的行動。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;影像閱讀式的&lt;strong&gt;主題閱讀&lt;/strong&gt;也很有意思：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;阿德勒在《如何閱讀一本書》表示，進行同主題閱讀時使用的思考技巧，是閱讀者的終極目標。因此我們把十倍速影像閱讀法的技巧融入他們的技巧中，讓各式各樣的想法可以在更短的時間內有效整合。&lt;/p&gt;
&lt;p&gt;每次進行同主題閱讀時，都有幾百個或幾千個頭腦，累積幾萬個小時的努力和經驗來幫助你達成目標。當你感覺到這種強大的力量時，就能夠深深體會到同主題閱讀的美妙滋味。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;從這裡可看出，影像閱讀法也是在對《如何閱讀一本書》致敬，儘管細部手法不同。&lt;/p&gt;
&lt;h2 id=&#34;精讀&#34;&gt;精讀&lt;/h2&gt;
&lt;p&gt;其實我最喜歡的是精讀。對我來說，泛讀是不得已的；是找不到值得精讀的對象，或是還沒把自己拉拔到足以精讀的程度，才做的權宜之計。&lt;/p&gt;
&lt;p&gt;找到值得的對象，也自我裝備好了，我往往直接切換成精讀模式。&lt;/p&gt;
&lt;p&gt;就以我的本職學能「軟體開發」為例吧。&lt;em&gt;Ｎ&lt;/em&gt; 年前那本《資訊游俠列傳》的專訪文中就指出：我的電腦書不多，或者說，相對於非電腦書，其實比例不算高。&lt;/p&gt;
&lt;p&gt;怎・麼・可・能？&lt;/p&gt;
&lt;p&gt;答案很簡單，對於電腦專業，我是精讀取向。&lt;/p&gt;
&lt;p&gt;從高中時代愛不釋手的 &lt;a href=&#34;https://en.wikipedia.org/wiki/The_C_Programming_Language&#34;&gt;K&amp;amp;R 第二版&lt;/a&gt;，到研究所時代翻譯的 C++ FAQ、&lt;a href=&#34;http://www.books.com.tw/products/0010181914&#34;&gt;&lt;em&gt;The C++ Programming Language&lt;/em&gt;&lt;/a&gt;、&lt;a href=&#34;http://www.tenlong.com.tw/items/9572054112?item_id=997944&#34;&gt;GoF&lt;/a&gt;，莫不是硬上加硬的原典磚頭。&lt;/p&gt;
&lt;p&gt;磚頭書，不必以多取勝。&lt;/p&gt;
&lt;p&gt;為什麼會選擇濃縮原汁，不選擇稀釋飲品？或許是深受王鼎鈞《&lt;a href=&#34;http://www.books.com.tw/products/0010043322&#34;&gt;開放的人生&lt;/a&gt;》的影響吧：「以大為貴／&lt;strong&gt;看山要看大山。看書要看大書&lt;/strong&gt;。」&lt;/p&gt;
&lt;p&gt;這並不容易，是理解力與意志力的考驗；但攻克之後，為目四顧，登泰山而小天下。反觀坊間書肆一大堆稀釋品，高下立判。（而且，引經據典回答別人的問題，格外有成就感⋯⋯）&lt;/p&gt;
&lt;p&gt;會當凌絕頂，一覽眾山小。有為者，亦若是。&lt;/p&gt;
&lt;p&gt;陸象山說得好：「學苟知本，六經皆我註腳。」&lt;/p&gt;
&lt;h2 id=&#34;泛讀高手其實也是精讀高手&#34;&gt;泛讀高手，其實也是精讀高手&lt;/h2&gt;
&lt;p&gt;其實，即使是鼓吹大量閱讀、主題閱讀的人，也不敢忽視精讀的重要性。&lt;/p&gt;
&lt;p&gt;他們懂得把精讀的能量放在刀口上。&lt;/p&gt;
&lt;p&gt;像《&lt;a href=&#34;http://www.books.com.tw/products/0010534848&#34;&gt;40歲，好日子才開始&lt;/a&gt;》在推薦主題式讀書法之後，下一頁旋即話鋒一轉：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;很多年長一輩的人後悔當初沒有好好看些書，最多的理由就是「忙得找不出時間」。不想讓人瞧不起，可是沒有時間讀書的人，我建議使用「經典式閱讀法」。&lt;/p&gt;
&lt;p&gt;先找到自己認為最「經典」的書，有空隨手就拿起來讀，以這本書為「基本參考書」，專讀這一本。&lt;/p&gt;
&lt;p&gt;找到自己的「經典」書籍，反覆閱讀到&lt;strong&gt;幾乎將這本書熟記&lt;/strong&gt;的程度。到自己可以&lt;strong&gt;以這本書做演講&lt;/strong&gt;的地步，這樣的熟讀方式有其意義在。&lt;/p&gt;
&lt;p&gt;讀書量多少當然有其影響力。可是如果沒有時間讀很多書的人，可以試試讀熟一本書，熟到幾乎可以背出來的方式，內容確確實實可以完全被自己吸收。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;就連大力鼓吹影像閱讀法的勝間和代，在《&lt;a href=&#34;http://www.books.com.tw/products/0010434249&#34;&gt;新．知識生產術&lt;/a&gt;》中，也鼓勵挑戰一些磚頭書：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;最近，大家愈來愈不看書了，太厚的書、字太小的書、太貴的書，幾乎都賣不掉。&lt;/p&gt;
&lt;p&gt;但正因為如此，才更要挑戰那些大家不去看的書，這樣才能建立起與不挑戰的人之間的差異。&lt;/p&gt;
&lt;p&gt;讀書時，如果只讀暢銷書，可能會變成只吃精緻的加工食品一樣，因此希望各位偶爾也要像吃吃略微澀口的新鮮蔬菜一樣，挑戰一下難讀的書籍。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;就連大力鼓吹影像閱讀法的神田昌典，在《&lt;a href=&#34;http://www.books.com.tw/products/0010473958&#34;&gt;10 年後會留在書架上的 100 本書&lt;/a&gt;》中，出人意料的對宅急便之父&lt;a href=&#34;http://www.books.com.tw/products/0010675380&#34;&gt;小倉昌男的書&lt;/a&gt;推崇備至。評價高到，不僅要用眼睛看這本書，甚至還要&lt;strong&gt;用嘴巴唸出聲音來&lt;/strong&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這本書簡直就是訂定經營戰略的最佳教科書，我很想要各位在閱讀各種經營戰略的理論書之前，先拿起本書「讀出聲音來」。&lt;/p&gt;
&lt;p&gt;一字一句讀出聲音，每天早上起床後先花十分鐘讀出來。這本書甚至於到了「只要你能夠到達流利讀出來的地步，自然就能夠體會到如何制定經營戰略」的層次。&lt;/p&gt;
&lt;p&gt;如果想成為他那樣的商業人，就把姿勢坐正、讀出聲音來！&lt;/p&gt;
&lt;p&gt;讀出聲音，可以把它的經營者魂，刻畫在我們的血肉上。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我想，一個人一生中，總要有幾本值得讓我們「把姿勢坐正、讀出聲音來」的精讀書籍呀。&lt;/p&gt;
&lt;h2 id=&#34;最好的記憶&#34;&gt;最好的記憶&lt;/h2&gt;
&lt;p&gt;好書的營養成分，要銘刻在內心。&lt;/p&gt;
&lt;p&gt;唐諾在《&lt;a href=&#34;http://www.books.com.tw/products/0010286827&#34;&gt;閱讀的故事&lt;/a&gt;》如是說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;最好的記憶，不是一個單獨的、孤立無援的點或原子。最好的記憶，不管是經由刻意地背誦或自然而然的記得，總有它和我們內心&lt;strong&gt;共鳴共振&lt;/strong&gt;的所謂&lt;strong&gt;印象深刻成分&lt;/strong&gt;，它對我們而言總是有線索、有來歷甚至是有（暫時）秩序的，你知道該把它安置在自己記憶的哪個「櫃子」裡，他日要用時你也大概知道存放何處可以把它找出來。&lt;/p&gt;
&lt;p&gt;而因應著如此觸及內心的美好共鳴，通常在那相遇的驚心動魄一刻，你總會要自己&lt;strong&gt;暫時放緩腳步&lt;/strong&gt;甚至停下來。&lt;/p&gt;
&lt;p&gt;嚴格來說，惟有通過如此的記憶過程，那東西才完完全全變成「你的」，甚至它不再只是記憶了，而是你生命的一部份、身體的一部份，彷彿已從抽象的訊息，轉變成實體的筋骨肌理。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;值此境界，泛讀或精讀，已不再重要。物我交融，得意而忘言。&lt;/p&gt;
&lt;p&gt;在到達此境界之前，還是先乖乖修煉閱讀的技術吧。&lt;/p&gt;
&lt;p&gt;這是一生受用不盡的技術。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>請循其本</title>
      <link>//william-yeh.net/post/2016/08/back-to-the-origin/</link>
      <pubDate>Mon, 01 Aug 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/08/back-to-the-origin/</guid>
      
        <description>&lt;p&gt;老子曰：「五色令人目盲，五音令人耳聾。」&lt;/p&gt;
&lt;p&gt;所以，最近我越來越喜歡從原始定義或目標下手。&lt;/p&gt;
&lt;p&gt;原理通了，邏輯通了，再加一點點創意及想像力，很多東西都是順理成章就推導得出來。&lt;/p&gt;
&lt;p&gt;像物件導向設計領域常見的 &lt;a href=&#34;https://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29&#34;&gt;SOLID 原則&lt;/a&gt;，或是再精煉出來的「&lt;a href=&#34;http://teddy-chen-tw.blogspot.tw/2014/04/solid.html&#34;&gt;五則皆變&lt;/a&gt;」觀點，深刻體會後，你可以推導出許多 design patterns 或 bad smell 論述。&lt;/p&gt;
&lt;h2 id=&#34;關於-devops&#34;&gt;關於 DevOps&lt;/h2&gt;
&lt;p&gt;溯源能力是很重要的，才不會被狀似革新，實則舊瓶裝新酒或跨領域借用的「新觀念」所迷惑。&lt;/p&gt;
&lt;p&gt;像近年來很潮的 DevOps，你可以說是革新，因為它的的確確顛覆許多公司的陳年作風；但你也可以說它只是舊瓶裝新酒，只是把 &lt;a href=&#34;//william-yeh.net/post/2016/05/devops-a-lean-perspective/&#34;&gt;Lean Thinking 的五大原則&lt;/a&gt;應用到軟體產業上。&lt;/p&gt;
&lt;p&gt;是新，是舊？係主觀評論範疇，不重要；重要的是，你是否實實在在掌握到核心精髓，並予以實踐？&lt;/p&gt;
&lt;p&gt;掌握了，實踐了，那麼，得魚忘筌，是新，是舊，根本不重要。沒有掌握，沒有實踐，那麼，是新，是舊，也不是現在的你有資格過問的事、最該過問的事。&lt;/p&gt;
&lt;p&gt;莊子曰：「請循其本。」&lt;/p&gt;
&lt;h2 id=&#34;關於-docker&#34;&gt;關於 Docker&lt;/h2&gt;
&lt;p&gt;面對別人提出的技術問題或導入問題，最近也更傾向不直接給答案。&lt;/p&gt;
&lt;p&gt;孔子曰：「吾有知乎哉？無知也。有鄙夫問於我，空空如也，我叩其兩端而竭焉。」推導過程，才是最深刻的。&lt;/p&gt;
&lt;p&gt;像許多人對 Docker 提出的疑惑，其實只要回到 Docker slogan 所揭櫫的本質：&amp;ldquo;build, ship, run any app, anywhere&amp;rdquo;，再反思自身的 DevOps 環節，「叩其兩端而竭焉」，關鍵癥結往往呼之欲出。&lt;/p&gt;
&lt;p&gt;我常常用這類的話作為引子，回答各種 Docker 疑難雜症：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;這和 Docker 無關。請先假設這世界上沒有 Docker。 [&amp;hellip;]&lt;/p&gt;
&lt;p&gt;請回到還沒有 Docker 的時代，重新思考你的問題。 [&amp;hellip;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;或許是出現太多次了，還有網友評論道：「葉大最近挺常講這句話的&amp;hellip; 果然是 Dockerize 之前最重要的 mindset。」&lt;/p&gt;
&lt;p&gt;也順便預告一下：我在今年九月 &lt;a href=&#34;http://containersummit.ithome.com.tw/&#34;&gt;Container Summit 2016&lt;/a&gt; 的專題演講〈[Docker 導入：障礙與對策]({{-&amp;lt; ref &amp;ldquo;embrace-docker.md&amp;rdquo; &amp;gt;}})〉，大致上就是秉持這種「叩其兩端而竭焉」加上 TOC 思維方法的角度，從 Docker 的 UDE 一路推導至核心衝突。血淋淋，但看到癥結，才能對症下藥（或許是猛藥⋯⋯）。&lt;/p&gt;
&lt;h2 id=&#34;關於-toc--satir&#34;&gt;關於 TOC &amp;amp; Satir&lt;/h2&gt;
&lt;p&gt;既然我在〈&lt;a href=&#34;//william-yeh.net/post/2016/06/change-framework/&#34;&gt;改變的框架&lt;/a&gt;〉一文中預告，我想以「左腦高德拉特，右腦薩提爾」作為下半年課題，那麼，「請循其本」，我也該試著抓出兩者的核心本質，作為思考或應用的指引。&lt;/p&gt;
&lt;p&gt;關於高德拉特 TOC 的核心理念，在《&lt;a href=&#34;https://www.amazon.com/dp/B014HV1W5O&#34;&gt;抉擇&lt;/a&gt;》書中，透過高德拉特父女的機鋒對話，歸納出這幾點：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/08/toc-core-spirits.jpg&#34; alt=&#34;TOC 核心理念&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/08/toc-core-spirits.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;TOC 核心理念&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;至於饒富創意的薩提爾治療手法，背後有哪些核心原則呢？&lt;/p&gt;
&lt;p&gt;在《&lt;a href=&#34;http://www.books.com.tw/products/0010154716&#34;&gt;薩提爾治療實錄&lt;/a&gt;》書中，如此闡述薩提爾治療手法的基本價值與假設：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;欣賞各種生活風貌，並相信在適當條件下，每一種生活形式都朝向成長。&lt;/li&gt;
&lt;li&gt;假設當事人本身擁有自我成長的因子。治療者就如同園丁，了解美麗的植物成長所需的最佳環境，提供成長需要的肥料及灌溉。&lt;/li&gt;
&lt;li&gt;欣賞家庭歷程，及家庭的掙扎奮鬥與各種可能性。欣賞並不一定意味著喜愛，而是比較非判斷性的態度。&lt;/li&gt;
&lt;li&gt;開放的態度，願意運用人性化作為治療的工具。必須有能力創造一個我們自己能被觀察、傾聽、觸摸和瞭解的情境。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在《&lt;a href=&#34;http://www.books.com.tw/products/0010004784&#34;&gt;薩提爾的家族治療模式&lt;/a&gt;》書中，如此闡述薩提爾治療手法的普遍信念與原則（以下僅部分摘錄）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;「改變」是有可能的。&lt;/li&gt;
&lt;li&gt;我們都擁有內在資源，以成功地應對和成長。&lt;/li&gt;
&lt;li&gt;我們有許多選擇，特別是面對壓力做出「適當回應」，而不是對情況做出「即時反應」。&lt;/li&gt;
&lt;li&gt;治療需把重點放在健康與各種可能性上，而不是病態上。&lt;/li&gt;
&lt;li&gt;「希望」是「改變」的一大重要成分。&lt;/li&gt;
&lt;li&gt;人們因「相似」而聯結，因「差異」而成長。&lt;/li&gt;
&lt;li&gt;治療的主要目標是為自己做出選擇。&lt;/li&gt;
&lt;li&gt;「問題」不是問題；如何「應對問題」才是問題。&lt;/li&gt;
&lt;li&gt;大部分人傾向於選擇其所熟悉的，而非舒適自在，特別是在承受壓力之際。&lt;/li&gt;
&lt;li&gt;父母往往重複他們成長過程中所熟悉的模式，即使知道這些模式是功能不良的。&lt;/li&gt;
&lt;li&gt;我們無法改變過去已發生的事件，只能改變該事件對我們的影響。&lt;/li&gt;
&lt;li&gt;欣賞並接納過去，可以增加我們管理現在的能力。&lt;/li&gt;
&lt;li&gt;「應對方式」是自我價值層次的展現；自我價值愈高，應對方式就愈統整。&lt;/li&gt;
&lt;li&gt;「一致性」與「高自我價值感」是薩提爾模式的主要目標。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由此可見，「一致性」與「高自我價值感」是薩提爾模式的主要目標。&lt;/p&gt;
&lt;p&gt;其中，關於「一致性」(congruence) 的生活原則，《&lt;a href=&#34;http://www.books.com.tw/products/0010327427&#34;&gt;家庭如何塑造人&lt;/a&gt;》如此闡述：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;溝通清晰。&lt;/li&gt;
&lt;li&gt;合作而非競爭。&lt;/li&gt;
&lt;li&gt;賦予力量而非壓制。&lt;/li&gt;
&lt;li&gt;強調個人的獨特性，而非將之分類。&lt;/li&gt;
&lt;li&gt;運用權威去引導和完成「所該做的事」，而非透過獨裁的力量去強迫服從。&lt;/li&gt;
&lt;li&gt;全然地關愛、珍視和尊重自己。&lt;/li&gt;
&lt;li&gt;對自己和社會負責。&lt;/li&gt;
&lt;li&gt;視問題為挑戰和機會，以獲得創造性的解決方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至於「高自我價值感」，《&lt;a href=&#34;http://www.books.com.tw/products/0010004784&#34;&gt;薩提爾的家族治療模式&lt;/a&gt;》如此闡述：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/self-esteem.jpg&#34; alt=&#34;自我價值&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/self-esteem.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;自我價值&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;!-- raw HTML omitted --&gt; 
&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;呼！「請循其本」，其實並不簡單。&lt;/p&gt;
&lt;p&gt;但可喜的是：兩大方法的「本」，其實交會處甚多。儘管一剛一柔，但到了某個境界，百鍊鋼化為繞指柔，組合技可達到綜效。&lt;/p&gt;
&lt;p&gt;看完這一篇，以後看到我以問題反問你的提問，就別再驚訝了喔！&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>專業態度的養成</title>
      <link>//william-yeh.net/post/2016/07/professional-attitude/</link>
      <pubDate>Sat, 30 Jul 2016 17:35:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/07/professional-attitude/</guid>
      
        <description>&lt;p&gt;最近在面試資深軟體工程師。幾次下來，對幾家公司培養出來的員工素質，有個概括印象了（或許也帶點偏見）。&lt;/p&gt;
&lt;p&gt;一個最顛覆既定印象的心得是：不是在大公司就一定學得深，不是在新創就一定學得廣。&lt;/p&gt;
&lt;p&gt;重點仍在於自己。在於自己有沒有「&lt;strong&gt;系統思考&lt;/strong&gt;及&lt;strong&gt;換位思考&lt;/strong&gt;的&lt;strong&gt;自覺&lt;/strong&gt;及&lt;strong&gt;行動&lt;/strong&gt;」。&lt;/p&gt;
&lt;p&gt;或者再濃縮成：在於「&lt;strong&gt;專業態度&lt;/strong&gt;」。&lt;/p&gt;
&lt;h2 id=&#34;專業技能-vs-態度&#34;&gt;專業：技能 vs 態度&lt;/h2&gt;
&lt;p&gt;專業，有技能面及態度面。&lt;/p&gt;
&lt;p&gt;「專業技能」的成長，只要選對適性的方向，早晚都功不唐捐，尤其在學習資源既廣且深的今天。&lt;/p&gt;
&lt;p&gt;但「專業態度」的成長，除了操之於人的機運（天降的好運氣，或天殺的壞運氣），更多是取決於個人的&lt;strong&gt;自覺&lt;/strong&gt;及&lt;strong&gt;行動&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;專業技能固然重要，但是，能夠讓自己從流水帳的制式履歷表欄位中脫穎而出的，終究是專業態度。&lt;/p&gt;
&lt;p&gt;很準。只要針對每一份履歷表，個別客製化追問幾句，幾乎就能分辨出哪些人有下意識追求專業態度的成長。&lt;/p&gt;
&lt;h2 id=&#34;自覺&#34;&gt;自覺&lt;/h2&gt;
&lt;p&gt;專業態度的層面非常多，我最在意的是「&lt;strong&gt;系統思考&lt;/strong&gt;及&lt;strong&gt;換位思考&lt;/strong&gt;的&lt;strong&gt;自覺&lt;/strong&gt;及&lt;strong&gt;行動&lt;/strong&gt;」。&lt;/p&gt;
&lt;p&gt;這類專業態度，由誰來教？&lt;/p&gt;
&lt;p&gt;這不是公司能夠主動教你的。大公司不見得會主動教你，也未必所有公司都有像杜書伍、何飛鵬、稻盛和夫這樣的 mentor，不斷為文內訓（還集結出書）。資源有限的小公司，更是如此。&lt;/p&gt;
&lt;p&gt;如果公司沒有這樣的 mentor，就自己往外找吧。從優質社群找，從有信譽的名師、課程找，或者，從書本找。&lt;/p&gt;
&lt;p&gt;其實，許多情況，回頭讀讀幾本好書，並實踐，你就有許多 mentor 加持了。&lt;/p&gt;
&lt;p&gt;試想：有 Andrew Grove、Peter Drucker、Stephen Covey 當你的私人 mentor，是不是更靠譜？&lt;/p&gt;
&lt;p&gt;少了自覺，就會像我某篇舊文〈南柯一夢二十年〉講的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;遇到這樣的個案。&lt;/p&gt;
&lt;p&gt;第一堂課：「我有 20 年的工作經驗。」&lt;/p&gt;
&lt;p&gt;最後一堂：「現在我才發現，我只有 1 年的工作經驗，只不過重複了 20 年。」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;要避免 20 年後發出這樣的喟嘆，就請立刻開始自覺培養起「&lt;strong&gt;系統思考&lt;/strong&gt;」及「&lt;strong&gt;換位思考&lt;/strong&gt;」的專業態度吧。&lt;/p&gt;
&lt;h2 id=&#34;行動&#34;&gt;行動&lt;/h2&gt;
&lt;p&gt;如果工作場域沒有專業態度的學習對象（不要以為大公司就一定有這樣足以學習的對象），可以改從優質社群學，可以從有信譽的名師、課程學，或者，從書本學。&lt;/p&gt;
&lt;p&gt;其實我一直覺得，學生時代講究的預習、複習、作業、考試循環，進了職場，一樣要有這種自我進修意識。&lt;/p&gt;
&lt;p&gt;學生時代，有定期的作業及考試督促你複習及活用；進了職場，沒人出作業練習題給你，該如何&lt;strong&gt;預習&lt;/strong&gt;＋&lt;strong&gt;複習&lt;/strong&gt;＋&lt;strong&gt;活用&lt;/strong&gt;？這就是身為在職場上打滾的成年人，該發揮創意及意志力的地方。像「換位思考」，就是一種在&lt;strong&gt;想像層面&lt;/strong&gt;的預習＋複習。&lt;/p&gt;
&lt;p&gt;新思惟他們有一句我很喜歡的 slogan：「&lt;a href=&#34;http://speak2015.innovarad.tw/create_your_stage/&#34;&gt;沒有機會，製造機會；沒有舞台，搭起舞台！&lt;/a&gt;」這也算是一種主動搭起的&lt;strong&gt;活用&lt;/strong&gt;機會。&lt;/p&gt;
&lt;p&gt;自己搭起實體的或想像的舞台，行動，操練，更有機會變成習慣，變成自覺。&lt;/p&gt;
&lt;h2 id=&#34;問與答&#34;&gt;問與答&lt;/h2&gt;
&lt;p&gt;網路上充斥著「成長」及「求職」的問與答。主動分享成長經驗者有之，但更多的是發問。&lt;/p&gt;
&lt;p&gt;發問是好事，但也要留意在網路上發問的局限性。就像 Joe 的〈&lt;a href=&#34;https://www.darencademy.com/article/view/id/7214&#34;&gt;如何問個好問題&lt;/a&gt;〉一文所說，要提問時，請把握下面五大重點：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;背景故事提供清楚。&lt;/li&gt;
&lt;li&gt;自己要先想一下自己要甚麼，這是別人無法幫你判斷的。&lt;/li&gt;
&lt;li&gt;不要問主觀判斷很重的問題，除非你只是想聊天與抱怨。&lt;/li&gt;
&lt;li&gt;不要讓問題過度開放，列出「選項」才能聽到客觀分析。&lt;/li&gt;
&lt;li&gt;問題討論要自行收斂。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;否則，討論串很容易一下子樓就歪了。&lt;/p&gt;
&lt;p&gt;正因網路問答有如此高的侷限，有時候，回頭讀讀幾本好書，並實踐，會比支離破碎又缺乏背景脈絡的網路問答，更有效。&lt;/p&gt;
&lt;h2 id=&#34;讀書&#34;&gt;讀書&lt;/h2&gt;
&lt;p&gt;網路上充斥著「成長」及「求職」的問與答。真心建議：何不回過頭來，好好讀讀幾本書？築起合適的&lt;strong&gt;心智框架&lt;/strong&gt;，就能在許多狀況下不假外求。&lt;/p&gt;
&lt;p&gt;聚焦於個人專業態度的成長，是值得的自我投資。&lt;/p&gt;
&lt;p&gt;在我的書架上，總是有一塊精華地帶，專門擺放這類專業態度的書籍。遇到疑惑，就來此寶地諮詢或印證。有時候，甚至只要把這幾本書的目錄瀏覽過一遍，就有吃下一顆定心丸的效果。&lt;/p&gt;
&lt;p&gt;沒騙你，真的光是目錄，就足以讓自己「低回留之，不能去云」。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/07/prof-attitude-books.jpg&#34; alt=&#34;專業態度的書籍&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/07/prof-attitude-books.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;專業態度的書籍&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這類書籍，務實，不打高空，很容易套用在自己的工作場域，操練「&lt;strong&gt;系統思考&lt;/strong&gt;」及「&lt;strong&gt;換位思考&lt;/strong&gt;」的專業態度。&lt;/p&gt;
&lt;p&gt;你我的書單未必有交集，但重點是：取法乎上，請儘早讓自己有「&lt;strong&gt;系統思考&lt;/strong&gt;及&lt;strong&gt;換位思考&lt;/strong&gt;的&lt;strong&gt;自覺&lt;/strong&gt;及&lt;strong&gt;行動&lt;/strong&gt;」。&lt;/p&gt;
&lt;p&gt;這是預習，也是複習。&lt;/p&gt;
&lt;h2 id=&#34;給不愛看書的人&#34;&gt;給不愛看書的人⋯⋯&lt;/h2&gt;
&lt;p&gt;如果實在懶得啃書，比較想上課的話，以下幾門課，都是大補帖！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;關於換位思考：&lt;a href=&#34;https://shop.darencademy.com/product/view/id/28&#34;&gt;A101 職場大人學&lt;/a&gt; （推薦文：&lt;a href=&#34;//william-yeh.net/post/2015/09/upgrade-adult-thinking/&#34;&gt;升級成大人版的思維作業系統&lt;/a&gt; &amp;amp; &lt;a href=&#34;//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/&#34;&gt;轉大人，Part 2&lt;/a&gt;）。&lt;/li&gt;
&lt;li&gt;關於系統思考：&lt;a href=&#34;https://shop.darencademy.com/product/view/id/2&#34;&gt;102 流程設計與跨部門溝通&lt;/a&gt; （推薦文：&lt;a href=&#34;//william-yeh.net/post/2016/04/learn-process-mgmt-by-game/&#34;&gt;向遊戲學習&lt;/a&gt;）。&lt;/li&gt;
&lt;li&gt;關於職涯：&lt;a href=&#34;https://shop.darencademy.com/product/view/id/30&#34;&gt;A103 履歷優化實戰班&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;⋯⋯但是，良心建議，上完課，灌完頂之後，還是該回頭看看書的啦⋯⋯&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>改變的框架</title>
      <link>//william-yeh.net/post/2016/06/change-framework/</link>
      <pubDate>Tue, 28 Jun 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/06/change-framework/</guid>
      
        <description>&lt;p&gt;前幾天在 Twitter 寫道：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;下半年自我的課題，就是左腦高德拉特，右腦薩提爾，左右互搏。&lt;/p&gt;
&lt;p&gt;   &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/746245079375876101&#34;&gt;2016-06-24 Tweet #1&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;為什麼會把兩者相提並論呢？&lt;/p&gt;
&lt;p&gt;對我來說，&lt;a href=&#34;https://en.wikipedia.org/wiki/Eliyahu_M._Goldratt&#34;&gt;高德拉特&lt;/a&gt;代表一種極度&lt;strong&gt;陽剛&lt;/strong&gt;的思維角度，&lt;a href=&#34;https://en.wikipedia.org/wiki/Virginia_Satir&#34;&gt;薩提爾&lt;/a&gt;代表一種極度&lt;strong&gt;柔軟&lt;/strong&gt;的治療角度。&lt;/p&gt;
&lt;p&gt;這麼形容，並不代表他們是分處「剛」與「柔」兩個極端；相反的，越深入研究，越可體會出剛柔相濟的妙境。像高德拉特在《&lt;a href=&#34;http://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》書中，演示了許多極度柔軟的「TOC 式說服程序」；而《&lt;a href=&#34;http://www.books.com.tw/products/0010004784&#34;&gt;薩提爾的家族治療模式&lt;/a&gt;》中闡釋的「高自我價值」，健旺的生命態度，令人動容：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/self-esteem.jpg&#34; alt=&#34;自我價值&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/self-esteem.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;自我價值&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這些特質，正與「&lt;a href=&#34;//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/&#34;&gt;大人思維&lt;/a&gt;」不謀而合。&lt;/p&gt;
&lt;p&gt;所以，在某個層次上，「剛」與「柔」並不是兩個極端，而是可以協調產生綜效的。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;回到正題。&lt;/p&gt;
&lt;p&gt;為什麼我會想以「左腦高德拉特，右腦薩提爾」作為我的下半年課題呢？&lt;/p&gt;
&lt;p&gt;因為，我看中兩者的一項共通性：面對「改變」的議題。&lt;/p&gt;
&lt;h2 id=&#34;改變&#34;&gt;改變&lt;/h2&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2016/05/change-viewpoint-on-lord-of-rings/&#34;&gt;從「改變」角度看《魔戒》&lt;/a&gt;〉一文提到：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;畢竟 Lean Change Canvas 只是個框架，只是建議可以從九個面向去思考，但並未給出個別面向該如何發想及收斂；這有待自己再融入其他更針對性的思考工具。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不管是在個人層次，或在家庭層次、人際層次、團隊層次、組織層次，「改變」總是無法迴避的議題，或者說：難題。在上述的任何一個層次，想發揮更大的影響力，都必須學習「改變」的技術及藝術。&lt;/p&gt;
&lt;h2 id=&#34;限制理論的改變框架&#34;&gt;限制理論的改變框架&lt;/h2&gt;
&lt;p&gt;「改變」的技術及藝術，是需要學習的，更需要不斷透過精準的提問來對焦。&lt;/p&gt;
&lt;p&gt;這也正是高德拉特《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》書末揭櫫的三個大哉問：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What to change / 應該改變哪些事情&lt;/li&gt;
&lt;li&gt;What to change to / 要朝什麼方向改變&lt;/li&gt;
&lt;li&gt;How to cause the change / 要如何改變&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這是很困難的大哉問。就連高德拉特本人，也要過了十年，在《&lt;a href=&#34;http://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》書中才正式提出具體的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Thinking_processes_%28theory_of_constraints%29&#34;&gt;Thinking Processes&lt;/a&gt; 體系來處理這三大課題。&lt;/p&gt;
&lt;p&gt;後來，高德拉特之女 Efrat Goldratt-Ashlag &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，則以組織心理學家的角度，提出 TOC 觀點的「&lt;a href=&#34;https://scholar.google.com.tw/scholar?cluster=3039241670493587705&#34;&gt;抵制變革層次&lt;/a&gt;」。 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:25em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/toc-layers-of-resistance.jpg&#34; alt=&#34;TOC 抵制變革層次&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/toc-layers-of-resistance.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;TOC 抵制變革層次&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;Efrat Goldratt-Ashlag 更語重心長說道：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;為了避免浪費時間和考驗我們自己及合作夥伴的耐心，我們需要忍住隨口亂說的衝動——我們應該盡快識別出&lt;strong&gt;未能達成共識的最早的「層次」&lt;/strong&gt;，並向對方建議，應該在進入下一步之前先集中討論該問題。&lt;/p&gt;
&lt;p&gt;抵制層次就好比一個&lt;strong&gt;路線圖&lt;/strong&gt;，標示著我們到了何處，何時適合繼續下一步討論，何時應該停在原處深呼吸一下，才不會有無所適從的感覺。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你看，TOC 是不是也有極度柔軟細緻的一面呢？&lt;/p&gt;
&lt;h2 id=&#34;薩提爾理論的改變框架&#34;&gt;薩提爾理論的改變框架&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Virginia_Satir&#34;&gt;薩提爾&lt;/a&gt;在從事個人及家族治療實務時，也淬煉出六階段的改變歷程：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:20em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/satir-change-model.jpg&#34; alt=&#34;Satir 六階段的改變歷程&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/satir-change-model.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Satir 六階段的改變歷程&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;薩提爾模式強調的一個取向是&lt;strong&gt;增添改變的概念&lt;/strong&gt; (the &lt;strong&gt;add-on&lt;/strong&gt; concept change)。從功能不良轉化到高功能的過程，往往涉及添加一些什麼到我們已經是或知道的東西上面。&lt;/p&gt;
&lt;p&gt;要重建高的自我價值，我們需要把案主帶入改變和轉化的過程。過程是改變之道：它有很多層次，包括從簡單的順序，到小心地察看發生了什麼、如何發生的以及改變&lt;strong&gt;觀點&lt;/strong&gt;、&lt;strong&gt;期待&lt;/strong&gt;和&lt;strong&gt;感受&lt;/strong&gt;。薩提爾整個模式的精神就在於&lt;strong&gt;覺察和欣賞轉化的過程&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&amp;mdash; Quote: 《&lt;a href=&#34;http://www.books.com.tw/products/0010004784&#34;&gt;薩提爾的家族治療模式&lt;/a&gt;》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;非常細緻，也是高度個別化的手法。&lt;/p&gt;
&lt;p&gt;和薩提爾彼此惺惺相惜的&lt;a href=&#34;https://en.wikipedia.org/wiki/Gerald_Weinberg&#34;&gt;溫伯格&lt;/a&gt;大師，也在《&lt;a href=&#34;http://www.books.com.tw/products/0010545251&#34;&gt;擁抱變革&lt;/a&gt;》書中，根據薩提爾的改變歷程，進一步點出其中的抉擇點／施力點：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:25em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/weinberg-change-process.jpg&#34; alt=&#34;溫伯格 - 變革抉擇點&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/weinberg-change-process.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;溫伯格 - 變革抉擇點&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這些對於「改變」內在外在歷程的藍圖，可讓我們做好更多的心理建設，也做更周詳的企劃。&lt;/p&gt;
&lt;h2 id=&#34;科特的改變框架&#34;&gt;科特的改變框架&lt;/h2&gt;
&lt;p&gt;變革大師&lt;a href=&#34;https://www.kotterinternational.com/team/john-kotter/&#34;&gt;約翰・科特&lt;/a&gt;在《&lt;a href=&#34;http://www.books.com.tw/products/0010675408&#34;&gt;超速變革&lt;/a&gt;》中，調整他早年 &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; 的變革步驟，提出 turbo 版的&lt;a href=&#34;http://www.kotterinternational.com/resources/landing-page/8-steps-to-accelerate-change-in-2015/&#34;&gt;變革加速器&lt;/a&gt;：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:25em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/kotter-8-steps.jpg&#34; alt=&#34;科特 - 變革加速器&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/kotter-8-steps.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;科特 - 變革加速器&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;本書所探討的，就是組織如何以靈活及創意，快速因應策略挑戰，把握今日更容易稍縱即逝的機會。我們從中可以明白，超前、創新的組織是如何早一步擺脫激烈競爭、處理前所未有的混亂狀況、面對技術斷層（technological discontinuies）的威脅，不必犧牲短期獲利，也不會耗損自己的人力。&lt;/p&gt;
&lt;p&gt;我的結論很簡單。當今世界的變化之快，導致過去一個世紀以來建立的基本系統、架構與文化，都無法跟上眼前的需求。就算你再怎麼精明，現在如果採取漸進方式調整管理與策略，恐怕也會使不上力。在變化莫測與變數日增的年代，你需要一個全新策略，才能保持領先。解決方法未必要捨棄原先已知的事物，全部從頭來過，而是要用&lt;strong&gt;有機方式&lt;/strong&gt;再導入&lt;strong&gt;第二套系統&lt;/strong&gt;；多數成功企業家對這套系統也很熟悉。&lt;/p&gt;
&lt;p&gt;新系統新增企業必備的靈活與速度；而原本的舊系統會持續運作，保持可靠與效率。兩者結合成「&lt;strong&gt;雙營運系統&lt;/strong&gt;」(dual operating system)。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這種「雙營運系統」組織設計法，和《&lt;a href=&#34;http://www.amazon.com/dp/0988262592/ref=cm_sw_r_tw_dp_a4p3wb0PSYY97&#34;&gt;鳳凰專案&lt;/a&gt;》的解法如出一轍，也很像我在〈&lt;a href=&#34;//william-yeh.net/post/2016/06/phoenix-proj-titles/&#34;&gt;《鳳凰專案》私房標題&lt;/a&gt;〉提出的 injection。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;理論歸理論，實際歸實際。一堆改變框架，足以讓自己好好消化吸收運用了。&lt;/p&gt;
&lt;p&gt;大人之路，就是一段華麗的冒險呀！&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      系列文章
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;❶ 改變的框架&lt;/p&gt;
&lt;p&gt;❷ &lt;a href=&#34;//william-yeh.net/post/2018/12/process-and-metrics/&#34;&gt;改變／改革：流程與衡量指標&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;❸ &lt;a href=&#34;//william-yeh.net/post/2022/05/evaluation-process-for-changes/&#34;&gt;推動改變的評估流程&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;高德拉特之女 Efrat Goldratt-Ashlag，也是《&lt;a href=&#34;https://www.amazon.cn/%E6%8A%89%E6%8B%A9-%E8%89%BE%E5%88%A9%C2%B7%E9%AB%98%E5%BE%B7%E6%8B%89%E7%89%B9/dp/B006006M6U&#34;&gt;抉擇&lt;/a&gt;》一書的合著者。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Efrat Goldratt-Ashlag 的〈&lt;a href=&#34;https://scholar.google.com.tw/scholar?cluster=3039241670493587705&#34;&gt;抵制變革層次&lt;/a&gt;〉這篇論文，亦收錄於《&lt;a href=&#34;http://www.books.com.tw/products/CN11199988&#34;&gt;瓶頸理論手冊&lt;/a&gt;》。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;科特 (John Kotter) 在變革領域著作等身。他最為人所知的，是在 1996 年《&lt;a href=&#34;https://www.books.com.tw/products/0010191080&#34;&gt;領導人的變革法則&lt;/a&gt;》提出著名的「八階段變革流程」。後來的著作，有專門探討八階段當中的特定議題（像 2008 年《&lt;a href=&#34;https://bookzone.cwgv.com.tw/books/details/BCB403&#34;&gt;急迫感&lt;/a&gt;》），也有改寫成寓言故事（像 2006 年《&lt;a href=&#34;https://www.books.com.tw/products/0010645587&#34;&gt;冰山在融化&lt;/a&gt;》）。2014 年的《&lt;a href=&#34;http://www.books.com.tw/products/0010675408&#34;&gt;超速變革&lt;/a&gt;》，則是「八階段變革流程」的進化版，也有改寫成寓言故事《&lt;a href=&#34;https://www.books.com.tw/products/0010731153&#34;&gt;這不是我們做事的方法！&lt;/a&gt;》。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>《鳳凰專案》私房標題</title>
      <link>//william-yeh.net/post/2016/06/phoenix-proj-titles/</link>
      <pubDate>Tue, 21 Jun 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/06/phoenix-proj-titles/</guid>
      
        <description>&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/dp/0988262592/ref=cm_sw_r_tw_dp_a4p3wb0PSYY97&#34;&gt;&lt;em&gt;The Phoenix Project&lt;/em&gt;&lt;/a&gt;（中譯本《&lt;a href=&#34;https://www.books.com.tw/products/0010765203&#34;&gt;鳳凰專案&lt;/a&gt;》）作者如是說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dr. Eliyahu Goldratt wrote his seminal book, &lt;a href=&#34;https://www.amazon.com/dp/0884270610/ref=cm_sw_r_tw_dp_eQmAxb6J5AFAR&#34;&gt;&lt;em&gt;The Goal: A Process of Ongoing Improvement&lt;/em&gt;&lt;/a&gt;, in 1984. [&amp;hellip;] My coauthors and I studied this book for nearly a decade, getting ready to write &lt;em&gt;The Phoenix Project&lt;/em&gt;. In many ways, I view our book as an homage to &lt;em&gt;The Goal&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;我和共同作者研究高德拉特博士的《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》將近十年了，為撰寫《鳳凰專案》做準備。我認為，從很多方面來看，我們這本書都是在&lt;strong&gt;向《目標》致敬&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果一本書蘊釀了十年，那麼，這本書就值得我們細細咀嚼。&lt;/p&gt;
&lt;h2 id=&#34;值得多讀幾次的書&#34;&gt;值得多讀幾次的書&lt;/h2&gt;
&lt;p&gt;我很早就有《&lt;a href=&#34;https://www.books.com.tw/products/0010765203&#34;&gt;鳳凰專案&lt;/a&gt;》這本書的 Kindle 英文版及 Audible 語音版了。&lt;/p&gt;
&lt;p&gt;第一次讀完的時間已不可考。第二次是在撰寫〈&lt;a href=&#34;//william-yeh.net/post/2016/03/origin-of-devops-elements/&#34;&gt;DevOps 核心元素的考古溯源&lt;/a&gt;〉文章時，特地選讀相關的部分。第三次是在準備〈&lt;a href=&#34;//william-yeh.net/post/2016/05/devops-a-lean-perspective/&#34;&gt;有了 Agile，為什麼還要有 DevOps？&lt;/a&gt;〉演講時，對書中所倡議的「&lt;a href=&#34;http://itrevolution.com/the-three-ways-principles-underpinning-devops/&#34;&gt;&lt;strong&gt;三步工作法&lt;/strong&gt;&lt;/a&gt;」做更仔細的檢視。&lt;/p&gt;
&lt;p&gt;因此，屈指算來，我在〈&lt;a href=&#34;//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/&#34;&gt;轉大人，Part 2&lt;/a&gt;〉文中提到的頓悟經歷，已經是第四次讀這本書了：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;對於這陣子已經把《目標》、《絕不是靠運氣》、《關鍵鏈》重看一次的我，再回頭重看《鳳凰專案》，開始萌生另一種閱讀角度。&lt;/p&gt;
&lt;p&gt;人性的角度。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;為什麼要讀這麼多次呢？因為以前不懂得用更寬廣的視野來讀這本書。&lt;/p&gt;
&lt;p&gt;這本書每一章，其實都很值得我們設身處地思考：換成是我們，面對那樣的狀況，會採取什麼技術及非技術的手法，去分析局面，找對策。&lt;/p&gt;
&lt;p&gt;這也是身為職場大人的自我練習。&lt;/p&gt;
&lt;p&gt;這類小說，就像推理小說一樣，本來就不應該直接翻到兇手揭曉的那一頁呀。&lt;/p&gt;
&lt;h2 id=&#34;核心衝突&#34;&gt;核心衝突&lt;/h2&gt;
&lt;p&gt;這陣子雖然把《目標》、《絕不是靠運氣》、《關鍵鏈》重看一次，對高德拉特在《&lt;a href=&#34;https://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》的論點，心嚮往之，但又不禁懷疑。高德拉特是這麼說的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們不應假設經理人疏忽或無能，我們應該假設他們陷入一個衝突之中，以至於他們無法正確地經營公司。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;真的是這樣嗎？&lt;/p&gt;
&lt;p&gt;索性拿 DevOps 當實驗品吧！我很好奇：DevOps 的「核心衝突」究竟是什麼？&lt;/p&gt;
&lt;p&gt;我想效法《絕不是靠運氣》的主角 Rogo、《鳳凰專案》的主角 Bill，嘗試獨立思考。&lt;/p&gt;
&lt;p&gt;當然啦，高德拉特藉著主角 Rogo 之口，事先提出警告：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;全套的思維方法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你需要的是：對主題的直覺，及有毅力去執行這套思維方法中的細緻步驟。&lt;br&gt;
    &amp;mdash; 《&lt;a href=&#34;https://www.books.com.tw/products/0010588043&#34;&gt;絕不是靠運氣&lt;/a&gt;》p.125&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，我對過程中的燒腦程度，已經先有了心理準備。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我興致勃勃的照著高德拉特 &lt;a href=&#34;https://en.wikipedia.org/wiki/Thinking_processes_%28theory_of_constraints%29&#34;&gt;Thinking Processes&lt;/a&gt; 的步驟，針對 DevOps 常見的問題／痛點／抱怨，老老實實地從 UDE → CRT → clouds → injection → FRT 一路推導 DevOps 議題。&lt;/p&gt;
&lt;p&gt;赫然發現：超誇張的，光是用 CRT，就能初步推導出 DevOps 的 &lt;a href=&#34;https://blog.devopsguys.com/2014/04/17/the-secret-of-devops-success-isnt-in-the-it-literature-yet/&#34;&gt;CALMS&lt;/a&gt; 及所謂的「三步工作法」。而且，DevOps 的核心衝突，果然就出現在 CRT 的下方：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/devops-crt.jpg&#34; alt=&#34;CRT in DevOps&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/devops-crt.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;CRT in DevOps&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;整個推導過程的確燒腦，也橫跨了好幾天，但值得。&lt;/p&gt;
&lt;h2 id=&#34;鳳凰專案最大的貢獻&#34;&gt;《鳳凰專案》最大的貢獻&lt;/h2&gt;
&lt;p&gt;DevOps 的 CRT 及核心衝突一旦現形，再回頭看《鳳凰專案》，許多推理過程就清晰許多。&lt;/p&gt;
&lt;p&gt;你也可以當自己的鐘納。&lt;/p&gt;
&lt;p&gt;突然有個很離經叛道的想法：《鳳凰專案》這本書最大的貢獻，恐怕不是所謂的「三步工作法」，而是「四種類型工作」的界定。&lt;/p&gt;
&lt;p&gt;畢竟，「四種類型工作」是因，「三步工作法」只是 TOC 及 Lean 的應用之果。&lt;/p&gt;
&lt;p&gt;這方面的想法，先賣個關子，留待 &lt;a href=&#34;http://devopssummit.ithome.com.tw/&#34;&gt;DevOps Summit 2016&lt;/a&gt; 的演講〈&lt;a href=&#34;//william-yeh.net/post/2016/08/devops-a-toc-perspective/&#34;&gt;從限制理論看 DevOps&lt;/a&gt;〉再發表吧。&lt;/p&gt;
&lt;p&gt;經過這些探索歷程，對《鳳凰專案》這本書，心生更多敬意。&lt;/p&gt;
&lt;p&gt;作者說他們為了這本書「蘊釀了十年」，誠然不虛。&lt;/p&gt;
&lt;h2 id=&#34;私房標題&#34;&gt;私房標題&lt;/h2&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/&#34;&gt;轉大人，Part 2&lt;/a&gt;〉文中曾預告過：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;現在重讀《鳳凰專案》時，私底下也在替每一章取個私房標題。接下來，會再加把勁兒，自我要求：練習用 Bryan 課堂上教的分析手法，重新分析箇中情節。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;漸漸發現，我想做的，不僅是「導讀」，甚至是「註釋」或「延伸學習單」了。不過我設想的進行方式是，一次只導讀某幾章，不要偷看後面的章節。就像面對推理小說一樣，偷看後面的解密，就不好玩了。&lt;/p&gt;
&lt;p&gt;整個活動，需要分好幾次才能完成。也就是說，是個有連載性質的導讀活動。&lt;/p&gt;
&lt;p&gt;在哪裡舉辦呢？&lt;/p&gt;
&lt;p&gt;辦在公司裡面，優點是風險較低，缺點是參與者同質性過高，激盪火花的力道較弱，我能學到的新東西也較少。或許應該先在有興趣的社群先小規模玩過一次？&lt;/p&gt;
&lt;p&gt;事情總是要一步一步來。我先將私房標題的初稿列在下面：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;沒有蜜月期&lt;/li&gt;
&lt;li&gt;為什麼是你而不是我？&lt;/li&gt;
&lt;li&gt;走捷徑&lt;/li&gt;
&lt;li&gt;交相指責&lt;/li&gt;
&lt;li&gt;管理人員的角度&lt;/li&gt;
&lt;li&gt;檢討變更流程&lt;/li&gt;
&lt;li&gt;Erik 登場&lt;/li&gt;
&lt;li&gt;分類變更要求&lt;/li&gt;
&lt;li&gt;第三種工作類型&lt;/li&gt;
&lt;li&gt;Brent 的一天&lt;/li&gt;
&lt;li&gt;半成品堆積&lt;/li&gt;
&lt;li&gt;上線災難&lt;/li&gt;
&lt;li&gt;救火&lt;/li&gt;
&lt;li&gt;IT 外包危機&lt;/li&gt;
&lt;li&gt;第四種工作類型&lt;/li&gt;
&lt;li&gt;辭職&lt;/li&gt;
&lt;li&gt;我是十足的混蛋&lt;/li&gt;
&lt;li&gt;混蛋的告白&lt;/li&gt;
&lt;li&gt;凍結新工作&lt;/li&gt;
&lt;li&gt;監控資源&lt;/li&gt;
&lt;li&gt;怎麼逃過審計的？&lt;/li&gt;
&lt;li&gt;如何決定優先序？&lt;/li&gt;
&lt;li&gt;多重工作交接&lt;/li&gt;
&lt;li&gt;John 的用處？&lt;/li&gt;
&lt;li&gt;對系統的鑑賞&lt;/li&gt;
&lt;li&gt;魔杖&lt;/li&gt;
&lt;li&gt;IT 風險不是 IT 風險&lt;/li&gt;
&lt;li&gt;又是 Sarah！&lt;/li&gt;
&lt;li&gt;特別行動隊&lt;/li&gt;
&lt;li&gt;持續交付&lt;/li&gt;
&lt;li&gt;Value stream&lt;/li&gt;
&lt;li&gt;“獨角獸”&lt;/li&gt;
&lt;li&gt;自動化的小勝利&lt;/li&gt;
&lt;li&gt;收回外包&lt;/li&gt;
&lt;li&gt;快車道&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;仍然強烈建議：請將這本書當成推理小說，不要驟然翻到後面。&lt;/p&gt;
&lt;p&gt;畢竟：&lt;/p&gt;
&lt;p&gt;

&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/phoenix-10years.png&#34; alt=&#34;十年成一書&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/phoenix-10years.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;十年成一書&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

   &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/743252388828446720&#34;&gt;2016-06-16 Tweet #1&lt;/a&gt;&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>轉大人，Part 2</title>
      <link>//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/</link>
      <pubDate>Sat, 04 Jun 2016 09:54:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/</guid>
      
        <description>&lt;p&gt;在我所處的軟體研發圈，最近也流行起「&lt;a href=&#34;http://www.gigihuang.com/2016/05/22/agile_meetup_show_dont_tell/&#34;&gt;18+ Adult Manifesto&lt;/a&gt;」這種話題。&lt;/p&gt;
&lt;p&gt;這就不得不佩服 J&amp;amp;B 取的「大人學」品牌名字，是多麼具有遠見。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/child-vs-adult.jpg&#34; alt=&#34;小孩 vs 大人&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/child-vs-adult.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;小孩 vs 大人&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;自從九個月前參加【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/28&#34;&gt;A101 職場大人學：職場人際關係與優勢策略&lt;/a&gt;】之後，不僅在 Facebook 私密社團繼續交流，我們同梯更舉辦自發性聚會，定期交換彼此的職場及閱讀心得。算是重要的&lt;strong&gt;族人&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;這陣子，旁觀別人形形色色的遭遇，不禁深自慶幸：用 14 PDU 換來 Bryan 積蓄 15 年的內功，何等划算！雖不敢說從此就無風無浪，但至少開了眼、醒了腦，懂得用更系統化、更跳離本位的角度來審視事情／世情，從那張表格的「苦主」晉升到⋯⋯自認進入前三個等級了（雖然偶爾還是會退化到第四等級⋯⋯）。&lt;/p&gt;
&lt;p&gt;箇中關鍵，真的就像 Bryan 反覆叮嚀的那「xx力」三字訣。&lt;/p&gt;
&lt;h2 id=&#34;內化&#34;&gt;內化&lt;/h2&gt;
&lt;p&gt;對老師最大的回饋，就是確實將老師所傳授的東西，反覆演練、運用，從思考及實踐中，努力內化成本能反應。&lt;/p&gt;
&lt;p&gt;如何確認自己內化的程度呢？&lt;/p&gt;
&lt;p&gt;這門課有學長姐回訓機制。回鍋再當一次學生，再度面對寫實案例，看看自己是否比第一次上課時更有身為「大人」的自覺，更能在所謂「關鍵四秒」中，迅速勾勒「局」與「勢」的關係，不啻是一場刺激的實境挑戰。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/a101-handouts.jpg&#34; alt=&#34;回訓&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/a101-handouts.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;回訓&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;我還偷偷給自己設限。&lt;/p&gt;
&lt;p&gt;老子曰：「五色令人目盲，五音令人耳聾。」&lt;/p&gt;
&lt;p&gt;因此，最近在思考問題、演講授課時，越來越喜歡從原始定義或目標下手。我認為，原理通了，邏輯通了，再加一點點創意及想像力，很多東西都是順理成章就推導得出來。&lt;/p&gt;
&lt;p&gt;於是，我想給自己一個挑戰：在回訓課堂上，要先自我歸零，就當自己是第一次來上課的學生；要自我克制，不要直接偷拿 Bryan 以前開釋過的大絕招來應付考古題。&lt;/p&gt;
&lt;p&gt;重點是思維角度，不是招數。&lt;/p&gt;
&lt;p&gt;結果呢？&lt;/p&gt;
&lt;p&gt;回訓，仍然感受到強烈的衝擊，仍然是點頭如搗蒜（所以，Bryan 的 15 年功力，真是超強！再聽一次，仍然收穫滿滿）。&lt;/p&gt;
&lt;p&gt;也很欣慰，原來自己已經不知不覺內化了某些部分。我沒有辜負去年在〈&lt;a href=&#34;//william-yeh.net/post/2015/09/upgrade-adult-thinking/&#34;&gt;升級成大人版的思維作業系統&lt;/a&gt;〉做的自我期許。&lt;/p&gt;
&lt;h2 id=&#34;訴求-vs-需求-vs-目標&#34;&gt;訴求 vs 需求 vs 目標&lt;/h2&gt;
&lt;p&gt;回訓，不是乖乖聽課就好，還要協助&lt;del&gt;小鮮肉&lt;/del&gt;學弟妹進行小組討論。面對組員，就像面對去年的自己，有趣之餘，也附帶了些引導（但不過度介入）的責任。&lt;/p&gt;
&lt;p&gt;為了因應可能被組員提出的問題，也為了自我成長，我也挑選想再深度探索的主題：&lt;a href=&#34;https://en.wikipedia.org/wiki/Evaporating_Cloud&#34;&gt;衝突圖&lt;/a&gt;，在課前先自我延伸學習。&lt;/p&gt;
&lt;p&gt;不過，在&lt;a href=&#34;https://en.wikipedia.org/wiki/Eliyahu_M._Goldratt&#34;&gt;高德拉特&lt;/a&gt;的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;TOC (Theory of Constraints)&lt;/a&gt; 發展史中，&lt;a href=&#34;https://en.wikipedia.org/wiki/Evaporating_Cloud&#34;&gt;衝突圖&lt;/a&gt;其實是隸屬於更大的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Thinking_processes_%5C%28theory_of_constraints%5C%29&#34;&gt;Thinking Process&lt;/a&gt; 當中的一環。為了更充分掌握這項思考方式，便將書架上擺了超過十年的高德拉特系列書籍：《目標》、《絕不是靠運氣》、《關鍵鏈》拿出來重讀一次，順便也讀一讀岸良裕司的兩本詮釋書籍。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/cloud-books.jpg&#34; alt=&#34;岸良裕司的書&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/cloud-books.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;岸良裕司的書&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;學了 TOC 的 Thinking Process 之後，不知不覺很喜歡思辨幾個層次的區別：「想要 vs 需要」、「訴求 vs 需求 vs 目標」。這也逐漸內化成我的思考工具。&lt;/p&gt;
&lt;p&gt;在此也要非常感謝 Bryan 在這門課指導的 TOC 衝突圖，算是我聽過最簡潔、最生動的詮釋。這次回頭再看那堆書，就懊惱：怎麼自己當年讀不出味道呢？&lt;/p&gt;
&lt;p&gt;好的引導，真的很重要。聽君一席話，勝讀十年書！&lt;/p&gt;
&lt;h2 id=&#34;集點卡&#34;&gt;集點卡&lt;/h2&gt;
&lt;p&gt;這次回訓，某些地方給了我另一個層次的衝擊。「集點卡」是其中之一。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/loyalty-card.jpg&#34; alt=&#34;Bryan 集點卡&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/loyalty-card.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Bryan 集點卡&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;看了這張集點卡，我相信 Bryan 所說的「我從 15 年前就在準備這門課了！」真實不虛。&lt;/p&gt;
&lt;p&gt;每當面臨職涯抉擇時，多少人腦海中，有這麼一張清晰的集點卡呢？&lt;/p&gt;
&lt;p&gt;這是很值得嚴肅面對的問題。&lt;/p&gt;
&lt;p&gt;去年上了這門課之後，我的確開始逐漸自我裝備，但不夠清晰。這次回訓，再度看到這張圖，也再度點燃集點的熱誠。&lt;/p&gt;
&lt;h2 id=&#34;做自己&#34;&gt;做自己&lt;/h2&gt;
&lt;p&gt;即使是同一位老師講同一門課，但只要學生組成不同，就會有不同的氣場及火花。&lt;/p&gt;
&lt;p&gt;這次回訓，有幾位同學針對「做自己」這一點，展開一連串的熱烈提問。&lt;/p&gt;
&lt;p&gt;現場激起的火花，真的很過癮！連 Bryan 都有感而發，隔天就寫出了〈&lt;a href=&#34;https://www.darencademy.com/article/view/id/16421&#34;&gt;所謂做自己，就是用自己的意志扮演自己想要的角色&lt;/a&gt;〉這篇文章。&lt;/p&gt;
&lt;p&gt;某些觀念，如果是不約而同被我私淑對象提到，那就一定值得我認真對待。&lt;/p&gt;
&lt;p&gt;其一，Bryan 課堂闡述的職場人際基礎：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/job-view.jpg&#34; alt=&#34;關於職場這個局&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/job-view.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;關於職場這個局&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;其二，阿德勒的「課題分離」原則。&lt;/p&gt;
&lt;p&gt;或許是這陣子被不同種族的&lt;strong&gt;族人&lt;/strong&gt;間接推坑（像&lt;a href=&#34;https://i-chentsai.innovarad.tw/2015/05/alfred_adler.html&#34;&gt;這位&lt;/a&gt;及&lt;a href=&#34;http://teddy-chen-tw.blogspot.com/2015/07/blog-post_30.html&#34;&gt;這位&lt;/a&gt;），讀了《&lt;a href=&#34;http://i-chentsai.innovarad.tw/2015/05/alfred_adler.html&#34;&gt;被討厭的勇氣&lt;/a&gt;》，知道適度的「課題分離」是件好事，所以，腦袋中已經埋下這些種子：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我們必須站在「這是誰的課題？」的觀點，將自己和他人的課題切割開來。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;所有人際關係中的紛爭，差不多都是因為一腳踩進人家的課題裡，或是自己的課題遭到干涉所引起的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;要區分是誰的課題，方法很簡單，請想一想「因為這個決定而帶來的結果，最後會由誰來承受」？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;別人不是為了滿足你的期望而活。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;關於自己的人生，你所能做的只有「選擇一條自認為最好的路」。別人要對你的選擇做出什麼樣的評論，這是別人的課題，你是無法干預的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你無法不在意他人的評價、無法不害怕被人討厭，也不想付出可能得不到認同的代價，就無法貫徹自己的生活方式。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其三，高德拉特的「清晰思考」觀點：&lt;/p&gt;
&lt;p&gt;

&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/toc-thinking-1.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/toc-thinking-1.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;



&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/toc-thinking-2.jpg&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/toc-thinking-2.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;從【A101職場大人學】課程，到《被討厭的勇氣》書籍，再到高德拉特 TOC 系列，覺得腦袋整個被翻轉。&lt;/p&gt;
&lt;p&gt;誠如上面《抉擇》導讀文章所說：這是一段「不斷探索、實踐和學習」的道路。&lt;/p&gt;
&lt;p&gt;大人之路，就是一段華麗的冒險呀！&lt;/p&gt;
&lt;h2 id=&#34;觸類旁通的新眼光&#34;&gt;觸類旁通的新眼光&lt;/h2&gt;
&lt;p&gt;最近，為了準備幾場專題演講，我開始重讀《&lt;a href=&#34;http://www.amazon.com/dp/0988262592/ref=cm_sw_r_tw_dp_a4p3wb0PSYY97&#34;&gt;鳳凰專案&lt;/a&gt;》這本 IT 界 DevOps 的經典小說（關於這本小說，請見我在〈&lt;a href=&#34;//william-yeh.net/post/2016/03/origin-of-devops-elements/&#34;&gt;DevOps 核心元素的考古溯源&lt;/a&gt;〉及〈&lt;a href=&#34;//william-yeh.net/post/2016/05/devops-a-lean-perspective/&#34;&gt;有了 Agile，為什麼還要有 DevOps？&lt;/a&gt;〉的介紹）。&lt;/p&gt;
&lt;p&gt;許多 IT 人，都是用工具主義的角度，求仙丹，求銀彈，想趕快翻到特效藥的章節；誰叫這本書故事內容，就是在宣傳「三個月就能將瀕危專案起死回生」的「一個 IT 運維的傳奇故事」呢？（其實《目標》及《絕不是靠運氣》兩本書的主角羅哥，不也是在短短三個月內就創下奇蹟嗎？）&lt;/p&gt;
&lt;p&gt;可是，這類小說，就像推理小說一樣，本來就不應該直接翻到兇手揭曉的那一頁呀。&lt;/p&gt;
&lt;p&gt;對於這陣子已經把《目標》、《絕不是靠運氣》、《關鍵鏈》重看一次的我，再回頭重看《鳳凰專案》，開始萌生另一種閱讀角度。&lt;/p&gt;
&lt;p&gt;人性的角度。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/surf.jpg&#34; alt=&#34;衝浪者的哲學&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/surf.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;衝浪者的哲學&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這次回訓，一席「衝浪者的哲學」，感覺好像把《鳳凰專案》裡面的許多情境，找到對應的鑰匙。許多推理過程，也隨之清晰起來。&lt;/p&gt;
&lt;p&gt;有夠神奇的。&lt;/p&gt;
&lt;p&gt;可見，有些東西，真的是跨產業的。尤其是人性。&lt;/p&gt;
&lt;p&gt;現在重讀《鳳凰專案》時，私底下也在替每一章取個&lt;a href=&#34;//william-yeh.net/post/2016/06/phoenix-proj-titles/&#34;&gt;私房標題&lt;/a&gt;。接下來，會再加把勁兒，自我要求：練習用 Bryan 課堂上教的分析手法，重新分析箇中情節。&lt;/p&gt;
&lt;p&gt;有一本書叫做《&lt;a href=&#34;https://shop.campus.org.tw/ProductDetails.aspx?ProductID=000401708&#34;&gt;聖經好好吃&lt;/a&gt;》，我這種做法，也算是另一種「大人學角度」的「鳳凰專案好好吃」嗎？&lt;/p&gt;
&lt;h2 id=&#34;以終為始&#34;&gt;以終為始&lt;/h2&gt;
&lt;p&gt;上完兩次課，不知不覺會變得雞婆起來，遇到親朋好友的狀況，就會推坑這門課。&lt;/p&gt;
&lt;p&gt;不過，誠如 Joe 在〈&lt;a href=&#34;https://www.darencademy.com/article/view/id/15791&#34;&gt;為何我們很難改變周圍那些愛抱怨的朋友？&lt;/a&gt;〉及〈&lt;a href=&#34;https://www.darencademy.com/article/view/id/16420&#34;&gt;怎麼才能有效安撫找你抱怨的朋友？&lt;/a&gt;〉兩篇文章的善意提醒：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;時常抱怨的人，其實抱怨的目的往往已經不是為了找到解答，而是某種隱含的自豪與炫耀。 而悲慘的境界，則是他自豪的理由！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;當你有朋友不斷來找你抱怨時，如果你很確定他壓根沒打算要跨出安適圈、沒打算做些自我根本上的改變，那你能帶給他最好的幫助，就是給他一個更慘的故事。 讓他們有種「原來我的人生還好」的感覺，進而會因此感覺舒坦。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;許多困境，不是訴諸簡單的自我轉念，就能解決的。這需要看懂局，也認清自己要的到底是什麼；這些都是需要高度理性的運作。&lt;/p&gt;
&lt;p&gt;自我轉念，很多人都這麼說、也這麼建議他人；可是，往往只是淪為自我催眠。最後，還是走回新亭對泣的迴圈。&lt;/p&gt;
&lt;p&gt;改變，是有方法的；但首先要先自問：自己真的想改變嗎？&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/06/career-goals.jpg&#34; alt=&#34;三大目的&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/06/career-goals.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;三大目的&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;相隔九個月，課堂一開始的「三大目的」便利貼，居然沒有變化。&lt;/p&gt;
&lt;p&gt;我相信，這應該就是我想要的。&lt;/p&gt;
&lt;p&gt;以終為始，莫忘初衷。&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>從「改變」角度看《魔戒》</title>
      <link>//william-yeh.net/post/2016/05/change-viewpoint-on-lord-of-rings/</link>
      <pubDate>Wed, 25 May 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/05/change-viewpoint-on-lord-of-rings/</guid>
      
        <description>&lt;p&gt;今年一月，參加 &lt;a href=&#34;http://kojenchieh.pixnet.net/blog&#34;&gt;David Ko&lt;/a&gt; 舉辦的一場敏捷轉型活動，從中學到了一個有趣的分析工具：Lean Change Canvas。&lt;/p&gt;
&lt;p&gt;知道了一個好東西，自然要追本溯源，加深加廣。便研讀相關資料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://kojenchieh.pixnet.net/blog/post/441018775-%E7%B2%BE%E5%AF%A6%E6%94%B9%E8%AE%8A%E7%95%AB%E5%B8%83&#34;&gt;精實改變畫布&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://kojenchieh.pixnet.net/blog/post/442550432-firstthing_of_agile_promotion&#34;&gt;推廣敏捷的第一要務是什麼&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://leankit.com/blog/2015/02/lean-change-method/&#34;&gt;Lean Change Method: Enabling Lean and Agile Transformations at Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.safaribooksonline.com/library/view/lean-change-livelessons/9780133443912/&#34;&gt;Lean Change LiveLessons (Video Training): Achieving Agile Transformation with Kanban, Kotter, and Lean Startup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外，也要找機會多演練、多思考，才會內化。於是，隔天我就在公司帶領小組討論任務時，現學現賣。數日後，也順便用在第二梯次 &lt;a href=&#34;http://get.soft-arch.net/ansible&#34;&gt;Ansible Workshop&lt;/a&gt; 課堂上：&lt;/p&gt;
&lt;p&gt;
&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/05/lord-of-rings-example.jpg&#34; alt=&#34;Ansible Workshop 第二梯次&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/05/lord-of-rings-example.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Ansible Workshop 第二梯次&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

    &amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/brecht/status/686004657085231104&#34;&gt;Brecht&amp;rsquo;s Tweet&lt;/a&gt;&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;之後，再歷經第三、四、五梯次的 Ansible Workshop 的演練引導，不僅更了解 Lean Change Canvas 適用時機，也發展出有助於聚焦的配套措施：說故事、&lt;a href=&#34;http://www.books.com.tw/products/0010463047&#34;&gt;ORID&lt;/a&gt; 及 &lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;TOC&lt;/a&gt;。畢竟 Lean Change Canvas 只是個框架，只建議出九個思考面向，但並未具體說明個別面向該如何發想及收斂——這都有待自己再融入其他更針對性的思考工具。&lt;/p&gt;
&lt;p&gt;我的方法是：先用某個耳熟能詳的故事，引介 Lean Change Canvas 九個格子的意涵。此處，我選擇大部分的人都看過電影版或小說版的《魔戒》為引子（應該是吧！），以求連結經驗。接著再拿真正要大家研討的案例，請大家各自照著 Lean Change Canvas 的九個面向去分析。最後的討論高潮，則以 ORID 的焦點討論法，及 TOC 的現況與衝突思辨手法，提煉出改變的共識。&lt;/p&gt;
&lt;p&gt;在可預見的未來，我大概不太會在課堂上，慢慢引導 Lean Change Canvas 的分析流程。因此，我把剛結束的第五梯次 Ansible Workshop 課堂錄影，擷取其中第一段【&lt;strong&gt;從「改變」角度看《魔戒》&lt;/strong&gt;】的引介內容，公開出來，給有興趣進行團隊引導的人參考。&lt;/p&gt;
&lt;p&gt;最後，要感謝 &lt;a href=&#34;http://kojenchieh.pixnet.net/blog&#34;&gt;David Ko&lt;/a&gt; 介紹 Lean Change Canvas 這麼有趣的分析框架，也要感謝過去四個梯次的 Ansible Workshop 學員，讓我有機會實際演練，反芻箇中細節。&lt;/p&gt;
&lt;p&gt;影片全長約 11 分鐘，請慢用。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/Ug5wKl8J2Ng?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>有了 Agile，為什麼還要有 DevOps？</title>
      <link>//william-yeh.net/post/2016/05/devops-a-lean-perspective/</link>
      <pubDate>Tue, 03 May 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/05/devops-a-lean-perspective/</guid>
      
        <description>&lt;p&gt;今晚，受 Agile Community Taiwan 之邀，在 &lt;a href=&#34;https://www.accupass.com/event/1604251622311845219210&#34;&gt;Agile Meetup Taipei&lt;/a&gt; 給了一場演講：【&lt;a href=&#34;http://www.slideshare.net/williamyeh/agile-devops&#34;&gt;有了 Agile，為什麼還要有 DevOps？&lt;/a&gt;】&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/05/devops-speech-cover.jpg&#34; alt=&#34;演講現場自拍&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/05/devops-speech-cover.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;演講現場自拍&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;之所以會給這場演講，是因為之前在討論區、演講、講課時，總是會收到這類的 Q&amp;amp;A：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DevOps 是不是在花大錢搞新技術？商業噱頭？&lt;/li&gt;
&lt;li&gt;DevOps 只是大雜燴？&lt;/li&gt;
&lt;li&gt;DevOps 只與 Agile 有關？&lt;/li&gt;
&lt;li&gt;DevOps 就是 Dev 把魔爪伸到 Ops 嗎？&lt;/li&gt;
&lt;li&gt;DevOps 需要改變文化嗎？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;林林總總，不是三言兩語就能回答得完整。雖然之前也寫了幾篇文章試著回答部分問題，但總是不夠全面。&lt;/p&gt;
&lt;p&gt;為了一勞永逸，我試著用以下的角度，完整闡釋個人觀點：&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      演講簡介
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;敏捷運動與 DevOps，有某些共同的淵源，但也有不同的偏重取向。&lt;/p&gt;
&lt;p&gt;Agile 陣營的人，常會有個疑問：「聽起來，DevOps 好像只是把 Agile 觸角從 Dev 伸到 Ops 端，只是舊瓶裝新酒？」&lt;/p&gt;
&lt;p&gt;Waterfall 陣營的人，也常會有個疑問：「聽起來，DevOps 好像只是 Agile 那一票人搞出來的；我們 Waterfall 陣營是不玩這一套的。」&lt;/p&gt;
&lt;p&gt;真的是這樣嗎？&lt;/p&gt;
&lt;p&gt;本次活動會以一些小活動、一些小短片，帶領大家從 Lean Thinking 角度，重新審視軟體研發的 value stream。回歸 DevOps 的原點，你將能夠自己給出上述問題的答案。&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;個人觀點，或許主觀，但至少給了一個出發點。尤其台灣似乎還沒有以較核心的 Lean Thinking 角度，好好探討 DevOps，乃至 Agile 的論述。看得到的，多半集中在「&lt;a href=&#34;http://wiki.mbalib.com/zh-tw/%E4%B8%83%E5%A4%A7%E6%B5%AA%E8%B4%B9&#34;&gt;消除七大浪費&lt;/a&gt;」這種角度；但 Lean Thinking 的核心原則，並不只有這個而已。&lt;/p&gt;
&lt;p&gt;我認為，軟體從業人員，有必要好好認識 Lean Thinking 的五大原則：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Value&lt;/li&gt;
&lt;li&gt;Value stream&lt;/li&gt;
&lt;li&gt;Flow&lt;/li&gt;
&lt;li&gt;Pull&lt;/li&gt;
&lt;li&gt;Perfection&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;認識這五大原則，會打通 agile、Scrum、Kanban、DevOps 等新潮名詞的任督二脈。&lt;/p&gt;
&lt;p&gt;不過，Lean Thinking 有些地方，硬是直接說理，言者諄諄，聽者藐藐；最好的方法，還是從遊戲中親身體會。所以在演講現場，我也帶大家玩一場 The Dot Game 的「William 式變形版」。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;演講的投影片在此，希望對大家有所幫助：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&#34;//www.slideshare.net/williamyeh/agile-devops&#34;&gt;有了 Agile，為什麼還要有 DevOps？&lt;/a&gt;&lt;/strong&gt;
&lt;iframe
  style=&#34;width: 100%; height: 500px;&#34; frameborder=&#34;0&#34; marginwidth=&#34;0&#34; marginheight=&#34;0&#34; scrolling=&#34;no&#34;
  src=&#34;https://www.slideshare.net/slideshow/embed_code/61628527&#34; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;現場實況錄影在此，全長整整 2 小時，請享用：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/2j3eP55Oygw?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>向遊戲學習</title>
      <link>//william-yeh.net/post/2016/04/learn-process-mgmt-by-game/</link>
      <pubDate>Sat, 23 Apr 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/04/learn-process-mgmt-by-game/</guid>
      
        <description>&lt;p&gt;前一篇文章〈&lt;a href=&#34;//william-yeh.net/post/2016/04/learn-from-plant-mgmt/&#34;&gt;向工廠管理致敬&lt;/a&gt;〉提到，最近為了準備一場 Agile/DevOps 演講，我特地研讀了數本原典，希望能對某些核心的思考元素來一場溯源之旅。&lt;/p&gt;
&lt;p&gt;啃原典，其實還有另一個原因：為了好好替今天要去大玩特玩的&lt;strong&gt;小火車遊戲&lt;/strong&gt;⋯⋯喔，不，是為了替今天要專程去上的一門【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/2&#34;&gt;102 流程設計與跨部門溝通&lt;/a&gt;】課程預作準備。&lt;/p&gt;
&lt;p&gt;盯上這門課，其實已經很久了。只是這門課⋯⋯摘錄一段課程文案：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;只有二十二個席次，因為道具很多，所以約每半年才開設一次公開班，錯過就要等很久了喔！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這文案一點也不誇張。所以，我緊盯著每一梯次開放報名的風吹草動，委實不易呀！&lt;/p&gt;
&lt;p&gt;上含金量這麼高的實作課程，不事先自我裝備一下，就太浪費了。但上課時，我還是盡量提醒自己要心態歸零，避免那些偷練的知識變成先入為主的反射思考，這樣才有更多 unknown unknown 可學。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/04/102-opening.jpg&#34; alt=&#34;102 - 開場白&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/04/102-opening.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;102 - 開場白&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;這門課，從實際的小火車遊戲中，讓我結結實實體會到以前從書中讀過的一堆觀念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》書中講的 &lt;a href=&#34;https://www.projectup.net/article/view/id/3124&#34;&gt;TOC 聚焦五步驟&lt;/a&gt;，是真的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;《&lt;a href=&#34;http://www.books.com.tw/products/0010662172&#34;&gt;精實革命&lt;/a&gt;》書中講的&lt;a href=&#34;http://www.cardiff.ac.uk/lean/principles/&#34;&gt;精實思考五原則&lt;/a&gt;，是真的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Toyota_Production_System&#34;&gt;豐田生產系統&lt;/a&gt;所講究的現地現物、自働化、看板、防呆、5S、反省⋯⋯，是真的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;甚至連以前上 PMBOK 課程看到的一堆令人生厭的 &lt;a href=&#34;http://www.pmexamsmartnotes.com/how-to-remember-ittos-of-all-47-pmbok-processes/&#34;&gt;ITTO&lt;/a&gt;，也看到在組織執掌分工下的真義。&lt;/p&gt;
&lt;p&gt;所以，不要小看小孩子玩的小火車；道在屎溺，不可不察也！&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/04/102-scene-1.jpg&#34; alt=&#34;102 - 第一回合&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/04/102-scene-1.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;102 - 第一回合&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;整天課程分兩回合進行。第一回合是由學生自己構思方法、執行，並自行檢討；這一回合，講師都先不予提示。&lt;/p&gt;
&lt;p&gt;好精彩的第一回合！和一群各行各業臥虎藏龍的 22 名高手合作，過癮！&lt;/p&gt;
&lt;p&gt;儘管差一點點就達標，但我已經從過程中體會到 lean &amp;amp; TOC 的某些原則。&lt;/p&gt;
&lt;p&gt;這的確是一場和高手合作，很能激盪出火花的體驗活動。也很高興自己貢獻的幾個流程及防呆手法，有派上用場。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/04/102-scene-2.jpg&#34; alt=&#34;102 - 第二回合&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/04/102-scene-2.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;102 - 第二回合&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;等大家都提出檢討報告之後，講師 Joe &amp;amp; Bryan 才根據現場觀察，給予精準的提示，並端出這門課的壓箱寶：品質流程六大手法。&lt;/p&gt;
&lt;p&gt;醍醐灌頂後，大家再度自發地提出改善計畫，重新規劃流程，再進行第二回合：目標不只是達標，更要追求卓越，挑戰加分項目！&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/04/102-certificate.jpg&#34; alt=&#34;102 - 證書&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/04/102-certificate.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;102 - 證書&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;玩了一天小火車，收穫滿滿。&lt;/p&gt;
&lt;p&gt;正題有收穫，也趁機向 Joe &amp;amp; Bryan 請教一些近日思考的疑點。我將把體驗到的思維角度運用在職場上（DevOps 其實非常需要這種綜觀全局的思考方式及流程改善）。&lt;/p&gt;
&lt;p&gt;除了正題收穫之外，也更確定了另一件事：如果想傳達的要點很多，那麼，設計活動時，要選擇在依存關係及統計波動上有某種複雜度的模擬案例（這也是《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》書中所提出的切入點）。&lt;/p&gt;
&lt;p&gt;敏捷陣營素以愛玩遊戲著稱。從今天的小火車遊戲中，我也偷學了一些遊戲設計的訣竅，希望以後能運用在團隊身上。&lt;/p&gt;
&lt;p&gt;最後，給一個 call to action：如果你也想親身體驗這麼好玩的遊戲，&lt;a href=&#34;http://www.accupass.com/event/register/1602250738221767316794&#34;&gt;最新梯次 9/03 已經開放報名&lt;/a&gt;。&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/DmG8VLQTobQ?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

</description>
      
    </item>
    
    <item>
      <title>向工廠管理致敬</title>
      <link>//william-yeh.net/post/2016/04/learn-from-plant-mgmt/</link>
      <pubDate>Fri, 22 Apr 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/04/learn-from-plant-mgmt/</guid>
      
        <description>&lt;p&gt;身為徹頭徹尾的軟體人，在軟體產業待久了，總會對「硬」一點的產業，尤其是製造業，有莫名的成見，以為他們是僵固的、反人性的。從 1972 年「&lt;a href=&#34;https://en.wikipedia.org/wiki/Software_crisis&#34;&gt;軟體危機&lt;/a&gt;」引發的論述當中，更加深軟體人的印象：製造業的經驗，是無法直接套用到軟體界的；我們是截然不同的國度。&lt;/p&gt;
&lt;p&gt;不過，近十年來許多軟體界的流程改革，尤其是同屬 Agile 陣營的 Scrum 及 Kanban，居然有許多元素是從製造業&lt;del&gt;偷竊&lt;/del&gt;學習而來。譬如說，由 Toyota 引領風潮的 &lt;a href=&#34;https://en.wikipedia.org/wiki/Lean_manufacturing&#34;&gt;Lean Production&lt;/a&gt; 及 &lt;a href=&#34;https://en.wikipedia.org/wiki/Just-in-time_manufacturing&#34;&gt;JIT&lt;/a&gt;、從 &lt;a href=&#34;https://en.wikipedia.org/wiki/Theory_of_constraints&#34;&gt;TOC（限制理論）&lt;/a&gt; 學來的流程分析及改善手法，都是相關文獻最常引述的。&lt;/p&gt;
&lt;p&gt;最近為了準備一場 Agile/DevOps 演講，特地研讀數本原典，對核心元素來一場溯源之旅：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/04/book-the-goals.jpg&#34; alt=&#34;目標&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/04/book-the-goals.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;目標&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;



&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/04/book-lean-revolution.jpg&#34; alt=&#34;精實方面的書籍&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/04/book-lean-revolution.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;精實方面的書籍&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;溯源之旅，很充實，也很有趣。&lt;/p&gt;
&lt;p&gt;一個有趣的觀察是，儘管 TOC 及 Lean/JIT 兩者有許多交集，合併服用的人也很多，但雙方的&lt;del&gt;本位主義者&lt;/del&gt;熱情擁護者卻常常各持己見。譬如說，《&lt;a href=&#34;https://www.books.com.tw/products/0010898249&#34;&gt;目標&lt;/a&gt;》審訂者在導讀中批評 JIT 的效用：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;八十年代，日本的「及時生產觀念」(JIT, Just In Time) 令日本製造業面貌一新，帶給美國莫大的威脅，一時間，美國企業在濃烈的危機感下，紛紛學習，並如法炮製，但效果始終有限。&lt;/p&gt;
&lt;p&gt;作者高德拉特博士強烈地認為，單靠抄襲沒有用，一定要闖出一條優於 JIT 的路才行，況且，絕大部分企業根本沒有條件和資源作 JIT 所需的巨額投資。本書所描述的「鼓—緩衝—繩子」(drum—buffer—rope)、「緩衝管理」(buffer management) 及 TOC 的各種觀念，就被業界評為比 JIT 更實用和快速見效的方法，而且投資少。美國福特汽車的電子部在花鉅資實行了兩年 JIT 後，發覺產品的生產期只縮短了少許，落後日本仍然甚遠，於是決定改用 TOC，在一年內就遠遠拋離對手。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而精實理論重鎮 &lt;a href=&#34;http://www.lean.org/&#34;&gt;LEI&lt;/a&gt; 出版的《&lt;a href=&#34;http://www.books.com.tw/products/0010339196&#34;&gt;學習觀察&lt;/a&gt;》，則批評 TOC 只有孤立效果，不是全面的改善：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;當我們在 1996 年秋初次發行《&lt;a href=&#34;http://www.books.com.tw/products/0010662172&#34;&gt;精實革命&lt;/a&gt;》時，我們敦促讀者要以大野耐一及豐田系統的其他開拓者的精神去「實踐它」。 [&amp;hellip;] 遺憾的是，我們發現採納我們循序漸進建議的人不多，往往在一頭鑽進消除浪費的工作之前，沒有認真地完成這關鍵的一步。&lt;/p&gt;
&lt;p&gt;這種急進性的改善和令人失望的結果，使得精實又像另一個無疾而終的運動，過了一段日子就被束之高閣，取而代之是像「消除瓶頸」（根據「制約理論」）或者六標準差方案，或者其他種種改善專案。但是這些項目都帶來了同樣的結果，在某些孤立的部分戰勝了浪費，其中的一部分甚至很有成效，但他們都不能成功地全面改善。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果有機會安排他們齊聚一堂&lt;del&gt;鬥嘴&lt;/del&gt;交流，一定很有趣。&lt;/p&gt;
&lt;p&gt;補充說明一下：高德拉特本人，對大野耐一可是推崇備至喔！&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;看了原典，想再看看有現場實務經驗的教練，是如何統合運用這些原理，尤其是不預設立場、善於提問引導的教練。&lt;/p&gt;
&lt;p&gt;《林俊哲的廠長教室》系列，就是如此趣味橫生的大補帖。尤其是〈工廠補習班〉系列文章：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.sina.com.cn/s/blog_a4c01d4a0102vryc.html&#34;&gt;工廠的口號洞悉管理的缺失&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://blog.sina.com.cn/s/blog_a4c01d4a0102vryf.html&#34;&gt;一個作業站反映工廠穩不穩定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://willy0936.blogspot.com/2014/12/blog-post_4.html&#34;&gt;一眼看出沒有效率的工廠&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://willy0936.blogspot.com/2018/05/blog-post.html&#34;&gt;工廠管理到底應該管什麼？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://willy0936.blogspot.com/2014/12/blog-post_8.html&#34;&gt;工廠管理走一遭&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://willy0936.blogspot.com/2014/12/blog-post_67.html&#34;&gt;「自動化」與「流水線」的迷失&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://willy0936.blogspot.com/2014/12/blog-post_72.html&#34;&gt;工廠管理教戰守則（全文）&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;簡直就是把 TOC、Lean、JIT 等原理重組統整的問答錄。極力建議看完上述原典的人，跟著這些問答錄，一起思辨、活用。&lt;/p&gt;
&lt;p&gt;看完之後，我還要好好思考，是否適合套用在軟體研發管理身上⋯⋯&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>多工切換：有趣的 Lean 觀點</title>
      <link>//william-yeh.net/post/2016/03/lean-perspective-of-multitasking/</link>
      <pubDate>Tue, 29 Mar 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/03/lean-perspective-of-multitasking/</guid>
      
        <description>&lt;p&gt;系統思考，全局思考，是困難的；即使是貌似常識的場域，亦然。&lt;/p&gt;
&lt;p&gt;最近在看 &lt;a href=&#34;https://www.books.com.tw/products/0010662172&#34;&gt;&lt;em&gt;Lean Thinking&lt;/em&gt;&lt;/a&gt; 原典時，感觸更深。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:15em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/03/lean-thinking.jpg&#34; alt=&#34;精實革命 (Lean Thinking)&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/03/lean-thinking.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;精實革命 (Lean Thinking)&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Lean Thinking&lt;/em&gt; 倡議小批量 (small batch)、單件流 (one piece flow) 工作方式；這種工作方式，會觸及到多工、工作切換的議題。&lt;/p&gt;
&lt;p&gt;以常識來說，多工、工作切換，代價是 context switch 的 overhead。因此，近代敏捷開發方法論，總是希望在制度設計上盡量降低工作切換：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;當知識工作者有三件或四件以上的工作要做，他們花費在工作切換時，所需重新設定工作模式的時間，會比實際花費在每件工作上的時間還要來的長。
&amp;mdash; 《&lt;a href=&#34;http://www.books.com.tw/products/0010549884&#34;&gt;笑談軟體工程：敏捷開發法的逆襲&lt;/a&gt;》 p.180&lt;/p&gt;
&lt;p&gt;多工是一種浪費，給員工同時間分配多種工作是專案產生浪費的一個根源。軟體開發人員每次在轉換工作時都會浪費大量的調換時間，因為他必須調整思路以便投入新的任務流程。當然，若是你同時參與多個開&lt;br&gt;
發團隊的話，自然會造成更多的停頓，從而引起更多的任務調換而浪費更多時間。
&amp;mdash; 《&lt;a href=&#34;http://www.books.com.tw/products/0010669225&#34;&gt;精實開發與看板方法&lt;/a&gt;》 p.11&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;原本我也把它當成不證自明的常識。不過，偶然看到 &lt;em&gt;Lean Thinking&lt;/em&gt; 提到的一項實驗，大大顛覆我的成見。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;先看一段 Ron Pereira 根據 &lt;em&gt;Lean Thinking&lt;/em&gt; 書中所提的實驗，錄的一段影片：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/Bi9R1Hqr8dI?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;單一動作，反覆做，練成不經大腦思考的機械式反應時，理論上，單一動作的效率會極大化。這也是科學管理之夫泰勒的觀點。&lt;/p&gt;
&lt;p&gt;所以，看了這段實驗，真是令人咋舌。&lt;/p&gt;
&lt;p&gt;兩年後，他又重做了一次實驗：&lt;/p&gt;
&lt;div style=&#34;position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;&#34;&gt;
      &lt;iframe allow=&#34;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen&#34; loading=&#34;eager&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; src=&#34;https://www.youtube.com/embed/Dr67i5SdXiM?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0&#34; style=&#34;position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;&#34; title=&#34;YouTube video&#34;&gt;&lt;/iframe&gt;
    &lt;/div&gt;

&lt;p&gt;實驗設計上，瑕疵當然很多，就連隨機對照實驗都沒做。不過，個人認為，實驗設計完美與否，並不是此例想彰顯的重點。它想彰顯的，都在第一段影片的小標上。&lt;/p&gt;
&lt;p&gt;我們當然可以坐下來徹底分析：違反直覺的第二種方法，為什麼反而比較快（儘管這可能只是後見之明）。不過，這實驗已經突顯一件事：「工作切換」這件事情的影響，可能需要重新思考；不能只從微觀的局部角度，更要從整體、flow 的角度去檢視。&lt;/p&gt;
&lt;p&gt;單純以「工作切換」這件事，換個 Lean Thinking 思維角度，就能得出違反直覺的結果。天知道還有多少尚未被推翻的「不證自明的常識」呢？&lt;/p&gt;
&lt;p&gt;整體 vs 局部的判斷，委實不能等閒視之呀。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>POLP：最小權限原則</title>
      <link>//william-yeh.net/post/2016/03/polp-intro/</link>
      <pubDate>Tue, 15 Mar 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/03/polp-intro/</guid>
      
        <description>&lt;p&gt;在我開的 &lt;a href=&#34;http://get.soft-arch.net/ansible/&#34;&gt;Ansible Workshop&lt;/a&gt; 中，不管是課前的【許願池】，還是課程現場的 Q&amp;amp;A，總有一個熱門議題：「如何確保系統是安全的？」&lt;/p&gt;
&lt;p&gt;這是大哉問，不是單獨一門組態管理課就能探討到令人滿意的地步（資安也不是我所擅長的⋯⋯）。不過，被問到的次數太多了，我還是給個簡單的導引吧。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;系統安全有許多層次。以 &lt;a href=&#34;https://www.safaribooksonline.com/library/view/learning-linux-security/9781771374194/&#34;&gt;&lt;em&gt;Learning Linux Security&lt;/em&gt;&lt;/a&gt; 教學課程的大綱來看，至少涵蓋幾個層次：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Booting：作業系統開機環節&lt;/li&gt;
&lt;li&gt;Kernel：作業系統核心&lt;/li&gt;
&lt;li&gt;Services：典型系統服務&lt;/li&gt;
&lt;li&gt;Users and permissions：帳號及權限&lt;/li&gt;
&lt;li&gt;Firewalls：防火牆&lt;/li&gt;
&lt;li&gt;Logging and log management：日誌管理&lt;/li&gt;
&lt;li&gt;Intrusion detection and prevention：入侵偵測及預防&lt;/li&gt;
&lt;li&gt;Utilities：診斷工具&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;各個環節，都有各自專門知識及輔助工具（我就說這是大哉問吧⋯⋯）。這些都是傳統 admin 或 ops 的責任區。&lt;/p&gt;
&lt;p&gt;不過，即使不是專業的 ops，身為一位 dev，至少有兩點是自己的責任區，需要好好掌握的。&lt;/p&gt;
&lt;p&gt;首先是 &lt;strong&gt;Users and permissions 環節&lt;/strong&gt;。近年來流行的軟體設計方式，部署時，常常不會 100% 寄生在 Apache、Nginx、Tomcat 這些 application container 底下，而是像 PHP 的 &lt;a href=&#34;http://php-fpm.org/&#34;&gt;FPM 模式&lt;/a&gt;、Python 的 &lt;a href=&#34;http://gunicorn.org/&#34;&gt;Gunicorn 模式&lt;/a&gt;、Ruby 的 &lt;a href=&#34;http://unicorn.bogomips.org/&#34;&gt;Unicorn 模式&lt;/a&gt;，有一個或多個協同作業的 process；甚至像 Node.js 或 Java 硬漢，往往不假外力，直接就把程式本身設計成 daemon 了。此時，開發者就不能逃避，必須考慮如何設定該軟體的帳號及權限，包括 process 的 UID、GID，以及相關的檔案目錄存取權限。&lt;/p&gt;
&lt;p&gt;其次是 &lt;strong&gt;Services 環節&lt;/strong&gt;。以 daemon 形式存在的軟體，通常會安裝成 service，透過 &lt;a href=&#34;https://en.wikipedia.org/wiki/Init&#34;&gt;SysV init&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Upstart&#34;&gt;Upstart&lt;/a&gt; 或 &lt;a href=&#34;https://en.wikipedia.org/wiki/Systemd&#34;&gt;systemd&lt;/a&gt; 等機制啟動與管理。這時，也必須連帶把前述的帳號權限處理好。有潔癖的，甚至還會加掛 &lt;a href=&#34;https://en.wikipedia.org/wiki/Chroot&#34;&gt;chroot&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/AppArmor&#34;&gt;AppArmor&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Security-Enhanced_Linux&#34;&gt;SELinux&lt;/a&gt; 等嚇人的保護機制。&lt;/p&gt;
&lt;p&gt;對於帳號權限不知道該如何設定的人，通常最好的方式是：觀摩別人是怎麼做的，尤其是經典級的 services。&lt;/p&gt;
&lt;p&gt;我們就在 Ubuntu 14.04 裡面，好好觀摩一下吧。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;以 Apache 為例，如果你是透過 &lt;code&gt;apt-get install apache2&lt;/code&gt; 來安裝，可看到它是以 &lt;code&gt;www-data&lt;/code&gt; 的身份來執行 worker process：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ps aux | grep apache2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root      2734  0.0  0.5  73368  2628 ?        Ss   04:36   0:00 /usr/sbin/apache2 -k start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;www-data  2737  0.0  0.4 362532  2240 ?        Sl   04:36   0:00 /usr/sbin/apache2 -k start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;www-data  2738  0.0  0.4 362532  2240 ?        Sl   04:36   0:00 /usr/sbin/apache2 -k start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;以 Nginx 為例，如果你是透過 &lt;code&gt;apt-get install nginx&lt;/code&gt; 來安裝，可看到它也是以 &lt;code&gt;www-data&lt;/code&gt; 的身份來執行 worker process：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ps aux | grep nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root      3313  0.0  0.2  85884  1340 ?        Ss   04:44   0:00 nginx: master process /usr/sbin/nginx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;www-data  3314  0.0  0.3  86228  1768 ?        S    04:44   0:00 nginx: worker process
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;www-data  3315  0.0  0.3  86228  1768 ?        S    04:44   0:00 nginx: worker process
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;www-data  3316  0.0  0.3  86228  1768 ?        S    04:44   0:00 nginx: worker process
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;www-data  3317  0.0  0.3  86228  1768 ?        S    04:44   0:00 nginx: worker process&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;以 MySQL 為例，&lt;!-- raw HTML omitted --&gt;如果你是透過 &lt;code&gt;apt-get install mysql-server&lt;/code&gt; 來安裝，可看到它是以 &lt;code&gt;mysql&lt;/code&gt; 的身份來執行：&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ps aux | grep mysql
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mysql     7004  0.5  8.8 623920 44536 ?        Ssl  04:48   0:00 /usr/sbin/mysqld&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;從以上三個經典案例，可以歸納出一個小結論：「他們都&lt;strong&gt;盡可能不以 root 身分執行&lt;/strong&gt;。」&lt;/p&gt;
&lt;p&gt;這些 &lt;code&gt;www-data&lt;/code&gt; 及 &lt;code&gt;mysql&lt;/code&gt; 帳號，甚至沒有登入的權力：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cat /etc/passwd | egrep &amp;#39;(mysql|www-data)&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mysql:x:109:116:MySQL Server,,,:/nonexistent:/bin/false
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cat /etc/group  | egrep &amp;#39;(mysql|www-data)&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;www-data:x:33:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mysql:x:116:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;也沒有偷開 sudo 後門：&lt;/p&gt;
&lt;div class=&#34;highlight-container&#34;&gt;
  &lt;button class=&#34;copy-code-btn outline&#34;&gt;Copy&lt;/button&gt;
    &lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo cat /etc/sudoers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Defaults    env_reset
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Defaults    mail_badpass
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Defaults    secure_path=&amp;#34;/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# User privilege specification
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;root    ALL=(ALL:ALL) ALL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Members of the admin group may gain root privileges
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;%admin ALL=(ALL) ALL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;# Allow members of group sudo to execute any command
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;%sudo    ALL=(ALL:ALL) ALL&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
  &lt;/div&gt;

&lt;p&gt;所以，這些經典級的服務，他們都非常自制，極度限縮自己的權力。&lt;/p&gt;
&lt;p&gt;用更有學問的說法：他們都遵循&lt;strong&gt;最小權限原則&lt;/strong&gt; (&lt;em&gt;principle of least privilege&lt;/em&gt;; POLP)。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;維基百科提到 POLP 的&lt;a href=&#34;https://en.wikipedia.org/wiki/Principle_of_least_privilege#History&#34;&gt;歷史淵源&lt;/a&gt;，可追溯至 1974 年：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every program and every privileged user of the system should operate using the least amount of privilege necessary to complete the job.&lt;/p&gt;
&lt;p&gt;— &lt;a href=&#34;https://en.wikipedia.org/wiki/Jerome_H._Saltzer&#34;&gt;Jerome Saltzer&lt;/a&gt;, &lt;a href=&#34;https://en.wikipedia.org/wiki/Communications_of_the_ACM&#34;&gt;&lt;em&gt;Communications of the ACM&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可見這算是歷久彌新的原則了。&lt;/p&gt;
&lt;p&gt;如果要將 POLP 套用到目前流行的 web application，我引述 &lt;em&gt;Secure Your Node.js Web Application&lt;/em&gt; 一書的&lt;a href=&#34;http://www.safaribooksonline.com/a/secure-your-nodejs/1159941/&#34;&gt;說法&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From our web application standpoint, we have the following rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The web application should not be run with root privileges. It should instead use a limited account that has access to only the required resources.&lt;/li&gt;
&lt;li&gt;The database account should not be a root account. The account should have limited privileges over the database tables.&lt;/li&gt;
&lt;li&gt;The users of the web application should be given the minimum set of privileges they need.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;也引述《Ruby on Rails 實戰聖經》的&lt;a href=&#34;https://ihower.tw/rails4/deployment.html&#34;&gt;說法&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;設定伺服器部署使用者&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;習慣上我們會在伺服器上開一個專門的帳號，用來放 Rails 應用程式：&lt;code&gt;sudo adduser --disabled-password deploy&lt;/code&gt; ⋯⋯&lt;/p&gt;
&lt;p&gt;本機執行 &lt;code&gt;cap deploy:check&lt;/code&gt;，就會自動登入遠端的伺服器，在登入的帳號下新建 current、releases 和 shared 這三個目錄。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，回頭檢視一下自己的軟體部署流程，有沒有遵循&lt;strong&gt;最小權限原則&lt;/strong&gt;吧！&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>DevOps 核心元素的考古溯源</title>
      <link>//william-yeh.net/post/2016/03/origin-of-devops-elements/</link>
      <pubDate>Mon, 07 Mar 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/03/origin-of-devops-elements/</guid>
      
        <description>&lt;p&gt;DevOps 和 Agile 的關係是什麼？DevOps 是源自 Agile 的嗎？&lt;/p&gt;
&lt;p&gt;我在〈&lt;a href=&#34;//william-yeh.net/post/2016/01/devops-goals-in-a-nutshell/&#34;&gt;一句話囊括 DevOps 的目標&lt;/a&gt;〉文中曾經簡略提過：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps 雖然和 agile 運動有歷史上的臍帶關係，但嚴格來說，沒有遵循《&lt;a href=&#34;http://www.agilemanifesto.org/&#34;&gt;敏捷宣言&lt;/a&gt;》四大原則，也是能做 DevOps 的；硬是把兩個議題綁在一起，會限縮 DevOps 論述空間⋯⋯&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這種&lt;del&gt;分離主義&lt;/del&gt;論點並不是我首創的。iThome 的〈&lt;a href=&#34;http://www.ithome.com.tw/news/96861&#34;&gt;為什麼會出現 DevOps？&lt;/a&gt;〉一開頭也提到，DevOps 的源頭不只有 agile 一系：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps 運動承襲自敏捷系統管理 (Agile System Administration) 運動以及企業系統管理 (Enterprise System Management，ESM) 運動。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不過，我還是想替這種論述，找到更權威、更全面一點的溯源分析。&lt;/p&gt;
&lt;p&gt;終於，我從 &lt;a href=&#34;http://www.amazon.com/dp/0988262592/ref=cm_sw_r_tw_dp_a4p3wb0PSYY97&#34;&gt;&lt;em&gt;The Phoenix Project&lt;/em&gt;&lt;/a&gt; 書中找到想要的論述。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:15em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/03/the-phoenix-project.png&#34; alt=&#34;The Phoenix Project&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/03/the-phoenix-project.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;The Phoenix Project&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/dp/0988262592/ref=cm_sw_r_tw_dp_a4p3wb0PSYY97&#34;&gt;&lt;em&gt;The Phoenix Project&lt;/em&gt;&lt;/a&gt; 這本書，以&lt;a href=&#34;http://www.bookzone.com.tw/event/201108_goldratt/&#34;&gt;高德拉特&lt;/a&gt;那種極受歡迎的企管小說形式，闡述在一個面臨內部外部危機的 IT 組織中，DevOps 能發揮什麼樣的功效。對這本書的背景有興趣的，請讀讀該書作者 Gene Kim 的&lt;a href=&#34;http://www.infoq.com/cn/articles/phoenix-project-book-review&#34;&gt;訪談文章&lt;/a&gt;，或是 Howie 寫的&lt;a href=&#34;http://lab.howie.tw/2016/02/phoenix-project.html&#34;&gt;重點整理&lt;/a&gt;、Ruddy 寫的&lt;a href=&#34;https://ruddyblog.wordpress.com/2016/01/26/the-phoenix-project-%E5%B0%8E%E8%AE%80/&#34;&gt;導讀&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;整本書非常豐富，本篇文章只專門針對該書附錄 &amp;ldquo;&lt;em&gt;Where DevOps Came From&lt;/em&gt;&amp;rdquo; 進行導讀。&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;作者如此定調 DevOps：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We refer to &amp;ldquo;DevOps&amp;rdquo; as the outcome of &lt;em&gt;applying Lean principles to the IT value stream&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;出現一個近年來非常潮的字眼——&lt;a href=&#34;http://leanmanufacturingtools.org/39/lean-thinking-lean-principles/&#34;&gt;Lean principles；精實／精益原則&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;這些原則，並不是 IT 界所獨有的，而是取經自其他領域，尤其是製造業：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;These principles are based on more than a century of sound management practices. However, instead of being applied to the transformation of physical goods, we are using these principles to &lt;em&gt;accelerate flow of work through Product Management, Development, Test, IT Operations, and InfoSec.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，DevOps 算是縱貫專案管理、開發、測試、維運、資安等環節的一條鞭精實手法。&lt;/p&gt;
&lt;p&gt;在整個 IT 價值鏈中，DevOps 的確受惠於 agile 陣營對於傳統專案管理的顛覆觀點：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps has benefited tremendously from the work the Agile Community has done, showing how small teams operating with &lt;em&gt;high trust&lt;/em&gt; combined with small batch sizes and &lt;em&gt;smaller, more frequent software releases&lt;/em&gt; can dramatically increase productivity of Development organizations. In fact, many of the key moments in the DevOps history happened at Agile conferences [&amp;hellip;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因此，在技術面來說，DevOps 吸納了以下的 agile 元素：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps extends and builds upon the practices of &amp;ldquo;&lt;em&gt;infrastructure as code&lt;/em&gt;&amp;rdquo; pioneered by Dr. Mark Burgess, as well as &lt;em&gt;continuous integration&lt;/em&gt; and &lt;em&gt;continuous deployment&lt;/em&gt; (pioneered by Jez Humble and David Farley), which is a prerequisite to &lt;em&gt;achieving fast deployment flow&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不過，從這裡可以清楚地看到，DevOps「向 agile 陣營取經」的元素，多半集中在對「加速部署速度」有直接助益的工具元素上。所以，只是一種選擇性的取經。&lt;/p&gt;
&lt;p&gt;另一方面，DevOps 本身也沒有停留在「只向 agile 陣營取經」的階段，仍繼續吸納其他領域的優點。尤其 DevOps 也著重最後一哩路的 &amp;ldquo;Ops&amp;rdquo; 這一端，因此，也向其他國度取經：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps also benefits from an astounding convergence of philosophical management movements, such as &lt;em&gt;Lean Startup&lt;/em&gt;, &lt;em&gt;Innovation Culture&lt;/em&gt;, &lt;em&gt;Toyota Kata&lt;/em&gt;, &lt;em&gt;Rugged Computing&lt;/em&gt;, and the &lt;em&gt;Velocity community&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;有趣的是，近年來，許多人再度向日本學習。Agile 陣營的 Kanban 是一例，DevOps 也師法許多 Lean 精神及作法。DevOps 要角 John Willis 甚至還寫了一篇文章 &amp;ldquo;&lt;a href=&#34;http://itrevolution.com/japanese-words-for-devops-practitioners/&#34;&gt;Japanese Terms For DevOps Practitioners&lt;/a&gt;&amp;rdquo; 來介紹這些源自日本的時髦詞彙呢。&lt;/p&gt;
&lt;p&gt;巨變的年代，或許正如作者所說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All of these mutually reinforce each other, creating the conditions of a &lt;em&gt;powerful coalition of forces&lt;/em&gt; that can accelerate DevOps adoption.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;好的東西，會互相吸引，互相融合。屆時，或許就沒有什麼考古的必要；我泥中有你，你泥中有我。就像柯仁傑在〈&lt;a href=&#34;http://kojenchieh.pixnet.net/blog/post/381131219-%E6%95%8F%E6%8D%B7%E5%92%8C%E7%B2%BE%E5%AF%A6%E7%9A%84%E9%97%9C%E4%BF%82-%281%29&#34;&gt;敏捷和精實的關係 (1)&lt;/a&gt;〉一文所說：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;早期敏捷愛好者受到精實的觀念的影響，因此在敏捷世界中也常常出現精實製造的說法。&lt;/p&gt;
&lt;p&gt;所以敏捷跟精實兩者，在軟體開發世界中已經是混合在一起。如果你在實施敏捷，其實代表你也是在套用精實，兩者是無法很清楚地分開來。&lt;/p&gt;
&lt;/blockquote&gt;</description>
      
    </item>
    
    <item>
      <title>電腦界的隱喻：組態管理</title>
      <link>//william-yeh.net/post/2016/03/metaphor-in-cm/</link>
      <pubDate>Wed, 02 Mar 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/03/metaphor-in-cm/</guid>
      
        <description>&lt;p&gt;人類是很喜愛比喻／譬喻的。戰國時代的莊子愛用譬喻，常和莊子抬槓的惠施也愛譬喻，《說苑‧善說》甚至記載著這麼一段故事：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;客謂梁王曰：「惠子之言事也，善譬。王使無譬則不能言矣。」王曰：「諾。」&lt;/p&gt;
&lt;p&gt;明日見， 謂惠子曰：「願先生言事則直言耳，無譬也。」惠子曰：「今有人於此而不知彈者，曰：『彈之狀何若？』應曰：『彈之狀如彈。』則諭乎？」王曰：「未諭也。」 「於是更應曰：『彈之狀如弓，而竹為弦』，則知乎？」王曰：「可知矣。」&lt;/p&gt;
&lt;p&gt;惠子曰：「夫說者固以其所知，喻其所不知，而使人知之。今王曰無譬，則不可矣。」 王曰：「善。」&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;用譬喻反擊「無譬也」的要求，真是高招！&lt;/p&gt;
&lt;p&gt;比喻／譬喻不只是修辭法，甚至是人類根深蒂固的認知媒介。認知語言學大師 George Lakoff 在 &lt;a href=&#34;http://www.amazon.com/dp/0226468011/ref=cm_sw_r_tw_dp_yQP1wb1VDN24N&#34;&gt;&lt;em&gt;Metaphors We Live By&lt;/em&gt;&lt;/a&gt; 書中，如此闡述它的地位：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Metaphor is not just a matter of language of mere words. We shall argue that, on the contrary, human &lt;em&gt;&lt;strong&gt;thought processes&lt;/strong&gt;&lt;/em&gt; are largely metaphorical.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，每次看到有趣的隱喻，我都會特別留意，細細品味背後的巧思。&lt;/p&gt;
&lt;p&gt;電腦界也很愛用隱喻，甚至還會帶出成群的隱喻。&lt;/p&gt;
&lt;p&gt;Java 之名，取材自咖啡。JavaScript 雖然並非嫡傳血脈，但由它衍生出來的其他技術，有些就刻意以「咖啡」為隱喻。像美化 JavaScript 語法的 &lt;a href=&#34;http://coffeescript.org/&#34;&gt;CoffeeScript&lt;/a&gt;、供 JavaScript 使用的測試框架 &lt;a href=&#34;https://mochajs.org/&#34;&gt;Mocha&lt;/a&gt;，甚至連咖啡的對手：&lt;a href=&#34;https://mochajs.org/&#34;&gt;Chai&lt;/a&gt; 都搬出來了。&lt;/p&gt;
&lt;p&gt;組態管理的四大工具，也是愛用隱喻的。&lt;/p&gt;
&lt;p&gt;Ansible 主要的隱喻是&lt;strong&gt;演戲&lt;/strong&gt;。所以，在 Ansible 劇場中，策劃好的動作及姿勢叫做 &lt;strong&gt;play&lt;/strong&gt;，集合起來就是 &lt;strong&gt;playbook&lt;/strong&gt;（劇本）。人生就是戲，演不完的戲；在舞台上，每一台主機扮演一個或多個 &lt;strong&gt;role&lt;/strong&gt;（角色），甚至還有天外飛來一筆的空降角色 —— 來自 &lt;strong&gt;galaxy&lt;/strong&gt;（銀河系）。&lt;/p&gt;
&lt;p&gt;Chef 主要的隱喻是&lt;strong&gt;廚師&lt;/strong&gt;。所以，在 Chef 世界中，珍藏厚厚的 &lt;strong&gt;cookbook&lt;/strong&gt;（食譜），根據裡面記載的 &lt;strong&gt;recipe&lt;/strong&gt;（料理步驟），用 &lt;strong&gt;knife&lt;/strong&gt;（菜刀）做菜，也有一個 &lt;strong&gt;kitchen&lt;/strong&gt;（廚房）可以實驗料理。&lt;/p&gt;
&lt;p&gt;Puppet 主要的隱喻是&lt;strong&gt;傀儡&lt;/strong&gt;、&lt;strong&gt;偶戲&lt;/strong&gt;。可惜的是，在 Puppet 舞台上出現的概念：manifest、resource、module、master、agent，似乎都沒有善用最初的隱喻。&lt;/p&gt;
&lt;p&gt;Salt 主要的隱喻是⋯⋯&lt;strong&gt;鹽&lt;/strong&gt;。可惜的是，在 Salt 世界中出現的概念：salt state、formula、master、minion，似乎都沒有善用最初的隱喻。嗯，&amp;ldquo;formula&amp;rdquo; 字眼，勉強算有沾到邊。&lt;/p&gt;
&lt;p&gt;呃，我要修正前面那一句話：「組態管理的四大工具當中，Ansible 和 Chef 也是愛用隱喻的。」&lt;/p&gt;
&lt;p&gt;或許這也是我對 Ansible 及 Chef 比較有好感的原因吧。&lt;/p&gt;
&lt;p&gt;最後，如果你想對這四大工具有個快速的概念，可參考 Roland Wolters 製作的單頁掛圖：&lt;a href=&#34;http://wall-skills.com/2015/configuration-management-ansible-salt-chef-puppet/&#34;&gt;Tools for Configuration Management&lt;/a&gt;。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/03/Ansible-Salt-Puppet-Chef-Wall-Skills.png&#34; alt=&#34;Tools for Configuration Management&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/03/Ansible-Salt-Puppet-Chef-Wall-Skills.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Tools for Configuration Management&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;</description>
      
    </item>
    
    <item>
      <title>一句話囊括 DevOps 的目標</title>
      <link>//william-yeh.net/post/2016/01/devops-goals-in-a-nutshell/</link>
      <pubDate>Fri, 29 Jan 2016 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2016/01/devops-goals-in-a-nutshell/</guid>
      
        <description>&lt;p&gt;TL;DR&lt;br&gt;
&lt;em&gt;DevOps is a set of practices intended to reduce the time between committing a change to a system and the change being placed into normal production, while ensuring high quality.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;我在許多演講場合，都喜歡調侃 DevOps 百家爭鳴各言爾志的現況。尤其是像 XebiaLabs 的 &amp;ldquo;&lt;a href=&#34;https://xebialabs.com/periodic-table-of-devops-tools/&#34;&gt;Periodic Table of DevOps Tools&lt;/a&gt;&amp;quot;，用化學元素週期表來類比，傳神極了！&lt;/p&gt;
&lt;p&gt;調侃歸調侃，但總還是得選一套說法當參考座標，議題定位才能明確。我也不喜歡太欠缺客觀性的打高空調調，尤其是涉及組織文化層面的論調。畢竟，DevOps 雖然和 agile 運動有歷史上的臍帶關係，但嚴格來說，沒有遵循《&lt;a href=&#34;http://www.agilemanifesto.org/&#34;&gt;敏捷宣言&lt;/a&gt;》四大原則，也是能做 DevOps 的；硬是把兩個議題綁在一起，會限縮 DevOps 論述空間，很容易挑起 &amp;ldquo;it doesn&amp;rsquo;t work here&amp;rdquo; 的防禦心態。&lt;/p&gt;
&lt;p&gt;推廣新觀念，就要從阻力最小的角度切入。&lt;/p&gt;
&lt;p&gt;因此，我在去年 12 月 Container Summit 2015 講〈&lt;a href=&#34;http://www.slideshare.net/williamyeh/dockers-impact-on-the-devops-toolchain&#34;&gt;擁抱或對抗？談 Docker 對傳統 DevOps 工具鏈的衝擊&lt;/a&gt;〉時，首次搬出 Brian Brazil 在 &amp;ldquo;&lt;a href=&#34;http://www.robustperception.io/do-you-have-basic-infrastructure/&#34;&gt;Do you have basic infrastructure?&lt;/a&gt;&amp;rdquo; 一文提出的三問句來破題：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You need to know:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How to recreate your system&lt;/li&gt;
&lt;li&gt;How to safely change your system&lt;/li&gt;
&lt;li&gt;When something has gone wrong&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;蘇格拉底式問句，不夾帶特定前提，不偷渡既定結論，很適合拿來引導團隊思考。因此，後來我在〈&lt;a href=&#34;//william-yeh.net/post/2015/12/devops-1st-step/&#34;&gt;DevOps 是圓的，找到立足點就是頂點&lt;/a&gt;〉文章、在 &lt;a href=&#34;http://get.soft-arch.net/ansible/&#34;&gt;Ansible Workshop 課堂&lt;/a&gt;上，也反覆用到這三問句。&lt;/p&gt;
&lt;p&gt;不過，私心還是希望能有一個更直述、更目標導向的操作型定義。&lt;/p&gt;
&lt;p&gt;找了很久，偶然在 2015 年 SEI 系列的新書 &lt;a href=&#34;http://www.amazon.com/dp/0134049845/ref=cm_sw_r_tw_dp_bB.Qwb0FF6QRZ&#34;&gt;&lt;em&gt;DevOps: A Software Architect&amp;rsquo;s Perspective&lt;/em&gt;&lt;/a&gt; 第一章，發現我想要的操作型定義了。&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2016/01/devops-from-architect-perspective.png&#34; alt=&#34;DevOps: A Software Architect&amp;#39;s Perspective&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2016/01/devops-from-architect-perspective.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;DevOps: A Software Architect&amp;#39;s Perspective&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;SEI 這塊金字招牌，乍看之下會以為又要端出像 CMMI、PSP 那樣硬梆梆的東西。不過，瞄到書名當中有 &amp;ldquo;A Software Architect&amp;rsquo;s Perspective&amp;rdquo; 字眼，就覺得應該比較貼近第一線的實務現場。&lt;/p&gt;
&lt;p&gt;他們的切入角度是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our definition of DevOps focuses on the &lt;strong&gt;goals&lt;/strong&gt;, rather than the &lt;strong&gt;means&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很多時候，先聚焦在共有的目標上，會比過早陷入細部做法的爭論來得有用。&lt;/p&gt;
&lt;p&gt;從「目標」角度出發，再對 DevOps 下定義，更顯得客觀中立。畢竟，不管是大機構還是小團隊，不管背後採用哪一種軟體開發流程，都能接受以下這種 DevOps 目標：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;DevOps is a set of &lt;em&gt;practices&lt;/em&gt; intended to &lt;strong&gt;reduce the time between committing a change to a system and the change being placed into normal production, while ensuring high quality&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;這跟前面那三問句是相互呼應的，只不過這一回用的是更直述、更目標導向的操作型定義。&lt;/p&gt;
&lt;p&gt;這段定義陳述，點出 DevOps 兩大目標：&lt;strong&gt;時間&lt;/strong&gt;及&lt;strong&gt;品質&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;時間：在「commit change」到「上線營運生效」兩者之間的時間差，要盡量縮短到某個設定的水平之內。&lt;/li&gt;
&lt;li&gt;品質：不能只求上線生效，還要對品質把關，維持在某個設定的水平之上。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;弄清楚 DevOps 的目標後，再看 DevOps 圈子倡議的 practices，就不覺突兀：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Treat Ops as first-class citizens from the point of view of requirements.&lt;/li&gt;
&lt;li&gt;Make Dev more responsible for relevant incident handling. These practices are intended to shorten the time between the observation of an error and the repair of that error.&lt;/li&gt;
&lt;li&gt;Enforce the deployment process used by all, including Dev and Ops personnel.&lt;/li&gt;
&lt;li&gt;Use continuous deployment.&lt;/li&gt;
&lt;li&gt;Develop infrastructure code, such as deployment scripts, with the same set of practices as application code.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這五項 practices，都可以回溯到先前設定的 DevOps 兩大目標：時間及品質。&lt;/p&gt;
&lt;p&gt;當然啦，同一份目標，可能衍生出不同的實作手法；此時此刻公認的 best practices，也可能在不久就被推翻。書中建議我們可以根據幾點來評估：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What is the particular practice you are considering?&lt;/strong&gt;&lt;br&gt;
這家 DevOps 百貨公司，大肆推銷的東西太多了，必須先針對組織的需求及現況加以評估、排序。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What other practices are implicit in the practice you are considering?&lt;/strong&gt;&lt;br&gt;
某些措施有隱含的前提。譬如說，想實現 continuous deployment 之前，不可能不先做 continuous integration。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;What is the culture of your business, and what are the ramifications of your adopting this particular DevOps practice?&lt;/strong&gt;&lt;br&gt;
任何改變都有受到波及的對象，所以，想導入任何改變，都不能忽略組織及人性的抗拒力道。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這就是 SEI 出版的書 &lt;a href=&#34;http://www.amazon.com/dp/0134049845/ref=cm_sw_r_tw_dp_bB.Qwb0FF6QRZ&#34;&gt;&lt;em&gt;DevOps: A Software Architect&amp;rsquo;s Perspective&lt;/em&gt;&lt;/a&gt; 當中的第一章，對於 DevOps 下的目標導向定義，以及隨之鋪陳的實踐手法及考量依據。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>DevOps 是圓的，找到立足點就是頂點</title>
      <link>//william-yeh.net/post/2015/12/devops-1st-step/</link>
      <pubDate>Mon, 28 Dec 2015 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2015/12/devops-1st-step/</guid>
      
        <description>&lt;p&gt;自從 IT 相關媒體開始傳頌 2009 年蔚為經典的 Flickr 經驗 “&lt;a href=&#34;https://youtu.be/LdOe18KhtT4&#34;&gt;10+ Deploys per Day&lt;/a&gt;”、2014 年 Marissa Mayer 的鐵桿作風「&lt;a href=&#34;http://www.ithome.com.tw/news/99283&#34;&gt;沒有持續交付，專案不得上線，我不是在說笑&lt;/a&gt;」之後，頓時 DevOps 成為 IT 界新的焦慮源。我還聽說有高層在聽完兩天 &lt;a href=&#34;https://www.ithome.com.tw/article/98527&#34;&gt;DevOps 2015 研討會&lt;/a&gt;之後，回頭要求 IT 部門要師法 2009 年的 Flickr 做到「10+ Deploys per Day」。&lt;/p&gt;
&lt;p&gt;聽了很潮的新觀念，就訂不合理的 KPI，這也是「負能量」呀！&lt;/p&gt;
&lt;p&gt;本質上，DevOps 是一種文化運動。文化不挪動，流程、工具也無法落地生效。&lt;/p&gt;
&lt;p&gt;如果組織文化充滿壁壘分明的界線，缺少從錯誤中學習的不指責氛圍，只盲目崇尚數字管理、成效管理，那就很難用健康的心態去嘗試新的流程及工具，進而受益。&lt;/p&gt;
&lt;h2 id=&#34;起點&#34;&gt;起點&lt;/h2&gt;
&lt;p&gt;如果組織文化已經做好改變的準備了，流程、工具該怎麼起步呢？&lt;/p&gt;
&lt;p&gt;Bryan 在大人學講座【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/57&#34;&gt;尋找天賦與熱情的系統化做法&lt;/a&gt;】曾提到一個觀點：「世界是圓的，找到立足點就是頂點。」&lt;/p&gt;
&lt;p&gt;我也想照樣照句：「DevOps 是圓的，找到立足點就是頂點。」&lt;/p&gt;
&lt;p&gt;我不太信奉放諸四海皆準的方法論、roadmap、步驟。而且，DevOps 真的是圓的，從任何一個契合組織現況的角度切入，都有機會逐步把整塊 DevOps 拼圖補齊。&lt;/p&gt;
&lt;p&gt;譬如說，如果你的組織是研發驅動的，或許從 CI 角度切入，阻力會比較小；這也是稍早兩篇文章〈&lt;a href=&#34;//william-yeh.net/post/2015/12/ci-no-turning-back/&#34;&gt;CI 是條不歸路&lt;/a&gt;〉、〈&lt;a href=&#34;//william-yeh.net/post/2015/12/ci-effect/&#34;&gt;CI 怎樣帶你遠離平庸？&lt;/a&gt;〉的論點。&lt;/p&gt;
&lt;p&gt;當然啦，並不是所有團隊都認為 CI 是他們的當務之急。此時，硬是要推銷 CI 理念或工具，不見得是上策。&lt;/p&gt;
&lt;p&gt;另一個我常拿來進行個案研討的蘇格拉底式問句，是從「&lt;strong&gt;DevOps 的原點&lt;/strong&gt;」來提問。&lt;/p&gt;
&lt;h2 id=&#34;原點&#34;&gt;原點&lt;/h2&gt;
&lt;p&gt;DevOps 的原點是什麼？&lt;/p&gt;
&lt;p&gt;我很喜歡引述 Brian Brazil 在 &amp;ldquo;&lt;a href=&#34;http://www.robustperception.io/do-you-have-basic-infrastructure/&#34;&gt;Do you have basic infrastructure?&lt;/a&gt; 一文的觀點。他提到軟體的基礎架構 (infrastructure)，或大或小，或新或舊，總是要面對以下三則基本問題：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;How to recreate your system&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;How to safely change your system&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;When something has gone wrong&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;好好面對這三個問題，不僅讓 DevOps 的核心議題變得無比清晰，更讓團隊自己理出當務之急切身之痛，而不是靠外部&lt;del&gt;名嘴&lt;/del&gt;顧問的通靈神諭。&lt;/p&gt;
&lt;h2 id=&#34;立足點很多只等你起步&#34;&gt;立足點很多，只等你起步&lt;/h2&gt;
&lt;p&gt;這三個問題，好好搞定，其實已經碰觸到許多 DevOps 技術層面的議題了。&lt;/p&gt;
&lt;p&gt;譬如說，【1. How to recreate your system】至少涉及這些議題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如何從原始碼變成可執行的軟體？&lt;/li&gt;
&lt;li&gt;如何確定軟體已經是可發佈的品質？&lt;/li&gt;
&lt;li&gt;如何備妥軟體的執行環境？&lt;/li&gt;
&lt;li&gt;如何自動化上述事項？自動化到什麼程度？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果選擇從這裡出發，你就會接觸到 build automation、acceptance test、configuration management 等技術。&lt;/p&gt;
&lt;p&gt;【2. How to safely change your system】至少涉及這些議題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如何管控原始碼變更？&lt;/li&gt;
&lt;li&gt;如何管控執行環境變更？&lt;/li&gt;
&lt;li&gt;如何確定軟體變更後，仍然是可發佈的品質？&lt;/li&gt;
&lt;li&gt;如何管控新版軟體的部署？&lt;/li&gt;
&lt;li&gt;如何自動化上述事項？自動化到什麼程度？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果選擇從這裡出發，你就會接觸到 Git/GitHub/GitLab flow、configuration management、test automation、continuous integration、continuous deployment 等技術。&lt;/p&gt;
&lt;p&gt;【3. When something has gone wrong】至少涉及這些議題：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如何知道系統出了狀況？&lt;/li&gt;
&lt;li&gt;怎麼樣才叫做「系統出了狀況」？有哪些質化量化指標？&lt;/li&gt;
&lt;li&gt;怎樣處理？&lt;/li&gt;
&lt;li&gt;怎樣復原？&lt;/li&gt;
&lt;li&gt;怎樣預防？&lt;/li&gt;
&lt;li&gt;怎樣集中處理？&lt;/li&gt;
&lt;li&gt;如何自動化上述事項？自動化到什麼程度？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果選擇從這裡出發，你就會接觸到 metrics aggregation、log aggregation、real-time monitoring/dashboard/alert、canary deployment 等技術。&lt;/p&gt;
&lt;p&gt;然後，你從任何一個立足點出發，解決切身之痛，嚐到甜美果實之後，一定會順便對其他相關議題有興趣嘗試、有信心搞定。至於文化議題，也會搭配著碰到。&lt;/p&gt;
&lt;p&gt;譬如說，我的 &lt;a href=&#34;http://get.soft-arch.net/ansible/&#34;&gt;Ansible Workshop 課程&lt;/a&gt;，就是從第一類問題當中的 &amp;ldquo;configuration management&amp;rdquo; 小課題出發，進而發展到 GitHub flow、CI、test automation、canary deployment 等第二、第三類問題。&lt;/p&gt;
&lt;p&gt;這就是文章開頭講的「DevOps 是圓的，找到立足點就是頂點。」&lt;/p&gt;
&lt;h2 id=&#34;不要妄想一步登天先累積小小的成功&#34;&gt;不要妄想一步登天，先累積小小的成功&lt;/h2&gt;
&lt;p&gt;有人認為，小團隊、新團隊包袱小，身兼數職是常態，無部門界線，先天上就比較容易導入 DevOps 流程。&lt;/p&gt;
&lt;p&gt;但也有人認為，大團隊、老團隊分工細密，各人有各自精深的專職技能，先天上比較容易執行一個個高度專業要求的 DevOps 元素。&lt;/p&gt;
&lt;p&gt;不同環境，看待 DevOps，各有不同的優勢與劣勢。所以，停止抱怨吧。&lt;/p&gt;
&lt;p&gt;導入 DevOps，請先回到 DevOps 的原點。&lt;/p&gt;
&lt;p&gt;我建議，先好好檢視上述的三個問題，嚴肅思考哪些是目前的痛點，哪些是容易有早期成功的項目。然後，賦予團隊充分的嘗試錯誤空間，下手去做。&lt;/p&gt;
&lt;p&gt;做了之後，自然就會發現：這是一條不歸路，&lt;strong&gt;你會不斷接觸『遠離平庸』的新觀點、新技術&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;你再也回不去過去那個老土砲的日子了。&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>CI 怎樣帶你遠離平庸？</title>
      <link>//william-yeh.net/post/2015/12/ci-effect/</link>
      <pubDate>Tue, 22 Dec 2015 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2015/12/ci-effect/</guid>
      
        <description>&lt;p&gt;前天我的文章〈&lt;a href=&#34;//william-yeh.net/post/2015/12/ci-no-turning-back/&#34;&gt;CI 是條不歸路&lt;/a&gt;〉提到：「CI/CD/DevOps 既是條不歸路，更是大躍進之路：一旦踏出第一步，就注定你會不斷接觸**『遠離平庸』**的新觀點、新技術。」&lt;/p&gt;
&lt;p&gt;為了避免陳義過高，這篇文章就來講一個具體的軟體研發故事吧。&lt;/p&gt;
&lt;h2 id=&#34;護城河&#34;&gt;護城河&lt;/h2&gt;
&lt;p&gt;我用 Ansible，也用 &lt;a href=&#34;https://prometheus.io/&#34;&gt;Prometheus&lt;/a&gt;，因此，我寫了一個 Ansible role &lt;a href=&#34;https://github.com/William-Yeh/ansible-prometheus&#34;&gt;&lt;code&gt;williamyeh.prometheus&lt;/code&gt;&lt;/a&gt; 來安裝 Prometheus。&lt;/p&gt;
&lt;p&gt;上個禮拜，我隱約覺得對它感興趣的人似乎變多了，便好奇的去 GitHub 後台調數據來看，發現：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;原來是被 Prometheus 官網列入 &amp;ldquo;&lt;a href=&#34;http://prometheus.io/docs/introduction/install/#using-configuration-management-systems&#34;&gt;Using configuration management systems&lt;/a&gt;&amp;rdquo; 清單了，難怪最近 PR 變多，品質更是超越其他幾家 CM 的例子。&lt;/p&gt;
&lt;p&gt;&amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/676897832071241728&#34;&gt;2015-12-16 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;被 Prometheus 官方欽點了，能見度提高了，就表示，三不五時會有人提出 bug report，提出 feature request；甚至更勤勞一點的，可能直接就會送出 PR (pull request)。&lt;/p&gt;
&lt;p&gt;面對 PR，其實要花很大的力氣去檢驗：檢驗對錯，檢驗風格，甚至 &lt;a href=&#34;https://en.wikipedia.org/wiki/The_Mythical_Man-Month#Conceptual_integrity&#34;&gt;conceptual integrity&lt;/a&gt;（語出《&lt;a href=&#34;https://en.wikipedia.org/wiki/The_Mythical_Man-Month&#34;&gt;人月神話&lt;/a&gt;》）。而且，對方既然已經很勤勞的送出 PR 了，他會預期你高度重視他的提案。&lt;/p&gt;
&lt;p&gt;我需要一道&lt;strong&gt;護城河&lt;/strong&gt;，讓我不必每次都事必躬親，回應每一則 PR。&lt;/p&gt;
&lt;p&gt;所幸我早就建立好&lt;strong&gt;個人的 discipline&lt;/strong&gt;：要替自己寫的 Ansible role 加上 CI。即使只是做一點點小小的 smoke test，總是聊勝於無。&lt;/p&gt;
&lt;p&gt;CI 是&lt;strong&gt;高度客觀中立&lt;/strong&gt;、&lt;strong&gt;不帶感情&lt;/strong&gt;的守門員。它，幫我初步過濾一些攸關對錯、風格的 PR。於是，我可以優先禮貌性回應已經被 CI 初步打勾放行的 PR；至於被打叉叉的，那就&lt;del&gt;謝謝再聯絡&lt;/del&gt;等有充裕時間精力時再說：&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2015/12/ansible-prometheus-pr.png&#34; alt=&#34;Pull requests&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2015/12/ansible-prometheus-pr.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Pull requests&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;CI，小小的投資，大大的省事。&lt;/p&gt;
&lt;h2 id=&#34;當-ansible-遇見-docker&#34;&gt;當 Ansible 遇見 Docker&lt;/h2&gt;
&lt;p&gt;個人還有另一項執念：自己寫的 Ansible role，要盡可能支援多種 Linux distributions 環境。&lt;/p&gt;
&lt;p&gt;這又是一條不歸路。&lt;/p&gt;
&lt;p&gt;在本機端研發時，我可以用各種 Vagrant box 來模擬各種 Linux （譬如：&lt;a href=&#34;https://app.vagrantup.com/bento/boxes/centos-6.7&#34;&gt;bento/centos-6.7&lt;/a&gt;、&lt;a href=&#34;https://app.vagrantup.com/bento/boxes/centos-7.1&#34;&gt;bento/centos-7.1&lt;/a&gt;、&lt;a href=&#34;https://app.vagrantup.com/debian/boxes/jessie64&#34;&gt;debian/jessie64&lt;/a&gt;），但這沒辦法 scale 到正式的 CI 流程上。此刻 Travis CI 及 CircleCI 只提供 Ubuntu 12.04 及 14.04 兩種 instance，也沒支援 &lt;a href=&#34;http://kitchen.ci&#34;&gt;Test Kitchen&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;所幸 Travis CI 和 CircleCI 都有支援 Docker，因此，我設計了 &lt;a href=&#34;https://github.com/William-Yeh/docker-ansible&#34;&gt;&lt;code&gt;williamyeh/ansible&lt;/code&gt;&lt;/a&gt; 這一系列的 Docker images，可在 Travis CI 及 CircleCI 上面模擬出 CentOS 6 &amp;amp; 7、Debian 7 &amp;amp; 8、Ubuntu 12.04 &amp;amp; 14.04 環境，來測試我的 Ansible roles。&lt;/p&gt;
&lt;p&gt;這下子，我的 CI 護城河就更穩固了。CI 這位&lt;strong&gt;高度客觀中立&lt;/strong&gt;、&lt;strong&gt;不帶感情&lt;/strong&gt;的守門員，協助我冷靜面對以下這則算是大工程等級的 PR，不帶批判情緒的進行對話，一起搞定 CentOS/Ubuntu 雙系統：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2015/12/pr-discussion.png&#34; alt=&#34;Discussion around a pull request&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2015/12/pr-discussion.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Discussion around a pull request&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;CI，小小的投資，大大的省事。&lt;/p&gt;
&lt;p&gt;對我而言，原本 &lt;code&gt;williamyeh/ansible&lt;/code&gt; 只是為了其他目的而順帶設計出來的副產品。但由於 Ansible 官方已不再維護它的 Docker images；而在非官方版當中，我的 &lt;code&gt;williamyeh/ansible&lt;/code&gt; 下載量居冠（統計數據&lt;a href=&#34;https://hub.docker.com/search/?q=ansible&amp;amp;page=1&amp;amp;isAutomated=0&amp;amp;isOfficial=0&amp;amp;pullCount=1&amp;amp;starCount=0&#34;&gt;在此&lt;/a&gt;），也持續有人提出 feature request⋯⋯該說是無心插柳嗎？&lt;/p&gt;
&lt;h2 id=&#34;吃自己的狗食&#34;&gt;吃自己的狗食&lt;/h2&gt;
&lt;p&gt;再拿另一個很受歡迎的 Ansible role：&lt;a href=&#34;https://github.com/William-Yeh/ansible-oracle-java&#34;&gt;&lt;code&gt;williamyeh.oracle-java&lt;/code&gt;&lt;/a&gt; 為例。它在 Ansible Galaxy 已經得到 &lt;a href=&#34;https://galaxy.ansible.com/william-yeh/oracle-java&#34;&gt;4.8 的高分&lt;/a&gt;，是一個已經為人所知，甚至為人所用的元件。&lt;/p&gt;
&lt;p&gt;因此，我必須維持良好的向後相容性，以對用戶負責。&lt;/p&gt;
&lt;p&gt;也因此，連我自己想對原始程式做更動，也不敢貿然造次。必須遵守 &lt;a href=&#34;http://nvie.com/posts/a-successful-git-branching-model/&#34;&gt;Git Flow&lt;/a&gt; 或 &lt;a href=&#34;https://guides.github.com/introduction/flow/&#34;&gt;GitHub Flow&lt;/a&gt; 之類的 &lt;strong&gt;workflow discipline&lt;/strong&gt;，一樣要看 CI 這位&lt;strong&gt;高度客觀中立&lt;/strong&gt;、&lt;strong&gt;不帶感情&lt;/strong&gt;的守門員的臉色。&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2015/12/github-graph.png&#34; alt=&#34;Network graph&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2015/12/github-graph.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;Network graph&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;專業，就是對自己也有 discipline。CI，就是&lt;strong&gt;強制幫助你建立 discipline&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;不要輕看-ci-的紅燈&#34;&gt;不要輕看 CI 的紅燈&lt;/h2&gt;
&lt;p&gt;對這個 Ansible role，有一點我一直耿耿於懷：Travis CI 和 CircleCI 的測試結果，時好時壞。&lt;/p&gt;
&lt;p&gt;像以下截圖顯示，同樣都是針對 &lt;code&gt;6598bed&lt;/code&gt; 這個 commit，Travis CI 一次就通過，但 CircleCI 居然會出現一堆紅燈。不死心的我，一直按 rebuild 好幾次，總算才出現綠燈：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2015/12/circleci-error.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2015/12/circleci-error.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;奇怪的是，同樣都是針對 &lt;code&gt;a9c105e&lt;/code&gt; 這個 commit，這回 CircleCI 一次就通過，反倒是 Travis CI 出狀況：&lt;/p&gt;


&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2015/12/travisci-error.png&#34; /&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2015/12/travisci-error.png&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;p&gt;前幾天，我終於忍不住出手。&lt;/p&gt;
&lt;p&gt;反覆比對兩邊的 log，發現，Oracle 疑似會對 jdk 下載點做 rate limiting。每次 Travis CI 及 CircleCI 的 CI 大隊一啟動，Oracle 就惱了。&lt;/p&gt;
&lt;p&gt;所以，不是我的 Ansible role 有問題，是 Oracle 太神經兮兮了。&lt;/p&gt;
&lt;p&gt;怪罪 Oracle 於事無補，問題總得解決⋯⋯&lt;/p&gt;
&lt;p&gt;為了解決這問題，我設計一個 prefetch 機制：只向 Oracle 抓一次需要的 rpm 及 tar.gz 檔案，存放在 role 的 &lt;code&gt;files&lt;/code&gt; 目錄裡面。如此一來，不僅避開 rate limiting 的限制，連帶的也降低整體的 build time，更讓整個 role 架構 refactor 得更乾淨。&lt;/p&gt;
&lt;p&gt;CI，小小的投資，大大的省事。&lt;/p&gt;
&lt;h2 id=&#34;卻顧所來徑&#34;&gt;卻顧所來徑&lt;/h2&gt;
&lt;p&gt;這一切的一切，濫觴都只是一個小起步：要替自己寫的 Ansible role 加上 CI。&lt;/p&gt;
&lt;p&gt;一旦踏出第一步，就注定你會不斷接觸**『遠離平庸』**的新觀點、新技術。&lt;/p&gt;
&lt;p&gt;你同意嗎？&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>CI 是條不歸路</title>
      <link>//william-yeh.net/post/2015/12/ci-no-turning-back/</link>
      <pubDate>Mon, 21 Dec 2015 08:00:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2015/12/ci-no-turning-back/</guid>
      
        <description>&lt;p&gt;今年九月初參加完 &lt;a href=&#34;https://www.ithome.com.tw/article/98527&#34;&gt;DevOps 2015&lt;/a&gt; 之後，有感而發，寫了兩則 tweets：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;說實在的，打從 1999 年 Kent Beck 經典著作 &lt;em&gt;Extreme Programming Explained&lt;/em&gt; 問世，整個軟體文化就被徹底分裂成&lt;strong&gt;兩個國度&lt;/strong&gt;。以 agile best practices 出發的國度，不斷演化至另一個國度難以企及的高度。&lt;!-- raw HTML omitted --&gt;
&amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/639246537151803392&#34;&gt;2015-09-03 Tweet #1&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;blockquote&gt;
&lt;p&gt;這個時代，如果還覺得 DevOps 是 mission impossible，可以說，連 1999 年的&lt;strong&gt;小團隊水準&lt;/strong&gt;都達不到。或許該回頭蹲馬步，好好思考 &lt;em&gt;Extreme Programming Explained&lt;/em&gt; 裡面講的幾個 best practices，有哪些可以嘗試看看。&lt;!-- raw HTML omitted --&gt;
&amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/639247547307986947&#34;&gt;2015-09-03 Tweet #2&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;http://www.amazon.com/dp/0321278658/ref=cm_sw_r_tw_dp_UMaEwb1ZRMGT1&#34;&gt;&lt;em&gt;Extreme Programming Explained&lt;/em&gt;&lt;/a&gt; 書中列的 best practices 很多。有些與組織文化及流程息息相關，不見得一開始就能說服眾人採用。其中，我覺得最立竿見影的，與組織文化流程互斥最少的，就是這兩項：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ten-Minute Build&lt;/li&gt;
&lt;li&gt;Continuous Integration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;說來容易，做起來可也得花一番工夫。但這世界上，有些&lt;strong&gt;打地基&lt;/strong&gt;的事，不做，就像不會基本代數，就註定與微積分的境界絕緣。&lt;/p&gt;
&lt;p&gt;CI，就是幫助你打好地基，開啟另一扇窗的手法。&lt;/p&gt;
&lt;h2 id=&#34;打地基的切入點&#34;&gt;打地基的切入點&lt;/h2&gt;
&lt;p&gt;初入這個新國度的人，面對 &lt;a href=&#34;https://en.wikipedia.org/wiki/Agile_software_development&#34;&gt;Agile&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Continuous_integration&#34;&gt;CI&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Continuous_delivery&#34;&gt;CD&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/DevOps&#34;&gt;DevOps&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Scrum_%28software_development%29&#34;&gt;Scrum&lt;/a&gt;、&lt;a href=&#34;https://en.wikipedia.org/wiki/Test-driven_development&#34;&gt;TDD&lt;/a&gt;⋯⋯太多神奇咒語，容易一頭霧水，搞不清楚優先順序。&lt;/p&gt;
&lt;p&gt;我不認為有放諸四海皆準的萬靈丹特效藥。如果真的要挑出一項切入手法，就從 &lt;a href=&#34;https://en.wikipedia.org/wiki/Continuous_integration&#34;&gt;CI&lt;/a&gt; 開始吧。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Continuous_integration&#34;&gt;CI (continuous integration)&lt;/a&gt;，是一條不會過度陷入工具至上的 &amp;ldquo;&lt;a href=&#34;https://en.wikipedia.org/wiki/Cargo_cult&#34;&gt;cargo cult&lt;/a&gt;&amp;rdquo; 迷思，又能從某些角度有效撼動既有的流程制度。難怪梅姐 (Marissa Mayer) 會選擇用這條角度切入：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「沒有持續交付 (Continuous Delivery)，專案不得上線，我不是在說笑。」Yahoo 執行長 Marissa Mayer 的宣言。&lt;br&gt;
&amp;mdash; Quote: &lt;a href=&#34;http://www.ithome.com.tw/news/99283&#34;&gt;【誰說大象不能實現 DevOps】雅虎 97% 專案擁抱持續交付的關鍵&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;CI，不管你選用的是當紅的自架工具 &lt;a href=&#34;https://jenkins.io/&#34;&gt;Jenkins&lt;/a&gt;，或託管給 &lt;a href=&#34;https://travis-ci.org/&#34;&gt;Travis CI&lt;/a&gt;（OSS 專案可免費使用），重點是：請踏出第一步。&lt;/p&gt;
&lt;p&gt;這不只是行動的第一步，也是照妖鏡、試金石。&lt;/p&gt;
&lt;p&gt;初步嘗試 CI，一定會踩到地雷；但你不是第一個踩雷的。我推薦過的好書《&lt;a href=&#34;http://www.books.com.tw/products/0010549884&#34;&gt;笑談軟體工程：敏捷開發法的逆襲&lt;/a&gt;》，就徹底討論過該議題了。摘錄一段當時的推薦文：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;作者感慨：「在臺灣很多試圖採用敏捷方法但卻槓龜的團隊，缺少『&lt;strong&gt;追求技術卓越&lt;/strong&gt;』的精神很有可能是一個主要的原因。」譬如說，如果沒有扎實的「自動化測試」及「持續整合」工夫，那麼，逐漸累積的「測試債」會讓 sprint 制度破功。當然啦，扎實的基本功並非一蹴可幾，作者也勉勵看過本書卻認為自己辦不到的人：「要『傻的願意相信書本裡所說的』，不要在尚未嘗試之前就先否定。」你願意開始嘗試嗎？&lt;br&gt;
&amp;mdash; Quote: &lt;a href=&#34;https://www.ithome.com.tw/tech/88496&#34;&gt;iThome 2012年 iT人必看的好書&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;手頭沒這本書的，不妨看看以下幾則文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://teddy-chen-tw.blogspot.tw/2011/03/ten-minute-build.html&#34;&gt;Ten-Minute Build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://teddy-chen-tw.blogspot.tw/2012/07/blog-post.html&#34;&gt;開發人員應遵循的七項持續整合要領&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://teddy-chen-tw.blogspot.tw/2012/07/blog-post_04.html&#34;&gt;持續整合工程師應遵循的十項要領（上）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://teddy-chen-tw.blogspot.tw/2012/07/blog-post_05.html&#34;&gt;持續整合工程師應遵循的十項要領（下）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不過，對「聰明人」來說，「&lt;strong&gt;傻得願意相信&lt;/strong&gt;」可能是頭一個要面對的關卡吧。&lt;/p&gt;
&lt;p&gt;能否面對該面對的關卡，決定你能否躍遷到更高的層次：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;CI/CD/DevOps 既是條不歸路，更是大躍進之路：一旦踏出第一步，就注定你會不斷接觸&lt;strong&gt;遠離平庸&lt;/strong&gt;的新觀點、新技術。&lt;/p&gt;
&lt;p&gt;至於背後是不是跑 agile，反而不那麼絕對了。&lt;/p&gt;
&lt;p&gt;屢屢從自己與別人演講、教育訓練、Q&amp;amp;A 中歸納出來的心法……&lt;br&gt;
&amp;mdash; Quote: &lt;a href=&#34;https://twitter.com/william_yeh/status/678524911351029760&#34;&gt;2015-12-21 Tweet&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;再強調一次：&lt;strong&gt;一旦踏出第一步，就注定你會不斷接觸「遠離平庸」的新觀點、新技術。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;所以，為了呼應剛剛的感想，在新梯次的 &lt;a href=&#34;http://get.soft-arch.net/ansible&#34;&gt;Ansible Workshop&lt;/a&gt;，乾脆帶大家用 Travis CI + Docker 玩一下 CI/CD 好了。因為從今年五個梯次 &lt;a href=&#34;https://github.com/William-Yeh/docker-workshop&#34;&gt;Docker Workshop&lt;/a&gt; 的經驗看來，滿意度最高的實作任務，一直都是 GitHub → Docker Hub 這一段 CI 動線⋯⋯&lt;/p&gt;
</description>
      
    </item>
    
    <item>
      <title>升級成大人版的思維作業系統</title>
      <link>//william-yeh.net/post/2015/09/upgrade-adult-thinking/</link>
      <pubDate>Tue, 15 Sep 2015 23:02:00 +0800</pubDate>
      
      <guid>//william-yeh.net/post/2015/09/upgrade-adult-thinking/</guid>
      
        <description>&lt;p&gt;兩個週末【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/28&#34;&gt;A101 職場人際關係與優勢策略工作坊&lt;/a&gt;】，一枚價值 14 PDU 的結業證書。雖然對沒有 PMP 證照企圖的我來說，帳面數字沒什麼用處；但獲得的，絕對遠遠超過這 14 PDU。&lt;/p&gt;
&lt;p&gt;用 14 PDU 換來 Bryan 積蓄 15 年的內功，還有什麼更划算的事情呢？&lt;/p&gt;

&lt;link rel=&#34;stylesheet&#34; href=&#34;//william-yeh.net/css/hugo-easy-gallery.css&#34; /&gt;
&lt;div class=&#34;box&#34;&gt;
&lt;figure  itemprop=&#34;associatedMedia&#34;
  itemscope itemtype=&#34;http://schema.org/ImageObject&#34; 
  style=&#34;max-width:30em&#34; &gt;
    &lt;div class=&#34;img&#34;&gt;
      &lt;img itemprop=&#34;thumbnail&#34; src=&#34;//william-yeh.net/img/2015/09/a101-certificate.jpg&#34; alt=&#34;A101 講義與結業證書&#34;/&gt;
    &lt;/div&gt;
    &lt;a href=&#34;//william-yeh.net/img/2015/09/a101-certificate.jpg&#34; itemprop=&#34;contentUrl&#34;&gt;&lt;/a&gt;
      &lt;figcaption&gt;
          &lt;p&gt;A101 講義與結業證書&lt;/p&gt;
      &lt;/figcaption&gt;
  &lt;/figure&gt;
&lt;/div&gt;

&lt;h2 id=&#34;上課也會上癮&#34;&gt;上課也會上癮&lt;/h2&gt;
&lt;p&gt;繼六月底【&lt;a href=&#34;https://shop.darencademy.com/product/view/id/57&#34;&gt;大人學講座 03：尋找天賦與熱情的系統化做法&lt;/a&gt;】之後，這是我第二次上姚詩豪 (Bryan) 的【&lt;a href=&#34;https://shop.darencademy.com/&#34;&gt;大人學&lt;/a&gt;】系列。&lt;/p&gt;
&lt;p&gt;Bryan 的演講或課程，承襲老本行「專案管理」的理性風格，就算主題再軟性，也一直都有「系統化做法」這五字訣。敢喊出「系統化做法」，就知道這不是洗腦催眠精神勝利喊話的&lt;del&gt;愚民&lt;/del&gt;激勵路線，而是不打高空、硬碰硬的真功夫。&lt;/p&gt;
&lt;h2 id=&#34;案例如人生倒帶&#34;&gt;案例如人生倒帶&lt;/h2&gt;
&lt;p&gt;課堂上，拿「人際網路圖」、「同理心地圖」、「TOC 衝突圖」這些硬底子的分析工具，運用在六個真實的職場情境上。與小組討論，聽老師闡釋，突然覺得以前被整得很慘的 PMP 模擬題，尤其是「利害關係人管理」，背後其實都真的有意義，也慶幸以前沒有白費精力搞那些東西。&lt;/p&gt;
&lt;p&gt;謝謝 Bryan 這麼精彩且血淋淋的真實案例，讓我回想起當年誤入(?)某單位，欠缺大機構人際溝通敏感度的自己，被推上火坑，被當做兩陣營派系惡鬥的炮灰，做填充工作，還自以為是做核心任務。真是「苦主」無誤呀！&lt;/p&gt;
&lt;p&gt;如果能夠重來一次，這次，我應該會做得更圓融。&lt;/p&gt;
&lt;h2 id=&#34;局與勢&#34;&gt;局與勢&lt;/h2&gt;
&lt;p&gt;案例有特定時空背景，分析工具也是現實狀況的簡化，兩者都有局限；重點是，要藉此培養出對於「局」與「勢」的判斷力。&lt;/p&gt;
&lt;p&gt;從『&lt;a href=&#34;https://www.darencademy.com/article/view/id/16127&#34;&gt;搞懂「考試」這個「局」&lt;/a&gt;』開始，「局」就如影隨行。不認識「局」，並不代表不存在；刻意忽略「局」，也不代表自己就能灑脫地「跳出三界外，不在五行中」。&lt;/p&gt;
&lt;p&gt;Bryan 箴言：「只會抱怨『鬼島』的人，是對『自己無能』的一種吶喊。」&lt;/p&gt;
&lt;p&gt;課堂上每聽到局與勢這兩個字，總不禁聯想到劉必榮、嚴定暹、劉墉等人的著作。我想，藉由 Bryan 所教的這些系統化做法，再回頭看那些更險惡詭譎的事，應該更能體會「局」與「勢」的奧妙。&lt;/p&gt;
&lt;h2 id=&#34;後遺症&#34;&gt;後遺症&lt;/h2&gt;
&lt;p&gt;上了一些補血課，後遺症是，自己好像撐破乾坤一氣袋的張無忌，「只覺體內真氣流轉，似乎積蓄著無窮無盡的力氣，可是偏偏使不出來，就似滿江洪水給一條長堤攔住了，無法宣洩。」&lt;/p&gt;
&lt;p&gt;我需要小昭幫我秀出羊皮上的乾坤大挪移心法⋯⋯&lt;/p&gt;


&lt;div class=&#34;notice notice--note&#34;&gt;
  &lt;div class=&#34;notice__title&#34;&gt;
    
      續集
    
  &lt;/div&gt;
  &lt;div class=&#34;notice__content&#34;&gt;&lt;p&gt;▷ 九個月後的回訓心得：【&lt;a href=&#34;//william-yeh.net/post/2016/06/upgrade-adult-thinking-part2/&#34;&gt;轉大人，Part 2&lt;/a&gt;】&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      
    </item>
    
  </channel>
</rss>
