Compilation principle

The main process

Precompile --> Compile --> Assemble --> Link * Expand define/ Remove comment/add line number Semantic check/generate AST/ static analysis (syntax check)/other analysis translate to IR/ Mach -- o Find link o Generate executable file --> Copy resource file --> Compile/link storyboard --> compile Asset --> Coacopods script --> signatureCopy the code

Compile link procedure

  1. Preprocessing: replace macro macro, import header and process other precompiled instructions to generate.i files. (All begin with a #)
  2. Compilation: the preprocessing of a series of files for a series of lexical, grammatical, semantic analysis, and optimization to generate the corresponding assembly code, generate. S files;
  3. Assembly: the assembler will generate assembly code machine instructions, output target files, generate. O files (according to the assembly instructions and machine instructions of the comparison table translation can be);
  4. Linking: There may be links to other files in one file, so you also need to combine the compiled object file with the system-provided file. This process is called linking. After linking, the executable file is generated.

After compilation and linking, the written code is converted into binary instructions that the computer can understand.

precompiled:

The main pretreatment rules are as follows:

  • Remove all #define and expand all macro definitions. The macro definitions used in the source code will be replaced with the corresponding code
  • Insert the included file into the location of the precompiled directive (#include) (this process is recursive)
  • Delete all comments: //, /* */ etc
  • Add line numbers and file name identifiers so that at compile time the compiler can generate line numbers for debugging and line numbers that display warnings and errors at compile time
  • Keep all #pragma compiler directives because the compiler needs to use them

When we can’t determine whether the macro definition is correct or whether the header file is included, we can look at the precompiled file to determine the problem

App Startup Process

There are three stages of App startup

  1. Before main() (pre-main phase)
  • Dylib loading: loads executable files
  • Rebase /binding: Adjusts the rebase pointer to bind to the bind symbol
  • Objc Setup: Objc Runtime initialization, Class registration, Category registration, Selector detection, etc
  • Initializer: initialization, +load() method execution, C++ global variable initialization, C/C++ statically initializing objects and a method labeled __attribute__(constructor)

One thing to note here is that the +load method is deprecated, and if you are developing with Swift you will find it impossible to write such a method. The official recommendation is to use initialize. The difference is that load is called when the class loads, while Initialize is called before the class first receives a message.

Dyld3 is used for loading after iOS13: dyld2 is a pure in-process, meaning that it is executed within the application process, meaning that dyld2 can only start executing tasks when the application is started. Dyld3 is partly out-of-process and partly in-process. In the figure, the part above the dotted line is out-of-process, which is executed during App download, installation and version update. Out-of-process does the following things: I. Analysis of Mach-o Headers II. Analysis of dependent dynamic library III. The lookup requires a symbol like Rebase & Bind iV. Write the above results to the cache

  1. Main () is executed (main is executed before setting rootViewController)
  • The first page Controller is loaded, and its children are loaded
  1. The first screen rendering (set after the rootViewController to didFinishLaunchWithOptions)
  • Initialize some additional functionality (third-party libraries, etc.)

Start the optimization

Reduce bundles — dylib — reduce categories — Rebase & Bind & Runtime — reduce loads and __atribute__((constructor)) — Initializers Lazy initializes unimportant SDKS and logic, initializes only necessary VC-main phases using Swift — cause binary reordering — startup process assist troubleshooting tool: TimeProfile

Multithreading and RunLoop

What is the RunLoop

What is runloop for? What does runloop have to do with threads? Does the main thread have Runloop enabled by default? What about child threads?
  • A runloop is a do-while loop in which various tasks (such as Source, Timer, Observer) events are continuously processed.
  • The relationship between runloops and threads: Each thread has one runloop. The runloop of the main thread is created and started by default, and the runloop of the child thread must be created and started manually (by calling the run method). Only one Mode can be selected to start the RunLoop. If there is no Source(Sources0, Sources1) or Timer in the current Mode, exit the RunLoop directly.

What does RunLoop do?

  • 1. Keep the program running
  • 2. Handle app events (touches, timers, etc.)
  • 3. Saves CPU resources and improves performance.

How is RunLoop implemented internally?

  1. A RunLoop contains several modes, each of which contains several sources/timers/observers.
  2. Only one Mode can be specified each time RunLoop’s main function is called, and this Mode is called CurrentMode.
  3. If you need to switch Mode, you can only exit Loop and specify another Mode to enter. The main purpose of this is to separate the Source/Timer/Observer groups from each other.

What does the mode of runloop do? How many modes are there?

  • Model: Is the running mode of runloop. Different runloop modes handle different events and messages. The system registers five modes by default:

(1) kCFRunLoopDefaultMode: the default Mode of App, usually the main thread runs under this Mode. (2) UITrackingRunLoopMode: interface tracking Mode, used for ScrollView tracking touch sliding, to ensure that the interface sliding is not affected by other modes. (3) UIInitializationRunLoopMode: when just start the App the first to enter the first Mode, start after the completion of the will no longer be used. (4) GSEventReceiveRunLoopMode: accept system internal Mode of events, usually in less than. (5) KcFRunLoopCommonMode: this is a placeholder Mode and has no effect. Note that iOS encapsulates the model in the above 5 NSDefaultRunLoopMode and NSRunLoopCommonModes

Runloop Startup process

Notify the observer that the run loop has started. 2. Notify the observer that Timer event 3 is about to start processing. Notify the observer that a non-port-based Source0 will be processed 4. Start the prepared Souecr0 5. If the port-based source Source1 is ready and in a waiting state, start immediately: and go to Step 9 6. Notify the observer that the thread is asleep 7. Put the thread into sleep until one of the following events occurs (1) an event reaches the port-based source (2) the timer is started (3) the Run loop set time has expired (4) The Run loop is explicitly awakened 8. 9. Handle unprocessed events, jump back to 2 (1) If the user-defined timer starts, process the timer event and restart the Run loop. Go to Step 2. (2) If the input source is started, pass the corresponding message. (3) If the run loop is awakened explicitly and the time has not expired, restart the run loop. Go to Step 2. 10. Notify the observer that the run loop ends

What is virtual memory

Virtual memory is an operating system for each process provides an abstract, each process has its own, private, continuous virtual memory address, of course we know the process of data and code is necessarily on the physical memory, so there must be some kind of mechanism can remember the some data in the virtual address space is on which physical memory addresses, This is called an address space mapping, a mapping between virtual memory addresses and physical memory addresses. How does the operating system remember this mapping? The page table records the mapping between virtual memory addresses and physical memory addresses. Page tables translate virtual addresses into physical memory addresses, a mechanism known as virtual memory. Each process has its own virtual address space, which is shared by all threads within the process.

Question:

What are the differences between threads and processes? How do processes communicate with each other?

1 between processes can not share memory, thread can be the same process thread shared a lot of resources changed process, including: process virtual space, process code segment, process shared data, etc., so it is easier to communicate between threads, multi-thread running efficiency is much higher than multi-process; 2. When the system creates a process, it allocates system resources to it, and the creation of threads is only a small part, so multithreading is easier than multi-process; 3. Multithreading can take full advantage of the processor (dual-core or multi-core), but the performance is no longer improved when the number of threads reaches the upper limit; 4. In a multi-threaded process, a thread crash will cause the process crash, if the main thread crash will cause the program crash; But the multi-process neutron process crash will not affect other processes, the program stability is better; 5. Multi-threading needs to control synchronization between threads, while multi-process needs to control interaction with the main process; 6. If two processes need to transmit a large amount of data to each other, performance will be greatly affected. Multi-process is suitable for small data transmission and intensive operation;

What is the difference between interprocess switching and interthread switching? Does thread switching require registers?

One of the main differences between process switching and thread switching is that process switching involves switching virtual address space while thread switching does not. Since each process has its own virtual address space, and threads share the virtual address space of the process they are in, thread switching does not involve the conversion of the virtual address space.

Why is the virtual address switchover slow? Now that we know that processes have their own virtual address space, converting virtual addresses to physical addresses requires page table lookup. Page table lookup is a slow process, so we usually use a Cache to Cache common address maps to speed up page table lookup. This Cache is called TLB. Translation Lookaside Buffer, we don’t need to worry about the name except that TLB is essentially a cache for speeding up page table lookup. Because each process has its own virtual address space, then obviously each process has its own page table, then when a process switch after the page table also wants to switch, switch a page table TLB after failure, cache invalidation results in the decrease of shooting, virtual addresses into physical addresses would be slow, showing it is slower, the program runs Thread switching does not invalidate TLB because thread threads do not need to switch address space, so we usually say thread switching compares process switching blocks, for this reason.

PerformSelector: afterDelay: why cannot execute the child thread?

PerformSelector: afterDelay: for in the current Runloop delay 3 seconds after the implementation method of the selector. Note the following when using this method: Calling performSelector in a child thread: withObject: afterDelay: This does not work by default, because the child thread’s Runloop is not enabled by default and therefore cannot respond to the method. So we try to add [[NSRunLoop currentRunLoop]run] to the GCD Block;

dispatch_async(dispatch_get_global_queue(0.0), ^{
        [self performSelector:@selector(sureTestMethod:)
                   withObject:params
                   afterDelay:3];
        [[NSRunLoop currentRunLoop]run];
    });
Copy the code

Running the code found that sureTestMethodCall prints normally. There’s a bit of a pit to note here. I tried to add [[NSRunLoop currentRunLoop]run] to performSelector: withObject: AfterDelay: before the afterDelay method, but the delay method is still not called. This is because a thread’s Runloop must have a timer, source, or observer event to trigger the start.

[self performSelector:@selector(sureTestMethod:)
                 onThread:thread
               withObject:params
            waitUntilDone:NO];
Copy the code

Method use the performSelector: onThread: it is important to note that in the thread life cycle is normal, if the thread has destroyed does not exist, while the performSelector to perform a task in this thread, can result in collapse:

RunLoop has several modes. What are the features?

Model: Is the running mode of runloop. Different runloop modes handle different events and messages. (1) kCFRunLoopDefaultMode: the default Mode of App, usually the main thread is run under this Mode. (2) UITrackingRunLoopMode: interface tracking Mode, used for ScrollView tracking touch sliding, to ensure that the interface sliding is not affected by other modes. (3) UIInitializationRunLoopMode: when just start the App the first to enter the first Mode, start after the completion of the will no longer be used. (4) GSEventReceiveRunLoopMode: accept system internal Mode of events, usually in less than. (5) KcFRunLoopCommonMode: this is a placeholder Mode and has no effect. Note that iOS encapsulates the model in the above 5 NSDefaultRunLoopMode and NSRunLoopCommonModes

What about memory management in threads?

If a thread is truncated, will the resource be released? The process?

Threads do not release resources and need to maintain resource release, especially locks.

Virtual memory management mechanism?

paging

Recent iOS systems, based on A7 and A8 processors, have 4KB physical memory pages and 16KB virtual memory pages. Based on A9 processor system, physical and virtual memory are 16KB paging system memory pages are divided into three states: (1) active page: memory pages have been mapped to physical memory, and recently accessed, in the active state. (2) Inactive page: an inactive page has been mapped to physical memory, but has not been accessed recently. (3) Free pages: set of physical memory pages that are not associated with virtual memory pages. When the number of available pages drops below a certain threshold, the system takes a low Memory response. In OSX, the system swaps inactive pages to hard disk, while in iOS, a Memory Warning is triggered. If your App does not handle the low Memory Warning and still uses too much Memory in the background, it may be killed.

A page table

The function of a page table is to provide a mapping of virtual pages to physical pages. The page table has the same number of entries as the number of virtual pages. In addition, the memory management unit relies on the page table for all page-related management activities, including determining whether a page number is in memory, whether the page is protected, whether the page is illegal space, and so on. Because of the special status of the page table, it is directly supported by the hardware, that is, the page table is a hardware data structure.

malloc

In OC, in addition to allocating memory using NSObject’s alloc, you can also allocate memory using c’s function malloc. Malloc allocates virtual memory first and then maps it to physical memory as it is used, but malloc has a defect that requires memset to set all values in the memory area to 0. This leads to the problem that when Malloc allocates a memory region, the system does not allocate physical memory. However, after calling memset, the system will associate all virtual memory from malloc with physical memory, because you have access to all memory regions. To solve this problem, Apple officially recommends using Calloc instead of Malloc. The memory region returned by Calloc is automatically zeroed out and only associated with physical memory when used.

ASLR

ASLR (Address Space Layout Randomization) is a security protection technology for buffer overflow. By randomizing the layout of linear areas such as heap, stack and shared library mapping, it increases the difficulty for attackers to predict the destination Address and prevents attackers from directly locating the attack code. To prevent overflow attacks.

Disadvantages of virtual memory

Virtual memory has the same disadvantage: hard disks have more capacity than memory, but only relatively, and are very slow. If data is exchanged with the hard disk too often, processing speed slows down and appears to be stuck, a phenomenon known as Thrushing. I believe that many people have had the experience of computer stopped responding, and one of the main reasons for the crash is jitter.

How to achieve synchronization and mutual exclusion of threads? How many ways are there to lock?

Juejin. Cn/post / 684490… There are 13 kinds of locks

1. os_unfair_lock

Os_unfair_lock is used to replace an unsafe OSSpinLock. Os_unfair_lock is available in iOS10 macos10.12

2. pthread_mutex_t pthread_cond_t

The mutex and condition variables are POSIX interfaces. For details, see Unix Interprocess Communication.

3. NSLock NSRecursiveLock

NSLock is a wrapper around the pthread_mutex plain lock. pthread_mutex_init(mutex, NULL); The default attribute is PTHREAD_MUTEX_NORMAL. NSLock follows the NSLocking protocol and uses the same method as pthread_mutex

4. NSCondition

NSCondtion is the encapsulation of pthread_mutex and pthread_cond

5. NSCondtionLock

NSConditionLock is a further encapsulation of NScondition

6. synchronized

@ synchronized using

Precautions for Use

Careful @ synchronized (self)

Use self to change the address of the object used externally. It is easy to mix @synchronized and other locks externally and cause _ deadlock _ problems

7. Pthread_rwlock Read/write lock

Pthread_rwlock is often used for reading and writing data, such as files

8. Atomic properties

Atomic is used to ensure atomicity of property setters and getters. It is equivalent to placing thread synchronization locks inside getters and setters (using a spin lock). It does not guarantee thread-safe use of properties (e.g. An array property is only thread-safe on sets and gets, but not array addObject and removeObject).

What is the difference between GCD and NSThread and OperationQueue?

Do you know coroutines?

reference

Semaphore mechanisms: Producers and consumers

memory

The article

1. Automatic release pool of past life

A. The entire iOS application is contained in an auto-release pool block; B. @autoreleasepool {} is converted to an __AtAutoreleasePool structure that calls the objc_autoreleasePoolPush() method on initialization, The objc_autoreleasePoolPop method is called at destructor time; C. AutoreleasePoolPage is a C++ class:

Objc-autorelease-autoreleasepoolpage it is defined in nsobject. mm as follows:

class AutoreleasePoolPage {
    magic_t const magic;
    id *next;
    pthread_t const thread;
    AutoreleasePoolPage * const parent;
    AutoreleasePoolPage *child;
    uint32_t const depth;
    uint32_t hiwat;
};
Copy the code
  • Magic Verifies the integrity of the current AutoreleasePoolPage
  • Thread saves the thread in which the previous page is located

Each AutoreleasePoolPage consists of a series of AutoreleasepoolPages, each of which is 4096 bytes (hexadecimal 0x1000).

B. The main thread will enable Runloop by default. Runloop will automatically create Autoreleasepool and perform Push and Pop operations for memory management. When you create a Pool in the child thread, the resulting Autorelease object will be managed by the Pool. The autoreleaseNoPage method is called if you did not create a Pool but generated an Autorelease object. In this method, a HotPage is automatically created for you

Conclusion:

The autorelease pool is implemented by AutoreleasePoolPage as a two-way linked list when an object calls the AutoRelease method, The AutoreleasePoolPage:: POP method is called to send a release message to the object in the stack

Question:

The difference between heap and stack

C++ memory structure

Block principle

Ref 2

When will the automatic release pool be released?

  • When RunLoop is enabled, an auto-release pool is automatically created, and when RunLoop is resting, the auto-release pool is released, and a new empty auto-release pool is created

Algorithms and data structures

Question: Implementation of virtual functions? Virtual function table, where is it stored? Implementation of polymorphism? Difference between malloc and New Difference between virtual memory and physical memory difference between vector and list index, implemented data structure (B-tree), B + tree and B tree and hash table How to implement load balancing?

Algorithm: Given an ascending sequence and target value, rotate the sequence, find the subscript of the target value, ask O (logn) to implement the mirrored binary tree design pattern, ok? (singleton, factory, observer), decorator patterns understood? Find the left view of the binary tree a sorted linked list, sorted forward for odd positions, sorted backward for even positions, the classic stock selling problem I & II

network

Congestion control TCP three-way handshake, four-way wave seven-layer model QUIC principle SSL mechanism DNS domain name resolution process

Packet size

DATA migration: avoid file compression caused by encryption invalid resources: pictures, class-static scan + code coverage check tool, three-party SDK size control + offline