java面试题整理(二)

参考文章http://blog.csdn.net/sgx425021234/article/details/8786152

1、 Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 

不可以,匿名内部类的实现简化了部分的编程环境,但是他的功能也较弱,他采用无参或者声明的时候传参来构造,他能访问的外部类的实例变量必须用final修饰,也就是他可以访问当时不可以修改

测试代码如下

package 匿名内部类;

public class Test {
    class A implements Help {
               public String getName() {
                      return "Name-A";
              }
   }
   interface Help{
	   public String getName();
   }
   class TestClassB{
	   
   }
   interface estInterface{
	   
   }
   public static void main(String[] args) {
             //正确写法

             Help help = new Help() {
                     public String getName() {
                              return "Name-Help";
                     }
             };

             //用 Eclipse 检验有没语法错误,就知道答案了
             //预先告诉结果:这种写法是不可行的。

//             Help help1 = new Help() implements TestInterface {
//                     public String getName() {
//                              return "Name-Help";
//                     }
//             };
   }

}
关于内部类的理解可以参考http://blog.sina.com.cn/s/blog_77c6324101016hgm.html

2、 HashMap和Hashtable的区别。 

来自度娘的回答:

Hashtable和HashMap类有三个重要的不同之处。第一个不同主要是历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。
  
  也许最重要的不同是Hashtable的方法是同步的,而HashMap的方法不是。这就意味着,虽然你可以不用采取任何特殊的行为就可以在一个多线程的应用程序中用一个Hashtable,但你必须同样地为一个HashMap提供外同步。一个方便的方法就是利用Collections类的静态的synchronizedMap()方法,它创建一个线程安全的Map对象,并把它作为一个封装的对象来返回。这个对象的方法可以让你同步访问潜在的HashMap。这么做的结果就是当你不需要同步时,你不能切断Hashtable中的同步(比如在一个单线程的应用程序中),而且同步增加了很多处理费用。
  
  第三点不同是,只有HashMap可以让你将空值作为一个表的条目的key或value。HashMap中只有一条记录可以是一个空的key,但任意数量的条目可以是空的value。这就是说,如果在表中没有发现搜索键,或者如果发现了搜索键,但它是一个空的值,那么get()将返回null。如果有必要,用containKey()方法来区别这两种情况。
  
  一些资料建议,当需要同步时,用Hashtable,反之用HashMap。但是,因为在需要时,HashMap可以被同步,HashMap的功能比Hashtable的功能更多,而且它不是基于一个陈旧的类的,所以有人认为,在各种情况下,HashMap都优先于Hashtable。
  
  关于Properties
  有时侯,你可能想用一个hashtable来映射key的字符串到value的字符串。DOS、Windows和Unix中的环境字符串就有一些例子,如key的字符串PATH被映射到value的字符串C:\WINDOWS;C:\WINDOWS\SYSTEM。Hashtables是表示这些的一个简单的方法,但Java提供了另外一种方法。
  
  Java.util.Properties类是Hashtable的一个子类,设计用于String keys和values。Properties对象的用法同Hashtable的用法相象,但是类增加了两个节省时间的方法,你应该知道。
  
  Store()方法把一个Properties对象的内容以一种可读的形式保存到一个文件中。Load()方法正好相反,用来读取文件,并设定Properties对象来包含keys和values。
  
  注意,因为Properties扩展了Hashtable,你可以用超类的put()方法来添加不是String对象的keys和values。这是不可取的。另外,如果你将store()用于一个不包含String对象的Properties对象,store()将失败。作为put()和get()的替代,你应该用setProperty()和getProperty(),它们用String参数。
  
  好了,我希望你现在可以知道如何用hashtables来加速你的处理了。

可以参考阅读http://blog.csdn.net/shohokuf/article/details/3932967

3、 Collection 和 Collections的区别。 

1、java.util.Collection 是一个 集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
  Collection   
├List   
│├LinkedList   
│├ArrayList   
│└Vector   
│ └Stack   
└Set 
 
