Java面试题

目录

Java(基础篇)

1、JDK和JRE有什么区别?

2、面向对象和面向过程的区别?

3、equals与==的区别?

4、Hashcode的作用?

5、final有哪些用法?

6、String、StringBuffffer 和 StringBuilder 的区别是什么?

7、重载和重写的区别?

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

9、说说List,Set,Map三者的区别?

10、ArrayList和linkedList的区别

11、HashMap和HashTable的区别?

12、HashMap 与 ConcurrentHashMap 的异同

13、JDK1.7和JDK1.8发生了什么变化?

14、浅拷贝和深拷贝?

15、hashMap的扩容机制?

16、什么是字节码?使用字节码的好处?

17、Java中的异常分类?

18、Java中的类加载器?


Java(基础篇)

1、JDK和JRE有什么区别?

JDK:Java开发工具包,提供了Java的开发环境和运行环境。

JRE:Java运行环境,为Java的运行环境提供所需要的环境。

2、面向对象和面向过程的区别?

面向过程:是分析解决问题的步骤,然后用函数把这些步骤一步一步地实现,然后在使用的时候一一调用则可。性能较高,所

以单片机、嵌入式开发等一般采用面向过程开发。

面向对象 是把构成问题的事务分解成各个对象,而建立对象的目的也不是为了完成一个个步骤, 而是为了描述某个事物在
解决整个问题的过程中所发生的行为。面向对象有封装、继承、多态的特性,所以易维护、易复用、易扩展。可以设计出低耦
合的系统。 但是性能上来说,比面向过程要低。

3、equals==的区别?

==如果是基本类型变量,比较的是值。如果是引用类型变量,比较的是引用的地址。

equals用来比较俩个对象的内容是否相同,由于所有的类都是继承java.lang.Object类的,所以适用于所有对象,如果没有对该

方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。

4、Hashcode的作用?

java 的集合有两类,一类是 List ,还有一类是 Set 。前者有序可重复,后者无序不重复。当我们在 set中插入的时候怎么判断是

否已经存在该元素呢,可以通过equals方法。但是如果元素太多,用这样的方法就会比较慢。于是有人发明了哈希算法来提高

集合中查找元素的效率。 这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组

分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储的那个区域。

hashCode我是这样理解的:他返回的是根据对象的内存算出来的一个值。这样一来当我们需要添加元素的时候,先调用这个

元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位

置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存

了,不相同的化,这就是我们平时说的产生哈希冲突了。解决哈希冲突的方法有三种,分别是拉链法、开放定址法、再哈希。

用来解决哈希冲突。

5、final有哪些用法?

(1)、被final修饰的类不可以继承和重写。

(2)、被final修饰的方法,JVM会尝试将其内联,可以提高运行效率。

(3)、被final修饰的变量不可以改变。如果修饰引用,那么表示引用不可变,引用指向的内容可变。

(4)、被final修饰的常量,在编译时会存入常量池中。

6、String、StringBuffffer StringBuilder 的区别是什么?

String:String是只读字符串,它并不是基本数据类型,而是一个对象。从底层源码来看是一个final类型的字符数组,所引用

的字符串不能被改变,一经定义,无法再增删改。每次对String的操作都会生成新的String对象。

StringBufffferStringBuilder:StringBuffffer和StringBuilder他们两都继承了AbstractStringBuilder抽象类,从

AbstractStringBuilder抽象类中我们可以看到他们的底层都是可变的字符数组,所以在进行频繁的字符串操作时,建议使用

StringBuffffer和StringBuilder来进行操作。 另外StringBuffffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安

全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。但是没加锁意味着它的执行效率更高。

7、重载和重写的区别?

重写:

(1)、 发生在父类与子类之间。
(2)、 方法名,参数列表,返回类型(除过子类中方法的返回类型是父类中返回类型的子类)必须相同。
(3)、 访问修饰符的限制一定要大于被重写方法的访问修饰符 (public>protected>default>private)。
(4)、 重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。

重载:

(1)、 重载 Overload 是一个类中多态性的一种表现。
(2)、 重载要求同名方法的参数列表不同 ( 参数类型,参数个数甚至是参数顺序)。
(3)、 重载的时候,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。

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

(1)、抽象类可以存在普通成员方法,而接口只能存在抽象方法。

(2)、抽象类只能继承一个,而接口可以多实现。

(3)、成员变量在抽象类中是各个类型的,在接口中只能是常量类型。

9、说说List,Set,Map三者的区别?

List List 接口存储一组不唯一(可以有多个元素引用相同的对象),有序的对象。
Set : 不允许重复的集合。不会有多个元素引用相同的对象。
Map : 使用键值对存储。 Map 会维护与 Key 有关联的值。两个 Key 可以引用相同的对象,但Key 不能重复,典型的 Key String
型,但也可以是任何对象。

10、ArrayListlinkedList的区别

