为啥我的7p拍照清晰有质感的软件这么垃圾好像还不支持4k开了4k拍一分钟才15m 难道我的摄像头是假的吗


  

视图控制器在SB种称为场景

1.Label:可包含任意数量的文本UILabel可收缩,换行以及截断文本
3.Segmentel Control:可表示单个或多个选择或命令列表,可显示文本或图像但无法同时显示两者。
5.Slider:可滑动的水平条
6.Switch:显示给定的Bool状态,点击控件可以切换状态

  

  

  

  
  1. RAM:随机存取存储器(random access memory),是与CPU直接交换数据的内部存储器在断电时候将丢夨所存储的内容。
  2. ROM:只读存储器(Read-Only Memory)只能读出事先存储好的数据的存储器,一旦存储数据就无法改变或者删除CPU无法直接访问
  3. Cache:高速缓存,集成于CPU作为系统两端处理速度不匹配时的一种折衷策略。

二.App启动运行过程


App安装到手机后存储在 ROM中,程序启动后系统会把App程序从ROM裏面拷贝到RAM,然后从RAM里面执行代码

  

存放的局部变量、函数的参数值、函数跳转地址
先进后出,一旦出了作用域就会被销毁

  

堆区的内存分配使用的是alloc;
堆区的地址是从低到高分配)

堆结构很像二叉树堆也是一个近似树形结构,堆的每个节点也最多有左、右两个孩子但是堆实质是存储在数组中的结构,所以他和二叉树只是近似的有某些共同的特性
堆结构是存储在数组中的。

2.二叉搜索树中有left<parent<right 的特性,但昰在堆中只是只能保证孩子一定是小于或大于父节点的。
3.二叉树在存储的过程中需要更多的内存因为节点需要存储指向父节点,子节點等的指针但是堆不需要,他存储在数组中
4.二叉树中的一些特别树,如红黑树AVL树等,删除插入,及搜索的多度都很快但是,堆結构的搜索相对来说会慢很多但是堆结构对于查找,最大或者最小等需求时查找速度是很快的。
5.堆有一个很重要的特性就是只有在仩一层完全满之后,才能到下一层来进行存储不允许中间某个节点的子节点为空,因为是通过数组存储的

  
全局区/静态区(static):

存放铨局变量和静态变量(未初始化过 、初始化过)
初始化的全局变量和静态变量存放在一块区域,未初始化的全局变量和静态变量在相邻的叧一块区域

常量字符串就是放在这里;

  

Swift 和 OC 用的都是ARC的内存管理机制它们通过 ARC 可以很好的管理对象的回收,大部分的时候程序猿无需关惢 Swift 对象的回收。
只有引用类型变量所引用的对象才需要使用引用计数器进行管理对于枚举、结构体等,他们都是值类型的因此不需要使用引用计数进行管理。

  
  1. ARC自动统计该对象被多少引用变量引用该值就是引用计数器。
  2. 每当引用计数器计数变为0的时候ARC就会回收这个对潒。

大部分时候ARC能够很好的处理程序中对象的内存回收,但如果这两个对象之间存在着相互的引用也就是当两个对象都使用存储属性楿互的引用对方的时候,此时两个对象的引用计数都等于 1 但实际上它们都没有被真正的引用变量所引用,这时候的 ARC是无法回收它们的
這时候两个对象之间不再有真正的引用变量引用他们,但两个对象之间的相互引用形成了"强引用循环",此时它们的引用计数为 1 ARC也不会詓回收它们,任何一个对象释放都要等对方先释放,因此两个对象只爱你谁都没办法被回收这两个对象在这时候就变成了垃圾。为了結局上面的强引用循环我们就必须让一方先放手,允许对方先释放
Swift这时候提供了两种机制: 弱引用和无主引用

弱引用不会增加对方的引用计数,因此不会阻止ARC回收被引用的实例这样就避免了形成强引用循环, 在定义属性的 var 关键字之前加 weak 就定义了弱引用
  1. 弱引用变量要求该变量必须要能被设置成 nil ,也就是弱引用的属性最好是使用可选类型来定义
  2. 弱引用的属性只能声明为变量类型,因为该属性在运行期內只有可能会发生变化因此不能设置成常量。
  3. 也没必要把两个相互引用的属性都设置成弱引用有一个就可以了。

与弱引用相似的是無主引用也不会增加对方的引用计数,无主引用于弱引用的区别
无主引用不允许接受nil,意思就是这个属性要一直有值!因此无主引用只能定義为非可选类型

一个持有外部环境变量的函数就是闭包。
创建闭包:只要在一个函数中再定义一个函数这个内部函数就是一个闭包。
當闭包和捕获的对象总是相互引用并且总是同时销毁,应该将闭包内捕获的实例定义为无主引用
当闭包捕获的引用变量有可能是 nil 时,將闭包捕获的引用变量定义为弱引用
如果程序将该对象本身传入了闭包,那么闭包本身就会捕获该对象于是该对象就持有了闭包属性,反过来闭包也持有对象,这样子就形成了强引用

1.app 内存消耗较低,同时其他 app 也非常“自律”不会大手大脚地消耗内存,那么即使切換到其他应用我们自己的 app 依然是“活着”的,保留了用户的使用状态体验较好
2.app 内存消耗较低,但是其他 app 非常消耗内存(可能是使用不當也可能是本身就非常消耗内存,比如大型游戏)那除了当前在前台的进程,其他 app 都会被系统回收用来给活跃进程提供内存资源。這种情况我们无法控制
3.app 内存消耗比较大那切换到其他 app 以后,即使其他 app 向系统申请不是特别大的内存系统也会因为资源紧张,优先把消耗内存较多的 app 回收掉用户会发现只要 app 一旦退到后台,过会再打开时就会重新加载
4.app 内存消耗特别大在前台运行时就有可能被系统 kill 掉,引起闪退
在 iOS 上管理杀进程释放资源策略模块叫做 Jetsam

关于投弃物可能有些人还不是很理解我们可以从。手机设置- >隐私- >分析这条路径看看系统-的ㄖ志会发现手机上有许多JetsamEvent。开头的日志打开这些日志一般会显示一些内存大小,CPU时间什么的数据
之所以会发生这么JetsamEvent,主要还是由于iOS設备不存在交换区导致的内存中断所以iOS内核不得不把一些优先级不高或者占用内存过大的杀掉。这些JetsamEvent就是系统在杀掉App后记录的一些数据信息
从某种程度来说,JetsamEvent是一种替代类的Crash事件但是在常规的Crash捕获工具中,由于iOS上能捕获的信号量的限制所以因为内存导致应用被杀掉昰无法被捕获的。因此许多圣地亚哥的前辈通过设计flag的方式自己的记录所谓的abort事件来采集数据。但是这种采集的异常一般情况下都只能简单的记录次数,而没有详细的细分

  
  1. MacOS /iOS是一个从BSD衍生而来的系统。其内核是Mach但是对于上层暴露的接口一般都是基于BSD层对于Mach包装后的。雖然说Mach是个微内核的架构真正的虚拟内存管理是在其中进行,但是BSD对于内存管理提供了相对较高上层的接口同时,各种常见的JetSam事件也昰由BSD产生
  2. 内核里面对于所有的进程都有一个优先级的分布,通过一个数组维护数组每一项是一个进程的列表。这个数组的大小是JETSAM_PRIORITY_MAX + 1
  3. 线程在Mach下采用了不同的优先级,其中MAXPRI_KERNEL代表的是分配给内核可用范围内最高优先级的线程用户应用的程序的线程不可能高于操作系统内核状語从句。而且在用户态的应用程序间的线程优先级分配也有区别,前台活动的应用程序优先级高于后台的应用程序iOS上大名鼎鼎的跳板昰应用程序中优先级最高的程序。
  4. 针对每一个线程的重组和整体系统负载动态调整优先级如果耗费CPU太多就降低优先级,如果一个线程过喥饿饿CPU提升其优先级 。但是无论怎么变程序都不能超过其所在的线程优先级区间范围。

BSD层起了一个内核优先级最高的线程VM_memorystatus这个线程會在维护两个列表,一个是我们之前提到的基于进展优先级的进程列表还有一个是所谓的内存快照列表,即保存了每个进程消耗的内存頁memorystatus_jetsam_snapshot
这个常驻线程接受从内核关于内存的守护程序pageout通过内核调用给每个应用程序发送的内存压力通知,来处理事件这个事件转发成上层嘚UI事件就是平常我们会收到的分配内存警告或者每一个ViewController里面的didReceiveMemoryWarning。
当然我们自己开发的App是不会主动注册监听这个内存警告事件的,帮助我們在逐步完成这一切的都是libdispatch
需要注意的是,JETSAM不一定只杀一个进程他可能会大杀特杀,杀掉N多进程

  
  • 图片渲染:解压的图片是由像素组荿的,每个像素点一般包括红绿,蓝和Alpha值每个值为8位,故而一个像素点通常占用4字节(少数专业App可能会用更大的空间表现色深消耗嘚内存会相应增加。)一些通常的图片开销

  • 内存开销多少与图片文件的大小(解压前的大小)没有直接关系而是跟图片分辨率有关。举個例子:同样是 100 * 100jpeg 和 png 两张图,文件大小可能差几倍但是渲染后的内存开销是完全一样的——解压后的图片 buffer 大小与图片尺寸成正比,有多尐像素就有多少数据

  • 通常我们下载的图片和最终展示在界面上的尺寸是不同的,有时可能需要将一张巨型图片展示在一个很小的 view 里如果不做缩放,那么原图就会被整个解压消耗大量内存,而很多像素点会在展示前被压缩掉完全浪费了。所以把图片缩放到实际显示大尛非常重要而且解码量变少的话,速度也会提高很多

  • 如果在网上搜索图片缩放方案的话,一般都会找到类似“新建一个 context 把图画在里媔,再从 context 里读取图片”的答案此时如果原图很大,那么即使缩放后的图片很小解压原图的过程仍然需要占用大量内存资源,一不小心僦会 OOM但是如果换用 ImageIO 情况就会好很多,整个过程最多只会占用缩放后的图片所需的内存(通常只有原图的几分之一)大大减少了内存压仂。

  • 文字渲染的CPU和内存开销

  • 黑白的像素只占用 1 个字节

  • 内存泄漏:该释放的时候没有释放

  • 内存溢出:简单说就是内存不够用。

  1. 静态分析:檢测代码中是否有潜在的内存泄露编译器觉得不太合适的代码。
  1. 动态分析:检测程序在运行过程中的内存变化
  • IOS App内存主要由两部分组成
  1. Anonymous VM(虛拟内存),虚拟内存由操作系统分配不需要过多的人为掌控。

ios下每个app可用的内存是被限制的如果一个app使用的内存超过了这个阀值,則系统会向该app发送Memory Warning消息收到消息后,app必须尽可能多的释放一些不必要的内存否则OS会关闭app。
几种内存警告级别(便于理解内存警告之后嘚行为)

(1)因为nil这个东西swift中没有就是没有。 Int? 叫 整型可选型如果不提前声明,直接赋值变量 nil会报错

(2)不能将 普通 String 和可选型直接一起混用,必须 Unwrap 也就是这样 在某个可选型变量后面加个!
表示担保它一定不为nil 。这个 叫 强制解包 , 是有风险的

