美文网首页
面试总结

面试总结

作者: Q14 | 来源:发表于2018-05-17 09:48 被阅读0次

    OC基础部分

    优质链接:面试相关
    面试300题

    关于block

    这是一篇很好的帖子

    1. block有三种类型:NSConcreteStackBlock,NSConcreteMalloBlock,NSCroncreteGlobalBlock。
      1.1 当block只捕获了外部局部变量,成员属性变量,没有强应用的block时候,block就是在栈上,执行完,立即释放。
      1.2 当block执行了copy操作,或者有强引用指向他的时候,block就是Malloc类型的。由程序员控制其生命周期,没有强引用的时候,释放。
      1.3 当block只引用了静态变量和全局变量的实话(没有用到外部变量肯定是_NSConcreteGlobalBlock),block是Global类型的。如果引用了全局变量和静态变量的同时,又引用了局部变量,那该block仍是stack

    2. block的copy和释放,分别是调用了:block_copy和block_release

    3. __block的前后
      3.1 被__block修饰过的变量,对应的会多出一个结构体 __block_byref_a_0。其中的__forwarding指针,就是指向自身类型的指针。
      3.2 这个被block修饰过的变量a,就对应的转换成这个结构体类型的变量a。
      3.3 然后,这个结构体类型的a的地址会被传入__main_block_imp_0内部,在构造方法中给a(__block_byref_a_0类型)赋值。
      3.4 那么,在__main_block_func_0方法中,通过__cself->a,取到__block_byref_a_0结构体变量,然后再通过a->forwarding->a,对相应的变量进行值的操作。

    4. 关于ARC和MRC
      4.1 ARC的情况下,一旦block被赋值,那就会执行copy操作,__block类型的变量就会被拷贝到堆上,block也是NSMallocBlock。
      4.2 MRC的情况下,只有执行copy方法,才会对应的copy,否则__block一直都在栈上,block也是NSStackBlock,forwarding指向的就是自身。
      4.3 ARC下的对象类型的变量,加了__block之后,在block内部会对变量进行retain,会造成循环引用。
      4.4 MRC情况下,block不会对__block对象本身进行复制,而是复制了他的指针而已。
      4.5 在ARC的情况下,block通过“=”赋值时,会调用:objc_retainBlock->block_copy->block_copy->internal方法链,从而将StackBlock转变为MallocBlock。

    5. 但是如果在block内部使用延时操作还使用弱指针的话会取不到该弱指针,需要在block内部再将弱指针强引用一下

    self和super的区别

    原来self是返回instancetype类型的代理方法,但又有些奇怪,我们在自定义子类的时候并没有实现这个方法,我认为self的功能,OC已经帮我们实现,只是我们看不到而已。这样就明确了,self最终返回的结果就是instancetype类型的东西,它是动态类型,最终运行时才会确定,实例方法返回实例类型、静态方法返回的是Class。

    当遇到super关键字时,编译器会生成一个objc_super结构体,作为消息的接收者,objc_super结构体使得接收消息的父类的定义被明确化。
    所以,super的含义应该是一种编译指令,它的作用用来给父类发送消息,并返回消息响应的结果。

    问题一:self = [super init]是面向对象思想的一种体现,意义就是,利用父类的init方法为子类初始化父类的公有属性。问题二:理解这个先要明确alloc和init的区别,alloc为对象开辟内存,init是对象初始化,所以,[super init] 是初始化在子类上的,super发出消息的主体对象是子类,和self是同一个对象。 class方法和self类似是NSObject协议中的代理方法,我认为class的功能,OC也已经帮我们实现在每个子类中,只是我们看不到而已,所以不管是super还是self发出的class消息,执行的时候,都在子类中,返回的都是子类。

    调用当前类的方法发消息时,调用的是:objc_msgSend(id, selector, params)
    调用父类的方法发消息时,调用的是:objc_msgSendSuper(struct objc_super *super, selector, params)
    其中,objc_super是一个结构体,里面有接收者和他的父类,这里的接收者在内存中就是当前实例,只不过,他寻找方法是先从父类的方法列表中去寻找而已。

    参考
    参考

    常见的面试题

    招一个靠谱的iOS程序员(上)

    招一个靠谱的iOS程序员(下)
    https://github.com/ChenYilong/iOSInterviewQuestions/blob/master/01%E3%80%8A%E6%8B%9B%E8%81%98%E4%B8%80%E4%B8%AA%E9%9D%A0%E8%B0%B1%E7%9A%84iOS%E3%80%8B%E9%9D%A2%E8%AF%95%E9%A2%98%E5%8F%82%E8%80%83%E7%AD%94%E6%A1%88/%E3%80%8A%E6%8B%9B%E8%81%98%E4%B8%80%E4%B8%AA%E9%9D%A0%E8%B0%B1%E7%9A%84iOS%E3%80%8B%E9%9D%A2%E8%AF%95%E9%A2%98%E5%8F%82%E8%80%83%E7%AD%94%E6%A1%88%EF%BC%88%E4%B8%8B%EF%BC%89.md

    关于runtime

    1. runtime如何添加属性和方法。
    2. runtime如何实现weak属性
    3. runtime如何通过selector找到对应的IMP方法实现的?
    4. runtime使用Associate方法关联的对象,需要在dealloc中释放吗
    5. _objc_msgForward是做什么的,直接调用会发生什么?
    6. 能否想编译后得到的类中增加实力变量?运行中呢?为什么?
    7. 描述方法调用的流程(基于runtime的角度)
    8. 什么是method swizzling?

    答:
    1.1 class_addMethod(Class cls, SEL name, IMP imp, const char *types)
    1.2 class_addIvar(Class cls, const char *name, size_t size,
    uint8_t alignment, const char *type)
    1.3 _class_addProperty(Class cls, const char *name,
    const objc_property_attribute_t *attrs, unsigned int count,
    bool replace)
    1.4 class_addProtocol(Class cls, Protocol *protocol_gen)
    1.5 class_replaceProperty(Class cls, const char *name,
    const objc_property_attribute_t *attrs, unsigned int n)

    1. weak变量都在一个哈希表中,对象的地址是key,value是一个weak引用的地址的数组。当一次runloop结束,自动释放池里引用计数为0的对象会被销毁,那么就会用他的地址去weak表中找到对应的value数组,把数组中的变量置为nil。所以,在ARC的情况下,不需要把weak属性在dealloc中置nil。

    2. 想对象发送消息时,调用objc_msgSend方法,第一个参数就是当前对象,通过对象的ISA指针,找到对应的类,然后在类的方法缓存列表中查找对应的SEL,如果没有,就到method_list中去查找,如果还没有,就到父类的方法列表中查找。目标方法的SEL是一个结构体,里面的有方法名字SEL和方法的具体实现:IMP,二者是对应的,所以直接取到IMP执行。另外,如果调用类方法,则到元类的方法列表中去找,如果找不到,直接到跟类的元类中去找,跟类要是找不到,直接到异常。另外,调用父类的方法,是调用的objc_msgSendSuper方法,第一个参数是一个objc_super结构体,里面有receiver(接收者,当前对象),super_class,这时候检索SEL就先去superclass里面去找。

    3. 无论是ARC还是MRC,都不需要对关联的对象进行释放。这些关联的对象会比被关联的对象释放的晚,他们会被NSObjcet的dealloc调用的object_dispose方法中释放。
      步骤如下:当前对象release,父类dealloc,NSObject调dealloc,调用object_dispose

    4. _objc_msgForward是IMP类型,用于消息转发的:当向一个对象发送一条消息,但是对象又没有实现它,就会触发转发。

    5. 不能向编译后得到的类中增加实例变量,因为

    6. 使用runtime Associate方法关联的对象,需要在主对象dealloc的时候释放么,对象的释放时间表。
      不需要,

    关于runloop

    非常详细
    可以参考

    1. runloop是啥:运行循环。主线程的runloop默认开启,无论如何都做不到手动关闭他。

    2. runloop作用是啥:为线程监听事件源,控制线程的调起和休眠。还可以和自动释放池配合管理内存:比如,局部变量是加入到当前最近的自动释放池里面去的,那自动释放池什么时候开始清理这些变量呢?处理自动释放池销毁,那就是当前运行循环结束,这个时候,自动释放池节点里的数据会被遍历发送release消息。

    3. runloop的使用场景:控制定时器,开启一个常驻线程[[NSRunloop currentRunloop] addPort:[NSPort port] forModel:NSDefalutRunloopModel];这样可以让某些事件、行为在某些模式下运行。

    4. CFRunLoopObserverRef是观察者,每个observer都有一个回调,当runloop的状态发生变化时,观察者就能在回调中获取到这个变化。变化的观测时机有:
      typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
      kCFRunLoopEntry = (1UL << 0), // 即将进入Loop
      kCFRunLoopBeforeTimers = (1UL << 1), // 即将处理 Timer
      kCFRunLoopBeforeSources = (1UL << 2), // 即将处理 Source
      kCFRunLoopBeforeWaiting = (1UL << 5), // 即将进入休眠
      kCFRunLoopAfterWaiting = (1UL << 6), // 刚从休眠中唤醒
      kCFRunLoopExit = (1UL << 7), // 即将退出Loop
      };

    关于http

    1.http常用的方法类型和含义
    • GET 请求指定的页面信息,并返回实体主体。
    • HEAD 请求报文头部,不返回消息体。
    • POST 向指定资源提交数据,数据包含在请求体中,他可以在服务器端生成不存在的资源,也可以替换原有的老资源。
    • PUT 用传递的新数据取代服务端指定数据
    • DELETE 请求删除指定的服务器的页面
    • TRACK 返回服务器收到的请求,主要用于测试或诊断,跟踪请求是否到达
    • OPTIONS 允许客户端查看服务器的性能
    • CONNECT 预留的能将链接改为通道的代理服务器

    关于加密

    对称加密和非对称加密
    对称加密:加密和解密用同一个密钥(因为需要在数据传输之前传递密钥和密文,所以一旦被截获,还是很危险的。)DES,AES,
    非对称加密:加密和解密用不同的密钥,加密用公钥,解密用私钥。RSA,
    加密原理
    原理二
    所以,建立连接的过程用非对称加密,保证密钥能安全传递,然后在数据传递的过程中用对称加密,以提高效率.

    MD5:不可逆的加密方式,不能解密,任意长度的数据加密之后都是16进制的32位数据。

    base64:
    base64的编码都是按字符串长度,以每3个8bit的字符为一组,
    然后针对每组,首先获取每个字符的ASCII编码,
    然后将ASCII编码转换成8bit的二进制,得到一组3*8=24bit的字节
    然后再将这24bit划分为4个6bit的字节,并在每个6bit的字节前面都填两个高位0,得到4个8bit的字节
    然后将这4个8bit的字节转换成10进制,对照Base64编码表 (下表),得到对应编码后的字符

    面试过程中问到的

    1.如果监听了一个readonly的属性,kvo会怎么处理?如果我们给这个属性添加了setter方法呢?为什么要创建一个新类?
    参考链接

    答:如果想要监听一个readonly属性,那么,在外部不能直接调用其setter方法(强行添加setter方法会连编译都通不过),可以通过一个传值的方法,结合KVC,来给这个只读属性赋值。
    - (void)careDog:(id)dog {
        [self setValue:dog forKey:@"aDog"];
    }
    
    1. 开始监听。当一个对象的属性被使用 KVO 监听的时候,系统会自动生成一个以 NSKVONotifying_ 打头的临时的类,然后将这个对象的 isa 指针指向这个临时的类;
    
    2.当监听的属性是 readwrite 的时候,并不会往这个属性的 setter 方法里插入 -willChangeValueForKey: 和 -didChangeValueForKey: 等方法,而是系统会在设置属性的值的时候调用 _NSSetObjectValueAndNotify 方法,这个方法会发送一条通知,然后 NSKeyValueNotifyObserver 这个监听者监听到值的改变的时候,会发送一个通知调起 -observeValueForKeyPath
    
    3.如果没有重写 -willChangeValueForKey: 和 -didChangeValueForKey: 方法,这两个方法就不会被调起。
    
    为什么要创建一个子类来实现?
    
    可以这样说,如果我们不通过创建子类,那可以通过什么方法来实现呢?
    提前知道的:通过子类继承父类属性并重写了它的setter方法,当这个属性被改变时,KVO 就可以观察到。通过method_swizzling方法来进行观察值?注意:如果内存当中有多个该类的实力,那这些事例都会受到影响。如最常用观察的UITableView的contentOffset, 此处如果直接在 Setter 方法中用 method_swizzling 的方法,那么所有的UITableView都会受到影响,而我们一个 App 中不止一个UITableView。
    

    2.用runloop做过什么功能?如何保证runloop不退出,除了timer之外还能添加什么方式?afn有一个关于runloop的经典处理,需要了解下。
    详细链接

    2.1 NSTimer的model切换
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
    2.2 ImageView的延迟加载
        [self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"tupian"] afterDelay:4.0 inModes:NSDefaultRunLoopMode]; 
    

    3.用多线程做过什么?各种常见锁的优缺点?
    各种多线程实现的方式

    锁:@synchronized 互斥锁
        优点:能有效防止因多线程抢夺资源造成的数据安全问题。
        缺点:需要消耗大量的CPU资源。
        
        自旋锁:原子操作的时候就是自旋锁,效率很高。
    
    具体的使用场景:图片上传,不阻塞主线程。复杂耗时的数据处理,
    UIGraphicsGetImageFromCurrentImageContext + drawInRect = 图片合成。
    

    4.组件化的本质,组件之间如何通讯。

    原则:上层依赖下层,下层服务不能依赖上层。同层级的服务尽量不要耦合。封闭固定不变的参数,暴露变化的参数。
    
    1.基础底层服务组件:网络,缓存,日志等。
    
    2.基础业务组件:登录、分享、推送、基础UI等。
    
    3.基础工具组件:颜色宏、设备信息宏、字符串处理相关。
    

    参考资料

    5.jsonmodel自己如何实现,如何做对象的映射。

    6.通知中心一定要在Delloc中移除监听吗,如果不移除会有什么后果?通知中心对当前类(观察者)是强引用吗,也就是说通知中心是怎么管理那些监听者的?
    实现原理
    多线程角度
    iOS9以后通知中心的变化
    7.MVVM的真正价值在哪里,他和MVC相比,解决了什么问题。

    8.截屏部分,如果再子线程中操作UIKit的UIImage,会报警告吗?

    消息发送

    1.向对象发送消息的流程

    2.向类发送消息的流程

    3.向nil发送消息的流程

    1.  如果一个方法返回值是一个对象,那么发送给nil的消息将返回0(nil)。
    例如:Person * motherInlaw = [[aPerson spouse] mother];
    如果 spouse 对象为 nil,那么发送给 nil 的消息 mother 也将返回 nil。
    
    2. 如果方法返回值为指针类型,其指针大小为小于或者等于sizeof(void*),float,double, long double 或者 long long 的整型标量,发送给 nil 的消息将返回0。 
    
    3. 如果方法返回值为结构体,发送给 nil 的消息将返回0。结构体中各个字段的值将都是0。 
    
    4. 如果方法的返回值不是上述提到的几种情况,那么发送给 nil 的消息的返回值将是未定义的
    

    4.消息转发流程

    4.1 首先在当前类里判断有没有实现 - (BOOL)resolveInstanceMethod方法,如果有,且返回YES,则执行该方法,我们可以在这个方法中为对象动态添加目标方法,class_addMethod(instance, SEL, IMP, "params")。然后,消息转发流程会重新调用一次。
    4.2 如果第一步失败,那么进入第二步,指定另一个响应该方法的target, - (id)forwardingTargetForSelector,返回另一个新对象来相应当前方法。如果返回nil对象,或者self,则进行下一步,否则就会重新对新对象发送消息。
    4.3 这也是最后一步,是创建一个新对象来接受消息 - (NSMethodSignature *)methodSignatureForSelector 获取到消息的参数和名字,如果返回nil,则最终处理找不到方法,程序crash。else,- (void)forwardingInvocation
    

    @synthesize

    1、在头文件中用@property声明一个属性名,编译器会自动为我们转换成这个属性名的getter方法和setter方法。

    2、在实现文件中使用@synthesize propertyName,编译器先会查找这个属性名的setter方法和getter方法有没有被人为实现,如果已经实现,则不再实现,如果没有,则会帮我们生成一个属性命的setter方法和getter方法。

    3、当在实现文件中使用了@synthesize propertyName,编译器还会做一件事情,在类成员变量中查找一个名为_propertyName的成员变量,如果没有,再继续查找名为propertyName的成员变量,如果这两个都没有,编译器会自动为我们生成一个私有的名为_propertyName的成员变量。注意,系统自动创建的都是私有的。

    4、当在实现文件中这样写@synthesize propertyName = varName;时,setter和getter方法所对应的是一个名为varName的成员变量,修改和读取的是varName成员变量的值。

    5、当我们在实现文件中不写@synthesize propertyName时,在Xcode 4.5之前的版本不会帮我们自动实现setter和getter方法,系统当然也不再会为我们生成对应的成员变量。但是在Xcode 4.5之后可以不用写@synthesize了,就跟3、4一样了。

    6、当我们既定义了@synthesize,又在实现文件中人为重写setter和getter方法时,那么@synthesize将不再工作,也就不会为我们创建没有定义的_propertyName成员变量了,这时候如果在setter和getter方法中调用_propertyName将会发生编译错误!@property 后面可以有哪些修饰符?

    深拷贝、浅拷贝

    NSString:
    在非集合类对象中:对 immutable 对象进行 copy 操作,是指针复制,mutableCopy 操作时内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制。用代码简单表示如下:
    • [immutableObject copy] // 浅复制
    • [immutableObject mutableCopy] //深复制
    • [mutableObject copy] //深复制
    • [mutableObject mutableCopy] //深复制

    NSArray,NSDictionary
    在集合类对象中,对 immutable 对象进行 copy,是指针复制, mutableCopy 是内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制。但是:集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制。用代码简单表示如下:
    [immutableObject copy] // 浅复制
    [immutableObject mutableCopy] //单层深复制
    [mutableObject copy] //单层深复制
    [mutableObject mutableCopy] //单层深复制

    UIKit部分

    table的优化

    1. 缓存高度
    2. table中耗时操作、计算、图片处理的功能放到子线程移步处理
    3. 条件绘制:1、滑动时不加载图片,2、高速滑动时,只处理停下来的那几个cell
    4. 少用透明图层(避免离屏渲染)
    5. 尽量减少subviews的数量(减少cell的层级,因为渲染层级树是一个耗时的操作)
    6. 在heightForRowAtIndexPath:中尽量不使用 cellForRowAtIndexPath:,如果你需要用到它,只用一次然后缓存结果
    7. 避免动态给cell添加view。如果有必要,可以开始就添加,不想显示就隐藏,需要显示才显示。

    朋友总结

    资深开发基础深入:

    • DSYM是什么,原理
    • 设计模式的分类,怎么写抽象工厂和工厂方法
    • layoutsubview和drawrect被调用时机
    • iOS消息与响应者原理,如何利用消息转发防止没有实现的方法闪退
    • 什么是内存泄漏和野指针,发生的场景有那些
    • NSOperation能不能取消,一定会取消?
    • iOS事件有哪些种类
    • 从GCD角度说同步异步,并行串行, GCD原理?
    • runloop和timer的关系
    • 遇到哪些闪退场景,怎么防范
    • method和selector的区别
    • autoreleasepool 参考
    • 宏define与常量const 参考
    • 深浅拷贝 参考
    • Http的请求,包含哪些?头部包含哪些?请求本身包含哪些, 如何进行传输瘦身?gzip?原理?有没有其他更好的方案?
    • iOS底层

    内存管理

    1.assign、weak、strong、copy的区别。assign、weak造成野指针和内存泄露的原因。
    1.1. runtime如何管理weak变量的。

    1.2 如果一个c类型的结构体,需要用什么关键字修饰。
        property可以声明结构体类型的属性,但是必须要之名struct,并且必须用assign。因为结构体不是对象。
    

    2.所有权修饰符的用法:__strong,__weak,__autoreleaseing,__bridge

    3.自动释放池的机制,自动释放池到底是什么


    4.深拷贝/浅copy
    mutable --> copy 深拷贝
    mutable --> mutablecopy 深拷贝
    imutable --> copy 浅拷贝
    imutable --> mutablecopy 深拷贝

    如果这些事集合类型,则对应的深拷贝为单层深拷贝。即:只拷贝对象本身,对象里面的对象指针不拷贝。

    UIKit

    1. UIButton、UIView、UIViewController的层级结构:
      UIButton ->UIControl -> UIView-> UIResponder -> NSObject
      UIViewController -> UIResponder -> NSObject

    2. UIView和UIWindow的关系。
      UIWindow是UIView的子类。

    3. UIView和CALayer的关系。

      UIView继承于UIResponder, UIResponder继承于NSObject,UIView可以响应用户事件。CALayer继承于NSObject,所以CALayer不能响应事件。UIView构建界面, UIView侧重于对内容的管理,CALayer侧重于对内容的绘制。UIView是用来显示内容的,可以处理用户事件;CALayer是用来绘制内容的,对内容进行动画处理,依赖与UIView来进行显示,不能处理用户事件。
      UIView:属于UIkit.framework框架,负责渲染矩形区域的内容,为矩形区域添加动画,响应区域的触摸事件,布局和管理一个或多个子视图UIWindow:属于UIKit.framework框架,是一种特殊的UIView,通常在一个程序中只会有一个UIWindow,但可以手动创建多个UIWindow,同时加到程序里面。UIWindow在程序中主要起到三个作用:1、作为容器,包含app所要显示的所有视图2、传递触摸消息到程序中view和其他对象3、与UIViewController协同工作,方便完成设备方向旋转的支持CAlayer:属于QuartzCore.framework,是用来绘制内容的,对内容进行动画处理依赖与UIView来进行显示,不能处理用户事件。UIView和CALayer是相互依赖的,UIView依赖CALayer提供内容,CALayer依赖UIView一共容器显示绘制内容。

    block

    1.block是什么?block类型的属性为什么要用copy修饰?一定得用copy吗?block的底层是怎么实现的?block有几种类型?

    2.使用block要注意什么?循环引用问题。修改外部变量问题。

    补充……

    js/native交互

    1.wk和UIWebView之间区别,探底。


    2.jscore的原理


    3.其他三方框架

    补充……

    runtime

    1.oc动态性表现在那些方面?

    2.oc对象的本质是什么,从消息的发送说一下runtime的工作流程。

    3.消息转发

    4.IMP,SEL,Method都是啥


    5.方法交换,可用于无痕埋点

    6.常用的给类添加方法和属性的API
    objc_setAssociatedObject
    objc_getAssociatedObject
    objc_removeAssociatedObjects

    category

    1.跟runtime有什么关系,从runtime的角度对category 的原理进行分析。

    struct objc_class {
    Class isa OBJC_ISA_AVAILABILITY;

    if !OBJC2

    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
    

    endif

    } OBJC2_UNAVAILABLE;

    struct objc_category {
    char *category_name OBJC2_UNAVAILABLE;
    char *class_name OBJC2_UNAVAILABLE;
    struct objc_method_list *instance_methods OBJC2_UNAVAILABLE;
    struct objc_method_list *class_methods OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
    } OBJC2_UNAVAILABLE;

    2.为什么不能给category添加属性,但是写了属性也不报错。

    3.和extension的区别

    多线程

    1.GCD/NSOrperationQueue的区别。

    2.说说线程依赖。NSOrperation能不能取消,一定可以取消吗?

    3.常用的API的用法

    4.加锁的方法,死锁的场景。

    5.串行、并行。进程、线程。

    6.线程间通讯。

    7.runloop的本质,各个model的区别。runloop和线程的关系。



    1. 从多线程的角度分析共享数据和私有数据。

    2. GCD和NSOperationQueue功能能完全对等吗?
      GCD和线程队列的区别第二篇
      不能,队列可以取消,可以设置最大并发数MaxConcurrentOperationCount,但他也可以通过dispatch_semaphore_t信号量来控制。

    补充……

    关于锁

    各种锁

    UIkit & Fundation

    1.事件类型有哪些。具体了解响应者和响应链。

    2.table的性能优化

    3.常用控件的继承体系,比如UIButton和UITableView

    4.APP的加载过程,他的各个状态。

    5.UIView和CALayer的区别。

    补充……

    KVO & KVC

    1.各自的实现原理。
    绝金iOS

    2.有什么优缺点,其他三方库的替代方案

    补充……

    网络

    1.http/HTTPS的区别,TCP和UDP的区别,get和post本质的区别

    2.一个请求的报文是什么。响应报文是什么。

    3.TCP方式cs之间的链接过程。

    4.HTTPS加密请求数据的过程


    5.如何对AFN进行二次封装。为什么afn用block而不用delegate?

    补充……

    数据采集

    代码埋点

    无痕埋点

    架构

    1.常用架构MVC、MVP、MVVM的区别,优缺点。


    2.组件化,中间件

    3.cocoapods管理库

    4.自动化集成Jenkins,fastlane

    5.reactivecocoa的原理

    补充……

    优化

    电量、启动速度、CPU占用、网络优化

    补充……

    数据结构和算法

    常用的排序查找方式,时间、空间复杂度



    其他几乎都是这几种推演过来的

    其他

    1.dsym是什么?

    2.内存分析工具

    3.缓存设计(存储安全,过期删除问题,以sd为例分析)

    4.数据加密

    5.设计模式

    6.iOS编译过程

    面试题

    hr面试问题

    1.作为技术经理,如何管理你的团队,如何激励员工,采取过哪些措施

    作为技术出身,我最能体会团队成员最根本的关注点在哪。举个例子,一个中级工程师最关切的往往是如何明确地规划自己以后的职业发展方向、技术侧重点等这些问题,这些也恰是我当初深为困惑的,我会经常和我的组员进行工作之外的沟通,了解他们的想法,针对他们不同时期的不同问题和他一起讨论,加上自己的一些经验,给出最终的一个建议。一个团队最重要的是活力,而这些年轻的组员恰是这些活力的提供者,我所作的是在恰当的时候点燃他们的热情,让他们始终抱有希望。具体的措施就主要体现在每个季度开始前的工作、学习计划安排,以及季度末的绩效审评。
    
    1. 和PM或其他部门发生意见分歧时,如何处理。

      主要还是沟通的技巧,明确自己的目标、可以接受的底线,沟通开始先抛出一个hight的目标,以谈判的方式把最终达成的协议控制在自己的底线之上。这是原则,可以接受让步,恰当照顾沟通方的感受,以最终达成协议为目的。另外需要注意的就是沟通中的措词,尽量避免“我”,“必须”,“我不管”这些字眼,取而代之可以用“我们”,“最好”,“我们可不可以”。

    2. 对你帮最大的人是谁?怎么看待你的前领导?(你能从他们身上学到什么?要客观,又要谦虚。)

      之前的组长,他身上有种不怕失败,勇于尝试的韧劲儿,只要是自己既定的目标,从不浅尝辄止,都要把他们弄的十分透彻,并且尽最大努力将其运用到工作中来,以提高我们的工作效率和稳定性等等。从不半途而废,即使这个问题临时搁浅,他也会挤时间把他落地。

    1. 你的优缺点是什么?

      缺点:有时候自己脑海中迸发一个想法之后,会固执己见坚持他是对的,想尽办法会将其付诸实施,这个过程中同事如果有一些否定的意见,自己会听不进去,除非他的说辞比较完美。这样的后果会导致不能及时听取他人意见,发现自己想法的弊端,这也是我正在努力改正的。

      优点:主观能动性强,能够及时了解自己的缺点并改正,与人交流过程中善于换位思考,做事注重效率、注重目标主导策略、注重及时暴露风险等。

    2. 工作中什么事是最困难的是什么?怎么解决?

      说服我的上级同意我的方案。当然,我自己作为小组leader的时候,也存在不能及时听取他人意见的时候,总是坚持自己是对的,从而导致其他组员一些好的想法被否决。针对这一问题,我深入的思考过,这也是我现在正刻意让自己做的一件事:换位思考。

    3. 最有意义的一些事是什么?

      主导推进自动化打包平台,解放了所以程序员在打包上浪费时间的问题。投入产出比非常高。

    4. 和别人相比,你的优势在什么地方?
      我经常反思自己的不足,花在这上面的时间要比我回顾自己获得的成就上的时间要多很多。这让我在以往这几年有很大的进步,当然,由于精力有限和公司快速迭代等原因,我的进步空间还有很大,这也恰是我现在思考的一个问题,如何让自己从一个称职的员工变成一个优秀的员工,推而广之,如何把我自身的这些想法总结成解决问题的原则,来帮助更多的人。作为一个技术经理,我认为这是我最核心的优势之一,其他还有很多,如果有幸成为同事,我们在以后的工作中可以做更加深入的探讨。谢谢。

    1. 阿里的核心竞争力:

      执行力

      管理者的指责:让员工成长、成功,这才是管理者的成功,管理者要以身作则。要考虑员工需要什么样的成长,什么样的机会,

      高远的目标和极强的使命感,使命:“让天下没有难做的生意”

      客户第一、团队合作、拥抱变化、激情、诚信、敬业,六脉神剑

    1.oc的内存管理机制,能说多少说多少。
    
    2.block你了解多少?讲讲原理,使用过程中的注意事项。
    
    3.runloop的实现原理是什么?你用runloop做过哪些事?了解AFN中关于runloop的经典用法吗?你用多线程做过什么?
    
    4.你在工作中是是用gcd多还是nsoporationQueue多?为什么?
    
    5.你怎么理解组件化?你们在组建化方面都做了哪些?有什么难点吗?怎么解决的?
    
    6.kvo和kvc的实现原理?kvo有点麻烦,有没有更好的设计方案来使用它?
    
    7.https的数据请求流程是什么?对称加密和非对称加密都扮演什么样的角色?
    
    8.数据安全你们是怎么做的?登录部分的session是怎么和h5同步的,如何保证他的安全性?
    
    9.怎么获取用户操作过程中出现的屏幕卡顿?卡顿的基本原因是什么?
    
    10.热修复用过什么方案,除了jspath,还了解其他的吗?jspath的核心原理是什么?
    
    11.如何预防类似数组越界造成的crash?
    
    12.一个数组分为两部分,前面升序,后面降序,如何快速的找到最大值?
    
    13.写一个递归,递归的缺陷在哪?如何优化递归?
    
    14.你用MVVM解决了什么痛点?说说你对MVVM的理解。
    
    15.对你影响最大的一个人是谁?
    
    16.工作中最有成就的是什么事?
    
    17.和同事意见不一致,你该怎么解决?如果是领导呢?
    

    相关文章

      网友评论

          本文标题:面试总结

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