文心一言 VS 讯飞星火 VS chatgpt (235)-- 算法导论17.2 3题

news2024/11/24 13:40:06

三、假定我们不仅对计数器进行增 1 操作,还会进行置 0 操作(即将所有位复位)。设检测或修改一个位的时间为 Θ(1) ,说明如何用一个位数组来实现计数器,使得对一个初值为 0 的计数器执行一个由任意 n 个 INCREMENT 和 RESET 操作组成的序列花费时间 O(n) 。(提示:维护一个指针一直指向最高位的 1 。)

文心一言:

为了实现这样一个计数器,我们可以使用一个位数组(bit array)来存储计数器的当前值,并维护一个额外的指针来指向最高位的 1。每次执行 INCREMENT 或 RESET 操作时,我们可以利用这个指针来高效地更新计数器。

下面是具体实现的步骤:

初始化:
创建一个足够大的位数组(bit array)来存储计数器的值。假设位数组的大小为 m。
初始化所有位为 0。
初始化一个指针 highestOne,指向位数组的起始位置(即最低位)。
INCREMENT 操作:
如果 highestOne 指向的位是 0,则将该位设置为 1,并返回。
否则,从 highestOne 指向的位开始,向右遍历位数组,直到找到一个 0 或者到达位数组的末尾。
如果找到一个 0,将其设置为 1,并更新 highestOne 指向这个新设置的 1。
如果到达位数组的末尾,则需要进位。此时,将 highestOne 指向的位重置为 0,并向右移动一位。如果到达位数组的末尾仍然需要进位,则扩展位数组的大小,并在新扩展的位上设置 1。更新 highestOne 指向新设置的 1。
RESET 操作:
将位数组中的所有位都设置为 0。
将 highestOne 指针重新指向位数组的起始位置。
这个实现的关键在于维护 highestOne 指针,它指向最高位的 1。这样,INCREMENT 操作可以尽快地找到需要修改的位置,而 RESET 操作则只需要简单地重置整个位数组和指针。由于每次操作都只需要修改常数个位,并且每个位的修改时间是 Θ(1),因此整个序列的时间复杂度是 O(n)。

请注意,这个实现假设位数组的大小可以动态扩展。如果位数组的大小是固定的,那么在执行大量的 INCREMENT 操作后,可能会出现溢出的情况。为了避免这种情况,可以在设计计数器时预先分配足够大的位数组,或者采取其他策略来处理溢出(例如,使用模运算或将计数器设计为循环的)。

在这里插入图片描述

讯飞星火:

为了实现一个位数组计数器,我们可以使用以下方法:

  1. 初始化一个空的位数组和一个指针指向最高位的 1。
  2. 对于每个 INCREMENT 操作,将指针指向的位设置为 1,然后将指针向左移动一位。
  3. 对于每个 RESET 操作,将所有位复位(即将所有位设置为 0),并将指针重新指向最高位的 1。

以下是实现这个方法的 Python 代码:

class BitArrayCounter:
    def __init__(self):
        self.bit_array = [0] * 32  # 假设我们使用 32 位整数作为计数器
        self.pointer = 0

    def increment(self):
        self.bit_array[self.pointer] = 1
        self.pointer += 1

    def reset(self):
        self.bit_array = [0] * 32
        self.pointer = 0

    def get_count(self):
        count = 0
        for i in range(len(self.bit_array)):
            if self.bit_array[i] == 1:
                count += 2 ** (len(self.bit_array) - 1 - i)
        return count

这个实现的时间复杂度为 O(n),因为每个 INCREMENT 和 RESET 操作的时间复杂度都是 O(1)。

在这里插入图片描述

360智脑:

我们可以使用一个位数组和一个指针来实现上述要求的计数器。位数组的每一位表示计数器的二进制表示中的一位,从最低位(右端)开始编号。初始时,整个位数组都为0。我们设置一个指针,始终指向当前最高位的1。

