学习笔记问题大全【整理】2

问:C语言中结构化程序设计的三种基本控制结构
 顺序结构
选择结构
循环结构
问:什么是预编译,何时需要预编译?
预编译又称为预处理,是做些代码文本的替换工作。处理#开头的指令,比如拷贝#include包含的文件代码,#define宏定义的替换,条件编译等,就是为编译做的预备工作的阶段,主要处理#开始的预编译指令,预编译指令指示了在程序正式编译前就由编译器进行的操作,可以放在程序中的任何位置。
c编译系统在对程序进行通常的编译之前,先进行预处理。c提供的预处理功能主要有以下三种:1)宏定义 2)文件包含 3)条件编译
1、总是使用不经常改动的大型代码体。
2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。
问:什么是预编译
何时需要预编译:
1、总是使用不经常改动的大型代码体。
2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

问:何时需要预编译。(跟上一题,是同一个问题)

总是使用不经常改动的大型代码体。?
程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

问:简述Debug版本和Release版本的区别?
Debug版本是调试版本,Release版本是发布给用户的最终非调试的版本,

问: 处理器标识#error的目的是什么?
答:编译时输出一条错误信息,并中止继续编译。
问:预处理器标识#error的目的是什么?(跟上一题,是同一个问题)
 如果你不知道答案,请看参考文献1。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会读C语言课本的附录去找出象这种问题的答案。当然如果你不是在找一个书呆子,那么应试者最好希望自己不要知道答案。

问:extern“C”有什么作用?(即在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”?)
参考答案1:C++语言支持函数重载,C 语言不支持函数重载。函数被C++编译后在库中的名字与C 语言的不同。假设某个函数的原型为: void foo(int x, int y);该函数被C 编译器编译后在库中的名字为_foo , 而C++编译器则会产生像_foo_int_int 之类的名字。C++提供了C 连接交换指定符号extern“C”来解决名字匹配问题。
参考答案2:?
extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren “c”后,C++就能直接调用C函数了。
extern “C”主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。

问:描述实时系统的基本特性
答 、在特定时间内完成特定的任务,实时性与可靠性。
问:设计模式:工厂模式 和 单例模式 介绍一下?
工程模式即将对象创建过程封装即为工厂模式。
单例模式即整个类只有一个对象,并且不允许显示创建。
问:三种基本的数据模型
 按照数据结构类型的不同,将数据模型划分为层次模型、网状模型和关系模型。
问:关系模型的基本概念
 关系数据库以关系模型为基础,它有以下三部分组成:
    ●数据结构——模型所操作的对象、类型的集合
    ●完整性规则——保证数据有效、正确的约束条件
    ●数据操作——对模型对象所允许执行的操作方式
    关系(Relation)是一个由行和列组成的二维表格,表中的每一行是一条记录(Record),每一列是记录的一个字段(Field)。表中的每一条记录必须是互斥的,字段的值必须具有原子性。
问:CVS是什么
 cvs(Concurrent Version System) 是一个版本控制系统。使用它,可以记录下你的源文件的历史。
例如,修改软件时可能会不知不觉混进一些 bug,而且可能过了很久你才会察觉到它们的存在。有了 cvs,你可以很容易地恢复旧版本,并从中看出到底是哪个修改导致了这个 bug。有时这是很有用的。
CVS服务器端对每个文件维护着一个修订号,每次对文件的更新,都会使得文件的修订号加1。在客户端中也对每个文件维护着一个修订号,CVS通过这两个修订号的关系,来进行Update,Commit和发现冲突等操作操作。
问:动态连接库的两种方式?
答:调用一个DLL中的函数有两种方法:
1.载入时动态链接(load-time dynamic linking),模块非常明确调用某个导出函数
,使得他们就像本地函数一样。这需要链接时链接那些函数所在DLL的导入库,导入库向
系统提供了载入DLL时所需的信息及DLL函数定位。
2.运行时动态链接(run-time dynamic linking),运行时可以通过LoadLibrary或Loa
dLibraryEx函数载入DLL。DLL载入后,模块可以通过调用GetProcAddress获取DLL函数的
出口地址,然后就可以通过返回的函数指针调用DLL函数了。如此即可避免导入库文件了

————————
————————
关于结构和算法

问:什么是平衡二叉树?
答:左右子树都是平衡二叉树,而且左右子树的深度差值的约对值不大于1
问:队列和栈有什么区别?
    队列先进先出,栈后进先出
问:求出两个数中的较大这
There are two int variables: a and b, don’t use “if”, “? :”, “switch”or other judgement statements, find out the biggest one of the two numbers.
答案:( ( a + b ) + abs( a - b ) ) / 2
问:插入排序和选择排序
插入排序基本思想:(假定从大到小排序)依次从后面拿一个数和前面已经排好序的数进行比较,比较的过程是从已经排好序的数中最后一个数开始比较,如果比这个数,继续往前面比较,直到找到比它大的数,然后就放在它的后面,如果一直没有找到,肯定这个数已经比较到了第一个数,那就放到第一个数的前面。那么一般情况下,对于采用插入排序法去排序的一组数,可以先选 取第一个数做为已经排好序的一组数。然后把第二个放到正确位置。
选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。
问:冒泡排序算法的时间复杂度是什么?
      时间复杂度是O(n^2)。
问:写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。
KMP算法效率最好,时间复杂度是O(n+m),
问:用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。
     循环链表,用取余操作做
问:一道算法题:
有两个字符串数组: string src[]  和string des[] ,每个字符串数组的长度都是10W跳左右,每个字符的 size<1KB ,设计一个算法 查找 两个字符串数组中想交的字符串。
解析方法:
分析 10W = 2^20 1KB*10W*2 = 2GB ,当今的内存中正好可以容下这么多数据,算法设计
(1)遍历字符串数组src,构造一个 tiretree(字典数),然后遍历字符串数组des遇到已经存储过的相同的结构则输出。
(2)设计一个hash,关键是哈希算法的设计,因为这是一个字符串数组,每个字符都是有范围的(0~25),我们可以字符串数组中的每个字符串看成一个26进制的数,将其转化为10进制,这样就可以得到一个唯一的key值,对于字符串太长的情况下,我们可以将这个字符串对10万取模,对10万取模后,我们并不能保证这个key唯一,这样我们就需要key值冲突处理,参考以下四种处理方式:http://blog.csdn.net/leo115/article/details/8052353
说明:同样可以直接使用string类型的字符串作为 hash key,每个string的ASCII码是不同的,所以具有唯一性,故可以直接作为 hash key。
问:一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?
将这个指针指向的next节点值copy到本节点,将next指向next->next,并随后删除原next指向的节点。
问:关联、聚合(Aggregation)以及组合(Composition)的区别?
涉及到UML中的一些概念:关联是表示两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;聚合表示has-a的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,如下图所示,用空的菱形表示聚合关系:从实现的角度讲,聚合可以表示为:
class A {...}  class B { A* a; .....}
而组合表示contains-a的关系,关联性强于聚合:组合类与被组合类有相同的生命周期,组合类要对被组合类负责,采用实心的菱形表示组合关系:实现的形式是:class A{...} class B{ A a; ...}

————————
————————
关于内存分配 内存管理
问:解释堆和栈的区别?
栈区(stack)— ? 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。

问:堆栈溢出一般是由什么原因导致的?
答 、堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界,结果覆盖了老的堆栈数据。
我认为堆栈溢出最重要的原因是我们编写的程序有问题。C++中堆栈溢出一般原因:
1、没有回收垃圾资源
2、层次太深的递归调用
3、变量访问越界

问:C++中什么数据分配在栈或堆中,New分配数据是在近堆还是远堆中?
答:栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理
堆: 程序运行时动态申请,new 和 malloc申请的内存就在堆上

问:内存的分配方式
分配方式有三种,
1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。
2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。
3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存。
问:描述内存分配方式以及它们的区别?
1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。
3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
问:C++中什么数据分配在栈或堆中?
答:栈: 存放局部变量,函数调用参数,函数返回值,函数返回地址。由系统管理
堆: 程序运行时动态申请,new 和malloc申请的内存就在堆上
问:C++中用指针是否需要Delete?
是否需要对指针delete取决于指针指向的内存是否是用new操作符申请的。 用了new表示动态分配了内存,需要用delete将内存还给系统。
?凡是使用new申请的内存,系统都不会自动释放的,都需要你手动delete,如果申请的是数组,也就是new [] ,就需要对用的手动delete[] .
不论在哪里,都需要,不分局部还是全局。
问:new、delete、malloc、free关系
delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数。malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。

问:New delete 与malloc free 的联系与区别?
答案:都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象,new 会自动调用对象的构造函数。delete 会调用对象的destructor,而free 不会调用对象的destructor.
realloc free的区别
void* realloc(void* ptr, unsigned newsize);
realloc是给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度 如: char* p; p=(char*)malloc(sizeof(char)*20); p=(char*)realloc(p,sizeof(char)*40); 注意,这里的空间长度都是以字节为单位。
free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。
http://www.cnblogs.com/BlueTzar/articles/1136549.html

