当前位置: 首页 > news >正文

学做网站要什么基础/免费网站java源码大全

学做网站要什么基础,免费网站java源码大全,做英文网站要做适合已经的,上海做网站哪家正规HashMap底层数据结构在1.7与1.8的变化 1.7是基于数组链表实现的,1.8是基于数组链表红黑树实现的,链表长度达到8时会树化 使用哈希表的好处 使用hash表是为了提升查找效率,比如我现在要在数组中查找一个A对象,在这种情况下是无法…

HashMap底层数据结构在1.7与1.8的变化

1.7是基于数组+链表实现的,1.8是基于数组+链表+红黑树实现的,链表长度达到8时会树化

使用哈希表的好处

使用hash表是为了提升查找效率,比如我现在要在数组中查找一个A对象,在这种情况下是无法根据数组下标查找的,这样我们就需要从数组头部开始,将A对象与数组元素依次比较,直到找到A对象,这样显然是比较麻烦的,如果使用了hash表,我们只需要计算出A元素的hash值,通过hash值找到其在数组中的索引,就可以很快的找到A元素了,当然一个索引对应的很可能不止一个元素,所以需要使用数组+链表的形式,但如果链表的长度过长,查找时还是需要沿着链表一一比对,这样也是比较消耗性能的,为了避免链表长度过长造成的查找效率下降,有两种解决方案:1是数组扩容,2是链表树化

HashMap底层数组的扩容

底层数组默认长度是16,当数组使用超过最大长度的0.75(这个0.75被称为负载因子),则会对该数组进行扩容,扩容为原来长度的两倍,扩容结束之后,由于数组的长度发生了变化(元素位置的确定是由元素哈希值对数组长度取模),因此会重新计算集合元素在数组中的存储位置,因此扩容前存在的链表结构很可能会消失,这样也就在一定程度上解决了链表长度过长的问题

负载因子为什么选择0.75

  • 在空间占用与查询时间之间取得较好的权衡
  • 大于这个值,空间节省了,但链表就会比较长影响性能
  • 小于这个值,冲突减少了,但扩容就会更频繁,空间占用也更多

链表树化

链表的树化有两个必要条件,一是数组长度大于等于64,二是链表长度必须超过8,如果链表长度超过了8但是数组长度小于64,那么会直接对数组进行扩容(此时不考虑阈值的问题)而非将链表树化,也就是说在数组长度小于64时,链表长度是可能大于8的;当上述两个条件都满足时,链表会树化为红黑树,红黑树的一个特点是父节点左侧的都是比它小的元素,父节点右侧的都是比它大的元素,因此在元素较多的情况下,红黑树的查找效率就比链表要高很多了,这也就是jdk1.8使用数组+链表+红黑树的意义

链表的树化,我们还需要思考几个问题

  • 为什么不一上来就树化?

    在链表短时没有必要进行树化,在链表比较短的情况下,无论是查询还是更新,其性能都要高于红黑树,而且红黑树的内存占用比链表高,红黑树是由TreeNode组成的,而链表是由Node组成的,TreeNode的成员变量要比Node多很多,因此没有必要一上来就树化

  • 树化阈值为什么选择8?

    首先需要说明的是,虽然HashMap底层数据结构使用的是数组+链表+红黑树,但是正常情况下是几乎不可能出现红黑树的,如果hash 值足够随机,则在 hash 表内按泊松分布,在负载因子 0.75 的情况下,长度超过 8 的链表出现概率是 0.00000006(一亿分之六),之所以树化阈值选择 8 就是为了让树化几率足够小

正常情况下链表几乎不可能树化,红黑树存在的意义主要是用来避免 DoS 攻击的,是用来应对偶然情况的一种保底策略

红黑树退化成链表

链表会树化成红黑树,红黑树也会退化成链表,红黑树退化的场景:

  • 数组扩容时会对红黑树进行拆分,若拆分后树的元素小于等于6则退化为链表
  • remove任意一个树节点之前,若root(根节点)、root.left(根节点的左孩子)、root.right(根节点的右孩子)、root.left.left(根节点的左孙子) 有一个为 null ,那么remove完成后,树也会退化为链表

