Inhaltsverzeichnis
几种保证线程安全的方案 " >几种保证线程安全的方案
1. 通过synchronized关键字实现同步:
2. 通过Lock锁实现同步
3. 使用 Atomic 原子类
4. 使用 LongAdder 原子类
CAS理论 " >CAS理论
CAS的实现 " >CAS的实现
Heim Java JavaInterview Fragen Echte Interviewfrage: Bitte sprechen Sie über den CAS-Mechanismus bei Parallelität

Echte Interviewfrage: Bitte sprechen Sie über den CAS-Mechanismus bei Parallelität

Jul 26, 2023 pm 03:05 PM
cas

Ich frage mich, ob Schüler jemals ein solches Interview erlebt haben:

Interviewer: Bitte sprechen Sie über den CAS-Mechanismus in Parallelität
Xiao Ming: Nun, CAS, richtig? Ich scheine davon gehört zu haben ... Denken Sie nach darüber (Gehirn denkt schnell nach)

2 Minuten sind vergangen...
Die Luft ist totenstill...

Der Interviewer konnte nicht still sitzen und räusperte sich : Ähem... Das, können Sie sagen mich kurz?
Xiao Ming lächelte naiv: Hehe, ich scheine es vergessen zu haben...
Interviewer: Oh, es ist okay, das war's für das heutige Interview, du gehst zurück und wartest auf die Benachrichtigung
Xiao Ming ging niedergeschlagen...


Lachen Sie nicht, Xiao Ming ist tatsächlich der Schatten vieler Menschen. Es gibt viele Klassenkameraden, die während des Interviewprozesses peinliche Gespräche führen, natürlich spiegelt dies eine sehr grausame Realität wider: Das Fundament ist nicht solide!

Dann stellt sich die Frage, wie man den Interviewer im Interview besiegt und felsenfest bleibt?

Lernen! Was nützt es, nur zu reden? Man muss lernen, man muss die Bücher lesen, die man kauft, und man muss den Kursen folgen, die man kauft. Wenn man stärker werden will, muss man nicht nur Spiele spielen und Fernsehdramen verfolgen muss eine Glatze haben!

Es ist jetzt 0:08 Uhr Pekinger Zeit. Ich schreibe einen Artikel im Code.

Echte Interviewfrage: Bitte sprechen Sie über den CAS-Mechanismus bei Parallelität

Ein kleines Beispiel, um darüber zu sprechen, was Thread-Sicherheit ist

Parallelität ist die Grundlage der Java-Programmierung. Natürlich wird dies auch getestet Interviews. Bei der gleichzeitigen Programmierung ist das am häufigsten erwähnte Konzept 线程安全 Schauen wir uns einen Code an, um zu sehen, was nach der Ausführung passiert:

public class Test {
    private static int inc = 0;

    public static void main(String[] args) {
     // 设置栅栏,保证主线程能获取到程序各个线程全部执行完之后的值
        CountDownLatch countDownLatch = new CountDownLatch(1000000);
        // 设置100个线程同时执行
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
             // 循环10000次,对inc实现 +1 操作
                for (int j = 0; j < 10000; j++) {
                    inc++;
                    countDownLatch.countDown();
                }
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 运行完毕,期望获取的结果是 1000000
        System.out.println("执行完毕,inc的值为:" + inc);
    }
}
Nach dem Login kopieren

Im Programm habe ich 100 Threads und gemeinsame Variablen in jedem Thread erstelltinc führt eine 10.000-fache Akkumulationsoperation aus. Wenn es synchron ausgeführt wird, sollte der Endwert von inc 1.000.000 sein, aber wir wissen, dass das Programm in Multithreads gleichzeitig ausgeführt wird, was unterschiedlich bedeutet Threads können gleichzeitig denselben Wert aus dem Hauptspeicher lesen, wie in diesem Szenario: inc进行累加10000次的操作,如果是同步执行的话,inc最终的值应该是1000000,但我们知道在多线程中,程序是并发执行的,也就是说不同的线程可能会同时读取到主内存相同的值,比如这样的场景:

  • 线程A在某一个瞬间读取了主内存的inc值为1000,它在自己的工作内存 +1,inc变成了1001;
  • 线程B在同样的瞬间读取到了主内存的inc值为1000,它也在自己的工作内存中对inc的值 +1, inc变成了1001;
  • 他们要往主内存写入inc的值的时候并没有做任何的同步控制,所以他们都有可能把自己工作内存的1001写入到主内存;
  • 那么很显然主内存在进行两次 +1 操作后,实际的结果只进行了一次 +1,变成了1001。

