柯達(dá)面試題詳解
一個(gè)朋友參加柯達(dá)的面試,被幾個(gè)問(wèn)題郁悶了,回來(lái)整理一下,鞏固一下基礎(chǔ)知識(shí),順便分享給大家,下次可不能再讓面試官給難住了:)
系統(tǒng)調(diào)用與函數(shù)的區(qū)別
從程序完成的功能來(lái)看,函數(shù)庫(kù)提供的函數(shù)通常是不需要操作系統(tǒng)的服務(wù),函數(shù)是在用戶空間內(nèi)執(zhí)行的,除非函數(shù)涉及到I/O操作等,一般是不會(huì)切到核心態(tài)的。系統(tǒng)調(diào)用是要求操作系統(tǒng)為用戶提供進(jìn)程,提供某種服務(wù),通常是涉及系統(tǒng)的硬件資源和一些敏感的軟件資源等。函數(shù)庫(kù)的函數(shù),尤其與輸入輸出相關(guān)的函數(shù),大多必須通過(guò)Linux的系統(tǒng)調(diào)用來(lái)完成。因此我們可以將函數(shù)庫(kù)的函數(shù)當(dāng)成應(yīng)用程序設(shè)計(jì)人員與系統(tǒng)調(diào)用程序之間的一個(gè)中間層,通過(guò)這個(gè)中間層,我們可以用一致的接口來(lái)安全的調(diào)用系統(tǒng)調(diào)用。這樣程序員可以只要寫(xiě)一次代碼就能夠在不同版本的linux系統(tǒng)間使用積壓種具體實(shí)現(xiàn)完全不同的系統(tǒng)調(diào)用。至于如何實(shí)現(xiàn)對(duì)不同的系統(tǒng)調(diào)用的兼容性問(wèn)題,那是函數(shù)庫(kù)開(kāi)發(fā)者所關(guān)心的問(wèn)題。
從程序執(zhí)行效率來(lái)看,系統(tǒng)調(diào)用的執(zhí)行效率大多要比函數(shù)高,尤其是處理輸入輸出的函數(shù)。當(dāng)處理的數(shù)據(jù)量比較小時(shí),函數(shù)庫(kù)的函數(shù)執(zhí)行效率可能比較好,因?yàn)楹瘮?shù)庫(kù)的作法是將要處理的數(shù)據(jù)先存入緩沖區(qū)內(nèi),等到緩沖區(qū)裝滿了,再將數(shù)據(jù)一次寫(xiě)入或者讀出。這種方式處理小量數(shù)據(jù)時(shí)效率比較高,但是在進(jìn)行系統(tǒng)調(diào)用時(shí),因?yàn)橛脩暨M(jìn)程從用戶模式進(jìn)入系統(tǒng)核心模式,中間涉及了許多額外的任務(wù)的切換工作,這些操作稱為上下文切換,此類的額外工作會(huì)影響系統(tǒng)的執(zhí)行效率。但是當(dāng)要處理的數(shù)據(jù)量比較大時(shí),例如當(dāng)輸入輸出的數(shù)據(jù)量超過(guò)文件系統(tǒng)定義的盡寸時(shí),利用系統(tǒng)調(diào)用可獲得較高的效率。
從程序的可移植性的角度來(lái)看,相對(duì)于系統(tǒng)調(diào)用,C語(yǔ)言的標(biāo)準(zhǔn)備函數(shù)庫(kù)(ANSI C) 具備較高的可移植性,在不同的系統(tǒng)環(huán)境下,只要做很少的修改,通常情況是不需要修改的。
可重入函數(shù)概念: 主要用于多任務(wù)環(huán)境中,一個(gè)可重入的函數(shù)簡(jiǎn)單來(lái)說(shuō)就是可以被中斷的函數(shù),也就是說(shuō),可以在這個(gè)函數(shù)執(zhí)行的任何時(shí)刻中斷它,轉(zhuǎn)入OS調(diào)度下去執(zhí)行另外一段代碼,而返回控制時(shí)不會(huì)出現(xiàn)什么錯(cuò)誤;而不可重入的函數(shù)由于使用了一些系統(tǒng)資源,比如全局變量區(qū),中斷向量表等,所以它如果被中斷的話,可能會(huì)出現(xiàn)問(wèn)題,這類函數(shù)是不能運(yùn)行在多任務(wù)環(huán)境下的。
也可以這樣理解,重入即表示重復(fù)進(jìn)入,首先它意味著這個(gè)函數(shù)可以被中斷,其次意味著它除了使用自己棧上的變量以外不依賴于任何環(huán)境(包括static),這樣的函數(shù)就是purecode(純代碼)可重入,可以允許有該函數(shù)的多個(gè)副本在運(yùn)行,由于它們使用的是分離的棧,所以不會(huì)互相干擾。如果確實(shí)需要訪問(wèn)全局變量(static),一定要注意實(shí)施互斥手段?芍厝牒瘮(shù)在并行運(yùn)行環(huán)境中非常重要,但是一般要為訪問(wèn)全局變量付出一些性能代價(jià)。 編寫(xiě)可重入函數(shù)時(shí),若使用全局變量,則應(yīng)通過(guò)關(guān)中斷、信號(hào)量(即P、V操作)等手段對(duì)其加以保護(hù)。 說(shuō)明:若對(duì)所使用的全局變量不加以保護(hù),則此函數(shù)就不具有可重入性,即當(dāng)多個(gè)進(jìn)程調(diào)用此函數(shù)時(shí),很有可能使有關(guān)全局變量變?yōu)椴豢芍獱顟B(tài)。 堆和棧的區(qū)別 一個(gè)由c/C++編譯的程序占用的內(nèi)存分為以下幾個(gè)部分 1、棧區(qū)(stack) 由編譯器自動(dòng)分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。 2、堆區(qū)(heap) 一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時(shí)可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表,呵呵。 3、全局區(qū)(靜態(tài)區(qū))(static),全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。 - 程序結(jié)束后有系統(tǒng)釋放 4、文字常量區(qū) 常量字符串就是放在這里的。 程序結(jié)束后由系統(tǒng)釋放 5、程序代碼區(qū)存放函數(shù)體的二進(jìn)制代碼。 在什么情況下析構(gòu)函數(shù)必須是虛函數(shù)若類中有虛函數(shù),這個(gè)類的析構(gòu)函數(shù)應(yīng)該是虛的析構(gòu)函數(shù),否則會(huì)有錯(cuò)假設(shè)夫類為a,子類為b,當(dāng)a* p = new b();要析構(gòu)p指向的對(duì)象時(shí),若a中的析構(gòu)函數(shù)不是virtual則調(diào)用 p時(shí),不會(huì)調(diào)用b的析構(gòu)函數(shù),這樣在b中分配的資源就無(wú)法釋放了。你可以在a和b的析構(gòu)函數(shù)中輸出看一下,或者用調(diào)試工具跟蹤看一下 在全局變量和全局靜態(tài)變量有什么區(qū)別變量可以分為:全局變量、靜態(tài)全局變量、靜態(tài)局部變量和局部變量。
按存儲(chǔ)區(qū)域分,全局變量、靜態(tài)全局變量和靜態(tài)局部變量都存放在內(nèi)存的靜態(tài)存儲(chǔ)區(qū)域,局部變量存放在內(nèi)存的棧區(qū)。
按作用域分,全局變量在整個(gè)工程文件內(nèi)都有效;靜態(tài)全局變量只在定義它的文件內(nèi)有效;靜態(tài)局部變量只在定義它的函數(shù)內(nèi)有效,只是程序僅分配一次內(nèi)存,函數(shù)返回后,該變量不會(huì)消失;局部變量在定義它的函數(shù)內(nèi)有效,但是函數(shù)返回后失效。
全局變量和靜態(tài)變量如果沒(méi)有手工初始化,則由編譯器初始化為0。局部變量的值不可知。靜態(tài)全局變量,只本文件可以用。全局變量是沒(méi)有定義存儲(chǔ)類型的外部變量,其作用域是從定義點(diǎn)到程序結(jié)束.省略了存儲(chǔ)類型符,系統(tǒng)將默認(rèn)為是自動(dòng)型.
靜態(tài)全局變量是定義存儲(chǔ)類型為靜態(tài)型的外部變量,其作用域是從定義點(diǎn)到程序結(jié)束,所不同的是存儲(chǔ)類型決定了存儲(chǔ)地點(diǎn),靜態(tài)型變量是存放在內(nèi)存的數(shù)據(jù)區(qū)中的, 它們?cè)诔绦蜷_(kāi)始運(yùn)行前就分配了固定的字節(jié),在程序運(yùn)行過(guò)程中被分配的字節(jié)大小是不改變的.只有程序運(yùn)行結(jié)束后,才釋放所占用的內(nèi)存.自動(dòng)型變量存放在堆棧區(qū)中.堆棧區(qū)也是內(nèi)存中一部分,該部分內(nèi)存在程序運(yùn)行中是重復(fù)使用的.聲明變量與定義變量有什么區(qū)別聲明是向編譯器介紹名字--標(biāo)識(shí)符。它告訴編譯器“這個(gè)函數(shù)或變量在某處可找到,它的模樣象什么”。而定義是說(shuō):“在這里建立變量”或“在這里建立函數(shù)”。它為名字分配存儲(chǔ)空間。無(wú)論定義的是函數(shù)還是變量,編譯器都要為它們?cè)诙x點(diǎn)分配存儲(chǔ)空間。對(duì)于變量,編譯器確定變量的大小,然后在內(nèi)存中開(kāi)辟空間來(lái)保存其數(shù)據(jù),對(duì)于函數(shù),編譯器會(huì)生成代碼,這些代碼最終也要占用一定的內(nèi)存。在C和C++中,可以在不同的地方聲明相同的變量和函數(shù),但只能有一個(gè)定義(有時(shí)這稱為ODR,單一定義規(guī)則)。。。
定義也可以是聲明,如果有int x;,之前編譯器未發(fā)現(xiàn)標(biāo)識(shí)符x,編譯器則把這一標(biāo)識(shí)符看成是定義并立即為它分配存儲(chǔ)空間。 。。。。。 對(duì)“變量聲明”的解釋向來(lái)模糊且自相矛盾。。。 函數(shù)聲明包括函數(shù)類型、函數(shù)名、參數(shù)列表和一個(gè)分號(hào),這些信息足以編譯器認(rèn)出它是一個(gè)函數(shù)聲明并可識(shí)別出這個(gè)函數(shù)的`外部特征。由此推斷,變量聲明應(yīng)是類型標(biāo)識(shí)后面跟一個(gè)標(biāo)識(shí)符。如int a;但這產(chǎn)生了一個(gè)矛盾,這段代碼有足夠的信息讓編譯器為之分配存儲(chǔ)空間,而且編譯器也確實(shí)給之分配了存儲(chǔ)空間。要解決這個(gè)問(wèn)題,對(duì)于C和C++需要一個(gè)關(guān)鍵字來(lái)說(shuō)明“這是一個(gè)聲明,它的定義在別的地方”,這個(gè)關(guān)鍵字就是extern,它表示變量是在文件以外定義的,或在文件后面定義的。
在變量定義前加extern表示聲明一個(gè)變量但不定義它,如: extern int a; extern也可用于函數(shù)聲明,如: extern int func1(int length,int width); 但由于沒(méi)有函數(shù)體,編譯器必把它當(dāng)成聲明而非定義,extern對(duì)于函數(shù)來(lái)說(shuō)是多余的、可選的。C語(yǔ)言的設(shè)計(jì)者并不要求函數(shù)聲明使用extern,這可能有些令人遺憾,如果函數(shù)聲明也要求用extern,那么形式上與變量聲明更加一致了,從而減少了混亂(但這就需要更多的輸入,這也許能解釋為什么不要求函數(shù)聲明使用extern的原因)。。。 什么是字節(jié)對(duì)齊,為什么要對(duì)齊?
現(xiàn)代計(jì)算機(jī)中內(nèi)存空間都是按照byte劃分的,從理論上講似乎對(duì)任何類型的變量的訪問(wèn)可以從任何地址開(kāi)始,但實(shí)際情況是在訪問(wèn)特定類型變量的時(shí)候經(jīng)常在特定的內(nèi)存地址訪問(wèn),這就需要各種類型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個(gè)接一個(gè)的排放,這就是對(duì)齊。
對(duì)齊的作用和原因:各個(gè)硬件平臺(tái)對(duì)存儲(chǔ)空間的處理上有很大的不同。一些平臺(tái)對(duì)某些特定類型的數(shù)據(jù)只能從某些特定地址開(kāi)始存取。比如有些架構(gòu)的CPU在訪問(wèn)一個(gè)沒(méi)有進(jìn)行對(duì)齊的變量的時(shí)候會(huì)發(fā)生錯(cuò)誤,那么在這種架構(gòu)下編程必須保證字節(jié)對(duì)齊.其他平臺(tái)可能沒(méi)有這種情況,但是最常見(jiàn)的是如果不按照適合其平臺(tái)要求對(duì)數(shù)據(jù)存放進(jìn)行對(duì)齊,會(huì)在存取效率上帶來(lái)?yè)p失。比如有些平臺(tái)每次讀都是從偶地址開(kāi)始,如果一個(gè)int型(假設(shè)為32位系統(tǒng))如果存放在偶地址開(kāi)始的地方,那么一個(gè)讀周期就可以讀出這32bit,而如果存放在奇地址開(kāi)始的地方,就需要2個(gè)讀周期,并對(duì)兩次讀出的結(jié)果的高低字節(jié)進(jìn)行拼湊才能得到該32bit數(shù)據(jù)。顯然在讀取效率上下降很多。
【柯達(dá)面試題詳解】相關(guān)文章:
華為硬件面試題08-22
經(jīng)典面試題回答思路03-17
求職英語(yǔ)面試題集錦08-22
銀行招聘英語(yǔ)面試題04-03
蘋(píng)果公司的面試題03-23
圖像處理的筆試面試題08-19
韋博英語(yǔ)面試題目06-27
英語(yǔ)教師面試題及答案03-20
蘋(píng)果公司英文面試題03-20