C语言,我定义了变量(未赋值)调试的时候t=0这是为什么?调试了很多次了

1. 可重定位内存分区分配目的为

下载文档原格式(Word原格式,共30页)

}

C语言SOCKT编程 超级完整


介绍 Socket 编程让你沮丧吗?从man pages中很难得到有用的信息吗?你想跟上时代去编Internet相关的程序,但是为你在调用 connect 前的bind 的结构而不知所措?等等… 好在我已经将这些事完成了,我将和所有人共享我的知识了。如果你了解 C 语言并想穿过网络编程的沼泽,那么你来对地方了。 读者对象 这个文档是一个指南,而不是参考书。如果你刚开始 socket 编程并想找一本入门书,那么你是我的读者。但这不是一本完全的 socket 编程书。 平台和编译器 这篇文档中的大多数代码都在 Linux 平台PC 上用 GNU 的 gcc 成功编译过。而且它们在 HPUX平台 上用 gcc 也成功编译过。但是注意,并不是每个代码片段都独立测试过。 目录: 1 什么是套接字? 2 Internet 套接字的两种类型 3 网络理论 4 结构体 5 本机转换 客户-服务器背景知识 19 简单的服务器 20 简单的客户端 21 数据报套接字Socket 22 阻塞 23 select --多路同步I/O 24 参考资料 什么是 socket? 你经常听到人们谈论着 “socket”,或许你还不知道它的确切含义。现在让我告诉你:它是使用 标准Unix 文件描述符 file descriptor 和其它程序通讯的方式。什么?你也许听到一些Unix高手 hacker 这样说过:“呀,Unix中的一切就是文件!”那个家伙也许正在说到一个事实:Unix 程序在执行任何形式的 I/O 的时候,程序是在读或者写一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数。但是 注意后面的话 ,这个文件可能是一个网络连接,FIFO,管道,终端,磁盘上的文件或者什么其它的东西。Unix 中所有的东西就是文件!所以,你想和Internet上别的程序通讯的时候,你将要使用到文件描述符。你必须理解刚才的话。现在你脑海中或许冒出这样的念头:“那么我从哪里得到网络通讯的文件描述符呢?”,这个问题无论如何我都要回答:你利用系统调用 socket ,它返回套接字描述符 socket descriptor ,然后你再通过它来进行send 和 recv 调用。“但是...”,你可能有很大的疑惑,“如果它是个文件描述符,那么为什 么不用一般调用read 和write 来进行套接字通讯?”简单的答案是:“你可以使用!”。详细的答案是:“你可以,但是使用send 和recv 让你更好的控制数据传输。”存在这样一个情况:在我们的世界上,有很多种套接字。有DARPA Internet 地址 Internet 套接字 ,本地节点的路径名 Unix套接字 ,CCITT X.25地址 你可以将X.25 套接字完全忽略 。也许在你的Unix 机器上还有其它的。我们在这里只讲第一种:Internet 套接字。 Internet 套接字的两种类型 什么意思?有两种类型的Internet 套接字?是的。不,我在撒谎。其实还有很多,但是我可不想吓着你。我们这里只讲两种。除了这些, 我打算另外介绍的 "Raw Sockets" 也是非常强大的,很值得查阅。 那么这两种类型是什么呢?一种是"Stream Sockets"(流格式),另外一种是"Datagram Sockets"(数据包格式)。我们以后谈到它们的时候也会用到 "SOCK_STREAM" 和 "SOCK_DGRAM"。数据报套接字有时也叫“无连接套接字” 如果你确实要连接的时候可以用connect 。 流式套接字是可靠的双向通讯的数据流。如果你向套接字按顺序输出“1,2”,那么它们将按顺序“1,2”到达另一边。它们是无错误的传递的,有自己的错误控制,在此不讨论。 有什么在使用流式套接字?你可能听说过 telnet,不是吗?它就使用流式套接字。你需要你所输入的字符按顺序到达,不是吗?同样,WWW浏览器使用的 HTTP 协议也使用它们来下载页面。实际上,当你通过端口80 telnet

}

疫情期间比较火的《阿里、字节:一套高效的iOS面试题
》,以下是自己在2020年3月份做了一遍的结果,和盲点总结,欢迎大家交流.
以下题目有些比较简单的就没有作答.部分题目需要篇幅较长的,在《另外一篇博客》中有纯手写作答.

介绍下runtime的内存模型(isa、对象、类、metaclass、结构体的存储信息等)

因为类也是对象,动态创建的时候object类(根类)的类就是meatclass

