2014年12月19日 星期五

Git 小筆記

跟 git 太不熟了,在這邊堆放一些常用筆記

Branch:

git branch //看local branch(星號代表現在所在的branch)
git branch <bar> // 新增 "bar" branch
git branch -D <foo> // 刪除 "foo" branch


Checkout:

git checkout <bar> // 切換到 local 的 "bar" branch
git checkout -b <NewBranch> // 新創一個 branch 並同時 checkout 它
註:如需從origin拉下一個branch,需在本地創一個branch,checkout 後再拉 "origin/branchname"。eg. "git pull origin test"


回溯:

git log // 取得過往的commit,其中以 hex code 為 id
git checkout <hex code> // checkout 過往 commit
git show // 顯示當前所在
git checkout <branchname> // 回到 local 最新commit,eg. "git checkout master"


Tag:

git tag -l // 列出所有 tags
git tag -a <tag name> <hex code> // 針對某一 commit 打 tag
git push origin --tags // 上傳所有本機 tags 到 遠端

2014年8月28日 星期四

[SQL] Common Table Expression (CTE)

CTE 簡單來說就是依據一定的查詢條件建立一個暫時的 table ,以便重複性的 Subquery 查詢。

舉例來說,我需要從 pc, laptop, printer 三個 Table 取最貴的產品出來,想像的寫法可能是如此:

SELECT model FROM (
    SELECT * FROM pc
    UNION
    SELECT * FROM laptop
    UNION
    SELECT * FROM printer
)
WHERE price=(
    SELECT MAX(price) FROM (
        SELECT * FROM pc
        UNION
        SELECT * FROM laptop
        UNION
        SELECT * FROM printer
    )
)

我們會發現三個 table 的 UNION 被重複使用,非常麻煩。
這時我們可以將這三個 table 的 UNION 暫存成 CTE,藉由以下的方式。

WITH product AS (
    SELECT * FROM pc
    UNION
    SELECT * FROM laptop
    UNION
    SELECT * FROM printer
)

SELECT model FROM product
WHERE price=(
    SELECT MAX(price) FROM product
)

TADA~~~是不是簡單明瞭又方便勒?

2014年8月9日 星期六

ES6 新玩意兒 - Generator

ㄜ....其實不太能算是新玩意了,畢竟小弟也好一陣子沒有繼續追JS的近況(廢)。
實在是因為前陣子臉書上太多好友在提Kao和CO,當初用的express好像過時了一樣....

「不行!我還沒老啊!」

身為一個技術潮人,臨時抱佛腳是必要的,就從ES6的新規範 - Generator(迭代器) 開始吧。


宣告方式

Generator 的宣告方式比較特別,有點像是 function ,基本上是長這樣:

function * gen(){
    console.log("start!");
    yield "hello";
    yield "I'm Kevin";
    console.log("end!");
}

這個 gen 是一個ㄜ.....函式?總之,使用他後會返回一個 generator,像這樣:

var g = gen(); // g 是一個 Generator


這時,就可以拿它來做這樣的事:

r = g.next(); // "start!"
console.log(r); // { value: "hello", done: false }
r = g.next();
console.log(r); // { value: "I'm Kevin", done: false }
r = g.next(); // "end!"
console.log(r); // { value: undefined, done: true }


Generator.next() 回傳什麼?Value & Done!

value的形式不拘,端看generator的yield後接著什麼,會被放到value中。
至於 done 則是個單純的 boolean,告訴你這個 generator 玩完了沒。

看到這邊,聰明的你應該可以得到一個結論,generator中的yield有點像是中斷點,當 next() 被執行時,generator內的程式碼開始被執行,直到下一個 yield 的那一行。直到 generator的最後一行,回傳 { done: true }。


Generator 也能接收資料

在迭代的過程中,我們也是可以將變數傳入next中的:

function * gen(){
    var got = yield "hello";
    yield got;
}

var g = gen();

g.next("Good morning!"); // "Hello"
g.next(); // "Good morning!"

TADA~~~很好玩吧?


