美文网首页
备战2019秋招之必会javase面试题(一)

备战2019秋招之必会javase面试题(一)

作者: Swen_9826 | 来源:发表于2019-06-28 20:47 被阅读0次
面向对象和面向过程的区别?
  • 面向过程
    优点: 性能比面向对象高。因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发
    缺点: 没有面向对象易维护、易复用、易扩展
  • 面向对象
    优点: 易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护
    缺点: 性能比面向过程低
Java 语言有哪些特点?
  • 简单易学;
  • 面向对象(封装,继承,多态);
  • 平台无关性( Java 虚拟机实现平台无关性);
  • 可靠性;
  • 安全性;
  • 支持多线程( C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持);
  • 支持网络编程并且很方便( Java 语言诞生本身就是为简化网络编程设计的,因此 Java 语言不仅支持网络编程而且很方便);
  • 编译与解释并存;
关于 JVM JDK 和 JRE 最详细通俗的解答?
  • JVM
    Java虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。

  • 什么是字节码?采用字节码的好处是什么?
    在 Java 中,JVM可以理解的代码就叫做字节码(即扩展名为 .class 的文件),面向虚拟机。
    Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。

  • 编译与解释共存的语言?
    .class->机器码 这一步,JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了 JIT 编译器,而JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。

JDK 和 JRE相关知识?
  • JDK是Java Development Kit,它是功能齐全的Java SDK。它拥有JRE所拥有的一切,还有编译器(javac)和工具(如javadoc和jdb)。它能够创建和编译程序。
  • JRE 是 Java运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java虚拟机(JVM),Java类库,java命令和其他的一些基础构件。但是,它不能用于创建新程序
Java和C++的区别?
  • 都是面向对象的语言,都支持封装、继承和多态
  • Java 不提供指针来直接访问内存,程序内存更加安全
  • Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
  • Java 有自动内存管理机制,不需要程序员手动释放无用内存
字符型常量和字符串常量的区别?
  • 形式上: 字符常量是单引号引起的一个字符; 字符串常量是双引号引起的若干个字符
  • 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)
  • 占内存大小 字符常量只占2个字节; 字符串常量占若干个字节(至少一个字符结束标志) (注意: char在Java中占两个字节)
构造器 Constructor 是否可被 override?
  • 在讲继承的时候我们就知道父类的私有属性和构造方法并不能被继承,所以 Constructor 也就不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。
重载和重写的区别?
  • 重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
  • 重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。
Java 面向对象编程三大特性: 封装 继承 多态
  • 封装
    封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。

  • 继承
    子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。
    子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
    子类可以用自己的方式实现父类的方法。

  • 多态
    在Java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。

String StringBuffer 和 StringBuilder 的区别是什么? String 为什么是不可变的?
  • 可变性
    String 类中使用 final 关键字修饰字符数组来保存字符串,private final char value[],所以 String 对象是不可变的。
    StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串char[]value 但是没有用 final 关键字修饰,所以这两种对象都是可变的。

  • 线程安全性
    String 中的对象是不可变的,也就可以理解为常量,线程安全。
    StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。
    StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

  • 性能
    每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuilder >StringBuffer

  • 总结:
    操作少量的数据: 适用String
    单线程操作字符串缓冲区下操作大量数据: 适用StringBuilder
    多线程操作字符串缓冲区下操作大量数据: 适用StringBuffer

自动装箱与拆箱
  • 装箱:将基本类型用它们对应的引用类型包装起来;
  • 拆箱:将包装类型转换为基本数据类型;
在一个静态方法内调用一个非静态成员为什么是非法的?
  • 类的静态成员(变量和方法)属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问;非静态成员(变量和方法)属于类的对象,所以只有在类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。在一个类的静态成员中去访问其非静态成员之所以会出错是因为在类的非静态成员不存在的时候类的静态成员就已经存在了,访问一个内存中不存在的东西当然会出错。
在 Java 中定义一个不做事且没有参数的构造方法的作用
  • Java 程序在执行子类的构造方法之前,如果没有用 super() 来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用 super() 来调用父类中特定的构造方法,则编译时将发生错误,因为 Java 程序在父类中找不到没有参数的构造方法可供执行。
  • 解决办法是在父类里加上一个不做事且没有参数的构造方法。
