面试知识点总结——JavaWeb

遇到注意点会持续更新。。。主要是梳理让自己增加印象。

琐碎

l  检查用户输入正确性,一般在前端进行检查,从而减少网络传输和响应时间。同样对于响应的数据在客户端进行编排可以减少服务端的负载。

l  把系统拆分成多个工程,要完成系统的工程需要多个工程协作完成。这种形式叫做分布式集群的概念则是多个Tomcat部署一个项目,扩展系统性能。

数据库

内连接和左连接

内连接:两张表都有的数据

SELECT * from Student s, studentcoure sc where s.ID= sc.SID

左连接:左表为主,返回左表所有行,并以此和右表连接,右表没有为null

select * from Student s left join studentcourse sc ons.ID = sc.SID

右连接可以改成左连接

范式和连接的代价

1NF:每个属性都不可再分

2NF:属性完全依赖主键(消除部分子函数依赖)

3NF:属性不依赖于其他非主属性(消除传递依赖)

BCNF(巴斯-科德范式):在1NF基础上,任何非主属性不能对主键子集依赖(在3NF基础上消除对主码子集的依赖)

4NF:把同一表内的多对多关系删除

5NF:从最终结构重新建立原始结构

数据库三范式,减少冗余,需要靠连接来查找相关数据,连接查询有一定代价,需要权衡业务需求,不一定完全按照三范式设计表。

group by和Having

group by是分组,having是筛选满足条件的组,如:

select 兴趣小组,sum(人数) as 总人数 from 兴趣小组记录表 group by 兴趣小组 Having sum(人数)<10

查找每个兴趣小组年级总人数小于10的

having也可以查看重复记录:

select ID from student group by ID having count(*)>1

索引的用途和代价

用途:索引加快查找效率

代价:索引需要占硬盘空间,插入删除数据需要重新建立索引

根据业务需求权衡。

例1:

针对book建立索引

select book from booktable,没有where语句没有用索引

select * from booktable where book=‘Java’,用到索引,如果经常这样查询并且book值重复率不高建议建立索引。

select * from booktable where book like ‘Java%’,模糊查询时,只要%不出现在第一个位置都能用到索引,而‘%Java’就不会用到。

例2:

select name from student where socure >95,对score 建立索引,非等值操作不使用索引,应该改成where score in(96,97,98,99,100)

select name from student where score +40 =100,不使用索引,应该写成where score = 100-40。

对索引字段进行函数操作也无法用到索引。

索引分类:

直接创建索引和间接创建索引;普通索引和唯一性索引;单个索引和复合索引;聚簇索引和非聚簇索引。

索引失效:

条件中有or;多列索引不是使用的第一部分;like查询以%开头;如果列类型是字符串,需要使用引号引起来。

预处理和批处理

预处理除了可以提升效率,还能避免SQL注入攻击。

如:

select username from users where username=’输入名字’ and pwd=’输入密码’,如果用户登录输入密码时输入:’1’ or ‘1’=’1’,那么就会绕过验证。

而预处理对象PrepareStatement就能有效防止,因为一个“?”就是一个占位符,无法扩展。

占位符编号从1开始,使用pstmt.addBatch()加入缓存,pstmt.executeBatch()提交。

一般批处理每批500条左右。

事务的提交与回滚

通过connection.setAutoCommit(false)设置非自动提交,在合适的地方使用connection()来提交事务,通过connection.rollback()来回滚事务,一般放在catch语句里。

JDBC中,有5个常量可以用来描述事务隔离级别(了解)

读取未提交:TRANSACTION_READ _UNCOMMITTED最低级别,任何情况都无法保证。

读取提交:TRANSACTION_READ_COMMITTED可避免脏读的发生。

可重读:TRANSACTION_REPEATABLE_READ可避免脏读、不可重复读的发生。

可串化:TRANSACTION_SERIALIZABLE可避免脏读、不可重复读、幻读的发生。

不支持事务常量:TRANSACTION_NONE JDBC。

 

脏读

不可重复读

幻读

Read uncommitted

Read committed

×

Repeatable read

×

×

Serializable

×

×

×

脏读:一个事务读取另一个事务尚未提交的数据。

不可重复读:对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。如事务T1读取了一行内容,T2修改了T1刚刚读取的那一行记录,然后T1再次读取该行记录发现与刚刚读取的不同。

幻读:事务非独立执行时发生的一种现象,幻读和不可重复读都是读取了另一条已经提交的事务(可重复读所有被select获取的数据都不能被修改,防止前后读取不一致,但可以增加数据,造成幻读),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

