JAVA经典面试题目答案_第1页
JAVA经典面试题目答案_第2页
JAVA经典面试题目答案_第3页
JAVA经典面试题目答案_第4页
JAVA经典面试题目答案_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1forword和redirect的区别以及各自的应用场景直接转发方式(Forward),客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于一个每个信息资源是共享的。场景:Web应用程序大多会有一个控制器。由控制器来控制请求应该转发给那个信息资源。然后由这些信息资源处理请求,处理完以后还可能转发给另外的信息资源来返回给用户,这个过程就是经典的MVC模式。间接转发方式(Redirect)实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。场景:一般用于避免用户的非正常访问。例如:用户在没有登录的情况下访问后台资源,Servlet可以将该HTTP请求重定向到登录页面,让用户登录以后再访问。区别Forward和Redirect代表了两种请求转发方式:直接转发和间接转发。对应到代码里,分别是RequestDispatcher类的forward()方法和HttpServletRequest类的sendRedirect()方法。对于间接方式,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。它本质上是两次HTTP请求,对应两个request对象。对于直接方式,客户端浏览器只发出一次请求,Servlet把请求转发给Servlet、HTML、JSP或其它信息资源,由第2个信息资源响应该请求,两个信息资源共享同一个request对象。2Spring套餐描述Spring容器初始化过程Ioc容器的初始化是由refresh()方法来启动的,这个方法标志着Ioc容器的正式启动。具体来说这个启动过程包括三个基本过程:1>.BeanDifinition的Resource定位指的是BeanDifinition的资源定位,它由ResourceLoader通过统一的Resource接口来完成,这些 BeanDifinition的存在形式,比如,在文件系统中的Bean定义信息可以使用FileSystemResource来进行 抽象,在类路径中的Bean定义信息可以使用ClassPathResource。2>.BeanDifinition的载入与解析把用户定义好的Bean表示成Ioc容器内部的数据结构,而这个容器内部的数据结构就是BeanDifinition。具体来说,BeanDifinition实际上就是POJO对象在IOC容器中的抽象,通过这个BeanDifinition定义的数据结构,使IOC容器能够方便的对POJO对象也就是Bean进行管理。3>.BeanDifinition在Ioc容器中的注册这个操作是通过调用BeanDifinitionRegistry借口来实现的。这个注册过程把载入过程中解析得到的BeanDifinition向Ioc容器进行注册。在阅读源码中可知,在IOC容器内部将BeanDifinition注入到一个HashMap中去,Ioc容器就是通过这个HashMap来持有这些BeanDifinition数据的。2、为什么要进行事务管理,Spring是如何进行事务管理支持的Spring事务是

Spring

AOP

的一种实现,本质是基于动态代理技术对所需要管理的bean进行加载,并在方法调用前后加入合适的事务管理代码实现事务的提交与产生异常时回滚。spring的事务声明有两种方式,编程式和声明式。spring主要是通过“声明式事务”的方式对事务进行管理,即在配置文件中进行声明,通过AOP将事务切面切入程序,最大的好处是大大减少了代码量。Spring如何配置数据库驱动<bean

id="dataSource"class="mons.dbcp.BasicDataSource"><property

name="driverClassName"value="com.mysql.jdbc.Driver"></property><property

name="url"value="jdbc:mysql://localhost:3306/test"></property><property

name="username"

value="root"></property><property

name="password"

value="admin"></property></bean>解释一下DI依赖注入和IOC控制反转,Spring中是如何做的

