cookie和session

添加链接描述
二者都是web端的会话跟踪技术,Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

  • Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头;有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。

  • Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。 无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效;
    在这里插入图片描述

  • Session技术则是服务端的解决方案,它是通过服务器来保持状态的。服务器会为Session生成唯一的Session id,而这个Session id在随后的请求中会被用来重新获得已经创建的Session;

  • 客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

  • 由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。
    在这里插入图片描述

请简述TCP和UDP的区别

TCP和UDP都是OSI模型中运输层中的协议,
TCP—传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。
UDP—用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。

  • TCP 是面向连接的,UDP 是面向无连接的
  • UDP程序结构较简单
  • TCP 是面向字节流的,UDP 是基于数据报的
  • TCP 保证数据正确性,UDP 可能丢包
  • TCP 保证数据顺序,UDP 不保证

为什么TCP可靠而UDP不可靠

  • 通过 TCP 连接传输的数据无差错,不丢失,不重复,且按顺序到达。

  • TCP 报文头里面的序号能使 TCP 的数据按序到达

  • 报文头里面的确认序号能保证不丢包,累计确认及超时重传机制

  • TCP 拥有流量控制及拥塞控制的机制

    可以参考这一篇博客

请简单说一下你了解的端口及对应的服务

  • 21端口:21端口主要用于FTP(File Transfer Protocol,文件传输协议)服务。
  • 25端口:25端口为SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)服务器所开放,主要用于发送邮件,如今绝大多数邮件服务器都使用该协议。
  • 53端口:53端口为DNS(Domain Name Server,域名服务器)服务器所开放,主要用于域名解析,DNS服务在NT系统中使用的最为广泛。
  • 80端口:80端口是为HTTP(HyperText Transport Protocol,超文本传输协议)开放的,这是上网冲浪使用最多的协议,主要用于在WWW(World Wide Web,万维网)服务上传输信息的协议。
    在这里插入图片描述

TCP三次握手

三次握手指的是:建立一个TCP连接时,需要客户端和服务器总共发送三个包。
三次握手的目的是:连接服务器的指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换TCP窗口大小。

  • 第一次握手:建立连接,客户端向服务器发送请求报文段,将SYN置为1,客户端进入SYN_SEND状态,等待服务器确认
  • 第二次握手:服务器接收到客户端的SYN 报文段,对这个SYN报文段进行确认;同时自己发送SYN请求信息,将SYN置为1;服务器将上述所有信息放入报文段(SYN+ACK)一起发送给客户端,此时服务器进入SYN_RECV状态
  • 客户端接收到SYN+ACK报文段,向服务器发送ACK报文段,发送完毕后客户端和服务器都进入ESTABLISHED状态,完成三次握手

TCP四次挥手

  • 第一次挥手:客户端数据传输完毕需要断开连接,发送报文段并停止再次发送数据,主动关闭TCP连接,进入FIN-WAIT-1状态
  • 第二次挥手:服务器接收到客户端发送的报文段后,进入关闭等待状态,客户端到服务器的连接释放,客户端收到服务器的确认后,进入FIN-WAIT-2状态,等待服务器发出连接释放的报文段
  • 服务器的数据传输完毕后,向客户端发送连接释放报文段,服务器进入最后确认状态,等待客户端的确认
  • 客户端收到服务器的连接释放报文段后,发出确认报文段,进入等待状态,经过等待时间后进入关闭状态,四次握手结束

从输入网址到显示网页的全过程

  • 输入网址
  • DNS域名解析,将url解析为ip地址
  • 客户端与服务器建立TCP连接
  • 客户端向服务器发送HTTP请求
  • 服务器处理客户端发来的请求
  • 服务器响应请求,返回给浏览器一个响应
  • 浏览器解析响应,展示HTML

参考

输入url没有访问到网页的原因
  • DNS域名解析出问题
  • 网络断了
  • 服务器拒绝访问
  • 请求或者响应在网络传输中途被劫走了

IP地址分为哪几类?简单说一下各个分类

在这里插入图片描述

OSI七层模型

在这里插入图片描述

TCP/IP四层模型

在这里插入图片描述

