面试点

tech2025-12-02  24

Java集合:

Java集合: Connection顶级接口 { List接口 ArrayList:动态扩容数组 第一次put()时,才初始化:10 扩容后1.5倍 查询快,一次读取连续数组到cpu内存。一次用户态和核心态的切换。 LinkedList:双向链表,头插和尾插都可添加 ,添加、删除快-分拆链表代价小于数组复制。 有序 Vector:动态扩容数组+synchronized (线程安全)初始化:10 扩容后2倍 Set接口 HashSet 初始化:16 扩容后2倍 底层调用HashMap的key实现 无序 TreeSet 有序的 LinkedHashSet 有序的 插入顺序 } Map接口: HashMap 初始化:16 扩容后2倍 负载因子0.75 JDK 1.6 数组加单向链表解决Hash冲突(拉链法、再Hash、扩展表、寻址法),头插法,扩容再hASH会导致回环,1.7 数组+链表+红黑书 链表长度大于8,总元素大于64,小于6变为链表,尾插法,改进渐进式Hash(redis)(红黑树可以用跳跃表) HashTable 初始化:11 扩容后2+1 + synchronized 底层调用HashMap实现。 无序,HashTable(key value) 都不为空(无法判断存的是null,还是没有映射操作过),hashMap相反,hashMap做了特殊处理,第一个槽位专门存key为空的键值对。 线程安全的类:Vector、HashTable 、StringBuffer

Java锁 synchronized与Lock

synchronized 锁原理:synchronized完成后强制刷新回主存 volication 开始是无锁状态,有工作线程进入带锁的区域,升级为偏向锁,把线程 ThreadID 存入对象头的Mark world 的一个位置,如果为null,则存入,该线程再次访问,与对象头比较相同则直接进入,上个线程结束后,把mark world thradID 置空(锁消除),非同一线程访问,到全局安全点,多次eplod到40,升级为轻量级锁,把mark world 拷贝一份存入线程栈帧,lock Record 锁记录,用cas,尝试把线程指针写入mark world 成功 获取轻量级锁,失败CAS自旋10(自适应自旋),失败升级重量级锁,先加上moinitorenter和monitorexit,锁对象关联一个monitor监视器锁,把线程id存储到monitor监视器锁中,重入monitor 监视器锁的jsoure++,失败的加入_cxq队列中,下次竞争失败加入entity队列中,调用wait方法,放入wait队列。 锁升级、 (静态同步方法{锁类}、普通方法上{锁对象}:ACC_SYNCHRONIZED 隐式带调用 换锁过程:编译后monitorenter monitorexit,加开始是无锁状态mark world 锁状态是01,关联监视器锁 monitor对象,把ThreadID写入,monitor 计数器(+1)把monitor指针写入mark world,修改锁对象为10,完成换锁。 代码块{锁对象or锁类}):monitorenter monitorexit 程序计数器 +1 Lock CAS自旋cpu开销(限制重试次数)--轻量级锁、一个共享标量加锁、ABA问题(versionCode) Lock与synchronized区别 Lock JDK层面,synchronized JVM层面 lock需要手动释放锁、synchronized自动释放或异常释放 lock可以打断,synchronized不可打断 lock丰富的API方法(高级特性)synchronized没有 lock可以交互加锁,A加锁成功B才能加锁,然后A才能释放,B才能释放,synchronized不能 lock适合低并发,synchronized锁升级(无法降级,偏向锁的锁消除oples,大量轻量级锁自旋) lock只能锁代码块,synchronized可以锁方法和代码块 synchronized非公平锁,lock可选择公平or非公平锁 lock有读锁提高效率
最新回复(0)