[Statistics] a群體與b群體各別標準差求整體標準差

Given \(\sigma_a\) and \(\sigma_b\), Ask for \(\sigma\) 1. 簡化 \(\sigma\) 將 \(\sigma\) 乘開 \(\sigma = \sqrt{\frac{\sum{(x_i-\bar x)^2}}{n}}\) \(\sigma = \sqrt{\frac{\sum{x_i^2-2\bar x\sum{x_i}+n\bar x^2}}{n}}\) 平均等於總和除以個數 \(\frac{\sum x_i}{n}=\bar x\),故 \(\sigma = \sqrt{\frac{\sum x_i^2}{n}-\frac{2\bar x\sum x_i}{n}+\frac{n\bar x^2}{n}}\) \(\sigma = \sqrt{\frac{\sum x_i^2}{n}-2\bar x^2+\bar x^2}\) 得 \(\boxed{\sigma = \sqrt{\frac{\sum x_i^2}{n}-\bar x^2}}-(1)\) 2. 求個別平方和 由\((1)\)式可推得各別的標準差為 \(\boxed{\sigma_a = \sqrt{\frac{\sum x_{ai}^2}{n_a}-\bar x_a^2}}-(2)\) 且 \(\boxed{n = n_a+n_b}-(3)\) \(\boxed{\sum x_i^2=\sum x_{ai}^2+\sum x_{bi}^2}-(4)\) 欲求 \(\sum x_{ai}^2\),我們將\((2)\)式展開 \(\sigma_a^2 = \frac{\sum x_{ai}^2}{n_a}-\bar x_a^2\) \(\sigma_a^2+\bar x_a^2= \frac{\sum x_{ai}^2}{n_a}\) 得\(\boxed{\sum x_{ai}^2=n_a(\sigma_a^2+\bar x_a^2)}-(5)\) 3....

<span title='2023-12-12 22:16:04 +0800 +0800'>December 12, 2023</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;Rain Hu

[IT] DDD, Hexagonal, Onion, Clean, CQRS 大整合

本文是介紹我如何將 DDD, Hexagonal, Onion, Clean, CQRS Architecture 等架構概念整合在一起,我將它命名為 Explicit Architecture。上述的概念基本上都是通過了市場的試驗,並在許多高要求的平台上被應用。 系統的基本組件 首先回顧 EBI 與 Ports & Adapter 架構。這兩種架構都明確區分了哪些程式碼是應用程式的內部,哪些是外部,以及哪些是連接內部和外部的程式碼。 Ports & Adapters 明確地定義出了系統的三個部分: 使用者介面 (User Interface, UI) 商業邏輯(business logic)、應用程式核心(application core) 基礎設施(Infrastructure),如 DB、搜尋引擎或第三方API等工具。 我們真正應該關心的是應用程式的核心,這是讓我們的程式碼能夠完成其應有功能的程式碼。它可能會使用多種 UI(網頁、手機、CLI、API 等等),但實際執行工作的程式碼是相同的,並位於應用程式的核心,觸發它的 UI 實際上並不重要。 一個典型的應用程式流程從 UI 的程式碼開始,經過應用程式核心到基礎設施程式碼,再回到應用程式核心,最後將回應傳遞給 UI。 工具 Tools 工具指的是那些遠離我們系統核心程式碼,但為我們應用程式所用的工具,例如,DB、搜尋引擎、網頁伺服器或 CLI 控制台(儘管後兩者也是交付機制)。 雖然將 CLI 與 DB 分類在一起可能有些奇怪,儘管它們有不同的目的,但實際上它們都是應用程式使用的工具。關鍵的區別在於,CLI 和網頁服務器用於告訴我們的應用程式做些什麼,而 DB 則由我們的應用程式告訴它做些什麼。這是一個非常重要的區別,因為它對我們如何建構連接這些工具與應用程式核心的程式碼有著強烈的影響。 將工具和傳遞機制連接到應用程式核心 連接工具與應用程式核心的程式碼單元被稱為適配器(Ports & Adapters Architecture),適配器實現了將業務邏輯與特定工具進行通訊。 告知我們應用程式應該做什麼事的適配器稱為 Primary 或 Driving Adapters; 被我們應用程式告知應該做什麼事的適配器稱為 Secondary or Driven Adapters。 埠 Ports 然而,這些適配器並非隨機創建的,它們是為了適應應用程式核心的一個非常特定的入口點,也就是埠。埠不過是一種規範,說明工具如何使用應用程式核心,或者說明它如何被應用程式核心使用。在大多數語言中,以其最簡單的形式,這種規範,或埠,即是一個介面(interface),但實際上可能由多個介面和 DTO 組成。...

<span title='2023-11-06 23:38:13 +0800 +0800'>November 6, 2023</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;hgraca

[IT] 服務導向的架構 Service Oriented Architecture (SOA)

The SOA Style has been around since the late 1980s and has its origins in ideas introduced by CORBA, DCOM, DCE and others. Much has been said about SOA, and there are a few different implementation patterns but, in essence, SOA focuses on only a few concepts and doesn’t give any prescription on how to implement them: SOA風格自 1980 年代晚期便一直存在,其起源於 CORBA、DCOM、DCE 等等。關於 SOA 已經有很多討論,且有許多不同的實作,但本質上,SOA 只關注少數幾個概念,而且指引我們如何去實作: 使用者導向的應用程式。 可重複使用的商業服務。 獨立的技術堆。 自治性(獨立演進、可擴展性與可部署性) SOA 是一最獨立於任何技術或產品的架構原則,就像多態與封裝一樣。...

<span title='2023-11-02 22:32:25 +0800 +0800'>November 2, 2023</span>&nbsp;·&nbsp;5 min&nbsp;·&nbsp;hgraca

