记美团iOS实习面试总结

1. 你做的app怎么保证他的安全性

我可以提我做的登录,有个记住用户名密码存在哪里,我一开始保存在NSUserDefaults中的

保存在NSUserDefaults中的信息也是一样的,所以对于存在NSUserDefaults中的东西,最好混淆加密一下再存储。

NSUserdefault 中不要保存关键信息,如果要保存,还是加密吧。。sqlite也是这样子的。

不使用NSUserDefaults保存密码,使用keyChain来保存密码

用https。代码混淆,Charles

2.iOS响应链原理

 

事件传递给窗口或控件的后,就调用hitTest:withEvent:方法寻找更合适的view,如果子控件是合适的view,则在子控件再调用hitTest:withEvent:查看子控件是不是合适的view,一直遍历,直到找到最合适的view,或者废弃事件。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    // 1.如果控件不允许与用用户交互,那么返回nil
    if (self.userInteractionEnabled == NO || self.alpha <= 0.01 || self.hidden == YES){
        return nil;
    }
    // 2. 如果点击的点在不在当前控件中,返回nil
    if (![self pointInside:point withEvent:event]){
        return nil;
    }
    // 3.从后往前遍历每一个子控件
    for(int i = (int)self.subviews.count - 1 ; i >= 0 ;i--){
        // 3.1获取一个子控件
        UIView *childView = self.subviews[i];
        // 3.2当前触摸点的坐标转换为相对于子控件触摸点的坐标
        CGPoint childP = [self convertPoint:point toView:childView];
        // 3.3判断是否在在子控件中找到了更合适的子控件(递归循环)
        UIView *fitView = [childView hitTest:childP withEvent:event];
        // 3.4如果找到了就返回
        if (fitView) {
            return fitView;
        }
    }
    // 4.没找到,表示没有比自己更合适的view,返回自己
    return self;
}

pointInside: 该方法判断触摸点是否在控件身上,是则返回YES,否则返回NO,point参数必须是方法调用者的坐标系.

3.uitableview 设置identitier的作用原因

https://blog.csdn.net/qq_18608029/article/details/51918759

讲的十分详细

4.UITableViewDelegate和UITableViewDataSource协议的几个方法

https://www.jianshu.com/p/f447da570d59

https://www.jianshu.com/p/efc094b1d49e

5.AFNetworking 多线程原理

https://www.jianshu.com/p/efc094b1d49e    AFNetworking  2.0

AFNetworking并没有为每一个请求创建一个线程,而是将每个请求封装成一个NSOperation放到一个queue中。但是每当该operation执行时,它都会在一个单独的线程(AFNetworking)中创建NSURLConnection对象,并监听所有的回调。由于网络请求都是采用NSURLConnection或者NSURLSession的异步API,因此一个单一的处理线程已经可以满足需要。

总而言之,AFNetworking其实是采用了NSOperationQueue+NSURLFoundation的异步API来完成高效的网络请求。

AFNetworking所有的网络请求都是放到了NSOperationQueue中,而该queue会有多个并发的线程来执行。默认情况下系统会根据硬件的条件,比如CPU的核心数等来设置并发的线程数,我们也可以手动的设置该变量。

[[self.requestOperationManager operationQueue] setMaxConcurrentOperationCount:2];

https://www.jianshu.com/p/ddf79f0763a7   AFNetworking的漂亮细节

6.md5加密原理

MD5算法的过程分为四步:处理原文,设置初始值,循环加工,拼接结果。

https://blog.csdn.net/sinat_27933301/article/details/79538169

MD5  Message-digest algorithm 5 就是信息摘要的一种,它可以从任意长度的明文字符串生成128位的哈希值

第一步:处理原文

    首先,我们计算出原文长度(bit)对512求余的结果,如果不等于448,就需要填充原文使得原文对512求余的结果等于448。填充的方法是第一位填充1,其余位填充0。填充完后,信息的长度就是512*N+448。

    之后,用剩余的位置(512-448=64位)记录原文的真正长度,把长度的二进制值补在最后。这样处理后的信息长度就是512*(N+1)。

第二步:设置初始值

    MD5的哈希结果长度为128位,按每32位分成一组共4组。4个初始值A、B、C、D经过不断演变得到

