網頁

搜尋此網誌

2013年12月19日 星期四

Debian package 套件開發工具

Debian 套件 (Debian package) 有兩種類型,一種是執行檔套件 (Binary package),另一種是原始檔套件 (Source package),一般使用套件管理工具 (如 apt-get ) 安裝的都是執行檔套件。
  • Binary package
    以 .deb 為副檔名,套件裡面包含可直執行檔、組態檔 (configuration file)、man/info 頁面、版權資訊與相關文件。
  • Source package
    包含兩個部分,以 .dsc 為副檔名的描述檔,以及以 .orig.tar.gz 為副檔名的壓縮原始檔,另外也有可能包含一個以 .diff.gz 為副檔名的壓縮檔。
這裡我主要討論最常使用的 Binary package ,說明建置一個執行檔套件需要有哪些套件?在這裡我將採取最原始的 Debian 套件管理程式 (dpkg) 進行這項工作,使用 dpkg-deb 指令建置 Debain 套件。當然,也有其他高階的工具可以使用,不過那隱藏了一些細節,我認為不利於學習,所以我還是採用 dpkg。

由於系統預設已安裝 debconf 和 dpkg 兩個套件,下列是 Ubuntu 內建的指令:
  • 屬於 dpkg 套件
    • dpkg
    • dpkg-deb
    • dpkg-divert
    • dpkg-maintscript-helper
    • dpkg-query
    • dpkg-split
    • dpkg-statoverride
    • dpkg-trigger
  • 屬於 debconf 套件
    • debconf
    • debconf-apt-progress
    • debconf-communicate
    • debconf-copydb
    • debconf-escape
    • debconf-set-selections
    • debconf-show
    • dpkg-preconfigure
    • dpkg-reconfigure
  • 補充:其中有一個 dpkg-log-summary 指令是屬於 xdiagnose 套件,在此不列入。
當我們想要建立一個執行檔套件時,使用內建的 dpkg-deb 指令就可以開始建置,不需要再安裝其他套件。但是一個 Debain 套件包含相關設定,該如何開始學習呢?這時候就必須參考說明文件,除了線上文件之外,建議安裝 dpkg-dev 套件,或是 build-essential 套件 (build-essential已包含 dpkg-dev),dpkg-dev 除了提供一些指令之外,還包含很多有關 Debain 套件的說明文件,對於學習相當有用。

安裝指令是 sudo apt-get install dpkg-dev 或 sudo apt-get install build-essential,安裝完成之後,Ubuntu 將增加下列說明文件,請使用 man 指令讀取:
  • deb-control
  • deb-extra-override
  • deb-old
  • deb-override
  • deb-shlibs
  • deb-split
  • deb-src-control
  • deb-substvars
  • deb-symbols
  • deb-triggers
  • deb-version
  • deb
  • dpkg-architecture
  • dpkg-buildflags
  • dpkg-buildpackage
  • dpkg-checkbuilddeps
  • dpkg-distaddfile
  • dpkg-genchanges
  • dpkg-gencontrol
  • dpkg-gensymbols
  • dpkg-mergechangelogs
  • dpkg-name
  • dpkg-parsechangelog
  • dpkg-scanpackages
  • dpkg-scansources
  • dpkg-shlibdeps
  • dpkg-source
  • dpkg-vendor
參考資料:
補充:還有 debconf-doc 套件有其他的說明文件。
###

2013年12月11日 星期三

nginx 網頁伺服器

nginx (念作 engine x )是一個由 Igor Sysoev 所開發的伺服器軟體,主要用作 HTTP 和反向代理伺服器,也可以用作郵件代理伺服器。

在 Ubuntu 上安裝只需要使用 apt-get 安裝即可,指令是:sudo apt-get install -y nginx

總共會安裝 3 個套件:nginx, nginx-common, 與 nginx-full,nginx 套件設定的套件相依性,提供 nginx 安裝的進入點,nginx-full 套件包含 nginx 的執行檔,而 nginx-common 則是預設設定檔和說明文件。

安裝完 nginx 之後,預設是沒有開啟伺服器,請用 sudo service nginx start 或 sudo service nginx restart 啟動服務,在瀏覽器輸入 http://127.0.0.1 將會看到「Welcome to nginx」的訊息。

nginx 的設定檔是 /etc/nginx/nginx.conf , 預設的使用者名稱是 www-data,有一個預設虛擬主機的設定檔在 /etc/nginx/sites-available/default ,相關的參數設定可以參考 nginx 核心功能的說明。

最後介紹一本參考書籍,由佳魁資訊所出版的「Nginx-完全取代Apache,超輕、快、強的Web伺服器」,這大概是中文第一本有關 nginx 的書籍,全書共分為四篇:基礎篇、進階篇、實戰篇與模組篇,大致上涵蓋所有 nginx 所需要的知識。不過書上所介紹的 nginx 版本是 0.6.x 版,目前已經是 1.4.x 版,Google 之後發現原簡體書是 2010 年所發行的,目前看來內容稍微舊了一點,但這不影響學習與參考的價值。

張宴,Nginx-完全取代Apache,超輕、快、強的Web伺服器,台北:佳魁資訊,2012。
譯自:實戰Nginx:取代Apache的高性能Web伺服器,電子工業出版社,2010年3月。

補充,目前2013年佳魁資訊已再出版另一本「王者歸來:進擊的伺服器 - 用Nginx取代Apache建立全語言種類的雲端網站」,有興趣者可以參考。

###

2013年12月3日 星期二

Lexical structure of JavaScript and Python 詞彙結構

詞彙結構 (Lexical Structure) 是程式語言最基礎的規則,說明如何使用一個程式語言撰寫程式。當程式語言定義一套詞彙結構之後,程式開發人員撰寫程式碼,詞彙分析器 (Lexical Analyzer) 將程式碼分析為標記 (token),解析器 (parser) 處理標記才能給編譯器或解析器處理,由此可知,一個程式語言最底層的是詞彙結構,若要設計一個程式語言,也應該要從詞彙結構開始。

這裡我將比較 JavaScript 和 Python 這兩種程式語言的詞彙結構。

JavaScript (ECMAScript 3) Python (2.6)
字元集 (character set) Unicode 預設是7-bit ASCII
可使用特殊註解指定字元集
# -*- coding: encoding -*-
識別字 (identifier) 區分大小寫 (case-sensitive)
字母、底線或錢字符號開始
區分大小寫
字母或底線開始
註解 (comment) //雙斜線表示單行註解
/*斜線與星號之間為多行註解*/
#數字符號 (number sign) 表示單行註解
"""多行註解可用3個單引號或雙引號"""
空白 (space) space (\u0020)
tabulation (\u0009)
vertical tabulation (\u000B)
form feed (\u000C)
no-break space (\u00A0)
byte order mark (\uFEFF)
space (\u0020)
tabulation (\u0009)
form feed (\u000C)
行結束字元 (line terminator) line feed (\u000A),即LF
carriage return (\u000D),即CR
line separator (\u2028)
paragraph separator (\u2029)
基本上是line feed (\u000A)
Windows平台則是CRLF
Unix平台則是LF
多行程式碼 程式碼直接分行,最後必須用分號 (semicolon ;) 結束 每行結尾必須用反斜線 (backslash \) 表示分行
關鍵字 (keyword)
保留字 (reserved words)
基本上共29個
break case catch
continue debugger default
delete do else
false finally for
function if in
instanceof new null
return switch this
throw true try
typeof var void
while with

ECMAScript 5增加下列幾個
class const enum export 
extends import super
共31個
and as assert  
break class continue
def del elif
else except exec
finally for from
global if import
in is lambda
not or pass
print raise return
try while with
yield
字面值 (literal) 數字(整數、浮點數)
字串
布林
正規表示式
物件
陣列
字串
數字(整數、浮點數、複數)


###

2013年11月23日 星期六

Knockout JavaScript Library

Knockout 是一個 JavaScript 的程式庫,簡稱 KO ,Knockout 是基於 MVVM (Model-View-View Model) 的設計模式,主要是提供資料繫結 (data-binding) 的功能,讓 UI 與資料模型之間能夠自動地動態更新。

MVVM 設計模式將 Web Application 分成下列三個部分:
  • Model
    模型是指 Web App處理的資料本身,與 UI 沒有任何關係,通常是伺服端資料庫儲存的資料,瀏覽器透過 Ajax 方式取得。
  • View Model
    檢視模型是指 UI 上資料 (data) 與操作 (operations) 的部分,在 Web App 中是一個 JavaScript 物件,物件的屬性對應至 UI 上的資料,而物件的方法則是操作的部分。
  • View
    檢視是檢視模型中可見的 (visible)、互動的部分,在 Web App 中是 HTML 文件,檢視顯示 View Model 的資訊,將命令傳送給 View Model ,並依據 View Model 的狀態更新顯示內容。
使用 KO 開發  Web App 時,我們通常會在前端(用戶端)撰寫 JavaScript 程式,做為 View Model,並設計  HTML 做為 View 的顯示,在 HTML 中使用 data-bind 屬性繫結 View Model。另一方面,後端(伺服端)則是以 Python 或 PHP 等提供資料庫存取的功能,接收或傳送Model 的 JSON 資料。

Knockout 中最重要的是物件「observable」,當 View Model 物件的屬性是 observable 物件時,KO 將自動提供雙向的資料繫結,在 KO 中有 3 種 observable:
  • ko.observable
  • ko.computed
  • ko.observableArray
一般最常使用的是 ko.observable,提供最基本的資料繫結,適合單一個物件的繫結,而 ko.observableArray 則是多個物件的繫結,KO 用的是陣列方式處理物件集合。最後 ko.computed 則提供將 observable 物件計算出新的 observable 物件,例如姓氏是 ko.observable,而名子是另一個  ko.observable,我們則可以利用 ko.computed 計算出姓名。

有了 MVVM 和 observable 的概念,已經可以著手開發以 KO 為基礎的 Web App 了,剩下只是認識 KO 提供的語彙,所幸內容不多很容易快速上手。如果你常常開發 CRUD 類型的 Web App,可以考慮採用 Knockout 程式庫。

###

2013年11月21日 星期四

JavaScript: The Definitive Guide

溫故知新:複習已經學過的知識,也能有新的認識和體會,這是我閱讀「JavaScript 大全」這本書的心得。不論你是 JavaScript 的初學者,或是已經熟悉 JavaScript 的使用者,這本書都能讓你學習並精通 JavaScript 。

David Flanagan著,黃銘偉譯,JavaScript大全,台北:碁峯資訊,2012。(共1080頁,定價  NT$1200 )
譯自:JavaScript: The Definitive Guide, O'Reilly Media, 1100 pages

「JavaScript 大全」總共分成四個部分,實際上內容只有兩個主幹,分別是核心 JavaScript客戶端 JavaScript。前兩部分說明核心與客戶端 JavaScript,後兩部分則是參考資料,因此這本書兼具學習手冊與參考手冊兩種用途。

核心 JavaScript (Core JavaScript) 這一部分主要講述 JavaScript 程式語言本身,包含程式語言的語彙結構、型別、運算式、運算子、陳述式、物件、陣列、函式等,一切有關程式語言的基本要素。

客戶端 JavaScript (Client-Side JavaScript)這部分則是介紹運行 JavaScript 的環境,包含瀏覽器和 HTML5 所提供的 API,其中一章介紹 jQuery 程式庫,讓開發 Web App更加方便,大致上已經涵蓋客戶端所需的相關知識。

我認為這本「JavaScript 大全」是 JavaScript 的聖經本,厚度與價格都是第一名,建議每位  Web 開發人員都必須擁有一本。
###

2013年11月4日 星期一

Development Environment 開發環境

在 Ubuntu 上面開發 Python 應用程式時,需要準備開發環境 (Development Environment),包含編輯器與 Python 相關套件,過去我常常手動逐一安裝,雖然一一安裝並不麻煩,但卻需要花費時間等待,於是寫了一個 Python Script 讓開發環境完全自動化安裝如下。

這個 Script 會安裝 JRE 用於執行 Eclipse IDE,並且安裝 Web Tools Platform 和 PyDev Eclipse Plugin,還有安裝 bpython 便於操作 Python Interpreter,以及 Python 套件管理程式 (pip)。其他 Git 版本管理工具和 Vim 編輯器也一併安裝。

執行 Eclipse 的參數可以參考 Provisioning platform (p2) 或 Running Eclipse

