服务端开发面试题

服务端开发工程师常见面试题目

多进程多线程的区别
1.进程是资源调度的最小单位,线程是cpu调度的最小单位
2.数据共享和同步:多进程(数据共享复杂,需要ipc;数据是分开的,同步简单)多线程(共享进程数据,数据同步复杂)
3.内存,cpu: 多进程(占用内存多,切换复杂,cpu利用率低)多线程(占用内存少,切换简单,cpu利用率高)
4.编程调试:多进程(编程调试简单)多线程(变成调试复杂)
5.可靠性:多进程(进程间不会互相影响)多线程(一个线程挂掉导致整个进程挂掉)
6.分布式:多进程(适应于多核,多机分布式;如果一台机器不够,扩展到多台机器比较简单)多线程(适应于多核分布式)


c++类里面编译器默认生成的函数有哪几个?
1.构造函数
2.拷贝构造函数
3.赋值构造函数
4.析构函数

voliate关键字的作用
使用voliate声明变量值的时候,系统总是重新从它所在的内存读取数据;用voliate声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错.
使用场景:多任务环境下各任务间共享的标志应该加voliate;存储器映射的硬件寄存器通常也要加voliate,因为每次对它的对写都可能有不同意义;

指针和引用的区别:
本质:指针是一个指向另一个地址的变量,引用是变量的别名
初始化:指针可以不用初始化,引用必须要初始化

c++中多态的实现:
1.函数重载
2.虚函数(虚函数的机制:虚表)

string类的实现:
class String{
public:
  String(const char* data = NULL);
  String(const String& str);
  ~String();

  String& operator=(const String& str);
private:
  char* data;
};


String::String(const char* data){
  if(!data){
    this->data = new char[1];
    this->data[0] = '\0';
  }else{
    this->data = new char[strlen(data)+1];
    strcpy(this->data, data);
  }
}

String::String(const String& str){
  this->data = new char[strlen[str->data]+1];
  strcpy(this->data, str->data);
}

String::~String(){
  if(this->data){
    delete[] data;
  }
}

String& operator=(const String& str){
  if(&str==this) return *this;
  String str_tmp(str.data);
  char* data_tmp = str_tmp.data;
  str_tmp.data = this->data;
  this->data = data_tmp;
}



epoll水平出发和边缘出发的区别:
Level_triggered(水平触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率!!!

Edge_triggered(边缘触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符!!!



select和epoll的区别:
(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。

(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。



文件描述限制
    在编写文件操作的或者网络通信的软件时,初学者一般可能会遇到“Too many open files”的问题。这主要是因为文件描述符是系统的一个重要资源,虽然说系统内存有多少就可以打开多少的文件描述符,但是在实际实现过程中内核是会做相应的处理的,一般最大打开文件数会是系统内存的10%(以KB来计算)(称之为系统级限制),查看系统级别的最大打开文件数可以使用sysctl -a | grep fs.file-max命令查看。与此同时,内核为了不让某一个进程消耗掉所有的文件资源,其也会对单个进程最大打开文件数做默认值处理(称之为用户级限制),默认值一般是1024,使用ulimit -n命令可以查看。在Web服务器中,通过更改系统默认值文件描述符的最大值来优化服务器是最常见的方式之一,具体优化方式请查看http://blog.csdn.net/kumu_linux/article/details/7877770。


你可能感兴趣的:(服务端研发,c++语法特性)