《2022年程序员面试宝典知识点总结 .pdf》由会员分享,可在线阅读,更多相关《2022年程序员面试宝典知识点总结 .pdf(15页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、程序员面试宝典知识点总结【预处理、 const 与 sizeof】1.BNF 范式常用的三种语法描述符号是:表示 中的内容可以缺省,也就是 中的内容可以不写出来; 表示 中的内容可以重复有限次,而n 表示固定重复n 次;|表示或者。2.编译预处理指令就是在源程序编译之前,由编译程序处理的指令。如:#include “ math.h” ,#define PI 3.14 注意:宏不能以“; ”结束;宏中应把参数用括号括起来。3.#include “”,#include ,使用 ”时,编译程序在系统当前目录与C 语言系统指定的INCLUDE目录中查找包含文件,使用时,编译程序仅在TC 指定的INCL
2、UDE目录中查找包含文件。4.#ifdef 宏名字 (#ifndef) 源程序 1 #else 源程序 2 #endif 在大型软件开发过程中,用户自定义头文件可能会无意识地被直接或间接地重复包含,使用条件编译指令可以有效解决上述问题。5.C 语言的整型根据存储长度分为8bit,16bit,32bit , 根据存储格式可分为无符号整数和有符号 整 数 。 Int 16bit(-32768+32767) , unsigned int 16bit(065535) , float 32bit , char 8bit(-128+127) ,unsigned char 8bit(0255) 。6.整型常
3、量 +L 占 8 字节;无后缀字母的实数位double 型,占用8 字节存储;有后缀字母F 的实数为float 型,占 4 字节存储; char 占 1 个字节;7.const 的用法主要有定义常量、修饰函数参数、修饰函数返回值、函数的定义体等用处。被 const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。8.const 常量有数据类型,而#define 定义的常量没有数据类型,编译器可以对const 进行类型安全检查,而宏定义只进行字符替换,没有类型安全检查,并且在字符替换中可能产生意料不到的错误;有些集成化的调试工具可以对const 常量进行调试,但不能对宏常量进行
4、调试。9.内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函数可以直接被镶嵌到目标代码中,而宏只是一个简单的替换。内联函数要做参数类型检查。10. 在 C+程序中,类里面的数据成员加上mutable 后,修饰为const 的成员函数就可以修改它了。11. exp(x)计算 ex;log10(x) 计算 lg(x) ;pow(x,y) 计算 xy;ceil(x) 求大于或等于x 的最小整数;floor(x) 求小于或等于x 的最大整数。12. 后置形式运算规则是先用变量原来的值参与表达式运算,然后对含有后置自加自减运算符的变量进行加减运算。13. C 中 pri
5、ntf 计算参数时是从右到左压栈的。14. C+语言支持函数重载,C 语言不支持, C+提供了 C 连接符号extern “ C” 解决名字匹配问题。15. 指针的大小是一个定值,就是4 个字节;对于最初未定大小的数组来说,具体大小由具体的填充值决定,注意要加上隐含的” 0” ;结构体的长度是最长的数据元素的整数倍;静态变量时存放在全局数据区的,而sizeof 计算栈中分配的大小,故计算时不算在内;空类所占空间为1,单一继承和多重继承的空类空间还是1,但虚继承涉及到虚表(虚指针) ,其占用空间为4;名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - -
6、 - - - - 名师精心整理 - - - - - - - 第 1 页,共 15 页 - - - - - - - - - 【指针及引用】1.不允许用一个整型常量表达式直接向指针变量赋初值;C 语言允许用一个字符串常量初始化一个char*型的指针变量。2.局部数组时局部变量,它所对应的是内存中的栈,全局数组时全局变量,它所对应的是内存中的全局区域。3.指针和引用的区别: (1)非空区别。在任何情况下都不能使用指向空值的引用。一个引用必须总是指向某些对象。使用引用的代码效率比使用指针要高;(2)合法性区别。在使用引用之前不需要测试它的合法性,相反, 指针则应该总是被测试,防止其为空;( 3)可修改
7、区别。指针可以被重新赋值以指向另一个不同的对象,但引用则总是指向在初始化时被指定的对象,以后不能改变,但是指定的对象的内容可以改变;(4)应用区别。总的来说,在以下情况下应该使用指针:一是考虑到存在不指向任何对象的可能,二是需要能够在不同的时间指向不同的对象。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么使用引用。4.句柄和指针式两个截然不同的概念。Windows 系统用句柄标记系统资源,用句柄隐藏系统的信息,是个32bit 的 uint。指针则标记某个物理内存地址。5.智能指针是存储指向动态分配(堆)对象指针的类。指针使用时有一些要注意的地方:有 new 就要有 delete
8、,对 COM 指针,要 AddRef 和 Release ,即这些动作要成对的出现,而往往大家会在这方面犯错误,应运而生的智能指针就是为了解决这个问题。首先把指针变量作为成员变量封装起来,在只能指针类对象离开作用域时,就会在析构的过程完成指针的释放。此外,智能指针类重载了如” & ”*” 之类的运算符,所以,用起来感觉和用一般指针一样。不过,使用智能指针类会使开销增大,还会因为太多行为是隐式调用反而造成混乱。智能指针带来的最好好处是安全。6.float(*def)10:def 是一个二级指针,它指向的是一个一维数组的指针,数组的元素都是 float;double*(*gh)10 :gh 是一个
9、指针,它指向一个一维数组,数组的元素都是double*;double(*f10)() :f 是一个数组, f 有 10 个元素,元素都是函数的指针,指向的函数类型是没有参数且返回double 的函数;Int*(*b)10):b 是一维数组的指针;Long(*fun)(int) :函数指针;Int(*(F)(int,int)(int):F 是一个函数指针,指向的函数的类型是有两个int 参数并且返回一个函数指针的函数,返回的函数指针指向有一个int 参数且返回int 的函数。【循环、递归与概率】1.设 a、b 的最大公约数为gcd(a,b),则 a、b 的最小公倍数lcm(a,b)=(a*b)/
10、gcd(a,b) 。根据求最大公约数的欧几里德辗转相除法,while(b!=0)t=a%b;a=b;b=t;当 b=0 时, gcd(a,b)=a;当 b!=0 时, gcd(a,b)=gcd(b,a%b); 2.一个过程或函数直接调用自己本身或通过其他的过程或函数调用语句间接地条用自己的过程或函数,成为递归过程或函数。递归过程的执行总是一个过程体未执行完,就带着本次执行的结果又进入另一轮过程体的执行,如此反复,不断深入,知道某此过程的执行时终止递归调用的条件成立,不再深入,二执行本次的过程体余下的部分,然后又返回到上一次调用的过程体中,执行余下的部分,如此反复,知道回到起始位置上,才最终结束
11、整个递归过程的执行,得到相应的执行结果。3.在程序设计面试中,一个能够完成任务的解决方案是最重要的,解决方案的执行效率要放在第二位考虑。如果题目是一个递归性的方案,不妨向面试官说明一下递归算法天生的低效率问题。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 15 页 - - - - - - - - - 【面向对象】1.对于一个空类,编译器默认产生4 个成员函数:默认构造函数、析构函数、拷贝构造函数和赋值函数。2.C+中的 struct 其实和class 意义一样,唯一不同
12、的就是struct 里面默认的访问控制是public,class中默认的访问控制是private。3.静态成员变量可以在同一个类的实例之间共享。如果把静态成员变量设为私有,可以通过共有静态成员函数访问。4.初始化列表的初始化变量顺序是根据成员变量的声明顺序来执行的。常量必须在构造函数的初始化列表里面初始化,或者将其设置成static。5.virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。 virtual 修饰符不能与static、abstract、private 或 override 修饰符一起使用。6.虚函数采用一种虚调用的办法,虚调用是一种可以在只有
13、部分信息的情况下工作的机制,特别允许我们调用一个只知道接口而不知道其准确对象类型的函数。但是如果要创建一个对象,必须知道对象的准确类型,所以构造函数不能为虚。7.带参数的构造函数如果不添加explicit关键字,会定义一个隐含的类型转换(从参数的类型转换到自己的类型) ,添加 explicit 可以消除这种隐含转换。8.C+ 中,下面三种对象需要调用拷贝构造函数:1)一个对象以值传递的方式传入函数体;2)一个对象以值传递的方式从函数返回;3)一个对象需要通过另外一个对象进行初始化;9.override 是指派生类重写基类的虚函数,重写的函数必须有一致的参数表和返回值;overload 指编写一
14、个与已有函数同名但参数表不同的函数。10. 友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend 。友元不是成员函数,但是他可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。例如:编写类String 的构造函数、析构函数和赋值函数class String/类 String 的原型 public: String(const char* str=NULL);/普通构造函数String(const String &other);/ 拷贝构造函数String
15、(void);/ 析构函数String & operate=(const String &other);/赋值函数private: char *m_data;/ 用于保存字符串 String :String(void)/ 析构函数 delete m_data;/由于 m_data是内部数据,也可以写成delete m_data String:String(const char *str)/ 构造函数 if(str=NULL) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共
16、 15 页 - - - - - - - - - m_data=new char1; *m_data=0; else int length=strlen(str); m_data=new charlength+1; strcpy(m_data,str); String:String(const String &other)/拷贝构造函数 int length=strlen(other.m_data); m_data=new charlength+1; strcpy(m_data,other.m_data); String & String : operate=(const String &oth
17、er) if(this=&other)/ 检查自赋值return *this; delete m_data;/释放原有的内存资源int length=strlen(other.m_data);/ 分配新的内存资源,并赋值内容m_data=new charlength+1; strcpy(m_data,other.m_data); return *this;/ 返回本对象的引用 【继承与接口】1.构造函数从最初始的基类开始构造,各个类的同名变量没有形成覆盖,都是单独的变量。2.虚函数是被子类同名函数所覆盖的。3.公有继承的特点:基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而
18、基类的私有成员仍然是私有的;私有继承的特点:私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问;保护继承的特点:基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的;4.如果一个类中有一个虚函数,那么必须得有一个对应的虚函数表来记录对应的函数入口地址,每个地址需标有一个虚指针,指针的大小为4。5.虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。A A B C / / / B C D 类 D 继承自类B 和 C,而 BC 都继承自A,所以会出现名师资料总结 - - -
19、精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 15 页 - - - - - - - - - A A / B C / D 类 D 中会出现两次A,为了节省内存空间,可以将B、C 对 A 的继承定义为虚拟继承,而 A 就成了虚拟基类。最后形成A / B C / D 代码如下:class A; class B:public virtual A; class C:public virtural A; class D:public B,public C; 6.纯虚函数是一种特殊的函数,一般格式为virt
20、ual()=0; 在许多情况下,在基类中不能对虚函数给出有意义有实现,而把它说明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。7.C+中为阻止一个类被实例化,可以使用抽象类或者构造函数被声明为private;一般要阻止编译器生成默认的copy constructor 的时候,构造函数被声明为private。8.COM(Components Object Model) 软件组件互相通信的一种方式。它是一种二进制和网络标准,允许任意两个组件互相通信,而不管它们是在什么计算机上运行,不管各计算机是什么操作系统,也不管该组件是用什么语言编写的。COM不是接口,也不是对象,而是一种标
21、准。 符合 COM 标准的对象就是COM 对象,其实 COM 对象无非是实现了很多接口的对象而已。COM 是可以被复用的,COM 对象的实现过程也可是被修改升级,如果两个程序都是用一个COM 对象,而这个COM 组件升级了的话,很可能会出现某个程序无法使用新组件的情况,被称为“DLL HELL ”(DLL 灾难 ) 【单链表】1.单链表存储结构:typedef struct LNode ElemType data; Struct LNode *next; LNode,*LinkList; 2.线性单链表的初始化实现:LinkList InitList_L(void) LNode *head;
22、head =(LNode*)malloc(sizeof(LNode); head -next=null; return (head); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 15 页 - - - - - - - - - 3.线性单链表访问第i 个元素:/L 为带头结点的单链表的头指针,当第i 个元素存在时,其值赋给e并返回 OK,否则返回 Error Status GetElem_L(LinkList L,int i,ElemType &e) LNode *p;
23、 int j=1; p=L-next;/ 初始化, p 指向第一个节点,j 为计数器 while(p&jnext;+j; if(!p|ji) return Error;/第 i 个元素不存在 e=p-data;/取第 i 个元素 return OK; 4.线性单链表插入元素/在带头结点的单链表L 中第 i 个位置之前插入元素e Status ListInsert_L(LinkList &L,int i,ElemType e) LNode *p,*s; int j=0; p=L; while(p&jnext;+j; if(!p|ji-1) return Error;/i 小于 1 或者大于表长+
24、1 s=(LNode*)malloc(sizeof(LNode);/生成新结点 s-data=e;s-next=p-next;p-next=s;/ 插入 L 中 return OK; 5.线性单链表删除元素/在带头结点的单链表L 中删除第 i 个元素,并由e 返回其值Status ListInsert_L(LinkList &L,int i,ElemType &e) LNode *p,*q; int j=0; p=L; while(p-next&jnext;+j; if(!(p-next)|ji-1) return Error;/i小于 1 或者大于表长 +1 名师资料总结 - - -精品资料
25、欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 15 页 - - - - - - - - - q=p-next;p-next=q-next;/ 删除并释放结点 e=q-data;free(q); return OK; 【双向链表】双向链表存储结构:typedef struct DuLNode ElemType data; Struct DuLNode*prior; Struct DuLNode*next; DuLNode,*DuLinkList; 【栈】1.栈的存储结构:typedef struct S
26、ElemType *base; SElemType *top; int stacksize; SqStack; 2.栈的初始化实现:Status InitListStack (SqStack &S) S.base =(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType ); if(!S.base) exit(OVERFLOW); S.top=S.base; S.stacksize=STACK_INIT_SIZE; return OK; 3.插入元素e为新的栈顶元素:void push(SqStack &S,int e) if(S.top-S.
27、base)=S.stacksize) / 栈满,追加存储空间 S.base=(int *)realloc(S.base,(S.stacksize+100)*sizeof(int); if(!S.base) exit(OVERFLOW); S.top=S.base+S.stacksize; S.stacksize+=100; *S.top=e; S.top+; 4.删除栈顶元素:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 15 页 - - - - - - - - - v
28、oid pop(SqStack &S,int& e) If(S.top=S.base) return ERROR; E=*(S.top-1); S.top-; 【队列】1.队列的存储结构:typedef struct QElemType data; struct QNode *next; QNode,*QueuePtr; typedef struct QueuePtr front;/ 队头指针 QueuePtr rear;/队尾指针LinkQueue; 示意图:datanextQ.frontQ.rear.2.队列的初始化:LinkQueue InitListQueue() LinkQueue
29、q; q.front=q.rear=(QNode*)malloc(sizeof(int); if(!q.front) exit(OVERLOW); q.front-next=NULL; return q; 【堆】1.栈和堆的主要区别:(1)栈由系统自动分配/释放,堆需要程序员自己分配/释放;(2)栈空间有限,堆是很大的自由存储区; (3)C 中的 malloc 函数分配的内存空间即在堆上,C+中对应的是new 操作符;程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行;2.经常操作的内存:名师资料总结 - - -精品资料欢迎下载 - - - - -
30、- - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 15 页 - - - - - - - - - (1)栈区:由编译期自动分配和释放,存放函数的参数值、局部变量的值等;(2)堆区:一般由程序员分配和释放,若程序员不释放,程序结束时,可能由系统回收。这与数据结构中的堆有不同的意义,分配方式类似于链表;(3)全局区 (静态区):全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量在一块区域,未初始化的在相邻的另一块区域,程序结束后由系统释放;(4)文字常量区:常量字符串就是放在这里,程序结束后由系统释放;(5)程序代码区:存放函
31、数体的二进制代码。【二叉树】1.先序遍历:访问根节点、左子树、右子树;中序遍历:左子树、根节点、右子树;后序遍历:左子树、右子树、根节点。2.二叉树的二叉链表存储表示:typedef struct BiTNode TElemType data; Struct BiTNode *lchild,*rchild; BiTNode,*BiTree; 【排序】1.选择排序算法思想:第0 步,找到a0aN-1 中的最小值元素并与元素a0交换位置;第 1 步,找到a1aN-1 中的最小值元素并与元素a1交换位置; , 第i 步,找到aiaN-1 中的最小值元素并与元素a1交换位置, 第N-2 步,找到aN-
32、2aN-1 中的最小值元素并与元素aN-2 交换位置。void SelSort(int aN) int min=a0; for(int i=0;iN-1;i+) int min=i; for(int j=i+1;jaj) min=j;/ 找到 aiaN-1 的最小值元素的下标 int t; if(min!=i)/ 如果最小值元素下标正好是i,则无需交换 t=ai;ai=amin;amin=t; 2.插入排序算法思想:第1 步,将一个元素的子数组a0视为一个升序数组,将a1作为待插入元素x,则 a1位置可视为空闲, 将 x 插入到升序数组a0a0 中,使得 a0a1升序;第2 步,将 a2作为待
33、插入元素x,则 a2位置可视为空闲,将x 插入到升序数名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 15 页 - - - - - - - - - 组 a0a1 中,使得a0a2 升序; , 第i 步,将 ai作为待插入元素x,则 ai位置可视为空闲,将x 插入到升序数组a0ai-1 中,使得a0ai 升序; , 第N-1 步,将 aN-1 作为待插入元素x, 则 aN-1 位置可视为空闲, 将 x 插入到升序数组a0aN-2中,使得a0aN-1 升序;void Inse
34、rt(int a,int n,int x) int i=n-1; /将大于 X 的元素向后挪动一个下标位置 while(x=0) ai+1=ai; i=i-1; /循环退出时,下标i+1 正是插入 x 的位置 ai+1=x; void InSort(int aN) int x; for(int i=1;iN;i+) Insert(a,i,ai); 3.冒泡排序算法思想:第1 步,将a0aN-1 中的最大元素浮到aN-1 ;第2 步,将a0aN-2 中的最大元素浮到aN-2 ; , 第i 步,将a0aN-i 中的最大元素浮到aN-i ; , 第N-1 步,将 a0a1 中的最大元素浮到a1 vo
35、id BubSort(int aN) int t; for(int i=0;iN;i+) /每趟冒泡之前,设置标识变量值为1,经过一趟冒泡后/标识变量仍为1,则退出循环/如果冒泡时发生了元素交换值,说明数组尚未排好,则令其值为0 int flag=1; for(int j=0;jaj+1) t=aj;aj=aj+1;aj+1=t; flag=0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 15 页 - - - - - - - - - if(flag=1) brea
36、k; 4.快速排序算法思想:第 1 步,设置两个指针i 和 j,他们的初始值分别为区间的下界和上界,即 i=low ,j=high ;选取无序区的第一个记录ai作为基准记录;第2 步,反复执行i=i+1 的操作,直到i 指向的元素大于等于基准元素,或者i 指向序列尾部为止。然后反复执行 j=j-1 的操作, 直到 j 指向的元素小于等于基准元素,或者 j 指向序列的首部为止。若此时 i=j ,则将基准元素与j 指向的元素交换位置,重复执行步骤2;第 3 步,递归地对基准元素前后序列按同样的方式进行快速排序,递归结束的条件是low=high ;void QuickSort(int a,int s
37、,int t) /as 为基准元素,s 为 low,t 为 high int i,j=0; int temp; if(st) i=s; j=t+1; while(ij) while(aias&j!=s) j-; if(i1) d=(d+1)/2; for(int i=low;iad+i) int temp=ai; ai=ad+i; ad+i=temp; 6.归并排序是将两个或两个以上的有序表组合成一个新的有序表;基数排序是一种借助多关键字排序的思想对单逻辑关键字进行排序的方法。7.各种内部排序方法的比较:排序方法平均时间最坏情况辅助空间简单排序O(n*n) O(n*n) O(1) 快速排序O(
38、nlogn) O(n*n) O(nlogn) 堆排序O(nlogn) O(nlogn) O(1) 归并排序O(nlogn) O(nlogn) O(n) 基数排序O(d(n+rd) O(d(n+rd) O(rd) (1)若 n 较小(如 n=50) ,可采用直接插入或直接选择排序;(2)若文件初始状态基本有序(正序),则应该用直接插入排序、冒泡排序或随机的快速排序为宜;(3)若 n 交大,则应采用时间复杂度为O(nlogn) 的排序方法:快速排序、堆排序或归并排序;(4)快速排序被认为是目前基于比较的内部排序中最好的方法,当待排序的关键字随机分布时,快速排序的平均时间最短;堆排序所需的辅助空间少
39、于快速排序,并且不会出现快速排序可能出现的最坏的情况,这两种排序都是不稳定的;若要求排序稳定,则可选用归并排序;【字符串】1.整数转化为字符串:可以采用加 0 ,再逆序的办法,整数加 0 就会隐性转化为char 类型的数;字符串转化成整数可以采用减 0 再乘 10 累加的办法,字符串减 0 就会隐性转化成 int 类型的数。2.字符串拷贝函数:char *strcpy(char *strDest,char *strSrc) char *address=strDest; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理
40、 - - - - - - - 第 12 页,共 15 页 - - - - - - - - - while(*strSrc!=0) *strDest+=*strSrc+; *strDest=0; return address; 3.字符数组和字符串的最明显的区别就是字符串会被默认的加上结束符 0 ,字符数组的初始化要求最后一个字符必须为 0 ,字符串并不要求最后一个字符时 0 ,是否需要加入 0 完全由系统需要决定。4.Strlen 得到的是字符串除结束符以外的长度。char 值范围为 -128127 5.头文件 iostream 中含有 cin,cout, cerr 几个对象,对应于标准输入流
41、、标准输出流、标准错误流。【软件工程】1.把业务逻辑放在服务器上的实现方式:业务逻辑就是对表现层输入的数据进行有效性的验证,处理数据,将处理后的数据传送到数据访问层。或者从表现层接收数据,处理后再送回表现层。实现的方式很多,比较好的回答是创建业务实体层,部署在应用服务器上。通过实现映射数据库的关系,其业务逻辑在中间服务器层实现,减轻了数据库服务器的压力,有利于负载均衡,客户端通过HTTP 、SOAP、Remoting 等方式访问。2.类与类之间的通信实现方式:可以采用Window 消息机制,或者共享空间及管道连接等方式实现类与类之间的通信。【操作系统】1.进程和线程的差别: 进程是程序的一次执
42、行,线程可理解为进程中执行的一段程序片段。进程间是独立的,这边现在内存空间、上下文环境上,线程运行在进程空间内;一般来讲,进程无法突破进程边界存取其他进程内的存储空间,而线程由于处于进程空间内,所以同一进程所产生的线程共享同一内存空间;同一进程中的两段代码不能够同时执行,除非引入线程;线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除。 线程占用的资源要少于进程所占用的资源;进程和线程都可以设定优先级。2.进程间的通信方式有信号、信号量、消息队列、共享内存。信号和信号量是不同的,它们虽然都可以用来实现同步和互斥,但信号是使用信号处理器来进行的,而信号量是使用 PV 操作来实现
43、的。消息队列可以再进程间传递message。3.多进程和多线程的区别:用多进程时没个进程有自己的地址空间,线程则共享地址空间。(1)速度:线程产生速度快,线程间通信快,切换快,因为它们在同一个地址空间内;(2)资源利用率:线程的资源利用率高,也是因为它们在同一个地址空间内;(3)同步问题:线程使用公共变量/内存时需要使用同步机制。理由同上。4.在 Windows 编程中互斥器(mutex)的作用和临界区(critical section)的区别:互斥器用于进程间互斥,临界区是线程间互斥。5.快表 Cache 在 OS 中运用:在操作系统中,为提高系统的存取速度,在地址映射机制中增加一个小容量的
44、联想寄存器,即快表,用来存放当前访问最频繁的少数活动页面的页号。当某用户需要存取数据时,根据数据所在的逻辑页号在快表中找到对应的内存块号,再联系页内地址,形成物理地址。如果在快表中没有相应的逻辑页号,则地址映射仍可通过内存中的页表进行,得到空闲块号后须将该块号填入快表的空闲块中,如果快表中没有空闲块,则根据淘汰算法淘汰某一行,再填入新的页号和块号。6.高速缓存存储器Cache:CPU 的执行速度越来越快,系统架构越来越先进,而主存名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13
45、页,共 15 页 - - - - - - - - - 的结构和存取速度改进则很慢,因此,高速缓存技术将越来越重要。高速缓存存储器是位于 CPU 与内存之间的临时存储器,它的容量比内存小但交换速度快。在Cache 中的数据时内存中的一小部分,但这一小部分是短时间内CPU 即将访问的。当CPU 调用大量数据时,就可避开内存,直接从Cache中调用,从而加快读取速度。【数据库】1.设 R 使一个具有属性集合U 的关系模式, 如果 X Y, 并且对于X 的任何一个真子集Z,ZY 都不成立,则称Y 完全函数依赖于X,记作 XY。若 X Y,但 Y不完全函数依赖于 X,则称 Y部分函数依赖于X,记作 X-
46、pY。设 R使一个具有属性集合U的关系模式,X、Y、Z 属于 U,X、 Y、Z 是不同的属性集。如果XY,YX不成立, YZ,则 称 Z 传递函数依赖于X 。2.1NF:第一范式。如果关系模式R 的所有属性的值域中每一个值都是不可再分解的值,则称 R 属于第一范式。 如果某个数据库模式都是第一范式的,则称该数据库模式属于第一范式的数据库模式。第一范式的模式要求属性值不可再分裂成更小的部分,即属性项不能是属性组合或有组属性组成。3.2NF:第二范式。 如果关系模式R 是第一范式,并且R 中每一个非主属性完全函数依赖于 R 的某个候选键, 则称 R 为第二范式模式。 如果某个数据库模式中每个关系模
47、式都是第二范式的,则称该数据库模式属于第二范式的数据库模式。(1NF 向 2NF 转换的方法是:消除其中的部分函数依赖,一般是激昂一个关系模式分解成多个2NF 的关系模式。即将部分函数依赖于键的非键属性及其决定属性移出,另成一个关系,使其满足2NF)4.3NF:第三范式。 如果关系模式R 是第二范式,且每个非主属性都不传递依赖于R 候选键,则称 R 是第三范式模式。 (2NF 关系向 3NF 转换的方法: 消除传递函数依赖,将 2NF关系分解成多个3NF 关系 )5.BCNF : BC 模式。 如果关系模式R 是第一范式,且每个属性都不传递依赖于R 的候选键,则称 R 为 BCNF 模式。6.
48、4NF:第四范式。设 R 是一个关系模式,D 是 R 上的多值依赖集合。如果D 中成立非凡多值依赖X Y 时, X 必是 R 的超键,那么称R 是第四范式的模式。7.存储过程和函数的区别:存储过程是用户定义个一系列SQL 语句的集合,涉及特定表或其他对象的任务,用户可以调用存储过程。而函数通常是数据库已定义的方法,它接收参数并返回某种类型的值,并且不涉及特定用户表。8.事务时作为一个逻辑单元执行的一系列操作。一个逻辑工作单元必须有4 个属性,成为ACID (原子性、一致性、隔离性和持久性)属性,只有这样才能称为一个事务。9.游标用于定位结果集的行。通过判断全局变量FETCH_STA TUS 可
49、以判断其是否到了最后,通常此变量不等于0 表示出错或到了最后。10. 所谓 SQL 注入式攻击, 就是攻击者把SQL 命令插入到Web 表单的输入域或者页面请求的查询字符串中,欺骗服务器执行恶意的SQL 命令。在某些表单中,用户输入的内容直接用来构造(或影响)动态SQL 命令,或作为存储过程的输入参数,这类表单特别容易受到 SQL 注入式攻击。 防范 SQL 注入式攻击, 只要在利用表单输入的内容构造SQL命令之前,把所有输入内容过滤一番就可以了。过滤输入内容可以按多种方式进行。第一,替换单引号;第二,删除用户输入内容中的所有连字符,防止攻击者顺利获得访问权限;第三,对于用来执行查询的数据库账
50、户,限制其权限;第四,用存储过程来执行所有的查询; 第五,检查用户输入的合法性,确信输入的内容只包含合法的数据;第六,将用户登录名称、密码进行加密保护;第七,检查提取数据的查询所返回的记录数量。11. 建立临时表: create table #temp(字段 1 类型,字段2 类型 ) 12. 索引是关于数据位置信息的关键字表,是数据库系统中的数据存储方法之一。聚簇索引:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 15 页 - - - - - - - - - 磁盘上