#!/usr/bin/env python
import subprocess
import sys

# JRE
subprocess.call(['wget',
                 '--no-cookies',
                 '--no-check-certificate',
                 '--header', 'Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F',
                 'http://download.oracle.com/otn-pub/java/jdk/7u45-b18/jre-7u45-linux-x64.tar.gz'])
subprocess.call(['mkdir', '/usr/java'])
subprocess.call(['tar', 'xzvf', 'jre-7u45-linux-x64.tar.gz', '-C', '/usr/java', '--no-same-owner'])
subprocess.call(['update-alternatives', '--install', '/usr/bin/java', 'java', '/usr/java/jre1.7.0_45/bin/java', '1'])
subprocess.call(['java', '-version'])

# Eclipse
subprocess.call(['wget', 'http://eclipse.stu.edu.tw/technology/epp/downloads/release/kepler/SR1/eclipse-standard-kepler-SR1-linux-gtk-x86_64.tar.gz'])
subprocess.call(['tar', 'xzvf', 'eclipse-standard-kepler-SR1-linux-gtk-x86_64.tar.gz', '-C', '/opt', '--no-same-owner'])
subprocess.call(['chgrp', '-R', 'sudo', '/opt/eclipse/'])
subprocess.call(['/opt/eclipse/eclipse',
                 '-application', 'org.eclipse.equinox.p2.director',
                 '-repository', 'http://download.eclipse.org/releases/kepler',
                 '-destination', '/opt/eclipse',
                 '-installIU', 'org.eclipse.wst.web_ui.feature.feature.group'])
subprocess.call(['/opt/eclipse/eclipse',
                 '-application', 'org.eclipse.equinox.p2.director',
                 '-repository', 'http://pydev.org/updates',
                 '-destination', '/opt/eclipse',
                 '-installIU', 'org.python.pydev.feature.feature.group'])
subprocess.call(['chmod', '-R', '775', '/opt/eclipse'])

# APT package
subprocess.call(['apt-get', 'update'])
subprocess.call(['apt-get', '-y', 'install', 'vim'])
subprocess.call(['apt-get', '-y', 'install', 'bpython'])
subprocess.call(['apt-get', '-y', 'install', 'git'])
subprocess.call(['apt-get', '-y', 'install', 'python-pip'])

# Desktop Menu
f=open('/usr/share/applications/eclipse.desktop','w')
f.write('''[Desktop Entry]
Type=Application
Name=Eclipse
Exec=/opt/eclipse/eclipse
Icon=/opt/eclipse/icon.xpm
Terminal=false
''')
f.close()

# exit
sys.exit()

歡迎大家參考利用。
###

2013年11月1日 星期五

Multiple Instances of Apache2 多網頁伺服器實體

這篇文章記錄如何將 Apache 設定成多個實體執行。所謂的實體 (instance) 指的是一個完整的執行環境,由多個程序 (process) 或執行緒 (thread),與一個設定組態 (configuration) 所組成。一個主機 (host) 上可以同時擁有多個執行實體,但為何需要多個 Apache 實體呢?

如果需要在一台主機上提供多個網站,使用虛擬主機 (virtual host) 的方式就可以達成,其實不需要多個 Apache 實體。不過採用虛擬主機的前提是:這些虛擬主機都是用相同的模組  (module) 的情況,例如所有的虛擬主機都是執行 PHP 而使用 php5_module 模組,或是為了執行 Python 而使用 mod_wsgi 模組。

當然,你也可以一起載入所有的模組,只是這樣不太好,明明我的虛擬主機只要執行 PHP,卻要載入其他 mod_wsgi 、 mod_perl 之類的模組,造成記憶體的浪費,對於電腦資源的利用不是很有效率。因此,面對這種「多語言」的使用情境,我們就有可能需要多個 Apache 實體。

在 Ubuntu 上建立多個 Apache 實體其實不難,先利用 apt-get install apache2 安裝完 Apache 之後,我們可以在範例中找到建立多個 Apache 實體的 script 程式碼,這個 script 基本上就是建立一組全新的設定組態和 daemon 啟動程式。使用語法如下:

usage: /usr/share/doc/apache2/examples/setup-instance <suffix>

例如:bash /usr/share/doc/apache2/examples/setup-instance mysite,就會建立一個新的mysite實體,原本常用的 apache2ctl 指令會變成 apache2ctl-mysite,其他設定檔也會多了「 -mysite」的字尾。

如果你要啟動新的 Apache 實體,記得去利用 Listen 指令修改伺服器的埠號,不然會與原本的 Apache 發生衝突。以上面例子來說,修改 /etc/apache2-mysite/ports.conf 設定檔,然後執行 sudo service apache2-mysite start 就能啟動新的 Apache 實體。

參考文件:
###

2013年9月25日 星期三

Ubuntu 上安裝與部署 Django

在很久以前曾經說明 Django 在 Windows 的安裝步驟,這篇文章將說明如何在 Ubuntu 上安裝 Django ,並且使用 mod_wsgi 部署在 Apache 伺服器上運行。

廢話不多說,直接提供 Shell Script 安裝部署,可以將下列程式碼儲存為檔案,利用 Bash 執行後將建立一個mysite的網站,你也可以修改 NAME 變數使用不同的網站名稱。

#! /bin/bash

#安裝 Apache HTTP Server, WSGI模組, Python套件安裝器
apt-get -y install apache2
apt-get -y install libapache2-mod-wsgi
apt-get -y install python-pip

#安裝Django web framework
pip install django

#網站名稱變數
NAME=mysite

cd /var/www

#新增一個名稱為NAME的Django專案
django-admin.py startproject $NAME

#新增虛擬主機的組態檔,最精簡的設定
(
cat <<EOF
<virtualhost *:80>
        WSGIScriptAlias / /var/www/$NAME/$NAME/wsgi.py
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</virtualhost>
EOF
) > /etc/apache2/sites-available/$NAME

#設定PYTHONPATH,Python執行時尋找程式庫的位置
(
cat <<EOF
import sys
PROJECT_PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(PROJECT_PATH)
EOF
) >> /var/www/$NAME/$NAME/wsgi.py

#啟用Django專案的虛擬主機,關閉預設的虛擬主機
a2ensite $NAME
a2dissite default

#使Apache伺服器重新載入設定檔
service apache2 reload

