2011年6月26日 星期日

DISCONTIGMEM on PXA270

Russell King在回覆給 dera 的 DISCONTIGMEM on PXA270 一文中,提到 PXA270 平台設定
多個 DRAM memory bank 在 Linux kernel 的設計方式:

1. PHYS_OFFSET 從最小的 SDRAM 開始,在該文中是以 0x8000,0000
2. 因為 memory bank 之間有太大的漏洞,必須修改  __virt_to_phys/__phys_to_virt 將你的實體
記憶體壓縮排列到虛擬記憶體中。
3. 因為實體與虛擬記憶體非 1:1 對應,因此不能定義 NODE_MEM_SIZE_BITS, 而是要以單一
bank (該文是 128MB) 設定 NODE_MEM_SIZE_MASK (128MB -1)
4. 定義 KVADDR_TO_NID(vaddr) 將虛擬記憶體轉為 node number
5. 定義 PFN_TO_NID(pfn)轉 page frame number (phys >> PAGE_SHIFT) 到同一
node number (memory bank)
6. 公式就是以下列式必須符合 SDRAM 每一個位址:
KVADDR(vaddr) == PFN_TO_NID(phys_to_pfn(virt_to_phys(vaddr)))
7. Vernon Sauder 在回文中提到 必須考慮到 arch/arm/mach-pxa/Makefile.boot
中定義的 linux kernel start address zreladdr, 有修改為 0x8000,8000.

但實務上現在 arm linux 不應該再使用 DISCONTIGMEM ,而該使用 SPARSEMEM
1. mach/memory.h 定義 MAX_PHYSMEM_BITS 跟 SECTION_SIZE_BITS
可以在 arch/arm/include/asm/sparsemem.h 找到這兩個參數的定義

2.  config 中加入 ARCH_SPARSEMEM_ENABLE 移除 ARCH_DISCONTIGMEM_ENABLE
3. 仍需要修改  __virt_to_phys/__phys_to_virt 將你的實體記憶體壓縮排列到虛擬記憶體中。
4. 確定 sparse memory 的 patch 有上, finish of sparse memory patch

2011年6月19日 星期日

條碼機 維基百科條目

摘譯維基百科英文條目 Barcode_reader

條碼機指的是讀取印刷條碼的讀取機器。跟影像掃瞄器一樣擁有光源、鏡頭、將光學脈衝解讀為電子訊號的感光器(ADC),差異點在條碼機幾乎都包括解碼器解讀影像資料,並將解碼結果傳送到條碼機的輸出介面。

條碼機的種類:CCD, Laser, 2D
CCD 指 Linearized CCD 只能掃一維條碼,只有一維(列)感測器,感應條碼因環境光線而反射後得到的條碼資訊。

Laser 指只能掃一維條碼,讀取打出去的特別頻率光線,再分析反射回來的光線讀取條碼。
2D 指能掃一維跟二維條碼,照相得到影像後再用影像解析解碼

ARM Linux kernel 記憶體配置

摘譯這篇由 Russell King 在 2005 年 11 月 17 日針對 2.6.15 Linux kernel 撰寫的 ARM Linux kernel 記憶體配置

裡面指的是 linux kernel 使用 arm cpu 的虛擬記憶體的位址配置與排列方式

arm cpu 的虛擬記憶體定址空間: 4GB (32 位元的定址空間, 0000,0000 ~ FFFF,FFFF)

沒有遵循這個記憶體配置的 kernel 可能無法開機或發生隨機當機


===========開始=========針對 user space 的加入內容==========================

針對每個 user space 程式而言,其實都跟硬體裝置的記憶體映射空間, kernel 使用的記憶體空間,三者共用整個 4GB 的虛擬記憶體。

user space 程式這個區塊內部的記憶體配置如下:
   +----------------------+---------------------+-----------+------------+------------+
    | Code segment(r+x) | Data segment(r+w) | BSS(r+w)  | Heap(r+w) | Stack(r+w) |
   +-------------------------------------------------------------------------------------+

