手撕代码题:
单项列表实现加法运算
举例:list1:1->2->3; list2: 4->5->6->7;返回list:4->6->9->0
思路:用2个栈存储两个list,然后一起弹出,并记录进位,然后把每一次计算的结果拼接成list返回即可
代码:后续补充。。。。求一个整数二进制表示中1的个数
最笨的方式是逐位取值,判断是否为1;复杂度是O(n)
快速的方式是只找1的位置,n&(n+1)是找到最右边的1,然后n-n&(n+1)是舍弃最右边的1,当n变成0,即所有的1都找到了
代码:
int n = 0b10001010010100;
int count = 0;
while(n != 0){
count++;
n -= n&(~n + 1);
}
System.out.println(count);
线程安全&不安全
volatile、AtomicInteger、LongAdder、synchronize
· volatile解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题,但是如果多写,同样无法解决线程安全问题。如果是count++操作,使用如下类实现:AtomicInteger count = new AtomicInteger(); count.addAndGet(1); 如果是JDK8,推荐使用LongAdder对象,比AtomicLong性能更好(减少乐观锁的重试次数)。
CAS是一个原子性操作理解线程安全与不安全
https://www.cnblogs.com/kubidemanong/p/9505944.html对象实例
对象实例由对象头、实例数据组成,其中对象头包括markword和类型指针,如果是数组,还包括数组长度;
Mark word
Mark word与锁的关系锁
锁膨胀:
偏向锁->轻量级锁(自旋锁、自适应自旋锁,也叫作非阻塞同步、乐观锁)->重量级锁(又被叫做互斥锁MutexLock、阻塞同步、悲观锁)