process, thread, coroutine

當我們談論到 process、thread 和 coroutine 時,可以用以下生活中的例子來解釋這些概念:


1. Process(進程):

假設你正在製作一道菜。這道菜需要多個步驟,例如切菜、炒菜和煮飯。你可以把整個製作菜的過程視為一個進程。在這個例子中,你是主進程,而切菜、炒菜和煮飯則是在這個主進程中執行的子進程。每個子進程都有自己的工作,並與其他子進程獨立運行。進程之間可以通過共享資源(如食材)來進行通信。


2. Thread(線程):

假設你正在閱讀一本書,同時你的朋友正在聽音樂。你們兩人可以被視為不同的線程。每個線程都在執行自己的任務,你閱讀書籍,你的朋友聽音樂。雖然你們兩人在同一個進程中,但各自的線程是相互獨立的,不會互相干擾。線程可以同時執行,並通過共享內存來實現信息交換。


3. Coroutine(協程):

當你在玩一個多人遊戲時,你可能與其他玩家在線上互動。這時候,你可以使用coroutine(協程)的概念來管理不同的遊戲任務。


假設你正在玩一個角色扮演遊戲,並且你的角色需要進行各種活動,例如戰鬥、採集資源、尋找任務等等。當你進入一個戰鬥場景時,你的角色需要處理戰鬥相關的邏輯,例如攻擊、防禦、計算傷害等等。同時,你可能也需要處理其他的活動,例如採集資源、與其他玩家聊天、接收遊戲通知等等。


在這種情況下,你可以使用coroutine來管理這些不同的遊戲任務。你可以將戰鬥相關的邏輯作為一個coroutine,當進入戰鬥時啟動它。同時,你也可以創建其他的coroutine來處理其他的活動。這樣,不同的coroutine可以在需要時進行切換,使得你的角色可以同時進行多個任務,例如在戰鬥期間也能夠採集資源或與其他玩家聊天。


透過使用coroutine,你可以更有效地管理遊戲中的不同任務,避免了阻塞和單一執行緒的限制。它提供了一種非阻塞的執行方式,使得你的角色可以在不同任務之間自由切換,並實現更好的遊戲體驗。



總結來說,process(進程)是一個獨立的執行環境,可以包含多個線程(threads)。每個線程(thread)是進程中的單獨執行單位,可以同時執行。而coroutine(協程)則是在同一線程中的一種特殊執行單位,可以暫停和恢復執行,並允許在不同任務之間進行切換。

Java Reference vs Object vs Instance vs Class 2

 



以上圖為例

House blueHouse = new House("blue")是創建 House 類別的新實例。記住 House 是一個藍圖,我們將它分配給 blueHouse 變數。 換句話說,它是對記憶體中物件的引用。 


下一行 House anotherHouse = blueHouse; 在記憶體中創建對同一物件的另一個引用。 這裡我們有兩個引用指向記憶體中的同一個物件。 仍然是一所房子,但對那個物件有兩個引用。舉例來說,我們有兩張紙,上面寫著房子建造地點的實際地址。


接下來我們有兩個打印 blueHouse 顏色和 anotherHouse 顏色的 println 語句。 兩者都將打印“blue”,因為我們有兩個對同一物件的引用。


下一行調用方法 setColor 並將顏色設置為黃色。 在左側,您可以看到 blueHouse 和 anotherHouse 現在都具有相同的顏色。 為什麼? 請記住,我們有兩個引用指向記憶體中的同一個物件。 一旦我們改變其中一個的顏色,兩個引用仍然指向同一個物件。 在我們的真實世界示例中,即使我們在兩張紙上寫了相同的地址,該地址仍然只有一所房屋。


從House greenHouse = new House("green"),我們正在創建另一個顏色設置為“綠色”的 House 類別的新實例。 現在我們在記憶體中有兩個物件,但我們有三個引用,分別是 blueHouse、anotherHouse 和 greenHouse。 變數(引用)greenHouse指向記憶體中的一個物件,而blueHouse和anotherHouse指向記憶體中的另一個物件。


這裡我們將anotherHouse指向greenHouse參考的物件。 換句話說,我們正在取消對另一個房子的引用。 它現在將指向記憶體中的另一個物件。 在它指向具有“黃色”顏色的房子之前,現在它指向具有“綠色”顏色的房子。 在這種情況下,我們在記憶體中仍然有三個引用和兩個對象,但是 blueHouse 指向一個物件,而 anotherHouse 和 greenHouse 指向記憶體中的同一個物件。


