2015年11月27日 星期五

聊預測自己未來的能力

比起預測下一期大樂透號碼的能力,這邊說的「預測未來的能力」跟「對未來的想像力」比較相關,是更日常生活相關的能力,。

這個故事是我最近一個月經常發生的事,剛剛又發生了。我經常會有沒洗澡就睡覺,隔天要出門去咖啡館寫程式的情況,這時就想還是洗一下澡好了、但為了時間還是不要洗頭好。但進入浴室在熱騰騰的蒸氣中間,就會想熱水洗頭會很舒服,然後就洗頭,舒服的回到房間,吹個頭舒服的弄很久才出門。然後隔天出門時又做了一樣的規劃,嗯 洗澡但不洗頭。

這故事跟個人工作能力無關,但卻大大了影響了我工作的計畫和效率。我缺乏的是清楚地理解自己在不同環境中,會受到怎樣的環境影響,就簡單地做出計畫。

如果我清楚地想像就算「現在做了決定不洗頭,等下還是會洗頭」,那在趕時間時,我就會決定不洗澡就出門。如果我清楚地想像到「現在在浴室中洗了頭,會舒服到等下在房間吹頭髮、花半小時東摸摸、西摸摸」,那我可能就會忍住不洗頭。

在這個小故事中影響不大。但在現實工作中,一樣會有這樣的情況。像是被問「這東西下個禮拜做得出來嗎?」腦袋中的想像是每天加班,努力工作,然後下週準時交差。但現實是,加班個兩天,發生了一些問題、或是加班三天後沒心情工作,這些都和你寫程式的能力無關,但卻會在你承諾的時間交不出東西,拖累整個團隊。


對自己能力過於樂觀的估計是大忌!!! 會拖累他人進度。

對自己能力過於悲觀的估計是大忌!!! 會拖累自己成長步調、不敢嘗試。

這種想像力、對過去歷史的記憶力、也許是可以訓練的。再不然只對自己一定能預測正確的情況做預測,其他情況就清楚明白的放在「不知道」這個類別。

俗話說得好「人貴自知,知己者明」。
努力認識自己吧~ 培養自知之明。

參考:《老子》第三十三章:「知人者智,自知者明;勝人者有力,自勝者強」
---
BTW, 這個能力是很容易被觀察的,只要看一個人有沒有準時完成他的承諾就知道了。


2015年11月20日 星期五

程式設計法與人生 (Programming Paradigm and Life)

解決問題流行的方式有兩種。
  1. 想出第一步要做什麼,然後開始做、做完再想下一個。
  2. 是把大問題切成數個小問題一直切到夠小,然後再一個一個做。
第一個 叫做命令式程式設計、第二個 叫做宣告式程式設計。
第一個 想要回答「怎麼做」、第二個 想要回答「做什麼」。
第一個 是工程師做的事、第二個是設計師做的事。
第一個 叫做敏捷式開發流程、第二個 叫做瀑布式開發流程。
第一個 叫做 connecting the dots、第二個叫做 設計研究。
第一個 叫貪婪演算法、第二個叫分治演算法。
第一個 叫活在當下、第二個叫有遠見。
第一個 把問題序列化、第二個把問題 心智圖化。

用第一種的人想出了外掛 - 設計模式 (design pattern)
用第二種的人想出了外掛 - 狀態機和不變資料 (state machine + immutable data)

還記得大二演算法排序的作業,標準解法是先做第二個 (qsort)、然後問題變小了就接第一個 (shell sort)

各有各的使用時機,冷靜分析後我從函數式編程的信仰者回到無神論者了。
第一個適合許多未知、經常變動的問題。
第二個適合有固定答案、行為可預測的問題。

嗯嗯 不過當然用 react 還是比其他好 XD
---
目標努力 iterative 的 functional programming~ 
=> 每次用第一個方法切一小塊問題,用第二個方法解。

2015年11月15日 星期日

參加 FB Hackathon 2015 感想

FB Hackathon 比賽篇

有點缺乏結束的感覺,這時候放下再前進的方法就是寫篇文,透過寫作把事情組織、整理好。

這是我第一次參加 Hackathon,這次是 FB 和 Girls in Tech 合辦的,主題是女性和公益。先不論結果、這次真的很新鮮 ( 趕期末作業的 fu ),之前上網研究過的 Hackathon 攻略,但今天完全丟在一邊沒在管... 哈哈

大家在交誼區自我介紹、聊自己的想做的主題,結果弄了很久大家有一點點熟,到一張桌子旁邊坐了下來就變成一隊!!! 然後我們這隊大部份都是做後端、資料處理的,結果就是 nodejs + java + python 各種語言混合大亂鬥,真的很酷~

經過聊天,發現大家都是第一次參加、發現大家都是熱心公益的人。前面三個小時,花了長時間 Brain Stroming,一般會得獎的參賽者都是決定好要做什麼才來的,還有偷做的。在 Hackathon 跑快速 BASIC 設計流程真的很神奇,定義問題 (Briefing)、分析已有解法 (Analysis)、思考改進方法(Synthesis)、實作 (Implementaion)、傳達 (Communication)。大概流程都有跑,不過 S & I 的部分有點亂。其他合作流程都有讓人 Hack 團隊的感覺。

一直看設計研究的初學者,終於有個玩的機會 XD~ 很多不熟的地方,設定 Target Audience、設計 Magic Moment ( 這個沒做... )、列出 User Story ( 這個也沒做... T.T )、設計互動 ( 光流程不算... )、紙牌分數投票法。設計師注重這問題是不是真正的問題,工程師注重的是這問題要怎麼解,Hacker 的精神在這兩個中間。但年紀大了真的開始變得比較嘴砲了... T.T

