一個(gè)知乎iOS面試題答案

本文將回答知乎上iOS面試問題鏈接:如何面試 iOS 工程師?

Model層:

數(shù)據(jù)持久化存儲(chǔ)方案有哪些?沙盒的目錄結(jié)構(gòu)是怎樣的?各自一般用于什么場(chǎng)合?SQL語句問題:inner join、left join、right join的區(qū)別是什么?sqlite的優(yōu)化網(wǎng)絡(luò)通信用過哪些方式(100%的人說了AFNetworking...)如何處理多個(gè)網(wǎng)絡(luò)請(qǐng)求并發(fā)的情況
在網(wǎng)絡(luò)請(qǐng)求中如何提高性能
在網(wǎng)絡(luò)請(qǐng)求中如何保證安全性

語言與基礎(chǔ)知識(shí):

內(nèi)存中的棧和堆的區(qū)別是什么?那些數(shù)據(jù)在棧上,哪些在堆上?#define和const定義的變量,有什么區(qū)別什么情況下會(huì)出現(xiàn)內(nèi)存的循環(huán)引用block中的weak self,是任何時(shí)候都需要加的么?GCD的queue,main queue中執(zhí)行的代碼,一定是在main thread么?
NSOperationQueue有哪些使用方式
NSThread中的Runloop的作用,如何使用?
.h文件中的變量,外部可以直接訪問么?(注意是變量,不是property)講述一下runtime的概念,message send如果尋找不到相應(yīng)的對(duì)象,會(huì)如何進(jìn)行后續(xù)處理 ?TCP和UDP的區(qū)別是什么?
MD5和Base64的區(qū)別是什么,各自場(chǎng)景是什么?
二叉搜索樹的概念,時(shí)間復(fù)雜度多少?

架構(gòu):(我們招的不是架構(gòu)師,這方面問的不多,而且從之前對(duì)APP的架構(gòu)介紹里可以邊聽邊問)

哪些類不適合使用單例模式?即使他們?cè)谥芷谥兄粫?huì)出現(xiàn)一次。
Notification的使用場(chǎng)景是什么?同步還是異步?
簡單介紹一下KVC和KVO,他們都可以應(yīng)用在哪些場(chǎng)景?

APP相關(guān):

如何添加一個(gè)自定義字體到工程中
如何制作一個(gè)靜態(tài)庫/動(dòng)態(tài)庫,他們的區(qū)別是什么?
Configuration中,debug和release的區(qū)別是什么?
簡單介紹下發(fā)送系統(tǒng)消息的機(jī)制(APNS) UI:
系統(tǒng)如何尋找到需要響應(yīng)用戶操作的那個(gè)Responder
多屏幕尺寸的適配
UIButton的父類是什么?UILabel呢?
push view controller 和 present view controller的區(qū)別
描述下tableview cell的重用機(jī)制
UIView的frame和bounds的區(qū)別是什么

最后是幾道場(chǎng)景題,也是我最喜歡問的:

發(fā)送10個(gè)網(wǎng)絡(luò)請(qǐng)求,然后再接收到所有回應(yīng)之后執(zhí)行后續(xù)操作,如何實(shí)現(xiàn)?
實(shí)現(xiàn)一個(gè)第三方控件,可以在任何時(shí)候出現(xiàn)在APP界面最上層
實(shí)現(xiàn)一個(gè)最簡單的點(diǎn)擊拖拽功能。上面那個(gè)拖拽之外,如果在手放開時(shí),需要根據(jù)速度往前滑動(dòng)呢?
如何減小一個(gè)應(yīng)用程序的尺寸?
如何提高一個(gè)性用程序的性能?
不同版本的APP,數(shù)據(jù)庫結(jié)構(gòu)變化了,如何處理?

作者:張之誠
鏈接:https://www.zhihu.com/question/19604641/answer/56306604
來源:知乎

下面是給出的答案,有不對(duì)的地方還請(qǐng)多多指教!