class_rw_tproperty_array_t,它的内容是property_t结构体,内容为nameattribute,对应属性,是成员变量的声明,在编译期前已经存在的属性会在编译期生成以_为开头的同名成员变量,attribute中是对成员变量的一些访问权限控制描述

class_ro_t 是编译期,编译器对类文件编译产生的,其中包含了类的方法,属性,协议等信息,它是不能被改变的,因为已经确定了大小

  • 0 在runtime加载过程中,加载完所有的类到hash表中后,会去遍历所有的类及其对应的类别列表,一次把它合并到类的class_rw_t中的信息中,如方法合并到method_list中等,这也是我们一直说类别方法是不是覆盖类中重名方法,而是在方法调用的时候会在method_list的中从后往前找,自然是category的先被找到,
  • 3,两个category的同名方法谁后被加载谁先被调用
  • 普通方法的优先级: 分类> 子类 > 父类, 优先级高的同名方法覆盖优先级低的
  • +load方法不会被覆盖
  • 同一主类的不同分类中的普通同名方法调用, 取决于编译的顺序, 后编译的文件中的同名方法会覆盖前面所有的,包括主类. +load方法的顺序也取决于编译顺序, 但是不会覆盖
  • 分类中的方法名和主类方法名一样会报警告, 不会报错
  • 声明和实现可以写在不同的分类中, 依然能找到实现
  • 当第一次用到类的时候, 如果重写了+ initialize方法,会去调用
  • 当调用子类的+ initialize方法时候, 先调用父类的,如果父类有分类, 那么分类的+ initialize会覆盖掉父类的, 和普通方法差不多
  • 父类的+ initialize不一定会调用, 因为有可能父类的分类重写了它

通过@property定义的变量,只能生成对应的getter和setter的方法声明,但是不能实现getter和setter方法,同时也不能生成带下划线的成员属性
注意:为什么不能添加属性,原因就是category是运行期决定的,在运行期类的内存布局已经确定,如果添加实例变量会破坏类的内存布局,会产生意想不到的错误。

可以给类添加成员变量,但是是私有的
可以給类添加方法,但是是私有的
添加的属性和方法是类的一部分,在编译期就决定的。在编译器和头文件的@interface和实现文件里的@implement一起形成了一个完整的类。
伴随着类的产生而产生,也随着类的消失而消失
必须有类的源码才可以给类添加extension,所以对于系统一些类,如nsstring,就无法添加类扩展
不能给NSObject添加Extension,因为在extension中添加的方法或属性必须在源类的文件的.m文件中实现才可以,即:你必须有一个类的源码才能添加一个类的extension。

消息转发机制,消息转发机制和其他语言的消息机制优劣对比

在方法调用的时候,方法查询-> 动态解析-> 消息转发 之前做了什么

load、initialize方法的区别什么?在继承关系中他们有什么区别

  • 当类被装载的时候被调用,只调用一次
    调用方式并不是采用runtime的objc_msgSend方式调用的,而是直接采用函数的内存地址直接调用的

  • 多个类的load调用顺序,是依赖于compile sources中的文件顺序决定的,根据文件从上到下的顺序调用

  • 子类和父类同时实现load的方法时,父类的方法先被调用

  • 本类与category的调用顺序是,优先调用本类的(注意:category是在最后被装载的)

  • load是被动调用的,在类装载时调用的,不需要手动触发调用

  • 当类或子类第一次收到消息时被调用(即:静态方法或实例方法第一次被调用,也就是这个类第一次被用到的时候),只调用一次

  • 调用方式是通过runtime的objc_msgSend的方式调用的,此时所有的类都已经装载完毕

  • 子类和父类同时实现initialize,父类的先被调用,然后调用子类的

  • initialize是主动调用的,只有当类第一次被用到的时候才会触发

说说消息转发机制的优劣

优势: 让语言具有动态性,更加灵活,具有更多让程序员在运行时做动作的可能性.
劣势: 高度的动态话导致安全性降低,多层机制势必降低语言执行效率

@property定义的变量,默认的修饰符是什么?

自旋锁: 线程反复检查所变量是否可用,线程这一过程中保持执行,因此是一种忙等状态,一旦获取了,线程一直保持,直到显示的释放,自旋锁避免了进程上下文切换的开销,因此,对于线程只阻塞很短的场合是有效的.

互斥锁: 避免两个线程同时对某一变量进行读写,通过将代码切片成一个个临界区而达成

