跳至主要内容

3 篇文章 含有標籤「go」

檢視所有標籤

MultiQueue:並行安全的寬鬆優先權佇列實現

· 閱讀時間約 9 分鐘
Vincent Chi
Software Enineer, Backend

前陣子,我耗費不少心力在撰寫 jr-dragon/olivine,這是一個為教學目的設計的純 Go 語言實現的 Redis 相容服務。

在研究的過程中,我不禁開始思考關於 Priority Queue 這個資料結構,在大學課程的訓練中,我們往往被教導著:Priority Queue 就是 Binary Heap 的一種應用,然而實際上這這種說並不完全正確。

Priority Queue 作為一種抽象資料結構,其實並沒有規定底層必須怎麼實現:只要能夠符合特性定義,單純的陣列都可以稱其為 Pirority Queue:

type pq []int

func (q pq) Push(n int) {
q = append(q, n)
}

func (q pq) Pop() (int, bool) {
if len(q) == 0 {
return 0, false
}

max := q[0]
for _, n := range q {
if max < n {
max = n
}
}

return max, true
}

以上是一個由陣列(Go Slice)所構成、符合定義的 Priority Queue,但顯而易見地其複雜度不盡如人意。

以 devcontainer 設計開發環境

· 閱讀時間約 4 分鐘
Vincent Chi
Software Enineer, Backend

因應近期在開發 Side Project 時與前端工程師有協作上的需求,原本想要沿用 Laravel 環境設定 中提到的 Local 與 Develop 環境,不過喜新厭舊的我在觀望了一陣子的 devcontainer 之後,決定來嘗試一下。

註:devcontainer 在 VSCode 上的支援性較好,在 JetBrains IDEs 上會有一些奇奇怪怪的小問題(但是我個人仍然是偏好使用 Jetbrains IDE,Jetbrains 該給業配了吧

In Memory SQLite 的備份與還原

· 閱讀時間約 3 分鐘
Vincent Chi
Software Enineer, Backend

近期在研究一個相對有趣的問題:如何讓 In-Memory SQLite 能夠在程式結束時進行自動備份,並且在程式啟動時自動套用最新的備份。

如果想要備份 SQLite,有幾種方式:

  1. 使用 .dump 將指定表中資料匯出為 SQL
    • 優點:將資料轉存為 SQL,如果需要跨資料庫(例如 sqlite to mysql)的話相當方便
    • 缺點:檔案為 UTF-8 純文字檔案,所需容量較大且需要轉換 SQL 故執行時間會較長
  2. 使用 VACUUM INTO 指令,將 DB 檔案轉存為獨立的檔案
    • 優點:執行後會將資料碎片彙整,進一步降低所需容量;且生成的檔案可以直接被 sqlite 客戶端讀取
    • 缺點:寫入時在極端情況下(例如當機或停電),並不保證資料能夠被完整寫入
  3. 使用 Online Backup API
    • 優點:直接鏡像備份兩個 SQLite 連線;效率較 VACUUM 來得高
    • 缺點:沒有直接的指令,需使用 SQLite API 達成;因為是鏡像備份,所以包括源資料庫的資料碎片等亦會被保留