IOC(控制反转)是spring的核心,由Spring管理创建响应的对象,即由IOC容器帮对象管理响应的依赖关系,并在运行时将对象注入,而不是通过传统的new来主动创建对象。而DI则是实现IOC注入关联对象的方式,有三种:set方法注入、构造函数注入和参数 (常量)注入。控制反转和依赖注入是同一个东西在不同的角度进行分析,在实际项目开发中我们需要把bean都放在spring中管理,告诉spring不同bean之间的依赖关系,而具体的创建注入都是由spring容器帮我们实现的,即通过控制反转和依赖注入,本质实现都是基于反射机制来实现的。Spring中的BeanFactory与ApplicationContext的作用有那些BeanFactory提供了配制框架及基本功能,负责对象实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。而ApplicationContext则增加了更多支持企业核心内容的功 能。比如更易与SpringAOP集成、消息资源处理(国际化处理)、事件传递及各种不同应用层的context实现(如针对web应用的WebApplicationContext)。Spring中的核心类有那些,各有什么作用BeanFactory:产生一个新的实例,可以实现单例模式BeanWrapper:提供统一的get及set方法ApplicationContext:提供框架的实现,包括BeanFactory的所有功能什么是aop,aop的作用是什么面向切面编程,或AOP允许程序员模块化横向业务逻辑,将系统中非核心的业务提取出来,进行单独处理,解决系统代码耦合度过高的问题。使代码重用度高、易于维护。例如权限认证、日志管理和事务管理。springbean的创建方式和生命周期三种创建方式:①构造器注入创建②工厂方法(静态工厂)③工厂类(实例工厂)1)Bean实例化:Bean的默认构造函数。2)Bean的初始化:Init()方法中可以进行初始化。3)Bean的使用:getBean()方法可以获取当前的Bean,从而做相对应的业务操作。4)Bean的销毁:destroy()方法执行bean的销毁。9、spring与springMVC的区别Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。springmvc类似于struts的一个MVC开框架,其实都是属于spring,springmvc需要有spring的架包作为支撑才能跑起来。3HashMap(或者Hashtable/ArrayList。。。)的数据结构(实现方式)HashMap:key:value底层使用数组(table)+链表(entry)结构,通过key进行二次hash计算出的hashCode%table.length确定对应的数组下标的位置存放value。HashTable:key:valueHashtable

继承于Dictionary,实现了Map、Cloneable、Java.io.Serializable接口,Hashtable的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。此外,Hashtable中的映射不是有序的。底层使用数组(table)+链表(entry)结构,hash计算方法是直接使用key的hashcode对table数组的长度直接进行取模。ArrayList:线性链表(线程不安全),最核心的两个成员变量是存储数据的数组和数组大小。a.ArrayList是通过将底层Object数组复制的方式(System.arraycopy方法)来处理数组的增长;

b.当ArrayList的容量不足时,其扩充容量的方式:先将容量扩充至当前容量的1.5倍,若还不够,则将容量扩充至当前需要的数量。4GET与POST的区别,分别用在什么场景合适?GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTPpost机制,将表单内各个字段与其内容放置在HTMLHEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。对于get方式,服务器端用doGet获取变量的值,对于post方式,服务器端用doPost获取提交的数据。get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。get安全性非常低,post安全性较高。但是执行效率却比Post方法好。5什么是单例模式,有哪些实现方式,写出其中两种Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。第一种(懒汉,线程不安全):略(参考第二种)第二种(懒汉,线程安全):

public

class

Singleton

{

private

static

Singleton

instance;

private

Singleton

(){}

public

static

synchronized

Singleton

getInstance()

{

if

(instance

==

null)

{

instance

=

new

Singleton();

}

return

instance;

}

}

这种写法能够在多线程中很好的工作,而且看起来它也具备很好的lazyloading,但是,遗憾的是,效率很低,99%情况下不需要同步。第三种(饿汉):

public

class

Singleton

{

private

static

Singleton

instance

=

new

Singleton();

private

Singleton

(){}

public

static

Singleton

getInstance()

{

return

instance;

}

}

第四种(静态内部类):

public

class

Singleton

{

private

static

class

SingletonHolder

{

private

static

final

Singleton

INSTANCE

=

new

Singleton();

}

private

Singleton

(){}

public

static

final

Singleton

getInstance()

{

return

SingletonHolder.INSTANCE;

}

}

这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,它跟第三种方式不同的是(很细微的差别):第三种是只要Singleton类被装载了,那么instance就会被实例化(没有达到lazyloading效果),而这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。想象一下,如果实例化instance很消耗资源,我想让他延迟加载,另外一方面,我不希望在Singleton类加载时就实例化,因为我不能确保Singleton类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化instance显然是不合适的。这个时候,这种方式相比第三方式就显得很合理。第五种(枚举):

public

enum

Singleton

{

INSTANCE;

public

void

instance()

{

}

}

这种方式是EffectiveJava作者JoshBloch提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum特性,用这种方式写不免让人感觉生疏,在实际工作中,我也很少看见有人这么写过。第六种(双重校验锁):

public

class

Singleton

{

private

volatile

static

Singleton

singleton;

private

Singleton

(){}

public

static

Singleton

getSingleton()

{

if

(singleton

==

null)

{

synchronized

(Singleton.class)

{

if

(singleton

==

null)

{

singleton

=

new

Singleton();

}

}

}

return

singleton;

}

}

