一、软件测试基础
1. 软测、软件质量
软件测试是为了发现错误而执行程序的过程。
测试分为功能测试和非功能测试:
功能测试:
正常功能、异常功能、边界测试、界面测试、接口测试、安全测试、错误处理测试等
非功能测试:
- 性能测试:测试软件的性能表现,考量软件运行的如何。
(1)压力测试:系统已经达到饱和程度时,测试系统是否会出现崩溃等
(2)负载测试:通过对被测试系统不断的加压,直到超过预定的指标或者部分资源已经达到了一种饱和状态不能再加压为止,为了寻找系统最大的负载能力
(3)容量测试:寻找软件系统某项指标(如最大并发用户数、数据库记录数、最大负载、工作量等)的极限值
(4)并发测:通过模拟用户并发访问,测试多用户同时访问同一应用、模块或数据,观察系统是否存在死锁、系统处理速度明显下降等性能问题
(5)可靠性测试(稳定性、健壮性):当系统在一定的业务压力下,让系统持续运行一段时间,观察系统是否达到要求的稳定性。
(6)配置测试:通过调整系统软/硬件环境,了解不同环境对系统性能的影响,从而找到系统的最优配置 - 安全性测试、恢复性测试、兼容性测试、可用性测试
软件质量可分解成六个要素:
3. 功能性:用户要求的功能是否全部实现了。
4. 可靠性:在规定的时间和条件下,软件所能维持它的性能水平的程度。
5. 易使用性:用户在学习、操作、准备输入和理解输出时,是否是需要作出很多的努力,就是说看用户在使用本软件时是否方便。
6. 效率:在指定的条件下,用软件实现某种功能所需的计算机资源(包括时间)的有效程度。
7. 可维修性:环境改变或软件错误发生时,进行相应修改所做的努力程度。
8. 可移植性:从一个计算机系统或环境转移到另一个计算机系统或环境的容易程度。
3.测试报告组成
- 概述:包括项目背景、需求分析
- 测试时间、测试环境
- 测试过程:评审记录、测试范围、测试用例
- 功能实现清单:列出是否已经按照测试计划实现功能
- 缺陷统计:测试缺陷统计;测试用例执行情况统计
- 测试统计情况:(1)资源统计(2)执行情况(3)问题统计(4)问题列表(5)遗留的问题
- 测试总结:测试结论(是否通过)(2)测试内容、测试用例的覆盖程度、bug的解决程度
- 测试风险
2.如何写测试用例
测试用例是为了实施测试而向被测试的系统提供一组集合,这组集合包含:测试环境、操作步骤、测试数据、预期结果等要素
1、测试人员尽早介入,彻底理解清楚需求,这个是写好测试用例的基础
2、如果以前有类似的需求,可以参考类似需求的测试用例,然后还需要看类似需求的 bug 情况
3、清楚输入、输出的各种可能性,以及各种输入的之间的关联关系,理解清楚需求的执行 逻辑,通过等价类、边界值、判定表等方法找出大部分用例
4、找到需求相关的一些特性,补充测试用例
5、根据自己的经验分析遗漏的测试场景
6、多总结类似功能点的测试点,才能够写出质量越来越高的测试用例
7、书写格式一定要清晰
基于需求的测试方法
- 等价类
- 边界值
- 因果图:适用于被测试程序具有多种输入条件、程序的输出又依赖于输入条件的各种情况
- 正交排列:目的:减少用例数目,用尽量少的用例覆盖输入的两两组合
- 场景设计法
- 错误猜测法
3.黑盒测试
黑盒测试也叫功能测试,测试的时候,完全不考虑程序内部结构和特性的情况下,在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当的接受数据而产生正确的输出信息,并且保持外部信息(如数据库或文件)的完整性。
黑盒测试是穷举输入测试,只有把所有可能的输入都作为测试情况使用,才能以这种方式查出程序中的所有错误。但是实际上测试情况有无穷多个,因此不仅要测试所有的合法输入,还应该尽可能的测试那些不合法的输入。
- 黑盒测试主要试图发现以下错误:
功能不正确或遗漏;界面错误;输入或输出错误;数据库访问错误;性能错误;初始化和终止错误。 - 常用的黑盒测试方法:
等价类划分法;边界值分析法;因果图分析法;场景法; - 正交实验设计法:(正交是从大量的试验点中挑选出适量的、有代表性的点。正交试验设计是研究多因素多水平 的一种设计方法,他是一种基于正交表的高效率、快速、经济的试验设计方法。)
判断表驱动分析法;错误推测法;功能图分析法。 - 等价类划分:
等价类划分法是把所有可能的输入数据,划分为若干子集,从每个子集中选取少量具有代表性的数据作为测试用例。
例子:验证码(4位),高于,低于四位的为一类,非数字为一类,数字为一类,4位为一类。
测试用例边界
通常边界值分析法 是作为对等价类划分法的补充,这种情况下,其测试用例来自等价类的边界。
常见的边界值
1)对 16-bit 的整数而言 32767 和 -32768 是边界
2)屏幕上光标在最左上、最右下位置
3)报表的第一行和最后一行
4)数组元素的第一个和最后一个
5)循环的第 0 次、第 1 次和倒数第 2 次、最后一次
4. 白盒测试
白盒测试也叫结构测试,是针对程序内部单元是如何进行工作的测试。他根据程序的控制结构设计测试用例,主要用于软件或程序验证。白盒测试法检查程序的内部逻辑结构,对所有的逻辑路径进行测试,是一种穷举路径的测试法,但即使每条路径都测试过了,仍然有可能存在错误。因为穷举路径测试无法检查出程序本身是否违反了设计规范,且穷举路径测试不可能检查出程序是否因为遗漏路径而出错;白盒测试无法发现与数据相关的错误。
白盒测试需要遵循的规则:
1.保证一个模块中的独立路径至少被测试了一次;
2.所有逻辑值均需要测试true或者false两种情况;
3.检查程序的内部数据结构,保证其结构的有效性;
4.在上下边界及可操作范围内运行所有循环。
常用的白盒测试方法:
逻辑覆盖法,基本路径法,符号测试,错误驱动测试。
静态测试:
不用运行程序的测试,包括代码检查、静态结构分析、代码质量度量、文档测试等等,可以由人工进行,充分发挥人的逻辑思维优势,也可以借助软件工具(Fxcop)自动进行。
动态测试:
需要执行代码,通过运行程序查找问题,包括功能确认与接口测试、覆盖率分析、性能分析、内存分析等。
条件覆盖
白盒测试中的覆盖标准有逻辑覆盖、循环覆盖和基本路径测试,其中逻辑覆盖包括语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖六种。
覆盖能力由弱到强:
- 语句覆盖每条语句至少执行一次;
- 判定覆盖:每一个判断的取真分支和取假分支至少执行一次
- 条件覆盖使每个判断中的每个条件的可能取值至少满足一次
- 判定/条件覆盖使判定条件中的所有可能至少执行一次取值,同时所有判断的可能结果(取真,取假),至少执行一次
- 条件组合覆盖每个判定中格条件的每一种组合至少出现一次;
- 路径覆盖使程序中每一条可能的路径至少执行一次。
5.测试步骤
- 单元测试
对最小的软件设计单元的进行验证,目标是确保模块被正确的编码。需要从程序内部结构出发设计测试用例,多个模块可以平行地独立进行单元测试。
(如模块接口测试、局部数据结构测试、路径测试、错误处理测试、边界测试) - 集成测试
通过测试发现与模块接口有关的问题。在单元测试的基础上,将所有模块按照概要设计说明书和详细设计说明书的要求进行组装。
自顶而下集成:首先集成主模块,然后按照控制层次结构向下进行,逐渐把各个模块结合起来。(在把附属于主控制模块的那些模块组装到程序结构中去时,可以使用深度优先的策略或者广度优先的策略。)
自底而上集成:把低层模块组合成实现某个特定的软件 - 系统测试
系统测试是基于系统整体需求说明书的黑盒类测试,通常意义上包括:压力测试(也称为强度测试),容量测试,负载测试,性能测试,安全测试,容错测试等。 - 回归测试
回归测试是指在发生修改之后重新测试先前的测试用例以保证修改的正确性 - 验收测试
独立测试人员根据测试计划和结果对系统进行测试和验收,它让系统用户决定是否接受系统。它是一项确定产品是否满足合同和用户规定需求的测试,验收测试包括alpha测试和beta测试。
Alpha测试:是由用户在开发者的环境下进行的,在一个受控的环境下进行。
Beta测试:由软件的最终用户在一个或者多个场所中进行,开发者通常不在现场,用户记录测试中遇到的问题并报告给开发者,开发者对系统进行最后的修改,并开始准备发布最终软件。
6.V模型和W模型
软件生命周期模型是跨越整个生存期的系统开发、运作和维护所实施的全部过程、活动和任务的结构框架。
v模型
V模型测试流程:
需求分析–概要设计–详细设计–软件编码
--单元测试–集成测试–系统测试–验收测试,
目的是改进软件开发的效率和效果,是瀑布模型的变种
软件测试V模型指出:
- 单元和集成测试应检测程序的执行是否满足软件设计的要求;
- 系统测试应检测系统功能、性能的质量特性是否达到系统要求的指标;
- 验收测试确定软件的实现是否满足用户需要或合同的要求。
优点:
- 明确地标注了测试过程中存在的不同测试类型;
- 清楚的描述了这些测试阶段和开发过程期间个阶段的对应关系;
缺点:
- 不适合需求变化频繁的程序;
- 发现错误时间较晚;
- 仅仅把测试作为在编码之后的一个阶段,未在需求阶段就进入测试;
w模型
W模型流程:
用户需求–需求分析与系统设计–概要设计–详细设计
–编码–单元测试–集成测试–验收测试–
单元测试设计–集成测试设计–系统测试设计–验收测试设计
–集成–实施–交付
W模型是为解决V模型的缺陷而产生,增加了软件开发阶段中应同步进行的验证的确认活动
特点:测试的对象不仅是程序,需求、设计等同样要测试,开发与测试同步
优点:可以尽早的发现错误,降低风险,减少成本,提高质量
缺点
12. 不能适应用户需求变化频繁的项目;
13. 需求、设计、编码等活动被视为串型的;
14. 测试和开发活动也保持这一种线性的前后关系,上一阶段完全结束,才可以正式开始下一个阶段工作;
15. 无法支持敏捷开发模式;
16. 对于当前软件开发复杂多变的情况,W模型并不能解除测试管理面临的困惑;
7.BUG生命周期
生命周期中BUG状态:新建–>指派–>已解决–>待验–>关闭
- 发现BUG–>提交BUG–>指派BUG–>研发确认BUG–>研发去修复BUG–>回归验证BUG–>是否通过验证–>关闭BUG
- 如果待验的BUG在验证时没有解决好,我们需要重新打开–指派—已解决—待验,循环这个过程。
8.BUG优先级
- 致命的(Fatal):
造成系统或应用程序崩溃、死机、系统挂起,或造成数据丢失,主要功能完全丧失,导致本模块以及相关模块异常等问题。如代码错误,死循环,数据库发生死锁、与数据库连接错误或数据通讯错误,未考虑异常操作,功能错误等 - 严重错误(critical):
系统的主要功能部分丧失、数据不能保存,系统的次要功能完全丧失。问题局限在本模块,导致模块功能失效或异常退出。如致命的错误声明,程序接口错误,数据库的表、业务规则、缺省值未加完整性等约束条件 - 一般错误(major):
次要功能没有完全实现但不影响使用。如提示信息不太准确,或用户界面差,操作时间长,模块功能部分失效等,打印内容、格式错误,删除操作未给出提示,数据库表中有过多的空字段等。 - 较小错误(Minor):
使操作者不方便或遇到麻烦,但它不影响功能的操作和执行,如错别字、界面不规范(字体大小不统一,文字排列不整齐,可输入区域和只读区域没有明显的区分标志),辅助说明描述不清楚
9.web 测试和 app 测试的不同点
- 系统架构方面:
web 项目,一般都是 b/s 架构,基于浏览器的
app 项目,则是 c/s 的,必须要有客户端,用户需要安装客户端。
web 测试只要更新了服务器端,客户端就会同步会更新。App 项目则需要客户端和服务器都 更新。 - 性能方面:
web 页面主要会关注响应时间 ;app 则还需要关心流量、电量、CPU、GPU、Memory 这些。
它们服务端的性能没区别,都是一台服务器。 - 兼容方面:
web 是基于浏览器的,所以更倾向于浏览器和电脑硬件,电脑系统的方向的兼容
app 测试则要看分辨率,屏幕尺寸,还要看设备系统。
web 测试是基于浏览器的所以不必考虑安装卸载。 而 app 是客户端的,则必须测试安装、更新、卸载。 - 除了常规的安装、更新、卸载还要考虑 到异常场景。包括安装时的中断、弱网、安装后删除安装文件 。 此外 APP 还有一些专项测试:如网络、适配性。
10.是否做过压力测试
- 首先对要测试的系统进行分析,明确需要对哪一部分做压力测试,比如秒杀,支付
- 如何进行施压
第一种:可以通过写脚本产生压力机器人对服务器进行发包收报操作
第二种:借助一些压力测试工具比如 Jmeter,LoadRunner - 如何进行正确的施压
需要用压力测试工具或者其他方法录制脚本,模拟用户的操作 - 设计多大的压力比较合适?
需要明确压力测试限制的数量,即用户并发量 - 如何通过这些数据来定位性能问题
通过测试可以得到吞吐量,平均响应时间等数据,这个数据的背后是整个后台处理逻辑综合作用的结果,这时候就可以先关注系统的 CPU,内存,然后对比吞吐量,平均响应时间达到瓶颈 时这些数据的情况,然后就能确认性能问题是系统的哪一块造成的
11.性能测试的指标
一、性能测试常用指标:
从外部看
- 吞吐量:每秒钟系统能够处理的请求数,任务数
- 响应时间:服务处理一个请求或一个任务的耗时
- 错误率:一批请求中结果出错的请求所占比例
从服务器的角度看,性能测试关注 CPU,内存,服务器负载,网络,磁盘I/O
二、对登录功能做性能测试
- 单用户登陆的响应界面是否符合预期
- 单用户登陆时后台请求数量是否过多
- 高并发场景下用户登录的响应界面是否符合预期
- 高并发场景下服务端的监控指标是否符合预期
- 高集合点并发场景下是否存在资源死锁和不合理的资源等待
- 长时间大量用户连续登录和登出, 服务器端是否存在内存泄漏
三、怎么测出可同时处理的最大请求数量:
可以采用性能测试工具(WeTest 服务器性能),该工具是腾讯 wetest 团队出品,使用起来很 简单方便,但测试功能相当强大,能提供 10w+以上的并发量,定位性能拐点,测出服务器模型 最大并发
12、安全性测试
安全性测试的工具又有很多,其中以AppScan最为全面,他几乎涵盖了所有安全测试的问题,并且能够生成一个安全测试报告。
- 跨网站脚本攻击:通过脚本语言的缺陷模拟合法用户,控制其账户,盗窃敏感数据
- 注入攻击:通过构造查询对数据库、LDAP和其他系统进行非法查询
- 恶意文件执行:在服务器上执行Shell 命令Execute,获取控制权
- 伪造跨站点请求:发起Blind 请求,模拟合法用户,要求转账等请求
- 不安全对象引用:不安全对象的引入,访问敏感文件和资源,WEB应用返回敏感文件内容
- 被破坏的认证和Session管理:验证Session token 保护措施,防止盗窃session
- Session的失效时间限制:Session的失效时间设置是否过长,会造成访问风险
- 不安全的木马存储:过于简单的加密技术导致黑客破解编密码,隐秘信息被盗窃,验证其数据加密
- 不安全的通讯:敏感信息在不安全通道中以非加密方式传送, 敏感信息被盗窃,验证其通讯的安全性
- URL访问限制失效:验证是否通过恶意手段访问非授权的资源链接,强行访问一些登陆网页,窃取敏感信息
- 信息泄露和不正确错误处理测试:恶意系统检测,防止黑客用获取WEB站点的具体信息的攻击手段获取详细系统信息
- 注册与登录测试:验证系统先注册后登录、验证登录用户名和密码匹配校验,密码长度及尝试登录次数,防止 非法用户登录
- 超时限制:验证WEB应用系统需要有是否超时的限制,当用户长时间不做任何操作的时候,需要重新登录才能使用
- 日志文件:验证服务器上日志是否正常工作,所有事务处理是否被记录
- 目录文件:验证WEB服务器目录访问权限,或者每个目录访问时有index.htm,防止 WEB 服务器处理不适当,将整个WEB目录暴露
- 身份验证:验证调用者身份、数据库身份、验证是否明确服务账户要求、是否强制式试用账户管理措施
- 授权:验证如何向最终用户授权、如何在数据库中授权应用程序,确定访问系统资源权限
- 会话:验证如何交换会话标识符、是否限制会话生存期、如何确保会话存储状态安全
- 配置管理:验证是否支持远程管理、是否保证配置存储安全、是否隔离管理员特权
- 备份与恢复:为了防止系统意外崩溃造成的数据丢失,验证备份与恢复功能正常实现、备份与恢复方式是否满足Web系统安全性要求
- 数据库关键数据是否进行加密存储,是否在网络中传递敏感数据
- 在登录或注册功能中是否有验证码存在,防止恶意大批量注册登录的攻击
- Cookie文件是否进行了加密存储,防止盗用cookie内容
- 密码强度提醒:建议对密码的规则进行加强设置
- 密码内容禁止拷贝粘贴
二、测试用例
1. 请问你怎么测试网络协议
协议测试包括四种类型的测试
- 一致性测试:检测协议实现本身与协议规范的符合程度
- 互操作性测试:基于某一协议检测不同协议实现间互操作互通信的能力
- 性能测试:检测协议实现的性能指标,比如数据传输速度,连接时间,执行速度,吞吐量,并发度
- 健壮性测试:检测协议是现在各种恶劣环境下运行的能力,比如注入干扰报文,通信故障,信道被切断
2.请你对朋友圈点赞功能进行测试
- 是否可以正常点赞和取消;
- 点赞的人是否在可见分组里
- 点赞状态是否能即时更新显示;
- 点赞状态,共同好友是否可见;
- 性能检测: 网速快慢对其影响;
- 点赞显示的是否正确,一行几个;
- 点赞是否按时间进行排序,头像对应的是否正确;
- 是否能在消息列表中显示点赞人的昵称、
- 不同手机,系统显示界面如何; 备注;
- 可扩展性测试,点赞后是否能发表评论;
- 是否在未登录时可查看被点赞的信息。
3. 杯子检测
- 功能
(1)水倒水杯容量的一半
(2)水倒规定的安全线
(4)水杯容量刻度与其他水杯一致
(5)盖子拧紧水倒不出来
(6)烫手验证 - 性能
(1)使用最大次数或时间
(2)掉地上不易损坏
(3)盖子拧到什么程度水倒不出来
(4)保温时间长
(5)杯子的耐热性
(6)杯子的耐寒性
(7)长时间放置水不会漏
(8)杯子上放置重物达到什么程度杯子会被损坏 - 界面
(1)外观完整、美观
(2)大小与设计一样(高、宽、容量、直径)
(3)拿着舒服
(4)材质与设计一样
(5)杯子上的图案掉落
(6)图案遇水溶解 - 安全
(1)杯子使用的材质毒或细菌的验证
(2)高温材质释放毒性
(3)低温材质释放毒性 - 易用性
(1)倒水方便
(2)喝水方便
(3)携带方便
(4)使用简单,容易操作
(5)防滑措施 - 兼容性
(1)杯子能够容纳果汁、白水、酒精、汽油等。 - 震动测试
(1)杯子加包装(有填充物),六面震动,检查产品是否能应对铁路/公路/航空运输。 - 可移植性
(1)杯子在不同地方、温度环境下都可以正常使用。
4.如何对淘宝搜索框进行测试
一. 功能测试
- 输入关键字,查看: 返回结果是否准确,返回的文本长度需限制
1.1 输入可查到结果的正常关键字、词、语句,检索到的内容、链接正确性;
1.2 输入不可查到结果的关键字、词、语句;
1.3 输入一些特殊的内容,如空、特殊符、标点符、极限值等,可引入等价类划分的方法等; - 结果显示:标题,卖家,销售量,单行/多行,是否有图片
- 结果排序:价格 销量 评价 综合
- 返回结果庞大时,限制第一页的现实量,需支持翻页
- 多选项搜索:关键字 品牌 产地 价格区间 是否天猫 是否全国购
- 是否支持模糊搜索,支持通配符的查询
- 网速慢的情况下的搜索
- 搜索结果为空的情况
- 未登录情况和登录情况下的搜索(登录情况下 存储用户搜索的关键字/搜索习惯)
二、性能测试
- 压力测试:在不同发用户数压力下的表现(评价指标如响应时间等)
- 负载测试:看极限能承载多大的用户量同时正常使用
- 稳定性测试:常规压力下能保持多久持续稳定运行
- 内存测试:有无内存泄漏现象
- 大数据量测试:如模拟从庞大的海量数据中搜索结果、或搜索出海量的结果后列示出来, 看表现如何等等。
三. 易用性:交互界面的设计是否便于、易于使用
- 依据不同的查询结果会有相关的人性化提示: 查不到时告知?查到时统计条数并告知?有 疑似输入条件错误时提示可能正确的输入项等等处理;
- 查询出的结果罗列有序,如按点击率或其他排序规则,确保每次查询出的结果位置按规则 列示方便定位,显示字体、字号、色彩便于识别等等;
- 标题查询、全文检索、模糊查询、容错查询、多关键字组织查询(空格间格开)等实用的 检索方式是否正常?
- 输入搜索条件的控件风格设计、位置摆放是否醒目便于使用者注意到,有否快照等快捷查 看方式等人性化设计?
四. 兼容性
- windows /Linux等各类操作系统下及各版本条件下的应用
- IE/FIREFOX/GOOGLE/360/QQ 等各类浏览器下及各版本条件下、各种显示分辨率条件下的应 用
- SQL/ORACLE/DB2/MYSQL 等各类数据库存储情况下的兼容性测试
- 简体中文、繁体中文、英文等各类语种软件平台下的兼容性测试
- IPHONE/IPAD、安卓等各类移动应用平台下的兼容性测试
- 与各相关的监控程序的兼容性测试,如输入法、杀毒、监控、防火墙等工具同时使用
五. 安全性
- 被删除、加密、授权的数据,不允许被 SQL 注入等攻击方式查出来的,是否有安全控制设 计;
- 录入一些数据库查询的保留字符,如单引号、%等等,造成查询 SQL 拼接出的语句产生漏 洞,如可以查出所有数据等等,这方面要有一些黑客攻击的思想并引入一些工具和技术,如爬网 等。
- 通过白盒测试技术,检查一下在程序设计上是否存在安全方面的隐患
- 对涉及国家安全、法律禁止的内容是否进行了相关的过滤和控制;
5.如何测试登陆界面
一、功能测试
- 输入正确的用户名和密码,点击提交按钮,验证是否能正确登录。
- 输入错误的用户名或者密码,验证登录会失败,并且提示相应的错误信息。
- 登录成功后能否能否跳转到正确的页面
- 用户名和密码,如果太短或者太长,应该怎么处理
- 用户名和密码,中有特殊字符(比如空格),和其他非英文的情况
- 记住用户名的功能
- 登陆失败后,不能记录密码的功能
- 用户名和密码前后有空格的处理
- 密码是否非明文显示显示,使用星号圆点等符号代替。
- 牵扯到验证码的,还要考虑文字是否扭曲过度导致辨认难度大,考虑颜色(色盲使 用者), 刷新或换一个按钮是否好用
- 登录页面中的注册、忘记密码,登出用另一帐号登陆等 链接是否正确
- 输入密码的时候,大写键盘开启的时候要有提示信息
- 什么都不输入,点击提交按钮,检查提示信息。
二、界面测试
- 布局是否合理,testbox 和按钮是否整齐。
- testbox 和按钮的长度,高度是否复合要求。
- 界面的设计风格是否与 UI 的设计风格统一。
- 界面中的文字简洁易懂,没有错别字。
三、性能测试
- 打开登录页面,需要的时间是否在需求要求的时间内。
- 输入正确的用户名和密码后,检查登录成功跳转到新页面的时间是否在需求要求的时间内。
- 模拟大量用户同时登陆,检查一定压力下能否正常登陆跳转。
四、安全性测试
- 登录成功后生成的 Cookie,是否是 httponly (否则容易被脚本盗取)。
- 用户名和密码是否通过加密的方式,发送给 Web 服务器。
- 用户名和密码的验证,应该是用服务器端验证,而不能单单是在客户端用 javascript 验 证。
- 用户名和密码的输入框,应该屏蔽 SQL 注入攻击。
- 用户名和密码的的输入框,应该禁止输入脚本 (防止 XSS 攻击)。
- 防止暴力破解,检测是否有错误登陆的次数限制。
- 是否支持多用户在同一机器上登录。
- 同一用户能否在多台机器上登录
五、可用性测试
- 是否可以全用键盘操作,是否有快捷键。
- 输入用户名,密码后按回车,是否可以登陆。
- 输入框能否可以以 Tab 键切换。
六、兼容性测试
- 不同浏览器下能否显示正常且功能正常(IE,6,7,8,9, Firefox, Chrome, Safari,等)。
- 同种浏览器不同版本下能否显示正常且功能正常。
- 不同的平台是否能正常工作,比如 Windows, Mac。
- 移动设备上是否正常工作,比如 Iphone, Andriod。
- 不同的分辨率下显示是否正常。
七、本地化测试
6. 不同语言环境下,页面的显示是否正确
6.测试有系统大量并发访问
如何做高并发系统的测试,一般而言,整体的测试策略是:
先针对部分系统进行性能测试及压力测试,得到各部分的峰值处理性能,再模拟整体流程测试,重点测试整体业务流程以及业务预期负荷.
着重测试以下几点:
- 不同省份,不同运营商 CDN 节点性能,可采用典型压力测试方案
- 核心机房 BGP 网络带宽,此部分重点在于测试各运行商的 BGP 网络可靠性,实际速率, 一般采用 smokeping,lxChariot 等工具
- 各类硬件设备性能,一般采用专业的网络设备测试工具
- 各类服务器并发性能,分布式处理能力,可采用压力测试方案工具
- 业务系统性能,采用业务系统压力测试方案
- 数据库处理性能,这部分需要结合业务系统进行测试,以获取核心业务场景下的数据库 的 TPS/QPS,
- 如果有支付功能,需要进行支付渠道接口及分流测试,此部分相对而言可能是最大的瓶 颈所在,此外还涉及备份方案,容灾方案,业务降级方案的测试。
三、计算机基础
1.讲一下OSI七层协议
- 应用层
位于第七层,作用是为用户的应用进程提供网络通信服务。
提供的常用协议有:HTTP(超文本传输协议,底层TCP,默认端口80)、HTTPS(443)、FTP(文本传输协议、TCP、23)、TFTP(简单文本传输协议、21、UDP) - 表示层
处理用户信息的表示问题:比如数据的编码,压缩和解压缩,数据的加密和解密、格式转换等。(LPP轻量级表示协议、XDP外部数据表示协议、会话服务协议) - 会话层
是用户应用程序和网络之间的接口,主要任务是:向两个实体的表示层提供建立和使用连接的方法。比如:会话管理、会话流量控制、寻址。(包含SQL结构化查询语言、网络文件系统 NFS、远程过程调用RPC 、DNS协议、SMTP协议)NDS(域名解析服务、53、服务器间进行域传输TCP、客户端查询UDP) - 传输层
主要是为两台主机进程之间的通信提供服务。(TCP、UDP) - 网络层
将网络地址翻译成对应的物理地址,并通过路由选择算法为分组通过通信子网选择最适当的路
径。(IP、ICMP、ARP、AKP等) - 数据链路层
接收来自物理层的位流形式的数据,并封装成帧,传送到上一层(PDN/PPP等) - 物理层
利用传输介质为数据链路层提供物理连接,实现比特流的透明传输,如网线;网卡标准。(IEEE 802.1A,IEEE 802.2到IEEE 802.11)
2.讲一下TCP/IP参考模型
应用层、传输层、网际互连层、网络访问层
3.网络层常见协议?(IP、ICMP、RIP、IGMP)
- IP(网际协议)
IP协议不但定义了数据传输时的基本单元和格式,还定义了数据报的递交方法和路由选择 - ICMP(Internet控制报文协议)
ICMP就是一个“错误侦测与回报机制”,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性,是ping和traceroute的工作协议 - RIP (路由信息协议)
使用“跳数”(即metric)来衡量到达目标地址的路由距离 - IGMP (Internet组管理协议)
用于实现组播、广播等通信
4. HTTP头部
通用头:是客户端和服务器都可以使用的头部,可以在客户端、服务器和其他应用程序之间提供一些非常有用的通用功能,如Date头部。
请求头:是请求报文特有的,它们为服务器提供了一些额外信息,比如客户端希望接收什么类型的数据,如Accept头部。
响应头:便于客户端提供信息,比如,客服端在与哪种类型的服务器进行交互,如Server头部。
实体头:指的是用于应对实体主体部分的头部,比如,可以用实体头部来说明实体主体部分的数据类型,如Content-Type头部。
5. HTTP状态码
HTTP 状态码由三个十进制数字组成,第一个数字定义了状态码的类型,后两个并没有起到分类的作用。HTTP 状态码共有 5 种类型:
- 1XX 指示信息–表示请求正在处理
- 2XX 成功–表示请求已被成功处理完毕
- 3XX 重定向–要完成的请求需要进行附加操作
- 4XX 客户端错误–请求有语法错误或者请求无法实现,服务器无法处理请求
- 5XX 服务器端错误–服务器处理请求出现错误
200 响应成功
302 跳转,重定向
403 拒绝访问 404 找不到资源
501 服务器不支持当前请求所需要的某个功能
6.GET和POST区别(http请求方法)
GET 请求指定的页面信息,并返回实体主体。
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
- get是获取数据,post是修改数据,而且 post比get更安全,
因为 get t把请求的数据放在url上, 以?分割URL和传输数据,参数之间以&相连,所以get不太安全。参数直接暴露在 URL中,可能会存在安全问题,因此往往用于获取资源信息。
而 post 参数放在 HTTP的包体内(requrest body )中,并且参数不会被保留,相比get 方法,post 方法更安全,主要用于修改服务器上的资源。
- get 请求只支持 URL 编码,post 请求支持多种编码格式。
- get 只支持 ASCII 字符格式的参数,而 post 方法没有限制。
- GET请求会被浏览器主动缓存,而POST不会,除非手动设置。
- get 提交的数据大小有限制(针对浏览器),最大是2k,而 post 方法提交的数据没限制
- GET产生一个TCP数据包,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
- POST产生两个TCP数据包,浏览器先发送header,服务器响应100 状态码,浏览器再发送data,服务器响应200 ok(返回数据)。
7 URI和URL的区别(应用层)
URL(统一资源定位符),就是平时上网输入的网址,它标识了一个互联网资源,并指定对其进行操作或获取该资源的方法;
URI(统一资源标识符)是一种抽象概念,URL是URI的子集
简而言之就是,只要能唯一标识资源的就是URI,在URI基础上给出其资源的访问方式的就是URL。
8.在浏览器输入一个URL(http请求)
- 在发送http请求前,需要域名解析(DNS解析),获取对应的IP
浏览器先查看浏览器缓存-操作系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。
(1)浏览器缓存:,先在浏览器找之前有没有缓存过的域名所对应的ip地址,如果有,就调用这个 IP 地址映射,解析完成。
(2)操作系统缓存:(查找硬盘的hosts文件)使系统调用操作系统,获取操作系统的记录(保存最近的DNS查询缓存);
(3) 路由器缓存:向DNS服务器发送DNS请求,查询本地DNS服务器,这其中用的是UDP的协议。在一个子网内采用ARP地址解析协议进行ARP查询,如果不在一个子网那就需要对默认网关进行DNS查询。如果缓存中有此条记录,就可以直接返回结果。
(5)如果没有,本地DNS服务器还要向DNS根服务器进行查询。 - 拿到解析的IP地址及端口号(http 80 端口,https 443 端口),调用系统库函数Socket,向服务器发起tcp连接,与浏览器建立tcp三次握手。
- 客户端向服务器发送 HTTP 请求报文。
- 服务器端经过物理层→数据链路层→网络层→传输层→应用层,解析请求报文,发送 HTTP 响应报文。
- 关闭连接,TCP 四次挥手。
- 客户端解析 HTTP 响应报文,浏览器开始显示 HTML
- 分析页面中的超链接,显示在当前页面,重复以上过程直至没有超链接需要发送,完成页面的全部显示。
(1)应用层:客户端发送 HTTP 请求报文。
(2)传输层:(加入源端口、目的端口)建立连接。实际发送数据之前,三次握手客户端和 服务器建立起一个 TCP 连接。
(3)网络层:(加入 IP 头)路由寻址。
(4)数据链路层:(加入 frame 头)传输数据。
(5)物理层:物理传输 bit。
9.HTTP和HTTPS的区别
1.HTTP协议以明文方式发送内容,数据未加密,安全性较差;而HTTPS数据传输过程是加密的。
2.HTTP和HTTPS使用的连接方式不一样,用的端口也不一样,HTTP使用80端口,HTTPS使用443端口。
3.HTTPS协议需要到数字机构申请证书,要钱。
4.HTTP页面响应比HTTPS快,主要HTTP使用三次握手建立连接,而HTTPS除了三次握手,还需要经历一个SSL协商过程。
10. HTTPS加密(SSL是怎么保证安全的)
HTTPS 采用对称加密和非对称加密相结合的方式。
使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。
- 对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥。
优点:运算速度快 缺点:无法安全地将密钥传输给通信方 - 非对称密钥加密,,加密(公开密钥)和解密(私有密钥)使用不同的密钥。
优点:可以更安全地将公开密钥传输给通信发送方;缺点:运算速度慢。
使用SSL(安全套阶层)、TLS(安全层传输协议)。SSL 利用数据加密、身份验证和消息完整性验证机制,为网络上数据的传输提供安全性保证。
(1)客户端向服务器端发起SSL连接请求;
(2)服务器把公钥发送给客户端,并且服务器端保存着唯一的私钥
(3)客户端用公钥对双方通信的对称秘钥进行加密,并发送给服务器端
(4)服务器利用自己唯一的私钥对客户端发来的对称秘钥进行解密,
(5)进行数据传输,服务器和客户端双方用公有的相同的对称秘钥对数据进行加密解密,可以保证在数据收发过程中的安全,即是第三方获得数据包,也无法对其进行加密,解密和篡改。
11.Cookie是什么?
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,
HTTP 协议是无状态的,主要是为了让 HTTP 协议尽可能简单,使得它能够处理大量事务,HTTP/1.1 引 入 Cookie 来保存状态信息,通过在请求和响应报文中写入cookie信息来控制客户端的状态。
可以用在哪些方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
12. Socket(TCP/IP)
- socket
是对TCP/IP协议的封装。socket是应用层与TCP/IP协议族通信的一组调用接口(TCP/IP网络的API函数),是基于TCP协议的,所以通常情况下 Socket 连接就是 TCP 连接,因此 Socket 连接一旦建立,通信双方即可开始相互发送数据内容. - HTTP
连接使用的是**“请求—响应**”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
13.http 1.0 和1.1区别
- 长连接:
http1.0 中默认使用短连接,服务器和客户端每进行一次 http 操作,就建立一次连接,任务结束就终端连接,
http1.1 :默认使用长连接,用以保持连接特性,当一个网页打开完成后, 服务器和客户端之间用于传输 http 数据的 tcp 连接不会关闭,客户端再次访问这个服务器时, 会继续使用这一条已经建立好的连接。 - 错误状态响应码 :
在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。 - 缓存处理 :
在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准
HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。 - 带宽优化及网络连接的使用 :
HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器;如果返回401,客户端就可以不用发送请求body了节约了带宽。
14.讲一下三次握手(传输层)
三次握手是TCP连接的建立过程,刚开始,客户端进入close状态,服务端处于listen状态
- 第一次握手:建立连接时,客户端发送 SYN 包到服务器(标志位SYN=1,初始序号为Seq = X),并进入SYN-SENT 状态, 等待服务器确认;SYN:同步序列编号。
- 第二次握手:服务器收到 SYN 包,必须确认客户的 SYN,(返回ACK=X+1),同时自己也发送一个 SYN 包(syn=1,Seq = y),即一起发了 SYN+ACK 包,此时服务器进入 SYN-RECV 状态;
- 第三次握手:客户端收到服务器的 SYN+ACK 包,向服务器发送确认包 ACK(ack=y+1),此包发送完毕,客户端和服务器进入 ESTABLISHED(TCP 连接成功)状态,完成三次握手。
为什么三次
如果只进行两次握手,服务端不知道客户端能否接收消息,同时也不知道自已的消息发出去了没有,三次握手已经保证了TCP连接的需求,所以就不用第四次握手了
15.讲一下四次挥手(传输层)
在挥手之前主动释放连接的客户端结束 ESTABLISHED 阶段,随后开始四次挥手:
- 第一次挥手
客户端向服务器发送一段 FIN 报文 (FIN=1,序号seq=u),表明其想要释放 TCP 连接,随后 客户端进入FIN-WAIT-1 阶段,并且停止发送通信数据。 - 第二次挥手
(1)服务端收到 FIN 报文之后,会发送 ACK 报文 (ACK=1 , 确认号 ack=u+1 , 序 号 seq=v),表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
(2) 客户端收到服务器发送过来的报文后,确认服务器已经收到连接释放的请求,随后客户结束 FIN-WAIT-1 阶段,进入FIN-WAIT-2 阶段 - 第三次挥手
服务器端在发出ACK 确认报文后,会将遗留的待传数据传送给客户端,待传输完成后即经过 CLOSE-WAIT 阶段,便做好了释放服务器端到客户端的连接准备,再次向客户端发出一段连接释放报文段 (FIN=1,ACK=1,序号seq=w,确认号ack=u+1),随后服务器端结束 CLOSE-WAIT 阶段,进入 LAST-ACK 阶段。并且停止向客户端发送数据。
4.第四次挥手
(1) 客户端收到 FIN 报文之后,再发送一个 ACK 报文作为应答(ACK=1,seq=u+1,ack=w+1),并结束 FIN-WAIT-2 阶段,进入 TIME-WAIT 阶段。
随后客户端开始在 TIME-WAIT 阶段 等待 2 MSL 。
(2)服务器端收到从客户端发出的 TCP 报文之后结束 LAST-ACK 阶段,进入 CLOSED 阶段。由此正式确认关闭服务器端到客户端方向上的连接。
客户端等待完 2 MSL 之后,结束 TIME-WAIT 阶段,进入 CLOSED 阶段,由此完成「四次挥手」。
为什么四次
在连接中,服务器的 ack 和 syn 包是同时发送的,
而在断开连接的时候,服务器向客户端发 送的 ack 和 fin 包是分两次发送的,因为服务器收到客户端发送的 fin 包时,可能还有数据要传 送,所以先发送 ack,等数据传输结束后再发送 fin 断开这边的连接。
CLOSE-WAIT 和 TIME-WAIT 的状态和意义
- CLOSE-WAIT 状态就是为了保证服务器在关闭连接之前将待发送的数据发送完成。
- TIME-WAIT 发生在第四次挥手,当客户端发送 ACK 确认报文后进入该状态,若取消该状态,即客户端在收到 FIN 报文后立即关闭连接,此时服务端相应的端口并没有关闭,若客户端在相同的端口立即建立新的连接,则有可能接收到上一次连接中残留的数据包,可能会导致不可预料的异常出现。
- 除此之外,假设客户端最后一次发送的 ACK 包在传输的时候丢失了,由于 TCP 协议的超时重传机制,服务端将重发 FIN 报文,若客户端并没有维持 TIME-WAIT 状态而直接关闭的话,当收到服务端重新发送的 FIN 包时,客户端就会用 RST 包来响应服务端,这将会使得对方误认为是有错误发生。
2MSL等待理由
MSL指最长报文段寿命,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
- 保证客户端发送的最后一个ACK报文段能够到达服务端。
- 防止“已失效的连接请求报文段”出现在本连接中。
16.TCP、UDP区别(传输层)
传输控制协议和用户数据报协议区别
面向连接的TCP协议保证了数据的传输可靠性,面向无连接的UDP协议能够实现数据表简单、快速地传输。
TCP 是面向连接的,UDP 是面向无连接的
UDP程序结构较简单,传输效率更高
TCP 是面向字节流的,UDP 是基于数据报的
TCP保证数据正确性,UDP 可能丢包
TCP 保证数据顺序,UDP 不保证
17.TCP是如何保证可靠的
- 数据分块:应用数据被分割成 TCP 认为最适合发送的数据块。
- 序列号和确认应答:TCP 给发送的每一个包进行编号,在传输的过程中,每次接收方收到数据后,都会发送 ACK 报文,告诉发送方成功接收了哪些数据以及下一次的数据从哪里开始发。
- 校验和:TCP 将保持它首部和数据部分的检验和,如果收到报文段的检验和有差错,TCP 将丢弃这个报文段并且不确认收到此报文段。
- 流量控制:发送方发送的数据量不能超过接收端缓冲区的大小。当接收方来不及处理发送方的数据,会提示发送方降低发送的速率,防止产生丢包。
- 拥塞协议:当网络某个节点发生拥塞时,减少数据的发送。
- ARQ协议:为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
- 超时重传:当 TCP 发出一个报文段后,它启动一个定时器,等待目的端确认收到这个报文段。如果超过某个时间还没有收到确认,将重发这个报文段。
- TCP 的顺序问题,丢包问题,流量控制都是通过滑动窗口来解决的拥塞控制时通过拥塞窗口来解决的
滑动窗口
TCP 建立连接时,各端分配一个缓冲区用来存储接受的数据,并将缓冲区的尺寸发送给另一 端,接收方发送的确认消息中包含了自己剩余的缓冲区尺寸,剩余缓冲区空间的数量叫做窗口, 所谓滑动窗口,就是接收端可以根据自己的状况通告窗口大小,从而控制发送端的接收,进行流 量控制
18.TCP拥塞控制(慢启动、拥塞避免、拥塞发生。快速回复)
拥塞控制到现在主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生,4)快速恢复。
-
慢热启动算法 – Slow Start
所谓慢启动,也就是TCP连接刚建立,一点一点地提速,试探一下网络的承受能力,以免直接扰乱了网络通道的秩序。
慢启动算法:
(1) 连接建好的开始先初始化拥塞窗口cwnd大小为1,表明可以传一个MSS大小的数据。
(2) 每当收到一个ACK,cwnd大小加一,呈线性上升。
(3)每当过了一个往返延迟时间RTT(Round-Trip Time),cwnd大小直接翻倍,乘以2,呈指数让升。
(4) 还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法” -
拥塞避免算法 – Congestion Avoidance
当拥塞窗口大小 >= 慢启动阈值 ssthresh后,就进入拥塞避免算法。
算法如下:
(1) 收到一个ACK,则cwnd = cwnd + 1 / cwnd
(2)每当过了一个往返延迟时间RTT,cwnd大小加一。
(3)过了慢启动阈值后,拥塞避免算法可以避免窗口增长过快导致窗口拥塞,而是缓慢的增加调整到网络的最佳值。 -
拥塞发生状态时的算法
TCP拥塞控制默认认为网络丢包是由于网络拥塞导致的,所以一般的TCP拥塞控制算法以丢包为网络进入拥塞状态的信号。
(1)对于丢包有两种判定方式,一种是超时重传RTO超时,另一个是收到三个重复确认ACK。
(2)超时重传是TCP协议保证数据可靠性的一个重要机制,其原理是在发送一个数据以后就开启一个计时器,在一定时间内如果没有得到发送数据报的ACK报文,那么就重新发送数据,直到发送成功为止。
(3)但是如果发送端接收到3个以上的重复ACK,TCP就意识到数据发生丢失,需要重传。这个机制不需要等到重传定时器超时 -
快速恢复算法 – Fast Recovery
在进入快速恢复之前,拥塞窗口cwnd和慢启动阈值ssthresh已经被更改为原有cwnd的一半。
19. PING(网络层)
- ping命令通常用来作为网络可用性的检查。ping命令可以对一个网络地址发送测试数据包,看该网络地址是否有响应并统计响应时间,以此测试网络。
- 两台电脑连起来后 ping 不通,你觉得可能存在哪些问题?
· 首先看网络是否连接正常,检查网卡驱动是否正确安装。
局域网设置问题,检查 IP 地址是否设置正确。
· 看是否被防火墙阻拦(有些设置中防火墙会对 ICMP 报文进行过滤),如果是的话,尝试关闭防火墙 。
· 看是否被第三方软件拦截。
· 两台设备间的网络延迟是否过大(例如路由设置不合理),导致 ICMP 报文无法在规定的时间内收到。
20.光猫、路由器和交换机的区别
- 交换机:是一种用于光/电信号转发的网络设备,它利用主机的物理地址(MAC 地址)确定数据转发的目的地址,它工作在数据链路层。
- 路由器:路由器接入光猫,发射wifi信号,实现网络共享,路由器通过数据包中的目的 IP 地址识别不同的网络从而确定数据转发的目的地址,网络号是唯一的。路由器根据路由选择协议和路由表信息从而确定数据的转发路径,直到到达目的网络,它工作于网络层。
- 光猫:负责的是将通过光纤传送的数字信号和模拟信号之间进行转换,在发送端通过调制将数字信号转换为模拟信号,而在接收端通过解调再将模拟信号转换为数字信号,通俗的说就是数字信号与模拟信号的“翻译员”。
21.IPV6和IPV4的区别
IP地址数量不同。
IPv4的地址是32位,采用A、B、C三类编址方式
而IPv6的地址是128位的。IPv6具有更大的地址空间,
- A类
地址范围从1.0.0.1——127.255.255.254 ,
子网掩码为255.0.0.0,适用大型网络,A类网络地址数量较少,有126个网络 - B类
地址范围从128.0.0.1——191.255.255.254,
子网掩码为255.255.0.0,适用中型网络,B类网络地址数量适中,有16384个网络 - C类
地址范围从192.0.0.1——223.255.255.254,
子网掩码为255.255.255.0,适用小型网络,C类网络地址数量较多,有209万余个网络
22.IP 协议(网络层)
即互联网协议,是支持网间互联的数据报协议。该协议工作在网络层,
主要目的:为了提高网络的可扩展性,和传输层 TCP 相比,IP 协议提供一种无连接/不可靠、尽力而为的数据包传输服务,其与TCP协议(传输控制协议)一起构成TCP/IP 协议族的核心。
IP 协议主要有以下几个作用:
- 寻址和路由:在IP 数据报中会携带源 IP 地址和目的 IP 地址,来标识该数据报的源主机和目的主机。IP 数据报在传输过程中,每个中间节点(IP 网关、路由器)只根据网络地址进行转发,如果中间节点是路由器,则路由器会根据路由表选择合适的路径。IP 协议根据路由选择协议提供的路由信息对 IP 数据报进行转发,直至抵达目的主机。
- 分段与重组:IP 数据包在传输过程中可能会经过不同的网络,在不同的网络中数据报的最大长度限制是不同的,IP 协议通过给每个 IP 数据包分配一个标识符以及分段与组装的相关信息,使得数据包在不同的网络中能够传输,被分段后的 IP 数据报可以独立地在网络中进行转发,在到达目的主机后由目的主机完成重组工作,恢复出原来的 IP 数据包。
23.MAC地址和IP地址(数据链路层)
- MAC 地址是数据链路层和物理层使用的地址,是写在网卡上的物理地址。用来定义网络设备的位置。
- IP 地址是网络层和以上各层使用的地址,是一种逻辑地址。IP 地址用来区别网络上的计算机。
四、c++
1.面向对象三大特性
面向对象:对象是指具体的某一个事物,这些事物的抽象就是类,类中包含数据(成员变量)和动作(成员方法)。
- 封装:
将具体的实现过程和数据封装成一个类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏,例如将公共的数据或方法使用public修饰,而不希望被访问的数据或
方法采用private修饰。 - 继承:
指可以让某个类型的对象获得另一个类型的对象的属性的方法。子类继承父类的特征和行为,子类有父类的非 private 方法或成员变量,子类可以对父类的方法进行重写,增强了类之间的耦合性,但是当父类中的成员变量、成员函数或者类本身被 final关键字修饰时,修饰的类不能继承,修饰的成员不能重写或修改。 - 多态:
多态就是不同继承类的对象,对同一消息做出不同的响应,同一个函数,在调用父类对象和子类对象的时候会产生不同的行为。(重载实现编译时多态,虚函数实现运行时多态)。
2.多态如何实现,为什么用多态
- 实现方法:
在基类的函数前加上 virtual 关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。 - 实现过程:
(1)编译器在发现基类中有虚函数时,会自动为每个含有虚函数的类生成一份虚表,该表是一个一维数组,虚表里保存了虚函数的入口地址
(2)编译器会在每个对象的前四个字节中保存一个虚表指针,指向对象所属类的虚表。在构造时,根据对象的类型去初始化虚指针vptr,从而让vptr指向正确的虚表,从而在调用虚函数时,能找到正确的函数;
(3)在派生类定义对象时,程序运行会自动调用构造函数,在构造函数中创建虚表并对虚表初始化。在构造子类对象时,会先调用父类的构造函数,此时,编译器只“看到了”父类,并为父类对象初始化虚表指针,令它指向父类的虚表;当调用子类的构造函数时,为子类对象初始化虚表指针,令它指向子类的虚表
(4)当派生类对基类的虚函数没有重写时,派生类的虚表指针指向的是基类的虚表;当派生类对基类的虚函数重写时,派生类的虚表指针指向的是自身的虚表;当派生类中有自己的虚函数时,在自己的虚表中将此虚函数地址添加在后面
(5)这样指向派生类的基类指针在运行时,就可以根据派生类对虚函数重写情况动态的进行调用,从而实现多态性。 - 虚表:虚函数表的缩写,类中含有virtual关键字修饰的方法时,编译器会自动生成虚表
虚表指针:在含有虚函数的类实例化对象时,对象地址的前四个字节存储的指向虚表的指针 - 多态的种类和表现形式?
静态多态(编译器多态):重载
动态多态(运行时多态):多态
为什么用多态:
1.代码重用: 封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);
2. 提高程序的可复用性:应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。
3. 提高可扩充性和可维护性: 派生类的功能可以被基类的方法或引用变量所调用,可以解决项目中紧偶合的问题。
4. 【 耦合度讲的是模块与模块之间,代码与代码之间的关联度,通过对系统的分析把他分解成一个一个子模块,子模块提供稳定的接口,达到降低系统耦合度的目的,模块与模块之间尽量使用模块接口访问,而不是随意引用其他模块的成员变量。】
3.深copy浅copy
- 浅拷贝是增加了一个指针,指向原来已经存在的内存。
- 而深拷贝是增加了一个指针,并新开辟了一块空间让指针指向这块新开辟的空间。浅拷贝在多个对象指向一块空间的时候,释放一个空间会导致其他对象所使用的空间也被释放了,再次释放便会出现错误。
4.哈希表及其原理
Hash 表即散列表,是通过关键字(key)根据哈希算法计算出应该存储地址的位置。其最突出的优点是查找和插入删除是O(1),最坏的就是hash值全都映射在同一个地址上,这样哈希表就会退化成链表。
实现原理:
- 把 Key 通过哈希函数转换成一个整型数字,然后将这份数字对数组长度进行取余,取余结果就当作数组的下标,将value 存储在以该数字为下标的数组空间里。
- 当使用哈希表进行查询的时候,就是再次使用哈希函数将 key 转换为对应的数组下标,并定位到该空间获取 value;
常见的哈希算法
哈希表的组成取决于哈希算法,也就是哈希函数的构成,下面列举几种常见的哈希算法。
- 直接定址法
取关键字或关键字的某个线性函数值为散列地址。
即 f(key) = key 或 f(key) = a*key + b,其中a和b为常数。 - 除留余数法
取关键字被某个不大于散列表长度 m 的数 p 求余,得到的作为散列地址。
即 f(key) = key % p, p < m。这是最为常见的一种哈希算法。 - 数字分析法
当关键字的位数大于地址的位数,对关键字的各位分布进行分析,选出分布均匀的任意几位作为散列地址。
仅适用于所有关键字都已知的情况下,根据实际应用确定要选取的部分,尽量避免发生冲突。 - 平方取中法
先计算出关键字值的平方,然后取平方值中间几位作为散列地址。
随机分布的关键字,得到的散列地址也是随机分布的。 - 随机数法
选择一个随机函数,把关键字的随机函数值作为它的哈希值。
通常当关键字的长度不等时用这种方法。
哈希hash冲突
哈希冲突是指哈希函数算出来的地址被别的元素占用了
key1 ≠ key2 , f(key1) = f(key2)
一般来说,哈希冲突是无法避免的,如果要完全避免的话,也就是一个值就有一个索引,这样一来,空间就会增大,甚至内存溢出。
解决办法:
- 线性探测
使用hash函数计算出的位置如果已经有元素占用了,则向后依次寻找,找到表尾则回到表头,直到找到一个空位 - 开链
每个表格维护一个链表list,如果hash函数计算出的格子相同,则按顺序存在这个list中 - 再散列
发生冲突时使用另一种hash函数再计算一个地址,直到不冲突 - 二次探测
使用hash函数计算出的位置如果已经有元素占用了,按照 1 2 1^2 12、 2 2 2^2 22、 3 2 3^2 32…的步长依次寻找,如果步长是随机数序列,则称之为伪随机探测 - 公共溢出区
一旦hash函数计算的结果相同,就放入公共溢出区
5.常用数据结构
有链表、栈、队列、树
- 链表
是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列节点组成,这些节点不必在内存中相连。每个节点由 数据部分 Data 和链部分 Next,Next 指向下一个节点,这样当添加或者删除时,只需要改变相关 节点的 Next 的指向,效率很高
6.二叉查找树、红黑树
二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”;
平衡二叉树(AVL树)在符合二叉查找树(左子树的键值小于根的键值,右子树的键值大于根的键值)的条件下,还满足任何节点的两个子树的高度最大差为1;
二叉查找树(中序遍历,时间O(n))
在树中的任意一个节点,其左子树中的每个节点的值,都要小于这个节点的值,而右子树节点的值都要大于这个节点的值。
- 查找
首先取根节点,如果它等于要查找的数据,则直接返回,如果小于要查找的数据,则在右子树中继续查找,如果大于要查找的数据,则在左子树中继续查找,也就是二分查找的思想,这样一直递归。 - 插入
首先还是从根节点开始,然后依次它与节点的关系。如果要插入的数据比节点的数据大,并且节点的右子树为空,就将新数据直接插到右子节点的位置;如果不为空,就再递归遍历右子树,查找插入位置。同理,如果要插入的数据比节点的数据小,也是类似的操作。 - 删除
如果要删除的节点没有子节点,只需要将父节点中,指向要删除节点的指针置为NULL,
如果要删除的节点只有一个子节点(只有左子节点或者右子节点),只需要删除父节点中,指向要删除的指针,让它指向要删除的节点的子节点就可以了。
如果要删除的节点上有两个子节点,要稍微复杂一点。首先找到这个节点的右子树中最小的节点,把它替换到要删除的节点,然后再删除这个最小节点。因为最小节点肯定没有左子节点。
红黑树
红黑树是一个近似平衡的二叉树,
7. 定义:
具有二叉查找树的特点;根节点是黑色的
每个叶子节点都是黑色的空节点(NIL),也就是说,叶子节点不存数据
任何相邻的节点都不能同时为红色,也就是说,红色节点是被黑色节点隔开的
每个节点,从该节点到达其可达的叶子节点是所有路径,都包含相同数目的黑色节点
7.STL常用容器
C++ STL从广义来讲包括了三类:算法,容器和迭代器。
算法包括排序,复制等常用算法,以及不同容器特定的算法。
容器就是数据的存放形式,包括序列式容器和关联式容器,序列式容器就是list,vector等,关联式容器就是set,map等。
迭代器就是在不暴露容器内部结构的情况下对容器的遍历。
顺序容器:
3. vector
是一种动态数组,具有连续的存储空间,支持快速随机访问。但在插入和删除操作方面,效率比较慢。
底层:
底层结构为数组,由于数组的特点,vector也具有以下特性:
1)、O(1)时间的快速访问;
2)、顺序存储,所以插入到非尾结点位置所需时间复杂度为O(n),删除也一样;
3)、扩容规则:
当我们新建一个vector的时候,会首先分配给他一片连续的内存空间,如std::vector vec,当通过push_back向其中增加元素时,如果初始分配空间已满,就会引起vector扩容,其扩容规则在gcc下以2倍方式完成:
首先重新申请一个2倍大的内存空间;
然后将原空间的内容拷贝过来;
最后将原空间内容进行释放,将内存交还给操作系统;
4. deque
和 vector 类似,支持快速随机访问。二者最大的区别在于,vector 只能在末端插入 数据,而 deque 支持双端插入数据。deque 空间的重新分配要比 vector 快,重新分配空间后,原有的元素是不需要拷贝的。
底层:
底层数据结构为一个中央控制器(map)和多个缓冲区,支持首位(中间不能)快速增删,也支持也随访问,deque 的内存空间分布是小片的连续,小片间用链表相连。中控器(map保存着一组指针,每个指针指向一段数据空间的起始位置,通过中控器可以找到所有的数据空间。如果中控器的数据空间满了,会重新申请一块更大的空间,并将中控器的所有指针拷贝到新空间中。
1.start迭代器:绑定到第一个有效的map结点和该结点对应的缓冲区。
2.finish迭代器:绑定到最后一个有效的map结点和该结点对应的缓冲区。
5. list
是一个双向链表,它的内存空间可以不连续,通过指针来进行数据的访问,导致其随机存储非常低效;但 list 可以很好地支持任意地方的插入和删除,只需移动相应的指针即可
底层:双向链表
关联容器:
- map && multimap
是一种关联性容器,该容器用唯一的关键字来映射相应的值,即具有 key-value 功能。map 内部自建一棵红黑树(一种自平衡二叉树),这棵树具有数据自动排序的功能,内部数据都是有序的。
map与multimap的区别在于,multimap允许关键字重复,而map不允许重复。
底层:
根据红黑树的原理,map与multimap可以实现O(lgn)的查找,插入和删除 - unordered_map 与unordered_multimap
无序排序,低层是哈希表,因此其查找时间复杂度理论上达到了O(n) - set & multiset
是一种关联性容器,set系与map系的区别在于map中存储的是,而set可以理解为关键字即值,即只保存关键字的容器。
低层:
底层使用红黑树实现,插入删除操作时仅仅移动指针即可,不涉及内存的移动和拷贝,所以效率比较高。set 中的元素都是唯一的,而且默认情 况下会对元素进行升序排列。所以在 set 中,要改变元素值必须先删除旧元素,再插入新元素。不提供直接存取元素的任何操作函数, 只能通过迭代器进行间接存取 - queue
是一个队列,实现先进先出功能,queue 不是标准的 STL 容器,却以标准的 STL 容器为基础。(stack和queue其实是适配器,而不叫容器,因为是对容器的再封装)
底层:
queue 是在 deque 的基础上封装的。 - stack
实现先进后出的功能,和 queue 一样,也是内部封装了 deque。 - priority_queue:
底层数据结构一般为vector为底层容器,堆heap为处理规则来管理底层容器实现。
8. 迭代器失效
- vector迭代器失效
(1)当执行erase方法时,指向删除节点的迭代器全部失效,指向删除节点之后的全部迭代器也失效
(2)当进行push_back()方法时,end操作返回的迭代器肯定失效。
(3)当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。
(4)当插入(push_back)一个元素后,如果空间未重新分配,指向插入位置之前的元素的迭代器仍然有效,但指向插入位置之后元素的迭代器全部失效。 - deque迭代器
(1)对于deque,插入到除首尾位置之外的任何位置都会导致迭代器、指针和引用都会失效,但是如果在首尾位置添加元素,迭代器会失效,但是指针和引用不会失效
(2)如果在首尾之外的任何位置删除元素,那么指向被删除元素外其他元素的迭代器全部失效
(3)在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。 - map
对于map,当进行erase操作后,只会使当前迭代器失效,不会造成其他迭代器失效,这是因为map底层实现是由红黑树实现的,所以当删除一个元素时,会进行二叉树的调整,但每个节点在内存中的地址是没有改变的,改变的只是他们之间的指针指向。
9.为什么要有迭代器,不是有指针吗?
Iterator(迭代器)模式是运用于聚合对象的一种模式,通过运用该模式,使得我们可以在不知道对象内部表示的情况下,按照一定顺序(由iterator提供的 方法)访问聚合对象中的各个元素。迭代器不是指针,是类模板,表现的像指针,提供了比指针更高级的行为,相当于一种智能指针,他可以根据不同类型的数据结构来实现不同的++,–等操作。
五、操作系统
1.线程资源共享与不共享
- 堆 由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的
- 全局变量 它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的
- 静态变量 虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的
- 文件等公用资源 这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。
独享的资源有
- 栈 栈是独享的
- 寄存器 因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC
2.进程间通信
目的:
数据传输:一个进程需要将它的数据发送给另一个进程。
资源共享:多个进程之间共享同样的资源。
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。
- 管道:
一个进程通过调用管程的一个过程进入管程。在任何时候,只能有一个进程在管程中执行,调用管程的任何其他进程都被阻塞,以等待管程可用。
(1)无名管道(内存文件):是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程之间使用。进程的亲缘关系通常是指父子进程关系。
(2)有名管道(FIFO文件,借助文件系统):也是半双工的通信方式,但是允许在没有亲缘关系的进程之间使用,先进先出的通信方式。 - 共享内存:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。
- 消息队列:消息队列是有消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号:传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
- 套接字socket:适用于不同机器间进程通信,在本地也可作为两个进程通信的方式。
- 信号:用于通知接收进程某个事件已经发生,比如按下ctrl + C就是信号。
- 信号量:是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,实 现进程、线程的对临界区的同步及互斥访问。
3.线程间通信
线程间的同步方式包括互斥锁、信号量、条件变量、读写锁:
4.了解的锁机制?(线程同步)
互斥锁:mutex,保证在任何时刻,都只有一个线程访问该资源,当获取锁操作失败时,线程进入阻塞,等待锁释放。
读写锁:rwlock,分为读锁和写锁,处于读操作时,可以运行多个线程同时读。但写时同一时刻只能有一个线程获得写锁。
互斥锁和读写锁的区别:
(a)读写锁区分读锁和写锁,而互斥锁不区分
(b)互斥锁同一时间只允许一个线程访问,无论读写;读写锁同一时间只允许一个线程写,但可以多个线程同时读。
3. 自旋锁:spinlock,在任何时刻只能有一个线程访问资源。但获取锁操作失败时,不会进入睡眠,而是原地自旋,直到锁被释放。这样节省了线程从睡眠到被唤醒的时间消耗,提高效率。
4. 条件锁:就是所谓的条件变量,某一个线程因为某个条件未满足时可以使用条件变量使该程序处于阻塞状态。一旦条件满足了,即可唤醒该线程(常和互斥锁配合使用)
5. 信号量:计数器,允许多个线程同时访问同一个资源。
5.讲一下死锁
如果一组进程中的每个进程都在等待一个事件,而这个事件只能由该组的另一个进程触发,这种情况会导致死锁。可以理解为:死锁就是两个线程同时占用两个资源,但又在彼此等待对方释放锁。比如两只羊过独木桥。进程比作羊,资源比作桥。若两只羊互不相让,争着过桥,就产生死锁。
产生条件:
1.互斥条件:进程对所需求的资源具有排他性,若有其他进程请求该资源,请求进程只能等待。
2.不剥夺条件:进程在所获得的资源未释放前,不能被其他进程强行夺走,只能自己释放。
3.请求和保持条件:进程当前所拥有的资源在进程请求其他新资源时,由该进程继续占有。
4.循环等待条件:存在一种进程资源循环等待链,链中每个进程已获得的资源同时被链中下一个进程所 请求。
数据库死锁:
常见的解决死锁的方法
1、如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会。
2、在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
3、对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;
6.虚拟内存
虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存 (一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换
7.大文件传输
- 基于socket
由于socket本身缓冲区的限制,大概一次只能发送4K左右的数据,所以在传输大数据时客户端就需要进行分包,在目的地重新组包。 - 使用现有的通讯中间件
- 基于共享文件、ftp(文件传输协议)、scp等
ftp:使用 TCP 传输
scp
用于在Linux下进行远程拷贝文件的命令,scp传输是加密的
scp 被复制目标 复制存储的目录
7.查看IP、GPU、显卡
- 查看ip:输入ifconfig -a,然后回车
- 查看显卡信息: lspci | grep -i vga
- 查看GPU使用情况:nvidia-smi
8.查看cpu、内存、磁盘(IO)使用率(top命令)
- 查看内存:free (总内存、使用、空闲)
- free -g # 以 G 为单位显示内存使用状况
- 查看磁盘使用率:df
- io状态查询:iostat -d -k 2
参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;2表示,数据显示每隔2秒刷新一次。
9.查看进程状态(PS命令)
用来查看当前运行的进程状态,一次性查看,如果需要动态连续结果使用 top
- 进程的状态
运行(正在运行或在运行队列中等待)
中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号)
不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)
僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放)
停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行) - 工具标识进程的5种状态码:
D 不可中断 uninterruptible sleep (usually IO)
R 运行 runnable (on run queue)
S 中断 sleeping
T 停止 traced or stopped
Z 僵死 a defunct (”zombie”) process - 命令参数:
-A 显示所有进程
-a 显示现行终端机下的所有程序,包括其他用户的程序
c 显示进程真实名称
e 显示环境变量
f 显示进程间的关系
r 显示当前终端运行的进程
-aux 显示所有包含其它使用的进程
1.显示当前所有进程环境变量及进程间关系
ps -ef
2.显示当前所有进程
ps -A
3.与grep联用查找某进程
ps -aux | grep apache
4.找出与 cron 与 syslog 这两个服务有关的 PID 号码
ps aux | grep ‘(cron|syslog)’
10.grep命令(文本搜索)
强大的文本搜索命令
//参数
-A n --after-context显示匹配字符后n行
-B n --before-context显示匹配字符前n行
-C n --context 显示匹配字符前后n行
-c --count 计算符合样式的列数
-i 忽略大小写
-l 只列出文件内容符合指定的样式的文件名称
-f 从文件中读取关键词
-n 显示匹配内容的所在文件中行数
-R 递归查找文件夹
//grep 的规则表达式:
^ #锚定行的开始 如:’^grep’匹配所有以grep开头的行。
$ #锚定行的结束,如:‘grep$‘匹配所有以grep结尾的行。
. 匹配一个非换行符的字符 如:‘gr.p’匹配gr后接一个任意字符,然后是p。
[] #匹配一个指定范围内的字符,如’[Gg]rep’匹配Grep和grep。
[^] #匹配一个不在指定范围内的字符,如:’[^A-FH-Z]rep’匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。
(…) #标记匹配字符,如’(love)’,love被标记为1。
< #锚定单词的开始,如:’<grep’匹配包含以grep开头的单词的行。
> #锚定单词的结束,如’grep>'匹配包含以grep结尾的单词的行。
x{m} #重复字符x,m次,如:'0{5}'匹配包含5个o的行。
x{m,} #重复字符x,至少m次,如:'o{5,}'匹配至少有5个o的行。
x{m,n} #重复字符x,至少m次,不多于n次,如:'o{5,10}'匹配5–10个o的行。
\w #匹配文字和数字字符,也就是[A-Za-z0-9],如:'G\w*p’匹配以G后跟零个或多个文字或数字字符,然后是p。
\W #\w的反置形式,匹配一个或多个非单词字符,如点号句号等。
\b #单词锁定符,如: '\bgrep\b’只匹配grep。
//查找指定进程
ps -ef | grep svn
//查找指定进程个数
ps -ef | grep svn -c
//从文件中读取关键词
cat test1.txt | grep -f key.log
//显示包含 ed 或者 at 字符的内容行
grep -E ‘ed|at’ test.txt
11.搜索文件(find)
find [path][options][expression]path
12.linux更改用户权限
chmod +/-rwx 文件名|目录名
六、数据库
1.平衡二叉树、B树和B+树是什么,区别
- 二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”;
- 平衡二叉树(AVL树)在符合二叉查找树(左子树的键值小于根的键值,右子树的键值大于根的键值)的条件下,还满足任何节点的两个子树的高度最大差为1;
- B树:就是为了存储设备或者磁盘设计的一种平衡查找树
1)树中的每个节点最多有m个孩子
2)除了根节点和叶子节点外,其他节点最少含有m/2(取上限)个孩子
3)若根节点不是叶子节点,则根节点最少含有两个孩子
4)所以叶子节点都在同一层,叶子节点不包含任何关键字信息
B树的插入
1)若B树中已存在需要插入的键值时,用新的键值替换旧值;
2)若B树中不存在这个值,则在叶子节点进行插入操作; - B+树
B树的一种变形,它把数据都存储在叶子节点,内部只存关键字(其中叶子节点的最小值作为索引)和孩子指针,简化了内部节点。
B+树插入
B+树插入:
1)若为空树直接插入
2)对于叶子结点:根据key找到叶子结点,对叶子结点进行插入操作。插入后如果当前叶子结点的key值数b不大于m-1,则插入结束
3)对于索引结点:如果当前结点的key个数小于等于m-1,插入结束。
3.区别
为什么B+树比B树更适合做系统的数据库索引和文件索引
1)B+树的磁盘读写代价更低
因为B+树内部结点没有指向关键字具体信息的指针,内部结点相对B树小
2)B+树的查询更加稳定
因为非终端结点并不是指向文件内容的结点,仅仅是作为叶子结点的关键字索引,因此所有的关键字查询都会走一条从根节点到叶子结点的路径。即s所有关键字查询的长度是一样的,查询效率稳定。
既然Hash比B+树更快,为什么MySQL用B+树来存储索引呢?
MySQL中存储索引用到的数据结构是B+树,B+树的查询时间跟树的高度有关,是log(n),如果用hash存储,那么查询时间是O(1)。
采用Hash来存储确实要更快,但是采用B+树来存储索引的原因主要有以下两点:
一、从内存角度上说,数据库中的索引一般是在磁盘上,数据量大的情况可能无法一次性装入内存,B+树的设计可以允许数据分批加载。
二、从业务场景上说,如果只选择一个数据那确实是hash更快,但是数据库中经常会选中多条,这时候由于B+树索引有序,并且又有链表相连,它的查询效率比hash就快很多了
2.并发问题(脏读、幻读、丢弃更改、不可重复读)
- 脏读:读脏数据指在不同的事务下,当前事务可以读到另外事务未提交的数据。例如:T1修改一个数据但未提交,T2随后读取这个数据。如果T1撤销了这次修改,那么T2读取的数据是脏数据。
- 幻读:幻读本质上也属于不可重复读的情况,T1读取某个范围的数据,T2在这个范围内插入新的数据,T1再次读取这个范围的数据,此时读取的结果和第一次读取的结果不同。
- 丢弃修改:指一个事务的更新操作被另外一个事务的更新操作替换。例如:T1和 T2两个事务都对一个数据进行修改,T1先修改并提交生效,T2随后修改,T2的修改覆盖了T1的修改。
- 不可重复读:在这一事务还未结束前,另一事务也访问了该同一数据集合并做了修改,由于第二个事务的修改,第一次事务的两次读取的数据可能不一致。
3.隔离级别
- 未提交读:事务中的修改,即使没有提交,对其它事务也是可见的。(可能导致脏读、幻读和不可重复读)
- 提交读:一个事务只能读取已经提交的事务所做的修改。(可以阻止脏读)
- 可重复读:保证在同一个事务中多次读取同一数据的结果是一样的。(可以阻止脏读、不可重复度)
- 可串行化:强制事务串行执行,这样多个事务互不干扰,不会出现并发一致性问题。该隔离级别需要加锁加粗样式实现,因为要使用加锁机制保证同一时间只有一个事务执行,也就是保证事务串行执行。(可以阻止脏读、幻读和不可重复读)
4.什么是索引,作用、优点,有哪些
- 索引是数据库管理系统中一个排序的数据结构索引就相当于目录,实现通常使用B树及其变种B+树。
- 优点
可以大大加快数据的检索速度,这也是创建索引的最主要的原因。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
缺点
创建索引和维护索引要耗费时间,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会降低增/改/删的执行效率;
索引需要占物理空间 - 主键索引: 数据列不允许重复,不允许为NULL,一个表只能有一个主键。
唯一索引: 数据列不允许重复,允许为NULL值,一个表允许多个列创建唯一索引。
普通索引: 基本的索引类型,没有唯一性的限制,允许为NULL值。
SELECT 查询列表 7
FROM 表 1 1
【连接类型】 JOIN 表 2 3
ON 连接条件 2
WHERE 筛选条件 4
GROUP BY 分组列表 5
HAVING 分组后的筛选条件 6
ORDER BY 排序的字段 8
LIMIT 起始的条目索引,条目数; 9
5.数据库分类
- 网络数据库
网络数据库是指把数据库技术引入到计算机网络系统中,借助于网络技术将存储于数据库中的大量信息及时发布出去,而计算机网络借助于成熟的数据库技术对网络中的各种数据进行有效管理,并实现用户与网络中的数据库进行实时动态数据交互。 - 层级数据库
层次结构模型实质上是一种有根节点的定向有序树(在数学中“树”被定义为一个无回的连通图)。 - 关系数据库
关系数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据
6.悲观锁、乐观锁
- 悲观锁:就是一种悲观心态的锁,每次访问数据时都会锁定数据
- 乐观锁:一种乐观心态的锁,每次访问数据时并不锁定数据,期待数据并没作修改,如果数据没被修改则作具体的业务。
- 适用场景:
1.响应速度:如果需要非常高的响应速度,建议采用乐观锁方案,成功就执行,不成功就失败,不需要等待其他并发去释放锁
2.冲突频率:如果冲突频率非常高,建议采用悲观锁,保证成功率,如果冲突频率大,乐观锁会需要多次重试才能成功,代价比较大
3.重试代价:如果重试代价大,建议采用悲观锁
7.请你说一下数据库事务、主键与外键的区别?
数据库的事务:事务即用户定义的一个数据库操作序列,这些操作要么全做要全不做,是一 个不可分割的工作单位,它具有四个特性,ACID,原子性,一致性,隔离性,持续性
主键和外键的区别:
- 主键是能确定一条记录的唯一标识,比如,一条记录包括身份正号,姓名,年龄。 身份证号是唯一能确定你这个人的,其他都可能有重复,所以,身份证号是主键。
- 外键用于与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。
8.数据库如何优化
- 调整数据结构的设计,对于经常访问的数据库表建立索引
- 调整 SQL 语句, 可以使用一些语句优化器、行锁管理器(来调整优化 SQL 语句。 减少数据访问
比如:不要使用BY RAND()命令,尽量避免SELECT *命令 - 调整服务器内存分配。是在运行过程中优化配置的,数据库管理员可以根据数据库运行状况调整数据库系统全局区(SGA 区)的数据缓冲区、日志缓冲区和共享池的大小;还可以调整程序全局区(PGA 区)的大小。
- 调整硬盘I/O,DBA 可以将组成同一个表空间的数据文件放在不同的硬盘上,做到硬 盘之间I/O负载均衡。
9.索引失效
- 如果条件中有or,即使其中有条件带索引也不会使用 (这也是为什么尽量少用or的原因)
- like查询是以%开头
- 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
- 对于多列索引,不是使用的第一部分,则不会使用索引
10.联合索引
联合索引是什么
对多个字段同时建立的索引(有顺序,ABC,ACB是完全不同的两种联合索引。)
为什么要使用联合索引
- 减少开销。
建一个联合索引(col1,col2,col3),实际相当于建了(col1),(col1,col2),(col1,col2,col3)三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销! - 覆盖索引
在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。 - 效率高。
索引列越多,通过索引筛选出的数据越少。有1000W条数据的表,有如下sql:select from table where col1=1 and col2=2 and col3=3,假设假设每个条件可以筛选出10%的数据,如果只有单值索引,那么通过该索引能筛选出1000W10%=100w条数据,然后再回表从100w条数据中找到符合col2=2 and col3= 3的数据,然后再排序,再分页;如果是联合索引,通过索引筛选出1000w10% 10% *10%=1w,效率提升可想而知
11.SQL中有哪些索引
- 普通索引:仅加速查询
- 唯一索引:加速查询 + 列值唯一(可以有null)
- 主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个
- 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
- 全文索引:对文本的内容进行分词,进行搜索
- 索引合并:使用多个单列索引组合搜索
- 覆盖索引:select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖
- 聚簇索引:表数据是和主键一起存储的,主键索引的叶结点存储行数据(包含了主键值),二级索引的叶结点存储行的主键值。使用的是B+树作为索引的存储结构,非叶子节点都是索引关键字,但非叶子节点中的关键字中不存储对应记录的具体内容或内容地址。叶子节点上的数据是主键与具体记录(数据内容)
-
20. 某一地区普遍反映卡顿
1、数据库问题,压力过大,如慢查询过多导致,某个查询吃完了内存,数据库并发量大 都有可能
2、web服务器CPU高,很多线程被锁,很多线程在等待IO或者其他服务响应
3、网络宽带原因
21.访问网址慢
- 本地网络原因,比如网络宽度被占用
- 网站服务器原因,可以通过 ping 命令查看链接到服务器的时间和丢包等情况(一个速度好的机房,首先丢包率不能超过 1%,其次 ping 值要小,最后是 ping 值要稳定,如最大和最小差值过大说明路由不稳定。
- 空间不稳定原因,表现为网速时快时慢,找网络空间商,有些地方慢有些地方快可能是网络线路问题,比如电信用户访问联通服务器。
- 网址本身设计原因,比如大尺寸图片和flash过多
22.视频直播卡顿
更多推荐
测试基础-面试
发布评论