iOS - 面试宝典将来跳槽用题库

2021年3月iOS面试题

2021-04-15  本文已影响0人  monkey姜啦

一、基础

1.如何令自己所写的对象具有拷贝功能?

2.是如何理解weak属性的?

3.swift 的mutating关键字的使用?

4.UIView 和UILayer的关系

5.@synthesize 和@dynamic分别有什么作用

6.动态绑定

程序在运行时,对象被确定后,这个对象的类型就被确定了,这个对象的属性和响应方法也会被确定。

7.Category、Extension、继承的区别

Category:
Extension:
继承:

8.为什么代理要用weak?delegate 和dataSource有什么区别?block和代理的区别?

9.id 和NSObject *的区别

10.使用系统的block API(如UIView 的动画时),是否要考虑循环引用?

11.@property 申明的NSString、NSArray、NSDictionary 经常使用copy关键字,为什么?改用strong关键字,可能会造成什么问题?

12. static有什么作用

13.Block的循环引用、内部修改外部变量、三种block?

14.对于Objective-C,你认为它最大的优点和最大的不足是什么?对于不足之处,现在有没有可用的方法绕过这些不足来实现需求。如果可以的话,你有没有考虑或者实践过重新实现OC的一些功能,如果有,具体会如何做?

15. 你实现过一个框架或者库以供别人使用么?如果有,请谈一谈构建框架或者库时候的经验;如果没有,请设想和设计框架的public的API,并指出大概需要如何做、需要注意一些什么方面,来使别人容易地使用你的框架。

16. block在ARC中和传统的MRC中的行为和用法有没有什么区别,需要注意些什么?如何避免循环引用?

17. property 默认参数是那些?

值类型:atomic assign readwrite
引用类型:atomic strong readwrite

18.atomic ?atomic和nonatomic的区别?

19.Block变量的截获?

    NSInteger num = 3;
    
    NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
        
        return n*num;
    };
    
    num = 1;
    
    NSLog(@"%zd",block(2)); // 这里的输出是6而不是2

20.NSDictionary 的key有要求吗?

遵守以下协议的类型才可以作为 NSDictionary 的key

21.new 的作用是什么?

22.ARC为什么会有内存泄漏?

23.数据结构有哪些?

常用的数据结构:数组、链表、堆、栈、树、图、散列表、队列

24.iOS设计的原则有哪些?

25.iOS面向对象的特性,重写和重载的区别?

26.iOS设计模式有哪几种?

27.iOS内存中有多少区,每一区的含义和用法?

28.OC类的结构体指针了解?里面有哪些属性?类方法存在哪里,实例方法在哪里?

29.+load和+initialize区别?

1、调用时机不同
+load是在类编译时调用,+initialize是在类第一次发送消息时调用
2、方法调用方式不同
+load是根据方法地址直接调用,+initialize是通过objc_msgSend消息机制调用
3、调用次数不同
+load方法只会调用一次,而父类的+initialize有可能会调用多次
4、调用顺序不同
+load的调用顺序跟类的编译顺序有关,+initialize是跟类的第一次发送有关
5、分类的影响
如果分类实现了+initialize,会覆盖类本身的+initialize调用,而对+load没有影响

30.一个NSObject对象分配多少内存?

31. NSTimer 如何解决循环引用?

image.png

解决办法: 由于循环引用的起因是target,则可以包装一个target,让target是另一个对象,而不是ViewController即可.
1.创建一个集成NSObject的分类TimerWeakTarget,创建类方法---开启定时器的方法
2.TimerWeakTarget.m文件中
3.在下面我们封装的类的方法中,我们将开启定时器的方法 [NSTimer scheduledTimerWithTimeInterval:interval target:timer selector:@selector(fire:) userInfo:userInfo repeats:repeats];中的target换掉了,换成了 本类的对象,timer.在OneViewController中开启定时器的时候直接调用这个类方法,就不会造成循环引用.


image.png

32. setNeedsLayout 刷新UI的时机

关键点

[self setNeedsLayout];
[self layoutIfNeeded];

反之可能会出现布局错误的问题。

二、底层

1.main()之前的过程有哪些?

2.KVO的基本原理?手动触发KVO?swift如何实现KVO?

3.Swift下如何使用KVC

4.swift有哪些模式匹配?

5.OC在向一个对象发送消息时,发生了什么?在向一个nil对象发送消息时,会发生什么?

6.静态库的原理是什么?有没有自己实现过静态编译库,遇到了哪些问题?

7.runloop是用来做什么的?runloop和线程有什么关系?主线程默认开启了runloop 了吗?子线程呢?runloop有哪几种工作模式?

总共是有五种CFRunLoopMode:

kCFRunLoopDefaultMode:默认模式,主线程是在这个运行模式下运行

UITrackingRunLoopMode:跟踪用户交互事件(用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他Mode影响)

UIInitializationRunLoopMode:在刚启动App时第进入的第一个 Mode,启动完成后就不再使用

GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到

kCFRunLoopCommonModes:伪模式,不是一种真正的运行模式,是同步Source/Timer/Observer到多个Mode中的一种解决方案
NSTimer 工作的模式为:DefaultMode、TrackingRunLoopMode、CommonModes下,CommonModes是一个集合,包含DefaultMode、TrackingRunLoopMode,如果timer既要在静态页面和滑动页面使用,那么就把timer运行在CommonModes模式。

8.不手动指定autorelease的情况下,一个autorelease对象会在什么情况下释放,比如在VC的viewDidLoad里面创建?

9.OC的消息转发机制完整的代码实现

20200407160626381.png

10.以+ scheduledTimerWithTimeInterval...的方式触发的定时器,在滑动页面时,定时器为什么会暂停回调?如何解决?

11.如何手动触发一个value的KVO?

分别前后手动调用valueWillChange 和valueDidChange两个方法

12.如何定位和分析项目中影响性能的地方?如何进行性能优化?

13.autoreleasePool 释放的时机

14.自旋锁和互斥锁的区别?

15.单例优缺点?

16.Command+B 和Cammand+R中间发生了什么?

17.内存管理方案TaggedPointer

比较下面两段代码的输出结果
代码1

  
  for (int i = 0; i<10000; i++) {
      dispatch_async(self.queue, ^{
          self.nameStr = [NSString stringWithFormat:@"a"];  // alloc 堆 iOS优化 - taggedpointer
           NSLog(@"%@",self.nameStr);
      });
  }

代码2

    self.queue = dispatch_queue_create("com.aaa.cn", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i<10000; i++) {
        dispatch_async(self.queue, ^{
            self.nameStr = [NSString stringWithFormat:@"内存管理,TaggedPointer,和谐学习不急不躁"];
            NSLog(@"%@",self.nameStr);
        });
    }

结果:
代码1正常运行
代码2发生崩溃

18.[self class] 与 [super class]

下面的代码输出什么?

@implementation Son : Father
   - (id)init
   {
       self = [super init];
       if (self) {
           NSLog(@"%@", NSStringFromClass([self class]));
           NSLog(@"%@", NSStringFromClass([super class]));
       }
       return self;
   }
   @end

NSStringFromClass([self class]) = Son
NSStringFromClass([super class]) = Son

那么objc_msgSendSuper最后就转变成:

// 注意这里是从父类开始msgSend,而不是从本类开始
objc_msgSend(objc_super->receiver, @selector(class))
 
/// Specifies an instance of a class.  这是类的一个实例
    __unsafe_unretained id receiver;   
 
 
// 由于是实例调用,所以是减号方法
- (Class)class {
    return object_getClass(self);
}

三、线程和网络

1.串行和并行,并行和并发,异步和同步的区别?

2.线程是什么?进程是什么?两者有什么区别和联系?

3.物理内存和虚拟内存间的关系?

4.有没有考虑过用户通过分享,启动app时,push到app的二级页面的场景优化?

5.在异步线程发送通知,在主线程接收通知。会不会有什么问题?

6 .内存管理的几条原则是什么?按照默认法则,哪些关键字生成的对象需要手动释放?使用property的时候,怎样避免内存泄露?

7.dispatch_barrier_async的作用是什么?

8.如何用GCD同步若干个异步调用?(如根据若干个URL异步加载图片,在图片都下载完成后合成一张图片)

9.http与https 的区别?

10.对称加密和非对称加密的概念以及有哪些使用?

11.服务器能否知道APNs推送后有没有到达客户端?

12.你用过NSOperationQueue么?如果用过或者了解的话,你为什么要使用NSOperationQueue,实现了什么?请描述它和GCD的区别和类似的地方(提示:可以从两者的实现机制和适用范围来描述)

13.慢启动?

传输控制协议(TCP)使用的一种阻塞控制机制。

14.TCP如何建立连接?

(1) 服务端通过socket,bind和listen准备好接受外来的连接,此时服务端状态为Listen
(2)客户端通过调用connect来发起主动连接,导致客户端TCP发送一个SYN(同步)字节,告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号,客户端状态为SYN_SENT。
(3)服务器确认(ACK)客户的SYN,并自己也发送一个SYN,它包含服务器将在同一连接中发送数据的初始序列号。
(4)客户端确认服务的ACK和SYN,向服务器发送ACK,客户端状态ESTABLISHED
(5)服务器接收ACK,服务器状态ESABLISHED。

15.为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

16.TCP 如何确定数据的可靠性?

能够保证TCP协议可靠的算法有

详解
https://www.jianshu.com/p/c4e53e5f2c58

17.TCP和UDP的区别?

18.http的请求方式有几种,每种的概念?

19.GET与POST的区别?

20.ARP是否了解?

地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个[TCP/IP协议]

21.一次完整的HTTP请求是怎么样的?请求由哪几部分组成构成?响应由哪几部分构成?

