- 相關(guān)推薦
移動計(jì)算機(jī)面試問題經(jīng)驗(yàn)
C語言考查的重點(diǎn)一般是:指針、結(jié)構(gòu)體、條件編譯、全局變量/局部變量。以下是
我遇見過的面試問題:
1)請說一下extern C的作用(漢略)
Extern “C”是由C++提供的一個(gè)連接交換指定符號,用于告訴C++這段代碼是C函數(shù)。這是因?yàn)镃++編譯后庫中函數(shù)名會變得很長,與C生成的不一致,造成C++不能直接調(diào)用C函數(shù),加上extren “c”后,C++就能直接調(diào)用C函數(shù)了。
Extern “C”主要使用正規(guī)DLL函數(shù)的引用和導(dǎo)出和 在C++包含C函數(shù)或C頭文件時(shí)使用。使用時(shí)在前面加上extern “c” 關(guān)鍵字即可
extern是C/C++語言中表明函數(shù)和全局變量作用范圍(可見性)的關(guān)鍵字,該關(guān)鍵字告訴編譯器,其聲明的函數(shù)和變量可以在本模塊或其它模塊中使用。記住,下列語句:
extern int a;
僅僅是一個(gè)變量的聲明,其并不是在定義變量a,并未為a分配內(nèi)存空間。變量a在所有模塊中作為一種全局變量只能被定義一次,否則會出現(xiàn)連接錯(cuò)誤。
通常,在模塊的頭文件中對本模塊提供給其它模塊引用的函數(shù)和全局變量以關(guān)鍵字extern聲明。例如,如果模塊B欲引用該模塊A中定義的全局變量和函數(shù)時(shí)只需包含模塊A的頭文件即可。這樣,模塊B中調(diào)用模塊A中的函數(shù)時(shí),在編譯階段,模塊B雖然找不到該函數(shù),但是并不會報(bào)錯(cuò);它會在連接階段中從模塊A編譯生成的目標(biāo)代碼中找到此函數(shù)。(
一、修飾名(Decorated Name)
C/C++程序中的函數(shù)在內(nèi)部是通過修飾名來標(biāo)識的。修飾名是在函數(shù)定義或原型編譯階段由編譯器創(chuàng)建字符串。當(dāng)你在LINK等工具中要指定一個(gè)函數(shù)名時(shí),會用到修飾名。
1、使用修飾名:
大多數(shù)情況下,你不必知道函數(shù)的修飾名是什么。連接器等工具通常都能處理函數(shù)未修飾的名字。然而,在有些情況下,你可能需要指定函數(shù)的修飾名。對于C++重載函數(shù)和特定的成員函數(shù)(如:構(gòu)造函數(shù)和析構(gòu)函數(shù)),你必須指定這些函數(shù)的修飾名,以便連接器等工具能夠匹配名字。同時(shí),你也必須在那些引用c或c++函數(shù)名的匯編源文件中使用修飾名。
2、查看修飾名:
如果你編譯了一個(gè)源文件,該源文件中包含了函數(shù)定義或原型,你可以獲得函數(shù)的修飾名形式。
(1)用編譯器列表(compiler listing)來查看:
(i)通過將列表文件類型編譯器選項(xiàng)(/FA[c|s]) 設(shè)置為下面中的一種,來產(chǎn)生列表文件:Assembly with Machine Code (/FAc); Assembly with Source Code (/FAs); Assembly, Machine Code, and Source (/FAcs).
(ii)在產(chǎn)生的列表文件中,找到包含未經(jīng)修飾的函數(shù)定義的行。
(iii)查找前面一行。PROC NEAR 命令標(biāo)簽前就是函數(shù)名經(jīng)過修飾后的形式。
(2)使用DUMPBIN工具來查看:
在.OBJ或.LIB上運(yùn)行DUMPBIN,使用/SYMBOLS選項(xiàng)。在輸出中查找未經(jīng)修飾的函數(shù)定義。后面跟著的就是經(jīng)過修飾的函數(shù)名,用圓括號括起來的。
二、替代連接說明:
如果在c++中編寫一個(gè)程序需要用到c的庫,那該如何?如果這樣聲明一個(gè)c函數(shù):
void f(int a,char b);
c++編譯器就會將這個(gè)名字變成相應(yīng)的修飾名,比如:?f@@YAXHD@Z。
然而,c編譯器編譯的庫的內(nèi)部函數(shù)名(連接器使用)是完全不同的。這樣,當(dāng)c++連接器連接c的函數(shù)庫時(shí),將會產(chǎn)生內(nèi)部使用函數(shù)不匹配。
故,c++中提供了一個(gè)替代連接說明(alternate linkage specification),它是通過重載extern關(guān)鍵字來實(shí)現(xiàn)的。
extern后跟一個(gè)字符串來指定想聲明的函數(shù)的連接類型,后面是函數(shù)聲明,比如:
extern "C" void f(int a,char b);
這樣,就是告訴編譯器是c連接,這樣就不會轉(zhuǎn)換函數(shù)名了。此例中,編譯后的內(nèi)部函數(shù)名是_f。
2)請說一下#ifdef...的作用(漢略)
#ifdef的作用大體上是工程功能的切換,通常是根據(jù)某些宏是否定義來決定是否啟用某些功能。比如網(wǎng)絡(luò)監(jiān)控系統(tǒng),通過宏的切換,可以實(shí)現(xiàn)平臺的移植,視屏路數(shù)的定義,云臺、矩陣和透明串口的切換,等等。由于#ifdef的存在,靜態(tài)配置一下參數(shù)即可讓firmware實(shí)現(xiàn)不同的功能。
1.利用#ifdef/#endif將某程序功能模塊包括進(jìn)去,以向某用戶提供該功能。
在程序首部定義#ifdef HNLD:
#ifdef HNLD
include"n166_hn.c"
#endif
如果不許向別的用戶提供該功能,則在編譯之前將首部的HNLD加一下劃線即可。
2.在每一個(gè)子程序前加上標(biāo)記,以便追蹤程序的運(yùn)行。
#ifdef DEBUG
printf(" Now is in hunan !");
#endif
3.避開硬件的限制。有時(shí)一些具體應(yīng)用環(huán)境的硬件不一樣,但限于條件,本地缺乏這種設(shè)備,于是繞過硬件,直接寫出預(yù)期結(jié)果。具體做法是:
#ifndef TEST
i=dial();
//程序調(diào)試運(yùn)行時(shí)繞過此語句
#else
i=0;
#endif
調(diào)試通過后,再屏蔽TEST的定義并重新編譯,即可發(fā)給用戶使用了。
3)C語言里,哪些變量是存放在堆里,哪些是存放在棧里?(普天)
heap area存放程序的動態(tài)數(shù)據(jù)
stack area存放程序的局部數(shù)據(jù)
1、棧區(qū)(stack)— 由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。地址是由高向低減少的
2、堆區(qū)(heap)— 一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時(shí)可能由OS回收。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表,呵呵。地址是由低向高增長的
4)C語言里的static關(guān)鍵詞是什么含義?(普天)
與extern對應(yīng)的關(guān)鍵字是static,被它修飾的全局變量和函數(shù)只能在本模塊中使用。因此,一個(gè)函數(shù)或變量只可能被本模塊使用時(shí),其不可能被extern “C”修飾。
5)進(jìn)程和線程有什么區(qū)別?(普天)
線程的引入:例如,有一個(gè)Web服務(wù)器要進(jìn)程的方式并發(fā)地處理來自不同用戶的網(wǎng)頁訪問請求的話,可以創(chuàng)建父進(jìn)程和多個(gè)子進(jìn)程的方式來進(jìn)行處理,但是創(chuàng)建一個(gè)進(jìn)程要花費(fèi)較大的系統(tǒng)開銷和占用較多的資源。除外,這些不同的用戶子進(jìn)程在執(zhí)行的時(shí)候涉及到進(jìn)程上下文切換,上下文切換是一個(gè)復(fù)雜的過程。所以,為了減少進(jìn)程切換和創(chuàng)建的開銷,提高執(zhí)行效率和節(jié)省資源,人們在操作系統(tǒng)中引入了"線程(thread)"的概念。
進(jìn)程的作用和定義:進(jìn)程是為了提高CPU的執(zhí)行效率,減少因?yàn)槌绦虻却龓淼腃PU空轉(zhuǎn)以及其他計(jì)算機(jī)軟硬件資源的浪費(fèi)而提出來的。進(jìn)程是為了完成用戶任務(wù)所需要的程序的一次執(zhí)行過程和為其分配資源的一個(gè)基本單位,是一個(gè)具有獨(dú)立功能的程序段對某個(gè)數(shù)據(jù)集的一次執(zhí)行活動。
線程和進(jìn)程的區(qū)別:
1、線程是進(jìn)程的一部分,所以線程有的時(shí)候被稱為是輕權(quán)進(jìn)程或者輕量級進(jìn)程。
2、一個(gè)沒有線程的進(jìn)程是可以被看作單線程的,如果一個(gè)進(jìn)程內(nèi)擁有多個(gè)進(jìn)程,進(jìn)程的執(zhí)行過程不是一條線(線程)的,而是多條線(線程)共同完成的。
3、系統(tǒng)在運(yùn)行的時(shí)候會為每個(gè)進(jìn)程分配不同的內(nèi)存區(qū)域,但是不會為線程分配內(nèi)存(線程所使用的資源是它所屬的進(jìn)程的資源),線程組只能共享資源。那就是說,出了CPU之外(線程在運(yùn)行的時(shí)候要占用CPU資源),計(jì)算機(jī)內(nèi)部的軟硬件資源的分配與線程無關(guān),線程只能共享它所屬進(jìn)程的資源。
4、與進(jìn)程的控制表PCB相似,線程也有自己的控制表TCB,但是TCB中所保存的線程狀態(tài)比PCB表中少多了。
5、進(jìn)程是系統(tǒng)所有資源分配時(shí)候的一個(gè)基本單位,擁有一個(gè)完整的虛擬空間地址,并不依賴線程而獨(dú)立存在。
進(jìn)程與程序的區(qū)別:
程序是一組指令的集合,它是靜態(tài)的實(shí)體,沒有執(zhí)行的含義。而進(jìn)程是一個(gè)動態(tài)的實(shí)體,有自己的生命周期。一般說來,一個(gè)進(jìn)程肯定與一個(gè)程序相對應(yīng),并且只有一個(gè),但是一個(gè)程序可以有多個(gè)進(jìn)程,或者一個(gè)進(jìn)程都沒有。除此之外,進(jìn)程還有并發(fā)性和交往性。簡單地說,進(jìn)程是程序的一部分,程序運(yùn)行的時(shí)候會產(chǎn)生進(jìn)程。
總結(jié):
線程是進(jìn)程的一部分,進(jìn)程是程序的一部分
【移動計(jì)算機(jī)面試問題經(jīng)驗(yàn)】相關(guān)文章:
面試問題的經(jīng)驗(yàn)10-01
銀行面試經(jīng)驗(yàn):平安銀行面試經(jīng)驗(yàn)及面試問題10-06
銀行面試經(jīng)驗(yàn):上海銀行面試經(jīng)驗(yàn)及面試問題09-15
銀行面試經(jīng)驗(yàn):臺州銀行面試經(jīng)驗(yàn)及面試問題分享08-14
銀行面試經(jīng)驗(yàn):北京銀行面試經(jīng)驗(yàn)及面試問題分享10-13
銀行面試經(jīng)驗(yàn): 寧波銀行面試經(jīng)驗(yàn)及面試問題分享06-16
銀行面試經(jīng)驗(yàn):中信銀行面試經(jīng)驗(yàn)及面試問題分享07-21