Skip to content

Latest commit

 

History

History
203 lines (156 loc) · 8.61 KB

07深圳iOS面试分享2018年4月.md

File metadata and controls

203 lines (156 loc) · 8.61 KB

深圳iOS面试分享2018年4月

作者:Xcode_boy&&juejin.im/post/5adaed6a518825673123c757

算法题

请在1000万个整型数据中以最快的速度找出其中最大的1000个数?

参考内容

这是一个经常被问到的问题,百度网上解法也很多。这里仅提供基本思路,供参考:

  • 把1000万的整型平均分到合适n个文件中,分别对每一份文件找出前1000个最大的数,最后对每份文件前1000数据用常规算法合并即可。
  • 那么,如何从每一份文件中找出前1000个最大的数呢?
  • 先取文件中前1000个数放到数组中,并排好序(假设升序),之后从文件中读取下一个数与数组第一个数比较,如果比数组中第一个数大,则替换数组第一个数,并重新排序,之后再取下一个数进行下轮比较即可。

循环链表题:一个有序循的整形环链表断开了,请插入一个整形数,使得链表仍然是有序的。

C语言实现参考内容
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *next;
}linklist;
 
linklist *createList(){
	linklist *head,*p,*q;
    int x;
	scanf("%d",&x);
	p=(linklist *)malloc(sizeof(linklist));
	p->data=x;
	head=p;
	scanf("%d",&x);
	while (x!=-1){
		q=(linklist *)malloc(sizeof(linklist));
		q->data=x;
		p->next=q;
		p=q;
		scanf("%d",&x);
	}
	p->next=NULL;
	return head;
}
 
linklist *insertList(int n,linklist *head){
	linklist *p,*q,*s;
	s=(linklist *)malloc(sizeof(linklist));
	s->data=n;s->next=NULL;
    if (head==NULL) return p;
	p=q=head;
	while (q!=NULL && q->data < n){
		p=q;q=q->next;
	}
	if (p==head){
		s->next=p;head=s;//在头部插入
	}
	else{
	    s->next=q;p->next=s;
	}
	return head;
}
void printList(linklist *head){
	linklist *t;
	t=head;
	if (t==NULL)
		printf("这是一个空列表\n");
	while (t!=NULL){
		printf("%d ",t->data);
		t=t->next;
	}
	printf("\n");
}
int main()
{
    linklist *head;
	int n;
	printf("请输入一组递增数,以-1结束\n");
	head=createList();
	printList(head);
	printf("请输入要插入的数\n");
	scanf("%d",&n);
	head=insertList(n,head);
	printList(head);
 
	system("pause");
	return 0;
}

Block中可以修改全局变量,全局静态变量,局部静态变量吗?

参考内容

修饰符所有权一同捕获

  • 参考链接 深入研究Block捕获外部变量和__block实现原理
    • 全局变量和静态全局变量的值改变,以及它们被Block捕获进去,因为是全局的,作用域很广
    • 静态变量和自动变量,被Block从外面捕获进来,成为__main_block_impl_0这个结构体的成员变量
    • 自动变量是以值传递方式传递到Block的构造函数里面去的。Block只捕获Block中会用到的变量。由于只捕获了自动变量的值,并非内存地址,所以Block内部不能改变自动变量的值。
    • Block捕获的外部变量可以改变值的是静态变量,静态全局变量,全局变量

NSString代码输出考察 会输出什么?

@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, weak)   NSString *weakString;
	
strongString =  [NSString stringWithFormat:@"%@",@"string1"];
weakString =  strongString;
strongString = nil;
	
NSLog(@"%@", weakString);
	
参考内容
  • NSString的问题,这个跟retainCount没什么太大的关系
  • 首先,stringWithFormat方法创建的字符串是autorelease的,本身就会延迟释放,直接跟log的话肯定不会输出null,如果你写个button做触发,放在方法外作log的话,才会打印出null
    • 在64位环境下,苹果对NSString做了优化,细节不说,具体表现是,当非字面值常量的数字,英文字母字符串的长度小于等于 9 的时候会自动成为 NSTaggedPointerString 类型,如果有中文或其他特殊符号存在的话则会直接成为__NSCFString 类型。而NSTaggedPointerString是个常量释放不掉的.
    • 最后,如果是使用@""或者initWithString:@""的方式创建的字符串,会被转换成__NSCFConstantString,也是个常量,释放不掉不会输出null

SDWebImage实现原理是什么? 它是如何解决tableView的复用时出现图片错乱问题的呢?

参考内容
  • 解决tableView复用错乱问题:每次都会调UIImageView+WebCache文件中的 [self sd_cancelCurrentImageLoad];
  • 原理解释参考
    • SDWebImageDownloader
    • 图片的下载操作放在一个NSOperationQueue并发操作队列中,队列默认最大并发数是6
    • 每个图片对应一些回调(下载进度,完成回调等),回调信息会存在downloader的URLCallbacks(一个字典,key是url地址,value是图片下载回调数组)中,URLCallbacks可能被多个线程访问,所以downloader把下载任务放在一个barrierQueue中,并设置屏障保证同一时间只有一个线程访问URLCallbacks。,在创建回调URLCallbacks的block中创建了一个NSOperation并添加到NSOperationQueue中
    • 下载的核心是利用NSURLSession加载数据,每个图片的下载都有一个operation操作来完成,并将这些操作放到一个操作队列中,这样可以实现图片的并发下载。
    • 内存缓存的处理由NSCache对象实现,NSCache类似一个集合的容器,它存储key-value对,类似于nsdictionary类,我们通常使用缓存来临时存储短时间使用但创建昂贵的对象,重用这些对象可以优化新能,同时这些对象对于程序来说不是紧要的,如果内存紧张就会自动释放。
    • 先在内存中放置一份缓存,如果需要缓存到磁盘,将磁盘缓存操作作为一个task放到串行队列中处理,会先检查图片格式是jpeg还是png,将其转换为响应的图片数据,最后吧数据写入磁盘中(文件名是对key值做MD5后的串)。

Swift问题

struct 和 class 的区别?

参考内容
  • 类可以继承,结构体不可以

  • 可以让一个类的实例来反初始化,释放存储空间,结构体做不到

  • 类的对象是引用类型,而结构体是值类型。所以类的赋值是传递引用 ,结构体则是传值。

class与staitc关键字的区别?

参考内容
  • static 可以在类、结构体、或者枚举中使用。而 class 只能在类中使用。
  • static 可以修饰存储属性,static 修饰的存储属性称为静态变量(常量)。而 class 不能修饰存储属性。
  • static 修饰的计算属性不能被重写。而 class 修饰的可以被重写。
  • static 修饰的静态方法不能被重写。而 class 修饰的类方法可以被重写。
  • class 修饰的计算属性被重写时,可以使用 static 让其变为静态属性。
  • class 修饰的类方法被重写时,可以使用 static 让方法变为静态方法。

觉得整理的蛮不错,可以赞赏一下旺仔(收集整理不易,且赞且珍惜)

链接