系統設計(架構師)指南4設計限速器

来源:https://www.cnblogs.com/testing-/archive/2023/09/08/17666492.html
-Advertisement-
Play Games

本文給大家介紹了什麼是"編程範式",選擇合適的編程範式可以提高代碼的可讀性、可維護性和可擴展性。 一、 什麼是編程範式? "編程範式"是一種編程思想的總稱,它是指在編寫程式時所採用的基本方法和規範。常見的編程範式有面向對象、函數式、邏輯式等。 選擇合適的編程範式可以提高代碼的可讀性、可維護性和可擴展 ...


4 設計限速器

在網路系統中,限速器用於控制客戶端或服務發送流量的速率。在HTTP世界中,限速器限制在指定時間內允許發送的客戶端請求數量。如果API請求數超過了限速器定義的閾值,超出調用都會被阻止。下麵是幾個例子:

  • 用戶每秒最多只能寫2篇文章。

  • 同一IP地址每天最多只能創建10個賬戶。

  • 同一設備每周最多可申請5次獎勵。

本章將要求您設計限速器。在開始設計之前,我們首先瞭解一下使用API限速器的好處:

  • 防止拒絕服務(DoS Denial of Service)攻擊造成的資源枯竭。

幾乎所有大型科技公司發佈的API都會強制執行某種形式的速率限制。例如,Twitter將推文數量限製為每3小時 300條。Google docs API的預設限制如下:每個用戶每60秒讀取請求300次。限速器通過阻止多餘的調用來防止有意或無意的DoS攻擊。

  • 降低成本

限制過量請求意味著減少伺服器數量,將更多資源分配給優先順序高的API。對於使用付費第三方API的公司來說,速率限制極為重要。例如,以下外部應用程式介面按調用次數收費:檢查信用、付款、檢索健康記錄等。限制調用次數對降低成本至關重要。

-防止伺服器過載

為減少伺服器負載,可使用限速器來過濾機器人或用戶不當行為造成的多餘請求。

4.1 步驟 1 - 理解問題並確定設計範圍

速率限制可以使用不同的演算法來實現,每種演算法都有其優缺點。面試官和應聘者之間的互動有助於明確我們要構建的限速器類型。

候選人:我們要設計哪種限速器?是客戶端限速器還是伺服器端API限速器?

面試官:問得好。我們的重點是伺服器端API限速器。

候選人:限速器是根據IP、用戶ID還是其他屬性來限制API請求?

面試官:限速器應該足夠靈活,以支持不同的節流規則。

應聘者:系統的規模有多大?是為初創公司還是擁有龐大用戶群的大公司構建的?

面試官:系統必須能夠處理大量請求。

應聘者:系統能否在分散式環境中運行?

面試官:可以。

應聘者:限速器是單獨的服務,還是應該在應用程式代碼中實現?

面試官:這取決於你的設計決定。

應聘者:我們需要通知被節流的用戶嗎?

面試官:需要。

要求

以下是系統要求的摘要:

  • 準確限制過多請求。
  • 低延遲。限速器不應減慢HTTP響應時間。
  • 使用儘可能少的記憶體。
  • 分散式速率限制。限速器可在多個伺服器或進程中共用。
  • 異常處理。當用戶的請求被節流時,向用戶顯示明確的異常。
  • 高容錯性。如果限速器出現任何問題(例如,緩存伺服器離線),不會影響整個系統。

4.2 第2步 - 提出概要設計方案並獲得支持

讓我們保持簡單,使用基本的客戶端和伺服器通信模型。

4.2.1 在哪裡設置限速器?

直觀地說,可以在客戶端或伺服器端實施限速器。

  • 客戶端

一般來說客戶端是實施速率限制的不可靠的,因為客戶端請求很容易被惡意行為者偽造。此外,我們可能無法控制客戶端的實施。

  • 伺服器端

假設我們的API允許每秒發出2個請求,而客戶端在一秒鐘內向伺服器發送了3個請求。前兩個請求被路由到API伺服器。但是,限速器中間件會對第三個請求進行節流,並返回HTTP狀態代碼 429。HTTP429響應狀態代碼表示用戶發送的請求過多。

雲微服務已廣為流行,速率限制通常在API網關的組件中實現。API網關是一種完全托管的服務,支持速率限制、SSL終止、身份驗證、IP白名單、靜態內容服務等。目前,我們只需知道API網關是支持速率限制的中間件。

速率限制器應該在哪裡實施,是在伺服器端還是在網關中?這個問題沒有絕對的答案。這取決於貴公司當前的技術堆棧、工程資源、優先順序、目標等。以下是幾條一般指導原則:

評估當前的技術堆棧,如編程語言、緩存服務等。確保您當前的編程語言能夠有效地在伺服器端實施速率限制。

確定適合您業務需求的速率限制演算法。在伺服器端實施一切時,您可以完全控制演算法。但是,如果使用第三方網關,您的選擇可能會受到限制。

  • 如果您已經使用了微服務架構,併在設計中加入了API網關來執行身份驗證、IP白名單等功能,您可以在API網關中添加速率限制器。

  • 創建自己的速率限制服務需要時間。如果沒有足夠的工程資源來實施速率限制器,商業API網關是更好的選擇。

參考資料

4.2.2 限速演算法

限速可以使用不同的演算法來實現,每種演算法都有明顯的優缺點。儘管本章的重點不是演算法,但從高層次瞭解這些演算法有助於選擇合適的演算法或演算法組合,以適應我們的使用情況。以下是常用演算法的列表:

  • 令牌桶(Token bucket)
  • 泄漏桶(Leaking bucket)
  • 固定視窗計數器(Fixed window counter)
  • 滑動視窗日誌(Sliding window log)
  • 滑動視窗計數器(Sliding window counter)

4.2.2.1 令牌桶演算法

令牌桶演算法廣泛用於限速。它簡單易懂,常用於互聯網公司。亞馬遜和都使用這種演算法。

令牌桶演算法的工作原理如下:

  • 令牌桶是一個具有預定容量的容器。令牌以預設的速率定期放入令牌桶。一旦桶滿,就不再添加令牌。如圖所示,令牌桶的容量為4,加油員每秒向桶中投入2枚令牌。一旦桶滿,多餘的代幣就會溢出。

  • 每個請求消耗一個代幣。當請求到達時,我們會檢查桶中是否有足夠的代幣。
    • 如果有足夠的令牌,我們會為每個請求取出令牌,然後請求通過。
    • 如果沒有足夠的令牌,請求就會被放棄。

令牌桶演算法需要兩個參數:

  • 令牌桶大小:令牌桶中允許的最大令牌數量

  • 填充率:每秒放入代幣桶的代幣數量

我們需要多少代幣桶?這取決於限速規則。下麵是幾個例子。

  • 通常需要為不同的API端點設置不同的桶。例如,如果允許用戶每秒發表1篇文章,每天添加150個好友,每秒喜歡5篇文章,那麼每個用戶需要3個桶。
  • 如果我們需要根據IP地址來限制請求,那麼每個IP地址都需要一個桶。
  • 如果系統每秒最多允許 10,000 個請求,那麼所有請求共用一個全局桶是合理的。

優點

  • 演算法易於實現。
  • 記憶體效率高。
  • 代幣桶允許短時間內的突發流量。只要還有代幣,請求就可以通過。

缺點

  • 演算法中的兩個參數是代幣桶大小和代幣填充率。然而,對它們進行適當調整可能具有挑戰性。

4.2.2.2 漏桶演算法

泄漏桶演算法與令牌桶類似,只是以固定速率處理請求。它通常使用先進先出隊列(FIFO)來實現。該演算法的工作原理如下:

  • 當請求到達時,系統會檢查隊列是否已滿。如果隊列未滿,則將請求添加到隊列中。
  • 否則,請求將被丟棄。
  • 從隊列中取出請求,並定期進行處理。

泄漏桶演算法需要以下兩個參數:

  • 桶大小:等於隊列大小。隊列容納以固定速率處理的請求。

  • 流出率:它定義了以固定速率(通常以秒為單位)處理的請求數量。

電子商務公司Shopify使用泄漏桶來限速。

優點

-由於隊列大小有限,因此記憶體效率高。
-請求以固定速率處理,因此適用於需要穩定流出速率的用例。

缺點

-突發流量會使隊列中充滿舊請求,如果不及時處理,最近的請求就會受到速率限制。
-演算法中有兩個參數。演算法中有兩個參數,可能不容易正確調整。

4.2.2.3 固定視窗計數器演算法

固定視窗計數器演算法的工作原理如下:

  • 將時間線劃分為固定大小的時間視窗,併為每個視窗分配一個計數器。

  • 每次請求都會使計數器遞增1。

  • 一旦計數器達到預定義的閾值,新的請求就會被放棄,直到新的時間視窗開始。

下圖中,時間單位為1秒,系統每秒最多允許3個請求。在每秒鐘的視窗中,如果收到的請求超過3個,系統就會丟棄多餘的請求。

這種演算法的一個主要問題是,時間視窗邊緣的突發流量可能會導致超過允許配額的請求通過。請考慮以下情況:

下圖,系統每分鐘最多允許5個請求,可用配額在人性化的整數分鐘重置。如圖所示,2:00:00至2:01:00之間有5個請求,2:01:00 至 2:02:00之間又有5個請求。在2:00:30和2:01:30之間的一分鐘視窗中,有10個請求通過。這是允許請求數的兩倍。

優點

-節省記憶體。
-易於理解。
-在單位時間視窗結束時重置可用配額,適合某些使用情況。

缺點

  • 視窗邊緣的尖峰流量可能導致超過允許配額的請求通過。

4.2.2.4 滑動視窗日誌演算法

如前所述,固定視窗計數器演算法有一個主要問題:它允許更多請求在視窗邊緣通過。滑動視窗日誌演算法解決了這個問題。其工作原理如下:

  • 該演算法跟蹤請求時間戳。時間戳數據通常保存在緩存中,如Redis的排序集。
  • 當有新請求時,刪除所有過期的時間戳。過時的時間戳是指比當前時間視窗開始時間更早的時間戳。
  • 將新請求的時間戳添加到日誌中。
    -如果日誌大小與允許計數相同或更小,則接受請求。否則,請求將被拒絕。

在本例中,速率限制器允許每分鐘2個請求。通常,Linux時間戳會存儲在日誌中。不過,為了提高可讀性,我們在示例中使用了人類可讀的時間表示法。

  • 當新請求在 1:00:01 到達時,日誌為空。因此,該請求是允許的。
  • 新請求在 1:00:30 到達時,時間戳 1:00:30 將被插入日誌。插入後,日誌大小為 2,不大於允許計數。因此,該請求是允許的。
  • 新請求在 1:00:50 到達,時間戳被插入日誌。插入後,日誌大小為 3,大於允許的 2。因此,即使時間戳仍保留在日誌中,該請求也會被拒絕。
  • 一個新請求在 1:01:40 到達。1:00:40,1:01:40)範圍內的請求在最新時間範圍內,但在 1:00:40 之前發送的請求已經過時。兩個過時的時間戳 1:00:01 和 1:00:30 將從日誌中刪除。刪除操作後,日誌大小變為 2,因此請求被接受。

優點

  • 該演算法實現的速率限制非常精確。在任何滾動視窗中,請求都不會超過速率限制。

缺點

  • 該演算法消耗大量記憶體,因為即使請求被拒絕,其時間戳仍可能存儲在記憶體中。

4.2.2.5 滑動視窗計數器演算法

滑動視窗計數器演算法是一種混合方法,它結合了固定視窗計數器和滑動視窗日誌。該演算法可以通過兩種不同的方法實現。我們將在本節中解釋其中一種實現方法,併在本節末尾提供另一種實現方法的參考。下圖展示了該演算法的工作原理。

假設速率限制器每分鐘最多允許7個請求,前一分鐘有5個請求,當前一分鐘有3個請求。對於到達當前分鐘 30% 位置的新請求,滾動視窗中的請求數按以下公式計算:

  • 當前視窗中的請求數 + 上一視窗中的請求數 * 滾動視窗與上一視窗的重疊百分比
  • 根據這一公式,我們得到 3 + 5 * 0.7% = 6.5 個請求。根據使用情況,該數字可以向上或向下舍入。在我們的例子中,四捨五入為6。

由於速率限制器每分鐘最多允許7個請求,因此當前請求可以通過。不過,再收到一個請求後就會達到限制。

優點

  • 由於速率基於前一個視窗的平均速率,因此可以平滑流量峰值。
  • 節省記憶體。

缺點

  • 只適用於不太嚴格的回看視窗。它是實際速率的近似值,因為它假定前一個視窗中的請求是均勻分佈的。不過,這個問題可能沒有想象中那麼嚴重。根據 Cloudflare 的實驗,在 4 億個請求中,只有 0.003% 的請求被錯誤地允許或限制了速率。

4.2.3 高層架構

我們需要一個計數器來跟蹤來自同一用戶、IP 地址等的請求數量。如果計數器大於限制,請求就會被禁止。

我們應該在哪裡存儲計數器呢?由於磁碟訪問速度較慢,使用資料庫並不是一個好主意。選擇記憶體緩存是因為它速度快,而且支持基於時間的過期策略。例如Redis是實現速率限制的常用選擇。它是一種記憶體存儲,提供兩種命令:INCREXPIRE。

  • INCR:將存儲的計數器加1。
  • EXPIRE:為計數器設置超時。如果超時,計數器將自動刪除。

  • 客戶端向限速中間件發送請求。
  • 限速中間件從Redis中相應的桶中獲取計數器,並檢查是否達到限制。
    • 如果達到限制,則拒絕請求。
    • 如果未達到限制,則將請求發送到API伺服器。同時,系統會遞增計數器並將其保存回Redis。

