软件测试及自动化测试

软件测试面经

文章目录

软件测试理论

1.GET和POST请求区别

1、GET使用URL或Cookie传参,而POST将数据放在BODY中。
2、GET的URL会有长度上的限制,则POST的数据则可以非常大。
3、POST比GET安全,因为数据在地址栏上不可见。
4、一般get请求用来获取数据,post请求用来发送数据。
5、get幂等,post不幂等(从服务器上获取资源)幂等表示执行相同的操作,结果也是相同的

2.web service的接口如何测试

它不需要你在拼报文了,会给一个webservice的地址,或者wsdl文件,直接在soapui导入,就可以看到这个webservice里面的所有接口,也有报文,直接填入参数调用,看返回结果就可以了。

3.cookie,session与Token的区别

1、cookie数据存放在客户的浏览器上,session数据放在服务器上。

2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗考虑到安全应当使用 session。

3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。

4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

将登录信息等重要信息存放为session
其他信息如果需要保留,可以放在cookie中

token:访问权限,保存在客户端本地
鉴权:访问的接口是否正常,是否非法访问绕过前端。 防止跳过页面直接访问接口token
授权:是否具有访问接口的权限。 唯一全局动态的 。

4.接口测试该怎么测

1)、通用接口用例设计

①、通过性验证:首先肯定要保证这个接口功能是好使的,也就是正常的通过性测试,按照接口文档上的参数,正常传入,是否可以返回正确的结果。

②、参数组合:现在有一个操作商品的接口,有个字段type,传1的时候代表修改商品,商品id、商品名称、价格有一个是必传的,type传2的时候是删除商品,商品id  是必传的,这样的,就要测参数组合了,type传1的时候,只传商品名称能不能修改成功,id、名称、价格都传的时候能不能修改成功。
③、接口安全:

1、绕过验证,比如说购买了一个商品,它的价格是300元,那我在提交订单时候,我把这个商品的价格改成3元,后端有没有做验证,更狠点,我把钱改成-3,是不是我的余额还要增加?

2、绕过身份授权,比如说修改商品信息接口,那必须得是卖家才能修改,那我传一个普通用户,能不能修改成功,我传一个其他的卖家能不能修改成功

3、参数是否加密,比如说我登陆的接口,用户名和密码是不是加密,如果不加密的话,别人拦截到你的请求,就能获取到你的信息了,加密规则是否容易破解。

4、密码安全规则,
2)、根据业务逻辑来设计用例
具体的看自己公司的业务了

5、异常验证:

所谓异常验证,也就是我不按照你接口文档上的要求输入参数,来验证接口对异常情况的校验。

5.postman和jemter的区别

1.Postman比较适合手工接口测试,因为简单,同时它能够实现半自动化。

2.JMeter比较适合自动化接口测试,因为功能强大并且可以保存脚本,批量执行设置很容易。

3.Postman一般用来做接口测试,用来发现Bug,验证后台程序。

4.JMeter一般用来做自动化测试,做冒烟测试。

6.在浏览器中输入 URL 地址到显示主页的过程

1.DNS(域名)解析:浏览器查询DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系统的DNS缓存、读取本地的Host文件和向本地DNS服务器进行查询等。对于向本地DNS服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;

2.TCP连接:浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;

3.发送HTTP请求:TCP连接建立起来后,浏览器向服务器发送 HTTP请求;

4.服务器处理请求并返回HTTP报文:服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;

5.浏览器解析渲染页面:浏览器解析并渲染视图,若遇到对js文件、css 文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。

6.连接结束。

7.冒烟测试

冒烟测试是在版本转测试之前,先选择一部分基础的测试用例进行验证,确保全流程没有严重、阻塞性的问题。有些也将其称为高压线测试。

冒烟测试就是完成一个新版本的开发后,对该版本最基本的功能进行测试,保证基本的功能和流程能走通。如果不通过,则打回开发那边重新开发;如果通过测试,才会进行下一步的测试(功能测试,集成测试,系统测试等等)。

8.请你分别介绍一下单元测试、集成测试、系统测试、验收测试、回归测试

单元测试:完成最小的软件设计单元(模块)的验证工作,目标是确保模块被正确的编码

集成测试:通过测试发现与模块接口有关的问题

系统测试:是基于系统整体需求说明书的黑盒类测试,应覆盖系统所有联合的部件

回归测试:回归测试是指在发生修改之后重新测试先前的测试用例以保证修改的正确性

验收测试:这时相关的用户或独立测试人员根据测试计划和结果对系统进行测试和接收。验收测试包括Alpha测试和Beta测试。

Alpha测试:是由用户在开发者的场所来进行的,在一个受控的环境中进行。并且在开发者对用户的指导下进行测试,开发者负责记录发现的错误和使用中遇到的问题
Beta测试 :由软件的最终用户在一个或多个用户场所来进行的,开发者通常不在现场。由用户记录在测试中遇到的一系列问题,并定期报给开发者。(内测)

36.集成测试和系统测试,并且Bug定位属于什么测试。

1.集成测试:针对模块接口有关问题,对已经进行了单元测试的模块拿来构造一个满足设计的程序结构,采用增量集成。有自顶向下和自底向上集成。
2.系统测试:根据系统整体需求说明书进行黑盒测试。验证产品系统是否符合需求规格。包括软件、硬件、数据、接口测试。在系统实际运行环境中进行。
区别:先做集成测试,等问题修复后再做系统测试。集成测试用例比系统测试更详细。
应用场景:集成测试程序内部结构特别是程序接口测试,白盒黑盒结合。系统测试按照需求规格说明书进行整个产品全面测试,一般是黑盒。
Bug定位应该属于单元测试吧,单元测试是最小设计单元验证,保证模块正确编码。

9.什么是黑盒?什么是白盒?黑盒和白盒的测试方法分别有哪些?

黑盒:黑盒测试也称功能测试或数据驱动测试。把程序看作一个不能打开的黑盆子,在完全不考虑程序内部结构和内部特性的情况下,对程序接口进行测试。“黑盒”法着眼于程序外部结构、不考虑内部逻辑结构、针对软件界面和软件功能进行测试。
常用的黑盒测试方法:等价类划分法;边界值分析法;因果图法;场景法;正交实验设计法;判定表驱动分析法;错误推测法;功能图分析法。

白盒测试:也称为结构测试或逻辑驱动测试,是针对被测单元内部是如何进行工作的测试
常用白盒测试方法:逻辑覆盖、循环覆盖、基本路径覆盖
静态测试:不用运行程序的测试;
动态测试:需要执行代码,通过运行程序找到问题;
逻辑覆盖包括:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖
1.语句覆盖每条语句至少执行一次。
2.判定覆盖每个判定的每个分支至少执行一次。
3.条件覆盖每个判定的每个条件应取到各种可能的值。
4.判定/条件覆盖同时满足判定覆盖条件覆盖。
5.条件组合覆盖每个判定中各条件的每一种组合至少出现一次。
6.路径覆盖使程序中每一条可能的路径至少执行一次。

10.测试流程

需求测试—>概要设计测试—>详细设计测试—>单元测试—>集成测试—>系统测试—>验收测试

11.软件开发流程。

1.需求分析 初步了解用户需求,列出开发系统的功能模块、界面,并且向用户确认
2.概要设计 对软件系统设计进行考虑,包括基本处理流程、系统组织、模块、接口等
3.详细设计 描述具体模块的主要算法、数据结构、类,子模块设计。
4.编码 根据《软件系统详细设计报告》的设计要求进行编写工作,实现模块功能。
5.测试 测试人员和用户
6.软件交付 测试达到要求后开发者向用户提交开发的目标安装程序,《用户安装手册》《用户使用指南》、需求报告、设计报告、测试报告等
7.验收 用户验收
8.维护 根据用户需求或者环境变化,对应用程序进行全部或者部分修改。

11.app测试性能指标

cpu 内存 流量 启动速度

12.web测试和app测试不同点

1.系统架构方面:
web项目,一般都是b/s架构,基于浏览器的
app项目,则是c/s的,必须要有客户端,用户需要安装客户端。
web测试只要更新了服务器端,客户端就会同步会更新。App项目则需要客户端和服务器都更新。

2.性能方面:
web页面主要会关注响应时间
app则还需要关心流量、电量、CPU、GPU、Memory等。

3.兼容方面:
web是基于浏览器的,所以更倾向于浏览器和电脑硬件,电脑系统方面的兼容
app测试则要看分辨率,屏幕尺寸,操作系统、网络。
web测试是基于浏览器的所以不必考虑安装卸载。
app是客户端的,则必须测试安装、更新、卸载。除了常规的安装、更新、卸载还要考虑到异常场景:包括安装时的中断、弱网、安装后删除安装文件 。

13.缺陷按优先级分为哪些类型? p1-p5

缺陷必须立即解决
缺陷要求正常排队等待修复
缺陷可以在方便时被纠正
下一个版本修复
不修复

14.测试用例的内容是什么?

1.用例编号 2.用例标题(测试概述) 3.测试步骤 4.预期结果 5.输入数据 6.优先级 7.前置条件等

15.测试结束的标准是什么?

1.全部测试用例都被执行完成
2.未修改bug都被确认或置为应有状态,暂缓修改的问题都有详尽的解析
3.测试报告编写完成
4.测试收尾工作结束
5.测试总结完成
6.项目处于试运行或上线阶段
在测试计划中定义结束的标准:在一定性能下平稳运行多少天、本版本没有严重bug,普通buh数量在多少个以下,bug修复百分之多少以上;实际测试达到上述要求,由项目、开发、测试经理共同签字,认同测试结束,版本即可发布。

16.测试工作中发现一个bug,而开发人员说不是一个bug,你该怎么处理?

说法一:

1、首先明确开发说不是bug的理由。

2、如果是需求变更, 那就找产品经理确认是否是需求变更。

3、如果开发说测试环境问题, 让他说明清楚测试环境问题是什么,按照他说的验证一遍, 如果确实如他所说, 关闭bug,但是不是他说的那样,继续激活bug给开发解决,确保产品质量。

4、如果开发说用户不存在这种使用场景, 但是我们不认可他说的,把这个bug 知会到测试经理,让测试经理去判定。

说法二:

1.告知开发bug的判断依据,同时明确开发说不是bug的理由。

2.对开发的理由进行校验,校验依据1.参照需求文档,2.跟产品经理进行沟通确认。

校验结果不是bug,关闭bug,如果是bug提交给开发进行处理,确保产品质量

17.软件生命周期及各类模型

生命周期:

从软件最初构思到最终消亡(退役)的过程。

大致:立项 ---需求分析 ----设计、编码、测试 ---发布 ---运行维护 ---淘汰

详细:软件立项--------可行性研究 ---------需求分析-------概要设计--------详细设计 ----编码实现 --------单元测试 --------集成测试--------系统测试 -------验收测试-------运行维护

1. 软件开发模型

  1. 瀑布模型(顺序)

缺点:
1. 各阶段划分完全固定,阶段之间产生大量文档,极大增加工作量
2. 由于开发模型是线性的,用户只有等到整个过程的末期才能看到开发结果,增加开发风险
3. 不适应用户需求变化

  1. 快速原型模型(现在特别流行模式) Axure 软件

  2. 原理:迅速搭建一个可以运行的软件原型,以便理解和澄清问题,使开发人员与用户达成共识,最后在确定需求基础上开发客户满意的软件产品

  3. 特点:适合预先不能确切定义需求的软件系统的开发

  4. 优点:克服瀑布模型缺点,减少由于软件需求不明确带来的开发风险

  5. 增量模型(最常用开发模型之一)
    分批次地分析、设计、编码和测试这些增量组件。

3.迭代模型 开发进度快

