TechTrajectory

Explore the dynamic landscape of technology with TechTrajectory. This blog offers a unique perspective on the ever-evolving tech world, shedding light on the intricacies of system design and the latest innovations.

微服務:優勢與挑戰   Microservices: Benefits and Drawbacks

Summary 摘要 Content 內容 Keywords 關鍵字 Microservices Definition 微服務架構定義 Microservices architecture allows large teams to build scalable applications composed of many loosely coupled services. 微服務架構允許大團隊建立由許多松散耦合的服務組成的可擴展應用程序。 Microservices, Loosely Coupled, Large Teams 微服務、松散耦合、大團隊 Functional Domains 功能領域 For instance, shopping cart, billing, user profile, push notifications can be separate microservices, sometimes referred to as domains. 例如,購物車、帳單、用戶資料、推送通知等都可以是單獨的微服務,這些功能區域有時被稱為域。 Shopping Cart, User Profile, Domains 購物車、用戶資料、域 Communication Methods 通信方式 Microservices communicate through a mix of remote procedure calls (RPC), event streaming, or message brokers.

LeetCode 104. Maximum Depth of Binary Tree

104MaximumDepthofBinaryTree.py from typing import Optional, List import pytest # Definition for a binary tree node. class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right class Solution: def maxDepth(self, root: Optional[TreeNode]) -> int: # 如果節點為空,返回深度為0 if not root: return 0 # 使用遞迴的方式計算左子樹的深度 left_depth = self.maxDepth(root.left) # 使用遞迴的方式計算右子樹的深度 right_depth = self.maxDepth(root.right) # 返回左、右子樹的最大深度 + 1 # +1 代表當前層的深度 return max(left_depth, right_depth) + 1 # Helper function to create a binary tree from a list.

LeetCode 206. Reverse Linked List

206ReverseLinkedList.py from typing import Optional import pytest class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next class Solution: def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: # 初始化前一个节点为None,因为反转后的最后一个节点将指向None prev = None # 初始化当前节点为链表的头节点 current = head # 迭代链表,直到当前节点为None,即遍历完整个链表 while current: # 保存下一个节点的引用,以便在反转后重新连接 next_node = current.next # 将当前节点的指针反向指向前一个节点 current.next = prev # 更新prev为当前节点,以便下一轮迭代使用 prev = current # 更新current为下一个节点,继续迭代 current = next_node # 当循环结束时,prev将成为新的头节点,即反转后的链表的头部 return prev def reverseListRecursively(self, head: Optional[ListNode]) -> Optional[ListNode]: # 递归的终止条件:当链表为空或只有一个节点时,无需反转,直接返回 if not head or not head.

API效能優化技巧

增強API校能的各種技巧 Key Techniques to Enhance API Performance 摘要 内容 優化(Optimization)的先決條件 優化不應該是過程的第一步。首先應該通過負載測試和請求分析來確定實際的瓶頸,只有當確認API端點存在性能問題時,才開始進行優化。 緩存(Caching) 緩存是加快API速度的最有效方法之一。可以存儲昂貴計算的結果,以便稍後再使用而不需要重新計算。可以使用Redis或Memcached來緩存反應,以避免反覆訪問數據庫。 連接池(Connection Pooling) 通過維護一個開放的連接池,而不是為每個API呼叫打開一個新的數據庫連接,可以大大提高吞吐量。對於使用無伺服器架構的情況,連接管理可能更具挑戰性。例如,AWS RDS Proxy和Azure SQL Database serverless可以為你管理連接池。 避免N+1查詢問題(Avoid N+1 queries) 當訪問一個實體及其相關實體的數據時,可能會出現N+1問題。例如,如果要提取博客文章及其評論,應該使用單一查詢或兩個查詢(一個查詢文章,另一個查詢該文章的所有評論)來提取數據,以避免為每個帖子的評論進行單獨的查詢。 分頁(Pagination) 如果API回應返回大量數據,可以使用分頁來加速數據傳輸並減少客戶端的負擔。 使用輕量級JSON序列化(Lightweight Serializers) 當從API返回JSON回應時,序列化過程的速度可能會影響回應時間。考慮使用一個快速的序列化庫來將數據轉換成JSON格式。 壓縮(Compression) 通過在大的API回應負載上啟用壓縮,可以減少網絡上傳輸的數據量。現在有像Brotli這樣的更高效的算法,提供更好的壓縮比率。很多內容交付網絡(CDNs)像Cloudflare可以幫助你處理壓縮,從你的伺服器上卸載這個任務。 異步日誌(Asynchronous Logging) 在許多應用程序中,寫日誌的時間可以忽略不計。但在高吞吐量系統中,寫日誌的時間可能會累計。異步日誌可以幫助解決這個問題,這涉及主應用程序線程快速地將日誌條目放入內存緩存,而一個單獨的日誌線程將日誌條目寫入文件或發送到日誌服務。

LeetCode 933. Number of Recent Calls

lc933NumberofRecentCalls_test.go package lc import "testing" type RecentCounter struct { queue []int } func Constructor() RecentCounter { return RecentCounter{ queue: make([]int, 0), } } func (r *RecentCounter) Ping(t int) int { r.queue = append(r.queue, t) // 移除所有小於t-3000的請求 for len(r.queue) > 0 && r.queue[0] < t-3000 { r.queue = r.queue[1:] } return len(r.queue) } func TestRecentCounter(t *testing.T) { rc := Constructor() if got := rc.Ping(1); got != 1 { t.Errorf("rc.Ping(1) = %d; want 1", got) } if got := rc.

LeetCode 238. Product of Array Except Self

lc238ProductofArrayExceptSelf_test.go package lc import ( "fmt" "reflect" "testing" ) func productExceptSelf(nums []int) []int { n := len(nums) // 設定數組的長度變數 left, right := 1, 1 // 設定左側、右側乘積的變數,初始都是1 result := make([]int, n) // 初始化結果數組 for i := range result { result[i] = 1 } // 同時從左和從右遍歷數組 for i := 0; i < n; i++ { // 先將當前索引左側的乘積與結果數組中的元素相乘 result[i] *= left left *= nums[i] // 更新左側乘積 // 先將當前索引右側的乘積與結果數組中的元素相乘 result[n-i-1] *= right right *= nums[n-i-1] // 更新右側乘積 } return result // 返回結果數組 } func TestProductExceptSelf(t *testing.