[Golang development side by side] Didi (three rounds of technical side)

write in front

Didi's interview is okay, it's very basic, and a lot of time is spent on digging projects, so everyone must be very familiar with their projects! The level of interviewers is also very high. But I also sigh that this once big factory has become like this now, alas. .

written examination

slightly

one side

inter-process communication

Pipes, message queues, semaphores, shared memory

Is it faster to allocate memory on the stack or on the heap, why?

显然从栈上分配内存更快,因为从栈上分配内存仅仅就是栈指针的移动而已

  1. The operating system will provide support for the stack at the bottom layer, and will allocate specialized ones 寄存器存放栈的地址.
  2. The stack's push and pop operations are also very simple, and there are 专门的指令执行, so the stack is more efficient and faster.
  3. The growth space of the heap is upward, and the address is getting larger and larger, and the growth space of the stack is downward, and the address is getting smaller and smaller.

channel bottom layer

type hchan struct {
    
    
 qcount   uint   
 // channel 里的元素计数
 dataqsiz uint   
 // 可以缓冲的数量,如 ch := make(chan int, 10)。 此处的 10 即 dataqsiz
 elemsize uint16 
 // 要发送或接收的数据类型大小
 buf      unsafe.Pointer 
 // 当 channel 设置了缓冲数量时,该 buf 指向一个存储缓冲数据的区域,该区域是一个循环队列的数据结构
 closed   uint32 
 // 关闭状态
 sendx    uint  
 // 当 channel 设置了缓冲数量时,数据区域即循环队列此时已发送数据的索引位置
 recvx    uint  
 // 当 channel 设置了缓冲数量时,数据区域即循环队列此时已接收数据的索引位置
 recvq    waitq 
 // 想读取数据但又被阻塞住的 goroutine 队列
 sendq    waitq 
 // 想发送数据但又被阻塞住的 goroutine 队列
 
 lock mutex
 ...
}

insert image description here

seven-layer model

From top to bottom are the application layer, presentation layer, session layer, transport layer, network layer, data link layer, physical layer, etc...

tcp、udp

TCP is a reliable transmission, connection-oriented, and flow-based, which occupies a lot of resources and is inefficient.

UDP is a best-effort delivery, based on connectionless, based on packets, UDP occupies less system resources and is efficient.

How redis persists and usage scenarios

Redis provides two persistence mechanisms, RDB and AOF. With this, 持久化机制we can basically avoid the problem of data loss caused by the abnormal exit of the process. Redis can use the persistent files generated between restarts to implement it 数据恢复.

  • RDB persistence means that the 当前进程的数据生成快照存入到磁盘triggering RDB mechanism is divided into 手动触发与自动触发.

  • AOF 持久化Each write command is recorded in an independent log, and the commands in the AOF file are re-executed when Redis is restarted to restore data, so AOF is the main solution 持久化的实时性.

How to implement thread pool?

The thread pool consists of two parts: the synchronization queue and the thread pool.

  • Synchronization queue: Create one in the form of a linked list. 同步队列The main job of the synchronization queue is Put()to add transactions to the queue through functions, and to remove transactions from the queue through the Get() function.
  • Thread pool: It is mainly composed of thread group (note: thread 类型the shared pointer stored in the thread group can only point to the working thread), Start()add numThreadsa thread to the thread group through the function, and make each thread call the RunThread()function to obtain the synchronization queue The transaction is executed and the transaction is executed; the Stop()thread pool work is stopped by the function.

insert image description here

Algorithm: Top View of Binary Tree

two sides

How to judge whether a given ip is within a given ip range?

The IP address can be converted into an integer, and the returned IP can be rounded into an integer range for troubleshooting.

package main

import (
    "fmt"
    "strconv"
    "strings"
)

func main() {
    
    
    ipVerifyList := "192.168.1.0-192.172.3.255"
    ip := "192.170.223.1"
    ipSlice := strings.Split(ipVerifyList, `-`)
    if len(ipSlice) < 0 {
    
    
        return
    }
    if ip2Int(ip) >= ip2Int(ipSlice[0]) && ip2Int(ip) <= ip2Int(ipSlice[1]) {
    
    
        fmt.Println("ip in iplist")
        return
    }
    fmt.Println("ip not in iplist")
}