原理:
强调开发的深入 ---优化过程 开发迭代是一次完整地经过所有工作流程的过程:需求分析、设计、实施和测试工作流程
优点:
降低在一个增量上的开支风险
降低产品无法按照既定进度进入市场的风险
加快开发工作进度 适应需求变化快的场景

  1. 螺旋模型

  2. 原理:
    兼顾了快速模型的迭代的特征以及瀑布模型的系统化与严格监控

  3. 优点:
    最大特点:引入其他模型不具备的风险分析,使软件在无法排除重大风险时有机会停止,以减少损失
    适合大型昂贵的系统级的软件应用

软件测试模型

1.v模型

  1. 原理:揭示开发过程和测试过程中各阶段的对应关系
  2. 缺点与不足:
    仅把测试过程作为需求分析、系统设计及编码之后的一个阶段,忽略了测试对需求分析、系统设计的验证
    需求的满足情况一直到后期验收测试才被验证
    没有体现出“尽早和不断地进行软件测试”原则

2.W模型

  1. 由两个 v 字模型组成,分别代表测试与开发过程,明确表示了测试与开发并行关系
  2. 优点:
    测试活动与软件开发同步进行
    测试对象不仅是程序,包括需求与设计
    尽早发现软件缺陷可降低软件开发成本
  3. 局限性:无法支持迭代开发模型(没有循环过程)

3.h模型

  1. 将测试活动完全独立出来,形成一个完全独立的流程
  2. 只要测试条件成熟了,测试准备活动完成了,测试执行活动就可以进行了
  3. 软件测试要尽早准备,尽早执行,不同测试活动可按某个次序先后进行,也可反复进行(迭代)

4.x模型

  1. 针对单独的程序片段进行相互分离的编码和测试;
  2. 定位了探索性测试,这是不进行事先计划的特殊类型的测试;

18.软件测试生命周期

获取测试需求
编写测试计划
制定测试方案
开发与设计测试用例
执行测试
提交缺陷报告
测试分析与评审
提交测试总结
准备下一版本测试

19. 简述缺陷(BUG)的生命周期? 面试重点

软件测试人员提交缺陷报告 new
测试负责人审核后将缺陷分配给相关开发人员修复 open
缺陷被修改后有测试人员根据缺陷报告中修改记录进行返测 fixed
返测通过的缺陷由负责人关闭 close
返测未通过的缺陷直接返回给开发人员重新修改,然后再由测试人员返测,直到测试和开发达成一致处理意见 reopen—>close

New:发现bug,未经评审决定是否指派给开发人员进行修改。
Open:确认bug,并且认为需要进行修改,指派给相应的开发人员。
Fixed:开发人员进行修改后标识成修改状态,有待测试人员的回归测试验证。
Rejected:如果认为不是Bug,则拒绝修改。
Delay:如果认为暂时不需要修改或暂时不能修改,则延后修改。
Closed:修改状态的Bug经测试人员的回归测斌验证通过,则关闭Bug。
Reopen:如果经验证Bug仍然存在,则需要重新打开Bug,开发人员重新修改。

20. 设计用例方法

  1. 黑盒测试

等价类划分法:(从文字中提取重点概念)将系统的输入域划分为若干部分,然后从每个部分选取少量代表性数据进行测试。等价类可以划分为有效等价类和无效等价类
边界值分析法:是通过优先选择不同等价类间的边界值覆盖有效等价类和无效等价类来更有效的进行测试,因此该方法要和等价类划分法结合使用。
正交试验法:正交是从大量的试验点中挑选出适量的、有代表性的点
状态迁移法是对一个状态在给定的条件内能够产生需要的状态变化,有没有出现不可达的状态和非法的状态
判定表分析法:判定表是分析和表达多种输入条件下系统执行不同动作的工具
因果图法:因果图是用于描述系统输入输出之间的因果关系、约束关系。

  1. 白盒测试
    静态:看代码结构
    动态:逻辑覆盖法,程序插桩技术,基本路径法,符号测试,错误驱动测试

21. 测试分类

1.按开发阶段分

单元测试(模块测试)
针对软件设计的最小单位—程序模块进行正确性校验的测试工作。
目的:检查每个程序单元能否正确实现详细设计说明中的模块功能、性能、接口和设计约束等要求,发现各模块内部可能存在的各种错误。
单元测试需要从程序内部结构出发设计测试用例
多个模块平行独立地进行单元测试
集成测试(组装测试): 有序、递增的测试,持续不断的过程,持续时间比较长
在单元测试基础上,将所有程序模块进行有序、递增的测试。
基础测试是检验程序单元或部件的接口关系,逐步成为符合概要设计要求的程序部件或整个系统
确认测试(有效性测试)—时间短
在模拟环境下,验证软件所有功能和性能及其他特性是否与用户预期要求一致。
系统测试:
在真实系统运行环境下,检查完整的程序系统能否和系统(硬件、外设、网络和系统软件、支持平台)正确配置、连接,最终满足用户的所有需求
验收测试
按项目任务书或合同、供需双方约定的验收依据文档进行的对整个系统的测试与评审,决定是否接收或拒收系统;

2.按测试技术划分

黑盒测试(80%):
通过软件外部表现来发现其缺陷和错误。黑盒测试把测试对象看出一个黑盒子,完全不考虑程序内部结构和处理过程。在程序界面处进行测试,只是检查程序是否按照需求规格说明书的规定正常实现
白盒测试(结构测试):
不管黑盒测试做得有多完全,白盒测试也有必要做
通过对程序内部结构和分析、检测来寻找问题。
把测试看成一个透明的盒子里,检测是否所有结构及路径都是正确的,检查软件内部动作是否按照设计说明的规定正常进行
灰盒测试(接口测试)
关注输出对输入的正确性

  1. 按代码运行划分
    静态测试:不实际运行被测对象,而是静态检查程序代码、界面或文档中可能存在错误的过程
    代码测试:主要测试代码是否符合相应的标准和规范
    界面测试:主要测试软件的实际界面与需求中的说明是否相符
    文档测试:主要测试用户手册和需求说明是否真正符合用户的实际需求
    动态测试: 实际运行被测对象,输入相应的测试数据,检查实际输出结果和预期结果是否相符的过程,所以我们判断一个测试属于动态还是静态测试,唯一标准就是看是否运行程序

  2. 按软件特性
    功能测试(黑盒测试):黑盒测试一方面,检查实际软件功能是否符合用户需求
    性能测试:关注软件中某一功能在指定的时间、空间条件下,是否使用正常
    主要有时间性能和空间性能
    安全性测试:验证按在系统内的包含机制能否在实际应用中对系统进行保护使之不被非法入侵,不受各种因素干扰

  3. 其他测试
    **回归测试:**对软件新版本测试时,重复执行之前某一个重要版本的测试用例(测试过程)
    目的:验证之前版本产生所有缺陷是否已被修复;确认修复这些缺陷没后引发新的缺陷
    **冒烟测试(可行性测试):**先验证一下软件基本功能是否实现,在对一个新版本进行系统大规模测试

22. 测试的优先级

先测试经过变更的部分,然后测试没有变更的部分

先测试程序的核心功能,然后测试一般功能

先测试逻辑性的功能,然后测试业务性的功能

先测试常规情况,然后测试异常情况

先测试功能,然后测试性能

23. app测试特点

适配性测试---------网络测试-----------在线升级测试-----------中断测试
耗电量测试---------弱网测试-----------安装卸载测试-----------流量测试

24.怎样进行弱网测试?

弱网测试主要进行特殊网络状态下的功能测试,同时关注用户体验。
弱网测试主要包括弱网功能测试、无网状态测试、网络切换测试
Fiddler中启动弱网:
打开Fiddler,Rules规则->Performance性能设置->勾选 Simulate Modem Speeds模拟慢速网络

25. 缺陷(BUG)的状态?

NEW:所有提交到开发对接的问题状态为NEW,表示为未处理

OPEN:开发对接人初判为需流转问题,指定测试人员和开发人员,状态为OPEN。

REFUSE:开发对接人判断为不需要流转至下环节的问题,状态为REFUSE,并且填写原因

FIXED:开发人员完成修复,待测试,状态为FIXED

REOPEN:测似人员针对开发人员的修复结果测试部通过,状态为REOPEN

CLOSE:测试人员判断问题为需求或其他问题,需填写原因;

26. 为什么要做接口测试

越底层发现BUG,修复成本越低

前端发生变化时,后端接口可以不用变

检查系统的安全性、稳定性,前端传参不可信

27. 接口测试是怎么做的

用postman模拟http请求的发送与接收

由于我们项目前后端调用主要是基于http协议的接口,所以测试接口时主要是通过工具或代码模拟http请求的发送与接收。工具有很多如:postman、jmeter、soupUI等。
也可以用 接口自动化来实现,就是用代码实现,框架和UI自动化差不多,发送请求用断言来判断。

28. 接口测试重点

检查接口返回的数据是否与预期的结果一致

检查接口的容错性,加入传递的类型错误时是否可以处理

接口测试的边界值

接口的性能

接口的安全性

28. 交换机测试的一些东西。

1.二层交换性能测试
Mac地址学习速度
Mac地址表容量
端口地址数量限制
转发性能
超长帧转发性能
丢帧率
地址处理
错误帧过滤
广播转发性能
广播抑制功能
Vlan堆叠测试
端口镜像功能测试
优先级控制
3.三层交换性能测试
第三层地址学习
路由表容量
Ospf路由震荡
吞吐量
延迟
丢包率
背靠背
有效吞吐率
3.功能测试
Arp功能测试
拥塞控制
板内交换性能测试
最大vlan数量测试
路由表容量测试
Mac地址访问控制表测试
4.可靠性测试
主控板和交换矩阵冗余
电源冗余
业务卡热拔插
设备防arp攻击
设备防icmp攻击
稳定性测试

28. CS/BS架构区别

上线方式不同:发版节奏/用户运营不同/修复线上问题,cs需要上应用商店,发版更严格,bs想上线就上线,cs修复线上问题需要热修,成本很高,bs成本低

测试过程:cs基本都是黑盒,很难看开发代码逻辑测,bs可以方便用调试工具看研发实现,也造成了自动化测试的时候需要适配不同的客户端代码实现,bs就不用

安全性:cs需要反编译才能拿到实现,bs直接打开调试工具就可以,cs可以很好的反抓包,bs则不行
用户体验:bs基于浏览器去进行系统调度,cs直接和操作系统交互性能更好

同一个需求:cs需要适配多种操作系统,android,ios,mac等等,bs只要适配浏览器即可,bs开发成本更低

29. 功能测试和接口测试是什么及区别

1.什么是功能测试
功能测试主要对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。
2.功能测试怎么做
功能测试如何进行的:编写测试用例,测试用例当中最主要的是测试步骤和预期结果;测试人员根据测试用例执行操作步骤,然后通过眼睛和思考判断实际结果与预期结果是否相等。如果相等,测试通过;如果不相等,测试失败。
3.什么是接口测试
接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。
4.功能测试和接口测试的区别
功能测试和接口测试的区别在于,功能测试侧重点在于前端ui界面,数据展示,图形界面,业务逻辑操作等,接口测试侧重点在于,后端返回的数据是否正确,接口是否正常。

30.测试是做什么的

测试项目的具体工作:搭建测试环境、编写和执行测试用例、写测试计划和报告、提交bug表单并跟踪bug修改、编写脚本执行自动化测试、进行性能测试压力测试等

31.比较两个网页的访问速度

Ping 两个网站的网址可以得到发送32字节需要的时间,直接比较

32.不能访问某个网站的可能原因

1.网站本身的问题,服务器故障、网站维护等。
2.访问网站的部分结点出现了拥堵或者短暂性的无连接。
3.Dns解析问题。
4.浏览器缓存了旧版本的js,需要清除缓存文件。

32.本机不能联网如何排查

Ping 192.168.1.1,本地循环地址,ping不通表示本地的tcp/ip协议不能正常工作
Ipconfig,ping自己的ip,ping不通则网络适配器有问题
Ping 默认网关,本机到路由是否正常
Ping 某网站,通了就可以上网

33.当数据库流量大,数据大应该怎么办

1.分表
将不常用的数据分一张结构与当前表一样的表
2.索引优化和sql优化(建立非聚集索引)

34.输入一个URL没有访问到预期的网站可能的原因

1.Dns故障
2.网络断开
3.服务器拒绝访问
4.请求或者响应在网络传输中被劫持

35.自己电脑上不了网怎么排查

1.排除接触故障,看物理连线是否正常
2.排除偶然故障,更改适配器设置里,设置本地连接或者无线网络连接,先禁用再启动
3.ipconfig all 看IP地址和网卡物理地址等,看是否已经断开
4.ping 127.0.0.1 若发送和接受了4个包,丢包率为0,网络协议正常,显示请求超时则网卡安装或者TCP/IP协议有问题。
5.ping 本机ip 不通则网卡驱动程序不正确,或网卡与网线连接有故障,或路由表破坏。检查本机网卡是否连接,网络参数是否正确(参数正确但不能ping通则应该重新安装网卡驱动程序)
6.ping 网关 通了则网络连接正常,不通可能网关设备或者上网参数有问题。

36.对软件测试这个工作有什么了解,平时一般通过什么途径自学

软件测试是为了捕捉软件中的错误,是一种经济高效的保证软件质量的方法。软件测试快速发展,充满挑战。一些传统测试可能会被自动化测试替代,但对于自动化软件开发、安全测试、性能测试、可靠性测试等还是需要专业人员操作。伴随着云计算、物联网、大数据的发展,测试技术可能会有更新,需要更加了解应用场景,具有更深厚的测试基础。
软件测试需要早发现问题和发现别人还没发现的问题,这样才能使解决问题的成本降低。
测试项目的具体工作:搭建测试环境、编写和执行测试用例、写测试计划和报告、提交bug表单并跟踪bug修改、编写脚本执行自动化测试、进行性能测试压力测试等

.软件测试的目的

软件测试是以发现软件的存在的故障或缺陷,并藉此对软件的质量进行度量。为达此目的,测试活动的目标是最大可能的找出最多的错误。
测试是从假定软 件含有缺陷和故障的假设而进行的,实现这个目标的关键是科学合理设计出最能 暴露问题的测试用例。
测试是程序执行过程,并限于执行处理有限的测试用例与情形,并发现了错误;
检测软件是否满足软件定义的各种需求目标;
执行的测试用例发现了未曾发现的错误,实现成功的测试。

  1. 软件测试的原则

依据软件测试的目的,归纳出一些测试的原则。
尽早和及时的进行测试。测试活动应从软件产品开发初始阶段就开始;
测试用例要由测试数据与预期结果两部分组成,并包括测试前置条件或 后置条件;
测试根据其需求和风险,可由专业测试者进行或程序开发者自行检测;
需要严格执行测试计划,并排除测试工作随意性;
充分注意测试中的集群效应,经验表明软件约 80%的错误仅与 20%的 程序有关;
应对测试结果作核查,存档测试计划、测试用例、缺陷统计和分析报告等文档,为软件维护提供资料及条件。

自动化测试

1.什么情况下定位不到元素

1.代码写错
2.元素未出现(需要元素等待)
3.元素在iframe中
4.多窗口
5.出现弹窗(系统弹窗、JS弹窗) 等待弹出框出现之后,定位弹出框,操作其中元素
6.元素属性值是动态加载的
7.元素无法确定唯一性
8.只读属性(元素不可操作)

出现弹窗了怎么办

等待弹出框出现之后,定位弹出框,操作其中元素

2.什么时候,什么项目/功能需要做web自动化

1.需求变动不频繁
2.项目周期长
3.项目需要回归测试

3.python+selenium常用命令

