Monday, February 24, 2014

《軟體測試專案實作:技術、流程與管理》筆記

《軟體測試專案實作:技術、流程與管理》筆記

一、軟體實作方法論

1.測試的策略:

(1)靜態測試:不測試程式本身,而直接尋找程式中可能存在的缺陷評估程式碼品質的行為。主要是在單元測試行為中,對技術、設計文件進行評核,程式無法執行或需要對原始程式進行規範符合性檢查時該使用這種策略。

(2)動態測試運作被測程式,輸入測試資料,檢查運作結果與預期結果的差異,從而判斷系統中是否存在缺陷的過程。


2.動態測試的測試技術:

(1)黑箱測試:測試人員完全不考慮程式內部的邏輯結構和內部特性,只依據程式的需求規格說明書,檢查程式的功能是否符合它的功能性說明的測試方法。主要是在系統測試階段時採用。

(2)白箱測試:使用被測程式內部如何工作的資訊,允許測試人員對程式內部邏輯結構及有關資訊來設計和選擇測試案例,對程式的邏輯路徑進行測試。其測試基於覆蓋全部程式碼、分枝、路徑、條件。

(3)灰箱測試:基於被測試程式邏輯結構的基礎上,從系統功能介面上設計測試案例。通常是作為黑箱測試的補充或在黑箱發現缺陷以後,回到原始程式碼分析原因確認問題時採用。


3.測試的階段:

(1)單元測試:為最小單位的測試。在單元測試行為中,各獨立單元模組在與系統其他模組隔離的情況下進行測試,檢查每個程式模組是否實現了規定的功能。

(2)整合測試:是在單元測試的基礎上將已經通過測試的單元模組按照設計要求組裝成系統或子系統進行測試的活動。測試著重在各模組、各子系統之間介面上的缺陷。

(3)系統測試:透過整合測試的軟體,同其運作環境、資料和使用者結合在一起,在實際或模擬實際環境下,對系統進行全面的測試。目的在於通過與系統需求規格書進行比較,發現軟體與系統定義不符合的地方。

(4)驗收測試:為最後一個測試行為。它是以使用者為主的測試,由使用者設計測試案例,使用實際資料進行測試。


4.測試的方法:

(1)功能測試:檢查軟體的功能是否符合規格說明書上的需求。

(2)效能測試:檢察系統是否實現了規定的效能指標要求。


5.測試的實施組織劃分:

(1)開發者測試(α 測試):開發者透過檢測和提供客觀證據,證實軟體的實現是否滿足規定的需求。主要是在系統交付給第三方測試或驗收測試之前進行的活動。

(2)使用者測試(β 測試):在使用者的應用環境下,透過使用檢測軟體來驗證是否符合自己預期的需求。

(3)第三方測試(外包測試):軟體發展方和使用者方之間的測試團隊進行的測試行為。


6.測試的其他概念:

(1)人工測試:由測試人員來執行測試案例,然後根據實際的結果和預期的結果進行比較,並記錄測試結果。

(2)自動化測試:透過重播錄製或編寫的自動化腳本,驅動系統運行的測試行為。

(3)回歸測試:軟體在修改以後再次運作之前,為尋找錯誤而執行程式曾用過的測試案例,以測試缺陷是否再次出現的行為。

(4)煙霧測試:軟體版本交付後,對其重要的部分先進行大概的測試,檢查主要功能是否正確,再進行後面的測試。


7.軟體測試模型請參考「软件测试过程管理实践 」




二、軟體品質和缺陷報告

1.規範需求需包括:

(1)使用者可能認為我們理解或遺漏的。

(2)行業規範。

(3)電腦領域的規範和習慣。

(4)客戶對電腦技術的限制。


2.外部品質與內部品質模型的六種屬性:

(1)功能性:

  • 適合
  • 準確
  • 互動
  • 保密安全
  • 功能依從

(2)可靠性:

  • 成熟
  • 容錯
  • 易回復
  • 可靠依從

(3)易用性

  • 吸引
  • 易學
  • 易理解
  • 易操作
  • 易用依從

(4)效率性:

  • 時間特性
  • 資源利用
  • 效率依從

(5)維護性:

  • 穩定
  • 易分析
  • 易改變
  • 易測試
  • 維護依從

(6)可攜性:

  • 適用
  • 相容
  • 易安裝
  • 易替換
  • 可攜依從


3.使用者品質模型的四種屬性:

(1)有效性

(2)生產率

(3)安全性

(4)滿意度


4.缺陷報告應填寫的元素:

(1)缺陷摘要

(2)缺陷所在的子系統(模組)

(3)缺陷位置

(4)缺陷類型、原因

(5)缺陷狀態

(6)詳細描述

(7)嚴重程度

(8)緊急程度

(9)附件

(10)發現行為

(11)發現途徑

(12)測試案例編號

(13)提交的版本

(14)提交的循環週期

(15)提交日期


5.缺陷處理後要填寫的三項資訊:

(1)修復的版本

(2)修復人

(3)拒絕者


6.缺陷的六種狀態:

(1)New:預設值,測試工程師填寫一個新缺陷報告時。

(2)Open測試團隊組長對缺陷進行審查後,將缺陷狀態從「New」改為「Open」,並在一定的時間內指派給對應的開發工程師。

(3)Fixed:當缺陷被修復並通過了驗證測試,開發工程師將缺陷狀態從「Open」改為「Fixed」。

(4)Pending:當缺陷由於各種原因無法修復時,開發工程師專案經理將缺陷狀態從「Open」改為「Pending」。處在此狀態的缺陷將等待條件具備時再進行修復。

(5)Closed:當缺陷在一個新建版本中完成了驗證測試時,測試工程師將狀態從「Fixed」改為「Closed」。

(6)Reopen:當缺陷驗證失敗時,測試工程師會將狀態從「Fixed」改為「Reopen」。當以前已經關閉的缺陷又在測試過程中出現時,測試工程師會將狀態從「Closed」改為「Reopen」。




三、文件審查和測試需求分析

1.業務規格需求說明書為整個軟體生產活動的依據,其審查項目包括:

(1)個業務功能和效能指標的描述是否清晰、明確。

(2)同需求描述之間是否存在矛盾和衝突。

(3)業務功能描述是否有遺漏。

(4)業務需求是否可以測量。

(5)業務功能描述是否會和行業規則、企業規範;國家法律規範、政策等發生衝突。

(6)需求中計算公式是否明確,公式中各因數是否明確。

(7)計算是否有精度要求。

(8)多角色和多使用者的系統角色、權限等是否合適。

(9)其引用的文件中是否正確且文件中是否有相應敘述。


2.概要設計文件為描述功能設計、資料結構、資料目錄、效能指標等的文件,其審查項目包括:

(1)設計是否涵蓋了業務需求。

(2)功能模組設計和內外介面之間的資料交換是否明確。

(3)資料結構或類別圖設計是否明確。

(4)資藥庫邏輯結構和物理結構設計描述是否正確,有無遺漏。

(5)應用邏輯設計、網路設計、安全設計是否正確。


3.安裝部署文件為描述系統的部署,其審查項目包括:

(1)文件閱讀者為維護人員,所以要注意技術描述而非業務描述。

