MySQL 劣即是夯

MySQL transactional lock 在 throughout 上 遠遠不及實作 mvcc 的 PostgrSQL,但在使用上,卻是大大的勝過 pg

原因是因為,在 pg 在寫程式裡,要處理很多因為碰撞產生的 rollback ,即使 db 會幫你處理,但是如果有外部系統呢?是要去招回還是要用 2 phase commit 呢?還有在 UI 上是要讓使用者馬上再試一次,還是請他五分鐘後再試一次了?

所以最簡單的實作就是乾脆把整個 table 鎖住,一次一個人寫入,這樣就不用做例外處理了。

科科科 劣即是夯

重回美國心得 – 金融業

離開美國五年再回來,金融業變化還真大啊。

GE Capital 的零售銀行被分割出來,變成 Synchrony Bank , GE 要把主力放在投資銀行的事業上。

Intuit 要把 30 年前開發,到目前都還是業界獨佔的 Quicken 賣掉,不再繼續開發,要把主力放在中小企業用的 Quickbook 跟 SaaS 的 Mint.com 上面。

FinTech 開了許多家,Personal Capital, Betterment WealthFront, Acorns ,雖然說整體的產品仍是比不上直接買 Vanguard Target Retirement Fund 的投資報酬率高,但是方便及充滿資訊的 UI ,讓許多年輕一代逃過收取 2% 手續費的傳統理專的魔掌。

兩年前就有聽過這些東西,不過直到回到美國,把自己的帳戶再調整一下,才發現變化還真大。

智慧電表

美國的電力公司真誇張,五年內進化到了讓使用者知道每小時的用電量,然後已經可以按照不同時段來收電費。

pg&e

反觀台灣,台電領了經濟部一堆補助,說是要在 2015 年完成安裝智慧電表到百萬戶,結果只有安裝一萬戶,然後就用成本不符不繼續執行計劃,反正國營企業,全民買單就好

http://news.ltn.com.tw/news/focus/paper/880231

關帳戶

啊,我的修養還是不夠,沒想到在台灣關個銀行戶頭,都要叫經理出來,還不能解決 Orz….

我有一間自己的公司,因為要長期出國,要把公司跟公司戶關掉,打去銀行問要帶什麼文件。

結果今天去,才跟我說缺公司登記文件。

回家,下午再來,又跟我說,要關甲存要連未用完的支票都帶來。

然後我就爆氣了,要行員幫我寫一樣樣下,到底關帳號要那些文件才可以關….

然後又被台灣的金融制度上了一堂課,原來關甲存帳戶,過去未用完的支票全部都要帶來,要不然一張要罰 240元跟簽切結書。


話說我三年前,人在台灣,還透過 email & skype out 開了 Wells Fargo 的戶頭,後來要關時,也是兩封 email 就關掉了,不用負責人親自到、不用把 debit card 寄回去、不用把支票簿寄回去


我可以理解,為什麼中華民國會要求支票要還回去,因為過去台灣芭樂票盛行,而中華民國又是個 nanny state ,什麼事都要政府負責,所以連個支付工具都要上層層的鎖。

在美國,個人支票就是沒什麼保障,要保障,請去買銀行本票 cashier check 。我當年要賣車時,就是跟買主約在銀行裡面,請他當場買 cashier check 給我,我再存進戶頭,而他把車子跟車籍資料帶走,當下就結清交易。

至於為什麼要用 cashier check 還有一個原因,因為在美國支票存進戶頭,帳戶上暫時會顯示這一筆進帳,但是還是要三到五天才能結清,所以既使存進去還是可能會跳票。

而當下結清,是商業運作上很重要的,因為當下就可以把風險減到零。反而在台灣,沒有這種安全、有紀錄、一手交錢一手交貨的運作的機制。

在台灣買車、買結婚戒指,還是要先到銀行轉帳給賣主的個人戶頭,才能領貨。非常沒保障。


最後,講到影響最大的,其實是台灣商業跟生活的雙軌制太嚴重。

我在美國只有生活七年,個人的金融交易方式,就是公司的金融交易方式,並沒有什麼太大的差易,都可以用經驗、常理判斷。

