Java面试系列总结 :JavaWEB

1. 说下原生jdbc操作数据库流程?

  • 第一步:Class.forName()加载数据库连接驱动;
  • 第二步:DriverManager.getConnection()获取数据连接对象;
  • 第三步:根据SQL获取sql会话对象,有2种方式 Statement、PreparedStatement ;
  • 第四步:执行SQL处理结果集,执行SQL前如果有参数值就设置参数值setXXX();
  • 第五步:关闭结果集、关闭会话、关闭连接。

详细代码请看(封装):http://blog.csdn.net/qq_29542611/article/details/52426006

2. 为什么要使用PreparedStatement?

  1. PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象。
  2. 作为 Statement 的子类 , PreparedStatement 继承了 Statement 的所有功能 。 三种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数
  3. 在 JDBC应用中,在任何时候都不要使用Statement,原因如下:
    一、代码的可读性和可维护性.Statement需要不断地拼接,而PreparedStatement不会。
    二、PreparedStatement尽最大可能提高性能.DB有缓存机制,相同的预编译语句再次被调用不会再次需要编译。
    三、最重要的一点是极大地提高了安全性.Statement 容易被 SQL 注入,而 PreparedStatementc 传入的内容不会和sql语句发生任何匹配关系。

3. 关系数据库中连接池的机制是什么?

前提:为数据库连接建立一个缓冲池。

  1. 从连接池获取或创建可用连接
  2. 使用完毕之后,把连接返回给连接池
  3. 在系统关闭前,断开所有连接并释放连接占用的系统资源
  4. 能够处理无效连接,限制连接池中的连接总数不低于或者不超过某个限定值。

其中有几个概念需要大家理解:

  • 最小连接数是连接池一直保持的数据连接。如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费掉。

  • 最大连接数是连接池能申请的最大连接数。如果数据连接请求超过此数,后面的数据连接请求将被加入到等待队列中,这会影响之后的数据库操作。

  • 如果最小连接数与最大连接数相差太大,那么,最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。

  • 上面的解释,可以这样理解:数据库池连接数量一直保持一个不少于最小连接数的数量,当数量不够时,数据库会创建一些连接,直到一个最大连接数,之后连接数据库就会等待。

4. http的长连接和短连接

HTTP协议有HTTP/1.0版本和HTTP/1.1版本。HTTP1.1默认保持长连接(HTTP persistent connection,也翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据;相反的就是短连接。

在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。从HTTP/1.1起,默认使用的是长连接,用以保持连接特性。

5. HTTP/1.1与HTTP/1.0的区别

1) 可扩展性

可扩展性的一个重要原则:如果HTTP的某个实现接收到了自身未定义的头域,将自动忽略它。

Ø 在消息中增加版本号,用于兼容性判断。注意,版本号只能用来判断逐段(hop-by-hop)的兼容性,而无法判断端到端(end-to-end)的兼容性。
例如,一台HTTP/1.1的源服务器从使用HTTP/1.1的Proxy那儿接收到一条转发的消息,实际上源服务器并不知道终端客户使用的是HTTP/1.0还是HTTP/1.1。因此,HTTP/1.1定义Via头域,用来记录消息转发的路径,它记录了整个路径上所有发送方使用的版本号。

Ø HTTP/1.1增加了OPTIONS方法,它允许客户端获取一个服务器支持的方法列表。

Ø 为了与未来的协议规范兼容,HTTP/1.1在请求消息中包含了Upgrade头域,通过该头域,客户端可以让服务器知道它能够支持的其它备用通信协议,服务器可以据此进行协议切换,使用备用协议与客户端进行通信。

2) 缓存

在HTTP/1.0中,使用Expire头域来判断资源的fresh或stale,并使用条件请求(conditional request)来判断资源是否仍有效。例如,cache服务器通过If-Modified-Since头域向服务器验证资源的Last-Modefied头域是否有更新,源服务器可能返回304(Not Modified),则表明该对象仍有效;也可能返回200(OK)替换请求的Cache对象。

此外,HTTP/1.0中还定义了Pragma:no-cache头域,客户端使用该头域说明请求资源不能从cache中获取,而必须回源获取。

HTTP/1.1在1.0的基础上加入了一些cache的新特性,当缓存对象的Age超过Expire时变为stale对象,cache不需要直接抛弃stale对象,而是与源服务器进行重新激活(revalidation)。

HTTP/1.0中,If-Modified-Since头域使用的是绝对时间戳,精确到秒,但使用绝对时间会带来不同机器上的时钟同步问题。而HTTP/1.1中引入了一个ETag头域用于重激活机制,它的值entity tag可以用来唯一的描述一个资源。请求消息中可以使用If-None-Match头域来匹配资源的entitytag是否有变化。

为了使caching机制更加灵活,HTTP/1.1增加了Cache-Control头域(请求消息和响应消息都可使用),它支持一个可扩展的指令子集:例如max-age指令支持相对时间戳;private和no-store指令禁止对象被缓存;no-transform阻止Proxy进行任何改变响应的行为。

Cache使用关键字索引在磁盘中缓存的对象,在HTTP/1.0中使用资源的URL作为关键字。但可能存在不同的资源基于同一个URL的情况,要区别它们还需要客户端提供更多的信息,如Accept-Language和Accept-Charset头域。为了支持这种内容协商机制(content negotiation mechanism),HTTP/1.1在响应消息中引入了Vary头域,该头域列出了请求消息中需要包含哪些头域用于内容协商。

3) 带宽优化

HTTP/1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了。例如,客户端只需要显示一个文档的部分内容,又比如下载大文件时需要支持断点续传功能,而不是在发生断连后不得不重新下载完整的包。

HTTP/1.1中在请求消息中引入了range头域,它允许只请求资源的某个部分。在响应消息中Content-Range头域声明了返回的这部分对象的偏移值和长度。如果服务器相应地返回了对象所请求范围的内容,则响应码为206(Partial Content),它可以防止Cache将响应误以为是完整的一个对象。

另外一种情况是请求消息中如果包含比较大的实体内容,但不确定服务器是否能够接收该请求(如是否有权限),此时若贸然发出带实体的请求,如果被拒绝也会浪费带宽。

HTTP/1.1加入了一个新的状态码100(Continue)。客户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。注意,HTTP/1.0的客户端不支持100响应码。但可以让客户端在请求消息中加入Expect头域,并将它的值设置为100-continue。

节省带宽资源的一个非常有效的做法就是压缩要传送的数据。Content-Encoding是对消息进行端到端(end-to-end)的编码,它可能是资源在服务器上保存的固有格式(如jpeg图片格式);在请求消息中加入Accept-Encoding头域,它可以告诉服务器客户端能够解码的编码方式。

而Transfer-Encoding是逐段式(hop-by-hop)的编码,如Chunked编码。在请求消息中加入TE头域用来告诉服务器能够接收的transfer-coding方式,

4) 长连接

HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求。此外,由于大多数网页的流量都比较小,一次TCP连接很少能通过slow-start区,不利于提高带宽利用率。

HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。例如:一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接。

HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。

在HTTP/1.0中,要建立长连接,可以在请求消息中包含Connection: Keep-Alive头域,如果服务器愿意维持这条连接,在响应消息中也会包含一个Connection: Keep-Alive的头域。同时,可以加入一些指令描述该长连接的属性,如max,timeout等。

事实上,Connection头域可以携带三种不同类型的符号:
1、一个包含若干个头域名的列表,声明仅限于一次hop连接的头域信息;
2、任意值,本次连接的非标准选项,如Keep-Alive等;
3、close值,表示消息传送完成之后关闭长连接;

客户端和源服务器之间的消息传递可能要经过很多中间节点的转发,这是一种逐跳传递(hop-by-hop)。HTTP/1.1相应地引入了hop-by-hop头域,这种头域仅作用于一次hop,而非整个传递路径。每一个中间节点(如Proxy,Gateway)接收到的消息中如果包含Connection头域,会查找Connection头域中的一个头域名列表,并在将消息转发给下一个节点之前先删除消息中这些头域。

通常,HTTP/1.0的Proxy不支持Connection头域,为了不让它们转发可能误导接收者的头域,协议规定所有出现在Connection头域中的头域名都将被忽略。

5) 消息传递

HTTP消息中可以包含任意长度的实体,通常它们使用Content-Length来给出消息结束标志。但是,对于很多动态产生的响应,只能通过缓冲完整的消息来判断消息的大小,但这样做会加大延迟。如果不使用长连接,还可以通过连接关闭的信号来判定一个消息的结束。

HTTP/1.1中引入了Chunkedtransfer-coding来解决上面这个问题,发送方将消息分割成若干个任意大小的数据块,每个数据块在发送时都会附上块的长度,最后用一个零长度的块作为消息结束的标志。这种方法允许发送方只缓冲消息的一个片段,避免缓冲整个消息带来的过载。

在HTTP/1.0中,有一个Content-MD5的头域,要计算这个头域需要发送方缓冲完整个消息后才能进行。而HTTP/1.1中,采用chunked分块传递的消息在最后一个块(零长度)结束之后会再传递一个拖尾(trailer),它包含一个或多个头域,这些头域是发送方在传递完所有块之后再计算出值的。发送方会在消息中包含一个Trailer头域告诉接收方这个拖尾的存在。

6) Host头域

在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。

HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。此外,服务器应该接受以绝对路径标记的资源请求。

7) 错误提示

HTTP/1.0中只定义了16个状态响应码,对错误或警告的提示不够具体。HTTP/1.1引入了一个Warning头域,增加对错误或警告信息的描述。

此外,在HTTP/1.1中新增了24个状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

8) 内容协商

为了满足互联网使用不同母语和字符集的用户,一些网络资源有不同的语言版本(如中文版、英文版)。HTTP/1.0定义了内容协商(contentnegotiation)的概念,也就是说客户端可以告诉服务器自己可以接收以何种语言(或字符集)表示的资源。例如如果服务器不能明确客户端需要何种类型的资源,会返回300(Multiple Choices),并包含一个列表,用来声明该资源的不同可用版本,然后客户端在请求消息中包含Accept-Language和Accept-Charset头域指定需要的版本。

就像有些人会说几门外语,但每种外语的流利程度并不相同。类似地,网络资源也可以有不同的表达形式,比如有母语版和各种翻译版本。HTTP引入了一个品质因子(quality values)的概念来表示不同版本的可用性,它的取值从0.0到1.0。例如一个母语是英语的人也能讲法语、甚至还学了点丹麦语,那么他的浏览器可用作如下配置:Accept-Language: en, fr;q=0.5, da;q=0.1。这时,服务器会优先选取品质因子高的值对应的资源版本作为响应。

6. http常见的状态码有哪些?

  • 200 OK //客户端请求成功
  • 301 Moved Permanently(永久移除),请求的URL已移走。Response中应该包含一个Location URL, 说明资源现在所处的位置
  • 302 found 重定向
  • 400 Bad Request //客户端请求有语法错误,不能被服务器所理解
  • 401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
  • 403 Forbidden //服务器收到请求,但是拒绝提供服务
  • 404 Not Found //请求资源不存在,eg:输入了错误的URL
  • 500 Internal Server Error //服务器发生不可预期的错误
  • 503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

7. GET和POST的区别?

