對 Oplog 不熟的朋友,建議先閱讀之前的內容


四年一度的大型盛事終於結束,來回顧一下這個我們都知道,卻隱藏得很好的 MongoDB 殺手 - Oplog。


在流量真正進入之前,我們進行了多次的功能驗證、壓力測試,確保在各個環節都沒有問題,對於各個服務的狀態也甚是滿意。展開了 MongoDB Atlas 監控,正式迎接挑戰!

剛開始我們很明顯感受到流量帶來的壓力,各項數據都還是穩定、可預期的,這時候是第一個錯誤。

等到第二天、第三天,我們開始發現 Oplog 的 headroom 開始有降低趨勢,這部分根 Oplog GB/Per hour 是呈現相反的,畢竟量多了,自然餘裕就開始減少。

第一個錯誤是沒有仔細評估合理性,對於流量的增長,到底多少是合理的呢?這個在事情必須要充足的測試才有辦法進行推斷。

這個問題也衍伸出另一件事,就是全服務的壓力測試非常重要,在 pre-production 環境應該事先給予充足的壓力測試。

閱讀全文 »

我們在使用二維陣列(或者更多)時,以前的語言會預先宣告,例如這樣:

1
2
3
4
5
6
int[,] array = new int[,]
{
{1,1,3},
{2,0,0},
{3,1,0}
};

這樣子宣告會造成空間的宣告浪費,正確的方式應該是使用 jagged(不定長度) 的陣列宣告:

1
2
3
4
5
6
int[][] array =
{
new int[] {1,1,3},
new int[] {2},
new int[] {3,1}
};
閱讀全文 »

RSS(Really Simple Syndication) 最早是由 Netscape 制定的協定,因為開源、開放與技術演進等問題,最後陸續衍伸出 ATOMJSON Feed。簡單來說這項技術是讓你能夠透過這個協定,訂閱多個網站,一但網站內容有更新,你就會收到通知。可以想像成 Youtube 的訂閱與開啟小鈴鐺功能。


安裝

首先我們使用的是 hexo-feed 套件,幫我們一次建立出這三種 RSS 格式。

1
npm install hexo-feed --save-dev

設定 Feed

安裝好後,我們找到 _config.yml,在最下面新增這段設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
feed:
limit: 20
order_by: "-date"
tag_dir: "tag"
category_dir: "category"
rss:
enable: true
template: "themes/theme/layout/feedtemplate/rss.ejs"
output: "rss.xml"
atom:
enable: true
template: "themes/theme/layout/feedtemplate/atom.ejs"
output: "atom.xml"
jsonFeed:
enable: true
template: "themes/theme/layout/feedtemplate/json.ejs"
output: "feed.json"

設定說明:

alt

閱讀全文 »

與高手共同合作是一件令人興奮的事,在很多小細節上能夠學到進階技巧以及錯誤用法,這些東西在平時工作上很不容易發現,且不見得有人能夠提點,甚至是產品運行後短時間不會有問題,直到爆炸的那一刻。作為受益者,我也想繼續分享這些部分,讓閱讀本篇文章的人也能夠枝微末節處,精進 C# 技巧。


宣告空陣列

我們很常會使用陣列來進行資料傳遞,比起 List 更安全且快速,若沒有改變元素或者長度,都應該使用陣列的。(兩者扣除效能外,使用情境也是差異很大)

  • 錯誤的宣告
1
var array = new int[0];

若很確定需要宣告一個空陣列,上述的方法會產生記憶體的分配(allocate),在現在硬體設備強大下,雖然不容易發現,但會使得程式肥大、浪費且給自己埋下不定時炸彈。

  • 正確的宣告
1
var array = Array.Empty<int>();

這樣一來就不會真正的佔用記憶體分配了。

閱讀全文 »

  1. 本文是給猶豫是否購入電子閱讀器的人閱讀,沒有產品推薦。
  2. 這裡沒有業配這種東西,請安心服用
  3. 我有購買電子閱讀器,且使用超過一年以上

時常有朋友提到電子書與紙本書的抉擇,與其每次辛苦解釋與比較,不如寫一篇文章,以後就貼連結給需要的人

這邊會比較三位選手:

  1. 電子閱讀器
  2. 電子書
  3. 紙本

先講結論:沒有最佳解,只有最適合


紙本

很多人就是對於紙本的手感愛不釋手,這個連我自己都是,翻頁速度是三者最佳!還可以有二手市場買賣,省錢啦!

缺點就是攜帶性不好、占空間。曾聽過一個有趣的說法,如果你是住在寸土寸金的都市,可以計算一下藏書會占掉你室內多少坪數,就知道成本有多可觀(要算上書櫃的設計喔)。