HTTP 协议包括哪些请求

  • GET:对服务器资源的简单请求
  • POST:发送包含用户提交数据的请求
  • HEAD:类似于GET请求,不过返回的响应中没有具体内容,用于获取报头
  • PUT:用来传输文件,要求在请求报文的主体中包含文件内容,然后保存到请求的URI指定位置
  • DELETE:与PUT相反,用来删除文件,按照请求删除指定的资源
  • TRACE:让服务器将之前的请求通信环返回给客户端
  • CONNECT:与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信

HTTP响应状态码

在这里插入图片描述

  • 200
    从客户端发来的请求在服务器端被正常处理了
  • 204
    服务器接收的请求已被成功处理,但在返回的响应报文中不包含实体的主体成分
  • 206
    客户端向服务器成功请求指定范围的实体内容
  • 301
    请求的资源已经被永久的移动到新的URI,以后新的请求应该使用新的URI代替
  • 302
    资源临时移动,客户端应继续使用原有的URI
  • 303
    请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源
  • 302
    客户端发送附带条件的请求时,服务器允许访问资源,但是并没有返回任何实体
  • 400
    客户端请求的语法错误,服务器无法理解
  • 401
    请求需要有通过HTTP认证的认证信息
  • 403
    请求资源的房屋内被服务器拒绝了
  • 404
    服务器上无法找到请求的资源
  • 500
    服务器内部错误,无法完成请求
  • 503
    服务器暂时处于超负载或正在进行停机维护,现在无法处理请求

线程和进程区别

  • 进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。
  • 每个进程都有独立的代码和数据空间,程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,线程之间切换的开销小。
  • 进程之间的资源是独立的,线程共享本进程的资源

多线程与多进程

  • 多进程:在同一个时间里,同一个计算机系统中如果允许两个或两个以上的进程处于运行状态,多任务之间不会相互影响
  • 多线程:在一个程序中,有很多的操作是非常耗时的,如数据库读写操作,IO操作等,如果使用单线程,那么程序就必须等待这些操作执行完成之后才能执行其他操作。使用多线程,可以在将耗时任务放在后台继续执行的同时,同时执行其他操作。多线程是异步的,但这不代表多线程真的是几个线程是在同时进行,实际上是系统不断地在各个线程之间来回的切换。
    在这里插入图片描述

http与https

  • HTTP协议以明文方式发送内容,不提供任何方式的数据加密,HTTP协议不适合传输一些敏感信息
  • HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密
  • http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443
  • HTTPS协议握手阶段比较费时,会使页面的加载时间延长近50%,增加10%到20%的耗电;
  • HTTPS连接缓存不如HTTP高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;
https加密原理

https://zhuanlan.zhihu.com/p/43789231

计算网络里面每一层的协议

添加链接描述
在这里插入图片描述

Python的生成器和迭代器区别

  • 以 list 容器为例,在使用该容器迭代一组数据时,必须事先将所有数据存储到容器中,才能开始迭代;而生成器却不同,它可以实现在迭代的同时生成元素。
  • 也就是说,对于可以用某种算法推算得到的多个数据,生成器并不会一次性生成它们,而是什么时候需要,才什么时候生成。

SQL语言的增删改查

select distinct

在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。

DISTINCT 关键词用于返回唯一不同的值。

SELECT DISTINCT column_name,column_name
FROM table_name;
where

在这里插入图片描述

order by

对结果进行排序,asc升序,desc降序

SELECT column_name,column_name
FROM table_name
ORDER BY column_name,column_name ASC|DESC;
插入 insert into
INSERT INTO table_name
VALUES (value1,value2,value3,...);
INSERT INTO table2
SELECT * FROM table1;
update更新
UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value;
delete删除
DELETE FROM table_name
WHERE some_column=some_value;
limit

从结果中选前number个

SELECT column_name(s)
FROM table_name
LIMIT number;
like操作符

按照匹配模型进行筛选

SELECT * FROM Websites
WHERE name LIKE 'G%'; | not like

在这里插入图片描述

in

IN 操作符允许您在 WHERE 子句中规定多个值。

SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,...);
as 别名
SELECT column_name AS alias_name
FROM table_name;
SELECT w.name, w.url, a.count, a.date
FROM Websites AS w, access_log AS a
WHERE a.site_id=w.id and w.name="菜鸟教程";
join连接
SELECT Websites.id, Websites.name, access_log.count, access_log.date
FROM Websites
INNER JOIN access_log
ON Websites.id=access_log.site_id
where ;