4.3 第3步 - 深入設計

上圖中的高層設計沒有回答以下問題:

  • 如何創建速率限制規則?規則存儲在哪裡?
  • 如何處理速率受限的請求?

4.3.1 限速規則

Lyft將其速率限制組件開源在https://github.com/lyft/ratelimit。我們將深入瞭解該組件,並舉例說明一些速率限制規則:

domain: messaging

descriptors:

  - key: message_type

    Value: marketing

    rate_limit:

      unit: day

      requests_per_unit: 5

在上例中,系統配置為每天最多允許發送5條營銷信息。下麵是另一個示例:

domain: auth

descriptors:

  - key: auth_type

    Value: login

    rate_limit:

      unit: minute

      requests_per_unit: 5

這條規則規定,1 分鐘內客戶端登錄次數不得超過5次。規則一般寫入配置文件並保存在磁碟上。

4.3.2 限速

如果請求受到限速,API會向客戶端返回HTTP響應代碼429(請求過多)。根據使用情況,我們可能會將速率受限的請求排入隊列,以便稍後處理。例如,如果一些訂單因系統超載而受到速率限制,我們可能會保留這些訂單,以便稍後處理。

4.3.3 速率限制器標頭

客戶端如何知道自己是否被節流?客戶端又如何知道被節流前允許的剩餘請求數?答案就在HTTP響應頭中。速率限制器會向客戶端返回以下HTTP頭信息:

  • X-Ratelimit-Remaining:視窗內允許的剩餘請求數。
  • X-Ratelimit-Limit:表示客戶端在每個時間視窗內可進行的調用次數。
  • X-Ratelimit-Retry-After: 在不被節流的情況下再次發出請求前需要等待的秒數。

當用戶發送的請求過多時,會向客戶端返回429請求過多錯誤和X-Ratelimit-Retry-After頭信息。

4.3.4 詳細設計

  • 規則存儲在磁碟上。工作站經常從磁碟中提取規則並將其存儲到緩存中。
  • 當客戶端向伺服器發送請求時,請求會首先發送到限速器中間件。
  • 限速器中間件從緩存中載入規則。它從Redis緩存中獲取計數器和上次請求的時間戳。根據響應,速率限制器決定
  • 如果請求不受速率限制,則將其轉發給API伺服器。
  • 如果請求有速率限制,速率限制器會向客戶端返回429請求過多錯誤信息。同時,請求會被丟棄或轉發到隊列中。

4.3.5 分散式環境中的限速器

建立能在單伺服器環境中運行的速率限制器並不困難。但是,將系統擴展到支持多台伺服器和併發線程則是另一回事。這其中有兩個難題:

  • 競賽條件
  • 同步問題

如前所述,速率限制器的高級工作原理如下:

  • 從Redis讀取計數器值。
  • 檢查(counter + 1)是否超過閾值。
  • 如果沒有,則將Redis中的計數器值遞增 1。

在高併發環境中可能會出現競賽條件。

假設Redis中的計數器值為3,如果兩個請求同時讀取計數器值,然後再寫回計數器值,那麼每個請求都會將計數器值遞增 1,然後寫回計數器值,而不會檢查其他線程。兩個請求(線程)都會認為自己的計數器值是 4。然而,正確的計數器值應該是5。

鎖是解決競賽條件最明顯的方法。但是,加鎖會大大降低系統運行速度。通常有兩種策略可以解決這個問題:Lua腳本 和 Redis中的排序集數據結構。

同步是分散式環境中需要考慮的另一個重要因素。要支持數百萬用戶,一臺速率限制器伺服器可能不足以處理流量。當使用多個速率限制器伺服器時,就需要同步。例如下圖的左側,客戶端1向速率限制器1發送請求,客戶端2向速率限制器2發送請求。由於網路層是無狀態的,客戶端可以向不同的速率限制器發送請求。如果不進行同步,速率限制器1就不包含任何有關客戶端2的數據。因此,速率限制器無法正常工作。

一種可能的解決方案是使用粘性會話,允許客戶端向同一個速率限制器發送流量。這種解決方案並不可取,因為它既不可擴展,也不靈活。更好的辦法是使用Redis等集中式數據存儲。

4.3.6 性能優化

性能優化是系統設計訪談中的一個常見話題。我們將從兩個方面進行改進。

