The two most important days in your life are the day you were born and the day you find out why. -Mark Twain

#88 資訊工程系的大學先修考試 APCS

在美國加拿大的大學入學測試中心成立了一種測驗,名為 Advanced Placement,裡面分成多個不同的專業考試,主要用來測驗高中生在該專業領域的 "程度" 如何.這些專業領域如生物,歷史,物理,語言,統計等等,其中電腦科學也是其中一個專業領域.簡單地說,就是要測驗那些資優班的高中學生,當他們申請大學時,可以附上 Advanced Placement 的成績用來代表他們有多少的能力在這些專業領域裡.詳情可參考 https://en.wikipedia.org/wiki/Advanced_Placement在數年前,台灣教育部也發動了一樣的計畫,其中電腦科學的專業是由台師大資工系來執行,詳情可參考 https://apcs.csie.ntnu.edu.tw/到今年...
Share:

#87 Binary Search Tree 簡介

在 "資料結構" 系列文章裡寫過了 Binary search ,也寫過了 Tree.Binary search 能幫助我們在一個 "排序" 好的資料序列做快速的資料尋找.Tree 提供我們一個資料儲存 (放置) 的結構,當這兩個碰在一起時,產生了一個相當有用的資料結構. Binary Search Tree 的發明比起我和絕大部份的讀者的都還要來的老,它出現在 1960 年代,在那個電腦硬體仍不太發達的年代,這個超級有用的資料結構就被發明出來了.誠如之前談的 binary search 內容,當你要進行...
Share:

#86 貪心方法是最佳解 ?

最佳解? 這種解答是許多問題所追尋的目標.例如,在一個城市裡找到出發點和目的地的最短距離.直覺來看,若你沒有把所有可能的路徑列出來,你怎麼知道那一個才是最短的.再舉例一個例子,在一個 int array 裡面,找出最大值的元素位置.若你沒把所有的元素都拜訪一遍,你怎知道那一個才是最大的.這兩個例子雖然都是在找 "最佳解",但是解法的思考卻不太一樣.第二個例子的思考是 "一條路",而第一個例子是 "多條絡".在 "一條路" 的情況下,對下一個步驟來說沒什麼好選擇的,只能一直往前走.然而,"多條路"的情況下,在什麼路口選擇什麼路,這對答案或執行過程會有很大的影響. 前面已有兩篇文章簡單地介紹了貪心方法.這篇文章要討論的是利用貪心方法得到的解答會是最佳解嗎 ? 用一個簡單的問題來測試.假設郵局提供的郵票面值如下:$10,...
Share:

#85 如何聘用適合的軟體工程師

如果你是一個團隊的領導者,尋找適合的軟體工程師一定是你份內工作裡不會缺少的一項任務.我這邊採用 "適合的軟體工程師" 而不是用 "優秀的軟體工程師",其主要原因在於每個團隊的任務與能力不同,所以無所謂的優不優秀,只要是適合的人,對你團隊來說都是優秀的.人們常說 "物以類聚",這句話適用在許多人類的活動裡,對於建構一個軟體開發團隊而言,其實也是適用的.真正優秀的工程師對於技術含量低的工作通常不見得感興趣,相同地,能力不好的工程師也無法在技術含量高的團隊裡存活下來.這些原因可能來是一個現實的條件 - 薪資.一般而言,薪資高的工作對於工程師的品質也會要求較高,相同地公司付出的薪水也會比較多.這是一個很簡單的經濟學原理 Supply-Demand 的觀念.一個健全的社會裡都是有這樣的現象.因此,身為團隊領導者的你首先必須思考一件事情,你需要什麼程度的軟體工程師.在你設定下了一個範圍之後,接下來的問題便是該如何衡量一個軟體工程師是否適合.以下是我的做法,已經行之有年了,這些做法並不是我發明的,只能說是被...
Share:

#84 程式設計的簡約格式 - 減少程式碼縮排

最近在 code review 的過程中,總是常常會看到一些令人驚喜的事情,其中一件事情和程式的寫法有關.有時候是邏輯可以在簡化,有時候是 coding style 上可以在簡化以便閱讀.首先來看 coding style 可以簡化的部份.在寫程式的過程中,有時會因為業務邏輯面的複雜而造成會寫出多個 nested if statements 的情況,如下面的例子 This file contains bidirectional Unicode text that may be interpreted or compiled differently...
Share:

#83 最近搜尋清單資料結構

最近遇到一個特別的需求有關一種像 Queue 但又不是 Queue 的資料結構 需求如下: 1. 可以自訂清單數量大小 2. 內容一筆一筆的存放,但讀取時是後進先出 3. 如果存放時,該資料已存在,則讀取時它會先被讀取. 舉些實例來說明 以下為動作順序 Initialize as size of 5 Set 1 Set 2 Set 3 GetItems() ==> 資料是 3,2,1 Set 4 Set 5 GetItems() ==> 資料是 5,4,3,2,1 Set 6 Set 7 GetItems() ==> 資料是 7,6,5,4,3 Set 5 GetItems() ==> 資料是 5,7,6,4,3 Set 3 GetItems() ==>...
Share:

#82 K個最近鄰居演算法 (k-nearest neighbor algorithm, KNN)

在大部份的科學領域裡都蠻注重分類 (Classification) 這件事.透過分類,它能幫助我們整理問題,也能整理答案,甚至在不同的問題集合裡找出通用的答案.在人工智慧的領域裡,有一門科目叫模式辨認 (pattern recognition),它應用在影像辨識,人臉辨識,語言辨識等的範圍,其中需要一個重要的技能就是將所要辦認的物件做分類,然後在該分類裡找出合適的對應結果.在這過程中,k-nearest neighbor (KNN) 是一種相對古老且直覺的方法.方法簡單而且能有高準確率,並且不需要所謂的 “訓練”.在人工智慧的領域裡,簡單而言,做的事情就是收集資料,然後依這些資料整理出一個數學模型,未來有新資料出現時,就可以丟入這數學模型加以運算,得出來的結果就是此模型的預測結果.KNN...
Share:

#81 出神入化的用介面 第四集 修改共用的介面 part.2

這一篇文章是上一集的延伸,再來說明新版本 interface 的後續實際使用的情況.先將此篇文章要解決問題再描述一次.想像一家公司出版了一套軟體,而這個產品裡包含了許多的元件檔案 (.dll),而且每一個元件是由不同的團隊產生.每個元件可以有獨立的發行時間,也就是說當 A 團隊要釋出新功能的版本時,他們可以自行釋出.在客戶端裡,可以透過該軟體裡的更新程式來下載並且安裝 A 團隊所製做的新版本元件.由於各元件釋出的時間並非一致,因此元件之間的互動將變得有挑戰性. A 團隊裡的某些功能是透過 B 團隊的元件所完成的.例如,A 團隊提供的功能裡有一項是計算產品折扣,而這項功能的細節實作者其實是 B 團隊,因此 B 團隊會提供 interface component 給 A 團隊使用,如: ...
Share:

#80 寫程式的參考準則 (coding guideline) - C# 篇

曾有一些朋友問我,在微軟公司裡是否有寫程式的準則 (coding guideline).這件事因不同的團隊而異,大部份的團隊都會依循 MSDN 文件裡的建議,但並非每一個團隊都有文件記錄這些準則.以前我在 Windows 部門裡的某個團隊就正好有文件說明 C# coding guideline.除了 C# coding guideline 以外,還有其他的文件,例如 code review 文件, database 開發文件等等.在這篇文章中,我將從 C# coding guideline 開始寫起.這些 coding guideline 不是什麼秘密,很多都是來自 MSDN 的文件.若你的團隊也需要一份 C# coding guideline, 希望能派的上用場. 1. 在一份 C# 原始碼裡,別有...
Share:

#79 貪心策略 - Greedy (2)

