剑指Offer面试题(First day)面试题1、2

面试题1:赋值运算符函数

题目:类型CMyString的声明,为该类型添加赋值运算符函数。 @@

class CMyString{    
	private char m_pData[];
	public CMyString(char pData[]){      //输入的是字符型
	m_pData = pData;
}
	public CMyString(CMyString str){    //输入的是CMyString类的对象
	m_pData = str.m_pData;
}
}
  1. 函数的返回类型必须是一个引用,因为只有返回引用,才可以连续赋值
  2. 注意传入的参数和当前的实例是不是同一个实例,如果是同一个,则不用进行赋值操作,直接返回即可。 注意传入的参数和当前的实例是不是同一个实例,如果是同一个,则不用进行赋值操作,直接返回即可。
public CMyString dengyu(CMyString str){//赋值运算符函数
	if(this == str)   return this;       
	 //自我赋值----------是为了判断传入的参数str与当前实例是否为同一实例。若是,则不再进行赋值操作,直接返回this即可。
	this.m_pData = null;           //将指针初始化为空          
	m_pData = new char[str.m_pData.length];	//设定数组大小为传入的实例str的长度
	for(int i = 0;i < m_p){                     //将每一个字符的数据赋给对应位置
		m_pData[i] = str.m_pData[i];
	}
	return this;     //返回当前实例this 确保返回一个引用
}
public String toString(){          //重写toString()
	StringBuilder result = new StringBuilder("字符串的结果是:");
	for(int i = 0;i < m_pData.length;++i) 
		result.append(m_pData[i]);
	
	return result.toString();	
}
public static void main(String[] args){  //主函数
	String s = "Change before";   //定义两个字符串
	String s1 ="Change after";
	CMyString cms = new CMyString(s.toCharArray());
	CMyString cms1 = new CMyString(s1.toCharArray());
	System.out.println(cms.toString());
	cms.dengyu(cms1);
	System.out.println(cms.toString());
}

面试题2:Singleton(单例)模式

饿汉模式:线程安全、耗费资源 @@@@
只要调用该类,就会实例化对象。有时只需调用此类中的一个方法,不需实例化一个对象,所以饿汉模式比较浪费资源。

class HungerSingletonTest(){
	private static final HungerSingletonTest ourInstance = new HungerSingletonTest();         //初始化对象
	
	public static HungerSingletonTest getInstance(){
		return ourInstance;        //get函数
	}
	private HungerSingletonTest(){    //无参构造函数

	}
}

懒汉模式:非线程安全 @@@@
当有多个进程调用getInstance()方法时,会创建多个实例化对象,所以是非线程安全的

public class Singleton{
	private static Singleton ourInstance;
	
	public static Singleton getInstance(){
		if(ourInstance == null){
			ourInstance = new Singleton();
		}
		return ourInstance;
	}
	private Singleton(){

	}
}

懒汉模式(非线程安全)===> 线程安全

  1. 给方法加锁 @@@
    当多个线程调用getInstance()方法时,一个线程获取了该方法,其他线程必须等待,消耗资源
public class Singleton{	
	private static Singleton ourInstance;
	public synchronized static Singleton getInstance(){
		if(ourInstance == null){
			ourInstance = new Singleton();
		}
		return ourInstance;
	}
	private Singleton(){

	}

}
  1. 双重检查锁(同步代码块) @@@
    双重检查锁:第一次检查为确保之前是个空对象,(若为非空对象,则不需进行同步)空对象的线程进入同步代码块之后,再次进行空对象检查,才能确保只创建一个实例化对象。(若无第二次空对象检查,则多个线程个同时获取同步代码块时,一个线程进入同步代码块,其他线程就会等待,且会创建多个实例化对象)
public class Singleton{	
	private static Singleton ourInstance;
	
	public static Singleton getInstance(){
		if(ourInstance == null){
			synchronized(Singleton.class){
				if(ourInstance == null){
					ourInstance = new Singleton();
				}
			}
		}
	}
	private Singleton(){

	}

}
  • 静态内部类
public class Singleton{	
	private static class SingletonHolder{       //静态内部类   
		private static Singleton ourInstance = new Singleton();
	}
	
	public synchronized static Singleton getInstance(){
		return SingletonHolder.ourInstance;
	}
	private Singleton(){

	}
}
  • 枚举
enum SingletonTest{
	INSTANCE;
	public void whateverMethod(){

	}
}

补充几点小知识:

  • Person person; //对象引用
    person = new Person(“王二”); //“王二”对象

  • == 比较两个对象引用是否指向同一个对象地址。

  • 类成员变量 + 实例成员变量
    public class Person{
    private String name;
    static int age;

    }
    Person person = new Person(“王二”,19);
    类成员变量---- Person.age;
    实例成员变量---- person.age;

  • 在编写Java的完整程序时,entity包中getXXX(),setXXX()【Java中有generate getters和setters方法】是为了访问类中的私有变量,确保数据的安全性、隐私,管理起来更加方便。

猜你喜欢

转载自blog.csdn.net/weixin_43137176/article/details/88181733