面试官提问的内容通常会由易到难, 如果前面容易的内容都答不上来, 往往就被刷了, 如果是前面提问的都答上来了, 他会问一些有深度的问题, 这时候就算你回答不上来也不要慌张, 他只是看看你的薪资水平而已
接下来我就说一下 java 面试通常会问到的一些知识点
如果你的简历上面没有写框架的东西, 只写了 web 的一些技术, 比如 servlet 和 jsp, 他一般会问 java 基础, 但是如果写了框架, 一般就不问 java 基础了, 当然, servlet 和 jsp 是要问的
一我这里就先开始说 servlet
1:servlet 的生命周期
void init(ServletConfig): 出生之后(1 次)
void service(ServletRequest request,ServletResponse response): 每次处理请求时都会被调用
void destroy(): 临死之前(1 次);
这样说也够了, 但是为了显示自己很厉害, 还可以说明他们分别是什么时候使用, 是干啥的
第一次创建 servlet 对象之后, 服务器会调用 init(ServletConfig), 他是是用来初始化 servlet, 参数 ServletConfig 就是 servlet 的配置信息; 每次接收请求, 都会调用 service(), 他是用来处理请求; 服务器关闭时会调用 destroy(),destroy 可以用来释放资源
2:servlet 是干什么的
Servlet 是 JavaWeb 的三大组件之一, 它属于动态资源. Servlet 的作用是处理请求, 服务器会把接收到的请求交给 Servlet 来处理, 在 Servlet 中通常需要:(1) 接收请求数据;(2) 处理请求;(3)完成响应.
3:servlet 是怎么得到的
有三种:(1)实现 servlet 接口 (2) 继承 GenericServlet 抽象类 (3) 继承 HttpServlet 抽象类
这样答基本上就可以了, 但是我们还可以解释一下
GenericServlet 抽象类实现 servlet 接口, 而 HttpServlet 抽象类是是 GenericServlet 抽象类的子类, 通常用的都是继承 HttpServlet 抽象类, 因为他是跟 Http 协议相关的, 专门用来处理 Http 协议的请求
4: 有哪些域对象
(1)域对象就是用来在多个 Servlet 中传递数据, 底层是一个 map, 用来存数据和取数据
(2)ServletRequest; 作用范围是一个请求
(3)HttpSession;l 一个会话创建一个 HttpSession 对象, 同一会话中的多个请求中可以共享 session 中的数据;
(4)ServletContext; 服务器会为每一个项目创建一个 ServletContext 对象! 作用范围是整个项目 ServletContext 对象的作用是在整个项目的动态资源之间共享数据!
5: 重定向和请求转发和请求包含
(1)l 请求转发是一个请求, 而重定向是两个请求;
(2)请求转发的目标只能是本应用中的资源, 重定向的目标可以是其他应用
请求转发和请求包含都是一次请求, 而且请求转发是留头不留体, 也就是的前一个 servlet 的响应头是可以设置的, 但是响应体是不允许输出, 而只能使用后一个 servlet 的
请求包含是留头又留体, 响应体和响应头都允许输出
所以请求包含大多都是在 jsp 页面中, 用来完成多页面的合并, 请求转发大多都是在 servlet 中. 转发目标大多是 jsp 页面
6 关于 servlet
Servlet 是线程不安全的, 而且是单实例对象, 当多个请求向一个 Servlet 发出时, 有可能会存在一个线程对其进行读操作. 另一个对其进行写操作,
有三种解决方法
不要在 Servlet 中创建成员! 创建局部变量即可!
可以创建无状态成员!(也就是没有 get(),set()方法)
可以创建有状态的成员, 但状态必须为只读的!(也就是没有 set()方法)
二 jsp
1:jsp 是干什么的
JSP(Java Server Pages)是 JavaWeb 服务器端的动态资源. 他是用来显示数据和获取数据.
JSP 是一种特殊的 Servlet, 当 JSP 页面首次被访问时, 容器 (Tomcat) 会先把 JSP 编译成 Servlet, 然后再去执行 Servlet. 所以 JSP 其实就是一个 Servlet!
2: 会话跟踪技术
(1)HTTP 协议中可以使用 Cookie 来完成会话跟踪! 在 JavaWeb 中, 使用 session 来完成会话跟踪, session 底层依赖 Cookie 技术
(2)cookie
不同浏览器之间是不共享 Cookie 的
如果服务器端发送重复的 Cookie 那么会覆盖原有的 Cookie
当客户端向服务器发出请求时会把所有这个服务器 Cookie 包含在请求中发送给服务器, 这样服务器就可以识别客户端了!
cookie 的生命, 默认情况下是保存在浏览器内存中, 一旦浏览器关闭 cookie 就消失了
但是可以通过设置时间来让他保存在磁盘中, 这样在浏览器关闭之后也会存在, 存在时间就是设置的时间
请求路径如果包含了 Cookie 路径, 那么会在请求中包含这个 Cookie, 否则不会请求中不会包含这个 Cookie.
这里要注意, cookie 的路径要比请求的路径要大, 应该这么想, 一个 cookie 可以被多个请求带上
(3)session
HttpSession 也是一个域对象
当首次使用 session 时, 服务器端要创建 session,session 是保存在服务器端, 而给客户端的 session 的 id(一个 cookie 中保存了 sessionId). 客户端带走的是 sessionId, 而数据是保存在 session 中.
当客户端再次访问服务器时, 在请求中会带上 sessionId, 而服务器会通过 sessionId 找到对应的 session, 而无需再创建新的 session.
session 保存在服务器, 而 sessionId 通过 Cookie 发送给客户端, 但这个 Cookie 的生命不 - 1, 即只在浏览器内存中存在, 也就是说如果用户关闭了浏览器, 那么这个 Cookie 就丢失了.
当用户再次打开浏览器访问服务器时, 就不会有 sessionId 发送给服务器, 那么服务器会认为你没有 session, 所以服务器会创建一个 session, 并在响应中把 sessionId 中到 Cookie 中发送给客户端.
这里有一个很重要的问题, 就是页面的路径的范围小于等于 Cookie 的路径的范围
Cookie 中不能存在中文
如果是在浏览器内存中就会出现当开两个相同的浏览器时是没有关联的, 是属于两个用户
如果是在计算机硬盘中, 说明就是有关联的, 是属于一个用户
4 三大指令:
page 指令(定义整个页面的一些属性和值),include 指令(静态包含, 先合并, 再编译, 如果是动态包含, 就是先编译再合并),taglib 指令(导入标签库)
5 九大内置对象:
out --> jsp 的输出流, 用来向客户端响应
page --> 当前 jsp 对象! 它的引用类型是 Object, 即真身中有如下代码: Object page = this;
config --> 它对应真身 (就是转译成的 Java 文件, 它其实是一个 Servlet) 中的 ServletConfig 对象!
pageContext --> 一个顶 9 个!(以下那些都和 Servlet 里的匹配起来, 他们的使用方法是一样的)
- request --> HttpServletEequest
- response --> HttpServletResponse
- exception --> Throwable
- session --> HttpSession
- application --> ServletContext(一个 jsp 页面! 这个域是在当前 jsp 页面和当前 jsp 页面中使用的标签之间共享数据!)
代理其他域: pageContext.setAttribute("xxx", "XXX", PageContext.SESSION_SCOPE);
> 全域查找: pageContext.findAttribute("xxx"); 从小到大, 依赖查找!
> 获取其他 8 个内置对象:
多个用户请求一个 JSP 页面时, 要为每一个用户开辟一个线程
6. 一般问到的是打开一个 IE 浏览器打开一个网站, 之后再打开这个浏览器, 也打开这个网站, 总共有几个 session 对象创建
这个这样答比较详细: 可能一个, 也可能两个, 因为 session 本身是存在于服务器端的, session 的识别是通过 cookie 中的 JSessionID,session 的底层是依赖于 cookie 的, 而如果 cookie 设置的时间是默认的(-1), 说明 cookie 是存在于浏览器内存中, 这样 cookie 是相对于浏览器存在的, 一个浏览器一个对象; 而如果设置的时间大于 0, 那么 cookie 就会存在于磁盘中, 只要是相同的浏览器开启之后都会是一个 session 对象, 而且虽然 cookie 存在于磁盘中, 不同的浏览器也不会有相同的 session 对象, 肯定是不一样的, 不同的浏览器是不共享 cookie 的
7. 还可能会问 session 是依赖于什么存在的
先回答是 cookie, 因为 session 对象本身是存在于服务器端的, 而把 JSessionID 是存放在 cookie 中, 当再次进行请求时, cookie 中会带上 JSessionID, 这样就可以得到服务器端的 session 了
但是如果这个请求时没有 cookie 的, 如果我们还想使用 session, 我们也可以通过 URL 重写的方式, 这需要在每个 URL 后面都加上 sessionId! 这样用户的请求中就包含了 sessionId, 服务器就可以通过 sessionId 找到对应的 session 对象了.
所以 session 是依赖于 cookie 或者 URL 重写
三: 过滤器
1 过滤器是怎么执行的
当用户请求某个 Servlet 时, 会先执行部署在这个请求上的 Filter, 如果 Filter"放行", 那么会继承执行用户请求的 Servlet; 如果 Filter 不 "放行", 那么就不会执行用户请求的 Servlet.
doFilter()方法的参数中有一个类型为 FilterChain 的参数, 它只有一个方法: doFilter(ServletRequest,ServletResponse). 执行这个方法就会放行
2 有哪几种拦截方式
拦截方式: REQUEST,FORWARD,INCLUDE,ERROR, 默认是 REQUEST 方式.
l REQUEST: 拦截直接请求方式;
l FORWARD: 拦截请求转发方式;
l INCLUDE: 拦截请求包含方式;
l ERROR: 拦截错误转发方式.
<filter-mapping > 的配置顺序决定了过滤器的执行顺序!
四: Struts2
1 拦截器的作用? 拦截器与过滤器的区别?
1)一组拦截器构成了过滤器来实现, 而过滤器和 action 是 Struts2 的核心组件, 同时可以减轻代码冗余, 提高重用率.
2) 过滤器是拦截用户请求的, 范围明显比拦截器大的多.
2 如何在 Struts2 中使用 Ajax 功能
3Struts2 如何访问 HttpServletRequest,HttpSession,ServletContext 三个域对象 (访问 servlet 的 API)
(1)通过 ActionContext 来访问, 这种方式可以访问这 servlet 的 API 对象, 但是无法直接获得对象
(2)实现接口, ServletRequestAware, 都是 API+Aware, 实现这些接口, 并且写上相应的与对象的变量和 set 方法就可以了
(3)ServletActionContext 的静态方法可以获取
4. 为什么要使用 Struts2 & Struts2 的优点(Struts2 和 Struts1 和 webWork 的关系)
5.Struts2 的前端控制器是什么
StrutsPrepareAndExecuteFilter, 他其实就是一个过滤器, 他有两个功能, 一个是预处理, 一个是执行, 预处理是通过他的生命周期方法 init 加载 action 配置文件, 过滤器由一组拦截器组成, 这些拦截器就是进行拦截
6action 中是怎么编写的呢
a: 只写个普通类, 不实现任何接口, 不继承任何类
b: 实现 action 接口
c: 继承 actionSupport 类(这个类就已经实现了 action 接口, 还实现了很多其他的接口)
7Struts2 的配置文件的加载顺序
struts.xml->struts.properties->Web.xml
8:Struts2 中的数据封装有哪几种方法
可以这么说, 有两种, 一个是属性封装, 一个是模型驱动封装, 属性封装有包括 set 方法和表达式封装
也可以说有三种, 一个是属性封装, 一个是模型驱动封装, 一个是表达式封装
属性封装: 设置属性的 set 方法
模型驱动封装: 通过实现 ModelDriver 接口来接收请求参数; 里面的泛型是要封装的类, 之后手动构建对象; 重写 getModel()方法返回的就是 Action 所使用的数据模型对象
表达式封装: 其实他本质上也是属性封装, 只是当属性很多的时候, 就会写很多 set 方法, 这样很臃肿, 所以就把这些属性和 setget 方法封装到一个对象中, 在 action 中直接使用这个对象
区别: 表达式封装是本质上就属于属性封装, 只是当属性太多时, 将这些属性封装到了一个对象中, 直接使用对象, 所以当属性少的时候就用属性封装, 当属性多的时候就用表达式封装; 而表达式封装和模型驱动封装本质上是不同的, 如果操作现有的 pojo 对象, 就用模型驱动封装, 而如果操作的属性很多, 但是不构成现有的 pojo 对象, 或者构成了多个 pojo 对象, 就需要使用表达式封装
9: 拦截器是怎么进行拦截的?
拦截器是动态拦截 action 的调用对象, 可以定义在执行 action 之前或之后可以执行的一些功能, 也可以判断是否进行拦截
他这里用到了 Aop 思想, 面向切面思想, 也就是不通过修改源代码而去扩展功能
还有就是责任链(也叫拦截器链), 将拦截器按照一定的顺序组成一个链, 之后当访问这个 action 时会按照定义好的顺序进行拦截
五: spring
1:spring 的特性是什么?
(1)spring 是一站式框架, 在 Web 层有 springMVC, 在 service 层有 IoC, 在 dao 层有 JDBCTamplate, 对于常见的 dao 层框架也有相应的 Template,
(2)IoC 思想, 控制反转: 对象的创建不是通过 new 方式来实现, 而是通过 spring 配置创建类对象
(3)AOP 思想, 面向切面编程: 不通过修改源代码而实现功能的扩展
2:IoC 底层原理是怎么实现的?
dom4j 解析 xml 文件, 工厂设计模式, 反射(最主要就要说出反射)
3:spring 是怎么配置创建类对象的?
可以这么答: 有两种, 一个是配置文件配置, 一种是注解方式
配置的方式有三种: 使用类的无参构造创建
来源: http://www.jianshu.com/p/03911102b6db