第三步:循环加工

A,B,C,D就是哈希值的四个分组。根据官方MD5所用到的函数有四种,每一次循环都会让旧的ABCD产生新的ABCD

第四步:拼接结果 
    最后把循环加工最终产生的A,B,C,D四个值拼接在一起,转换成字符串即可。

7.其他加密算法,对称加密和非对称加密,优缺点

对称加密 非对称加密总结    https://www.jianshu.com/p/b078282653b3

对称加密:A与 B 之间之间的通讯数据都用同一套的密钥来进行加密解密。

  • 优点
    简单快捷,密钥较短,且破译困难。
  • 缺点
    如果用户一旦多的话,管理密钥也是一种困难。不方便直接沟通的两个用户之间怎么确定密钥也需要考虑,这其中就会有密钥泄露的风险,以及存在更换密钥的需求。
  • 对称加密通常有 DES,IDEA,3DES 加密算法。

非对称加密:用公钥和私钥来加解密的算法。打个比方,A 的公钥加密过的东西只能通过 A 的私钥来解密;同理,A 的私钥加密过的东西只能通过 A 的公钥来解密。顾名思义,公钥是公开的,别人可以获取的到;私钥是私有的,只能自己拥有。

  • 缺点
    加解密比对称加密耗时.
  • 优点
    比对称加密安全.

但是非对称加密也是存在漏洞,因为公钥是公开的,如果有 C 冒充 B 的身份利用 A 的公钥给 A 发消息,这样就乱套了,所以接下来就采用非对称加密+摘要算法+数字签名的机制来确保传输安全。

常见的非对称加密算法有:RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)

Hash算法(摘要算法)

Hash算法的特点是单向不可还原,用户可以通过hash算法对目标信息生成一段特定长度的唯一hash值,却不能通过这个hash值重新获得目标信息。因此Hash算法常用在不可还原的密码存储、信息完整性校验等。只要源数据不同,算法得到的摘要必定不同。

常见的Hash算法有MD2、MD4、MD5、HAVAL、SHA

8.为什么挥手是四次而握手是三次,tcp五层以及每层对应的协议

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,”你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

应用层: (典型设备:应用程序,如FTP,SMTP ,HTTP) 

HTTP    (Hypertext Transfer Protocol )超文本传输协议 <端口号 80>, 面向事务的应用层协议。 

DHCP(Dynamic Host Configuration Protocol)动态主机分配协议,使用 UDP 协议工作,主要有两个用途:给内部网络或网络服务供应商自动分配 IP 地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段。实 现即插即用连网。 

FTP   (File Transfer Protocol )文件传输协议<端口号21>减少或消除不同操作系统下处理文件的不兼容性。 

传输层:  (典型设备:  进程和端口)       数据单元:数据段 Segment https

 TCP  Transmission Control Protocol )传输控制协议提供可靠的面向连接的服务,传输数据前须先建立连接,结束后释放。可靠的全双工信道。可靠、有序、无丢失、不重复。 

 UDP (User Datagram Protocol )用户数据报协议发送数据前无需建立连接,不使用拥塞控制,不保证可靠交付,最大努力交付。 