接口和抽象类的区别是什么?
  • 接口是绝对抽象的,不可以被实例化,抽象类也不可以被实例化。
  • 接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
  • 类可以实现很多个接口,但是只能继承一个抽象类
  • 类可以不实现抽象类和接口声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
  • 抽象类可以在不提供接口方法实现的情况下实现接口。
  • Java接口中声明的变量默认都是final的。抽象类可以包含非final的变量。
  • Java接口中的成员函数默认是public的。抽象类的成员函数可以是private,protected或者是public。
  • 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
成员变量与局部变量的区别有那些?
  • 从语法形式上看
    成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;
    成员变量可以被 public,private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及 static 所修饰;
    但是,成员变量和局部变量都能被 final 所修饰。

  • 从变量在内存中的存储方式来看
    如果成员变量是使用static修饰的,那么这个成员变量是属于类的,如果没有使用static修饰,这个成员变量是属于实例的。
    而对象存在于堆内存,局部变量则存在于栈内存。

  • 从变量在内存中的生存时间上看
    成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。

  • 成员变量如果没有被赋初值,则会自动以类型的默认值而赋值(一种情况例外被 final 修饰的成员变量也必须显示地赋值),而局部变量则不会自动赋值。

创建一个对象用什么运算符?对象实体与对象引用有何不同?
  • new运算符。
  • 对象实例在堆内存中,对象引用存放在栈内存中。
一个类的构造方法的作用是什么? 若一个类没有声明构造方法,该程序能正确执行吗? 为什么?
  • 主要作用是完成对类对象的初始化工作。
  • 可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。
构造方法有哪些特性?
  • 名字与类名相同。
  • 没有返回值,但不能用void声明构造函数。
  • 生成类的对象时自动执行,无需调用。
静态方法和实例方法有何不同
  • 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
  • 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。
对象的相等与指向他们的引用相等,两者有什么不同?
  • 对象的相等,比的是内存中存放的内容是否相等。而引用相等,比较的是他们指向的内存地址是否相等。
简述线程、程序、进程的基本概念。以及他们之间关系是什么?
  • 线程与进程相似,但线程是一个比进程更小的执行单位。进程是多个线程的集合。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
  • 程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。
  • 进程是是系统运行程序的基本单位,简单来说,一个进程就是一个执行中的程序,当程序在执行时,将会被操作系统载入内存中。 线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。
线程有哪些基本状态?
    1. 新建( new ):新创建了一个线程对象。
    1. 可运行( runnable ):线程对象创建后,其他线程(比如 main 线程)调用了该对象 的 start ()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获 取 cpu 的使用权 。
    1. 运行( running ):可运行状态( runnable )的线程获得了 cpu 时间片( timeslice ) ,执行程序代码。
    1. 阻塞( block ):阻塞状态是指线程因为某种原因放弃了 cpu 使用权,也即让出了 cpu timeslice ,暂时停止运行。直到线程进入可运行( runnable )状态,才有 机会再次获得 cpu timeslice 转到运行( running )状态。阻塞的情况分三种:
      等待阻塞:运行( running )的线程执行 o . wait ()方法, JVM 会把该线程放 入等待队列( waitting queue )中。
      同步阻塞:运行( running )的线程在获取对象的同步锁时,若该同步锁 被别的线程占用,则 JVM 会把该线程放入锁池( lock pool )中。
      其他阻塞: 运行( running )的线程执行 Thread . sleep ( long ms )或 t . join ()方法,或者发出了 I / O 请求时, JVM 会把该线程置为阻塞状态。当 sleep ()状态超时、 join ()等待线程终止或者超时、或者 I / O 处理完毕时,线程重新转入可运行( runnable )状态。
    1. 死亡( dead ):线程 run ()、 main () 方法执行结束,或者因异常退出了 run ()方法,则该线程结束生命周期。死亡的线程不可再次复生。


  • Java 中的异常处理


  • Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。
  • Exception(异常):是程序本身可以处理的异常。Exception 类有一个重要的子类 RuntimeException。RuntimeException 异常由Java虚拟机抛出。NullPointerException(要访问的变量没有引用任何对象时,抛出该异常)、ArithmeticException(算术运算异常,一个整数除以0时,抛出该异常)和 ArrayIndexOutOfBoundsException(下标越界异常)。
  • 异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。
Java序列化中如果有些字段不想进行序列化,怎么办?
  • 对于不想进行序列化的变量,使用transient关键字修饰。transient只能修饰变量,不能修饰类和方法。

java学习资料分享:关注公众号[Swen学java]即可免费领取详情见java学习资源汇总

java学习资源框架.png

相关文章

网友评论

      本文标题:备战2019秋招之必会javase面试题(一)

      本文链接:https://www.haomeiwen.com/subject/sgfycctx.html