2020 C/C++ Selected Interview Questions and Answers (2)

What is parallel computing?
Parallel computing refers to the process of using multiple computing resources to solve computing problems at the same time. It is an effective means to improve the computing speed and processing capacity of a computer system. Its basic idea is to use multiple processors to solve the same problem cooperatively, that is, to decompose the solved problem into several parts, and each part is calculated in parallel by an independent processor. The parallel computing system can be a specially designed supercomputer with multiple processors, or a cluster of several independent computers interconnected in a certain way. The data processing is completed through the parallel computing cluster, and then the processing result is returned to the user.

Parallel computing can be divided into parallel in time and parallel in space.

Parallel in time: refers to the assembly line technology, for example, when the factory produces food, the steps are divided into:

1. Cleaning: Rinse the food.

2. Disinfection: Disinfect food.

3. Cutting: Cut the food into small pieces.

4. Packaging: Put the food in a packaging bag.

If the assembly line is not used, after one food completes the above four steps, the next food will be processed, which is time-consuming and affects efficiency. But with assembly line technology, four foods can be processed simultaneously. This is the time parallelism in parallel algorithms. Two or more operations are started at the same time, which greatly improves computing performance.

Spatial parallelism: refers to the concurrent execution of calculations by multiple processors, that is, connecting two or more processors through a network to simultaneously calculate different parts of the same task, or large-scale problems that a single processor cannot solve.

What are the host IP addresses that belong to the same network segment as 10.110.12.29mask 255.255.255.224?

The IP address segment calculated based on the IP address and mask you provided is 10.110.12.0/27.

That is from 10.110.12.0 to 10.110.12.31.

Tell me about the content of Makefile.

target-target file, it can be Object File or executable file

prerequisites-generate files or targets required by target

command-the command to be executed by make (any shell command), the command in the Makefile must start with [tab]

Display rules: Explain how to generate one or more target files (including generated files, file dependent files, generated commands)

Obscure rules: rules executed by make's automatic derivation function

Variable definition: Variables defined in Makefile

File instructions:: Quote other Makefiles in Makefile; Specify valid parts in Makefile; Define a multi-line command

Note:: Makefile only has a line comment "#", if you want to use or output the "#" character, you need to escape it, "#"

Finally, it is worth mentioning that the commands in the Makefile must start with the [Tab] key.

Talk about C++ inline functions

Inline function inline: The purpose of introducing inline function is to solve the efficiency problem of function call in the program. Let’s put it this way, when the program is compiled by the compiler, the compiler will use the inline function call expression in the program. The function body of the associative function is replaced, and for other functions, it is replaced at runtime. This is actually a saving of space and time. So inline functions are generally small functions with lines 1-5. Be careful when using inline functions:

1. Loop statements and switch statements are not allowed in inline functions;

2. The definition of the inline function must appear before the first call of the inline function;

3. The class description in the class structure indicates that the internally defined function is an inline function.

vector, deque, list, set, map The underlying data structure vector (vector)-the standard and safe array in STL. You can only add data to the "front" of the vector.

deque (double-ended queue)-similar in function to vector, but you can add data to it at the front and back ends.

list-The cursor can only move one step at a time. If you are already familiar with linked lists, the list in STL is a doubly linked list (each node has two pointers to the predecessor and the successor).

set (collection)-Contains sorted data, the value of these data must be unique.

map (mapping)-a set of sorted two-tuples, each element in the map is composed of two values, where the key (key value, the key value in a map must be unique) is in Used when sorting or searching, its value can be retrieved in the container; and the other value is the value associated with the element. For example, in addition to finding a data with ar[43] = "overripe", map can also find a data with ar["banana"] = "overripe". If you want to get the element information, you can do it easily by entering the full name of the element.

Advantages and disadvantages of macro definitions

