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.rhkb.cn/news/36650.html

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

相关文章

谷歌or-tools开源库入门

1.命令行编译程序 这里要说明下&#xff0c;直接用qt或者VS2022打开cmake工程&#xff0c;编译没有成功。所以&#xff0c;老老实实的按照官方教程来&#xff0c;使用命令行编译。 &#xff08;1&#xff09;准备 1&#xff09;安装cmake&#xff0c;版本3.18以上&#xff0…

Python实现WYY音乐下载

一、需求背景 WYY音乐作为国内主流音乐平台,其歌曲资源丰富但下载接口存在多重加密保护。本文将通过Python结合JS逆向技术,解析其核心加密逻辑,实现免费歌曲的下载功能。 二、技术难点分析 1. 接口加密机制 通过抓包分析可知,网易云核心接口使用两次加密: 第一次:获取…

拥抱健康生活,开启养生之旅

在快节奏的现代生活中&#xff0c;健康养生愈发重要&#xff0c;它不仅能让我们保持良好状态&#xff0c;更是享受美好生活的基石。​ 饮食养生是健康的关键。我们应秉持均衡原则&#xff0c;一日三餐合理搭配。多摄入新鲜蔬果&#xff0c;它们富含维生素、矿物质与膳食纤维&a…

《Waf 火绒终端防护绕过实战:系统程序副本+Certutil木马下载技术详解》

目录 绕过火绒终端安全软件的详细方法 方法一&#xff1a;利用系统程序副本绕过命令监控 方法二&#xff1a;结合certutil.exe副本下载并执行上线木马 注意事项 总结 实际案例解决方案 前提条件 详细操作步骤 1. 攻击主机&#xff08;VPS&#xff09;上的准备工作 2.…

机器学习概要

文章目录 一、什么是机器学习 二、机器学习的种类 1. 有监督学习 2. 无监督学习 3.强化学习 三、机器学习的应用 四、机器学习的步骤 1. 数据的重要性 2. 数据和学习的种类 3. 可视化 一、什么是机器学习 机器学习指的是计算机根据给定的问题、课题或环境进行学习&a…

C# Winform 实现换肤,并自定义皮肤功能

具体实现原理详见 SkinHelp.cs类&#xff0c;实现了对原有控件的重绘&#xff0c;详见源码 public abstract class SkinHelp{private static SkinColor _currentSkinColor SkinColor.Default;private static BackgroundStripe _currentStripe BackgroundStripe.Default;priva…

基于FPGA的3U机箱模拟量高速采样板ADI板卡,应用于轨道交通/电力储能等

板卡简介&#xff1a; 本板为模拟量高速采样板&#xff08;ADI&#xff09;&#xff0c;主要用于电机转速和相电流检测&#xff0c;以实现电机闭环控制。 性能规格&#xff1a; 电源&#xff1a;DC5V&#xff0c;DC3.3V&#xff0c;DC15V&#xff0c;DC24V FPGA&#xff1a;…

python爬虫概述

0x00 python爬虫概述 以豆瓣的选电影模块为例&#xff0c;当查看源代码搜索猫猫的奇幻漂流瓶是搜不到的 这时服务器的工作方式应该是这样的 客户端浏览器第一次访问其实服务器端是返回的一个框架(html代码) 当客户端浏览器第二次通过脚本等方式进行访问时服务器端才返回的数据…

win10 如何用我的笔记本 接网线 远程控制 台式机

1.查看笔记本ip&#xff0c;台式机ip。确保在同一网段 可以ping通 1.1 ip在同一网段&#xff0c;但是ping不通 1.解决&#xff1a;把双方防火墙关闭 2.解决&#xff1a;当前网口&#xff0c;先禁用再启用 以上两台电脑就可以ping通了 2.设置双方电脑 启动远程控制 此电脑-》…

给管理商场消防安全搭建消防安全培训小程序全过程

一、需求沟通 “我是管理商场消防安全的嘛&#xff0c;做这个的作用呢&#xff0c;1是商场的所有商户员工可以看平面或者视频随时自学&#xff0c; 2是我们定期培训必修课程、考试&#xff0c;这个需要留存他们的手签字的签到表确认我们讲给他们听了&#xff08;免责很重要&am…

