主頁 > 軟體設計 > 中秋節爆肝萬字,帶你熟悉Linux行程的基本操作!!!

中秋節爆肝萬字,帶你熟悉Linux行程的基本操作!!!

2021-09-22 10:39:50 軟體設計

今天是中秋節,祝各位小伙伴中秋節快樂,記得吃月餅吖

圖片來自網路,侵聯刪

圖片來自網路,侵聯刪

Linux行程基本操作

1.行程基本概念

在Linux中行程資訊被保存在task_struct(PCB)

2.查看行程的方法
ps 

ps aux | greap myproc

ls /proc
3.創建行程

fork():創建一個子行程

#include<iostream>
#include<unistd.h>
using namespace std;
int main()
{
    fork();
    while(1)
    {
        printf("hehe\n");
    }
    return 0;
}

fork之前的代碼,被父行程執行,fork之后的代碼,父子都可以執行

fork之后,父子行程代碼共享

fork之后,父子進行那個先運行不確定,取決于作業系統調度演算法

fork函式會有兩次回傳值,給父行程回傳子行程pid,給子行程回傳0

image-20210911194317560

  6   pid_t id=fork();
  7   if(id==0)
  8   {
  9     while(1)
 10     {
 11       printf("我是子行程\n");
 12       sleep(1);
 13     }
 14   }
 15   else if(id>0)
 16   {
 17     while(1)
 18     {
 19       printf("父行程\n");
 20       sleep(2);
 21     }
 22   }
 23   else
 24   {
 25     printf("行程創建失敗\n");                                                   
 26   }
 27   return 0

image-20210911195055735

結果:父子行程同時執行

4.行程的狀態

行程狀態------>資料化-------->行程資料被保存到tack_struct中

行程主要有以下幾種狀態:

R狀態:

可以同時存在多個R狀態的行程

R狀態的行程不一定是正在運行的,表示隨時可以呼叫該行程

系統中所有處于R狀態的行程都會被連接起來形成調度佇列(run_queue)

S狀態:休眠狀態(淺度睡眠)通常用來等待某種事件發生,隨時可以被喚醒,也可以被殺掉

//休眠狀態
#include<stdio.h>
#include<unistd.h>
int main()
{
  printf("I am Running\n");
  sleep(10000000);
  printf("Ending\n");
  return 0;
}

D狀態:深度睡眠狀態,D狀態沒有辦法模擬,表示該行程不會被殺掉,即便是作業系統,除非重啟殺掉,或者主動醒來

image-20210911202604639

T狀態:將行程進行暫停

如上圖所示,摁下19sigstop即可暫停行程

X狀態:死亡行程

Z狀態:僵尸狀態

行程退出,在作業系統層面,曾經申請的資源,并不是被立即釋放,而是要暫存一段事件,供OS(父行程)進行讀取,,而父行程沒有讀取,叫做僵尸狀態

為什么要有僵尸行程:

行程創建的目的:完成某種作業

當任務完成的時候,呼叫方應該指導任務完成得怎么樣

(除非不關心)

sjw@iZ2zedu4njy79sqivntvprZ test_9_11]$ cat test.c
#include<stdio.h>
#include<unistd.h>
int main()
{
  printf("I am Running\n");
  sleep(10000000);
  printf("Ending\n");
  return 20;
}
[sjw@iZ2zedu4njy79sqivntvprZ test_9_11]$ echo $?//查看行程碼,查看最近一次行程退出時得行程碼(如回傳值return  0等)
//行程退出時,行程資訊(退出碼)是會被暫時保存起來的,相關資訊被保存到task_struct,此時,該task_struct相關資料不應該被釋放掉   Z
當有行程來讀取資訊時,task_struct被釋放
如何讀取資訊:行程wait

行程退出的資訊(退出碼)會被暫時保存起來

保存在task_struct中,如果沒有人讀取,此時,task_struct相關資料不應該被釋放

