主頁 > 軟體設計 > 函式的創建和銷毀(細)

函式的創建和銷毀(細)

2021-08-10 16:01:06 軟體設計

前言

我們都知道函式是在堆疊區開辟空間的,但你是否知道:

  • 函式堆疊幀是什么?
  • 函式是如何在堆疊區開辟空間的呢?
  • 函式的實參是如何傳參的?傳參的順序如何?
  • 為什么函式形參無法改變外部的變數?
  • 為什么說實參是形參的一份臨時拷貝? 形參和實參的關系又是什么?
  • 函式是怎么呼叫的?
  • 函式呼叫是如何回傳值的?
  • 區域變數是如何在堆疊開辟空間的?
  • 為什么說區域變數的值是隨機的?

這篇文章都已給你解答這些問題,接下來跟著我一起走下去,讓我們一起進入函式是如何在堆疊區中玩耍的旅途,我們慢慢來回倒這個問題

🦻🦻🦻注意:測驗環境是在vs2013編譯器下的,其他編譯器和本編譯器可能會有略微資料或者界面等差異,但是大體邏輯上是沒有變的


文章目錄

  • 前言
  • main函式也是被呼叫的
  • 函式堆疊幀
  • 函式的創建呼叫程序
  • 函式開始銷毀的程序
  • 回答開頭的問題
  • 一個還沒開始銷毀函式空間的記憶體布局圖

簡單的小常識:
👀:eax,ebx,ecx,edx,這些暫存器都是用來存放資料的;可以存放地址,可以存放值,

👀:esp 是存放堆疊頂指標,ebp是存放堆疊底指標,

👀:堆疊區的使用特點是:從高地址向低地址使用,并且當壓堆疊時候,暫存器essp–;彈堆疊時候,esp++;


main函式也是被呼叫的

我們寫的程式都是從main函式入口的,程式的開始也是從main函式入口進去,但是main函式其實也是被別的函式呼叫起來的,我們來看看具體代碼,是誰呼叫了main函式;

操作步驟:

  1. 在vs2013按下 F10,開始逐步除錯,進入主函式,然后,按下圖點擊進入呼叫堆疊的選項:
    在這里插入圖片描述
    然后觀察那個黃色的小箭頭,就是除錯的按鈕,一直按F10,直到黃色小箭頭到達右花括號 },這說明,main函式執行完畢,也就是說明,main函式被呼叫完畢,但是被誰呼叫的呢?
    在這里插入圖片描述
    我們再繼續按F10,此時后,我們就會跳轉到這個頁面:這個頁面就顯示著是main函式被呼叫了,在呼叫堆疊我們可以看到,這個main函式是被一個名為:__tmainCRTStartup() ;的函式呼叫,
    在這里插入圖片描述
    其實繼續下去,還可以繼續看到__tmainCRTStartup()函式也是被呼叫的,但是我么那就看下去了,這里我是想要說明什么問題呢?

在main函式被呼叫時候,我們是在堆疊空間開辟一段空間,并且用,esp指標和ebp指標,指向這段空間給main函式去使用

函式堆疊幀

👀:什么是函式堆疊幀呢?

在上面我們說到,main函式被呼叫時候,會在堆疊開辟一段空間,并且這段空間是由兩個指標,esp和ebp來維護的,被維護的這段空間,我們就叫做main函式的堆疊幀;就是可以給main函式去自由使用的空間,

如下圖:
在這里插入圖片描述
esp 和 ebp兩個指標,是哪個函式正在被呼叫,就用來維護哪一段空間

👀并且發現了嗎? 堆疊頂指標esp是在低地址,堆疊底指標ebp是在高地址,當我們壓堆疊時候,也是從高地址往低地址壓堆疊,


函式的創建呼叫程序

接下來我以一段簡單的加法函式來講解函式的創建程序:

# include<stdio.h>

int Add(int x, int y)
{
	int z = 0;
	z = x + y;
	return z;
}
int main()
{
	int a = 10;
	int b = 20;
	int c = 0;

	 c = Add(10, 20);
	return 0;
}

