向初學者學習編程技巧

向初學者學習編程技巧

如何從初學者的行爲中學習編程技巧?

避免過度嵌套的條件判斷語句:條件反轉

初學者的(存在問題的)做法:

def foo(*args):
    if cond1:
        if cond2:
            if cond3:
                return something complex
    return 0

條件語句的嵌套太深了,可讀性不佳。

稍微好一點的例子:

def foo(*args):
    if cond1 and cond2 and cond3:
        return something complex
    return 0

這樣做的缺點是,在每個條件都很長的情況下,if cond1 and cond2 and cond3這一行代碼會很長。

受此現象啓發,改版的代碼:

def foo(*args):
    if not cond1: return 0
    if not cond2: return 0
    if not cond3: return 0 
    return something complex

雖然這個代碼可讀性也一般,但是也提供了新的思路:模式匹配的思路在開發的很多時候是很有用的。算是多種思路吧。

代碼簡化:建立思維慣性和直覺

初學者的(存在問題的)做法:寫代碼時沒有直覺,或事事自己實現而不調包。

建立直覺包括:

  • 明確知道“調包”的範圍:在這個範圍內的代碼不要手動實現,而應該選擇調包。這樣做的好處是,不但省工省力,而且可讀性好。
    • 原則上,只要有包可調,就應該調。但實際上,應該選擇實現起來最簡單/效率最高/可讀性最好/可維護性最好的方式。要理解包的邏輯粒度(granularity of logic),如果功能很簡單但是包很複雜,就沒有必要過度fit包。
  • 在寫下一行代碼的時候,明確知道自己期待什麼,並能夠目標導向地debug。或者說,對於自己的預期目標,能明確地描述之,並能建立完整的思路實現這個目標。

建立直覺的方式:

  • 多投入時間寫代碼
  • 多參與要求質量的、不同方向的項目
  • 接觸編程語言和編程範式
  • 多思考自己該怎麼把代碼寫好

代碼優化的準則:先完成功能再優化

初學者的(值得借鑑的)做法:啥都不想,先完成功能再說。

一旦在寫代碼的時候考慮過度,比如一邊寫一邊考慮性能優化、安全問題、可讀性優化等,就會降低開發效率。在輔助直覺判斷的情況下,應該先實現功能,再考慮各項指標的優化。提前考慮的很多目標,尤其是性能優化,很有可能被證明是沒有用的(在開發者的自我測試中,或在後面的迭代中)。所以,先work再說。

更細緻地說,目標的層次應該是:

  • work,且沒大毛病:最優先的目標
  • 可讀性:在開發時和上一步同時做到,方法是在開發中通過開發經驗來保證代碼質量
  • 可維護性:在開發時和上一步同時做到,方法是使用設計模式
  • 性能:相對最不重要

等等…目標性問題?

有目標的探索方法:明確目標,然後找到工具來解決它。
無目標的探索方法:我想要X,於是我做了Y,並這樣那樣的改了一下,現在部分work了,但我不知道爲什麼這部分work,也不知道爲什麼其他部分不work

對於程序員的編程工作,肯定要採用前者。對於生活中的其他問題,不好說,因爲沒有明確的目標/評價指標,而且通常沒有“完全解決”或者說“最優”的方法。

The way of code: We proceed by understanding the abstractions afforded by the language, and then match those abstractions to a model of the business domain of the program

從工具開發者的角度來說,應該設計工具的功能,使得工具支持使用者的成功:有目標時,方便使用者使用;無目標時,能把使用者領到正確的道路來。

不要釘死在一門語言上

初學者的(存在問題的)做法:以Java入門的初學者認爲類是編程的最小粒度,所以(比如)在編C++時,實現很簡單的邏輯也非用類不可。

心得:

  • 不要釘死在一門語言上,過度overfit這門語言的高級特性,而不去關注其他語言的低級特性。(這種情況尤其在OOP語言上出現的多。)這樣會使自己考慮問題和解決問題的思維過於片面,從而得不到最優解決方法。
  • 要根據實際情況寫代碼,不要過度fit設計模式而使代碼很冗餘。

經驗:還是上文所說的,多接觸幾門語言和幾種設計模式,並將其概括,活學活用。

多讀代碼

初學者的(存在問題的)做法:只用自己習慣的模式寫代碼,讀別人的代碼,採用的語法或開發的思路不同於自己所習慣的範式,就讀不懂了。

心得:

  • 從輸入的層面:多讀代碼,培養自己“讀得懂代碼”的能力。這樣做的好處是增加學習速度(在需要的時候),以及在和他人協同開發時不會出問題。
  • 從輸出的層面:如果是明確的模式,就寫出來(代碼、註釋),使讀代碼的人能意識到;對於其他,根本不要形成模式,就算看起來很有規律也要解釋清楚:this is not universal.

技能樹(技術棧)的取捨

學習了高級的東西之後,要積極地忘記低級的東西,不要在低級的事情上浪費時間。

正例:FP和OOP是並列的,學會FP之後也不要忘記OOP,實踐時該用啥用啥。
反例:(只是舉個例子)推出Python3且Py3逐漸成爲主流,就應該擁抱Py3,把原來用Py2寫的東西換掉;進入大學之後高中的知識點已經不再重要,應該好好上課和學習,而不是繼續鞏固高考的知識點。

本文是對What senior developers can learn from beginners的學習筆記,不過在內容上多有擴展,加入了很多自己的認識和例子。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章