手把手教你如何玩转面试(Web知识)

     本篇是讲解关于JavaWeb岗位面试方面的一些对于Web知识的整理,当然,不只是需要知道这个方面的内容,还需要掌握其他方面的知识,我都根据自己的经历来进行了整理,方便大家进行系统化的学习,只有多复习多研究,才能对技术有更好的掌握,才能拿到更好的offer。

下面是其他方面的知识点,欢迎大家进行浏览

Spring的精华:https://blog.csdn.net/cs_hnu_scw/article/details/78677502

Hibernate的精华:https://blog.csdn.net/cs_hnu_scw/article/details/78762294

Java基础:https://blog.csdn.net/Cs_hnu_scw/article/details/79635874

数据结构:https://blog.csdn.net/Cs_hnu_scw/article/details/79896717

数据库:https://blog.csdn.net/Cs_hnu_scw/article/details/82900559

操作系统:https://blog.csdn.net/Cs_hnu_scw/article/details/79896500

计算机网络:https://blog.csdn.net/Cs_hnu_scw/article/details/79896621

其他方面的知识:https://blog.csdn.net/Cs_hnu_scw/article/details/79896876

思维导图github地址:git@github.com:qq496616246/MindMapping.git 或者 https://github.com/qq496616246/MindMapping.git​​​​​​​

1:Spring中获取连接池的方式有哪些?

(1)DBCP数据源
(2)C3P0数据源
(3)Tomcat Jdbc Pool
(4)BoneCP

(5)Druid数据源----阿里开源

详情可以参考这篇博文写得非常不错

2:forward和redirect的区别有哪些?

(1)地址栏显示:前者不变,而后者会进行修改
forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
(2)数据共享:前者是共享的,而后者是不能共享的
forward:转发页面和转发到的页面可以共享request里面的数据.
redirect:不能共享数据.
(3)发生的方式:前者是在服务器端,而后者是发生在客户端
(4)运用场景:forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.
(5)效率:前者效率高,而后者效率低

注意:redirect默认是302码,包含两次请求和两次响应

3:Http返回码301和302之间的区别?

共同点:都是进行重定向返回的状态码

不同点:301是代表永久性转移;而302是短暂性转移,会发生网址劫持的情况;尽量使用301而不要使用302,会发生“URL劫持”现象。

4:PreparedStatement与Statement的区别?

(1)preparedStatement是继承的Statement接口,它们两者都是接口;
(2)preparedStatement是通过占位符,能够进行预编译的,而Statement不能,其每次执行SQL语句都需要重新进行处理;
(3)preparedStatement安全性更好,因为其能够防止SQL的注入
(4)preparedStatement对于重复执行的代码的执行效率更快,对于批处理效率相对Statemet好
(5)PreaparedStatement代码的维护性和可读性更加好

稍微补充一点额外知识:CallableStatement,其是PreparedStatement的子类,主要是用于调用数据库的存储过程;

5:JSP中静态Include和动态Include的区别?

(1)动态include是通过<jsp:include page = "hello.jsp">,而静态include是通过<%@ include file="hello.html"%>
(2)动态的可以包含相同的变量,而静态的是不可以包含相同变量
(3)动态的是先分别编译每个jsp,然后再使用的时候进行的包含在一起,是先编译再包含;而静态的是先包含在一起,然后再进行一起编译,是先包含,后编译
(4)如果被包含的页面经常更新,那么应该使用动态包含,因为使用静态包含,可能不会及时的进行更新;
(5)静态的include是通过伪码实现,不会检查文件的改变,适用于静态页面;

6:JSP有哪些内置对象?作用分别是什么?

答:一共是9个。

