面试题

一、iOS

1、快速排序

平均时间复杂度O(nlogn) 

最差时间复杂度O(n^2)

核心思想是分治

算法过程:

1)从待排序数组中选取一个参照数A。

2)把<=A的数放到A的左边,>A的数放到A的右边。这样就形成了左右两个待排序的子数组。

3)对子数组重复步骤1)和2),直到所有子数组都只包含一个数。 

示例代码:

/**
 @param arr 待排序子数组
 @param l 子数组起点下标
 @param r 子数组终点下标
 */
+ (void)quick_sort:(NSMutableArray *)arr left:(NSInteger)l right:(NSInteger)r {
    if(l < r) { // 子数组不止一个数,递归边界条件
        NSInteger pivot = [arr[l] intValue]; // 参照数,这里取起点数,这样简单的选取会出现逆序最坏情况,所以会有随机选取参照数等优化
        NSInteger pl = l, pr = r; // 游标
        while(pl < pr) { // 循环寻找小数、大数
            while(pl < pr && [arr[pr] intValue] >= pivot) pr--; // 从右向左找一个比参照数小的数
            if(pl < pr) {
                // 因[arr[pr] intValue] < pivot,跳出循环
                arr[pl] = arr[pr]; // 找到小的数,放左边
                pl++;
            }
            while(pl < pr && [arr[pl] intValue] < pivot) pl++; // 从左向右找一个大于等于参照数的数
            if(pl < pr) {
                // 因[arr[pl] intValue] >= pivot,跳出循环
                arr[pr] = arr[pl]; // 找到大的数放右边
                pr--;
            }
        }
        // 因pl=pr跳出循环
        arr[pl] = [NSNumber numberWithInteger:pivot];
        // 分治,为了减少递归调用代价,会有子数组的数比较少时,采用其他排序,如选择排序等优化
        [Algorithm quick_sort:arr left:l right:pl-1];
        [Algorithm quick_sort:arr left:pl+1 right:r];
    }
}

 

2、KVO

参见:https://www.cnblogs.com/yangwenhuan/p/9270776.html

  

3、内存区域

1)栈区:由编译器自动分配和释放;存放函数形参、局部变量;类比数据结构中的栈,连续,后进先出;向低地址增长;分配速度快;

2)堆区:由程序员分配和释放;类比数据结构中的链表,不连续,记录空闲内存块;向高地址增长;分配速度慢;

NSString *str1 = @"abcde"; // str1指针本身在栈中,@"abcde"字符串内容在堆中
NSString *str2 = str1; // 指针str2和str1指向同一块堆内存

3)全局区(静态区):

4)文字常量区:

5)代码区: 

 

4、KVC

 

 

5、isa指针

 

6、GCD,NSThread,NSOperationQueue

1)串行和并行,队列中block的执行顺序

2)同步和异步,线程阻塞与否

 

7、TCP,UDP

1、Transmission Control Protocol,传输控制协议。面向连接、可靠、基于字节流的传输层协议。

2、 

 

8、NSString的copy和strong(retain)

 

9、内存管理

引用计数,垃圾回收机制

1)ARC

2)MRC 

 

10、MVC,MVP,MVVM 

1)Model-View-Controller,展示逻辑,Massive View Controller

图10.1

2)Model-View-ViewModel, 

 

 

 

11、Objective-C是动态语言

1)在编译期,只确定要向receiver发送message(即知道selector及相关参数),但是receiver如何响应这条message,就要看运行时期动态绑定到的selector对应的方法实现了。 

 

12、delegate用weak 

 防止循环引用

 

13、property默认关键字

1)基本类型:atomic(原子性),readwrite(可读可写),assign(赋值)

2)Objective-C类型:atomic,readwrite,strong(强引用)

 

14、二叉查找树

 

15、HTTP,HTTPS

1)get和post都不安全,只不过get的数据带在url上,更容易篡改,而post的数据放在包体中,一旦被抓包就都跪了。想要安全,必须进行数据校验,或者使用HTTPS。

 

16、category(类别),extension(类扩展)

1)category有名字;extension没名字,是一种特殊的category

2)category只能添加方法和@dynamic属性,不能添加实例变量

3)extension可以添加方法、属性和实例变量 

 

17、反转链表

 

18、在main函数之前的过程

参见:https://www.cnblogs.com/yangwenhuan/p/9126223.html 

 

19、self,super

1)self是方法调用的隐含参数,表示当前对象(实例方法对应实例对象,或者类方法对应类对象)。另一个隐含参数是_cmd,表示方法的selector。

2)但super并不表示父类对象。[self message]和[super message]对应的消息接受者,都是当前对象。区别在于,前者是从当前类开始查找message对应的方法,而后者直接从父类开始查找。 

objc_msgSendSuper(struct objc_super *super, SEL op, ...) // 编译器把[super message]转成C方法调用

struct objc_super {  
    id receiver; // 当前对象 
    Class superClass; // 当前对象的父类 
};
@implementation Son : Father
- (id)init
{
    self = [super init];
    if (self)
    {
        NSLog(@"%@", NSStringFromClass([self class]));
        NSLog(@"%@", NSStringFromClass([super class])); // 也是输出Son,即receiver所属的类
    }
    return self;
}
@end

 

20、Associate

 

21、block

参见:https://www.cnblogs.com/yangwenhuan/p/9099612.html

 

22、tableview

 

23、持久化

 

24、继承

1)Objective-C不支持多继承(一个子类有多个父类)

 

25、#import,#include,@class

1)#import不重复引入头文件,相当于#include加上#pragma once(或者#ifndef #define #endif)

2)#import<>引入库的头文件(系统库或者用户自定义的库),#import引入普通头文件

3)当只需要用到一个类的类名(例如形参),而不需要任何具体信息,比如属性、实例变量和方法等等,就可以使用@class指令来告诉编译器,存在类A。这样,当类A的头文件发生改变时,那些通过@class指令引用类A的文件就不需要重新编译,从而节省编译时间。

4)@class可以避免头文件相互引入

 

26、#define宏,const常量

1)宏不做类型检查,只是文本替换;const常量有类型检查,更安全。 

 

27、static

1)

 

28、字符串反转

 

29、锁 

1)

 

30、奇数全排前面,偶数全排后面

1)最简单直接的想法 

 

二、微信小程序

 

三、机器学习

 

posted @ 2018-04-19 10:50  happyyoung  阅读(177)  评论(0编辑  收藏  举报