面試小結(jié)

又到了不得不想換家公司的時(shí)間了。不是不想長(zhǎng)待,各種心酸就不排解了,下面是幾次面試的題目,次序不分先后。稍后會(huì)一一給自己解釋

1.線(xiàn)性表:順序表和鏈表優(yōu)缺點(diǎn),增刪改查插入如何操作,在內(nèi)存上是如何處理的;
2.表(UITableView)視圖的重用機(jī)制,如何實(shí)現(xiàn);
3.集合視圖(UICollectionView)瀑布流如何實(shí)現(xiàn)及優(yōu)化;
4.cell自適應(yīng)高度的處理方式及優(yōu)化;
5.loadView、awakeFromNib和layoutSubView、drawRect、setNeedsLayout、setNeedDisplay、layoutIfNeeded等方法何時(shí)調(diào)用;
6.如何使用cocoaPods管理第三方;
7.如何快速更換第三方類(lèi)庫(kù);
8.輪播圖的實(shí)現(xiàn)以三張圖片為例;
9.簡(jiǎn)述APNS,及遠(yuǎn)程和本地推送的實(shí)現(xiàn);
10.GCD的作用,適當(dāng)說(shuō)明使用過(guò)程;
11.簡(jiǎn)述HTTP協(xié)議錯(cuò)誤代碼的含義;
12.GET和POST的理解和區(qū)別;
13.熱修復(fù)的方式及如何實(shí)現(xiàn);
14.bug的搜集管理;
15.如何對(duì)接口數(shù)據(jù)進(jìn)行緩存;
16.簡(jiǎn)述SDWebImage的實(shí)現(xiàn)原理;
17.AF和SD是如何管理線(xiàn)程的,如何實(shí)現(xiàn)線(xiàn)程安全;
18.簡(jiǎn)述自己知道的加鎖方式;
19.簡(jiǎn)述幾大線(xiàn)程方式及區(qū)別;
20.對(duì)于常用動(dòng)畫(huà)你的理解和使用;
21.簡(jiǎn)述delegate和block,及block對(duì)于變量的修改問(wèn)題;
22.談?wù)勑阅軆?yōu)化;
23.instruments你用了哪些功能,如何檢測(cè)內(nèi)存泄露;

以上如此多的問(wèn)題,不論哪個(gè)都是一大塊的知識(shí),畢竟個(gè)人技能樹(shù)上沒(méi)點(diǎn)過(guò)的,還有很多,根本不敢談一個(gè)技能點(diǎn),被點(diǎn)滿(mǎn)的情況。還好面試一般都是需要簡(jiǎn)述即可,點(diǎn)到即止。

又想吐槽今年下半年的遭遇了,再次忠告自己或他人,珍視生命,遠(yuǎn)離自詡創(chuàng)業(yè)公司無(wú)休止無(wú)報(bào)酬無(wú)贊賞的公司。好了說(shuō)正題:

1.線(xiàn)性表:順序表和鏈表優(yōu)缺點(diǎn),增刪改查插入如何操作,在內(nèi)存上是如何處理的;

這個(gè)問(wèn)題是我近期的第一家面試公司問(wèn)的,因?yàn)槊嬖嚨哪切┨煲恢痹诠就ㄏ影啵緵](méi)有時(shí)間補(bǔ)充正規(guī)水軍的套路,回答的時(shí)候也是啃啃巴巴的,不過(guò)也算是回答到點(diǎn)上了。但是面試官預(yù)期的答案應(yīng)該是這樣的:

定義
1.線(xiàn)性表:零個(gè)或者多個(gè)數(shù)據(jù)元素的有限序列。
2.順序表和鏈表是線(xiàn)性表的兩種物理存儲(chǔ)方式,
3.順序表:用地址連續(xù)的存儲(chǔ)單元來(lái)存放數(shù)據(jù)元素的數(shù)據(jù)結(jié)構(gòu);
4.鏈表:鏈表是一種物理存儲(chǔ)單元上非連續(xù)、非順序的數(shù)據(jù)結(jié)構(gòu);
不同點(diǎn)
1.存儲(chǔ)空間上
    順序表是物理地址連續(xù)的數(shù)據(jù)結(jié)構(gòu);
    鏈表是一種物理地址非連續(xù)的數(shù)據(jù)結(jié)構(gòu)、
2.增刪改查上(時(shí)間上)
順序表:
    正因?yàn)槲锢泶鎯?chǔ)結(jié)構(gòu)的不同,其表現(xiàn)形式不同,導(dǎo)致了其功能上的不同;
    增:準(zhǔn)確說(shuō)是插入的一種,只是插入的位置是最后;
    刪:若刪除位置后面還有元素,后邊元素全部前移一位;
    插入:若所插入位置后有元素,后面元素分別后移一位;
    查:獲取位置之后直接取;
    改:查到之后,修改數(shù)據(jù)域數(shù)據(jù);
從功能實(shí)現(xiàn)看其優(yōu)缺點(diǎn):
    順序表的存讀時(shí)間復(fù)雜度是O(1);
    插入或者刪除的時(shí)候時(shí)間復(fù)雜度是O(n);
順序表優(yōu)點(diǎn):(主要用于查詢(xún))
    (1)快速存取任意位置元素;
    (2)無(wú)需為了表示元素之間邏輯關(guān)系而增加存儲(chǔ)空間(相對(duì)鏈表而言);
