Java常见面试题(二)

目录

1、JDK常用的包有哪些?

2、Get 和 Post的区别?

3、Hashtable 与 HashMap的区别?

4、Java九大隐式对象?

5、Forword(转发) 与 Redirect(重定向)的区别?

6、线程、程序、进程的基本概念。以及他们之间关系是什么?

7、session 和 cookie的区别?

8、Java常见状态码及其含义?

9、抽象类与接口的区别?

10、GC 是什么?为什么要有 GC?

11、final、finally、finalize的区别?

12、Collection 和 Collections的区别?

13、启动一个线程是调用 run()还是 start()方法?

14、Java 中如何实现序列化,有什么意义?

15、Java 中 ++ 操作符是线程安全的吗?

16、a = a + b 与 a += b 的区别?

17、int 和 Integer哪个会占用更多的内存?

18、“==” 和 ”equals()”有什么区别?

19、equals() 和 hashCode()的区别?

19、为什么重写 equals 时必须重写 hashCode 方法?

20、为什么两个对象有相同的 hashcode 值,它们也不一定是相等的?

22、public,private,protected继承有什么区别?

23、类加载的过程?有哪些类加载器?

24、Java泛型是什么?什么是类型擦除?介绍一下常用的通配符?


1、JDK常用的包有哪些?

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

2、Get 和 Post的区别?

  1. get是从服务器上获取数据,post是向服务器传送数据
  2. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制
  3. get安全性非常低,post安全性较高。但是执行效率却比post方法好
  4. 在进行文件上传时只能使用post而不能是get

3、Hashtable 与 HashMap的区别?

  • HashTable底层数组+链表实现,无论key还是value都不能为null,线程安全
  • HashMap底层数组+链表+红黑树实现,可以存储null键和null值,线程不安全

4、Java九大隐式对象?

隐式对象:访问容器所提供的服务或资源,在使用的时候不用显示的声明,可以直接使用的对象。

  • 输入/输出对象:request、response、out
  • 作用域通信对象:session、application、pageContext
  • Servlet 对象:page、config
  • 错误对象:exception

5、Forword(转发) 与 Redirect(重定向)的区别?

  1. redirect 地址栏发生变化,forward 地址栏不发生变化
  2. redirect 可以访问其他站点(服务器)的资源,forward 只能访问当前服务器下的资源
  3. redirect 是两次请求,不能使用 request对象来共享数据;forward 是一次请求,可以使用 request对象来共享数据

6、线程、程序、进程的基本概念。以及他们之间关系是什么?

线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程

程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码

进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如 CPU 时间,内存空间,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段

7、session 和 cookie的区别?

  1. cookie数据存放在客户的浏览器上,session数据放在服务器上
  2. cookie不是很安全,可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session
  3. session会在一定时间内保存在服务器上,当访问增多,会比较占用服务器的性能
  4. 单个cookie保存的数据不能超过4K,浏览器都限制一个站点最多保存20个cookie,session存储在服务端,浏览器对其没有限制

8、Java常见状态码及其含义?

  • 200:请求成功
  • 400:请求和服务器对接不上,发送请求时出现的问题
  • 401:unauthorized(未授权的、非法的)表示发送的请求需要有通过 HTTP 认证的认证信息
  • 403:服务器拒绝请求,服务器不接受请求(可能没有权限)
  • 404:找不到页面,路径有问题
  • 500:服务器遇到错误,无法完成请求。服务器中的错误即请求成功后服务器运行出现错误,java代码写的有问题

9、抽象类与接口的区别?

  1. 抽象类使用 abstract关键字修饰,要被子类继承,接口要被类实现,一个类可以实现多个接口
  2. 接口全部的方法都是抽象方法,只能做方法声明,抽象类中可以作方法声明,也可以做方法实现
  3. 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量
  4. 接口是设计的结果,抽象类是重构的结果
  5. 抽象类可以有具体的方法和属性,接口只能有抽象方法和不可变常量
  6. 抽象类主要用来抽象类别,接口主要用来抽象功能

10、GC 是什么?为什么要有 GC?

GC 是垃圾收集的意思,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java 提供的 GC 功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java 语言没有提供释放已分配内存的显示操作方法,垃圾收集器会自动进行管理

请求垃圾收集,可以调用下面的方法之一:System.gc() 或 Runtime.getRuntime().gc() ,但 JVM 可以屏蔽掉显示的垃圾回收调用。垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存。垃圾回收器通常作为一个单独的低优先级的线程运行,不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清除回收,程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收

11、final、finally、finalize的区别?

final:修饰符有三种用法:如果一个类被声明为 final,它就不能被继承;将变量声明为 final,被声明为 final 的变量不能发生改变并且必须在声明时给定初值;被声明为 final的方法只能使用,不能在子类中被重写

finally:通常放在 try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要 JVM 不关闭都能执行,可以将释放外部资源的代码写在 finally 块中finalize:Object 类中定义的方法,Java 中允许使用

finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写 finalize()方法可以整理系统资源或者执行其他清理工作

12、Collection 和 Collections的区别?

  • Collection 是一个接口,它是 Set、List容器的父接口
  • Collections 是个一个工具类,提供了一系列的静态方法来辅助容器操作,比如对容器的搜索、排序等

13、启动一个线程是调用 run()还是 start()方法?

启动一个线程是调用 start() 方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由 JVM 调度并执行,这并不意味着线程就会立即运行。run() 方法是线程启动后要进行回调的方法

14、Java 中如何实现序列化,有什么意义?

