2014年7月23日 星期三

[]byte 轉型 string 必須注意 []byte 的長度

常常需要從 []byte 轉換到 string,來使用 string 的功能。
但是必須注意的是 []byte 並不一定是以 0x00 結束,如果就直接轉型到string,而直接使用strings的一些函式。“有時”就會造成不可預期的結果。像是我要從socket讀取資料,先建立了一個BUF_SIZE的[]byte array,這個大小是2M Bytes。

read_buf := make([]byte, BUF_SIZE)
byte_count, err := conn.Read(read_buf)
log.Println("Receive ", byte_count, " bytes\n", string(read_buf))

跑到Println的時候,發現而且ssh連線幾乎沒有反應。找了又找,後來發現到是Println花很久的時間。我才意會到,原來golang還是要處理結束字元。所以[]byte轉換string的時候,必須要知道byte的長度。因此Println改成下面代碼就解決了問題

log.Println("Receive ", byte_count, " bytes\n", string(read_buf[:byte_count]))

2014年7月6日 星期日

駭埕市



         第一次參加hackthon的我,懷著赤子之心去參加了這個駭埕市的活動。從題目的挑選、組隊、討論、田野調查、轉換題目,一直到最後面得到了第一名。這2天的活動就好像是自己開了一間公司的過程,一個隊伍(公司)最後能否獲得評審(客群)的青睞,其實從題目(產品)定位就決定了這間隊伍是站在哪一個位階。

         位階並不代表失敗與否,而是隊員們、員工們需要付出的勞力程度,大家要多拚才能達到一樣的獲利水平。我們這一隊"呱"花了非常多的時間在決定題目,大約3個小時的田野調查來打翻我們在冷氣房裡的決策。我們一直環繞著 Target Audience(TA) 的需求:
  1. 大稻埕的零售
  2. iBeacon
  3. 需要影片
  4. 需要能運作的App
我很幸運地參加到了4個學生有備而來的隊伍,因此他們的組合基本上已經符合了3,4的需求,剩下的只有題目的選定了。而題目的選定必須要在幾個小時內就能實做出來。

         題目或是產品必須要環繞在解決TA的問題,TA是最後買單的一群人。產品最後能不能獲利,並不是產品有沒有人做過,也不見得是單價過高,而是有沒有找到TA遭遇到的問題。2天的比賽題目就訂在那邊不會變。相較於開公司來說,可怕的是TA可能是會變的!我的意思不是TA本身會變,而是公司裡的人會變。因為技術達不到而變、因為預算燒光而變、因為人力而變。正是這麼多的因素會改變TA,新創公司才這麼有挑戰性....又....或者說是風險性...。

我認為一間新創公司能否抓到最準確的TA,你的員工必須是TA的一部分。






2013年11月10日 星期日

分享治療背痛的有效方法

我做軟體這一行已經6年了,前幾年幾乎就是每天至少10小時的時間都坐在椅子上盯著電腦螢幕。大約在工作3年的時候,發現到自己在做轉體運動的時候,會發出咖咖的關節聲響,然後伴隨著壓迫肺臟發出的聲音。前胸的肋骨也常常不固定位置發出微微的不適感。過了一年後,胸椎的部分開始隱隱作痛,旋轉脖子開始有肌肉拉傷的那種痛感,甚至有一次搬嬰兒車都會瞬間痛到,可能壓迫到神經。於是我就去找了間復健診所(沒健保,每次800),做了有10次,但是也都沒有特殊改善。期間也有去陳潮宗針灸、推拿、喝水藥(4次),還好有實支實付否則真的虧大,因為真的沒用...。3年間主要去看中醫、推拿,也都沒有實際的改善。直到2013上半年,常常在落枕,受不了了就去google了一下,發現有骨科這種診所是可以治療這種傷害(以前天真以為骨科只看骨頭),於是就去了骨科看。醫師照了X光以後說頸椎間隙異常的小,可能有磨損到,於是也說了一些恐怖的後果。後來就安排去拉脖子,第一次拉的時候是9公斤的樣子,拉了很痛,因為那天剛好落枕才去骨科試試看。拉完幾乎無法坐起來,而且手有點麻麻,過了幾分鐘終於慢慢的坐起來。隨後就這樣做了好幾輪的拉脖子,隨著次數增加,來到了十多公斤,漸漸的那些背痛的症狀與落枕狀況都沒有發生了,我認定這就是治療我的背痛方法了!這簡直就是看到耶穌一樣有重生的感覺啊!因為很多報導都說背痛是跟心臟有關,或是影響到心臟導致心臟病,也有看過新聞報導曾經有一個人心臟病猝死,當時就貼著一個貼布在背後。現在已經拉到16公斤,一開始還是有點痛,不過做了中後段就不痛了,常常會睡著。所以我希望這個經驗也能夠讓跟我一樣是坐辦公室坐到背痛的人有一個方式可以去治療看看,不是說中醫無效,而是骨科也有類似的療程可以試試看。