这个是第二种方式的升级版,俗称双重检查锁定,但仅在JDK1.5之后有效。6常见的设计模式有哪些,并写出简单的示例代码单例模式(略):工厂模式(普通、多方法和静态工厂方法、抽象工厂):该模式主要功能是统一提供实例对象的引用建造者模式:一个对象的组成可能有很多其他的对象一起组成的,比如说,一个对象的实现非常复杂,有很多的属性,而这些属性又是其他对象的引用,可能这些对象的引用又包括很多的对象引用。封装这些复杂性,就可以使用建造模式。策略模式:这个模式是将行为的抽象,即当有几个类有相似的方法,将其中通用的部分都提取出来,从而使扩展更容易。门面模式:这个模式个人感觉像是Service层的一个翻版。比如Dao我们定义了很多持久化方法,我们通过Service层将Dao的原子方法组成业务逻辑,再通过方法向上层提供服务。门面模式道理其实是一样的。代理模式:其实每个模式名称就表明了该模式的作用,代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做,此处的代理就是这个意思。7原生JS的继承是怎么实现的,都有哪几种?①对象冒充functionParent(username){...}functionChild(username,password){//第一步:this.method是作为一个临时的属性,并且指向Parent所指向的对象,this.method=Parent;//第二步:执行this.method方法,即执行Parent所指向的对象函数this.method(username);//最关键的一行//第三步:销毁this.method属性,即此时Child就已经拥有了Parent的所有属性和方法deletethis.method;...}②call方法call方法是Function类中的方法call方法的第一个参数的值赋值给类(即方法)中出现的thiscall方法的第二个参数开始依次赋值给类(即方法)所接受的参数functionParent(username){...}functionChild(username,password){Parent.call(this,username);...}③apply()方法方式

apply方法接受2个参数,

A、第一个参数与call方法的第一个参数一样,即赋值给类(即方法)中出现的this

B、第二个参数为数组类型,这个数组中的每个元素依次赋值给类(即方法)所接受的参数functionParent(username){...}functionChild(username,password){Parent.apply(this,newArray(username));...}④原型链方式,即子类通过prototype将所有在父类中通过prototype追加的属性和方法都追加到Child,从而实现了继承。functionPerson(){}Ptotype.hello="hello";Ptotype.sayHello=function(){alert(this.hello);}functionChild(){}

Ctotype=newPerson();//这行的作用是:将Parent中将所有通过prototype追加的属性和方法都追加到Child,从而实现了继承

Ctotype.world="world";

Ctotype.sayWorld=function(){alert(this.world);}⑤混合方式(略):混合了call方式、原型链方式8数据库优化方式有哪些?(下面是可能会连贯性问到的问题)MySQL和Oracle的区别,在什么情况下更适合?MySQL开源免费,适合中小型应用系统,ORACLE庞大健全用于大型应用系统和安全性要求较高的领域。使用细节也有些区别,例如:①mysql中组函数在select语句中可以随意使用,但在oracle中如果查询语句中有组函数,那其他列名必须是组函数处理过的,或者是groupby子句中的列否则报错selectname,count(money)fromuser;这个放在mysql中没有问题在oracle中就有问题了。②自动增长列的实现MYSQL有自动增长的数据类型,插入记录时不用操作此字段,会自动获得数据值。ORACLE没有自动增长的数据类型,需要建立一个自动增长的序列号,插入记录时要把序列号的下一个值赋于此字段。③单引号处理MYSQL里可以用双引号包起字符串,ORACLE里只可以用单引号包起字符串。④分页处理MYSQL使用limit即可,ORACLE必须使用三层子查询结合ROWNUM实现⑤日期字段MYSQL日期字段分DATE和TIME两种,ORACLE日期字段只有DATE,包含年月日时分秒信息,用当前数据库的系统时间为SYSDATE,精确到秒。⑥空字符串MYSQL的非空字段也有空的内容,ORACLE里定义了非空字段就不容许有空的内容。按MYSQL的NOTNULL来定义ORACLE表结构,导数据的时候会产生错误。因此导数据时要对空字符进行判断,如果为NULL或空字符,需要把它改成一个空格的字符串。MySQL的性能方面你了解多少?比如一个正常的读写操作你觉得多少时间算是正常?服务器12核24线程,64G内存,SATA盘的情况下:读1.5~3W/s,写4000~10000/s,TPS800~1500/s。,平均响应10ms以内正常。如果一张表的查询速度慢了.你会从哪些方面去优化?①慢查询定位及改进:Show命令、慢查询日志、explain分析查询、profiling分析②索引优化合理建立索引、优化索引相关的查询SQL1>.

当结果集只有一行数据时使用LIMIT12>.

避免SELECT*,始终指定你需要的列3>.

使用连接(JOIN)来代替子查询(Sub-Queries)4>.

使用合理的字段属性长度5>.

尽可能的使用NOTNULL6>.

固定长度的表会更快7>.

拆分大的DELETE

或INSERT

语句8>.

查询的列越小越快有些where条件会导致索引无效:Ø

where子句的查询条件里有!=,MySQL将无法使用索引。Ø

where子句使用了Mysql函数的时候,索引将无效Ø

使用LIKE进行搜索匹配的时候,模糊匹配不能放在前面,否则失效。如’%xxxx’③配置优化MySQL服务器全局参数优化④分表(横、纵)减少单表的数据量及将常用列和不常用列、大列和小列分到不同的表。你做的三个项目里应该都会用到权限设计,你对表是怎么设计的?按照RBAC权限体系设计通用的权限管理表你们对表的设计怎么优化?你觉得一张表装多少行数据才会影响性能?数据类型:数字类型尽量不选择double、float,尽量使用decimal、int和long类型。字符类型除非非得是TEXT,而要尽量使用CHAR和VARCHAR。日期时间类型尽量使用TIMESTAMP,对于精确到某天的日期类型尽量选择DATE。尽量不使用BLOB/CLOB等LOB类型。适当拆分:纵向分表适度冗余:空间换时间,将常用的需要连接查询的数据放到主表。不过,冗余的同时需要确保数据的一致性不会遭到破坏,确保更新的同时冗余字段也被更新。避免NULL:NULL类型比较特殊,SQL难优化。虽然MySQLNULL类型和Oracle的NULL有差异,会进入索引中,但如果是一个组合索引,那么这个NULL类型的字段会极大影响整个索引的效率。此外,NULL在索引中的处理也是特殊的,也会占用额外的存放空间。Mysql单表如果数据结构简单2000W以下几乎可以支撑,如果复杂的数据结构500W既可以考虑分表,一般而言如果单表超过5000W,那么性能下降比较厉害。数据库最基本,最常用的优化是什么?表结构优化:正确的数据类型选择、横向/纵向分表、建立索引、删除不必要的字段、适度冗余索引优化:主键索引、独立索引、联合索引SQL语句优化:尽量使用索引、尽量不对条件左边的对象进行运算(包括函数运算)、尽量不使用(!=/<>/not/or)等,可用union代替betweenand区间的取值、尽量使用exists代替in、使用like时尽量使用左匹配’key%’、一般表连接比子查询更快存储过程:利用存储过程完成复杂且传输数据量大的逻辑。数据库储存引擎myisam/innodb的区别①MyISAM不支持事务,而InnoDB支持②InnoDB支持数据行锁定,MyISAM不支持行锁定,只支持锁定整个表③InnoDB支持外键,MyISAM不支持④InnoDB的主键范围更大,最大是MyISAM的2倍。⑤InnoDB不支持全文索引和GIS数据,而MyISAM支持。⑥MyISAM磁盘上是3个文件,.frm文件存储表定义。数据文件的扩展名为.MYD(MYData)。索引文件的扩展名是.MYI(MYIndex)。InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。⑦MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。模糊查询可以使用索引吗?可以,但必须是左匹配’key%’索引的优缺点优点:加快查询效率和表连接的效率、减少分组和排序时间。缺点:创建和更新索引需要耗费时间,随着数据量的增加而增加。索引会额外占用磁盘存储空间。9java中4种修饰符分别为public、protect、default、private的区别修饰符同类同包子类公共private(私有)√默认不写√√protected(受保护)√√√public(公共)√√√√主要是修饰类中的成员(字段、方法、构造方法,内部类); public默认不写:可以修饰类 privateprotedted:不能够修饰类(外部类)10介绍一下Hibernate的缓存机制(或者问:二级缓存)Hibernate中的缓存分一级缓存和二级缓存。一级缓存就是Session级别的缓存,在事务范围内有效是,内置的不能被卸载。二级缓存是SesionFactory级别的缓存,从应用启动到应用结束有效。是可选的,默认没有二级缓存,需要手动开启。保存数据库后,在内存中保存一份,如果更新了数据库就要同步更新。什么样的数据适合存放到第二级缓存中?1)很少被修改的数据帖子的最后回复时间2)经常被查询的数据电商的地点2)不是很重要的数据,允许出现偶尔并发的数据3)不会被并发访问的数据4)常量数据扩展:hibernate的二级缓存默认是不支持分布式缓存的。使用memcahe,redis等中央缓存来代替二级缓存。11说说你日常用到存储过程与触发器的场景触发器:①实施复杂的安全性检查(例如:禁止在非工作时间插入新员工数据)②数据确认或审计(例如:涨薪水,涨后的薪水不能小于涨前)③数据备份与同步(给更新员工信息后自动备份新信息到备份表,或更新和员工相关连的冗余信息)存储过程:定时性的ETL任务、报表统计函数及复杂业务(大量SQL及大数据量传输)可以采用存储过程处理,另外涉及到算法或数据保密的情况也可以将保密逻辑及数据放到存储过程中计算完成,程序只关注传入参数及返回结果。12String,StringBuffer,StringBuilder的区别String(JDK1.0时代)

不可变字符序列StringBuffer(JDK1.0时代)

线程安全的可变字符序列StringBuilder(JDK1.5时代)

非线程安全的可变字符序列

①String和StringBuffer中的value[]都用于存储字符序列,String中的是常量(final)数组,只能被赋值一次。StringBuffer中的value[]就是一个很普通的数组,而且可以通过append()方法将新字符串加入value[]末尾。②StringBuffer线程安全,而StringBuilder不是。③StringBuilder的效率比StringBuffer稍高,如果不考虑线程安全,StringBuilder应该是首选。④StringBuffer对象的append效率要高于String对象的"+"连接操作。13int与Integer的区别①int是基本数据类型,Integer是其包装类,注意是一个类。②Integer默认值是null,而int默认值是0;③声明为Integer的变量需要实例化,而声明为int的变量不需要实例化;④Integer是对象,用一个引用指向这个对象,而int是基本类型,直接存储数值。14如何实现序列化,有什么意义,适用于那些场景?(追问:序列化接口在JVM是怎么实现的)序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆。只有实现了serializable和Externalizable接口的类的对象才能被序列化

后者是前者的子类

实现这个借口的类完全由自身来控制序列化的行为,而仅仅实现前者的类可以采用默认的序列化方式。实现这两个接口标志着对象可以被序列化了Java

