测试开发面试题

目录

 

功能测试用例的设计

(一).我想要回家,让你给我买一张票,然后设计测试用例

工作测试流程

(一).功能测试流程

app专项测试

工具使用

基础概念:

什么是性能测试

HTTP协议(哪些方法,什么区别(GET\POST),怎么组成,状态码)

TCP三次握手四次离手

线程,进程区别联系

内存泄露,内存溢出区别

死锁

自动化测试:

自动化测试脚本的应用场景:

自动化框架的搭建:

功能自动化框架

平台工具:

算法:

c程序实现找二叉树交叉节点

从100亿随机数中找到前100万个最大的数

斐波那契,递归非递归 时间复杂度

linux:

linux常用指令(说了10个左右)

数据库:

数据库中索引和主键有什么相同点和区别

网络

tcp和udp的区别

dns的解析过程

dns属于udp还是tcp,原因

ISO七层的作用,分别有什么协议

给定ip,url,time等参数,去重获取其中一天,某一时间段得日志ip信息

典型例题

(一).Web页面出现空白页怎么定位问题

(二).Web页面响应过慢怎么定位问题

测试用例的题目:微信有发送文字消息的功能,如果让你设计功能点,你会设计什么样的测试用例来测试它的功能是不是正确的

有一个场景要测试:比如说一个微信有群聊功能,怎么测试这个功能是不是正确的,确保这个群聊可以用

你为了软件测试这个岗位做了什么准备呢?

对测试开发的理解

给你一个需求,怎么开始测试;发版前遇到重大bug,怎么处理?

在跟进版本过程中要处理很多事情,怎么平衡?

你觉得测试最重要的是什么?

职业规划


功能测试用例的设计

举例:

(一).我想要回家,让你给我买一张票,然后设计测试用例

答案:

1.确定需求(回家回哪,需要什么票,买什么时候的票)

2.开始测试

2.1功能测试(我去买票(买火车票,飞机票),买到票(什么时候),回来给你)

2.2可靠性测试(我去买票过程中被撞死了,票买不到怎么办,延期了,买那个点的票没了怎么办让我帮他买票的人的身份,比如是否有特殊优待,如军人,1米2以下儿童等,身份证丢了,或者票丢了,责任划分)

2.3可维护性测试(票是否可保存完好)

2.4兼容性(还不同人的去买,我中间招人去买,我坐车走路)

2.5算法测试(我通过不同的渠道买票花费的时间)

2.6竞品测试(别的人怎么买的票)

2.7安全性测试(身份信息保密)

2.8性能测试(一个身份证买多张票,同时多张身份证买多张票)

工作测试流程

(一).功能测试流程

1.需求评审(重点,你发挥的作用是什么,需求可执行性,关联影响的功能模块,异常情况处理)

2.评估测试时间(测试计划)

3.测试用例设计(正交,边界值,等价类。。)

4.用例review(领导,开发,产品)

5.提测(确认开发进行过自测,功能主流程畅通,然后开始介入测试)(产品开发测试一块走流程)

6.codediff(代码改动点,从根源发现开发的问题,代码中明显测试代码(return,写死值),

公共静态变量在发生高并发时容易出问题,所以不能让这个变量的值去内存里面取)

7.执行用例

8.提bug(jira)

9.回归测试

10.确认测试(准生产环境确认)(分情况)

11.发布(线上回归))

12.BUG review(总结问题)

注意点:

发布测试来控制,测试环境部署测试来控制

发布过程中,开发运维做监控。(分批发布)

app专项测试

1.CPU,内存,流量,电量,弱网,兼容性,FPS,中断,安装,稳定性

   怎么自动化实现,写一些自动化框架方法封装起来,重复的使用

2.冷热启动的区别

冷启动:在个人电脑中,冷启动是切断电源后重新启动。App类似,就是完全退出(不在后台运行)后重启启动。

