tag:blogger.com,1999:blog-19662891355027643382024-03-19T17:13:59.328+08:00MaxkitInformation Sharing from Maxkit Fellowsmaxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.comBlogger585125tag:blogger.com,1999:blog-1966289135502764338.post-46973478595831471082024-03-18T08:19:00.004+08:002024-03-18T08:19:24.049+08:00Guava Collection 1 Immutable CollectionsImmutable Collections
ref: ImmutableCollectionsExplained · google/guava Wiki · GitHub
collection 的資料不一定需要隨時可以修改,如果可以任意修改,反而在某些時候,會造成問題。
不能修改的 collection,將資料傳給 untrusted libraries 使用,也不會被 library 任意修改資料
thread-safe,再多執行緒環境共用資料時,可避免同時修改發生問題
可節省 time, space
JDK 也有提供 Collections.unmodifiableXXX methods,但還是有可能有以下問題
unwieldy and verbose: 使用時必須要在每一個地方,都先產生一份
unsafe: 只有在沒有其他地方,有儲存原本 maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-15776952129983418342024-03-11T08:26:00.000+08:002024-03-11T08:26:08.840+08:00Guava in Java - ObjectUtilities基本工具
CommonObjectUtilities
equals
當使用 Object.equals 時,如果遇到某個物件為 null,就會發生問題
com.google.common.base.Objects.equal 可做 null Object 的比較
JDK 提供類似的 java.util.Objects.equals()
@Test
public void equals() {
com.google.common.base.Objects.equal("a", "a"); // returns true
com.google.common.base.Objects.equal(null, "a"); // returns false
com.google.common.base.Objects.equal("amaxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-38876775338695114322024-03-04T08:19:00.000+08:002024-03-04T08:19:05.637+08:00Guava Basic PreconditionsGuava 是 Google 開發的 Java 開源工具 Library。內容主要有兩個部分:擴充 Java Collection Framework,提供更好用的 function,例如cache, range,以及 hash function
使用 Guava 只需要在 maven pom.xml 直接加入 dependency 即可
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.2-jre</version>
<!-- or, for Android: -->
<!-- <version>maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-37115692658346377342024-02-26T08:20:00.001+08:002024-02-26T08:20:15.757+08:00Well-known URIwell-known URI 是網站上以 /.well-known/ 開始的網頁路徑,例如 https://www.example.com/.well-known/ 這樣的路徑。Well-known URI 是在 RFC 8615 定義,目的是在不同 http server 之間,提供該 http server 相關的一些資訊。
目前最常見的使用方式有兩種,第一種是在申請 http server SSL 憑證的時候,憑證中心會發送一個檔案給申請者,請申請者將該檔案放到 .well-known 的某個路徑下,讓憑證中心可以檢查確認憑證申請者確實有服務該網域的 http server 的所有權。
例如 Let's Encrypt 就是將驗證的檔案放在這個路徑下面 /.well-known/acme-challenge/,這是給 ACME (Automatic Certificate maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-66369003306077894672024-02-19T08:21:00.004+08:002024-02-19T08:21:46.103+08:00Java Date Time API以往處理日期是用 java.util.Date,以及 java.util.Calendar,但 Date 裡面不存在時區概念,只是 Timestamp 的一個 wrapper,Calendar 也很奇怪的將一月份的數值設定為 0,Java 8 以後可以改用 java.time.* API
java.time 這個 package 裡面有這些 class
Instant – represents a point in time (timestamp)
LocalDate – represents a date (year, month, day)
LocalDateTime – same as LocalDate, but includes time with nanosecond precision
OffsetDateTime – maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-14781666715990007662024-02-05T08:31:00.004+08:002024-02-05T08:31:59.253+08:00在網頁使用 sqliteSQLite compiled to JavaScript 透過 WASM,可在網頁直接載入 sqlite db,使用 SQL 指令操作資料庫。WebAssembly或稱wasm是一個低階程式語言,讓開發者能運用自己熟悉的程式語言(最初以C/C++作為實作目標)編譯,再藉虛擬機器引擎在瀏覽器內執行。透過 WebAssembly 可以讓一些 C/C++ 開發的函示庫,移動到網頁裡面運作。sql.js 就是用這種方式,讓網頁可以直接使用 sqlite 資料庫。
使用sql.js要先初始化資料庫物件
引用 javascript
<script src='https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.9.0/sql-wasm.min.js'></script>
接下來有兩種方式初始化資料庫
方法 1: fetch
maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-90297824487287797492024-01-22T08:31:00.001+08:002024-01-22T08:31:39.179+08:00Leaflet 基本使用方法
大部分想到地圖 API 直覺都是 Google Map,但在商業用途上,Google Map API 有使用量要收費的問題。目前可以透過 Leaflet 使用 OpenStreepMap,這部分在商業用途是可以免費使用的。
建立地圖
使用 leaflet 要先 include css 及 js,一開始要先指定地圖的中心點,以下範例定位在台中市政府。過程是用 L.map 建立地圖物件,然後加入 OpenStreetMap 這個 tile layer
建立地圖的範例
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-34698494275553888662024-01-15T08:39:00.003+08:002024-01-15T08:39:57.843+08:00webcam 即時影像有一種特殊的 MIME 類型,稱為 multipart/x-mixed-replace,這是由 Netscape 在1995年引入的。當伺服器想向客戶端持續發送資料時,瀏覽器可以在一個 http 通道中,持續接收這些改變的資料。它可以用於串流傳輸圖像的 webcam。
通常 http protocol 會需要 content-length 這個 header,讓接收資料的一端,明確知道這個 http 封包的資料有多少,但 multipart/x-mixed-replace 刻意在 client 打開一個 http 連線後,不回傳 response 的 content length,反而是直接用 multipart 的格式,持續對 client 發送資料。browser 在收到這些 content 時,可用來持續更新畫面。
最常見的應用是 webcam,在高速公路、氣象局的網頁,有即時影像maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-62252731928320173082024-01-08T08:45:00.002+08:002024-01-08T08:45:16.650+08:00HSTS(HTTP Strict Transport Security)RFC 6797 規定了網際網路瀏覽安全機制 HSTS(HTTP Strict Transport Security) ,宣告瀏覽器與伺服器之間通訊方式必須強制採用 TLS/SSL。
只要從伺服器端送出一個 Strict-Transport-Security 標頭 (Header) 給瀏覽器,即可告知瀏覽器於未來的某段時間內一律使用 SSL 來和該網站連接。一旦發生憑證失效情況,使用者將無法再瀏覽該網站,如此一來便可大幅減少中間人攻擊的問題發生。
換句話說:HSTS Header 就是負責將 http 強制轉為 https。
設定方式是 Server 回傳的 html response,必須要有 Strict-Transport-Security header,內容為
Strict-Transport-Security: max-age=<expire-time>
maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-83980941495371948112023-12-25T08:51:00.003+08:002023-12-25T08:51:35.819+08:00Daemon Thread in javaJava 的 thread 有分為 User 與 Daemon Thread 兩種。
User Thread 的執行優先順序比較高,JVM會等所有的 User Thread 都結束工作後,才會完全地停止工作。
Daemon Thead 的 priority 比較低,通常是用來提供 service 給 user thread 使用。如果有資料 IO 的工作,不建議在 daemon thead 裡面實作。因為JVM 不需要等待 daemon thread,所以可以隨時中止 daemon thread,通常在 daemon thread 會用無窮迴圈實作,如果有 finally 部分的程式,在 daemon thread 並不會保證一定會被執行。
Daemon thead 可用在 garbage collection,釋放記憶體,釋放 cache 的工作。
Daemon thead 要在產生maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-53596156632570483912023-12-18T08:54:00.002+08:002023-12-18T08:54:09.370+08:00Fluent APIfluent API 是一種 OO API design 方式,可讓 API 的使用者,透過 chain method 的方式持續呼叫該物件的 method。在實作這種 API 介面時,method 必須要在最後回傳物件本身的 reference,以最常見的 set methods 來說,以往都是回傳 void,但要改為回傳 this。
在實作支援 Fluent API 這樣的類別時,要注意物件的 immutability 特性,如果該類別是修改物件內部資料的狀態,那麼就直接回傳 this 就好了,但也有可能是持續產生相同類別的新物件。
Difference Between Fluent Interface and Builder Pattern in Java | Baeldung 這個網頁提出了兩種不同的例子
以下是 User 的 Builder,可透過 set method 不斷地maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-46469277771427202012023-12-04T08:43:00.002+08:002023-12-04T08:43:26.557+08:00TSN (Time-Sensitive Networking)時效性網路(Time-sensitive Networking, TSN)是電機電子工程師協會(IEEE)定義的專用於使乙太網路更具確定性的一種網路拓展。TSN 是區域網路(LAN)解決方案,只有在TSN LAN內部才能保證其即時性。
為解決乙太網路低延遲與時間同步的問題,Industrial Ethernet 的 Protocol
EtherCAT
EtherNet/IP
PROFINET
Powerlink
Modbus-TCP
SERCOS Ⅲ
在應用上來說Industrial Ethernet是與Standard Ethernet不相容的。TSN 解決了這些問題
TSN相容於Standards Ethernet IEEE802.1規範,可以與非TSN乙太網路一起使用的區域網路,TSN支援更高頻寬的傳輸速度 (Gbit/s以上)
TSN工作在Layermaxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-59624145723924734452023-11-27T08:45:00.001+08:002023-11-27T08:45:00.990+08:00Doppler Radar都卜勒效應 波源和觀察者有相對運動時,觀察者接受到波的頻率與波源發出的頻率並不相同的現象。這一現象最初由奧地利物理學家都卜勒於1842年發現。
物體的相對運動會引起頻率的增大或減小。當物體和波源相背離時時,波長會增大,頻率會降低,稱為都卜勒紅移,當物體和波源相向運動時,波長減小,頻率增大,稱為都卜勒藍移,根據探測到的都卜勒頻移 f′ 可以計算出物體的速度。
在馬路上,最常遇到的是消防車與救護車的警報,我們通常會發現,當車子往我們的方向靠近跟遠離時,我們聽到的警報聲音是不一樣的,而且一直在改變。
都卜勒雷達 Doppler radar 是利用都卜勒效應測量物體在雷達波束方向上的路徑運動速度的一種雷達。常用於氣象觀測。
為了檢查心臟、血管的運動狀態,了解血液流動速度,可以通過發射超聲來實現。超聲振盪器產生一種高頻的等幅超聲信號,激勵發射換能器探頭,產生連續不斷的超音波,向人體心血管器官發射,maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-28940614664493161832023-11-20T08:29:00.004+08:002023-11-20T08:29:49.480+08:00抽象洩漏定律 (The Law of Leaky Abstractions)Joel Spolsky 於 2002 年提出 Leaky Abstractions 抽象洩漏定律
All non-trivial abstractions, to some degree, are leaky. 所有難以理解複雜的抽象機制,在某種程度上,都是有漏洞的。
因為軟體的開發與運作環境複雜,開發人員不可能自造所有的輪子,而必須依靠各種抽象化的機制(大部分是 API 函式庫)進行開發,在隱藏細節的環境下,進行開發。經過一個開發人員的實作與開發後,某個程度下,又多了一層抽象封裝。但這些抽象封裝機制,不可避免都會洩漏出底層的一些問題,洩漏出無法封裝的問題。
在使用者使用抽象化後的介面後,在遇到不可預期的問題時,就必須要去了解底層的細節,才能知道發生的原因,也才能解決問題與除錯。雖然抽象封裝節省了開發的時間,但踩雷與除錯所耗費的時間也不少。因此我們才會在很多 QA 網站中,找到一些其他maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-55278455996772743262023-11-13T08:30:00.000+08:002023-11-13T08:30:01.226+08:00複雜性守恆定律 Tesler's LawLarry Tesler 於 1984 年提出複雜性守恆定律 Tesler's Law。每個程式都有其內在無法簡化的複雜程度,無法被刪除或是隱藏,到了臨界點,就無法再被簡化,因此,必須在人機介面的設計中,不斷地調整與平衡,適當地將使用介面跟產品內部的複雜度調整與轉移。
例如傳統的電視機,畫面裡面的顯示設定很簡單,複雜的是在電視遙控器,遙控器上有數十個按鈕可以進行設定。新的智慧電視,遙控器的介面非常簡潔,但畫面內的功能與設定卻非常多。使用者跟電視之間的交互作用關係的整體複雜度不變,但透過介面設計的不同,轉移了複雜度的比重關係。
Macbook Pro 在外接的介面孔,逐漸地簡化,導致使用者無法直接使用 HDMI、SD card、USB,機器因為孔位減少,外觀簡潔更好看。但使用者卻必須要透過外接的轉接線路,才能連接 USB、SD card。
Tesler's Law 說明了,系統「整體複雜度maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-89149990954224812332023-11-06T08:13:00.004+08:002023-11-06T08:13:35.983+08:00分布式計算的謬論 (The Fallacies of Distributed Computing)Sun MicroSystem 的幾位工程師,提出了分散式系統的八個謬論,是一般開發人員,對於分散式系統的錯誤認知假設,有了這些基本的認知錯誤,設計的系統常會發生一些不能預期的問題。
前四個是 Bill Joy 與 Dave Lyon 定義的,後來 Peter Deutsch 增加了 5,6,7 三個,最後 James Gosling 定義了第八個。
網路是可靠的
任何透過網路的遠端系統呼叫,都有可能會發生意外而失敗。為了處理遠端系統可能的離線異常,通常會帶入 MQ 系統,將遠端呼叫的需求放入 MQ,然後自動 retry,但加入了 MQ,就會用非同步的方式,處理一開始的 Request,這會直接影響原始的系統設計。
延遲是零
網路因為頻寬的限制,以及客戶端到伺服器端的距離,一定會發生資料傳遞的延遲。
傳統的電話線路是獨佔式的,一條線路只能讓一通電話使用。網路電話是不同的,需要經過語音maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-15241265311363796162023-10-30T08:34:00.006+08:002023-10-30T08:36:23.738+08:00Vue 的 js 建構版本資訊vue - Libraries - cdnjs vue 有多個版本的 js file,每一個版本有不同的用途
cjs
vue.cjs.js
vue.cjs.prod.js 有壓縮的正式版
CommonJS,是一種模組的定義,伺服器端使用,透過 require() 在 NodeJS 裡面使用。但目前 NodeJS 已宣布放棄了 CommonJS
global
vue.global.js 完整版,包含編譯器及 runtime
vue.global.prod.js 正式版
vue.runtime.global.js
vue.runtime.global.prod.js
這是在瀏覽器直接用 <script src""> 引用時使用,會得到一個 global Vue 物件,可直接使用。
完整版跟 runtime 版本的maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-5937412329966081992023-10-23T08:37:00.000+08:002023-10-23T08:37:25.421+08:00Chicken-or-Egg Problem in Network在網路效應中,常見到 2-sided martketplace,nfx 提出 19 個策略,用來解決先有雞還是先有蛋的問題。
Get the hardest side first
比較困難的那一邊,也代表其網路價值比較高
ex: Ourdoorsy 是 RV 租借市場,困難點在於如何吸引 RV owners
Appeal tightly to a niche and repeat
找到市場的痛點
ex: eBay 一開始 Beanie Babies。Craigslist 一開始是Craig的朋友想要找公寓,找工作
Subsidize the most valuable side of the market
付費補貼給該網路中最有價值的一方,請他們加入網路
ex: Uber 付費給司機
Make the supply look bigger with automation
從 maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-905320757626065232023-10-16T08:37:00.003+08:002023-10-16T08:37:45.903+08:00網路效應nfx.com 有一份 The Network Effects Bible 討論網路效應的重要性,每增加一個使用者,會讓這個產品/服務更有價值,也就是大者恆大的局面,在網路時代,所有系統發展的初期,都還是在獲取使用者的眼球的競爭下,只有大量的使用者,才算是拿到了入場門票,才會有下一個維持跟進化的問題。
分類
文中提到 16 種不同的網路效應(該文章有持續在更新),根據網路化的程度由小到大排列
Physical (e.g. landline telephones)
Protocol (e.g. Ethernet)
Personal Utility (e.g. iMessage, WhatsApp)
Personal (e.g. Facebook)
Market Network (e.g. HoneyBook, AngelList)
maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-69542936845715741982023-10-02T08:32:00.005+08:002023-10-02T08:32:50.387+08:00erlang poolboypoolboy: A hunky Erlang worker pool factory 是一個通用用途的 erlang pool library,主要是用在 pool 管理,對於 server 程式來說,最常見的就是連接資料庫的 connection pool。
連接資料庫最簡單的做法,是在程式中要呼叫使用資料庫時,要經過連線與認證,使用完畢後,就馬上關閉該資料庫連線,但對於 server 來說,因為大量的連線建立關閉,消耗了很多運算資源,故通常會以資料庫 connection pool 的方式來處理。
一般的 connection pool,會有初始的連線 pool 數量,就是一開始啟動時,固定會產生並維持幾個連線數量,然後在所有連線都被佔用時,有一個 overflow 的數量,設定超量使用時,一次多產生幾個連線。另外為了確保該網路連線是正常連線的狀態,DB pool 通常會定時發送maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-80416413648233893872023-09-25T08:47:00.001+08:002023-09-25T08:47:25.948+08:00firewalld在 rockylinux 8 以前,可以不使用firewalld,還是沿用舊的 iptables
# Stop firewalld
systemctl stop firewalld
# disable firewalld
systemctl disable firewalld
# hide firewalld
systemctl mask firewalld
安裝 iptables
dnf -y install iptables iptables-services
systemctl enable iptables
systemctl start iptables
systemctl status --no-pager iptables
在 rockylinux 9 以後,firewalld 成為預設的 firewall
firewalld 支援 network/firewall maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-81414531415716485672023-09-18T08:38:00.005+08:002023-09-18T08:38:50.237+08:00OAuth傳統的 Client-Server 架構裡, Client 要拿取受保護的資源 (Protected Resoruce) 的時候,要向 Server 出示使用者 (Resource Owner) 的帳號密碼才行。如果要讓第三方應用程式也可以使用這些 Resources ,則需要 Resource Owner 把帳號密碼給這個第三方應用程式,這時候會產生以下的問題:
第三方應用程式必須以明碼儲存 Resource Owner 的帳號密碼
Server 要支援密碼認證
第三方應用程式會得到完整存取 Protected Resources 的權限,無法限制時效
Resource Owner 無法只撤回某一個第三方應用程式的存取權,必須要修改密碼才能撤回。
當某一個第三方應用程式被破解,就會導致使用該密碼的所有資料被破解。
OAuth 解決這些問題的方式,是引入一個認證層 (maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-15390762072459734462023-09-11T08:36:00.005+08:002023-09-11T08:36:45.015+08:00mDNS DNS-SDDNS-SD(DNS Service Discovery) 跟 mDNS (multicast DNS) 是不同的 protocol,但可以互相相容。DNS-SD 能透過標準的 DNS 技術,尋找區域網路中,提供某些服務的協定。而 mDNS 是能夠在區域網路中,在不需要 DNS Server 的情況下,就能透過機器名稱,直接查出 IP。
apple 的 Bonjour protocol 就是合併了 mDNS 與 DNS-SD 實作的。
mDNS
可用在沒有 DNS server 的區域網路中,用來作機器 domain name 的 IP 查詢。設備會透過對 224.0.0.251 這個 multicast address,Port 為 5353,進行廣播,mDNS 使用跟 DNS 一樣的封包格式。mDNS 只接受 .local 的網域名稱,可同時運作在一個設備中,跟原本的 DNS 並存。maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-75966704601553478992023-08-21T08:29:00.005+08:002023-08-21T08:29:51.702+08:00柯林漢定律 (Kernighan's Law)
Brian Kernighan 在其著作 "The Elements of Programming Style" 提出一個經驗法則,稱為 Kernighan's Law。
Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible,
you are, by definition,
not smart enough to debug it.
除錯要比寫程式困難兩倍,
因此,如果程式寫得很精巧,
那你就沒有足夠的智慧能夠除錯。
對這句話的理解,我認為是跟程式的簡潔度及可讀性有關。
越複雜冗長的程式碼,因為程式碼太長,在 debug 時,就越不容易找到問題點。但有些人會在寫程式時,追求到極致,希望能用maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0tag:blogger.com,1999:blog-1966289135502764338.post-6198024577872780712023-08-14T08:31:00.003+08:002023-08-14T08:31:26.015+08:00過早優化效應 (Premature Optimization Effect)Donald Knuth 在 The Art of Computer Programming 提出了過早優化法則
We should forget about small efficiencies,
say about 97% of the time:
premature optimization is the root fo all evel.
Yet we should not pass up our opportunities
in that critical 3%.
有 97% 的優化是不值得花時間去做的,過早優化是萬惡根源。
但還是要注意在關鍵的 3% 要提早去優化。
把開發時間花在不重要的優化上,可能會因為過度優化,而化簡為繁,讓系統太過複雜。過早的優化,會浪費大量資源,包含時間、金錢、人力,同時也可能因為這些優化,而衍生出其他的問題。
對於這個法則的爭論點在於,系統的maxkithttp://www.blogger.com/profile/12745931998714117709noreply@blogger.com0