串行化技术可以使你将一个对象的状态写入一个Byte

流里,并且可以从其它地方把该Byte

流里的数据读出来,重新构造一个相同的对象。这种机制允许你将对象通过网络进行传播,并可以随时把对象持久化到数据库、文件等系统里。Java的串行化机制是RMI、EJB等技术的技术基础。用途:利用对象的串行化实现保存应用程序的当前工作状态,下次再启动的时候将自动地恢复到上次执行的状态。15JDBC连接数据库的步骤①加载数据库驱动Class.forName("com.mysql.jdbc.Driver");②创建数据库连接Connectioncon=DriverManager.getConnection(url,username,password);③创建一个Statement1、执行静态SQL语句。通常通过Statement实例实现。2、执行动态SQL语句。通常通过PreparedStatement实例实现。3、执行数据库存储过程。通常通过CallableStatement实例实现。④执行SQL语句Statement接口提供了三种执行SQL语句的方法:executeQuery、executeUpdate和execute方法。⑤处理结果ResultSet⑥关闭JDBC对象关闭记录集ResultSet、声明Statement和连接Connection16Mybatis中#{...}和${...}的区别#{}语法,MyBatis会产生PreparedStatement语句中,并且安全的设置PreparedStatement参数,这个过程中MyBatis会进行必要的安全检查和转义。${}是直接输出变量的值,未经过预编译的,仅仅是取变量的值,是非安全的,存在sql注入.尽量使用#,但是${}在什么情况下使用呢?有时候可能需要直接插入一个不做任何修改的字符串到SQL语句中。这时候应该使用${}语法。比如,动态SQL中的字段名,如:ORDERBY${columnName}17什么是乐观锁,什么是悲观锁,两者的区别是什么悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。开始改变对象时锁住直到完成所有操作后才释放。乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。修改过程不锁定对象,直到提交所做更改时才将对象锁住。读取时不加锁,因此可能会造成脏读。乐观锁的实现方式①使用自增长的整数表示数据版本号。更新时检查版本号是否一致,比如数据库中数据版本为6,更新提交时version=6+1,使用该version值(=7)与数据库version+1(=7)作比较,如果相等,则可以更新,如果不等则有可能其他程序已更新该记录,所以返回错误。②使用时间戳来实现.注:对于以上两种方式,Hibernate自带实现方式:在使用乐观锁的字段前加annotation:@Version,Hibernate在更新时自动校验该字段。在实际生产环境里边,如果并发量不大且不允许脏读,可以使用悲观锁解决并发问题;但如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,所以我们就要选择乐观锁定的方法.18VectorArrayListLinkedList的区别这三者都实现了List接口.所有使用方式也很相似,主要区别在于因为实现方式的不同,所以对不同的操作具有不同的效率。ArrayList是一个可改变大小的数组.当更多的元素加入到ArrayList中时,其大小将会动态地增长.内部的元素可以直接通过get与set方法进行访问,因为ArrayList本质上就是一个数组.LinkedList是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList.当然,这些对比都是指数据量很大或者操作很频繁的情况下的对比,如果数据和运算量很小,那么对比将失去意义.Vector和ArrayList类似,但属于强同步类。如果你的程序本身是线程安全的(thread-safe,没有在多个线程之间共享同一个集合/对象),那么使用ArrayList是更好的选择。Vector和ArrayList在更多元素添加进来时会请求更大的空间。Vector每次请求其大小的双倍空间,而ArrayList每次对size增长50%.而LinkedList还实现了Queue接口,该接口比List提供了更多的方法,包括offer(),peek(),poll()等.注意:默认情况下ArrayList的初始容量非常小,所以如果可以预估数据量的话,分配一个较大的初始值属于最佳实践,这样可以减少调整大小的开销。19HashtableHashMapTreeMap的区别

