李洪强经典面试题17

面试题及答案java

1.写一个NSString类的实现ios

+ (id)initWithCString:(c*****t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding; 程序员

+ (id) stringWithCString: (c*****t char*)nullTerminatedCString  面试

            encoding: (NSStringEncoding)encoding 数据库

编程

  NSString  *obj; 设计模式

  obj = [self allocWithZone: NSDefaultMallocZone()]; 数组

  obj = [obj initWithCString: nullTerminatedCString encoding: encoding]; 浏览器

  return AUTORELEASE(obj); 缓存

2static 关键字的做用: 

(1)函数体内 static 变量的做用范围为该函数体,不一样于 auto 变量,该变量的内存只被分配一次, 

所以其值在下次调用时仍维持上次的值; 

(2)在模块内的 static 全局变量能够被模块内所用函数访问,但不能被模块外其它函数访问; 

(3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 

它的模块内; 

(4)在类中的 static 成员变量属于整个类所拥有,对类的全部对象只有一份拷贝; 

(5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,于是只能访问类的static 成员变量。  

3线程与进程的区别和联系? 

进程和线程都是由操做系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。 

程和线程的主要差异在于它们是不一样的操做系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不一样执行路径。线程有本身的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,因此多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行而且又要共享某些变量的并发操做,只能用线程,不能用进程。

4堆和栈的区别 

管理方式:对于栈来说,是由编译器自动管理,无需咱们手工控制;对于堆来讲,释放工做由程序员控制,容易产生memory leak。 

申请大小: 

栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就肯定的常数),若是申请的空间超过栈的剩余空间时,将提示overflow。所以,能从栈得到的空间较小。 

堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是因为系统是用链表来存储的空闲内存地址的,天然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。因而可知,堆得到的空间比较灵活,也比较大。 

碎片问题:对于堆来说,频繁的new/delete势必会形成内存空间的不连续,从而形成大量的碎片,使程序效率下降。对于栈来说,则不会存在这个问题,由于栈是先进后出的队列,他们是如此的一一对应,以致于永远都不可能有一个内存块从栈中间弹出 

分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,好比局部变量的分配。动态分配由alloca函数进行分配,可是栈的动态分配和堆是不一样的,他的动态分配是由编译器进行释放,无需咱们手工实现。 

分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

5什么是键-,键路径是什么 

模型的性质是经过一个简单的键(一般是个字符串)来指定的。视图和控制器经过键来查找相应的属性值。在一个给定的实体中,同一个属性的全部值具备相同的数据类型。键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。 

键路径是一个由用点做分隔符的键组成的字符串,用于指定一个链接在一块儿的对象性质序列。第一个键的 

性质是由先前的性质决定的,接下来每一个键的值也是相对于其前面的性质。键路径使您能够以独立于模型 

实现的方式指定相关对象的性质。经过键路径,您能够指定对象图中的一个任意深度的路径,使其指向相 

关对象的特定属性。 

6目标-动做机制 

 

目标是动做消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见"插座变量"部分) 

的形式保有其动做消息的目标。 

动做是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动做而实现的方法。 

程序须要某些机制来进行事件和指令的翻译。这个机制就是目标-动做机制。 

7objc的内存管理 

??  若是您经过分配和初始化(好比[[MyClass alloc] init])的方式来建立对象,您就拥 

有这个对象,须要负责该对象的释放。这个规则在使用NSObject的便利方法new 时也一样适用。 

??  若是您拷贝一个对象,您也拥有拷贝获得的对象,须要负责该对象的释放。 

??  若是您保持一个对象,您就部分拥有这个对象,须要在再也不使用时释放该对象。 

反过来, 

??  若是您从其它对象那里接收到一个对象,则您不拥有该对象,也不该该释放它(这个规则有少数 

的例外,在参考文档中有显式的说明)。 

8 自动释放池是什么,如何工做 

当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,所以自动释放池定义的做用域内的其它对象能够向它发送消息。当程序执行到做用域结束的位置时,自动释放池就会被释放,池中的全部对象也就被释放。 

1.  ojc-c 是经过一种"referring counting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,之后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,若是此对象的计数变为了0, 就会被系统销毁. 

2. NSAutoreleasePool 就是用来作引用计数的管理工做的,这个东西通常不用你管的. 

3. autorelease和release没什么区别,只是引用计数减一的时机不一样而已,autorelease会在对象的使用真正结束的时候才作引用计数减一. 

9类工厂方法是什么 

类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中,返回被建立的对象,并 

进行自动释放处理。这些方法的形式是+ (type)className...(其中 className不包括任何前缀)。 

工厂方法可能不只仅为了方便使用。它们不但能够将分配和初始化合在一块儿,还能够为初始化过程提供对 

象的分配信息。 

类工厂方法的另外一个目的是使类(好比NSWorkspace)提供单件实例。虽然init...方法能够确认一 

个类在每次程序运行过程只存在一个实例,但它须要首先分配一个“生的”实例,而后还必须释放该实例。 

工厂方法则能够避免为可能没有用的对象盲目分配内存。 

10单件实例是什么 

Foundation 和 Application Kit 框架中的一些类只容许建立单件对象,即这些类在当前进程中的惟一实例。举例来讲,NSFileManager 和NSWorkspace 类在使用时都是基于进程进行单件对象的实例化。当向这些类请求实例的时候,它们会向您传递单一实例的一个引用,若是该实例还不存在,则首先进行实例的分配和初始化。单件对象充当控制中心的角色,负责指引或协调类的各类服务。若是类在概念上只有一个实例(好比 

NSWorkspace),就应该产生一个单件实例,而不是多个实例;若是未来某一天可能有多个实例,您可 

以使用单件实例机制,而不是工厂方法或函数。

11动态绑定 

—在运行时肯定要调用的方法 

 

动态绑定将调用方法的肯定也推迟到运行时。在编译时,方法的调用并不和代码绑定在一块儿,只有在消实发送出来以后,才肯定被调用的代码。经过动态类型和动态绑定技术,您的代码每次执行均可以获得不一样的结果。运行时因子负责肯定消息的接收者和被调用的方法。运行时的消息分发机制为动态绑定提供支持。当您向一个动态类型肯定了的对象发送消息时,运行环境系统会经过接收者的isa指针定位对象的类,并以此为起点肯定被调用的方法,方法和消息是动态绑定的。并且,您没必要在Objective-C 代码中作任何工做,就能够自动获取动态绑定的好处。您在每次发送消息时, 

 

特别是当消息的接收者是动态类型已经肯定的对象时,动态绑定就会例行而透明地发生。

12obj-c的优缺点 

objc优势: 

  1) Cateogies 

  2) Posing 

  3) 动态识别 

  4) 指标计算 

  5)弹性讯息传递 

  6) 不是一个过分复杂的 C 衍生语言 

  7) Objective-C 与 C++ 可混合编程 