而在台灣,我是一個商學院畢業的學生,我自認對台灣社會運行的方式在同儕間算是不錯的了,念過會計,幫忙 “手工” 過帳過,上週才把我的公司法、商事法課本給丟掉,但是在過去幾年間,被台灣的會計及金融制度還是撞上許多的問題。

無法把生活經驗推演到商業上的運作,我想是台灣在培養商業人材上,很大的問題。

遺失停車代幣的解決方案

停車把代幣給搞丟,結果意外的上了兩課。

原來停車場收費機,往四個角點兩下,可以叫出隱藏的控制面板,輸入密碼後,繳當日最高停車費及罰金後,會掉一個不一樣顏色的代幣出來,可以讓你直接出場。

第二課是,我拿到的代幣壞了(運氣真好),停車場管理員,雖然下班了,還是可以透過手機,直接看監視器跟操作停車桿,直接放我出場。

這次我運氣不錯,兩年前,代幣被嘟嘟房的機器吃掉,繳完錢不退我代幣,打過去是 0800 中心接的,一點忙都幫不上,還好機器過了五分鐘後,良心發現,退給我。

不知道這系統是誰做的,把例外處理做的這麼好,前前後後才擔誤我十分鐘,我還以為要等收費員從家裡趕來,還是說隔天早上才能取車。

Type Inference 在實務上碰上的問題

最近在讀 Implementing Domain-Driven Design 這本書,學習一下別人
是怎麼整理好整個大型軟的架構,並且重新檢視一下我們公司的程式碼的問題。

在 DDD 的概念中,一個模組 Domain / Bounded Context 應該是一個獨立的觀念,一個大型程式,應該是由許多 Bounded Context 組合而成,整個程式的架構應該僅量保持這些的純淨性,Bounded Context 的互用,要把上下行的關係定義清楚,程式碼間不應該在一個區塊中引入多個 Bounded Context

在整實作上,如何合檢視一個 class 是否有妥善的處理引用入的 Domain ,最簡單也最好用的方式就是看檔頭 import 的地方

import com.codahale.metrics.Meter

import org.apache.commons.lang.StringUtils
import org.jboss.netty.handler.timeout.TimeoutException
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yunglinho.common.JsonSerializer

import com.yunglinho.app.core.model.Location
import com.yunglinho.app.feature.SocialProfile
import com.yunglinho.app.service.LocationService

import scala.concurrent.Await
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.concurrent.duration._

過去我排 import 的慣用法是按 有授權疑慮 的順序去排

  • com.* 的在最上面
  • org, net 排第二
  • 接著是排自己公司的東西,按 common, base, app 的順序去排,common 跟 based 是放 utilities & framework , app 就是放一個專案的東西了
  • 最後scala & java 的東西

這樣排的好處是, code review 一眼看過去,就可以知道用了那些版權有疑慮的東西,而且 import 時,不會把 java & scala 內建的東西蓋過去,同時也知道這支程式碼用了多少其它的東西

然而,這個機制,在 Scala’s Type Inference 的影響下,變的很不可靠。

Type Inference 是初學 Scala 時,覺得很方便的一個功能,能夠在寫程式時,少打很多的字,例如:

   // 在沒有 Type Inference 下, statement 的左右兩邊都要宣告型態
   val location: Location = new Location("Taipei")

   // 左邊的這邊其實是可以省下的
   val location = new Location("Taipei")

   // 左右兩邊都沒有 *Location* 的存在,但是卻是被引入在這邊了 
   val location = locationService.lookup("Taipei")

這看似方便的功能,卻有著非常深遠且負面的影響,在上面的例子中 Location 這類別,雖然在 import 時沒有出現過,但是卻是在 Reviewer 意料之外中,被帶入到了這程式碼中。

當然,在上面的例子中,Location & LocationService 是一套的觀念,所以沒有真的引入意料之外的 Domain 進來,但是如果今天程式碼寫的不好,是有個 ApplicationContextHolder.getCalendarService 的話,那就不一樣了。

在一行行 code review 時,有可能會抓到這問題,但是如果你沒有空一行行的看呢?或者是你是在 refactor 數千行程式碼時,那要怎樣一行行的去看呢?

所以,設計程式語言真的是很困難,一個看似方便的功能,卻在意料之外的地方造成困擾,讓我最近有點想回去改用 Java 。當然 Scala 還是個很好的語言,能夠幫我增加兩三倍的生產力,不過,卻會讓團隊工作時造成困擾。