从表面现像上面看GET和POST的区别:

  1. GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=zhagnsan&password=123456。POST把提交的数据则放置在是HTTP包的包体中。
  2. GET方式提交的数据最多只能是1024字节,理论上POST没有限制,可传较大量的数据。其实这样说是错误的,不准确的:
    “GET方式提交的数据最多只能是1024字节",因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了。而实际上,URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。 IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
  3. POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在 URL 上,因为(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site request forgery攻击。
    Get是向服务器发索取数据的一种请求,而Post是向服务器提交数据的一种请求,在FORM(表单)中,Method默认为"GET",实质上,GET和POST只是发送机制不同,并不是一个取一个发!

参考原文:https://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html

8. http中重定向和请求转发的区别?

  • 本质区别:转发是服务器行为,重定向是客户端行为。
  • 重定向特点:两次请求,浏览器地址发生变化,可以访问自己web之外的资源,传输的数据会丢失。
  • 请求转发特点:一次强求,浏览器地址不变,访问的是自己本身的web资源,传输的数据不会丢失。

9. Cookie和Session的区别

Cookie 是 web 服务器发送给浏览器的一块信息,浏览器会在本地一个文件中给每个 web 服务器存储 cookie。以后浏览器再给特定的web服务器发送请求时,同时会发送所有为该服务器存储的cookie。

Session 是存储在 web 服务器端的一块信息。session 对象存储特定用户会话所需的属性及配置信息。当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

Cookie和session的不同点:

  1. 无论客户端做怎样的设置,session都能够正常工作。当客户端禁用cookie时将无法使用cookie。
  2. 在存储的数据量方面:session能够存储任意的java对象,cookie只能存储String类型的对象。

10. session共享怎么做的(分布式如何实现session共享)

问题描述:一个用户在登录成功以后会把用户信息存储在session当中,这时session所在服务器为server1,那么用户在session失效之前如果再次使用app,那么可能会被路由到server2,这时问题来了,server没有该用户的session,所以需要用户重新登录,这时的用户体验会非常不好,所以我们想如何实现多台server之间共享session,让用户状态得以保存。

当然业界已经有很多成熟的解决方案,我罗列如下:
1.服务器实现的session复制或session共享,这类型的共享session是和服务器紧密相关的,比如webSphere或JBOSS在搭建集群时候可以配置实现session复制或session共享,但是这种方式有一个致命的缺点,就是不好扩展和移植,比如我们更换服务器,那么就要修改服务器配置。

2.利用成熟的技术做session复制,比如12306使用的gemfire,比如常见的内存数据库如redis或memorycache,这类方案虽然比较普适,但是严重依赖于第三方,这样当第三方服务器出现问题的时候,那么将是应用的灾难。

3.将session维护在客户端,很容易想到就是利用cookie,但是客户端存在风险,数据不安全,而且可以存放的数据量比较小,所以将session维护在客户端还要对session中的信息加密。

我们实现的方案可以说是第二种方案和第三种方案的合体,可以利用gemfire实现session复制共享,还可以将session维护在redis中实现session共享,同时可以将session维护在客户端的cookie中,但是前提是数据要加密。这三种方式可以迅速切换,而不影响应用正常执行。我们在实践中,首选gemfire或者redis作为session共享的载体,一旦session不稳定出现问题的时候,可以紧急切换cookie维护session作为备用,不影响应用提供服务,下面我简单介绍方案中session共享的实现方式和原理。

这里主要讲解redis和cookie方案,gemfire比较复杂大家可以自行查看gemfire工作原理。利用redis做session共享,首先需要与业务逻辑代码解耦,不然session共享将没有意义,其次支持动态切换到客户端cookie模式。redis的方案是,重写服务器中的HttpSession和HttpServletRequest,首先实现HttpSession接口,重写session的所有方法,将session以hash值的方式存在redis中,一个session的key就是sessionID,setAtrribute重写之后就是更新redis中的数据,getAttribute重写之后就是获取redis中的数据,等等需要将HttpSession的接口一一实现。

实现了HttpSesson,那么我们先将该session类叫做MySession(当然实践中不是这么命名的),当MySession出现之后问题才开始,怎么能在不影响业务逻辑代码的情况下,还能让原本的request.getSession()获取到的是MySession,而不是服务器原生的session。这里,我决定重写服务器的HttpServletRequet,这里先称为MyRequest,但是这可不是单纯的重写,我需要在原生的request基础上重写,于是我决定在filter中,实现request的偷梁换柱,我的思路是这样的,MyRequest的构建器,必须以request作为参数,于是我在filter中将服务器原生的request(也有可能是框架封装过的request),当做参数new出来一个MyRequest,并且MyRequest也实现了HttpServletRequest接口,其实就是对原生request的一个增强,这里主要重写了几个request的方法,但是最重要的是重写了request.getSession(),写到这里大家应该都明白为什么重写这个方法了吧,当然是为了获取MySession,于是这样就在filter中,偷偷的将原生的request换成MyRequest了,然后再将替换过的request传入chan.doFilter(),这样filter时候的代码都使用的是MyRequest了,同时对业务代码是透明的,业务代码获取session的方法仍然是request.getSession(),但其实获取到的已经是MySession了,这样对session的操作已经变成了对redis的操作。这样实现的好处有两个,第一开发人员不需要对session共享做任何关注,session共享对用户是透明的;第二,filter是可配置的,通过filter的方式可以将session共享做成一项可插拔的功能,没有任何侵入性。

这个时候已经实现了一套可插拔的session共享的框架了,但是我们想到如果redis服务出了问题,这时我们该怎么办呢,于是我们延续redis的想法,想到可以将session维护在客户端内(加密的cookie),当然实现方法还是一样的,我们重写HttpSession接口,实现其所有方法,比如setAttribute就是写入cookie,getAttribute就是读取cookie,我们可以将重写的session称作MySession2,这时怎么让开发人员透明的获取到MySession2呢,实现方法还是在filter内偷梁换柱,在MyRequest加一个判断,读取sessionType配置,如果sessionType是redis的,那么getSession的时候获取到的是MySession,如果sessionType是coolie的,那么getSession的时候获取到的是MySession2,以此类推,用同样的方法就可以获取到MySession 3,4,5,6等等。

这样两种方式都有了,那么我们怎实现两种session共享方式的快速切换呢,刚刚我提到一个sessionType,这是用来决定获取到session的类型的,只要变换sessionType就能实现两种session共享方式的切换,但是sessionType必须对所有的服务器都是一致的,如果不一致那将会出现比较严重的问题,我们目前是将sessionType维护在环境变量里,如果要切换sessionType就要重启每一台服务器,完成session共享的转换,但是当服务器太多的时候将是一种灾难。而且重启服务意味着服务的中断,所以这样的方式只适合服务器规模比较小,而且用户量比较少的情况,当服务器太多的时候,务必需要一种协调技术,能够让服务器能够及时获取切换的通知。基于这样的原因,我们选用zookeeper作为配置平台,每一台服务器都会订阅zookeeper上的配置,当我们切换sessionType之后,所有服务器都会订阅到修改之后的配置,那么切换就会立即生效,当然可能会有短暂的时间延迟,但这是可以接受的。

参考原文:http://blog.csdn.net/sxiaobei/article/details/57086489

11. 在单点登录中,如果cookie被禁用了怎么办?

单点登录的原理是后端生成一个 session ID,然后设置到 cookie,后面的所有请求浏览器都会带上 cookie,然后服务端从 cookie 里获取 session ID,再查询到用户信息。所以,保持登录的关键不是 cookie,而是通过 cookie 保存和传输的 session ID,其本质是能获取用户信息的数据。除了 cookie,还通常使用 HTTP 请求头来传输。但是这个请求头浏览器不会像 cookie 一样自动携带,需要手工处理。

12. 什么是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程序,实现页面交互。

13. jsp有哪些域对象和内置对象及他们的作用?

四大域对象:

(1)pageContext page域-指当前页面,在当前jsp页面有效,跳到其它页面失效
(2)request request域-指一次请求范围内有效,从http请求到服务器处理结束,返回响应的整个过程。
在这个过程中使用forward(请求转发)方式跳转多个jsp,在这些页面里你都可以使用这个变量
(3)session session域-指当前会话有效范围,浏览器从打开到关闭过程中,转发、重定向均可以使用
(4)application context域-指只能在同一个web中使用,服务器未关闭或者重启,数据就有效

九大内置对象:

1)request对象