Code segment 是 instruction memory,儲存程式碼
Data segment 是 data memory,使用 brk(), sbrk() system call 改變或查詢 Program break 大小
BSS segment 是未初始化的 global 變數存放位置
Heap segment 儲存程式執行期產生的動態變數、記憶體區塊由 malloc() 取用,free()  釋放
Stack segment 使用 SP stack pointer 暫存器輔助 IP instrcution pointer 指定,由 function call, 與其 local 變數使用 

註:參考 Memory Management for System Programmers (pdf)

在 Linux 系統底下我們可以藉由 /proc/some_pid/maps 看到執行檔與 library memory map,另外 smaps 則詳列各區段 memory map 的使用狀態。其中可以看到從  0x0000,1000~0xBF00,0000 的載入函式庫與 heap, stack, 其中 stack 與 TASK_SIZE 相鄰

舉某個 android process 為例:
其中

    0xBEBE,9000- 0xBEBF,E00 是 stack 使用
    0xB000,0000 ~ 0xB001,0000 是 linker 載入位置, Thread 0 Stack
    0x8000,0000 ~ 0xAFE46000  是 Non-prelinked libraries
    0x4154,C000 ~ 0x8000,0000 是 mmap'd 記譯體,Java jar library, apk 檔案
    0x4000,0000 ~ 0x4154,C000 是 mmaped open file
    0x0000,A000 ~ 0x003C,4000 用在 heap
    0x0000,1000~0x0000, A000 佔用 .text (code segment) / .data 

Android 2.3 以前的 prelink library build/core/prelink-linux-arm.map 裡面除了重述 Russel King 的 ARM Linux kernel memory 的記憶體配置,Android 的記憶體配置中,包含兩塊系統預設的 library memory mapping:

    其中 Android prelink 定義了以下兩大塊記憶體對應:

    # 0xA0000000 - 0xBFFFFFFF Prelinked System Libraries
    # 0x90000000 - 0x9FFFFFFF Prelinked App Libraries
    可以在 prelink-linux-arm.map 中找到或新增你要加入的 library 記憶體對應。

    # 0xA0000000 - 0xBFFFFFFF Prelinked System Libraries
    0xAEF00000  - 0xAFF00000 # core system libraries
    0xAE700000 - 0xAEE00000 # bluetooth libraries
    0xAE300000 - 0xAE600000 # extended system libraries
    0xACA00000 - 0xAE200000 # core dalvik runtime support
    0xA9C00000 - 0xAC900000 # graphics
    0xA8D00000 - 0xA9B00000 # audio
    0xA7000000 - 0xA8B00000 # assorted system libraries
    0xA4800000 - 0xA6F00000 # pv libraries
    0xA4000000 - 0xA4700000 # opencore hardware support
    0xA3800000 - 0xA3900000 # pv libraries
    0xA2F00000 - 0xA3700000 # stagefright libraries
    0xA2A00000 - 0xA2E00000 # libraries for specific hardware

    # 0x90000000 - 0x9FFFFFFF Prelinked App Libraries
    0x9CA00000 - 0x9F000000 # libraries for specific apps or temporary libraries

# 0xC0000000 - 0xFFFFFFFF Kernel
# 0xB0100000 - 0xBFFFFFFF Thread 0 Stack
# 0xB0000000 - 0xB00FFFFF Linker
# 0xA0000000 - 0xBFFFFFFF Prelinked System Libraries
# 0x90000000 - 0x9FFFFFFF Prelinked App Libraries
# 0x80000000 - 0x8FFFFFFF Non-prelinked Libraries
# 0x40000000 - 0x7FFFFFFF mmap'd stuff
# 0x10000000 - 0x3FFFFFFF Thread Stacks
# 0x00000000 - 0x0FFFFFFF .text / .data / heap

====================針對 user space 的加入內容==========結束================

因為 cpu 架構的發展變化可能影響 kernel 記憶體位置的配置,user space 程式應該只使用到 0000,1000 ~ TASK_SIZE -1 這段記憶體。請使用 open(), mmap() 系統呼叫使用這段記憶體。

    FFFF,8000 ~ FFFF,FFFF           copy_user_page/clear_user_page 使用
    SA11xx 跟 Xscale cpu 建立 minicache 的記憶體位址

    FFFF,1000 ~ FFFF,7FFF           保留
    各平台禁止使用這塊記憶體配置

    FFFF,0000 ~ FFFF,0FFF           cpu vector page
    如果 cpu 支援改變中斷向量位址 (control register V bit), 會把中斷向量映射到這
    4K bytes 區塊

    FFC0,0000 ~ fffe,ffff           DMA 記憶體映射區塊,由 dma_alloc_xxx 的
    函式呼叫都使用這塊記憶體動態配置,總共 0x003F,0000 佔 4MB

    FF00,0000 ~ FFBFF,FFFF          保留給 DMA 記憶體映射擴充使用 佔 12MB

    VMALLOC_END ~ feff,ffff         平台自由運用的記憶體區塊都建議用這段
    VMALLOC_END 必須對齊 2MB 的記憶體區塊
    在 arch/arm/mach-pxa/include/mach/memory.h 中定義

    #define ARM_DMA_ZONE_SIZE SZ_64M 除了以上 16MB 保留給 DMA 另外用了 48 MB
    使用 FBC0,0000~fffe,ffff
    在 arch/arm/mach-pxa/include/mach/vmalloc.h 定義
    #define VMALLOC_END       (0xE8000000UL)

    VMALLOC_START ~ VMALLOC_END - 1 vmalloc() / ioremap() space
    由 vmalloc() 及 ioremap() 取得的記憶體會動態配置在這區塊,VMALLOC_START 相依
    於 high_memory(不能有重疊)
    在 arch/arm/include/asm/pgtable.h 中註解有說明留 8MB 給誤動作的記憶體錯誤緩衝空間,
    定義如下:
    #ifndef VMALLOC_START
    #define VMALLOC_OFFSET      (8*1024*1024)
    #define VMALLOC_START       (((unsigned long)high_memory + VMALLOC_OFFSET) &
                                                      ~(VMALLOC_OFFSET-1))
    #endif

其中 high_memory 在 arch/arm/mm/init.c 的 void __init bootmem_init(void) 計算:
    high_memory = __va(((phys_addr_t)max_low << PAGE_SHIFT) - 1) + 1;

    PAGE_OFFSET ~ high_memory - 1   Kernel direct-mapped RAM region
    這段記憶體對應到平台上的實體記憶體,通常跟系統記憶體是 1:1 的對應
    (direct addressing) 在 arch/arm/include/asm/memory.h 看到 PAGE_OFFSET 定義為
    UL(CONFIG_PAGE_OFFSET)
    也因此我們可以在 arch/arm/include/asm/memory.h 看到以下 virtual, physical 記憶體互轉的
    巨集定義:
    #define __virt_to_phys(x)   ((x) - PAGE_OFFSET + PHYS_OFFSET)
    #define __phys_to_virt(x)   ((x) - PHYS_OFFSET + PAGE_OFFSET)

    其中的 PHYS_OFFSET 實體記憶體在 cpu 定址的記憶體初始(start of bank 0 dram)位址
    ,是定義在同檔案的以下巨集:
    #define PHYS_OFFSET UL(CONFIG_DRAM_BASE) 與
    #define PHYS_OFFSET PLAT_PHYS_OFFSET
    CONFIG_DRAM_BASE 是實體記憶體起始的 offset 值,在 pxa 平台可以
    在 arch/arm/mach-pxa/include/mach/memory.h 中看到定義為:
    #define PLAT_PHYS_OFFSET    UL(0xa0000000)
    我們可以對照 pxa270 spec memory map 章節的 dram map 起始位址
    0xa000,0000 作為實體記憶體的起始位址得到驗證。
    再配合 arch/arm/Makefile 定義的 Linux kernel image text area 值
    TEXT_OFFSET := $(textofs-y)
    而 textofs-y   := 0x00008000 是預設值。
    arch/arm/boot/Makefile 告訴我們 zImage 等 target 就是
     21 #   ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
    因此可以算出:ZRELADDR = PHYS_OFFSET + TEXT_OFFSET = 0xA000,8000 (physical)
    而虛擬位置是 0xC000,8000(virtual),這個計算結果可以跟 Makefile include 的
    include $(srctree)/$(MACHINE)/Makefile.boot 檔案,在 pxa 平台就是
    arch/arm/mach-pxa/Makefile.boot 檔案裡面定義的 zreladdr-y
    zreladdr-y   := 0xa0008000
    在實務上我們也可以修改 zreladdr-y 定義的實體記憶體位址,來改成我們想要把 linux kernel
    起始點放在 physical memory 的哪一個位置上。這也就是為何我們從 boot loader 載入 linux
    kernel 都要指定到某個固定實體記憶體位址的原因,因為在 make kernel 時就決定了這個位址。

    PAGE_OFFSET 也就是 linux kernel image 的虛擬位址起始點, 0xC000,0000 3GB 的 user address
    space

    TASK_SIZE ~ PAGE_OFFSET - 1     Kernel module space
    使用 insmod 動態載入的 kernel modules 會在這段記憶體使用動態配置
    arch/arm/include/asm/memory.h 定義
    #define PAGE_OFFSET     UL(CONFIG_PAGE_OFFSET)

    0000,1000 ~ TASK_SIZE - 1       User space mapping
    每個 thread 使用 mmap 對應到這段位置
    arch/arm/include/asm/memory.h 定義
    #define TASK_SIZE         (UL(CONFIG_PAGE_OFFSET) - UL(0x01000000))
    如果 PAGE_OFFSET = 0xC000,0000,則 TASK_SIZE = 0xBF00,0000 (3GB - 16MB)

    0000,0000 ~ 0000,0FFF           cpu vector page, null pointer trap
    不支援中斷向量重新映射的 cpu 會把中斷向量 page 放在這 4K bytes

