2016年3月iOS面试总结

作者: 一缕殇流化隐半边冰霜 | 来源:发表于2016-04-28 23:56 被阅读16006次

今年3月中下旬因为个人原因,换了一份工作,期间面试了有4,5家,基本都是D轮或者上市公司,也从他们的面试笔试中看到了自己的一些不足,于是就想写出来和大家分享一下,如果能帮到正在面试的同学更好。从面试题中,其实可以看到一些行业的发展,以及总体人才需求是怎样的了。

一.笔试题

笔试基本都有一两道基础题,比如说UITableView的重用机制,ARC的基本原理,如何避免retain cycle,谈谈对MVC的理解,iOS内存管理机制。这些大家应该都很清楚了。笔试的内容有几种有选择题,问答题,难一点的就是多选题了。我面试了一家就是给了10道多选题,多选,少选,错选都不行,当时做完以后就感觉不是很好,有些题目题干就是一下哪些是对的,然后ABCD依次给4个不同的概念,这种一道题相当于考了4个点。总之遇到这种“恶心”的多选题也不要太慌,静下心来一一甄别应该能拿到不错的成绩。

接下来我说几个我当时答的不怎么好的题目,我当时记了一下,和大家分享一下。

1.进程和线程的区别和联系

这个其实是操作系统的问题,当时一下子把我问的懵了,后来仔细回想了一下,加上自己的理解就答了,下面说说稍微完整的答案,大家可以准备准备,再问这种问题就可以完美作答了。

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.

一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.

2.并行和并发的区别

并行是指两个或者多个事件在同一时刻发生;
并发是指两个或多个事件在同一时间间隔内发生。

3.谈谈你对Block和delegate的理解

我当时是这么答的,delegate的回调更多的面向过程,而block则是面向结果的。如果你需要得到一条多步进程的通知,你应该使用delegation。而当你只是希望得到你请求的信息(或者获取信息时的错误提示),你应该使用block。(如果你结合之前的3个结论,你会发现delegate可以在所有事件中维持state,而多个独立的block却不能)

4.谈谈instancetype和id的异同

1、相同点
都可以作为方法的返回类型

2、不同点
①instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;②instancetype只能作为返回值,不能像id那样作为参数

5.category中能不能使用声明属性?为什么?如果能,怎么实现?

这种问题一问,我当时就感觉肯定能实现的,但是实在不知道怎么做,后来回来查了一下,才知道是用到了Runtime的知识了。贴一下答案

给分类(Category)添加属性
利用Runtime实现getter/setter 方法

@interface ClassName (CategoryName)
@property (nonatomic, strong) NSString *str;
@end

//实现文件
#import "ClassName + CategoryName.h"
#import <objc/runtime.h>
  
static void *strKey = &strKey;
@implementation ClassName (CategoryName)

-(void)setStr:(NSString *)str
{
    objc_setAssociatedObject(self, & strKey, str, OBJC_ASSOCIATION_COPY);
}

-(NSString *)str
{
    return objc_getAssociatedObject(self, &strKey);
}

@end
6.isKindOfClass和isMemberOfClass的区别

这个题目简单,但是就是当时紧张的情况下,别答反了。

isKindOfClass来确定一个对象是否是一个类的成员,或者是派生自该类的成员
isMemberOfClass只能确定一个对象是否是当前类的成员

7.block里面的如何防止retain cycle

使用弱引用打断block里面的retain cycle
MRC中__ _block 是不会引起retain;但在ARC中 _block 则会引起retain。ARC中应该使用 _weak __或__unsafe_unretained弱引用

8.iOS多线程有哪几种实现方法?GCD中有哪些队列?分别是并行还是串行?

iOS中多线程编程工具主要3有:
1.NSThread
2.NSOperation
3.GCD

dispatch queue分为下面3种:而系统默认就有一串行队列main_queue和并行队列global_queue:

GCD中有三种队列类型:
The main queue: 与主线程功能相同。实际上,提交至main queue的任务会在主线程中执行。main queue可以调用dispatch_get_main_queue()来获得。因为main queue是与主线程相关的,所以这是一个串行队列。

