快手iOS实习面试总结

快手面试。

3. 内存分区:                 函数分配在哪个区?

  • 栈区(stack):

- 存放的局部变量、先进后出、一旦出了作用域就会被销毁;函数跳转地址,现场保护等;

- 程序猿不需要管理栈区变量的内存;        对于基本数据类型的变量,则直接存储它的值,对于引用类型的变量,则存的是指向对象的指针

-栈区地址从高到低分配;    

  • 堆区(heap):  
    • 堆区的内存分配使用的是alloc;        C语言中,程序员可以通过malloc函数和free函数在堆上申请和释放空间。
    • 需要程序猿管理内存;
    • ARC的内存的管理,是编译器再便宜的时候自动添加 retain、release、autorelease;
    • 堆区的地址是从低到高分配)
  • 全局区/静态区(static):
    • 包括两个部分:未初始化过 、初始化过;
      也就是说,(全局区/静态区)在内存中是放在一起的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域;
      eg:int a;未初始化的。int a = 10;已初始化的。
  • 常量区:常量字符串就是放在这里;
  • 代码区: 存放App代码;

 

 

结构体与类的区别

struct能包含成员函数吗? 能!
struct能继承吗? 能!!
struct能实现多态吗? 能!!! 

结构体和类的共同点:

都可以将多个数据封装为一个整体

结构体和类的不同点:

  • 结构体只能封装数据,而类还可以封装行为;
  • 结构体实例是值类型,类实例是对象类型
  • 结构体实例存储在栈空间,类实例存储在堆空间
  • 结构体变量赋值是值拷贝,类实例赋值是指针引用

 

C语言中malloc函数的使用方法

C语言中malloc是动态内存分配函数。
函数原型:void *malloc(unsigned int num_bytes);
参数:num_bytes 是无符号整型,用于表示分配的字节数。
返回值:如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者...)
功能:分配长度为num_bytes字节的内存块
注意:当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象。关于该函数的原型,在以前malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。

 

二叉树,完全二叉树,堆排序过程

二叉树基本概念

二叉树在图论中是这样定义的:二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点。二叉树性质如下:

 

二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。

二叉树的第 i 层至多有 2i−12i−1 个结点。

深度为 k 的二叉树至多有 2k−12k−1 个结点。

对任何一棵二叉树T,如果其终端结点数为n0n0,度为2的结点数为n2n2,则n0=n2+1n0=n2+1。

一棵深度为k,且有 2k−12k−1 个节点称之为满二叉树;

深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中,序号为1至n的节点对应时,称之为完全二叉树。

平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

 

堆排序:。它的基本思想是,将待排序的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将其与堆数组的末尾元素交换,此时末尾元素就是最大值,然后将剩余的 n - 1 个序列重新构造成一个堆,这样就得到 n - 1个元素中的次大值。如此反复执行, 便能得到一个有序序列了

比较当前父节点是否大于子节点,如果大于就交换,直到一趟建堆完成

堆排序是将数据看成是完全二叉树、根据完全二叉树的特性来进行排序的一种算法

  • 最大堆要求节点的元素都要不小于其孩子,最小堆要求节点元素都不大于其左右孩子

 

tcp几层模型,每层具体有哪些协议。

应用层: (典型设备:应用程序,如FTP,SMTP ,HTTP) 

HTTP    (Hypertext Transfer Protocol )超文本传输协议 <端口号 80>, 面向事务的应用层协议。 

DHCP(Dynamic Host Configuration Protocol)动态主机分配协议,使用 UDP 协议工作,主要有两个用途:给内部网络或网络服务供应商自动分配 IP 地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段。实 现即插即用连网。 

FTP   (File Transfer Protocol )文件传输协议<端口号21>减少或消除不同操作系统下处理文件的不兼容性。 

传输层:  (典型设备:  进程和端口)       数据单元:数据段 Segment https

 TCP  Transmission Control Protocol )传输控制协议提供可靠的面向连接的服务,传输数据前须先建立连接,结束后释放。可靠的全双工信道。可靠、有序、无丢失、不重复。 

 UDP (User Datagram Protocol )用户数据报协议发送数据前无需建立连接,不使用拥塞控制,不保证可靠交付,最大努力交付。 

