java基础面试集锦

1. java跨平台原理

扩展名.java --> 扩展名.class --jvm虚拟机–> 适合系统的字节编码 --> 编译执行

2. jvm jdk jre

jvm:虚拟机,实现java跨平台以及编译运行的核心
jdk: java开发工具包
jre: java运行环境
三者关系:jdk开发工具包中包括jre运行环境,如果只是运行java代码的话,只需要jre运行环境即可。jre和jdk中都包含jvm的一些部分,而jvm虚拟机中包含许多类解析器和加载器

3. 基本类型

基本类型(字节数)
 byte (1)
 short(2)
 int(4)
 long(8)
 float(4)
 double(8)
 boolean(1)
 char(2)

4. 基本数据类型转变

自动转变规则:由数据范围小的向数据范围大的转变
强制转换规则:超出基本数据类型的数据范围时间,使用强制类型转换

5.break和continue

两者都是跳出循环,只是跳出层次不同
 注意:在多层循环中,最外层出现标注时间,使用beak "标注”,程序会跳出多重循环
 代码如下:

          int i,j;
		A:for(i=0;i<3;i++) {
			System.out.println("i="+i);
			for(j=0;j<5;j++){
			   System.out.println("j="+j);
			   if(j==2) 
				 break;
			}
		}

结果如下:
java基础面试集锦_第1张图片

6. 类和对象的区别

类是对象的抽象,对象是类的具体实现
例子:”人类“是一个概括类,而”小王“是该类的具体实现

7. 面向对象和面向过程

两者都是编程的一种思维,现有面向过程,才有面向对象
面向对象的出现是为了补充面向过程的不足

类比:
现在有"蛋炒饭”和"盖浇饭“两种,前者是面向过程,后者是面向对象,对于”盖浇饭“而言,菜和饭都是两个具体的对象,菜不满意,可以换,饭不满意也可以换,处理就可变的很灵活,也就是程序上的可维护性良好

区别:
面向过程是函数式编程为主,面向对象是以对象为主
面向过程有类的继承和多态性,而面向过程没有

相辅相成:
面向过程将复杂的问题抽象化,简化成具体的微小问题,然后使用面向过程思维来解决

8.关键字

1)this和super

this是自身的引用,一般用于区别成员变量和局部变量
super对直接父类的引用,可以调用父类的成员变量和成员方法(private修饰不能调用)
也可调动父类的构造方法,但是只能在子类的构造方法中使用

2)static

可以修饰方法、变量、代码块、内部类
static属性属于类所有,所有实现类共享一个static属性
注意:

  • static修饰的属性属于类本身,所有的实现类公用一个,在内存中只有一个
  • static修饰的静态变量在方法区中,而实例变量在堆内存中
  • 静态变量调用方式 类名.变量名; 类似的方式来调用
  • 静态变量在类第一次使用时间就被创建了内存,静态代码块在类第一次使用时被执行,只被执行一次
  • 静态方法只能访问类中的静态变量(原因:静态方法和静态方法是类特有,在类被第一次使用时间就被创建,而成员变量是在new对象之后创建内存,使用静态方法访问成员变量,可能成员变量还没有在内存中创建)
public class StaticClass {
  
	static String name="123456";
	
	int age;
	String sex;
	public StaticClass(String sex,int age) {
		this.sex=sex;
		this.age=age;
	}
	static {
		System.out.println("Name:"+name);
	}
	
	public static void SS() {
		System.out.println("name1111:"+name);
	}
}

public class Main {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	   System.out.println("StaticClass:"+StaticClass.name);
       StaticClass st1;
       StaticClass.SS();
       st1 = new StaticClass("123",10);
       System.out.println("st1.name:"+st1.name);
	}
}

运行结果:
java基础面试集锦_第2张图片
结论:可以看到,静态方法在该类第一次调用时就开始运行,并且只运行一次

3) final abstract

final: final可修饰属性 类 方法。
   被修饰的变量不可更改
   被修饰的类不可被继承
   被修饰的方法不可被重写
abstract:acstract可以修饰类和方法
   被修饰的类必须被继承
   被修饰的方法必须被重写
注意:final修饰的变量不可被更改,也就变成了常量。而修饰的引用类型,其引用不可被更改,但是类型的属性可被更改