2、java.util.Collections 是一个包装类。它包含有各种有关集合操作的 静态多态方法。此类 不能实例化,就像一 个工具类,服务于Java的Collection框架。
Java代码   收藏代码
  1. import java.util.ArrayList;  
  2. import java.util.Collections;  
  3. import java.util.List;  
  4.   
  5. public class TestCollections {  
  6.       
  7.     public static void main(String args[]) {  
  8.         //注意List是实现Collection接口的  
  9.         List list = new ArrayList();  
  10.         double array[] = { 11211123456231 };  
  11.         for (int i = 0; i < array.length; i++) {  
  12.             list.add(new Double(array[i]));  
  13.         }  
  14.         Collections.sort(list);  
  15.         for (int i = 0; i < array.length; i++) {  
  16.             System.out.println(list.get(i));  
  17.         }  
  18.         // 结果:23.0 111.0 112.0 231.0 456.0  
  19.     }  
  20. }  
 参考来源:http://pengcqu.iteye.com/blog/492196

4、什么时候用assert。 

1.4新增关键字(语法),用于测试boolean表达式状态,可用于调试程序。

使用方法 assert <boolean表达式>,表示如果表达式为真(true),则下面的语句执行,否则抛出AssertionError。

另外的使用方式assert < boolean表达式>:<other表达式>,表示如果表达式为真,后面的表达式忽略,否则后面表达式的值用于AssertionError的构建参数。

注意编译时要增加-source 1.4 参数,否则报错。]运行时要增加 –ea参数,否则assert行被忽略


我通常是在JUNIT中使用来达到单元测试的目的


5、 String s = new String("xyz");创建了几个String Object? 

哈哈,要理解这个,就要知道string类的工作原理。 

你知道在java中除了8中基本类型外,其他的都是类对象以及其引用。所以 "xyz "在java中它是一个String对象.对于string类对象来说他的对象值是不能修改的,也就是具有不变性。 


看: 
String   s= "Hello "; 
s= "Java "; 
String   s1= "Hello "; 
String   s2=new   String( "Hello "); 

啊,s所引用的string对象不是被修改了吗?之前所说的不变性,去那里了啊? 

你别着急,让我告诉你说发生了什么事情: 
在jvm的工作过程中,会创建一片的内存空间专门存入string对象。我们把这片内存空间叫做string池。 

String   s= "Hello ";当jvm看到 "Hello ",在string池创建string对象存储它,并将他的引用返回给s。 
s= "Java ",当jvm看到 "Java ",在string池创建新的string对象存储它,再把新建的string对象的引用返回给s。而原先的 "Hello "仍然在string池内。没有消失,他是不能被修改的。 

所以我们仅仅是改变了s的引用,而没有改变他所引用的对象,因为string对象的值是不能被修改的。 

String   s1= "Hello ";jvm首先在string池内里面看找不找到字符串 "Hello ",找到,返回他的引用给s1,否则,创建新的string对象,放到string池里。这里由于s= "Hello "了,对象已经被引用,所以依据规则s和s1都是引用同一个对象。所以   s==s1将返回true。(==,对于非基本类型,是比较两引用是否引用内存中的同一个对象) 

String   s2=String( "Hello ");jvm首先在string池内里面看找不找到字符串 "Hello ",找到,不做任何事情,否则,创建新的string对象,放到string池里面。由于遇到了new,还会在内存上(不是string池里面)创建string对象存储 "Hello ",并将内存上的(不是string池内的)string对象返回给s2。所以s==s2将返回false,不是引用同一个对象。 

好现在我们看题目: 
String   s   =   new   String( "xyz "); 
首先在string池内找,找到?不创建string对象,否则创建,   这样就一个string对象 
遇到new运算符号了,在内存上创建string对象,并将其返回给s,又一个对象 

所以总共是2个对象 

======================================================================
"xyz "本身作为字符常量,在汇编语言中应该作为常量放在数据段,Java有一个类似数据段的constant   pool保存这个常量,在classloader加载这个类的时候就把 "xyz "和这个类的其他一些信息放在constant   pool 
new   String( "xyz ")根据常量 "xyz "在heap上创建String对象 
s只不过是stack上的一个引用,指向heap上的String对象 
所以,一共两个对象

参考来源http://blog.csdn.net/luo86106/article/details/6104074

测试代码

public class Pointer {
   public static void main(String[] args){
	   String a = "Hello";
	   String b = "Hello";
	   String c = new String("Hello");
	   System.out.println(a==b);
	   System.out.println(a==c);
   }
}


6、 第十,Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 

round返回最接近的数,0.5的的round 都取ceiling,和Math.ceil()的结果等价