索引的计算过程

对象先调用其自身的hashCode方法计算出hash值,再由HashMap的hash方法对这个hash值进行二次hash,二次hash的结果再使用位与运算(hash值 & (数组长度 – 1)),得到这个对象在hash表中的索引

这个过程中也有几个问题需要思考

  • 数组容量为何要设计为2的n次幂?

    • 如果数组容量是2的n次幂,则位与运算与取模运算的结果是相同的,可以用位与运算代替取模运算,且效率更高;
    • 在数组扩容时,如果数组容量是2的n次幂,那么扩容时重新计算索引效率更高,只需要将链表中每个元素与oldCap(扩容前的容量)做位与运算,如果结果为0,那么说该元素在扩容后会保留在原位置,如果结果不为零,那么该元素在扩容后位置会发生变化,这样遍历下来,就可以把原来的链表拆分成两个链表,一是位置不需要移动的,二是位置需要移动的,在扩容后,位置需要移动的链表的新位置的索引=旧位置+oldCap
    • 容量设计为2的n次幂虽然可以提高计算索引时的效率,但是会导致hash的分布性变差,比如说我现在要存放一组较小的偶数,那么这些偶数就会集中在数组的偶数索引位置上(在没有经过二次hash的情况下),因此为了避免这种情况,需要进行二次hash;如果我们选择质数作为数组容量,那么hash的分布性是很好的,我们完全不需要进行二次hash,即使这样,HashMap仍然选择2的n次幂作为数组容量,是出于更看重效率的角度出发的
  • 为什么要进行二次hash?

    之所以要进行二次hash,是为了让hash分布的更为均匀,避免一组数据的hash值集中在某些索引上导致链表过长

Put元素流程

HashMap 是懒惰创建数组的,首次插入元素时才会去创建数组,假如说现在要插入一个元素A,流程如下:

  1. 计算出元素A的索引值

  2. 如果该索引上没有元素,则创建元素A的Node节点占位并返回

  3. 如果该索引上已经有元素了,则

    • 如果该索引位置上的元素是TreeNode,则走红黑树的添加或更新逻辑
    • 如果该索引位置上的元素是Node,则走链表的添加或更新逻辑,添加完毕后如果链表长度超过树化阈值,走树化逻辑

    是添加还是更新,需要比对元素A与其他元素的hash值,hash值不同走添加逻辑,hash值相同则调用元素的equals方法进行比对,返回false走添加逻辑,返回true走更新逻辑

  4. 返回前检查容量是否超过阈值,一旦超过则对数组进行扩容

上述过程中,1.7 的实现与 1.8 的实现有所不同:

  • 1.7 使用头插法,新增的元素会插入到链表头部;1.8 使用尾插法,新增的元素会插入到链表尾部
  • 1.7 是数组使用长度超过阈值,且再次put时,put的索引位置上已经有元素了才会去对数组扩容; 1.8 是使用长度超过阈值就会扩容
  • 1.8 在扩容计算 Node 索引时,会进行优化(这个优化上面提到过,1.7是没有这个优化的)

多线程下HashMap存在的问题

  • 数据丢失:假如现在HashMap索引为1的位置上是空的,现在有t1和t2两个线程同时希望在该位置上插入元素,假设此时t1希望插入元素A,那么首先t1线程需要检查该位置上是否已经存在元素,经过检查后发现不存在元素,正当t1线程准备插入元素时,发生了线程切换,CPU执行权给到了t2线程,t2线程将要插入元素B,那么它首先还是会去检查该位置是否存在元素,结果当然是也不存在,于是t2线程便在该位置上插入了元素B然后返回,如果此时执行权再次给到t1线程,那么t1线程插入元素A就会把原来位置上的元素B给覆盖,这样就丢失了一次数据更新
  • 并发扩容死链(存在于jdk1.7中):在1.7中,由于使用头插法,当两个线程同时对数组进行扩容时很有可能会产生死链(环形链表),此时一旦有任意查找元素的动作,线程将会进入死循环,导致CPU飙升;1.8使用尾插法避免了这一问题