可视化图解算法:链表中倒数(最后)k个结点

1. 题目 描述 输入一个长度为 n 的链表&#xff0c;设链表中的元素的值为ai &#xff0c;返回该链表中倒数第k个节点。 如果该链表长度小于k&#xff0c;请返回一个长度为 0 的链表。 数据范围&#xff1a;0≤n≤105&#xff0c;0 ≤ai≤109&#xff0c;0 ≤k≤109 要求&am…

Quartz知识点总结

简单说明 简单的定时任务使用Timer或者ScheduledExecutorService quartz支持复杂的定时执行功能。支持ram存储&#xff08;内存存储&#xff09;和持久化存储。quartz有分布式和集群能力 简单使用 获取任务调度器Schedule。任务调度器可以管理任务。创建任务实例。使用JobB…

C语言每日一练——day_12(最后一天)

引言 针对初学者&#xff0c;每日练习几个题&#xff0c;快速上手C语言。第十二天。&#xff08;最后一天&#xff0c;完结散花啦&#xff09; 采用在线OJ的形式 什么是在线OJ&#xff1f; 在线判题系统&#xff08;英语&#xff1a;Online Judge&#xff0c;缩写OJ&#xff0…

【宇宙回响】从Canvas到MySQL:飞机大战的全栈交响曲【附演示视频与源码】

&#x1f31f; 这是星际大战系列的第三篇送福利文章&#xff0c;感谢一路以来支持和关注这个项目的每一位朋友&#xff01; &#x1f4a1; 文章力求严谨&#xff0c;但难免有疏漏之处&#xff0c;欢迎各位朋友指出&#xff0c;让我们一起在交流中进步。 &#x1f381; 项目代码…

数据结构知识点1

目录 一、时间复杂度和空间复杂度 1.1时间复杂度&#xff1a; 1.2空间复杂度&#xff1a; 二、装箱和拆箱 三、泛型 3.1泛型类的使用&#xff1a; 3.2泛型的上界&#xff1a; 3.3泛型方法&#xff1a; 一、时间复杂度和空间复杂度 1.1时间复杂度&#xff1a; 时间复杂…

华为ipd流程华为流程体系管理华为数字化转型流程数字化管理解决方案介绍81页精品PPT

华为流程体系最佳实践主要包括构建完善的流程框架&#xff0c;明确各层级流程要素与职责&#xff0c;梳理涵盖研发、采购、营销、服务、资产管理等多领域的流程&#xff0c;通过梳理业务场景和核心能力搭建差异化流程框架&#xff0c;采用自上而下与自下而上相结合的建模方法&a…

在大数据开发中ETL是指什么?

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在数字经济时代&#xff0c;数据已成为企业最核心的资产。然而&#xff0c;分散在业务系统、日志文件…

Collection系列集合的小结+集合并发修改异常问题

一、Collection系列集合的小结 二、补充知识&#xff1a;集合的并发修改异常问题 三、Collection的其他相关知识 1. 前置知识&#xff1a;可变参数 2. 集合的工具类&#xff1a;Collections 3. 综合案例&#xff1a;斗地主游戏 &#xff08;1&#xff09;创建Card类 public c…

QT Quick(C++)跨平台应用程序项目实战教程 2 — 环境搭建和项目创建

目录 引言 1. 安装Qt开发环境 1.1 下载Qt安装包 1.2 安装Qt 1.3 安装Visual Studio 2022 1.4 在Visual Studio 2022中安装Qt插件 1.5 在Visual Studio 2022中安装大模型编程助手 2. 创建Qt Quick项目 2.1 创建新项目 2.2 项目结构 2.3 运行项目 3. 理解项目代码 3…

免密登录远程服务器shell脚本

一、脚本代码 #!/bin/bash #提示用户输入用户i名和ip地址 read -p "请输入远程服务器的用户名: " hname read -p "请输入远程服务器的IP地址: " fip read -p "请输入远程服务器的远程端口:" sdk #检查是否配置了免密登录 function sfmm(){ …