iOS面试系列

记一次某公司iOS面试总结

2018-04-19  本文已影响17人  温特儿

昨天去了一公司面试,面试官问的都是些很基础的东西,觉得虽然基础,但却在工作中可能会有用到,所以特意记录下来。

结合面试问题然后展出的一些相关的知识点~

Q:"abcd"占多大空间,int类型占多大?

A:
"abcd" 占用5个字节,因为双引号括起的叫字符串,并含一个字符串结束符
字符串长度strlen( "abcd")-》 4
占内存 sizeof ("abcd") -》 5

延伸:
位:"位(bit)"是电子计算机中最小的数据单位。每一位的状态只能是0或1。
字节:8个二进制位构成1个"字节(Byte)",它是存储空间的基本计量单位。1个字节可以储存1个英文字母或者半个汉字,换句话说,1个汉字占据2个字节的存储空间

一般32位操作系统中 int占用4字节(Byte)/32位,char占1字节(Byte),short占2字节(Byte)

Q:内存栈和内存堆的区别

A:

例子:

//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main() {
  int b; 栈
  char s[] = "abc"; 栈
  char *p2; 栈
  char *p3 = "123456"; 123456/0 在常量区,p3在栈上。
  static int c =0;全局(静态)初始化区
  p1 = (char *)malloc(10);
  p2 = (char *)malloc(20);
  分配得来得10和20字节的区域就在堆区。
  strcpy(p1, "123456"); 123456/0放在常量区,编译器可能会将它与  p3所指向的"123456"优化成一个地方。
}

Q:进程和线程的关系

A:

Q:进程、线程、堆、栈的关系

在一个进程中的线程中 共享堆区,而进程中的线程各自维持自己的堆栈
(感觉这块说的有点太简单了,如果你有好的见解,不妨在下面👇评论区,写上你的看法,我会及时更新的)

Q:HTTP在七层结构中的哪个层? HTTPS呢

A:
七层结构:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

TCP属于传输层,HTTP属于应用层

HTTPS加密在传输层,传输层的功能包括是否选择差错恢复协议还是无差错恢复协议,以及同一主机上对不同应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包重新排序

HTTPS在数据传输过程中采用非对称加密方式
对称加密:加密数据用的密钥,跟解密数据用的密钥是一样的
非对称加密:加密数据的密钥(公钥),跟解密数据使用的密钥(公钥)不一样

公钥放在客户端,密钥放在服务端,公钥加密的数据只有密钥能解开,私钥加密的数据也只有公钥能解开
可信任的证书颁发机构CA颁发的证书里面包含了公钥信息

HTTPS虽然用到了公开密钥加密,但同时也结合了其他手段,如对称加密,来确保授权、加密传输的效率、安全性

整个简化的加密通信的流程就是:
小明访问XX,XX将自己的证书给到小明(其实是给到浏览器,小明不会有感知)
浏览器从证书中拿到XX的公钥A
浏览器生成一个只有自己的对称密钥B,用公钥A加密,并传给XX(其实是有协商的过程,这里为了便于理解先简化)
XX通过私钥解密,拿到对称密钥B
浏览器、XX 之后的数据通信,都用密钥B进行加密

注意:对于每个访问XX的用户,生成的对称密钥B理论上来说都是不一样的。比如小明、小王、小光,可能生成的就是B1、B2、B3.

握手:证书下发,密钥协商
数据传输:使用握手阶段协商的密钥加密

参照 //www.ruanyifeng.com/blog/2014/02/ssl_tls.html

Q:多线程使用问题

A:
Critical Section(临界代码段)
指的是不能同时被两个线程访问的代码段,比如一个变量,被并发进程访问后可能会改变变量值,造成数据污染(数据共享问题)。

Race Condition (竞态条件)
当多个线程同时访问共享的数据时,会发生争用情形,第一个线程读取改变了一个变量的值,第二个线程也读取改变了这个变量的值,两个线程同时操作了该变量,此时他们会发生竞争来看哪个线程会最后写入这个变量,最后被写入的值将会被保留下来。

Deadlock (死锁)
两个(多个)线程都要等待对方完成某个操作才能进行下一步,这时就会发生死锁。

Thread Safe(线程安全)
一段线程安全的代码(对象),可以同时被多个线程或并发的任务调度,不会产生问题,非线程安全的只能按次序被访问。
所有Mutable对象都是非线程安全的,所有Immutable对象都是线程安全的,使用Mutable对象,一定要用同步锁来同步访问(@synchronized)。
互斥锁:能够防止多线程抢夺造成的数据安全问题,但是需要消耗大量的资源
原子属性(atomic)加锁
atomic: 原子属性,为setter方法加锁,将属性以atomic的形式来声明,该属性变量就能支持互斥锁了。
nonatomic: 非原子属性,不会为setter方法加锁,声明为该属性的变量,客户端应尽量避免多线程争夺同一资源。

Context Switch (上下文切换)
当一个进程中有多个线程来回切换时,context switch用来记录执行状态,这样的进程和一般的多线程进程没有太大差别,但会产生一些额外的开销。

Q:快速排序算法实现

A:
算法思路:基于递归实现

参考代码:

void quickSort(int *arr, int _left, int _right) {
    if (_left >= _right)  return; // 左边的索引大于等于右边索引,代表已经整理完成一组
    int left = _left;
    int right = _right;
    int key = arr[left];
    while (left < right) { // 当left!<right时说明一轮扫描结束
        while (left < right && key <= arr[right]) {
            // 结束循环的条件是:找到第一个比key小的元素位置 && left<right
            right--; // 向左扫描
        }
        arr[left] = arr[right]; // 找到第一个比key小的元素,补key值的空缺位

        while (left < right && key >= arr[left]) {
            // 这是left在左侧组内向右扫描,同上,不过注意结束循环条件相反
            left++;
        }
        arr[right] = arr[left];
    }
    arr[left] = key; // 当组内扫描一遍完成后,key值回归
    quickSort(arr, _left, left-1);
    quickSort(arr, right+1, _right);
}

以上是本篇文章的所有内容~ 希望会对你有所帮助🙏

上一篇下一篇

猜你喜欢

热点阅读