22.HTTP2.0与HTTP 1.1相比,主要区别包括

HTTP/2采用二进制格式而非文本格式
HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个连接即可实现并行
使用报头压缩,HTTP/2降低了开销
HTTP/2让服务器可以将响应主动“推送”到客户端缓存中

22.粘包处理

给每个数据包添加头部,头部中包含数据包的长度,这样接收到数据后,通过读取头部的长度字段,便知道每一个数据包的实际长度了,再根据长度去读取指定长度的数据便能获取到正确的数据了


image.png

完整的数据包 = 服务号 + 数据包长度 + 数据
数据包头 = Id(4B) + length(4B) 共占用8字节
数据包 = length(假设占100个字节)
所以这条消息的长度就是108字节可以看到,要想知道一条完整数据的边界,关键就是数据包头中的length字段

四、APP

1.什么方式可以看到上架App的头文件?

2.阅读过哪些框架的源码?能说说它的架构方式吗

3.iOS iAP内购审核可能失败的问题?

4.IAP内购中虚拟货币导致审核无法通过的问题?

五.算法

1.假设有一个字符串aabcad,请写一段程序,去掉字符串中不相邻的重复字符串,即上述字符串处理之后的输出结果为:aabcd

- 比较前后相邻的字符串,重复且相邻的字符放入容器A
- 不重复的字符遍历容器A,如果不存在则放入容器A
- 最后得到容器A就是满足条件的字符串集合

- (NSString *)deleteRepeatString:(NSString *)str{
    NSMutableArray *components = [[NSMutableArray alloc]init];//存放需要保留的容器
    [components addObject:[str substringWithRange:NSMakeRange(0, 1)]];//第一个不需要删除
    for (int i = 1; i < str.length-1; i ++) {//第一个不需要判断,最后一个在末尾判断
        NSString *curStr = [str substringWithRange:NSMakeRange(i, 1)];
        NSString *preStr = [str substringWithRange:NSMakeRange(i-1, 1)];
        NSString *nextStr = [str substringWithRange:NSMakeRange(i+1, 1)];
        // 当前的字符与前后比较,相同的保留
        if ([curStr isEqualToString:preStr] || [curStr isEqualToString:nextStr]) {
            [components addObject:curStr];
            continue;
        }
       
        BOOL isRepeat = NO;
        for (int j = 1; j <components.count; j ++) {//处理单个字符的情况,遍历到容器中还没有出现,就保留单个字符
            NSString *copareStr = components[j];
            if ([curStr isEqualToString:copareStr]) {
                isRepeat = YES;
                break;
            }
        }
        if (!isRepeat) {
            [components addObject:curStr];
        }
    }
    if ([[str substringWithRange:NSMakeRange(str.length-1, 1)] isEqualToString:components.lastObject]) {
        [components addObject:components.lastObject];
    }
    NSString *reslutStr = [components componentsJoinedByString:@""];
    NSLog(@"%@",reslutStr);
    return reslutStr;
}

2.两个数m、n,如果m=2,n=5,用递归实现2 3 4 5相加= 14

- (int )sum:(int )m :(int )n{
    if (m == n){
        return m    
    }   
    if (m > n){
        int tmp = m
        n = m
        m = n
    }
    return sum(m,n-1)+n
}

3.自定义宏 #define MIN(A,B) A<B?A:B 代码运行结果?

float a = 1;
float b = MIN(a++,1.5);
问 a= ? b = ?
答案: a = 3; b = 2
a++ 会后执行, a++在表达式出现了2次,得3,  a++<1.5,返回a++,得2

// 扩展
float a = 1;
float b = [self getMax:a++ b:1.5];
- (CGFloat)getMax:(CGFloat ) a b:(CGFloat)b{
   return a>b?a:b;
}
运行 a = 2; b =1.5;

4.找出字符串中重复最多的字串?

- 第一步:取出第一个字符
- 第二步:遍历相同的字符
- 第三步:判断是否拼接
- 第四步:拼接的字符串超过输出字串就赋值

//@"asdfghjklwertyuivbhnhghfhvvddssssssssbvfvvccccccccccc";
- (NSString *)getSubString:(NSString *)input{
    NSString *outString;
    int i = 0;
    NSString *tmpStr = [input substringWithRange:NSMakeRange(0, 1)];
    while (i < input.length-1) {
        NSString *curStr = [input substringWithRange:NSMakeRange(i, 1)];
        if ([tmpStr rangeOfString:curStr].location == NSNotFound ) {
            tmpStr = curStr;
        }else{
            tmpStr = [tmpStr stringByAppendingString:curStr];
        }
        
        if (tmpStr.length > outString.length) {
            outString = tmpStr ;
        }
        I++;
    }
    NSLog(@"outString == %@",outString);//outString == cccccccccc
    return outString;
}
上一篇 下一篇

猜你喜欢

热点阅读