(2)開發團隊使用的一些術語或縮寫詞語要有解釋說明。

(3)部署中的硬體設備要與上線設備一致。

(4)部署應用系統所需要的作業系統、支援軟體等要確定的版本要求和配置參數要求。

(5)文件中的截圖要與系統實際上線環境中的系統介面、操作一致。

(6)有條件時應該對照部署手冊進行實際部署測試。


4.使用者手冊為產品最終的規範,其審查項目包括:

(1)按照手冊描述的操作步驟來操作程式。要確認手冊中的描述是正確的,不要出現導致使用者錯誤操作的情況。

(2)手冊中的建議操作應做重點驗證。建議應該是使用者選擇的操作,所以要按步驟去驗證使用者依照建議所做的操作,測試人員應嘗試更多的可能性。

(3)檢查每條陳述。測試人員需要對每條陳述進行檢查。

(4)檢查圖表、截圖是否與發佈的版本一致。

(5)對業務術語和縮寫詞要進行必要的解釋。使用者手冊中不應該出現閱讀者可能不熟悉的專業術語和縮寫詞。

(6)像使用者一樣使用樣例和示例,按步驟去驗證每個樣例或示例。

(7)尋找容易誤導使用者的內容。應盡早標示出如意被人誤解的內容。


5.系統功能測試需求的六大分類:

(1)業務功能測試需求。

(2) 可靠性測試需求。

(3)安全性測試需求。

(4)易用性測試需求。

(5)可攜性測試需求。

(6)可維護性測試需求。


6.測試工作的依據首先是業務需求規格說明書,所以首先應該把需求從中提取出來,再把業務需求分解為測試需求,每個業務需求對應一條或多條測試需求。




四、測試設計

1.測試案例是為了驗證受測系統的某一品質子屬性而設計的。共有四個基本要素:

(1)案例描述:測試的目的和預期的結果。

(2)測試資料:執行測試案例時所載入的輸入資料。

(3)執行步驟:測試案例執行時所要進行的操作佇列。

(4)預期結果:測試案例執行完後所期望系統提供的結果。


2.測試案例的設計方法-等價類劃分:

等價劃分是把系統某個輸入資料集合劃分成若干部分,然後從每個部份中選取少數代表性資料作為測試案例的輸入。

步驟:

(1)為每個等價類別限定一個唯一的編號。

(2)設計一個新的測試案例,使其盡可能多地覆蓋尚未覆蓋的有效等價類(對於程式的規格說明書來說是合理的、有意義的輸入資料構成的集合)。重複這一步,最後使得所有有效等價類均被測試案例所覆蓋。
(3)設計一個小的測試案例,使其只覆蓋一個無效等價類(對於程式的規格說明書來說是不合理的、無意義的輸入資料構成的集合)。重複這一步,使所有無效等價類均被覆蓋。

3.測試設計階段的工作包括:

(1)把測試需求轉化為測試案例。

(2)補充完善的測試需求。

(3) 完善的測試策略。

(4)測試條件、設備、環境的準備。




五、做好專案測試計劃

1.測試計畫包含的要素:

(1)測試目標和範圍。

(2)測試資源。

(3)進度計畫。

(4)測試約束條件。

(5)測試循環週期。

(6)測試策略。

(7)專案風險。

(8)測試約定。


2.進行測試策略的三步驟:

(1)確定測試需求。

(2)評估專案風險並確定測試優先順序。

(3)確定測試策略。




六、單元測試及結果測試

1.語法涵蓋:設計若干測試案例,執行受測程式,使得每一條可執行語法至少被執行一次。


2.判定(分支)覆蓋:設計若干測試案例,執行受測程式,使程式中每個判斷的邏輯為真和邏輯為假至少被執行一次。


3.條件覆蓋:設計足夠多的測試案例,執行受測程式,使程式中判斷的每個條件的每個可能取值至少被執行一次。


4.判定-條件覆蓋:設計足夠多的測試案例,執行受測程式,使程式中判斷的每個條件的每個可能取值至少執行一次,並且每個可能的判斷結果也至少被執行一次。


5.條件組合測試:設計足夠多的測試案例,執行受測程式,使程式中每個判斷的所有可能的條件取值組合至少被執行一次。


6.路徑測試:設計足夠多的測試案例,覆蓋受測物件中的所有可能路徑


7.單元測試的步驟:

(1)計畫:確定測試需求,制定測試策略,確定測試所用資源,建立測試任務的時間表。

(2)設計:設計單元測試模型,制定測試方案,制定具體的測試案例,建立可再使用的測試腳本。

(3)執行:執行測試案例,對單元模組進行測試,驗證測試的結果並記錄測試過程中出現的缺陷。

(4)評審:對單元測試的結果進行評審。主要進行測試完備性評估。




七、產品整合測試

1.產品整合測試的重點:

(1)在把各個模組 / 子系統連接起來的時候,跨模組介面的資料是否會遺失。

(2)一個功能模組 /子系統是否會對另一個功能 / 子系統模組產生不利的影響。

(3)各個子功能 / 子系統模組累加起來,是否能達到預期的功能。

(4)全域資料結構是否有問題。

(5)單個模組的誤差是否會累加放大到不能接受的程度。


2.煙霧測試的重點:

(1)整個系統是否會實現全部主要功能。如果沒有實現,這些未實現的功能是否會給系統其他部分造成很大的影響。

(2)著重已經實現功能的品質,透過簡單執行主要業務流程,分析功能完成品質。

(3)看看是否有具體的實現,而不要被系統功能功能表和視窗所迷惑。


3.整合測試流程:

(1)測試計畫:確認測試物件、範圍,分析測試需求,測試策略、方法和出、允入準則,估算工作量,估算所需資源。

(2)測試設計:設計測試案例、測試資料、測試環境部署等。

(3) 測試執行:執行案例,記錄測試過程日誌,提交缺陷並追蹤缺陷處理流程,測試案例維護。

(4)測試總結:發現評估整合測試、測試報告。


4.整合測試設計需考量的要點:

(1)考慮支援本系統執行而需要的測試環境及測試環境與生產環境的差別。

(2)測試案例的執行策略。

(3)測試案例運行需要的外部條件。


5.整合測試報告應包括的內容:

(1)測試案例執行情況分析。

(2)整合測試需求符合程度分析。

(3)缺陷分析。

(4) 測試過程分析。




八、專案功能測試

1.專案經理在功能測試執行之前的準備工作:

(1)完成對功能測試計畫的評審。

(2)完成對功能測試案例的評審。

(3)測試環境建置完成,且通過審查。

(4)功能測試需要的測試資料和結果記錄形式準備完成。

(5) 系統中的參數配置等已準備好。




九、專案效能測試

1.測試允入準則:

(1)效能測試計畫撰寫完成,且通過評審。

(2)與業務人員溝通,選擇常見交易和混和業務比例。

(3)整個系統功能趨於穩定。

(4)測試環境搭建完成,且通過驗收。

(5)測試環境應用部署完成,並驗證可用性。

(6)效能測試腳本和測試資料準備結束。

(7) 預期效能指標確定。


2.測試允出準則:

(1)校能測試完成,系統達到效能測試指標。

(2)校能測試完成,若未達到效能測試指標,則返回最佳化處理。