Java Reference vs Object vs Instance vs Class

 









如果以蓋房子來比喻

類別(Class)基本上是房子的藍圖。

使用藍圖,我們可以根據這些計劃建造任意數量的房屋。

我們建造的每個房子(換句話說,使用 new 關鍵字)都是一個物件(Object)。

這個物件也可以稱為實例或實體(Instance),通常我們會說它是類別的實例。 所以在這個例子中我們會有一個 house 的實例。

我們建造的每棟房子都有一個地址。

換句話說,如果我們想告訴別人我們住在哪裡,我們就給他們我們的地址。 這稱為參考(Reference)。

我們可以根據需要多次復制該引用,但我們仍然只引用一所房子。

換句話說,我們複製的是地址,而不是房子本身。

我們可以將引用作為參數傳遞給構造函數和方法。

Docker Image & Container

 Docker Image: single file with all the dependencies and config required to run a program.

Docker container: Instance of an image. Runs a program.













kernel是作業系統的核心元件,負責處理應用程式和硬體之間的溝通。











只要運行docker, 一個linux VM也在你的電腦上運行。

在linux vm內,會有一個linux kernel負責在容器中運行和托管進程。


什麼是Goroutine?


什麼是Goroutine?

 











以這張圖為例,最上面的Go program就是我們寫的程式。

在 Go 語言中,每個 Go program都運行在一個稱為 Go runtime 的運行系統之上。

Go runtime是什麼?

In Go, the runtime is an essential part of the language that manages memory allocation, garbage collection, and scheduling of goroutines. The Go program interacts with the runtime through the Go standard library, which provides an abstraction layer over the runtime. The Go program is compiled into machine code and executed by the operating system. When the program starts, it initializes the Go runtime, which sets up the memory management system, creates the main goroutine, and starts the scheduler.

The Go program can create additional goroutines to run concurrently with the main goroutine. The runtime manages the scheduling of these goroutines, ensuring that they execute efficiently and safely. The runtime also handles the communication and synchronization between goroutines through channels and other synchronization primitives. Therefore, the Go program and the Go runtime are tightly integrated, with the runtime providing the underlying infrastructure that enables the program to execute efficiently and concurrently.

然後最底層是Operating system, 程式碼會被編譯成machine code在OS執行。

在Scheduler和OS之間就有一個稱為Thread的構造。無論使用哪種OS,Thread都是OS用來管理其併發性的工具。當OS跟蹤同時發生的多個事情時,它們使用Thread來區分這些工作。












Scheduler的工作是將這些 goroutine(也稱為虛擬線程,這些線程純粹由我們的 Go program維護)映射到OS的thread上。然而,goroutine 有限制,因為它不直接與OS互動,所以它本身無法做任何事情。這就是Scheduler發揮作用的地方。Scheduler會將 goroutine 映射到OS的thread上。


 








goroutine跟thread差異

通常thread有固定的stack space, 約1mb

而goroutine的stack space是變動的, 起始大小為2kb

thread被os管理,goroutine被 Go runtime管理

thread比較消耗資源, goroutine相較起來較少



ps. go runtime簡介













Js object array 多條件篩選且條件可能為空

 最近在工作上遇到需要多條件篩選,且條件為空就不進行判斷,花了一點時間才研究出怎麼做

以下是解法

const originItems =
[{id:1, live:true, name:"test1",color:"red",size:"large"},
{id:2, live:true,name:"test2",color:"blue",size:"large"},
{id:3, live:true,name:"test3",color:"green",size:"medium"},
{id:4, live:false, name:"test4",color:"red",size: "small"},
{id:5, live:false, name:"test5",color:"blue",size: "small"},
{id:6, live:false, name:"test6",color:"green",size:"medium"}];

const sort = {live: true, color: "", size:"large"}

const result = originItems.filter( (o) =>
(!sort.live || o.live === sort.live) && (!sort.color || o.color === sort.color)
&& (!sort.size || o.size === sort.size)
)

console.log(result)

結果如下:

  1. length: 2

useEffect的三種dependency差異


第一種方式因為傳入的dependency是empty array

所以只會執行一次 

useEffect(() =>{

console.log("Hi)

},[])



第二種方式當每一次dependency變動時就會執行一次useEffect
useEffect(() =>{

console.log("Hi)

},[dependency])


第三種方式會變成無限迴圈...慎用
useEffect(() =>{

console.log("Hi)

},)