博客> ios面试问题整理[一]
ios面试问题整理[一]
2019-12-11 00:09 评论:0 阅读:2153 魔灵
ios swift 面试 网络 总结

iOS 面试问题

what is the difference between strong and weak when defining a property? 当定义一个属性时strong 和 weak 有什么区别?

weak是弱引用,相当于assign,指定在目标对象中有一个弱(非拥有)关系。 如果目标对象被释放,属性值自动设置为零。不会造成循环引用!

strong是强引用,相当于retain.指定有一个强(拥有)关系到目标对象。用了它,引用计数自动+1。

扩展内容 weak有指针的情况下,防止生成野指针。 unsafe_unretained 会导致野指针。访问野指针的内存就造成crash. 尽量少用unsafe_unretained关键字。(弱属性不支持OS X V10.6和iOS 4;使用assigninstead。)

copy 指定要用于赋值的对象的副本。 前一个值是发送一个发布消息。 copy是通过调用复制方法。此属性仅对对象类型,它必须实现NSCopying协议。

assign 指明setter使用简单赋值。此属性为默认值。 你使用这个属性为标量类型,如NSInteger和CGRect。

retain 指定在赋值时应调用保留对象的保留。 前一个值是发送一个发布消息。 在OS X V10.6和之后,你可以用attribute关键字指定一个核心基础属性应该像对待一个Objective-C对象的内存管理:

@property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

what method needs to be overridden when implementing deep copy an object? 在实现深层复制对象时需要重写什么方法? 重写copyWithZone方法 扩展 深拷贝同浅拷贝的区别:浅拷贝是指针拷贝,对一个对象进行浅拷贝,相当于对指向对象的指针进行复制,产生一个新的指向这个对象的指针,那么就是有两个指针指向同一个对象,这个对象销毁后两个指针都应该置空。深拷贝是对一个对象进行拷贝,相当于对对象进行复制,产生一个新的对象,那么就有两个指针分别指向两个对象。当一个对象改变或者被销毁后拷贝出来的新的对象不受影响。 实现深拷贝需要实现NSCoying协议,实现- (id)copyWithZone:(NSZone *)zone 方法。当对一个property属性含有copy修饰符的时候,在进行赋值操作的时候实际上就是调用这个方法。

父类实现深拷贝之后,子类只要重写copyWithZone方法,在方法内部调用父类的copyWithZone方法,之后实现自己的属性的处理

父类没有实现深拷贝,子类除了需要对自己的属性进行处理,还要对父类的属性进行处理。

Define a standard macro MAX with 2 input paramenters .it returns the greater one (please provide program segments ) 用2个input参数定义一个标准宏MAX。返回较大的一个(请提供程序段)

define MIN(x, y) ((x)>(y)?(y):(x))