(3)滿足上述兩個條件之一,且系統效能報告評審通過,則退出效能測試。




十、客戶驗收測試和測試報告評核

1.測試報告的內容:

(1)目的。

(2)測試環境。

(3)測試實際進度和計畫進度對比。

(4)測試版本。

(5)測試結果。

(6)落差分析。

(7)測試有效性分析。

(8)輸入文件。

(9)遺留缺陷分析。

(10) 缺陷清單。


2.撰寫測試報告的注意事項:

(1)在測試報告的文字中只是描述問題、事情或過程等,不要出現帶有明顯感情色彩的字眼。

(2)提供明確的資訊,而不要出現不確定的詞語。

(3) 測試報告的每一個資料都要有測試結果進行驗證,且是經過多次測試驗證的資料,是經得起推敲的資料,不同地方的資料要一致。




十二、測試專案管理

1.專案工作量評估模型-專案經驗模擬法

根據公司以前所作的類似專案,所累積的經驗或歷史資料來估算工作量。

步驟:

(1)在公司的知識庫中搜索類似的專案,獲得類似專案的資訊。

(2)把目前專案與類似專案進行比較,找出差異性。

(3)對差異性進行分析,找出目前專案的特點。

(4)對目前專案進行評估。

(5)最後統計出總體工作量,請相關的主管、專案經理、測試專家參與討論,確定最後的工作量。


2.專案工作量評估模型-WBS估算法

將專案或產品分解為實際的工作,然後分別對各個工作進行時間估算,最終求和統計得出專案或產品的測試工作量。


單元測試的步驟:

(1)如果有系統詳細設計說明書,則依據詳細說明書中劃分的模組來計算劃分的單元模組數量﹔若沒有該文件,確定是否可透過其他文件估算單元模組的數量。

(2) 確定單元測試審核中每個活動的工作量。


產品整合測試的步驟:

(1)把整個系統分解成子系統,確定每個子系統的介面數量。

(2)對每兩個子系統之間含有介面的子系統進行評估,需要建構多少測試案例覆蓋介面,也要考慮介面之間的測試方案。

(3) 需要考慮整個整合測試所用的工作量。


系統功能測試的步驟:

(1)把整個系統中的各子系統分解成需求點 / 功能點,在各功能點上確定運算元素,確定功能點的劃分密度。

(2)統計出所有的需求點為整個系統中的功能需求總數,再考慮測試中實際方案的工作量,是否考慮自動化測試、是否需要建構大量基礎資料等。

(3)需要考慮整個系統功能測試所用的工作量。


系統效能測試的步驟:

(1)把整個系統中的效能需求點整理出來,包括功能測試之外的所有測試行為。

(2)評估每個效能點需要的工時,形成整個系統效能測試的總工時。


3.專案工作量評估模型-Delphi 法

要求有多種相關經驗的人參與,互相說服對方。

(1)專案協調人和各測試專家和專案經理介紹專案規格和估計表格。

(2)專案協調人召集小組會,各測試專家和專案經理討論與規模相關的因素。

(3)各測試專家匿名填寫迭代表格。

(4)專案協調人整理出一個估計總結,以迭代表格的形式送回給測試專家。

(5)專案協調人召集小組會,討論較大的估計差異。

(6)測試專家複查估計總結,並在迭代表格上提交另一個不記名估計。

(7)重複步驟4~6,直到達到一個最低和最高估計基本一致。

Reference:
http://w1a2d3s4q5e6.blogspot.ca/2012/11/blog-post_7.html

Verification and Validation

LCamel 一提,發現英文的用詞很有趣,Verification and Validation 裡這麼解釋:

It is sometimes said that validation can be expressed by the query "Are you building the right thing?" and verification by "Are you building the thing right?" "Building the right thing" refers back to the user’s needs, while "building it right" checks that the specifications be correctly implemented by the system.

意即:

滿足需求 = validation = do the right thing.
驗證作法 = verification = do the thing right.
語言真是奇妙啊,用一句話來總結,就是「Are the do you right thing right?」

http://en.wikipedia.org/wiki/Verification_and_Validation
http://fcamel-fc.blogspot.tw/2009/09/blog-post_05.html

How to Think About the "new" Operator with Respect to Unit Testing

By Miško Hevery

  • Unit Testing as the name implies asks you to test a Class (Unit) in isolation.
  • If your code mixes Object Construction with Logic you will never be able to achieve isolation.
  • In order to unit-test you need to separate object graph construction from the application logic into two different classes
  • The end goal is to have either: classes with logic OR classes with “new” operators.

Unit-Testing as the name implies is testing of a Unit (most likely a Class) in isolation. Suppose you have a class House. In your JUnit test-case you simply instantiate the class House, set it to a particular state, call the method you want to test and then assert that the class’ final state is what you would expect. Simple stuff really…

class House {
  private boolean isLocked;

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    isLocked = true;
  }
}

If you look at House closely you will realize that this class is a leaf of your application. By leaf I mean that it is the end of the dependency graph, it does not reference any other classes. As such all leafs of any code base are easy to tests, because the dependency graph ends with the leaf. But testing classes which are not leafs can be a problem because we may not be able to instantiate the class in isolation.

class House {
  private final Kitchen kitchen = new Kitchen();
  private boolean isLocked;

  private boolean isLocked() {
    return isLocked;
  }

  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}

In this updated version of House it is not possible to instantiate House without the Kitchen. The reason for this is that the new operator of Kitchen is embedded within the House logic and there is nothing we can do in a test to prevent the Kitchen from getting instantiated. We say that we are mixing the concern of application instantiation with concern of application logic. In order to achieve true unit testing we need to instantiate real House with a fake Kitchen so that we can unit-test the House in isolation.

class House {
  private final Kitchen kitchen;
  private boolean isLocked;

  public House(Kitchen kitchen) {
    this.kitchen = kitchen;
  }

  private boolean isLocked() {
  return isLocked;
}

  private boolean lock() {
    kitchen.lock();
    isLocked = true;
  }
}

Notice how we have removed the new operator from the application logic. This makes testing easy. To test we simply new-up a real House and use a mocking framework to create a fake Kitchen. This way we can still test House in isolation even if it is not a leaf of an application graph.

But where have the new operators gone? Well, we need a factory object which is responsible for instantiating the whole object graph of the application. An example of what such an object may look like is below. Notice how all of the new operators from your applications migrate here.

class ApplicationBuilder {
  House build() {
    return new House(new Kitchen(
      new Sink(),
      new Dishwasher(),
      new Refrigerator())
    );
  }
}

As a result your main method simply asks the ApplicationBuilder to construct the object graph for you application and then fires of the application by calling a method which does work.

class Main {
  public static void main(String...args) {
    House house = new ApplicationBuilder().build();
    house.lock();
  }
}

Asking for your dependencies instead of constructing them withing the application logic is called "Dependency Injection" and is nothing new in the unit-testing world. But the reason why Dependency Injection is so important is that within unit-tests you want to test a small subset of your application. The requirement is that you can construct that small subset of the application independently of the whole system. If you mix application logic with graph construction (the new operator) unit-testing becomes impossible for anything but the leaf nodes in your application. Without Dependency Injection the only kind of testing you can do is scenario-testing, where you instantiate the whole application and than pretend to be the user in some automated way.

