零碎知识点
1 Java 原子类中,CAS是如何保证原子性的?
原子类中,用volatile修饰value,并使用unsafe类获取到value的地址偏移量,在执行更新操作时,使用unsafe类执行compareAndSwap操作,而该方法是一个Native方法,底层是通过汇编指令CMPXCHG加上Lock前缀,保证内存区域只允许一个线程访问。
2 运行时多态和编译时多态
运行时多态:通过基类或者抽象类、虚函数等调用具体实例的方法,在运行时才可以确定具体方法,这种情况时运行时多态。
编译时多态:函数的重载、模板类等,在编译时即可确定具体的方法,这种情况是编译时多态。
3 B树的具体应用
降低磁盘IO?
4 C++和Java的堆栈有什么区别
栈内存更快,但是堆内存更加灵活。
编译期间没有办法确定堆空间上的内存分配情况,堆上分配的内存需要回收(C++需要程序员手动回收,而Java有自动垃圾回收机制);而栈内存的内存回收由系统管理。
C++的对象既可以创建在堆上,也可以创建在栈上,Java绝大多数对象都创建在堆上。Java中的栈一般情况只存储引用和基本变量。
C++用alloca申请栈内存,new申请堆内存,malloc申请自由存储区,此外还有全局(静态)存储区用于存储全局变量和静态变量,常量存储区存储常量。
注意:栈中申请的内存都需要使用指针指向,Java也是如此,只不过对程序员屏蔽掉了指针。
5 C++的内存分布
由上至下分别是:栈、堆、全局区、常量区、代码区。
堆区内存向上增长,栈区内存向下增长。
6 Java中的对象内存分配
栈上内存分配:当对象的生命周期与入栈的方法一致时,JVM的对象逃逸分析会让该对象直接在栈上进行空间分配,从而减少GC压力
堆上内存分配:对象优先在eden区分配,大对象直接进入老年代,eden区对象经过GC后,如果存活,则存入survivor区并增加年龄,当年龄达到阈值,会进入老年代(注意:当survivor区内存不足时,会动态调整年龄阈值,将对象送入老年代)。老年代空间分配担保机制:指的是minorGC前会计算老年代剩余空间和年轻代中的对象大小,如果空间不足,则触发一次FullGC,如果垃圾回收后空间不足则会触发OOM。
7 进程的内存分配
内核区(用户不可读写)高地址段
栈(向下增长)
堆(向上增长)
数据段
代码段
8 Redis中的ListPack是什么
listpack:…
:4字节,表示listpack占用字节数
:2字节,元素个数
:entry
:1字节,结束标志,0xFF
entry:
:编码类型
:元素数据
:entry长度,最高位作为标记位,表示是否为element的最后一个字节,并采用大端存储方式。
=
ListPack中Entry改为记录自身长度,从而避免了ziplist的连锁更新问题。
反向查询:通过读取前一个元素的字节,逐步向前读取至element-tot-len最后一个字节,得到偏移值,从而访问上一个元素。
https://blog.csdn.net/ldw201510803006/article/details/122420585