我這天在工程師的部分一直撞牆,真的是... 超弱。Node & Express 才摸一週多、Facebook APP 第一次開發 ( 這個真的超多地雷限制 )、mongodb 第一次用、環境設定在 Macbook 卡一卡、在 linode linux server 卡一卡。就像馬拉松配速沒配好一樣,在經過三小時討論、五小時 Coding,我在最後的四小時完全失去戰鬥能力。壓垮我的稻草是從 Facebook 抓圖隨機一直回傳 403。

真的很感謝強者隊友們,PeiPei / Gordon / Joanne / Leo / Erica,就 12 小時 sprint 的角度來看,第一次還蠻成功的,如果再 iterate 幾次、這個團隊應該會生出好產品的。今天過程真的很好玩~ 有了好同伴,就從在 Panic Zone 變成在 Learning Zone 了。

會再參加嗎?喔 真的很累,想到下個月還有一場就很崩潰。

Hackathon 前問題研究篇

因為主題是女性和公益,賽前大概花了半天看了很多議題,挑出兩個覺得適合的問題。

1. 增加同理心 (empathy) & 跨出舒適圈 (Comfort Zone) 的主題:
    > I don't like that man. I must get to know him better. - 林肯
    > While nothing is easier then denounce the evil doer, nothing is more difficult than understand him. - 杜斯妥也夫斯基
    > Step outside of your tiny little world. And step inside of the tiny little world of somebody else. - Sam Richards
    > Life begins at the end of your comfort zone.
    > comfort zone / learning zone / panic zone
    > Ted影片:一個關於同理心的激進實驗
    > 厚書: 好人總是自以為是:政治與宗教如何將我們四分五裂


2. 在東亞,特別少女生走自然組:不是因為能力不同、而是因為社會期待。 ( 昨天才突然發現我修大學資工系的課時,從來沒跟女生共事過 )
    > 台灣女生不喜歡讀科學,「世界第一」帶來的驚愕與警訊
    > 高中選組男女大不同?性別與高中選組之研究


好好放下、明天再前進 Javascript 和 函數編程的世界、Full Stack Developer 之路。
---
延伸閱讀:10 tips for hackathon success

2015年11月10日 星期二

做 Prototype 的工具 framer js



今天逛到一個設計聚會的臉書頁面,他們投票最想學的 Prototype Framework 是 framerjs。一點進去他們網站看,就發現了學 React 一直很缺乏的 Animation 和設計感。後來也發現 React 也有人做 Animation,今年的 ReactEurope 有兩個很好的 Talk,不過先來看這個影片,進修一下、看這個影片教設計師的 prototype 的方法吧。

framers 是一個創意設計的工具,讓你能建立互動和動畫的 prototype。為什麼要做 prototype?探索和發明新的互動、定義要設計出的感覺是什麼、做有效的概念溝通。

對我來說最有趣的部分是當你從你的設計中建出互動的 prototype,你會發現很多全新的互動。如果你只是做靜態的 mockup,然後叫其他人做一些 Animation,你會失去跟它玩的機會... 試著反過來做、亂玩參數、試著發明東西。對我來說,這是 prototyping 中最有趣的地方,總之就是東搞西搞一些。

另一件事是當你談到設計,除了視覺設計外還有很多東西,當你開發 App 或是網頁,更要在意的是它感覺起來怎樣,怎麼互動、怎麼流動,很多視覺設計以外的東西。

另一件很實際的是當你在團隊中工作,prototype 能讓你很有效的其他人溝通你的新想法。今天我可在這邊給個好例子:「想像你有一個可排序的列表,被選擇的項目會放大和加陰影浮在上面。所有的項目都會對此改變它們的位置。」

下一步你會做一堆速寫

然後是精美、有陰影的 Mockup 


但我們真正接下來想看到是有動畫能互動的 Prototype
試著做一些操作,移動項目


animation:after effect / keynote
prototyping: ... 一堆,最後一個是framer
 我們今天想著要 prototype 什麼,它實際上就是在設計明天。從概念到執行中間大概可以分成四個階段:Paper -> Sketch / Photoshop -> Framer -> Code。以流程來說,Prototype 大概是在正中間的位置。Prototype 可以往前或往後一點。現在的產品設計流程,通常會做很多靜態的 mockup 但只做一個到兩個 Prototype,我們希望有了更好的 Prototype 工具之後,可以變成三五個 mockup 但做很多的 Prototype。

Framer js 是一個開源的程式庫,提供 Framer Studio Mac App:它提供程式碼編輯器、即時視覺回饋、可以從別的軟體 Import、展示模式。

Framer Studio 可以直接從 Sketch 導入 layer、階層。


Framer 提供這些功能。
Layer 就是一個 Container 可以設定大小、位置、透明度、縮放、圖片、模糊... 一堆屬性。
Animation 讓你從一組 states 過渡到另一組 states。可以設定 curve、延遲、時間長度。
States 讓你命名一組 states,之後你就可以指定從 XXX 變成 YYY。
Events 讓你可以處理 drag、drop、click、scrolling、touchstart ...

開始 Demo Prototype examples & QA 從影片13分15秒。

---
framer 教學影片:https://www.youtube.com/watch?v=3zaxrXK7Nac

從影片中可以看到,設計師是直接把一整張圖當成 Layer 來操作。然後視覺上的元件就當成自訂元件,不用管甚麼 HTML / JSX,然後就對視覺上的這個元件 ( 一張 button 的圖 ),安上click 事件,然後用動畫把另外一張圖換上來...

設計師設計時用不同大小的圖片當成自訂元件,以這樣的元件視角去設計整個 Prototype,看是這張圖要不要模糊、要浮在前面還是後面、要不要讓他可以 Scroll、動畫時要如何從一個 State 變成另外一個 State。

這樣子好直覺啊,一個元件就一張圖,用 sketch 畫畫就好,不像程式設計師要用 HTML / CSS / UIKit 兜好久。


framer 教學影片 https://www.youtube.com/watch?v=kJYI4oYrHik
他們的 script 語法好簡單,超簡潔、超適合簡單的 UI,像 Python 用 indent 代替大括號真的很棒,然後設定 Event 也太簡單。都在操作 Image 超簡單。