順序表缺點(diǎn):
     增、刪、改操作
鏈表優(yōu)點(diǎn):(主要用于增刪該)
    (1)增刪該時(shí)只需要修改指針;
    (2)不需要事先明確表長(zhǎng);
鏈表缺點(diǎn):
    查:鏈表的查詢(xún)需要從前向后掃描;

2.表(UITableView)視圖的重用機(jī)制,如何實(shí)現(xiàn);

reuseIdentifier

tableView創(chuàng)建的時(shí)候,會(huì)新建一個(gè)復(fù)用池保存著創(chuàng)建的cell,而cell的復(fù)用標(biāo)識(shí)符就是reuseIdentifier,不同標(biāo)識(shí)符的cell是不同類(lèi)的cell。通過(guò)dequeueReusableCellWithIdentifier:方法獲取cell。

重用--><對(duì)象池設(shè)計(jì)模式>

重用cell的創(chuàng)建有兩種方法:
    初始化:沒(méi)有注冊(cè)的情況下,當(dāng)重用池取出的cell為空時(shí),需要初始化cell,并標(biāo)注其reuseIdentifier。
    注冊(cè):
          純代碼注冊(cè):代碼注冊(cè)
          xib注冊(cè):代碼注冊(cè)
          storyBoard注冊(cè):不需要代碼注冊(cè)

3.集合視圖(UICollectionView)瀑布流如何實(shí)現(xiàn)及優(yōu)化;

瀑布流實(shí)現(xiàn)的正確姿勢(shì)就是自定義UICollectionViewLayout,當(dāng)然自定義的時(shí)候需要實(shí)現(xiàn)以下內(nèi)部方法
1. - (CGSize)collectionViewContentSize;(主要返回cell的size)
2.- (void)prepareLayout;(預(yù)布局,每次刷新都會(huì)走的方法)
3.- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;(獲取cell的布局屬性數(shù)組)
4.- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;(根據(jù)indexPath設(shè)置cell布局屬性)
 /**
 *  初始化
 */
- (void)prepareLayout {
  [super prepareLayout];

  self.contentHeight = 0;

  //清除以前計(jì)算的所有高度
  [self.columnHeights removeAllObjects];
  for (NSInteger i = 0; i < self.columnCount; i++) {
    [self.columnHeights addObject:@(self.edgeInsets.top)];
}

  //清除之前所有布局屬性
  [self.attrsArray removeAllObjects];
  //開(kāi)始創(chuàng)建每一個(gè)cell對(duì)應(yīng)發(fā)布局屬性
  NSInteger count = [self.collectionView numberOfItemsInSection:0];
  for (NSInteger i = 0; i < count; i++) {
    //創(chuàng)建位置
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
    //獲取indexPath位置cell對(duì)應(yīng)的布局屬性
    UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
    [self.attrsArray addObject:attrs];
  }
}
/**
 *  決定cell的布局
 */
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
  return self.attrsArray;
}
/**
 *  返回indexPath位置cell對(duì)應(yīng)的布局屬性
 */
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {

  //創(chuàng)建布局屬性
  UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

  //collectionView的寬度
  CGFloat collectionViewW = self.collectionView.frame.size.width;

  //設(shè)置布局屬性的frame
  CGFloat w = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin) / self.columnCount;
  CGFloat h = [self.delegate waterflowlayout:self heightForItemAtIndex:indexPath.item itemWidth:w];

  //找出高度最短的那一列
  NSInteger destColumn = 0;
  CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
  for (NSInteger i = 0; i < self.columnCount; i++) {
    //取得第i列的高度
    CGFloat columnHeight = [self.columnHeights[i] doubleValue];
    if (minColumnHeight > columnHeight) {
        minColumnHeight = columnHeight;
        destColumn = i;
      }
    }
  CGFloat x = self.edgeInsets.left + destColumn * (w + self.columnMargin);
  CGFloat y = minColumnHeight;
  if (y != self.edgeInsets.top) {
    y += self.rowMargin;
  }
  attrs.frame = CGRectMake(x, y, w, h);

  //更新最短那列的高度
  self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));

  //記錄內(nèi)容的高度
  CGFloat columnHeight = [self.columnHeights[destColumn] doubleValue];
  if (self.contentHeight < columnHeight) {
      self.contentHeight = columnHeight;
  }
  return attrs;
}

- (CGSize)collectionViewContentSize {
   return CGSizeMake(0, self.contentHeight + self.edgeInsets.bottom);
}

- (CGFloat)rowMargin {
  if ([self.delegate respondsToSelector:@selector(rowMarginInWaterflowLayout:)]) {
    return [self.delegate rowMarginInWaterflowLayout:self];
  }else {
    return SMDefaultRowMargin;
  }
}

- (CGFloat)columnMargin {
  if ([self.delegate respondsToSelector:@selector(columnMarginInWaterflowLayout:)]) {
    return [self.delegate columnMarginInWaterflowLayout:self];
  }else {
    return SMDefaultColumnMargin;
  }
}

- (NSInteger)columnCount {
  if ([self.delegate respondsToSelector:@selector(columnCountInWaterflowLayout:)]) {
    return [self.delegate columnCountInWaterflowLayout:self];
  }else {
    return SMDefaultColumnCount;
  }
}