Generator 的特性及用途

因為迭代器中斷函數時,是不會卡死其他程式碼的,這樣的特性非常適合拿來做同步處理。

舉例來說....

舉例來說....

舉例來說....

舉不出來,看看大大們怎麼說好了:


基本上主要是用作「非同步流程控管」及「解決回調地獄(callback hell)」用途使用。


2014年7月29日 星期二

[JS] nextTick() 介紹與應用


Node.js是單線程的,除了系統IO之外,在它的事件輪詢過程中,同一時間只會處理一個事件。你可以把事件輪詢想象成一個大的隊列,在每個時間點上,系統只會處理一個事件。即使你的電腦有多個CPU核心,你也無法同時並行的處理多個事件。但也就是這種特性使得node.js適合處理I/O型的應用,不適合那種CPU運算型的應用。在每個I/O型的應用中,你只需要給每一個輸入輸出定義一個回調函數即可,他們會自動加入到事件輪詢的處理隊列里。當I/O操作完成後,這個回調函數會被觸發。然後系統會繼續處理其他的請求。

在這種處理模式下,process.nextTick()的意思就是定義出一個動作,並且讓這個動作在下一個事件輪詢的時間點上執行。我們來看一個例子。例子中有一個foo(),你想在下一個時間點上調用他,可以這麽做:
function foo() {
    console.error('foo');
}
 
process.nextTick(foo);
console.error('bar');

執行結果將會是:
bar
foo

我們也可以使用setTimeout()函數來達到貌似同樣的執行效果:
setTimeout(foo, 0);
console.log('bar');

但在內部的處理機制上,process.nextTick()和setTimeout(fn, 0)是不同的,process.nextTick()不是一個單純的延時,他有更多的特性,這裡有兩者的效能比較
更精確的說,process.nextTick()定義的調用會創建一個新的子堆棧。在當前的棧里,你可以執行任意多的操作。但一旦調用netxTick,函數就必須返回到父堆棧。然後事件輪詢機制又重新等待處理新的事件,如果發現nextTick的調用,就會創建一個新的棧。


什麼時候會使用到 nextTick ?

因為JavaScript是單線程的Runtime,如果有需要長時間的運算,往往會卡死其他的程式,例如事件觸發的 function。
更多應用情境可以參考原出處

也可以參考Fred的這篇:探討 NODE.JS 的非同步機制

2014年2月19日 星期三

在development模式下,assets 與 precompiled assets 衝突的解決方法

因為自己的開發環境效能往往比production server 還好,有時候我們為了求快,會直接在local 將 assets precompile 過,上傳到 production。
但繼續在 development 模式下開發時,就有個很機車的情況出現了,在 public/assets 中已經 compile 過的 assets 也被 require 進來,造成某些 lib 被 require 兩次而造成不正常的情況,當有新的變更時也會被舊的蓋過去。

查了一下發現可以針對 development 模式對 asset 路徑加上prefix:
  config.assets.prefix = "/dev/assets"

這樣子 request 的路徑就會變成 /dev/assets/application.js ,避免被precompile的assets搞亂。



2014年2月12日 星期三

修正 PG::UniqueViolation: ERROR: Duplicate Key Value Violates Unique Constraint 'Your_table_name_pkey' 問題

PG::UniqueViolation: ERROR: Duplicate Key Value Violates Unique Constraint 'Your_table_name_pkey'

今天在新產品上遇到了這個 error,查了一下發現是因為 postgres 因為不明原因而把 seq 搞亂了,以致於新增資料時使用到了既有資料的 id 。

了解問題所在後,循以下作法順利解決了問題:
  1.  rails db production
  2.  SELECT setval('your_table_id_seq', (SELECT MAX(id) FROM your_table));
打完收工~


2014年1月8日 星期三

Rails 的 i18n fallback 問題

當在 config/application.rb 中指定了 config.i18n.fallbacks 語系順序後,別忘了要 comment 掉 produciton.rb 中的 config.i18n.fallbacks = true
production 下的語系順序才會乖乖實現。