最近面试,发现这些题个人遇到的几率大一些,与大家分享一下,分三文给大家:

当然Xcode新版本与之前一版本的区别,以及iOS新特性是必要了解的吧。

Xcode8 和iOS 10 在之前文章有发过,感兴趣的可以查阅。 http://www.cnblogs.com/xujiahui/p/6025830.html

之一:

1.请简述你对协议的理解 官方定义协议:

Protocols Define Messaging Contracts

A class interface declares the methods and properties
associated with that class. A protocol, by contrast,
is used to declare methods and properties that are
independent of any specific class.

译:协议用来定义 消息契约 (暂且这么翻译)
一个类接口声明与类相关的方法和属性。一个协议,相比之
下,用于声明的方法和属性是独立于任何特定的类。

总结一下:
(1)协议相当于没有与类相关联的接口(网上也有说 协议是
一个方法签名的列表 ),他申明一组方法,列出他的参数
和返回值,共享给其他类使用,然后不进行实现,让用它的
类来实现这些方法
(2)在任何一个类中,只要声明了协议,都可以实现协议里
的方法。

(3)协议不是一个类,且独立于任何特定的类。
(4)用@protocol 关键字声明一个协议

委托:

苹果的官方文档给了很清晰的解释:

Delegation is a simple and powerful pattern in which
one object in a program acts on behalf of, or in
coordination with, another object. The delegating
object keeps a reference to the other object—the
delegate—and at the appropriate time sends a message
to it. The message informs the delegate of an event that
the delegating object is about to handle or has just
handled. The delegate may respond to the message by
updating the appearance or state of itself or other
objects in the application, and in some cases it can
return a value that affects how an impending event is
handled. The main value of delegation is that it allows
you to easily customize the behavior of several objects
in one central object.

意译一下就是:代理是一种简单而功能强大的设计模式,这
种模式用于一个对象“代表”另外 一个对象和程序中其他
的对象进行交互。 主对象(这里指的是 delegating object)
中维护一个代理(delegate)的引用并且在合适的时候向这
个代理发送消息。这个消息通知“代理”主对象即将处理或
是已经处理完了某一 个事件。这个代理可以通过更新自己
或是其它对象的 UI 界面或是其它状态来响应主对象所发送
过来的这个事件的消息。或是在某些情况下能返回一个值来

影响其它 即将发生的事件该如何来处理。代理的主要价值
是它可以让你容易的定制各种对象的行为。注意这里的代理
是个名词,它本身是一个对象,这个对象是专门代表被代 理
对象来和程序中其他对象打交道的。

委托是 objC 中使用非常频繁的一种设计模式,它的实现与
协议的使用是分不开的

代理:

在设计模式层面上:

委托(delegate)也叫代理是 iOS 开发中常用的设计模式。
我们借助于 protocol 可以很方便的实现这种设计模式。

2.如何理解 ARC 自动引用计数机制

手动引用计数(Manully Reference Counting, aka
MRC)

Objective-C 的 MRC,简单来说就是一句话:谁创建,谁释
放。复杂一点的解释如下:

• 所有由 alloc、copy(mutablecopy)、retain、new 创建
的 object,必须手动 release(或 autorelease)

• 反之,则不需要也不可以

• autorelease 不是自动释放,是 AutoreleasePool 的实
例,在 runloop 中被”稍后“释放。

MRC 有什么问题
常犯的错误:

  • Crash! Reject! 内存管理是导致 app crash 的最主要
    原因。也是 App Store 审核时拒审的最多的原因;

  • 规则简单,但细节太多,依赖于工程师的清醒头脑和良
    好习惯,依赖于命名规范

  • Dangling Pointer,delegate 需要手动设置为 nil

  • 触发 NSError、或者有复杂的条件分支逻辑时,忘记释

    放内存
    需要使用一堆工具,帮助你检测代码:

  • Instruments: Allocations, Leaks, Zombies

  • Static Analyzer

  • Heap

  • ObjectAlloc

  • vmmap

  • Debugger

    工程师需要做的事情:

  • 理解 MRC,写正确的代码

  • 正确的命名规范

  • 使用五花八门的辅助工具,来保证代码没问题

  • 保持清醒的头脑,不犯低级错误

    这不是工程师所擅长的事情,这个工作应该由编译器来做才
    对—LLVM 3.1

    什么是 ARC

  • Objective-C 对象的自动管理机制

  • 由 LLVM 编译器来保证

  • 与 MRC 完全兼容

  • 引入新的运行时特性:弱指针、性能优化

    ARC 不是

  • 新的运行时模型

  • 自动 malloc/free, CF 等等(不负责纯 C 代码的内存管

    理)

  • 不是 GC。不扫描堆、不暂停进程运行、没有不确定的

    内存释放

