[IT] CORS 跨原始來源要求

TL;DR CORS (Cross-Origin Resource Sharing) 是一個支援安全跨源請求和資料傳輸的機制,用於在瀏覽器和伺服器之間進行跨源請求。 這是一個 W3C 標準,可讓伺服器放寬相同原始來源原則。 不是安全性功能,CORS 會放寬安全性。 允許 CORS 並不會增強 API 的安全性。CORS 的運作方式 允許伺服器明確允許某些跨原始來源要求,同時拒絕其他要求。 比舊版技術 (例如:JSONP) 更安全且更有彈性。 何謂相同原始來源 如果兩個 URL 具有相同的配置、主機和連接埠,則其原始來源相同 (RFC 6454)。 這兩個 URL 具有相同的原始來源: https://example.com/foo.html https://example.com/bar.html 這些 URL 的原始來源與前兩個 URL 不同: https://example.net:不同的網域 https://www.example.com/foo.html:不同的子網域 http://example.com/foo.html:不同的配置 https://example.com:9000/foo.html:不同的連接埠 如何啟動 CORS 有三種方式可以啟用 CORS: 在中介軟體中,使用具名原則或預設原則。 使用端點路由。 使用 [EnableCors] 屬性。 搭配具名原則使用 [EnableCors] 屬性能夠以最精細的程度來控制對於支援 CORS 之端點的限制。 ...

January 19, 2024 · 3 分鐘 · Rain Hu

[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. 求總體標準差 由\((1)\)式展開 得 \(\boxed{\sigma = \sqrt{\frac{(\sum x_{ai}^2+\sum x_{bi}^2)}{n}-\bar x^2}}-(6)\) 將\((5)\)代入\((6)\) \(\boxed{\sigma=\sqrt{\frac{n_a(\sigma_a^2+\bar x_a^2)+n_b(\sigma_b^2+\bar x_n^2)}{n}-\bar x^2}}-(7)\) 其中 \(\boxed{\bar x=\frac{n_a\bar x_a + n_b\bar x_b}{n}}-(8)\) 故我們可以從上式輾轉得通式: \(\boxed{\sigma=\sqrt{\frac{\sum(n_i(\sigma_i^2+\bar x_i^2))}{n}-\bar x^2}}-(9)\) 或寫成 \(\boxed{\sigma=\sqrt{\frac{\sum(n_i(\sigma_i^2+\bar x_i^2))-\sum n_i\bar x_i}{n}}}-(9)\) summary 個數 \(\boxed{n=n_a+n_b=\sum n_i}\) 平均數 \(\boxed{\bar x=\frac{n_a\bar x_a+n_b\bar x_b}{n_a+n_b}=\frac{\sum{n_i\bar x_i}}{\sum{n_i}}}\) 標準差 \(\boxed{\sigma=\sqrt{\frac{n_{ai}(\sigma_{ai}^2+\bar x_{ai}^2)+n_{bi}(\sigma_{bi}^2+\bar x_{bi}^2)-(n_a\bar x_a+n_b\bar x_b)}{n_a+n_b}}=\sqrt{\frac{\sum(n_i(\sigma_i^2+\bar x_i^2))-\sum n_i\bar x_i}{\sum n_i}}}\) 4. sql 現有一 table 存有 avg_value std_value site_count with stats as ( select ... sum(site_count*avg_value)/sum(site_count) as avg_value, sqrt((sum(site_count*(square(std_value)+square(avg_value)))-sum(site_count*avg_value))/sum(site_count)) as std_value, sum(site_count) as site_count from data where ... group by ... ) select * from stats

December 12, 2023 · 1 分鐘 · 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 組成。 ...

November 6, 2023 · 2 分鐘 · 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 是一最獨立於任何技術或產品的架構原則,就像多態與封裝一樣。 ...

November 2, 2023 · 5 分鐘 · 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 的指令,這個指令將會執行前述的三個動作,作為一個封裝的業務流程。 ...

November 1, 2023 · 2 分鐘 · 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. - Eric Evans 2014, Domain-Driven Design Reference […] 指定一個團隊同意共享的領域模型的子集,並明確劃定其範疇。保持這個核心部分的規模小。[…] 這些明確共享的內容具有特殊的地位,不應在未與其他團隊諮詢的情況下進行更改。 - 艾瑞克·埃文斯 2014,領域驅動設計參考資料 ...

October 31, 2023 · 2 分鐘 · hgraca

[IT] 乾淨架構 Clean Architecture

Robert C. Martin (aka Uncle Bob) 在 2012 年在他的部落格上發表了他對於乾淨架構的想法,並在幾個會議上進行了關於乾淨架構的演講。 乾淨架構套用了許多為人熟知的概念、規則和模式,並解釋如何將它們組合在一起,以提出一種標準化的應用程式建構方式。 站在 EBI, Ports & Adapters 與洋蔥架構的肩膀上 乾淨架構背後的核心目標與 Ports & Adapters(六邊形)和洋蔥架構的目標是相同的: 工具的獨立性。 交付機制的獨立性。 獨立測試的可行性。 在發布有關乾淨架構的文章中,這是用來解釋整體概念的一張圖: 正如 Uncle Bob 在他的文章中所說,上面這張圖嘗試將最新的架構思想整合成一個可行的概念。 讓我們將乾淨架構的圖表與用來解釋六角架構和洋蔥架構的圖表進行比較,看看它們在哪些地方相符: 工具和交付機制的外部化 六角形架構專注於將工具和交付機制從應用程式中外部化,使用介面(ports))和適配器(adapters)。這也是洋蔥架構的核心價值之一,如圖所見,UI、基礎設施和測試都在圖表的最外層。乾淨的架構具有完全相同的特性,將 UI、Web、DB 等都放在最外層。最後,所有應用程式核心程式碼都是與框架、庫獨立的。 依賴方向 在六角架構中,我們並沒有任何明確的指示告訴我們依賴性的方向。然而,我們可以輕易地推斷出來:應用程式有一個埠(或介面),必須由一個適配器來實現或使用。因此,適配器依賴於介面,它依賴於位於中心的應用程式。外部的東西依賴於內部的東西,依賴性的方向是朝向中心。在洋蔥架構圖中,我們也沒有任何明確的指示告訴我們依賴性的方向,然而,在他的第二篇文章中,Jeffrey Palermo 非常清楚地說明所有的依賴性都是朝向中心。乾淨架構則是非常明確地指出依賴性方向是朝向中心。他們都在架構層面引入了依賴反轉原則。內圈中的任何東西都不能知道外圈中的任何東西。此外,當我們跨越邊界傳遞數據時,它總是以對內圈來說最方便的形式存在。 分層 六角形架構圖只顯示了兩層:應用程式的內部和外部。然而,洋蔥架構則將 DDD 中 application layer 融入其中:application service 持有用例邏輯(use case logic);domain service 封裝不屬於實體或價值對象的領域邏輯。與洋蔥架構相比,乾淨架構保留了 application layer(use case)和 entities layer,但似乎忽略了 domain service layer。然而,閱讀 Uncle Bob 的文章後,我們意識到他認為一個 entity 不僅是 DDD 意義上的 entity,而且是任何 domain object:「一個實體可以是一個帶有方法的物件,或者可以是一組數據結構和函數。」實際上,他合併了這兩個最內層的層級以簡化圖表。 ...