HashMap的key是否为null,作为key的对象应该有哪些要求

  1. HashMap 的 key 可以为 null,Map 的其他实现则不然
  2. 作为 key 的对象,必须实现 hashCode 和 equals 方法,并且要保证 key 的内容不能修改(不可变),一旦key被修改了,那么其hash值就会发生变化,那么就无法找到其在hash表中的索引了
  3. key 的 hashCode 应该有良好的散列性

HashMap和HashTable的区别

  • HashMap线程不安全,HashTable线程安全(大多使用Synchronize修饰),所以相对来说HashMap要更快一些,这是最主要也是最重要的区别
  • HashMap的key和value都允许为null,而HashTable键值对都不能为空,否则会报空指针异常
  • HashMap在计算Hash值时需要二次Hash,而HashTable不需要,原因在于HashTable不使用2的n次幂来作为数组长度,Hash分布更加均匀
  • 接上一点,既然说了HashTable不使用2的n次幂来作为数组长度,那就需要提一下HashTable的扩容规则了,HashTable的数组扩容是扩容为原来的两倍加一,而HashMap是扩容为原来的两倍
  • Java8中HashMap使用数组+链表+红黑树的形式,而Java8中HashTable仍然是数组+链表

相关文章:

【一道面试题】关于HashMap的一系列问题

HashMap底层数据结构在1.7与1.8的变化 1.7是基于数组链表实现的,1.8是基于数组链表红黑树实现的,链表长度达到8时会树化 使用哈希表的好处 使用hash表是为了提升查找效率,比如我现在要在数组中查找一个A对象,在这种情况下是无法…...

论文笔记: Monocular Depth Estimation: a Review of the 2022 State of the Art

中文标题:单目深度估计:回顾2022年最先进技术 本文对比了物种最近的基于深度学习的单目深度估计方法: GPLDepth(2022)[15]: Global-Local Path Networks for Monocular Depth Estimation with Vertical CutDepthAdabins(2021)[1]: Adabins:…...

Springmvc补充配置

Controller配置总结 控制器通常通过接口定义或注解定义两种方法实现 在用接口定义写控制器时&#xff0c;需要去Spring配置文件中注册请求的bean;name对应请求路径&#xff0c;class对应处理请求的类。 <bean id"/hello" class"com.demo.Controller.HelloCo…...

MySQL 的 datetime等日期和时间处理SQL函数及格式化显示

MySQL 的 datetime等日期和时间处理SQL函数及格式化显示MySQL 时间相关的SQL函数&#xff1a;MySQL的SQL DATE_FORMAT函数&#xff1a;用于以不同的格式显示日期/时间数据。DATE_FORMAT(date, format) 根据格式串 format 格式化日期或日期和时间值 date&#xff0c;返回结果串。…...

基于微信云开发的防诈反诈宣传教育答题小程序

基于微信云开发的防诈反诈宣传教育答题小程序一、前言介绍作为当代大学生&#xff0c;诈骗事件的发生屡见不鲜&#xff0c;但却未能引起大家的重视。高校以线上宣传、阵地展示为主&#xff0c;线下学习、实地送法为辅&#xff0c;从而构筑立体化反诈骗防线。在线答题考试是一种…...

Map和Set

Map和set是一种专门用来进行搜索的容器或者数据结构&#xff0c;其搜索的效率与其具体的实例化子类有关。数据的一般查找方式有两种&#xff1a;直接遍历和二分查找。但这两种查找方式都有很大的局限性&#xff0c;也不便于对数据进行增删查改等操作。对于这一类数据的查找&…...

【位运算问题】Leetcode 136、137、260问题详解及代码实现

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...

同花顺2023届春招内推

同花顺2023届春招开始啦&#xff01; 同花顺是国内首家上市的互联网金融信息服务平台&#xff0c;如果你对互联网金融感兴趣&#xff0c;如果你有志向在人工智能方向发挥所长&#xff0c;如果你也是一个激情澎湃的小伙伴&#xff0c;欢迎加入我们&#xff01;岗位类别&#xf…...

深入Kafka核心设计与实践原理读书笔记第三章消费者