ARC 如何工作

  • 编译器在编译期,帮你动态添加
    retain/release/autorelease

  • 返回同样结果的不同 API,在内存方面,没有区别(把
    alloc/init 模式与 convenient method 当成一样就可
    以了)

    ARC 有什么好处

  • 不用写 retain/release/autorelease 这样的代码,甚
    至连 dealloc 方法都不需要(前提是类不需要管理 C 指
    针)

  • 更好的性能,ARC 智能地在”适当“的地方插入
    retain/release

  • Block just work

  • Less code, less bug

  • 少浪费脑细胞和脑时钟周期

    如何打开 ARC

  • Xcode 的 Project Setting 中,设置 Objective-C
    Automatic Reference Counting 为 YES

  • Xcode 4.2+,新的 Project 默认为 ARC

为了实现 ARC,LLVM 编译器必须保证 4 条规则

  • 不能调用或实现跟引用计数相关的方法
    (retain/release/autorelease/retaincount 等),否
    则产生编译错误

  • C 的结构体里面,不能有 Object 指针;如果必须使用,
    那么可以用 Objective-C 的类代替

  • 编译器必须清楚 void*是否被 retained。引入新的 API
    来转换 Objective-C 和 Core Foundation 类型的对象

  • 编译器必须清楚自动释放的对象,因此
    AutoreleasePool 不能是对象,而只是语义上的符号。
    @autoreleasepool directive 甚至可能在 MRC 中使用

    如何理解 ARC

  • 从对象的从属关系角度考虑:强引用(retain)保证对象
    的存在,或没有强引用,则对象被自动销毁

  • 想清楚程序的对象图

  • 不要再考虑 retain, release, autorelease 了

    弱引用(必须在 iOS 5 中使用)

    • 安全的”弱指针“,引用的对象被销毁时,自动变成
    nil;避免了 Dangling Pointer

• 在 property 中使用 weak 关键字声明,ivar 中使用_weak
声明

循环引用

  • ARC 依然存在循环引用的可能

  • 手动设置某一个引用为 nil,破坏循环引用

  • 使用弱引用来避免

    性能

  • 与 MRC 没有实质的性能区别,甚至更好(有时候好得
    多),内存峰值比 MRC 低

  • 没有 GC 的开销;没有延迟的销毁,没有进程暂停,没
    有不能确定的释放

    ARC 的优点

  • 更容易理解

  • 写更少的代码,更少的 bug

  • 更容易维护,甚至更好的性能

  • 安全、稳定

iOS 的什么版本才能支持 ARC

  • iOS 6 发布后,以 iOS 5.0 作为 Deployment Target 完
    全没问题。所以都可以使用 ARC。如果你必须支持 5.0
    以下的设备,那么看后两条。

  • ARC 由 LLVM 3.1 保证,LLVM 3.1 在安装 Xcode 4.2 自
    动安装;也就是说只要 Xcode 4.2 以上的版本,可以设
    置的 Deployment Target 的最低版本,都支持 ARC。笔
    者在 4.0+的 app 中使用 ARC。

  • 弱引用(Weak Reference)必须在 iOS 5 以上的设备才
    支持

    3. 如何理解

    retain/copy/assign/release/autorelease/deallo
    c 关键字

    首先了解:
    (1)内存管理

    范围:

    • 任何继承了 NSObject 的对象,对基本数据类型无效

    原理:

  • 每个对象内部都保存了一个与之相关联的整数,称为引
    用计数器(auto reference count)

  • 每当使用 alloc、new 或者 copy 创建一个对象时,对
    象的引用计数器被设置为 1

  • 给对象发送一条 retain 消息(即调用 retain 方法),
    可以使引用计数器值+1

  • 给对象发送一条 release 消息,可以使引用计数器值-1

  • 当一个对象的引用计数器值为 0 时,那么它将被销毁,

    其占用的内存被系统回收,OC 也会自动向对象发送一
    条 dealloc 消息。一般会重写 dealloc 方法,在这里释
    放相关资源。一定不要直接调用 dealloc 方法。

  • 可以给对象发送 retainCount 消息获得当前的引用计
    数器值。

    (2)内存管理原则

  1. 谁创建,谁释放(“谁污染,谁治理”)。如果你通过
    alloc、new 或者(mutable)copy 来创建一个对象,那么
    你必须调用 release 或 autorelease。或句话说,不是
    你创建的,就不用你去释放

  2. 一般来说,除了 alloc、new 或 copy 之外的方法创建的
    对象都被声明了 autorelease(autorelease 是延迟释

放内存,不用你自己去手动释放,系统会知道在什么时

候该去释放掉它。)