模擬僵尸狀態:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
  pid_t id=fork();
  if(id==0)
  {
    int count=5;
    while(count)
    {
      printf("I am child, pid:%d, ppid:%d, count:%d\n",getpid(),getppid(),count--);
    sleep(1);
    }
    printf("child exit......\n");
    exit(-1);
  }
  else if(id>0)
  {
    while(1)
    {
      printf("I am father,pid:%d, ppid:%d\n",getpid(),getppid());
      sleep(1);
    }
  }
  else
  {
    printf("fork fail\n");
  }
  return 0;
}

[sjw@iZ2zedu4njy79sqivntvprZ test_9_11]$ make clean
rm -rf *.o myproc
[sjw@iZ2zedu4njy79sqivntvprZ test_9_11]$ make
gcc -c test.c -o test.o
gcc -o myproc test.o
[sjw@iZ2zedu4njy79sqivntvprZ test_9_11]$ ./myproc
I am father,pid:9259, ppid:308
I am child, pid:9260, ppid:9259, count:5
I am father,pid:9259, ppid:308
I am child, pid:9260, ppid:9259, count:4
I am father,pid:9259, ppid:308
I am child, pid:9260, ppid:9259, count:3
I am father,pid:9259, ppid:308
I am child, pid:9260, ppid:9259, count:2
I am father,pid:9259, ppid:308
I am child, pid:9260, ppid:9259, count:1
I am father,pid:9259, ppid:308
child exit......
I am father,pid:9259, ppid:308
I am father,pid:9259, ppid:308
I am father,pid:9259, ppid:308
I am father,pid:9259, ppid:308
I am father,pid:9259, ppid:308
^Z

然后在另外一個視窗輸入以下監控腳本:

image-20210911210810042

while :; do ps aux | head -1 && ps aux | grep myproc|grep -v grep;echo "#############################"; sleep 1; done

剛開始運行時,二者都是S狀態,到子行程運行完畢退出進行時,子行程編程僵尸行程

image-20210911211033832

僵尸行程的危害:

造成記憶體浪費

造成記憶體泄漏

孤兒行程

Linux中,行程關系,主要是父子關系,

孤兒行程:父行程退出,子行程還在運行

孤兒進行會立即被系統領養(作業系統:1號行程Init)

? 監控腳本:

while :; do ps axj | head -1 && ps axj | grep myproc|grep -v grep;echo "#############################"; sleep 1; done
#include<stdio.h>
#include<stdlib.h>
#include<unstd.h>
int main()
{
	pid_t id=fork();
	if(id==0)
	{
		while(1)
		{
			printf("I am child,pid:%d,ppid:%d\n",getpid(),getppid());
			sleep(1);
		}
	}
	else if(id>0)
	{
		int count=5;
		while(count)
		{
			printf("I am father,pid:%d,ppid:%d,count:%d\n",getpid(),getppid(),count--);
		}
		exit(-1);
	}
	return 0;
}

查看行程:

ps aux |grep Mytest

行程是能夠知道自己當前所處的作業目錄的

5.行程的優先級

cpu分配資源的先后順序,即是行程的優先級,優先級越高說明行程被執行的越早

在Linux下輸入:

ps -l

image-20210917191658420

出現如上圖所示的結果,有幾個內容需要我們關注一下:

UID:代表執行者的身份

PID:當前行程的代號

PPID:父行程的代號

PRI:代表行程的優先級,該數字越低,代表行程的優先級越高,被執行的越早(默認該值為80)

NI:代表行程的nice值

NI與PRI的關系:

PRI用來表示行程的優先級,該值越低,代表行程的優先級越高,被執行的越早,該值默認為80,而NI用來改變行程的優先級,NI的取值范圍為-2019,PRI(new)=PRI(old)+NI,也就是說我們通過修改NI的值來改變行程的優先級,那么被修改后的行程優先級PRI的取值范圍為6099,60代表優先級最高的,99代表優先級最低(ps:每次修改PRI后再次修改時PRI默認為80,在80的基礎上進行修改)