- (UIEdgeInsets)edgeInsets {
   if ([self.delegate respondsToSelector:@selector(edgeInsetsInWaterflowLayout:)]) {
      return [self.delegate edgeInsetsInWaterflowLayout:self];
    }else {
      return SMDefaultEdgeInsets;
    }
}
優(yōu)化(tableView優(yōu)化參考)
1.通過(guò)正確的姿勢(shì)設(shè)置reuseIdentifier重用cell,headerView,footerView;
2.盡量減少不必要的透明View;
3.盡量避免漸變、拉伸、offScreen渲染;(maskToBouds)
4.一般情況下,處理數(shù)據(jù)的時(shí)候把對(duì)應(yīng)高度計(jì)算好,封進(jìn)Model中,避免重復(fù)計(jì)算;
5.展示網(wǎng)絡(luò)數(shù)數(shù)據(jù)時(shí),異步加載(一般都這樣干的)
6.如果設(shè)置shadow,使用shadowPath;
7.盡量減少subView,如果subView多變,考慮異步繪制或者重寫(xiě)drawRect;(drawRect慎用)
8.cellForRow中的邏輯如果需要處理數(shù)據(jù),請(qǐng)緩存結(jié)果;
9.對(duì)于數(shù)據(jù)結(jié)構(gòu)慎重對(duì)待,針對(duì)不同業(yè)務(wù)處理使用合適數(shù)據(jù)結(jié)構(gòu),避免性能消耗;(一般都這么干了)
10.對(duì)于不同的height,size,請(qǐng)perpare并且cache;
11.cell在使用代理,block,target-action等操作時(shí),防止循環(huán)引用;(weak,weak-Strong Dance,weak)

4.cell自適應(yīng)高度的處理方式及優(yōu)化;

我的處理方式是這樣的:cell自適應(yīng)是根據(jù)數(shù)據(jù)來(lái)的,那么在數(shù)據(jù)Model中建立對(duì)應(yīng)屬性并LazyLoad。

5.loadView、awakeFromNib和layoutSubView、drawRect、setNeedsLayout、setNeedDisplay、layoutIfNeeded等方法何時(shí)調(diào)用;

1.loadView()
    調(diào)用順序:view->loadViewIfRequired->loadView
    [super loadView];重載:加載指定xib--(否)-->加載同名xib--(否)-->創(chuàng)建空白View
    當(dāng)重指向self.view的時(shí)候,可以在當(dāng)前方法中設(shè)置;
    該方法只能重載不能主動(dòng)調(diào)用;
2. awakeFromNib()
  方法由nib loading machinery 發(fā)出,當(dāng)調(diào)用loadNibFile時(shí),完成初始化設(shè)置和鏈接,并且在所有關(guān)聯(lián)的對(duì)象喚醒該方法。
  當(dāng)一個(gè)視圖或者控制器加載多個(gè)nib文件時(shí),方法會(huì)被調(diào)用多次,所以當(dāng)重寫(xiě)該方法時(shí)需要注意;
3.layoutSubViews()
    事件的調(diào)用時(shí)機(jī):
    (1)addSubView:之后,并且子視圖有frame,
    (2)在有子視圖的情況下,設(shè)置父視圖size;
    (3)更新子視圖size時(shí),當(dāng)且僅當(dāng)size不同時(shí),才會(huì)調(diào)用子視圖的該方法;
    (4)滾動(dòng)scrollView會(huì)觸發(fā)該方法;
    (5)init的時(shí)候不會(huì)觸發(fā)該方法
4.drawRect()
    (1)view的初始化沒(méi)有設(shè)置rect時(shí),方法不被調(diào)用。控制器中該方法調(diào)用在viewDidLoad之后;
    (2)sizeToFit()之后會(huì)調(diào)用該方法;
    (3)當(dāng)view屬性contentMode為UIViewContentModeRedraw。每次設(shè)置frame都會(huì)調(diào)用該方法;
    (4)調(diào)用setNeedsDisplay,或者setNeedsDisplayInRect:時(shí),如果view的frame設(shè)置不為0,都會(huì)調(diào)用該方法;
    注意:
        (1)不可以顯示調(diào)用
        (2)實(shí)時(shí)畫(huà)圖時(shí),不可用gestureRecognizer,只能用touchBegin等方法來(lái)調(diào)用setNeedsDisplay,實(shí)現(xiàn)調(diào)用drawRect;
 5. setNeedsLayout
    在receiver標(biāo)上一個(gè)需要被重新布局的標(biāo)記flag,在系統(tǒng)runloop的下一個(gè)周期自動(dòng)調(diào)用layoutSubviews;
 6.setNeedDisplay
    在receiver標(biāo)上一個(gè)需要被重新繪圖的標(biāo)記,在下一個(gè)draw周期自動(dòng)重繪,iphone device的刷新頻率是60hz,也就是1/60秒后重繪;
 7.layoutIfNeeded
    遍歷的不是superview鏈,應(yīng)該是subviews鏈;
    如果,有需要刷新的標(biāo)記,立即調(diào)用layoutSubviews進(jìn)行布局(如果沒(méi)有標(biāo)記,不會(huì)調(diào)用layoutSubviews);
    如果要立即刷新,要先調(diào)用[view setNeedsLayout],把標(biāo)記設(shè)為需要布局,然后馬上調(diào)用[view layoutIfNeeded],實(shí)現(xiàn)布局;
    在視圖第一次顯示之前,標(biāo)記總是“需要刷新”的,可以直接調(diào)用[view layoutIfNeeded];

