<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                [TOC] # 面試真題 ## 1\. 動態語言和靜態語言的區別? ## 2\. 弱類型語言和強類型語言的區別? ## 3\. JavaScript是強類型還是弱類型語言? ## 4\. JavaScript是動態語言還是靜態語言? # 幫助理解 我們在學習編程語言的類型系統時,經常聽說”靜態語言“、”動態語言“、”強類型語言“、”弱類型語言“這些概念,它們究竟是什么意思呢?各個概念之間又有什么區別呢? 沒看這篇文章之前可能會認為靜態語言 = 強類型語言,或者動態語言 = 弱類型語言,但它們其實不是一回事 。 <span class="vip">靜態和動態語言應該放在一起提及</span>,它們是從同一種維度來評價的;而<span class="vip">強類型/弱類型語言應該放在一起提及</span>,它們是從另外一種不同的維度來評價的。 靜態語言并不意味著強類型,動態語言也不意味著弱類型,<span class="vip">一種編程語言的類型可以是靜態/動態和強/弱的任意組合</span>,例如: * `C/C++/Java` 是靜態語言 + 強類型 * `JavaScript/PHP` 是動態語言 + 弱類型 * `Python` 是動態語言 + 強類型 在很多編程語言(比如 `C`、`C++`、`Java`、`C#` 等)中,定義變量時除了需要指明變量的名字,還需要告訴計算機它是什么類型,比如簡單的整數、浮點數、字符串,還有復雜的類、結構體、數組等。編程語言中的數據最終都要放到內存中,在內存中存取數據要明確三件事情:<span class="vip">數據存儲地址、數據的長度以及數據的處理方式</span>。 * 數據存儲地址決定了數據放在哪里; * 數據長度決定了當前數據使用了多少個字節的內存; * 數據處理方式不僅讓計算機能夠正確轉換數據的內容,不至于導致“亂碼”,還讓計算機知道如何處理基于該數據的各種運算,比如加減乘除。 變量名不僅僅是為數據起了一個好記的名字,還告訴我們數據的存儲地址,使用數據時,只要提供變量名即可,變量名會自動轉換成數據在內存中的地址。而數據類型則指明了數據的長度和處理方式,它確定了除地址以外的其它所有信息。 例如:`int n`、`char s`、`float money`等這樣的變量定義形式就確定了數據在內存中的所有要素 每種編程語言都有一個數據類型系統,沒有它的話,計算機將不知道如何處理我們程序中的數據,這包括: * 計算機不知道數據的長度,不知道該操作多少個字節; * 計算機不知道如何將值存儲到內存,不知道如何解析內存中的值; * 計算機不知道如何運算數據; 我們可以在不了解底層類型系統的情況下還可以編程,這就是高級語言的美妙之處。但是,了解我們程序中的數據將給編程帶來巨大的優勢,如下所示: **可以更少地使用內存資源** 當數據量比較大時,采用長度較小且夠用的數據類型,將節省成百上千個字節的內存空間。 **可以讀懂報錯信息** 比如將兩份數據相加時可能報錯,因為其中一個是數字類型,一個是字符串類型,雖然人類眼睛看起來都是數字,但是計算機不允許對字符串類型執行相加操作,這告訴我們,不能使用引號來包圍數字。 **改變規則** 一旦你知道數據類型是如何工作的,知道如何改變規則。比如將一個字符和一個整數相加,就可以得到另一個字符。 ## 靜態類型和動態類型語言 ### 靜態類型語言 <span class="vip">靜態類型指的是在創建數據(變量、參數、返回值等)時需要顯式指明該數據的類型</span>。通常情況下,如果不經過強制轉換,這些數據的類型一旦被定義,在程序的整個生命周期也不再改變。 ~~~java int m = 7; // 整數類型 string name = "小漂亮"; // 字符串類型 final double PI = 3.1415926; // 雙精度浮點類型 // sum() 函數包含兩個整數類型的參數,返回值也是整數類型 public int sum(int m1, int m2) { return m1 + m2; } ~~~ 這是一段`Java`代碼,它定義了幾個變量,以及一個求和函數。在代碼中,我們已經明確的指明了要處理的數據類型,包括整數、雙精度浮點數、字符串。如果沒有給編譯器這些提示,編譯器將不知道如何處理變量、方法,它只是一個對我們有意義的名稱,但是計算機不理解它。 靜態類型的編程語言有很多,常見的有 `C/C++`、`Java`、`C#`、`Go`等。 ### 動態類型語言 讓我們再對比一下動態類型的語言,請看下面的例子: ~~~javascript let m = 7; // 整數類型 let name = "小漂亮"; // 字符串類型 let PI = 3.1415926; // 單精度浮點類型 // sum() 包含兩個參數和一個返回值 function sum(m1, m2) { return m1 + m2; } ~~~ 這是一段 `JS`代碼,代碼中我們并沒有使用任何明確的數據類型,這就是一種典型的動態類型語言。 <span class="vip">動態類型的編程語言在創建數據時往往不需要指明該數據的類型,而且數據的類型也會隨著值的改變而改變,給數據賦予不同的值,數據將得到不同的類型</span>。 那么,不給數據指明類型,編程語言是如何知道它的類型的呢?編程語言會根據賦予數據的值進行猜測或者推斷。對于例子中的第一行代碼,`js`知道 `7` 是一個數字,將`7`賦值給變量 `m`,`js`也會推斷出`m`是一個數字類型。 `sum()` 函數包含的參數類型,會根據調用 `sum()` 時傳遞的值(實參)進行推斷;`sum()` 函數包含的返回值類型,會根據`m1 + m2`的運算結果進行推斷。這意味著,`sum()` 可以接收兩個數字并返回一個數字。對動態類型語言,類型是推斷出來的,甚至可以在程序運行期間更改。我們可以給上面的程序中增加一行代碼,把`"最編程"`賦值給`m`變量,這樣 `js`將把`m`變量切換為字符串類型。 常見的動態類型語言有 `JavaScript`、`PHP`、`Python`、`Ruby`等。 ### 靜態類型和動態類型的優勢 <span class="vip">對于靜態類型語言,我們需要預先明確地告訴編譯器要處理的數據的類型,這樣在程序部署之前就能發現代碼中的錯誤或者疏忽</span>。比如我們將一個變量定義為整數,將另一個變量定義為字符串,如果我們嘗試將兩個變量相加,那么編譯器在編譯期間可能就會捕獲這種語法錯誤,并且不會讓我們完成程序的構建。 這很好,<span class="vip">因為越早發現錯誤,修復它的成本就越低</span>。在部署之前修復問題,要比部署之后修復問題容易得多造成的損失也越小,加加班就搞定了,但是上線之后那可能會涉及到經濟損失。 那么,使用靜態類型是不是就一定正確呢?<span class="vip">使用靜態類型的負擔就是,在使用數據之前你必須明確地將它定義好</span>。你必須輸入更多的代碼,你必須事先知道正在使用的數據的類型,你必須知道你的操作過程中會發生什么。然而在實際開發中由于我們的疏忽或者知識缺陷,想要預判這么多往往是比較困難的。例如在`C/C++` 中,你必須知道`1/3`得到的是整數 `0`,而不是浮點數 `0.3333...`,這對初學者來說是一個坑。 在這方面,<span class="vip">動態類型語言就為我們提供了更多靈活性</span>,程序員經常稱動態語言“更具表現力”。例如在 `JS`中,`1/3`將會得到 `0.3333...`,這在很多時候都是我們期望的結果。 然而問題在于,<span class="vip">解釋器有時候會對數據類型做出錯誤的猜測,你必須知道這種情況,否則這將成為一個潛在的危險,因為解釋器不會給出錯誤提示</span>。 由于我們不能捕獲所有的潛在危險,因此<span class="vip">使用動態語言編寫的代碼往往更加脆弱,也更容易出錯</span>。 <span class="vip">動態語言中的數據類型通常在程序運行期間才能確定,這使得程序在被部署到生產環境之前很難捕獲太多錯誤</span>。程序可能在你的本地機器上正常工作,但是生產環境可能略有不同,解釋器就會產生一些不同的猜測,這將導致潛在的風險。 `JavaScript`被認為是一種典型的動態語言。隨著 `TypeScript`的誕生,程序員也想在定義變量時能夠聲明它的類型,以使 `JavaScript`變得更加靜態。 隨著 `JavaScript` 越來越流行,人們已經不限于在瀏覽器上使用它了,大名鼎鼎的 `Node.js` 使得人們可以在脫離瀏覽器,直接在機器上運行 `JavaScript`。此時程序員意識到為 `JavaScript`增加靜態類型的好處,這樣能夠消除 `JavaScript`在處理數據類型時所做的一些錯誤猜測。 將動態語言 `JavaScript`變得更像靜態語言,可以及時發現錯誤,并生成更加健壯的代碼。在 `Node.js` 的幫助下,`JavaScript`越來越多地滲透到服務器端編程,讓 `JavaScript`變得靜態就顯得尤為重要。 **總結** <span class="vip">靜態語言為我們提供了一個更加嚴格的編程環境,并且通常會生成更加健壯的代碼。動態語言為編寫代碼帶來了靈活性,同時也提高了編寫代碼的效率,但是如果你不注意數據的類型,可能就會導致代碼更容易出錯</span>。 ## 強類型語言和弱類型語言 正如前面提到的,經常混淆靜態/動態類型和強/弱類型的概念,傾向于將<span class="vip">靜態類型等同于強類型,將動態類型等同于弱類型,實際上這是不對的</span>。 <span class="vip">強/弱類型指的是編程語言如何處理運算過程中的值</span>。當值的類型不符合運算規則時,編程語言究竟是做出一些猜測臨時轉換值的類型以幫助人們解決問題,還是停止運行。 ### 強類型語言 ~~~cpp int main() { int m1 = 7; std::string m2 = "7"; // 編譯器會報錯 std::cout << (m1 + m2); return 0; } ~~~ 這是一段 `C++` 代碼,我們嘗試將一個整數和一個字符串相加,很顯然這是沒有意義的,編譯器會停止構建,并拋出一條錯誤信息。在這個例子中,我們將變量 `m2` 定義為字符串類型,但是在使用 `m2` 的時候,我們對它施加了一種不匹配的運算(字符串類型不支持算數求和運算)。`C++` 也可以在后臺默默地做一些猜測,臨時將字符串`"7"`轉換成整數`7`,這樣以上代碼就能行得通;但是 `C++` 并不會這樣做,它會立即標記此處的問題(報錯),并放棄構建,交給程序員自己處理。這就是<span class="vip">強類型語言的典型特征,它們不會處理與類型定義明顯矛盾的運算,而是把它標記為一個問題,并作為錯誤拋出</span>。通常人們認為 `C/C++`、`Java`、`C#`、`Python`、`Go`都是強類型語言,它們都不允許上述代碼中的行為。 現在雖然有辦法削弱 `C++` 的強類型系統,讓 `C++` 能夠容忍一些與類型定義不匹配的運算,但是這超出了本文的討論范圍,所以不再贅述 ### 弱類型語言 和強類型語言不一樣,<span class="vip">當我們執行一些與類型定義不匹配的運算時,弱類型語言嘗試提供幫助,它可能會臨時轉換值的類型,讓它符合當前運算</span>。 下面的例子中,我們使用 `JavaScript` 代碼執行與上述 `C++` 代碼類似的操作: ~~~javascript var m1 = 7; var m2 = "7"; console.log( m1 + m2 ); ~~~ 如果你對 `JavaScript` 特性有所了解,就會知道這段代碼不會報錯,而是正常運行,它會在控制臺上顯示 `14`,這也許正是你所期望的。 對于相加運算,如果`+`兩邊的值的類型不一樣,那么 `JavaScript`將嘗試轉換其中一個值的類型,讓它和另一個值的類型相同,然后再進行運算,并給出運算結果。這里之所以顯示 `14`,是因為 `JavaScript`將變量 `m2` 的值轉換為整數類型,得到一個數字 `7`,然后再和變量 `m1` 相加,結果就是 `14`。 `PHP` 也是一種典型的弱類型語言,對 `PHP` 執行類似的操作,它的結果是怎樣的呢?請看下面的代碼: ~~~php $m1 = 7; $m2 = "7"; echo $m1 + $m2; // 77 ~~~ 你對這個結果可能會比較驚訝,認為它和預期的不一樣,這是因為 `PHP`對值的類型進行了不同的轉換。`PHP`會將變量 `$m1` 的值轉換為字符串類型,然后再和變量 `$m2` 的字符串拼接起來,得到一個新的字符串。 字符串拼接工作非常簡單,就是將字符串中的內容直接連接起來。 `PHP` 和 `JavaScript`雖然都是弱類型語言,但是當它們遇到和類型定義明顯矛盾的運算時,可能會做出不同的猜測或者轉換,這種猜測有時讓人匪夷所思。 <span class="vip">類型系統的“強/弱”指的是當編程語言遇到與類型定義不匹配的運算時,嘗試猜測或者轉換的力度/程序。它不是一條明確的界限,而是一個范圍</span>。 * 強類型語言在遇到與類型定義明顯矛盾的運算時,一般會當做一種語法錯誤,而不會嘗試對值的類型進行轉換。 * 弱類型語言恰好相反,會猜測程序員的意圖,并對其中一些值的類型進行轉換,以讓程序繼續執行。 <span class="vip">強/弱類型是一個相對概念,將兩種語言放在一起對比時,才更容易發現明顯的差異</span>。 ### 強類型和弱類型各有什么優勢 <span class="vip">強類型語言是嚴謹的,它要確保程序員明確地知道自己在做什么</span>。如果發生錯誤,強類型語言認為這是程序員不了解當前的運算規則導致的,或者程序員對正在處理的問題含混不清。 例如,將整數`7`和字符串`"7"`相加對計算機來說是一種沒有意義的操作,如果你沒有意識到,那么強類型語言就明確地提示你。強類型語言會強迫你必須了解運算規則,并明確地告訴計算機你想做什么(通常使用強制類型轉換),不能含混不清。 <span class="vip">強類型使得程序被部署到生產環境時更加健壯,不易出錯</span>。但是,<span class="vip">我們需要付出更多成本,這包括花費更多時間編寫合理規范的代碼,以及解決更多細枝末節的問題</span>。 相反的,<span class="vip">弱類型語言消除了強類型語言的嚴格性,在較大程度上允許程序構建并正常運行,因此弱類型語言更有靈活性和表達性</span>。 弱類型語言不利的一方面是,<span class="vip">它可能錯誤地猜測程序員的意圖,并得到不被期望的運行結果</span>。 `JavaScript`是一種弱類型語言(恰好也是動態語言),但是可以使用 `TypeScript`增強,以使程序更加健壯。`TypeScript`改變了類型系統,它允許程序員在定義變量時增加顯式類型聲明,這樣 `JavaScript`就能獲得強類型語言的好處,在編譯時捕獲更多錯誤,并防止一些模糊的猜測被帶入到生產環境。 此外,支持 `TypeScript`的編輯器基本也可以在你編寫代碼時就給出錯誤提示。 # 真題解答 ## 1\. 動態語言和靜態語言的區別 靜態類型指的是在創建數據(變量、參數、返回值等)時需要顯式指明該數據的類型。通常情況下,如果不經過強制轉換,這些數據的類型一旦被定義,在程序的整個生命周期也不再改變。靜態語言為我們提供了一個更加嚴格的編程環境,并且通常會生成更加健壯的代碼。 動態類型的編程語言在創建數據時往往不需要指明該數據的類型,而且數據的類型也會隨著值的改變而改變,給數據賦予不同的值,數據將得到不同的類型。動態語言為編寫代碼帶來了靈活性,同時也提高了編寫代碼的效率,但是如果你不注意數據的類型,可能就會導致代碼更容易出錯。 ## 2\. 弱類型語言和強類型語言的區別 強/弱類型指的是編程語言如何處理運算過程中的值。當值的類型不符合運算規則時,編程語言究竟是做出一些猜測臨時轉換值的類型以幫助人們解決問題,還是停止運行。 強類型語言的典型特征就是它們不會處理與類型定義明顯矛盾的運算,而是把它標記為一個問題,并作為錯誤拋出。強類型使得程序被部署到生產環境時更加健壯,不易出錯;但是,我們需要付出更多成本,這包括花費更多時間編寫合理規范的代碼,以及解決更多細枝末節的問題。 弱類型語言就是當我們執行一些與類型定義不匹配的運算時,弱類型語言嘗試提供幫助,它可能會臨時轉換值的類型,讓它符合當前運算。弱類型語言消除了強類型語言的嚴格性,在較大程度上允許程序構建并正常運行,因此弱類型語言更有靈活性和表達性。弱類型語言不利的一方面是,它可能錯誤地猜測程序員的意圖,并得到不被期望的運行結果。 ## 3\. JavaScript是強類型還是弱類型語言? JavaScript是弱類型語言 ## 4\. JavaScript是動態語言還是靜態語言? JavaScript既是弱類型語言同時也是動態語言
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看