某团#
- static定义在头文件的危害,回来做了下测试直接上代码
#import <Foundation/Foundation.h>
#include <objc/runtime.h>
#include "staticccccc.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"%p",&a);
static int a = 1000;
NSLog(@"%p",&a);
staticccccc *s = [[staticccccc alloc] init];
s.prinstA;
}
return 0;
}
/*
2016-09-19 21:15:54.600 内存[2105:104521] main : 0x1000011a8
2016-09-19 21:15:54.601 内存[2105:104521] main : 0x1000011ac
2016-09-19 21:15:54.601 内存[2105:104521] staticccccc : 0x1000011b0
Program ended with exit code: 0
*/
在staticccccc类中声明了一个静态变量,prinstA方法可以打出来。
3个静态变量的地址都是不一样的,全局静态变量的作用域只在当前文件里面,如果头文件被其他引用,那么头文件里面的静态变量会再次定义一次。危害就是如果头文件被引用了多次,那么这个静态变量就会被定义多次,虽然在不同的作用域,但是名字相同
2,线程崩溃了这个进程一定会崩溃?一般崩溃肯定伴随栈溢出、读取或者访问了非法地址。 如果线程以非法的形式结束的话,必然进程会崩溃啊。
3,NSMutableArray的线程安全问题。self.mArr = [NSMutableArray new]有没有问题?
我不大明白面试官的意思, [NSMutableArray new]创建这个东西我觉得应该是没有线程问题的,如果觉得执行这个操作需要时间,在这段时间内其他线程又访问这个NSMutableArray的话,那么我一般就会
NSMutableArray *marr = [NSMutableArray new];
self.mArr = marr;
或者从另外一方面来讲直接给实例变量赋值而不走set方法貌似是一个不错的解决方案
_mArr = [NSMutableArray new];
赋值操作应该是原子的。即使self.mArr 是空使用插入操作也不会出错,因为OC是可以给空对象发消息的。如果真要制造一个崩溃的场景。可是谁会这样做呢?
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSMutableArray *marr = [NSMutableArray new];
self.mArr = marr;
});
for (int i = 0; i < 10; i++) {
[_mArr insertObject:[NSNumber numberWithInt:1] atIndex:i];
}
通常对于NSMutableArray多线程操作,加上互斥锁就可以避免大部分崩溃情况了.加上@synchronized (self)
dispatch_async(dispatch_get_global_queue(0, 0), ^{
@synchronized (self) {
NSMutableArray *marr = [NSMutableArray new];
_mArr = marr;
}
});
@synchronized (self) {
for (int i = 0; i < 10; i++) {
[_mArr insertObject:[NSNumber numberWithInt:1] atIndex:i];
}
}
或者直接加锁和用GCD也行。
4,NULL、Nil、nil、NSNull 有何区别?一脸蒙蔽
nil对象被设计来跟NULL空指针关联的。他们的区别就是nil是一个对象,而NULL只是一个值...而且我们对于nil调用方法,不会产生crash或者抛出异常....
The NSNull class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).
一般在集合中不允许使用nil值,但是可以使用NSNULL。
Nil Defines the id of a null class 。 nil是空对象的定义 , Nil是空类的定义。
ifndef Nil
if __has_feature(cxx_nullptr)
define Nil nullptr
else
define Nil __DARWIN_NULL
endif
endif
5,数据库索引
完全忘记概念了,聚簇索引 是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。
我唯一的印象就是非聚类索引会增加数据库内存,开辟一段空间来建立数据结构,通常是一颗查找数,建立索引到数据地址的映射。
聚簇索引 是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。这句话说得蛮好的。
6,KVO说多了都是泪,本来以为需要大书特书一番的,结果其实几句话就可以解决了。
1,被监听对象设置addOserbver方法,存储需要那个对象监听。
2,set方法重写,如果发现本属性被监听,那么发消息给监听对象。
3,监听对象需要一个实现一个接受方法,来接收被监听对象发过来的消息。
7,算法--找出数组中出现次数超过一半的数,
貌似是编程之美上的,以前见过全忘了,以后面试的时候不要一来就想最复杂度最小的方法,想到啥说啥,这种题,哈希,排序都可以解的,但是的确不是最优的,但是应该还是要向面试官表明自己能做这道题。虽然并不是最优的,总比一味的想最优的方法卡在那特别尴尬。复杂度为N的方法.回来写2分钟搞定 欲哭无泪。
int main(int argc, const char * argv[]) {
int n = 10;
int a[10] = {1,2,1,1,4,5,3,1,1,1};
int tmp = a[0];
int count = 1;
for (int i = 1 ; i<n; i++) {
if (a[i] == tmp) {
count++;
}else{
count--;
if (count == 0) {
count = 1;
tmp = a[++i];
}
}
}
printf("%d",tmp);
return 0;
}
某狗:#
1.delloc方法,学的时候全是ARC根本没有接触过delloc这个方法!“#¥#%&‘
百度了半天,得出的结论是ARC下面可以忽略这个方法,如果实在需要delloc方法里面去销毁一些东西,比如不受ARC管理的C++对象,写个method swizzling貌似是个不错的选择。
2, imageNamed
利用它可以方便加载资源图片。用imageNamed的方式加载时,会把图像数据根据它的名字缓存在系统内存中,以提高imageNamed方法获得相同图片的image对象的性能。即使生成的对象被 autoReleasePool释放了,这份缓存也不释放。而且没有明确的释放方法。如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存, 不会被autorelease释放,不会被autorelease释放,不会被autorelease释放,不会被autorelease释放。
imageWithContentsOfFile不会生成缓存 , 会被autorelease释放。
机会很少且面且珍惜!!!!