既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
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 [options] mode files
多数用三位八进制数字的形式来表示权限,第一位指定属主的权限,第二位指定组权限,第三位指定其他用户的权限,每位通过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
- adb shell monkey {+命令参数} Monkey 测试出现错误后,一般的分析步骤(我以前被问到过,当时一脸懵逼(´⊙ω⊙`)) 看Monkey的日志 (注意第一个swith以及异常信息等)
- 程序无响应的问题: 在日志中搜索 “ANR”
- 崩溃问题:在日志中搜索 “Exception” (如果出现空指针, NullPointerException) 肯定是有bug
十九.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键呼出应用列表和切换应用,然后右滑则终止应用;
- 多分辨率测试,Android端20多种,ios较少;
- 手机操作系统,Android较多,ios较少且不能降级,只能单向升级;新的ios系统中的资源库不能完全兼容低版本中的ios系统中的应用,低版本ios系统中的应用调用了新的资源库,会直接导致闪退(Crash);
- 操作习惯:Android,Back键是否被重写,测试点击Back键后的反馈是否正确;应用数据从内存移动到SD卡后能否正常运行等;
- push测试:Android:点击home键,程序后台运行时,此时接收到push,点击后唤醒应用,此时是否可以正确跳转;ios,点击home键关闭程序和屏幕锁屏的情况(红点的显示);
- 安装卸载测试:Android的下载和安装的平台和工具和渠道比较多,ios主要有app store,iTunes和testflight下载;
- 升级测试:可以被升级的必要条件:新旧版本具有相同的签名;新旧版本具有相同的包名;有一个标示符区分新旧版本(如版本号),对于Android若有内置的应用需检查升级之后内置文件是否匹配(如内置的输入法)
二十五.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抓包也可以,没仔细研究
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
t/1000/tcp_rcv计算下行流量
再启动APP到APP彻底启动 cat/proc/uid_stat/1000/tcp_sed计算上行流量
然后sed-rcv即可
或者通过wireshark抓包也可以,没仔细研究
[外链图片转存中…(img-x03cIpGV-1715364953912)]
[外链图片转存中…(img-3iRr3t5O-1715364953912)]
[外链图片转存中…(img-nNbb2k0b-1715364953912)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新