• iOS面试题01-多线程网络


    1.面试题方向:

    1>.多线程+网络

    2>.项目(简历上的项目,每一个细节:技术实现细节、业务、项目周期、人数)

    3>.性能优化:图片优化、内存优化(tableView的循环利用)

    4>.常见的小操作:发布程序、真机调试、推送

    5>.OC:内存管理(重点,ARC与非ARC区别)、语法细节、偏僻的语法

    2.面试题

    1.多线程的底层实现?

    答:1>回答可以从”多线程“是从哪个系统中开始使用:Mach是第一个以多线程方式处理任务的系统,

    因此多线程的底层实现的底层机制是基于Mach的线程

    2.>回答多线程的使用环境:多线程处理包括Core Data的多线程访问,UI的并行绘制,异步网络请求

    以及在运行态内存吃紧的情况下处理大文件的方案等 

    3>回答并且举例说明iOS提供的多线程的实现方法:iOS中提供了以下几种处理多线程的实现方式

    1.回答C语言中的POSIX接口,通过导入库#include <pthread.h>

    2.多线程使用方法

    1>.NSOBjcet实现

    // 最简单的多线程 执行方式
        // 参数1:需要在后台(子线程)执行方法
        // 参数2:给这个方法传参
        [self performSelectorInBackground:@selector(btnUpClicked:)withObject:nil];
    View Code

    2>NSThread实现

    // 优点:在所有的多线程实现方式中  最轻量级
    //      可以按照需求 任意控制thread对象 即:线程的加锁等操作
    // 缺点:控制太繁琐 不能自己控制线程安全
        // NSThread 的一个对象 就代表一个线程
        NSThread *thread = [[NSThread alloc]initWithTarget:selfselector:@selector(btnUpClicked:)object:nil];
        [thread start];
        [thread release];
    View Code
    3>NSOperation实现
    // NSOperation代表一个任务 自己不能实现多线程
    // NSOperation是一个抽象类 不能直接使用 需要创建一个子类去编写实现的内容
    // 任务开始 会在当前线程执行任务(main方法中的代码)
     
        MyOperation *operation = [[MyOperation alloc] init];
        [operation start];
        [operation release];
         
        // 系统已经写好了两个类 可以直接使用
    //    NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:<#(id)#> selector:<#(SEL)#> object:<#(id)#>]
        NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
                // 填写你要执行的任务内容
        }];
    View Code
    @implementation MyOperation
     
    - (void)main
    {
        // operation在main方法中写要执行的任务
         
        static int count = 0 ;
         
        for (int i = 0 ; i < 600000000; i ++) {
            count ++;
        }
        NSLog(@"%d", count);
         
        // 判断当前任务是否为主线程  0为不是 1为是
        BOOL b = [NSThread isMainThread];
        NSLog(@"%d", b);
         
        NSThread *thread = [NSThread currentThread];
        NSLog(@"当前线程为:%@", thread);
         
    }
    @end
    View Code

    4>NSOperationQueue

     // 任务队列(NSOperationQueue) 内部管理一些列的线程
         
        MyOperation *op1 = [[MyOperation alloc] init];
        MyOperation *op2 = [[MyOperation alloc] init];
        MyOperation *op3 = [[MyOperation alloc] init];
        MyOperation *op4 = [[MyOperation alloc] init];
         
        NSOperationQueue *queue = [[NSOperationQueue alloc] init];
         
        // 设置最大并发数
        [queue setMaxConcurrentOperationCount:2];
         
        [queue addOperation:op1];
        [queue addOperation:op2];
        [queue addOperation:op3];
        [queue addOperation:op4];
         
        // 优点:能够自己管理 线程安全 能够合理的安排线程 降低系统的开销 提高对线程的利用率
        // 缺点:可读性差 写起来比较繁琐
    View Code

    5>GCD

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0) ,^{
         //下载图片
         dispatch_async(dispatch_get_main_queue(),^{
             //回到主线程
         });
    });   
    View Code

     2.线程是如何通信的?

    1>回答线程通信:一条线程回到另外一条线程(一个线程数据传输到另外一条线程 )

     

    2>线程通信第一种方法(performSelector,performSelectorOnMainThread)

     

    3>.线程通信第二种方法(NSMarchPort)

    主线程可以通过NSMarchPort输入给子线程NSMarchPort,反之亦可


    3.网络图片处理问题中怎么解决一个相同的网络地址重复请求的问题?

    回答:利用字典(图片地址为key,下载操作为value)

    4.用NSOperation和NSOpertionQueue处理A,B,C三个线程,要求执行A,B后才能执行C,怎么做?

    回答:

    //创建队列
    NSOperationQueue *queue = [[NSOperation alloc]  init];
    
    //创建3个操作
    NSOperation *a = [NSBlockOperation blockOperationWithBlock:^{
           NSLog(@"operation--a");
          
      }];
    NSOperation *b = [NSBlockOperation blockOperationWithBlock:^{
           NSLog(@"operation--b");
          
      }];
    NSOperation *c = [NSBlockOperation blockOperationWithBlock:^{
           NSLog(@"operation--c");
          
      }];
    //添加依赖
    [c addDependency:a];
    [c addDependency:b];
    
    //执行操作
    [queue addOperation:a];
    [queue addOperation:b];
    View Code

    5.列举cocoa 中常见对几种多线程的实现,并谈谈多线程安全的几种解决方法及多线程安全怎么控制?

    回答:1>只在主线程刷新访问UI

         2>如要要防护资源抢夺,得用synchronied进行加锁保护

             3>如果异步操作要保证线程安全等范围,尽量使用GCD(有些函数默认是安全的,默认加锁)

    6.GCD内部怎么实现?

    回答:1>iOS的OS X核心是XNU内核,GCD是基于XNU 内核实现的,

             2>GCD的API全部在libdispatch库中

             3>GCD的底层实现主要有Dispatch Queue和Dispatch Source 

        ~ Dispatch Queue :管理block(操作)

        ~Dispatch Source:处理事件(比如线程通信)

          GCD的block存放在队列:底层实现主要存在队列

    7.你用过NSOperationQueue ?如果用过或者了解的话,你为什么要用NSOperationQueue实现了什么?

    请描述它和GCD的区别和类似的地方?

    回答:1>GCD是纯C语言的API, NSOperationQueue是基于 的OC版本封装

         2>GCD只支持FIFO(先进先出)的队列,NSOperationQueue可以很方便地调整执行顺序(可以添加依赖顺序执行)设置最大并发数量

         3>NSOperationQueue可以轻松在Operation间设置依赖关系,而GCD需要写很多的代码才能实现

             4>NSOperationQueue支持KVO,可以检测operation是否正在执行(isExecuted)、是否结束(isFinished)、是否结束(isCanceld) 

         @1.KVC:间接通过字符串类型的key取出对应的属性值

       KVC的价值:

       #1.可以访问私有成员变量的值

       #2.可以间接修改私有成员变量的值(替换系统自带的导航栏、tabbar)

            #3.KVC valueForKey与valueForKeyPath区别:

       ^1.valueForKey:只能访问当前对象的属性

       ^2.valueForKeyPath:能利用,运算符一层一层往内部访问属性

             5>GCD的执行速度比NSOperationQueue快

         任务之间不太互相依赖:GCD

             任务之间有依赖、或者要监听任务的执行情况:NSOperationQueue

    8.提到GCD,那么 问一下在使用GCD以及block时要注意一些什么?他们两是一回事么?

    block在ARC中和传统的MRC中行为和用法有没有什么区别,需要注意一些什么?

    回答:Block使用注意:

      1>block的内存管理

      

      block进行copy操作后(堆空间对所引用的对象产生一个强引用,对p对象产生一个强引用,就会造成循环引用):

       附:block只要不进行copy操作,block内存永远在栈内存当中,就不会对所引用对象产生强引用

             block存储于堆空间,就会对block内部所用到的对象产生强引用

        

       block 进行weak操作后(弱指针引用)  

        

       附:ARC如果block进行copy防止内存泄露可以使用 __unsafe_unretained typeof(对象)释放内存,解决循环引用

        非ARC可以使用__block typeof(p) 解决循环引用

          变量前添加__block,传入地址

      2>防止循环retain

      @非ARC(MRC):_block

      @ARC:_weak/__unsafe_unretained

           block进行copy操作后,对象在,block就存在,

    9.在异步线程中下载很多图片,如果失败了,该如何处理?请结合RunLoop重新发送网络请求

    回答:1>重新下载图片

            2>下载完毕,利用RunLoop的输入源回到主线程刷新UIImageView

          

  • 相关阅读:
    算法-动态规划 Dynamic Programming--从菜鸟到老鸟
    DTW动态时间规整
    安装splash
    安装 Tesserocr (填坑)
    pip3 install tesserocr安装失败(已解决)
    从头到尾彻底理解傅里叶变换算法
    ruby之——安装gem提示:Please update your PATH to include build tools or download the DevKit
    关于0x80000000为什么等于-2147483648和负数在内存上储存的问题
    html5 canvas
    html5 视频和音频
  • 原文地址:https://www.cnblogs.com/linmingjun/p/4784230.html
Copyright © 2020-2023  润新知