美文网首页iOSiOS面试相关iOS 开发
《孙源Sunny 面试小灶》直播笔记

《孙源Sunny 面试小灶》直播笔记

作者: 天空中的球 | 来源:发表于2016-10-23 17:49 被阅读1216次

    前两天的直播: **孙源的面试小灶直播- 简历、面试题、进阶 **,今天回看,特此笔记下。

    话说那个经典的 招聘一个靠谱的 iOS 的面试题 就是孙源出的。

    直播中的要点:

    • 1、面试中的一些问题
    • 2、印象比较深的两个题,特别是第二个
    • 3、iOS进阶的话题

    1、面试中的一些问题

    • 注意最近一个工作经历(最重视,尽量详细)
    • 细节问题:
      大小写、空格之类的,说明的就是标准式,可用 MarkDown
    • 可以提供更多的信息来体现你的特别
      github、blog 的展示
    • 专业技能: 到底用这个做过什么?(例如 runtime 具体做过什么,Category 添加属性?替换方法?)
    • 项目经验: 也是尽量详细, 可多描述下,自己所处团队中的位置,自己做了一些什么 模块。
    sunny 的面试套路

    另外面试中, 要注意沟通的流畅性,不知道的也可以试探性回答,甚至请教;不要老久不说话,也不要装 X,更不要造假 。

    2、印象比较深的两个题,特别是第二个

    2-1、 array0 为什么有问题?
    copy strong
    • array0 也是有问题的,当外面传入一个NSMutableArray的时候,会产生一些不必要的麻烦
    • array1 和 array2 是正常的
    • array3 是有问题的,copy 后会让 array3 从NSMutableArray 变成 NSArray ,后期假如使用 插入、删除之类的方法时,就会出现 Crash 的。

    此处我的疑惑是 array0 ,因为我一般就是这样写的,虽说传 NSMutableArray 的时候,我一般会 mutableArray.copy 的,但是偶尔也有没传的时候,但是没有出问题啊? 这个一下子没有想到例子...

    后来再次看那经典的面试题: 【招聘一个靠谱的 iOS 参考答案(上)】才重新理解了(它里面那个例子错了,可能手误)。

        NSArray *array = @[@1, @2, @3, @4];
        NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
        self.array0 = mutableArray;
        [mutableArray removeAllObjects];;
        NSLog(@"array0 == %@",self.array0);
        
    

    array0 打印出来就是空的,像上面中当我们使用是 strong ,那么这个array0 就指向一个可变对象, 如果这个可变对象在外部被修改了,那么会影响该属性。
    父类指针可以指向子类对象,使用copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本。

    2-2、 Block 的瞬间执行

    例如为什么 在下面的方法中,self 不需要写 __weak__strong

        [UIView animateWithDuration:1.0f animations:^{
            self.view.alpha = 0.5f;
        }];
    

    因为它是瞬间执行的,这个 UIView animationPush 之后,马上就执行了,所以这个 Block 里面不会持有这个 self,所以就不会造成循环引用啦,所以就不需要写啦。

    怎样让这个 Block 不被执行呢

    对于这个问题,Sunny 给出了七种方法...

    • ** 1、借助他人, 传入Block ,立即执行掉**
        - (void)blcokProblemAnswerOne:(void(^)(void))block {
        // 让他人帮我们调用
        // 立即调用
        [UIView animateWithDuration:0 animations:block];
        // Or GCD
        dispatch_async(dispatch_get_main_queue(), block);
      }
    
    • 2、 也是借助他人,传入Block ,手动让其销毁
     - (void)blcokProblemAnswerTwo:(void(^)(void))block {
       [[NSBlockOperation blockOperationWithBlock:block] start];
     }
    
    • 3、NSInvocation 这个类动态实行方法
      - (void)blcokProblemAnswerThree:(void(^)(void))block {
        [[NSInvocation invocationWithMethodSignature:[NSMethodSignature signatureWithObjCTypes:"v@?"]]invokeWithTarget:block];
        
        // v@? 需要详细了解下
      }
    

    顺便看看 动态组一个 OC 方法的调用

      - (void)testUserInvacation {
        NSMethodSignature *singnature = [self methodSignatureForSelector:@selector(description)];
        NSInvocation *invacation = [NSInvocation invocationWithMethodSignature:singnature];
        invacation.target = self;
        invacation.selector = @selector(description);
        [invacation invoke];
      }
    
    • 4、内部 NSBlock 的方法,这是隐式的API
      // 此处推荐了 一个工具  DLIntrospection
      - (void)blcokProblemAnswerFour:(void(^)(void))block {
        [block invoke];
      }
    
    • 5、 通过Blcok 内存的结构来处理
    // 需要对指针、地址很熟悉
      - (void)blcokProblemAnswerFive:(void(^)(void))block {
        
       /**
        struct Block_layout {
            void *isa; // 指针
            int flags; // 什么类型 (int32_t)
            int reserved; // int32_t
            void (*invoke)(void *, ...); // C 函数的指针,真正的调用
            struct Block_descriptor *descriptor;
            // Imported variables.
        };
        */
        
        // 目的是找到   void (*invoke)(void *, ...) 这个方法
        // 实际上就是 首地址 看偏移多少,前面总共 16 (isa== 8, flag == 4, reservaed == 4)
        
        void *pBlcok = (__bridge void *)block;
        // 这个 加 2, ???
        void (*invoke)(void *, ...) = *((void **)pBlcok + 2);
        invoke(pBlcok); // 传第一个参数
      }
    
    • ** 6、利用 Clang 中一些节点,完全懵的**
      static void blcokCleanUp(__strong void(^*block)(void)) {
          (*block)();
      }
    
      - (void)blcokProblemAnswerSix:(void(^)(void))block {
          __strong void(^cleaner)(void) __attribute ((cleanup(blcokCleanUp),unused)) = block;
      }
    
    • 7、内联一个汇编 完成调用,完全醉了
      - (void)blcokProblemAnswerSeven:(void(^)(void))block {
         //  block(); // dis 找到其 方法的来源
          asm("callq *0x10(%rax)");
      }
    

    这真的是大开眼界啊,个人第一种和第二种还能接受,第三种和第五种是想要掌握,其他的还是看看吧,确实是涨知识啦!!!像 NSInvocation 就得立马去补补啦!

    PS1: class 关键词用于 property 的新特征 , 表示类的属性,和 Swift 桥接的。

    @interface TestObject : NSObject
    @property (nonatomic, class) TestObject *shareObject; // 尽量让其访问权限最小
    @end
    
    

    可以更好的写单例

    // 写单例,都可以直接, 这样写啦
    + (TestObject *) shareObject {
    }
    

    PS2: DLIntrospection 一个很赞的工具
    可以获取 NSObject 的 属性、方法、继承结构之类的 ,看Sunny 用的很爽。

    DLIntrospection

    3、iOS进阶的话题

    单靠知识点累计还不行,需要有自己的思考,对技术的主见
    将各个知识点串联起来形成自己的东东。

    sunny 的视频点

    对于我个人来说,对我很有启发的是:

    • 写文章可以用点代替面,注意积累
    • 丁字领域说法不错,发展一门深的,其他的都融会贯通啦
    • 对于知识点的深挖,挖到自己不能再挖为止,后期还得经常反思、串联,然后形成自己体系。

    而我最大的问题,就是每次浅尝即止,没能刨根问底!

    另外Sunny 的说:写博客就要写别人没写过的,我想对于我来说是有待商榷的,个人应该是说写博客要追求别人没写过的!毕竟目前还是以记笔记为主,希望得先积累多一些点吧!


    最后,Sunny 为大家带来了福利,之前的视频下载地址,包括 他之前 Clang 和 RunLoop 的视频,,非常赞,也非常感谢!

    相关文章

      网友评论

      • 陈鸡蛋:哥们,之前的视频下载地址失效了,可以发我一下吗谢谢:smile:
      • 庆先:优秀

      本文标题:《孙源Sunny 面试小灶》直播笔记

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