目录
2、String s = "Hello"; s = s + " world!";这两行代码执行后,原始的String 对象中的内容到底变了没有?
4、String s = new String("xyz");创建了几个 String Object? 二者之间有什么区别? xyz 是字面量
6、try {}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会不会被执行,什么时候被执行,在 return 前还是后?
7、final, finally, finalize 的区别
String
1、String 是最基本的数据类型吗?
基本数据类型包括 :
byte、int、char、long、float、double、boolean 和 short
2、String s = "Hello"; s = s + " world!";这两行代码执行后,原始的String 对象中的内容到底变了没有?
没有。因为 String 被设计成不可变(immutable)类,s 原先指向一个 String 对象,内容是 "Hello",然后我们对 s 进行了+操作这时,s 不指向原来那个对象了,而指向了另一个 String 对象,内容为"Hello world!"
package com.yx.test;
public class Test {
public static void main(String[] args) {
String s = "hello ";
s = s + "world!";
System.out.println(s);
}
}
3、是否可以继承 String 类?
String 类是 final 类故不可以继承
4、String s = new String("xyz");创建了几个 String Object? 二者之间有什么区别? xyz 是字面量
两个,一个放在常量区,不管写多少遍,都是同一个。 New String 每写一遍,就创建一个新
5、String 和 StringBuffer 的区别
StringBuffer ,它们可以储存和操作字符串,即包含多个字符的字符数据这个 String 类提供了数值不可改变的字符串。而这个 StringBuffer 类提供的字符串进行修改
异常
6、try {}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会不会被执行,什么时候被执行,在 return 前还是后?
package com.yx.test;
@SuppressWarnings("all")
public class Test {
public static void main(String[] args) {
System.out.println(new Test().test());
}
static int test() { int x = 1;
try {
return x;//产生中断 保存断点 压栈 x=1
}finally {
System.out.println("finally="+(++x));//接着恢复断点 弹栈 x=1 }
}
}
}
结果:
7、final, finally, finalize 的区别
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。内部类要访问局部变量,局部变量必须定义成 final 类型finally 是异常处理语句结构的一部分,表示总是执行// 析构函数finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 JVM 不保证此方法总被调用
8、运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
普通异常:
运行时异常:
9、error 和 exception 有什么区别?
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
10、最常见到的 runtime exception。
列如:
ArithmeticException BufferUnderflowException ClassCastExceptionArrayStoreException CannotRedoException ConcurrentModificationExceptionBufferOverflowException CannotUndoException CMMException........
线程
11、sleep() 和 wait() 有什么区别?
sleep:
sleep 是线程类 Thread 的方法,此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用 sleep 不会释放对象锁
wait:
wait 是 Object 类的方法, 对此对象调用 wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出 notify 方法(或 notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
12、同步和异步有何异同,在什么情况下分别使用他们?
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率
13、当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其它方法?
分几种情况:1. 其他方法前是否加了 synchronized 关键字,如果没加,则能2. 如果这个方法内部调用了 wait ,则可以进入其他 synchronized 方法3. 如果其他个方法都加了 synchronized 关键字,并且内部没有调用 wait ,则不能
14、多线程有几种实现方法?同步有几种实现方法?
多线程有两种实现方法,分别是继承 Thread 类与实现 Runnable 接口同步的实现方面有两种,分别是 synchronized , wait 与 notify wait() : 使一个线程处于等待状态,并且释放所持有的对象的 lock 。sleep() : 使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉 InterruptedException 异常。notify() : 唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且不是按优先级。Allnotity() : 唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争
15、启动一个线程是用 run()还是 start()?
启动一个线程是调用 start() 方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码, run()方法是该线程所关联的执行代码。
16、线程的基本概念、线程的基本状态以及状态之间的关系
Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态
状态名称 | 说明 |
new | 初始状态,线程被构建,但是没有调用start()方法 |
runnable | 运行时,java线程将操作系统中的就绪和运行两种状态,称作“运行中” |
blocked | 阻塞状态,表示线程塞于锁 |
waiting | 等待状态,线程进入等待,需要等待其他线程做出一些特定动作(通知或中断) |
time_waiting | 超时等待状态,该状态不同于waiting,它是可以在指定的时间自行返回的 |
terminated | 终止状态,表示当前线程已经执行完毕 |
线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。 Java 线程状态变迁如下图所示:
17、简述 synchronized 和 java.util.concurrent.locks.Lock 的异同 ?
主要相同点: Lock 能完成 synchronized 所实现的所有功能主要不同点: Lock 有比 synchronized 更精确的线程语义和更好的性能。 synchronized 会自动释放锁,而 Lock 一定要求程序员手工释放,并且必须在 finally 从句中释放。 Lock 还有更强大的功能,例如,它的 tryLock 方法可以非阻塞方式去拿锁。举例说明(对下面的题用 lock 进行了改写):
package com.yx.test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest {
private int j;
private Lock lock = new ReentrantLock();
public static void main(String[] args) {
ThreadTest threadtest = new ThreadTest();
for (int i = 0; i < 2; i++) {
new Thread(threadtest.new adder()).start();
new Thread(threadtest.new subtractor()).start();
}
}
private class subtractor implements Runnable{
@Override
public void run() {
while(true) {
lock.lock();
try {
System.out.println("j--="+j--);
} finally {
lock.unlock();
}
}
}
}
private class adder implements Runnable{
@Override
public void run() {
while(true) {
lock.lock();
try {
System.out.println("j++="+j++);
} finally {
lock.unlock();
}
}
}
}
}
18、设计 4 个线程,其中两个线程每次对 j 增加 1,另外两个线程对 j 每次减少 1。写出程序。
以下程序使用内部类实现线程,对 j 增减的时候没有考虑顺序问题
package com.yx.test;
public class ThreadTest1 {
private int j;
public static void main(String[] args) {
ThreadTest1 threadtest =new ThreadTest1();
Inc inc=threadtest.new Inc();
Dec dec=threadtest.new Dec();
for (int i = 0; i < 2; i++) {
Thread thread=new Thread(inc);
thread.start();
thread = new Thread(dec);
thread.start();
}
}
private synchronized void inc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
}
private synchronized void dec(){
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
class Inc implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
inc();
}
}
}
class Dec implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
dec();
}
}
}
}
集合
19、ArrayList 和 LinkedList 的区别
ArrayList 和 LinkedList 在性能上各有优缺点,都有各自所适用的地方,总的说来可以描述如下:
1 .对 ArrayList 和 LinkedList 而言,在列表末尾增加一个元素所花的开销都是固定的。对 ArrayList 而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对 LinkedList 而言,这个开销是统一的,分配一个内部 Entry 对象。2 .在 ArrayList 的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在 LinkedList 的中间插入或删除一个元素的开销是固定的。3 . LinkedList 不支持高效的随机元素访问。4 . ArrayList 的空间浪费主要体现在在 list 列表的结尾预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗相当的空间可以这样说:当操作是在一列数据的后面添加数据而不是在前面或中间 , 并且需要随机地访问其中的元素时 , 使用 ArrayList 会提供比较好的性能;当你的操作是在一列数据的前面或中间添加或删除数据 , 并且按照顺序访问其中的元素时 , 就应该使用 LinkedList 了
20、HashMap 和 Hashtable 的区别
HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口主要区别在于 HashMap 允许空(null)键值(key), 由于非线程安全,在只有一个线程访问的情况下,效率要高于 Hashtable
HashMap 允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
就 HashMap 与 HashTable 主要从三方面来说如下:
一. 历史原因 :Hashtable 是基于陈旧的 Dictionary 类的, HashMap 是 Java 1.2 引进的 Map 接口的一个实现
二.同步性:Hashtable 是线程安全的,也就是说是同步的,而 HashMap 是线程序不安全的,不是同步的
三.值:只有 HashMap 可以让你将空值作为一个表的条目的 key 或 value
21、List, Set, Map 是否继承自 Collection 接口?
List , Set 是, Map 不是
22、List、Map、Set 三个接口,存取元素时,各有什么特点?
List 以特定次序来持有元素,可有重复元素。 Set 无法拥有重复元素 , 内部排序。 Map 保存 key-value 值, value 可多值。
23、去掉一个 List 集合中重复的元素
package com.yx.test;
import java.util.ArrayList;
import java.util.List;
public class Dome {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add(new Student("zs", 16));
list.add(new Student("ls", 18));
list.add(new Student("ww", 17));
if (!list.contains(new Student("ls", 18))) {
list.add(new Student("ls", 18));
}
for (Object object : list) {
System.out.println(object);
}
}
}
class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if(obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if(age != other.age)
return false;
if(name == null) {
if (other.name != null)
return false;
}else if (!name.equals(other.name))
return false;
return true;
}
}
24、Collection 和 Collections 的区别。
Collection 是集合类的上级接口,继承与他的接口主要有 Set 和 List.Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。
25、Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
Set 里的元素是不能重复的,元素重复与否是使用 equals() 方法进行判断的。equals() 和 == 方法决定引用值是否指向同一对象 equals() 在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
26、两个对象值相同(x.equals(y) == true),但却可有不同的 hash code,这句话对不对?
答案为:对如果对象要保存在 HashSet 或 HashMap 中,它们的 equals 相等,那么,它们的 hashcode 值就必须相等。如果不是要保存在 HashSet 或 HashMap ,则与 hashcode 没有什么关系了,这时候h ashcode 不等是可以的,例如 arrayList 存储的对象就不用实现 hashcode ,当然,我们没有理由不实现,通常都会去实现的。
27、java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
字节流,字符流。字节流继承于 InputStream OutputStream ,字符流继承于 Reader , Writer 。在 java.io 包中还有许多其他的流,主要是为了提高性能和使用方便
28、什么是 java 序列化,如何实现 java 序列化?
我们有时候将一个 java 对象变成字节流的形式传出去或者从一个字节流中恢复成一个 java 对象,例如,要将 java 对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个 java 对象变成某个格式的字节流再传输,但是,jre 本身就提供了