您現在的位置是:首頁 > 網路遊戲首頁網路遊戲
你知道自己到底想學什麼嗎?PHP、Java、Python、
- 2022-02-02
什麼指令是加速
相信每一個計算機科班出身的同學或許都有這樣的經歷:在大三的某一天,彷彿打通了全身筋脈一般把三年的所學:“數電裡的與非門——計算機體系結構——組合語言——語言——Java語言”。所有知識全部串聯了起來。所有這些語言的出現都彷彿都有了必然性和追根溯源的歷史感。
**閱讀指引**
讀懂此文,需要以下基礎:
1。 至少寫過50000行的程式碼;
2。 彙編基礎(靜態資料段,程式碼段,堆疊段)。
有以下或者類似知識就更好了:
1。 MFC反射的實現
2。 JAVA的直譯器執行原理
3。 使用過javascript,Python,PHP:感受過程式碼和型別系統在執行時的自由程度的不同
4。 計算機組成原理
**序 —— 一些問題**
1。 程式設計語言的目的是什麼?
2。 為什麼大多數語言有控制流?逐行執行+跳轉。這與我們的需求差很遠(例如一個教務管理系統、一個自動打車APP)
3。 為什麼型別申明在C語言中要與控制流隔離開來?
4。 現在主流語言最基本的元素是?
5。 有沒有語言它的型別結構,在執行時也可以改變?
動態性?
什麼是動態性?
1。 編譯後確定了什麼資訊,之後不再改變;
2。 執行時可以改變、新增什麼;
3。 執行時是否儲存著型別資訊。
程式中的資訊分為幾類?
1。 資料資訊
a) 編譯時Meta-Data元資料(型別框架、空間佔用)
b) 執行時Meta-Data元資料(繼承體系、用於new或者反射)(特別區別編譯與執行的Meta-Data的不同。)
c) 堆疊段中地址偏移(C++的switch case中不能宣告變數、共享記憶體)
d) 靜態段中地址
2。 指令資訊
a) 程式碼段(動態性需要作業系統或者虛擬機器支援,例如動態連結庫,動態類載入,lisp語言自生成程式碼)
**語言舉例**
**組合語言**
組合語言沒有動態性嗎?
沒有。首先,暫存器、資料段、堆疊、程式碼段完全由程式設計師控制。完完全全是寫死了的。然後,根據馮諾伊曼機的規則;取指令,執行,取指令,執行……
既然都有資料段了,還要堆疊段來做什麼?這不是多餘?
一開始本沒有堆疊,直到60年代出現了module模組化,才有了堆疊。彙編中的模組叫子程式,不過仍舊靠程式設計師全權控制。
堆疊和模組化的優點有?
1。 遞迴
2。 功能分離到模組,可複用
3。 封裝作用域
堆疊和模組化的缺點有?
1。 時間上:儲存現場、還原現場的代價(另,高階語言編譯“消除尾遞迴”節約部分成本)
2。 空間上:爆棧的危險
*
程式設計正規化是什麼?
就是一套指導思想行為準則。
(例如,C是過程式,Haskell是函式式,JAVA是面向物件,Python是簡單的大雜燴,shell是呼叫命令的,lua是呼叫c程式的,PHP是寫頁面的,ProLog是線性邏輯推理的。
再例如,UML是描述規格specification的,XML是儲存資料的。
再再例如,CSS是描述網頁表現的,HTML是描述網頁內容的。
javascript比較神奇,不敢說。)
**JAVA語言**
(推薦《本地Java程式碼的靜態編譯和動態編譯問題》)
JAVA語言比C++語言多了什麼?
1。 虛擬機器
a) 跨平臺
b) 動態編譯
c) 動態特性
2。 沒有指標
3。 沒有類的多繼承,有介面的多繼承。
4。 統一的庫
從編譯來說,JAVA比C++邁出了一大步。
它的跨平臺特性和執行時的靈活性,為JAVA自己以及未來語言都提供了很多可能性。
虛擬機器的好處有什麼?
1。 跨平臺:在OS與位元組碼間隔了一層。實現了程式設計師無負擔的跨平臺。
2。 動態編譯:許多資訊不必在編譯後確定,為動態特性提供可能,稍後詳細說。
3。 執行時維護著型別資訊,甚至可以載入新的型別。(CORBRA依賴這個實現)
JAVA編譯執行的過程是怎樣的?
1。 編譯後產生一個基於堆疊的位元組碼。
2。 JRE在不同的OS上提供支援。
3。 起初的JRE是解釋執行的,效率低下。
a) 獲取待執行的下一個位元組碼。
b) 解碼。
c) 從運算元堆疊獲取所需的運算元。
d) 按照 JVM 規範執行操作。
e) 將結果寫回堆疊。
JAVA是如何解決執行效率低下的問題呢?
使用JIT(Just-in-time)編譯器進行動態編譯。
JIT(Just-in-time)是怎樣執行的呢?如何解決了效率的問題?
如上圖:
1。 每次按照一個function來編譯。轉成中間表示,並最佳化其效率,再生成可執行碼。
2。 編譯器的編譯執行緒和執行執行緒是分開的,應用程式不會等待編譯的執行。
3。 分析框架Profiler會觀察程式行為,對頻繁執行的function進一步最佳化。(例如function內部物件維持一個池不必每次生成。)
動態編譯的優點有什麼?
可以根據程式的行為,最佳化其程式碼
1。 例如頻繁執行的function——熱方法
2。 例如arrayCopy方法,如果每次都複製大段記憶體,在指令集中有特別指令可以加速。
3。 例如類層次結構,多型的最佳化。(大多數虛呼叫都有其固定的一個目標,JIT因此生成的直接呼叫程式碼比虛表呼叫程式碼的效率會更高。)
動態編譯的缺點有什麼?
1。 大量的初始編譯會影響程式啟動時間。
2。 執行時候的編譯,行為分析都需要花費時間。
3。 執行效率達到穩定需要時間。
4。 實時GUI型的程式不能忍受“動態編譯”和“GC”帶來的延遲。
JAVA如何解決實時的需求?
使用AOT(Ahead-of-time)編譯器:預先編譯成為可執行碼。
AOT(Ahead-of-time)的缺點:
對於一些動態特性的支援效率低下
1。 反射機制
2。 執行時類載入
JIT與AOT的對比
總體來說,JAVA適合怎樣的應用呢?
JAVA比較時候需要長期執行的應用,例如Web伺服器,Daemon服務。
**函式式語言**
函式式語言通常有哪些呢?
1。 函式式語言
a) Lisp
b) Scheme
c) Haskell(純函式式)
d) F#?
2。 包含了函式式特性的語言
a) Python
b) Javascript
c) JAVA
d) C?
函式式語言有哪些特性?
1。 函式無副作用,只對輸入輸出有作用
2。 高階函式,lamda演算。(這個像C函式指標,但是它是高階的,即返回值可能也是函式)
3。 沒有過程,類似規格說明的語法,更容易理解,自解釋。
4。 基於list的程式設計,函式更通用。
5。 惰性計算(這個很像“樹形DP”)
6。 有對應的數學形式化表達,有可能證明其正確性。(最終目標可能是保證程式沒有bug。)
7。 其模型適合多核或者分散式的計算。
a) 不變性(immutable)
b) 惰性計算/按需計算(lazy evaluation)
c) **最重要的是,由於函式式語言不可在同一資料上做修改,每一次運用一個函式都會在新的位置產生新的資料,這與過程式語言在同一位置對資料做多次操作不同:函式式語言的函式依賴於前一次函式產生的結果資料,過程式語言依賴於資料的位置。這裡函式式語言就暗含了計算的依賴順序,如果沒有前後順序關係,就可以併發。而過程式語言沒有指定這個順序,就需要透過加鎖、Actor、Channel等模式來指定這個順序**
總的來說,函式式語言,向著更抽象邁了一大步,更像是數學上的表達,幾乎與馮諾伊曼體系斷絕了關係。
函式式語言的劣勢?
1。 效率不高(因為其抽象,遠離了馮諾伊曼體系)
2。 平臺以及開發環境都比較簡單。
3。 缺少推廣,應用不廣泛
**邏輯程式設計**
ProLog語言,線性邏輯。人工智慧語言。沒有接觸過。
**總結**
動態性有哪些呢?
1。 多型性:執行時根據具體物件來訪問屬於它的方法。(而不理會指標的型別。)
2。 反射:執行時維繫著型別結構的Meta-Data。
3。 執行時類載入:執行後再次載入新的資料型別和指令流。
4。 動態連結:OS根據按需連結庫檔案。
編譯語言 和 解釋語言 的分界在哪裡?
語言本身並沒有編譯型別或者解釋型別。(例如:JAVA也可以靜態編譯後成可執行碼。)只有少數執行時特性是依賴於解釋型的。(可能需要執行環境的支援。)
為什麼解釋語言都需要虛擬機器或者執行環境支援?
動態編譯,執行時Meta-Data的儲存,這些功能對於每個程式都是一致的。
所以把它們分離開來,不必每個程式植入這些程式碼
非指令碼語言 和 指令碼語言
指令碼語言,我理解是負責排程其他程式碼的語言。
例如shell指令碼(呼叫命令),lua(呼叫C)。
跨平臺分為哪些層次?
1。 原始碼跨平臺(C,C++,但是因為系統呼叫介面不同,程式設計師負擔太大,但是彙編卻不是。)
2。 執行碼跨平臺(JAVA,有些語言直接從原始碼解釋執行,例如Javascript,PHP)
發展歷史(推薦《近看圖靈碗 (一。 從蘇黎世到巴黎)》)
學術上有哪些實驗性語言?
1。 Fortran
2。 ALGOL58
3。 ALGOL60
4。 Lisp
5。 smalltalk
常用語言
過程式:C,ALGOL,Pascal,
面向物件式:C++,smalltalk,JAVA,Delphi
函式式:Lisp,Scheme,Haskell,
邏輯式:Prolog
指令碼?PHP,Python,Ruby
儲存描述資訊:XML,CSS,HTML
**回答問題**
程式設計語言的目的是什麼?
1。 控制資料
2。 控制指令流
為什麼大多數語言有控制流?逐行執行+跳轉。這與我們的需求差很遠(例如一個教務管理系統。)
逐行執行,很大程度是起源於馮諾依曼體系結構。
為什麼型別申明在C語言中要與控制流隔離開來?
因為在編譯時,具體的型別資訊,要轉化成地址偏移,然後替換控制流中的型別變數。
現在主流語言最基本的元素是?
控制流 與 型別系統。
有沒有語言它的型別結構,在執行時也可以改變?
Javascript只有物件沒有類,使用prototype的方式繼承,執行時給某個物件新增新的資料成員。沒有型別體系。
許多後來的語言在執行時都儲存著型別資訊的,例如Python,JAVA。
**綜上所述**
控制流——指令流
型別系統——為了計算出變數地址資訊
區分執行時的Meta-Data與編譯時的Meta-Data
想清楚自己想要什麼,才能有的放矢,不然浪費的還是自己的時間。
如果需要一些Python和Java的一些核心知識點
私信傳送“1”,即可獲取
私信方法:點我主頁頭像旁邊的私信按鈕,回覆“1”即可
也希望我的一些資料和資源可以為你能有所幫助!