發現那個 script 叫 coffee script 喔喔喔 看了完全不想寫 Javascript了 XD

2015年11月9日 星期一

函數式編程介紹 ( 1 / 2 )

函數式編程的專有名詞篇


純函數 ( Pure Function )給同樣輸入參數,就會回傳同樣結果的函數,而且沒有任何可觀察到的副作用。Pure Function 的例子:sin(x)。非 Pure Function 的例子:getChar()、random()、還有許多類別中的 member function。從數學上來理解,純函數就是一個數學函數,一個輸入會對到一個輸出。

純函數的特點:
  1. Portable / Self-Documenting :完全是自給自足的 ( self contained ),沒有外在的依賴 (Dependency)。
  2. 可暫存 ( Cacheable ):把計算值暫存的技巧被稱作 memorization,可以用來避免重複計算,加速程式。
  3. 好測試 ( Testable ):不需要管上下文和呼叫順序就可以測試。
  4. 適合平行處理、純函數是線程安全的 ( thread safe )。
  5. 引用透明 ( Referential Transparent ):一個引用透明的運算式指的是 如果這個運算式可以被他的值 (回傳值) 替換而不影響整個程式的行為。簡單講就是有可交換性啦。
  6. 可以熱抽換 ( Hot-Loading ):因為不依賴外部的狀態。

副作用 ( Side Effect )如果一個函數或運算式 ( expression ) 被說有副作用,這指的是它改變了一些狀態 ( states ) 或是 跟呼叫他的函數或外在世界,有可觀察到的互動。舉例來說,一個函數可能會改變全域變數或函數的靜態變數、改變傳進來的參數、引發例外 ( exception )、列印資料到螢幕或是呼叫了其他有副作用的函數。如果有了副作用,函數的行為會受到歷史、執行順序的影響。這樣子一來,想要理解或除錯有副作用的函式會較難,因為就必須要了解他的上下文 ( Context ) 和執行歷史。

顯式 ( Explicit ):形容函數与外界交換資料只有一個唯一管道——参數和回傳值。和顯式的相反是隱式 ( Implicit )。

一級函數( First-Class Function ):指的是語言支援把 Function 當成第一類公民,可以支援一般變數的操作,像是把 Function 當成變數傳給另外一個 Function。

Lambda Function:Lambda 運算式是匿名函式,可用來建立委派或運算式樹狀架構類型。

形式系統 ( Formal System ):形式系統可以的廣泛地被定義為任何基於數學模型的、良好的抽象思考的系統 ( system of abstract thought )。

Currying:這個技巧能把接受多參數的函數轉換為多個連續呼叫的單一參數函數。

閉鎖 ( Closure ) / MDN:Closure 是可以使用獨立 / 自由變數的函數。換句話說,Closure 記得它實體化時的環境變數。

PS:專有名詞那邊引用了很多別人的解釋,可以點前面的連結進去看完整版。

-----------------------------------------------------------------------------------------


函數式編程簡介篇

函數式編程的的哲學就是假設副作用 ( side effect ) 是不正確行為的主要原因。所以努力想要控制和管理副作用,經常的解法就是把純函數、單子和不純的函數 ( impure function ) 分開來管理。另外鼓勵大家多寫純函數。我們對待資料要像玩戲法般,一直傳來傳去、禁止使用狀態 ( state ) 和副作用。剛剛這段文字有提到很多專有名詞,但這樣子怎麼寫程式?這邊我開始介紹一個新工具叫 柯里化 ( currying )。

Currying:
Currying 把任何的函數轉換成 一連串只做單一事情的函數,各個擊破。

Curring的概念是簡單的。它讓你呼叫函數 A 時可以傳比預期還少的參數。然後這個函數 A 會回傳函數 B函數 B 需要的參數是先前沒傳進函數 A 的參數。所以整個流程是:

函數A (x, y) 可以等價於下面這段
-------------------------------------
函數B = 函數A (x)
函數B (y)

先前傳進去函數 A 的參數會利用閉鎖 ( Closure ) 的方式變成函數 B 的環境變數。看完上面這段解說,一定會想這什麼鬼東西?來看看 這邊的例子 會容易理解的多。利用這個技巧,就可以選擇一次傳所有參數或是把參數分幾次傳給數個函數。

lodash提供了把函數 curry化的工具,用法:

var divide =           function (x,y) { return x / y } 可以被改寫成
-----------------------------------------------------
var divide = curry( function (x,y) { return x / y } );

之後就可以被這樣呼叫

divide ( x ) ( y );

或是

var xDividedBy = divide ( x );
tenDividedBy ( y );

PS:這工具的名字是為了紀念一個美國數學家 --- Haskell Curry,跟咖哩沒有關係。

接下來我們看另外一個工具 代碼組成( compose )。

組合 / 組成 / 合成 ( compose )
Composition 把許多函數用管子 ( pipe ) 連接起來,變成一個新個函數。


f, g 都是函數,x 在它們之間被傳遞。
注意g函數的參數是 x、f函數的參數是 g函數的回傳值。
較常用在 f & g 都吃同一類參數的時候 (ex: 字串)。


例子:變大寫和去空白函數 = compose (變大寫函數, 去空白函數)

因為有了一級函數、Currying、組合,Pointfree 風格變得流行了起來,指的是函數呼叫時不用提到它要處理的資料。例如:

var snakeCase = function ( word ) {
      return word.toUpperCase( ).replace( /\s+/ig, '_' );


可被改寫成
-----------------------------------------------
var snakeCase = compose ( replace( /\s+/ig'_' ), toLowerCase );

用組合形成新函數就不用提到資料 --- 也就是之前寫法中的 word

Pointfree的編程風格可以讓我們移除不需要的名字 (names),讓我們保持簡潔 ( concise ) 和一般化 / 泛型 ( generic )。但要小心 Pointfree 是個雙面刃,有時會把原來的目的變得模糊。

( 以上是書本前五章的內容,其他待續... 後面有點硬,不知道什麼時候會看。)

---
這篇文介紹得很好 函數式編程

2015年11月8日 星期日

Javascript 中的函數式編程 (a talk @ ReactiveConf 2015)

影片:Functional Programming in Javascript By Daniel Steigerwald 

Daniel 是 google 前員工、也是 https://github.com/este/este 這個 React + Redux + immutable.js Starter Kit 的作者,在 Github 上有 1800 顆星。

我認為函數式編程 ( Functional Programming ) 將在明年成為主流。像在 C++11 和 Java 8 中已經開始有 lambda function。我接下來聊我已經用在 Production 的東西。我認為函數式編程已經在前端的世界已經被 React 引入。

什麼是函數式編程?
沒有什麼神秘的東西,到處都是純函式 ( Pure functions everywhere )、不可變的數值 ( Immutable values )、用組成而不用繼承 ( composition over inheritance )、紀錄代替類別 (records over classes)、處理好副作用 ( taming side-effects )。我覺得 functional programming 有點像是人工智慧,聽起來有點酷、有點奇怪,但當你了解了它以後,就只是無聊、很平常的寫程式而已。

為什麼要函數化 ( functional )? 
因為軟體正在吃掉這個世界,它必須要做到最好。函數式編程已經被證明,比較少臭蟲 ( less bugs)、較不複雜 ( less complexity )、程式碼更可讀 ( more readable code ) 和更好的效能 ( more performance )。

物件導向程式設計 ( OOP ) 有什麼問題?
沒有問題,只是很難、常被誤用,而且有時是難以避免的。整個物件導向程式設計的模式 (paradigm) 是基於「送訊息給物件是唯一跟狀態 ( state ) 互動的方法」,因此狀態就會被分散。於是在分散式系統中狀態的一致的難度是跟世界和平一樣的 XD


物件導向程式設計 和 函數式編程的設計模式比較
Scott Wlaschin是很好的講者,不像我鼓勵大家去聽他的演講。

在 OOP 中,每次方法在某個實體上被呼叫其實就是副作用。副作用很難被追蹤、被理解,沒有人喜歡驚喜。驚喜在生活中是好的,但驚喜在程式碼裡面沒有任何好的地方。我們被教導要用繼承,但他是陷阱,程式碼會不夠彈性、很難之後改變。設計模式最難的是如何幫這些模式取名字,動詞偽裝成名詞。策略、工廠、Commands...

React 中最耀眼的原則是函式組成法 ( function composition )。

純函數 ( pure function ) vs 髒類別 (dirty class)

純函數沒有任何副作用。他很難去違反只負責一件事的原則 ( single responsibility principle) 因為純函數只有一個明顯的目的 --- 把輸入轉成輸出。所以測試就變得超簡單。

類別是髒的。互叫一個簡單的類別函式,就會改變它。誰做的?為什麼做?我們永遠不知道 ( 直到我們 debug 後)...

推薦這本 github 上的書適當的函數式編成指南 ( 在 github 上有 6000 顆星)


如果你不理解這個程式,沒關係。我也不懂。在函數式編程裡它等於 ( (4 + 0) * 2) + (4 * 2)
Immutable.js
不可變資料一旦被建立就不能被改變,這使得更簡單的應用程式開發,不用預防性的回傳複製品,更可以使用間單的邏輯來達到進階的 memoization 和改變偵測。一個針對不變資料的可變 API 並不改變原來資料,而是總是產生新的資料。
   - 和 原生的 Javascript array 有很相似的 API
   - 保持永遠的不可變 (List, stack, map, orderedMap, Set, OrderedSet and Record)
   - 非常快

---
PS:作者講的不多,上面很多都是照投影片上大量文字打的。

2015年11月7日 星期六

Redux = 事件驅動系統 = 伺服器

Redux 做的事情其實很簡單 ( 主程式才99行 ),就是可客制 Event 的 Event System。這概念在別的領域已經很成熟。但因為 Redux 的目標使用者是 Flux 的使用者,套用了很多原來 Flux 裡的專有名詞,所以對非 Flux 使用者變得很難懂。這邊透過類比大家都知道的名詞,目標讓 Redux 的概念連六歲小孩都能理解。

Flux:

Actions trigger reducer to update states in the store.


Redux 的行為等於事件驅動系統 ( Event-driven System ) / 有限狀態機 ( FSM ):

Events trigger event handler to update states in the machine.

Action Event | Signal | Message
Reducer Event Handler | Finite State Machine 中的 transducer


Redux 的行為等於一個網頁伺服器:

When a request came, using route table mapping to get a method to process it。

Action Http Request
Store.dispatch(Action) 送 Request 到 Server
Reducer Router 把 Request 送到對應的 Router Method,更新 Database
Store Database
UI / React Http Response


Redux的行為等於巷口那家... 哎 想不出來比較生活的說法。

現在有沒有覺得 Redux 很 Awesome?好像沒有啊... 但我們回到瀏覽器的環境重新看一下,因為 HTML 的元件很小,開發者會組合 HTML元件成為可重複使用的「大元件」。但問題是瀏覽器中的 「事件處理系統」 是針對 HTML 小元件的,沒有給「大元件」的。於是Redux 提供了給開發者可以自行定義事件的「大元件」事件處理系統,因為你可以控制整個事件處理系統,重播和紀錄事件都變成毫不費力的事。現在又感覺到  Redux 很 Awesome了吧!!!

故事到了這邊,一定會想這樣解說,哪個六歲小孩能了解啊,相信這是大家共同的疑惑,不過 「投資一定有風險,基金投資有賺有賠,申購前應詳閱公開說明書」,我會反省的...

---

延伸閱讀:
redux 的專有名詞解釋
Redux Issue 891:Is redux conflating actions with events?
六歲小孩也能懂的 Javascript Closure 說明

2015年11月6日 星期五

訓練英文的閱讀能力


最近每天就是一直上網苦苦追趕 Javascript 的 state of art。吸取資訊需要三個重要的能力:英文聽力能力、簡體中文閱讀能力、英文閱讀能力

英聽:
看youtube都開 1.25x 或 1.5x 的速度,聽得很順、完全可以理解。(感謝無字幕的 冰與火之歌 和 廢話很多的 ASP Surfing Championship 對我的訓練 )

簡體中文閱讀:
看了很多對岸的文件和字幕 XD,一下就適應了。快要和繁體一樣快。( 因為看太多小說,我對中文的閱讀速度真的很有自信 )

英文閱讀能力:
唯一的問題就是我的英文閱讀速度,上不去啊。想十年前 ibt 托福閱讀還拿了 29/30,還是不夠。做了這個 英文閱讀能力線上測驗 發現我現在的閱讀速度只有每分鐘 150 個字 ( 退化...? ),大概是美國小學生的能力。成人平均是 300 個字、大學生平均 500 個字、成績好的大學生大概是 800 個字 ( 這應該是一般部落客的水準吧 )、練過速讀大概是 1500 字。測完就知道我瓶頸在哪了。以前看論文或是教科書,完全沒問題啊,因為那時的瓶頸是理解能力。但現在 Javascript 的資訊很多是部落格,廢話跟我一樣多的部落格,英文閱讀能力就變得超重要。

偷吃步的解法:一個是叫 Mac 唸給你聽... 叫 Mac 念得很快,測過快到超過我的英文閱讀速度還是聽得懂。另一個是只看程式碼,但這畢竟只是治標,今天開始尋找治本的方法。

速讀的訓練的方法:
1. 練習眼睛移動
用規律的速度,拿支筆從每行的開頭,指到每行的結尾。影片剛開始建議的速度是 1.0 秒/行,然後縮減到 0.5 秒 / 行的速度。換算下來大概是每分鐘 800 個字到 1500個字。但對我這個小弱弱,剛開始每三秒一行就好,然後目標練到一秒一行就好。練習的方式是開著節拍器,跟打鼓一樣,設定它每十五分鐘從 20 bpm 加速到 60 bpm,每拍一行開個 16 分音符剛好,每個聲響移動1/4行,慢慢進步。

2.  練習邊緣視覺:
筆不用從開頭指到句尾。從開頭第 N 個字開始,看到結尾前第 N 個字就好,因為邊緣視覺會看見。慢慢練習 讓 N 從 0 變成 3。

今天開始每天練十五分鐘,看到底管不管用、目標每分鐘 800 字。 (快五倍... 這有可能嗎?)
目前能力:每分鐘 150 字 (每五秒一行)
週目標:每分鐘 400 字 (每兩秒一行, 30 bpm)
月目標:每分鐘 800 字

好像會有個 browser extension 來訓練這種事吧,我找找...

---
wow... 估了一下,我國中看一本金庸大概五小時、大概每分鐘 900 個字。是我現在英文閱讀能力的六倍 T.T

2015年11月5日 星期四

用 Redux 實踐「狀態機導向的介面開發」

BIG WORD ALERT!!!
———
研究了Redux.js之後,對State Machine有了更深的領悟。

上個月解了一百多題 LeetCode,深深覺得程式解問題很重要的一點就是,想出一個「資料的表達的方式」讓問題運算過程中的所有「狀態」能夠清楚的表達,之後只要叫電腦從 Initial State 算到 Final State,題目就解完了。這個「資料表達的方式」也許是 stack、也許是 Array 再加上兩個 Pointer、也許是 2D Array表達地圖狀態、或複雜一點的像是 八皇后(N-queens) 問題用四個 array 來表達row, column, 兩個斜線方向有沒有皇后。只要想完「怎麼用資料來清楚表達所有狀態?」這個題目就解一半了,如果是 backtracking / 窮舉的問題的話,那你就已經解完了。

不過,這個跟 Redux 有什麼關係呢?Redux做為Flux概念的實現,設計中 Store 是唯一的資料儲存中心,它把所有「元件狀態的資料」集中放在一起。讓開發者很容易用抽離 UI 的角度思考,一開始就把應用程式中「0. 怎麼用資料來清楚表達所有邏輯狀態?」這個問題給想清楚。這個問題解完了之後,剩下的只有兩件事:

 1. 收到使用者 Action 或伺服器的更新,要從哪個 state 換到 哪個 state:應用程式的運作邏輯,這部分 Redux 用 Reducer 做掉了。在 Reducer 中你要清楚定義狀態機中的 Transition 也就是 ( previousState, Action ) => newState 這件事

 2. 在每個state的時候,應用程式 / 元件要畫成什麼樣子:React 想解的問題

0 和 1 兩個步驟常常會平行設計、互相影響,這部分會定義你的產品功能面。
2 的步驟就是視覺化、資料傳達的部分。


總結,從State Machine的角度來開發只要做下面三件事:
1. 想好怎麼表達 state。 ( Redux Store )
2. 想好有哪些事件,事件會讓 state 間怎麼切換。 ( Redux Reducer )
3. 如何把狀態傳達給使用者。 ( React )
從此開發就有了 SOP。

PS: 「資料的表達方式」包含了「資料結構」和裡面結構中資料代表的意義。

React 和 Flux 到底在做什麼?

看了下面兩個文章,終於知道 React 和 Flux 在做什麼了。
1. ReactJS For Stupid People
2. Flux For Stupid People

以下開始和主題不很相關的廢話,可以直接跳到最後一段「好啦,說了一大堆廢話。」

前兩天一直迷惑,到底這套新的 UI 開發流程和我過去接觸過的 framework 們有什麼不同?以前用過 Java AWT, JAVA SWING, ZK Markup Language, JQuery UI, iOS UI Kit, Android, QT Component, OpenGL, xxxRendering Engine ... 列出來才發現,真的是有的沒的一大堆。

在螢幕上生出畫面大概可以分成三群:
1. 網頁開發
2. 桌上 / 手機的原生應用程式
3. 遊戲 / 動畫

3) 寫遊戲和動畫的流程最簡單,大二用組語刻了魔法氣泡遊戲 / 大三參加趨勢比賽徒手硬幹JAVA Swing ( 真的超慢的 T.T ) / 研究所用 3DS Max 和 Blender 做動畫 / 工作上用 OpenGL 做了動態路徑規劃的資料展示。這一類大概每次就是重畫,隨時檢查物件狀態一直重畫。看一下 FPS 有到 Real-Time 就好。

