2017年面試總結

1.Runtime的理解和項目運用
2.TableView的優(yōu)化

  • 正確使用reuseIdentifier來重用Cells
  • 盡量使所有的view 不透明,包括Cell自身
  • 盡量少用或不用透明圖層
  • 如果Cell內現(xiàn)實的內容來自web,使用異步加載,緩存請求結果
  • 減少subviews的數(shù)量
  • 在heightForRowAtIndexPath:中盡量不使用cellForRowAtIndexPath:,如果你需要用到它,只用一次然后緩存結果
  • 盡量少用addView給Cell動態(tài)添加View,可以初始化時就添加,然后通過hide來控制是否顯示
  • 提前計算并緩存好高度(布局),因為heightForRowAtIndexPath:是調用最頻繁的方法;
  • 異步繪制,遇到復雜界面,遇到性能瓶頸時,可能就是突破口;
  • 滑動時按需加載,這個在大量圖片展示,網(wǎng)絡加載的時候很管用!(SDWebImage已經(jīng)實現(xiàn)異步加載,配合這條性能杠杠的)。

3.二叉樹,快速排序,冒泡排序(實際應用題)
4.Socket是如何實現(xiàn)的
5.[[person alloc] init]內存棧結構問題
6.無限展開列表實現(xiàn)
7.大圖片資源分段加載問題,類似于地圖
8.核心動畫,Quartz2D
9.設計模式理解MVC MVVM MVP 項目運用

image.jpeg

10.手寫約束
11.ARC內存管理解實現(xiàn)
oc 中內存的管理主要依賴引用計數(shù),而對引用計數(shù)的影響又依賴修飾屬性,
①修飾屬性:
讀寫控制:
readwrite:可讀可寫,會生成getter和setter方法。
readonly:只讀,只會生成getter方法,不會生成setter方法。
引用方式:
copy:拷貝,復制一個對象并創(chuàng)建strong關聯(lián),引用計數(shù)為1 ,原來對象計數(shù)不變。
assign:賦值,不涉及引用計數(shù)的變化,弱引用。ARC中對象不能使用assign,但原始類型(BOOL、int、float)仍然可以使用。
retain:持有,對原對象引用計數(shù)加1,強引用。ARC中使用strong。
weak:賦值(ARC),比assign多了一個功能,對象釋放后把指針置為nil,避免了野指針。
strong:持有(ARC),等同于retain。
②修飾變量(修飾不使用@property 定義時,比如函數(shù)內的局部變量)
__strong:是缺省的關鍵詞,強引用。
__weak:聲明了一個可以自動置 nil 的弱引用(ARC 中)。
__unsafe_unretained:聲明一個弱引用,但是不會自動 nil 化(只有 iOS 4 才
應該使用)。
__autoreleasing:用來修飾一個函數(shù)的參數(shù),這個參數(shù)會在函數(shù)返回的時候被
自動釋放(類似 autorelease)。
(3)默認的引用計數(shù):
alloc:分配對象,分配后引用計數(shù)為 1。
autorelease:對象引用計數(shù)減 1,但如果為 0 不馬上釋放,等待最近一個 pool 時釋放。
12.第三方框架的版本號
13.最新在看哪些新技術,iOS版本特點,技術博客,自己多久會寫Demo
14.iOS消息轉發(fā)機制
15.git和SVN優(yōu)缺點
①GIT是分布式的,SVN是集中式
②GIT把內容按元數(shù)據(jù)方式存儲,而SVN是按文件
③GIT分支和SVN的分支不同
④GIT沒有一個全局的版本號,而SVN沒有
⑤GIT的內容完整性要優(yōu)于SVN

16.數(shù)據(jù)庫多表查詢,sqlite和coredata優(yōu)缺點 sqlite語句
①sqlite語句

//建表語句:
CREATE TABLE IF NOT EXISTS t_class (id integer primary key autoincrement ,name text, age integer);
//刪除表:
drop table if exists t_person;
//插入數(shù)據(jù) 字符串使用''括住.
INSERT INTO t_class (name ,age) values ('hm13' ,7);
//更新數(shù)據(jù)
UPDATE t_class SET name = 'lisi' WHERE age < 8; 
//刪除數(shù)據(jù)
DELETE FROM t_class WHERE name = 'zhangsan';
//查詢數(shù)據(jù)
SELECT name , age  FROM t_class  WHERE age > 6 LIMIT 5;

②多表查詢
外連接可分為:左連接、右連接、完全外連接。

左連接  left join 或 left outer join
右連接  right join 或 right outer join
完全外連接  full join 或 full outer join
內連接  join 或 inner join
交叉連接 cross join

