文章最后有面試題福利艇肴!記得看一下哦~
前言
寫這篇文章的目的是因為前兩天同學(xué)想應(yīng)聘iOS開發(fā)腔呜,從網(wǎng)上找了iOS面試題和答案讓我?guī)兔纯础N覓吡艘谎墼俚浚刮艘豢诶錃夂顺耄屑氁豢矗瑲獾陌l(fā)抖冲九。整篇題目30多個沒有一個答案是對的谤草,總結(jié)這篇面試題的作者對iOS機制根本就是一知半解就敢發(fā)到網(wǎng)上,不管有心還是無心都是坑害新人莺奸。所以在這里總結(jié)一下這幾年面試別人和被別人面試遇到的一些我認為比較好的基礎(chǔ)題目分享給大家丑孩,進階題目在后續(xù)補充。我的理解如果有錯漏請一定指出灭贷,非常感謝温学!
從12年開始做面試官到現(xiàn)在已經(jīng)三個年頭了,這期面過很多形形色色的開發(fā)氧腰,有騰訊的枫浙、有百度的刨肃、有小公司的、有做外包的箩帚,還有完全沒有代碼能力來做管理的真友。給我的感覺是百度出品的技術(shù)能力最好,基礎(chǔ)知識紧帕、技術(shù)細節(jié)掌握的非常的扎實并且自信盔然。騰訊出品技術(shù)細節(jié)上也非常厲害,平均來說比百度差一些是嗜,但是解決問題的能力非常強愈案,思維很活躍大局觀好。小公司鹅搪、外包公司的同學(xué)技術(shù)細節(jié)站绪、基礎(chǔ)知識要差一些。我個人是非常反對以出身論英雄BAT出品就一定比其他公司的優(yōu)秀丽柿,只能說BAT提供的技術(shù)氛圍更好恢准,你可以跟更多優(yōu)秀的人共事,相比小公司技術(shù)進步更容易些甫题。
這期間我也面了很多互聯(lián)網(wǎng)公司馁筐,騰訊、百度坠非、阿里敏沉、快播還有其他很多中小型公司,給我的感覺是中國整體的互聯(lián)網(wǎng)面試官的態(tài)度非常糟糕炎码,面試官經(jīng)常性習(xí)慣性的遲到盟迟,理由有開會啦、在吃飯啦辅肾,最離譜的是沒有任何理由就讓你在那里等队萤。其實我覺得現(xiàn)在這些公司啊還沒有認清楚一個現(xiàn)狀,就是絕大多數(shù)干開發(fā)的都只是來看看機會矫钓,不是來求職的要尔,所以總是找不到人。一邊說自己的公司多么求賢若渴新娜,應(yīng)聘者來了又不給予應(yīng)有的尊重赵辕。我認為面試是非常不好的一個詞,應(yīng)聘過程應(yīng)該叫面談概龄、review更合適还惠,它是一個雙向選擇的過程。
我參加的面試不下五十次私杜,只有兩次面試官遞給我一杯水蚕键,一次是騰訊的技術(shù)一面救欧,后來那個面試官也是我最尊敬的組長,還有一次是快播的hr面锣光。其他面試官直接無視汗流浹背頂著深圳烈日趕來面試的我笆怠,基本上每次面試完都是半脫水狀態(tài)。面試更主要的是考察一個應(yīng)聘者在正常環(huán)境下的工作能力而不是極端環(huán)境下的應(yīng)激能力誊爹,面試官不是要把應(yīng)聘者問倒蹬刷、提一些刁鉆的問題把他難住而是應(yīng)該幫助應(yīng)應(yīng)聘者緩解他的緊張和壓力,并適當?shù)奶崾酒登穑寫?yīng)聘者最大限度的發(fā)揮办成,這才是一個合格面試官最基本的素質(zhì)。
iOS面試知識點
現(xiàn)在進入本篇的正題搂漠。本篇的面試題是我認為比較好的iOS開發(fā)基礎(chǔ)知識點迂卢,希望大家看過這后在理解的基礎(chǔ)上掌握而不是死記硬背。死記硬背很快也會忘記的状答。
1 iOS基礎(chǔ)
1.1 父類實現(xiàn)深拷貝時冷守,子類如何實現(xiàn)深度拷貝。父類沒有實現(xiàn)深拷貝時惊科,子類如何實現(xiàn)深度拷貝。
深拷貝同淺拷貝的區(qū)別:淺拷貝是指針拷貝亮钦,對一個對象進行淺拷貝馆截,相當于對指向?qū)ο蟮闹羔樳M行復(fù)制,產(chǎn)生一個新的指向這個對象的指針蜂莉,那么就是有兩個指針指向同一個對象蜡娶,這個對象銷毀后兩個指針都應(yīng)該置空。深拷貝是對一個對象進行拷貝映穗,相當于對對象進行復(fù)制窖张,產(chǎn)生一個新的對象,那么就有兩個指針分別指向兩個對象蚁滋。當一個對象改變或者被銷毀后拷貝出來的新的對象不受影響宿接。
實現(xiàn)深拷貝需要實現(xiàn)NSCoying協(xié)議,實現(xiàn)- (id)copyWithZone:(NSZone *)zone 方法辕录。當對一個property屬性含有copy修飾符的時候睦霎,在進行賦值操作的時候?qū)嶋H上就是調(diào)用這個方法。
父類實現(xiàn)深拷貝之后走诞,子類只要重寫copyWithZone方法副女,在方法內(nèi)部調(diào)用父類的copyWithZone方法,之后實現(xiàn)自己的屬性的處理
父類沒有實現(xiàn)深拷貝蚣旱,子類除了需要對自己的屬性進行處理碑幅,還要對父類的屬性進行處理戴陡。
1.2 KVO,NSNotification沟涨,delegate及block區(qū)別
KVO就是cocoa框架實現(xiàn)的觀察者模式恤批,一般同KVC搭配使用,通過KVO可以監(jiān)測一個值的變化拷窜,比如View的高度變化开皿。是一對多的關(guān)系,一個值的變化會通知所有的觀察者篮昧。
NSNotification是通知赋荆,也是一對多的使用場景。在某些情況下懊昨,KVO和NSNotification是一樣的窄潭,都是狀態(tài)變化之后告知對方。NSNotification的特點酵颁,就是需要被觀察者先主動發(fā)出通知嫉你,然后觀察者注冊監(jiān)聽后再來進行響應(yīng),比KVO多了發(fā)送通知的一步躏惋,但是其優(yōu)點是監(jiān)聽不局限于屬性的變化幽污,還可以對多種多樣的狀態(tài)變化進行監(jiān)聽,監(jiān)聽范圍廣簿姨,使用也更靈活距误。
delegate 是代理,就是我不想做的事情交給別人做扁位。比如狗需要吃飯准潭,就通過delegate通知主人,主人就會給他做飯域仇、盛飯刑然、倒水,這些操作暇务,這些狗都不需要關(guān)心泼掠,只需要調(diào)用delegate(代理人)就可以了,由其他類完成所需要的操作般卑。所以delegate是一對一關(guān)系武鲁。
block是delegate的另一種形式,是函數(shù)式編程的一種形式蝠检。使用場景跟delegate一樣沐鼠,相比delegate更靈活,而且代理的實現(xiàn)更直觀。
KVO一般的使用場景是數(shù)據(jù)饲梭,需求是數(shù)據(jù)變化乘盖,比如股票價格變化,我們一般使用KVO(觀察者模式)憔涉。delegate一般的使用場景是行為订框,需求是需要別人幫我做一件事情,比如買賣股票兜叨,我們一般使用delegate穿扳。
Notification一般是進行全局通知,比如利好消息一出国旷,通知大家去買入矛物。delegate是強關(guān)聯(lián),就是委托和代理雙方互相知道跪但,你委托別人買股票你就需要知道經(jīng)紀人履羞,經(jīng)紀人也不要知道自己的顧客。Notification是弱關(guān)聯(lián)屡久,利好消息發(fā)出忆首,你不需要知道是誰發(fā)的也可以做出相應(yīng)的反應(yīng),同理發(fā)消息的人也不需要知道接收的人也可以正常發(fā)出消息被环。
1.3 KVC如果實現(xiàn)糙及,如何進行鍵值查找。KVO如何實現(xiàn)
1.4 將一個函數(shù)在主線程執(zhí)行的4種方法
- GCD方法筛欢,通過向主線程隊列發(fā)送一個block塊丁鹉,使block里的方法可以在主線程中執(zhí)行。
dispatch_async(dispatch_get_main_queue(), ^{
//需要執(zhí)行的方法
});
- NSOperation 方法
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; //主隊列
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
//需要執(zhí)行的方法
}];
[mainQueue addOperation:operation];
- NSThread 方法
[self performSelector:@selector(method) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES modes:nil];
[self performSelectorOnMainThread:@selector(method) withObject:nil waitUntilDone:YES];
[[NSThread mainThread] performSelector:@selector(method) withObject:nil];
- RunLoop方法
[[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];
1.5 如何讓計時器調(diào)用一個類方法
- 計時器只能調(diào)用實例方法悴能,但是可以在這個實例方法里面調(diào)用靜態(tài)方法。
- 使用計時器需要注意雳灾,計時器一定要加入RunLoop中漠酿,并且選好model才能運行。scheduledTimerWithTimeInterval方法創(chuàng)建一個計時器并加入到RunLoop中所以可以直接使用谎亩。
- 如果計時器的repeats選擇YES說明這個計時器會重復(fù)執(zhí)行炒嘲,一定要在合適的時機調(diào)用計時器的invalid。不能在dealloc中調(diào)用匈庭,因為一旦設(shè)置為repeats 為yes夫凸,計時器會強持有self,導(dǎo)致dealloc永遠不會被調(diào)用阱持,這個類就永遠無法被釋放夭拌。比如可以在viewDidDisappear中調(diào)用,這樣當類需要被回收的時候就可以正常進入dealloc中了。
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
-(void)timerMethod
{
//調(diào)用類方法
[[self class] staticMethod];
}
-(void)invalid
{
[timer invalid];
timer = nil;
}
1.6 如何重寫類方法
- 1鸽扁、在子類中實現(xiàn)一個同基類名字一樣的靜態(tài)方法
- 2蒜绽、在調(diào)用的時候不要使用類名調(diào)用,而是使用[self class]的方式調(diào)用桶现。原理躲雅,用類名調(diào)用是早綁定,在編譯期綁定骡和,用[self class]是晚綁定相赁,在運行時決定調(diào)用哪個方法。
1.7 NSTimer創(chuàng)建后慰于,會在哪個線程運行钮科。
- 用scheduledTimerWithTimeInterval創(chuàng)建的,在哪個線程創(chuàng)建就會被加入哪個線程的RunLoop中就運行在哪個線程
- 自己創(chuàng)建的Timer东囚,加入到哪個線程的RunLoop中就運行在哪個線程跺嗽。
1.8 id和NSObject*的區(qū)別
- id是一個 objc_object 結(jié)構(gòu)體指針,定義是
typedef struct objc_object *id
- id可以理解為指向?qū)ο蟮闹羔樢吃濉K衞c的對象 id都可以指向桨嫁,編譯器不會做類型檢查,id調(diào)用任何存在的方法都不會在編譯階段報錯份帐,當然如果這個id指向的對象沒有這個方法璃吧,該崩潰還是會崩潰的。
- NSObject *指向的必須是NSObject的子類废境,調(diào)用的也只能是NSObjec里面的方法否則就要做強制類型轉(zhuǎn)換畜挨。
- 不是所有的OC對象都是NSObject的子類,還有一些繼承自NSProxy噩凹。NSObject *可指向的類型是id的子集巴元。
我的理解如果有錯漏請一定指出,非常感謝驮宴!
小編給大家推薦一個iOS技術(shù)交流群:679884541逮刨!群內(nèi)提供數(shù)據(jù)結(jié)構(gòu)與算法、底層進階堵泽、swift修己、逆向、底層面試題整合文檔等免費資料迎罗!希望找到更多的同行多多交流睬愤!以下資料,進群可以免費獲得哦