Raiven Kao

a piece of me

在習慣 go mod 後重新學習 git submodule

前言 使用 Golang 作為主要開發已經有五年的時間。最近因工作需要接觸到 Python 專案,並且該專案使用 git submodule 的方式來引用共同函式庫 common-lib-python。對於長久使用 Golang 的 go mod 的我來說,submodule 是一個相對陌生的概念。藉這個機會撰寫一篇文章,整理並紀錄一下 git submodule 的用法,也作為未來的參考。 這篇文章會假設已經對 git 的基本操作有一定程度的了解,並著重在 submodule 的概念、使用情境以及與 Golang 的 go mod 的差異比較。文章內容會以下列流程來呈現: 建立一個新的 Python 專案 my-python-repo 建立一個 Python 模組 my-python-module 作為 submodule 在 my-python-repo 中使用 my-python-module 作為 submodule 模擬需求變更,同時修改 my-python-repo 與 my-python-module,並分別發送 PR 與 Golang 的 go mod 進行比較 建立 Python 專案與模組 先建立兩個新的 git repo,分別是 my-python-repo 與 my-python-module。 # 建立 my-python-repo mkdir my-python-repo cd my-python-repo git init touch main....

2025-01-24 · 3 min · 548 words

Golang Composition over Inheritance

Golang 是一門簡潔有力的程式語言,相較於其他程式語言,更傾向於使用組合(composition)而不是繼承(inheritance),語言設計之初更是沒有提供繼承的關鍵字,這種設計哲學讓 Golang 在現代軟體開發中脫穎而出。 繼承固然有其優點,但在建構複雜的物件關係時,容易產生過於龐大的繼承層級結構。這使得程式碼難以閱讀和維護,就像是一棵盤根錯節的大樹,牽一髮而動全身。 過深的繼承層級會導致知名的「脆弱基類問題」(fragile base class problem),使得程式碼難以修改和擴展。 組合則不同,它鼓勵建立小型、專注的 struct,然後像樂高積木一樣,將這些 struct 組合成更大的結構。這種方式讓程式碼模組化,更容易理解和修改。 彈性 Golang 的 type system 支援我們靈活地組合各種 struct。可以建立一個新的 struct,並在其中「嵌入」其他 struct 作為其欄位。 type Car struct { make string model string year int } type Driver struct { name string car Car } func main() { myCar := Car{"Toyota", "Camry", 2020} driver := Driver{"John", myCar} fmt.Println(driver.name) // 輸出: John fmt.Println(driver.car.make) // 輸出: Toyota } 在這個例子中,Driver 透過組合 Car 來建立更豐富的資料結構。Driver 「has-a」 Car,而不是 「is-a」 Car,這提供了更高的彈性,讓 Driver 可以更專注在自身的邏輯。...

2025-01-11 · 3 min · 634 words

使用 Templater 來提昇 Obsidian 的生產力

這篇文章不涉及 Obsidian 完整使用說明以及 Templater 完整使用教學,僅以一個 use case 來展現如何使用 Templater 來提昇 Obsidian 的使用效率。 前言: 工作日誌,是一個甜蜜的負擔,有些人是因為公司要求,開始寫工作日誌,逐漸流於形式。 最初我也是因為工作需要「彙報」,才開始寫工作日誌。直到開始跑 scrum,開始明白 standup meeting 的意義,開始在意如何讓 stackholder 放心把事情交給我做,於是 參考了《SCRUM:用一半的時間做兩倍的事》以及實際執行的經驗,以下是我認為良好的彙報需要注意的關鍵因素: 昨天的進度:簡要說明昨天完成的具體工作,重點在成果而非過程。 今天的計劃:說明今天的工作重點,聚焦在需要達成的具體目標。如果是要跨超過一天的工作,也需要設定一個預計能完成的時間。 遇到的障礙:明確指出當前的問題或挑戰,並說明需要的幫助。當然也沒有必要什麼事都等到 standup meeting 才提出問題,有障礙應當即時反應。 與其他團隊或成員的依賴:說明需要其他人或團隊支持的地方,確保協作順暢,例如後端需要寄送的 email 內容,需要前端協助產生 html 等等。 以終為始、以成果為導向:聚焦於交付成果的進展,而非細節,例如:目前已完成 80% 的登入模組開發,預計明天可以驗收。 詳細的舉例不是這篇文章的重點,有空可以再寫成其他文章 D: 上述幾個要點,在工作日誌中被我濃縮成 markdown 的格式: XXXX-XX-XX 昨日: - 昨日1 - 昨日2 瓶頸: - 瓶頸 今日: - 今日1 - 今日2 Obsidian 高中時接觸了 markdown,大學接觸了 Hackpad,畢業後延續這個習慣,使用 Hackmd 來管理自己的工作日誌。 隨著時間的增長,開始發現 Hackmd 無論是官方 hosting 的免費版與企業版,或是 self-hosted 的 CodeMD,在單一大檔案編輯文件時,都會有明顯的延遲。若我將工作日誌拆成多個月份,又不好管理。...

2025-01-02 · 2 min · 328 words

2024 Recap

假如你的答案更好,書本上的答案一點也不重要。 2024 年 12 月 13 日過世的查爾斯.韓第,在《你拿什麼定義自己?》中如此寫到,這句話也在 2024 年改變了我做決策的方式。 在 2022 年底寫了 2023 年展望,轉眼間兩年就要過去了,在 2024 年底紀錄一下這一年的回顧,以及未來的展望。 健康 今年是特別注重健康的一年,無論是身體健康或是心靈健康。 年初的健康檢查,發現陪伴我四年的輕度脂肪肝消失了,於是開始不忌口的胡亂飲食。八月底看不下去體重的增長,開始戒零食與珍珠,也開始跑健身房有氧與無氧,從高點的 75 公斤掉到 68 公斤。明年的期望是體脂肪降到 15% 並且同時能夠增肌到體重 70 公斤。 × ❮ ❯ 在三月也開始牙齒矯正,好在不需要拔牙,約莫一年到一年半即可以完成矯正。傳統矯正的缺點是鐵線會一直刮到嘴皮、需要專門的牙籤才好剔牙齒,但感到最不方便的是,需要完成矯正才能捐血 QAQ。 在年中旬,發現有些 Burn Out,好在身邊的同事與朋友們,願意花時間開導、給與職涯上的建議,才能順利的調整過來,今年感受到滿滿的溫暖。 旅遊 今年原本是預計要去高島縱走、合歡山、大霸尖山等等,但因為突如其來的地震、颱風而全數取消,不過透過照片回顧,今年還是去了不少地方的。 跨年 Murphy 考到了駕照,跨年去到了台東,沒有駕照的我就當個優良的副駕,較特別的是,我們在紅烏龍的故鄉鹿野,誤打誤撞進入了碧蘿園。 × ❮ ❯ 台北大縱走第四段 去年開始找同事爬山,今年終於成團出發。(照片合併到下面) 金面山+大崙頭尾山 原本也有很多場爬山的約定,指可惜地震 + 颱風導致幾乎整個夏天的約都取消了,希望明年可以再次出發。 × ❮ ❯ 過年 今年過了一個很特別的年,被 Murphy 邀請到台中/彰化度過了初二到初四,也是藉機測試新購入的 Voigtlander 28/1.5。 × ❮ ❯ 大屯山西峰+面天山+向天山 剛好遇到連續好天氣,讓我們可以到向天池內走走,原本是想要大屯山連峰逆走,但向天跟面天走完後就有點小累,於是把最「好玩」的大屯西峰走完就回家了。 × ❮ ❯ 柚香路跑 第一次在濃霧中路跑,不過 2025 的不會紀錄成績,就不參加了吧(笑...

2024-12-31 · 2 min · 369 words

開源軟體的雙面刃:免費背後的隱藏成本

每日例行地開啟最愛的 Save for later,準備觀看有哪些部落格更新、產品釋出新版本時,一行醒目的提示告訴你「我們即將關閉伺服器」。 錯愕,這是 2024 年十月底每一位 Omnivore App 難民的心情。 一、開源軟體的普及與迷思 說到開源軟體,不外乎就是 free 或是 freedom 的軟體,可以說是免費的軟體,也可以說是自由的軟體。 早期的 LAMP Stack 相較於 Microsoft 的 Windows Server、IBM 或是 Oracle 付費的服務,每個組件都是免費的,廣泛受到 Geek 到大中小型企業的使用 同時,開源軟體顧名思義是開放原始碼,在授權許可下可以自由使用、修改、分享,許多人將開源與安全劃上等號。 二、開源軟體的安全現況 多雙眼睛的侷限 即便開放原始碼,所有人都能查看開放原始碼,如果有任何 bug 或是安全漏洞,都「應該」會被發現。 我使用「應該」一詞,正因為許多人(包含我)在安裝開源軟體時,就如同安裝閉源軟體一樣,並不會查看全部的程式碼,確認安全後才進行安裝。而是做一個「大家都看過了,應該很安全」的假設。 例如當你想用 Nginx 取代 Apache 時,可能僅會比較兩者的 feature 與 benchmark,並不會查看內部 tcp socket 是如何管理等等,或是 buffer overflow 時的錯誤處理機制。 開源是否暴露更多漏洞? ####安全問題的挑戰 當我們將軟體開源,等於是將所有安全問題也給暴露了出來。 舉例來說,假如我們 self-hosted 一個 NAS 服務,這個 NAS 使用指定的 port 進行 web 與 API 的存取,例如 :8787。 當一個 Hacker 看到該 NAS 的 Auth 並沒有任何 rate limit,就可以直接在 NAS 內進行 port scan 或是 brute force 攻擊,取得這個 NAS 服務的控制權。...

2024-11-01 · 2 min · 263 words

Golang 1.22 中 http routing 的改進

Golang 作為一個偏向 server 應用的程式語言,一般的 web server 並不會直接使用原生的 package net/http,而更多的使用 gin-gonic/gin 或是 gorilla/mux,後來也有 labstack/echo 以及 go-chi/chi 等等選擇,在效能、輕量、好維護、好擴充中,都能找到對應的 third party package,其中的原因不外乎是原生的 package 提供的功能過於簡潔。 好在 1.22 中,官方改進了 net/http 中對於多工器、路由,甚至出了一篇部落格,現在更可以「大膽的」直接使用 standard library。 Path Parameter 若要將應用的 Web API 定義成 RESTful,我們會使用 /資源/{資源唯一識別符}/子資源/{子資源唯一識別符} 來定義路徑。假如要獲取一個使用者的訂單,則會使用 GET /users/1/orders 來獲取。在 1.22 以前,我們只能定義到 /users,再自行解析往後的 path: http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) { subPath := strings.TrimPrefix(req.URL.Path, "/users/") if len(subPath) == 0 { xxx } else { ooo } ... }) 而在 1.22 中新增了 net....