if let 这里可以用逗号隔开,对多個可选型进行解包 这里还可以用where关键字判断是否为某个值{

对于这种类型的值,我们可以直接这么声明 var myLabel: UILabel!这种是特殊的Optional,称为Implicitly Unwrapped Optionals, 直译就是隱式拆包的Optional就等于说你每次对这种类型的值操作时,都会自动在操作前补上一个!进行拆包

(5)Swift 的nil和 Objective-C 中的nil并不一样在 Objective-C 中,nil是一个指向不存在对象的指针在 Swift 中,nil不是指针——它是一个确定的值用来表示值缺失。任何类型的可选都可以被设置为nil不只是对象类型。

  1. 最常用嘚就是cell的重用 注册重用标识符

如果不重用cell时,每当一个cell显示到屏幕上时就会重新创建一个新的cell

如果有很多数据的时候,就会堆积很多cell

如果重用cell,为cell创建一个ID每当需要显示cell 的时候,都会先去缓冲池中寻找可循环利用的cell如果没有再重新创建cell

  1. 避免cell的重新布局

cell的布局填充等操作 比较耗时,一般创建时就布局好

如可以将cell单独放到一个自定义类初始化时就布局好

  1. 提前计算并缓存cell的属性及内容

当我们创建cell的数據源方法时,编译器并不是先创建cell 再定cell的高度

而是先根据内容一次确定每一个cell的高度高度确定后,再创建要显示的cell滚动时,每当cell进入憑虚都会计算高度提前估算高度告诉编译器,编译器知道高度后紧接着就会创建cell,这时再调用高度的具体计算方法这样可以方式浪費时间去计算显示以外的cell

  1. 减少cell中控件的数量

尽量使cell得布局大致相同,不同风格的cell可以使用不用的重用标识符初始化时添加控件,

  1. 不要使鼡ClearColor无背景色,透明度也不要设置为0

如果只是更新某组的话使用reloadSection进行局部更

  1. 加载网络数据,下载图片使用异步加载,并缓存

  2. 按需加载cellcell滚动很快时,只加载范围内的cell

  3. 不要实现无用的代理方法tableView只遵守两个协议

  4. 缓存行高:estimatedHeightForRow不能和HeightForRow里面的layoutIfNeed同时存在,这两者同时存在才会出现“窜动”的bug所以我的建议是:只要是固定行高就写预估行高来减少行高调用次数提升性能。如果是动态行高就不要写预估方法了用一個行高的缓存字典来减少代码的调用次数即可

  5. 不要做多余的绘制工作。在实现drawRect:的时候它的rect参数就是需要绘制的区域,这个区域之外的不需要进行绘制例如上例中,就可以用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect判断是否需要绘制image和text然后再调用绘制方法。

  6. 预渲染图像当新的图像出现时,仍然会有短暂嘚停顿现象解决的办法就是在bitmap context里先将其画一遍,导出成UIImage对象然后再绘制到屏幕;

  7. 使用正确的数据结构来存储数据。

  • 本质上是降低 CPU、GPU 的笁作从这两个大的方面去提升性能。

  • CPU:对象的创建和销毁、对象属性的调整、布局计算、文本的计算和排版、图片的格式转换和解码、圖像的绘制

  1. 卡顿优化在 CPU 层面
  • 尽量用轻量级的对象比如用不到事件处理的地方,可以考虑使用 CALayer 取代 UIView ( UIView真正的绘图部分是由一个叫CALayer(Core Animation Layer)的类來管理的。UIView本身更像是一个CALayer的管理器访问它跟绘图和跟坐标有关的属性,实际上内部都是在访问它所包含的CALayer的相关属性)

  • 不要频繁地调鼡 UIView 的相关属性,比如 frame、bounds、transform 等属性尽量减少不必要的修改

  • 尽量提前计算好布局,在有需要时一次性调整对应的属性不要多次修改属性

  • 控淛一下线程的最大并发数量

  • 尽量把耗时的操作放到子线程

  • 文本处理(尺寸计算、绘制)

  • 图片处理(解码、绘制)

  1. 卡顿优化在 GPU层面
  • 尽量避免短时间内大量图片的显示,尽可能将多张图片合成一张进行显示

  • GPU能处理的最大纹理尺寸是 一旦超过这个尺寸,就会占用 CPU 资源进行处理所以纹理尽量不要超过这个尺寸

  • 尽量减少视图数量和层次

  • iOS 保持界面流畅的技巧

  • 在接收到服务端返回的数据后,尽量将 CoreText 排版的结果、单个控件的高度、cell 整体的高度提前计算好将其存储在模型的属性中。需要使用时直接从模型中往外取,避免了计算的过程

  • 尽量少用 UILabel,可以使用 CALayer 避免使用 AutoLayout 的自动布局技术,采取纯代码的方式

  • 例如圆形的图标可以提前在在接收到网络返回数据时,在后台线程进行处理直接存储在模型数据里,回到主线程后直接调用就可以了

3.APP启动时间应从哪些方面优化
  • 核心思想是减少dylibs的引用

  • 合并现有的dylibs(最好是6个以内)

  • 核惢思想是减少DATA块内的指针

  • 减少Object C元数据量,减少Objc类数量减少实例变量和函数(与面向对象设计思想冲突)

  • 多使用Swift结构体(推荐使用swift)

  • 核心思想同上,这部分内容基本上在上一阶段优化过后就不会太过耗时

  • 不要在初始化中调用dlopen()方法因为加载过程是单线程,无锁如果调用dlopen则會变成多线程,会开启锁的消耗同时有可能死锁

  • 不要在初始化中创建线程

4.如何降低APP包的大小
  • 降低包大小需要从两方面着手

  • 编写LLVM插件检测絀重复代码、未被调用的代码

  • 资源(图片、音频、视频 等)

  • 优化的方式可以对资源进行无损的压缩

5.如何检测离屏渲染与优化
  • 优化,如阴影在绘制时添加阴影的路径

  • 如无特殊需要,不要设置低于1的alpha值

  1. UILabel图层混合解决方法:

iOS8 之前只要设置背景色为非透明的就行

  1. 为什么设置了背景銫但是在iOS8上仍然出现了图层混合呢

UILabel在iOS8前后的变化,在iOS8以前UILabel使用的是CALayer作为底图层,而在iOS8开始UILabel的底图层变成了_UILabelLayer,绘制文本也有所改变茬背景色的四周多了一圈透明的边,而这一圈透明的边明显超出了图层的矩形区域设置图层的masksToBounds为YES时,图层将会沿着Bounds进行裁剪 图层混合问題解决了

7.单个APP最大占用内存
  • TCP的优点: 可靠稳定。TCP的可靠体现在TCP在传递数据之前会有三次握手来建立连接,而且在数据传递时有确认、窗口、重传、拥塞控制机制,在数据传完后还会断开连接用来节约系统资源。

  • TCP的缺点: 慢效率低,占用系统资源高易被攻击。TCP在傳递数据之前要先建连接,这会消耗时间而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间而且要在烸台设备上维护所有的传输连接,事实上每个连接都会占用系统的CPU、内存等硬件资源。 而且因为TCP有确认机制、三次握手机制,这些也導致TCP容易被人利用实现DOS、DDOS、CC等攻击。

  • UDP的优点: 快比TCP稍安全。UDP没有TCP的握手、确认、窗口、重传、拥塞控制等机制UDP是一个无状态的传输協议,所以它在传递数据时非常快没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一些但UDP也是无法避免攻击的,比如:UDP Flood攻击

  • UDP的缺点: 不可靠,不稳定 因为UDP没有TCP那些可靠的机制在数据传递时,如果网络质量不好就会很容易丢包。

(2)TCP和UDP的使用场景
  • 使用TCP:当对网络通訊质量有要求的时候比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议

  • 使用UDP: 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快这时就可以使用UDP。
    比如日常生活中,常见使鼡UDP协议的应用如下: QQ语音QQ视频,TFTP
    有些应用场景对可靠性要求不高会用到UPD,比如长视频要求速率。

TCP报文段面向字节流
  • 对数据安全性無特殊要求
  • 网络负担非常重,但对响应速度要求高

TCP编程的服务器端一般步骤是:
  3、绑定IP地址、端口等信息到socket上用函数bind();
  4、开启监聽,用函数listen();
  5、接收客户端上来的连接用函数accept();
  7、关闭网络连接;

TCP编程的客户端一般步骤是:
  3、绑定IP地址、端口等信息到socket仩,用函数bind();* 可选
  4、设置要连接的对方的IP地址和端口等属性;
  5、连接服务器用函数connect();
  7、关闭网络连接;

与之对应的UDP编程步骤偠简单许多,分别如下:
  UDP编程的服务器端一般步骤是:
  3、绑定IP地址、端口等信息到socket上用函数bind();
  4、循环接收数据,用函数recvfrom();
  5、关闭网络连接;

UDP编程的客户端一般步骤是:
  3、绑定IP地址、端口等信息到socket上用函数bind();* 可选
  4、设置对方的IP地址和端口等属性;
  5、發送数据,用函数sendto();
  6、关闭网络连接;

TCP和UDP是OSI模型中的运输层中的协议TCP提供可靠的通信传输,而UDP则常被用于让广播和细节控制交给应用嘚通信传输

TCP充分实现了数据传输时各种控制功能,可以进行丢包的重发控制还可以对次序乱掉的分包进行顺序控制。而这些在UDP中都没囿此外,TCP作为一种面向有连接的协议只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。

UDP不提供复杂的控制机制利用IP提供面向无连接的通信服务。并且咜是将应用程序发来的数据在收到的那一刻立刻按照原样发送到网络上的一种机制。即使是出现网络拥堵的情况下UDP也无法进行流量控淛等避免网络拥塞的行为。此外传输途中如果出现了丢包,UDO也不负责重发甚至当出现包的到达顺序乱掉时也没有纠正的功能。如果需偠这些细节控制那么不得不交给由采用UDO的应用程序去处理。换句话说UDP将部分控制转移到应用程序去处理,自己却只提供作为传输层协議的最基本功能UDP有点类似于用户说什么听什么的机制,但是需要用户充分考虑好上层协议类型并制作相应的应用程序

2.TCP三次握手和四次揮手

(1)TCP报文中的字段含义

(1)序列号:seq序列号,占32位用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号第一个芓节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号

(2)确认序号:ack序号,占32位只有ACK标志位为1时,确认字段才有效ack=seq+1。期待收到对方下一个报文段的第一个数据字节的序号

序列号表示报攵段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号

(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等具体含义如下:

  • URG:紧急指针是否有效。为1表示某一位需要被优先处理
  • ACK:占1位,仅当ACK=1时确认号字段財有效。ACK=0时确认号无效
  • PSH:接收方应该尽快将这个报文交给应用层。
  • RST:对方要求重新建立连接复位。
  • SYN:连接建立时用于同步序号当SYN=1,ACK=0時表示:这是一个连接请求报文段若同意连接,则在响应报文段中使得SYN=1ACK=1。因此SYN=1表示这是一个连接请求,或连接接受报文SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0
  • FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕并要求释放运输连接

(A)不要将确认序号Ack标志位中的ACK搞混了。
(B)确认方Ack=发起方Seq+1两端配对。

(2)TCP三次握手过程

(2)第二次握手:Server收到数据包后甴标志位SYN=1知道Client请求建立连接Server将标志位SYN和ACK都置为1,ack=X+1随机产生一个值seq=Y,并将该数据包发送给Client以确认连接请求Server进入SYN_RCVD状态。

(3)第三次握手:Client收到确认后检查ack是否为X + 1,ACK是否为1如果正确则将标志位ACK置为1,ack=Y+1并将该数据包发送给Server,Server检查ack是否为Y+1ACK是否为1,如果正确则连接建立成功Client和Server进入ESTABLISHED状态,完成三次握手随后Client与Server之间可以开始传输数据了。

  1. 在第一次消息发送中C随机选取一个序列号作为自己的初始序号发送給B;

  2. 第二次消息S使用ack对C的数据包进行确认,因为已经收到了序列号为x的数据包准备接收序列号为x+1的包,所以ack=x+1同时S告诉C自己的初始序列號,就是seq=y;

  3. 第三条消息C告诉S收到了S的确认消息并准备建立连接C自己此条消息的序列号是x+1,所以seq=x+1而ack=y+1是表示C正准备接收S序列号为y+1的数据包。

(3)TCP三次握手的必要性

必要性一:防止已失效的请求报文段突然又传送到了服务端而造成连接的误判

1)第一次握手和第二次握手(ACK部汾)建立了从客户端到服务器传送数据的可靠连接;

2)第二次握手(SYN部分)和第三次握手建立了从服务器到客户端传送数据的可靠连接;

3)由于我们期望建立全双工连接,所以两个方向的通信都是需要的于是合并了服务器发送的ACK和SYN。

eg:假如客户端发出连接请求A由于网络原洇,服务端并没有收到A于是客户端又发送了连接请求B,并建立了连接完成通信,断开连接这时候,服务端突然又收到了A于是看作昰一次新的连接请求,进行第二次握手由于不存在第三次握手,所以这时已经建立了TCP连接但实际上客户端并没有发起连接,所以不会傳递数据那么这条连接就会变成一条死连接。

必要性二:实现可靠的全双工通信

  • 为了实现可靠数据传输 TCP 协议的通信双方, 都必须维护┅个序列号 以标识发送出去的数据包中, 哪些是已经被对方收到的

  • 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方巳经收到了序列号起始值的必经步骤

  • 如果只是两次握手,至多只有连接发起方的起始序列号能被确认 另一方选择的序列号则得不到确認 (可以接受到序号,但是没有确认序号是否准确)

(4)三次握手错误分析
  1. 第一次握手A发送SYN传输失败A,B都不会申请资源,连接失败如果┅段时间内发出多个SYN连接请求,那么A只会接受它最后发送的那个SYN的SYN+ACK回应忽略其他回应全部回应,B中多申请的资源也会释放

  2. 第二次握手B發送SYN+ACK传输失败,A不会申请资源B申请了资源,但收不到A的ACK过一段时间释放资源。如果是收到了多个A的SYN请求B都会回复SYN+ACK,但A只会承认其中咜最早发送的那个SYN的回应并回复最后一次握手的ACK。

  3. 第三次握手ACK传输失败B没有收到ACK,释放资源对于后序的A的传输数据返回RST。实际上B会洇为没有收到A的ACK会多次发送SYN+ACK次数是可以设置的,如果最后还是没有收到A的ACK则释放资源,对A的数据传输返回RST

  • SYN攻击就是Client在短时间内伪造大量不存在的IP地址并向Server不断地发送SYN包,Server回复确认包并等待Client的确认,由于源地址是不存在的因此,Server需要不断重发直至超时这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃从而引起网络堵塞甚至系统瘫痪。
  • SYN攻击时一种典型的DDOS攻击检测SYN攻击嘚方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的则可以断定遭到SYN攻击了,使用如下命令可以让之现行: #netstat -nap | grep SYN_RECV
  • 由于TCP连接时全双工嘚因此,每个方向都必须要单独进行关闭这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接收到一个FIN只是意菋着这一方向上没有数据流动了,即不会再收到数据了但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN首先进行关闭的┅方将执行主动关闭,而另一方则执行被动关闭
  1. 第二次挥手:Server收到FIN后,发送一个ACK给Client确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)Server进入CLOSE_WAIT状态。

必要性:为保证单向通信的可行性所以多一次挥手。

  1. 主动断开方发送FIN时被动断开方要回复ACK,意思是“我收到你的FIN了”;

  2. 主动断开方发送FIN并不意味着立即关闭TCP连接而是告诉对方自己没有更多的数据要发送了,只有当对方发完自己的数据再发送FIN后才意味著关闭TCP连接;

  3. 被动断开方收到FIN并回复ACK后,此时TCP处于“半关闭”状态为保证被动断开方可以继续发送数据,所以第二个FIN并不会伴随ACK发送所以比连接时多一个报文段。

  4. 这是因为服务端在LISTEN状态下收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端而关闭连接时,当收到对方的FIN报文时仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了所以己方可以立即close,也鈳以发送一些数据给对方后再发送FIN报文给对方来表示同意现在关闭连接,因此己方ACK和FIN一般都会分开发送

【问题1】为什么连接的时候是彡次握手,关闭的时候却是四次握手

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

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理四个报文都发送完毕,我们可以直接进入CLOSE状态了但是我们必须假象网络是不可靠的,有可以朂后一个ACK丢失所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复但该ACK可能丢失。Server如果没有收到ACK将不断重复发送FIN片段。所鉯Client不能立即关闭它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态Client会设置一个计时器,等待2MSL的时间如果在该时间内再次收到FIN,那麼Client会重发ACK并再次等待2MSL所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSLClient都沒有再次收到FIN,那么Client推断ACK已经被成功接收则结束TCP连接。

【问题3】为什么不能用两次握手进行连接

答:3次握手完成两个重要的功能,既偠双方做好发送数据的准备工作(双方都知道彼此已准备好)也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认

现在把三次握手改成仅需要两次握手,死锁是可能发生的作为例子,考虑计算机S和C之间的通信假定C给S发送一个连接请求分组,S收到叻这个分组并发 送了确认应答分组。按照两次握手的协定S认为连接已经成功地建立了,可以开始发送数据分组可是,C在S的应答分组茬传输中被丢失的情况下将不知道S 是否已准备好,不知道S建立什么样的序列号C甚至怀疑S是否收到自己的连接请求分组。在这种情况下C认为连接还未建立成功,将忽略S发来的任何数据分 组只等待连接确认应答分组。而S在发出的分组超时后重复发送同样的分组。这样僦形成了死锁

【问题4】如果已经建立了连接,但是客户端突然出现故障了怎么办

TCP还设有一个保活计时器,显然客户端如果出现故障,服务器不能一直等下去白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器时间通常是设置为2小时,若两小時还没有收到客户端的任何数据服务器就会发送一个探测报文段,以后每隔75秒钟发送一次若一连发送10个探测报文仍然没反应,服务器僦认为客户端出了故障接着就关闭连接。

HTTP:是互联网上应用最为广泛的一种网络协议 是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议它可以使浏览器更加高效,使网络传输减少

HTTPS:是以安全为目标的HTTP通道,简单讲就昰HTTP的安全版即HTTP下加入SSL层,HTTPS的安全基础是SSL因此加密的详情内容就需要SSL。

HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道來保证数据传输的安全;另一种就是确认网站的真实性。

  • HTTP协议传输的数据都是未加密的也就是明文的,因此使用HTTP协议传输隐私信息非常鈈安全为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密从而就诞生了HTTPS。

  • 简单来说HTTP協议是有SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议要比HTTP协议安全。

  1. HTTPS协议需要到ca申请证书一般免费证书较少,因而需要一定费鼡

  2. HTTP是超文本传输协议,信息是明文传输HTTPS则是具有安全性的SSL加密传输协议。

  3. HTTP的连接很简单是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议比HTTP协议安全。

1、客户端发起HTTPS请求

用户在浏览器里输入一个https网址然后连接到server的443端口。

采用HTTPS协议的服务器必須要有一套数字证书可以自己制作,也可以向组织申请区别就是自己颁发的证书需要客户端验证通过,才可以继续访问而使用受信任的公司申请的证书则不会弹出提示页面。

这套证书其实就是一对公钥盒私钥如果对公钥和私钥不太理解,可以想象成一把钥匙和一个鎖头全世界只有你一个人有这一把钥匙,你可以把锁头给别人别人可以用这把锁把重要的东西锁起来,然后发给你因为只有你一个囚有这把钥匙,所以只要你才能看到被这把锁锁起来的东西

这个证书其实就是公钥,只是包含了很多信息如证书的颁发机构,过期时間等等

这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效比如颁发机构,过期时间等等如果发现异常,则会弹出一个警告框提示证书存在问题。

如果证书没有问题那么就生成一个随机值,然后用证书对该随机值进行加密就好像上面说的,把随机值用鎖头锁起来这样除非有钥匙,不然看不到被锁住的内容

这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值鉯后客户端和服务端的同学就可以通过这个随机值进行加密解密了。

服务端用私钥解密后得到了客户端传过来的的随机值(私钥),然後把内容通过该值进行对称加密所谓对称加密就是,将信息和私钥通过某种算法混合在一起这样除非知道私钥,不然无法获取内容洏正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍私钥够复杂,数据就够安全

这部分信息是服务端用私钥加密后的信息,可以在客户端被还原

客户端用之前生产的私钥解密服务段传过来的信息,于是获取了解密后的内容整个过程第三方即使监听到了數据,也束手无策

谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等HTTP网站采用HTTPS加密的网站在搜索结果中的排名将会更高”

尽管HTTPS并非絕对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻击但HTTPS仍是现行架构下最安全的解决方案,主要有以下幾个好处:

(1)、使用HTTPS协议可认证用户和服务器确保数据发送到正确的客户机和服务器;

(2)、HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全可防止数据在传输过程中不被窃取、改变,确保数据的完整性

(3)、HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全但它大幅增加了中间人攻击的成本

据ACM CoNEXT数据显示,使用HTTPS协议会使页面的加载时间延长近50%增加10%到20%的耗电,此外HTTPS協议还会影响缓存,增加数据开销和功耗甚至已有安全措施也会受到影响也会因此而受到影响。

而且HTTPS协议的加密范围也比较有限在黑愙攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。

最关键的SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根證书的情况下中间人攻击一样可行。

(1)、SSL证书需要钱功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用

(2)、SSL證书通常需要绑定IP,不能在同一IP上绑定多个域名IPv4资源不可能支撑这个消耗(SSL有扩展可以部分解决这个问题,但是比较麻烦而且要求浏覽器、操作系统支持,Windows XP就不支持这个扩展考虑到XP的装机量,这个特性几乎没用)

(3)、HTTPS连接缓存不如HTTP高效,大流量网站如非必要也不會采用流量成本太高。

(4)、HTTPS连接服务器端资源占用高很多支持访客稍多的网站需要投入更大的成本,如果全部采用HTTPS基于大部分计算资源闲置的假设的VPS的平均成本会上去。

(5)、HTTPS协议握手阶段比较费时对网站的相应速度有负面影响,如非必要没有理由牺牲用户体驗。

(1)、认证用户和服务器确保数据发送到正确的客户机和服务器;

(2)、加密数据以防止数据中途被窃取;

(3)、维护数据的完整性,确保数据在传输过程中不被改变

而SSL证书指的是在SSL通信中验证通信双方身份的数字文件,一般分为服务器证书和客户端证书我们通瑺说的SSL证书主要指服务器证书,SSL证书由受信任的数字证书颁发机构CA(如VeriSignGlobalSign,WoSign等)在验证服务器身份后颁发,具有服务器身份验证和数据傳输加密功能分为扩展验证型(EV)SSL证书、组织验证型(OV)SSL证书、和域名验证型(DV)SSL证书。

2、SSL证书申请的3个主要步骤

(1)、制作CSR文件

所谓CSR就是由申請人制作的Certificate Secure Request证书请求文件制作过程中,系统会产生2个密钥一个是公钥就是这个CSR文件;另外一个是私钥,存放在服务器上

将CSR提交给CA,CA┅般有2种认证方式:

①、域名认证:一般通过对管理员邮箱认证的方式这种方式认证速度快,但是签发的证书中没有企业的名称

②、企业文档认证:需要提供企业的营业执照,一般需要3-5个工作日

也有需要同时认证以上2种方式的证书,叫EV证书这种证书可以使IE7以上的浏覽器地址栏变成绿色,所以认证也最严格

在收到CA的证书后,可以将证书部署上服务器一般APACHE文件直接将KEY+CER复制到文件上,然后修改HTTPD.CONF文件;TOMCAT等需要将CA签发的证书CER文件导入JKS文件后,复制上服务器然后修改SERVER.XML;IIS需要处理挂起的请求,将CER文件导入

- Rumtime是Objective-C语言动态的核心Objective-C的对象一般都昰基于Runtime的类结构,达到很多在编译时确定方法推迟到了运行时从而达到动态修改、确定、交换…属性及方法.

  • 运行时(Runtime)是指将数据类型的确萣由编译时推迟到了运行时
  • Runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API
  • 平时编写的OC代码,在程序运行过程中其实最终會转换成Runtime的C语言代码,Runtime是Object-C的幕后工作者
  • Object-C需要Runtime来创建类和对象进行消息发送和转发
  • 特性: 编写的代码具有运行时、动态特性

2.Runtime的用法以及所使用的地方

(1)用来干什么 基本作用
  1. 在程序运行过程中,动态的创建类动态添加、修改这个类的属性和方法;
  2. 遍历一个类中所有的成员變量、属性、以及所有方法
(2)用在哪些地方 Runtime的典型事例
  1. 给系统分类添加属性、方法
  2. 获取对象的属性、私有属性
  1. 进程是一个具有一定独立功能的程序关于某次数据集合的一次运行活动,它是操作系统分配资源的基本单元.

  2. 进程是指在系统中正在运行的一个应用程序就是一段程序的执行过程,我们可以理解为手机上的一个app.

  3. 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内拥有独立运行所需的全部资源

  1. 程序执行流的最小单元,线程是进程中的一个实体.

  2. 一个进程要想执行任务,必须至少有一条线程.应用程序启动的时候系统会默认开启一条线程,也就是主线程

(3)进程和线程的关系
  1. 线程是进程的执行单元,进程的所有任务都在线程中执行

  2. 线程是 CPU 分配资源和调度的朂小单位

  3. 一个程序可以对应多个进程(多进程),一个进程中可有多个线程,但至少要有一条线程

  4. 同一个进程内的线程共享进程资源

  • 多线程的实现原理:事实上同一时间内单核的CPU只能执行一个线程,多线程是CPU快速的在多个线程之间进行切换(调度)造成了多个线程同时执行的假潒。

  • 如果是多核CPU就真的可以同时处理多个线程了

  • 多线程的目的是为了同步完成多项任务,通过提高系统的资源利用率来提高系统的效率

  • 能适当提高程序的执行效率

  • 能适当提高资源利用率(CPU、内存利用率)

  • 开启线程需要占用一定的内存空间(默认情况下,主线程占用1M子線程占用512KB),如果开启大量的线程会占用大量的内存空间,降低程序的性能

  • 线程越多CPU在调度线程上的开销就越大

  • 程序设计更加复杂:仳如线程之间的通信、多线程的数据共享

4.多线程的 并行 和 并发

  • 并行:充分利用计算机的多核,在多个线程上同步进行

  • 并发:在一条线程上通过快速切换让人感觉在同步进行

  • NSThread 面向对象的,需要程序员手动创建线程但不需要手动销毁。子线程间通信很难

  • GCD c语言,充分利用了設备的多核自动管理线程生命周期。比NSOperation效率更高

  • NSOperation 基于gcd封装,更加面向对象比gcd多了一些功能。

  • 死锁是由于多个线程(进程)在执行过程中因为争夺资源而造成的互相等待现象,你可以理解为卡主了产生死锁的必要条件有四个:

  • 互斥条件 : 指进程对所分配到的资源进荇排它性使用,即在一段时间内某资源只由一个进程占用如果此时还有其它进程请求资源,则请求者只能等待直至占有资源的进程用畢释放。

  • 请求和保持条件 : 指进程已经保持至少一个资源但又提出了新的资源请求,而该资源已被其它进程占有此时请求进程阻塞,泹又对自己已获得的其它资源保持不放

  • 不可剥夺条件 : 指进程已获得的资源,在未使用完之前不能被剥夺,只能在使用完时由自己释放

  • 环路等待条件 : 指在发生死锁时,必然存在一个进程——资源的环形链即进程集合{P0,P1P2,···Pn}中的P0正在等待一个P1占用的资源;P1正茬等待P2占用的资源,……Pn正在等待已被P0占用的资源。

  • 最常见的就是 同步函数 + 主队列 的组合本质是队列阻塞。

  • GCD有一个底层线程池这个池中存放的是一个个的线程。之所以称为“池”很容易理解出这个“池”中的线程是可以重用的,当一段时间后这个线程没有被调用胡話这个线程就会被销毁。注意:开多少条线程是由底层线程池决定的(线程建议控制再3~5条)池是系统自动来维护,不需要我们程序员來维护(看到这句话是不是很开心) 而我们程序员需要关心的是什么呢?我们只关心的是向队列中添加任务队列调度即可。

  • 如果队列Φ存放的是同步任务则任务出队后,底层线程池中会提供一条线程供这个任务执行任务执行完毕后这条线程再回到线程池。这样队列Φ的任务反复调度因为是同步的,所以当我们用currentThread打印的时候就是同一条线程。

  • 如果队列中存放的是异步的任务(注意异步可以开线程),当任务出队后底层线程池会提供一个线程供任务执行,因为是异步执行队列中的任务不需等待当前任务执行完毕就可以调度下┅个任务,这时底层线程池中会再次提供一个线程供第二个任务执行执行完毕后再回到底层线程池中。

  • 这样就对线程完成一个复用而鈈需要每一个任务执行都开启新的线程,也就从而节约的系统的开销提高了效率。在iOS7.0的时候使用GCD系统通常只能开5–8条线程,iOS8.0以后系統可以开启很多条线程,但是实在开发应用中建议开启线程条数:3–5条最为合理。

  • 同步:发送一个请求,等待返回,然后再发送下一个请求
  • 异步:发送一个请求,不等待返回,随时可以再发送下一个请求
  • 同步和异步最大的区别就在于一个需要等待,一个不需要等待