電子書

閱讀全文 »

LINQ(Language Integrated Query),在 .Net Framework 3.5 之後發布的技術,讀作 “link”,不是 “另Q”。照中文翻譯就是語言整合查詢,大概就是這個意思,雖然背後有很多實作概念,但目前還沒有要提到。

使用關聯式資料庫儲存資料必然使用 SQL 語法查詢,LINQ 這項技術能夠讓你在程式語言中直接使用類似 SQL 語法來查詢、操作、聚合資料等。很古早時候要從一個陣列中找到符合條件的程式寫起來很辛苦,舉個例子,找到數值大於 5的值有哪些:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var data = new List<int>() {1,3,5,7,9};
var greaterThan5Data = new List<int>();

foreach (var item in data)
{
if (item > 5)
{
greaterThan5Data.Add(item);
}
}

foreach (var item in greaterThan5Data)
{
Console.WriteLine(item);
}

當然,上述例子是比較誇張的,但事後回想,在 LINQ 問世前,或者工作經驗比較不足時,確實也都是類似的做法。

1
2
3
4
5
6
7
8
9
var data = new List<int>() {1,3,5,7,9};

var greaterThan5Data = from item in data
where item > 5;

foreach (var item in greaterThan5Data)
{
Console.WriteLine(item);
}

這樣是不是簡潔很多了?
不是!還可以再簡潔!

C# 這個語言進步速度飛快,扣除 語法糖(syntax sugar) 之外,很多技術都在持續演進中。上面這個語法我們稱為 查詢表示式(Query Expression),在多一點的操作後就會變得閱讀性不佳(當然,多看總會習慣的),不過實作上更多的是使用另一種表示方法,Lambda Expression

1
2
3
4
5
6
7
8
var data = new List<int>() {1,3,5,7,9};

var greaterThan5Data = data.Where(item => item > 5);

foreach (var item in greaterThan5Data)
{
Console.WriteLine(item);
}

這兩者之間的差異就是哪個格式你看的習慣,或者團隊習慣使用哪一種,編譯後都是長得一樣的,所以也沒有存在效能上差異,除此之外 lamda 表示式還能夠延伸出更多使用的功能,在後面會演示一下。

以我個人的經驗來說,lamda 表示式是更方便排版與直觀上的閱讀。在設計上傾向讓這些 SQL 類型的過濾都放在資料庫做,一來這就是資料庫強項,二來減少資料傳輸 IO,把資料減少絕對是首選。

閱讀全文 »

  • “you don’t have permission to open this application”
  • “你沒有打開應用程式的權限”

從網路上下載的 .app 檔案很常遇到 “你沒有打開應用程式的權限”,這個警告彷彿每次 macOS 更新都會遇到,但其實問題很簡單處理。

  • Step1 開啟終端機(Terminal)

使用任何軟體或內建的都可以

  • Step2 找到要開啟 .app 的路徑
1
cd /Applications
  • Step3 輸入指令修改權限
1
sudo chmod -R 755
  • Step4 嘗試打開 app
閱讀全文 »

聲明:本文內容僅限個人所經歷、所學之觀點,不能完全代表行業與產業狀況


本人是完全在純軟體業打滾的,對於半導體或硬體廠的軟體需求印象停留在 MES、CRM、ERP、BOM 等,韌體更是完全沒涉獵。

前陣子參加了 TSMC 的 IT Day,深深被震撼到。使用的技術內容有 AI、ML、數據分析、容器化、雲原生、私有、公有與混合雲,完善的 DevOps,全部技術看下來,其實已經近乎完虐台灣的所有純軟公司了,這跟我原本認知大大不同。

分析一下原因:

  1. 相較於純軟公司,半導體廠有著「近乎無限的銀彈」,光是資本額與收入方式就無法相比,除非軟體公司有創新的商業模式,且有足夠的資金燒到產品上線後數年,還要考慮到 marketing 的成本。
  2. 順著無限的銀彈,也能招募近乎無限的人力。在選擇適合的軟體技術時,一個是單獨測試多時,另一個策略可以是分多組人馬,同時測試不同工具(產品),最終放在一起比較優缺點,這樣便能在短時間內找出最適合公司的工具。讓我想起專案管理的笑話:「專案需要六個月才能完成,於是找了 6 個工程師就能在一個月完成」,沒想到這是真的,甚至可以派 12 個工程師在一個月內更精確地完成。

經過這次的分享,我對於純軟的分壘又更模糊了,對於目前身處純軟的我又多了更多變數….?


後記:

感覺對於軟體工程師有很多想聊的,這應該會成為系列文的起頭。

閱讀全文 »

  • 使用環境:macOS
  • MongoDB 版本:不拘

