Category Archives: 中文文章

Python SCSS與Compass/Blueprint輕鬆整合

身為網頁的開發者,相信在寫CSS時總會覺得少了什麼,很多風格明明都只差了一兩句,就得複製貼上或是重寫好幾次,此時你會想說如果有個import或是繼承CSS樣式的語法就好了、如果能夠訂義變數然後在CSS語法裡做加減乘除就好了,而事實上這些SCSS與SASS都可以幫你做到,它是一種將CSS擴充的一種語言,先用SCSS或SASS寫好網頁的排版,接著再用工具將其編譯成CSS檔 取此官網的例子,例如你可以這樣寫 $blue: #3bbfce; $margin: 16px; .content-navigation { border-color: $blue; color: darken($blue, 9%); } .border { padding: $margin / 2; margin: $margin / 2; border-color: $blue; } 事先定義好變數,然後在裡面使用,這還只是小小的功能之一,它還可以繼承、引入,比起直接寫CSS方便了許多 搭配上Compass/Blueprint的CSS框架,寫起來更是輕鬆愉快,想要重設CSS嗎? 很簡單 @import “compass/reset” @include blueprint-global-reset; @import “compass/reset” 是指引入compass/rest這個模組,然後@include blueprint-global-reset;是指將SCSS的語法片段插入此處,如此一來就輕鬆地重設了CSS,然而,這只不過是小菜一盤 想要採用CSS3,但是又對於-moz、-webkit、-ms … … Continue reading

Posted in Python, 中文文章, 分享 | Tagged , , , , , , , | 1 Comment

新世紀通訊函式庫 – ZeroMQ

2012年就快到了,離2015年第三次衝擊也快到了,聽不懂我在說什麼就算了,跟主題沒什麼關聯,在介紹主角之前,我總喜歡描述一下主角的背景 欲上雲端,必先分散 這幾年,雲端炒得正熱門,愛跟風的台灣人當然也不能錯過,不管是賣主機的聲稱他們是做雲端的,連賣房子的也稱他們的是雲端,哪天就連在路邊看見雲端雞排都請不要大驚小怪,因為那簡直和奈米光觸媒雞排一樣有異曲同工之妙,然而口口聲聲說雲端,但前陣子iPhone4S預購就給了各家電信商一個大巴掌,他們的網頁伺服器都在一瞬間被大量擁入的使用者塞暴了,更別說其中還有不乏自家推出雲端服務的電信商,說真的,連分散運算的基本功都做不到,跟人家雲什麼端? 你說是吧? 但今天的主角不在於雲端是什麼,或是什麼才算真正的雲端之類的無聊話題,今天的主軸是分散式運算,因為要達到規模的運算和高可得性就一定要扯到分散式的運算,而分散式運算一直以來都不是什麼簡單的議題,最麻煩的就要算是溝通上的問題了,如果你有 三個節點之間想要進行溝通,該怎麼做? 你說簡單,直接串在一起不就好了? 好吧,或許你只有固定的三個節點,這好辦,但是要是你有更多的節點呢? 考慮一下十個節點、一百個節點,光想像就能知道,隨著節點的增加,他們之間的連線數量呈指數在成長,不光是連線本身的問題,連這些節點要如何知道對方的存在以及管理都是相當麻煩的問題 中央集權 光想就令人頭皮發麻,為了解決這樣的問題,一個經典的模式被設計且大量使用,那就是所謂的 Broker (掮客),也有稱Message Queue、Message bus等,簡單的概念,就是所有節點都連向中間的訊息交換伺服器,而溝通都透過這個中央的交換中心來進行,節點與節點之間無需去在意到底誰在和我溝通,只需要在意訊息的種類和內容即可   雖然這樣的模式解決了一些問題,但同時也引入了新的問題,分散式系統的頭號公敵 – 單點失效,正因為所有節點都依賴著這個中間的掮客幫忙轉送訊息,這也意味著當掮客網路斷線、當機等等意外的發生,都會讓整個系統陷入停擺的狀態,除此之外還有另一個嚴重的問題,就是當節點數量增加,掮客的工作量也會一直往上升,在無法擴增的情況下會造成整個系統的擴展性受到限制,效能也會因為掮客受限制 各自為政 正因為中央集權造成了問題,所以有人提出了各自為政來解決問題,可以想見的,在分散式的系統裡,並不是所有的節點都需要和所有人進行溝通,他們通常只需要和特定的節點溝通,舉個例子,假設你設計的是一個多媒體檔案的處理系統,在第一個節點可能做的是Hash,用來產生該檔案的唯一識別編號,節點二做的是轉檔,節點三做的是儲存,節點四做的是歸檔,那麼你需要的就只是這樣的結構,如果以物件導向的設計模式來看,我們稱這樣的結構為責任鏈   再看另一個例子,如果我們是氣象局,想發佈各種天氣的消息,那麼你需要的是一個伺服器,讓大家去訂閱他們有興趣的主題,這樣的結構以物件導向的觀點來看就叫做觀察者模式,與我們先前見到的Broker做的是一樣的事情,然而在這裡的重點在於該伺服器只負責發佈天氣消息,並不參與訊息的交換 整體的概念就是各自有不同的子系統,我們透過通訊的方式將它們串在一起,這樣做有個好處就是效能好,再來就是設計得當的話,某子系統雖然停擺,但不會影響到所有的系統 各自為政的代價 雖然各自為政的做法有其好處,但相對的也有它的代價,光是通訊的協定就是很腦人的問題,考慮一下各種不同的子系統間該用什麼協定來溝通,連線中斷了怎麼處理,負載平衡? 這些問題都要花相當大的心力來解決 而在不同的環境下,使用不同的通訊方式都各有好處,使用TCP/IP的話,不管你的節點在同一台機器或是遠端,都可以連線,缺點是在同一台機器會有一定的效能耗損,而且遇到廣播的訊息,同樣的訊息被傳送N次,就沒有UDP廣播來得划算,如果節點是在同一台機器上溝通,使用IPC的方式效率好,如果是在同一個thread裡,那麼分享記憶體的方式最快,IPC反而會拖慢速度,正因為有各種不同的考量,使得想要達成高效率的分散式系統是一件困難的事情 是主角登場的時候了 – ZeroMQ 講了半天,ZeroMQ到底是做什麼用的? 簡單的來說,它是一套網路通訊函式庫,用來解決上面所提到的問題,考慮一下上面所提到的物件導向設計模式,你想,即然那樣的模式一再出現,為什麼我們不能將這些常見的通訊方式變成可以輕易重覆使用的形式? ZeroMQ所做到的即是如此,它將常見的通訊方式定義成不同行為的socket,讓你可以輕易地重覆使用這些樣式去組出強健的分散式系統 老樣子 Hello world.. 不! 是Hello baby … Continue reading