JSP和Servlet

1.       jsp有哪些内置对象作用分别是什么

JSP共有以下9种基本内置组件(可与ASP的6种内部组件相对应):

1、request 用户端请求,此请求会包含来自GET/POST请求的参数 (javax.servlet.ServletRequest类的对象,可以获取包含http请求中的所有数据)

2、response 网页传回用户端的回应 (javax.servlet.ServletResponse的对象,包含http响应中的所有数据)

3、application  (javax.servlet.ServletContext的对象,封装了web.xml中的全局变量的初始化参数,整个web应用程序就只有一个application对象,因此可以通过他来在各个jsp页面之间传递参数,当然也可以通过request对象来传递参数)

4、config (javax.servlet.ServletConfig类的实例,ServletConfig对象封装了web.xml的中的当前servlet或者jsp的初始化参数,通过getInitParameter(String name)就可以获得,该局部变量主要用于初始化)

5、out 用来传送回应的输出(javax.servlet.jsp.JspWriter类的对象)

6、pageContext (javax.servlet.jsp.PageContext类的对象,代表当前jsp页面编辑后的内容,通过pageContext可以获取到jsp中的各个内置对象,以及页面的一些属性,可以在jsp页面中查找各个变量,可获得当前范围内对象的scope,比如当前范围内一个pojo的的scope)

7、page JSP网页本身(javax.servlet.jsp.HttpJspPage对象) (当前的jsp页面)

8、session (javax.servlet.http.HttpSession类的对象,包含session中的所有信息。如session创建时间,最后访问时间,存活时间,sessionid等)

9、exception 针对错误网页,未捕捉的例外(java.lang.Excetion类的对象)

2.       jsp有哪些动作作用分别是什么

JSP共有以下6种基本动作(也叫行为)

1、jsp:include:在页面被请求的时候引入一个文件。

(注意与指令<@pageinclude=”usl”>的区别:jsp:include是在运行的时候包含进来,如果要包含进来的文件有程序,先执行程序,然后返回结果,而include指令只是在编译的时候将文件全部包含进来)(polo就是只有私有属性和getter,setter方法的类)

2、jsp:useBean:寻找或者实例化一个JavaBean。

(具体用法:<form action=”userBean.jsp” method=“post“>,然后定义一个userBean.jsp页面,在jsp页面中用上如下语句<jsp:useBeam id=”person(随便取)” class=”com……Person类” scope=”page(表示该bean的可以作用的范围)“>,之后就可以用setProperty标签和getProperty标签获取bean的各个属性了)在这个域中

Scope的值可以是page,request,session,application;如果scope设置为session,就可以统计某个用户访问某个界面的次数,当scope设置为applocation的时候,就可以统计所有用户的用户次数;(可能的做法:在内存中只存在一个pojo对象,然后如果scope是session,则通过sessionid判断是否同一个人,如果是就count++;如果scope是application,则不用判断sessionid,直接调用该pojo,然后count++)

3、jsp:setProperty:设置JavaBean的属性。

4、jsp:getProperty:输出某个JavaBean的属性。

5、jsp:forward:把请求转到一个新的页面。对servlet中,requeat.getRequestdispather(“servlet名字“).forward()方法的封装,可以实现对request,reponse对象的转发。

6、jsp:plugin:根据浏览器类型为Java插件生成OBJECT或EMBED标记

3.       JSP中动态INCLUDE与静态INCLUDE的区别?

动态INCLUDE用jsp:include动作实现,它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数,如果jsp页面有程序,先执行程序直接返回结果。

静态INCLUDE用include伪码实现,不会检查所含文件的变化,适用于包含静态页面(用<%@include file=”文件名”>命令实现;include指令一般用在有同一个header.jsp,或者foot.jsp;会全部引入进来。当然,最上面的<%@page language=”java”,contentType=”text/html”;character=utf-8 %>这一行是不会引进来的。)

4.       两种跳转方式分别是什么有什么区别

跳转有两种方法:RequestDispatcher.forward()方法和HttpServletResponse.sendRedirect()方法.

区别是:

转发:仅是容器中控制权(从一个servlet对应Wrapper容器转让给另一个Wrapper容器对应的servlet)的转向,在客户端浏览器地址栏中不会显示出转向后的地址,他是不会改变Request的值,如果你需要在下一个页面中能从中获取新的信息的话,你可以Request.setAttribute()来放置一些标志,这样从下一个页面中获取;

