標籤:python
從8月到12月的四個月裡,除去本來的工作,為了學習品質,我會保證平均每天4個小時的學習時間,周末也不例外。另外,所有的文檔,問答都盡量看英文的,這可以幫你剩下大量的時間。12月13日,我做的網站上線了,3天時間大概有5000人訪問了這個網站,我有時在後台看著日誌,不免有些心潮噴湧,我想把自己的經驗寫下來,希望對於那些有心學習編程但無從下手的朋友提供一些協助和鼓勵。
1. 我的自學編程之路
1)基礎
剛開始的時候,我對搭建網站一無所知。為了給自己迅速建立一個架構,我在Google上面泡了整整一天,瞭解了HTML,CSS,JavaScript,Ajax,jQuery,React,SQL,伺服器指令碼等等知識,不求精通,只是瞭解每一項技術是幹嘛的,另一方面建立起了一個學習的roadmap,這樣大概知道做一個Web App需要哪些知識,分別學習的主次順序。重點推薦兩個資源:
Python基礎知識:Learn Python the Hard Way
Web App基礎知識:@張秋怡的答案寫的通俗易懂,極力推薦。
有了這個roadmap,我明白了前端三大必須掌握技能HTML,CSS和JavaScript,花了大概10天左右把W3Schools上的教程全部過了一遍,然後試著寫了幾個網頁,感覺自己寫的很沒有底氣。於是根據知乎和豆瓣上的推薦,買了《JaveScript DOM》和《Head First HTML與CSS》,邊看書邊把例子過了一遍。
W3Schools: www.w3schools.com/
JavaScript:JavaScript DOM編程藝術
HTML & CSS : Head First HTML與CSS(第2版)
前端是需要慢慢學習的,在看完上面的資料後,雖然能寫出來一些挺漂亮的頁面,但是我自己知道很多都是不符合標準的,更不要說代碼風格什麼的。這隻能通過不斷地積累和增加代碼量來提高。由於明白伺服器端需要耗費自己大量的時間,所以在發現自己能夠按照構思勉強實現網頁之後,我就把學習中心放到了伺服器端上。不過每天還是會抽空寫一寫網頁,避免手生。
2)伺服器端
最先瞭解的是HTTP協議,也就是瀏覽器和伺服器之間是如何通訊的。也就是當你在瀏覽器裡鍵入網址按下斷行符號直到網頁顯示在你瀏覽器的這個過程中,瀏覽器和瀏覽器之間發生了什麼事情。這是很有意思的內容,我是以讀小說的心情瞭解了這部分內容。瞭解這部分後,你就會明白類似為什麼有時候會有404頁面?在百度搜尋方塊裡鍵入的搜尋字詞是如何提交到百度伺服器的?為什麼重新登入知乎的時候就不用再輸入密碼了?之類的問題了。
瞭解了HTTP協議之後,我就多少有些入迷了。看似神秘難懂的現象其實原理並不複雜,你反而會被吸引。接下來就進入到我投入時間最多的部分了——後端開發。記得當時瞭解Web開發的MVC(Model-View-Controller)模式後,有一種心血噴湧的感覺,覺得太有意思了(程式員別噴,我就是這麼沒見過世面)。
每個人的首頁都是相同的布局和風格,例如最上面的菜單搜尋欄,顏色分割,左邊顯示動態等,右邊是個人資訊等,然後具體的內容卻因人而異——每個人的頭像,名字,動態都是不一樣的。那麼知乎是如何保證每一個人看到的都是自己的首頁呢?
你可以把這個相同的布局想象成一個模板,裡面有一個個空格子,當你用你的賬戶登陸頁面時,想象你的電腦裡有無數個小人根據你的帳號從知乎背景資料庫裡取出你的頭像,動態,認證資訊等等內容,然後對應著模板上規定好的位置,把對應的內容填進去。這些小人的動作實在是太快了,以至於你覺得這是在瞬間完成的。
上面所說的模板就是MVC中的V,是View的縮寫,負責顯示。這樣做的好處在於,如果知乎有一天突然想改變一下個人首頁的風格,那麼只需要改變這一個模板,然後幾千萬註冊使用者的首頁就相應的變化了,因為模板是公用的,是不是省了很多事情?(早期的Web開發可不是這樣喲,你可能要一個個使用者去改,非常麻煩。)
而這些小人除了擺放內容,它們真正負責的是商務邏輯,我們把他們叫做Controller,也就是MVC中的C。例如當你登陸的時候,這些小人要檢查你的使用者名稱是不是準確的,如果準確,它們要去資料庫裡取出你請求的資訊等,如果使用者名稱錯誤,它們要攔截住你的登陸。它們的職責還有很多,無法一一列舉。在實際中,這些小人做的事情其實就是Python(或者其它指令碼語言)做的事情。
最後,MVC中的Model其實就是傳給View的資料,包括上面的頭像,使用者名稱,動態等因人而異的資料。這些資料在知乎伺服器上是以資料庫表格(table)的形式存在的,你可以把它們想象成很多不同的excel表格,不同的表格儲存著不同的資訊,有些記錄著知乎使用者的個人資訊,有些記錄著回答,有些記錄著評論等等,而這些表格之間又彼此聯絡,當你在知乎的不同網頁間跳轉的時候,上面說的那些小人就根據你的要求,組合對應的表格取出對應的資料,然後把他們放到模板對應的空格裡,發送給瀏覽器。然後瀏覽器根據你寫的CSS,用不同的顏色,大小等等,將資料很漂亮的顯示出來。
這樣做的好處是什麼呢?雖然你最終在瀏覽器裡看到的是一個完整的頁面,但是在後端邏輯上它們都是區分開的——模型(M),視圖(V)和控制器(C)的區分就保證了較高的可維護性——我可以隨時修改首頁的顯示並看到效果,同樣我可以隨時加入一些商務邏輯。
如果你的學習堅持到這裡了,首先要恭喜你。其次你可能已經知道一些非常成熟的Python Web架構了,例如Django,Flask等等,並且你可能看到了很多小白教程教你直接使用,畢竟大部分人可能覺得沒有必要重複造輪子。
本來為了省事,我也打算直接用架構。我是在設計資料庫的時候,當時在看SQLAlchemy文檔,覺得相對自己的項目SQLAlchemy太過複雜,所以我決定自己寫自己的ORM(名詞不懂沒關係),這對於當時的我來說是一件難度非常大的事情。於是我投入了極大的精力每天都在看關於SQL和Python相關的教程和資料,Python核心編程(第二版) 給了我很大的啟發。在自己完成了ORM後,又寫了URL處理函數,同樣沒有用任何現成的Web架構。
現在回頭看,我認為這一段時間的造輪子是提升編程能力最快的時候。比如為了寫ORM,就必須去花很多時間學習SQL,去瞭解Python裡面的metaclass,而如果用一個現成的架構,我很有可能偷懶不去關注某些細節。而不出問題還好,一旦出問題,我就只能跪。另外,造輪子迫使我在開始的時候就構思整個架構,因為我必須儘可能的考慮到所有的情況,於是就會不斷的強迫自己完善知識體系,和別人的代碼作對比從而改進自己的,這個過程充滿了無盡的挫敗感,但是得來的成就和快樂也是無可比擬的。
SQL書籍:Sams Teach Yourself MySQL in 21 Days
Python:Python核心編程(第二版)
Github上的優質Python資源:CodementorIO/Python-Learning-Resources
過程中還牽涉到部署,我的網站是跑在Linux上的。關於部署網上有非常多的優質教程,一搜一大把。這裡就不再贅述。
這些是我學習大致路線,當然過程中充滿著小的磕磕絆絆,雖然網站上線了,貌似運行還比較順利,但是如果以一個程式員的標準來要求自己,自己依然非常菜鳥。不過我並沒有以前那樣懼怕技術了,就像你明白魔術的背後的原理後,會更多的思考原理本身。
2. 自學編程需要注意的問題
很多人都推薦小白第一門語言選Python,因為文法簡單。這句話只說了一半,Python確實容易上手,對初學者的門檻很低。但我發現,對於小白真正的門檻在於系統知識,這就和用什麼語言完全沒有任何關係了。例如很多人學完了Python的文法,覺得確實簡單,但是轉頭去用Python標準庫的時候,卻發現自己連文檔都看不懂。標準庫提供了Python和其它系統功能的介面,最終實現了Python和系統之間的互動。讀標準庫需要系統知識,比如作業系統,資料庫,進程和線程,socket編程,網路通訊協定等等,這些對於編程小白來才構成很高的門檻,但是只有學會這些,才能真正發揮出Python的威力來。
這也是我覺得自己的經曆對小白是有價值的一個原因。因為設計一個動態網頁是一個很不錯的練手Project。建立網頁(Web App)會逼迫你瞭解從你在瀏覽器裡鍵入地址按下斷行符號到網頁顯示在瀏覽器的過程中,瀏覽器,網路,伺服器都幹了些什麼。具體到技術上面,你不得不去學習前端的HTML,CSS和JavaScript,後端的指令碼,資料庫,作業系統等。也就是說,這個過程能夠促使你去主動學習上面提到的系統知識,如果你再做另外一個項目,你就不會像現在這樣無從下手,而有能力去進行一些技術性的探討,所以我認為這是一個非常好的練手項目。
1)一定要空出時間補充理論知識
很多人會強調learn by doing,邊做項目邊學習,這也是我自己採用的方式。在這種方式中,你不斷犯錯,改正……學習效率非常高。但是,很多人走了極端,最後的結果就是不注意理論知識的學習。你會發現自己Google的能力越來越高,但是真實的編程能力並沒有得到提升。如果有這種情況,你需要反思一下。
一種可能是你太過於依賴各種成熟的架構,結果編程就變成了用「膠水」去粘合不同的架構完成需求。就好比你的Web App用了SQLAlchemy,雖然自己不太懂SQL,但是網站跑的也還不錯。這時候如果資料庫出現了問題,那你就只能跪了。
另外一種可能是你完全沉浸在做項目中,忽略了學習理論知識。做項目雖然充滿困難,但回報是強烈的成就感,很容易沉浸其中。我覺得這是極其錯誤的。首先半路出家的程式員都沒有經過系統的學習,沒有形成自己的知識體系,如果你不懂資料結構,演算法複雜度,作業系統這些理論,那麼你能達到的高度就極其有限。所以,在每天做項目的同時,一定要保證抽出一定的時間,惡補理論知識。這部分的書單在豆瓣和知乎上都有很多總結,可以自行搜尋。
2)不要太糾結於無意義的問題,比如什麼架構好,XX語言比XX語言好啦這種問題。前期確定了練手項目,就去專心積累代碼量,積累基礎知識。那些你現在還看不懂的炫酷技術你慢慢也就能明白是怎麼回事了,反而沒有基礎,再炫酷的架構對你而言都是天書。
3)學會發問。好問題是建立在你自己已經實踐或者思考的基礎上問出來的,這是對自己的負責,也是對別人的尊重。不要一遇到困難就喜歡直接上網搜尋:「這個問題是怎麼回事啊?」,「我不明白你能不能幫我看看……」。
4)學好英語。
如何系統地自學 Python?