java八股文之常见的集合

一、数组的索引为什么从0开始?

寻址公式: 数组的首地址+索引乘以存储数据的类型大小
在根据数组索引获取元素的时候,会用索引和寻址公式来计算内存所对应的元素数据。如果数组的索引从1开始,寻址公式中,就需要增加一次减法操作(数组的首地址-1),对于CPU来说就多了一次指令,性能会降低。

二、数组进行查找操作的时间复杂度

  • 如果是通过下标,查询的时间复杂度是O(1)
  • 如果不通过下标,和使用的查找方式有关
    – 从头往后顺序查找是O(n)
    – 排序后,使用二分查找发是O(log)

三、数组进行修改操作的时间复杂度

进行插入或者修改操作是,为了保证数组的连续性,需要挪动元素,平均复杂度是O(n)

四、ArrayList的底层实现原理

  • ArrayList底层是用动态的数组实现的
  • ArrayList初始容量为0,当第一次添加数据的时候才会初始化容量为10
  • ArrayList在进行扩容的时候是原来容量的1.5倍,每次扩容都需要拷贝数组
  • ArrayList在添加数据的时候
    1. 确保数组已使用长度(size)加1之后足够存下下一个数据
    2. 计算数组的容量,如果当前数组已使用长度+1后的大于当前的数组长度,则调用grow方法扩容,扩容为原来的1.5倍
    3. 确保新增的数据有地方存储之后,则将新元素添加到位于size的位置上。
    4. 返回添加成功布尔值。

五、List list = new ArrayList(10)中list扩容了几次

未进行扩容,该语句只是声明了一个长度为10的ArrayList。

六、数组和List之间如何转换

  • 数组转List
    – 调用Arrays.asList()方法
// 转换完成后,进行的修改会影响生成的List,因为只进行了地址的引用
String[] strArr = {"1","2"};
List<String> stringList = Arrays.asList(strArr);
  • List转数组
    – 调用list的toArray方法()
// 转换完成后,进行的修改不会影响生成的Array数组,因为底层进行了数据的拷贝
List<String> list = new ArrayList(n);
String[] toArray = list.toArray(new String[list.size()]);

七、单向链表和双向链表的区别是什么

  • 单向链表只有一个方向,结点只有一个后继指针next。
  • 双向链表它支持两个方向,每个结点不止有一个后继指针next指向后面的结点,还有一个前驱指针prev指向前面的结点
  • 单项链表的增删查操作时间复杂度在头结点是O(1),其他是O(n)。
  • 双向链表的增删查操作时间复杂度在头尾结点是O(1),其他是O(n),如果给定节点,则增删是O(1)

八、ArrayList好LinkedList区别是什么

  • ArrayList是动态数组的数据结构实现; LinkedList是双向链表的数据结构实现
  • ArrayList按照下标查询的时间复杂度O(1);LinkedList按照下标查询的时间复杂度O(n)
  • ArrayList插入或者删除元素的速度是O(n);LinkedList插入或者删除元素的速度是O(1)
  • ArrayList底层是连续的数组,占用内存更小;LinkedList是双向链表需要存储数据,和两个指针,更占用内存

线程方面
ArrayList和LinkedList都不是线程安全的,想要保证安全有两个方法

  1. 在方法内使用,局部变量大多数情况下是线程安全的(在内部开多线程或者引用了共享的变量就不安全了)
  2. 使用线程安全的ArrayList和LinkedList(用Collections.synchronizedList方法包一下)
// 性能会下降
List<Object> syncArrayList = Collections.synchronizedList(new ArrayList<>());
List<Object> syncLinkedList = Collections.synchronizedList(new LinkedList<>());

九、说一说二叉树和二叉搜索树

二叉树

  1. 每个节点最多有两个“叉”,分别是左子节点和右子节点。
  2. 不要求每个节点都有两个子节点,有的节点只有左子节点,有的节点只有右子节点。
  3. 二叉树每个节点的左子树和右子树也分别满足二叉树的定义

二叉搜索树

  1. 二叉搜索树(Binary Search Tree,BST)又名二叉查找树,有序二叉树
  2. 在树中的任意一食节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都大于这个节点的值
  3. 没有键值相等的节点
  4. 通常情况下二叉树搜索的时间复杂度为O(logn)