request 对象是 javax.servlet.httpServletRequest类型的对象。 该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。(包括头信息、系统信息、请求方式以及请求参数等)。request对象的作用域为一次请求。

2)response对象

response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。response对象也具有作用域,它只在JSP页面内有效。

3)session对象

session 对象是由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。

4)application对象

application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。

5)out 对象

out 对象用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。待数据输出完毕后,要及时关闭输出流。

6)pageContext 对象

pageContext 对象的作用是取得任何范围的参数,通过它可以获取 JSP页面的out、request、reponse、session、application 等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。

7)config 对象

config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。

8)page 对象

page 对象代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。

9)exception 对象

exception 对象的作用是显示异常信息,只有在包含 isErrorPage=“true” 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。

14. 什么是xml,使用xml的优缺点,xml的解析器有哪几种,分别有什么区别?

xml是一种可扩展性标记语言,支持自定义标签(使用前必须预定义)使用DTD和XML Schema标准化XML结构。

具体了解xml详见:http://www.importnew.com/10839.html

优点:用于配置文件,格式统一,符合标准;用于在互不兼容的系统间交互数据,共享数据方便;

缺点:xml文件格式复杂,数据传输占流量,服务端和客户端解析xml文件占用大量资源且不易维护 Xml常用解析器有2种,分别是:DOM和SAX;

主要区别在于它们解析xml文档的方式不同。使用DOM解析,xml文档以DOM 树形结构加载入内存,而SAX采用的是事件模型。

详细区别:https://wenku.baidu.com/view/fc3fb5610b1c59eef8c7b410.html

15. 监听器(Listener)有哪些作用和用法?

Java Web开发中的监听器(listener)就是application、session、request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件,如下所示:

①ServletContextListener:对Servlet上下文的创建和销毁进行监听。
②ServletContextAttributeListener:监听Servlet上下文属性的添加、删除和替换。
③HttpSessionListener:对Session的创建和销毁进行监听。

  • 补 充:session的销毁有两种情况:
  • session超时(可以在web.xml中通过/标签配置超时时间);
  • 通过调用session对象的invalidate()方 法使session失效。

④HttpSessionAttributeListener:对Session对象中属性的添加、删除和替换进行监听。
⑤ServletRequestListener:对请求对象的初始化和销毁进行监听。
⑥ServletRequestAttributeListener:对请求对象属性的添加、删除和替换进行监听。

常见的监听器用途主要包括:网站在线人数技术、监听用户的行为(管理员踢人)

16. 过滤器(Filter)有哪些作用和用法?

Java Web开发中的过滤器(filter)是从Servlet 2.3规范开始增加的功能,并在Servlet 2.4规范中得到增强。对Web应用来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端和服务器之间的请求与响应信息,并对这些信息进行过 滤。当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个资源相关联。如果有,那么容器将把请求交给过滤器进行处理。在过滤器中,你可以改变请求的内容,或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时候,容器同样会将响应先转发给过滤器,再过滤器中, 你可以对响应的内容进行转换,然后再将响应发送到客户端。

常见的过滤器用途主要包括:对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过滤或替换、转换图象格式、对响应内容进行压缩以减少传输量、对请求或响应进行加解密处理、触发资源访问事件、对XML的输出应用XSLT等。

和过滤器相关的接口主要有:Filter、FilterConfig、FilterChain

17. 谈谈你对ajax的认识?

Ajax是一种创建交互式网页应用的的网页开发技术;Asynchronous JavaScript and XML”的缩写。

Ajax的优势:

  • 通过异步模式,提升了用户体验。
  • 优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用。
  • Ajax引擎在客户端运行,承担了一部分本来由服务器承担的工作,从而减少了大用户量下的服务器负载。

Ajax的最大特点:

  • 可以实现局部刷新,在不更新整个页面的前提下维护数据,提升用户体验度。
注意ajax 在 实 际 项 目 开 发 中 使 用 率 非 常 高 ( 牢 固 掌 握 ) , 针 对 ajax 的 详 细 描 述 :http://www.jb51.net/article/93258.htm

18. jsonp原理

JavaScript是一种在Web开发中经常使用的前端动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略)。这一策略对于JavaScript代码能够访问的页面内容做了很重要的限制,即JavaScript只能访问与包含它的文档在同一域下的内容。

JavaScript 这个安全策略在进行多 iframe 或多窗口编程、以及 Ajax 编程时显得尤为重要。根据这个策略,在 baidu.com 下的页面中包含的 JavaScript 代码,不能访问在 google.com 域名下的页面内容;甚至不同的子域名之间的页面也不能通过 JavaScript 代码互相访问。对于 Ajax 的影响在于,通过 XMLHttpRequest 实现的Ajax 请求,不能向不同的域提交请求,例如,在 abc.example.com 下的页面,不能向 def.example.com 提交Ajax请求,等等。

