百度质量部测试开发面试题可萌

附件1的19-21页是一个模拟的面试场景,其中有不少经典题型和问题。不过已经在网上广为流传,建议了解其中面试思路为主,题目不要照搬太多。

答:白盒测试:逻辑覆盖法,主要包括语句覆盖,判断覆盖,条件覆盖,判断条件覆盖,条件组合覆盖、路径覆盖。

黑盒测试:等价划分类,边界值分析,错误推测法等

答:静态方法是指不运行被测程序本身,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性。对需求规格说明书、软件设计说明书、源程序做结构分析、流程图分析、符号执行来找错。静态方法通过程序静态特性的分析,找出欠缺和可疑之处,例如不匹配的参数、不适当的循环嵌套和分支嵌套、不允许的递归、未使用过的变量、空指针的引用和可疑的计算等。静态测试结果可用于进一步的查错,并为测试用例选取提供指导。

动态方法是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能,这种方法由三部分组成:构造测试实例、执行程序、分析程序的输出结果。所谓软件的动态测试,就是通过运行软件来检验软件的动态行为和运行结果的正确性。目前,动态测试也是公司的测试工作的主要方式。根据动态测试在软件开发过程中所处的阶段和作用,动态测试可分为如下几个步骤:1、单元测试2、集成测试3、系统测试4、验收测试5、回归测试。

答:等价类分为以下几类:

答:优点:考虑了单个数据域的各类情况,避免盲目或随机的选取输入数据的不完整性和不稳定性,同时可有效控制测试设计的数量。

缺点:对组合情况考虑不足,同时等价类划分基于等价类中的输入都能产生相同的效果,在很多情况下用例选择不当会产生问题(如边界)。

答:长期的测试工作经验告诉我们,大量的错误是发生在输入或输出范围的边界上,而不是发生在输入输出范围的内部。因此针对各种边界情况设计测试用例,可以查出更多的错误。

不过边界值分析法与等价类划分法一样,没有考虑输入之间的组合情况,因此需要进一步结合其他测试用例设计方法。

答:等价类划分的原则如下:

加分点:新旧版本对比,性能瓶颈分析方法(雪崩、线性拐点等)。

答:常见的软件测试模型包括V模型、W模型、H模型、X模型和前置模型。([注]:具体解释太长了,见附件1的前几页。)

题目:一个程序需要根据配置文件,将本地的多个文件(model.0,model.1,model.2…)分发到不同机房的不同机器上去。其中,配置文件格式如下:

#机房数量

SITE_NUM:5

#第0个机房机器数量

SITE_0_HOST_NUM:10

#该机房第n个机器的ip

SITE_0_HOST_0:192.168.0.1

SITE_0_HOST_1:192.168.0.2

。。。

SITE_0_HOST_9:192.168.0.10

SITE_1_HOST_NUM:10

SITE_1_HOST_0:192.168.1.1

SITE_1_HOST_1:192.168.1.2

#文件数量

MODEL_NUM:5

#第n个文件在第m个机房需要的备份数

MODEL_0_REP_NUM:0:3,1:3,2:3,3:3:4:3

MODEL_1_REP_NUM:0:3,1:3,2:3,3:3:4:3

MODEL_2_REP_NUM:0:3,1:3,2:3,3:3:4:3

MODEL_3_REP_NUM:0:3,1:3,2:3,3:3:4:3

MODEL_4_REP_NUM:0:3,1:3,2:3,3:3:4:3

分发要求:一台机器上不能布置多份相同的文件

每台机器上要求分发的文件数量尽量均匀

问题:请设计测试用例。

答:各种边界值;不同机器的IP重复;在某机房的需要的备份数超过了机器数;

答:冒烟测试:速度装一杯水,是否漏水

功能测试:漏水测试,透明度测试,卫生情况测试,杯口平滑测试,重量测试,均匀度测试

压力测试:抗摔测试,抗高温测试

欢迎添加

答:基本情况;边界值;鲁棒性;性能以及其算法优化;

题目:设有一个档案管理系统,要求用户输入以年月表示的日期。假设日期限定在1990年1月~2049年12月,并规定日期由6位数字字符组成,前4位表示年,后2位表示月。

问题:现用等价类划分法设计测试用例,来测试程序的"日期检查功能"。

答:

输入等价类

有效等价类

无效等价类

日期的类型及长度

6位数字字符

有非数字字符

少于6位数字字符

多于6位数字字符

年份范围

在1990~2049之间

小于1990

大于2049

月份范围

在01~12之间

等于00

大于12

测试数据期望结果覆盖的有效等价类

200211输入有效①、⑤、⑧

为每一个无效等价类设计一个测试用例,设计结果如下:

测试数据期望结果覆盖的无效等价类

95June无效输入②

20036无效输入③

2001006无效输入④

198912无效输入⑥

200401无效输入⑦

200100无效输入⑨

200113无效输入⑩

答:主要从异常、功能和性能三方面考虑:

参数异常:源和目标参数异常:包含特殊字符;参数超长;指定的位置实际不存在

拷贝对象异常:非法的执行权限;存储介质有损坏;非法的文件格式和内容

执行过程异常:拷贝到一半断电;拷贝过程中硬盘满;拷贝过程中源或目的被删除

不同文件大小:0,1k,10k。。。

不同的文件类型:文本,二进制,设备文件。。。

包含各种文件类型

包含子目录,目录深度

目录文件数量很多

针对文件和目录分别验证拷贝的准确性,完整性。

拷贝大文件

拷贝目录中存在大量小文件

跨文件系统间拷贝

跨存储介质间拷贝(硬盘到U盘。。。)

构造源的各种磁盘分布(磁盘扇区分布。。。)

并发执行拷贝

题目:百度首页是由模板展现,请问如何对它进行测试;

(考察点:测试能力+思维系统性+思维发散性)

展现检查:文字图片内容,链接,一致性

数据传递:字符串长短与截断;特殊字符;中英文;空格;下拉条提示

兼容性检查:不同浏览器,不同操作系统,不同分辨率

用户行为:窗口拉大,放小;字号大小;编码格式;刷新;前进后退

题目:本流程图描述了某子程序的处理流程,现要求用白盒测试法对子程序进行测试。

要求:根据白盒测试常用的以下几种方式:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、多重条件覆盖(条件组合覆盖)、路径覆盖六种覆盖标准,从供选择的答案中分别找出满足相应覆盖标准的最小的测试数据组并简述各种测试方法。

供选择的答案

x=3y=3z=0;x=1y=2z=1

x=1y=2z=0;x=2y=1z=1

x=4y=2z=0;x=3y=3z=0;x=2y=1z=0;x=1y=1z=1

x=4y=2z=0;x=1y=2z=1;x=2y=1z=0;x=1y=1z=1

x=4y=2z=0

x=4y=2z=0;x=1y=1z=1

参考答案:

问题:请给出BAIDUhi聊天消息收发的测试思路?(10分钟)

(考察点:基本测试思路)

参考答案:主要从以下几个方面来考察:正常测试、异常测试、不同的消息类型、组合测试、长度极值、是否延迟、是否丢失、是否被篡改、安全性

参考答案:希望可以对测试点做分类划分,如功能、UI、性能、安全

题目:测试自动贩卖机,场景:贩卖机将用在露天的繁华的大街上

(考察点:主要考察逻辑思维、思维的发散性)

参考答案:

大概可以从以下几个方面来考虑:

题目:一个程序,从输入框中读取三个整数值,这三个数值代表了三角形三边的长度。程序显示提示信息,指出该三角形究竟是不规则三角形、等腰三角形还是等边三角形。(注:不规则三角形指三角形中任意两边不相等,等腰三角形指有两条边相等,等边三角形指三条边相等)

要求:假设你将作为一名测试工程师对该程序进行测试,你会采用什么方法进行测试用例设计?请写出你采用的方法、测试用例设计的过程以及最后的测试用例。(30分钟)

(考查点:考察测试思维的严谨性,答全难)

参考答案:可以采用等价类划分的方法进行测试用例的设计。

输入条件

是否三角形的三条边

⑴A>0

⑺A<=0

⑵B>0

⑻B<=0

⑶C>0

⑼C<=0

⑷A+B>C

⑽A+B<=C

⑸B+C>A

⑾B+C<=A

⑹A+C>B

⑿A+C<=B

是否等腰三角形

⒀A=B

⒃A!=B&&B!=C&&C!=A

⒁B=C

⒂C=A

是否等边三角形

⒄A=B&&B=C&&C=A

⒅A!=B

⒆B!=C

⒇C!=A

序号

[A,B,C]

覆盖等价类

