最近的面试题(一)

40 阅读3分钟

HashMap

hashCode()和equals()的重要性

HashMap的键必须实现hashCode()和equals()方法。hashCode()用于计算哈希值,以决定键的存储位置,而equals()

用于比较两个键是否相同。在put操作时,如果两个键的hashCode()相同,但equals()返回false,则这两个键会被视为不同的键,存储在同一个桶的不同位置。

误用hashCode()和equals()会导致HashMap中的元素无法正常查找或插入。

HashMap扩容机制(hash扰动函数-rehashing)

HashMap中的扩容是基于负载因子(load factor)来决定的。默认情况下,HashMap的负载因子为0.75,这意味着当HashMap的已存储元素数量超过当前容量的75%时,就会触发扩容操作。

例如,初始容量为16,负载因子为0.75,则扩容阈值为16×0.75=12。当存入第13个元素时,

HashMap就会触发扩容。

当触发扩容时,HashMap的容量会扩大为当前容量的两倍。例如,容量从16增加到32,从32增加到64等。

扩容时,HashMap需要重新计算所有元素的哈希值,并将它们重新分配到新的哈希桶中,这个过程称为rehashing。每个元素的存储位置会根据新容量的大小重新计算哈希值,并移动到新的数组中。

JDK1.8对HashMap除了红黑树还进行了哪些改动?

  1. 改进了哈希函数的计算:JDK1.8中优化了哈希函数,使得哈希值的分布更加均匀,减少了哈希冲突的发生。通过在生成哈希值时使用“扰动函数”,确保哈希值的高低位都能参与到桶的选择中。
  2. 扩容机制优化:JDK1.8改进了扩容时的元素迁移机制。在扩容过程中不再对每个元素重新计算哈希值,而是根据原数组长度的高位来判断元素是留在原位置,还是迁移到新数组中的新位置。这一改动减少了不必要的计算,提升了扩容效率。
  1. 头插法变为尾插法:头插法的好处就是插入的时候不需要遍历链表,直接替换成头结点,但是缺点是扩容的时候会逆序,而逆序在多线程操作下可能会出现环,产生死循环,于是改为尾插法。

Mybatis

MyBatis编程步骤是什么样的?【重要】

1、 创建SqlSessionFactory
-->2、 通过SqlSessionFactory创建SqlSession -->3、 通过sqlsession执行数据库操作 -->4、 调用session.commit()提交事务 -->5、 调用session.close()关闭会话

为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。

而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。