JAVA面试常见问题之基础篇

时间:2022-08-19 14:27:08

一.  面向对象的特征:继承、封装、(抽象)、多态

  • 继承:继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。
  • 封装:封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类中。
  • 抽象:抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处
  • 多态:指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确

二.  final, finally, finalize 的区别

           1、final:java关键字,修饰符。可以声明成员变量、方法、类以及本地变量。一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。

1、修饰变量,该变量不能再被重新赋值。

2、修饰方法,该方法不能再被重写。

3、修饰类,该类不能再被继承。

2、finally:java的一种异常处理机制。finally结构的代码总会执行,不管发不发生代码异常。一般使用在关闭的功能上,比如:关闭连接,关闭流。

3、finalize:java中的一个方法。java使用finalize()在垃圾收集器将对象从内存中清除出去前,做必要的清除工作。

参考博客:http://www.cnblogs.com/smart-hwt/p/8257330.html

三、Exception、Error、运行时异常与一般异常有何异同

JAVA面试常见问题之基础篇

所有的异常都是由Throwable类,下一层分解为两个分支:Error和Exceprion。
        Error:层次结构描述了java运行时系统的内部错误和资源耗尽错误。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。应用程序不应该抛出这种类型的对象。
        Exceprion:这个层次结构又分解为连个分支:一个分支派生于RuntimeException;另一个分支包含其他异常。划分两个分支的规则是:由程序错误导致的异常属于RuntimeException;而程序本身没有没有问题,但由于像I/O错误这类异常导致的异常属于其他异常。
  常见的RuntimeException(运行时异常):
         IndexOutOfBoundsException(下标越界异常)
         NullPointerException(空指针异常)
         NumberFormatException (String转换为指定的数字类型异常)
         ArithmeticException -(算术运算异常 如除数为0)
         ArrayStoreException - (向数组中存放与声明类型不兼容对象异常)
         SecurityException -(安全异常)
     IOException(其他异常):
        FileNotFoundException(文件未找到异常)
        IOException(操作输入流和输出流时可能出现的异常)
        EOFException (文件已结束异常)
    参考博客:https://blog.csdn.net/m0_37531231/article/details/79502778

四、请写出5种常见到的runtime exception

  • 空指针异常   -- 使用null去调用方法
  • 下标越界异常  --声明数组时Wine[] wines = new Wine[2],但是却要放大于2个对象
  • 类型转换异常  --String a = "爱",将a强转成int类型
  • 算数运算异常  --除数为0
  • 类型不兼容异常  --向数组中存放与声明类型

五、int 和 Integer 有什么区别,Integer的值缓存范围

   Integer是int的包装类 ,可以自动的拆装箱,int 的初值(默认值)为0,Integer的初值(默认值)为null。

1,无论如何,Integer与new Integer不会相等。不会经历拆箱过程,new出来的对象存放在堆,而非new的Integer常量则在常量池(在方法区),他们的内存地址不一样,所以为false。
       2,两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false。因为java在编译Integer i2 = 128的时候,被翻译成:Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存。
       3,两个都是new出来的,都为false。还是内存地址不一样。
       4,int和Integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比。
    Integer的值缓存范围:-128到127

参考博客:https://blog.csdn.net/login_sonata/article/details/71001851

六、重载和重写的区别

  • 方法重载是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同。
  • 方法重写是存在子父类之间的,子类定义的方法与父类中的方法具有相同的方法名字,相同的参数表和相同的返回类型

注:
             (1)子类中不能重写父类中的final方法
             (2)子类中必须重写父类中的abstract方法

参考博客:https://www.cnblogs.com/upcwanghaibo/p/6527354.html

七、抽象类和接口有什么区别

  • 抽象类:用来捕捉子类的通用特性的 。它不能被实例化,只能被用作子类的超类。抽象类是被用来创建继承层级里子类的模板。(abstract)
  • 接口:抽象方法的集合。如果一个类实现了某个接口,那么它就继承了这个接口的抽象方法。

抽象类和接口的对比

参数 抽象类 接口
默认的方法实现 它可以有默认的方法实现 接口完全是抽象的。它根本不存在方法的实现
实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
构造器 抽象类可以有构造器 接口不能有构造器
与正常Java类的区别 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 接口是完全不同的类型
访问修饰符 抽象方法可以有publicprotecteddefault这些修饰符 接口方法默认修饰符是public。你不可以使用其它修饰符。
main方法 抽象方法可以有main方法并且我们可以运行它 接口没有main方法,因此我们不能运行它。
多继承 抽象方法可以继承一个类和实现多个接口 接口只可以继承一个或多个其它接口
速度 它比接口速度要快 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
添加新方法 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 如果你往接口中添加方法,那么你必须改变实现该接口的类。

参考博客:http://www.importnew.com/12399.html

