從Go語言角度淺談內存分配
前言
相信各位小伙伴一定看過這樣的言論,某某B乎大佬xxx,發了一堆文字,一定要學好底層,一定要學好C語言!!,然后下面各種抬杠。
B乎大佬:C語言是最牛掰的,一定要從C語言開始學起。
杠精張三:學C有啥用,啥都干不成,直接學Java,然后上框架,直接開始開發。
杠精李四:@杠精張三,你會懂C嗎,瞎胡扯,xxx一堆理由,反正,C是一定要學的,基礎一定要打好。
...各路杠精大V正在趕來...
杠精王五:PHP萬歲,PHP NB,PHP天下第一。
嗯...,可能各位小伙伴或多或少,都看到過這些言論,作為吃瓜群眾,我們樂呵樂呵就好了,咱們回歸正題叭!!
是否需要學習C語言,我的回答是,不是必要的,但是需要懂為什么要學習C語言。
為什么要學習C語言
嗯,,,今年是2020年,要是從目前的各種開發項目中開說,C語言的確是用的很少,除了嵌入式等一些一定領域,基本很少能見到C的蹤影了,但是為什么還是一直能聽到xx說要學好C語言呢?
按照我的理解,其實學習C語言,學的并不是這個語言,而是這個語言背后所代表的一些東西,代表的一些設計,代表的一些本質。
C語言學的好,究竟會帶來什么優勢
相信不少萌新在群里可能聽到某個大佬說,我一星期學完了xx語言,然后直接上手干活,然后你默默的說了一句,裝13,也可能,你們就在群里直接杠起來了。
那么,真的可以說,一周,或者兩周時間,學會一門語言嗎?。
我可以負責任的,告訴你,絕對沒問題,但是需要建立在強大的基礎上。
而指針,是一個特別重要的基礎,現在不管哪個語言,其實本質都是指針的應用,只不過是封裝的簡單了而已。
但是這造成的就是根基如果不穩,就會造成一些莫名奇妙并且不懂的問題,尤其是對萌新來說。
所以,不管現在不管在任何階段,沒有學習C語言的一定要學學C,撿起曾經丟下的重要的基礎。
那么,就先聽我簡單的入門一下吧。
所需要的技術棧
本次使用的技術棧是Go語言,理論來說是用C語言的,但是因為在指針這一塊入門時,Go和C的本質基本一樣,所以就采用更加人性化的Go語言。
后期會在加上Python,和Go對比一下,區別在哪,看看燒了一把火的Python是如何分配內存的。
當前,在看此文章時,我還是建議小伙伴有一定基礎的,至少能看懂怎么定義變量啥的都行。
操作系統各硬件的關系
首先,我們需要了解一下計算機主要組成部分。
首先,簡單的說,至少由 CPU 內存條 硬盤 顯卡 顯示器 操作系統(Linux,Windowns)等。
那么這些硬件是如何互相配合的呢。
嗯...大概是這樣子的,有點丑。
簡而言之就是:
- 系統上的每個應用(qq,微信,等)想要讓電腦播放音樂了,顯示器顯示個東西了,像硬盤寫入個文件了,都需要經過操作系統的同意。
- 操作系統調用CPU完成指令的執行,CPU將打開的應用讀取到內存條中,所以,為什么原來在機械硬盤會那么卡,機械太慢了,現在的固態嗖嗖嗖的就完成了硬盤數據到內存條數據的轉移。
- CPU分析讀取到內存條中的應用數據,如果是CPU處理的數據,自己拿走計算,如果是顯卡處理的數據,調用給顯卡計算,如果是聲音數據,給聲卡計算,等。
- 通過以上協調,整個應用基本就能跑起來了,如果需要將數據寫入硬盤,CPU在將內存條中的寫入硬盤就行了。
好嘞,通過上述,我們基本可以了解到操作系統和各硬件的協調關系。
悄悄的說個秘密咯,我們寫的代碼,基本都是運行在內存條中的呢,同理,上述所說的應用,基本也是將應用的代碼跑在內存條中的。
內存條
沒錯,就是這玩意,內存條。
同理,我還還可以這樣理解內存條內部的結構。
我們可以將內存條理解成一個個房子,就像這樣。
依然還是很丑...
但是我們的內存條是有的坐標的,也叫地址,每個小格子里放著一個個的值。
但是通常情況下,我們都是平面圖理解的,就像這樣。
地址(坐標)一般以十六進制表示,值該是啥就是傻。
代碼簡述
我們來看一段非常短Go的代碼。
聲明一個age變量并且賦值為18,并且輸出。
- package main
- import "fmt"
- func main() {
- var age int = 18
- fmt.Println("我今年:",age,"歲")
- }
在內存中如何表示。
我們的變量名age指向了0x1001地址,并且輸出了0x0001存儲的值。
就像這樣。
注:一定要理解這句話,變量名指向的就是內存條上的地址。
上述age指向就是地址0x1001。
但是我們在fmt.Println("我今年:",age,"歲")打印時,我們打印的是地址里面的值。
同理,我們在賦值,交換變量時,還是是地址里面的值。
例如:
上述代碼內存分配圖。
age2會重新申請一個地址存儲age的值18。
可能有時候可能會有人問,星期八,有沒有這種情況,他倆同時指向一個內存,這種不是更省內存嘛。
結果:當然會,這種情況,我們后面會講到的,現在能看懂就行,一步一步來。
結論
變量名指向的是內存地址。
我們在賦值時,或者打印等操作變量時,操作的是地址上面的值。
本文轉載自微信公眾號「 Go語言進階學習」,可以通過以下二維碼關注。轉載本文請聯系 Go語言進階學習公眾號。