修改行程優先級的方法:

 top命令--->輸入r--->輸入想要修改的行程的pid--->輸入NI值--->q保存退出

image-20210917193108076

如上圖所示我們將上面的行程NI修改為20,而PRI變為60,即最高優先級

其它概念:

獨立性:多個行程獨自運行,獨自享受各種資源,多個行程之間互不干擾

并行:多個行程在多個CPU上分別,同時進行運行

并發:多個行程在一個CPU下采用行程切換的方式,在一段時間內,讓多個行程得以推進,稱為并發

6.環境變數

環境變數一般使之作業系統中用來指定運行環境得一些引數

如:撰寫c/c++代碼時,在連接的時候,從來不知道我們所連接的動態靜態庫在哪里,但是照樣鏈接得動,就是相關環境變數幫助環境變數進行查找

常見環境變數

PATH:指定當前搜索路徑

HOME:指定用戶的主作業目錄(即用戶登錄到LInux系統中時,默認的目錄)

SHELL:當前Shell,它的值通常為/bin/bash

查看環境變數的方法

echo $NAME//NAME:你的環境變數名稱

image-20210917194515582

我們執行mpproc時前面必須加./,而執行ls之類的卻不用加,就是因為ls進行了環境變數的配置,我們也可以進行配置,使之向ls一樣直接執行

sudo cp -f mpproc /usr/bin
//直接將我們的可執行程式mpproc復制到/usr/bin目錄下,但是這種方法不推薦,因為以后如果同名的或者該目錄下檔案過多可能會造成誤刪

image-20210917195215201image-20210917195255911

這樣我們就可以像ls一樣執行mpproc,除了這種方式之外還有一個更推薦的方法

首先我們先洗掉這次的配置:

sudo rm -rf /usr/bin/mpproc
//注意不要直接把bin目錄直接給刪了

image-20210917195748504

這樣我們就洗掉了上次的配置,比較推薦的是下面這種方法,這種寫法當我們退出服務器后路勁會自動消除:

export PATH=$PATH:/home/sjw/Linux_Learning/test_9_17
//直接將路徑設定到環境變數當中去
//export:設定環境變數

image-20210917200010882

查看PATH:

 echo $PATH

image-20210917200352593

查看HOME:

image-20210917200444600

 echo $HOME

查看SHELL:

echo $SHELL

image-20210917200543291

顯示當前所有的環境變數

env

image-20210917200715193

set:顯示本地系統中所有的環境變數

export :設定自己的環境變數

export myvalue=100

image-20210917201007513

如上所示我們設定自己的環境變數并進行查看

unset:取消自己設定的環境變數

unset myvalue
//取消剛剛設定的環境變數

image-20210917201213849

6.環境變數的組織方式

每個程式都會收到一張環境表,環境表是一個字符指標陣列,每個指標指向一個以‘\0’結尾的環境變數字符

這里我們以c/c++程式為例:

所有的c/c++程式從main函式開始執行,main函式是沒有引數的,但實際上main是有引數的

int main(int argc,char*argc[],char*envp[])
{
	
}
//argc用來統計命令列引數
//argc是一個字符指標陣列,里面每一個都是字符型的指標,指向命令列引數
//envp也是一個字符指標陣列,里面每一個都是字符型的指標,指向環境變數信
//息,而環境變數資訊也是通過這樣傳遞給一個函式的

什么是命令列引數,下面我來帶大家演示一下


#include<stdio.h>
#include<string.h>
int main(int argc, char*argv[],char*envp[])
{
    for(int i=0;i<argc;i++)
    {
        printf("%s\n",argv[i]);
    }

    if(strcmp(argv[1],"-a")==0)
    {
        printf("hello world\n");
    }
    else
    {
        printf("哈哈\n");
    }
}

 gcc test.c -o Mytest -std=c99