3. 谁 retain,谁 release。只要你调用了 retain,无论

这个对象是如何生成的,你都要调用 release

retain:释放旧的对象,将旧对象的值赋给新对象,新对象
的引用计数加 1,属于指针拷贝。

copy:建立一个索引计数为 1 的对象,然后释放旧对象,新对
象计数加 1,旧对象没有变化。

assign: 简单赋值,不更改索引计数,对基础数据类型 (例
如 NSInteger,CGFloat)和 C 数据类型(int, float, double,
char, 等) 适用简单数据类型。此标记说明设置器直接进
行赋值,这也是默认值。在使用垃圾收集的应用程序中,如
果你要一个属 性使用 assign,且这个类符合 NSCopying 协
议,你就要明确指出这个标记,而不是简单地使用默认值,
否则的话,你将得到一个编译警告。这再次向编译器说明你
确实需要赋值,即使它是 可拷贝的。

release:引用计数减 1,nil 和 release 的区别:nil 就是把
一个对象的指针置为空,只是切断了指针与内存中对象的联

系;而 release 才是真正通知内存释放这个对象。所以 nil
并没有释放内存,只有 release 才会真正释放内存。

autorelease:自动释放对象,引用计数减 1

原理:

a.先建立一个 autorelease pool

b.对象从这个 autorelease pool 里面生成。

c.对象生成 之后调用 autorelease 函数,这个函数的作用
仅仅是在 autorelease pool 中做个标记,让 pool 记得将来
release 一下这个对象。

d.程序结束时,pool 本身也需要 rerlease, 此时 pool 会把
每一个标记为 autorelease 的对象 release 一次。如果某个
对象此时 retain count 大于 1,这个对象还是没有被销毁。

dealloc:对象的引用计数为 0 时调用,arc 里面的 dealloc
方法和 mrc 手动内存管理的区别在于:arc 里面不能调用
super 方法。arc 里面的 dealloc 一般用来注 NSNotification
或者 timer 之类的实例。如果是类里面的强引用,可以在
didReceiveMemoryWarning 置于 nil,如楼 上所说,确实 arc
的内存销毁有滞后性,但是从性能上来说 arc 更优.

4.请简述 self.name = xxx 与_name= xxx 的区别

前者会调用对象的 setName()方法,会使对象引用计数加
1,后者会直接把对象赋值给当前对象的 name 属性,引用
计数不增加。

5. 请简述类别和继承有什么联系和区别
(1)继承

这个是面向对象语言都有的一个特性,子类会继承父类的方
法和属性。
对于以下情况,无法使用类别,必须使用继承。
1)新扩展的方法与原方法同名,但是还需要使用父类的实
现。因为使用类别,会覆盖原类的实现,无法访问到原来的
方法。

2)扩展类的属性,这个类别无法做到。

(2)类别

它是 OC 语言的一个特性,可以在不改变类名和原来类
的实现的前提下,实现对类的方法扩展。以下两种方式
最后使用类别。

1)针对系统提供一些类,例如:
NSString,NSArray,NSNumber 等类,系统本身不提倡
使用继承去扩展方法,因为这些类内部实现对继承有所
限制,所以最后使用类别来进行方法扩展。

2)类别支持开发人员针对自己构建的类,把相关的方
法分组到多个单独的文件中,对于大型而复杂的类,这
有助于提高可维护性,并简化单个源文件的管理。

