my favorite

2013/01/29

最壞的時代,也是最好的時代



之前看了網路上的一篇文章,故事敘述一位從巨匠開始的軟體人後來出國就業的心路歷程
剛好那陣子偶爾有機會提及我為何選擇出國工作,以及怎麼會有這樣的機會出國工作。
想說也整理一下自己到底在每個階段面臨的選擇,來呼應這位十里坡劍神。
(在巨匠都練成這等高手真是太威啦 xD)

決定成為一位軟體工程師
大學到研究所六年的時間,我從不懷疑自己想要,也需要一份工作。猶豫的只是要選擇哪個領域

從資訊科學系到資訊應用研究所,我是大家所謂的本科生。只是,大學四年的訓練對於程式苦手的我一直都沒辦法享受寫程式的過程與結果,我決定在研究所放手一博。當大家考慮的是選什麼課程可以拿高分的時候,我考慮的是我到底能不能在眾多的科目裡面找到自己的興趣。曾經一個學期選修六門課程,範圍從電機、資訊、教育、光電都有接觸。最後被當掉一科,而大部份的科目成績也只是差強人意。

大量修課顯然對我超過負荷,也沒有真正讓我找到自己的興趣,倒是讓我發現自己不擅長硬體相關領域,同學用 FPGA 板子做出可以整合藍芽加上 WiFi 還有 GPS 的服務,都快做出小叮噹了,而我還在寫小時鐘….

當時也擔任系上網頁開發課程的助教,一門課將近 150 個學生,每星期一個作業,助教安排時間讓學生 demo 打分數。粗估一下,我每星期光是看學生的 demo 加上評分就去了一整天。那時候台北新竹兩地跑,有時候就在回台北的車上看學生作業,有時候主機當掉了又找不到人幫忙我還得從台北坐車回新竹「開機」。雖然這樣的方法很蠢,但是回想起來我竟然也不覺得辛苦,反而有一種樂在其中的感覺(絕對不只是因為可以看漂亮學妹 demo 的關係)。

畢業前後我找了幾家公司投簡歷,過程中也是有一些同學好言相勸,如果想賺錢的話應該去硬體產業,這話擺在當時真是一點也沒錯,成績優秀的學生大部份在畢業前早就被台積電、聯發科這些高科技產業挖走,像我這種成績只過及格門檻的就得辛苦一點自己去找工作。然而,新竹的公司雖然薪水都好一些,但是在幾番考量下決定留在台北,去內科(註1)上班。

態度就是一切
在第一家公司一年多的時間,除了技能有點長進之外,對我影響最大的還是面對壓力時,團體如何協助我成長。

我們當時做得是將桌面版的應用程式改為網頁版,過程中遇到的阻礙不少,網頁技術在當時還沒這麼先進,那時候 Firefox 剛出第二版,IE6 才剛在 Windows Mobile 上出現,更不用提 AJAX 這種現在連阿媽可能都會寫的東西,在當時光講出口自己都覺得好像小當家一樣背後有條龍飛起來。當時的第一版送一個表單要等好幾秒,有時候程式錯了還得重打整張單子,相比穩定的桌面版本,用屁股想就知道沒有人想成為第一批的白老鼠。過程中不僅部門外的使用者不會給好果子吃,部門內也因為壓力常常有意見衝突的時候,而我這個又菜又愛亂搞的頗龜麼(註2) 也常常讓大家很蛋疼,連另一個部門吃齋念佛的經理都曾經對我咆哮過。幸運的是,主管一直對我很有耐心,往往在我沮喪失志的時候適時鼓勵。再加上同事也知道我平常算是一個認真負責的人,犯錯時自己難過都來不及了,根本不用別人另外釘,所以也不會太過苛責。

天賦與興趣
選擇離職是有許多的不得已,主管開出優渥的條件留人,再加上回役只能回去當兵,所以對我來說相當吸引。只是我一直聽聞聯發科的員工四年有一千萬,我想我應該有他們一半強吧,四年一千萬我應該是無緣了,四年五百萬或許可以拼拼看。

