将这五个原则变成习惯,你的开发经验更值钱!
前言
馬超
每年的三月到六月,都是招聘高峰,除了大量的應(yīng)屆畢業(yè)生涌入社會(huì)之外,還有一些工作了一兩年尚未找到穩(wěn)定歸屬感的人,也會(huì)開始投遞簡(jiǎn)歷,是的,基本都是在拿了年終獎(jiǎng)之后。
作為前端技術(shù)主管,有幸,或者說(shuō)是不幸,我需要在這些投遞過(guò)來(lái)簡(jiǎn)歷的人中,耗費(fèi)大量精力來(lái)篩選符合公司要求、團(tuán)隊(duì)發(fā)展、技術(shù)基礎(chǔ)三方面條件的人選來(lái),這不是一個(gè)容易的活兒。
我不是一個(gè)擅長(zhǎng)技巧的面試官,盡管公司HR也給我們培訓(xùn)過(guò)招聘的原則、技巧,但是真正的體驗(yàn)和感受,卻是在做了大量面試之后自然而然悟出來(lái)的。常見的招聘要求中,基本都有“工作經(jīng)驗(yàn)”的要求,而且都是以年作為單位,HR似乎比較迷戀這個(gè)數(shù)字,但是實(shí)際情況卻告訴我,工作經(jīng)驗(yàn)往往不是以年衡量的,甚至有些時(shí)候,跟時(shí)間沒有關(guān)系。
今天想要分享的一點(diǎn)是關(guān)于“為什么你的工作經(jīng)驗(yàn)不值錢”,或者“怎么樣才能讓工作經(jīng)驗(yàn)值錢”,庸俗,卻能讓每個(gè)人提起精神。
以下經(jīng)驗(yàn)分享,僅僅適用于碼農(nóng)相關(guān)職位,其他職位可借鑒其思想,不可照搬。
開始
從一個(gè)小小的面試題目入手:
編寫一個(gè)javscript函數(shù) fn,該函數(shù)有一個(gè)參數(shù) n(數(shù)字類型),其返回值是一個(gè)數(shù)組,該數(shù)組內(nèi)是 n 個(gè)隨機(jī)且不重復(fù)的整數(shù),且整數(shù)取值范圍是 [2, 32]。
如果愿意,請(qǐng)先暫停閱讀文章,自己動(dòng)手寫一下這個(gè)函數(shù),是的,老簡(jiǎn)單了。我可以等你五分鐘。
~~~ 華麗的5分鐘過(guò)去了 ~~~
現(xiàn)在假設(shè)你的工作時(shí)間為 y 年,經(jīng)驗(yàn)系數(shù)默認(rèn)為 1,即工作經(jīng)驗(yàn)是:Y = 1 * y。從現(xiàn)在開始,以下的錯(cuò)誤,你要是遇到了,請(qǐng)自行調(diào)整經(jīng)驗(yàn)系數(shù)。
1. 可用
作為一段需要滿足需求的代碼來(lái)說(shuō),它最核心的、最低的要求就是:可用。
如果你沒有產(chǎn)出一個(gè)函數(shù)( fn ),或者產(chǎn)生了語(yǔ)法錯(cuò)誤,那就請(qǐng)?jiān)O(shè)置 經(jīng)驗(yàn)系數(shù)為 0,然后去面壁思過(guò);
請(qǐng)將代碼在控制臺(tái)運(yùn)行,并執(zhí)行 fn(3),看看是否輸出一個(gè)數(shù)組,數(shù)組中包含了三個(gè)隨機(jī)且不同且在[2,32]的整數(shù),如果不是,請(qǐng)將 經(jīng)驗(yàn)系數(shù) * 0;
一個(gè)參考的半偽代碼是:
function fn(n){
? ? //準(zhǔn)備一個(gè)容器保存結(jié)果
? ? var arr = [];
? ? //循環(huán)
? ? for(var i=0; i<n; i++){
? ? ? ? //創(chuàng)建一個(gè)隨機(jī)數(shù)
? ? ? ? var rnd = getRand(2, 32);
//檢查是否重復(fù)
? ? ? ? if( checkInArr(arr, rnd) ){
? ? ? ? ? ? i--;
? ? ? ? }else{
? ? ? ? ? ? arr.push(rnd);
? ? ? ? }
? ? }
? ? return arr;
}
其中 getRand 、checkInArr 還另有講究,后面會(huì)提到。當(dāng)然思路和方法不止一個(gè),后面也會(huì)提到。
有相當(dāng)多的面試者,包括不少工作時(shí)間為2年以內(nèi)的同學(xué),都會(huì)在這一步犯錯(cuò),非常遺憾。
2. 健壯
代碼是否老道,過(guò)了“可用”這一關(guān)后,就開始見分曉了。所謂“健壯”,即最基本的兼容性處理、邊界處理,異常處理、用戶輸入校驗(yàn)。很多時(shí)候,需求方不會(huì)明確告訴你這些邏輯怎么處理(在實(shí)際開發(fā)中,似乎也比較常見),但并不意味著你不需要處理。健壯的程序,一定會(huì)將這些兼容性、邊界、異常、輸入做處理,以保證核心功能的正確輸出。當(dāng)然,如果你的代碼沒有任何輸入并不考慮兼容性(可能嗎?)或者僅僅是內(nèi)部函數(shù),那這一步要求可以降低,并不意味著你可以完全不做。
好,回過(guò)頭看代碼:
如果你沒有對(duì) n 的取值范圍做校驗(yàn)(n必須是 1 到 31 之間的整數(shù)),請(qǐng)將 經(jīng)驗(yàn)系數(shù) * 0.3;
如果你沒有對(duì) n 是否為數(shù)字做校驗(yàn),請(qǐng)將 經(jīng)驗(yàn)系數(shù) * 0.5;
如果你沒有對(duì) n 是否存在做校驗(yàn),請(qǐng)將 經(jīng)驗(yàn)系數(shù) * 0.7;
如果上述校驗(yàn)都做了,但是沒有校驗(yàn)對(duì),請(qǐng)將 經(jīng)驗(yàn)系數(shù) * 0.9;你需要多練習(xí),仔細(xì)認(rèn)真的。
一個(gè)參考的半偽代碼是:
function fn(n){
? ? //健壯性校驗(yàn)
? ? if(!isThere(n)) return;
? ? if(!typeOK(n)) return;
? ? if(!rangeOK(n, 2, 32)) return;
? ? //核心功能同上,此略
...
}
有了這些健壯性校驗(yàn)后,媽媽就不用擔(dān)心 fn 函數(shù)死循環(huán)、語(yǔ)法錯(cuò)誤以及錯(cuò)誤的API調(diào)用了。偽代碼中,校驗(yàn)是分為三步的,但實(shí)際代碼中,完全可以合并處理,但是邏輯不能少。
3. 可靠
大多數(shù)面試者都止步于前兩關(guān),鮮有進(jìn)入第三關(guān)的:可靠。javascript沒有強(qiáng)數(shù)據(jù)類型,函數(shù)的返回值也無(wú)法強(qiáng)制返回的數(shù)據(jù)格式。但是作為“可靠”的要求,盡可能在任何情況下,都返回一個(gè)可靠的結(jié)果,哪怕是異常情況下。是的,這一步很簡(jiǎn)單,幾乎不耗費(fèi)幾個(gè)字節(jié)的代碼,但是會(huì)讓 fn 的返回值變得可靠:
function fn(n){
? ? //健壯性校驗(yàn)
? ? if(!isThere(n)) return [];
? ? if(!typeOK(n)) return [];
? ? if(!rangeOK(n, 2, 32)) return [];
? ? //核心功能同上,此略
...
}
如果你留意到并處理可靠返回值的問(wèn)題,那請(qǐng)將經(jīng)驗(yàn)系數(shù) * 1.2;
另外,一個(gè)牽涉的話題就是:異常情況下,是否要拋出 Error,或 console.error ?關(guān)于這個(gè)話題,似乎沒有定論,需要自己衡量。我的觀點(diǎn)是:如果異常情況下不會(huì)造成太大影響的話(包括定位錯(cuò)誤),就不用拋錯(cuò)或提示。但同樣的,這個(gè)衡量仍然是經(jīng)驗(yàn)性的。此處不再展開討論。
4. 寬容
如果在你的日常開發(fā)中注意“可用”、“健壯”、“可靠”原則的話,你的工作經(jīng)驗(yàn)就會(huì)大于你的工作時(shí)間,也就會(huì)更容易受到重視,自己所挖的坑就會(huì)少。而我近期面試的人中,甚至包括5、6年工作時(shí)間的,幾乎都止步于此。
如果你要想成為一個(gè)受歡迎的技術(shù)人員,“寬容”是第一步: 對(duì)需求寬容、對(duì)用戶寬容、對(duì)調(diào)用者寬容、對(duì)維護(hù)者寬容。
回到代碼:
如果 n 是一個(gè)字符串?dāng)?shù)字,是否可以允許進(jìn)入處理流程? 如果是,請(qǐng)將經(jīng)驗(yàn)系數(shù) * 1.1;
如果 n 是一個(gè)含有小數(shù)的數(shù)字,比如 3.000001,是否允許進(jìn)入處理流程?如果是,請(qǐng)將經(jīng)驗(yàn)系數(shù) * 1.1;
你的代碼中,是否有足夠多且清晰的注釋? 如果是,請(qǐng)將經(jīng)驗(yàn)系數(shù) * 1.2;
如果需求調(diào)整了 [2, 32] 的范圍,你的代碼是否可以快速調(diào)整,甚至不用調(diào)整? 如果是,請(qǐng)將經(jīng)驗(yàn)系數(shù) * 1.2;
一個(gè)參考的半偽代碼是:
/**
?* 獲取指定個(gè)數(shù)的隨機(jī)整數(shù),整數(shù)范圍[2,32]
?* @param ?{number} ? n 需要的整數(shù)個(gè)數(shù)
?* @return {array} ?返回包含n個(gè)整數(shù)的數(shù)組,如果n非法,則返回空數(shù)組
?*/
function fn(n){
? ? //將整數(shù)取值范圍作為變量提取出來(lái)
? ? var min = 2, max = 32;
? ? //參數(shù)校驗(yàn)
? ? if(!isThere(n)) return [];
? ? if(!typeOK(n) && !isOKStr(n)) return [];
? ? n = formatInitNum(n);
? ? if(!rangeOK(n, min, max)) return [];
? ? //準(zhǔn)備一個(gè)容器保存結(jié)果
? ? var arr = [];
? ? //循環(huán)
? ? for(var i=0; i<n; i++){
? ? ? ? //創(chuàng)建一個(gè)隨機(jī)數(shù)
? ? ? ? var rnd = getRand(min, max);
//檢查是否重復(fù)
? ? ? ? if( checkInArr(arr, rnd) ){
? ? ? ? ? ? i--;
? ? ? ? }else{
? ? ? ? ? ? arr.push(rnd);
? ? ? ? }
? ? }
? ? return arr;
}
5. 精益求精
恭喜你完成了前四關(guān),如果你在實(shí)際開發(fā)中,時(shí)時(shí)刻刻留意這些原則,這足夠讓你的工作經(jīng)驗(yàn)擴(kuò)大化,并給你帶來(lái)更多的認(rèn)可,這些認(rèn)可來(lái)自于需求方(或許是那個(gè)曾經(jīng)非常蠻橫的產(chǎn)品狗)、用戶以及你的同事。但,不因該包括你自己,你還需要更進(jìn)一步。
寬容是寬以待人,精益求精是嚴(yán)以律己。內(nèi)外兼修才是高手。
上文做了一點(diǎn)伏筆,現(xiàn)在討論 getRand 、 checkInArr 到底有哪些講究:
getRand
如果你不知道 Math.random() 返回 [0, 1) 的小數(shù),請(qǐng)自行翻閱js手冊(cè);
如果你不知道怎么將 [0, 1) 等比放大到任意區(qū)間 [min, max),請(qǐng)慎重考慮是否合適做一個(gè)碼農(nóng);
代碼是類似這樣的: Math.random() * ( max - min + 1 ) + min。 現(xiàn)在的問(wèn)題是:如果要取整數(shù),是向上取整,還是向下取整?
如果你不假思索,就回答:“都行”,那你需要去面壁思過(guò);
如果你略作停頓,回答: “取整方法會(huì)影響邊界設(shè)置”,那恭喜你有一些進(jìn)步;
如果你認(rèn)真思考后,回答:“只能向下取整”,那你已經(jīng)走在了高手的路上。
是的,只能向下取整,這涉及“隨機(jī)”概率的分布問(wèn)題,請(qǐng)為邊界值仔細(xì)考慮一下。這里不再細(xì)述。
checkInArr
Array.prototype.indexOf 是優(yōu)先方案,除非你考慮IE6(當(dāng)然也可以用墊片函數(shù)給IE6加上這個(gè)indexOf);
用 map 來(lái)作為key查詢代理,這個(gè)方法簡(jiǎn)單高效,兼容性也非常好;
最不濟(jì),自己for循環(huán)。
好了,
這些方案有性能差異嗎?
差異的分水嶺在循環(huán)多少次的情況下出現(xiàn)?
不同瀏覽器表現(xiàn)如何?
能否寫一個(gè)性能測(cè)試腳本,把不同方案跑上 10000 次看看?創(chuàng)建一個(gè)包含 2... 32的數(shù)組,然后亂序排序( Array.prototype.sort )后,直接取前 n 個(gè)整數(shù),是不是更高效?
還有,
返回的數(shù)組要不要控制一下排序?
當(dāng) n 大于 31 時(shí),是要返回空數(shù)組,還是全部31個(gè)數(shù)字?當(dāng) n 為 30 的時(shí)候,遍歷30次(或更多),是不是不如直接隨機(jī)去掉一個(gè)更簡(jiǎn)單、更高效?
這些,就交給你了。
當(dāng)你將這五個(gè)原則(可用、健壯、可靠、寬容、精益求精)變成你自己的開發(fā)習(xí)慣,你的工作經(jīng)驗(yàn)就跟你的工作時(shí)間沒有關(guān)系了。
6. one more thing
樂于分享,也是一個(gè)好同學(xué)的必要素質(zhì)。覺得本文還不錯(cuò)的,點(diǎn)贊、轉(zhuǎn)載,讓更多人受益吧。
?
· EDN ·
網(wǎng)易云信|無(wú)IM開發(fā)經(jīng)驗(yàn)也能開發(fā)IM
ID:neteaseim ?長(zhǎng)按識(shí)別,關(guān)注精彩
總結(jié)
以上是生活随笔為你收集整理的将这五个原则变成习惯,你的开发经验更值钱!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 家在深圳接入云信,让用户在社交中感受到“
- 下一篇: 混合编程黑科技:跨语言编程问题迎刃而解的