我應該是為瞭解決工程問題而去學習演算法的。

記得二十多年前,在高中做《王子傳奇》戰鬥系統的時候,需要計算及顯示角色可以移動的範圍,每個角色跟據等級和裝備能計算出行動力,而二維柵格地圖每個方形格子的類型會減去一定的行動力。

那個時候我沒想到如何編程去解決這個問題,同事口頭告訴我一個方法,就是從開始位置,減去當前格子所扣除的行動力,如果行動力有餘,則遞歸往四個方向移動(更新:印象中是用 BFS 不是 DFS),如果格子已曾到達,僅當現時行動力比之前到達該格子的行動力少才覆蓋舊數據。這個演算法解決了工程上的問題。到讀大學的時候,才知道更優的做法是 Dijkstras algorithm 的變種。

對比每次遇到工程問題才尋找並學習一兩個演算法,在大學課程裏系統地學習演算法是更為高效的,也可以從更抽象的層面瞭解各種演算法問題的核心。現在大多數常遇到的問題都已有很好的(可能已是最優的)解決方法,如果沒有現成的解決方法,可能真的是未解決的難題。在工程上更多情況是把問題拆解,考慮各種演算法的優劣點,進行一些組合及盡量實現得最優。


ACM選手

上大學後,學校有相關的培訓,讓所有的學生都到,以為是正經的課,本著拿獎學金做學霸,學好每一門課的心理,帶著小本子就去了

到了發現這都是在說啥,啥float+0.5 %f%lf的,一點都聽不懂,後來的一個月,每節課都去聽,一點都不懂

十一前的最後一節基礎語法課,還是什麼都不懂,安排所有的學長在15樓答疑,在同學的幫助下艱難的過了a+b

十一假期,帶牙套,整天疼的睡不著,那時候雷劈壞了電壓器,整個假期通宵給電,外邊下著雨,我在屋裡通宵做水題,那時候刷本校oj,整天想著不打到新生rankx不睡覺

水題的正反饋很強的

後來新生賽第二,和室友花式喫飯,後來又去別的學院拿一等獎,那時候演算法的意義似乎就是拿個錢裝個逼?

後來被學長的激情感動,雖然大一的上半年被同學們吊打,但是暑假對著kuangbin專題瘋狂刷刷刷,自學了很多演算法

到了開學,大家都打不過我了,那時候演算法的意義就是比賽,吊打別人,很舒服,比什麼lol好玩多了

後來暑假訓練,從知乎上學了一下cf大法,應該刷了100+比賽並堅持補題,和學長組隊,區域賽遺憾拿銅,和現同級隊友組隊,寧波打鐵,那時候演算法的意義在於,和許多菊苣交流,在acfun不要臉的問各種問題,不斷的追問qls被qls懟後轉移到acm貼吧or wannfly繼續問,然後被qls繼續回答追問懟,不斷的進步感受到不斷地樂趣,那時候同院的人都打不過我們了,去和其他學院打,去vj cf開虛擬比賽,和各種假想敵打

想起天童寺的涼風帶著雨在天空中劃過,總有種開心的感覺

後來的寒假學各種數據結構,一個bug盯一天才能修出來,那時候開始思考演算法到底是什麼,數據結構到底是什麼,後來得出一個結論,數學之美

直到現在,演算法已經成為了我生活中的一部分,沒事的時候不如打開cf觀察一個新題,等人的時候看看訓練賽學弟做的怎麼樣,雖然自己水平不高但是也能感受到自己的快樂,在自我介紹的時候也會說一句「愛好是打演算法競賽」

最後強行切題,我為什麼要學演算法?從水題正反饋-&>比賽壓人很舒服-&>思考演算法真的很有趣呀⊙?⊙!


早上起牀:「今天我也是個廢物呢」

習慣性的打開某個OJ開始補題...

"這怎麼題目都看不懂啊?"

"這數據範圍能寫?"

臥槽這什麼鬼條件哦...

然後開始失去自我,思考人生...

我為什麼要學演算法啊....

美好的大學生活不是等著我嗎...

這真的是我想要的生活嗎...

做這種事情真的能的得到幸福嗎...

一萬年以後

"MD漏看了某個條件???"

"那這不是傻逼題?"

啪嗒啪嗒...

Wrong Answer

"唉woc怎麼下標寫錯了..."

Time Limit Exceed

優化+扣常數又過去半年..

Runtime Error

"智障了...怎麼數組都能開小的.."

Accept


剛開始學C語言的時候,能做出列印菱形、枚舉N以內的素數,就以為可以當程序員了。學完C語言的第一個暑假,花了幾天的時間,成功擼了一個能跑起來的中國象棋馬踏棋盤路徑尋找並實時顯示路徑變化的程序,看著閃爍無比的動畫,心中充滿了成就感,興奮地讓這個程序跑了兩天兩夜,當然了,我當時的程序並沒有找出一條路徑。第二個學期學習了演算法,用「貪心演算法」瞬間就能找出一條路徑。這是我對演算法最初的印象。

cpu其實很慢,這就是必須要學演算法的原因。面對指數級或是排列組合級別的各種計算,每秒幾億次的運算速度根本不夠看。就拿前面象棋的例子,搜索一次全部的位置大概需要10**35(10的35次方)年。所以說,學習演算法是成長為合格程序員的必經之路。

我做的是遊戲伺服器開發,對於演算法高手有很大的用武之地,因為工作中用到的演算法,並不是全部都能在書上、網上找到,可能是自己第一次碰到,也可能是別人解決了並沒有分享,需要自己去解決。當然,對於這樣的任務,每個團隊裡面只要有一個演算法高手就行了,其它人學演算法有沒有用呢?其實是有用的,熟悉演算法的人思路也會更清晰,寫出來的代碼質量也會不一樣。

現在很多公司招聘都會考察演算法,越是大廠對演算法似乎也越看重。對於招聘來說,演算法是區分應聘者編程功底和勤奮程度的好方法。有些人說是會寫程序,但是隻會做增刪改查,稍微難一點的兩重循環都不會寫,這樣的人在演算法面試題面前一下就被打回原形。

程序員一個很普遍的問題就是年齡危機,比如說超過30怎麼辦、超過35怎麼辦、超過40怎麼辦,行業內確實有相當一部分人,他們隨著年齡增長就不得不面臨被淘汰。如果把不被淘汰的最長工作年限比喻成能建一棟樓房的高度,樓房高度的一個重要的因素是地基有多牢。演算法其實就是樓房地基一個重要的組成部分。勿在浮沙築高臺,學好演算法,是讓自己能夠在程序員的道路上走得更遠的一個重要保證。

我最崇拜的後臺技術專家同事說過:伺服器的cpu是為玩家服務的,不是為我們程序員服務的。我現在仍在堅持學習演算法,因為我知道演算法肯定有用。


當初寫網站,搞反爬功能,做了個IP段過濾,學了BST-&>23樹-&>紅黑樹-&>AVL,最後擼了個區間樹來做匹配。

考慮到多線程問題,學了CAS、CopyOnWrite等演算法。

又想加個垃圾評論篩選功能,學了前綴樹-&>TernaryTrie-&>AC自動機,後來覺得準確率不行得上AI,可惜沒精力學......

剛開始學C的時候一直納悶如果輸入長度不定應該怎麼定義數組初始大小,百度後學到了ArrayList和鏈表。

還有腦子抽風覺得JAVA裏裝箱操作慢,自己擼了一套值類型的集合。

非科班,沒打過比賽,我覺得但凡寫代碼的時候願意思考的人肯定要碰到演算法問題。
推薦閱讀:
查看原文 >>
相關文章