跳到主要內容

發表文章

目前顯示的是有「book」標籤的文章

書籍推薦 -- SICP

Structure and Interpretation of Computer Programs (SICP) 是非常經典的一本程式設計"入門書"。英文的資訊非常多,也有不少針對書中作業的討論( Eli Bendersky , Scheme Community )。由於正體中文的資訊不多,所以我想寫一篇 blog 來紀錄目前的閱讀心得,希望對還沒看過這本書的朋友(或翻過但還在觀望)有些幫助。 這本書建構了程式設計中各種設計取捨與手法的一個 mental framework。開發軟體時我們會遇到各式各樣的問題,針對不同實務問題我們有許多的慣用法去解決,但這些慣用法背後的精神卻只存於經驗豐富的老手心中,難以言表,導致一般新手不易感受。這本書講的就是作者在選擇設計手法時的系統化方式與思考轉折。 書中使用的語言是 Scheme ,雖然不是一般主流的語言,但作者刻意這麼選擇是有道理的。Scheme 的基本語法極其簡單,但抽象化的威力強大,可以在短短的幾行程式中轉換其設計典範。不同的設計典範各有其適合範疇,作者藉由實例與練習題讓我們不斷思考為什麼這樣比較好、為什麼那樣比較好、為什麼... OK~如果你好奇書中到底提了哪些資訊,以下是我目前的讀書摘要: 使用 procedure 建構抽象化。第一章講得是基本要素:基本型別與 procedure。千萬不要以為這部份跟其他語言書籍一樣無趣,這章從最基本的四則運算開始,逐漸引進 recursion的概念,而 recursion 的各式手法也逐一討論,並且在讀者熟悉用 recursion 計算簡單的數值問題後,開始將 procedure 當作 first class object ,在 procedure 間傳遞操作,引進更多設計手法。到這章結束後,我發現自己以前根本就沒善用 procedure 的能力(原因之一是常用的 C/C++ 不易用簡單的方式完成 procedure 的任意傳遞與組合)。 使用 data 建構抽象化。第一章將 procedure 與一般 data 的界線弭平了,但很多時候我們需要強化的概念是在操作的對象本身。我們會希望用簡單的方式看待複雜的 data 與其使用方式。第一章的 data 都是基本數值,雖然說電腦看到的都是數值,但對人類來說,想看到的是 picture, p...

Book review:專業嵌入式軟件開發

這本書 講得是嵌入式系統的軟體開發,嵌入式系統的形貌多樣,這本書將系統開發者所應俱備的基礎摘要出來,值得研讀。此書共有六大篇,分別為: 硬件篇:嵌入式軟體的開發常常脫離不了對硬體的直接控制,所以基礎的硬體知識在一開始就說明。當然,實際開發時仍需與硬體工程師請教細節。 工具篇:作者花了非常大的篇幅介紹了makefile的撰寫,makefile作為C語言的主要建置工具,能夠善用它的能力規劃出模組化、易分工的開發環境變得非常重要,但現實業界的工程師真的了解的卻不多,使得許多SDK釋出後,客戶問題一大堆...除了makefile,也簡要說明了gcc、binutils、ld、gdb...利器善事,雖不難,但很重要。 編程語言篇:嵌入式系統中,C語言的使用佔據核心地位,所以俱備解讀C語言轉換成組合語言的過程同樣也是必須的。在這篇中,作者一步步說明x86上的轉換,並畫了許多示意圖,相當實用。 設計篇:軟體設計的重點在於設計。這是再明白不過的道理,但許多業界的工程師卻對設計的概念非常缺乏或觀念偏差。如何在模組化、效率與開發時程取得平衡?這篇涵蓋的幾個章節值得一看。比較可惜的是,沒有舉出其他類似專案的手法作為對照比較,這個部份可以閱讀其他設計書籍來補充。 操作系統篇:這篇是這本書的血肉。作者實現了一個在user space運行的OS - ClearRTOS,藉由實現部份作業系統的功能,展現嵌入式系統的核心軟體技術。跟著實作其中的功能,我們可以知道context switch、scheduling、stack overflow detection、synchronization...如何完成,知道如何實現簡易版本對我們理解業界使用的複雜作業系統有很大幫助,可以很快地抓到其重點。 質量保證篇:這篇講述了一些提升軟體質量的方式。作者不打高空,提出的方法與技巧都已經時間驗證。像是:單元測試、assertion、coding style、static analysis、dynamic analysis、profiling...都可以為軟體品質帶來立竿見影的好處。 我們可以看到,完成嵌入式系統的軟體設計需要多少功夫,這些知識必須扎扎實實地被軟體工程師所理解才行。雖然每一個篇章都有更多書籍與專案可供參考,但我覺得這本書提出了一個門檻,如果不完全理解此書內容,甚至很難說自己...

