阿里巴巴面试题- - -Java体系最新面试题(十)

简介: ​目录基础篇37、有数组了为什么还要搞个 ArrayList 呢?通常我们在使用的时候,如果在不明确要插入多少数据的情况下,普通数组就很尴尬了,因为你不知道需要初始化数组大小为多少,而 ArrayList 可以使用默认的大小,当元素个数到达一定程度后,会自动扩容。可以这么来理解:我们常说的数组是定死的数组,ArrayList 却是动态数组。38、说说什么是 fail-fast?fail-fast 机制是 Java 集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。例如:

   前言:七月末八月初的时候,秋招正式打响,公司会放出大量的全职和实习岗位。为了帮助秋招的小伙伴们,学长这里整理了一系列的秋招面试题给大家,所以小伙伴们不用太过焦虑,相信你们一定能超常发挥,收到心仪公司的Offer~~

内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、Linux等技术栈

🌐 推荐一款找工作神器网站:《牛客网》 |笔试题库|面试经验|实习招聘内推|

image.gif编辑

目录

基础篇

37、有数组了为什么还要搞个 ArrayList 呢?

38、说说什么是 fail-fast?

39、说说Hashtable 与 HashMap 的区别

40、HashMap 中的 key 我们可以使用任何类作为 key 吗?

41、HashMap 的长度为什么是 2 的 N 次方呢?


基础篇

37、有数组了为什么还要搞个 ArrayList 呢?

通常我们在使用的时候,如果在不明确要插入多少数据的情况下,普通数组就很尴尬了,因为你不知道需要初始化数组大小为多少,而 ArrayList 可以使用默认的大小,当元素个数到达一定程度

后,会自动扩容。

可以这么来理解:我们常说的数组是定死的数组,ArrayList 却是动态数组。

38、说说什么是 fail-fast?

fail-fast 机制是 Java 集合(Collection)中的一种错误机制。当多个线程对同一个集合的内容进行操作时,就可能会产生 fail-fast 事件。

例如:当某一个线程 A 通过 iterator 去遍历某集合的过程中,若该集合的内容被其他线程所改变

了,那么线程 A 访问集合时,就会抛出 ConcurrentModificationException 异常,产生 fail-fast 事件。这里的操作主要是指 add、remove 和 clear,对集合元素个数进行修改。

解决办法:建议使用“java.util.concurrent 包下的类”去取代“java.util 包下的类”。

可以这么理解:在遍历之前,把 modCount 记下来 expectModCount,后面 expectModCount 去和 modCount 进行比较,如果不相等了,证明已并发了,被修改了,于是抛出

ConcurrentModificationException 异常。

39、说说Hashtable 与 HashMap 的区别

本来不想这么写标题的,但是无奈,面试官都喜欢这么问 HashMap。

1. 出生的版本不一样,Hashtable 出生于 Java 发布的第一版本 JDK 1.0,HashMap 出生于 JDK

1.2。

2. 都实现了 Map、Cloneable、Serializable(当前 JDK 版本 1.8)。

3. HashMap 继承的是 AbstractMap,并且 AbstractMap 也实现了 Map 接口。Hashtable 继承

Dictionary。

4. Hashtable 中大部分 public 修饰普通方法都是 synchronized 字段修饰的,是线程安全的,

HashMap 是非线程安全的。

5. Hashtable 的 key 不能为 null,value 也不能为 null,这个可以从 Hashtable 源码中的 put 方

法看到,判断如果 value 为 null 就直接抛出空指针异常,在 put 方法中计算 key 的 hash 值之

前并没有判断 key 为 null 的情况,那说明,这时候如果 key 为空,照样会抛出空指针异常。

6. HashMap 的 key 和 value 都可以为 null。在计算 hash 值的时候,有判断,如果

key==null,则其 hash=0;至于 value 是否为 null,根本没有判断过。

7. Hashtable 直接使用对象的 hash 值。hash 值是 JDK 根据对象的地址或者字符串或者数字算出

来的 int 类型的数值。然后再使用除留余数法来获得最终的位置。然而除法运算是非常耗费时

间的,效率很低。HashMap 为了提高计算效率,将哈希表的大小固定为了 2 的幂,这样在取

模预算时,不需要做除法,只需要做位运算。位运算比除法的效率要高很多。

8. Hashtable、HashMap 都使用了 Iterator。而由于历史原因,Hashtable 还使用了

Enumeration 的方式。

9. 默认情况下,初始容量不同,Hashtable 的初始长度是 11,之后每次扩充容量变为之前的

2n+1(n 为上一次的长度)而 HashMap 的初始长度为 16,之后每次扩充变为原来的两倍。

另外在 Hashtable 源码注释中有这么一句话:

Hashtable is synchronized. If a thread-safe implementation is not needed, it is recommended to use HashMap in place of Hashtable . If a thread-safe highly-

concurrent implementation is desired, then it is recommended to use

ConcurrentHashMap in place of Hashtable.

大致意思:Hashtable 是线程安全,推荐使用 HashMap 代替 Hashtable;如果需要线程安全高并发的话,推荐使用 ConcurrentHashMap 代替 Hashtable。

这个回答完了,面试官可能会继续问:HashMap 是线程不安全的,那么在需要线程安全的情况下还要考虑性能,有什么解决方式?

这里最好的选择就是 ConcurrentHashMap 了,但面试官肯定会叫你继续说一下

ConcurrentHashMap 数据结构以及底层原理等。

40、HashMap 中的 key 我们可以使用任何类作为 key 吗?

