美文网首页
2019-01-27 面试题

2019-01-27 面试题

作者: Fisland_枫 | 来源:发表于2019-01-27 10:13 被阅读7次

    [TOC]

    1 设计模式是什么? 你知道哪些设计模式,并简要叙述。

    1. 单例模式
    2. 通知模式
    3. 代理模式
    4. 工厂模式

    2 多线程有什么作用?怎样实现线程间通信?

    iOS有三种多线程方式,NSThread、NSOperation、GCD,越往后抽象程度越高,使用起来越简单,也是苹果越推荐

    1. NSThread, 最轻量级,相对简单,但是需要自己手动管理所有的线程活动,如生命周期,线程同步,睡眠等。
    2. NSOperation,自带线程周期管理。操作上可以更注重自己的逻辑,但是面向对象的抽象类,只能实现它或者它定义好的两个子类,NSInvocationOperation和NSBlockOperation
    3. GCD,最高效,避开并发陷阱。一般安全有简单可以使用NSOperation.而处理大量并发数据,

    线程之间通信

    1. 主线程进入子线程
    2. 子线程回到主线程
    //常用方法
    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
    
    //GCD
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            NSLog(@"donwload---%@", [NSThread currentThread]);
            
            // 1.子线程下载图片
            NSURL *url = [NSURL URLWithString:@"http://d.jpg"];
            
            NSData *data = [NSData dataWithContentsOfURL:url];
            
            UIImage *image = [UIImage imageWithData:data];
            
            // 2.回到主线程设置图片
            dispatch_async(dispatch_get_main_queue(), ^{
                
                NSLog(@"setting---%@ %@", [NSThread currentThread], image);
                
                [self.button setImage:image forState:UIControlStateNormal];
            });
        });
    

    3 简要概述 UDP 与 TCP 通讯协议的区别。

    区别 TCP UDP
    有无连接 面向连接的协议 五连接协议
    可不可靠 可靠(丢包会自动重传) 不可靠
    有无序 有序(可以对其乱序的重排序) 无序
    有无界 无界(通过字节流传输) 有界(每个包都是独立的)
    有无流量控制 流量控制(拥塞控制) 没有
    速度 传播慢(建立连接,保证可靠和有序比较耗时) 传播快
    大小 重量级,信息多,头部大(20个字节) 轻量级,头部小(8个字节)
    基于的协议 HTTP,Telent,FIP,SMTP DNS,DHCP,SNMP,TFTP

    TCP三次握手

    • 第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
    • 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN+RECV状态;
    • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次状态。

    4. 如何进行 ios 应用的性能优化,至少列出 5 点

    初级
    1.使用ARC进行内存管理
    2.在适当的情况下使用reuseIdentifier
    3.尽可能将View设置为不透明(Opaque)
    4.避免臃肿的XIBs
    5.不要阻塞主线程
    6.让图片的大小跟UIImageView一样
    7.选择正确的集合
    8.使用GZIP压缩
    中级
    9.重用和延迟加载View
    10.缓存、缓存、缓存
    11.考虑绘制
    12.处理内存警告
    13.重用花销很大的对象
    14.使用Sprite Sheets
    15.避免重新处理数据
    16.选择正确的数据格式
    17.设置适当的背景图片
    18.降低Web内容的影响
    19.设置阴影路径
    20.优化TableView
    21.选择正确的数据存储方式
    高级
    22.加速启动时间
    23.使用Autorelease Pool
    24.缓存图片 — 或者不缓存
    25.尽量避免Date格式化

    优化tableview

    优化TableView
    Table views需要快速的滚动——如果不能的话,用户会感觉到停顿。为了让table view平滑的滚动,确保遵循了如下建议:
    1.设置正确的reuseIdentifer以重用cell。
    2.尽量将view设置为不透明,包括cell本身。
    3.避免渐变,图像缩放以及离屏绘制。
    4.如果row的高度不相同,那么将其缓存下来。
    5.如果cell显示的内容来此网络,那么确保这些内容是通过异步来获取的。
    6.使用shadowPath来设置阴影。
    7.减少subview的数量。
    8.在cellForRowAtIndexPath:中尽量做更少的操作。如果需要做一些处理,那么最好做过一次之后,就将结果缓存起来。
    9.使用适当的数据结构来保存需要的信息。不同的结构会带来不同的操作代价。
    10.使用rowHeight, sectionFooterHeight 和 sectionHeaderHeight 来设置一个恒定 高度,而不要从delegate中获取。

    【iOS开发】25种常见的APP性能优化方法

    5. 代码编辑:有一组随机数字 :“14,3,67,98,33,344,453”,请使用常用算法 将其进行由大到小的排序:

    冒泡排序

    冒泡排序的理念十分简单:不断比较相邻的两个元素,如果它们的顺序不符合要求就互相调换。

    //冒泡排序
    - (void)popoSort{
        //从大到小
        NSMutableArray *arr_M = [NSMutableArray arrayWithObjects:@14,@3,@67,@98,@33,@344,@453,nil];
    
        for (int i = 0; i < arr_M.count; ++i) {
            
            //遍历数组的每一个`索引`(不包括最后一个,因为比较的是j+1)
            for (int j = 0; j < arr_M.count-1-i; ++j) {
                
                //根据索引的`相邻两位`进行`比较`
                NSNumber *a = (NSNumber *)arr_M[j];
                NSNumber *b = (NSNumber *)arr_M[j+1];
                if (a.integerValue < b.integerValue) {
                    
                    [arr_M exchangeObjectAtIndex:j withObjectAtIndex:j+1];
                }
                
            }
        }
        NSLog(@"最终结果: %@",arr_M);
    }
    

    选择排序

    #pragma mark - 选择升序排序
    - (void)selectionAscendingOrderSortWithArray:(NSMutableArray *)ascendingArr
    {
        for (int i = 0; i < ascendingArr.count; i ++) {
            for (int j = i + 1; j < ascendingArr.count; j ++) {
                if ([ascendingArr[i] integerValue] > [ascendingArr[j] integerValue]) {
                    int temp = [ascendingArr[i] intValue];
                    ascendingArr[i] = ascendingArr[j];
                    ascendingArr[j] = [NSNumber numberWithInt:temp];
                }
            }
        }
        NSLog(@"选择升序排序后结果:%@", ascendingArr);
    }
    
    #pragma mark - 选择降序排序
    - (void)selectionDescendingOrderSortWithArray:(NSMutableArray *)descendingArr
    {
        for (int i = 0; i < descendingArr.count; i ++) {
            for (int j = i + 1; j < descendingArr.count; j ++) {
                if ([descendingArr[i] integerValue] < [descendingArr[j] integerValue]) {
                    int temp = [descendingArr[i] intValue];
                    descendingArr[i] = descendingArr[j];
                    descendingArr[j] = [NSNumber numberWithInt:temp];
                }
            }
        }
        NSLog(@"选择降序排序后结果:%@", descendingArr);
    }
    

    内存管理

    答:Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。
    1). 自动内存计数ARC:由Xcode自动在App编译阶段,在代码中添加内存管理代码。
    2). 手动内存计数MRC:遵循内存谁申请、谁释放;谁添加,谁释放的原则。
    3). 内存释放池Release Pool:把需要释放的内存统一放在一个池子中,当池子被抽干后(drain),池子中所有的内存空间也被自动释放掉。内存池的释放操作分为自动和手动。自动释放受runloop机制影响。

    循环引用

    对象之间的循环引用:使用弱引用避免
    block与对象之间的循环引用:__weak处理
    timer的target强引用,也会导致内存泄漏

    相关文章

      网友评论

          本文标题:2019-01-27 面试题

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