關於以上作業系統的 Virtual address map 我們可以使用 arch/arm/mach-pxa/generic.c 與 arch/arm/mach-pxa/include/mach/hardware.h 的建立 memory mapped device 跟 chip select memory mapped device 的 Virtual -> Physical mapping

arm 因為使用到 co processor 15,controller register(1th), v bit (13th), 因此用到 vector page relocate 功能,原本會到 0x0000, 0000 找 vector table 的動作改為到 0xffff, 0000 找 vector table,而我們在 mmu 啟動後使用的 0xffff,0000 Virtual address 就是在 arch/arm/mm/mmu.c 的 devicemaps_init() 中將 Linux kernel 開機時在 arch/arm/kernel/entry-armv.S 建立的 vector table 存在 SDRAM 後,建立一組 0xffff, 0000 high vector page 對映到實體記憶體的 vector table,因此 Linux kernel 開機啟動 mmu 進入 virtual address mode 後才能在硬體發出 exception 中斷時,找到 vector table 處理中斷。

2011年6月14日 星期二

安滅菌

幾個月前,SSH不小心被狗咬傷,傷口不大,但為了安全起見,我帶他前往大醫院就診。醫生診斷問題不大,因為是家中飼養的小狗咬傷,且狗兒也有按時打預防針,所以不需過於擔心,只要口服抗生素一週,再加上一天兩次傷口塗抹藥膏即可。當時醫生開的抗生素,就是最近被衛生署檢驗出含有塑化劑並強制禁用的-「安滅菌」。

「安滅菌」是小兒科常見的抗生素用藥。像鼻竇炎、肺炎、中耳炎都常以「安滅菌」作為治療藥物。
它是白色粉狀,玻璃瓶裝,要自行加水調成糊狀服用。開封後要冷藏保存,三天內吃完。ssh當時只是被狗咬,吃抗生素是保險起見,避免細菌感染,沒想到卻吃進更毒的東西。

2011年6月12日 星期日

就算沒有需要隱瞞的事也要在乎隱私

喬治華盛頓大學的法律教授 Daniel J. SoloveChronicle 寫了篇 Why privacy matters even if you have nothing to hide

摘譯部份如下:

許多人面對隱私爭議時,所持的態度是:我沒有什麼需要隱瞞的。或我沒有做虧心事,不怕別人知道任何事。當然也有變形的說法:我的資訊不值得別人蒐集。

