转载

南京JingDong笔试题

序言

今天在微博上有一小伙伴说去京东面试了一下下,答得不如意,希望笔者能提供更详细的参考答案。出于笔者未挑战过京东的笔试题,自然也想看看究竟有多难。那么,本篇文章就有笔者针对题目给出笔者的参考答案,不具有答案代表性,只具备一定的参考价值。

题照

南京JingDong笔试题

1、请写出以下代码输出

  int a[5] = {1, 2, 3, 4, 5}; int *ptr = (int *)(&a + 1); printf("%d, %d", *(a + 1), *(ptr + 1));   

参考答案:2, 随机值

这种类型题好像挺常见的。考的就是C语言上的指针的理解和数组的理解。

分析:

a代表有5个元素的数组的首地址,a[5]的元素分别是1,2,3,4,5。接下来,a + 1表示数据首地址加1,那么就是a[1],也就是对应于值为2.但是,这里是&a + 1,因为a代表的是整个数组,它的空间大小为5 * sizeof(int),因此&a + 1就是a+5。a是个常量指针,指向当前数组的首地址,指针+1就是移动sizeof(int)个字节。

因此,ptr是指向int *类型的指针,而ptr指向的就是a + 5,那么ptr + 1也相当于a + 6,所以最后的*(ptr + 1)就是一个随机值了。而*(ptr – 1)就相当于a + 4,对应的值就是5。

2、写一个标准宏Max,并给出以下代码的输出

  int array[5] = {1, 2, 3, 4, 5}; int *p = &array[0]; int max = Max(*p++, 1); printf("%d %d", max, *p);   

参考答案: 1,2

  #define Max(X, Y) ((X) > (Y) ? (X) : (Y))   

当看到宏时,就会想到宏定义所带来的副作用。对于++、–,在宏当中使用是最容易产生副作用的,因此要慎用。

分析:

p指针指向了数组array的首地址,也就是第一个元素对应的地址,其值为1.

宏定义时一定要注意每个地方要加上圆括号

*p++相当于*p, p++,所以Max(*p++, 1)相当于:

  (*p++) > (1) ? (*p++) : (1)   =>   (1) > (1) ? (*p++) : (1)   =>   第一个*p++的结果是,p所指向的值变成了2,但是1 > 1为値,所以最终max的值就是1。而后面的(*p++)也就不会执行,因此p所指向的地址对应的值就是2,而不是3.   

扩展:如果上面的*p++改成*(++p)如何?

分析:

  (*++p) > (1) ? (*++p) : (1)   =>   (2) > (1) ? (*++p) : (1)   =>   max = *++p;   =>    *p = 3,max = 3;   

3、在一个对象的方法里:self.name=@ object ;和name=@ object 有什么不同

参考答案:

这是老生常谈的话题了,实质上就是问setter方法赋值与成员变量赋值有什么不同。通过点语法self.name实质上就是[self setName:@ object ];。而name这里是成员变量,直接赋值。

一般来说,在对象的方法里成员变量和方法都是可以访问的,我们通常会重写Setter方法来执行某些额外的工作。比如说,外部传一个模型过来,那么我会直接重写Setter方法,当模型传过来时,也就是意味着数据发生了变化,那么视图也需要更新显示,则在赋值新模型的同时也去刷新UI。这样也不用再额外提供其他方法了。

4、怎样使用performSelector传入3个以上参数,其中一个为结构体

参考答案:

  - (id)performSelector:(SEL)aSelector; - (id)performSelector:(SEL)aSelectorwithObject:(id)object; - (id)performSelector:(SEL)aSelectorwithObject:(id)object1withObject:(id)object2;   

因为系统提供的performSelector的api中,并没有提供三个参数。因此,我们只能传数组或者字典,但是数组或者字典只有存入对象类型,而结构体并不是对象类型,那么怎么办呢?

没有办法,我们只能通过对象放入结构作为属性来传过去了:

  typedef struct HYBStruct {   int a;   int b; } *my_struct;   @interfaceHYBObject: NSObject   @property (nonatomic, assign) my_structarg3; @property (nonatomic, copy)  NSString *arg1; @property (nonatomic, copy) NSString *arg2;   @end   @implementation HYBObject   // 在堆上分配的内存,我们要手动释放掉 - (void)dealloc {   free(self.arg3); }   @end   

测试:

  my_structstr = (my_struct)(malloc(sizeof(my_struct))); str->a = 1; str->b = 2; HYBObject *obj = [[HYBObject alloc]init]; obj.arg1 = @"arg1"; obj.arg2 = @"arg2"; obj.arg3 = str;   [selfperformSelector:@selector(call:)withObject:obj];    // 在回调时得到正确的数据的 - (void)call:(HYBObject *)obj {     NSLog(@"%d %d", obj.arg3->a, obj.arg3->b); }   

5、UITableViewCell上有个UILabel,显示NSTimer实现的秒表时间,手指滚动cell过程中,label是否刷新,为什么?

参考答案:

这是否刷新取决于timer加入到Run Loop中的Mode是什么。Mode主要是用来指定事件在运行循环中的优先级的,分为:

  • NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
  • UITrackingRunLoopMode:ScrollView滑动时会切换到该Mode
  • UIInitializationRunLoopMode:run loop启动时,会切换到该mode
  • NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合

苹果公开提供的Mode有两个:

  • NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
  • NSRunLoopCommonModes(kCFRunLoopCommonModes)

