一、手機百度(搜索業務)
1.技術亮點、難點。
2.web加載渲染過程
3.組件化,路由和taget-action兩種方案的優劣
4.算法
a>判斷鏈表是否有環,一億個數
快慢指針,直到兩個指針相遇或者到達尾部
b>如何用100M的內存篩選出最小的100個數。
http://www.lxweimin.com/p/119c1ff5ea69
5.runloop線程保活(具體代碼是什么樣子的)
http://www.lxweimin.com/p/4d5b6fc33519
6.runloop監聽卡頓(具體代碼是什么樣子的)
http://www.lxweimin.com/p/ef2599f7251f
7.網路層的優化
要點 :dns緩存 弱網環境優化 包體積大小
域名合并:淘寶、美團等公司公布的解決方案中都有提到,就是將公司原來的很多域名都合并到較少的幾個域名。為什么?因為 HTTP 的通道復用就是基于域名劃分的。如果域名只有幾個,那么多數請求都可以在長連接通道進行,這樣就可以降低延遲、增加成功率
預熱,盡早建立長連接。這樣其他的業務請求就可以復用長連接通道。加快訪問速度。因為每次建立連接都需要經過 DNS 域名解析、TCP 三次握手等漫長步驟。建立長連接的時機可以考慮:冷啟動、前后臺切換、網絡切換等
如果情況允許,可以將網絡切換到 HTTP 2.0,解決了 HTTP1.1 的 head of blocking ,降低了網絡延遲,提供了更強大的多路復用技術。還加入了流量控制、新的二進制格式、Server Push、請求優先級和依賴等待等特性。
建立多通道。比如攜程、藝龍、美團等公司都有自己的 TCP、UDP 通道。具有多域名共用通道。
有些超級大廠還自研了協議。比如 QUIC
加入 CDN 加速,動態靜態資源分離
對于類似埋點的業務數據請求,可以合并請求,減小流量。另外結合埋點數據壓縮上傳
App 網絡情況診斷
根據網絡情況,動態設置超時時間等
https://zhuanlan.zhihu.com/p/115134324
8.包大小優化
https://blog.csdn.net/xj1009420846/article/details/80313566
9.啟動速度優化(runtime和dyld階段之間還有其他的)減少不必要的framework,因為動態鏈接比較耗時
check framework應當設為optional和required,如果該framework在當前App支持的所有iOS系統版本都存在,那么就設為required,否則就設為optional,因為optional會有些額外的檢查
合并或者刪減一些OC類,關于清理項目中沒用到的類,使用工具AppCode代碼檢查功能,查到當前項目中沒有用到的類如下:
image
刪減一些無用的靜態變量
刪減沒有被調用到或者已經廢棄的方法
方法見:http://stackoverflow.com/questions/35233564/how-to-find-unused-code-in-xcode-7
https://developer.Apple.com/library/ios/documentation/ToolsLanguages/Conceptual/Xcode_Overview/CheckingCodeCoverage.html
將不必須在+load方法中做的事情延遲到+initialize中
盡量不要用C++虛函數(創建虛函數表有開銷)
main()調用之后的加載時間
在main()被調用之后,App的主要工作就是初始化必要的服務,顯示首頁內容等。而我們的優化也是圍繞如何能夠快速展現首頁來開展。 App通常在AppDelegate類中的- (BOOL)Application:(UIApplication *)Application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中創建首頁需要展示的view,然后在當前runloop的末尾,主動調用CA::Transaction::commit完成視圖的渲染。
而視圖的渲染主要涉及三個階段:
準備階段 這里主要是圖片的解碼
布局階段 首頁所有UIView的- (void)layoutSubViews()運行
繪制階段 首頁所有UIView的- (void)drawRect:(CGRect)rect運行
再加上啟動之后必要服務的啟動、必要數據的創建和讀取,這些就是我們可以嘗試優化的地方
因此,對于main()函數調用之前我們可以優化的點有:
不使用xib,直接視用代碼加載首頁視圖
NSUserDefaults實際上是在Library文件夾下會生產一個plist文件,如果文件太大的話一次能讀取到內存中可能很耗時,這個影響需要評估,如果耗時很大的話需要拆分(需考慮老版本覆蓋安裝兼容問題)
每次用NSLog方式打印會隱式的創建一個Calendar,因此需要刪減啟動時各業務方打的log,或者僅僅針對內測版輸出log
梳理應用啟動時發送的所有網絡請求,是否可以統一在異步線程請求
http://www.lxweimin.com/p/7096478ccbe7
10.離屏渲染
runloop有個60fps回調,繪制內容交給GPU渲染,包括view拼接,紋理的渲染。
CPU計算好顯示內容提交到GPU,GPU渲染完成后將渲染結果放入幀緩沖區
1 當前屏幕渲染,指的是GPU的渲染操作是在當前用于顯示的屏幕緩沖區中進行
2 離屏渲染,指的是GPU在當前屏幕緩沖區以外新開辟一個緩沖區進行渲染操
3 重寫了drawRect方法,并且使用任何Core Graphics的技術進行了繪制操作,就涉及到了CPU渲染
4 CoreGraphic通常是線程安全的,所以可以進行異步繪制,顯示的時候再放回主線程
11.響應者鏈
- Initial view 嘗試著去處理事件或者消息。如果不能處理事件,它就遞交事件給superview,因為這個initial view并不是視圖控制器層級中得頂級view.
- 這個superview嘗試去處理該事件,如果superview不能處理該事件,它就遞交事件給它的父view,因為它也不是view層級的頂級view。
- 視圖控制器的頂級view嘗試著去處理該事件,如果連頂級view都不能處理該事件,它就遞交事件給它的controller。
- 這個viewcontroller嘗試著去處理該事件,并且如果它不能處理該事件,它就會遞交事件給window。
- 如果window不能處理該事件,它就遞交事件給singlegon app object(既UIApplication)
- 如果連application都不能處理該事件,那么毫無疑問該事件將會被丟棄。
響應事件+響應者鏈條(單向 從子控件到父控件)
UIAppliction --> UIWiondw -->遞歸找到最適合處理事件的控件-->控件調用touches方法-->判斷是否實現touches方法-->沒有實現默認會將事件傳遞給上一個響應者-->找到上一個響應者
用戶點擊屏幕后產生的一個觸摸事件,經過一些列的傳遞過程后,會找到最合適的視圖控件來處理這個事件
整個響應順序是從上到下再從下到上; 響應者鏈的響應事件是從下到上
如何找到合適控件處理事件 觸摸事件是從父控件傳遞到子控件
1 自己能否接收觸摸事件
2 觸摸點是否在自己身上
3 從后往前遍歷子控件 重復前面2個步驟
4 沒有合適的子控件 就自己做處理
二、快手
1.算法
a> 兩個數n、m 如果是n= 2 m=5,用遞歸實現2 3 4 5相加等于14;
public static int sum(int n1, int n2) {
if(n1 == n2) {
return n1;
}
if(n1 > n2) {
int temp = n1;
n1 = n2;
n2 = temp;
}
return sum(n1, n2-1) + n2;
}
2.weak和assign的區別
一、區別
1.修飾變量類型的區別
weak 只可以修飾對象。如果修飾基本數據類型,編譯器會報錯-“Property with ‘weak’ attribute must be of object type”。
assign 可修飾對象,和基本數據類型。當需要修飾對象類型時,MRC時代使用unsafe_unretained。當然,unsafe_unretained也可能產生野指針,所以它名字是"unsafe_”。
2.是否產生野指針的區別
weak 不會產生野指針問題。因為weak修飾的對象釋放后(引用計數器值為0),指針會自動被置nil,之后再向該對象發消息也不會崩潰。 weak是安全的。
assign 如果修飾對象,會產生野指針問題;如果修飾基本數據類型則是安全的。修飾的對象釋放后,指針不會自動被置空,此時向對象發消息會崩潰。
二、相似
都可以修飾對象類型,但是assign修飾對象會存在問題。
三、總結
assign 適用于基本數據類型如int,float,struct等值類型,不適用于引用類型。因為值類型會被放入棧中,遵循先進后出原則,由系統負責管理棧內存。而引用類型會被放入堆中,需要我們自己手動管理內存或通過ARC管理。
weak 適用于delegate和block等引用類型,不會導致野指針問題,也不會循環引用,非常安全。
3.weak原理(很細致,具體到如何查找的)
1、調用objc_release
2、因為對象的引用計數為0,所以執行dealloc
3、在dealloc中,調用了_objc_rootDealloc函數
4、在_objc_rootDealloc中,調用了object_dispose函數
5、調用objc_destructInstance
6、最后調用objc_clear_deallocating。
https://blog.csdn.net/future_one/article/details/81606895
4.autoreleasePool 的結構和自動釋放池中的對象存儲過程,autoreleasePool的結構。(比較細致的問了一遍過程)
關鍵字:結構體 parent和child 雙向鏈表
http://www.lxweimin.com/p/58dab9c28a12
5.objc_msgSend()經歷的過程,具體到cache_t結構和具體hashmap的查找方法。動態解析和消息轉發要說具體的方法名稱。
objc_msgSend匯編部分僅僅完成很少的緩存查找功能,如果找不到就會調用C方法去對象的方法二維數組中找,找不到再查父類的緩存(這也是匯編實現的)和父類的方法數組,一直找到根類,如果此過程中找到對應的方法則調用并添加緩存,如果沒有找到,則表明該繼承體系都沒有直接實現該方法,這時runtime會調用對象的方法決議去嘗試解決。如果不行則由CoreFoundation框架提供的forwarding來轉發到其他對象處理,若還不能處理則拋出異常。
http://www.lxweimin.com/p/75a4737741fd
6.block的捕獲機制,block類型的區分,__block做了什么,__block修飾對象類型和基本數據類型的區別。
https://blog.csdn.net/DreamcoffeeZS/article/details/102257488
https://blog.csdn.net/DreamcoffeeZS/article/details/102475351
7.load()和initialize()區別
<meta charset="utf-8">
調用方式
1、load是根據函數地址直接調用
2、initialize是通過objc_msgSend調用
調用時刻
1、load是runtime加載類、分類的時候調用(只會調用一次)
2、initialize是類第一次接收到消息的時候調用, 每一個類只會initialize一次(如果子類沒有實現initialize方法, 會調用父類的initialize方法, 所以父類的initialize方法可能會調用多次)
load和initializee的調用順序
1、load:
先調用類的load, 在調用分類的load
先編譯的類, 優先調用load, 調用子類的load之前, 會先調用父類的load
先編譯的分類, 優先調用load
2、initialize
先初始化分類, 后初始化子類
通過消息機制調用, 當子類沒有initialize方法時, 會調用父類的initialize方法, 所以父類的initialize方法會調用多次
8.圖層方法兩倍形變后,frame和bouns的變化,相對位置,絕對位置。
三、快手二面
1.算法
a>爬樓梯,動態規劃,是否可以優化空間復雜度
b>一面時面試題的變種
2.__strong和__weak的區別
3.strong和copy的區別
4.看代碼(題目較多)
5.項目中重要的技術點
6.實現線程同步方案的幾種方式的優缺點
四、探探/網易有道
1、算法
a> LRU(最近最少使用次數、最近最晚使用)
https://blog.csdn.net/elricboa/article/details/78847305
b>哈希沖突
開放定址法 拉鏈法
https://blog.csdn.net/xtzmm1215/article/details/47177701
c>哈希表以對象為鍵,怎么處理
2.A,B,C三個線程 打印array中元素,【1,2,3,4……100】,A線程打印1,B打2,C打3,A打4,依次打印。
http://www.lxweimin.com/p/40078ed436b4
3.kvo監聽一個weak修飾的屬性,當對象釋放的時候,kvo回調方法會被釋放嗎
kvo作為一個中間對象,在當前控制器銷毀時任然會存在,所以在銷毀時應該移除當前觀察釋放kvo對象
4.100*100像素的圖片在內存中的大小,
一個像素是RGB + alpha 一個是16位,所以是100 * 100 * 4 *16 位
5.看代碼的題目比較多
五、美團
1.block對mutablearray 修改需要用__block嗎?對block的捕獲是深拷貝還是淺拷貝?
淺拷貝,可以在block中修改數組中的元素
2.GCD和operation的區別
3.GCD是如何實現線程調度的
https://blog.csdn.net/zhangshichi/article/details/51161245
3.1GCD怎么實現線程同步的
組隊列(dispatch_group) 阻塞任務(dispatch_barrier)
http://www.lxweimin.com/p/81576172ad1f
4.線程同步的方案,
5.鎖有哪些,有什么區別
6.讀寫鎖實現的原理
7.內存管理的理解
8.方法查找
9.MVC和MVVM的區別
10.項目架構
11.autoreleasePool
12.autoreleasePool和runloop的關系
13.實際開發中autoreleasePool的作用以及應用
14.kvo底層原理
檢查對象的類有沒有相應的 setter 方法。如果沒有拋出異常;
檢查對象 isa 指向的類是不是一個 KVO 類。如果不是,新建一個繼承原來類的子類,并把 isa 指向這個新建的子類;
檢查對象的 KVO 類重寫過沒有這個 setter 方法。如果沒有,添加重寫的 setter 方法;
添加這個觀察者
http://www.cocoachina.com/articles/11321
15.哈希沖突的解決方案
16.循環引用的原因,舉例說明
http://www.lxweimin.com/p/3ffa8bc19cbe
17.線程導致死鎖的原因,舉例說明
互斥條件 請求和保持條件 不剝奪條件 環路等待條件
18.weak和strong的區別,和assign的區別
19.llvm的編譯流程
http://www.lxweimin.com/p/333cf1c02a0e
20.對swift和oc的區別
21.跨平臺技術的了解
六、知乎
1.組件化拆分的過程問答的很細致,以及拆完組件化是否還有可以優化的
2.包體積優化
3.啟動優化
4.dyld階段的細節
5.autoreleasepool和線程有什么關系
6.數組中有1萬個數字,如果刪除某一個元素,得到一個新的數組,怎么判斷出刪除的是幾???
7.手觸摸到屏幕,整個事件的響應全過程。
8.用協議實現一個一對多的通知效果
9.判斷鏈表是否有環,且環是多少個節點
10.用棧實現一個數組的增刪改查
11.設計上報日志的庫
12.抽象工廠和工廠有什么區別
七、騰訊(個人覺得面試官實力有點差)
1.引用計數的理解?系統為什么這么設計
2.runloop和autoreleasepool的關系,子線程創建的時候需要些一個autoreleasepool嗎,為什么?
3.webView和WKWebView的區別
4.實現多線程的方式,各有什么優缺點
多線程有多種實現方式,常見的有以下三種:
1、繼承Thread類,重寫run()方法。
1) 定義Thread類的子類,并重寫該類的run()方法,該run()方法的方法體就代表了線程要完成的任務。因此把run()方法稱為執行體。
2)創建Thread子類的實例即創建了線程對象。
3)調用線程對象的start()方法啟動線程。
2、實現Runnable接口,重寫run()方法。
1)定義Runnable接口的實現類,并重寫該方法的run()方法,該run()方法同樣是該線程的執行體。
2)創建Runnable實現類的實例,并依此實例作為Thread的target來創建Thread對象,該Thread對象才是真正的線程對象。
3)調用線程對象的start()方法啟動線程。
3、通過實現Callable接口和使用FutureTask包裝器來實現線程。
1)創建Callable接口的實現類,并實現call()方法,該call()方法的方法體同樣是該線程的執行體。
2)創建Callable實現類的實例,使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了該Callable對象的call()方法的返回值。
3)使用FutureTask對象作為Thread對象的target創建并啟動新線程。
4)調用FutureTask對象的get()方法來獲得子線程執行結束后的返回值。
三種實現方式的優缺點對比:
1、實現Runnable和Callable接口方式:
優點:
1)線程類只是實現了Runnable接口(JDK1.0開始)或Callable接口(JDK1.5開始),還可以繼承其他類。
2)多線程可以共享同一個target對象,非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數據分開,形成清晰的模型,較好地體現了面向對象的思想。
3)實現Callable接口創建多線程最大的好處是可以有返回值。
缺點:
編程稍顯復雜,如果要訪問當前線程,則必須使用Thread.currentThread()方法。
2、使用繼承Thread類方式:
優點:
編寫簡單,如果要訪問當前線程無需使用Thread.currentThread()方法,直接使用this即可獲得當前線程。
缺點:
線程類已經繼承了Thread類,不能再繼承其他類(java的單繼承性),因此該方式不夠靈活。
補充說明:
1)Callable規定重寫call()方法;Runnable重寫run()方法。
2)Callable的任務執行結束后可有返回值;Runnable的任務是不能有返回值的。
3)call()方法可以拋出異常;run()方法不可以。
4)運行Callable任務可以拿到一個Future對象,表示異步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,并檢查計算的結果。通過Future對象可以了解任務執行情況,可取消任務的執行,可以獲取執行結果。
5.iOS如何實現多繼承,代碼書寫一下。
代理 消息轉發
動態方法解析:向當前類發送resolveInstanceMethod: 信號,檢查是否動態向該類添加了方法
快速消息轉發:檢查該類是否實現了 forwardingTargetForSelector: 方法,若實現了則調用這個方法,若該方法返回nil或者非self,則向該返回對象重新發送消息
標準消息轉發:runtime發送methodSignatureForSelector:消息獲取Selector對應的方法簽名。返回值非空則通過forwardInvocation:轉發消息,返回值為空則向當前對象發送doesNotRecognizeSelector:消息,程序崩潰退出.
6.創建子線程需要創建一個autoreleasepool嗎?
https://blog.csdn.net/qq_22389025/article/details/85162240?utm_medium=distribute.pc_relevant.none-task-blog-title-1&spm=1001.2101.3001.4242
不需要,但是他說如果不出創建autoreleasepool對象,如果有autorelease修飾的對象會有警告,簡直是胡扯。
7.為什么不能在子線程刷新UI
http://www.lxweimin.com/p/5849eb69ec82
8.一個imageView在屏幕中顯示的整個過程,那些步驟可以放在子線程,那些要在主線程執行
1. 百度
- 一面
- MVC、MVP、MVVM的區別,使用場景
- NSLayout、Masonry、SpanKit的區別,使用場景
- ARC內存管理機制
- 對Runtime的了解
- 對Runloop的了解
- 項目中遇到的困難
- 性能優化
- App體積優化
- 啟動時間優化
- 離職原因
- 你開發的SDK的使用量
- 用Python做過什么
- 對開發的這個App有沒有自己的看法
- 最近看了什么書
- 發展方向(職業規劃)
- 對百度地圖了解嗎
- 對加班的看法
- 你想問的問題
- 有其他公司的offer嗎
- 想問的問題
- 二面
- 談談你做的自動化測試
- GCD的幾個題目做一下
- 子線程中創建NSTimer會執行嗎
- 在dealloc中釋放NSTimer會怎樣
- NSNoticationCenter不釋放監聽者著會怎樣
- 自動釋放池什么時候釋放
- Runloop何時退出
- 互斥鎖、自旋鎖
- NSLock、遞歸所、讀寫鎖的區別和使用場景
- 看過哪些源碼
- NSNoticationCenter的實現原理,如何自定義
- KVO原理
- 手寫:字符串中尋找是否出現了重復的字符
- 兩層循環
- hash
- 設計hash表
- 想問的問題
- 三面
- 項目架構
- 職業規劃
- 遇到的困難
- 對項目的貢獻
- 離職原因
- 如何看待加班
- 和同事有矛盾如何解決
- 你的優點
- 你的缺點
- 想問的問題
2. 騰訊
- 一面
- 談談你做的自動化測試
- Block中捕獲全局、靜態、實例、局部變量是怎樣實現的
http://www.lxweimin.com/p/ee9756f3d5f6
自動變量是以值傳遞方式傳遞到Block的構造函數里面去的。Block只捕獲Block中會用到的變量。由于只捕獲了自動變量的值,并非內存地址,所以Block內部不能改變自動變量的值。Block捕獲的外部變量可以改變值的是靜態變量,靜態全局變量,全局變量。 - ARC內存管理機制
- Runloop
- Runtime
- 性能優化
- App體積優化
- 啟動時間優化
- 動/靜態庫分別在哪里占用了時間?
- 項目中遇到的困難
- 字符串轉數字
- 你想問的問題
3. 富途
- 一面
- ARC內存管理機制
- Runloop
- Runtime
- 性能優化
- App體積優化
- 啟動時間優化
- KVO原理
- struct和class的區別
- swift協議
- 手寫快排
- 手寫,數組[1,0,3,0,4,0,0,-2],將0放在數組最前面且不影響非0值的順序
- 手寫翻轉二叉樹
- 繩子粗細不均勻,但燒完一定需要60分鐘,如何燒出45分鐘。
- 想問的問題
- 二面
- 啟動時間優化
- 結構體 { char int int } 占用多少字節,內存對齊是什么
- int a = 0, 兩個線程中各加十次,a=多少,為什么,a的范圍是多少?
- 員工表,18年3月-18年8月工資少發了,現在需要對其補發,手寫SQL
- 25個人有5個跑道,求出最快的三個人,至少需要比賽多少次
- 有2個玻璃珠和100層樓,玻璃珠摔壞了則無法二次使用,求玻璃球能承受的最大高度,至多需要多少次測試。
- 1000瓶水,1瓶有毒,老鼠喝水后3天死亡,給3天時間,求至少需要多少只老鼠。
- 手寫二叉搜索樹插入函數
- 求無序數組中最大的K個數
- 想問的問題
4. 有贊
- 一面
- Runloop
- Runtime
- 消息轉發機制
- 事件傳遞機制
- 性能優化
- App體積優化
- 啟動時間優化
- KVO原理
- 組件化
- 職業規劃
- 想問的問題
- 二面
- 你做了什么功能,畫出并解釋流程圖和項目結構
- 你的職業規劃
- 想問的問題
- 三面
- 項目架構
- 你的職業規劃
- 想問的問題
5. 方直
- 一面
- Runtime
- Runloop
- 性能優化
- App體積優化
- 啟動時間優化
- 啟動流程
- KVO原理
- 事件傳遞機制
- 消息轉發機制
- 自動釋放池內部實現
- Storyboard、classify
- 想問的問題
- 二面
- 性能優化
- 項目架構
- 你能為公司帶來什么
- 你的價值
- 你的職業規劃
- 想問的問題
6. TCL
- 一面
- Runloop
- Runtime
- OC底層結構
- 消息轉發機制
- 事件傳遞機制
- 性能優化
- App體積優化
- 啟動時間優化
- 啟動流程
- KVO原理
- 組件化
- load和initlize的區別
- 兩個相同的油漆桶,一個紅色一個藍色,一個勺子,使用勺子從紅桶挖一勺到藍桶并攪拌均勻,此時從藍桶挖一勺到紅桶攪拌均勻,問紅桶中的紅藍比和藍桶中的藍紅比是怎樣的
- 手寫歸并排序
- 想問的問題
- 二面
- 性能優化
- App體積優化
- 啟動時間優化
- 組件化
- 項目的產品角度
- 項目架構
- 想問的問題
7. 編程貓
- 一面
- Runloop
- 性能優化
- App體積優化
- 啟動時間優化
- 啟動流程
- KVO原理
- 暗黑模式適配
- 了解哪些設計模式
- 一個按鈕會觸發網絡加載然后更新列表,用MVVM說思路
- RAC的冷信號和熱信號區別
- 說說自動化測試
- Bugly解決不了的異常,怎么處理的
- atomic, weak
- 鏈表和數組的區別,隊列和棧的區別
- SwiftUI
- 想問的問題
8. 抖音
- 一面
- 說一個你做的App有什么功能
- 說一說用到了AVFoundation的哪些功能
- AVFoundation相機代理的視頻流返回的圖片是什么格式,如何顯示在屏幕上
- KVO原理
- struct和class的區別,如果for循環1000次struct會怎樣
- unowned和weak的區別
- NSTimer準嗎,不準的話會延時調用嗎,如何解決
- AutoRelease對象什么時候釋放
- Runloop什么時候釋放
- Runloop干了什么
- 自動釋放對象在Runloop的哪個階段釋放
- 野指針如何產生的
- 使用Block時,為什么會使用__strong或__weak
- 離屏渲染是什么,如何產生的,如何解決
- 屏幕上的內容是如何顯示的,卡頓是如何產生的,如果解決
- 以對角線順序打印二維數組
- 想問的問題
9. 隨手
- 一面
- Runloop
- Runtime
- OC底層結構
- 消息轉發機制
- 事件傳遞機制
- 性能優化
- App體積優化
- 啟動時間優化
- 啟動流程
- KVO原理
- 英文筆試題:給NSString添加一個分類,實現將其轉換為NSNumber
- 英文筆試題:如何產生循環引用
- 英文筆試題:設計低耦合的<花開蜂猜謎,花閉蜂回家>
- 英文筆試題:尋找數組中出現次數最多的數值的和
- 想問的問題
- 二面
- 消息轉發機制
- 事件傳遞機制
- 性能優化
- App體積優化
- 啟動時間優化
- 組件化
- 向我解釋什么是GCD,假設我不懂iOS。
- 職業規劃
- 想問的問題