iOS面試題-第十四頁

62.談?wù)凮bject-C的內(nèi)存管理方式及過程?

答: 1).當(dāng)你使用new,alloc和copy方法創(chuàng)建一個對象時,該對象的保留計數(shù)器值為1.當(dāng)你不再使用該對象時,你要負責(zé)向該對象發(fā)送一條release或autorelease消息.這樣,該對象將在使用壽命結(jié)束時被銷毀.

2).當(dāng)你通過任何其他方法獲得一個對象時,則假設(shè)該對象的保留計數(shù)器值為1,而且已經(jīng)被設(shè)置為自動釋放,你不需要執(zhí)行任何操作來確保該對象被清理.如果你打算在一段時間內(nèi)擁有該對象,則需要保留它并確保在操作完成時釋放它.

3).如果你保留了某個對象,你需要(最終)釋放或自動釋放該對象.必須保持retain方法和release方法的使用次數(shù)相等.

63.Object-C有私有方法嗎?私有變量呢?

答: objective-c – 類里面的方法只有兩種, 靜態(tài)方法和實例方法. 這似乎就不是完整的面向?qū)ο罅?按照OO的原則就是一個對象只暴露有用的東西. 如果沒有了私有方法的話, 對于一些小范圍的代碼重用就不那么順手了. 在類里面聲名一個私有方法


@interface Controller : NSObject { NSString *something; }

+ (void)thisIsAStaticMethod;

– (void)thisIsAnInstanceMethod;

@end

@interface Controller (private) -

(void)thisIsAPrivateMethod;

@end

@private可以用來修飾私有變量

在Objective‐C中,所有實例變量默認都是私有的,所有實例方法默認都是公有的

64.Object-C有多繼承嗎?沒有的話用什么代替?cocoa 中所有的類都是NSObject 的子類

答: 多繼承在這里是用protocol 委托代理 來實現(xiàn)的

你不用去考慮繁瑣的多繼承 ,虛基類的概念.

ood的多態(tài)特性 在 obj-c 中通過委托來實現(xiàn).

65.內(nèi)存管理 Autorelease、retain、copy、assign的set方法和含義?

答: 1).你初始化(alloc/init)的對象,你需要釋放(release)它。例如:

NSMutableArray aArray = [[NSArray alloc] init]; 后,需要 [aArray release];

2).你retain或copy的,你需要釋放它。例如:

[aArray retain] 后,需要 [aArray release];

3).被傳遞(assign)的對象,你需要斟酌的retain和release。例如:

obj2 = [[obj1 someMethod] autorelease];

對象2接收對象1的一個自動釋放的值,或傳遞一個基本數(shù)據(jù)類型(NSInteger,NSString)時:你或希望將對象2進行retain,以防止它在被使用之前就被自動釋放掉。但是在retain后,一定要在適當(dāng)?shù)臅r候進行釋放。

關(guān)于索引計數(shù)(Reference Counting)的問題

retain值 = 索引計數(shù)(Reference Counting)

NSArray對象會retain(retain值加一)任何數(shù)組中的對象。當(dāng)NSArray被卸載(dealloc)的時候,所有數(shù)組中的對象會 被 執(zhí)行一次釋放(retain值減一)。不僅僅是NSArray,任何收集類(Collection Classes)都執(zhí)行類似操作。例如 NSDictionary,甚至UINavigationController。

Alloc/init建立的對象,索引計數(shù)為1。無需將其再次retain。

[NSArray array]和[NSDate date]等“方法”建立一個索引計數(shù)為1的對象,但是也是一個自動釋放對象。所以是本地臨時對象,那么無所謂了。如果是打算在全Class中使用的變量(iVar),則必須retain它。

缺省的類方法返回值都被執(zhí)行了“自動釋放”方法。(*如上中的NSArray)

在類中的卸載方法“dealloc”中,release所有未被平衡的NS對象。(*所有未被autorelease,而retain值為1的)

66. C和obj-c 如何混用

答: 1).obj-c的編譯器處理后綴為m的文件時,可以識別obj-c和c的代碼,處理mm文件可以識別obj-c,c,c++代碼,但cpp文件必須只能用c/c++代碼,而且cpp文件include的頭文件中,也不能出現(xiàn)obj-c的代碼,因為cpp只是cpp

2).在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是問題

3).在cpp中混用obj-c其實就是使用obj-c編寫的模塊是我們想要的。

如果模塊以類實現(xiàn),那么要按照cpp class的標準寫類的定義,頭文件中不能出現(xiàn)obj-c的東西,包括#import cocoa的。實現(xiàn)文件中,即類的實現(xiàn)代碼中可以使用obj-c的東西,可以import,只是后綴是mm。

如果模塊以函數(shù)實現(xiàn),那么頭文件要按c的格式聲明函數(shù),實現(xiàn)文件中,c++函數(shù)內(nèi)部可以用obj-c,但后綴還是mm或m。