问:多重继承的内存分配问题:
比如有class A : public class B, public class C {} 那么A的内存结构大致是怎么样的?
这个是compiler-dependent的, 不同的实现其细节可能不同。如果不考虑有虚函数、虚继承的话就相当简单;否则的话,相当复杂。可以参考《深入探索C++对象模型
问:CMemoryState主要功能是什么
答案:查看内存使用情况,解决内存泄露问题。
问:对内存操作的考查主要集中在:
  (1)指针的理解;
  (2)变量的生存期及作用范围;
  (3)良好的动态内存申请和释放习惯。
  再看看下面的一段程序有什么错误:  
以下是引用片段:
swap( int* p1,int* p2 )
  {
  int *p;
  *p = *p1;
  *p1 = *p2;
  *p2 = *p;
  }
  在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为
以下是引用片段:
swap( int* p1,int* p2 )
  {
  int p;
  p = *p1;
  *p1 = *p2;
  *p2 = p;
  }
问:分析下面的程序:
void GetMemory(char **p,int num)
{
    *p=(char *)malloc(num);
   
}       
int main()
{
    char *str=NULL;
   
    GetMemory(&str,100);
   
    strcpy(str,"hello");
   
    free(str);
   
    if(str!=NULL)
    {
        strcpy(str,"world");
    }   
       
    printf("/n str is %s",str);
    getchar();
}   
问输出结果是什么?希望大家能说说原因,先谢谢了
输出str is world。
free 只是释放的str指向的内存空间,它本身的值还是存在的.
所以free之后,有一个好的习惯就是将str=NULL.
此时str指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,
尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚了),但是通常会打印出world来。
这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。
当你malloc一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存前面一点),并将可用内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的,只不过。。。。。。。。楼上都说过了,最好别这么干。
问:Heap与stack的差别。
Heap是堆,stack是栈。
Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。
Stack空间有限,Heap是很大的自由存储区
C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。
程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行
问:死锁的4个必要条件:
4.1、互斥使用(资源独占)  一个资源每次只能给一个进程使用 4.2、不可强占(不可剥夺)     资源申请者不能强行的从资源占有者手中夺取资源,资源只能由占有者自愿释放 4.3、请求和保持(部分分配,占有申请) 一个进程在申请新的资源的同时保持对原有资源的占有(只有这样才是动态申请,动态分配) 4.4、循环等待 存在一个进程等待队列     {P1 , P2 , … , Pn},     其中P1等待P2占有的资源,P2等待P3占有的资源,…,Pn等待P1占有的资源,形成一个进程等待环路。
问:嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
这一问题测试你是否知道为了访问一绝对地址把一个整型数强制转换(typecast)为一指针是合法的。这一问题的实现方式随着个人风格不同而不同。典型的类似代码如下:
    int *ptr;
    ptr = (int *)0x67a9;
    *ptr = 0xaa55;


 A more obscure approach is:
一个较晦涩的方法是:


    *(int * const)(0x67a9) = 0xaa55;


即使你的品味更接近第二种方案,但我建议你在面试时使用第一种方案。
问:关于动态内存分配(Dynamic memory allocation)。尽管不像非嵌入式计算机那么常见,嵌入式系统还是有从堆(heap)中动态分配内存的过程的。那么嵌入式系统中,动态分配内存可能发生的问题是什么?
这里,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时间等等。这个主题已经在ESP杂志中被广泛地讨论过了(主要是 P.J. Plauger, 他的解释远远超过我这里能提到的任何解释),所有回过头看一下这些杂志吧!让应试者进入一种虚假的安全感觉后,我拿出这么一个小节目:
下面的代码片段的输出是什么,为什么?
char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
    puts("Got a null pointer");
else
    puts("Got a valid pointer");
这是一个有趣的问题。最近在我的一个同事不经意把0值传给了函数malloc,得到了一个合法的指针之后,我才想到这个问题。这就是上面的代码,该代码的输出是"Got a valid pointer"。我用这个来开始讨论这样的一问题,看看被面试者是否想到库例程这样做是正确。得到正确的答案固然重要,但解决问题的方法和你做决定的基本原理更重要些。
Typedef

问:char szstr[10];
  strcpy(szstr,"0123456789");
  产生什么结果?为什么?
  长度不一样,会造成非法的OS

问:关于内存对齐的问题以及sizof()的输出
答:编译器自动对齐的原因:为了提高程序的性能,数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;然而,对齐的内存访问仅需要一次访问。

————————
————————
关于数据库
问:对数据库的一张表进行操作,同时要对另一张表进行操作,如何实现?
答:将操作多个表的操作放入到事务中进行处理