Hashmap是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null;允许多条记录的值为Null;HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用Collections的synchronizedMap方法使HashMap具有同步的能力.

Hashtable与HashMap类似,但是主要有6点不同。

1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样。

2.HashTable不允许null值,key和value都不可以,HashMap允许null值,key和value都可以。HashMap允许key值只能由一个null值,因为hashmap如果key值相同,新的key,

value将替代旧的。

3.HashTable有一个contains(Object

value)功能和containsValue(Object

value)功能一样。

4.HashTable使用Enumeration,HashMap使用Iterator。

5.HashTable中hash数组默认大小是11,增加的方式是

old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

6.哈希值的使用不同,HashTable直接使用对象的hashCode。

TreeMap能够把它保存的记录根据键排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。20TomcatApachejbossweblogic的区别Apache:全球应用最广泛的http服务器,免费,出自apache基金组织Tomcat:应用也算非常广泛的web服务器,支持部分j2ee,免费,出自apache基金组织JBoss:开源的应用服务器,比较受人喜爱,免费(文档要收费)Weblogic:应该说算是业界第一的appserver,全部支持j2ee1.4,对于开发者,有免费使用一年的许可证。Apache支持静态页,Tomcat支持动态的,比如Servlet等,一般使用Apache+Tomcat的话,Apache只是作为一个转发,对JSP的处理是由Tomcat来处理的。Apche可以支持PHPcgiperl,但是要使用Java的话,你需要Tomcat在Apache后台支撑,将Java请求由Apache转发给Tomcat处理。Apache是Web服务器,Tomcat是应用(Java)服务器,它只是一个Servlet(JSP也翻译成Servlet)容器,可以认为是Apache的扩展,但是可以独立于Apache运行。JBoss和WebLogic都含有Jsp和Servlet容器,也就可以做web容器,也包含EJB容器,是完整的J2EE应用服务器。Tomcat只能做jsp和servlet的container21SessionCookie的区别①cookie数据存放在客户的浏览器上,session数据放在服务器上。②cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。③session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能

