當(dāng)前的答案只是我自己的理解.(標(biāo)題黨來了).
完整答案請(qǐng)找????
題目出處
作者:Cooci_和諧學(xué)習(xí)_不急不躁
鏈接:http://www.reibang.com/p/ec75262fc316
來源:簡(jiǎn)書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)阎曹,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。
一、選擇題(每題5分)
LGTeacher 繼承于 LGPerson, 下面代碼輸出為什么 () 分值5分
LGTeacher *t = [[LGTeacher alloc] init];
- (instancetype)init{
self = [super init];
if (self) {
NSLog(@"%@ - %@",[self class],[super class]);
}
return self;
}
A: LGTeacher - LGTeacher
B: LGTeacher - LGPerson
C: LGTeacher - NSObject
D: LGTeacher - 它愛輸出啥就輸出啥,我不清楚
A [super class] 只是從父類開始找. 接受者還是self
下面代碼能否正常執(zhí)行以及輸出 () 分值5分
@interface LGPerson : NSObject
@property (nonatomic, retain) NSString *kc_name;
- (void)saySomething;
@end
@implementation LGPerson
- (void)saySomething{
NSLog(@"%s - %@",__func__,self.kc_name);
}
@end
- (void)viewDidLoad {
[super viewDidLoad] ;
Class cls = [LGPerson class];
void *kc = &cls;
[(__bridge id)kc saySomething];
}
A: 能 - ViewController
B: 能 - null
C: 能 - ViewController: 0x7ff8d240ad30
D: 能不能自己運(yùn)行一下不就知道,非要問我 - 它愛輸出啥就輸出啥,我不清楚
C 假設(shè)有一個(gè)LGPerson 的實(shí)例對(duì)象的內(nèi)存結(jié)構(gòu)是
isa 8
kc_name 8
第一句獲取到類對(duì)象. 然后 kc = &cls .可以理解為kc 是一個(gè)isa指針指向了LGPerson 的類對(duì)象.
調(diào)用實(shí)例方法.打印kc_name. 也就是 *kc 接下去的8個(gè)字符.所代表的是什么.打印的就是什么. 所以應(yīng)該是C
下面代碼執(zhí)行,控制臺(tái)輸出結(jié)果是什么 () 分值5分
NSObject *objc = [NSObject new];
NSLog(@"a:%ld",CFGetRetainCount((__bridge CFTypeRef)(objc)));
void(^block1)(void) = ^{
NSLog(@"b:%ld",CFGetRetainCount((__bridge CFTypeRef)(objc)));
};
block1();
void(^__weak block2)(void) = ^{
NSLog(@"c:%ld",CFGetRetainCount((__bridge CFTypeRef)(objc)));
};
block2();
void(^block3)(void) = [block2 copy];
block3();
__block NSObject *obj = [NSObject new];
void(^block4)(void) = ^{
NSLog(@"d:%ld",CFGetRetainCount((__bridge CFTypeRef)(obj)));
};
block4();
A: 1 2 2 2 2
B: 1 2 3 3 2
C: 1 3 3 4 1
D: 1 3 4 5 1
答案是D
a是1.
block1 執(zhí)行下面的時(shí)候.
void(^block1)(void) = ^{
NSLog(@"---%ld",CFGetRetainCount((__bridge CFTypeRef)(objc)));
};
//會(huì)生成結(jié)構(gòu)體
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
NSObject *__strong objc; 引用計(jì)數(shù) +1
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, NSObject *__strong _objc, int flags=0) : objc(_objc) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr; // 方法的具體實(shí)現(xiàn)
};
在arc環(huán)境下.會(huì)自動(dòng)給block 進(jìn)行copy 操作.所以 b : 3
block2 執(zhí)行
void(^__weak block2)(void) = ^{
NSLog(@"c:%ld",CFGetRetainCount((__bridge CFTypeRef)(objc)));
};
block2();
跟b一樣.生成strong指針指向objc +1.因?yàn)槭褂胈_weak 修飾.所以不會(huì)自動(dòng)做copy操作. c:4
block3 執(zhí)行
void(^block3)(void) = [block2 copy];
block3();
直接進(jìn)行copy 操作 +1 . c 在打印一次 5
block4 執(zhí)行
__block NSObject *obj = [NSObject new];
void(^block4)(void) = ^{
NSLog(@"d:%ld",CFGetRetainCount((__bridge CFTypeRef)(obj)));
};
block4();
//會(huì)將obj 直接轉(zhuǎn)成block結(jié)構(gòu)體
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__Block_byref_obj_0 *obj; // by ref
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_obj_0 *_obj, int flags=0) : obj(_obj->__forwarding) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
struct __Block_byref_obj_0 {
void *__isa;
__Block_byref_obj_0 *__forwarding;
int __flags;
int __size;
void (*__Block_byref_id_object_copy)(void*, void*);
void (*__Block_byref_id_object_dispose)(void*);
NSObject *__strong obj; //數(shù)據(jù)存儲(chǔ)在這里
};
// main調(diào)用變成
int main(int argc, const char * argv[]) {
//會(huì)將對(duì)象轉(zhuǎn)成block結(jié)構(gòu)體的對(duì)象
__Block_byref_obj_0 obj = {(void*)0,
(__Block_byref_obj_0 *)&obj,
33554432,
sizeof(__Block_byref_obj_0),
__Block_byref_id_object_copy_131,
__Block_byref_id_object_dispose_131,
((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("new"))
};
void(*block4)(void) = &__main_block_impl_0(__main_block_func_0,
&__main_block_desc_0_DATA,
(__Block_byref_obj_0 *)&obj,
570425344));
((__block_impl *))((__block_impl *)block4)->FuncPtr)((__block_impl *)block4);
}
return 0;
}
會(huì)將對(duì)象轉(zhuǎn)成block 的對(duì)象.所以d : 1
下面代碼執(zhí)行,控制臺(tái)輸出結(jié)果是什么 () 分值5分
- (void)MTDemo{
while (self.num < 5) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.num++;
});
}
NSLog(@"KC : %d",self.num);
}
- (void)KSDemo{
for (int i= 0; i<10000; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
self.num++;
});
}
NSLog(@"Cooci : %d",self.num);
}
A: 0 , 10000
B: 0 , <10000
C: <=5 , <10000
D: >=5 , <10000
D
下面代碼執(zhí)行,控制臺(tái)輸出結(jié)果是什么 () 分值5分
- (void)textDemo2{
dispatch_queue_t queue = dispatch_queue_create("cooci", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
- (void)textDemo1{
dispatch_queue_t queue = dispatch_queue_create("cooci", NULL);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
A: 1 5 2 3 4 , 1 5 2
B: 1 5 2 4 3 , 死鎖奔潰
C: 1 5 2 3 4 , 死鎖奔潰
D: 1 5 2 3 , 死鎖奔潰
C 15234 152死鎖
題目問的是終端打印什么 .所以應(yīng)該是A (手動(dòng)捂臉)
下面代碼執(zhí)行,控制臺(tái)輸出結(jié)果是什么 () 分值5分
@property (nonatomic, strong) NSMutableArray *mArray;
- (NSMutableArray *)mArray{
if (!_mArray) _mArray = [NSMutableArray arrayWithCapacity:1];
return _mArray;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
self.mArray = arr;
void (^kcBlock)(void) = ^{
[arr addObject:@"3"];
[self.mArray addObject:@"a"];
NSLog(@"KC %@",arr);
NSLog(@"Cooci: %@",self.mArray);
};
[arr addObject:@"4"];
[self.mArray addObject:@"5"];
arr = nil;
self.mArray = nil;
kcBlock();
}
A: 1 2 4 5 3 , nil
B: 1 2 4 5 3 , a
C: 1 2 4 5 3 , 1 2 4 5 3 a
D: 1 2 4 5 3 a , 1 2 4 5 3 a
B
二、判斷題 (每題5分)
可變數(shù)組線程是安全 () 分值5分
對(duì)
錯(cuò)
錯(cuò)
主隊(duì)列搭配同步函數(shù)就會(huì)產(chǎn)生死鎖 () 分值5分
對(duì)
錯(cuò)
錯(cuò)
下面代碼執(zhí)行不會(huì)報(bào)錯(cuò) () 分值5分
int a = 0;
void(^ __weak weakBlock)(void) = ^{
NSLog(@"-----%d", a);
};
struct _LGBlock *blc = (__bridge struct _LGBlock *)weakBlock;
id __strong strongBlock = [weakBlock copy];
blc->invoke = nil;
void(^strongBlock1)(void) = strongBlock;
strongBlock1();
對(duì)
錯(cuò)
對(duì)
下面代碼執(zhí)行不會(huì)報(bào)錯(cuò) () 分值5分
NSObject *a = [NSObject alloc];
void(^__weak block1)(void) = nil;
{
void(^block2)(void) = ^{
NSLog(@"---%@", a);
};
block1 = block2;
NSLog(@"1 - %@ - %@",block1,block2);
}
block1();
對(duì)
錯(cuò)
錯(cuò).會(huì)報(bào)錯(cuò)
下面代碼會(huì)產(chǎn)生循環(huán)引用 () 分值5分
__weak typeof(self) weakSelf = self;
self.doWork = ^{
__strong typeof(self) strongSelf = weakSelf;
weakSelf.doStudent = ^{
NSLog(@"%@", strongSelf);
};
weakSelf.doStudent();
};
self.doWork();
對(duì)
錯(cuò)
會(huì)產(chǎn)生循環(huán)引用
下面代碼是否有問題 () 分值5分
- (void)demo3{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(0, 0);
for (int i = 0; i<5000; i++) {
dispatch_async(concurrentQueue, ^{
NSString *imageName = [NSString stringWithFormat:@"%d.jpg", (i % 10)];
NSURL *url = [[NSBundle mainBundle] URLForResource:imageName withExtension:nil];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
dispatch_barrier_async(concurrentQueue, ^{
[self.mArray addObject:image];
});
});
}
}
對(duì)
錯(cuò)
對(duì).有問題.
dispatch_barrier_async 沒有效果.在全局并發(fā)隊(duì)列 barrier 無法生效
下面代碼不會(huì)產(chǎn)生循環(huán)引用 () 分值5分
static ViewController *staticSelf_;
- (void)blockWeak_static {
__weak typeof(self) weakSelf = self;
staticSelf_ = weakSelf;
}
對(duì)
錯(cuò)
不會(huì)
三庵楷、簡(jiǎn)單題 (每題 10分 合計(jì) 120分)
請(qǐng)把它當(dāng)成一場(chǎng)面試,認(rèn)真對(duì)待 希望大家耐心 切忌浮躁 (和諧學(xué)習(xí) 不急不躁)
1蛇捌、請(qǐng)用GCD實(shí)現(xiàn)讀寫鎖 , 解釋為什么這么設(shè)計(jì) 分值10分
其實(shí)就是多讀單寫.使用自己創(chuàng)建的并發(fā)隊(duì)列.然后使用barrier進(jìn)行寫入的操作.就好.
2、@synchronized 為什么應(yīng)用頻次最多 分值10分
最根本原因肯定是因?yàn)閷懛ê?jiǎn)單粗暴.
本質(zhì)是一個(gè)遞歸鎖.
3滚婉、block 的種類有幾種 是符合區(qū)分的? 分值10分
global 全局
malloc 堆
stack 棧
4、KVC 普通對(duì)象 setter 過程 分值10分
5帅刀、KVO 底層原理機(jī)制分析 分值10分
創(chuàng)建當(dāng)前類的子類.然后將當(dāng)前類的isa 指向子類.重寫監(jiān)聽的對(duì)象的set 方法
willchanggevalueforkey
super set
didchangevalueforkey
6让腹、下面代碼的棧幀入棧情況是什么的? 分值10分
- (void)viewDidLoad {
[super viewDidLoad] ;
Class cls = [LGPersonP class];
void *kc = &cls;
[(__bridge id)kc saySomething];
LGPersonP *person = [LGPersonP alloc];
}
- LGPersonP
- Viewcontroller : 內(nèi)存地址
- 其他接下去的地址
7、iOS 線程如何笨勰纾活, 為什么要線程焙希活 分值10分
線程如何保活.通過給runloop 添加source0/source1/timer/observer 都可以.一般的做法就是給source1添加一個(gè)port.然后在當(dāng)前線程進(jìn)行run.
為什么線程弊队啵活: 主要是考慮業(yè)務(wù)上的問題.用空間換時(shí)間.比如網(wǎng)絡(luò)請(qǐng)求.可能需要頻繁的進(jìn)行網(wǎng)絡(luò)請(qǐng)求.這時(shí)候.我們創(chuàng)建一個(gè)子線程.然后需要用的時(shí)候.直接調(diào)用就行
8腹纳、循環(huán)引用,為什么要在block中加strong,不加會(huì)怎樣 分值10分
保證在block運(yùn)行的時(shí)候.內(nèi)部的對(duì)象不要釋放
9、你使用過 dispatch_once 嗎驱犹?了解底層嗎嘲恍?讓你實(shí)現(xiàn)一個(gè)應(yīng)該怎么操作? 分值10分
10雄驹、iOS 多線程原理和線程生命周期是什么樣的 分值10分
11佃牛、請(qǐng)簡(jiǎn)述信號(hào)量和調(diào)度組的原理 分值10分
12、請(qǐng)簡(jiǎn)述 __block 修飾變量被 block 捕獲之后的情況 分值10分
被__block修飾的對(duì)象.最后本質(zhì)會(huì)變成一個(gè)X_block_impl_X結(jié)構(gòu)體.
四医舆、拓展?jié)M分題 (15分)
作為一名iOS中高級(jí)開發(fā)人員, 你的加分項(xiàng)和優(yōu)勢(shì)是什么?
略