精华内容
下载资源
问答
  • HashMap是一个用于存储Key-Value键值对的集合,每一个键值对对象叫做Entry,这些键值对(entry)储存在一个数组中。 对于hashmap,我们最常用的就是get和put方法,那么这个方法具体做了什么事情? put方法: 比如...

    hashmap

    HashMap是一个用于存储Key-Value键值对的集合,每一个键值对对象叫做Entry,这些键值对(entry)储存在一个数组中。

    对于hashmap,我们最常用的就是get和put方法,那么这两个方法具体做了什么事情?
    put方法: 比如调用hashmap.put(name,tang); 首先会调用hash函数来决定键值对插入数组的索引,假设算出来的索引为3.在这里插入图片描述
    但是当多次put之后,难免会出现又一个键值对,hash函数后索引也为3.这就是哈希冲突。

    这个时候,我们采用链表来解决问题,也就是说,hashmap的底层是链表加上数组。每个Entry对象也是链表的头节点,它的next指向下一个Entry对象,也就是哈希冲突的对象。(tip:采用头插法插入,因为默认后插入的键值对有更大几率被使用

    在这里插入图片描述
     
    get方法:它首先会对key做一次hash映射,然后对得到的索引进行查找,按照链表从头到尾,比对key值。

    hash map的初始值是多少,又是如何进行哈希运算的?
    hashmap的默认初始值为16,每次进行手动初始化,或者自动扩容时都是2的幂次方。

    hashmap没有采用简单的hashcode(key)%length的取模运算,因为它的效率底下。而采用了index = HashCode(Key) & (Length - 1) 这种位运算的方式。这种方式不仅高效,而且最大化的使得到的索引值均匀分布。

    这也是为什么要求值必须是2的幂次方,因为只有此时length-1得到的二进制数是全1,最后的结果就是hashcode值的最后几位,这样能使得到的索引值均匀分布。

     

    jdk1.8之后

    在jdk1.8之后,hashmap的底层加入的红黑树结构,也就是底层变成了数组,链表和红黑树。它主要是为了防止一种极端情况,也就是当所以的hash运算后的索引都是一个值,就会使某一个数组下标的链表过长,降低效率。而加入了红黑树后,当我们的链表长度达到8后就会使链表变成红黑树结构,将最坏情况下的性能从O(n)降低成了O(lgn)。

    此时完整的put方法
    1.若hashmap未被初始化,就执行初始化操作。
    2.对key进行hash取模运算,得到索引值。
    3.若未发生碰撞就放入数组对应下标。
    4.若发生碰撞,则以头插法插入链表。
    5.链表长度超过8时,将链表结构转换为红黑树,当长度低于6时将红黑树变为链表。
    6.若节点已经存在,就替换它
    7.当数组内的键值对满了,也就是(16(默认初始化长度)*0.75(扩容因子))时,resize(扩容两倍后重排)

    关于扩容的过程:主要是两步
    1.创建一个新的Entry(1.8后改名为Node)数组,长度是原来的两倍。

    2遍历原数组,将所有元素重新hash到新数组中。

     

    ConcurrentHashMap

    hashmap不是线程安全的,它可能产生环形链表(暂不深究),此时我们可以使用ConcurrentHashMap来保证线程安全。hashtable也可以保证线程安全,但它是建议保留的。并且它会锁住整个集合,性能低下。

    早期的ConcurrentHashMap将整个集合拆分为segment,segment也是hashmap对象,所以ConcurrentHashMap的结构大概如下:
    在这里插入图片描述
    ConcurrentHashMap通过更细粒化的分为segment,只锁住一个segment来提高性能。

    1.8之前的put方法过程:
    1.对key做hash运算定位到segment对象。
    2.获得可重入锁
    3.再次hash运算得到数组中具体的位置
    4.执行操作,释放锁(注意使用两次hash

    1.8之后put方法的过程是
    1.判断hash map是否被初始化,若未初始化,则进行初始化操作。
    2.通过hash得到索引,若索引处没有Node对象,则用CAS进行添加,添加失败则重试。
    3.如果索引处存在Node对象,则用synchornized锁住此元素,进行添加操作。
    4.判断链表长度是否达到8,若是,则将链表转换为红黑树。

    ConcurrentHashMap在jdk1.8之后相比以前有什么区别?
    ConcurrentHashMap的锁更加细粒化了,早期是锁住整个segment,现在是锁住某个Node对象。现在是用CAS和synchornized来实现线程安全的。

    展开全文
  • 如果预算不多,似乎小米游戏本可以作为考虑对象,虽然他们依然停留在九代酷睿平台,但不得不说这价格太便宜了,如果拿价格做对比似乎没什么对手。小米游戏本到目前为止已经出了代,最新的产品依然是九代酷睿的,...

    现在游戏本市场并存两大现象,第一是十代酷睿已经大行其道,并且几乎和AMD平台贴身肉搏,第二是很多热门产品都缺货或者涨价,让不少消费者不知道如何选。在这种情况下该选什么笔记本呢?如果预算不多,似乎小米游戏本可以作为考虑对象,虽然他们依然停留在九代酷睿平台,但不得不说这价格太便宜了,如果拿价格做对比似乎没什么对手。

    f75afcda8df5f053a716d3d0f5a9f353.png

    小米游戏本到目前为止已经出了两代,最新的产品依然是九代酷睿的,目前没有更新产品。其实总体上看,小米游戏本的战略根本算不上成功,这主要是因为这个品牌的时间节奏把控非常不好,在九代酷睿上市的时候推八代产品,在十代酷睿上市的时候推九代产品。其他方面短板倒是并不明显,被说得最多的噪音问题,其实也通过后来更新BIOS改善了很多。

    036eeaf88d012b52962fe6442029eb01.png

    当然,笔记本另一个地方也被吐槽很多,那就是键盘。虽然是15.6英寸笔记本,没有小键盘的设计让一些人不太喜欢。其他应该没什么短板了,金属机身设计,硬件配置上是九代酷睿i5-9300H处理器,搭配8GB内存和512GB SSD,显卡为GTX1660Ti,这款产品发布时价格为7499元,而现在售价只要5799元。同样价格还能买什么样的游戏本?质感、做工等方面必定是不及小米这款的。

    a5854792238649c77a9ff30d2a9fefac.png

    和前代相比,这个新版本扩展性方面稍有削弱,主要是去掉了唯一的USB type-C接口,原因就不知道了。造型方面,小米游戏本采用了冷色系配色,除了键盘灯之外几乎看不出这是一款游戏本,这种造型决定了它拥有百搭属性,而不像某些游戏本那样过于张扬。关注游戏本的各位不难发现,如今已经越来越流行这样风格,毕竟除了玩游戏之外,大家都是打工人。而游戏本的性能,对于日常工作来说也是非常合适的。

    d51f9a9e666bacd825e67d8d59cff83e.png

    这样的笔记本性能够用吗?其实是非常够用的,而且基于这个价格来说更是够用。这款笔记本唯一的短板大概就是8GB内存,买回来如果加一条升级成16GB双通道,性能就完全够用了。硬盘方面也可以增加一款,但要在M.2和2.5英寸之间二选一,网上似乎也有将两个扩展接口全部用上的方法。

    6f0ff8ad2575c6bb7c12c0d7b4c24eb8.png

    总体来看,颜值、性能、价格,小米游戏本都已经非常合适,这款笔记本的不成功是因为它在不合适的时间推出不合适的产品,而不是产品本身有什么问题。当然刚发布时缺少价格优势也是主要原因,现在这些都不叫问题。5799元还能买啥?这就是它最值得说的卖点。

    展开全文
  • 下面来说说引用计数法是如何统计所有对象的引用计数的,再对比分析可达性算法是如何解决引用技术算法的不足,好比说循环引用。循环引用 举个栗子:有对象,A引用B,B引用A。 这种情况下对象都存在引用,...

    目前的GC算法有两个大分类:引用计数可达性。下面来说说引用计数法是如何统计所有对象的引用计数的,再对比分析可达性算法是如何解决引用技术算法的不足,好比说循环引用。

    循环引用
    举个栗子:有两个对象,A引用B,B引用A。
    这种情况下两个对象都存在引用,那么是否这两个对象就无法被GC了呢?先卖个关子,让我们记住这种情况,带着疑问往下读,接下来了解一下GC算法的一些概念。

    GC采用的算法
    1.引用计数算法:每个对象都有一个引用计数器,当对象被引用时计数器+1,对象引用失效的时候,引用计数器-1,当计数为0的时候,意味着此对象是一个垃圾对象,可以被gc了。

    2.可达性算法:从GC Roots作为起点开始搜索,对于GC Roots无法到达的对象便成了垃圾回收对象,随时可被gc掉。常见的可达性算法有标记、清除法。

    对这两种算法有一定的了解之后,我们来观看下面这两个图(以下图片均来自知乎):

    引用计数法
    这里写图片描述
    (图一)
    这里有四个step:
    · step1:Java堆中实例1引用计数+1,当前计数为1;
    · step2:Java堆中实例2引用计数+1,当前计数为1;
    · step3:Java堆中实例2引用计数+1,当前计数为2;
    · step4:Java堆中实例1引用计数+1,当前计数为2。

    四个步骤下来,堆中实例1计数=堆中实例2计数=2。

    接下来再看一图:
    这里写图片描述
    (图二)
    我们看到step1跟step2的连线已经消失了。也就是栈帧中的obj1跟obj2不再指向Java堆中的实例了。我们拆分成两个步骤(step5、step6),这时:

    · step5:obj1不再指向实例1,引用数-1,当前计数为2-1=1;
    · step6:obj2不再指向实例1,引用数-1,当前计数为2-1=1。

    我们发现,实例1和实例2的计数都不为0,如果采用引用计数法的话,那么这两个实例所占用的内存就得不到释放了。所以,引用计数法无法解决循环利用
    的gc问题。

    那么,可达性算法就可以吗?它是如何操作的?

    上面提到的可达性算法的概念,有个字眼-GC Roots

    可以作为GC Roots的对象
    · 虚拟机栈的栈帧的局部变量表所引用的对象;
    · 本地方法栈的JNI所引用的对象;
    · 方法区的静态变量和常量所引用的对象.

    图二中,把虚拟机栈的栈帧的局部变量表看作GC Roots的话,Java堆中的实例1跟实例2就与GC Roots“失联”了。GC Roots无法到达的对象便成了垃圾回收对象,随时被gc掉。所以,可达性算法可以处理循环引用的问题,解决了引用计数算法带来的缺陷。这也是目前虚拟机基本都是采用可达性算法的原因。

    大家有技术上的兴趣请加Q群:543827083。我们一起聊聊Android开发的知识

    展开全文
  • jvm学习笔记

    2019-11-26 23:14:28
    复制(copying)法的优点是 不会产生内存碎片,而且可以完整的保留对象, 缺点是:犹豫eden 和个 survivor区是8:1:1 所以总有百分之10的空间浪费,对象存活率高的话,复制性能就比较差了 标记清除(Mark Sweep):1...
    对比 Minor GC Full CG
    发生位置 新生代 老年代
    算法 复制 标记清除/标记整理
    • 复制算(copying)法的优点是 不会产生内存碎片,而且可以完整的保留对象,
      缺点是:犹豫eden 和两个 survivor区是8:1:1 所以总有百分之10的空间浪费,对象存活率高的话,复制性能就比较差了
    • 标记清除(Mark Sweep):1.扫描对存活的对象进行标记。2.扫描整个空间,对未被标记的对象进行回收。节约空间,但是需要两次扫描,并且产生了内存碎片。
    • 标记整理 (Mark Compact ):效率低,不仅需要标记所有存活的对象,而且还需要整理所有存活对象的引用地址
      调优参数 :Xms : Xmx:
      看日志:XXprintdetail;
      新生代分为 Eden ,sur0 ,sur1
      老年代
    对比1.6 ,1.7 ,1.8 jvm ,hotspot
    1.6 1.7 1.8
    运行时常量池 方法区 元空间
    永久代 ×

    在这里插入图片描述
    在永久代移除后,字符串常量池也不再放在永久代了,但是也没有放到新的方法区—元空间里,而是留在了堆里(为了方便回收?)。运行时常量池当然是随着搬家到了元空间里,毕竟它是装静态变量、字节码等信息的,有它的地方才称得上方法区。

    展开全文
  • 虚拟DOM 与 diif算法

    2019-07-01 08:14:17
    虚拟dom Q: vdom是什么? A: 它是一个Object对象模型,用来模拟真实dom节点的结构; 虚拟DOM的使用基本流程; vdom的使用流程: ...- 使用 diff 算法对比两次 vdom ,生成 patch 对象; 什么是diff...
  • 以平面2R串联机器人机构为研究对象,运用拉格朗日方法建立了机构的动力学模型,并通过数值例,运用Matlab、ADAMS个软件对机 构的动力学模型进行了仿真,通过对比,证明了所建立的平面2R串联机器人机构动力学模型...
  • 2016.10.19 韬光养晦

    2016-10-19 22:21:00
    2.转义字符加上需要转义的字符,只一个字符,例如:\\一个字符而不是个字符 3.字符串处理 a.字符串截取  str.substring(a,b)->a<=str<b b.判断字符串是否相等  object == 对象对比  object ...
  • 基于Stackelberg博弈的多V2M电力交易...研究将传统价格模型和Stackelberg博弈模型进行对比例结果证明了博弈模型的有效性,所提出的模型和结论均具有一定普适性,为多V2M系统的发展方向和管理措施提供了理论依据。
  • 最短路径的选择是图论中的经典问题之一....最后,通过例验证此方法的可行性,通过与Dijkstra算法对比分析说明所提出方法的合理性和有效性,并且分析了采用不同排序方法对中智图最短路径选择的影响.
  • 有实例化对象当前与历史做对比若发生变化就保存这个功能,只能清除或者在会话结束后调一下加密。拦截器就尴尬了我只能拦截到Onsave方法,对update就拦截不到了 实现过saveorupdate监听后,确实监听到了,但是系统中...
  • c# 加密和解密相关代码

    热门讨论 2011-09-06 11:04:59
    对比两个二进制的值,从右向左按位对比,如果个二进制数的相应位都为1 或个二 进制数的相应位都为0,则返回0;如果个二进制数的相应位中一个为1 一个为0,则返回1,最后得到的结 果为二进制值11000,该值转换...
  • 学费输入数据求最大精确划分思维解决最大次大交换数据实现按行显示围棋棋盘绘制国际象棋绘制为什么要用函数函数的四种类型函数的一般形式必须用函数的理由-哥德巴赫函数的本质就是地址函数变量意义函数变量用途...
  • React开发实战

    2018-10-25 11:23:43
    微软出产品一般规律是:一版本是看着花哨,二版本是试着用用,三版本才定型,过了三版之后,还能稳定,你再介入吧。 三:后台硬不硬。关键看支持的研究机构或公司牛不牛,不牛的公司当然也可能成功,但概率较低。...
  • oracle动态性能表

    2011-01-06 14:32:04
    2:语义是否合法(权限,对象是否存在) 3:检查该sql是否在共享池中存在 -- 如果存在,直接跳过4和5,运行sql. 此时soft parse 4:选择执行计划 5:产生执行计划 -- 如果5个步骤全做,这就叫hard parse. 注意物理I/O ...
  • 对比了在服务端刷新率为 60 Hz 同时维护 50 个角色时的响应时间,详细对比报告见: Kcp a new low latency secure network stack 关于协议 近年来,网络游戏和各类社交网络都在成几何倍数的增长,不管网络游戏...
  • 黑客资料(crack)

    2008-12-29 19:49:40
    我认为最经典的爆破对象就是一个模拟器软件,如果你知道我说的是哪一个的话可以去研究研究它的加密。 如果有一天你不是一上来就是拿着斧头砍来砍去而是从内存里嗅出了一串儿注册码的话,那就恭喜你进阶了。 第...
  • 将csv数据导出成JSON对象、JSON数组纯数据文件,省市区3级数据120kb+。 网页版省市区镇多级联动测试。 网页版省市区多级联动js代码生成(含数据)。 效果图 :open_book:拼音标注 拼音源 省市区这三级采用在线...
  • 大话数据结构

    2018-12-14 16:02:18
    高斯在上小学的一天,老师要求每个学生都计算1+2+…+100的结果,谁先出来谁先回家…… 2.4算法定义 20 现实世界中的算法千变万化,没有通用算法可以解决所有问题。甚至一个小问题,某个解决此类问题很优秀的算法...
  • 上,每个进程所使用的内存也肯定少于 4 GB。因此,当加载一个进程时,它会得到一个取决于某个称为系统中断点(system break)的特定地址的初始内存分配。该地址之后是未被映射的内存 —— 用于在 RAM 或者...

空空如也

空空如也

1 2 3
收藏数 51
精华内容 20
关键字:

两算对比对象