當我們說軟體工程師的時候我們在說什麼
基於個人的經歷和理解,下面內容列出了我認為對於一個軟體工程師最重要的六個方面,然後對於每個方面我給出了解釋和例子。如果你對這個話題有興趣,請在評論寫下你的觀點和看法,謝謝!
=============== 我是分割線的開始 ===============
您還可以在這裡找到我:
博客:http://haochuan.io/
Medium:_haochuan
Github:haochuan (haochuan) · GitHub
英文版請前往:
Medium: https://medium.com/@haochuan/what-matters-most-to-a-software-engineer-bc63092d033d#.aiaqs7u76
博客:http://haochuan.io/what-matters-most-to-a-software-engineer/
=============== 我是分割線的結束 ===============
計算機科學的基礎
如果你在日常的工作中從來沒有認識到一些基本的數據結構,演算法知識,以及設計模式對一個軟體工程師來講是必不可少的,那麼我就有理由對你是不是一個合格的軟體工程師而產生懷疑。這裡我說計算機科學的基礎知識,是因為作為一個軟體工程師而不是一個計算機科學家,我們完全沒有必要去深入的研究探索某個概念或者更某個演算法。我們僅僅只需要知道一些比較基礎的原理,和用代碼實現這些原理的方法。
例子 1
現在你的任務是編寫一個英語聽力測驗的軟體,假設你有100個英語句子和它們的錄音,你將會讓用戶聽這些錄音並且寫下來錄音里的內容,然後去和原始的句子比對看看區別有多大,你應該怎麼做來比對這兩個句子?
好
你瞬間就能意識到你應該用edit distance, 然後你能在10分鐘以內完成代碼實現。
中
你隱約記得有種方法是專門用來計算兩個字元串的相似/相同,你花了15分鐘在網上找到了這個東西叫edit distance, 然後你又花了15分鐘找到了實現方法然後貼在你的代碼里。
差
完全不知道怎麼辦
例子 2
你現在要在一個軟體的輸入框里添加撤銷/恢復的功能。
好
- 兩個棧(stack): undoStack [] 和 redoStack [].
- 輸入 a, push a 到 undoStack, undoStack = [a], redoStack = [], input = a
- 輸入 b, push b 到 undoStack, undoStack = [a, b], redoStack = [], input = ab
- 輸入 c, push c 到 undoStack, undoStack = [a, b, c], redoStack = [], input = abc
- 撤銷, undoStack 出棧一個元素, push 這個出棧的元素到 redoStack, undoStack = [a, b] and redoStack = [c], input = ab
- 撤銷, undoStack 出棧一個元素, push 這個出棧的元素到 redoStack, undoStack = [a] and redoStack = [c, b], input = a
- 恢復, redoStack 出棧一個元素, push 這個出棧的元素到 undoStack, undoStack = [a, b] and redoStack = [c], input = ab
差
完全不知道怎麼辦
例子 3
你聽見有人在談論斐波那契(Fibonacci)
好
首先想到的是遞歸(recursion).
中
首先想到的是1 1 2 3 5 8.
差
什麼都沒想到
某種語言的代碼能力和解決問題的能力
大家都知道軟體工程師寫代碼,所以不需要太多語言來解釋為什麼代碼能力很重要。關於不同語言的選擇問題,在某種方面看來,所以的語言都是一樣的,它們都是一種工具來讓計算機做我們想做的事情。每種語言都有它們各自的特點,優點以及缺點,作為一個軟體工程師你必須要至少掌握其中一種語言。
對於一種語言語法以及內建庫/函數的熟悉是代碼能力中很重要的一個方面。但是在剛開始學習這門語言的時候,死記硬背這些東西貌似並不是一個明智的選擇。經常查文檔來獲取這些還沒有那麼熟悉的東西的這種行為絕對不是代碼能力不夠的體現。
註:以下的例子都是Javascript
例子 1
一個很常見的問題就是我們需要把URL里的參數提出來並且轉化為一個Javascript的Object。假設這個URL是:`http://helloworld.com/?user=haochuan¶m1=aaa¶m2=bbb`,我們應該怎麼樣將它轉化為以下的Object:
{ user: "haochuan", param1: "aaa", param2: "bbb"}
好
正則表達式
const URL = "http://helloworld.com?user=haochuan?m1=aaa?m2=bbb";const RE = /(?|&)([^=]+)=([^&]+)/g;let paramsObject = {};URL.replace(RE, (match, p1, p2, p3) => { paramsObject[p2] = p3;});console.log(paramsObject);// will be { user: haochuan, param1: aaa, param2: bbb }
中
`URL.split(?)` -> `split(&)` -> `split(=)`, 然後構建這個Object。
差
完全不知道怎麼辦
例子 2
你的同事讓你幫他寫個函數,交換兩個整數, 不能用任何臨時變數。
好
function swapNumb(a, b){ a = a ^ b; b = a ^ b; a = a ^ b;}
中
function swapNumb(a, b){ b = b - a; a = a + b; b = a - b;}
差
沒有了臨時變數完全不知道怎麼辦
例子 3 (語言特性)
從1到5每隔一秒列印出一個數字
好
for (var i = 1; i < 6; i++) { (function (num) { setTimeout(function (){ console.log(num); }, 1000); })(i);}
差
for (var i = 1; i < 6; i++) { setTimeout(function (){ console.log(num); }, 1000);}
例子 4 (注釋和文檔)
保證你在五年之後看今天你寫的代碼的時候能夠較快的明白你當時想要幹嘛,然後在你的代碼里合理的利用`FIXME`, `TODO`, `REMOVEME`等標籤
好
/** * Function to return the sum of two integer * @param {Integer} a first integer * @param {Integer} b second integer * @return {Integer} sum of a and b */// TODO: support float sum in next monthfunction sum(a, b) { return a + b;}
差
function sum(a, b) { return a + b;}
開發工具的熟練度
沒有必要所有人都要是vim或者emacs的大神,但是你必須能夠玩轉至少一個你喜歡的編輯器/IDE,包括各種插件,自動化,以及git和常用的命令行命令。
例子 1
假設你有一個3行的Javascript文件,然後每行的末尾都忘記了分號,現在你想把分號加進來,應該怎麼做?
const HOST = http://hello.comconst API = /api/getPageloadContent(HOST + API)
好
- vim: `gg` -> `shift + a` -> `;` -> `Esc` -> `j` -> `.` -> `j` -> `.`
- sublime: 自己寫插件或者網上找插件來完成這種常用的操作
差
眼睛找 - 滑鼠點 - 鍵盤上點分號鍵 - 重複三遍
例子 2
假設你有一個3行的Javascript文件,你想要替換第2航和第三行的內容,應該怎麼做?
const HOST = http://hello.comconst API = /api/getPageloadContent(HOST + API)
好
- vim: `3gg` -> `Esc` -> `:m 1` -> `Enter`
- sublime: 滑鼠單擊第三行的任意地方,然後`Command + Control + upArrow`
差
全選 - 複製 - 新建一行 - 粘貼
熟悉軟體開發的流程和步驟
儘管在有些公司會有人來專門幫你做這些事情,但是如果你對這整個流程比較了解的話,會讓你生活輕鬆點並且節約很多時間。
好
- 知道怎麼用git/svn來跟其他人合作
- 知道怎麼快速的設置開發環境
- 知道一個產品的開發流程
- 知道怎麼部署你的代碼
- 知道測試相關的內容
學習能力
在我看來強行的要求每個軟體工程師都用一樣的東西和擁有一樣的技術棧是幾乎不可能的事情,即使他們有著相同的職位和相同的工作內容,所以在平時的工作中我們有一部分時間花在了學習別人熟悉的技術和任何人都不熟悉的新技術上。讓我們回到React剛開始變火的那個時候,是否能在短時間內判斷出react到底好不好,是否能在短時間內判斷出哪個flux的實現更適合你的項目,是否能在短時間內開始用React來替換你之前的工具,這些就是所謂的學習能力。假設你從來沒有用過bootstrap,通過官方的文檔和網上的各種資源,你需要多長時間才能把這個新東西用到你自己的項目里,這就是所謂的學習能力。
溝通能力
以下我列出了在我的經歷中我認為最重要的幾點:
- 方法不限,形式不限,能不能用簡短的語言和在有限的時間裡讓其他的工程師理解你寫的代碼?
- 方法不限,形式不限,能不能在有限的時間裡理解其他工程師所寫的代碼?
- 如果你現在的項目有一個新的工程師加入,你能不能很好的幫助他來快速熟悉項目並且保證他在短時間內就可以對項目有所貢獻?
- 你能在開各種會的時候簡介明了的表達你的問題和觀點么?
推薦閱讀:
※狼叔:Node.js 源碼是如何執行的?| Live 預告
※越獄環境全局開啟任意 iOS App 的 WebView 調試
※外刊君譯者挖掘機計劃