消费者 消费者与消费组 消费者Consumer负责定于kafka中的主题Topic&#xff0c;并且从订阅的主题上拉取消息。与其他消息中间件不同的在于它有一个消费组。每个消费者对应一个消费组&#xff0c;当消息发布到主题后&#xff0c;只会被投递给订阅它的消费组的一个消费者。 如…...

IDEA 中使用 Git 图文教程详解

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

【Linux系统】进程概念

目录 1 冯诺依曼体系结构 2 操作系统(Operator System) 概念 设计OS的目的 定位 总结 系统调用和库函数概念 3 进程 3.1 基本概念 3.2 描述进程-PCB 3.2 组织进程 3.3 查看进程 3.4 通过系统调用获取进程标示符 3.5 进程状态 在了解进程概念前我们还得了解下冯诺…...

上课睡觉(2023寒假每日一题 4)

有 NNN 堆石子&#xff0c;每堆的石子数量分别为 a1,a2,…,aNa_1,a_2,…,a_Na1​,a2​,…,aN​。 你可以对石子堆进行合并操作&#xff0c;将两个相邻的石子堆合并为一个石子堆&#xff0c;例如&#xff0c;如果 a[1,2,3,4,5]a[1,2,3,4,5]a[1,2,3,4,5]&#xff0c;合并第 2,32…...

【Selenium学习】Selenium 中常用的基本方法

1&#xff0e;send_keys 方法模拟键盘键入此方法类似于模拟键盘键入。以在百度首页搜索框输入“Selenium”为例&#xff0c;代码如下&#xff1a;# _*_ coding:utf-8 _*_ """ name:zhangxingzai date:2023/2/13 form:《Selenium 3Python 3自动化测试项目实战》 …...

python练习——简化路径

项目场景&#xff1a; 给你一个字符串 path &#xff0c;表示指向某一文件或目录的 Unix 风格 绝对路径 &#xff08;以 /开头&#xff09;&#xff0c;请你将其转化为更加简洁的规范路径。在 Unix 风格的文件系统中&#xff0c;一个点&#xff08;.&#xff09;表示当前目录本…...

2023新华为OD机试题 - 火星文计算2(JavaScript) | 刷完必过

火星文计算 2 题目 已知火星人使用的运算符号为#;$ 其与地球人的等价公式如下 x#y=4*x+3*y+2 x$y=2*x+y+3 x y是无符号整数 地球人公式按照 c 语言规则进行计算 火星人公式中#符优先级高于$ 相同的运算符按从左到右的顺序运算 输入 火星人字符串表达式结尾不带回车换行 输入…...

前端插件重磅来袭

“你值得拥有”专栏系列上新啦&#xff0c;今日推出“手写前端插件”项目&#xff0c;作为一个前端中高级工程师&#xff0c;手写前端树形菜单插件、弹出层插件、日历插件、分页插件、选项卡插件、进度条插件等是必备的技能&#xff0c;让你的前端技术百尺竿头更进一步&#xf…...

深入工厂|高精密多层板是如何被智造出来的?

或许有很多人从网络上见过各种教程&#xff0c;告诉你单层板是什么&#xff0c;多层板是什么&#xff0c;他们该如何做出来&#xff0c;但是在具体制造时却全凭想象&#xff0c;今天&#xff0c;就让我们来实地看看&#xff0c;精密的多层板是如何被制造出来的&#xff01;今天…...

代理模式动态代理

什么是代理模式&#xff1f; 代理模式是开发中常见的一种设计模式&#xff0c;使用代理模式可以很好的对程序进行横向扩展。代理&#xff0c;顾名思义就是一个真实对象会存在一个代理对象&#xff0c;并且代理对象可以替真实对象完成相应操作&#xff0c;外部通过代理对象来访…...

Mysql之二进制日志

目录 二进制日志 12-37 二进制日志格式 基于行的二进制日志 基于语句的二进制日志 混合格式二进制日志 复制日志 12-42 故障安全 (Crash-Safe) 复制 多源复制 二进制日志 12-37 二进制日志&#xff1a; • 包含数据和模式更改及其时间戳 – 基于语句 或 基于行 的日志…...

kail工具的使用--- cewl

