(筆試題)應(yīng)聘iphone開發(fā)工程師,iphone和Objective-C的筆試題? 請各位iphone開發(fā)工程師,積極參與解答筆試題,幫助初學(xué)者通過面試難關(guān)。在此提前表示感謝! 請各位iphone開發(fā)工程師不要太保守,拿出您所知道的面試題與大家一起分享?;ハ鄮椭?!謝謝! 以下是我找來的面試真題,請各位iphone開發(fā)工程師,多多指點(diǎn)指點(diǎn)!大家一起分享,討論。看答案是否正確!互相幫助,希望對(duì)各位有所幫助! 1.main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); printf("%d,%d",*(a+1),*(ptr-1)); } 答:2,5 *(a+1)就是a[1],*(ptr-1)就是a[4],執(zhí)行結(jié)果是2,5 &a+1不是首地址+1,系統(tǒng)會(huì)認(rèn)為加一個(gè)a數(shù)組的偏移,是偏移了一個(gè)數(shù)組的大?。ū纠?個(gè)int) int *ptr=(int *)(&a+1); 則ptr實(shí)際是&(a[5]),也就是a+5 原因如下: &a是數(shù)組指針,其類型為 int (*)[5]; 而指針加1要根據(jù)指針類型加上一定的值,不同類型的指針+1之后增加的大小不同。 a是長度為5的int數(shù)組指針,所以要加 5*sizeof(int) 所以ptr實(shí)際是a[5] 但是prt與(&a+1)類型是不一樣的(這點(diǎn)很重要) 所以prt-1只會(huì)減去sizeof(int*) a,&a的地址是一樣的,但意思不一樣 a是數(shù)組首地址,也就是a[0]的地址,&a是對(duì)象(數(shù)組)首地址, a+1是數(shù)組下一元素的地址,即a[1],&a+1是下一個(gè)對(duì)象的地址,即a[5]. 2.以下為Windows NT下的32位C++程序,請計(jì)算sizeof的值 void Func ( char str[100] ) { sizeof( str ) = ? } void *p = malloc( 100 ); sizeof ( p ) = ? 這題很常見了,Func ( char str[100] )函數(shù)中數(shù)組名作為函數(shù)形參時(shí),在函數(shù)體內(nèi),數(shù)組名失去了本身的內(nèi)涵,僅僅只是一個(gè)指針;在失去其內(nèi)涵的同時(shí),它還失去了其常量特性,可以作自增、自減等操作,可以被修改。Windows NT 32位平臺(tái)下,指針的長度(占用內(nèi)存的大?。?字節(jié),故sizeof( str ) 、sizeof ( p ) 都為4。 3.還是考指針,不過我對(duì)cocoa的代碼還是不太熟悉 大概是這樣的 - (void)*getNSString(const NSString * inputString) { inputString = @"This is a main test\n"; return ; } -main(void) { NSString *a=@"Main"; NSString *aString = [NSString stringWithString:@"%@",getNSString(a)]; NSLog(@"%@\n", aString); } 最后問輸出的字符串:NULL,output在函數(shù)返回后,內(nèi)存已經(jīng)被釋放。 4.用預(yù)處理指令#define聲明一個(gè)常數(shù),用以表明1年中有多少秒(忽略閏年問題) #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL 我在這想看到幾件事情: ; #define 語法的基本知識(shí)(例如:不能以分號(hào)結(jié)束,括號(hào)的使用,等等) ; 懂得預(yù)處理器將為你計(jì)算常數(shù)表達(dá)式的值,因此,直接寫出你是如何計(jì)算一年中有多少秒而不是計(jì)算出實(shí)際的值,是更清晰而沒有代價(jià)的。 ; 意識(shí)到這個(gè)表達(dá)式將使一個(gè)16位機(jī)的整型數(shù)溢出-因此要用到長整型符號(hào)L,告訴編譯器這個(gè)常數(shù)是的長整型數(shù)。 ; 如果你在你的表達(dá)式中用到UL(表示無符號(hào)長整型),那么你有了一個(gè)好的起點(diǎn)。記住,第一印象很重要。 寫一個(gè)"標(biāo)準(zhǔn)"宏MIN ,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。 #define MIN(A,B) ((A) <= (B) ? (A) : (B)) 這個(gè)測試是為下面的目的而設(shè)的: ; 標(biāo)識(shí)#define在宏中應(yīng)用的基本知識(shí)。這是很重要的,因?yàn)橹钡角度?inline)操作符變?yōu)闃?biāo)準(zhǔn)C的一部分,宏是方便產(chǎn)生嵌入代碼的唯一方 法,對(duì)于嵌入式系統(tǒng)來說,為了能達(dá)到要求的性能,嵌入代碼經(jīng)常是必須的方法。 ; 三重條件操作符的知識(shí)。這個(gè)操作符存在C語言中的原因是它使得編譯器能產(chǎn)生比 if-then-else 更優(yōu)化的代碼,了解這個(gè)用法是很重要的。 ; 懂得在宏中小心地把參數(shù)用括號(hào)括起來 ; 我也用這個(gè)問題開始討論宏的副作用,例如:當(dāng)你寫下面的代碼時(shí)會(huì)發(fā)生什么事? least = MIN(*p++, b); 結(jié)果是: ((*p++) <= (b) ? (*p++) : (*p++)) 這個(gè)表達(dá)式會(huì)產(chǎn)生副作用,指針p會(huì)作三次++自增操作。 5.寫一個(gè)委托的interface @protocol MyDelegate; @interface MyClass: NSObject { id <MyDelegate> delegate; } // 委托方法 @protocol MyDelegate - (void)didJobs:(NSArray *)args; @end 6.寫一個(gè)NSString類的實(shí)現(xiàn) + (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding; + (id) stringWithCString: (const char*)nullTerminatedCString encoding: (NSStringEncoding)encoding { NSString *obj; obj = [self allocWithZone: NSDefaultMallocZone()]; obj = [obj initWithCString: nullTerminatedCString encoding: encoding]; return AUTORELEASE(obj); } 7.obj-c有多重繼承么?不是的話有什么替代方法? cocoa 中所有的類都是NSObject 的子類 多繼承在這里是用protocol 委托代理 來實(shí)現(xiàn)的 你不用去考慮繁瑣的多繼承 ,虛基類的概念. ood的多態(tài)特性 在 obj-c 中通過委托來實(shí)現(xiàn). 要注意的是Objective-c只支持單繼承,如果要實(shí)現(xiàn)多繼承的話,可以通過類別和協(xié)議的方式來實(shí)現(xiàn)。 8.obj-c有私有方法么?私有變量呢 objective-c - 類里面的方法只有兩種, 靜態(tài)方法和實(shí)例方法. 這似乎就不是完整的面向?qū)ο罅?按照OO的原則就是一個(gè)對(duì)象只暴露有用的東西. 如果沒有了私有方法的話, 對(duì)于一些小范圍的代碼重用就不那么順手了. 在類里面聲名一個(gè)私有方法 @interface Controller : NSObject { NSString *something; } + (void)thisIsAStaticMethod; - (void)thisIsAnInstanceMethod; @end @interface Controller (private) - (void)thisIsAPrivateMethod; @end @private可以用來修飾私有變量 在Objective‐C中,所有實(shí)例變量默認(rèn)都是私有的,所有實(shí)例方法默認(rèn)都是公有的 9.關(guān)鍵字const有什么含意?修飾類呢?static的作用,用于類呢?還有extern c的作用 const意味著"只讀",下面的聲明都是什么意思? const int a; int const a; const int *a; int * const a; int const * a const; 前兩個(gè)的作用是一樣,a是一個(gè)常整型數(shù)。第三個(gè)意味著a是一個(gè)指向常整型數(shù)的指針(也就是,整型數(shù)是不可修改的,但指針可以)。第四個(gè)意思a是一個(gè)指向整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是可以修改的,但指針是不可修改的)。最后一個(gè)意味著a是一個(gè)指向常整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是不可修改的,同時(shí)指針也是不可修改的)。 結(jié)論: ; 關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息,實(shí)際上,聲明一個(gè)參數(shù)為常量是為了告訴了用戶這個(gè)參數(shù)的應(yīng)用目的。如果 你曾花很多時(shí)間清理其它人留下的垃圾,你就會(huì)很快學(xué)會(huì)感謝這點(diǎn)多余的信息。(當(dāng)然,懂得用const的程序員很少會(huì)留下的垃圾讓別人來清 理的。) ; 通過給優(yōu)化器一些附加的信息,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。 ; 合理地使用關(guān)鍵字const可以使編譯器很自然地保護(hù)那些不希望被改變的參數(shù),防止其被無意的代碼修改。簡而言之,這樣可以減少bug的出現(xiàn)。 (1)欲阻止一個(gè)變量被改變,可以使用 const 關(guān)鍵字。在定義該 const 變量時(shí),通常需要對(duì)它進(jìn)行初 始化,因?yàn)橐院缶蜎]有機(jī)會(huì)再去改變它了; (2)對(duì)指針來說,可以指定指針本身為 const,也可以指定指針?biāo)傅臄?shù)據(jù)為 const,或二者同時(shí)指 定為 const; (3)在一個(gè)函數(shù)聲明中,const 可以修飾形參,表明它是一個(gè)輸入?yún)?shù),在函數(shù)內(nèi)部不能改變其值; (4)對(duì)于類的成員函數(shù),若指定其為 const 類型,則表明其是一個(gè)常函數(shù),不能修改類的成員變量; (5)對(duì)于類的成員函數(shù),有時(shí)候必須指定其返回值為 const 類型,以使得其返回值不為“左值”。 關(guān)鍵字volatile有什么含意?并給出三個(gè)不同的例子。 一個(gè)定義為volatile的變量是說這變量可能會(huì)被意想不到地改變,這樣,編譯器就不會(huì)去假設(shè)這個(gè)變量的值了。精確地說就是,優(yōu)化器在用到 這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子: ; 并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器) ; 一個(gè)中斷服務(wù)子程序中會(huì)訪問到的非自動(dòng)變量(Non-automatic variables) ; 多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量 ; 一個(gè)參數(shù)既可以是const還可以是volatile嗎?解釋為什么。 ; 一個(gè)指針可以是volatile 嗎?解釋為什么。 下面是答案: ; 是的。一個(gè)例子是只讀的狀態(tài)寄存器。它是volatile因?yàn)樗赡鼙灰庀氩坏降馗淖?。它是const因?yàn)槌绦虿粦?yīng)該試圖去修改它。 ; 是的。盡管這并不很常見。一個(gè)例子是當(dāng)一個(gè)中服務(wù)子程序修該一個(gè)指向一個(gè)buffer的指針時(shí)。 static 關(guān)鍵字的作用: (1)函數(shù)體內(nèi) static 變量的作用范圍為該函數(shù)體,不同于 auto 變量,該變量的內(nèi)存只被分配一次, 因此其值在下次調(diào)用時(shí)仍維持上次的值; (2)在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問; (3)在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用,這個(gè)函數(shù)的使用范圍被限制在聲明 它的模塊內(nèi); (4)在類中的 static 成員變量屬于整個(gè)類所擁有,對(duì)類的所有對(duì)象只有一份拷貝; (5)在類中的 static 成員函數(shù)屬于整個(gè)類所擁有,這個(gè)函數(shù)不接收 this 指針,因而只能訪問類的static 成員變量。 extern "C" 的作用 (1)被 extern "C"限定的函數(shù)或變量是 extern 類型的; extern 是 C/C++語言中表明函數(shù)和全局變量作用范圍(可見性)的關(guān)鍵字,該關(guān)鍵字告訴編譯器, 其聲明的函數(shù)和變量可以在本模塊或其它模塊中使用。 (2)被 extern "C"修飾的變量和函數(shù)是按照 C 語言方式編譯和連接的; extern "C"的慣用法 (1)在 C++中引用 C 語言中的函數(shù)和變量,在包含 C 語言頭文件(假設(shè)為 cExample.h)時(shí),需進(jìn) 行下列處理: extern "C" { #include "cExample.h" } 而在 C 語言的頭文件中,對(duì)其外部函數(shù)只能指定為 extern 類型,C 語言中不支持 extern "C"聲明, 在.c 文件中包含了 extern "C"時(shí)會(huì)出現(xiàn)編譯語法錯(cuò)誤。 (2)在 C 中引用 C++語言中的函數(shù)和變量時(shí),C++的頭文件需添加 extern "C",但是在 C 語言中不 能直接引用聲明了 extern "C"的該頭文件,應(yīng)該僅將 C 文件中將 C++中定義的 extern "C"函數(shù)聲明為 extern 類型。 10.為什么標(biāo)準(zhǔn)頭文件都有類似以下的結(jié)構(gòu)? #ifndef __INCvxWorksh #define __INCvxWorksh #ifdef __cplusplus extern "C" { #endif /*...*/ #ifdef __cplusplus } #endif #endif /* __INCvxWorksh */ 顯然,頭文件中的編譯宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用 是防止該頭文件被重復(fù)引用。 11.#import跟#include的區(qū)別,@class呢? @class一般用于頭文件中需要聲明該類的某個(gè)實(shí)例變量的時(shí)候用到,在m文件中還是需要使用#import 而#import比起#include的好處就是不會(huì)引起交叉編譯 12.MVC模式的理解 MVC設(shè)計(jì)模式考慮三種對(duì)象:模型對(duì)象、視圖對(duì)象、和控制器對(duì)象。模型對(duì)象代表特別的知識(shí)和專業(yè)技能,它們負(fù)責(zé)保有應(yīng)用程序的數(shù)據(jù)和定義操作數(shù)據(jù)的邏輯。視圖對(duì)象知道如何顯示應(yīng)用程序的模型數(shù)據(jù),而且可能允許用戶對(duì)其進(jìn)行編輯??刂破鲗?duì)象是應(yīng)用程序的視圖對(duì)象和模型對(duì)象之間的協(xié)調(diào)者。 13.線程與進(jìn)程的區(qū)別和聯(lián)系? 進(jìn)程和線程都是由操作系統(tǒng)所體會(huì)的程序運(yùn)行的基本單元,系統(tǒng)利用該基本單元實(shí)現(xiàn)系統(tǒng)對(duì)應(yīng)用的并發(fā)性。 程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí),耗費(fèi)資源較大,效率要差一些。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程。 14.列舉幾種進(jìn)程的同步機(jī)制,并比較其優(yōu)缺點(diǎn)。 答案: 原子操作 信號(hào)量機(jī)制 自旋鎖 管程,會(huì)合,分布式系統(tǒng) 進(jìn)程之間通信的途徑 答案:共享存儲(chǔ)系統(tǒng)消息傳遞系統(tǒng)管道:以文件系統(tǒng)為基礎(chǔ) 進(jìn)程死鎖的原因 答案:資源競爭及進(jìn)程推進(jìn)順序非法 死鎖的4個(gè)必要條件 答案:互斥、請求保持、不可剝奪、環(huán)路 死鎖的處理 答案:鴕鳥策略、預(yù)防策略、避免策略、檢測與解除死鎖 15.堆和棧的區(qū)別 管理方式:對(duì)于棧來講,是由編譯器自動(dòng)管理,無需我們手工控制;對(duì)于堆來說,釋放工作由程序員控制,容易產(chǎn)生memory leak。 申請大?。? 棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個(gè)編譯時(shí)就確定的常數(shù)),如果申請的空間超過棧的剩余空間時(shí),將提示overflow。因此,能從棧獲得的空間較小。 堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲(chǔ)的空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見,堆獲得的空間比較靈活,也比較大。 碎片問題:對(duì)于堆來講,頻繁的new/delete勢必會(huì)造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對(duì)于棧來講,則不會(huì)存在這個(gè)問題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列,他們是如此的一一對(duì)應(yīng),以至于永遠(yuǎn)都不可能有一個(gè)內(nèi)存塊從棧中間彈出 分配方式:堆都是動(dòng)態(tài)分配的,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動(dòng)態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的,他的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放,無需我們手工實(shí)現(xiàn)。 分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會(huì)在底層對(duì)棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的,它的機(jī)制是很復(fù)雜的。 16.什么是鍵-值,鍵路徑是什么 模型的性質(zhì)是通過一個(gè)簡單的鍵(通常是個(gè)字符串)來指定的。視圖和控制器通過鍵來查找相應(yīng)的屬性值。在一個(gè)給定的實(shí)體中,同一個(gè)屬性的所有值具有相同的數(shù)據(jù)類型。鍵-值編碼技術(shù)用于進(jìn)行這樣的查找—它是一種間接訪問對(duì)象屬性的機(jī)制。 鍵路徑是一個(gè)由用點(diǎn)作分隔符的鍵組成的字符串,用于指定一個(gè)連接在一起的對(duì)象性質(zhì)序列。第一個(gè)鍵的 性質(zhì)是由先前的性質(zhì)決定的,接下來每個(gè)鍵的值也是相對(duì)于其前面的性質(zhì)。鍵路徑使您可以以獨(dú)立于模型 實(shí)現(xiàn)的方式指定相關(guān)對(duì)象的性質(zhì)。通過鍵路徑,您可以指定對(duì)象圖中的一個(gè)任意深度的路徑,使其指向相 關(guān)對(duì)象的特定屬性。 For example, the key path address.streetwould get the value of the address property from the receiving object, and then determine the street property relative to the address object. 17.c和obj-c如何混用 1)obj-c的編譯器處理后綴為m的文件時(shí),可以識(shí)別obj-c和c的代碼,處理mm文件可以識(shí)別obj-c,c,c++代碼,但cpp文件必須只能用c/c++代碼,而且cpp文件include的頭文件中,也不能出現(xiàn)obj-c的代碼,因?yàn)閏pp只是cpp 2) 在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是問題 3)在cpp中混用obj-c其實(shí)就是使用obj-c編寫的模塊是我們想要的。 如果模塊以類實(shí)現(xiàn),那么要按照cpp class的標(biāo)準(zhǔn)寫類的定義,頭文件中不能出現(xiàn)obj-c的東西,包括#import cocoa的。實(shí)現(xiàn)文件中,即類的實(shí)現(xiàn)代碼中可以使用obj-c的東西,可以import,只是后綴是mm。 如果模塊以函數(shù)實(shí)現(xiàn),那么頭文件要按c的格式聲明函數(shù),實(shí)現(xiàn)文件中,c++函數(shù)內(nèi)部可以用obj-c,但后綴還是mm或m。 總結(jié):只要cpp文件和cpp include的文件中不包含obj-c的東西就可以用了,cpp混用obj-c的關(guān)鍵是使用接口,而不能直接使用實(shí)現(xiàn)代碼,實(shí)際上cpp混用的是obj-c編譯后的o文件,這個(gè)東西其實(shí)是無差別的,所以可以用。obj-c的編譯器支持cpp. 18.目標(biāo)-動(dòng)作機(jī)制 目標(biāo)是動(dòng)作消息的接收者。一個(gè)控件,或者更為常見的是它的單元,以插座變量(參見"插座變量"部分) 的形式保有其動(dòng)作消息的目標(biāo)。 動(dòng)作是控件發(fā)送給目標(biāo)的消息,或者從目標(biāo)的角度看,它是目標(biāo)為了響應(yīng)動(dòng)作而實(shí)現(xiàn)的方法。 程序需要某些機(jī)制來進(jìn)行事件和指令的翻譯。這個(gè)機(jī)制就是目標(biāo)-動(dòng)作機(jī)制。 19.cocoa touch框架 iPhone OS 應(yīng)用程序的基礎(chǔ) Cocoa Touch 框架重用了許多 Mac 系統(tǒng)的成熟模式,但是它更多地專注于觸摸的接口和優(yōu)化。UIKit 為您提供了在 iPhone OS 上實(shí)現(xiàn)圖形,事件驅(qū)動(dòng)程序的基本工具,其建立在和 Mac OS X 中一樣的 Foundation 框架上,包括文件處理,網(wǎng)絡(luò),字符串操作等。 Cocoa Touch 具有和 iPhone 用戶接口一致的特殊設(shè)計(jì)。有了 UIKit,您可以使用 iPhone OS 上的獨(dú)特的圖形接口控件,按鈕,以及全屏視圖的功能,您還可以使用加速儀和多點(diǎn)觸摸手勢來控制您的應(yīng)用。 各色俱全的框架 除了 UIKit 外,Cocoa Touch 包含了創(chuàng)建世界一流 iPhone 應(yīng)用程序需要的所有框架,從三維圖形,到專業(yè)音效,甚至提供設(shè)備訪問 API 以控制攝像頭,或通過 GPS 獲知當(dāng)前位置。Cocoa Touch 既包含只需要幾行代碼就可以完成全部任務(wù)的強(qiáng)大的 Objective-C 框架,也在需要時(shí)提供基礎(chǔ)的 C 語言 API 來直接訪問系統(tǒng)。這些框架包括: Core Animation 通過 Core Animation,您就可以通過一個(gè)基于組合獨(dú)立圖層的簡單的編程模型來創(chuàng)建豐富的用戶體驗(yàn)。 Core Audio Core Audio 是播放,處理和錄制音頻的專業(yè)技術(shù),能夠輕松為您的應(yīng)用程序添加強(qiáng)大的音頻功能。 Core Data 提供了一個(gè)面向?qū)ο蟮臄?shù)據(jù)管理解決方案,它易于使用和理解,甚至可處理任何應(yīng)用或大或小的數(shù)據(jù)模型。 功能列表:框架分類 下面是 Cocoa Touch 中一小部分可用的框架:
Core Audio OpenAL Media Library AV Foundation
Core Data SQLite
Core Animation OpenGL ES Quartz 2D
Bonjour WebKit BSD Sockets
Address Book Core Location Map Kit Store Kit 20.objc的內(nèi)存管理 如果您通過分配和初始化(比如[[MyClass alloc] init])的方式來創(chuàng)建對(duì)象,您就擁 有這個(gè)對(duì)象,需要負(fù)責(zé)該對(duì)象的釋放。這個(gè)規(guī)則在使用NSObject的便利方法new 時(shí)也同樣適用。 如果您拷貝一個(gè)對(duì)象,您也擁有拷貝得到的對(duì)象,需要負(fù)責(zé)該對(duì)象的釋放。 如果您保持一個(gè)對(duì)象,您就部分擁有這個(gè)對(duì)象,需要在不再使用時(shí)釋放該對(duì)象。 反過來, 如果您從其它對(duì)象那里接收到一個(gè)對(duì)象,則您不擁有該對(duì)象,也不應(yīng)該釋放它(這個(gè)規(guī)則有少數(shù) 的例外,在參考文檔中有顯式的說明)。 21.自動(dòng)釋放池是什么,如何工作 當(dāng)您向一個(gè)對(duì)象發(fā)送一個(gè)autorelease消息時(shí),Cocoa就會(huì)將該對(duì)象的一個(gè)引用放入到最新的自動(dòng)釋放池。它仍然是個(gè)正當(dāng)?shù)膶?duì)象,因此自動(dòng)釋放池定義的作用域內(nèi)的其它對(duì)象可以向它發(fā)送消息。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時(shí),自動(dòng)釋放池就會(huì)被釋放,池中的所有對(duì)象也就被釋放。 1. ojc-c 是通過一種"referring counting"(引用計(jì)數(shù))的方式來管理內(nèi)存的, 對(duì)象在開始分配內(nèi)存(alloc)的時(shí)候引用計(jì)數(shù)為一,以后每當(dāng)碰到有copy,retain的時(shí)候引用計(jì)數(shù)都會(huì)加一, 每當(dāng)碰到release和autorelease的時(shí)候引用計(jì)數(shù)就會(huì)減一,如果此對(duì)象的計(jì)數(shù)變?yōu)榱?, 就會(huì)被系統(tǒng)銷毀. 2. NSAutoreleasePool 就是用來做引用計(jì)數(shù)的管理工作的,這個(gè)東西一般不用你管的. 3. autorelease和release沒什么區(qū)別,只是引用計(jì)數(shù)減一的時(shí)機(jī)不同而已,autorelease會(huì)在對(duì)象的使用真正結(jié)束的時(shí)候才做引用計(jì)數(shù)減一. 22.類工廠方法是什么 類工廠方法的實(shí)現(xiàn)是為了向客戶提供方便,它們將分配和初始化合在一個(gè)步驟中,返回被創(chuàng)建的對(duì)象,并 進(jìn)行自動(dòng)釋放處理。這些方法的形式是+ (type)className...(其中 className不包括任何前綴)。 工廠方法可能不僅僅為了方便使用。它們不但可以將分配和初始化合在一起,還可以為初始化過程提供對(duì) 象的分配信息。 類工廠方法的另一個(gè)目的是使類(比如NSWorkspace)提供單件實(shí)例。雖然init...方法可以確認(rèn)一 個(gè)類在每次程序運(yùn)行過程只存在一個(gè)實(shí)例,但它需要首先分配一個(gè)“生的”實(shí)例,然后還必須釋放該實(shí)例。 工廠方法則可以避免為可能沒有用的對(duì)象盲目分配內(nèi)存。 23.單件實(shí)例是什么 Foundation 和 Application Kit 框架中的一些類只允許創(chuàng)建單件對(duì)象,即這些類在當(dāng)前進(jìn)程中的唯一實(shí)例。舉例來說,NSFileManager 和NSWorkspace 類在使用時(shí)都是基于進(jìn)程進(jìn)行單件對(duì)象的實(shí)例化。當(dāng)向這些類請求實(shí)例的時(shí)候,它們會(huì)向您傳遞單一實(shí)例的一個(gè)引用,如果該實(shí)例還不存在,則首先進(jìn)行實(shí)例的分配和初始化。單件對(duì)象充當(dāng)控制中心的角色,負(fù)責(zé)指引或協(xié)調(diào)類的各種服務(wù)。如果類在概念上只有一個(gè)實(shí)例(比如 NSWorkspace),就應(yīng)該產(chǎn)生一個(gè)單件實(shí)例,而不是多個(gè)實(shí)例;如果將來某一天可能有多個(gè)實(shí)例,您可 以使用單件實(shí)例機(jī)制,而不是工廠方法或函數(shù)。 24.動(dòng)態(tài)綁定 —在運(yùn)行時(shí)確定要調(diào)用的方法 動(dòng)態(tài)綁定將調(diào)用方法的確定也推遲到運(yùn)行時(shí)。在編譯時(shí),方法的調(diào)用并不和代碼綁定在一起,只有在消實(shí)發(fā)送出來之后,才確定被調(diào)用的代碼。通過動(dòng)態(tài)類型和動(dòng)態(tài)綁定技術(shù),您的代碼每次執(zhí)行都可以得到不同的結(jié)果。運(yùn)行時(shí)因子負(fù)責(zé)確定消息的接收者和被調(diào)用的方法。運(yùn)行時(shí)的消息分發(fā)機(jī)制為動(dòng)態(tài)綁定提供支持。當(dāng)您向一個(gè)動(dòng)態(tài)類型確定了的對(duì)象發(fā)送消息時(shí),運(yùn)行環(huán)境系統(tǒng)會(huì)通過接收者的isa指針定位對(duì)象的類,并以此為起點(diǎn)確定被調(diào)用的方法,方法和消息是動(dòng)態(tài)綁定的。而且,您不必在Objective-C 代碼中做任何工作,就可以自動(dòng)獲取動(dòng)態(tài)綁定的好處。您在每次發(fā)送消息時(shí), 特別是當(dāng)消息的接收者是動(dòng)態(tài)類型已經(jīng)確定的對(duì)象時(shí),動(dòng)態(tài)綁定就會(huì)例行而透明地發(fā)生。 25.obj-c的優(yōu)缺點(diǎn) objc優(yōu)點(diǎn): 1) Cateogies 2) Posing 3) 動(dòng)態(tài)識(shí)別 4) 指標(biāo)計(jì)算 5)彈性訊息傳遞 6) 不是一個(gè)過度復(fù)雜的 C 衍生語言 7) Objective-C 與 C++ 可混合編程 缺點(diǎn): 1) 不支援命名空間 2) 不支持運(yùn)算符重載 3) 不支持多重繼承 4) 使用動(dòng)態(tài)運(yùn)行時(shí)類型,所有的方法都是函數(shù)調(diào)用,所以很多編譯時(shí)優(yōu)化方法都用不到。(如內(nèi)聯(lián)函數(shù)等),性能低劣。 26.sprintf,strcpy,memcpy使用上有什么要注意的地方 strcpy是一個(gè)字符串拷貝的函數(shù),它的函數(shù)原型為strcpy(char *dst, const char *src); 將src開始的一段字符串拷貝到dst開始的內(nèi)存中去,結(jié)束的標(biāo)志符號(hào)為'\0',由于拷貝的長度不是由我們自己控制的,所以這個(gè)字符串拷貝很容易出錯(cuò)。具備字符串拷貝功能的函數(shù)有memcpy,這是一個(gè)內(nèi)存拷貝函數(shù),它的函數(shù)原型為memcpy(char *dst, const char* src, unsigned int len); 將長度為len的一段內(nèi)存,從src拷貝到dst中去,這個(gè)函數(shù)的長度可控。但是會(huì)有內(nèi)存疊加的問題。 sprintf是格式化函數(shù)。將一段數(shù)據(jù)通過特定的格式,格式化到一個(gè)字符串緩沖區(qū)中去。sprintf格式化的函數(shù)的長度不可控,有可能格式化后的字符串會(huì)超出緩沖區(qū)的大小,造成溢出。 27. 用變量a給出下面的定義 a) 一個(gè)整型數(shù)(An integer) b)一個(gè)指向整型數(shù)的指針( A pointer to an integer) c)一個(gè)指向指針的的指針,它指向的指針是指向一個(gè)整型數(shù)( A pointer to a pointer to an intege)r d)一個(gè)有10個(gè)整型數(shù)的數(shù)組( An array of 10 integers) e) 一個(gè)有10個(gè)指針的數(shù)組,該指針是指向一個(gè)整型數(shù)的。(An array of 10 pointers to integers) f) 一個(gè)指向有10個(gè)整型數(shù)數(shù)組的指針( A pointer to an array of 10 integers) g) 一個(gè)指向函數(shù)的指針,該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(A pointer to a function that takes an integer as an argument and returns an integer) h)一個(gè)有10個(gè)指針的數(shù)組,該指針指向一個(gè)函數(shù),該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)( An array of ten pointers to functions t hat take an integer argument and return an integer ) 答案是: a) int a; // An integer b) int *a; // A pointer to an integer c) int **a; // A pointer to a pointer to an integer d) int a[10]; // An array of 10 integers e) int *a[10]; // An array of 10 pointers to integers f) int (*a)[10]; // A pointer to an array of 10 integers g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer 28.readwrite,readonly,assign,retain,copy,nonatomic屬性的作用 @property是一個(gè)屬性訪問聲明,擴(kuò)號(hào)內(nèi)支持以下幾個(gè)屬性: 1,getter=getterName,setter=setterName,設(shè)置setter與getter的方法名 2,readwrite,readonly,設(shè)置可供訪問級(jí)別 2,assign,setter方法直接賦值,不進(jìn)行任何retain操作,為了解決原類型與環(huán)循引用問題 3,retain,setter方法對(duì)參數(shù)進(jìn)行release舊值再retain新值,所有實(shí)現(xiàn)都是這個(gè)順序(CC上有相關(guān)資料) 4,copy,setter方法進(jìn)行Copy操作,與retain處理流程一樣,先舊值release,再Copy出新的對(duì)象,retainCount為1。這是為了減少對(duì)上下文的依賴而引入的機(jī)制。 5,nonatomic,非原子性訪問,不加同步,多線程并發(fā)訪問會(huì)提高性能。注意,如果不加此屬性,則默認(rèn)是兩個(gè)訪問方法都為原子型事務(wù)訪問。鎖被加到所屬對(duì)象實(shí)例級(jí)(我是這么理解的...)。 @synthesize xxx; 來實(shí)現(xiàn)實(shí)際代碼 請各位iphone開發(fā)工程師不要太保守,拿出您所知道的面試題與大家一起分享?;ハ鄮椭≈x謝! [ 此帖被haoxue在2012-06-30 17:32重新編輯 ] |
以下是我親身經(jīng)歷,應(yīng)聘iphone開發(fā)工程師是面試真題。拿出來與大家分享。希望對(duì)各位有幫助。 以下是百分之百iphone開發(fā)企業(yè)筆試真題 1、objective-c中是所有對(duì)象間的交互是如何實(shí)現(xiàn)的?(深圳皆凱科技有限公司筆試題) 2、如何將產(chǎn)品進(jìn)行多語言發(fā)布? 3、objective-c中是如何實(shí)現(xiàn)線程同步的? 4、編寫函數(shù)_memmove說明如下:實(shí)現(xiàn)C語言庫函數(shù)memmove的功能:將一塊緩沖區(qū)中的數(shù)據(jù)移動(dòng)到另一塊緩沖區(qū)中。可能有重復(fù)。 5、什么叫數(shù)據(jù)結(jié)構(gòu)?(面試順風(fēng)快遞iphone開發(fā)) 6、編程中,保存數(shù)據(jù)有哪幾種方式? 7、Sizeof與strlen的區(qū)別和聯(lián)系? 8、什么是抽象類?抽象類有什么作用?能實(shí)例化嗎? 9、 用Objective-C寫冒泡法. 10、考察對(duì)@interface和@property的理解? 11、Iphone開發(fā)中控制類有什么作用? 12、線程中有哪些函數(shù)?寫出來。 13、有沒有寫過自定義的控件? 14、調(diào)用一個(gè)類的靜態(tài)方法需不需要release? 15、do-while 與 while-do的區(qū)別? 16、寫出幾個(gè)死循環(huán)? 請各位iphone開發(fā)工程師解答上面的面試真題,寫上詳細(xì)答案。幫助一下初學(xué)者。謝謝! [ 此帖被haoxue在2011-06-06 10:24重新編輯 ] | ||||||||||||||
清空我的評(píng)分動(dòng)態(tài)本帖最近評(píng)分記錄: 共1條評(píng)分記錄
|
Objective-C筆試題,自己寫的答案。 1.ObjC中,與alloc語義相反的方法是dealloc還是release?與retain語義相反的方法是dealloc還是release,為什么?需要與alloc配對(duì)使用的方法是dealloc還是release,為什么?答:alloc與dealloc語意相反,alloc是創(chuàng)建變量,dealloc是釋放變量。 retain 對(duì)應(yīng)release,retain 保留一個(gè)對(duì)象。調(diào)用之后,變量的計(jì)數(shù)加1?;蛟S不是很明顯,在這有例為證: - (void) setName : (NSString*) name { [name retain]; [myname release]; myname = name; } 我們來解釋一下:設(shè)想,用戶在調(diào)用這個(gè)函數(shù)的時(shí)候,他注意了內(nèi)存的管理,所以他小心的寫了如下代碼: NSString * newname = [[NSString alloc] initWithString: @"John"]; [aClass setName: newname]; [newname release]; 我們來看一看newname的計(jì)數(shù)是怎么變化的。首先,它被alloc,count = 1; 然后,在setName中,它被retain, count = 2; 最后,用戶自己釋放newname,count = 1,myname指向了newname。這也解釋了為什么需要調(diào)用[myname release]。我們需要在給myname賦新值的時(shí)候,釋放掉以前老的變量。retain 之后直接dealloc對(duì)象計(jì)數(shù)器沒有釋放。alloc 需要與release配對(duì)使用,因?yàn)閍lloc 這個(gè)函數(shù)調(diào)用之后,變量的計(jì)數(shù)加1。所以在調(diào)用alloc 之后,一定要調(diào)用對(duì)應(yīng)的release。另外,在release一個(gè)變量之后,他的值仍然有效,所以最好是后面緊接著再var = nil。 2.在一個(gè)對(duì)象的方法里面: self.name = “object”; 和 name =”object” 有什么不同嗎? 答:self.name = "object"會(huì)調(diào)用對(duì)象的setName()方法,name = "object"會(huì)直接把object賦值給當(dāng)前對(duì)象的name 屬性。 [backcolor=transparent][backcolor=transparent]3.這段代碼有什么問題嗎: [backcolor=transparent]@implementation Person [backcolor=transparent]- (void)setAge:(int)newAge { [backcolor=transparent]self.age = newAge; [backcolor=transparent]} [backcolor=transparent]@end 答:會(huì)進(jìn)入死循環(huán)。 出現(xiàn)死循環(huán),循環(huán)調(diào)用。 4.什么是retain count?答:引用計(jì)數(shù)(ref count或者retain count)。對(duì)象的內(nèi)部保存一個(gè)數(shù)字,表示被引用的次數(shù)。例如,某個(gè)對(duì)象被兩個(gè)指針?biāo)赶颍ㄒ茫┠敲此膔etain count為2。需要銷毀對(duì) 象的時(shí)候,不直接調(diào)用dealloc,而是調(diào)用release。release會(huì) 讓retain count減1,只有retain count等于0,系統(tǒng)才會(huì)調(diào)用dealloc真正銷毀這個(gè)對(duì)象。 5.以下每行代碼執(zhí)行后,person對(duì)象的retain count分別是多少 Person *person = [[Person alloc] init]; count 1 [person retain]; count 2 [person release];count 1 [person release];retain count = 1; 6.為什么很多內(nèi)置類如UITableViewController的delegate屬性都是assign而不是retain的?答:會(huì)引起循環(huán)引用。 7.定義屬性時(shí),什么情況使用copy,assign,和retain 。答:assign用于簡單數(shù)據(jù)類型,如NSInteger,double,bool,retain 和copy用戶對(duì)象,copy用于當(dāng) a指向一個(gè)對(duì)象,b也想指向同樣的對(duì)象的時(shí)候,如果用assign,a如果釋放,再調(diào)用b會(huì)crash,如果用copy 的方式,a和b各自有自己的內(nèi)存,就可以解決這個(gè)問題。retain 會(huì)使計(jì)數(shù)器加一,也可以解決assign的問題。另外:atomic和nonatomic用來決定編譯器生成的getter和setter是否為原子操作。在多線程環(huán)境下,原子操作是必要的,否則有可能引起錯(cuò)誤的結(jié)果。加了atomic,setter函數(shù)會(huì)變成下面這樣: if (property != newValue) { [property release]; property = [newValue retain]; } 8.的對(duì)象是在什么時(shí)候被release的?答:autorelease實(shí)際上只是把對(duì)release的調(diào)用延遲了,對(duì)于每一個(gè)Autorelease,系統(tǒng)只是把該Object放入了當(dāng)前的Autorelease pool中,當(dāng)該pool被釋放時(shí),該pool中的所有Object會(huì)被調(diào)用Release。對(duì)于每一個(gè)Runloop, 系統(tǒng)會(huì)隱式創(chuàng)建一個(gè)Autorelease pool,這樣所有的release pool會(huì)構(gòu)成一個(gè)象CallStack一樣的一個(gè)棧式結(jié)構(gòu),在每一個(gè)Runloop結(jié)束時(shí),當(dāng)前棧頂?shù)腁utorelease pool會(huì)被銷毀,這樣這個(gè)pool里的每個(gè)Object(就是autorelease的對(duì)象)會(huì)被release。那什么是一個(gè)Runloop呢? 一個(gè)UI事件,Timer call, delegate call, 都會(huì)是一個(gè)新的Runloop。那什么是一個(gè)Runloop呢? 一個(gè)UI事件,Timer call, delegate call, 都會(huì)是一個(gè)新的Runloop。 9.這段代碼有什么問題,如何修改 for (int i = 0; i < someLargeNumber; i++) { NSString *string = @”Abc”; string = [string lowercaseString]; string = [string stringByAppendingString:@"xyz"]; NSLog(@“%@”, string); } 答:會(huì)內(nèi)存泄露, for(int i = 0; i<1000;i++){ NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init]; NSString *string = @"Abc"; string = [string lowercaseString]; string = [string stringByAppendingString:@"xyz"]; NSLog(@"%@",string); [pool1 drain]; } 10.autorelease和垃圾回收機(jī)制(gc)有什么關(guān)系?答案:不懂 11.IPhone OS有沒有垃圾回收(gc)?沒有。iPhone開發(fā)的時(shí)候沒有垃圾回收機(jī)制。 12.什么是Notification?答:觀察者模式,controller向defaultNotificationCenter添加自己的notification,其他類注冊這個(gè)notification就可以收到通知,這些類可以在收到通知時(shí)做自己的操作(多觀察者默認(rèn)隨機(jī)順序發(fā)通知給觀察者們,而且每個(gè)觀察者都要等當(dāng)前的某個(gè)觀察者的操作做完才能輪到他來操作,可以用NotificationQueue的方式安排觀察者的反應(yīng)順序,也可以在添加觀察者中設(shè)定反映時(shí)間,取消觀察需要在viewDidUnload 跟dealloc中都要注銷)。參考鏈接:http://useyourloaf.com/blog/2010/6/6/delegation-or-notification.html 13.什么時(shí)候用delegate,什么時(shí)候用Notification?答:delegate針對(duì)one-to-one關(guān)系,并且reciever可以返回值給sender,notification 可以針對(duì)one-to-one/many/none,reciever無法返回值給sender.所以,delegate用于sender希望接受到reciever的某個(gè)功能反饋值,notification用于通知多個(gè)object某個(gè)事件。 14.什么是KVC和KVO?答:KVC(Key-Value-Coding)內(nèi)部的實(shí)現(xiàn):一個(gè)對(duì)象在調(diào)用setValue的時(shí)候,(1)首先根據(jù)方法名找到運(yùn)行方法的時(shí)候所需要的環(huán)境參數(shù)。(2)他會(huì)從自己isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)的接口。(3)再直接查找得來的具體的方法實(shí)現(xiàn)。KVO(Key-Value-Observing):當(dāng)觀察者為一個(gè)對(duì)象的屬性進(jìn)行了注冊,被觀察對(duì)象的isa指針被修改的時(shí)候,isa指針就會(huì)指向一個(gè)中間類,而不是真實(shí)的類。所以isa指針其實(shí)不需要指向?qū)嵗龑?duì)象真實(shí)的類。所以我們的程序最好不要依賴于isa指針。在調(diào)用類的方法的時(shí)候,最好要明確對(duì)象實(shí)例的類名。 15.Notification和KVO有什么不同?答:不知道 16.KVO在ObjC中是怎么實(shí)現(xiàn)的?答:不知道 17.ViewController 的 loadView, viewDidLoad, viewDidUnload 分別是在什么時(shí)候調(diào)用的?在自定義ViewController的時(shí)候這幾個(gè)函數(shù)里面應(yīng)該做什么工作?答:viewDidLoad在view 從nib文件初始化時(shí)調(diào)用,loadView在controller的view為nil時(shí)調(diào)用。此方法在編程實(shí)現(xiàn)view時(shí)調(diào)用,view 控制器默認(rèn)會(huì)注冊memory warning notification,當(dāng)view controller的任何view 沒有用的時(shí)候,viewDidUnload會(huì)被調(diào)用,在這里實(shí)現(xiàn)將retain 的view release,如果是retain的IBOutlet view 屬性則不要在這里release,IBOutlet會(huì)負(fù)責(zé)release 。 18.ViewController 的 didReceiveMemoryWarning 是在什么時(shí)候被調(diào)用的?默認(rèn)的操作是什么?答:默認(rèn)調(diào)用[super didReceiveMemoryWarning] [ 此帖被haoxue在2012-06-30 17:50重新編輯 ] |
聯(lián)系客服