IEEE 也宣佈禁用 Lenna 圖了

Lenna (Lena) 是個經典的標準測試圖片,一方面是因為有很多細節可以觀察 image-related algorithm 的情況,另外一方面也是因為這張圖是取自 1972 年的 Playboy 雜誌:

Lenna (or Lena) is a standard test image used in the field of digital image processing starting in 1973, but it is no longer considered appropriate by some authors.

To explain why the image became a standard in the field, David C. Munson, editor-in-chief of IEEE Transactions on Image Processing, stated that it was a good test image because of its detail, flat regions, shading, and texture. He also noted that "the Lena image is a picture of an attractive woman. It is not surprising that the (mostly male) image processing research community gravitated toward an image that they found attractive."

也因為後者的原因,後來也有愈來愈多其他的圖片可以達到類似的效果 (甚至更好),就有替代的聲音出現了。

另外一方面,Lena 本人在 2019 年也提到希望淡出的想法:「How a Nude “Playboy” Photo Became a Fixture in the Tech World」。

But I retired from modeling a long time ago. It’s time I retired from tech, too.

而最新的消息就是 2024/04/01 開始,IEEE 不再接受使用 Lenna 圖的投稿:「Institute bans use of Playboy test image in engineering journals」。

之後大概只會在歷史回顧的時候會引用提到了...

RFC 9512:application/yaml

看到「RFC 9512: YAML Media Type」這個,原來還沒有註冊 application/yaml 啊...

另外在 media type 的文件裡面,意外的給出了安全性的建議:

Code execution in deserializers should be disabled by default and only be enabled explicitly. In the latter case, the implementation should ensure (for example, via specific functions) that the code execution results in strictly bounded time/memory limits.

這邊用的是 should 不是 SHOULD,所以當一般的英文句子在讀,而非具有規範性的敘述。

但還是給了預設關閉 code execution 的建議...

Bluesky 支援 RSS 2.0

在「Bluesky has launched RSS feeds (openrss.org)」這邊看到 Bluesky 支援 RSS 2.0 的消息:「Bluesky has launched RSS feeds」。

以作者提到的例子來說,Jay Graber 的頁面上 (在「@jay.bsky.team on Bluesky」這邊) 有 auto-discovery link:

<link rel="alternate" type="application/rss+xml" href="https://bsky.app/profile/did:plc:oky5czdrnfjpqslsw2a5iclo/rss">

選擇 RSS 2.0 而不是 Atom,不知道是什麼原因...

有了 feed 以後現有的 RSS reader 都可以直接訂起來了,像是在 Slack 上可以用 /feed add [url] 訂閱。

Amazon RDS 推出 RDS Extended Support

AWSAmazon RDS 推出了 MySQL 5.7 與 PostgreSQL 11 的 RDS Extended Support 服務:「Your MySQL 5.7 and PostgreSQL 11 databases will be automatically enrolled into Amazon RDS Extended Support」。

直接看官方整理的這張表格比較清楚:

基本上都到 2027Q1 左右,差不多再多支援三年。

另外表上的時間有些接不起來的地方,則是在 Note 的地方說明。

其中 MySQL 5.7 的部分分成兩塊,其中 RDS for MySQL 5.7 的部分是比較清楚的:原來的 RDS standard support 到 2024/02/29,後續從 2024/03/01 馬上接付費的 RDS Extended Support。

Aurora MySQL 2 的 RDS standard support 則是直接一路到 2024/10/31,然後 2024/11/01~2024/11/30 的 RDS Extended Support 不收費,從 2024/12/01 開始收費:

RDS Extended Support for Aurora MySQL 2 starts on November 1, 2024, but will not be charged until December 1, 2024. Between November 1 and November 30, all Aurora MySQL 2 clusters are covered under RDS Extended Support.

而 PostgreSQL 11 的部分都一樣 (RDS for PostgreSQL 11 與 Aurora PostgreSQL 11),原來的 RDS standard support 到 2024/02/29,而 2024/03/01~2024/03/31 的 RDS Extended Support 則是免費的,從 2024/04/01 開始收費:

RDS Extended Support for PostgreSQL 11 starts on March 1, 2024, but will not be charged until April 1, 2024. Between March 1 and March 31, all PostgreSQL 11 instances on Aurora and RDS are covered under RDS Extended Support.

然後費用的部分也查的到了,是用 vCPU-hour 計算的,四條產品線的價位在 us-east-1 的計價是相同的,前面兩年是 $0.1/vCPU/hr,而第三年是 $0.2/vCPU/hr。

