C/C++,系统知识考点

http://www.cnblogs.com/hanxi/archive/2012/11/04/2753993.html

一、C
①基本函数实现
swap()
reverse()

void reverse(char s[],int longest)
{
  char c;
  int i=0;
  if (longest>1)
  {
    for (i=0;i<longest-1;i++)
    {
      c=s[i];
      s[i]=s[i+1];/* 依次交换数组中相邻的数组元素 */
      s[i+1]=c;
     }
      longest--;
      reverse (s,longest);
   }
}

strcpy()

char *strcpy(char *strDestination, const char *strSource)

{

  assert(strDestination!=NULL && strSource!=NULL);

  char *strD=strDestination;

  while ((*strDestination++=*strSource++)!='\0');

  return strD;

}


②五个存储区:

代码区:

全局区:存储全局变量和静态变量

常量区:存储常量

栈:存储局部变量

堆:存储malloc,new申请的内存空间
③内存对齐
④数组名问题
int a[10];
int *p=a;
p++;p+1;a+1;
a++;//错误,数组名名是常量

二、C++
①static的作用
②const的作用
③四个类型转换
static_cast<>:普通类型之间的转换(int,float等)static_cast<int>(a)
dynamic_cast<>;类之间的转换,且具有继承关系的类之间
const_cast<>;将const数据转换成非const
reinterpret_cast<>;改变函数指针类型之间的转换(不可移值,与具体编译器有关)
④placement new
规定对象的存储位置
http://blog.csdn.net/xiaobo68688/article/details/5650516
⑤浅拷贝和深拷贝
析构函数,operator=(),拷贝构造函数,三者一般同时自定义(自定义了一个则需定义其它两个)
⑥在C++中引用C的函数和变量
在前面加extern "C"
⑦虚析构函数的作用
防止内存泄露

三、数据结构
①链表
创建、添加、删除
②查找时间对比
栈、队列、二叉排序树、hash表
③Btree,Hash

四、算法
①排序
插入:直接插入、希尔

插入排序:

void insertion_sort(char array[], unsigned int first, unsigned int last)
{
  int i,j;
  int temp;
  for (i = first+1; i<last;i++)
  {
    temp = array[i];
    j=i-1;

    //与已排序的数逐一比较,大于temp时,该数移后
    while((j>=first) && (array[j] > temp)) //当first=0,j循环到-1时,由于[[短路求值]],不会运算array[-1]
    {
      array[j+1] = array[j];
      j--;
    }
    array[j+1] = temp; //被排序数放到正确的位置

  }
}


交换:冒泡、快速

冒泡:

void BubbleSort(char a[], int n)
{
  int i, j;
  char temp;
  for (i = 0; i < n; i++)
  {
    for (j = 1; j < n - i; j++)
    {
      if (a[j - 1] > a[j])
      {
        temp=a[j];
        a[j]=a[j+1];
        a[j+1]=temp;
      }
    }
  }
}


选择:直接选择、堆排序

选择排序:

void select_sort(char *a, int n)
{
  register int i, j, min, t;
  for(i = 0; i < n - 1; i ++)
  {
    min = i;
    //查找最小值
    for(j = i + 1; j < n; j ++)
    {
      if(a[min] > a[j])
      {
        min = j;
      }
      //交换
      if(min != i)
      {
        t = a[min];
        a[min] = a[i];
        a[i] = t;
      }
    }
  }
}

归并排序

const int n = 10;
int is1[n],is2[n];// 原数组is1,临时空间数组is2,n为个人指定长度

void merge(int low,int mid,int high)
{
 int i=low,j=mid+1,k=low;
 while(i<=mid&&j<=high)
 if(is1[i]<=is1[j]) // 此处为排序顺序的关键,用小于表示从小到大排序
 is2[k++]=is1[i++];
 else
 is2[k++]=is1[j++];
 while(i<=mid)
 is2[k++]=is1[i++];
 while(j<=high)
 is2[k++]=is1[j++];
 for(i=low;i<=high;i++)// 写回原数组
 is1[i]=is2[i];
}

