锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

[金三银四面试季]Java面向对象高频面试题

时间:2022-11-16 14:00:00 荧光法溶解氧传感器oos61

在这里插入图片描述??金三银四是跳槽加薪的好时机。波哥为大家整理了很多高频面试问题,帮助大家找到更好的工作。关注一下,谢谢你的支持。

面对面试题

1.谈谈你对面向对象思想的理解

面向过程编程(POP):以过程为中心的编程理念

面向对象编程(OOP):与面向过程相比,面向对象方法将相关数据和方法组织成一个整体,从更高的层次进行系统建模,更接近事物的自然运行模式

2. 谈谈你对面向对象特征的理解

封装

包裹对象的属性和方法, 访问只能通过约定的接口实现

在java通过关键字private实现封装。

package com.bobo.interview0001.domain;  /** * 属性 方法 */ public class User { 
             // 将age设置为私有属性     private int age;      public String name;      /** * 为外部设置提供age属性的方法 * @param age */     public void setAge(int age){ 
                 if(age < 0 || age > 120){ 
                     System.out.println("age设置不合法!");             age = 0;         }         this.age = age;     }      /** * 为外界提供获取age属性的方法 * @return */     public int getAge(){ 
                 return age;     }   }  

??包装的好处:可以将私有数据与公共数据分离,保护私有数据,提高程序安全性!

继承

??继承是面向对象最显著的特征之一。继承是从现有类别中衍生出新类别。新类别可以吸收现有类别的数据属性和行为,扩展新能力。
为什么要继承:

  1. 反映现实的真实关系

  2. 减少代码冗余

  3. 扩展和重写父类的属性和方法

??在继承过程中,子类不能选择性地继承父类的东西,而是继承父类的所有属性和方法。父类也被称为超级或基本类,子类也被称为衍生物。父类是子类的一般化,子类是父类的特殊化(具体化)。java中不支持多继承,一个类最多只能有一个父类。而在java通过接口实现中多继承。

public class Person { 
             private String userName;     private int age;      private String sex;     private String address;     private String idCard;      public void showspan class="token punctuation">(){ 
        
        System.out.println("父类中的方法");
    }
}
public class Doctor extends Person{ 
        
    @Override
    public void show() { 
        
        System.out.println("Doctor ... show");
    }
}
public class Student  extends Person{ 
        
    private String ClassNum;
    private String stuNo;
    // ....
    public void learn(){ 
        

    }

    @Override
    public void show() { 
        
        System.out.println("Student ... show");
    }
}

多态

  Java对象的多种状态,多态主要是基于继承和重写,最终可以实现相同的类型调用相同的方法,结果不相同

    public static void main(String[] args) { 
        
        // 多态的体现
        Person p1 = new Student();
        p1.show();
        Person p2 = new Doctor();
        p2.show();
    }

3.介绍下访问权限修饰符

修饰符 当前类 同 包 子 类 其他包
public
protected ×
default × ×
private × × ×

  重点注意protected和default,protected相比较default多了一个不同包下面的子类可见

4. String是基本数据类型吗?

Java中的8个基本数据类型:

  • byte
  • short
  • int
  • long
  • float
  • double
  • char
  • boolean

  String类型显然不在8个基本数据类型之中,String类型是我们讲的引用类型

5. float f=6.6这样写是否正确?

  不正确的,6.6默认是双精度类型,将double类型赋值给float类型,属性向下转型,会造成精度丢失

public class Demo01 { 
        

    public static void main(String[] args) { 
        
        // 小数 默认的是 double类型 双精度类型 向下转型 精度丢失
        float f2 = 1.1;
        float f = 6.6F;
        float f1 = 7.7F;
    }
}

6 程序题1

short s1 = 1; 
s1 = s1 + 1; // 此处需要强制类型转换

有错吗? – 有错

short s1 = 1; 
s1 += 1; // s1 = (short) ( s1 + 1 )

有错吗?-- 没有错

7. 程序题2

​ 以下程序的输出结果是:

    public static void main(String[] args) { 
        
        Integer f1=100,f2=100,f3=150,f4=150;
        System.out.println(f1==f2);
        System.out.println(f3==f4);
    }

输出结果:true,false

原因解释:

IntegerCache中的定义

    private static class IntegerCache { 
        
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static { 
        
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) { 
        
                try { 
        
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) { 
        
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
			// 创建了一个缓存的数组 长度256
            cache = new Integer[(high - low) + 1];
            int j = low;
            // 循环256次
            for(int k = 0; k < cache.length; k++)
                // 一次创建 -128 到 127 对应的Integer对象,并保存到数组中
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() { 
        }
    }

valueOf(int)中的源码

    public static Integer valueOf(int i) { 
        
        // 如果 i 在 -128 到 127之间
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            // 就从缓存的数组中返回之前创建的 Integer对象
            return IntegerCache.cache[i + (-IntegerCache.low)];
        // 否则创建一个新的Integer对象
        return new Integer(i);
    }

  提醒:越是貌似简单的面试题,其中的玄机就越多,要求面试者需要相对深厚的功力。

8. &和&&的区别

&:按位与

int a = 5;   // 101
int b = 3;   // 011
int c = a & b;// 001

  逻辑与:都为true结果才为true,左边如果为false,右边表达式还是会运行

  &&:短路与:都为true结果才为true,左边如果为false,右边表达式不会运行

    public static void main(String[] args) { 
        
        int a = 5;   // 101
        int b = 3;   // 011
        int c = a & b;// 001
        System.out.println("c = " + c);
        // 逻辑与 & 左右两边都为true 那么结果才为true
        // 左边为false,结果为false,但是右边的表达式还是会进行运算
        if(a == 0 & a ++ > 0){ 
        
            System.out.println("------");
        }
        System.out.println("a = " + a);
        // && 短路与 左边如果为false,那么整体的结果也为false,而且右边的表达式不会运算
        if(a == 0 && a ++ > 0){ 
        
            System.out.println("------");
        }
        System.out.println("a = " + a);
        String name = null;
        // 短路与在实际使用的时候还是很有使用场景的
        if(name != null & !name.equals("")){ 
        

        }
    }
}

9. switch可以使用的数据类型

JDK5之前:byte,short,int,char

JDK5之后:Java中引入了枚举类型,枚举类型也可以

JDK7之后:可以使用String,但是long类型一直是不可以的

10. 用最有效的方法计算2乘以8?

  2 << 3(左移3位,相当于乘以2的3次方)

11. 构造器是否可以被重写?

  构造器不能被继承,因此是不能被重写的,但是我们可以重载构造器

12. 是否可以继承String类?

  String类是final类型,所以不可以被继承。

13. 重载和重写的区别

  方法的重载和重写都是实现多态的方式, 区别在于前者实现的是编译时的多态性, 而后者实现的是运行时的多态性。

  重载:在同一个类中,同名的方法如果有不同的参数列表(参数类型,参数个数,顺序)视为重载

package com.bobo.interview0006;

public class Demo01 { 
        
    public static void main(String[] args) { 
        
        A a = new A();
        a.show1();
        a.show1(18);
        a.show1("a",18);
        a.show1(18,"aaa");
    }
}

class A{ 
        

    /** * 方法的重载:在同一个类中 方法名称相同 参数列表不同 */
    public void show1(){ 
        

    }

    public void show1(String name){ 
        

    }

    public void show1(int a){ 
        

    }
    public void show1(String name,int a){ 
        

    }

    public void show1(int a,String name){ 
        

    }
}

  重写:发生在父子关系类中,子类重写父类的方法,有相同的返回类型或子类

class B extends A{ 
        

    /** * 重写,子类重写父类中的方法 */
    @Override
    public void show1() { 
        
        // super.show1();
        System.out.println("show1 --- B");
    }

    /** * 重写的返回类型必须相同或者是父类返回类型的子类 * @param n * @return */
    @Override
    public Integer fun1(Number n) { 
        
        return 666;
    }
}

14. 抽象类和接口的区别

  1. 接口和抽象类都不能实例化
  2. 抽象类相比于普通类多的限制是可以添加抽象方法
  3. 接口中只能声明常量和抽象方法且访问修饰符必须都为public,在JDK8之后可以定义default方法和static方法
package com.bobo.interview0007;

public class Demo01 { 
        
    public static void main(String[] args) { 
        

    }
}

/** * 抽象类 * 不能被实例化 * 可以声明普通的属性和方法 * 还可以定义抽象方法 */
abstract class A{ 
        

    private int a;
    public int b;


    public void fun1(){ 
        

    }
    public abstract  void fun2();

}

/** * 接口 * 不能被实例化 * 属性只能是常量 * 方法只能是抽象方法 * JDK1.8之后可以有 default和static方法 */
interface B{ 
        
     public final  int a = 9;
     // public abstract 方法默认的类型 可以不添加
     public abstract void show1();

    /** * default方法 */
    public default void fun1(){ 
        

     }

    /** * 静态方法 */
    public static void fun2(){ 
        

     }
}

15. 静态内部类和内部类的区别

  静态内部类是被声明为static的内部类,它可以不依赖外部类的实例被实例化,而通常我们的内部类是需要通过外部类的实例才能实例化。

public class OutterClass { 
        

    /** * 普通内部类 */
    class InnerClass{ 
        
        public void show(){ 
        
            System.out.println("InnerClass ...");
        }
    }

    /** * 静态内部类 */
    static class StaticInnerClass{ 
        
        public void show(){ 
        
            System.out.println("StaticInnerClass ...");
        }
    }
}

测试代码

    public static void main(String[] args) { 
        
        // 获取普通内部类对象
        OutterClass.InnerClass innerClass = new OutterClass().new InnerClass();
        innerClass.show();
        // 获取静态内部类对象
        OutterClass.StaticInnerClass staticInnerClass = new OutterClass.StaticInnerClass();
        staticInnerClass.show();
    }

16. 抽象方法是否可以同时是静态的本地方法及被synchronized修饰?

  抽象方法所在的类肯定是抽象类,

  1. 不能被static修饰,因为静态不能被重写,而抽象方法必须要被子类重写,所以矛盾。

  2. 不能被native修饰,本地方法是由C代码实现的,而抽象方法没有实现,也是矛盾的

  3. 不能被synchronized修饰,同步是和方法的实现的细节有关系的,而抽象方法没有具体的实现,也是相互矛盾的

17. 静态变量和实例变量的区别

静态变量:是被static所修饰的变量,也称为类变量,它是属性类对象的,不属于类的任何一个对象。静态变量是对象间共享的

实例变量:数据具体的某个对象,必须要先创建对象,然后通过该对象来访问实例变量,

18.静态方法中是否可以访问普通方法

  肯定不可以,静态方法是在类加载阶段就创建的,而普通方法是属性对象的,在类加载阶段还没有对象,所以是矛盾的,静态方法只能访问静态成员,普通方法必须要先创建对象,然后通过对象来调用普通方法。

public class Person { 
        

    static void show(){ 
        
        // 静态方法中不可以调用 普通方法
       // speak();
    }

    void speak(){ 
        
        // 普通方法可以调用静态方法
        show();
    }
}

19.如何实现克隆

原型模式 说明
浅克隆 只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝, 还是指向原生对象的内部元素地址
深度克隆 深复制把要复制的对象所引用的对象都复制了一遍
package com.dpb.prototype;

import java.io.Serializable;
import java.util.Date;

/** * 原型类:被克隆的类型 * @author dengp * */
public class User implements Cloneable,Serializable{ 
        
	
	private String name;
	
	private Date birth;
	
	private int age;

	public String getName() { 
        
		return name;
	}

	public void setName(String name) { 
        
		this.name = name;
	}

	public Date getBirth() { 
        
		return birth;
	}

	public void setBirth(Date birth) { 
        
		this.birth = birth;
	}

	public int getAge() { 
        
		return age;
	}

	public void setAge(int age) { 
        
		this.age = age;
	}
	
	/** * 实现克隆的方法 */
	public Object clone() throws CloneNotSupportedException{ 
        
		return super.clone();
	}
}

深度克隆

package com.dpb.prototype;

import java.io.Serializable;
import java.util.Date;

/** * 原型类:被克隆的类型 * 深度克隆测试 * @author dengp * */
public class User2 implements Cloneable,Serializable{ 
        
	
	private String name;
	
	private Date birth;
	
	private int age;

	public String getName() { 
        
		return name;
	}

	public void setName(String name) { 
        
		this.name = name;
	}

	public Date getBirth() { 
        
		return birth;
	}

	public void setBirth(Date birth) { 
        
		this.birth = birth;
	}

	public int getAge() { 
        
		return age;
	}

	public void setAge(int age) { 
        
		this.age = age;
	}
	
	/** * 实现克隆的方法 * 深度克隆(deep clone) */
	public Object clone() throws CloneNotSupportedException{ 
        
		Object object = super.clone();
		// 实现深度克隆(deep clone)
		User2 user = (User2)object;
		user.birth = (Date) this.birth.clone();
		return object;
	}
}

序列化和反序列化

public static void main(String[] args) throws CloneNotSupportedException, Exception { 
        
	Date date =  new Date(1231231231231l);
	User user = new User();
	user.setName("波波烤鸭");
	user.setAge(18);
	user.setBirth(date);
	System.out.println("-----原型对象的属性------");
	System.out.println(user);
	System.out.println(user.getName());
	System.out.println(user.getBirth());
	
	//使用序列化和反序列化实现深复制
	ByteArrayOutputStream bos = new ByteArrayOutputStream();
	ObjectOutputStream    oos = new 元器件数据手册IC替代型号,打造电子元器件IC百科大全!
          

相关文章