然而,当进行一些比较深入的前端编程的时候,不可避免地需要进行跨域操作,这时候“同源策略”就显得过于苛刻。JSONP跨域GET请求是一个常用的解决方案,下面我们来看一下JSONP跨域是如何实现的,并且探讨下JSONP跨域的原理。

jsonp 的最基本的原理是:动态添加一个<script>标签,使用 script 标签的 src 属性没有跨域的限制的特点实现跨域。首先在客户端注册一个 callback, 然后把 callback 的名字传给服务器。此时,服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个 function , function 名字就是传递上来的参数 jsonp。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。 客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里。

参考资料:http://www.nowamagic.net/librarys/veda/detail/224

19. 说一下常用的Linux命令

  • 列出文件列表:ls 【参数 -a -l】
  • 创建目录和移除目录:mkdir rmdir
  • 用于显示文件后几行内容:tail
  • 打包:tar -xvf
  • 打包并压缩:tar -zcvf
  • 查找字符串:grep
  • 显示当前所在目录:pwd
  • 创建空文件:touch
  • 编辑器:vim vi
  • 列出文件列表:ls 【参数 -a -l】
  • 创建目录和移除目录:mkdir rmdir
  • 用于显示文件后几行内容:tail
  • 打包:tar -xvf
  • 打包并压缩:tar -zcvf
  • 查找字符串:grep
  • 显示当前所在目录:pwd
  • 创建空文件:touch
  • 编辑器:vim vi

20. Linux中如何查看日志?

动态打印日志信息:tail –f 日志文件

参考资料:https://www.cnblogs.com/zdz8207/p/linux-log-tail-cat-tac.html

21. Linux怎么关闭进程

通常用ps 查看进程PID ,用kill命令终止进程。

ps 命令用于查看当前正在运行的进程。
grep 是搜索
例如: ps -ef | grep java
表示查看所有进程里CMD是java的进程信息。

ps -aux | grep java
-aux 显示所有状态
kill 命令用于终止进程。
例如: kill -9 [PID]
-9表示强迫进程立即停止。

22. 解释一下什么是 Servlet, 说一说 Servlet 的生命周期

Servlet是一种服务器端的Java应用程序,具有独立于平台和协议的特性,可以生成动态的Web页面。 它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应(HTTP服务器上的数据库或应用程序)的中间层。 Servlet是位于Web 服务器内部的服务器端的Java应用程序,与传统的从命令行启动的Java应用程序不同,Servlet由Web服务器进行加载,该Web服务器必须包含支持Servlet的Java虚拟机 。

Servlet生命周期可以分成四个阶段:加载和实例化、初始化、服务、销毁。 当客户第一次请求时,首先判断是否存在 Servlet 对象,若不存在,则由 Web 容器创建对象,而后调用 init()方
法对其初始化,此初始化方法在整个Servlet生命周期中只调用一次。

完成Servlet对象的创建和实例化之后,Web容器会调用Servlet对象的service()方法来处理请求。

当Web容器关闭或者Servlet对象要从容器中被删除时,会自动调用destory()方法。

23. 如何从 cookie 中拿到 session?

session 在服务器端,cookie 在客户端(浏览器),session 默认被存在在服务器的一个文件里(不是内存),session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id);

session 可以放在 文件、数据库、或内存中都可以。

用户验证这种场合一般会用 session ,因此,维持一个会话的核心就是客户端的唯一标识,即 session id

24. 列举 Maven 常见的六种依赖范围

  1. compile:编译依赖范围(默认),对其三种都有效
  2. test:测试依赖范围,只对测试classpath有效
  3. runtime:运行依赖范围,只对测试和运行有效,编译主代码无效,例如JDBC
  4. provided:已提供依赖范围,只对编译和测试有效,运行时无效,例如selvet-api
  5. system:系统依赖范围.谨慎使用.例如本地的,maven仓库之外的类库文件
  6. import(maven2.0.9以上):导入依赖范围,不会对其他三种有影响

25. 简述 SSH 的概念以及中主要的设计思想?

SSH是 struts+spring+hibernate的一个集成框架,是目前比较流行的一种Web应用程序开源框架。

集成SSH框架的系统从职责上分为四层:表示层、业务逻辑层、数据持久层和域模块层,以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的Web应用程序。其中使用Struts作为系统的整体基础架构,负责MVC的分离,在Struts框架的模型部分,控制业务跳转,利用Hibernate框架对持久层提供支持,Spring做管理,管理struts和hibernate。具体做法是:用面向对象的分析方法根据需求提出一些模型,将这些模型实现为基本的Java对象,然后编写基本的DAO(Data Access Objects)接口,并给出Hibernate的DAO实现,采用Hibernate架构实现的DAO类来实现Java类与数据库之间的转换和访问,最后由Spring做管理

**26. Lunix 下如何让命令在后台执行? **

要让程序在后台执行,只需在命令行的最后加上“&”符号。
例如:$ find . -name abc -print&;

27. 日志打印的 log4j 的配置中%t 表示什么?

%t 输出产生该日志事件的线程名

扩展:

  • %M是输出方法的名字
  • %m 输出代码中指定的消息
  • %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
  • %r 输出自应用启动到输出该log信息耗费的毫秒数
  • %c 输出所属的类目,通常就是所在类的全名
  • %t 输出产生该日志事件的线程名
  • %n 输出一个回车换行符,Windows平台为"rn”,Unix平台为"n”
  • %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy MM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921 %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。
  • %x: 输出和当前线程相关联的 NDC(嵌套诊断环境),尤其用到像 java servlets 这样的多客户多线程的应用中。
  • %%: 输出一个”%”字符
  • %F: 输出日志消息产生时所在的文件名称
  • %M: 输出执行方法
  • %L: 输出代码中的行号

28. 说出常见的 5 个 linux 系统日志,至少 3 个并做简述日志的用途。

access-log 纪录HTTP/web的传输
acct/pacct 纪录用户命令
aculog 纪录MODEM的活动
btmp 纪录失败的纪录
lastlog 纪录最近几次成功登录的事件和最后一次不成功的登录
messages 从syslog中记录信息(有的链接到syslog文件)
sudolog 纪录使用sudo发出的命令
sulog 纪录使用su命令的使用
syslog 从syslog中记录信息(通常链接到messages文件)
utmp 纪录当前登录的每个用户
wtmp 一个用户每次登录进入和退出时间的永久纪录
xferlog 纪录FTP会话