问:一般数据库若出现日志满了,会出现什么情况,是否还能使用?
答:只能执行查询等读操作,不能执行更改,备份等写操作,原因是任何写操作都要记录日志。也就是说基本上处于不能使用的状态。
问:如果数据库满了会出现什么情况,是否还能使用?
答:见上一题

问:SQL Server是否支持行级锁,有什么好处?
答:支持,设立封锁机制主要是为了对并发操作进行控制,对干扰进行封锁,保证数据
的一致性和准确性,行级封锁确保在用户取得被更新的行到该行进行更新这段时间内不
被其它用户所修改。因而行级锁即可保证数据的一致性又能提高数据操作的迸发性。
问:数据库与T-SQL语言   
关系数据库是表的集合,它是由一个或多个关系模式定义。SQL语言中的数据定义功能包括对数据库、基本表、视图、索引的定义。
问:SQL语言概述
    SQL(结构化查询语言)是关系数据库语言的一种国际标准,它是一种非过程化的语言。通过编写SQL,我们可以实现对关系数据库的全部操作。
    ●数据定义语言(DDL)——建立和管理数据库对象
    ●数据操纵语言(DML)——用来查询与更新数据
    ●数据控制语言(DCL)——控制数据的安全性
起来是一个很简单的问题,每一个使用过RDBMS的人都会有一个概念。
事务处理系统的典型特点是具备ACID特征。ACID指的是Atomic(原子的)、Consistent(一致的)、Isolated(隔离的)以及Durable(持续的),它们代表着事务处理应该具备的四个特征:
原子性:组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分
一致性:在事务处理执行之前和之后,数据是一致的。
隔离性:一个事务处理对另一个事务处理没有影响。
持续性:当事务处理成功执行到结束的时候,其效果在数据库中被永久纪录下来。

问:触发器怎么工作的?
答:触发器主要是通过事件进行触发而被执行的,当对某一表进行诸如UPDATE、 INSERT、 DELETE 这些操作时,数据库就会自动执行触发器所定义的SQL 语句,从而确保对数据的处理必须符合由这些SQL 语句所定义的规则。

 