输出

1

[3,4,5]

⑴⑵⑶⑷⑸⑹

一般三角形

2

[0,1,2]

不能构成三角形

3

[1,0,2]

4

[1,2,0]

5

[1,2,3]

6

[1,3,2]

7

[3,1,2]

8

[3,3,4]

⑴⑵⑶⑷⑸⑹⒀

等腰三角形

9

[3,4,4]

⑴⑵⑶⑷⑸⑹⒁

10

[3,4,3]

⑴⑵⑶⑷⑸⑹⒂

11

⑴⑵⑶⑷⑸⑹⒃

非等腰三角形

12

[3,3,3]

⑴⑵⑶⑷⑸⑹⒄

等边三角形

13

⑴⑵⑶⑷⑸⑹⒁⒅

非等边三角形

14

⑴⑵⑶⑷⑸⑹⒂⒆

15

⑶⑷⑸⑹⒀⒇

a)手机号码:以13开头,长度为11的连续数字

d)一次输入中如果有多个正确号码(空格为分割符),以最后一个正确号码的类型为准

对实现上述功能的程序设计测试用例。(40分钟)

区号范围(x表示任意数字):

3位区号

4位区号

03××

20

04××

21

05××

22

06××

23

07××

24

08××

25

09××

27

28

29

参考答案:以下是测试设计的参考思路:

有空格

空格在两头

中间无字符

空格在中间

一个空格

最后一个为错误手机号

全部为错误手机号

最后一个为正确手机号

多个空格

第一个为正确手机号

超长字符含空格

无空格

只含数字

以0开头

前三位是区号

区号识别

前三位非区号

前四位为区号

前四位非区号

非0开头

13开头

长度为11

长度非11

座机号码

非座机号码

非13开头

座机号码识别

含数字和-

一个-

-前是区号

-后为座机

-后非座机

-前非区号

多个-

含其他字符

超长字符不含空格

空输入

座机识别

首位为0

长度为6

所有数字均能被识别??

长度为7

长度为5

长度为8

首位非0

三位长度

010开头

02开头

026开头

非026

非010、02开头

011开头

030开头

四位长度

03-09开头

01

02

Divide:把长度为n的输入序列分成两个长度为n/2的子序列。

Conquer:对这两个子序列分别采用归并排序。

Combine:将两个排序好的子序列合并成一个最终的排序序列。

最坏情况:当每次pivot选择恰好都把列表元素分成了(1,n-1)

采取措施:pivot的选取是通过random来进行

选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。

单向链表有交点意思是交点后的节点都是一样的;因此,如果两个单向链表相交,是成Y字形的。

思路:求出第一个链表长m,第二个长n。假设m>=n,那么就去掉第一个链表的前m-n个元素,使之等长,然后依次比较第一个、第二个、第三个元素,直到找到或者结束。

NODE*FindNode(NODE*pHead1,NODE*pHead2)

{

NODE*p1=pHead1;

NODE*p2=pHead2;

inti=1,j=1,k=0,f=0;

if(pHead2==NULL||pHead2==NULL)

returnNULL;

}

while(p1->next!=NULL)

p1=p1->next;

i++;

while(p2->next!=NULL)

p2=p2->next;

j++;

if(p1!=p2)

returnNULL;//如果尾节点不同,直接返回NULL

else//否则寻找第一个相同的节点

p1=pHead1;//1

p2=pHead2;//2

f=fabs(i,j);//计算两条链表长度的差

if(i>j)//如果第一个链表比第二个长,第一个链表先向前移动f步

for(k=0;k

while(p1!=p2)

returnp1;

else

先放置几个队列:

L1:3^i(i>=0)

L2:3^i*5^j(j>=1)

L3:3^i*5^j*7^k(k>=1)

Step1:清空三个队列、分别把3,5,7放入三个队列的首位。准备一个新队列L(目前为空)。

Step2:比较三个队列的头,找出最小的那个。把这个元素从队列出队,并加到L的尾部。

Step3:

如果Step2中的元素是从L1中获取的,假设是3^m,则在L1的尾部加入3^(m+1),L2的尾部加入3^m*5,L3的尾部加入3^m*7。

如果Step2中的元素是从L2中获取的,假设是3^m*5^n,则在L2的尾部加入3^m*5^(n+1),L3的尾部加入3^m*5^n*7。

如果Step3中的元素是从L3中获取的,假设是3^m*5^n*7^p,则在L3的尾部加入3^m*5^n*7^(p+1)。

Step4:L的长度到达N了吗?如果没到达,重复L2-L4。如果到达,则进行L5。

Step5:取得L的末尾元素,即为所求。

A

/\

B----->C

//\

E----->F->G

buildRightSibling(Linkedlistlist)

Linkedlistnextlevel=newLinkedlist();

把list中的每个元素的子节点,放入nextlevel中。

//对list中每个元素,设置右邻结点,指向list中的下一个元素

//这一步可以在链表中就实现掉。

If(nextlevel==null||nextlevel.length()==0)

Return;

Else

buildRightSibling(nextlevel);

//启动函数

buildRightSibling(newLinkedlist(root));

层序遍历每一层,对每一个元素都打上标记。比如(1,1)代表第1层第1个元素。

所有元素都打上标记以后,对每个元素(m,n)都寻找(m,n+1)元素

初始:f(0)=0;f(1)=1;f(2)=1+1=2;

递推公式:f(n)=f(n-1)+f(n-2)+f(n-3)

题目:2进制除了0,1,还可以用2表示。例如:

1->1

2->10or02

3->11

4->100or020or012

问题:这样一个十进制数转为二进制数,就不是唯一的了。现求十进制数N转换为这种二进制数的所有表示方法数。

f(0)=1,f(1)=1,f(2)=2,

f(n)=f((n-1)/2)当n为奇数

=f(n/2)+f((n-2)/2)当n为偶数

设两个指针走的次数为x,使用简单的数学公式即可证明。难度1面。考察基本的数学知识。

设链表有m个元素,head1在第一次相遇时走了n步,c为head1和head2第一次相遇的节点距离出发节点的距离。

则:head1走过的路程为c=n;

head2走过的路程为c+k*m=2n;(k为整数)

因此,c=k*m,即c恰好是链表长度的整数倍,即两个指针第一次相遇一定是在出发的节点。

让两个指针head1和head2从同一个节点出发,head1每次走一步,head2每次走两步,当二者重合时,让head2回到链表的头部,以每次一步的步长走,当head1和head2再次相遇时,就是环路的起始节点了。

(考察点:该数出现次数超过其他所有数出现次数总和,使用计数方式解答。难度:2面)

解法1:开一个新的列

比较第1,2个数字。如果相同,则放入新的列中如果不同,则两个都丢弃

然后比较第3,4个数字,5,6个数字

这个时候新的列最长为n/2(实际上会远远更短)

然后对新的列如法炮制再次缩短一半

当某个时刻列的长度是1或者列突然消失时候结束

长度为1说明这个就是的。消失,说明不存在大于n/2的个数的数

解法2:

构造一个hashtable,其中key是这个N个数的值,而value则是他们出现的次数;

最后遍历这个hashtable,找出最大的即可。[ZhaiYao:这个方法应该不好。不应该使用hashtable]

环形的拼成2n的数组后求解。

最长连续子序列之和:扫描数组,从左到右记录当前子序列的和ThisSum,若这个和不断增加,那么最大子序列的和MaxSum也不断增加(不断更新MaxSum)。如果往前扫描中遇到负数,那么当前子序列的和将会减小。此时ThisSum将会小于MaxSum,当然MaxSum也就不更新。如果ThisSum降到0时,说明前面已经扫描的那一段就可以抛弃了,这时将ThisSum置为0。然后,ThisSum将从后面开始将这个子段进行分析,若有比当前MaxSum大的子段,继续更新MaxSum。这样一趟扫描结果也就出来了。

和最接近0的子序列:【标记】

环形数组的最大子序列之和:将环形数组首尾拼接成一个2n的线型数组(如环形数组012,可以拼接成012012),按1)的方法可以找到最大连续子序列之和

题目要求:

(1)不是用排序库函数;

(2)代码实现;

(3)算法复杂度估算;

(4)测试自己的代码;

(5)能否用另一种排序方式,比较优缺点;(plus)

