阿里腾讯实习生题目


腾讯笔试

2.   假设函数f1的时间复杂度O(n),那么f1*f1的时间复杂度为()

A.  O(n)B.   O(n*n)C.  O(n*log(n))D.  以上都不对

 这个题目我的思路是A,讨论后答案应该是D,因为f1的返回值不确定,如果是个数组当然复杂度就不同了。


3.   对下列四种排序方法,在排序中关键字比较次数与记录初始化顺序无关的是()

A.  直接排序B.   二分法插入C.  快速排序D.  归并排序

B

1)冒泡:无关;如果加上特殊标志,没有交换就提前退出,就有关;(大的沉底)
2)选择:无关;(未排序部分选择最小值)
3)插入:有关,排序程度越大,比较越少;
4)shell:有关,它的基本思想基于插入排序;
5)归并:有关,排序程度愈大,融合过程的比较次数越少;
6)堆排序:有关,排序程度越大,建立堆下沉操作越少;
7)快排序:有关,如果选择最后值作为阀值,那么排序程度越好,就越可能退化成O(n^2);
           无关,随机选择阀值,那么与排序程度无关。

4.   已知一段文本有1382个字符,使用了1382个字节存储,这段文本全部是由a、b、c、d、e字符组成,a 354次,b 483次,c 227次,d 96次,e 222次,对这5个字符使用哈夫曼编码。则以下说法正确的是?()

A.  使用哈夫曼编码后,使用编码值来存储这段文本将花费最少的存储空间、

B.   使用哈夫曼编码后,a b c d e 这5个字符对应的编码值是唯一确定的

C.  使用哈夫曼编码后,a b c d e 这5个字符对应的编码值可以有多套,但每个字符的编码位数是确定的

D.  b这个字符的编码位数最短,d这个字符的哈夫曼编码位数应该最长

有人选D

6.   在编译过程中,产生Parse  tree的过程是(A)  
A.  语法分析 B.   语义分析阶段C.  词法分析D.  目标代码生成阶段


7.   阅读下面代码,程序会打印出来的值是()

 

1
2
3
4
5
6
7
8
9
10
#include
Void
f(
char  **p){
                 *p
+= 2;
}
Void
main() {
                 Char
*a[] = { “123”,”abc”,”456”},**p;
                 p
= a;
                 f(p);
                 printf (“%s\r\n”,**p);
}

 

  A.  123  B.   abc  C.  456  D.  3 

 char *a[] , 多维数组,数组中每个元素是含有3个char类型对象的数组,指针的应用,a是二维数组的首位指针,首先取值之后变成第一行的首指针,+2移动至3的位置,输出为3。