这就是一个很典型的多线程并发修改共享变量带来的问题,那么很显然,它的运行结果也如我们分析的那样,某些情况下达不到1000000:

执行完毕,inc的值为:962370
Nach dem Login kopieren

有些人说通过volatile关键字可以解决这个问题,因为volatile可以保证线程之间的可见性,也就是说线程可以读取到主内存最新的变量值,然后对其进行操作。

注意了,volatile只能保证线程的可见性,而不能保证线程操作的原子性,虽然线程读取到了主内存的inc的最新值,但是 读取inc+1写入主内存

  • Thread A las den Inc-Wert des Hauptspeichers zu einem bestimmten Zeitpunkt als 1000. Er fügte 1 zu seinem eigenen Arbeitsspeicher hinzu und der Inc wurde zu 1001;
  • Thread B las gleichzeitig den Inc-Wert des Hauptspeichers als 1000 und es Fügen Sie außerdem 1 zum Wert von inc in Ihrem eigenen Arbeitsspeicher hinzu, und inc wird zu 1001.
  • Wenn sie den Wert von inc in den Hauptspeicher schreiben möchten, führen sie keine Synchronisationssteuerung durch, sodass alle 1001 ihres Arbeitsspeichers in den Hauptspeicher schreiben können Speicher;
  • Dann Es ist offensichtlich, dass das tatsächliche Ergebnis nur einmal +1 ausführt und 1001 wird, nachdem der Hauptspeicher zwei +1-Operationen ausgeführt hat.

Dies ist ein sehr typisches Problem, das dadurch verursacht wird, dass mehrere Threads gleichzeitig gemeinsam genutzte Variablen ändern. In einigen Fällen können die Ergebnisse nicht erreicht werden 1000000:

public class Test {
    private static int inc = 0;

    public static void main(String[] args) {
        // 设置栅栏,保证主线程能获取到程序各个线程全部执行完之后的值
        CountDownLatch countDownLatch = new CountDownLatch(1000000);
        // 设置100个线程同时执行
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                // 循环10000次,对inc实现 +1 操作
                for (int j = 0; j < 10000; j++) {
                 // 设置同步机制,让inc按照顺序执行
                    synchronized (Test.class) {
                        inc++;
                    }

                    countDownLatch.countDown();
                }
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行完毕,inc的值为:" + inc);
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Manche Leute sagen mit 27, 31, 35, 0,05);Schriftfamilie: „Operator Mono“, Consolas, Monaco, Menlo, Monospace;Word-Break: Break-All;Farbe: RGB(239, 112 , 96);">volatile kann dieses Problem lösen, da volatile die Sichtbarkeit zwischen Threads gewährleisten kann, was bedeutet, dass Threads die neuesten Variablenwerte im Hauptspeicher lesen und sie dann bearbeiten können. 🎜🎜Hinweis: Volatil kann nur die Lesen, synchronized 设置类锁,保证了代码的同步执行,这是一种基于JVM自身的机制来保障线程的安全性,如果在并发量比较大的情况下,synchronized 会升级为重量级的锁,效率很低。synchronized无法获取当前线程的锁状态,发生异常的情况下会自动解锁,但是如果线程发生阻塞,它是不会释放锁的

执行结果:

执行完毕,inc的值为:1000000
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

可以看到,这种方式是可以保证线程安全的。

2. 通过Lock锁实现同步

public class Test {
    private static int inc = 0;
    private static Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        // 设置栅栏,保证主线程能获取到程序各个线程全部执行完之后的值
        CountDownLatch countDownLatch = new CountDownLatch(1000000);

        // 设置100个线程同时执行
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                // 循环10000次,对inc实现 +1 操作
                for (int j = 0; j < 10000; j++) {
                 // 设置锁
                    lock.lock();
                    try {
                        inc++;
                    } finally {
                     // 解锁
                        lock.unlock();
                    }
                    countDownLatch.countDown();
                }
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行完毕,inc的值为:" + inc);
    }
}
Nach dem Login kopieren

ReentrantLock的底层是通过AQS + CAS来实现的,在并发量比较小的情况下,它的性能不如 synchronized,但是随着并发量的增大,它的性能会越来越好,达到一定量级会完全碾压synchronized。并且Lock是可以尝试获取锁的,它通过代码手动去控制解锁,这点需要格外注意。

执行结果:

执行完毕,inc的值为:1000000
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

