分類: 程式語言

Node.js實作Mutex(互斥鎖)防止緩存擊穿

Node.js程式語言

最近在工作上需要寫一隻會高併發的API。為了不讓DB被灌爆,所以在DB前面再加一層redis當緩存,並且設定TTL過期,因此整個API程式流程大致上變成:

  • 從redis取資料 -> 成功取到資料 -> 返回

如果今天redis因為資料TTL過期導致取不到資料,這時候才訪問DB:

  • 從redis取資料 -> 沒有取到資料 -> 從DB取資料 -> 成功取到資料,將資料回存redis並設定TTL -> 返回

 
轉換成程式碼的話看起來也並沒有特別的複雜:

const item = await redisClient.hgetall(itemKey);
if(item) {
	return item;
}

const sql = 'SELECT * FROM `Product` WHERE `id` = ?';
const [rows, fields] = await dbConnection.query(sql, [itemKey]);
if(rows.length > 0) {
	const [item] = rows;
	await redisClient
		.multi()
		.hmset(itemKey, item)
		.expire(itemKey, 60)
		.exec();
	return item;
}

return null;

 
不過,魔鬼藏在細節裡。Node.js雖然說是使用單執行緒在執行,但因為用到了async/await的語法,所以實際上當遇到異步函式時,Node.js會將異步函式丟進event loop等有空時才執行,並且當promise被resolve或reject後才從剛剛await處接續往下。這就讓在高併發的情況下,會發生如下圖中的狀況。

完整圖解Node.js的Event Loop(事件迴圈)

Node.js程式語言

最近當完兵在面試Backend Engineer的缺,想把主力放在Node.js上,因此又把一些Node.js的核心觀念拿出來啃了一遍。網路上太多把前端瀏覽器的Event Loop與Node.js的Event Loop混著講的文章了,因此趁記憶猶新時把Node.js的Event Loop記錄一下,釐清一下觀念。

在開始前先做個小測驗,如果你都能答對代表你的觀念很清晰,這篇文章的內容你應該都懂了。如果答錯了就請繼續往下閱讀吧。

請寫出各個console.log();輸出的順序:

console.log('start');

process.nextTick(function() {
  console.log('nextTick1');
});

setTimeout(function() {
  console.log('setTimeout');
}, 0);

new Promise(function(resolve, reject) {
  console.log('promise');
  resolve('resolve');
}).then(function(result) {
  console.log('promise then');
});

(async function() {
  console.log('async');
})();

setImmediate(function() {
  console.log('setImmediate');
});

process.nextTick(function() {
  console.log('nextTick2');
});

console.log('end');

挑戰一下自己先別往下滑

再往下滑就是解答嘍!!

白話文講解支持向量機(二) 非線性SVM

Python機器學習程式語言

先恭喜一下我自己煎熬了四個月終於退伍了XD。趁著退伍後的空閒時間趕快來補齊之前還沒寫完的SVM續集。😝

在上一篇白話文講解支持向量機(一) 線性SVM中我們學到了線性SVM的損失函數、目標函數,以及調整超參數C來決定決策線在訓練時對於資料點的靈敏程度。本篇我們將來介紹當資料不是單純可以線性分割時,非線性SVM是如何分類資料的。

以下是本篇講解的順序:

  • 線性SVM(上一篇)
  • 特性
  • 損失函數
  • 目標函數
  • 目標函數中的正規化項

 

白話文講解支持向量機(一) 線性SVM

Python機器學習程式語言

大學畢業後7月正式入伍登入了國軍online。在軍中由於有太多的時間可以發呆思考人生,所以想說利用這些時間把一些機器學習的模型在頭腦裡跑過一遍。SVM在機器學習領域裡算是一個滿經典的演算法,因此值得趁記憶猶新時花些篇幅記錄一下,希望可以以我自己比較白話的理解方式介紹SVM。

我將以下面的順序講解SVM,先讓大家有個大致的概念:

  • 非線性SVM(下一篇)
  • 特性
  • 實際上的運作方式
  • 預測新資料
  • Kernel
  • Kernel Trick
  • 目標函數

 
本篇會先從線性SVM開始講起,如何使用一條直線、一個平面或是在更高維度的任何線性函數來達成二元分類。除了線性的SVM以外,也有非線性SVM。不過我覺得線性SVM跟非線性SVM還是要明確分開來講比較好,不然像我在自學的時候就把這這兩個混在一起看,導致在kernel的觀念那邊卡關很久。

因此下一篇我們才會進入非線性SVM,假設資料不是單純可以線性分割時,SVM可以怎麼變化達成非線性的切割,進而帶到非線性SVM使用的kernel概念、以及實際上電腦在訓練時都會採用kernel trick優化減少運算量。

 

採用YOLOv3模型的自助餐菜色自動辨識結帳系統

Python機器學習程式語言

大三時因緣際會在國外留學時修了一堂人工智慧的課,從那時起就被機器學習的魅力深受吸引:即便對問題只有稍淺的domain knowledge,但是只要透過大量的資料去做訓練,依然可以使模型學會這些資料之間的關聯(當然對問題的domain knowledge懂得越多,對於資料的敏銳程度也會比較高;在feature selection時比較容易挑出好的feature,訓練時converge的速度也會比較快)。

回國後大四上要開始做畢業專題了,我找了幾個隊友以及一位從大一關係就還不錯專長是影像處理與訊號處理的教授討論方向,最後決定結合機器學習與影像辨識,做出一個概念性的自助餐菜色自動辨識結帳系統。


(將打完的自助餐放在攝影機下,系統即可辨識出菜色、結帳金額及卡路里)

 
本篇將以以下的順序紀錄整個畢業專題從無到有的過程: