近日,華為輪值董事長徐直軍撰寫了《關於公司高端精英類、軟件類人才面試方法調整的建議》。其中重點講到:軟件類人才面試要以考察軟件工程能力與編程能力,識別出真正的軟件開發與設計高手。文章也給出了具體的考核方式:
應聘人員首先應該進行網上編程,時間 90 分鍾,網上編程符合要求的進入面試環節。
在網上編程環節中,有兩輪面試,每輪 45 分鍾。每輪面試當面或視頻面試,考察實際編程能力及相關知識技能的掌握程度。編程時間 30 分鍾,提問與討論 15 分鍾。
看到網上編程的時候,我立刻想到了 ThoughtWorks 這家公司。ThoughtWorks 的面試重點就是考核面試者的編程能力和設計能力。面試者在正式面試之前,首先會受到一個 homework,只有做完這個 homework,並且達到要求的候選人才能進入后續的面試。而后續面試也與我們平常的面試不同,ThoughtWorks 的后續面試都會圍繞這份 homework 進行編程面試。例如:當場給出新的需求,讓你重構你原來的代碼。
對於習慣了國內面試流程的開發者來說,如果去 ThoughtWorks 面試,homework 過不了都是一種常態。因為國內互聯網公司因為追求速度,所以很多時候就犧牲了代碼的質量。如果平時都是這么一種狀態,那么面試的時候自然不會考察編程能力了。
華為注重編程能力的考察、注重軟件工程實踐也是一件好事。短期來講會提高門檻,但是長期看來會提高編程的科學性,減少重復勞動。而且隨着國內 IT 行業的不斷成熟,國內公司會越來越注重編程能力的考核。那作為軟件開發者的我們,應該如何順應這一趨勢提升自己呢?
測試驅動
測試驅動是一種編程的思想,簡單地說就是用測試來驅動編程。想象一下:當我們在重構一個系統的時候,如果沒有測試用例,那么我們重構完成之后怎么能保證它是沒有問題的呢?而如果你的項目一開始就是采用測試驅動開發的,那么當你完成重構后,只需要運行一遍測試用例,就可以發現存在的問題,從而減少潛在的 bug。
當然測試驅動並沒有我說的那么簡單,上面只是測試驅動開發帶來的一個好處。真正的測試驅動需要遵循一套比較完整的流程:
- 首先,分析需求,針對需求編寫測試用例。
- 接着,針對測試用例編寫業務代碼。
- 接着,對通過測試用例的代碼進行重構,使其更易於擴展。
- 最后,還需要運行一次測試用例,確保重構后的代碼沒有問題。
通過這么一種方式,我們能夠在一開始的時候就發現需求中的問題,從而避免代碼寫完之后進行變更,從而提高了效率。而有了測試用例的存在,我們可以確保重構時不會使原有功能受損。
設計模式
在測試驅動中我們說到重構,而在重構中不得不說的就是設計模式。設計模式對於初學者來說就像天書一樣,完全搞不懂它是做什么的。但如果你有一定的項目經驗和源碼閱讀經驗,你會發現設計模式的好處。設計模式的本質是用編程模式去承載業務的復雜性,使得業務代碼更加容易擴展。
例如我們使用得最多的策略模式,其實就是將每種可能的情況放到一個單獨的類中,使得每種情況單獨分開,從而有利於擴展和修改。
public interface PeelOff {
void peelOff();
}
public class ApplePeelOff implement PeelOff{
void peelOff(){
//deal with apple
}
}
public class BananaPeelOff implement PeelOff{
void peelOff(){
//deal with banana
}
}
而模板模式在源碼設計中也用得非常多。例如在 AQS 的實現中,在 AQS 的實現中調用了 tryAcquire() 方法,但在 AQS 中的 tryAcquire() 方法中卻沒有具體實現。這是因為其將 tryAcquire() 的具體實現交給了子類,從而實現了實現方式的多樣化。
// AQS的tryAcquire實現,使用了模板方法
// 在AQS中直接拋出異常,沒有具體實現,具體的實現在子類中
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
// 在acquire方法中調用tryAcquire方法
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
類似的設計模式還有很多,這里就不過多介紹了。從這些例子中我們可以看到,因為設計模式的存在,使得程序更加靈活、更加易於擴展了。了解常見的設計模式只是開始,我們需要在日常工作中不斷地嘗試使用它們。在不斷的實踐中加深對於設計模式的理解,最終才能對設計模式有深層次的理解和運用。
重構
重構可以說是高級開發人員必備的技能了,前面所說的設計模式在重構的時候會發揮很大的作用。但設計模式只是重構過程的一個重要運用,在重構過程中還有許多可以運用的原則,例如:單一職責原則等。
關於重構這塊的知識點有很多,這里就不深入介紹了。關於重構建議閱讀《重構》這本書,相信會有不少收獲。
軟件工程
關於這塊知識點,我們許多人都是忽略的。我現在能回想得起也是在大學的時候,那時候有一門課程叫軟件工程。但是自從工作之后,基本上就和軟件工程斷了聯系。
隨着工作年限的增長,慢慢發現這塊東西還是非常有用的。特別是當你作為一個團隊 leader或項目經驗,要去管理整個技術團隊的時候,軟件工程就是你必須要懂的東西。我們前面所說的「測試驅動編程」就是軟件工程中的一塊,除此之外還有「領域編程(DDD)」等。
軟件工程可以從項目角度讓我們更科學地把我研發進度,形成更合理的研發體系。所以關於軟件工程的知識點也是我們需要重點學習的。
總結
或許是由於 IT 發展歷程的原因,所以國內 IT 公司都不怎么注重編程能力和軟件工程的考核。但如果你有留意國外公司的面試流程,你會發現國外公司都比較注重編程能力的考核,通常都會有手寫代碼、在線編程等考核。我相信隨着國內 IT 行業越來越成熟,肯定有越來越多的公司將編程能力納入考核范圍。
對於軟件開發從業者的我們,我覺得這是一件好事。編程能力的提升、軟件工程的實踐會使得項目變得更加可控,這在一定程度上會減弱無效的編程勞動,提高軟件開發從業者的幸福感。與此同時,它也對我們提出了更高的要求,需要我們掌握更多的專業知識技能。
簡單地說,我們不應該只是簡單地思考如何應付這次面試改革,而應該去思考這背后的原因。從而讓我們的能力跟上市場的需求,只有這樣我們才能立於不敗之地。在我看來,測試驅動、設計模式、重構、軟件工程是我未來要重點加強的能力。
對於這次華為面試改革,你覺得軟件從業者應該加強哪方面的能力,歡迎留言討論。