正確執行後,打開瀏覽器,輸入主機IP或本機位置 (http://127.0.0.1),將可以看到 Django 的歡迎畫面:



其他參考資料

###

2013年9月23日 星期一

NetworkManager 網路管理員

Ubuntu Desktop 的網路設定是由 NetworkManager 管理,NetworkManager 簡稱 NM,目前最新的版本是 0.9.8.x, NM 提供圖形化介面讓使用者設定網路連線,使用者不用去修改 /etc/network/interfaces 這個設定檔,這裡將介紹 NetworkManager 的相關資料與PPPoE的設定方式。

相關資料

設定資訊

  • NetworkManager 的組態檔資料夾位置
    /etc/NetworkManager
  • NetworkManager 的系統組態檔
    /etc/NetworkManager/NetworkManager.conf
  • 系統組態檔的設定意義
    參考:https://wiki.gnome.org/NetworkManager/SystemSettings
    或是:man NetworkManager.conf

預設系統組態檔內容:
[main]
plugins=ifupdown,keyfile
dns=dnsmasq

[ifupdown]
managed=false

意思是使用 ifupdown 和 keyfile 兩個外掛,dns使用dnsmasq這個DNS快取。
ifupdown 從 /etc/network/interfaces 讀取連線,managed=false 是指 /etc/network/interfaces 中的連線不受管理,會被 NetworkManager 忽略。

其他指令

  • 重新啟動 NetworkManager:
    sudo service network-manager restart
  • NetworkManager 完整的使用說明:
    man NetworkManager
  • 命令列工具:
    nmcli
  • 列出連線狀態與裝置資訊(實用!)
    nm-tool

PPPoE

有關PPPoE的設定不建議使用 NetworkManager ,因為經過測試發現,開機後不會自動連線,需要手動點選連線實在不方便,我建議使用pppoeconf這項工具程式,在terminal中輸入pppoeconf會出現對話視窗,輸入使用者帳號和密碼,完成設定後輸入pon dsl-provider手動連線。重新開機後,一樣會自動建立PPPoE連線。

參考資料:https://help.ubuntu.com/community/ADSLPPPoE

###

2013年9月22日 星期日

HTML4 第二講

結構 (structure) 元素是 HTML 最重要的一個部份,數量也是最多的一類,結構元素將網頁內容組織成有系統的結構,用來標示那些內容是文字、清單或表格等等。結構元素包括5大項目:文字、清單、表格、連結與物件,如下表總共有 46 個元素。

分類文字(text)清單 (list)表格 (table)連結 (link)物件 (object)
數量1981036
元素名稱
em
strong
dfn
code
samp
kbd
var
cite
abbr
acronym
blockquote
q
sub
sup
p
br
pre
ins
del

ul
ol
li
dl
dt
dd
dir
menu

table
caption
thead
tbody
tfoot
colgroup
col
tr
th
td

a
link
base

img
object
param
applet
map
area

接著我將概略介紹各類結構元素,詳細內容請參閱 HTML 的規範。

文字類

最常使用的大就是 p 元素,代表的是段落 (paragraph) ,一個段落代表的是作者的思想或論點,與文字如何呈現沒有任何關係,可以是左右對齊 (double-justified) 或是靠左對齊 (left-justified) ,結構上都是相同的。

如果要強制在段落中的文字分行 (line break) ,則是使用 br 元素。不然瀏覽器會在英文段落中空白或連字符號 (hyphen) 的地方自動分行,中文段落則是每個字的地方都能自動分行。如果不想要在空白的地方分行,則可以使用&nbsp;實體,如果要指定文字在何處分行,則在英文字中插入&shy;實體。

另外,HTML 文件中的 Carriage Return (\r) 和 Line Feed (\n) 控制字元都會變成空白字元,如果想讓這些控制字元原汁原味呈現,那麼就要使用 pre 元素,pre 是指預先編排 (preformatted)的

意思。

對於內容的變動,使用 ins 元素標示新增的內容,使用 del 元素標示刪除的內容。對於引用的內容,HTML 提供兩個元素標示引用資料, blockquote 元素用於區塊元素,q 元素則用於行內元素。

文字上若需要下標 (subscript) 與上標 (superscript) 的文字標示,使用 sub 元素標示下標符號,上標符號則使用 sup 元素。

最後介紹文字類中的詞組元素 (phrase elements),這些都是用來組織文字片段的結構,總共有10個。
  • em:強調
  • strong:比em更強調
  • dfn:定義
  • code:程式碼片段
  • samp:程式碼的輸出結果
  • kbd:使用者的輸入
  • var:變數或引數
  • cite:引用或參考
  • abbr:縮寫詞
  • acronym:首字母縮略字

清單類

HTML 提供三種清單結構,分別是無次序 (unordered)、有次序 (ordered) 與定義 (definition) 。無次序清單使用 ul 元素,而有次序清單使用 ol 元素,不論有無次序,這兩種元素都要包含一個以上的清單項目,也就是 li 元素。

定義的清單結構是使用 dl 元素,dl 元素中不是包含 li 元素,而是使用名稱 (term) 與描述 (description) 的組合當作清單項目,名稱和描述個別使用的是 dt 元素和 dd 元素。

在清單類中還有兩個 dir 元素和 menu 元素,dir 使用來做路徑清單,而 menu 則用來做選單清單,這兩個元素 HTML 規格已經標示為棄用 (deprecated),建議改用 ul 元素取代。

表格類

表格類元素的使用大概是僅次於文字類,表格除了可以呈現資料外,也可以用來做排版設計。一個表格由 table 元素組成, table 元素內有 cpation 元素顯示表格標題,表格的每列 (row) 是由 tr 元素組成,表格中最小的單位則是單元格 (cell),單元格使用的是 td 或 th 元素。

一個表格中包含多列,我們可以群組這些列, HTML 中有三種元素可以使用,thead 元素是表頭 (table header),tbody 是表體 (table body) ,thead是表尾 (table footer)。這些群組元素的用途在於,如果有一個很多列的表格,表體的內容會橫跨多個頁面,但表頭和表尾則會固定在頁面上顯示欄 (column) 資訊。

除了表格列群組,欄也可以群組,使用 colgroup 和 col 元素,這些用途是在設定欄的寬度和樣式,平常很少使用。

連結類

一個連結包含兩個部分,錨點 (anchor)和方向 (direction),連結的方向是從來源錨點 (source anchor) 指向目標錨點 (destination anchor)。

在文件標頭設定連結是使用 link 元素,不會顯示給使用者,而在文件主體中使用連結則是用 a 元素。 link 元素通常是設定外部樣式表,或是設定個網頁之間的關係。 一般在頁面上看到的超連結都是指 a 元素,將頁面上的資訊連結至目標錨點。

另外還有一個 base 元素, base 元素是用來設定路徑資訊,當使用相對路徑時,利用 base 元素指定參考的基礎路徑位置,這個元素必須放在文件標頭裡面。

物件類

物件類的元素是用來組織多媒體資訊,如圖像、媒體播放器、Java Applet等,最常使用的是 img 元素,img 元素用來插入圖像到 HTML 文件之中。此外,插入圖像也可以使用 object 元素,object 元素是通用類型的物件,通常是用來嵌入媒體播放器,物件執行時期的參數設定使用 param 元素。目前,applet 標示為棄用 (deprecated),建議 Java Applet 使用 object 元素。

在使用圖像的時候, HTML 提供影像地圖的功能,利用 map 和 area 元素設定圖像上特定區域的動作,通常是用來設定圖像上的超連結。

###

2013年8月26日 星期一

102學年技專校院一覽

利用政府資料開放平臺取得大專校院名錄,再利用程式處理就可以得到技專校院的清單,102學年技專校院的名稱與網址如下:

科技大學 (共55所)

  1. 國立臺灣科技大學:www.ntust.edu.tw
  2. 國立雲林科技大學:www.yuntech.edu.tw
  3. 國立屏東科技大學:www.npust.edu.tw
  4. 國立臺北科技大學:www.ntut.edu.tw
  5. 國立高雄第一科技大學:www.nkfust.edu.tw
  6. 國立高雄應用科技大學:www.kuas.edu.tw
  7. 國立虎尾科技大學:www.nfu.edu.tw
  8. 國立高雄海洋科技大學:www.nkmu.edu.tw
  9. 國立澎湖科技大學:www.npu.edu.tw
  10. 國立勤益科技大學:www.ncut.edu.tw
  11. 國立臺北護理健康大學:www.ntunhs.edu.tw
  12. 國立高雄餐旅大學:www.nkuht.edu.tw
  13. 國立臺中科技大學:www.nutc.edu.tw
  14. 朝陽科技大學:www.cyut.edu.tw
  15. 南臺科技大學:www.stust.edu.tw
  16. 崑山科技大學:www.ksu.edu.tw
  17. 嘉南藥理科技大學:www.chna.edu.tw
  18. 樹德科技大學:www.stu.edu.tw
  19. 龍華科技大學:www.lhu.edu.tw
  20. 輔英科技大學:www.fy.edu.tw
  21. 明新科技大學:www.must.edu.tw
  22. 弘光科技大學:www.hk.edu.tw
  23. 健行科技大學:www.uch.edu.tw
  24. 正修科技大學:www.csu.edu.tw
  25. 萬能科技大學:www.vnu.edu.tw
  26. 建國科技大學:www.ctu.edu.tw
  27. 明志科技大學:www.mcut.edu.tw
  28. 高苑科技大學:www.kyu.edu.tw
  29. 大仁科技大學:www.tajen.edu.tw
  30. 聖約翰科技大學:www.sju.edu.tw
  31. 嶺東科技大學:www.ltu.edu.tw
  32. 中國科技大學:www.cute.edu.tw
  33. 中臺科技大學:www.ctust.edu.tw
  34. 台南應用科技大學:www.tut.edu.tw
  35. 遠東科技大學:www.feu.edu.tw
  36. 元培科技大學:www.ypu.edu.tw
  37. 景文科技大學:www.just.edu.tw
  38. 中華醫事科技大學:www.hwai.edu.tw
  39. 東南科技大學:www.tnu.edu.tw
  40. 德明財經科技大學:www.takming.edu.tw
  41. 南開科技大學:www.nkut.edu.tw
  42. 中華科技大學:www.cust.edu.tw
  43. 僑光科技大學:www.ocu.edu.tw
  44. 育達科技大學:www.ydu.edu.tw
  45. 美和科技大學:www.meiho.edu.tw
  46. 吳鳳科技大學:www.wfu.edu.tw
  47. 環球科技大學:www.twu.edu.tw
  48. 中州科技大學:www.ccut.edu.tw
  49. 修平科技大學:www.hust.edu.tw
  50. 長庚科技大學:new.cgust.edu.tw
  51. 台北城市科技大學:www.tpcu.edu.tw
  52. 大華科技大學:www.tust.edu.tw
  53. 醒吾科技大學:www.hwu.edu.tw
  54. 南榮科技大學:www.njtc.edu.tw
  55. 文藻外語大學:www.wtuc.edu.tw

技術學院 (共22所)

  1. 國立屏東商業技術學院:www.npic.edu.tw
  2. 國立臺北商業技術學院:www.ntcb.edu.tw
  3. 國立臺灣戲曲學院:www.tcpa.edu.tw
  4. 大漢技術學院:www.dahan.edu.tw
  5. 慈濟技術學院:www.tccn.edu.tw
  6. 永達技術學院:www.ytit.edu.tw
  7. 和春技術學院:www.fotech.edu.tw
  8. 致理技術學院:www.chihlee.edu.tw
  9. 亞東技術學院:www.oit.edu.tw
  10. 桃園創新技術學院:www.nanya.edu.tw
  11. 德霖技術學院:www.dlit.edu.tw
  12. 蘭陽技術學院:www.fit.edu.tw
  13. 黎明技術學院:www.lit.edu.tw
  14. 東方設計學院:www.tf.edu.tw
  15. 經國管理暨健康學院:www.cku.edu.tw
  16. 崇右技術學院:www.cit.edu.tw
  17. 大同技術學院:www.ttc.edu.tw
  18. 亞太創意技術學院:w2.apic.edu.tw
  19. 高鳳數位內容學院:www.kfcdc.edu.tw
  20. 華夏技術學院:www.hwh.edu.tw
  21. 臺灣觀光學院:www.tht.edu.tw
  22. 台北海洋技術學院:www.tcmt.edu.tw

專科學校 (共14所)

  1. 國立臺南護理專科學校:www.ntin.edu.tw
  2. 國立臺東專科學校:www.ntc.edu.tw
  3. 康寧醫護暨管理專科學校:www.knjc.edu.tw
  4. 馬偕醫護管理專科學校:www.mkc.edu.tw
  5. 仁德醫護管理專科學校:www.jente.edu.tw
  6. 樹人醫護管理專科學校:www.szmc.edu.tw
  7. 慈惠醫護管理專科學校:www.tzuhui.edu.tw
  8. 耕莘健康管理專科學校:www.ctcn.edu.tw
  9. 敏惠醫護管理專科學校:www.mhchcm.edu.tw
  10. 高美醫護管理專科學校:www.kmvs.khc.edu.tw
  11. 育英醫護管理專科學校:www.yuhing.edu.tw
  12. 崇仁醫護管理專科學校:www.cjc.edu.tw
  13. 聖母醫護管理專科學校:www.smc.edu.tw
  14. 新生醫護管理專科學校:www.web.hsc.edu.tw

Python 的程式碼如下:

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# 技專校院清單
# list of technological and vocational college
import urllib2
import urlparse

def export_html(category, schools):
    print '<div>'
    print '<h3>%s</h3>' % category
    print '<ol>'
    for school in schools:
        print '<li>%s:<a href="http://%s" target="_blank">%s<a></li>' % \
         (school['name'], school['netloc'], school['netloc'])
    print '</ol>'
    print '</div>'

if __name__ == '__main__':
    req = urllib2.Request('https://stats.moe.gov.tw/files/school/102/u1_new.txt')
    
    f = urllib2.urlopen(req)
    data = f.read().decode('utf-16')
    f.close()
    rows = data.split('\r\n')[3:]
    
    university = []
    institute = []
    college = []
    
    for row in rows:
        cols = row.split('\t')        
        if len(cols) == 7 and cols[6] == '[2]技職':
            name = cols[1]
            o = urlparse.urlparse(cols[5])            
            school = {'name': name, 'netloc': o.netloc}
            
            if name[-2:] == '大學':
                university.append(school)
            elif name[-2:] == '學院':
                institute.append(school)
            elif name[-2:] == '學校':
                college.append(school)
    
    export_html('科技大學', university)
    export_html('技術學院', institute)
    export_html('專科學校', college)


###

2013年8月21日 星期三

Raspberry Pi 樹莓派

Raspberry Pi (樹莓派)是一台價格便宜的電腦 (35美元),而且體積小 (一張信用卡大),你可以用它做很多事情,例如編輯文書或程式、機上盒、家電控制等等。不過開始之前,這台 Raspberry Pi 和一般 PC 不太一樣,它是使用 Linux 的作業系統,而且系統是運行在 SD 記憶卡上,相信對於一般使用者而言有些陌生,這裡推薦一本書給大家。

Maik Schmidt (梅克‧施密特)著,周均健、謝瑩霖譯,Raspberry Pi 快速上手指南,台北:馥林文化,2013。

這本「Raspberry Pi 快速上手指南」寫的詳細而清楚,附錄還包含 Linux 入門的使用方法,雖然薄薄一本,然而內容涵蓋基礎知識和操作步驟說明,個人非常這本書推薦給初學者學習參考,若是你已經瞭解 Linux 的操與安裝,則直接參閱官方網站或 Google 搜尋的方式學習吧。

Raspberry Pi, Model-B 的樣子與包裝外盒,從天瓏書店購得。

###

2013年8月20日 星期二

HTML4 第一講

最新的 HTML 規範是第5版,稱為 HTML5 。在此,我想先介紹 HTML 第4版,而不是 HTML5 ,原因在於 HTML4 已經廣泛使用、規格已確定,而且學習 HTML4 之後瞭解 HTML5 也不難,所以我認為比較適合初學者優先學習。

認識 HTML

網頁是一個 HTML 文件,由 HTML 語言所撰寫而成的檔案,HTML全名為 HyperText Markup Language ,稱為超文字標記語言,是屬於一種標準通用標記語言 (Standard Generalized Markup Language, SGML) ,所謂標記語言指的是用標示 (mark up) 表示內容的結構、顯示和語意的資訊。

HTML 標記語言主要有兩個概念:元素 (element)屬性 (attribute),這些都定義在文件宣告定義 (Document Type Definition, DTD)裡面,每個元素具有多個屬性,元素由起始標籤、內容、結束標籤3個部分組成。元素名稱和屬性名稱都是不區分大小寫 (case-insensitive)

不過注意到,HTML 元素和標籤是不一樣的概念,元素不一定需要起始標籤結束標籤,例如 body, head, html, tbody這四個就允許完全不需要起始和結束標籤,但這些元素依舊存在於 HTML 文件中,有些元素則允許忽略結束標籤。另外,有一部分元素是不需要結束標籤,而且內容要為空。

HTML 文件是由 HTML 元素所組成,HTML4 總共有91個元素,我們可以依據不同用途分成四大類:基礎元素、結構元素、外觀元素與互動元素。這裡我們會先介紹 HTML 文件和基礎元素。

一個 HTML 文件可以分成三部分:版本資訊、文件標頭 (document head) 與文件主體 (document body) 。版本資訊是 HTML 文件的第一列,目前有三種文件類型宣告 (document type declaration) 指定版本資訊,分別是:

嚴謹的 (strict) 宣告
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

過渡的 (transitional) 宣告
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

框架組的 (frameset) 宣告
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">

這三個版本資訊的差異在於 HTML 元素支援的數量不同,參閱下表所述:
stricttransitionalframeset
支援元素數量778891

接著版本資訊是 html 元素,代表 HTML 文件, html 元素內包括 head 與 body 兩個區塊。head 區塊由 head 元素組成文件標頭,是用來儲存文件的資訊,通常不會顯示給使用者看,所以只要不屬於內容的資料都應該在 head 區塊中。而 body 區塊則由 body 元素組成文件主體,這部分是文件的內容本身,寫網頁絕大多數都是在編輯 body 區塊,使用者看的網頁也就是 body 元素的內容。

一個 HTML 文件會像下面這樣的結構:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <!-- head 區塊:文件標頭 -->
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>這是標題</title>
  </head>

  <body>
    <!-- body 區塊:文件主體 -->
  </body>
</html>

注意,DTD中定義 html 元素中必須包含一個 head 元素與 body 元素,如果你在 HTML 文件中差入多個 head 標籤內容,還是只會有一個 head 元素, body 元素也是相同的行為,這其實說明 HTML 元素和標籤是不一樣的概念。

HTML 基礎元素如下表所示,加上 html 元素自己總共有 14 個基礎元素。
文件標頭文件主體
組成的元素headbody
所屬的元素title
meta
群集:div, span
標題:h1, h2, h3, h4, h5, h6
address

這裡還必須介紹一個觀念,文件主體內的元素可以分成兩大類,區塊 (block-level) 元素行內  (inline ,或稱 text-level) 元素。區塊元素中可以包含行內元素和其他區塊元素,而行內元素只能包含行內元素或資料,兩類的內容模型 (content model) 不太一樣。區塊元素通常從新的一列開始放置,而行內元素則會在同一列中延續放置,所以才稱為「行內」。這兩類元素對於語言方向性的行為也有所不同,這部分將另外說明。

###

2013年8月16日 星期五

網站、網頁、網頁應用程式

網站、網頁、網頁應用程式

這裡將對一些術語進行解釋說明,因為網站 (website) 網頁 (web page) 很多人常常搞不清楚。

網頁

先說明什麼是網頁 (web page),一個網頁是你開啟網頁瀏覽器 (web browser) 所看到的那個畫面,而這個畫面實際上是一個 HTML 文件的檔案,就好像一本書裡的一「頁」內容,因此才稱為網頁。目前以技術上來說,網頁不一定是一個 HTML 文件,也有可能是一個程式,利用程式產生 HTML 文件,這種方式稱為網頁應用程式 (web application, Web App)

以內容來看,網頁分為動態網頁靜態網頁兩大類。動態網頁不是因為網頁有會動的內容,而是網頁依據用戶輸入而產生不同的內容,內容是「動態」的才稱為動態網頁,大多數網頁應用程式都是動態網頁。另一方面,靜態網頁則指的是 HTML 文件的檔案,任何用戶讀取都是固定不變的內容,所以這是「靜態」的。

網站

那網站 (website) 又是什麼?一個網站是由一個以上的網頁所構成,有一個明確的網址位置,讓我們能夠經由網路存取。在瀏覽器中輸入網址,我們將在畫面上看到一個網頁,對一個網站而言,通常會有一個主要的頁面作為入口,稱之為首頁 (home page) 。從電腦的角度來看,網頁就像是一個檔案,網站則像是一個資料夾,這樣思考是不是比較清楚了。

再更進一步說明,網站是一個虛擬概念,真正的網站是存在於一台電腦上,這種電腦稱為伺服器 (server) ,用作網站的主機 (host) 。實際的應用中,伺服器是一個很強大的電腦,通常會存放多個網站,這樣的主機稱為虛擬主機 (virtual host)

另外,也常聽到網路應用程式 (network application) 這個名詞,網路應用程式是指利用網路完成工作的應用程式,廣泛來說,只要有使用網路資源的程式都可稱為網路應用程式。換句話說,網頁應用程式也是一種網路應用程式。

我們用一些類似的東西比喻網站、網頁、網頁應用程式這些概念,如下表所述:
書頁網頁檔案
書本網站資料夾
書店(建築物)主機(伺服器)磁碟機(電腦)
地址網址路徑

###

學習網頁的心得分享

學習網頁的心得分享

學習網頁應該如何開始?

我認為有兩方面需要學習,一個是網頁本身的技術,另一方面是寫網頁的工具軟體。

寫網頁的工具軟體

我自己一開始是用微軟的 FrontPage 2003 編輯網頁, FrontPage 的優點在於操作簡單,如果你會使用 Word 編輯文件,那麼使用 FrontPage 不會太困難,兩者擁有類似的操作介面和使用觀念,即使沒有任何網頁技術基礎也可以做出一個網站,加上 FrontPage 提供所見及所得 (What You See Is What You Get, WYSIWYG) 的操作介面,基本上不會接觸任何程式碼,這對於新手而言是另一個優點。

不過當網站越做越複雜,想要更進一步的功能,這時候 FrontPage 的優點反而變成缺點,操作簡單代表軟體幫你做了一些事情,你只看到結果而不知道其中的原理,只用 WYSIWYG 的方式製作網頁讓你無法精確控制背後的程式碼,因而發覺真正需要瞭解網頁技術,於是開始認識網頁的程式碼。

第二個使用的軟體是 Macromedia Dreamweaver MX, Dreamweaver 在當時(2002年)是最熱門的網頁編輯軟體,本身除了是 WYSIWYG 的網頁編輯器,也提供很多強大的程式碼編輯功能,而且可以控制的選項比 FrontPage 更多,因此可以藉著修改選項去學習程式碼,經由這套軟體讓我學習到更進一步的網頁技術。

現在,寫網頁都不用這些 WYSIWYG 的軟體,而是用 Eclipse 整合開發環境和網頁瀏覽器(web browser)。在  Eclipse 中編寫程式碼,接著用網頁瀏覽器(例如Chrome)查看執行結果,這樣的組合優點是精確控制網頁程式碼、在瀏覽器中完整呈現網頁結果,加上不用付任何費用就能取得軟體,而且 Eclipse 提供很多外掛可以擴充功能,不僅限於網頁開發使用,有助於降低爾後的學習門檻。我認為這樣的工具組合非常適合推薦給新手,因為這是自由又免費的工具軟體。

網頁本身的技術

綜括來說,網頁包含三種技術: HTML 、 CSS 與 JavaScript ,我稱之為「網頁三元素」,其中又以 HTML 為網頁最重要的基礎。 HTML 處理的是網頁結構, CSS 處理的是網頁的外觀樣式,而 JavaScript 則處理網頁的互動行為。學習的順序當然是以基礎為先,先學習 HTML ,接著是 CSS 或 JavaScript 。

如果你是設計人員,建議從 CSS 著手學習,因為 CSS 是控制網頁的版面和外觀,修改 CSS 可以在網頁畫面上看到結果,學起來會比較有感覺。

如果你是程式開發人員,則建議從 JavaScript 著手,因為 JavaScript 程式語言對任何一種程式開發人員都會是熟悉的,不像 CSS 是另一種概念。

不管是哪種學習路徑,最後三者都是必須完全學習接觸,這樣對於網頁才會有完整的認識。

網頁最重要的是「內容/服務」

說了這麼多,技術與工具都不是重點,網頁最重要的是「內容/服務」,所有的努力都是為了將內容和服務透過網路傳播,你可以利用很複雜的 HTML 、絢麗的 CSS 樣式、強大的 JavaScript 程式碼做出一個網站,但如果沒有豐富且實用的內容和服務,這一切都是沒有意義的。

我們將網頁技術比喻成身體,如下表所述, HTML 像骨骼架構起身體, CSS 如皮膚覆蓋身體, JavaScript 像神經控制身體,內容和服務則如同血肉構築整個身體。如果沒有血肉,人不就像是一個空殼,因此內容是網頁的主體。

HTMLCSSJavaScript內容/服務
骨骼皮膚神經血肉

###

2013年8月1日 星期四

Rework 工作大解放

這本書,「工作大解放 (Rework) 」應該列為禁書,強烈禁止所有軟體開發人員閱讀,足以顛覆所有工作常理,非常危險!在於多數公司文化根本不像書中所述那樣,看完後你真的想仿照書說的那樣做,心中充滿行動的熱情。作者10多年的業界經驗證實,他們就是如此執行,因而創造出一個不符合「常理」的軟體公司。

Teddy Chen在最近「還少一本書」也提到這本工作大解放,他說這本書充滿了 Agile 與 Lean 的精神,確實如此,特別適合新創公司和敏捷開發團隊閱讀,非常推薦。+1


福萊德 (Jason Fried ), 漢森 (David Heinemeier Hansson) 著,胡瑋珊譯,工作大解放:這樣做事反而更成功,台北:天下遠見,2010。
譯自:Rework

全書總共分成11章,總共88篇短文,文章不長很好閱讀,很適合利用休息時間閱讀一篇。以下幾篇是我認為非讀不可的文章,推薦給大家:
  • 從成功中學習
    當某件事成功了,你就會知道你做對了什麼,你以後可以再做一次,而下次可能做得更好。
  • 計畫是一種猜測
    沒有計畫地做事聽起來可能很可怕,但盲目的遵循與現實脫節的計畫更恐怖。
  • 騷到自己的癢處
    當你打造自己需要的事物時,便可直接且迅速地評估產品的品質,無須透過中間人。
  • 明確表明立場
    當你不清楚自己的信念,任何事物會產生爭議,每件事都是可以辯論的。
  • 從核心要點做起
    將注意力集中在讓它變得更美好,然後你所做的一切都要取決於這個基礎。
  • 忽略初期的細枝末節
    在你著手進行之前,你往往無法辨識哪些細節最重要。在你動手開始做時,你才會明白哪些地方要多加注意。
  • 有時放棄是對的
    不要把美好的時間浪費在不好的工作上。
適合放在工作桌上的一本書,提醒自己。

###

2013年7月29日 星期一

National Taipei University of Technology 台北科技大學

今年(2013年)捐贈書籍的時間又到了。延續去年 Web 浪潮,今年對於 Web 與行動網頁開發的書籍非常多, HTML5 和 CSS3 方面的基礎書籍已經逐漸飽和(氾濫),出版社開始引進較進階的內容(吸引讀者),像是效能最佳化、大規模建置等議題。

另一方面,NoSQL 資料庫的風潮逐漸受到開發者注意,彈性而無 Schema 的方式讓生產力有所提升,目前也有些 NoSQL 資料庫的書籍翻譯發行。這種有別於關聯式資料庫 (RDBMS) 的開發使用方式還很新,值得各位開發人員學習並評估是否適用。



這次捐贈的書籍清單如下所述:
  • Kristina Chodorow, Michael Dirolf著,吳曜撰譯 ,MongoDB技術手冊,台北:歐萊禮,2012。
  • Christopher Schmitt, Kyle Simpson著,賴屹民譯 ,HTML5 錦囊妙計,台北:歐萊禮,2013。
  • Steve Souders著,楊仁和譯,高效能網站建置指南,台北:歐萊禮,2013。
  • Rachel Andrew著,羅友志譯,CSS3網頁設計師手札,台北:碁峰資訊,2013。
  • 郭欣,巨型網站大師親自指導-建立極速Web站台的祕密,台北:佳魁資訊,2013。
  •  Matt West著,林盈新譯,HTML5 新世代網頁建置-新手也可以快速設計出專業網站,台北:果禾文化,2013。
  • 郭家寶,Google 御用網頁語言 Node.js:一流程式設計師養成精華,台北:佳魁資訊,2013。
  • 高俊峰,網站平台全面換血+完美優化:Linux伺服器加速營運14大原則,台北:佳魁資訊,2013。
  • Pramod J. Sadalage、Martin Fowler著,吳曜撰譯,搞懂NoSQL的15堂課,台北,碁峰資訊,2013。
  • 張春曉等編著,王者歸來:UNIX 王者殿堂,台北:佳魁資訊,2013。
  • Ian Lunn著,陳亦苓譯,CSS3 網頁設計優化-新手也能快速建立跨平台網頁台北:果禾文化,2013。
  • 張宴,Nginx-完全取代Apache,超輕、快、強的Web伺服器,台北:佳魁資訊,2013。
###

2013年7月23日 星期二

NoSQL Distilled 搞懂 NoSQL 的15堂課

最近這一年以來,NoSQL 資料庫越來越熱門,一直缺少一本書籍好好介紹 NoSQL ,現在,「搞懂NoSQL的15堂課 (NoSQL Distilled 中文版)」是很好的基礎入門書,讓我們搞清楚什麼是 NoSQL 資料庫,作者不講各個資料庫的操作細節,而是站在一個高度下有系統的介紹 NoSQL 資料庫,讓我們清楚瞭解 NoSQL 資料庫,不管你是否正在使用 NoSQL ,這本搞懂 NoSQL 的15堂課都非常值得閱讀。

Pramod J. Sadalage、Martin Fowler 著,吳曜撰譯,搞懂 NoSQL 的15堂課,台北,碁峰資訊,2013。
譯自:NoSQL Distilled: A Brief Guide to the Emerging World of Polyglot Persistence

NoSQL 不是 Not Only SQL ,事實是來自 Twitter 的分類標籤 (hashtag) ,由 Johan Oskarsson 命名使用的。實際上, NoSQL 是對一種類型資料庫的統稱,這類資料庫有幾個特徵:聚集 (aggregate) 的資料模型、無綱要 (schemaless) 、使用叢集 (cluster) 執行等,目前世界上有的 NoSQL 清單可以參考這個網站:http://nosql-databases.org/

「搞懂 NoSQL 的15堂課」分成兩大部分共15章,第一部分介紹 NoSQL 的資料模型,主要讓我們瞭解 NoSQL 的特點,第二部分則針對實作進行說明,主要是說明鍵值資料庫 (Key-Value Databases)文件資料庫 (Document Databases)欄位群資料庫 (Column-Family Stores ) 圖形資料庫 (Graph Databases) 這四大資料模型的差異與特性。

NoSQL 由於無綱要的性質,使得程式設計師開發應用程式的生產力提高,加上叢集的實現方式, NoSQL 有利於大規模的資料量。相對的,這些看似優點的特性也產生另外一些問題,例如一致性 (consistency) 的議題,由於無綱要與叢集的性質,這讓資料必須分散在各主機上,加上聚集的資料模型,使資料庫在讀取與更新的一致性必須處理與注意。

書中最後提到不同的資料庫是設計用來解決不同的問題,我們面對 NoSQL 的同時,不應該完全放棄使用關聯式資料庫,針對不同應用場合使用特定的資料庫,或是採用多語言維持 (polyglot persistence) 的儲存方式,這些都值得我們進一步思考設計。

###

2013年7月21日 星期日

Go Programming Language

最近檢視一下Google開發的Go程式語言,這裡是一些學習筆記。
  • 發明者
    • Robert Griesemer
    • Rob Pike
    • Ken Thompson (B語言發明者)
  • 開發小組,總共有5人,除3位發明者外,還有
    • Ian Taylor
    • Russ Cox
Go程式語言的發展歷史,這部份可以參考常見問題,摘要如下:
Go程式語言的標準規範:http://golang.org/ref/spec

Go程式語言的簡介,參考『The Expressiveness of Go』投影片的內容
  • 發明原因:為了Google內部需要
    • 有效率大規模的編程
    • 加速編輯撰寫
    • 分散式系統
    • 多核心與網路硬體
  • 速度與安全,或容易使用,結合下列兩類語言的特質
    • C++, Java
    • Python, JavaScript
  • 設計4原則
    • 簡單(simple)
      • 概念是容易理解認識的
    • 正交(orthogonal)
      • 混合概念是清楚的
      • 容易理解和預測發生什麼行為
    • 簡潔(succint)
      • 不需要預先宣告任何意圖
    • 安全(safe)
      • 違反的行為應該被偵測到
  • 簡單原則可以從語言的關鍵字評比
    • Go語言:25個
    • Python 2.7:31
    • C (K&R):32
    • C++:48
    • C#:77
  • 著眼點
    • Go相信程式設計師所寫下的程式碼
    • 意思是,Go試著尊重程式設計師的意圖
    • 這將是安全(safe)而有趣(fun)
    • 用比喻來說,這是安全帶(seat belts)和輔助輪(training wheels)的差異
到這裡為止,對Go程式語言已有初步的認識,了解Go是為了大規模的分散式系統而發明的程式語言。目前工作上也沒有這類應用場合,所以也不會特別花心思去學習,但Go在大規模Web Application上的應用確實有潛力,值得留意Go程式語言的發展。

###

2013年6月25日 星期二

Beginning Eclipse

Eclipse 是一個強大的整合式開發環境 (Integrated Development Environment, IDE) ,除了可以開發 Java 應用程式之外,也支援其他程式語言的開發,如 C, C++, Python, PHP 等。

這篇文章將說明如何將 Eclipse 安裝在 Ubuntu 上,或者你也可以參閱官方的安裝指南

Step 1. 安裝Java Virtual Machine (JVM)
  • 可以參考 Ubuntu 的社群文件:https://help.ubuntu.com/community/Java
  • JVM 有很多實踐方式,建議安裝 Oracle Java ,可以參考安裝教學
    • 前往http://www.oracle.com/technetwork/java/javase/downloads/index.html
    • 依照作業系統是32或64位元選擇 JRE 下載,以64位元為例,選擇下載 Linux x64 的檔案為 jre-7u21-linux-x64.tar.gz
    • 在 /usr 下建立 java 目錄,指令:sudo mkdir /usr/java
    • 將 jre-7u21-linux-x64.tar.gz 解壓縮至 /usr/java 下,
      指令:sudo tar xzvf jre-7u21-linux-x64.tar.gz -C /usr/java/ --no-same-owner
    • 利用 update-alternatives 安裝 java 命令,指令:
      sudo update-alternatives --install "/usr/bin/java" "java" "/usr/java/jre1.7.0_21/bin/java" 1
    • 在 Terminal 中輸入:java -version,將顯示版本資訊,用以測試 java 是否安裝成功。
Step 2. 安裝 Eclipse
  • 前往http://www.eclipse.org/downloads/
  • Eclipse 有不同套裝軟體(差異請參考比較表),建議下載 Eclipse Classic ,請依據作業系統是32或64位元選擇。
  • 下載後,解壓縮至 /opt 目錄下,以64位元的最新版 Eclipse 為例,指令:
    sudo tar xzvf eclipse-SDK-4.2.2-linux-gtk-x86_64.tar.gz -C /opt --no-same-owner
  • 變更權限,指令:sudo chgrp -R sudo /opt/eclipse/
  • 執行 /opt/eclipse/eclipse 這個執行檔將啟動 Eclipse Classic ,第一次啟動會要求設定工作區 (workspace)
Step 3. 安裝 Marketplace Client
  • Eclipse Classic 預設是沒有安裝 Marketplace Client ,有了 Marketplace Client 可以讓我們安裝延伸套件更加方便,有點類似 App Store !
  • 啟動 Eclipse ,在工具列的 Help 選擇「Install New Software...」,在 Work With 選擇 Juno 項目,下方表格中選擇 General Purpose Tools 的 Marketplace Client 。
  • 按下 Next ,之後確認 License 繼續安裝。安裝完成後會要求重新啟動 Eclipse 。
Step 4. 安裝 Eclipse Color Themes
  • Eclipse Color Themes 是一個佈景配色管理的套件,能夠讓Eclipse的編輯環境有不同的高亮 (highlight) 顯示方式。
  • 啟動 Eclipse ,在工具列的 Help 選擇「Eclipse Marketplace...」,搜尋 Eclipse Color Themes 安裝,完成後重新啟動 Eclipse。
  • 另外必須安裝 Web content engine library for GTK+才能正常工作,
    指令:sudo apt-get install libwebkitgtk-1.0-0
  • 上述步驟都完成後,可以在 Eclipse 的 Preferences 裡面的 Appearance 看到 Color Theme 的設定項目。
到此,你已經擁有一個完整又強大的程式開發環境囉!

補充:
2013/07已經發布 Eclipse 4.3 (代號 Kepler ),看來把 Eclipse Classic 稱為 Eclipse Standard ,這次發行增加許多功能,請見http://eclipse.org/kepler/

###

2013年6月12日 星期三

Big Data 大數據

Big Data稱為巨量資料大數據,這大概是雲端運算之後最為流行的科技議題,然而沒多少人知道什麼是巨量資料。現在,這本「大數據」清楚解釋什麼是巨量資料,以及巨量資料對人類造成的革命性改變(如同雲端運算對商業模式的影響),這本書的內容在技術方面著墨不深,主要是說明巨量資料的觀念與影響,非常適合任何對於巨量資料有興趣的人閱讀,可說是巨量資料的入門書(科普書)。

麥爾荀伯格、庫基耶著,林俊宏譯,大數據,台北:天下遠見,2013。
譯自: Big data: a revolution that will transform how we live, work, and think

「大數據」整本書是一個金字塔架構,全書共10章,從現在談到未來,如果你真的沒有時間,只看第一章也能對巨量資料有基本的認識,這本書建議各位依序閱讀完全,感覺就像上了兩位大數據專家的一堂課。

巨量資料目前還沒有明確定義,不妨參考 Gartner 公司的研究副總裁蘭尼 (Doug Laney) 提出的「三個V」性質(參閱第一章參考資料),即資料量 (volume) 、速度 (velocity) 、種類 (variety) ,這樣對於「巨量」會比較有感覺。這本書沒有確切說明何謂巨量資料,主要是強調巨量資料帶來的改變,主要改變有三點:
  1. 能夠取得、分析的資料量大為增加
  2. 不會堅持一切都要做到精確
  3. 放下長久以來對於因果關係的堅持
之所以有這些改變在於現在是從「小量資料」轉變到「巨量資料」的時刻,由於科技的進步,分析處理巨量資料已經不再困難,然而過去小量資料 (small data) 的時代發產出來概念已不適用於未來。

第一個改變來自於資料取得不是隨機抽樣的方式。過去,因為處理資料能力有限,不得不對真實世界以隨機抽樣取得小量資料,現在,已有能力處理巨量資料,資料的取得盡可能是真實世界的全部且完整的資訊,或者說:全部都是樣本。

第二個改變基於第一個。由於資料是全部的測量點(取樣點),因而產生三個結果:發生錯誤的可能性相對提高、取得不同來源與類型的資料、各資料格式也會不盡一致,這些都是雜亂 (messy) 。雜亂是巨量資料的特性,資料的「精確」已經不是重點,關注的反而是「可能性」這個目標,由於有了全部的資料,我們在乎的是整體輪廓的價值。對於巨量資料而言,資料的數量比品質更為重要。

第三個改變是最重要的變革。基於我們已經擁有完整的資料,分析某個現象的因果關係其實已經不太重要,不太需要知道「為何如此」,我們只需要了解現象之間彼此的相關性 (correlation) ,觀念必須改為知道「正是如此」就夠了,這個概念讓我們得到更多新的「因果關係」,將足以改變我們看待一切的方式。

上述這三個改變將影響我們的生活與工作,並建立全新的思考方式,若想更進一步瞭解巨量資料,這本「大數據」絕對值得好好閱讀。

###

2013年6月4日 星期二

Selenium Browser Automation 瀏覽器自動化

Selenium (硒) 」是一套瀏覽器自動化 (browser automation) 的套件軟體,包含一系列工具程式 (suite of tools) ,最主要的目的是用來自動化測試 (testing) 網頁應用程式 (web application) ,或者利用自動化的功能建立網頁操作的管理工作。簡單來說,利用Selenium去幫我們操作瀏覽器,免除人為操作而達成自動化。

Selenium目前的版本是第2版,稱為「Selenium 2」,Selenium 的工具程式主要有4個部分,其中以 IDE 和 WebDriver 最為重要,各程式介紹如下:
  • Selenium IDE
    這是一個 Firefox 的附加元件,提供測試工作的錄製、編輯、執行與除錯等功能。
  • Selenium WebDriver
    這是一個用來操作瀏覽器的 API,對 Selenium 而言就像是瀏覽器的「驅動程式」,不同瀏覽器必須安裝不同的 WebDriver ,呼叫這個 API 的方式是安裝不同程式語言的程式庫,程式庫將直接對瀏覽器進行操作(直接呼叫瀏覽器的 API )。這是在第2版才加入的工具程式, Selenium WebDriver 又稱為「Selenium 2」。
  • Selenium Remote Control
    簡稱 Selenium RC ,也稱為「Selenium 1」,目前不建議 (deprecated) 使用。 Selenium RC 採用 Server-Client 架構的方式進行瀏覽器自動化,主要是利用瀏覽器內的 JavaScript 來達到自動化的操作。
  • Selenium Grid
    這是可以同時間執行多個 Selenium 的技術,由一個 Hub 和多個 Node 組成一個 Grid ,使用者透過 WebDriver 將測試工作送至 Hub ,而 Hub 將依據瀏覽器不同分派至特定 Node 執行,利用這種方式可以縮短總執行時間。
執行 Selenium 瀏覽器自動化必須在有桌面環境的系統下執行,例如 Windows 或 Ubuntu Desktop 的作業系統,因為 Selenium 會去真的啟動瀏覽器程序並控制它的動作,若要在 Ubuntu Server 上執行就會發生錯誤(沒有安裝瀏覽器)。

一般會建議使用 Windows 系統進行自動化測試,因為在 Windows 上可以執行 Internet Explorer (IE)、Chrome、Firefox、Safari 都不會有問題,適合進行 Web Application 的相容性(跨瀏覽器)測試,因為 IE 只能在 Windows 上執行!不然就是使用 Selenium RC Server ,遠端操作不同作業系統的瀏覽器。

###

2013年5月16日 星期四

Size of Python built-in types 內建型別大小

利用sys模組的getsizeof函式,可以取得Python物件的大小。這裡我用來取得Python內建型別的物件大小,用來分析一個最基本的型別物件(實體化物件,不指定初值)之成本(overhead),各型別物件的大小如下表所述。

TypeSize (Bytes)
bool24
bytearray48
bytes37
complex32
dict280
float24
frozenset232
int24
list72
long24
object16
property88
set232
str37
tuple56
unicode52

可以看到萬物基礎的object物件,其初始大小是16 bytes,其他物件都是繼承至object類別,因此物件不會比「object」小。最大的型別物件是280 bytes,dict用起來非常方便,用key就能取得value,但要注意「成本」,撰寫程式時務必選擇適當的型別,才不會造成記憶體的浪費(雖然,現在記憶體都是1~2GB以上)。

從這個表格也可以看到一件事,可變更(mutable)的物件普遍比不可變更(immutable)來得大,例如「list」比「tuple」大,而「bytearray」比「str」大,如果撰寫程式時不會變更其值,不妨使用較「經濟」的型別!

計算上述物件成本是用程式撰寫而產生,其程式碼如下:

if __name__ == "__main__":
    import types
    import sys
    tbody='<tr><th>Type</th><th>Size (Bytes)</th></tr>'
    for item in dir(__builtins__):
        attr = getattr(__builtins__, item)
        if type(attr) is types.TypeType and \
           not issubclass(attr, BaseException):
            try:
                obj =attr()
                tbody +='<tr><td>%s</td><td>%s</td></tr>' %\
                      (item, sys.getsizeof(obj))
            except TypeError:
                pass
    table = '<table border="1" cellpadding="5" style="width: 80%%;">%s</table>' % tbody
    print table

###

2013年5月14日 星期二

Visualization of Python’s built-in exceptions 視覺化Python內建例外

修改前一篇的程式碼,可以得到內建例外(Built-in Exceptions)的繼承關係。

if __name__ == "__main__":
    import types
    import gv
    g = gv.digraph('exceptions')
    gv.setv(g, 'overlap', 'false')
    gv.setv(g, 'splines', 'true')
    gv.setv(g, 'pad', '1')
    for item in dir(__builtins__):
        attr = getattr(__builtins__, item)
        if type(attr) is types.TypeType and \
           issubclass(attr, BaseException):
            tail = None
            head = None            
            for i in attr.__mro__:
                nodename = i.__name__
                tail = gv.findnode(g, nodename)
                if not tail:
                    tail = gv.node(g, nodename)
                if head and not gv.findedge(tail, head):
                    gv.edge(tail, head)
                head = tail
    
    gv.layout(g, 'neato')
    gv.render(g, 'png', 'built-in_exceptions.png')

視覺化結果如下圖所示:(大圖連結)

由圖上可以看到,例外物件的基底類別是BaseException,而Exception繼承BaseException,提供給所有內建的、系統的與使用者定義的例外去繼承Exception,這裡可以看到Python例外分成兩大類,一個是StandardError,另一個是Warning

###

2013年5月13日 星期一

Visualization of Python’s built-in types 視覺化Python內建型別

利用Graphviz軟體可以將結構性資料用圖形呈現,這裡將以圖形繪製Python內建型別的繼承關係,我使用Graphviz的Python API輸出PNG圖形,程式碼如下:

if __name__ == "__main__":
    import types
    import gv
    g = gv.digraph('types')
    gv.setv(g, 'overlap', 'false')
    gv.setv(g, 'splines', 'true')
    for item in dir(__builtins__):
        attr = getattr(__builtins__, item)
        if type(attr) is types.TypeType and \
           not issubclass(attr, BaseException):
            tail = None
            head = None            
            for i in attr.__mro__:
                nodename = i.__name__
                tail = gv.findnode(g, nodename)
                if not tail:
                    tail = gv.node(g, nodename)
                if head and not gv.findedge(tail, head):
                    gv.edge(tail, head)
                head = tail
    
    gv.layout(g, 'neato')
    gv.render(g, 'png', 'built-in_types.png')

執行完畢之後,將會在程式同一路徑下產生一個檔名為built-in_types的PNG檔。

從這張圖可以看到所有的型別都是繼承至object類別。

###

2013年5月6日 星期一

安裝Python

記錄Python安裝過程與套件管理工具的安裝。

Linux (Ubuntu Distribution)平台,以Ubuntu 12.04 LTS為例。
  • 內建已經安裝Python 2.7。
  • 安裝套件管理工具,指令:sudo apt-get install pip。
Windows平台,以Windows 7 64-bit為例。
  • 下載python-2.7.3.amd64.msi,執行安裝,預設路徑安裝至C:\Python27。
  • 下載setuptools,由於64位元系統沒有MSI安裝精靈,請下載ez_setup.py,使用python.exe執行,指令:C:\Python27\python.exe ez_setup.py
  • 利用easy_install.exe安裝套件管理工具,指令:c:\Python27\Scripts\easy_install.exe pip
在Windows上也可以用pip喔!

如果在開發Python應用程式有需要任何套件,都可以使用「pip install 套件名稱」進行下載安裝(前提是要可以上網),非常方便。

###

徹底研究Python:談標準程式庫

徹底研究Python:談標準程式庫(standard library)。

Pyhton提供的標準程式庫相當多,去除特定平台,大致上可以分成26類服務,大概有239個模組。
  1. String Services (11)
  2. Data Types (19)
  3. Numeric and Mathematical Modules (9)
  4. File and Directory Access (12)
  5. Data Persistence (13)
  6. Data Compression and Archiving (5)
  7. File Formats (6)
  8. Cryptographic Services (4)
  9. Generic Operating System Services (17)
  10. Optional Operating System Services (9)
  11. Interprocess Communication and Networking (7)
  12. Internet Data Handling (16)
  13. Structured Markup Processing Tools (15)
  14. Internet Protocols and Support (25)
  15. Multimedia Services (10)
  16. Internationalization (2)
  17. Program Frameworks (2)
  18. Graphical User Interfaces with Tk (5)
  19. Development Tools (5)
  20. Debugging and Profiling (5)
  21. Python Runtime Services (17)
  22. Custom Python Interpreters (2)
  23. Restricted Execution (2)
  24. Importing Modules (7)
  25. Python Language Services (13)
  26. Miscellaneous Services (1)

詳細的說明可以參閱官網的The Python Standard Library。這理必須提到Python的哲學,Python具有「batteries included」,battery指的就是這些標準程式庫,這些標準程式庫都是一般普遍常用的功能,能夠立即解決功能上的需求,因此開發時不太需要額外安裝其他程式庫。

###

2013年4月23日 星期二

The $100 Startup 小資創業老闆的實戰成功術

近一兩年以來,出現很多創業與創投的相關書籍,這些書多半討論科技網路方面的創業內容(例如成立網路公司、利用創投基金開始...),對於不是在科技網路領域創業的人而言,這些書的幫助有限。

現在「3000元開始的自主人生」這本以相當務實的角度出發,利用「小資(即書名的$100美金)」開始自己的「微型創業」之路,作者古利博(Chris Guillebeau)訪問相當多的微型創業老闆,分析並研究這些創業歷程,他找出實際可行的方法,在書中教導大家如何從事自己所愛的事情,以及如何創造「錢途」,這本書不講高深複雜的商業知識,而是提供立即可用的實戰技術。


古利博(Chris Guillebeau)著,連育德譯,3000元開始的自主人生:50位小資創業老闆的實戰成功術,台北市:天下遠見,2013。
譯自:The $100 Startup: reinvent the way you make a living, do what you love, and create a new feature

整本書的架構分成三部曲共14章,「創業首部曲」主要是建立正確的小資創業觀念,自己創業是為了什麼?為了做自己想要的事情(興趣),還是因為意外解雇而不得不的選擇之一,不管為何,創業是為了追尋自己所要的自由,而創造價值則是通往成功創業的途徑。

這本書最重要的一點是;「唯有提供價值給別人,才能獲得工作自由。」利用自己的專長或興趣去創造出別人所需要的產品或服務,這是微型創業成功的關鍵!如何提供別人所需的價值呢?這本書都有一些方法讓你找出來。

「創業二部曲」則是討論創業之後的工作,主要以行銷方面為主,如何開始第一筆生意,如何讓別人知道你的服務或產品,還有重要的訂價策略,價格取決於你提供的價值,而不是工作的時間。最後「創業三部曲」是討論創業上軌道後的事情,例如事業如何持續成長,商業模式的規劃等。

###

2013年4月19日 星期五

amazon.com的秘密

這是一本講述亞馬遜公司(amazon.com)從創業至成功的故事書,輕鬆地閱讀這本書來認識amazon.com,瞭解它成功的原因,為何貝佐斯(Jeffrey Preston Bezos)要從賣書這個領域開始,時間若回到亞馬遜創立的1994年,就不得不佩服他洞燭先機!

貝佐斯發現當時網際網路一年是成長23倍,他認為快速成長就代表無限商機,分析潛力商品發現賣書是最有機會的一條路,因為書本市場夠大、易於運送、不需庫存...等,加上書本的資料非常容易用電腦與網路去搜尋和管理,顧客可以用網路找書、買書。天時地利之下,貝佐斯本身也是個聰明人,也喜歡閱讀,最重要的一點,顧客至上,「點一下還不夠」,提供客戶更好的服務,這也是所有成功企業的重要基本要素,從下面這段話可以看到。

「我們要成為全世界最重視顧客的企業,無論人們想要在網路上買什麼東西,都可以在我們的網站上找到。」亞馬遜的企業使命 p. 33


理察‧布蘭特(Richard L. Brandt)著,閻紀宇譯,amazon.com的秘密,台北市,天下雜誌,2012。
譯自:One Click: Jeff Bezos and the Rise of Amazon.com

書中除了敘述這些成功過程之外,部分也描述亞馬遜如何壓榨員工的故事,也有商場上競爭的故事,整體而言,這本書完整而有秩序的介紹亞馬遜,閱讀上建議從頭開始讀起。

最後,書中附錄有一段「貝佐斯2010年普林斯頓大學畢業演講摘錄」,這段演講也可以在TouTube上看到完整演說。


貝佐斯(Jeff Bezos):仁慈比聰明困難。(It is Harder to be Kind than Clever.)...聰明是天賦,仁慈是選擇。天賦與身俱來,但是選擇就難了。如果不小心,你們可能就會被聰明誘使做了傷害仁慈的選擇。

###

2013年4月8日 星期一

Clean Code 無瑕的程式碼

最近這本『無瑕的程式碼』非常熱門!除了廣告打的兇之外(暢銷的書總是一開始就暢銷),重點在於作者和書的內容,Bob 大叔 (即Robert C. Martin) 也是另一本經典著作『敏捷軟體開發:原則、樣式及實務』的作者,不論你是否認同敏捷軟體開發 (Agile Software Development),只要是撰寫程式的軟體開發人員都要好好閱讀這本 Clean Code,因為我相信大家都會遇到這樣的事情:

公司急於讓產品完成上市,導致程式碼慢慢變得一團亂。加入越來越多的功能,程式碼越來越糟糕。每次修改程式也讓程式碼更加混亂、曲折及可怕,程式碼越來越龐大、艱深且複雜。

生產力漸漸降低,於是管理者想辦法招募更多新員工,由於新員工不知原始系統的設計,因而修改將破壞原本設計的原意,程式碼趨近崩解的邊緣。於是開發人員提出無法在現有設計上繼續開發下去,新的專案油然而生...持續陷入永無止境的迴圈之中,總是希望下一個軟體專案會更好。

這樣的問題到底出在哪裡?


Robert C. Martin 著,戴于晉、博碩文化編譯,無瑕的程式碼:敏捷軟體開發技巧守則,新北市:博碩文化,2013。
譯自:Clean Code: a handbook of agile software craftsmanship

作者 Martin 先生認為在於軟體開發人員(程式設計師)的態度,程式設計師沒有專業的把程式碼撰寫優良,導致劣質的程式碼慢慢腐蝕軟體的進度和品質,解決之道是『Clean Code』!

Bob 大叔將本書分成3大部分,第一部份(第1至第10章)說明什麼是無瑕的程式碼與 Clean Code 的原則、模式和實踐方式,第二部份(第11至第16章)則是以一些案例進行討論程式碼的清理 (clean)。最後第三部份(第17章)則是『程式碼氣味型錄』,記錄這本書中 Clean Code 的心得,這部份算是重點整理。(在序中沒有明確說明章節是第幾部分,這裏是看內容後自己劃分的)

整本書相當精彩,閱讀起來也相當舒適,可以感覺博碩文化出版的用心。書中提到博碩文化在這個『名家名著系列』 的願景,這裡不得不推崇一下出版社的堅持和貢獻,希望未來台灣與華人地區有更多經典著作的中文翻譯書籍。

###

2013年4月5日 星期五

Virtualization 虛擬化技術

這篇文章將簡述虛擬化技術(virtualization),主要目的是將一些觀念說明清楚,因為現在大家對於虛擬化好像都只知道CPU的虛擬化,其實虛擬化的範圍很廣,有必要讓大家都知道。主要參考資料是『雲端策略』這本書,由陳瀅 等著,天下文化所出版。

虛擬化概念是在1950年代首次提出,到1960年代才在IBM大型主機上實現商用。電腦系統之所以可以虛擬化,原因在於電腦系統分為若干層次,在這些不同層次之間建構虛擬化層,對使用者提供與真實系統相同或類似的功能,使得上層系統可以運行在該中間層(虛擬化層)之上。由於中間層解除上下兩層間原本存在的耦合關係,使上層的運行不依賴下層的具體實作方式。

虛擬化的對象主要是各式各樣的電腦資源,經過虛擬化後的邏輯資源對使用者隱藏了不必要的細節,使用者可以在虛擬環境中實現其在真實環境中的部分或者全部功能。以電腦資源區分虛擬化技術有:
  • 硬體資源
    • CPU虛擬化
      • 軟體:全虛擬化(Full Virtualization)、半虛擬化(Para-Virtualization)
      • 硬體(硬體輔助虛擬化,hardware assisted virtualization ):Intel®VTAMD-V™
    • 記憶體虛擬化(虛擬記憶體)
      • 影子分頁表法
      • 分頁表寫入法
    • I/O虛擬化
    • 伺服器虛擬化:CPU虛擬化+記憶體虛擬化+I/O虛擬化
      • 原生虛擬化:虛擬化平台(hypervisor)
      • 寄宿虛擬化:虛擬機監視器(Virtual Machine Monitor, VMM)
    • 儲存虛擬化
      • 基於儲存設備虛擬化:磁碟陣列(Redundant Array of Inexpensive Disks, RAID)
      • 基於網路虛擬化:網路附加儲存(Network Attached Storage, NAS)與儲存區域網(Storage Area Network, SAN)
    • 網路虛擬化
      • 區域網路虛擬化:虛擬區域網路(Virtual LAN, VLAN)
      • 廣域網路虛擬化:虛擬私有網路(Virtual Private Network, VPN)
  • 軟體資源
    • 作業系統虛擬化
    • 檔案系統虛擬化
    • 桌面虛擬化(Desktop Virtualization)
    • 應用程式虛擬化(Application Virtualization)
    • 高階語言虛擬化
可以看到在CPU虛擬化的部份,一般大家說的全虛擬化、半虛擬化是指用軟體去模擬CPU,顯然這種方式一定比硬體輔助虛擬化的方式效率要差,目前幾乎都是使用硬體輔助虛擬化。注意到,除了CPU虛擬化之外,其實還有記憶體虛擬化、I/O虛擬化、儲存虛擬化、網路虛擬化等不同的資源虛擬化,不要只認為虛擬化都是指硬體CPU的部份,這是不完整的觀念!

###

2013年4月2日 星期二

Catalog of Design Patterns 設計模式型錄

這裡將列出物件導向程式設中的「設計模式」型錄,資料是節錄自「物件導向設計模式:可再利用物件導向軟體之要素(Design Patterns: Elements of resuable object-oriented software)」這本書的內容,此書作者是Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides著(所稱「四人幫」),由葉秉哲先生所翻譯,台灣培生教育出版,可以在天瓏書局購買(好像也只有天瓏有賣)。

下列型錄包含3大類共23個設計模式,並列出其目的。

生成模式(Creational Patterns)
將物件具現化的過程抽象化地加以萃取,使系統能獨立於物件的建立、組成及表現方式之外。
  • 工廠方法模式(Factory Method)
    定義可資生成物件的介面,但讓子類別去決定該具現出哪一種類別的物件。此模式讓類別將具現化程序交付給子類別去處置。
  • 抽象工廠模式(Abstract Factory)
    以同一個介面來建立一整族相關或相依的物件,不需點明各物件真正所屬的具象類別。
  • 建造者模式(Builder)
    從複雜物件的佈局中抽取出生成程序,以便用同一個生成程序製造各種不同的物件佈局。
  • 原型模式(Prototype)
    制訂可用原型個體生成的物件類型,爾後只須複製此原型即可生成新物件。
  • 獨體模式(Singleton)
    確保類別只會有一個物件實體存在,並提供單一存取窗口。

結構模式(Structural Patterns)
在探討如何以類別和物件組合成大型的結構。
  • 轉接器模式(Adapter)
    將類別的介面轉換成外界所預期的另一種介面,讓原先囿於介面不相容問題而無法協力合作的類別能夠兜在一起用。
  • 橋接模式(Bridge)
    將實作體系與抽象體系分離開來,讓兩者能各自更動各自演進。
  • 組合模式(Composite)
    將物件組織成樹狀結構、「部分─全體」層級關係,讓外界以一致性的方式對待個別物件和整體物件。
  • 裝飾模式(Decorator)
    將額外權責動態附加於物件身上,不必衍生子賴別即可彈性擴增功能。
  • 外觀模式(Façade)
    替子系統裡一堆介面定義一套統一的高階介面,讓子系統更易使用。
  • 享元模式(Flyweight )
    以共享機制有效地支援一大堆小規模的物件。
  • 代理模式(Proxy)
    替其他物件預留代理者空位,藉此控制存取其他物件。

行為模式(Behavioral Patterns)
探討物件之間的演算法及權責分配問題。
  • 解譯器模式(Interpreter)
    針對標的語言定義出文法,以及可解讀這種語句的解釋器。
  • 範本方法模式(Template Method)
    對於操作,只先定義好演算法的輪廓,某些步驟則留給子類別去填補,以便在不改變演算法整體構造的情形下讓子類別去精鍊某些步驟。
  • 職責鏈模式(Chain of Responsibility)
    讓多個物件都有機會處理某一訊息,以降低訊息發送者和接收者之間的耦合關係。它將接收者物件串連起來,讓訊息流經其中,直到被處理了為止。
  • 命令模式(Command)
    將訊息封裝成物件,以便能用各種不同訊息、暫存、記錄、復原等方式加以參數化處理。
  • 迭代器模式(Iterator)
    毋須知曉聚合物件的內部細節,即可依序存取內含的每一個元素。
  • 仲介者模式(Mediator)
    定義可將一群物件互動方式封裝起來的物件。因為物件彼此不直接相互指涉,所以耦合性低,容易逐一變更互動關係。
  • 備忘錄模式(Memento)
    在不違反封裝性的前提下,捕捉物件的內部狀態並存在外面,以便日後回復至此一狀態。
  • 觀察者模式(Observer)
    定義一對多的物件依存關係,讓物件狀態一有變動,就自動通知其他相依物件作該做的更新動作。
  • 狀態模式(State)
    讓物件的外顯行為隨內部狀態改變而改變,彷彿連類別也變了似的。
  • 策略模式(Strategy)
    定義一整族演算法,將每一個演算法封裝起來,可互換使用,更可在不影響外界的情況下個別抽換所引用的演算法。
  • 訪問者模式(Visitor)
    定義能逐一施行於物件結構裡各個元素的操作,讓你不必修改作用對象的類別介面,就能定義新的操作。
對於上述設計模式的目的說明,看完與看懂是兩種不同的境界,若以投手與捕手做例子,看完23個設計模式就像捕手可以接到投手所投的球,但這不表示捕手知道投手為什麼會投這樣的球,看懂則是進入知其然的境界了。

###

2013年3月27日 星期三

Refactoring: Improving the Design of Existing Code 重構:改善既有程式的設計

什麼是重構(Refactoring)?所謂重構是這樣的一個過程:「在不改變程式碼外在行為的前提下,對程式碼做出修改,以改進程式的內部結構」。重構是一種有紀律的、經過訓練的、有條不紊的程式整理方法,可以將整理過程中不小心引入錯誤的機率降到最低。本質上說,重構就是「在程式碼寫好之後改進他的設計」。p. xvi

這是一本介紹「重構」技術的書籍,如果你想認識並瞭解這門技術,「重構:改善既有程式的設計」絕對是聖經本。一開始作者以案例方式帶領讀者進入重構的過程,第一章藉由案例認識重構的方式與準則。接著第二章說明重構的基礎知識,包括何謂重構、為何需要重構、何時應該重構...等基本問題,再來第四章用「程式的壞味道」來判斷何時應該開始重構、何時應該停止重構,第四章則是說明重要的觀念:重構的前提必須是擁有一個可靠的測試環境。大致上來說,如果你閱讀完前四章,那你對於重構技術已經有完整的認識了。


Martin Fowler等著,侯捷、熊節合譯,重構:改善既有程式的設計,台北:台灣培生教育出版:碁峰資訊發行,2008。
譯自:Refactoring: Improving the Design of Existing Code,作者群:Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts。

接著第5章至第12章則是作者在工作中整理出來的「重構名錄(catalog of refactorings)」,這些重構名錄是這本書的核心,利用這些重構名錄所記載的重構方法,我們可以很方便的改善既有程式的設計。這些重構方法如下(也就是書的目錄一部份),這些方法可分成7大類總共72個:
  • 重新組織你的函式 (Composing Methods)
    1. Extract Method (提煉函式)
    2. Inline Method (將函式內聯化)
    3. Inline Temp (將暫時變數內聯化)
    4. Replace Temp with Query (以查詢取代變數)
    5. Introduce Explaining Variable (引入解釋性變數)
    6. Split Temporary Variable (剖解暫時變數)
    7. Remove Assignments to Parameters (移除對參數的賦值動作)
    8. Replace Method with Method Object (以函式物件取代函式)
    9. Substitute Algorithm (替換你的演算法)
  • 在物件之間移動特性 (Moving Features Between Objects)
    1. Move Method (搬移函式)
    2. Move Field (搬移欄位)
    3. Extract Class (提煉類別)
    4. Inline Class (將類別內聯化)
    5. Hide Delegate (隱藏「委託關係」)
    6. Remove Middle Man (移除中間人)
    7. Introduce Foreign Method (引入外加函式)
    8. Introduce Local Extension (引入區域性擴展)
  • 重新組織你的資料 (Organizing Data)
    1. Self Encapsulate Field (自我封裝欄位)
    2. Replace Data Value with Object (以物件取代資料值)
    3. Change Value to Reference (將實質物件改為引用物件)
    4. Change Reference to Value (將引用物件改為實質物件)
    5. Replace Array with Object (以物件取代陣列)
    6. Duplicate Observed Data (複製「被監視資料」)
    7. Change Unidirectional Association to Bidirectional (將單向關聯改為雙向)
    8. Change Bidirectional Association to Unidirectional (將雙向關聯改為單向)
    9. Replace Magic Number with Symbolic Constant (以符號常數/字面常數 取代魔術數字)
    10. Encapsulate Field (封裝欄位)
    11. Encapsulate Collection (封裝群集)
    12. Replace Record with Data Class (以資料類別取代記錄)
    13. Replace Type Code with Class (以類別取代型別代碼)
    14. Replace Type Code with Subclasses (以子類別取代型別代碼)
    15. Replace Type Code with State/Strategy (以 State/Strategy 取代型別代碼)
    16. Replace Subclass with Fields (以欄位取代子類別)
  • 簡化條件句 (Simplifying Conditional Expressions)
    1. Decompose Conditional (分解條件式)
    2. Consolidate Conditional Expression (合併條件式)
    3. Consolidate Duplicate Conditional Fragments (合併重複的條件片段)
    4. Remove Control Flag (移除控制旗標)
    5. Replace Nested Conditional with Guard Clauses (以衛述句取代巢狀條件式)
    6. Replace Conditional with Polymorphism. (以多型取代條件式)
    7. Introduce Null Object (引入Null物件)
    8. Introduce Assertion (引入斷言)
  • 簡化函式呼叫 (Making Method Calls Simpler)
    1. Rename Method (重新命名函式)
    2. Add Parameter (添加參數)
    3. Remove Parameter (移除參數)
    4. Separate Query from Modifier (以查詢函式和修改函式分離)
    5. Parameterize Method (令函式攜帶參數)
    6. Replace Parameter with Explicit Methods (以明確函式取代參數)
    7. Preserve Whole Object (保持物件完整)
    8. Replace Parameter with Method (以函式取代參數)
    9. Introduce Parameter Object (引入參數物件)
    10. Remove Setting Method (移除設值函式)
    11. Hide Method (隱藏某個函式)
    12. Replace Constructor with Factory Method (以工廠函式取代建構式)
    13. Encapsulate Downcast (封裝「向下轉型」動作)
    14. Replace Error Code with Exception (以異常取代錯誤碼)
    15. Replace Exception with Test (以測試取代異常)
  • 處理繼承關係 (Dealing with Generalization)
    1. Pull Up Field (欄位上移)
    2. Pull Up Method (函式上移)
    3. Pull Up Constructor Body (建構式本體上移)
    4. Push Down Method (函式下移)
    5. Push Down Field (欄位下移)
    6. Extract Subclass (提煉子類別)
    7. Extract Superclass (提煉超類別)
    8. Extract Interface (提煉介面)
    9. Collapse Hierarchy (摺疊繼承體系)
    10. Form Template Method (塑造模板函式)
    11. Replace Inheritance with Delegation (以委託取代繼承)
    12. Replace Delegation with Inheritance (以繼承取代委託)
  • 大型重構 (Big Refactorings)
    1. Tease Apart Inheritance (梳理並分解繼承體系)
    2. Convert Procedural Design to Objects (將程序式設計轉化為物件設計)
    3. Separate Domain from Presentation (將領域和 表述/顯示 分離)
    4. Extract Hierarchy (提煉繼承體系)
註:侯捷先生在他的網站上有公布書中第一章至第六章的內容,有興趣的讀者可以先上網試讀!網站是http://jjhou.boolan.com/jjtbooks-refactoring.htm
###

2013年3月13日 星期三

徹底研究Python:談關鍵字(keywords)

徹底研究Python:談關鍵字(keywords)。

討論一下Python程式語言的關鍵字,所謂關鍵字指的是程式語言本身保留的識別名稱(Identifiers ),我們不能使用這些關鍵字作為程式的識別名稱,例如變數名稱、函式名稱或類別名稱等等。

Pythony總共有31個關鍵字,可以匯入keyword模組找出有哪些關鍵字,存取keyword.kwlist就會列出關鍵字的串列資料。Python的關鍵字如下:
  1. and
  2. as
  3. assert
  4. break
  5. class
  6. continue
  7. def
  8. del
  9. elif
  10. else
  11. except
  12. exec
  13. finally
  14. for
  15. from
  16. global
  17. if
  18. import
  19. in
  20. is
  21. lambda
  22. not
  23. or
  24. pass
  25. print
  26. raise
  27. return
  28. try
  29. while
  30. with
  31. yield
注意到print在Python 2是關鍵字,然而在Python 3的版本則是內建函式。

###

2013年3月8日 星期五

徹底研究Python:談型別(type)

徹底研究Python:談型別(type)。

Python內建型別總共28個,這些型別本身也是一種物件(在Python程式語言裡面所有的都是物件),稱為型別物件(type objects),使用type()函式可以知道物件的型別是什麼型別物件。

在Python的標準程式庫中,types模組定義部分型別的型別名稱,我們可以使用這些型別名稱取得型別物件,像是types.IntType就是取的int型別物件,注意到並不是所有的型別物件都有定義名稱,只有16個型別有定義名稱,整理如下表。

內建型別物件型別名稱
basestring
boolBooleanType
bufferBufferType
bytearray
bytes (bytes型別是Python 3.0才正式新增, 2.x等於str)
classmethod
complexComplexType
dictDictType, DictionaryType 
enumerate
fileFileType
floatFloatType
frozenset
intIntType
listListType
longLongType
memoryview
objectObjectType
property
reversed
set
sliceSliceType
staticmethod
strStringType
super
tupleTupleType
typeTypeType
unicodeUnicodeType
xrangeXRangeType

另外在內建常數的部分,types模組定義定義3個型別名稱,分別是:

內建常數型別名稱
NoneNoneType
NotImplementedNotImplementedType
EllipsisEllipsisType


剩下的型別名稱則是常用的物件,因此types模組定義這些物件的型別名稱,總共17個
  1. BuiltinFunctionType
  2. BuiltinMethodType
  3. ClassType
  4. CodeType
  5. DictProxyType
  6. FrameType
  7. FunctionType
  8. GeneratorType
  9. GetSetDescriptorType
  10. InstanceType
  11. LambdaType
  12. MemberDescriptorType
  13. MethodType
  14. ModuleType
  15. StringTypes
  16. TracebackType
  17. UnboundMethodType

列出內建型別的程式碼
if __name__ == "__main__":
    import types
    for item in dir(__builtins__):
        attr = getattr(__builtins__, item)
        if type(attr) is types.TypeType and \
           not issubclass(attr, BaseException):
            print attr

###

2013年3月6日 星期三

徹底研究Python:談內建(built-in)物件

徹底研究Python:談內建(built-in)物件。

啟動Python interpreter之後,就已經可以使用一些東西,這些東西稱為Python的內建(built-in)物件,是Python程式語言本身的一部分(即Python的核心)。我們可以使用「__builtin__」模組存取這些內建物件,使用len(dir(__builtin__))或len(__builtins__)指令可以發現總共有144個,這些內建物件可以分成下列4類:
  • 內建常數,共11個
    • Python程式語言本身內建,共6個
      1. False
      2. True
      3. None
      4. NotImplemented
      5. Ellipsis
      6. __debug__
    • 因Python自動匯入site模組,額外加入常數至內建名稱空間之中,共5個
      1. quit
      2. exit
      3. copyritht
      4. license
      5. credits
  • 內建型別,共28個
    1. basestring
    2. bool
    3. buffer
    4. bytearray
    5. bytes (bytes型別是Python 3.0才正式新增,2.x版的bytes等於str型別)
    6. classmethod
    7. complex
    8. dict
    9. enumerate
    10. file
    11. float
    12. frozenset
    13. int
    14. list
    15. long
    16. memoryview
    17. object
    18. property
    19. reversed
    20. set
    21. slice
    22. staticmethod
    23. str
    24. super
    25. tuple
    26. type
    27. unicode
    28. xrange
  • 內建函式,共53個
    1. __import__
    2. abs
    3. all
    4. any
    5. apply
    6. bin
    7. callable
    8. chr
    9. cmp
    10. coerce
    11. compile
    12. delattr
    13. dir
    14. divmod
    15. eval
    16. execfile
    17. filter
    18. format
    19. getattr
    20. globals
    21. hasattr
    22. hash
    23. help:因Python自動匯入site模組,額外加入至內建函式中
    24. hex
    25. id
    26. input
    27. intern
    28. isinstance
    29. issubclass
    30. iter
    31. len
    32. locals
    33. map
    34. max
    35. min
    36. next
    37. oct
    38. open
    39. ord
    40. pow
    41. print
    42. range
    43. raw_input
    44. reduce
    45. reload
    46. repr
    47. round
    48. setattr
    49. sorted
    50. sum
    51. unichr
    52. vars
    53. zip
  • 內建例外,共48個
    1. ArithmeticError
    2. AssertionError
    3. AttributeError
    4. BaseException
    5. BufferError
    6. BytesWarning
    7. DeprecationWarning
    8. EOFError
    9. EnvironmentError
    10. Exception
    11. FloatingPointError
    12. FutureWarning
    13. GeneratorExit
    14. IOError
    15. ImportError
    16. ImportWarning
    17. IndentationError
    18. IndexError
    19. KeyError
    20. KeyboardInterrupt
    21. LookupError
    22. MemoryError
    23. NameError
    24. NotImplementedError
    25. OSError
    26. OverflowError
    27. PendingDeprecationWarning
    28. ReferenceError
    29. RuntimeError
    30. RuntimeWarning
    31. StandardError
    32. StopIteration
    33. SyntaxError
    34. SyntaxWarning
    35. SystemError
    36. SystemExit
    37. TabError
    38. TypeError
    39. UnboundLocalError
    40. UnicodeDecodeError
    41. UnicodeEncodeError
    42. UnicodeError
    43. UnicodeTranslateError
    44. UnicodeWarning
    45. UserWarning
    46. ValueError
    47. Warning
    48. ZeroDivisionError
上述數量加起來共140個,剩下4個是模組屬性(attribute):
  • _:上一次最新輸出的結果(last printed expression)
  • __doc__:文件字串
  • __name__:名稱
  • __package__:套件

###

2013年2月23日 星期六

Graphviz 圖形視覺化

偶然在自由軟體鑄造場讀到這篇「Graphviz - 用指令來畫關係圖吧!」,玩了一下之後,發現Graphviz是個不錯的軟體,Graphviz是開放源碼的圖形視覺化軟體,圖形視覺化(graph visualization)是將結構化資訊以圖表(diagram)的方式呈現圖形(graph)或網路(network),所以Graphviz就是graph visualization。

Graphviz讀取DOT語言所建立的圖形描述檔案,依據我們設定輸出有用的檔案格式,像是JPG, PNG, SVG, PDF...等。此外,Graphviz對於具體圖表也提供許多有用的特色,例如顏色、字型
、樣式、超連結...等,讓使用者可以調整外觀樣式。

想要在Ubuntu上安裝Graphviz相當容易,執行「sudo apt-get install graphviz」就可以了,安裝完成後,就能利用下列指令建立不同圖表。(這些指令說明透過man graphviz指令)
  • dot
    階層式配置(hierarchical layout)圖形,繪製的圖形有方向性。
  • neato
    彈簧模型配置(spring model'' layout)圖形,通常不超過100個節點,繪製的圖形無方向性。
  • twopi
    放射狀的配置(radial layout)圖形。
  • circo
    環狀配置(circular layout)圖形。
  • fdp
    和neato的配置相似,差別在於neato是最小化energy function,而fdp是減少force,繪製的圖形無方向性。
  • sfdp
    多尺度(multiscale)的fdp版本,繪製的圖形無方向性。
對於這些指令有基本認識之後,最簡單使用Graphviz的方式是利用DOT語言建立一個檔案(通常是.gv的副檔名),利用Graphviz的指令處理輸出圖片,這部分可以參考「Graphviz - 用指令來畫關係圖吧!」裡面的「Graphviz 的使用」。

還有,若想使用Python控制Graphviz,可以使用libgv-python,安裝指令是sudo apt-get install libgv-python,使用方式請參考Graphviz的API文件

###

2013年1月9日 星期三

Android User Interface 使用者介面

這篇將概略介紹開發Android應用程式所需的User Interface資訊,詳細內容請參閱官方網站:http://developer.android.com/guide/topics/ui/index.html
  • Android應用程式的UI是用View物件與ViewGroup物件所建置出來的。
    • ViewGroup類別是View的子類別,比較特殊的是ViewGroup可以包含其他View,或者說ViewGroup是裝載View的容器。
    • 常用的ViewGroup元件有三個
      • LinearLayout
      • RelativeLayout,最強大的配置方式,專家建議使用。
      • AbsoluteLayout,絕對定位的配置方式,幾乎不太會用到。
    • 常用的View元件有
      • Button
      • EditText
      • CheckBox
      • RadioButton
      • ToggleButton
      • Spinner
      • DatePicker
      • TimePicker
      • TextView
  • 建立UI的方式有兩種
    • 使用XML文件宣告UI元素,XML Layout檔案會在專案的res/layout資料夾中。專家建議使用這種方式建立UI!可以讓Code和Design分離。
    • 撰寫程式碼在執行時間實體化UI元素,讓程式可以動態控制UI。
  • UI設計,參閱http://developer.android.com/design/get-started/ui-overview.html
    • Action Bar很重要, Android 3.0 (API level 11)之後加入,官方建議使用。
###

熱門文章