Global queues: 全局队列是并发队列,并由整个进程共享。进程中存在三个全局队列:高、中(默认)、低三个优先级队列。可以调用dispatch_get_global_queue函数传入优先级来访问队列。

用户队列: 用户队列 (GCD并不这样称呼这种队列, 但是没有一个特定的名字来形容这种队列,所以我们称其为用户队列) 是用函数 dispatch_queue_create
创建的队列. 这些队列是串行的。正因为如此,它们可以用来完成同步机制, 有点像传统线程中的mutex。

9.谈谈load和initialize的区别

这个题目当时问出来,真的是一下子就傻了,平时虽然用的多,但是真的没有注意比较过他们俩,看来平时学习还是多要问问所以然!

10.Core Data是数据库么?有哪些重要的类?

我当时一看问到是不是的问题,我就留神,感觉应该不是常理的,当时仔细想了想,Core Data确实不是一个数据库,只是把表和OC对象进行的映射,当时并不是进进映射那么简单,底层还是用的Sqlite3进行存储的,所以Core Data不是数据库。

有以下6个重要的类:
(1)NSManagedObjectContext(被管理的数据上下文)
操作实际内容(操作持久层)
作用:插入数据,查询数据,删除数据
(2)NSManagedObjectModel(被管理的数据模型)
数据库所有表格或数据结构,包含各实体的定义信息
作用:添加实体的属性,建立属性之间的关系
操作方法:视图编辑器,或代码
(3)NSPersistentStoreCoordinator(持久化存储助理)
相当于数据库的连接器
作用:设置数据存储的名字,位置,存储方式,和存储时机
(4)NSManagedObject(被管理的数据记录)
相当于数据库中的表格记录
(5)NSFetchRequest(获取数据的请求)
相当于查询语句
(6)NSEntityDescription(实体结构)
相当于表格结构

11. frame和bound 一定都相等么?如果有不等的情况,请举例说明

在上图中,如果蓝色的View旋转了,那么它的frame是外面的大框,而bound是蓝色的边框。

以上是我3月份面试遇到的问到的我一下子没有答全或者没答好的问题,大神全部都会的话请忽略哈。然后还有2个开放性的问题,那基本就是完全考验实力和自己理解的深度了。一个是谈谈你对Runtime的理解,另一个是谈谈你对Runloop的理解,由于我个人这两个理解都不是很深,这里就不贴我的理解了。大家如果也感觉欠缺的,就赶紧去网上多看看吧!

二.机试

这个环节基本都是大公司,或者是复试的时候会出现,因为上机打代码确实很很快区分出谁好谁坏,当然我也面了一家这样的公司,就给一张白纸,全程都是手写代码,这就完全是考验基本功了,因为没了代码补全,没有了编译器告诉你哪里错了,一切都要靠自己的基本功来了。

机试基本就是靠靠算法题了。当然也有算法题在笔试的最后几道题出现,那就看公司面试怎么安排的。

2年前我也是面试iOS,当时对算法和 数据结构要求很低的,很多面试基本都不问这些,今年面试多了这些问题,也让我眼前一亮,也感叹,2年技术发展之快,面试如今都会涉及到算法,不会算法和数据结构的程序员的道路会越走越窄。

算法题,我遇到的都不难,毕竟不是BAT那种公司,简单的就是直接要你写一个算法出来,稍微高级点的就是有一个背景,然后要你解决问题,其实就是和ACM题目一样的,不过就是没有那么复杂。我贴几段问的最多的算法,太难的题只能考自己的算法功底了。

二分查找 θ(logn)

递归方法
int binarySearch1(int a[] , int low , int high , int findNum)
{    
      int mid = ( low + high ) / 2;       
      if (low > high)        
            return -1;   
     else   
     {        
              if (a[mid] > findNum)          
                    return binarySearch1(a, low, mid - 1, findNum);        
              else if (a[mid] < findNum)            
                    return binarySearch1(a, mid + 1, high, findNum);                    
              else            
                    return mid;   
    }
}

非递归方法
int binarySearch2(int a[] , int low , int high , int findNum)
{    
       while (low <= high)
      {
            int mid = ( low + high) / 2;   //此处一定要放在while里面
            if (a[mid] < findNum)           
                low = mid + 1;        
            else if (a[mid] > findNum)            
                high = mid - 1;       
             else           
                return mid;    
    }       
    return  -1;
}
冒泡排序   θ(n^2)
void bubble_sort(int a[], int n)
{
    int i, j, temp;
    for (j = 0; j < n - 1; j++)
        for (i = 0; i < n - 1 - j; i++) //外层循环每循环一次就能确定出一个泡泡(最大或者最小),所以内层循环不用再计算已经排好的部分
        {
            if(a[i] > a[i + 1])
            {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
            }
        }
}

快速排序  调用方法  quickSort(a,0,n);  θ(nlogn)
void quickSort (int a[] , int low , int high)
{
    if (high < low + 2)
        return;
    int start = low;
    int end = high;
    int temp;
    
    while (start < end)
    {
        while ( ++start < high && a[start] <= a[low]);//找到第一个比a[low]数值大的位子start

        while ( --end  > low  && a[end]  >= a[low]);//找到第一个比a[low]数值小的位子end

        //进行到此,a[end] < a[low] < a[start],但是物理位置上还是low < start < end,因此接下来交换a[start]和a[end],于是[low,start]这个区间里面全部比a[low]小的,[end,hight]这个区间里面全部都是比a[low]大的
        
        if (start < end)
        {
            temp = a[start];
            a[start]=a[end];
            a[end]=temp;
        }
        //在GCC编译器下,该写法无法达到交换的目的,a[start] ^= a[end] ^= a[start] ^= a[end];编译器的问题
    }
    //进行到此,[low,end]区间里面的数都比a[low]小的,[end,higt]区间里面都是比a[low]大的,把a[low]放到中间即可

    //在GCC编译器下,该写法无法达到交换的目的,a[low] ^= a[end] ^= a[low] ^= a[end];编译器的问题
    
    temp = a[low];
    a[low]=a[end];
    a[end]=temp;
    
    //现在就分成了3段了,由最初的a[low]枢纽分开的
    quickSort(a, low, end);
    quickSort(a, start, high);
}

注释我也写上了,这些算法基本上简单的算法题都能应对了。

数据结构的题目我就遇到了链表翻转,实现一个栈的结构,先进后出的,树先跟,中跟,后跟遍历,图的DFS和BFS。代码就不贴了,太长了。如果有忘记的,可以再去翻翻回顾一下。

三.面试

面试基本都是问你之前做过什么项目啦,遇到了哪些问题了,自己如何解决的。谈谈对XXX的看法等等这些问题,只要平时认真完成项目,其实面试反而问的东西更好答,因为都是关于你项目的,这些你最了解和清楚了。

好了,到此就是2016年3月上海地区除了BAT公司,招聘iOS开发工程师的行情了,比2年前,最大的体会就是面试面更广了,要求更高了。现在要求除了会OC,还要懂算法和数据结构,还有要么会ReactNative,或者PhoneGap一系列混合开发的框架,或者熟悉Swift,程序员要一直跟上主流才能不能被时代淘汰。才能具有竞争力。这也是我面试了这些公司的感悟,活到老学到老!最后希望大家都和我交流交流,我也是个iOS菜鸟,请大家多多指教!

GitHub Repo:Halfrost-Field

Follow: halfrost · GitHub

Source: https://halfrost.com/ios_interview/

相关文章