我們知道,當我們開始呼叫代碼時候,從main函式入口進去,一旦進入main函式,就為main函式開辟了一段空間,用堆疊頂和堆疊頂指標去維護這段main函式的空間,一旦當程式走到,int c = Add(10,20);時候,Add函式被呼叫起來,一旦進入到Add函式,就會在堆疊區就用堆疊頂著堆疊底指標去指向這一段空間,用來維護Add函式,
大概是這個程序:

維護的細節到底是怎么樣的?讓我們來看看吧,
首先先按F10開始除錯,然后,在一個空白的界面右擊滑鼠,點擊
轉到反匯編

在這里插入圖片描述
然后就會彈出一個反匯編的界面,這個界面是程式對應的匯編代碼:
如下圖:
在這里插入圖片描述
不要被匯編代碼嚇走了,你看到這里,我可以保證你看的懂,就很簡單的匯編指令,不過你現在包滑鼠放到反匯編界面,右擊滑鼠,把那個顯示符號名的選項去掉,這是為了看到偏移地址的位置,不看變數名,
在這里插入圖片描述
去掉之后,帶你簡單熟悉以下匯編的界面:
大概布局就是這個模樣,至于指令是什么功能接下來一步一步的分析;
在這里插入圖片描述
接下來我把機器碼的選項勾走不要,因為和接下來講的內容關系不大;


在呼叫main函式之前,也就是我們即將進去main函式的時候,我們是不是說了,有一個函式會呼叫main函式呀,同時這個__tmainCRTStartup()函式,也會在記憶體開辟一段空間,用esp和ebp維護:
在記憶體的布局如下:
在這里插入圖片描述
接下來我們看main函式的匯編代碼:
push ebp,這是什么什么意思呢?就是把ebp的值壓入堆疊中,壓到哪兒呢?壓到堆疊頂,同時,esp指標會向上移動一位,
同時注意:不要以為壓堆疊了,就把ebp的指向給改變了,只是把一個ebp的值壓堆疊而已;
如下圖:
在這里插入圖片描述
我們監視看看還沒有執行push ebp時候 esp 和 ebp的值是多少,這個值,也就是維護__tmainCRTStartup()函式的堆疊指標,
在這里插入圖片描述
一旦我們按F10也就是執行了push ebp操作,你看esp的值發生了變化,并且,這個值是變小的,這說明壓堆疊進去了,且小了4個位元組
在這里插入圖片描述
如果你還是覺得不像壓堆疊了,那我們從記憶體角度看看,esp指標指向的位置,里面存放的值是否和ebp相等,如果相等這就說明了一個問題:我們執行push ebp操作確實是把 ebp壓堆疊進去了,
在這里插入圖片描述
好,理解了上面的push ebp,接下來就是 mov ebp,esp這是什么意思呢?就是mov 指令把 esp的值移動到,存放到ebp暫存器里面,那我們進一步思考 把esp值給ebp,而且espebp又是堆疊指標,這類操作不就是像 ebp = esp嗎,這說明什么問題?這就說明 ebp指標指向了esp指標的記憶體空間啊.
在這里插入圖片描述
所以我們從監視看,按下F10,即一旦執行 mov ebp,esp操作,就會看到ebp的值和esp值相等,這里的值是地址,
在這里插入圖片描述
好的,我們繼續,這時候接下來的指令是 sub esp,0E4h ,這又是怎么理解sub這個指令?就是用esp暫存器的值減去0E4h,之后賦值給esp ,等價這條陳述句:esp = esp - 0E4h; 這個0E4h就是表示十六進制的數字;
那這條指令的作用在記憶體發生了什么?esp是一個指標,當指標減去一個數時候,就會發生偏移到這個esp-0E4h地址,也就是說,在記憶體中,這個堆疊底指標esp指向了 esp-0E4h這個記憶體地址;由于地址是減小了,所以esp指向了更低的地址,在記憶體的大概圖如下:
在這里插入圖片描述

我們回頭看一看,是不是突然發現ebp和esp不再維護__tmainCRTStartup()函式的空間地址了?
使得就是不在維護了,那維護了誰?還記得是我們剛剛是從什么函式入口的嗎?對,就是main函式入口的,這就是esp和ebp維護的新空間,即main函式的堆疊幀;
這就是傳說中的當呼叫函式時候,就會在堆疊空間開辟一段記憶體空間