func ip2Int(ip string) int64 {
    
    
    if len(ip) == 0 {
    
    
        return 0
    }
    bits := strings.Split(ip, ".")
    if len(bits) < 4 {
    
    
        return 0
    }
    b0 := string2Int(bits[0])
    b1 := string2Int(bits[1])
    b2 := string2Int(bits[2])
    b3 := string2Int(bits[3])

    var sum int64
    sum += int64(b0) << 24
    sum += int64(b1) << 16
    sum += int64(b2) << 8
    sum += int64(b3)

    return sum
}

func string2Int(in string) (out int) {
    
    
    out, _ = strconv.Atoi(in)
    return
}

How to optimize slow SQL?

  1. Check to see if the index is used.
  2. Check whether the SQL statement conforms to the leftmost matching principle.
  3. Optimize queries to avoid full table scans as much as possible
  4. Field redundancy, reducing cross-database queries or multi-table join operations
  5. Put some common data structures in the buffer (department name, organizational structure, etc.), you don't need to check the database.

When is it not recommended to use an index

  1. Fields that are not used in the where condition (including group by and order by) do not need to be indexed. The value of the index is fast positioning. If the field cannot be positioned, it is usually not necessary to create an index.
  2. It is best not to use indexes for tables with a small amount of data, less than 1000
  3. If there is a lot of duplicate data (gender) in the field, there is no need to create an index
  4. Avoid creating too many indexes on frequently updated tables.
  5. Using unordered values ​​as indexes is not recommended.

Several rejection strategies of thread pools and their application scenarios

I didn't know what it was at the time...
Read this blog for details. Application Scenario of Thread Pool Rejection Policy

Difference between http and tcp

http is an application layer protocol based on the tcp implementation of the transport layer.

Long and short connections

A long connection means that after a data transfer, the connection is not closed and the connection is maintained for a long time.

A short connection means that a new connection needs to be established for each data transfer, and then it is closed immediately after it is used up. Re-establish a new connection the next time you use it, and so on.

Talk about tcp waving?

After the data transmission is completed, both parties of the communication can release the connection. Now both A and B are in ESTABLISHEDstate.

  1. The application process of A first sends a connection release segment to TCP, stops sending data again, and actively closes the TCP connection. A puts the termination control FINposition as 1, and its sequence number is seq=uequal to the sequence number of the last byte of the previously transmitted data 1. At this time, A enters the FIN-WAIT-1(终止等待1)state and waits for B's confirmation.

Note : TCP stipulates that even if the FIN segment does not carry data, it consumes a sequence number! !

  1. After B receives the link release segment, it sends an acknowledgement. The acknowledgement number is ack = u + 1, and the sequence number of this segment is vequal to the data that has been transmitted before 最后一个字节的序号加1B. Then B enters the CLOSE-WAIT(关闭等待)state. The TCP server process should notify the high-level application process at this time, so the link from A to B is released. At this time, the TCP link is in a half-closed state, that is, A has no data to send, but if B sends data, A Still to receive, that is, the connection in the direction from B to A is not closed. This state may last for a while.
  2. After A receives the confirmation from B, it enters the FIN-WAIT-2(终止等待2)state full and waits for the connection release segment sent by B. If B has no data to send to A, its application process will notify TCP to release the connection. At this time, the connection release segment sent by B must be FIN = 1used. Now suppose that the serial number of B is w(in the half-closed state B may send some more data). B must also repeat the confirmation number that has been sent last time ack = u + 1. At this time, B enters the LAST-ACK(最后确认)state and waits for A's confirmation.
  3. After A receives B's link release segment, it must issue an acknowledgement. In the confirmation segment, the ACK置1confirmation number ack=w+1, and its own sequence number is seq=u+1(according to the TCP standard, the previously sent FIN segment consumes a sequence number). Then enter the TIME-WAIT(time waiting) state. Note: Now TCP connection 还没有还没有释放掉. A must wait for the time set by the timer 2MSLbefore A can enter the CLOSED state.

The time MSL is called the maximum segment lifetime, and RFC793 recommends setting it at two minutes. But two minutes is too long in current engineering, so TCP allows different implementations to use smaller MSL values ​​depending on the situation.

insert image description here

time wait, what to do if there is too much

  1. Modify the upper limit value of the TIME_WAIT connection state
  2. Start the fast recovery mechanism
  3. Enable multiplexing mechanism
  4. Modify short connection to long connection
  5. Actively disconnected by the client

Algorithms: Forgot...

Three sides

talk about life...

Guess you like

Origin blog.csdn.net/weixin_45304503/article/details/126690590