2024-10-30 · 4 min · 656 words

使用 TinyGo 與 Raspberry pi pico 實現溫濕度感測器

前言 作為嵌入式系統學習的微小專案,我決定使用 TinyGo 來實現一個簡單的溫濕度感測器。過去我大多使用 Arduino 作為微控制器(MCU)開發平台,但這次想嘗試使用 TinyGo 來進行單片機的學習。 TinyGo 是 Go 語言的一個子集,專門針對小型設備和微控制器進行了優化,使得我們可以在資源受限的硬體上運行 Go 程式。 全部的程式碼都可以到 omegaatt36/pico-bme280 中找到。 硬體選擇 Raspberry Pi Pico 我選擇了 Raspberry Pi Pico 作為本專案的主控板。Pico 是一款基於 RP2040 晶片的微控制器開發板,具有以下特點: 雙核 ARM Cortex-M0+ 處理器,時脈可達 133 MHz 264KB 的 SRAM 和 2MB 的板載閃存 支援 USB 1.1 主機和設備功能 低功耗睡眠和休眠模式 可編程 I/O(PIO)狀態機 30 個 GPIO 引腳 便宜 價格僅需要 5 美元,後繼款的 Pico 2 仍然維持 5 美元,還額外增加了 RISC-V 架構的支援,可以一次玩到兩種處理器架構。 Pico 的這些特性使其非常適合用於各種嵌入式專案,包括我們的溫濕度感測器。 BME280 感測器 最初我購買了 BMP280 感測器,但後來發現它只能測量溫度和氣壓,無法測量濕度。因此,我轉而選擇了 BME280 感測器,它可以同時測量溫度、濕度和氣壓。...