當我們按了F10,觀察監視esp的值,會變小,變小了多少呢?就是小了0E4h的值;
在這里插入圖片描述
我們從記憶體角度看看,esp指向的地方和ebp指向的地方之間就是main函式堆疊幀空間,那么在記憶體中到底有多少呢?只要我們找到esp和ebp對應的指標地址,就可以知道它們之間的地址了,
在這里插入圖片描述
你有沒有發現,哇哦,好長啊,居然可以為一個main函式開辟那么多空間,嗯,確實,我也覺得好長,
接下來就繼續指向壓堆疊了,看匯編指令push ebx push esi push edi,就是往堆疊頂壓堆疊,先不用管這是什么意思,,只需知道,在堆疊空間,ebx esi edi這個三個暫存器的值依次被壓入堆疊了,同時不要忘記堆疊頂指標esp也會跟著指到堆疊頂,
在這里插入圖片描述
繼續按F10,按3下,把剛剛三條指令指向完,觀察esp堆疊頂指標的值,變化了12個位元組:
在這里插入圖片描述
接下到了 lea edi,[ebp+FFFFF1Ch]這個操作,lea是加載有效地址的意思,把 ebp+FFFFFF1Ch的地址加載到edi暫存器里面,為什么說是加載地址呢?因為這里有個 中括號[ ],他的意思就是把中括號[ ]里面值當作地址;那ebp+FFFFFF1Ch到底是什么地址?我們打開反匯編的加載符號選項,可以看到,ebp+FFFFFF1Ch就是 ebp-0e4h的地址.
在這里插入圖片描述
那接下來來到了這幾條指令 mov ecx,39h mov eax,0CCCCCCCCh rep stos dword ptr es:[edi] ,這里有三條指令,我們不需要理解具體是干什么的,我們只需要理解這三條指令合起來就是做一件事情:
ebp-0E4h的地址到ebp的地址 ,這個范圍地址空間里面的每4個位元組的值賦值為0CCCCCCCCh,為什么是4個位元組,因為在rep stos dword ptr es:[edi]這條指令中,有個dword表示double word 就是4個位元組的意思,一個 word就是兩個位元組;
在記憶體布局的模樣就是大概這個樣子:
在這里插入圖片描述
下面開始指向,main函式里面代碼了,來到int a= 10;即來到匯編指令: mov dword ptr [ebp-8],0Ah,意識就是把 0Ah放到ebp-8的地址空間,看看我們的記憶體布局 ebp在堆疊底,那么很容易就知道ebp-8在哪里了:
注意記憶體布局圖:里賣弄 ebp-8的位置值修改成為了 0Ah
在這里插入圖片描述
繼續接下來的指令,一模一樣也是 指向int b = 20; mov dword ptr [ebp-14h],14h int c= 0; mov dword ptr [ebp-20h],0都是把 值放入對應的位置,在記憶體布局如下:
找到 ebp-14h ebp-20h這兩個記憶體地址就行:
到這里,你思考一下:你有沒有發現無形之中,你好像看到了區域變數在記憶體是如何存放在堆疊空間的了


好了執行完后,你會來到這個 c = Add(10,20); 這是什么?這是函式呼叫,我們知道函式呼叫要傳參,來看看是如何如何傳參的,你看我為啥先說傳參?因為匯編指令就是這么玩的,為什么我不說函式呼叫為函式開辟堆疊空間?因為匯編就是先傳參,
如何傳參?
首先,push 14h 和 push 0Ah,就是壓堆疊,同時esp指標往上移動,先傳了20,在傳10,你有沒有發現,傳參的順序是從括號()的右邊往左邊傳
在這里插入圖片描述

接下來到了 call 004E10E1 這個操作,這個操作是干什么的?call指令就是開始真正的呼叫 Add函式了,并且這個call指令還會把下條指令的地址進行壓堆疊;
在這里插入圖片描述