操作步骤如下:

  1. 初始化:位数组全为0,指针指向最低位(即第一位)。

  2. INCREMENT操作:将指针所指位置的值加1,如果加1后该位值为1,则将指针向左移动一位;否则,将该位值置为0。

  3. RESET操作:将整个位数组置为0,指针指向最低位。

在执行操作序列时,我们按照操作的顺序依次进行上述步骤。因为每个操作只需要访问一位,所以花费时间为O(1)。由于我们总是将指针指向最高位的1,所以在最坏情况下,指针最多需要向左移动n次,因此总时间为O(n)。

这个方案的关键在于,我们通过移动指针和更新位数组的方式,有效地模拟了计数器的运算过程,同时保证了操作的时间复杂度为O(n)。

在这里插入图片描述

智谱清言:

为了实现一个对任意 n 个 INCREMENT 和 RESET 操作组成的序列花费时间 O(n) 的计数器,我们可以使用一个位数组,并维护一个指针,该指针一直指向最高位的 1 。

我们定义一个位数组 counts ,其中 counts[i] 表示从最高位到第 i 位(包含第 i 位)的 1 的个数。这样,对于任意一个位置 i,如果我们想要增加 counts[i] 的值,我们只需要将 counts[i]counts[len(counts) - 1] 都加 1 即可,因为这些位置的 1 都会对第 i 位产生影响。同理,如果我们想要重置 counts[i] 的值,只需要将 counts[i]counts[len(counts) - 1] 都置 0 即可。

为了实现这个计数器,我们需要以下几个操作:

1 INCREMENT(x):这个操作意味着我们需要将第 x 位加 1。因此,我们需要将 counts[x]counts[len(counts) - 1] 都加 1。由于我们只需要修改一次,这个操作的时间复杂度为 Θ(1)。

2.RESET():这个操作需要将所有的位都重置。因此,我们需要将整个 counts 数组都置 0。这个操作的时间复杂度为 Θ(1)。
由于每个操作的时间复杂度都是 Θ(1),所以对于任意 n 个操作组成的序列,总的时间复杂度为 O(n)。

下面是一个 Python 的实现:

class Counter:
    def __init__(self, width):
        self.width = width
        self.counts = [0] * (width + 1)
        self.pointer = 0
    def increment(self, x):
        for i in range(x, self.width + 1):
            self.counts[i] += 1
    def reset(self):
        for i in range(self.width + 1):
            self.counts[i] = 0
    def get_value(self):
        value = 0
        for i in range(self.width, 0, -1):
            if self.counts[i] > 0:
                value += 1 << (i - 1)
                break
        return value

这个 Counter 类包含了一个 increment 方法,一个 reset 方法和一个 get_value 方法。使用这个类,我们可以对计数器执行 INCREMENT 和 RESET 操作,并且可以获取当前计数器的值。这个实现满足了题目中的要求。

在这里插入图片描述

在这里插入图片描述

天工:

回答问题:位数组实现计数器的优化

概述
本次问题探讨的是如何使用位数组来实现计数器,并对计数器的操作进行优化,以减少执行时间。给定的条件是,计数器的初始值为0,并且可以进行INCREMENT(增加1)和RESET(清零)操作,我们需要设计一种数据结构和方法,使得执行任意数量的INCREMENT和RESET操作所花费的时间总和为O(n)。

位数组计数器的基本实现
一个直接的想法是将计数器表示为一个位数组,数组的每一位可以表示一个比特,初始时全部为0。当我们执行INCREMENT操作时,我们可以简单地将最高位的1向右移动一位,即进行位运算A[i] = (A[i] + 1) % 2;而执行RESET操作时,我们可以将所有位都设置为0,即进行位运算A[i] = 0

然而,这种方法在执行RESET操作时需要O(n)的时间来遍历所有位,导致无法满足题目要求的时间复杂度。因此,我们需要进一步优化。

优化策略
为了优化计数器,我们可以考虑维护一个指针,始终指向最高位的1。当执行INCREMENT操作时,我们可以简单地移动这个指针;而执行RESET操作时,我们可以从最高位的1开始向下遍历,找到所有位的0,并将它们设置为1。