序列化是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题 (如果不进行序列化可能会存在数据乱序的问题)

实现序列化,需要让一个类实现 Serializable 接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过 writeObject (Object)方法就可以将实现对象写出;如果需要反序列化则可以用一个输入流建立对象输入流,然后通过 readObject 方法从流中读取对象

15、Java 中 ++ 操作符是线程安全的吗?

不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,然后存储回内存,这个过程可能会出现多个线程交叉

16、a = a + b 与 a += b 的区别?

+= 隐式的将加操作的结果类型强制转换为持有结果的类型。如果两这个整型相加,如 byte、short 或者 int,首先会将它们提升到 int 类型,然后在执行加法操作

17、int 和 Integer哪个会占用更多的内存?

Integer 是一个对象,会占用更多的内存;int是基本数据类型,所以占用的空间更少

18、“==” 和 ”equals()”有什么区别?

equals() :它的作用也是判断两个对象是否相等,它不能用于比较基本数据类型的变量,equals()方法存在于 Object类中

Object 类 equals() 方法:

public boolean equals (Object obj){
    return (this == obj);
}

19、equals() 和 hashCode()的区别?

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

以“ HashSet 如何检查重复” 为例子来说明为什么要有 hashCode:把对象加入 HashSet 时, HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的 hashcode, HashSet 会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals() 方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置

  • equals():反映的是对象或变量具体的值,即两个对象里面包含的值可能是对象的引用,也可能是值类型的值
  • hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数。根类 Object的 hashCode()方法的计算依赖于对象实例的(内存地址),故每个 Object对象的 hashCode都是唯一的;当对象所对应的类重写了 hashCode()方法时,结果就截然不同了
  • 如果两个对象相等(equal),那么他们一定有相同的哈希值
  • 如果两个对象的哈希值相同,但他们未必相等(equal)

19、为什么重写 equals 时必须重写 hashCode 方法?

如果两个对象相等,则 hashcode 一定也是相同的。两个对象相等,对两个对象分别调用 equals 方法都返回 true。但是,两个对象有相同的 hashcode 值,它们也不一定是相等的 。因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。

20、为什么两个对象有相同的 hashcode 值,它们也不一定是相等的?

因为 hashCode() 所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。越糟糕的杂凑算法越 容易碰撞,但这也与数据值域分布的特性有关,所谓碰撞也就是指的是不同的对象得到相同的 hashCode 。 我们刚刚也提到了 HashSet ,如果 HashSet 在对比的时候,同样的 hashcode 有多个对象,它会使用 equals() 来判断是否真的相同。也就是说 hashcode 只是用来缩小查找成本。

22、public,private,protected继承有什么区别?

  • 私有继承(private):默认的继承方式,基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问,父类的 protected和 public属性在子类中变为 private
  • 保护继承(protected):基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数,基类的私有成员仍然是私有的,父类的 protected和 public属性在子类中变为 protected
  • 公有继承(public):基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问,父类的 protected和 public属性不发生改变

23、类加载的过程?有哪些类加载器?

一般分为三个比较大的阶段,分别是加载阶段,连接阶段和初始化阶段,五个主要的阶段。在这五个阶段中,加载验证准备初始化这四个阶段发生的顺序是确定的,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始。另外注意这里的几个阶段是按顺序开始,而不是按顺序进行或完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行的过程中调用或激活另一个阶段

JAVA中的类加载器主要分为下图的四种

引导类加载器(bootstrap class loader)

  • 用来加载 Java 的核心库(JAVA_HOME/jre/lib/rt.jar,sun.boot.class.path路径下的内容),用原生代码(C语言)来实现的,并不继承自 java.lang.ClassLoader
  • 加载扩展类和应用程序类加载器,并指定他们的父类加载器

扩展类加载器(extensions class loader)

  • 用来加载 Java 的扩展库(JAVA_HOME/jre/ext/*.jar,或java.ext.dirs路径下的内容) 。Java 虚拟机的实现会提供一个扩展库目录,该类加载器在此目录里面查找并加载 Java类,由sun.misc.Launcher$ExtClassLoader实现

应用程序类加载器(application class loader)

  • 根据 Java 应用的类路径(classpath,java.class.path 路径下的内容)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的,由sun.misc.Launcher$AppClassLoader实现

自定义类加载器

  • 开发人员可以通过继承 java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求
  • 遵守双亲委派模型:继承ClassLoader,重写findClass()方法
  • 破坏双亲委派模型:继承ClassLoader,重写loadClass()方法

24、Java泛型是什么?什么是类型擦除?介绍一下常用的通配符?

Java泛型是 JDK 5 中引入的一个新特性,泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数

Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,这也就是通常所说类型擦除

常用的通配符为:T,E,K,V,?

  • ?表示不确定的 Java类型
  • T (type) 表示具体的一个 Java类型
  • K V (key value) 分别代表 Java键值中的Key Value
  • E (element) 代表Element

泛型一般有三种使用方式:泛型类、泛型接口、泛型方法

泛型类:

//此处T可以随便写为任意标识,在实例化泛型类时,必须指定T的具体类型
public class Generic<T> {
    private T key;

    public Generic(T key) {
        this.key = key;
    }

    public T getKey() {
        return key;
    }
}

泛型接口:

public interface Generator<T> {
    public T method();
}

泛型方法:

public static <E> void printArray(E[] inputArray) {
    for (E element : inputArray) {
        System.out.printf("%s ", element);
    }
    System.out.println();
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

South.return

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值