上一篇文章談了貪心策略的基本想法,但並沒有提到任何的程式碼來說明貪心策略是怎麼進行的.其實貪心策略並沒有一個很明顯程式碼撰寫方式,如果硬是要湊出一個程式碼外型的話,我覺得它的長相可能如下: while ( 依問題條件來決定是否要繼續下一步 ) { // 1. 依照問題,在這一個步驟裡取得最佳解 // 2. 根據步驟一得到的最佳解來決定程式的下一個狀態 // 3. 將程式目前的狀態移動到下一個狀態,下一個狀態將會更接近最終的答案 } 老鼠走迷宮是很典型資料結構 Stack 作業,它的內容是假設一個方形的土地,這土地用畫分成許多面積相等的小格子,就像棋盤那樣.每一個格子都是一種地形,如山,河,平地.老鼠只能走平地,不能爬山也不能過河.老鼠將從起點走到終點,起點是在這土地的左上角,而終點是在右下角.這個作業就是要讓老鼠能走出一條路從起點到終點.如果沒有路存在,則最後的答案是...
Share:

#78 貪心策略 - Greedy (1)

前面的文章曾提過,在這世界上有很多不同類型的問題,基本上我們太不可能找到一個方法來解決所有的問題.所以,不同類型的問題就會有不同的解法.有的解法很好理解並且單純,有的解法不易理解.解法本身並沒有所謂的好壞,只有適不適合使用的情況.通常來說,難的問題若要有好的執行結果,通常那個解法不見得簡單,就算是簡單,也絕非容易可以想的出來.這也許就是演算法美妙的地方,或許可以說是邏輯之美.廣泛地也可以說成是數學之美,都是宇宙空間裡所擁有的一些特質. 今天要提的解法是一種貪心 (Greedy) 的 “精神”.若你沒念過演算法這門課,恭喜你可以免除這個宇由特質的迫害,可以遠離那種整晚埋頭寫作業的崩潰時光.我想我是比較笨的,所以我以前寫演算法和計算理論的作業時,常常抱著頭在燒.如今,回頭看看,這些都是人生裡蠻有趣且值得回憶的時光.演算法課本裡,前面一半的內容中主要是提到一般市面上對問題的...
Share:

#77 部落格的原始動機與人生所需的財務智商

這篇文章來分享二個主題,第一是為何我開始寫這個部落格,第二是人生所需的財務智商. 我在 "大毛電腦科學筆記" 裡從 2015 年 3 月開始寫下第一篇文章到現在已經有三年半的時間了.剛開始的第一年,由於我沒有設計任何的讀者回饋方式,因此第一年並不知道寫的內容是否有用.後來第二年開始加入 Google Form 讓讀者們可以留下回饋資訊,並且也為網站上加入 Google Analytics 用來查看網站的流量資訊.大約一年前成立了 Facebook 社團以及舉辦公益課程來做為另一種推廣此部落格的管道.從去年 (2017) 開始,我陸陸續續收到一些讀者們的回饋,有些是單純地謝謝我寫這些淺顯易懂的內容,也有些是來問我一些工作上的問題.謝謝大家的捧場和問題讓我知道這個部落格已經發揮了一些作用.其實,我最早的想法並不是寫部落格,而是打算把所有的資訊匯集成冊出版用.早在十年前,我收集了以前在台灣和美國念的上課筆記,打算將這些內容寫成書來出版.但可惜,後來因為搬家緣故,那一大本的筆記已下落不明,所以把筆記匯集成書的想法便中斷了.但我並沒有忘記要分享電腦科學的基礎知識這件事.後來心想,匯集成冊需要大量時間並且有出版時程的壓力,於是...
Share:

#76 演算法裡一個基本的觀念 - Reduction

Reduction 是一個在演算法知識裡基本且簡單的觀念.其實在各位的工作中也一定常用到這觀念,只是你不知道而己.在這文章裡一如往昔,不用學術理論的描述方式,而是用平常寫程式的例子來讓非電腦科系畢業的資訊人了解什麼是 Reduction. 接下來用寫程式的角度來看什麼是 Reduction.假設你需要寫一個影像辨識的程式,這個程式需要辨識一個圖片裡是否含有某個數字,所以你寫的 function 可能會像下列: This file contains bidirectional Unicode text that may be interpreted...
Share:

#75 將問題和演算法分類

學習基礎的演算法過程中,許多課本最常用的方式是將問題分類好,然後對每一類問題進行討論並給出一些著名的演算法來解決這一類的問題.因此,要了解自己面對的問題屬於那一類型的問題便是件重要的課題.在這一系列的文章中,我的目的並不是要告訴你大學課程的演算法內容,而是希望用一種比較實際工作上會遇到的普遍情況來說明在工作中可能會碰到跟演算法課本內容有關係的課題.就像上一篇文章提過的,演算法的內容就像是你寫的程式裡某一個 function,每一個 function 一定有一個特定的目的.因此,你可以想像世界上存在許多的演算法,每一個演算法都有一個目的.當你認識了許多演算法時,有一個簡單的方法來分類演算法的種類,就是按照目的來分類.只要你知道你的問題是屬於那一類,這樣你就知道該去找那一類的演算法.例如,你的工作裡某一個任務需要將資料庫中的訂單做排序,因此,你就可以在市面上找到許多的排序演算法,挑一個適合用在你的工作裡.排序是一個相當簡單的例子,你甚至不用找演算法,因為這類基礎的演算法都已被實做在許多產品裡.另外一個例子,你的工作是做一個檢查文章裡的英文字是否拼錯,如果拼錯的話,必須列出一些建議清單來讓使用者選擇.這一類的演算法通常不會在一般的...
Share:

#74 演算法從零開始

資料結構和演算法算是最基礎而且重要的知識.若沒有這兩個科目的足夠知識的話是很難在其他電腦科學領域有所進步的,其中也包括程式設計這一條路.基本上來說,程式設計這條路需要強大的邏輯基礎,除了你得對 if .. else .. for loop 用的很熟練外,你還得了解你所用的 SDK, framework 的優缺點,這樣使用起來,你才知道你的 SDK, framework 為你的程式做了什麼事情.除此之外,你便需要知道資料結構和演算法的基本知識,這兩個學科是能幫助你寫出好程式的關鍵. 從前面的文章裡,我談了許多資料結構及其應用,也談了許多面試考題.當你看完那些文章後,你應該能抓到一個重點,這重點就是儘量地省時間 (省運算步驟),不然的話,就得用空間來換時間 (提高空間複雜度來降低時間複雜度).雖然每一種問題的情況都不一樣,不見得都能用空間換時間,但至少這是一個讓你思考的方向.演算法在這過程中扮演了重要角色,因為這門學問能幫助你辨別問題,知道什麼樣的問題...
Share: