面试题

2016-07-07  本文已影响67人  三秒嗨
1.  main() 
 {  
   int a[5]={1,2,3,4,5};  
   int *ptr=(int *)(&a+1);
//(&a+1)
&a取到数组a的首地址 &a+1就是最后的地址+1   
   printf("%d,%d",*(a+1),*(ptr-1)); 
} 
2 , 5
2.  void Func ( char str[100] )  
{  
  sizeof( str ) = ?  
}  
void *p = malloc( 100 ); 
sizeof ( p ) = ? 
100 ,4
5.写一个委托的interface 

@protocol MyDelegate;

@interface MyClass: NSObject
{
id <MyDelegate> delegate;
}

// 委托方法
@protocol MyDelegate
- (void)didJobs:(NSArray *)args;
@end
NSString类的实现
+ (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;
 
 
+ (id) stringWithCString: (const char*)nullTerminatedCString 
            encoding: (NSStringEncoding)encoding
{
  NSString  *obj;
 
 
  obj = [self allocWithZone: NSDefaultMallocZone()];
  obj = [obj initWithCString: nullTerminatedCString encoding: encoding];
  return AUTORELEASE(obj);
}
obj-c有多重继承么?不是的话有什么替代方法? 
cocoa 中所有的类都是NSObject 的子类,多继承在这里是用protocol 委托代理来实现的。你不用去考虑繁琐的多继承,虚基类的概念。多态特性在 obj-c 中通过委托来实现。 
关键字volatile有什么含义?并给出三个不同的例子
  一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
  1). 并行设备的硬件寄存器(如:状态寄存器)
  2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
  3). 多线程应用中被几个任务共享的变量
  回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。
  假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
  1). 一个参数既可以是const还可以是volatile吗?解释为什么。
  2). 一个指针可以是volatile 吗?解释为什么。
  3). 下面的函数有什么错误:
  int square(volatile int *ptr)
  {
  return *ptr * *ptr;
  }
  下面是答案:
  1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
  2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
  3). 这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
  int square(volatile int *ptr)
  {
  int a,b;
  a = *ptr;
  b = *ptr;
  return a * b;
  }
  由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
  long square(volatile int *ptr)
  {
  int a;
  a = *ptr;
  return a * a;
  }
私有方法私有属性
先说私有方法,由于Objective-C的动态消息传递机制,OC中不存在真正意义上的私有方法。但是如果你不在.h文件中声明,只在.m文件中实现,或在.m文件的Class Extension里声明,那么基本上和私有方法差不多。至于私有变量是可以通过@private来声明的,例如@interface Sample : NSObject{ @private NSString *tteesstt;} @property (nonatomic,strong) NSString *hoge;- (void)foo;@end 

则tteesstt变量是私有的。而属性hoge是默认公有。现在Apple官方文档里是用property比较多,直接定义instance variable少。将property定义到.m的Class Extension也基本上和私有变量差不多。简而言之,将你希望公有的放到.h文件,私有的放到.m文件。在import时只import .h文件(.m文件也是可以import的,但是我们一般不这么做)
作者:邵公奭链接:http://www.zhihu.com/question/26835462/answer/34217839来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
一、 Objective-C 中 #import 和 #include 的区别   




预编译指令
Objective-C:#import
C,C++:#include
#import由gcc编译器支持

在 Objective-C 中,#import 被当成 #include 指令的改良版本来使用。除此之外,#import 确定一个文件只能被导入一次,这使你在递归包含中不会出现问题。

使用哪一个还是由你来决定。一般来说,在导入 Objective-C 头文件的时候使用 #import,包含 C 头文件时使用 #include。比如:

#import <foundation /Foundation.h>

#include <asl .h>
#include <mach /mach.h>


#import比起#include的好处就是不会引起交叉编译

二、@class是用来做类引用的
@class就是告诉编译器有这么一个类,至于类的定义是啥不知道

@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import



