分析一些常見的低感知高複雜度案例:
「同步」是一個實際上非常複雜但是表現上非常簡單的東西:保持兩邊同步,一邊不一樣了另一邊也跟著動,how hard that can be?
如果沒有做過資料雲端同步的系統,即使是開發者的你也會覺得這有啥難,尤其是CRDT輪子滿天飛的當下。
實際上同步過程只有兩種主要做法,一種是記錄更改過程,根據更改的先來後到一個個apply change;另一種是比較兩邊差異,根據資料特徵得出一個merged version。
兩個approach都有對應的缺點:前者消耗大量的空間去存每一個更改,且在合併過程裡消耗大量計算資源;後者如果缺乏足夠heuristics,要不要求user input去manual merge,要不做一個大膽假設但冒猜錯了丟失資料的風險。
Like any good engineering practice,實際上的同步方案採用的都是這兩個approach的結合。changelog的粒度會放粗一點,合併時間上或邏輯上相鄰的變更;這樣優化造成無法分辨先後的變更,則先用heuristics判斷intention,判斷不了就讓用戶選擇;如果A在和B同步開始之前都沒有變更可以直接採信B的版本……
如果你突然覺得這很複雜,覺得像git一樣有很多概念很令人困惑,那你想對了,git就是一個允許你manually實作同步流程的工具。為什麼軟體工程界一直沒有「雲同步」source code這一說呢?正是因為那些「雲同步」方案都沒法做到軟體工程師需要的可靠性啊……
「同步」是一個實際上非常複雜但是表現上非常簡單的東西:保持兩邊同步,一邊不一樣了另一邊也跟著動,how hard that can be?
如果沒有做過資料雲端同步的系統,即使是開發者的你也會覺得這有啥難,尤其是CRDT輪子滿天飛的當下。
實際上同步過程只有兩種主要做法,一種是記錄更改過程,根據更改的先來後到一個個apply change;另一種是比較兩邊差異,根據資料特徵得出一個merged version。
兩個approach都有對應的缺點:前者消耗大量的空間去存每一個更改,且在合併過程裡消耗大量計算資源;後者如果缺乏足夠heuristics,要不要求user input去manual merge,要不做一個大膽假設但冒猜錯了丟失資料的風險。
Like any good engineering practice,實際上的同步方案採用的都是這兩個approach的結合。changelog的粒度會放粗一點,合併時間上或邏輯上相鄰的變更;這樣優化造成無法分辨先後的變更,則先用heuristics判斷intention,判斷不了就讓用戶選擇;如果A在和B同步開始之前都沒有變更可以直接採信B的版本……
如果你突然覺得這很複雜,覺得像git一樣有很多概念很令人困惑,那你想對了,git就是一個允許你manually實作同步流程的工具。為什麼軟體工程界一直沒有「雲同步」source code這一說呢?正是因為那些「雲同步」方案都沒法做到軟體工程師需要的可靠性啊……