重定向:(如果发生重定向,服务端向客户端发送http状态吗301(永久重定向)或者302(临时重定向),并把新的url传给浏览器,浏览器再去访问服务端返回的url)后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。所以,前者更加高效,在前者可以满足需要时,尽量使用Request Dispatcher.forward()方法,并且,这样也有助于隐藏实际的链接。

对于用户:

(301,302对用户来说没有区别,他们看到效果只是一个跳转,浏览器中旧的URL变成了新的URL。页面跳到了这个新的url指向的地方。)

对于引擎及站长

(采用302临时重定向可能造成网址劫持的可能:一个在在自己的网站中使用了302重定向,就代表重定向的目标可能被更换成别的网站;网站劫持就是当网站A重定向到网站B,在浏览器的url栏框中显示的是原网站A的地址,但是显示的页面的内容却是网站B的地址,这样就网站劫持,你幸幸苦苦写的网页就成别人的了。造成网站被劫持的情况:比如说,有的时候A网址很短,但是它做了一个302重定向到B网址,而B网址是一个很长的乱七八糟的URL网址,甚至还有可能包含一些问号之类的参数。很自然的,A网址更加用户友好,而B网址既难看,又不用户友好。这时Google很有可能会仍然显示网址A。)

5.       描述JSPServlet的区别、共同点、各自应用的范围

1、jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)

2、jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.

3、rvlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象

得到.

4、此在实际应用中采用Servlet来控制业务流程,而采用JSP来生成动态网页.在struts框架中,JSP位于MVC设计模式的视图层,而Servlet位于控制层.

6.       Web开发中需要处理HTML标记时,应做什么样的处理,要筛选那些字符

(< >&“”)(可以用正则表达式提取)

7.       JSP中如何读取客户端的请求,如何访问CGI变量,如何确定某个Jsp文件的真实路径。

request里面有很多方法与cgi(common gateway interface)变量对应,getParameter(), getHeader(), getCookies()等等

真实路径通过getServletContext().getRealPath()来取到

8.       描述CookieSession的作用,区别和各自的应用范围,Session工作原理。

区别:1.cookie 是一种服务器发送到客户浏览器的文本串句柄,并保存在客户机硬盘上,可以用来在某个WEB站点会话间持久的保持数据。(常用cookie来记住用户/密码,还有sessionid,访问某个网站的时候直接通过读取访问网站对应cookie,然后发送到服务端,下次不用手动输入)

session实在服务器端创建了的一个对象,来保存该客户端和服务端之间的一个链接,该对象其实就是一个hashmap,它可以存储key,value形式的数值,有一个专门sessionMangage来管理该session的存活时间,最后访问时间,过期时间等信息。

cookie和session的共同之处在于:cookie和session都是用来跟踪浏览器用户身份的会话方式。

cookie 和session的区别是:cookie数据保存在客户端,session数据保存在服务器端。

cookie使用的场景是保存每一个用户名/密码,或者作为sessionid方式的一种,session主要是用来解决http协议的无状态的问题的,如果不用session,服务器在浏览器访问结束以后是不存储关于客户端的任何信息的,同时session也是可以持久化的。同时session存储在服务器端,可以保证用户在一段时间内可以不用用户名/密码登录;用户过期以后,则需要的。

cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session。

session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE

单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K。

session跟踪的三种方法:重点说Cookie、隐藏表单和URL重写:

隐藏表单:<inputtype="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">也主要是用来存储sessionid;也就是服务器发送到客户端浏览其中的隐藏了一个hidden;他用来存储sessionid,因为session只在一段时间内才会有用,他不想用户名密码一样一直保存,因此用隐藏表单是可行的;

URL重新:也就是服务器在每一个url请求的后面都加入sessionid=xxxx;然后就可以识别该sessionid了,因为sessionid放在url后面是一个参数,所以可以通过request.getParameter获取得到sessionid的值的。(就是在所有的页面跳转上加上 encodeURL() 或者 encodeRedirectURL():如:<ahref="<%=response.encodeRedirectURL("test.jsp")%>">totest.jsp</a>)

9.       一个常见的误解是以为session在有客户端访问时就被创建

然而事实是直到某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建,注意如果JSP没有显示的使用 <% @page session="false"%> 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句 HttpSession session =HttpServletRequest.getSession(true);这也是JSP中隐含的 session对象的来历。由于session会消耗内存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。

10.   Session删除的时间是:

1)Session超时:超时指的是连续一定时间服务器没有收到该Session所对应客户端的请求,并且这个时间超过了服务器设置的Session超时的最大时间。