#获取窗口大小
driver.get_window_size()
#改变窗口大小
driver.set_window_size(x, y)
#获取当期标题
driver.title
#获取url地址
driver.current_url
#截屏
driver.get_screenshot_as_file('1.png')
#上传文件,定位到再通过sendkeys路径上传
driver.find_element(By.CSS_SELECTOR, 'input[type=file]').sendkeys(r'h:\g02.png'

3.Pytest+selenium+python 自动化框架总结

Pytest+selenium+python 自动化框架总结
一.整体分层
1、公共方法层Common
2、日志&报告层 Output
3、页面元素层PageLocators
4、case具体实现的逻辑层PageObjects
5、case层TestCase(pytest中测试类py文件都以test_开头。)
6、测试数据层TestDatas
6、自动化执行入口main.py&runner.py

pytest fixture 夹具

场景:执行测试用例时,有的用例需要登录才能执行,有些用例不需要执行
1.导入pytest
2.在登录的函数上面加上@pytest.fixture()
3.在要使用的测试方法中传入(登录函数名称)
4.不传入的就不登陆直接执行测试方法

4.PO模式简介

PO模型是:Page Object Model的简写 页面对象模型

作用:就是把测试页面和测试脚本进行分离,即把页面封装成类,供测试脚本进行调用;
分层机制,让不同层去做不同类型的事情,让代码结构清晰,增加复用性。

PO模式的优缺点:
优点:
提高代码的可读性
减少了代码的重复
提高代码的可维护性,特别是针对UI界面频繁的项目

缺点:
造成项目结构比较复杂,因为是根据流程进行了模块化处理

1.页面名称Page(对象库层):需要浏览器驱动对象;封装元素定位方法

2.页面名称Handle (操作层):对象库层封装的元素定位对象;封装元素操作方法

3.页面名称Proxy (业务层):操作层封装的元素操作对象;封装测试业务方法

代码演示—登录页面:

"""
登录页面
"""
from utils import DriverUtil


class LoginPage(object):
    """对象库层(封装元素定位方法)"""

    def __init__(self):
        self.driver = DriverUtil.get_driver()  # 获取浏览器驱动对象

    def find_username(self):
        """用户名定位方法"""
        return self.driver.find_element_by_id('username')

    def find_password(self):
        """密码定位方法"""
        return self.driver.find_element_by_id('password')

    def find_code(self):
        """验证码定位方法"""
        return self.driver.find_element_by_id('verify_code')

    def find_login_btn(self):
        """登录按钮定位方法"""
        return self.driver.find_element_by_name('sbtbutton')


class LoginHandle(object):
    """操作层(封装元素操作方法)"""

    def __init__(self):
        self.login_page = LoginPage()  # 元素对象定位类对象

    def input_username(self, name):
        """用户名输入方法"""
        # send_keys('13811110000')
        self.login_page.find_username().send_keys(name)

    def input_password(self, pwd):
        """密码输入方法"""
        self.login_page.find_password().send_keys(pwd)

    def input_code(self, code):
        """验证码输入方法"""
        self.login_page.find_code().send_keys(code)

    def click_login_btn(self):
        """登录按钮点击方法"""
        self.login_page.find_login_btn().click()


class LoginProxy(object):
    """业务层(封装具体的测试执行步骤)"""

    def __init__(self):
        self.login_handle = LoginHandle()  # 元素操作类对象

    def login_func(self, name, pwd, code):
        """登录方法"""
        self.login_handle.input_username(name)  # 输入用户名
        self.login_handle.input_password(pwd)  # 输入密码
        self.login_handle.input_code(code)  # 输入验证码
        self.login_handle.click_login_btn()  # 点击登录按钮

5.八大定位元素的方法

1.根据元素id属性定位元素(重点)
element = driver.find_elemet_by_id(‘’)

2.根据class属性定位元素 (通常不用,因为找到的元素可能不唯一,记住就可以了)
element = driver.find_element_by_class_name(‘’)

3.根据tag_name标签名定位元素
element = driver.find_element_by_tag_name(‘input’)

4.通过link_text的文本去查找
element = driver.find_element_by_link_text(‘新闻’)

5.通过链接标签的文本去查找
element = driver.find_element_by_partial_link_text(‘新’)

6.通过元素的name属性定位元素
element = driver.find_element_by_name(‘’)

7.通过xpath定位表达式查找元素(重点-定位元素特别精准)-chrpath插件(协助)
浏览器支持在F12,查看源代码处直接copy表达式xpath语句,有绝对路径和相对路径(ctrl+f 验证)
ele = driver.find_element_by_xpath(‘’)

8.通过css选择器定位表达式查找元素,主要是层级查找
ele = driver.find_element_by_css_selector(‘’)

6.RF自动化框架

RF自动化框架:主要由关键字组成 有的函数svn库里有 没有的需要自己去编写

变量 关键字 参数

在这里插入代码片# 定义变量
${a}  Set Variable  100

# 打印信息
Log  ${a}

# 获得系统时间
${time}  Get Time

# 字符串拼接,默认以空格拼接
${str}  catenate  a  b  c
# 使用特定字符拼接(如用#拼接)
${str}  catenate  SEPARATOR=#  a  b  c

# 创建列表,得到${a} = ['a', 'b', 'c']
${list}  Create List  a  b  c
Log  ${list}    # 和python一样的列表格式

最基本的配置自己都要会写,也要能看懂函数意思
比如配置ccc透传模式(配置四台设备接口,再让R4作主设备去进行透传)这些,还有配置isis 分别向设备区配置接口IP 还有loopback ip

com_ccc_setup
    ${cmd_list1}    create list    configure    l2 vfi ${evi_name} vpnid ${vpnid}    end
    dut_write_cmdlist    ${cmd_list1}    alias=dut4
    ${cmd_list1}    create list    configure    interface ${dut4_port1}    no shutdown    xconnect vfi ${evi_name}    end
    dut_write_cmdlist    ${cmd_list1}    alias=dut4
    ${cmd_list1}    create list    configure    interface ${dut4_port2}    no shutdown    xconnect vfi ${evi_name}    end
    dut_write_cmdlist    ${cmd_list1}    alias=dut4
    ${cmd_list1}    create list    configure    interface ${dut4_port3}    no shutdown    xconnect vfi ${evi_name}    end
    dut_write_cmdlist    ${cmd_list1}    alias=dut4




com_isis_setup
    # dut1、dut2、dut3配置接口IP、loopback IP
    fw_log     dut1配置接口IP、loopback IP
    ${cmd_list}    create list    enable    configure
    ...    interface ${dut1_port1}     no shutdown    ipv6 address ${dut1_port1_ipv6}/64    exit
    ...    interface ${dut1_port2}     no shutdown    ipv6 address ${dut1_port2_ipv6}/64    exit
    ...    interface loopback 0    ip address ${dut1_loopback_ipv4} 32    ipv6 address ${dut1_loopback_ipv6}/128    exit
    dut_write_cmdlist    cmd_list=${cmd_list}    alias=dut1

7.EVPN基础配置

1.进入特权模式
enable
2.进入全局配置模式
configure terminal
3.开启EVPN功能并进入EVPN配置模式
evpn
缺省情况下,EVPN功能处于关闭状态。

4.配置标识PE设备的源地址
source-address ipv4-address
缺省情况下,未配置表示PE设备的源地址。
配置EVPN VPLS和EVPN VPWS时,必须通过此命令配置PE。

5.创建EVI实例
请选择其中一项进行配置。(EVI就是一个EVPN实例)
a.创建EVI实例,配置VNI ID并进入VNI配置模式
vni vni-id
缺省情况下,不存在EVI实例
b.批量创建EVI实例,并进入EVI实例批量配置模式。
vni range vni-id-list
缺省情况下,不存在EVI实例
c.创建BD或者VPWS模式的EVI实例,并进入EVI配置模式
evi evi-name [{ bd-mode | vpws ] }
缺省情况下,不存在EVI实例

6.配置EVI的描述信息
description description-information
缺省情况下,EVI没有描述信息。

7.定义EVI实例的RD值*(RD)路由标识符
rd { auto | rd-value }
缺省情况下,EVI实例未配置RD值。
BD和VPWS模式的EVI实例不支持配置自动生成RD值。

8.定义EVI的RT(Route Target,路由目标)属性。
route-target { both | import | export | import } { auto | rt_value }
缺省情况下,EVI未配置RT属性。
BD和VPWS模式的EVI实例不支持配置自动生成RT值。

9.(可选)设置远端EVPN路由导入本地VNI实例的策略规则
import map routemap-name
缺省情况下,未配置远端EVPN路由导入本地VNI实例的策略规则。

10.(可选)设置本地分发给远端的EVPN路由的扩展团体属性策略规则
export map routemap-name
缺省情况下,未配置本地分发给远端的EVPN路由的扩展团体属性策略规则。
#if defined(CAP_VXLAN_VNIARPSUPRESS)

11.(可选)配置ARP代理/抑制
arp { proxy | suppress } enable
缺省情况下,未配置ARP代理/抑制。
#endif /* defined(CAP_VXLAN_VNIARPSUPRESS) */
#if defined(CAP_VXLAN_VNINDSUPRESS)

8.EVPN测试用例

EVPN VPLS over SRv6双归单活
两台设备发流量只有一台能发送到 另一台的流量被截断了

测试步骤与预期结果一一对应

测试步骤:

  1. R1、R2、R3作为PE(提供商边缘路由器(运营商)),之间配置接口Ipv6地址,使能SRv6
  2. R4作为CE(客户边缘路由器)设备, 配置ccc透传模式
  3. 在R1、R2、R3上分别创建EVI实例,形成双归场景,并使能单活模式
  4. 在R1上查看远端PE的ECMP、FRR状态 (R1先发给R2和R3发送流量,R1直接到不了R4)
  5. Port1和Port2发送双向源mac跳变10次的流量 (通过接口发送跳变流量)
  6. 在R1上查看mac表和路由表
  7. Port1发送BUM流量,去检测能不能收到

(流量转发正常无丢包,R2、R3只有一台设备把流量送到R4,另外一台在AC口截断流量。)

预期结果:

  1. ISIS建立成功,BGP建立成功。
  2. CCC状态正常。
  3. EVPN建立成功。
  4. 远端PE显示单活模式,形成FRR。
  5. Port1发送的流量走向FRR状态中的主设备,Port2发送的流量走向R1,流量转发不丢包。
  6. BGP路由表中收到远端type2路由,同时远端MAC安装正常,查看到所有跳变MAC。
  7. 流量转发正常无丢包,R2、R3只有一台设备把流量送到R4,另外一台在AC口截断流量。

Python 6种数据类型总结

数据类型
不可变数据: Number(数字)、String(字符串)、Tuple(元组)
可变数据: List(列表)、Dictionary(字典)、Set(集合)

Postman测试过程出现什么问题

Selenuim测的是管理者网页部分
1.Postman的返回值正常,但是在浏览器上采用post方法提交数据后端没有办法获取数据
当我们采用前后端分离的方式开发项目时,需要从前端采用的post方法向后台提交数据时,发现提交不了,而且进入不了接口方法,接口失效。

一般出现这种情况都需要设置请求头为,Content-Type:application/x-www-form-urlencoded

2.下载图片接口苹果行,安卓不行
下载图片的时候老是获取不到图片,而用浏览器访问没问题,postman和苹果也没问题,要么报406,要么提示
error:12 errorMessage:“response is unsuccessful: response get error content type!”
1
后来发现是因为当图片不存在时返回了一个html,导致小程序解析错误报406
而另外一个12错误码则是因为响应头设置不正确导致的。
刚开始设置的是application/octet-stream ,安卓上不行。
后来改成了根据图片类型设置对应的content-type,
mage/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
设置完成之后安卓也能成功访问了。

为什么要用postman测试接口

首先在项目的初期,测试人员提前介入,进行接口测试模拟客户端与服务端的交互。有问题提前抛出来。保证接口调用是没问题的。其次,接口测试完成之后在进行系统测试,会轻松很多。明白了各个接口在做什么,各个参数的模拟实际上就是业务场景的模拟。系统测试出现一些问题更快速的定位是客户端还是服务端出问题。最后接口最省时,省力,而且收益很高。
接口中的返回相对单纯,不像web页面,html代码中有太多ui的东西,ui最不稳定,变化太快,接口相对稳定一点点,但是里面的干扰信息更少,断言相对容易很多。

为什么要用postman测试接口

另外,接口是获取和操作资源的方式,而大部分系统和产品中,资源一般都是产品的核心,比如微信核心资 源就是通讯录关系链和聊天记录等,因此资源是必测的。

而接口中大部分的内容是数据,通过数据的对比我们能推测到系统和产品的逻辑,测接口就是测逻辑。最后接口中的返回相对单纯,不像web页面,html代码中有太多ui的东西,ui最不稳定,变化太快,接口相对稳定一点点,但是里面的干扰信息更少,断言相对容易很多。

shell编程和命令部分

1.目录信息查看命令 ls [选项] [路径]
Is命令主要用于显示指定目录下的内容,列出指定目录下包含的所有的文件以及子目录
-a显示所有的文件以及子目录,包括以“”开头的隐藏文件。
-l 显示文件的详细信息,比如文件的形态、权限、所有者、大小等信息。
-t 将文件按照创建时间排序列出。
-A 和-a一样,但是不列出“.”(当前目录)和“…”(父目录)。
-R 递归列出所有文件,包括子目录中的文件。

文档名称:r(读取):4 w(写入): 2 x(执行):1
rwx 可读、可写、可执行 4+2+1=7

r-x 可读、不可写、可执行 4+1=5

rw- 可读、可写、不可执行 4+2=6

-wx 不可读、可写、可执行 2+1=3

2.目录切换命令 cd [路径]
cd / 进入到根目录“/”下,Linux系统的根目录为“/”
cd /usr 进入到目录“/usr”里面。
cd … 进入到上一级目录。
cd ~ 切换到当前用户主目录

3.显示当前路径命令pwd
pwd命令用来显示当前工作目录的绝对路径,不需要任何的参数。

4.系统信息查看命令uname

要查看当前系统信息,可以使用命令uname,命令格式如下:
uname [选项]

可选的选项参数如下:
-r 列出当前系统的具体内核版本号。
-s 列出系统内核名称。
-o 列出系统信息。

5.清屏命令clear
clear命令用于清除终端上的所有内容,只留下一行提示符。

6、切换用户执行身份命令sudo
sudo [选项] [命令]

选项主要参数如下:
-h 显示帮助信息。
-l 列出当前用户可执行与不可执行的命令。
-p 改变询问密码的提示符。

7.添加用户命令adduser

此命令需要root身份去运行。命令格式如下:
adduser[参数][用户名]

常用的参数如下:
-system 添加一个系统用户
-home DIR DIR表示用户的主目录路径
-uid ID ID表示用户的uid。
-ingroup GRP 表示用户所属的组名。

8.删除用户命令deluser
deluser [参数][用户名]
主要参数有:

-system 当用户是一个系统用户的时候才能删除。
-remove-home 删除用户的主目录。
-remove-all-files 删除与用户有关的所有文件。
-backup 备份用户信息

9.切换用户命令su

“sudo”是以root用户身份执行一个命令,并没有更改当前的用户身份,所有需要root身份执行的命令都必须在前面加上“sudo”。命令“su”可以直接将当前用户切换为root用户,切换到root用户以后就可以尽情的进行任何操作了!因为已经获得了系统最高权限,在root用户下,所有的命令都可以无障碍执行,不需要在前面加上“sudo”,“su”命令格式如下:

su [选项] [用户名]
常用选项参数如下:

-c -command 执行指定的命令,执行完毕以后恢复原用户身份。
-login 改变用户身份,同时改变工作目录和PATH环境变量。
-m 改变用户身份的时候不改变环境变量
-h 显示帮助信息
注意:由于root用户权限太大,稍微不注意就可能删除掉系统文件,导致系统奔溃,因此强烈建议大家,不要以root用户运行Ubuntu。当要用到root身份执行某些命令的时候使用“sudo”命令即可。要切换回原来的用户,使用命令“sudo su用户名”即可。

10.显示文件内容命令cat
查看文件内容是最常见的操作了,在windows下可以直接使用记事本查看一个文本文件内容,linux下也有类似记事本的软件,叫做gedit,找到一个文本文件,双击打开,默认使用的就是gedit。命令“cat”,命令格式如下:

cat [选项] [文件]
选项主要参数如下:

-n 由1开始对所有输出的行进行编号。
-b 和-n类似,但是不对空白行编号
-s 当遇到连续两个行以上空白行的话就合并为一个行空白行。

11.显示和配置网络属性命令ifconfig
查看当前网络属性,也可以通过此命令配置网络属性,比如设置网络IP地址等等,此命令格式如下:
ifconfig interface options|address

主要参数如下:
interface 网络接口名称,比如eth0等。
up 开启网络设备。
down 关闭网络设备。
add IP地址,设置网络IP地址。
netmask add 子网掩码

12.系统帮助命令man
通过“man”命令可以查看其它命令的语法格式、主要功能、主要参数说明等,“man”命令格式如下:
man [命令名]

13.创建文件夹mkdir命令

-p :递归创建目录
-m:设置新建目录权限

14.删除文件夹rmdir命令
-p :递归删除目录

15.创建文件touch命令 一般不加可选项

16.删除文件rm命令

-f :强制删除文件。
-r :递归删除目录及内容

17.文件权限修改chmod命令

对目录和文件读、写、执行的权限进行修改。
-u user 用户
-g grop 用户组
-o others 其他人
-a all 所有人

chmod u+x a.txt 用户增加执行权限
chmod 777 a.txt 所有人增加所有权限

18.grep :grep 命令用于查找文件里符合条件的字符串
-c 计算找到‘搜索字符串’的行数
-o 指数出匹配的内容
-i 不区分大小写
-n 是显示行号
grep与管道符:将一个命令的输出作为下一个的输入

利用Linux所提供的管道符“|”将两个命令隔开,管道符左边命令的输出就会作为管道符右边命令的输入。

19.获取文本对应文本的行号 ,可以用grep,也可以用sed
grep -n “xxx” a.txt | cut -d “:” -f 1
sed -n -e ‘/xxx/=’ a.txt

20.获取进程ID pid

21.网络相关常用命令
ifconnfig:查看网卡配置信息
route显示路由表
netstat:查看本地计算机所使用的网络服务状况
ping:测试本地计算机与目标主机是否连接 如ping 127.0.0.1

22.linux查看进程 ps-aux

查看端口号 netstat –tunlp|grep 端口号

动态查看日志的指令 先切换到:cd usr/local/tomcat5/logs
tail -f catalina.out

sed 流文本编辑器

awk 文本和数据处理

find作用是在目录中搜索文件,它的使用权限是所有用户

23.系统重启命令reboot
Shell命令“reboot”来重启系统,直接输入命令“reboot”然后点击回车键即可。

24.系统关闭命令poweroff
命令“poweroff”就可以关闭系统,在终端中输入命令“poweroff”然后按下回车键即可关闭Ubuntu系统。

25.mv指令
mv oldNameFile newNameFile (功能描述:重命名)
mv /temp/movefile /targetFolder (功能描述:移动文件)

26.find指令
find指令将从指定目录向下递归地遍历其各个子目录,将满足条件的文件或者目录显示在终端。

26.zip指令
zip [选项] XXX.zip 将要压缩的内容

Java

1.LinkedList类 ArrayList类 Vector类 HashMap类 区别

1.LinkedList类
LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。

2.ArrayList类
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。

3.Vector类
Vector非常类似ArrayList,但是Vector是同步的。

4.HashMap
键值对

2.Java中final、finally、finalize的区别与用法

1.final:java中的关键字,修饰符。方法不可覆盖,类不可继承。
2.finally:java的一种异常处理机制。表示总是执行。
3.finalize:Java中的一个方法名。是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。

3.windows怎么查看路由表

windows怎么查看路由表 :CMD–>route print

4.面向对象的特性?什么是多态?

面向对象的特征有哪些方面?

答:特征可以说有三种,继承、封装、多态,也可以说有四种,继承、封装、多态、抽象。

继承性是类的一种层次模型,其提供了一种明确表述共性的方法,对象的新类可以从现有的类中继承派生,类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。

封装性是把过程和数据包围起来,使得数据的访问只能通过已定义的接口,保证了对象被访问的隐私性和可靠性。

多态有两种描述方式,一种是方法的多态性、一种是对象的多态性。多态是发生在编译期间的。
一、方法的多态性:
① 方法的重载:同一个方法名称,会根据传入参数的类型及个数不同执行不同的方法体;(实现在一个类中)
② 方法的覆写: 同一个方法,会根据子类的不同,实现不同的功能。也就是继承了父类的多个子类对父类方法的重写,导致了方法的多态性。(实现在子类中)

如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Override)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。

