af银联招聘面试经验完一般多久通知

您当前的位置:&>&&>&
现将邹城市2017年邹城市事业单位公开招聘面试入围人员名单及有关事项公告如下:
一、确定面试入围人员
面试入围人员根据招聘岗位计划的3倍,按照有效笔试总成绩由高分到低分依次确定。笔试总成绩相同且同时达到招聘计划3倍的报考人员,同时确定为该职位面试入围人员(不区分名次先后);笔试人数不足招聘计划3倍的,按实有人数确定面试人选。各招聘岗位面试入围人员名单见附件。
二、面试入围人员资格审查
面试入围人员资格审查同时发放《面试通知书》,具体要求及时间、地点另行通知,请保持通讯方式畅通。
三、面试人选递补
因资格审查不合格等原因取消面试资格需要递补的,将按该职位有效笔试总成绩依次递补。有关考生在此期间应当保持通讯方式畅通,以免给个人造成损失。
2017年邹城市事业单位公开招聘面试入围人员名单(公开发布).xls
&(234.00 KB)
免责申明:本站部分内容来自网络,如有侵权请来信告知,我们将在第一时间内删除
版权所有:中共邹城市委对外宣传办公室
联系电话: Email:
版权所有 严禁转载 鲁ICP备号IOS面试 - 简书
字数 10235
(一)1.简述你对协议的理解:
a想做一件事却因为一些原因不能做,于是让b遵循a的一些约定,这样b就可以帮助a做事了。协议中包括了遵循方b需要实现的一些方法,以及b能够做的事情。
2.如何理解ARC自动引用计数机制:
ARC--自动引用计数
可以用来管理对象的使用以及了解对象的使用情况,当对象引用计数不为0时,对象不会被释放,当对象引用计数为0时
dealloc函数被调用 对象将会被释放。
3.如何理解retain/copy/assign/release/autorelease/dealloc关键字:
retain让对象引用计数加1,release让对象引用计数减1,当对象引用计数为0时会调用dealloc 将对象进行释放。copy是你不想让a和b共享一块内存时候,让a和b有各自的内存。在使用基本数据类型的时候需要使用assgin,assgin是直接赋值,会引起对象引用计数加1.
(1)assign:普通赋值,一般用于基本数据类型,防止循环引用。
(2)retain:保留计数,获得用户的所有权。
(3)copy:用来赋值对象,一般字符串使用copy,Foundation中的不可变对象使用copy效果相当于retain,只是引用计数+1.
(4)nonatomic:非原子性访问,不加同步,多线程并发访问会提高性能。
4.请简述类别和继承有什么联系和区别 以及weak和assgin的区别:
类别和继承 都会使用父类的中原有的方法和属性,类别是对父类进行扩展,继承是将父类中的属性、方法等保留下来,根据自己的实际情况进行实现。
weak用于各种UI控件和代理,assgin用于基本数据类型。
继承可以增加,修改,删除方法,还可以增加属性;
category只能添加属性;
@property (nonatomic, strong) NSString *string1;
@property (nonatomic, strong) NSString *string2;
self.string1 = @"String 1";
self.string2 = self.string1;
self.string1 =
NSLog(@"String 2 = %@", self.string2);
结果是:String 2 = String 1由于string2是strong定义的属性,所以引用计数+1,使得它们所指向的值都是@"String 1"
@property (nonatomic, strong) NSString *string1;
@property (nonatomic, weak) NSString *string2;
self.string1 = @"String 1";
self.string2 = self.string1;
self.string1 =
NSLog(@"String 2 = %@", self.string2);
结果是:String 2 = null
分析一下,由于self.string1与self.string2指向同一地址,且string2没有retain内存地址,而self.string1=nil释放了内存,所以string1为nil。声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。
5.请简述你对strong和weak关键字的理解 以及_unsafe_unretained与weak的区别:
strong相当于retain
让对象引用计数加1,防止对象在异常情况下被提前释放,导致crash。weak
弱引用防止产生循环应用无法释放对象和产生野指针。
strong叫做强引用,在ARC中使用strong告诉编译器帮组我们自动插入retain,weak是普通赋值相当于手动管理内存的assign。_unsafe_unretained与weak功能一致,区别在于当指向的对象销毁后,weak会将变量重置为nil,防止调用野指针,产生EXC_BAD_ACCESS这类的错误。
6.如何实现ARC和MRC的混合编程:
在targets的build phases选项下Compile Sources下选择要使用arc编译的文件:  在targets的build phases选项下Compile Sources下选择要不使用arc编译的文件, 就会出报错。方法如下,双击它 输入 -fno-objc-arc 即可。如果在ARC 工程中 加MRC
加 -fno-objc-arc
如果在MRC 工程中 加 ARC
加 -fobjc-arc
7.Objective-C是否支持多继承:
不支持多继承 因为消息机制名字查找发生在运行时而非编译时,很难解决多个基类可能导致的二义性问题
。可以通过消息转发
类别实现与多继承相似的功能。
8.Objective-C中变量默认是私有的么?方法默认是私有的么?
变量默认是private,方法默认是public。
9.#import"".h 和@class+类名的区别:
import"".h为导入头文件,@class+类名 为前向引用申明。
1.import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑,后面会再告诉你。2.在头文件中, 一般只需要知道被引用的类的名称就可以了。 不需要知道其内部的实体变量和方法,所以在头文件中一般使用@class来声明这个名称是类的名称。 而在实现类里面,因为会用到这个引用类的内部的实体变量和方法,所以需要使用#import来包含这个被引用类的头文件。3.在编译效率方面考虑,如果你有100个头文件都#import了同一个头文件,或者这些文件是依次引用的,如A–&B, B–&C, C–&D这样的引用关系。当最开始的那个头文件有变化的话,后面所有引用它的类都需要重新编译,如果你的类有很多的话,这将耗费大量的时间。而是用@class则不会。4.如果有循环依赖关系,如:A–&B, B–&A这样的相互依赖关系,如果使用#import来相互包含,那么就会出现编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现。所以,一般来说,@class是放在interface中的,只是为了在interface中引用这个类,把这个类作为一个类型来用的。 在实现这个接口的实现类中,如果需要引用这个类的实体变量或者方法之类的,还是需要import在@class中声明的类进来.
10.请简述页面传值都有哪些实现方法:
Block、 委托协议、 通知、 单例、NSUserDefaults
11.请简述深拷贝和浅拷贝的区别:
深拷贝会重新在堆上开辟一块内存空间 是一个全新的对象
指针地址和原来不一样
浅拷贝不会重新开辟一块内存空间
指针和原来是一样的。深拷贝和浅拷贝的本质是地址相同,就是浅拷贝,地址不同就是深拷贝。 浅拷贝是拷贝操作后,并没有进行真正的复制,而是另一个指针也指向了同一个地址。深拷贝操作后,是真正的复制了一份,另一个指针指向了拷贝后的地址。
浅拷贝:在复制操作时,对于被复制的对象的每一层复制都是指针复制。
深拷贝:在复制操作时,对于被复制的对象至少有一层复制是对象复制。
完全复制:在复制操作时,对于被复制的对象的每一层复制都是对象复制。
浅拷贝好比你的影子,你没了,你的影子也没有了;
深拷贝好比你的克隆人,你没了,你的克隆人还在 ;
备注:retain:始终是浅复制。引用计数每次加一。返回对象是否可变与被复制的对象保持一致。copy:对于可变对象为深复制,引用计数不改变;对于不可变对象是浅复制,引用计数每次加一。始终返回一个不可变对象。mutableCopy:始终是深复制,引用计数不改变。始终返回一个可变对象。不可变对象:值发生改变,其内存首地址随之改变。可变对象:无论值是否改变,其内存首地址都不随之改变。引用计数:为了让使用者清楚的知道,该对象有多少个拥有者(即有多少个指针指向同一内存地址)。
12.系统中有哪些对象是单例:
NSTimer、NSNotification、UIWindow、UIApplication自己写单例需要注意:不使用GCD:
// 单例模式实现要点:
// 1. 废掉构造方法(调用的时候抛出异常)
// 2. 提供一个类方法向外界返回该类的唯一实例
- (instancetype)init {
@throw [NSException exceptionWithName:@"CDSingleton" reason:@"不允许调用构造方法" userInfo:nil];
// 此方法由于没有在.h文件中暴露接口相当于是私有方法
- (instancetype) initPrivate {
if(self = [super init]) {
_value = arc4random();
+ (instancetype) sharedInstance {
// static类型的变量拥有全局的生命周期
static CDSingleton *instance =
// 使用同步块保证在多线程环境下仍然是单例
//同步加锁,在多线程中使用,可以使线程安全
@synchronized(self) {
if(!instance) {
instance = [[self alloc] initPrivate];
+(instancetype)sharedInstance{
static HCDSingleton *singleton =
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
singleton = [[HCDSingleton alloc]init];
13.简述你对MVC设计模式的理解:
View - Controller
模型负责数据任务
试图负责呈现 以及和用于进行交互
控制器用来控制试图
model 模型:主要负责存储和操作数据
view 视图:主要负责展?示数据和?用户交互
controller 主要负责将model和view联系起来:
从网络获取数据-&赋值给数据模型-&将model的数据传递给view展?示(响应view的delegate和datasource?方法)-&刷新view
14.IOS中那些技术符合观察者模式:
Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。每次指定的被观察的对象的属性被修改后,KVO自动通知相应的观察者。
model中定义:
@interface StockData : NSObject { NSString * stockN}
@implementation StockData
controller中使用,这里相当于跟模型说,我要收听你的更新广播
- (void)viewDidLoad{
[super viewDidLoad];
stockForKVO = [[StockData alloc] init];
[stockForKVO setValue:@"searph" forKey:@"stockName"];
[stockForKVO setValue:@"10.0" forKey:@"price"];
[stockForKVO addObserver:self forKeyPath:@"price" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
myLabel = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 100, 30 )];
myLabel.textColor = [UIColor redColor];
myLabel.text = [stockForKVO valueForKey:@"price"];
[self.view addSubview:myLabel];
UIButton * b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
b.frame = CGRectMake(0, 0, 100, 30);
[b addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:b];
用户单击View中的button调用控制器中的action去更改模型中的数据
-(void) buttonAction{
[stockForKVO setValue:@"20.0" forKey:@"price"];
控制器需要实现的回调,相当于收到广播后我应该做啥事
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
if([keyPath isEqualToString:@"price"])
myLabel.text = [stockForKVO valueForKey:@"price"];
注意使用通知和KVO一定要记着移除,否则会导致crash
视图dealloc需要取消观察
- (void)dealloc{
[super dealloc];
[stockForKVO removeObserver:self forKeyPath:@"price"]; [stockForKVO release];
15.简述你对工厂方法的理解:
创建对象的时候,我们一般是alloc一个对象,如果需要创建100个这样的对象,如果是在一个for循环中还好说,直接一句alloc就行了,但是事实并不那么如意,我们可能会在不同的地方去创建这个对象,那么我们可能需要写100句alloc 了,但是如果我们在创建对象的时候,需要在这些对象创建完之后,为它的一个属性添加一个固定的值,比方说都是某某学校的学生,那么可能有需要多些100行重复的代码了,那么,如果写一个-(void)createObj方法,把创建对象和学校属性写在这个方法里边,那么就是会省事很多,也就是说我们可以alloc 创建对象封装到一个方法里边,直接调用这个方法就可以了,这就是简单工厂方法。
16.什么是代理模式,实现代理需要注意什么:
代理模式:帮助别人完成别人委托你完成的事情。你需要注意遵守别人给你定的约定,和你是否拥有完成这件事的能力。
17.简述StoryBoard和Xib的联系和区别:
StoryBoard可以在上面实现整个项目界面的搭建,可以清楚得看到各个试图控制器之间的关系,XIB实现自定义要素和良好部件重用性复杂的UI。
18.请简述UITableView对CELL的重用机制:
比如一个屏幕可以放下5个UITableViewCell
总共会创建6个
设置CELL的重用标志符
一旦可以重用就重用
不能重用再创建,减少内存的消耗。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"healthNewsTableViewCell";
healthNewsTableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = (healthNewsTableViewCell*)[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier: @"healthNewsTableViewCell"];
//再将数据绑定写在WillDisPlayCell中
//让UITableView稍微顺滑点的方法
在显示cell前被调用
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
healthNewsTableViewCell *MyCell = (healthNewsTableViewCell *)
MyCell.model = dataArray[indexPath.row];
MyCell.backgroundColor = [UIColor colorWithRed:0.936 green:0.941 blue:0.936 alpha:1.000];
19.如何使用UIScrollView实现无限加载多张图片:
写一个NSTimer
执行以下回调方法changPic
如果图片数量有限
进行一个if判断
当超过图片总数时候,显示第一张,重新开始从第一张显示。
20.请简述试图控制器的生命周期:
当一个视图控制器被创建,并在屏幕上显示的时候。 代码的执行顺序
创建对象,分配空间2、init (initWithNibName) 初始化对象,初始化数据3、loadView
从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图4、viewDidLoad
载入完成,可以进行自定义数据以及动态创建其他控件5、viewWillAppear
视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了6、viewDidAppear
视图已在屏幕上渲染完成
当一个视图被移除屏幕并且销毁的时候的执行顺序,这个顺序差不多和上面的相反
1、viewWillDisappear
视图将被从屏幕上移除之前执行2、viewDidDisappear
视图已经被从屏幕上移除,用户看不到这个视图了3、dealloc
视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放
21.UITableView有哪些优化方式:
1.图片使用异步加载如SDWebImage。2.使用重用标识符reuseIdentifier,将重用标识标示符static NSString *CellIdentifier = @"XXX";3.将数据绑定写在WillDisPlay这个协议方法中。4.尽量在CELL中少使用不透明的View。5.如果不是必须,减少使用reloadData全部cell。
22.简述IOS中的事件传递机制:
举例:如果view是控制器的view,就传递给控制器;如不是,则将其传递给它的父视图 在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理 如果window对象也不处理,则其将事件或消息传递给UIApplication对象 如果UIApplication也不能处理该事件或消息,则将其丢弃
注意:为什么用队列管理事件,而不用栈?
队列先进先出,能保证先产生的事件先处理。栈先进后出。
23.UITableView有哪些必须要实现的数据源方法:
// 获得section包含的cell个数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)
//创建UITableViewCell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexP
//看情况实现的数据源方法:
//TableView中分组数目
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableV
//分组头的标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)
//分组尾的标题
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)
个人习惯在此方法中实现给模型绑定数据
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
24.简述Http协议中get请求和post请求的区别:
get 是从服务器获取数据
,post是向服务器发送数据
GET安全性较低,POST安全性较高。因为GET在传输过程,数据被放在请求的URL中,而如今现有的很多服务器、代理服务器或者用户代理都会将请求URL记录到日志文件中,然后放在某个地方,这样就可能会有一些隐私的信息被第三方看到。另外,用户也可以在浏览器上直接看到提交的数据,一些系统内部消息将会一同显示在用户面前。POST的所有操作对用户来说都是不可见的。
GET请求,将参数直接写在访问路径上。操作简单,不过容易被外界看到,安全性不高,地址最多255字节;POST请求,将参数放到body里面。POST请求操作相对复杂,需要将参数和地址分开,不过安全性高,参数放在body里面,不易被捕获。
25.简述你对异步请求数据的理解:
更好的用户体验:
减少卡顿 假死的现象。因为异步请求数据 不会一直等待某个任务完成才执行另外一个任务,可以执行其他的操作。
26.IOS中有哪些技术可以实现开辟线程,他们之间有什么联系:由一个单例方法的实现推出多线程使用:
第一种,使用@synchronized(self)
static LocationController *sharedI
+ (LocationController *)sharedInstance {
@synchronized(self)//使用一个同步保护 保证一个线程使用时,其他线程无法进入。
if (!sharedInstance)
sharedInstance=[[LocationController alloc] init];
return sharedI
第二种,使用GCD(Grand Central Dispatch:宏中心派发)
当你调用dispatch_async,你通过一个dispatch队列,在这个队列上存有很多block,先进先出,依次执行。
这个队列可以使用dispatch_create自己创建,也可以调用主线程队列dispatch_get_main_queue。
这里建立的队列名称是onceToken。
static LocationController *sharedI
+ (LocationController *)sharedInstance {
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
if (!sharedInstance)
sharedInstance = [[self alloc] init];
return sharedI
第三种,使用NSOperationQueue
static LocationController *sharedI
+ (LocationController *)sharedInstance {
NSOperationQueue *onceToken=[[NSOperationQueue alloc] init];
[onceToken addOperationWithBlock:^(){
if (!sharedInstance)
sharedInstance = [[self alloc] init];
return sharedI
正式列举实现单例的常用的3种方法:
创建方式主要有两种://下面为两种NSThread的创建方法:
[NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];
NSThread* myThread = [[NSThread alloc] initWithTarget:selfselector:@selector(myThreadMainMethod:)object:nil];
[myThread start]; //启动线程
这两种方式的区别是:前一种一调用就会立即创建一个线程来做事情;而后一种虽然你 alloc 了也 init了,但是要直到我们手动调用 start 启动线程时才会真正去创建线程。这种延迟实现思想在很多跟资源相关的地方都有用到。后一种方式我们还可以在启动线程之前,对线程进行配置,比如设置 stack 大小,线程优先级。此外还有一种间接的方式:利用NSObject的方法performSelectorInBackground:withObject: 来创建一个线程:[myObj performSelectorInBackground:@selector(myThreadMainMethod) withObject:nil];
//在后台运行某一个方法其效果与 NSThread 的 detachNewThreadSelector:toTarget:withObject: 是一样的。
NSOperationQueue (操作队列)
@interface ViewController () {
// 操作队列
NSOperationQueue *
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 并发队列(队列中的操作会并发执行)
queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 5;
for (int i = 0; i & 5; i++) {
CDCar *myCar = [[CDCar alloc] initWithX:20 + 70 * i andY:10];
[myCar draw:self.view];
NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{
[myCar run];
[queue addOperation:op];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 耗时的操作
比如网络数据数据请求
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
27.NSThread中线程是如何实现通信的:28.GCD中有哪些创建线程的方式:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 耗时的操作
比如网络数据数据请求
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
29.IOS中哪些技术可以保证线程的安全:
1.使用互斥锁
互斥锁使用格式
@synchronized(锁对象)
// 需要锁定的代码
注意:锁定1份代码只用1把锁,用多把锁是无效的
互斥锁的优缺点优点:能有效防止因多线程抢夺资源造成的数据安全问题缺点:需要消耗大量的CPU资源互斥锁的使用前提:多条线程抢夺同一块资源相关专业术语:线程同步,多条线程按顺序地执行任务互斥锁,就是使用了线程同步技术
OC在定义属性时有nonatomic和atomic两种选择atomic:原子属性,为setter方法加锁(默认就是atomic)nonatomic:非原子属性,不会为setter方法加锁
@property (assign, atomic)
- (void)setAge:(int)
@synchronized(self)
原子和非原子属性的选择nonatomic和atomic对比atomic:线程安全,需要消耗大量的资源nonatomic:非线程安全,适合内存小的移动设备
30.ASIHttpRequest的父类是什么:
ASIHTTPRequest是一款极其强劲的HTTP访问开源项目。让简单的API完成复杂的功能,如:异步请求,队列请求,GZIP压缩,缓存,断点续传,进度跟踪,上传文件,HTTP认证。
它是NSOperationQueues的扩展,小而强大。
但也与它的父类略有区别。
如,仅添加到队列中其实并不能执行请求,只有调用[queue go]才会执行;
一个正在运行中的队列,并不需要重复调用[queue go ]。
默认情况下,队列中的一个请求如果失败,它会取消所有未完成的请求。
可以设置[queue setShouldCancel];
31.简述AFNetWork的实现原理:
AFNetwork是一个轻量级的网络请求api类库。是以NSURLConnection, NSOperation和其他方法为基础的。
AFNewWork的基本使用://创建一个下载任务NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"/download.zip"];NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
NSLog(@"File downloaded to: %@", filePath);
[downloadTask resume];
//创建一个上传任务NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"/upload"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
NSLog(@"Success: %@ %@", response, responseObject); }
[uploadTask resume];
//带进度的上传任务NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"/upload" parameters:nil constructingBodyWithBlock:^(id&AFMultipartFormData& formData) {
[formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil];
} error:nil];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionUploadTask *uploadT
uploadTask = [manager uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) {
// This is not called back on the main queue. // You are responsible for dispatching to the main queue for UI updates dispatch_async(dispatch_get_main_queue(), ^{
//Update the progress view
[progressView setProgress:uploadProgress.fractionCompleted];
}); } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (error) {
NSLog(@"Error: %@", error);
NSLog(@"%@ %@", response, responseObject);
[uploadTask resume];
//请求数据的任务NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:@"http://httpbin.org/get"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
NSLog(@"%@ %@", response, responseObject);
[dataTask resume];
32.如何理解Block,block有什么用途:
void (^block)() = ^(){};//实质就是保存一段代码
typedef void (^Block)();
@property (strong,nonatomic) Block
Block是没有名字的匿名函数,类似于C语言中的函数指针。
可以用于页面间传值
进行回调...举例://第二个页面:
// 定义Block类型的属性(用来保存一段回调代码)
// 属性修饰符必须写copy因为要从栈将Block拷贝到堆上
@property (nonatomic, copy) void(^myBlock)(NSString *);
- (IBAction)buttonClicked:(id)sender {
if (_myBlock) {
// 调用Block 语法跟调用C函数是一致的
_myBlock([NSString stringWithFormat:@"你好, %@", _nameField.text]);
[self dismissViewControllerAnimated:YES completion:^{
NSLog(@"回到第一个视图控制器!!!");
//第一个页面
(接收页面)
- (IBAction)buttonClicked:(UIButton *)sender {
CDSecondViewController *secondVC = [[CDSecondViewController alloc] init];
// 给第二个视图控制器的Block变量赋值
secondVC.myBlock = ^(NSString *str) {
_myLabel.text =
[self presentViewController:secondVC animated:YES completion:^{
// NSLog(@"搞定第二个视图控制器!!!");
具体使用block:
#import "ViewController.h"
typedef void (^otherBlock) ();
typedef void(^ResultBlock)(BOOL suc,NSString *plat,NSString *info);
@interface ViewController ()
//属性定义block
@property (nonatomic,copy) void(^someBlock)();
//alias定义block
@property (nonatomic,copy) otherBlock oB
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
-(void)getDataFromServerWithResult:(otherBlock)oBlock{
-(void)getData:(ResultBlock)shareBlock{
- (void)pullDownRefreshWithFinishedCallBack:(void(^)())finishCallBack{
33.简述TCP和UDP的区别:
TCP传输可靠有保证,它有三次握手机制,这一机制保证校验了数据,保证了他的可靠性。而UDP就没有了,所以不可靠。不过UDP的速度是TCP比不了的,而且UDP的反应速度更快,QQ就是用UDP协议传输的,HTTP是用TCP协议传输的。
34.如何保证定位更省电:
desiredAccuracy,这个属性用来控制定位精度,精度越高耗电量越高,所以应该看实际情况设置这个属性的值。
35.简述SDWebImage的实现原理:
SDWebImage加载图片的流程:
1.入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImageManager 根据 URL 开始处理图片。
2.进入 SDWebImageManager-downloadWithURL:delegate:options:userInfo:,交给 SDImageCache 从缓存查找图片是否已经下载 queryDiskCacheForKey:delegate:userInfo:。
3.先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo: 到 SDWebImageManager。
4.SDWebImageManagerDelegate 回调 webImageManager:didFinishWithImage: 到 UIImageView+WebCache 等前端展示图片。
5.如果内存缓存中没有,生成 NSInvocationOperation 添加到队列开始从硬盘查找图片是否已经缓存。
6.根据 URLKey 在硬盘缓存目录下尝试读取图片文件。这一步是在 NSOperation 进行的操作,所以回主线程进行结果回调 notifyDelegate:。
7.如果上一操作从硬盘读取到了图片,将图片添加到内存缓存中(如果空闲内存过小,会先清空内存缓存)。SDImageCacheDelegate 回调 imageCache:didFindImage:forKey:userInfo:。进而回调展示图片。
8.如果从硬盘缓存目录读取不到图片,说明所有缓存都不存在该图片,需要下载图片,回调 imageCache:didNotFindImageForKey:userInfo:。
9.共享或重新生成一个下载器 SDWebImageDownloader 开始下载图片。
10.图片下载由 NSURLConnection 来做,实现相关 delegate 来判断图片下载中、下载完成和下载失败。
11.connection:didReceiveData: 中利用 ImageIO 做了按图片下载进度加载效果。
12.connectionDidFinishLoading: 数据下载完成后交给 SDWebImageDecoder 做图片解码处理。
13.图片解码处理在一个 NSOperationQueue 完成,不会拖慢主线程 UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多。
14.在主线程 notifyDelegateOnMainThreadWithInfo: 宣告解码完成,imageDecoder:didFinishDecodingImage:userInfo: 回调给 SDWebImageDownloader。
15.imageDownloader:didFinishWithImage: 回调给 SDWebImageManager 告知图片下载完成。
16.通知所有的 downloadDelegates 下载完成,回调给需要的地方展示图片。
17.将图片保存到 SDImageCache 中,内存缓存和硬盘缓存同时保存。写文件到硬盘也在以单独 NSInvocationOperation 完成,避免拖慢主线程。
18.SDImageCache 在初始化的时候会注册一些消息通知,在内存警告或退到后台的时候清理内存图片缓存,应用结束的时候清理过期图片。
19.SDWI 也提供了 UIButton+WebCache 和 MKAnnotationView+WebCache,方便使用。
20.SDWebImagePrefetcher 可以预先下载图片,方便后续使用。
36.简述XML和JSON数据各有哪些优势:
(1).可读性方面。JSON和XML的数据可读性基本相同,JSON和XML的可读性可谓不相上下,一边是建议的语法,一边是规范的标签形式,XML可读性较好些。(2).可扩展性方面。XML天生有很好的扩展性,JSON当然也有,没有什么是XML能扩展,JSON不能的。(3).编码难度方面。XML有丰富的编码工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的编码明显比XML容易许多,即使不借助工具也能写出JSON的代码,可是要写好XML就不太容易了。(4).解码难度方面。XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析难度几乎为0。这一点XML输的真是没话说。(5).流行度方面。XML已经被业界广泛的使用,而JSON才刚刚开始,但是在Ajax这个特定的领域,未来的发展一定是XML让位于JSON。到时Ajax应该变成Ajaj(Asynchronous Javascript and JSON)了。(6).解析手段方面。JSON和XML同样拥有丰富的解析手段。(7).数据体积方面。JSON相对于XML来讲,数据的体积小,传递的速度更快些。(8).数据交互方面。JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互(9).数据描述方面。JSON对数据的描述性比XML较差。(10).传输速度方面。JSON的速度要远远快于XML。
37.简述线程和进程有什么联系和区别:
看到过一篇博客 博客上面,在这里引用博客中对线程和进程的理解:
1.计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。2.假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。3.进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。4.一个车间里,可以有很多工人。他们协同完成一个任务。线程就好比车间里的工人。一个进程可以包括多个线程。5.车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。6.可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。7.一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。8.还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。9.这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做(Semaphore),用来保证多个线程不会互相冲突。不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。
38.简述NSUserDefaults的使用场景和使用注意事项:
对于NSUerdefaults来说 一般可以用来保存用户的偏好设置 比如登陆账号 密码这些。 除此之外 我们还可以用它来保存图片, 字符串 , 数字 和对象。它被保存到项目中的Plists文件里面里。保存图片 一般用它里面的两个方法 图片保存可以用PNG或者JPG对应的方法 先转换成NSData 再用NSUerdefaults保存 保存的时候为了让它马上存下来要用synchronize 。它还可以用来在程序间进行反向传值。
39.IOS中数据库是用什么技术实现的:
40.简述什么是主键 什么是外键:
主键是用来唯一确定一条记录的唯一标记,如身份证号码。外键是用来关联其他表,可以通过这个外键唯一确定另外一张表上面的字段。如:A表中有个字段是B表中的主键,那么这个字段就是A的外键。
41.IOS中如何实现数据模型的存储:42.简述IOS的沙盒机制:
IOS中的沙盒机制(SandBox)是一种安全体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如图片、声音、属性列表和文本文件等。1.每个应用程序都在自己的沙盒内2.不能随意跨越自己的沙盒去访问别的应用程序沙盒的内容3.应用程序向外请求或接收数据都需要经过权限认证
43.如何实现真机调试:
Xcode7以后可以不用配置开发者证书直接进行真机测试
44.如何查找项目中的内存泄露:
使用Instruments来查找程序中的内存泄露,以及NSZombieEnabled。
45.项目中支付环节如何实现的:
注意需要配置Apple ID
其他按照微信支付或者支付宝文档进行配置
46.如何实现项目上线到AppStore47.简述你在项目中遇到过哪些问题:
以前做一个项目时,项目中使用了高德地图,当时时每点击进入一个单元格就进入地图,后来发现点击和退出的速度加快后,程序会crash。后来找了好久,发现 每次创建地图会占用很大的内存,而你每次还没有创建完毕就退出,就会导致崩溃,所以最后把创建地图的那一部分代码转移到了创建单元格哪里(前一个页面中),这样保证每次都只有一个地图。而不会因为地图还没有创建好就退出导致crash。
48.如何实现流媒体格式的视频边播放边缓存:49.简述self.name = xxx 与_name=xxx的区别:
(1)self.name
有getter 和sett er 方法 (2)self.name 可以被kvo 监听到
(set 方法 和kvc方法)(3)self.name
考虑了内存管理
是一个对象指针
前者是调用了setter方法,后者是普通的赋值。
50.#include与#import的区别、#import与@class的区别:
(1)#include与#import区别:#include和#import效果相同,只是后者不会引起交叉编译,确保头文件只会被导入一次。(2)#import和@class的区别:import会导入类的所有信息,包括变量和方法,而@class只是告诉编译器,后面的名称是类的名称。推荐使用#import,编译效率更高,防止相互包含的编译错误。
(二)1.IOS中是否支持垃圾回收机制:
IOS开发只支持手动内存管理和ARC,Mac开发支持GC垃圾回收机制,10.8之后弃用了GC,推荐使用ARC。
2.用户自定义了一个对象,如何实现拷贝(可变和不可变拷贝)
必须实现copying和mutableCopying协议,表示返回一个不可变和可变的对象。否则程序将会出现异常。
-(id)copyWithZone:(NSZone*)zone{
Person *person = [[self Class] allocWithZone:zone];
person-&age = self.
person-&name = self.
-(id)mutableCopyWithZone(NSZone*)
3.释放对象的时候为什么要调用[super dealloc]:
因为子类继承父类,子类中一些对象(实例变量)也是继承父类的,因此我们需要调用父类的方法,将父类所拥有的实例进行释放。
4.简述常见的设计模式:
单例设计、代理设计、观察者(通知)、工厂方法。
5.内存管理中使用release方法好还是使用self.xxx = nil好:
使用self.xxx = nil 好,因为它会先调用release方法,而且将变量设置为nil,这样就可以更安全的释放对象,防止野指针调用。
6.事件响应者链的概念:
响应者链表示一系列的响应者对象。事件被交给第一响应者处理,如果第一响应者不处理,事件会沿着响应者链条向上传递,交给下一个响应者(next responder)。一般来说第一响应者是个视图或者其子类对象,当其被触摸后事件交给它处理,如果不处理,事件就会被传递到它的视图控制器(如果存在),然后是它的父视图(superview)(如果存在),以此类推,直到顶层视图。接下来会沿着顶层视图(top view)到窗口(UIWindow)再到UIApplication。如果整个过程都没有响应这个事件,该事件就会被丢弃。
7.static变量和static函数的区别:
(1)static变量表示静态存储变量,变量存储在静态存储区。(2)加在函数前面表示该函数是内部连接,只在本文件中有效,别的文件中不能应用该函数。
static 全局变量与普通的全局变量有什么区别:static 全局变量只初使化一次,防止在其他文件单元中被引用;static 局部变量和普通局部变量有什么区别:static 局部变量只被初始化一次,下一次依据上一次结果值;static 函数与普通函数有什么区别:static 函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
8.面向对象的三大支柱 以及如何理解动态绑定(多态):
三大支柱:封装、多态、继承多态:继承父类,实现方法,只看对象不看指针,不同的对象实现自己重写的不同的方法。
9.frame与bounds的区别:
(1)Frame:该view是在父view坐标系中的位置和大小(参照点是父视图的坐标系)当view做了transform时,该值不准确。(2)Bounds:该view是在本身坐标系的位置和大小(参照点是本身的坐标系统)。
10.谈谈对Runloop的理解:
Run loop是线程相关的基础框架的一部分。一个run loop就是一个事件处理的循环,用来不停的调度工作以及处理输入事件。使用run loop的目的就是让你的线程在有工作的时候忙起来,没有工作的时候休眠。
11.SVN、Git协作开发,怎样防止代码文件冲突:
(1)防止代码冲突:不要同时多人修改同一个文件。例如A、B都同时修改一个文件,先让A修改,然后提交到服务器,然后B更新下来,在进行修改。(2)服务器上的项目文件xcodeproj,仅让一个人管理提交,其他人只更新。防止此文件产生冲突。
12.断点续传如何实现的:
将下载的文件分成几个部分,通过http协议的请求头,设置每一部分下载的偏移量,然后通过多线程下载每一部分,下载完成以后 再组成为最终的完整文件。
13.堆和栈的区别 以及队列和栈的区别:
栈区(stack)由编译器自动分配释放,存放 方法(函数)的参数值、局部变量的值等、堆区(heap)一般由程序员分配和释放、若不释放,则内存溢出。队列:先进先出
栈:先进后出
14.协议、代理的理解:
实际上是两个对象的相互调用A类 B类
A中有B的对象
B.delegate=A
15.HTTP协议、TCP、UDP协议
数据请求:状态行、请求头、请求体服务端响应:响应头(状态码:200;404资源没有找到;400客户端请求语法错误;500服务器错误;)响应体w3c school在线教程
16.IOS 6 与 IOS 7区别:
IOS 6 拟物化风格IOS 7 扁平化风格
17.什么是指针:
type *p;type:类数据类型。用来存储内存单元的编号指针 不完全等于 地址!有类型的标识很多类型的指针,指向数据、指向方法、void 型 。不同的编译环境,sizeof 可能不同。
18.写一个宏,输入两个参数返回其中较小的一个:
#define MIN(a,b) ((a)&(b)?(b):(a))
19.排序算法:
-(void)bunbleSort:(NSMutableArray *)aData{
int count = 0;
for(int i = 0; i & [aData count]-1;i++)
for(int j = i+1; j & [aData count];j++)
if([[aData objectAtIndex:i] integerValue] & [[aDataobjectAtIndex:j]integerValue])
NSNumber *temp = [aData objectAtIndex:i];
[aData replaceObjectAtIndex:i withObject:[aData
objectAtIndex:j]];
[aData replaceObjectAtIndex:j withObject:temp];
count ++;}
-(void)sort2:(NSMutableArray *)resource{
//NSNumber小 -& 大
int count = [resource count];
for(int i = 0; i & count-1; i ++)
for(int j = 0; j & count-i-1; j ++)
if([[resource objectAtIndex:j] integerValue]&[[resource objectAtIndex:j+1] integerValue])
NSNumber *temp = [resource objectAtIndex:j];
[resource replaceObjectAtIndex:j
withObject:[resource objectAtIndex:j+1]];
[resource replaceObjectAtIndex:j+1
withObject:temp];
-(void)quickSortWithArray:(NSMutableArray *)aDataleft:(NSInteger)left right:(NSInteger)right
if (right & left) {NSInteger i =
NSInteger j = right + 1;
while (true) {
while (i+1 & [aData count] && [aData objectAtIndex:++i] &[aData objectAtIndex:left]) ;
while (j-1 & -1 && [aData objectAtIndex:--j] & [aDataobjectAtIndex:left]) ;
if (i &= j)
[self swapWithData:aData index1:i index2:j];
[self swapWithData:aData index1:left index2:j];
[self quickSortWithArray:aData left:left right:j-1];
[self quickSortWithArray:aData left:j+1 right:right];
-(void)swapWithData:(NSMutableArray *)aDataindex1:(NSInteger)index1 index2:(NSInteger)index2
NSNumber *tmp = [aData objectAtIndex:index1];
[aData replaceObjectAtIndex:index1 withObject:[aDataobjectAtIndex:index2]];
[aData replaceObjectAtIndex:index2 withObject:tmp];
20.写一个单链表,要求可以插入数据和删除单个数据:
struct QFInfo{
struct QFInfo *
struct QFInfo *
void insert_AtFirst(struct QFInfo *head,struct QFInfo *insert)
insert-&next = head-&
head-&next =
void insert_AtEnd(struct QFInfo *head,struct QFInfo *insert)
struct QFInfo *temp = head-&
while (temp-&next != NULL) {
temp = temp-&
insert-&next = NULL;
temp-&next =
void delete_1(struct QFInfo *head,struct QFInfo *del)
struct QFInfo *temp = head-&
while (temp-&next != NULL && temp-&next != del)
temp = temp-&
if(temp-&next != NULL)
temp-&next = temp-&next-&
21.下面的程序中,3次retainCount分别是什么,为什么:
NSMutableArray *arr = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
[str retain];
[arr addObject:str];
NSLog(@"%@%lu",str,[str retainCount]);
[str retain];
[str release];
[str release];
NSLog(@"%@%lu",str,[str retainCount]);
[arr removeObject:str];
NSLog(@"%@%lu",str,[str retainCount]);
分别是3、2、1,因为初始化的时候retain
为1,retain的时候+1,往数组中add的时候+1,release的时候-1,从数组中删除的时候-1。
22.引用和指针的区别:
1 .从现象上看:指针在运行时可以改变其所指向的值,而引用一旦和某个对象绑定后就不再改变。引用访问一个变量是直接访问,而指针是间接访问。2.从内存分配上看:程序为指针变量分配内存区域,而引用不分配内存区域。3.从编译上看:程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变指向的对象(指针变量中的值可以改),而引用对象不能改。
23.如何将图片添加到相册:
UIImage *img = [UIImage imageWithNamed:@”123.ppng”];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
24.写一个获取日期的方法,输出格式为:
NSDate *date = [NSDate date];
NSDateFormatter *dateFm = [[NSDateFormatter alloc] init];
dateFm.dateFormat = @"yyyy-MM-dd";
NSString *dateStr = [dateFm stringFromDate:date];
NSLog(@"dateStr:%@",dateStr);
25.将一组数据永久保存到手机里:
NSUserDefaults、plist、数据库、普通文件、归档
26.NSarray *array = @[@“a”,@“b”,@“c”,@“a”,@“d”....],里面有N个string元素,求出array中唯一元素,要求复杂度为N:
(分析:将重复的元素去掉拼接成一个字符串)
NSArray *arr = @[@"a",@"b",@"b",@"c"];
NSString *resultStr = [arr objectAtIndex:0];
for (NSString *str in arr)
if ([resultStr rangeOfString:str].location == NSNotFound) {
resultStr = [resultStr stringByAppendingString:str];
NSLog(@"%@",resultStr);
27.写一个Block使用的例子,尽可能体现出block编程的语法和优势:
void(^myBlock)(NSString *msg);
myBlock = ^(NSString *str){
NSLog(@"%@",str);//line3
//使用block
//相当于把line3的代码放在这里执行。
myBlock(@"hello!");
28.nil和NULL有什么区别:
nil是一个对象,NULL是一个值
29.什么时候使用NSMutableArray,什么时候使用NSArray:
当数组在程序运行时,需要不断变化的,使用NSMutableArray,当数组在初始化后,便不再改变的,使用NSArray。需要指出的是,使用NSArray只表明的是该数组在运行时不发生改变,即不能往NSAarry的数组里新增和删除元素,但不表明其数组內的元素的内容不能发生改变。NSArray是线程安全的,NSMutableArray不是线程安全的,多线程使用到NSMutableArray需要注意。
30.如果我们不创建内存池,是否有内存池提供给我们:
界面线程维护自己的内存池,用户自己创建的数据线程,则需要创建该线程的内存池。
31.类NSObject的那些方法经常被使用:
NSObject是Objetive-C的基类,其由NSObject类及一系列协议构成。其中类方法alloc、class、description 对象方法init、dealloc、– performSelector:withObject:afterDelay:等经常被使用。
32.什么是谓词:
谓词是通过NSPredicate,是通过给定的逻辑条件作为约束条件,完成对数据的筛选。
predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n];
a = [customers filteredArrayUsingPredicate:predicate];
33.简述内存分区情况:
1).代码区:存放函数二进制代码2).数据区:系统运行时申请内存并初始化,系统退出时由系统释放。存放全局变量、静态变量、常量3).堆区:通过malloc等函数或new等操作符动态申请得到,需程序员手动申请和释放4).栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数
记录一些有用的,有意思的。

我要回帖

更多关于 银联招聘面试经验 的文章

 

随机推荐