- 簡要說一下
autoreleasePool
的數(shù)據(jù)結構
簡單說是
雙向鏈表
物蝙,每張鏈表頭尾相接泛豪,有parent械筛、child
指針捎泻,每創(chuàng)建一個池子,會在首部創(chuàng)建一個哨兵
對象作為標記埋哟,最外層池子的頂端會有一個next
指針笆豁。當鏈表容量滿了,就會在鏈表的頂端赤赊,并指向下一張表
- 說一下
autoreleasePool
的實現(xiàn)原理
autoreleasePool
是一個延時release
的機制闯狱,在自動釋放池被銷毀或耗盡時,會向池中的所有對象發(fā)送release
消息抛计,釋放所有autorelease
對象
autoreleasePool
并沒有單獨的結構哄孤,而是由若干個autoreleasePoolPage
作為結點以雙向鏈表
的形式組合而成
- 每一個指針代表一個加入到釋放池的
對象
或者是哨兵
對象,哨兵對象是在@autoreleasepool{}
構建的時候插入的- 當自動釋放池
pop
的時候吹截,所有哨兵對象之后的對象都會release
- 鏈表會在一個
Page
空間占滿時進行增加瘦陈,一個autoreleasePoolPage
的空間被占滿時凝危,會新建一個autoreleasePoolPage
對象連接鏈表,后來的autorelease
對象在新的page
加入
- 解釋一下三次握手和四次揮手
- 三次握手
- 由客戶端向服務端發(fā)送
SYN
同步報文- 當服務端收到
SYN
同步報文之后晨逝,會返回給客戶端SYN
同步報文和ACK
確認報文- 客戶端會向服務端發(fā)送
ACK
確認報文蛾默,此時客戶端和服務端的連接正式建立
- 四次揮手
- 先由客戶端向服務端發(fā)送
FIN
結束報文- 服務端會返回給客戶端
ACK
確認報文。此時捉貌,由客戶端發(fā)起的斷開連接已經(jīng)完成- 服務端會發(fā)送給客戶端
FIN
結束報文和ACK
確認報文- 客戶端會返回
ACK
確認報文到服務端支鸡,至此,由服務端方向的斷開連接已經(jīng)完成
拓展:
SYN
攻擊
在三次握手過程中趁窃,Server
發(fā)送SYN-ACK
之后苍匆,收到Client
的ACK
之前的TCP
連接稱為半連接half-open connect
,此時Server
處于SYN_RCVD
狀態(tài)棚菊,當收到ACK
后,Server
轉入ESTABLISHED
狀態(tài)叔汁。SYN
攻擊就是Client
在短時間內(nèi)偽造大量不存在的IP
地址统求,并向Server
不斷地發(fā)送SYN
包,Server
回復確認包据块,并等待Client
的確認码邻,由于源地址是不存在的,因此另假,Server
需要不斷重發(fā)直至超時像屋,這些偽造的SYN
包占用未連接隊列,導致正常的SYN
請求因為隊列滿而被丟棄边篮,從而引起網(wǎng)絡堵塞甚至系統(tǒng)癱瘓己莺。SYN
攻擊時一種典型的DDOS
攻擊
一般有兩種方式
1、客戶端惡意不發(fā)送ACK
2戈轿、在發(fā)送給服務器的SYN
報文段中提供虛假的IP
地址凌受,造成服務器永遠收不到ACK
- 一個
NSObject
對象占用多少內(nèi)存
一個指針變量所占用的大小,
64bit
占8
個字節(jié)思杯,32bit
占4
個字節(jié)
- 對象的
isa
指針指向哪里
instance
對象的isa
指針指向class
對象胜蛉,class
對象的isa
指針指向meta-class
對象,meta-class
對象的isa
指針指向基類的meta-class
對象色乾,基類自己的isa
指針也指向自己
-
OC
的類信息存放在哪里
成員變量的具體值存放在
instance
對象誊册,對象方法、協(xié)議暖璧、屬性案怯、成員變量信息存放在class
對象,類方法信息存放在meta-class
對象
- 為什么使用
runtime
技術中的關聯(lián)對象可以為類別添加屬性
關聯(lián)對象都由
AssociationsManager
管理澎办,AssociationsManager
里面是由一個靜態(tài)AssociationsHashMap
來存儲所有的關聯(lián)對象的殴泰。這相當于把所有對象的關聯(lián)對象都存在一個全局map
里面于宙。而map
的key
是這個對象的指針地址,而這個map
的value
又是另外一個AssociationsHashMap
悍汛,里面保存了關聯(lián)對象的kv
對
- 用過哪些鎖捞魁?哪些鎖的性能比較高?談下
Objective-C
都有哪些鎖機制离咐,你一般用哪個
常用的鎖有
NSLock谱俭、@synchronized代碼塊、信號量 dispatch_semaphore_t
os_unfair_lock
(推薦)
dispatch_semaphore
(推薦)
pthread_mutex
(推薦)
dispatch_queue(DISPATCH_QUEUE_SERIAL)
(推薦)
NSLock
()
NSCondition
()
@synchronized
(最不推薦)
信號量性能最高
@synchronized
代碼塊最方便
- 為什么一定要在主線程里面更新
UI
UIKit
不是線程安全的宵蛀,容易產(chǎn)生UI
更新上的混亂
- 類和結構體的區(qū)別
類是引用類型昆著,結構體是值類型。結構體變量分配在棧术陶,
OC
對象分配在堆凑懂。結構體只能封裝屬性,類不僅可以封裝屬性也可以封裝方法
- 引用和指針的區(qū)別
指針的本質(zhì)也就是變量梧宫,它不僅有自己的地址接谨,也有它所存放的值,只不過這個值是地址而已
引用也就是指針常量塘匣,它是一個對象的別名脓豪,既然初始化了所指向的地址,那么它一定不為空忌卤,而且地址不可變
引用必須被初始化扫夜,指針不必
引用初始化以后不能被改變,指針可以改變所指的對象
不存在指向空值的引用驰徊,但存在指向空值的指針
-
id
類型笤闯、nil
、Nil
棍厂、NULL
和NSNULL
的區(qū)別
id
類型是一個獨特的數(shù)據(jù)類型望侈,可以轉換為任何數(shù)據(jù)類型,id類型的變量可以存放任何數(shù)據(jù)類型的對象勋桶,id
聲明的對象具有運行時特性脱衙,可以指向任意類型的對象
nil
是一個實例對象值,如果我們要把一個對象設置為空的時候就用nil
Nil
是一個類對象的值例驹,如果我們要把一個class
的對象設置為空的時候就用Nil
NULL
指向基本數(shù)據(jù)類型的空指針C語言的變量的指針為空
NSNull
是一個對象捐韩,它用在不能使用nil
的場合
-
weak
的底層實現(xiàn)的原理是什么
weak
表其實是一個hash
哈希表,Key
是所指對象的地址鹃锈,Value
是weak
指針的地址數(shù)組
runtime
維護了一個weak
表荤胁,用于存儲指向某個對象的所有weak
指針,weak
表其實是一個hash
表屎债,Key
是所指對象的地址仅政,value
是weak
指針的地址數(shù)組
為什么value
是數(shù)組垢油?因為一個對象可能被多個弱引用指針指向
-
weak
原理實現(xiàn)步驟
weak
的實現(xiàn)原理可概括三步
- 初始化時:
runtime
會調(diào)用objc_initWeak
函數(shù),初始化一個新的weak
指針指向對象的地址- 添加引用時:
objc_initWeak
函數(shù)會調(diào)用objc_storeWeak()
函數(shù)圆丹,objc_storeWeak()
的作用是更新指針指向滩愁,創(chuàng)建對應的弱引用表- 釋放時,調(diào)用
clearDeallocating
函數(shù)辫封,clearDeallocating
函數(shù)首先根據(jù)對象地址獲取所有weak
指針地址的數(shù)組硝枉,然后遍歷這個數(shù)組把其中的數(shù)據(jù)設為nil
,最后把這個entry
從weak
表中刪除倦微,最后清理對象的記錄
- 編譯過程做了哪些事情
Objective妻味、Swift
都是編譯語言。編譯語言在執(zhí)行的時候欣福,必須先通過編譯器生成機器碼责球,機器碼可以直接在CPU
上執(zhí)行,所以執(zhí)行效率較高
Objective拓劝、Swift
二者的編譯都是依賴于Clang + LLVM
不管是OC
還是Swift
雏逾,都是采用Clang
作為編譯器前端,LLVM(Low level vritual machine)
作為編譯器后端
- 編譯器前端:編譯器前端的任務是進行語法凿将、語義分析,生成中間代碼价脾。在這個過程中會進行類型檢查牧抵,如果發(fā)現(xiàn)錯誤或者警告會標注出來在哪一行
- 編譯器后端:編譯器后端會進行機器無關的代碼優(yōu)化,生成機器語言侨把,并且進行機器相關的代碼優(yōu)化犀变。
LLVM
優(yōu)化器會進行BitCode
的生成,鏈接器優(yōu)化等等秋柄,LLVM
機器碼生成器會針對不同的架構获枝,比如arm64
等生成不同的機器碼
-
Linux
命令之-Strings
strings
命令是在對象文件或者二進制文件中查找可打印的字符串,常用來在二進制文件中查找字符串骇笔,與grep
配合使用省店,例如一個用法就是在編譯的so
中定義字符串常量作為動態(tài)庫的版本號,然后就可以使用strings+grep
組合命令查看當前編譯的so
的版本號了笨触。輸入strings -h
查看strings
命令的用法懦傍,下面為具體用法實例
strings /lib/tls/libc.so.6 | grep GLIBC
strings /Users/y**ar/Desktop/Demo2/Libraries/libiPhone-lib.a | grep "UIWebView"
cat /Users/y**ar/Desktop/Demo2/Libraries/libiPhone-lib.a
-
OC
格式化打印
%d
整數(shù)
%02d
表示不足2
位補0
%u
無符號整型
%f
浮點(雙字節(jié))
%.2f
精度浮點數(shù),只保留兩位小數(shù)
%x芦劣,%X
十六進制整數(shù)
%o
八進制整數(shù)
%p
指針
%s
C
字符串
%c
字符