Metrics

歡迎各位來到首屆的 Java Community Conference ,我是何永琳,目前於飛向科技擔任工頭,所謂的工頭,就是做
大家做的事跟做大家不喜歡做的事,什麼是大家不喜歡做的事呢?那就是管上線機器的大大小小問題。

在我們開始之前,先岔題一下,大家都是工程師,(放someone on the internet is wrong)應該都有些大大小小的睡
眠問題,過去我一直以為我一天有睡到七小時,一直到去年穿戴式配備的興起,我買了個 Jawbone 來戴(放 Jawbone Up的圖片),
才知道我一天只睡六小時左右,中間的睡眠品質不佳。有了 Jawbone Up 天天計錄我的生活起居狀況,我才了解到自己真
正的狀況,才能著手改善問題。

上面的故事,就是今天講題的主軸 測量 / metrics

在軟體開發的過程中,程式的編寫,其實只在軟體生命週期的很小一塊,在經過數個禮拜至數週的開發及測試後,軟體就
被佈屬到線上環境中,在過去,可能是放在公司的機房中或是資料中心,現在則是被放到雲端平台之上,總之,你細心開
發的軟體,將要被真實世界開始摧殘。

在一個軟體的生命週期中,他可能會碰上大量的用戶擁入,也可能跑了數十天沒有重開,也有可能在臨晨三點碰上資料庫
備份,當然也有可能每兩個禮拜碰上其它整個的 REST API 不穩的狀況,在他跑了一兩年後,有可能被換到新的硬體上。

問題在於,你有沒有辦法知道這些狀況會不會出現,如果出現了,你能不能知道發生了什麼事;而且在這些狀況下,你的
應用程式會出什麼怪手?是全面性的慢下來、還是不可預期的某些 Thread 才慢些來,或者是,你的應用程式可以輕鬆
應付這些狀況,不用你擔心。

如果上線的系統不能應付這些狀況,你要做出什麼相對應的調整呢??

Metrics By Codahale

Metrics 一套是由 Codahale 在 2011 公布出來的 Opensource 專案,自此之後,因為他的 API 設計精良又容
易跟其它的外部程式整合,所以開始被業界所採用。

http://codahale.com/codeconf-2011-04-09-metrics-metrics-everywhere.pdf

為什麼我們需要測量的原因

手動調整

Iterative tuning -> 建立假設 -> 重建問題 -> 提出對應 -> 修理 -> 驗證

談台灣年輕人低薪問題

台灣這幾年商界、政界、很喜歡對年輕人指指點點,說只要努力就可以脫離 22K ,年輕人收入不好的問題根源是在年輕人上,所以在這邊寫一下我的看法。

我在美國念書畢業一年後,在 26 歲時,底薪收入就有八萬美金,後來我又幹了四年,回台灣又幹了四年,但我的收入連八年前的一半都沒有,所以說,是我能力退步了嗎?不對啊,我現在寫程式碼比以前快不知道多少倍,還帶一個團隊,怎麼可以說我退步了呢?

一個人所能領的薪水,是相對於他所能創造的產值,而一個人能創造的產值,則是基於他所在的團隊以及社會之上,我過去還是一兩年經驗的新人能領高薪,是因為我所處在的團隊、社會可以創造高價值,因此我所做的邊邊角角的工作,依附在團隊上仍是有價值的,公司就我當下及未來可能的貢獻,給我高的報酬。

所以說穿了,年輕人能領的薪水,很大的決定因素是在於這個社會能夠如何運用他們,這個社會的掌權者、這個社會的中監份子,能為年輕人創造怎樣的舞台,如果掌權者創造的社會有價值,能夠利用年輕人創造更多的價值,那麼年輕人自然能夠領高薪。

如過這個社會的掌權者,只在乎金錢遊戲,忽視產業,那麼年輕人沒有舞台,自然只能領低薪

TDD

總算是把 TDD 的戰文看完了,看完後我對 DHH 的評估仍是沒變。

DHH 在 Rework 中自述到,他偏好帶領一個三十人的團隊自在的工作,而不要把組織擴大到上百上千人把自己搞的焦頭濫額。 DHH 在組織架構跟應用範圍的偏好偏食,讓我在讀 DHH 文章時都會先考慮過他的出發點跟局限性。

