当前位置:网站首页>IOS development interview strategy (KVO, KVC, multithreading, lock, runloop, timer)
IOS development interview strategy (KVO, KVC, multithreading, lock, runloop, timer)
2022-04-21 16:16:00 【InfoQ】
KVO & KVC
KVO
Usage and underlying principles
- Usage method : Add observers , Then how to implement the listening agent
KVOThe bottom layer usesisa-swizlingTechnology .
OCEach object in / Class hasisaThe pointer ,isaIndicates which class the object is .
- When a property of an object is registered with observer, The system will create a new intermediate class (
intermediate class) Inherit the originalclass, Put the object'sisaPointer to intermediate class .
- Then the intermediate class will override
setterMethod , callsetterPrevious callwillChangeValueForKey, callsetterThen calldidChangeValueForKey, This notifies all observers that the value has changed .
- Rewrote
-classMethod , Trying to deceive us, this class has not changed , It's the original kind of .
KVO Advantages and disadvantages
- advantage
- 1、 The association and synchronization of two objects can be realized conveniently and quickly , for example
view & model
- 2、 Changes in new and old values can be observed
- 3、 You can easily observe the data changes of nested types
- shortcoming
- 1、 Observation object passing
stringType settings , If you write it wrong or the variable name changes , It can pass at compile time, but it will happen at run timecrash
- 2、 Observing multiple values requires multiple values in the proxy method
ifJudge
- 3、 Forgetting to remove the observer or repeatedly removing the observer can lead to
crash
How to trigger manually
KVO
KVOThe mechanism is throughwillChangeValueForKey:anddidChangeValueForKey:Triggered by two methods .
- Call before observing object changes
willChangeValueForKey:
- After watching the change of objects
didChangeValueForKey:
- Therefore, you only need to call it manually before and after changing the observation value .
to KVO Add filter
- rewrite
automaticallyNotifiesObserversForKey, Need to be screenedkeyreturnNO.
setterManually triggered after adding judgment inKVO
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
if ([key isEqualToString:@"age"]) {
return NO;
}
return [super automaticallyNotifiesObserversForKey:key];
}
- (void)setAge:(NSInteger)age {
if (age >= 18) {
[self willChangeValueForKey:@"age"];
_age = age;
[self didChangeValueForKey:@"age"];
}else {
_age = age;
}
}
Use KVC Modification will trigger KVO Do you ?
- Meeting , as long as
accessInstanceVariablesDirectlyreturnYES, adopt KVC Modifying the value of a member variable triggers KVO.
- This explanation KVC Internal call
willChangeValueForKey:Methods anddidChangeValueForKey:Method
Modifying member variables directly triggers KVO Do you ?
- Can't
KVO Collapse and protection of
- KVO Number of add and remove does not match , Most are removed more than registered .
- Observed
deallocIs still registered KVO, Cause crash .
- Added observers , But not implemented
observeValueForKeyPath:ofObject:change:context:. Protection plan 1:
- Use it directly facebook Open source framework
KVOControllerProtection plan 2:
- Customize a hash table , Record the relationship between the observer and the observed object .
- Use
fishhookReplaceaddObserver:forKeyPath:options:context:, Judge whether the same observer already exists before adding , Add... If it doesn't exist , Avoid repeated triggering bug.
- Use
fishhookReplaceremoveObserver:forKeyPath:andremoveObserver:forKeyPath:context, Judge whether there is a corresponding relationship before removing , Release only if it exists .
- Use
fishhookReplacedealloc, performdeallocDetermine whether there are observers that have not been removed before , Remove if it exists first .
KVC Underlying principle
setValue:forKey:
The implementation of the
- lookup
setKey:Methods and_setKey:Method , Pass parameters directly as soon as they are found , Calling method ;
- If not found
setKey:and_setKey:Method , seeaccessInstanceVariablesDirectlyReturn value of method , If you returnNO( Direct access to member variables is not allowed ), callsetValue:forUndefineKey:And throw an exceptionNSUnknownKeyException;
- If
accessInstanceVariablesDirectlyMethod returnsYES( You can access its member variables ), Just look it up in order_key、_isKey、key、isKeyThese four member variables , If it is found, it will be assigned directly ; If we don't find out , callsetValue:forUndefineKey:And throw an exceptionNSUnknownKeyException.
valueForKey:
The implementation of the
- according to
getKey,key,isKeyHow to find the order of , Call directly as soon as you find it ;
- If not found ,
accessInstanceVariablesDirectlyreturnYES( You can access its member variables ), Find in order_key、_isKey、key、isKeyThese four member variables , Just find it ; If the member variable is not found , callvalueforUndefineKeyAnd throw an exceptionNSUnknownKeyException.
accessInstanceVariablesDirectlyreturnNO( Direct access to member variables is not allowed ), Then callvalueforUndefineKey:Method , And throw an exceptionNSUnknownKeyException;
Multithreading
Difference between process and thread
- process : A process is an application running in the system , A process has multiple threads .
- Threads : A thread is a unit in a process , Want to perform a task , There must be at least one thread . The main thread is turned on by default when the program starts .
What's the state of the process
Not Running: Not running .
Inactive: Front desk inactive . At the front desk , But you can't accept event handling .
Active: Foreground activity status . At the front desk , Can accept event handling .
Background: Backstage status . Backstage , If you have executable code , Can execute code , Code execution completed , The program is suspended .
Suspended: Pending state . Backstage , Can't execute code , If there is not enough memory , The program will be killed .
What is thread safety ?
- Multiple threads access a piece of code at the same time , It will not cause data confusion
How to ensure thread safety ?
- Lock through thread
pthread_mutexThe mutex (C Language )
@synchronized
NSLockObject lock
NSRecursiveLockRecursive lock
NSCondition & NSConditionLockConditional lock
dispatch_semaphoreGCD The semaphore realizes locking
OSSpinLockspinlocks ( Not recommended )
os_unfair_lockspinlocks (IOS10 Replace laterOSSpinLock)
Projects you come into contact with , Which scenarios apply thread safety ?
- Additions and deletions to the online list , Need to lock to keep it thread safe .
iOS
How many types of threads are there in development ? Talk about
- 1、
pthread
- C Language implementation of cross platform general multithreading API
- It's very difficult to use , No use.
- 2、
NSThread
OCObject oriented multithreadingAPI
- Simple and easy to use , You can manipulate Thread objects directly .
- Need to manually manage the lifecycle
- 3、
GCD
- C Language implementation of multi-core parallelism CPU programme , It can run multi-core more reasonably
CPU
- It can automatically manage the life cycle
- 4、
NSOperation
OCbe based onGCDEncapsulation
- Fully object-oriented multithreading scheme
- It can automatically manage the life cycle
GCD What queue is there , Which queues are provided by default
- Serial synchronization queue , The tasks are in order ( Serial ), Execute on current thread ( Sync )
- Serial asynchronous queue , The tasks are in order ( Serial ), Open up new threads to execute ( asynchronous )
- Parallel synchronization queue , The tasks are in order ( Cannot embody parallelism ), Execute on current thread ( Sync )
- Parallel asynchronous queue , The task is carried out at the same time ( parallel ), Open up new threads to execute ( asynchronous )
- Main queue and global queue are provided by default
GCD
The main thread & The relationship between the home team
- The main queue task is executed only in the main thread
- The main thread is running a
runloop, Except for the task of the main line , also UI Processing and drawing tasks .
Describe the difference between synchronous and asynchronous threads ?
- Thread synchronization means that there are currently multiple threads , You must wait for one thread to finish executing before you can execute the next thread .
- Thread asynchrony refers to a thread executing , His next thread doesn't have to wait for him to finish executing .
Thread synchronization
GCDThe serial queue of , The tasks are executed one by one
NSOperationQueueSet upmaxConcurrentOperationCount = 1, Only... At the same time 1 individualNSOperationBe performed
- Use
dispatch_semaphoreSemaphores block threads , Release until the task is completed
dispatch_groupIt can also be blocked until all tasks are completed
Under what circumstances will thread deadlock
- Serial queue , The task in progress A Add a synchronization task to the serial queue B, Can cause AB The two tasks are waiting for each other , Formation of a deadlock .
- Priority reversal ,
OSSpinlock
dispatch_once
Realization principle
dispatch_onceNeed todispatch_once_tParameters of type , It's actually a long plastic surgery
- Handle
blockWill judge the incomingdispatch_once_tIs it 0, by 0 ExpressblockHas not yet been performed .
- Put... After execution
tokenTo change the value of 1, The next time you come in, judge whether it's not 0 Don't deal with it directly .
performSelector
and
runloop
The relationship between
- call
performSelecter:afterDelay:, Inside it will create aTimerAnd add... To the current threadRunLoop.
- If the current thread
RunloopDidn't run , This method will fail .
- Other
performSelectorA series of methods are similar
Sub thread execution
[p performSelector:@selector(func) withObject:nil afterDelay:4]
What's going to happen ?
- The above method is placed in the sub thread , In fact, an internal will be created
NSTimerTimer .
- The child thread will not be turned on by default
runloop, If it is necessary to carry outfuncThe function has to be turned on manuallyrunloop
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
// [[NSRunLoop currentRunLoop] run]; It doesn't work on it
// Just turn on runloop But there are no events in it , Failed to open
[self performSelector:@selector(test) withObject:nil afterDelay:2];
[[NSRunLoop currentRunLoop] run];
});
Why only refresh in the main thread UI
UIKitIt's not thread safe ,UI The operation involves rendering and accessingViewProperties of , Asynchronous operation will have read and write problems , Locking it will consume a lot of resources and slow down the running speed .
- The starting point of the program
UIApplicationInitialize in the main thread , All user events ( Touch interaction ) Are passed in the main thread , thereforeviewEvents can only be responded to on the main thread .
A queue is responsible for inserting data , A queue is responsible for reading operations , Operate a stored queue at the same time , How to ensure smooth progress
- Use
GCDThe fence function realizes multiple single write
- When reading, use
dispatch_syncReturn data immediately
- Use... When writing
dispatch_barrier_asyncWrite after blocking other operations
- Be careful not to use global queues , Because there are other operations in the global queue
lock
Why locks are needed ?
- In multithreaded programming, threads interfere with each other , For example, multiple threads access a resource .
- Need some synchronization tools , Make sure it's safe when threads interact .
What is a mutex
- If the shared data has been locked by other threads , The thread will sleep and wait for the lock
- Once the accessed resource is unlocked , The thread waiting for the resource will be awakened .
- It is recommended to use mutex when the task is complex and takes a long time
- advantage
- Thread hibernates when resources are not available ,cpu You can schedule other threads to work
- shortcoming
- There is the overhead of thread scheduling
- If the task time is short , Thread scheduling is reduced cpu The efficiency of
What is spin lock
- If the shared data has been locked by another thread , Threads wait for locks in a dead loop
- Once the accessed resource is unlocked , The thread waiting for the resource will execute immediately
- Suitable for holding the lock for a short time
- advantage :
- Spin locks do not cause threads to sleep , No thread scheduling and CPU Time consuming operations such as time slice rotation .
- If you can get the lock in a short time , The efficiency of spin lock is much higher than that of mutual exclusion lock .
- shortcoming :
- Spin lock always occupied CPU, In a busy state without a lock .
- If you can't get the lock in a short time , send CPU Low efficiency .
- Spin locks do not implement recursive calls .
Read-write lock
- Read write locks are also known as
rw lockperhapsreadwrite lock
- Not the most commonly used , Generally, it is only used for database operation .
- The specific operation is multi read and single write , Write operations can only be performed serially , And cannot be read while writing ; Reading needs to support multi-threaded operation , And cannot write when reading
Tell me about the locks you know
pthread_mutexThe mutex (C Language )
@synchronized
NSLockObject lock
NSRecursiveLockRecursive lock
NSCondition & NSConditionLockConditional lock
dispatch_semaphoreGCD The semaphore realizes locking
OSSpinLockspinlocks ( It is not recommended to use )
os_unfair_lockspinlocks (IOS10 Replace laterOSSpinLock)
say something
@synchronized
- principle
- The inside should be a reentrant mutex (
recursive_mutex_t)
- At the bottom is the list , Storage SyncData,SyncData It contains a
threadCount, Is the number of threads accessing resources .
objc_sync_enter(obj),objc_sync_exit(obj), adoptobjThe address ofhashPass parameter searchSyncData, Lock and unlock .
- Incoming
objBe released or benil, It will release the lock
- advantage
- The lock function can be realized without creating a lock object
- Easy to use , Code readability
- shortcoming
- Lock the code as little as possible
- The performance is not so good
- Note that the object of the lock must be the same
OCobject
say something
NSLock
- follow
NSLockingagreement
- Be careful
- The same thread
lockandunlockYou need to be in pairs
- The same thread runs continuously
lockTwice will cause a deadlock
say something
NSRecursiveLock
NSRecursiveLockIt's a recursive lock
- Be careful
- The same process
lockMultiple times without deadlock
- When the same thread
lock & unlockThe lock will only be released when the number is the same , Other threads can be locked
say something
NSCondition & NSConditionLock
- Conditional lock : Execute locked code when conditions are met ; If the condition is not met, the thread will be blocked , Until another thread sends an unlock signal .
NSConditionObject actually acts as a lock and a Thread Checker
- Locks protect data sources , Executing tasks triggered by conditions .
- The thread checker determines whether to block the thread according to the condition .
- Manual waiting and manual signal release are required
- One
waitMust correspond to asignal, All need to be used in one wake-upbroadcast
NSConditionLockyesNSConditionEncapsulation
- Through different
conditionValues trigger different operations
- Unlock through
unlockWithConditionmodifyconditionImplement task dependencies
- adopt
conditionAutomatically determine whether to block or wake up the thread
say something GCD The semaphore realizes the lock
dispatch_semaphore_creat(0)Generate a semaphoresemaphore = 0( The value passed in can control the number of parallel tasks )
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)sendsemaphore - 1, When the value is less than 0 Has reached the awaited
dispatch_semaphore_signal(semaphore)Signal , sendsemaphore + 1, When the value is greater than or equal to 0 release
say something
OSSpinLock
OSSpinLockIt's a spin lock , Busy waiting lock
- Spin lock has the problem of priority reversal , When a thread has priority, it may cause the following situations .
- A low priority thread accesses some data first , At this time, the spin lock is used to lock .
- A high priority thread accesses the data again , High priority threads will always occupy CPU Resources are busy waiting for access
- As a result, threads with low priority do not CPU Resources complete the task , The lock cannot be released .
- Due to the problems of spin lock itself , So Apple has been abandoned
OSSpinLock.
say something
os_unfair_lock
- iOS10 Replace later
OSSpinLockLock of , No longer busy waiting
- Hibernate when resources are not available , When the resource is obtained, the kernel wakes up the thread
- There is no strengthening of fairness and order , The thread that releases the lock may immediately re lock , The thread waiting for the lock may fail to lock successfully after waking up .
- Although priority inversion is solved , But it also causes hunger (
starvation)
starvationThe greedy thread takes up too many resources , Other threads cannot access shared resources .
5 A thread reads a file , How to achieve at most only 2 Two threads read this file at the same time
dispatch_semaphoreSemaphore control
Objective-C Atomic and non atomic properties in
- OC When defining properties, there are
nonatomicandatomicTwo options
atomic: Atomic properties , bysetter/getterAll methods are locked ( The default isatomic), Thread safety , It takes a lot of resources
nonatomic: Non atomic properties , No locks , Non-thread safety
atomic Lock principle :
property (assign, atomic) int age;
- (void)setAge:(int)age
{
@synchronized(self) {
_age = age;
}
}
- (int)age {
int age1 = 0;
@synchronized(self) {
age1 = _age;
}
}
atomic
Decorated attributes
int a
, Execute on different threads
self.a = self.a + 1
Ten thousand times , Will the value of this attribute be 10000 ?
- Can't , The point syntax on the left calls
setter, The call on the right isgetter, This line is not atomic .
atomic
Can thread safety be guaranteed ?
- You can't , Only guarantee
setterandgetterSecurity in the current thread
- When a thread reads a property value several times in a row , Other threads are changing values at the same time , In the end, we can't get the expected value
- A thread is getting the value of the current property , Another thread released this property , May cause breakdown
nonatomic
Is a non atomic operator , Why
nonatomic
no need
atomic
?
- If the object does not need to consider multithreading , Please add this attribute to modify , This will make the compiler generate less mutex locking code , Can improve efficiency .
- Use
atomic, The compiler will be theresetterandgetterMethod to automatically generate mutex code , Avoid asynchronous reading and writing of this variable .
Some people say yes
atomic
Memory consumption , Do you think? ?
- Because it locks automatically , So performance ratio
nonatomicBad .
atomic
Why does it fail
atomicModified attributes are automatically generated by the compilerget/setMethod to realize atomic operation , If you rewrite any one ,atomicKeyword properties will be invalidated
nonatomic
Realization
- (NSString *)userName {
return _userName;
}
- (void)setUserName:(NSString *)userName {
_userName = userName;
}
atomic
The implementation of the
- (NSString *)userName {
NSString *name;
@synchronized (self) {
name = _userName;
}
return name;
}
- (void)setUserName:(NSString *)userName {
@synchronized (self) {
_userName = userName;
}
}
runloop
runloop
What is it? ?
- There is a circular mechanism for managing events in the system
runloopIs to use this cycle , Objects that manage messages and events .
runloop
Is it equal to
while(1) { do something ... }
?
- No
while(1)It's a busy state , Need to occupy resources all the time .
runloopGo to sleep when there are no messages to process , Here comes the news , Wake up when you need to deal with .
runloop
The basic model of
- iOS There are five of them
runLoopPattern
UIInitializationRunLoopMode( Enter the first... After startupMode, It will not be used after startup , Switch tokCFRunLoopDefaultMode)
kCFRunLoopDefaultMode(App DefaultMode, Usually the main thread is in thisModeRun under )
UITrackingRunLoopMode( Interface trackingMode, be used forScrollViewTrack touch slide , Make sure that the interface doesn't slide under any otherModeinfluence )
NSRunLoopCommonModes( This is a fakeMode, Equivalent toNSDefaultRunLoopModeandNSEventTrackingRunLoopModeThe combination of )
GSEventReceiveRunLoopMode( Accept the inside of the system eventMode, It's not usually used )
runLoop
The basic principle of
- The mainline in the system will be turned on by default
runloopDetect events , When there are no events to deal withrunloopWill be dormant .
- Once an event triggers , For example, the user clicks on the screen , Will wake up
runloopPut into listening state , Then deal with the incident .
- After the event processing is completed, it will enter sleep again , Wait for the next event to wake up
runloop
Relationship with thread
runloopOne to one correspondence with thread .
- When the main thread is created, it is enabled by default
runloop, To keep the program running .
- Threaded
runloopIt's lazy , Manual opening required .
runloop
Event handling process
- Events will trigger
runloopThe entry function ofCFRunLoopRunSpecific, The function will first notifyobserverSwitch the state tokCFRunLoopEntry, And then through__CFRunLoopRunstart-uprunloopHandling events
__CFRunLoopRunThe core of is ado - whileloop , The cycle is as follows

runloop
How was it awakened
- When there is no message to process , Sleep threads to avoid resource consumption . Switch from user state to kernel state , Waiting for news ;
- When there is a message to process , Wake up the thread now , Go back to user mode to process messages ;
source0Direct wake-up via screen trigger
source0By callingmach_msg()Function to transfer control of the current thread to kernel state / User mode .
What is user mode 、 Nuclear mentality
- Kernel mode : Run the operating system program , Indicates that after an application process executes a system call , or I/O interrupt , After the clock is interrupted , The process is in kernel execution
- User mode : Run the user program , Indicates that the process is executing in user state
runloop The state of
CFRunLoopObserverRef observerRef = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
switch (activity) {
case kCFRunLoopEntry: NSLog(@"runloop start-up "); break;
case kCFRunLoopBeforeTimers: NSLog(@"runloop About to deal with timer event "); break;
case kCFRunLoopBeforeSources: NSLog(@"runloop About to deal with sources event "); break;
case kCFRunLoopBeforeWaiting: NSLog(@"runloop Going to sleep "); break;
case kCFRunLoopAfterWaiting: NSLog(@"runloop Awakened "); break;
case kCFRunLoopExit: NSLog(@"runloop sign out "); break;
default: break;
}
});
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observerRef, kCFRunLoopDefaultMode);
}
runLoop
The method of Caton detection
NSRunLoopThe processing time is mainly in the following two cases
kCFRunLoopBeforeSourcesandkCFRunLoopBeforeWaitingBetween
kCFRunLoopAfterWaitingafter
- The above two times are too long , It can be determined that the main route is stuck at this time
- You can add
ObserverTo the main threadRunloopin , monitorRunloopState switching takes time , Monitor Caton
- Use one
do-whileCyclic treatment of subgrade , The semaphore sets the threshold to judge whether it is stuck
dispatch_semaphore_waitReturn valueNot 0ExpresstimeoutWhat happened to carton
- Get the stack of Caton and pass it to the back end , reanalysis
How to start a resident thread
// Create thread
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(play) object:nil];
[thread start];
// runloop Keep alive
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
// Handling events
[self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:NO];
Copy code
timer
NSTimer、CADisplayLink、dispatch_source_t
The advantages and disadvantages of
NSTimer
- The advantage is that
target-actionPattern , Simple to use
- The disadvantage of careless citation is that it is easy to cause circulation . Need to rely on
runloop,runloopIf it is blocked, it will be delayed until the next timerunloopCycle to execute , Therefore, the time accuracy is also slightly insufficient
CADisplayLink
- The advantage is high precision , Call... After each refresh , Suitable for timing without stopping redrawing , For example, video
- The disadvantage is that it is easy to accidentally cause circular references .
selectorThe cycle interval is greater than the interval between redrawing each frame , Will result in skipping several call opportunities . Single execution cannot be set .
dispatch_source_t
- be based on
GCD, High precision , Do not rely onrunloop, Easy to use , Favorite timer
- It should be noted that the timer must be held when using , Otherwise, it will be released in advance .
NSTimer What happens when the child thread executes ?
NSTimerWhen the sub thread calls, the sub thread needs to be opened manuallyrunloop
[[NSRunLoop currentRunLoop] run];
NSTimer
Why not ?
- If
runloopAt the right timeNSTimerArrival trigger time ,NSTimerThe trigger will be postponed to the nextrunloopcycle
NSTimer
A circular quotation of ?
timertargettimer & targetGCD timer
NSTimeInterval interval = 1.0;
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), interval * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(_timer, ^{
NSLog(@"GCD timer test");
});
dispatch_resume(_timer);

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204211614304045.html
边栏推荐
- 嵌入式GUI盘点-你了解几款?
- How can I easily manage harbor in multi-user scenarios!
- Download the documentation tutorial for free
- Detailed explanation of swap automatic arbitrage robot ecosystem development mode
- PHP 零基础入门笔记(11):字符串 String
- CLion 中添加 release 配置
- CRM系统可以帮助改善客户体验吗?
- 【Android,Kotlin】教你写一个弱引用的Handler工具,避免内存泄漏
- SQL--数据库的操作(DDL,DML,DQL)+使用命令查看当前数据库的存储位置(数据库版本查询)
- 全国查询水电气费免费接口(二)
猜你喜欢

Announcement of the first ship sea data intelligent application innovation competition

2022骨传导耳机排名,最好用的骨传导耳机推荐

确定还不来看看?这样管理你的代码库既方便又省心

几种单USB转多串口的方案

Must brush the simulated question bank and answers of the latest eight members of Chongqing in 2022

Solution to the problem of file damage caused by forced shutdown and power failure during nodejs FS readfilesync
Programmer meituan interview experience, from basic to algorithm, lasted six hours, with an annual salary of 20W

Qt5.14.2编译mysql

Assembly language programming: design and debugging of input character type statistics in modular programming

(11) definition of macro language - (C.4)
随机推荐
干货 | 解决 App 自动化测试的常见痛点(弹框及首页启动加载完成判断处理)
【2023校招刷題】華為性格測評(綜合測評)戰略指南
云呐:机房资产管理系统web版,设备资产信息管理的应用
Burp is a simple TP5 rce passive scanning plug-in
Realize Gaode coordinate to GPS coordinate
微信h5、APP、微信内jsapi支付接口
AT2293 [AGC009D] Uninity(贪心、状压)
金仓数据库KingbaseES V8R3集群修改data路径测试案例
Can CRM system help improve customer experience?
c# 坐标点击webBrowser1
At2293 [agc009d] unity
Data processing input box section
ABAP keywords at first and at last learning
Establishment of instant messaging system and development of IM chat social software
PHP 零基础入门笔记(11):字符串 String
SQL--数据库的操作(DDL,DML,DQL)+使用命令查看当前数据库的存储位置(数据库版本查询)
Mini LED有哪些优势
"Checking and remedying deficiencies", sorting out the core concepts of DDD
Software testing MySQL interview question: using SQL to create tables and filter?
Burp 一个简易的tp5-rce被动扫描插件