兰瑟作为一个已经工作有 4 年经验的测试工程师,其间也辗转了几个大的互联网公司,虽然确实缺少了一些稳定性,但同时也积累了一些面试的经验,不才分享一些给大家。那么主要是针对测试工程师的一些总结,对于其他的工种,我可能会在别的文章中去总结一些面试技巧,本文会着重于测试工程师的面经。
测试的面试重点分为两大部分:技术,项目
扩充一下:技术的一些注意点,项目上的一些处理方式(有些还会有一些沟通上的小技巧),可能不会写的特别详细,但点我都会点到,后续会再继续补充(近 3 万字的长文预警,希望能帮助到各位互联网的孩子们)
那么直接上货,希望能帮助到各位同行,或者不是同行却也能激发起你们的灵感的伙伴们~
一.黑盒测试方法 (可能会问等价类的分类,等价类和边界值是最重要的:
1、等价类划分:
(有效等价类:对于程序规格说明来说,是合理的,有意义的输入数据构成的集合)
(无效等价类:对于程序规格说明来说,是不合理的,无意义的输入数据构成的集合)
2、边界值分析方法
3、因果图方法
4、正交实验设计方法
5、功能图分析方法
6、错误推测法
7、需求文档转化法
8、随机测试
9、对象属性分析法
二.白盒测试方法 (可以选择性记忆....不知道会不会问):
1.语句覆盖:就是设计若干个测试用例,运行被测程序,使得每一可执行语句至少执行一次。
2.判定覆盖:使设计的测试用例保证程序中每个判断的每个取值分支至少经历一次。
3.条件覆盖:条件覆盖是指选择足够的测试用例,使得运行这些测试用例时,判定中每个条件的所有可能结果至少出现一次,但未必能覆盖全部分支
4.判定条件覆盖:判定 - 条件覆盖就是设计足够的测试用例,使得判断中每个条件的所有可能取值至少执行一次,同时每个判断的所有可能判断结果至少执行,即要求各个判断的所有可能的条件取值组合至少执行一次。
5.条件组合覆盖:在白盒测试法中,选择足够的测试用例,使所有判定中各条件判断结果的所有组合至少出现一次,满足这种覆盖标准成为条件组合覆盖。
6.路径覆盖:是每条可能执行到的路径至少执行一次。
补充:
(1)语句覆盖在所有的测试方法中是一种最弱的覆盖。
(2)判定覆盖和条件覆盖比语句覆盖强,满足判定/条件覆盖标准的测试用例一定也满足判定覆盖、条件覆盖和语句覆盖
(3)路径覆盖也是一种比较强的覆盖,但未必考虑判定条件结果的组合,并不能代替条件覆盖和条件组合覆盖。
三.TCP/IP 分层协议 (每层的协议要注意):
1.链路层(数据链路层/网络接口层):包括操作系统中的设备驱动程序、计算机中对应的网络接口卡
2.网络层(互联网层):处理分组在网络中的活动,比如分组的选路。
3.运输层:主要为两台主机上的应用提供端到端的通信。
4.应用层:负责处理特定的应用程序细节。
TCP 和 UDP 的区别(网络上的知识点):
1、TCP 面向连接(如打电话要先拨号建立连接);UDP 是无连接的,即发送数据之前不需要建立连接
2、TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付
3、TCP 面向字节流,实际上是 TCP 把数据看成一连串无结构的字节流;UDP 是面向报文的
UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等)
4、每一条 TCP 连接只能是点到点的;UDP 支持一对一,一对多,多对一和多对多的交互通信
5、TCP 首部开销 20 字节;UDP 的首部开销小,只有 8 个字节
6、TCP 的逻辑通信信道是全双工的可靠信道,UDP 则是不可靠信道
四.TCP/IP 三次握手,四次挥手(常问项)
三次握手:
第一次握手(SYN=1,seq=x):
客户端发送一个 TCP 的 SYN 标志位置 1 的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。
第二次握手(SYN=1,ACK=1,seq=y,ACKnum=x+1):
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为 1。服务器端选择自己的 ISN 序列号,放在 seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加 1,即 X+1。发送完毕后,服务器端进入 SYN_RCVD 状态。
第三次握手(ACK=1,ACKnum=y+1):
客户端再次发送确认包(ACK),SYN 标志位为 0,ACK 标志位为 1,并且把服务器发来 ACK 的序号字段 +1,放在确定字段中发送给对方,并且在数据段放写 ISN 的 +1。
发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束,TCP 连接建立完成
我的理解....:
A 问 B:你听到了么,发确认信息
B 回答 A:听到了,告诉 A 它能接收到 A 的消息
A 再回 B:我能接收到你的消息,再发一次确认 ,然后建立连接
四次挥手:
第一次挥手(FIN=1,seq=x):
假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为 1 的包,表示自己已经没有数据可以发送了,但是仍然可以接收数据。
发送完毕之后,客户端进入 FIN_WAIT_1 状态。
第二次挥手(ACK=1,ACKnum=x+1):
服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接收到了客户端关闭连接的请求,但还没有准备好关闭连接。
发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后进入 FIN_WAIT_2 状态,等待服务器端关闭连接。
第三次挥手(FIN=1,seq=y):
服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为 1。
发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个 ACK
第四次挥手(ACK=1,ACKnum=y+1):
客户端接收到来自服务器的端的关闭请求,发送一个确认包,并进入 TIME_WAIT 状态,等待可能出现的要重传的 ACK 包。
服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。
客户端等待了某个固定时间(两个最大段生命周期,2MSL,2Maximum Segment Lifetime)之后,没有收到服务器端的 ACK,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。
为什么是三次,不是两次或者四次 (这个问题真的可能会被问到)
两次握手并不能保证可靠性 (B 不确定 A 能收到自己的信息),四次握手又浪费了效率
五.OSI 七层模型 (记一记应用层,传输层,网络层我觉得就可以了....)
六. DNS(运行在 UDP 协议上,端口 53)
概念:dns 是一个域名系统,是万维网上作为域名和 IP 地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的 IP 数串
七:http 协议 (https://www.cnblogs.com/ranyonsue/p/5984001.html细致的大家可以阅读这一篇)
restful 接口:
1.URI 资源 2.表现:XML,HTML 等格式 3.状态转移:get,post 等
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少
HTTPS:是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版,即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。
HTTP 和 HTTPS 区别:(这个还挺重要的,端口号稍微记一下)
1、https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用。
2、http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议。
3、http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
4、http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。
HTTP 协议特点:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有 GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type(Content-Type 是 HTTP 包中用来表示内容类型的标识)加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP 原理:
1、客户端连接到 Web 服务器
一个 HTTP 客户端,通常是浏览器,与 Web 服务器的 HTTP 端口(默认为 80)建立一个 TCP 套接字连接。
2、发送 HTTP 请求
通过 TCP 套接字,客户端向 Web 服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据 4 部分组成。
3、服务器接受请求并返回 HTTP 响应
Web 服务器解析请求,定位请求资源。服务器将资源复本写到 TCP 套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据 4 部分组成。
4、释放连接 TCP 连接
若 connection 模式为 close,则服务器主动关闭 TCP 连接,客户端被动关闭连接,释放 TCP 连接;若 connection 模式为 keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
5、客户端浏览器解析 HTML 内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的 HTML 文档和文档的字符集。客户端浏览器读取响应数据 HTML,根据 HTML 的语法对其进行格式化,并在浏览器窗口中显示。
GET 和 POST 请求的区别 (个人感觉这个是要了解的):
1.GET 提交的数据会放在 URL 之后,以?分割 URL 和传输数据,参数之间以&相连,如 EditPosts.aspx?name=test1&id=123456. POST 方法是把提交的数据放在 HTTP 包的 Body 中.
2.GET 提交的数据大小有限制(因为浏览器对 URL 的长度有限制),而 POST 方法提交的数据没有限制.
3.GET 方式需要使用 Request.QueryString 来取得变量的值,而 POST 方式通过 Request.Form 来获取变量的值。
4.GET 方式提交数据,会带来安全问题,比如一个登录页面,通过 GET 方式提交数据时,用户名和密码将出现在 URL 上,如果页面可以被缓存或者其他人可以访问这台机器,就可以从历史记录获得该用户的账号和密码.
状态码:
1xx:指示信息 -- 表示请求已接收,继续处理
2xx:成功 -- 表示请求已被成功接收、理解、接受
3xx:重定向 -- 要完成请求必须进行更进一步的操作
4xx:客户端错误 -- 请求有语法错误或请求无法实现
5xx:服务器端错误 -- 服务器未能实现合法的请求
常见状态码:
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的 URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
八:TestNG(这个我自己用过,感兴趣也可以看看) testng 传参方式 (parameter 在 testng.xml 或者通过 dataprovider)
运行方式:1.Run as 2.testng.xml
按顺序执行:preserve-order=true
忽略测试:@Test(enable=false)
分组测试:@Test(groups=..)
依赖测试:@Test(dependsonmethods=...)
结果在 oup-put,日志级别是 verbose
并发运行用例:parallel=methods
九:appium(可以稍稍了解,和 selenium 异曲同工,有些点我觉得是 UI 自动化想通的)
特点 (为什么流行我觉得):
1.左边的 WebDriver script 是我们的 selenium 测试脚本 (其实就是测试代码)
2.中间是起的 Appium 的服务,Appium 在这边起了一个 Server(4723 端口),跟 selenium
Webdriver 测试框架类似,Appium ⽀支持标准的 WebDriver JSONWireProtocol 。在这里提供了一套 web 服务,Appium Server 接收 web driver 标准请求,解析请求内容,调⽤用对应的框架响应操作。
如:脚本发送一个点击按钮的请求给 appium server,
1.左边的 WebDriver script 是 selenium 测试脚本
2.中间是起的 Appium 的服务,Appium 在这边起了⼀一个 Server(4723 端口),跟 selenium
Webdriver 测试框架类似,Appium ⽀支持标准的 WebDriver JSONWireProtocol 。在这里提供了一套 web 服务,Appium Server 接收 web driver 标准请求,解析请求内容,调⽤用对应的框架响应操作。
如:脚本发送一个点击按钮的请求给 appium server,
十. linux 常用命令 (我觉得比较可能问的多的)
Cd:切换目录
当前目录和上层目录:./ ../
主目录:~/
查看当前路径:pwd
清屏:clear
退出当前命令:ctrl+c 彻底退出
软链接:ln -s slink source
查找自己所在的终端信息:who am i
查看当前谁在使用该主机:who
ls -l (也可以直接 ll ) :列出长数据串,包含文件的属性与权限数据等
ls -a :列出全部的文件,连同隐藏文件(开头为.的文件)一起列出来(常用)
find -name 文件名 :找匹配的文件名
mkdir :创建指定的名称的目录
cp -a file1 file2 :连同文件的所有特性把文件 file1 复制成文件 file2
cp file1 file2 file3 dir :把文件 file1、file2、file3 复制到目录 dir 中
mv file1 file2 file3 dir : 把文件 file1、file2、file3 移动到目录 dir 中
mv file1 file2 : 把文件 file1 重命名为 file2
rm -fr dir : 强制删除目录 dir 中的所有文件
ps -ef|grep java :找出所有 java 进程
kill -9 进程号 :彻底杀死某个进程
chmod 改变文件的权限
语法:chmod
多数用三位八进制数字的形式来表示权限,第一位指定属主的权限,第二位指定组权限,第三位指定其他用户的权限,每位通过 4(读)、2(写)、1(执行) 三种数值的和来确定权限。如 6(4+2) 代表有读写权,7(4+2+1) 有读、写和执行的权限
chmod u+x file :给 file 的属主增加执行权限
vi :文件名 # 编辑方式查看,可修改
cat :文件名 # 显示全部文件内容
more :文件名 # 分页显示文件内容
less :文件名 # 与 more 相似,更好的是可以往前翻页
head :文件名 # 仅查看头部,还可以指定行数
tail -f 20160921.logs :查看正在改变的日志文件
tail -3000 catalina.out:查看倒数前 3000 行的数据
history:查看用过的命令列表
df -hl:查看磁盘使用空间
which :只能查可执行文件
whereis :只能查二进制文件、说明文档,源文件等
du :显示目录或文件的大小
df :显示每个<文件>所在的文件系统的信息,默认是显示所有文件系统
df 命令获得真正的文件系统数据,而 du 命令只查看文件系统的部分情况
bash shell 的内置命令 let 可以进行整型数的数学运算
free:显示系统当前内存的使用情况,包括已用内存、可用内存和交换内存的情况
top:显示当前系统中占用资源最多的一些进程
netstat -anp|grep port:查看某端口是否被占用
chown -R:更改某个文件或目录的属主和属组
Shift + PageUp:翻页
清空文件:echo "" > filename 或者 cat /dev/null > a.txt 或者>a.txt
Linux 统计文件中出现的次数:
(1) 单个字符串:grep -o targetstr filename | wc -l
多个字符串:grep -o “targetstr_1\targetstr_2” filename | wc -l
(2) awk '{s+=gsub(/targetStr/,"&")}END{print s}' filename
Linux 查找某个文件中的某个词:
grep ‘test’a,b,c 在文件 a,b,c 中寻找 test 这个词
grep -r 'test' . # 在当前目录中找 test 这个词
grep -r 'test' example # 在 example 目录中找 test 这个词
wc -l filename: 查看文件里有多少行
uniq testfile: 删除一个文件中重复都是行
sort testfile1 | uniq:删除重复之后进行排序 (次数的)
十一.Mysql(乱七八糟语句不写了,写点我觉得可能会被问到的)
授权语句:
grant select, insert, update, delete on testdb.* to common_user@'%'
事务:
1.原子性: 要么全部完成,要么不完成,若发生错误会进行回滚操作;
2.一致性: 开始到结束后,数据库完整性约束没收到破坏;(实体完整性,参照完整性,用户定义的完整性)
3.隔离性: 事务与事务之间相隔离,串行化执行;
4.持久性: 事务完成对数据的影响是永久的;
四个隔离:
1.脏读
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
当一个事务正在多次修改某个数据,而在这个事务中这多次的修改都还未提交,这时一个并发的事务来访问该数据,就会造成两个事务得到的数据不一致。例如:用户 A 向用户 B 转账 100 元,对应 SQL 命令如下
update account set money=money+100 where name=’B’; (此时 A 通知 B)
update account set money=money - 100 where name=’A’;
当只执行第一条 SQL 时,A 通知 B 查看账户,B 发现确实钱已到账(此时即发生了脏读),而之后无论第二条 SQL 是否执行,只要该事务不提交,则所有操作都将回滚,那么当 B 以后再次查看账户时就会发现钱其实并没有转。
2.不可重复读
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了
3.虚读 (幻读)
幻读是事务非独立执行时发生的一种现象。例如事务 T1 对一个表中所有的行的某个数据项做了从 “1” 修改为 “2” 的操作,这时事务 T2 又对这个表中插入了一行数据项,而这个数据项的数值还是为 “1” 并且提交给数据库。而操作事务 T1 的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务 T2 中添加的,就好像产生幻觉一样,这就是发生了幻读
Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
Repeatable read (可重复读):可避免脏读、不可重复读的发生。
Read committed (读已提交):可避免脏读的发生。
Read uncommitted (读未提交):最低级别,任何情况都无法保证。
四种隔离级别最高的是 Serializable 级别,最低的是 Read uncommitted 级别,级别越高,执行效率就越低。
主键,外键:
主键 :对表中数据进行唯一标识的数据列的组合;不能缺失;不能空值;
外键 :该列为另一表的主键
索引:
1.数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。索引的实现通常使用 B 树及其变种 B+ 树
2.通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
CREATE INDEX index_name ON table_name(username(length));
建立索引的缺陷:
1.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行 INSERT,UPDATE 和 DELETE。因为更新表时,mysql 不仅要保存数据,还要保存一下索引文件
2.建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在要给大表上建了多种组合索引,索引文件会膨胀很宽
drop,delete 与 truncate 的区别
drop 直接删掉表 truncate 删除表中数据,再插入时自增长 id 又从 1 开始 delete 删除表中数据,可以加 where 字句
一般而言,drop > truncate > delete
连接种类,区别:
Inner join,left join,right join,full join
分库分表:
数据库引擎:myisam 和 innodb,前者比较适合大量 select,事务不安全;后者支持外键,事务安全,,适合大量 update,insert
十二.Jmeter
1.性能测试几个概念
TPS:每秒钟 request/事务 数量
并发数: 系统同时处理的 request/事务数
响应时间: 一般取平均响应时间
下面几个概念可以看看
负载测试(Load Test):负载测试是一种性能测试,指数据在超负荷环境中运行,程序是否能够承担 (通俗讲我觉得就是到了拐点就停了,再往上指标也不会上涨)
压力测试(Stress Test): 压力测试(又叫强度测试)也是一种性能测试,它在系统资源特别低的情况下软件系统运行情况,目的是找到系统在哪里失效以及如何失效的地方。
(1) 稳定性压力测试:在选定的压力值下,长时间持续运行。通过这类压力测试,可以考察各项性能指标是否在指定范围内,有无内存泄漏、有无功能性故障等;
(2) 破坏性压力测试:在稳定性压力测试中可能会出现一些问题,如系统性能明显降低,但很难暴露出其真实的原因。通过破坏性不断加压的手段,往往能快速造成系统的崩溃或让问题明显的暴露出来
极限测试 Extreme testing:在过量用户下的负载测试 Hammer testing:连续执行所有能做的操作
像一般性能测试可能会发现数据库连接上的错误,代码的异常,也有可能是 jmeter 自身这个软件有性能瓶颈
Jmeter-plugins-manager(一个插件)
下载之后放到 lib/ext 下面,重启,然后就如图
1.其中 Transaction per Second 就是 tps 图,Response Time Over Time 就是平均响应时间,方便实时观察,而不是最后看查看结果树
2.一般短的压测都是相同条件压三次取平均值
3.一般很少会直接压线上,所以会有一个线上和测试的机器参数对比,有一个倍数关系,测试环境做完压测后再计算大概线上的结果
怎么确定性能指标?
1.互联网上对于用户响应时间,有一个普遍的标准,2-5-10 原则
2.1.5 倍峰值作为参考 + 服务器 (内存,CPU 等等)
jmeter 怎么用上一个接口的结果作为下一个接口的参数 (使用 Json extractor)-加分点
十三.测试用例设计
这一块的东西我写个大致的范围....
登陆模块
1.功能用例
2.兼容性 (app 版本,操作系统版本,不同移动设备分辨率)
3.性能上 (单用户的响应时间,高并发,长时间多用户登陆)
4.安全性 (加密,SQL 注入 (通过把 SQL 命令插入到 Web 表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令),脚本攻击,多设备登陆的互斥)
5.弱网 (android 在 fiddler 下,ios 通过自身的 status ,下一章写)
6.UI 测试
7.可用性,易用性 (全键盘输入,enter,tab)
8.本地化 (多语言)
还有很多,测试纸杯,电梯,购物车,支付功能 (这都是我面试遇到过的) 很多别的也可以考虑这些方面,反正都凭自身经验吧~~
十四.弱网测试
1.IOS
IOS 平台,通过自带的开发者选项 --Network Link Conditioner, 简单的模拟各种速度的网络
2.android
Fiddler :
1.先开启网络模拟
2.开启延迟
然后编辑脚本
每上传和下载 1KB 的数据要延迟多少秒
Charles:
延迟设置 --选择相应的网络延迟设置或者自定义延迟 -- 开启延迟即可
charles 抓 https 的包:
1.安装 Charles
2.电脑安装 Charles 证书 (install charles root certificate)
3.手机安装证书 (install charles root certificate on a mobile device or a remote browser)
4.手机网页输入网址 chls.pro/ssl 后提示下载证书并信任 (ios11 开始需要手动信任描述文件)
5.开始抓包
Charles 设置 Proxy
Proxy -> SSL Proxying Settings
6.把想要抓 https 包的站点添加到 Proxy -> SSL Proxying Settings--include 中即可
原理 (简单说就是 charles 伪装自己拿到 CA 证书后先从客户端拿到公钥,加密后给服务器,服务器再用用私钥解密再返回响应给客户端):
(1) Charles 拦截客户端的请求,伪装成客户端向服务器进行请求
(2) 服务器向 “客户端”(实际上是 Charles)返回服务器的 CA 证书
(3) Charles 拦截服务器的响应,获取服务器证书公钥,然后自己制作一张证书,将服务器证书替换后发送给客户端。(这一步,Charles 拿到了服务器证书的公钥)
(4) 客户端接收到 “服务器”(实际上是 Charles)的证书后,生成一个对称密钥,用 Charles 的公钥加密,发送给 “服务器”(Charles)
(5) Charles 拦截客户端的响应,用自己的私钥解密对称密钥,然后用服务器证书公钥加密,发送给服务器。(这一步,Charles 拿到了对称密钥)
(6) 服务器用自己的私钥解密对称密钥,向 “客户端”(Charles)发送响应
(7) Charles 拦截服务器的响应,替换成自己的证书后发送给客户端
十五.Fiddler(我觉得知道怎么改数据的方式就行了)
打断点和 AutoResponder 的区别,注意修改数据后请求超时导致客户端不做请求
1、打断点,是阻塞了请求,一直没有结果返回,请求将在线程中一直存在,直到超时被踢出来。
2、AutoResponder 返回 404/502,这种情况是有结果返回的,代表请求也结束了,不会在线程中一直存在
fiddler 抓 https 包:
(1) 原理同 charles,首先:给 fiddler 安装 certmaker 插件 (然后重启)
(2) Tools->Fiddler Options->HTTPS ,Actions-> Trust Root Certificate,弹框后安装 CA 证书
安装成功后可以通过 Actions—>open windows certificate Manager 查看安装的证书
(3) 手机安装 Fiddler 证书,打开手机浏览器,在浏览器地址输入代理服务器 IP 和端口
点击之后安装证书即可
十六.APP crash
1.crash 常见的原因 (空指针,内存泄漏,数组越界,调用高版本 API)
设备碎片化:由于设备极具多样性,App 在不同的设备上可能有表现不同。
带宽限制:带宽不佳的网络对 App 所需的快速响应时间可能不够。
网络的变化:不同网络间的切换可能会影响 App 的稳定性。
内存管理:可用内存过低,或非授权的内存位置的使用可能会导致 App 失败。
用户过多:连接数量过多可能会导致 App 崩溃。
代码错误:没有经过测试的新功能,可能会导致 App 在生产环境中失败。
(可能是 java 的 UnChecked 异常发生时,由于没有相应的 try…catch 处理该异常对象,所以 Java 运行环境将会终止,程序将退出)
第三方服务:广告或弹出屏幕可能会导致 App 崩溃。
2.App 崩溃的测试用例设计:
验证在有不同的屏幕分辨率,操作系统和运营商的多个设备上的 App 行为。
用新发布的操作系统版本验证 App 的行为。
验证在如隧道,电梯等网络质量突然改变的环境中的 App 行为。
通过手动网络从蜂窝更改到 Wi-Fi ,或反过来,验证 App 行为。
验证在没有网络的环境中的 App 行为。
验证来电/短信和设备特定的警报(如警报和通知)时的 App 行为。
通过改变设备的方向,以不同的视图模式,验证 App 行为。
验证设备内存不足时的 App 行为。
通过用测试工具施加载荷验证 App 行为。
十七.Git(命令为主)
简单命令
git clone
git status 查看仓库状态
git diff * 查看 X 文件修改了那些内容
git log 查看历史记录
git reset –hard HEAD^ 回退到上一个版本
git reset --hard HEAD~第几个 如果想回退到第 3 个版本,使用 git reset –hard HEAD~3
git branch 查看本地所有的分支
git branch -a 查看远程所有的分支
git branch name 创建分支
git branch –d dev 删除 dev 分支
git checkout –b dev 创建 dev 分支 并切换到 dev 分支上
git merge dev 在当前分支上合并 dev 分支代
提交代码三部曲哈哈哈:
git add * 把 x 文件添加到暂存区去
git commit –m "*" 提交文件 –m 后面的是注释
git push
十八.Monkey(命令用到查就行了这个,要知道-p 是指定包)
1.Monkey 程序由 Android 系统自带,使用 Java 语言写成,在 Android 文件系统中的存放路径是:/sdk/sdk/tools/lib/monkey.jar
2.Monkey.jar 程序是由一个名为 “monkey” 的 Shell 脚本来启动执行,shell 脚本在 Android 文件系统中的存放路径是:/sdk/sdk/tools/bin/monkey
十九.Tomcat(想不到啥,有可能会问问)
Tomcat 的缺省端口及修改 (服务的部署新站点的时候就会改这个,要不然端口冲突)
1.找到 Tomcat 目录下的 conf 文件夹
2.进入 conf 文件夹里面找到 server.xml 文件
3.打开 server.xml 文件
4.在 server.xml 文件里面找到下列信息
将 8080 改成你想要的端口即可
Tomcat 部署方式 (服务的用的多的是 2,有空可以稍微了解下,server.xml 最下面就是第二点那种,如果我没记错的话哈哈~~)
1.直接把 Web 项目放在 webapps 下,Tomcat 会自动将其部署
2.在 server.xml 文件上配置节点,设置相关的属性即可
3.通过 Catalina 来进行配置:进入到 conf\Catalina\localhost 文件下,创建一个 xml 文件,该文件的名字就是站点的名字,编写 XML 的方式来进行设置。
二十.排序算法 (单独就列这个算法吧,其他算法先不用看了...因为这个是我印象最深的被问过最多的,可以看这篇,写的很全https://blog.csdn.net/hellozhxy/article/details/79911867,冒泡尤为重要)
总结:
1.一些概念
稳定:如果 a 原本在 b 前面,而 a=b,排序之后 a 仍然在 b 的前面;
不稳定:如果 a 原本在 b 的前面,而 a=b,排序之后 a 可能会出现在 b 的后面;
内排序:所有排序操作都在内存中完成;
外排序:由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行;
时间复杂度: 一个算法执行所耗费的时间。
空间复杂度:运行完一个程序所需内存的大小。
2.排序分类 图总结的挺好
(1) 冒泡排序 (你记住这个就行,一用百面通..问的最多哈哈)
算法描述:
1.比较相邻的元素,如果第一个比第二个大,就交换它们两个;
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
3.针对所有的元素重复以上的步骤,除了最后一个;
重复步骤 1~3,直到排序完成。
剩下的我就不写这里了,其实代码不懂也无所谓,我的经验是一般描述一下这个算法的过程就可以了,然后如果能写出来肯定是最好的,还是看面试时候的具体情况~~
二十一.Java 简单知识点 (我对 java 熟点,所以就写写 java 了~~,不过大同小异,本质一样的,一些语法不同而已,可以抽空看看简单的这些,还是有可能会问的)
1.面向对象的特征
(1) 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。
(2) 继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。
(3) 封装:通常认为封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口(可以想想普通洗衣机和全自动洗衣机的差别,明显全自动洗衣机封装更好因此操作起来更简单)。
(4) 多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。运行时的多态性可以解释为:当 A 系统访问 B 系统提供的服务时,B 系统有多种提供服务的方式,但一切对 A 系统来说都是透明的。
2.修饰符 (范围自上而下,看这个就够了~
这个图是一个完整的 java 程序,这样应该好理解点..子类我直接口述下:
3.java 数据类型
4.JDK、JRE、JVM 基本概念
JDK: Java Development kit Java 开发工具包
JRE: Java Runtime Environment Java 运行环境
JVM: Java virtual Machine Java 虚拟机
5.Java 程序编译和运行的过程(了解下就好)
(1) Java 编译程序将 Java 源程序翻译为 JVM 可执行代码 -- 字节码,创建完源文件之后,程序会先被编译成 “.class” 文件。
(2) 在编译好的 java 程序得到 “.class” 文件后,使用命令 java 运行这个 .class 文件,系统就会启动一个 jvm 进程,并找到主函数的入口,开始执行 main 函数。
6.int 和 Integer 的区别
Java 为了编程的方便引入不是对象的基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的封装类型(wrapper class),int 的封装类就是 Integer,从 JDK1.5 开始引入了自动封箱/解封箱机制,使得二者可以相互转换。
Java 为每个原始类型提供了封装类:
原始类型: boolean,char,byte,short,int,long,float,double
封装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
7.值传递和引用传递的区别
值传递:值传递是将进行传递的值进行拷贝,然后对拷贝之后的值进行传递,传递过程前后不改变原值的大小;
引用传递:引用传递是将需要传递值的地址进行传递,传递过程前后会改变原值的大小。
8.重载(Overload)和重写(Override)的区别
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常。重载对返回类型没有特殊的要求,不能根据返回类型进行区分
9.break 和 continue 的区别 (循环里面用到的关键字~)
break 是直接结束循环, 而 continue 不是直接结束本次循环而是跳过循环,继续执行下一次的循环
10.抽象类(abstract class)和接口(interface)的异同 (时间多的话可以看下)
接口和抽象类的相似性
(1) 接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。
(2) 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
接口和抽象类的区别
(1) 接口里只能包含抽象方法,静态方法和默认方法,不能为普通方法提供方法实现,抽象类则完全可以包含普通方法。
(2) 接口里只能定义静态常量,不能定义普通成员变量,抽象类里则既可以定义普通成员变量,也可以定义静态常量。
(3) 接口不能包含构造器,抽象类可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。
(4) 接口里不能包含初始化块,但抽象类里完全可以包含初始化块。
(5) 一个类最多只能有一个直接父类,包括抽象类,但一个类可以直接实现多个接口,通过实现
多个接口可以弥补 Java 单继承不足
11.final, finally, finalize(我简单概括)
final:当用 final 修饰类的时,表明该类不能被其他类所继承
finally:作为异常处理的一部分,它只能用在 try/catch 语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常)
finalize:finalize() 方法在垃圾收集器将对象从内存中清除之前做必要的清理工作,所有的类都继承了它
12.java 多线程的实现方式 (看一遍就行)
1.继承 Thread 类,重写 run 方法
2.实现 Runnable 接口,重写 run 方法,实现 Runnable 接口的实现类的实例对象作为 Thread 构造函数的 target
3.通过 Callable 和 FutureTask 创建线程
4.通过线程池创建线程
13.set list map(集合里面的,也简单概括)
集合类存放于 java.util 包中,类型主要有 3 种:set(集)、list(列表)和 map(映射)
(1) List 集合中对象按照索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象,例如通过 list.get(i) 方法来获取集合中的元素;
(2) Map 中的每一个元素包含一个键和一个值,成对出现,键对象不可以重复,值对象可以重复;
(3) Set 集合中的对象不按照特定的方式排序,并且没有重复对象,但它的实现类能对集合中的对象按照特定的方式排序,例如 Tree Set 类,可以按照默认顺序,也可以通过实现 Java.util.Comparator< Type >接口来自定义排序方式。
14.HashMap 和 HashTable
(1) HashMap 是线程不安全的,HashMap 是一个接口,是 Map 的一个子接口,是将键映射到值得对象,不允许键值重复,允许空键和空值;由于非线程安全, HashMap 的效率要较 HashTable 的效率高一些.
(2) HashTable 是线程安全的一个集合,不允许 null 值作为一个 key 值或者 Value 值;
(3) HashTable 是 sychronize(同步化),多个线程访问时不需要自己为它的方法实现同步,而 HashMap 在被多个线程访问的时候需要自己为它的方法实现同步
15.ArrayList 和 LinkedList的区别
1.ArrayList 是实现了基于动态数组的数据结构,LinkedList 基于链表的数据结构。
2.对于随机访问 get 和 set,ArrayList 效率优于 LinkedList,因为 LinkedList 要移动指针。
3.对于新增和删除操作 add 和 remove,LinedList 比较占优势,因为 ArrayList 要移动数据。
16.JAVA 的 GC
GC 是垃圾收集的意思,Java 提供的 GC 功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,垃圾回收可以有效的防止内存泄露,有效的使用可以使用的内存
实现 GC 的方法:System.gc() 或 Runtime.getRuntime().gc()
17.几个关键字
实现接口:implements
接口:interface
继承:extends
super:我们可以通过 super 关键字来实现对父类成员的访问,用来引用当前对象的父类
static: static 方法就是没有 this 的方法。在 static 方法内部不能调用非静态方法,反过来是可以的
18.equal 和==的区别
==:比较的是两个字符串内存地址(堆内存)的数值是否相等,属于数值比较;
equals():比较的是两个字符串的内容,属于内容比较。
19.进程和线程
1.进程是资源分配的最小单位,线程是程序执行的最小单位。
2.进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此 CPU 切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
3.线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC) 进行。不过如何处理好同步与互斥是编写多线程程序的难点。
4.多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
20.wait() 与 sleep() 的区别
1.sleep() 来自 Thread 类,和 wait() 来自 Object 类。调用 sleep() 方法的过程中,线程不会释放对象锁。而 调用 wait 方法线程会释放对象锁
2.sleep() 睡眠后不出让系统资源,wait 让其他线程可以占用 CPU
3.sleep(milliseconds) 需要指定一个睡眠时间,时间一到会自动唤醒.而 wait() 需要配合 notify() 或者 notifyAll() 使用
二十二.web 和 app 测试的区别 (感觉不是问这个就是问 android 和 ios 的区别)
1.兼容
2.性能上,比如电量,内存,CPU
3.健壮性,专项测试,比如中断,来电,短信,关机,弱网
4.因为 web 是基于浏览器的,app 是基于客户端的,所以要考虑 app 的安装,更新,卸载
5.app 的触摸
6.自动化,web 多为 selenium,app 多为 appium
二十三.nmon(性能监控工具)
nmon -s1 -c60 -f -m /home/nmon
参数说明:
-s1 每隔 n 秒抽样一次,这里为 1 秒
-c60 取出多少个抽样数量,这里为 60,即监控=1*60/60=1 分钟
-f 按标准格式输出文件名称:_YYMMDD_HHMM.nmon
-m 指定监控文件的存放目录,-m 后跟指定目录
二十四.Android 和 IOS 测试区别
1 . Android 长按 home 键呼出应用列表和切换应用,然后右滑则终止应用;
二十五.IOS 和 android 日志抓取
iOS:
1.通过 iTunes Connect(Manage Your Applications - View Details - Crash Reports)获取用户的 crash 日志
2.通过 Xcode 从你的设备上获得崩溃日志
3.自己在程序中添加崩溃捕捉代码,如果应用集成第三方 SDK,如百度统计
Android:
1.通过集成第三方 SDK,如百度统计、友盟统计等
2、发版时使用加固工具,他们也会收集错误日志,如 360 加固
3、在程序中添加程序异常崩溃的捕捉代码,保存到本地文件中
二十六.SQL 注入 (想了半天,这个得列一下,安全虽然我们不做,但问基本都是问这东西,看懂这段就够了,要是问怎么防止就说对用户输入进行校验,不要动态拼接 SQL)
select * from users where username='' or 1=1#' and password=md5('')
等价于
select * from users where username='' or 1=1
SQL 注入采用的' OR 1=1 # 是什么意思呢?
最后一个 # 号有什么意义呢?
SELECT * FROM test WHERE name='' OR 1=1 #' AND age='20'
这后面写的 #' 是什么意思呢?
解释:可以注释掉后面的一行 SQL 代码
相当于去掉了一个 where 条件
MySQL 注释, 过滤掉后面的 SQL 语句,使其不起作用
因为 1=1 永远是都是成立的,即 where 子句总是为真,将该 sql 进一步简化之后,等价于如下 select 语句:
select * from users 没错,该 sql 语句的作用是检索 users 表中的所有字段
二十七.cookie 和 session 的区别
1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2、cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗
考虑到安全应当使用 session。
3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用 COOKIE。
4、单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
5、所以个人建议:
将登陆信息等重要信息存放为 SESSION
其他信息如果需要保留,可以放在 COOKIE 中
二十八.客户端的性能测试https://blog.csdn.net/xiaomaoxiao336368/article/details/83547318
1、响应 (冷启动即首次启动,热启动为非首次启动)
冷启动:首次启动 app 的时间间隔(只是启动时间,不包括页面加载)
热启动:非首次启动 app 的时间间隔(只是启动时间,不包括页面加载)
方法:adb shell am start -W packageName 或者通过 Android Monitor 的 logcat
2、内存 测试点一般如下
空闲状态:切换至后台或者启动后不做任何操作,消耗内存最少。
中强度状态:时间偏长的操作应用。
高强度状态:高强度使用应用,可以跑 monkey 来测试(通常用来测试内存泄漏)。
方法:adb shell dumpsys meminfo packageName
3、cpu 测试点一般如下
在空闲时间 (切换至后台) 的消耗,基本没大应用使用 cpu
在运行一些应用的情况下,cpu 已占 50% 的情况下,观察应用程序占用 cpu 的情况
在高负荷的情况下看 CPU 的表现(cpu 占用应是在 80% 以上)
方法: top -m -s cpu |grep packageName(-m 是最大 -s 是排序) 或者 dumpsys cpuinfo |grep packageName
4、FPS (app 使用的流畅度,60 帧/s,要保持画面流畅不卡顿,一般是要求每一帧的时间不超过 1000/60=16.6ms)
方法:adb shell dumpsys gfxinfo packageName 或者开发者选项—>profile GPU rendering —> on screen as bars(这个基本不用,了解就行了我感觉)
5、GPU 过度渲染 (开发者选项—>Debug GPU overdraw—>show overdraw areas)
6、耗电 测试点一般如下
测试手机安装目标 APK 前后待机功耗无明显差异;
常见使用场景中能够正常进入待机,待机电流在正常范围内;
长时间连续使用应用无异常耗电现象
方法:adb shell dumpsys batterystats |grep packageName
7、耗流
方法:
先查看 UID:cat /data/system/packages.list | grep com.newsplus.tr 假设 UID 为 1000
然后 通过 cat /proc/uid_stat/1000/tcp_rcv 计算下行流量
再启动 APP 到 APP 彻底启动 cat/proc/uid_stat/1000/tcp_sed 计算上行流量
然后 sed-rcv 即可
或者通过 wireshark 抓包也可以,没仔细研究
二十九.CI,CD
https://blog.csdn.net/yuanjunliang/article/details/81211684
三十.adb
adb 全称为 Android Debug Bridge,就是起到调试桥的作用。顾名思义,adb 就是一个 debug 工具。
Adb 的原理:
1)当你启动一个 adb Client(客户端),Client 首先会选确认是否已有一个 adb Server(服务器)进程在运行,如果没有,则会启动 Server 进程。此时,adb Server 就会绑定本地的 TCP 端口 5037,并监听 adb Client 发来的命令。
2)接着,Server 将会扫描所有 5555 到 5585 范围内的奇数端口来定位所有的模拟器或设备,并与之建立连接。一旦 Server 找到 了 adb daemon(守护程序),它将建立一个到该端口的连接,这样,我们就可以使用 adb 命令控制和访问模拟器或设备了。在这里,需注意的是任何模拟器或设备实例会取得两个连续的端口:一个偶数端口用来相应控制台的连接,和一个奇数端口用来响应 adb 连接。
常用命令:
adb devices:查看当前连接的设备(连接计算机的 Android 设备或者模拟器)
adb install ,将指定的 apk 安装到设备上,安装的 apk 包会放在/data/app 目录下。
几个参数:
-r 强制安装
-d(真机,多个设备中只有一个真机时适用)
-e(模拟器,多个设备中只有一个模拟器时适用)
-s(指定设备,后接序列号)
adb –s 44a188f9 install –r test.apk(其中 44a188f9 即序列号,通过 adb devices 可获取)
adb reboot:重启 android 设备
adb shell ps/top:查看当前终端中的进程信息,如 pid 等
adb shell pm list packages:列出当前设备所有已安装的程序的包名
adb pull 和 adb push:
adb pull <设备中的文件路径> <本地路径>:从模拟器或设备中复制文件到本地。
adb push <本地文件路径> <设备中的路径>:将本地文件或目录复制到模拟器或设备。
adb shell dumpsys:
三十一.DDMS
DDMS(Dalvik Debug Monitor Service),是 Android 开发环境中的 Dalvik 虚拟机调试监控服务,可以进行的操作有:为测试设备截屏,查看特定行程中正在运行的线程以及堆信息、Logcat、广播状态信息、模拟电话呼叫、接收 SMS、虚拟地理坐标
原理:
DDMS 将搭建起 IDE 与测试终端(Emulator 或者 connected device)的链接,它们应用各自独立的端口监听调试器的信息,DDMS 可以实时监测到测试终端的连接情况。当有新的测试终端连接后,DDMS 将捕捉到终端的 ID,并通过 adb 建立调试器,从而实现发送指令到测试终端的目的
DDMS 工具存放在 SDK 的 tools 路径下,启动 DDMS 方法如下:
直接双击 ddms.bat 运行
主要功能:
Devices:在 GUI 的左上角可以看到标签为 “Devices” 的面板,这里可以查看到所有与 DDMS 连接的终端的详细信息(真机或模拟器),以及每个终端正在运行的 APP 进程,每个进程最右边相对应的是与调试器链接的端口。因为 Android 是基于 Linux 内核开发的操作平台,同时也保留了 Linux 中特有的进程 ID,它介于进程名和端口号之间。
Screen captrue:截屏操作。
Dump View:显示手机当前屏幕对应当前调试页面,选择页面元素,会在右面就是显示对应 View 的信息,这对我们分析页面布局很有用。
Threads:查看进程中线程情况。
Heap:查看应用中内存使用情况。
File Exporler:File Explorer 非常有用,它是一个文件浏览器,可以把文件上传到 Android 手机,或者从手机下载下来,也可以进行删除操作。选中 file explorer 选项卡后可实现对 Android 手机文件系统的上传、下载、删除操作,不过真机上的很多操作需要 Root 权限才能进行。
Emulator Control:通过这个面板的一些功能可以非常容易的使测试终端模拟真实手机所具备的一些交互功能,比如:接听电话,根据选项模拟各种不同网络情况,模拟接受 SMS 消息和发送虚拟地址坐标用于测试 GPS 功能等。
LogCat :查看日志输入信息,可以对日志输入进行 Filter 过滤一些调试的信息筛选查看等。
Console:是 Android 模拟器输出的信息,加载程序等信息。
技术上暂时先写到这,我后续还会更新~下面是一些个人总结的面试小技巧和小的问点吧
一些我认为可能会问的问题
1.自我介绍
2.你现在的测试流程描述下?
3.挑一个你最熟悉的项目描述下,说一说你在其中的工作
4.你认为如何做一个好的测试 (或者说你觉得你做测试比别人的优势在哪)
5.你印象中测试过程中最大的问题是什么?怎么解决的 (包括线上问题)
6.工作以来或者未来的规划 (有个规划就好)
7.什么样的测试用例算是一个好的测试用例 (建议与第一点的黑盒方法结合着说)
8.一般你都怎么定位 bug
9.为什么要做自动化测试?或者说和手工测试有什么不同 (https://www.cnblogs.com/test_home_c/p/9399287.html)
(这个写的挺好,总结其实最主要:回归,提高效率,减少重复工作,能及时报警,更好保证产品质量)
10.离职原因 (千万不要说前公司的坏话,尽量靠在工作方向说,只要不是一些偏激的我认为都可以)
11.期望薪资 (要么直接说,要么我觉得就是问之前可以先问问年终是几个月,或者补贴什么的有多少再说自己的期望,具体情况具体分析)
12.对于加班你怎么看?(加班分两方面,一方面是对于自己来说是成长,同时也会 push 公司业务的增进;第二就是有压力的情况下其实会有动力,也会自己平时有一些解压的方法)
13.你有什么问题想问我么 (我觉得是一定是要问的,除非确实没啥兴趣或者觉得挂了,先考虑考虑,比如业务相关)
14.作为测试工程师,怎么保证软件的质量?(怎么做好一个测试)
(1) 代码质量:开发通过单元测试保证
(2) 让用户参与 UAT 测试,保证用户体验(使用质量)
(3) 功能测试、性能测试、兼容性测试等多种测试类型的结合
(4) 采用合适的用例方法,如何进行需求分析,用例评审
(5) 要有把控全局的能力 (推动客户端和 UI,交互的时间,推动研发提测时间,提测质量;比如说研发提测质量低,那我们可以制定冒烟测试标准,且让他们在测试环境联调)
(6) 要有好的沟通能力和责任心
15.开发坚持说这不是一个问题怎么办?(1.看需求,如果是的话就没什么说的 2.如果坚持,尽量重现,三方讨论)
16.紧急需求怎么办?(一般拿出来看优先级,如果是重要且紧急的那种,那就紧急发布,如果不重要不紧急,看是否可以延后至下个版本;当出现紧急需求的时候,我们要和产品,研发 leader 讨论是否可以在版本原先上线时间的基础上延后,要为自己争取)
给大家剧透一些问题(曾经我遇到过的,一个示例,大家也可以参考,具体的公司我就避免一些意外,不在此透露):
7.遇到过的印象最深的线上问题
8.如果你提到支付,应该会问支付异常 case(数据库,流程尤为关键)
9.对加班怎么看
10.测试用例设计 (购物车)
11.web 和 app 测试的最大区别 (上面有)
12.怎么进行 sql 注入 (我觉得这个还是看下,安全上虽然没做过,不过看过这个在面试过程中会有加分的时候)
13.jmeter 参数化的方法 ( 总结 1.用 jmeter 的用户参数,直接下面的用上面的 2.jmeter 的函数助手,csvread 3.csv_data,这个传参)
14.一周的紧急需求怎么排期能尽量保证上线质量
15.描述最近的工作,项目,你做的什么
16.字符串倒序怎么实现
17.自动化
暂时写这些吧,后面兰瑟会持续更新~
像测试方法,TCP/IP,HTTP,android 和 ios,web 区别,抓包,linux,简单的 sql 这些个是一定要知道些的,嗯~
其实在测试当中,也有很多测试工种的分类,不过此文我暂时没有分的很细,是一个总的小结,后续我会继续拆分,将功能,性能,自动化等等测试方面的经验,技术,都分享给大家。
我个人的一点点见解是一定会对着简历细问的,所以
简历一定要好好写!
简历一定要好好写!
简历一定要好好写!
最后,祝愿大家都能成功进入自己理想的公司~