1、关系数据库中连接池的机制是什么?
前提: 为数据库连接建立一个缓冲池。 (1)从连接池获取或创建可用连接。 (2)使用完毕之后,把连接返回给连接池。 (3)在系统关闭前,断开所有连接并释放连接占用的系统资源。 (4)能够处理无效连接,限制连接池中的连接总数不低于或者不超过某个限定值。
其中有几个概念: 最小连接数 是连接池一直保持的数据连接。如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费掉。
最大连接数 是连接池能申请的最大连接数。如果数据连接请求超过此数,后面的数据连接请求将被加入到等待队列中,这会影响之后的数据库操作。 如果最小连接数与最大连接数相差太大,那么,最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。 上面的解释,可以这样理解:数据库池连接数量一直保持一个不少于最小连接数的数量,当数量不够时,数据库会创建一些连接,直到一个最大连接数,之后连接数据库就会等待。
2、SQL的select 语句完整的执行顺序
SQL Select 语句完整的执行顺序: (1)from子句组装来自不同数据源的数据;
(2)where子句基于指定的条件对记录行进行筛选;
(3)group by子句将数据划分为多个分组;
(4)使用聚集函数进行计算;
(5)使用having子句筛选分组;
(6)计算所有的表达式;
(7)select的字段;
(8)使用order by对结果集进行排序。
3、MySQL性能优化
(1)尽量选择较小的列。
(2)将where中用的比较频繁的字段建立索引。
(3)select子句中避免使用‘*!。
(4)避免在索引列上使用计算、notin和>等操作。
(5)当只需要一行数据的时候使用limit 1。
(6)保证单表数据不超过200W,适时分割表。针对查询较慢的语句,可以使用explain来分析该语句具体的执行情况。
(7)避免改变索引列的类型。
(8)选择最有效的表名顺序,from字句中写在最后的表是基础表,将被最先处理,在from子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。
(9)避免在索引列上面进行计算。
(10)尽量缩小子查询的结果。
4、delete、drop、truncate区别
(1)delete和truncate仅仅删除表数据,drop连表数据和表结构一起删除,打个比方,delete是单杀,truncate是团灭,drop是把电脑摔了。 (2)delete是DML语句,操作完以后如果没有不想提交事务还可以回滚,truncate和drop是DDL语句,操作完马上生效,不能回滚,打个比方,delete是发微信说分手,后悔还可以撤回,truncate和drop是直接扇耳光说滚,不能反悔。 (3)执行的速度上,drop>truncate>delete,打个比方,drop是神舟火箭,truncate是和谐号动车,delete是自行车。
5、一张表里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把mysql重启,再insert一条记录,这条记录的ID是18还是15?
一般情况下,我们创建的表的类型是InnoDB,如果新增一条记录(不重启mysql的情况下),这条记录的id是18;但是如果重启(文中提到的)MySQL的话,这条记录的ID是15。因为InnoDB表只把自增主键的最大ID记录到内存中,所以重启数据库或者对表OPTIMIZE操作,都会使最大ID丢失。 但是,如果我们使用表的类型是MylSAM,那么这条记录的ID就是18。因为MylSAM表会把自增主键的最大ID记录到数据文件里面,重启MYSQL后,自增主键的最大ID也不会丢失。 注:如果在这17条记录里面删除的是中间的几个记录(比如删除的是10,11,12三条记录),重启MySOL数据库后,insert一条记录后,ID都是18。因为内存或者数据库文件存储都是自增主键最大ID。
6、时间字段用什么类型?
(1)varchar: 如果用varchar类型来存时间,优点在于显示直观。但是坑的地方也是挺多的。比如,插入的数据没有校验,你可能某天就发现一条数据为2013111的数据,请问这是代表2013年1月11日,还是2013年11月1日? 其次,做时间比较运算,你需要用STR TO DATE等函数将其转化为时间类型,你会发现这么写是无法命中索引的。数据量一大,是个坑!
(2)timestamp: 该类型是四个字节的整数,它能表示的时间范围为1970-01-0108:00:01到2038-01-19 11:14:07。2038年以后的时间,是无法用timestamp类型存储的。 但是它有一个优势,timestamp类型是带有时区信息的。一旦你系统中的时区发生改变,例如你修改了时区SET TIME ZONE="america/new york";你会发现,项目中的该字段的值自己会发生变更。这个特性用来做一些国际化大项目,跨时区的应用时,特别注意!
(3)datetime: datetime储存占用8个字节,它存储的时间范围为1000-01-0100:00:00~9999-12-3123:59:59。显然,存储时间范围更大。但是它坑的地方在于,他存储的是时间绝对值,不带有时区信息。如果你改变数据库的时区,该项的值不会自己发生变更!
(4)bigint: 也是8个字节,自己维护一个时间戳,表示范围比timestamp大多了,就是要自己维护,不大方便。
7、Cookie和Session的区别
Cookie是web服务器发送给浏览器的一块信息,浏览器会在本地一个文件中给每个web服务器存储 cookie。以后浏览器再给特定的web服务器发送请求时,同时会发送所有为该服务器存储的cookie。 Session 是存储在web服务器端的一块信息。session对象存储特定用户会话所需的属性及配置信息。当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
Cookie 和session的不同点: (1)无论客户端做怎样的设置,session都能够正常工作。当客户端禁用cookie 时将无法使用cookie。 (2)在存储的数据量方面:session能够存储任意的java对象,cookie只能存储 String类型的对象。
8、什么是jsp,什么是Servlet?jsp和Servlet有什么区别?
jsp本质上就是一个Servlet,它是Servlet的一种特殊形式(由SUN公司推出),每个jsp页面都是一个servlet实例。 Servlet 是由Java提供用于开发web服务器应用程序的一个组件,运行在服务端,由servlet容器管理,用来生成动态内容。一个servlet 实例是实现了特殊接口Servlet的Java类,所有自定义的servlet均必须实现Servlet接口。
区别: jsp是html页面中内嵌的Java代码,侧重页面显示; Servlet 是html代码和Java代码分离,侧重逻辑控制,mvc设计思想中jsp位于视图层,servlet 位于控制层Jsp运行机制:
如下图
JVM只能识别Java类,并不能识别jsp代码。web容器收到以.jsp为扩展名的url请求时,会将访问请求交给tomcat中jsp引擎处理,每个jsp页面第一次被访问时,jsp引擎将jsp代码解释为一个servlet源程序,接着编译 servlet 源程序生成.class文件,再有web容器servlet 引擎去装载执行servlet程序,实现页面交互。
9、servlet生命周期
Servlet 加载一>实例化一>服务一>销毁。
9.1 生命周期详解:
init(): 在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。
service(): 它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。 在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。
destroy(): 仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。 一个Servlet 在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。
9.2 如何与Tomcat 结合工作步骤:
(1)Web Client 向Servlet容器(Tomcat)发出Http请求。
(2)Servlet 容器接收Web Client的请求。
(3)Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。
(4)Servlet容器创建一个HttpResponse对象。
(5)Servlet 容器调用HttpServlet 对象的service 方法,把HttpRequest对象与HtpResponse对象作为参数传给HttpServlet 对象。
(6)HtpServlet 调用HttpRequest对象的有关方法,获取Http请求信息。
(7)HttpServlet 调用HttpResponse对象的有关方法,生成响应数据。
9.3 servlet特性
单例多线程
10、如何解决Servlet线程不安全的问题?
(1)不要在servlet中使用成员变量。
(2)可以给servlet中的方法添加同步锁,Synchronized,但是,数据并发访问会造成阻塞等待。
(3)可以实现SingleThreadModel接口,如下。这样可以避免使用成员变量的问题,但是也不提倡,原因同上。
Public class Servlet1 extends HttpServlet implements Single ThreadModel{
………..
}
11、拦截器和过滤器有什么区别
拦截器是基于java的反射机制的,而过滤器是基于函数回调。
拦截器不依赖servlet容器,过滤器依赖与servlet容器。
拦截器只能对action 请求起作用,而过滤器则可以对几乎所有的请求起作用。
拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
12、拦截器和过滤器的执行顺序
过滤前-拦截前-Action处理-拦截后-过滤后。 过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);过滤通过后,拦截器将检查用户提交数据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;Action处理完成返回后,拦截器还可以做其他过程,再向上返回到过滤器的后续操作。
13、说一下jsp的4种作用域?
application、session、request、page
application作用域
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。 application作用域上的信息传递是通过ServletContext实现的,它提供的主要方法如下所示:
Object getAttribute(String name)//从application中获取信息;
void setAttribute(String name,Object value)//向application作用域中设置信息。
session作用域
session作用域比较容易理解,同一浏览器对服务器进行多次访问,在这多次访问之间传递信息,就是session作用域的体现。如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。 session是通过HttpSession接口实现的,它提供的主要方法如下所示:
ObjectHttpSession.getAttribute(String name)//从session中获取信息。
void HttpSession.setAtribute(String name,Object value)//向 session中保存信息。
HttpSession HttpServletRequest.getSession()/获取当前请求所在的session的对象。
session的开始时刻比较容易判断,它从浏览器发出第一个HTTP请求即可认为会话开始。但结束时刻就不好判断了,因为浏览器关闭时并不会通知服务器,所以只能通过如下这种方法判断:如果一定的时间内客户端没有反应,则认为会话结束。Tomcat的默认值为120分钟,但这个值也可以通过HttpSession的setMaxInactiveInterval0方法来设置:
void setMaxInactiveInterval(int interval)
如果想主动让会话结束,例如用户单击“注销”按钮的时候,可以使用HttpSession的invalidate()方法,用于强制结束当前 session: void invalidate()。
request作用域
一个HTTP请求的处理可能需要多个Servlet合作,而这几个Servlet之间可以通过某种方式传递信息,但这个信息在请求结束后就无效了。request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算了。如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。所谓请求周期,就是指从http 请求发起,到服务器处理结束,返回响应的整个过程。在这个过程中可能使用forward的方式跳转了多个isp页面,在这些页面里你都可以使用这个变量。 Servlet之间的信息共享是通过HtpServletRequest接口的两个方法来实现的:
void setAttribute(String name,Object value)//将对象value以name为名称保存到request作用域中。
Object getAtribute(String name)//从request作用域中取得指定名字的信息。
JSP中的doGet()、doPost()方法的第一个参数就是HttpServletRequest对象,使用这个对象的setAttribute()方法即可传递信息。那么在设置好信息之后,要通过何种方式将信息传给其他的Servlet呢?这就要用到RequestDispatcher接口的forward()方法,通过它将请求转发给其他Servlet。
RequestDispatcher ServletContext.getRequestDispatcher(String path)//取得Dispatcher以便转发,path为转发的目的Servlet。
void RequestDispatcher.forward(ServletRequest request,ServletResponse response)//将 request和response 转发
需要在当前Servlet中先通过setAttribute()方法设置相应的属性,再使用forward()方法进行跳转,最后在跳转到的Servlet中通过使用getAttribute()方法即可实现信息传递。
需要注意两点: (1)转发不是重定向,转发是在Web应用内部进行的。
(2)转发对浏览器是透明的,也就是说,无论在服务器上如何转发,浏览器地址栏中显示的仍然是最初那个Servlet的地址。
page作用域
page对象的作用范围仅限于用户请求的当前页面,对于page对象的引用将在响应返回给客户端之后被释放,或者在请求被转发到其他地方后被释放。page里的变量只要页面跳转了,它们就不见了。如果把变量放到pageContext里,就说明它的作用域是page,它的有效范围只在当前jsp页面里。从把变量放到pageContext开始,到jsp 页面结束,你都可以使用这个变量。 以上介绍的作用范围越来越小,request和page的生命周期都是短暂的,它们之间的区别:一个request可以包含多个page页(include,forward及filter)。
14、jsp有哪些内置对象?作用分别是什么?
JSP共有以下9个内置的对象: request 用户端请求,此请求会包含来自GET/POST请求的参数。
response 网页传回用户端的回应。
pageContext 网页的属性是在这里管理。
session与请求有关的会话期。
application servlet 正在执行的内容。
out用来传送回应的输出。
config servlet的构架部件。
pageJSP网页本身。
exception针对错误网页,未捕捉的例外。
request 表示HttpServletRequest对象。它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie,header,和session数据的有用的方法。
response表示HttpServletResponse对象,并提供了几个用于设置送回浏览器的响应的方法(如cookies,头信息等)out 对象是javax.jsp.JspWriter的一个实例,并提供了几个方法使你能用于向浏览器回送输出结果。
pageContext 表示一个javax.servlet.jsp.PageContext对象。它是用于方便存取各种范围的名字空间、servlet相关的对象的API,并且包装了通用的servlet相关功能的方法。
session 表示一个请求的javax.servlet.http.HttpSession对象。Session可以存贮用户的状态信息。
applicaton表示一个javax.servle.ServletContext对象。这有助于查找有关servlet 引擎和servlet环境的信息。
config表示一个javax.servlet.ServletConfig对象。该对象用于存取servlet实例的初始化参数。
page表示从该页面产生的一个servlet实例。
15、转发(Forward)和重定向(Redirect)的区别?
重定向会改变URL地址,请求转发不会。
重定向可以用URL绝对路径访问其他web服务器的资源,而请求转发只能在一个web应用程序内进行资源转发。