面试题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;
}
}
- 函数的返回类型必须是一个引用,因为只有返回引用,才可以连续赋值
- 注意传入的参数和当前的实例是不是同一个实例,如果是同一个,则不用进行赋值操作,直接返回即可。 注意传入的参数和当前的实例是不是同一个实例,如果是同一个,则不用进行赋值操作,直接返回即可。
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(){
}
}
懒汉模式(非线程安全)===> 线程安全
- 给方法加锁 @@@
当多个线程调用getInstance()方法时,一个线程获取了该方法,其他线程必须等待,消耗资源
public class Singleton{
private static Singleton ourInstance;
public synchronized static Singleton getInstance(){
if(ourInstance == null){
ourInstance = new Singleton();
}
return ourInstance;
}
private Singleton(){
}
}
- 双重检查锁(同步代码块) @@@
双重检查锁:第一次检查为确保之前是个空对象,(若为非空对象,则不需进行同步)空对象的线程进入同步代码块之后,再次进行空对象检查,才能确保只创建一个实例化对象。(若无第二次空对象检查,则多个线程个同时获取同步代码块时,一个线程进入同步代码块,其他线程就会等待,且会创建多个实例化对象)
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方法】是为了访问类中的私有变量,确保数据的安全性、隐私,管理起来更加方便。