OSSpinLock已经被弃用,因为会出现低优先级线程持有锁,然后高优先级去获取锁的时候,spin lock会进入忙等状态,占用大量cpu时间,这时低优先级队列无法争夺cpu时间片,从而导致任务无法完成,无法释放lock

这个志向了一个静态变量,值为-1,是根据系统情况去分配他的数值.

视图&图像相关

定时器都是依赖runloop运行的,
NSTimer是最见的定时器,注意在使用的时候在滑动的时候不会被触发,需要加入到runloop commonmode 中,在没有runloop运行的子线程,也不会执行
有内存泄漏问题,注意invalied.提供了比较多的初始化方法.比较方便易用

CADisplaylink 是根据屏幕刷新频率处罚的定时器,苹果目前的屏幕刷新频率为60HZ,华为刚出了一个90HZ的以后可能这需要注意下改动,在不同的手机上是不同的频率,他比较准确,在没有什么耗时任务卡住runloop的情况下,很稳定,但是不灵活,适合做UI刷新,添加进runloop即刻启动

这时响应者链,事件传递链就是一层层翻上去,看看谁可以响应事件.


3.1,CoreGraphic基于Quartz高级绘画引擎,主要用于运行时图像绘制,开发者可以用来处理基于路径的绘图,转换,颜色管理,离屏渲染,图案,渐变和阴影,图像数据管理,图像创建和图像遮照以及PDF文档创建、显示和分析

3.2,CoreImage用于运行前创建的图像,大部分情况下CoreImage在GPU中完成工作,如果GPU忙,会使用CPU进行处理.支持两种处理模式

  • Prepare: 准备阶段,该阶段一般处理图像解码和转换工作.
  • Commit: 将图层进行打包(序列化),并发送至Render Server,该过程递归执行,因为图层和视图都是以树形存在.
  • 将图层书转化为渲染树(对应每个图层的信息,比如顶点坐标、颜色等信息的抽离出来,形成树状结构)

图形渲染管线,实际上指的是一堆原始图形数据经过一个输送管道,期间经过各种变化处理最终出现在屏幕的过程,通常情况下,渲染管线可以描述成vertices(顶点)到pixels(像素)的过程

关于图中详细解析,看链接内

CPU计算显示内容–>GPU渲染–>渲染结果放到帧缓冲区(iOS是双缓冲)–>视频控制器按照VSync信号逐行读取帧缓冲区数据,传递给显示器显示

隐式动画 & 显示动画区别

加载后会由系统管理内存,内存占用比较小,对象释放,内存不会,多次加载相同图片不会重复加载.
适合小图片,频繁重复加载的场景

内存占用小,相同图片会重复加载,重复占用内存,对象释放,对应的内存也会释放.
适合大图片,不频繁重复加载的场景

图片是什么时候解码的,如何优化

2,图片处理(裁剪,边框等)
4,从磁盘读取数据到内核缓冲区
5,从内核缓冲区复制到用户空间(内存级别拷贝)
6,解压缩为位图(耗cpu较高)
7,如果位图数据不是字节对齐的,CoreAnimation会copy一份位图数据并进行字节对齐
以上4,5,6,7,8步是在UIImageView的setImage时进行的,所以默认在主线程进行(iOS UI操作必须在主线程执行)。

如果GPU的刷新率超过了iOS屏幕60Hz刷新率是什么现象,怎么解决

1,GPU处理完后会放入帧缓冲区,视频控制器定时读取缓冲区内容,给屏幕显示
2,如果缓冲区允许覆盖,那么就会产生丢帧,或者和面断层.不允许覆盖,就会丢帧

可以用双缓冲区,或者加大缓冲区的方案解决

如何做启动优化,如何监控

慢的原因是因为主线程的工作量大,比如IO,大量计算

从启动周期每一步分析,优化

  • 加载可执行文件(App的.o文件合集)
  • 加载动态链接库,进行rebase和bind符号绑定
  • load方法中的内容尽量放到首屏渲染后在执行或换成在initialize中执行
  • 控制C++全局变量的数量
  • 减少不用的类(类别)和方法
  • 首屏初始化所有配置文件的读写操作
  • 只放和首屏渲染相关的业务代码,其他非首屏业务的初始化监听注册,配置文件读取放到首屏渲染后
  • 使用time profiler观察方法耗时,优化对应的方法

1,定时任务获取主队列的调用栈,0.002获取一次,记录每次获取的方法内容,对应方法时间累加
2,hook objcMsgSend方法 获取每个方法前后时间,记录时间,需要汇编,难度大

