面试-年初面试问题精选

来源:互联网 发布:你曾是少年 知乎 编辑:程序博客网 时间:2024/05/20 16:11

PS: 文章是从垃圾箱找出来的,之前误删了,看有些问题还是挺好的,所以再次发布出来。


Block在哪个内存区?

block块的存储位置(block入口的地址)可能存放在3个地方

  • 全局区
    • 不引用栈区的变量(如局部变量)和堆区的变量(如用alloc创建的对象)时,此时block存放在代码区
  • 堆区
    • 访问了堆区的变量,此时block存在于堆区
  • 栈区(MRC)

    • 访问了栈区的变量,此时block存在于栈区,在ARC情况下自动拷贝到堆区

    注:ARC情况下会自动拷贝到堆区、因此ARC下只有两个地方:全局区和堆区


如何实现深拷贝?

  • 1、基本数据类型直接可以实现深拷贝
  • 2、自定义数据类型需要实现NSCoping协议,并调用 copyWithZone:这个方法

手写冒泡排序算法

OC语言
NSMutableArray *nums = @[@2,@34,@8,@23,@5,@54,@333,@9].mutableCopy;        for (int i = 0; i < nums.count; i++) {            for (int j = 0; j < nums.count - i - 1; j++) {                if (nums[j] > nums[j+1]) {                    NSNumber *temp = nums[j];                    nums[j] = nums[j+1];                    nums[j+1] = temp;                }            }        }    NSLog(@"%@",nums);// 打印结果(    2,    5,    8,    9,    23,    34,    54,    333)
C 语言
int nums[7] = {10,8,5,27,6,22,90};    for (int i = 0; i < 7; i++) {        for (int j = 0; j < 7 - i - 1; j++) {            if (nums[j] > nums[j+1]) {                int temp = nums[j];                nums[j] = nums[j+1];                nums[j+1] = temp;            }        }    }    for (int i = 0; i < 7; i++) {        printf("%d  ",nums[i]);    }

MVC 和 MVVM 区别及各自的优缺点?

MVC:

作为老牌架构, 优点在于将业务场景按展示数据类型划分出多个模块, 每个模块中的C层负责业务逻辑和业务展示, 而M和V应该是互相隔离的以做重用, 另外每个模块处理得当也可以作为重用单元. 拆分在于解耦, 顺便做了减负, 隔离在于重用, 提升开发效率. 缺点是没有区分业务逻辑和业务展示, 对单元测试不友好.


MVVM:

作为集大成者, 通过数据绑定做数据更新, 减少了大量的代码工作, 同时优化了代码逻辑, 只是学习成本有点高, 对新手不够友好.

MVVM 优点:
  • 1、由于展示逻辑被抽取到了 ViewModel 中,所以 View 中的代码将会变得非常轻量级;
  • 2、由于 ViewModel 中的代码是与 UI 无关的,所以它具有良好的可测试性;
  • 3、对于一个封装了大量业务逻辑的 Model 来说,改变它可能会比较困难,并且存在一定的风险。在这种场景下,ViewModel 可以作为 Model 的适配器使用,从而避免对 Model 进行较大的改动。

MVVM+RAC 结合使用实现双向绑定

通过KVO和RAC的RACSignal实现双向绑定

详见个人博客:

iOS-ReactiveCocoa(RAC)的高级使用之视图与模型的双向绑定


单利的几种实现方式

1、自己创建
+(instancetype)sharedSingleton {    static id instance = nil;    @synchronized (self) {        if (!instance) {            instance = [[self alloc] init];        }    }    return instance;}
2、通过GCD的dispatch_once创建(推荐)
+(instancetype)sharedSingleton{    static id instance = nil;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        instance = [[self alloc] init];    });    return instance;}