全世界監視器密度最高的英國政府對人民說:如果你沒有要隱藏什麼,就不需要害怕。Daniel J. Solove 在他的部落格提了這個疑問,並詢問重視隱私的讀者都如何回應?

他收到了以下幾種回答:

一、你有裝窗簾嗎?你的信用卡帳單願意借我看嗎?

二、我不需要跟你解釋為何我要保護自己的資訊,你先說憑什麼收集我的資料吧,有搜索票嗎?

三、我的確沒有要隱藏什麼,但我也不想要讓你知道任何事情。

四、要知道我的什麼資料,那你先公開你的吧。

五、這跟我要隱藏什麼無關,而是這些都是我的私事,跟別人無關。

六、如果你真的沒什麼好隱藏,那你可能沒有私生活吧。

其實若我們仔細回想,表面上說得再冠冕堂皇的人,都會想起自己對某些人事物的愧疚,想對某些人物隱藏某些事物以維持關係。重點是你肯不肯面對真實的自己而已。每個人都有自己主觀的意識與真正願意公開的事物底限,誇張點說,有誰願意公開自己的裸照而不害羞的呢?

以上的說法可能都還算偏激的回應。但我們可以回到隱私的意義,每個人可能對隱私有不同程度的定義,但是當我們感覺隱私被侵犯時,感覺是類似的,即使目前被取得的資訊不會影響到生活,會不會又洩露更多資料後,真正開始影響到生活呢?感覺受到監視、怕被知道秘密而被勒索、盜用個人資料導致個人財產名譽受損,各種不要緊的細項資訊結合起來,可能就會拼湊出你不想讓人知道、或被誤解的不實資料。

比如你買了頂假髮,最近常上醫院,於是照資料上來看,可能會出現你得了癌症,正在做化療這種離譜的結論。實際上你可能只是要練習剪頭髮,或想要變裝。

類似這種不想被誤解而想要保有隱私的例子,在個人對個人的人際關係中也可以找到例子。

有些堅持沒有需要隱藏的事就不用在乎隱私的人,他們的論點是,除非造成人員傷亡了才是真正造成隱私損害,這是根本不尊重別人,自私、完全沒有人權觀念的論述。

隱私的侵害也常常是溫水煮青蛙般,逐漸失去的,因為被強迫公開某些資訊而勉強接受,接著進一步的被迫公開更多資訊,直到完全沒有隱私。

如果某天被蒐集的資訊被認為你有犯罪意圖,而像關鍵報告電影般,發生有人因私利栽贓你要如何自救?答案就是保有隱私權。

此文是節錄自耶魯大學出版社出版,喬治華盛頓大學的法律教授 Daniel J. Solove 所著作的新書 Nothing to hide: The false tradeoff between privacy and security。

2011年6月10日 星期五

Jonathan Danylko 二十年來的程式設計心得

Jonathan Danylko 寫了一篇 Top 20 Programming Lessons
 I've learned in 20 years

摘譯如下:

Jonathan Danylko 自十一歲起就已經愛上科技與程式設計。
他發現從事程式設計二十年來有許多困難與容易的課題,也
許同樣身為程式設計師的你沒有經歷過,接下來將要分享他
的經歷與心得(以下的我,如無特別註記,代表 Jonathan
 Danylko 先生):

我會隨著時間修改內容,也許以後會想到更多的事,但目前
這二十條心得已經足以包含所有的程式設計大小事。以下就
是記憶最深的部份:

一、設定你認為解決這個問題要花的時間。不管設定半小時
或一小時都好,當你在自己設定的時間內無法解決某個問題
,就找人問吧,不然趕快上網查資料也好。

二、一個程式語言就只是個語言。當你對單一個程式語言
夠熟,就很容易對其他程式語言觸類旁通,學習效果越來
越好。你用來解決問題的程式語言要讓自己有相當的"
舒適"感,不影響邏輯思緒,可以產生有效率而且簡潔的程
式碼,最重要的是挑一個最適合解決這個問題的程式語言。

三、不要過度強迫自己使用設計模式。有時候一個簡單的演
算法就足夠,不需要再去勉強套上 singleton, facade 設計
模式。對大部份的情況來說,簡潔的寫法最容易懂。

四、永遠要記得備份程式碼。我記得當發生硬碟全毀,資料
完全救不回來的情景,並對曾經發生的慘劇永保警惕之心。
當你忘記備份時,可能就在要交程式的前夕發生悲劇,不管
某一版本程式碼(snapshot)或版本控管紀錄都需要備份。

五、面對現實吧!你不是最強的程式設計師。我以前常認為
自己很瞭解程式設計,但事實上你總是會遇到比你強的程式
設計師。請向他們學習。

六、增進你的學習能力。因為第五項的緣故,我總是手邊帶
著一份電腦書籍或雜誌(我的朋友可以幫我作證),的確目
前電子科技日新月異,要真的完全趕流行可是一份全職工作
才做得來的。當你有足夠聰明的學習媒介與方法,就可能一
直乘著浪頭走。

七、變化是常態。你的科技知識跟程式設計能力應該像投資
股票一樣:分散風險。不要一直專注在單一項目自我感覺
良好。

如果某個程式語言與科技的支援不足,你也可能需要更新
履歷,開始重新練功。讓我保持一直向前的原則:至少要會
兩到三種不同類別的程式語言,當其中一項開始被取代,失
去應用場合,至少你還有可以撐場面的第二專長,並開始繼
續學習新專長,隨時保持熟悉兩、三種程式語言的程度。

八、支援新進人員。幫助並訓練新進開發人員,教導程式設
計原則與技巧。你永遠無法預測下一步...你可能陞官,此時
你會慶幸自己有對新進人員傾囊相授,因為你陞官空缺的位
子將有人幫你抬轎。

九、簡化演算法。撰寫程式時可以窮盡你的能力寫出複雜的
程式,當完成後記得回去檢視你的程式碼進行改善。一點一
滴的程式改進讓你日後可以愉快的維護這份程式碼。

十、為程式碼撰寫文件。不管是網站服務的 API 或是單一類
別的文件,凡寫過的程式必留下文件。我常被批評寫太多
註解,但這卻是我引以為傲之處,為兩三行程式碼註解可能
只要幾秒鐘,如果是用了非常規的解決辦法,則更需要註解
清楚你在寫什麼。

如果文件寫得好,將可以嘉惠設計架構、接手的程式設計師
、技術支援部門的人。

十一、測試、測試、測試。我是黑箱測試的擁護者。當你完
成程式後,就開始要對這段程式負責了,如果你們有品保
部門,你將需要跟品保部門解釋更多程式錯誤。如果你不完
整的測試程式,除了需要改善程式碼以外,還會得到壞名聲。

十二、慶祝每次成功。我看到很多程式設計師解決令人頭痛
的問題,他們會跟同事慶祝,不論是簡單的搖擺、擊掌或是
一段舞動。每個人在生命中遇到美好的事物,寫程式時也可
能因為寫出得意的程式碼想分享喜樂,也許你已經看過類似
的解決方法上百次,還是要記得跟你的同事同慶第一百零一
次的歡樂。

十三、不論是專案或個人的程式,頻繁檢視程式碼。在公司
中你總是有機會檢視程式碼,讓人評鑑你的程式碼品質。不
要認為別人故意惹惱你,把建議當作建設性批評。就個人
而言,永遠都要重新檢視程式碼,並總是自問:

我要如何寫得更好?這將加速你的學習,讓你成為更好的程
式設計師。

十四、回憶自己的程式碼。有兩種看以前程式碼的方式:

我不敢相信以前寫這麼差。



我不敢相信以前寫這麼好。

第一種是覺得以前寫得很差,想知道如何改進。你將知道舊
的程式碼可以如何重構成更好的函式,或甚至改善整個專案
的程式碼。

第二種是驚訝於自己以前的成就,開發者會有一兩個完成的
專案,讓同事對你肅然起敬。當然這是來自你的絕佳的程式
設計能力,你可以拿出以前的函式庫或專案計劃,並改進成
為更好的產品或創意。

十五、培養幽默感。在二十年的開發經驗中,所有同事都抱
著一定的幽默感,事實上幽默感是你在這行業生存的必備
技能。