1.char*sort(char*a){

inti,j;

chartmp;

for(i=0;a[i]!='\0';i++){

for(j=i+1;a[j]!='\0';j++){

if(a[i]>a[j]){

tmp=a[i];

a[i]=a[j];

a[j]=tmp;

2.算法复杂度:输入为一个n个字符的字符串,则复杂度为O()

3.另一种排序算法:快排,复杂度O(nlgn)[ZHAIYAO:可不可以用另一种方式?开一个26长的数组,记录每个字母出现的次数。然后根据这个记录,重新打印(构造)出来排序后的字符串]

例如:给定数组为10237135275041

排序后的结果为:17102327354150

相邻两数的最大间隔为13(10-23)。

遍历找到数列找到最大最小值(max,min),则所求的gap>=(max-min)/n,以(max-min)/n为步长建立k个桶,每个桶记录落入桶内的最大最小值,顺序比较各个桶之间的最大gap。

用基于桶排序的方式,具体如下:

先找到最小和最大,分别记为min和max,并设avg=(max-min)/n

按照avg的大小将[min,max]分配(N-1)个桶

将数组中的数存入桶中

然后按顺序对每个相邻桶(跳过没有数的桶)进行比较,如相邻桶(a,b)(c,d)的距离D=c-b

最终比较D的最大值,则为所求

题目:设a[0..n-1]和b[0..n-1]是两个已经排好序的数组,设计一个算法,找出a和b的2n个数的中位数。要求给出算法复杂度(O(lgn))。

设a[0..n-1]的中位数是m1,b[0..n-1]的中位数为m2

如果m1=m2,则m1则为2n个数的中位数

如果m1>m2,则2n个数的中位数一定在a[0..2/n]和b[n/2..n],在求这两个子数组的中位数

如果m1

如果n=2k,则C(k)=

如果n=2k+1,则C(k)=

全排序算法就是列举一些字符的所有排列顺序。

voidPerm(charlist[],intk,intm)

{//生成list[k:m]的所有排列方式

inti;

if(k==m){//输出一个排列方式

for(i=0;i<=m;i++)

putchar(list[i]);

putchar('\n');

else//list[k:m]有多个排列方式

//递归地产生这些排列方式

for(i=k;i<=m;i++){

Swap(&list[k],&list[i]);

Perm(list,k+1,m);

在多线程编程中,对临界资源,经常需要lock(),unlock()这样的操作,但是经常在lock之后忘记unlock,造成多线程问题。现在用C++类的思想实现一个scopelock类(校招)

例如:

lock()

……

unlock()

这种使用模式变成

Scopelock()

(在构造函数和虚构函数中实现lock和unlock)

题目:Spider抓取能力一天10w个url,互联网每天新增1000w个url(社招)

这1000w个都是新增的url,spider怎么选取10w个进行抓取,选优的准则

这1000w个有些是抓取过的,存在历史抓取信息,spider怎么选取10w个进行抓取,选优的准则。

在获取URL的时候按照一定数量分组,然后分别在每组用URL的sign作为key,用awk以key为标来构造数组;最后把每组过滤过的结果在merge起来过滤。

答:sort|uniq-c|sort-nr|head

题目:有十路数组,数组元素组成为:{intid,unsignedintweight},每路数组内id、weight均为无序

要求:如何求出这十路数组的交集(交集:id相同),并将交集内的元素按照weight排序?给出思路和复杂度;如果原始的十路数组中的id均为有序的,又该如何做?给出思路和复杂度;

题目:dog和god这类字母出现的次数和种类都完全一样的字符串称为兄弟单词,现在有海量的字符串,设计检索系统,支持查找用户输入字符串的所有兄弟单词。

题目:互联网上每天有大量的网页成为死链,如何用最小的代价降低搜索引擎的死链率。

参考答案:发散问题,常见输入法错误、缺字多字编辑距离判断,用户session挖掘等等

方法A:

方法B:

答:5只猫

答:27/53

答:赚20元

答:12天

1.列出2个已知方程和一个求解方程,给分

2.算出答案,给分假设牧场的草为1单位,每天生长x单位,每个牛每天吃y单位

27y*6-6x=1

23y*9-9x=1

解得:y=1/72,x=15/72[得一半分]

21头牛,就是1/(21y-x)=12天[得满分]

【4人时候,答案是9/24。9种可能分别是2143,4123,3142,3412,4312,2413,4321,3421,2341)】

【n人时候,解法如下】

解法1:

n人时候,运用容斥原理的高级形式求解。【想到容斥原理就给出一半分数】

zhaiyao:本科的离散数学课程,本帽子题目是一个例题。我做助教的时候背熟了。。。

设人站成一排,第1个的帽子设为帽子1,第i的人的帽子设为帽子i。

设帽子i戴在人i的头上(其他人无所谓)的情况数为Ai

那么很明显有|Ai|=(n-1)!;

i和j同时带对(不考虑其他人对不对)情况是|Ai∩Aj|=(n-2)!;

i和j,k同时带对(不考虑其他人对不对)|Ai∩Aj∩Ak|=(n-3)!

问题问没有一个人带对帽子,问题的反面就是问“存在至少一个人戴对帽子”

“存在至少一个人戴对帽子”的情况数为:|A1∪A2∪...∪An|

根据容斥原理,

|A1∪A2∪...∪An|=(|A1|+|A2|+…+|An|)-(|A1∩A2|+|A1∩A3|)+(|A1∩A2∩A3|+)-….(参见容斥原理)

=n*(n-1)!-C(n,2)*(n-2)!+C(n,3)*(n-3)!-...+(-1)^(n-1)*C(n,n)*0!

=n!(1/1!-1/2!+...+(-1)^(n-1)*1/n!)

所以都带错的情况是:

n!-n!(1/1!-1/2!+...+(-1)^(n-1)*1/n!)

=n!*(1-1/1!+1/2!+...+(-1)^n*1/n!)

概率是1-1/1!+1/2!-...+(-1)^(n-1)*1/n!

=1/2!-...+(-1)^(n-1)*1/n!【得到答案得到全部分数】

形象点就是:

2个人:1/2!

3个人:1/2!–1/3!

4个人:1/2!–1/3!+1/4!(不是4/24,而是9/24。)

5个人:1/2!–1/3!+1/4!–1/5!

6个人:1/2!–1/3!+1/4!–1/5!+1/6!

人肉写出n=2,3,4的情况。然后进行数列规律解析,猜测出来最终表达式1/2!-...+(-1)^(n-1)*1/n!。

【如果只能列出n=2,3,4等情况,建议不给分,因为这个思路很容易想。

但是能够找到规律并猜测出表达式,建议给三分之二或者四分之三的分数。因为这个数列规律很不好找。但是这种思路一定不给满分,因为没有严格的推理过程】

甲乙丙每人花了1.8元,但丁坐车没有花4角(丁自己没有钱),甲乙丙花的钱里面,已经包含了丁的钱

这题无法根据中间过程给分,不推荐

【ZhaiYao:这题有点混淆概念,可以看出来一个人在混乱时候脑子能不能反应过来,分析清楚各种关系。解释清楚就得满分,否则不得分】

答:34

1.根据第2块图形填入的个数分类讨论(或其他方式分类讨论),给分

2.回答对答案,给分

[追问:对2*n的情况,有多少种?递推关系:n=1或者2,有1种;否则,f(n)=f(n-1)+f(n-2),斐波拉契数列]

答:3条

1.从1条病狗的情况开始分析,给三分之一的分

2.推广到3条病狗,给满分(需要解释,直接说3条,却解释不清楚的,不得分)

[追问:如果第x天传来一阵枪声,那么问一共有几条病狗?这天响了多少枪?]

由于题目的知名度较高,如果面试者很快答对,考虑不予计分

答:3121

1.从最后一只猴子开始考虑,给分

2.设最后一只猴子来的时候,桃子的数量为5x+1;第4只就为(5x+1)*(5/4)+1,给分

3.依次类推,得到第一只猴子来的时候,桃子的数量,给分

4.算出x的值,给分

[张一]:用递归的方式来做,很巧妙!设f(n)为第n次每只猴子的份数。则4f(n)=5f(n+1)+1

1.给出递归式,给分

2.化为等比数列,给分f(n)=a*(4/5)^n-1。

2.算出答案,

F(5)有意义,a最少为5^5,所以f(1)=5^4*4–1=624,总数为624*5+1=3121

给分

1.如果只有一顶红帽子,则红帽子的人当场就知道了,排除。给分

2.如果三顶都是红帽子,则无人能知道自己的颜色,因为他看到的另两顶都是红帽子。可以排除。给分

3.只能是2顶红帽子,1顶黑帽子。思路如下:A黒,BC红。3人都无法确定,回家苦思。B想:如果自己头上黒帽,则C立即知道头上是红帽,既然C不知道,则说明自己头上也是红帽。第二天猜出自己的帽子。C也是这样。A根据BC的表现,知道只有2顶红帽,自己头上是黒帽。给分。

面试者解释比较繁琐,不推荐。

【ZhaiYao:该题目面试者有自信的说出答案就可以给分,不需要面试者详细解释】

1.将比赛结果分为胜、平、负三种。给分

2.各射50箭时,三种结果的可能性为x,y,x;且x+y+x=100%。给分

3.A多射1箭,则原来获胜时,现在还是获胜;原来打平时,现在50%可能获胜;原来输时,现在不可能获胜。因此获胜的可能性为x+0.5y,正好等于50%。给分

注:如果面试者能以各射0箭,各射1箭等简单情况,推算出结果和原本的箭数无关,固定为50%,可以考虑给分。

解法1:假设一共生育x孩子。那么每次生育并不被其他事件所影响,所以男女孩子各半。1:1

解法2:数学建模。

解法3:设想极端情况:(1)大家都坚持只生一胎;(2)大家都一直生育,直到得到男孩为止;结论均为50%。所以推出一般情况下,也为50%

1.char*strcpy(char*strDest,constchar*strSrc){

if((strDest==NULL)||(strSrc==NULL))//[1]

throw"Invalidargument(s)";//[2]

char*strDestCopy=strDest;//[3]

while((*strDest++=*strSrc++)!='\0');//[4]

returnstrDestCopy;

2.为了实现链式返回

题目:voidmultiple(inta[],intb[],intc[]);//a,b为两个乘数,c为输出结果

如果写的比较快,再考察一下怎么测自己的代码

voidmultiply(inta[],intb[],intc[]){

inti,j,k;

inttmp;

for(i=0;i

k=i;

for(j=0;j

result[k++]+=a[i]*b[j];

for(k=c.size()-1;k>=0;--k){

if(result[k]>9){

if(k!=0){

c[k-1]+=c[k]/10;

c[k]%=10;

}else{

tmp=result[k]/10;

result[k]%=10;

result.insert(result.begin(),tmp);

题目:Thestrtok()functioncanbeusedtoparsethestringsintotokens.Thefirstcalltostrtok()shouldhavesasitsfirstargument.SubsequentcallsshouldhavethefirstargumentsettoNULL.Eachcallreturnsapointertothenexttoken,orNULLwhennomoretokensarefound.

char*mystrtok(char*s,constchar*delim)

staticchar*last;

char*tok;

char*ucdelim;

char*spanp;

intc,sc;

/**//*s为空,并且上次剩余值也为空,则直接返回NULL,否则s为last或当前值中有值的一方*/

if(s==NULL&&(s=last)==NULL)

intfound=0;//是否找到与delim匹配的字符

//处理连续的待匹配的字符

cont:

c=*s++;

for(spanp=(char*)delim;(sc=*spanp++)!=0;)

if(c==sc)

gotocont;

if(c==0)

last=NULL;

tok=s-1;

while(!found&&*s!='\0')

ucdelim=(char*)delim;

while(*ucdelim)

if(*s==*ucdelim)

found=1;

*s='\0';

last=s+1;

break;

ucdelim++;

if(!found)

s++;

if(*s=='\0')

returntok;

答:32bit下12;64bit下16

答:byteóunsignedchar=>a=-1;

要求:

考察点:

intc;//currentchar

intresult;

intsign;//if'-',negative;otherwisepositive;

/*skipthewhitespace*/

while(isspace(*s))

sign=(*s=='-')-1:1;

if(*s=='+'||*s=='-')//skipthesign

result=0;

while(isdigit(*s)){

result=10*result+(*s-'0');

returnsign*result;

char*strstr(constchar*s,constchar*find){

char*cp=s;

char*s1;

char*s2;

/*find="\0"*/

if(!*find)

returns;

while(*cp){

s1=cp;

s2=find;

while(*s1&&*s2&&!(*s1-*s2)){

s1++;

s2++;

if(!*s2)

returncp;

cp++;

单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。

1.Node定义:

typedefstructNode{

DataTypedata;

structnode*next;

}node;

2.add():在head增加一个节点

intadd(Node*head,DataTypeDataX){

//返回参数:0分配空间失败,1成功

NodeNodeAdd=newLinkList;

if(!NodeAdd)

return(0);

NodeAdd->data=DataX;

NodeAdd->Next=head->Next;

head->Next=NodeAdd;

return(1);

3.delete():删除指定节点

intdelete(Node*head,DataTypeDataX){

Node*p=head;

Node*s=p->next;

while(s!=NULL){

if(s->data!=Datax){

p=p->next;

s=s->next;

else{

p->next=s->next;

free(s);

return1;

return0;

4.retrieve():对所有节点进行“指定的函数操作”,“指定的函数操作”由用户输入;

voidretrieve(Node*head,void(*visit)(data)){

while(p!=NULL){

(*visit)(p->data);

说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”

1、#include"string.h"

2、main()

3、{

4、char*src="hello,world";

5、char*dest=NULL;

6、intlen=strlen(src);

7、dest=(char*)malloc(len);//分配len+1

8、char*d=dest;

9、char*s=src[len];//len-1

10、while(len--!=0)

11、d++=s--;

12、printf("%s",dest);//尾部要加\0

13、return0;//返回前要释放malloc的内存

14、}

voidMerge(int*p1,unsigneduCount1,int*p2,unsigneduCount2)

if(p1==NULL||p2==NULL||uCount1==0||uCount2==0)

return;

inti=0;

intj=0;

boolfSign=false;

while((i

if(p1[i]==p2[j])

if(!fSign)

printf("%d\n",p1[i]);

fSign=true;

++i;

elseif(p1[i]

fSign=false;

++j;

charstr[]=”hello”;

int*p=(int*)str;

*p=0x00313200;

printf("%s",str);

//提示0x31对应字符'1',0x32对应字符'2'。

答:返回空。”\0”

voidtest1()

charstring[10];

char*str1="0123456789";

strcpy(string,str1);

voidtest2()

charstring[10],str1[10];

for(i=0;i<10;i++)

str1[i]='a';

voidtest3(char*str1)

if(strlen(str1)<=10)

试题1字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;

试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string,str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;

对试题3,if(strlen(str1)<=10)应改为if(strlen(str1)<10),因为strlen的结果未统计’\0’所占用的1个字节。

intfunction(char*s1,char*s2)

while(s1[i]==s2[i]&&s2[i]!=0)i++;

return(s1[i]==0&&s2[i]==0);

功能——判断s2与s1是否内容一致

问题——没有判断参数为NULL的情况;当s1==s2的时候,函数应该直接返回true,不需要一个个去比较下去;

classmyclass

public:

//Constructor

myclass(strings):str(s)

cout<<"Constructing"<

//Destructor

~myclass()

cout<<"Destructing"<

stringgetValue()

returnstr;

private:

stringstr;

};

voiddisplay(myclasst)

cout<

myclassgetTest()

returnmyclass("Jun");

intmain()

myclasste=myclass("chenjq");

display(te);

getTest();

输出:

Constructing

chenjq

Destructing

重点:需要了解在按值传向函数,以及按值从函数返回的时候对象的构造、析构过程:

(1)将对象按值传给函数的时候,首先会创建该对象的一个副本,将这个副本传给函数,但是在创建这个副本的时候,不会调用构造函数,而在这个函数返回的时候会调用析构函数。

(2)函数按值返回对象的时候,也会创建返回对象的一个副本,同样的也不会调用构造函数,在返回后调用析构函数销毁该对象。

classmyclass{

myclass(unsignedintk):length(k){

content=(int*)malloc(sizeof(int)*k);

~myclass(){

if(content)free(content);

unsignedintlength;

int*content;

voidfunction()

myclassc1=100;

myclassc2=c1;

myclassc3;

myclassc4=200;

c4=c1;

void*p=newmyclass(100);

deletep;

Delete操作,由于p是void*类型,在free对象本身所占的内存空间之前,不会调用destructor,带造成content指针指向的内存区域的泄露。

#include

usingstd::cout;

classP

virtualvoidprint()

cout<<"P";

classQ:publicP

cout<<"Q";

P*p=newP;

Q*q=static_cast(p);

q->print();

cout<

q=newQ;

p=q;

p->print();

p=new(q)P;

p->~P();

deleteq;

inline函数:

定义:

用途:

引入它的主要原因是用它替代C中表达式形式的宏定义。

虚函数:

实现多态性,通过指向派生类的基类指针,访问派生类中同名覆盖成员函数。

虚函数是否可以实现成inline?

从狭义的角度来讲是不能的,因为虚函数是在运行期间决定如何调用,而inline函数实在编译期间决定是否inline。从广义的角度讲是可以的。参见《MoreExceptionalC++》第8条款,《ExceptionalC++Style》第25条款。

函数调用过程中,第一个进栈的是(主函数中的)调用处的下一条指令(即函数调用语句的下一条可执行语句)的地址;然后是函数的各个参数,而在大多数C/C++编译器中,在函数调用的过程中,函数的参数是由右向左入栈的;然后是函数内部的局部变量(注意static变量是不入栈的);在函数调用结束(函数运行结束)后,局部变量最先出栈,然后是参数,最后栈顶指针指向最开始存的指令地址,程序由该点继续运行。

函数调用方式决定了函数参数入栈的顺序,是由调用者函数还是被调用函数负责清除栈中的参数等问题,而函数名修饰规则决定了编译器使用何种名字修饰方式来区分不同的函数,如果函数之间的调用约定不匹配或者名字修饰不匹配就会产生以上的问题。

C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为:voidfoo(intx,inty);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。

C++的class具有数据封装功能,其包含属性访问级别可以为private,public和protect,还具有实现类接口功能和辅助功能的操作函数,而struct属性访问权限只有public,没有数据封装功能,也就没有实现信息隐藏这一面向对象的思想的机制,struct本身不含有操作函数,只有数据。

静态绑定:编译时绑定,通过对象调用

动态绑定:运行时绑定,通过地址实现

只有采用“指针->函数()”或“引用变量.函数()”的方式调用C++类中的虚函数才会执行动态绑定。对于C++中的非虚函数,因为其不具备动态绑定的特征,所以不管采用什么样的方式调用,都不会执行动态绑定。

多态(Polymorphism)是面向对象的核心概念,C++中多态可以分为基于继承和虚函数的动态多态以及基于模板的静态多态,

1)描述以下表示形式的意义:Char*q[]={“xxx”,“yyy”,“zzz”};

Char(*p)[]=a;

答:

前者:指针数组,q[0],q[1],q[2]都为char*类型的指针;

后者:数组指针,p指向一个char数组。

2)解释以下表示形式的意义:

A)"a"B)'\\'C)'W'D)’abc’

3)解释以下表示形式的意义及其作用:typedefint(*PFUN)(intx,inty);

答案:函数指针;

4)Callbyvalue、callbyreference和callbypointer的优缺点,举例说明各自的应用形式。

5)C++对象的copyconstructor与copyassignment的区别与联系,谈谈使用时的注意事项,列举它们应用的场景及。

copyconstructor:从一个已有的对象来构造另一个对象;包括:

将对象按值传递给函数作为参数;

函数按值返回对象。

copyassignment:将已有的对象赋值个另一个已有的对象;

实例:

PersonA(B);//copyconstructor

PersonC=B;//copyconstructor

Function1(D);//copyconstructor

B=Function2(…);//copyconstructor

PersonD;

D=B;//copyassignment

注意事项:编译器默认的copyconstructor和copyassignment操作,是按照member-wisecopy的方式逐个copy每个member,这种浅拷贝操作在有些情况下可能造成资源泄漏/指向重叠。

如果的确需要deepcopy,需要自定义相应操作。这时需要清楚哪些地方用了copyconstructor,哪些地方用了copyassignment,从而分别自定义copyconstructor和copyassignment。一般来说,自定义的copyconstructor、destructor和copyassignment操作常常同时出现。

区别与联系:

copyconstructor不用检测是否是用一个对象来初始化它自己;

copyconstructor不用对被构造对象做资源清理操作,如delete操作;

6)说明以下表达式的意义:TYPE*t=new(a)TYPETYPE;

答:Placementnew操作:在a指向的内存区域,调用defaultconstructor构造一个TYPE类型的对象,并返回该对象的指针。

7)解释以下表达式的区别:TYPEt与TYPE*PT=newTYPE;

答:TYPEt;从staticarea或者stack上分配内存,并调用defaultconstructor;

TYPE*PT=newTYPE;从堆上分配内存,并调用defaultconstructor;

1)Java多线程编程机制,线程类,互斥机制(synchronize)Java线程类:Thread,Runnable接口Java互斥:synchronize关键字wait和notify方法

但是,如果被同步的方法里面有一些代码是可以被共享的,而且这些能够被共享的代码里面存在比较耗时的操作时,仅仅使用synchronized关键字就无法达到最高的效率,这个时候可以使用wait与notify方法来对并发访问做更进一步的控制。

wait()方法表示,放弃当前对资源的占有权,等啊等啊,一直等到有人通知我,我才会运行后面的代码。notify()方法表示,当前的线程已经放弃对资源的占有,通知等待的线程来获得对资源的占有权,但是只有一个线程能够从wait状态中恢复,然后继续运行wait()后面的语句;notifyAll()方法表示,当前的线程已经放弃对资源的占有,通知所有的等待线程从wait()方法后的语句开始运行。

2)引用传递Java函数传递的是参数的引用深度拷贝:重写clone()

3)接口和抽象类的作用有什么区别

接口能够多重继承;抽象类只能继承一个;

接口只能定义常量;抽象类能够定义变量

接口的函数都是抽象的;抽象类的函数可以是非抽象的

接口implement,抽象extend

4)重载和覆写

重载时function(inti),function(inti,intj)。相同的函数名,不同的签名;重写是函数签名相同。但是子类的函数覆盖了父类的同名(签名)函数。

5)容器类型选择:ArrayList:随机访问好LinkedList:元素添加和移出(中心位置)HashSet:普遍性能都比TreeSet好TreeSet:保持内部元素的排序状态HashMap:Hashtable的替代品,一般性能都较好TreeMap:保持内部元素的排序状态

6)向上转型和向下转型向上安全,向下执行期检查:ClassCastException

7)多态继承,接口与多态的关系

1)是否写过多线程代码

2)线程间通信的方法

答:同一进程的各线程可以直接读写进程数据段进行通信,同时需要同步和互斥手段的辅助。而不同进程间的线程通信可以参考不同进程间的通信。

3)多线程同步方式(能答出几个就可以)

答:事件Event,临界区域CriticalSection,互斥器Mutex,信号量Semaphore

4)同步和异步的区别

答:同步是阻塞模式,即发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式;而异步是非阻塞方式,发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。

例如:普通B/S模式(同步)AJAX技术(异步)

同步:提交请求->等待服务器处理->处理完毕返回这个期间客户端浏览器不能干任何事

异步:请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕

5)进程和线程的概念

线程(thread),有时被称为轻量级进程(LightweightProcess,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。

6)进程的地址空间是怎么回事?虚拟内存是如何实现的

答:虚拟内存的存在使得CPU上的指令访问的地址都是虚拟地址,而这些地址是需要在物理内存中真实存在的,这里就需要在虚拟地址和物理地址直接建立一个映射关系(应当是多对一的关系),说白了就是一个整数集合到另一个整数集合的映射。然后在查找时,根据相应的算法(如先进先出,最多使用等)进行调度。

7)Linux进程间通信有哪些方式,优缺点如何

答:Linux下进程间通信的几种主要手段:

1)Tcp/IP连接模型

答:TCP/IP通讯协议采用了四层的层级模型结构,每一层都调用它的下一层所提供的网络任务来完成自己的需求:

应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业商业应用和互联网应用。

传输层(Transport):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP提供传输保证。

网络层(Network):网络层协议由一系列协议组成,包括ICMP、IGMP、RIP、OSPF、IP(v4,v6)等。

链路层(Link):又称为物理数据网络接口层,负责报文传输。

2)Io复用,select和poll的区别

答:IO复用模型:调用select或poll,在这两个系统调用中的某一个上阻塞,而不是阻塞于真正I/O系统调用。阻塞于select调用,等待数据报套接口可读。当select返回套接口可读条件时,调用recevfrom将数据报拷贝到应用缓冲区中。

select()函数的接口主要是建立在一种叫'fd_set'类型的基础上。它('fd_set')是一组文件描述符(fd)的集合。

poll()接受一个指向结构'structpollfd'列表的指针,其中包括了你想测试的文件描述符和事件。事件由一个在结构中事件域的比特掩码确定。当前的结构在调用后将被填写并在事件发生后返回。

3)实现一个client/server的通信过程,写一段伪代码(重点写出需要调用的各socketapi)

Server端:

socketaddr_insvr_addr;

socketaddr_inclient_addr;

ServerSocket(addr_in_svr_addr);

bind();

listen();

while(true){

client=accept(addr_inclient_addr);

if(!fork()){

read();

send(client);

close(client);

Client端:

socket(addr_in_client_addr);

connect(server);

data=recv();

close();

4)TCP和UDP的区别,拥塞窗口的概念,如何建立一个TCP连接

答:TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。

UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

拥塞窗口:在TCP传送中的拥塞控制中,发送端通过网络的拥塞程度所给出的一个大小值,而这个值就是拥塞窗口。

建立TCP连接:TCP连接时通过三次握手建立的,详细见下面所示。

5)Tcp连接建立的三次握手是指什么

答:第一步是请求端(客户端)发送一个包含SYN即同步(Synchronize)标志的TCP报文,SYN同步报文会指明客户端使用的端口以及TCP连接的初始序号;

第二步,服务器在收到客户端的SYN报文后,将返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加一,ACK即确认(Acknowledgement)。

第三步,客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加一,到此一个TCP连接完成。然后才开始通信的第二步:数据处理。

TCPClient

Flags

TCPServer

1SendSYN(seq=x)

----SYN--->

SYNReceived

2SYN/ACKReceived

<---SYN/ACK----

SendSYN(seq=y),ACK(x+1)

3SendACK(y+1)

----ACK--->

在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状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据,

6)tcp连接的time_wait是什么状态,描述其发生的场景,说明它存在的好处/坏处

TIME_WAIT的优点:可靠地实现TCP全双工连接的终止;允许老的重复分节在网络中消逝。

TIME_WAIT的缺点:重负载服务器有可能保留有上千个TIME_WAITTCB,因而消耗了大量的内存并能减慢活动的连接。

1)Shell命令,sed,awk等。