(1)HttpServletRequest类的request对象:代表请求对象,主要用于接受客户端通过HTTP协议链接传输到服务器端的数据
(2)HttpServletResponse类的response对象:代表响应对象,主要用于向客户端发送数据
(3)JspWriter类的out对象:主要用于向客户端输出数据,Out类的基类是JspWriter
(4)HttpSession类的session对象:主要用来分别保存每个用户信息和会话状态
(5)ServletContex类的application对象:主要用于保存所有应用系统中的公有数据,它是一个共享的内置对象,即一个容器中的多个用户共享一个application读写,只要没有关闭服务器,application对象一直存在
(6)PageContext类的PageContext对象:管理网页属性,代表了页面的上下文。PageContext对象的创建和初始化都是由容器自动完成。
(7)ServletConfig类的Config对象:代码片段配置对象,用于初始化Servlet的配置参数。
(8)Object类的Page对象:代表了当前正在运行的JSP页面,也就是说,page对象代表了JSP编译后的Servlet。page对象只能在当前的JSP范文之内使用。
(9)exception对象:处理JSP文件执行时发生的错误和异常,只有在错误页面里才可以使用;

7:JSP中的基本动作指令和作用?

答:(1)jsp:include:在页面被请求的时候引入一个文件

(2)jsp:useBean:寻找或者实例化一个JavaBean

(3)jsp:setProperty:设置JavaBean的属性

(4)jsp:getProperty:输出某个JavaBean的属性

(5)jsp:forward:把请求转到一个新的页面

(6)jsp:plugin:根据浏览器类型为java插件生成object或embed标记

8:Spring的事务传播特性和隔离级别分别是如何?

答:事务传播特性主要是分为7类:

PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

隔离级别主要分为4类:

1.未授权读取(Read Uncommitted):也称未提交读。允许脏读取但不允许更新丢失,如果一个事务已经开始写数据则另外一个数据则不允许同时进行写操作但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。事务隔离的最低级别,仅可保证不读取物理损坏的数据。与READ COMMITTED 隔离级相反,它允许读取已经被其它用户修改但尚未提交确定的数据。
2. 授权读取(Read Committed):也称提交读。允许不可重复读取但不允许脏读取。这可以通过“瞬间共享读锁”和“排他写锁”实现,读取数据的事务允许其他事务继续访问该行数据,但是未提交写事务将会禁止其他事务访问该行。SQL Server 默认的级别。在此隔离级下,SELECT 命令不会返回尚未提交(Committed) 的数据,也不能返回脏数据。
3. 可重复读取(Repeatable Read):禁止不可重复读取和脏读取。但是有时可能出现幻影数据,这可以通过“共享读锁”和“排他写锁”实现,读取数据事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。在此隔离级下,用SELECT 命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。
4. 串行(Serializable):也称可串行读。提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作事务访问到。事务隔离的最高级别,事务之间完全隔离。如果事务在可串行读隔离级别上运行,则可以保证任何并发重叠事务均是串行的。

 

温馨提示:

(1)关于操作数据库中出现的脏读,不可重复读,幻读

脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。

 

幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

 

不可重复读的重点是修改: 同样的条件,你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除: 同样的条件,第 1 次和第 2 次读出来的记录数不一样

(2)问:Mysql5.6(Innodb)以后其数据库本身是如何解决幻读问题的?

答:首先,Innodb引擎默认的隔离级别是可重复读,所以,它本身是能够解决了脏读和不可重复读的问题,但是对于幻读是不能够解决的,但是,它本身又提供了一种机制来解决这种幻读的问题,就是通过NextKey lock方式,其实就是使用一种锁的机制;具体的过程如下:

9:Http中的request和response的头都含有什么字段?

答:https://blog.csdn.net/selinda001/article/details/79338766

10:JavaWeb的高并发处理的一些优化方式有哪些?

答:高并发可以分为用户量并发和数据并发

针对用户量的并发的解决方式可以从下面的方面进行考虑:

(1)网页静态化(纯HTML):主要是提高反应速度和提高安全性与稳定性(因为不容易被攻击);

(2)图片服务器分离:主要是减轻服务器压力,比如jQuery中的lazyload.js就能够实现这样的懒加载方式

(3)ajax请求:主要是不需要页面进行重新刷新获取

(4)服务器的负载均衡:主要是减轻服务器的压力,这里可以通过Nginx反向代理来进行;

