search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

從學Python到學編程

由於python有很多其他編程語言所不能及的優點,比如具有可移植、可擴展、豐富的開源庫,跨平台、易於學習、易於閱讀等特性blablabla……不過關鍵還是我得用它來幹活,這兩天都在猛學。

剛開始壓力是不小的,萬事開頭難啊,不過學著學著,發現其實編程語言都有很多相同的地方,今天把基礎部分學完了。憑心而論,感覺pyhton結合了C/C++的部分內容,又和matlab語法有很多相通之處,大同小異,只需專註學習pyhton所具有的新特性就好了,省了不少精力(大學的有些課程還是有點用的,比如C/C++,matlab)很多都是換了個名稱而已,思想還是不變的。比如 C/C++裡面講的函數的值傳遞和引用傳遞,在pyhton這裡表述為可變對象傳遞和不可變對象傳遞。(小樣,換了個馬甲我就不認識你了?哈哈~~)

拿以前學過的java,javascript,C/C++,matlab(姑且算是一門語言吧,雖然很簡單)語法做個對比,其實各種定義思想都是大同小異的,很多只是語法的不同,即「語言特性」有所差異。

任何一種「語言」,都是各種「語言特性」的組合。

打個比方,一個程序語言就像一台電腦。它的牌子可能叫「聯想」,或者「IBM」,或者「Dell」,或者「蘋果」。那麼,你可以說蘋果一定比 IBM 好嗎?你不能。你得看看它裡面裝的是什麼型號的處理器,有多少個核,主頻多少,有多少 L1 cache,L2 cache……,有多少內存和硬碟,顯示器解析度有多大,顯卡是什麼 GPU,網卡速度,等等各種「配置」。有時候你還得看各個組件之間的兼容性。

這些配置對應到程序語言裡面,就是所謂「語言特性」。舉一些語言特性的例子:

變數定義、算術運算、for 循環語句,while 循環語句、函數定義,函數調用、遞歸

靜態類型系統、類型推導、lambda 函數、面向對象、指針算術比較blablabla……

學編程要重視語言特性,而不是語言

這些語言特性,就像你在選擇一台電腦的時候,看它裡面是什麼配置。選電腦的時候,沒有人會說 Dell 一定是最好的,他們只會說這個型號裡面裝的是 Intel 的 i7 處理器,這個比 i5 的好,DDR3 的內存 比 DDR2 的快這麼多,SSD 比磁碟快很多,ATI 的顯卡是垃圾…… 如此等等。

程序語言也是一樣的道理。

每一種語言裡面必然有一套「通用」的特性。比如變數,函數,整數和浮點數運算,等等。這些是每個通用程序語言裡面都必須有的,一個都不能少。只要通過「某種語言」學會了這些特性,掌握這些特性的根本概念,就能隨時把這些知識應用到任何其它語言。而且為此投入的時間基本不會浪費。

如果不能用一種語言裡面的基本特性寫出好的代碼,那換成另外一種語言也無濟於事。會寫出一樣差的代碼。經常看到有些人明明 Java 代碼寫得相當亂,相當糟糕,卻罵 Java 不好,雄心勃勃要換用 Go 語言。這些人沒有明白,是否能寫出好的代碼在於人,而不在於語言。如果你的心中沒有清晰簡單的思維模型,你用任何語言表述出來都是一堆亂麻。如果你 Java 代碼寫得很糟糕,那麼你寫 Go 語言代碼也會一樣糟糕,甚至更差。

編程是為解決問題而學

編程語言就是一種工具,是用來解決問題的。既然設計出那麼多種編程語言,那麼它們肯定在解決某類型問題上各有所長。不能為了學某種語言而學,要為了解決問題而學。

一個高明的程序員如果開始用一種新的程序語言,他往往不是去看這個語言的大部頭手冊或者書籍,而是先有一個需要解決的問題。手頭有了問題,他可以用兩分鐘瀏覽一下這語言的手冊,看看這語言大概長什麼樣。然後,他直接拿起一段例子代碼來開始修改搗鼓,想法把這代碼改成自己正想解決的問題。在這個簡短的過程中,他很快的掌握了這個語言,並用它表達出心裡的想法。

在這個過程中,隨著需求的出現,他可能會問這樣的問題:

這個語言的「變數定義」是什麼語法,需要「聲明類型」嗎,還是可以用「類型推導」?