缺点: 

  1) 不支援命名空间 

  2)  不支持运算符重载 

  3)不支持多重继承 

  4)使用动态运行时类型,全部的方法都是函数调用,因此不少编译时优化方法都用不到。(如内联函数等),性能低劣。 

13sprintf,strcpy,memcpy使用上有什么要注意的地方 

strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char *dst, c*****t char *src); 

将 src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为'\0',因为拷贝的长度不是由咱们本身控制的,因此这个字符串拷贝很容易出错。具有字符串拷贝功能的函数有memcpy,这是一个内存拷贝函数,它的函数原型为memcpy(char *dst, c*****t char* src, unsigned int len); 

将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。可是会有内存叠加的问题。 

sprintf是格式化函数。将一段数据经过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,形成溢出。 

14答案是:   

a) int a; // An integer   

b) int *a; // A pointer to an integer   

c) int **a; // A pointer to a pointer to an integer   

d) int a[10]; // An array of 10 integers   

e) int *a[10]; // An array of 10 pointers to integers   

f) int (*a)[10]; // A pointer to an array of 10 integers   

g) int (*a)(int); // A pointer to a function a that  takes an integer argument and returns an integer   

h) int (*a[10])(int); // An array of 10 pointers to functi*****  that take an integer argument and return an integer 

15.readwritereadonlyassignretaincopynonatomic属性的做用 

@property是一个属性访问声明,扩号内支持如下几个属性: 

1,getter=getterName,setter=setterName,设置setter与getter的方法名 

2,readwrite,readonly,设置可供访问级别 

2,assign,setter方法直接赋值,不进行任何retain操做,为了解决原类型与环循引用问题 