2) 開發原生應用程式的流程就是用原生的物件,不管太元件長什麼樣子,反正就是設計互動,註冊事件,最多就小改一下背景、顏色之類的。反正最差就是比較醜,功能都沒問題啊。話說 MFC 到底是什麼鬼東西啊... 記得花了兩三天從來沒搞懂過。

1) 網頁開發不像開發原生應用程式,有功能性較大完整的原生元件。只有一堆小到不行的 HTML 元件。然後問題就來了... 網頁上一塊塊重複的物件,像是 部落格、購物網站、討論區上面一個個的模組要怎麼搞。

如果是靜態的網頁,就背後用 php 弄個模組 ( 喔 交作業而已別太嚴格啦 ),Header 一個Template、商品一個 Template、側邊欄一個 Template、導覽列一個 Template,然後就很開心地從資料庫抓一些資料填進去Template就好啦。有什麼事件發生就傳資料到伺服器端,整個重新畫頁面就好。老實說還挺簡單的,怎麼流程聽起來很像ReactJS。但是 2004 年,總是有一些天才們發明了一些讓人很累的東西叫做 Ajax 把 Gmail 推上了時代尖端。Ajax 告訴所有開發者:「喔 什麼!!! 你把使用者輸入送到伺服器再傳回來,然後才更新 UI,太慢了喔 弱~」。然後從這時候開始,網頁設計師就很苦情的開始在客戶端開始亂刻元件,MVC 邏輯的重擔就移交給 HTML、CSS、Javascript。但主流的開法方式是,不管 MVC 也行啦,反正網頁會動看起來有設計感就好。