一. 數(shù)據(jù)持久化存儲(chǔ)方案有哪些?

  1. 屬性列表(NSUserdefaults)
    NSUserdefaults適合存儲(chǔ)輕量級(jí),弱業(yè)務(wù)相關(guān)的數(shù)據(jù),存儲(chǔ)在應(yīng)用程序的一個(gè)plist文件里,Document目錄平級(jí)的/Library/Prefereces里。
  2. NSCoding
  3. 文件存儲(chǔ)(NSFileManager)
  4. NSKeydeArchive歸檔存儲(chǔ)
    又名序列化,把對(duì)象轉(zhuǎn)為字節(jié)碼,通過key-value以文件的形式加密存儲(chǔ)在磁盤上
  5. 數(shù)據(jù)庫
    SQlite庫提供了三種方式:Single Thread, Multi Thread, Serialized(默認(rèn))
    Serialized串行隊(duì)列執(zhí)行所有操作,
  6. Keychain
    蘋果提供的帶有可逆加密的存儲(chǔ)機(jī)制,存儲(chǔ)密碼和用戶唯一標(biāo)識(shí)串。

二. 沙盒的目錄結(jié)構(gòu)是怎樣的?各自一般用于什么場(chǎng)合?

在應(yīng)用的安裝過程中,系統(tǒng)為每個(gè)單獨(dú)的應(yīng)用程序生成它的主目錄和一些關(guān)鍵的子目錄。蘋果對(duì)沙盒的幾天限制:

  1. 應(yīng)用程序在自己的沙盒中運(yùn)作,不能訪問任何其他應(yīng)用程序的沙盒;
  2. 應(yīng)用之間不能共享數(shù)據(jù);
  3. 蘋果禁止任何讀寫沙盒以外的文件,禁止應(yīng)用程序?qū)?nèi)容寫到沙盒以外的文件中;
  4. 沙盒目錄里有三個(gè)文件夾:Documents、Library、Temp、AppName.app目錄
    Documents-----存儲(chǔ);應(yīng)用程序的數(shù)據(jù)文件,存儲(chǔ)用戶數(shù)據(jù)或其他定期備份的信息;
    library下有兩個(gè)文件夾:Caches存儲(chǔ)應(yīng)用程序再次啟動(dòng)所需的信息,
    Preferences包含應(yīng)用程序的偏好設(shè)置文件,不可在這更改偏好設(shè)置;
    temp存儲(chǔ)臨時(shí)文件
  5. 獲取沙盒根目錄方法:NSHomeDirectory獲取
    獲取Document路徑
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).

三. SQL語句問題:inner join、left join、right join的區(qū)別是什么?

left join(左聯(lián)接)返回包括左表中的所有記錄和右表中聯(lián)結(jié)字段相等的記錄
right join(右聯(lián)接)返回包含右表中的所有記錄和左表中聯(lián)接字段相等的記錄
inner join (等值聯(lián)接) 只返回兩個(gè)表中聯(lián)接字段相等的行
select *from A left join B on A.id = B.id

四. 在網(wǎng)絡(luò)請(qǐng)求中如何提高性能?

1.減少請(qǐng)求寬帶:(壓縮請(qǐng)求與響應(yīng))
(1)使用JSON數(shù)據(jù),高效的數(shù)據(jù)交換格式
(2)Base64格式上傳文件,對(duì)Base64數(shù)據(jù)進(jìn)行壓縮,減少30%的數(shù)據(jù)體積
2.降低請(qǐng)求延遲:(管道化請(qǐng)求)
(1)降低多個(gè)請(qǐng)求的延遲
(2)在單個(gè)TCP連接上發(fā)送HTTP請(qǐng)求,以管道的形式發(fā)送HTTP請(qǐng)求,從而優(yōu)化全雙工TCP連接的使用。
(3)Apache和IIS都支持管道,無需任何額外的配置。
3.避免網(wǎng)絡(luò)請(qǐng)求
(1)在本地緩存內(nèi)容避免不必要的網(wǎng)絡(luò)流量

五. 在網(wǎng)絡(luò)請(qǐng)求中如何保證安全性

https 和 加密

六. 內(nèi)存中的棧和堆的區(qū)別是什么?那些數(shù)據(jù)在棧上,哪些在堆上?

棧區(qū)是由編譯器自動(dòng)分配釋放,存放方法(函數(shù))的參數(shù)值,局部變量的值等,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存區(qū)域。棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的。
堆由程序員分配釋放,若不釋放,程序結(jié)束時(shí)由OS回收,向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域,
OC對(duì)象放在堆內(nèi),非OC對(duì)象一般放在棧里面
棧是吃了吐,堆是吃了拉
鏈接:iOS 堆和棧的區(qū)別?