十、说一说红黑树

  1. 红黑树也是一种自平衡二叉树
  2. 红黑树的增删查时间复杂度都是O(logn)
  3. 红黑树节点要么是红色要么是黑色
  4. 红黑树节点根节点都是黑色,叶子结点也是黑色且为空值
  5. 红黑树红色节点的子节点都是黑色
  6. 从任意节点到叶子节点的所有路径都包含相同数目的黑色节点
  7. 红黑树所有规则都是为了保证平衡

十一、说一说散链表

  1. 散列表(Hash Table)又名哈希表/Hash表,是根据键(Key)直接访问在内存存储位置值(Value)的数据结构。是由数组演化而来的,利用了数组支持按照下标进行随机访问数据
  2. 散列表的key是根据hash计算得来的,相同和key算出来的hash值一定相同。当不同的key计算出相同的hash值时,就会发生散列冲突,又名哈希碰撞
  3. 解决散列表冲突方方法是链表法,又名拉链。存储hashkey数组的每个下标位置称之为桶(bucket)或者槽(slot),每个桶会对应一条链表。hash冲突后的元素都放到相同的桶对应的链表中或红黑树中。

十二、说一说HashMap的实现原理

  1. HashMap的底层的数据结构是hash表,即数组加链表或数组加红黑树
  2. 当我们往HashMap中put元素时,利用寻址算法算出当前对象的元素在数组中的下标。此时如果出现hash值相同的key会再次对key进行比较:如果key相同,则覆盖原始值;如果key不同,则将当前的key-value放入链表或红黑树中
  3. 获取时,寻址算法得到对应的桶索引位置,在进一步判断key是否相同,从而找到对应值。
  4. jdk1.8之后当链表的长度大于8且数组长度大于64时,会转换为红黑树;扩容resize()时,红黑树拆分成的树的结点数小于等于临界值6个,则退化成链表

十三、说一说HashMapput方法的具体流程

  1. 判断键值对数组table是否为空或为null,否则执行resize()进行扩容(初始化)
  2. 根据寻址算法得到对应的桶索引位置table[i]
  3. 判断table[i]==null,条件成立,直接新建节点添加
  4. 如果table[i]==null,不成立
    4.1 判断table[i的首个元素是否和key一样,如果相同直接覆盖value
    4.2 判断table[i]是否为treeNode,即table[i]是否是红黑树,如果是红黑树,则直接在树中插入键值对
    4.3 否则遍历table[i],链表的尾部插入数据,然后判断链表长度是否大于8,大于8的话把链表转换为红黑树,在红黑树中执行插入操作,若遍历过程中若发现key已经存在则直接覆盖value
  5. 插入成功后,判断实际存在的键值对数量size是否超过了最大容量threshold(数组长度*0.75),如果超过,进行扩容。

十四、说一说HashMap的扩容机制

  1. 在添加元素或初始化的时候需要调用resize方法进行扩容,第一次添加数据初始化数组长度为16,以后每次扩容都是达到了扩容阈值(数组长度*0.75)
  2. 每次扩容的时候,都是扩容之前容量的2倍;
  3. 扩容之后,会新创建一个数组,需要把老数组中的数据挪动到新的数组中
    – 没有hash冲突的节点,则直接使用e.hash&(newCap-1)计算新数组的索引位置(newCap是新数组长度)
    – 如果是红黑树,走红黑树的添加
    – 如果是链表,则需要遍历链表,可能需要拆分链表,判断(e.hash&oldCap)是否为0,为0该元素的位置停留在原始位置,否则移动到原始位置+增加的数组大小这个位置上(oldCap是老数组长度)

十五、说一说HashMap的寻址算法

  1. 计算对象的hashCode()
  2. 再进行调用hash()方法进行二次哈希,hashcode值右移16位再异或运算,让哈希分布更为均匀
  3. 最后(capacity-1)&hash得到索引。这个运算相当于hash%capacity且更快,但是这个只对2的幂数生效

十六、为何HashMap的数组长度一定是2的次幂?

  1. 计算索引时效率更高:如果是2的n次幂可以使用位与运算代替取模
  2. 扩容时重新计算索引效率更高:hash&oldCap==0的元素留在原来
    位置,否则新位置=旧位置+oldCap

十七、说一说hashmap在jdk1.7情况下的多线程死循环问题

在jdk1.7的hashmap中在数组进行扩容的时候,因为链表是头插法,在进行数据迁移的过程中,有可能导致死循环

比如说,现在有两个线程
线程一:读取到当前的hashmap数据,数据中一个链表,在准备扩容时,线程二介入
线程二:也读取hashmap,直接进行扩容。因为是头插法,链表的顺序会进行颠倒过来。比如原来的顺序是AB,扩容后的顺序是BA,线程二执行结束。
线程一:继续执行的时候就会出现死循环的问题。
线程一先将A移入新的链表,再将B插入到链头,由于另外一个线程的原因,B的next指向了A,所以B->A->B,形成循环。
当然,JDK8将扩容算法做了调整,不再将元素加入链表头(而是保持与扩容前一样的顺序),尾插法,就避免了jdk7中死循环的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/73820.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用ASCII字符转化图片

代码 from PIL import Image# 定义 ASCII 字符集&#xff0c;从最暗到最亮 ASCII_CHARS "%#*-:. "def resize_image(image, new_width100):width, height image.sizeratio height / widthnew_height int(new_width * ratio)resized_image image.resize((new_wi…

详解Sympy:符号计算利器

Sympy是一个专注于符号数学计算的数学工具&#xff0c;使得用户可以轻松地进行复杂的符号运算&#xff0c;如求解方程、求导数、积分、级数展开、矩阵运算等。其中比较流行的深度学习框架pytorch的用到了Sympy,主要用于将模型的计算图转换为符号化表达式&#xff0c;以便进行分…

高频SQL 50 题(持续更新)

SQL的编写与运用 0. 写在前面 最近学习了数据库系统概论&#xff0c;其中涉及到了关于SQL语句的编写&#xff0c;感觉理论知识不足以让我掌握相关的编写方式&#xff0c;因此选择刷力扣上的题目进行复习巩固。 时间不是很多&#xff0c;可能不会经常更新&#xff0c;有时间写…

【Python】12、函数-02

文章目录 1. 返回值2.文档字符串3. 作用域4. 命名空间 1. 返回值 返回值就是函数执行以后返回的结果&#xff0c;可以通过return来指定函数的返回值。返回值可以通过变量接收返回值 return 后可以返回任意的对象&#xff0c;甚至是一个函数如果仅写一个return或者不写return&…

Unity插件-适用于画面传输的FMETP STREAM使用方法(三)基础使用

目录 一、插件介绍 二、组件介绍 三、Game View Streaming 1、使用 FM Network UDP 的基本设置 Server Scene Client Scene 2、使用使用 FM WebSocket 的基本设置 四、Audio Streaming 五、Microphone Streaming 一、插件介绍 ​​​​​​Unity插件-适用于画面传输的…

如何为预训练模型进行领域适配:全参数微调、LoRA 还是 Prompt Tuning?

目录 如何为预训练模型进行领域适配&#xff1a;全参数微调、LoRA 还是 Prompt Tuning&#xff1f; 1. 全参数微调&#xff08;Full Fine-tuning&#xff09; 适用场景 优缺点 示例代码&#xff08;使用 Hugging Face Transformers 进行全参数微调&#xff09; 2. LoRA&am…

C++ —— 线程同步(互斥锁)

C —— 线程同步&#xff08;互斥锁&#xff09; 线程同步互斥锁&#xff08;互斥量&#xff09;测试代码mutex互斥锁 线程同步 线程同步&#xff1a;多线程协同工作&#xff0c;协商如何使用共享资源。 C11线程同步包含三部分内容&#xff1a; 互斥锁&#xff08;互斥量&…

UI设计中的加载动画:优化用户体验的细节

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在数字产品泛滥的今天&#xff0c;用户对体验的要求早已超越功能本身。一个看似简单的加载动画&…

SpringBoot3+Vue3实战(Vue3快速开发登录注册页面并对接后端接口)(4)

目录 一、SpringBoot3Vue3实现基本增删改查。前后端通信交互、配置后端跨域请求。数据批量删除。(博客链接) 二、SpringBoot3Vue3快速开发登录、注册页面并实现对接。 &#xff08;1&#xff09;操作数据表employee(员工信息表)。 <1>修改employee表的字段组成。 <2&g…

Python标准库中bisect模块的bisect_right()函数在网格交易中的应用

本文将深入探讨Python标准库中bisect模块的bisect_right()函数在网格交易中的具体应用。 bisect模块 bisect模块是Python标准库中的一个模块&#xff0c;提供了对有序列表的插入和搜索操作的支持。它基于二分查找算法&#xff0c;可以高效地在有序列表中查找或插入元素&#x…

Excel(函数篇):IF函数、FREQUNCY函数、截取函数、文本处理函数、日期函数、常用函数详解

目录 IF函数等于判断区间判断与AND函数、OR函数一同使用IFNA函数和IFERROR函数 FREQUNCY函数、分断统计LEFT、RIGHT、MID截取函数FIND函数、LEN函数SUBSTITUTE函数ASC函数、WIDECHAR函数实战&#xff1a;如何获取到表中所有工作簿名称文本处理函数TEXT函数TEXTJOIN函数 日期函数…

生成PDF文件:从html2canvas和jsPdf渲染到Puppeteer矢量图

刚刚实现而已&#xff1a;第一次明白&#xff0c;双击或file:///打开html文件&#xff0c;居然和从localhost:3000打开同一个html文件有本质的区别。 字体居然还能以Base64代码嵌入到网页&#xff0c;只是太大太笨。 需要安装node.js&#xff0c;npm安装更多依赖&#xff1a;…

Git 分支删除操作指南(含本地与远程)

&#x1f680; Git 分支删除操作指南&#xff08;含本地与远程&#xff09; 在多人协作的开发过程中&#xff0c;定期清理已合并的临时分支&#xff08;如 feature/*、bugfix/*、hotfix/* 等&#xff09;可以保持仓库整洁&#xff0c;避免混乱。 &#x1f4cc; 分支命名规范回…

Qt中打开windows的cmd窗口并显示

在windows上&#xff0c;用Qt的GUI程序打开另一个程序&#xff0c;使用QProcess即可&#xff0c;并且被打开的程序通常也会显示出来&#xff0c;但是如果想要打开dos窗口并显示&#xff0c;并执行其中的命令或者批处理&#xff0c;则需要使用QProcess提供的windows特有的函数QP…

Modbus TCP到RTU:轻松转换指南!

Modbus TCP 到 RTU&#xff1a;轻松转换指南&#xff01; 在现代工业自动化领域&#xff0c;Modbus TCP和Modbus RTU两种通信协议因其高效、稳定的特点被广泛应用。然而&#xff0c;随着技术的发展和设备升级的需求&#xff0c;经常会遇到需要将这两种协议进行互相转换的场景。…

微信小程序订阅消息发送消息,点击消息进入小程序页面

1、在小程序官网订阅消息选用或创建消息模板获取模板ID可多个 如图&#xff1a; 2、微信小程序前端页面发送请求订阅权限 请求模板id的权限可以是一个可以是多个&#xff0c;用户同意订阅&#xff0c;获取code传递给后端——后端拿到code生成唯一的openid用于发送订阅消息 注…

卷积神经网络 - 卷积层

卷积神经网络一般由卷积层、汇聚层和全连接层构成&#xff0c;本文我们来学习卷积层。 卷积层&#xff08;Convolutional Layer&#xff09;是卷积神经网络&#xff08;CNN&#xff09;的核心组件&#xff0c;专门用于处理具有网格结构的数据&#xff08;如图像、音频、时间序…

Vue3全局化配置(ConfigProvider)

效果如下图&#xff1a; 在线预览 APIs ConfigProvider 参数说明类型默认值theme主题对象Theme{}abstractboolean是否不存在 DOM 包裹元素truetagstringConfigProvider 被渲染成的元素&#xff0c;abstract 为 true 时有效‘div’ Theme Type 名称说明类型默认值common?全…

LabVIEW烟气速度场实时监测

本项目针对燃煤电站烟气流速实时监测需求&#xff0c;探讨了静电传感器结构与速度场超分辨率重建方法&#xff0c;结合LabVIEW多板卡同步采集与实时处理技术&#xff0c;开发出一个高效的烟气速度场实时监测系统。该系统能够在高温、高尘的复杂工况下稳定运行&#xff0c;提供高…

若依excel工具类导出excel模板数据带下拉映射

导出模板代码&#xff0c;原理是combo属性 传递一个数组 里面是label下拉数组。 Overridepublic void downloadTemplate(HttpServletResponse response) {ExcelUtil<ThMachineryManageExcel> util new ExcelUtil<>(ThMachineryManageExcel.class);List<SysDist…