2)程序调用HttpSession.invalidate()

3)服务器关闭或服务停止

11.   sessionid是从哪里来的,sessionID是如何使用的

当客户端第一次请求session对象时候,服务器会为客户端创建一个session,并将通过特殊算法算出一个session的ID,用来标识该session对象,当浏览器下次(session继续有效时)请求别的资源的时候,浏览器会偷偷地将sessionID放置到请求头中,服务器接收到请求后就得到该请求的sessionID,服务器找到该id的session返还给请求者(Servlet)使用。一个会话只能有一个session对象,对session来说是只认id不认人

12.   如何现实servlet的单线程模式

1、果是通过jsp实现servlet单线程,则可以通过如下设置

<%@ page isThreadSafe=”false”%>,(记忆:之所以是false,是因为此时不用sychronized修饰每一个servlet对象的service方法了,所以就不是线程安全的)此时该servlet方法继承SimpleThreadModel接口,该接口是一个空接口,实现了该接口的servlet容器能保证只有一个线程调用该servlet的service方法,是保证servlet一次只能有一个请求,但是由于service方法都是线程私有,这样设计的目的是为了只有一个线程调用service方法,则在service中调用的成员属性就不会出现线程被两个线程同时更改的效果,此时达到加syschronized的目的(这样也就不用加锁了,节省了开支),但是在让一个servlet同一时刻只处理一个servlet,这样严重影响了容器的性能,所以会创建很多个继承了SimpleThreadModel的servlet的多个实例,然后存入servlet实例池,才能提高性能,所以这样的servlet并不是单例的。

2、Servlet容器默认是只创建一个servlet对象,:多个线程可以同时调用一个实例的service方法,所以在servlet中一般是不要用到成员属性,(要用的话就要加锁,这种事最安全的,继承SimpleThreadModel被认为是不安全的,因为他不加锁同步)。

3、servlet不是线程安全的;用到成员属性时需要加锁同步。

13.   页面间对象传递的方法

request,session,application,cookie等

Request,session,application都是在服务器端传值,而cookie是在客户端和服务器端传值。

14.   单点登录怎么实现

单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。单点登录在大型网站里使用得非常频繁,例如像阿里巴巴这样的网站,在网站的背后是成百上千的子系统,

方法1:将登录的session持久化到数据库,在访问另一的主机上的应用的时候遍历数据库中的session,通过sessionid找到对应的session来辨别。(我自己的思路)(持久化到缓存服务器中也可以,就是不可靠,这样就不用每访问一次就去数据库中找,)

方法2:使用最简单的方法就是cookie,在第一层登录成功以后,给客户端一个cookie,然后每次访问别的子系统的时候,都带上该cookie信息,就ok啦。(缺点,不安全,不能跨域登录)

方法3:普遍采用的方案,当第一次登录成功以后,服务器产生可以免登录的url传送到客户端,客户端用免登录的url去访问分系统的时候,分系统就验证该客户端的一些信息,验证通过就免登录,不通过就不允许登录,这样的问题也就有,服务端还是得存储相关的临时信任数据,有可能不是session,但是这里就可以用缓存了,一般临时信息不需要持久化。

JSP+Servlet+JavaBean+JDBC框架(Model 1)

l  Model1(JSP+JavaBean)——>Model2(JSP+JavaBean+Servlet)——>三层模型

l  jsp负责视图,servlet负责业务响应控制(跳转),javabean负责模型,JDBC即DAO层。

l  Java发展分为前端和后端,前端主要负责CSS+DIV、jQuery、Ajax,后端负责数据库连接、业务实现等。

 

l  多个servlet处理不同业务请求。

Servlet是单实例多线程。对于同一种业务请求只有一个实例。多个用户请求触发多个线程调用service()。

l  保存上下文的ServletContext和负责处理Session对象的HttpSession是线程不安全的,而处理请求的ServletRequest是线程安全的。由于ServletRequest是线程安全的,尽量在Servlet中使用局部变量,即有单属于本Servlet的对象,如request.getParameter(“user”);

l  Servlet本身是无状态的,一个无状态的Servlet是绝对线程安全的,无状态对象设计也是解决线程安全问题的一种有效手段。所以,servlet是否线程安全是由它的实现来决定的,如果它内部的属性或方法会被多个线程改变,它就是线程不安全的,反之,就是线程安全的。多线程下每个线程对局部变量都会有自己的一份copy,这样对局部变量的修改只会影响到自己的copy而不会对别的线程产生影响,所以这是线程安全的。但是对于实例变量来说,由于servlet在Tomcat中是以单例模式存在的,所有的线程共享实例变量。多个线程对共享资源的访问就造成了线程不安全问题。