總結(jié):只要cpp文件和cpp include的文件中不包含obj-c的東西就可以用了,cpp混用obj-c的關(guān)鍵是使用接口,而不能直接使用 實現(xiàn)代 碼,實際上cpp混用的是obj-c編譯后的o文件,這個東西其實是無差別的,所以可以用。obj-c的編譯器支持cpp

67. Objective-C堆和棧的區(qū)別?

答: 管理方式:對于棧來講,是由編譯器自動管理,無需我們手工控制;對于堆來說,釋放工作由程序員控制,容易產(chǎn)生memory leak。

申請大小:

棧:在Windows下,棧是向低地址擴展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個編譯時就確定的常數(shù)),如果申請的空間超過棧的剩余空間時,將提示overflow。因 此,能從棧獲得的空間較小。

堆:堆是向高地址擴展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲的空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計算機系統(tǒng)中有效的虛擬內(nèi)存。由此可見,堆獲得的空間比較靈活,也比較大。

碎片問題:對于堆來講,頻繁的new/delete勢必會造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對于棧來講,則不會存在這個問題,因為棧是先進后出的隊列,他們是如此的一一對應(yīng),以至于永遠都不可能有一個內(nèi)存塊從棧中間彈出

分配方式:堆都是動態(tài)分配的,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動態(tài)分配由alloca函數(shù)進行分配,但是棧的動態(tài)分配和堆是不同的,他的動態(tài)分配是由編譯器進行釋放,無需我們手工實現(xiàn)。

分配效率:棧是機器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的,它的機制是很復(fù)雜的。

68. ViewController的didReceiveMemoryWarning怎么被調(diào)用:

答:[supper didReceiveMemoryWarning];

69.什么時候用delegate,什么時候用Notification?

答: delegate針對one-to-one關(guān)系,用于sender接受到reciever的某個功能反饋值。

notification針對one-to-one/many/none,reciver,用于通知多個object某個事件。

70.用預(yù)處理指令#define聲明一個常數(shù),用以表明1年中有多少秒(忽略閏年問題)

答:

#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

我在這想看到幾件事情:

#define 語法的基本知識(例如:不能以分號結(jié)束,括號的使用,等等)

懂得預(yù)處理器將為你計算常數(shù)表達式的值,因此,直接寫出你是如何計算一年中有多少秒而不是計算出實際的值,是更清晰而沒有代價的。

意識到這個表達式將使一個16位機的整型數(shù)溢出-因此要用到長整型符號L,告訴編譯器這個常數(shù)是的長整型數(shù)。

如果你在你的表達式中用到UL(表示無符號長整型),那么你有了一個好的起點。記住,第一印象很重要。

71.寫一個”標準"宏MIN ,這個宏輸入兩個參數(shù)并返回較小的一個。

答:


#define MIN(A,B) ((A) <= (B) ? (A) : (B))

這個測試是為下面的目的而設(shè)的:

標識#define在宏中應(yīng)用的基本知識。這是很重要的,因為直到嵌入(inline)操作符變?yōu)闃藴蔆的一部分,宏是方便產(chǎn)生嵌入代碼的唯一方

法,

對于嵌入式系統(tǒng)來說,為了能達到要求的性能,嵌入代碼經(jīng)常是必須的方法。

三重條件操作符的知識。這個操作符存在C語言中的原因是它使得編譯器能產(chǎn)生比 if-then-else 更優(yōu)化的代碼,了解這個用法是很重要的。

懂得在宏中小心地把參數(shù)用括號括起來

我也用這個問題開始討論宏的副作用,例如:當(dāng)你寫下面的代碼時會發(fā)生什么事?


least = MIN(*p++, b);

結(jié)果是:


((*p++) <= (b) ? (*p++) : (*p++))

這個表達式會產(chǎn)生副作用,指針p會作三次++自增操作。

72.關(guān)鍵字const有什么含意?修飾類呢?static的作用,用于類呢?還有extern c的作用

答:

const 意味著"只讀",下面的聲明都是什么意思?

const int a;

int const a;

const int *a;

int * const a;

int const * a const;

前兩個的作用是一樣,a是一個常整型數(shù)。

第三個意味著a是一個指向常整型數(shù)的指針(也就是,整型數(shù)是不可修改的,但指針可以)。

第四個意思a是一個指向整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是可以修改的,但指針是不可修改的)。

最后一個意味著a是一個指向常整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是不可修改的,同時指針也是不可修改的)。

結(jié)論:

關(guān)鍵字const的作用是為給讀你代碼的人傳達非常有用的信息,實際上,聲明一個參數(shù)為常量是為了告訴了用戶這個參數(shù)的應(yīng)用目的。