----------------------------- what is singleton pattern ?please try to implement one 什么是单例模式?请尝试实现一个 单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 1.单例模式的要点:   显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。 2.单例模式的优点:   1.实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例。   2.灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程  -------------   在objective-c中要实现一个单例类,至少需要做以下四个步骤:   1、为单例对象实现一个静态实例,并初始化,然后设置成nil,   2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,   3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,   4、适当实现allocWitheZone,copyWithZone,release和autorelease。 下面以SurveyRunTimeData为例子:   static SurveyRunTimeData *sharedObj = nil; //第一步:静态实例,并初始化。 @implementation SurveyRunTimeData

  • (SurveyRunTimeData*) sharedInstance  //第二步:实例构造检查静态实例是否为nil {     @synchronized (self)     {         if (sharedObj == nil)         {             [[self alloc] init];         }     }     return sharedObj; }

  • (id) allocWithZone:(NSZone *)zone //第三步:重写allocWithZone方法 {     @synchronized (self) {         if (sharedObj == nil) {             sharedObj = [super allocWithZone:zone];             return sharedObj;         }     }     return nil; }

  • (id) copyWithZone:(NSZone *)zone //第四步 {     return self; }

  • (id) retain {     return self; }

  • (unsigned) retainCount {     return UINT_MAX; }

  • (oneway void) release {      }

  • (id) autorelease {     return self; }

  • (id)init {     @synchronized(self) {         [super init];//往往放一些要初始化的变量.         return self;     } }

@end ---------------- what is the difference between frame and bounds ? frame和bounds之间有什么区别? 坐标系不同。 bounds是自己坐标系,rect中的origin一般都是(0,0)开始的。 frame是父坐标系,rect中的origin就是指的在父系中的开始点。

how to hid status bar in ios7 /8 如何隐藏状态栏在ios7 / 8

how to implement push notification in a app (please provide program segments ) 如何在应用程序中实现推送通知(请提供程序段) 推送的注册、监听和处理都集中在AppDelegate类里: 1.(BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions 在该方法体里主要实现两个功能: 一是完成推送功能的注册请求,即在程序启动时弹出是否使用推送功能; 二是实现的程序启动是通过推送消息窗口触发的,在这里可以处理推送内容; 1 - (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions      2 {      3     self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];      4     // Override point for customization after application launch.      5     self.viewController = [[[ViewController alloc] init] autorelease];      6     self.window.rootViewController = self.viewController;      7     [self.window setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"background.png"]]];      8     [self.window makeKeyAndVisible];      9     /* 注册推送通知功能, /     10     [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];      11           12     //判断程序是不是由推送服务完成的      13     if (launchOptions) {      14         NSDictionary pushNotificationKey = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];      15         if (pushNotificationKey) {      16             UIAlertView alert = [[UIAlertView alloc]initWithTitle:@"推送通知"       17                                                            message:@"这是通过推送窗口启动的程序,你可以在这里处理推送内容"     18                                                           delegate:nil       19                                                  cancelButtonTitle:@"知道了"       20                                                  otherButtonTitles:nil, nil];      21             [alert show];      22             [alert release];      23         }      24     }      25     return YES;      26 }     

 2. 接收从苹果服务器返回的唯一的设备token,该token是推送服务器发送推送消息的依据,所以需要发送回推送服务器保存 1 - (void)application:(UIApplication )app didRegisterForRemoteNotificationsWithDeviceToken:(NSData )deviceToken {      2     NSString token = [NSString stringWithFormat:@"%@",deviceToken];      3     NSLog(@"apns -> 生成的devToken:%@", token);      4     //把deviceToken发送到我们的推送服务器      5     DeviceSender sender = [[[DeviceSender alloc]initWithDelegate:self ]autorelease];      6     [sender sendDeviceToPushServer:token ];          7 }     

3.接收注册推送通知功能时出现的错误,并做相关处理:   1 - (void)application:(UIApplication )app didFailToRegisterForRemoteNotificationsWithError:(NSError )err {      2     NSLog(@"apns -> 注册推送功能时发生错误, 错误信息:\n %@", err);      3 }    

4. 接收到推送消息,解析处理   1 - (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo      2 {      3     NSLog(@"\napns -> didReceiveRemoteNotification,Receive Data:\n%@", userInfo);      4     //把icon上的标记数字设置为0,      5     application.applicationIconBadgeNumber = 0;      6     if ([[userInfo objectForKey:@"aps"] objectForKey:@"alert"]!=NULL) {      7         UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"推送消息"     8                                                         message:[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]      9                                                        delegate:self      10                                               cancelButtonTitle:@"关闭"     11                                               otherButtonTitles:@"处理推送内容",nil];      12         alert.tag = alert_tag_push;      13         [alert show];      14     }      15 }      通过上面的代码,基本推送功能的开发已经完成了

how to invoke an app from another app ? (please provide program segments ) 如何从另一个应用程序调用应用程序? (请提供节目段)

要为 iOS 程序添加自定义协议的支持是一件很方便的事,只需要在程序的 Info.plist 添加一个 URL types 节点就可以了。在这个节点里,可以设置这个程序所支持的自定义协议名称,像 http、ftp 这种,一般我们可以设置为程序英文名称,像淘宝客户端中就设置了 taobao,这样 taobao:// 这个形式的 URL 就会关联到淘宝客户端的 App。

实现 在 Info.plist 里面设置完 URL types 之后,就可以在程序中处理这类 URL 的打开请求了。 在外部程序中,如果打开了指定自定义协议的 URL,程序中 application delegate 的 application:handleOpenURL: 方法就会被调用,在这个方法里,可以获取到触发这个方法的 URL,可以通过对这个 URL 进行判断,例如根据不同的 Host,不同的 Query String 来执行不同的动作。

  • (void)application:(UIApplication )application handleOpenURL:(NSURL )url {     NSLog(@"%@", [url absoluteString]);     // 在 host 等于 item.taobao.com 时,说明一个宝贝详情的 url,     // 那么就使用本地的 TBItemDetailViewController 来显示     if ([[url host] isEqualToString:@"item.taobao.com"]) {         // 这里只是简单地假设 url 形式为 taobao://item.taobao.com/item.htm?id=12345678         // 先获取要查看的宝贝详情的 itemId         NSString itemId = [[url query] substringFromIndex:[[url query] rangeOfString:@"id="].location+3];         // 使用本地 ViewController 来显示淘宝商品详情         TBItemDetailViewController controller = [[TBItemDetailViewController alloc] initWithItemId:itemId];         [self.navigationController pushViewController:controller animated:YES];         [controller release];     } } 淘宝 for iOS 现在,淘宝 和 淘宝 HD 两个客户端都支持 taobao:// 协议,来打开特定的链接。目前已经支持的有: 宝贝详情 taobao://item.taobao.com/item.htm?id=12688928896 宝贝搜索 taobao://s.taobao.com/?q=iphone 店铺搜索 taobao://shopsearch.taobao.com/browse/shop_search.htm?q=iphone 例如,想要在自己的程序中,使用淘宝客户端来显示一个淘宝商品的详情,以支持用户可以直接在 iPhone 上购买,收藏等,就可以使用下面的代码:
  • (void)showItemInTaobao4iOS:(NSString )itemId {     // 构建淘宝客户端协议的 URL     NSURL url = [NSURL URLWithString:[NSString stringWithFormat:@"taobao://item.taobao.com/item.htm?id=%@", itemId]];     // 判断当前系统是否有安装淘宝客户端     if ([[UIApplication sharedApplication] canOpenURL:url]) {         // 如果已经安装淘宝客户端,就使用客户端打开链接         [[UIApplication sharedApplication] openURL:url];     } else {         // 否则使用 Mobile Safari 或者内嵌 WebView 来显示         url = [NSURL URLWithString:[NSString stringWithFormat:@"http://item.taobao.com/item.htm?id=%@", itemId]];         [[UIApplication sharedApplication] openURL:url];     } } 使用淘宝客户端来打开淘宝链接的好处就是可以让用户更加方便的去购买商品,而不需要再重新登录,或者把用户名密码给了第三方的网站而导致安全隐患。

==========================================

kvo ,NSNotification , delegate 及block区别

kvo (Key-Value Observing)它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知就是cocoa框架实现的观察者模式。 ------------------- 实例: 接收到json数据之后 解析 NSDictionary, 然后把字典对应的字段建立一个model, model里自定义类方法+(instancetype)modelWithDictionary:(NSDictionary*)keyDictionary方法中调用: [self setValuesForKeysWithDictionary:jsonObject]; 从而达到我们想要的效果。将字典转model。

对于一些想要特殊处理的字段可以调用以下方法进行处理: (比如厘米有些key事字典类型的) -(void) setValue:(id)value forKey:(NSString *)key{ if([key isEqualToString:@“products”]){ for(NSMutableDictionary *productionDic in value){ Product * product =[[Product alloc]initWithDictionary:productionDic]; [self.products addobject : product]; } } }

另外情况,里面的key 压根就没有定义,可用通过重写一下这个方法把key和value对应上:

-(void)setValue:(id)value forUndefinedKey:(NSString *)key{ if([key isEqualToString:@“name***”]){self.name = value;} if([key isEqualToString :@“age***”]){ self.age = value; }else{ [super setValue:value forKey:key]; } }

------------------------------------------- Key Value Observing, 顾名思义就是一种observer 模式用于监听property的变化, KVO跟NSNotification有很多相似的地方,

用addObserver:forKeyPath:options:context:去start observer, 用removeObserver:forKeyPath:context去stop observer, 回调就是observeValueForKeyPath:ofObject:change:context:。 KVO 的实现也依赖于 Objective-C 强大的 Runtime 。

------------------------------------------- 简单概述下 KVO 的实现: 当你观察一个对象时,一个新的类会动态被创建。这个类继承自该对象的原本的类,并重写了被观察属性的 setter 方法。

自然,重写的 setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象值的更改。

最后把这个对象的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么 ) 指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例。

原来,这个中间类,继承自原本的那个类。

不仅如此,Apple 还重写了 -class 方法,企图欺骗我们这个类没有变,就是原本那个类。 更具体的信息,去跑一下 Mike Ash 的那篇文章里的代码就能明白,这里就不再重复。

下面是从另外一个博客搞过来的示例代码:

@interface StockData : NSObject {       NSString  stockName;       float price;   }   @end   @implementation StockData   @end - (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];      } -(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"];       }   } - (void)dealloc   {       [stockForKVO removeObserver:self forKeyPath:@"price"];   }

-=========================================-

一般kvc(Key-Value Coding)搭配私用,通过kvo检测一个值的变化。 比如view 的高度变化,是一对多的关系,一个值的变化会通知所有观察者。 -------------------------------------------

NSNotification是通知,也是一对多的使用场景。 在某些情况下,KVO和NSNotification是一样的,都是状态变化之后告知对方。

NSNotification的特点,就是需要被观察者先主动发出通知,然后观察者注册监听后再来进行响应,比KVO多了发送通知的一步,但是其优点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,使用也更灵活。

------------------------------------------- delegate 是代理,就是我不想做的事情交给别人做。比如购物者需要买什么东西,就通过delegate通知卖东西的,卖东西的就会给购物者、选东西、打包,发货。这些操作,这些购物者都不需要关心,只需要调用delegate(代理人)就可以了,由其他类完成所需要的操作。所以delegate是一对一关系。

------------------------------------------- block是delegate的另一种形式,是函数式编程的一种形式。 使用场景跟delegate一样,相比delegate更灵活,而且代理的实现更直观。

------------------------------------------- kvo一般的使用场景是数据,需求是数据变化,比如股票价格变化,我们一般使用KVO(观察者模式)。 delegate一般的使用场景是行为,需求是需要别人帮我做一件事情,比如买卖股票,我们一般使用delegate。 Notification一般是进行全局通知,比如利好消息一出,通知大家去买入。

delegate是强关联,就是委托和代理双方互相知道,你委托别人买股票你就需要知道经纪人,经纪人也不要知道自己的顾客。

Notification是弱关联,利好消息发出,你不需要知道是谁发的也可以做出相应的反应,同理发消息的人也不需要知道接收的人也可以正常发出消息。 ------------------------------------------ ========================================== 将一个函数在主线程执行的4种方法

GCD方法,通过向主线程队列发送一个block块,使block里的方法可以在主线程中执行。 dispatch_async(dispatch_get_main_queue(), ^{
//需要执行的方法 }); ------------------------------------------

NSOperation 方法 NSOperationQueue mainQueue = [NSOperationQueue mainQueue]; //主队列 NSBlockOperation operation = [NSBlockOperation blockOperationWithBlock:^{ //需要执行的方法 }]; [mainQueue addOperation:operation]; ------------------------------------------

NSThread 方法 [self performSelector:@selector(method) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES modes:nil];

[self performSelectorOnMainThread:@selector(method) withObject:nil waitUntilDone:YES];

[[NSThread mainThread] performSelector:@selector(method) withObject:nil]; ------------------------------------------

RunLoop方法 [[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];

========================================== 如何让计时器调用一个类方法 计时器只能调用实例方法,但是可以在这个实例方法里面调用静态方法。 ------- 使用计时器需要注意,计时器一定要加入RunLoop中,并且选好model才能运行。

scheduledTimerWithTimeInterval方法创建一个计时器并加入到RunLoop中所以可以直接使用。

如果计时器的repeats选择YES说明这个计时器会重复执行,一定要在合适的时机调用计时器的invalid。不能在dealloc中调用,因为一旦设置为repeats 为yes,计时器会强持有self,导致dealloc永远不会被调用,这个类就永远无法被释放。

比如可以在viewDidDisappear中调用, 这样当类需要被回收的时候就可以正常进入dealloc中了。 [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];

-(void)timerMethod { //调用类方法 [[self class] staticMethod]; }

-(void)invalid { [timer invalid]; timer = nil; } ==========================================

如何重写类方法 在子类中实现一个同基类名字一样的静态方法

在调用的时候不要使用类名调用,而是使用[self class]的方式调用。原理,用类名调用是早绑定,在编译期绑定,用[self class]是晚绑定,在运行时决定调用哪个方法。 ========================================== NSTimer创建后,会在哪个线程运行。 用scheduledTimerWithTimeInterval创建的,在哪个线程创建就会被加入哪个线程的RunLoop中就运行在哪个线程

自己创建的Timer,加入到哪个线程的RunLoop中就运行在哪个线程。 ========================================== id和NSObject*的区别

id是一个 objc_object 结构体指针,定义是 typedef struct objc_object id ---------------------- id可以理解为指向对象的指针。所有oc的对象 id都可以指向,编译器不会做类型检查,id调用任何存在的方法都不会在编译阶段报错,当然如果这个id指向的对象没有这个方法,该崩溃还是会崩溃的。 ------------------------ NSObject 指向的必须是NSObject的子类,调用的也只能是NSObjec里面的方法否则就要做强制类型转换。

不是所有的OC对象都是NSObject的子类,还有一些继承自NSProxy。 NSObject *可指向的类型是id的子集。 ==========================================

iOS 核心框架 • CoreAnimation • CoreGraphics • CoreLocation • AVFoundation • Foundation iOS核心机制 • UITableView 重用 • ObjC内存管理;自动释放池,ARC如何实现 • runloop • runtime • Block的定义、特性、内存区域、如何实现 • Responder Chain • NSOperation • GCD 数据结构 • 8大排序算法 • 二叉树实现 • 二分查找实现 面向对象编程 • 封装、继承、多态 • 设计模式6个原则 • 设计一个类的功能,如何划分粒度(单一职责) • 接口隔离。 • 如果有一个鸟类,有飞的动作,一个鸵鸟继承它是合适的吗(里氏替换) • 类之间的依赖如何依赖偶合度最小(依赖倒转) 高层依赖低层,低层不能依赖高层。依赖接口,不能依赖具体的类。 • 如果A要调用C函数,但C是B的成员类,应该如何设计?(迪米特) • 如何设计类,能做到只增加代码,而不修改代码,有哪些经验(开放封闭) 通过设计模式解决。 计算机技术 • 计算机网络: TCP/IP、HTTPCDN、SPDY • 计算机安全: RSA、AES、DES • 操作系统:线程、进程、堆栈、死锁、调度算法 iOS新特性、新技术 • iOS7 UIDynamic、SpritKit、新布局、扁平化 • iOS8 应用程序扩展、HealthKit、SceneKit、CoreLocation、TouchID、PhotoKit • iOS9 • Apple Watch • 第三方库:SDWebImage、AFNetwork、JSONKit、wax • swift •     ==========================================

import和#include的区别,@class代表什么?

@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文件中还是需要使用#import 而#import比起#include的好处就是不会引起重复包含 ==========================================

谈谈Object-C的内存管理方式及过程? 当你使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1. 当你不再使用该对象时,你要负责向该对象发送一条release或autorelease消息.这样,该对象将在使用寿命结束时被销毁. --------------------------------------

当你通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,而且已经被设置为自动释放,你不需要执行任何操作来确保该对象被清理. 如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它. ------------------------------------- 如果你保留了某个对象,你需要(最终)释放或自动释放该对象. 必须保持retain方法和release方法的使用次数相等. ========================================== Object-C有私有方法吗?私有变量呢? objective-c – 类里面的方法只有两种, 静态方法和实例方法.  这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西. 

如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了.  在类里面声名一个私有方法 @interface Controller : NSObject { NSString *something; } + (void)thisIsAStaticMethod; – (void)thisIsAnInstanceMethod; @end @interface Controller (private)  –(void)thisIsAPrivateMethod; @end @private可以用来修饰私有变量 在Objective‐C中, 所有实例变量默认都是私有的, 所有实例方法默认都是公有的 ========================================== Object-C有多继承吗?没有的话用什么代替? cocoa 中所有的类都是NSObject 的子类 多继承在这里是用protocol 委托代理 来实现的 你不用去考虑繁琐的多继承 ,虚基类的概念. ood的多态特性 在 obj-c 中通过委托来实现. ==========================================

内存管理 Autorelease、retain、copy、assign的set方法和含义?

初始化(alloc/init)的对象,你需要释放(release)它。例如: NSMutableArray aArray = [[NSArray alloc] init]; 后,需要 [aArray release];

retain或copy的,你需要释放它。例如: [aArray retain] 后,需要 [aArray release];

被传递(assign)的对象,你需要斟酌的retain和release。例如: obj2 = [[obj1 someMethod] autorelease];

对象2接收对象1的一个自动释放的值,或传递一个基本数据类型(NSInteger,NSString)时:你或希望将对象2进行retain,以防止它在被使用之前就被自动释放掉。但是在retain后,一定要在适当的时候进行释放。

关于索引计数(Reference Counting)的问题 retain值 = 索引计数(Reference Counting)

NSArray对象会retain(retain值加一)任何数组中的对象。 当NSArray被卸载(dealloc)的时候,所有数组中的对象会 被 执行一次释放(retain值减一)。 不仅仅是NSArray,任何收集类(Collection Classes)都执行类似操作。 例如 NSDictionary,甚至UINavigationController。

Alloc/init建立的对象,索引计数为1。无需将其再次retain。

[NSArray array]和[NSDate date]等“方法”建立一个索引计数为1的对象,但是也是一个自动释放对象。 所以是本地临时对象,那么无所谓了。

如果是打算在全Class中使用的变量(iVar),则必须retain它。

缺省的类方法返回值都被执行了“自动释放”方法。(*如上中的NSArray)

在类中的卸载方法“dealloc”中,release所有未被平衡的NS对象。(*所有未被autorelease,而retain值为1的) ========================================== 浅拷贝和深拷贝区别是什么 简单的来说就是,在有指针的情况下, 浅拷贝只是增加了一个指针指向已经存在的内存, 而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,

采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误 ==========================================

C和obj-c 如何混用

obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码, 处理mm文件可以识别obj-c,c,c++代码, 但cpp文件必须只能用c/c++代码, 而且cpp文件include的头文件中,也不能出现obj-c的代码, 因为cpp只是cpp --------------------------- 在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题 --------------------------- 在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

========================================== Objective-C中类别和类扩展的区别。

category类别和extensions类扩展的不同在于后者可以添加属性。另外后者添加的方法是必须要实现的。

========================================== 我们说的Objective-C是动态运行时语言是什么意思? 多态。  主要是将数据类型的确定由编译时,推迟到了运行时。 这个问题其实浅涉及到两个概念,运行时和多态。 简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法

多态:不同对象以自己的方式响应相同的消息的能力叫做多态。

意思就是假设生物类(life)都用有一个相同的方法-eat;

那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。

也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。 因此也可以说,运行时机制是多态的基础 ==========================================

Objective-C堆和栈的区别? 管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制; 对于堆来说,释放工作由程序员控制,容易产生memory leak。 ------------------ 申请大小: 栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因 此,能从栈获得的空间较小。 堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。 ------------------------ 碎片问题:

对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出 对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。 ------------------------ 分配方式:堆都是动态分配的,没有静态分配的堆。 栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。 ---------------------- 分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。

======================================= ======================================= 如何处理多个网络请求的并发的情况 一、概念 1.并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。 2.并行 当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。 3.区别 并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。 举个栗子 1).并发 一个送外卖的A需要把两份外卖分别送到两个客户B和C手里。 A必须先送完B外卖才能接着送C的。这就是并发 2).并行 客户C 分别从饿了么和美团订了一共两份外卖。那么外卖员A和外卖员B需要把外卖一同送到客户C手里。 这就是并行   在iOS中,经常可以看见有这样的需求,就是一个方法要等另外一个方法执行完毕再做相对应的处理,比如说一些网络请求,需要根据上一个请求的返回值做相对应的处理再执行第二个请求,所以我们不能让两个请求同时去请求网络。下面就记录以下通过GCD和NSOperationQueue来控制并发。 二、代码部分(GCD) dispatch_semaphore  信号量     信号量是一个整型值并且具有初始计数值,信号量通常支持两个操作:通知和等待。当信号被通知的时候计数值会增加,当信号量在线程上等待的时候,必要的情况下线程会被阻塞掉,直至信号被通知时计数值大于0,然后线程会减少这个计数继续工作。   GCD中又3个信号量有关的操作:   dispatch_semaphore_create    信号量创建   dispatch_semaphore_signal    发送通知   dispatch_semaphore_wait     信号量等待 GCD  

1 #import 2 3 int main(int argc, const char * argv[]) { 4 5 @autoreleasepool { 6 7 // 创建信号量 8 9 __block dispatch_semaphore_t sem = dispatch_semaphore_create(0); 10 11 // 创建队列 12 13 dispatch_queue_t queue = dispatch_queue_create("testBlock", NULL); 14 15 dispatch_async(queue, ^{ 16 17 for (int i = 0; i<10; i++) { 18 19 NSLog(@"i的值是:%d",i); 20 21 } 22 23 // 发送通知 24 25 dispatch_semaphore_signal(sem); 26 27 }); 28 29
30 31 // 信号量等待 32 33 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); 34 35
36 37 for (int j = 0; j<20; j++) { 38 39 NSLog(@"j的值是:%d",j); 40 41 } 42 43 } 44 45 return 0; 46 47 }

      打印结果为 2015-07-28 16:17:04.195 多线程[16370:1833932] i的值是:0 2015-07-28 16:17:04.197 多线程[16370:1833932] i的值是:1 2015-07-28 16:17:04.197 多线程[16370:1833932] i的值是:2 2015-07-28 16:17:04.197 多线程[16370:1833932] i的值是:3 2015-07-28 16:17:04.197 多线程[16370:1833932] i的值是:4 2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:5 2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:6 2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:7 2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:8 2015-07-28 16:17:04.198 多线程[16370:1833932] i的值是:9 2015-07-28 16:17:04.198 多线程[16370:1833932] j的值是:0 2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:1 2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:2 2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:3 2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:4 2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:5 2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:6 2015-07-28 16:17:04.199 多线程[16370:1833932] j的值是:7 2015-07-28 16:17:04.221 多线程[16370:1833932] j的值是:8 2015-07-28 16:17:04.221 多线程[16370:1833932] j的值是:9 2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:10 2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:11 2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:12 2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:13 2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:14 2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:15 2015-07-28 16:17:04.222 多线程[16370:1833932] j的值是:16 2015-07-28 16:17:04.223 多线程[16370:1833932] j的值是:17 2015-07-28 16:17:04.223 多线程[16370:1833932] j的值是:18 2015-07-28 16:17:04.223 多线程[16370:1833932] j的值是:19  我们看到先打印完i值后在打印j值 这就完成了并发请求 NSOperationQueue   

  • (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    // 创建一个队列

    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    // 设置最大线程数

    queue.maxConcurrentOperationCount = 5;

    // 创建一个A操作

    NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{

    for (int i = 0; i&lt;10; i++) {
        NSLog(@"i的值是:%d",i);
    }

    }];

    // 创建一个B操作

    NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{

    for (int j = 0; j&lt;20; j++) {
    
        NSLog(@"j的值是:%d",j);
    
    }

    }];

    // 分别加入到队列中

    [queue addOperation:operationA];

    [queue addOperation:operationB];

}

     打印结果 2015-07-28 17:51:09.508 111[16598:1880752] j的值是:0 2015-07-28 17:51:09.508 111[16598:1880750] i的值是:0 2015-07-28 17:51:09.509 111[16598:1880752] j的值是:1 2015-07-28 17:51:09.509 111[16598:1880750] i的值是:1 2015-07-28 17:51:09.509 111[16598:1880752] j的值是:2 2015-07-28 17:51:09.509 111[16598:1880750] i的值是:2 2015-07-28 17:51:09.509 111[16598:1880752] j的值是:3 2015-07-28 17:51:09.509 111[16598:1880750] i的值是:3 2015-07-28 17:51:09.509 111[16598:1880752] j的值是:4 2015-07-28 17:51:09.509 111[16598:1880750] i的值是:4 2015-07-28 17:51:09.509 111[16598:1880752] j的值是:5 2015-07-28 17:51:09.509 111[16598:1880750] i的值是:5 2015-07-28 17:51:09.509 111[16598:1880752] j的值是:6 2015-07-28 17:51:09.509 111[16598:1880750] i的值是:6 2015-07-28 17:51:09.509 111[16598:1880752] j的值是:7 2015-07-28 17:51:09.509 111[16598:1880750] i的值是:7 2015-07-28 17:51:09.509 111[16598:1880752] j的值是:8 2015-07-28 17:51:09.509 111[16598:1880750] i的值是:8 2015-07-28 17:51:09.510 111[16598:1880752] j的值是:9 2015-07-28 17:51:09.510 111[16598:1880750] i的值是:9   我们看到打印顺序是交替进行的。 那么如何进行顺序操作呢。只需一行代码。

  • (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    // 创建一个队列

    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

    // 设置最大线程数

    queue.maxConcurrentOperationCount = 5;

    // 创建一个A操作

    NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{

    for (int i = 0; i&lt;10; i++) {
    
        NSLog(@"i的值是:%d",i); 
    
    }

    }];

    // 创建一个B操作

    NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{

    for (int j = 0; j&lt;20; j++) {
    
        NSLog(@"j的值是:%d",j);
    
    }

    }];

 // 添加依赖 B要在A打印完在进行打印 所以是B依赖于A 那么只需要添加如下代码即可完成

  [operationB addDependency:operationA];

// 分别加入到队列中

 [queue addOperation:operationA];

[queue addOperation:operationB];

}

  打印结果 2015-07-28 17:54:02.606 111[16625:1882738] i的值是:0 2015-07-28 17:54:02.609 111[16625:1882738] i的值是:1 2015-07-28 17:54:02.609 111[16625:1882738] i的值是:2 2015-07-28 17:54:02.609 111[16625:1882738] i的值是:3 2015-07-28 17:54:02.609 111[16625:1882738] i的值是:4 2015-07-28 17:54:02.609 111[16625:1882738] i的值是:5 2015-07-28 17:54:02.609 111[16625:1882738] i的值是:6 2015-07-28 17:54:02.609 111[16625:1882738] i的值是:7 2015-07-28 17:54:02.610 111[16625:1882738] i的值是:8 2015-07-28 17:54:02.610 111[16625:1882738] i的值是:9 2015-07-28 17:54:02.610 111[16625:1882738] j的值是:0 2015-07-28 17:54:02.610 111[16625:1882738] j的值是:1 2015-07-28 17:54:02.610 111[16625:1882738] j的值是:2 2015-07-28 17:54:02.610 111[16625:1882738] j的值是:3 2015-07-28 17:54:02.610 111[16625:1882738] j的值是:4 2015-07-28 17:54:02.611 111[16625:1882738] j的值是:5 2015-07-28 17:54:02.611 111[16625:1882738] j的值是:6 2015-07-28 17:54:02.611 111[16625:1882738] j的值是:7 2015-07-28 17:54:02.611 111[16625:1882738] j的值是:8 2015-07-28 17:54:02.611 111[16625:1882738] j的值是:9 顺序操作请求完成。 计算机网络常见面试题总结 1.       OSI , TCP/IP ,五层协议的体系结构 OSI分层(7层) :物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP分层(4层) :网络接口层、网际层、运输层、应用层。 五层协议(5层) :物理层、数据链路层、网络层、运输层、应用层。 每一层的作用如下 : 物理层:激活、维持、关闭通信端点之间的机械特性、电气特性、功能特性以及过程特性。该层为上层协议提供了一个传输数据的物理媒体。 数据链路层 :数据链路层在不可靠的物理介质上提供可靠的传输。该层的作用包括:物理地址寻址、数据的成帧、流量控制、数据的检错、重发等。 网络层 :网络层负责对子网间的数据包进行路由选择。此外,网络层还可以实现拥塞控制、网际互连等功能。 传输层 :第一个端到端,即主机到主机的层次。传输层负责将上层数据分段并提供端到端的、可靠的或不可靠的传输。此外,传输层还要处理端到端的差错控制和流量控制问题。 会话层 :会话层管理主机之间的会话进程,即负责建立、管理、终止进程之间的会话。会话层还利用在数据中插入校验点来实现数据的同步。 表示层 :表示层对上层数据或信息进行变换以保证一个主机应用层信息可以被另一个主机的应用程序理解。表示层的数据转换包括数据的加密、压缩、格式转换等。 应用层 :为操作系统或网络应用程序提供访问网络服务的接口。 2.       IP 地址的分类 A类地址:以0开头,第一个字节范围:0~127; B类地址:以10开头,第一个字节范围:128~191; C类地址:以110开头,第一个字节范围:192~223; D类地址:以1110开头,第一个字节范围为224~239; 3.       ARP 协议的工作原理 首先,每台主机都会在自己的ARP缓冲区中建立一个 ARP列表,以表示IP地址和MAC地址的对应关系。当源主机需要将一个数据包要发送到目的主机时,会首先检查自己 ARP列表中是否存在该 IP地址对应的MAC地址,如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个 ARP响应数据包,告诉对方自己是它需要查找的MAC地址;源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。 4.       路由设备与相关层 物理层 :中继器(Repeater,也叫放大器),集线器。 数据链路层 :网桥,交换机。 网络层 :路由器。 网关 :网络层以上的设备。 5.       常见的路由选择协议,以及它们的区别 常见的路由选择协议有:RIP协议、OSPF协议。 RIP协议 :底层是贝尔曼福特算法,它选择路由的度量标准(metric)是跳数,最大跳数是15跳,如果大于15跳,它就会丢弃数据包。 OSPF协议 :底层是迪杰斯特拉算法,是链路状态路由选择协议,它选择路由的度量标准是带宽,延迟。 6.       TCP 与 UDP 的区别 UDP是面向无连接的,不可靠的数据报服务; TCP是面向连接的,可靠的字节流服务。 7.       TCP 的可靠性如何保证? TCP的可靠性是通过顺序编号和确认(ACK)来实现的。 8.       TCP 三次握手和四次挥手的全过程

10.   在浏览器中输入 www.baidu.com 后执行的全部过程 现在假设如果我们在客户端(客户端)浏览器中输入http://www.baidu.com,而baidu.com为要访问的服务器(服务器),下面详细分析客户端为了访问服务器而执行的一系列关于协议的操作: 1、客户端浏览器通过DNS解析到www.baidu.com的IP地址220.181.27.48,通过这个IP地址找到客户端到服务器的路径。客户端浏览器发起一个HTTP会话到220.161.27.48,然后通过TCP进行封装数据包,输入到网络层。 2、在客户端的传输层,把HTTP会话请求分成报文段,添加源和目的端口,如服务器使用80端口监听客户端的请求,客户端由系统随机选择一个端口如5000,与服务器进行交换,服务器把相应的请求返回给客户端的5000端口。然后使用IP层的IP地址查找目的端。 3、客户端的网络层不用关系应用层或者传输层的东西,主要做的是通过查找路由表确定如何到达服务器,期间可能经过多个路由器,这些都是由路由器来完成的工作,我不作过多的描述,无非就是通过查找路由表决定通过那个路径到达服务器。 4、客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定IP地址的MAC地址,然后发送ARP请求查找目的地址,如果得到回应后就可以使用ARP的请求应答交换的IP数据包现在就可以传输了,然后发送IP数据包到达服务器的地址。 11.   HTTP 协议包括哪些请求? GET:请求读取由URL所标志的信息。 POST:给服务器添加信息(如注释)。 PUT:在给定的URL下存储一个文档。 DELETE:删除给定的URL所标志的资源。 12.   HTTP 中, POST 与 GET 的区别 (1)Get是从服务器上获取数据,Post是向服务器传送数据。 (2)Get是把参数数据队列加到提交表单的Action属性所指向的URL中,值和表单内各个字段一一对应,在URL中科院看到。 (3)Get传送的数据量小,不能大于2KB;post传送的数据量较大,一般被默认为不受限制。 (4)根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。 I.所谓 安全的 意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。 II. 幂等 的意味着对同一URL的多个请求应该返回同样的结果。 13.   TCP/IP 中,每一层对应的协议 网络层 :IP协议、ICMP协议、ARP协议、RARP协议。 传输层 :UDP协议、TCP协议。 应用层 :FTP(文件传送协议)、Telenet(远程登录协议)、DNS(域名解析协议)、SMTP(邮件传送协议),POP3协议(邮局协议),HTTP协议。 14.   TCP 对应的协议和 UDP 对应的协议 TCP对应的协议: (1) FTP :定义了文件传输协议,使用21端口。常说某某计算机开了FTP服务便是启动了文件传输服务。下载文件,上传主页,都要用到FTP服务。 (2) Telnet :它是一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上,通过这种端口可以提供一种基于DOS模式下的通信服务。如以前的BBS是-纯字符界面的,支持BBS的服务器将23端口打开,对外提供服务。 (3) SMTP :定义了简单邮件传送协议,现在很多邮件服务器都用的是这个协议,用于发送邮件。如常见的免费邮件服务中用的就是这个邮件服务端口,所以在电子邮件设置-中常看到有这么SMTP端口设置这个栏,服务器开放的是25号端口。 (4) POP3 :它是和SMTP对应,POP3用于接收邮件。通常情况下,POP3协议所用的是110端口。也是说,只要你有相应的使用POP3协议的程序(例如Fo-xmail或Outlook),就可以不以Web方式登陆进邮箱界面,直接用邮件程序就可以收到邮件(如是163邮箱就没有必要先进入网易网站,再进入自己的邮-箱来收信)。 (5)HTTP协议: 是从 Web 服务器传输超文本到本地浏览器的传送协议。 UDP对应的协议: (1) DNS :用于域名解析服务,将域名地址转换为IP地址。DNS用的是53号端口。 (2) SNMP :简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。 (3) TFTP (Trival File Transfer Protocal),简单文件传输协议,该协议在熟知端口69上使用UDP服务。 15.特殊的IP地址 (1)网络地址 IP地址由网络号(包括子网号)和主机号组成,网络地址的主机号为全0,网络地址代表着整个网络。 (2)广播地址 广播地址通常称为直接广播地址,是为了区分受限广播地址。 广播地址与网络地址的主机号正好相反,广播地址中,主机号为全1。当向某个网络的广播地址发送消息时,该网络内的所有主机都能收到该广播消息。 (3)组播地址 D类地址就是组播地址。 先回忆下A,B,C,D类地址吧 A类地址以00开头,第一个字节作为网络号,地址范围为:0.0.0.0~127.255.255.255; B类地址以10开头,前两个字节作为网络号,地址范围是:128.0.0.0~191.255.255.255; C类地址以110开头,前三个字节作为网络号,地址范围是:192.0.0.0~223.255.255.255。 D类地址以1110开头,地址范围是224.0.0.0~239.255.255.255,D类地址作为组播地址(一对多的通信); E类地址以1111开头,地址范围是240.0.0.0~255.255.255.255,E类地址为保留地址,供以后使用。 Notice:只有A,B,C有网络号和主机号之分,D类地址和E类地址没有划分网络号和主机号。 (4)255.255.255.255 该IP地址指的是受限的广播地址。受限广播地址与一般广播地址(直接广播地址)的区别在于,受限广播地址之只能用于本地网络,路由器不会转发以受限广播地址为目的地址的分组;一般广播地址既可在本地广播,也可跨网段广播。例如:主机192.168.1.1/30上的直接广播数据包后,另外一个网段192.168.1.5/30也能收到该数据报;若发送受限广播数据报,则不能收到。 Notice:一般的广播地址(直接广播地址)能够通过某些路由器(当然不是所有的路由器),而受限的广播地址不能通过路由器。 (5)0.0.0.0 常用于寻找自己的IP地址,例如在我们的RARP,BOOTP和DHCP协议中,若某个未知IP地址的无盘机想要知道自己的IP地址,它就以255.255.255.255为目的地址,向本地范围(具体而言是被各个路由器屏蔽的范围内)的服务器发送IP请求分组。 (6)回环地址 127.0.0.0/8被用作回环地址,回环地址表示本机的地址,常用于对本机的测试,用的最多的是127.0.0.1。 (7)A、B、C类私有地址 私有地址(private address)也叫专用地址,它们不会在全球使用,只具有本地意义。 A类私有地址:10.0.0.0/8,范围是:10.0.0.0~10.255.255.255 B类私有地址:172.16.0.0/12,范围是:172.16.0.0~172.31.255.255 C类私有地址:192.168.0.0/16,范围是:192.168.0.0~192.168.255.255 15.   NAT 协议、 DHCP 协议、 DNS 协议的作用 NAT协议 :网络地址转换(NAT,Network AddressTranslation)属接入广域网(WAN)技术, 是一种将私有(保留)地址转化为合法IP地址的转换技术,它被广泛应用于各种类型Internet接入方式和各种类型的网络中。原因很简单,NAT不仅完美地解决了lP地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。 DHCP协议 :动态主机设置协议(Dynamic Host ConfigurationProtocol, DHCP) 是一个局域网的网络协议,使用UDP协议工作,主要有两个用途:给内部网络或网络服务供应商自动分配IP地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段。 DNS协议 :DNS 是域名系统 (Domain Name System) 的缩写,是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。

收藏
0
sina weixin mail 回到顶部