於是我回去數饅頭了,八個月後我去趨勢當了 QA。月薪還不錯,而且人才培訓也很實在,主管及整個團隊相處下來也很開心。一年下來我對兩件事情特別有印象。第一件是趨勢 QA 要求不僅得找出問題,還得分析問題的成因,最好還可以提供不同解法的利弊。當時在我的團隊裡有一位比較資深的員工,有一天他看我坐在位置上想破腦袋,後來把我抓到機房帶著我邊解說邊操作一次,然後比著大拇指,再露出喬治克隆尼般的微笑說:你看,問題就出在這裡,這樣你懂了嗎(牙齒發光)。第二件是同一個團隊的 RD 有一天晚上只剩我跟他在加班,他偷偷把我叫到他座位然後給我看他的螢幕,接著說:你看,這就是 Windows 2000 藍白畫面的程式碼,原來只有 640x480,難怪都 blahblah,說完然後一直笑,害得我也趕快跟著笑,免得他知道我聽不懂。從這兩件事我就知道,我在這個領域再怎麼努力也趕不上這一群瘋子,就像廖化即使拿了倚天劍武力加 12 還是會被呂布一招砍下馬,我決定換工作去做我自認擅長的 - 寫網頁

就是要熱血!Yahoo~
加入 Yahoo! 可能是我目前最幸運的決定。我一直以為自己了解怎麼寫網頁,HTML 就是幾個標籤,CSS 調一下樣式,Javascript 除錯永遠都是 alert。進來了才知道,原來所謂的前端工程比我想像地複雜許多,開發像 Yahoo! Search 這種量級的網站真的是有許多不同的思維。因為自己心理清楚技不如人,在這段時間我一直到處參加研討會,OSDC / COSCUP / Ruby Tuesday / GTUG,只要有人願意花時間分享技術,場地費又不會太離譜我幾乎都參加,不僅可以快速吸收一些入門的知識,也可以認識這個產業的高手,像是 ihower / xDite / Richard / ericsk / 阿嗚 還有其它許多大大。有時候主辦單位佛心來著連晚餐都免費,不去還真對不起良心。不必參加研討會的假日就跑去天瓏書局翻書,雖然偶爾才買一本,有時候為了貪便宜還買簡體的。後來老板娘也知道有一個常來這邊翻書的大個兒,就大方送給我會員卡,感念老板娘仗義,從此離不開天瓏。

因為對網頁開發的高度興趣,再加上 Yahoo! 也有心栽培前端工程師,我便有了第一次去美國出差的經驗。正所謂天下武功出少林,天下前端出雅虎,去美國可以認識好多高手真的覺得好爽,有一天晚上跟前幾年就到美國的 Hedger (現 Facebook 工程師) 聊一晚上就好像進入精神時光屋練成二十倍界王拳一樣舒暢!剛好那段時間 Yahoo! 有一年一度的 Frontend Summit (前端高峰會),主要是給內部的員工參加,探索前端開發的現在與未來。索性厚著臉皮去報名當內部的講者。這樣就可以在不花部門預算的情況下再飛美國一趟,也是因為這樣的巧合讓我一腳跨進了美國 Yahoo! 的大門。

走出台灣
那時候同事知道我對美國的職缺有興趣,跟我說有缺人問我要不要試試,履歷當天晚上生出來,再加上之前寫過的程式交出去就硬著頭皮上了。三位同事分三天面試,問完以後我整個人好像快蒸發一樣,那時候想這輩子英文會話可能都沒有那三天講的多,我高中推甄是因為英文被刷掉的,大學英文好不容易賽到高標竟然還是政大的倒數 10% 囧。所以英文一直都是我的罩門之一。老實說我壓根兒不曉得他們有沒有聽懂,但是可以感覺到大大到哪兒都是一樣的,身懷絕技同時也虛懷若谷,對我的菜英文包容度相當高,也讓我留下很好的印象。