————————
————————
关于线程 进程  socket  TCP/IP协议
问:程序什么时候应该使用线程,什么时候单线程效率高。
答:1.耗时的操作使用线程,提高应用程序响应
2.并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。
3.多CPU系统中,使用线程提高CPU利用率
4.改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独
立的运行部分,这样的程序会利于理解和修改。
其他情况都使用单线程。
问:进程和线程的区别
什么是进程(Process):普通的解释就是,进程是程序的一次执行,而什么是线程(Thread),线程可以理解为进程中的执行的一段程序片段。在一个多任务环境中下面的概念可以帮助我们理解两者间的差别:
进程间是独立的,这表现在内存空间,上下文环境;线程运行在进程空间内。 一般来讲(不使用特殊技术)进程是无法突破进程边界存取其他进程内的存储空间;而线程由于处于进程空间内,所以同一进程所产生的线程共享同一内存空间。 同一进程中的两段代码不能够同时执行,除非引入线程。线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除。线程占用的资源要少于进程所占用的资源。 进程和线程都可以有优先级。在线程系统中进程也是一个线程。可以将进程理解为一个程序的第一个线程。
线程是指进程内的一个执行单元,也是进程内的可调度实体.与进程的区别:
(1)地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;
(2)进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源
(3)线程是处理器调度的基本单位,但进程不是.
(4)二者均可并发执行.
问:进程和线程的差别。(跟上一题,是同一个问题)
线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。
问: 什么是UDP和TCP的区别是什么?
TCP的全称为传输控制协议。这种协议可以提供面向连接的、可靠的、点到点的通信。
UDP全称为用户报文协议,它可以提供非连接的不可靠的点到多点的通信。
用TCP还是UDP,那要看你的程序注重哪一个方面?可靠还是快速?
问:进程间通信类型:
参考答案1:
(1)环境变量、文件描述符 一般Unix环境下的父进程执行fork(),生成的子进程拥有了父进程当前设置的环境变量以及文件描述符;由于通信是一个单向的、一次性的通信,随后的父进程以及子进程后续的内容不能再能共享;
(2)命令行参数 大多数用户都使用过ShellExec相关的命令,此API可以打开新的进程,并可以通过接口里的输入参数进行信息共享;同样,他也是一个单项、一次性的通信;
(3)管道 使用文件和写方式访问公用的数据结构;管道分为匿名管道和命名管道,前者是用作关联进程间用,后者为无关联的进程使用;前者通过文件描述符或文件句柄提供对命名管道的访问,后者需要知道管道名称才能读写管道;一般来讲,读写的内容是字节流,需要转换为有意义的结构才有意义;
(4)共享内存 进程需要可以被其他进程访问浏览的进程块;进程间共享内存的关系与函数间共享全局变量的关系类似
(5)DDE 动态数据交互
参考答案2:
(1)全局数据;
(2)全局变量;
(3)全局数据结构;
(4)线程间通信的参数:pThread_create这类API接口中的参数
问:winsock建立连接的主要实现步骤?
答:
服务器端:socket()建立套接字,绑定(bind)并监听(listen),用accept()等待客户端连接, accept()发现有客户端连接,建立一个新的套接字,自身重新开始等待连接。该新产生的套接字使用send()和recv()写读数据,直至数据交换完毕,closesocket()关闭套接字。
客户端:socket()建立套接字,连接(connect)服务器,连接上后使用send()和recv(),在套接字上写读数据,直至数据交换完毕,closesocket()关闭套接字。
问:网络编程中设计并发服务器,使用多进程 与 多线程 ,请问有什么区别?
1,进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。
2,线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。
两者都可以提高程序的并发度,提高程序运行效率和响应时间。
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。
问:CSingleLock是干什么的。
答:同步多个线程对一个数据类的同时访问
问:使用线程是如何防止出现大的波峰。
答:意思是如何防止同时产生大量的线程,方法是使用线程池,线程池具有可以同时提
高调度效率和限制资源使用的好处,线程池中的线程达到最大数时,其他线程就会排队
等候。
问: 进程间主要的通讯方式?
信号量,管道,消息,共享内存
问:IP地址的编码分为哪俩部分?
答 IP地址由两部分组成,网络号和主机号。(过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。)
问:用什么函数开启新进程、线程。
答案:
线程:CreateThread/AfxBeginThread等
进程:CreateProcess等
问:SendMessage和PostMessage有什么区别
答案:SendMessage是阻塞的,等消息被处理后,代码才能走到SendMessage的下一行。PostMessage是非阻塞的,不管消息是否已被处理,代码马上走到PostMessage的下一行。
问:多线程编程的优点?
(1) 响应度高;比如说一个交互式的程序,比如说QQ视频聊天时,视频传输很明显是耗时的,而且很多时候都会出现视频卡的现象,这个时候假如说我们采用多线编程,当一个视频阻塞的时候,当前这个程序仍能运行,我们仍然通过另外一些线程可以 打字,语音等。
(2) 资源共享,线程默认共享当前进程内的内存和资源。这种共享的优点是 允许同一进程,同一地址空间 存在多个线程
(3)经济,系统开销小;创建进程是要系统分配资源的,回收进程是要回收资源的,这个过程比较耗时,而创建线程则相对来说快速的多。
(4)充分利用处理器资源;现在的处理器一般为多核的,当有多个线程的时候,同一时刻,每个核都能在工作,并行的工作;但是假如说的单线程的话,只能运行在一个核上,相对来说,另外一个核就浪费了,所以使用多线程能充分利用CPU的资源,加快程序执行的速率。
问:进程中都有什么?
在操作系统中,进程是由一个进程控制块来管理 和 存放进程的一些信息的,每个进程均有一个进程控制块,在进程创建的时候,创建一个进程控制块,并伴随着进程运行的全过程,知道进程撤销回收。
不同的操作系统 Linux / Window 中进程控制块内的信息基本上是一样的:
(1) 进程ID,唯一标识一个进程
(2)进程状态 status ,进程是动态的,有五种状态 : 开始 就绪 运行 阻塞 终止
(3)程序代码段
(4)数据段
(5)进程的资源清单 。 进程用于的I/O 文件等
(6)进程优先级
(7)进程同步 与 通信的方式
(8)家族关系, 父进程 子进程
(9)CPU现场
参考:http://oa.gdut.edu.cn/os/multimedia/oscai/chapter2/pages/ch22.htm
为了进程控制块的管理,常将进程控制块组织起来,组织方式有两种:链式和索引式,便于查询和管理
问:进程和线程之间的区别?什么是“线程安全”?
简单的介绍:进程是动态运行的程序的实例,是操作系统分配资源的基本单位,每一个进程都是一个实体,都有自己的地址空间,(包括:文本区域,数据区域,堆栈),进程是运行中的程序。线程是 进程中某单一顺序的控制流,也被称为轻量级进程,是运行中的程序的调度的基本单位,说明:单一顺序的控制流,每个独立的线程都有一个程序的入口、运行队列和程序的出口。但是线程不能独立的执行,必须存在应用程序中,由应用程序提供多个线程执行控制。
(0)一个程序至少拥有一个进程(通过fork创建进程),一个进程至少拥有一个线程(必有一个主线程)。
(1) 从调度方面考虑,线程是作为调度和分配的基本单位,进程是作为拥有资源的基本单位,线程是CPU和内存的真正的使用者
(2)并发性方面考虑:不仅相同进程中的线程可以并发,不同进程中线程之间也是可以并发的;同时进程与进程之间也是可以并发的
(3)拥有资源:进程拥有自己独立的地址空间,而线程不拥有系统资源,但是可以访问所在的进程的资源。
(4)系统开销方面:在创建和撤销进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建和撤销线程时的开销。
接着解释第二个问题 什么是“线程安全”?
(1)如果程序代码所在的进程中有多个线程在同时运行,这些线程可能会同时运行这段代码,如果每次运行的结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的一样,就是线程安全的。
(2)或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口执行的结果产生二义性,也就是说我们不用考虑同步问题,这个时候线程是安全的。
(3)线程安全问题往往是由全局变量及静态变量引起的。
(4)一般来说若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量的线程是安全的;若有多个线程同时执行写操作,一般要考虑线程同步问题,线程同步的解决办法一般是:临界区、信号量、互斥锁等
 