JQuery Library 在這亂世中應運而生,讓我苦讀 vanilla Javascript 的經典「ppk談Javascript」變得英雄無用武之地,JQuery 的 selector 就像用 matlab 來處理資料的有快感、dot chain rule 讓語法看起來糖分很高、不用打 getElementById 就像 C++11 中用 STL 不用打 Iterator 一樣清爽。可以快速開發出很難維護的網頁。解決了 Javascript 操作 DOM 會讓人想罵髒話的問題。為什麼很難維護,因為沒有元件化,Javascript有很有力量,讓人在網頁裡隨性的的東改西改,但不知道誰改的就很難 Debug,漸漸變得複雜就不能開發大型網頁。

然後 AngularJS 把後端流行的 資料綁定搬到瀏覽器來,用 Javascript 的 Closure 來做封裝、一區區的資料分別藏起來,限制一部分 Javascript 只能操作 一部分的資料和 HTML,充分發揮了各個擊破的演算法 ( Divide and Conquer ),可是問題又來了... 媽的我花了兩天,學不會 AngularJS 啊一直 Typos 很煩,雙向綁定怎麼那麼複雜,讓我寫程式一直 NG NG。所以我沒太多研究,只聽說是雙向資料綁定會引起 DOM Tree 的 Cacading Update,導致效能容易有問題。另外 HTML 裡塞了太多髒髒的東西,容易消化不良。

好啦,說了一大堆廢話,React 和 Flux 到底做了什麼?

React 讓人用 Javascript 和 HTML 刻更高級的元件 ( Virtual DOM ),像是 Angular 元件做的限制 讓一小段 Javascript只負責一小塊的UI / HTML更新,使用各個擊破的演算法,刻完元件之後就像開發原生應用程式時一樣,有了較大的元件,讓人跳脫低級 ( low level ) 的思考,少說一點髒話,透過 JSX 讓人從模組化的角度看 UI。簡單的譬喻就是讓人用組語開發高階語言的語法,之後可以用高階語言寫程式。

React 只 Update 新的 DOM Tree 中和前一次 DOM Tree 差異之處,他們管這叫 一致 (reconciliation) 讓重繪的速度快很多,當重繪夠快,網頁的開發者就可以回到 pre-AJAX時代,回憶2004年之前的寫開發體驗:把資料送回伺服器,然後收到新資料,整個網頁重繪。

只是這回,資料來源的不是 Database,是 Flux 資料集中管理辦法中的各個 Store ( Client-side Database )。Flux的單向資料流理念,強迫你在客戶端有一個像資料庫的資料集中處,Store裡有來自使用者輸入的資料、有來自伺服器端的資料更新。然後這個資料商店把每一家元件訂閱的資料送上門,元件看了看送來的資料商品然後就更新。Store 像是介於 CPU 和 硬碟中間的 Cache / Memory,是資料的 暫存處和Hub,或是你叫它客戶端的暫存資料庫也行 ( 用 Javascript 物件存的 )。

原來:
Browser -- Client Side ......................................... Server

有了 React + Flux 之後 :
Browser -- Client Side -- Client Side VM + Server ( React + Flux ) .......................................... Server

有點像是在 Client Side 包了一層 VM + Server 一樣,會把 JSX 轉譯成JS / HTML、集中把資料放在客戶端資料庫裡 ( Flux 的 Store )。

簡單總結一下:
React + Flux 是大規模動態資料網頁的解法。

React 讓需要大型互動元件的客戶端,可以用自己刻的、封裝良好的元件,並在新元件的高度思考。用了個 Reconciliation 的 Trick使得重繪很快,和 Flux 的資料集中管理辦法,讓開發者只要專注做好一件事「當資料來到元件時,把元件要畫好」。