4) finally finalize

finally:使用 try 和 catch 抛出异常时间使用finally.
当用异常事件
finalize: 在object对象中被定义,用于垃圾回收器删除对象之前调用,做必要清理工作

注意:

A:
public static void main(String[] args) {
		try{
			System.out.println("error before");
			int i;
			i = 10/1;
			return ;
			//System.out.println("error after");
		}catch(Exception e){
			System.out.println("error");
		}finally{
			System.out.println("finally");
		}
	}
B:
public static void main(String[] args) {
		try{
			System.out.println("error before");
			int i;
			i = 10/0;
			return ;
			//System.out.println("error after");
		}catch(Exception e){
			System.out.println("error");
		}finally{
			System.out.println("finally");
		}
	}

运行结果:
java基础面试集锦_第3张图片
java基础面试集锦_第4张图片
结论:可看到无论代码是否抛出异常或者使用return,finally中的代码总会被执行

5) private default public protected

访问级别如下
java基础面试集锦_第5张图片

6) synchronized

用于给代码加锁,被修饰的代码,每次只能一个线程进入进行处理,其他线程等待
被修饰的方法被称为同步方法,被修饰的代码块被称为同步代码块
两者区别在于:
同步方法的范围较大,同步代码块可以在方法内部,相对来说范围较小
一般来说,范围越大,性能越低

9. 继承类下构造函数的加载

构造函数:

  1. 如果子类没有使用super或者this来调用相应构造方法,那么它自身会调动父类的无参构造方法
  2. 如果子类使用super来调用父类的有参构造方法,那么调动相应的有参构造方法,而不是无参构造方法
  3. 如果子类使用this调动自身其他构造方法,那么调用规则使用以上两个规则
  4. 如果是多级继承,构造参数规则会根据以上规则以此向上一级父类来调用
A:
public class Base {
	String name;
	public Base() {
		name = "123456";
		System.out.println("fu");
	}
}
public class BNext extends Base{
	public BNext() {
		System.out.println("zi");
	}
	public BNext(String name) {
		super.name = name;
		System.out.println("name zi");
	}
}
public static void main(String[] args) {
		BNext base = new BNext();
	}
	
B:
public class Base {
	String name;
	public Base() {
		name = "123456";
		System.out.println("fu");
	}
	
	public Base(String name) {
		this.name = name;
		System.out.println("name fu");
	}
}

public class BNext extends Base{
	public BNext() {
		System.out.println("zi");
	}
	public BNext(String name) {
		super(name);
		System.out.println("name zi");
	}
}
	
public static void main(String[] args) {
		BNext base = new BNext("12345");
	}

运行结果:
java基础面试集锦_第6张图片
java基础面试集锦_第7张图片
结果可看到正如上面规则所示

10. 继承下静态代码块和静态方法加载

  1. 静态代码块的继承,是先执行父类静态代码,之后执行子类的静态代码,并且执行在构造方法之前,也就是第一次调用时间。
  2. 静态方法是直接执行调用的方法,不论是重写或者重载,只有调用才有作用
public class Base {
	String name;
	public Base() {
		name = "123456";
		System.out.println("fu");
	}
	
	static {
		System.out.println("static base");
	}
	
	public static void sysoName() {
		System.out.println("static name");
	}
	
	public Base(String name) {
		this.name = name;
		System.out.println("name fu");
	}
}

public class BNext extends Base{
	public BNext() {
		System.out.println("zi");
	}
	public BNext(String name) {
		super(name);
		System.out.println("name zi");
	}
	static {
		System.out.println("static BNext");
	}
	public static void sysoName() {
		System.out.println("static BNext name");
	}
}

public static void main(String[] args) {
		BNext base = new BNext();
		BNext.sysoName();
}

执行结果:
java基础面试集锦_第8张图片

11. == 和equals的区别

== 作用
 - 基本数据类型,比较的是数值
 - 对象比较的是地址
 - 不能比较没有父子关系的两种类型
equals 作用
 - 系统中的类一般都会重写equals方法,比较的是内容
 - 类本身没用重写该方法,会调动父类的该方法
 - 自定义类小覆盖父类的equals方法
