【每天10问】002 后端知识点 2022.02.16 周三

 

每天10问: 是一个系列,不代表一定是10问,可能只有3问,主要是 记录当天自己的 技术思考和收获等

 

 

 

  1.   问题01:LinkedHashMap的底层也还是 数组吗? 普通的 HashMap有什么区别?
    答: 是 数组+ 双向链表 (树化后是 红黑树),普通的 HashMap是 数组+单向链表, 具体可以查看 https://blog.csdn.net/weixin_30988079/article/details/112375182
    
         
    
    ===={知识点}
    1)【知识点 01】LinkedHashMap是HashMap的一个子类,底层实现基本上和HashMap一样,只是在原来的单链表的基础上改成了双向链表,这样做的目的是为了让它能够实现插入数据的排序。也就是说如果遍历整个LinkedHashMap时,是会按照插入数据的顺序来遍历数据的。
    2)【知识点 02】:
    Map.Entry (以 HashMap这个具体实现为例)是 HashMap的静态内部类 Map.Entry

     


  2.问题02【todo】:LinkedHashMap中 其中的一个构造方法中的 accessOrder字段传递 true时,每次get()操作都会把get到的那个元素的顺序放到最后
这样做的意义或者作用是什么呢?

TODO --待解答

 

 

  3.问题02:Java的 volatile的底层原理和使用的方法是怎样的?

    答:1)volatile的特点是: ① 保证了可见性  ② 不支持原子性  ③禁止指令重排,具体参考:https://blog.csdn.net/u012723673/article/details/80682208?utm_source=app&app_version=5.0.0

【原理】:在JVM底层volatile是采用“内存屏障”来实现的。加入volatile关键字时,会多出一个lock前缀指令,这个lock的前缀指令就相当于是 内存屏障。提供的3种功能,正好是 对应 禁止指令重排 变量的各线程的可见性。

 

   4.问题04:单例模式的双重锁为什么要加volatile

public class TestInstance{
    private volatile static TestInstance instance;
    
    public static TestInstance getInstance(){        //1
        if(instance == null){                        //2
            synchronized(TestInstance.class){        //3
                if(instance == null){                //4
                    instance = new TestInstance();   //5
                }
            }
        }
        return instance;                             //6
    }

====
 需要volatile关键字的原因是,在并发情况下,如果没有volatile关键字,在第5行会出现问题。instance = new TestInstance();可以分解为3行伪代码

a. memory = allocate() //分配内存
 
b. ctorInstanc(memory) //初始化对象
 
c. instance = memory //设置instance指向刚分配的地址
   上面的代码在编译运行时,可能会出现重排序从a-b-c排序为a-c-b。在多线程的情况下会出现以下问题。当线程A在执行第5行代码时,B线程进来执行到第2行代码。假设此时A执行的过程中发生了指令重排序,即先执行了a和c,没有执行b。那么由于A线程执行了c导致instance指向了一段地址,所以B线程判断instance不为null,会直接跳到第6行并返回一个未初始化的对象。

 

 

 5.问题05: Java中引用reference具体指什么?

https://cloud.tencent.com/developer/article/1657759

答:
1) 知识点 01: java中有值类型也有引用类型,引用类型一般是针对于java中对象来说的
2) 知识点 02: java为引用类型专门定义了一个类叫做Reference。Reference是跟java垃圾回收机制息息相关的类,通过探讨Reference的实现可以更加深入的理解java的垃圾回收是怎么工作的。


3)知识点03:java中的四种引用类型分别是:强引用,软引用,弱引用和虚引用。



问题01: 引用reference中的 ReferenceQueue 具体指什么,有什么作用?
  答: 初步理解: 比如 软引用 SoftReference的 构造方法 public SoftReference(T referent, ReferenceQueue<? super T> q)
  第二个参数叫做ReferenceQueue,是用来存储封装的待回收Reference对象的,ReferenceQueue中的对象是由Reference类中的ReferenceHandler内部类进行处理的。

4) 知识点 04:

  • Reference类是所有引用类的父类
  • Reference中可以在创建时注册引用队列
  • Reference有四种状态,如果创建时没有注册引用队列,则只有两种状态
  • 可以通过get方法获取内部的对象,但如果对象已经被回收了,则会返回null

 

在讲这三个Queue/List之前,我们先讲一下Reference的四个状态:

 其完整生命周期

对于带ReferenceQueue的Reference,GC会把要回收对象的Reference放到ReferenceQueue中,后续该Reference需要程序员自己处理(调用poll方法)。

不带ReferenceQueue的Reference,由GC自己处理,待回收的对象其Reference状态会变成Inactive。

创建好了Reference,就进入active状态。

active状态下,如果引用对象的可到达状态发送变化就会转变成Inactive或Pending状态。

Inactive状态很好理解,到达Inactive状态的Reference状态不能被改变,会等待GC回收。

Pending状态代表等待入Queue,Reference内部有个ReferenceHandler,会调用enqueue方法,将Pending对象入到Queue中。

入Queue的对象,其状态就变成了Enqueued。

Enqueued状态的对象,如果调用poll方法从ReferenceQueue拿出,则该Reference的状态就变成了Inactive,等待GC的回收。

这就是Reference的一个完整的生命周期。

 

 

 

WeakHashMap

最后讲一下WeakHashMap,WeakHashMap跟WeakReference有点类似,在WeakHashMap如果key不再被使用,被赋值为null的时候,该key对应的Entry会自动从WeakHashMap中删除。

      

posted @ 2022-02-16 20:22  程序员的文娱情怀  阅读(28)  评论(1编辑  收藏  举报