October 29, 2023 · 1 分鐘 · hgraca

[IT] 洋蔥架構 Onion Architecture

洋蔥架構 洋蔥架構是由 Jeffrey Palermo 在 2008 年提出的。在我看來,它是基於 Ports & Adapters 架構的構念,將領域(domain)放在應用程式的中心,將交付機制(UI)和系統使用的基礎設施(infrastructure, ex.ORM,搜索引擎,第三方API等)。差別是,它對內部進行了分層。 我們從分層架構學習到最基本的分層通常有: Presentation 呈現層 Application 應用層 Domain 領域層 Persistence 持久層 而 Ports & Adapters 架構隱含了兩個同心層: 外部:傳遞機制(delivery mechanisms)與基礎設施(infrastructure) 內部:業務邏輯 Ports & Adapters 和 Onion Architecture 同時擁有一個概念,那就是通過編寫適配器(adapter),將應用程式的核心與基礎設施隔離,以防止基礎設施滲透到應用程式核心中(意思是應用程式核心直接對基礎設施產生依賴)。這使得抽換應用程式使用的工具和交付機制變得更容易,提供了一些對技術、工具和供應商鎖定的保護。 這也賦予應用程式一種愉快的能力,即無需真實的基礎設施或交付機制就能運行,因為它們可以被模擬物件所替換,這易於進行程式碼的測試。 然而,洋蔥架構也告訴我們,在企業應用中,我們將不只有內部與外部這樣簡單的分層,在內部,也就是業務邏輯中,我們會增加一些我們從領域驅動設計(DDD)認識的一些層: 此外,它明確地闡述了 Ports & Adapters 架構中關於依賴方向的隱含概念: 外層依賴於內層, 內層對外層一無所知。 這意味著耦合的方向是朝向中心,為我們提供了一個獨立的物件模型(domain model),其核心不依賴任何東西。我們有足夠的靈活性可以改變外層,而不影響內層,更重要的層面。它在架構層面上運用了依賴反轉原則。 洋蔥架構的主要原則: 應用程式是建立在一個獨立的物件模型周圍。 內層定義介面,外層實現介面。 耦合的方向是朝向中心。 所有應用程式的核心代碼都可以獨立於基礎設施進行編譯和運行 此外,任何外層都可以直接呼叫任何內層,這不會破壞耦合方向,並避免創建僅包含無業務邏輯的 proxy methods,甚至是 proxy classes,僅為了符合某種分層方案。這也符合 Martin Fowler 所表達的。 […] the layers above can use any layer beneath them, not just the layer immediately beneath. - Jeffrey Palermo 2008, The Onion Architecture: part 3 […] 上層的層次可以使用任何位於其下的層次,而不僅僅是直接下方的那一層。 - 傑弗里‧巴勒莫 2008,洋蔥架構:第三部分 ...