Reference:
http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/

detect file encoding and convert it to UTF-8

# file -i input.txt
input.txt: text/html; charset=unknown-8bit

# iconv -f unknown-8bit -t utf-8 input.txt > out.txt
iconv: iconv_open(utf-8, unknown-8bit): Invalid argument

# cd /usr/ports/converters/enca ; make install clean

# enca -L none input.txt
Universal transformation format 8 bits; UTF-8
Surrounded by/intermixed with non-text data

# iconv -f utf-8 -t utf-8 input.txt > out.txt

Sunday, February 23, 2014

Filesharing with chrooted SFTP

Live demo in BSD Now Episode 024.
So you've followed our SSH tutorial and now you're ready to hand out accounts to your friends, right? Well, there are times when you want to securely share files with them, but don't want them having shell access to your server. OpenSSH includes SFTP, the secure file transfer protocol, which provides both authentication and encryption. Normally, you need to give a user an SSH login for them to be able to transfer files via SFTP, but there’s also a useful option to disallow shell access and only let them transfer files. What's more, you can lock them to a certain directory so they can't browse your filesystem. This tutorial will show you how to do just that. I’m assuming you already have sshd configured and running.
Let's create a new user for them to use and edit the sshd_config file to chroot them.
# adduser

Username: gnub
Full name: Some Random GNUb
Uid (Leave empty for default):
Login group [gnub]:
Login group is gnub. Invite gnub into other groups? []:
Login class [default]:
Shell (sh csh tcsh bash rbash nologin) [sh]: nologin
Home directory [/home/gnub]:
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username   : gnub
Password   : *****
Full Name  : Some Random GNUb
Uid     : 1004
Class     :
Groups   : gnub
Home       : /home/gnub
Home Mode  :
Shell     : /usr/sbin/nologin
Locked   : no
OK? (yes/no): yes
adduser: INFO: Successfully added (gnub) to the user database.
Add another user? (yes/no): no
Goodbye!
Take note of the "nologin" shell - that's not the default. Next we edit the SSH configuration:
# vi /etc/ssh/sshd_config
Add something like this to the bottom:
Match User gnub
    ChrootDirectory %h
    PasswordAuthentication yes
    ForceCommand internal-sftp
    PermitTTY no
    X11Forwarding no
    AllowTcpForwarding no
    AllowAgentForwarding no
Restart the daemon.
# /etc/rc.d/sshd restart
Next, we set some permissions and make a directory for them to actually put files in.
# chown root:gnub /home/gnub
# mkdir /home/gnub/files
# chown gnub:gnub /home/gnub/files
Now you can give your friend the SFTP login and they will be locked in the home directory, but able to upload and download things to and from the "files" directory. If they try to login via SSH to get a shell, they should get the error:
This service allows sftp connections only.
Too bad for them.
Originally written by TJ for bsdnow.tv | Last updated: 2014/02/12

Reference:
http://www.bsdnow.tv/tutorials/chroot-sftp

給尚未大學畢業的朋友的幾個人生建議 - 能力培養篇


前天,應母校 文化大學應用數學系 的邀請,再次回系演講關於大學後的職涯規劃。這已經是第二次受邀演講相同的主題。受邀的原因相當單純。純粹是我的表現一再的讓系上老師跌破眼鏡,在短短數年間一路從不起眼的小職員,迅速累積出社會普世價值觀上相對可觀的成就。( T客邦技術部經理、HTC 資深經理、Facebook World Hack Grand Prize…etc.) 所以老師們想邀請我回校演講。分享我在這一路上成長的感想,並給予學弟妹人生建議,回答對於對於將來路上的一些疑惑。
會後的問題,我一路上其實在各大場合都答過類似的問題。內心對於大學生缺乏適當明燈指引,相當感慨。有些問題我想甚至可能只有我這樣的經歷的人,才可能答的出來。這些建議我覺得若只限於在校學弟妹才能聽到,相當可惜。所以趁記憶猶新,把它整理出來。
當然,這只是基於我的人生經歷,做出來的建議。並非絕對,還請讀者自行判斷斟酌。

最值得投資的技能

1. 中文速讀

我最常被問到的問題其中有一個是:「你覺得出社會前你練過最值得的技能是什麼?」對於這個問題,我的答案毫不猶豫的會是「中文速讀」。
為什麼是「中文速讀」?坦白說,在小時候會選擇投資這個技能,原因純粹是 (1) 被逼 (2) 我有天份 (3) 可以在短時間看完一堆雜文小說很爽。
18 歲前,「速讀」這個技能對我來說,是可有可無的雞肋。但是在 18 歲以後,遇上網際網路的高速成長,整個世界呈現一個「資訊爆炸」的狀態。原先的雞肋技能,搖身一變成為我一路上闖蕩的最厲害武器。
原本我個人學習的速度,還被大大牽制在老家附近的書店販售書種的數量。因為網際網路的爆炸性成長,我的閱讀視野一下子被拉到網際網路的邊界。而高速的閱讀速度,即便在資訊爆炸的今天,我還是能夠只花上極少時間,就能夠輕鬆追完今日關注 timeline 上的大小事…
工作上遇到任何疑難雜症,也能透過閱讀速度以及網際網路,快速的整理出相對應的解決方案。
如果時間只能投資在一個專業技能上,我毫不猶豫會推薦你選擇「中文速讀」。

2. 英文能力

其次,我推薦練習的技能就是「英文能力」。每當學弟妹聽到我這樣說,無不哀號遍野,瞬間卻步。
其實,學弟妹不知道的是:所謂的「英文能力」真的非常非常重要。重要到超乎你想像。我出社會到現在的感想是,「英文能力」的重要性也遠超乎我當年的想像。
不只是所謂好的工作需要英文(外商工作需要聽說讀寫)。甚至是幫助你高速成長,超車過同儕的專業知識也通通都是英文 (如同我現在賴以為生的專業技能: Ruby on Rails )。就別說這麼專業的進階知識好了。
就連外國的許多線上初階自助學習課程:CodeSchoolCodecademy。也都是英文教材。
其實台灣不乏素質高的軟體人才、學生。其實只要正確的導引,具備適當的教材與練習,成果往往能突破目前國民教育造成的限制。唯一可惜的是,大家往往只要聽到「是英文的」,下意識就刪掉這個選項。我一直覺得這是一件可惜的事。
很多學弟妹也許會期待,將來這些東西有天會有好心人出中文版。就我的觀察,這個機會可能是越來越小。目前的現實是:這個世界呈現高速成長中,能夠翻譯這些知識的人,往往也是能夠少數能夠突破天際線以及國際限制的人。他們目前的聚焦,無不是專注在自身能力與事業的突破。很少能夠還有資源和時間能夠停下來拉別人…
於是造成了一個極端的現象:強者越強,弱者越弱。甚至就算強者有心停下來救別人,有時候往往也不知道怎救起…
大家對於「英文學習」的盲點,在於英文學習很枯燥,無法靜下心來投資一個「不知道有什麼報酬率」的知識。
其實各位可能不知道的是:在大學之前,我的英文能力也非常非常的弱,每次段考都只有 30 分。但是我現在的英文能力,卻能讀聽能說能寫(哈,抱歉,有時候 blog 還是一堆 typo 錯字)。跟外國人順暢的聊天和工作的能力我應該還算是不錯的。
如今我具備的所有專業知識與能力,甚至是得到的機運,也全部都是因為英文賺進來的。
現在回頭看,英文練得起來的原因,只是因為我的一個單純的小嗜好:「看美劇」。其實把英文練好並沒有那麼難。我雖然不喜歡「嚴肅的學英文」,但卻非常喜歡看美劇(含字幕)。劇情精彩是我當初被深深吸引的一個原因,十年來我看過不下千集美劇。
習慣美國人講話的速度,是我進步的第一環。習慣了聽美國人講話,自然腔調與口語速度就會自然而然接近美國人。聽說能力就自然起來了。
因為不害怕英文,在需要大量接觸英文的程式開發專業環境下,就會完全不覺得英文是什麼可怕的門檻。很快的,自己就會習慣「太平洋其實並沒有加蓋」這件事。
能夠接觸到的機會,看到的世界,就不會被所謂的「台灣洗腦電視台」蓋台進入無窮迴圈。(其實我已經接近十年沒有在看台灣新聞與連續劇了…)
我認知到的一件現實是,現在全球已經進入非常扁平化而且快速變革的激烈變化中。如果國家國力本身夠強,還抵的住這種變化的衝擊。但是台灣,在經過這四年政府無作為且大量惡搞的狀況下,本地機會迅速的惡劣、變小、變少。
如果不能夠把自己變成全球需要的人才,將很快的被這波洪流吞噬。如果你的英文能力不好,勢必只能是被吞沒的那一群人…

