掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
為了順利的再進(jìn)職場,最近一個月來都在做有目的訓(xùn)練,訓(xùn)練自己的實操能力(因為這是我的一個弱項——前端項目經(jīng)驗薄弱,加上在特長上,編碼和分析更傾向后者),而不是任意的自由的學(xué)習(xí)。然而,在具體的學(xué)習(xí)主題上,除了參考和對比常規(guī)面試題,找出一些基礎(chǔ)主題外,對什么是“最有價值”的學(xué)習(xí)主題,我沒有指引。

創(chuàng)新互聯(lián)公司主要從事網(wǎng)站制作、做網(wǎng)站、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)潼關(guān),十多年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
其實我一真很相信自己的直覺,但是難免有盲區(qū),和價值沖突,我不清楚明天面對面的考官他希望我具備什么能力。我的擔(dān)心不是沒有原因的,因為軟件開發(fā)技術(shù)崗位向來都是既難招亦難找,企業(yè)不知道怎么考核應(yīng)聘者實力,求職者不知道學(xué)什么最重要。
這里邊有一個推理,在面試和通過面試的情景里,假設(shè)把企業(yè),和求職者分兩類:
那么會出現(xiàn)四種面試情況:C1P1 C1P2 C2P1 C2P2
如果假設(shè)成立,那么通過面試的只有 C1P1 和C2P2,但是真正算成功面試只有C1P1,因為只有這種結(jié)合才是良性的。
要創(chuàng)造一次良性的結(jié)合,關(guān)鍵點其實也很明顯了,就是 企業(yè)掌握了評估技術(shù)崗位候選者能力的技術(shù),包括考核的目標(biāo)(T),和考核的方法;同時,求職者通過掌握同樣的學(xué)習(xí)目標(biāo)(T)和學(xué)習(xí)方法,更有效提高的水平。
這里 關(guān)于T的認(rèn)識 是重中之重,它是對招聘者和求職者都極具意義的一點。最近在研習(xí) 函數(shù)式編程過程中,從Eric Elliott(《Programming JavaScript Applications》一書的作者)的這篇文章《 10 Interview Questions Every JavaScript Developer Should Know 》中,找到了一些相關(guān)有價值的觀點,嘗試轉(zhuǎn)譯出來。
Table of Contents
我寫過一篇文章叫《 Why Hiring is So Hard in Tech 》, 其中給出評估 技術(shù)崗位候選者 的一些 常規(guī)原則,以什么是應(yīng)該和不應(yīng)該的形式羅列出來,其中有一條:
The best way to evaluate a candidate is a pair programming exercise.
評估候選者最有效的方法是「和候選者結(jié)伴的完成編程練習(xí)」。
意思是說,與候選人坐一起,讓候選人敲鍵盤,你在旁邊多看多聽,少說。例如演示例如從Twitter API中提取tweet數(shù)據(jù)項,并在時間軸上顯示出來。
雖然結(jié)伴練習(xí)很有價值,但是不存在一個單獨的練習(xí)能決斷一切,面對面交談(的面試)也是一個非常有用的工具 [em] 。不過, 不要浪費時間詢問語法或語言怪癖 。你需要看到大局,詢問有關(guān)架構(gòu)設(shè)計(architecture)和編程范型(paradigms) 等對整個項目有重大影響的經(jīng)驗知識。
EM:臨場小練習(xí)能測試到能力(種類)是有限的,有很多深層經(jīng)驗或知識只能通過 別的手段探測 到,例如交談,主題試題;而且沒有很具體的答案(檢測標(biāo)準(zhǔn)),例如怎么檢測候選人 功能編程 的能力?
語法細(xì)節(jié)和API功能特性的知識 是很容易搜索的,但對于像 軟件工程的智慧或 JavaScript開發(fā)人員 從經(jīng)驗中獲得的 范型特性和習(xí)慣用法 這些經(jīng)驗知識,是很難短時間通過搜索學(xué)到的。
EM:這里提到了重點,作為招聘方,測試 候選人 的那些 不能在半小時查資料能習(xí)得的技能,求職者同樣要明白這個道理。
EM:當(dāng)然,作者提到的工程智慧,和編程經(jīng)驗具體指什么,有待研發(fā)
鑒于以上結(jié)論,對于Web開發(fā)和Javascript方面,我認(rèn)為以下十個問題用在面試中,能比較有效評估候選人開發(fā)實力:
JavaScript 是一種多范型( multi-paradigm )編程語言,支持過程式編程,面向?qū)ο缶幊?,和函?shù)式編程,三種(實質(zhì)兩種)編程范型。JavaScript通過 原型繼承( prototypal inheritance) 支持面向?qū)ο缶幊?,?函數(shù)作值(所謂一等公民)支持函數(shù)式編程。
函數(shù)式編程是使用 純函數(shù)(或數(shù)學(xué)函數(shù))構(gòu)造 程序的一種編程范型,純函數(shù)的優(yōu)點是沒有副作用(避免使用共享數(shù)據(jù) shared state),和不使用可變數(shù)據(jù)(mutable data) [em] ;
Lisp(1958年)是最早支持函數(shù)式編程的語言之一,并且受到了lambda演算的極大啟發(fā)。Lisp和很多Lisp家族語言至今仍在流行。
JavaScript 支持函數(shù)式編程,并且越來越流行,例如JavaScript社區(qū)流行的閉包,高階函數(shù),函數(shù)作參數(shù)傳遞都是 重要表現(xiàn)。
EM:純函數(shù)的優(yōu)點有待實證,純函數(shù)(功能)和類對象的區(qū)別有待分析
傳統(tǒng)類繼承是說,類(class)是「一個功能」的模板或設(shè)計樣板(blueprint),它可以用來派生子類(子類繼承父類所有功能,并可以有所擴(kuò)展),和創(chuàng)建多個對象實例(使用new操作); 通過類繼承的設(shè)計可實現(xiàn)程序的一種精致的分類層次結(jié)構(gòu)(hierarchical class taxonomies)。
但是,由于子類和父類繼承關(guān)系是一種白箱復(fù)用(父類不是完全封裝,對子類可見),最終的類層次結(jié)構(gòu)會高度耦合,這是類繼承最大的問題。
與類繼承不同,原型繼承沒有類概念(類是一個抽象的功能的“模子”),一切都是對象實例?!腹δ艽a繼承復(fù)用」通過 直接連接兩個對象實例 實現(xiàn),例如通過一個特殊的對象工廠函數(shù)( factory functions)生成新復(fù)用的對象,或復(fù)制(Object.create())。一個「目標(biāo)新對象實例」 [em]可以將需要的功能小對象直接連入其中來實現(xiàn)復(fù)用功能,這是一種非常靈活的代碼復(fù)用方法。
EM:無論何種代碼復(fù)用技術(shù)(類繼承,或是原型組合,或是其它),目標(biāo)任務(wù)都是生成新的對象實例,實現(xiàn)軟件功能的開發(fā)。
在 JavaScript中,原型繼承有以下幾種應(yīng)用表現(xiàn):
FP和OOP作為完成編程這個「任務(wù)」的「工具」,有各自的適用和優(yōu)點與不足。
直觀,對象由數(shù)據(jù)和方法組成的概念很容易理解,也容易解釋方法調(diào)用的意義。OOP傾向于使用命令式風(fēng)格,而不是聲明式風(fēng)格,命令式風(fēng)格讀起來像是一組供計算機(jī)遵循的直接指令,很形象。
OOP通常依賴于共享狀態(tài)。對象和行為通常被綁定在同一個實體上,可以被任意數(shù)量的順序不確定的函數(shù)隨機(jī)訪問,這可能會導(dǎo)致不希望的行為,比如競態(tài)事件(race conditions)。
使用 純函數(shù)作為功能單元,程序員可以避免任何共享狀態(tài)或副作用 [em] ,從而消除多個功能競爭相同資源所導(dǎo)致的bug。與OOP相比,F(xiàn)P的大功能的復(fù)合方式,例如所謂的無參數(shù)風(fēng)格(point-free ),大大簡化復(fù)雜功能的組合方式,和改善代碼可重用方式。
EM:使用和不使用共享狀態(tài)都是技術(shù),重點是那個「功能的實現(xiàn)」的任務(wù);就是為什么一定要使用中間狀態(tài)?「純函數(shù)」和「類對象」是兩種編程范式最大「工具」區(qū)別。
另外,F(xiàn)P 傾向于 聲明式和符號指代(denotational)的功能命名風(fēng)格 [em] ,F(xiàn)P不傾向通過詳細(xì)說明功能操作的步驟,而是關(guān)注「功能要做什么」。這為重構(gòu)和性能優(yōu)化留下了巨大的空間,它甚至允許你用更高效的算法替換整個舊算法,而代碼更改很少(例如,memoize,或者用惰性求值來代替eager 求值)。
EM:就是更傾向使用名詞, 而不是動詞表達(dá)「功能」
EM:兩種工具思想?yún)^(qū)別在于,F(xiàn)P是關(guān)注功能的形式和邏輯關(guān)系,OOP關(guān)于功能實現(xiàn)的數(shù)據(jù)的處理
使用純函數(shù)實現(xiàn)的計算功能也很容易移植到多處理器,或分布式計算集群環(huán)境上,而不用擔(dān)心線程資源沖突、競態(tài)事件(race conditions)等。
過度使用FP風(fēng)格的代碼(例如大量使用無參數(shù)式風(fēng)格分割和組合 大功能 )可能會降低代碼可讀性,因為生成的代碼通常很抽象,它簡潔且不夠具體。
與函數(shù)式編程相比,習(xí)慣OOP和命令式編程的人會更多,更深厚,因此,即使是函數(shù)式編程中的常見習(xí)慣用法也會讓新團(tuán)隊成員感到困惑。
另外,F(xiàn)P的學(xué)習(xí)曲線要比OOP陡峭得多,因為OOP的廣泛流行使得OOP的語言和學(xué)習(xí)材料變得更加對話化,而FP的語言則更加學(xué)術(shù)化和形式化。
總的來說,OOP使用共享狀態(tài)「 實現(xiàn)復(fù)合功 」能是有害的,雖然它很直觀;高度使用OOP的codebase比較“頑固”和脆弱,難改又錯誤百出;FP除了沒有OOP的這些不足外,程序比較易讀易維護(hù),只是適應(yīng)FP風(fēng)格需要一些時間。
幾乎沒有適用的場景, 類繼承能免則免,除非只有一層的繼承;
第六,在什么場景下最適合使用 原型繼承?
在JS中,當(dāng)需要復(fù)用代碼時都幾乎可以使用原型繼承,當(dāng)然包括不適用函數(shù)式復(fù)用(FP也提供了復(fù)用機(jī)制)的時候。JS中有三類的原型繼承:
每一類 原型繼承都有各自適用場景,不過,它們都?xì)w結(jié)為 構(gòu)成(composition)復(fù)用,是一種 has-a or uses-a or can-do 的關(guān)系,與類繼承的 is-a關(guān)系相反。

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流