iOS百度面试记录

百度面试

一面

上来先是自我介绍,然后开始问问题。
iOS的基础知识,runtime,runloop,多线程等等

问到一个“alloc之前都做了什么? ”没答上来
alloc调用了_objc_rootAlloc方法,_objc_rootAlloc方法又调用了callAlloc方法。callAlloc方法经过一系列判断,最终会调用class_createInstance方法来创建对象,其内部实际上是调用class_createInstanceFromZone方法,并在其中进行size计算,内存申请,和isa指针初始化等操作。size计算是通过cls->instanceSize方法,64位系统下,系统分配内存按照16字节对齐分配。
拓展:
init方法,唯一的作用是规范代码,交给子类去重写,没有任何实质性的功能。
New方法:实际上就是alloc+init。

整体进行的还挺愉快,最后问什么时候有时间二面。

二面

上来先是自我介绍,然后开始问问题。
1.http的请求头里面,有什么字段。返回的状态码有哪些,分别代表什么含义。
状态码: 1XX,接受的请求正在处理。
2XX,请求成功。
3XX,重定向,
4XX,客户端请求失败。
5XX,服务端出现问题导致请求失败。

请求头字段:
Cache-Control 控制缓存的行为
Connection 连接的管理
Date 创建报文的时间
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 报文主体的编码方式
Upgrade 升级为其他协议
Via 代理服务器相关信息
Warning 错误通知
Accept 用户代理课处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言
Authorization Web认证信息
Host 服务器地址
User-Agent HTTP客户端程序信息

2.为什么https自带了安全机制,还要自己实现一套加密机制(跟项目有关)
因为Https自带的证书是可以被伪造的,并不是完全的安全的。

3.https的实现流程
首先客户端向服务端发送一个含有TLS版本号、支持的协议以及随机数c的报文,服务端收到后,向客户端回传一个包含商定协议、随机数S以及证书。客户端验证证书的正确性,验证成功后,根据生产的预主秘钥和随机数C,随机数S生成会话秘钥。然后将预主秘钥通过证书公钥加密发送给服务端,服务端收到后用私钥解密,然后同样组成会话秘钥。接着客户端和服务端互相发送一个加密的握手信息,来确保链接畅通。

4.iOS的内存泄漏的原因有哪些和排查方法
1.commond+B 静态解析
2.leak
3.Xcode提供的查看内存中堆栈信息的工具
4.debug memory Graph

在ARC下,导致内存泄漏的根本原因就是循环引用,从而导致一些内存无法释放,最终导致dealloc方法不会被调用。例如NSTimer没有停止,delegate没有用weak修饰,blcok导致的循环引用。

5.关于循环引用相关的
循环引用实际上有三种,1是自循环引用,一个对象本身强持有了对象本身,会造成循环引用。2.两个对象相互引用,一个对象A中强持有了对象B,二对象B也强持有了对象A。3是大环循环引用,对象A持有B,B持有C,C持有了A,也会造成循环引用。
项目中最常见的循环引用就是block造成的循环引用,一般用__weak修饰就可以避免。

6.关于APP内的加密是怎么实现的,是否有计算过消耗。
解释项目中的加密机制。 V3版本由于采用的是字符串操作,耗时较长,大约100毫秒左右,V4版本我们的加密AES是采用128位的,而不是256位的,所以相对来说消耗比较小,对于V3版本大幅减少了消耗,加密时长大约在1毫秒。

7.简历上有些适配屏幕,怎么适配的。
一般对于刘海屏的判断是判断屏幕高度大于812小于1024.
对于其他的控件适配,一般使用的是ib的autoLayout或者是第三方的Masonry来进行适配,有的比较复杂的页面,多控件排布会使用frame的方式来排布。对于图片有的地方会等比例缩放,有的地方会无论在任何机型上都采用同样的大小。

8.如何将一张图片在不同的分辨率机型下,都比较清晰且节省资源的现实存储。
将图片从网络上下载下来以后,根据控件显示大小进行等比例缩放,然后将缩略图存储在内存中,这样就能保证节省资源,同时在各个分辨率下都能够清晰的显示。

9.是否知道像素对齐,怎么实现
在iOS设备上,有逻辑像素和物理像素之分,像素对齐指的是物理像素对齐,对齐就是像素点的值是整数。逻辑像素和物理像素例如2x和3x,就是1逻辑像素=3物理像素。GPU在渲染前会将逻辑像素换算成物理像素。如果某个视图的宽高x2,x3后是整数,则是对齐的,否则就是不对齐的。

出现像素不对齐的情况,会导致在GPU渲染时,对没对齐的边缘,需要进行插值计算,这个插值计算的过程会有性能损耗。

1、一般在动态计算高度的时候,会有这种情况,因为算出来的几乎都不是整数,可以使用ceil()方法抹掉后面的小数。
2、tableview的Head和Foot高度,一般会返回0.01这样也会造成像素不对齐,可以直接使用CGFloat_MIN
3.图片的size和显示图片的size不相等。
如果是本地的图片,则要UI提供2x和3x的图片。网络的图片则需要将图片缩放到UIImageView对应的尺寸,且缩放后的图片的scale和[UIScreen mainScreen].scale相等,再显示出来。将图片的缩放,放到子线程中进行,避免卡顿同时做好缓存,避免每次显示都要缩放。

