记面试题讲解

今天去某大公司面试,然而简历上的一大半没回答上来,浪费了这么好的机会,自己太没放在心上了,非常可惜,下面记录的面试中的问题, 这部分主要是出自 新浪微博大牛的视频讲解,近期编写的博客跟这些关系很小,所以写下这篇博客为面试做好准备。

LRU算法


YYMemoryCache使用了LRU淘汰算法,也就是当数据超过某个限制条件后,我们会从链表的尾部开始删除数据,直到达到要求为止。

通过这种方式,就实现了类似数组的功能,是原本无序的字典成了有序的集合

YYCache里面关于缓存的机制,区别于SDWebImage,AFNetWorking中关于缓存处理的不同

SDWebImage缓存处理是七天

1.先清除已超过的最大缓存时间
2.第一轮会保留文件属性
3.清除之后,如果设置了最大的缓存, 保留之前的文件,先删除最老的文件
4.删除最老的文件, 到达它最大缓存的一半
复制代码

AFNetWorking缓存处理方案:

//memoryCapacity 内存 : 100 ---> 102 (100-100 = 0) //preferredMemoryUsageAfterPurge: 60 : 102-60 = 42 只需要清理 42 根据时间清除

dispatch_barrier_async(self.synchronizationQueue, ^{
    if (self.currentMemoryUsage > self.memoryCapacity) {
        UInt64 bytesToPurge = self.currentMemoryUsage - self.preferredMemoryUsageAfterPurge;// 102-60=42
        NSMutableArray <AFCachedImage*> *sortedImages = [NSMutableArray arrayWithArray:self.cachedImages.allValues];
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastAccessDate"
                                                                       ascending:YES];
        [sortedImages sortUsingDescriptors:@[sortDescriptor]];

        UInt64 bytesPurged = 0;
        // 不一定=42,>=42,可能最后一张图片较大,剩余就小于等于42m
        for (AFCachedImage *cachedImage in sortedImages) {
            [self.cachedImages removeObjectForKey:cachedImage.identifier];
            bytesPurged += cachedImage.totalBytes;
            if (bytesPurged >= bytesToPurge) {
                break ;
            }
        }
        self.currentMemoryUsage -= bytesPurged;
    }
    });
复制代码

TCP如何保证可靠传输?


无差错无重复按序到达

    无差错:
    不丢失:
    不重复:
复制代码

可靠传输是通过停止等待协议实现的:

58CB2E72-FC3B-401E-A3C0-BA88CC159575.png

客户端发送一个分组报文m1
服务端给确认
客户端发送m2报文
服务端再确认m2报文给客户端
复制代码

超时重传

扫描二维码关注公众号,回复: 14233223 查看本文章

665A287C-07D4-494D-8F0B-095CB7B31572.png

此时,如果m1没有发送过去,
由于网络,默认server端在一定时间未收到这个报文,就不会确认客户端未收到确认就会重传服务端再确认重传
复制代码

**确认丢失 **

5ACA3ED2-9CF5-4589-B671-0999C1B7FFFA.png

客户端发送报文m1
服务端确认报文丢失
客户端超时重发报文m1
服务端已经接收过m1报文,会丢弃重传的m1报文,重传确认报文
客户端收到确认报文后继续发其它报文
复制代码

**确认迟到 **

75AFF1D5-2CB7-4317-A0F0-5BDCD93D893D.png

客户端发送报文m1
服务端发的确认报文迟到了
超时后客户端重传m1报文
server收到m1之后会丢弃重传的m1报文,再重传确认报文
后续客户端收到两个确认报文,多收一个,可以不作任何处理
    
复制代码

按序到达: 是通过滑动窗口来实现的

HTTPS是在哪个网络层上的?


https协议是应用层,tcp,udp是传输层
复制代码

HTTPS和HTTP的不同点是什么?


HTTPS = HTTP + SSL, 流程可以参照AFN源码解析 | 第一天 目录中 HTTPS流程图和详解部分

HTTP 2.0


HTTP1.x有 keep-alive,time时间内多次请求不需要重新连接

下面的内容原文链接:blog.csdn.net/qq_36807862…

但是HTTP2.0的多路复用解决了HTTP1.X中的长连接复用的什么痛点? HTTP/1.* 一次请求-响应,建立一个连接,用完关闭;每一个请求都要建立一个连接; HTTP/1.1 Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;

也就是说,HTTP1.1尽管减少了TCP连接的消耗,但是本身仍然是串行执行。 HTTP2.0多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;   补充:HTTP2.0多路复用优势 HTTP性能优化的关键并不在于高带宽,而是低延迟。TCP 连接会随着时间进行自我「调谐」,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐则被称为 TCP 慢启动。由于这种原因,让原本就具有突发性和短时性的 HTTP 连接变的十分低效。 HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。

属性关键字有哪些


assign,copy,strong,readwrite,没有提到readwrite(属性和实例变量的不同, 属性=实例变量+get/set), 默认的atomic,原子性,声明都应该写noatomic,

项目中遇到的难点:


此处保密

静态库和动态库区别:


静态库: 链接时会被完整的复制到可执行文件中,被多次使用就有多份拷贝 动态库:链接时不复制,程序运行时由系统动态加载到内存,系统只加载一次,多个程序共用,节约内存。

系统的库是动态库,共用内存,自己编写的最好用静态库,不会共用内存,保证数据安全 至于怎么创建库,就没必要讲解了

