面试题目涉及:
(1) block的本质
2017年5月iOS招人心得(附面试题)
2018年 iOS 面试心得
出一套 iOS 高级面试题
iOS 高级面试题–答案
iOS----BAT网易笔试&面试题&参考答案
阿里iOS三面答案
答《 卓同学的 Swift 面试题 》
《招聘一个靠谱的 iOS》
2019 面试总结
也许,这样理解HTTPS更容易
HTTP与HTTPS
iOS音视频小结
2019 iOS面试题-----网络相关之HTTP协议
腾讯一二面
会问:算法,数据结构,scoket原理,用过什么框架,编译原理,自己搭建的网络框架(用非官方api)
App启动
iOS面试题:介绍下App启动的完成过程?
iOS启动执行顺序:点击程序图标->main()->UIApplicationMain()-UIApplicationDelegate
【iOS程序main函数之前发生了什么】
影响启动性能的因素
(1)动态库加载多
(2)ObjC类越多
(3)C的constructor函数越多
(4)C++静态对象越多
(5)ObjC的+load越多
iOS-load, initialize同名方法的调用顺序
iOS- load和initialize 子类,分类,父类,以及同名方法的调用顺序
第三方框架原理
iOS-SDWebImage实现原理
AFNetworking3.0后为什么不再需要常驻线程?
答:一、AF2.x需要常驻线程,用到的是NSURLConnection。新建常驻线程在这个线程里发起请求、接收回调。
主线程的runloop默认是NSDefaultRunLoopMode,当scrollview滑动,回调函数不执行。[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]
注意:并发数并不等于所开辟的线程数。具体开辟几条线程由系统决定。
二、NSURLSession,回调的是delegateQueue。当某个请求正在回调时,下一个请求回调还是得等待一直到上个请求获取完所要的资源后解锁才可以进行。
SDWebImage4.0源码探究(一)面试题
SDWebImage 源码阅读笔记
【iOS开源库】SDWebImage源码阅读&原理解析
设计模式
设计模式有哪几种? mvc,mvvm , mvp ,分别介绍一下,runtime作用。
常用的:工厂模式,单例模式,观察者模式,MVC模式,命令模式,外观模式,代理模式。
23种设计模式:
1.创建型模式:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。
创建型模式关注对象的创建过程。
2.结构型模式:适配器模式、代理模式、桥接模式、装饰模式、组合模式、外观模式、享元模式。
结构型模式关注对象和类的组织。
3.行为型模式:模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
单例 -> UIApplication ;观察者模式 -> KVO;类簇 -> NSNumber;装饰者模式 -> 分类;命令模式 -> NSInvocation;享元模式 -> UITableviewCell(UITableview的重用)
ReactiveCocoa
RACSequence:集合类
[数组.rac_sequence.signal subscribeNext:^(idx){}],x为数组元素
[字典.rac_sequence.signal subscribeNext:^(idx){}],x为元组
RACCommand:处理事件类 (eg:监听按钮点击,网络请求)
switchToLatest:获取signal of signals发出的最新信号
iOS内省:
isMemberOfClass //对象是否是某个类型的对象
isKindOfClass //对象是否是某个类型或某个类型子类的对象
isSubclassOfClass //某个类对象是否是另一个类型的子类
isAncestorOfObject //某个类对象是否是另一个类型的父类
respondsToSelector //是否能响应某个方法
conformsToProtocol //是否遵循某个协议
(3)基本的问题:数据库的泛型。json xml 区别。
(4)ARC内存管理机制.
dispatch_group
dispatch_barrier
dispatch_semaphore : 为线程加锁
线程、锁、GCD
线程间通信
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
dispatch_async(queue,^(){});
一篇专题让你秒懂GCD死锁问题!
多线程死锁的产生以及如何避免死锁
五个案例让你明白GCD死锁
iOS线程锁及其性能
自选锁:自旋锁的效率远高于互斥锁,保持锁时间非常短,当等待时会消耗大量 CPU 资源。
对象锁:
互斥锁:多个线程安全访问竞争资源。
条件锁:根据条件决定是否继续运行线程,即线程是否被阻塞。
递归锁:同一线程中在未解锁之前还可以上锁, 执行锁中的代码。主要是用在循环或递归操作中
dispatch_semaphore_create(信号量值)[最多几个线程可访问]
dispatch_semaphore_wait(信号量,等待时间) [总信号量减1,当信号总量为0时,线程阻塞]
dispatch_semaphore_signal(信号量) [信号总量加1]
笔试题
//C++问题
(1)实现一个深度拷贝的方法
实现一个深度拷贝的方法`deepClone`,要求考虑到可能的所有类型,兼容node.js
(2)字符串快速排序
请用快速排序算法将字符串按字典序进行排序,然后按升序输出
输入包含若干行,每行为一个字符串,如:
str3
str2
str1
在排序后,逐行输出排序后的字符串,如:
str1
str2
str3
//等待异步任务完成后才执行
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_queue_create("com.apple.test", DISPATCH_QUEUE_SERIAL);
__block int number = 0;
dispatch_async(queue, ^{
number = 100;
dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"等待异步任务完成后才执行,number=%d",number);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{ /*加载图片1 */ });
dispatch_group_async(group, queue, ^{ /*加载图片2 */ });
dispatch_group_async(group, queue, ^{ /*加载图片3 */ });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并图片
});
//方法一:
-(void)doBarrier{
dispatch_queue_t queue = dispatch_queue_create("com.test.sx", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"AAAAAA");
});
dispatch_async(queue, ^{
NSLog(@"BBBBBB");
});
dispatch_barrier_sync(queue, ^{
NSLog(@"");
});
dispatch_async(queue, ^{
NSLog(@"CCCCCC");
});
dispatch_async(queue, ^{
NSLog(@"DDDDDD");
});
}
//方法二:
-(void)doGroupAndNotify{
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"AAAAAA");
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"BBBBBB");
});
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"CCCCCC");
});
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"DDDDDD");
});
}
UIViewController生命周期
1.initWithNibName:bundle:(storyBoard, xib,纯代码布局都会执行)
2.initWithCoder(storyBoard,xib执行)
3.awakeFromNib(storyBoard,xib执行)
4.loadView
5.viewDidLoad
6.viewWillAppear
7.viewWillLayoutSubviews
8.viewDidLayoutSubviews
9.viewDidAppear
10.viewWillDisappear
11.viewDidDisappear
app生命周期
app生命周期
app有5种状态:
1、Not running未运行(app没启动或被迫终止)
2、Inactive未激活(当前应用正在前台运行,但是并不接收事件)
3、Active激活
4、Backgroud后台(程序在后台而且能执行代码)
5、Suspended挂起(程序在后台不能执行代码)
app生命周期,UIViewController生命周期
Runloop
区分(runloop,响应者链) :在一个app中间有一个button,在你手触摸屏幕点击后,到这个button收到点击事件,中间发生了什么.
(6)RunLoop相关,使用定时器要注意什么问题?
iOS 常见知识点(二):RunLoop
深入理解RunLoop
《IOS—实例化讲解 RunLoop》
Runtime
(1)runtime在实际开发的应用。
1.将某些OC代码转为运行时代码,探究底层,比如block的实现原理(上边已讲到);
2.拦截系统自带的方法调用(Swizzle 黑魔法),比如拦截imageNamed:、viewDidLoad、alloc;
3.实现分类也可以增加属性;
4.实现NSCoding的自动归档和自动解档;
5.实现字典和模型的自动转换。
《Runtime应用之关联对象和MethodSwizzling》
《谈Runtime机制和使用的整体化梳理》
《OC最实用的runtime总结,面试、工作你看我就足够了!》
项目难点、遇到问题
可以回答:组件化,网络优化,socket连接沾包,大图片处理。启动优化、性能优化
(1)
快速滑动解码,可能因为解码造成卡顿。
解决方法:Prefetching+Background decoding (预加载+后台解码)
比如:UITableView的代理:prefetchRowsAtIndexPaths
位图(Bitmap),有称位点阵图或栅格图。
位深度,1,4,8,…,32位图像。
如果位为1,只有黑白色,称为二位图。
位为8,2^8=256可能的灰色值。
(2)
基础组件添加feature,比如原先是1.6.19,那么现在要变成1.7.0.
造成主工程与壳工程不同步。
pod update时间过长,Analyzing Dependency卡好久,是因为Podspec有关。
解决方法是配置了subspec.
可以考虑打包成framework.
(3)
遭遇HTML被恶意注入JS弹广告。(利用HTTPS)
(4)
地图多点集合怎么实现,数据量超多的时候
百度地图点聚合实现方式
简述回源原理和CDN缓存
基础知识
问:如果服务器返回的是泛型的数据,怎么解析。
问:如何防止应用闪退?除了方法交换,把代码写在本地。
问:GCD线程通信的底层原理。线程如何通信。
问:MVVM设计时遇到的问题。
问:用户强杀app,日志存放在哪个文件夹。
问:instance,id,NSObject区别?
自动化测试
问:Appium怎么实现,遇到什么问题,自动化测试详细流程,测试用例怎么写。
iOS自动化单元测试示例
Appium IOS】环境搭建并运行demo(完整版)
移动端UI自动化测试–Appium和Cucumber的完美结合
iOS KIF自动化测试
iOS- Mac基于Appium DeskTop的iOS自动化测试环境搭建
问:为什么要使用自动化测试?
性能优化
问:FPS显示原理。怎么去计算FPS?
伪代码:
利用CADisplayLink初始化添加到mainRunLoop。
在selector方法中,定义两个静态变量,lastTime(记录上次的时间戳),frameCount(记录帧数)
利用CADisplayLink的timestamp属性,和lastTime的差值。为时间差。
如果时间差>1,则fps= frameCount/时间差。
iOS查看屏幕帧数工具–YYFPSLabel
iOS 计算fps
iOS 保持界面流畅的技巧
iOS开发–APP性能检测方案汇总(一)
问:内存统计,如何定位到哪段代码消耗内存?
App性能监控,包括:CPU占用率、内存占用大小、卡顿、启动闪退、崩溃、耗电量等。
问:代码规范是怎么设计?
问:怎么样高效的写入数据库。考虑B+树
iOS端数据库解决方案分析
问:电量统计,代码是如何计算电量,如何定位到哪段代码耗电?
问:App启动怎么优化,启动时间如何计算?
ios启动时间优化–实践
滑动流畅性优化
遇到tableView卡顿嘛?会造成卡顿的原因大致有哪些?
1.最常用的就是cell的重用, 注册重用标识符。
2.避免cell的重新布局
3.提前计算并缓存cell的属性及内容
4.减少cell中控件的数量
5.不要使用ClearColor,透明度也不要设置为0
6.使用局部更新
7.加载网络数据,下载图片,使用异步加载,并缓存
8.少使用addView 给cell动态添加view
9.按需加载cell,cell滚动很快时,只加载范围内的cell
10.不要实现无用的代理方法,tableView只遵守两个协议
11.缓存行高
12.不要做多余的绘制工作。
13.预渲染图像。当新的图像出现时,仍然会有短暂的停顿现象。解决的办法就是在bitmap context里先将其画一遍,导出成UIImage对象,然后再绘制到屏幕;
14.使用正确的数据结构来存储数据。
(8)地图用了什么坐标系。
(9)C指针类型转换。core graph 画图,圆点。
编译原理
1.编译过程做了哪些事情?
Clang编译器前端,LLVM编译器后端。
编译器前端任务:语法分析,语义分析,生成中间代码
编译器后端任务:会进行机器无关的代码优化,生成机器语言,并且进行机器相关的代码优化
图像、渲染
iOS中ImageIO框架详解与应用分析
渐进渲染大图
使用的是ImageIO框架,一般在对大图片进行网络请求时,可以获取一部分数据就加载一部分数据。
实际问题:地图加载
setNeedsDisplay->drawRect
UIView 内部都有一个CALayer
CALayer负责绘图和渲染。
CALayer的contents是寄宿图,其实对寄宿图进行绘制。
直接使用UILabel,drawRect没有实现。寄宿图不需要。
使用drawRect绘图,默认实现CALayerDelegate协议。
如果必须用到drawRect,如何优化绘图?
用CAShaperLayer,属于CoreAnimation框架,CPU处理。CAShaperLayer+UIBezierPath.
drawRect:图层每次重绘的时候都需要重新抹掉内存然后重新分配,消耗内存。使用CPU绘图
CAShapeLayer:不会创建寄宿图,不占用太多内存。使用GPU绘图。
Downsampling (缩减采样,生成缩略图),作用:降低内存使用。
解码消耗内存和cpu
Load Thumbnail
CGImageSource -> CGImageRef -> Decode -> UIImage
网络
百度App网络深度优化系列《一》DNS优化
百度App网络深度优化系列《二》连接优化
百度App网络深度优化系列《三》弱网优化
(1)基础网络优化,当遇到弱网络下连通率较低,可用复合连接(代码见complexconnect.inl)和 IP 排序(代码见simple_ipport_sort.cc)=
(2)平台优化,减少频繁的唤醒手机,引入了智能心跳。
微信终端跨平台组件mars系列
灰度测试-(特定人群试用,逐步增大数量)
A/B测试-(对比不同方案的转化率、点击量、留存率等指标)
DNS 防劫持、动态 IP 下发、就近接入、容灾恢复
优化DNS:HTTPDNS则是利用HTTP协议与DNS服务器交互,绕开了运营商的Local DNS服务。
容灾恢复:(1)HTTPDNS服务不可用或者缓存失效,运营商的localDNS方案。(2)当xxx,使用backup IP。
基础网络库:Cronet Stack->URLSession->AFNetWorking
一类是TLS的连接优化,一类是TCP的连接优化。
socket心跳机制,通信原理,怎么跟服务器进行报文传输,怎么防止丢包,断线重连
TCP/IP位于哪一层?
HTTP与scoket关系。Socket
网络优化的成果是怎么样,指标是多少?
ATP协议?ATP和socket协议的关系?
TCP/IP,IP协议是?
socket是对TCP/IP协议的封装,不是协议、是调用接口。
socket心跳时间一般多长?为什么这样设置。
socket为什么要封装协议好,封装数据。
socket,tcp,http三者之间的区别和原理
答案
Shell中,将command1的输出作为command2的输入应该使用的命令:command1 | command2
已知二叉树后序遍历序列是dabec,中序遍历序列是debac
错误:当使用ARC来管理内存时,代码中不可以出现autorelease
错误:一个对象的delegate指派给多个其他类型的对象
在运行时动态加载lib文件 (不是动态语言的特性)
正确:在使用ARC的项目中不能使用NSZone
正确:Objective-C没有私有方法,有私有变量。
正确:多线程中栈私有,堆公有。
#import和#include的描述正确是
一个n个顶点的无向连通图最多有n(n-1) /2 条边,最少有 n-1 条边
https://www.jianshu.com/p/6184a4b240bd
http://www.mamicode.com/info-detail-1140851.html
https://max.book118.com/html/2018/0301/155333965.shtm
已知前序遍历,中序遍历,求后序遍历
(12)Swift面试题
苹果最新的技术
快应用
无限轮播
WillBeginDragging 停止定时器
ViewDidEndDragging 启动定时器
DidScroll 找出占屏幕比例超过一半的那张图片,设置currentPage
DidEndDecelerating 手指拖动scrollview停止, 显示图片,contentOffsetX为屏幕宽度。
DidEndScrollingAnimation 定时器滚动scrollview停止,显示图片,contentOffsetX为屏幕宽度。
事件响应、第一响应者、响应者
(13)iOS UI事件传递与响应者链
找到第一响应者
hitTest:withEvent:(返回点击所在的视图)
pointInside:withEvent:(释放在视图的点击范围内)
不能响应:(1)userInteractionEnabled = NO (2)hidden = YES (3)透明度 alpha 小于等于0.01 (4)子视图超出了父视图区域
响应机制?第一响应者是谁?
事件的产生:runloop把事件放在消息队列。
事件的传递:寻找合适的控件响应。UIApplication-UIWindow-UIViewController-UIView
hitTest:withEvent:触摸点所在的视图,返回UIView
pointInside:withEvent:触摸点是否在视图,返回BOOL
寻找合适控件响应
1.view是否能接收事件
2.触摸点是否在view上
3.view子控件数组从后往前遍历,重复1.2两个步骤。
4.直到子控件没有符合条件的子控件,自己成为最合适处理这个事件。
(14)iOS 远程消息推送 APNS推送原理和一步一步开发详解篇
苹果禁用UDID,
应用卸载重装或者系统升级,UUID会变化。
UDID是Unique Device Identifier的缩写,设备唯一标识
UUID是Universally Unique Identifier的缩写,是通用唯一识别码
(15) 2018FFMPEG跨平台iOS&Android高级开发视频教程
(17)iOS NSCache缓存类的详解
(18)程序员面试闪充–iOS密码学 AES,MD5,HMAC,RSA,BASE64
(19)一个int占多少个字节?
(20)【iOS沉思录】Objective-C语言的动态性总结(编译时与运行时)
(21)UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
(22)十六进制转二进制,二进制转10进制,十六进制转10进制
eg: 0110 0001 是 0x61
0001 1111 是 0x1f
0x17 是 23
十进制转二进制
除二取余,直到商为1或0,余数倒序排列
eg: 8 -> 1000 , 2 -> 10 , 4 -> 100
二进制转换为十进制
eg:11 -> 1 * 2 ^ 1 + 1* 2 ^ 0 = 3
十进制转换为十六进制
除16取余,直到商为0,余数倒序排序
eg: 120 -> 78
十六进制转换为十进制
eg:2AF5 转为 5 * 16 ^ 0 + 15 * 16 ^1 + 10 * 16 ^ 2 + 2 * 16 ^ 3 = 10997
二进制转16进制
eg: 10111011011.1001
B9B.9
16进制和二进制对应关系:
二进制 16进制
0000 -> 0
0001 -> 1
0010 -> 2
0011 -> 3
0100 -> 4
0101 -> 5
0110 -> 6
0111 -> 7
1000 -> 8
1001 -> 9
1010 -> A
1011 -> B
1100 -> C
1101 -> D
1110 -> E
1111 -> F
表示16进制方法:
1.字母H后缀表示
2.0x前缀表示
eg: BH 等价于 0xB
(23)
1.字节就是Byte,也是B
2.位就是bit也是b
3.转换关系如下:1)1KB=1024B
2) 1B= 8b
(24)iOS Block 详解 全局块,栈块,堆块
全局block,相当于单例,存在内存。
栈区block,变量作用域结束,block被释放
堆区block,手动管理block内存。
在ARC环境下,外界变量copy从栈区拷贝到堆区。
block和block修饰的变量从栈区拷贝到堆区。是怎么做到?
block内部有个__forwarding私有成员变量,指向__block变量。
防止循环引用:
__weak typeof(self) weakSelf = self;
整型数组长度为n,内部有一个元素的出现次数大于n>>1,请设计一个算法求出这个元素(要求时间复杂度O(n),空间复杂度O(1))
(25)一个int变量被__block修饰与否的区别?
(26)Flex 布局
CSS 常见布局方式
转载-flexbox布局口诀(图文)
(27)iOS Core Animation: Advanced Techniques核心动画中文译本
iOS图片分片加载
WWDC2018 图像最佳实践
组件化
iOS 组件化 —— 路由设计思路分析
WWDC2014之iOS使用动态库
iOS插件化
ios组件化/模块化
滴滴出行iOS客户端架构演进之路
iOS组件化(二)-组件化前期工作
iOS组件化(三)-podspec使用详解
京东 iOS 客户端组件管理实践
组件化
1.组件的独立性
2.资源重用
3.高效迭代
4.加快项目编译速度
业务可以认为模块、功能可以认为组件。
1.代码解耦,组件与组件之间通信用router
eg:通过 JDRouter 调用,类似于有这样一个方法,完成 a 到 b 的通信
id g = [JDRouter openURL:@"router://JDBClass/getString?name=steven" arg:nil error:nil completion:nil];
//宏定义
#define JDROUTER_EXTERN_METHOD(m,i,p,c) + (id) routerHandle_##m##_##i:(NSDictionary*)arg callback:(Completion)callback
业务与业务之间不耦合
2.(1)通过 Cocoapods 搭建私有库,创建相应的模版
(2)自定义gem,完成podspec源码二进制切换
(3)二进制文件(组件编译为静态包)存储到内部云
(4)使用工具/脚本管理 podfile
3.组件管理系统
(1)组件配置表(记录责任人、版本、对接产品、测试、开发)
1.openURL 只是页面间的调用方式
2.组件间的调用通过 protocol 来实现
dSYM
iOS开发:dSYM文件分析
(1)dSYM是保存16进制函数地址映射信息的中转文件
(2)获取uuid
寻找xxx.app、xxx.app.dSYM、crash这三个文件相同的UUID。crash文件第一行尖括号里的字符串是UUID.
(3)利用dSYM文件分析工具
把xcarchive拖放在工具中,选择cpu类型,填写uuid,输入错误信息的内存地址。结果:可以获取到代码crash的位置。
命令模式
CTMediator
Command:抽象命令类 提供接口
ConcreteCommand:具体命令类
Invoker:调用者
Receiver:接收者
Client:客户类
命令的
命令接收者
(28)
1.OS底层-基于C的BSD Socket
socket(),close(),bind(),accept(),connect(),send(),receive()…
2.基于Socket原生的CocoaAsyncSocket
获取消息超时就断开?发送消息成功后,调用这个超时读取的。如果一段时间没收到服务器的响应,那么说明连接不可用。
3.基于webSocket的IM,SocketRocket
心跳:检测TCP连接的双方是否可用。
4. MQTT:适合订阅发布模式,不适合IM的场景
应用场景:微信的实时共享位置,滴滴的地图上小车的移动、客户端推送等
Protocol Buffer:
优点:省电,省流量,序列化后的大小是 JSON 的1/10
缺点:APP 的包体积增大。(通过 Google 提供的脚本生成的 Model)
断线重连:
TCP的keepAlive机制:只能保证连接的存在,但是并不能保证客户端以及服务端的可用性.
心跳机制:客户端发起心跳,如果没收到回复,主动断开连接。服务器端维护心跳间隔,约定时间没收到客户端发来的心跳,主动断开连接。
需要心跳机制的原因:在于国内运营商NAT超时。
NAT:网络地址转换.NAT设备到出去和进来的数据进行修改。映射被NAT设备淘汰,无法通信。
心跳间隔:而国内的运营商一般NAT超时的时间为5分钟,所以通常我们心跳设置的时间间隔为3-5分钟。
PingPong机制:当服务端发出一个Ping,客户端没有在约定的时间内返回响应的ack,Server端会主动断开Scoket连接,并且改由APNS推送的方式发送消息
重连机制:第一次立刻重连,第二次2秒,第三次4秒,第四次8秒…直到大于64秒就不再重连,连接成功,重置重连时间。
传输技术:分片上传、断点续传、秒传技术。
音视频的采集、编码、网络传输、解码、播放
粘包:同一时间发送几条数据,服务端只收到一条大数据。
粘包原因:TCP的Nagle算法,多次间隔小且数据量小,合成一大块封包。
断包:发送缓存去大小有限,分段发送。
解析数据机制:封包时候给每个数据包加一个长度或者一个开始结束标记。
拆包的时候按照长度或者分解符拆包。
封包发送具体过程:
定义(长度、类型)字典->json字符串->NSData(长度data)
新建可变data ->拼接长度data -> 拼接分界符data -> 拼接消息data
->调用:writeData:withTimeout:tag
拆包具体过程:
读取包头,NSData->NSDictionary,取出数据长度->读取数据长度的数据readDataToLength: withTimeout:tag:->根据长度和类型,数据处理.
数据读取完,继续读取下一数据包包头
readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:110
算法
各种排序算法的时间复杂度
多线程同步和互斥有几种实现方法
十大经典排序算法动画与解析
(29)断点续传:
实现断点续传要了解HTTP请求头Range,通过设置Range可以指定每次从网络下载数据包的大小
Range
bytes=0-499 ,从0到499的头500个字节
bytes=500-999,从500到999的第二个500字节
bytes=500- ,从500字节以后的所有字节
bytes=-500, 最后500个字节
bytes=500-599,800-899 同时指定几个范围
用原生API请求
NSURL *url = [NSURL URLWithString:@""];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *range = [NSString stringWithFormat:@“bytes=%lld-”, self.currentLength];
[request setValue:range forHTTPHeaderFiled:@“Range”];
实现方式
(1)NSURLConnection
(2)NSURLSession(iOS7 新出)
有三种任务类型:
NSURLSessionDataTask : 普通的GET\POST请求
NSURLSessionDownloadTask : 文件下载
NSURLSessionUploadTask : 文件上传
注意
NSURLSessionDownloadTask* downloadTask = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
}];
location就是下载好的文件写入沙盒的地址(iOS沙盒文件夹(Documents,Library,tmp))
下载完成之后会自动删除temp中的文件,开发者需要在回调中把文件移动或者复制到指定目录下
缺点就是无法监听下载进度
要监听下载进度,NSURLSessionDownloadDelegate
NSURLSessionDownloadDelegate的三个方法
didFinishDownloadingToURL 下载完毕会调用
didWriteData:totalBytesWritten:totalBytesExpectedToWrite: (这次写入的大小:已经写入沙盒的大小:文件总大小)
didResumeAtOffset:expectedTotalBytes (恢复下载后调用)
downloadTaskWithResumeData: (恢复下载)
开发遇到问题:
接收文件的NSMutableData一直内存,随着文件的下载一直变大.
解决:
NSFileHandle,对文件读取,写入,更新.
移动到文件的最后面: seekToEndFile
将数据写入沙盒: writeData
累计写入文件的长度: self.currentLength += data.length
加载完毕调用: closeFile
边下边播
iOS实现边下边播
mp4的基本格式可参考
TCP交互协议中的字节处理,查看iOS基础之字节处理(NSData,Byte,NSString转换)
解析媒体文件,最关心是视频文件的宽高,时长,码率,编码格式,帧列表,关键帧列表
开发难点:
1.解析视频的头信息(mp4)
2.播放优化(播放到未下载的地方的处理方式)
注意:
手机录制的视频都比较大,1s就得占用1M
上传服务器必须压缩
功能实现:
将视频或图片分段读取并上传服务器,NSFileHandle
读取服务器返回的分段数据并保存在本地
AVPlayer包含以下几个类:
AVURLAsset 是AVAsset的子类,负责网络连接,请求数据
AVPlayerItem 播放资源的状态。
AVPlayer 解码处理成为图像和声音
AVPlayerLayer 图像层
注意:
视频没准备好播放,不要把AVPlayerLayer图层添加到cell上,这样会造成显示的图层变成黑色.
流程:(AVFoundation可以帮我们完成)
建立连接,请求数据 AVURLAsset
数据状态管理 AVPlayerItem
解码数据 AVPlayer
音视频输出 AVPlayerLayer
手动干预系统播放器加载数据的内部实现
AVURLAsset下有一个AVAssetResourceLoader属性
AVAssetResourceLoader 负责加载数据,调用时机:AVURLAsset不知道如何去加载这个URL资源时
AVAssetResourceLoaderDelegate
怎么手动干预?回答:把目标视频URL地址的scheme替换为不能识别的scheme.
视频第一次播放,播放器获取前两个字节的数据,就是URL的contentType
注意:
大文件读取应该分段读取.不应该将视频文件一次性全部读出来.假如一个视频有 1 GB,那内存会突然爆掉
(30)
教你开发省电的 iOS app(WWDC17 观后)
耗电:
CPU处理,网络,定位,图像
app安全
手段:class-dump,tweak,反汇编,http抓包
第三方sdk:网易易盾,360,顶象
iOS应用加固:(1)字符串加密 (2)代码逻辑混淆 (3)符号混淆
网络安全: (1)DDoS高防 (2)渗透测试 (3)Web应用防火墙
如何防止反编译?
1.本地数据加密。NSUserDefaults,sqlite
2.URL编码加密
3.网络传输数据加密
4.方法体,方法名高级混淆
5.程序结构混排加密
6.借助第三方APP加固,例如:网易云易盾
模拟黑客攻击
反爬虫,防止sql注入
线上的异常信息如何捕捉
didFinishLaunching添加NSSetUncaughtExceptionHandler异常
获取异常的堆栈信息数组、原因、标题,格式化字符串,发邮件给开发者。
性能指标,监控的范围,有哪些辅助工具,提交代码时可以机器检查团队代码命名规范,JIRA和Confluence,iOS Monkey测试,图片预加载,无埋点技术的实现.
史上最强无痕埋点
iOS-无痕埋点设计
iOS一行代码监测FPS/内存/CPU
代码规范检测工具: 1.OCLint + xcpretty 2.sonar 3.infer 4.fauxpas
iOS代码检测入坑记事
基于Sonar的iOS代码质量检测系统
(31)
Object-c的类没有多继承,只支持单继承,如果要实现多继承的话,可以通过类别和协议的方式来实现,OC类似于多继承,是在 用protocol委托代理来实现的;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。
(32)AVFoundation/CoreMedia/VideoToolBox, Poco C/C++开源库
音视频编码解码+渲染,音视频合成
AVFoundation视频播放和录制,音视频合成写入box合成mp4,aac+h264写入box,创建音频输入,视频写入,AVAssetWriter.
(33)怎么创建一个可以释放的单例,怎么实现多继承,怎么调用c和c++
(34)
(34)消息转发的底层实现:
1.+resolveInstanceMethod:
+resolveClassMethod:(如果已添加了实现函数,消息发送,否则跳到下一步)
2.-forwardingTargetForSelector:(不是self和nil,消息发送,否则跳到下一步)
3.-methodSignatureForSelector:(函数的参数和返回值类型为nil,doesNotRecognizeSelector,否则跳到下一步)
4.-forwardInvocation:(消息发送)
答案参考资源:
<2>
内
存
管
理
\color{maroon}{内存管理}
内存管理:
《从经典问题来看 Copy 方法》在初学iOS的时候,可能会被灌输这么一个常识,切记NSString的property的修饰变量要写作copy,而不是strong,那么这是为什么?
<5>
架
构
模
式
\color{maroon}{架构模式}
架构模式:
什么 MVC、MVVC、MVP…本质上都是一样的,核心思想是 Separated Presentation 和 Observer Synchronization
iOS 架构模式 - 简述 MVC, MVP, MVVM 和 VIPER (译)
<7>
多
线
程
技
术
\color{maroon}{多线程技术}
多线程技术:
GCD 那些事
dispatch_barrier_sync 和dispatch_barrier_async的区别
<8>
算
法
相
关
\color{maroon}{算法相关}
算法相关:
leetcode刷题
<9>
C
o
r
e
G
r
a
p
h
i
c
s
\color{maroon}{Core Graphics}
CoreGraphics:
iOS 开发之Core Graphics(二)详解-基础篇
iOS绘图框架CoreGraphics分析
<10>
多
媒
体
音
视
频
\color{maroon}{多媒体音视频}
多媒体音视频:
iOS 音频录制AMR和WAV互转(支持64位)
iOS 通过(lame)将录制音频转换成Mp3
<11>UIView and layer 的关系
UIView和CALayer是啥关系?
<12>JS
UIWebView:
通过JavaScriptCore.framework
JSContext *context =[webView valueForKeyPath:@“documentView.webView.mainFrame.javaScriptContext”]
context[@""]=^(){};
WKWebView:
window.webkit.messageHandlers[messageHandlerName].postMessage()
evaluateJavaScript:completionHandler: