常见面试题05

简介: 本内容介绍了Java中常见概念的区别与原理,包括重载与重写、==与equals、String相关类的区别,以及HashMap的结构与执行流程。内容详实,适合Java开发者巩固基础知识。

重载与重写的区别

  • 重载是对象的方法之间,它们方法名相同,但方法的参数列表不同
  • 重写是父子类(包括接口与实现类)中两个同名方法,它们方法名相同,且方法的参数列表相同
  • 重载在编译阶段,由编译器根据传递给方法的参数来区分方法,例如
  • 而重写是在运行阶段,由虚拟机解释器去获取引用对象的实际类型,根据类型才能确定该调用哪个方法,例如
  • 有没有发生重写,可以使用 @Override 来检查

== 与 equals 的区别

  • 对于基本类型,== 是比较两边的值是否相同
  • 对于引用类型,== 是比较两边的引用地址是否相同,用来判断是否引用着同一对象
  • equals 要看实现
  • Object.equals(Object other) 的内部实现就是 ==,即判断当前对象和 other 是否引用着同一对象
  • 比如 String,它的内部实现就是去比较两个字符串中每个字符是否相同,比较的是内容
  • 比如 ArrayList,它的内部实现就是去比较两个集合中每个元素是否 equals,比较的也是内容

String,StringBuilder 和 StringBuffer 的区别

  • 它们都可以用来表示字符串对象
  • String 表示的字符串是不可变的,而后两者表示的字符串是内容可变的(可以增、删、改字符串里的内容)
  • StringBuilder 不是线程安全的,StringBuffer 是线程安全的,而 String 也算是线程安全的

适用场景

  • 大部分场景下使用 String 就足够了
  • 如果有大量字符串拼接的需求,建议用后两者,此时
  • 此字符串对象需要被多线程同时访问,用 StringBuffer 保证安全
  • 此字符串对象只在线程内被使用,用 StringBuilder 足够了

另外针对 String 类是 final 修饰会提一些问题,把握下面几点

  • 本质是因为 String 要设计成不可变的,final 只是条件之一
  • 不可变的好处有很多:线程安全、可以缓存等

HashMap 原理(数据结构)

底层数据结构:数组+链表+红黑树

接下来的回答中要点出数组的作用为啥会有冲突如何解决冲突

  • 数组:存取元素时,利用 key 的 hashCode 来计算它在数组中的索引,这样在没有冲突的情况下,能让存取时间复杂度达到 O(1)
  • 冲突:数组大小毕竟有限,就算元素的 hashCode 唯一,数组大小是 n 的情况下要放入 n+1 个元素,根据鸽巢原理,肯定会发生冲突
  • 解决冲突:一种办法就是利用链表,将这些冲突的元素链起来,当然在在此链表中存取元素,时间复杂度会提高为 O(n)

接下来要能说出为什么在链表的基础上还要有红黑树

  • 树化目的是避免链表过长引起的整个 HashMap 性能下降,红黑树的时间复杂度是 O(log{n})

有一些细节问题可以继续回答,比如树化的时机【进阶】

  • 时机:在数组容量达到 >= 64 链表长度 >= 8 时,链表会转换成红黑树
  • 如果树中节点做了删除,节点少到已经没必要维护树,那么红黑树也会退化为链表

HashMap 原理(扩容)

扩容因子:0.75 也就是 3/4

  • 初始容量 16,当放入第 13 个元素时(超过 3/4)时会进行扩容
  • 每次扩容,容量翻倍
  • 扩容后,会重新计算 key 对应的桶下标(即数组索引)这样,一部分 key 会移动到其它桶中

HashMap 原理(方法执行流程)

以 put 方法为例进行说明

  1. 产生 hash 码。
  1. 先调用 key.hashCode() 方法
  2. 为了让哈希分布更均匀,还要对它返回结果进行二次哈希,这个结果称为 hash
  3. 二次哈希就是把 hashCode 的高 16 位与低 16 位做了个异或运算
  1. 搞定数组。
  1. 如果数组还不存在,会创建默认容量为 16 的数组,容量称为 n
  2. 否则使用已有数组
  1. 计算桶下标。
  1. 利用 (n - 1) & hash 得到 key 对应的桶下标(即数组索引)
  2. 也可以用 hash % n 来计算,但效率比前面的方法低,且有负数问题
  3. 用 (n - 1) & hash 有前提,就是容量 n 必须是 2 的幂(如 16,32,64 ...)
  1. 计算好桶下标后,分三种情况
  1. 如果该桶位置还空着,直接根据键值创建新的 Node 对象放入该位置即可
  2. 如果该桶是一条链表,沿着链表找,看看是否有值相同的 key,有走更新,没有走新增
  • 走新增逻辑的话,是把节点链到尾部(尾插法)
  • 新增后还要检查链表是否需要树化,如果是,转成红黑树
  • 新增的最后要检查元素个数 size,如果超过阈值,要走扩容逻辑
  1. 如果该桶是一棵红黑树,走红黑树新增和更新逻辑,同样新增的最后要看是否需要扩容

目录
相关文章
|
7天前
|
人工智能 运维 安全
|
5天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
6天前
|
机器学习/深度学习 人工智能 自然语言处理
B站开源IndexTTS2,用极致表现力颠覆听觉体验
在语音合成技术不断演进的背景下,早期版本的IndexTTS虽然在多场景应用中展现出良好的表现,但在情感表达的细腻度与时长控制的精准性方面仍存在提升空间。为了解决这些问题,并进一步推动零样本语音合成在实际场景中的落地能力,B站语音团队对模型架构与训练策略进行了深度优化,推出了全新一代语音合成模型——IndexTTS2 。
588 20
|
12天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
949 110
|
6天前
|
人工智能 测试技术 API
智能体(AI Agent)搭建全攻略:从概念到实践的终极指南
在人工智能浪潮中,智能体(AI Agent)正成为变革性技术。它们具备自主决策、环境感知、任务执行等能力,广泛应用于日常任务与商业流程。本文详解智能体概念、架构及七步搭建指南,助你打造专属智能体,迎接智能自动化新时代。