Hi! 這裡是我轉貼喜歡文章的地方,你也可以到推薦文章列表查看所有的推薦文章呦!

【每天推薦一篇文章】Geohash

前幾天我們有介紹過把地圖切成很多小方格的三詞地址,昨天跟朋友吃飯的時候想起另一個同樣切小方格的做法,決定今天就來轉貼這篇;

要認識 Geohash,可以先從第二篇文章中的這一段開始:

app 介面上會顯示出自己附近一個範圍內可用的計程車或者共享單車。假設地圖上會顯示以自己為圓心,5公里為半徑,這個範圍內的車。如何實現呢?

最直觀的想法就是去資料庫裡面查表,計算並查詢車距離使用者小於等於5公里的,篩選出來,把數據返回給用戶端。

這種做法比較笨,一般也不會這麼做。為什麼呢?因為這種做法需要對整個表裡面的每一項都計算一次相對距離。太耗時了。

現在用的比較多的資料庫 MySQL、PostgreSQL 都原生支援 B+ 樹。 這種數據結構能高效的查詢。地圖分塊的過程其實就是一種添加索引的過程,如果能想到一個辦法,把地圖上的點添加一個合適的索引,並且能夠排序,那麼就可以利用類似二分查找的方法進行快速查詢。

問題就來了,地圖上的點是二維的,有經度和緯度,這如何索引呢?

Geohash 同樣是把地圖切成多個小方格,但同時也有精度的概念。該區塊的索引長度越長,指定的區域也就越小

例如說 AAA 這個區塊在 AAB 旁邊,而 AAA 的這個方格又可以往下切分成 AAAA 和 AAAB。然後 AAAA 再繼續拆成 AAAAA…

同時因為編碼是用 Z 字形排列下去的,像是

AA AB
AC AD…

所以編碼相近的位置也會相近,也就可以用來判斷兩點距離

我們可以拿這兩個點的 Hash 檢查前幾碼是不是一致,來判斷兩點是不是同一個區塊內、又是大概多少精度的時候不在同一區

如果需要範圍大一點、模糊一點,也可以直接限制字串長度。如此一來就可以藉由這些切好的地圖區塊快速查詢附近的點和區域了

……

閱讀全文



【每天推薦一篇文章】最小可行性產品 (MVP)

今天轉貼一篇朋友丟來的香香文章,主要在說明什麼是最小可行性產品(MVP)、它帶來什麼好處,還有我們該怎麼建立一個 MVP:
Minimum Viable Product: The Do’s and Dont’s For Testing Your App Idea

先讓我節錄文章中的一小段來快速介紹 MVP 的概念:

Developing a basic version of the app based on must-have features and launching it in the market for customer validation is the idea behind a minimum viable product (MVP)
根據必要功能開發一個基本版本的應用程式,並在市場上推出以進行客戶驗證,這就是最小可行產品(MVP)的概念

In short, an MVP is a low-cost app version for testing user acceptance and response instead of launching a fully-fledged product in the market and realizing it didn’t address the user pain points.
簡而言之,MVP是一個低成本的應用程式版本,用於測試使用者的接受度和回饋,而不是在市場上推出一個完整的產品,然後發現它根本沒有解決使用者的痛點。

接著,這篇文章說明了採用的 MVP 的好處和步驟。文章中對每一個項目都進行了簡短直接的說明,但依照慣例(?),附上我濃縮後的版本(方便我之後查詢),有興趣的朋友可以直接閱讀內文

建立 MVP 的好處:

  • 從初期使用者收集回饋
  • 更早地進入市場,獲得競爭優勢
  • 節省成本(相較於開發完整的產品)
  • 確保產品有符合市場需求(試水溫)
  • 獲得高品質回饋,然後迭代並改進產品

