理智的選擇仍是在一條路上不斷摸索。理想是把整個計算機體系搞懂。2017/12/05
http://coolshell.cn/articles/4990.html
月光博客6月12日發表了《寫給新手程序員的一封信》,翻譯自《An open letter to those who want to start programming》,個人朋友(他在本站的id是Mailper)告訴我,他但願在酷殼上看到一篇更具操做性的文章。由於他也是喜歡編程和技術的傢伙,因而,我讓他把他的一些學習Python和Web編程的一些點滴總結一下。因而他給我發來了一些他的心得和經歷,我在把他的心得作了很少的增改,並根據個人經歷增長了「進階」一節。這是一篇由新手和我這個老傢伙根據咱們的經歷完成的文章。javascript
個人這個朋友把這篇文章取名叫Build Your Programming Technical Skills,我實在不知道用中文怎麼翻譯,但我在寫的過程當中,我以爲這很像一個打網遊作任務升級的一個過程,因此取名叫「技術練級攻略」,題目有點大,呵呵,這個標題純粹是爲了好玩。這裏僅僅是在分享Mailper和我我的的學習經歷。(注:省去了我做爲一個初學者曾經學習過的一些技術(今天明顯過期了),如:Delphi/Power builder,也省去了我學過的一些我以爲沒意思的技術Lotus Notes/ActiveX/COM/ADO/ATL/.NET ……)php
前言
你是否以爲本身從學校畢業的時候只作太小玩具同樣的程序?走入職場後哪怕沒有什麼經驗也能夠把如下這些課外練習走一遍(朋友的抱怨:學校課程老是從理論出發,做業項目都看不出有什麼實際做用,不如從工做中的需求出發)html
建議:前端
- 不要亂買書,不要亂追新技術新名詞,基礎的東西通過很長時間積累並且還會在將來至少10年通用。
- 回顧一下歷史,看看歷史上時間線上技術的發展,你才能明白明天會是什麼樣。
- 必定要動手,例子無論多麼簡單,建議至少本身手敲一遍看看是否理解了裏頭的細枝末節。
- 必定要學會思考,思考爲何要這樣,而不是那樣。還要觸類旁通地思考。
注:你也許會很奇怪爲何下面的東西很偏Unix/Linux,這是由於我以爲Windows下的編程可能會在將來很沒有前途,緣由以下:java
- 如今的用戶界面幾乎被兩個東西主宰了,1)Web,2)移動設備iOS或Android。Windows的圖形界面不吃香了。
- 愈來愈多的企業在用成本低性能高的Linux和各類開源技術來構架其系統,Windows的成本過高了。
- 微軟的東西變得太快了,很不持久,他們徹底是在玩弄程序員。詳情參見《Windows編程革命史》
因此,我我的認爲之後的趨勢是前端是Web+移動,後端是Linux+開源。開發這邊基本上沒Windows什麼事。python
啓蒙入門
一、 學習一門腳本語言,例如Python/Rubylinux
可讓你擺脫對底層語言的恐懼感,腳本語言可讓你很快開發出能用得上的小程序。實踐項目:nginx
- 處理文本文件,或者csv (關鍵詞 python csv, python open, python sys) 讀一個本地文件,逐行處理(例如 word count,或者處理log)
- 遍歷本地文件系統 (sys, os, path),例如寫一個程序統計一個目錄下全部文件大小並按各類條件排序並保存結果
- 跟數據庫打交道 (python sqlite),寫一個小腳本統計數據庫裏條目數量
- 學會用各類print之類簡單粗暴的方式進行調試
- 學會用Google (phrase, domain, use reader to follow tech blogs)
爲何要學腳本語言,由於他們實在是太方便了,不少時候咱們須要寫點小工具或是腳原本幫咱們解決問題,你就會發現正規的編程語言太難用了。程序員
二、 用熟一種程序員的編輯器(不是IDE) 和一些基本工具web
- Vim / Emacs / Notepad++,學會如何配置代碼補全,外觀,外部命令等。
- Source Insight (或 ctag)
使用這些東西不是爲了Cool,而是這些編輯器在查看、修改代碼/配置文章/日誌會更快更有效率。
三、 熟悉Unix/Linux Shell和常見的命令行
- 若是你用windows,至少學會用虛擬機裏的linux, vmware player是免費的,裝個Ubuntu吧
- 必定要少用少用圖形界面。
- 學會使用man來查看幫助
- 文件系統結構和基本操做 ls/chmod/chown/rm/find/ln/cat/mount/mkdir/tar/gzip …
- 學會使用一些文本操做命令 sed/awk/grep/tail/less/more …
- 學會使用一些管理命令 ps/top/lsof/netstat/kill/tcpdump/iptables/dd…
- 瞭解/etc目錄下的各類配置文章,學會查看/var/log下的系統日誌,以及/proc下的系統運行信息
- 瞭解正則表達式,使用正則表達式來查找文件。
對於程序員來講Unix/Linux比Windows簡單多了。(參看我四年前CSDN的博文《其實Unix很簡單》)學會使用Unix/Linux你會發現圖形界面在某些時候實在是太難用了,至關地至關地下降工做效率。
四、 學習Web基礎(HTML/CSS/JS) + 服務器端技術 (LAMP)
將來必然是Web的世界,學習WEB基礎的最佳網站是W3School。
- 學習HTML基本語法
- 學習CSS如何選中HTML元素並應用一些基本樣式(關鍵詞:box model)
- 學會用 Firefox + Firebug 或 chrome 查看你以爲很炫的網頁結構,並動態修改。
- 學習使用Javascript操縱HTML元件。理解DOM和動態網頁(http://oreilly.com/catalog/9780596527402) 網上有免費的章節,足夠用了。或參看DOM 。
- 學會用 Firefox + Firebug 或 chrome 調試Javascript代碼(設置斷點,查看變量,性能,控制檯等)
- 在一臺機器上配置Apache 或 Nginx
- 學習PHP,讓後臺PHP和前臺HTML進行數據交互,對服務器相應瀏覽器請求造成初步認識。實現一個表單提交和反顯的功能。
- 把PHP鏈接本地或者遠程數據庫 MySQL(MySQL 和 SQL現學現用夠了)
- 跟完一個名校的網絡編程課程(例如:http://www.stanford.edu/~ouster/cgi-bin/cs142-fall10/index.php ) 不要以爲須要多於一學期時間,大學生是全職一學期選3-5門課,你業餘時間必定能夠跟上
- 學習一個javascript庫(例如jQuery 或 ExtJS)+ Ajax (異步讀入一個服務器端圖片或者數據庫內容)+JSON數據格式。
- HTTP: The Definitive Guide 讀完前4章你就明白你天天上網用瀏覽器的時候發生的事情了(proxy, gateway, browsers)
- 作個小網站(例如:一個小的留言板,支持用戶登陸,Cookie/Session,增、刪、改、查,上傳圖片附件,分頁顯示)
- 買個域名,租個空間,作個本身的網站。
進階加深
一、 C語言和操做系統調用
- 從新學C語言,理解指針和內存模型,用C語言實現一下各類經典的算法和數據結構。推薦《計算機程序設計藝術》、《算法導論》和《編程珠璣》。
- 學習(麻省理工免費課程)計算機科學和編程導論
- 學習(麻省理工免費課程)C語言內存管理
- 學習Unix/Linux系統調用(Unix高級環境編程),,瞭解系統層面的東西。
- 用這些系統知識操做一下文件系統,用戶(實現一個能夠拷貝目錄樹的小程序)
- 用fork/wait/waitpid寫一個多進程的程序,用pthread寫一個多線程帶同步或互斥的程序。多進程多進程購票的程序。
- 用signal/kill/raise/alarm/pause/sigprocmask實現一個多進程間的信號量通訊的程序。
- 學會使用gcc和gdb來編程和調試程序(參看個人《用gdb調試程序》)
- 學會使用makefile來編譯程序。(參看個人《跟我一塊兒寫makefile》)
- IPC和Socket的東西能夠放到高級中來實踐。
- 學習Windows SDK編程(Windows 程序設計 ,MFC程序設計)
- 寫一個窗口,瞭解WinMain/WinProcedure,以及Windows的消息機制。
- 寫一些程序來操做Windows SDK中的資源文件或是各類圖形控件,以及做圖的編程。
- 學習如何使用MSDN查看相關的SDK函數,各類WM_消息以及一些例程。
- 這本書中有不少例程,在實踐中請不要照抄,試着本身寫一個本身的例程。
- 不用太多於精通這些東西,由於GUI正在被Web取代,主要是瞭解一下Windows 圖形界面的編程。@virushuo 說:「 我以爲GUI確實不那麼熱門了,但充分理解GUI工做原理是很重要的。包括移動設備開發,若是沒有基礎知識仍然很吃力。或者說移動設備開發必須理解GUI工做,或者在win那邊學,或者在mac/iOS上學」。
二、學習Java
- Java 的學習主要是看經典的Core Java 《Java 核心技術編程》和《Java編程思想》(有兩卷,我僅鏈了第一卷,足夠了,由於Java的圖形界面瞭解就能夠了)
- 學習JDK,學會查閱Java API Doc http://download.oracle.com/javase/6/docs/api/
- 瞭解一下Java這種虛擬機語言和C和Python語言在編譯和執行上的差異。從C、Java、Python思考一下「跨平臺」這種技術。
- 學會使用IDE Eclipse,使用Eclipse 編譯,調試和開發Java程序。
- 建一個Tomcat的網站,嘗試一下JSP/Servlet/JDBC/MySQL的Web開發。把前面所說的那個PHP的小項目試着用JSP和Servlet實現一下。
三、Web的安全與架構
- 學習HTML5,網上有不少不少教程,之前酷殼也介紹過不少,我在這裏就不羅列了。
- 學習Web開發的安全問題(參考新浪微博被攻擊的這個事,以及Ruby的這篇文章)
- 學習HTTP Server的rewrite機制,Nginx的反向代理機制,fast-cgi(如:PHP-FPM)
- 學習Web的靜態頁面緩存技術。
- 學習Web的異步工做流處理,數據Cache,數據分區,負載均衡,水平擴展的構架。
- 實踐任務:
- 使用HTML5的canvas 製做一些Web動畫。
- 嘗試在前面開發過的那個Web應用中進行SQL注入,JS注入,以及XSS攻擊。
- 把前面開發過的那個Web應用改爲構造在Nginx + PHP-FPM + 靜態頁面緩存的網站
四、學習關係型數據庫
- 你能夠安裝MSSQLServer或MySQL來學習數據庫。
- 學習教科書裏數據庫設計的那幾個範式,1NF,2NF,3NF,……
- 學習數據庫的存過,觸發器,視圖,建索引,遊標等。
- 學習SQL語句,明白錶鏈接的各類概念(參看《SQL Join的圖示》)
- 學習如何優化數據庫查詢(參看《MySQL的優化》)
- 實踐任務:設計一個論壇的數據庫,至少知足3NF,使用SQL語句查詢本週,本月的最新文章,評論最多的文章,最活躍用戶。
五、一些開發工具
- 學會使用SVN或Git來管理程序版本。
- 學會使用JUnit來對Java進行單元測試。
- 學習C語言和Java語言的coding standard 或 coding guideline。(我N年前寫過一篇關C語言很是簡單的文章——《編程修養》,這樣的東西你能夠上網查一下,一大堆)。
- 推薦閱讀《代碼大全》《重構》《代碼整潔之道》
高級深刻
一、C++ / Java 和麪向對象
我我的覺得學好C++,Java也就是舉手之勞。可是C++的學習曲線至關的陡。不過,我以爲C++是最須要學好的語言了。參看兩篇趣文「C++學習信心圖」 和「21天學好C++」
- 學習(麻省理工免費課程)C++面向對象編程
- 讀個人 「如何學好C++」中所推薦的那些書至少兩遍以上(若是你對C++的理解可以深刻到像我所寫的《C++虛函數表解析》或是《C++對象內存存局》,或是《C/C++返回內部靜態成員的陷阱》那就很是不錯了)
- 而後反思爲何C++要幹成這樣,Java則不是?你必定要學會對比C++和Java的不一樣。好比,Java中的初始化,垃圾回收,接口,異常,虛函數,等等。
- 實踐任務:《設計模式》必需一讀,兩遍以上,思考一下,這23個模式的應用場景。主要是兩點:1)鍾愛組合而不是繼承,2)鍾愛接口而不是實現。(也推薦《深刻淺出設計模式》)
- 用C++實現一個BigInt,支持128位的整形的加減乘除的操做。
- 用C++封裝一個數據結構的容量,好比hash table。
- 用C++封裝並實現一個智能指針(必定要使用模板)。
- 實踐任務:學習STL的用法和其設計概念 – 容器,算法,迭代器,函數子。若是可能,請讀一下其源碼。
- 使用工廠模式實現一個內存池。
- 使用策略模式製作一個類其能夠把文本文件進行左對齊,右對齊和中對齊。
- 使用命令模式實現一個命令行計算器,並支持undo和redo。
- 使用修飾模式實現一個酒店的房間價格定價策略——旺季,服務,VIP、旅行團、等影響價格的因素。
- 實踐任務:嘗試使用面向對象、STL,設計模式、和WindowsSDK圖形編程的各類技能學習C++的一些類庫的設計,如: MFC(看看候捷老師的《深刻淺出MFC》) ,Boost, ACE, CPPUnit,STL (STL可能會太難了,可是若是你能瞭解其中的設計模式和設計那就太好了,若是你能深刻到我寫的《STL string類的寫時拷貝技術》那就很是不錯了,ACE須要很強在的系統知識,參見後面的「增強對系統的瞭解」)
- 作一個貪吃蛇或是俄羅斯方塊的遊戲。支持不一樣的級別和難度。
- 作一個文件瀏覽器,能夠瀏覽目錄下的文件,並能夠對不一樣的文件有不一樣的操做,文本文件能夠打開編輯,執行文件則執行之,mp3或avi文件能夠播放,圖片文件能夠展現圖片。
- Java是真正的面向對象的語言,Java的設計模式多得不能再多,也是用來學習面向對象的設計模式的最佳語言了(參看Java中的設計模式)。
- 推薦閱讀《Effective Java》 and 《Java解惑》
- 學習Java的框架,Java的框架也是多,如Spring, Hibernate,Struts 等等,主要是學習Java的設計,如IoC等。
- Java的技術也是爛多,重點學習J2EE架構以及JMS, RMI, 等消息傳遞和遠程調用的技術。
- 學習使用Java作Web Service (官方教程在這裏)
- 實踐任務: 嘗試在Spring或Hibernate框架下構建一個有網絡的Web Service的遠程調用程序,並能夠在兩個Service中經過JMS傳遞消息。
C++和Java都不是能在短期內能學好的,C++玩是的深,Java玩的是廣,我建議二者選一個。我我的的學習經歷是:
- 深究C++(我深究C/C++了十來年了)
- 學習Java的各類設計模式。
二、增強系統瞭解
重要閱讀下面的幾本書:
- 《Unix編程藝術》瞭解Unix系統領域中的設計和開發哲學、思想文化體系、原則與經驗。你必定會有一種醍醐灌頂的感受。
- 《Unix網絡編程卷1,套接字》這是一本看完你就明白網絡編程的書。重要注意TCP、UDP,以及多路複用的系統調用select/poll/epoll的差異。
- 《TCP/IP詳解 卷1:協議》- 這是一本看完後你就能夠當網絡黑客的書。瞭解以太網的的運做原理,瞭解TCP/IP的協議,運做原理以及如何TCP的調優。
- 實踐任務:《Unix網絡編程卷2,進程間通訊》信號量,管道,共享內存,消息等各類IPC…… 這些技術好像有點老掉牙了,不過仍是值得了解。
- 理解什麼是阻塞(同步IO),非阻塞(異步IO),多路複用(select, poll, epoll)的IO技術。
- 寫一個網絡聊天程序,有聊天服務器和多個聊天客戶端(服務端用UDP對部分或全部的的聊天客戶端進Multicast或Broadcast)。
- 寫一個簡易的HTTP服務器。
- 實踐任務:學習《Windows核心編程》一書。把CreateProcess,Windows線程、線程調度、線程同步(Event, 信號量,互斥量)、異步I/O,內存管理,DLL,這幾大塊搞精通。
- 主要實踐各類IPC進程序通訊的方法。
- 嘗試寫一個管道程序,父子進程經過管道交換數據。
- 嘗試寫一個共享內存的程序,兩個進程經過共享內存交換一個C的結構體數組。
- 實踐任務:使用CreateProcess啓動一個記事本或IE,並監控該程序的運行。把前面寫過的那個簡易的HTTP服務用線程池實現一下。寫一個DLL的鉤子程序監控指定窗口的關閉事件,或是記錄某個窗口的按鍵。
- 有了多線程、多進程通訊,TCP/IP,套接字,C++和設計模式的基本,你能夠研究一下ACE了。使用ACE重寫上述的聊天程序和HTTP服務器(帶線程池)
- 實踐任務:經過以上的全部知識,嘗試
- 寫一個服務端給客戶端傳大文件,要求把100M的帶寬用到80%以上。(注意,磁盤I/O和網絡I/O可能會頗有問題,想想怎麼解決,另外,請注意網絡傳輸最大單元MTU)
- 瞭解BT下載的工做原理,用多進程的方式模擬BT下載的原理。
三、系統架構
- 負載均衡。HASH式的,純動態式的。(能夠到Google學術裏搜一些關於負載均衡的文章讀讀)
- 多層分佈式系統 – 客戶端服務結點層、計算結點層、數據cache層,數據層。J2EE是經典的多層結構。
- CDN系統 – 就近訪問,內容邊緣化。
- P2P式系統,研究一下BT和電驢的算法。好比:DHT算法。
- 服務器備份,雙機備份系統(Live-Standby和Live-Live系統),兩臺機器如何經過心跳監測對方?集羣主結點備份。
- 虛擬化技術,使用這個技術,能夠把操做系統當應用程序一下切換或從新配置和部署。
- 學習Thrift,二進制的高性能的通信中間件,支持數據(對象)序列化和多種類型的RPC服務。
- 學習Hadoop。Hadoop框架中最核心的設計就是:MapReduce和HDFS。MapReduce的思想是由Google的一篇論文所說起而被廣爲流傳的,簡單的一句話解釋MapReduce就是「任務的分解與結果的彙總」。HDFS是Hadoop分佈式文件系統(Hadoop Distributed File System)的縮寫,爲分佈式計算存儲提供了底層支持。
- 瞭解NoSQL數據庫(有人說多是一個過渡炒做的技術),不過由於超大規模以及高併發的純動態型網站日漸成爲主流,而SNS類網站在數據存取過程當中有着實時性等剛性需求,這使得目前NoSQL數據庫慢慢成了人們所關注的焦點,並大有成爲取代關係型數據庫而成爲將來主流數據存儲模式的趨勢。當前NoSQL數據庫不少,大部分都是開源的,其中比較知名的有:MemcacheDB、Redis、Tokyo Cabinet(升級版爲Kyoto Cabinet)、Flare、MongoDB、CouchDB、Cassandra、Voldemort等。
寫了那麼多,回顧一下,以爲本身至關的有成就感。但願你們不要嚇着,我本身這十來年也在不斷地學習,今天我也在學習中,人生原本就是一個不斷學習和練級的過程。不過,必定有漏的,也有不對的,還但願你們補充和更正。(我會根據你們的反饋隨時更新此文)歡迎你們經過個人微博(@左耳朵耗子)和twitter(@haoel)和我交流。
—– 更新 2011/07/19 —–
1)有朋友奇怪爲何我在這篇文章開頭說了web+移動,卻沒有在後面提到iOS/Android的前端開發。由於我內心有一種感受,移動設備上的UI最終也會被Javascript取代。你們能夠用iPhone或Android看看google+,你就會明白了。
2)有朋友說我這裏的東西太多了,不能爲了學習而學習,我很是贊成。我在文章的前面也說了要思考。另外,千萬不要覺得我說的這些東西是一些新的技術,這份攻略裏95%以上的全是基礎。並且都是久經考驗的基礎技術。便是可讓你一通百通的技術,也是可讓你找到一份不錯工做的技術。
3)有朋友說學這些東西學完都40了,還不如想一想怎麼去掙錢。我想告訴你們,一是我今年尚未40歲,二是學無止境啊,三是我不以爲掙錢有多難,難的是怎麼讓你值那麼多錢?不管是打工仍是創業,是什麼東西讓你本身的價值,讓你公司的價值更值錢?別的地方我不敢說,對於互聯網或IT公司來講,技術實力絕對是其中之一。
4)有朋友說技術都是工具,不該該如此癡迷這句話沒有錯,有時候咱們須要更多的是擡起頭來看看技術之外的事情,或者是說咱們在做技術的時候不去思考爲何會有這個技術,爲何不是別的,問題不在於技術,問題在於咱們死讀書,讀死書,成了技術的書呆子。
5) 對於NoSQL,最近比較火,但我對其有點保守,因此,我只是說了解就能夠。對於Hadoop,我以爲其在分佈式系統上有巨大的潛力,因此須要學習。 對於關係型數據庫,的確是很重要的東西,這點是個人疏忽,在原文裏補充。
(全文完,轉載時請註明做者和出處)