Math.round(11.5)==12

Math.round(-11.5)==-11

round方法返回与参数最接近的长整数,参数加1/2后求其floor.

7、 short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 

short s1 = 1; s1 = s1 + 1; (s1+1运算结果是int型,需要强制转换类型)

short s1 = 1; s1 += 1;(+=   不能再 short,int 的情况下使用)

测试代码

public class TestShort {
   public static void main(String[] args){
	   Short s1 =1;
	   s1 = (short) (s1+1);
//	   s1 += 1;
	   int i =1;
	   i +=s1;
   }
}


8、 sleep() 和 wait() 有什么区别? 

sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。

wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

9、数组有没有length()这个方法? String有没有length()这个方法?

数组没有length()这个方法,有length的属性。

String有有length()这个方法。

10、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?
方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写指的是子类自定义实现父类的某个方法,重载指的是提供同名方法在不同参数(顺序,类型)下的实现。

java只能通过方法名+参数(类型和顺序)来区分一个方法,并不能通过返回值的类型来区别方法。


11、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

Set里的元素是不能重复的,Set实现了 Collection的接口,存储的是指向对象的引用,内部元素 不含重复元。Set判断元素是否重复是通过iterator遍历,然后依次调用equals方法来实现的。

equals()     可以被复写,用来完成两个对象是否相等的比较,一般都是通过对象的属性值比较来实现,比如 不同String之间是否相等的比较

==     是比较两个引用指向的对象是否相同

12、error和exception有什么区别?

error 表示预期不可能出现,恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

exception 预期出现,可以被处理或者解决

13、abstract class和interface有什么区别?

1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。

2、抽象类要被子类继承,接口要被类实现。

3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现

4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。

5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。

6、抽象方法只能申明,不能实现。abstract void abc();不能写成abstract void abc(){}。

7、抽象类里可以没有抽象方法

8、如果一个类里有抽象方法,那么这个类只能是抽象类

9、抽象方法要被实现,所以不能是静态的,也不能是私有的。

10、接口可继承接口,并可多继承接口,但类只能单根继承。


14、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?

abstract的method不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系!
    native方法表示该方法要用另外一种依赖平台的编辑语言实现的,不存在者被子类实现的问题,所以,他也不能是抽象的,不能与abstract混用。例 如,FileOutputSteam类要硬件打交道,底层的实现用的是操作系统相关的api实现,例如,在windows用才语言实现的,所以,查看 jdk的源代码,可以发现FileOutputStream的Open方法的定义如下:
    private native void open(String name)throws FlieNotFoundException;
    如果我们要用java调用别人写的C语言函数,我们是无法直接调用的,我们需要按照java的要求写一个C语言的函数,又我们的这个C语言函数去调用别人 的C语言函数。由于我们的C语言行数是按java的要求来写的,我们这个c语言函数就可以与Java对接上,java那边的对接方式就是定义出于我们这个 C函数相对应的方法,java中对应的方法 不需要写具体的代码,但需要在前面声明native。
   关于synchronized中avstract合用的问题,我觉得也不行,因为我觉得 synchronized应该是作用在一个具体的方法上才有意义。而且,方法上的synchronized同步所使用的同步锁对象是this,而抽象方法 上无法确定this是什么。

参考链接http://blog.csdn.net/fhm727/article/details/5222965

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

15、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?

接口可以继承接口。抽象类可以实现(implements)接口,抽象类是可继承实体类,但前提是实体类必须有明确的构造函数

红字部分的说法有问题,具体理解参考http://blog.csdn.net/xuyuxin8145/article/details/6658991


16、是否可以继承String类?

String类是final类故不可以继承。

17、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

不能, synchronized  使用了this关键字 也就是当前对象,通过获取当前对象的对象锁,线程进入同步区,其他线程不能进去该同步区

18、第二十八,编程题: 用最有效率的方法算出2乘以8等於几?

2 << 3(二进制为10左移三位)

位移运算要优于算数运算

19、两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
不对,有相同的hash code。

上面给出的回答是针对符合规范的情况,而在现实情况中可能存在着覆盖了equals方法 却没覆盖hashcode方法的案例,可能导致两者得到的结果不一致

参考文档http://java-min.iteye.com/blog/1416727

20、swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?

switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值