C以及Objective-C测试题讲解(下)

接前天的博客,今天继续讲解后27题。测试题地址:http://www.eosgarden.com/en/articles/objc-quizz/take/

31.Which of the following can be inherited?

以下哪些可被继承?

答案:protocols,classes。协议和类

说明:要注意categories无法被继承。

 

32.How do you throw an exception?

如何抛出异常?

答案:@throw e

说明:Object-C语言的异常处理符号和C++、JAVA相似。再加上使用NSException,NSError或者自定义的类,你可以在你的应用程序里添加强大的错误处理机制。异常处理机制是由这个四个关键字支持的:@try,@catch,@thorw,@finally。

 

33.What will be printed by the following program?

以下程序的输出结果是?

 

#include <stdio.h>
int main( void )
{
    int x = 3;
    printf( "%d", x++  +  ++x );
    return 0;
}

答案:Undefined behavior 不明确

 

说明:The C specification says that changing the value of a same variable multiple times in the same statement results in an undefined behavior.C语言规范说同一个变量在同一语句中被改变多次,其结果是不明确的。笔者刚开始以为是7,但xcode中运行后发现结果是8,果然很奇葩。

 

34.What will be printed by the following program?

以下程序的输出结果是?

 

#include <stdio.h>
int main( void )
{
    printf( "%u", -1 );
    return 0;
}

答案:最大的int值。

 

说明:基础,涉及负数的补码。

 

35.What class specifiers are supported by Objective-C?

OC中支持的类说明符是?

答案:OC不支持类说明符。

说明:就是不支持。

 

36.Which are true about the "realloc" function?

以下关于"realloc"方法的正确说法是?

 

void * realloc( void * ptr, size_t size );

答案:It changes the size of the allocated memory pointed to by the first argument.改变了第一个参数所指向的分配的内存大小。
The newly allocated memory will be uninitialized.新分配的内存将是未初始化的。

A NULL pointer can be passed safely as first argument.空指针可作为realloc的第一个参数。

说明:realloc的作用就是重新分配内存,先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。另外新分配的内存是未初始化的,空指针可以作为其第一个参数。

 

 

37.When was Objective-C 2.0 released by Apple?

OC2.0啥时候出的?

答案:2007

说明:这题真的没有什么意义,咱测的是技术,又不是历史。

 

38.Is it absolutely necessary for an Objective-C class to have "NSObject" as root class?

OC中的类将NSObject作为基类一定是必要的吗?
答案:不必要

说明:不一定要以NSObject为基类,但是这样的话要注意“init”、“alloc”等继承自NSObject的方法就不能使用了。

 

39.When using the "removeObjectAtIndex:" method of the "NSMutableArray" class, is the retain count of the removed object changed?

当使用NSMutableArray的removeObjectAtIndex:方法时,被移出的对象的引用计数会改变吗?

答案:会的

说明:用过的都知道,NSMutableArray和NSMutableDictionary在加入对象时引用计数+1,移出时-1。

 

40.What can you say about the code below, assuming we are developing for iPhone OS?

假设我们开发iOS程序,你怎么看以下代码?

 

- (void)bar
{
    NSArray * array = [NSArray arrayWithObjects: @"Hello", @"world", nil];
}
- (void)foo
{
    [NSThread detachNewThreadSelector:@selector(bar) toTarget:self withObject:nil];
}

答案:Runtime error 运行时错误

 

说明:标准答案是运行时错误,笔者对此稍有疑问。这段代码看起来的确是有内存泄露,使用类构造方法构造的对象将是autorelease(自释放)的,而这个方法在子线程中运行,iOS程序无垃圾回收机制,多线程状态下,子线程必须拥有一个autorelease pool(自动释放池)来管理autorelease对象。但是这段代码应该还不至于造成运行时错误,亲测,Xcode4.6.2,iPad simulator 6.1,运行时并未报错。但还是要郑重提醒,有内存泄露的代码是不可取的,虽然当时可能没什么问题,但等出问题的时候你再想去定位问题所在就很费时费力了。

 

41.What is the correct syntax for declaring the prototype of a block named "foo" returning an integer and taking a character pointer as argument?

以下声明一个名字为“foo”,返回一个整型,并以一个字符指针作为参数的正确的block语法是?

答案:int( ^ foo )( char * );

说明:其实仔细看就能发现block的声明语法和函数指针的声明语法相当类似,block的强大之处在于可以修改同一作用域下的变量。

 

42.What will be printed by the following program?

以下程序的输出?

 

#include <stdio.h>
int main( void )
{
    int x = 0xFF;
    printf( "%d", x << 2 );
    return 0;
}

答案:1020

 

说明:基础,左移2位就是乘以4,255X4=1020。

 

43. What type of variable do you need to use to implement the singleton pattern?

当你要使用单例模式的时候,变量应当定义为什么类型?

答案:static 静态类型

说明:不管是懒汉式还是饿汉式,只要用到单例,都应该确保这个类有且仅有一个实例,static静态类型是必须的。

 

44. What will be printed by the following program?

以下程序的输出?

 

#include <string.h>
#include <stdio.h>
char * get_ptr( void );
char * get_ptr( void )
{
    static char ptr[ 10 ] = "123456789";
    return ptr;
}
int main( void )
{
    char * ptr = "00000";
    strcpy( get_ptr() + 4, ptr );
    ptr = get_ptr();
    5[ strcpy( ptr, "12345" ) ] = '6';
    printf( "%s\n", get_ptr() );
    return 0;
}