ArrayList:ArrayList底层是基于动态数组存放数据的,一旦数据存储好了,查询的效率就会变高。

LinkedList:LinkedList底层是基于链表实现的,对于新增删除元素的操作,LinkedList比较占优势。

但是我在开发中,大部分还是使用的ArrayList。因为我觉得ArrayList在处理好的情况下,性能不比LinkedList差。在我们一开始建立集合时,如果确定其容量然后再使用尾插法进行添加元素。就可以大大提高其的性能。而且LinkedList下创建对象时,会大量创建node对象,这样会使其性能变差。而且如果我们在遍历元素的时候只能使用迭代器来遍历元素,想要使用for来遍历元素并且用get(i)取元素的时候。每次get的时候都需要遍历元素。这样也会对其的性能消耗变差。

11、HashMapHashTable的区别?

(1)、HashMap方法没有synchronize修饰,线程不安全。HashTable线程为安全。

(2)、HashMap允许key和value为null。key只能有一个空值,而value可以为多个空值。而HashTable不允许为空值。

(3)、但是HashMap的效率要远高于HashTable。如果想要使用多线程并保证线程安全,我们可以使用ConcurrentHashMap

12、HashMap ConcurrentHashMap 的异同

(1)、都是 key-value 形式的存储数据。

(2)、HashMap 是线程不安全的,ConcurrentHashMap 是JUC下的线程安全的。

(3)、HashMap 底层数据结构是数组 + 链表(JDK 1.8 之前)。JDK 1.8 之后是数组 + 链表 + 红黑树。当链表中元素个数

达到 8 的时候,链表的查询速度不如红黑树快,链表会转为红黑树,红黑树查询速度快。

(4)、HashMap 初始数组大小为 16(默认),当出现扩容的时候,以 0.75 * 数组大小的方式进行扩容;

(5)、ConcurrentHashMap 在 JDK 1.8 之前是采用分段锁来现实的 Segment + HashEntry,Segment 数组大小默认是 16

2 n 次方;JDK 1.8 之后,采用 Node + CAS + Synchronized来保证并发安全进行实现。

13、JDK1.7和JDK1.8发生了什么变化?

(1)、JDK1.7底层为数组+链表。JDK1.8底层为数组+链表+红黑树。红黑树用来提高其插入和查询的效率。

(2)、JDK1.7使用的插入方法是头插法。JDK1.8使用的插入方法是尾插法。

(3)、JDK1.7中的算法比较复杂,JDK1.8增加了红黑树节省了CPU的资源。

14、浅拷贝和深拷贝?

(1)、浅拷贝:如果我们要拷贝基本数据类型直接拷贝,如果我们要拷贝引用数据类型时,只能拷贝它的引用地址。它们还

同时指向一个对象。

(2)、深拷贝:如果我们要拷贝基本数据类型直接拷贝,如果我们要拷贝引用数据类型时,拷贝之后,他们会指向不同的对

象,相当于重新建立一个对象。

15、hashMap的扩容机制?

JDK1.7(数组+链表):

(1)、生成一个新数组。

(2)、遍历老数组每个位置上的链表元素。

(3)、取出key,并基于新数组的长度,计算出新数组的下标。

(4)、将数组复制到新数组中去。

(5)、所有元素转移完后,将新数组将新数组赋值给HashMap的table属性。

JDK1.8(数组+链表+红黑树):

(1)、生成一个新数组。

(2)、遍历数组中的链表和红黑树。

(3)、如果是链表,则计算出列表的下标,并添加到新数组中去。

(4)、如果为红黑树,计算出红黑树每个元素对象的数组下标位置。

(4.1)、统计红黑树的下标个数。

(4.2)、如果超过了8个,则会产生新的红黑树,并将根点添加。

(4.3)、如果没有超过8个,则生成一个链表,并将链表插入新数组中去。

(5)、将新数组添加到HashMap对象的table属性中。

16、什么是字节码?使用字节码的好处?

编译器(javac)将java源文件(*.java)编译成为字节码文件(*.class)。

采用字节码的好处就是,一方面可以跨平台使用。另一方面编译器在编译源代码可以做一些编译器的优化,比如锁消除、标准替换、方法内联等。

17、Java中的异常分类?

(1)、Java中异常都来自于Throwable

(2)、Throwable下有俩个子类分别为Exception和Error。

(3)、Exception又分为RuntimeException(编译以后报错),和非RuntimeException(直接不能进行编译)。

18、Java中的类加载器?

JDK自带的有三个:bootstrap Classloader 、ExtClassLoader  、AppClassloader。

bootstrap Classloader 是 ExtClassLoader 的父类。加载lib下的jar包和class文件。

ExtClassLoader 是 AppClassloader的父类。加载lib/ext下的jar包class文件。

AppClassloader是 自定义类加载器的父类。负责加载classpath下的类文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

꧁༺๑小王不是程序员๑༻꧂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值