建立 MVP 的步驟:
  • 市場研究(調查使用者的需求,或是競爭對手)
  • 圍繞必要功能來制定策略
    • 必備功能(Must Haves):MVP 就是要搞這個吧
    • 應該有的功能(Should Haves):先跳過,之後推出到市場的時候再來搞
    • 可以有的功能(Could Haves):先省略,之後看預算和交付時間再說
    • 不會有的功能(Won’t Haves):就是不會有了 = =
  • 建立一個概念驗證(PoC)
  • 做出一個原型(有 UI/UX 的那種,基本上就是半成品了)
  • 如果原型行得通,開始跑設計、開發、測試、迭代、整合和交付…
  • 把 MVP 噴出去,開始搞市場營銷,準備下一輪改進

我個人之前常常分不太清楚 MVP 和 PoC,在這篇裡面也有直接簡短的說明

  • PoC 是為了驗證技術可行性,讓開發仔們去動手試試看搞不搞得出來
  • MVP 則是已經有必備功能的小小產品,是用來丟下去驗證並拿到回饋的

這邊就額外紀錄一下,後續才不會搞混了。

……

閱讀全文



【每天推薦一篇文章】面對模糊需求的六個步驟

今天剛好跟同事聊到處理需求跟專案的部份,想說就貼之前收藏的這篇上來:
接到一個模糊的需求時,該怎麼處理? - Evonne Tsai

雖然這篇文章開場是站在 PM 的角度出發,但我覺得在評估目標的部份,以及面對模糊需求的步驟等等,對我等 CRUD 工程師還是很有參考價值。

作者將接到需求之後要進行的項目分成兩個階段,各三個步驟:

  • 分析與探索階段
    • Step 1: 確認提出這個需求的目的或背後動機
    • Step 2: 確認事實與現況
    • Step 3: 清楚的目標以及衡量指標
  • 執行階段
    • Step 4: 找出各種解法
    • Step 5: 排定優先順序和「組合技」
    • Step 6: 制訂與執行專案管理計畫

以上的每個步驟都有更細的說明,例如 Step 3,要訂下具體的目標時就可以使用「SMART 原則」。這邊就不附上,有興趣的朋友可以再進內文看看。

我在看這篇的時候有點小反省:當遇到一個需求,我很常直接跳到 Step 4 開始想各種實作方案,而忽略了前面的分析與探索

但在某些時候,可能這個需求根本不能解決原本的問題(有點像 X-Y 問題 ),又或是我們根本沒想清楚要達成怎樣的效益、怎麼樣評估結果是有效的,掄起槌子就要開幹,然後才發現:啊!我們根本沒搞清楚!就浪費了一堆時間,設計可能也要變來變去

其實我發現,越是會解決問題的人,越會花很多時間在釐清「阿現在到底是發生了什麼事?」「大家眼中的問題到底長怎麼樣?」

而越是菜鳥,越是會直接接受問題以及假設,甚至接受非事實的「他人觀點」(例如顧客說產品太貴就回頭爭取折扣),埋首去解決問題、使命必達,卻不知在瞎忙什麼。

希望自己之後也能先冷靜下來好好分析狀況,共勉之。

……

閱讀全文



【每天推薦一篇文章】多服務的 SLA 計算方式

手邊的東西還沒弄完,決定今天簡單轉貼一下前輩丟的 SLA 計算文章,有需要的朋友可以看看:
計算出正確的服務水平協議:探索 Composite SLAs 計算和架構設計 - 魂系架構 Phil’s Workspace

這篇文章裡列了蠻多場景。例如

  • 相依的兩個服務(SLA = 兩者相乘)
  • 沒有相依的兩個服務(SLA = 1 - 兩者同時失敗機率)

以及多個區域的狀況:

首先先計算應用程式在所有區域爆炸的機率
應用程式在多個區域合併 SLA 公式為 (1 - (1 - SLA) ^ R)

R: 是區域數量
SLA: 是單一區域的 SLA 協議數字

故可得知程式佈署在兩個區域時,可獲得下列 SLA 等級:
Composite SLA for Azure Red Hat OpenShift in 2 regions = 99.9999% = (1 - (1 - 0.99929011)^2)

但因前面需要放置 Azure Traffic Manager 服務確保前置流量能夠兩邊導流,故還需計算,故可得:
Totla Composite SLA = 99.9899% = 99.99% * 99.99%


這篇我收起來哪天需要算的時候參考,不過我特喜歡這段:

Q1: 某某個服務超爛,一天會當機七小時以上,約 SLA 68.3772234%,是不是永遠達不到 2 nines?

A1:以上面計算單一區域所需最低 SLA 計算來說,不考慮資料一致性及網路可達性,你只要在 4 個不同區域建立相同 SLA 68.3772234% 服務,最差還是可以拿到 SLA 99% 的等級

但… 你應該要做的事情是研究一下為啥一個服務一天會噴掉七小時以上,而不是在這邊算數學

……

閱讀全文



【每天推薦一篇文章】思考的框架

《思考的框架 The Great Mental Models》閱讀筆記:建立多元思維模型 - Mick Zhuang

第一條規則是,如果你只是記得一些孤立的事實,而試圖把它們硬湊起來,將無法真正理解任何東西。如果這些事實不在一個理論框架中相互聯繫,就無法派上用場

你必須在腦中擁有一些思維模型,靠這些模型組成的框架來整理間接和直接的經驗。你必須把經驗掛在腦中一個由許多思維模型組成的框架上。

—— 查理蒙格

……

閱讀全文



【每天推薦一篇文章】Airbnb 的架構演進

剛剛看到這篇香的,立馬拿來當作今日轉貼:
A Brief History of Airbnb’s Architecture

文章裡介紹了 Airbnb 的架構從一個單體長成 SOA 的過程,包括他們在大單體時遇到的問題、逐步遷移的比對機制、SOA 的優缺點,以及他們搞的 API 框架等等。

這邊就節選一些我覺得有趣的地方,對其他部份有興趣的朋友可以直接閱讀文章。


因為搬家不是一兩天就搬得完的,所以 Airbnb 在過程中有對新舊系統的操作進行比對

例如讀取相關的操作,就同時呼叫新舊系統並且比對查詢結果,確定都沒問題之後才遷移過去

寫入相關的操作,則是建立第二顆 DB,然後再查詢出來比對兩邊的內容

之所以對這段有興趣,是因為之前也遇過把舊系統的功能遷移到新系統的場景,喊了一聲「絞殺者模式!」就開始搬磚頭

當時也是藉由同時查詢兩邊來比對,現在看到人家也這麼幹,稍微安心了一點(?)


這篇文章裏面也整理了服務導向架構(Service-Oriented Architecture, SOA)的優缺點,也節錄上來讓大家參考(同時方便我之後查詢)

Some pros were as follows:
一些優點如下:

The system became more reliable and highly available. Even if one service went down, other parts of the service-oriented architecture could still function. 系統變得更加可靠且高度可用。即使其中一個服務出現故障,服務導向架構的其他部分仍然可以運作。

Services were now individually scalable, allowing fine-tuning of the resource allocation depending on the real needs of the system. 現在服務可以進行個別的可擴展性調整,根據系統的實際需求進行資源分配的微調。

Increased business agility due to separating different parts of the product into different services. Each team could iterate in parallel. 將產品的不同部分分開成不同的服務,能夠增加業務的靈活性。每個團隊都可以並行進行迭代

However, there were some cons as well:
然而,也有一些缺點:

Engineers can take more time to ship a feature in service-oriented architecture because they need to first acquaint themselves with the various services. Also, any change potentially involves multiple services 工程師在服務導向架構中可能需要更多時間來發布一個功能,因為他們需要先熟悉各種服務。此外,任何變更都可能涉及多個服務

Even though services were loosely coupled, certain patterns of logic had to be repeated across different services. 即使服務之間鬆散耦合,某些邏輯模式仍需要在不同服務之間重複

Complicated dependency graph especially when there is a lack of API governance. This could also result in circular dependencies and also make it difficult for engineers to debug errors. 當 API 管理不足時,複雜的依賴關係圖可能會出現。這可能導致循環依賴,並使工程師難以調試錯誤。

……

閱讀全文



【每天推薦一篇文章】反問面試官的時候到了

剛剛看到前輩貼了一篇實用列表,立馬轉貼上來:
反向面試 - 技術面試最後反問面試官的題庫

如何使用本份文件

  • 檢查一下哪些問題你感興趣
  • 檢查一下哪些是你可以自己在網上找到答案的
  • 找不到的話就向面試官提問

絕對不要想把這個列表裡的每個問題都問一遍。 (請尊重面試官的時間,而且你可以通過搜尋已經公開的答案來顯示你的主動性)

請記住事情總是靈活的,組織的結構調整也會經常發生。擁有一個 bug 追踪系統並不會保證高效處理 bug。 CI/CD (持續集成系統) 也不一定保證交付時間會很短。

有需要的朋友再自行取用,祝好運!

……

閱讀全文



【每天推薦一篇文章】社交型單元測試

今天還要聚餐,決定簡單轉貼一下之前讓我很衝擊的東東:社交型單元測試
探討單元測試和整合測試的涵蓋範圍 - WadeHuang的學習迷航記

  • 孤立型的單元測試:受測物件不會使用真實的依賴類別
  • 社交型的單元測試:受測物件會使用真實的依賴類別

我一直以為出手就是要瘋狂 MOOOOOOOCCCKKKKK,著實有點嚇到= =

但當我看到這段:

在《修改軟件的藝術》第 10 章測試先行,作者提及 TDD 的單元測試與狹義的單元測試不同,TDD 是以一個行為作為一個單元

一個獨立、可驗證的行為。這個行為會對系統產生可觀察的影響,且不和系統的其他行為耦合。

這個單元測試的定義意味著:每個可觀察到的行為都應該要有一個相對應的測試。
另外在《Growing Object-Oriented Software, Guided by Tests》第五章節也指出,應該針對行為進行單元測試,而非針對方法。

這下真相大白了!如果你是 BDD 或 TDD 的實踐者,那麼你的單元測試就可能是跨多個類別的社交型單元測試,因為測試的對象是 一個行為,而非一個類別

覺得也挺有道理 🤔

……

閱讀全文



【每天推薦一篇文章】軟體開發的復盤

今天打開收件閘,發現魯迪老師有貼了新文章,立馬轉貼上來給大家:
軟體開發的復盤 - RUDDYLLEE

在這篇文章裡,魯迪老師先提了復盤的意義:「重來一次可以學得最多」

接著馬上就進入第一個復盤的情境:Code Review

程式碼審核 (Code review) 是程式復盤的基石

程式碼在開發作業中的 code review 行為是團隊復盤的第一個情境,程式撰寫人應該負起說明程式碼情境的責任 (對程碼做標題說明 WHY? 解決了甚麼需求的問題)

審核人員則應該針對解決問題的方法給予回饋,以提出”如果 …會怎樣”就是what if 的提問方式來做回答,目的在造成當事人的反思,這樣做或許可以促成當事人想到更好的解題方案,或是避免掉將來可能產生的缺陷中。

在必要時進行面對面的溝通,對學習更有幫助,形成教學相長。

Code Review 讓團隊可以協作,並且分享彼此的知識,讓團隊學到更多。


第二個情境則是復盤需求:

復盤的第二個情境是針對需求的復盤

由於需求的來源是針對使用者的操作情境而來,它的排序方式是以協助使用者順利完成任務為出發點。而程式設計人員則是以整個專案開發的技術範疇為主,它思考的是盲點與疑惑…(中略)

無論是疑惑或是盲點,都是程式設計人員依據需求的陳述和自己所擁有的經驗、技能進行評估後所產生的概念,中間難免會做了許多的假設,這一點;就好比對弈時猜測對方為什麼會下這步棋時的動機一般,需要事後印證來學得正確的經驗。