平时可能大家使用的最多的就是使用 String 作为 HashMap 的 key,但是现在我们想使用某个自定义类作为 HashMap 的 key,那就需要注意以下几点:

如果类重写了 equals 方法,它也应该重写 hashCode 方法。

类的所有实例需要遵循与 equals 和 hashCode 相关的规则。

如果一个类没有使用 equals,你不应该在 hashCode 中使用它。

咱们自定义 key 类的最佳实践是使之为不可变的,这样,hashCode 值可以被缓存起来,拥有更好的性能。不可变的类也可以确保 hashCode 和 equals 在未来不会改变,这样就会解决与可变相关的问题了。

41、HashMap 的长度为什么是 2 的 N 次方呢?

为了能让 HashMap 存数据和取数据的效率高,尽可能地减少 hash 值的碰撞,也就是说尽量把数据能均匀的分配,每个链表或者红黑树长度尽量相等。

我们首先可能会想到 % 取模的操作来实现。

下面是回答的重点哟:

取余(%)操作中如果除数是 2 的幂次,则等价于与其除数减一的与(&)操作(也就是说

hash % length == hash &(length - 1) 的前提是 length 是 2 的 n 次方)。并且,采用二进

制位操作 &,相对于 % 能够提高运算效率。

这就是为什么 HashMap 的长度需要 2 的 N 次方了。

42、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

来保证并发安全进行实现。

本期分享到此为止,关注博主不迷路,叶秋学长带你上高速~~

相关文章
|
2月前
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
5月前
|
缓存 Java 关系型数据库
2025 年最新华为 Java 面试题及答案,全方位打造面试宝典
Java面试高频考点与实践指南(150字摘要) 本文系统梳理了Java面试核心考点,包括Java基础(数据类型、面向对象特性、常用类使用)、并发编程(线程机制、锁原理、并发容器)、JVM(内存模型、GC算法、类加载机制)、Spring框架(IoC/AOP、Bean生命周期、事务管理)、数据库(MySQL引擎、事务隔离、索引优化)及分布式(CAP理论、ID生成、Redis缓存)。同时提供华为级实战代码,涵盖Spring Cloud Alibaba微服务、Sentinel限流、Seata分布式事务,以及完整的D
325 0
|
5月前
|
存储 安全 Java
常见 JAVA 集合面试题整理 自用版持续更新
这是一份详尽的Java集合面试题总结,涵盖ArrayList与LinkedList、HashMap与HashTable、HashSet与TreeSet的区别,以及ConcurrentHashMap的实现原理。内容从底层数据结构、性能特点到应用场景逐一剖析,并提供代码示例便于理解。此外,还介绍了如何遍历HashMap和HashTable。无论是初学者还是进阶开发者,都能从中受益。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
288 3
|
4月前
|
缓存 Java API
Java 面试实操指南与最新技术结合的实战攻略
本指南涵盖Java 17+新特性、Spring Boot 3微服务、响应式编程、容器化部署与数据缓存实操,结合代码案例解析高频面试技术点,助你掌握最新Java技术栈,提升实战能力,轻松应对Java中高级岗位面试。
449 0
|
4月前
|
Java 数据库连接 数据库
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
本文全面总结了Java核心知识点,涵盖基础语法、面向对象、集合框架、并发编程、网络编程及主流框架如Spring生态、MyBatis等,结合JVM原理与性能优化技巧,并通过一个学生信息管理系统的实战案例,帮助你快速掌握Java开发技能,适合Java学习与面试准备。
220 2
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
|
2月前
|
算法 Java
50道java基础面试题
50道java基础面试题
|
5月前
|
存储 安全 Java
2025 最新史上最全 Java 面试题独家整理带详细答案及解析
本文从Java基础、面向对象、多线程与并发等方面详细解析常见面试题及答案,并结合实际应用帮助理解。内容涵盖基本数据类型、自动装箱拆箱、String类区别,面向对象三大特性(封装、继承、多态),线程创建与安全问题解决方法,以及集合框架如ArrayList与LinkedList的对比和HashMap工作原理。适合准备面试或深入学习Java的开发者参考。附代码获取链接:[点此下载](https://pan.quark.cn/s/14fcf913bae6)。
2988 48
|
5月前
|
算法 架构师 Java
Java 开发岗及 java 架构师百度校招历年经典面试题汇总
以下是百度校招Java岗位面试题精选摘要(150字): Java开发岗重点关注集合类、并发和系统设计。HashMap线程安全可通过Collections.synchronizedMap()或ConcurrentHashMap实现,后者采用分段锁提升并发性能。负载均衡算法包括轮询、加权轮询和最少连接数,一致性哈希可均匀分布请求。Redis持久化有RDB(快照恢复快)和AOF(日志更安全)两种方式。架构师岗涉及JMM内存模型、happens-before原则和无锁数据结构(基于CAS)。
165 5
|
5月前
|
Java API 微服务
2025 年 Java 校招面试全攻略:从面试心得看 Java 岗位求职技巧
《2025年Java校招最新技术要点与实操指南》 本文梳理了2025年Java校招的核心技术栈,并提供了可直接运行的代码实例。重点技术包括: Java 17+新特性(Record类、Sealed类等) Spring Boot 3+WebFlux响应式编程 微服务架构与Spring Cloud组件 Docker容器化部署 Redis缓存集成 OpenAI API调用 通过实际代码演示了如何应用这些技术,如Java 17的Record类简化POJO、WebFlux构建响应式API、Docker容器化部署。
262 5