七. #define和const定義的變量,有什么區(qū)別:

1.#define在預(yù)處理階段進(jìn)行簡單的替換,const在編譯階段使用;
2.#define不做類型檢查,只是簡單的替換,const有數(shù)據(jù)類型會(huì)執(zhí)
行類型檢查;
3.#define不能調(diào)試, const可以調(diào)試
4.#define大量的宏造成編譯時(shí)間久
5.#define可以定義一些簡單的函數(shù),const不可以
6.const修飾右邊的變量只讀 NSString * const p

static作用:

  1. 修飾局部變量
    (1)延長局部變量的生命周期,程序結(jié)束才會(huì)銷毀
    (2)局部變量只會(huì)生成一份內(nèi)存,只會(huì)初始化一次
  2. 修飾全局變量:只能在本文件中訪問,修改全局變量的作用域,生命周期不會(huì)改

extern作用:聲明全局變量
聲明一個(gè)變量,不能定義變量

static和const聯(lián)合使用:聲明一個(gè)靜態(tài)全局只讀變量
static NSString * const name = @"name";

extern與const聯(lián)合使用
當(dāng)有多個(gè)文件使用同一個(gè)字符串常量時(shí),可以使用extern和const組合

新建一個(gè)全局的文件管理全局的變量
在.m里定義 NSString *const YYTextViedBegin = @"YYTextVditing";
在.h里應(yīng)用 UIKIT_EXTERN NSString *const YYTextViewTextDidBegin;

八. 什么情況下會(huì)出現(xiàn)內(nèi)存的循環(huán)引用

block,A強(qiáng)引用了block,block有強(qiáng)引用了A

九. block中的weak self,是任何時(shí)候都需要加的么?

只有產(chǎn)生循環(huán)引用了才會(huì)加

十. GCD的queue,main queue中執(zhí)行的代碼,一定是在main thread么?

對(duì)于queue中所執(zhí)行的代碼不一定在main thread中。如果
queue是在主線程中創(chuàng)建的,那么所執(zhí)行的代碼就是在主線程中執(zhí)行。如果是在子線程中創(chuàng)建的,那么就不會(huì)在main thread中執(zhí)行。
對(duì)于main queue就是在主線程中的,因此一定會(huì)在主線程中執(zhí)行。獲取 main queue就可以了,不需要我們創(chuàng)建,獲取方式通過調(diào)用方法 dispatchgetmain_queue來獲取。
鏈接:多線程

十一. NSOperationQueue有哪些使用方式

鏈接:iOS多線程之NSOperationQueue

與GCD的區(qū)別

  1. GCD使用方便,代碼邏輯清晰,
  2. GCD是C語言構(gòu)成的API,NSOperationQueue是基于GCD的Objective-C對(duì)象的封裝,提供了更多的選擇
  3. NSOperationQueue任務(wù)可以很方便的取消未執(zhí)行的任務(wù)
  4. GCD只支持FIFO隊(duì)列,NSOperation可以通過依賴關(guān)系設(shè)置操作執(zhí)行順序,控制在特定的任務(wù)執(zhí)行完后才執(zhí)行,GCD可以通過barrier或者group控制執(zhí)行順序,但是依賴關(guān)系復(fù)雜時(shí),代碼邏輯太復(fù)雜
  5. NSOperation支持KVO監(jiān)聽任務(wù)的狀態(tài)(完成、執(zhí)行中、取消等狀態(tài))
  6. NSOperation可以設(shè)置同一隊(duì)列中任務(wù)的優(yōu)先級(jí),GCD只能區(qū)分不同隊(duì)列的優(yōu)先級(jí)
  7. 自定義NSOperation,封裝任務(wù)邏輯,提高整個(gè)代碼的復(fù)用度

十二. NSThread中的Runloop的作用,如何使用

runloop是一個(gè)線程里運(yùn)行循環(huán),并對(duì)收到的事件進(jìn)行處理,

  1. 保持線程長時(shí)間存活
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop addPort:[NSMachPort port] forMode:NSRunLoopCommonModes];
    [runLoop run];
  2. 用于定時(shí)器

十三. .h文件中的變量,外部可以直接訪問么?(注意是變量,不是property)

