2019,9,29面試中的不足與總結

1.hello world程序運行過程

預處理器根據以字符#開頭的命令修改原始的c程序,比如#include<stdio.h>告訴預處理器讀取系統頭文件stdio.h的內容,並把它直接插入程序文本中,將#define的變量替換等等,結果得到了另一個c程序,通常以.i作爲文件擴展名。

       編譯器將文本文件hello.i翻譯成hello.s,它包含了一個彙編語言程序。彙編語言程序中的每條語句都以一種標準的文本格式確切的描述一條低級機器語言指令。

       彙編器將彙編程序翻譯爲機器語言指令,把這些指令打包成可重定位目標程序(relocateble object program)的格式,並把結果保存在hello.o中。hello.o文件是二進制文件,因爲他的字節編碼是機器語言指令而不是ascii碼。如果用文本編輯器打開hello.o會看到一堆亂碼。

       鏈接階段,比如hello中用到了printf函數,這是標準c庫的函數,存在於一個名爲printf.o的單獨編譯好的目標文件中,這個文件必須以某種方式合併到我們編譯好的的目標文件中。鏈接器(ld)程序負責處理這種合併,結果得到hello文件,它是可執行目標文件,可以被加載到內存中,由系統執行。

2.靜態庫與動態庫的區別

靜態庫
概念

靜態庫是指在我們的應用中,有一些公共代碼是需要反覆使用,就把這些代碼編譯爲“庫”文件;在鏈接步驟中,連接器將從庫文件取得所需的代碼,複製到生成的可執行文件中的這種庫
特點

可執行文件中包含了庫代碼的一份完整拷貝

靜態庫的代碼是在編譯過程中被載入程序中

缺點

就是被多次使用就會有多份冗餘拷貝
動態庫(動態鏈接庫)
概念

動態鏈接提供了一種方法,使進程可以調用不屬於其可執行代碼的函數
特點

函數的可執行代碼位於一個 DLL 中,該 DLL 包含一個或多個已被編譯、鏈接並與使用它們的進程分開存儲的函數

DLL 還有助於共享數據和資源

多個應用程序可同時訪問內存中單個DLL 副本的內容

DLL 是一個包含可由多個程序同時使用的代碼和數據的庫,Windows下動態庫爲.dll後綴,在linux下爲.so後綴

Linux下靜態庫和動態庫區別
命名上:靜態庫文件名的命名方式是“libxxx.a”,庫名前加”lib”,後綴用”.a”,“xxx”爲靜態庫名;動態庫的命名方式與靜態庫類似,前綴相同,爲“lib”,後綴變爲“.so”。所以爲“libmytime.so”

鏈接上:靜態庫的代碼是在編譯過程中被載入程序中;動態庫在編譯的時候並沒有被編譯進目標代碼,而是當你的程序執行到相關函數時才調用該函數庫裏的相應函數

更新上:如果所使用的靜態庫發生更新改變,你的程序必須重新編譯;動態庫的改變並不影響你的程序,動態函數庫升級比較方便

當同一個程序分別使用靜態庫,動態庫兩種方式生成兩個可執行文件時,靜態鏈接所生成的文件所佔用的內存要遠遠大於動態鏈接所生成的文件

內存上:靜態庫每一次編譯都需要載入靜態庫代碼,內存開銷大;系統只需載入一次動態庫,不同的程序可以得到內存中相同的動態庫的副本,內存開銷小

靜態庫和程序鏈接有關和程序運行無關;動態庫和程序鏈接無關和程序運行有關

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章