3,retain,setter方法对参数进行release旧值再retain新值,全部实现都是这个顺序(CC上有相关资料) 

4,copy,setter方法进行Copy操做,与retain处理流程同样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减小对上下文的依赖而引入的机制。 

copy是在你不但愿a和b共享一块内存时会使用到。a和b各自有本身的内存。

5,nonatomic,非原子性访问,不加同步,多线程并发访问会提升性能。注意,若是不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的...)。

atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操做。在多线程环境下,原子操做是必要的,不然有可能引发错 误的结果。加了atomic,setter函数会变成下面这样:

16何时用delegate,何时用Notification?答:delegate针对one-to-one关系,而且reciever能够返回值 给sender,notification 能够针对one-to-one/many/none,reciever没法返回值给sender.因此,delegate用于sender但愿接受到 reciever的某个功能反馈值,notification用于通知多个object某个事件。 

17什么是KVC和KVO?答:KVC(Key-Value-Coding)内部的实现:一个对象在调用setValue的时候,(1)首先根据方法名找到运行方法的时候所须要的环境参数。(2)他会从本身isa指针结合环境参数,找到具体的方法实现的接口。(3)再直接查找得来的具体的方法实现。KVO(Key-Value- Observing):当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。因此 isa指针其实不须要指向实例对象真实的类。因此咱们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名

18ViewController 的 loadView, viewDidLoad, viewDidUnload 分别是在何时调用的?在自定义ViewController的时候这几个函数里面应该作什么工做?答:viewDidLoad在view 从nib文件初始化时调用,loadView在controller的view为nil时调用。此方法在编程实现view时调用,view 控制器默认会注册memory warning notification,当view controller的任何view 没有用的时候,viewDidUnload会被调用,在这里实现将retain 的view release,若是是retain的IBOutlet view 属性则不要在这里release,IBOutlet会负责release 。

19

"NSMutableString *"这个数据类型则是表明"NSMutableString"对象自己,这二者是有区别的。

而NSString只是对象的指针而已。

面向过程就是分析出解决问题所须要的步骤,而后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就能够了。 

面向对象是把构成问题事务分解成各个对象,创建对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。;

20类别的做用

类别主要有3个做用:

(1)将类的实现分散到多个不一样文件或多个不一样框架中。

(2)建立对私有方法的前向引用。

(3)向对象添加非正式协议。

类别的局限性

有两方面局限性:

(1)没法向类中添加新的实例变量,类别没有位置容纳实例变量。

(2)名称冲突,即当类别中的方法与原始类方法名称冲突时,类别具备更高的优先级。类别方法将彻底取代初始方法从而没法再使用初始方法。

没法添加实例变量的局限可使用字典对象解决

21关键字volatile有什么含意?并给出三个不一样的例子:

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到

这个变量时必须每次都当心地从新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

• 并行设备的硬件寄存器(如:状态寄存器)

• 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)

• 多线程应用中被几个任务共享的变量

 

• 一个参数既能够是const还能够是volatile吗?解释为何。

• 一个指针能够是volatile 吗?解释为何。

 

下面是答案:

• 是的。一个例子是只读的状态寄存器。它是volatile由于它可能被意想不到地改变。它是const由于程序不该该试图去修改它。

• 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

22@synthesize 是系统自动生成getter和setter属性声明

@dynamic 是开发者自已提供相应的属性声明

@dynamic 意思是由开发人员提供相应的代码:对于只读属性须要提供 setter,对于读写属性须要提供 setter 和 getter。@synthesize 意思是,除非开发人员已经作了,不然由编译器生成相应的代码,以知足属性声明。

 查阅了一些资料肯定@dynamic的意思是告诉编译器,属性的获取与赋值方法由用户本身实现, 不自动生成。

23Difference between shallow copy and deep copy?
浅复制和深复制的区别?
答案:浅层复制:只复制指向对象的指针,而不复制引用对象自己。
深层复制:复制引用对象自己。
意思就是说我有个A对象,复制一份后获得A_copy对象后,对于浅复制来讲,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象自己资源
仍是只有一份,那若是咱们对A_copy执行了修改操做,那么发现A引用的对象一样被修改,这其实违背了咱们复制拷贝的一个思想。深复制就好理解了,内存中存在了
两份独立对象自己。
用网上一哥们通俗的话将就是:
浅复制比如你和你的影子,你完蛋,你的影子也完蛋
深复制比如你和你的克隆人,你完蛋,你的克隆人还活着。

24What is advantage of categories? What is difference between implementing a category and inheritance?
类别的做用?继承和类别在实现中有何区别?
答案:category 能够在不获悉,不改变原来代码的状况下往里面添加新的方法,只能添加,不能删除修改。
而且若是类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,由于类别具备更高的优先级。
类别主要有3个做用:
(1)将类的实现分散到多个不一样文件或多个不一样框架中。
(2)建立对私有方法的前向引用。
(3)向对象添加非正式协议。
 继承能够增长,修改或者删除方法,而且能够增长属性。

25.Difference between categories and extensions?

类别和类扩展的区别。

 答案:category和extensions的不一样在于 后者能够添加属性。另外后者添加的方法是必需要实现的。

extensions能够认为是一个私有的Category。

26.Difference between protocol in objective c and interfaces in java?
oc中的协议和java中的接口概念有何不一样?
答案:OC中的代理有2层含义,官方定义为 formal和informal protocol。前者和Java接口同样。
informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,可是若是有实现,就会改变类的属性。
其实关于正式协议,类别和非正式协议我很早前学习的时候大体看过,也写在了学习教程里
“非正式协议概念其实就是类别的另外一种表达方式“这里有一些你可能但愿实现的方法,你可使用他们更好的完成工做”。
这个意思是,这些是可选的。好比我门要一个更好的方法,咱们就会申明一个这样的类别去实现。而后你在后期能够直接使用这些更好的方法。
这么看,总以为类别这玩意儿有点像协议的可选协议。"
如今来看,其实protocal已经开始对二者都统一和规范起来操做,由于资料中说“非正式协议使用interface修饰“,
如今咱们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。

26What are KVO and KVC?

答案:kvc:键 - 值编码是一种间接访问对象的属性使用字符串来标识属性,而不是经过调用存取方法,直接或经过实例变量访问的机制。

不少状况下能够简化程序代码。apple文档其实给了一个很好的例子。

kvo:键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。

具体用看到嗯哼用到过的一个地方是对于按钮点击变化状态的的监控。

好比我自定义的一个button

[cpp] 

[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil]; 

#pragma mark KVO 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 

    if ([keyPath isEqualToString:@"highlighted"] ) { 

        [self setNeedsDisplay]; 

    } 

对于系统是根据keypath去取的到相应的值发生改变,理论上来讲是和kvc机制的道理是同样的。
对于kvc机制如何经过key寻找到value:
“当经过KVC调用对象时,好比:[self valueForKey:@”someKey”]时,程序会自动试图经过几种不一样的方式解析这个调用。首先查找对象是否带有 someKey 这个方法,若是没找到,会继续查找对象是否带有someKey这个实例变量(iVar),若是尚未找到,程序会继续试图调用 -(id) valueForUndefinedKey:这个方法。若是这个方法仍是没有被实现的话,程序会抛出一个NSUndefinedKeyException异常错误。
(cocoachina.com注:Key-Value Coding查找方法的时候,不只仅会查找someKey这个方法,还会查找getsomeKey这个方法,前面加一个get,或者_someKey以及_getsomeKey这几种形式。同时,查找实例变量的时候也会不只仅查找someKey这个变量,也会查找_someKey这个变量是否存在。)
设计valueForUndefinedKey:方法的主要目的是当你使用-(id)valueForKey方法从对象中请求值时,对象可以在错误发生前,有最后的机会响应这个请求。这样作有不少好处,下面的两个例子说明了这样作的好处。“
来至cocoa,这个说法应该挺有道理。
由于咱们知道button倒是存在一个highlighted实例变量.所以为什么上面咱们只是add一个相关的keypath就好了,

27What is purpose of delegates?
代理的做用?
答案:代理的目的是改变或传递控制链。容许一个类在某些特定时刻通知到其余类,而不须要获取到那些类的指针。能够减小框架复杂度。
另一点,代理能够理解为java中的回调监听机制的一种相似。

28What are mutable and immutable types in Objective C?
oc中可修改和不能够修改类型。
答案:可修改不可修改的集合类。这个我我的简单理解就是可动态添加修改和不可动态添加修改同样。
好比NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者能够添加等,能够动态申请新的内存空间