问:11月3号青牛软件面试
青牛软件的一面就是聊项目,没有做题,然后遇到下面的一个问题:
操作系统中 什么是临界区?什么是临界资源? 举例说明!
答:操作系统中对临界区的定义是这样的:每个进程中访问临界资源的那段程序称为临界区。临界资源的定义是:临界资源可以由多个进程所共享,但是一次仅能由一个进程访问的共享资源。 临界区要求每次只准许一个进程进入临界区,占时拥有临界资源;
临界资源的举例:打印机,磁盘等, 一个全局变量可以允许多个进程访问,所以全局变量不是临界资源。
问:TCP/IP 建立连接的过程(3-way shake)
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到客户端连接请求,向客户端发送允许连接应答,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的允许连接应答,向服务器发送确认,客户端和服务器进入通信状态,完成三次握手

问:TCP/IP 建立连接的过程?(3-way shake) 即跟上一问题相同
答:在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
  第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状
态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个
SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)
,此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

问:ICMP是什么协议,处于哪一层?
答:Internet控制报文协议,处于网络层(IP层)

问:IP组播有那些好处?
答:Internet上产生的许多新的应用,特别是高带宽的多媒体应用,带来了带宽的急剧
消耗和网络拥挤问题。组播是一种允许一个或多个发送者(组播源)发送单一的数据包
到多个接收者(一次的,同时的)的网络技术。组播可以大大的节省网络带宽,因为无
论有多少个目标地址,在整个网络的任何一条链路上只传送单一的数据包。所以说组播
技术的核心就是针对如何节约网络资源的前提下保证服务质量。
问:ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点?
应用层
表示层
会话层
运输层
网络层
物理链路层
物理层
tcp /udp属于运输层
TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。
与 TCP 不同, UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单, UDP 头包含很少的字节,比 TCP 负载消耗少。
tcp: 提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好
udp: 不提供稳定的服务,包头小,开销小  

面试题: 线程与进程的区别和联系? 线程是否具有相同的堆栈? dll是否有独立的堆栈?
进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。


每个线程有自己的堆栈。
DLL中有没有独立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为DLL中的代码是被某些线程所执行,只有线程拥有堆栈,如果DLL中的代码是EXE中的线程所调用,那么这个时候是不是说这个DLL没有自己独立的堆栈?如果DLL中的代码是由DLL自己创建的线程所执行,那么是不是说DLL有独立的堆栈?


以上讲的是堆栈,如果对于堆来说,每个DLL有自己的堆,所以如果是从DLL中动态分配的内存,最好是从DLL中删除,如果你从DLL中分配内存,然后在EXE中,或者另外一个DLL中删除,很有可能导致程序崩溃

问:Internet物理地址和IP地址转换采用什么协议?
      ARP (Address Resolution Protocol)(地址解析協議)

问:Internet采用哪种网络协议?该协议的主要层次结构?
      Tcp/Ip协议
      主要层次结构为: 应用层/传输层/网络层/数据链路层/物理层。
问:请你分别画出OSI的七层网络结构图和TCP/IP的五层结构图。
应用层:为应用程序提供服务
表示层:处理在两个通信系统中交换信息的表示方式
会话层:负责维护两个结点间会话连接的建立、管理和终止,以及数据交换
传输层:向用户提供可靠的端到端服务。UDP TCP协议。
网络层:通过路由选择算法为分组通过通信子网选择最适当的路径,以及实现拥塞控制、网络互联等功能。数据传输单元是分组。IP地址,路由器,IP协议。
数据链路层:在物理层提供的服务基础上,数据链路层在通信的实体间建立数据链路连接,传输一帧为单位的数据包(,并采用差错控制与流量控制方法,使有差错的物理线路变成无差错的数据链路。)
物理层:传输比特流。传输单元是比特。调制解调器。
问:请问交换机和路由器各自的实现原理是什么?分别在哪个层次上面实现的?
交换机:数据链路层。路由器:网络层。
——————————————
————————————
关于调试 错误查找 测试
问:assert()的作用?
ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。

