• 一个资深测试工程师面试一来就问我这些题目


    德玛作为一个已经工作有10年经验的测试工程师,其间也辗转了几个大的互联网公司,虽然确实缺少了一些稳定性,但同时也积累了一些面试的经验,不才分享一些给大家。那么主要是针对测试工程师的一些总结,对于其他的工种,我可能会在别的文章中去总结一些面试技巧,本文会着重于测试工程师的面经。

    测试的面试重点分为两大部分:技术,项目
    扩充一下:技术的一些注意点,项目上的一些处理方式(有些还会有一些沟通上的小技巧),可能不会写的特别详细,但点我都会点到,后续会再继续补充(近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. 跨平台,native hybrid webview(H5)

    2. 跨设备,android iOS

    3. 跨app,可以在多个app之间交互

    4. 不依赖APP开源代码(保留意见,android Uiautomator对H5的支持需要代码支持,这里不细说)

    5. 支持Selenium WebDriver / Selenium Grid

    6. 跨语言,java python ruby nodejs

    7. Open Source 原理: Android 

    1.左边的WebDriver script是我们的selenium测试脚本(其实就是测试代码)
    2.中间是起的Appium的服务,Appium在这边起了一个Server(4723端口),跟selenium
    Webdriver测试框架类似,Appium⽀支持标准的WebDriver JSONWireProtocol 。在这里提供了一套web服务,Appium Server接收web driver 标准请求,解析请求内容,调⽤用对应的框架响应操作。
    如:脚本发送一个点击按钮的请求给appium server,

    1. appium server会把请求转发给中间件Bootstrap.jar ,它是用java写的,安装在手机上. Bootstrap 接收appium 的命令(4724端口),最终通过调⽤用UiAutomator的命令来实现。4.最后执⾏行的结果由Bootstrap返回给appium server 5.另外,appium还用到了chromedriver来⽀支持基于H5(webview)的测试。IOS: 

    1.左边的WebDriver script是selenium测试脚本
    2.中间是起的Appium的服务,Appium在这边起了⼀一个Server(4723端口),跟selenium
    Webdriver测试框架类似,Appium⽀支持标准的WebDriver JSONWireProtocol 。在这里提供了一套web服务,Appium Server接收web driver 标准请求,解析请求内容,调⽤用对应的框架响应操作。
    如:脚本发送一个点击按钮的请求给appium server,

    1. appium server调用instruments.js 启动⼀一个socket server,同时分出⼀一个⼦子进程运⾏行instruments.app,将bootstrap.js(一个UIAutomation脚本)注⼊入到device⽤用于和外界进⾏行交互。4.对于H5的操作,运⽤用了 iOS webkit debug proxy来实现 Android和IOS的区别我觉得就是bootstrap.jar和bootstrap.js去分别驱动uiautomator和uiautomation,新版本的Appium已经支持uiautomator2了,IOS支持XCUItest 定位元素方法(By后面那些东西,ID可以唯一定位): webdriver提供的用 By 定位元素 find_element(By.ID,"kw") find_element(By.NAME,"wd") find_element(By.CLASS_NAME,"s_ipt") find_element(By.TAG_NAME,"input") find_element(By.LINK_TEXT,u"新闻") find_element(By.PARTIAL_LINK_TEXT,u"新") find_element(By.XPATH,"//*[@class='bg s_btn']") find_element(By.CSS_SELECTOR,"span.bg s_btn_wr>input#su") find_element()方法只用于定位元素。它需要两个参数,第一个参数是定位方式,这个由 By 提供;另第二个参数是定位的值。

    十. 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 [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

    1. adb shell monkey {+命令参数} Monkey 测试出现错误后,一般的分析步骤(我以前被问到过,当时一脸懵逼(´⊙ω⊙`)) 看Monkey的日志 (注意第一个swith以及异常信息等)

    2. 程序无响应的问题: 在日志中搜索 “ANR”

    3. 崩溃问题:在日志中搜索 “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键呼出应用列表和切换应用,然后右滑则终止应用;

    1. 多分辨率测试,Android端20多种,ios较少;

    2. 手机操作系统,Android较多,ios较少且不能降级,只能单向升级;新的ios系统中的资源库不能完全兼容低版本中的ios系统中的应用,低版本ios系统中的应用调用了新的资源库,会直接导致闪退(Crash);

    3. 操作习惯:Android,Back键是否被重写,测试点击Back键后的反馈是否正确;应用数据从内存移动到SD卡后能否正常运行等;

    4. push测试:Android:点击home键,程序后台运行时,此时接收到push,点击后唤醒应用,此时是否可以正确跳转;ios,点击home键关闭程序和屏幕锁屏的情况(红点的显示);

    5. 安装卸载测试:Android的下载和安装的平台和工具和渠道比较多,ios主要有app store,iTunes和testflight下载;

    6. 升级测试:可以被升级的必要条件:新旧版本具有相同的签名;新旧版本具有相同的包名;有一个标示符区分新旧版本(如版本号),对于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抓包也可以,没仔细研究

    二十九.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讨论是否可以在版本原先上线时间的基础上延后,要为自己争取)

    给大家剧透一些问题(曾经我遇到过的,一个示例,大家也可以参考,具体的公司我就避免一些意外,不在此透露):

    1. 介绍项目

    2. 怎么测一个接口,哪些方式(我理解是跟用例差不多,协议,url,参数,请求方式,头部信息,返回;然后性能上响应时间,并发,安全上SQL注入,权限什么的,提一下就行,反正能多说就说,对方会觉得你知识面广一些)

    3. 会问有多少个服务,其实就是站点,大概算下就好了,10多个吧,然后就问服务端的一个流转(主要是服务的流转性)

    4. Android和ios测试区别(上面有..1.右滑 2.IOS版本少一些,一般兼容4个系统版本,比如12,11,10,9,也看具体用户情况 ,android版本多,分辨率也多 3.home键,android能后台运行 4.android性能没IOS好,电量,内存什么的都不如IOS其实 5.想到的可以自己补充哦)

    5. 测试这个项目的时候比如在用户表插入一条数据,数据库哪些字段会变化(他的意思是测了一个查询接口,其实我答错了,不过回答的应该是id,userid,用户名,密码,插入时间,用户状态,权限,针对借款项目的话比如还有绑卡信息什么的)

    6. linux查看日志的命令(上面有,less,more,cat,tail,echo.....)

    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这些个是一定要知道些的,嗯~
    其实在测试当中,也有很多测试工种的分类,不过此文我暂时没有分的很细,是一个总的小结,后续我会继续拆分,将功能,性能,自动化等等测试方面的经验,技术,都分享给大家。
    我个人的一点点见解是一定会对着简历细问的,所以
    简历一定要好好写!
    简历一定要好好写!
    简历一定要好好写!

    最后,祝愿大家都能成功进入自己理想的公司~

  • 相关阅读:
    Linux内存查看通用方法
    (附源码)springboot学生宿舍管理系统 毕业设计 161542
    华为云CDN,如何推动互联网行业健康发展?
    关于组合数(二项系数)的一个递推公式
    Docker安装Jenkins
    Java Elasticsearch教程
    (22)语义分割--LR-ASPP
    【每天学习一点新知识】HTTP各个响应状态所表示的含义
    MongoDB
    RocketMQ的介绍以及部署
  • 原文地址:https://blog.csdn.net/jj2772367224/article/details/126110481