l  在多个Servlet中,如果同时对外部对象(如文件)进行修改,一定要加锁互斥访问。一般servlet只负责跳转。

l  JavaBean具备的特征:无参构造函数、属性私有、getter和setter。在Model1模式中,JavaBean还涉及业务逻辑。

 

Struts是一个实现MVC各部分之间跳转的模板编写web.xml和struts.xml(根据字符串映射jsp页面)和action类(返回字符串)。这里只做了解和对比。

 

Spring

Spring技术点主要分为四大块:1、IoC和AOP等。2、SpringMVC。3、和其他框架整合,如MyBatis。4、数据方面应用,如事务等。

IoC、AOP

l  IoC和DI是从不同角度讲述同一件事。依赖注入强调类的注入是有Spring容器在运行时完成,而控制反转强调类之间关系由Spring容器控制。避免每次使用都要实例化new一个对象,能够减少GC回收压力。

l  理解面向接口编程的重要性,本质是缩小修改的影响范围。

l  在实际项目中,一般用单例模式来创建无状态Bean,对于有状态Bean,一般不用这种模式。

l  Spring做项目遇到的问题,大量注解对项目维护带来的问题,或者单例创建Bean的时候对多线程之间的调用带来一定问题。

l  Spring使用ThreadLocal解决线程安全问题。我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。

l  autowired种类:no、byName、byType、constructor、autodetect、default。

l  Bean作用域:singleton(单例,默认)、prototype(每次请求)、request(当前request内有效)、session(当前session内有效)、global session(基于portlet的web中有效)。

l  Bean的生命周期和IoC、AOP源码是加分项。

Spring读取配置文件的方式

XmlBeanFactory类

Resource resource = new ClassPathResource(“bean.xml”);

BeanFactory factory = new XmlBeanFactory(resource);

ClassPathXmlApplicationContext类

ApplicationContext factory =

newClassPathXmlApplicationContext(“conf/appcontext.xml”)

FileSystemXmlApplicationContext类

ApplicationContext =

newFileSystemXmlApplicationContext(“classpath:appcontext.xml”);

 

@Autowired等同于XML配置中autowire=”byType”

@Resource等同于XML配置中autowire=”byName”

 

 

Spring MVC

l  与Struts MVC区别,针对URL请求是方法级别,通过@RequestMapping等注解,Struts是类级别。拦截器实现机制,SpringMVC使用AOP,Struts2使用自己的interceptor机制,配置文件较多。SpringMVC性能更好,开发灵活。

l  通过HandlerMapping接口来指定处理的控制器类,实现类有SimpleUrlHandlerMapping、BeanNameUrlHandlerMapping、AnnotationMethodHandlerAdapter。通过视图解析器ViewResolver处理响应结果。通过ModelAndView返回视图结果。

l  可用来重定向(forward、redirect)、在不同控制器之间跳转(可带参数),默认为forward。

SSM整合相关配置文件配置内容

MyBatis

配置mybatisConfig.xml,可以为空,或者配置一些全局属性(驼峰命名转换等),其他都在application-dao.xml中配置。

DAO层

配置application-dao.xml文件。主要配置:

配置数据源dataSource;配置SqlsessionFactory(单例)到Spring容器中;配置mapper的代理对象,使用时可直接注入接口。

Service层

配置application-service.xml文件。主要配置:

事务管理(也可以单独配置在一个文件中);扫描注解的配置。

View层

配置spring-mvc.xml文件。主要配置:

配置注解驱动;配置视图解析器;配置扫描controller;配置静态资源映射。

为什么不能一起把servicedao一起全扫描了??)因为Spring和SpringMVC是父子容器的关系,子容器可以访问父容器中的对象,父容器不能访问子容器对象。

web.xml文件配置

Spring容器配置;SpringMVC前端控制器配置(一个servlet);乱码过滤器。

Spring事务

MyBatis和Spring整合后,可以由Spring来管理事务。一般可以用编程式事务和声明式事务。详见http://blog.csdn.net/qq407388356/article/details/79318151

事务传播机制

也叫事务传播行为,是一个独立的概念。通过事务传播机制,可以定义事务之间的交互行为。Spring容器定义了7种类型的事务传播行为。详见http://blog.csdn.net/qq407388356/article/details/79318151。

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值