面試小結(jié)

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

1.線性表:順序表和鏈表優(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.如何快速更換第三方類庫(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是如何管理線程的棠众,如何實(shí)現(xiàn)線程安全;
18.簡(jiǎn)述自己知道的加鎖方式有决;
19.簡(jiǎn)述幾大線程方式及區(qū)別闸拿;
20.對(duì)于常用動(dòng)畫你的理解和使用;
21.簡(jiǎn)述delegate和block书幕,及block對(duì)于變量的修改問(wèn)題新荤;
22.談?wù)勑阅軆?yōu)化;
23.instruments你用了哪些功能台汇,如何檢測(cè)內(nèi)存泄露苛骨;

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

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

1.線性表:順序表和鏈表優(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.線性表:零個(gè)或者多個(gè)數(shù)據(jù)元素的有限序列碳胳。
2.順序表和鏈表是線性表的兩種物理存儲(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):(主要用于查詢)
    (1)快速存取任意位置元素;
    (2)無(wú)需為了表示元素之間邏輯關(guān)系而增加存儲(chǔ)空間(相對(duì)鏈表而言);
順序表缺點(diǎn):
     增糠馆、刪嘶伟、改操作
鏈表優(yōu)點(diǎn):(主要用于增刪該)
    (1)增刪該時(shí)只需要修改指針;
    (2)不需要事先明確表長(zhǎng)又碌;
鏈表缺點(diǎ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是不同類的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];
  //開始創(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多變作煌,考慮異步繪制或者重寫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)重寫該方法時(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í)畫圖時(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.如何快速更換第三方類庫(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í)的用戶骏全;
  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ù)中母怜,切換回主線程,更新UI缚柏;
對(duì)比:
    pthread:通用于Unix/Linux/Windows的C語(yǔ)言線程管理API苹熏,可移植性強(qiáng),但是使用繁瑣币喧,需要使用者管理線程生命周期轨域;
    NSThread:使用Objective-C實(shí)現(xiàn),輕量級(jí)的線程管理杀餐,但是也需要手動(dòng)管理線程的生命周期疙挺;
    NSOperation:基于GCD,使用Objective-C實(shí)現(xiàn)的面向?qū)ο蟮木€程管理怜浅,比GCD更高級(jí),但是處理簡(jiǎn)單任務(wù)會(huì)比GCD代碼更多;
    競(jìng)爭(zhēng)&同步:兩個(gè)線程搶奪同一個(gè)資源恶座,就會(huì)競(jìng)爭(zhēng)搀暑,為了防止競(jìng)爭(zhēng),一個(gè)線程擁有資源的時(shí)候跨琳,會(huì)對(duì)資源加鎖自点,另一個(gè)線程就要等待解鎖以后再擁有這個(gè)資源,這叫同步脉让。
    死鎖:兩個(gè)線程互相等待對(duì)方釋放資源桂敛;
    主線程&后臺(tái)線程:主線程也叫前臺(tái)線程,程序啟動(dòng)的默認(rèn)線程溅潜,操作UI的線程术唬。后臺(tái)線程,即非主線程滚澜,用于不影響主線程的完成一些任務(wù)粗仓;
    并行&串行:并行,就是幾個(gè)任務(wù)一起完成设捐。串行借浊,就是幾個(gè)任務(wù)一個(gè)接著一個(gè)完成。
    同步&異步:同步執(zhí)行線程萝招,等待新線程執(zhí)行完以后蚂斤,再繼續(xù)執(zhí)行當(dāng)前線程,很少用到槐沼。異步執(zhí)行線程曙蒸,在執(zhí)行新線程的同時(shí),繼續(xù)執(zhí)行當(dāng)前線程母赵,常用逸爵。

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)求者只能使用代理訪問(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))類似兑徘,但指定請(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 (未滿足前提條件) 服務(wù)器未滿足請(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 (不支持的媒體類型) 請(qǐng)求的格式不受請(qǐng)求頁(yè)面的支持虑粥。
    416 (請(qǐng)求范圍不符合要求) 如果頁(yè)面無(wú)法提供請(qǐng)求的范圍,則服務(wù)器會(huì)返回此狀態(tài)代碼宪哩。
    417 (未滿足期望值) 服務(wù)器未滿足"期望"請(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ù)贩汉,或者查詢數(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.使用蘋果提供的Crash崩潰收集服務(wù)蚯窥。

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

 輕量級(jí)<覆蓋型>
 1.Plist文件<初始化文件路徑,數(shù)據(jù)寫入路徑writeToFile:> 可以使用plist的數(shù)據(jù)類型有 NSArray,NSDictionary,NSData,NSString,NSNumber,NSDate拦赠;
 2.NSUserDefaults<存儲(chǔ)一些簡(jiǎn)單的信息>及時(shí)更新存儲(chǔ)synchronize巍沙;
 3.NSKeyedArchiver<遵循NSCoping協(xié)議,歸檔解檔>
  重量級(jí)<關(guān)系型>
  1.sqlite3<FMDB>直接編寫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 開始處理圖片,處理進(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ì)列開始從硬盤查找圖片是否已經(jīng)緩存;
 (6)根據(jù) URLKey 在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進(jìn)行的操作援岩,所以回主線程進(jìn)行結(jié)果回調(diào) notifyDelegate:;
 (7)如果上一操作從硬盤讀取到了圖片熟史,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過(guò)小,會(huì)先清空內(nèi)存緩存)窄俏。SDImageCacheDelegate 回調(diào) imageCache:didFindImage:forKey:userInfo:。進(jìn)而回調(diào)展示圖片;
 (8)如果從硬盤緩存目錄讀取不到圖片碘菜,說(shuō)明所有緩存都不存在該圖片凹蜈,需要下載圖片,回調(diào) imageCache:didNotFindImageForKey:userInfo:;
 (9)共享或重新生成一個(gè)下載器 SDWebImageDownloader 開始下載圖片;
 (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ì)拖慢主線程 UI计雌。如果有需要對(duì)下載的圖片進(jìn)行二次處理悄晃,最好也在這里完成,效率會(huì)好很多;
 (14)在主線程 notifyDelegateOnMainThreadWithInfo: 宣告解碼完成凿滤,imageDecoder:didFinishDecodingImage:userInfo: 回調(diào)給 SDWebImageDownloader;
 (15)imageDownloader:didFinishWithImage: 回調(diào)給 SDWebImageManager 告知圖片下載完成;
 (16)通知所有的 downloadDelegates 下載完成妈橄,回調(diào)給需要的地方展示圖片;
 (17)將圖片保存到 SDImageCache 中,內(nèi)存緩存和硬盤緩存同時(shí)保存翁脆。寫文件到硬盤也在以單獨(dú) NSInvocationOperation 完成眷蚓,避免拖慢主線程;
 (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是如何管理線程的篙贸,如何實(shí)現(xiàn)線程安全;

1.AF并沒(méi)有為每個(gè)請(qǐng)求創(chuàng)建一個(gè)線程枫疆,而是將每個(gè)請(qǐng)求封裝成一個(gè)NSOperation放到queue中爵川,當(dāng)operation執(zhí)行時(shí),都會(huì)在一個(gè)單獨(dú)線程中創(chuàng)建NSURLSession對(duì)象养铸,并用KVO監(jiān)聽所有回調(diào)雁芙。下面是值得借鑒的地方
  (1)并發(fā)粒度:因?yàn)锳F的所有網(wǎng)絡(luò)請(qǐng)求都在operationQueue中轧膘,而該queue會(huì)有多個(gè)并發(fā)線程來(lái)執(zhí)行,最大的并發(fā)線程數(shù)一般是系統(tǒng)根據(jù)硬件信息默認(rèn)的兔甘,AF則留有設(shè)置最大并發(fā)線程數(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ú)線程中創(chuàng)建自己的NSURLSession對(duì)象,并通過(guò)觀察者模式澡匪,發(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)述幾大線程方式及區(qū)別疑苔;

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

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

1.UIView動(dòng)畫
    通過(guò)UIView支持的動(dòng)畫屬性來(lái)實(shí)現(xiàn)動(dòng)畫效果候学,如frame,bounds纵散,center梳码,tranform,alpha伍掀,backgroundColor掰茶,contentStretch等,對(duì)于約束的修改則需要在block中調(diào)用 setNeedsLayout蜜笤,而約束的改變?cè)趧?dòng)畫之后執(zhí)行濒蒋。