6.请简述你对 strong 和 weak 关键字的理解

iOS 5 中对属性的设置新增了 strong 和 weak 关键字来修饰
属性,实在 ARC 模式下。

strong 用来修饰强引用的属性;

@property (strong) SomeClass * aObject;

对应原来的

@property (retain) SomeClass * aObject; 和 @property
(copy) SomeClass * aObject;

weak 用来修饰弱引用的属性;

@property (weak) SomeClass * aObject;

对应原来的

@property (assign) SomeClass * aObject;

__weak, __strong 用来修饰变量,此外还有
__unsafe_unretained, __autoreleasing 都是用来修饰变
量的。

__strong 是缺省的关键词。

__weak 声明了一个可以自动 nil 化的弱引用。




使用

方法

ARC 时,需要遵循一定的规则:

不能使用 retain/release/retainCount/autorelease

不能使用 NSAllocateObject/NSDeallocateObject 方

不能显示的调用 dealloc 方法
使用@autoreleasepool 块代替 NSAutoreleasePool
不能使用 NSZone(防止内存碎片化而引入的结构)
显示转换"id"和"void *"

__unsafe_unretained 声明一个弱应用,但是不会自动 nil
化,也就是说,如果所指向的内存区域被释放了,这个指针
就是一个野指针了。

__autoreleasing 用来修饰一个函数的参数,这个参数会在
函数返回的时候被自动释放。

7.请简述 weak 和 assgin 有什么区别

(1)assign:对基础数据类型(NSInteger,CGFloat)和
C 数据类型(int, float, double, char 等),还有 id
类型

(2)weak:ARC 模式下使用, 取代之前的 assign,对象销
毁之后会自动置为 nil,防止野指针。Assign 不能自动

置为 nil,需要手动置为 nil。Delegate 基本总是使用
weak,以防止循环引用。特殊情况是,希望在 dealloc
中调用 delegate 的某些方法进行释放,此时如果使用
weak 将引起异常,因为此时已经是 nil 了,那么采用
assign 更为合适。

8. 如何实现 ARC 和 MRC 的混合编程

iOS5.0 以后就开始可以使用 ARC( Automatic Reference
Counting:自动引用计数 )来代替之前的 MRC(Manual
Reference Counting:人工引用计数)。使用 ARC 会减少很
多代码和忘了释放对象的苦恼。但是事情都有两面性。使用
了 ARC 之后如果你想复用以前写过的使用 MRC 的类, 就会
出报错。这时候怎么办?方法比较简单, 只需要做下面的
一个步骤就可以解决:

在 targets 的 build phases 选项下 Compile Sources 下选
择要不使用 arc 编译的文件,双击它,输入 -fno-objc-arc
即可 MRC 工程中也可以使用 ARC 的类。方法如下:

在 targets 的 build phases 选项下 Compile Sources 下选
择要使用 arc 编译的文件,双击它,输入 -fobjc-arc 即可

9.Objective-c 中是否支持多继承

OC 支持多继承,只要单继承,也就是说某个类只有一个
父类。当单继承不够用,很难为问题域建模时,我们通常都
会直接想到多继承。多继承是从多余一个直接基类派生类的
能力,可以更加直接地为应用程序建模。但是 Objective-C
不支持多继承,由于消息机制名字查找发生在运行时而非编
译时,很难解决多个基类可能导致的二义性问题。不过其实
Objective-C 也无需支持多继承,我们可以找到如下几种间
接实现多继承目的的方法:(1)消息转发 (2)delegate 和
protocol(3)类别

10. Objective-c中变量默认是私有的吗,方法默认
是私有的吗

OC – 类里面的方法只有两种, 静态方法和实例方法.

在类里面声名一个私有方法
@interface MyClass : NSObject

{

NSString *something;

}

+ (void)thisIsAStaticMethod;

– (void)thisIsAnInstanceMethod;

@end

@interface MyClass

(private)

-(void)thisIsAPrivateMethod;
@end

@private 可以用来修饰私有变量

在 Objective‐C 中,所有实例变量默认都是私有的,所有
实例方法默认都是公有的。

11. #import"".h 和@class+类名的区别