热启动:非冷启动情况都可以称为热启动。热启动比冷启动多了一个触发点,那就是在后台启动App,比如双击苹果的HOME键,进行App的热启动。同时热启动通常会有一个计时器,特别是一些理财和银行的类的App会做此处理,当你间隔一段时间触发了热启动后,会让你再次登录(通过密码/手势/指纹)。也有比如网易新闻客户端这样的,当你间隔一段时间后触发热启动,会弹出广告页。

工具使用

postman:接口,功能测试,可以做参数化

httprequester:接口,功能测试

jemter:接口功能性能工具

lr:接口功能性能

fiddler:抓包,设置代理,设置断点,mock数据

charles:抓包,设置代理,设置断点,mock数据

robot:功能自动化

uft(qtp):功能自动化

docker:容器

monkey:性能稳定性(app)

jenkins:自动持续集成

git,svn:代码管理

xmind/visio:脑图

soapUI:接口功能测试(HTTP,WEBSERVICE协议)

xshell/SecureCRT/putty:

slor:关键字分词

slor:我测试:我   测试分别去数据库搜索结果

nginx(反向代理)

tomcat(动态网页发布)

基础概念:

什么是性能测试

概念:性能测试就是通过特定的方式对被测试系统按照一定测试策略施加压力,获取该系统的响应时间、TPS、吞吐量、资源利用率等性能指标,来检测系统上线后能否满足用户需求的过程。

什么是软件性能:软件性能覆盖面广泛,对一个系统来说包含系统的执行效率、服务器资源使用情况、系统稳定性、安全性、兼容性、可扩展性、可靠性等等

软件性能的影响因素:

1:网络环境 2:硬件设备(CPU、内存、存储设置) 3:操作系统、应用服务器、数据库配置 4:数据库设计和数据库访问实现(SQL语句)。 5:系统构架(同步、异步)

不同人员对软件性能的认识:1、实际用户角度 2、系统管理员角度 3、开发设计人员角度

客户使用角度:软件对用户操作的响应时间,如用户提交一个查询操作、打开一个Wed页面的链接等

系统管理员角度:1、并发压力 2、服务器硬件资源的使用情况 3、是否出现性能瓶颈 4、系统的扩展性如何

开发设计角度:1、架构设计的合理性 2、数据库设计是否存在问题 3、代码编程的规范是否需要优化例如SQL 4、看是否通过代码的优化或是调节系统参数设置来提高系统优化。

HTTP协议(哪些方法,什么区别(GET\POST),怎么组成,状态码)

HTTP/1.1协议中共定义了8种HTTP请求方法,HTTP请求方法也被叫做“请求动作”,不同的方法规定了不同的操作指定的资源方式。服务端也会根据不同的请求方法做不同的响应。

GET

GET请求会显示请求指定的资源。一般来说GET方法应该只用于数据的读取,而不应当用于会产生副作用的非幂等的操作中。

GET会方法请求指定的页面信息,并返回响应主体,GET被认为是不安全的方法,因为GET方法会被网络蜘蛛等任意的访问。

HEAD:HEAD方法与GET方法一样,都是向服务器发出指定资源的请求。但是,服务器在响应HEAD请求时不会回传资源的内容部分,即:响应主体。这样,我们可以不传输全部内容的情况下,就可以获取服务器的响应头信息。HEAD方法常被用于客户端查看服务器的性能。

POST:POST请求会 向指定资源提交数据,请求服务器进行处理,如:表单数据提交、文件上传等,请求数据会被包含在请求体中。POST方法是非幂等的方法,因为这个请求可能会创建新的资源或/和修改现有资源。

PUT:PUT请求会身向指定资源位置上传其最新内容,PUT方法是幂等的方法。通过该方法客户端可以将指定资源的最新数据传送给服务器取代指定的资源的内容。

测试开发面试题_第1张图片

TCP三次握手四次离手

三次握手:

  1. 客户端发送一个SYN段,并指明客户端的初始序列号,即ISN(c).
  2. 服务端发送自己的SYN段作为应答,同样指明自己的ISN(s)。为了确认客户端的SYN,将ISN(c)+1作为ACK数值。这样,每发送一个SYN,序列号就会加1. 如果有丢失的情况,则会重传。
  3. 为了确认服务器端的SYN,客户端将ISN(s)+1作为返回的ACK数值。

四次挥手:

1. 客户端发送一个FIN段,并包含一个希望接收者看到的自己当前的序列号K. 同时还包含一个ACK表示确认对方最近一次发过来的数据。 2. 服务端将K值加1作为ACK序号值,表明收到了上一个包。这时上层的应用程序会被告知另一端发起了关闭操作,通常这将引起应用程序发起自己的关闭操作。 3. 服务端发起自己的FIN段,ACK=K+1, Seq=L 4. 客户端确认。ACK=L+1

线程,进程区别联系

进程概念:进程是表示资源分配的基本单位,又是调度运行的基本单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等。然后,把该进程放人进程的就绪队列。进程调度程序选中它,为它分配CPU以及其它有关资源,该进程才真正运行。所以,进程是系统中的并发执行的单位。在Mac、Windows NT等采用微内核结构的操作系统中,进程的功能发生了变化:它只是资源分配的单位,而不再是调度运行的单位。在微内核系统中,真正调度运行的基本单位是线程。因此,实现并发功能的单位是线程。

线程概念线程是进程中执行运算的最小单位,亦即执行处理机调度的基本单位。如果把进程理解为在逻辑上操作系统所完成的任务,那么线程表示完成该任务的许多可能的子任务之一。例如,假设用户启动了一个窗口中的数据库应用程序,操作系统就将对数据库的调用表示为一个进程。假设用户要从数据库中产生一份工资单报表,并传到一个文件中,这是一个子任务;在产生工资单报表的过程中,用户又可以输人数据库查询请求,这又是一个子任务。这样,操作系统则把每一个请求――工资单报表和新输人的数据查询表示为数据库进程中的独立的线程。线程可以在处理器上独立调度执行,这样,在多处理器环境下就允许几个线程各自在单独处理器上进行。操作系统提供线程就是为了方便而有效地实现这种并发性

引入线程的好处

(1)易于调度。

(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。

(3)开销少。创建线程比创建进程要快,所需开销很少。。

(4)利于充分发挥多处理器的功能。通过创建多线程进程(即一个进程可具有两个或更多个线程),每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。

进程和线程的关系

(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。

(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。 同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。

(3)处理机分给线程,即真正在处理机上运行的是线程。

(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

进程的两个基本属性:

(1)进程是一个可拥有资源的独立单位;

(2)进程同时又是——个可以独立调度和分派的基本单位。正是由于进程具有这两个基本属性,才使之成为一个能独立运行的基本单位,从而也就构成了进程并发执行的基础。

然而为使程序能并发执行,系统还必须进行以下的一系列操作:

(1)创建进程。系统在创建进程时,必须为之分配其所必需的、除处理机以外的所有资源。如内存空间、I/0设备以及建立相应的PCB。

(2)撤消进程。系统在撤消进程时,又必须先对这些资源进行回收操作,然后再撤消PCB。

(3)进程切换。在对进程进行切换时,由于要保留当前进程的CPU环境和设置新选中进程的CPU环境,为此需花费不少处理机时间。

由于进程是一个资源拥有者,因而在进程的创建、撤消和切换中,系统必须为之付出较大的时空开销。也正因为如此,在系统中所设置的进程数目不宜过多,进程切换的频率也不宜太高,但这也就限制了并发程度的进一步提高。

线程与进程的比较

从调度、并发性、 系统开销、拥有资源等方面,来比较线程与进程。

1.调度:在传统的操作系统中,拥有资源的基本单位和独立调度、分派的基本单位都是进程。而在引入线程的操作系统中,则把线程作为调度和分派的基本单位。而把进程作为资源拥有的基本单位,使传统进程的两个属性分开,线程便能轻装运行,从而可显著地提高系统的并发程度。在同一进程中,线程的切换不会引起进程的切换,在 由一个进程中的线程切换到另一个进程中的线程时,将会引起进程的切换。

2.并发性:在引入线程的操作系统中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间,亦可并发执行,因而使操作系统具有更好的并发性,从而能更有效地使 用系统资源和提高系统吞吐量。例如,在一个未引入线程的单CPU操作系统中,若仅设置一个文件服务进程,当它由于某种原因而被阻塞时,便没有其它的文件服 务进程来提供服务。在引入了线程的操作系统中,可以在一个文件服务进程中,设置多个服务线程,当第一个线程等待时,文件服务进程中的第二个线程可以继续运 行;当第二个线程阻塞时,第三个线程可以继续执行,从而显著地提高了文件服务的质量以及系统吞吐量。

3.拥有资源:不论是传统的操作系统,还是设有线程的操作系统,进程都是拥有资源的一个独立单位,它可以拥有自己的资源。一般地说,线程自己不拥有系统资源(也有一点必 不可少的资源),但它可以访问其隶属进程的资源。亦即,一个进程的代码段、数据段以及系统资源,如已打开的文件、I/O设备等,可供问一进程的其它所有线 程共享。

4.系统开销:由于在创建或撤消进程时,系统都要为之分配或回收资源,如内存空间、I/o设备等。因此,操作系统所付出的开销将显著地大于在创建或撤消线程时的开销。类 似地,在进行进程切换时,涉及到整个当前进程CPU环境的保存以及新被调度运行的进程的CPU环境的设置。而线程切换只须保存和设置少量寄存器的内容,并 不涉及存储器管理方面的操作。可见,进程切换的开销也远大于线程切换的开销。此外,由于同一进程中的多个线程具有相同的地址空间,致使它们之间的同步和通信的实现,也变得比较容易。在有的系统中,线程的切换、同步和通信都无须

内存泄露,内存溢出区别

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出. 

以发生的方式来分类,内存泄漏可以分为4类: 

1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。 
2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。 
3. 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。 
4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。 

从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到 

死锁

概念:当线程A持有独占锁a,并尝试去获取独占锁b的同时,线程B持有独占锁b,并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。

造成死锁必须达成的4个条件(原因):

  1. 互斥条件:一个资源每次只能被一个线程使用。
  2. 请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:线程已获得的资源,在未使用完之前,不能强行剥夺。
  4. 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
  1. 互斥条件 ---> 独占锁的特点之一。
  2. 请求与保持条件 ---> 独占锁的特点之一,尝试获取锁时并不会释放已经持有的锁
  3. 不剥夺条件 ---> 独占锁的特点之一。
  4. 循环等待条件 ---> 唯一需要记忆的造成死锁的条件。

不错!复杂的死锁条件经过简化,现在需要记忆的仅只有独占锁与第四个条件而已。

所以,面对如何避免死锁这个问题,我们只需要这样回答!
: 在并发程序中,避免了逻辑中出现复数个线程互相持有对方线程所需要的独占锁的的情况,就可以避免死锁。

自动化测试:

自动化测试脚本的应用场景:

1.重复性较多的,写脚本能省时间,节省效率,

接口重复回归,功能重复回归

2.手动做不了的测试

上万数据的准确性校验,脚本跑,错误数据筛选出来

数据更新机制的调整,全量变成增量更新()

自动化框架的搭建:

接口自动化框架

1.结构(1.框架思想(数据,关键字,行为,事件,混合)

2.读取用例的模块(excel,txt,mysql,xml)

3.发请求的模块(requests封装)

4.断言模块(re,遍历断言)

5.日志模块

6.测试报告生成模块

7.发邮件模块

8.配置文件)

2.怎么设计测试用例,注意哪些点()

3.怎么断言

功能自动化框架

1.和接口自动化类似

2.对页面各个控件的api封装(哪些封装,下拉框,选择框,对隐形控件怎么处理)

3.不同环境处理

4.xpath定位方法()

5.js定位方法()

平台工具:

1.接口自动化集成到平台上;

2.平台做测试环境,线上环境的监控

3.做公用统计线上badcase的统计

算法:

(会多门语言(前端了解。java熟练,python熟练))

排序算法:

冒泡

快排

查找算法:

二分查找,

队列,堆,栈实现:

c程序实现找二叉树交叉节点

寻找两个链表中相交部分的起点,不得改变链表结构,时间复杂性要求为O(n),空间复杂性为O(1),不相交则返回null

    例如:链表A:        a1->a2->c1->c2->c3 

               链表B: b1->b2->b3->c1->c2->c3

             相交的起点为c1

思路较简单:链表后部分相同,可以先把链表以后端为基准对齐,再一个一个元素的比较,第一个相同的元素则为相交的起点。(这里认为两个链表只有一个相交点,且相交点之后的部分全都相同,如果这种假设不成立,这种方法无效,不过题目应该是支持这种假设的,否则测试案例肯定通不过)

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    //boundary check
    if(headA == null || headB == null) return null;
    
    ListNode a = headA;
    ListNode b = headB;
    
    //如果a和b的长度不相等,那么下面的循环会循环两次,第一次循环后把两个链表的指针交换,同时完成末端对齐。大神就是大神。。
    while( a != b){    
    	//for the end of first iteration, we just reset the pointer to the head of another linkedlist
        a = a == null? headB : a.next;
        b = b == null? headA : b.next;    
    }
    
    return a;
}

从100亿随机数中找到前100万个最大的数

堆排序做法:先取出前100个数,维护一个100个数的最小堆,遍历一遍剩余的元素,在此过程中维护堆就可以了。具体步骤如下:
step1:取前m个元素(例如m=100),建立一个小顶堆。保持一个小顶堆得性质的步骤,运行时间为O(lgm);建立一个小顶堆运行时间为m*O(lgm)=O(m lgm);
step2:顺序读取后续元素,直到结束。每次读取一个元素,如果该元素比堆顶元素小,直接丢弃
如果大于堆顶元素,则用该元素替换堆顶元素,然后保持最小堆性质。最坏情况是每次都需要替换掉堆顶的最小元素,因此需要维护堆的代价为(N-m)*O(lgm);
最后这个堆中的元素就是前最大的10W个。时间复杂度为O(N lgm)。

根据快速排序划分的思想
(1) 递归对所有数据分成[a,b)b(b,d]两个区间,(b,d]区间内的数都是大于[a,b)区间内的数
(2) 对(b,d]重复(1)操作,直到最右边的区间个数小于100个。注意[a,b)区间不用划分
(3) 返回上一个区间,并返回此区间的数字数目。接着方法仍然是对上一区间的左边进行划分,分为[a2,b2)b2(b2,d2]两个区间,取(b2,d2]区间。如果个数不够,继续(3)操作,如果个数超过100的就重复1操作,直到最后右边只有100个数为止。

斐波那契,递归非递归 时间复杂度

概念:由于斐波纳挈数列是以兔子的繁殖引入的,因此也叫“兔子数列”。它指的是这样一个数列:0,1,1,2,3,5,8,13......从这组数可以很明显看出这样一个规律:从第三个数开始,后边一个数一定是在其之前两个数的和。在数学上,斐波纳挈数列可以以这样的公式表示:F(0) = 0 F(1) = 1 F(n) = F(n-1) + F(n-2),(n>=2)
既然该数列已经有这样一个规律:F(n) = F(n-1) + F(n-2);那么我们很容易就能想到用递归的方法,这样写出来的代码比较简洁

long long Fib1(long long num)
{
	assert(num >= 0);
 
	//递归
	if ((num == 1) || (num == 0))
	{
		return num;
	}
	return Fib1(num-1)+Fib1(num-2);
}

时间复杂度 ----- O(2^N)

由于使用递归时,其执行步骤是:要得到后一个数之前必须先计算出之前的两个数,即在每个递归调用时都会触发另外两个递归调用,例如:要得到F(10)之前得先得到F(9)、F(8),那么得到F(9)之前得先得到F(8)、F(7)......如此递归下去

从上图我们可以看出,这样的计算是以 2 的次方在增长的。除此之外,我们也可以看到,F(8)和F(7)的值都被多次计算,如果递归的深度越深,那么F(8)和F(7)的值会被计算更多次,但是这样计算的结果都是一样的,除了其中之一外,其余的都是浪费,可想而知,这样的开销是非常恐怖的!

两种非递归算法来实现:

@@:时间复杂度为O(N),空间复杂度为O(N)

创建一个数组,每次将前两个数相加后直接赋给后一个数。这样的话,有N个数就创建一个包含N个数的一维数组,所以空间复杂度为O(N);由于只需从头向尾遍历一边,时间复杂度为O(N)

long long* Fib2(long long num)
{
	assert(num >= 0);
	//非递归
	long long* array = new long long[num+1];
	array[0] = 0;
	array[1] = 1;
	for (int i=2; i<=num; i++)
	{
		array[i] = array[i-1] + array[i-2];
	}
	return array;
}

linux:

linux常用指令(说了10个左右)

1、cd命令:它用于切换当前目录,它的参数是要切换到的目录的路径,可以是绝对路径,也可以是相对路径。
2、ls命令:查看文件与目录的命令,list之意,它的参数非常多
3、grep命令:该命令常用于分析一行的信息,若当中有我们所需要的信息,就将该行显示出来,该命令通常与管道命令一起使用,用于对一些命令的输出进行筛选加工等等,它的简单语法为grep [-acinv] [--color=auto] '查找字符串' filename
# 取出文件/etc/man.config中包含MANPATH的行,并把找到的关键字加上颜色
grep --color=auto 'MANPATH' /etc/man.config
# 把ls -l的输出中包含字母file(不区分大小写)的内容输出
ls -l | grep -i file
4、find命令:基于查找的功能非常强大的命令,相对而言,它的使用也相对较为复杂,参数也比较多,所以在这里将给把它们分类列出,它的基本语法如下:find [PATH] [option] [action]
find /root -mtime 0 # 在当前目录下查找今天之内有改动的文件
5、cp命令:该命令用于复制文件,copy之意,它还可以把多个文件一次性地复制到一个目录下,它的常用参数如下:
cp -a file1 file2 #连同文件的所有特性把文件file1复制成文件file2
cp file1 file2 file3 dir #把文件file1、file2、file3复制到目录dir中
6、mv命令:该命令用于移动文件、目录或更名,move之意。

7、rm命令:该命令用于删除文件或目录,remove之间。

rm -i file # 删除文件file,在删除之前会询问是否进行该操作

rm -fr dir # 强制删除目录dir中的所有文件

8、ps命令:用于将某个时间点的进程运行情况选取下来并输出,process之意。

其实我们只要记住ps一般使用的命令参数搭配即可,它们并不多,如下:

ps aux # 查看系统所有的进程数据
ps ax # 查看不与terminal有关的所有进程
ps -lA # 查看系统所有的进程数据
ps axjf # 查看连同一部分进程树状态

9、kill命令

该命令用于向某个工作(%jobnumber)或者是某个PID(数字)传送一个信号,它通常与ps和jobs命令一起使用,它的基本语法如下:

kill -signal PID

例如:

# 以正常的结束进程方式来终于第一个后台工作,可用jobs命令查看后台中的第一个工作进程
kill -SIGTERM %1 
# 重新改动进程ID为PID的进程,PID可用ps命令通过管道命令加上grep命令进行筛选获得
kill -SIGHUP PID

10、tar命令

只需要记住下面三条命令即可:
压缩:tar -jcv -f filename.tar.bz2 要被处理的文件或目录名称
查询:tar -jtv -f filename.tar.bz2
解压:tar -jxv -f filename.tar.bz2 -C 欲解压缩的目录
注:文件名并不定要以后缀tar.bz2结尾,这里主要是为了说明使用的压缩程序为bzip2
11、cat命令

该命令用于查看文本文件的内容,后接要查看的文件名,通常可用管道与more和less一起使用,从而可以一页页地查看数据。例如:

cat text | less # 查看text文件中的内容
# 注:这条命令也可以使用less text来代替

12、chmod命令:该命令用于改变文件的权限。

同时,chmod还可以使用u(user)、g(group)、o(other)、a(all)和+(加入)、-(删除)、=(设置)跟rwx搭配来对文件的权限进行更改。

# 例如:
chmod 0755 file # 把file的文件权限改变为-rxwr-xr-x
chmod g+w file # 向file的文件权限中加入用户组可写权限

13、vim命令:该命令主要用于文本编辑,它接一个或多个文件名作为参数,如果文件存在就打开,如果文件不存在就以该文件名创建一个文件。vim是一个非常好用的文本编辑器,它里面有很多非常好用的命令,在这里不再多说。你可以从这里下载vim常用操作的详细说明。

14、gcc命令
对于一个用Linux开发C程序的人来说,这个命令就非常重要了,它用于把C语言的源程序文件,编译成可执行程序,由于g++的很多参数跟它非常相似,所以这里只介绍gcc的参数,它的常用参数如下:

-o :output之意,用于指定生成一个可执行文件的文件名
-c :用于把源文件生成目标文件(.o),并阻止编译器创建一个完整的程序
-I :增加编译时搜索头文件的路径
-L :增加编译时搜索静态连接库的路径
-S :把源文件生成汇编代码文件
-lm:表示标准库的目录中名为libm.a的函数库
-lpthread :连接NPTL实现的线程库
-std= :用于指定把使用的C语言的版本

# 例如:
# 把源文件test.c按照c99标准编译成可执行程序test
gcc -o test test.c -lm -std=c99
#把源文件test.c转换为相应的汇编程序源文件test.s
gcc -S test.c

15、看日志(cat,head,tail,more)

grep|wc -l

数据库:

关系型数据库:

mangodb

mysql(sql,慢查询,配置)

oracal

GP数据库

非关系型数据库:

redis

服务架构:

服务分布式架构(超融合):概念实现理解

数据库中索引和主键有什么相同点和区别

主键是表中的一个或多个字段,它的值用于惟一地标识表中的某一条记录.;使用索引可快速访问数据库表中的特定信息。
索引是对数据库表中一列或多列的值进行排序的一种结构,只有当经常查询索引列中的数据时,才需要在表上创建索引。索引占用磁盘空间,并且降低添加、删除和更新行的速度。当然索引也有好处就是查询速度快,它利还是大于弊的所以请慎重使用索引。

网络

tcp和udp的区别

测试开发面试题_第2张图片

TCP编程的服务器端一般步骤是: 
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt(); * 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind(); 
  4、开启监听,用函数listen(); 
  5、接收客户端上来的连接,用函数accept(); 
  6、收发数据,用函数send()和recv(),或者read()和write(); 
  7、关闭网络连接; 
  8、关闭监听; 

TCP编程的客户端一般步骤是: 
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt();* 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 
  4、设置要连接的对方的IP地址和端口等属性; 
  5、连接服务器,用函数connect(); 
  6、收发数据,用函数send()和recv(),或者read()和write(); 
  7、关闭网络连接;

UDP:
与之对应的UDP编程步骤要简单许多,分别如下: 
  UDP编程的服务器端一般步骤是: 
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt();* 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind(); 
  4、循环接收数据,用函数recvfrom(); 
  5、关闭网络连接; 

UDP编程的客户端一般步骤是: 
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt();* 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 
  4、设置对方的IP地址和端口等属性; 
  5、发送数据,用函数sendto(); 
  6、关闭网络连接;

dns的解析过程

概念:DNS的全称是domain name system,即域名系统。DNS是因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的去访问互联网而不用去记住能够被机器直接读取的IP地址。通过域名,最终得到该域名对应的IP地址的过程则是域名解析的过程。

解析方法:

1、递归查询

测试开发面试题_第3张图片

递归查询时如果客户端所询问的本地域名服务器不知道被查询的域名的IP地址,那么本地域名服务器就以DNS客户的身份,向其他顶级域名服务器继续发出查询,直到查询到结果后,再层层传递回来。

2、迭代查询

测试开发面试题_第4张图片

总结:

测试开发面试题_第5张图片

当我们在浏览器中输入一个网站时,会发生如下过程

1、浏览器中输入想要访问的网站的域名,操作系统会先检查本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。

2、如果hosts里没有这个域名的映射,客户端会向本地DNS服务器发起查询。本地DNS服务器收到查询时,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析。

3、如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置,采用递归或者迭代查询,直至解析完成。

dns属于udp还是tcp,原因

DNS同时占用UDP和TCP端口53是公认的,这种单个应用协议同时使用两种传输协议的情况在TCP/IP栈也算是个另类。但很少有人知道DNS分别在什么情况下使用这两种协议。

为什么既使用TCP又使用UDP? 
首先了解一下TCP与UDP传送字节的长度限制: 
UDP报文的最大长度为512字节,而TCP则允许报文长度超过512字节。当DNS查询超过512字节时,协议的TC标志出现删除标志,这时则使用TCP发送。通常传统的UDP报文一般不会大于512字节。 
区域传送时使用TCP,主要有一下两点考虑: 
1.辅域名服务器会定时(一般时3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,则会执行一次区域传送,进行数据同步。区域传送将使用TCP而不是UDP,因为数据同步传送的数据量比一个请求和应答的数据量要多得多。 
2.TCP是一种可靠的连接,保证了数据的准确性。 
域名解析时使用UDP协议: 
客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过TCP三次握手,这样DNS服务器负载更低,响应更快。虽然从理论上说,客户端也可以指定向DNS服务器查询的时候使用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。

ISO七层的作用,分别有什么协议

webp

给定ip,url,time等参数,去重获取其中一天,某一时间段得日志ip信息

(采用了set方法,time和logging模块)好像面试官不是很满意

后来想想可以用linux查logger文件,ls-ld获取某天全部日志信息,再py去重。。

典型例题

(一).Web页面出现空白页怎么定位问题

1.抓包(抓包)

2.看服务日志

3.看你当前url 用接口实际访问模拟下请求

4.mock数据,给请求,确认是那部分问题

 

(二).Web页面响应过慢怎么定位问题

从一个浏览器输入url到形成页面经历了什么

(三).你所测试的系统架构

测试用例的题目:微信有发送文字消息的功能,如果让你设计功能点,你会设计什么样的测试用例来测试它的功能是不是正确的

1、根据需求文档,完全按照需求文档框架/功能描述,根据自己的理解整理为用例。简单来说,就是将需求文档描述的内容,重新按照用例的格式编辑一次,把能想到的各种可能性添加进去。

2、搜索其他测试人员编写的同类型功能用例,先理解,再根据项目实际需求的较小差异,重新新增/删/改,组成满足需求的用例组。

有一个场景要测试:比如说一个微信有群聊功能,怎么测试这个功能是不是正确的,确保这个群聊可以用

你为了软件测试这个岗位做了什么准备呢?

对测试开发的理解

测试开发工程师是属于测试工程师的。与纯测试不同的是,还需要有编码能力,能够写一些测试工具,脚本来帮助提高测试效率。

给你一个需求,怎么开始测试;发版前遇到重大bug,怎么处理?

在跟进版本过程中要处理很多事情,怎么平衡?

你觉得测试最重要的是什么?

尽可能的找出软件的错误

职业规划

参考

https://blog.csdn.net/qq_30758629/article/details/81568366

你可能感兴趣的:(面试题汇总,测试工程师,面试)