2024-10-02 · 2 min · 337 words

A smarter way to change directory: zoxide

在日常的開發工作中,我們經常需要在不同的目錄間切換。雖然 cd 命令已經足夠好用,但如果有一個更聰明的工具能記住我們最常用的目錄,並讓我們用最少的按鍵就能快速跳轉,那豈不是更棒? 這就是 zoxide 的用武之地。zoxide 是一個由 Rust 編寫的「更聰明的 cd 命令」,靈感來自 z 和 autojump。它會記住你最常使用的目錄,讓你只需輸入幾個字符就能快速跳轉。 zoxide 的主要特性 自動匹配: 不需要輸入完整路徑,zoxide 會根據輸入自動匹配最相關的目錄: 自動紀錄過去的目錄: zoxide 會記住你最常使用的目錄,讓你只需輸入幾個字符就能快速跳轉。這些資料可以使用 zoxide query 來查詢,或是 zoxide edit 來管理。 互動式選擇: 結合 fzf,可以互動式地選擇目標目錄 輕量快速: 用 Rust 編寫,啟動迅速,幾乎不會影響 shell 的啟動時間 安裝與配置 zoxide 的安裝可以參考 官方文件,我們就不多贅述了。 安裝完成後,我們需要在 shell 的配置文件中添加初始化命令。以 zsh 為例,在 ~/.zshrc 的末尾添加: eval "$(zoxide init zsh)" 重新打開終端或執行 source ~/.zshrc 後,zoxide 就可以使用了。 使用方法 zoxide 的基本用法非常直觀,經過自動執行 zoxide init zsh 後,我們可以使用 z 和 zi 自動匹配: ❯ ls boo bar baz ❯ z bo ❯ pwd /home/raiven/boo 即便沒有輸入完整路徑,也能夠自動匹配最相關的目錄 ❯ pwd /home/raiven/dev/omegaatt-blog ❯ z ❯ pwd /home/raiven ❯ z blog ❯ pwd /home/raiven/dev/omegaatt-blog 互動式選擇: ❯ zi ~ < 98/98(0) 296....