(1)import 会包含这个类的所有信息,包括实体变量和方法,
而@class 只告诉编译器,声明的类的名称,至于这些类是如
何定义的,暂时不用考虑,后面会再告诉你,所以在头文件
中如果用@class 声明某个类后,在.m 的实现中如果用到声
明类的具体方法或变量时还得再#import 类

(2)在.h 头文件中进行声明时用#import 的话,如果 100 个
头文件都#import 同一个头件,或者这些文件是依次引用的,
如 A->B,B->C,C->D,当最开始的那个头文件有变化后进行
编译时,后面所有引用它的类都需要重新编译,如果引用最
开始的头文件 的类很多的话,那么这将耗费大量的时间,

而用@class 则不会,可能有人会想即然.h 只是用@class 只
是简单的一个声明告编译器有这个类不让其报错,那么.m 中
要用到引入的类的方法和属性时,不还是要#import 头文件
一次,是的这个是对的,但编译器编译的时候只编译头文件
的,所以你的.m 中 用#import 与编译时间没太大关系

(3)接下来说说什么时候该用@class,什么时候该用#import
进行声明,

a.一般如果有继承关系的用#import,如B是A的子类那么
在B中声明A时用#import

b.另外就是如果有循环依赖关系,如:A->B,B->A 这样相
互依赖时,如果在两个文件的头文件中用#import 分别声明
对方,那么就会出现头文件循环利用的错误,这时在头文件
中用@class 声明就不会出错

c.还有就是自定义代理的时候,如果在头文件中想声明代理
的话如@interface
SecondViewController:UIViewController<XXXDelegate>
时应用#import 不然的话会出错误,注意 XXXDelegate 是自
定义的.

12. 请简述页面传值都有哪些实现方式

属性/初始化/AppDelegate/单例/委托代理/消息
/block 这七种传值方法。

13. 请简述深拷贝和浅拷贝的区别

首先回顾下 copy 和 retain。copy 是创建一个新对象,retain
是创建一个指针,引用对象计数加 1。Copy 属性表示两个对
象内容相同,新的对象 retain 为 1 ,与旧有对象的引用计
数无关,旧有对象没有变化。copy 减少对象对上下文的依
赖。 retain 属性表示两个对象地址相同(建立一个指针,
指针拷贝),内容当然相同,这个对象的 retain 值+1 也就
是说,retain 是指针拷贝,copy 是内容拷贝。而我们说的
深和浅拷贝是针对指针地址来说的,地址相同,就是浅拷贝,
地址不同就是深拷贝。

当然在 ios 中并不是所有的对象都支持 copy,mutableCopy,
遵守 NSCopying 协议的类可以发送 copy 消息,遵守
NSMutableCopying 协议的类才可以发送 mutableCopy 消息。
假如发送了一个没有遵守上诉两协议而发送 copy 或者
mutableCopy,那么就会发生异常。但是默认的 ios 类并没有
遵守这两个协议。如果想自定义一下 copy 那么就必须遵守

NSCopying,并且实现 copyWithZone: 方法,如果想自定义
一下 mutableCopy 那么就必须遵守 NSMutableCopying,并且
实现 mutableCopyWithZone: 方法。

14. 系统中有哪些对象是单例

单例的应用十分普遍, 单例模式使一个类只有一个实
例 。使用单例好处:易于供外界访问;方便控制实例个数 ,
节约系统资源 .

(1)OC 中的 常见单例 : UIApplication
/UIActionSheet/NSNotificationCenter/NSUserDefaults/
NSFIleManager。

(2)应用程序中用到的单例:
背景音乐/音效管理等。