网络层: (典型设备:路由器,防火墙、多层交换机) 数据单元:数据包(Packet  

IP (IPv4 · IPv6) (Internet Protocol) 网络之间互连的协议 

ARP (Address Resolution Protocol) 即地址解析协议,实现通过IP 地址得 知其物理地址。 

OSPF (Open Shortest Path Firs)开放式最短路径优先,分布式链路状态协议。 

数据链路层: (典型设备:  网卡,网桥,交换机)            数据单元:帧 Frame

物理层:(典型设备:中继器,集线器、网线、HUB)                           数据单元:比特 Bit 

9. https,证书加密原理

HTTPS 的认证有单向认证和双向认证,这里简单梳理一下客户端单向认证时的握手流程:

(1)客户端发起一个请求,服务端响应后返回一个证书,证书中包含一些基本信息和公钥。
(2)客户端里存有各个受信任的证书机构根证书,用这些根证书对服务端返回的证书进行验证,如果不可信任,则请求终止。
(3)如果证书受信任,或者是用户接受了不受信的证书,客户端会生成一串随机数的密码 random key,并用证书中提供的公钥加密,再返回给服务器。
(4)服务器拿到加密后的随机数,利用私钥解密,然后再用解密后的随机数 random key,对需要返回的数据加密,加密完成后将数据返回给客户端。
(5)最后用户拿到被加密过的数据,用客户端一开始生成的那个随机数 random key,进行数据解密。整个 TLS/SSL 握手过程完成。

image 

<div align="center">图 7 TLS/SSL 握手过程(单向认证)</div>

完整的 HTTPS 连接的建立过程,包括下面三个步骤:

(1)TCP 协议的三次握手;
(2)TLS/SSL 协议的握手、密钥协商;
(3)使用共同约定的密钥开始通信。


 

10 怎么用数组链表实现二叉树

11 要我说一下数组链表,图二叉树

12 二叉树的深度无线,怎么用数组去实现二叉树,NSarray new 出来不需要指定长度为什么可以随便adddelete,原理

13 智力题,ab和分别和cd握手,每个人手上颜色不同,需要几个手套才能握手成功并且每个人手上颜色不同

 

二面

1.线程和进程的区别,线程的五种状态,死锁原因,怎么解决

根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

1.地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。

2.资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。

3.一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

4.进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程

5.线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。

两者均可并发执行。

线程的几种状态:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。

  死锁及死锁的必要条件和解决方法  https://blog.csdn.net/abigale1011/article/details/6450845

死锁,是指多个进程循环等待对方占有的资源而无限期地僵持下去的局面

在一条河上有一座桥,桥面较窄,只能容纳一辆汽车通过,无法让两辆汽车并行。如果有两辆汽车A和B分别由桥的两端驶上该桥,则对于A车来说,它走过桥面左面的一段路(即占有了桥的一部分资源),要想过桥还须等待B车让出右边的桥面,此时A车不能前进;对于B车来说,它走过桥面右边的一段路(即占有了桥的一部分资源),要想过桥还须等待A车让出左边的桥面,此时B车也不能前进。两边的车都不倒车,结果造成互相等待对方让出桥面,但是谁也不让路,就会无休止地等下去。这种现象就是死锁。

死锁产生的四个必要条件 
1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用 
2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。 
3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。 
4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路

产生原因: 
竞争资源引起进程死锁 
当系统中供多个进程共享的资源如打印机、公用队列的等,其数目不足以满足诸进程的需要时,会引起诸进程对资源的竞争而产生死锁。 

竞争不可剥夺资源 
在系统中所配置的不可剥夺资源,由于它们的数量不能满足诸进程运行的需要,会使进程在运行过程中,因争夺这些资源而陷于僵局。

竞争临时资源 
上面所说的打印机资源属于可顺序重复使用型资源,称为永久资源。还有一种所谓的临时资源,这是指由一个进程产生,被另一个进程使用,短时间后便无用的资源,故也称为消耗性资源,如硬件中断、信号、消息、缓冲区内的消息等,它也可能引起死锁。

S3是临时性资源,进程P1产生消息S1,又要求从P3接收消息S3;进程P3产生消息S3,又要求从进程P2处接收消息S2;进程P2产生消息S2,又要求从P1处接收产生的消息S1。如果消息通信按如下顺序进行: 
P1: ···Relese(S1);Request(S3); ··· 
P2: ···Relese(S2);Request(S1); ··· 
P3: ···Relese(S3);Request(S2); ··· 
并不可能发生死锁。但若改成下述的运行顺序: 
P1: ···Request(S3);Relese(S1);··· 
P2: ···Request(S1);Relese(S2); ··· 
P3: ···Request(S2);Relese(S3); ··· 
则可能发生死锁。 

三、如何避免(预防)和解决死锁?
A: 死锁预防 
    理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。只要打破四个必要条件之一就能有效预防死锁的发生:
打破互斥条件:改造独占性资源为虚拟资源,大部分资源已无法改造。打破不可抢占条件:当一进程占有一独占性资源后又申请一独占性资源而无法满足,则退出原占有的资源。打破占有且申请条件:采用资源预先分配策略,即进程运行前申请全部资源,满足则运行,不然就等待,这样就不会占有且申请。打破循环等待条件:实现资源有序分配策略,对所有设备实现分类编号,所有进程只能采用按序号递增的形式申请资源。 [3] 
所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源,在系统运行过程中,对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,若分配后系统可能发生死锁,则不予分配,否则予以分配。因此,对资源的分配要给予合理的规划。 
下面几种方法可用以避免重装死锁的发生: 
①允许目的节点将不完整的报文递交给目的端系统; 
②一个不能完整重装的报文能被检测出来,并要求发送该报文的源端系统重新传送; 
③为每个节点配备一个后备缓冲空间,用以暂存不完整的报文。 
①、②两种方法不能很满意地解决重装死锁,因为它们使端系统中的协议复杂化了。一般的设计中,网络层应该对端系统透明,也即端系统不该考虑诸如报文拆、装之类的事。③方法虽然不涉及端系统,但使每个节点增加了开销。 
有序资源分配法 
这种算法资源按某种规则系统中的所有资源统一编号(例如打印机为1、磁带机为2、磁盘为3、等等),申请时必须以上升的次序。系统要求申请进程: 
1、对它所必须使用的而且属于同一类的所有资源,必须一次申请完; 
2、在申请不同类资源时,必须按各类设备的编号依次申请。例如:进程PA,使用资源的顺序是R1,R2; 进程PB,使用资源的顺序是R2,R1;若采用动态分配有可能形成环路条件,造成死锁。 
采用有序资源分配法:R1的编号为1,R2的编号为2; 
PA:申请次序应是:R1,R2 
PB:申请次序应是:R1,R2 
这样就破坏了环路条件,避免了死锁的发生 

银行家算法 
避免死锁算法中最有代表性的算法是Dijkstra E.W 于1968年提出的银行家算法: 
银行家算法是避免死锁的一种重要方法,防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。通过这个算法可以用来解决生活中的实际问题,如银行贷款等。 
程序实现思路银行家算法顾名思义是来源于银行的借贷业务,一定数量的本金要应多个客户的借贷周转,为了防止银行家资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其他进程使用资源。如果资源分配不得到就会发生进程循环等待资源,则进程都无法继续执行下去的死锁现象。 
把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。当进程在处于等待态时,表示系统不能满足该进程当前的资源申请。“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。显然,每个进程的资源需求总量不能超过系统拥有的资源总数, 银行算法进行资源分配可以避免死锁。

B:解决方法 
在系统中已经出现死锁后,应该及时检测到死锁的发生,并采取适当的措施来解除死锁。 
死锁预防 
这是一种较简单和直观的事先预防的方法。方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。 
死锁避免 
系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源;如果分配后系统可能发生死锁,则不予分配,否则予以分配。这是一种保证系统不进入死锁状态的动态策略。 
死锁检测和解除 
先检测:这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源。检测方法包括定时检测、效率低时检测、进程等待时检测等。 
然后解除死锁:采取适当措施,从系统中将已发生的死锁清除掉。 
这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。死锁的检测和解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。

如果我们在死锁检查时发现了死锁情况,那么就要努力消除死锁,使系统从死锁状态中恢复过来。消除死锁的几种方式:

1.最简单、最常用的方法就是进行系统的重新启动,不过这种方法代价很大,它意味着在这之前所有的进程已经完成的计算工作都将付之东流,包括参与死锁的那些进程,以及未参与死锁的进程;

2.撤消进程,剥夺资源。终止参与死锁的进程,收回它们占有的资源,从而解除死锁。这时又分两种情况:一次性撤消参与死锁的全部进程,剥夺全部资源;或者逐步撤消参与死锁的进程,逐步收回死锁进程占有的资源。一般来说,选择逐步撤消的进程时要按照一定的原则进行,目的是撤消那些代价最小的进程,比如按进程的优先级确定进程的代价;考虑进程运行时的代价和与此进程相关的外部作业的代价等因素;

进程回退策略,即让参与死锁的进程回退到没有发生死锁前某一点处,并由此点处继续执行,以求再次执行时不再发生死锁。虽然这是个较理想的办法,但是操作起来系统开销极大,要有堆栈这样的机构记录进程的每一步变化,以便今后的回退,有时这是无法做到的。
 

2.你做项目什么时候用到了多线程吗,异步开始线程

3.web端和移动端的联系

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值