29When we call objective c is runtime language what does it mean?
咱们说的oc是动态运行时语言是什么意思?
答案:多态。主要是将数据类型的肯定由编译时,推迟到了运行时。
这个问题其实浅涉及到两个概念,运行时和多态。
简单来讲,运行时机制使咱们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。
多态:不一样对象以本身的方式响应相同的消息的能力叫作多态。意思就是假设生物类(life)都用有一个相同的方法-eat;
那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,可是调用是咱们只需调用各自的eat方法。
也就是不一样的对象以本身的方式响应了相同的消息(响应了eat这个选择器)。
所以也能够说,运行时机制是多态的基础?~~~

30what is difference between NSNotification and protocol?
通知和协议的不一样之处?
答案:协议有控制链(has-a)的关系,通知没有。
首先我一开始也不太明白,什么叫控制链(专业术语了~)。可是简单分析下通知和代理的行为模式,咱们大体能够有本身的理解
简单来讲,通知的话,它能够一对多,一条消息能够发送给多个消息接受者。
代理按咱们的理解,到不是直接说不能一对多,好比咱们知道的明星经济代理人,不少时候一个经济人负责好几个明星的事务。
只是对于不一样明星间,代理的事物对象都是不同的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的
发布会了。可是通知就不同,他只关心发出通知,而不关心多少接收到感兴趣要处理。
所以控制链(has-a从英语单词大体能够看出,单一拥有和可控制的对应关系。

31What is push notification?
什么是推送消息?
答案:太简单,不做答~~~~~~~~~~
这是cocoa上的答案。
其实到不是说太简单,只是太泛泛的一个概念的东西。就比如说,什么是人。
推送通知更是一种技术。
简单点就是客户端获取资源的一种手段。
普通状况下,都是客户端主动的pull。
推送则是服务器端主动push。

32.Polymorphism?
关于多态性
答案:多态,子类指针能够赋值给父类。
这个题目其实能够出到一切面向对象语言中,
所以关于多态,继承和封装基本最好都有个自我意识的理解,也并不是必定要把书上资料上写的能背出来。
最重要的是转化成自我理解。

33

What is responder chain?
说说响应链
答案:事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播。
能够说点事件的分发,传递以及处理。具体能够去看下touch事件这块。由于问的太抽象化了
严重怀疑题目出到越后面就越笼统。

34Difference between frame and bounds?

frame和bounds有什么不一样?

答案:frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)

bounds指的是:该view在自己坐标系统中 的位置和大小。(参照点是自己坐标系统)

35

.Difference between method and selector?

方法和选择器有何不一样?

答案:selector是一个方法的名字,method是一个组合体,包含了名字和实现.

36NSOperation queue?
答案:存放NSOperation的集合类。
操做和操做队列,基本能够当作java中的线程和线程池的概念。用于处理ios多线程开发的问题。
网上部分资料提到一点是,虽然是queue,可是却并非带有队列的概念,放入的操做并不是是按照严格的先进现出。
这边又有个疑点是,对于队列来讲,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,
可是Bfunc是等Afunc彻底操做完之后,B才开始启动而且执行,所以队列的概念离乱上有点违背了多线程处理这个概念。
可是转念一想其实能够参考银行的取票和叫号系统。
所以对于A比B先排队取票可是B率先执行完操做,咱们亦然能够感性认为这仍是一个队列。
可是后来看到一票关于这操做队列话题的文章,其中有一句提到
“由于两个操做提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”
瞬间以为这个queue名字有点忽悠人了,还不如pool~
综合一点,咱们知道他能够比较大的用处在于能够帮组多线程编程就行了。

37What is lazy loading?
答案:懒汉模式,只在用到的时候才去初始化。
也能够理解成延时加载。
我以为最好也最简单的一个列子就是tableView中图片的加载显示了。
一个延时载,避免内存太高,一个异步加载,避免线程堵塞。

38Can we use two tableview controllers on one viewcontroller?
是否在一个视图控制器中嵌入两个tableview控制器?
答案:一个视图控制只提供了一个View视图,理论上一个tableViewController也不能放吧,
只能说能够嵌入一个tableview视图。固然,题目自己也有歧义,若是不是咱们定性思惟认为的UIViewController,
而是宏观的表示视图控制者,那咱们却是能够把其当作一个视图控制者,它能够控制多个视图控制器,好比TabbarController
那样的感受。