2013年11月8日 星期五

關於效能改進,memory copy不是第一個要考量的

常常聽到有人說為了速度,要避免memory copy。但我在無論是維護性與效能上的考量,都覺得不是這麼回事。不要去追求pointer上的巧妙操作達到的zero copy,而忽略了平行處理上的可讀性。zero copy要作的地方是user與kernal space間的copy,而非同user space內的copy。後者幾乎是可以放在最後才去考量的。因此,我在評估系統設計對效能的衝擊有下面順序:
1. 減少 context switch:少用process,thread,少呼叫system call。使用 libev 這樣 event driven backend 來達到多工。而多處理器則使用 thread pool 的方式。
2. 增加 cache hit rate:在可攜的原始碼的原則下,採用那種記憶體也決定了cache的效率:
    1. 優先使用 function 內部定義的空間,因為它是位於 stack,只要function return,SP 暫存器一減回去,就相當於被釋放了,是極為有效率的。

    2. 如果要跨 function,就要訂好一個結構或是陣列,定義在 globol 的記憶體,因為它會位於固定的 .DATA 區段,當很密集在上面操作時,就很容易將資料保留在cache中。

    3. 最後才考慮使用 malloc 系列函式,取得的空間會位於 heap 裡面。常常有一些作法是使用動態配置去配出一塊塊的記憶體,然後用 pointer 將它們連起來成為某一種資料結構。下面文章就是在講這種方式的問題在哪裡。
http://www.codeproject.com/Articles/340797/Number-crunching-Why-you-should-never-ever-EVER-us#TOC_DA_IV

使用heap取得的記憶體會東一塊西一塊,一下在這個 page 一下在另一個,就比較不容易 cache hit。反觀如果配置靜態記憶體加上event driven,將資料與運算集中起來一次在user space處理掉,就會很有效率。

如果資料結構真的很龐大、所指向的資料又不一定大小,該如何靜態?
這時候,一樣可以設計一個 warm cache 與 cold cache。將你的資料結構的"節點"放在靜態的array,並且用你最擅長的point連結他們,這是warm cache,因此走訪節點的時候就很容易在cache就搞定。當你找到節點後,再取出point指向的資料,這就是cold cache。


當你都檢視了用了多少 process、thread,IPC的資料傳輸有多少,資料結構是否容易cache hit。這些問題都已經釐清以後,再去探討資料搬移造成了多少負荷才能真的增加速度。


2012年11月28日 星期三

install stlinux on ubuntu 12.04

I would like to hack into a 網樂通 to run an awesome daemon.
There are lots of problem when installed stlinux2.3. Even though this is a tough work, I finally installed it. The main problem I encounter is that the rpmkeys does not support --force-debian option. The solution is to edit the install file.

1. Open the install file with an edit you favorite.
2. search force-debian.
3. you will find rpm_extra_opts="--force-debian".
4. just comment it !



2012年10月17日 星期三

UDP hold punching in a nutshell(UDP打洞)

當你使用TCP or UDP連線,假設要從PeerA已知道PeerB的IP,並且嘗試著連到PeerB,若是你沒手動設定port fordwarding,這次連線一定會失敗。但 PeerA 的 NAT 會把這個連線的IP與Port給記錄下來,這筆紀錄就可當作自動的 Port forwarding。PeerB若能夠知道這筆紀錄的Port,就能夠利用這個連到PeerA,因此雙方就能夠P2P傳輸了。

但要如何讓 PeerB 知道 PeerA 連過來但失敗的 IP 與 Port,最一般的做法就是有一個會面伺服器 (Rendezvous Server),可能的流程如下:

1. PeerA 在伺服器上主動地找到 PeerB 的 IP 與 Port ,並嘗試連一次,但一定失敗。不過這次
    PeerA的NAT上已經有個洞了。
2. 伺服器通知 PeerB:PeerA 要跟PeerB 連線,並且把 PeerA 連出的 IP 與 Port 帶給 PeerB。
3.  PeerB 知道 PeerA 上NAT的洞之後,就能連到PeerA了。


使用 UDP 的原因就是 UDP 是不可靠連線,因此 NAT上面會保留這個紀錄一段時間,可能幾秒到幾小時都有可能。這是我目前的認知,在此做個紀錄,但如有錯誤還請不吝指教。