advantage:

  1. Improve the readability of the program, but also facilitate the modification;

  2. Improve the operating efficiency of the program: The use of macro definitions with parameters can not only complete the function of function calling, but also avoid the stack and stack operations of functions, reduce system overhead and improve operating efficiency;

3. The macro is processed by the preprocessor, and many functions that the compiler cannot achieve can be accomplished through string manipulation. Such as ##connector.

Disadvantages:

  1. Because it is directly embedded, the code may be relatively more;

  2. Too many nested definitions may affect the readability of the program, and it is easy to make mistakes;

  3. For macros with parameters, since it is a direct replacement, it does not check whether the parameters are legal, which poses security risks.

[Article Welfare] I recommend my Linux and C/C++ technology exchange group: [960994558] I have compiled some learning books and video materials that I think are better for sharing, and you can add them if you need them! ~

How to traverse bfs and dfs

1. Depth First Search (DFS)

The depth-first search code in the original text is problematic. It is the promotion of middle-order traversal, and depth-first search is the promotion of first-order traversal. I will give both codes here. The non-recursive implementation of depth-first search is used. A stack.

The depth-first method of traversing the graph is to start from a vertex v in the graph:

a. Visit vertex v;

b. Starting from the unvisited neighboring points of v in turn, depth-first traversal of the graph; until the vertices in the graph that have a path to v are visited;

c. If there are still vertices in the graph that have not been visited at this time, starting from an unvisited vertex, the depth-first traversal is repeated until all vertices in the graph have been visited.

Use a diagram to express this process as follows:

1). Starting from v = vertex 1, visit vertex 1 first
Insert picture description here

Insert picture description here

Insert picture description here

2). Recursively visit an unvisited adjacent point 2 of v according to depth-first search. After vertex 2 ends, one of 3 or 5 should be visited, here is vertex 3, at this time vertex 3 has no out-degree , So back to vertex 2, and then visit another adjacent point 5 of vertex 2. Since the arc head of the only edge of vertex 5 is 3, it has already been visited, so at this time continue to backtrack to vertex 1, find other adjacent points of vertex 1 point.

The above figure can be expressed as an adjacency matrix:

int maze[][] = { {0, 1, 1, 0, 0 }, {0, 0, 1, 0, 1 }, {0, 0, 1, 0, 0 }, {1, 1, 0 , 0, 1 }, {0, 0, 1, 0, 0} }; The specific code is as follows:






import java.util.LinkedList;
import classEnhance.EnhanceModual;
 
public class DepthFirst extends EnhanceModual {
    
    
 
 @Override
 public void internalEntrance() {
    
    
 // TODO Auto-generated method stub
 int maze[][] = {
    
    
{
    
     0, 1, 1, 0, 0 }, 
{
    
     0, 0, 1, 0, 1 }, 
{
    
     0, 0, 1, 0, 0 }, 
{
    
     1, 1, 0, 0, 1 },
 {
    
     0, 0, 1, 0, 0 } 
};
 dfs(maze, 1);
 }
 
 public void dfs(int[][] adjacentArr, int start) {
    
    
 int nodeNum = adjacentArr.length;
 if (start <= 0 || start > nodeNum || (nodeNum == 1 && start != 1)) {
    
    
 System.out.println("Wrong input !");
 return;
 } else if (nodeNum == 1 && start == 1) {
    
    
 System.out.println(adjacentArr[0][0]);
 return;
 }
 
 int[] visited = new int[nodeNum + 1];//0表示结点尚未入栈,也未访问
 LinkedList<Integer> stack = new LinkedList<Integer>();
 stack.push(start);
 visited[start] = 1;//1表示入栈
 
 while (!stack.isEmpty()) {
    
    
  int nodeIndex = stack.peek();
 boolean flag = false;
 if(visited[nodeIndex] != 2){
    
    
 System.out.println(nodeIndex);
 visited[nodeIndex] = 2;//2表示结点被访问
 }
 
 //沿某一条路径走到无邻接点的顶点
 for (int i = 0; i < nodeNum; i++) {
    
    
 if (adjacentArr[nodeIndex - 1][i] == 1 && 
visited[i + 1] == 0) {
    
    
 flag = true;
 stack.push(i + 1);
 visited[i + 1] = 1;
  break;//这里的break不能掉!!!!
 }
 }
 
 //回溯
 if(!flag){
    
    
 int visitedNodeIndex = stack.pop();
 }
 
 }
 }
}