Posted in 中文文章, 分享 | Tagged , , , , , , , , , , , , , | 8 Comments

那些台灣軟體產業所缺少的 – 開放源始碼

前面幾篇談到了台灣軟體產業界常見的毛病,除了工具以外,還有一項令我感到相當意外的,就是我發現台灣業界對於開放源始碼的認知真的很有問題,例如我曾有和別人討論過,跟他們你們可以使用open source的現成資源來減低成本,但是得到的回應很常是 那不是讓你用但之後就要付錢嗎? 從這類的回應就可以大略知道,其實有很多人對於開放源始碼都有一些錯誤的認知,到底什麼時候該付錢、什麼情況可以使用都搞不清楚,因此這回我大算介紹一下一些常見的開源授權的常識 免責聲明 在讀本文前我得先聲明,我不是律師,這不是提供專業的法律見解,只是試著用較易懂的方式解釋授權,以我自己的經驗來說明,其中多少可能會有錯誤,請自行判斷,也歡迎指出錯誤,如有需要請洽詢專業的法律諮詢,在本文末會提到 認識授權 (License) 首先要從授權(License)的概念開始談起,開放源始碼通常不是只是單純把程式碼公開出來,而是一般都會搭配某種授權,而授權的意思,以白話來說,就是寫了一份聲明,裡面這樣提到 此程式任何人可以免費使用,但是使用前你必需遵守以下條款…. 有了這樣的聲明,使用開源的人就可以放心使用,當然前提是要遵守授權所提出的條款,基本上因為已經授權出來,所以就算是原作者反悔,也沒辦法控告你什麼,除非你違反他當初訂出來的條款,而一般人看見落落長的條款項目可能就怕了,更何況是用英文寫的,但是別擔心,事實上要注意的要點只有幾樣,都大同小異,同一類條款的性質都很類似 散佈(Redistribute) 在理解授權之前,首先要理解散佈,這是授權裡面一定會提到的重要關鍵動作,那麼什麼是散佈呢? 簡單的來說,就是將軟體轉交給其它人,不管你是以原始碼的形式,或是編成二進制執行檔後,只要是轉交給其它法人,就算是散佈,舉個例子 把原始碼上傳供人下載 把原始碼拿來販售 把原始碼編成執行檔供人下載 把原始碼編成執行檔販售 以上都算是散佈的行為,所有的授權條款裡面都會提到散佈開源程式時你應盡的義務,當然,也有很多行為是稱不上散佈的,例如 將原始碼交給公司內部某個單位 將原始碼編譯成執行檔自己使用 在伺服器上以開源程式執行提功服務給使用者 像這樣沒有法人的經手,都不算是散佈的行為,對於散佈的行為介定是很重要的,等一下會解釋 授權(License)的種類 授權有(License)非常多種,我們在此大略將其分成三大類,第一類是GPL,第二類為BSD,而第三類為商業授權,是較為特別且少見的,其中GPL最不自由,而BSD最自由   在這裡自由與不自由主要是指你在使用這些開源軟體時所要盡的義務的多和少 GPL GNU General Public License主要是由Linux陣營的開源軟體開發者為主在使用的,它有幾個特色 散佈要連修改的部份一起開源 病毒的感染性 排它性 散佈與修改 如同我們前面提到的散佈,最重要的重點是,如果你改了程式,而又要散佈程式,那麼你在散佈的同時也要把你修改的部份也公開出來,例如 修改了原始碼後拿來販售 修改了原始碼後編成執行檔供別人使用 上列行為都扯到了散佈,因此如果你程式有修改,你不能只給別人執行檔,要連改的部份一起開源出來,這條款的目的主要是在於GNU的社群,希望強迫使用者能回饋社群,因為一但你改了程式,想拿來賣錢,就得公開出來,避免有人改進了程式,拿來販售,但沒有公開程式的問題 … Continue reading