Hackers and Coders

今天想跟大家分享一下我這陣子讀的兩本書,算是非技術類的計算機書籍。一本從歷史的角度出發,介紹黑客文化;另一本則是數位頂尖coders的訪談記錄。雖然風格與取向不同,但共通點就是 - 非常有趣。我想,應該適合所有喜歡計算機的朋友參考看看。 1. Hackers: Heroes of Computer Revolution 這本書從黑客的起源開始講起,描述了計算機領域的第一批黑客如何誕生,他們如何看待這個世界,如何進行思考,甚至往往在不經意的情況下改變了這個世界。閱讀這本書,你會看到不同類型的黑客,差距之大令人難以想像,但他們也有不少共同點,包括喜歡進入極度專心的思考狀態、喜歡了解事物最根本的運作機制、熱愛開放與自由。如果你也是覺得計算機這個東西很神奇,想要探究這個人類智慧的結晶,進而愛上程式設計,那麼這本書真的值得好好看一下。  2. Coders at Work 如果第一本書引起你的興趣,那這本Coders at Work就更不能錯過了。此書作者專訪了十幾位黑客中的黑客,每位都是公認的master,更有趣的是,作者提出了許多有趣的問題,這些問題在目前的情況來說,似乎都有不同學派提出解決方法,但我覺得要實際解決問題,往往還是要我們動手之後才真的明瞭,無論在哪個知識領域其實都是如此,但在軟體領域這點更是少數的不變定律。也因為如此,當我們有機會看到在計算機領域真的有所成就的大師們提出建言時,我認為這些智慧話語比什麼都還珍貴(當然,要經過思考後再決定是否接受其觀點)。另外,你也可以看到,即使是這些大師,他們也幾乎都還是每天不斷地寫程式呢!!相比之下,台灣不少程式設計師一天到晚想著哪天可以不用再coding,實在是...唉... :-(

From Nand to Tetris - Step I

如果有一本書,教導你如何從無到有設計一個計算機系統,並且最後可以在上面開發小遊戲,你的感覺如何?我覺得棒呆了!! 最近發現一本很好的電腦書籍 - The Elements of Computing Systems ,這本書就指導讀者如何從基本的邏輯元件設計開始,逐步地完成CPU、Memory、Assembler、Compiler、OS,最後則是一些小遊戲。所以在這個過程我們要學習如何撰寫HDL、如何設計CPU、如何設計memory、如何實作assembler、如何實作compiler、如何實作OS,到最後就是一些應用程式(我的目標是俄羅斯方塊)。 並且完全是依靠自給自足的開發環境來完成這個過程,所有的工具都是作者自行設計實作的,也都open source,可以盡情hack。 在網站上提供的各種教學文件非常完整且獨立,我們可以一步一步完成每個組件,讓新的組件依據我們前一個完成的基礎去運作,也可以隨意跳到喜歡的章節開始實作該組件,完成後可以進行模擬的測試。 這本書並不厚,因為作者在書中描述的主要是觀念,然後將工具的使用說明放在網站上,我蠻喜歡這種作法,因為這樣書籍可以專注在知識的呈現,而操作就在電腦上直接執行。由於我打算將這本書精讀,並實作每個projects,所以定一個hobby project給自己,就叫作FNTT好了,意思是From Nand to Tetris(這也是作者開的課程的名稱),今天剛完成第一章的習題(如果你也有興趣的話,歡迎一起參加這個 小專案 ),是用HDL設計幾個基本元件,截圖如下,很酷吧? :)

Book review : Introduction to Computing - part III

