面试日记_2020-10-21
【千聊】
一. open、public的区别?
private、fileprivate、internal、public和open的区别
二. Swift中struct、class的区别?
Swift中enum、struct、class三者异同
三. Swift中Optional实现原理?
可选型Optional
四. Swift什么情况使用final?
五. assign和weak底层实现原理?
六. category(类别)、extension(拓展)、继承的区别?
iOS分类(category)、类扩展(extension)、继承的区别
七. KVO实现原理?
IOS底层(三) KVO底层实现原理
八. 下面代码执行结果如何?
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
NSLog(@"3");
// 打印:1;然后线程发生异常,出现卡死现象。线程相互等待对方任务执行完毕导致卡死现象.
九. 冒泡排序最坏时间复杂度是多少?【O(n^2)】
冒泡排序、插入排序、选择排序时间复杂度都是O(n2)
【维梦科技】
一. Swift的优点?缺点?
Swift相比OC语言有哪些优点
二、assign和weak的区别?
ARC:才有weak
weak:__weak 弱指针,不会让引用计数器+1,如果指向对象被销毁,指针会自动清空
assgin:__unsafe_unretained修饰,不会让引用计数器+1,如果指向对象被销毁,指针不会清空
解析2
三、如何实现监听屏幕帧率?
关于CADisplayLink的描述有两种
CADisplayLink 是一个和屏幕刷新率一致的定时器(但实际实现原理更复杂,和 NSTimer 并不一样,其内部实际是操作了一个 Source)。如果在两次屏幕刷新之间执行了一个长任务,那其中就会有一帧被跳过去(和 NSTimer 相似),造成界面卡顿的感觉。在快速滑动TableView时,即使一帧的卡顿也会让用户有所察觉。
CADisplayLink是一个执行频率(fps)和屏幕刷新相同(可以修改preferredFramesPerSecond改变刷新频率)的定时器,它也需要加入到RunLoop才能执行。与NSTimer类似,CADisplayLink同样是基于CFRunloopTimerRef实现,底层使用mk_timer(可以比较加入到RunLoop前后RunLoop中timer的变化)。和NSTimer相比它精度更高(尽管NSTimer也可以修改精度),不过和NStimer类似的是如果遇到大任务它仍然存在丢帧现象。通常情况下CADisaplayLink用于构建帧动画,看起来相对更加流畅,而NSTimer则有更广泛的用处。
不管怎么样CADisplayLink和NSTimer是有很大不同的,详情可以参考这篇文章CADisplayLink
ibireme根据CADisplayLink的特性写了个FPS指示器YYFPSLabel,代码非常少
原理是这样的:既然CADisplayLink可以以屏幕刷新的频率调用指定selector,而且iOS系统中正常的屏幕刷新率为60Hz(60次每秒),所以使用 CADisplayLink 的 timestamp 属性,配合 timer 的执行次数计算得出FPS数
作者:小凉介
链接:https://www.jianshu.com/p/f33c0e5ad0e2
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【中软国际】
一、冒泡排序(上机题 )
Swift-冒泡排序、快速排序、归并排序、二分查找
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
let array: [Int] = [23, 523, 11, 98, 1, 54, 83, 22]
let result = bubbleSort(array)
for a in result {
print(a);
}
}
func bubbleSort(_ array:[Int]) -> [Int]{
var sortArr:[Int] = array
for i in 0..<sortArr.count {
for j in i+1..<sortArr.count {
if sortArr[i] > sortArr[j] {
sortArr.swapAt(i, j)
}
}
}
return sortArr
}
【爱拍】
1、什么是dSYM文件?
dSYM文件
收集崩溃信息
2、常用第三方库原理:AFN、SDWebImage
AFNetworking的漂亮细节
AFNetworking到底做了什么?(一)
AFNetworking到底做了什么?(二)
AFNetworking之于https认证
3、SDWebImage
SDWebImage源码解析(一)——WebCache+Manager模块
SDWebImage源码解析(二)——SDImageCache缓存模块
SDWebImage源码解析(三)——SDWebImage图片解码/压缩模块
SDWebImage源码解析(四)——SDWebImage图片下载模块
SDWebImage深度剖析
4、一个 NSObject 对象占用多少内存空间?
一个 NSObject 对象占用16字
一个OC对象占用多少内存?
【YY】
1、webp配置
ios项目支持webp图片格式
2、runtime底层原理
3、异步线程如何控制确保数据读写安全。
GCD信号量-dispatch_semaphore_t
利用dispatch_semaphore信号旗来控制线程安全操作数据.
dispatch_semaphore_create
dispatch_semaphore_wait
dispatch_semaphore_signal
4、自旋锁和互斥锁的区别?
自旋锁和互斥锁的区别
5、常用设计模式
6、项目架构:mvc、mvvm、mvp
7、如何检测卡顿
iOS卡顿优化方案
iOS界面流畅之卡顿产生的原因和解决方案
8、启动性能优化
iOS开发-性能优化-启动优化
9、性能优化
iOS性能优化
【声网】
1、runtime实现原理,消息转发机制
runtime底层实现原理
用runtime看OC中类与对象,消息的底层实现原理
2、KVO/KVC
KVC/KVO实现原理
3、HandyJSON实现思路
HandyJSON 设计思路简析
4、RxSwift中冷信号、热信号有什么区别?
RxSwift-冷信号和热信号
热信号
热信号在订阅期间不会产生任何副作用,但是它确实存在自己的上下文,这些事件都是在自己的上下文环境中生成的,并且RxSwift并不能控制它(也就是说,它在自己的线程中运行)
热信号可以随时发送元素,如果观察者在其开始发送元素之后才开始订阅,那么会错过先前发送的所有元素
冷信号
冷信号在其他观察者订阅之前是不会生成任何元素的。这意味着它在订阅之前是没有自己的上下文环境的,当订阅发生之后,它会创建某个上下文环境并且开始生成元素
冷信号只有在有观察者进行订阅之后才发送元素
冷热信号的区分可以简化成一个简单的问题:在订阅的时候是否存在副作用?
是否存在副作用可以转换成,副作用是否是共享的?
如果副作用只是在订阅之后才执行的,那么这个副作用就是不共享的;
反之,这个副作用就是共享的
冷热信号的对比
热信号:
无论是否存在订阅者都会使用资源
无论是否存在订阅者都会生成元素
主要跟BehaviorSubject这类状态类型一起使用
冷信号:
只有在订阅生成之后才消耗资源
只有有订阅者的时候才会生成元素
主要用于异步操作,比如网络请求
【网易一面】
1、assign、weak区别?weak底层实现原理?
2、copy、mutablecopy区别? 可变数组执行mutablecopy操作,数组中的元素是深度拷贝吗?
【解析】
只有不可变对象进行mopy操作是浅拷贝,其余情况都是深拷贝;
可变数组mutablecopy是深拷贝,但是数组中的元素是浅拷贝(指针拷贝).
- (void)test1Example {
NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@"1", @"2", nil];
NSMutableArray *arr2 = [arr mutableCopy];
NSObject *obj1 = [arr objectAtIndex:0];
NSObject *obj2 = [arr2 objectAtIndex:0];
NSLog(@"\n%p\n%p", arr, arr2);
NSLog(@"+++++++++++++");
NSLog(@"\n%p\n%p", obj1, obj2);
}
2020-11-08 10:40:16.026207+0800 OCTest[40991:4888017]
0x600002d56df0
0x600002d56e80
2020-11-08 10:40:16.026365+0800 OCTest[40991:4888017] +++++++++++++
0x102966080
0x102966080
3、线程卡死问题
NSLog(@"1");
NSLog(@"2");
NSLog(@"3");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"4");
});
NSLog(@"5");
4、同步执行
NSLog(@"1");
NSLog(@"2");
NSLog(@"3");
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
NSLog(@"4");
});
NSLog(@"5");
2020-11-12 22:14:01.314141+0800 OCTest[50753:6640569] 1
2020-11-12 22:14:01.314352+0800 OCTest[50753:6640569] 2
2020-11-12 22:14:01.314456+0800 OCTest[50753:6640569] 3
2020-11-12 22:14:01.314555+0800 OCTest[50753:6640569] 4
2020-11-12 22:14:01.314643+0800 OCTest[50753:6640569] 5
5、苹果内购流程以及丢单问题
6、多线程如何控制多读单写?
7、响应链的流程
事件传递和响应机制
8、KVO实现原理
9、多个分类实现同一个方向,如何调用问题
多个category实现同一个方法调用的顺序
根据编译的顺序,只调用最后编译的分类方法.
10、https认证流程
11、Http、Tcp的理解
12、Tcp三层握手、四次挥手流程?为什么不是2次握手呢?
【今日头条】一面
1、#import<>和#import""的区别
#import、#include、@class、#import<>和#import""的区别
<>: 引用系统文件,它用于对系统自带的头文件的引用,编译器会在系统文件目录下去查找该文件。
"": 用户自定义的文件用双引号引用,编译器首先会在用户目录下查找,然后到安装目录中查。
2、frame、bounds区别? 旋转View的情况下,frame和bounds是否会变化?
旋转的情况下frame会变,bounds不会变
3、同一线程执行异步任务顺序
func testGCD() {
// 主线程异步执行任务,异步任务先进先出
DispatchQueue.main.async {
DispatchQueue.main.async {
sleep(5)
print("-->1")
}
print("-->2")
DispatchQueue.main.async {
print("-->3")
}
}
}
打印结果:
-->2
-->1
-->3
【算法题】
一、对称二叉树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isMirro(TreeNode *t1, TreeNode *t2){
if(t1 == NULL && t2 == NULL){
return true;
}
if(t1 == NULL || t2 == NULL){
return false;
}
return (t1->val == t2->val) && isMirro(t1->left, t2->right) && isMirro(t1->right, t2->left);
}
bool isSymmetric(TreeNode* root) {
return isMirro(root, root);
}
};
【重点知识点】
IOS中weak的底层实现原理?
Runtime会维护一个weak表,用于维护指向对象的所有weak指针。weak表是一个哈希表,其key为所指对象的指针,value为weak指针的地址数组。
具体过程如下:
1、初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。
2、添加引用时:objc_initWeak函数会调用 objc_storeWeak() 函数,更新指针指向,创建对应的弱引用表。
3、释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取所有weak指针地址的数组,然后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。
iOS alloc方法中做了什么?
核心三步:
1.计算对象所有属性所需要 size
2.调用 calloc 开辟足够的空间
3.isa 进行位运算将对象和类关联起来
alloc分配内存并将内存地址返回给指针,init对分配的内存初始化
-
Runloop
深入理解RunLoop
iOS笔试面试题15--Runloop -
OpenGL渲染原理
OpenGL渲染原理 -
离屏渲染
离屏渲染 -
底层面试题
iOS底层原理总结 -- iOS面试题 -
Https
-
Socket
-
推拉流
面试题收集:
直击2020——iOS 面试题大全(补充完整版)