Breadth First Search (BFS)

Breadth-first search is to process vertices in layers. The vertices closest to the starting point are visited first, and the vertices farthest are visited last. This is very similar to the order variable of a tree. The BFS code uses a queue. Search steps:

a. First select a vertex as the starting vertex, and dye it gray, and the remaining vertices are white.

b. Put the starting vertex in the queue.

c. Select a vertex from the head of the queue and find all the adjacent vertices, put the found adjacent vertices at the end of the queue, paint the vertices that have been visited black, and the vertices that have not been visited white. If the color of the vertex is gray, it means it has been found and put in the queue, if the color of the vertex is white, it means it has not been found yet

d. Process the next vertex in the queue in the same way.

Basically, the top of the queue becomes black, the one in the queue is gray, and the one that has not entered the queue is white.

Use a diagram to express this process as follows:
Insert picture description here

1. Initial state, starting from vertex 1, queue = {1}

Insert picture description here

2. Visit the adjacent vertices of 1, 1 goes out of the queue and turns black, 2,3 enters the queue, queue = {2,3,}

Insert picture description here

3. Visit the adjacent vertex of 2, 2 out of the queue, 4 into the queue, queue = {3,4}

Insert picture description here

4. Visit the adjacent vertex of 3, 3 dequeue, queue = {4}

Insert picture description here

5. Visit the adjacent vertices of 4, 4 dequeue, queue = {empty}

analysis:

Start breadth first search from vertex 1:

Initial state, starting from vertex 1, queue = {1}

Visit the adjacent vertices of 1, 1 goes out and turns black, 2,3 joins the queue, queue={2,3,}

Visit the adjacent vertex of 2, 2 dequeue, 4 enqueue, queue = {3,4}

Visit 3 adjacent vertices, 3 dequeue, queue = {4}

Visit 4 adjacent vertices, 4 dequeue, queue = {empty}

Vertex 5 is unreachable for 1.

The above figure can be represented by the following adjacency matrix:

int maze[][] = { {0, 1, 1, 0, 0 }, {0, 0, 1, 1, 0 }, {0, 1, 1, 1, 0 }, {1, 0, 0 , 0, 0 }, {0, 0, 1, 1, 0} }; The specific code is as follows. This code has two functions. The bfs() function finds the search result from a vertex, and the minPath() function Find the shortest distance from a vertex to another vertex:






import java.util.LinkedList;
import classEnhance.EnhanceModual;
 
public class BreadthFirst extends EnhanceModual {
    
    
 
 @Override
 public void internalEntrance() {
    
    
 // TODO Auto-generated method stub
 int maze[][] = {
    
    
 {
    
     0, 1, 1, 0, 0 }, 
 {
    
     0, 0, 1, 1, 0 }, 
 {
    
     0, 1, 1, 1, 0 },
 {
    
     1, 0, 0, 0, 0 },
 {
    
     0, 0, 1, 1, 0 }
 };
 
 bfs(maze, 5);//从顶点5开始搜索图
 
 int start = 5;
 int[] result = minPath(maze, start);
 for(int i = 1; i < result.length; i++){
    
    
 if(result[i] !=5 ){
    
    
 System.out.println("从顶点" + start +"到顶点" + 
i + "的最短距离为:" + result[i]);
 }else{
    
    
 System.out.println("从顶点" + start +"到顶点" + 
i + "不可达");
 }
 }
 }
 