二、对象的多态性(指的是发生在继承关系之中,子类和父类之间转换问题)

父类对象——子类实例:

① 向上转型(自动完成):父类 父类对象 = 子类实例 <new 实现>

子类对象——父类实例:

② 向下转型(强制完成):子类 子类对象 = (子类)父类实例 <new 实现>

抽象性是指对一类事物的高度提炼以得到共同的共性部分,抽象不需要了解全部细节,而只是一种通用的描述约束,抽象可以是过程抽象或者数据抽象。

多态的优点:
1.提高了代码的维护性(继承保证);
2.提高了代码的扩展性(由多态保证);

多态的缺点:
1.不能使用子类的特有功能(非要使用只能通过不优雅的创建子类对象方式,但是占用内存,其次就是使用强转类型,也容易出现问题);
2.向下转型(把父类转换为子类型)中有可能会出现异常;

5.接口和抽象类有什么区别

都不能实例化对象,都可以包含抽象方法,而且抽象方法必须被继承的类全部实现。
区别:
1.抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2.抽象类要被子类继承,接口要被类实现。
3.接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4.接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5.抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6.抽象方法要被实现,所以不能是静态的,也不能是私有的。
7.接口可继承接口,并可多继承接口,但类只能单根继承。
8.抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果

接口的设计目的,是对类的行为进行约束
抽象类的设计目的,是代码复用。

5.int和Integer的区别

1、Integer是int的包装类,int则是java的一种基本数据类型
2、Integer变量必须实例化后才能使用,而int变量不需要
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
4、Integer的默认值是null,int的默认值是0

linux

1.常用linux命令

ifconfig 查看IP地址

cat 用于显示指定文件的全部内容

more 用分页的形式显示指定文件的内容

mkdir 创建目录

touch 创建新的文件

grep 查找文件里符合条件的字符串

find-name 查找指定的文件

tail -f 用于自动刷新显示文件后N行数据内容

kill -9 强制结束

netstat -anp | grep 端口号 查看端口

chmod -R 777 赋予777权限

2. Linux 的NAPI机制

中断收包模式难以适应千兆,万兆带宽了。如果每个数据包大小等于MTU大小1460字节。当驱动以千兆网速收包时,CPU将每秒被中断91829次。在以MTU收包的情况下都会出现每秒被中断10万次的情况。过多的中断会引起一个问题,CPU一直陷入硬中断而没有时间来处理别的事情了。为了解决这个问题,内核在2.6中引入了NAPI机制。

NAPI就是混合中断和轮询的方式来收包,当有中断来了,驱动关闭中断,通知内核收包,内核软中断轮询当前网卡,在规定时间尽可能多的收包。时间用尽或者没有数据可收,内核再次开启中断,准备下一次收包。

(中断收包模式难以适应千兆万兆的网速,一直中断收包太影响CPU的性能,由此引入NAPI机制。NAP机制主要通过混合中断和轮询的方式收报,再一次中断的时间内尽可能的多收包,直到时间用尽或者没有数据可收)

3.Linux #! bin/bash的作用

第一行是告诉操作系统,使用#! /bin/bash,使用这个路径下的sh实现来执行下面的shell scirpt

4.后缀的作用是指明打开文件的方式,Linux不管后缀的话怎么知道该如何执行呢

事实上,Linux下的文件不需要扩展名。一切皆文件,包含设备文件、目录文件、普通文件等。要知道是否是可执行文件,一般是通过 ls -l 命令看文件属性中是否包含可执行权限 (x)。

Linux不使用文件名扩展来识别文件的类型。相反,Linux根据文件的头内容来识别其类型。为了提高文件可读性您仍可以使用文件名扩展,但这对 Linux 系统来说没有任何作用。

5.如何将一个文件的权限改为可执行

linux里把一个文件更改成所有的用户都有可执行权限可以使用以下命令: chmod 777 filename

6.权限1表示什么,读写权限什么数字表示

如果可读、可写、可运行,就表示为二进制的111,转换成十进制就是7。

如果可读、可写、不可运行,就表示为二进制的110,转换成十进制就是6。

如果可读、不可写、可运行,就表示为二进制的101,转换成十进制就是5。

7.linux怎么查看用户属于哪个组

1、直接执行“groups”命令,可查看当前用户所属组;
2、执行“groups 用户名”命令,可查看指定用户所属组;
3、执行“id 用户名”命令,可查看指定用户所属组;
4、执行“cat /etc/group”命令,输出组文件信息。

8.win查看GPU使用率

C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe
CPU:任务管理器

9.linux查看CPU使用率

linux查看CPU基本信息,可以使用命令:
cat /proc/cpuinfo
显示的cpu cores 位于相同物理封装的处理器中的内核数量。

10.linux命令:查看所有进程

Linux ps命令:查看正在运行的进程
a:显示一个终端的所有进程,除会话引线外;
u:显示进程的归属用户及内存的使用情况;
x:显示没有控制终端的进程;
-l:长格式显示更加详细的信息;
-e:显示所有进程;

11.什么是进程调度?

所谓进程调度其实就是通过 “并发” “并行” 的方式让计算机可以同时执行多个进程(任务), 这就是我们平常为什么说操作系统是 多任务 的原因。
3.2.1、并行执行
多个 CPU 核心,在同时独立的运行多个进程。(每一个CPU都运行一个独立的进程)
3.2.2、并发执行
一个 CPU 核心,先运行一下进程1,再运行进程2,再运行进程3…
只要微观上切换的足够快,宏观上看起来就好像是3个进程同时运行一样。

12.Linux启动过程

1.内核引导
打开电源先bios自检。操作系统接管硬件后,读入/boot目录下的内核文件
2.运行init
Init程序首先要读取配置文件 /etc/inittab
运行级别0~6, 0停机,1单机、root、维护、禁止远程登录,2多用户,3完全多用户,4系统未使用、保留,5 x11控制台,6正常关闭并重启
3.系统初始化
Rc.sysinit是每个运行级别都要运行的脚本。
激活交换分区、检查磁盘、加载硬件、其他需要优先执行的任务
4.建立终端
Rc执行完之后返回init,基本系统环境配置好了,守护进程已经启动。打开六个终端便于用户登录。
运行mingetty程序,这个程序可以打开终端、设计模式。显示一个文本登录界面,输入用户名密码,作为参数传给login验证用户身份。
5.用户登录系统
登录方式:命令行、ssh、图形界面

13.虚函数

1.如果一个类含有一个虚函数,则系统会为这个类分配一个指针,指向一张虚函数表,表中每一项都指向一个虚函数地址。
2.在基类成员函数声明前面加上关键字virtual即可成为虚函数。
3.允许在派生类中重新定义与基类同名的函数,并且可以通过基类的指针或者引用来访问基类和派生类的同名函数

14.进程及线程区别,进程间通信和线程间通信的几种方式

进程:子进程是父进程的复制品,从父进程那里获得父进程的数据空间,堆和栈的复制品。

线程:相对于进程而言,可以和同进程的其他线程之间直接共享数据,而且拥有自己的栈空间,拥有独立序列。

共同点: 提高程序的并发效率,
不同点:
1.线程执行开销比较小,产生的速度快,通讯快,切换快,因为他们处于同一地址空间。但不利于资源的管理和保护,而进程相反
2.多进程中每个进程有自己的地址空间,线程则共享地址空间,线程使用公共变量或者内存的时候需要同步机制,但进程不用。

一、进程间的通信方式
1.管道( pipe ):
管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2.信号 (sinal ) :
信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
3.共享内存(shared memory ) :
共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

二、线程间的通信方式
1.锁机制:包括互斥锁、条件变量、读写锁
互斥锁提供了以排他方式防止数据结构被并发修改的方法。
读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
2.信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
3.信号机制(Signal):类似进程间的信号处理
线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。

14.死锁,死锁产生的条件,死锁解决办法

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
死锁产生的条件:
1.互斥
2.占有并等待
3.非抢占
4.循环等待
死锁解决办法:
1.通过协议来预防或避免死锁,确保系统不会进入死锁状态。
2.可以允许系统进入死锁状态,然后检测它,并加以恢复。
3.可以忽视这个问题,认为死锁不可能在系统内发生。
第三种解决方案为大多数操作系统所采用,包括 Linux 和 Windows。因此,应用程序开发人员需要自己编写程序,以便处理死锁。

15.查看进程(资源占用)的命令,top和ps有什么区别

ps 命令查看系统的瞬时信息

top 命令能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。
top 主要看 cpu,内存使用情况

计算机网络

1.关于路由器和交换机的区别

主要区别
1、路由器在网络层,路由器根据IP地址寻址,路由器可以处理TCP/IP协议,交换机不可以,交换机根据MAC地址寻址。交换机在数据链路层。
2.路由器可以把一个IP分配给很多个主机使用,这些主机对外只表现出一个IP。交换机可以把很多主机连起来,这些主机对外各有各的IP。
3.交换机分割冲突域,但不分割广播域,而路由器分割广播域。
4.路由器提供防火墙的服务,交换机不能提供该功能。

通俗解释:
我们每个人相当于主机,路由器相当于快递员,宿管大爷相当于交换机,学校是一个局域网
快递员根据学校地址(IP)把包裹送到学校,再根据公寓号(子网IP)把快递交给这个公寓的宿管大爷,宿管大爷根据你的名字(MAC)交给你。

2.TCP和UDP的区别

1.TCP是可靠传输,UDP是不可靠传输;
2.TCP面向连接,UDP无连接;
3.TCP传输数据有序,UDP不保证数据的有序性;
4.TCP不保存数据边界,UDP保留数据边界;
5.TCP传输速度相对UDP较慢;
6.TCP有流量控制和拥塞控制,UDP没有;
7.TCP是重量级协议,UDP是轻量级协议;
8.TCP首部较长20字节,UDP首部较短8字节;

用tcp的协议
SMTP/TELNET/HTTP/FTP
电子邮件、远程终端接入、万维网、文件传输

用udp的协议
DNS/TFTP/RIP/BOOTP,DHCP/SNMP/NFS/专用协议
域名映射、文件传输、路由选择、ip地址配置、网络管理、远程文件服务器、ip电话、流式多媒体通信

3.为什么是三次握手 而不是两次呢?

防止出现请求超时脏链接
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了,由于client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据,但server却以为新的运输连接已经建立,并一直等待client发来数据。所以没有采用“三次握手”,这种情况下server的很多资源就白白浪费掉了。

4.BGP协议 RIP(Routing information Protocol)路由信息协议

1.边界网关协议(BGP):路由器交换ip范围信息
2.路由信息协议(RIP):防止环路

RIP(Routing information Protocol)路由信息协议,是早期第一代动态路由协议,是一种基于距离矢量(Distance-Vector)算法来计算到达目的网络的最佳路径路由协议,它通过UDP报文进行路由信息的交换,使用的端口号为520,RIP是基于跳数(最多支持15跳)来衡量到达目的地址的距离,称为度量值,RIP协议有多个版本,分为v1/v2/ng版。