---
Flux 目的是提出一個客戶端的資料管理辦法。其中的單向資料流 / 資料環其實隱含了 Two way Data Binding,只是不是綁死,比較像是 Two way Data Notification。Dispatcher 管的是 View Actions -> Store ( Models )。Store 除了存資料外還包含了 Store ( Models ) -> View 的通知。還有人覺得 Dispatcher 很多餘,就寫了一個 reflux.js 把 Dispatcher 拿掉。

延伸閱讀:
聊一聊基於Flux的前端系統

介紹 React.js (2013 by Facebook )


Introduction to React.js by Tom Occhino and Jordan Walke

整個React.js的由來是很多Facebook內部對一個問題的討論。這個問題是 開發Javacript的應用時,它的結構應該是如何? ( " How should we structure a javascript application? " )。特別是瀏覽器端的 Javascript 應用。前人透過各式各樣的 framework 提出一大堆的解答。這些 framework 通常試著去實踐 MVC, MVVM, MVW 各種概念。這些架構或 framework 共同點就是 M,也就是 Model... 基本就只是一種可觀察的物件 ( observable object ),然後這些可觀察的物件有一些Event API,讓你訂閱物件改變的通知 ( subscribe changes )。

實際上發生的事 是開發者建立了這些雙向資料綁定 ( bi-directional data-binding ),讓你可以訂閱物件改變的通知。當某個東西改變了,你就可以變動 ( mutate ) / 更新你的 View。但這種觀察模式 ( observation pattern ) 實際上鼓勵 UI 的變動 ( mutation )。每次先把元件畫出來,然後當改變發生時,就試著更新之前畫出來的 UI 元件。這邊的關鍵字是變動 ( mutation )。變動 ( mutation ) 是複雜的。大概兩年半前,Facebook試著重寫聊天室。我們試著把事情變簡單,試著把開發者要處理的變異 ( mutation ) 減到最少。讓我來解釋一下那是什麼意思,下面是一個簡單應用的架構:



要注意到的一件事是 在這個系統中的所有更新 ( updates ) 都會走一個單一的通道 ( go through a single channel )。它們都朝著單一方向流動,讓我們叫它 單向資料綁定 ( one directional data-binding )。所有輸入到這個系統的更新,不管是來自使用者輸入、即時的server updates或是起始的Loading。這些所有的更新都只透過單向的流動,不管怎樣最後都會流到 View 方格那裏。這一塊是所有前端工程師,我最關心的地方... 對嗎? 我關心使用者經驗、使用者真正看到和接觸的地方。概念上來說,我們發現建造這一塊 / View 最簡單的方式就是避免變異 ( mutation )。基本上是完全避免變異。我們發現,如果每次更新發生我們可以把整個 View 砍掉,整個重繪,那會變得超簡單。因為這樣,你只要寫怎麼把 View 畫出來就好,不用管 View 怎麼更新的程式碼。

但這樣亂搞,可行嗎?

從瀏覽器的角度來看這一定會很慢,記憶體還會不夠之類的。但概念上來說 ( conceptually ),我們還是想要用這個Model。因為每次更新就重繪真的很方便,但前提是要速度可行和還是能給使用者好的經驗。我們提出來的解法就是React.js。

React:一個為了建立使用者介面的Javascript程式庫。

我們想要所有來自 更新就重繪這理念 好的部分,但避免其中壞的副作用 ( bad performance & bad ux )。從此之後你不用管你的應用中從 state a -> state b -> state c,只剩下 零 -> 畫出來。

React 的核心是宣告元件 ( Declarative components ):
在任何時間點都只要描述你的元件長什麼樣子,這不只是一個樣板 ( template ),這不是呼叫一個函式然後回傳一段字串那種事。因為那樣的話,你要整個 DOM 砍掉,然後把新的 HTML 掛上去。元件實際上是可重複使用的 API,封裝了一大堆東西,像是 markup、這東西看起來怎樣、它的功能是什麼、它的行為、CSS、Javascript 和這些東西的結構是什麼,是這些全部的東西。對於使用者元件隱藏了實作的細節,讓我給你一個實例:
輸入元件:提供互動的 auto-complete search box,只要用跟原始 HTML <input> 一樣多的程式碼。然後我應該可以對她註冊事件、設定它的行為 ( behavior ) 有哪些。

No explicit data binding:不像 AngularJS,React 不需要實際上 Wire 你的 View 到你的 Model,你只要說哪一個屬性 ( property ) 你的 Model 想要在你的 View 中使用,然後當 Model 改變時、你的 View 就會被更新。

它是怎麼運作的? ( How does it work? ) 我們這邊說兩件事。
1) 它一開始是如何畫出來的。 ( Initial Render )
2) 更新是如何發生的。

Initial Render:在 React 我們只找一個 render function,這個 render function 完美的地方是它一直能告訴你這元件在任何時間的樣子。你提供的這個 render function 不會回傳一個字串,它回傳的是你的 View 的表現 ( representation ) ,我們做的事是... 既然元件可以由其他元件組成  ( composited by other components ),我們遞迴的呼叫render來建立UI架構。

Two Pass Rendering:
1. 先建立 markup
2. 在最上層用 Event Delegation 附加上事件處理器

因為步驟一,先把元件畫出來,我們可以做 Server-side Rendering。

更新是如何發生的?
我們不稱這個動作為Update,我們叫它 一致 ( reconciliation )。它的目的是保持你的 UI 元件 新鮮、當資料變化時自動更新。每個人應該現在都感到懷疑,如果不懷疑你大概剛剛都在睡覺。但你應該記得剛剛說的 Initial Rendering function,任何時間點它要回傳一個元件的表現 ( representation )。當改變發生時,我們重新呼叫一次 Render,然後比較原來 Render 的結果和改變過後 Render的結果,計算出兩個時間點元件的差別 ( diff )。接著批次計算出最少的變動量,然後一次 把變動更新到 DOM Tree 上面。所以很快。

