项目架构
一、Tomcat实际上是一个servlet容器?
servlet其实就是一个运行在服务端的程序,专门用来处理用户端的请求并响应给用户。而Tomcat可以理解是一个servlet容器,用来处理不同的服务。在Tomcat中,servlet容器从外层到内层可以分为以下几层:
Engine->Host->Context->Wrapper
Host在Tomcat中表示虚拟主机,处理时Tomcat会根据请求的域名进入到能够响应处理的Host中,而一个虚拟主机中有多个context web应用,最后一个web应用包含有多个Wrapper servlet容器。(一个Wrapper对应一个servlet容器之外,还包括一个Filter和pool)
其中每级容器下都有一个Pipeline管道,而每个管道中都有多个Valve阀门,每个管道中最后一个阀门Valve的作用就是根据Request,来告诉当前servlet容器把请求转发给下级的哪个servlet处理。
二、什么是门面模式?
一般我们使用servlet实现doGet()方法中,都会继承一个HTTPServletRequest接口,执行doGet传过来的实例并不是Request对象,而是它的门面RequestFacade对象[fəˈsɑːd]。因为Request对象很多方法都是供内部组件进行交互使用的,不适合暴露给外部,因此通过一个门面类,来将内部组件交互的方法屏蔽。(Tomcat的实现类RequestFacade实现了HTTPServletRequest接口,但其实requestFacade类里面是通过request对象进行操作的,类似于代理模式)
public calss RequestFacade implements HTTPServletRequest{
protected Request request=null;
}
门面模式设计的意义在于,子系统之间涉及相互通信,它们一些方法设置为public,但是又不希望对外公开,因此子系统就会设计一个门面,把外系统感兴趣的数据封装起来,通过门面访问。
public class TestServlet extends HTTPServlet{
public void doGet(HTTPServletRequest request,HTTPServletResponse response)
throws IOException
{
}
}
三、应用部署?war包和jar包区别?web.xml和server.xml配置什么?
1.部署方式有三种:
①描述符部署:可以在servlet.xml中定义<context path=“应用的名字” docBase="项目文件夹的路径">
②war包部署
③文件夹部署:主动把应用的.class文件放到Tomcat文件夹下。
2.war包和jar包区别?
war包放到webapps文件下可以直接部署应用。jar包打包到webapps下时,Tomcat不知道它是一个应用还是依赖。
3.web.xml用来配置url和对应使用哪个servlet处理请求的映射。
server.xml可以修改Tomcat默认端口,定义context节点部署web应用
四、tomcat容器是如何创建servlet类实例?
当Tomcat容器启动时,首先查看webapps文件下所有应用的web.xml文件,把里面注册的url-servlet映射的所有servlet类进行类加载,然后先查看缓存池是否已经存在Servlet对象,否则通过反射机制实例化(分懒汉式和饿汉式)。注意servlet对象采用了单例模式。
五、什么是观察者模式?
当一个对象实体状态改变时,所有依赖于它的观察者对象都会得到通知,并自动更新。用于一对多依赖关系。
Tomcat中生命周期管理使用的就是观察者模式。
补充
一、Redis持久化机制是什么?
Redis的数据全部放在内存,数据查询都是内存操作因此非常快速。因此若突然宕机,就会导致数据全部丢失。Redis持久化机制有两种:
1.RDB快照:Redis在某个时间点上会把数据保存到一个RDB文件中,它是一个经过压缩的二进制文件。Redis可以通过RDB文件把数据还原到Redis中。但是安全性不如AOF。
2.AOF:每次对Redis进行修改,都会把写命令保存到一个AOF文件中。Redis只需要重新执行一遍AOF中的写命令就可以恢复数据。实现时通过服务器创建一个没有网络连接的伪客户端(因为Redis命令只能在客户端上下文中进行),然后从AOF文件读一条指令,并写入到Redis中,不断重复。
缺点在于AOF的文件体积可能会越来越大,比如不断对同一条记录添加删除添加删除,因此Redis提供了AOF重写来减小AOF文件体积。
系统优先使用AOF持久化进行数据复原;若AOF关闭则使用RDB文件进行还原。
二、CopyOnWriteArrayList用于什么场景?
CopyOnWriteArrayList容器写操作时,会复制一个数组副本,在副本上进行修改数据,此时可以对原数组继续无锁读操作。写操作完成之后,就把旧容器引用指向副本数组。
缺点在于仅能保证最终一致性,而不能保证强一致性(写过程读会读到旧数据)。并且需要另外开辟内存空间。
一般用于读多写少场景,比如白名单黑名单。
三、为什么wait,notify方法不定义在thread中?
因为java的锁是对象级的,对象通过线程获得锁,锁是属于对象的。如果定义在thread中,那么线程等待的是哪的锁就不是很明确。
今日总结
学习,给导师发邮件