记录陌陌iOS岗位的面试题

1,815 阅读6分钟
		* [记录陌陌iOS岗位的面试题](#记录陌陌ios岗位的面试题)
		* [暮色四合](#暮色四合)
		* [花灯初上](#花灯初上)
		* [子夜](#子夜)

记录陌陌iOS岗位的面试题

本人前一段时间面试了陌陌iOS岗位,到了今天应该是没下文了。可能还是自己的一些知识不全面,还是不能胜任该公司的开发要求。所以还需努力,和大家一块进步。

暮色四合

不过本次的面试过程是很舒服的,问题也很新颖,面试很开放,一问一答中不呆板。平常面试中,一定会碰到一些我称之为“烂大街”的问题

如一下问题:

  1. 谈谈你对ARC的理解
  2. Category如果覆盖了原有类的方法时会调用哪一个方法
  3. 分类的方法什么时候加载的?加载到那里
  4. Category和Exteion的区别
  5. autoreleasePool
  6. 怎么解决循环引用(__weak,__block)
  7. weak怎么实现的
  8. kvc/kvo
  9. 自旋锁和互斥锁的区别(一看就是百度的)
  10. 可变数组(NSMutableAray)能用copy修饰吗 ...........

花灯初上

回顾一下本次陌陌面试中我还能记得到得问题如下,供各位看官查看(答案仅供参考)

  1. 手机app的启动流程 解: app启动可以分为两种:1:冷启动 2:热启动 这里说的就是冷启动。首先冷启动会分为3个大阶段
  • 第一阶段=>dyld加载阶段

    1. 装载app启动的可执行文件,同时递归加载所有依赖的动态库
    2. 当dyld把可执行文件,动态库,装载完毕后,会通知runtime进行下一步操作
  • 第二阶段=>runtime阶段

    1. 调用map_images进行可执行文件内容的解析和处理
    2. 在load_images中调用call_load_mthods,调用所有class和Category的+load方法
    3. 进行各种Objc结果的初始化(注册objc类,初始化类对象等)
    4. 调用C++的静态初始化器和__attribute_修饰的函数
    5. 到此,可执行文件和动态库中所有的符号(calss,protocl,selector,imp)都已经按格式成功加载到内存中,被runtime所管理
  • 第三阶段=>main函数启动 这里就调用Appdelegate中得didfinfishLaunchWithOptions函数

 总结一下:
 1. app启动有dyld主导将可执行文件加载到内存,顺便加载所有依赖的动态库
 2. 由runtime负责加载成objc定义的结构
 3. 所有初始化结束后,dyld会调用main函数
 4. 这里就调用Appdelegate中得didfinfishLaunchWithOptions函数
  1. 操作系统为什么会设计栈空间和堆空间 解: 由各个内存区域的特点和单一性来说
  2. 栈空间会扩容吗 解: 操作系统的栈空间足够大
  3. 栈溢出是什么 解: 由于栈一般默觉得1-2m,一旦出现死循环或者是大量的递归调用,在不断的压栈过程中,造成栈容量超过1m而导致溢出。
  4. 队列和线程的关系 解: 只有在异步线程(async)和非主队列(主线程是特殊的串行)是要开辟子线程的
  5. .a和framework的区别和加载顺序 解:
  • .a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。
  • .a文件不能直接使用,至少要有.h文件配合,.framework文件可以直接使用。 -.a+ .h + sourceFile = .framework。 建议用.framework。
  • 静态库的优势 1.方便共享代码,便于合理使用。 2.实现iOS程序的模块化。可以把固定的业务模块化成静态库。 3.和别人分享你的代码库,但不想让别人看到你代码的实现。 4.开发第三方sdk的需要。
  • 运行 1.静态库:链接时完整的拷贝到可执行文件,多次使用多次拷贝,造成冗余,使包变的更大。 2.动态库:链接时不复制,程序运行时由系统加在到内存中,供系统调用,系统加在一次,多次使用,共用节省内存。
  1. autorelease什么时间释放(不是autoreleasepool) 解: 系统的主runloop启动时,会有两个observer的监听,具体叫什么名字说不上来了,但是有一个observer的名字是含有autorelease字符的。这两个监听,是监听进入(entry),退出(exit),休眠(wairt)。即会调用objc_autoreleasepoolpush()用objc_autoreleasepoolpop(),用objc_autoreleasepoolpush(),用objc_autoreleasepoolpop()函数。所用autorelease修饰的对象就是由runloop控制,是这对象所属的runloo循环中,runloop休眠前调用release
  2. 变量什么时候释放 解: ARC:局部变量,在代码段结束释放。 MRC:局部变量,在调用release释放
  3. 一个线程对应一个runloop吗?(注意这里不是runloop对应一个线程) 解: 是对应的。每条线程都有一个对应的runloop。但是线程刚刚创建的时间是没有runloop对象,runloop会在第一次获取他的时候创建。默认么有启动 但是当我们手动开启一个thread的时候,他是没有runloop对象。因为线程执行完就会被系统回收,对象会被释放,runloop也会再这个时候销毁。如果一直有runloop就会一直活着,不会被释放。这个和AFN早起的常住线程有点关联把
  4. time能再异步线程中执行吗? 解: 不能!!! 即便将定时器加到runloop中,主要是子线程中runloop默认未开启,所以代码最终不会执行。我们需要单独启动runloop。 如果在子线程中访问,当子线程结束时候,runloop就会释放,线程会被回收和释放。而此时time也会被释放掉。
  5. 怎么修改对time引起的循环引用 解:
  • 如果用的是block回调,就用烂大街的方法在bock里把self若引用掉,让__weak修饰的对象在引用计数为0的时候自动释放
  • 如果用的是target方式调用,可以创建一个中间对象, 把self传入,并转为弱引用对象,在调用消息转发到该弱引用对象上执行。 此时VC强拥有timer,而timer强持有这个中间类,而中间类弱持有self。即不存在循环应用关系。你还可以利用NSProxy处理该循环引用问题。
  1. 索引是什么 解: 都知道主键是一个数据库表的唯一表示列。 那么索引是对数据库表中的一列或者多列的值进行排序的一种数据结构,如果把数据库中的表比作一本书,索引就是这本书的目录,通过目录可以快速查找到书中指定内容的位置

索引也是一张表,该表中存储着索引的值和这个值的数据所在行的物理地址,使用索引后可以不用扫描全表来定位某行的数据,而是通过索引表来找到该行数据对应的物理地址

  1. main函数启动之前能做哪些启动优化 解: 二进制重排(感觉有没有搞过不要紧,但是你要知道!!!)

子夜

最后给了一个算法如下

最接近的三数之和(给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数, 使得它们的和与 target 最接近。返回这三个数的和)

例如,
给定数组 nums = [-121-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

请看下一篇文件,讲解该算法

ps:上述如有问题,请留言告诉我。3Q

如果你觉得可以请扫描我的公众号

洲洲