Swift 与 Objective-c的区别

  • 1、强语言,更加严谨,每写一行代码系统都会自动检测是否有错误,这样就减少了运行后出错的可能;
  • 2、代码简洁,文件减少,语法简洁已读
  • 3、有命名空间
  • 4、性能更好,可以理解为没有C的OC,舍去了C,编译过程比OC少了一层
  • 5、没有了宏定义,摒弃了OC大量使用宏的弊端
  • 6、……自行补充吧,很多细节有变化,比如:懒加载,单例

Swift 中的@objc的作用

  • 在 Swift 代码中,使用@objc修饰后的类型,可以直接供 Objective-C 调用
  • Swift 为了效率禁用了 Objective-C 中有的动态特性,通过 @objc 关键字来使用动态特性

一个视图,旋转45度,frame和bounds如何变化?

frame会发生改变,而且变大,bounds不变

这里写图片描述

子视图旋转45度后:
这里写图片描述


WKWebView与H5交互,遇到的问题(项目中印象深的一个问题之一)?

用WKWebView与H5交互的时候,交互不成功,alert( )方法不被调用!不管是通过原声的交互方法,还是第三方,都不提示alert(),以为无法进行交互!最后发现WKWebView不支持JS的弹窗,需要自己实现对应方法,才可以显示alert弹窗。


KVO的底层实现?

Runtime
当你观察一个对象时,一个新的类会动态被创建。这个类继承自该对象的原本的类,并重写了被观察属性的 setter 方法。自然,重写的 setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象值的更改。最后把这个对象的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么 ) 指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例。


出现crash的情况有哪些?项目中遇到的哪些crash?

数组越界、野指针、数组插入空对象、拷贝自定义对象、类型不匹配、方法找不到……


一个类,实现了多个分类,实现了父类的同一个方法,执行顺序?

方法只会执行一次,谁第一个实现的分类,执行谁的分类方法实现


同一个线程,发出通知,自己的类中有一个观察者,其他类也有观察者,他们的执行顺序?

谁先注册,谁先执行


SDWebImage内部实现过程

  • 1、先把placeholderImage显示,然后 SDWebImageManager 根据 URL 开始处理图片;
  • 2、SDWebImageManager 从缓存查找图片是否已经下载;

    • 先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,前端展示图片
    • 如果内存缓存中没有,根据 URLKey 在硬盘缓存目录下尝试读取图片文件
  • 3、如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片;

  • 4、下载完成,回调给需要的地方展示图片;
  • 5、将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。

属性中的 copy 和 strong

  • 在平时定义属性的时候,对于NSString 和 block 我们经常用 copy 来修饰
  • 数组和字典等类型用 strong 来修饰;
  • 当使用 copy 修饰属性的时候,属性的setter方法会调用[object copy]产生新的对象,
  • 这样,当原object对象的值发生改变时,并不影响新对象值;
// 定义NSString @property(nonatomic, copy) NSString *name;// 当调用上面的copy的时候,等价于下面的代码- (void)setName:(NSString *)name {      if (_name != name) {         [_name release];          _name = [name copy];       }}

当使用 strong 修饰属性的时候,属性的setter方法会直接强引用该对象,
这样,当原object对象的值发生改变时,新对象的属性也改变;

例如:我们平时使用strong修饰的NSMutableArray,这个可变数组在当前文件中只有一个,而且是可变的;

/** 数组 */ @property(nonatomic,strong)NSMutableArray  *array; ` ` `  // 当调用上面的strong的时候,等价于下面的代码 -(void)setArray:(NSMutableArray *)array{          _array = array;   }

GCD的具体运用

  • 同步/异步 + 串行/并发队列的组合
  • 延迟执行(dispatch_after)
  • 只执行一次(dispatch_once)
  • 快速遍历(dispatch_apply)
  • 创建线程群组
    开启多条线程,去执行群组中的任务,当群组内的三个任务执行完毕后,再去执行notify里面的任务
    • 创建屏障线程队列
      会优先执行屏障前面的任务,当屏障前的所有任务执行完毕后,再去执行后面的任务
原创粉丝点击