当前位置:网站首页>JUC interview questions about synchronized, ThreadLocal, thread pool and atomic atomic classes
JUC interview questions about synchronized, ThreadLocal, thread pool and atomic atomic classes
2022-04-23 13:43:00 【0oIronhide】
List of articles
-
-
-
- 1. say synchronized keyword
- 2. How do you use it? synchronized keyword
- 3. The way synchronized The underlying principle of keywords
- 4. JDK1.6 After that synchronized What optimizations have been done at the bottom of keywords
- 5. Synchronized And Lock The difference between locks
- 6. Synchronized And ReentrantLock The difference between
- 7. ThreadLocal What is it?
- 8. The way ThreadLocal principle
- 9. Why? ThreadLocalMap Does the bottom layer need an array ? How to solve the problem without the linked list Hash What about the conflict ?
- 10. Whether the objects in the thread are stored in the heap or stack ?
- 11. ThreadLocal Is the instance and its value stored on the stack ?
- 12. ThreadLocal Memory leak of
- 13. Want to share threads ThreadLocal What about the data ?
- 14. Class implementation Runnable Interface and implementation Callable Interface differences
- 15. Thread pool execution execute() Methods and submit() What's the difference between methods ?
- 16. How to create a thread pool
- 17. What are the four rejection strategies when the thread pool is saturated
- 18. Analysis of the principle of thread pool executing tasks
- 19. Introduce to you Atomic Atomic classes
- 20. JUC What is the atomic class in the package 4 class ?
- 21. Tell me about AtomicInteger Use
- 22. Introduce to you AtomicInteger The principle of class
-
-
1. say synchronized keyword
synchronized Solve the synchronization of accessing resources in multi-threaded environment , By synchronized A modified method or code block can only be executed by one thread at a time . stay jdk6 Before ,synchronized It's a heavyweight lock , inefficiency ; stay jdk6 after ,Java The official in the JVM Face to face synchronized Make major optimization , It also optimizes the implementation of locks , Such as the spin lock 、 Adaptive spin lock 、 Lock elimination 、 Lock coarsening 、 Biased locking 、 Lightweight lock and other technologies to reduce the cost of lock operation .
2. How do you use it? synchronized keyword
- Decorated instance method , Is to lock the instance of the current object .
- Modified static method , Is to give the current class class Object locking , The lock is no longer an instance member , But class members , So if a thread A Calling an instance object is not static synchronized Method , And threads B You need to call the static state of the class to which this instance object belongs synchronized Method , Permissible , There will be no mutual exclusion , Because accessing static synchronized The lock occupied by the method is the lock of the current class , Access is not static synchronized The lock occupied by the method is the current instance object lock .
- Decorated code block , Lock the specified object .
3. The way synchronized The underlying principle of keywords
-
When decorating a code block :
Use javac Compile the following classes :
public class SynchronizedDemo { public void method() { synchronized (this) { System.out.println("synchronized"); } } }
After compiling the bytecode file , adopt
javap -c -s -v -l SynchronizedDemo.class
decompile , Check the decompiled method :
You can find the 3 Xing He 13 The difference is monitorenter And monitorexit , Come to the conclusion : among monitorenter The instruction points to the start of the synchronization block ,monitorexit The command indicates the end of the synchronization block .
Every Java Objects all contain a monitor object , There is also a counter , When executed monitorenter When the command , Get the current object , Then lock the counter +1. Corresponding in the implementation monitorexit After the instruction , Set the lock counter to 0, Indicates that the current object is released .
-
When modifying a method :
Compile the following code :
public class SynchronizedDemo { public synchronized void method() { System.out.println("synchronized"); } }
After decompiling :
Find previous examples monitorenter And monitorexit The instructions are gone , It is ACC_SYNCHRONIZED identification ; This flag indicates that the method is a synchronization method ,JVM This identifier is used to identify whether a method is declared as a synchronous method , So as to execute the corresponding synchronous call .
4. JDK1.6 After that synchronized What optimizations have been done at the bottom of keywords
JDK1.6 A lot of optimizations have been introduced into the implementation of locks , Such as biased lock 、 Lightweight lock 、 spinlocks 、 Adaptive spin lock 、 Lock elimination 、 Lock coarsening and other technologies to reduce the cost of lock operation .
There are four main states of locks , In turn, is : No lock state 、 Biased lock state 、 Lightweight lock state 、 Heavyweight lock state , They will gradually upgrade with the fierce competition . Note that locks can be upgraded, not demoted , This strategy is to improve the efficiency of obtaining and releasing locks .
5. Synchronized And Lock The difference between locks
- Synchronized It's a keyword ;Lock Is a class
- Synchronized Unable to get lock status ;Lock You can know the status of the current lock and the owner of the lock ;
- Synchronized Will automatically release the lock ;Lock Need to manually lock and unlock
- Synchronized, A thread gets a lock , The rest of the threads have to wait ; Use Lock, Other threads do not necessarily wait
- Synchronized It's a reentrant lock , You can't interrupt , Unfair ;Lock It's also a re-entry lock , You can get the lock state 、 Fair and unfair locks can be set
- Synchronized Suitable for locking a small number of synchronous statement blocks ,Lock Suitable for locking a large number of synchronous statement blocks
6. Synchronized And ReentrantLock The difference between
- Both are reentrant locks , Reentrant lock, e.g :
// Reentrant lock means that the same lock can be acquired multiple times in a thread
// The main thread is calling method1 Time to get test Object lock , stay method1 Call in method2, The main thread does not need to retrieve test lock
public class SynchronizedDemo {
public static void main(String[] args) {
Test test = new Test();
test.method1();
}
}
class Test {
synchronized void method1() {
System.out.println("method1");
this.method2();
}
synchronized void method2() {
System.out.println("method2");
}
}
- synchronized Depend on JVM and ReentrantLock Depend on API
|
synchronized It depends on JVM Realized , Not directly exposed to us .ReentrantLock Is a class , Is in JDK Level realized , We need to do it manually lock() and unlock() , We can check the source code , See how it works .
- ReentrantLock Than synchronized More powerful
|
- ReentrantLock Fair and unfair lock can be realized , By constructor
ReentrantLock(boolean fair)
Realization- Know the status of the current lock and the owner of the lock
- Implement wait interruptible , adopt
lock.lockInterruptibly()
To implement this mechanism . That is to say, the waiting thread can choose to give up waiting , Deal with other things instead- The implementation specifies to wake up a waiting thread , adopt
lock.newCondition()
Get one condition After the object , Thread waiting can be realizedcondition.await();
、 Wake up the specified threadcondition1.signal();
、 Wake up all threadscondition.signalAll();
and synchronized Keywords are equivalent to the whole Lock There is only one object Condition example , All threads are registered on one of them . If you execute notifyAll() Method will notify all waiting threads , This will cause great efficiency problems , and Condition Example of signalAll() Method Will only wake up registration in this Condition All waiting threads in the instance .
7. ThreadLocal What is it?
Usually , The variables we create can be accessed and modified by any thread . If you want to realize that each thread has its own unique local variables, how to solve it ? JDK Provided in
ThreadLocal
Class is to solve this problem .ThreadLocal
The main solution of class is to let each thread bind its own value , Can beThreadLocal
A class image is a box for storing data , The box can store the private data of each thread .
If you create a
ThreadLocal
Variable , Then each thread accessing this variable will have a local copy of this variable , This is alsoThreadLocal
The origin of variable names . They can useget()
andset()
Method to get the default value or change its value to the value of the copy saved by the current thread , This avoids thread safety issues .
8. The way ThreadLocal principle
see ThreadLocal Class source code :
static class ThreadLocalMap{
...
}
It defines a static inner class ThreadLocalMap, We can ThreadLocalMap Understood as a container for threads to store data . When accessing data, you call ThreadLocalMap Class get、set Method .
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
and ThreadLocalMap Defined in ThreadLocal As key, Any type as value Data type of , It also defines a Entry Array :
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
...
// The initial size of the array is 16
//`private static final int INITIAL_CAPACITY = 16;`
private Entry[] table;
}
Now the data structure is relatively clear , One Thread Class can have multiple ThreadLocal class , One Thread Class has a ThreadLocalMap, Key value pair
Entry(ThreadLocal<?> k, Object v)
( Multiple ThreadLocal) Are stored in the ThreadLocalMap In the array , It's likeMap[{id:1},{name:" Zhang San "},{age:20}]
.
ThreadLocal by map Structure is to allow each thread to be associated with multiple ThreadLocal Variable . That explains ThreadLocal Why do declared variables have their own local variables in each thread .
9. Why? ThreadLocalMap Does the bottom layer need an array ? How to solve the problem without the linked list Hash What about the conflict ?
So let's see set Method source code :
private void set(ThreadLocal<?> key, Object value) {
Entry[] tab = table;
int len = tab.length;
// Here will be ThreadLocal Conduct hash And with (len-1), Got i Is the subscript of the array
int i = key.threadLocalHashCode & (len-1);
// Loop traversal Entry[] Array
for (Entry e = tab[i];
e != null;
e = tab[i = nextIndex(i, len)]) {
ThreadLocal<?> k = e.get();
// If the currently traversed ThreadLocal With the incoming ThreadLocal Agreement , Coverage value value
if (k == key) {
e.value = value;
return;
}
// If you traverse to the key by null, That is, this position is empty , That directly new One Entry Put it in i position
if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
}
tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash();
}
Of course. get When the method is used , I can also calculate ThreadLocal The hash value of is calculated with the subscript i The location of , Then judge the position Entry Object ThreadLocal Whether it is the same as that in this position key Agreement , If it's not consistent , Just judge the next position , Source code :
private Entry getEntry(ThreadLocal<?> key) {
// Figure out the location i
int i = key.threadLocalHashCode & (table.length - 1);
Entry e = table[i];
if (e != null && e.get() == key)
// Match to the same ThreadLocal
return e;
else
// Didn't match the same ThreadLocal
return getEntryAfterMiss(key, i, e);
}
private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
Entry[] tab = table;
int len = tab.length;
// Traverse and compare each ThreadLocal
while (e != null) {
ThreadLocal<?> k = e.get();
// Equality returns directly to , If it's not equal, keep looking , Go back if you can't find it null
if (k == key)
return e;
if (k == null)
expungeStaleEntry(i);
else
i = nextIndex(i, len);
e = tab[i];
}
return null;
}
10. Whether the objects in the thread are stored in the heap or stack ?
stay Java in , Stack memory belongs to a single thread , Each thread will have a stack memory , The stored variables can only be seen in the thread to which they belong , That is, stack memory can be understood as thread's private memory , Objects in the heap memory are visible to all threads , Objects in heap memory can be accessed by all threads .
11. ThreadLocal Is the instance and its value stored on the stack ?
No , It's on the pile , because ThreadLocal An instance is actually held by the class it creates , Just when accessing data , It will get the data belonging to the thread according to the current thread ThreadLocal data , Other threads cannot access , It's equivalent to isolation .
12. ThreadLocal Memory leak of
We saw before ThreadLocalMap Medium Entry Class inherits weak references , Express ThreadLocalMap Used in key Is a weak reference , and value Is a strong quote . therefore , If ThreadLocal Without strong external reference , When it comes to recycling ,key It's going to be cleaned up , and value It won't be cleaned up . thus ,ThreadLocalMap Will appear in key by null Of Entry. If we don't do anything ,value Can never be GC Recycling , At this time, there may be a memory leak .
ThreadLocalMap This situation has been considered in the implementation , Calling
set()
、get()
、remove()
Method time , Will clean up key by null The record of . Use up ThreadLocal After the method It's better to call... Manuallyremove()
Method
13. Want to share threads ThreadLocal What about the data ?
Use InheritableThreadLocal Class can implement multiple thread access ThreadLocal Value , We create a... In the main thread InheritableThreadLocal Example , And then get this in the child thread InheritableThreadLocal Instance settings .
14. Class implementation Runnable Interface and implementation Callable Interface differences
Runnable since Java 1.0 There has always been ,Callable stay Java 1.5 Introduction in , The purpose is to deal with Runnable Unsupported use cases .Runnable Of run Method has no return value and cannot throw an exception , however Callable Of call Methods can be . therefore , If the task does not need to return results or throw exceptions, it is recommended to implement Runnable Interface , So the code looks more concise .
Tool class Executors Can achieve Runnable Objects and Callable The transformation of objects .(
Executors.callable(Runnable task
) orExecutors.callable(Runnable task,Object resule)
)
15. Thread pool execution execute() Methods and submit() What's the difference between methods ?
- execute() Method is used to submit tasks that do not require a return value , Therefore, it is impossible to judge whether the task is successfully executed by the thread pool .
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
- submit() Method is used to submit tasks that require a return value . The thread pool will return a Future Object of type , Through this Future Object can determine whether the task is executed successfully , And through Future Of
get()
Method to get the return value ,get()
Method blocks the current thread until the task is completed , While usingget(long timeout,TimeUnit unit)
Method will block the current thread timeout Return after time , At this time, it is possible that the task is not finished .
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
16. How to create a thread pool
Use Executors Create four types of thread pools
Executors.newSingleThreadExecutor(); // Create a thread pool for a single thread
Executors.newFixedThreadPool(4); // Create a thread pool with a fixed number of threads
Executors.newCachedThreadPool(); // Create a thread pool with variable number of threads
Executors.newScheduledThreadPool(4); // Create a thread pool that can process tasks regularly
However, creating a thread pool in the above way is not safe , It could happen OOM( out of memory ) The accident .
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
// In the pool where a single thread is created ,new A blocking queue with linked list structure is
// A queue can be understood as a container for storing tasks , When threads in the pool are running , Subsequent tasks will enter the queue for execution
new LinkedBlockingQueue<Runnable>()));
}
// When the blocking queue is created , The queue length is integer Maximum ,
// If the stacked tasks exceed this threshold , Then OOM( out of memory )
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
FixedThreadPool and SingleThreadExecutor : The queue length allowed for requests is Integer.MAX_VALUE , If the stacked tasks exceed this threshold , It can lead to OOM.
CachedThreadPool and ScheduledThreadPool : The number of threads allowed to be created is Integer.MAX_VALUE , If the number of threads created exceeds this threshold , It can lead to OOM.
So in Alibaba programming protocol , Not allowed Executors Creating a thread pool .
You can use new ThreadPoolExecutor
Way to create , And more flexible :
// This is the construction method of creating a pool safely , All seven parameters can be customized
public ThreadPoolExecutor(int corePoolSize, // Number of core threads in the pool
int maximumPoolSize, // The maximum number of threads in the pool
long keepAliveTime, // The thread is in keepAliveTime There are no tasks in time , Automatically destroy
TimeUnit unit, // keepAliveTime Time unit of
BlockingQueue<Runnable> workQueue, // Blocking queues
ThreadFactory threadFactory, // Thread factory
RejectedExecutionHandler handler // Refusal strategy , When all the threads in the pool are working , The queue is full, too , And the strategy of how to refuse the task
) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
17. What are the four rejection strategies when the thread pool is saturated
new ThreadPoolExecutor.AbortPolicy() // The pool is full , The queue is full , There's a mission coming in , Don't deal with the task , And throw the exception
new ThreadPoolExecutor.CallerRunsPolicy() // Which thread started the task , Just by which thread
new ThreadPoolExecutor.DiscardPolicy() // The pool is full , The queue is full , Lose the job , Don't throw exceptions
new ThreadPoolExecutor.DiscardOldestPolicy() // The pool is full , The queue is full , See if the first thread to execute is free , Try to compete , Don't throw exceptions
18. Analysis of the principle of thread pool executing tasks
Take a look at the following code and execution results :
public class ThreadPoolExecutorDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
5, 10, 2, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
// Turn on 10 individual Task1 Threads
for (int i = 0; i < 10; i++) {
pool.execute(new Task1(i));
}
while (pool.getActiveCount() != 0) {
}
pool.shutdown();
}
}
class Task1 implements Runnable {
int i;
Task1(int i) {
this.i = i;
}
@Override
public void run() {
try {
System.out.println("start time: " + new SimpleDateFormat("hh : ss").format(new Date()) + " Task" + i);
TimeUnit.SECONDS.sleep(5);
System.out.println("end time: " + new SimpleDateFormat("hh : ss").format(new Date()) + " Task" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Print the results :
start time: 10 : 19 Task1
start time: 10 : 19 Task2
start time: 10 : 19 Task0
start time: 10 : 19 Task4
start time: 10 : 19 Task3
end time: 10 : 24 Task2
end time: 10 : 24 Task0
end time: 10 : 24 Task1
end time: 10 : 24 Task4
start time: 10 : 24 Task5
start time: 10 : 24 Task6
start time: 10 : 24 Task7
end time: 10 : 24 Task3
start time: 10 : 24 Task8
start time: 10 : 24 Task9
end time: 10 : 29 Task6
end time: 10 : 29 Task5
end time: 10 : 29 Task7
end time: 10 : 29 Task8
end time: 10 : 29 Task9
We found that the thread pool performs five tasks first , When one of the tasks is completed , Go on with the remaining five tasks . In order to explore why it is like this , It's about analyzing execute Method :
public void execute(Runnable command) {
// When task null when , Throws a null pointer exception
if (command == null)
throw new NullPointerException();
int c = ctl.get();
// Judge whether the number of working threads in the current thread pool is less than the number of core threads
if (workerCountOf(c) < corePoolSize) {
// If it is less than , Then start a thread to execute the task
if (addWorker(command, true))
return;
c = ctl.get();
}
// If the number of worker threads is greater than or equal to the number of core threads , Determine whether the thread pool is Running state , Try to put the task in the queue
// The thread pool is in Running In the state of , Ability to take on new tasks , And processing the tasks in the blocked queue
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// If the thread pool state is not Running state , Remove the task from the task queue , And try to determine whether all threads have completed execution . At the same time, the rejection strategy
if (! isRunning(recheck) && remove(command))
reject(command);
// If the current thread pool is empty, create a thread and execute
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// adopt addWorker Create a new thread , And perform the task , If the execution fails, reject the task
else if (!addWorker(command, false))
reject(command);
}
Intuitive execution process :
Conclusion : After we opened 10 After a mission ,5 A core thread executes first 5 A mission , be left over 5 Put one in the queue , When a task is completed , To perform the tasks in the queue .
19. Introduce to you Atomic Atomic classes
Atomic Class, for example AtomicBoolean、AtomicInteger、AtomicLong, These classes have the atomicity of data operations , Just as transactions are atomic , Operation is inseparable ; The usage scenario is in a multithreaded environment without locks , for example 20 A thread of AtomicInteger Object to carry out +1 operation , One thread plus 100 Time , this 20000 All operations must be performed successfully , There will be no data inconsistency .
20. JUC What is the atomic class in the package 4 class ?
Basic types
- AtomicInteger: Shaping atoms
- AtomicLong: Long integer atom class
- AtomicBoolean: Boolean atom class
An array type
- AtomicIntegerArray: Shape array atomic class
- AtomicLongArray: Long shape array atomic class
- AtomicReferenceArray: Reference type array atomic class
Reference type
- AtomicReference: Reference type atomic class
- AtomicStampedReference: Atomic update the field atomic class in the reference type with version number
- AtomicMarkableReference : The atom updates the reference type with the tag bit
Object's property modification type
- AtomicIntegerFieldUpdater: Atom update shaper field updater
- AtomicLongFieldUpdater: Atom update long shape field updater
- AtomicStampedReference: Atomic update reference type with version number ( Optimism lock ). This class associates integer values with references , It can be used to solve the update data of atoms and the version number of data , It can solve the problem of using CAS What may occur when atomic updates are made ABA problem .
21. Tell me about AtomicInteger Use
AtomicInteger Usage method :
public final int get() // Get the current value
public final int getAndSet(int newValue) // Get the current value , And set to newValue
public final int getAndIncrement() // Get the current value , And self increase
public final int getAndDecrement() // Get the current value , And reduce
public final int getAndAdd(int delta) // Get the current value , And will delta Add to the current value
boolean compareAndSet(int expect, int update) // If the value entered is equal to the expected value , Then put update Set to actual value
public final void lazySet(int newValue) // The final setting is newValue, It is possible that other threads can read the old value for a short period of time . The old value can still be read for a short period of time when it is the actual value .
22. Introduce to you AtomicInteger The principle of class
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
// setup to use Unsafe.compareAndSwapInt for updates
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex); }
}
private volatile int value;
...
}
AtomicInteger Class mainly uses CAS ( Compare and exchange ) + volatile and native Method to ensure atomic operation , To avoid synchronized The high cost of , Greatly improved execution efficiency .
CAS yes (compare and swap) Abbreviation , That is, comparison and exchange .CAS The principle is to compare the expected value with the original value , If it is the same, update it to a new value .UnSafe Class objectFieldOffset() The method is a native Local method , This method is used to get “ The value of the original ” Memory address of , The return value is valueOffset.CAS It's a lock based operation , And optimistic lock , It handles shared variables without locking . in addition value It's a volatile Variable , Visible in memory , therefore JVM It can guarantee that any thread can always get the latest value of this variable at any time .
版权声明
本文为[0oIronhide]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230600132335.html
边栏推荐
- ACFs file system creation, expansion, reduction and other configuration steps
- The query did not generate a result set exception resolution when the dolphin scheduler schedules the SQL task to create a table
- Dolphin scheduler scheduling spark task stepping record
- Dolphin scheduler configuring dataX pit records
- 聯想拯救者Y9000X 2020
- Parameter comparison of several e-book readers
- Ai21 labs | standing on the shoulders of giant frozen language models
- Explanation of input components in Chapter 16
- Apache seatunnel 2.1.0 deployment and stepping on the pit
- QT调用外部程序
猜你喜欢
Cross carbon market and Web3 to achieve renewable transformation
[point cloud series] pointfilter: point cloud filtering via encoder decoder modeling
Zero copy technology
Static interface method calls are not supported at language level '5'
Logstash数据处理服务的输入插件Input常见类型以及基本使用
Set Jianyun x Feishu Shennuo to help the enterprise operation Department realize office automation
Window analysis function last_ VALUE,FIRST_ VALUE,lag,lead
Unified task distribution scheduling execution framework
QT calling external program
Usereducer basic usage
随机推荐
Innobackupex incremental backup
JS compares different elements in two arrays
./gradlew: Permission denied
QT calling external program
[point cloud series] multi view neural human rendering (NHR)
Two ways to deal with conflicting data in MySQL and PG Libraries
Opening: identification of double pointer instrument panel
Migrating your native/mobile application to Unified Plan/WebRTC 1.0 API
MySQL and PgSQL time related operations
Aicoco AI frontier promotion (4.23)
[andorid] realize SPI communication between kernel and app through JNI
Example of specific method for TIA to trigger interrupt ob40 based on high-speed counter to realize fixed-point machining action
Detailed explanation of constraints of Oracle table
[point cloud series] pointfilter: point cloud filtering via encoder decoder modeling
SAP UI5 应用开发教程之七十二 - SAP UI5 页面路由的动画效果设置
Tersus notes employee information 516 MySQL query (time period uniqueness judgment of 2 fields)
Explanation of input components in Chapter 16
Oracle database combines the query result sets of multiple columns into one row
PG library checks the name
NPM err code 500 solution