Chapter 9 Mutation Scheme的語言特性中也包含了改變物件狀態的模型。由於一般主流語言都是imperative的作法,所以一般業界的programmer應該對這章的概念不會陌生。有趣的是,由於Scheme慣用的functional paradigm會因為imperative的引入而造成很多的副作用,所以在使用時多了許多要考慮的地方,這章也慢慢引入如何用Scheme作語言內的小語言(internal DSL)的手法,作者用了一些技巧,讓Scheme中沒有直接支援的許多imperative construct(ex: while loop)可以產生出來。從這章也可看得出來,Scheme很適合作為發展internal DSL的host language。 Chapter 10 Objects 在與imperative programming結合後,當然不能略過物件導向技術的討論啦~Scheme一般的實作品並沒有物件導向的成份在裡頭,不過從Chapter 9我們已經學到不少擴展語言的技巧,同樣地可以套用到物件技術身上。作者討論了物件技術的基本概念,並在Scheme中實作了一個物件模型,從這章更可以清楚的認知到,Scheme真的是一個非常強大的語言,幾乎可以不費太大力氣就改變其風貌,變化成另一種型式程式設計方法。本章最後一小節則講了物件技術的小歷史,主要是Alan Kay開發出第一個廣為使用的物件語言-Smalltalk的經過,很有趣喔~ Chapter 11 Interpreters 如果你有看到我的前一篇文章,你就會知道我最近在搞些什麼?沒錯!!就是interpreter!在看了這章後,看到作者用短短幾行Python程式碼就實作出Scheme interpreter時,實在是很震驚。"A-ha"的感覺不斷灌進腦袋。程式設計的領域很廣,最吸引我的一部份就是抽象化的各式手法,在"The practice of programming"一書中也有花整章在討論這點,最低階的抽象化大概算是命名,接著是在使用的語言內進行介面的抽象(像是C語言中的printf; C++中的STL ),再更進一步就是設計新語言,而新語言的設計可以透過interpreter的型式進行許多語言的概念性試驗(compiler會複雜許多,...

Book review: Introduction to Computing - part II

Chapter 5 - Data 為了避免程式設計師直接透過數字去思考問題,每個程式語言都會提供一些對欲處理的資料的抽象化機制來讓這些010000111變得有意義。這章開始說明Scheme提供的機制,包括:pair, list, tagged list for data abstraction,有了這幾個機制,實作適當的ADT(abstract data type)就不是件難事。要特別注意的是,Scheme裡對list操作的頻率極高,最好將每個習題都作一下以了解what is the Scheme way。最後一小節替第一章到第五章的內容作了個小結,一步步實作了一個較大的小遊戲。 Chapter 6 - Machines 這章從講古開始...機械式計算機的發展、數位計算機的發展、第一個程式設計師,然後重點在Turing Machines,基本上...嗯,這章我沒什麼"A-ha"的感覺。:P Chapter 7 - Cost 這章講的是如何估算程式執行的代價。嗯,基本上就是把Big-O、Omega、Theta的表示法與估算如何進行講一遍。熟悉基本資料結構與演算法的同學這邊可以快速翻過。 Chapter 8 - Sorting and Searching 學了如何估算複雜度之後,當然就要舉一些實際的例子來驗證啦~這章講的是經典的sorting與searching。雖然不比專門的演算法教科書深入,但用Scheme來表示這些算法還是很好的練習。不過跟前一章一樣,如果你對基本的算法已經很熟悉了,那就很快地翻過去吧~(不過小弟自己的經驗是,工作了幾年後,還是應該要定期複習基本學科,免得在工作裡用了太過糟糕的算法,會被後續維護的工程師笑(罵? )...) OK,接下來就是此書的精彩章節了,還有一章會實作Interpreter呢!!Watch out!! :)

Book review: Introduction to Computing - part I