3. 使用 Atomic 原子类

public class Test {
    private static AtomicInteger inc = new AtomicInteger();

    public static void main(String[] args) {
        // 设置栅栏,保证主线程能获取到程序各个线程全部执行完之后的值
        CountDownLatch countDownLatch = new CountDownLatch(1000000);

        // 设置100个线程同时执行
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                // 循环10000次,对inc实现 +1 操作
                for (int j = 0; j < 10000; j++) {
                    inc.getAndAdd(1);
                    countDownLatch.countDown();
                }
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行完毕,inc的值为:" + inc.get());
    }
}
Nach dem Login kopieren

AtomicInteger 底层是基于 CAS 的乐观锁实现的,CAS是一种无锁技术,相对于前面的方案,它的效率更高一些,在下面会详细介绍。

执行结果:

执行完毕,inc的值为:1000000
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

4. 使用 LongAdder 原子类

public class Test {
    private static LongAdder inc = new LongAdder();

    public static void main(String[] args) {
        // 设置栅栏,保证主线程能获取到程序各个线程全部执行完之后的值
        CountDownLatch countDownLatch = new CountDownLatch(1000000);

        // 设置100个线程同时执行
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                // 循环10000次,对inc实现 +1 操作
                for (int j = 0; j < 10000; j++) {
                    inc.increment();
                    countDownLatch.countDown();
                }
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("执行完毕,inc的值为:" + inc.intValue());
    }
}
Nach dem Login kopieren

LongAdder 原子类在 JDK1.8 中新增的类,其底层也是基于 CAS 机制实现的。适合于高并发场景下,特别是写大于读的场景,相较于 AtomicInteger、AtomicLong 性能更好,代价是消耗更多的空间,以空间换时间。

执行结果:

执行完毕,inc的值为:1000000
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren
Nach dem Login kopieren

CAS理论

讲到现在,终于我们今天的主角要登场了,她就是CAS

CAS的意思是比较与交换(Compare And Swap),它是乐观锁的一种实现机制。

什么是乐观锁?通俗的来说就是它比较乐观,每次在修改变量的值之前不认为别的线程会修改变量,每次都会尝试去获得锁,如果获取失败了,它也会一直等待,直到获取锁为止。说白了,它就是打不死的小强。

而悲观锁呢,顾名思义,就比较悲观了,每次在修改变量前都会认为别人会动这个变量,所以它会把变量锁起来,独占,直到自己修改完毕才会释放锁。说白了,就是比较自私,把好东西藏起来自己偷偷享用,完事了再拿出来给别人。像之前的synchronized关键字就是悲观锁的一种实现。

CAS是一种无锁原子算法,它的操作包括三个操作数:需要读写的内存位置(V)、预期原值(A)、新值(B)。仅当 V值等于A值时,才会将V的值设为B,如果V值和A值不同,则说明已经有其他线程做了更新,则当前线程继续循环等待。最后,CAS 返回当前V的真实值。CAS 操作时抱着乐观的态度进行的,它总是认为自己可以成功完成操作。

CAS的实现

在Java中,JUC的atomic包下提供了大量基于CAS实现的原子类:

Echte Interviewfrage: Bitte sprechen Sie über den CAS-Mechanismus bei Parallelität

我们以AtomicInteger来举例说明。

AtomicInteger类内部通过一个Unsafe类型的静态不可变的变量unsafe来引用Unsafe的实例。

 // setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
Nach dem Login kopieren

然后,AtomicInteger类用value保存自身的数值,并用get()方法对外提供。注意,它的value是使用volatile修饰的,保证了线程的可见性。

private volatile int value;

/**
 * Creates a new AtomicInteger with the given initial value.
 *
 * @param initialValue the initial value
 */
public AtomicInteger(int initialValue) {
    value = initialValue;
}

/**
 * Gets the current value.
 *
 * @return the current value
 */
public final int get() {
    return value;
}
Nach dem Login kopieren

一路跟踪incrementAndGet方法到的末尾可以看到是一个native的方法:

/**
 * Atomically increments by one the current value.
 *
 * @return the updated value
 */
public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

//  getAndAddInt 方法
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

    return var5;
}

// compareAndSet方法
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
Nach dem Login kopieren

可以看到其实incrementAndGet内部的原理就是通过compareAndSwapInt调用底层的机器指令不断比较内存旧值和期望的值,如果比较返回false就继续循环比较,如果返回true则将当前的新值赋给内存里的值,本次处理完毕。