注意:object的equals方法比较的地址,此时和==作用相同

12. 基本数据类型和包装类

基本数据类型都对应了java中的包装类,由于java中是面向对象,而基本数据类型不是一个具体对象,实际使用时有不便之处

  1. java中提供了自动拆装箱来完成基本数据类型和包装类之间的转换
  2. int和Integer的区别
     int是基本数据类型,Integer是int的包装类
     具体比较如下:
  • 当new两个新的Integer时间,两者永远是不对等的(new的时间是创建了两个对象,两者的地址不等)
      Integer a = new Integer(3);
      Integer b = new Integer(3);
      a==b --> false
  • new的新对象和Integer包装类的对象不对等( 包装类包装的对象是在常量池中,而new的对象实在堆中)
    Integer a = new Integer(3);
    Integer b = 3;
    a==b --> false
  • new的对象和int基本类型比较时间,只要数值相等,两者就是对等的(此时比较时间,java会自动将Integer拆装成int,之后再进行比较)
     Integer a = new Integer(3);
     int b = 3;
     a==b --> true;
  • 两个非new生成的对象,对于-128~127之间的数字,两者比较相等,对与该范围之外的数值,两者比较不等。
     Integer a = 100;
     Integer b = 100;
     a==b; --> true;
     Integer a = 128;
     Integer b = 128;
     a == b; --> false
     
    原因如下:
public static Integer valueOf(int i){
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high){
        return IntegerCache.cache[i + (-IntegerCache.low)];
    }
    return new Integer(i);
}

对于-128~127之间的数值,直接进行缓存,下次使用直接拿出,而范围之外的数字,则是创建了新的对象。

13. 抽象类和接口

  • 抽象类中可以有构造方法。接口中不能有
  • 类可以实现多个接口(has-a),但是只能继承一个抽象类(is-a)
  • 接口和抽象类都不可被实例化
  • 接口可继承接口,抽象类可实现接口,抽象类可继承实体类

14. java序列化

序列化:在java中将一个实体类的状态信息写入字节流,使其可以通过socket传输,或者是写入数据库、文件系统中持久化,当使用时间,将字节流拿出,重写还原创建该实体对象

15. 创建类的几种方法

  • new创建对象,最常用的创建对象方法
  • 通过java.lang.class或者java.lang.reflect.Constructor类的newInstance()实例方法
  • 通过clon()来克隆对象
  • 通过反序列话来创建对象

注意:第一种和第二种都需要通过构造方法来创建对象,第三种是直接对已有对象进行克隆,第四种是从文件中还原对象

1:
Integer a = new Integer(3);

2:
public static void main(String args[]){
        try {
            Class class1 = Class.forName("java.lang.Integer");
            Integer a = (Integer) class1.newInstance();
        }catch (Exception e){
            System.out.println(e);
        }
    }
   
  3:
  public static void main(String args[]){
        try {
            Class class1 = Class.forName("java.lang.Integer");
            Constructor con = class1.getConstructor();
            Integer a = (Integer) con.newInstance();
            System.out.println();
        }catch (Exception e){
            System.out.println(e);
        }
    }
4:
public class Hello implements Cloneable{
    public void sayHello(){
        System.out.println("hello !");
    }
    public static void main(String args[]){
          Hello h1 = new Hello();
          try{
              Hello h2 = (Hello) h1.clone();
              h2.sayHello();
          }catch(Exception e){
              System.out.println(e);
          }

    }
}
5:反序列化来创建对象
 FileInputStream in1 = new FileInputStream(f);
 ObjectInputStream oos = new ObjectInputStream(in1);

16. 重载 重写

java基础面试集锦_第9张图片

17. equals 和 hashcode

简单来说,可以这样理解:hashcode的相等是equals为true的前提。hashcode相等,equals不一定为真,但是equals为真,那么hashcode一定相等

18.hashcode 和 equals一起重写

HashMap中,key的比较是两个都要比较,先比较hashcode,再比较equals。两者都是继承自父类。追根结底是要比较地址。若两者不一起重写,当比较equals()时只是看他们是否为同一对象(即进行内存地址的比较),所以必定要两个方法一起重写。

你可能感兴趣的:(java面试)