首先,多數據中心設置對於速率限制器來說至關重要,因為對於遠離數據中心的用戶來說,延遲很高。大多數雲服務提供商都在全球建立了許多邊緣伺服器位置。例如,截至2020年5月20日,Cloudflare擁有194個地理分佈廣泛的邊緣伺服器。流量會自動路由到最近的邊緣伺服器,以減少延遲。

第二,使用最終一致性模型同步數據。

4.3.7 監控

設置速率限制器後,收集分析數據以檢查速率限制器是否有效非常重要。首先,我們要確保

  • 速率限制演算法是否有效。
  • 速率限制規則有效。

例如,如果速率限制規則過於嚴格,許多有效請求就會被丟棄。在這種情況下,我們希望稍微放寬規則。再比如,我們發現當流量突然增加(如閃購)時,我們的速率限制器就會失效。在這種情況下,我們可以更換演算法來支持突發流量。令牌桶就是一個很好的選擇。

4.4 步驟4 - 總結

在本章中,我們討論了不同的速率限制演算法及其優缺點。討論的演算法包括

  • 令牌桶
  • 泄漏桶
  • 固定視窗
  • 滑動視窗日誌
  • 滑動視窗計數器

然後,我們討論了系統架構、分散式環境中的速率限制器、性能優化和監控。與任何系統設計面試問題類似,如果時間允許,你還可以提到一些額外的談話要點:

  • 硬性與軟性速率限制。

    • 硬性:請求數不能超過閾值。
    • 軟:請求數可以在短時間內超過閾值。
  • 不同級別的速率限制。在本章中,我們只討論了應用層(HTTP:第 7 層)的速率限制。也可以在其他層應用速率限制。例如,可以使用 Iptables (IP:第 3 層)按 IP 地址限制速率。

  • 避免速率受限。以最佳實踐設計客戶端:

  • 使用客戶端緩存,避免頻繁調用API。

  • 瞭解限制,不要在短時間內發送過多請求。

  • 包含捕獲異常或錯誤的代碼,以便客戶端可以從容地從異常中恢復。

  • 為重試邏輯添加足夠的後退時間。

釘釘或微信號: pythontesting 微信公眾號:pythontesting
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # pentaho使用 先展示一下用途和效果 ![image](https://jsd.cdn.zzko.cn/gh/YuanjunXu/Images@main/src/image.1gzusdgfiiao.webp) ## 1. 環境準備 ### 1.1 pentaho是什麼? > `pentah ...
  • 在這篇文章中,我將分享一次由於操作不當導致資料庫癱瘓的經驗。通過回顧故障發生的時間、系統簡介、時間線、問題分析和經驗總結等方面的內容。討論操作時間不當、操作流程不當、缺乏執行計劃和限流機制等問題,並提出一些建議,如確認資料庫更新時間、優化更新操作、使用限流工具、設置超時時間和重試機制、調整資料庫參數... ...
  • 最近研發apk校驗服務,很多游戲安裝包兩三個G,如果整個拿去校驗,耗時基本二十多秒,這還僅僅是校驗的時間,如果加上下載的時間,等待時間太長了 網上很多方案嘗試了一下,不太行 1、fast md5 一個第三方庫,csdn有人用過說可以提升40%的速度,然後我去試了一下,本來9秒可以完成的校驗,變成了2 ...
  • 如果你會 Java, 那麼來看一看 Kotlin , 基礎入門。 如果你不理解 Kotlin 的lambda 表達式,那麼來看一看,幫助你真正理解函數類型,lambda 表達式。 ...
  • >我們是[袋鼠雲數棧 UED 團隊](http://ued.dtstack.cn/),致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 >本文作者:琉易 [liuxianyu.cn](https://link.juejin.cn/?target=ht ...
  • 需求: 設計一個標題,讓中間部分隨著文字而撐大,同時文字漸變,兩邊自適應,這種情況就不能用傳統的背景圖片了,想到可以使用圖片邊框來做 解決思路: 1.需要一個大盒子和三個小盒子 2.大盒子設置display:flex; 左右兩個小盒子分別設置flex-grow; 並設置背景圖片 3.給中間盒子設置邊 ...
  • 此篇文章用於記錄柏成從零開發一個canvas九宮格手勢解鎖器的歷程。我們基於 canvas 實現了一款簡單的九宮格手勢解鎖器,用戶可以通過在九宮格中繪製特定的手勢來解鎖。 ...
  • ##一、定義 **使用原型實例指定待創建對象的類型,並且通過複製這個原型來創建新的對象。原型模式是一種創建型模式。** ##二、描述 **包含以下三個角色:** ![](https://img2023.cnblogs.com/blog/1780813/202305/1780813-202305271 ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...