如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。当我们滚动的时候,也希望不调度,那就应该使用默认模式。但是,如果希望在滚动时,定时器也要回调,那就应该使用common mode。

对于这道题,如果要cell滚动过程中定时器正常回调,UI正常刷新,那么要将timer放入到CommonModes下,因为是NSDefaultRunLoopMode,只有在空闲状态下才会回调。

6、有a、b、c、d 4个异步请求,如何判断a、b、c、d都完成执行?如果需要a、b、c、d顺序执行,该如何实现?

参考答案:

  1. 对于这四个异步请求,要判断都执行完成最简单的方式就是通过GCD的group来实现:
  dispatch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_tgroup = dispatch_group_create(); dispatch_group_async(group, queue, ^{ /*任务a */ }); dispatch_group_async(group, queue, ^{ /*任务b */ }); dispatch_group_async(group, queue, ^{ /*任务c */ });  dispatch_group_async(group, queue, ^{ /*任务d */ });    dispatch_group_notify(group, dispatch_get_main_queue(), ^{     // 在a、b、c、d异步执行完成后,会回调这里 });   

当然,我们还可以使用非常老套的方法来处理,通过四个变量来标识a、b、c、d四个任务是否完成,然后在runloop中让其等待,当完成时才退出run loop。但是这样做会让后面的代码得不到执行,直到Run loop执行完毕。

  1. 要求顺序执行,那么可以将任务放到串行队列中,自然就是按顺序来异步执行了。

7、使用block有什么好处?使用NSTimer写出一个使用block显示(在UILabel上)秒表的代码。

参考答案:

说到block的好处,最直接的就是代码紧凑,传值、回调都很方便,省去了写代理的很多代码。

对于这里根本没有必要使用block来刷新UILabel显示,因为都是直接赋值。当然,笔者觉得这是在考验应聘者如何将NSTimer写成一个通用用的Block版本。

代码放到了这里:NSTimer封装成Block版

使用起来像这样:

  NSTimer *timer = [NSTimerscheduledTimerWithTimeInterval:1.0                                     repeats:YES                                    callback:^() {   weakSelf.secondsLabel.text = ... } [[NSRunLoop currentRunLoop]addTimer:timerforMode:NSRunLoopCommonModes];   

8、一个view已经初始化完毕,view上面添加了n个button(可能使用循环创建),除用view的tag之外,还可以采用什么办法来找到自己想要的button来修改Button的值

参考答案:

这个问题有很多种方式,而且不同的使用场景也不一样的。比如说:

  • 第一种:如果是点击某个按钮后,才会刷新它的值,其它不用修改,那么不用引用任何按钮,直接在回调时,就已经将接收响应的按钮给传过来了,直接通过它修改即可。
  • 第二种:点击某个按钮后,所有与之同类型的按钮都要修改值,那么可以通过在创建按钮时将按钮存入到数组中,在需要的时候遍历查找。

9、tableview在滑动时,有时候会大量加载本地图片,这时候会很卡,如何解决加载耗时过长导致不流畅的问题

参考答案:

这是优化tableview的相关专题,如果只是处理图片加载问题,那可以通过异步读取图片然后刷新UI。当然,我们也可以在取数据时,在模型中提前准备好需要显示的图片资源,这样在cell只就不需要操作图片读取,而是直接显示。

如果想要更深入地优化,学习以下知识点:

  • Offscreen-Rendered
  • Color Misaligned Images
  • Color Blended Layers

10、给定一个如下的字符串(1,(2,3),(4,(5,6)7))括号内的元素可以是数字,也可以是括号,请实现一个算法清除嵌套的括号,比如把上面的表达式的变成:(1,2,3,4,5,6,7),表达式有误时请报错。

参考答案:

如果只是判断整个表达式是否有错误,然后去掉里面的圆括号,那么一个循环就可以了。不过我们只需要加两个变量分别来记录左圆括号和右圆括号的个数。这里假设逗号总是正确的情况下,伪代码如下:

  left = 0; rigt = 0;   for i = 0; i < str.length; ++i {   if 是左括号 {     left++;     continue;   }      if 是右括号 {     right++;          // 处理(1,)这样的结构     if 前一个是逗号 {         error;     }          continue;   }      [newStrappend:str[i]]; }   if left != right {   error; }   

这里只能提供一种参考,大家根据自己的想法尝试去实现一下,然后再评论中回复即可。

最后

从这里看,似乎JingDong更偏向C语言的笔试题,所以大家还是要好好准备准备好C语言的基础知识。本篇文章所提供的所有参考答案均是笔者个人想法,请大家发现有什么不对的地方时,及时评论。

推荐阅读

这里是面试、笔试题的收集整理的总入口,这里提供了所有的参考答案,持续更新!

  • iOS面试宝典

关注我

关注 账号 备注
标哥博客iOS交流群一 324400294(满) 群一若已满,请申请群二
标哥博客iOS交流群二 494669518(满) 群二若已满,请申请群三
标哥博客iOS交流群三 461252383(满) 群三若已满,请申请群四
标哥博客iOS交流群四 250351140 群四若已满,会有提示信息
关注微信公众号 iOSDevShares 关注微信公众号,会定期地推送好文章
关注新浪微博账号 标哥的技术博客 关注微博,每次发布文章都会分享到新浪微博
关注标哥的GitHub CoderJackyHuang 这里有很多的Demo和开源组件
关于我 进一步了解标哥 如果觉得文章对您很有帮助,可捐助我!
原文  http://www.henishuo.com/nanjing-jingdong-interview/
正文到此结束
Loading...