4 初级ios开发工程师面试题

4.1 c语言

4.1.1 指针

说明:a&a包含的地址相同,但含义不同

  • a:数组的首地址,也就是 a[0]的地址
  • &a:对象的首地址,也就是数组的地址
1
2
3
4
5
6
7
8
9
main {
int a[5] = {1, 2, 3, 4, 5};
// a:相当于a[0]
// &a:数组的地址
// (&a + 1):指针加1根据指针的类型增加的量不同,a是指向数组的指针,数组的大小为5个Int,因此(&a + 1)指向a[5](溢出)
// *(ptr - 1):因为ptr指向的是元素,因此*(ptr - 1)为a[4]
int *ptr = (int *)(&a + 1);
printf("%d, %d", *(a + 1), *(ptr - 1));// 2, 4
}

4.2 Object-C笔试

4.2.1 写一个NSString类的实现

接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 类方法:初始化
* @param {char *} const nullTerminatedCString 字符串(不带\0结尾)
* @param {NSStringEncoding} encoding 编码方式
*/

+ (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;

/**
* 类方法(工厂方法)
* @param {char *} const nullTerminatedCString 字符串(不带\0结尾)
* @param {NSStringEncoding} encoding 编码方式
* @return {} 实例
*/

+ (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding {
NSString *obj;
// 分配内存
obj = [slef allocWithZero: NSDefaultMallocZone()];
// 初始化
obj = [obj initWithCString: nullTerminatedCString encodign: encoding];
return AUTORELEASE(obj);
}

4.2.2 Object-C 有多重继承吗?不是的话有什么替代方法?

答:cocoa中所有的类都是NSObject的子类,多继承在这里是用protocol委托代理来实现的。

4.2.3 Object-C有私有方法吗?私有变量呢?

答:Object-C类里面的方法只有两种,静态方法实例方法

  • 实例变量:默认都是私有的
  • 实例方法:默认都是共有的

4.2.4 const以为这只读,下面的声明都是什么意思?

const作用:

  1. 声明变量:阻止一个变量被修改
  2. 声明指针:可以指定指针本身为const,也可以指定指针所指的数据为const
  3. 声明函数:可以修饰形参,表明它是一个输入参数,在函数内部不能改变值
  4. 类的成员函数:若指定为const类型,则表明其是一个常函数,不能修改类的成员变量
1
2
3
4
5
6
const int a;// 只读整形变量
int const a;// 只读整形变量

const int *a;// 指向int型常量的指针(整型数不可修改,指针可修改)
int * const a;// 指向int型变量的只读指针(整型数可修改,指针不可修改)
int const * a const;// 指向int型常量的只读指针(整型不可修改,指针不可修改)

4.2.5 static的作用

说明:

  1. 函数体内:函数体内static变量的作用范围为改函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值
  2. 全局变量:在模块内的static全局变量可以被模块内所有函数访问,但不能被模块外其它函数访问
  3. 全局函数:模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内
  4. 类中的成员变量:在类中的static成员变量属于整个类所有,对类的所有对象只有一份拷贝。
  5. 类中的成员函数:在类中的static成员函数属于整个类所有,这个函数不接收this指针,因而只能访问类的static成员变量。

4.2.6 extern “C”的作用

说明:

  1. extern "C"限定的函数或变量是extern类型的
  2. extern "C"限定的变量和函数是按照C语言方式编译和链接的

4.2.7 #import跟#include区别,@class呢?

答:@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在.m
文件中还是需要使用#import;而#import比起#include的好处就是好不会引起交叉编译。

4.2.8 Object-C的优缺点

优点:

  1. Cateogies
  2. Posing
  3. 动态识别
  4. 指标计算
  5. 弹性信息传递
  6. 不是一个过度复杂的C衍生语言
  7. Object-CC++可以混合编程

缺点:

  1. 不支持命名空间
  2. 不支持运算符重载
  3. 不支持多重继承
  4. 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。

4.2.9 Object-C的内存管理

说明:通过分配和初始化(比如[[MyClass alloc] init])的方式来创建对象,那就拥有这个对象,需要负责该对象的释放。这个规则在使用NSObject的便利方法new时也同样适用。

  • 拷贝(copy)对象:也会拥有拷贝得到的对象,需要负责该对象的释放
  • 保持(retain)对象:部分拥有这个对象,需要在不再适用时释放该对象。

注意:反过来如果从其它对象那里接收到一个对象,则不拥有该对象,也不应该释放它。

4.2.10 自动释放池是什么,如何工作?

答:当向一个对象发送一个autorelease消息时,Cocoa就会将改对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的对象也就被释放。

4.2.11 堆和栈的区别

**
管理方式 由编译器自动管理,无序手工控制 释放工作由程序控制,容易产生内存泄漏
申请大小 是向高地址扩展的数据结构,是不连续的内存区域。堆获得空间比较灵活,也比较 Windows下,栈时向低地址扩展的数据结构,是一块连续的内存区域。能从栈获得的空间较
碎片问题 频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低 栈是先进先出的队列,不会产生碎片
分配方式 动态分配 静态分配和动态分配
分配效率 堆是c/c++函数库提供的,机制比较复杂 栈是及其系统提供的数据结构,计算机在底层对栈提供支持

4.3 Swift特性

答:

  1. 支持所有CObject-C的基本类型
  2. 提供了两种功能强劲的集合类型ArrayDictionary
  3. 支持一种新的高级类型元组
  4. 可选类型
  5. 闭包特性
  6. 支持脚本语言的特性,但能高效地编译运行
  7. 类型安全