39Can we use one tableview with two different datasources? How you will achieve this?
一个tableView是否能够关联两个不一样的数据源?你会怎么处理?
答案:首先咱们从代码来看,数据源如何关联上的,实际上是在数据源关联的代理方法里实现的。
所以咱们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据本身的须要去设置如相关的数据源。
所以,我以为能够设置多个数据源啊,可是有个问题是,你这是想干吗呢?想让列表如何显示,不一样的数据源分区块显示?

40id、nil表明什么?

id和void *并不是彻底同样。在上面的代码中,id是指向struct objc_object的一个指针,这个意思基本上是说,id是一个指向任何一个继承了Object(或者NSObject)类的对象。须要注意的是id是一个指针,因此你在使用id的时候不须要加星号。好比id foo=nil定义了一个nil指针,这个指针指向NSObject的一个任意子类。而id *foo=nil则定义了一个指针,这个指针指向另外一个指针,被指向的这个指针指向NSObject的一个子类。

nil和C语言的NULL相同,在objc/objc.h中定义。nil表示一个Objctive-C对象,这个对象的指针指向空(没有东西就是空)。

首字母大写的Nil和nil有一点不同,Nil定义一个指向空的类(是Class,而不是对象)。

SEL是“selector”的一个类型,表示一个方法的名字

Method(咱们常说的方法)表示一种类型,这种类型与selector和实现(implementation)相关

IMP定义为 id (*IMP) (id, SEL, …)。这样说来, IMP是一个指向函数的指针,这个被指向的函数包括id(“self”指针),调用的SEL(方法名),再加上一些其余参数.说白了IMP就是实现方法。

41层和UIView的区别是什么?

答:二者最大的区别是,图层不会直接渲染到屏幕上,UIView是iOS系统中界面元素的基础,全部的界面元素都是继承自它。它自己彻底是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView自己更像是一个CALayer的管理器。一个UIView上能够有n个CALayer,每一个layer显示一种东西,加强UIView的展示能力。

42GCD为Grand Central Dispatch的缩写。  Grand Central Dispatch (GCD)是Apple开发的一个多核编程的较新的解决方法。在Mac OS X 10.6雪豹中首次推出,并在最近引入到了iOS4.0。  GCD是一个替代诸如NSThread等技术的很高效和强大的技术。GCD彻底能够处理诸如数据锁定和资源泄漏等复杂的异步编程问题。 

 GCD能够完成不少事情,可是这里仅关注在iOS应用中实现多线程所需的一些基础知识。  在开始以前,须要理解是要提供给GCD队列的是代码块,用于在系统或者用户建立的的队列上调度运行。  声明一个队列  

以下会返回一个用户建立的队列:

  dispatch_queue_t myQueue = dispatch_queue_create("com.iphonedevblog.post", NULL);其中,第一个参数是标识队列的,第二个参数是用来定义队列的参数(目前不支持,所以传入NULL)。 

执行一个队列 

 以下会异步执行传入的代码: 

 dispatch_async(myQueue, ^{ [self doSomething]; });其中,首先传入以前建立的队列,而后提供由队列运行的代码块。  

声明并执行一个队列  

若是不须要保留要运行的队列的引用,能够经过以下代码实现以前的功能:  dispatch_async(dispatch_queue_create ("com.iphonedevblog.post", NULL), ^{ [self doSomething]; });  若是须要暂停一个队列,能够调用以下代码。暂停一个队列会阻止和该队列相关的全部代码运行。  dispatch_suspend(myQueue);暂停一个队列  

若是暂停一个队列不要忘记恢复。暂停和恢复的操做和内存管理中的retain和release相似。调用dispatch_suspend会增长暂停计数,而dispatch_resume则会减小。队列只有在暂停计数变成零的状况下才开始运行。dispatch_resume(myQueue);恢复一个队列   从队列中在主线程运行代码  有些操做没法在异步队列运行,所以必须在主线程(每一个应用都有一个)上运行。UI绘图以及任何对NSNotificationCenter的调用必须在主线程长进行。在另外一个队列中访问主线程并运行代码的示例以下:  dispatch_sync(dispatch_get_main_queue(), ^{ [self dismissLoginWindow]; });注意,dispatch_suspend (以及dispatch_resume)在主线程上不起做用。