void mergeSort(int a,int b)// 下标,例如数组int is[5],全部排序的调用为mergeSort(0,4)
{
 if(a<b)
 {
  int mid=(a+b)/2;
  mergeSort(a,mid);
  mergeSort(mid+1,b);
  merge(a,mid,b);
 }
}


基数排序

int data[10]={73,22,93,43,55,14,28,65,39,81};
int temp[10][10]={0};
int order[10]={0};
int i,j,k,n,lsd;
k=0;n=1;
printf("\n排序前: ");
for (i=0;i<10;i++) printf("%d ",data[i]);
putchar('\n');
while (n<=10){
for (i=0;i<10;i++){
lsd=((data[i]/n)%10);
temp[lsd][order[lsd]]=data[i];
order[lsd]++;
}
printf("\n重新排列: ");
for (i=0;i<10;i++){
if(order[i]!=0)
for (j=0;j<order[i];j++){
data[k]=temp[i][j];
printf("%d ",data[k]);
k++;
}
order[i]=0;
}
n*=10;
k=0;
}
putchar('\n');
printf("\n排序后: ");
for (i=0;i<10;i++) printf("%d ",data[i]);
②最短路径
计算一个节点到其他所有节点的最短路径:Dijkstra算法
算法是解决任意两点间的最短路径的一种算法:Floyd-Warshall算法
③贪心法
贪心算法解决部分背包问题
http://blog.sina.com.cn/s/blog_5cf6cbf80100fnrv.html
④动态规划
动态规划法之背包问题
http://blog.163.com/guixl_001/blog/static/41764104200863015855721/

五、数据库
①基本语句
数据库基本语句
http://wenku.baidu.com/view/f66f573067ec102de2bd893d.html
②常用聚合函数
MIN(),MAX(),COUNT(),AVG(),SUM()
③查询语句
数据库查询语句
http://wenku.baidu.com/view/ae344d2a915f804d2b16c1fd.html

六、操作系统
①线程和进程的区别
1、 线程是进程的一部分,所以线程有的时候被称为是轻权进程或者轻量级进程。
2、 一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个进程,进程的执行过程不是一条线(线程)的,而是多条线(线程)共同完成的。
3、 系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源。那就是说,出了CPU之外(线程在运行的时候要占用CPU资源),计算机内部的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。
4、 与进程的控制表PCB相似,线程也有自己的控制表TCB,但是TCB中所保存的线程状态比PCB表中少多了。
5、 进程是系统所有资源分配时候的一个基本单位,拥有一个完整的虚拟空间地址,并不依赖线程而独立存在。

②进程同步的方式
管道/FIFO/共享内存/消息队列/信号

③线程同步的方式
临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问
互斥量:为协调共同对一个共享资源的单独访问而设计的
信号量:为控制一个具有有限数量用户资源而设计
事件:用来通知线程有一些事件已发生,从而启动后继任务的开始

临界区、互斥区、事件、信号量四种方式
临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)的区别
1、临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。
2、互斥量:采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享
3、信号量:它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目
4、事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作

④进程间通讯的方式
管道:速度慢,容量有限
消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题。
信号量:不能传递复杂消息,只能用来同步
共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不过没这个必要,线程间本来就已经共享了一块内存的。

⑤死锁的四个必要条件
互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
循环等待条件(Circular wait):系统中若干进程组成环路,改环路中每个进程都在等待相邻进程正占用的资源。

⑥处理死锁的策略
忽略该问题。例如鸵鸟算法,该算法可以应用在极少发生死锁的的情况下。为什么叫鸵鸟算法呢,因为传说中鸵鸟看到危险就把头埋在地底下,可能鸵鸟觉得看不到危险也就没危险了吧。跟掩耳盗铃有点像;
检测死锁并且恢复;
仔细地对资源进行动态分配,以避免死锁;
通过破除死锁四个必要条件之一,来防止死锁产生;