---
12:20 開始 Show Code Sample 和 JSX 語法
   程式碼還是看影片比較清楚... XD

26分開始大概一小時的Q & A 還蠻精彩的~~~

2015年11月4日 星期三

Be predictable, not correct. by Pete Hunt (from Instagram)


Pete Hunt from Instagram Web Team.

What makes UI hard?

最難的是管理所有使用者的狀態 ( state ),更可怕的是隨時間改變的狀態。然後 Unit Test 不能完全測試 UI 的所有情況 ( 太多例外 )、靜態分析 ( JSLint / JSHint ) 也不行。因為這樣的複雜度,我不曾試著讓 UI 完全正確。我只是試著讓 UI 變得可預測。

Two silver bullet:

1. Composition: 讓簡單的 function 組合成更大的 function。
2. Idempotence: 讓每次同樣的 Input 得到同樣的 Output。不變性 ( Immutability ) 的資料結構讓我免費得到 Idempotence。努力讓 mutable state 的數量越少越少,mutable state只有一個owner。

React.js 讓工程師照著上面的兩個規則。
React 是 宣告式的 ( declarative ) JQuery。

React

 > Data 輸入 => virtual DOM 輸出。
 > 當資料改變的時候,就整個重繪,所以少掉很多 State。

Demo Example (從15- 分)

Demo on jsfiddle.net jsbin.com
一直在看Code

2015年11月3日 星期二

研究 Node.js 和 Express.js 有感

簡單來說網頁設計,就是設計ㄧ個讓在給了Key 後把相關資料轉換成網頁的 function。

Node 提供ㄧ個可以用 JS 與其溝通的 non-blocking http server。Express 在上面提供了簡易建立 RESTFUL API、在頁面間 (在 server 上) 傳遞資料的方法。

從外部來看,就是一個 JavaScript 程式,然後你對它送一些 Request,他就會吐 http response 回來。

Http response 包含了資料 ( ex: 文章、作者、照片、標題、按鈕文字 ) 和 UI/排板 ( CSS / HTML / client-side JavaScript )。通常資料是不重複的。但根據不同的資料,UI 很多重複的地方就變成用 UI Template/UI 元件來表示。

傳統產生網頁的方式是把資料和 UI 原件混成一個個各別的網頁然後傳給 Browser 畫出來;最近流行的方式是把資料和UI原件分別傳給 Browser,在 client-side browser 再用 JavaScript 把資料和 UI 原件組合成網頁。

近年流行的 json 是一顆用 ( key:value or array ) pair建起來的關聯式資料樹。因此後端資料庫不再用關聯式資料庫,用簡單 NoSql 資料庫 ( 即 dictionary ) 就夠了。

簡單來說現代的網頁開發就是開發一個程式:從後端抓一顆 json 資料樹,然後轉成前端美美的 DOM Tree。就是模組化的 Data Visualization,這樣想一切都輕鬆多了。


這樣的想法很自然的催生了一堆 UI 的程式庫,像是 Angular.js 和 react.js,然後還有 mobile上的 react native。

Node.js 的發明人 Ryan Dahl 在 Yahoo 介紹 Node.js (2010)


Node.js主要專注在Performance。Node的特點是對I/O有特別的處理方式,特別快。

在有100個client下,每次回應1MB的Benchmark
node  822 reqs/secs
nginx 7xx reqs/secs
others  1x reqs/secs

node用javascript寫,但居然跑的比純C寫的nginx還要快!!! nginx快的原因是它不用一個Process來接處理一個 client,而是用Event Loop。

All about non-blocking I/O

non-blocking I/O:   L1 / L2 / L3/Memory <             250 cycles
blocking I/O:          disk / network           > 41,000,000 cycles (ex: select .. from database)

應該用不同的方式來處理這兩種I/O,他們從根本上根本不一樣。L1 cache像是拉開抽屜拿東西,存取memory像是到樓下買個東西回來,但從硬碟上拿東西像是跳上飛機、飛到地球的另一邊再飛回來一樣。

要用non-blocking I/O,就要全部的API Call都用non-blocking I/O,即時用了第三方的程式庫去存取資料庫,可能就變成blocking I/O了。要實現的方法有幾種,event loop、using callback function。

database_query("select ...",  callback function); //應該這樣做

但是大部份的語言都不預設這種寫程式的方式,如果要達成這種功能,通常要花很大的心力,最後大部份程式員最多就做到多個執行緒,然用用一個執行緒去處理一個I/O Operation。

但Javascript是個特別的例外,因為這語言從第一天就一直在處理瀏覽器的Event Loop,callback function、anonymous function、Closure 是在平常也不過的方法了。Javascript的文化就是Event Programming。

Node.js 就是讓你單純只用Event、non-blocking的infrastructure來寫高度concurrent的程式。設計的目標是任何的function都不能直接存取I/O,一定要用callback的function來處理。其他特性還有專注在Low level、什麼都用串流、不強迫buffering、提供DNS/HTTP/TLS的內建支援。

HTTP包含: Chunked encoding, Pipelined message, hanging message.

Node的API要用client side JS Programmer熟悉的慣例,幾乎100% MIT/BSD Licensed。(唯一例外是openssl)

架構


Javascript               Node standard library
------------------------------------------------------------
                               Node binding
C                             -------------------------------------
                               V8   Thread pool & event pool

努力把使用者關在non-blocking的環境,用C語言當作屏障... XD


Node execution stack : only one stack

| load(index.html)    |
-------------------------
| http_parse(1)          |
-------------------------
| socket_readable(1) |
-------------------------
| ev_loop                  |
-------------------------
           | |
           V

| file_loaded()           |
-------------------------
| ev_loop                  |
-------------------------

然後是一大堆的小段程式範例。
包含web server和 file system的non-blocking I/O.
然後是2010年接下來的 Road Map。