由此我们知道,原子类实现的自增操作可以保证原子性的根本原因在于硬件(处理器)的相关指令支持。将语义上需要多步操作的行为通过一条指令来完成,CAS指令可以达到这个目的。

Nachteile von CAS

CAS wird unweigerlich ABA-Probleme haben. Erklärungen und Lösungen für ABA-Probleme finden Sie in meinem Artikel: Der Interviewer fragt Sie: Wissen Sie, was ABA-Probleme sind?

  • Okay, dieses Mal endet der Austausch über CAS hier.
    Als Eckpfeiler der Java-Programmierung ist Parallelität ein sehr wichtiger Wissenspunkt. Wenn die Schüler dieses Thema nur schwach verstehen, hoffe ich, dass ich nach dem Lesen des Artikels den Code selbst eingeben und darüber nachdenken kann, was CAS ist und was Seine Vor- und Nachteile sind die Implementierungsmethoden.
    Natürlich ist Parallelität ein sehr großes Konzept. Hier ist nur eine kleine Einführung, in der ich einen der kleinen Wissenspunkte erwähne und einige meiner eigenen Lernerfahrungen darlege.
Wenn etwas nicht richtig erklärt wird oder falsch ist, senden Sie mir bitte eine private Nachricht, um es gemeinsam zu besprechen, vielen Dank!

Ich bin Programmierer Qing Ge Die Interviewfragen für diese Ausgabe werden hier geteilt. Wer sich verbessern und zu großen Unternehmen aufsteigen möchte, muss auf meinen offiziellen Account achten: Java Study Guide

Hier helfen wir Ihnen, Java-bezogenes Wissen basierend auf täglichen Interviews zu erlernen und zusammenzufassen, um Ihren Technologie-Stack zu erweitern und Ihre persönliche Stärke zu verbessern. Bis zum nächsten Mal~

Das obige ist der detaillierte Inhalt vonEchte Interviewfrage: Bitte sprechen Sie über den CAS-Mechanismus bei Parallelität. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Implementieren Sie die PHP-Sicherheitsüberprüfung über CAS (Central Authentication Service). Implementieren Sie die PHP-Sicherheitsüberprüfung über CAS (Central Authentication Service). Jul 24, 2023 pm 12:49 PM

PHP-Sicherheitsüberprüfung durch CAS (CentralAuthenticationService) Mit der rasanten Entwicklung des Internets werden Benutzerrechteverwaltung und Identitätsüberprüfung immer wichtiger. Bei der Entwicklung von Webanwendungen ist es von entscheidender Bedeutung, Benutzerdaten zu schützen und unbefugten Zugriff zu verhindern. Um dieses Ziel zu erreichen, können wir CAS (CentralAuthenticationService) zur PHP-Sicherheitsüberprüfung verwenden. CAS

Was ist das Konzept von Java CAS? Was ist das Konzept von Java CAS? May 03, 2023 pm 09:34 PM