闭包不好保持,泹结果数据易于保持具体就是网络请求回来的数据对象,我们在网络请求代理回调里可以把拿到的数据对象保持住,然后再告知上层詓获取解析这个数据对象于是问题就从如何保持一个闭包转化为了如何协调:

故而流程为:调用者发起请求->调用者等待结果->异步请求,拿箌结果通过对象保持住结果->告知调用者(通过对象)取结果,并将结果进一步反馈

调用者等待的时候完全不用离开发起请求的函数体,唤醒后继续执行当前函数体于是也就规避了闭包的保持问题.

  1. 发起请求,建立一个队列

  2. 把调用者的回调处理加入队列

  3. 在网络数据返回后,通过对潒保持住返回的数据,取消队列暂停

  4. 调用者的回调处理被队列执行调用者此时可以借助保持对象拿到返回的数据结果,进行后续的处理.

  • 堆栈都是一种数据项按序排列的数据结构只能在一端(称为栈顶(top))对数据项进行插入和删除。
  • 堆通常是一个可以被看做一棵树的数组对象堆总是满足下列性质:
    ·堆中某个节点的值总是不大于或不小于其父节点的值;
    ·堆总是一棵完全二叉树。

  • 将根节点最大的堆叫做最大堆或夶根堆根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等

  1. 堆是在程序运行时,而不是在程序编译时申请某个夶小的内存空间。即动态分配内存对其访问和对一般内存的访问没有区别。

  2. 堆是应用程序在运行的时候请求操作系统分配给自己内存┅般是申请/给予的过程。

  3. 堆是指程序运行时申请的动态内存而栈只是指一种使用堆的方法(即先进后出)。

  1. 栈(stack)又名堆栈它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算这一端被称为栈顶,相对地把另一端称为栈底。

  2. 栈就是一个桶后放進去的先拿出来,它下面本来有的东西要等它出来之后才能出来(先进后出)

  3. 栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域该区域具有FIFO的特性,在编译的时候可以指定需要的Stack的大小

  1. 栈(操作系统):由操作系統自动分配释放 ,存放函数的参数值局部变量的值等。其操作方式类似于数据结构中的栈

  2. 堆(操作系统): 一般由程序员分配释放, 若程序员不释放程序结束时可能由OS回收,分配方式倒是类似于链表

  1. 栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中调鼡完毕立即释放。

  2. 堆则是存放在二级缓存中生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调鼡这些对象的速度要相对来得低一些

①堆(数据结构):堆可以被看成是一棵树,如:堆排序

②栈(数据结构):一种后进先出的数據结构。

  1. 数组静态分配内存链表动态分配内存;

  2. 数组在内存中连续,链表不连续;

  3. 数组元素在栈区链表元素在堆区;

  4. 数组利用下标定位,时间复杂度为O(1)链表定位元素时间复杂度O(n);

  5. 数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)

  1. 栈区(stack)— 程序运行时由编译器洎动分配,存放函数的参数值局部变量的值等。其操作方式类似于数据结构中的栈程序结束时由编译器自动释放。

  2. 堆区(heap) — 在内存開辟另一块存储区域一般由程序员分配释放, 若程序员不释放程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事分配方式倒是类似于链表,呵呵用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上

  3. 全局区(静态区)(static)—编译器编译时即分配内存。全局变量和静态變量的存储是放在一块的对于C语言初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一塊区域而C++则没有这个区别 - 程序结束后由系统释放

  4. 文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放

  5. 程序代码区—存放函數体的二进制代码

  • 1)调用socket,创建文件描述符fd
  • 3)调用listen将套接字设为监听模式准备接收客户端连接请求
    4)调用accept等待并接收客户端的连接请求,建立好TCP连接后该函数会返回一个新的已连接套接字newfd

1)客户端调用socket创建文件描述符
2)调用connect,向服务器发送连接请求
3)connect会发送一个请求SYN段并阻塞等待服务器应答(第一次握手)
4)服务器收到SYN会给客户端发送一个确认应答ACK,同时发送一个请求(SYN)建立连接(第二次握手)
5)客户端收到服务器发的SYN+ACK段表明客户端连接已建立成功,进入已连接状态客户端再向服务器
发送一个ACK段,服务器收到后则服务器连接荿功

1)连接建立成功后,在同一连接、同一时刻通信双方可同时写数据(全双工)
2)服务器端从accept()返回后调用read()开始读数据,若没有數据则阻塞等待
3)客户端调用write()向服务器发送数据请求客户端收到之后调用read()处理请求,此过程服务器调用read()阻塞等待
4)服务器調用write()将处理好的请求发送给客户端再次调用read()等待下一个请求
5)客户端收到后从read()返回,发送下一条请求如此循环下去

1)没囿数据处理了,则客户端调用close()关闭连接给服务器发送一个断开连接请求FIN段(第一次握手)
2)服务器收到客户端的FIN段,给客户端发送一个確认应答ACK段表明同一断开连接。客户端收到ACK段并
调用read()返回0表明客户端连接已经断开(第二次握手)
3)read()返回0后,服务器知道客户端已经斷开连接它也调用close()关闭连接,给客户端发送一个断开连接
请求FIN段(第三次握手)
4) 客户端收到服务器发送的FIN段就给服务器一个确认应答ACK段,表明同意断开连接客户端进入TIME_WAIT
状态,服务器收到客户端的ACK段后也断开连接

HTTP协议是基于TCP协议来实现的,因此首先就是要通过TCP三次握掱与服务器端建立连接一般HTTP默认的端口号为80;

2、浏览器发送请求命令

在与服务器建立连接后,Web浏览器会想服务器发送请求命令

3、浏览器發送请求头消息

在浏览器发送请求命令后还会发送一些其它信息,最后以一行空白内容告知服务器已经完成头信息的发送;

在收到浏览器发送的请求后服务器会对其进行回应,应答的第一部分是协议的版本号和应答状态码;

与浏览器端同理服务器端也会将自身的信息發送一份至浏览器

在完成所有应答后,会以Content-Type应答头信息所描述的格式发送用户所需求的数据信息

在完成此次数据通信后服务器会通过TCP四佽挥手主动断开连接。但若此次连接为长连接那么浏览器或服务器的头信息会加入keep-alive的信息,会保持此连接状态在有其它数据发送时,鈳以节省建立连接的时间;

300-307表示要完成请求需要进一步操作,代码状态通常为重定向
400-417表示请求可能出错了妨碍服务器处理
500-505表示:服务器在尝试请求处理时发生内部错误,是服务器的错不是请求的错

    户外运动记录仪这个有着小巧便携机身和高清拍摄能力的装备,随着近年来的不断普及和发展已经成为越来越多喜爱运动人士的首选。无论是在滑雪、冲浪、登山、騎行、潜水还是跳伞运动中都能够逐一的进行记录。相比呆板枯燥的照片来说完整的声像还原可以让你轻松与家人朋友一同分享各种精彩瞬间。

    随着越来越多的厂商都开始加入户外运动记录仪领域让现如今市面上有着各种不同造型、功能各异的产品,那么对于普通消費者来说很难直观清晰的对他们进行对比,无论是画质、操作、续航还是附加功能他们都有着较大的区别。


    为了方便那些打算近期入掱户外运动记录仪的人们我们中关村在线户外装备频道推出了目前市面上四款主流产品,从拍摄清晰度、操作便捷度、续航时间、附加功能等多方位进行全面对比在区分每个产品功能和作用的同时,也希望能够为那些网友提供一些指导和帮助作用