17.什么時候用到單例

第一、基本概念 單例模式是一種常用的軟件設計模式。在它的核心結構中只包含一個被稱為單例類的特殊類。通過單例模式可以保證系統(tǒng)中一個類只有一個實例而且該實例易于外界訪問。

第二、在IOS中使用單例模式的情況

1.如果說創(chuàng)建一個對象會耗費很多系統(tǒng)資源,那么此時采用單例模式,因為只需要一個實例,會節(jié)省alloc的時間

2.在IOS開發(fā)中,如果很多模塊都要使用同一個變量,此時如果把該變量放入單例類,則所有訪問該變量的調用變得很容易,否則,只能通過一個模塊傳遞給另外一個模塊,這樣增加了風險和復雜度

第三、創(chuàng)建單例模式的基本步驟

1.聲明一個單例對象的靜態(tài)實例,并初始化為nil
2.聲明一個類的工廠方法,生成一個該類的實例,并且只會生成一個
3.覆蓋allcoWithZone方法,確保用戶在alloc 時,不會產生一個多余的對象
4.實現(xiàn)NSCopying協(xié)議,覆蓋release,autorelease,retain,retainCount方法,以確保只有一個實例化對象
5.在多線程的環(huán)境中,注意使用@synchronized關鍵字

①單例模式:餓漢式 ,懶漢式,登記式

當A、B線程并發(fā)的情況下,會創(chuàng)建出兩個實例來,也就是單例的控制在并發(fā)情況下失效了。
(2)餓漢式是線程安全的,因為虛擬機保證只會裝載一次,在裝載類的時候是不會發(fā)生并發(fā)的。
(3)如何實現(xiàn)懶漢式的線程安全呢?

當然懶漢式也是可以實現(xiàn)線程安全的,只要加上synchronized即可,如下:

1.  public static synchronized Singleton getInstance(){} 

但是這樣一來,會降低整個訪問的速度,而且每次都要判斷。那么有沒有更好的方式來實現(xiàn)呢?

(4)雙重檢查加鎖

可以使用"雙重檢查加鎖"的方式來實現(xiàn),就可以既實現(xiàn)線程安全,又能夠使性能不受到很大的影響。那么什么是"雙重檢查加鎖"機制呢?
所謂雙重檢查加鎖機制,指的是:并不是每次進入getInstance方法都需要同步,而是先不同步,進入方法過后,先檢查實例是否存在,如果不存在才進入下面的同步塊,這是第一重檢查。進入同步塊過后,再次檢查實例是否存在,如果不存在,就在同步的情況下創(chuàng)建一個實例,這是第二重檢查。這樣一來,就只需要同步一次了,從而減少了多次在同步情況下進行判斷所浪費的時間。
雙重檢查加鎖機制的實現(xiàn)會使用一個關鍵字volatile,它的意思是:被volatile修飾的變量的值,將不會被本地線程緩存,所有對該變量的讀寫都是直接操作共享內存,從而確保多個線程能正確的處理該變量。

看看代碼可能會更加清楚些。示例代碼如下:

1.  public class Singleton {  
2.  /**  
3.  * 對保存實例的變量添加volatile的修飾  
4.  */  
5.  private volatile static Singleton instance = null;  
6.  private Singleton(){  
7.  }  
8.  public static  Singleton getInstance(){  
9.  //先檢查實例是否存在,如果不存在才進入下面的同步塊  
10.  if(instance == null){  
11.  //同步塊,線程安全地創(chuàng)建實例  
12.  synchronized(Singleton.class){  
13.  //再次檢查實例是否存在,如果不存在才真正地創(chuàng)建實例  
14.  if(instance == null){  
15.  instance = new Singleton();  
16.  }  
17.  }  
18.  }  
19.  return instance;  
20.  }  
21.  } 

這種實現(xiàn)方式可以實現(xiàn)既線程安全地創(chuàng)建實例,而又不會對性能造成太大的影響。它只是在第一次創(chuàng)建實例的時候同步,以后就不需要同步了,從而加快了運行速度。

②iOS單例的創(chuàng)建與銷毀
18.如何讓程序后臺不退出
19.UIKit Foundation區(qū)別
20.GCD底層實現(xiàn)和如何添加操作依賴,GCD 和NSOperation區(qū)別

image.jpeg

⑴底層實現(xiàn)

①IOS和OS X的核心是XNU內核,GCD是基于XUN內核實現(xiàn)的
②GCD的API全部在libdispatch庫中
③GCD的底層實現(xiàn)主要有Dispatch Queue 和Dispatch Source
Dispatch Queue :管理block操作
Dispatch Source :處理事件(比如線程間通信)
⑵GCD操作依賴


