電腦科學界已經構築了許多知識體系,還有必要自行建立知識體系嗎?是的!畢竟開發者面對的需求各不相同,持有一套既存的知識體系,或許足以解決許多事情,然而若能自行建立專屬的知識體系,可以解決更多!

知識體系的銜接難度

開發者多半有這種經驗,某個難處理的問題,在百思不得其解,遍尋不得其法後,不得已,只好暫時放下,卻在某個不經意的時候靈光乍現、找到解法;俗話也有這種說法:「不要鑽牛角尖。」在某些程度上,就是暫時別將焦點放在問題本身,而是藉由其他的學習、做法或經驗的累積,來增加對問題的認識、刺激解答的產生。

最近我在這方面的鮮明經驗是,打算尋找Perlin噪聲的輪廓線。其實,開發者若曾使用OpenCV的findContours或D3.js的contours之類的函式,對尋找輪廓線可能並不陌生,常見的應用是生成等值線圖,像是地型等高線、氣象等壓線等,目前有不少程式庫可以協助開發者解決這類問題。

問題就在於,我想在OpenSCAD運用的話,就須自行實作。這類輪廓線函式的背後原理是行進方塊(Marching Squares)演算法,不過,在我既有的知識體系中,尚未有任何聯繫行進方塊的相關連結,在試圖使用Perlin、contour之類關鍵字搜尋時,找到的通常就是既有程式庫方案,或者是〈Randomized Contour Lines〉之類的文件,並非我想要的效果。

這就是拼湊知識體系的難處,雖然知道方案應該就在某處,卻不知道怎麼銜接,以進一步納為已用。這可能來自經驗上無法理解問題、對問題本身的認識不夠,也有可能是對解答問題必須的基礎能力不足,或者是問題本身牽涉的領域不只一個,也就是可能連接到另一個領域的知識體系了。

此時需要的方式或許是「闕疑」,暫停對問題的直接探索。不過這並非相信腦袋的潛意識能自動找出解答,而是在試著去解決其他的問題,或獲取其他知識的過程中,偶而思考一下與被闕疑問題的相關性,看看是否能將其他問題的解決方案,納入自身的知識體系。

自我試誤的重要性

我在先前專欄〈隨機演算之美〉曾經提過,可以從迷宮中生成哈密頓路徑,其實,若開發者探索過如何走出迷宮的演算法,會發現其實這種哈密頓路徑就是沿壁法(Wall Following),也就是摸著牆走迷宮,對完美迷宮(Perfect maze)來說,雖然不會得到最佳路徑,然而一定可以走出迷宮。

從另一角度來看,摸牆走迷宮就是在畫出迷宮牆的輪廓,在解完迷宮中生成哈密頓路徑的問題後,我想到可否用類似方式,畫出多邊型的輪廓。的確,若是基於像素來運算,畫出簡單多邊型沒有問題,而且效率不錯,然而,試著用相同方式尋找Perlin噪聲的輪廓線,卻行不通。

這令人沮喪,但也是個不錯的經驗,事實上在試圖設計其他演算法的過程中,雖然有效性都不足,然而至少知道這條路無法通往想要的方案,知道「行不通」這件事,對建構知識體系而言,其實是個去枝裁葉的重要過程。

這讓我想到現今許多開發者,對於刷LeetCode有不同的聲音,對我來說,刷LeetCode不單只是知道怎麼解,更重要的是「知道怎麼解行不通」,自己設計過的演算法才是你的,或更精確地說,自行設計演算法的過程中建立的思路才是你的,即便最後無法解決LeetCode的題目,思考過程並不會白費!

寫程式碼與演算法設計其實是兩件事,如果刷LeetCode時看到題目,就想直接知道解答,在「建立演算法設計領域的知識體系」這件事上,就失去了大半意義。

當然,不少演算法是前人數月或甚至數年思考之下,才設計出來,或者基於他人的演算法改良而來,因此,面對某些題目,在有限時間之內,確實不太可能憑一己之力設計出解答,然而,我們至少在試過幾個無效的思路後,再來看看可解決問題的演算,如此才能辨別出該演算為何會是有效的,從而能加以變化。

這是因為,在無效的試誤過程中,我們才能知道哪些要素會導致演算法無效。例如,自行尋找Perlin噪聲的輪廓線過程中,知道了沿壁法只能處理簡單多邊形,後來看到行進方塊時才能知道,其有效的理由在於獨立處理每個網格,並列舉了各網格有限的可能案例。

碎片化或系統化知識來源?

現今是個碎片化年代,意思是指網路普及之後,人們習慣從網路擷取片面資訊,而不是從書或課程等循序漸進管道來獲得知識;在程式開發領域也就經常會有這類論戰,有人覺得看看官方或其他開發者的文件就夠了,有人覺得從書或課程中,系統化地學習某個技術會比較紮實。

其實,知識的來源是碎片化或系統化,並不是重點,重要的是能從中擷取自身需要的知識,填補個人的知識體系,從而在往後可以在專屬的個人知識體系中,進行系統化的思考。

以沿壁法生成哈密頓路徑來說,在演算過程中,會針對網格四個角落標識1、2、4、8欄位,而這個方式成為我的知識體系一部份後,才能變化出像素版本的輪廓演算,而在後來接觸到行進方塊演算時,才能將其中也用到的角落欄位標識方式,立即地連結到既有的經驗。

然而,有些基礎論的開發者仍鄙視碎片化知識。其實,若經驗充足,碎片化知識來源並不會是問題,因為既有知識體系若能系統化連結碎片化的知識,能夠碎片化地吸收知識,對開發者反而是比較有效率的方式,因為可以迅速填補不足之處。

而對於有些碎片化知識支持者而言,他們一味認定沒必要看書或參與課程,單靠網路上的知識已經足夠。然而,若開發者的相關經驗不足,系統化知識的來源就至關重要,像是書或課程,基本上已安排好知識間的銜接,這讓開發者不用自行花費過多心力或時間,就可以從中建立基本知識體系。

開發者可以回想一下,接觸第一門語言時,若缺少系統化資訊來源,學習起來會很辛苦,然而有了一門語言經驗後,面對語言中共通元素的部份,我們在既有的知識體系中已經有經驗,或許就不需要本質上類似的知識,只需要釐清差異的部份,這時若從碎片化來源擷取知識,可能會覺得較有效率。若既有的知識體系仍不足以彌補,那麼回頭尋找系統化知識來源,也是好的作法。

完成專屬的拼圖

建構專屬於自身的知識體系,過程極為複雜,很大程度上就像在拼湊巨大的拼圖,在看似無關的圖塊間找尋相關,一開始通常只會獲得各自獨立的殘破輪廓,在拼圖完成前,也很難知道全貌是什麼,畢竟每個人需要的知識各不相同,如果一開始就知道全貌是什麼,你所看到的大概是別人的知識體系,不是你的!

持有一套既存的知識體系,或許已經足以解決許多事情,然而建立自身的知識體系,可以解決更多,因為隨著圖塊之間的連結越來越完整,各自獨立的殘破輪廓會在某個時間點開始銜接,之後拼湊的速度就會加快,甚至感覺到過去看似無關的零碎知識,瞬間融會貫通了,許多過去難解的題目也就迎刃而解,更多的靈感也會不斷地浮現!

專欄作者

熱門新聞

Advertisement