如何做卡顿优化,如何监控

在一个VSync内GPU和CPU的协作,未能将渲染任务完成放入到帧缓冲区,视频控制器去缓冲区拿数据的时候是空的,所以卡帧

  • 提高代码执行效率(JSON to Model的方案,锁的使用等,减少循环,UI布局frame子线程预计算)
  • UI减少全局刷新,尽量使用局部刷新
  • CADisplayLink 监控,结合子线程和信号量,两次事件触发时间间隔超过一个VSync的时长,上报调用栈

如何做耗电优化,如何监控

使用定时器,每隔一段时间获取一次电量,并上报

电量优化(原则尽量少的减少计算)

  • 降低地理位置的刷新频次,蓝牙和定位按需获取.不用关掉
  • 整合UI刷新,降低刷新频次
  • 避免使用透明元素,image和imageview大小设置相同降低计算
  • 使用懒加载,不用的东西不要提前创建
  • 选择合适的数据结构存储数据,
    字典,使用键来查找很快
    NSSets,是无序的,用键查找很快,插入/删除很快
  • 优化算法,减少不必要的循环

如何做网络优化,如何监控

网络优化分为,提速,节流,安全,选择合理网络协议处理针对的业务(比如聊天的,用socket)

  • 增加缓存,比如图片缓存,H5缓存,列表页数据放入数据库缓存
  • 降低请求次数,多个借口合并,这里需要服务端配合
  • 压缩传输内容,减少不必要数据传输
  • 在用户角度上,在视频等大流量场景要判断是否为wifi网络,并提示用户
  • 数据加密,防止中间人窃听
  • 加入签名,防止中间人篡改
  • 加入https证书校验,防止抓包

苹果使用证书的目的是什么

为了防止开发者的应用随意安装在手机上,用证书控制,只有经过苹果允许的应用才可以安装上,防止盗版什么的
这么做的目的是为了整个应用生态的体验着想,当然也有安全因素在里边.

开发者怎么在debug模式下把app安装到设备呢(这个题不会)

只是列出一些iOS比较核心的开源库,这些库包含了很多高质量的思想,源码学习的时候一定要关注每个框架解决的核心问题是什么,还有它们的优缺点,这样才能算真正理解和吸收

JSPatch、Aspects(虽然一个不可用、另一个不维护,但是这两个库都很精炼巧妙,很适合学习)
Weex/RN, 笔者认为这种前端和客户端紧密联系的库是必须要知道其原理的
CTMediator、其他router库,这些都是常见的路由库,开发中基本上都会用到
请圈友们在评论下面补充吧

手动埋点、自动化埋点、可视化埋点

  • 手动埋点:代码侵入,不好维护,无法线上动态,但是灵活

  • 可视化买点:开发代价大,自定义程度低,灵活性差.好处就是的运营人员上手快.对业务发展由好处.

单例,工厂,MVC、MVP、MVVM、观察者,代理,装饰模式

  • 内存一直占用,滥用导致内存浪费
  • 线程安全问题多地方使用其中的数据,线程安全需要注意
  • 内容数据如果影响多个地方,代码耦合度很高.

常见的路由方案,以及优缺点对比

设计一个图片缓存框架(LRU)
设计一个线程池?画出你的架构图
你的app架构是什么,有什么优缺点、为什么这么做、怎么改进
oc怎么实现多继承?怎么面向切面(可以参考Aspects深度解析-iOS面向切面编程)
哪些bug会导致崩溃,如何防护崩溃
app的启动过程(考察LLVM编译过程、静态链接、动态链接、runtime初始化)
沙盒目录的每个文件夹划分的作用
什么是中间人攻击?怎么预防
TCP的握手过程?为什么进行三次握手,四次挥手

堆和栈区的区别?谁的占用内存空间大

栈由编译器申请空间大小,是固定的,连续的,对应线程是唯一的,快速高效,缺点是有限制,先入后出不灵活

堆区是通过alloc分配的,它的内存空间是动态的,由一个空闲内存空间指针链表维护,内存空间不连续,可以很大,但是容易内存碎片化.好处就是查询快.

###加密算法:对称加密算法和非对称加密算法区别

常见的对称加密和非对称加密算法有哪些

对于移动开发者来说,一般不会遇到非常难的算法,大多以数据结构为主,笔者列出一些必会的算法,当然有时间了可以去LeetCode上刷刷题

基本的动态规划题、贪心算法、二分查找

}

我要回帖

更多关于 全局变量不赋值是0吗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信