七、计算机网络
①TCP和UDP
1。基于连接与无连接
2。对系统资源的要求(TCP较多,UDP少)
3。UDP程序结构较简单
4。流模式与数据报模式
5。TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证

②TCP/IP四层协议
网络接口层、网间网层、传输层、应用层

③OSI七层网络协议
OSI的7层从上到下分别是
7 应用层
6 表示层
5 会话层
4 传输层
3 网络层
2 数据链路层
1 物理层

④五种网络I/O
Unix网络编程中的的五种I/O模型
http://www.linuxidc.com/Linux/2012-08/66976.html

 

String 实现

class String

 

  {

 

  public:

 

  String(const char *str = NULL);// 普通构造函数

 

  String(const String &other); // 拷贝构造函数

 

  ~ String(void); // 析构函数

 

  String & operator =(const String &other);// 赋值函数

 

  private:

 

  char *m_data;// 用于保存字符串

 

  };

 

  请编写String的上述4个函数。

 

  //普通构造函数

 

  String::String(const char *str)

 

  {

 

  if(str==NULL)

 

  {

 

  m_data = new char[1]; // 对空字符串自动申请存放结束标志'\0'的//加分点:对m_data加NULL 判断

 

  *m_data = '\0';

 

  }

 

  else

 

  {

 

  int length = strlen(str);

 

  m_data = new char[length+1]; // 若能加 NULL 判断则更好

 

  strcpy(m_data, str);

 

  }

 

  }

 

  // String的析构函数

 

  String::~String(void)

 

  {

 

  delete[] m_data; // 或delete m_data;

 

  }

 

  //拷贝构造函数

 

  String::String(const String &other) // 输入参数为const型

 

  {

 

  int length = strlen(other.m_data);

 

  m_data = new char[length+1]; //对m_data加NULL 判断

 

  strcpy(m_data, other.m_data);

 

  }

 

  //赋值函数

 

  String & String::operator =(const String &other) // 输入参数为const

 

  型

 

  {

 

  if(this == &other) //检查自赋值

 

  return *this;

 

  delete[] m_data; //释放原有的内存资源

 

  int length = strlen( other.m_data );

 

  m_data = new char[length+1]; //对m_data加NULL 判断

 

  strcpy( m_data, other.m_data );

 

  return *this; //返回本对象的引用

 

  }

 
单链表反转
struct linka {
int data;
linka* next;
};

void reverse(linka*& head)
{
if(head ==NULL)
return;
linka*pre, *cur, *ne;
pre=head;
cur=head->next;
while(cur)
{
ne = cur->next;
cur->next = pre;
pre = cur;
cur = ne;
}
head->next = NULL;
head = pre;
}

查找字符串中连续最长的数字串

int continuemax(char *outputstr, char *inputstr)
{
    int maxLen = 0;
    char *pStart;
    char *maxStr;
    bool begin = true;
    int count = 0;
    while (*inputstr != '\0')
    {
        if (begin && isdigit(*inputstr))
        {
            pStart = inputstr;
            count++;
            begin = false;
        }
        else if (isdigit(*inputstr))
        {
            count++;
        }
        else
        {
            if (count > maxLen)
            {
                maxStr = pStart;
                maxLen = count;
            }
            count = 0;
            begin = true;
        }
        inputstr++;
        if (*inputstr == '\0' && count > maxLen)
        {
            maxStr = pStart;
            maxLen = count;
        }
    }
    *(maxStr + maxLen) = '\0';
    while(*maxStr != '\0')
    {
        *outputstr++ = *maxStr++;
    }
    *outputstr = '\0';
    return maxLen;
}