(5)数据库集群:主要是减轻数据库的压力,这里主要是通过master/slave(主从)数据库进行;

(6)使用缓存服务器缓存数据:主要是对于查询频繁的内容进行缓存,这里主要是通过redis进行;

针对数据并发可以从下面的方面进行考虑:

(1)对于方法采取synchronize机制

(2)通过spring的事务隔离级别:主要是用四种

(3)通过数据库的锁机制:表锁和行锁

(4)通过悲观锁和乐观锁

11:Web安全方面的知识点

答:(1)SQL注入:主要发生在登录系统的用户名和密码场景,利用SQL的拼接而导致的问题,所以,可以通过预处理命令来进行对SQL的处理;

(2)密码安全:主要是如果密码存储是以明文的形式,那么当数据泄露之后,就很容易进行用户密码的窃取,所以,可以通过MD5加密,或者SHA和盐值加密;

(3)Cookie安全:主要是通过判断本地是否有对应系统的Cookie值,从而进行修改,以达到直接登录系统的目的,所以,可以通过对Cookie值进行安全性的加密处理,再进行保存;

(4)XSS(跨站脚本攻击):主要是由于编写了脚本内容,导致在页面解析的时候进行脚本语言的解析,通常发生在评论区功能,所以,可以通过字符过滤掉非法字符的形式或者转义字符进行防范;

(4)CSRF(跨站请求伪造):攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在并未授权的情况下执行在权限保护之下的操作;比如用户访问了一个转账的网页(通过get提交),而后面又访问了一个非法链接(而这个链接正好是指向转账网页,那么当点击之后就会发生又一次转账,而受害用户却还不知道),所以,针对这情况,可以采取HTTP referer字段(在http请求头里面,有referer字段用于判断网页的链接源地址),请求中添加token验证,

可以参考这篇文章的CSRF攻击内容:https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/

(5)SYN攻击:主要是由于tcp是一种全连接的方式,而SYN就是利用发送大量的半连接请求,消耗CPU和系统资源,从而导致服务器崩溃;所以,可以利用验证码的方式来进行预防;

可以参考看看这篇文章:https://blog.csdn.net/willie_chen/article/details/50381173

12:请说说关于JDBC的基本操作流程

    1)加载(注册)数据库驱动(到JVM)。-------Class.forname("com.mysql.jdbc.Driver");
    2)建立(获取)数据库连接。---------Connection con=DriverManager.getConnection(url,username,password);
    3)创建(获取)数据库操作对象。------------Statement st = con.createStatement();
    4)定义操作的SQL语句。-------------String sql = "select * from student";
    5)执行数据库操作。---------------ResultSet rst =  st.excuteQuery(sql);
    6)获取并操作结果集。 ---------while(rst.next){ 进行操作 }
    7)关闭对象,回收数据库资源(关闭结果集-->关闭数据库操作对象-->关闭连接)。----rst.close(); st.close();con.close();

13:请说说关于SSO(单点登录)的工作原理

SSO的含义:单点登录全称single sign on,简称SSO,指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权而无需再次登录,包括单点登录和单点注销两部分。

SSO的出现的原因:

(1)由于多级系统之间,如果对每个子系统都单独登录一次,那么这样会导致很麻烦。

(2)由于共享cookie有很多局限性。例如:域名难以统一,子系统技术难以统一。所以,需要一种全新的登录方式实现多系统应用群的登录--单点登录。

SSO实现原理:

登录实现原理:sso需要一个独立的认证中心,只有认证中心能接受用户的用户名密码等安全信息,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,sso认证中心验证用户的用户名密码没问题,创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌,即得到了授权,可以借此创建局部会话,局部会话登录方式与单系统的登录方式相同。具体过程如图所示:

时序图如下:

时序图解析:

1.用户访问系统1的受保护资源,系统1发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数
2.sso认证中心发现用户未登录,将用户引导至登录页面
3.用户输入用户名密码提交登录申请
4.sso认证中心校验用户信息,创建用户与sso认证中心之间的会话,称为全局会话,同时创建授权令牌
5.sso认证中心带着令牌跳转会最初的请求地址(系统1)
6.系统1拿到令牌,去sso认证中心校验令牌是否有效
7.sso认证中心校验令牌,返回有效,注册系统1
8.系统1使用该令牌创建与用户的会话,称为局部会话,返回受保护资源
9.用户访问系统2的受保护资源
10.系统2发现用户未登录,跳转至sso认证中心,并将自己的地址作为参数
11.sso认证中心发现用户已登录,跳转回系统2的地址,并附上令牌
12.系统2拿到令牌,去sso认证中心校验令牌是否有效
13.sso认证中心校验令牌,返回有效,注册系统2

14.系统2使用该令牌创建与用户的局部会话,返回受保护资源骤

注销原理:在一个子系统中注销,所有的子系统都会注销。如下图所示:

时序图解析:

1.用户向系统1发起注销请求
2.系统1根据用户与系统1建立的会话id拿到令牌,向sso认证中心发起注销请求
3.sso认证中心校验令牌有效,销毁全局会话,同时取出所有用此令牌注册的系统地址
4.sso认证中心向所有注册系统发起注销请求
5.各注册系统接收sso认证中心的注销请求,销毁局部会话
6.sso认证中心引导用户至登录页面

14:说说你对RPC的过程理解

答:

RPC主要的重点有:

动态代理,主要是invoke反射原理------ 对应代理层

序列化,使用Thrift的效率高 ------------对应序列化层

通信方式,使用Netty的NIO能提高效率------对应网络层(客户端)和通信层(服务器端)

服务发现,使用zookeeper可以实现

调用过程分析:

1、服务消费方(client)调用以本地调用方式调用服务;

2、client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;

3、client stub找到服务地址,并将消息发送到服务端;

4、server stub收到消息后进行解码;

5、server stub根据解码结果调用本地的服务;

6、本地服务执行并将结果返回给server stub;

7、server stub将返回结果打包成消息并发送至消费方;

8)client stub接收到消息,并进行解码;

9、服务消费方得到最终结果。

15:Tomcat的架构是如何理解的?

答:这个问题主要是考察队Tomcat的理解,毕竟做JavaWeb对于这个是非常重要的,所以,可以从它的结构和每个部件的功能进行分析(Server,Service,Container,connector来分析)。可以通过我绘制的这个图来理解架构:

详细内容可以参考如下的文章:

https://blog.csdn.net/cx520forever/article/details/52743166

16:Tomcat处理Http请求的过程是如何?(这个可以扩展到浏览器请求一个域名,这个过程是如何进行的,这个在我的网络总结专题中是进行了详细分析的)

比如请求:localhost:8080//TestProject/index.jsp
1、请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2、Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3、Engine获得请求localhost:8080//TestProject/index.jsp,匹配它所拥有的所有虚拟主机Host
4、Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5、localhost Host获得请求/TestProject/index.jsp,匹配它所拥有的所有Context
6、Host匹配到路径为/TestProject的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
7、path="/neuq"的Context获得请求/neuq _index.jsp,在它的映射表中寻找对应的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对象返回给客户浏览器
注意一点:其实JSP就是一种servlet,它在内部进行的时候,就会把jsp作为servlet的代码进行分析。所以,针对请求jsp页面和直接请求servlet是类似的方式的。(所以,可以延伸一个知识点jsp和servlet的相同点和共同点)

17:对Ajax了解吗?说说Ajax的工作原理是什么?

含义:Ajax 的全称是AsynchronousJavaScript and XML,其中,Asynchronous 是异步的意思。即能够实现不刷新整个页面,而来进行更新页面的部分内容。
工作原理
简单点描述:

    Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。
