面试题1 -- 赋值运算符函数
题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数。
自定义了一种字符串类,实现字符串的拷贝。其中关键点在于涉及到C++的内存回收与申请的顺序问题,Java由于内存回收通过JVM自动处理,不会有相关问题,此题忽略。
面试题2 -- 实现Singleton模式
题目:设计一个类,我们只能生成该类的一个实例。
单例模式实现代码少,是面试过程中常见的考察设计模式功底的题目。
不好的解法一:只适用于单线程环境
public class Singleton1 {
private Singleton1(){}
private static Singleton1 instance = null;
/**
* 线程不安全
*/
public static Singleton1 getInstance() {
if (instance == null) {
instance = new Singleton1();
}
return instance;
}
}
不好的解法二:虽然在多线程环境中能工作,但效率不高
在Java的实现中,需要将instance增加volatile修饰,防止在 instance = new Singleton3() 这行的执行过程中new与=的执行顺序被JMM优化打乱。
public class Singleton2 {
private Singleton2() { }
private static volatile Singleton2 instance = null;
/**
* 低效率
*/
public static Singleton2 getInstance() {
synchronized (Singleton2.class) {
if (instance == null) {
instance = new Singleton2();
}
return instance;
}
}
}
可行的解法:加同步锁前后两次判断实例是否已存在
此方法即Double-Check-Lock,与书中不同的是,在Java的实现中,需要将instance增加volatile修饰,防止在 instance = new Singleton3() 这行的执行过程中new与=的执行顺序被JMM优化打乱。
public class Singleton3 {
private Singleton3(){}
private static volatile Singleton3 instance = null;
/**
* Double check lock
*/
public static Singleton3 getInstance() {
if (instance == null) {
synchronized (Singleton3.class) {
if (instance == null) {
instance = new Singleton3();
}
}
}
return instance;
}
}
强烈推荐的解法一:利用静态构造函数
即饿汉模式。
public class Singleton4 {
private Singleton4(){}
private static Singleton4 instance = new Singleton4();
public static Singleton4 getInstance() {
return instance;
}
}
强烈推荐的解法二:实现按需创建实例
也是Java版最推荐的懒汉模式单例模式的实现方式,通过JVM类加载的内置同步性保证线程安全,只有在调用 getInstance 方法的时候才会加载Nested内部类,实现懒加载。
public class Singleton5 {
private Singleton5(){}
private static Singleton5 getInstance() {
return Nested.instance;
}
private static class Nested {
Nested() { }
private static Singleton5 instance = new Singleton5();
}
}