考虑到减轻服务器性能方面,应当使用COOKIE。④单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。22JDBC、Hibernate、Mybatis的区别JDBC->Mybatis->Hibernate:原生->半自动化->全自动化1)从层次上看,JDBC是较底层的持久层操作方式,而Hibernate和MyBatis都是在JDBC的基础上进行了封装使其更加方便程序员对持久层的操作。2)从功能上看,JDBC就是简单的建立数据库连接,然后创建statement,将sql语句传给statement去执行,如果是有返回结果的查询语句,会将查询结果放到ResultSet对象中,通过对ResultSet对象的遍历操作来获取数据;Hibernate是将数据库中的数据表映射为持久层的Java对象,实现数据表的完整性控制;MyBatis是将sql语句中的输入参数和输出参数映射为java对象,放弃了对数据表的完整性控制,但是获得了更灵活和响应性能更快的优势。3)从使用上看,如果进行底层编程,而且对性能要求极高的话,应该采用JDBC的方式;如果要对数据库进行完整性控制的话建议使用Hibernate;如果要灵活使用sql语句的话建议采用MyBatis框架。23SpringMVC与Struts2的区别目前企业中使用SpringMvc的比例已经远远超过Struts2,那么两者到底有什么区别,是很多初学者比较关注的问题,下面我们就来对SpringMvc和Struts2进行各方面的比较:1.核心控制器(前端控制器、预处理控制器):对于使用过mvc框架的人来说这个词应该不会陌生,核心控制器的主要用途是处理所有的请求,然后对那些特殊的请求(控制器)统一的进行处理(字符编码、文件上传、参数接受、异常处理等等),springmvc核心控制器是Servlet,而Struts2是Filter。2.控制器实例:SpringMvc会比Struts快一些(理论上)。SpringMvc是基于方法设计,而Sturts是基于对象,每次发一次请求都会实例一个action,每个action都会被注入属性,而Spring更像Servlet一样,只有一个实例,每次请求执行对应的方法即可(注意:由于是单例实例,所以应当避免全局变量的修改,这样会产生线程安全问题)。3.管理方式:大部分的公司的核心架构中,就会使用到spring,而springmvc又是spring中的一个模块,所以spring对于springmvc的控制器管理更加简单方便,而且提供了全注解方式进行管理,各种功能的注解都比较全面,使用简单,而struts2需要采用XML很多的配置参数来管理(虽然也可以采用注解,但是几乎没有公司那样使用)。4.参数传递:Struts2中自身提供多种参数接受,其实都是通过(ValueStack)进行传递和赋值,而SpringMvc是通过方法的参数进行接收。5.学习难度:Struts更加很多新的技术点,比如拦截器、值栈及OGNL表达式,学习成本较高,springmvc比较简单,很较少的时间都能上手。6.intercepter的实现机制:struts有以自己的interceptor机制,springmvc用的是独立的AOP方式。这样导致struts的配置文件量还是比springmvc大,虽然struts的配置能继承,所以我觉得论使用上来讲,springmvc使用更加简洁,开发效率SpringMVC确实比struts2高。springmvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上spring3mvc就容易实现restfulurl。struts2是类级别的拦截,一个类对应一个request上下文;实现restfulurl要费劲,因为struts2action的一个方法可以对应一个url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。spring3mvc的方法之间基本上独立的,独享requestresponse数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架方法之间不共享变量,而struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码,读程序时带来麻烦。7.springmvc处理ajax请求,直接通过返回数据,方法中使用注解@ResponseBody,springmvc自动帮我们对象转换为JSON数据。而struts2是通过插件的方式进行处理在SpringMVC流行起来之前,Struts2在MVC框架中占核心地位,随着SpringMVC的出现,SpringMVC慢慢的取代struts2,但是很多企业都是原来搭建的框架,使用Struts2较多。24请描述SpringMvc工作原理1、用户向服务器发送请求,请求被Spring前端控制ServeltDispatcherServlet捕获(捕获)2、

DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;(查找handler)3、

DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter。

提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller),

Handler执行完成后,向DispatcherServlet

返回一个ModelAndView对象(执行handler)4、DispatcherServlet根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)

(选择ViewResolver)5、通过ViewResolver结合Model和View,来渲染视图,DispatcherServlet

将渲染结果返回给客户端。(渲染返回)25请描述ssm(springspringmvcmybatis)工作流程先写实体类entity,定义对象的属性,(可以参照数据库中表的字段来设置,数据库的设计应该在所有编码开始之前)。写Mapper.xml(Mybatis),其中定义你的功能,对应要对数据库进行的那些操作,比如insert、selectAll、selectByKey、delete、update等。写Mapper.java,将Mapper.xml中的操作按照id映射成Java函数。写Service.java,为控制层提供服务,接受控制层的参数,完成相应的功能,并返回给控制层。写Controller.java,连接页面请求和服务层,获取页面请求的参数,通过自动装配,映射不同的URL到相应的处理函数,并获取参数,对参数进行处理,之后传给服务层。写JSP页面调用,请求哪些参数,需要获取什么数据26说说你对Java中反射的理解以及应用场景JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。应用:①获取某个对象的属性②获取类的静态属性③执行某对象方法④执行类的静态方法⑤创建某个类的实例⑥判断对象是否是某个类的实例27Servlet的生命周期Servlet生命周期:Servlet加载>实例化>服务>销毁。init:在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。service:它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。destroy:

仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。创建Servlet对象的时机:Servlet容器启动时:读取web.xml配置文件中的信息,构造指定的Servlet对象,创建ServletConfig对象,同时将ServletConfig对象作为参数来调用Servlet对象的init方法。在Servlet容器启动后:客户首次向Servlet发出请求,Servlet容器会判断内存中是否存在指定的Servlet对象,如果没有则创建它,然后根据客户的请求创建HttpRequest、HttpResponse对象,从而调用Servlet

对象的service方法。Servlet