除了系統程式以外,我對各種程式設計的思考方式也很有興趣,尤其是在硬體為主的工作環境中,我的每日工作脫離不了與底層細節打交道。但軟體的領域如此廣泛,有很多有趣的軟體知識是可以獨立於硬體而進行的抽象思考。在" Introduction to Computing "這本書中(快下載,作者open給大家喔!!),作者便是希望將這些重要的知識強調出來,讓剛入門計算機領域的學生知道資訊科學中最要緊的是哪些概念。 我其實還未讀完這本書,目前只讀到了第四章左右,但覺得實在值得推荐給想學習程式設計的學生(或那些從來沒碰過functional programming的程式設計師),所以日後會陸續將部份心得繼續紀錄下來。這篇文章會先紀錄到目前為止我所學到的東西。 Chapter 1 - Computing 我們有不少人寫了好幾年的程式,控制計算機進行計算,但我們仔細思考過計算的意義嗎?什麼是資訊?什麼是資訊的處理?資訊如何表達?作者選擇了從比較寬廣的角度來思考計算這回事,並討論"計算"這件事到底是科學、工程、還是藝術? Chapter 2 - Language 這本書不同於其他的入門書的地方從這章開始展露無疑。作者從控制計算機的主要媒介 - Language,開始討論起。先討論了日常語言的構件,然後介紹如何利用Recursive Transition Networks與Replacement Grammers去表示一個語言。然後在後續章節會不斷的用這些概念去說明要提出的主題。 Chapter 3 - Programming 前兩章都沒有寫到任何的程式碼,這章開始介紹了本書中所用到的主要程式語言 - Scheme (用的是 DrRacket 的編程環境)。Scheme是一個LISP的方言,特點是極為簡潔的規則以及語法,但又支援非常強大的抽象化能力,並與底層隔離的很漂亮,很適合作為學習計算本質的程式語言。 在這章中會開始感受到何謂functional programming。下面是我練習時的DrRacket截圖,很漂亮吧? Chapter 4 - Problems and Procedures 這章開始真正展示functional programming的威力。我們可以依序看到如何透過Scheme的一致性語法做到p...

Book review: System Software 系統程式

今天跟大家推荐一本由金門大學的陳鐘誠教授所撰寫的系統程式教科書,書名叫作,嗯...就叫作" 系統程式 "。:) 因為小弟一直對系統程式非常有興趣,所以只要看到有什麼新鮮的東西,不管書籍或文章,必定都會儘可能地加以拜讀。但是講解系統程式的許多作者,往往才高八斗,很多時候一個段落裏面就提到了數個我們可能之前都沒有過的概念與名詞。很多愛好者都是在各種模糊中努力打滾了許久,才慢慢獲取一些基本概念,但其實我們可以不用這麼辛苦。 這本書的最大優點就是將許多看似神祕複雜的概念簡化再簡化,直到不能再簡化了為止,然後讓你看到: 1. CPU如何設計與實作其虛擬機 2. assembler如何設計與實作 3. Linker與Loader如何設計與實作 4. compiler如何設計與實作 當我閱讀到書中所設計的極簡版CPU0時,心中不免有些疑問,"天啊,買錯書了,這本書太過基礎了...",但很快地,當我繼續跟著作者一步一步的實現出assembler、compiler、virtual machine,並且用自製的compiler去編譯source code為assembly code,然後再用assembler去組譯assembly code為執行檔,最後在CPU0的虛擬機上跑出1+1=2的結果時,真是令人興奮啊!! 於是,我們可以用很短的時間(我大約花了兩周的時間閱讀並實驗書中的實作)就獲得一個具體而微的計算機系統,並了解了重要組件之間的合作關係。總的來說,這本書值得那些想了解神祕的系統程式的愛好者閱讀,也值得要寫教科書的作者學習,看看要如何以簡單的方式解說複雜的系統。 講完了優點,來講缺點...有些部份簡略的有些過頭了,應該再加入一點解釋,比如說compiler的步驟為何要切割成數個?沒碰過compiler的學生大概很難理解為何會需要abstract syntax tree吧?另外程式碼的部份,應該可以教導學生在面對較大結構的程式時,要如何進行切割,適當地引入一點C的慣用法,畢竟系統程式中,以C為大宗,熟悉其慣用法也是蠻重要的,舉例來說,很多地方用了超巨大的switch case,如果試著用table of function pointers或structure with callback funcion去化簡主結構的邏輯...

Book Review:The Practice of Programming