image.jpeg

隊列:串行隊列,并行隊列,全局隊列,主隊列

image.jpeg

串行隊列
同步執(zhí)行任務 會在當前線程內執(zhí)行 # 不一定是主線程
異步執(zhí)行 會創(chuàng)建一個新的線程來執(zhí)行任務

并行隊列,

同步的方式執(zhí)行 并不會開辟新線程

異步的方式執(zhí)行 會創(chuàng)建多個新的線程來執(zhí)行多個任務 是隨機無序執(zhí)行的

  1. //串行隊列 同步執(zhí)行任務 會在當前線程內執(zhí)行 //所以打印的會是當前線程的編號 不一定是主線程
2.  -(void)demo  
3.  {  
4.  //串行隊列 DISPATCH_QUEUE_SERIAL  
5.  //并行隊列 DISPATCH_QUEUE_CONCURRENT  
6.  dispatch_queue_t queue=dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL);  

8.  //創(chuàng)建任務  
9.  dispatch_block_t task1=^{  
10.  NSLog(@"%@  同步執(zhí)行了方法1",[NSThread currentThread]);  
11.  };  

13.  dispatch_block_t task2=^{  
14.  NSLog(@"%@  同步執(zhí)行了方法2",[NSThread currentThread]);  
15.  };  
16.  //加入隊列  

18.  //同步的方式 dispatch_sync  
19.  //異步的方式 dispatch_async 
20.  dispatch_sync(queue, task1);  

22.  dispatch_sync(queue, task2);  
23.  }  

⑶區(qū)別

①GCD是純C語言的API, NSOperationQueue是基于GCD的OC版本封裝
②GCD只支持FIFO的隊列,NSOperationQueue可以很方便地調整執(zhí)行順序 設置最大并發(fā)數(shù)量
③NSOperationQueue 可以輕松地在operation 間設置依賴關系,而GCD需要寫很多的代碼
④NSOperationQueue支持KVO,可以監(jiān)測operation是否正在執(zhí)行(is Executed),是否結束(is finished),是否取消( is canceld);
⑤ GCD的執(zhí)行速度比NSOperationQueue快

總結:
NSOperationQueue 任務之間有依賴/或者要監(jiān)聽任務的執(zhí)行情況
GCD 任務之間不太互相依賴

21.js交互的方式

iOS7之后

①JavaScriptCore
JavaScriptCore中類及協(xié)議:

  • JSContext:給JavaScript提供運行的上下文環(huán)境
  • JSValue:JavaScript和Objective-C數(shù)據(jù)和方法的橋梁
  • JSManagedValue:管理數(shù)據(jù)和方法的類
  • JSVirtualMachine:處理線程相關,使用較少
  • JSExport:這是一個協(xié)議,如果采用協(xié)議的方法交互,自己定義的協(xié)議必須遵守此協(xié)議

自定義JSObjcDelegate協(xié)議,而且此協(xié)議必須遵守JSExport這個協(xié)議,自定義協(xié)議中的方法就是暴露給web頁面的方法。在webView加載完畢的時候獲取JavaScript運行的上下文環(huán)境,然后再注入橋梁對象名為Toyun,承載的對象為self即為此控制器,控制器遵守此自定義協(xié)議實現(xiàn)協(xié)議中對應的方法。在JavaStript調用完本地應用的方法做完相對應的事情之后,又回調了JavaStript中對應的方法,從而實現(xiàn)了web頁面和本地應用之間的通訊。

JavaScriptCore使用注意
JavaStript調用本地方法是在子線程中執(zhí)行的,這里要根據(jù)實際情況考慮線程之間的切換,而在回調JavaScript方法的時候最好是在剛開始調用此方法的線程中去執(zhí)行那段JavaStript方法的代碼

②攔截協(xié)議
攔截協(xié)議這個適合一些比較簡單的一些情況,不需要引入什么框架,只需要web前端配合一下就好
③第三方框架WebViewJavaScriptBridge github
iOS8之后
WKWebView的代理方法實現(xiàn)JS交互(WKScriptMessageHandler)

23.多線程安全的幾種解決辦法及多線程安全如何控制
① 只在主線程刷新訪問UI
② 如果要防止資源搶奪,得用synchronized進行加鎖保護
③ 如果異步操作要保證線程安全等問題,盡量使用GCD(有些函數(shù)默認就是安全的)

24.NSTimer和Runloop
25.網(wǎng)絡傳輸加密

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容