问:测试方法
人工测试:个人复查、抽查和会审
机器测试:黑盒测试和白盒测试

————————
————————
关于MFC  Window
问: windows消息系统由哪几部分构成?
由一下3部分组成:
1.        消息队列:操作系统负责为进程维护一个消息队列,程序运行时不断从该消息队列中获取消息、处理消息;
2.        消息循环:应用程序通过消息循环不断获取消息、处理消息。
3.        消息处理:消息循环负责将消息派发到相关的窗口上使用关联的窗口过程函数进行处理。

问:MFC中CString是类型安全类么?
答:不是,其它数据类型转换到CString可以使用CString的成员函数Format来转换
问:NEWTEXTMETRIC是什么。
答:物理字体结构,用来设置字体的高宽大小
问:MFC中,大部分类是从哪个类继承而来?        CObject
问: 什么是消息映射?
消息映射就是让程序员指定MFC类(有消息处理能力的类)处理某个消息。然后由程序员完成对该处理函数的编写,以实现消息处理功能。
问: 构成Win32 API 函数的三个动态链接库是什么?
答:内核库,用户界面管理库,图形设备界面库。
问:创建一个窗口的步骤是?
答:填充一个窗口类结构->注册这个窗口类->然后再创建窗口->显示窗口->更新窗口。
问: 模态对话框和非模态对话框有什么区别?
答:1.调用规则不同:前者是用DoModal()调用,后者通过属性和ShowWindow()来显示。
2.模态对话框在没有关闭前用户不能进行其他操作,而非模态对话框可以。
3.非模态对话框创建时必须编写自己的共有构造函数,还要调用Create()函数。
问: windows消息分为几类?并对各类做简单描述。
1.窗口消息:与窗口相关的消息,除WM_COMMAND之外的所有以WM_开头的消息;
2.命令消息;用于处理用户请求,以WM_COMMAND表示的消息;
3.控件通知消息:统一由WM_NOTIFT表示,
4.用户自定义消息。
问:如何自定义消息?
使用WM_USER 和WM_APP两个宏来自定义消息,

问: 简述Visual C++ 、Win32 API和MFC之间的关系?
(1)        Visual C+是一个以C++程序设计语言为基础的、集成的、可视化的编程环境;
(2)        Win32 API是32位Windows操作系以C/C++形式提供的一组应用程序接口;
(3)        MFC是对Win32 API的封装,简化了开发过程。
问:Windows是内核级线程么。
答:见下一题

问:Linux有内核级线程么。
答:线程通常被定义为一个进程中代码的不同执行路线。从实现方式上划分,线程有两
种类型:“用户级线程”和“内核级线程”。 用户线程指不需要内核支持而在用户程序
中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度
和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统中也可实现
,但线程的调度需要用户程序完成,这有些类似 Windows 3.x 的协作式多任务。另外一
种则需要内核的参与,由内核完成线程的调度。其依赖于操作系统核心,由内核的内部
需求进行创建和撤销,这两种模型各有其好处和缺点。用户线程不需要额外的内核开支
,并且用户态线程的实现方式可以被定制或修改以适应特殊应用的要求,但是当一个线
程因 I/O 而处于等待状态时,整个进程就会被调度程序切换为等待状态,其他线程得不
到运行的机会;而内核线程则没有各个限制,有利于发挥多处理器的并发优势,但却占
用了更多的系统开支。
Windows NT和OS/2支持内核线程。Linux 支持内核级的多线程

————————
————————
关于其他