具体来说,我们可以使用一个指针max_pointer来跟踪最高位的1的位置,初始时max_pointer为-1,表示没有找到1。当执行INCREMENT操作时,我们可以从max_pointer开始向上查找,直到找到1为止,然后将它向右移动一位。执行RESET操作时,我们从max_pointer开始向下查找,找到所有位的0,并将它们设置为1,然后重置max_pointer为-1。

详细描述
以下是使用位数组来实现计数器的伪代码:

class BitArrayCounter:
    def __init__(self):
        self.bits = [0] * (n + 1)  假设n是位数组的长度
        self.max_pointer = -1
    def increment(self):
        if self.max_pointer == -1:
            self.max_pointer = 0
        else:
            self.bits[self.max_pointer] = 0
            self.max_pointer += 1
    def reset(self):
        if self.max_pointer == -1:
            return
        for i in range(self.max_pointer, -1, -1):
            self.bits[i] = 0
        self.max_pointer = -1
对于任意的n次INCREMENT和RESET操作
def optimize_counter(n):
    bits_array = BitArrayCounter()
    for i in range(n):
        op = random.choice([1, 0])  假设0代表RESET,1代表INCREMENT
        if op == 1:
            bits_array.increment()
        else:
            bits_array.reset()
    return bits_array.bits

在这个实现中,BitArrayCounter类包含了一个位数组bits和一个指针max_pointerincrement方法用于执行INCREMENT操作,而reset方法用于执行RESET操作。由于每次操作只会影响max_pointer指针的位置,因此可以在O(1)时间内完成。
结论
通过上述优化,我们可以看到,无论是INCREMENT还是RESET操作,都可以在O(1)时间内完成,因此,对于任意长度的操作序列,总时间复杂度为O(n)。
引用索引

  • 计数器的类型和工作原理
  • 计数器的优化技巧
  • 算法导论中关于计数器的讨论
  • 《C和指针》中关于位操作的解释
  • 摊还分析的概念
    附注
    由于搜索结果中并没有直接提到位数组实现计数器的优化方法,所以上述答案是基于现有的计数器实现方法和位操作的知识推导出来的。在实际应用中,这种方法可以有效地减少计数器的操作时间,尤其是在进行大量RESET操作时。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

灵小智:

要实现一个计数器,使得执行任意n个INCREMENT和RESET操作的序列花费时间为O(n),可以使用一个位数组来表示计数器。

具体实现步骤如下:

1.首先创建一个位数组bits,用于表示计数器的每一位。初始时所有位都为0。

2.创建一个指针pointer,指向最高位的1。初始时指针指向第一个位。

3.执行INCREMENT操作时,将当前指针指向的位加1。如果该位的值变为1,则将指针向右移动一位,指向下一个位。

4.执行RESET操作时,将整个位数组都置为0,并将指针重新指向第一个位。

通过这种方式,对于每个INCREMENT操作,只需常数时间来修改一个位的值,并且在最坏情况下(即每次INCREMENT都使得指针移动到最右边),只需线性时间来将指针移动到正确的位置。因此,整个序列的执行时间为O(n)。

需要注意的是,上述实现假设了对一个位进行检测或修改的时间为Θ(1),即常数时间。如果位操作的时间复杂度不是常数,则整个操作序列的时间复杂度可能会受到影响。

在这里插入图片描述

chatgpt:

我们可以使用一个位数组来实现计数器,并通过维护一个指针来指向最高位的 1。

首先,创建一个大小为n+1的位数组,其中n是计数器能够表示的最大值。初始时,所有位都被置为0,并且指针指向最高位的下一位(即第n+1位)。

接下来,对于每个INCREMENT操作,我们从指针所在位置开始检查每一位。如果某一位为0,则将其设置为1,并将指针移到该位置上。如果某一位已经是1,则将其复位为0,并将指针移到下一位置上。这样可以保证指针始终指向最高位的1。

对于RESET操作,我们只需要将整个数组全部置为0,并将指针重新定位到第n+1位。