复杂的描述:
    Ajax的工作原理相当于在用户和服务器之间加了—个中间层,使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像—些数据验证和数据处理等都交给Ajax引擎自己来做, 只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。
    Ajax其核心只有JavaScript、XMLHTTPRequest和DOM,在旧的交互方式中,由用户触发一个HTTP请求到服务器,服务器对其进行处理后再返回一个新的HTHL页到客户端, 每当服务器处理客户端提交的请求时,客户都只能空闲等待,并且哪怕只是一次很小的交互、只需从服务器端得到很简单的一个数据,都要返回一个完整的HTML页,而用户每次都要浪费时间和带宽去重新读取整个页面。而使用Ajax后用户从感觉上几乎所有的操作都会很快响应没有页面重载(白屏)的等待。
Ajax的优势:
1、减轻服务器的负担。因为Ajax的根本理念是“按需取数据”,所以最大可能在减少了冗余请求和响影对服务器造成的负担;
2、无刷新更新页面,减少用户实际和心理等待时间;
3、也可以把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担,节约空间和带宽租用成本;
4、Ajax使WEB中的界面与应用分离(也可以说是数据与呈现分离);
总结:Ajax的过程主要就是XMLHttpRequest这个对象发挥着非常重要的作用。要理解,它的创建(var xmlHttp = new XMLHttpRequest()),发送请求(xmlHttp.open()和xmlHttp.send()方法),返回状态码(xmlHttp.readyState)和回调函数的使用(xmlHttp.onreadystatechage)以及返回结果的类型(xmlHttp.responseText和xmlHttp.responseXML两种类型)

18:请说说对于正向代理和反向代理有什么理解?

正向代理:用户A访问服务器B的时候,会先连上代理服务器,通过代理服务器去访问服务器。而用户和代理服务器是一个整体,因为代理服务器是为了用户来进行服务的,所以发生的是在客户端。比如,我们访问国外的链接的时候,我们通过翻墙工具和VPN的方式,其实就是一种正向代理的处理。

作用:(1)用户A需要绕过某些障碍访问服务器B ,也就是翻墙(2)用户A需要加速到达B,也就是加速器(3)缓存作用,也就是用户访问服务器都要通过代理服务器,那么别的用户之前访问的内容,代理服务器可以先缓存下来给其他用户使用(4)用户上网的管制,也就是所有用户都只能通过代理服务器来访问(5)匿名访问,也就是代理服务器帮助用户不让服务发现用户的存在,因为服务器是不知道是代理服务器访问还是用户来进行的。

反向代理:就是用户A访问网站的时候,访问到的是反向代理服务器,但是代理服务的内容其实是偷偷从服务器B那里搬过来的,从而实现的一种访问。所以,对于很多的访问量的网站,其实都是利用的一种负载均衡的形式,就常见的就是Nginx。而反向代理中,代理服务器和服务器本身是一个整体,代理服务器是为了服务器而进行的服务,这就区别了正向代理,其发生在服务端

作用:(1)保护原始服务器(2)缓冲和负载均衡(3)内容分发CDN

