什麼是算法
任何一個問題的解決方案都並非是憑空出現的,解決一個問題都需要選擇一個合適的方法,並在此方法的引導下完成一系列的解答步驟,最終將問題轉換爲結果狀態,對於計算機來說,這樣的方法就是算法。
算法有很多種分類,可以是一系列的數學計算,也可以是一系列的操作步驟,總之,它存在的意義就是爲了有針對性地解決問題,之所以強調針對性解決問題,是因爲這個世界上還沒有一種可以解決一切的萬能算法,每個問題都有它獨特的一面。
而對於這些特殊的需求,於是在這行業中出現了新的一批人,他們負責設計解決各種問題的算法。
不過也正所謂沒有最好用的,只有最合適的方案,不同的算法能夠適配的是不同的環境,就好比不同的場景也要使用不同的服務架構模式。
所以算法是什麼,答案已經出來了 => 算法就是對問題一系列的分析得出的數據進行數學建模,用程序表達出來,來解決實際遇到的問題。
學習算法的用處
我們在軟件開發的領域中,很多東西都會因爲時間的變遷而變化,編程語言也會不斷地推陳出新,各種軟件技術的更新換代更是日新月異,但是萬變之中,有一種東西是不變的,那就是算法。
數據結構,算法,計算機體系原理,遠比編程語言,軟件開發技術重要,因爲算法和數據結構被稱爲軟件的核心內容。
在現今軟件開發的領域中,技術迭代速度飛快,掌握任意一個技術都有可能在第二年被技術的潮流所沖走,而算法,是一個應用程序中不可動搖的東西,無論語言怎麼改變,算法的設計理念都是一樣的。
包括在工作中遇到的算法也往往並非是ACM那樣的題目(所以說比賽誤人子弟啊…咳),常見的問題比如說是:
- 交換機中端口和VLAN的映射關係維護 (沒聽說過…)
- 路由器帶寬限速 (也沒什麼想法…)
- …
學習算法的目的是爲了提高自己的軟件編寫,解決問題的能力,這種能力是在今後的工作或者項目開發過程中所需要展現出來的關鍵能力,換句話來說,就是:
本身學習算法,目的是培養出一套思維框架,在未來可以真正改變自己做事的思維,而不是爲了算法而學習算法,那樣只會讓自己被封閉住,最終失去了自己的彈性。
秉承着這種原則去學習算法,更應該做的是找到方法,思考算法實現的設計和分析過程,而並非是去死記硬背各種算法的實現方法,學會釣魚的方法永遠比魚更受益不是麼?
所以我們學習算法不能死記硬背各種算法的實現方法,而是通過這些算法的學習,特別是算法實現的設計和分析的過程,培養我們解決實際問題的能力,工作中遇到的問題是自己動手解決的問題,還是到處貼吧發帖子求助,它的背後就是這種能力的體現,而這種能力,籠統的來說,就是編程能力。
編程能力大致包括以下:
邏輯思維能力
抽象建模能力
編程的方法與技巧
…
編程能力的培養,不是三五天能成的,也不是死記硬背就能會的,需要的是大量的實踐(鄙人也在學繪畫…兩者感觸頗深…)
學習算法本身,有幾點是值得借鑑的:
- 是能夠比較直觀的去提升自己編程能力的方法,掌握核心思想,能夠在程序的道路中如虎添翼。
- 同樣是在寫代碼,但是在和別人思考同樣的問題的時候,就會想的更細緻些,比如時間複雜度,空間複雜度,計算效率問題的求解過程,對其它模塊的影響等等(感觸不能頗深,但有過的開發經驗告訴我還是有的)
- 我們經常會用代碼堆出來一個功能,比如用戶點擊按鈕的事件,這種流程化的動作機器也是可以做的,大量這樣的場景都是可以避免去堆代碼的
學習算法,有很多種方法,可以根據問題的類型採取不同的方法,算法被權威人士大致分爲三類,權威人士有多權威,我就不說了:
三種算法
- 已知算法 (擁有成熟且高效的實現方法的算法) => { 這類算法,除非是這個領域的從業人員或是勵志成爲該領域的專家,否則瞭解下就好,不至於工作中束手無策 }
- avl樹和紅黑樹的插入
- 刪除算法
- 二分圖匹配的匈牙利算法
- 數據壓縮
- 視頻編碼
- 編解碼算法
…
- 理論算法 (沒有固定的實現方法的算法) => { 理論中的內容是需要進行數學建模之後纔會有結果的,抽象的方法本身是需要根據場景變動而變動,結合問題的數學模型,將算法原理翻譯成算法是代碼的實現 }
- 遺傳算法
- 貝葉斯算法
- 決策樹算法
- KN分類算法
…
- 實際問題或是算法比賽中的題目 (沒有通用的答案) => { 要有對問題抽象建模的能力,轉化爲數據模型的能力,實現數據模型的能力,… } 需要堆積的算法常用模式:
- 貪婪法
- 窮舉法
- 分治法
- 動態規劃法
…
對於後兩類算法,門檻比較高,對抽象建模的能力和經驗有要求,是需要時間來沉澱出來的。
其實,開篇也就這麼多內容,所提倡的學習方法,也正是我想要學習的目的,抱着這種思想,選擇了這麼一條道路,簡單講講今日這四小時的收穫,以及未來短期的規劃和長期的規劃。
- 無論是什麼技術,都不能爲了技術而學技術,保持自己的彈性。
- 學習算法,學的是算法思想,算法之禪,在各種場景中的靈活運用。
- 雖然需要學習的是思維框架,是編程思想,但是基礎的東西還是需要掌握的,比如貪婪法,窮舉法等基本算法。
學習目標
- 完成每日的代碼案例
- 溫習一次過去寫的案例
- 每日至少一小時的思考,沉澱
- 繪製應用程序流程圖
- 每日的博客,日常總結,打卡
短期思想
- 結束第一個月每週溫習一次過去學過的所有內容
- 至少一天完成一個課後習題
- 結束第二個月每兩週溫習一次過去學過所有的內容
- 一週完成至少一個課後習題
- 結束後三個月以後,每一個月複習一次學過的所有內容,週期持續到結束後六個月
長期改變
- 重審自己的編程思想