Java字符串常量池 本文讨论的是JDK8及之后的版本
内存模型的变化 jdk8之后字符串常量池从Perm区转移到堆中
intern机制的变化 如果字符串常量池中存在(StringTable在比较时equals返回true),则返回该字符串对象地址;
如果字符串常量池中不存在,则返回调用intern的字符串对象在堆中的地址,达到复用该对象
字符串常量池的添加方式 通过双引号字符串声明添加 //创建一个对象 String s = "test"; //创建hello,world两个字符串常量池中对象,两个栈中中间变量,一个堆中最终变量"helloworld",注意此字符串不在常量池中 String s = new String("hello") + new String("world"); 通过intern方法添加 //常量池不存在时 String s = new String("hello") + new String("world"); s.
JUC JUC知识体系 @startmindmap * juc ** base *** unsafe *** varhandle *** volatile ** atomic *** AtomicInteger *** AtomicBoolean *** AtomicLong *** AtomicReference *** AtomicMarkablereference *** AtomicStampedReference *** AtomicXXXArray *** AtomicXXXFieldUpdater *** LongAdder/DoubleAdder *** LongAccumulator/DoubleAccumulator ** Locks *** AQS *** ReentrantLock *** ReentrantReadWriteLock *** StampedLock ** uitls *** CountdownLatch *** CyclicBarrier *** Semaphore *** Exchanger *** Phaser ** Containers *** BlockingQueue **** ArrayBlockingQueue **** LinkedBlockingQueue **** PriorityBlockingQueue **** SynchronusQueue ***** TransferQueue ***** TransferStack **** DelayQueue *** BlockingDeque **** LinkedBlockingDeque *** TransferQueue **** LinkedTransferQueue *** CopyOnWrite **** CopyOnWriteArrayList **** CopyOnWriteArraySet *** Concurrent **** ConcurrentLinkedDeque **** ConcurrentLinkedQueue **** ConcurrentSkipListSet **** ConcurrentSkipListMap **** ConcurrentHashMap ** ThreadPool *** ThreadPoolExecutor *** ScheduledThreadPoolExecutor *** ForkJoinPool ** Async *** Future **** FutureTask(Treiber Stack) *** CompletableFuture @endmindmap Synchronized 使用wait/notifyAll,Lock/Condition实现阻塞队列 实现锁的核心要素 为了实现一把具有阻塞或唤醒功能的锁,需要几个核心要素:
本质是一个最小二叉堆,底层使用数组进行存储
使用到的二叉堆性质:(n为二叉堆节点个数,数组从索引0开始存储,从上到下从左到右从0开始依次编号)
节点i若有左右孩子,则左孩子索引为(i«1)+1,右孩子索引为(i«1)+2
第一个叶子结点的索引为size»1,最后一个非叶子节点索引为(size»1)-1
节点i的父节点为(i-1)»1,若(i«1)+1 >=size(无左孩子)则该节点一定为叶子结点
叶子结点在数组后半段且从第一个叶子结点开始后续全都是叶子结点
初始化注意事项:
本质: 循环数组,支持双端存取
JDK8中底层数组的大小必须为2的n次幂有多个好处:
2.1 方便按顺序遍历数组中所有元素
int mask=elements.
Springboot参数校验及相关异常处理 不同类型参数校验 实体添加校验规则
@Data public class User { @NotNull(message = "name不能为空") private String name; @Range(min = 0, max = 120, message = "必须在0-120之间") private int age; } 通过query string传递的参数 需要在Controller上加上@Validated注解否则不会触发校验规则
本质: 双向链表 序列化时仅需要按顺序序列化元素本身无需序列化Node,只需要在反序列化时重建双向链表即可 不推荐作为Deque,Queue,Stack(不允许存储null)使用,因为LinkedList可以存储null,不符合取出元素返回null时集合为空的接口定义
本质:底层使用数组,超出数组容量后会扩容50%并将数据拷贝到新数组对应位置 序列化的优化:仅序列化存有元素的数据,不序列化未使用数组部分 使用modCount做简化的并发检测,并不能做到并发安全,可以控制使用迭代器时无法修改集合,仅能通过迭代器提供的操作进行处理 Collection#toArray接口要求返回一个新的存有集合数据的数组,不能返回底层数组防止被意外修改影响原集合功能
单个测试覆盖率
直接选择"Run with Coverage"即可
所有测试的覆盖率(gradle)
在gradle插件中找到test任务(Tasks/verification/test),右键test选择"Run with Coverage"即可