3. 寫作能力與程式開發能力

其三,我認為值得投資的部分是:「寫作能力」或者是「程式開發能力」。
每當我一提到這兩件事,也是很多人馬上會皺起眉頭。
但我一路上走來的感想是:我很高興能夠同時都把這兩塊能力練得不錯。而且是這兩個能力,才把我帶到今天這條路上。
(也許你認為我能夠拿到 Grand Prize of Facebook World Hack,是個程式奇才,其實我可以很清楚的跟你說:我明白自己不是寫程式的料。
我真正有狂熱興趣的是寫作以及作產品。我小學立志當作家或歷史學家。成為一個厲害的 Developer 從來不在我念大學之前的志願選項。
我只是喜歡作網站,我被迫去學 coding,去學有關 coding 的 everything,然後莫名其妙的就被迫站在這個領域的前端… )
寫作能力與程式開發能力,帶給我的影響是:
  1. 寫作能極大化的強迫把我沒有章法的思緒收斂在一起,當累積到能夠把想法準確的寫下來,並重複的寫到讓人家明白。最大的受益人其實是我自己,我透過寫作梳理以及掌握了整件事的來龍去脈。能夠把事情精準的重複,才是弄懂整件事。透過不斷的寫作可以大大強化「把事情想清楚」這方面的能力。
  2. 程式開發也是類似的事。Knuth 曾經說過 「A person does not really understand something until after teaching it to a computer」。電腦並沒有很聰明,它只能執行絕對有邏輯的事情。換句話說:你在教電腦事情的時候,其實是在釐清自己的思考與整件事的邏輯。沒有邏輯的事,你又如何期待可以被 work 呢?
而培養寫作能力與程式開發能力,其實最大的好處不是培養出強大的邏輯核心能力群。而是產生出來的副產品:「文章」以及「程式碼」。
很多 Developer 常常怨歎,我也很有能力,為什麼沒有人要挖掘我?很簡單的道理,因為沒有人知道你作過什麼。沒有文章放在 Blog 上,沒有程式碼放在 Github 上,沒有可以實際端出的 project。光憑短短的幾分鐘面談,和洋洋灑灑履歷。誰能在這麼短的時間,知道你是不世出的曠世奇才呢?
如果你想要世界看到你,你必須要做的就是,主動站出來。

小結

現在的社會絕對不是爸媽從小告訴你的那樣:只要專注「上學唸書」,找份「穩定的工作」就能安穩一輩子的社會。相反地,這個社會正用以往沒有的速度,每半年每三個月就快速演化一次。
以具體的例子來說,就看看你身邊的電腦、平板、手機演化趨勢就知道了。2007 年之前有誰能預期到 Facebook 能夠演化成如此怪獸?
世界上的工作型態以及職務需求,也在這幾年間劇烈的變化。昨天在蔡依橙醫生的部落格上面看到這一段話:『至於台北,他們根本不想拿來比較。我們還在講古老的「四小龍」攀關係,人家已經在亞洲制霸的路上了。』
在台灣媒體的鎖國洗腦下,其實很多人不知道,台灣已完全從先進國家之林掉出去了。很多人以為選出馬英九,即使無能不做事,其實也不可能把國家害到多慘的境界。這真是大錯特錯,在 2007 年以前,台灣與世界的差距真的還沒有那麼大。2008 以後的這黃金四年,全世界都在往前衝,以每三個月一變的速度在進化,只有台灣還在原地沾沾自喜的原地踏步。四年過去了,我們國家以及人民的競爭力完全不知道掉到哪裡去。
我不是跑得很前面的人,我真的只是勉強跟著世界的速度一起跑而已。
很多學弟妹常直接希望我給他們一些將來就業方向上的建議,該選什麼學科好,該選什麼職業好。老實說,在這麼瞬息萬變的社會改變裡,我實在無法告訴大家,什麼職業絕對賺,絕對不會被淘汰。因為這種事已經很難繼續再被持續發生了。
但無論如何,至少我可以告訴大家,如何不被世界變化的速度甩開….我認為這三項核心能力是至關重要的。無論社會再怎麼變,至少你還可以靠這三個核心技能維持個人的競爭優勢。
  • 中文速讀
  • 英文能力
  • 寫作 / 程式能力
這一篇是關於「什麼技能建議學」。下一篇的主題我將談「什麼樣的決定不要作」。

Reference:
http://blog.xdite.net/posts/2012/10/23/some-advice-for-undergraduate

給尚未大學畢業的朋友的幾個人生建議 - 挑戰未來篇


上一篇中,我談到了三個能力是我建議培養的:「大量快速閱讀、外語交流、邏輯歸納推導」。接下來我想談談,我會勸你「什麼樣的決定不要作」。
這一篇我曾經思考了很久,我到底要不要認真的寫出來。(考量到文章刊登出來的批評聲浪)

最不值得做的事

1. 漫無目的的拿高等教育學位(大學、碩士)

