They say, “Evil prevails when good men fail to act.”

  • What they ought to say is, “Evil prevails.” - Yuri Orlov, Lord of War

Celebrating a Milestone

工作來到一個里程碑,其實因為不同的工作節奏所以心得也是有好有壞;壞的部份就留在心裡等到哪天爆炸時再說好了,先來講講正面的事情也許心態上會比較樂觀一點 (? 更多的自省 因為大半時間都自己獨處在一個私人的空間裡,最主要是能夠自我思考的時間變多,雖然工時還是相對地緊,但看待一些事情的想法會比以往再成熟一點;面對工作的結果產生與決策也會在第一時間先反省還有哪些不足的地方或需要改進的點。 自己也一直在反思若換成別的同事站在這個位置會採取什麼做法來處理工作,更會去看別人怎麼發揮長處,試著更進一步用不同的角度看待問題,也試著提醒自己心態上要更穩重。 更多的溝通 這邊是指內部的橫向溝通,向上管理這塊我直接放棄。自己花了非常多時間在橫向溝通這塊,確保工作的目標一致並且達成共識,也協助問題的排查處理,多一個人多一個角度看待問題就多一個解決問題的方法。 當然還是有很多的進步空間,例如遇到比較資深或比較自我的同事就要花更多思考力氣去溝通跟協調。不過都是自己人還比較好處理,跨部門的狀況反而是最難搞的,也是最心累最沒人可以幫的。 多半遇到的工作危機都是在這些跨部門溝通不良的情況下發生,信任不足,說空話,各自為政,都是滿關鍵的心態問題累積造成的。 更多的技術成長 學到很多是真的收獲滿滿,特別是 reivew 別人的程式碼真的是五花八門花樣百出,很難想像過去年輕的自己寫出這樣的程式會被前輩給予什麼樣的評價。 對於軟技術該成長到什麼地步倒沒有標準答案,通常是看得越多就越顯得自己無知,回去看收件夾滿滿的待看清單就知道沒有所謂的盡頭。 過去的工作經驗其實也是在提醒自己,很多缺點在十年前就知道了,也是因為這些缺點讓自己走向不同道路;中間好幾次機會在招手時,自己也是心裡知道這些缺點都一直存在,再往下掉實在沒有意義,只是萬萬沒想到今天這一步還是算錯。 挨著性子先把自己的情緒穩定,檢討看看是不是能夠有什麼樣的工作調整好讓自己能在這個位子上繼續發揮,很多時候面對的不是單純工作本身,而是人與人之間的政治關係,這種困境不是找誰誰誰出面溝通就能解決的,在這種醬缸文化裡提出問題的人反而還比較危險,特別的是如果本來的圈子就不是交集的話,摸摸鼻子也不能再多做點什麼。 下個 milestone 就待續吧。

September 11, 2023 · Keanu Pang

Rust Extensions with VS Code

最近在初學 Rust 然後為了要在 VS Code 裡能有較好的開發體驗,所以找了幾個還不錯的 extensions 方便使用。 rust-analyzer 必裝的工具,我自己是安裝 Pre-Release 的版本先享受比較新的功能,目前使用上算穩定。 Event Better TOML 會幫忙將 toml 檔案內容檢查語法跟 syntax highlighting,另外也有貼心的 formatting 跟 folding 功能,在編輯 toml 檔案會方便很多。 crates 這工具最讓我驚豔的功能是在編輯 Cargo.toml 檔案的 dependencies 時,可以做版本的檢查,引用的版本如果沒問題就會顯示綠色勾勾,這其實會給開發者比較大的信心確認 dependency 版本: CodeLLDB 為了能 debug Rust 所以需要裝上這套工具,就可以在指定的中斷點上查看變數跟 call stack 等 debug 操作。 就目前來說,這幾個工具已經有滿足需求,在開發上的體驗也滿正面,已經很久沒有花時間力氣在 VS Code 上面,希望這個過程能一切順利。

September 2, 2022 · Keanu Pang

My Mac Dev Tools

update 2022-09-02: Edge Extension 部份加上 SwissTransfer 服務 最近正在整理公司電腦的作業環境,先集結成工具清單這樣方便之後換電腦就可以快速 setup 好。做程式開發常用的工具軟體就不列上去了,反正該做什麼工作就會對應到什麼軟體,基本上大家會使用的都是那幾套,所以這邊只記錄我自己偏好使用的工具集。 Menu Bar Shuttle 非常老牌的 SSH 快速啟動器,只要一個簡單的設定檔就可以把常連的 ssh 登入資訊建立成清單方便快速點選就可以開 terminal 連上;開發環境通常自己會在遠端再設定好 passwordless 登入。這種小工具其實也不用常常更新只要專做好這個重點功能就很好用了。 Input Source Pro 在不同 Apps 間切換常會遇到輸入法的干擾,之前看到有人分享這個工具就是解決輸入法的問題,可以為每個 App 設定專門的規則把鍵盤鎖在指定的輸入法,真的是完全解決我們東方人在切換輸入法的困擾。 Raycast 用來取代以前在用的 Alfred,對我來說只要能快速開啟要操作的 Apps 這個功能就好。 Dato 在角落顯示日期時間等資訊,這很重要。點了日期之後會下拉出 calendar 的資訊,這更重要更方便。所以自然也成為我常用的工具之一。 Shottr 用來截圖之後可以有基本工具對截圖內容做標註,是目前找到算美觀且簡單方便操作的截圖工具。 Magnet 在接大螢幕時比較常會將重點的視窗都排列好,所以都是靠這個工具來快速設定。 MonitorControl 也是在外接螢幕時很方便可以設定顯示亮度跟音量調整,必備的基本重要工具之一。 coconutBattery 可以在 menu bar 上顯示比較直覺得的電池電量的基本資訊,比原本 MacOS 陽春的電量顯示好用多了。 Folder Peek 這是最近才掛上來的工具,主要是可以把工作上常會用到的幾個工作目錄都設定快捷入口,方便在 menu bar 上直接切換過去。 Desktop Tools SmartGit Git 工具的唯一首選,我有付費 lifetime 的授權,用了七八年吧我想完全沒有缺點可講。每每看到同事還在為了 merge/rebase 跟檔案 conflict 問題在 Sourcetree 裡胡搞我就內心一把冷汗。...

August 5, 2022 · Keanu Pang

套件組合技經驗:JSON Server

前陣子因為在開發環境需要有個簡易又不會太粗糙的 mock server,所以快速用短短的時間把幾個套件組合串起來,成為基本可用的迷你 project,最主要還是拜豐富 NodeJS 的生態系所賜,很多東西都有現成可用幾乎不用多寫幾行程式碼,原則上就是可以推到開發環境。 一開始先找到最熱門的 json server 就是 typicode 的專案,跑起來基本上已經符合需求,所以從這邊開始來組合。 如果是用程式碼方式建立 json server 來做客製化,其實骨子裡就是 express web framework,所以用法都是一樣: const https = require("https"); const devcert = require("devcert"); const jsonServer = require("json-server"); const server = jsonServer.create(); server.use(jsonServer.defaults()); server.use(jsonServer.rewriter(require("./routes.json"))); server.use(jsonServer.router("api.json")); async function start() { let ssl = await devcert.certificateFor("api.dev"); https.createServer(ssl, server).listen(8443); } start(); 開發環境希望也是走 HTTPS 方式所以用到 devcert 掛了一個自簽的開發用憑證就可以跑 HTTPS 了,如上幾乎就是開箱即用的 server。 由於需要 db.json 檔裡面就是擺好被視為資料庫的 JSON 內容,然後依 request 的 HTTP method 進行資料的 CRUD,但也因為這個很棒的特性所以為了我自己的需求只好魔改原本程式變成 json-server-deformation。...

July 4, 2022 · Keanu Pang

試玩 Hummingbird 的 middleware

之前為了測試 Hummingbird 這個輕量 server framework 所以做了一個叫 LocalWeb 的 web project,主要是用來讓使用者在開發環境下方便地瀏覽與下載檔案;結果沒想到內建的 middleware 就幾乎把所有事情都搞定了。 當然還是要再加點工才可以方便使用,例如當我點進目錄時,希望可以一覽目錄下的檔案清單,所以就客製化做了個 middleware 掛上來,把目錄下的檔案展開成清單做成連結讓使用者可以下載,當使用者點到檔案時就直接串到 HBFileMiddleware 下載檔案這樣。 第一次嘗試實作 Hummingbird 的 middleware 所以花了點時間研究,目前實作版本可以參考這 DirectoryIndexMiddleware ,還好進入門檻不高就是,花最多時間反而是在刻呈現頁面的 html。 因為想呈現那種傳統 Apache web server 檢視目錄下的復古感,於是參考 HBResponseGenerator 這個 protocol,是用來產生 response 結果頁,基本上只要實作 func response(from request: HBRequest) 把刻好的 html 產生成 HBResponse 結果就可以。 成品像是這樣 DirectoryIndexPage 會在剛剛的 DirectoryIndexMiddleware 裡被用到回傳 response。 為了求快所以先不套用什麼 template engine,直接用 String 拼出來,之後有時間再研究看看 Stencil 還是 Leaf 哪個好用。 雛型差不多完成之後,想說要掛個 HTTPS 功能結果好像沒有那麼直覺。本來以為只要把 Configuration 裡的 tlsOptions 設定上去就好,然後就會被噴 warning 訊息: tlsOptions set in Configuration will not be applied to a BSD sockets server....

June 28, 2022 · Keanu Pang

幾個 WebView 互動功能筆記

好像只有在亞洲地區才流行這樣的組合,也就是從 native app 畫面開 web view 切到行銷活動網頁,再透過 javascript 方式跟 app 互動之後回到 app 裡進行後面的導頁與串行銷資料。 同步切換 app 畫面標題 為了要讓 webView 載入的網頁標題也能貼回到 App 裡的 navigation bar 上,所以在 viewDidLoad() 的時候,加上 addObserver: webView.addObserver(self, forKeyPath: #keyPath(WKWebView.title), options: .new, context: nil) 為了避免 leak,若有開啟 addObserver 更新 title 的話,在 ViewController dismiss 時要移除掉: webView.removeObserver(self, forKeyPath: "title") 顯示與取消 Loading 對應到 WKNavigationDelegate 可以透過下方兩個 methods 顯示或取消自訂的 loading view: func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { guard isBeingDismissed || isMovingFromParent else { // present loading view return } } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!...

March 22, 2022 · Keanu Pang

Snapshot Testing 的調整經驗筆記

我們的專案已經有 816 snapshot tests 並且有 600 張 snapshots,對專案的 coverage 約 47%,對產品的品質信心算是滿足夠的。 常被抱怨的點是在 CI 上跑 unit test 的時間太久,以專案 800 多個 snapshot tests 來說需要花上 15 mins 才能跑完,有時候開的 PR 一多幾乎都是在等待 unit test 跑結束,反而有點浪費在等待,目前只能採取折衷的作法,在特定的 branch 才啟動 unit test。 另外遇到的問題是不同機器配上對應的模擬器有時候會發生圖片”看起來”是一樣內容,但檔案大小卻差了幾個 bytes,所以程式比對圖片就直接認定 assert failed。原因是畫面在截取的當下可能仍會因為動畫等視覺效果,而造成產生的 snapshot 有些微色彩的差異。 這類問題的解法目前是走 duplicate image detection 的做法,也就是算出 snapshot 對應的 hash 值,然後將兩張圖片的 hash 根據 Hamming distance 來評估是不是一樣的圖片。 本來是在這邊 GitHub – benhoyt/dhash 看到這個,查了一下大概就是這幾種 hash 方法的比較,來源是 GitHub – ameingast/cocoaimagehashing 這裡: Name Performance Quality aHash good bad dHash excellent good pHash bad excellent 其實滿推崇 pHash 的方法,看 別人分享 iOS 上測試的過程 具有很多優勢;但因為 dHash 實作上相對容易,也滿多實作的作品可以參考。自己參考的實作是這兩篇:...

March 2, 2022 · Keanu Pang

Some useful CLI tools for myself

列幾個針對檔案操作的 CLI 工具是我在平日工作時比較常會用到的,最常用的就是 AG 了,在查找專案目錄下的特定關鍵字顯得非常方便快速。 AG: 用來查找目錄下的所有符合指定文字的檔案內容 fd: 用來查找目錄下所有符合指定文字的檔名 bat: 替換 cat 指令的好工具 sd: 尋找與取代指定檔案裡的文字內容,快又有效

February 16, 2022 · Keanu Pang

ArangoDB 的資料檔備份與還原

之前在測試 ArangoDB 操作特別註記下來的小筆記。 建立 dump unix> arangodump --server.endpoint tcp://<host>:<port> --server.database <database> --include-system-collections --collection _graphs --collection imdb_vertices --collection imdb_edges --compress-output false --envelope true 還原資料 準備好之前 dump 的資料,目前名為 dump,再執行如下指令,預設會找當前目錄下的 dump 目錄: unix> arangorestore --server.endpoint tcp://<host>:<port> --server.database IMDB --create-database --include-system-collections

December 9, 2021 · Keanu Pang

快速實驗與驗證功能的小工具 swift-sh

OK, 我們現在可以用 swift-sh 工具預先安裝到系統裡,這樣子之後只要做小型測試時只要單一個 swift 檔案,裡面標註 import 的敘述,就可以直接執行它。 先安裝好 swift-sh 工具: brew install swift-sh 然後就可以開始編寫 swift 檔案做小型的驗證: #!/usr/bin/swift sh import Foundation import PromiseKit // @mxcl ~> 6.5 firstly { after(.seconds(2)) }.then { after(.milliseconds(500)) }.done { print("notice: two and a half seconds elapsed") exit(0) } RunLoop.main.run() 要記得檔案最前面的 shebang 要寫明 #!/usr/bin/swift sh 的敘述,這樣系統才會去觸發 swift-sh 工具來處理;以及 import 第三方套件時,要在該行的最後加上註解是哪個 SwiftPM 的來源,甚至可以標註版本。 最後只要把這個檔案加上可執行權限就可以直接執行了。

December 3, 2021 · Keanu Pang