由于每次操作都只涉及到一个位的检测或修改操作,时间复杂度是常数级别的。而进行任意n个INCREMENT和RESET操作所花费的总时间与操作数量成正比,因此整个序列花费的时间是O(n)级别的。

总结起来,在这种实现方式下,我们利用了一个大小为n+1的位数组和一个额外的指针变量来维护计数器状态并支持增加和重置操作,在保证时间复杂度O(n)的前提下完成计数任务。

在这里插入图片描述

kimi:

为了实现一个计数器,我们可以使用一个位数组来存储计数器的值。数组的每个元素代表一个位,最左边的位(最高位)代表计数器的最高位。由于我们可以使用常数时间检测或修改一个位,我们需要一种策略来确保在执行 INCREMENT 和 RESET 操作时,总的时间复杂度为 O(n)。

以下是使用位数组实现计数器的方法:

  1. 初始化:创建一个长度为 k 的位数组 counter,其中 k 是我们希望计数器能够表示的最大值所需的位数。例如,如果我们希望计数器能够表示的值范围是 0 到 1023,那么 k 应该是 11(因为 2^11 = 2048)。初始化 counter 数组的所有位为 0。

  2. INCREMENT 操作

    • 遍历位数组 counter 从最低位到最高位。
    • 对于每个位,如果该位为 0,将其设置为 1 并停止遍历。
    • 如果所有位都是 1,这意味着计数器已经达到其最大值,无法再进行 INCREMENT 操作。在这种情况下,可以返回一个错误或特殊值,表示计数器溢出。
  3. RESET 操作

    • 将位数组 counter 的所有位设置为 0,重置计数器为 0。
  4. 维护指针:为了在 INCREMENT 操作中减少遍历的时间,我们可以维护一个指针 ptr,它始终指向最高位的 1。当我们执行 INCREMENT 操作时,我们首先检查 ptr 指向的位是否为 1。如果是,我们将其设置为 0 并递增 ptr。如果 ptr 已经指向最低位且该位为 1,我们知道计数器即将溢出。在执行 RESET 操作时,我们将 ptr 重置为指向最低位。

下面是这个过程的伪代码表示:

function increment(counter, ptr):
    while ptr < length(counter):
        if counter[ptr] == 0:
            counter[ptr] = 1
            return
        else:
            counter[ptr] = 0
            ptr += 1
    return overflow  // 表示计数器溢出

function reset(counter, ptr):
    for i = 0 to length(counter):
        counter[i] = 0
    ptr = 0  // 重置指针到最低位

// 初始化
counter = [0, 0, ..., 0]  // k 位的数组
ptr = 0

// 执行操作序列
for each operation in operations:
    if operation is INCREMENT:
        ptr = increment(counter, ptr)
    else if operation is RESET:
        reset(counter, ptr)

在这个实现中,INCREMENT 操作的时间复杂度是 O(k),因为最坏情况下我们需要遍历整个数组。然而,由于我们维护了一个指针 ptr 指向最高位的 1,所以在大多数情况下,INCREMENT 操作的时间复杂度会更低。RESET 操作的时间复杂度是 O(1),因为它只需要将所有位设置为 0。

对于任意长度为 n 的操作序列,总的时间复杂度是 O(n * k)。但是,由于我们只关心位的数量 k 而不是计数器可以表示的具体值,我们可以认为 k 是一个常数。因此,对于一个初值为 0 的计数器执行一个由任意 n 个 INCREMENT 和 RESET 操作组成的序列的总时间复杂度是 O(n)。

在这里插入图片描述

在这里插入图片描述

混元:

我们可以使用一个位数组(bit array)来实现这个计数器

  1. 初始化:创建一个位数组,将所有位初始化为 0。同时,设置一个指针,初始时指向数组的第一个位置。

  2. INCREMENT 操作:
    a. 将指针所指向的位设置为 1。
    b. 检查指针左侧的位是否为 1。如果是,则将指针向左移动一位。否则,停止移动指针。

  3. RESET 操作:
    a. 将指针指向的位设置为 0。
    b. 将指针移动到数组的第一个位置。