如果你曾花很多時間清理其它人留下的垃圾,你就會很快學(xué)會感謝這點多余的信息。(當(dāng)然,懂得用const的程序員很少會留下的垃圾讓別人來清理的)? 通過給優(yōu)化器一些附加的信息,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。合理地使用關(guān)鍵字const可以使編譯器很自然地保護那些不希望被改變的參數(shù),防止其被無意的代碼修改。簡而言之,這樣可以減少bug的出現(xiàn)。

1).欲阻止一個變量被改變,可以使用 const 關(guān)鍵字。在定義該 const 變量時,通常需要對它進行初

始化,因為以后就沒有機會再去改變它了;

2).對指針來說,可以指定指針本身為 const,也可以指定指針所指的數(shù)據(jù)為 const,或二者同時指

定為 const;

3).在一個函數(shù)聲明中,const 可以修飾形參,表明它是一個輸入?yún)?shù),在函數(shù)內(nèi)部不能改變其值;

4).對于類的成員函數(shù),若指定其為 const 類型,則表明其是一個常函數(shù),不能修改類的成員變量;

5).對于類的成員函數(shù),有時候必須指定其返回值為 const 類型,以使得其返回值不為“左值”。

73. 關(guān)鍵字volatile有什么含意?并給出三個不同的例子。

答:一個定義為 volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設(shè)這個變量的值了。精確地說就是,優(yōu)化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器里的備份。

下面是volatile變量的幾個例子:

并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)

一個中斷服務(wù)子程序中會訪問到的非自動變量(Non-automatic variables)

多線程應(yīng)用中被幾個任務(wù)共享的變量

74. 一個參數(shù)既可以是const還可以是volatile嗎? 一個指針可以是volatile 嗎?解釋為什么。

答:1).是的。一個例子是只讀的狀態(tài)寄存器。它是volatile因為它可能被意想不到地改變。它是const因為程序不應(yīng)該試圖去修改它。

2).是的。盡管這并不很常見。一個例子是當(dāng)一個中服務(wù)子程序修該一個指向一個buffer的指針時。

75 . static 關(guān)鍵字的作用:

答:

1).函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體,不同于 auto 變量,該變量的內(nèi)存只被分配一次,

因此其值在下次調(diào)用時仍維持上次的值;

2).在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問;

3).在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個函數(shù)的使用范圍被限制在聲明

它的模塊內(nèi);

4).在類中的 static 成員變量屬于整個類所擁有,對類的所有對象只有一份拷貝;

5).在類中的 static 成員函數(shù)屬于整個類所擁有,這個函數(shù)不接收 this 指針,因而只能訪問類的static 成員變量。

76. 線程與進程的區(qū)別和聯(lián)系?

答:

1). 進程和線程都是由操作系統(tǒng)所體會的程序運行的基本單元,系統(tǒng)利用該基本單元實現(xiàn)系統(tǒng)對應(yīng)用的并發(fā)性

2). 進程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。

3). 進程有獨立的地址空間,一個進程崩潰后,在保護模式下不會對其它進程產(chǎn)生影響,而線程只是一個進程中的不同執(zhí)行路徑。

4.)線程有自己的堆棧和局部變量,但線程之間沒有單獨的地址空間,一個線程死掉就等于整個進程死掉。所以多進程的程序要比多線程的程序健壯,但在進程切換時,耗費資源較大,效率要差一些。

5). 但對于一些要求同時進行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進程。

77. 列舉幾種進程的同步機制,并比較其優(yōu)缺點。

答: 原子操作? 信號量機制? ? 自旋鎖? ? 管程,會合,分布式系統(tǒng)

78. 進程之間通信的途徑

答:共享存儲系統(tǒng)消息傳遞系統(tǒng)管道:以文件系統(tǒng)為基礎(chǔ)

79. 進程死鎖的原因

答:資源競爭及進程推進順序非法

80. 死鎖的4個必要條件

答:互斥、請求保持、不可剝奪、環(huán)路

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn):http://www.cocoachina.com/programmer/20151019/13746.htm...
    Style_偉閱讀 1,464評論 0 3
  • 之前看了很多面試題,感覺要不是不夠就是過于冗余,于是我將網(wǎng)上的一些面試題進行了刪減和重排,現(xiàn)在分享給大家。(題...
    Job_Yang閱讀 12,203評論 12 143
  • 注:此文章來源:Job_Yang 的簡書 1. Object-c的類可以多重繼承么?可以實現(xiàn)多個接口么?Categ...
    廣益散人閱讀 1,423評論 0 13
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,619評論 30 472
  • 姓名:張弛 公司:沈陽防銹包裝材料有限責(zé)任公司 【六項精進打卡第108天】 【知~學(xué)習(xí)】 閱讀《六項精進》大綱0遍...
    Leo_zhang閱讀 188評論 0 0

友情鏈接更多精彩內(nèi)容