STRING_AGG
☘️ 人的一生中有三大難題:
中午吃什麼?
明天要不要請假?
怎麼把一堆資料拼成一句話?
前兩個我還在想,第三個已經找到解答了—— STRING_AGG。
他是 SQL 裡常用來做文字串接的聚合函數,官方定義是這樣子的 :用於把 “指定的欄位” 串成一個 “以指定分隔符分隔的字符串”,不用寫一堆複雜的迴圈或自製拼接邏輯
123456STRING_AGG ( expression, separator ) [ <order_clause> ]<order_clause> ::= WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
說到文字串接就讓我想到,每天上班打開公司群組,就像打開一個沒人整理過的資料表,一堆廢話、貼圖、+1、讚、下午茶,語焉不詳的訊息而零散像剛剛爆炸過。有時真的很想把他們 STRING_AGG 起來丟到任何看不見的地方
🧪 實戰「那個誰,幫我把這個資料表裡的這些串在一起」老闆手上揮舞著資料像在招魂一樣,語音剛落, ...
HttpClient - Header 都亂了,我還怎麼好好當人
我們人生中最尷尬的某些時刻,不是沉默,而是訊息傳錯像是你在聊天室打了一句「我覺得主管頭好禿」,下一秒才發現你傳的是公司群組聊天室。你懊悔、你重開手機假裝這一切會 Reset、數秒鐘後你開始思考辭職信該不該寫得文藝一點。
又或者你做為一個老師,把生活中的小抱怨傳到學生群組中
來自 Thread 一篇貼文的情境支援
這種「錯頻溝通」其實不只在人生會發生,連程式也會。我們寫程式時,也會很天真地以為,訊息只會送到我們想送的人那裡。但如果發送 Request 時,將秘密資訊設定在 HttpClient.DefaultRequestHeaders 上,相當於把「寫給 A 的情書,貼在公共佈告欄」。
📲 為什麼會這樣?HttpClient 是一個設計上建議共用的元件,也就是說,我們應該用一個 HttpClient instance 去處理多個 request,以節省資源、避免連線耗盡(像是 socket exhausted)。
但問題也就來了:既然大家都用同一支手機在傳訊息,那麼貼在手機上的「身份識別貼紙」(也就是 DefaultRequestHeaders 裡的 token)是不是有可能搞混?
...
BaseAddress - 那一撇,決定了命運的方向
這是一隻蛇蛇。突發奇想想用 / 畫出來當開場,欸還真不錯,看著看著竟有點可愛(?)
🐍 寄錯的明信片有時候,一行程式碼,就像一張寄出的明信片。
你滿懷誠意地寫下問候、地址、郵遞區號,甚至還貼上特別版的郵票,只為讓那封來自心底的訊息,抵達你想念的那個人手上。
但你忘了一件事──地址格式要「符合規格」。
就像 HttpClient 看著那個不完整的 BaseAddress,露出一種:「呃,好啦我自己猜看看好了」的尷尬表情。於是它猜錯了,訊息雖然出發了,但永遠沒有人收到。
🐍 建立實驗讓我們來實驗一下 BaseAddress 設定錯誤會發生甚麼事吧!
1.Autofac 註冊HttpClient12345678910111213141516171819public class ServiceModule : Module{ protected override void Load(Autofac.ContainerBuilder builder) { builder.RegisterType<BoredHttpClient>() .As& ...
Json Ignore
最近處理一個快取文案與顯示前台文案不一致的 Bug,尻了很久,找不到原因,最後才發現是因為某個 Class Property 被掛上了JsonIgnore,導致即使這個 Property 已經拿到了打 API 翻譯後的新文案,在將資料存進 RedisCache 的過程中,這個 property 的資料沒有送出去,而沒有正確的快取,因此重刷後又會拿到舊的文案(抓到舊 Cache)
當初其實有看到這個 Attribute 但沒有在意,而這就是所謂的 你不理他,他也不理你的境界
搜了一下專案發現,使用率其實挺高
Jason Feels Ignored
JsonIgnore基本上作用用於在序列化和反序列化期間忽略特定的屬性,讓該屬性資料不要傳遞出去,.NET 中,我們熟知的System.Text.Json 以及 Json.NET都有支援 JsonIgnore Attribute,作用上基本也相同。
舉個栗
假設有一間公司他的工作簡歷需要填上你是否是光頭的資訊,因為實在太不好意思,所以我只好偷偷加上 JsonIgnore 沙小
1234567891011121314151617181920pub ...
Asynchronous - 第一章:雲端中的未竟之事
我拿著號碼呼叫器,坐在靠窗的位置。
咖啡廳裡播放著熟悉的爵士樂,氣味是熱牛奶與咖啡豆交融後的溫暖。呼叫器還沒響,但我確定店員剛剛有聽見我點了那杯熟成黑咖啡。
我不確定她現在是不是正在打奶泡,或是還在處理上一張訂單;我也不確定我該不該起身確認一下。但最終我選擇坐著,等她做好準備、等震動響起,等那杯「尚未完成的事」,被端到我手中。
🎵 章節一:傳訊以後的沉默 —— S3 上傳的非同步陷阱
這是一段將資料上傳到 S3 的程式碼
12345678910111213private async Task UpdateS3DataAsync(string s3RecordData, string s3Path){ using var stream = new MemoryStream(Encoding.UTF8.GetBytes(s3RecordData)); var request = new PutObjectRequest { BucketName = this._bucketName, InputStream = stream, Key = s ...
Asynchronous - 第二章:任務 (Task)
清晨,陽光尚未透過窗簾,我們站在廚房前,嘗試用程式煮一頓早餐。那是一個沒有 await、沒有 Task 的時代,所有的流程只能靠一層一層的 callback 串接。
🎵 callback hell
乍聽之下,好像還不難 煮水、烤麵包、沖咖啡、煎蛋,各做各的
但實際上,設計上的重點是 : 程式必須非常確切地知道「什麼時候可以開始下一步」。我們不能一開始就同時烤麵包、煎蛋,因為你得等水煮好才能確定一切準備開始。
所以寫了第一個 callback:水煮好後要做三件事。那三件事每一個也不是即時完成,它們也要非同步地執行完之後,才能說「早餐好了」。於是你只好在第一個 callback 裡再寫三個 callback,讓它們「各自完成時回報進度」。
而這些回報又必須集中到某個地方統一判斷:「三件事都完成了嗎?」才能進一步呼叫最後的完成通知。就這樣,每一個步驟都像是娃娃裡的另一個娃娃:你打開一個 callback,裡面又包了一個 callback,再包一個。每一層都綁著條件與時序,錯一個就會讓整體邏輯崩塌。
每一口麵包、每一杯咖啡的背後,其實藏著的是:「時機控制的難度、流程依賴的交織,以及錯 ...
OutputCache
🍂 與其他快取的差異最大的差異,是他快取的維度是整個 API 回傳的結果,但與 Redis 等獨立快取系統相比,OutputCache 的使用門檻較低,無需額外安裝與維護快取伺服器,只要設定好屬性即可立即套用,對中小型應用特別友善。
🍂 專案觀察
Cache.Config集中管理設定值
🍂 設定OutputCache 屬性,我們可以指定多項快取參數,其中的 Location 是非常關鍵的設定,它決定了快取資料的儲存位置,包含:
Client 快取存在用戶端(例如瀏覽器)。
Server 快取存在伺服器的記憶體中。
Any 交由系統決定最合適的位置。
在使用 OutputCache 機制時,快取資料的仍受到一定限制,以避免對系統資源造成過大負擔。以下為主要的限制項目:
SizeLimit 指快取區域的總容量上限。當快取資料總量達到此上限時,若未進行資料逐出(Eviction),系統將不再快取任何新的回應。預設上限為 100 MB。
MaximumBodySize 指單一回應(Response Body)可被快取的最大容量。若回應內容超過此大小,系統將不進 ...
Flag Enum - 人生應該有更多種可能性
上回我們聊了 Enum 對這世界建立秩序的重要性,但有一個問題是
一個東西可能會同時擁有「多個狀態」,我們希望可以用「一個變數」表示出這些狀態的「組合」。
如同人不只是單一角色,而是多重身分的集合,在人生裡,我們每個人都不只是一種角色:
你可能是學生
同時是 朋友的情感諮商專家
同時是 家庭的支撐者
同時是某個創作者、夢想家
普通的 Enum 是「單選題」,例如有個權限控管的 Enum 像這樣
1234567enum FilePermission{ Read, Write, Execute}
導致你只能寫
1var permission = FilePermission.Read;
但,通常我們會希望同時可以 Read 和 Write,怎麼辦?這時候你可能會想用 List、Array、HashSet 等來處理:但這樣會比較麻煩,判斷時也比較繞口,十分痛苦
12var permissionList = new List<FilePermission> { FilePermission.Read, FilePermission ...
Enum - 關於溝通
阿罵 : 要吃水果嗎我 : 不用
…
阿罵 : 要吃蘋果嗎我 : 不用,謝謝阿罵…
阿罵 : 要吃芭樂嗎我 : 不要
…
阿罵 : 要吃蘋果還是芭樂我 : (。ŏ_ŏ)
…………
我們是否也曾在溝通上感到無力 ? 是否想過為甚麼阿罵總是覺得你要吃水果 ?其實你知道阿罵只是想跟你聊聊天、想跟你有更多的互動你的拒絕也不是討厭水果甚至討厭阿罵,你只是當下沒有足夠的耐心與阿罵交流,或是某種程度上是因為溝通成本太高
溝通,是一門藝術,更是一種選擇。人生中最痛苦的事之一,莫過於你以為你說得很清楚,對方卻完全接收不到對應的資訊。這樣的錯頻,在程式世界裡也屢見不鮮。你明明送出了一個清楚的 StatusEnum.Full,卻被序列化成一個看似陌生又難以理解的 2。又或是,在情感世界裡,你說「我很好」,但其實你需要的是「你懂我」。真正的溝通,從來不是你說了什麼而已,而是雙方是否都「懂了」。
JSON 序列化與反序列化假設我們今天定義訂單的結構
123456789101112131415public enum StatusEnum{ WaitingToPay, Processing, Fini ...
Enum - 限制,是自由的基礎
凡可列舉者,皆應被命名,用數字或字串記錄分類,像在沙地上寫字。風吹就散,誰都能改,誰都會迷路。唯有列舉(Enum),能為混亂命名,能讓程式碼之神歸位,如編鐘之列、星辰之座。有些人會說,Enum 限制了自由,但真相是:「沒有邊界的自由,終究會走向混亂。」
說到這裡,應該不難理解,Enum 的本質,可以減少混亂值、提升可讀性、強化型別安全,杜絕魔法數字與野生字串,我們會說,有結構的程式碼,是對未來同事最好的善意。當你看到一個架構龐大的 C# 專案,結果一個收藏 Enum 的資料夾都沒有時,個人認為,隔天就可以提交離職信了(當天先去收個驚)
我們來定義一下它存在的意義
Enum 用來代表「一組固定、有限、離散的值」,
讓我們的程式碼更有語意、更安全、更容易維護。
舉個例子處理訂單的狀態時(待處理、處理中、完成、取消),當我們 hardcode 字串在做判斷的話會長 ...