java 面试

来源:互联网 发布:天津广电网络网上缴费 编辑:程序博客网 时间:2024/06/06 00:10

http://blog.sina.com.cn/s/blog_701b128e0101dywn.html

IGT公司java第一轮面试总结

 (2013-09-25 22:41:51)
转载
标签: 

java

 

it

 

igt

分类: JAVA学习中的总结
1.Object有哪些方法?
2.equals和hashCode有什么关系?
  sun公司规定,覆盖equals方法的同时必须同时覆盖hashCode方法,equals返回为true时,hashCode应该相等,但是hashCode相等时,equals不一定相等;hashCode主要是在集合中会隐式的调用,如几个一hash开头的集合:HashSet、HashTable、HashMap等。
3.如何防止多线程并发的访问某一方法?
  可以给某一代码块加同步对象锁,synchronized(this){}(作用是进入代码块的线程获得了当前对象锁,this代表当前对象,一个对象只有一个对象锁,如果另一个线程要想操作对象锁,则必须等待对象锁空闲),或者用synchronized修饰某一方法。
4.单例模式的设计和多线程下的安全问题?
  1)使用Class锁机制

以上问题最直观的解决办法就是给getInstance方法加上一个synchronize前缀,这样每次只允许一个现成调用getInstance方法:

Java代码  收藏代码
  1. public static synchronized Singleton getInstance(){        
  2.     if (instance == null       
  3.     instance new Singleton();         
  4.     return instance;         
  5.       

 

    这种解决办法的确可以防止错误的出现,但是它却很影响性能:每次调用getInstance方法的时候都必须获得Singleton的锁,而实际上,当单例实例被创建以后,其后的请求没有必要再使用互斥机制了

    2)double-checked locking
曾经有人为了解决以上问题,提出了double-checked locking的解决方案

Java代码  收藏代码
  1. public static Singleton getInstance(){        
  2.     if (instance == null       
  3.         synchronized(instance){        
  4.             if(instance == null       
  5.                 instance new Singleton();        
  6.                
  7.     return instance;         
  8.  

 

         让我们来看一下这个代码是如何工作的:首先当一个线程发出请求后,会先检查instance是否为null,如果不是则直接返回其内容,这样避免了进入synchronized块所需要花费的资源。其次,即使第2节提到的情况发生了,两个线程同时进入了第一个if判断,那么他们也必须按照顺序执行synchronized块中的代码,第一个进入代码块的线程会创建一个新的Singleton实例,而后续的线程则因为无法通过if判断,而不会创建多余的实例。

         上述描述似乎已经解决了我们面临的所有问题,但实际上,从JVM的角度讲,这些代码仍然可能发生错误。

         对于JVM而言,它执行的是一个个Java指令。在Java指令中创建对象和赋值操作是分开进行的,也就是说instance = new Singleton();语句是分两步执行的。但是JVM并不保证这两个操作的先后顺序,也就是说有可能JVM会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。这样就使出错成为了可能,我们仍然以A、B两个线程为例:

1.         A、B线程同时进入了第一个if判断

2.         A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();

3.         由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块。

4.         B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。

5.         此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。

      通过内部类实现多线程环境中的单例模式
为了实现慢加载,并且不希望每次调用getInstance时都必须互斥执行,最好并且最方便的解决办法如下:

    3)静态内部类实现多线程下的单例模式(静态内部类也是用到时候才加载,比如下面是调用getInstance时候才加载)

Java代码  收藏代码
  1. public class Singleton{        
  2.     private Singleton(){        
  3.         …        
  4.            
  5.     private static class SingletonContainer{        
  6.         private static Singleton instance new Singleton();        
  7.            
  8.     public static Singleton getInstance(){        
  9.         return SingletonContainer.instance;        
  10.            
  11.       

 

       JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心3.2中的问题。此外该方法也只会在第一次调用的时候使用互斥机制,这样就解决了3.1中的低效问题。最后instance是在第一次加载SingletonContainer类时被创建的,而SingletonContainer类则在调用getInstance方法的时候才会被加载,因此也实现了惰性加载。

5.可以画出数据库表的联合查询结果?(内连接、左外连接、右外连接)

create table A(aid int(1),adata varchar(1));

create table B(bid int(1),bdata varchar(1));

insert into A values(1,'1');

insert into A values(2,'2');

insert into A values(3,'3');

insert into B values(1,'1');

insert into B values(2,'2');

insert into B values(4,'4');

select *from A a inner join B b on(a.aid=b.bid);

select *from A a left outer join B b on(a.aid=b.bid);

select *from A a right outer join B b on(a.aid=b.bid);


6.session是用来干什么的?

    根据设计,HTTP是一种无状态的协议。它意味着Web应用并不了解有关同一用户以前请求的信息。维持会话状态信息的方法之一是使用Servlet或者JSP容器提供的会话跟踪功能。Servlet API规范定义了一个简单的HttpSession接口,通过它我们可以方便地实现会话跟踪。

7.spring是用来做什么的?

8.一个无序集合放着可能重复的数字(1-100),请用你认为很快的方法找到里面重复的数字有哪些?

0 0
原创粉丝点击