9.5 用算法和数学奠定专业基础——《逆袭大学》连载
返回到【全文目錄】
目錄
9.5?用算法和數學奠定專業基礎
算法有大用
抓住算法,打造核心競爭力?
數學的思維之用與直接之用
盡量學好數學
9.5?用算法和數學奠定專業基礎
一個程序設計的初學者,在剛剛開始學習時,會認為編程中語言是最重要的。沒有語言,沒有掌握好編程語言,寫不出程序來。而后又知道熟練運用語言僅僅是學會了一種表達的方式而已,如同一個三歲的小孩,空有伶牙俐齒,說著幼稚的話。小孩要說出成熟的話來,還需要有思想,會思考。學編程也是一樣,學會了語言,還應該學會思考,學會給出問題的解決方案。
經典著作《計算機程序設計藝術》的作者,著名計算機科學家高德納(Donald Ervin Knuth)曾經說過:“軟件設計者需要的最基本的構件是算法、語言和數學。”在專業基本功能方面,圍繞算法和數學,積累足夠的專業基本功,這是計算機類大學生該有的準備。
算法有大用
很多人在開始一個新的學習歷程時,總是關心需要有什么基礎。上二年級要先上過一年級,要學會走先得要學會爬。這樣一種思維容易理解,體現的是一種對系統學習的期望。實際上,無論要進到哪一個領域學習,總是可以找到一個入口,隨時開展體驗即可。隨著體驗的加深,逐漸地將需要學習的其他內容拉進來,一種體系就這樣逐漸建立。在編程中,有一定的算法基礎是占有優勢的。但現實的方法是,先從一種編程語言開始學習,通過學會編寫一些不需要復雜算法的程序,對編程有了感性認識,然后再進入算法與編程緊密結合的學習階段。
從這個意義上講,編程是不需要基礎的。剛開始編寫的簡單程序,要處理的數據不復雜,構造一些表達式即可以完成。進一步的學習,利用一些很樸素的算法思想就能解決的問題,在很多時候都可以不用意識到算法兩字。初學者甚至都先不必關注效率等工程中必須關注的重要指標,能解決問題,能將學習進行下去就行。算法這樣一個重要的領域,不應該成為初學者起步的包袱。編程學習中要先放開步子來,利用很自然的思維,解決需要體驗的問題,享受由此而來的一切成就感。
編程不需要有基礎,這句話是對的。其語境是面向白紙一張似的初學者,從零開始學起,避其高深之處,找到入口得門而入,任何的學習都可以這樣開始。編程要以算法為基礎,這也是對的。其語境是面向已經具備了一定的程序設計基礎的學習者,要得到提高,要將編程從關注語言的級別,提升到真正解決問題能力的級別,這就需要知道算法的重要性。
算法無論是作為思考的中介,還是思考的結果,都是在編程學習起步之后必須正視的問題。由關注語言的學習,轉而到對算法的重視,到達的就是一個新的層次。高層次總是在低層次積累到一定程度才能到達。一方面,從低層次起步時,需要安于當前階段,通過學習和實踐,完成該有的積累;另一方面,積累到一定程度時,再行突破,到達另外新的層次。
可以對算法的學習給予超出編一手好程序的期望。遞推方法使用“步步為營”的策略,不斷利用已有的信息推進求解,最終得到收斂的解;枚舉(窮舉)方法有個霸氣十足的別名——暴力求解,從所有候選答案中去搜索問題的解;遞歸方法是一種直接或者間接調用自身的辦法;分治方法將要解決的問題劃分成若干規模較小的同類子問題,將子問題的解逐層合并產生最終的解;貪婪方法從初始解開始就在追求接近給定的目標,以求盡可能快地得到最好的解;試探算法選擇一種可能進行試探,發現選擇錯誤就即時回退,然后繼續試探;分枝限界法意圖找到最優,將不可產生最優解的分支盡可能早地剔除候選隊伍。算法思想的光芒普照天下,這樣的策略其實并不限于編寫程序。學計算機的人是能干大事的,學計算機的人是多面手,他們的底氣是掌握這些歸為類的方法和策略。
算法學習中會遇到很多問題,結合著數據結構,圍繞著抽象數據類型漸次展開。算法研究人員和算法的學習者并不是成天鉆在抽象的符號當中工作,經典算法通過是借著經典的具體問題,甚至是一些好玩的故事來體現。查找和排序既是在計算機系統中使用頻率最高的問題,又是特別能體現算法思想的問題。背包問題、貨郎擔問題、流水線調度問題,對應著無數的各式應用。在智能計算中大顯身手的模擬退火算法、遺傳算法、神經網絡等等,來自大自然的智慧,促成了計算的成長。
效率問題是程序設計中的核心問題之一。程序運行要盡可能快,占用內存空間要盡可能小。算法的學習中,到處都體現出了這種“精打細算”的味道。我們能順暢地欣賞視頻,游戲中享受著逼真的感覺,點擊“搜索”,瞬間就有搜索結果呈現在眼前,可以體會一下這些應用背后高效率的算法立下的奇功。到了移動計算、物聯網的時代,手機、平板電腦這些低速計算設備,以及計算能力更加有限的專用設備顯得更加重要,對效率的追求不降反升。在環境保護日益受到重視的今天,計算機設備的耗電量已經成為用電大戶,中國所有臺式機的用電量,相當于三峽電站發電量的總和,用上更快的算法,意味著計算機運行時間的減少,“綠色計算”成了業界的共識。
隨著技術的發展,不斷有運行更快、存儲量更大的計算機被制造出來,也有了將更多的計算機連接起來組成機群,提供了超級的計算能力。在這樣的背景下,有人質疑:“現在的機器設備已經足夠快,還用如此費力地用人腦在算法方面有那么多的考慮嗎?”他們主張,遇到問題,用暴力求解方法寫成程序,交給足夠快的超級計算機,一切搞定。甚至我親自聆聽過一位著名教授的言論:“我們不需要在算法方面花那么大的精力,利用機群,增加并行度,是一種更直接和簡單的方法。”教授的言論有些道理,但事情并非如此。
舉一個實例。在物理學、力學以及信息處理的很多領域,常常需要用到離散傅里葉變換,見公式(9–1):
? (9–1)
從算法復雜性度量的角度看,如果直接用公式計算,需要n2次乘法。如果能夠利用指數函數的周期性和其他一些計算技巧,則可以把計算量降低到nlog2n次,這種方法叫做快速離散傅里葉變換。算法關注計算規模,當n值很大以后將會體現出高效算法的必要性。如果現在要用計算機對衛星拍攝的照片進行分析處理,對10×10 cm2的照片每隔1微米進行劃分然后進行計算。用傳統的傅里葉變換算法,需要計算n2=1016次,即一億億次,如果用百萬次級的計算機,需要300年,這樣的算法是在實際應用中不能接受的,而使用快速算法,則可以在1小時內獲得結果。
在摩爾定律的作用下,計算機的能力在飛快地增長,價格也在不斷下降。但是,永遠不會有太快的計算機,因為總會產生出新的應用。進入了大數據的時代,需要處理的信息量更是呈指數級的增長,已經給計算、存儲的設備提出更多的挑戰。基于互聯網,現在每人每天都會創造出大量照片、視頻、語音、文本等數據,日益先進的存儲手段使我們每個人的信息量都在爆炸式的增長,互聯網的信息流量和日志容量也在飛快增長。在科學研究方面,隨著研究手段的進步,數據量更是達到了前所未有的程度,三維圖形、海量數據處理、機器學習、語音識別,都需要極大的計算量。在未來,更需要依靠卓越的算法解決問題,更需要大量的掌握了算法規律和方法的高水平人才承擔責任。
面對一塊巨石,等待一位大力士將之強力搬開是一種辦法。找來一根杠桿,用很小的力量也可以將之撬動。常指望著高性能的計算機求解,依靠的是大力士,而在算法上做文章,用的卻是巧勁。我們需要的是智慧的力量,體現出的是智慧的美。當遇到任何大力士都無法撼動的巨石時,我們只有依靠智慧了。
抓住算法,打造核心競爭力?
學計算機,要關注算法的學習。除了在課名中就帶有“算法”的課程,專業核心課程幾乎都是圍繞算法展開的,只不過針對的是專門的問題:操作系統關注的是系統資源分配、管理的問題和解決算法;編譯原理關注人工語言處理的算法;計算機網絡中的重點——協議實際就是算法;計算機圖形學關注圖形表示的數據結構,以及圖形顯示、變換等的算法;多媒體技術基礎是圖像、音頻、視頻編碼、壓縮的算法;密碼學中是保證信息安全的算法;人工智能中涉及各種決策、模式匹配、優化算法;并行計算是多處理機同時完成一個任務的算法。各種基礎的課程,盡管其描述的方式中數學味濃一些,涉及的也是算法。離散數學、可計算理論是算法,線性代數、數值分析、概率論和數理統計中也是算法。認識不到這一點,有些同學就會聲稱的“操作系統中全是些概念,背一背就過了”、“概率論沒有用”之類的斷言,真的會將自己學習的方向引入歧途,甚至找不到方向和動力。經歷了求職的大學生會發現,技術類崗位的筆試、面試,考到、問到的內容,需要的是算法基礎。在企業招人的考試中都是這樣,可以知道算法的基礎性作用。
學得常用的算法,學會算法分析和設計,這是計算機類專業大學生應該達到的程度。遇到要解決的問題時,為問題建立計算模型,用已有的算法解決問題;進一步,能根據具體問題的實際情境,從多種算法中選擇一個最合適算法;更高的要求,解決問題沒有現成的算法可以利用,憑借著算法方面的良好素養,能夠在已經有的算法基礎上進行改進,甚至運用學到的算法策略,設計出新的適用算法,這是充滿創造性的工作。在高等教育中專科、本科、碩士、博士的不同層次,都設有計算機專業。不同的學歷側重不同,學歷越高,對算法要求有更深入的學習,并且要學習和研究的算法,由一般性算法問題逐漸過渡到專門的算法。
有人說:“本科生用不著學太多的算法。”他馬上可以舉出的例子就是,現如今有多少碼農的工作需要算法?很多人的工作,拖拖控件,寫些調用數據庫的語句,如此而已。這是業內一部分技術人員的工作場景,但這不是全部,不能成為我們放松學習算法的理由。要在行業的生態系統中生存發展,對大學生的要求不能只看著技術生態鏈中的一部分。縱觀行業中高薪的、核心的技術崗位,豈是只會拖控件就能勝任?萬萬不可以將剛進入行業時立足的工作形態,當作長期發展的形態。這句話背后的事實是,有些本科生連拖控件的要求都達不到。這句話也還提醒我們,專業基礎很重要,但基礎不是全部。花一段時間,實踐應用開發,學習和體會拖控件之類的其他技能和要求,這也是大學中必要的安排。
很少用到算法的人,有些人是知其有且知其不必用,而有些人是不知其有,進而需要用時當然也不知用,這兩方面的差距很分明。實際上,人們之所以說算法很重要,是因為任何的程序,任何的軟件,都是由很多的算法和數據結構組成的,大學階段學習的算法都是基本的算法,是作為每一名專業人員都需要有的公共知識,實在不必因為“很少用到”就生出“放一放”的心思。
這樣看來,有的程序員很少用到算法的背后,體現的是軟件行業中的分工不同。可以將軟件開發工作分為算法密集型、業務邏輯密集型和使用體驗密集型三種類型,這三種類型的工作對算法的要求各不想同。算法密集型的如搜索引擎、游戲引擎開發、模式識別等,這些主要的任務都與算法密切相關;業務邏輯密集型,典型的如信息管理系統,其中工作量最大的是實現用戶的業務需求,熟悉用戶的業務并按要求完成應用更重要;使用體驗密集型,如教育、游戲軟件開發,更注意友好的界面、方便的操控和愉悅的使用體驗。在后兩種類型的工作中,會有90%以上的代碼只是涉及到業務流程,以及用戶界面,的確不需要直接使用什么算法。但是,往往就是余下的10%代碼,有相當高的性能要求,所采用的算法決定了系統整體的性能,決定了產品的競爭力。想在軟件行業成為有競爭力的從業者,有盡可能好的算法功底,也就成了自然的選擇。
數學的思維之用與直接之用
傳說中,數學對計算機很重要,但有些程序員也宣稱感覺不到數學對他們的意義。其實考察下來,與對算法的態度對比下來,有關用不用數學的觀點,也是大致相似的。
有位學生給我來信,他很想知道高數和線性代數對計算機專業有什么作用,要學到什么地步。這個問題在和大學生交往過程中沒有少被問到。一些人只是問問而已,還有的是想找個理由不想學那么多數學,當然應該都是遇到了困難。有些計算機類專業的學生,對學數學有情緒。
數學對于計算機學科的重要性常被人談起。數學與計算之間存在著不可分割的聯系:數學起源于對計算的研究,計算作為數學的研究對象已有幾千年,數學仍在為計算提供著理論、方法和技術,而計算科學為數學提供了能自動計算的設備,并為更有效地完成任務提供了工程方法和技術手段。計算曾經是數學的一個分支,而當其承擔起構造能自動計算和會思維的機器的任務時,逐漸發展出了其特有的成分,并具有了更多工程性質的內容,形成了自己的體系。盡管現在計算與數學已經不再等同看待,但縱觀學科間的聯系,計算與數學之間的親緣關系還是最近的。
數學,對于計算機專業人員的作用主要表現在兩個方面:
第一方面,是數學的思維之用。數學是科學之母,承載的是一種科學家思考和解決科學問題的具體方式和途徑。學數學的過程,就是要獲得這種思考和解決問題能力的過程,還可以獲得從事IT行業的技術工作中需要的邏輯思維能力和嚴謹的工作作風。
另一方面,是數學的直接之用。數學可以直接應用于解決一些問題。數學是從各種實際應用需求中抽象出來的理論,之所以要將實際抽象成理論,目的就在于將直擊本質的、具有普適性的理論更好地指導實踐,將已有的理論,伸入到無限的應用場景中。在計算機工程實踐中,要大量用到數學各個分支的知識。例如
- 無論二維平面繪圖還是三維動畫軟件,都需要有幾何學的支持;各種圖形軟件開發中,需要用線性代數中的坐標變換、矩陣運算;
- 游戲開發中圖形處理是一個重頭戲,此外,還涉及物理方程和公式,想想憤怒的小鳥在被彈射出去的那一剎那,彈力、重力、滾下斜坡,統統要用到;
- 談及數據壓縮與還原、數據加密與解密,以及倍受關注的信息安全,離不開數論、代數編碼理論,小波函數等數學分支;
- 在人工智能及其衍生的各個領域,涉及決策、智能的話題,概率、統計不能不提。
這樣的例子數不勝數。有很多人感嘆,搞計算機,學多少數學都不算多。
盡量學好數學
IT業是一個包容性很強的行業,不少從業人員并非計算機專業畢業,甚至有不少沒有接受過大學教育。很多在校大學畢業生很在意這種“搶飯碗”的事情,也為此表示擔憂。應該要意識到,一些簡單的專業技能、一般的程序設計技術,門檻并不高,掌握起來相對容易,讓更多的人有機會從事合適的工作,要能接受這樣的事實。而作為計算機類專業的大學生,需要知道自己的競爭優勢和不可替代性,就在于在接受專業培養的過程中,具備了專業的思維,積累了扎實的關于計算的基本理論,掌握了許多其他人員并不深究也深究不了的東西,例如,算法、計算機體系結構,等等。用專業的思維分析和解決問題,有能力研制大型系統,從事底層開發,這需要有專業的知識結構和技能作為支撐,其中數學方面的知識,在為專業理論充當支撐。數學專業的畢業生到軟件企業中從事軟件設計與分析工作的工作要有優勢,而計算機類專業的畢業生從程序員起步的居多,原因就在于數學專業的學生在分析推理能力方面,從所受的訓練要比計算機類專業的學生多。計算機類專業畢業的學生有自己的特點,倒不用對數學專業的學生有多少羨慕,但從中應該看到數學對計算學科的重要意義。至于和別人搶低端飯碗的專業畢業生,一方面,這只是在剛進入行業的一種方式,另一方面,有些畢業生沒有具備專業的核心能力,不得不這樣去做。
不過,也有IT行業的專業技術人士說,他們在工作中根本沒有感覺到數學的存在。甚至有人認為程序員不需要了解數學,更重要的是要去了解設計模式、面向對象原理、軟件工具、界面設計,以及一些其他類似的東西,數學不好也可以做一個很專業的程序員。這樣的感覺是對的,這也是在行業內的一種生存方式。
為什么會有這樣的感覺?從數學的思維之用看,當訓練出來了專業思維,在解決問題時,自然而然就用上了,這是一種最佳的效果。我曾經與我的學生談離散數學非常重要,其重要程度甚至到了幾乎感覺不到其存在的程度。這句話聽起來矛盾,我要說的是,要讓離散數學的精髓成為你的思維習慣。遇到問題,不用想用離散數學中的哪個定義、定理,但確實就是那樣想了,那樣做了,這和武術中的“出手不見招”的境界是一樣的。
從數學的直接之用看,大學教學需要關注到未來各種可能的用途,要考慮到大多數人的需要。這樣一來,對某些人,自然會有一部分用不上。工作中是否要用到大量的數學,和從事的工作領域有很大的關系。例如:
- 投身到科學計算,以及近幾年非常熱門的數據分析領域,數學知識時時要用;
- 從事游戲開發,涉及圖形處理、實體建模、逼真效果展示,數學很重要;
- 從事系統開發中最核心的工作,在算法層面考慮問題,數學基礎不好不行;
- 涉及信息安全領域,沒有數學功底沒法玩。
然而,如果從事的是系統實現環節的工作,如大多數信息系統開發中的實現、測試工作、人機交互界面設計、系統管理等崗位,真的就不需要太多的數學,感覺不到數學的存在也就不足為奇。
另外一個因素是,軟件業內的分工進一步細化,很多在開發中需要用到的底層處理由成熟的軟件組件提供,用到的數學就“藏”在這些組件中,不需要開發人員考慮了。例如:
- 搜索引擎構造中要用到復雜的算法,而大多數的開發直接引入類庫,如開源的Lucence,調用函數就行;
- 游戲開發中要到各種計算模型,足以將目前游戲開發隊伍中一大半人淘汰,但使用功能強大的游戲開發引擎,如2D的Cocos和3D的Unity,難度、成本降低,開發周期縮短,開發質量提高,何樂而不為?
由此可見,數學對于計算機類專業很重要,但也不是重要到每個人都必須要精學多學的那種程度。行業中有分工,每個層次、每個領域需要的能力結構和要求也各不相同,實在也沒有必要千人一面地做出硬性的要求,要求大家都向數學專業的學生靠攏。另外,在有限的大學時間內,僅培養出突出的數學能力是不夠的,誠如上述所提到的純粹工程的能力,也是不可或缺的部分。在這一方面,計算機類專業的培養方案還是考慮了這樣的需求。其中,對計算機科學技術專業,在數學及其他的理論方面的要求相對要高,而對于軟件工程、網絡工程等專業,工程能力要求相對更重要。
這不能成為一些同學放棄培養方案內正常的數學課要求的理由。數學的思維之用和直接之用并不是能夠嚴格劃分開來的,數學之用的無限可能也不是哪位老師能隨意講清。在大學這樣一個重基礎的學習階段,還是要有些耐心,完成該有的積累。我們應該看出,達到培養目標的畢業生,在各種崗位上的游刃有余,數學和算法能力強的,將擁有更多的選擇機會。即使是在利用Lucence和Unity開發探索引擎和游戲,如果能對其內部的機制多一引起了解,你的層次將不只是“使用”,而可以是“駕馭”,意味著工作質量的提高,意味著你的個人價值和潛力。而如果過早地放棄了對專業核心能力的追求,在崗位選擇以及發展空間上面臨的限制,也就顯而易見了。除非是因為各種原因真的失去了機會,我們再作退而求其次的打算。
返回到【全文目錄】【下一節】
?
總結
以上是生活随笔為你收集整理的9.5 用算法和数学奠定专业基础——《逆袭大学》连载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用计算机唱黑人台湾音乐,运用计算机音乐技
- 下一篇: mysql统计类似SQL语句查询次数