尽量细的HashMap

1.HasMap基础

  • key-value形式

  • 用key做hash定位 整个将k和v存储到对应位置

2.解决hash冲突方法

  • 拉链法

  • 开放地址法

3.jdk1.7和1.8的区别

1.7

  • 头插法

  • hash()->4次扰动

  • 先扩容再插入

  • 数组+链表

1.8

  • 尾插法

  • hash()->1次扰动

  • 数组+链表/红黑树

    • 当前链表长度>=8 数组长度>64

  • 先插入再扩容

4. jdk1.8HashMap插入原理

  1. 判断数组是否为空,为空进行初始化;

  2. 不为空的,计算插入key的hash值,通过(n-1)&hash计算存放在数组的下标index;

  3. 查看是否存在数据,没有数据就构造一个Node存放其中;

  4. 存在数据,则证明发生了hash冲突(两个key的hash值一样),然后判断他的key是否相等,相等的话,用新值替换旧值

  5. 如果不相等,判断当前节点是否为树节点,如果是树形节点,插入红黑树中

  6. 如果不是树节点,插入链表中;然后判断链表长度是否大于8并且数组长度大于64,如果满足链表转换为红黑树

  7. 插入完成后判断节点数是否大于阈值,如果大于扩容为原来数组二倍

5.hashmap初始化

        一般如果new HashMap() 不传值,默认大小是16,负载因子是0.75, 如果自己传入初始大小k,初始化大小为 大于k的 2的整数次方,例如如果传10,大小为16。

6.hashmap的扩容机制

当数组长度达到(最大程度*负载因子(0.75))的就会扩容数组。扩容大小为原数组的二倍

扩容引子为什么为0.75:

  • 负载因子过大,虽然空间利用率上去了,但是时间效率降低了(大量的hash冲突)。

  • 负载因子太小,虽然时间效率提升了,但是空间利用率降低了

  • 负载因子是0.75的时候,空间利用率比较高,而且避免了相当多的Hash冲突,使得底层的链表或者是红黑树的高度比较低,提升了空间效率。

hashmap扩容为什么是2倍

HashMap计算添加元素的位置时,使用的(hash运算)位运算,这是特别高效的运算;另外,HashMap的初始容量是2的n次幂,扩容也是2倍的形式进行扩容,是因为容量是2的n次幂,可以使得添加的元素均匀分布在HashMap中的数组上,减少hash碰撞,避免形成链表的结构,使得查询效率降低!

位运算 :当HashMap的容量是2的n次幂时,(n-1)的2进制也就是1111111***111这样形式的,这样与添加元素的hash值进行位运算时,能够充分的散列,使得添加的元素均匀分布在HashMap的每个位置上,减少hash碰撞

7.hashmap为什么1.8采用红黑树

        链表的时间复杂度是O(n),红黑树的时间复杂度O(logn),很显然,红黑树的复杂度是优于链表的,红黑树拥有更高的查找性能

为什么不直接用红黑树:

        因为树节点所占空间是普通节点的两倍,所以只有当节点足够多的时候,才会使用树节点。红黑树的空间复杂度比较大,只有节点足够多,红黑树占空间大这一劣势不太明显的时候,才会舍弃链表,使用红黑树。

为什么是大于8才扩容

链表中节点数是8的概率已经接近千分之一,而且此时链表的性能已经很差了。所以在这种比较罕见和极端的情况下,才会把链表转变为红黑树。因为链表转换为红黑树也是需要消耗性能的,特殊情况特殊处理,为了挽回性能,权衡之下,才使用红黑树,提高性能。

1.8链表红黑树节点转化机制

节点数大于8转为红黑树 节点数小于6转化为链表

红黑树特点

红黑树核心是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。

  1. 节点是红色或黑色。

  2. 根节点是黑色。

  3. 所有叶子都是黑色。

  4. 从每个叶子到根的所有路径上不能有两个连续的红色节点

  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

红黑树是平衡二叉树 平衡二叉树的特点:

  1. 所有节点最多拥有两个子节点,即度不大于2;

  2. 左子树的键值小于根的键值,右子树的键值大于根的键值;

  3. 任何节点的两个子树的高度最大差为1。

8.为什么1.8将头插法改为尾插法

因为1.7头插法扩容时,头插法会使链表发生反转,多线程环境下会产生环

        A线程在插入节点B,B线程也在插入,遇到容量不够开始扩容,重新hash,放置元素,采用头插法,后遍历到的B节点放入了头部,这样形成了环,如下图所示:

9.hashmap是线程安全的,怎么解决

        不是,在多线程的情况下,1.7 会产生死循环数据丢失数据覆盖的问题,1.8 中会有数据覆盖的问题,

如何解决:

  • java中有hashTable(哈希表),ConcurrentHashMap可以实现线程安全的Map。

  • HashTable(全段锁)是直接在操作方法上加synchronized关键字,锁住整个数组,粒度比较大,

  • ConcurrentHashMap使用分段锁,降低了锁粒度,让并发度大大提高。