成員變量三中權(quán)限:@private, @protected, @public
不可以,.h中的成員變量默認(rèn)是@protected權(quán)限,子類可以訪問,可以做權(quán)限修改,外部調(diào)用會(huì)報(bào)protected錯(cuò)誤

十四. 講述一下runtime的概念,message send如果尋找不到相應(yīng)的對(duì)象,會(huì)如何進(jìn)行后續(xù)處理 ?

objc向一個(gè)對(duì)象發(fā)送消息,runtime會(huì)根據(jù)對(duì)象的isa指針找到該對(duì)象實(shí)際所屬類,然后在該類方法列表以及父類的方法列表中查找方法實(shí)現(xiàn),如果向一個(gè)nil對(duì)象發(fā)送消息,在查找isa指針時(shí)就是0地址返回,不會(huì)出錯(cuò)

十五. TCP和UDP的區(qū)別是什么?

TCP:面向連接、傳輸可靠(保證數(shù)據(jù)正確性,數(shù)據(jù)順序)、用于傳輸大量數(shù)據(jù)(流模式)、速度慢、建立連接需要開銷較多(時(shí)間,系統(tǒng)資源)。
UDP:面向非連接、傳輸不可靠、用于傳輸少量數(shù)據(jù)(數(shù)據(jù)包模式)、速度快。
TCP在連接持續(xù)過程中,socket收到的數(shù)據(jù)是同一臺(tái)主機(jī)發(fā)出。
UDP只要知道接收端的IP和端口,網(wǎng)絡(luò)可達(dá),任何主機(jī)都可以向接受端發(fā)送數(shù)據(jù)

十六. MD5和Base64的區(qū)別是什么,各自場(chǎng)景是什么

MD5是用哈希算法(摘要算法)加密的:不可逆;密文總是16進(jìn)制32位
一般用于文件校驗(yàn)、密碼存儲(chǔ)
Base64是公開的代碼加密,url加密

十七. 二叉搜索樹的概念,時(shí)間復(fù)雜度多少

采用二叉樹鏈表作為存儲(chǔ)結(jié)構(gòu),每個(gè)左節(jié)點(diǎn)均小于父節(jié)點(diǎn),每個(gè)右節(jié)點(diǎn)均大于父節(jié)點(diǎn)
時(shí)間復(fù)雜度:O(log2(n))

十八. 哪些類不適合使用單例模式?即使他們?cè)谥芷谥兄粫?huì)出現(xiàn)一次。

同一類型的對(duì)象需要在不同的用例場(chǎng)景發(fā)生變化

十九. Notification的使用場(chǎng)景是什么?同步還是異步?

一對(duì)多,同步

二十. 簡單介紹一下KVC和KVO,他們都可以應(yīng)用在哪些場(chǎng)景?

KVO:鍵值監(jiān)聽,觀察某一屬性的方法
KVC:鍵值編碼,間接訪問對(duì)象的屬性

二十一. 如何添加一個(gè)自定義字體到工程中
> 添加ttf文件,通過[UIFont fontWithName:@“字體名” size:20]使用

二十二. 如何制作一個(gè)靜態(tài)庫/動(dòng)態(tài)庫,他們的區(qū)別是什么?

靜態(tài)庫在編譯時(shí)期:commond+shift+N(即新建工程)----->FrameWork&library—>Cocoa Touch Static Libiary
動(dòng)態(tài)庫在運(yùn)行時(shí)期:commond+shift+N(即新建工程)----->FrameWork&library—>Cocoa Touch Libiary
區(qū)別:靜態(tài)庫:模塊化,分工合作,避免少量改動(dòng),但是會(huì)導(dǎo)致大量的重復(fù)編譯連接,也可以重用,注意不是共享使用 動(dòng)態(tài)庫:可將可執(zhí)行的文件體積縮小,多個(gè)應(yīng)用程序用同一份庫文件,節(jié)省資源

二十三. Configuration中,debug和release的區(qū)別是什么?

debug :測(cè)試時(shí)期,調(diào)試版本,能設(shè)置斷點(diǎn),單步執(zhí)行 release:發(fā)行版本,體積小,運(yùn)行速度快

二十四. 簡單介紹下發(fā)送系統(tǒng)消息的機(jī)制(APNs)

蘋果的APNS不保證送達(dá)率,如你網(wǎng)絡(luò)不好,在APNs那里下線,只保留最后一條消息,并告知推送數(shù),其他消息會(huì)被APNs丟棄。

