人與 web service 語言不通,只好透過大量的 log,大量的 monitor 來判斷他的健康、他在忙碌什麼、他需要什麼處置。

即使只是簡單的 tail -f,也能提供許多資訊。為何 log 在這時卡了一下?為何 log 奔馳的速度沒有預期的快?看久了,每一個小細節都可能是發現新的狀況的契機。



On Driving Technical Changes in Your Team

Here are some tips when you want to introduce new technology, language, or tool to your team:

Solve a Real Pain Point

Don’t just introduce something new to the stack solely because “it looks cool”.

Start with a concrete demonstration, a strong pitch.

Maybe it will increase the throughput of your web service by 10x. Or it can greatly simplify the tedious deploy process everyone’s complaining about.

It’s easier to sell when the customer already saw the benefit.

Start Humble

A better configuration DSL is a “safer” change than a complete rewrite of core algorithm.

It’s important to manage the fear. If people fear about the change, you won’t achieve anything. Make them fell in charge.

Start small. Don’t change everything in one step.

Encapsulation is the key. Wrap the change into things people familiar with: a C-like DSL, a well-known format like JSON.

Make sure the change is revertible. When technical change failed, it’s still a succeeded refactoring.

Provide Easy-to-use Instruction or Workflow

Make the process as seamlessly as possible. You want to solve problem, not introduce new work.

Think youself as a teacher. You need to make sure the material does not contains any basic mistake. Beginners should be able to follow it without any issue.

Learning new technology might be fun, but debugging misleading document is definite not.

Manage Tempo

After you introduced a change, give the team some time to cool down.

Try to find the correct tempo of your team to work with changes. Too fast, people feel fatigue, too slow, people feel bored.









How to write maintainable software without testing and documentation

Programming is about writing down your knowledge of a complex system in a form which computer can understand. The more the computer knows, the less you need to memorize. We write our knowledge down in different programming language because the system, the knowledge, and our taste are different.

However, programming languages have different level of expressiveness. In JavaScript, we can’t write down the type of a parameter in the function definition. We have to express them in the form of unit testing, documentation, and naming convention. In C, we can’t determine whether a function have side-effects or not without looking into the implementation.

The formula of programming complexity

Here is the formula of programming complexity:

C = P + U

where C is the total complexity we need to achieve to solve the programming task. P is the complexity we can express in the form of code. U is the complexity we have to address in the form of non-code, such as documentation and unit testing.

The more complexity we can address in P, the less U we need.

In other words, if we program in a language can express all kinds of details such as “Is this function pure?", “Does this method mutate the object itself?", “What kind of parameters does the function need?", “Is the function thread-safe?" without looking into the implementation. We can avoid a lots of tedious paper works.

The document will never out-of-date if there’s no need of document.

So, how do we write maintainable software without unit test and documentation?

Choose your programming language wisely

The programming language you choose decided the maximum of P. If the maximum of P is higher than C, you might not need U at all. If your programming language can’t produce a P large enough. You need a huge amount of U to satisfy your C.

Or, choose your problem wisely

The C part of the formula is decided by the task programmer need to do. If we can achieve business requirement with a task with small enough C, we can solve the task with little codes and no document. And we still have a maintainable software because it’s so simple that anyone can understand it in hours, not months.

調整 OSX Yosemite 的 ulimit

OSX 每次改版,改 ulimit 的方式都會改一次… 以前是 launchd.conf、sysctl 想不到到了 Yosemite ,要改 ulimit 竟然要寫 plist… 而且這方法還是在 Riak 文件找到的。Open Files Limit。要改的有兩個檔案:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
        <true />
        <false />


Operational Transformation 在 JavaScript 上的實作

最近因緣際會下接觸到 Operational Transformation 這東西… OT 是 Google Wave、Hackpad、Etherpad 等等即時協作工具背後的基礎。Wikipedia 的說明依然是有些抽象,想了解一些基本觀念的話,這篇會是不錯的起點。

根據前 Google Wave 工程師的說法:實作 OT 並不是一件容易的事情。當初他們花了兩年寫出 Google Wave,如果搬到今天,可能也還是需要兩年。幸好,已經有一些現成的 OT 實作可以參考:



ShareJS 就是前面那位前 Google Wave 工程師的作品。相較於其他函式庫,ShareJS 走的是全端全包的路線。從跟前端編輯器的整合各式 OT 演算法的定義與實作、直接就可使用的整套同步系統、甚至還有自己自製的 Database Frontend

不過,寫這篇文章的時候,ShareJS 正在進行 0.7 版的改版,文件跟程式碼有些混亂,不太容易理解…



ot.js 是另一套 OT 在 js 上的實作,包含 OT type 與基本的 server/client 的實作。跟 ShareJS 比起來較單純,也比較好懂。缺點是文件很少,範例似乎也有些 bug。

btw, firepad 是基於這套做出來的。



我目前使用的是這套實作,它只實作了針對文字的 OT ,並不包含 server/client 等等其他元件。不過,他的文件應該是最清楚的,也支援從 diff 建立 OT 。


我想 OT 在這幾年應該會有不少有趣的應用?反正現在玩玩也不吃虧 :P


用 vim 開發 Unity3d (C#)



感謝 YouCompleteMe 這個超神 vim plugin,終於可以不用忍受 monodevelop 的龜速,改用 vim 啦。設定步驟如下:

  1. 用你喜歡的 vim plugin 安裝方式安裝 YouCompleteMe
  2. 至 YouCompleteMe 安裝目錄下執行 ./install.sh –omnisharp-completer
  3. 將你的 Unity3d Project 目錄底下的 PROJECT_NAME.sln 刪除,只留下 PROJECT_NAME-csharp.sln
  4. 完成!


  • 剛開啟 vim 後的第一次補完會失敗,第二次才會開始運作。