原文链接:http://os.51cto.com/art/200711/60313.htm

29. EJB 程序与普通的 java 程序区别有哪些?

EJB是sun的服务器端组件模型,最大的用处是部署分布式应用程序当然,还有许多方式可以实现分布式应用,类似微软的.net 技术。凭借 java 跨平台的优势,用 EJB 技术部署的分布式系统可以不限于特定的平台。EJB (EnterpriseJavaBean)是J2EE的一部分,定义了一个用于开发基于组件的企业多重应用程序的标准。其特点包括网络服务支持和核心开发工具(SDK)。 在J2EE里,Enterprise Java Beans(EJB)称为Java 企业 Bean,是Java的核心代码,分别是会话Bean(Session Bean),实体Bean(Entity Bean)和消息驱动Bean(MessageDriven Bean)。

简单来讲:比如做一个工程就和盖房子,如果,你会 java,那么你就拥有了基本的技能,一步一步累砖,总能把房子盖好但是 EJB 就是一个框架,盖房子的时候,先有这个框架,然后你根据这个框架去累砖,房子就会盖的又快又好。java是基础,EJB是在java上发展出来的模型,框架。

原文链接:http://blog.csdn.net/cs_fei/article/details/9824639

30. 请简述什么是集群?—了解就可以

服务器集群就是指将很多服务器集中起来一起进行同一种服务,在客户端看来就象是只有一个服务器。集群可以利用多个计算机进行并行计算从而获得很高的计算速度,也可以用多个计算机做备份,从而使得任何一个机器坏了整个系统还是能正常运行。一旦在服务器上安装并运行了群集服务,该服务器即可加入群集。群集化操作可以减少单点故障数量,并且实现了群集化资源的高可用性。下述各节简要介绍了群集创建和群集操作中的节点行为。

31. 继承(inheritance)的优缺点是什么?

优点
新的实现很容易,因为大部分是继承而来的 。很容易修改和扩展已有的实现
缺点
打破了封装,因为基类向子类暴露了实现细节 ,白盒重用,因为基类的内部细节通常对子类是可见的 ,当父类的实现改变时可能要相应的对子类做出改变 ,不能在运行时改变由父类继承来的实现。由此可见,组合比继承具有更大的灵活性和更稳定的结构,一般情况下应该优先考虑组合。只有当下列条件满足时才考虑使用继承: 子类是一种特殊的类型,而不只是父类的一个角色 ,子类的实例不需要变成另一个类的对象子类扩展,而不是覆盖或者使父类的功能
失效。

32. 为什么要使用接口和抽象类?

Java 接口和Java 抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP面向对象的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为你结构层次上的顶层。

1、Java接口和Java抽象类最大的一个区别,就在于Java抽象类可以提供某些方法的部分实现,而Java接口不可以,这大概就是Java抽象类唯一的优点吧,但这个优点非常有用。 如果向一个抽象类里加入一个新的具体方法时,那么它所有的子类都一下子都得到了这个新方法,而 Java 接口做不到这一点,如果向一个 Java 接口里加入一个新方法,所有实现这个接口的类就无法成功通过编译了,因为你必须让每一个类都再实现这个方法才行.

2、一个抽象类的实现只能由这个抽象类的子类给出,也就是说,这个实现处在抽象类所定义出的继承的等级结构中,而由于 Java 语言的单继承性,所以抽象类作为类型定义工具的效能大打折扣。 在这一点上,Java 接口的优势就出来了,任何一个实现了一个 Java 接口所规定的方法的类都可以具有这个接口的类型,而一个类可以实现任意多个Java接口,从而这个类就有了多种类型。

3、从第2点不难看出,Java接口是定义混合类型的理想工具,混合类表明一个类不仅仅具有某个主类型的行为,而且具有其他的次要行为。

4、结合 1、2 点中抽象类和Java 接口的各自优势,具精典的设计模式就出来了:声明类型的工作仍然由Java接口承担,但是同时给出一个Java抽象类,且实现了这个接口,而其他同属于这个抽象类型的具体类可以选择实现这个Java接口,也可以选择继承这个抽象类,也就是说在层次结构中,Java接口在最上面,然后紧跟着抽象类,哈,这下两个的最大优点都能发挥到极至了。这个模式就是“缺省适配模式”。 在 Java 语言 API 中用了这种模式,而且全都遵循一定的命名规范:Abstract +接口名。

Java 接口和 Java 抽象类的存在就是为了用于具体类的实现和继承的,如果你准备写一个具体类去继承另一个具体类的话,那你的设计就有很大问题了。Java 抽象类就是为了继承而存在的,它的抽象方法就是为了强制子类必须去实现的。

使用 Java 接口和抽象 Java 类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。而不要用具体 Java 类进行变量的类型声明、参数是类型声明、方法的返还类型说明,以及数据类型的转换等。

我想,如果你编的代码里面连一个接口和抽象类都没有的话,也许我可以说你根本没有用到任何设计模式,任何一个设计模式都是和抽象分不开的,而抽象与Java接口和抽象Java类又是分不开的。

接口的作用,一言以蔽之,就是标志类的类别。把不同类型的类归于不同的接口,可以更好的管理他们。把一组看如不相关的类归为一个接口去调用.可以用一个接口型的变量来引用一个对象,这是接口我认为最大的作用。

33. 什么是自定义异常?

今天我们要来理解的是什么是自定义异常,为什么要使用自定义异常,使用自定义异常有哪些好处,有哪些不好的地方?

要使用自定义异常就跟你和女朋友相处一样的,首先你得知道你为什么要跟你女朋友在一起,你女朋友有哪些好处,有哪些不好的地方,再来和你女朋友谈婚论嫁过一辈子,我们就先来说说这些问题,最后再来看怎么使用自定义异常,自定义异常的实现和使用非常简单,关键还是理解why的内容。

34. 为什么要使用自定义异常,有什么好处?

1.我们在工作的时候,项目是分模块或者分功能开发的 ,基本不会你一个人开发一整个项目,使用自定义异常类就统一了对外异常展示的方式。