October 29, 2023 · 1 分鐘 · hgraca

[ML] sample1 - 手寫數字辨識

MNIST NIST(National Insitute of Standards and Technology) 是美國國家標準與技術研究院,MNIST 是由 NIST 所提供的一組經典的機器學習測資,可以想成是深度學習中的「Hello World!」,它由 60000張 訓練圖片與 10000 張測試圖片所組成,為手寫數字的灰階圖片,大小為 28 * 28 像素,分類 0 到 9 共 10 個數字。 可透過 keras 模組直接取得資料 >>> from tensorflow.keras.datasets import mnist 輸入 mnist.load_data() 可取得 mnist 資料集,回傳值為 2*2 的 tuple of ndarray。 >>> (train_images, train_labels), (test_images, test_labels) = mnist.load_data() tuple 裡面裝載的是 NumPy 的 ndarray 物件,我們可以利用 o.shape 來取得 ndarray 的屬性 len(o) 來取得陣列的個數 >>> train_images.shape (60000, 28, 28) # 3 軸陣列,其大小為 60000 * 28 * 28 >>> test_images.shape (10000, 28, 28) # 3 軸陣列,其大小為 10000 * 28 * 28 >>> len(train_labels), len(test_labels) (60000, 10000) # 訓練集與測試集各有 60000 與 10000 筆 labels >>> train_labels array([5, 0, 4, ..., 5, 6, 8], dtype=uint8) # train_labels 裝 60000 筆資料對應的解答(0-9 的數字) 我們可以利用 matlabplot 把圖片印出來看看 plt.matshow(train_images[0], cmap = plt.get_cmap('gray')) plt.show() 用 Dense 層建構神經網路 首先我們需要建立神經網路架構,層(layer)是組成神經網路的基本元件,一個層就是一個資料處理的模組。具體而言,每一層都會從資料中萃取出特定的轉換或表示法,經過數層的資料萃取(data distillation)後,將資料「過瀘」成最後特定的轉換或表達(representation)。 ...

October 28, 2023 · 3 分鐘 · Rain Hu

[IT] 埠與適配器架構 Ports & Adapters Architecture aka 六邊形架構 Hexagonal Architecture

埠與適配器架構(又稱為六角架構)是由 Alistair Cockburn 所構想,並在 2005 年於他的部落格中寫下。這是他用一句話定義其目標的方式: Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases. - Alistair Cockburn 2005, Ports and Adapters 允許一個應用程式能夠同等地由用戶、程式、自動化測試或批次腳本驅動,並且能夠在與其最終運行時間設備和數據庫隔離的情況下進行開發和測試。 - 艾利斯特·科本 2005,端口與適配器 我看過一些討論「Ports & Adapters 架構」的文章,其中大量提到了分層(layers)。然而,在原始的 Alistair Cockburn 的文章中,我並未讀到任何關於分層的內容。 Ports & Adapters 架構的思想是將我們的應用程式視為系統的中心產物,所有的輸入和輸出都通過一個端口進入/離開應用程式,該端口將應用程式與外部工具、技術和交付機制隔離。應用程式應該對誰/什麼正在發送輸入或接收其輸出一無所知。這旨在提供一些保護,以防止技術和業務需求的演變,促使產品在開發完成後不久就因為技術/供應商的封鎖而變得過時。 在這篇文章中,我們將深入探討以下主題: 傳統方法的問題 傳統的方法在前後兩端都可能帶來問題。 在前端方面,我們最終會有業務邏輯滲透到 UI 中(例如,當我們在控制器或視圖中放置用例邏輯,使其在其他 UI 中無法重用)或甚至是 UI 滲透到業務邏輯中(例如,由於我們在模板中需要一些邏輯,因此我們在我們的實體中創建方法)。 在後端方面,我們可能會有外部庫和技術滲透到業務邏輯中,因為我們可能會透過類型提示、子類別化,甚至在我們的業務邏輯內實例化庫類別來直接引用它們。 ...

October 27, 2023 · 1 分鐘 · hgraca