参考问题及答案:

Shell:

用没用过shell命令。如果用过,说下常用的shell命令。

问下catchmoddiffmore/less,paste,head/tail,uniq,sort,who

Sed:

考察这几个命令的理解:

(1)sed'/line/p'list.txt

(2)sed-n'/line/p'list.txt

(3)sed'3q'new

(4)

$sed-n-fholdtestlist.txt

其中holdtest是个文本文件

$catholdtest

h

n

p

g

(***OnlyFor面试官***

h#拿到一行line1并且复制到hold区。目前p区[line1],h区[line1]

n#取下一行line2放入p区。目前p区[line2],h区[line1]

p#打印p区内容:line2

g#把h区内容复制到p区。目前p区[line1],h区[line1]

p#打印p区内容:line1。这样就做到了每两行互相替换。)

Awk:

可以考察如下题目:

gawk'/^f/'cars

gawk'$1~/l/'cars

用gawk把所有行加上行长,并按照长度大小排序

gawk'{printlength,$0}'cars|sort–n

2)是否熟悉Linux下的C/C++开发,gcc,gdb,makefile等一些编译,调试工具,是否熟悉。

3)文件系统的组织结构,文件重定向是如何实现的

参考答案:ls-la/

下面我们把Linux文件系统的树形结构的主要目录列一下