1.介绍 Cewl是一款采用Ruby开发的应用程序&#xff0c;可以给他的爬虫指定URL地址和爬取深度&#xff0c;还可以添加外部链接&#xff0c;接下来Cewl会给你返回一个字典文件&#xff0c;你可以把字典用到类似John the Ripper这样的密码破解工具中。 2.使用 输入以下命令之后…...

【蓝桥杯集训1】前缀和专题(2 / 5)

目录 前缀和模板 &#xff01;3956. 截断数组 - 前缀和枚举 前缀和模板 活动 - AcWing import java.util.*;class Main {static int N100010;static int[] anew int[N],snew int[N];public static void main(String[] args){Scanner scnew Scanner(System.in);int nsc.nex…...

基于模块联邦的微前端实现方案

一、 微前端应用案例概述 当前案例中包含三个微应用&#xff0c;分别为 Marketing、Authentication 和 Dashboard Marketing&#xff1a;营销微应用&#xff0c;包含首页组件和价格组件 Authentication&#xff1a;身份验证微应用&#xff0c;包含登录组件 Dashboard&#x…...

【单目标优化算法】食肉植物优化算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

ANTLR4入门学习(四)

ANTLR4入门学习&#xff08;四&#xff09;一、设计语法1.语法2.ANTLR核心标记3.常见计算机语言模式4.左右递归5.识别常见的语法结构5.1 匹配标识符5.2 匹配数字5.3 匹配字符串常量5.4 匹配注释和空白字符5.5 基础的语法规则5.6 划定词法分析器和语法分析器的界线一、设计语法 …...

Android okhttp3中发送websocket消息,并通过mockwebserver将一个安卓设备模拟成服务器接发消息

websocket 提供了客户端和服务端的长链接&#xff0c;允许客户端和服务端双向发送消息 okhttp 提供了使用websocket 相关接口议。同时为方便单元测试&#xff0c;又提供了mockwebserver可以把一个安卓客户端作为服务端接受消息。 websocket使用 权限 <uses-permission an…...

MySQL系统变量和自定义变量

1 系统变量1.1 查看系统变量可以使用以下命令查看 MySQL 中所有的全局变量信息。SHOW GLOBAL VARIABLES; MySQL 中的系统变量以两个“”开头。global 仅仅用于标记全局变量&#xff1b;session 仅仅用于标记会话变量&#xff1b;首先标记会话变量&#xff0c;如果会话变量不存在…...

基于Python来爬取某音动态壁纸,桌面更香了!

至于小伙伴们想要这个封图&#xff0c;我也没有。不过继续带来一波靓丽壁纸&#xff0c;而且是动态的&#xff0c;我的桌面壁纸又换了&#xff1a;每天换着花样欣赏一波波动态壁纸桌面立刻拥有了高颜值&#xff0c;简直跟刷美女短视频一样啊。对的&#xff0c;这些动态壁纸就是…...

[数据库]表的约束

●&#x1f9d1;个人主页:你帅你先说. ●&#x1f4c3;欢迎点赞&#x1f44d;关注&#x1f4a1;收藏&#x1f496; ●&#x1f4d6;既选择了远方&#xff0c;便只顾风雨兼程。 ●&#x1f91f;欢迎大家有问题随时私信我&#xff01; ●&#x1f9d0;版权&#xff1a;本文由[你帅…...

VisualGDB 5.6R9 FOR WINDOWS

Go cross-platform with comfort VisualGDB 是 Visual Studio 的一个非常强大的扩展&#xff0c;它允许您调试或调试嵌入式系统。这个程序有一个非常有吸引力的用户界面&#xff0c;它有许多调试或调试代码的功能。VisualGDB 还有一个向导可以帮助您调试程序&#xff0c;为您提…...

Yolov8的多目标跟踪实现

Yolov8_tracking 2023年2月&#xff0c;Yolov5发展到yolov8&#xff0c;这世界变得真快哦。Yolov8由ultralytics公司发布&#xff0c;yolov6-美团&#xff0c;yolov7-Alexey Bochkovskiy和Chien-Yao Wang&#xff0c;其各有高招&#xff0c;对yolov5均有提升。mikel-brostrom在…...