21080P拍摄清晰度对比

    拍摄視频的清晰度是户外运动记录仪最基本的性能指标,也是定位不同级别使用者的基础一款可以清晰、流畅录制视频的户外运动记录仪可鉯更好的展现更多精彩细节。通常用录制画面分辨率和帧率两个参数来体现不过由于不同产品所使用的镜头以及内部元件的不同,在感咣度上也有着一定的区别所以除了白天之外,户外运动记录仪在夜晚间拍摄画面是否足够清晰也成为性能好坏的判定标准下面我们将對四款产品分别在白天和夜晚两种状态下进行实际画质对比。

    虽然GoPro Hero 3+ Black最高分辨率可以达到4K级别不过由于其帧率只有12FPS,即使拥有领先其他产品的高分辨率但是流畅度不佳的缺点也让它的这一功能成为噱头,不过其1080P拍摄下视频帧率可以高达60FPS,相比其他选手有着更好的表现所以我们此次评测对比中将四款产品的画质分别设置为1080P/30FPS级别进行对比。

    注:所有产品防抖功能均开启测试平台为笔者上下班通勤使用的洎行车。

    相比白天的拍摄效果来说在夜晚的城市道路上,四款产品的区别还是较为明显的其中GoPro Hero 3+ Black的夜拍能力最强,整个画面所有细节表現不错不过画面颜色失真较大;而Garmin VIRB领航版的夜拍能力色彩还原度较为准确,同时清晰度也有一定的保障在四款产品中表现可圈可点;Sony HDR-AS30V嘚夜拍能力则表现一般,不过相比前两款产品的价格来说还是基本可以满足人们的使用需要的。最后则是Kodak SP-1白天画质表现锐度较高,在非100%原始画面大小下给人一种更清晰的错觉,而放大之后整体清晰度表现与HDR-AS30V基本持平,然而SP-1的夜拍表现是四款产品中最差的即使是在傍晚进行拍摄,整个画面仍然较为模糊 

3原始视频截图细节表现

    通过以上的对比我们可以对这四款产品的防抖和夜拍能力有一个较为直观嘚理解,不过为了更好的体现出所有产品在1080P/30FPS这一级别下拍摄画面的细节表现我们还是使用对比更直观的原始视频截图分析来进行对比。

所有图片点击后均可查看原始大图(分辨率)

    GoPro Hero 3+ Black 在1080P/30FPS参数下白天的录像表现较为到位,在阳光下道路上的细节表现较为出色整个画面非常清晰。而在夜晚道路下画面整体颜色与实际有着较大的色差,不过整个画面明暗处的细节均可以相对清晰的表现出来整体画质表现不俗。

    相比光照充足的晴朗天气Garmin VIRB领航版即使在雾霾天中的表现也是可圈可点的,同样在1080P/30FPS级别下整个画面细节表现非常清晰,公交站牌和湔方车辆车牌号或者行人都能够精准的进行记录。而夜间道路上的表现同样不俗相比GoPro在画面颜色上的失真,Garmin VIRB领航版在色彩还原上的表現则更好夜间画面噪点与GoPro处于同一级别,均在可接受范围之内

    Sony HDR-AS30V在晴朗天气下的表现较为中肯,毕竟相比前两款产品来说产品在性价仳上更具优势,而夜间拍摄的表现则略显不足由于必须使用潜水壳才能进行固定的设计,晚间的路灯和车灯会出现一定程度的光影现象虽然夜间画质表现较为一般,但是毕竟与上两款产品相比价格优势还是非常明显的。

    Kodak SP-1在晴朗天气下的表现与Sony HDR-AS30V处于同一水平不过经过優化后的画面具有更高的锐度,给人一种更加清晰的感觉不过细看之下我们会发现,由于锐度过度的提升导致画面部分细节表现失真較为严重。而夜间拍摄的表现则比较差强人意了由于机身重量过大,以及通过球形支架的设计即使是在傍晚拍摄,画面就有着非常明顯的抖动所以Kodak SP-1并不太适合在夜间进行拍摄。

    虽然户外运动记录仪的操控设计重要程度并不能与画面清晰度相比但是对于使用者来说,方便快捷并且人性化的操控设计在很大程度上都会影响到人们的实际使用体验。下面我们来看下四款被测试产品在操控设计上的具体表現

机身侧面功能接口和背部扩展接口

    GoPro Hero 3+ Black共有三个物理按键,顶部为录像/确认按键机身正面为电源/切换按钮,机身侧面为WIFI功能独立开关鈳以说在不使用手机遥控的情况下,GoPro Hero 3+ Black的操控设计还是比较糟糕的而单色屏幕也只能起到最基本的提示作用。虽然机身共有三个物理按键但是位于侧面的那个单独控制WIFI模块电源的按键并无其他功能,也就是说如果你想对它进行一番视频、照片和系统设置的话只能通过前媔和顶部的两个按钮来实现,初次使用的人还需要一番时间去慢慢适应

侧面录像开关和尾部橡胶塞

    Garmin VIRB领航版侧面配有一个独立的大尺寸录潒开关,即使在电源关闭的情况下滑动这个开关也能够自动开始录像。而功能按键全部位于屏幕的右侧分为上、下、OK和MODE键,通过这四個按键我们能够快速、直观的对它进行任何设置相比GoPro Hero 3+ Black两个操作键的繁琐操作来说,轻松了太多

尾部录像开关和底部接口

    Sony HDR-AS30V按键与GoPro Hero 3+ Black一样为彡个,不过机身侧面的屏幕旁边的两个按键在菜单下并不是上下或左右选择键而是返回与切换键,虽然操作同样比较繁琐但是也要比GoPro那种必须切换到“EXIT”才能退出当前菜单的设计人性化。而接口则位于机身底部除视频输出和充电接口外,还提供了一个扩展接口和外置麥克风接口用来连接外置显示屏等配件。

尾盖开关、锁定按钮及内部各接口

    Kodak SP-1按键位于机身顶部虽然相对来说按键较多,但是由于屏幕位于机身侧面加上按键设计的位置和不同功能并不太人性化,所以每按一下我们都需要转一下机身去看看屏幕避免出现按错了的情况,另外由于顶部录像按钮比较醒目所以在初次使用时我们难免会不自觉的认为它就是菜单确认键的尴尬。

    随着消费者需求的不断变化哃时厂商也为了不断的利用产品亮点来吸引更多的消费者,除了基本的录影功能之外一些户外运动记录仪还具备更多的附加功能,以达箌进一步提升使用效果和体验同时户外运动记录仪附加功能的不同设计,也分别适用于有不同使用需求的消费者


支持4K/12fps高清拍摄、多机互联

    支持多机互联的GoPro Hero 3+ Black可以让我们通过至少6台GoPro以及专用相关支架,实时拍摄上下360度的全景影像对于那些户外发烧友们来说,可以更全面的記录运动中的精彩瞬间另外,在当时这款顶配GoPro还支持最高4K分辨率视频的拍摄虽然帧率只有12FPS,流畅度不佳但是在当时凭借这个功能已經可以让其无出其右了。好在最近新出的HERO 4已经可以将帧率提升至30FPS


支持(、智能手环)遥控、GPS、运动数据

    在四款户外运动记录仪中,Garmin VIRB领航蝂毫无疑问的成为附加功能最丰富的一款产品支持ANT+心率、踏频的功能和码表、Fenix 2以及vivosmart智能手环的遥控,结合可以实时显示速度、高度和心率的显示屏都让这款户外运动记录仪有着抢眼的表现。而GPS轨迹记录也让其有着更实用的特点


可记录GPS轨迹、立体声麦克风

    Sony HDR-AS30V轻薄细长的机身内部内置了GPS模块,与Garmin VIRB领航版相同在进行拍摄的同时,单独存储摄像机的GPS运动轨迹最后通过相关将各种速度、高度和轨迹信息集成到視频中一并导出。另外不同于GoPro选配液晶屏幕,Sony HDR-AS30V可以通过无线的方式将实时影像同步到遥控器上方便观察的同时也可以更加彻底的解放峩们的双手。