Block的主要作用:


截获变量,修改外部变量,把观察到的变量由栈copy到堆上,指针地址&a=0x7变成 &a=0x6 int a = __cself->a; copy

runtime:


有什么用:

改变变量值
交换方法
添加方法
给分类扩展属性
复制代码

改变变量值:

object_setIvar(self.person, var, @"daming");//object_setIvar(类名, 属性名称, 变更后的名称)

剩余三个具体参考: www.jianshu.com/p/6bcff1f9f…

类方法和实例方法的结构体有什么不同,消息传输机制的流程(忘记了这个是消息传递,只知道objc_msgSend)


objc_object ----根元类对象,存在类方法 objc_object 对应 OC里面的id类型

objc_object包含如下: isa_t 关于isa操作相关 弱引用相关 关联对象相关 内存管理相关

objc_class 这玩意是不是对象呢? 答: 它是对象, 他有个专有名字 类对象, 类对象就是它了!

objc_class包含如下:

Class SuperClass, 指向父类对象 cache_t cache, 方法缓存, 消息传递过程中会用到 class_data_bits_t bits, 一个类变量,属性, 方法啥的,都在这里

存在实例方法

关于消息传输机制参考iOS | runtime 中的 OC方法底层调用过程

链表反转?

这部分考察算法, 代码地址:

github.com/tanghaitao/…

设计模式中责任链、桥接,适配器、单例、命令等模式,KVO本质

设计模式的代码地址:

github.com/tanghaitao/…

责任链


现有业务有a,b,c  ,程序启动后调用a,调用b,最后调用c
      如果哪天业务变了,调用c 调用b 调用a
      怎么解决问题?
      
      类构成 
        有个类 类有个成员变量,这个成员变量的类型和这个类是一样的,这就是基础数据定义
        
 
 BusinessObject.h       
#import <Foundation/Foundation.h>

@class BusinessObject;//相当于业务 a b c
typedef void(^CompletionBlock)(BOOL handled);//表达某一业务处理完成之后,返回的结果代表它是否有处理对应的业务
typedef void(^ResultBlock)(BusinessObject *handler, BOOL handled);//业务最终处理者 参数2表达是否有处理这业务

@interface BusinessObject : NSObject

// 下一个响应者(响应链构成的关键)定义和当前类类型相同的成员变量,就组成了基本的责任链结构
@property (nonatomic, strong) BusinessObject *nextBusiness;
// 响应者的处理方法,作为响应链的入口函数
- (void)handle:(ResultBlock)result;

// 各个业务在该方法当中做实际业务处理,完成后通过block作为业务结果返回,因为可能有异步网络请示,用block
- (void)handleBusiness:(CompletionBlock)completion;
@end


BusinessObject.m
#import "BusinessObject.h"

@implementation BusinessObject

// 责任链入口方法
- (void)handle:(ResultBlock)result
{
    CompletionBlock completion = ^(BOOL handled){
        // 当前业务处理掉了,上抛结果
        if (handled) {
            result(self, handled);//处理了返回当前处理的对象以及返回结果
        }
        else{//没处理掉
            // 沿着责任链,指派给下一个业务处理,a业务处理完如果再处理b业务会走这段代码
            if (self.nextBusiness) {
                [self.nextBusiness handle:result];//递归的去调用
            }
            else{
                // 没有业务处理, 上抛,a后面没有下其它业务如b,c会返回这个处理结果
                result(nil, NO);
            }
        }
    };
    
    // 当前业务进行处理,这里就是不同的业务a,b,c,相当于当前不同的类对象,作不同的业务处理,如a业务处理完成之后就会调用上面代码的block
    [self handleBusiness:completion];
}

- (void)handleBusiness:(CompletionBlock)completion
{
    /*
     业务逻辑处理
     如网络请求、本地照片查询等
     */
}

@end

      
  答:使用责任链模式解决这种问题,业务c可以作为第一个要处理的,可把它的nextBusiness指向为b,
  b可把它的 nextBusiness指向为c,c的nextBusiness指向为nil
复制代码

桥接

11-3 桥接模式相关面试问题

面试题: 你是怎样理解桥接模式的?

一个关于业务解耦相关的问题:

一个vc列表,它由网络数据b1变到网络数据b2再变到网络数据b3 同一列表的网络数据发生了三次变化,但这三套数据是需要并存的,比如说 判断此时该用哪一套数据,对于这个需求,这个设计方案和思路?

可以通过桥接模式解决列表与数据之间的耦合问题。

桥接模式的类构成:

比如说有一个抽象类a,有一个成员变量是抽象类b,这样构成桥接模式的关键 抽象类a有三个子类a1,a2,a3,抽象类b有三个子类b1,b2,b3 vc列表可以看作抽象类a的子类a2,三套列表可以看成是b1,b2,b3,可解决上述问题

BridgeDemo桥接模式的使用方 
BaseObjectA 就是上述的抽象类a
ObjectA1 ,ObjectA2 是BaseObjectA 子类
BaseObjectB 就是上述的抽象类b
ObjectB1,ObjectB2 是BaseObjectB 子类

ObjectA1可以使用   ObjectB1,ObjectB2 的数据
ObjectA2可以使用    ObjectB1,ObjectB2 的数据
复制代码

奥迪

猜你喜欢

转载自juejin.im/post/6971635309046038535