网友评论

  • 索努木:大哥,加个好友,求带我飞!你qq私信发我。😄
    一缕殇流化隐半边冰霜:@索努木 已经加了吧?
  • 只懂搬砖的z_bl:现在的面试也是在考查这些内容,只是感觉,现在问的东西越来越深入,或者说,找个切入点,一直刨根揭底的。问到没啥可问:joy: 但了解一个知识点不行。。关键还是看能否融会贯通。。
    只懂搬砖的z_bl:@一缕殇流化隐半边冰霜 有看到发布时间,是的。。也不是说很难,就是真的要了解更多的内容了,不能仅仅局限于OC语言了。。
    感觉毫无希望啊~哈
    一缕殇流化隐半边冰霜:@holiMoIng 嗯,现在就是这样,考察深度也考查广度,我这篇是一年以前的,现在面试题目只会更难!:disappointed_relieved:
  • 某非著名程序员:刚毕业的时候,对上面几个算法挺熟悉的,现在只有印象了。
    一缕殇流化隐半边冰霜:@努力的iOS开发 对,这些都是基本功,需要长时间的修炼。基础才是决定以后在开发的路上可以走多远的因素。基础扎实的人学什么都比较快。
    a63a82f3b861:我曾经面试过阿里,他们对项目经验感觉看得不是很重,而是对底层的理解,思考问题的方式,以及一些算法和数据结构看得很重,但是在快速迭代的互联网行业,对这些底层的东西,真的是不一定能够理解的透彻,还是要平时多积累。
    一缕殇流化隐半边冰霜:@260d120058f7 :kissing_heart: 可以再补习补习呀。。
  • 羊驼先生丶:大神,能不能分享一下算法基础,数据结构基础,网络基础的资料啊,我是转行入的坑,对于ios底层的东西很茫然,对于一些计算的思维完全缺乏。想通过一下基础的东西慢慢了解ios底层的原理。
    羊驼先生丶:@一缕殇流化隐半边冰霜 好的。谢谢你的回答。
    一缕殇流化隐半边冰霜:@羊驼先生丶 这个。。。这些基础我也都是大学的时候学的。。资料可能都是大学课本。。
  • 闭家锁:面了几家知名的,基本都是问到runtime内部原理和底层实现,数据结构算法有笔试
    一缕殇流化隐半边冰霜:@闭家锁 加油!!!你可以的!!我相信你!!
    闭家锁:@一缕殇流化隐半边冰霜 每天加班闷头做项目,项目经历写了一堆,结果问一个基础知识的细节原理实现,马上磕磕巴巴,言非所指了,其实内心是知道这些知识点的,网上也看过很多文章,无奈说不清楚感觉好挫败,打算把书拿起来啃一啃吧
    一缕殇流化隐半边冰霜:@闭家锁 是的,BAT都这样吧。还有TMD
  • 茄子_Apple:霜40,表示人气很旺啊!最近也是在面试,确实都是问的一些原理性的东西,如weak的内部实现,GCD的内部实现之类的!还得多补习一下,表示天天满头做项目,完全没什么进步,还是需要自己多一点总结!继续努力中……
    一缕殇流化隐半边冰霜:@茄子_Apple 嗯。。周末需要自己提升提升。。一起加油进步哈
  • 是小胖阿:想问下11题是指 frame和bound两者的size么?
  • mu_yang:真好,谢谢!
    一缕殇流化隐半边冰霜:@mu_yang 不客气,一起学习
  • MrRight_li:都是面试题库中出现的
    1d7082db2be0:@MrRight_li 求题库地址
  • 7a9b96db00e3:谢谢你说了这么多,写的很好,大神加个好有位行吗?
    7a9b96db00e3:@一缕殇流化隐半边冰霜 649913972
    一缕殇流化隐半边冰霜:@YangSir_ 你想加QQ么??
  • TTanys:mark 感谢分享
  • 选一个昵称也被使用了:大哥
    一缕殇流化隐半边冰霜:@选一个昵称也被使用了 我是小弟 :smiley:
  • carpond:mark
  • 陈阿票:当回调之后要做的任务在每次回调时都是一致的情况下,选择delegate,在回调之后要做的任务在每次回调时无法保证一致,选择block。在离散型调用的场景下,每一次回调都是能够保证任务一致的,因此适用delegate。这也是苹果原生的网络调用也采用delegate的原因。这样回答可不可以?
    一缕殇流化隐半边冰霜:@陈阿票 关于这个问题最好的答案,我觉得还是objc上面那篇文章靠谱
  • _常小仙儿:期待能跟上你的脚步、
    一缕殇流化隐半边冰霜:@爱生活Geek 一起学习:kissing_heart:
  • 逸小山:唉,大公司真心不好进,现在对应届毕业生的要求是真高,之前内推面网易,问的问题和博主说的差不多,前几天面的百度,京东,美团,完全被吊打,问题一点都不常规,顿时懵逼,不过也是自己没有深入了解oc语法,希望今年能找到工作吧,真想问一句,我大iOS是不行了么(⊙o⊙)。 @bestswifter ,对,就要艾特你,百度给我虐待不要不要的,问的题和你发的面经出入挺大的。哭。。。
    一缕殇流化隐半边冰霜:@逸小山 这个。。我当初也看过bs的面试经验的。。基本上那些搞懂了,可以随便面试OC的职位的。。那种水平算百度的水准的。。
    逸小山: @bestswifter 恩恩,我明年和你一起毕业。我积攒够了能力再麻烦博主了。
    逸小山: @bestswifter 嘿嘿,我瞅准你们百度了,以后走社招还麻烦博主给递下简历,先谢谢了。
  • 唐桑阿米达::cry::cry:马上进项目期。好多问题都不懂。大神。能不能加个qq244629996
  • Delpan:现在考算法的是越考越深入了,慢慢地感觉到,越深入系统就越难在开发当中所有体现。
  • 皮皮玥宝:刚看到,能加下qq吗。3508186364
  • 小凉介:大神太厉害了,能否加QQ,漫漫长路走的太困难了,QQ335050309
    小凉介:@一缕殇流化隐半边冰霜 收到了 :smiley:
    一缕殇流化隐半边冰霜:@大神Q 加你了。。看看收到了不??
  • 翼须付出:我马上要辞职了,感觉形势还是不太乐观啊!我也是菜鸟一枚,看了你的文章,感觉自己还有很多不足啊!还是多学习!
    一缕殇流化隐半边冰霜:@翼须付出 那只能每天都学习一点,学习路上没有捷径。
    翼须付出:@一缕殇流化隐半边冰霜 没有,我在帝国的首都-北京!做P2P的,基础不太好,你有什么合适的建议么?感觉有点慌!
    一缕殇流化隐半边冰霜:@翼须付出 你在上海的么??
  • 885389eb08b2:写的很好,收益很多,能否问下博主是几年经验的?
    一缕殇流化隐半边冰霜:@啊左 一起学习:kissing_heart::kissing_heart:
    啊左:@一缕殇流化隐半边冰霜 写的博文很有逻辑,哈哈,赞。
    一缕殇流化隐半边冰霜:@Hissia 我13年毕业的,有3年经验了。。感觉我还是菜鸟:sob::sob:
  • 9c08a27c277b:学习!
  • 孤独的剑客:刚刚看了几篇你写的文章,感觉思路很清晰,了解的也很广泛,希望有机会加个好有一起探讨下

    孤独的剑客:我的微信
    孤独的剑客:mengrenjie55kai
    一缕殇流化隐半边冰霜:@孤独的剑客 那我加你吧。
  • 一缕殇流化隐半边冰霜:可以预测的是今年下半年,swift一定会大量普及,未来肯定是swift的时代!!!要想精通RN,就需要熟练掌握Js ES6规范那些的,要学习的东西还是比较多的。。学好JS,对R N的帮助很大的!!!
  • 1012b281fac1:我觉得你写的很好,我是刚转行的,哈哈感觉好多都不知道,就会用swift做做前端,唉,要学的东西真多,今天又知道了RN,以前根本都不知道这是啥,6月份的开发语言,swift已经超过OC了,是时候增加新技能了,齐头并进吧,最近在学JS,不知道对于RN有没有帮助。反正趋势肯定是快速开发,传统app开发的弊端感觉就是周期长,确实要学一门快速开发的新技能。
    一缕殇流化隐半边冰霜:@名字的问题 可以预测的是今年下半年,swift一定会大量普及,未来肯定是swift的时代!!!要想精通RN,就需要熟练掌握Js ES6规范那些的,要学习的东西还是比较多的。。学好JS,对R N的帮助很大的!!!
  • dbbe0167ce9d:mark 学习
  • 10a96c454ea7:感谢分享 :blush:
  • f97641e05579:thanks share
  • 1e03c3d5f93f:赞!!
  • 鼻毛长长:问算法真的很坑啊= =
    一缕殇流化隐半边冰霜:@鼻毛长长 嗯。。考算法完全就是为了筛选人的。。
  • 飞翔的道长:mark,干货,谢谢
    一缕殇流化隐半边冰霜:@飞翔的道长 嘻嘻。。谢谢。。一起学习!!一起进步!!
  • 阿黎转呀转:支持
    一缕殇流化隐半边冰霜:@阿黎转呀转 我私信你了
    阿黎转呀转:@一缕殇流化隐半边冰霜 可以!加油!有QQ吗,加一个有问题可以探讨下。
    一缕殇流化隐半边冰霜:@阿黎转呀转 谢谢!!一起学习!!相互进步!!
  • _Sven:谢谢前辈分享!
    一缕殇流化隐半边冰霜:@callmeJoeJoe 也不是前辈啦。。相互学习,一起进步:stuck_out_tongue_winking_eye:
  • 英贰与我:感觉你已经很厉害了,好想能和你有交流机会,能提供一些技术指导那就最好不过了,我微信zy877083696,还希望能临幸一下我这刚入行一年多一点点,还不是科班出身的小菜鸟,我都打赏了,加个好友呗
    一缕殇流化隐半边冰霜:@ZZ_running 加你了。。看看了没有
    英贰与我: @一缕殇流化隐半边冰霜 谢谢😜
    一缕殇流化隐半边冰霜:@ZZ_running 好。。我一会加你吧。。相互交流。。。我也走了不少弯路。。一会我加你哈。。
  • 系统盘:其实很难想象要求数据结构和算法,而且就算有用到,其实临时查也能查,但是笔试直接写算法,真的要求很高,而且iOS对算法数据结构要求那么高不懂为什么要这样,很少用到现实中,除非你担任的职位带有领导权,主要最近iOS多了,为了区分面试,加了算法和数据结构,其实考这个还不如考些新的,比如swift比如你说的ReactNative之类,说实话,要我写sqlite的语句我现场也写不出,但是这些东西,用过了就在笔记里,到时候根据需求把笔记进行更改最方便,凭空写出代码来意义何在,考验更快吗,我翻笔记速度能慢到哪里去
    一缕殇流化隐半边冰霜:@我旁边坐了一个胖子 嗯。。是的。。BAT那些考算法和数据结构无外乎是要考一个思维方式,他们可能更需要创造一些新的东西。。而一般的公司在我看来,更多的是想找一个熟练工,进去就能立即产生价值的就能上手的程序员。看今年6月吧,Swift感觉很可能在今年的WWDC上面大放异彩,那估计到今年年底很可能就有替代OC的局势了。我面了达达,这家公司现在也很厉害,他们就只招Swift的,他们全部都是用RxSwift写的。。现在很多小公司项目起步就直接是上Swift,大公司也逐步在用Swift + RN去替换死板的没有动态性的OC。。。我们也需要跟上潮流了!哈哈。。我们一起加油哈!!! :+1: :+1:
    系统盘:@一缕殇流化隐半边冰霜 哈哈,加油,现在iOS比Android多的多,导致市场不景气,所以多学点东西,掌握多一点,少一点失业的几率,慢慢有时间研究swift吧,不久真的会替代OC,不知道具体多久,但是迟早的事,有时间练默写代码的时间拿来学新东西,大部分公司面试还是只要你说并不要你写的,而且咱看来一个字母一个字母分毫不差写出来意义不大
    一缕殇流化隐半边冰霜:@我旁边坐了一个胖子 我很同意你的观点!!我有一个同学去了阿里面试iOS开发,大概有5,6轮,他们最后几轮才是考算法呢,BAT公司考数据结构和算法还好,现在一般公司要是面试也考这些,完全就是为了筛选人。不过今年的iOS的就业形势真的不乐观,我3月那会投了几家还可以的公司,2,3天之后一刷新,都是70多个人投了,iOS现在真的是僧多粥少了。当然啦,你说的又会Swift的,会ReactNative的,精通的还是很少的。。嘻嘻。。一起努力变成大神吧! :stuck_out_tongue_winking_eye: :stuck_out_tongue_winking_eye:
  • 0bc1476dc110:git it
    一缕殇流化隐半边冰霜:@BigFun :stuck_out_tongue_winking_eye::stuck_out_tongue_winking_eye:一起加油努力!!
  • 卖劈柴的小蓝孩:感谢分享
    一缕殇流化隐半边冰霜:@烟花绽那是谁的容颜 嘻嘻。。一起学习进步!!

本文标题:2016年3月iOS面试总结

本文链接:https://www.haomeiwen.com/subject/pymhrttx.html