它的「類型」是什麼語法?是否支持「泛型」?泛型的 「variance」 如何表達?

這個語言的「函數」是什麼語法,「函數調用」是什麼語法,可否使用「預設參數」?

……

注意到了嗎?上面每一個引號裡面的內容,都是一種語言特性(或者叫概念)。這些概念可以存在於任何的語言裡面,雖然語法可能不一樣,它們的本質都是一樣的。比如,有些語言的參數類型寫在變數前面,有些寫在後面,有些中間隔了一個冒號,有些沒有。

這些實際問題都是隨著寫實際的代碼,解決手頭的問題,自然而然帶出來的,而不是一開頭就抱著語言手冊看得仔仔細細。因為掌握了語言特性的人都知道,自己需要的特性,在任何語言裡面一定有對應的表達方式。如果沒有直接的方式表達,那麼一定有某種「繞過方式」。如果有直接的表達方式,那麼它只是語法稍微有所不同而已。所以,他是帶著問題找特性,就像查字典一樣,而不是被淹沒於大部頭的手冊裡面,昏昏欲睡一個月才開始寫代碼。

掌握了通用的語言特性,剩下的就只剩某些語言「特有」的特性了。研究語言的人都知道,要設計出新的,好的,無害的特性,是非常困難的。所以一般說來,一種好的語言,它所特有的新特性,終究不會超過一兩種。如果有個語言號稱自己有超過 5 種新特性,那就得小心了,因為它們帶來的和可能不是優勢,而是災難!

掌握關鍵語言特性,忽略次要特性

舉個誇張點的例子。發現很多編程培訓班和野雞大學的編程入門課,往往一來就教學生如何使用 printf 列印「Hello World!」,進而要他們記憶 printf 的各種「格式字元」的意義,要他們實現各種複雜格式的列印輸出,甚至要求列印到文本文件里,然後再讀出來……

可是殊不知,這種輸出輸入操作其實根本不算是語言的一部分,而且對於掌握編程的核心概念來說,都是次要的。有些人的 Java 課程進行了好幾個星期,居然還在布置各種 printf 的作業。學生寫出幾百行的 printf,卻不理解變數和函數是什麼,甚至連算術語句和循環語句都不知道怎麼用!這就是為什麼很多初學編程的人感覺編程很難,我連%d,%f,%.2f的含義都記不住,還怎麼學編程!

然而這些野雞大學的「教授」頭銜是如此的洗腦,以至於被他們教過的學生遇到不會做的題,跟有經驗的教授請教,反而罵教授凈教一些沒用的東西,學了連 printf 的作業都沒法完成 :P 你別跟我講 for 循環,函數什麼的了…… 可不可以等幾個月,等我背熟了 printf 的用法再學那些啊?

所以就會發現一旦被差勁的老師教過,這個程序員基本就毀了。就算遇到好的老師,他們也很難糾正過來。

當然這是一個誇張的例子,因為 printf 根本不算是語言特性,但這個例子從同樣的角度說明了次要膚淺的語言特性帶來的問題。

自己動手實現語言特性

完全理解一種「語言特性」最好的方法就是自己親自實現它。

只有實現了各種語言特性,才能完全地擁有它們,成為它們的主人。否則就只是它們的使用者,會被語言的設計者牽著鼻子走。

舉個例子,學習 SICP 的時候,大家都會親自用 Scheme 實現一個面向對象系統。用 Scheme 實現的面向對象系統,跟 Java,C++,Python 之類的語言語法相去甚遠,然而它卻能幫助理解任何這些 OOP 語言裡面的「面向對象」這一概念,它甚至能幫助理解各種面向對象實現的差異。

這種效果是直接學習 OOP 語言得不到的,因為在學習 Java,C++,Python 之類語言的時候,自己只是一個用戶,而用 Scheme 自己動手實現了 OO 系統之後,自己成為了一個創造者。

類似的特性還包括類型推導,類型檢查,惰性求值,如此等等。如果你實現過幾乎所有的語言特性,那麼任何語言在你的面前,都是可以被任意拆卸組裝的玩具,而不再是凌駕於你之上的神聖。

總結

寫了這麼多,都在圍繞著一個核心:語言特性.所以學習編程,應該專註於語言特性,而不是糾結於整個的「語言品牌」。只有這樣才能達到融會貫通,拿起任何語言幾乎立即就會用,並且寫出高質量的代碼。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