從美國回來以後心裡就一直很忐忑,過了兩個星期的一天早上,收到美國主管的信一開始就寫 Sorry..真是晴天屁力呀!仔細看下去才發現是「Sorry,(中譯)過了這麼久才回你,如果你還有興趣加入的話,我們很歡迎你」。喔喔喔 (請自行想像 Tamama 的嘴砲)。就這樣,也真的算巧合,離開第一家公司後的四年算起來還真的是跟當初希望的收入差不多。

最後
這一個真實故事只是想說,只要去試,機會真的很多
不要侷限在台灣,22K 讓很多企業喪失良心,但是並無法封鎖你往外追尋希望的勇氣
尤其是那些還不到三十歲的人,不要想說自己語言不行或是哪裡不行,不行就去學
學不會就問高手,網路上這麼多大大樂意分享,偶爾被罵一下不會怎樣,學到東西就是你的
專注可以讓你快速成長的環境以及能力,三十歲之前的薪水不要太計較
能力跟心態都準備好了,三十歲之後也許賺一年就抵之前五年。
最壞的時代,也是最好的時代,謹獻給所有努力的台灣人,也希望我五年、十年之後再回過頭來看,我還是能夠繼續熱血

註1: 內湖軟體科學園區
註2: 頗龜麼, 我自己對 programmer 的戲稱

2012/04/11

PCHOMEUS 美金轉台幣 USD2TWD

pchomeus 顯示美金看了有點不習慣

把下面的連結拖到書籤列上面,到pchomeus點一下就可以轉成台幣啦

USD 2 TWD

2012/03/19

Formula is the king


Recently I am thinking how to master javascript performance

I noticed several discussions about recursive and iteration. Fibonacci! (yes, super boring recursive examples but it works quite well for lots of students)

I tried to implement it in javascript and run it in V8 engine with node-bench

Model: MBA
CPU: 1.86G C2D
RAM: 2G

formula
Raw:
 > 7153.846153846154
 > 7283.716283716284
 > 7059.94005994006
 > 7017.982017982018
 > 7074.925074925075
Average (mean) 7118.081918081918

iteration
Raw:
 > 1230.7692307692307
 > 1243.7562437562437
 > 1237.7622377622379
 > 794.2057942057942
 > 1237.7622377622379
Average (mean) 1148.851148851149

recursive
Raw:
 > 0.03229348317509526
 > 0.03268080656230596
 > 0.032544667556220916
 > 0.03117401334247771
 > 0.03111581305619516
Average (mean) 0.031961756738458996

Above results doesn't shock me but it does REMIND me that Formula is always a good point to deal with calculation

2012/02/29

[notes] to insert elements via javascript

shorthand
// style element
var d = document,
h = d.getElementsByTagName('head')[0],
s = d.createElement('link');

s.rel = "stylesheet";
s.href = "css-URL";
s.type = "text/css";
h.appendChild(s);
one liner
var d=document,h=d.getElementsByTagName('head')[0],s=d.createElement('link');s.rel="stylesheet";s.href="css- URL";s.type="text/css";h.appendChild(s);

// script element
var d = document,
h = d.getElementsByTagName('head')[0],
s = d.createElement('script');

s.href = "js-URL";

h.appendChild(s);
one liner
var d=document,h=d.getElementsByTagName('head')[0],s=d.createElement('script');s.href="js-URL";h.appendChild(s);

2011/08/09

Readdown: To add .md extension support

It's not bad to read markdown document in terminal, however, it's better if we do have another choice, especially it's free and beautiful

Readdown is a good alternative to read markdown document. Unfortunately, it's a little buggy? in case you open a .md or extension other than markdown/mkdn/text/txt, it just throw out an error.

Workaround:
To add more extensions to be supported in Readdown


> vim /Applications/Readown.app/Contents/Info.plist
# update below section
<key>CFBundleTypeExtensions</key>
<array>
<string>markdown</string>
<string>md</string>
<string>mkdn</string>
<string>text</string>
<string>txt</string>
</array>

2011/07/11

nodejs powered goo.gl