使用GCD,可让你的程序不会失去响应. 多线程不容易使用,用了GCD,会让它变得简单。你无需专门进行线程管理, 很棒!

dispatch_queue_t t1=dispatch_queue_create("1", NULL);

    dispatch_queue_t t2=dispatch_queue_create("2", NULL);

    dispatch_async(t1, ^{

        [self print1];

    });

    dispatch_async(t2, ^{

        [self print2];

    });

43Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net做为Provider。 

APNS 是Apple Push Notification Service(Apple Push服务器)的缩写,是苹果的服务器。

上图能够分为三个阶段。

第一阶段:.net应用程序把要发送的消息、目的iPhone的标识打包,发给APNS。 
第二阶段:APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。 
第三阶段:iPhone把发来的消息传递给相应的应用程序,而且按照设定弹出Push通知。

http://blog.csdn.net/zhuqilin0/article/details/6527113    //消息推送机制

看内存泄露时候:在搜索中搜索run 找到Run Static Snalyzer .

44.可扩展标记语言extensible markup language;XML

2.用于标记电子文件使其具备结构性的标记语言,能够用来标记数据、定义数据类型,是一种容许用户对本身的标记语言进行定义的源语言。

3,数据库提供了更强有力的数据存储和分析能力,例如:数据索引、排序、查找、相关一致性等,XML仅仅是存储数据。

4.XML与HTML的设计区别是:XML的核心是数据,其重点是数据的内容。而HTML 被设计用来显示数据,其重点是数据的显示。

5.XML和HTML语法区别:HTML的标记不是全部的都须要成对出现,XML则要求全部的标记必须成对出现;HTML标记不区分大小写,XML则大小敏感,即区分大小写。

 

结合

  XML的简单使其易于在任何应用程序中读写数据,这使XML很快成为数据交换的惟一公共语言,虽然不一样的应用软件也支持其它的数据交换格式,但不久以后他们都将支持XML,那就意味着程序能够更容易的与Windows,Mac OS,Linux以及其余平台下产生的信息结合,而后能够很容易加载XML数据到程序中并分析他,并以XML格式输出结果。

  XML去掉了以前令许多开发人员头疼的SGML(标准通用标记语言)的随意语法。在XML中,采用了以下的语法:

  1 任何的起始标签都必须有一个结束标签

  2 能够采用另外一种简化语法,能够在一个标签中同时表示起始和结束标签。这种语法是在大于符号以前紧跟一个斜线(/),例如<tag/ >。XML解析器会将其翻译成<tag></tag>。

  3 标签必须按合适的顺序进行嵌套,因此结束标签必须按镜像顺序匹配起始标签,例如this is a samplestring。这比如是将起始和结束标签看做是数学中的左右括号:在没有关闭全部的内部括号以前,是不能关闭外面的括号的。

  4 全部的特性都必须有值。

  5 全部的特性都必须在值的周围加上双引号。

45union u

{

 double a;

 int b;

}; 

 

union u2

{

 char a[13];

 int b;

}; 

 

union u3

{

 char a[13];

 char b;

}; 

 

cout<<sizeof(u)<<endl; // 8

cout<<sizeof(u2)<<endl; // 16

cout<<sizeof(u3)<<endl; // 13

 


  都知道union的大小取决于它全部的成员中,占用空间最大的一个成员的大小。因此对于u来讲,大小就是最大的double类型成员a了,因此 sizeof(u)=sizeof(double)=8。可是对于u2和u3,最大的空间都是char[13]类型的数组,为何u3的大小是13,而 u2是16呢?关键在于u2中的成员int b。因为int类型成员的存在,使u2的对齐方式变成4,也就是说,u2的大小必须在4的对界上,因此占用的空间变成了16(最接近13的对界)。 struct s1

{

 char a;

 double b;

 int c;

 char d; 

}; 

 

struct s2

{

 char a;

 char b;

 int c;

 double d;

}; 

 

cout<<sizeof(s1)<<endl; // 24