10.关于多线程,在项目里面有什么应用。
多线程有3中,NSOperration,GCD,NSThread.
关于多线程在项目中的应用解释。

11.是否遇到过多线程导致的崩溃,怎么处理
1.属性写nonatomic在多线程中频繁频繁创建可能会导致崩溃。原因是对象被重复relaese了。当两个线程同时跑到最后relaese的时候,线程A先释放了,线程B再去释放就会崩溃。

2.多线程下对变量的存取

if(self.xxx) {
	[self.dict setObject:@111” forKey:self.xxx];
}

这个代码在单线程中是正确的,但是在多线程中,可能会当线程A调用完判断以后,线程B设置了属性等于Nil,最终导致崩溃。使用局部变量来解决这个问题。

3.dispatch_group的崩溃

12.聊一聊锁
常用的锁有
NSLock
NSRexxxx 递归锁
NSConditionLock 条件锁
@synchronized 常用来初始化单例
信号量 dispch_sepxxxx_t

13.关于死锁,死锁的四个必要条件。如何避免死锁
1.互斥条件。
2.不可剥夺条件
3.请求与保持条件
4.循环等待条件

避免死锁
1.加锁顺序(线程按照一定的顺序加锁)
2.加锁时限(线程尝试获取锁的时候加上一定的时限,超时则放弃对该锁的请求,并释放自己占有的锁)
3.死锁检测。
每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。

14.关于UI卡顿,为什么会卡顿,随后延伸出什么是离屏渲染,离屏渲染在iOS中有哪些操作。为什么离屏渲染会导致卡顿。
UI卡顿造成的原因是CPU和GPU各自负责的工作耗时相加大于了16.6毫秒,就会把这一帧给丢掉,在用户看来就是卡顿了。

离屏渲染是GPU在当前屏幕缓冲区外额外的开辟了一个新的缓冲区来进行渲染操作。
触发离屏渲染后会导致GPU的工作负担加重,工作耗时加长,最后可能大于16.7毫秒,从而导致丢帧,进而导致卡顿。

iOS中离屏渲染的操作:
1.设置layer圆角(同时设置masktoBounds等于YES)
2.设置阴影
3.设置蒙层遮罩
4.光栅化

15.关于app瘦身有什么(动态素材下发,将一些控件不使用图片自己画这两点没答到,后续补充说明,控件不使用图片自己绘制在项目中有用到,但是一时忘了没说)
16.除了这些,还想要包体瘦身,有什么办法(回答的是将armv7的架构删除,可以减少,不知道对不对)。

17.是否有统计过app启动时长,app图片加载时长,算法消耗时长,以及不同分辨率图片在内存中占用大小(跟他扯了下 webp)。
算法消耗时长,V3版本100毫秒左右,V4版本1毫秒。
在iOS上,图片会自动缩放到2的N次方大小,例如一张10241025的图片,占用内存与10242048的图片是一样的,公式是长4.这样一张512512占用的内存就是5125124 = 1M.iOS上支持的最大尺寸为20482048;

18.熟悉什么算法,说一下快速排序的实现流程。
排序算法,字符串反转,判断一个链表是不是有环,找到单链表中的倒数第K的元素等。
快排的流程
设置两个变量,i,j,排序开始时,i=0,j=末尾。
指定一个key值,通常为数组第一个元素,所以从j往前开始开始查找比key小的,如果找到了则i和j互换,并且停止下一步操作。然后从i往后开始找比key大的值,如果找到了则i和j互换,并停止往后搜索,重复第3、4步,直到i==j,停止排序。

19.单链表反转在iOS中有什么应用。(回答不知道,面试官说在消息传递过程中,方法缓存的时候有使用。)

20.方法缓存里面具体是怎么实现的。
里面实际上可以理解为一个数组,里面包的的bucket_t,里面包含key和IMP,key实际上就是SEL,里面实际上是hash算法实现的,拿到一个key以后,通过hash算法定位到一个具体的bucket_t,然后查找到里面的IMP,来找到具体调用。hash算法,实际上就是拿到一个key以后,通过一些函数算出一个下标值,然后把需要存储的数据放到该下标值的位置,后面要再次使用的时候,将Key通过同样的函数算出下标值就能快速找到该value值。

21.队列和线程的关系
1.开不开线程,取决于执行任务的函数,同步不开,异步开。
2.开几条线程取决于队列,串行开一条,并发开多条(前提是异步队列)。
3.主队列:专门用来在主线程上调度任务的“队列”,主队列不能在其他线程中调度任务。
4.如果主线程上当前正在有执行的任务,主队列暂时不会调度任务的执行。主队列同步任务会造成死锁,原因是循环等待。
5.同步队列可以队列调度多个异步任务前,指定一个同步任务,让所有的异步任务,等待同步任务执行完成,这是依赖关系。
6.全局队列:并发能够调度多个线程,执行效率高,但是相对费电。穿行队列效率较低,省电省流量,或者任务之间需要依赖关系,也可以用串行队列。

结束(回去等消息)
二面自己感觉很多东西问到的都不会,主要也是小团队里面,没有那么高的要求和严谨性,面试官提出的一些例如加密算法的耗时统计,图片加载的耗时统计等等,这些平时都没有考虑过。还有一些更底层的深入应用,也没有了解的很透彻。暴露出了许多问题,所以感觉没有第三面了,在好好学习下,准备好下次面试吧。(当然,如果有的三面,我还会继续回来更新的)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值