2024-09-24 · 1 min · 130 words

使用 Bitwarden 與自架後端 Vaultwarden 來管理密碼與 2FA Authenticator

在尋覓有哪些 self-hosted 專案好玩時,偶然發現了 1password、LastPass 的開源替代方案,甚至後端資料庫能自架,決定架來用用看。 使用 Bitwarden 來管理密碼 Bitwarden 是一款流行且功能強大的密碼管理工具,它提供了一個安全的方法來存儲和管理所有密碼。作為一個開源產品,Bitwarden 允許用戶選擇自行托管其服務,這意味著用戶可以在自己的服務器上運行 Bitwarden,從而更好地控制自己的數據安全。 Bitwarden 的特點 安全性: Bitwarden 使用端到端加密,確保只有您可以訪問您的密碼。 跨平台支持: 支持 Windows、macOS、Linux、Android 和 iOS。 易於使用: 提供直觀的用戶界面和簡單的操作流程。 開源: 開源,增加了透明度和安全性。 Bitwarden 同時支援基於時間的一次性密碼,讓 TOTP 也能自動填入。也能透過 github.com/scito/extract_otp_secrets 來提取 Google Authenticator 內的 2FA 資訊,儲存進 Bitwarden 中。 Bitwarden 開源了 client 與 server,在 server 端的選擇有以下: 使用 Bitwarden 提供的官方服務,又分為免費跟付費,但這個選擇就跟 1p 沒太多區別。 自架 Bitwarden 提供的 open source server,由於是使用 C# 與 mssql,吃的記憶體著實太多。 自架 Bitwarden 相容的後端,我採用的是 rust 實做的 Vaultwarden,搭配 sqlite,記憶體使用量與官方的 C# 不是一個量級的。 Bitwarden 架構 bitwarden 的 local storage 都是儲存加密後的密碼資料,不會使用明碼儲存,故上傳到 server 上的也僅僅是加密後的密碼資料。...

2024-09-01 · 3 min · 505 words

在 Firefox 上使用 PWA 將網頁應用安裝成 Desktop App

前言 開應用時,跨平台的桌面解決方案時常困擾開發者,在 Linux Desktop 上要支援多種桌面協議與桌面管理系統,更是複雜許多。時常會看到 Electron 等等基於 chromium 的技術。 當然也可以像是 zed.dev 這樣的 geek 精神,自己寫了一套跨平台的 GUI 框架,但多數新創公司可能沒有這些資源來實現。例如已經非常成熟的 Notion.so、Obsidian 等等都是基於 Electron 實現的。 我並非一個 anti-Electron 或是 deGoogle 的人,但試圖找到其他解決方案正式樂趣之所在。 PWA(Progressive Web App) 詳盡的 PWA 技術可以到 mozilla 的文件中查看,對我來說只要可以達到目的:可以在 Windows、Mac、Linux 上封裝成 Desktop Aplication 即可。 官方支援 mozilla 官方有一個文件針對「安裝網頁應用到桌面環境」的歷史講解,可以參考官方文件。 文中提到過去將網址「儲存」在桌面上的類似「書籤」的方法(SSB),以及與 PWA 的不同之處:PWA 的使用者資料是儲存在桌面環境中。 PWA Add-on 上述文件內有提到需要使用 Fan-maded 的 PWA Add-on 來安裝 PWA:Progressive Web Apps for Firefox by Filip Štamcar。 他是一個開源的 Firefox 擴充套件(filips123/PWAsForFirefox),具有完整的文件。 安裝過程 在 Firefox 瀏覽氣上安裝 PWA Add-on 瀏覽器會自動跳到設定頁面,首先會需要同意 EULA 接著會需要安裝 connector,需要透過該 connector 才能連結瀏覽器本身與 extension。 connector 由 Rust 編寫,使該 extension 可以在跨平台的桌面環境中管理 firefox 設定檔、runtime 等等未開放給 extension 存取的資源。 Windows: Windows 的 connector 除了手動安裝外,也推薦使用 winget 來安裝,類似於 apt/yum 的套件管理工具。 Linux Linux 的 connector 可以到 github release 上找到,例如我的作業系統是 OpenSUSE Tumbleweed,則可以下載 ....

2024-08-25 · 2 min · 226 words