前提:上周同事去一家初創(chuàng)型互聯(lián)網(wǎng)公司去面試iOS開發(fā)遇到如下的面試題芜繁,也跟我分享了一下具體面試內(nèi)容剿干,寫篇博客總結(jié)一下章咧。
面試題如下
- 極光推送使用
- 談?wù)剬?duì)高德地圖的使用
- 項(xiàng)目中使用過(guò)阿里云的即時(shí)通訊验靡,是否使用過(guò)非第三方的即時(shí)通訊
- 談?wù)劯卟l(fā)編程
- 你理解的多線程
- 介紹APP啟動(dòng)過(guò)程劲弦,如果啟動(dòng)比較耗時(shí)是否有優(yōu)化的方法
- 簡(jiǎn)單說(shuō)說(shuō)TCP和UDP的理解
- 說(shuō)下MD5 base64以及AES加密耳标,以及如何防止反編譯
- 說(shuō)一下了解的設(shè)計(jì)模式,以及架構(gòu)設(shè)計(jì)
- 項(xiàng)目中的角色權(quán)限和分配邑跪,是否做過(guò)單點(diǎn)登錄
- 有沒有處理過(guò)萬(wàn)以上的數(shù)據(jù)實(shí)時(shí)傳輸次坡,如何處理
- 是否有自己的博客和開源,或者談?wù)剬?duì)于常用框架的理解
看到具體的面試題后画畅,我總結(jié)了一下如下分四個(gè)部分:
1.第一部分的是對(duì)常規(guī)SDK的使用和項(xiàng)目中常用框架砸琅。
- 友盟、極光轴踱、支付寶/微信症脂、高德。
- 登錄、分享诱篷,通知壶唤,支付,地圖
友盟
極光
支付寶棕所、微信
高德地圖
- AFNetworking闸盔、SDWebImage、Masonry橙凳、MJExtension
- 網(wǎng)絡(luò)請(qǐng)求,圖片加載笑撞,布局岛啸,轉(zhuǎn)模型解析
AFNetworking
SDWebImage
Masonry
MJExtension
2.第二部分的是對(duì)概念設(shè)計(jì)模式的理解。
高并發(fā)編程
圍繞高并發(fā)的核心詞 :
Grand Central Dispatch(簡(jiǎn)稱GCD)茴肥、NSOperation坚踩、NSThread
、Operation Queues(運(yùn)行隊(duì)列)
瓤狐、多線程
- GCD:
GCD
屬于Apple開發(fā)的線程管理瞬铸,是最常使用的并發(fā)編程方式。其核心思想是將并發(fā)執(zhí)行的任務(wù)封裝到Block
回調(diào)中础锐,在把Block
分發(fā)到不同類型的隊(duì)列里嗓节,對(duì)不同類型的隊(duì)列,實(shí)現(xiàn)并發(fā)執(zhí)行皆警。GCD
以dispatch_async
開頭是一套C函數(shù)的調(diào)用方法:
//dispatch_async:異步執(zhí)行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#time#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
<#do something#> // 待執(zhí)行的任務(wù)
});
- NSOperation:
NSOperation
的核心是對(duì)GCD
的一種封裝拦宣,把需要并發(fā)執(zhí)行的任務(wù)封裝到NSOperation
中,然后添加到NSOperationQueue
并發(fā)執(zhí)行信姓。調(diào)用start
方法即可開始執(zhí)行操作鸵隧,調(diào)用cancel
方法中途取消操作,completionBlock
處理完的回調(diào)意推。
- NSThread:
GCD
的清量易用一定意義上替代諸NSThread
這種較為復(fù)雜技術(shù)高效的技術(shù)豆瘫。每一個(gè)NSThread
都是一個(gè)線程。selector:
線程執(zhí)行的方法菊值,該selector
只能有一個(gè)參數(shù)外驱,而且返回值是void
。target:selector
消息發(fā)送的對(duì)象argument:
傳遞給target
的唯一參數(shù)腻窒,可以為nil
略步。NSThread
的開啟,關(guān)閉以及一些執(zhí)行狀態(tài)控制都需要開發(fā)者自己管理 detachNewThreadSelector:toTarget:withObject:
initWithTarget:selector:object:
兩者區(qū)別在于下面獲取到了NSThread
對(duì)象方便終止線程定页。
[NSThread detachNewThreadSelector:@selector(loadData) toTarget:self withObject:nil];
#pragma mark - 加載耗時(shí)數(shù)據(jù)
- (void)loadData
{
//并發(fā)執(zhí)行執(zhí)行任務(wù)
}
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadData) object:nil];
[thread start]; //調(diào)用
總結(jié):如果選擇的話我更傾向于
GCD
,GCD
是一個(gè)輕量級(jí)別的級(jí)別趟薄,底層實(shí)現(xiàn)影藏的技術(shù),通過(guò)其和Block
相結(jié)合可以輕松實(shí)現(xiàn)多線程編程典徊。
你理解的多線程
- 多線程的原理
同一時(shí)間恩够,CPU只能處理1條線程,只有1條線程在工作(執(zhí)行) 多線程并發(fā)(同時(shí))執(zhí)行羡铲,其實(shí)是CPU快速地在多條線程之間調(diào)度(切換) 如果CPU調(diào)度線程的時(shí)間足夠快蜂桶,就造成了多線程并發(fā)執(zhí)行的假象 思考:如果線程非常非常多,會(huì)發(fā)生什么情況?
CPU會(huì)在N多線程之間調(diào)度也切,CPU會(huì)累死扑媚,消耗大量的CPU資源 每條線程被調(diào)度執(zhí)行的頻次會(huì)降低(線程的執(zhí)行效率降低)
- 多線程的優(yōu)點(diǎn)
能適當(dāng)提高程序的執(zhí)行效率 能適當(dāng)提高資源利用率(CPU、內(nèi)存利用率)
- 多線程的缺點(diǎn)
開啟線程需要占用一定的內(nèi)存空間(默認(rèn)情況下雷恃,主線程占用1M疆股,子線程占用 512KB),如果開啟大量的線程倒槐,會(huì)占用大量的內(nèi)存空間旬痹,降低程序的性能
線程越多,CPU在調(diào)度線程上的開銷就越大 程序設(shè)計(jì)更加復(fù)雜:比如線程之間的通信讨越、多線程的數(shù)據(jù)共享
簡(jiǎn)單說(shuō)說(shuō)TCP和UDP的理解
這兩個(gè)工作在TCP/IP協(xié)議傳輸層的兩個(gè)不同的協(xié)議两残,是用來(lái)傳輸數(shù)據(jù)用的。
TCP:(Transmission Control Protocol)和UDP(User Datagram Protocol)屬于傳輸層協(xié)議把跨。這是一個(gè)全雙工的人弓、面向連接的、可靠的并且是精確控制的協(xié)議着逐。
- 主要應(yīng)用在那些實(shí)用性不強(qiáng)票从,但要求不能出錯(cuò)的地方。比如網(wǎng)頁(yè)瀏覽滨嘱,文件下載峰鄙,文件收發(fā)。
UDP:(User Datagram protocol)是面向數(shù)據(jù)報(bào)的運(yùn)輸層協(xié)議太雨。是一個(gè)不可靠的傳輸協(xié)議吟榴。
- 不關(guān)心傳輸數(shù)據(jù)段到達(dá)的目的方的順序,所以不可靠囊扳。開銷比
TCP
小很多吩翻。比如及時(shí)通訊,視頻锥咸,語(yǔ)音狭瞎。
兩者的區(qū)別和聯(lián)系:
區(qū)別:TCP是面向連接的可靠的傳輸控制協(xié)議,UDP是面向非連接的用戶數(shù)據(jù)協(xié)議搏予。
聯(lián)系:TCP(三次握手保證相對(duì)可靠性)可傳大量數(shù)據(jù)熊锭,速度相對(duì)比較慢,UDP一次性傳輸少量對(duì)可靠性要求不高的數(shù)據(jù),速度比較快
tcp一般用于音頻碗殷、視頻等數(shù)據(jù)的傳輸精绎,資源能耗比較小,對(duì)可靠性要求不高锌妻,即使丟失一兩條數(shù)據(jù)也不會(huì)產(chǎn)生太大影響代乃。
什么是“三次握手”:
是指建立一個(gè)TCP連接時(shí),需要客戶端和服務(wù)器總共發(fā)送3個(gè)包仿粹。三次握手的目的是連接服務(wù)器指定端口搁吓,建立TCP連接,并同步連接雙方的序列號(hào)和確認(rèn)號(hào)并交換 TCP 信息。
介紹APP啟動(dòng)過(guò)程吭历,如果啟動(dòng)比較耗時(shí)是否有優(yōu)化的方法
APP啟動(dòng)過(guò)程
1. 解析Info.plist
- 加載相關(guān)信息堕仔,如閃屏
- 沙箱建立,權(quán)限檢查
2. Mach-O加載
- 如果是胖二進(jìn)制毒涧,尋找合適CUP類別的部分
- 加載所有依賴Mach-O文件
- 定位內(nèi)部贮预,外部指針引用贝室,如字符串契讲,函數(shù)
- 執(zhí)行聲明函數(shù)
- 加載擴(kuò)展類
- C++靜態(tài)對(duì)象加載,調(diào)用Objc的+(load)函數(shù)
3. 程序執(zhí)行
- main函數(shù)
- 執(zhí)行UIApplicationMain函數(shù)
- UIApplicationDelegate對(duì)象開始處理監(jiān)聽事件
APP啟動(dòng)緩慢滑频,想到的因素
- main( ) 函數(shù)內(nèi)有耗時(shí)操作
- 動(dòng)態(tài)庫(kù)加載太多
rootViewControlle
以及childViewController
的加載捡偏,view
和subViews
的加載耗時(shí)
優(yōu)化
- 移除不需要用到的動(dòng)態(tài)庫(kù)
- 移除不需要用到的類
- 合并功能類似的類和擴(kuò)展(Category)
- 壓縮圖片資源
- 優(yōu)化
applicationWillFinishLaunching
- 優(yōu)化
rootViewController
加載
設(shè)計(jì)模式
MVC:
MVC(Model View Controller):模型(model)-視圖(view)-控制器(controller)
- M(Model):實(shí)際上考慮的是什么的問題,你程序本質(zhì)上是什么峡迷,獨(dú)立于
UI
工作银伟,是程序中用于處理應(yīng)用邏輯的部分,通常賦值存取數(shù)據(jù)绘搞。 - C(Controller):控制你的數(shù)據(jù)(Model)如何顯示在屏幕上彤避,他需要數(shù)據(jù)的時(shí)候會(huì)告訴Model,你幫我獲取數(shù)據(jù)夯辖,當(dāng)他需要如何展示界面的時(shí)候和更新界面的時(shí)候他告訴V(View)琉预,是V和M之間的溝通橋梁。
- V(View):是
Controller
的使用類蒿褂,用于構(gòu)建視圖圆米。通常根據(jù)Model
來(lái)創(chuàng)建。
MVC的優(yōu)點(diǎn)
- 低耦合性
視圖層和業(yè)務(wù)層分離啄栓,這樣就允許更改視圖層代碼而不用重新編譯模型和控制器代碼娄帖,同樣,一個(gè)應(yīng)用的業(yè)務(wù)流程或者業(yè)務(wù)規(guī)則的改變只需要改動(dòng)MVC的模型層即可昙楚。因?yàn)槟P团c控制器和視圖相分離近速,所以很容易改變應(yīng)用程序的數(shù)據(jù)層和業(yè)務(wù)規(guī)則。
- 高重用性和可適用性
由于模型返回的數(shù)據(jù)沒有進(jìn)行格式化,所以同樣的構(gòu)件能被不同的界面使用数焊。例如永淌,很多數(shù)據(jù)可能用HTML來(lái)表示,但是也有可能用WAP來(lái)表示佩耳,而這些表示所需要的命令是改變視圖層的實(shí)現(xiàn)方式遂蛀,而控制層和模型層無(wú)需做任何改變。
- 較低的生命周期成本
MVC使開發(fā)和維護(hù)用戶接口的技術(shù)含量降低干厚。
- 可維護(hù)性
分離視圖層和業(yè)務(wù)邏輯層也使得應(yīng)用更易于維護(hù)和修改李滴。
總結(jié)優(yōu)點(diǎn):提高代碼的可讀性和可移植性,降低耦合度蛮瞄,提高內(nèi)聚所坯,大大提高開發(fā)的效率。
MVC的缺點(diǎn):
對(duì)于一些接單的界面額外的增加復(fù)雜性挂捅,視圖與控制器間的過(guò)于緊密的連接芹助。不適合中小型APP的開發(fā),會(huì)額外增加開發(fā)成本闲先。
V向C發(fā)消息:
- target-action:C會(huì)在自己的內(nèi)部“懸掛”一個(gè)目標(biāo)(target)状土,可能屏幕上是一個(gè)按鈕,當(dāng)按鈕被點(diǎn)擊時(shí)伺糠,
action
就會(huì)被發(fā)送給與之對(duì)應(yīng)的target
蒙谓,這樣V和C就有了交流。 - delegate(代理):
delegate
在上圖中是黃色的箭頭训桶,C把自己設(shè)置為V的委托(delegate),它讓V知道累驮,如果該顯示什么,就給C發(fā)delegate
消息舵揭。 - datasource(數(shù)據(jù)源):當(dāng)V需要顯示數(shù)據(jù)的時(shí)候谤专,他將需要?jiǎng)e人的幫助將數(shù)據(jù)傳遞給他,這就是數(shù)據(jù)源了午绳。
- Notification & KVO:一種類似電臺(tái)的方法置侍,Model信息改變時(shí)會(huì)廣播消息給感興趣的人。
架構(gòu)設(shè)計(jì):
建議可以從以下幾個(gè)方面回答
- 網(wǎng)絡(luò)層的設(shè)計(jì)方案
- 本地持久化方案
-
View
層組織和調(diào)用方案
APP好的架構(gòu)的評(píng)判標(biāo)準(zhǔn)
- 代碼整齊,分類明確
- 易擴(kuò)展耕漱,方便測(cè)試
- 沒有橫向依賴算色,不到萬(wàn)不得已沒有跨層訪問
- 接口少,統(tǒng)一螟够,參數(shù)少
- 高性能
- 思路與方法上統(tǒng)一保持一致
說(shuō)下MD5 base64以及AES加密
MD5:Message Digest Algorithm 5
MD5
是iOS中比較常見的加密方法之一灾梦,其特點(diǎn)有一下幾點(diǎn)
加密的不可逆性峡钓,只能夠加密,不能夠解密若河。
明文加密后長(zhǎng)度都是固定的能岩,長(zhǎng)度為16進(jìn)制32位。
AES加解密:相較于DES和3DES算法而言萧福,AES算法有著更高的速度和資源使用效率拉鹃,安全級(jí)別也較之更高了。
AES使用的是對(duì)稱加密.所謂對(duì)稱加密就是加解密雙方使用的密鑰相同.因此通過(guò)一種保密的方法讓客戶端與服務(wù)器擁有該密鑰,即可成功使用加解密鲫忍。
base64加密:使用64個(gè)字符來(lái)對(duì)任意數(shù)據(jù)進(jìn)行編碼膏燕。
- base64加密:
base64EncodedStringWithOptions
- base64解密:
initWithBase64EncodedString
如何防止反編譯
- 本地?cái)?shù)據(jù)加密:對(duì)
NSUserDefaults
和sqlite
等本地存儲(chǔ)數(shù)據(jù)加密 - URL編碼加密:對(duì)程序中出現(xiàn)的
URL
進(jìn)行加密,防止URL
被靜態(tài)分析 - 網(wǎng)絡(luò)傳輸加密:有效的防止數(shù)據(jù)接口攔截
- 程序結(jié)構(gòu)混排加密:把應(yīng)用程序的邏輯打亂悟民,將可讀性降到最低坝辫。
3.第三部分的是對(duì)項(xiàng)目中具體某個(gè)功能點(diǎn)的實(shí)現(xiàn)。
角色權(quán)限和分配射亏,是否做過(guò)單點(diǎn)登錄
在處理這類問題的時(shí)候近忙,角色權(quán)限和分配對(duì)后臺(tái)的依賴比較大。拿單點(diǎn)登錄來(lái)說(shuō):?jiǎn)吸c(diǎn)登錄SSO(Single Sign On)是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一智润。SSO的定義是在多個(gè)應(yīng)用系統(tǒng)中及舍,用戶只需要登錄一次就可以訪問所有相互信任的應(yīng)用系統(tǒng)。簡(jiǎn)單來(lái)說(shuō)單點(diǎn)登錄核心就是要解決做鹰,驗(yàn)證信任機(jī)制的有效性即存儲(chǔ)信任和驗(yàn)證信任击纬。如下優(yōu)缺點(diǎn)和三種實(shí)現(xiàn)方式
單點(diǎn)登錄優(yōu)點(diǎn)
- 提高用戶的效率鼎姐。
- 提高開發(fā)人員的效率钾麸。
- 簡(jiǎn)化管理。
單點(diǎn)登錄缺點(diǎn)
- 不利于重構(gòu)
- 無(wú)人看守桌面
1.以Cookie作為憑證媒介
最簡(jiǎn)單的單點(diǎn)登錄實(shí)現(xiàn)方式炕桨,是使用cookie作為媒介饭尝,存放用戶憑證。
用戶登錄父應(yīng)用之后献宫,應(yīng)用返回一個(gè)加密的cookie钥平,當(dāng)用戶訪問子應(yīng)用的時(shí)候,攜帶上這個(gè)cookie姊途,授權(quán)應(yīng)用解密cookie并進(jìn)行校驗(yàn)涉瘾,校驗(yàn)通過(guò)則登錄當(dāng)前用戶。
以上通過(guò)Cookie的方式實(shí)現(xiàn)單點(diǎn)登錄很容易發(fā)現(xiàn)弊端
- Cookie不安全
- 以及不能跨域
第一個(gè)
Cookie
不安全上我們可以通過(guò)加密等方式來(lái)避免泄露捷兰,但第二天跨域是硬傷立叛。
2.通過(guò)JSONP實(shí)現(xiàn)
相比較Cookie的方法,JSONP更好的在于解決了跨域問題贡茅,我們父應(yīng)用在登錄成功后把Session匹配的Cookie會(huì)存到應(yīng)用中秘蛇。當(dāng)用戶需要登錄子應(yīng)用的時(shí)候其做,授權(quán)應(yīng)用訪問父應(yīng)用提供的JSONP接口,并在請(qǐng)求中帶上父應(yīng)用域名下的Cookie赁还,父應(yīng)用接收到請(qǐng)求妖泄,驗(yàn)證用戶的登錄狀態(tài),返回加密的信息艘策,子應(yīng)用通過(guò)解析返回來(lái)的加密信息來(lái)驗(yàn)證用戶蹈胡。
雖然解決了跨域但是還是存在上一個(gè)方法一樣的弊端,就是信任機(jī)制的不安全性朋蔫,易泄露审残。
3.通過(guò)頁(yè)面重定向的方式
通過(guò)父應(yīng)用和子應(yīng)用來(lái)回重定向中進(jìn)行通信,解決信任機(jī)制的不安全性斑举,實(shí)現(xiàn)信息的安全傳遞搅轿。
父類提供一個(gè)登錄接口,用戶通過(guò)子應(yīng)用登錄連接訪問這個(gè)接口富玷,判斷如果用戶還未登錄璧坟,則返回登錄界面輸入賬號(hào)密碼登錄。如以及登錄則聲稱密碼Token赎懦,驗(yàn)證Token的接口雀鹃,檢驗(yàn)后是否登錄成功。
這個(gè)方法固然解決了跨域和安全兩個(gè)問題励两,但是相比較上兩種而言增加了登錄的復(fù)雜度黎茎。
4.博客,開源当悔。
開源的話傅瞻,推薦
GitHub
- github地址:RocketsChen歡迎
Star
和Follow
堅(jiān)持開源寫博客,對(duì)技術(shù)的提升還是很有幫助的盲憎,如果把平常項(xiàng)目開發(fā)中小技巧和問題記錄下來(lái)嗅骄,長(zhǎng)期積累下去也是一件有意義的事。