声明

本文翻译自: http://www.roytuts.com/core-java-interview-questions-and-answers/

1. java thread对象可以掉用start 方法两次吗

  1. 不可以,当连续调用start方法时,会抛出一个异常 – java.lang.IllegalThreadStateException
  2. 参考下面例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.walterlife.blog;

public class ThreadInvokeStartTwice extends Thread {

@Override
public void run() {
// TODO Auto-generated method stub
System.out.print("Thread runing" + Thread.activeCount());
}

public static void main(String[] args) {
ThreadInvokeStartTwice thread = new ThreadInvokeStartTwice();
thread.start();
thread.start();
}
}
// output
Thread runing2Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at com.walterlife.blog.ThreadInvokeStartTwice.main(ThreadInvokeStartTwice.java:14)

2. collection 与 collections 的区别

collection

  1. 这是个接口. 一个 collection 包含了一组对象,这些对象有的collection 允许是重复的[List],有的允许不能重复的[Set],
    有的是有序的[插入顺序和在collection中的位置是一致的,而不是排序过的],有的是无序的。
  2. JDK中并没有直接的实现该接口,而是提过了一些子接口[List, Set]等
  3. http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html 可以阅读更多相关信息

collections

  • 这是个类,该类包含了许多静态函数,用来处理或者返回collection 类。
  • 同时包含了很多有用的函数,比如sort, addAll, copy 等[个人觉得该类和c++ 中 STL中的algorithm.h类似]

3. ArrayList 怎么定位一个元素

  • ArrayList 中的 indexOf 和 contains 是大小写敏感的

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package com.walterlife.blog;

import java.util.ArrayList;
import java.util.List;

class InsensitiveSearch {
private List<String> searchColl;

public InsensitiveSearch(List search) {
this.searchColl = search;
}

public boolean contains(String str) {
for (String s : searchColl) {
if (str.equalsIgnoreCase(s)) {
return true;
}
}
return false;
}

public int indexOf(String str) {
for (int index = 0; index < searchColl.size(); index++) {
if (str.equalsIgnoreCase(searchColl.get(index))) {
return index;
}
}
return -1;
}
}

public class SearchInArrayList {

public static void main(String[] args) {

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");

boolean found = list.contains("a");
System.out.println("element a : " + (found ? "found" : "not found"));

found = list.contains("B");
System.out.println("element B : " + (found ? "found" : "not found"));

int index = list.indexOf("c");
System.out.println("element c : " + (index <= 0 ? "not found" : "found"));

index = list.indexOf("C");
System.out.println("element C : " + (index <= 0 ? "not found" : "found"));

InsensitiveSearch test = new InsensitiveSearch(list);

found = test.contains("a");
System.out.println("element : " + (found ? "found" : "not found"));

found = test.contains("B");
System.out.println("element B : " + (found ? "found" : "not found"));

found = test.contains("c");
System.out.println("element c : " + (found ? "found" : "not found"));

found = test.contains("C");
System.out.println("element C : " + (found ? "found" : "not found"));

}
}

输出

1
2
3
4
5
6
7
8
element a : not found
element B : found
element c : not found
element C : found
element a : found
element B : found
element c : found
element C : found

4. String, StringBuffer, StringBuilder 的区别

String

  • String 是一个不可变的类,一旦创建,其值就不能被改变
  • String 是线程安全的,因为他是不可变的,多线程不可能同时修改其值
  • String 对象的内存是存储在常量池
  • 如果对同一个String 对象重复赋值,则重新赋值前对象的引用将找不到了,但是其内存不能被马上释放掉

StringBuffer

  • StringBuffer 是可变的,其值是可以改变的
  • StringBuffer 是线程安全的,其内部实现了同步访问元素的方法,所以多线程是可以同时访问的,但是在一个cpu时间片内值允许一个线程访问[CPU是串行的]
  • 因为其实线程安全的[锁机制],故其在性能上不及StringBuffer
  • StringBuffer 对象的内存是存储在heap上
  • 可以通过toString 将值转为String

StringBuilder

  • StringBuilder 是可变的,其值是可以改变的
  • StringBuffer 是线程不安全的,其内部没有实现同步访问元素的方法,所以多线程是不可以同时访问的
  • 因为其实线程不安全的,故其在性能上比StringBuffer 更快
  • StringBuffer 对象的内存是存储在heap上
  • 可以通过toString 将值转为String

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.roytuts.java.string;

public class StringStringBufferStringBuilder {

public static void main(String[] args) {
String s = "Hello, World!";
System.out.println(s);
s = "Welcome to Hello World!";
System.out.println(s); // we lost reference to "Hello, World!"
System.out.println();

StringBuffer stringBuffer = new StringBuffer("Hello, World!");
System.out.println(stringBuffer);
System.out.println(stringBuffer.toString()); // convert to String object
stringBuffer = new StringBuffer("Welcome to Hello World!");
System.out.println(stringBuffer);
System.out.println();

StringBuilder stringBuilder = new StringBuilder("Hello, World!");
System.out.println(stringBuilder);
System.out.println(stringBuilder.toString()); // convert to String
// object
stringBuilder = new StringBuilder("Welcome to Hello World!");
System.out.println(stringBuilder);
}

}