iOS 面试题、知识点 之一的更多相关文章

  1. 《招一个靠谱的移动开发》iOS面试题及详解(下篇)

    iOS面试知识点 现在进入本篇的正题.本篇的面试题是我认为比较好的iOS开发基础知识点,希望大家看过这后在理解的基础上掌握而不是死记硬背.死记硬背很快也会忘记的. 1 iOS基础 1.1 父类实现深拷 ...

  2. 最全的iOS面试题及答案-转载

    1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承:可以实现多个接口,通过实现 ...

  3. IOS面试题总结

    iOS面试题: 一:网络理论知识的理解 1:Internet物理地址和IP地址转换采用什么协议 ARP(Address Resolution Protocol)地址解析协议 2:Internet采用哪 ...

  4. php高级面试题知识点(转载)

    php高级面试题知识点大全 时间:2016-01-26 06:36:22来源:网络 导读:php高级面试题知识点大全,本套面试题内容包括php魔术方法.php单点登录.linux基本命令.前端开发技术 ...

  5. iOS面试题及答案2015.6.7

    iOS面试题及答案     1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承 ...

  6. iOS 面试题 总结

    #include <iostream> using namespace std; int main () { char p[]={'a','b','c'}, q[]="abc&q ...

  7. [转载]iOS面试题总

    转载自:http://blog.sina.com.cn/s/blog_67eb608b0101r6xb.html (2014-06-13 20:23:33) 转载▼ 标签: 转载   crash 原文 ...

  8. 试答卓同学的 iOS 面试题

    卓同学昨天写了一篇文章<4道过滤菜鸟的iOS面试题>.我手痒决定默写一个参考答案.后来发现不认真回答被大家喷成狗,所以决定积极改造,重新做人.下面就是修编之后的答案. 1. struct和 ...

  9. iOS面试题大全-点亮你iOS技能树

    所有的内容大部分来自于网络的搜集,所以我不是一个创造者,而是一个搬运工.我尽量把题目,尤其是参考答案的出处列明.若有任何疑问,建议,意见,请联系我. 第一部分面试题来源于iOS-Developer-I ...

  10. 原 iOS面试题收集

    原 iOS面试题收集 发表于2年前(2013-07-22 13:47)   阅读(369) | 评论(0) 4人收藏此文章, 我要收藏 赞0 听云性能监测产品App.Server.CDN免费试用,绑定 ...

随机推荐

  1. install plugin group_replication ERROR 1126 (HY000)

    在给MySQL安装插件的时候,你可能会遇到如题所示的报错. 更详细的错误输出如下: mysql> INSTALL PLUGIN group_replication SONAME 'group_r ...

  2. 初窥 MongoDB

    最近在研究Nodejs 自然就接触到了MongoDB  这玩意儿有意思  与关系型数据库相比少了很多条条框框 让我情不自禁的想要了解它的所有 MongoDB与Redis同类 属于NoSql的一种,特点 ...

  3. Python 面向对象(一) 基础

    Python 中一切皆对象 什么是面向对象? 面向对象就是将一些事物的共有特征抽象成类,从类来创建实例. 类class 可以理解为模版 比如人类,都具有身高.体重.年龄.性别.籍贯...等属性,但属性 ...

  4. 《java.util.concurrent 包源码阅读》27 Phaser 第一部分

    Phaser是JDK7新添加的线程同步辅助类,作用同CyclicBarrier,CountDownLatch类似,但是使用起来更加灵活: 1. Parties是动态的. 2. Phaser支持树状结构 ...

  5. 使用map做数组与链表去重

    #include<iostream> #include<map> using namespace std; class node{ public: node():value() ...

  6. 前端测试框架Jest系列教程 -- Asynchronous(测试异步代码)

    写在前面: 在JavaScript代码中,异步运行是很常见的.当你有异步运行的代码时,Jest需要知道它测试的代码何时完成,然后才能继续进行另一个测试.Jest提供了几种方法来处理这个问题. 测试异步 ...

  7. MYSQL 主从复制---简单易学

    本帖最后由 传说中的草包 于 2017-4-12 09:12 编辑为什么要用mysql主从复制? 这个问题不需要回答吧,,,,,想想,一个人干活快呢,还是一万个能性格功力一样的人干活快呢. 不用解释大 ...

  8. PHP获取路径或目录实现

    <?php /**  * PHP获取路径或目录实现  */    //魔术变量,获取当前文件的绝对路径 echo "__FILE__: ========> ".__FI ...

  9. appium+Linux环境安装配置

      背景:想要在Jenkins上跑appium的自动化测试,所以想要在Jenkins服务器(Linux远程)上安装appium服务,故而研究了一下appium+Linux下安装.虽然有无数的前辈踩过坑 ...

  10. PHP 静态缓存

    今天来说说PHP页面的静态缓存. 根据个人理解,由于客户端重复的请求某个页面,导致该页面短时间内被重复请求相同的数据,导致给服务端一定的压力,同时用户访问速度也会变慢.此时如果把这个页面缓存起来,客户 ...