在記憶體中,我們只要觀察 esp指標指向的值是否為 call指令的下一條指令即可,
在這里插入圖片描述
呼叫函式時候,我們按F11;此時就是執行了call 004E10E1;此時就進入了Add函式,你仔細觀察一下,前面的匯編指令
004E13C0 push ebp
004E13C1 mov ebp,esp
004E13C3 sub esp,0CCh
004E13C9 push ebx
004E13CA push esi
004E13CB push edi

這操作是不是和main函式呼叫時候,很像?對就是很像,那你說這幾段匯編代碼做了什么?哎,就是給我們的Add函式開辟堆疊空間,開辟我們Add的堆疊幀
下面那幾條就是在Add函式的空間內,存放隨機值,
在這里插入圖片描述
在記憶體布長這個模樣
在這里插入圖片描述

此時,到了 int z = 0;這個代碼對應匯編就是 mov dword ptr [ebp-8],0,也就是在 ebp-8的位置存放 0 值,在記憶體布局中:

在這里插入圖片描述
接下來到 z = x +y;這段代碼對應匯編:
z = x + y;
004E13E5 mov eax,dword ptr [ebp+8]

004E13E8 add eax,dword ptr [ebp+0Ch]

004E13EB mov dword ptr [ebp-8],eax


先看: mov eax,dword ptr [ebp+8] :
把ebp+8的地址指向的值放入 eax暫存器中,你看, ebp+8在哪兒?
是不是存放的剛好時我們在main函式堆疊幀里面值 014h;也就是20
add eax,dword ptr [ebp+0Ch]
這個也是 add指令把 ebp+och地址里面的值,也在main函式的堆疊幀中,也就是10,加到eax里面,并賦值給eax,那么 eax就變成了 30;
mov dword ptr [ebp-8],eax
最后把eax里面的30 放入到 ebp-8的位置,那ebp-8的位置就是變數 z的位置啊;
到此這個z = x +y;就是執行完了;
在記憶體布局時這樣的
在這里插入圖片描述
到這里,你思考一下:是否:在 Add函式使用的變數 不是在 自己Add函式里面的,而是在main函式的堆疊幀里面的壓進去的值,也就是說在呼叫Add函式的時候,我們先把實參壓堆疊,此時,這個實參就是形參的一份拷貝了,你往記憶體布局下面看,你就發現,實參還是在函式的堆疊幀里面,根本沒有和形參發生真正的使用,這就是說實參為什么說就是形參的一份拷貝了


接下來就到return z;這個陳述句了, 那對應的匯編: mov eax,dword ptr [ebp-8]
把 ebp -8的值放入到eax中,這個時候,并沒有發生什么函式呼叫完了就回傳的操作,只是把值放入到eax暫存器中,但是函式呼叫完后,就回傳到主函式把return陳述句的值帶回去是有錯的嗎?并沒有,還有的是,函式回傳了,不是說,區域變數都銷毀了嘛,那怎么還可以把區域變數的值帶回去,匯編代碼告訴你,在函式回傳的時候,是先把return z中的區域變數先保存起來,到一個暫存器先,等函式執行結束后,才開始回傳


函式開始銷毀的程序

這時候當Add函式執行完后,就開始銷毀空間了,看看接下來的彈堆疊的匯編代碼
pop edi
pop esi
pop ebx
一旦執行了這三句匯編,就會從堆疊頂開始彈堆疊,此時esp++;如下圖;
在這里插入圖片描述
之后來到這句匯編:
mov esp,ebp
這個意思就是esp指向了ebp,此時就發生了一個重大的事情,一旦esp指向了ebp,這就說明,這段空間的堆疊幀沒了,也就是說Add函式被銷毀了,你發現了嗎?在函式被銷毀的時候,我們的return z 還是沒有回傳啊,不用擔心,因為z已經被保存到暫存器eax里面了,及時函式的空間沒有了,eax里面的值還是存在的;那什么時候回傳,別急,往下看;
在這里插入圖片描述
繼續看 pop ebp:這個匯編指令就很厲害了,當我們 pop ebp時候,
ebp就不指向剛剛的空間了,而是回到了main函式原來是ebp所指向的空間,我們要知道 ebp指向的那段空間里面存放的就是 main函式的地址,并且,esp也會++;
所以記憶體布局是這個樣子
在這里插入圖片描述
之后來到 ret 這條指令,這條指令的意思是 回傳到堆疊頂元素存放值地址指令那里,同時彈出堆疊頂元素:
此時esp++的位置
在這里插入圖片描述

