关于JavaWeb的笔试面试题(一)

1.什么是ORM?自己概括ORM干嘛的就行

对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换  。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。---百度百科

对象-关系映射(OBJECT/RELATIONALMAPPING,简称ORM),是随着面向对象的软件开发方法发展而产生的。用来把对象模型表示的对象映射到基于S Q L 的关系模型数据库结构中去。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的 SQ L 语句打交道,只需简单的操作实体对象的属性和方法。O R M 技术是在对象和关系之间提供了一条桥梁,前台的对象型数据和数据库中的关系型的数据通过这个桥梁来相互转化。---百度百科

ORM的方法论基于三个核心原则:
· 简单:以最基本的形式建模数据。
· 传达性:数据库结构被任何人都能理解的语言文档化。
· 精确性:基于数据模型创建正确标准化了的结构。

2.持久层设计要考虑的问题有哪些?浅了解

架构的目标是什么

  正如同软件本身有其要达到的目标一样,架构设计要达到的目标是什么呢?一般而言,软件架构设计要达到如下的目标:

·可靠性(Reliable)。软件系统对于用户的商业经营和管理来说极为重要,因此软件系统必须非常可靠。

·安全行(Secure)。软件系统所承担的交易的商业价值极高,系统的安全性非常重要。

·可扩展性(Scalable)。软件必须能够在用户的使用率、用户的数目增加很快的情况下,保持合理的性能。只有这样,才能适应用户的市场扩展得可能性。

·可定制化(Customizable)。同样的一套软件,可以根据客户群的不同和市场需求的变化进行调整。

·可扩展性(Extensible)。在新技术出现的时候,一个软件系统应当允许导入新技术,从而对现有系统进行功能和性能的扩展

·可维护性(Maintainable)。软件系统的维护包括两方面,一是排除现有的错误,二是将新的软件需求反映到现有系统中去。一个易于维护的系统可以有效地降低技术支持的花费

·客户体验(Customer Experience)。软件系统必须易于使用。

·市场时机(Time to Market)。软件用户要面临同业竞争,软件提供商也要面临同业竞争。以最快的速度争夺市场先机非常重要。

3.Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗(两个线程能够共享同一个Session吗)?重要

SessionFactory负责创建SessionSessionFactory是线程安全的,多个并发线程可以同时访问一个 SessionFactory 并从中获取Session实例。而Session并非线程安全(线程间不能共享session),也就是说,如果多个线程同时使用一个Session实例进行数据存取, 则将会导致 Session 数据存取逻辑混乱.因此创建的Session实例必须总与当前的线程相关。为了避免创建太多的session,可以使用ThreadLocalsession和当前线程绑定在一起,这样可以让同一个线程获得的总是同一个session(ThreadLocal Java中一种较为特殊的线程绑定机制,通过ThreadLocal存取的数据, 总是与当前线程相关, 也就是说,JVM 为每个运行的线程,绑定了私有的本地实例存取空间,从而为多线程环境常出现的并发访问问题提供了一种隔离机制,ThreadLocal并不是线程本地化的实现,而是线程局部变量。也就是说每个使用该变量的线程都必须为该变量提供一个副本,每个线程改变该变量的值仅仅是改变该副本的值,而不会影响其他线程的该变量的值,ThreadLocal是隔离多个线程的数据共享,不存在多个线程之间共享资源,因此不再需要对线程同步。)(括号内容了解就行)

4.Hibernate中Session的load和get方法的区别是什么?重要

1:在立即加载对象(当hibernate在从数据库中取得数据组装好一个对象后会立即再从数据库取得数据此对象所关联的对象)时,如果对象存在,load()和get()方法没有区别,都可以取得已初始化的对象;但如果当对象不存在且是立即加载时,使用get()方法则返回null,而使用load()则抛出一个异常。因此使用load()方法时,要确认查询的主键ID一定是存在的,从这一点讲它没有get方便!
2:在延迟加载对象(Hibernate从数据库中取得数据组装好一个对象后,不会立即再从数据库取得数据组装此对象所关联的对象,而是等到需要时,都会从数据库取得数据组装此对象关联的对象)时,get()方法仍然使用立即加载的方式发送SQL语句,并得到已初始化的对象,而load()方法则根本不发送SQL语句,它返回一个代理对象,直到这个对象被访问时才被
初始化。

load()方法的执行顺序如下:
a):首先通过idsession缓存中查找对象,如果存在此id的对象,直接将其返回
b):在二级缓存中查找,找到后将 其返回。
c):如果在session缓存和二级缓存中都找不到此对象,则从数据库中加载有此ID的对象
因此load()方法并不总是导致SQL语句,只有缓存中无此数据时,才向数据库发送SQL

主要有以下三项区别:

如果没有找到符合条件的记录,get方法返回nullload方法抛出异常。

② get方法直接返回实体类对象,load方法返回实体类对象的代理。

Hibernate 3之前,get方法只在一级缓存中进行数据查找,如果没有找到对应的数据则越过二级缓存,直接发出SQL语句完成数据读取;load方法则可以从二级缓存中获取数据;从Hibernate 3开始,get方法不再是对二级缓存只写不读,它也是可以访问二级缓存的。

说明:对于load()方法Hibernate认为该数据在数据库中一定存在可以放心的使用代理来实现延迟加载,如果没有数据就抛出异常,而通过get()方法获取的数据可以不存在。

