來張圖:這個帖子寫給新人的,老玩家就直接無視他,因為這個完完全全是白話基礎原理。
解釋:上面的圖是從上往下依次調用的關系。
操作系統(Windows/Linux)管理硬件,讓硬件能夠正常、合理的運行,當然各種硬件的驅動實現了操作系統的接口,操作系統調用這些接口就能管理硬件,操作系統還像程序員提供了一層接口,叫做系統呼叫層,程序員可以面向這一層的接口編程,來實現對計算機的控制,而不同的操作系統(或者說不同的CPU架構)所提供的接口都是不一樣的,Windows和Linux提供給的那肯定是完全不一樣的,雖然站在最終的角度來看都能實現某一功能。所以同樣一個程序是不能在不同的系統上運行的,甚至可能在同一個系統的不同版本都不一定能完美運行,這就是所謂的平台相關的程序,比如C/C++程序,然而計算機和互聯網的飛速發展,計算機種類和型號千千萬,操作系統也有很多種類,Window、Linux、iOS等,同樣一款軟件不能不做改變就在不同的操作系統上面運行,這對開發者來說不是很友好。Java語言就能解決這個問題(說成是Java平台更准確,JVM+JavaAPI),鑒於不同的操作系統所需要的程序是不一樣的,那么就可以尋找一個方法來解決這個問題,於是JVM就誕生了,又JVM來向下關聯所有操作系統,他能操作所有操作系統,向上提供統一接口,也就是JavaAPI,開發者只需要面向JVM(JavaAPI)編程,至於JVM是如何各種不同的操作系統打交道開發者完全不用管,管他是怎么溝通交流的,於是只要面向JVM+JavaAPI編程,一個程序可以在任意操作系統平台上面運行,這就是所謂的跨平台,Java代碼和平台是無關的,沒有任何關系。---而這,就是Java的跨平台性質。
特別指出:也並不是只能面向JavaAPI編程,其實也可以掉本地接口,只不過不推薦這樣做,這樣就跟平台相關了,除非萬不得已,否則就只使用JavaAPI,據我的經驗,還沒見過Java不能解決而需要調用本地接口的問題,可能是我才疏學淺。
其實這個理念跟Linux的shell是一樣的,Linux操作系統管理硬件,Linux向上提供統一接口,而Shell(就等於是上面的JVM)作為命令輸入這和操作系統接口的中間人,中間人會將輸入的命令解釋給操作系統接口來管理和調用各種硬件,只不過shell沒有JVM做得那么徹底,這也就是為什么對於那么多不同的shell來說,輸入的命令都基本上是一樣的的道理。我們形象的稱之為“殼”,說白了跟設計模式里面的門面模式一個道理,讓用戶能控制的都是安全穩定的,有風險的或者不希望用戶觸摸得到的就隱藏在門面后面。同事“殼”也能調用其他應用,像什么ls -l,vi,fdisk -l,df -h這種。
舉個例子:我們國家有很多方言,比如廣東人至聽得懂廣東話,四川人只聽得懂四川話,天津人只聽得懂天津話,這些方言就是所謂的地域相關的語言,對應計算機軟件來說就是平台相關性,如果我一個北京人要跟廣東、四川和天津人說話,我必須要會說這三種方言,這對於我的語言能力來說很痛苦,要學會這三種話。但是我們知道湖南衛視汪涵很牛逼,會說各種方言,我把他請來當翻譯,汪涵就是JVM,他能說這三種方言,並且他只聽懂得普通話,但是會說各種方言,這好像有點奇怪,所有想要跟廣東、四川和天津打交道的人都跟汪涵說普通話,讓他來幫忙翻譯,我們說一句他翻譯語句,這樣的最終目的我們只需要學會普通話就可以跟任何人交流了。這就是Java平台。正是因為多了中間翻譯人這么一個過程,所以很明顯我說普通話跟廣東人交流顯得很慢,需要等汪涵來翻譯,肯定是沒有我直接說廣東話來的直接。這也就是為什么Java比C/C++慢的原因,虛擬機需要解釋執行。雖然速度慢,但是換來的是我們只需要說普通話就能跟所有人交流,這樣的代價是值得的,而且虛擬機性能和各種Java技術的發展,這個解釋執行的過程越來越快,以后說不定就追上C/C++了,也就是汪涵的語速會變得和好聲音華少的語速,甚至再快,到了周傑倫唱歌速度那么快,我們和不同地區的人交流就更快了。當然現在的JVM不僅僅是逐行解釋執行,還有部分JIT技術和其他很多各方面的提升。
操作系統的核心是不能夠讓用戶隨便操作的,於是就有了各種應用來操作操作系統核心,比如java應用,各種桌面英勇,所有應用其實都應該叫做shell,只不過一般的應用都有一個很好聽的名字,而Linux就是各種shell,什么bshell、cshell,shell也是一個應用,只不過很特別,通過指令來控制操作系統核心而不是GUI來控制,就跟Windows環境下的DOS模式差不多。
題外話,關於我的理解,我們對於計算機的操作,事實上都是對內存模型(或者說內存的數據結構)在操作,CPU和內存的通信會觸發計算機相關的硬件控制,內存變化的時候他會給CPU發送信號,然后CPU執行相關的操作顯示到顯示器上面。內存首先是建立操作系統的內存模型,然后其他內存模型都建立在操作系統的內存模型之上或者跟操作系統內存模型有關。就包括JVM的內存模型,當我們操作數據的時候,JVM內存模型發生變化,從而控制操作系統,操作系統跟CPU之間完成非常復雜的溝通,然后得出結果,從IO送出信號。而這一切的一切在計算機內部都是所謂的二進制在運行,再向下一點,就是無數個高低電平的變化。而我們的代碼其實就是這些內存模型的另一種表示方法,這種表示方法可以讓人很容易看懂和改變。我們平常所謂的內存,硬盤這些數據和控制都是邏輯性的,這讓人才容易懂,而轉換到底層就是物理性的。舉個例子:我們平常的String str = "123",我們人看懂,字符串str賦值123,那么當我們在eclipse中輸入String str = "123"點點擊Ctrl + S保存,其實CPU和內存之間已經經過了無數次溝通,首先會把"123"轉換成二進制,從而保存在硬盤上面的,當我們的JVM開始運行之后,從硬盤把"123"加載內存,當我們調用str這個引用的時候,內存會把"123"在內存中的的數據結構通過高低電平傳給cpu,cpu做出運算,控制之后會通過IO,把信號送到屏幕,當然,還需要經過顯卡,然后屏幕通過送過來的信號拉扯液晶,從而屏幕上面顯示"123"字樣。總之一句話,計算機軟件其實就是無數次的改變內存模型,我們操作的其實都是內存。