8.   Char p1[] = “Tencent”, void* p2 = malloc((10)在32位机器上sizeof(p1)和sizeof(p2)对应的值是()

A.  8:0 B.   4:10 C.  8:4 D.  4:4

数组的长度和指针的长度,数组只有在传参的时候才会退化为指针。sizeof的时候针对指针进行计算。字符串字面值""后面自动添加null‘\0’ 在申请空间时记得多个结束


9.   现在有以下两个函数,调用test的结果是()

 

复制代码
Char* getMem(void) {      Char * p = “hello world ”;
      P[5] = 0x0;
      Return p;
}
Voidtest(void) {      Char *s = 0x0;
      s = getMem();
      Printf(s);
}
复制代码

 

A.  hello B.   无输出 C.  Hello0world D.  不确定

 局部变量在函数返回的时候会删除掉,指向内容就不确定了。答案应该是D。


10.  冯诺依曼体系结构计算机的基本原理是()
A信息存储  B 存储智能 C 数字控制 D 存储程序和程序控制 

 应该是D。

12.下面哪种设计模式的定义为:定义对象间的一种一对多的关系,当一个对象改变时,其他依赖于他的对象都能够得到通知并自动更新。()

A.  Visitor B.   Adapter C.  Observer D.  Interpreter

 观察者模式也就是C符合描述。

13.请看一下这一段C++代码,如果编译后程序在windows下运行,则一下说话正确的是()

Char*p1 = “123456”;  //123456\0,在常量区;p1在栈中或者在全局区  

Char*p2 = (char*)malloc(10); //p2在栈中或者全局区,分配来的是个字节在堆中  看他们出现在main()函数的里面还是外面

A.  P1 he p2都存在栈中

B.   P2指向的10个字节内存在栈中

C.  堆和栈在内存中的生长方向是相反的

D.  “123456”这6个字符存储在栈中

在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

  栈,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

  堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

  自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

  全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

  常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。

15.对n个元素的数组进行快速排序,所需要的二外空间为()

A.  O(1)B.   O(n)C.  O(log(2n)D.  O(n^2))

说明:最好O(log(n)),最差O(n)

16.下面关于编译器与解释器的观点,错误的是()

A.  解释器不产生目标程序,它直接执行源程序或者源程序的内部形式

B.   解释程序和编译程序的主要区别在于是否产生目标程序

C.  编译器对高级语言程序的处理过程划分成词法分析、语法分析、语义分析,中间代码生成、代码优化、目标代码生成几个阶段

D.  解释器参与运行控制、程序执行的速度快

 这个我选择的是D。

18.下面哪些协议,存在源端口和目的端口是()

A.  IP B.   TCP C.  UDP D.  ICMP协议

AB

19.下列哪些sql是等价的()

A.  Select A.tname ,A.depart from teacher A joincourse B on B.tno = .A.tno

B.   Select A.tname ,A.depart from teacher A whereA.tno = course.tno

C.  Select A.tname ,A.depart from teacher wheretno in (select tno from course)

D.  Select A.tname ,A.depart from teacher where exsist (select * from course B where B.tno = A.tno);

BC

21.将一个C类网络划分为3个子网,每个子网最少要容纳55台主机,使用的子网掩码是:()
  A、255.255.255.248   B、255.255.255.224  C、255.255.255.224  D、255.255.255. 192

 192,保留6位计算得到的。3个子网不确定是怎么得到。

22下列关于计算机硬件的描述,正确的是:()
A、磁盘的平均存取时间指的是磁盘的寻道时间加上磁头在某一磁道等待记录扇区的时间
B、计算机的控制器是由多种部件组成,其中包括,指令寄存器、程序计数器和算数逻辑单元
C、一台计算机的字长是32位,表明该机器能处理的数值最多为4个字节//32位CPU就是在同一时间内处理字长为32位的二进制数据,不是数值。
D、系统总线可以分为数据总线、地址总线和控制总线三类
A:硬盘的平均存取时间由寻道时间和读写时间两部分构成。寻道就是硬盘通过移动磁头到达信息所在磁道上。读就是利用电磁感应原理把信息从磁信号转变为电信号。写就是电变磁。
B: 计算机的控制器是由由程序计数器、指令寄存器、指令译码器、时序产生器和操作控制器组成,它是发布命令的“决策机构”,即完成协调和指挥整个计算机系统的操作

23、假设有关系模式R(A,B,C,D),其数据依赖集:F={(A,B)- >C,C->D},则关系模式R的规范化程度最高达到:()
A.1NF
B.2NF
C.3NF
D.BCNF

这个也不太会,同学说选择应该是B。

24.以下为一段浏览器中可运行的Javascript 代码,则运行该段Javascript代码的页面弹出框中显示的结果是:()
Var obj = { “key”:”1”,”value”:2};
Var newObj = obj;
newObj.value += obj.key;
alert(obj.value);
A、2           B、12          C、3         D、21

javascript的题目,答案是D...我还以为是考引用的...???


25.有足够量的2分、5分、1分硬币,如果想凑齐一元钱,可以有()种方法
A、541    B、270   C、1024    D、128

说明:看成50个2分和20个5分构成小于一元,不够的用1分来补。当20个5分,2分0个共1种;当19个5分时,2分可能有:0,1,2共3种;。。。。。。当有2个5分时,2分可能有0,1,2...45共46种;当有一个5分时,2分可能有:0,1,2...47共48种;当有0个5分,2分可能有:0,1,2...50共51种。所以共有1+3+...+48+51=(1+48)+(3+46)+...+(23+26)+51=49*(20/2)+51=541  

28.在一个采用页式虚拟存储管理的系统中,有一用户作业,它依次要访问的也没序列是1,2,3,4,1,2,5,1,2,3,4,5.假定分配给该作业的页数为3且作业初始时未装载页面,那么采用FIFO调度算法产生的缺页中断数为(),采用LRU调度算法产生的缺页中断数为()
9,10,当时写了一个6,7,错在初始未装载

29.

 

复制代码
#include <stdio.h>
class Base
{
public:
virtual int foo(int x){return x*10;}
int foo(char x[14]){return sizeof(x)+10;}
};
class Derived:public Base
{
int foo(int x){return x*20;}
virtual int foo(char x[10]){return sizeof (x)+20;}
};
int main(void)
{
Derived  stDerived;
Base * pstBase=& stDerived;
char x[10];
printf(“%d\n”,pstBase->foo(100)+pstBase->foo(x));
return 0;
}
复制代码

 

在32位环境下,以上程序的输出结果是()
2014, 蛮经典的考到两点,1)虚函数,基类指着指向派生类时,如果调用的是基类已经声明过的虚函数,动态绑定,如果不是虚函数,那么基类指针将会体现裁割的性质,就是只能指向派生类对象的基类部分;2)数组在传递给函数时退化成了指针,当数组作为非引用类型的形参时,编译器不会检查数组大小,x就是指针,只有当引用传递数组才会检查传递的数组大小,传递的不再是数组的指针而是数组的引用本身