6.如何使用cocoaPods管理第三方;

要點(diǎn):
  (1)cocoaPods的安裝;
  (2)Podfile的創(chuàng)建、編輯、install;

7.如何快速更換第三方類(lèi)庫(kù);

簡(jiǎn)單來(lái)說(shuō)用第三方的正確姿勢(shì)必須要自己封裝下再使用,否則后期維護(hù)特別麻煩,修改的地方太多了。對(duì)于面試來(lái)說(shuō),直接提下封裝的優(yōu)點(diǎn),一般就可以了;

8.輪播圖的實(shí)現(xiàn)以三張圖片為例;

自己實(shí)現(xiàn):
這里給出思路:第一張圖片前加一張最后一張的圖片,目前有四張,在最后位置添加第二張圖片;可以在滾動(dòng)首尾的時(shí)候,減速方法中切換(視覺(jué)效果),保證正常輪播;
第三方:SDCycleScrollView

9.簡(jiǎn)述APNS,及遠(yuǎn)程和本地推送的實(shí)現(xiàn);

APNs全名是Apple Push Notification Service。
遠(yuǎn)程推送
  1.deviceToken
      該字段是在應(yīng)用注冊(cè)通知服務(wù)時(shí)APNS返回的設(shè)備唯一標(biāo)示。
  2.遠(yuǎn)程推送流程
      一般應(yīng)用在前臺(tái)時(shí)主要走應(yīng)用服務(wù)器和應(yīng)用的socket長(zhǎng)連接。這樣消息的傳遞要比APNS快,此時(shí)一般不需要deviceToken;應(yīng)用處于后臺(tái)時(shí),長(zhǎng)連接中斷,應(yīng)用服務(wù)器會(huì)將標(biāo)識(shí)信息和要發(fā)送的信息以一定模板發(fā)送給APNS,APNS將消息發(fā)送給具有標(biāo)識(shí)的用戶(hù);
  3.本地推送
   流程:創(chuàng)建本地通知、設(shè)置屬性、加入本地通知調(diào)度池、(iOS8.0以后)獲取授權(quán)。

10.GCD的作用,適當(dāng)說(shuō)明使用過(guò)程;

    GCD主要用在后臺(tái)執(zhí)行較慢任務(wù);延遲執(zhí)行任務(wù);以及在后臺(tái)任務(wù)中,切換回主線(xiàn)程,更新UI;
對(duì)比:
    pthread:通用于Unix/Linux/Windows的C語(yǔ)言線(xiàn)程管理API,可移植性強(qiáng),但是使用繁瑣,需要使用者管理線(xiàn)程生命周期;
    NSThread:使用Objective-C實(shí)現(xiàn),輕量級(jí)的線(xiàn)程管理,但是也需要手動(dòng)管理線(xiàn)程的生命周期;
    NSOperation:基于GCD,使用Objective-C實(shí)現(xiàn)的面向?qū)ο蟮木€(xiàn)程管理,比GCD更高級(jí),但是處理簡(jiǎn)單任務(wù)會(huì)比GCD代碼更多;
    競(jìng)爭(zhēng)&同步:兩個(gè)線(xiàn)程搶奪同一個(gè)資源,就會(huì)競(jìng)爭(zhēng),為了防止競(jìng)爭(zhēng),一個(gè)線(xiàn)程擁有資源的時(shí)候,會(huì)對(duì)資源加鎖,另一個(gè)線(xiàn)程就要等待解鎖以后再擁有這個(gè)資源,這叫同步。
    死鎖:兩個(gè)線(xiàn)程互相等待對(duì)方釋放資源;
    主線(xiàn)程&后臺(tái)線(xiàn)程:主線(xiàn)程也叫前臺(tái)線(xiàn)程,程序啟動(dòng)的默認(rèn)線(xiàn)程,操作UI的線(xiàn)程。后臺(tái)線(xiàn)程,即非主線(xiàn)程,用于不影響主線(xiàn)程的完成一些任務(wù);
    并行&串行:并行,就是幾個(gè)任務(wù)一起完成。串行,就是幾個(gè)任務(wù)一個(gè)接著一個(gè)完成。
    同步&異步:同步執(zhí)行線(xiàn)程,等待新線(xiàn)程執(zhí)行完以后,再繼續(xù)執(zhí)行當(dāng)前線(xiàn)程,很少用到。異步執(zhí)行線(xiàn)程,在執(zhí)行新線(xiàn)程的同時(shí),繼續(xù)執(zhí)行當(dāng)前線(xiàn)程,常用。

11.簡(jiǎn)述HTTP協(xié)議錯(cuò)誤代碼的含義;

1xx(臨時(shí)響應(yīng))表示臨時(shí)響應(yīng)并需要請(qǐng)求者繼續(xù)執(zhí)行操作的狀態(tài)代碼。
    100 (繼續(xù)) 請(qǐng)求者應(yīng)當(dāng)繼續(xù)提出請(qǐng)求。服務(wù)器返回此代碼表示已收到請(qǐng)求的第一部分,正在等待其余部分。 
    101 (切換協(xié)議) 請(qǐng)求者已要求服務(wù)器切換協(xié)議,服務(wù)器已確認(rèn)并準(zhǔn)備切換。