Posted in 中文文章, 作品, 嘴砲 | Tagged , , , , | 8 Comments

那些台灣軟體產業所缺少的 – 自動化測試

你是否有計算過,你在寫專案的過程中,測試過了多少次的程式? 我想是沒有,我也沒有,但是你是否有曾想過,或是感覺過,隨著專案的膨漲,你要測試的項目也跟著變多了? 這是理所當然的事情,當專案小,測試還算很輕鬆,因為程式的功能不外乎就那幾樣,一轉眼就測完了,常見的寫程式流程會像這樣 撰寫新功能 測試新功能 當然,也有修正bug的情況 修正bug 測試bug 如此一直循環,當你寫了新功能,理所當然地會去測試新功能,看是否如你預期地執行,那舊功能呢? 或許你記憶力不錯,在寫新功能的同時,想到先前某個舊功能是依賴現在改的東西,這麼一改可能會造成舊的功能出問題,於是你也順便測了一下舊的功能,當程式還小 撰寫新功能 測試新功能 測試舊功能 嘿,不怎麼樣吧? 只佔了開發時間的三分之一,好吧那如果有更多的舊功能要測呢? 撰寫新功能 測試新功能 測試舊功能 測試舊功能 測試舊功能 …. 發現了沒有? 隨著你的專案越來越大,如果要確保整個系統所有的功能都是正常運作的,無可避免地,在你修改程式之後要測試的項目會越來越多 這表示你每寫一行新程式的成本增加了,身為以減低成本為傲的島國 國民: 台灣人…,你說,簡單! 不要測舊功能不就好了? 是的,我想這可能就是最常見的情況,不要測試舊功能理所當然地,每寫一行的程式成本都保持一樣很低,但這代表著舊程式可能出錯的風險也跟著增加了,當你喜滋滋地覺得你幫公司省了成本,結果在一個月後因為舊程式缺乏測試,因改動了核心的部份造成舊的功能將所有資料外洩,公司損失慘重,這就是不重視軟體品質的後果 舉真實生活上發生過的例子,PTT曾經有過改程式未經好好地測試,造成每個人都能以管理員的權限登入的事情,知名的檔案同步平台Dropbox,也曾經發生過因為認證的程式改版有bug,造成任何人都可以登入別人帳號的事,我也有曾聽聞一些網站因為工程師為了測試方便,把認證的函數暫時改成 function authenticate(user_id, password) { return true; // do authentication here // … Continue reading

Posted in 中文文章, 分享, 嘴砲, 資訊安全 | Tagged , , , , , , | 5 Comments

那些台灣軟體產業所缺少的 – 版本控制系統

這幾年來,多多少少接觸了不少業界的人,雖然我自己還不算有真正待過業界太久,但是這期間看到不少業界的現象都令我挺驚訝的,例如在聊天時提到你們公司用的版本控制系統是什麼,有很多人都會回答 「那是什麼?」,一直以來這些在國外的主流開發環境都基本常識或是標準配備的東西台灣業界居然很多都連有那樣的工具存在都不知道,或著是對於某些東西有錯誤的認知,所以我想大略提一下常見的幾個問題 版本控制系統 我想這是最常見的毛病,很常發現很多公司在開發軟體時從來都不使用版本控制系統,最誇張的狀況就是管它三七二十一直接修改   除此之外,常見的土法鍊鋼有聽說過資料夾複製,然後將資料夾名稱命名為版本1之類的方法,高級一點還有搭配Excel來記錄改過了什麼之類的 更進階的還有多人共同開發,還架了FTP來放這些檔案 但這些都有很大的問題,而且其會遇到的問題都正好是版本控制系統所要解決的,所以到底是什麼樣的問題非用版本控制系統不可? 首先,用資料夾copy有個很大的問題,一來是copy的過程很容易出錯,而且更糟的是出的錯很難發現,你怎麼從資料夾的內容來判斷這到底是哪個版本? 最常見的做法就是回想你到底在哪個版本改了什麼,然後去看對應的位置,是否有那些改動,但你有可能記得嗎? 要是程式不是你改的呢? 因此依賴資料夾名稱來得知檔案的版本是極度不可靠的做法,再者,如果你不幸改到錯誤的版本,辛辛苦苦改了半天,才發現改到舊版本了,那你要如何把你改的和正確的版本合在一起? 如果你只改了三行,這還好辦,但如果你改了三百行,那該怎麼辦? 用Excel來記錄改動的事項和版本一樣不會有幫助 那多人開發使用FTP來分享檔案呢? 老天,事情更慘了,原先只是你自己的開發,自己改錯了就算了,如今變成多人開發,有時出問題還不是你改的,這樣想好了,FTP上有個檔案 hello.py 今天張三載回去改了,變成 hello.py (張三版) 不幸的是,王五在張三上傳回FTP之前,也載回來改,變成 hello.py (王五版) 接著,張三把它的檔案上傳了,所以FTP上的檔案變成了 hello.py (張三版) 然後好戲發生了,王五也把它改的東西上傳了,所以FTP上的檔案被蓋掉,變成 hello.py (王五版) 發生了什麼事? 張三改的版本被蓋掉了,你可以想見張三在demo給老闆看時發現改的地方被蓋掉了,翻過辦公桌衝過去揍王五的情景了嗎? 像這樣還只是最簡單的情境,以這類土法鍊鋼的方式,還有太多太多預料不到的複雜情況會發生,什麼? 那你說,如果我們規定每人都得把資料夾以自己的名稱命名,加上版號,再上傳,這樣就不會錯了吧? hello_project-王五-rev123/ 拜託,何苦呢 ? 版本控制系統就是用來解決這些問題而開發出來的,學一套新工具有這麼難嗎? 常見的理由可能會有什麼沒時間學、不信任工具等等,事實上那些都不是理由,只要是程式碼的開發,都得使用版本控制系統,現在已經是2011年,如果你的軟體開發沒有使用版本控制系統,我說這不叫落後,這是原始 用了版本控制系統,最重要的好處是 你可以安心地放膽去改程式 … Continue reading

Posted in 中文文章, 分享, 嘴砲 | Tagged , , , | 9 Comments

淺談區域性 (locality)

在設計不同的網路服務系統時,為了能夠有擴展性,通常都會設計成分散式的架構,然而除了架構上的設計,如何部署也是很重要的事,其中有個很重要的議題叫做區域性,因為沒有統一或明確的翻譯慣例,所以以英文來說明較為精確,在這裡指的區域性英文為locality,對於這個議題最近有一點心得 所以,回到主題,到底什麼是區域性? 簡單的來說,就是存取資料或資源時,很常存取或是相關的資料放在一起、或很近的地方的特性,舉個實例,例如假設我們有關於某個使用者的資料,但是使用者相關的資料分散在全球不同的資料庫裡,這時我們就會說,這資料庫的區域性不好,以圖來表示,我們假設使用者的資料分散在美西的DB1、美中的DB2和美東的DB3,而使用者在西雅圖要存取這些資料,就得走很遠的距離到三個很遠的地點存取資料 反言之,如果關於這使用者的資料,都存在離使用者很近的點,而且也都在同樣或是很接近的資料庫裡,那麼存取起來就會較快,這樣一來我們就可以說這樣的資料儲存方式它的區域性比較好,我們假設把同一使用者相關的資料都放在相近的地方,以圖為例,都放在加洲,這樣一來同樣是存取使用者的資料,其中所花的傳輸距離成本就遠比上一個例子來得少,反應速度也會因此較快 一般而言,區域性是越強越好,但是也有例外,那就是當考慮到可得性(availability)的時候,這樣的特性是指資料或資源隨時都可取得的機率高低,如果當我們把雞蛋放在同一個籃子裡,也就是資料都放在同樣的Datacenter裡,一但這個Datacenter對外的網路中斷,或是甚至遇到不可預料的災難時,那麼那些資料都會因此而無法取得,所以除了考慮到存取時的區域性,當資料有一定重要程度時,可得性也是很重要的考量,所以某些情況下,資料分散也是必要的 然而,區域性就表面看來,似乎只要將常用的、相關的資料都放在一起好像就能達成,然而經過仔細思考會發現其實並不是只有這樣,還有需要考慮到存取資料的距離,還有存取要求本身的高低階,在這篇文章我想分享的就是主要在於思考關於區域性設計上的一些理論的心得 請求的相依性與粒度 我發現並不是所有的情況下不佳的地區性都一定會嚴重影響到存取的效能,像是請求的相依性其實對於延遲的影響就非常大,如果說所有的情求都不能同時處理,一定得要上一個完成才能完成下一個的話,這樣一來就會造成每個request的請求都要額外花費一次連線的延遲成本,可以參考下圖 很明顯的,左邊的情況,傳輸距離所造成的影響,會是 請求數量 * (運算成本 + 延遲成本) 右邊的情況是 (請求數量 * 運算成本) + 延遲成本 因此光是請求是否能同步處理,並且是否有前後相依,就會造成相當大的差別,如果請求的數量越多,這樣的成本差距就越大,左邊的例子我們以NoSQL或是 SQL的請求為例子,通常下一道請求都是基於上一道請求的資料而決定的,如果說任務被拆散成很零碎的多道請求,像是有些key-value based的NoSQL資料庫,因為沒有高階的查詢指令,必然會有大量的請求,如此一來如果NoSQL資料庫放在很遠的地方,就會造成光是這之間的傳輸成本就會高得嚇人,而以SQL來看,因為可以盡可能地將多道SQL濃縮為少數幾道查詢,因此同樣的傳輸成本對於SQL資料庫來說,傳輸的成本造成的影響會小一點 而右邊的情況,通常是大量的資料傳輸,例如影音串流,因為上一筆資料無關下一筆資料,以這種情況來看,傳輸的距離不會是太大的問題,只有一開始會有的傳輸延遲 心得 一些簡單的心得就是,當請求是相依的,如果數量不大,那麼其實傳輸的延遲是可以被忽視的,又或著是大量連續的資料傳輸,距離的影響是較小的,如果不考慮連線的品質問題的話,但是如果是有相依特性的請求,數量又大的話,最好資料庫的部署要越接近越好,否則光是連線的延遲成本就相當驚人,就算你的NoSQL資料庫再怎麼快,也沒有任何幫助,甚至會比SQL資料庫還要慢

Posted in 中文文章, 分享 | Tagged , , , , | Comments Off on 淺談區域性 (locality)

我有一個夢想

我很幸運,出生在網路快速成長的年代,感謝網路的發明,我從國一就有機會開始學習寫程式,在這些年裡,心底一直都有一個疑問,我相信很多人都跟我一樣有同樣的疑問 「為什麼台灣沒有軟體服務產業?」 我們從新聞看見Yahoo成功、Google成功、Facebook成功,但是卻很少看見來自台灣的軟體服務產品能夠站上國際舞臺,台灣的硬體毫無疑問的是相當有競爭力的產業,然而隨著競爭國家的掘起、工資物料成本的提升,到後來就只能爭取幾毛錢的毛利,相對於硬體,軟體和服務才是能增加最多價值的產品,搭配台灣的硬體優勢將會是最強的組合,然而縱觀千百種不會成功的理由,不管是教育的問題、硬體產業的排擠效應、社會風氣的問題等等,這些都不是一朝一夕就可以改變的,因此我相信只有透過一些人來開路,先建立成功的典範,以這些人當種子散播就有機會帶動整個台灣軟體發展,不管是Google、Yahoo等等公司,有很多新創的公司都是從這些公司出去的員工 「那麼誰來做這些事?」 我知道,不管我有再多的想法,不去做都只是空想而已,我告訴我自己,不要期待別人來完成你的夢想,只有靠自己才有辦法改變這世界,我相信 「做的比說的大聲」 或許有人會說,這會失敗,我們的教育都傾向教我們一定要成功,卻沒有教我們要如何失敗,或許最終會以失敗收場,但又如何呢? 在我大學一年級決定開始Now.in的計劃時,我想過各種失敗的可能性,但是我這樣問自己 「如果因為怕失敗不去做,難道你要等到哪天看見別人做出你想做的東西,那時才大聲嚷嚷那是我的想法嗎?」 我不想成為最後只剩一張嘴的人,於是我開始動手,在大學上面講課時我在下面畫伺服器架構的設計圖,回到宿舍上網找適合的技術,當別人在寫程式作業時,我在寫Now.in的程式,當別人在打魔獸時 . . . . . . . . 我也在打魔獸,終於網站在2009年年底上線,隨著時間過去,從一開始只有最簡單的廣播功能,到後來漸漸增加了一些功能,看著使用人數越來越多,就像生了一個女兒看她長大一樣 她在 Alexa的排名也來到了全台458,全球57K 而在前陣子我們也在IDEAS Show得到不錯的成績,朝我們的夢想邁進了一小步,我們希望有一天我們可以成為廣播界的Youtube,然而隨著我們想做的東西越來越多,而技術人力只有我自己一個,很多使用者都以為我們是一個公司或團隊,當收到抱怨信說為什麼出問題時我們也只能無奈的賠不是,因為使用者不知道這其實是一個人做出來的,直到前陣子我找了我兩位同學幫忙寫iPhone和Android的app,才有其它的人加入,雖然手機只是我們很久以前就有的想法,但只因為人力不足,所以一直都沒辦法實現,甚至一開始我還打算連手機的app都自己完成,因此我想在這裡大聲地說 「我們需要你的幫助」 在擁抱美好夢想前,我想先把醜話說在前頭 「我們沒有資金」 很不幸的是我們並沒有太多的資金能夠雇用人力,我們沒有豪華的辦公室,沒有員工旅遊,沒有錢請全聯先生替我們代言,我們只能提供微薄的薪水雇用實習的員工,所以為什麼你要加入我們? 我們有技術 我們有的是以Python為核心的相關技術,在Now.in裡幾乎所有程式都是用相當新的Python技術寫的,而且範圍牽涉之廣,從桌面應用程式、網路伺服器、網頁應用程式甚至到伺服器管理都是,所以加入我們你可以學到技術,這些是花錢去補習班或請家教也學不到的 我們有使用者 身為一個程式設計師,我想最傷心的事情大概莫過於寫出來的程式沒有人使用,對於Now.in來說,現在每天有十萬個訪客,線上聽眾的鋒值可以達到一萬,電台可以達到一千個,我相信最開心的事情就是看到自己的程式有人使用,我同學推出的iPhone和Android App在短短幾週內都達到了五千次的下載,並且一直在成長,這成就感我想是金錢無法比擬的 我們有理想 就如同我們的口號 「廣播和收聽全世界」 我們希望能夠打造一個線上的廣播社群,讓任何人都可以有發聲的管道,除此之外我們還希望能夠讓人們可以更緊密地在我們的平臺上互動,還有太多太多我們想達成的目標,簡單的來說 「我們想改變世界」 這些理想都是在大公司很難找到的 我們需要你的參與 我們需要以下的人才 … Continue reading

Posted in 中文文章 | Tagged , | 35 Comments

那些在Now.in學到的 – Software engineering practices

Now.in這個網站在2009年年底上線,在這幾天參加IDEAS Show之前終於來到了台灣前五百大,全球六萬名,這期間只花了一年半,而事實上這個網站早在我大學一年級約2006年左右就開始有這樣的想法,接著花了一兩年的時間開始構思和找相關的技術,2009年開始實作,從開始到上線只花了一年的時間,其中專案之龐大還有牽扯到的層面之廣,從架構的設計、後端伺服器的譔寫、前端網頁、Client端、伺服器管理、資料庫管理,很多人都不相信這只有我一個人完成的,而且還是在讀大學和碩士的課餘時間,直到最近上線的Android和iPhone才找了同學幫忙寫,感寫他們這幾週的辛苦 這整個過程的經驗,事實上多到可以寫一本書,不只是技術上的,之後有空我也會寫一些文章來分享我在其中所學到的一些東西,今天我要分享的是我在碩士一門軟體工程課以Now.in為主題所分享的一些經驗,主要是一些我在開發Now.in前後所體認到的一些經驗與想法,因為我發現很多人不是沒有技術,而是缺少對於服務、軟體工程等等的相關思維,或許這篇文章會有一些幫助,除此之外,我也希望能夠將我自己的想法記錄下來,當我要接受新的想法時,就可以回頭看看以前的自己為什麼會有這樣的想法 人越少,越有效 這樣的想法主要來自人月神話這本書,軟體開發不像是收割小麥,人越多越有效率,因為需要溝通,這意味著當你有越多人牽扯在這其中,所花的溝通成本也越高,每個人的平均效率就越低,除此之外,有一句話這麼說 讀程式比寫程式困難 相信有寫過真正程式的人都會有這樣的體認,寫程式的過程是將你的思想轉化為程式寫出來,而讀程式則是透過這些字句語法來理解程式原本的想法,就有如瞎子摸象一樣,因此當你的團隊裡有越多人寫同一份程式,光是在讀程式理解想法才能繼續寫的這整個過程中就損耗了不少生產力,因此甚至知名的電腦科學學者Dijkstra主張程式應該由單一個人來寫,因為它是一個人的想法 這樣的想法除了來自人月神話,也受最近出版的一本書Rework影響,它是來自37Signals公司的經驗,37Signals是一家小型軟體公司,雖然只有十幾個人的規模,但是推出的產品都很受歡迎,他們強調要找對的優秀開發者,還有開會是造成生產力浪費的原因之一,我認為Now.in之所以能以我一人之力完成,正因為我不需要開會做決策、不需要溝通,將我自己的生產力發揮到極致才有可能完成的 然而,如果是小型的專案能夠一個人寫當然是最有效率的,但是當專案的規模大到一定的程度,超過一個人或少數人能完成的地步,增加人力資源就是不可避免的事,不過在此之前,要慎重考量引入新的人力所造成的影響 保持敏捷 很常見的錯誤軟體開發方式就是一口氣推出一大堆功能,然後期待使用者會喜歡這些功能,但是可悲的事實是這些功能推出來通常都不是使用者所要的,就如投影片所表示的,一口氣在單一個開發循環中推出了一大堆的功能,這花了很多的時間與心力,但是卻發現使用者要的的只有一小部份和目前所做的有所重疊 在現實上,你總覺得你可以抓到使用者所想要的,但仔細想想會發現那是你自己想要的,並不一定每個人都跟你想要的是一樣的東西,一口氣在一個循環內開發如此多的功能,對於變化如此快速的網路世界來說,你永遠都趕不上變化 邊移動邊開火才是正確的方式,這有一部份的想法是來自約耳談軟體,如投影片所看到的,一開始先從最核心的功能做起就好,然後看使用者的反應與需求再來改版與新增功能,盡量保持每個開發循環很小,才能抓到使用者所要的 Now.in就是這樣的開發方式,就如投影片裡的抓圖,在一開始只有最核心的廣播功能,其餘的功能都是後來才加上去的,因我看見了需求,我看見使用者們邊聽廣播邊在PTT上推文討論,顯而易見的聊天是必需要有的功能,此後才開發了聊天室 右手邊這張圖是來自Rework裡的插畫,他們認為計劃就是在猜測,是的,沒錯,網路上充滿了創新與變化,很多東西是以前從來沒有人做過的,那麼你要如何計劃? 你沒辦法計劃,任何五年、十年計劃之類的東西都只是在賭博而已,不要浪費時間做太過長遠的計劃,邊移動邊開火才是正卻的做法,阿里巴巴的馬雲也說過,他們成功是因為 沒有資金、沒有技術、沒有計劃 這裡指的沒有計劃就是這麼一回事 老程式不死只是凋零 很多人會犯的一個毛病就是認為舊的程式都是很糟的,要完全砍掉重新寫才是好的,但是事實上從我的經驗告訴我,那些在線上跑經過多次修改的,遇過一大堆你在開發中想都想不到的詭異問題才存活到現今的,它們是如此的老練,有很多失敗的例子就是因為將舊有程式丟棄,直接採用全新的程式來面對實際的應用,事實上這樣就有如送沒見過世面的新兵上最慘烈的前線戰場送死是沒有兩樣的,我想或許Digg就是這樣的一個例子 Digg在去年推出全新的版本,但是不停地出現嚴重的問題,加上新的使用方式受到原本的使用者反彈,導至使用者大量且快速地流失,另一個例子是Netscape在推出新版時將舊的程式全部丟掉,在約耳談軟體的Things you should never do裡有提到 所以我們就一直使用舊程式就好了? 請別會錯我的意思,我想表達的是在前線跑的程式裡有太多是你重新寫不會想到的問題處理,請不要單純為了想砍掉重練而重寫,你需要的是重構而不是重頭寫過,就算你真的打算重新寫過,也請好好重視原本的寫法,以Now.in來說,有些東西就是從最早的版本傳承到現在的經驗 # XXX Workaround for fucking IE6, fuck you IE6! response.cache_control = “no-store, no-cache, … Continue reading

Posted in 中文文章 | Tagged , , , , | 26 Comments

技術應為服務而生

在前面的一系列文章裡,我發現有些人有些很有趣的想法,有些人覺得使用Windows是很落後的事,或是要用vim、gcc、gdb來寫程式才顯得有技術,我自己也是從小玩技術長大的人,事實上我很能理解這樣的想法,或著說我以前也是這樣的想法,但後來漸漸地想法就改變了 在大學時有位組合語言很強的傳說中的教授,他的組合語言課真的很令人印相深刻,他從來不帶課本,一上台就開始畫圖,然後用很粗俗易懂的例子講解,可以看得出他對低階的這塊領域實力有多深厚,有一次他在上課談到 我以前在做賭博電玩時,有人來跟我推銷繪圖晶片,可是我跟他說,不用,我覺得自己寫一個pixel一個pixel畫才有技術 可是後來發現別人用繪圖晶片來畫圖,一下子就做出來了,我還在刻低階的繪圖功能 後來因為這樣做不過別人就不做了 聽了之後仔細想想我自己也是這樣的想法,以前在寫遊戲時最初是用Direct Draw,後來覺得使用現成的函式庫沒什麼技術,在之後重寫的版本中,就自己寫畫圖的函式庫,一個pixel一個pixel去填,半透明混色也是自己去算,甚至想自己寫3D的繪圖引擎,雖然確實在這過程中學到很多東西,但事實上整個寫遊戲的過程中有好一大半的時間是花在底層的這些基礎繪圖功能上,後來漸漸理解,重覆利用別人做好的輪子是很重要的事,只因為覺得 “那樣才叫有技術” 而去自己做別人已經做好的東西是很不成熟的想法,後來我終於理解到 技術只不過是在工程中完成目標的手段,並不是最終的目的 除了技術以外,事實上在整個軟體的工程當中,還有太多值得注意的事,從你學習那項技術需要花多少心力,技術相關的社群,如果你是商業公司還得考慮到有沒有支援商業服務,還有你用這項技術的話能不能找到人來接替你的位置? 你用了這項技術生產力有因此而提升嗎? 以先前提到的例子,用gcc直接下指令編譯,用gdb下指令除錯,你的生產力有因此而提升嗎? 為了從一般的IDE環境下切換到這樣的環境需要多少的學習成本? 如果你找一個人來接續你的工作,他是否有辦法像你一樣熟練地使用這些工具? 如果你要教新來的人熟悉你的環境,你需要花多少時間? 我相信,大部份提到要使用這些工具的人都沒想過這些問題,這很正常,因為他們熱愛技術,但是實際的工程應用這些都會是很重要的問題。 人適應工具 而在這些提到的一些工具中,有個很極端例子,那就是vi/vim,我自己有用vim,因為打大量程式會比較有效率,或在Linux下改程式都得用到,為什麼說vim是很極端的例子,因為它的設技概念與我們一般常見的IDE是相反的,一般的工具都是設計工具來適應人,然而vim卻是設計工具要人去適應它,因為如果需要打大量的字,手一直保持在鍵盤上是最有效率的,所以它設計讓你手都不用離開鍵盤,就能進行所有的操作 Vim cheat sheet 來自 http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html 當然,缺點是它的學習曲線很陡,在一開始你可能打幾個字都會弄得灰頭土臉,身為技術人員如果你覺得打大量的字是很常有的事,這投資是值得的話,學一學vim確實是不錯,但推薦初學者學vim就不是什麼好事 所以,當你很興奮地覺得這個東西才算有技術,或著是開源萬歲之類的理由,推薦給別人時,想想你自己花多少時間學這東西,別人又能因此得到什麼好處好嗎? 而當你開始設計產品時,你想想如果Apple的Macbook廣告詞是 經過三個月的練習,使用我們的系統工作效率提升了50%!! 你覺得還會有人買這樣的產品嗎? 工具適應人 另一種設計的想法,也是主流的設計思維就是讓工具去適應人,大多數你能在市面上看到的產品都是這樣的設計,我們舉一些例子,Visual Studio最近推出了一種新的UI,叫Debugger Canvas,是將整個debugging trace的過程以泡泡視窗的方式串聯在一起,讓你可以很直覺地理解程式呼叫的過程 [yframe url=’http://www.youtube.com/watch?v=3p9XUwIlhJg’] 有這樣視覺化的輔助,除錯的過程會輕鬆許多,在有現代化工具可用的情況下,除了學習以外的炫技理由堅持使用原始的工具,就只是浪費寶貴的開發時間而已 再舉另一個例子,就是git或mercurial在送commit之前,我個人都會對送出的內容review一次,以免將測試用的程式也送進去,例如像是這樣糟糕的例子 def auth(user_id, password): # … Continue reading

Posted in 中文文章, 嘴砲 | Tagged , , | 16 Comments

常見的Linux暴炸原因

今天看大家在搶COSCUP報名,報名頁面一如往年掛掉了,以我自己的經驗看來這樣等級的流量樣打掛Nginx應該還有很大的距離,我自己處理過Now.in在運行中遇過無數各種奇奇怪怪的問題,所以很多常見的Linux暴炸原因都見怪不怪了,對於上千等級連線的伺服器這些是很常遇到的事,如果沒有弄好的話很容易就整個Linux卡住或炸掉,以下介紹一些我所知道Linux會被塞暴的主要原因,都是參數沒設好為主 最大檔案數沒設好 我想這是最多常犯的錯,當然我也犯過,linux預設每個user可以開1024個檔案,嚴格來說是file descriptor,當然socket也算在內,如果這個數字沒有調的話,就算你的Nginx或是什麼鬼伺服器再怎麼威猛,1024這麼少的數字,稍微大一點的流量,都一樣是被塞暴的下場,因為執行伺服器的使用者開不出新的檔案、socket來,而這個問題最常遇到是因為一般情況下你的網站連線數量要達1024不是每天都會發生的,可能發生一下子就沒了,等到哪天真正大流量來時才會發現整個網站暴炸了,但是1024個以上的同時連線數對於目前的now.in伺服器來說隨時都在發生的,所以如果我有哪台伺服器忘記設,很快的就會炸掉 至於要怎樣提高檔案數限制,請參考 Linux Increase The Maximum Number Of Open Files / File Descriptors (FD) ip_conntrack已滿,丟失封包 另一個常見被塞暴的是ip_conntrack,是iptables用來追蹤連線用的表,如果滿起來的話,新進來的封包會被丟掉,你可以在/var/log/message裡看見 Jul 15 19:22:30 hostname kernel: ip_conntrack: table full, dropping packet 這樣的訊息,可以透過修改最大值來解決,參考Linux Iptables ip_conntrack: table full, dropping packet error and solution 或是重開iptables service也可以洗掉目前的table … Continue reading

Posted in Linux, 中文文章 | Tagged , , , , | 3 Comments