腾讯面经总结

1、给一个正整数,将它分成n个正数,使其乘积最大。

将正整数从2,3,4…..开始连续分割,最后没分完的均匀地从最大的已分割出的数开始均匀分配下去。

2、map底层为什么用红黑树实现

3、字节对齐

4、共享内存位于进程中的什么位置

5、程序内存崩溃了怎么办?

gdb core dump文件,backtrace可以查看哪里有段错误

6、Linux下查看程序内存状况

top指令可以查看按内存大小排序的查询内存状况,或者查看/proc/pid/status文件,这个文件会记录进程id所代表的进程的内存状态

7、用户态和内核态

为什么要划分用户空间和系统空间呢?当然是有必要的。操作系统的数据都是存放于系统空间的,用户进程的数据是存放于用户空间的。这是第一点,不同的身份,数据放置的位置必然不一样,否则大混战就会导致系统的数据和用户的数据混在一起,系统就不能很好的运行了。分开来存放,就让系统的数据和用户的数据互不干扰,保证系统的稳定性。分开存放,管理上很方便,而更重要的是,将用户的数据和系统的数据隔离开,就可以对两部分的数据的访问进行控制。这样就可以确保用户程序不能随便操作系统的数据,这样防止用户程序误操作或者是恶意破坏系统。

Linux使用了Ring3级别运行用户态,Ring0作为 内核态,没有使用Ring1和Ring2。Ring3状态不能访问Ring0的地址空间,包括代码和数据。程序特权级别的不同,其所拥有的权力也不同。

用户态切换到内核态的3种方式:

a. 系统调用

这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作,比如fork()实际上就是执行了一个创建新进程的系统调用。而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现,例如Linux的int 80h中断。

b. 异常

当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。

c. 外围设备的中断

当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

这3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。

8、有抓过rpc的包吗?(没有…)

9、connect会阻塞,怎么解决? 2.如果select返回可读,结果只读到0字节,什么情况?

解决connect阻塞的方法:

1.使用定时器;(最常用也最有效的一种方法)
2.采用非阻塞模式:设置非阻塞,返回之后用select检测状态。

如果读到0字节:

某个套接字集合中没有准备好,可能会select内存用FD_CLR清该位为0。
如果在一个描述符上碰到了文件尾端,则select会认为该描述符是可读的。然后调用read,它返回0,这是Unix系统指示到达文件尾端的方法。

10、exit()和_exit()的区别

exit()会将缓冲区的内容写入文件,才结束进程。而_exit()直接关闭进程,缓冲区的内容将丢失。

11、i++是否原子操作?并解释为什么?

不是,在高级程序语言中,如java与C++等,并不能保证多个线程i++,操作同一个i,可以得到正确的结果。因为还有寄存器的因素,多个cpu对应多个寄存器。每次要先把i从内存复制到寄存器,然后++,然后再把i复制到内存中,这需要至少3步。从这个意义上讲,说i++是原子的并不对。

12、哪些库函数属于高危函数,为什么?

void * memcpy( void *dst, const void *src, size_t len); 当len超过dst实际内存大小时,存在踩越界;
char* strcpy(char* dest,const char* src); 当src字符串长度超过dest字符串长度,存在踩越界;
char * strncpy( void *dst, const void *src, size_t len); 当len超过dst实际内存大小时,存在踩越界;
当len小于src实际内存大小时,实际按len大小拷贝到dest中,不会置结束符,可能会存在访问越界风险。
int sprintf(char * buf, const char *fmt, …); 当参数fmt变长字符串长度超过buf长度,存在踩越界;
char* strcat(char* dest,const char* src) 当src字符串长度超过dest剩余长度,存在踩越界;
char * strncat(char *dest, const char *src, size_t count) 当count超过dest剩余内存大小时,存在踩越界;

15、写一个程序判断大端小端

#include<iostream>
#include<vector>

using namespace std;

union A{
    char a;
    int num;
};

int main()
{
    union A tmp;
    tmp.num = 0x12345678;
    if (tmp.a == 0x78)
    {
    cout << "it is small"<<endl;
    }
    else
    {
    cout << "it is small" << endl;
    }
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38921322/article/details/81782009