5、谈谈你对C++三个特点的理解(简单描述一下)。   
  答:c++三个特点是:   
  封装:把对象的属性和服务结合成一个独立的系统单位,并尽可能隐蔽对象的实现细节。   
  继承:特殊类的对象拥有一般类的全部属性和服务。   
  多态:不同的对象对相同界面的接口表现出不同的行为。   
  6、 为什么要封装,如何解释他的用意。   
  答:使对象和外界形成一个边界,这样做的好处是是对象的接口个数限制到最小,坏处是有时会使调用者难以理解该对象的功能。(这个缺点是我自己的观点,真正面试时最好别这么说,呵呵)   
  7、 多态的实现机制。   
  答:虚函数表和动态联编。   
  8、 纯虚函数的概念,有什么作用。   
  答:基类中要派生类必须只继承其接口且必须由派生类自己提供相应的实现的函数。其作用就是建立一个公共的接口。   
  9、 友元函数的优点和缺点。   
  优点或者说作用:提供了不同类的对象的成员函数之间、同一个类的成员函数与一般函数至尽进行数据共享的机制。   
  缺点:不利于程序的重用,且增加了函数之间、类之间的藕合度。   
  10、 TCP/IP中服务器端和客户端的实现流程。   
  答:   用三次握手法。其运行过程见计算机网络教材。内部实现机制我就不知道了,呵呵   
    
  11、 服务器端是如何处理客户端的连接请求。   
  答:见三次握手法中的第二步的说明   
  12、 线程与进程的区别   
  答:进程是程序在其数据集合上的一次运行。线程是一个进程内的基本调度单位。进程是资源分配的基本单位,也是强占处理机的调度单位,线程与资源分配无关。进程的调度与分配都由操作系统内核进行,线程的调度可由用户完成。   
  13、 进程间是如何通讯的(在Windows中)   
  答:不知道。   
  14、 线程的同步方式有哪几种?   
  答:线程的同步与进程相同有信号量、临界区、管程   
  15、 请写一条查询语句:(答:select   字段名   from   表名   where   条件语句     …)。   
    
  16、 数据库中的存储过程与一般的语句有什么不同,哪一个的执行速度快?为什么?   
  答:存储过程带有参数。存储过程创建后即被编译,执行速度比单个sql语句快的多。   
  17、 在团队合作过程中遇到哪些问题,是如何处理的。   
  答:一、各开发者的能力、经验学历不一样,导致开发效率不一   
          二、缺少一个技术权威,遇到技术问题时无现成经验可参考   
          三、开发队伍不稳定,辞职与被辞的现象时有发生,且预先无任何迹象。   
          四、没有一致的代码规范,导致代码无法进行快速的检查   
  Top

1、先讲一下做的项目;   
  答:答过了:-)   
  2、C和Java的主要区别;   
  答:不知道   
  3、进程和线程的区别,为什么要使用线程;   
  答:区别见前面的答案。引入线程的好处是在有多个任务需要处理机处理时,减少处理机的切换时间。另外使用线程可以简化程序的结构,提高执行效率。(前提是该程序有大量的进程调度和切换,如服务器中的文件管理系统、前后台的处理、异步处理)   
  4、TCP和UDP的区别;   
  答:tcp需要建立连接和确认、可靠但增加大量开销   
          udp不需要建立连接和确认、不可靠但开销少   
  5、TCP/IP的状态;   
  答:不知道。       
  6、存储过程和触发器;   
  答:存储过程是一系列SQL语句的集合。触发器是一种特殊的存储过程,都数据库系统在一定的触发条件下自动执行。   
  7、UINX常用命令;   
  答:ls、rmdir、cd、su、man、cp   
  8、为什么用虚析构函数;   
  答:析构函数的主要任务之一是向操作系统归还资源(内存),因此它必须确切知道被释放的对象的类型,否则就可能产生严重后果。因此析构函数经常被声明为虚函数,特别是在用一个基类指针指向派生类对象的情况下。(这段话是我从一本书抄的,我也没看明白它推理的过程,呵呵)   
  9、文档的重要性;   
  答:是开发、进度组织、代码量估算、代码编写等等的基础和审核标准   
  10、有关测试方面的一些内容;   
  答:我写过测试计划、测试用例、测试报告   
  11、构造函数和析构函数的执行顺序;   
  答:创建对象实例时执行构造函数,对象退出时执行析构函数。   
  12、UNIX中进程之间是如何通信的。   
  答:有低级通信、管道通信、进程间通讯。   
    