10.hashTable

  • Hashtable(线程安全,对整个结构加锁,性能不好)

  • 同样为Key-Value数据结构,但不允许key,value的值为null

  • 默认数组长度为11

  • 实现原理:数组+链表

11.ConcurrentHashMap

        Java7 中 ConcruuentHashMap 使用的分段锁,也就是每一个 Segment 上同时只有一个线程可以操作,每一个 Segment 都是一个类似 HashMap 数组的结构,它可以扩容,它的冲突会转化为链表。但是 Segment 的个数一但初始化就不能改变。

        Java8 中的 ConcruuentHashMap 使用的 Synchronized 锁加 CAS 的机制。结构也由 Java7 中的 Segment 数组 + HashEntry 数组 + 链表 进化成了 Node 数组 + 链表 / 红黑树,Node 是类似于一个 HashEntry 的结构。它的冲突再达到一定大小时会转化成红黑树,在冲突小于一定数量时又退回链表。

image-20200727163100466

12.ConcurrentHashMap的分段锁的实现原理

        ConcurrentHashMap成员变量使用volatile 修饰,免除了指令重排序,同时保证内存可见性,另外使用CAS操作和synchronized结合实现赋值操作,多线程操作只会锁住当前操作索引的节点。

13.ConcurrentHashMap和HashTable有什么区别?能否取代HashMap?

答:主要区别体现在实现线程安全的方式上

  1. 在jdk1.7时,ConcurrentHashMap采用分段锁方式对整个桶数组进行了分割分段(Segment)(其中segment继承自ReentrantLock)0每一把锁只锁容器中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提供了并发访问率; 到了jdk1.8,直接摒弃了Segment的概念,直接采用Node数组+链表+红黑树来实现,并发控制使用synchronized和CAS来操作。

  2. Hashtable则直接对整个结构加锁(synchronized)来保证线程安全,效率非常低下。当一个线程访问同步方法时,其它线程也访问同步方法,可能会进入阻塞或轮询状态,如果使用put添加元素,另一个线程就不能使用put添加元素,也不能使用get。

  3. 不能取代HashMap,Hashtable的任何操作都会把表锁住,是阻塞的,好处是总能够获取最实时的更新,ConcurrentHashMap为非阻塞的,在更新时会局部锁住某部分数据,但不会把整个表都锁住,同步读取操作是完全非阻塞的,在合理条件下效率非常高,坏处是在大量的读取操作时不能保证数据的实时更新。

14.HashMap是有序还是无序的,有序的map有哪些

hashmap是无序的,是根据hash值随机插入的\

有序的Map有那些

LinkedHashMap 和 TreeMap

15.LinkedHashMap

        LinkedHashMap可以认为是HashMap+LinkedList,也就是说,它使用HashMap操作数据结构,也用LinkedList维护插入元素的先后顺序.

LinkedHashMap的特点

  • key和value都允许为空

  • key重复会覆盖,value可以重复

  • 有序的

  • LinkedHashMap是非线程安全的

16.LinkedHashMap怎么实现有序的

        LinkedHashMap内部维护了一个单链表,有头尾节点,同时LinkedHashMap节点Entry内部除了继承HashMap的Node属性,还有before 和 after用于标识前置节点和后置节点。可以实现按插入的顺序或访问顺序排序。

17.TreeMap怎么实现有序的

        TreeMap是按照Key的自然顺序或者Comprator的顺序进行排序,内部是通过红黑树来实现。所以要么key所属的类实现Comparable接口,或者自定义一个实现了Comparator接口的比较器,传给TreeMap用于key的比较。        

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。
数字社区解决方案是一套综合性的系统,旨在通过新基建实现社区的数字化转型,打通智慧城市建设的"最后一公里"。该方案以国家政策为背景,响应了国务院、公安部和中央政法会议的号召,强调了社会治安防控体系的建设以及社区治理创新的重要性。 该方案的建设标准由中央综治办牵头,采用"9+X"模式,通过信息采集、案(事)件流转等手段,实现五级信息中心的互联互通,提升综治工作的可预见性、精确性和高效性。然而,当前社区面临信息化管理手段不足、安全隐患、人员动向难以掌握和数据资源融合难等问题。 为了解决这些问题,数字社区建设目标提出了"通-治-服"的治理理念,通过街道社区、区政府、公安部门和居民的共同努力,实现社区的平安、幸福和便捷。建设思路围绕"3+N"模式,即人工智能、物联网和数据资源,结合态势感知、业务分析和指挥调度,构建起一个全面的数据支持系统。 数字社区的治理体系通过"一张图"实现社区内各维度的综合态势可视化,"一套表"进行业务分析,"一张网"完成指挥调度。这些工具共同提升了社区治理的智能化和效率。同时,数字社区还提供了包括智慧通行、智慧环保、居家养老和便民服务等在内的多样化数字服务,旨在提升居民的生活质量。 在硬件方面,数字社区拥有IOT物联网边缘网关盒子和AI边缘分析盒子,这些设备能够快速集成老旧小区的物联设备,实现传统摄像设备的智能化改造。平台优势体现在数字化能力中台和多样化的应用,支持云、边、端的协同工作,实现模块化集成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值