在这里插入图片描述

create database


在这里插入图片描述

mysql索引了解吗,用法都是什么,实现原理

简述一下B+树的实现、特点

python的GIL全局解释锁

python解释器的主循环中,同时只有一个线程在运行,即在任意时刻只有一个线程在解释器中运行。对python虚拟机访问的控制由全局解释锁GIL控制,正是这个锁来控制同一时刻只有一个线程能够运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。

python的深拷贝与浅拷贝

  • 深复制和浅复制最根本的区别在于是否是真正获取了一个对象的复制实体,而不是引用。
  • 浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变。
  • 深复制 —-在计算机中开辟了一块新的内存地址用于存放复制的对象。
  • 浅拷贝出来的数据并不独立,如果被复制的对象改变了,那么浅拷贝的对象也会改变,深拷贝之后就会完全独立,与浅拷贝断绝关系。

python多线程多进程的使用

  • 多线程:python中有两种方式实现线程:实例化一个threading.Thread的对象,并传入一个初始化函数对象(initial function )作为线程执行的入口;继承threading.Thread,并重写run函数; 在主线程中创建若线程之后,他们之间没有任何协作和同步,除主线程之外每个线程都是从run开始被执行,直到执行完毕。可以通过将创建的线程指定为守护线程(daemon),这样主线程执行完毕之后会立即结束未执行完的线程,然后结束程序。
  • 多进程:创建进程的方式和创建线程的方式类似:实例化一个multiprocessing.Process的对象,并传入一个初始化函数对象(initial function )作为新建进程执行入口;继承multiprocessing.Process,并重写run函数;对于python线程,双线程并行执行耗时比单线程要高的多。

python程序如何处理内存释放,内存泄漏内存管理

Python的内存管理机制可以从三个方面来讲

  • 垃圾回收

    • 当内存中有不再使用的部分时,垃圾收集器就会把他们清理掉。它会去检查那些引用计数为0的对象,然后清除其在内存的空间。
  • 引用计数
    在这里插入图片描述

  • 内存池机制

    • python的内存池有四层
    • 第0层是C中的malloc,free等内存分配和释放函数进行操作;
    • 第1层和第2层是内存池,有Python的接口函数PyMem_Malloc函数实现,当对象小于256K时有该层直接分配内存;
    • 第3层是最上层,也就是我们对Python对象的直接操作;
      在这里插入图片描述
      关于释放内存方面,当一个对象的引用计数变为 0 时,python就会调用它的析构函数。调用析构函数并不意味着最终一定会调用free 释放内存空间,如果真是这样的话,那频繁地申请、释放内存空间会使 Python的执行效率大打折扣。因此在析构时也采用了内存池机制,从内存池申请到的内存会被归还到内存池中,以避免频繁地 释放 动作。

什么情况下会导致内存泄漏

  • 资源释放问题
    程序代码的问题,长期保持某些资源,如Context,Cursor,IO流的引用,资源得不到释放造成内存泄漏.
  • 对象内存过大
    保存了多个耗用内存过大的对象,如 Bitmap,XML文件,造成内存超出限制。
  • static关键字的使用问题static是java中的一个关键字,当用它修饰成员变量时,那么该变量就属于该类,而不是该类的实例。所以用static修饰的变量,它的生命周期是很长的,如果他用来引用一下资源耗费过多的实例(Context的情况最多),这时就要谨慎对待。
  • 线程导致内存溢出
    线程产生内存泄漏的主要原因是在于线程的生命周期不可控。
python的list基本操作有哪些
  • 增加 list.append(num)
  • 删除 list.pop()/list.remove(obj)
  • 修改 list[] = new
  • 排序 list.sort()
  • 插入 list.insert(index,obj)
  • 获取某个值的索引 list.index(obj)
  • 统计某个值出现的次数 list.count(x)
list和tuple的区别
  • list是[],tuple是()
  • tuples在操作时相比list更快,当数据足够大的时候tuples的数据操作性能更优
  • tuples内的元素一旦建立就无法更改、删除、排序,但是可以增加
  • Tuples 通常存储的是一连串的不同种类的事务;List 通常存储的是一连串的相同种类的事务
range和xrange的区别
  • range()是Python的内置函数,用于创建整数的列表,可以生成递增或者递减的数列
  • xrange用法与range完全相同,所不同的是生成的不是一个数组,而是一个生成器
  • xrange函数在Python3中已经取消,在python3中,range()这种实现被移除了,保留了xrange()的实现,且将xrange()重新命名成range()。
  • 要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要预先开辟一块很大的内存空间
python中的*args与**kargs

在函数定义时使用,可以进行不定数量的传参

def demo(*args):
    for x in args:
        print(x,)

demo(1,2,3,4,5)

def demo(**kargs):
    for x,v in kargs.items():
        print(x,v)

demo(name='123',name2='345')
面向对象中的__init__
  • __init__是初始化方法,创建类的实例对象后,就立刻被默认调用了,可接收参数
  • init() 方法可以包含多个参数,但必须包含一个名为 self 的参数,且必须作为第一个参数
  • 仅包含 self 参数的 init() 构造方法,又称为类的默认构造方法
面向对象中的self
  • 无论是构造方法还是实例方法,最少要包含一个参数,并没有规定该参数的具体名称,可以是self也可以是其他
  • 同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,Python 会自动绑定类方法的第一个参数指向调用该方法的对象。在调用实例方法和构造方法时,不需要手动为第一个参数传值
python排序

列表排序:
sort与sorted的区别
lis.sort()会改变原列表,sorted(lis)不会改变原列表
字典排序:

dic = {'c':2,'b':1,'a':3}
newdic = {k:v for k,v in sorted(dic.items(),key=lambda x:x[0])}
print(newdic)

linux系统常用的命令

文件和目录
  1. cd … 返回上一级目录
  2. cd …/… 返回上两级目录
  3. cd /home 进入home目录
  4. cd 进入个人主目录
  5. cd - 返回上次所在目录
  6. pwd 显示当前工作路径
  7. ls 查看目录中的文件
  8. ls -a 查看目录中包括隐藏文件
  9. mkdir dir1 创建一个叫dir1的文件夹
  10. rm -f file1 删除file1文件
  11. rmdir dir1 删除dir1目录
  12. rm -rf dir1 删除dir1目录并删除内容
  13. mv 文件1 文件2 将文件1改名文件2
  14. mv 文件 目录 将文件移动到目录
  15. cp -r test/ newtest 将test/文件夹下的所有文件复制到newtest
  16. ln -s log.txt link2021 为log.txt创建软连接
  17. ln log.txt link2021 创建硬链接
  18. touch a.txt 修改时间戳
linux安装与解压操作

参考

  • 使用rpm命令安装扩展名为".rpm"的软件包
    在这里插入图片描述
  • yum安装 格式:yum install 软件名 [-y]
  • 对于安装有依赖包的软件,用yum命令特别方便,如果用rpm命令,就必须要先装依赖包再装软件包,而yum命令会直接匹配依赖包然后直接安装
  • 编译安装源码包
    • 1.解压 — tar tar zxvf tar包
    • 2.配置 — ./configure :针对当前系统、软件环境,配置好安装参数
    • 3.编译 — make: 将源代码文件变为二进制的可执行程序,用make命令
    • 4.安装 — make install

linux命令:top、free、netstat、ps grep、nslookup

top持续监听进程运行状态

top 命令的输出内容是动态的,默认每隔 3 秒刷新一次。命令的输出主要分为两部分:

  • 第一部分是前五行,显示的是整个系统的资源使用状况,我们就是通过这些输出来判断服务器的资源使用状态的;
  • 第二部分从第六行开始,显示的是系统中进程的信息;
free显示内存状态
netstat显示网络状态
  • ps命令将某个进程显示出来
  • grep命令是查找,使用正则表达式搜索文本,并把匹配的行打印出来
nslookup
  • 查询DNS的记录,查看域名解析是否正常,在网络故障的时候用来诊断网络问题

linux目录权限

参考博客

查看权限:

ls -l xxx.xxx 注:xxx.xxx是文件名,或者不写文件名则是当前目录下所有文件

修改某个目录下的所有文件的权限,包括子目录中的文件,例子如下:

chmod 777 /home/user
注:仅把/home/user目录的权限设置为rwxrwxrwx
chmod -R 777 /home/user 
注:表示将整个/home/user目录与其中的文件和子目录的权限都设置为rwxrwxrwx`
其中,参数`-R`表示启动递归处理

chmod 用3个数字来表达对 用户(文件或目录的所有者),用户组(同组用户),其他用户 的权限:
数字7是表达同时具有读,写,执行权限:
读取–用数字4表示;
写入–用数字2表示;
执行–用数字1表示;
按照规则,如你想设置/test目录的权限为:
    对用户可读可写:4(读取)+ 2(写入)= 6 ;
    对用户组可读可执行:4(读取)+ 1(执行)= 5 ;
    对其他用户仅可读:4(读取);

vim中查找数据

参考博客

  • 使用vim编辑文件:vim xxx
  • (命令模式)冒号+指令
    在这里插入图片描述
linux连接数据库
  • 连接本地的mysql:mysql -uroot -p
  • 远程:mysql -h localhost -uroot -p
    在这里插入图片描述

死锁的概念及条件

多个线程因争夺资源而造成的僵局
(1)互斥条件:指线程对所分配的资源进行排他性使用,即在一段时间内某资源只由一个线程占用。
(2)请求和保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3)不可剥夺条件:进程已获得的资源,在未使用之前,不能强行剥夺。
(4)循环等待条件:指在发生死锁时,必然存在一个进程资源循环等待链,链中每一个进程已获得的资源同时被链中下一个进程所请求

全局变量和局部变量的区别

  1. 作用域不同:全局变量的作用域为整个程序,而局部变量的作用域为当前函数或循环等
  2. 内存存储方式不同:全局变量存储在全局数据区中,局部变量存储在栈区
  3. 生命期不同:全局变量的生命期和主程序一样,随程序的销毁而销毁,局部变量在函数内部或循环内部,随函数的退出或循环退出就不存在了
  4. 使用方式不同:全局变量在声明后程序的各个部分都可以用到,但是局部变量只能在局部使用。函数内部会优先使用局部变量再使用全局变量

输入http://www.baidu.com以后的过程

在这里插入图片描述


测试用例的编写

参考博客

等价类分析

将测试的范围划分成几个互不相交的子集,他们的并集是全集,从每个子集选出若干个有代表性的值作为测试用例。

  • 等价类是具有相同属性或者方法的事务集合,这个集合中某个个体所表现的特征与其他个体完全一致
    在这里插入图片描述
    在这里插入图片描述
边界值划分
  • 规定了取值范围,利用该范围的边界以及边界附近的数据进行测试
  • 规定了取值的个数,选取少于个数一个或多于个数一个的值进行测试
  • 需求规定了一个有序集合,使用集合的第一个和最后一个
  • 程序中使用了一个内部数据结构,从数据结构的边界进行考虑,如int的长度范围
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
判定表法
  • 判定表是把作为条件的输入的各种组合值以及对应输出值都罗列出来而形成的表格。
    判定表通常由以下4部分组成:
      条件桩——列出问题的所有条件
      条件项——针对条件桩给出的条件列出所有可能取值
      动作桩——列出问题规定的可能采取的操作
      动作项——指出在条件项的各组取值情况下应采取的动作
    在这里插入图片描述
因果图

添加链接描述

  • 因果图法是一种利用图解法分析输入的各种组合情况,从而设计测试用例的方法,它适合于检查程序输入条件的各种组合情况
  • 等价类划分法和边界值分析法都是着重考虑输入条件,但没有考虑输入条件的各种组合,输入条件之间的相互制约关系,这样虽然各种输入条件可能出错的情况已经测试到了,但多个输入条件组合起来可能出错的情况却被忽视了。
  • 如果在测试时必须考虑输入条件的各种组合,则可能的组合数目将是天文数字,因此必须考虑采用一种适合于描述多种条件的组合,相应产生多个动作的形式来进行测试用例的设计,这就需要利用因果图(逻辑模型)。
  • 利用因果图导出测试用例需要经过一下几个步骤:
    1.找出所有的原因,原因即输入条件或输入条件的等价类。
    2.找出所有的结果,结果即输出条件。
    3.明确所有输入条件之间的制约关系以及组合关系。
    哪些条件不能组合到一起,哪些条件可以组合到一起
    4.明确所有输出条件之间的制约关系以及组合关系。
    哪些输出结果不能同时输出,哪些输出结果可以同时输出
    5.找出什么样的输入条件组合会产生哪种输出结果。
    6.把因果图转换成判定表/决策表。
    7.为判定表/决策表中的每一列表示的情况设计测试用例。

测试计划包含哪些内容

参考模板

  • 测试目标
  • 测试概要
  • 测试范围
    测试计划所包含的测试软件需测试的范围和优先级,哪些需要重点测试、哪些无需测试或无法测试或推迟测试。
  • 重点事项
    列出需要测试的软件的所有的主要功能和测试重点,这部分应该能和测试案例设计相对应和互相检查。
  • 质量目标
    制定测试软件的产品质量目标和软件测试目标
  • 资源需求
    进行测试所需要的软硬件、测试工具、必要的技术资源、培训、文档等。
  • 人员组织
  • 测试策略
    制定测试整体策略、所使用的测试技术和方法
  • 发布提交
    在按照测试计划进行测试发布后需要交付的软件产品、测试案例、测试数据及相关文档
  • 测试进度和任务人员安排
  • 测试开始/完成/延迟/继续的标准
  • 风险分析
测试报告含有那些东西
  • 测试结论(测试是否通过/是否满足发布要求/是否能够发布)
  • 罗列发现的主要问题(或者说该版本存在的主要风险)
  • 测试版本(客户端,服务器)(如果允许发布,附件发布包或其链接,包大小,以及md5校验码)
  • 测试内容(测试范围)
  • 测试用例执行情况(一共多少,执行了多少,未执行多少,通过多少,失败多少)
  • 发现的严重缺陷有哪些(仅仅罗列最严重级别的bug)
  • 邮件的附件是测试计划执行结果文件
测试用例中包括什么

在这里插入图片描述
图片来源

测试的流程

  • 需求:阅读需求,理解需求,与客户、开发、架构多方交流,深入了解需求。
  • 测试计划: 根据需求估算测试所需资源(人力、设备等)、所需时间、功能点划分、如何合理分配安排资源等。
  • 用例设计:根据测试计划、任务分配、功能点划分,设计合理的测试用例。
  • 执行测试:根据测试用例的详细步骤,执行测试用例。–every tester(主要是初级测试人员)
  • 执行结果记录和bug记录:对每个case记录测试的结果,有bug的在测试管理工具中编写bug记录
  • defect tracking:追踪leader分配给你追踪的bug.直到 bug fixed。–every tester
  • 测试报告:通过不断测试、追踪,直到被测软件达到测试需求要求,并没有重大bug.
  • 用户体验、软件发布等。

从哪些方面设计测试用例

功能性、兼容性、易用性、可靠性、性能、安全

给你一个水杯你会怎么测试

  • 功能测试:主要关注水杯基本功能
    • 1.1 水杯是否可以正常装水
    • 1.2 水杯是否可以正常喝水
    • 1.3 水杯是否有盖子,盖子是否可以正常盖住
    • 1.4 水杯是否有保温功能,保温功能是否正常保温
    • 1.5 水杯是否会漏水,盖住盖子拧紧后是否会漏水
  • 界面测试:主要关注水杯外观、颜色、设计等方面
    • 2.1 外观是否完整
    • 2.2 外观是否舒适
    • 2.3 颜色搭配及使用是否让人感到舒适
    • 2.2 杯子外观大小是否适中
    • 2.3 杯子是否有图案,图案是否易磨损
  • 易用性测试:主要关注水杯使用是否方便
    • 3.1 水杯喝水时否方便
    • 3.2 水杯拿起放下是否方便,这里会衍生到水杯形状的测试
    • 3.3 水杯装水是否方便
    • 3.4 水杯携带是否方方便
    • 3.5 水杯是否有防滑功能
    • 3.6 水杯装有低温或者高温水时,是否会让手感到不适
  • 性能测试:
    • 4.1 水杯装满水时,是否会露出来
    • 4.2 水杯最大使用次数
    • 4.3 水杯的保温性是否达到要求
    • 4.4 水杯的耐寒性是否达到要求
    • 4.5 水杯的耐热性是否达到要求
    • 4.6 水杯掉落时时,是否可以正常使用
    • 4.7 水杯长时间放置时,是否会发生泄露
  • 兼容性测试:主要关注水杯是否可以装其他液体,如果汁、汽油、酒精等可
  • 移植性测试:主要关注水杯放置环境等
    • 6.1 将水杯放在常温环境中,使用是否正常
    • 6.2 将水杯放在零下的环境中,使用是否正常
    • 6.3 将水杯放在高于正常温度的环境中,使用是否正常
  • 安全性测试:主要关注水杯外观和各种异常条件下是否释放有毒物质等
    • 7.1 当水杯装满热水时,水杯是否会烫手
    • 7.2 当水杯装上水后,是否会产生有毒物质
    • 7.3 把水杯放在零下环境时,是否会产生有毒物质
    • 7.4 把水杯放在高温环境时,是否会产生有毒物质

介绍diff测试

  • 接口Diff测试,简单来说就是比对相同接口在不同版本/不同环境下面的返回内容是否符合预期

黑盒测试白盒测试灰盒测试

  • 黑盒测试中主要关注被测软件的功能实现,而不是内部逻辑。在黑盒测试中,被测对象的内部结构,运作情况对测试人员是不可见的。
  • 最常见的黑盒测试有:功能性测试、容量测试、安全性测试、负载测试、恢复性测试、标杆测试、稳定性测试、可靠性测试等。
  • 白盒测试需要你对系统内部的结构和工作原理有一个清楚的了解,并且基于这个知识来设计你的用例。
  • 白盒可以检测代码中的每条分支和路径;揭示隐藏在代码中的错误;对代码的测试比较彻底
  • 灰盒测试:白盒测试和黑盒测试往往不是决然分开的,一般在白盒测试中交叉使用黑盒测试的方法,在黑盒测试中交叉使用白盒测试的方法。灰盒测试就是这类界于白盒测试和黑盒测试之间的测试。

静态测试和动态测试

  • 静态测试
    就是不实际运行被测软件,而只是静态地检查程序代码、界面或文档中可能存在的错误的过程。
  • 动态测试
    实际运行被测程序,输入相应的测试数据,检查实际输出结果和预期结果是否相符的过程
常见的bug类型划分
  • 代码错误
  • 设计缺陷
    功能没有实现,或者功能和需求不一致
  • 界面优化
  • 性能问题
  • 配置相关
  • 安装部署
  • 其他划分: 功能类,界面类,性能类,易用性类,兼容性类,其他
bug的等级
  • 致命错误
  • 严重错误
  • 一般错误
bug的生命周期

发现BUG–>提交BUG–>指派BUG–>研发确认BUG–>研发去修复BUG–>回归验证BUG–>是否通过验证–>关闭BUG



数据结构-二分查找

def sort(arr,num):
    i,j = 0,len(arr)-1
    while i<=j:
        mid = (i+j) // 2
        if arr[mid]<num:
            i = mid+1
        elif arr[mid]>num:
            j = mid-1
        else:
            return True
    return False

注意判断条件:while i<=j

选择排序

def sort(arr):
    for k in range(len(arr)-1):
        for i in range(k+1,len(arr)):
            if arr[i] < arr[k]:
                arr[i],arr[k] = arr[k],arr[i]
    return arr

冒泡排序

def sort(arr):
    for i in range(len(arr)-1):
        flag = True
        for j in range(len(arr)-i-1):
            if arr[j]>arr[j+1]:
                arr[j],arr[j+1] = arr[j+1],arr[j]
                flag = False
        if flag:
            break
    return arr

插入排序

def sort(arr):
    for i in range(1,len(arr)):
        tmp = arr[i]
        j = i-1
        while j>=0:
            if arr[j]>tmp:
                arr[j+1] = arr[j]
            else:
                break
            j -= 1
        arr[j+1] = tmp
    return arr

快速排序

def sort(arr,a,b):
    if a<b:
        i,j = a,b
        tmp = arr[i]
        while i!=j:
            while arr[j]>=tmp and i!=j:
                j -= 1
            arr[i] = arr[j]
            while arr[i]<=tmp and i!=j:
                i += 1
            arr[j] = arr[i]
        arr[i] = tmp
        sort(arr,a,i-1)
        sort(arr,i+1,b)

参考

https://www.zhihu.com/people/song-ni-yike-zi-dan-qiu
https://blog.csdn.net/jiangjiang_jian/article/details/79140742
https://blog.csdn.net/a88055517/article/details/6736284
https://zhuanlan.zhihu.com/p/166494237
http://blog.sina.com.cn/s/blog_89b433ac0102whn7.html
https://blog.csdn.net/zhzhl202/article/details/7547445

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