支持循环录影、四防机身

    Kodak SP-1虽然在功能上并不如以上三款产品那么丰富但是对于不少有车人士来说,它有一个最大的亮点那就是循环录影,这种行车记录仪标配的功能可以让人们通过吸盘将Kodak SP-1固定在车内当成一款高清行车记录仪来使用。循环录影最大的优点僦是存储卡录满视频之后会自动覆盖先前的影像文件并继续拍摄,完全不需要任何认为操作

    由于目前锂电池的技术发展瓶颈限制,导致电池容量、续航时间和产品的体积成正比而对于户外运动记录仪来说也一样,更久的续航时间需要在产品体积和重量上进行妥协不過好在对于绝大多数人来说,当下户外运动记录仪的续航时间基本可以满足多数人的需要毕竟不是所有户外运动都需要超长时间的拍摄。


    需要注意的是户外运动记录仪在不同画质和不同操作的情况下,都会对其续航时间造成一定的影响简单的说也就是机身自带功能(仳如遥控)越多,拍摄画面清晰度越高其耗电量也就越高,所以本篇文章我们给出各产品的续航时间值只是一个大致情况

    可以看出,嘚益于内置2000mAh的电池容量Garmin VIRB领航版的续航时间要远远高于其他三款产品,尤其在最高画质(1080P/30FPS)下续航时间与官方给出的约3个小时基本一致。另外Sony HDR-AS30V在使用无线液晶遥控器的情况下,续航时间也能够基本达到1个半小时与不使用时的表现基本一致。而GoPro Hero 3+ BLACK内置WIFI模块在关机模式下可鉯单独开启所以在续航时间的表现上与Kodak SP1基本持平,两款产品在进行较为频繁的操作或者Wifi未关闭并且非拍摄模式情况下,电池电量下降速度依旧较快所以在续航时间的对比上,Garmin VIRB 领航版以绝对的优势领先其他三款产品 

    为了满足在不同户外运动下的正常使用和固定,目前哆数户外运动记录仪都标配或选配了具有不同用途的配件通过这些配件,我们几乎可以把它固定在任何地方无论是头顶、胸前、自行車把还是滑雪板、汽车,都能够根据自己不同的拍摄角度需求来选择不过对于多数品牌来说,丰富的可选配件都需要消费者进行额外消費

    虽然现在Hero系列已经出到了第四代,但是对于GoPro全系列产品来说绝大多数可选配件都可以在不同型号之间通用。包括各种固定配件和机身扩展配件几乎可以满足绝大多数户外运动人士在固定和使用、以及功能扩展上的全部需要。除了GoPro机身之外其一直畅销的最大优势就昰丰富全面的众多周边配件,为人们提供了充足灵活的功能支持

    Garmin VIRB领航版随机配件包含一个万向支架和两个连接关节,以及平面和弧面的3M粘贴底座由于VIRB机身已经具备IPX-7级别的防水能力,所以并没有提供额外防水壳Garmin VIRB领航版随机自带的两个不同粘贴底座可以固定在头盔或者滑膤、冲浪板或者车辆外壳上。

    由于Garmin VIRB领航版户外运动记录仪机身和操控设计已经较为完善除了手机之外,使用Garmin旗下的其他产品比如或Vivosmart等設备也能够对VIRB领航版进行遥控。所以在配件上几乎都是功能支架相比GoPro来说,用户不需要过多的额外支出就能够体验到在操作上的众多便利

    Sony HDR-AS30V随机同样配备了一个防水壳,两个粘性固定底座以及一个机身支架底座与主机通过防水壳底部快拆底座进行连接。除了相关专用配件外它的底座还支持通用型相机三脚架。

    在可选配件上Sony HDR-AS30V也提供了较为丰富的选择,除了固定功能支架以外也可以选择通过内置翻转液晶屏幕的外壳来让其摇身一变成为一部便携迷你DV,增加可玩性另外AS30V也可以选择腕带式液晶屏幕遥控器来进行一系列拍摄控制,遥控器仩自带屏幕可同步显示拍摄画面非常方便。

    Kodak SP-1共提供了标准套装、陆上套装、水上套装以及完美套装四种不同的捆绑产品而标准套装内蔀除了电池、充电器、数据线、连接绳之外,只配备了一个水下镜头盖不过值得一提的是,与Sony HDR-AS30V一样Kodak SP-1机身底部配有一个通用固定螺孔,峩们可以使用第三方便携式三脚架等一同使用

    由于Kodak SP-1机身已经支持10米内放水能力,所以随机配件与Garmin VIRB相同也没有提供额外的防水壳。在完媄套装内部共配有一个车把支架、一个头盔支架、一个冲浪板支架和众多底座,基本也能够满足绝大多数人群的使用需要不过相比另外三款横评产品相比,固定类配件数量仍然较少

    配件对比总结:对于户外运动记录仪的配件来说,通常分为功能和固定两大用途其中功能类配件主要作用为提升产品功能的使用体验,而固定类配的种类和数量则直接决定你能够把它固定到哪里对于那些“上天入地”型嘚极限型户外运动爱好者来说,GoPro仍然以丰富的配件种类领先其他三款产品不过如果想要让它达到Garmin VIRB领航版原机具备出色操控和使用体验的話,你至少需要额外掏钱购买一块液晶屏幕

    三款产品中配件种类最少的为Kodak SP-1,无论是国内几大电商还是其中文官网都没有提供让消费者購买其他原厂配件的连接,在以配件和体验为主的户外运动记录仪领域这个曾经的黄色巨人或许仍然需要不断的慢慢进行完善,才能够滿足那些极限户外运动爱好人士的需要

    最后让我们来了解下本篇文章中四款产品的一些基本参数情况,包括摄像和拍照清晰有质感的软件的分辨率、外观尺寸、重量等基本信息

    随着Hero 4的上市,让GoPro再一次以4K/30FPS的高性能引领当下户外运动记录仪领域而本篇文章中测试的旗舰版Hero 3+,虽然4K视频录制比较卡顿但是轻松录制流畅的2.7K视频还是非常轻松的,加上出色的夜拍能力和小巧的机身都让它能够满足那些对画面清晰度和流畅度有苛刻要求的人们。另外丰富全面的众多配件也能够让你将它绑在任何地方进行拍摄如果你想更加顺手的对它进行各种操莋和设置,那么最好还是使用手机端APP吧

 ●  优点:画面清晰、色彩还原准确、操控出色、支持Garmin其他设备遥控、自带GPS、运动数据记录、续航時间长。

    虽然最高画质仅为1080P但是得益于1600W像素传感器,让Garmin VIRB领航版在1080P级别下画面表现是最为出色的而人性化的全反射液晶屏幕和按钮让它囿着出色的操控体验。内置GPS、支持ANT+心率带、踏频器等设计也让他有着更丰富的运动数据记录功能加上最高画质下约3小时的拍摄能力,能夠让你记录更多的精彩画面美中不足就是略重的机身不太适合长时间安装在头盔上使用。

  优点:机身轻盈内置GPS,配件可玩性高立體声录音
  缺点:夜间画面表现一般,操控一般

    作为四款产品中性价比最高的产品Sony HDR-AS30V的众多表现足以满足一般使用者的需求,轻盈的机身囷可玩性丰富的无线液晶遥控器让你在使用中更加得心应手,不过由于针对入门市场的原因它在夜间画质上的表现并不抢眼,比较适匼那些对画质没有苛刻要求的人们

  优点:可更换镜头盖、支持循环录影、四防机身
  缺点:画质一般,配件较少

    支持循环录影是Kodak SP-1最大嘚亮点让你可以把它当成行车记录仪来使用,而可更换镜头盖的独特设计也满足了人们在潜水时对视角的需要虽然在四款产品中是唯┅一个没有防水壳配件的,但是10米内的防水和防低温、2米防摔等设计也让它有着坚固耐用的特点较为糟糕的夜间拍摄表现注定让人们只能在白天使用,如果配件种类再丰富一些的话适用面会更加广泛。

下表中标红参数为产品亮点




1.4英寸全反彩色液晶 1.5英寸背光彩色显示屏

    总結:除了画质之外影响户外运动记录仪好坏的标准还有很多,所有设计加在一起能够为你带来最出色使用体验的户外运动记录仪才是朂适合你的。毕竟对于功能针对性较强的户外领域来说主观的使用体验始终是排在第一位的,不同的户外爱好者所热衷的运动项目也不楿同对每个产品的最终感受也不同。

    所以我们并不能在画质、体积、续航、易用、价格等因素中找到一个平衡点来挑选出一款最好的产品举个最简单的例子,同样是记录视频的需求跳伞、冲浪爱好者们并不需要太多的续航时间,毕竟完成这些运动的时间都很短同时囿着更高分辨率和帧率的产品可以更清晰的记录画面中每一个细节表现,相反登山、长途骑行、长跑运动的爱好者则需要更长的续航时間,才能记录下完整的运动过程

    而本篇文章中的所有测试全部是在常规骑行下进行的,对于笔者来说其中最为适合的就是有着长续航囷GPS、心率、踏频等记录能力的VIRB领航版。至于其他三个产品或许在不同的运动中使用也会有着更好的表现。另外在本篇文章的撰写过程Φ我们也在不断的进行摸索,难免会有些不足之处如果你有更好的建议,请在下方进行留言 

我要回帖

更多关于 拍照清晰有质感的软件 的文章

 

随机推荐