2.有时候我们遇到某些校验或者问题时,需要直接结束掉当前的请求,这时便可以通过抛出自定义异常来结束,如果你项目中使用了SpringMVC比较新的版本的话有控制器增强,可以通过@ControllerAdvice注解写一个控制器增强类来拦截自定义的异常并响应给前端相应的信息(关于springMVC控制器增强的知识有空再和大家分享)。

3.自定义异常可以在我们项目中某些特殊的业务逻辑时抛出异常,比如"中性".equals(sex),性别等于中性时我们要抛出异常,而Java是不会有这种异常的。系统中有些错误是符合Java语法的,但不符合我们项目的业务逻辑。

4.使用自定义异常继承相关的异常来抛出处理后的异常信息可以隐藏底层的异常,这样更安全,异常信息也更加的直观。自定义异常可以抛出我们自己想要抛出的信息,可以通过抛出的信息区分异常发生的位置,根据异常名我们就可以知道哪里有异常,根据异常提示信息进行程序修改。比如空指针异常NullPointException,我们可以抛出信息为“xxx为空”定位异常位置,而不用输出堆栈信息。

35. 怎么使用自定义异常?

在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。

  • 所有异常都必须是 Throwable 的子类。
  • 如果希望写一个检查性异常类,则需要继承 Exception 类。
  • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

可以像下面这样定义自己的异常类:

class MyException extends Exception{ }

使用

throw new MyException("自定义异常");

36. 什么是工作流?

(举个栗子)现在大多数公司的请假流程是这样的:员工打电话(或网聊)向上级提出请假申请——上级口头同意——上级将请假记录下来——月底将请假记录上交公司——公司将请假录入电脑。采用工作流技术的公司的请假流程是这样的:员工使用账户登录系统——点击请假——上级登录系统点击允许。就这样,一个请假流程就结束了。有人会问,那上级不用向公司提交请假记录?公司不用将记录录入电脑?答案是,用的。但是这一切的工作都会在上级
点击允许后自动运行!这就是工作流技术。

Georgakopoulos 给出的工作流定义是: 工作流是将一组任务组织起来以完成某个经营过程:定义了任务的触发顺序和触发条件,每个任务可以由一个或多个软件系统完成,也可以由一个或一组人完成,还可以由一个或多个人与软件系统协作完。

37. 工作流技术的优点

从上面的例子,很容易看出,工作流系统实现了工作流程的自动化,提高了企业运营效率、改善企业资源利用、提高企业运作的灵活性和适应性、提高量化考核业务处理的效率、减少浪费(时间就是金钱)。而手工处理工作流程,一方面无法对整个流程状况进行有效跟踪、了解,另一方面难免会出现人为的失误和时间上的延时导致效率低下,特别是无法进行量化统计,不利于查询、报表及绩效评估。

38. 工作流生命周期

除了我们自行启动(start)或者结束(finish)一个 Activity,我们并不能直接控制一个 Activity 的生命状态,我们只能通过实现 Activity 生命状态的表现——即回调方法来达到管理 Activity 生命周期的变化。

39. 反射机制一般应用在什么场景?

反射机制的应用场景:
1)逆向代码 ,例如反编译
3)与注解相结合的框架 例如Retrofit
4)单纯的反射机制应用框架 例如EventBus 2.x
5)动态生成类框架 例如Gson

40. ThreadLocal 的原理和应用场景

每一个ThreadLocal能够放一个线程级别的变量,可是它本身能够被多个线程共享使用,并且又能够达到线程安全的目的,且绝对线程安全。

ThreadLocal的应用场景:
最常见的ThreadLocal使用场景为 用来解决数据库连接、Session管理等

参考文档:http://blog.csdn.net/sonny543/article/details/51336457

41. 简述 TCP 的三次握手

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

1).第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态, 等待服务器确认; SYN:同步序列编号(Synchronize Sequence Numbers)

2).第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

3)第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1), 此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

参考文档:http://blog.csdn.net/q1512451239/article/details/53122512

42. Java 出现 OutOfMemoryError(OOM)的原因有那些?出现 OOM 错误后,怎么解决?

触发 java.lang.OutOfMemoryError:最常见的原因就是应用程序需要的堆空间是大的,但是 JVM 提供的却小。这个的解决方法就是提供大的堆空间即可。除此之外还有复杂的原因:

内存泄露
特定的编程错误会导致你的应用程序不停的消耗更多的内存,每次使用有内存泄漏风险的功能就会留下一些不能被回收的对象到堆空间中,随着时间的推移,泄漏的对象会消耗所有的堆空间,最终触发java.lang.OutOfMemoryError: Java heap space错误。
解决方案
第一个解决方案是显而易见的,你应该确保有足够的堆空间来正常运行你的应用程序,在JVM的启动配置中增加如下配置:

-Xmx1024m

流量/数据量峰值
应用程序在设计之初均有用户量和数据量的限制,某一时刻,当用户数量或数据量突然达到一个峰值,并且这个峰值已经超过了设计之初预期的阈值,那么以前正常的功能将会停止,并触发java.lang.OutOfMemoryError: Java heap space异常
解决方案
如果你的应用程序确实内存不足,增加堆内存会解决GC overhead limit问题,就如下面这样,给你的应用程序1G的堆内存:

java -Xmx1024m com.yourcompany.YourClass 

参考播客:http://www.jianshu.com/p/2fdee831ed03

43. 写出一个冒泡排序

从大到小:

public void BigAndSmall(){    
    int arr[]={-5,29,7,10,5,16};    
    for(int i=1;i<arr.length;i++){     
        for(int j=0;j<arr.length-i;j++){      
            if(arr[j]<arr[j+1]){       
                int temp;       
                temp=arr[j];       
                arr[j]=arr[j+1];       
                arr[j+1]=temp;      
            }     
        }    
    }    
    for(int i =0;i<arr.length;i++){     
        System.out.print(" "+arr[i]+" ");    
    } 
}

44. 写出一个单例的实现(懒加载方式)

public class LazySingleton { 
    private LazySingleton(){  
    }  
    private static class SingletonHolder{   
        private static LazySingleton instance = new LazySingleton();  
    }  
    public static LazySingleton getInstance(){      
        return SingletonHolder.instance;  
    }
}