1.边界网关协议(BGP):
在BGP中,使用传输控制协议TCP。它是网格拓扑或设计的一种。它由两个独立的网络(自治系统或自治系统)交换路由信息来工作。这两个路由器同意交换有关如何达到某些IP范围的信息。BGP使用传输控制协议(TCP)端口179。

2.路由信息协议(RIP):
RIP代表路由信息协议,其中距离矢量路由协议用于数据/分组传输。在路由信息协议(RIP)中,最大跳数为15,因为它可以防止从源到目标的路由环路。与其他路由协议相比,RIP(路由信息协议)较差且规模有限,即小型网络。使用RIP的主要优点是它使用UDP(用户数据报协议)。
在这里插入图片描述

5.HTTP协议 与 TCP协议 的区别,Http报文格式,TCP三次握手

TCP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。
Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求。Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开,这个过程是很短的,所以Http连接是一种短连接,是一种无状态的连接。

http请求由三部分组成,分别是:请求行、消息头部、请求正文
(请求头:Host,User-Agent,Cookie,content-type)
在这里插入图片描述在这里插入图片描述
HEAD方法与GET方法几乎是一样的,对于HEAD请求的回应部分来说,它的HTTP头部中包含的信息与通过GET请求所得到的信息是相同的。

HTTP响应也是由三个部分组成,分别是:状态行、响应头、响应报文
(响应头:Sever,Date,Set-Cookie,content-type)
在这里插入图片描述

HTTP特点

无状态:协议对客户端没有状态存储,对事物处理没有“记忆”能力,比如访问一个网站需要反复进行登录操作
无连接:HTTP/1.1之前,由于无状态特点,每次请求需要通过TCP三次握手四次挥手,和服务器重新建立连接。比如某个客户机在短时间多次请求同一个资源,服务器并不能区别是否已经响应过用户的请求,所以每次需要重新响应请求,需要耗费不必要的时间和流量。
基于请求和响应:基本的特性,由客户端发起请求,服务端响应。请求和响应必须成对,先有请求后有响应

http协议默认端口:80 https协议默认端口:443