19:如果数据要通过TCP连接传输出去要怎么办?(底层原理模块知识

例如,web服务对客户端的响应数据,需要通过TCP连接传输给客户端。
TCP/IP协议栈维护着两个缓冲区:send buffer和recv buffer,它们合称为socket buffer。需要通过TCP连接传输出去的数据,需要先复制到send buffer,再复制给网卡通过网络传输出去。如果通过TCP连接接收到数据,数据首先通过网卡进入recv buffer,再被复制到用户空间的app buffer。
同样,在数据复制到send buffer或从recv buffer复制到app buffer时,是CPU参与的拷贝。从send buffer复制到网卡或从网卡复制到recv buffer时,是DMA操作方式的拷贝。

如下图所示,是通过TCP连接传输数据时的过程。

扩展知识:
当某个进程/线程(后文将不加区分的只认为是进程)需要某段数据时,它只能在用户空间中属于它自己的内存中访问、修改,这段内存暂且称之为app buffer(用户缓冲区)。
假设需要的数据在磁盘上,那么进程首先得发起相关系统调用,通知内核去加载磁盘上的文件。但正常情况下,数据只能加载到内核的缓冲区,暂且称之为kernel buffer。

20:说说关于Http请求的方式有哪些?各自特点是什么?

1、OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
2、HEAD
向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
3、GET
向特定的资源发出请求。注意:GET方法不应当被用于产生“副作用”的操作中,例如在WebApplication中,其中一个原因是GET可能会被网络蜘蛛等随意访问。Loadrunner中对应get请求函数:web_link和web_url
4、POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。Loadrunner中对应POST请求函数:web_submit_data,web_submit_form
5、PUT
向指定资源位置上传其最新内容
6、DELETE
请求服务器删除Request-URL所标识的资源
7、TRACE
回显服务器收到的请求,主要用于测试或诊断
8、CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
注意:
1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(MothodNot Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(Not Implemented)。
2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的方法。

21:Http提交form表单和文件的时候,它们之间有什么差别?

enctype的multipart/form-data是专门用于文件上传的MIME格式, 不会对提交数据进行编码,上传的就是原始的二进制编码, 而form表单默认是application/x-www-form-urlencoded的格式, 不适用于文件上传,因为他会把form表中的数据进行编码,空格转换为+, 特殊字符用ASCII码表示.

22:Spring中获取request对象的方法以及线程安全性

(1)直接在controller层方法中传入request对象参数:通过该方法得到的request对象是不同的,是线程安全。

(2)自动注入::通过该方法得到的request对象是不同的,是线程安全。

(3)通过在controller基类中进行自动注入::通过该方法得到的request对象是不同的,是线程安全。

(4)手动调用生成::通过该方法得到的request对象是不同的,是线程安全。

(5)通过@ModelAttribut注解方法::通过该方法得到的request对象是相同的,是线程不安全

综上所述,Controller中加参数(方法1)、自动注入(方法2和方法3)、手动调用(方法4)都是线程安全的,都可以用来获取request对象。如果系统中request对象使用较少,则使用哪种方式均可;如果使用较多,建议使用自动注入(方法2 和方法3)来减少代码冗余。如果需要在非Bean中使用request对象,既可以在上层调用时通过参数传入,也可以直接在方法中通过手动调用(方法4)获得。

23:请说说你平时的controller层的类是多例还是单例?(快手boss二面题)

回答:单例。

那么既然你说单例,那么请看下面的这个题,它能否通过变量'm'进行计算该controller的方法调用的次数呢?为什么呢?

@Control
public class TestController{
	int m = 0 ; //用于记录testMethod方法被调用了多少次
	@RequestMapper(value = "/test")
	public String testMethod(){
		m++;
	}
}

回答:不能,原因如下:

(1)首先,如果是单例的话, 那么确实整个JVM中只会有一份该controller类
(2)但是,即使只有一个实例,如果遇到高并发的请求,那么同时进行请求这个方法的时候
(3)由于这个变量“m”并不是会当值被修改之后会立刻将值同步到主存中
(4)另外,由于JVM对于java程序会存在原子性,顺序性,可见性的处理,而m++操作并不是原子性操作。
(5)而这个时候,正有新的请求过来,而读到的还是之前的变量“m”的值,
(6)那么,由于(3)和(4)的发生,导致数据不一致性,所以变量“m”的计数的值肯定是会<=实际调用的次数的。
(7)如果说等于的情况,那么就是所有的请求都是顺序请求,而没有并发请求,就有可能实现。
(8)如果说小于的情况,那么就是只要存在并发请求,那么就一直会出现。
(9)所以:综合起来就是说,这样的计数方式是不可靠的。

修改为正确的方法有如下几种:

(1)在变量“m”的定义时,添加static和volatile关键字。
原因:因为添加static关键字,可以让该变量存储在常量池中,而且由于java程序的原子性,顺序性,可见性,所以可以利用volatile关键字进行修饰,这样可以让修改后的值立即被同步到主存,但是要保证对于变量“m”的操作必须是原子性操作,然而m++并不是原子性操作,所以,单独这样的方式是不行的,还需要与方法(2)结合。
(2)在testMethod方法加入关键字synchronized
原因:通过这个可以把该方法设置为同步方法,所以对于并发请求的时候,会进行“排队请求”,这样就能解决并发处理。
(3)在testMethod方法中,将m++方法放入到同步代码块中,synchronized(TestController.class){m++}
原因:这个比同步方法好,因为这样减少不必要的同步消耗。
(4)利用JDK中的同步原子类AtomicInteger定义变量m
原因:通过这个类的对象,那么进行的就是同步安全的原子操作(内部是通过CAS实现),所以这样就可以达到并发原子操作
(5)利用面向切面编程中的AOP来进行controller方法的切入。
原因:就类似我们进行日志和事务的处理方式一样,这样才实现方法调用次数的处理,相对前面会麻烦一点。

24:Spring中的事务管理有哪几种方式?

对于Spring中的事务的,有这三API接口需要特别清晰的明白:事务管理器(PlatformTransactionManager),TransactionDefinition接口定义事务隔离级别(五种)和传播行为(七种),以及TransactionStatus接口(主要是可以用于判断事务是否执行完成和是否有保存点)
(1)编程式事务管理(不经常使用

该方式主要是通过手动编码进行的事务管理,所以称为编程式事务管理。其通过在spring配置文件中,注入事务管理器以及事务管理模板transactionTemplate,再将需要进行事务管理的方法代码块进行transactionTemplate执行execute()方法,从而实现事务管理。

(2)声明式事务管理(该方式的第二种和第三种使用最多

第一种方式:基于TransactionProxyFactoryBean的方式。该方法主要是通过动态代理机制进行实现。该方式不经常使用,因为要针对每一个需要事务管理的类都配置一个代理类去管理,很显然,这需要代理的类多了,配置文件内容就多了。

第二种方式:基于AspectJ的XML配置。主要是通过在spring中的xml中,利用AOP的机制原理进行配置事务切面,从而实现事务的管理操作。通过这种方式的开发,可以在xml中很清晰的看到具体的事务管理配置内容。

第三种方式:基于注解的配置。主要是通过在spring中的xml中,配置事务注解的配置。然后在需要进行事务管理的类或者方法上面使用@transactional注解进行设置相关的传播特性和隔离级别以及异常回滚类型等。通过这种方式的开发,配置少,便于我们进行相应的方法和类的控制,但是需要我们对类和方法进行修改。

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource" />
</bean>
 <!-- enable transaction annotation support -->
<tx:annotation-driven transaction-manager="txManager" />

25:请说说SpringMVC的执行流程

(1)用户通过浏览器向服务器发送请求,请求被DispatchServlet捕获;
(2)DispachServlet对请求的URL进行解析,得到请求资源标识符(URI),然后根据URI调用HandMapping将请求映射到处理器HandlerExcutionChain;如果无法映射,那么就表示该请求是一个无效请求,而不进行后续处理,进行相应错误码的返回,
(3)DispatchServlet根据获得Handler选择一个合适的HandlerAdapater适配器处理;
(4)Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatchServlet;
(5)Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispathServlet通过ViewResolver试图解析器将逻辑视图转化为真正的视图View。
(6)DispatchServlet通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。

26:说说Spring中用到了哪些经典的设计模式

(1)单例模式:对于spring容器中的bean,默认都是采取单例模式,但是也可以通过修改bean的protoy来进行修改。
(2)工厂模式:这个主要就是在创建bean的时候,根据传入的类参数来进行创建不同的bean(其实内部就是用map进行存储),这个最明显的就是BeanFacoty
(3)模板模式:为了减少代码的重复,所以在比如JpaTemplate,RestTemplate,JmsTemplate就是采取这种模式的思想。
(4)代理模式:最明显的就是在AOP编程中,如果代理类实现了接口,那么就采取JDK的动态代理,否则就使用CGLIB代理。

27:请说说在Web应用中,对于SimpleDateFormat对象如何实现线程安全?

(1)每次使用的时候,都在方法进行重新创建一个新的对象。这种方法会产生多个对象,增加了负担,但其实正常情况下,影响并不是很大。
(2)通过同步代码块

public class DateCommonUtils{
      private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
      public static String formatDate(Date date)throws ParseException{
          synchronized(sdf){
              return sdf.format(date);
          }  
      }
      
     public static Date parse(String strDate) throws ParseException{
         synchronized(sdf){
             return sdf.parse(strDate);
         }
     } 
 }

(3)通过threadlocal对象

public class DateCommonUtils {
      private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
          @Override
          protected DateFormat initialValue() {
              return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
          }
     };
      public static Date parse(String dateStr) throws ParseException {
          return threadLocal.get().parse(dateStr);
     }
     public static String format(Date date) {
         return threadLocal.get().format(date);
     }
 }

(4)使用其他的日期处理对象,比如jdk1.8中的localtime等等。

28:拦截器和过滤器的区别有哪些?

(1)拦截器是基于java的反射机制的,而过滤器是基于函数回调。
(2)拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
(3)拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
(4)拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
(5)在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
(6)拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

29:Struts2中有哪些常用结果类型?各自的用处是什么?

(1)dispatcher:默认的请求转发的结果类型,Action转发给JSP
(2)chain:Action转发到另外一个Action(同一次请求)
(3)redirect:重定向,重定向到一个路径信息,路径信息没有限制(不在一个请求)Action重定向到JSP
(4)dedircAction:Action重定向到另一个Action
(5)stream:将原始数据作为流传递回浏览器,该结果类型对下载图片和内容很有好处。
(6)freemarker:呈现freemarker模板
(7)plaintext:返回普通文本内容

30:Hibernate中的get和load查询有什么区别?

(1)get是立即加载,而load是懒加载
(2)get是先查询一级缓存,再查询二级缓存,再进行数据库的查询。而load是先查询一级缓存,如果没有找到,就创建一个代理对象,等需要的时候去查询二级缓存和数据库
(3)get如果没有找到,则返回的是null,而load如果没有找到,则返回异常
(4)当我们使用session。load()方法进行加载一个对象时,此时并不会发出sql语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实体对象的id值,只有当我们要使用这个对象,得到其他属性时,这个时候才会发出sql语句,从数据库去查询我们的对象。相对于load的延迟加载方式,get就直接多了,当我们使用session.get()方法来得到一个对象时,不管我们使用不使用这个对象,此时都会发出sql语句去从数据库中查询出来。

31:请说说Quartz是否有用过?里面的核心对象有哪些?作用分别是什么?

Quartz是一个定时调度的框架,使用起来非常简单,功能也非常强大,适合对于有规律的任务进行调度执行。
核心的对象主要有:
(1)Scheduler:待办一个调度容器,一个调度容器中可以注册多个JobDetail和Trigger。当Trigger与JobDetail组合,就可以被Scheduler容器调度了。
(2)Trigger:代表一个调度参数的配置,也就是设置什么时候进行调度处理
(3)JobDeatil:表示一个具体的可执行的调度程序,Job是这个可执行程序调度程序所要执行的内容,另外JobDetail还包含了这个任务调度的方案和策略。其实就是设置需要进行处理的参数
(4)Job:表示一个任务,即就是要进行的操作

32:在Spring中获取request对象的方法以及线程安全性分析?(Web)

https://mp.weixin.qq.com/s/16TRbbsyJwisFwpIFQEa4w

33:禁止Cookie是否还能够登录系统?是否还能够操作系统中的功能模块?(58到家二面)

(1)能够:因为在登录的时候,并没有采取和cookie相关的内容,进行登录主要是采取用户名和密码的匹配关系,只是在登录之后,会存在返回给浏览器一个cookie的值。
(2)不能够。因为系统判定是谁登录系统的话,主要是通过cookie中的SESSINID进行判断的。如果现在禁止了cookie,那么就会存在一个问题,系统无法得到sessionID,无法判断获取当前登录人是谁,那么这样就会导致系统混乱。所以,是无法操作系统的模块。

34:针对Spring中的循环依赖的问题和解决办法?(百度二面)

https://blog.csdn.net/jijianshuai/article/details/78122738

https://blog.csdn.net/quliuwuyiz/article/details/79416184

35:

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值