<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          從一道面試題來看計算機專業(yè)基礎知識的重要性

          2020-05-06 23:21

          以前碰到過這樣一道面試題:

          // 請分析如下代碼的執(zhí)行結果。#include 
          int main(){????int?i?=?0;????int?arr[3]?=?{0}; for(;i<=3;i++) { arr[i] = 0; printf("Hello, World! \n"); } return 0;}

          我心想,頭一次面試碰到這么簡單的面試題,面試官你是不是看不起我?

          奮筆疾書,我寫了個三行?Hello,World

          可是當我自信滿滿的交給面試官的時候他卻詭異的笑了,仿佛在說,小伙計,你太天真了,你是不是看不起我出的題?

          這一笑笑得我是冷汗直冒,就跟偷偷打飛機被人發(fā)現(xiàn)了一樣,異常尷尬。

          當然,以上都是我胡謅出來的,一個面試不可能有這么多內心戲,我是一個寫代碼的程序員,又不是戲精,哪來那么多想法。

          但是,雖然內心戲是胡謅的,可是這道面試題目確實實打實的。

          接下來我們仔仔細細分析下這道題目,為了先快速得到執(zhí)行結果,我們先運行一遍看看:

          894d77e2a5da6f16f4311fc7ede18046.webp執(zhí)行結果

          可以看到,這段代碼竟然無限循環(huán)了,是不是很難理解。

          想分析這段代碼,我們首先需要了解數(shù)組這個數(shù)據(jù)結構,簡單來說:數(shù)組是用一組連續(xù)的內存空間,存儲一組具有相同類型的數(shù)據(jù)的線性數(shù)據(jù)結構。

          ee13078fcd65076684f49c6655e7bd39.webp數(shù)據(jù)邏輯結構

          根據(jù)數(shù)組的邏輯結構圖我們可以總結出一位數(shù)組的尋址公式為:arr[i]_address = base_address + i*data_size,其中?data_size?表示每個數(shù)據(jù)的磁盤空間大小。

          根據(jù)這個尋址公式,我們來對上邊的代碼做出尋址行為的分析,當 i = 3 時,理論上尋址公式為?arr[3]_address = arr[2]_address + i*data_size,此處需要注意的是因為 C 語言中,數(shù)組越界是一種未決行為,如果你是從事 Java 或者其他高級語言的話會發(fā)現(xiàn)對于數(shù)組越界是當做一種異常行為來處理的,但是 C 語言不是。對于 C 語言來說,只要不是訪問受限的內存空間,所有的內存空間都是可以自由訪問的,哪么根據(jù)既定尋址公式,arr[3]會被定位到某塊本不屬于數(shù)組的內存地址上,而這塊地址恰恰存儲的是我們定義的變量 i,也就是說此時?arr[3] = 0?,相當于 i = 0 時的情況,這樣就會導致無限循環(huán)。

          如果i<=3改成i<3,結果才是我們想要的樣子。

          2972f4e4d4f48ef5cf154d2b27b076b9.webp我們想要的結果

          到此,程序的執(zhí)行結果我們分析完了,但是你可能對于上邊加粗的?而這塊地址恰恰存儲的是我們定義的變量 i?這句話有疑問,怎么就?arr[3] = 0?了呢?

          這個時候我們大學學過的操作系統(tǒng)和計算機體系結構以及甚至可能是編譯原理的知識就要排上用場啦。

          我們都知道在寫一個函數(shù)時會使用形參,形參實例化時會形成一份拷貝,調用這個函數(shù)時會把實參傳進去,調用完之后那些臨時拷貝又被釋放,那么計算機在調用函數(shù)時是如何進行形參的保存和釋放的呢?這個時候會用到一個叫棧的數(shù)據(jù)結構。

          棧用于維護函數(shù)調用的上下文,離開了棧,函數(shù)調用就無法實現(xiàn)。棧是從高地址向低地址延伸的。每個函數(shù)的每次調用都有它自己獨立的一個棧幀,這個棧幀中有它所需要的各種信息。

          回到上邊那段代碼,產生死循環(huán)的第一個原因就是因為函數(shù)調用棧的特殊性:函數(shù)體內的局部變量是存在棧上的,且是連續(xù)壓棧。在 Linux 進程的內存布局中,棧區(qū)在高地址空間,從高向低增長。變量 i 和 arr 在相鄰地址,且 i 比 arr 的地址大,所以 arr 越界正好訪問到i。當然,前提是 i 和 arr 元素要同類型,否則那段代碼仍是未決行為。

          還有另一個原因是因為編譯器分配內存和字節(jié)對齊,我們定義 3 個元素的數(shù)組加上一個變量 i 。4 個整數(shù)剛好能滿足 8 字節(jié)對齊 所以 i 的地址恰好跟著?arr[2]?后面導致死循環(huán)。如果數(shù)組本身有 4 個元素 則這里不會出現(xiàn)死循環(huán)。因為編譯器 64 位操作系統(tǒng)下,默認會進行 8 字節(jié)對齊 變量 i 的地址就不緊跟著數(shù)組后面了。

          通過今天這道看似簡單實則還是比較復雜的題目,可以說坑很多,涉及到的知識點也不少,但恰恰這些知識點是我們大學學過的一些計算機基礎知識,沒有涉及任何框架,也沒有任何的新技術,可很多人還是答不上來。

          簡言之,你別看有些人整天這框架那框架的玩的很嗨,但是它的計算機專業(yè)素養(yǎng)是遠遠不夠的,職業(yè)生涯前期可能不會有什么區(qū)別,但是長遠來看,掌握了基礎知識的人上限勢必要高一些。

          從今天開始,本公眾號也會更新一些計算機基礎知識的專欄,自打我停止更新這段時間,我也思考了很多,總覺得每天都很焦慮,玩著手機的時候焦慮沒有好好學習,學習的時候又心心念著電視劇劇情走向,今天學這個框架明天學那個框架,到頭來發(fā)現(xiàn)不但啥都沒學會,原來會的東西還給忘了。

          5 月份開始,我會陸陸續(xù)續(xù)更新算法和數(shù)據(jù)結構、計算機網(wǎng)絡、操作系統(tǒng)原理以及設計模式等和編程語言不強相關的一些內容,希望大家能喜歡。

          ?往期推薦?

          ?

          IntelliJ IDEA 2020.1 穩(wěn)定版發(fā)布




          如果你喜歡這篇文章,歡迎在看轉發(fā)

          生活很美好,明天見

          瀏覽 50
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线观看无码高清视频 | 国产精品资源 | 久久久久亚洲AV色欲av | 免费看国产黄色视频 | 超碰国内自拍 |