5.阐述Session加载实体对象的过程。(了解

Session加载实体对象的步骤是: 
① Session在调用数据库查询功能之前,首先会在一级缓存中通过实体类型和主键进行查找,如果一级缓存查找命中且数据状态合法,则直接返回; 
如果一级缓存没有命中,接下来Session会在当前NonExists记录(相当于一个查询黑名单,如果出现重复的无效查询可以迅速做出判断,从而提升性能)中进行查找,如果NonExists中存在同样的查询条件,则返回null 
如果一级缓存查询失败则查询二级缓存,如果二级缓存命中则直接返回; 
如果之前的查询都未命中,则发出SQL语句,如果查询未发现对应记录则将此次查询添加到SessionNonExists中加以记录,并返回null 
根据映射配置和SQL语句得到ResultSet,并创建对应的实体对象; 
将对象纳入Session(一级缓存)的管理; 
如果有对应的拦截器,则执行拦截器的onLoad方法; 
如果开启并设置了要使用二级缓存,则将数据对象纳入二级缓存; 
返回数据对象。

6.Hibernate如何实现分页查询?

通过Hibernate实现分页查询,开发人员只需要提供HQL语句(调用SessioncreateQuery()方法)或查询条件(调用SessioncreateCriteria()方法)、设置查询起始行数(调用QueryCriteria接口的setFirstResult()方法)和最大查询行数(调用QueryCriteria接口的setMaxResults()方法),并调用QueryCriteria接口的list()方法,Hibernate会自动生成分页查询的SQL语句。

7.Tomcat的优化经验现在看可能看不懂,可以先了解个大概,知道有这么回事儿就行,到快毕业的时候再细看,面试中有的会问到

Tomcat作为Web服务器,它的处理性能直接关系到用户体验,下面是几种常见的优化措施:

一、调web.xml的监视,把jsp提前编辑成Servlet。有富余物理内存的情况,加大tomcat使用的jvm的内存
二、服务器资源
  服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。
(1) 对于高并发情况下会有大量的运算,那么CPU的速度会直接影响到处理速度。
(2) 内存在大量数据处理的情况下,将会有较大的内存容量需求,可以用-Xmx -Xms -XX:MaxPermSize等参数对内存不同功能块进行划分。我们之前就遇到过内存分配不足,导致虚拟机一直处于full GC,从而导致处理能力严重下降。
(3) 硬盘主要问题就是读写性能,当大量文件进行读写时,磁盘极容易成为性能瓶颈。最好的办法还是利用下面提到的缓存。
三、利用缓存和压缩
  对于静态页面最好是能够缓存起来,这样就不必每次从磁盘上读。这里我们采用了Nginx作为缓存服务器,将图片、cssjs文件都进行了缓存,有效的减少了后端tomcat的访问。
  另外,为了能加快网络传输速度,开启gzip压缩也是必不可少的。但考虑到tomcat已经需要处理很多东西了,所以把这个压缩的工作就交给前端的Nginx来完成。
  除了文本可以用gzip压缩,其实很多图片也可以用图像处理工具预先进行压缩,找到一个平衡点可以让画质损失很小而文件可以减小很多。一个图片从300kb压缩到几十kb,几乎看不出来区别。
 四、采用集群
  单个服务器性能总是有限的,最好的办法自然是实现横向扩展,那么组建tomcat集群是有效提升性能的手段。我们还是采用了Nginx来作为请求分流的服务器,后端多个tomcat共享session来协同工作。可以参考之前写的《利用nginx+tomcat+memcached组建web服务器负载均衡》。
五、 优化tomcat参数
  这里以tomcat7的参数配置为例,需要修改conf/server.xml文件,主要是优化连接配置,关闭客户端dns查询。

<Connector port="8080"   
           protocol="org.apache.coyote.http11.Http11NioProtocol"  
           connectionTimeout="20000"  
           redirectPort="8443"   
           maxThreads="500"   
           minSpareThreads="20"  
           acceptCount="100" 
           disableUploadTimeout="true" 
           enableLookups="false"   
           URIEncoding="UTF-8" /> 

六、改用APR

    tomcat默认采用的BIO模型,在几百并发下性能会有很严重的下降。tomcat自带还有NIO的模型,另外也可以调用APR的库来实现操作系统级别控制。

    NIO模型是内置的,调用很方便,只需要将上面配置文件中protocol修改成org.apache.coyote.http11.Http11NioProtocol,重启即可生效。默认的是HTTP/1.1

APR则需要安装第三方库,在高并发下会让性能有明显提升。具体安装办法可以参考http://www.cnblogs.com/huangjingzhou/articles/2097241.html。安装完成后重启即可生效。如使用默认protocal就是apr,但最好把将protocol修改成

org.apache.coyote.http11.Http11AprProtocol,会更加明确

七、优化网络

    Joel也明确提出了优化网卡驱动可以有效提升性能,这个对于集群环境工作的时候尤为重要。由于我们采用了linux服务器,所以优化内核参数也是一个非常重要的工作。给一个参考的优化参数:

1.  修改/etc/sysctl.cnf文件

2.  保存退出,执行sysctl -p生效

八、让测试说话

    优化系统最忌讳的就是只调优不测试,有时不适当的优化反而会让性能更低。以上所有的优化方法都要在本地进行性能测试过后再不断调整参数,这样最终才能达到最佳的优化效果。

补充BioNioApr模式的测试结果:

    对于这几种模式,我用ab命令模拟1000并发测试10000词,测试结果比较意外,为了确认结果,我每种方式反复测试了10多次,并且在两个服务器上都测试了一遍。结果发现BioNio性能差别非常微弱,难怪默认居然还是Bio。但是采用apr,连接建立的速度会有50%100%的提升。直接调用操作系统层果然神速啊,这里强烈推荐apr方式!(这个看不懂没关系,知道在炫技就行)

猜你喜欢

转载自blog.csdn.net/weixin_41768263/article/details/80377914