台灣已經來到一個瘋狂的病態狀況。大學錄取率超過 100%。什麼人都能夠上大學。甚至大學招不滿人,還拜託對岸的大陸學生來念大學。
來念大學的人,往往也不知道自己來念大學的目的是什麼,只是因為爸媽叫自己來念,就來這裡放空四年等畢業。因為負擔不起學費,於是半工半讀,甚至多數學生整個大學生涯都在打工,唸書反倒是兼差而已。
在寫完上一篇文章的時候,有讀者發問:『私心希望加上「後悔以前沒有做什麼」的部分 XD 』
我必須要很認真的說,我最後悔的是:『後悔沒有拒絕我爸的願望:去念大學』。
別誤會,我並不是要說後悔曾經念過這間學校、後悔去念應用數學系。(甚至我這一輩子最感謝的就是當年被大學老師鞭策出來的極佳邏輯能力)
而是,早知道我喜歡的「作網站」這個職業。並不需要靠付高額的高等教育學費就能取得相關知識,並變成職業從業者。我不需要逃避那些我不喜歡修的課,修我根本沒興趣的學分,只為了取得學歷在等畢業。
因為甚至我翹課的時間,都是在宿舍玩架站或者是泡系上機房弄伺服器…
我可以早一點去就業,早一點為社會有貢獻。而不需要國家浪費在我身上的寶貴高等教育資源。最輝煌的四年時間被當年不懂事的我,浪費在「滿足我爸對我的表面期望」。
我爸真正的期望應該是希望我成為一個有用的人,不會餓死自己,對社會多少有貢獻。而不是去「拿一個大學學位」(取得一個大學學位是他『希望』的一種『表現形式』)。
這黃金的四年我浪費了很多時間在閉門造車,在揮霍人生,而不是真的認真的幹一些有意義的事業出來。
我的能量一直等到大學畢業後、終於不用躲躲藏藏的滿足別人對我的表面期望之後,才用力的迸發出來。如果可以,我希望我一開始就不用花時間在這件事情上。
而一直到出社會、甚至當主管以後,我才開始意識到全民盲目的拿高等學位這件事,對國家的競爭力是多麼可怕的傷害。很多人以為讀大學用的都是自己的錢,浪費學費也是自己家的事。事實上,完全不是這回事。不管是讀公立大學或者是私立大學,國家都花了非常多錢在你身上。每一個人讀大學的成本,其實並不是光光只有學費而已。事實上政府對每一間學校的大量補助,才讓你可以每學期以最多只繳五六萬的代價就取得學位。事實上若真要計算,一個學期正常的每人教育成本應該是幾十萬台幣…。
但是,這當中有多少比例的人真的渴望上大學唸書?恐怕真的很少。幾乎絕大多數的學生都把念大學當作是可以打電動郊遊的坐牢而已。國家投注四年心血,結果學生放空放四年。
這完全是巨大的實體資源(金錢)以及黃金的無形資源(年輕人的青春)浪費。但卻沒有人對這件事情提出質疑。
大家都覺得外國人都超厲害,十幾歲二十幾歲技術就都超強,做出超屌的網站,創上超級厲害的公司。為什麼台灣人沒辦法?
很簡單,因為台灣人的人生從 22 歲才開始…人家 15-18 歲就開始了…
很多人也害怕,如果沒有一個大學學歷會找不到好的工作,有不錯的薪水。我出社會、當上主管以後才知道企業選才的標準完全不是你念哪個大學畢業的。而是你專業技能的純熟度、你當年的可塑性(年紀)。(換句話說你越老,但技術越嫩,競爭力只會越來越弱。)
沒有一個好的大學、碩士學歷,也只會影響你「第一分工作」的起薪。「第一分工作」並不是人生的全部。「第一分工作」只是唯一一個人家願意容忍你犯超級愚蠢錯誤的地方。
把時間浪費在『坐學校牢』上,完全沒有意義。如果你有一件事超級有熱情,那麼你就應該現在去作。如果你想光宗耀祖,那麼你應該從現在開始。
爸媽不會跟你說這件事,而他們會認為我在傳邪道。

2. 不要去當研發替代役

我的不少朋友和同學都是男生。他們不少人選擇服替代役,而不是直接當兵。我可以跟大家說,他們剛錄取的時候第一年都很開心。然後,然後,然後他們就不會再跟你講後面的故事了…..
因為大家都很後悔。但是你聽不到這些後悔的聲音。
每當有大學生在 conference 或社群聚會攔住我,詢問我對於未來的建議規劃,每次聽到有人想去再念個碩士,念完個碩士想再去當個替代役…
我總會試著勸他打消這個念頭,因為我知道後面會發生什麼事。但是我永遠都擋不住,因為他們總會堵我一句:「替代役 pay 起薪比較高,而且三年有保障…」
我聽到這一句,我就不繼續再講下去了。因為再講下去,我又會看成是「邪道中人」了。
現在看來,經歷了這一段歲月之後,我會回頭認為,也許台灣的「科技替代役」制度,原本是為了保證科技業人才的來源,以及保護科技業人才不因為當兵一年之後退伍變白癡(後來我覺得這有點像是都市傳說,因為不少人上班後被操了一兩個月後,魂就回來了。)。
但後來某種程度上,我認為是把台灣優秀人才殺光光的一種可怕制度….
為什麼?首先是「研發替代役」的資格需要「碩士畢業」。
嗯。聽到「碩士畢業」,其實多半就是「放空….」。
放空兩年,接下來綁三年的研發替代役的生活。
為什麼綁三年替代役通常是開始後悔的起點?因為真實的狀況是,有辦法申請到研發替代役的公司,多半是已經相對有經濟規模的大型公司了。雖然他們有辦法給上「穩定」的 pay。但是通常役南們能拿到的也就是「穩定的工作內容」,沒有什麼特別性的機率拿到能夠開疆拓土的機會(逼自己成長)。穩定 pay 保證不低,但是幅度通常也跳不高。
其實出社會頭三年,是一個人很黃金的三年。因為第一年有人願意大幅負擔你學習犯錯的機會。接著第二年,你開始不再犯錯了,大致上可以開始摸出自己擅長什麼,適合往哪個方向走。第三年,開始有籌碼換上 pay 更好的工作。(而這個 pay,運氣好的話,甚至可以拿到比剛出社會高上 1.5 甚至 2 倍的數字)
而科技業的工作更現實,每三個月風向就換一次,每六個月技術就革命一次。甚至每年的黃金主題,都不一樣。
許多人會後悔。原因歸納不出以下幾個:
  • (1) 現在工作,三個月就不喜歡,但是他不能跑,於是之後 2 年 9 個月的日子,放空…
  • (2) 現在工作,做得算有點興趣。但是完全沒有向上向左向又突破的空間,只好放空…
  • (3) 外面有更好的機會,有超級好的 pay,跑不了。有被外國挖角的機會,也跑不了。放空…
你可以觀察到,最後的狀況幾乎都是放空…
放空完浪費了多少歲月呢?這樣一輪下來,通常都是 27,28 歲了… 這時候,他們才開始想找自己「真的有興趣的工作」。但,門檻這時候變得非常高…
我身處在這個火熱的軟體圈子,時不時的就會接到很多軟體獵頭信(國內外都有)。不少的 offer 都相當好,只是囿於時空背景,無法接受邀約。最後,他們也總會希望我推薦幾個優秀的人才,因為想進入台灣拓展分部,而他們都願意給的起非常非常好的 pay。
這不是偶爾才發生的特例,我一天到晚都在接到這種的詢問信…
但我卻總是只能愛莫能助。因為能夠介紹的優秀人才不是正在「替代役」,就是正在「念碩士班」準備「替代役」,或者是根本還沒當兵(年紀太小或太老正在閃兵役)。
而對方也沒辦法接受,收進來的工程師 27,28 歲技術還是很菜的 junior ….(因為這個年紀,在外國都應該要是 Senior Engineer 或 Architect 了)
矽谷蓬勃的軟體生態,在於優秀的人能夠在各個公司靈活流動,把各個公司優點有效的交互傳播。同時,因為沒有誰被簽約綁死的問題,所以人才可以不用浪費大量時間在放空等出獄,想換領域鍛鍊就換領域。三年的鍛鍊就變成架構師,根本不是不可能的事。
只要有天份,只要沒被綁死,幾年內都有機會鍛鍊出萬丈光芒。你也許說不是每個人都拿的到外國的好工作。第一年當然不太可能。但是第三年,誰能曉得會發生什麼事呢?
但是我們的社會觀念卻是,把流動視為不成熟。把綁架回來互相浪費看成保障。
你要怪世界進步的太快,我們追不上。怪政府無能,拖累國家競爭力。我卻認為是我們自己活生生憋死了自己。卻還在找替罪羊。

