閒聊「刷題」這件事
概要
「Leetcode.com」是一個全球知名的程式設計題庫網站。
程式設計師是當今最熱門的職業之一,而該行業最大的特點就是具有「全球共通性」,舉例來說,美國工程師所撰寫的程式碼與台灣工程師所撰寫的程式碼基本上會是相同的,相較於其它地域性較高的職業,如律師,各國的律法不同、如廚師,各地的口味不同;程式設計師跨國就業的門檻就相對的容易許多。
因此,許多一流的人才其目標就不僅止於國內企業,而是放眼國際企業,以科技業為例,「FLAG」:Facebook、LinkedIn、Amazon、Google,就是科技人的夢想企業。
然而有競爭,就必須互相傷害,因此做考古題就成了重要的準備項目之一。
以「Leetcode.com」來說,裡頭就收錄了不少上述知名國際企業的考古題,不論是筆試、面試,而到「Leetcode.com」網站中練習解題的行為,我們就稱之為「刷題」。
正文
如何刷題?
首先,我們必須擁有一個「Leetcode.com」的帳號,註冊過程是免費的。
完成註冊並登入後,在首頁選擇「Problems」,如下:
然後就會到題庫首頁,此處的題目會依照其性質被分類,如「Algorithms」類、「Database」類、「Shell」類和「Concurrency」類,我們可以依照需求選擇自己想要練習的題目種類,實際上,題目大多數屬於「Algorithms」類,而下方則是題目列表,如下:
我們可以依照自己的偏好選擇題目,題目會依照其難度大致分為「Easy」、「Medium」、「Hard」,共三個等級。
事實上,對於非演算法相關的程式設計工作,如前端、後端、iOS APP 或 Android APP…等,筆者認為不必特地去追求高難度的題型,反而是以將目標放在「Easy」和「Medium」的難度更為適合。
在選定目標題目後,點擊進到題目頁面,如下:
左上的區塊是題目描述,右邊上方是輸入程式碼的區塊,其左上角處可以選擇語言。
接著,我們僅需將符合題目需求的代碼貼在程式碼區塊後,按下「Submit」即可,然而在送出之前,我們也可以自行輸入「Testcase」,並藉由「Run Code」來驗證我們的代碼。
值得一提的是,「Leetcode.com」也為所有考題設有「討論區」,如下:
在此處,會有許多「LeetCoder」分享自己的代碼與解題思路,記住,高手在民間,在刷題時,不妨多逛逛討論版的文章,或許會有意想不到的收穫。
討論區
在「Leetcode.com」所收錄的所有題目中,除了上述之外,還有另一部份的題型是無法藉由輸入一段程式碼來得到驗證的「開放試題型」,如「System Design」類、「OO Design」類以及「Operating System」類…等。
對於這類型的題目,「LeetCode.com」也有提供專門的討論區,只要點擊上方的「Discuss」選項就可以來到討論區,如下:
事實上,該討論區除了「Interview Question」之外,還有其它項目的討論版,如「Interview Experience」、「Compensation」、「Gareer」、「General Discussion」及「Support & Feedback」…等。
演算法常用的標準
回到「刷題」的主題上。
當我們輸入解題的程式碼並送出後,伺服器就會開始驗證我們所輸入的程式碼,若我們的代碼不符合題目的需求,這時候就會顯示錯誤,其中,最常見的原因通常是我們的考量不周全而出現的例外的「Case」,此時,畫面會顯示錯誤原因以及「Test Case」,如下:
若成功則會顯示「Success」,並分析該演算法的狀態,如下:
一般來說,「演算法」好壞的評定會以「效率」和「效能」為標準,前者即執行的時間:「時間越短,效率越高。」,後者則所佔據記憶空間:「所需容量越大,效能越差。」。
而每次的送出都會被紀錄,如下:
因此,我們可以藉此比較「不同解法」的情形,此外,我們可以點擊目標項目以顯示當次的詳細資料。
複雜度
複雜度是一種「量化演算法的方式」,通常我們會將「複雜度」分為「時間複雜度」跟「空間複雜度」。
首先是「時間複雜度」,簡單的說就是「當演算法的運算資料量增加時,其所耗費的時間變化程度。」,複雜度常以「常數」、「線性」、「對數」、「次方」、「指數」和「階乘」…等量詞表示,其詳細資訊可以參考「來源連結」,圖如下:
舉個例子,就「常數時間複雜度」而言,通常我們會以「O(c)」或「O(1)」來表示,其代表的意義是「該演算法運算的時間是不會受到其『運算資料量多寡』的影響」,其效率如下圖:
備註:「Big O Notation」為「演算法時間函式的上限(Upper bound)」,意思是就算在「最糟的狀況」下,其演算時間也不會超過「Big Ο」。
然而「空間複雜度」的概念也是類似,即「當演算法的運算資料量增加時,其所需要的記憶體空間變化。」。
重要性
毫無疑問的,「刷題」絕對是紮實基本功的方式之一,但其「重要性」是值得討論的,尤其在台灣。
因為題型的限制,「刷題」的題目幾乎為「演算法」類,但這並非目前台灣軟體業界的主流需求,以一般工程人員而言,如前端、後端或移動裝置應用的開發者而言,「演算邏輯」、「資料結構」…等並非其主要工作內容;筆者的意思是並非說「演算法」不重要,只是相較於「物件觀念」、「代碼維護」、「方法設計」、「框架應用」、「第三方函式庫應用」…等,該類工程人員對於演算法的知識需求並非那麼高。
就筆者的觀點而言,對於上述觀點我是認同的,但是這並不代表我認為「基本功」不重要,事實上,我的觀點是「基礎的培養並非一蹴可及的,它是一種日常的積累。」;而「刷題」就是累積實力的方式,不用急於一時,也不用刻意追求,而是當作閒暇時的練習即可。