2019-01-27 面试题

2019-01-27  本文已影响7人  Fisland_枫

[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三次握手

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

上一篇 下一篇

猜你喜欢

热点阅读