java 面试题(每日5题)

ArrayList和LinkedList的区别

  1. ArrayList底层数据结构是数组实现的,LinkedList底层数据结构是基于链表实现的
  2. 因为数据结构不同,所以使用的场景不同,ArrayList适用于随机查询,LinkedList适用于添加和删除
  3. ArrayList和LinkedList都实现了list接口,但是LinkedList还实现了Deque接口,所以LinkedList还可以当队列来使用

说一下HashMap的put方法

  1. Put方法先根据key通过哈希算法与与运算得出数组下标
  2. 如果数组下标为空就把key-value封装为对象(1.7是Entry,1.8是Node)放入改下标位置
  3. 如果下表位置不为空,则分情况讨论:
  • 如果是jdk1.7,则需要判断是否要扩容,如果要扩容就扩容,不需要扩容就生产Entry对象,并使用头插法添加到当前位置的链表中。

  • 如果是jdk1.8,则先判断当前位置上的node类型,看是红黑树的node还是链表的node
  • 如果node类型是链表,则把key-value封装成node对象使用尾插法插入到链表的最后位置,因为是用尾插法所以会遍历链表,如果有key相同,则更新value。遍历完链表后把新的链表node插入到链表中,插入后会判断当前链表节点的个数,如果超过8则将链表转化为红黑树。
  • 如果node类型是红黑树,就会把node封装成一个红黑树节点添加到红黑树中,在添加过程中会判断key,如果key相同就会更新value。
  • 将key-value封装成node插入到链表或红黑树中后,再判断是否需要扩容,如果不需要就结束put方法。

jdk1.7和jdk1.8 HashMap 发生了什么变化(底层)

  1. jdk1.7中底层是数组+链表,jdk1.8中底层数据结构是数组+链表+红黑树
  2. jdk1.7中使用的是头插法,jdk1.8中使用的是尾插法,因为1.8中要遍历链表进行判断链表节点的元素个数,所以就使用尾插法
  3. 1.7中哈希算法复杂度高,1.8中进行了简化,因为负载的哈希算法目的是为了提高散列性,而1.8新增了红黑树,所以可以适当的简化哈希算法,节省cpu资源

jdk1.7到jdk1.8java 虚拟机发生了什么改变

  1. 1.7中存在永久代,1.8中没有永久代,替换为元空间,元空间不占用虚拟机的内存,而是本地内存空间。因为不管是元空间还是永久代,它们都是方法区的具体实现,之所以改官方的说法是为了和JRockit统一,不过还有一些额外的原因;比如方法区所存的类通常是比较难以确定的,所以对于方法区的大小是比较难以确定的,太小了容易内存泄露,太多了容易造成jvm内存资源浪费,而转移到本地内存后就不会影响虚拟机的内存

Redis的数据结构及使用场景

  1. 字符串:可以用过来做简单的缓存,可以缓存简单的字符串,也可以缓存json格式的字符串,Redis分布式锁就是利用了这种数据结构,可以实现计数器、session共享、分布式ID
  2. 哈希表:可以用来存储一些key-value对,更适合存储对象
  3. 列表:Redis的列表通过命令的组合可以当做栈,也可以当作队列,可以用来缓存公众号、微博信息
  4. 集合:和列表类似,可以存储多个元素,但是不能重复,集合可以进行交集、并集、差集,从而实现我于某人的共同关注、朋友圈点赞
  5. 有序集合:集合是无序的,有序集合可以设置排列顺序,可以用来实现排行榜功能
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值