前言
由于種種原因说贝,我離開了上家公司,加上現(xiàn)在是疫情期間慎颗。招人的少乡恕,找工作的多。不好好準(zhǔn)備一下俯萎,真的是竹籃打水一場空傲宜。雖然我是初級開發(fā)者,但是也要好好學(xué)習(xí)夫啊。離開公司之后函卒,找工作找了20天,這段時間經(jīng)歷了boss直拒撇眯、前程擔(dān)憂报嵌、58不成、失聯(lián)招聘熊榛。很多公司都是掛個名在招聘網(wǎng)沪蓬,發(fā)消息基本不回復(fù)或者是幾個月才回復(fù)。這不来候,前幾天,一家公司打電話叫我面試逸雹,但是我是一個半月前投的簡歷营搅。。梆砸。转质。。帖世。休蟹。沸枯。。
以下就是我這些天面試了好幾家公司遇到的問題赂弓,在此記錄一下绑榴,答案不是詳細(xì)答案,有需要的可以去詳細(xì)了解盈魁。希望能幫助到大家翔怎。有什么不對的地方可以指出來我加以改正
1、UIview和CALayer的區(qū)別
答:這道題問的時候杨耙,我腦海里第一想到的是UIview具有響應(yīng)事件赤套、而layer沒有,UIView主要是對顯示內(nèi)容的管理珊膜,而 CALayer 主要側(cè)重顯示內(nèi)容的繪制容握。UIview是CALayer的高層實現(xiàn)與封裝,兩者有種依賴的關(guān)系车柠。所以一些簡單的控件不需要包裹的剔氏,用layer可以提高性能。
2堪遂、http和https的區(qū)別介蛉、對稱加密和非對稱加密
答:HTTP和HTTPS的區(qū)別就算不復(fù)習(xí)也多多少少知道一點,就是安全性的區(qū)別和請求過程的差別溶褪。對稱和非對稱這個對于我們移動端來說很陌生币旧,就是公鑰和密鑰的知識。對稱加密的加密和解密都是用的同一個密鑰猿妈。而非對稱加密會分開公有密鑰和私有密鑰吹菱。
3、swift的泛型簡單描述一下
答:現(xiàn)在面試不僅問oc彭则,還會問swift鳍刷。泛型我開發(fā)中有用過,但是直到我復(fù)習(xí)準(zhǔn)備面試的時候俯抖,才知道這東西叫泛型输瓜,真是慚愧。其實就是不用指定類型芬萍,比較靈活的一個東西尤揣,寫出可復(fù)用的函數(shù)。
4柬祠、swift跟oc的區(qū)別北戏,有什么優(yōu)勢劣勢
答:基本你的簡歷有寫會swift和oc的,都會被問這個問題漫蛔。最基本的區(qū)別就是oc是動態(tài)語言嗜愈、swift是靜態(tài)語言旧蛾。swift類型是安全的,因為在編譯的時候會進行一個類型檢測蠕嫁。而oc因為有runtime锨天,所以在類型安全方面沒有swift好。swift定義變量比oc方便快捷拌阴,用let或者var就可以绍绘。swift運行更快。swift打包出來的安裝包比oc打包的要大等等很多方面的區(qū)別迟赃。
5陪拘、說說幾個你常用的第三方庫的實現(xiàn)原理
答:我說的是AFN,就是早期對NSURLConnection的封裝纤壁,后面廢棄改用NSURLSession左刽。這里他又問我NSURLSession和NSURLConnection有什么區(qū)別。就是前者可以暫停網(wǎng)絡(luò)請求酌媒,而后者只能停止然后重新開始欠痴。下載文件的時候,后者是先下載到內(nèi)存秒咨,然后再寫入沙盒喇辽,如果數(shù)據(jù)很大,會出現(xiàn)內(nèi)存暴漲雨席,而NSURLsession是默認(rèn)下載到沙盒的tem文件夾菩咨,不會出現(xiàn)內(nèi)存暴漲,不過下載完成就會移除陡厘,所以需要在回調(diào)的時候增加一個保存的代碼抽米。
6、runloop的實現(xiàn)原理
答:內(nèi)部實現(xiàn)其實就是個do while死循環(huán)糙置。從我點擊APP圖標(biāo)開始云茸,就會開啟一個runloop來保證程序的運行。工作的時候運作谤饭,沒用到的時候休眠标捺。休眠的時候內(nèi)部會發(fā)出一個端口來監(jiān)聽,有事情做的時候端口會發(fā)出通知揉抵,進而結(jié)束休眠進入工作亡容。平時一些優(yōu)化和解決一些bug也會用到runloop,比如下面有兩個問題有說到功舀。
7、delegate為什么用weak身弊,系統(tǒng)有哪些代理是用strong辟汰,為什么用strong
答:就是為了防止循環(huán)引用列敲。其實不止用weak,有一些也用strong帖汞,比如NSURLSession的代理就是用strong戴而,為了防止回調(diào)還沒完成就被釋放了。但是用strong的代理記得在回調(diào)完成后及時釋放翩蘸,否則會引起循環(huán)引用所意。
8、kvo怎么監(jiān)聽數(shù)組
答:kvo是不能直接監(jiān)聽數(shù)組的催首,需要把數(shù)組定義在一個nsobject對象中扶踊,通過這個對象來監(jiān)聽才可以。
9郎任、點擊屏幕上的按鈕秧耗,這個過程發(fā)生了什么事
答:每次點擊屏幕的時候,uikit都會產(chǎn)生一個包含該處理事件的對象舶治,也就是UIevent對象分井。然后把這個對象放進APP的隊列中等待處理。怎么處理霉猛,當(dāng)然得找到點擊的這個視圖來處理尺锚,怎么找。系統(tǒng)會使用觸碰測試(hit-testing)來找任何一個在該點擊范圍內(nèi)的視圖惜浅,然后使用遞歸找子視圖瘫辩,一直找下去,直到?jīng)]有子視圖為止赡矢。
10杭朱、調(diào)用一個方法的時候,這個過程發(fā)生了什么事
答:1.在類的緩存方法列表中去找要調(diào)用的方法吹散,找到直接執(zhí)行其實現(xiàn)弧械。
2.如果類的緩存方法列表里沒找到,就去meta類的方法列表里找空民,找到了就執(zhí)行其實現(xiàn)刃唐。
3.還沒找到,說明這個類自己沒有了界轩,就會通過isa去meta類的父類里執(zhí)行1画饥、2。
4.如果找到了根meta類還沒找到浊猾,那么就是沒有了抖甘,會轉(zhuǎn)向一個攔截調(diào)用的方法,可以自己在攔截調(diào)用方法里面做一些處理葫慎。
5.如果沒有在攔截調(diào)用里做處理衔彻,那么就會報錯崩潰
11薇宠、nsarray和mutablearray被copy和mutablecopy修飾的結(jié)果
答:NSMutableArray被copy修飾之后變成NSArray,這時候進行增刪改查會報錯
NSMutableArray被mutablecopy修飾之后變成NSMutableArray
NSArray被copy修飾之后還是NSArray艰额,沒有產(chǎn)生新對象
NSArray被mutablecopy修飾之后變成NSMutableArray
12澄港、淺拷貝和深拷貝的理解
答:淺拷貝就是拷貝指針,深拷貝就是拷貝地址柄沮。
13回梧、簡述一下控制器的生命周期
答:無非就是init、load祖搓、viewdidload狱意、viewwilldidappear等等的執(zhí)行順序
14、oc是怎么進行內(nèi)存管理的
答:現(xiàn)在的公司項目基本都是ARC了棕硫,就是利用引用計數(shù)來管理髓涯。MRC時代的時候,我還沒參加工作哈扮,也不怎么懂纬纪。
15、簡述最常用的屬性修飾詞滑肉、weak包各、strong、copy等等
答:就是說一下這些屬性平時用在什么地方等等靶庙。像weak就是修飾代理等等问畅、copy就是修飾block等等。說到這里六荒,他還問了block為什么用copy护姆。因為block定義的時候是在棧,這個是系統(tǒng)自動回收的掏击,我們得把他拷貝到堆上卵皂,由我們自己去釋放。
16砚亭、怎么控制并發(fā)
答:我一開始總是把并發(fā)和并行搞混灯变。并發(fā)是指若干個事件在一個時間間隔內(nèi)發(fā)生,得一件一件來處理捅膘。并行是指若干個時間在同一時刻發(fā)生添祸,可以同時處理。我項目中并發(fā)是用信號量和NSOperationQueue來做
17寻仗、gcd的使用
答:面試官想了解你平時開發(fā)中是怎么用gcd的刃泌,用來解決什么問題,根據(jù)你自身情況就行
18、tableview復(fù)用機制
答:只有當(dāng)你所創(chuàng)建的cell數(shù)多于屏幕能夠顯示的數(shù)目時才會發(fā)生復(fù)用機制耙替,就是不用創(chuàng)建所有數(shù)量的cell鲤遥,當(dāng)cell離開屏幕的時候會放進緩存池,顯示出來的時候可以從緩存池取
19林艘、tableviewcell緩存池緩存多少個
答:屏幕最多顯示多少個就緩存多少個
20、tableview頭部和尾部可以復(fù)用
答:組的頭部尾部可以混坞,tableview的不可以
21狐援、block有多少種,有什么區(qū)別
答:沒查資料之前究孕,我一直以為block就一種啥酱。其實有三種。堆block厨诸、棧block镶殷、全局block。我們平時定義的大部分是堆block
22微酬、各種控件的繼承類是誰
答:他問了我UIview和UIviewcontroller绘趋。UIview的父類和UIviewcontroller的父類都是UIResponder。
23颗管、各設(shè)備間字體怎么適配
答:這一個我的做法跟文章的一樣(傳送門)
24陷遮、UItableview和UIcollectionview的區(qū)別
答:布局方式不一樣、后者對于自定義樣式比較靈活垦江、后者有水平和垂直兩個滾動方向
25帽馋、堆和棧的區(qū)別
答:這個問題我當(dāng)時支支吾吾的說了一些,平時開發(fā)中基本不怎么了解這些東西
26比吭、UIview可以在子線程設(shè)置frame嗎绽族,設(shè)置frame算是刷新UI嗎
答:不能,刷新UI要在主線程
27衩藤、UIview的layoutsubviews觸發(fā)時機是怎么樣的
答:我當(dāng)時說的是進行布局時執(zhí)行吧慢,用于設(shè)置控件的frame
28、oc的switch和swift的switch有什么區(qū)別
答:雖然oc和swift的switch都是用來做判斷執(zhí)行慷彤,但是還是有區(qū)別娄蔼。oc的switch語句分支必須是整數(shù),而且每個語句需要break底哗。swift的switch語句分支可以是各種類型岁诉,而且可以不用break。swift的Switch還能判斷string類型
29跋选、說說Swift中數(shù)組的map涕癣、filter、reduce
答:可以看看這篇文章
30、oc支持多繼承嗎
答:不可以
31坠韩、oc如何實現(xiàn)多繼承
答:要是上一道題答可以的話距潘,估計不會往下問了。實現(xiàn)多繼承的方式有:1只搁、使用delegate音比,我個人感覺這個不符合多繼承的理念。2氢惋、利用組合洞翩,就是把對象聲明成變量的形式。3焰望、增加分類
32骚亿、flutter是多線程還是單線程
答:因為我做過flutter項目,也在簡歷中寫了熊赖,所以面試官順便問了我這個問題来屠。flutter默認(rèn)是單線程
33、項目中如何配置多域名情況震鹉,就是生產(chǎn)環(huán)境和測試環(huán)境和其他環(huán)境各自的域名俱笛,除了在pch判斷環(huán)境來切換,還有啥方法
答:在工程配置config文件
34传趾、gcd和nsoperation有什么區(qū)別
答:gcd的核心是c語言嫂粟,nsoperation可以說是在gcd基礎(chǔ)上封裝的。nsoperation可以設(shè)置優(yōu)先級墨缘,而gcd只能設(shè)置隊列的優(yōu)先級星虹。nsoperation可以取消任務(wù)。
35镊讼、i++和++i的區(qū)別
答:前者是先賦值后加宽涌,后者是先加后賦值。也就是n=5++蝶棋,n等于5卸亮。n=++5,n等于6玩裙。
36兼贸、tableview調(diào)優(yōu)策略
答:1、避免開過多線程吃溅、cell的圖片都是異步加載溶诞,每次滑動的時候也是會加載的,這樣會增加內(nèi)存開銷决侈,應(yīng)該設(shè)置在滑動停止的時候才開始加載圖片螺垢。
2、圖片過大會造成GPU負(fù)荷,可以壓縮之后再顯示
3枉圃、使用Core Graphics實現(xiàn)圓角等功能功茴。
4、使用cell的復(fù)用機制
5孽亲、緩存cell高度坎穿,在數(shù)據(jù)回調(diào)之后計算并保存在model上
6、計算高度時返劲,盡量避免邏輯運算赁酝,盡可能使用加減乘除
7、使用drawRect添加子控件
8旭等、盡量少使用xib,因為xib會被編譯衡载,也是需要性能消耗的搔耕。
9、少使用約束痰娱,因為約束會被轉(zhuǎn)換為frame弃榨,多了一步
37、tableview如何在滑動停止的時候才開始加載圖片
答:面試官會問我這個問題是因為上一個問題我說了這個點梨睁,面試官都是喜歡深挖的鲸睛,一個問題挖下去。這個問題可以把設(shè)置圖片的操作放在runloop的defaultmode里面坡贺,因為在滑動的時候官辈,mode是trackingmode,導(dǎo)致這個設(shè)置圖片的方法不會被執(zhí)行遍坟,等滑動停止的時候拳亿,狀態(tài)切換回來了,就開始執(zhí)行了
38愿伴、為什么tableview在滑動的時候肺魁,cell上的timer會停止
答:那是因為runloop不能同時有兩個mode,在滑動的時候隔节,mode是UITrackingRunLoopMode鹅经。
與timer的mode不一致,所以會停止怎诫,需要把timer的mode改為UITrackingRunLoopMode或者NSRunLoopCommonModes就可以
39瘾晃、load和initialize的區(qū)別,他們的執(zhí)行時機是怎么樣的
答:load:當(dāng)類被引進項目的時候就會執(zhí)行該方法幻妓,執(zhí)行時機比main函數(shù)還前酗捌,不管這個類有沒有被用到,并且只會調(diào)用一次。一般用于方法交換的時候胖缤。
initialize:當(dāng)項目被初始化的時候尚镰,第一個方法被調(diào)用之前調(diào)用。一般用于初始化靜態(tài)變量之類的
兩者都是線程安全的哪廓,因為在內(nèi)部加了鎖狗唉,所以使用的時候避免阻塞
40、kvo的實現(xiàn)為什么要新建一個派生類
答:這里我能想到的就是開銷的問題涡真,新建派生類繼承并重寫了屬性的setter分俯,這樣哈希表里面查找的時間也相對減少,如果不新建的話哆料,可能在哈希表里面查找的時間變長缸剪。我的理解是這樣,有錯誤的請指正东亦,多多指教
41杏节、對runtime的理解和平時項目中用到runtime的情況
答:RunTime實際上是一個庫,這個庫使我們可以在程序運行時動態(tài)的創(chuàng)建對象典阵、檢查對象奋渔,修改類和對象的方法。他的作用其實就是在程序運行時做一些事情壮啊。
項目中我用到runtime其實就一個場景嫉鲸,就是給分類添加屬性
42、上一問題的延伸歹啼,為什么分類不能直接添加屬性玄渗,需要使用runtime來添加
答:
struct _category_t {
const char *name;
struct _class_t *cls;
const struct _method_list_t *instance_methods; // 對象方法列表
const struct _method_list_t *class_methods; // 類方法列表
const struct _protocol_list_t *protocols; // 協(xié)議列表
const struct _prop_list_t *properties; // 屬性列表
};
1.從結(jié)構(gòu)體可以知道,有屬性列表,所以分類可以聲明屬性狸眼,但是分類只會生成該屬性對應(yīng)的get和set的聲明捻爷,沒有去實現(xiàn)該方法。
2.結(jié)構(gòu)體沒有成員變量列表份企,所以不能聲明成員變量也榄。
如何使用runtime添加屬性
#import "Student+Extern.h"
#import <objc/runtime.h>
static NSString *nameKey = @"nameKey"; //定義一個key值
@implementation Student (Extern)
- (void)setName:(NSString *)name {
objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY);
}
- (NSString *)name {
return objc_getAssociatedObject(self, &nameKey);
}
@end
43、簡述iOS消息機制
答:
消息機制包含消息傳遞和消息轉(zhuǎn)發(fā)
消息傳遞:就是調(diào)用一個對象的方法時司志,通過SEL_IMP去查找找到對應(yīng)的方法甜紫,先從系統(tǒng)緩存找,找不到就在對象的方法列表找骂远,還找不到就在父類的方法列表找囚霸,實在找不到就會變成消息轉(zhuǎn)發(fā),通過消息轉(zhuǎn)發(fā)去其他對象找激才。
可以自行百度SEL和IMP的相關(guān)知識拓型,個人見解就是sel是選擇子额嘿,也就是方法的名稱,imp是函數(shù)指針劣挫,通過sel去查找imp册养,找到方法的指針之后就可以調(diào)用該方法。答的不對望指出
44压固、Swift權(quán)限訪問的關(guān)鍵字
指的是屬性球拦、方法、對象被關(guān)鍵字修飾后帐我,有沒有被訪問的權(quán)限
答:
open:權(quán)限最大坎炼,所有地方都可以訪問,也允許繼承拦键、重寫
public:所有地方都可以訪問谣光,不允許繼承、重寫
internal:默認(rèn)的關(guān)鍵字芬为。在同一模塊可以訪問
filePrivate:在同一文件內(nèi)可以訪問
private:只能在同一作用域訪問
final:防止類被繼承萄金,只能修飾類,不能修飾其他
45碳柱、類別和擴展的區(qū)別
答:
類別是在原有的類的源碼上建一個文件,文件名帶有+號熬芜,不用修改源碼即可添加方法莲镣,但是不能添加屬性,需要用runtime添加
擴展是可以像已有類添加方法和屬性涎拉,在.m文件用@interface 類名 ()創(chuàng)建瑞侮,所定義的方法和屬性只能在當(dāng)前文件使用,項目中代碼分塊可以考慮一下用這個
結(jié)束
平時得好好學(xué)習(xí)沉淀自己鼓拧,通過這次找工作意識到現(xiàn)在公司對開發(fā)者的要求是越來越高半火,不僅僅滿足于開發(fā)業(yè)務(wù)代碼。不過要記住一句話季俩,寧缺毋濫钮糖。總有合適的公司等著你