UI:

二十五. 系統(tǒng)如何尋找到需要響應(yīng)用戶操作的那個(gè)Responder

系統(tǒng)通過調(diào)用hitTest:withEvent:接受位置參數(shù)CGPoint,從底層按照subview的順序,測(cè)試該點(diǎn)在哪個(gè)view上,如果在該view上,則繼續(xù)測(cè)試是否在view的subview上。。。
響應(yīng)鏈?zhǔn)菑牡讓油系?,?dāng)沒有可以處理的responder時(shí)按響應(yīng)鏈往上回溯,一直到application也無人處理則丟棄

二十六. 多屏幕尺寸的適配

Autolayout、Masonry、SDAutoLayout、純Frame計(jì)算比例

二十七. UIButton的父類是什么?UILabel呢?

UIControl UIView

二十八. push view controller 和 present view controller的區(qū)別

是否使用UINavigationController

二十九. 描述下tableview cell的重用機(jī)制

當(dāng)cell被移出界面,進(jìn)入重用池,當(dāng)cell要顯示時(shí)候從重用池中獲取cell

三十. UIView的frame和bounds的區(qū)別是什么

Frame是參考父視圖的坐標(biāo)系,bounds參考自身坐標(biāo)系

三十一. 發(fā)送10個(gè)網(wǎng)絡(luò)請(qǐng)求,然后再接收到所有回應(yīng)之后執(zhí)行后續(xù)操作,如何實(shí)現(xiàn)?

GCD信號(hào)量,隊(duì)列組

  1. 做法:通過dispatch_group_t來實(shí)現(xiàn),將每個(gè)請(qǐng)求放入到Group中,將合并成大圖的操作放在dispatch_group_notify中實(shí)現(xiàn)。
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{ /*加載圖片1 / });
    dispatch_group_async(group, queue, ^{ /
    加載圖片2 / });
    dispatch_group_async(group, queue, ^{ /
    加載圖片3 */ });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // 合并圖片
    });
  2. dispatch_group_enter()和dispatch_group_leave()

三十二. 實(shí)現(xiàn)一個(gè)第三方控件,可以在任何時(shí)候出現(xiàn)在APP界面最上層

三十三. 實(shí)現(xiàn)一個(gè)最簡單的點(diǎn)擊拖拽功能。

三十四. 上面那個(gè)拖拽之外,如果在手放開時(shí),需要根據(jù)速度往前滑動(dòng)呢?

三十五. 如何減小一個(gè)應(yīng)用程序的尺寸?
鏈接:減小iOS App或者靜態(tài)庫體積
鏈接: iOS App 瘦身 - 以 Swift App Yep 為例

三十六. 如何提高一個(gè)應(yīng)用程序的性能?
鏈接:25條提高iOS App性能的建議和技巧

三十七. 不同版本的APP,數(shù)據(jù)庫結(jié)構(gòu)變化了,如何處理?
數(shù)據(jù)庫遷移

  1. 運(yùn)行APP后,判斷是否存在數(shù)據(jù)庫,不存在則直接創(chuàng)建數(shù)據(jù)庫,若存在取出數(shù)據(jù)庫版本號(hào)進(jìn)行case處理
  2. 第一次運(yùn)行APP,第一次建立版本庫,將數(shù)據(jù)信息存入數(shù)據(jù)庫,同時(shí)保存一個(gè)當(dāng)前版本加一的字段到數(shù)據(jù)庫中
  3. 當(dāng)APP更新時(shí),從數(shù)據(jù)庫中取出數(shù)據(jù)庫中保存的版本字段,然后case執(zhí)行相關(guān)方法,修改完數(shù)據(jù)結(jié)構(gòu)以后,再一次將版本字段加一存到數(shù)據(jù)庫中。
    鏈接:App升級(jí)時(shí)數(shù)據(jù)庫的遷移更新
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 2,255評(píng)論 0 7
  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理。運(yùn)行時(shí)機(jī)制的原理和運(yùn)用場(chǎng)景。SDWebImage的原...
    LZM輪回閱讀 2,133評(píng)論 0 12
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,580評(píng)論 0 35
  • ———————————————回答好下面的足夠了---------------------------------...
    恒愛DE問候閱讀 1,846評(píng)論 0 4
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,667評(píng)論 30 472

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