A. 珠宝商甲需要去鉴定一批41克以下的宝石(可能是41克以下不包括41克的任意重量),他只能携带一个天平和四个砝码去称重,请问他会携带那些重量的砝码?  1 3 9 27  

说明:我第一反应有两种思路。1、由上往下尝试,假设需要40/2=20,转化为有3个发吗解决1-20的问题,发现走不通;2、然后尝试由下往上,首先以2倍为步长,明显不行,再以3倍为步长1,3,9,27,短暂尝试发现确实可以经过加减构造出任意1-40.  

阿里

32位编译器:

      char :1个字节
      char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
      short int : 2个字节
      int:  4个字节
      unsigned int : 4个字节
      float:  4个字节
      double:   8个字节
      long:   4个字节
      long long:  8个字节
      unsigned long:  4个字节

  64位编译器:

      char :1个字节
      char*(即指针变量): 8个字节
      short int : 2个字节
      int:  4个字节
      unsigned int : 4个字节
      float:  4个字节
      double:   8个字节
      long:   8个字节
      long long:  8个字节
      
unsigned long:  8个字节


2.64位系统上,定义的变量int*a[2][3]占据的——字节

A、4      B、12      C、24    D、48

参考答案 D。int *a[2][3]表示的是定义一个二维数组指针,指针指向整型数据。数组里有2*3=6个指针变量。在32位系统中为指针变量分配4个字节,在64位系统中为指针变量分配8个字节。指针存的是一个地址,在32位操作系统里面,最大寻址空间位0~2^32-1,即4个字节(32位)就可以表示,相应的在64位操作系统环境中用8个字节表示指针。指针本身所占空间大小与所指对象所占空间大小无关,只与操作系统能够有关。

3.Linux中使用df-h/homedu-sh/home所查看到的已使用的磁盘容量不同,可能的原因是——

A、命令不同,所以结果肯定不同   B、两个命令参数有问题

C、运行中的进程打开的文件被删除导致 DLinux的特性导致的

参考答案 C。df——Disk Free。du——Disk Usage。当一个文件被删除后,在文件系统目录中已经不可见了,所以du就不会再统计它了。然而如果此时还有运行的进程持有这个已经被删除了的文件的句柄,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改。这样df仍旧会统计这个被删除了的文件。


3. linux使用df -h /home和du -sh /home所查看到的已使用的磁盘容量不同的原因

1. 如何记忆这两个命令

du-Disk Usage

df-Disk Free

2. df 和du 的工作原理

2.1 du的工作原理

du命令会对待统计文件逐个调用fstat这个系统调用,获取文件大小。它的数据是基于文件获取的,所以有很大的灵活性,不一定非要针对一个分区,可以跨越多个分区操作。如果针对的目录中文件很多,du速度就会很慢了。

2.2 df的工作原理

df命令使用的事statfs这个系统调用,直接读取分区的超级块信息获取分区使用情况。它的数据是基于分区元数据的,所以只能针对整个分区。由于df直接读取超级块,所以运行速度不受文件多少影响。

3 du和df不一致情况模拟

常见的df和du不一致情况就是文件删除的问题。当一个文件被删除后,在文件系统目录中已经不可见了,所以du就不会再统计它了。然而如果此时还有运行的进程持有这个已经被删除了的文件的句柄,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改。这样df仍旧会统计这个被删除了的文件。

4 工作中需要注意的地方

(1)当出现du和df差距很大的情况时,考虑是否是有删除文件未完成造成的,方法是lsof命令,然后停止相关进程即可。
(2)可以使用清空文件的方式来代替删除文件,方式是:echo > myfile.iso。
(3)对于经常发生删除问题的日志文件,以改名、清空、删除的顺序操作。
(4)除了rm外,有些命令会间接的删除文件,如gzip命令完成后会删除原来的文件,为了避免删除问题,压缩前先确认没有进程打开该文件。

8.char str[] = "hello";
sizeof(str)             //6
char *p = str;
sizeof(p)               //4
sizeof(*p)              //1

char str[sizeof("hello")];//6,strlen("hello") = 5
strcpy(str,"hello");//赋值也必须有足够空间,不然错误

11. 度为4的树中,有度为4的节点20个,度为3的节点10个,度为2的节点1个,度为1的节点10个,求有多少个叶子节点
设N为总的节点数!总的入度=20*4+10*3+1*2+10*1=122=N-1,所以N=123。而N又=20+10+1+10+n(n为度为0的点,即叶子)即n=82


最大流算法。解题时,每找出一条路径算出流量后,该路径上各段线路上的流量应扣除已经算过的流量,形成剩余流量。剩余流量为0的线段应将其删除(断开)。这种做法比较简单直观。

17. 2^100 mod 7 = 2
2^100=2^99*2=8^33*2=(7+1)^33*2=(7^33+33*7^32+……+33*7+1)*2=2*7^33+2*33*7^32+……+2*33*7+2
前面的项都是7的倍数
最后是2
所以余数是2
18. 某公司在华东和华南两大区域开展业务,年底汇总业绩的时候发现,两大区域的月度客户转化率(=成为会员的客户数/访问店铺的客户数)分别提高了10%和5%,以下描述中正确的是       。 
A.尽管各自的月度转化率都有提高,但公司的整体月度转化率仍有可能降低 B.市场对业务认可度提高,越来越多访问店铺的客户成为会员 
C.华东区的客户更容易被转化,该公司应该把业务重点放在这个区域 D.华南区的客户更需要提高转化,该公司应该把业务重点放在这个区域
不会做
参考答案:B。

20. 某国家非常重男轻女,若一户人家生了一个女孩,便再要一个,直到生下男孩为止,假设生男生女概率相等,请问平均每户人家有       个女孩。

A. 0.5    B. 2/3     C. 1      D. 4/3

我用的概率做的  每户人家有女孩是一个期望值,S = 求和 i(1/2)^i,S -  2S  = (1/2)的等比数列,近似为1
停时是一个随机变量。你给定一个条件,让这个过程在某个时刻停下。这个停下的时间就是停时。
比如我要在时间t=5时停下,那么这个停时就永远是5。从概率论的角度来讲这个停时就是一个定义在trivial sigma algebra上的随机变量。
比如我要在这个过程达到10的时候停下,那么因为这个过程是随机的,所以这个停时也是个随机变量。因为这个过程在什么时候达到10是随机的。
但是要注意一个停时只能定义在在这个停时之前的时间所关联的sigma域上。比如你可以让一个过程在它第一次达到10的时候停下,这个时间是一个停时。但是你不能让一个过程在它最后一次达到10的时候停下。因为你永远不知道这一次停下是不是最后一次。因此它就不是一个停时。

停时定理就是说如果一个鞅满足特定条件(这些条件基本就是要求停时和过程本身almost surely bounded)那么这个鞅在任何停时的期望值等于它在零时刻的期望值

21. 以下有关C语言的说法中,错误的是       

A.内存泄露一般是只程序申请了一块内存,使用完后,没有及时将这块内存释放,从而导致程序占用大量内存。

B.无法通过malloc(size_t)函数调用申请超过该机器物理内存大小的内存块。

C. 无法通过内存释放函数free(void *)直接将某块已经使用完的物理内存直接归还给操作系统

D. 可以通过内存分配函数malloc(size_t)直接申请物理内存。

A:在 计算机科学 中, 内存泄漏 指由于疏忽或错误造成程序未能释放已经不再使用的 内存 。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。

B,C,D 虚拟内存的存在


22.下面关于二叉搜索树的正确说法包括——

A、待删除结点有左子树和右子树时,只能使用左子树的最大值结点替换待删除结点。

B、给定一棵二叉搜索树的前序和后序结果,无法确定这棵二叉树

C、给定一棵二叉搜索树,根据节点值大小排序所需时间复杂度是线性的

D、给定一棵二叉搜索树,可以在线性时间复杂度内转化为平衡二叉搜索树

A,C

23.被称为中国雨人的周玮,仅仅使用1分钟的时间就可以对16位数字开14次方。那么,以下数字钟,不可能成为其候选答案的是——

A11.0 B12.0C13.0D14.0E15.0

参考答案ADE。最小数字1000000000000000开14次方,得到11.7,最大数字9999999999999999开14次方,得到13.8。

25.某电子眼睛分辨率640*360;(省略一段废话)。蓝牙4.0最大带宽24Mbps,请问能否通过该技术将每秒50帧真彩(24bit)画面传输至它的屏幕。如果是,请说明原因,如果否,说明理论上大约多久才能传送一帧。

参考答案:不能,640*360*24*50=2.76*10^8>24*1024*1024=2.5*10^7

传输速率是指集线器的数据交换能力,也叫“带宽”,单位是Mbps(兆位/秒)


26.N条长度为M的有序链表进行合并,合并以后的链表也保持有序,时间复杂度为——M*logN

26题:不是M*N?26题当然是堆排序啊.

归并问题?两两归并,先1 2归并,3 4归并,在重复就可以了,时间复杂度是NMlog(N)。总共logN次归并每次NM,为NMlog(N)。

也可以用堆来做,结果一样,将N个链表头放入堆中,每次取出顶端节点插入,NM个元素都要进入堆堆排序复杂度是log(n)、而后取出堆中元素。入堆的是链表,不是每个元素。我的思路是,一般的堆排序,一般是每个元素是一个数字,这里是每个元素一个链表。当前的值是链表头。每次选出来一个值是log(N),一共N*M个数,故是M*NlogN。只是不同的做法而已...结果一样很正常啊。

我觉得可以理解成两两归并,两两归并,复杂度容易算。我觉得用堆要好理解些 ,更直接。


29.跳跃链表:(MIT麻省理工-算法导论公开课-12讲:跳跃表http://v.163.com/movie/2010/12/7/S/M6UTT5U0I_M6V2TTJ7S.html)

设当前在第i层第j列那个节点上。
i)如果第j列恰好只有i层(对应插入这个元素时第i次调用随机化模块时所产生的B决策,概率为1-p),则当前这个位置必然是从左方的某个节点向右跳过来的。
ii)如果第j列的层数大于i(对应插入这个元素时第i次调用随机化模块时所产生的A决策,概率为p),则当前这个位置必然是从上方跳下来的。(不可能从左方来,否则在以前就已经跳到当前节点上方的节点了,不会跳到当前节点左方的节点)
设C(k)为向上跳k层的期望步数(包括横向跳跃)
有:
C(0) = 0
C(k) = (1-p)(1+向左跳跃之后的步数)+p(1+向上跳跃之后的步数)
     = (1-p)(1+C(k)) + p(1+C(k-1))
C(k) = 1/p + C(k-1)
C(k) = k/p
    而跳跃表的高度又是logn级别的,故查找的复杂度也为logn级别




微软

1.死锁的条件:

1.互斥资源 2.不可剥夺 3.环路等待 4.请求与保持

1.mutual exclusion, 2.No preemption,4.hold and wait


2.TCP avoid congestion collapse:

A.Slow-start 

B.sliding window

C.fast retransmit

D.fast recovery

慢开始,拥塞窗口,快重传,快恢复


5. 20^13 mod 7 = 20^12*20 = (21-1)^12*20 , 6


7.28.5625 -》四进制 

每次将小数部分乘以对应的进制,相应的整数部分就是对应的数字
小数部分一直乘以4,直到小数部分为0结束
比如此例,整数部分就不说了,小数部分是:
0.5625 * 4 = 2.25                // (0.2)4            // 整数部分为2,第一位小数就是2
0.25 * 4 = 1                         // (0.21)4          // 整数部分为1,第二位小数就是1

(0.5625)10 = (0.21)4

测试名称

测试内容

Black box黑盒测试

把软件系统当作一个“黑箱”,无法了解或使用系统的内部结构及知识。从软件的行为,而不是内部结构出发来设计测试.

White box白盒测试

设计者可以看到软件系统的内部结构,并且使用软件的内部知识来指导测试数据及方法的选择。

Gray box.  灰盒测试

介于黑盒和白盒之间

 

总结:   实际工作中,对系统的了解越多越好。目前大多数的测试人员都是做黑盒测试,很少有做白盒测试的。 因为白盒测试对软件测试人员的要求非常高,需要有很多编程经验。做.NET程序的白盒测试你要能看得懂.NET代码。做JAVA程序的测试,需要你能看懂JAVA的代码。 如果你都能看懂了,你还会做测试么


10.同一台机器上的进程怎样分享一个数据最高效

A.memory mapped file

B.Socket

C.semaphore

D.file

E.signal

C??

1   文件映射
  文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容。文件映射是在多个进程间共享数据的非常有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中,而开发者还必须控制进程间的同步。

2  共享内存
  Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替文件句柄(HANDLE),就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射对象就可以访问该内存块。由于共享内存是用文件映射实现的,所以它也有较好的安全性,也只能运行于同一计算机上的进程之间。

3  匿名管道
  管道(Pipe)是一种具有两个端点的通信通道:有一端句柄的进程可以和有另一端句柄的进程通信。管道可以是单向-一端是只读的,另一端点是只写的;也可以是双向的一管道的两端点既可读也可写。
  匿名管道(Anonymous Pipe)是 在父进程和子进程之间,或同一父进程的两个子进程之间传输数据的无名字的单向管道。通常由父进程创建管道,然后由要通信的子进程继承通道的读端点句柄或写 端点句柄,然后实现通信。父进程还可以建立两个或更多个继承匿名管道读和写句柄的子进程。这些子进程可以使用管道直接通信,不需要通过父进程。
  匿名管道是单机上实现子进程标准I/O重定向的有效方法,它不能在网上使用,也不能用于两个不相关的进程之间。
4  命名管道
  命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。
  命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。

9 动态连接库
  Win32动态连接库(DLL)中的全局数据可以被调用DLL的所有进程共享,这就又给进程间通信开辟了一条新的途径,当然访问时要注意同步问题。
  虽然可以通过DLL进行进程间数据共享,但从数据安全的角度考虑,我们并不提倡这种方法,使用带有访问权限控制的共享内存的方法更好一些。

12 Sockets
  Windows Sockets规范是以U.C.Berkeley大学BSD UNIX中流行的Socket接口为范例定义的一套Windows下的网络编程接口。除了Berkeley Socket原有的库函数以外,还扩展了一组针对Windows的函数,使程序员可以充分利用Windows的消息机制进行编程。
  现在通过Sockets实现进程通信的网络应用越来越多,这主要的原因是Sockets的跨平台性要比其它IPC机制好得多,另外WinSock 2.0不仅支持TCP/IP协议,而且还支持其它协议(如IPX)。Sockets的唯一缺点是它支持的是底层通信操作,这使得在单机的进程间进行简单数据传递不太方便,这时使用下面将介绍的WM_COPYDATA消息将更合适些。

Linux下的进程间通信机制大致包括:管道、信号(在Windows上成为消息)、信号队列(实际是消息链表)、共享内存、信号量、套接字。

 

共同点

 由上面的分析可以看出两个操作系统共有的且用的较多的进程间通信机制有:管道、消息、共享内存和套接字。简介如下:

  管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

   信号或者消息(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身。

   共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

   套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。


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




临界区(Critical Section)(同一个进程内,实现互斥)
===================================
保证在某一时刻只有一个线程能访问数据的简便办法。在任意时刻只允许一个线程对共享资源进行访问。如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。




互斥量(Mutex)(可以跨进程,实现互斥)
===================================
互斥量跟临界区很相似,只有拥有互斥对象的线程才具有访问资源的权限,由于互斥对象只有一个,因此就决定了任何情况下此共享资源都不会同时被多个线程所访问。当前占据资源的线程在任务处理完后应将拥有的互斥对象交出,以便其他线程在获得后得以访问资源。互斥量比临界区复杂。因为使用互斥不仅仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。
互斥量与临界区的作用非常相似,但互斥量是可以命名的,也就是说它可以跨越进程使用。所以创建互斥量需要的资源更多,所以如果只为了在进程内部是用的话使用临界区会带来速度上的优势并能够减少资源占用量。




信号量(Semaphores)(主要是实现同步,可以跨进程)
===================================
信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目,不能在允许其他线程的进入,此时的信号量信号将无法发出




事件(Event)(实现同步,可以跨进程)
===================================
事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。

11.数据库外键

12.编译器从源文件产生可执行二进制文件的过程

C语言编译全过程


    编译的概念:编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。
    编译的完整过程:C源程序-->预编译处理(.c)-->编译、优化程序(.s、.asm)-->汇编程序(.obj、.o、.a、.ko)-->链接程序(.exe、.elf、.axf等)


14.c++的构造函数

注意点:

A.转换构造函数(conversion constructor)
可用单个实参调用的非explicit构造函数。隐式使用转换构造函数将实参的类型转换为类类型。
B.编译器生成的默认拷贝构造函数,实现的是浅拷贝
C.只要程序员自定义了一个构造函数,编译器都不会再生成默认构造函数
D.从一个构造函数去调用另一个构造函数,可以避免代码重复,是好的(错误)
题目如下:问下列代码的打印结果为0吗?

#include <stdlib.h>
#include 
<iostream>
using namespace  std;

struct
 CLS
{
    
int
 m_i;
    CLS( 
int
 i ) : m_i(i){}
    CLS()
    {
        CLS(
0
);
    }
};
int
 main()
{
    CLS obj;
    cout 
<< obj.m_i <<
 endl;

    system(
"PAUSE"
);
    
return 0
;
}
打印结果是不定的,不一定为0

代码奇怪的地方在于构造函数中调用了自己的另一个构造函数

我们知道,当定义一个对象时,会按顺序做2件事情:
1)分配好内存(非静态数据成员是未初始化的)
2)调用构造函数(构造函数的本意就是初始化非静态数据成员)

显然上面代码中,CLS obj;这里已经为obj分配了内存,然后调用默认构造函数,但是默认构造函数还未执行完,却调用了另一个构造函数,这样相当于产生了一个匿名的临时CLS对象,它调用CLS(int)构造函数,将这个匿名临时对象自己的数据成员m_i初始化为0;但是obj的数据成员并没有得到初始化。于是obj的m_i是未初始化的,因此其值也是不确定的

从这里,我们归纳如下:
1)在c++里,由于构造函数允许有默认参数,使得这种构造函数调用构造函数来重用代码的需求大为减少
2)如果仅仅为了一个构造函数重用另一个构造函数的代码,那么完全可以把构造函数中的公共部分抽取出来定义一个成员函数(推荐为private),然后在每个需要这个代码的构造函数中调用该函数即可
3)偶尔我们还是希望在类的构造函数里调用另一个构造函数,可以按下面方式做:
在构造函数里调用另一个构造函数的关键是让第二个构造函数在第一次分配好的内存上执行,而不是分配新的内存,这个可以用标准库的placement new做到:

    先看看标准库中placement new的定义

inline void *__cdecl operator new(size_t, void * _P)
{
    
return
 (_P); 

可见没有分配新的内存。

正确的方式:

struct  CLS
{
    
int
 m_i;
    CLS( 
int
 i ) : m_i(i){}
    CLS()
    {
        
new (this)CLS(0
);
    }
};

 


另: 若构造函数调用自身,则会出现无限递归调用,是不允许的


15. In a multiple-thread process ???
A. When one thread crashes, the other won't be affected
B. One thread can't share memory with other threads
C. Process to process communication is required between different threads
D. All threads share the same address space

趋势
1.SQL join

首先都是基于cross join(笛卡尔乘积),然后是inner join,在笛卡尔乘积的结果集中去掉不符合连接条件的行。

left outer join 是在inner join的结果集上加上左表中没被选上的行,行的右表部分每个字段都用NUll填充。

right outer join 是在inner join的结果集上加上右表中没被选上的行,行的左表部分全用NULL填充。


2.网络层的协议 RIP BGP都是网关协议
3.子网掩码,c类分给7个公司。。。。??
4.可以解决IP地址不足的措施???
VLSM, CIDR, NAT, IPV6
5. LRU是Least Recently Used的缩写,即最近最少使用页面置换算法
9.具体的黑盒测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法、场景法等。
11. web安全中xss的全称是:XSS 全称(Cross Site Scripting) 跨站脚本攻击, 是Web程序中最常见的漏洞。
12.c++中不能被重载的运算符
算术运算符:+,-,*,/,%,++,--;
位操作运算符:&,|,~,^(位异或),<<(左移),>>(右移)
逻辑运算符:!,&&,||;
比较运算符:<,>,>=,<=,==,!=;
赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;
其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*。 

不能重载的5个运算符
.  
?: 
siezof 
::     
.*     
15. 构造函数 ,是一种特殊的方法 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值