3. 不要自願關在一份你根本不喜歡做的工作,下班再找機會作喜歡的事

要是我能從出社會的幾年來,得到的最寶貴教訓,無非是這一課了。
千萬不要白天去作完全不喜歡而且沒熱情的工作(即使薪水看起來還不錯),晚上再用閒暇時間找機會作自己有熱情的事。
也許你聽過了很多,熱血車庫創業,下班努力扭轉人生的故事。想要努力自己說服自己你也可以…
我不想直接潑你冷水笑你這根本是在做夢。
直接來說說自己的故事好了。
我出社會之後頭兩年,也有這種美麗單純的幻想。當時也是選了一個我沒有太討厭沒有太喜歡,但上班時間規規矩矩做事。晚上可以有很多時間「偷玩」自己喜歡的東西(寫部落格、寫網站)的工作,而且最重要的,這個工作還是一份鐵飯碗…(半公家機關,符合我家對我的期望)。
直到兩年的某一天,碰上一個技術遠高於我卻大我沒幾歲的前輩。才意識到原來當初這種這種想法簡直是自 high,是在自毀長城。
人家每天上班八小時都在玩自己喜歡的東西。我每天下班還要努力擠才有兩小時可以進行業餘可笑的練習。不要說綻放光芒了,光是要追上他,我要努力到什麼牛年馬月 -_-?
那個禮拜過後我馬上就辭職了。
我還沒有時間馬上想清楚我未來要幹什麼。但我很清楚的知道一件事:再這樣繼續下去,很快我就會被我自己挖的洞埋掉。
一兩個禮拜以後我跑去找了一份我應該有興趣的工作開始幹,就是職業的網站工程師,
四年過去了…
四年過後我站在這裡。這一路上經歷過的事簡直遠超乎我的想像。我蓋出來的網站、我的部落格文章讀者不計其數。我經歷了很多各種好笑、感動的 event(你可以 google 到一大堆)。我透過網路,結交到了一大堆沒見過太多面,卻很交心的朋友。我在我這個年紀,玩到了超過正常人應該玩過的網站專案數量。在奇怪的年紀當上資深經理。在完全沒心理準備的情況下拿到世界賽首獎。
對一件事情有熱情真的是一件很可怕的事情。
我在這個奇妙的旅程中發現一件鐵律:有熱情的事情你才有動力把它做得好。而做得好,就很容易 生出成就感。而這個成就感又會激起你更大的熱情,把事情做得更加好。而一旦你把某件事情做得無人能敵,奇妙的機會就會自然從天上掉下來。
從前不知道怎麼敲門得到的機會。會在幾年後的某一天,以意想不到的方式掉在你面前。而因為身上的技術已經不再是僥倖。所以就算這個幸運可能是意外,也能夠牢牢的被抓在自己手中,不再溜走。
有些人總覺得我總是能得到的奇妙的幸運,或者是到底哪來的這麼無窮詭異的毅力在充實自己。我只能告訴你這是熱情。我喜歡作這件事不只是每天的 8 小時。我每天花的時間是 12 小時。甚至是週末還把這件事情當娛樂。
所謂「一萬小時的威力」並不只是個噱頭而已。他是真的會產生 something 的,而且這個 something 無窮巨大。
要是我當年選擇了繼續作這一份沒有溫度的工作。什麼事情都不會發生。因為我一輩子可能都只會是一個業餘工程師。只能繼續躲在角落酸別人,他是幸運他是幸運…
我不知道為什麼在台灣的大家都有一種奇怪的執念。要是經濟有虞就算了,無虞也要逼自己作自己不喜歡做的事情。再說服自己其實下班可以再擠時間偷做,然後這樣總有一天就有機會出頭。
我學到的唯一一件事,就是喜歡的事情就絕對不要當業餘。一個月的職業訓練,就足足幹掉三年的業餘偷練。而把一件事情做到真正好,上天會讓接下來的一切順理成章出現…
如果你只是為錢作一件你完全不喜歡做的事,相信我,你真的會每天活得就好像在地獄裡。而給你再多 pay 當補償還是一樣,因為下班為了發洩情緒,你還是會選擇把它狠狠花光。但相反地,要是你正在做的事情是喜歡的事,其實收多少 pay 你可能根本也不在意。而且,當你喜歡到能夠把這件事情做得非常好。那麼那個數字上天是不可能少給你的。

小結

這兩天寫了這麼多字下來。我發現我自己也遠遠寫超過了未畢業的大學生可能看得懂的範疇。但無論如何,我還是想把這些悶在心裡很久的話寫出來。
即便冒著被人罵邪道的危險。我試圖告訴大家,其實
  • (1) 可以不需要念大學
  • (2) 替代役可能不是幫你解套,而是有可能斷了你無限未來的一條路
  • (3) 熱情比什麼都重要