cout<<sizeof(s2)<<endl; // 16

 

  一样是两个char类型,一个int类型,一个double类型,可是由于对界问题,致使他们的大小不一样。计算结构体大小能够采用元素摆放法,我举例子说明一下:首先,CPU判断结构体的对界,根据上一节的结论,s1和s2的对界都取最大的元素类型,也就是double类型的对界8。而后开始摆放每一个元素。

 

  对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,可是下一个元素d是double类型,要放到8的对界上,离1最接近的地址是8了,因此d被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是4,16能够知足,因此c放在了16,此时下一个空闲地址变成了20,下一个元素d须要对界1,也正好落在对界上,因此d放在了20,结构体在地址21处结束。因为s1的大小须要是8的倍数,因此21- 23的空间被保留,s1的大小变成了24。

 

  对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,下一个元素的对界也是1,因此b摆放在1,下一个空闲地址变成了2;下一个元素c的对界是4,因此取离2最近的地址4摆放c,下一个空闲地址变成了8,下一个元素d的对界是 8,因此d摆放在8,全部元素摆放完毕,结构体在15处结束,占用总空间为16,正好是8的倍数。

46ASIDownloadCache 设置下载缓存

它对Get请求的响应数据进行缓存(被缓存的数据必需是成功的200请求):

[ASIHTTPRequest setDefaultCache:[ASIDownloadCache   sharedCache]];

当设置缓存策略后,全部的请求都被自动的缓存起来。

另外,若是仅仅但愿某次请求使用缓存操做,也能够这样使用:

ASIHTTPRequest *request = [ASIHTTPRequest   requestWithURL:url];

[request setDownloadCache:[ASIDownloadCache   sharedCache]];

缓存存储方式

你能够设置缓存的数据须要保存多长时间,ASIHTTPRequest提供了两种策略:

a,ASICacheForSessionDurationCacheStoragePolicy,默认策略,基于session的缓存数据存储。当下次运行或[ASIHTTPRequest clearSession]时,缓存将失效。

b,ASICachePermanentlyCacheStoragePolicy,把缓存数据永久保存在本地,

如:

ASIHTTPRequest *request = [   ASIHTTPRequest requestWithURL:url ];

[ request   setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy ];

47HTTP协议详解

HTTP是一个属于应用层的面向对象的协议,因为其简捷、快速的方式,适用于分布式超媒体信息系统。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工做正在进行之中。

 http(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的链接方式,HTTP1.1版本中给出一种持续链接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。
HTTP协议的主要特色可归纳以下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法经常使用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不一样。因为HTTP协议简单,使得HTTP服务器的程序规模小,于是通讯速度很快。
3.灵活:HTTP容许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无链接:无链接的含义是限制每次链接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开链接。采用这种方式能够节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺乏状态意味着若是后续处理须要前面的信息,则它必须重传,这样可能致使每次链接传送的数据量增大。另外一方面,在服务器不须要先前信息时它的应答就较快。

48URL

HTTP URL (URL是一种特殊类型的URI是他的子类,包含了用于查找某个资源的足够的信息)的格式以下:
错误超连接引用无效。]
http表示要经过HTTP协议来定位网络资源;host表示合法的Internet主机域名或者IP地址;port指定一个端口号,为空则使用缺省端口80;abs_path指定请求资源的URI;若是URL中没有给出abs_path,那么当它做为请求URI时,必须以“/”的形式给出,一般这个工做浏览器自动帮咱们完成。

49TCP/UDP区别联系

TCP---传输控制协议,提供的是面向链接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间创建一个TCP链接,以后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另外一端。 

UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,可是并不能保证它们能到达目的地。因为UDP在传输数据报前不用在客户和服务器之间创建一个链接,且没有超时重发等机制,故而传输速度很快 

TCP(Transmission Control Protocol,传输控制协议)是基于链接的协议,也就是说,在正式收发数据前,必须和对方创建可靠的链接。一个TCP链接必需要通过三次“对话”才能创建起来,咱们来看看这三次对话的简单过程:1.主机A向主机B发出链接请求数据包;2.主机B向主机A发送赞成链接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工做)的数据包;3.主机A再发出一个数据包确认主机B的要求同步:“我如今就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,通过三次“对话”以后,主机A才向主机B正式发送数据。 

UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非链接的协议,它不与对方创建链接,而是直接就把数据包发送过去!  UDP适用于一次只传送少许数据、对可靠性要求不高的应用环境。 

tcp协议和udp协议的差异 

是否链接面向链接面向非链接 

传输可靠性可靠不可靠 

应用场合传输大量数据少许数据 

速度慢快

相关文章
相关标签/搜索