而函数通常是数据库已定义的方法。它接收参数并返回某种类型的值,并且不涉及特定用户表。
数据库事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么全做要么全不做,是一个不可分割的工作单位。事务的开始与结束可以由用户显式控制,或者由DMBS按默认规定自动划分事务,事务具有原子性(一个事务要么全部执行、要么不执行,不可能只执行了一半就停止了。)、一致性(事务的运行并不改变数据库中数据的一致性)、独立性(两个以上的事务不会出现交错执行的状态)、持久性(指事务运行成功以后,就系统的更新是永久的)
游标用于定位结果集的行。通过判断全局变量@@FETCH_STATUS可以判断其是否到了最后。通常此变量不等于0表示出错或到了最后。
create table #temp(??);//临时表要在表名前面加#.
进程间的通信如何实现?
现在最常用的进程间通信的方式有信号、信号量、消息队列、共享内存。
所谓进程通信,就是不同进程之间进行一些“接触”。这种接触有简单、也有复杂。机制不同,复杂度也不一样。通信是一个广义上的意义,不仅仅指传递一些message。方法是基本相同的,所以只要掌握了一种使用方法,然后记住其他的使用方法就可以了。信号与信号量是不相同的,它们虽然都可用来实现同步与互斥,但前者是使用信号处理器来进行的,后者使用P、V操作来实现的。消息队列是比较高级的一种进程间通信方法。一个消息队列可以被多个进程所共享(IPC就是在这个基础上进行的)。如果一个进程的消息太多了,一个消息队列放不下,也可以用多于一个的消息队列。共享消息队列的进程所发送的消息中除了message本身还有一个标志,这个标志可以指明该消息将由哪个进程或者是哪类进程接受。每个共享消息队列的进程针对这个队列也有自己的标志,可以用来声明自己的身份。
互斥器是进程之间互斥,临界区是用于线程之间的互斥。
作业:用户在一次解题或一个事务处理过程中要求计算机系统所做工作的集合。它包括用户程序、所需要的数据及控制命令等。作业是由一系列有序的步骤组成的。
进程:一个程序在一个数据集合上的一次运行过程。所以一个程序在不同数据集合上运行,乃至一个程序在同样数据集合上的多次运行都是不同的进程。
线程:线程是进程中一个实体,是被系统独立调度和执行的基本单位。
管程:管程实际上是定义了一个数据结构和在该数据结构上的能为并发进程所执行的一组操作,这组操作能同步进程和改变管程中的数据。
产生死锁的4个必要条件:(经典算法:银行家算法) 1、 互斥条件:一个资源每次只能被一个进程使用。
2、 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 3、 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。 4、 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
PE文件被称为可移植的执行体,常见的EXE、DLL、OCX、SYS、COM都是PE文件。
Window平台的大多数程序都是用各种动态连接接库(DLL)来避免重复实现功能。操作系统为每个程序加载若干个DLL,具体有程序的类型决定。当程序不指定DLL的绝对位置时,操作系统自动搜索,顺序为一下:1、内存。2、KnownDLLs。3、清单与.local。4、应用程序目录。5、当前工作目录。6、系统目录。7、路径变量。(1、进程当前工作目录2、包含EXE文件的目录3、Windows系统目录4、Windows目录5、列在Path环境变量中的一系列目录)
在OSI参考模型中,物理层的作用是透明的传输比特流。对等实体在一次交互作用中传送的信息单位称为协议数据单元,它包括控制信息和用户数据两部分。上下层实体之间的接口称为服务访问点(SAP),网络层的服务访问点也称为网络地址,通常分为网络号和主机地址两部分。
在一个IP数据包到达目的地址之前,它可能成为碎片,而且不会重组。在TCP、IP协议栈里,如果出现阻塞,会导致丢失包。
TCP的3次握手4次挥手全过程?
1. 第一次握手:建立连接时,客户端发送SYN包(syn = j)到服务器,并进入SYN_SEND状态,等待服
务器确认。
2. 第二次握手:服务器收到SYN包,必须确认客户的SYN(ack = j + 1),同时自己也发送一个SYN包
(syn = k),即SYN + ACK包,此时服务器进入SYN_RECV状态。
3. 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack = k + 1),此包发送完
毕,客户端和服务端进入ESTABLISHED状态,完成了3次握手。
在子网210.27.48.21/30中有多少个可用地址? 210.27.48.21/30代表的子网的网络号是30位。
致命端口号:80用于浏览网页服务的、21用于FTP服务的、25分配给SMTP、135分配给RPC、8000与4000为QQ端口号、53是DNS服务的、161是属于SNMP、23是Telnet。0-1023端口号为常用端口,不能使用。
1. 物理层:涉及在信道上传输的原始比特流。
2. 数据链路层:是加强物理层传输原始比特流的功能,使之对应的网络层显现为一条无错线路。发送包
把输入数据封装在数据帧,按顺序传送出去并处理接收收方会送的确认帧。
3. 网络层:关系到子网的运行控制,其中一个关键问题是确认源端到目的端如何选择路由。 4. 传输层:是从会话层接收数据而且把其分成较小的单元传递给网络层。 5. 会话层:允许不同机器上的用户建立会话关系。 6. 表示层:完成某些特定的功能。
7. 应用层:包含大量人们普遍需要的协议。
DLL文件是什么?有几种调用方式?
DLL文件(动态链接库文件)是一种不能单独运行的文件,它允许程序共享执行特殊任务所必需的代码和其他资源。比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们互相协作来完成整个软件系统的工作,可能存在一些模块的功能较为通用,在构造其他软件系统时乃会使用。在构造软
件系统时,如果将所有模块的源代码都静态编译到整个应用程序EXE文件中,会产生一些问题:一是增加了应用程序的大小,会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费。另一个是,在编写大的EXE程序时,在每次修改重建时都必须调整编译所有源代码增加了编译过程的复杂性,也不利于价段性的单元测试。
一般来说,DLL是一种磁盘文件,以.dll/.DRV、.FON/.SYS和许多的.exe为扩展名的系统文件都可以是DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到调用进程的虚拟空间中,成为调用进程的一部分。如果与其他DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL模块中包含各种导出函数,用于向外界提供服务。DLL可以有自己的数据段,但没有自己的堆栈,使用与调用他的应用程序是相同的堆栈模式。一个DLL在内存中只有一个实例。DLL实现了代码封装性。DLL的编写与具体的编程语言及编译器无关。DLL占有内存小,好编译,但不能单独运行,也不能接收消息。只有其他模块调用动态链接库中的函数时,才发挥作用。 调用方式:
1、 静态调用:由编译系统完成对DLL的加载和应用程序结束时DLL的卸载的编码(如还有其他程
序使用该DLL,则Windows对DLL的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它),方法简单实用,但不灵活,只能满足一般要求。
2、 动态调用:是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,使用上较复杂,但
能有效使用内存,是编制大型应用程序时重要方式。
描述一个测试结束的准则:
一个测试结束的标准可以查看已提交的bug是否已经全部解决并已验证关闭,一般来说,bug验证率在95%以上,并且没有大的影像功能的bug处于未解决状态,就可以通过。
整数转化成字符串,或者字符串转化成整数,可以采用加’0’或者减’0’。 char c[5] = {‘C’,’h’,’i’,’n’,’a’};//这样定义是错误的
strcpy经典实现代码:
char *strcpy(char *strDest, const char *strSrc) { } 名字 冒泡排序 插入排序 归并排序 基数排序 时间复杂度 最差、平均都是O(n2);最好是O(n) 最差、平均都是O(n2);最好是O(n) 最差、平均、最好都是O(nlogn) O(dn)d为常数 空间复杂度 1 1 O(n) O(n) 稳定性 稳定 稳定 稳定 稳定 assert((strDest != NULL) && (strSrc != NULL)); char *address = strDest;
while((*strDest ++ = *strSrc++) != ‘\\0’)
;
return address;
二叉树排序 选择排序 希尔排序 堆排序 快速排序(好) O(nlogn) 最差、平均都是O(n2) O(nlogn) O(nlogn) 平均O(nlogn);最坏O(n2) O(n) 1 1 1 O(logn) 稳定 不稳定 不稳定 不稳定 不稳定 1 < O(log(2)n) < O(n) < O(nlog(2)n) < O(n2) < O(n3)
简单排序中直接插入排序最好,快速排序最快。当文件为正序时,直接插入排序和冒泡排序均最佳。 1、 若n较小(如n < 50),可采用直接插入排序或直接选择排序。
2、 若文件初始状态基本有序 ,则应选用直接插入排序、冒泡排序或快速排序为宜。 3、 若n较大,则应采用时间复杂度为O(nlogn)的排序(快速排序、堆排序、归并排序) 4、 快速排序被公认为基于内部比较最好的方法。
经典面试问题:
1、 有一千万的条短信,有重复的,以文本文件的形式保存,一行一条,请用5分钟的时间,找出重复出
现最多的前10条。
解析:本题目如果使用将数据导进数据库的形式是不能满足时间上的要求。 a)
可以用哈希表的方法对1千万条分成若干组进行边扫描边建散列表。第一次扫描,取首字节,尾字节,中间随便两个字节作为HashCode,插入到hashTable中。并记录其地址和信息长度和重复次数,1千万条信息,记录这几个信息还放得下。同hashCode并且等长就是疑似相同,比较一下。相同记录只加1次进hashTable。一次扫描后,已经记录各自的重复次数,进行第二次处理?. b)
可以采用内存映射方法。1千万条短信将不会超过1G。其次,对每条短信的第i个(i从0到70)个字母按照ASCII码进行分组,其实也就是创建树。i是树的深度,也是短信第i个字母。
2、 有一亿浮点数,请找出其中最大的10000个。提示:假设每个浮点数占4个字节,1亿就要占相当大
的空间,因此不能一次将全部读入内存进行排序。 a) b)
二叉树:或者是一棵空树,或者是具有下列性质的二叉树:对于树中的每个节点X,它的左子树中的关键字的值都小于X的关键字的值,右边则比较大。 {
int i = 0x22222222222; char szTest[] = “aaaa”;
func/*第3个压栈,为函数地址*/ (i/*第2个压栈,为参数地址*/ , szTest/*第1个压栈,为参数地址*/); }
调用函数时首先进行参数压栈,一般情况下压栈顺序为从右到左,在Windows平台上,栈都是从上向下生长的。
读取100万个数据,找出最大的1万个,以这1万个作为最小的基准,可以过滤掉1亿个数据,最后就再一次在剩下的100万里面找出最大的1万个
分块查找:将全部的数据分成好几份的一百万份,从中100万数据中找出最大的一万个。最后再在剩下来的数据中查找最大的1万个数据。
对于一个进程的内存空间而言,可以在逻辑上分成了3个部分:代码区、静态数据区和动态数据区。动态数据区一般就是“堆栈”,“栈”和“堆”是两种不同的动态数据区。栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然代码一样,但本地变量的数据都是互不干涉的。一个堆栈可以通过“基地址”和“栈顶”地址来描述。程序通过堆栈的基地址和偏移量来访问本地变量。
栈区:由编译器自动分配和释放,存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈。
堆区:一般由程序员分配和释放,若程序员不释放,程序结束时可能由操作系统回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
全局区(静态区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域程序结束后由系统释放。 文字常量区:常量字符串就是放在这里的。程序结束由系统释放。 程序代码区:存放函数体的二进制代码。 例子:
//main.cpp
int a = 0;//全局初始化区 char *p1;//全局未初始化区 main() {
int b;//栈
char s[] = “abc”;//栈 char *p2;//栈
char *p3 = “123456”;//”123456”存放在常量去,p3在栈区 static int c = 0;//全局(静态)初始化区 p1 = (char *)malloc(10);
p2 = (char *)malloc(20);//分配得来的10与20字节的区域就在堆区。
strcpy(p1, “123456”);//”123456”放在常量区,编译器可能会被它与p3所指向的”123456”优化成一个地方 }
私有继承:基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。基类的私有成员是不可见的,派生类不可访问基类中的私有成员。基类的成员只能由直接派生类访问,而无法再往下继承。
保护继承:基类的公有成员和保护成员都作为派生类的保护成员,并且不能被这个派生类的子类所访问。基类的成员也只能由直接派生类访问,而无法再往下继承。
#include