[IT] 從 CQS 到 CQRS

當我們有一個以數據為中心的應用程式,即只實現基本的 CRUD 操作,並將業務流程(即要更改的數據和更改的順序)留給用戶時,好處是用戶可以在不需要更改應用程式的情況下更改業務流程。另一方面,這意味著所有用戶都需要知道所有可以使用該應用程式執行業務流程的所有細節,這在沒有明確的規範且有大量人員參與其中時,將會是一個大問題。 在一個以數據為中心的應用程式中,該應用程式對業務流程一無所知,因此該 domain 無法擁有任何「動詞」,也就是說,應用程式本身無法做出除了改變原始數據以外的任何事情。它變成了數據模型(data model)的高度抽象。這些流程只存在於應用程式用戶的腦海中,或者甚至存在於釘在電腦螢幕上的便利貼中。 一個非凡且實用的應用程式旨在減輕使用者的「流程」負擔,透過捕捉他們的意圖,使其成為一個能夠處理行為的應用程式,而不僅僅是儲存數據。 CQRS is the result of an evolution of several technical concepts that work together to help provide the application with an accurate reflection of the domain, while overcoming common technical limitations. CQRS 是許多技術概念演變的結果,這些概念使應用程式能準確地反映領域(domain),並同時克服常見的技術限制。 命令查詢分離 Command Query Separation 正如 Martin Fowler 所述,「命令查詢分離」這個術語是由 Bertrand Meyer 在他的《物件導向軟體建構(Object Oriented Software Construction)》(1988年)中首次提出的 - 這本書被認為是物件導向早期最具影響力的書籍之一。 梅爾認為,作為一個原則,我們不應該有既改變數據又返回數據的方法。因此,我們有兩種類型的方法: Queries(查詢):返回數據但不更改數據,因此沒有副作用; Commands(指令):更改數據,但不返回數據。 換句話說,提問不應改變答案,而行動也不應回饋答案,這同時也有助於尊重單一責任原則。 然而,有些模式是這條規則的例外,傳統的佇列和堆疊會彈出在佇列或堆疊中的元素,既改變了佇列或堆疊,也返回了從中移除的元素。 命令模式 Command Pattern 命令模式的主要概念是將我們從資料中心的應用程式轉移到以流程為中心的應用程式,具有領域知識和應用程式流程知識。 在實際操作中,這意味著我們不再讓使用者執行 CreateUser, ActivateUser 和 SendUserCreatedEmail 這三個動作,而是讓使用者直接執行一個 RegisterUser 的指令,這個指令將會執行前述的三個動作,作為一個封裝的業務流程。...

<span title='2023-11-01 23:29:40 +0800 +0800'>November 1, 2023</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;hgraca

[IT] 事件驅動架構 Event-Driven Architecture

利用事件來設計應用程式似乎是 80年代後期開始的一種做法,我們可以在使用事件在前端或後端任何地方使用事件,當按下一個按鈕,涉及某些數據變更,或是執行某些後端動作時。 What/When/Why 就像類別(classes)一樣,組件(components)之間應該保持低耦合,但在內部應保持高內聚。當組件需要協作時,比如說組件A需要觸發組件B中的某些邏輯,自然的做法就是讓組件A調用組件B中一個物件的方法。然而,如果A知道B的存在,那麼它們就是耦合的,A依賴於B,這使得系統更難改變和維護,事件可以用來防止耦合。 如果我們有一個團隊只專注於組件B的工作,它可以改變組件B對組件A邏輯的反應,甚至不需要與負責組件A的團隊溝通。組件可以獨立進化:我們的應用程式變得更有機(organic)。 即使在同一個組件中,有時我們會需要執行程式碼作為一個行動的結果,但它並不需要立即執行,也就是說,當事件的結果互不影響的情境下,我們可以採用 異步(async) 的策略執行程式。 然而,這樣做也存在危險,如果我們不加選擇地使用事件,可能會使一個概念上高度內聚的邏輯被解耦。換句話說,本應在一起的程式碼被強行分開,變得很難追蹤、理解(類似goto語句),最後使得它變成:speghetti code! 為了防止我們的程式碼變成一堆混亂的 speghetti code,我們應該清楚的限制事件的使用規則。根據我的經驗,有三種情況下應該使用事件: 解耦元件。 執行異步任務。 追蹤狀態變更 (audit log) 1. 解耦元件 當元件A執行需要觸發元件B邏輯的動作時,我們可以選擇不直接呼叫它,而是將一個事件發送到事件調度器(dispatcher)中。元件B將會在調度器中監聽該特定事件,並在事件發生時作出反應。 這意味著A和B都將依賴於調度器和事件,但他們將對彼此一無所知,也就是說他們是解耦的。 理想情況下,調度器和事件都不應存在於任何組件中: 調度器應該是一個與我們的應用程式完全獨立的庫,因此應該使用依賴性管理系統安裝在一個通用的位置。在PHP世界中,我們會使用 Composer 將之安裝在 vendor 的資料夾。(C# 可以參考我 EventBus 的文章) 這個事件雖然是我們應用程式的一部分,但應該存在於兩個組件之外,以保持它們對彼此一無所知。該事件在組件之間共享,並且是應用程式核心的一部分。事件是 DDD 所稱的 共享核心(Shared Kernel) 的一部分。這樣,兩個組件將依賴於共享核心,但將對彼此保持不知情。然而,在單體應用程式中,為了方便,可以將其放置在觸發事件的組件中。 Shared Kernel 共享核心 […] Designate with an explicit boundary some subset of the domain model that the teams agree to share. Keep this kernel small. […] This explicitly shared stuff has special status, and shouldn’t be changed without consultation with the other team....

<span title='2023-10-31 23:25:09 +0800 +0800'>October 31, 2023</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;hgraca