由於 RDS 的機器最少是 2 vCPU,所以一台機器至少要多付 $0.2/hr 的費用,這個費用基本上會比 RDS 費用還貴。

這邊給個比較的數字,同樣在 us-east-1 上,2 vCPU + 8GB RAM 的 db.t4g.large 要 $0.129/hr,而一樣 2 vCPU + 8GB RAM 如果是 db.m7g.large 則是 $0.168/hr,都還沒有 RDS Extended Support 貴;要到 r7g.large 這種以記憶體導向的 $0.1071/hr 才差不多跟上一樣的價錢。

另外一個方法應該就是改成自己在 EC2 上架設?這樣成本會因為 RDS 轉 EC2 的下降,整體大約會降到 1/4...

不過應該也會有公司就是用下去,在上面跑的好好而且很賺錢的東西就不想亂動...

GCP 提供每個區域的 Standard Tier Networking 每個月 200GB 的免費頻寬

GCP 提供每個區域 Standard Tier Networking 每個月有 200GB 的免費頻寬:「Announcing 200 GB free Standard Tier internet data transfer per month」。

這類優惠應該是要給練習或是試用的人用的,吸引他們放一些量上來...

另外雖然是每個區域都有 200GB/mo 的 free bandwidth,但通常也只會用一個或兩個區域,以台灣的 asia-east1 來說,如果有量在上面跑的話,省下來的會是 $0.07/GB 這個部分,大概就是 $14/mo 左右?

strlcpy() 與 strlcat() 被加入 glibc

Hacker News 上看到「Strlcpy and strlcat added to glibc 2.38 (sourceware.org)」這個,印象中極度排斥 strlcpystrlcatglibc 要包進去了。

主要的原因在原始的 commit log 裡面有提到,是因為 POSIX 標準要放入這兩個 function 了:

These functions are about to be added to POSIX, under Austin Group issue 986.

找了一下提到的 Austin Group issue 986,最後更新是 2022 年,看起來進度不快,但是就是一直推進?

反過來看了一下 Hacker News 上的討論,果然有人把當年 Ulrich Drepper 臭 BSD 流派的信件翻出來:「Re: PATCH: safe string copy and concetation」。

Python 內建的工具

Hacker News Daily 上看到「CLI tools hidden in the Python standard library」這個,在講 Python 內建的工具。

其中 python -m calendar 這組看起來還不錯,測了一下可以用 python -m calendar 2024 顯示所有 2024 的月曆,用 python -m calendar 2024 1 則可以顯示 2024 一月單月的月曆。

這操作起來比先前用的 ncal 好多了,先前用 cal 2024 會出現錯誤,因為只有一個參數時他會當作月份,而兩個參數時要把月份放前面,也就是用 cal 1 2024 才能正確顯示。

所以就把本來的 ncal 移除掉,改用 alias 來處理:「Add alias "cal".」。

其他的大多都有習慣的工具了,像是 base64 可以用 openssl base64 處理;而 json.tool 有 jq 可以用。

SQL:2023 的新玩意

Hacker News 上看到「SQL: 2023 is finished: Here is what's new (eisentraut.org)」這篇題到了 SQL:2023 標準的新東西,對應的原文在「SQL:2023 is finished: Here is what's new」這邊。

「UNIQUE null treatment (F292)」讓你可以決定 NULL 到底要不要算 unique,剛好跟之前寫過的「PostgreSQL 15 將可以對透過 UNIQUE 限制 NULL 的唯一性了」要做的事情一樣。

「ORDER BY in grouped table (F868)」則是針對沒有出現在 SELECT 的欄位頁可以 ORDER BY,看了一下說明,主要是在 JOIN 的時候限制住了。很明顯的 workaround 是多加上這個欄位,但就代表會增加傳回的資料量。

「GREATEST and LEAST (T054)」這個因為 MIN()MAX() 已經被 aggregate function 用掉了,所以只好另外取名。

「String padding functions (T055)」與「Multi-character TRIM functions (T056)」是熟悉的語法,各家都有對應的 function 可以做,但這次就放進標準化。

「Optional string types maximum length (T081)」是 VARCHAR 可以不用指定大小了,實務上應該是還好?

「Enhanced cycle mark values (T133)」這編提到的 recursive 真的是每次用每次忘,然後 cycle 這個功能就沒看懂了...

「ANY_VALUE (T626)」看起來可以隨機取出資料,搭配 GROUP BY '' 就不用拿 ORDER BY RAND() 這種髒髒的東西出來了?

「Non-decimal integer literals (T661)」與「Underscores in numeric literals (T662)」都是讓數字更好讀以及操作。

後面講了很多 JSON 功能,看起來是 SQL:2016 有先納入一些,但 SQL:2023 補的更完整了。

然後有 Graph 相關的標準也被定義進 SQL:2023,原文介紹的也不是很多,看起來是要跨足過來?

calloc() 與 malloc() 的差異

前陣子在 Hacker News Daily 上看到的,原文是 2016 的文章:「Why does calloc exist?」,裡面講的東西包括了 implementation dependent 的項目,所以要注意一下他的結論未必適用於所有的平台與情境。

malloc()calloc() 的用法是這樣,其中 calloc() 會申請 countsize 的空間:

void* buffer1 = malloc(size);
void* buffer2 = calloc(count, size);

第一個差異是,count * size 可能會 overflow (而 integer overflow 在 C 裡面是 undefined behavior),這點除非你在乘法時有檢查,不然大多數的行為都還是會生一個值出來。

calloc() 則是會幫你檢查,如果會發生 overflow 的時候就不會真的去要一塊記憶體用。

第二個差異是 calloc() 保證會將內容都設定為 0,這點在 POSIX 的標準裡面是這樣寫的:

The calloc() function shall allocate unused space for an array of nelem elements each of whose size in bytes is elsize. The space shall be initialized to all bits 0.

但作者就發現 malloc() + memset() + free() 還是比 calloc() + free() 慢很多:

~$ gcc calloc-1GiB-demo.c -o calloc-1GiB-demo
~$ ./calloc-1GiB-demo
calloc+free 1 GiB: 3.44 ms
malloc+memset+free 1 GiB: 365.00 ms

研究發現是 calloc() 用了 copy-on-write 的技巧,先把所有的 page 都指到同一塊完全被塞 0 的記憶體,只有在真的寫到該段記憶體時,系統才會要一塊空間來用:

Instead, it fakes it, using virtual memory: it takes a single 4 KiB page of memory that is already full of zeros (which it keeps around for just this purpose), and maps 1 GiB / 4 KiB = 262144 copy-on-write copies of it into our process's address space. So the first time we actually write to each of those 262144 pages, then at that point the kernel has to go and find a real page of RAM, write zeros to it, and then quickly swap it in place of the "virtual" page that was there before. But this happens lazily, on a page-by-page basis.

但畢竟這是 implementation dependent,看看有個印象就好。

C 語言裡面的 ??! 符號

Hacker News Daily 上看到這個奇怪的知識:「What does the ??!??! operator do in C? (stackoverflow.com)」,原文在 Stack Overflow 上:「What does the ??!??! operator do in C?」。

這是 trigraph,在 C89 就有了,從 Rationale for International Standard—Programming Languages—C 這邊的 5.2.1.1 可以看到 trigraph 的歷史原因:

Trigraph sequences were introduced in C89 as alternate spellings of some characters to allow the implementation of C in character sets which do not provide a sufficient number of non-alphabetic graphics

而且是強制要求實做:

Implementations are required to support these alternate spellings, even if the character set in use is ASCII, in order to allow transportation of code from systems which must use the trigraphs. AMD1 also added digraphs (see §6.4.6 and §MSE.4).

其中遇到的問題就是當年得決定 C 可以用的 charset,得考慮到很多不同機器 charset 相容性的問題:

The C89 Committee faced a serious problem in trying to define a character set for C. Not all of the character sets in general use have the right number of characters, nor do they support the graphical symbols that C users expect to see. For instance, many character sets for languages other than English resemble ASCII except that codes used for graphic characters in ASCII are instead used for alphabetic characters or diacritical marks. C relies upon a richer set of graphic characters than most other programming languages, so the representation of programs in character sets other than ASCII is a greater problem than for most other programming languages.

然後就使用了 ISO/IEC 646 這個標準 (要記得 Unicode 1.0.0 是 1991 年才出現):

The solution is an internationally agreed-upon repertoire in terms of which an international representation of C can be defined. ISO has defined such a standard, ISO/IEC 646, which describes an invariant subset of ASCII.

The characters in the ASCII repertoire used by C and absent from the ISO/IEC 646 invariant repertoire are:

[ ] { } \ | ~ ^

後面就是定義 ?? 當作 escape digraph。

算是一個歷史產物,現在不太需要用到了...