那我們看現在堆疊頂就是 call指令得下一條指令,還記得是什么嘛?就是執行完函式得時候時候,即Add(int x,int y);j就會回到主調函式 c = Add(10,20);此時,我們并沒有執行完這條陳述句
所以你就可以思考:為什么剛剛我要把 call指令下一條指令壓堆疊呢?就是為了還能回到主調函式函式;
之后就來到了 add esp 8;這個意思就是esp+8 賦值給esp,所以 esp指向了下面8個位元組的位置,這也說明 形參 x, y 空間銷毀;
esp的指向如下圖
在這里插入圖片描述

接下來到 :mov dword ptr [ebp-20h],eax ,這個就強了,到這里才是把 eax的值 放到 ebp-20h的地方去,ebp_20h就是 變數c的值,此時,這算終于把Add函式回傳的 z給帶回來了,
在這里插入圖片描述
啊,這里終于解釋完了,add函式的創建和銷毀了,那么main函式的銷毀機制也是一樣的我就不過多解釋了,你們可以試一試,


回答開頭的問題

接下來我們終于看完了,來回答一下開頭的問題吧:測一測自己,

  • 函式堆疊幀是什么?

函式堆疊幀就是esp和ebp維護的空間,這段空間可以共供給函式使用,一旦esp和ebp發生變化,指向另一段新的空間時候,這個就發生了函式呼叫,此時 esp 和ebp又會重新維護那一段空間,總的來說:函式堆疊幀就是函式能夠利用的空間范圍,并且由esp和ebp指標維護;

  • 函式是如何在堆疊區開辟空間的呢?

函式在堆疊區開辟空間,一旦進入函式體,首先做的事情是給函式設定堆疊指標,用來維護堆疊空間,同時會給堆疊空間賦值 0CCCCCCCCh,即給維護的空間賦值為隨機值;并且我們知道堆疊的使用是從高地址向低地址使用的;

  • 函式的實參是如何傳參的?傳參的順序如何?

函式傳參是先碰到呼叫函式,先給形實參壓堆疊,壓堆疊的時候,還是在主調函式體里面,壓堆疊的順序是從實參串列的右邊到左邊依次入堆疊;
當進入到函式體內部時候,形參是使用主調函式體里面的實參資料;這就是實參傳參給形參,這也說明了,實參是形參的一份臨時拷貝,

  • 為什么函式形參無法改變外部的變數?

因為我們在呼叫函式的時候,是給實參壓堆疊一份資料進去堆疊頂的,形參使用的資料就是在呼叫函式中實參的資料,所以說,形參改變不了外面函式的變數

  • 為什么說實參是形參的一份臨時拷貝? 形參和實參的關系又是什么?

這個參考上面的兩個問題;

  • 函式是怎么呼叫的?

函式的呼叫,首先,會給實參壓堆疊,其次會保存呼叫函式體執行結束后的下一條指令的地址,然后給函式設定堆疊指標,用來維護函式的空間,同時,為函式的賦值為隨機值,這個時候,執行函式體的代碼,如果函式執行有回傳值,先把回傳值放到一個暫存器臨時保存,然后函式體執行結束,銷毀了函式的堆疊空間,回到主調函式的呼叫函式中,此時銷毀形參,同時把回傳值帶回來,

  • 函式呼叫是如何回傳值的?

參考上面的回答

  • 區域變數是如何在堆疊開辟空間的?

區域變數是以壓堆疊的形式創建的,并且,創建時從高地址向低地址使用空間,在創建區域變數的時候,函式堆疊空間的地址已經時隨機值了,此時當你創建區域變數時候,得到的也是隨值

  • 為什么說區域變數的值是隨機的?

參考上面的回答;


一個還沒開始銷毀函式空間的記憶體布局圖

在這里插入圖片描述

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

標籤:其他

上一篇:你看不見的函式堆疊幀的創建與銷毀(C語言)

下一篇:《畫解資料結構》「基數排序」演算法教程

標籤雲
其他(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