以程式設計師的角色來說, DHH 的精兵政策當然看起來很爽,我自己也做過類似的選擇,捨棄 Java 而就 Scala ,追求更高的個人產值。

然而若是以一個架構師的角度來說,我的目標是成為像 Martin Fowler 的角色,相較於只有 36 個員工的 37 signals ,ThoughtWorks 是個有超過 2500 個員工的專業代工廠,在 ThoughtWorks 掛頭牌的 Martin Fowler 在技術的選用上,自然的考量要更全面,顧慮到不同應用領域的開發需求、以及不同程度的程式設計師該怎麼管理。

DHH 對 TDD 的批評我多數同意,尤其是 Testing / DI 對 Design 的入侵也是一直困擾我的問題,但是我是把 Testing 當成一個需求來看,所以是多一個需求造成的額外成本在困擾我,而不是降低可讀性等問題在困擾我。
在目前看不到較好的替代品之前,我還是會繼續用 TDD (w/o test first) 來做設計上的工法。

我目前對程式的想法是從資料做起,我做的系統,多數就是把輸入的資料,透過一串串的轉換,Map, Filter, Count, Sum, Aggregation 後,變成最後要的樣子,在A -> B -> C -> D 中間,可能會有一些中介型態的出現。

在我的設計中就會變成,在每一次的轉換的過程中,讓輸入輸出是可以被測試的,在設計階段就預先考量到要怎麼測試這些轉換。

至於會不會做 Unit Test, Test First, 我是看有多少時間做多少事的,但至少模組內的一串流程的測試是會去做的。

另外我會把 DAO & Data Transformer(Service) 分開來,資料轉換的運算,是可以不用靠 DB 來的資料直接做測試,這樣跑起來才會快。

許多的商業邏輯,我會在 DAO -> Service 上再多架一層 Controller ,這個 Controller 就會很醜,因為只有三(四)層,所以一個 Controller 可能換串個十來個 Service ,但是醜的就是在這裡面而以。

測試的時候,至少是可以分層把底層容易測的都測好是穩定不容易出錯的,到時後上線有問題時,就可以知道是在 Controller 把東西串起來時出錯了。

沒有 Test First 沒有 Unit Test ,但是會做 regression test, integration test 會在設計時預先留下容易稽核的點。這是不是 TDD??

原點科技介紹既2011年終回顧

原點科技成立於2010年十月,在過去的一年多間,本公司就為Location Based Service & Mobile開發及學習了許多技術。

Json WebService API with Jersey

身為SaaS的提供者,我們需要提供許多不同的WebService API給我們的客戶,在轉換內部的Java Object到外部的Json Object,我們選用的是Jersey這套 JAX-RS 標準的實作,以及Jackson這套 Json library。

這部份的成果,我們曾在2010年11月於 TWJUG 發表過,相關的投影片請見,另外關於Jackson的使用,我們也發表了幾篇部落格文章講解,怎麼在Scala上使用Jackson怎麼樣處理多型使用Jackson的小眉角,以及怎麼在Android上使用Jackson

對於 Jersey & Jackson 這一套 Json WebService framework,我們使用的經驗是很滿意,也大量的使用在我們的內外部系統間。

Search with Lucene

在 Lucene 之上,我們建立了一套,不同於Solr的 WebService 實作,透過我們自有的Search API,能夠對我們的Json文件庫做全文檢索及條件比對,並且可做翻頁、及選取部份欄位等運算。

Location Based(Spatial) Search

當我們開始做 LBS 時,一開始我們是始用 lucene-spatial 這套官方的函式庫來做 LBS ,但是,很快的,我們就了解到,用 Map Tile 來做 LBS 的問題,Map Tile的做法是,把地圖割成不同大小的區塊然後編號,然後,把這區塊內所有的座標,都標上一樣的 tag 值,例如 t16m2345 – t(tile_size)m(tile_id)。那麼,在做搜尋時,我們只要把現在的座標位址的tile id算出來,在去找有相同tile id的點就好。

這種做法的問題是,找出來的點,並沒有依距離排序;當 Lucene 對選出來的文件做 scoring 時,因為同一個區塊內的點都具有一樣的tile_id,所以,他們的分數都是一樣的,並不會依距離的不同,而有不同的分數。