问:从EDIT框中取出数据给关联的变量,已经把关联的变量的数据显示在EDIT框上的函数是什么?
答: UpdateData(TRUE),  Updatedata(FALSE).
问:简单介绍GDI?
答;GDI是Graphics Device Interface 的缩写,译为:图形设备接口;是一个在Windows应用程序中执行与设备无关的函数库,这些函数在不同的输出设备上产生图形以及文字输出。
问:在8086 汇编下,逻辑地址和物理地址是怎样转换的?(Intel)
答案:通用寄存器给出的地址,是段内偏移地址,相应段寄存器地址*10H+通用寄存器内地址,就得到了真正要访问的地址。
问:Ado与Ado.net的相同与不同?
除了“能够让应用程序处理存储于DBMS 中的数据“这一基本相似点外,两者没有太多共同之处。但是Ado使用OLE DB 接口并基于微软的COM 技术,而ADO.NET 拥有自己的ADO.NET 接口并且基于微软的.NET 体系架构。众所周知.NET 体系不同于COM 体系,ADO.NET 接口也就完全不同于ADO和OLE DB 接口,这也就是说ADO.NET 和ADO是两种数据访问方式。ADO.net 提供对XML 的支持。
问:有哪几种情况只能用intialization list 而不能用assignment?
答案:当类中含有const、reference 成员变量;基类的构造函数都需要初始化表。
问:8086是多少位的系统?在数据总线上是怎么实现的?
8086微处理器共有4个16位的段寄存器,在寻址内存单元时,用它们直接或间接地存放段地址。
  代码段寄存器CS:存放当前执行的程序的段地址。
  数据段寄存器DS:存放当前执行的程序所用操作数的段地址。
 堆栈段寄存器SS:存放当前执行的程序所用堆栈的段地址。
附加段寄存器ES:存放当前执行程序中一个辅助数据段的段地址。
由cs:ip构成指令地址,ss:sp构成堆栈的栈顶地址指针。DS和ES用作数据段和附加段的段地址(段起始地址或段值)
问:8086/8088微处理器的存储器管理 (跟上一题相似 相关)
   1.地址线(码)与寻址范围:N条地址线     寻址范围=2N
   2.8086有20地址线     寻址范围为1MB  由 00000H~FFFFFH
   3. 8086微处理器是一个16位结构,用户可用的寄存器均为16位:寻址64KB
   4. 8086/8088采用分段的方法对存储器进行管理。具体做法是:把1MB的存储器空间分成若干段,每段容量为64KB,每段存储器的起始地址必须是一个能被16整除的地址码,即在20位的二进制地址码中最低4位必须是“0”。每个段首地址的高16位二进制代码就是该段的段号(称段基地址)或简称段地址,段号保存在段寄存器中。我们可对段寄存器设置不同的值来使微处理器的存储器访问指向不同的段。
   5.段内的某个存储单元相对于该段段首地址的差值,称为段内偏移地址(也叫偏移量)用16位二进制代码表示。

   6.物理地址是由8086/8088芯片地址引线送出的20位地址码,它用来参加存储器的地址译码,最终读/写所访问的一个特定的存储单元。
   7.逻辑地址由某段的段地址和段内偏移地址(也叫偏移量)两部分所组成。写成: 段地址:偏移地址(例如,1234H:0088H)。
   8.在硬件上起作用的是物理地址,物理地址=段基地址×10H十偏移地址
问:关于中断(Interrupts)
中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字 __interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。
__interrupt double compute_area (double radius)
{
    double area = PI * radius * radius;
    printf("/nArea = %f", area);
    return area;
}
这个函数有太多的错误了,以至让人不知从何说起了:
1)ISR 不能返回一个值。如果你不懂这个,那么你不会被雇用的。
2) ISR 不能传递参数。如果你没有看到这一点,你被雇用的机会等同第一项。
3) 在许多的处理器/编译器中,浮点一般都是不可重入的。有些处理器/编译器需要让额处的寄存器入栈,有些处理器/编译器就是不允许在ISR中做浮点运算。此外,ISR应该是短而有效率的,在ISR中做浮点运算是不明智的。
4) 与第三点一脉相承,printf()经常有重入和性能上的问题。如果你丢掉了第三和第四点,我不会太为难你的。不用说,如果你能得到后两点,那么你的被雇用前景越来越光明了。
问:vector 和 list的区别?
vector内部使用数组,访问速度快,但是删除数据比较耗性能
list内部使用链表,访问速度慢,但是删除数据比较快
问:2012年10月22号百度客户端二面面试题:
Linux下的一个文件/proc 这个目录是存放什么的?如何查看当前跑的进程的最大数量?如果查看当前所打开的文件的数量?如何查看当前所建立的连接?统计当前建立的连接的数量?
我在Linux环境下周游了一年多的时间,感觉对这个平台还算很熟悉吧,但是对于面试官提出的几个命令,表示都没有接触过,再者就是忘了, 再者就是完全没用到,对于第一个命令,这个目录是是linux下的一个伪文件系统,里边存储一些与 进程相关的,系统相关的,以及系统子系统部分,可以直接通过cat /echo 直接输出一些用户需要的内核信息。平时在做多线程编程的时候更多的调用继承开发环境自带的库函数,可能是自己所操作的线程比较少 或者是 平时做的项目的深度确实没达到,都是一些浅层面的操作,导致自己根本没有掌握这么多知识,只的表示不会。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值