备战2022春招-java-day2

java

  1. CAS? => compareAndSet 比较并交换
    全称为:Compare-And-Swap,它是一条CPU并发原语。功能是判断内存某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子的。
  2. Unsafe?是CAS的核心类,由于java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,给予该类可以直接操作特定内存的数据。Unsafe类存在于sun.misc包种,其内部方法操作可以像C的指针一样直接操作内存,因为Java中CAS操作的执行依赖于Unsafe类的方法(Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务)
  3. CAS缺点?①循环时间长开销大;② 只能保证一个共享变量的原子操作;③引出来ABA问题
  4. ABA问题?狸猫换太子
    就是有两个线程A和B。比如线程A对主内存中的变量countA变为了countB,然后又将countB变回了countA。这时候线程B进行CAS操作发现内存中仍然是countA,但他不知道这个countA不是原来的countA
    • AutomicReference原子引用
      class User {
          private String name;
          private Integer age;
      }
      
      public class AtomicReferenceDemo {
          public static void main(String[] args) {
              User zs = new User("zs", 22);
              User lisi = new User("lisi", 25);
      
              AtomicReference<User> atomicReference = new AtomicReference<>();
              atomicReference.set(zs);
      
              System.out.println(atomicReference.compareAndSet(zs, lisi) + "\t current user is " + atomicReference.get());// true lisi
              System.out.println(atomicReference.compareAndSet(zs, lisi) + "\t current user is " + atomicReference.get());// false lisi
          }
      }
      
    • AtomicStampedReference版本号原子引用
    public class ABADemo {
       
           static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
           static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(100, 1);
       
           public static void main(String[] args) {
               //============ABA问题的产生=============
               new Thread(() -> {
                   atomicReference.compareAndSet(100, 101);
                   atomicReference.compareAndSet(101, 100);
               }, "t1").start();
       
               new Thread(() -> {
                   System.out.println(atomicReference.compareAndSet(100, 2022) + "\t atomicReference value is " + atomicReference.get());
               }, "t2").start();
       
       
               //============ABA问题的解决=============
               new Thread(() -> {
                   // 获取版本号
                   int stamp = atomicStampedReference.getStamp();
                   System.out.println(Thread.currentThread().getName() + "\t第一次版本号:" + stamp);
                   try {
                       TimeUnit.SECONDS.sleep(2);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   atomicStampedReference.compareAndSet(100, 101, atomicStampedReference.getStamp(),
                           atomicStampedReference.getStamp()+1);
                   System.out.println(Thread.currentThread().getName() + "\t第二次版本号:" + atomicStampedReference.getStamp());
                   atomicStampedReference.compareAndSet(101, 100, atomicStampedReference.getStamp(),
                           atomicStampedReference.getStamp()+1);
                   System.out.println(Thread.currentThread().getName() + "\t第三次版本号:" + atomicStampedReference.getStamp());
               }, "t3").start();
       
               new Thread(() -> {
                   // 获取版本号
                   int stamp = atomicStampedReference.getStamp();
                   System.out.println(Thread.currentThread().getName() + "\t第一次版本号: " + stamp);
                   try {
                       TimeUnit.SECONDS.sleep(3);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   boolean b = atomicStampedReference.compareAndSet(100, 2022, stamp, stamp + 1);
                   System.out.println(Thread.currentThread().getName() + "\t修改成功否:" + b + "\t当前版本号为:" + atomicStampedReference.getStamp()
                   + "\t当前实际值:" + atomicStampedReference.getReference());
               }, "t4").start();
           }
       }
    
  5. 集合类不安全?
    • 集合类不安全之并发修改异常 ArrayList
      解决:①Vector(); ②Collections.synchronizedList(new ArrayList<>());③new CopyOnWriteArrayList<>();(推荐)
    • 集合类不安全之Set
      解决:①Collections.synchronizedSet(new HashSet<>());②new CopyOnWriteArraySet<>();(推荐)
    • 集合类不安全之Map
      解决:①Collections.synchronizedMap(new HashMap<>());②new ConcurrentHashMap<>();(推荐)

算法

  • 数组:存放在连续内存空间上的相同类型数据的集合
  • 二分查找:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-search
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法一:定义target在一个左闭右闭区间

class Solution {
    public int search(int[] nums, int target) {
        int i = 0, j = nums.length - 1;
        while (i <= j) {
            int mid = i + (j - i) / 2;
            if (nums[mid] > target)
                j = mid - 1;
            else if (nums[mid] < target)
                i = mid + 1;
            else 
                return mid;
        }
        return -1;
    }
}

方法二:定义target在一个左闭右开的区间

class Solution {
    public int search(int[] nums, int target) {
        int i = 0, j = nums.length;
        while (i < j) {
            int mid = i + (j - i) / 2;
            if (nums[mid] > target)
                j = mid;
            else if (nums[mid] < target)
                i = mid + 1;
            else 
                return mid;
        }
        return -1;
    }
}
  • 移除元素
    给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:遍历这个数组,如果数组中的元素和传入的值val相等,则continue,直接跳到下一个循环。如果值不相等的话,就将值赋给原数组,下标(定义一个len)从0开始。返回len。

class Solution {
    public int removeElement(int[] nums, int val) {
        int length = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == val) {
                continue;
            }
            nums[length] = nums[i];
            length++;
        }
        return length;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值