1.什么时候用虚析构函数,不使用会怎样。   
  答:答过了   
  2.继承时构造函数析构函数的调用顺序。   
  答:建立对象时先调用基类的构造函数,后调用派生类的构造函数   
          释放对象时先调用派生类的析构函数,后调用基类的析构函数   
  3.什么时候会出现内存泄露,如何防止。   
  答:程序向操作系统申请了内存而忘记在适当的时候归还,就是内存泄露。   
  防止办法:   
  动态内存的申请和释放必须配对,即用new的要delete。用malloc的要free。   
  4.select中的order   by   干什么用,group   by   干什么用,升序的关键字。   
  答:order   by指明按哪几列排序,group   by对查询结果进行分组,指明升序的关键字是ASC   
  5.数据库日志干什么用,数据库日志满的时候再查询数据库时会出现什么情况。   
  答:不知道   
  6.数据库中的三步提交。   
  答:见数据库教材   
  7.线程进程同步方式。   
  答:答过了   
  8.Unix下进程库的名称。   
  答:不知道   
  9.MFC下进程库的名称。   
  答:不知道   
  10.MFC中线程同步对象的名称。   
  答:不知道   
  11.switch   for   中定义的简单变量的生存周期。   
  答:到该复合语句的结束点   
  12.线程同步时如何得到另一个线程中CASE中的代码。   
  答:不知道   
  13.进程fork后用什么函数进行等待。   
  14.   fork函数的返回值各表示什么。   
  答:0:创建子进程,从子进程返回的ID值   
          >0:从父进程返回的子进程id值   
          -1:创建失败   
  15.socket   客户端、服务器端的处理流程。   
  答:不知道   
  16.TCP   UDP   的区别。   
  答:答过了   
  17.描述C++的三个特点。   
  答:答过了   
  18.STL中迭代器的名字,链表的迭代方法。   
  答:迭代器有五种:输入、输出、前向、双向、随机。链表用的是前向迭代器。   
  19.MFC中CString是类型安全类么?   
  答:不知道   
  20.C++中为什么用模板类。   
  答:为了支持泛型编程   
  21.CSingleLock是干什么的。   
  22.NEWTEXTMETRIC   是什么。   
  答:不知道   
  23.程序什么时候应该使用线程,什么时候单线程效率高。   
  24.Windows是内核级线程么。   
  答:不是   
  25.Linux有内核级线程么。   
  答:有   
  26.C++中什么数据分配在栈或堆中,New分配数据分配在近堆、远堆中。   
  27.使用线程是如何防止出现大的波峰。   
  答:不知道Top

5、谈谈你对C++三个特点的理解(简单描述一下)。   
  每个人都有不同的理解,C++的设计者,Java,C#的设计者的理解都不一样,看看他们设计的语言的差异都知道.   
  2、C和Java的主要区别;   
  一个是结构化的经典之作,一个是OO的简单作品   
  9.MFC下进程库的名称。   
  MFC就是一个类库,问题是不对的   
  23.程序什么时候应该使用线程,什么时候单线程效率高。   
  IO操作和CPU运算   
    
  进程间通讯   
  楼上的,20多种,都说出来看看   
  DDE建立在消息机制上,所以这种只能算一种,说出来开开眼界   
    
  20.C++中为什么用模板类。   
  为了提高开发效率   
    
  ...Top