答案:123456000

 

说明:看到"5[strcpy(ptr, "12345")] = '6';"这行时还真愣住了,一般不这么写,但是这种写法的确是不会报错的。

 

45.What is a category?

OC中category(分类)是什么?

答案:一种给既存的类添加方法的手段。

说明:注意category不能给既存类添加变量,如要添加变量,还是用继承吧。

 

46.What will be printed by the following program?

以下程序的输出?

 

#include <stdio.h>
void foo( char ** s );
void foo( char ** s )
{
    ++s;
}
int main( void )
{
    char * s = "Hello World!";
    foo( &s );
    foo( &s );
    printf( "%s\n", s );
    return 0;
}

答案:Hello World!

 

说明:形式参数和实际参数的问题

 

47.Does the retain count of an object change when you send an autorelease message to it?

当你发送autorelease消息给一个对象时,它的引用计数会改变吗?

答案:不会

说明:发送autorelease消息后,对象会被加入autorelease pool(自动释放池),这时引用计数是不会改变的。当自动释放池drain的时候,对象会收到relase消息,此时引用计数才会减一。

 

48.What will be printed by the following program, assuming it will run on an architecture with 8 bytes pointers?

以下程序的输出结果?假设我们是运行在一个8字节指针的架构上。

 

#include <stdio.h>
int main( void )
{
    const char foo[] = "Hello";
    const char * bar = " Universe!";
    printf( "%lu\n", sizeof( foo ) + sizeof( bar ) );
    return 0;
}

答案:14

 

说明:foo为数组,sizeof(foo)为6(注意字符串结尾符“\0”),bar为指针,sizeof(bar)为8,6 + 8 = 14。sizeof的时候要注意数组与指针的差别。

49.What does Objective-C not support?

以下选项中哪些是OC不支持的?

答案:Class variables 类变量,Private methods 私有方法,Protected methods 保护方法。

说明:和c++不同,OC不支持类静态成员变量(也就是不支持class variables),通常的做法是在class之外定义静态变量来代替。另外OC中的方法没有公有私有之分,都是公有的。

 

50.What is the C type behind the Objective-C 'id' type, used to represent objects?

OC中的“id”类型实质上是C的什么类型?

答案:structure 结构体

说明:这题涉及的就比较底层了,id类型在objc.h文件中被定义,代码如下:

 

typedef struct objc_class *Class;
typedef struct objc_object {
    Class isa;
} *id;

 

51. What will be printed by the following program?

 

以下程序的输出?

 

#include <stdio.h>
int main( void )
{
    int a    = 31;
    int b    = 10;
    int c    = 3;
    double d =  a / b % c;
    printf( "%f\n", d );
    return 0;
}

答案:0

 

说明:确切的说应该是0.000000

 

52.In the following code, what is the value returned by the last statement?

以下代码最后一条语句的返回值是?

 

#define M( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) )
#define N( x, y, z ) ( M( x, M( y, z ) ) )
N( 1, 2, 3 )

答案:1

 

说明:基础,注意define宏定义时应注意括号的使用。

 

53.Which of the following is false?

以下说法错误的是?

答案:The called object is available as an automatic variable (like self or super) when a method is called.
Methods in static libraries must be present at link time.

说明:真心不太懂这两句话的意思。不知其正确的说法是?

 

54.What happens if two categories define methods with the same names for the same class?

当两个categories(分类)为同一个类定义了同名的方法时会怎样?

答案:Undefined behavior不确定

说明:运行时会随机选择,记住,不要轻易去尝试这种代码!会妨碍你定位bug。

 

55. In the following code, what is the value of "y" after the last statement?

以下代码中,最后一条语句的y值是多少?

 

#define ADD( x ) x + 1
int x = 5;
int y = 10;
y = ADD( x ) * 2;

答案:7

 

说明:基础,define只是简单替换,define定义中注意括号的使用,防止结果与预想的不一致。

 

56.What happen when an exception is thrown in an @synchronized block?

当@synchronized块中有异常抛出时,会发生什么?

答案:对象解锁

说明:@synchronized块的作用一般是多线程编程时给对象上锁,达到互斥的目的,有异常抛出时,对象解锁。

 

57.Is there a memory leak in the following code?

以下代码是否有内存泄露?

 

@interface Foo: NSObject
{
    id object;
}
@property( retain ) __strong id object;
- ( id )initWithObject: ( id )object;
@end
@implementation Foo
@synthesize object;
- ( void )dealloc
{
    [ object release ];
    [ super dealloc ];
}
- ( id )initWithObject: ( id )o
{
    if( ( self = [ self init ] ) )
    {
        self.object = [ o retain ];
    }
    return self;
}
@end

答案:有内存泄露

 

说明:@property的时候设置了retain属性,那么在对象赋值的时候调用系统自动生成的set方法就会retain一次,所以initWithObject中对象o的retain是多余的,这将导致引用计数一直大于0,内存不被释放,造成内存泄露

PS:再次感谢提供该测试地址的 @im_xiaobin 以及提出宝贵建议的 @delo @厉害的小花,还有能抽出时间阅读我这篇技术博客的人们!!!

原文链接:http://blog.csdn.net/xiemotongye/article/details/8922352

posted on 2015-08-15 17:42  绿梦灵逸  阅读(238)  评论(0编辑  收藏  举报