Java相关
IO
BIO:单线程处理所有请求
NIO:一个线程池处理accept, 一个线程池处理read/write并处理读写后相关逻辑
AIO:一个线程池处理accept, 一个线程池处理read/write并submit个新线程处理读写后的相关逻辑
AtomicInteger/AtomicReference
原理:
通过Unsafe 类型进行自旋+ CAS (compare and set) 操作
内部维护一个指针,在进行CAS时候,由于是汇编指令,获取地址并比较数值然后设置新值,所以是原子级别的。
自旋就是do while去调用CAS (jdk.internal.misc.Unsafe.getAndAddInt)
三种问题:
可能出现长时间的自旋
只能用一个变量,或者一个对象。
会出现ABA问题
AtomicStampedReference 不会ABA,因为内部存储了一个版本号 stamp。
Calendar使用
Calendar calendar = Calendar.getInstance(); calendar.get(Calendar.XXX);要注意每个参数的定义,月从0开始算的,星期是从周日(1)开始算的
BigDecimal 精度问题:
System.out.println(new BigDecimal(0.99)); // 0.9899999999999999911182158029987476766109466552734375 System.out.println(BigDecimal.valueOf(0.99d)); // 0.99
原因:第一种时二进制转十进制导致精度问题,第二种转为string再去转BigDecimal
@HotSpotIntrinsicCandidate注解
这个注解允许HotSpot VM自己来写汇编或IR编译器来实现该方法以提供性能。 也就是说虽然外面看到的在JDK9中weakCompareAndSet和compareAndSet底层依旧是调用了一样的代码,但是不排除HotSpot VM会手动来实现weakCompareAndSet真正含义的功能的可能性。
反编译
JVM GC
GC 分为
Yong 区 (一般数据创建了都放里面) 会频繁发送 minor GC
Old 区 (大对象或者经历15次minor GC后仍然存在的对象), 存放不下时会 Full GC
Perm 区 基本不动 (可以说时"永久代")
GC 算法:
引用计数法(因无法处理循环引用已淘汰)
对每个对象都要有一个引用计数器,耗性能
复制算法 (年轻代中使用的)
优点: 直接拷贝存活的对象然后清空原来的区域,没有内存碎片 (空的且可能无法被使用的空间) 缺点: 需要双倍的空间
标记清除 (老年代的)
优点: 不需要额外的空间 缺点: 需要进行两次扫描,一次标记,一次清除。还有内存碎片
标记压缩 (老年代)
优点:没有内存碎片 缺点:需要两次扫描和移动对象的成本。
标记清除压缩
标记清除和标记压缩的混合版,只有多次GC后才进行压缩,减少了移动对象的成本。
SQL 注入
预编译需要数据库支持预编译才行。 在 ClientPreparedStatement executeQuery() 中有chekDML,判断sql中是否有非法字符。
使用PreparedStatement,在执行语句前,
先将sql传给mysql做一次prepare,
然后再校验参数中的非法字符,有不合法的就会报异常,
然后传给 mysql 参数,执行之前的prepare 语句。
static 修饰作用
在类内部使用,既表明:这个方法、变量在加载实例前就被加载了,既类变量、类方法的含义。
如果是静态内部类,则可以脱离外部类生存,声明时不需要 new Out().new Inner(), 只需要 new Out.Inner();
如果类变量和局部变量重名,会怎么样
如果类变量和局部变量重名,则进行就近原则。
地址引用
String 和 包装类( Integer/ Double...) 是地址引用。
Last updated