15.socket   客户端、服务器端的处理流程。   
  一般情况:   
  服务器:                                   客户端:   
  socket();                             socket();   
  bind();   
  listen();     <<<<<<             connect();   
  accept();   
      .                                               .   
      .                                               .   
      .                                               .     
  close();                               close();Top

华为的试题,面试的,我觉得挺变态的   
    
  #include   "string.h"   
  char   *func(void)   
  {   
  char   p[10];strcpy(p,"123");   
  return   p;   
  }   
  问有没有问题。   
    
  我答,有问题,但我也不知道问题在哪里。但我估计是内存的问题。Top

玩一下,我顶,   
  5、谈谈你对C++三个特点的理解(简单描述一下)。   
  答复:特点就是C,+,   +,一共3个点。呵呵。   
  6、为什么要封装,如何解释他的用意。   
  答复:总有一些东西不能给人看,或者总有一些人想偷窥、破坏你的东西、而且这种人太多了,封装就是防止这些疯子。(其实疯子一般还是得逞了,每次我看完我被人改过的代码就有这个感觉。哈哈!)   
  7、多态的实现机制。   
  答复:基本是指针,负责的指针机制。   
  8、纯虚函数的概念,有什么作用。   
  答复:多态的最美妙的地方。OO最美妙的地方。   
  9、友元函数的优点和缺点。   
  答复:友元(不纯粹指函数)用好了是可以体现OO的美妙,比如ACE的SingleTon的用法,但是用差了就把OO变成魔鬼了。但是我的感觉中国的程序员不喜欢用友元,大部分人喜欢用public解决问题。   
  10、TCP/IP中服务器端和客户端的实现流程。   
  答复:监听,请求,接收,发送,接收............   
  11、服务器端是如何处理客户端的连接请求。   
  答复:........   To   or   Not   to   be     .....   
  12、线程与进程的区别   
  答复:就像兄弟,父子,等等等等。   
  13、进程间是如何通讯的(在Windows中)   
  答复:Socket,   消息,共享内存....   ....   
  14、线程的同步方式有哪几种?   
  答复:   
  15、请写一条查询语句:   
  答复:select   *   from   Table   where     星星撞地球   
  16、数据库中的存储过程与一般的语句有什么不同,哪一个的执行速度快?为什么?   
  答复:理论上应该是存储过程,因为毕竟是在数据的操作进程中运行,减少交互成本。但绝对吗。这要看很多东西。   
    
  Top

  1、先讲一下做的项目;   
  答复:呵呵............   
  2、C和Java的主要区别;   
  答复:一个是C,一个是Java,这就是本质的区别。   
  3、进程和线程的区别,为什么要使用线程;   
  答复:可以是说线程是进程的子集。在某些时候使用线程可以提高处理能力和速度。   
  4、TCP和UDP的区别;   
  答复:是否存在虚连接,是否保证传递数据性,时序是否能保证。   
  5、TCP/IP的状态;   
  答复:不知道,   
  6、存储过程和触发器;   
  数据库的两个宝宝,存储过程用于代替一组SQL过程的处理(可以高效,动态),触发器就是在某个事件时触发处理。可以用于保证数据的完整性等。   
  7、UINX常用命令;   
  ls,cd,最常用的两个。   
  8、为什么用虚析构函数;   
  答复:让程序的架构更美丽。而且C++提供了。   
  9、文档的重要性;   
  答复:让你知道文档和程序间有多大差距,而且让一部分统计人员有事情。   
  10、有关测试方面的一些内容;   
  答复:让你知道自己犯了多少错的事情。   
  11、构造函数和析构函数的执行顺序;   
  答复,一般来说,构造函数函数先执行。   ^_^。   
  12、UNIX中进程之间是如何通信的。   
  答复:Socket,消息,管道,信号等。

 
posted @ 2012-11-04 18:53  全绍辉  阅读(364)  评论(0编辑  收藏  举报