另外,我們也發現,多數的搜尋技術,在處理地理位址時,只處理地點的資料,例如餐廳、百貨公司等小地理區塊等,但是這些地點搜詢技術,並不適合用在處理大區塊範圍的資料,如行政區及學區等。

如多數外國網站用的坐標轉行政區的GeoNames,他在搜尋某個座標目前所屬的行政區時,是計算座標點與附近行政區中心的距離來猜測,但是行政區往往不是正圓型的,行政區的劃分多是依自然環境(如河川)來切割的,所以,既始某個座標離行政區甲較近,但是,在實務上則是被劃分到乙行政區去的;類似的例子還有學區等

另一類無法用點去描述的,是線型的資料,如登山步道、腳踏車道,當我們登山時,我們不一定要從起點開始爬,而是可以從中間點開始加入,因此,當我們在找附近所有的登山步道時,該是計算所有線型資料與目前座標點的最短距離,而非是算起點與目前座標點的距離。

因此,就這兩個問題,我們實作了對地理區塊搜尋的功能,讓用戶能對點(Point)、線(LineString),多邊型(Polygon)等資料,做搜尋,並對尋結果依距離來排序。

就這功能,我們發表了搜詢座標所在行政區台北水災地圖

Search Analytics

講到搜尋,當然也不得不提用戶行為分析(Analytics),我們在我們的Search API中,內建了記錄使用者行為的功能,當一個使用者,打開程式送出第一個搜尋、翻到第二頁、點選了第三個連結、再做另一個搜尋、選了第一個結果、離開,這一整串的行為,都會被我們的後端自動記錄下來。

透過我們自己開發的 Mobile Analytics 技術,我們可以就這些使用者行為,提供底下的分析報告

  • Client Profiles
    • number of clients by device family
    • number of clients by device.
    • number of active clients by device family.
    • number of active clients by hour/day/week/month
    • the location of clients.
    • the location of active clients by hour/day/week/month.
    • average usage frequency(how often clients use your app per week)
  • Visit Trends
    • number of request of the hour/day/week/month
    • unique visits of the hour/day/week/month
    • average length of visits.
    • new vs return clients on the hour/day/week/month.
  • Search Usage
    • top search keywords of the hour/day/week/month.
    • top search keywords by location/country
    • the location of search usage of the hour/day/week
    • average search usage per visit.
    • top-exit search.
  • Content Usage:
    • popular contents.
    • popular result document ids.
    • top-exit result.

大量運算

在過去的一年多間,我們花了很多的心力在學習雲端相關技術,評估什麼技術適合我們,什麼不適合我們,像在做Analytics時,我們選用了MySQL而不是熱門的Hadoop

因為我們有群組軟體的需求,需要知道,在Cluster中,那幾台機器是負責處理 Domain X 的資料;我們嘗試了使用 jgroups 及 zookeper 來實作 service registry/discovery 的功能,這經驗,也在CloudTW發表過,投影片在此

為了在我們的 indexing 中使用 Producer and Consumer Pattern & durable message box,我們也投入了許多時間去學習Akka, Actor Model, Amazon SQS, ActiveMQ, Apache Camel,Akka的成果,我們也在 COSCUP 發表過Video on YouTube

社群服務

在我們專注於軟體開發的同時,原點科技也不忘回饋社會及社群,原點科技的創辦人加入多個社群,並多次主講議題,包括

  • TWJUG: Introduction to Tapestry
  • CloudTW: Groupware – JGroups and Zookeeper.
  • Coscup: Introduction to Actor Model and Akka
  • OpenData: 系列講座 #2 – 第一次爬資料就上手?! 碰壁!

在今年底,原點科技將協助Scala Taipei的運作

關於未來

在下一個年度,我們將會把心力放在推廣我們的產品Search Cloud之上,通過參展與競賽,增加我們的媒體知名度。另外一方面,我們也會開始接一些關於LBS, Analytics, Distributed System的外包案。

此外,我們也會把一部份的心力,放置在推廣 Scala 及 Akka 的企業應用,透過教育訓練、外包專案、雜誌文章及研討會的方式,讓台灣的軟體界對這兩者有更多的了解