1. 面向对象和面向过程的区别

  • 面向过程

    • 优点:性能比面向对象要高,因为类的实例化需要消耗大量的资源,通常用在嵌入式系统开发中
    • 缺点:代码量太大,难维护,难扩展
  • 面向对象
    • 优点 易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
    • 缺点 性能低于面向对象程序

2. Java语言的特点

  • 简单、易学
  • 跨平台
  • 面向对象
  • 分布式
  • 健壮性
  • 支持多线程
  • 支持网络编程
  • 支持编译和解释

3. JDK、JRE、JVM的关系

JDK是Java提供的开发工具包,除了包含Java程序运行的JRE外,还包含了一些提供给程序员使用的开发程序包
JRE是Java运行时环境
当我们通过JRE运行程序时,JVM将字节码转换成机器码,JVM还提供了内存管理、垃圾回收和安全机制,独立于操作系统和硬件,也是Java跨平台的原因

4. Java是解释执行,这句话正确吗?

Java是一门面向对象的语言,最显著的特性有两个方面,一是跨平台性,二是垃圾收集。Java通过垃圾收集器回收分配内存,所以我们不需要手动管理内存。对于Java是解释执行这句话,这个说法不太准确。我们开发的Java源代码,通过javac编译成字节码文件,然后,在运行时通过JVM内嵌的解释器将字节码转换成机器码,但是常见的JVM都提供了JT编译器,也就是通常所说的动态编译器,JT能够在运行时将热点代码编译成字节码,这种情况下部分热点代码就属于编译执行,而不是解释执行了

5. Java和C++的区别

  • 都支持面向对象三大特性
  • C++支持多继承,Java不支持多继承,但是接口可以多实现
  • Java不提供指针操作,程序更加安全
  • Java有内存管理,不需程序员手动分配释放内存

6. 重载和重写的区别

  • 重载:处于同一个类中,方法名相同,返回值,参数个数和类型都可以不相同
  • 重写:处于子类中,方法名,返回值,参数个数和类型都必须相同,构造器不可以被重写

7. 面向对象三个特性

  • 封装

    封装就像对象的属性进行私有化,同时提供一些方法提供给外界访问

  • 继承

    继承是通过已存在的类创建新的类,继承父类的非私有属性和方法,我们可以使用父类继承的属性和方法,也可以添加一些属性和方法,但是,不可以选择性的继承父类的属性和方法

  • 多态

    所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定
    在Java中有两种形式可以实现多态:继承和接口

8. 自动拆箱和装箱

  • 装箱 将基本类型用它们对应的引用类型包装起来
  • 拆箱 将包装类型转换为基本数据类型

9. 为什么在一个非静态方法中调用静态变量是非法的?

由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员

10. 在 Java 中定义一个空参构造的作用

因为子类在调用自己的构造方法之前,会调用父类的构造方法,如果没有显示的使用super调用父类的构造方法,就是隐式的调用父类的空参调用,如果父类中只有带参构造,就会出现编译出错

11. 接口和抽象类的区别

  • 接口中的方法都是抽象方法,抽象类中的方法可以是抽象的,也可以不是抽象的
  • 一个类可以实现多个接口,但是只可以继承一个抽象类
  • 一个类实现接口必须实现接口的中的所有方法,但是抽象不需要
  • 抽象的实例变量都是常量,抽象类不一定
  • 接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范

12. 成员变量和局部变量的区别

从语法形式上,成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数,成员变量可以被权限修饰符所修饰,而局部变量不能被访问控制修饰符及static所修饰
成员变量和局部变量都能被 final 所修饰
从变量在内存中的存储方式来看,成员变量是对象的一部分,而对象存在于堆内存,局部变量存在于栈内存
从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失
成员变量如果没有被赋初值,则会自动以类型的默认值而赋值而局部变量则不会自动赋值

14. 静态方法和实例方法有何不同

静态方法可以使用类名.方法名和实例名.方法名的方式调用,实例方法只能使用实例名.方法名的方式调用
静态方法在访问本类时,只允许访问静态方法和静态成员,实例方法则没有此限制

13. 创建一个对象用什么运算符?对象实体与对象引用有何不同?

