2019-01-27 面试题

[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强引用,也会导致内存泄漏

猜你喜欢

转载自blog.csdn.net/weixin_34071713/article/details/87076886