Java面试(持续更新......)

hibernate 对象状态

瞬时态
由new命令开辟内存空间的java对象,

eg.Person person=newPerson("xiaoxiao","女");

如果没有变量对该对象进行引用,它将被java虚拟机回收.

瞬时对象在内存孤立存在,它是携带信息的载体,不和数据库的数据有任何关联关系,在Hibernate中,可通过session的save()或saveOrUpdate()方法将瞬时对象与数据库相关联,并将数据对应的插入数据库中,此时该瞬时对象转变成持久化对象.

持久态
处于该状态的对象在数据库中具有对应的记录,并拥有一个持久化标识.如果是用hibernate的delete()方法,对应的持久对象就变成瞬时对象,因数据库中的对应数据已被删除,该对象不再与数据库的记录关联.

当一个session执行close()或clear()、evict()之后,持久对象变成脱管对象,此时持久对象会变成脱管对象,此时该对象虽然具有数据库识别值,但它已不在HIbernate持久层的管理之下.

持久对象具有如下特点:

1.和session实例关联;

2.在数据库中有与之关联的记录.

脱管态
当与某持久对象关联的session被关闭后,该持久对象转变为脱管对象.当脱管对象被重新关联到session上时,并再次转变成持久对象.

脱管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等方法,转变成持久对象.

脱管对象具有如下特点:

1.本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;

2.比瞬时对象多了一个数据库记录标识值.


 

integer int 区别

int是基本数据类型,Integer是对int进行了封装的一个类。 
声明为int的变量不需要实例化,声明为Interger的变量需要实例化 


 

forward redirect区别

答:forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。
redirect就是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取


 

overloadoverride

override(重写) 
1、方法名、参数、返回值相同。
2、子类方法不能缩小父类方法的访问权限。
3、子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。
4、存在于父类和子类之间。
5、方法被定义为final不能被重写。
overload(重载)
1、参数类型、个数、顺序至少有一个不相同。 
2、不能重载只有返回值不同的方法名。
3、存在于父类和子类、同类中。


 

struts2原理

1.       浏览器发送一个请求。

2.       核心控制器FilterDispatcher根据请求决定调用合适的Action。

3.       WebWork的拦截器链自动对请求应用通用功能,如验证等。

4.       回调Action的execute方法,该execute方法根据请求的参数来执行一定的操作。

5.       Action的execute方法处理结果信息将被输出到浏览器中,支持多种形式的视图

FilterDispatcher 询问 -->ActionMapper决定是否调用action --> ActionProxy 调用struts.xml


 

webservice 底层协议是什么

1.定义
由两部分组成
·SOAP--Web Service之间的基本通信协议。
·WSDL--Web Service描述语言,它定义了WebService做什么,怎么做和查询的信息。


2.简单的Web Service实现
包含四个基本步骤
·创建Web Service的商业逻辑(通常是一些Java类)
·将这些Java类部署到一个SOAP服务器
·生成客户访问代码
·部署客户应用
注意:WSDL等文件的生成通常是利用厂商提供的工具来完成



spring 哪种创建模式来创造对象,通过哪个类

可以把IoC模式看做是工厂模式的升华,可以把IoC看作是一个大工厂,只不过这个大工厂里要生成的对象都是在XML文件中给出定义的,然后利用Java 的“反射”编程,根据XML中给出的类名生成相应的对象。从实现来看,IoC是把以前在工厂方法里写死的对象生成代码,改变为由XML文件来定义

其实控制反转就是不需要我们手动new一个对象了,它把我们所要实例化的对象都写在了配置文件xml中了,一般这个类都是我们应用的业务类(Business Object)


 

left join, right join

left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 
right join(
右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录

inner join(等值连接) 只返回两个表中联结字段相等的行 



强制杀死一个线程,后面跟什么参数

查看线程 ps ax

查看线程 kill-9


 

如何给目录创建任何人都能访问的权限

mkdir  777 /home/cc/it.dengchao.org

 

1.      使用 useradd 命令来创建一个锁定的用户账号:

useradd <username>

2.      使用 passwd 命令,通过指派口令和口令老化规则来给某账号开锁:

passwd <username>

 

useradd 的命令行选项在表 25-1中被列出。

linuxuserdel 命令详解

  功能说明:删除用户帐号。

  语  法:userdel [-r][用户帐号]

  补充说明:userdel可删除用户帐号与相关的文件。若不加参数,则仅删除用户帐号,而不删除相关文件。

  参  数:
  -f  删除用户登入目录以及目录中所有文件。


不用排序算法,利用I/O自带的方法完成排序


Javascript如何删除数组对象

 

vararr=['a','b','c'];

 

若要删除其中的'b',有两种方法:

 

1.delete方法:delete arr[1]

 

这种方式数组长度不变,此时arr[1]变为undefined了,但是也有好处原来数组的索引也保持不变,此时要遍历数组元素可以才用

 

for(index in arr)

 

document.write('arr['+index+']='+arr[index]);

 

这种遍历方式跳过其中undefined的元素

 

* 该方式IE4.o以后都支持了

 

2.数组对象splice方法:arr.splice(1,1);

 

这种方式数组长度相应改变,但是原来的数组索引也相应改变

 

splice参数中第一个1,是删除的起始索引(从0算起),在此是数组第二个元素

 

第二个1,是删除元素的个数,在此只删除一个元素,即'b';

 

此时遍历数组元素可以用普通遍历数组的方式,比如for,因为删除的元素在

 

数组中并不保留

 


简单讲述notify()以及wait()的使用

 

The use of theimplicit monitors in Java objects is powerful, but you can achieve a moresubtle level of control through inter-process communication. As you will see,this is especially easy in Java.

Multithreadingreplaces event loop programming by dividing your tasks into discrete andlogical units. Threads also provide a secondary benefit: they do away withpolling. Polling is usually implemented by a loop that is used to check somecondition repeatedly. Once the condition is true, appropriate action is taken.This wastes CPU time. For example, consider the classic queuing problem, whereone thread is producing some data and another is consuming it. To make theproblem more interesting, suppose that the producer has to wait until theconsumer is finished before it generates more data. In a polling system, theconsumer would waste many CPU cycles while it

waited for theproducer to produce. Once the producer was finished, it would start polling,wasting more CPU cycles waiting for the consumer to finish, and so on. Clearly,this situation is undesirable.

 

To avoid polling,Java includes an elegant interrocess communication mechanism via the wait( ),notify( ), and notifyAll( ) methods. These methods are implemented as finalmethods in Object, so all classes have them. All three methods can be calledonly from within a synchronized method. Although conceptually advanced from acomputer science perspective, the rules for using these methods are actuallyquite simple:

 

wait( ) tells thecalling thread to give up the monitor and go to sleep until some other

thread enters thesame monitor and calls notify( ).

notify( ) wakes upthe first thread that called wait( ) on the same object.

notifyAll( ) wakes upall the threads that called wait( ) on the same object. The

highest prioritythread will run first.

These methods aredeclared within Object, as shown here:

 

final void wait( )throws InterruptedException

final void notify( )

final void notifyAll()

 

Additional forms ofwait( ) exist that allow you to specify a period of time to wait. The followingsample program incorrectly implements a simple form of the producer/consumerproblem. It consists of four classes: Q, the queue that you're trying tosynchronize; Producer, the threaded object that is producing queue entries;Consumer, the threaded object that is consuming queue entries; and PC, the tinyclass that creates the single Q, Producer, and Consumer.

 

// An incorrectimplementation of a producer and consumer.

class Q {

int n;

synchronized intget() {

System.out.println("Got:" + n);

return n;

}

synchronized voidput(int n) {

this.n = n;

System.out.println("Put:" + n);

}

}

 

class Producerimplements Runnable {

Q q;

Producer(Q q) {

this.q = q;

new Thread(this,"Producer").start();

}

public void run() {

int i = 0;

while(true) {

q.put(i++);

}

}

}

 

class Consumerimplements Runnable {

Q q;

Consumer(Q q) {

this.q = q;

new Thread(this,"Consumer").start();

}

public void run() {

while(true) {

q.get();

}

}

}

 

class PC {

public static voidmain(String args[]) {

Q q = new Q();

new Producer(q);

new Consumer(q);

System.out.println("PressControl-C to stop.");

}

}

 

Although the put( )and get( ) methods on Q are synchronized, nothing stops the producer fromoverrunning the consumer, nor will anything stop the consumer from consumingthe same queue value twice. Thus, you get the erroneous output shown here (theexact output will vary with processor speed and task load):

 

Put: 1

Got: 1

Got: 1

Got: 1

Got: 1

Got: 1

Put: 2

Put: 3

Put: 4

Put: 5

Put: 6

Put: 7

Got: 7

 

As you can see, afterthe producer put 1, the consumer started and got the same 1 five times in arow. Then, the producer resumed and produced 2 through 7 without letting theconsumer have a chance to consume them.

 

The proper way towrite this program in Java is to use wait( ) and notify( ) to signal in bothdirections, as shown here:

 

// A correctimplementation of a producer and consumer.

class Q {

int n;

boolean valueSet =false;

synchronized intget() {

if(!valueSet)

try {

wait();

}catch(InterruptedException e) {

System.out.println("InterruptedExceptioncaught");

}

System.out.println("Got:" + n);

valueSet = false;

notify();

return n;

}

synchronized voidput(int n) {

if(valueSet)

try {

wait();

}catch(InterruptedException e) {

System.out.println("InterruptedExceptioncaught");

}

this.n = n;

valueSet = true;

System.out.println("Put:" + n);

notify();

}

}

 

class Producerimplements Runnable {

Q q;

Producer(Q q) {

this.q = q;

new Thread(this,"Producer").start();

}

public void run() {

int i = 0;

while(true) {

q.put(i++);

}

}

}

 

class Consumerimplements Runnable {

Q q;

Consumer(Q q) {

this.q = q;

new Thread(this,"Consumer").start();

}

public void run() {

while(true) {

q.get();

}

}

}

 

class PCFixed {

public static voidmain(String args[]) {

Q q = new Q();

new Producer(q);

new Consumer(q);

System.out.println("PressControl-C to stop.");

}

}

 

Inside get( ), wait() is called. This causes its execution to suspend until the Producer notifiesyou that some data is ready. When this happens, execution inside get( )resumes. After the data has been obtained, get( ) calls notify( ). This tellsProducer that it is okay to put more data in the queue. Inside put( ), wait( )suspends execution until the Consumer has removed the item from the queue. Whenexecution resumes, the next item of data is put in the queue, and notify( ) iscalled. This tells the Consumer that it should now remove it.

 

Here is some outputfrom this program, which shows the clean synchronous behavior:

 

Put: 1

Got: 1

Put: 2

Got: 2

Put: 3

Got: 3

Put: 4

Got: 4

Put: 5

Got: 5

 


Struts1struts2的区别


Lazyloadinstant load的区别


对数据库进行操作的时候是如何考虑SQL语句的效率的


单元测试的覆盖率的问题,如何保证


自定义标签如何实现国际化


简单描述所知道的分页方法,实现细节


Hashmaphashtable


谈谈所熟悉的Ajax框架以及在项目中的使用


结合项目谈谈webservice是如何实现的(client/server


数据库设计表的时候应该注意哪些问题


程序中的事务管理是怎么做得


数据库的乐观锁以及悲观锁的认识

 

锁( locking )

 

业务逻辑的实现过程中,往往需要保证数据访问的排他性。如在金融系统的日终结算

处理中,我们希望针对某个 cut-off 时间点的数据进行处理,而不希望在结算进行过程中

(可能是几秒种,也可能是几个小时),数据再发生变化。此时,我们就需要通过一些机

制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓

的 “ 锁 ” ,即给我们选定的目标数据上锁,使其无法被其他程序修改。

Hibernate 支持两种锁机制:即通常所说的 “ 悲观锁( Pessimistic Locking ) ”

和 “ 乐观锁( Optimistic Locking ) ” 。

 

悲观锁( Pessimistic Locking )

 

悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自

外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定

状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能

真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系

统不会修改数据)。

一个典型的倚赖数据库的悲观锁调用:

select * from accountwhere name=”Erica” for update

这条 sql 语句锁定了 account 表中所有符合检索条件( name=”Erica” )的记录。

本次事务提交之前(事务提交时会释放事务过程中的锁),外界无法修改这些记录。

Hibernate 的悲观锁,也是基于数据库的锁机制实现。

 

注意,只有在查询开始之前(也就是 Hiberate 生成 SQL 之前)设定加锁,才会

真正通过数据库的锁机制进行加锁处理,否则,数据已经通过不包含 for update

子句的 Select SQL 加载进来,所谓数据库加锁也就无从谈起。

 

乐观锁( Optimistic Locking )

 

相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依

靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库

性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。

如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进

行修改时(如更改用户帐户余额),如果采用悲观锁机制,也就意味着整个操作过

程中(从操作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作

员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见,如果面对几

 

百上千个并发,这样的情况将导致怎样的后果。

乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本

( Version )记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于

数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来

实现。

读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提

交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据

版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

对于上面修改用户帐户信息的例子而言,假设数据库中帐户信息表中有一个

version 字段,当前值为 1 ;而当前帐户余额字段( balance )为 $100 。

1 操作员 A 此时将其读出( version=1 ),并从其帐户余额中扣除 $50

( $100-$50 )。

2 在操作员 A 操作的过程中,操作员 B 也读入此用户信息( version=1 ),并

从其帐户余额中扣除 $20 ( $100-$20 )。

3 操作员 A 完成了修改工作,将数据版本号加一( version=2 ),连同帐户扣

除后余额( balance=$50 ),提交至数据库更新,此时由于提交数据版本大

于数据库记录当前版本,数据被更新,数据库记录 version 更新为 2 。

4 操作员 B 完成了操作,也将版本号加一( version=2 )试图向数据库提交数

据( balance=$80 ),但此时比对数据库记录版本时发现,操作员 B 提交的

数据版本号为 2 ,数据库记录当前版本也为 2 ,不满足 “ 提交版本必须大于记

录当前版本才能执行更新 “ 的乐观锁策略,因此,操作员 B 的提交被驳回。

这样,就避免了操作员 B 用基于 version=1 的旧数据修改的结果覆盖操作

员 A 的操作结果的可能。

从上面的例子可以看出,乐观锁机制避免了长事务中的数据库加锁开销(操作员 A

和操作员 B 操作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系

统整体性能表现。

需要注意的是,乐观锁机制往往基于系统中的数据存储逻辑,因此也具备一定的局

限性,如在上例中,由于乐观锁机制是在我们的系统中实现,来自外部系统的用户

余额更新操作不受我们系统的控制,因此可能会造成脏数据被更新到数据库中。在

系统设计阶段,我们应该充分考虑到这些情况出现的可能性,并进行相应调整(如

将乐观锁策略在数据库存储过程中实现,对外只开放基于此存储过程的数据更新途

径,而不是将数据库表直接对外公开)。


正则表达式的使用以及认识


使用Threadrunnable来实现多线程性能的差别

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值