我們要啟動 MongoDB 只需要使用 mongod 指令即可,但實務上總不可能只有這樣,尤其是要搭上 CI/CD、容器化等自動部署,因此本文先來講解如何使用 .conf 檔案來設定資料庫。


首先要知道的是 MongoDB 預設的資料庫路徑是 /data/db/,如果直接在 macOS 底下啟動,只會遇到這樣的錯誤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
MingYi mongod
2022-10-05T00:50:47.786+0800 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] MongoDB starting : pid=26591 port=27017 dbpath=/data/db 64-bit host=ApieMacbook.local
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] db version v4.0.3
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] git version: 7ea530946fa7880364d88c8d8b6026bbc9ffa48c
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] allocator: system
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] modules: none
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] build environment:
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] distarch: x86_64
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] target_arch: x86_64
2022-10-05T00:50:47.795+0800 I CONTROL [initandlisten] options: {}
2022-10-05T00:50:47.796+0800 I STORAGE [initandlisten] exception in initAndListen: NonExistentPath: Data directory /data/db not found., terminating
2022-10-05T00:50:47.796+0800 I NETWORK [initandlisten] shutdown: going to close listening sockets...
2022-10-05T00:50:47.796+0800 I NETWORK [initandlisten] removing socket file: /tmp/mongodb-27017.sock
2022-10-05T00:50:47.796+0800 I CONTROL [initandlisten] now exiting
2022-10-05T00:50:47.796+0800 I CONTROL [initandlisten] shutting down with code:100

可以看到 Exception: exception in initAndListen: NonExistentPath: Data directory /data/db not found.,嗯..資料夾不存在,於是我們嘗試著建立 /data/db/ 資料夾:

1
2
3
4
5
➜  / pwd
/
➜ / mkdir data
mkdir: data: Read-only file system
➜ /

會發現無法建立,這是因為 macOS 的安全機制緣故。我們在這邊不打算跟它硬碰硬,山不轉路轉,我們改成指定 MongoDB 的資料庫位置,使用的是 dbpath 設定:

ex: mongod --dbpath=/Users/mingyi/Documents/MingYi/data/db/

閱讀全文 »

在開始這個議題之前,先來閒聊這個速食當道世代,對於一個全新或者普羅大眾沒聽過的名詞,在台灣大部分的職場工作者都沒有太多時間去了解真正的意義,多半都是透過新聞或是網路文章,其內容可能是帶有政治傾向、未經過考證,甚至是斷章取義。舉個早年的例子,「宅男」一詞來自日本的「御宅族」,是形容對特定文化有深入研究者,內容不限於當今的動漫類,也包含了電影、鐵道與格鬥等,但來到了台灣,經過媒體大肆報導後,變成了喜好二次元文化、不修邊幅與不善交際的男性。之後又延伸了「宅」這個字,只要不出門就是「宅」。

我並不是要說這樣是好或壞,這也是一種語言的自然演進,只是這個過程並不健康,且媒體經常性的誤用原本意義、再演化出新的意涵。今天的「安靜辭職」一詞,也有這種狀況。


安靜辭職一詞爆紅於 TikTok,zkchilling的這部影片,其意思並不是指默默得、低調的離職,而是內心對於這份工作崗位選擇做到工作的基本要求,不上也不下,能理解為60-70分鐘個區間,不再追求工作表現卓越,不競爭往上爬,但也不會愧對於公司,將更多的精力與心思用在下班後的生活上。

安靜辭職強調的是,不要因為過度在意工作而毀了自己的生活

我認為這個名詞會再度活躍在媒體上是拜Covid-19所賜,部分類型員工得以(被迫)在家遠距上班。自從在家上班後,少了通勤花費的時間與精力,讓很多人重新開始省思汲汲營營上班的意義,以及少了上下班的分壘所帶來的隱性延長工時。(這部分我也在之前文章- 在台灣的遠距上班為何窒礙難行提到過)。

愚民政策後,亞洲新興的控制手段:讓人民越忙碌於工作,就越少時間去思考、了解其他事物,便更好管理。

當我嘗試著用「安靜辭職」四個字進行搜索,仔細的看了一些文章後,蠻多文章的觀點都是非常極端,使用了假探討、真主觀的方式來洗腦讀者,任何事過於絕對肯定是有問題的。

公司老闆與主管必然不希望下屬是「安靜辭職」的狀態,在管理方面會顯得很無力且辛苦。這樣的員工很容易與「擺爛」劃上等號,甚至誇張一點會被形容為沒上進心

溫水煮青蛙的壞習慣是最難以發現的,當意識到時通常為時已晚

閱讀全文 »