1. Erklären Sie, dass, wenn mehrere Threads gleichzeitig CAS-Operationen für eine Ressource ausführen, nur ein Thread erfolgreich ist, andere Threads jedoch nicht blockiert werden und andere Threads nur ein Signal erhalten, dass die Operation fehlgeschlagen ist. Es ist ersichtlich, dass CAS tatsächlich eine optimistische Sperre ist. 2. Wenn wir dem AtomInteger-Code folgen, können wir feststellen, dass letztendlich sum.misc.Unsafe aufgerufen wird. Schauen Sie sich den Namen „Unsafe“ an. Dabei handelt es sich um eine unsichere Klasse, die genau die richtigen Lücken in den Klassen- und Sichtbarkeitsregeln von Java ausnutzt. Aus Gründen der Geschwindigkeit geht Unsafe einige Kompromisse bei den Sicherheitsstandards von Java ein. publicfinalnativebooleancompareAndSwapInt(Objec

So verwenden Sie CAS und Java Optimistic Locking So verwenden Sie CAS und Java Optimistic Locking May 01, 2023 pm 08:07 PM

Was CASCAS ist, ist CompareAndSwap, also Vergleichen und Tauschen. Warum verwendet CAS keine Sperren, gewährleistet aber dennoch den sicheren Betrieb von Daten unter gleichzeitigen Bedingungen? Daten und der zu ändernde Wert werden an die Methode übergeben, um zu vergleichen, ob der aktuelle Zielvariablenwert mit dem ursprünglich übergebenen Wert übereinstimmt. Wenn sie identisch sind, bedeutet dies, dass die Zielvariable nicht von anderen Threads geändert wurde . Ändern Sie einfach den Zielvariablenwert direkt, dann beweisen Sie, dass die Zielvariable von anderen Threads geändert wurde. Aus dem obigen Prozess können wir ersehen garantiert tatsächlich eine sichere Änderung der Daten, es gibt jedoch Fälle, in denen die Änderung fehlschlägt.

So wenden Sie CAS in Java an So wenden Sie CAS in Java an Apr 18, 2023 pm 06:37 PM

CAS-Erklärung: CAS (compareandswap), vergleichen und austauschen. Ein Mechanismus, der den durch die Verwendung von Sperren in Situationen mit mehreren Threads verursachten Leistungsverlust beheben kann. Die CAS-Operation enthält drei Operanden: Speicherort (V), erwarteter Originalwert (A) und neuer Wert (B). Wenn der Wert eines Speicherorts mit dem erwarteten Originalwert übereinstimmt, aktualisiert der Prozessor den Ort automatisch auf den neuen Wert. Ansonsten macht der Prozessor nichts. Ein Thread ruft den Num-Wert aus dem Hauptspeicher ab und verarbeitet Num. Beim Schreiben des Werts vergleicht der Thread den ersten Num-Wert mit dem Num-Wert im Hauptspeicher. Wenn sie gleich sind, ist der geänderte Wert Num Wenn sie nicht gleich sind, wird der Vergleich wiederholt, bis er erfolgreich ist. Hergestellt von CAS

Java-Sperren-Parallelität, sperrenfreie Parallelität und CAS-Beispielanalyse Java-Sperren-Parallelität, sperrenfreie Parallelität und CAS-Beispielanalyse May 23, 2023 pm 01:34 PM

Gesperrte Parallelität Für die meisten Programmierer (natürlich bin ich im Grunde einer von ihnen) ist gleichzeitiges Programmieren fast gleichbedeutend mit dem Hinzufügen einer Sperre (Mutex) zur relevanten Datenstruktur. Wenn wir beispielsweise einen Stapel benötigen, der Parallelität unterstützt, besteht die einfachste Möglichkeit darin, eine Sperre std::sync::Mutex zu einem Single-Threaded-Stack hinzuzufügen. (Arc wird hinzugefügt, um mehreren Threads den Besitz des Stapels zu ermöglichen) usestd::sync::{Mutex,Arc};#[derive(Clone)]structConcurrentStack{inner:Arc,}implConcurrentStack{pubfnnew()-> Self{

Echte Interviewfrage: Bitte sprechen Sie über den CAS-Mechanismus bei Parallelität Echte Interviewfrage: Bitte sprechen Sie über den CAS-Mechanismus bei Parallelität Jul 26, 2023 pm 03:05 PM

Im Programm habe ich 100 Threads erstellt und jeder Thread hat 10.000 Operationen für die gemeinsam genutzte Variable inc gesammelt. Wenn es synchron ausgeführt wird, sollte der Endwert von inc 1.000.000 sein, aber wir wissen, dass das Programm beim Multithreading gleichzeitig ausgeführt wird Das heißt, verschiedene Threads können gleichzeitig denselben Wert aus dem Hauptspeicher lesen.

So erstellen Sie einen CAS-Client basierend auf Springboot So erstellen Sie einen CAS-Client basierend auf Springboot May 14, 2023 am 10:46 AM

1. Erstellen Sie ein neues Springboot-Projekt und führen Sie die Abhängigkeit org.jasig.cas.clientcas-client-support-springboot3.6.22 ein. Konfigurieren Sie das @EnableCasClient-Annotationspaketcom.codetiler.demo;importorg.jasig.cas.client.boot.configuration. EnableCasClient;importorg.springframework.boot.SpringApplication;importorg.spring

Der Interviewer fragt Sie: Wissen Sie, was ein ABA-Problem ist? Der Interviewer fragt Sie: Wissen Sie, was ein ABA-Problem ist? Jul 26, 2023 pm 03:09 PM

In dieser Ausgabe geht es um die Analyse eines klassischen ABA-Problems im CAS-Bereich. Ich weiß nicht, ob Sie in der tatsächlichen Arbeit darauf gestoßen sind, aber dies ist der Schwerpunkt des Parallelitätswissenstests im Interview. Wenn Sie noch nicht auf ein solches Problem gestoßen sind, empfehle ich Ihnen, den obigen Code selbst auszuführen.

See all articles