在前一天的 LeetCode 解題的思考策略與解題地圖 中提到程式題目的兩種考法,分別是「前測的技術面試題目」或「現場互動的白板題」。今天想要跟大家聊聊解題時的心態與策略,如何理解題目背後的設計思維。
其實寫程式本身就是一種對話,你不是機器人、也不是百科全書,所以很難一昧、單向的進行解題。回想我們平常在開發程式的過程,其實上網搜尋、查閱書籍的時間一定佔用不少的時間,真正「敲程式碼」的時間反而有限。因此,不管你是在面試當下面對面試官的解題或平常在練習刷題時,透過「對話」釐清需求、發想解法都是蠻建議的方法。
我自己會把刷題過程的心態與技巧的大概可以總結為這三項:
就像經典的 黃色小鴨除錯法(Rubber Duck Debugging) 一樣,你需要其實是那個「思考」的過程。
所謂的「如何理解題目背後的設計思維」這個問題,需要先思考「寫程式的本質」到底是什麼?而 LeetCode 的題目就是其實就是一種「評斷程式能力到什麼程度?」的面試題目匯總,比起刷題更值得關注的是該如何從這些練習中鍛鍊出更好的程式碼品質開發功力。
所謂的寫程式就是利用電腦的記憶與運算,根據 Input 產生 Output 的過程,而演算法指的是在有限步驟與時間內執行的程式,這也是寫程式與演算法之間最大的差異。演算法我們更執著「多少個步驟」或「多少時間」可以完成,這個效能與複雜度是否堪用。
程式設計利用「變數」使用記憶體儲存與記憶、利用「流程控制」實現運算,所以寫程式就是在變數與運算間穿梭。流程控制可以由「循序」、「條件」與「重複」三種結構所組成,使用不同的程式碼搭配創造出各式各樣的運行結果。一般討論程式碼寫得好不好,可以從「記憶體的空間複雜度」與「CPU 的運算時間複雜」兩個方向著手,也就是如何管理好變數以及如何設計好流程。
資料結構這一門學科專注在如何利用一些抽象的結構有效在程式中儲存資料,換句話說,就是在討論怎樣更好的使用變數的方法。演算法的話則是搜集那些經典的方法,介紹那些常見的問題過去是如何設計出漂亮的方法來解決的,也可以視為是一種流程上的優化。所以,其實資料結構與演算法就是寫程式,資料結構或演算法其實就是程式碼經年累月淬煉出的精華,經過整理而成的武功秘笈,讓我們得以站在巨人的肩膀上寫出更好的程式碼。
從「如何理解題目背後的設計思維」到「看懂題目背後的設計思維」,其實就是一種寫出更好的程式碼品質的過程。這些題目背後在意的其實就是那些曾經被優化過的歷程(例如資料結構或演算法),你能否站在巨人的肩膀上再持續往前呢?所以你說 LeetCode 題就是在考資料結構或演算法嗎?這句話我覺得對與不對,應該說是想考的是你能否從這些方法中習得「優化程式」碼的能力。
這個段落聽起來也許有點抽象,我們試著思考以下兩種場景:
① A 看完了題目馬上畫了關鍵字,心中想過我練過這個題目,然後埋首刻出了一個「一個非常漂亮」的寫法
② B 看完了題目皺了眉頭,向面試官釐清了一些疑問之後,然後寫出來了一個「好像沒有那麼厲害」的寫法
這邊我們可以明顯感覺到 A > B,但你丟出下一個問題「你可以怎麼優化這個程式碼呢?」後 ...
① A 同學就說這是我在解答中看過最佳的算法,已經沒有更好的方法了。
② B 開始與面試官討論並且根據經驗提出這邊可以怎麼改、那邊可以使用另外一種方法,然後拼湊出優化後的程式碼。
從這兩個情境中可以明顯感覺 A 與 B 不太一樣,我也不確定那一種人在面試過程中比較容易受到青睞。不過更多的情況下,你很難真的刷到面試一模一樣的題目,所以我想能夠「從根據經驗提出優化的策略」是刷題中必須習得的技能之一。
嗨,大家好!我是維元,一名擅長網站開發與資料科學的雙棲工程師,斜槓於程式社群【JSDC】核心成員及【資料科學家的工作日常】粉專經營。目前在 ALPHACamp 擔任資料工程師,同時也在中華電信、工研院與多所學校等單位持續開課。擁有多次大型技術會議講者與競賽獲獎經驗,持續在不同的平台發表對 #資料科學、 #網頁開發 或 #軟體職涯 相關的分享,邀請你加入 訂閱 接收最新資訊。