./myproc -a

image-20210917203321910

這次我們使main帶引數,然后進行編譯,鏈接,在最后執行時我們在命令列上輸入 ./Mytest -a

這時argv就發揮了作用,用來存盤這兩個命令列引數,argc用來記錄命令列引數的個數,利用這個命令列引數我們可以在剛開始時就進行判斷進行分支陳述句的執行

再比如:

#include<stdio.h>
#include<string.h>
int main(int argc, char*argv[],char*envp[])
{
    printf("argc:%d\n",argc);
    for(int i=0;i<argc;i++)
    {
        printf("argv[%d]:%s\n",i,argv[i]);

    }
    return 0;
}

image-20210917203946572

如上圖所示,即將命令列引數進行了保存

接下來我們來聊一聊envp,它也是一個字符指標陣列,指向系統的環境變數資訊,通過envp我們可以呼叫到系統的環境變數資訊

#include<stdio.h>
#include<string.h>
int main(int argc, char*argv[],char*envp[])
{
    int i=0;
    while(envp[i])
    {
        printf("envp[%d]:%s\n",i,envp[i]);
        i++;
    }
    return 0;
}
//envp以'\0'進行結尾

image-20210917204700982

仔細觀察就會發現這和上面利用env命令查看到的系統環境變數資訊是一致的

在Windows中也存在命令列引數,也可以通過envp來獲取系統環境變數資訊

//列印Windows下環境變數的資訊
#include<stdio.h>
//命令列引數的寫法
int main(int argc,char*argv[],char*envp[])
{
	int i = 0;
	while (envp[i])
	{
		printf("Windows:envp[%d]:%s\n", i, envp[i]);
		i++;
	}
	return 0;
}

image-20210917210148988

如上所示即為Windows下的環境變數資訊,同學名還可以在自己的電腦上試一試

環境變數是一個系統級別的全域變數,更本原因是bash之下所有的行程都可以獲取

通過系統函式呼叫查看環境變數

getenv(“NAME”)//NAME為環境變數名稱

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char*argv[],char*envp[])
{
    //顯示PATH環境變數名稱
    printf("%s",getenv("PATH"));
    return 0;
}

image-20210917205511760

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/type>
//定義全域變數
int g_val=100;
int main(int argc,char*argv[],char*envp[])
{
	pid_t id=fork();
	if(id==0)
	{
	//在子行程中改變這個全域變數,觀察父行程中的全域變數是否發生變化
	g_val=200;
		printf("child:pid:%d,ppid:%d,g_val:%d,&g_val:%p\n",getpid(),getppid(),g_val,&g_val);
	}
	else
	{
		sleep(2);
		printf("father:pid:%d,ppid:%d,g_val:%d,&g_val:%p\n",getpid(),getppid(),g_val,&g_val);
	}
	sleep(1);
}

image-20210917205511760

如上所示,我們在上面代碼中定義了一個全域變數g_val,而我們在子行程中改變了g_val的值為200,但是在父行程中g_val的值仍然為100,而且兩個行程中g_val的地址是一樣的

證明:該地址不是物理地址,而是虛擬地址

是語言層面上見到的地址而不是物理地址

我們在c/c++語言所見到的地址都是虛擬地址,物理地址一般看不到,由作業系統統一進行管理

OS(作業系統)負責將虛擬地址轉化為物理地址

每一個行程都有一個行程地址空間,都有一個映射串列

子行程的寫入,不會影響父行程,行程之間具有獨立性,不會互相影響

寫的時候單獨拷貝一塊空間,資料層面上發生了分離

今天是中秋節,祝各位小伙伴節日快樂,也感謝大家的收藏,評論,轉發,期待下次再見
To Be Continued…

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/302003.html

標籤:其他

上一篇:你想知道的字串函式全家桶都在這

下一篇:華為數通設備命令大全(建議收藏??)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more