![在这里插入图片描述](https://img-blog.csdnimg.cn/f45f7ccd9325489f8b1728a94f4446ba.png

5.Fiddler抓包信息主要包括什么

请求的ID编号,状态码,协议,主机名,URL(请求的资源路径和文件名),内容类型,Body大小(Byte为单位),进程信息
修改代理

RIP算是工作在应用层吧,以路由器系统为载体
ARP协议在网络层,解析mac地址

6.广播地址是干嘛的

广播地址 (Broadcast Address)是专门用于同时向网络中所有 工作站 进行发送的一个 地址 。
IP网络上发送信息都是要有IP地址的,如果一个网络内有10台电脑,其中一台电脑要给所有的电脑发送信息,如果没有广播功能,那这台电脑需要发出9条信息,分别以9台电脑的地址标识。有了广播就方便了,发一个信息就好了,以广播地址标识,其他电脑都可以接收到。

7.DNS域名解析过程

DNS解析过程由本地设备的DNS服务模块发起查询请求然后经过路由提交到网络运营商DNS(Local DNS)进行查询,如果在运营商的DNS缓存中有之前其他用户查询后保存的缓存记录则可立即返回告知本地设备请求访问的域名所在IP地址。

8. udp和connect和tcp的connect有什么区别

1、UDP中可以使用connect系统调用。
2、TCP中调用connect会引起三次握手,client与server建立连结。
  UDP中调用connect内核仅仅把对端ip&port记录下来。
3、UDP中可以多次调用connect,TCP只能调用一次connect。

9. 五元组是哪五元?

源IP地址,源端口,目的IP地址,目的端口,和传输层协议

10. UDP编程有必要调用connect吗

1.效率变高了
没有调用connect的udp socket,只能调用sendto发送数据,我们可以看到sendto的参数比send要多,这就意味着每次系统调用的时候都会多拷贝一些数据到内核空间。

  1. 消耗变少了
    调用sendto的时候,内核就需要再次分配内存存放这些临时的数据结构,周而复始,就会形成一个 不断地分配和释放临时内存的过程。
    调用sendto的时候,内核就需要再次分配内存存放这些临时的数据结构,周而复始,就会形成一个 不断地分配和释放临时内存的过程。并且永久维护一个数据结构,存储这些地址信息,后面每次进行发送数据,内核就不需要再分配删除内存了。

  2. 错误信息的提示能够报上来了
    对于一个没有connect的udp socket, 内核将数据发出去之后,没有维护五元组,ICMP有错误返回的时候,内核就找不到是哪个 udp socket出的错,所以用户层也就无法收到这个错误信息的。

11.除了sendto、send,还有什么api实现传输

还有connect也可以触发tcp握手的动作,实现传输

12.Fork一个进程的整个过程

1.fork()函数其实是调用发起_fork()系统调用,控制权由用户态转为内核态,
2.内核会分配新的内存块和内核数据结构给子进程(也就是PCB task_struct结构体),
3.然后内核会将父进程的部分数据内容以二进制形式拷贝到子进程,
4.再将子进程加入到管理链表中
5.然后从内核态返回用户态(父进程fork返回进程pid,子进程返回0),

fork之前父进程独立执行,fork之后父子进程分别执行自己的执行流,但是谁先执行由调度器调度。

这里还有一点需要注意,当子进程刚被创建出来,父子进程不再写入的时候,父子进程是数据共享一份,代码独有,但是当有任意一方试图写入数据的时候,便已写时拷贝的方式各自拥有一份数据

13.两个进程管道通信的详细描述

1.Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间
2.任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信

在进程间完成数据传递需要借助操作系统提供特殊的方法,如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。随着计算机的蓬勃发展,一些方法由于自身设计缺陷被淘汰或者弃用。现今常用的进程间通信方式有:

管道 (使用最简单):管道是一种最基本的IPC机制,也称匿名管道,应用于有血缘关系的进程之间,完成数据传递。调用pipe函数即可创建一个管道。(亲缘关系)

1.管道的本质是一块内核缓冲区
2.由两个文件描述符引用,一个表示读端,一个表示写端。
3.规定数据从管道的写端流入管道,从读端流出。
4.当两个进程都终结的时候,管道也自动消失。
5.管道的读端和写端默认都是阻塞的。

信号 (开销最小)
共享映射区 (无血缘关系)
本地套接字 (最稳定)
共享内存

13.父子进程使用管道通信

一个进程在由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程间的通信(因此也不难推出,只要两个进程中存在血缘关系,这里的血缘关系指的是具有共同的祖先,都可以采用管道方式来进行通信)。父子进程间具有相同的文件描述符,且指向同一个管道pipe,其他没有关系的进程不能获得pipe()产生的两个文件描述符,也就不能利用同一个管道进行通信。

第一步:父进程创建管道
第二步:父进程fork出子进程
第三步:父进程关闭fd[0],子进程关闭fd[1]

13.Fork出来的进程和原来进程是同一块地址映射,怎么样做到子进程更改不影响父进程

1.fork时子进程获得父进程数据空间、堆和栈的复制,所以变量的地址(当然是虚拟地址)也是一样的。
2.每个进程都有自己的虚拟地址空间,不同进程的相同的虚拟地址显然可以对应不同的物理地址。因此地址相同(虚拟地址)而值不同没什么奇怪。
3.fork子进程完全复制父进程的栈空间,也复制了页表,但没有复制物理页面,所以这时虚拟地址相同,物理地址也相同,但是会把父子共享的页面标记为“只读”(类似mmap的private的方式),如果父子进程一直对这个页面是同一个页面,知道其中任何一个进程要对共享的页面“写操作”,这时内核会复制一个物理页面给这个进程使用,同时修改页表。而把原来的只读页面标记为“可写”,留给另外一个进程使用。

14.网络路由转发的过程

路由接收数据包→查看目的地址→与路由表进行匹配找到转发端口→转发到该端口

网络层的IP数据包是如何在网络中传输的呢?
答案是根据目的IP地址查找路由表转发的

路由: 路由是指路由器从一个接口上收到数据包,根据数据包的目的地址进行定向并转发到另一个接口的过程。

每一个路由器负责将数据包按照最优的路径向下一跳路由器进行转发,通过多个路由器一站一站的接力,最终将数据包通过最优路径转发到目的地。当然有时候由于实施了一些特别的路由策略,数据包通过的路径可能并不一定是最佳的。

路由器: 路由器是网络层的设备,(交换机是数据链路层的设备)用于指导IP报文转发。路由器也可以称之为网关设备。

路由表: 每个路由器中都保存着一张路由表,表中每条路由项都指明了数据包要到达某网络或某主机应通过路由器的哪个物理接口发送,以及可到达该路径的哪个下一个路由器,或者不再经过别的路由器而直接可以到达目的地。

14.路由器工作原理:

1、路由器收到一个数据包后,会检查其目的IP地址,然后依据最长匹配原则查找路由表;

2、如果查找到匹配的路由表项之后,路由器会根据该表项所指示的出接口信息和下一跳信息将数据包转发出去;

如果没有找到,会查找是否有缺省路由,找到的话会依据出接口信息和下一跳信息将数据包转发出去;

3.如果都没有找到,数据包会被丢弃;

15.静态路由怎么配置

路由A设置:
1.进入接口
2.配置接口ip和子网掩码
3.启用接口
(config)#interface f0/1 (进入接口f0/1)
(config-if)#ip address 192.168.10.254 255.255.255.0 (设置接口ip地址和子网掩码)
#no shutdown (启用接口)

(config)#interface f0/0
(config-if)#ip address 192.168.2.1 255.255.255.0
(config-if)#no shutdown

路由B设置:
路由设置 ip route 目标网段掩码 下一跳ip地址
路由A(config)#ip route 192.168.30.0 255.255.255.0 192.168.20.2
路由B(config)#ip route 192.168.10.0 255.255.255.0 192.168.20.1

最后测试网络是否ping通
10.0网段与30.0网段主机ping通

16.路由器基本命令及配置命令

直联路由命令
在这里插入图片描述
静态路由命令
在这里插入图片描述

默认路由命令
在这里插入图片描述

17.路由器的配置方法

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

18.upd怎么判断是否成功发送信息了?

udp是一种不安全的协议。只管发送成功,不管接收是否成功。
但通常在网络比较好的状态下(比如局域网内),丢包的概率非常小,但如果网络环境不好,则非常可能丢包。
所以你要是仅仅判断send是否成功,要是程序能正常运行且端口正常,一般来说一定能成功

但是可以你自己实现,你想另一端发送一个数据包,你让另一端接受到数据后向你发送一个确认数据包,如果你发送以后受到一个确认数据包,就是连接成功了
还有就是在通信过程中服务器可以定时想客户端发送数据包,让客户端回应,以确认其在线

19.子网掩码和子网划分的问题

子网划分简单来说就是把一个两级IP地址划变为三级地址,相当于从原来的主机号中借用若干个位作为子网号。

一个B类网络被划分了三个子网,每个子网此时其实已经处于不同网段了。子网划分是一个单位内部的事情,对外仍是一个二级IP地址。

凡是从其他网络发送给本单位某个主机的 IP 数据报,仍然是根据 IP 数据报的目的网络号 net-id,先找到连接在本单位网络上的路由器。然后此路由器在收到 IP 数据报后,再按目的网络号 net-id 和子网号 subnet-id 找到目的子网,最后就将 IP 数据报直接交付目的主机。

划分子网时有以下几点需要注意:
● 子网的划分并没有改变原来的网络号,只是将主机号部分再划分。因此,单看一个IP地址是无法判断该地址是否进行了子网划分的。
● 子网号能否为全0和全1需要根据题目来判断,因为对分类IP地址进行划分时,子网号不能为全0或全1 ,但CIDR可以。
● 无论是IPv4地址还是CIDR,主机号都不能全为0(全0表示子网网络号)或全为1(全1位广播地址)。

子网掩码是用来划分子网的网段和遮掩部分IP地址

子网掩码的划分规则如下:
● 子网掩码长度:32位
● 某位=1:IP地址中对应的网络号或子网号
● 某位=0:IP地址中对应位为主机号

20.网络协议-两个不同的局域网中的机器如何通讯

不同网段:

1.主机A在准备发向主机B的数据中,封装好自己的IP地址和MAC地址,同时也封装好目标主机B的IP地址,
2.再通过ARP去广播去请求得到网关的MAC地址,因为网关必须和本机在同一网段,网关能够收到这个ARP请求并能正确回应给主机A,这时主机A在数据包中封装好自己和主机B的IP地址和MAC地址,把数据包从网卡发出去
3.网关收到这个数据包后,发现目标MAC是自己,而目标IP不同,所以它不可以再往上打开这个数据包,它要做的工作就是把这些数据包发给下一跳路由器,结束。

注释:((如果网关自身就是一台路由器的话),如果网关是一台普通PC,那么它就发给路由器,让路由器把这些数据包正确传输到远程目标网络,到达远程网络后,它们的网关再将数据包发给数据包中的目标IP,即源主机A苦苦寻找的目标主机B,从而真正结束不同网络之间的通信,)
注释:(1.因为不是一个网段,所以需要先发给网关,配置好静态路由,再利用ARP协议获得的mac地址,发送包
2.包到达网口后,发现 MAC 一致,将包收进来,再转发。

同网段:

1.主机A知道自己的IP和MAC地址及主机B的IP
主机A通过封装好的源IP和目标IP,通过子网掩码计算一下,发现源IP和目标IP恰好在同一个IP网络内

2.主机A就向本网段发过一个ARP请求,同网段主机B能够收到来自主机A的ARP请求,构建一个包括自己的MAC地址的ARP回应包,回应给主机A

3.主机A再向网络发送数据包,包括源IP和源MAC以及目标IP和目标MAC,因为目标地址在本网段,所以本网段所有主机都能收到这个数据包,但只有真正的目标主机B能够打开这些数据包

20.两台pc中间有两台路由,问pc1和pc2的源ip目的ip源mac目的mac

如:A访问B,
首先对比是否同一子网,如果是,检查ARP表,有B的MAC就直接发送,没有就发送ARP请求.如果否,发送到默认网关C,源IP为A,源MAC为A,目的IP为B,目的MAC地址为C,
C接收到这个包,检查路由表,发送到下一跳D,源IP为A,源MAC为C,目的IP为B,目的MAC为D……
如此循环,直到发送到B.

20.动态路由,静态路由,直连路由哪个优先级更高

直连路由不需要配置,路由器自动感知链路,自动关联接口
静态路由,网络管理员使用命令配置路由
动态路由,路由器自动建立路由表,根据网络拓扑状态自动调整

21.什么是三次握手

第一次握手:
建立连接时,客户端发送SYN包(SYN=x)到服务器,并进入SYN_SENT状态,等待服务器确认;

第二次握手:
服务器收到SYN包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态

第三次握手:
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态

22.四次挥手

1.第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于FIN_WAIT1状态。
2、第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 + 1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT状态。
3、第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
4、第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 + 1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态
5、服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。

23.三次握手和四次挥手发生在什么时候?

发生在 TCP/IP协议 的 传输层

24.为什么挥手要比握手多一次?

关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,
所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。
只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。
故需要四步握手。

用我自己的话理解就是:

A给B发消息:“我打算关闭了!”
B给A回消息:“你的消息我收到了!但是我活还没干完,等我一会!”
B给A回消息:“好了,我活干完了!”
A给B发消息:“好的,我挂断了!”——同时等待一段时间后关闭
B收到消息后立即关闭

25.网络拓扑画过吗?

网络拓扑图是指由网络结点设备和通信介质构成的网络结构图
主要有星形、环状、总线型

26.OSPF与RIP的定义与区别

Rip分布式的基于距离向量的路由选择协议,ospf分布式的基于链路状态的路由选择协议
Rip和相邻的路由器交换路由表,固定时间间隔交换
Ospf向本自治系统所有路由器发信息,交换的是本路由器周边网络的拓扑,当网络状态改变时,洪泛法发送信息
Rip知道当前路由器到所有路由器的距离以及下一跳路由器是哪个,不知道全网的拓扑结构。好消息传的快,坏消息传的慢,慢收敛
Ospf快收敛
Rip用udp传送,ospf用ip数据报传送

27.HTTP/HTTPS的区别

1.http是超文本传输协议,明文传输。https是用SSL协议加密后的http协议,属于加密传输协议。
2.http端口为80,https端口为443.
3.http连接简单,无状态。https加密传输、身份认证,安全。

28.五层,OSI七层模型及常见协议

在这里插入图片描述
在这里插入图片描述
五层模型:
1、物理层:负责光电信号传递方式。集线器工作在物理层。以太网协议。
2、数据链路层:负责设备之间的数据帧的传输和识别。交换机工作在数据链路层。例如网卡设备的驱动,帧同步,冲突检测,数据差错校验等工作。
3、网络层:负责地址管理和路由选择。路由器工作在网络层。
4、传输层:负责两台主机之间的数据传输。
5、应用层:负责应用程序之间的沟通。网络编程主要针对的就是应用层。

29.隧道技术,常用的隧道技术

隧道技术的实质是用一种网络层的协议来传输另一种网络层协议,其基本功能是封装和加密,主要利用网络隧道来实现。
vpn点对点传输就利用的是隧道技术

常用的隧道技术
二层数据链路层:ppp协议
三层网络层:IPv6隧道,ICMP隧道,GRE隧道
传输层:TCP隧道,UDP隧道,常规端口转发
应用层:SSH隧道,HTTP隧道,HTTPS隧道,DNS隧道

30.BGP协议

1.我们BGP扩展协议来传递二层或三层的可达性信息
2.它颠覆了传统二层VPN通过转发面来学习MAC地址的机制,引入了控制面,利用BGP扩展协议来传递MAC信息
3…BGP协议是外部网关协议,由于互联网规模太大,使得自治系统AS之间路由选择非常困难。BGP协议通过在自治系统之间交换“可达性”信息。例如,告知相邻路由器:达到目的网路N可经过自治系统ASx。
4.BGP 只能是力求寻找一条能够达到目的网络且比较好的路由,而并非最佳路由。BGP采用了路径向量路由选择协议。

31.三种路由协议比较RIP,OSPF,BGP

1.RIP是一种分布式的基于距离向量的内部网关路由选择协议,通过UDP报文来交换路由信息,是应用层协议。
2.OSPF是一种基于链路状态协议的内部网络路由选择协议,交换的信息量大,所以不使用传输层协议,而直接采用IP数据报传送,是网络层协议。
3.BGP是一个基于路径向量协议的外部网关协议,在不同的自治系统之间交换路由协议,采用TCP报文交换路由协议,是应用层协议。

在这里插入图片描述

31.为什么应用开发人员宁愿在UDP之上构建应用,而不选择在TCP上构建应用?

1.能够及时传递应用数据:采用UDP时,只要应用进程将数据传递UDP,UDP就会将此数据打包进 UDP报文段并立即将其传递给网络层。在另一方面,TCP有一个拥塞控制机制,以便当源和目的主机间的一条或多条链路变得极度拥塞时来遏制运输层TCP发送方。TCP仍将继续重新发送数据报文段直到目的主机收到此报文并加以确认,而不管可靠交付需要用多长时间。因为实时应用通常要求最小的发送速率,不希望过分地延迟报文段的传送,且能容忍一些数据丢失,TCP服务模型并不是特别适合这些应用的需要。

2.无需连接建立:TCP在开始数据传输之前要经过三次握手。UDP却不需要任何准备即可进行数据传输。因此UDP不会引入建立连接的时延。这可能是 DNS运行在 UDP之上而不是运行在TCP之上的主要原因(如果运行在TCP上,则 DNS会慢得多)。

3.无连接状态:TCP需要在端系统中维护连接状态。此连接状态包括接收和发送缓存、拥塞控制参数以及序号与确认号的参数。UDP不维护连接状态,也不跟踪这些参数。因此,专门用于某种应用的服务器当应用程序运行在UDP之上而不是运行在TCP上时,—般都能支持更多的活跃客户。

4.分组首部开销小:每个TCP报文段都有20字节的首部开销,而 UDP仅有8字节的开销。

31.数据包的封装过程

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

31.访问http请求到主页过程

1.DNS解析:浏览器查询DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系统的DNS缓存、读取本地的Host文件和向本地DNS 服务器进行查询等。对于向本地DNS服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;

2.TCP连接:浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;3.发送HTTP请求:TCP连接建立起来后,浏览器向服务器发送HTTP请求;

4.服务器处理请求并返回HTTP 报文:服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;

5.浏览器解析渲染页面:浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。

6.连接结束。

在这里插入图片描述

数据结构

1.堆这个数据结构你了解吗?有哪些应用场景?

场景:堆排序和优先队列

2.大根堆和小根堆有什么区别?

父节点的值大于或者小于两个子节点

3.哈希表你了解吗?哈希表是怎么实现的?(数组+链表)

通过把码值映射来访问,加快查找速度

4.C语言用过吗?字符串拷贝函数有哪些?

Strcpy

数据库

1.简述mysql和redis区别

redis: 内存型非关系数据库,数据保存在内存中,速度快
mysql:关系型数据库,数据保存在磁盘中,检索的话,会有一定的IO操作,访问速度相对慢

2.mysql 事务的特性

ACID 原子性、一致性、隔离性、持久性

3.B树和B+树的区别?

1、B-树是一类树,包括B-树、B+树、B*树等,是一棵自平衡的搜索树,它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点。

B-树是专门为外部存储器设计的,如磁盘,它对于读取和写入大块数据有良好的性能,所以一般被用在文件系统及数据库中。
2、B+树是B-树的变体,也是一种多路搜索树, 它与 B- 树的不同之处在于:
所有关键字存储在叶子节点出现,内部节点(非叶子节点并不存储真正的 data)
为所有叶子结点增加了一个链指针
因为内节点并不存储 data,所以一般B+树的叶节点和内节点大小不同,而B-树的每个节点大小一般是相同的,为一页

4.什么是死锁?怎么解决?

死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象

常见的解决死锁的方法:
如果不同程序会并发存取多个表, 尽量约定以相同的顺序访问表,可以大大降低死锁机会。
在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;

5.什么是数据库查询很慢,分析原因

没有用索引
i/o吞吐量小
内存不足
网速慢
查询结果数据量过大
锁或者死锁
读写竞争资源
查询语句没有优化
优化措施:
数据、日志、索引放到不同的i/o设备上
纵向、横向分隔表,减小表的尺寸
升级硬件
优化索引
提升网速
扩大服务器内存

6.简单sql(按分数排序)

直接按照学生student分组 然后sum(成绩 score)
SELECT studentid,SUM (score) FROM student_score GROUP BY studentid ORDER BY a DESC

7.drop,truncate,delete 三者的区别

drop:删除内容和定义,释放空间。(表结构和数据一同删除)
【drop语句将删除表的结构,被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。】

drop table user;

truncate:删除内容,释放空间,但不删除定义。(表结构还在,数据删除)

【truncate table 权限默认授予表所有者、sysadmin 固定服务器角色成员、db_owner 和 db_ddladmin 固定数据库角色成员且不可转让。】

truncate table user;

delete:删除内容,不删除定义,也不释放空间。

delete from user;

Python

1.浅拷贝和深拷贝

深浅拷贝
浅拷贝:创建新对象,其内容是原对象的引用,只拷贝一层,在类的任何成员中所做的更改也将影响它的原始副本

深拷贝:和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。深拷贝出来的对象是一个全新的对象,不再与原来的对象有任何关联。原始副本中所做的更改不会影响使用该对象的任何其他副本,因此深拷贝会使程序的执行速度变慢。

实现方式:

1.JSON.parse()和JSON.stringify()

2.函数库lodash的_.cloneDeep方法

3.手写递归实现
浅拷贝:直接循环遍历,将需要克隆对象的属性依次添加到新对象
深拷贝:
原始类型,无需继续拷贝,直接返回;
如果是引用类型,创建一个新的对象,遍历需要克隆的对象,将需要克隆对象的属性执行深拷贝后依次添加到新对象上。

function clone(target) {
    if (typeof target === 'object') {
        let cloneTarget = {};
        for (const key in target) {
            cloneTarget[key] = clone(target[key]);
        }
        return cloneTarget;
    } else {
        return target;
    }
};

4.应用场景:

1:从服务器fetch到数据之后我将其存放在store中,通过props传递给界面,然后我需要对这堆数据进行修改,那涉及到的修改就一定有保存和取消,所以我们需要将这堆数据拷贝到其它地方。

2:当你想使用某个对象的值,在修改时不想修改原对象,那么可以用深拷贝弄一个新的内存对象。像es6的新增方法都是深拷贝,所以推荐使用es6语法。

2.多线程、多进程和协程的区别与联系

多线程:
线程是进程的一个实体,是CPU进行调度的最小单位,他是比进程更小能独立运行的基本单位。
线程基本不拥有系统资源,只占用一点运行中的资源(如程序计数器,一组寄存器和栈),但是它可以与同属于一个进程的其他线程共享全部的资源。
提高程序的运行速率,上下文切换快,开销比较少,但是不够稳定,容易丢失数据,形成死锁。

多进程:
进程是系统进行资源分配的最小单位,每个进程都有自己的独立内存空间,不用进程通过进程间通信来通信。
但是进程占据独立空间,比较重量级,所以上下文进程间的切换开销比较大,但是比较稳定安全。

协程:
协程是更小的执行单位,是一种轻量级的线程,协程的切换只是单纯的操作CPU的上下文,所以切换速度特别快,且耗能小。

gevent是第三方库,通过greenlet实现协程,其基本思想是:
当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

3.并发和并行的理解?

1.并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生;

2.并行是在不同实体上的多个事件,并发是在同一实体上的多个事件;

4.python 装饰器函数装饰器与类装饰器 迭代器和生成器

函数装饰器:函数能作为参数传递给其他函数,可以被赋值给其他变量,可以作为返回值,可以被定义在另外一个函数内;

类装饰器:类具有__call__方法,当使用 @ 形式将装饰器附加到函数上时,就会调用此方法;

装饰器是一种增加函数或类的功能的方法,可以快速的给不同的函数或者类插入相同的功能。

迭代器:是一个可以记住遍历位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
迭代器有两个基本方法:iter()和 next()。其中iter( )方法用来创建迭代器对象;next()用来遍历对象的元素。

生成器:使用生成器可以生成一个值的序列用于迭代,并且这个值得序列不是一次生成的,而是使用一个在生成一个,可以使程序节约大量内存。
使用了yield的函数被称为生成器,与普通函数不同的是,生成器将返回一个迭代器的函数,并且生成器只能用于迭代操作

应用场景: 插入日志、性能测试、事务处理、缓存、权限校验等

5.元组是不可变的,元组中存一个列表,列表中元素是否可以改变?

可以

6.init和new

new 负责对象的创建,而 init 负责对象的初始化。
new:创建对象时调用,会返回当前对象的一个实例
init:创建完对象后调用,对当前对象的一些实例初始化,无返回值

7.sizeof和strlen的区别

sizeof是数据类型所占的空间大小,strlen是字符串长度
sizeof是运算符,strlen是函数
子函数传参,sizeof会把传进来的数组当指针,sizeof为4

8.py数据类型

不可变类型:Numbers(数字) String(字符串) Tuple(元组)

可变类型:List(列表) Set(集合) Dictionary(字典)

9.java数据类型

Java中主要有八种基本数据类型:

1、整型:byte、short、int、long

2、字符型:char

3、浮点型:float、double

4、布尔型:boolean

10.数据结构

哈希表(Hash):根据键和值 (key和value) 直接进行访问的数据结构

队列(Queue):队列的特点是先进先出

树(Tree):有限节点组成一个具有层次关系的集合
满二叉树:除了叶子节点,每个节点都有两个子节点
完全二叉树:除开最后一层,每一层都是满二叉树,且最后一层的结点依次从左到右分布

堆(Heap):堆可以看做是一颗用数组实现的二叉树,所以它没有使用父指针或者子指针
大根堆(上面的节点大于下面的节点) 小根堆(下面的节点大于上面的节点)

数组(Array):数组是有序元素的序列,在内存中的分配是连续的。缺点是:删除增加、删除慢

栈(Stock):先进后出从栈顶放入元素

链表(Linked List):链表是由一系列节点Node(也可称元素)组成,由数据域和指针域。优点:新增节点、删除节点快

图(Graph):图是一系列顶点(元素)的集合,这些顶点通过一系列边连接起来组成图这种数据结构
有向图:有指向,有箭头
无向图:无指向,无箭头

广度搜索:搜索到一个顶点时,先将此顶点的所有子顶点全部搜索完毕,再进行下一个子顶点的子顶点搜索;

深度搜索:搜索到一个顶点时,先将此顶点某个子顶点搜索到底部(子顶点的子顶点的子顶点…),然后回到上一级,继续搜索第二个子顶点一直搜索到底部;

SpringBoot和Mybatis

Mybatis是什么

MyBatis 是一个(ORM)持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java为数据库中的记录。

Springboot是什么

SpringBoot通过.properties或者.yml文件替代了Spring繁杂的XML配置文件,它是Spring组件的一站式解决方案,采取了习惯优于配置的方法。

,同时支持@ImportResource注解加载XML配置。

Spring Boot还提供了嵌入式HTTP服务器、命令行接口工具、多种插件等等,使得应用程序的测试和开发简单起来。

Spring Boot 优点:独立运行、简化配置、自动配置和无需部署war文件等等

Spring Boot 的配置文件有哪几种格式?它们有什么区别?

主要有.properties 和 .yml格式,它们的区别主要是书写格式不同。
另外.yml 格式不支持 @PropertySource 注解导入配置。

你用过的springboot注解

6.1 controller层
@Controller@ResponseBody 用于注解 Controller 类,等效于 @RestController 注解。
@RequestMapping 注解用于匹配什么样的请求,可以有6个属性:

1、value:请求的url,比如 /user/getUserInfo。
2、method:请求的方法,比如   @GetMapping("/test")   @ResponseBody   PostMapping("/test")
3、consumes:请求的内容类型,即http请求报文中的 Content-Type 字段是什么。
4、produces:返回报文的内容类型。
5、params:请求中必须包含哪些<参数,参数值>6、headers:请求报文中必须包含哪些请求头部字段。

@RequestParam 注解用于匹配请求的参数,一般匹配独立的,单一的参数,可以有3个属性:

1、value:参数名。
2、required:请求是否必须包含该参数,如果没有包含,则抛出异常。
3、defaultValue:如果参数为空,则使用这个默认值作为参数值。

@RequestBody 注解用于匹配请求参数,匹配对象类型的参数,有1个属性,required(同上)。


6.2 service层
service层包含了service接口和service接口实现类,在service接口中定义需要的方法,在service接口实现类中实现具体的方法(需要调用dao层的Mapper@Service 用于注解service接口实现类。
@Autowired@Resource 注解用于引入dao层的mapper,建议使用 @Resource,按照名字(前提是项目里的命名很规范)去引入指定的 mapper。

6.3 dao层
dao层是数据持久层。
@Parm 注解用于标注mapper接口中的方法的参数,比如 public User getUser(@Parm("id") int  userId); @Parm括号里的id对应数据库里的字段,userId对应Java中的字段。

机器学习及深度学习

什么是经验风险?什么是结构风险?

经验风险:关于训练数据集的平均损失的称为经验风险
度量平均意义下模型预测效果的好坏,经验风险越小,模型越复杂

结构风险:在经验风险上加上模型复杂度
结构风险强调的是模型能力太强,把样本中的噪声都学进去了,对于测试样本的泛化能力很差,需要引入复杂度较低的模型去学习

前向传播和反向传播

前向传播:将上一层的输出作为下一层的输入,并计算下一层的输出,一直到运算到输出层为止
反向传播:计算梯度,改变参数,通过对参数求导

损失函数和代价函数

损失函数(loss function)预测的输出值和真实值之间的误差。(计算的是一个样本的误差)

1.损失函数越小越好
2.计算实际输出与目标之间的差距
3.为更新输出提供依据(反向传播)损失很小的时候就不用再继续传播了

反向传播是更新权重w和b的过程,当损失函数为0时,表示预测值达到了真实值,参数不需要再更新了

损失函数:

均方差(Mean Squared Error,MSE)、平均绝对误差(Mean Absolute Error Loss,MAE)

MAE与MSE的区别:
1.MSE比MAE能够更快收敛:当使用梯度下降算法时,MSE损失的梯度为,而MAE损失的梯度为正负1。
2.MSE的梯度会随着误差大小发生变化,而MAE的梯度一直保持为1,这不利于模型的训练
3.MAE对异常点更加鲁棒:从损失函数上看,MSE对误差平方化,使得异常点的误差过大;从两个损失函数的假设上看,MSE假设了误差服从高斯分布,MAE假设了误差服从拉普拉斯分布,拉普拉斯分布本身对于异常点更加鲁棒(差异点对模型影响小)

代价函数:整个训练集上所有样本误差的平均

激活函数

激活函数:主要作用是提供网络的非线性建模能力

就是把当前特征空间通过一定的线性映射转换到另一个空间,让数据能够更好的被分类。

sigmoid、 tanh、ReLU

你用过的python库

torch:张量的有关运算。如创建、索引、链接、转置、加减乘除、切片等。
matplotlib:画图库
numpy:处理数组
TensorFlow
Pandas:有两种数据结构: Series 和 DataFrame

注意力机制

先降维再生维(2,512,8,8) -> (2,512,1,1)-> (2,512,8,8)

注意力机制代码:

class SELayer(nn.Module):
    def __init__(self, channel, reduction=4):
        """ SE注意力机制,输入x。输入输出特征图不变
            1.squeeze: 全局池化 (batch,channel,height,width) -> (batch,channel,1,1) ==> (batch,channel)
            2.excitaton: 全连接or卷积核为1的卷积(batch,channel)->(batch,channel//reduction)-> (batch,channel) ==> (batch,channel,1,1) 输出y
            3.scale: 完成对通道维度上原始特征的标定 y = x*y 输出维度和输入维度相同

        :param channel: 输入特征图的通道数
        :param reduction: 特征图通道的降低倍数
        """
        super(SELayer, self).__init__()
        # 自适应全局平均池化,即,每个通道进行平均池化,使输出特征图长宽为1
        self.avg_pool = nn.AdaptiveAvgPool2d(1)

        # 全连接的excitation
        self.fc = nn.Sequential(
            nn.Linear(channel, channel // reduction),
            nn.ReLU(inplace=True),
            nn.Linear(channel // reduction, channel),
            nn.Sigmoid()
        )
        # 卷积网络的excitation
        # 特征图变化:
        # (2,512,1,1) -> (2,512,1,1) -> (2,512,1,1)
        self.fc2 = nn.Sequential(
            nn.Conv2d(channel, channel // reduction, 1, bias=False),
            nn.ReLU(inplace=True),
            nn.Conv2d(channel // reduction, channel, 1, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        # (batch,channel,height,width) (2,512,8,8)
        b, c, _, _ = x.size()
        # 全局平均池化 (2,512,8,8) -> (2,512,1,1) -> (2,512)
        y = self.avg_pool(x).view(b, c)
        # (2,512) -> (2,512//reducation) -> (2,512) -> (2,512,1,1)
        y = self.fc(y).view(b, c, 1, 1)
        # (2,512,8,8)* (2,512,1,1) -> (2,512,8,8)
        pro = x * y
        return x * y

  • 2
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值