復盤可以讓我們學到最多。當然針對核心部分的 MVP 開發作業的驗證,也是很值得復盤以充分學習了解的地方。

這段看起來有點像是需求完成後,回頭找出認知落差再校準,藉此累積經驗的感覺

例如我們可能誤以為這個功能應該就是長得像A,結果來來回回老半天才發現客戶是要B,下次我們就知道還有B這個可能性


這篇有個我覺得蠻重要的概念:檢討的目的是不再犯相同的錯,而復盤的目的是找出更適合的解決方法、從錯誤中學習。兩者並不相同

檢討跟復盤之間很常會發生誤解,有時候我們會在寶貴的學習機會前忙著找戰犯,這樣就浪費了(特別把這個概念寫出來,也算是提醒我自己吧)

……

閱讀全文



【每天推薦一篇文章】Consistent Hashing

昨天有朋朋提到 Consistent Hashing,發現我筆記庫沒有相關資料,果斷重新了解一下並轉貼上來:Consistent Hashing Algorithm: 應用情境、原理與實作範例 - chyeh

Consistent Hashing 主要是應用於分散式系統的場景,用來判斷要把資料送給哪個服務節點時用的

如果同一份資料會隨機亂噴,兩次噴都噴到不一樣的服務,要追查問題或是搞什麼監控警報就會變得比較麻煩(?)。因此我們會希望同一份資料進來,就固定會到某一個服務。除了容易重現問題以外,在這個服務上搞快取也比較方便好命中

但如果只是使用簡單的 Hash 來對應(例如說平均分配,第一筆資料丟給第一台服務、第二筆資料丟給第二台服務……),就有可能遇到當節點新增或減少時,資料對應到的服務大量變動的問題

這一段我有點不太會說明(有更熟的朋朋歡迎幫忙),這邊就跟 GPT 一起 Pair 來舉個例子:

想像一下,你有一堆信件需要放到幾個郵箱裡。你決定用一個簡單的方法:每個郵箱輪流放信。

例如說你有 10 封信、3 個郵箱。那麼第 1 封信(編號為 1)就放到編號 1 的郵箱,第 2 封信放到編號 2 的郵箱,以此類推。編號 10 的信會放到編號 1 的郵箱,因為 10 除以 3 餘 1。

但是,如果你突然多了一個郵箱,變成 4 個郵箱,這個簡單的分配方法就需要改變了,因為你現在是按照 4 來計算每封信應該放哪了。

第 4 封信原本在第 1 個郵箱,現在得放到第 4 個郵箱了,這樣我們就得把很多信都拿出來,重新分一遍,非常麻煩,特別是信件很多的時候。

這時候我們就可以使用 Consistent Hashing,就如上面轉貼的文章所說:

Consistent Hashing 的做法是找「沿著順時鐘方向走,遇到的第一個 Index」

圖片來源:今天轉貼的這篇文章

同樣地,我們請 GPT 同樣用郵箱的例子支援一下:

想像一下,你有一堆信件需要放到幾個郵箱裡。而你站在一個圓形的大廳,大廳有些方向的牆壁上掛著郵箱

你決定像時鐘一樣把大廳分為 1 ~ 12,然後你會根據郵件的編號找到對應的數字,再沿著房間的圓形牆壁走,走到下一個郵箱就把信件投遞進去。

比如說,編號是 10 的信,就先找到圓圈上對應 10 的位置,開始順著圓走,直到碰到的第一個郵箱(可能這個郵箱位在 12),然後就把信放進去。

這樣即使多了一個郵箱,大多數郵箱的信也不用再重新分配了

因為計算 Hash 之後是去找到下一個圓圈上的節點,當節點新增的時候,只有新增節點的前一段受到影響;移除的時候也只有到下一個節點之間會影響

這樣就比較不會有資料和服務的對應關係大幅變動的問題了,我們又成功地拯救了我們各個服務的快取(?),可喜可賀

……

閱讀全文