**45. System.out.println(3/2); System.out.println(3.0/2); System.out.println(3.0/2.0); 分别会打印什么结果? **

答案:1, 1.5,1.5

**46. Spring 中什么时候引起 NotWritablePropertyException 和 Could not open calss path resource[ApplicationContext.xml] **

出现NotWritablePropertyException异常的原因一般是在ApplicationContext.xml中property name的错误等相关错误。

47. 什么叫对象?什么叫类?什么面向对象(OOP)?

类的概念:类是具有相同属性和服务的一组对象的集合。它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分。在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属性说明和服务说明两个主要部分。

对象的概念:对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。从更抽象 的角度来说,对象是问题域或实现域中某些事物的一个抽象,它反映该事物在系统中需要保存的信息和发挥的作用;它是一组属性和有权对这些属性进行操作的一组 服务的封装体。客观世界是由对象和对象之间的联系组成的。

类与对象的关系就如模具和铸件的关系,类的实例化结果就是对象,而对一类对象的抽象就是类.类描述了一组有相同特性(属性)和相同行为(方法)的对象。上面大概就是它们的定义吧, 也许你是刚接触面象对象的朋友, 不要被概念的东西搞晕了, 给你举个列子吧,如果你去中关村想买几台组装的PC机,到了那里你第一步要干什么, 是不是装机的工程师和你坐在一起,按你提供的信息和你一起完成一个装机的配置单呀, 这个配置单就可以想像成是类,它就是一张纸,但是它上面记录了你要买的 PC机的信息,如果用这个配置单买10台机器,那么这 10台机子,都是按这个配置单 组成的,所以说这 10 台机子是一个类型的,也可以说是一类的。那么什么是对象呢,类的实例化结果就是对象, 用这个配置单配置出来(实例化出来)的机子就是对象, 是我们可以操作的实体, 10 台机子, 10 个对象。 每台机子都是独立的,只能说明他们是同一类的,对其中一个机做任何动作都不会影响其它 9 台机器,但是我对类修改, 也就是在这个配置单上加一个或少一个配件, 那么装出来的 9 个机子都改变了, 这是类和对象的关系(类的实例化结果就是对象) 。

48. Svn解决冲突

解决的办法是先使用svn update命令获取SVN库上最新修改的文件,这个命令并不会直接覆盖掉您本地所做的修改,SVN客户端会先尝试将SVN库上该文件的修改合并到你的本地文件中。

如果SVN客户端成功的进行了合并,您可以再次执行SVNcommit命令进行本地文件的提交即可。

如果SVN客户端无法进行自动合并(可能因为文件是一些二进制文件,或者两人修改的地方是同一个,或者修改的地方太多等原因),则svn客户端会提示“one or more files are in confict state这时候就需要去协调

49. Maven常用命令

Mvn clean 清除
Mvn pachage 打包
Mvn install 在本地Repository中安装jar
Mvn test 测试
Mvn deploy 发布命令

50. WEB部署项目

  1. 下载tomca服务器
  2. 启动并部署tomcat服务器
  3. 将编写并编译好的web项目,如果是eclipse可以将项目打包成war包放入,放入到webapps
  4. 启动tomcat,startup.bat,启动 tomcat 服务器

51. JVM调优

Jvm的重点是垃圾回收和内存管理。垃圾回收的时候会导致整个虚拟机暂停服务。因此,
应该尽可能缩短垃圾h回收的处理时间。

  1. 开启server模式(虽然启动慢,但是效率高)
  2. 针对JVM设置,可以通过xmx,xms限定其最小,最大值,为了防止垃圾收集器在最小和最大之间产生额外时间,我们通常把最大和最小值设置为相同的值。
  3. 年轻带和年老带根据默认比例1:2分配堆内存,原则上减少GC的使用频率和Gc的使用次数。
  4. 在配置较好的机器上,为年老代选择并行手机算法默认Serial
  5. 线程堆栈的设置,每个线程都会默认开启1M的堆栈,用于存放栈帧,局部变量,调用参数等,可对于大多数而言来说,这个值太大了,一般256K足够,理论上,在内存不变的情况下,减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统

52. SVN提交

首先呢要和线上的数据进行对比,解决要冲突之后,把数据更新到本地,再把本地的数据传上去,具体的操作呢就是点右键team,与资源进行同步,查看哪个文件有冲突,左边是本地数据,右边是服务器数据更新之后会标红,之后点击拷贝把服务器的数据拷贝到本地。点击标记为合并,更新提交。

53. 介绍一下你的项目是如何开发的

先了解业务需求,然后根据自己所负责的模块进行技术的整合,设计流程图,并搭建合适的框架,(先做什么,后做什么)然后将技术或者业务方面的陷阱罗列出来,并用文本写出来,之后呢由相关人员进行检测,然后就是代码的实现

54. 分布式的锁

基于数据库实现分布式锁
基于数据库表
要实现分布式锁,最简单的方式可能就是直接创建一张锁表,然后通过操作该表中的数据来实现了。
当我们要锁住某个方法或资源时,我们就在该表中增加一条记录,想要释放锁的时候就删除这条记录。
创建这样一张数据库表:

CREATE TABLE `methodLock` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `method_name` varchar(64) NOT NULL DEFAULT '' COMMENT '锁定的方法名',
  `desc` varchar(1024) NOT NULL DEFAULT '备注信息',
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '保存数据时间,自动生成',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uidx_method_name` (`method_name `) USING BTREE) ENGINE=InnoDB DEFAULT 
 CHARSET=utf8 COMMENT='锁定中的方法';

当我们想要锁住某个方法时,执行以下SQL:

insert into methodLock(method_name,desc) values (‘method_name’,desc)

因为我们对method_name做了唯一性约束,这里如果有多个请求同时提交到数据库的话,数据库会保证只有一个操作可以成功,那么我们就可以认为操作成功的那个线程获得了该方法的锁,可以执行方法体内容。

55. 高并发解决方法

  • HTML静态化
  • 图片服务器分离
  • 数据库集群、库表散列
  • 缓存
  • 镜像
  • 负载均衡

欢迎关注作者的公众号《Java编程生活》,每日记载Java程序猿工作中遇到的问题
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值