2xx(成功)表示成功處理了請(qǐng)求的狀態(tài)代碼。
    200 (成功) 服務(wù)器已成功處理了請(qǐng)求。通常,這表示服務(wù)器提供了請(qǐng)求的網(wǎng)頁(yè)。
    201 (已創(chuàng)建) 請(qǐng)求成功并且服務(wù)器創(chuàng)建了新的資源。
    202 (已接受) 服務(wù)器已接受請(qǐng)求,但尚未處理。
    203 (非授權(quán)信息) 服務(wù)器已成功處理了請(qǐng)求,但返回的信息可能來(lái)自另一來(lái)源。
    204 (無(wú)內(nèi)容) 服務(wù)器成功處理了請(qǐng)求,但沒(méi)有返回任何內(nèi)容。
    205 (重置內(nèi)容) 服務(wù)器成功處理了請(qǐng)求,但沒(méi)有返回任何內(nèi)容。
    206 (部分內(nèi)容) 服務(wù)器成功處理了部分 GET 請(qǐng)求。
3xx(重定向)表示要完成請(qǐng)求,需要進(jìn)一步操作。 通常,這些狀態(tài)代碼用來(lái)重定向。
    300 (多種選擇) 針對(duì)請(qǐng)求,服務(wù)器可執(zhí)行多種操作。服務(wù)器可根據(jù)請(qǐng)求者 (user agent) 選擇一項(xiàng)操作,或提供操作列表供請(qǐng)求者選擇。
    301 (永久移動(dòng)) 請(qǐng)求的網(wǎng)頁(yè)已永久移動(dòng)到新位置。服務(wù)器返回此響應(yīng)(對(duì) GET 或 HEAD 請(qǐng)求的響應(yīng))時(shí),會(huì)自動(dòng)將請(qǐng)求者轉(zhuǎn)到新位置。
    302 (臨時(shí)移動(dòng)) 服務(wù)器目前從不同位置的網(wǎng)頁(yè)響應(yīng)請(qǐng)求,但請(qǐng)求者應(yīng)繼續(xù)使用原有位置來(lái)進(jìn)行以后的請(qǐng)求。
    303 (查看其他位置) 請(qǐng)求者應(yīng)當(dāng)對(duì)不同的位置使用單獨(dú)的 GET 請(qǐng)求來(lái)檢索響應(yīng)時(shí),服務(wù)器返回此代碼。
    304 (未修改) 自從上次請(qǐng)求后,請(qǐng)求的網(wǎng)頁(yè)未修改過(guò)。服務(wù)器返回此響應(yīng)時(shí),不會(huì)返回網(wǎng)頁(yè)內(nèi)容。
    305 (使用代理) 請(qǐng)求者只能使用代理訪(fǎng)問(wèn)請(qǐng)求的網(wǎng)頁(yè)。如果服務(wù)器返回此響應(yīng),還表示請(qǐng)求者應(yīng)使用代理。
    307 (臨時(shí)重定向) 服務(wù)器目前從不同位置的網(wǎng)頁(yè)響應(yīng)請(qǐng)求,但請(qǐng)求者應(yīng)繼續(xù)使用原有位置來(lái)進(jìn)行以后的請(qǐng)求。
4xx(請(qǐng)求錯(cuò)誤)這些狀態(tài)代碼表示請(qǐng)求可能出錯(cuò),妨礙了服務(wù)器的處理。
    400 (錯(cuò)誤請(qǐng)求) 服務(wù)器不理解請(qǐng)求的語(yǔ)法。
    401 (未授權(quán)) 請(qǐng)求要求身份驗(yàn)證。 對(duì)于需要登錄的網(wǎng)頁(yè),服務(wù)器可能返回此響應(yīng)。
    403 (禁止) 服務(wù)器拒絕請(qǐng)求。
    404 (未找到) 服務(wù)器找不到請(qǐng)求的網(wǎng)頁(yè)。
    405 (方法禁用) 禁用請(qǐng)求中指定的方法。
    406 (不接受) 無(wú)法使用請(qǐng)求的內(nèi)容特性響應(yīng)請(qǐng)求的網(wǎng)頁(yè)。
    407 (需要代理授權(quán)) 此狀態(tài)代碼與 401(未授權(quán))類(lèi)似,但指定請(qǐng)求者應(yīng)當(dāng)授權(quán)使用代理。
    408 (請(qǐng)求超時(shí)) 服務(wù)器等候請(qǐng)求時(shí)發(fā)生超時(shí)。
    409 (沖突) 服務(wù)器在完成請(qǐng)求時(shí)發(fā)生沖突。服務(wù)器必須在響應(yīng)中包含有關(guān)沖突的信息。
    410 (已刪除) 如果請(qǐng)求的資源已永久刪除,服務(wù)器就會(huì)返回此響應(yīng)。
    411 (需要有效長(zhǎng)度) 服務(wù)器不接受不含有效內(nèi)容長(zhǎng)度標(biāo)頭字段的請(qǐng)求。
    412 (未滿(mǎn)足前提條件) 服務(wù)器未滿(mǎn)足請(qǐng)求者在請(qǐng)求中設(shè)置的其中一個(gè)前提條件。
    413 (請(qǐng)求實(shí)體過(guò)大) 服務(wù)器無(wú)法處理請(qǐng)求,因?yàn)檎?qǐng)求實(shí)體過(guò)大,超出服務(wù)器的處理能力。
    414 (請(qǐng)求的 URI 過(guò)長(zhǎng)) 請(qǐng)求的 URI(通常為網(wǎng)址)過(guò)長(zhǎng),服務(wù)器無(wú)法處理。
    415 (不支持的媒體類(lèi)型) 請(qǐng)求的格式不受請(qǐng)求頁(yè)面的支持。
    416 (請(qǐng)求范圍不符合要求) 如果頁(yè)面無(wú)法提供請(qǐng)求的范圍,則服務(wù)器會(huì)返回此狀態(tài)代碼。
    417 (未滿(mǎn)足期望值) 服務(wù)器未滿(mǎn)足"期望"請(qǐng)求標(biāo)頭字段的要求。