十六、小心自稱全知、最懂的同事,佔有慾強,與沒經驗的
程式設計師。遇到這些人你反而要表現謙虛。自稱全知、最
懂的人只是想吸引你的注意力,無法成為團隊成員。佔有慾
強的同事完成工作後,不會跟任何人分享。沒經驗的同事每
十分鐘就會問你一個問題,到最後他的程式都是你幫他完
成的,而非他自己寫的。

十七、沒有簡單的專案。我常遇到朋友、家人、夥伴說:幫
我寫個簡單的程式。要寫個簡單的程式或網站,實際上需要
雙方共同規劃,才可能完成一個雙方都滿意的產品。如果有
人說需要使用微軟 Access 寫三頁網頁,實際上他要的可能
需要十五個網頁才能完成的功能,並且需要使用 SQL server
、還有討論區、客製化的內容管理系統。

十八、沒有理所當然的事。當你接下簡易的專案,可能會發
現有些部份很容易解決。別這樣想。在你沒有一份已經完成
的類別、元件、或一段函式,並且經過完整測試,在成功加
入現有專案的產品之後,你再這樣想吧。

十九、軟體沒有完成的一天。曾經有同事告訴我軟體沒有完
成的一天,只有暫時結案。非常棒的建議。只要客戶還在使
用你寫的程式,在經過一段時日的驗證後,大部份情況是你
還在繼續維護同一份程式碼。當然這並非壞事,這樣我們才
有工作。

;-)

二十、耐心是一項美德。當客戶、朋友、家人使用電腦遇到
挫折,最後對電腦元件莫可奈何時。我總是告訴他們:是人
在控制電腦,不要讓電腦反客為主。寫電腦程式時也同樣需
要足夠的耐心,當程式設計師知道自己犯錯,並從電腦的角
度理解之後,就會知道錯誤在哪裡。

希望以上的心得能夠啟發你,或讓你會心一笑。

;-)

2011年6月4日 星期六

Javascript 語法蜜糖 CoffeeScript

摘譯 CoffeeScript 維基百科:

CoffeeScript 是用 ruby 寫的一種 Javascript 程式碼產生器。其中採用了 Ruby 與 Python
(比如 indent 取代大括號) 兩種程式語言的特性來簡化撰寫 Javascript 的語法,另外也
增加陣列轉換 (Array Comprehension)與正規表示(Pattern Matching) 的擴充語法。

使用 CoffeeScript 的好處是可以用更簡潔的程式碼,達到原本用 Javascript 寫出的
同樣功能,而不影響到執行期效能。Javascript 之父 Brendan Eich 表示 CoffeeScript
也影響到他對 Javascript 語言將來的發展規劃。

Ruby on Rails 預計在 3.1 版將會支援 CoffeeScript 。

CoffeeScript 可以在瀏灠器直接執行或透過 Node.js (Server side 執行的 Javascript 程式
,event driven I/O framework for V8 Javascript engie on Unix)執行。

 讀完維基百科後,可以繼續看 PragProg Magazine 的 CoffeeScript 五項改進
一、變數宣告依所在的 namespace 為全域或區域變數,不再因為宣告變數忘記加
var 而覆蓋已經宣告過的全域變數。CoffeeScript 也會將變數限定在單一檔案的匿名
函式中。

二、ajax call 中的 this 在 CoffeeScript 中同樣指到目前 context 的物件,this 關鍵字
也可以用符號 @ 代替

三、CoffeeScript 繼承 ruby 慣例將函式最後的 expression 自動當函式返回值,也可
以在變數賦值的語法 a = 後加上 '->' 自動將 a 由變數改為函式

四、CoffeeScript 在迴圈中使用 do 關鍵字,可以更容易為迴圈加入需取值的函式。

五、提供語法蜜糖,讓程式碼更簡潔

另外據說現在 GitHub 的開放源碼存量已經超過 SourceForge,再來是 Google Code 
第四是微軟的 CodePlex,另外還有支援 Mercurial distributed version control system (DVCS)
BitBucket 可以參考。

CoffeeScript 官網
CoffeeScript@Gihub 
A CoffeeScript Intervension