Servlet容器在启动时自动创建Servlet,这是由在web.xml文件中为Servlet设置的<load-on-startup>属性决定的。从中我们也能看到同一个类型的Servlet对象在Servlet容器中以单例的形式存在。28equals相关问题:Java中equals和==的区别是什么?相等的理解(==和equals)相等:传统的理解一般都是数字值是否相等;在程序中任何东西都是数据,都会比较是否相等==基本数据类型:比较的就是值是否相等;引用数据类型:比较的是对象的地址是否一样;equals(最初定义在根类Object中的)基本数据类型:不能够使用!基本数据类型不是对象,不能够调用Object中的方法引用数据类型:在Object的源码中定义的就是==进行比较比较如果我们没有去覆写过equals方法而是直接调用到了Object中的此方法,那么结果和==比较应用数据类型一样的;在实际开发中,我们一般比较对象都是通过对象的属性值进行比较(一般比较对象的地址没有多大用处),所以我们会经常覆写Object中的此方法,把自己的规则写在方法里面;覆写equals方法必须覆写hashCode方法吗?你的理解是什么?不是必须。但是假如一个类要创建很多对象,而这些对象要存储集合不确定,有可能是hashSet,也有可能是TreeSet,为了保证唯一性,所以最好复写hashCode方法,因为对象存入带hash的集合,如hashSet,hashMap,都要基于hashCode和equals方法,当hashCode方法返回的值一样时,还会调用equals方法判断,如果两个方法返回的都是一致,才判断两个对象是同一个对象,不存入集合(带hash的集合都保证数据是唯一的!)29开发这么久了遇到了哪些异常?Nullpointerexception、classnotfoundexception、arrayindexoutofboundsexception、illegalargumentexception、ClassCastException、FileNotFoundException、NumberFormatException、NoSuchMethodException、IOException、SQLException、NoClassDefFoundError、OutOfMemoryError30你了解分布式和数据库集群吗?分布式是一个非常广泛的概念,从系统的角度来说,可以理解为,一个业务分拆多个子业务,部署在不同的服务器上,集群则是同一个业务部署在多个服务器上。JavaEE开发过程中,常见的分布式框架有:Dubbo、Hadoop、Elasticsearch数据库集群:MySQL集群是一个无共享的(shared-nothing)、分布式节点架构的存储方案,其目的是提供容错性和高性能。通过多个MySQL服务器分配负载,从而最大程序地达到高性能,通过在不同位置存储数据保证高可用性和冗余。一般由一个主(写)+一个备(写)和N个从(读)库组成。31静态变量和实例变量的区别?类变量也叫静态变量,也就是在变量前加了static的变量;实例变量也叫对象变量,即没加static的变量;区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象32Overload和Override的区别方法重载和方法重写33MyBatis如何防止Sql注入①使用#{},避免使用${}。②使用存储过程34svn提交代码,发生冲突了如何处理①更新最新的服务器代码下来②打开冲突的文件进行对比③简单冲突直接修改,复杂冲突找到上个提交人协助修改,修改完成后标记为“已解决”④提交修改完成的文件35线程问题进程和线程的区别,简单描述进程和线程?进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.关系一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。区别进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。1)

简而言之,一个程序至少有一个进程,一个进程至少有一个线程.2)

线程的划分尺度小于进程,使得多线程程序的并发性高。3)

另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。4)

线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。5)

从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。讲讲JDK的线程池ThreadPoolExecutor

ThreadPool中的线程不用手动开始,也不用手动取消,要做的只是把工作函数排入线程池,剩下的工作由系统自动完成,不能控制线程池中的线程。以下情况不适宜用ThreadPool:线程执行时间长、线程需要制定不同的优先级、执行过程中需要控制线程的睡眠和挂起等操作。所以ThreadPool适合并发运行若干个运行时间不长且互不干扰的函数。①ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程调度,线程池管理等等服务;②Executors方法提供的线程服务,都是通过参数设置来实现不同的线程池机制。lock和synchronized区别①、ReentrantLock拥有Synchronized相同的并发性和内存语义,此外还多了锁投票,定时锁等候和中断锁等候

线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定,

如果使用synchronized,如果A不释放,B将一直等下去,不能被中断

如果使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情

ReentrantLock获取锁定与三种方式:

a)

lock(),如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁

b)tryLock(),

如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;

c)tryLock(long

timeout,TimeUnit

unit),

如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;

d)lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断

②、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中

③、在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;系统中的并发是怎样解决的synchronized关键字主要解决多线程共享数据同步问题。

ThreadLocal使用场合主要解决多线程中数据因并发产生不一致问题。ThreadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别:synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。Synchronized用于线程间的数据共享,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论