new运算符,new创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可以指向0个或1个对象,一个对象可以有n个引用指向它

15. String 和 StringBuffer、StringBuilder 的区别是什么 String 为什么是不可变的?

String类使用final修饰,所以说String是不可变的,StringBuffer和StringBuilder继承于AbstractStringBuilder类,这个类没有被final修饰,所以这两个类都是可变的

  • 线程安全:所谓线程安全,就是多个线程访问的时候,我们的程序还能按照我们预期的行为去执行,Stiring是不可变的,可以理解为常量,所以String是线程安全的,StringBuffer增加了同步锁,所以StringBuffer是线程安全的,StringBuilder是线程不安全的
  • 性能:因为String是不可变的,所以每次修改对象都会在堆内存中创建一个新的对象,所以它的性能最低,StringBuffer是线程安全的,所以它的性能略低于StringBuilder
  • 总结:
    • 操作少量数据,使用String
    • 单线程操作大量数据,使用StringBuilder
    • 多线程操作大量数据,使用StringBuffer

16. 什么是方法返回值?

返回值就是一个方法执行完成后返回的结果

17. 构造方法的作用?

构造方法的作用就是完成对实例的初始化操作,即使没有自定义构造方法,这个类中也会自带一个无参构造

18. ==和equals

==比较的是两个对象的内存地址是否相同,而equals比较是两个对象的值是否相同

19. hashCode 与 equals

  • hashCode

    hashCode() 的作用是获取哈希码,也称为散列码,它实际上是返回一个int整数,这个哈希码的作用是确定该对象在哈希表中的索引位置,Java中的任何类都包含有hashCode() 函数

    散列表存储的是键值对,它的特点是:能根据“键”快速的检索出对应的“值”,这其中就利用到了散列码

  • 为什么要有 hashCode

    当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现,但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同,如果两者相同,HashSet 就不会让其加入操作成功,如果不同的话,就会重新散列到其他位置,这样我们就大大减少了执行equals的次数,相应就大大提高了执行速度

  • hashCode()与equals()的相关规定

    如果两个对象相等,则hashCode一定也是相同的
    两个对象相等,对两个对象分别调用equals方法都返回true
    两个对象有相同的hashCode值,它们也不一定是相等的
    因此,equals方法被覆盖过,则hashCode方法也必须被覆盖
    hashCode()的默认行为是对堆上的对象产生独特值,如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等

20. 异常

  • Java异常体系层次图
    JavaSE基础知识总结

    在 Java 中,所有的异常都有一个共同的祖先,Throwable类
    Throwable: 有两个重要的子类
    Error:是程序无法处理的错误,表示运行应用程序中较严重问题,大多数错误与代码编写者执行的操作无关,而表示代码运行时JVM出现的问题
    Exception:是程序本身可以处理的异常,Exception 类有一个重要的子类

  • 编译期异常和运行期异常的区别

    编译器异常是指编译器要求必须处理的异常,即程序在运行时由于外界因素造成的一般性异常,编译器要求必须捕获或声明所有编译期异常
    运行时异常是指编辑器不要求强制处理的异常,一般是程序的逻辑错误,对于这类异常,可以不做处理,若全部处理可能会对程序的可读性和运行效率产生影响

  • 异常和错误的区别

    异常能被程序本身可以处理,错误是无法处理

  • Throwable类常用方法

    public string getMessage():返回异常发生时的详细信息
    public string toString():返回异常发生时的简要描述
    public string getLocalizedMessage():返回异常对象的本地化信息,使用Throwable的子类覆盖这个方法,可以声称本地化信息,如果子类没有覆盖该方法,则该方法返回的信息与getMessage返回的结果相同
    public void printStackTrace():在控制台上打印Throwable对象封装的异常信息

  • 异常处理总结

    try块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块
    catch块:用于处理try捕获到的异常
    finally块:无论是否捕获或处理异常,finally块里的语句都会被执行,当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行

  • 在以下4种特殊情况下,finally块不会被执行

    在finally语句块中发生了异常
    在前面的代码中用了System.exit()
    程序所在的线程死亡
    关闭CPU