面試記錄
提到以下問題:
- 線程死鎖是什么果复?什么樣的情況會造成死鎖?如何確保不會發(fā)生死鎖渤昌?
在串行隊列中,執(zhí)行 A 時同步調(diào)度一個任務(wù) B 會造成 AB 之間互相等待走搁,造成死循環(huán)独柑;
syncSerialBlock
{
dispatch_queue_t queue = dispatch_queue_create("yanhooQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
// 這里阻塞了
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
});
}
/// 或者
-(void)syncMain
{
// 獲得主隊列
dispatch_queue_t queue = dispatch_get_main_queue();
// 這里阻塞了
dispatch_sync(queue, ^{
NSLog(@"1-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2-----%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3-----%@", [NSThread currentThread]);
});
}
> 不要在串行隊列(先進(jìn)先出)中同步調(diào)度任務(wù),可以避免死鎖私植。
- 如何監(jiān)測 App 中主線程上某些操作占用耗時過長忌栅?Instruments 使用起來很麻煩,如何監(jiān)測并上報內(nèi)存和幀率異常情況曲稼,如何優(yōu)化索绪?
監(jiān)測 UI 線程卡頓可以參考此文:http://mrpeak.cn/blog/ui-detect/
啟動性能的優(yōu)化:https://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653579242&idx=1&sn=8f2313711f96a62e7a80d63851653639
以下代碼為獲取當(dāng)前內(nèi)存情況的實現(xiàn):
vm_size_t usedMemory(void) {
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes
}
vm_size_t freeMemory(void) {
mach_port_t host_port = mach_host_self();
mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
vm_size_t pagesize;
vm_statistics_data_t vm_stat;
host_page_size(host_port, &pagesize);
(void) host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size);
return vm_stat.free_count * pagesize;
}
void logMemUsage(void) {
// compute memory usage and log if different by >= 100k
static long prevMemUsage = 0;
long curMemUsage = usedMemory();
long memUsageDiff = curMemUsage - prevMemUsage;
if (memUsageDiff > 100000 || memUsageDiff < -100000) {
prevMemUsage = curMemUsage;
NSLog(@"Memory used %7.1f (%+5.0f), free %7.1f kb", curMemUsage/1000.0f, memUsageDiff/1000.0f, freeMemory()/1000.0f);
}
// 周期性獲取目前占用的內(nèi)存,設(shè)定閾值贫悄,如果較大瑞驱,記錄并上報堆棧信息
[NSThread callStackSymbols]);
}
///以下是幀率的獲取方法
let displayLink CADisplayLink(
target: urDelegate,
selector: #selector(urFunc)
)
//每幀刷新都會回調(diào) urFunc ,
func urFunc() {
if lastNotificationTime == 0.0 {
lastNotificationTime = CFAbsoluteTimeGetCurrent()
return
}
numberOfFrames += 1
let currentTime = CFAbsoluteTimeGetCurrent()
let elapsedTime = currentTime - self.lastNotificationTime
if elapsedTime >= self.notificationDelay {
let fps = Int(round(Double(self.numberOfFrames) / elapsedTime))
lastNotificationTime = 0.0
numberOfFrames = 0
print(fps) //幀率
}
}
-
中間人攻擊是什么窄坦?如何預(yù)防中間人攻擊唤反?
指攻擊者 C 與通訊的兩端 A凳寺、B分別建立獨立的聯(lián)系,欺詐 A彤侍、B 使通訊的兩端 A 肠缨、B認(rèn)為他們正在通過一個私密的連接與對方直接對話(A ? B),并交換其所收到的數(shù)據(jù)盏阶,但事實上整個會話都被攻擊者完全控制(A ? C ? B)晒奕。iOS 中,App 端保存一份公鑰證書名斟,進(jìn)行 HTTPS 的 SSL 通信建立時脑慧,比對服務(wù)器提供的公鑰證書與本地是否一致,不一致拒絕蒸眠。
-
TCP 與 UDP 有什么區(qū)別漾橙? 如何保證網(wǎng)絡(luò)層使用 UDP 時應(yīng)用層的數(shù)據(jù)可達(dá)與完整性?
TCP 通信握手更多楞卡,通信可靠霜运;UDP 更簡單更快不需要握手,不可靠蒋腮,如果詳細(xì)比較 TCP 與 UDP 有很多不同淘捡,可以參照此文章 http://www.diffen.com/difference/TCP_vs_UDP
關(guān)于握手有一個笑話:
我想聽一個 TCP 的笑話。你好池摧,你想聽 TCP 的笑話么焦除?嗯,我想聽一個 TCP 的笑話作彤。好的膘魄,我會給你講一個TCP 的笑話。好的竭讳,我會聽一個TCP 的笑話创葡。你準(zhǔn)備好聽一個TCP 的笑話么?嗯绢慢,我準(zhǔn)備好聽一個TCP 的笑話Ok灿渴,那我要發(fā) TCP 笑話了。大概有 10 秒胰舆,20 個字骚露。嗯,我準(zhǔn)備收你那個 10 秒時長缚窿,20 個字的笑話了棘幸。抱歉,你的連接超時了倦零。你好够话,你想聽 TCP 的笑話么 蓝翰。過癮不,沒過癮再來一個我給你們講個UDP的笑話吧女嘲,哈哈哈哈哈哈畜份。
有關(guān)實現(xiàn)可靠 UDP 可參照這里,我的實現(xiàn)思路類似欣尼,文末有同道的討論爆雹,僅供參考 http://blog.codingnow.com/2016/03/reliable_udp.html -
鎖的作用是什么?iOS 中有哪些鎖愕鼓?怎么使用钙态?
- NSLock
- NSConditionLock
- NSRecursiveLock
- NSCondition
- @synchronized http://yulingtianxia.com/blog/2015/11/01/More-than-you-want-to-know-about-synchronized/
- dispatch_semaphore GCD信號量邏輯
- OSSpinLock 自旋鎖 (因線程優(yōu)先級問題,Apple 已不推薦使用)
- pthread_mutex
使用方法菇晃,參照這里:
http://yulingtianxia.com/blog/2015/11/01/More-than-you-want-to-know-about-synchronized/
http://www.reibang.com/p/ddbe44064ca4 -
在慢速網(wǎng)絡(luò)與高丟包率網(wǎng)絡(luò)下保證請求結(jié)果的可靠性册倒?在運(yùn)營商屏蔽服務(wù)器時,如何解決 App 與 服務(wù)器通信磺送?
多次請求驻子,與后端合作合并部分請求,減少 request 的復(fù)雜度和大泄啦印崇呵;關(guān)鍵請求為了確保可達(dá)馅袁,可以先持久化域慷,萬一失敗從持久層恢復(fù)重試;失敗后通知用戶手動重試汗销,提示網(wǎng)絡(luò)質(zhì)量犹褒;一般的請求失敗也無妨。 如果在運(yùn)營商屏蔽服務(wù)時弛针,與運(yùn)營商聯(lián)系協(xié)商解決化漆,或采用其他云服務(wù)。
-
在需求多變的前提下钦奋,你會如何設(shè)計,使用什么樣的技術(shù)來保證高復(fù)用性與遠(yuǎn)端控制疙赠?
復(fù)雜場景 ReactNative付材、簡單場景 Hybrid、Native 的自定義 UI 控件封裝
-
SQLite 圃阳、CoreData厌衔、Realm 等數(shù)據(jù)庫技術(shù)如何取舍?如果一個數(shù)據(jù)庫很大捍岳,查詢性能很低富寿,如何改善這種情況睬隶,請設(shè)計一下表結(jié)構(gòu)?
數(shù)據(jù)庫是持久化的需求:最簡單的場景用 Plist 或簡單的文件存儲(JSON 页徐、XML等)苏潜;在 iOS 上平臺上單獨管理的可以考慮 CoreData;如果需要與安卓平臺共用數(shù)據(jù)庫可選用 SQLite 或 Realm 变勇;Realm 使用方便恤左,也可跨多平臺,并且專為移動平臺設(shè)計搀绣,查詢性能是 CoreData 和 SQLite 的五倍飞袋,但是多線程處理不好; SQLite 需要傳統(tǒng)數(shù)據(jù)庫基礎(chǔ)链患,但是與傳統(tǒng)數(shù)據(jù)庫兼容性好巧鸭,易于遷移。大數(shù)據(jù) A 抽出關(guān)鍵詞做成小數(shù)據(jù)庫 B麻捻,小數(shù)據(jù)庫與大數(shù)據(jù)采用一對一關(guān)系纲仍,B 中的每一條記錄都有 A 中的一條記錄與之匹配,A 中主鍵是關(guān)鍵字芯肤,鍵值是 B 的主鍵巷折,查詢時查詢小數(shù)據(jù)庫,然后再匹配 A 的主鍵崖咨。
數(shù)據(jù)庫的關(guān)系可以參照微軟此文:
https://technet.microsoft.com/en-us/library/ms190651(v=sql.105).aspx
Realm 與 CoreData 和 SQLite 的比較:
https://sebastiandobrincu.com/blog/5-reasons-why-you-should-choose-realm-over-coredata 你們在 App 開發(fā)中遇到什么難點锻拘?