5xx(服務(wù)器錯(cuò)誤)這些狀態(tài)代碼表示服務(wù)器在嘗試處理請(qǐng)求時(shí)發(fā)生內(nèi)部錯(cuò)誤。 這些錯(cuò)誤可能是服務(wù)器本身的錯(cuò)誤,而不是請(qǐng)求出錯(cuò)。
    500 (服務(wù)器內(nèi)部錯(cuò)誤) 服務(wù)器遇到錯(cuò)誤,無(wú)法完成請(qǐng)求。
    501 (尚未實(shí)施) 服務(wù)器不具備完成請(qǐng)求的功能。例如,服務(wù)器無(wú)法識(shí)別請(qǐng)求方法時(shí)可能會(huì)返回此代碼。
    502 (錯(cuò)誤網(wǎng)關(guān)) 服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到無(wú)效響應(yīng)。
    503 (服務(wù)不可用) 服務(wù)器目前無(wú)法使用(由于超載或停機(jī)維護(hù))。通常,這只是暫時(shí)狀態(tài)。
    504 (網(wǎng)關(guān)超時(shí)) 服務(wù)器作為網(wǎng)關(guān)或代理,但是沒(méi)有及時(shí)從上游服務(wù)器收到請(qǐng)求。
    505 (HTTP 版本不受支持) 服務(wù)器不支持請(qǐng)求中所用的 HTTP 協(xié)議版本。

12.GET和POST的理解和區(qū)別;

get請(qǐng)求和post請(qǐng)求都可以用于做獲取數(shù)據(jù)請(qǐng)求,在請(qǐng)求數(shù)據(jù)安全方面post請(qǐng)求比get請(qǐng)求安全;
get是以明文的方式向服務(wù)器發(fā)送請(qǐng)求,post是包裝到請(qǐng)求體body中后,在向服務(wù)器發(fā)送請(qǐng)求;
get請(qǐng)求的參數(shù)全部暴露在接口中,一般叫做明文請(qǐng)求或者傻瓜式請(qǐng)求,post請(qǐng)求的參數(shù)一般是以字典的方式進(jìn)行拼接,相對(duì)于get比較安全;
如果從服務(wù)器獲取數(shù)據(jù),或者查詢(xún)數(shù)據(jù),使用get請(qǐng)求;如果上傳數(shù)據(jù)到服務(wù)器或者修改服務(wù)器上傳數(shù)據(jù)使用post請(qǐng)求;
get請(qǐng)求的URL在使用過(guò)程中,會(huì)限制長(zhǎng)度,因此長(zhǎng)度非常長(zhǎng)的請(qǐng)求建議用post請(qǐng)求;
對(duì)文件大小的請(qǐng)求:get不允許向服務(wù)器上傳文件(圖片,pdf,音視頻);

13.熱修復(fù)的方式及如何實(shí)現(xiàn);

熱修復(fù)的相關(guān)框架還是很多的,簡(jiǎn)單來(lái)說(shuō)主要是利用了iOS運(yùn)行時(shí)特性。在運(yùn)行時(shí),調(diào)用修改的方法,達(dá)到熱更新的目的;

14.bug的搜集管理;

一般常用bug分析方式有:
1.使用友盟、百度等第三方崩潰統(tǒng)計(jì)工具。
2.自己實(shí)現(xiàn)應(yīng)用內(nèi)崩潰收集,并上傳服務(wù)器。
3.Xcode-Devices中直接查看某個(gè)設(shè)備的崩潰信息。
4.使用蘋(píng)果提供的Crash崩潰收集服務(wù)。

15.如何對(duì)接口數(shù)據(jù)進(jìn)行緩存;

 輕量級(jí)<覆蓋型>
 1.Plist文件<初始化文件路徑,數(shù)據(jù)寫(xiě)入路徑writeToFile:> 可以使用plist的數(shù)據(jù)類(lèi)型有 NSArray,NSDictionary,NSData,NSString,NSNumber,NSDate;
 2.NSUserDefaults<存儲(chǔ)一些簡(jiǎn)單的信息>及時(shí)更新存儲(chǔ)synchronize;
 3.NSKeyedArchiver<遵循NSCoping協(xié)議,歸檔解檔>
  重量級(jí)<關(guān)系型>
  1.sqlite3<FMDB>直接編寫(xiě)splite3語(yǔ)言
  2.coreData<遷徙>對(duì)于數(shù)據(jù)庫(kù)的封裝,圖形化設(shè)計(jì),提供了一種映射的存儲(chǔ)關(guān)系;

