Java面试题整理html
一、SpringMVC的执行流程前端
- 用户发送请求至前端控制器DispatcherServlet
- DispatcherServlet收到请求调用HandlerMapping处理器映射器。
- 处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(若是有则生成)一并返回给DispatcherServlet。
- DispatcherServlet调用HandlerAdapter处理器适配器
- HandlerAdapter通过适配调用具体的处理器(Controller,也叫后端控制器)。
- Controller执行完成返回ModelAndView
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器
- ViewReslover解析后返回具体View
- DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet响应用户
二、JVM内存溢出具体指哪些内存溢出?都会抛出什么异常?java
- JVM管理两种类型的内存,堆和非堆。堆是在 Java 虚拟机启动时建立的。简单来讲堆就是留给开发人员使用的;非堆就是JVM留给本身用的,运行期内GC不会释放其空间。
- 堆内存的分配使用
-Xms
和-Xmx
两个参数指定,默认值分别是系统内存的1/64
和1/4
。默认空余堆内存小于40%
时,JVM就会增大堆直到-Xmx
的最大限制;空余堆内存大于70%
时,JVM会减小堆直到-Xms
的最小限制。所以服务器通常设置-Xms、 -Xmx
相等以免在每次GC 后调整堆的大小。通常的要将-Xms
和-Xmx
选项设置为相同,而-Xmn
为1/4
的-Xmx
值,建议堆的最大值设置为可用内存的最大值的80%
。堆的最大值受限于系统使用的物理内存。- 非堆内存也叫永久保留区域,用于存放
Class
和Meta
信息。
三、String类为何是不可变类?面试
- 缓存池
- hashcode
- 多线程中不肯定值
四、经常使用JVM设置参数有哪些?redis
- -Xms 设置JVM最小可用内存
- -Xmx 设置JVM最大可用内存
- -Xmn 设置年轻代大小
- -Xss 设置每一个线程的堆栈大小(在相同物理内存下,减少这个值能生成更多的线程。可是也不能无限生成,最多3000~5000个)
- -XX:NewRatio 设置年轻代(包括Eden和两个Survivor区)与年老代的比值。(设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5)
- -XX:SurvivorRatio 设置年轻代中Eden区与Survivor区的大小比值(设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6)
- -XX:MaxPermSize 设置持久代大小
- -XX:MaxTenuringThreshold 设置垃圾最大年龄(若是设置为0的话,则年轻代对象不通过Survivor区,直接进入年老代。对于年老代比较多的应用,能够提升效率.若是将此值设置为一个较大值,则年轻代对象会在Survivor区进行屡次复制,这样能够增长对象再年轻代的存活时间,增长在年轻代即被回收的概论)
五、谈谈Spring事物传播特性算法
REQUIRED
若是存在一个事务,则支持当前事务。若是没有事务则开启一个新的事务MANDATORY
支持当前事务,若是当前没有事务,就抛出异常NEVER
以非事务方式执行,若是当前存在事务,则抛出异常NOT_SUPPORTED
以非事务方式执行操做,若是当前存在事务,就把当前事务挂起REQUIRES_NEW
新建事务,若是当前存在事务,把当前事务挂起SUPPORTS
支持当前事务,若是当前没有事务,就以非事务方式执行NESTED
支持当前事务,新增Save Point点,与当前事务同步提交或回滚。
嵌套事务一个很是重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所作的动做。而内层事务操做失败并不会引发外层事务的回滚NESTED
与REQUIRES_NEW
的区别 ?
- 它们很是 相似,都像一个嵌套事务,若是不存在一个活动的事务,都会开启一个新的事务。
- 使用
PROPAGATION_REQUIRES_NEW
时,内层事务与外层事务就像两个独立的事务同样,一旦内层事务进行了提交后,外层事务不能对其进行回滚。两个事务互不影响。两个事务不是一个真正的嵌套事务。同时它须要JTA
事务管理器的支持。- 使用
PROPAGATION_NESTED
时,外层事务的回滚能够引发内层事务的回滚。而内层事务的异常并不会致使外层事务的回滚,它是一个真正的嵌套事务。
六、MySql索引的类型和实现方式?sql
七、Tomcat请求的处理流程?shell
八、如何防止Sql注入?数据库
‘or 1 = 1 –
sql
拼接九、谈谈HashMap、ConcurrnetHashMapjson
HashMap
null
key和 null
valuefail-fast
机制,多线程修改会产生ConcurrentModificationException
)Hashtable
和Collections.synchronizedMap(hashMap)
,不过这两个方案基本上是对读写进行加锁操做,一个线程在读写元素,其他线程必须等待,性能可想而知。ConcurrnetHashMap 占小狼的博客
不容许null
的key和value
Jdk1.7
jdk1.8
抛弃了Segment
分段锁机制。利用CAS
+Synchronized
来保证并发更新的安全,底层采用数组+链表+红黑树的存储结构;
Node[] table:默认为null,初始化发生在第一次插入操做(initTable
方法),默认大小为16
的数组,用来存储Node节点数据,扩容时大小老是2的幂次方
nextTable:默认为null,扩容时新生成的数组,其大小为原数组的两倍;
sizeCtl :默认为0,用来控制table的初始化和扩容操做;
Node:保存key
,value
及key
的hash
值的数据结构。其中value
和next
都用volatile
修饰,保证并发的可见性。
class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; volatile V val; volatile Node<K,V> next; ...... }
table初始化
Unsafe.compareAndSwapInt
方法去修改sizeCtl的值为-1
,有且只有一个线程可以修改为功,其它线程经过Thread.yield()让出CPU时间片等待table初始化完成。put
操做
CAS
+synchronized
实现并发插入或更新操做spread
方法计算hashcode值(n - 1) & hash
定位table
数组索引位置Unsafe.getObjectVolatile
方法获取table
中对应的索引到元素fnull
,说明table
中这个位置第一次插入元素,利用Unsafe.compareAndSwapObject
方法插入Node节点。若是CAS成功,说明Node节点已经插入,随后addCount(1L, binCount)
方法会检查当前容量是否须要进行扩容。若是CAS失败,说明有其它线程提早插入了节点,自旋从新尝试
在这个位置插入节点。十、JVM GC(minor gc,full gc)
JVM垃圾算法:
- 引用计数法(循环引用问题)
- 可达性分析(思路就是经过一系列名为GC Roots**的对象做为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证实此对象是不可用的)。Java中能够被做为GC Roots中的对象有:
- 虚拟机栈(栈桢中的本地变量表)中的引用的对象
- 方法区中的类静态属性引用的对象
- 方法区中的常量引用的对象
- 本地方法栈中JNI(Native方法)的引用的对象
垃圾回收算法:
- 标记-清除算法(Mark-Sweep) 【会产生大量碎片】
- 复制算法(Copying) 【内存被压缩一半,效率低】
- 标记-整理算法(Mark-Compact) 【将存活对象移向内存的一端。而后清除端边界外的对象】
- 分代收集算法(Generational Collection)
- 新生代(复制算法,年龄>15就被移动到老生代中)
- Eden
- Survivor 0(From),Survivor 1(To)
- Young GC ,也叫 Minor GC
- 触发条件:
- 新生代采用“空闲指针”的方式来控制GC触发,指针保持最后一个在新生代分配的对象位置,当有新的对象要分配内存时,用于检查空间是否足够,不够就触发GC
- 老生代(标记-整理算法,通常通过2次以上标记)
- Full GC ,也叫Major GC
- 触发条件:
- 老生代空间不足(避免建立过大对象)
- Pemanet Generation空间不足 (增大Perm Gen空间,避免太多静态对象)
- GC后晋升到老生代的平均大小大于老生代剩余空间 (控制好新生代和旧生代的比例)
- 手动调用System.gc();(垃圾回收不要手动触发,尽可能依靠JVM自身的机制)
垃圾回收器 :
[参考文章]:
十一、什么CAS,什么是ABA问题,如何解决?
- CAS(Compare and Swap),比较并交换,实现并发算法时经常使用到的一种技术
- CAS的思想很简单:三个参数,一个当前内存值V、旧的预期值A、即将更新的值B,当且仅当预期值A和内存值V相同时,将内存值修改成B并返回true,不然什么都不作,并返回false。
- 若是变量V初次读取的时候是A,而且在准备赋值的时候检查到它仍然是A。若是在这段期间曾经被改为B,而后又改回A,那CAS操做就会误认为它历来没有被修改过。针对这种状况,java并发包中提供了一个带有标记的原子引用类
AtomicStampedReference
,它能够经过控制变量值的版原本保证CAS的正确性。
十二、Spring中的IOC和AOP是如何实现的?
- IOC是使用Java的反射机制实现的
- AOP是根据动态代理机制实现的
1三、什么是SpringBeans?
具体说来,它是被Spring框架容器初始化、配置和管理的对象。
1四、说说Dubbo的内部实现原理?
1五、了解Netty么?
1六、说说什么是NIO、AIO?
1七、经常使用的设计模式及好处?
1八、Java IO中常用的类?
1九、了解Java中的线程池么?
20、Java中都有哪些锁?
2一、MySql数据库都有哪些引擎?它们的区别是什么?
2二、谈谈MySql索引的类型和实现方式?
- 惟一索引 惟一索引是不容许其中任何两行具备相同索引值的索引。当现有数据中存在重复的键值时,大多数数据库不容许将新建立的惟一索引与表一块儿保存。数据库还可能防止添加将在表中建立重复键值的新数据。例如,若是在employee表中职员的姓(lname)上建立了惟一索引,则任何两个员工都不能同姓。
- 主键索引 数据库表常常有一列或列组合,其值惟一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动建立主键索引,主键索引是惟一索引的特定类型。该索引要求主键中的每一个值都惟一。当在查询中使用主键索引时,它还容许对数据的快速访问。
- 汇集索引 在汇集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个汇集索引。
2三、MySql慢查询如何定位和优化?
2四、JVM内置了哪些垃圾回收器?
2五、什么是Fail-Fast、Fail-Safe模式?
2六、说说ThreadLocal
2七、知道volatile关键字么?
- 内存可见性
- 禁止指令重排
- 不能保证原子性
内存可见性:通俗来讲就是,线程A对一个volatile变量的修改,对于其它线程来讲是可见的,即线程每次获取volatile变量的值都是最新的。
不能保证原子性
操做普通变量的流程
读操做会优先读取工做内存的数据,若是工做内存中不存在,则从主内存中拷贝一份数据到工做内存中;写操做只会修改工做内存的副本数据,这种状况下,其它线程就没法读取变量的最新值。
volatile关键字修饰的变量
对于volatile变量,读操做时JMM会把工做内存中对应的值设为无效,要求线程从主内存中读取数据;写操做时JMM会把工做内存中对应的数据刷新到主内存中,这种状况下,其它线程就能够读取变量的最新值。
2八、synchronized关键字
2九、使用过SpringCloud么?
30、知道AQS(同步器)么?
3一、Spring事物的隔离级别?
3二、MyBatis的执行流程?
3三、Linux经常使用命令
3四、Redis的数据类型、经常使用命令和使用场景?
Redis
经常使用的数据类型有:String
、List
、Set
、Sorted Set
、Hash
- 操做
KEY
经常使用命令:
DEL
key 若是存在删除键DUMP
key 返回存储在指定键的值的序列化版本EXISTS
key 此命令检查该键是否存在EXPIRE
key seconds 指定键的过时时间EXPIREAT
key timestamp 指定的键过时时间。在这里,时间是在Unix时间戳格式PEXPIRE
key milliseconds 设置键以毫秒为单位到期PEXPIREAT
key milliseconds-timestamp 设置键在Unix时间戳指定为毫秒到期KEYS
pattern 查找与指定模式匹配的全部键MOVE
key db 移动键到另外一个数据库PERSIST
key 移除过时的键PTTL
key 以毫秒为单位获取剩余时间的到期键。TTL
key 获取键到期的剩余时间。RANDOMKEY
从Redis返回随机键RENAME
key newkey 更改键的名称RENAMENX
key newkey 重命名键,若是新的键不存在TYPE
key 返回存储在键的数据类型的值。- String
- 使用场景:普通单值存储、
JSON
格式存储、数字存储- 经常使用命令:
SET
、GET
、MSET
、MGET
、SETEX
、SETNX
、INCR
、INCRBY
、APPEND
- List 【双向链表,列表的最大长度为2^32 - 1,也即每一个列表支持超过40亿个元素】
- 使用场景:关注列表、粉丝列表。轻量级消息队列,生产者
push
,消费者pop/bpop
。- 经常使用命令:
BLPOP
BLPOP key1 [key2 ] timeout
取出并获取列表中的第一个元素,或阻塞,直到有可用BRPOP
BRPOP key1 [key2 ] timeout
取出并获取列表中的最后一个元素,或阻塞,直到有可用BRPOPLPUSH
BRPOPLPUSH source destination timeout
从列表中弹出一个值,它推到另外一个列表并返回它;或阻塞,直到有可用LINDEX
LINDEX key index
从一个列表其索引获取对应的元素LINSERT
LINSERT key BEFORE|AFTER pivot value
在列表中的其余元素以后或以前插入一个元素LLEN
LLEN key
获取列表的长度LPOP
LPOP key
获取并取出列表中的第一个元素LPUSH
LPUSH key value1 [value2]
在前面加上一个或多个值的列表LPUSHX
LPUSHX key value
在前面加上一个值列表,仅当列表中存在LRANGE
LRANGE key start stop
从一个列表获取各类元素LREM
LREM key count value
从列表中删除元素LSET
LSET key index value
在列表中的索引设置一个元素的值LTRIM
LTRIM key start stop
修剪列表到指定的范围内RPOP
RPOP key
取出并获取列表中的最后一个元素RPOPLPUSH
RPOPLPUSH source destination
删除最后一个元素的列表,将其附加到另外一个列表并返回它RPUSH
RPUSH key value1 [value2]
添加一个或多个值到列表RPUSHX
RPUSHX key value
添加一个值列表,仅当列表中存在- Hash【Redis Hash对应Value内部实际就是一个HashMap,这个Hash的成员比较少时Redis为了节省内存会采用相似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构】
- 使用场景:假设有多个用户及对应的用户信息,能够用来存储以用户ID为key,将用户信息序列化为好比json格式作为value进行保存
- 经常使用命令:
HDEL
HDEL key field[field...]
删除对象的一个或几个属性域,不存在的属性将被忽略HEXISTS
HEXISTS key field
查看对象是否存在该属性域HGET
HGET key field
获取对象中该field属性域的值HGETALL
HGETALL key
获取对象的全部属性域和值HINCRBY
HINCRBY key field value
将该对象中指定域的值增长给定的value,原子自增操做,只能是integer的属性值可使用HINCRBYFLOAT
HINCRBYFLOAT key field increment
将该对象中指定域的值增长给定的浮点数HKEYS
HKEYS key
获取对象的全部属性字段HVALS
HVALS key
获取对象的全部属性值HLEN
HLEN key
获取对象的全部属性字段的总数HMGET
HMGET key field[field...]
获取对象的一个或多个指定字段的值HSET
HSET key field value
设置对象指定字段的值HMSET
HMSET key field value [field value ...]
同时设置对象中一个或多个字段的值HSETNX
HSETNX key field value
只在对象不存在指定的字段时才设置字段的值HSTRLEN
HSTRLEN key field
返回对象指定field的value的字符串长度,若是该对象或者field不存在,返回0.HSCAN
HSCAN key cursor [MATCH pattern][COUNT count]
相似SCAN
命令- Set
- 使用场景:微博应用中,每一个用户关注的人存在一个集合中,就很容易实现求两我的的共同好友功能。
- 经常使用命令:
SADD
SADD key member [member ...]
添加一个或者多个元素到集合(set)里SACRD
SCARD key
获取集合里面的元素数量SDIFF
SDIFF key [key ...]
得到队列不存在的元素SDIFFSTORE
SDIFFSTORE destination key [key ...]
得到队列不存在的元素,并存储在一个关键的结果集SINTER
SINTER key [key ...]
得到两个集合的交集SINTERSTORE
SINTERSTORE destination key [key ...]
得到两个集合的交集,并存储在一个集合中SISMEMBER
SISMEMBER key member
肯定一个给定的值是一个集合的成员SMEMBERS
SMEMBERS key
获取集合里面的全部keySMOVE
SMOVE source destination member
移动集合里面的一个key到另外一个集合SPOP
SPOP key [count]
获取并删除一个集合里面的元素SRANDMEMBER
SRANDMEMBER key [count]
从集合里面随机获取一个元素SREM
SREM key member [member ...]
从集合里删除一个或多个元素,不存在的元素会被忽略SUNION
SUNION key [key ...]
添加多个set元素SUNIONSTORE
SUNIONSTORE destination key [key ...]
合并set元素,并将结果存入新的set里面SSCAN
SSCAN key cursor [MATCH pattern] [COUNT count]
迭代set
里面的元素[参考连接]
3五、微服务中如何保证数据的一致性?
- 一、同步事件服务,经过发送同步消息通知来保证
- 二、异步事件服务
- 三、外部事件服务(额外的网络通讯)
- 四、可靠事件通知(1. 事件的正确发送; 2. 事件的重复消费。)
- 五、业务补偿机制(数据一致性的时效性很低,多个服务经常可能处于数据不一致的状况。)
- 六、TCC(try、confirm、cancel)
3六、ZooKeeper的使用场景?
3七、经常使用数据结构及其实现?
3八、Docker/区块链
3九、什么状况下会产生死锁?
40、Redis有哪几种数据淘汰策略?【redis 每服务客户端执行一个命令的时候,会检测使用的内存是否超额。若是超额,即进行数据淘汰。】
- volatile-lru:从已设置过时时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
- volatile-ttl:从已设置过时时间的数据集(server.db[i].expires)中挑选将要过时的数据淘汰
- volatile-random:从已设置过时时间的数据集(server.db[i].expires)中任意选择数据淘汰
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
- no-enviction(驱逐):禁止驱逐数据
4一、Redis一个字符串类型的值能存储最大容量是多少?
- 根据Redis官网的说法,应该是521MBMB。其他的(list、set、hash)都是2的32次方。
4二、Redis集群方案应该怎么作?都有哪些方案?
4三、消息队列的实现原理?
4四、说说类的加载顺序?
- 父类的static静态代码块
- 子类的static静态代码块
- 类内部变量
- 静态成员类
- 普通成员类
4五、并发包下都用过哪些类?
4六、Redis持久化方式?
4七、Linux下Redis安装
- mkdir -p /usr/local/src/redis
- cd /usr/local/src/redis
- wget http://download.redis.io/releases/redis-2.8.11.tar.gz
- tar xzfredis-2.8.11.tar.gz
- cdredis-2.8.11
- make
- makeinstall
- 修改配置文件,使用redis后台运行:
- vi /etc/redis.conf
- daemonize yes
- 启动
- redis-server/etc/redis.conf
4八、Redis事物是如何实现的?
Redis事务一般会使用
MULTI,EXEC,WATCH
等命令来完成watch指令在redis事物中提供了CAS的行为。为了检测被watch的keys在是否有多个clients同时改变引发冲突,这些keys将会被监控。若是至少有一个被监控的key在执行exec命令前被修改,整个事物不执行任何动做,从而保证原子性操做,而且执行exec会获得null的结果。
4九、Redis主从、集群?
50、TCP/IP三次握手、四次挥手
5一、流量控制与滑动窗口?
5二、什么状况下索引会失效?
5三、什么是动态代理,都有哪些方式?
5四、知道一致性hash么?
5五、数据库的锁(行锁,表锁,页级锁,意向锁,读锁,写锁,悲观锁,乐观锁,以及加锁的select sql方式)
5六、Java的线程模型?
使用一对一的线程模型实现的,一条Java线程就映射到一条轻量级进程之中。
Java线程调度:线程调度是指系统为线程分配处理器使用权的过程
协同式调度
线程的执行时间由线程自己来控制,线程把本身的工做执行完了以后,要主动通知系统切换到另一个线程上。
抢占式调度(Java使用的线程调度方式就是抢占式调度)
那么每一个线程将由系统来分配执行时间,线程的切换不禁线程自己来决定(在Java中,Thread.yield()可让出执行时间,可是要获取执行时间的话,线程自己是没有什么办法的)
线程优先级(1-10,可设置,不靠谱)
Java线程的状态
Java语言定义了5种线程状态,在任意一个时间点,一个线程只能有且只有其中的一种状态,这5种状态分别以下。
新建(New):建立后还没有启动的线程处于这种状态。
运行(Runable):Runable包括了操做系统线程状态中的Running和Ready,也就是处于此状态的线程有可能正在执行,也有可能正在等待着CPU为它分配执行时间。
无限期等待(Waiting):处于这种状态的线程不会被分配CPU执行时间,它们要等待被其余线程显式地唤醒。
如下方法会让线程陷入无限期的等待状态:
没有设置Timeout参数的Object.wait()方法。
LockSupport.park()方法。
如下方法会让线程进入限期等待状态:
Thread.sleep()方法。
LockSupport.parkUntil()方法。
5七、Java中如何序列化一个对象?
//序列化: ObjectOutputStream os = new ObjectOutputStream( new FileOutputStream("C:/wxp.txt")); os.writeObject(user); os.close(); //反序列化 ObjectInputStream is = new ObjectInputStream( new FileInputStream("C:/wxp.txt")); User temp = (User) is.readObject();
5八、Java中多态的实现机制?
5九、数据库三范式是什么?
答案一:
答案二:
第一范式(1NF):
数据表中的每一列(字段),必须是不可拆分的最小单元,也就是确保每一列的原子性。
例如: userInfo: '山东省烟台市 1318162008' 依照第一范式必须拆分红userInfo: '山东省烟台市' userTel: '1318162008'两个字段
第二范式(2NF):
知足1NF后要求表中的全部列,都必需依赖于主键,而不能有 任何一列与主键没有关系(一个表只描述一件事情)。例如:订单表只能描述订单相关的信息,因此全部的字段都必须与订单ID相关。
产品表只能描述产品相关的信息,因此全部的字段都必须与产品ID相关。所以在同一张表中不能同时出现订单信息与产品信息。
第三范式(3NF):
知足2NF后,要求:表中的每一列都要与主键直接相关,而不是间接相关(表中的每一列只能依赖于主键)
例如:订单表中须要有客户相关信息,在分离出客户表以后,订单表中只须要有一个用户ID便可,而不能有其余的客户信息,由于其余的用户信息是直接关联于用户ID,而不是关联于订单ID。
60、数据库ACID
6一、Redis高级应用及技巧
6二、MyBatis原理
6三、MQ的原理
6四、Tomcat Server处理一个http请求的过程
假设来自客户的请求为:
http://localhost:8080/wsota/wsota_index.jsp
1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector得到
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine得到请求localhost/wsota/wsota_index.jsp,匹配它所拥有的全部虚拟主机Host
4) Engine匹配到名为localhost的Host(即便匹配不到也把请求交给该Host处理,由于该Host被定义为该Engine的默认主机)
5) localhost Host得到请求/wsota/wsota_index.jsp,匹配它所拥有的全部Context
6) Host匹配到路径为/wsota的Context(若是匹配不到就把该请求交给路径名为”"的Context去处理)
7) path=”/wsota”的Context得到请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,做为参数调用JspServlet的doGet或doPost方法
10)Context把执行完了以后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector
13)Connector把HttpServletResponse对象返回给客户browser
6五、