http://blog.csdn.net/midgard/article/details/4084884
今天實在是頭腦不聽使喚了,沒力氣看書,寫代碼了。寫點總結吧。
都說算法是內功,究竟練到什么程度才算修成了呢?
為什么要學習,強化算法?
首先強調的是,下面的原因均是建立在算法熟練到一定程度后的效果。不熟的話,未見得能達到效果。這些原因很現實。但很多程序員卻不知道或不以為然。
-
比較世俗的方面,頂級軟件公司筆試,面試會問到。別說你不想去谷歌,百度,微軟,如果真的沒想過,我希望你能想想自己是否具備進入的實力。如果還是沒興趣想,那就忘了這條,看看下面的原因吧。
-
如果算法熟練,能顯著提高看代碼的速度,越是工作久了,越會發現很多時候是在讀別人寫的代碼,然后在其基礎上追加功能,或修改bug。所以這是很現實的技能。
- 算法操練上手快,注意只是快,但不見得容易。因為練習省去了界面等操作,只利用編譯器最基本的功能,非常適合初學者,編程環境不十分熟練的人來學習,別小看這一點,這能讓你不論在家,在同學的電腦上,甚至在網吧,只要你想操練都是能迅速找到辦法寫程序實現的。
-
難學,有區分度,正因為難,屬于內功級別的學習,不是工具型的學習,所以她經久不衰,這項技能能讓你不論什么時候都能作為一個亮點技能展示,并運用。比如眼下學python的人不少,但如果再出現更進步,高效的語言,而且這是完全有可能的,又需要重新學習,那什么才是被各種紛繁語言覆蓋的,能讓你擁有后在短時間能適應任何語言層面的轉換工作,更為通用的技能呢?無疑,數據結構+算法是其中一個,而且是非常重要的一項技能。而更為重要的是,算法這種技能,最實實在在的在于他的優勢持久性,周圍的人如果沒有經過大量算法編碼訓練,只是看過書寫過簡單算法的人是很難短期內超越你的。也就是說,這項技能越高越能保證你的能力、水平在社會上具有唯一性。即:稀缺人才。
-
很多簡單的UI操作,短期培訓班出來的照著做也能做出來很炫的效果,要佩服微軟的封裝工作,把UI設計大大簡化了。
-
對編程語言的基本功能會得到大量強化,比如操作符重載,數組,指針的運用,類的構建,對字符串的操作,以及STL,泛型的理解、運用。這里我想你應該看到了學習算法的過程是如何與計算機應用建立起了聯系,因為你肯定在寫程序時無數次與這些內容打交道,當然,不深入學習算法,也同樣可以獲得這些知識,而且.NET,Java,已經封裝了非常多的這類基礎操作,使得字符串處理變得容易多了。這就要看你的風格,需求了。這里我只是介紹深入學習算法能帶來的好處,至于不深入學習有沒有壞處,我不做評價。注意"深入"二字的修飾作用,如果沒學過基本的數據結構,甚至數組、鏈表都沒搞懂區別的話,那做程序員一定是不行的。遲早會遇到瓶頸,而且很快。
-
提供了足夠的可擴展空間。對計算機科學的深層研究必備武器,比如操作系統,搜索引擎,編譯器等等。要分析linux源代碼,會發現,操作系統在內存管理,進程,線程管理,文件管理,協議棧中,運用了大量算法實現,如果基本算法都不理解,甚至不知道,很難說分析源代碼能有多深入。因為看不懂啊。這時會有種遇到瓶頸的感覺。類似玩勁樂團的人,玩到一定程度,眼睛能跟上,但手速跟不上了。
- 注意,算法雖然是內功,但不是全部,還有很多知識是非常重要的,值得學習的,跟算法關系不太大的。比如設計模式,面向對象思想。所以算法學習到什么程度,自己酌情處理。畢竟越深入,會發現數學知識可能遇到瓶頸,但我想大多數人,只要不是搞科學研究,是不必深入到寫龍格-庫塔,FFT等算法的地步的。
- 總之深入學習算法的目的,對于程序員來說,是為了提高編程效率,提高解決問題的效率,能達到需要算法時,自己實現或找來能用的算法,很容易的嵌入到自己的程序中即可。
說說自己的學習,和強化路線吧,考慮到自己年事已高(28),相比之下算法,數據結構基礎未見得比少數玩ACM的大一(18)學生強。
自信一點!如果真的多數大一學生比我強,那確實沒法混了,轉行的時候到了。呵呵。
當然不能妄自菲薄,要相信自己有這個學習能力,有這個潛質。相信自己的數學基礎足夠用,這點要感謝中國對中小學數學教育普及的深啊,
況且我也一直是數學方面的優等生。同時自己的編碼,學習經驗也將是事半功倍的最大幫助。
對內存的分析,編譯器的使用,代碼的細節,操作系統的運作原理等知識的理解都要好于大一學生。
雖然意識有點晚,但我看好這項技能,并希望擁有她,而且相信我可以通過努力實現目標。
先定目標:
1 通過練習算法,提高分析問題,利用計算機解決問題的能力。
2 提高讀代碼,發現問題的能力。
3 提高對C++,C#等語言的運用能力,如STL的應用。C++各種語法細節的理解。
方法:練習+看書+做題+實戰。
1. 練習常用數據結構,算法的實現,如,鏈表,隊列,二叉樹,排序,圖等。以及下面說的第一階段內容。
要求代碼實現,用C,C++,C#均可,還要能用STL實現。總之,越熟越好。能盲打最高境界了。到這個程度,算法內功對我來說,應付各種工作都足夠用了。
2. 不斷重新看數據結構,算法的講解,從中更深刻的理解每種算法的核心思想。
3. 練習常用算法,看書,很容易過度訓練,然后惡心。一個容易激發熱情的方式是做題,ACM,topcoder等平臺,都有良好的積分評級政策。還有就是筆試題。這個只在處于找工作期間有很大動力。
沒看到ACM題庫中又多了一個綠色的對號,自己的blog又多了些人來訪問,等級提高都會有一種潛在的成就感,榮譽感萌發。這些虛擬的等級就是源動力。
4. 寫總結,1,2,3如果都不能激發你的潛在興趣了,實在編惡心了,那就把感受,辛酸苦辣,收獲寫出來與大伙分享吧。同時也是對自己的過去進行回憶,發現自己的進步之處。
不斷給自己找出新的理由去繼續學習。最重要的,這也是一個知識儲備,構建自己的knowledge base的過程。對你未來的工作絕對是最寶貴,熟悉的財富。
比如,萬一你將來夠牛了,想出書了,這些一點一滴的積累過程將是再好不過的素材了。
量化目標:
我一向認為能將質變效果量化了是一種很好的創新方式。因為他提供了一條完成的路。而且符合現代人,現代社會的價值觀。
功成名就,無可厚非,這是一個大好的結果,如果辦到,是千萬老百姓都在尋找的答案。可惜每個成功人事的路都無法得到復制。
新東方老師曾問在做的學生,想GRE取得高分,拿獎學金么? 當然想。
答案:熟背2萬英語單詞,得2萬美刀,背的過程中去想1個單詞就是1刀,全部完成后才能兌現。
這個例子在我印象中很多年,一直是我認為將質變量化的最為典型,貼切的例子。
理想,夢想,高薪,富足生活,都可以看作一種質變,而努力奮斗的生活就是量化的過程。不同的是有人提前知道路在哪里,有人走著走著才知道。
有人雖然知道路,但怕黑怕孤獨不愿走,有人堅持下去了,走到了最后;有人走著走著發現走錯路了,有人走著走著慶幸的發現走對路了。
很難說,哪條路好走,哪條路是對的, 相比之下我更傾向于能看到結果的路,這可能就是老人說的,要有個奔頭吧。
1 TopCoder上250的題目(包括讀題),曾有個人說20分鐘能搞定去Google不成問題。我試過些,包括讀題還是比較有難度,所以現實點吧:30分鐘內搞定。
2 做完500 ACM題目。
3 如果能做到1,2相信算法能力已經有小小質變了。再加個基礎要求吧,對于常用算法能40分鐘內在紙上完成代碼。
另外轉一個網上的評述:
一般要做到50行以內的程序不用調試、100行以內的二分鐘內調試成功.acm主要是考算法的,
主要時間是花在思考算法上,不是花在寫程序與debug上。
下面給個計劃你練練:
第一階段:練經典常用算法,下面的每個算法給我打上十到二十遍,同時自己精簡代碼,因為太常用,所以要練到寫時不用想,10-15分鐘內打完,甚至關掉顯示器都可以把程序打出來.
1.最短路(Floyd、Dijstra,BellmanFord)
2.最小生成樹(先寫個prim,kruscal要用并查集,不好寫)
3.大數(高精度)加減乘除
4.二分查找. (代碼可在五行以內)
5.叉乘、判線段相交、然后寫個凸包.
6.BFS、DFS,同時熟練hash表(要熟,要靈活,代碼要簡)
7.數學上的有:輾轉相除(兩行內),線段交點、多角形面積公式.
8. 調用系統的qsort, 技巧很多,慢慢掌握。
9. 任意進制間的轉換
第二階段:練習復雜一點,但也較常用的算法。
如:
1. 二分圖匹配(匈牙利),最小路徑覆蓋
2. 網絡流,最小費用流。
3. 線段樹.
4. 并查集。
5. 熟悉動態規劃的各個典型:LCS、最長遞增子串、三角剖分、記憶化dp
6. 博弈類算法。博弈樹,二進制法等。
7. 最大團,最大獨立集。
8. 判斷點在多邊形內。
9. 差分約束系統.
10. 雙向廣度搜索、A*算法,最小耗散優先.
時間:
人都是總結,展望容易,靠想靠說當然容易些,尤其是技術人員。真的去做,去完成卻是最難的。所以上面說了一大堆,真正最后能實現多少,都是未知數。定些計劃,往往能激發自己去完成,如果再把這個計劃公開,那就更能加上點督促的力量。2-3年吧,是個比較合理的估計,那時工作也快滿5年了。應該有一定積累了,也是質變的時候了。