这样,我们可以在 O(n) 时间内执行任意 n 个 INCREMENT 和 RESET 操作。因为每个操作只需要检查和修改 O(1) 个位,而指针的移动次数也是 O(1)。

以下是一个 Python 示例实现:

class Counter:
    def __init__(self):
        self.bit_array = [0] * 64  # 假设计数器的最大值为 2^64 - 1
        self.pointer = 0

    def increment(self):
        self.bit_array[self.pointer] = 1
        if self.pointer > 0 and self.bit_array[self.pointer - 1] == 1:
            self.pointer -= 1

    def reset(self):
        self.bit_array[self.pointer] = 0
        self.pointer = 0

    def get_value(self):
        value = 0
        for i in range(self.pointer, len(self.bit_array)):
            value += self.bit_array[i] * (1 << i)
        return value

这个实现中,incrementreset 方法分别对应 INCREMENT 和 RESET 操作。get_value 方法用于获取计数器的当前值。

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1588912.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【每日练习】二叉树

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;二叉树 &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 文章目录 一、100. 相同的树1. 题目简介2.…

程序员需要考证吗?程序员考证真的有用吗?

程序员需要考证吗?程序员考证真的有用吗? 软考简介 软考&#xff0c;即软件设计师考试&#xff0c;是由中国人事部主管的一项专业技术资格考试。通过软考&#xff0c;考生可以获得软件设计师等级证书&#xff0c;这是国家认可的专业技术资格证书之一。软考作为我国软件行业的…

docker安装华为高斯-opengauss

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

【XR806开发板试用】自带mqtt的调试教学

1、下载代码 mkdir xr806_openharmony cd xr806_openharmony repo init -u ssh://gitgitee.com/openharmony-sig/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify -m devboard_xr806.xml repo sync -c repo forall -c git lfs pull **最近仓库在整合&#xff…

软件设计师-基础知识科目-算法设计与分析8

八、算法设计与分析&#xff1a; 常见算法&#xff1a; 回溯方法&#xff1a; 用深度优先的探索问题的解空间。应用场景&#xff1a;N皇后问题。&#xff08;背&#xff09; 分支界限法&#xff1a; 用广度优先的探索问题的解空间&#xff0c;采用的是分支界限法算法设计策…

【数据库】PostgreSQL源码编译安装方式与简单配置(v16.2)

PostgreSQL源码编译安装方式与简单配置&#xff08;v16.2&#xff09; 一、PostgreSQL安装基本介绍1.1 几种PostgreSQL的安装方式1.2 删除原有的PostgreSQL1.3 编译安装过程简介 二、源码编译安装方式详情2.1 下载源代码2.2 编译安装运行 configure执行 make执行 make install …

监控服务zabbix的部署

监控服务zabbix部署 文章目录 监控服务zabbix部署1. zabbix介绍2. zabbix特点3. zabbix配置文件4. 部署zabbix4.1apache安装4.2mysql安装php安装(yum方式)4.3php安装&#xff08;源码方式&#xff09;4.4配置apache代理4.5zabbix安装4.6zabbix服务端配置4.7zabbix服务端web界面…

Python应用|获取矢量数据的多边形个数

import geopandas as gpd #首先导入geopandas包# 读取Shapefile文件 shp_file "E:\python\china" gdf gpd.read_file(shp_file)# 获取多边形个数 num_polygons len(gdf)print("Number of polygons:", num_polygons) 图1|输出结果

淄博、哈尔滨、天水…社交媒体助推下的网红城市能“长红”吗?

烧烤卷饼带火山东传统工业小镇淄博&#xff1b; 冰雪狂欢让东北的哈尔滨在寒冬爆火&#xff1b; 一碗麻辣烫让西北天水小城变“网红”…… 在刚刚过去的清明假期&#xff0c;甘肃天水可谓是“热辣滚烫”&#xff0c;在春暖花开时节&#xff0c;迎来了属于它的春天。而被人们逐…

QT:QMainWindow、ui界面、资源文件的添加、信号和槽

1.练习&#xff1a;使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(…