This post is shooting for nodejs-powered Mac users

It's pretty useful if we can shorten URL in command-line, especially we can have a helper to achieve below
1. ease to have/install
2. ease to use

for installation
npm-g install goo.gl

we still need do some modification since goo.gl output key -> value, that say if you do shorten google.com you will see
http://google.com -> http://goo.gl/mR2d

edit /usr/local/bin/goo.gl (check installation path)
change line 135 from
console.log('%s -> %s', val, (res.id || JSON.stringify(res)));
to
console.log('%s', (res.id || JSON.stringify(res)));

added a bash helper in ~/.profile

function gg() {
goo.gl $1 | pbcopy
}

then
source ~/.profile

now you can simply type
gg www.yahoo.com and get shorten url in clipboard

nodejs packages

2011/06/18

NodeJS + YUI3: Crawling Web via CSS selector

Story:

YQL is a killer tool to crawl web data, we can fetch remote pages and get json/jsonp/xml output via YQL console.
The magic behind it's using xpath like we crawl web in tranditional way.
However, to be a frontend engineer, to "select" desired DOM elements is a dead simple things via CSS selector and that's what Dav's talk inspire me a lot.


YUI3 + NodeJS

For details about node.js I strongly recommend to read it here: http://nodejs.org
To me it's so interesting to deal w/ DOM stuff at server side. YUI3 (and jsdom) enpower NodeJS fetch pages in a easy(maybe frontend-friendly :P) way.


Demo:

1. To crawl all link titles in hacker news
http://hapi.nodester.com/api?host=http://news.ycombinator.com&rule=table%20td.title%20a&callback=hackernews

2. To crawl lady gaga information title in yahoo search
http://hapi.nodester.com/api?host=http://search.yahoo.com/search?p=lady+gaga&fr=sfp&fr2=&iscqry=&rule=%23web%20.res%20.sm-media%20img&callback=ladygaga

3. To crawl iOS/Android app and get all app icon images in yahoo app search
http://hapi.nodester.com/api?host=http://apps.search.yahoo.com/search?p=plants&fr=apps_sfp&fr2=&iscqry=&rule=%23main%20.app-res%20.left%20img&callback=yappsearch

To link above you can get a jsonp object and use it in your webpage


Future work:

There are still a lot of rooms to improve this prototype,
in case some websites needed additional http headers such as Referer or Cookie is not yet supported.
Moreover, to avoid of confusion we have to encode '#' (sharp?) to %23 since it's a valid character in URL and it's a identifier selector in css rule.

Reference

1. Dav Glass — Using Node.js and YUI 3
http://developer.yahoo.com/yui/theater/video.php?v=glass-node

2. Dav Glass — Node.js + YUI 3 (YUIConf 2010)
http://developer.yahoo.com/yui/theater/video.php?v=yuiconf2010-glass

2011/05/17

function terminology

Notes about Javascript Patters Chapter 4: Function

named function expression

// named function expression
var add = function add(a, b) {
return a + b;
};


// function expression, a.k.a. anonymous function
var add = function (a, b) {
return a + b;
};

The only difference of above 2 function expressions are name property of function

// named function expression
var add = function add(a, b) {
return a + b;
};

> add.name
"add"

// function expression, a.k.a. anonymous function
var add = function (a, b) {
return a + b;
};

> add.name
""



// function declarations
function foo() {
// function body goes here
}

The difference between function expressions and function declarations are not that obvious, function expressions need tailing semicolon while function declarations don't

contradiction of javascript

By reading Javascript Patterns (by Stoyan Stefanov)

> var a = NaN;
undefined
> a.constructor
function Number() { [native code] }

it's so weird that NaN's constructor is in Number type.

> var a = new Array(1, 2, 3);
undefined
> a
[1, 2, 3]
> var b = new Array(1);
undefined
> b
[]

By using Array constructor w/ only one argument, it's array length, not first element.
Conclusion: using Array literal instead of Array constructor

BIO

Taipei, GuTing, Taiwan

huang47 | personal

huang47 | personal