A few days later, I had a phone interview at 7 o ‘clock on Friday evening. After the phone interview, Baidu HR called me on Monday of the second week to make an appointment for an on-site interview. Here continue to recall the baidu company’s second round of interviews.
The interview form | On-site interview |
---|---|
The interview node | Second round |
The interview time | On a Thursday afternoon in June |
interview | Baidu International Building, Shenzhen |
Recall version of the topic of the author only for a simple personal analysis, spin quotes, welcome readers to leave more opinions in the comments section ~~
Tell me a little about yourself
Study, work experience, project, wheel, technology sharing
Explain your understanding of memory management
Reference counting, creating new objects, copying objects, setting new values, and releasing them manually all affect it. You can talk about the location of reference counting itself. This reader needs to dig up the runtime source code for himself. IOS source code thinking: Where are object reference counts stored? Inspiration from runtime source code
How does ARC implement automatic release and how does it differ from MRC?
Resolution:
-
By default, local variable objects are strong Pointers and stored in the heap. However, strong Pointers to local variables are freed after the code block ends and the corresponding memory space is destroyed.
-
MRC does not have strong, weak, and local variable objects are equivalent to basic data types. MRC must use the set method to assign member attributes. It cannot access underline member attribute assignments directly, because underline assignments are direct (such as _name = name), and set does a lot of things that affect reference counting, such as retain.
Why did Apple launch ARC?
-
In the MRC era, to retain an object, we just needed “retain”. ARC is no longer needed. You can now point to the object with a pointer in either of two cases. Second: the pointer is not null, the object is always stored in the heap, if the pointer points to a new value, the original object will be released once, the system will automatically fix it for us at the appropriate time, we don’t need to care.
-
In ARC, whenever the object pointer is null, it is released. Otherwise, the object stays on the heap. When you point to a new value, the original object is released once.
With threads, why do you have runloops? What does runloop have to do with threads?
Runloop is used to manage threads. When a thread’s Runloop is enabled, the thread will go to sleep after executing a task. When a task is available, it will be woken up to execute it.
More on the relationship between the two:
- Runloops correspond to threads one by one. A runloop corresponds to a core thread, which is core because runloops can be nested, but there can only be one core, and their relationship is stored in a global dictionary.
- The runloop is created on the first fetch and destroyed at the end of the thread.
- For the main thread, the runloop is created by default as soon as the program starts.
- For child threads, runloops are lazily loaded and only created when we use them, so be careful when using timers on child threads: make sure the runloop is created for the child thread, otherwise the timer will not call back.
How do you think runloop is implemented?
The implementation principle is not good, so I said a do while loop. I guess the starting point the interviewer might want is based on the CFRunLoopRef analysis? When I asked the interviewer for a hint, he said the interviewer didn’t answer questions, so he didn’t know yet. Readers who are familiar with this area can also leave their own thoughts.
NSRunLoop is a layer of OC wrapper based on CFRunLoopRef, so we need to study the API of CFRunLoopRef layer (Core Foundation layer).
“` // should only be called by Foundation // t==0 is a synonym for “main thread” that always works CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) { if (pthread_equal(t, kNilPthreadT)) { t = pthread_main_thread_np(); } __CFLock(&loopsLock); if (! __CFRunLoops) {// Create a thread if there are no threads
__CFUnlock(&loopsLock);
Copy the code
/ / create a mutable dictionary CFMutableDictionaryRef dict = CFDictionaryCreateMutable (kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
// Put the main thread in and create a RunLoop(i.e., CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_NP ()); // Save the main thread RunLoop and main thread as key/value. CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop); if (! OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void * volatile *)&__CFRunLoops)) { CFRelease(dict); } CFRelease(mainLoop); __CFLock(&loopsLock); } // When you type cunrrentRunLoop, the current thread key will be used to find the corresponding RunLoop in the dictionaryCopy the code