网络层: (典型设备:路由器,防火墙、多层交换机) 数据单元:数据包(Packet  

IP (IPv4 · IPv6) (Internet Protocol) 网络之间互连的协议 

ARP (Address Resolution Protocol) 即地址解析协议,实现通过IP 地址得 知其物理地址。 

OSPF (Open Shortest Path Firs)开放式最短路径优先,分布式链路状态协议。 

数据链路层: (典型设备:  网卡,网桥,交换机)            数据单元:帧 Frame

物理层:(典型设备:中继器,集线器、网线、HUB)                           数据单元:比特 Bit 

 

get,post,区别,如果我要修改数据,是不是不能用get

 

1.post与get区别

GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。

(1)post是向指定的资源提交要被处理的数据,get是从指定的资源请求数据;get请求不会改变服务器的数据,但是post是可以更新的

·  get请求页面后退时,不产生影响,post请求页面后退时,会重新提交请求

·  get产生的url地址可以被缓存,而post不会缓存

·  get请求会被浏览器主动缓存,而post不会,除非手动设置

·  get请求只能进行url编码,而post支持多种编码方式

 get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留

·  get 请求在url中传送的参数有长度限制,而post没有 不超过2k-4k(根据浏览器不同,限制不一样,但相差不大)

·  对参数的数据类型,get只接受ascll字符,而post没有限制

·  post比get更安全,因为参数直接暴露在url上,所以不能用来传递敏感信息

·  get参数通过url传递,post放在request body中

GET产生一个TCP数据包;POST产生两个TCP数据包。
(记不住全部的,重点回答出1,2,5,6,9这几点即可)

对于GET方式的请求,浏览器会把http headerdata一并发送出去,服务器响应200(返回数据);

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

 

MAC和ip区别作用,区别

ip在上面一层——网络层,Mac在下一层——链路层

MAC是网卡的物理地址,是固化在网卡芯片里的,无论是电脑还是手机,正常情况下都是唯一的,对于电脑而言,大家还可以通过更换网卡的形式更换MAC地址,

。不过IP地址是跟据现在的IPv4标准指定的,不受硬件限制比较容易记忆的地址,而Mac地址却是用网卡的物理地址,多少与硬件有关系

http状态码

https://www.cnblogs.com/gitnull/p/9532129.html

下面是常见的HTTP状态码:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误

线程进程区别   资源怎么分配(多个线程来访问,加锁)

根本区别:进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位

1.地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。

2.资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。

3.一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。

4.进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程

5.线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。

两者均可并发执行。

https://blog.csdn.net/qq_35247219/article/details/51930849    iOS的锁

NSLock
NSLock是Cocoa提供给我们最基本的锁对象,这也是我们经常使用的,除lock和unlock外,NSLock还提供了tryLock和lockBeforeDate:两个方法,前一个方法会尝试加锁,如果锁不可用(已经被锁住),并不会阻塞线程,直接返回NO。后一个方法则会在指定的Date之前尝试加锁,如果在指定的时间内都不能加锁,则返回NO
 synchronized(互斥锁)
synchronized会创建一个异常捕获handler和一些内部的锁,所以使用@synchronized替换普通锁的代价是要付出更多的时间消耗
创建给给@synchronized指令的对象是一个用来区别保护块的唯一标识符。如果你在两个不同的线程里面执行上述方法,每次在一个线程传递了一个不同的对象给anObj参数,那么每次都将会拥有它的锁,并持续处理,中间不会被其他线程阻塞。然而如果你传递的是同一个对象,那么多个线程中的一个线程会首先获得该锁,而其他线程将会被阻塞直到第一个线程完成它的临界区
作为一个预防措施。@synchronized块隐式的添加一个异常处理例程来保护代码,该处理例程会在异常抛出的时候自动的释放互斥锁,这就意味着为了使用@synchronized指令,你必须在你的代码中启用异常处理。如果你不想让隐式的异常处理例程带来额外的开销,那么可以使用其他的锁
atomic
atomic只是给成员变量的set和get方法加了一个锁,防止多线程一直去读写这个成员变量。但这也仅仅是对读写的锁定,并不是线程安全。而且使用atomic比nonatomic慢了将近20倍


常见的查找算法,(哈希查找,二分查找)

https://www.cnblogs.com/yw09041432/p/5908444.html

怎么解决哈希冲突

https://www.cnblogs.com/wuchaodzxx/p/7396599.html

  1. 开放定址法
    1. 线性探测再散列
    2. 二次探测再散列
    3. 伪随机探测再散列
  2. 再哈希法
  3. 链地址法

 

ios渲染在哪一层

http://www.cocoachina.com/cms/wap.php?action=article&id=25123

iOS渲染视图的核心是Core Animation

其渲染层次依次为:图层树->呈现树->渲染树

https://www.cnblogs.com/bao-yu/p/5437415.html

CALayer 和 UIView的区别和联系

1.首先UIView可以响应事件,Layer不可以.

2.View和CALayer的Frame映射及View如何创建CALayer.

一个 Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同决定的,而一个 View 的 frame 只是简单的返回 Layer的 frame,同样 View 的 center和 bounds 也是返回 Layer 的一些属性。

 

 

ios消息传递,当元类也没有这个消息,会做什么处理?

 

基本修饰符, 哪些修饰符用哪个,NSInteger NSNumber,block,

NSNumber的属性修饰符应该用什么呢?

如果使用assign的话会有什么后果呢?

如果一个值,我们从一个属性我们从一开始就使用assign,那么久没有一个对象会保持对这个对象的应用。那么它很快就会释放了。之后我们再访问的话,就会出现野指针问题。

因此我们需要使用strong来对NSNumber进行修饰。

使用assign:对基础数据类型(如NSInteger, CGFloat)和C数据类型(int, float, double, char等), 另外还有id类型

使用copy:对NSString类型

使用retain:对其它NSObject和其子类

 

循环引用,原因,举个例子

copy MutableCopy,MutableArray。分别用什么修饰的时候是浅拷贝

ios多线程有哪些,你用过哪些

gcd dispathch_asycn和主队列,死锁。

oc写单例模式

https://www.cnblogs.com/xubaoaichiyu/p/5503225.html

OC 单例模式


概念

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

书写步骤

  1. 创建类方法,返回对象实例.以shared,default,current开头。
  2. 创建一个全局变量用来保存对象的引用
  3. 判断对象是否存在,若不存在,创建对象
非线程安全

static UserHelper * helper = nil;
+ (UserHelper *)sharedUserHelper {
    if (helper == nil) {
        helper = [[UserHelper alloc] init];
    }
    return helper;
}

线程安全

方法一

static UserHelper * helper = nil;
+ (UserHelper *)sharedUserHelper {
    @synchronized(self) {
        
        if (helper == nil) {
            helper = [[UserHelper alloc] init];
        }
    }
    return helper;
}
方法二

static UserHelper * helper = nil;
+ (void)initialize {
    
    if ([self class] == [UserHelper class]) {
        helper = [[UserHelper alloc] init];
    }
}

写法三(苹果推荐,主要用这个)

static UserHelper * helper = nil;
+ (UserHelper *)sharedUserHelper {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        helper = [[UserHelper alloc] init];
    });
    
    return helper;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值