八、说说反射的用途及实现

  1. 反射作用:是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
  2. 反射的用途:开发各种通用框架。
  3. 反射实现
    1. 获得Class对象
      1. 使用Class类的forName静态方法
      2. 直接获取某一个对象的class(Object.class)
      3. 调用某个对象的getClass()方法
    2. 判断是否为某个类的实例
      1. 用instanceof关键字来判断是否为某个类的实例
    3. 创建实例
      1. 使用Class对象的newInstance()方法来创建Class对象对应类的实例。
      2. 先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。
    4. 获取方法
      1. getDeclaredMethods()
    5. 获取构造器信息
      1. getDeclaredMethods()
      2. getMethods()
      3. getMethod()
    6. 获取类的成员变量(字段)信息
      1. getFiled: 访问公有的成员变量
      2. getDeclaredField:所有已声明的成员变量。但不能得到其父类的成员变量
      3. getFileds和getDeclaredFields用法
    7. 调用方法  invoke()
    8. 利用反射创建数组 Array.newInstance()
     

九、说说自定义注解的场景及实现

  • 场景:前端传到后端加密数据的解密
  • 实现:未实现过,也没有研究过。

十、HTTP请求的GET与POST方式的区别

  • 安全性: get安全性非常低,post安全性较高。
  • 请求形式:GET将参数拼在url之后,用?将url和参数分开,用&将多个参数分开。POS将参数放在body体中发送到后台。
  • 传输数据的大小:get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
  • 服务端获取方式:对于get方式,服务器端用Request.QueryString获取数据,对于post方式,服务器端用Request.Form获取提交的数据。

参考博客:https://www.cnblogs.com/zizo/p/3538820.html

十一、Session与Cookie区别

  1. Cookie数据存放在客户的浏览器(本地),session数据放在服务器上
  2. Cookie不如session安全,别人可以分析存放在本地的Cookie并进行Cookie欺骗,所以出于安全性的考虑应当使用Session
  3. Session会在一定时间内保存在服务器上。当访问增多,会占用较多的服务器资源,所以出于性能考虑则应当使用cookie

十二、列出自己常用的JDK包

  • java.lang: 这个是系统的基础类,比如String、Math、Integer、System和Thread, 提供常用功能。
  • java.io: 这里面是所有输入输出有关的类,比如文件操作等
  • java.net: 这里面是与网络有关的类,比如URL,URLConnection等。
  • java.util : 这个是系统辅助类,特别是集合类Collection,List,Map等。
  • java.sql: 这个是数据库操作的类,Connection, Statememt,ResultSet等

十三、MVC设计思想

MVC是model、view、controller的简称。它是一中软件的设计思想,将应用的一个输入、处理、输出按照模型层,视图层,控制层进行分层设计。

  • 模型层(model):业务逻辑包含了业务数据的加工与处理以及相应的基础服务。相当于工程的业务逻辑层加上数据持久层
  • 控制层(controller):视图发请求给控制器,由控制器来选择相应的模型来处理;模型返回的结果给控制器,由控制器选择合适的视图。相当于工程的控制层action层
  • 视图层(view):展现模型处理的结果;另外,还要提供相应的操作界面,方便用户使用。相当于:前端的jsp+html

十四、equals与==的区别

  • == 是一个比较运算符,基本数据类型比较的是值,引用数据类型比较的是地址值。
  • equals() 是一个方法,只能比较引用数据类型。重写前比较的是地址值,重写后比一般是比较对象的属性。

十五、hashCode和equals方法的区别与联系

  • 区别
    • 返回值类型:hashCode返回int类型,equals返回boolean类型
    • 判断精度:hashCode判断不精确,equals重写后可以精确判断
  • 联系
    • 如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等
    • 如果两个对象不equals,他们的hashcode有可能相等。
    • 如果两个对象hashcode相等,他们不一定equals。
    • 如果两个对象hashcode不相等,他们一定不equals。

十六、什么是Java序列化和反序列化,如何实现Java序列化?或者请解释Serializable 接口的作用

序列化:将Java对象按照一定的格式输出为字节序列,它可以完整的保持Java对象的所有状态和描述信息。从而将其传递给另外的Java进程或者保存在本地。其最核心的工作量就在于Java对象的分解和重建。
       反序列化:顾名思义,Java序列化的反过程,将已经序列化的字节序列转化成有效完整的Java对象的过程,这就是反序列化。

实现Serializable接口,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

可以用对象实现Serilizable接口实现对象的序列化与反序列化。

十七、Object类中常见的方法,为什么wait  notify会放在Object里边

  • 常见方法
    • finalize():垃圾收集器调用的方法
    • toString():将对象转成字符串类型
    • equals():比较对象是否相等
    • hashCode():获取哈希值
  • 因为这些方法在操作同步线程时,都必须要标识它们操作线程的锁,只有同一个锁上的被等待线程,可以被同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒。

    也就是说,等待和唤醒必须是同一个锁。而锁可以是任意对象,所以可以被任意对象调用的方法是定义在object类中。

十八、Java的平台无关性如何体现出来的

跨平台性,Java程序只要编译一次,就可到处运行。

十九、JVM、JDK和JRE的区别

  • JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库
  • JRE是运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。
  • JVM是Java Virtual Machine(Java虚拟机)的缩写,是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。

二十、Java 8有哪些新特性

  • 针对时间的操作:LocalTime now1 = LocalTime.now();
  • lambda表达式