關於作者
我是Victor Lin,Now.in的創辦人,興趣是程式設計,Python目前是我最喜歡的語言,從國一開始寫程式到現在已經有十個年頭,不過還有很多要學習,除此之外偶爾用小提琴製造一些噪音也是我的興趣之一
E-Mail: 
Tag Archives: now.in
Now.in 兩週年回顧
時間過得很快,這兩天SSL的憑證過期了,忘了事先申請,上次申請才不過是去年的今天左右的時間,轉眼間Now.in已經上線超過兩年的時間了,從原本只有幾隻小貓到今天有上萬人在線上,頁面檢視數量也在最近超過了一億次 我們也朝我們的目標挺進了不少,在許多國家都有不少的使用者,而且也有成長的趨勢 我們的使用者來自全世界的每個有網路的角落 就我們所知,台灣從沒有一個網站可以走到這個地步,在全球的競爭下哪怕能打下一小片天地而不是只有國內的市場,我們希望有一天大家可以驕傲地說對全世界說 Now.in是來自台灣的網站,在這整個過程中我們用了最少的資源來達成最大的效益,這些靠的都是熱情,還記得曾有訪問中有一個問題是 – Now.in改版了多少次? 我的答案是無數次,而事實上也是如此,改進是持續的,而不是突然達成的,紀念Now.in上線兩週年,回顧一下這整個演進的過程 一切的開始 最初版本的網頁,非常地陽春,就只有最簡單的註冊、登入與電台、編輯個人電台和收聽功能而已,右邊的按鈕本來是預留想做好看的插圖按鈕,但是沒有美術能力,所以就兩個框框留在右邊,看起來挺奇怪的 收聽的頁面也只有單純的一個播放器而已,用的還不是自己寫的,是Google reader的音訊播放器 早期的Mr.DJ也只有單純的播曲子串流到伺服器的功能,而且UI的設計是將播放列表和電台控制與收音的面版放在一起的 加入聊天室 聊天室早在一開始就是計劃好的,但在2010年4月份才正式加入,功能非常地陽春,連加入聊天室的動作都不用做,只要打名稱就能聊天,不過這也有個問題在於,任何人都可以假冒別人的名稱說話,除了聊天室,社群網站的推薦按鈕也被加入了 為了解決聊天室名稱會被別人冒用的問題,如果直接顯示出使用者的IP會有隱私權和安全性的問題,而且也不好看,所以我就將使用者IP拿去做hash來產生顏色,如此一來不同的IP有不同的顏色,要冒充別人就比較困難,除此之外旁邊醜醜的按鈕也用CSS3弄好看了一些 播放器 因為Google reader的那種player是設計給一般的音訊檔案用的,然而Now.in的是串流,時間軸是沒有用的,為了有較好用的介面,這時加入了自己寫的Flash player 接著增加了電台個性圖編的功能,網頁的排版也進行了重新設計,雖然一樣還是一點美感都沒有 音樂資訊 大家在聽電台時一定會想知道目前播的到底是什麼曲子,所以即時更新曲目的功能就在2010年6月左右被實作了出來,這其實也是一開始就有想好要做的,而播放器的版本跟現今的已經差不了多少了 Mr.DJ2.0 為了支援傳送音樂曲目到伺服器,Mr.DJ也做了一些修改,同時也在這時來到了2.0版本,整個UI算是重新設計過,基本上的想法是播音樂和電台的功能想拆開來,原先的設計不管怎樣加東西進去都很難排版 網頁重寫 因為舊的網頁程式已經有點雜亂,加上對於TurboGears的一些毛病有些反感,同時也想試試新的網頁框架Pyramid,並好好寫自動化測試,除此之外也找人設計了logo,因此順手就將整個網頁重寫,網頁的設計上一開始還試了不同的樣式,但這最後沒有公開 但是最後還是重新設計過一次,就成了今天看到的這個版本 中間還經過了無數次細節修改,不同瀏覽器看起來的效果調整等等 Android和iPhone app 在手機上也能收聽這樣的功能一直也都是在一開始就有想好的,然而要扛起所有的開發我已經是分身乏術了,感謝兩位同學的幫忙,分別負責了iPhone和Android的app,從此之後在手機上也能收聽電台 積沙成塔 回顧舊的程式才發現原來已經經過了這麼多的改版,事實這些看得到的改進都還只是冰山一角而已,因為有些改進太小就沒有一一介紹,要跑老舊的程式實在太痛苦了,還有另外一大部份都是看不到的改進,那些才是最重要的,改進伺服器的穩定,改進整個系統的承載能力,改進聊天室的承載能力等等,這些都是無數的微小細累積起來的,惡魔都在細節裡,這也是為什麼這個行業沒有熱情是做不起來的,沒有熱情就只會想應付了事,東西能運作就不再改善,剩的就只有等產品死亡,不再有人使用 在看這些舊程式的過程中我心中有些疑問,開發過程中我到底送了多少個commit? 到底寫了多少行? 有空的話或許可以分析一下另外寫一篇文章也說不定 展望 雖然走到今天這個地步已經是很不容易,但事實上我們離目標還有很遠的一段距離,還有成堆如山的改進在前面等著我們去實行,但不管怎樣,感謝各位在過去兩年來對於Now.in的支持,今後也會更加努力向前邁進
我有一個夢想
我很幸運,出生在網路快速成長的年代,感謝網路的發明,我從國一就有機會開始學習寫程式,在這些年裡,心底一直都有一個疑問,我相信很多人都跟我一樣有同樣的疑問 「為什麼台灣沒有軟體服務產業?」 我們從新聞看見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
那些在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
Mr.DJ 2.0.3 Mac OS X版發佈
Mr.DJ 2.0.3 Mac OS X版正式發佈 截圖 下載頁面
Ajax/Comet實作聊天室心得
今天為now.in做了一個最陽春版本的聊天室 這聊天室用了AJAX/Comet技術,說穿了AJAX/Comet真的沒什麼,其實不過就一個http request在server端在接受到後,直到有事件發生才回傳,也有另一種做法是利用比較特別的header讓browser對於每次收到的資料分批處理,而這些都在一個response中完成,因為似乎後者還得有browser的支援,所以我用的是前者,而雖然概念上很簡單,但實際做起來會有些細節得注意的 前端不可以有proxy 原本我寫好後放上去結果不能跑,發現原因出在於透過WebFaction前端的Apache再rewrite到我的server,似乎在前端的連線數很快就被擠暴了,因為線上會有數百個連線一直在線上,所以如果前端有proxy,很容易就會被塞暴,後來改用直接連線,問題就解決了 一般的伺服器架構其實根本不適合Ajax/Comet 事實上一般常見的伺服器架構大多都不適合寫Ajax/Comet,為什麼呢? 原因很簡單,大多的伺服器架構都是thread pool之類的做法,一個連線進來,就從thread pool中拿一個worker丟給他去做,在完成之前都屬於在處理的階段,因此你有同時100個連線被Ajax/Comet卡住,就佔掉了thread pool中100個worker,這些worker什麼都不能做,通常只能sleep,定期檢查事件發生了沒,除了伺服器很快就會被塞暴以外,一點效率都沒有,像是Apache就是這類的架構 解決的方案: 非同步的IO 解決方案其實很簡單,就是改用非同步IO的網路框架,我個人最熟的就是Twisted,自然就是選擇這個,身為愛好Python的程式設計師,其實很多時候苦腦的不是沒有選擇,而是選擇太多,Python的非同步網路函式庫不是用一打就能數完的,多到誇張的一個地步,而且一直在增加,不久前又多出了一個Tornado,這也只是冰山一角,有人寫了一篇文章專門是在比較Python非同步網路函式庫的 Asynchronous Servers in Python 當然,這文章裡列出的也只是一部份而已 Twisted的Ajax/Comet做法 class Chatroom(resource.Resource): isLeaf = True def wait(self, request): """Wait for notifications """ self.waitingRequests.append(request) log.debug(’[%s] %d users are waiting’, self.name, … Continue reading