16.簡(jiǎn)述SDWebImage的實(shí)現(xiàn)原理;

 (1)入口 sd_setImageWithURL: placeholderImage: options: progress: completed:會(huì)先把 placeholderImage 顯示,然后會(huì)把重復(fù)的請(qǐng)求刪除掉, SDWebImageManager 根據(jù) URL 開(kāi)始處理圖片,處理進(jìn)度progress,處理完成complete;
 (2)進(jìn)入 SDWebImageManager-downloadWithURL:delegate:options:userInfo: 交給 SDImageCache 從緩存查找圖片是否已經(jīng)下載queryDiskCacheForKey:delegate:userInfo:;
 (3)先從內(nèi)存圖片緩存查找是否有圖片,如果內(nèi)存中已經(jīng)有圖片緩存, SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager;
 (4)SDWebImageManagerDelegate 回調(diào) webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示圖片;
 (5)如果內(nèi)存緩存中沒(méi)有,生成 NSInvocationOperation 添加到隊(duì)列開(kāi)始從硬盤(pán)查找圖片是否已經(jīng)緩存;
 (6)根據(jù) URLKey 在硬盤(pán)緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進(jìn)行的操作,所以回主線(xiàn)程進(jìn)行結(jié)果回調(diào) notifyDelegate:;
 (7)如果上一操作從硬盤(pán)讀取到了圖片,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過(guò)小,會(huì)先清空內(nèi)存緩存)。SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo:。進(jìn)而回調(diào)展示圖片;
 (8)如果從硬盤(pán)緩存目錄讀取不到圖片,說(shuō)明所有緩存都不存在該圖片,需要下載圖片,回調(diào) imageCache:didNotFindImageForKey:userInfo:;
 (9)共享或重新生成一個(gè)下載器 SDWebImageDownloader 開(kāi)始下載圖片;
 (10)圖片下載由 NSURLConnection 來(lái)做,實(shí)現(xiàn)相關(guān) delegate 來(lái)判斷圖片下載中、下載完成和下載失敗;
 (11)connection:didReceiveData: 中利用 ImageIO 做了按圖片下載進(jìn)度加載效果;
 (12)connectionDidFinishLoading: 數(shù)據(jù)下載完成后交給 SDWebImageDecoder 做圖片解碼處理;
 (13)圖片解碼處理在一個(gè) NSOperationQueue 完成,不會(huì)拖慢主線(xiàn)程 UI。如果有需要對(duì)下載的圖片進(jìn)行二次處理,最好也在這里完成,效率會(huì)好很多;
 (14)在主線(xiàn)程 notifyDelegateOnMainThreadWithInfo: 宣告解碼完成,imageDecoder:didFinishDecodingImage:userInfo: 回調(diào)給 SDWebImageDownloader;
 (15)imageDownloader:didFinishWithImage: 回調(diào)給 SDWebImageManager 告知圖片下載完成;
 (16)通知所有的 downloadDelegates 下載完成,回調(diào)給需要的地方展示圖片;
 (17)將圖片保存到 SDImageCache 中,內(nèi)存緩存和硬盤(pán)緩存同時(shí)保存。寫(xiě)文件到硬盤(pán)也在以單獨(dú) NSInvocationOperation 完成,避免拖慢主線(xiàn)程;
 (18)SDImageCache 在初始化的時(shí)候會(huì)注冊(cè)一些消息通知,在內(nèi)存警告或退到后臺(tái)的時(shí)候清理內(nèi)存圖片緩存,應(yīng)用結(jié)束的時(shí)候清理過(guò)期圖片;
 (19)SDWebImage 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用;
 (20)SDWebImagePrefetcher 可以預(yù)先下載圖片,方便后續(xù)使用。

17.AF和SD是如何管理線(xiàn)程的,如何實(shí)現(xiàn)線(xiàn)程安全;

1.AF并沒(méi)有為每個(gè)請(qǐng)求創(chuàng)建一個(gè)線(xiàn)程,而是將每個(gè)請(qǐng)求封裝成一個(gè)NSOperation放到queue中,當(dāng)operation執(zhí)行時(shí),都會(huì)在一個(gè)單獨(dú)線(xiàn)程中創(chuàng)建NSURLSession對(duì)象,并用KVO監(jiān)聽(tīng)所有回調(diào)。下面是值得借鑒的地方
  (1)并發(fā)粒度:因?yàn)锳F的所有網(wǎng)絡(luò)請(qǐng)求都在operationQueue中,而該queue會(huì)有多個(gè)并發(fā)線(xiàn)程來(lái)執(zhí)行,最大的并發(fā)線(xiàn)程數(shù)一般是系統(tǒng)根據(jù)硬件信息默認(rèn)的,AF則留有設(shè)置最大并發(fā)線(xiàn)程數(shù)的接口;
  (2)block優(yōu)化:如果某一個(gè)operation的success和failure的回調(diào)占用較多CPU,則可以創(chuàng)建一個(gè)任務(wù)隊(duì)列并賦值給該operation的completionQueue;
2.SDWebImage中每個(gè)圖片的下載都是一個(gè)Operation操作,每個(gè)operation在單獨(dú)線(xiàn)程中創(chuàng)建自己的NSURLSession對(duì)象,并通過(guò)觀(guān)察者模式,發(fā)送加載狀態(tài)的廣播,以便對(duì)加載進(jìn)行管控。