2.核心動(dòng)畫
    核心動(dòng)畫采用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)畫樹)贮配,modeLayer tree(模型樹),render tree(渲染樹)塞赂,在做iOS動(dòng)畫的時(shí)候泪勒,我們修改動(dòng)畫的屬性,在動(dòng)畫的其實(shí)是CALayer的present Layer的屬性值宴猾,而最終展示在界面上的其實(shí)是提供UIView的modelLayer酣藻。
  CALayer核心動(dòng)畫與UIView動(dòng)畫的區(qū)別:
    UIView封裝的動(dòng)畫執(zhí)行完畢之后不會(huì)反彈,CALayer核心動(dòng)畫則會(huì)鳍置;另外UIView的動(dòng)畫期間可以處理用戶事件,CALayer核心動(dòng)畫則不能送淆。例如:如果是通過(guò)CALayer核心動(dòng)畫改變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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市膳凝,隨后出現(xiàn)的幾起案子碑隆,更是在濱河造成了極大的恐慌,老刑警劉巖蹬音,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件上煤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡祟绊,警方通過(guò)查閱死者的電腦和手機(jī)楼入,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)牧抽,“玉大人嘉熊,你說(shuō)我怎么就攤上這事⊙锸妫” “怎么了阐肤?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)讲坎。 經(jīng)常有香客問(wèn)我孕惜,道長(zhǎng),這世上最難降的妖魔是什么晨炕? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任衫画,我火速辦了婚禮,結(jié)果婚禮上瓮栗,老公的妹妹穿的比我還像新娘削罩。我一直安慰自己,他們只是感情好费奸,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布弥激。 她就那樣靜靜地躺著,像睡著了一般愿阐。 火紅的嫁衣襯著肌膚如雪微服。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天缨历,我揣著相機(jī)與錄音以蕴,去河邊找鬼。 笑死辛孵,一個(gè)胖子當(dāng)著我的面吹牛舒裤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播觉吭,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼腾供,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起伴鳖,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤节值,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后榜聂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搞疗,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年须肆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匿乃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡豌汇,死狀恐怖幢炸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拒贱,我是刑警寧澤宛徊,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站逻澳,受9級(jí)特大地震影響闸天,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜斜做,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一苞氮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瓤逼,春花似錦笼吟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)艳狐。三九已至定硝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毫目,已是汗流浹背蔬啡。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留镀虐,地道東北人箱蟆。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像刮便,于是被迫代替她去往敵國(guó)和親空猜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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