其他分享
首页 > 其他分享> > 微软面试

微软面试

作者:互联网

Q:链表是什么?

   
A: 当需要存储多个相同数据类型的时候,可以使用数组存储,数组可以通过下标直接访问,但数组有个缺点就是无法动态的插入或删除其中的元素(特别是操作第一个位置上的元素),而链表弥补了这个缺陷,对于元素的插入和删除操作是很方便的,不过访问元素的“性能”就差很多了。

    所谓单链表,即只有一个指针,指向下一个元素(结点)的地址,只要知道单链表的首地址,就可以遍历整个链表了。由于链表结点是在堆区动态申请的,其地址并不是连续的,因此无法进行随机访问,只有通过前一结点的next指针才能定位到下一个结点的指针。

    单链表只能向后遍历,不能逆序遍历,所以有了使用更广泛的双链表。即结点多了一个存储前一个结点地址的prev指针。双链表可以双向遍历,但也只能按顺序访问。


Q:哈希表的 table 的容量如何确定?loadFactor 是什么? 该容量如何变化?这种变化会带来什么问题?

A:①、table 数组大小是由 capacity 这个参数确定的,默认是16,也可以构造时传入,最大限制是1<<30;
②、loadFactor 是装载因子,主要目的是用来确认table 数组是否需要动态扩展,默认值是0.75,比如table 数组大小为 16,装载因子为 0.75 时,threshold 就是12,当 table 的实际大小超过 12 时,table就需要动态扩容;
③、扩容时,调用 resize() 方法,将 table 长度变为原来的两倍(注意是 table 长度,而不是 threshold)
④、如果数据很大的情况下,扩展时将会带来性能的损失,在性能要求很高的地方,这种损失很可能很致命。

 


Q:哈希表的工作原理?


A:HashMap 底层是 hash 数组和单向链表实现,数组中的每个元素都是链表,由 Node 内部类(实现 Map.Entry<K,V>接口)实现,HashMap 通过 put & get 方法存储和获取。

存储对象时,将 K/V 键值传给 put() 方法:①、调用 hash(K) 方法计算 K 的 hash 值,然后结合数组长度,计算得数组下标;②、调整数组大小(当容器中的元素个数大于 capacity * loadfactor 时,容器会进行扩容resize 为 2n);
③、i.如果 K 的 hash 值在 HashMap 中不存在,则执行插入,若存在,则发生碰撞;
ii.如果 K 的 hash 值在 HashMap 中存在,且它们两者 equals 返回 true,则更新键值对;
iii. 如果 K 的 hash 值在 HashMap 中存在,且它们两者 equals 返回 false,则插入链表的尾部(尾插法)或者红黑树中(树的添加方式)。

 

Q:哈希表中,当两个对象的 hashCode 相同会发生什么?

A:因为 hashCode 相同,不一定就是相等的(equals方法比较),所以两个对象所在数组的下标相同,"碰撞"就此发生。又因为 HashMap 使用链表存储对象,这个 Node 会存储到链表中。

标签:结点,hash,HashMap,微软,链表,面试,数组,table
来源: https://www.cnblogs.com/wl-blog/p/16437592.html