输出

1
2
3
4
5
6
7
8
9
10
Hello, World!
Welcome to Hello World!

Hello, World!
Hello, World!
Welcome to Hello World!

Hello, World!
Hello, World!
Welcome to Hello World!

5. ClassNotFoundException 和 NoClassDefinitionFoundException的区别

ClassNotFoundException

  • 抛出异常的情况: 当应用程序通过类名来加载类的时候,使用的方法如下:
  • forName 在 Class 类中
  • findSystemClass 在 ClassLoader 类中
  • loadClass 在 ClassLoader 类中
  • 如果应用程序没有定义指定类名的类时,就会抛出该异常
  • 当使用反射机制来调用该类相关接口时,而该类区不存在时,也会抛出ClassNotFoundException 异常
  • 另外该异常是checked 异常,故在程序中要捕获该异常或者抛出
  • 例子
1
2
3
4
5
6
7
8
9
10
11
12
package com.roytuts.classexception;

public class ClassNotFoundExceptionTest {

public static void main(String[] args) {
try {
Class.forName("ClassA"); // ClassA 没有定义
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
  • 输出
1
2
3
4
5
6
7
8
9
10
11
    java.lang.ClassNotFoundException: ClassA
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at CoreJavaLearn.ClassNotFoundExceptionTest.main(ClassNotFoundExceptionTest.java:8)

NoClassDefinitionFoundException

  • 当在jvm中,或者使用ClassLoader实例来加载雷时,但是该类的定义却不存在,此时会抛出该异常
  • 而在编译期间,要加载的类的类定义是存在的
  • 所以只有在代码成功编译了,但是在部署时没有将需要的jar‘文件全部包含,才会抛出此异常
  • 例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import javax.jms.ConnectionFactory;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class NoClassDefinitionFoundExceptionTest {

public static void main(String[] args) {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_BROKER_URL);
}
}
```

+ 输出

```java
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
ConnectionFactory cannot be resolved to a type
ActiveMQConnectionFactory cannot be resolved to a type
ActiveMQConnection cannot be resolved to a variable
at com.roytuts.classexception.NoClassDefinitionFoundExceptionTest.main(NoClassDefinitionFoundExceptionTest.java.11

6. 什么是class loaders

7. 当异常处理完后,异常对象内存什么时候回收

  • 会在下一次垃圾回收时回收掉

8. equals 与 hashCode 的联系

  • 当 object 类重写了equals 时,就必须同时重写 hashCode
  • 当两个对象 hashcode相同时,并不代表两个对象的值就一定相等
  • 所以在设计hashCode方法时,我们有必要保证两个不同的对象的hashCode 也不同,这样可以提升hash tables的性能[查找性能]
  • 要保证每次调用hashCode 的值是相同的
  • 个人认为这个可以参考c++ 中 hashtable 内部实现机制来理解

9. 使用 HashMap 需要注意什么?

  • HashMap 不允许key值重复,但是value值可以重复
  • key值和value 值都可以为 null

10. 列出 Object 类中常用的方法

  • getClass() – 返回运行时对象的类型
  • hashCode() – 返回对象的hash值
  • equals() – 辨明对象是否和其他对象相等
  • clone() – 返回对象的副本
  • toString() – 将对象的值转为字符串
  • notify() – 唤醒在某个正在等待某个资源可用的线程
  • notifyAll() – 唤醒在所有正在等待某个资源可用的线程
  • wait() – 使当前线程处于Waiting 状态,直到另外一个线程调用 notify 或者 notifyAll 来唤醒该线程,或者该线程被另外一个线程中断了,或者运行超时了
  • finalize() – 由jvm判定该对象已经没有任何引用后回收时调用

11. 可以重写 static 方法吗?

12. 怎样防止方法被重写

1
2
3
// 使用final 关键字修饰函数即可
public void final funcname () {
}

13. 在接口中可以有 static 方法吗?

14. transient 变量

15. 抽象类和抽象方法的区别

  • 抽象类不能实例化,在类名前有 abstract 关键字修饰
1
2
public class abstract AbstractClass{
}
  • 抽象方法不需要实现,方法名前有 abstract 修饰
1
2
public abstract void AbstractMethod(){
}
  • 抽象可以不需要包含抽象方法

16. Boolean 的 默认值

  • false

ArrayList 和 LinkedList 的区别和使用

17. java中每个线程都有独立的栈区域吗

  • 是的,这是运行时栈,但共享同一块内存域

18. java获取当前时间时间戳

1
System.currentTimeMills()   //可用于性能测试中

留言