举个例子说明:
在ClassA.h中
#import ClassB.h 相当于#include整个.h头文件。如果有很多.m文件#import ClassA.h,那么编译的时候这些文件也会#import ClassB.h增加了没必要的#import,浪费编译时间。在大型软件中,减少.h文件中的include是非常重要的。

如果
只是@class ClassB 那就没有include ClassB.h。仅需要在需要用到ClassB的ClassA.m文件中 #import ClassB.h

那么什么时候可以用@class呢?
如果ClassA.h中仅需要声明一个ClassB的指针,那么就可以在ClassA.h中声明
@ClassB
...
ClassB *pointer;

答案:  原子操作信号量机制    自旋锁    管程,会合,分布式系统 
进程之间通信的途径
答案:共享存储系统消息传递系统管道:以文件系统为基础 
进程死锁的原因
答案:资源竞争及进程推进顺序非法 
死锁的4个必要条 件
答案:互斥、请求保持、不可剥夺、环路 
死锁的处理
答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁

57.堆和栈的区别
管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
申请大小:栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个 问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出
分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

58.什么是键-值,键路径是什么? 
模型的性质是通过一个简单的键(通常是个字符串)来指定的。视图和控制器通过键来查找相应的属性值。在一个给定的实体中,同一个属性的所有值具有相同的数据类型。键-值编码技术用于进行这样的查找—它是一种间接访问对象属性的机制。
键路径是一个由用点作分隔符的键组成的字符串,用于指定一个连接在一起的对象性质序列。第一个键的性质是由先前的性质决定的,接下来每个键的值也是相对于其前面的性质。键路径使您可以以独立于模型实现的方式指定相关 对象的性质。通过键路径,您可以指定对象图中的一个任意深度的路径,使其指向相关对象的特定属性。

59.c和obj-c如何混用
1)obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj- c的代码,因为cpp只是cpp2) 在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题3)在cpp中混用obj- c其实就是使用obj-c编写的模块是我们想要的。如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。如果模块以函数实现,那么头文件要按 c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,而不能直接使用实现代码,实际上cpp混用的是 obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。obj-c的编译器支持cpp.

60.目标-动作机制
目标是动作消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见"插座变量"部分)的形式保有其动作消息的目标。
动作是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动作而实现的方法。
程序需要某些机制来进行事件和指令的翻译。这个机制就是目标-动作机制。
63.自动释放池是什么,如何工作
 当您向一个对象发送一个autorelease消息时,Cocoa就会将该对 象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。
1. ojc-c 是通过一种"referringcounting"(引用计数)的方式来管理内存的, 对象在开始分配内存(alloc)的时候引用计数为一,以后每当碰到有copy,retain的时候引用计数都会加一, 每当碰到release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁.2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的.3. autorelease和release没什么区别,只是引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一.

64.类工厂方法是什么
 类工厂方法的实现是为了向客户提供方便,它们将分配和初始化合在一个步骤中, 返回被创建的对象,并进行自动释放处理。这些方法的形式是+ (type)className...(其中 className不包括任何前缀)。
工厂方法可能不仅仅为了方便使用。它们不但可以将分配和初始化合在一起,还可以为初始化过程提供对象的分配信息。
类工厂方法的另一个目的是使类(比如NSWorkspace)提供单件实例。虽 然init...方法可以确认一个类在每次程序运行过程只存在一个实例,但它需要首先分配一个“生的”实例,然后还必须释放该实例。工厂 方法则可以避免为可能没有用的对象盲目分配内存。

65.单件实例是什么
Foundation和Application Kit 框架中的一些类只允许创建单件对象,即这些类在当前进程中的唯一实例。举例来说,NSFileManager和NSWorkspace 类在使用时都是基于进程进行单件对象的实例化。当向这些类请求实例的时候,它们会向您传递单一实例的一个引用,如果该实例还不存在,则首先进行实例的分配和初始化。 单件对象充当控制中心的角色,负责指引或协调类的各种服务。如果类在概念上只有一个实例(比如NSWorkspace),就应该产生一个单件实例,而不是多个实例;如果将来某一天可能有多个实例,您可以使用单件实例机制,而不是工厂方法或函数。

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

