美文网首页
Java 面试题整理

Java 面试题整理

作者: 四月Chen | 来源:发表于2019-04-14 16:05 被阅读0次

    [toc]

    Java 集合

    1. HashMap和TreeMap的区别
    • HashMap:基于哈希表实现。数组方式存储key/value,线程非安全,允许null作为key和value,key不可以重复,value允许重复,不保证元素顺序,要求key必须重写equals和hashcode方法,可以调优初始容量和负载因子,需要扩容。
    • TreeMap:基于红黑二叉树的NavigableMap的实现,线程非安全,不允许null,key不可以重复,value允许重复,存入TreeMap的元素应当实现Comparable接口或者实现Comparator接口,会按照排序后的顺序迭代元素,两个相比较的key不得抛出classCastException。主要用于存入元素的时候对元素进行自动排序,迭代输出的时候就按排序顺序输出
    2. HashSet和TreeSet的区别
    • HashSet保存的数据是无序的,TreeSet保存的数据是有序的。
    • TreeSet 依靠的是Comparable来区分重复数据;HashSet依靠的是hashCode()、equals()来区分重复数据
    • TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null值。
      HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复。
    3.队列和链表的区别
    • 队列:先进先出;队尾插入,队头删除
    • 链表:有一个指针,该指针指向下一个元素的地址。任意位置插入、删除
    4.HashMap线程不安全表现

    1、put的时候导致的多线程数据不一致。
    这个问题比较好想象,比如有两个线程A和B,首先A希望插入一个key-value对到HashMap中,首先计算记录所要落到的桶的索引坐标,然后获取到该桶里面的链表头结点,此时线程A的时间片用完了,而此时线程B被调度得以执行,和线程A一样执行,只不过线程B成功将记录插到了桶里面,假设线程A插入的记录计算出来的桶索引和线程B要插入的记录计算出来的桶索引是一样的,那么当线程B成功插入之后,线程A再次被调度运行时,它依然持有过期的链表头但是它对此一无所知,以至于它认为它应该这样做,如此一来就覆盖了线程B插入的记录,这样线程B插入的记录就凭空消失了,造成了数据不一致的行为。
    2、resize死循环

    Java 并发

    1. synchronized原理
    2. ReentrantLock原理
    3. synchronized和ReentrantLock的区别
    • synchronized不可中断,ReentrantLock可中断。如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断。
      如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情。
    • synchronized是在JVM层面上实现的,ReentrantLock是Java API层
      面的
    • ReentrantLock

    1.等待可中断
    2.公平锁
    3.锁绑定多个条件

    1. AQS原理
    2. CAS原理
    3. ConcurrentHashMap原理
    4. wait和sleep的区别

    JVM

    1. JVM内存结构
    2. 类加载机制

    分布式

    1. 分布式事务和分布式数据一致性
      幂等性
    • 两阶段提交(2PC)


      image.png
    • 第一阶段:事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交.
    • 第二阶段:事务协调器要求每个数据库提交数据。

    拿西方结婚时仪式做比喻。大致好像是牧师分别询问男女双方“你愿意吗?”相当于这里的「请求提交」,得到的“yes”相当于「是」这个答复。然后再要求给对方带上戒指,这个要求就相当于这里的「提交」,带完戒指之后的反馈就是「ACK」。
    另外值得注意的是,参与者在答复「是」之前会将自己的内部资源变为阻塞状态。因此如果在产生阻塞后协调者出问题,那么这些被阻塞的资源有可能就一直不被释放了,需要额外的介入。

    • 三阶段提交(3PC)
    image.png

    通过运用本地事务代替了全局事务,使得可以不需要协调者的存在,避免了协调者的单点问题。
    3PC中协调者的另一个作用:故障恢复后的数据一致性。在TTC里通过事务日志来确保。

    3PC的出现就是通过增加复杂度(性能也因此降低)来解决或优化2PC中的一部分问题。本质的变化就是在2PC的「请求提交」之后增加了一个「准备提交」环节,以增加每个参与者需要等待其它的参与者确认后方可进行具体的操作。

    「阻塞」这个动作延后到这个「准备提交」环节再做,使得阻塞范围缩小为2PC的2/3(图中背景黄色和绿色部分)。正如上面的例子,在交换戒指之前增加了把戒指交给牧师的动作。

    同时还解决了协调者的单点问题。故障恢复或者新接替的协调者,可以利用「准备提交」产生的状态结果,来作为参与者和协调者在「提交」出现故障恢复后的界定依据。还是前面的例子,夸张点,交换戒指的时候我失忆了,意识恢复后我只要看到牧师手掌上托着戒指或者我的手上已经被戴好了戒指,就知道我的妻子已经答应了,我只要继续给她做带戒指这个事就好了。

    新引入了timeout机制,在发生超时执行默认约定,避免了永久阻塞,也因此对多个参与者下的100%数据一致性作出了妥协。比如,协调者在向参与者A发送「doCommit」时timeout了,会引发广播「abort」,但是这个「abort」又未能投递到参与者B,导致参与者B执行了「ACK」后的timeout默认约定「commit」。

    • TCC
    image.png
    • 通过运用本地事务代替了全局事务,使得可以不需要协调者的存在,避免了协调者的单点问题。
    • 3PC中协调者的另一个作用:故障恢复后的数据一致性。在TTC里通过事务日志来确保。
    • 异步消息——本地消息表


      image.png
    image

    这种实现方式的思路,源于ebay,与提出BASE理论在同一篇论文中[4]。设计思想是将远程分布式事务拆分成一系列的本地事务,借助关系型数据库中的表即可实现。

    • MQ 事务消息 RocketMQ


      image.png
    • Sagas 事务模型

    • Gossip协议

    相关文章

      网友评论

          本文标题:Java 面试题整理

          本文链接:https://www.haomeiwen.com/subject/uphswqtx.html