【STL】栈(stack)

笔者在做下面这道题的时候想到用栈&#xff0c;但写的很麻烦 代码&#xff1a; #include<bits/stdc.h> using namespace std; #define MAXC 255 typedef int SElemType; typedef struct StackNode {SElemType data;struct StackNode *next; }StackNode,*LinkStack; bool…

LiveNVR监控流媒体Onvif/RTSP功能-概览负载统计展示取流中、播放中、录像中点击柱状图快速定位相关会话

LiveNVR概览负载统计展示取流中、播放中、录像中点击柱状图快速定位相关会话 1、负载信息说明2、快速定位会话3、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、负载信息说明 实时展示取流中、播放中、录像中等使用数目 取流中&#xff1a;当前拉流到平台的实时通道数目播放中&am…

天诚物联网锁亮相福州南京沈阳西安展会,与您见证AIoT行业发展

目光灼灼&#xff0c;步履不辍。自4月1日第七届CCLE中国教育后勤展览会一别&#xff0c;全场景AIoT解决方案服务商——江苏新巢天诚智能技术有限公司&#xff08;以下简称“天诚”&#xff09;打造的校园物联网锁软硬一体化解决方案获得了诸多准意向代理商、集成商同仁们的咨询…

人形机器人行业报告:AI赋能人形机器人开启产业化元年

今天分享的是人形机器人专题系列深度研究报告&#xff1a;《AI赋能&#xff0c;人形机器人开启产业化元年》。 &#xff08;报告出品方&#xff1a;国泰君安证券&#xff09; 报告共计&#xff1a;56页 要点 通用性是人形机器人商业化的关键&#xff0c;AI大模型赋能加速机…

蓝桥杯 每日2题 day5

碎碎念&#xff1a;哦哈呦&#xff0c;到第二天也是哦哈哟&#xff0c;&#xff0c;学前缀和差分学了半天&#xff01;day6堂堂连载&#xff01; 0.单词分析 14.单词分析 - 蓝桥云课 (lanqiao.cn) 关于这题就差在input前加一个sorted&#xff0c;记录一下下。接下来就是用字…

jenkins+git+maven+nodejs安装(linux系统)

前文已经安装完成sonarqube和Sonar Scanner了&#xff0c;接下来可以开始jenkins了 jenkins安装 命令&#xff08;版本为 2.440&#xff09; wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo wget https://pkg.jenkins.io/redh…

golangci-lint 报错

File is not gci-ed with --skip-generated -s standard,default (gci) golangci-lint 报错上面的错解决办法&#xff1a; 1. 文件换行需要换成"LF" 而不是"CRLF" ---->>> 我用的goland IDE&#xff0c;随便在这个文件删除一个空行&#xff…

《手把手教你》系列基础篇之2-python+ selenium自动化测试-打开和关闭浏览器(详细)

1. 简介 本节介绍如何初始化一个webdriver实例对象driver&#xff0c;然后打开和关闭firefox浏览器。要用selenium打开fiefox浏览器。首先需要去下载一个driver插件geckodriver.exe&#xff0c; 下载地址https://github.com/mozilla/geckodriver/releases&#xff0c;下载好这…

爬虫现在还有那么吃香嘛?

Python 作为一种广泛应用的编程语言&#xff0c;在 Web 开发、大数据开发、人工智能开发和嵌入式开发等领域都有着重要的应用。 Python 的易学性、清晰性和可移植性等特点使它得到很多技术人士的喜爱。对于数据科学和机器学习领域的程序员来说&#xff0c;Python 提供了强大的…

并发编程-线程安全:volatile、Lock、synchronized、CAS、ABA、AQS

并发编程-线程安全 1、volatile 关键字1.1 作用1.2 底层实现原理 2、synchronized2.2 synchronized 用法2.2 synchronized 和 volatile 的区别 3、Lock3.1 Lock 和 synchronized 的区别3.2 ReentrantLock 和 synchronized 的区别 4、CAS4.1 CAS 执行流程4.2 ABA问题 5、AQS&…