67.obj-c的优缺点
objc优点:  1)Cateogies   2) Posing   3) 动态识别  4) 指标计算   5)弹性讯息传递  6) 不是一个过度复杂的 C 衍生语言  7) Objective-C 与 C++ 可混合编程
缺点:   1) 不支援命名空間   2)  不支持运算符重载
  3) 不支持多重继承
  4) 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。

68.readwrite,readonly,assign,retain,copy,nonatomic 属性的作用?
@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。这是为了减少对上下文的依赖而引入的机制。5,nonatomic,非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的…)。

为什么标准头文件都有类似以下的结构?
#ifndef __INCvxWorksh 
#define __INCvxWorksh 
#ifdef __cplusplus 
extern "C" { 
#endif 
/*...*/ 
#ifdef __cplusplus 
} 
#endif 
#endif /* __INCvxWorksh */ 
显然,头文件中的编译宏“#ifndef __INCvxWorksh、#define __INCvxWorksh、#endif” 的作用 
是防止该头文件被重复引用。

简述对cocoa touch 框架的理解(包含有哪些基础框架)

iPhoneOS应用程序的基础CocoaTouch框架重用了许多Mac系统的成熟模式,但是它更多地专注于触摸的接口和优化。UIKit为您提供了在iPhoneOS上实现图形,事件驱动程序的基本工具,其建立在和MacOSX中一样的Foundation框架上,包括文件处理,网络,字符串操作等。

CocoaTouch具有和iPhone用户接口一致的特殊设计。有了UIKit,您可以使用iPhoneOS上的独特的图形接口控件,按钮,以及全屏视图的功能,您还可以使用加速仪和多点触摸手势来控制您的应用。

各色俱全的框架除了UIKit外,CocoaTouch包含了创建世界一流iPhone应用程序需要的所有框架,从三维图形,到专业音效,甚至提供设备访问API以控制摄像头,或通过GPS获知当前位置。CocoaTouch既包含只需要几行代码就可以完成全部任务的强大的Objective-C框架,也在需要时提供基础的C语言API来直接访问系统。这些框架包括:

CoreAnimation:通过CoreAnimation,您就可以通过一个基于组合独立图层的简单的编程模型来创建丰富的用户体验。

CoreAudio:CoreAudio是播放,处理和录制音频的专业技术,能够轻松为您的应用程序添加强大的音频功能。

CoreData:提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。

功能列表:框架分类

下面是CocoaTouch中一小部分可用的框架:

音频和视频:CoreAudio、OpenAL、MediaLibrary、AVFoundation

数据管理:CoreData、SQLite

图形和动画:CoreAnimation、OpenGLES、Quartz2D

网络/li>:Bonjour、WebKit、BSDSockets

用户应用:AddressBook、CoreLocation、MapKit、StoreKit

12、KVC是什么?KVO是什么?有什么特点?

• KVC是键值编码,特点是通过指定表示要访问的属性名字的字符串标识符,可以进行类的属性读取和设置

• KVO是键值观察,特点是利用键值观察可以注册成为一个对象的观察者,在该对象的某个属性变化时收到通知

13、MVC是什么?有什么特性?

– MVC是一种设计模式,由模型、视图、控制器3部分组成。

– 模型:保存应用程序数据的类,处理业务逻辑的类

– 视图:窗口,控件和其他用户能看到的并且能交互的元素

– 控制器:将模型和试图绑定在一起,确定如何处理用户输入的类

14、定义属性时,什么情况使用copy、assign、retain?

使用assign: 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float,double, char, 等等)

使用copy: 希望获得源对象的副本而不改变源对象内容时,对NSString

上一篇下一篇

猜你喜欢

热点阅读