The Practice of Programming(中譯本:程式設計專家手冊)講的是軟體開發實務上的一些經驗談,包括了編碼風格、效率調校、測試、除錯、表示法...等。 這些主題每個程式設計師每天都會遇到,所以每個人或多或少都慢慢有自己的一套處理的方式,有時不同類型的設計師之間對於同一個主題甚至會有南轅北轍的作法,有時各自都可以運作的很有效,但更多時候我們其實只是在多次的失敗中學到寶貴的經驗,勉力賺取經驗值,然後逐漸修正每一個細節。 如果有這麼一本書,總結了經驗值破表的編程大師的數十年心血結晶,你會不會心動?這就是這樣子的一本書。Brian W. Kermighan是C語言聖經K&R的K,並開發出許多Unix下的軟體(AWK的K也是他),Rob Pike也是開發過數個程式語言(目前google的GO),以及作業系統(plan 9)的大牛。他們的編碼時間比大多數的程式設計師的年紀還要大的多,所以當他們提供編程上的意見,實在值得我們好好花時間思考學習。 我簡單摘要章節內容: 第一章 風格 這章講的是coding convention,或許很多人會覺得老生常談,畢竟每天都在命名、使用函式、設計新strucure、類別、模組、為程式加上註解...連入門一兩年的菜鳥都該很熟悉吧?非也,單就命名這件事來講就大有學問,程式碼要能夠讀來簡潔易懂,第一關就是好的名稱,不好的名稱很容易誤導閱讀代碼的人,造成後患無窮的結果。從這基礎但極其重要的編程環節,你可以窺見大師是如何思考代碼的細節。 第二章 演算法與資料結構 這章比較沒有太多思想在其中,但因為基礎演算法與資料結構對任何程式都是如此重要,所以自然也佔有一席之地。作者提供了個很不錯的觀念:對某些應用來說,演算法的重要性的比重可能會佔到絕對的地位,但對絕大多數程式來說(甚至包括作業系統、編譯器),往往大量使用的都是些基本的資料結構,或從基礎型式去做工程上的微調修改。所以別因為害怕大程式需要高深的演算法,通常都是需要時才去尋找適合的來用,畢竟,嗯...計算機科學家每天就是在搞那些東西。那麼,哪些算共同必備的基礎呢?作者列出:Big-O表示法、search、 sort、list、growing array、tree、hash table,夠基礎了吧? :P 第三章 設計與實作 這章開始進入本書精彩...

Book Review: 程式設計師的自我修養

這本書的書名很特別,所以一開始就讓我很好奇地拿起來翻閱,講述的內容也較為少見,講的是連結、載入、以及執行期程式庫。 這樣的主題在實用上可能並沒有立即的效果,但對程式設計師而言,這三大主題可看成是我們所撰寫的軟體與作業系統之間的重要轉換過程,瞭解了這個轉換過程,就會更進一步發現系統程式在整體架構上的許多設計考量,這樣的訓練可以幫助在未來想從事系統程式時,提供整體的紮實觀念。 甚至,當我們想撰寫的程式是要跑在裸機上時(像boot loader或作業系統),完整瞭解這本書中提到的概念,才有可能對如何完成有所了解。 好了,廢話不多說,我來簡單摘要重點章節的內容吧~ Chapter 1 溫故而知新 這章講的是必要的基礎概念,是閱讀此書所必須先俱備一點作業系統的概念,包括:多工、排程、記憶體管理...當然啦,你不需要是作業系統專家就可以閱讀這本書(因為我也不是),不過如果有過一點kernel programming的實務經驗的話,應該會更能"體會"。:) Chapter 2 編譯和連結 這章講的是C語言如何從原始碼轉變成可執行檔的過程,當然啦,主要的細節會在後續章節補上,但先有個大局觀,的確是不錯的開始。 如果你稍有程式經驗的話,基本上前兩章應該可以毫不費力地讀完,搞不好一杯咖啡還沒喝完就翻完了,不過要注意,從第三章開始就是本書的重點嘍~ Chapter 3 剖析目的檔 在開始講述實際的連結動作之前,作者先從.o檔的格式下手,剖析的標的是Linux 32bit ELF,俗話說的好,要閱讀一份龐大的原始碼時,從它的資料結構下手幾乎會是最好的開頭,剖析目的檔也有類似的現象。目的檔經過多年的經驗累積去調整,有許許多多的欄位塞在裏面,了解重要的幾個欄位,是追蹤時先備的要件。 Chapter 4 靜態連結 靜態連結就是在執行檔被產出的那個moment完成了全部的符號決議與位址計算。沒錯,就是這個moment!!這章講解這個過程如何完成。當完整了解這章後,你應該就完全能理解如何在裸機上寫程式了。酷吧?這是我閱讀這本書的第一個"A Ha"moment~很爽啊~ Chapter 5 Windows PE/COFF 原諒我,我沒有讀這章,因為我實在對M$的環境...