- 【版权所有,文章允许转载,但须以链接方式注明源地址,否则追究法律责任】
- 【创作不易,点个赞就是对我最大的支持】
前言
仅作为学习笔记,供大家参考
每篇更新20道高频率面试题
适宜阅读人群
- 需要面试的初/中/高级 java 程序员
- 想要查漏补缺的人
- 想要不断完善和扩充自己 java 技术栈的人
- java 面试官
目录
- 前言
- 适宜阅读人群
- 一、Java 基础
- 61.jdk 中哪些类是不能继承的?
- 62.Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢?
- 63.JDK 和 JRE 的区别是什么?
- 64.是否可以在 static 环境中访问非 static 变量?
- 65.Java 支持多继承么?
- 66.什么是迭代器(Iterator)?
- 67.Iterator 和 ListIterator 的区别是什么?
- 68.Enumeration 接口和 Iterator 接口的区别有哪些?
- 69.List, Set, Map 是否继承自 Collection 接口?
- 70.字符串常量池到底存在于内存空间的哪里?
- 71.Java 中的编译期常量是什么?使用它又什么风险?
- 72.用哪两种方式来实现集合的排序?
- 73.说出 JDK 1.7 中的三个新特性?
- 74.说出 5 个 JDK 1.8 引入的新特性?
- 75.ArrayList 源码分析?
- 76.HashMap 源码分析?
- 77. ConcurrentHashMap 源码分析?
- 78.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
- 79.java 中的 Math.round(-1.5) 等于多少?
- 80.java 中操作字符串都有哪些类?它们之间有什么区别?
一、Java 基础
61.jdk 中哪些类是不能继承的?
不能继承的是类是那些用 final 关键字修饰的类。一般比较基本的类型或防止扩展类无意间破坏原来方法的实现的类型都应该是 final 的,在 jdk 中System,String,StringBuffer 等都是基本类型。
62.Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢?
Set 里的元素是不能重复的,元素重复与否是使用 equals()方法进行判断的。
equals()和==方法决定引用值是否指向同一对象 equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
63.JDK 和 JRE 的区别是什么?
Java 运行时环境(JRE)是将要执行 Java 程序的 Java 虚拟机。它同时也包含了执行 applet需要的浏览器插件。Java 开发工具包(JDK)是完整的 Java 软件开发包,包含了 JRE,编译器和其他的工具(比如:JavaDoc,Java 调试器),可以让开发者开发、编译、执行 Java 应用程序。
64.是否可以在 static 环境中访问非 static 变量?
static 变量在 Java 中是属于类的,它在所有的实例中的值是一样的。当类被 Java 虚拟机载入的时候,会对 static 变量进行初始化。如果你的代码尝试不用实例来访问非 static的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。
65.Java 支持多继承么?
不支持,Java 不支持多继承。每个类都只能继承一个类,但是可以实现多个接口。
66.什么是迭代器(Iterator)?
Iterator 接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代的过程中删除底层集合的元素。
克隆(cloning)或者是序列化(serialization)的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。
67.Iterator 和 ListIterator 的区别是什么?
下面列出了他们的区别:
Iterator 可用来遍历 Set 和 List 集合,但是 ListIterator 只能用来遍历 List。
Iterator 对集合只能是前向遍历,ListIterator 既可以前向也可以后向。
ListIterator 实现了 Iterator 接口,并包含其他的功能,比如:增加元素,替换元素,获
取前一个和后一个元素的索引,等等。
68.Enumeration 接口和 Iterator 接口的区别有哪些?
Enumeration 速度是 Iterator 的 2 倍,同时占用更少的内存。但是,Iterator 远远比Enumeration 安全,因为其他线程不能够修改正在被 iterator 遍历的集合里面的对象。同时,Iterator 允许调用者删除底层集合里面的元素,这对 Enumeration 来说是不可能的。
69.List, Set, Map 是否继承自 Collection 接口?
只有 List 和 Set 接口继承于 Collection 接口,Map 是与 Collection 并列的接口概念
70.字符串常量池到底存在于内存空间的哪里?
jdk 6.0 字符串常量池在方法区,方法区的具体体现可以看做是堆中的永久区。
jdk 7.0 java 虚拟机规范中不再声明方法区,字符串常量池存放在堆空间中
jdk 8.0 java 虚拟机规范中又声明了元空间,字符串常量池存放在元空间中
71.Java 中的编译期常量是什么?使用它又什么风险?
公共静态不可变(public static final )变量也就是我们所说的编译期常量,这里的 public 可选的。实际上这些变量在编译时会被替换掉,因为编译器知道这些变量的值,并且知道这些变量在运行时不能改变。这种方式存在的一个问题是你使用了一个内部的或第三方库中的公有编译时常量,但是这个值后面被其他人改变了,但是你的客户端仍然在使用老的值,甚至你已经部署了一个新的 jar。为了避免这种情况, 当你在更新依赖 JAR 文件时,确保重新编译你的程序。
72.用哪两种方式来实现集合的排序?
你可以使用有序集合,如 TreeSet 或 TreeMap,你也可以使用有顺序的的集合,如 list,然后通过 Collections.sort() 来排序。
73.说出 JDK 1.7 中的三个新特性?
虽 然 JDK 1.7 不 像 JDK 5 和 8 一 样的 大版 本 ,但 是, 还 是有 很多 新的 特 性, 如try-with-resource 语句,这样你在使用流或者资源的时候,就不需要手动关闭,Java 会自动关闭。Fork-Join 池某种程度上实现 Java 版的 Map-reduce。允许 Switch 中有 String 变量和文本。菱形操作符(<>)用于类型推断,不再需要在变量声明的右边申明泛型,因此可以写出可读写更强、更简洁的代码。另一个值得一提的特性是改善异常处理,如允许在同一个catch 块中捕获多个异常。
74.说出 5 个 JDK 1.8 引入的新特性?
Java 8 在 Java 历史上是一个开创新的版本,下面 JDK 8 中 5 个主要的特性: Lambda 表达式,允许像对象一样传递匿名函数 Stream API,充分利用现代多核 CPU,可以写出很简洁的代码 Date 与 Time API,最终,有一个稳定、简单的日期和时间库可供你使用 扩展方法,现在,接口中可以有静态、默认方法。 重复注解,现在你可以将相同的注解在同一类型上使用多次。
75.ArrayList 源码分析?
-
(1)ArrayList 是一种变长的集合类,基于定长数组实现,使用默认构造方法初始化出来的容量是 10(1.7 之后都是延迟初始化,即第一次调用 add 方法添加元素的时候才将elementData 容量初始化为 10)
-
(2)ArrayList 允许空值和重复元素,当往 ArrayList 中添加的元素数量大于其底层数组容量时,其会通过扩容机制重新生成一个更大的数组。ArrayList 扩容的长度是原长度的 1.5 倍
-
(3)由于 ArrayList 底层基于数组实现,所以其可以保证在 O(1) 复杂度下完成随机查找操作。
-
(4)ArrayList 是非线程安全类,并发环境下,多个线程同时操作 ArrayList,会引发不可预知的异常或错误。
-
(5)顺序添加很方便
-
(6)删除和插入需要复制数组,性能差(可以使用 LinkindList)
-
(7)Integer.MAX_VALUE - 8 :主要是考虑到不同的 JVM,有的 JVM 会在加入一些数据头,当扩容后的容量大于 MAX_ARRAY_SIZE,我们会去比较最小需要容量和 MAX_ARRAY_SIZE 做比较,如果比它大, 只能取 Integer.MAX_VALUE,否则是 Integer.MAX_VALUE -8。 这个是从 jdk1.7 开始才有的
76.HashMap 源码分析?
jdk1.8 之前 list + 链表
jdk1.8 之后 list + 链表(当链表长度到 8 时,转化为红黑树)
HashMap 的扩容因子默认 0.75,也就是会浪费 1/4 的空间,达到扩容因子时,会将 list 扩容一倍,0.75 是时间与空间一个平衡值;
77. ConcurrentHashMap 源码分析?
ConcurrentHashMap 所使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。有些方法需要跨段,比如 size()和 containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁。这里“按顺序”是很重要的,否则极有可能出现死锁,在 ConcurrentHashMap 内部,段数组是 final 的,并且其成员变量实际上也是 final 的,但是,仅仅是将数组声明为 final 的并不保证数组成员也是 final 的,这需要实现上的保证。这可以确保不会出现死锁,因为获得锁的顺序是固定的。
ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成。Segment 是一种可重入锁 ReentrantLock,在 ConcurrentHashMap 里扮演锁的角色,HashEntry 则用于存储键值对数据。一个 ConcurrentHashMap 里包含一个 Segment 数组,Segment 的结构和 HashMap类似,是一种数组和链表结构, 一个 Segment 里包含一个 HashEntry 数组,每个 HashEntry是一个链表结构的元素, 每个 Segment 守护者一个 HashEntry 数组里的元素,当对 HashEntry数组的数据进行修改时,必须首先获得它对应的 Segment 锁。
78.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
不对,两个对象的 hashCode()相同,equals()不一定 true。
代码示例:
String str1 = "温眉";
String str2 = "苏闻";
System.out.println(String.format("str1:%d | str2:%d", str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));
执行的结果:
str1:1179395 | str2:1179395
false
代码解读:很显然“温眉”和“苏闻”的 hashCode() 相同,然而 equals() 却为 false
因为在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。
79.java 中的 Math.round(-1.5) 等于多少?
运行结果: -1
JDK 中的 java.lang.Math 类
- round() :返回四舍五入,负 .5 小数返回较大整数,如 -1.5 返回 -1。
- ceil() :返回小数所在两整数间的较大值,如 1.5 返回 -1。
- tail() :返回小数所在两整数间的较小值,如 -1.5 返回 -2。
80.java 中操作字符串都有哪些类?它们之间有什么区别?
操作字符串的类有:
- String
- StringBuffer
- StringBuilder
三者区别:
- StringBuffer和StringBuilder都继承自抽象类AbstractStringBuilder。
- String 声明的是不可变的对象,每次操作都会生成新的 String 对象,然后将指针指向新的 String 对象
- StringBuffer、StringBuilder 存储数据的字符数组没有被final修饰,说明值可以改变,抽象类AbstractStringBuilder内部都提供了一个自动扩容机制,当发现长度不够的时候(初始默认长度是16),会自动进行扩容工作,扩展为原数组长度的2倍加2,创建一个新的数组,并将数组的数据复制到新数组,所以对于拼接字符串效率要比String要高。
- 线程安全性:StringBuffer由于很多方法都被 synchronized 修饰了所以线程安全,但是当多线程访问时,加锁和释放锁的过程很平凡,所以效率相比StringBuilder要低。StringBuilder相反执行效率高,但是线程不安全。
- 单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。 执行速度:StringBuilder > StringBuffer > String。
本文精选20道Java高频面试题,涵盖基础概念、集合框架、多线程、JDK新特性等内容,适合各阶段Java程序员查漏补缺。
&spm=1001.2101.3001.5002&articleId=108018204&d=1&t=3&u=a28c2d70c63640b9939586d5e2ef5eb4)
3229

被折叠的 条评论
为什么被折叠?