最起碼我想拿我自己來說,應該可以看起來應該是一個很難被挑骨頭的例子吧。我是一個普通家庭出來的普通小孩,大學念的也是大家看起來很普通的系(甚至可以被人說不好的學校)。而一直到 24 歲之前,我都按照著普通家庭對我的普通期望,過上一個非常普通的人生。
唯一的不同,就是我在 24 歲以後開始想清楚了,我不應該再為了滿足別人的表面期待去過我的人生,眼前可以走的路,也不是只有政府和爸媽所說的那幾條路而已。然後我就這麼出發了。
而我在這個旅途中,也看到現在世界是長什麼樣的。這也是為什麼我寫了 三個要學習的技能三件不要去做的事
(1)世界正在以越來越快的速度再演化。快到現在任何的國民教育完全跟不上的階段。從前必須要上高等教育才能修到的學分,現在都可以透過網路越來越容易的取得這些知識,甚至超越本國大學可以供應的範圍。而從正規大學取得的知識,從前在畢業後還可以保值個兩三年。現在可能還沒出校門口就直接過期了。
是不是要花上這個四年取得越來越被廉價化的學歷,坐上四年根本沒有人喜歡的大學牢,背上你潛意識裡面覺得根本不應該背的大學學貸。我覺得這是可以思考的事情。
(2) 我們爸媽的時代,跟我們身處的時代,其競爭以及變化的程度,完全不可同日而語。這十年間科技的變化程度大家也看到了。而這個速度只有可能更快,而不會更慢。所以是否真的有那個價值繼續依照爸媽陳舊的建議悶著頭走一條「放空的路」?
很多人總是說,台灣的人才素質很高,但卻很奇怪的沒有辦法在世界上綻放光芒。某種程度上,我認為就是因為我們長期以來雖然「聞」到世界正在劇烈的變化,卻還是悶著頭走著一條老早過期的路,但還是期望著會有一個比別的國家更好的結果。
我們社會繼續用著奇怪的迷思,把未來有希望的孩子,一一推進黑洞裡。(不用說推,很多人甚至根本是搶著自己跳進去。)幾年後發現不對了。才在電視政論上抱怨以及檢討為什麼高等教育廉價化,為什麼花了四年書只有 22k。為什麼我們的國民素質高,但是長期競爭力低落?
(3) 但隨著世界交流的門檻逐漸降低。取得國外的工作機會真的沒有那麼難。而且就以我身處的網路業來說,隨著全世界的軟體缺工潮,英文還可以的 Senior Developer 簡直人人都搶著要。
(我所在的這個圈子,美國矽谷挖美國其他州的人,美國挖加拿大的人,加拿大挖日本的人,日本人挖中國的人和台灣的人。大家到處互相挖來挖去。因為缺工…)
這世界機會簡直是太多了。完全不是只有「澳洲屠夫」才能真正賺得到錢。每當只要電視上報導,念完大學畢業,結果只能到別的國家「打工度假」賺錢當台勞(明明是國家培養的高級知識人才,卻選擇跑去用勞力賺錢)。我內心就真的只有「國家的教育資源又泡湯了」的感想…
學弟妹在我演講結束後,曾跑來問我,到底我們這個科系的學什麼技能才有求職競爭力。我給了他們一個他們沒有意料過的連結:Github Job board。而不是 104 …
多逛逛這裡,你就會知道練什麼技能是值得投資,而且也是大家需要的。
看世界,不要只看台灣。
我想我這兩篇文章,要說的可能從頭到尾就只有這九個字……
Reference:

寫給大學生的程式技能 Cheatsheets

昨天去參加 HappyDeisgner Mini #5 聽到 Caesar Chi 在講他跑校園傳道 (提倡 OpenSource)的故事,Caesar Chi 說他會這麼做是受到 Jserv 南下傳道的啟發。
為什麼要深入校園傳道。我想其中最大的問題是:大家都已經深刻發現了「校園的資訊教育」與「現行職場」、甚至與「國際技術圈」上的巨大差距。已經大到一個相當難以扭轉的狀態。其實,任何技術,在寫下來製成紙本教材並且搬到課堂的那一刻,就過時了。只是現在速度更快到,當你今年寫下來準備開課,明年這套技藝就已經有可能過時了。真的很難期待,從傳統學校傳授知識的過程中去介入什麼。
所以唯有提倡學生儘量跳脫只能在學校學習的思考框架。在線上學習( Online School )。多多參與接觸開源社群。
But, How?
在線上學習( Online School )。多多參與接觸開源社群。 對我們已經在工作的職業程式設計師,這個概念再簡單不過。但是我發現這對初學者來說,是一個很空泛的概念。他們其實更需需要的是一份 Guideline,有一個具體的方向去「自學」去把目標具體化。
(這份 Guideline 也是我回想若當初我剛出社會時,希望有人能給我的一份清單)
=== 分隔線 ===

Source Control

  • 理解什麼是「版本控制」,為什麼我們要使用「版本控制」
  • 學習 Git : http://try.github.io
    • git commit
    • git push
    • git pull
    • git branch
    • git checkout
    • git merge
  • 註冊 Github 帳號
  • 把自己的作業推上 Github
  • Fork 同學的作業,幫他修錯字,然後拉 pull-request
  • 卡關就上 Google 找 Stackoverflow 的答案

Do a "real" project

讀書跟做事不一樣。你不應該去「讀完」Ruby 再去用「Ruby on Rails」寫一個網站。
  • 找一本可以教你作一個 project 的書(不知道去哪找可以上網問),從頭到尾貼 code 跟著作一遍搞懂架構以及學習 debug。
  • 扔開書後的第一次:作一個比書裡面的 demo 還小的 project,如果裡面 demo 一個論壇,那麼就做一個留言板。
  • 扔開書後的第二次:重新作一個簡單的論壇,不看書。
  • 扔開書後的第三次:重新作一個有你想要的功能的論壇,可以貼圖,可以分享到 FB。
  • 去找可以幫助你重新把程式技巧提煉的更好的書,重新補基本功(這時候你可以好好的看 Ruby 書了)。
  • 去 Meetup 找職業的前輩,問他們怎麼樣可以更好的翻修你的 project

學習協作

獨自開發一個小東西,和實際上與多人一起開發一個中型結構的專案是完全不一樣的世界。而學校幾乎不可能有這樣的環境。
  • 註冊 Trello 帳號(這是一個簡單協作、看板式的專案系統)
  • 試著與同學或同事「合作」。但用 Trello 管理所有待辦事項。
  • 重點是
    • 把一件龐大的目標拆分成數十個可以執行的小事項
    • 每一樣事項有各自的狀況。現在做到哪裡,還缺什麼,需要交付的材料,多久才會做完,遇到什麼困難
    • 不要用 Off-book (phone/email) 的管道溝通
    • 有問題就提出,不要藏在台面下。
    • 每一件事都應該要有一個可以指派的人

分享(程式碼以及文章)

不斷的貼 code 以及練習在網路上發表文章,可以強化你的表達能力與邏輯組織能力。知名軟體公司 37Signals 甚至表示,他們不太注重程式底子,只雇用「寫作能力」良好的人。因為寫作能力強大代表著:組織能力與邏輯能力強。
這不是什麼可以速成可以偽裝的東西。同時不斷發表東西,連帶的效應就是可以幫你建立 reputation,和讓別人發現你的存在
  • 把學到的東西發表到 Blog 上面。(不要怕害羞)
  • 即便是小小的程式片斷也貼到 Blog 上。
  • 不斷的貼 code 以及練習在網路上發表文章,
  • 把自己作品放到 Github 上

Learn English

這裡說的學習英文不是說去背單字,上補習班,考 TOEIC。而是:
  • 練習幫自己在 Github 的 Project 上寫 README
  • 有辦法在在 Github 上用英文 open issue / reply issue
  • 在 Stackoverflow 上用英文問問題
  • 訂閱社群電子報。(尤其讀社群電子報,如 Ruby Weekly,是個學習 Ruby 非常快的方式)
  • 聆聽社群 Podcast。(社群都會有一些 Podcast,短的 5 分鐘如 Ruby5,長的 30-45min,可以很快的讓你抓到這個禮拜世界上最新的重點是什麼)
  • 購買線上教材。(現在網上學習的教材都比大學教科書便宜非常多,有些甚至不要錢。不過他們都是「英文」影片以及作業)
=== 分隔線 ===

小結:

這是由我過去的實戰經驗總結出來的 CheatSheet。當然,這些事我並沒有說都是非常「輕鬆」做到的事。但我可以向你保證這些方向,如果練成都是「非常值錢非常具有競爭力」的技能。認真執行三個月,你「馬上」可以見到與台灣完全不一樣的那個世界。

Reference:
http://blog.xdite.net/posts/2013/11/22/opensource-cheatsheets