18.簡(jiǎn)述自己知道的加鎖方式;

1. @synchronized 關(guān)鍵字加鎖(最耗時(shí))
2. NSLock 對(duì)象鎖
3. NSCondition
4. NSConditionLock 條件鎖(最耗時(shí))
5. NSRecursiveLock 遞歸鎖
6. pthread_mutex 互斥鎖(C語(yǔ)言)
7. dispatch_semaphore 信號(hào)量實(shí)現(xiàn)加鎖(GCD)(加鎖時(shí)間第二快)
8. OSSpinLock(已不再安全)(加鎖時(shí)間最快)

19.簡(jiǎn)述幾大線(xiàn)程方式及區(qū)別;

1.pthread:跨平臺(tái)可移植,線(xiàn)程需手動(dòng)管理;
2.NSThread:面向?qū)ο螅苯硬僮骶€(xiàn)程對(duì)象,需要手動(dòng)管理線(xiàn)程生命周期,可以獲取當(dāng)前線(xiàn)程及是否為主線(xiàn)程;
3.GCD:充分利用設(shè)備多核,線(xiàn)程生命周期自動(dòng)管理,使用之后不用管什么時(shí)候結(jié)束。
4.NSOperation:封裝GCD,更加面向?qū)ο螅€(xiàn)程生命周期手動(dòng)管理。相對(duì)GCD可以實(shí)現(xiàn)更高級(jí)的管理功能。

20.對(duì)于常用動(dòng)畫(huà)你的理解和使用;

1.UIView動(dòng)畫(huà)
    通過(guò)UIView支持的動(dòng)畫(huà)屬性來(lái)實(shí)現(xiàn)動(dòng)畫(huà)效果,如frame,bounds,center,tranform,alpha,backgroundColor,contentStretch等,對(duì)于約束的修改則需要在block中調(diào)用 setNeedsLayout,而約束的改變?cè)趧?dòng)畫(huà)之后執(zhí)行。
2.核心動(dòng)畫(huà)
    核心動(dòng)畫(huà)采用Core Animation框架,直接作用在CALayer層,而不再UIView;
  UIView與CALayer的主要區(qū)別
  1、UIView是可以響應(yīng)事件的,但是CALayer不能響應(yīng)事件
  2、UIView主要負(fù)責(zé)管理顯示內(nèi)容,而CALayer主要負(fù)責(zé)渲染和呈現(xiàn)。如果沒(méi)有CALayer,我們是看不到內(nèi)容的。
  3、CALayer內(nèi)部維護(hù)著三分layer tree,分別是presentLayer tree(動(dòng)畫(huà)樹(shù)),modeLayer tree(模型樹(shù)),render tree(渲染樹(shù)),在做iOS動(dòng)畫(huà)的時(shí)候,我們修改動(dòng)畫(huà)的屬性,在動(dòng)畫(huà)的其實(shí)是CALayer的present Layer的屬性值,而最終展示在界面上的其實(shí)是提供UIView的modelLayer。
  CALayer核心動(dòng)畫(huà)與UIView動(dòng)畫(huà)的區(qū)別:
    UIView封裝的動(dòng)畫(huà)執(zhí)行完畢之后不會(huì)反彈,CALayer核心動(dòng)畫(huà)則會(huì);另外UIView的動(dòng)畫(huà)期間可以處理用戶(hù)事件,CALayer核心動(dòng)畫(huà)則不能。例如:如果是通過(guò)CALayer核心動(dòng)畫(huà)改變layer的位置狀態(tài),表面上看雖然已經(jīng)改變了,但是實(shí)際上它的位置是沒(méi)有改變的。

21.簡(jiǎn)述delegate和block,及block對(duì)于變量的修改問(wèn)題;

  delegate和block主要解決對(duì)象之間通信問(wèn)題。都需要注意循環(huán)引用的問(wèn)題,ARC下,delegate為weak修飾,block用copy修飾,防止block實(shí)現(xiàn)代碼被釋放掉。在block塊內(nèi)對(duì)外局部變量修改時(shí),局部變量需要__block修飾。

22.談?wù)勑阅軆?yōu)化;

  1.性能優(yōu)化:
    (1)UITableView優(yōu)化
    (2)網(wǎng)絡(luò)請(qǐng)求優(yōu)化
    (3)圖片加載優(yōu)化
  2.代碼優(yōu)化:
    (1)合理使用設(shè)計(jì)模式
    (2)善于使用面向?qū)ο笳Z(yǔ)言特性
    (3)設(shè)計(jì)優(yōu)化,緩存等
    (4)代碼規(guī)范
  3.程序體積優(yōu)化:
  4.數(shù)據(jù)安全:

23.instruments你用了哪些功能,如何檢測(cè)內(nèi)存泄露;

  1. Zombies:查看僵尸對(duì)象
  2.Leaks:內(nèi)存泄漏
  3.Time Profiler:查看加載耗時(shí)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評(píng)論 6 532
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 176,305評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,962評(píng)論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,727評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,193評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,411評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,777評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,978評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,216評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,642評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,878評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,657評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,960評(píng)論 2 373

推薦閱讀更多精彩內(nèi)容