 public void bfs(int[][] adjacentArr, int start) {
    
    
 int nodeNum = adjacentArr.length;
 if (start <= 0 || start > nodeNum || (nodeNum == 1 && start != 1)) {
    
    
 System.out.println("Wrong input !");
 return;
 } else if (nodeNum == 1 && start == 1) {
    
    
 System.out.println(adjacentArr[0][0]);
  return;
 }
 
//0表示顶点尚未入队,也未访问,注意这里位置0空出来了
 int[] visited = new int[nodeNum + 1];
 LinkedList<Integer> queue = new LinkedList<Integer>();
 queue.offer(start);
 visited[start] = 1;//1表示入队
 
 while (!queue.isEmpty()) {
    
    
 int nodeIndex = queue.poll();
 System.out.println(nodeIndex);
 visited[nodeIndex] = 2;//2表示顶点被访问
 
 for (int i = 0; i < nodeNum; i++) {
    
    
 if (adjacentArr[nodeIndex - 1][i] == 1 && 
visited[i + 1] == 0) {
    
    
 queue.offer(i + 1);
 visited[i + 1] = 1;
 }
 }
 }
 }
 
 /*
 * 从start顶点出发,到图里各个顶点的最短路径
 */
 public int[] minPath(int[][] adjacentArr, int start) {
    
    
 
 int nodeNum = adjacentArr.length;
 
 LinkedList<Integer> queue = new LinkedList<Integer>();
 queue.offer(start);
 int path = 0;
 int[] nodePath = new int[nodeNum + 1];
 for (int i = 0; i < nodePath.length; i++) {
    
    
 nodePath[i] = nodeNum;
 }
 nodePath[start] = 0;
 
 int incount = 1;
 int outcount = 0;
 int tempcount = 0;
 
 while (path < nodeNum) {
    
    
 path++;
 while (incount > outcount) {
    
    
 int nodeIndex = queue.poll();
 outcount++;
 
 for (int i = 0; i < nodeNum; i++) {
    
    
 if (adjacentArr[nodeIndex - 1][i] == 1 && 
nodePath[i + 1] == nodeNum) {
    
    
 queue.offer(i + 1);
 tempcount++;
 nodePath[i + 1] = path;
 }
 }
 }
 
 incount = tempcount;
 tempcount = 0;
 outcount = 0;
 }
 
 return nodePath;
 }
}

How does the CPU access memory?

Through the memory management unit (MMU)

First look at a simple flow chart of CPU access memory:
Insert picture description here

TLB: Convert lookaside cache. With it, the conversion speed of virtual address to physical address can be greatly increased.

From the above figure, we can clearly know the relationship between CPU, DDR, and MMU. When the MMU is turned on, the CPU accesses all virtual addresses.

First, the virtual address is converted to a physical address through the MMU,

Then access the memory through the bus (we all know that the memory is hung on the bus).

Then how does the MMU convert the virtual address to the physical address? Of course, it is through the page table. The MMU finds out the physical address corresponding to the virtual address from the page table, and then accesses the physical memory.

Find the numbers that are not in the A array and the B array, and the numbers that are not in the A array in the B array


```cpp
public static void find(int arr[],int[]b){
    
    
 HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
 for (int i = 0; i < arr.length; i++) {
    
    
 map.put(arr[i],0);
 }
 for (int i=0;i<b.length;i++) {
    
    
 if(map.containsKey(b[i])){
    
    
 map.put(b[i],1);
 }else{
    
    
 System.out.println("在B数组中A不存在的数字");
 System.out.println(b[i]);
 }
 }
 for (int i = 0; i <arr.length ; i++) {
    
    
 if(map.get(arr[i])==0){
    
    
 System.out.println("在A数组中存在的,在B数组不存在的数字");
 System.out.println(arr[i]);
 }
 }
}

Guess you like

Origin blog.csdn.net/weixin_52622200/article/details/110563825