/Linux文件系统的入口,也是处于最高一级的目录;

/bin基础系统所需要的那些命令位于此目录,也是最小系统所需要的命令;比如ls、cp、mkdir等命令;功能和/usr/bin类似,这个目录中的文件都是可执行的,普通用户都可以使用的命令。做为基础系统所需要的最基础的命令就是放在这里。

/bootLinux文件系统的内核及引导系统程序所需要的文件,比如vmlinuzinitrd.img文件都位于这个目录中。在一般情况下,GRUB或LILO系统引导管理器也位于这个目录;

/dev设备文件存储目录,比如声卡、磁盘......

/etc系统配置文件的所在地,一些服务器的配置文件也在这里;比如用户帐号及密码配置文件;

/home普通用户家目录默认存放目录;

/lib库文件存放目录

/mnt这个目录一般是用于存放挂载储存设备的挂载目录的,比如有cdrom等目录。

/rootLinux文件系统超级权限用户root的Home目录;

考察管道,重定向等概念和使用。

重定向用着简单,重要是思考重定向的实现方式。

可以考下./myprog1>tmp2>tmp是否正确?应该怎么改?

答案:./myprog1>tmp2>&1

具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。

同时我们也看到,由于才服务器端保持状态的方案在客户端也需要保存一个标识,所以session

机制可能需要借助于cookie机制来达到保存标识的目的。其实有其他办法。

session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。但程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为sessionid,如果已经包含一个sessionid则说明以前已经为此客户创建过session,服务器就按照sessionid把这个session检索出来使用(如果检索不到,可能会新建一个,这种情况可能出现在服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。

cookie:将你的所有提供的这些信息和登陆信息,以文件的形式保存到你的计算机上,当访问其他文件的时候,首先把cookies提交给服务器,服务器判断这里的信息,得知你是什么样的一个用户,然后给出你相应的功能页面.可以自行设置cookies的存在周期,除非设置了临时cookies,否则关闭浏览器后cookies信息仍旧保存在主机的硬盘上。

session:将你所提供的信息,以牺牲服务器资源的方式记录下来,当你访问其他页面的时候,先判断服务器上的关于你的信息,并提供给你相应的功能页面.变量保存在客户端主机的内存上,关闭浏览器或者session脚本过期后,即自动清除。

Cookies的安全性能一直是倍受争议的。虽然Cookies是保存在本机上的,但是其信息的完全可见性且易于本地编辑性,往往可以引起很多的安全问题。所以Cookies到底该不该用,到底该怎样用,就有了一个需要给定的底线。

先来看看,网站的敏感数据有哪些。

登陆验证信息。一般采用Session("Logon")=trueorfalse的形式。

用户的各种私人信息,比如姓名等,某种情况下,需要保存在Session里

需要在页面间传递的内容信息,比如调查工作需要分好几步。每一步的信息都保存在Session里,最后在统一更新到数据库。

当然还会有很多,这里列举一些比较典型的

假如,一个人孤僻到不想碰Session,因为他认为,如果用户万一不小心关闭了浏览器,那么之前保存的数据就全部丢失了。所以,他出于好意,决定把这些用Session的地方,都改成用Cookies来存储,这完全是可行的,且基本操作和用Session一模一样。那么,下面就针对以上的3个典型例子,做一个分析

很显然,只要某个有意非法入侵者,知道该网站验证登陆信息的Session变量是什么,那么他就可以事先编辑好该Cookies,放入到Cookies目录中,这样就可以顺利通过验证了。这是不是很可怕?

Cookies完全是可见的,即使程序员设定了Cookies的生存周期(比如只在用户会话有效期内有效),它也是不安全的。假设,用户忘了关浏览器或者一个恶意者硬性把用户给打晕,那用户的损失将是巨大的。

这点如上点一样,很容易被它人窃取重要的私人信息。但,其还有一个问题所在是,可能这些数据信息量太大,而使得Cookies的文件大小剧增。这可不是用户希望所看到的。

显然,Cookies并不是那么一块好啃的小甜饼。但,Cookies的存在,当然有其原因。它给予程序员更多发挥编程才能的空间。所以,使用Cookies改有个底线。这个底线一般来说,遵循以下原则。

不要保存私人信息。

任何重要数据,最好通过加密形式来保存数据(最简单的可以用URLEncode,当然也可以用完善的可逆加密方式,遗憾的是,最好不要用md5来加密)。

是否保存登陆信息,需有用户自行选择。

长于10K的数据,不要用到Cookies。

参考答案网上都有

考察项目多为前端开发/测试的面试者对基本概念的了解

结合项目询问对测试了解的情况,谈谈对测试流程的理解:什么阶段介入测试比较好;对CodeReview的看法,RD和QA各自的侧重点;测试完成的衡量标准,是否接触过测试覆盖率;自动化的实现方法,谈一下测web常见的一些自动化思路。。。

1)介绍一下selenium?Selenium有哪些特点?

答:Selenium是一个针对Web应用的开源测试框架,它的测试用例可以用HTMLtable和HTML代码或者一些非常流行的编程序言进行开发,而且它能在几乎所有现在的浏览器上执行。selenium可以被部署到Windows,Linux和Macintosh平台上。它支持的语言有Java,Python,Ruby,.Net,Perl等等

主要的特点:

l支持录制和回放

l能够灵活的根据ID,Name或者XPath来进行页面元素的选取

l能够进行Debug和设置断点

l能够把测试脚本保存成HTML,Ruby或者其他语言

l支持user-extensions.js形式的用户扩展

l能够自动进行页面的断言

2)Selenium分为哪几部分

SeleniumIDE:一个firefox插件,可以录制、回放测试脚本。

SeleniumRC:支持用程序语言编写测试用例,比如Ruby、Java、C#等,这样做的好处是,可以将Selenium和其他测试框架集成,比如.NET环境下,可以把Selenium和NUnit集成,用Selenium来编写测试用例,用NUnit来实现测试用例的自动化运行。

SeleniumCore:SeleniumCore是Selenium的核心,是由Javascript和Html文件组成的,它是SeleniumIDE和SeleniumRC的核心引擎。

3)Selenium中verifyTextPresent和assertTextPresent命令的区别?

答:verifyTestPresent和assertTextPresnt命令都用于判断页面上是否存在指定的文本,区别是verifyTestPresent结果是false时,剩余的步骤会继续执行。但assertTextPresent结果是false时直接终结该脚本剩余步骤的运行。

4)Selenium中click和clickAndWait的区别?

答:click命令模拟用户点击的动作。命令执行完毕后立刻执行下一条命令。ClickAndWait命令在点击后有一个等待的过程,会等页面重新加载完毕再执行下一条命令。

5)如果有一个按钮,点击该按钮后会发出一个ajaxcall,然后得到返回结果后将该内容显示到新弹出的一个layer中。在写脚本的时候,点击按钮这个动作是否可以用clickAndWait命令?如果不行,怎么解决?

答:不能使用clickAndWait。因为ajaxcall不会刷新页面,clickandWait命令会因为等待页面重新加载而出现Timeout.对这种情况应该使用click命令结合pause命令。

6)下面是某页面中的一段htmlsource,其中某a链接的地址中包含关键字test。用xpath定位该a元素。

......

7)Selenium内部运行机制是这样的?为什么Selenium脚本可以运行在几乎所有的主流浏览器上。

答:Selenium的核心是Javascript写的,它通过javascript来实现对Html页面的操作的。它提供了丰富的指定Html页面元素和操作页面元素的方法。Selenium打开浏览器时,把自己的JavaScript文件嵌入网页中。然后Selenium的网页通过frame嵌入目标网页。这样,就可以使用Selenium的JavaScript对象来控制目标网页。因为selenium是用javascript去操作页面元素,所以支持几乎所有主流的浏览器。

8)Selenium用javascript去操作页面元素会碰到什么问题?Selenium是如何解决这个问题的?

答:javascript受同源策略的限制。当浏览器要运行一个脚本时,便会进行同源检查,只有和被操控网页同源的脚本才能被执行。

Selenium通过采用代理模式来解决这个问题。测试脚本向SeleniumServer发送Http请求,要求和SeleniumServer建立连接。SeleniumServer启动浏览器,把SeleniumCore加载入浏览器页面当中,并把浏览器的代理设置为SeleniumServer的HttpProxy。测试脚本向SeleniumServer发送Http请求,SeleniumServer对请求进行解析,然后通过HttpProxy发送JS命令通知SeleniumCore执行操作浏览器的动作。SeleniumCore接收到指令后,执行操作。SeleniumServer接收到浏览器的发送的Http请求后,自己重组Http请求,获取对应的Web页面。SeleniumServer的HttpProxy把接收的Web页面返回给浏览器。因为浏览器存在同源策略,所以SeleniumRC中的SeleniumServer需要以这种代理模式运行

1)对于Javascript生成的元素,Watir识别和操作该元素是如何做的?

答:实际上,Watir::IE封装了一个当前页面的DOMtree,而不是htmlsource。比如如果用javascrīpt动态产生一个元素,在这里仍然可以访问。普通元素,按照Watir封装的类就可以实现访问和操作。Windows对象支持并不好。

2)对于多浏览器的web测试,Ruby-watir是如何支持的?

3)简述ruby-watir中如何实现数据驱动。

答:将与逻辑无关的数据剥离开来,多组数据作为一组输入,循环调用重复的用例接口。在ruby-watir中,支持读取Excel等多种数据管理格式。

4)Ruby-watir中对于正则的支持,正则表达式的考察。

答:在Ruby中,要建立一个正则表达式,只要把要匹配的模式放到两个斜线中就行了(/pattern/),而且,在Ruby中,正则表达式也是对象,可以像对象一样被操作。

5)watir不支持的windows控件,是如何解决的?

解答:采用第三方autoit技术,来模拟键盘或鼠标操作。参考

6)简述ruby元编程的概念,应用场景,以及如何应用。

答:通常元编程被认为是通过程序来生成程序,在Ruby中,Ruby元编程的使用变得相当的简单和容易实现,使用Ruby语言本身来产生Ruby代码,不需要借助外部的工具,著名的RoR框架就是建立在Ruby元编程的基础上的。

比如ROR框架中的

classPerson

attr_reader:name

end

attr_reader的实现如下:

#defattr_reader(*syms)

#syms.eachdo|sym|

#class_eval%{def#{sym}

#@#{sym}

#end

#注:class_eval是为一个class增加method的。可以接string和block为参数。

在ROR框架中已经广泛应用了元编程,ActiveRecord在OR映射模型中,将关系数据库中的关系表映射到对象模型时,将关系表的表名映射到类名,表中的每一个元组映射到对应于这个类的一个对象,元组的一个字段对应于对象的一个属性。ActiveRecord在这里灵活应用了ruby元编程的动态特性,实现了优雅的解决方案。51Testing软件测试网&S9ttathFh}

1)简单介绍下QTP

答:QTP是个用于录制和回放脚本的自动化测试工具。它可以用于web和客户端程序的自动化测试。

2)QTP中RO与TO的区别?

答:TO是TestObject的简称,RO是RuntimeObject简称,既用来区分仓库对象和实际对象,又用来区分对象的封装接口和自身接口。

从实际作用上来看,应该说TO就是是仓库文件里定义的仓库对象,RO是被测试软件的实际对象。

为用户提供了两种操作对象的接口,一种就是对象的封装接口,另一种是对象的自身接口。对象的自身接口是对象控件本身的接口,对象的封装接口是QTP为对象封装的另一层接口,它是QTP通过调用对象的自身接口来实现的。两种接口的脚本书写格式的差别在于:自身接口需要在对象名后面加object再加属性名或方法名,封装接口就不用在对象名后面加object.

3)QTP中OBJECTSPY的作用?

答:查看对象,在查看窗口里有列出这些接口,包括属性和方法。

窗口中间有选择栏让你选择Run-timeObject或者TestObject,当你选择RuntimeObject时,它显示的就是对象的自身接口(自身的属性和方法).当你选择TestObject时,它显示的就是对象的封装接口(封装的属性和方法)

4)如何激活一个窗口?

答:激活窗口使用的方法Window("").Activate

5)编写一个QTP脚本,实现向记事本中输入“baidu”。

答:SystemUtil.Run“C:\WINDOWS\system32\notepad.exe”

Window(”Notepad”).Activate

Window(”Notepad”).WinEditor(”Edit”).Type“baidu”

1)什么是负载测试?什么是性能测试?

答:负载测试是通过改变系统负载方式、增加负载等来发现系统中所存在的性能问题。负载测试是一种测试方法,可以为性能测试、压力测试所采用。负载测试的加载方式也有很多种,可以根据测试需要来选择。

性能测试是为获取或验证系统性能指标而进行测试。多数情况下,性能测试会在不同负载情况下进行。

压力测试通常是在高负载情况下来对系统的稳定性进行测试,更有效地发现系统稳定性的隐患和系统在负载峰值的条件下功能隐患等。

2)性能测试包含了哪些测试(至少举出3种)

答:压力测试、负载测试、并发测试、可靠测试、失效恢复测试。

3)简述使用Loadrunner的步骤

答:脚本录制设置—录制脚本—调试脚本—场景设置—结果分析

4)LoadRunner由哪些部件组成?你使用LoadRunner的哪个部件来录制脚本,哪个部件可以模拟多用户并发下回放脚本?

答:virtualusergenerator

controller

analysis

virtualusergenerator来录制脚本,controller来回放脚本

5)什么是集合点?设置集合点有什么意义Loadrunner中设置集合点的函数是哪个

答:集合点:设置多个用户到达某个用户数量点集合,同时触发一个事务,以达到模拟真实环境下同时多个用户操作,同时模拟负载,实现性能测试的最终目的

LR_rendezvous(“集合点名称”)

6)你在LR中如何编写自定义函数?请给出一些你在以前进行的项目中编写的函数。

答:在创建用户自定义函数前我们需要和创建DLL(externallibary)。把库放在VuGenbin目录下。一旦加了库,把自定义函数分配做一个参数。该函数应该具有一下格式:__declspec(dllexport)char*(char*,char*)。

7)以线程方式运行的虚拟用户有哪些优点?

答:VuGen提供了用多线程的便利。这使得在每个生成器上可以跑更多的虚拟用户。如果是以进程的方式跑虚拟用户,为每个用户加载相同的驱动程序到内存中,因此占用了大量的内存。这就限制了在单个生成器上能跑的虚拟用户数。如果按进程运行,给定的所有虚拟用户数(比如100)只是加载一个驱动程序实例到内存里。每个进程共用父驱动程序的内存,因此在每个生成器上可以跑更多的虚拟用户。

THE END
1.玩转手工测试之百度客户端产品手工测试提效实践2、高频迭代发布诉求:百度内部的产品呈现出高频迭代的趋势,需求方希望尽早地看到结果,并给予及时反馈,所以技术团队需要用“小步快跑”的姿势来做产品,尽早地交付新版本;因此很多大型 APP 逐步切换到单周/双周发布模式,对于测试来说没有固定的回归测试时间,要求开发完成后立即完成测试; https://xie.infoq.cn/article/65a6a38e38cc83529b04f4f26
2.软件测试之百度界面测试用例的设计设计百度首页测试用例,里面有各种软件测试+开发资料和技术可以一起交流学习哦。 最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走: ? 这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮https://blog.csdn.net/lzz718719/article/details/140688621
3.百度无代码发开工具“秒哒”开启企业邀测调用李彦宏大模型知名企11月12日,在百度世界2024现场,百度创始人李彦宏发布无代码开发工具“秒哒”。百度智能云宣布,秒哒已正式开启企业测试申请。不到一天时间,已有300余家企业申请秒哒测试。 李彦宏介绍,秒哒可以让每个人都具备程序员的能力,会说话就能做出应用。秒哒具备无代码编程、多智能体协作和多工具调用三大特性,李彦宏称之为“迄今https://www.163.com/dy/article/JGSFUGTR05118MCQ.html
4.「测试开发招聘」百度招聘百度测试开发招聘,薪资:10-18K,地点:北京,要求:经验不限,学历:本科,福利:五险一金、补充医疗保险、定期体检、加班补助、年终奖、带薪年假、员工旅游、免费班车、餐补、通讯补贴、交通补助、节日福利、住房补贴、零食下午茶、娱乐健身,测试开发工程师刚刚在线,随https://www.bosszhipin.com/job_detail/1413014711.html
5.一百度页面测试1.功能测试:一、百度页面测试 1. 功能测试: - 除了确保基本的链接、搜索框和按钮功能正常,还可以测试搜索框的自动提示功能、搜索结果的分页功能、高级搜索选项等。 - 对搜索结果的准确性进行深入测试,可以选择一些特定领域的关键词,检查结果是否与预期相符。 - 测试百度的其他功能模块,如百度地图、百度百科、百度学术等的入口链https://www.nowcoder.com/discuss/comment/20549845
6.百度开发测试工程师招聘(工资待遇要求)百度在线网络技术(北京说明:北京 开发测试工程师 平均工资¥25550 ,北京互联网/电子商务行业 开发测试工程师 平均工资¥27602 按学历统计 本科 ¥26.4K 百度 开发测试工程师 工资按学历统计,本科工资¥26.4K,想知道其他学历工资,请点击查看。 招聘经验要求:1-3年最多 查看经验分布占比 > 1-3年 3-5年 百度 开发测试工程https://m.jobui.com/company/11712594/salary/j/kaifaceshigongchengshi/
7.校招VIP百度测试开发面经【校招VIP】百度测试开发面经 转载声明:文章来源https://www.nowcoder.com/feed/main/detail/1075fdc1f7ed494491e384bd9556cd7b 1.自我介绍 2.详细介绍一下自己的项目中的细节,针对数据集小做出了哪些努力(和我的研究生方向有关)。 3.stringbuilder和stringbuffer的区别。 https://naoffer.com/article/detail/6547
8.百度校园招聘历年经典面试题汇总:开发测试岗云社区(30)、百度搜索每天那么大访问量,将所有检索过的字条都存放下来,如何快速判断新search的词是否搜索过? (31)、写一段代码比较字符串s1,s2是否字符和字符出现次数一样? (32)、从测试的角度看百度地图的离线包下载功能,从哪些方面测试? 文章来源: fantianzuo.blog.csdn.net,作者:兔老大RabbitMQ,版权归原作者所有https://bbs.huaweicloud.com/blogs/377857
9.向开发者示好:百度宣布正式开放“百度应用引擎”,升级“百度移动除了开放BAE外, 百度还宣布重新升级了MTC(Mobile TestingCenter),即百度移动云测试中心的服务。MTC为开发者提供了上百种主流厂商的移动终端设备及增强模拟器,涵盖了主流Android手机和各种配置的模拟器,方便开发者进行实时的手机应用开发和测试工作。目前国内提供类似服务的还有Testin、易测云以及中国移动MM终端池等。 https://36kr.com/p/1641705996289
10.百度点击软件开发百度开发者工具使用教程php在测试过程中,你可以使用开发者工具中的日志查看和修改变程的执行情况,并查看和修改变量的值,从而确保百度点击软件能够正常工作。 本文介绍了百度点击软件的开发以及如何使用百度开发者工具。通过使用百度开发者工具,你可以轻松地构建出更加优秀的应用,并充分利用百度提供的API接口提供的各种服务。https://blog.yyzq.team/post/338762.html
11.百度校招研发开发测试岗位笔试题大概是游戏端与服务器,可实现功能是朋友圈的得分与排名可见,每个人可在服务器查询自己的总排名; 要求:客户端与服务器交互设计;结构与功能、实时更新、排名查询等并问在1亿用户量时是否可行, 资料共享平台 《百度校招研发、开发测试岗位笔试题》(https://www.unjs.com)。 大概就是这样子吧。https://www.unjs.com/fanwenwang/ziliao/201178.html
12.百度密码保护:百度-测试开发工程师三郎面经(一)这是一篇受密码保护的文章,您需要提供访问密码: 密码: 您可能还喜欢密码保护:三郎Golang学习笔记 类的生命周期 Win下IIS设置FTP实现局域网文件共享 三郎君的日常 ? 2024. 版权所有 侵权必究 ICP备案号:豫ICP备2021011695号 联系方式:179874957@qq.com 感谢支持http://sanlangcode.com/?p=1287
13.百度发布无代码开发工具“秒哒”300余家企业申请测试上证报中国证券网讯(记者 温婷)11月12日,在百度世界2024现场,百度创始人李彦宏发布无代码开发工具“秒哒”。百度智能云11月13日宣布,秒哒正式开启企业测试申请。不到一天时间,已有300余家企业申请秒哒测试。 据李彦宏介绍,秒哒具备无代码编程、多智能体协作和多工具调用三大特性,可以让每个人都具备程序员的能力,会说https://finance.sina.com.cn/roll/2024-11-13/doc-incvwwiq8179676.shtml
14.对百度搜索页面设计的测试用例设计测试百度搜索页面设计时,可以设计多种测试用例来确保页面的功能、性能和用户体验。以下是一些可能的测试用例: 搜索框功能测试: 输入有效关键字,验证搜索结果是否正确显示。 输入无效关键字或特殊字符,验证系统是否给出适当的提示或错误信息。 搜索按钮测试: https://developer.aliyun.com/article/1419631
15.微信小程序开发之颜值测试,调用百度AI人脸检测接口识相Insight 图像识别微信小程序 AI图像识别 百度图像识别 微信小程序 微信小程序应用开发赛 产品文档 By:Autumnhui 丘天惠 代码开源,欢迎学习交流(大佬不要喷,自学JavaScript) ? 拒绝一切将他人学习成果白嫖/盈利的行为 ? 如果对你有用,可以 ** Star** 一下 Insight 微信图像识别小程序 扫码体验 一、产品https://www.pianshen.com/article/66611138021/
16.百度测开一面凉经+技术中台质量部一二三四面(已OC)6.说下你对测试开发工程师的理解 7.自己想做的是测试,还是工具开发 8.看你的学历从专科开始,都是全日制的嘛,都是计算机相关的嘛,考研考了两年嘛,能说说这一路走来的事嘛 9.测试微信怎么测试 10.你参加过小程序设计大赛,具体的项目时什么相关的 https://ceshiren.com/t/topic/18913
17.百度地图开发实例番外篇实用方法(持续更新)摘要:一前言在使用百度地图开发的过程中,查阅百度地图官网基本上就能满足开发的需求,但是有时候需要设置一些东西,很难在官网上查阅到相关的方法技巧。希望百度地图能够越来越强大,这样开发者就可以愉快的开发了 一 前言 在使用百度地图开发的过程中,查阅百度地图官网demo基本上就能满足开发的需求,但是有时候需要设置一些https://www.ucloud.cn/yun/92580.html