<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    從一道面試題來(lái)看計(jì)算機(jī)專業(yè)基礎(chǔ)知識(shí)的重要性

    2020-05-06 23:21

    以前碰到過(guò)這樣一道面試題:

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

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

    奮筆疾書(shū),我寫了個(gè)三行?Hello,World

    可是當(dāng)我自信滿滿的交給面試官的時(shí)候他卻詭異的笑了,仿佛在說(shuō),小伙計(jì),你太天真了,你是不是看不起我出的題?

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

    當(dāng)然,以上都是我胡謅出來(lái)的,一個(gè)面試不可能有這么多內(nèi)心戲,我是一個(gè)寫代碼的程序員,又不是戲精,哪來(lái)那么多想法。

    但是,雖然內(nèi)心戲是胡謅的,可是這道面試題目確實(shí)實(shí)打?qū)嵉摹?/p>

    接下來(lái)我們仔仔細(xì)細(xì)分析下這道題目,為了先快速得到執(zhí)行結(jié)果,我們先運(yùn)行一遍看看:

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

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

    想分析這段代碼,我們首先需要了解數(shù)組這個(gè)數(shù)據(jù)結(jié)構(gòu),簡(jiǎn)單來(lái)說(shuō):數(shù)組是用一組連續(xù)的內(nèi)存空間,存儲(chǔ)一組具有相同類型的數(shù)據(jù)的線性數(shù)據(jù)結(jié)構(gòu)。

    ee13078fcd65076684f49c6655e7bd39.webp數(shù)據(jù)邏輯結(jié)構(gòu)

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

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

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

    2972f4e4d4f48ef5cf154d2b27b076b9.webp我們想要的結(jié)果

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

    這個(gè)時(shí)候我們大學(xué)學(xué)過(guò)的操作系統(tǒng)和計(jì)算機(jī)體系結(jié)構(gòu)以及甚至可能是編譯原理的知識(shí)就要排上用場(chǎng)啦。

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

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

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

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

    通過(guò)今天這道看似簡(jiǎn)單實(shí)則還是比較復(fù)雜的題目,可以說(shuō)坑很多,涉及到的知識(shí)點(diǎn)也不少,但恰恰這些知識(shí)點(diǎn)是我們大學(xué)學(xué)過(guò)的一些計(jì)算機(jī)基礎(chǔ)知識(shí),沒(méi)有涉及任何框架,也沒(méi)有任何的新技術(shù),可很多人還是答不上來(lái)。

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

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

    5 月份開(kāi)始,我會(huì)陸陸續(xù)續(xù)更新算法和數(shù)據(jù)結(jié)構(gòu)、計(jì)算機(jī)網(wǎng)絡(luò)、操作系統(tǒng)原理以及設(shè)計(jì)模式等和編程語(yǔ)言不強(qiáng)相關(guān)的一些內(nèi)容,希望大家能喜歡。

    ?往期推薦?

    ?

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




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

    生活很美好,明天見(jiàn)

    瀏覽 50
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    日本人日逼视频 | 91吴梦梦无码一区二区在线看 | 中文字幕第一页亚洲 | 欧美性爱永久免费 | 日韩欧美一级A片久久久一区S图 |