正文前面先一个碎碎念,放在后面的话可能就没人看了233。
我本科非科班,秋招找非技术岗工作失败(无法通过群面)于是春招转码了。谁又能想到春招形势严峻比秋招还严峻….
我太难了我太难了!!!!
2月末开始投简历,3月份开始面了tplink、字节、美团、广立微电子这四家公司,然后这边最近春招结束,受了牛油们的很多帮助!感谢!所以来发下自己整理的一些知识点来回馈牛油,或许明年有人能用上?
我春招投的岗位都是测开/测试,测试涉及的东西太多啦反正你最好啥都懂呗,面试常见题以及我被问到过的题都加进去了,Python和操作系统部分比较详细,还有计算机网络也比较重点,然后添了些小姐妹理出来的测试基础和Linux常用操作!数据库、数据结构、C、算法就一点点没来得及理了先上岸了2333。
内容的话大部分来自牛客和谷歌,有些口语化的地方是我写的但是我想主要就是整理(东抄抄西抄抄),应该不会涉及什么版权问题吧233
字节和美团的面试我写了面经挺有趣的大家可以去看,tp我觉得这面试没什么参考价值主要就是靠学校和成绩单保命所以没发。
整个内容两万多字,全背下来应付面试抱佛脚扯扯没什么问题。
但骗到offer之后还是要补一下学的更全面点不能光会说呀2333。
------------------------------------广告插播------------------------------------
另外有些小伙伴私信问我有些什么学习资料,那我补充一下。我主要就是刷leetcode和《剑指offer》,然后资料来源谷歌百度牛客…有些东西就没有系统学,面试的时候有点憨憨。再来一次的话肯定是应该更早安排更系统的去学。
会的东西当然是越多越好,但是一定要保证有一门是比较 深入的了解的,不能太浅尝辄止走马观花哈~
算法这个东西我觉得还是挺重要的,我要是当时这方面能力更强的话薪资水平应该能不止白菜。但当时一是没有时间准备二是也没有资源,现在牛客这边正好有套算法课程!!这个课我最近听了听感觉就挺好,思路清晰老师也挺好玩的,现在这个时间段我觉得同学们一定要抓住机会好好学习呀!
然后是用我这的优惠码:AQDLDbj 或者直接在下面的链接买,就能优惠140元!
购课链接:牛客算法中级班_牛客网
其实我觉得要是能帮助找到更好的工作这买课多少钱优惠多少钱都是小钱啦,但主要是希望大家买了的课能好好学,收藏了我的帖子的话也要能好好看。别放在收藏夹里吃灰呀!!
新一届秋招又快来了,大家加油呀!!
------------------------------------插播结束------------------------------------
祝大家都能拿到自己满意的offer呀!!
要是有什么错误我先对不起(跪),一定要联系我改掉啊不能误导人!!
Python
Python为什么是解释型语言
顺序执行的 没有静态检查 没有编译链接过程 可以交互式运行
c语言类型不对是编译抛的错误,python类型不对是运行抛的错误
也就是python是一条条运行的,c需要整个编译过了才能运行
面向对象和面向过程的区别
面向对象是把构成问题的事务分解成各个对象,建立对象来描述某个事务在解决问题的步骤中的行为;
面向过程是分析出解决问题所需要的步骤,然后用一些函数把这些步骤一步步实现,使用的时候依次调用函数就行了。
Python有什么优势
解释型,语法简单易懂,可读性强
有很多库可以用,可以让我们站在巨人的肩膀上简单的实现想要的功能
可扩展,和其他编程语言或其他软件有可连接的接口
免费开源、可移植
自动内存管理,让程序员可以专注于代码的实现
缺点:
他的可解释特征使其运行速度变慢
动态语言的特点可能会增加运行时错误。
装饰器
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,它接受一个函数作为参数,并返回一个函数,利用python的@语法来放置
功能:1.引入日志;2.函数执行时间统计;3.执行函数前预备处理;4.执行函数后清理功能;5.权限校验;6.缓存
python 装饰器@staticmethod和@classmethod区别和使用
@classmethod:类方法,类方法是给类用的,类在使用时会将类本身当做参数传给类方法的第一个参数,python为我们内置了函数classmethod来把类中的函数定义成类方法。
@staticmethod:静态方法
用上面两个装饰器就可以不用在实用类前对类进行实例化了,
@property:将一个实例方法提升为属性,便于访问
写一个装饰器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import functools
import time
def print_run_time(func):
@functools.wraps(func) def wrapper(*args,**kw):
local_time=time.time()
func(*args,**kw)
t=time.time()-local_time
print(t)
return wrapper
@print_run_time
def test(x):
for i in range(1000):
print(x,end=‘’)
print(‘\n’)
return x
test(1)
functools.warp方法是把被wrapped的函数的属性传递给wrapper的函数,不写的话不支持参数
深拷贝、浅拷贝和等号赋值
深拷贝:新建一个对象,把原来对象的内存完全复制过来,改变复制后的对象,不会改动原来内存的内容。(两个对象在复制之后是完全独立的对象)
等号赋值:相当于为原来的对象打一个新的标签,两个引用指向同一个对象,修改其中的一个,另一个也会产生变化
浅拷贝:两种情况,1. 浅拷贝的值是不可变对象(数值、字符、元组)时,和等于赋值一样,对象的id值和浅拷贝原来的值相同;2. 如果是可变对象(列表、字典等),a. 一个简单的没有嵌套的对象,复制前后的对象相互之间不会影响,b. 对象中有复杂子对象,如列表嵌套,如果改变原来的对象中复杂子对象的值,浅拷贝的值也会受影响,因为在浅拷贝时只复制了子对象的引用(只拷贝父对象)。
在python中如何实现多线程
Thread,新建线程,然后可以用GIL实现线程通信
GIL
GIL(全局解释锁)能确保一次执行一个线程,线程轮流保存GIL并且在把他传给下一个线程之前执行一些操作,以达到多个进程在CPU上轮流运行,但是这个转换速度很快,让我们觉得他是并行的。
类
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类的继承
当一个类继承自另一个类,它就被称为一个子类/派生类,继承自父类/基类/超类。它会继承/获取所有类成员(属性和方法)。
Python如何内存管理
-
引用计数:python内部使用引用计数,来保持追踪内存中的对象,Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。
-
垃圾回收:python会检查引用计数为0的对象,清除其在内存占的空间;循环引用对象则用一个循环垃圾回收器来回收
-
内存池机制:在Python中,许多时候申请的内存都是小块的内存,这些小块内存在申请后,很快又会被释放,由于这些内存的申请并不是为了创建对象,所以并没有对象一级的内存池机制。这就意味着Python在运行期间会大量地执行malloc和free的操作,频繁地在用户态和核心态之间进行切换,这将严重影响Python的执行效率。为了加速Python的执行效率,Python引入了一个内存池机制,用于管理对小块内存的申请和释放。
a) Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
b) Python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的 malloc。另外Python对象,如整数,浮点数和List,都有其独立的私有内存池,对象间不共享他们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
Python垃圾回收机制
(自动处理分配回收内存的问题,没用了内存泄漏的隐患),以引用计数机制为主,标记-清楚和分代收集两种机制为辅
计数机制就是python中的每一个对象都有一个引用计数的值,当有引用的时候,这个值会增加,引用他的对象被删除时,这个值减小,引用计数的值为0时,该对象生命结束,python会把这段内存自动回收。(缺点,循环引用,如果l1和l2相互引用,没用其他的对象引用他们,这两段内存永远无法被回收)
猴子补丁
在运行期间动态修改一个类或模块,比较灵活?
为什么要用猴子补丁:
引用通用库里的模块,又想丰富模块的功能,就可以用猴子补丁。
参数,传参
位置参数和关键字参数的区别
args一定要在kwargs前面
*args和kwargs的含义
不知道向函数传递多少参数时,比如传递一个列表或元组,就使用args
def func(*args):…
Func(1,2,3,4,5)
不知道该传递多少关键字参数时,使用**kwargs来收集关键字参数(keyword argument)
def func(**kwargs):…
Func(a=1,b=2,c=3)
全局变量和局部变量
常用方法
join()和split()
join(),把指定的字符串添加到字符串中,也可以把join后面带的一个含字符串的列表用指定的字符串连接起来
split(),把字符串用指定字符分割,结果是一个列表
strip(), lstrip(), rstrip()
移除字符串两边的空格
is家族 检查字符串……
islower(), isupper(), istitle()…
isalnum(), isdigit(), isnumeric(), isdecimal()…
pass
比如函数没想好怎么写的时候可以用来在函数中占位,保证语法正确
continue直接跳到下一个循环,pass则是占位,虽然什么都不会发生,但是如果后面语句的话这些语句会继续运行
yield
1.保存当前运行状态(断点),然后暂停执行,即将函数挂起
2.将yeild关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用,当使用next()、send()函数让函数从断点处继续执行,即唤醒函数。
match()和search()
match()检测RE是不是在字符串开始位置匹配,只有在0匹配成功才返回True,search()会扫描整个字符串查找有无匹配
模块和包
模块:python中包含并有组织的代码片段,xxx.py的xxx就是模块名
包:模块之上的有层次的目录结构,定义了由很多模块或很多子包组成的应用程序执行环境。包是一个包含__init__.py文件和若干模块文件的文件夹。
库:具有相关功能模块的集合,python有很多标准库、第三方库…
闭包
闭包使得局部变量在函数外被访问成为可能。
python运算符(7)
算术、关系、赋值、逻辑、位、成员、身份运算符
多进制数字
0b二进制(bin),0o八进制,0x十六进制
Python标准数据类型(5)
Numbers数字,Strings字符串,Lists列表,Tuples元组,Dictionary字典
他们的一些特点:
元组解封装
Namedtuple:(从collections模块中导入)能够用标签获取一个元组的元素。
集合:无序且元素不重复
PYTHONPATH变量是什么
Python中的环境变量,用于在导入模块的时候搜索路径。因此它必须包含Python源库目录以及含有Python源代码的目录。
生成器generator和迭代器iterator
生成器
生成器是一种特殊迭代器。生成一系列的值用于迭代,在for循环的过程中不断计算出下一个元素并在恰当的条件结束循环
使用了yield的函数,返回迭代器
迭代器
迭代器是访问集合元素的一种方式,他的对象从集合的第一个元素开始访问,直到所有元素被访问完结束,用iter()创建迭代器,调用next()函数获取对象(迭代只能往前不能后退)。
两者区别:
-
创建/生成,生成器创建一个函数,用关键字yield生成/返回对象;迭代器用内置函数iter()和next()
-
生成器中yield语句的数目可以自己在使用时定义,迭代器不能超过对象数目
-
生成器yield暂停循环时,生成器会保存本地变量的状态;迭代器不会使用局部变量,更节省内存
生成器和函数:
生成器和函数的主要区别在于函数 return a value,生成器 yield a value同时标记或记忆 point of the yield 以便于在下次调用时从标记点恢复执行。 yield 使函数转换成生成器,而生成器反过来又返回迭代器。
参数传递机制
如果实际参数的数据类型是可变对象(列表、字典),则函数参数的传递方式将采用引用传递方式。如果是不可变的,比如字符串、数值、元组,他们就是按值传递。
Python对象基本要素(3),id,type和value
==比较value,即值,is比较id
__new__和__init__的区别?
new:创建对象时调用,会返回当前对象的一个实例
init:创建完对象后调用,对当前对象的一些实例初始化,无返回值
调用顺序:先调用__new__生成一个实例再调用__init__方法对实例进行初始化,比如添加属性。
全局变量和局部变量
主(main)函数的作用
作为整个程序文件的入口。
调试代码的时候,在if name == ‘main’中加入一些我们的调试代码,我们可以让外部模块调用的时候不执行我们的调试代码,但是如果我们想排查问题的时候,直接执行该模块文件,调试代码能够正常运行!
cookie和session的关系和区别
cookie保存在浏览器端,session保存在服务器端,但是为了区分不同的客户端,服务器会在浏览器中发送一个对应的sessionid保存到cookies中,下次浏览器请求服务器的时候会将sessionid一并发送给服务器。所以session机制依赖于cookie机制
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
什么是Python的命名空间?
在Python中,所有的名字都存在于一个空间中,它们在该空间中存在和被操作——这就是命名空间。它就好像一个盒子,每一个变量名字都对应装着一个对象。当查询变量的时候,会从该盒子里面寻找相应的对象。
计算机网络
连不上网可能哪里有问题
网络模型
七层网络模型
-
物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
-
数据链路层
-
网络层 IP
-
传输层 TCP、UDP
-
会话层
-
表示层 对底层命令和数据进行解释,
-
应用层 应用层协议:DNS、HTTP、SMTP等,用户在这一层与网络进行交互
TCP/IP四层
-
网络接口层
-
网际层 IP
-
运输层 TCP、UDP
-
应用层 HTTP、SMTP、FTP等
五层协议
-
物理层 实现相邻计算机之间比特流的透明传递
-
数据链路层 将IP数据报组装成帧,控制信息在相邻两节点的链路上进行传输
-
网络层 IP,为不同主机分组交换信息服务
-
运输层 TCP、UDP,为两台主机之间的通信提供通用的数据传输服务
-
应用层 HTTP、SMTP、FTP等
HTTP
HTTP和HTTPS的区别
https需要到ca申请证书,因而需要一定费用
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议,成本较高
http的连接很简单,是无状态的,https协议是由ssl+http协议构建的可进行加密串苏,身份验证的网络协议
http用的端口是80,https用的端口是443
HTTP请求报文的内容
请求行包括请求方法(GET、POST…),URL,HTTP协议版本
请求头。格式为,头部字段:值。常见头部字段有…
请求正文
HTTP头部有哪些主要字段
Host:接受请求的服务器地址,可以是IP或者是域名
User-Agent:发送请求的应用名称
Connection:指定与连接相关的属性,例如(Keep_Alive,长连接)
Accept-Charset:通知服务器端可以发送的编码格式
Accept-Encoding:通知服务器端可以发送的数据压缩格式
Accept-Language:通知服务器端可以发送的语言
HTTP响应报文
状态行:协议版本,状态码,状态码描述
响应头
响应正文
HTTP响应头主要字段
Server:服务器应用软件的名称和版本
Content-Type:响应正文的类型
Content-Length:响应正文的长度
Content-Charset:响应正文所使用的编码
Content-Encoding:响应正文使用的数据压缩格式
Content-Language:响应正文使用的语言
HTTP状态码
1xx 服务器收到请求,需要请求者继续执行操作
2xx ok,请求成功
3xx 重定向,资源已经重新分配
4xx 客户端请求错误,403 forbidden请求资源被拒绝,404 not found找不到请求资源
5xx 服务器错误,500 服务器故障,503 服务器超载或停机维护
200,请求成功
301,资源(网页等)被永久转移到其它URL
302,资源临时移动
403,forbidden,服务器理解请求客户端的请求,但是拒绝执行此请求。请求资源被拒绝,通常原因是服务器上某些文件或目录设置了权限,客户端权限不够
404,not found,用户输入错误的链接,该链接指向的网页不存在。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。
500,internal server error 服务器内部错误(比如浏览器代理除了问题,ip,端口不对等)该状态码表明服务器端在执行请求时发生了错误。也有可能是Web应用存在的bug或某些临时的故障。
502,Bad Gateway,作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503,服务器超载或停机维护
504,Gateway Timeout网关超时 服务器作为网关或代理,未及时从上游服务器接收请求。
HTTP劫持
在正常的数据流中插入特定的网络数据报文,让客户端解释错误的数据,并以弹出新窗口的形式向使用者展示小广告或网页内容
步骤:
在TCP连接中标识HTTP协议链接;
改HTTP响应体;
将篡改后的数据包抢先回发到用户,这样后面的数据包在到达后会被直接丢弃。而客户端显示改后的网页
防范:
事前加密:HTTPS,防止明文传输被挟持,(但防不了DNS挟持)
事中加密:拆分HTTP请求数据包,运营商的旁路设备没有完整的TCP/IP协议栈,不能标记,web服务器有完整的TCP/IP协议栈,能把接收到的数据包拼成完整的HTTP请求,不影响服务
事后屏蔽:前端显示HTTP时对内容进行检测,在DOM结构发生变化时触发回调
DNS劫持:通过劫持DNS服务器,获得某域名的解析记录控制权,修改此域名的解析结果。把原来对A域名的访问转入B域名,返回错误的查询结果。可能是一些产品的持续的推广
区别:DNS劫持倾向于持续性,访问一个界面时强行推送广告,HTTP劫持频率多变,劫持过程也非常快,一般多出现于网站小尾巴
HTTPS挟持:伪造证书来进行挟持….
跨域
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
同源:域名,协议,端口均相同
即浏览器只能执行相同协议、相同域名、相同端口下的网站脚本,执行的时候如果网站的脚本不属于现在这个界面,就不会执行
HTTP请求响应中断原因
网断了,网络阻塞,请求超时,浏览器出问题,服务器出问题
如何检查
检查网络,检查本地…
HTTP有几种请求方式
HTTP1.0 定义了三种请求方法: GET, POST 和HEAD方法。
HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和CONNECT 方法。
GET和POST的区别
GET的参数放在url中,返回服务器拿数据;POST在request body里自带一个参数去服务器拿指定的数据;
因为GET的参数暴露在url上,所以安全性不能保证,也有长度的限制
应用场景
GET用来查询数据,POST用来修改数据,以及其他更需要安全性的场景如密码
DNS的查找过程(应用层)
用于将用户提供的主机名解析为ip地址
0. 浏览器从接收到的url中抽取出域名地址,将域名传给DNS应用的客户端
-
检查浏览器缓存、本地hosts文件是否有这个网址的映射,如果有,就调用这个IP地址映射
-
如果没有,则查找本地DNS解析器缓存是否有这个网址的映射,如果有,返回映射
-
如果没有,则向DNS服务器提出查询请求
-
服务器接收到查询时,查询本地配置区域资源,查到就返回结果
-
如果查不到,但服务器缓存了此网址映射关系,返回查找结果
-
如果没有缓存,就继续间请求转发至上一级DNS服务器进行查询。最终将解析结果依次返回本地DNS服务器,本地DNS服务器在返回给客户端,并把这个映射存到服务器的缓存中
IP
IP地址分类
A类:1字节(8位)网络号,3字节(24位)主机号。网络号第一位固定为0,剩下7位随便用。保留地址0(00000000)表示“本文网络”,127(01111111)表示本地环回软件测试
B类:2字节(16位)网络号,2字节(16位)主机号。网络号前两位固定为10,剩下16位随便用。保留地址
C类:3字节(24位)网络号,1字节(8位)主机号。前三位固定为110,剩下21位可用。
D类:
E类:
主机号全是0的IP地址表示是“本主机”所连接到的单个网络。
主机号全是1的IP地址表示是该网络上的所有主机。
A类地址的表示范围是:0.0.0.0-126.255.255.255,默认网络掩码为:255.0.0.0,A类地址分配给规模特别大的网络使用,
B类地址表示范围是:128.0.0.0-191.255.255.255,默认网络掩码为:255.255.0.0,B类地址分配给一般的中型网络
C类地址的表示范围是192.0.0.0-223.255.255.255,默认网络掩码是:255.255.255.0,C类地址分配给小型网络,如局域网
D类地址称为广播地址,共特殊协议向选定的节点发送信息使用。
ipv4和ipv6的转换。ipv4到ipv6的过渡手段
ipv4和ipv6的过渡是一个循序渐进的过程,在用户体验IPv6带来的好处的同时仍能与网络中其余的IPv4用户通信。
主流技术:1. 双栈策略:(最直接方式)在IPv6结点中加入IPv4协议栈。这种具有双协议栈的结点称作“IPv6/v4结点”,这些结点可以使用IPv4与IPv4结点互通,也可以直接使用IPv6与IPv6结点互通。
2. 隧道技术:(为解决局部纯IPv6网络与IPv4骨干隔离形成的孤岛问题,用隧道技术的方式解决)利用穿越现存IPv4互联网的隧道技术将孤岛连接起来,逐步扩大IPv6的实现范围。在隧道的入口处,路由器将IPv6的数组分组封装进入IPv4中,IPV4分组的源地址和目的地址分别是隧道入口和出口的IPV4地址。在隧道的出口处再将IPV6分组取出转发给目的节点。
隧道技术在实践中有四种具体形式:构造隧道、自动配置隧道、组播隧道以及6to4。
3. 隧道代理TB,Tunnel Broker。(目的是简化隧道的配置,提供自动的配置手段),TB可以看作是一个虚拟的IPv6 ISP,它为已经连接到IPv4网络上的用户提供连接到IPv6网络的手段,而连接到IPv4网络上的用户就是TB的客户。
4. 协议转换技术。其主要思想是在V6节点与V4节点的通信时需借助于中间的协议转换服务器,此协议转换服务器的主要功能是把网络层协议头进行V6/V4间的转换,以适应对端的协议类型。
5. SOCKS64。
在客户端里引入SOCKS库,它处于应用层和socket之间,对应用层的socket API和DNS域名解析API进行替换。
另一种是SOCKS网关。
6. 传输层中继
与SOCKS64的工作机理相似,只不过是在传输层中继器进行传输层的“协议翻译”
7. 应用层代理网关(ALG)
类似。在应用层进行协议翻译。
ARP协议
Address Resolution Protocol,即地址解析协议, 用于实现从 IP 地址到 MAC 地址的映射,即询问目标IP对应的MAC地址
-
查主机缓存里(的ARP列表里)有没有记录这个IP和MAC地址的对应
-
有就直接发送,没有就向本网段所有主机发送广播,发送自己的IP地址和MAC地址,询问谁是这个IP地址,这个地址的MAC地址是什么
-
网络中的其他主机收到之后对照被询问的地址和自己能不能对上,是的话就从数据包中提取源主机的IP和mac地址写入自己的ARP列表,并将自己的MAC地址写入响应包,回复源主机
-
源主机收到ARP响应包之后,就可以用这些信息发送数据
为什么要用ARP协议:OSI把网络分成7层,每层之间不直接交流,只有特定接口有交流。IP在第三层网络层,MAC地址工作在第二层数据链路层。协议发包时需要封装IP地址和MAC地址,但只知道IP,又不能跨层直接找,所以得用ARP协议的服务帮助获取目的节点的MAC地址
浏览器中输入一个URL后,按下回车后发生了什么
URL,统一资源定位符,l简单点就是网址=ip或域名 + 端口号 + 资源位置 + 参数 + 锚点
1.输入一个网址之后,首先浏览器通过查询DNS,查找这个URL的IP地址,(通过层层向上级DNS服务器查找直到找到对应URL的IP地址)
2.得到目标服务器的IP地址及端口号(http 80端口,https 443端口),会调用系统库函数socket,请求一个TCP流套接字。客户端向服务器发送HTTP请求报文
(1)应用层:客户端发送HTTP请求报文。
(2)传输层:(加入源端口、目的端口)建立连接。实际发送数据之前,三次握手客户端和服务器建立起一个TCP连接。
(3)网络层:(加入IP头)路由寻址。
(4)数据链路层:(加入frame头)传输数据。
(5)物理层:物理传输bit。
3.服务器端经过物理层→数据链路层→网络层→传输层→应用层,解析请求报文,发送HTTP响应报文。
4.关闭连接,TCP四次挥手。
5.客户端解析HTTP响应报文,浏览器开始显示HTML
网页卡顿原因
网速慢、带宽不足、硬件配置低、内存被占满。
JS脚本过大,阻塞了页面的加载。
网页资源过多、接受数据时间长、加载某个资源慢。
DNS解析速度。
一般怎么检查
硬件问题:检查网线或者无限网卡有没有插好,有没有连上路由器,就是底层是不是联通状态;
软件问题:查看是否有对应的驱动,服务器好不好,DNS对不对,或者可能是代理没关
当网页加载很慢的时候,应如何分析其原因并解决问题?
http请求次数太多
资源过大,资源过多
JS脚本过大
网速慢
…
给一个网址先解析什么后解析什么(域名解析顺序)?
域名分层:从右到左分别为顶级域名、二级域名…最左为主机名(服务器名)。比如www.baidu.com的com为顶级域名,email.tsinghua.edu.cn中cn为顶级域名,为中国国家域名,edu为教育科研部门域名,email为服务器名。
域名解析时,优先查找匹配的子域名,如果子域名存在,则从子域名的配置文件查询解析结果,如果子域名不存在,就从上一级的配置文件查询结果
高并发
响应时间、吞吐量、并发用户数…
测试多用户同时访问,访问量的缓慢增加/迅速增加…
大量相同类型访问,大量不同类型的访问
服务器角度,能够承受多大的压力(?),客户端角度,数据能否成功得到需要的信息,响应时间怎么样
实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息
一方面保证数据不丢失、一方面保证性能
TCP、UDP
TCP连接三次握手的过程
初始状态客户端CLOSED,服务器LISTEN
-
客户端A向服务器B发送SYN数据包(SYN, x:0)请求连接。此时状态为SYN_SENT,表示客户端已发送SYN报文。
-
服务器B收到,发送SYN/ACK数据包(SYN/ACK, y:x+1)回应。此时服务器状态由LISTEN(服务器socket处于监听状态,可以接受连接)变为SYN_RECV,表示收到SYN报文
-
客户端A收到并发出确认ACK(ACK, x+1:y+1),连接成功。双方状态ESTABLISHED
TCP四次挥手的过程
初始状态双方ESTABLISHED
- 客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。客户端FIN_WAIT_1。表示主动关闭连接,向对方发送了FIN,进入FIN_WAIT_1,等待对方的确认
- 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。客户端FIN_WAIT_2,表示半连接,而服务器可能还有数据要发,这边稍后关闭。服务器CLOSE_WAIT。
- 服务器B关闭与客户端A的连接,发送一个FIN给客户端A。服务器LAST_ACK,等待对面的ACK报文
- 客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。客户端进入TIME_WAIT,表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。
为何TIME_WAIT:
防止服务器在处于LAST_ACK状态下未收到ACK报文而重发FIN报文,这个TIME_WAIT 状态的作用就是用来重发可能丢失的ACK报文。
TCP和UDP的特点
TCP面向连接,UDP无连接
TCP可靠,保证安全,UDP尽最大努力交付,不保证安全
TCP是点对点的,UDP可以一对一 一对多 多对多 多对一
TCP面向字节流,UDP无拥塞控制
TCP开销较大,UDP开销小
TCP、UDP的应用场景
UDP使用场景 DNS协议(因为用UDP快),看视频、发语音、QQ聊天、多媒体教室屏幕广播
TCP使用场景 HTTP协议,QQ传文件,邮件,登陆
TCP怎么实现可靠传输
确认和重传机制:建立连接、发送包时的确认,运输过程中校验失败、丢包或延时发送端重传
数据排序:把数据分成很多包,按顺序进行传输
流量控制:滑动窗口和计时器
拥塞控制:慢启动、拥塞避免、快速重传、快速恢复
流量控制
作用于接收方,控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。
由滑动窗口实现
滑动窗口
TCP进行流量控制的方式,接收方通过告诉对方自己的窗口大小,从而控制发送方的发送速度,以防止由于发送方发送速度过快而导致自己被淹没的现象
计时器
发送端收到为0的窗口后开启一个计时器,时间到了之后发包询问现在的滑动窗口,防止死锁(接收端发回的不为0的窗口的包丢失,双方相互等待)
拥塞控制
作用于网络,防止过多的数据注入到网络中,避免出现网络负载过大的情况。
拥塞:对网络中某一资源的需求超过了该资源所能提供的可用部分,影响到网络性能
拥塞控制:防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。
拥塞窗口
发送方使用的流量控制,另外考虑到接受方的接收能力,发送窗口可能小于拥塞窗口。
慢启动和拥塞避免
慢启动:不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小。
拥塞窗口一开始设为1 ,每收到一次确认,就让拥塞窗口变为原来的两倍,当窗口值为16时(慢启动门限),改为加法增大,每次+1,直到网络拥塞。拥塞时让新的慢启动门限设为拥塞时的一半,并把拥塞窗口置为1,再让他重复,这时一瞬间会将网络数据量大量降低。
拥塞避免:拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。
快重传和快恢复
快重传:接收方每收到一个失序的报文段(收完2后就收到了4说明3丢了)就立即发出包2的重复确认,这样可以让发送方尽早知道丢包了。
发送端连续收到三个重复确认就立即重传3
快恢复:发送方收到3个连续确认时,把慢开始门限减半,把拥塞窗口的值置为慢开始门限的一半,实行拥塞避免算法,每次确认收到后+1
操作系统
操作系统(Operating System,OS):
控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配,以提供给用户和其他软件方便的接口和环境的程序集合。
为用户提供服务,使用户能在计算机上使用各种应用程序来操作计算机资源
是用户和计算机硬件系统之间的接口
处理机:
计算机系统中存储程序和数据,并按照程序规定的步骤执行指令的部件。包括中央处理器、主存储器、I/O接口,处理器+外围设备(鼠标键盘之类)构成完整的操作系统
程序是描述处理机完成某项任务的指令序列。
指令则是处理机能直接解释、执行的信息单位。
中央处理器(CPU,Central Processing Unit):
是一块超大规模的集成电路,是一台计算机的运算核心和控制核心。它的功能主要是解释计算机指令以及处理计算机软件中的数据。
内核:
操作系统的最基本部分、核心,决定一个程序在什么时候对某部分硬件操作多长时间
提供操作系统的最基本的功能,是操作系统工作的基础,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性
操作系统的四个特性
并发:同一段时间内多个程序执行(与并行区分,并行指的是同一时刻有多个事件,多处理器系统可以使程序并行执行)
共享:系统中的资源可以被内存中多个并发执行的进线程共同使用
虚拟:通过分时复用(如分时系统)以及空分复用(如虚拟内存)技术把一个物理实体虚拟为多个
异步:系统进程用一种走走停停的方式执行,(并不是一下子走完),进程什么时候以怎样的速度向前推进是不可预知的
操作系统的目标和功能
处理机管理:
处理机的运行以进程(或线程)为基本单位,对处理机的管理可归结为对进程的管理。
管理进程的资源共享:进程控制、进程同步、进程通信、死锁处理、处理机调度
存储器管理:
给多道程序的运行提供良好环境,方便用户使用+提高内存利用率
内存分配、地址映射、内存保护与共享、内存扩充
文件管理:
计算机中的信息以文件形式存在。
文件存储空间管理、目录管理、文件读写管理和保护
设备管理:
完成用户的I/O请求,方便用户使用各种设备,并提高设备利用率
缓冲管理、设备分配、设备处理、虚拟设备
线程和进程
进程是操作系统进行资源分配和调度的最小单位,多个进程之间相互独立,如果一个进程崩溃,不会影响其他进程;
线程是CPU进行分配和调度的最小单位(或者说是进程的最小单位,进程的一部分),一个进程下可以有很多个线程共享该进程的所有资源,如果一个线程崩溃,整个进程就会崩溃。
进程和线程的区别
进程是操作系统进行资源分配和调度的最小单位,每个进程有自己的一部分独立的资源,如果一个进程崩溃,不会影响其他进程;线程是CPU进行分配和调度的最小单位,一个进程下可以有很多个线程共享该进程的所有资源,如果一个线程崩溃,整个进程就会崩溃。
线程一般是共享资源,在创建、或是进行调度的时候开销比进程小很多,通信同步也比较方便
通信方面进程间通讯需要同步或互斥手段的辅助,来保证数据的一致性,线程间可以直接读/写进程数据段(如全局变量)来进行通信。
简述多进程和多线程
线程间通讯和进程间通讯的方法
线程间:互斥锁、信号量、临界区…
互斥量(全局变量):采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。
信号量:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
临界区:是一个访问共用资源的程序片段,而这些共用资源又无法同时被多个线程访问的特性。当有线程进入临界区段时,其他线程或是进程必须等待,有一些同步的机制必须在临界区段的进入点与离开点实现,以确保这些共用资源是被互斥获得使用。
进程间:共享内存、信号量、管道、消息队列…
共享内存就是映射一段能被其它进程访问的内存,这段共享内存由一个进程创建,但是多个进程可以访问。读写操作时需要用同步互斥的工具,保证在一个进程对这段内存进行访问的时候其他进程不能同时来
信号量是一个计数器,用来控制多个进程对资源的访问,它通常作为一种锁机制。
管道是一种半双工的通信方式,数据只能单项流动,并且只能在具有亲缘关系的进程间流动,进程的亲缘关系通常是父子进程。Pipe(管道),FIFO(有名管道)。调用管道,在内核里开辟一块缓冲区(一个共享文件)来进行进程间通信,有一个读端和一个写端(单向通信)
消息队列是消息的链表,存放在内核中并由消息队列标识符标识。
进程同步
目的:对多个相关进程在执行顺序上进行协调,使并发执行的进程可以有效的共享资源和相互合作,保证程序执行的可再现性。
进程死锁
多个并发的进程中,如果每个进程都持有某种资源由等待其他进程释放它现在保持的资源,这些资源都只允许一个进程占用,结果两个进程都不能继续执行,也不会释放自己占有的资源,所以这种双方循环等待的现象回无限期持续,发生死锁。
原因(4)
互斥条件:资源不能共享,只能一个进程用
请求与保持条件:已经得到资源的进程可以再次申请新的资源
非剥夺条件:已经分配的资源不能从相应进程中强制剥夺
循环等待条件:系统中若干进程形成环路,环路中的每个进程都在等待相邻进程正占用的资源
死锁处理
预防:破环四个原因中的一个或多个,但会影响到资源利用率及吞吐量
避免:在资源的动态分配中防止系统进入不安全状态
检测:死锁发生后,用一定的算法进行检测,并确定相关死锁相关的资源和进程,采取方法清楚死锁。
解除:对死锁相关进程,通过撤销或挂起的方式,释放一些资源
处理机调度
常用的调度算法
先来先服务调度:按进程到达的先后顺序依次调度
短作业优先调度:选择队列中估计时间较短的先进行处理
优先权调度:为不同队列设不同的优先级,等待时间长的适当提高优先级
时间片轮转:按进程到达的先后顺序放入队列,给队首进程分配CPU时间片,用完后计时器发出中断,暂停当前进程并将其放到队伍尾部,循环。
线程状态(5)
创建:new Thread(r)创建,有了相应的内存空间和其他资源,但还未开始执行
就绪:start()方法启动,进入线程队列排队,等待CPU服务
运行:获得处理器资源
阻塞:需要进行耗时的输入输出操作时,要等阻塞清除才能进入队列排队
终止:stop()、destory()或run()结束后,不在具有继续运行的能力
进程三态的转化(也有说5态的,和线程差不多)
运行状态:进程正在处理机上运行。在单处理机环境下,每一时刻最多只有一个进程处于运行状态。
就绪状态:进程已处于准备运行的状态,即进程获得了除处理机之外的一切所需资源,一旦得到处理机即可运行。(只缺处理机这个资源)
阻塞状态,又称等待状态:进程正在等待某一事件而暂停运行,如等待某资源为可用(不包括处理机)或等待输入/输出完成。即使处理机空闲,该进程也不能运行。(缺除了处理机之外的其他资源)
四个转换的过程
僵尸进程
僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。
孤儿进程
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
内存
内存分区
(高地址)
栈区:编译器自动分配,存放函数的参数值、局部变量的值,系统自动回收用完的内存
堆区:一般由程序员分配(malloc申请内存和free释放内存),如果不释放内存容易因引起内存泄漏
全局区(静态区):静态变量和全局变量,内存被分配后直到程序结束之后才释放
常量区:(只读)存一些字符串常量、数组名等
代码区:(只读)存一些CPU执行的一些机器指令
(低地址)
堆和栈的区别
栈:先进后出,生长方向向下,系统自动分配回收,高效快速;但有限制,数据不灵活。申请内存时,只要栈的剩余空间大于所申请的空间,系统将为程序员提供内存,否则报栈溢出。
堆:向上生长,需要程序员自己申请并指明大小。堆里分布的内存是不连续的。操作系统应该有记录空闲内存地址的链表,申请内存时遍历链表,找第一个空间大于申请空间的堆节点,分配内存…
把数据存到栈里比堆更快,因为系统会自动分配内存,堆需要自己分配和释放内存;另外访问堆的一个具体单元需要两次访问内存,一次获得指针,第二次才是真正的数据,而栈只要一次。
缓冲区
又称缓存。在内存空间中预留一定的存储空间,用来缓冲输入输出的数据。
原因:CPU直接从磁盘读数据速度慢,增加读写次数对磁盘性能会有影响;使用缓冲区减小读写次数,CPU对缓冲区的操作速度也远大于磁盘的操作速度,增加计算机的运行速度。
缓冲区溢出
计算机向缓冲区填充数据的时候超出了缓冲区本身的容量,溢出的数据覆盖在合法数据上。导致程序崩溃、趁这个机会获取程序乃至系统的控制权。
虚拟内存
相当于从逻辑上扩充内存容量,在程序装入的时候,只把程序的一部分装入内存,就启动程序执行,执行过程中,访问的信息不在内存里时,操作系统将需要的部分调入内存,并把暂时不适用的内容换到外存上,腾出内存空间。让应用程序认为他用了一个比实际内存大得多的存储器。
虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。
多次性、对换性、虚拟性
内存泄漏
程序没有释放已经不再使用的内存,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,因此这段内存一直被占用,无法释放,造成空间的浪费。
怎么查
-
用封装的malloc函数,写代码时在malloc外封装一层,封装函数内打印一下malloc地址,free也是,然后运行时收集打印信息,可以用另外的脚本来分析内存的申请和释放是否一一对应。
- dmalloc库,第三个方案是valgrind工具 提一下常用的用法就行。
内存溢出
要求分配的内存超过了系统能给我的,系统不能满足需求。内存泄漏的堆积如果不及时处理最终会导致内存溢出
基本分页储存管理方式
把主存空间划分为大小相等且固定的块,作为主存的基本单位,每个进程也以块为单位进行划分,进程执行时,以块为单位逐个申请主存中的块空间。用页表记录分散的内存分布情况。
页表:
用来记录逻辑地址和实际存储地址之间的映射关系,以实现从页号到物理块号的映射。
访问分页系统中内存数据需要两次内存访问,一次从内存中访问页表,找到实际物理地址,第二次根据得到的物理地址访问内存
页表储存在内存中。
逻辑空间->页表->物理空间
快表机制:
访问内存数据的时候先在快表里查询,如果查到了就可以直接读取相应的物理块号,如果每找到再访问页表,得到物理地址并访问,同时把该页表中的该映射项添加到块表中
两级页表或多级页表
基本分段储存管理方式
分段管理:每个段内部连续内存分配,但段与段之间是离散的,因此会用到段表,记录每段在内存中的起始地址和该段长度。
段表可以放在内存或寄存器中。
分页和分段的比较
页是信息的物理单位,是出于系统内存利用率的角度提出的离散分配机制;
段是信息的逻辑单位,每个段含有一组意义完整的信息,是出于用户角度提出的内存管理机制
页的大小是固定的,由系统决定;
段的大小是不确定的,由用户决定
页面置换算法
为什么:
地址映射的过程中,如果页面中发现要访问的页面不在内存中,会产生缺页中断。此时操作系统必须在内存里选择一个页面把他移出内存,为即将调入的页面让出空间。选择淘汰哪一页的规则就是页面置换算法
分类:
最佳置换算法(理想):将当前页面中在未来最长时间内不会被访问的页置换出去
先进先出:淘汰最早调入的页面
最近最久未使用 LRU:每个页面有一个t来记录上次页面被访问直到现在,每次置换时置换t值最大的页面(用寄存器或栈实现)
时钟算法clock(也被称为最近未使用算法NRU):页面设置访问为,将页面链接为一个环形列表,页面被访问的时候访问位设为1。页面置换的时候,如果当前指针的访问位为0,置换,否则将这个值置为0,循环直到遇到访问位为0的页面。
改进型Clock算法:在clock算法的基础上添加一个修改位,优先替换访问位和修改位都是0的页面,其次替换访问位为0修改位为1的页面。
最少使用算法LFU:设置寄存器记录页面被访问次数,每次置换当前访问次数最少的
用户态 内核态
内核态:cpu可以访问内存的所有数据,包括外围设备,例如硬盘,网卡,cpu也可以将自己从一个程序切换到另一个程序。
用户态:只能受限的访问内存,且不允许访问外围设备,占用cpu的能力被剥夺,cpu资源可以被其他程序获取。
最大的区别就是权限不同,在运行在用户态下的程序不能直接访问操作系统内核数据结构和程序。
为什么要有这两态:
需要限制不同的程序之间的访问能力,防止他们获取别的程序的内存数据,或者获取外围设备的数据,并发送到网络,CPU划分出两个权限等级 – 用户态和内核态。
什么时候转换
系统调用:
用户进程主动发起的。用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作,比如fork()就是执行一个创建新进程的系统调用
用户程序使用系统调用,系统调用会转换为内核态并调用操作系统
异常:
会从当前运行进程切换到处理次此异常的内核相关程序中
外围设备的中断:
所有程序都运行在用户态,但在从硬盘读取数据、或从键盘输入时,这些事情只有操作系统能做,程序需要向操作系统请求以程序的名义来执行这些操作。这个时候用户态程序切换到内核态。
用户接口程序(GUI或shell)
GUI,Graphical User Interface,图形用户界面,带有图形界面的操作系统;基于文本、命令行的叫shell
处于用户态中,位于用户态的最底层,允许用户运行其他程序
(而操作系统运行在内核态中
Linux
Linux常用命令
系统管理命令
::su
切换账户
Ifconfig
查看IP地址
Ping
检查网络是否连接
Kill
杀死进程
Kill -9
强制杀死
系统资源查询命令
ps
查看进程
Ps -ef
查看所有的进程
Netstat
查看网络状况
Netstat -apn
查看所有的端口
df
显示磁盘空间使用情况
top
查看进程资源占用
管道命令(同时执行)
Ps -ef | grep
查看所有进程,通过管道找到相应的进程包名
Chmod
赋权命令
目录操作命令
cd
进入目录里面
cd /
根目录
pwd
当前目录
mkdir
创建目录
rmdir
删除目录
ls
查看现有的目录
文件编辑就命令
vi + 文件
编辑文件
Cat a.txt
查看文件,显示内容
rm -rf
强制删除
find / -name .txt
在根目录下面查找txt文件
cp -ai a.txt test
复制a.txt到test目录下
tail -f pin.log
显示pin.log文件末尾内容
Find
查找
grep
文本搜索
touch
如果没有就创建,有就不理它
文件解压压缩命令
tar -czvf test.tar.gz.test
压缩 将文件压缩成.test.tar.gz
tar -xzvf test.tar.gz.test
解压 将文件解压成.test.tar.gz
linux和windows的区别,linux相比windows有什么优势
Linux是一个以开发者为中心的操作系统,而windows是以消费者为中心的操作系统
Linux是免费的、开源的,更容易得到他的源代码,也就更容易实现个性化定制
Linux的命令行功能强大,windows的命令行没这么厉害…
Linux基于网络,只要有相应权限,就能远程操控相应的服务器
……
| 是什么:
管道符,就是把符号左边命令本来要打印到终端上的信息当做右边命令的操作对象
Linux命令 如何杀死占用指定端口的进程
先查端口对应的进程,然后kill进程号
(ss、netstat查进程
grep怎么输出文本中包含某个关键字的行,不包含的呢
grep -v xxx输出不包含的
装软件
系统是debian的,apt-get
其他方式还有yum、rpm
du,df的区别
VI 显示所有行的行号:vi set number
找到共用80端口的线程
linux基本指令 awk、find、grep
shell脚本:统计一个文件中重复的行和重复次数
linux 如何将文件从一台服务器转移到另一台服务器
如何查找出现频率最高的100个ip地址
sh .sh source .sh ./a.sh区别
数据结构
用列表实现队列
用队列实现栈
用栈实现队列
二叉树节点间最小距离
二叉树中的最大路径和
二叉树的序列化和反序列化
深度优先搜素、宽度优先搜索
堆排序的原理和复杂度
…
C
Static/const
static,静态:1. 将函数或变量对其他源文件隐藏,只能被本地模块引用,即局部有效。2. 静态局部变量,在函数体内用static修饰变量,将本来要被存在栈中的局部变量保存在了静态空间中,函数退出时他仍然存在,延长了该变量的生命周期。
const,只读:被const修饰的量为常量,表示禁止这个量被修改;同时向阅读代码的人传递信息表示:这一块的内容不要区改他,只读的,同样也能保护代码。
字节序
在存储器中储存字节的顺序,分大端和小端两种。大端:高位字节在前,低位字节在后,是人类的读写方式;小端反过来,是计算机的读写方式
Strcpy(destination, sourse)
从sourse字符串的第一位开始往后赋值,直到遇到”\0”
Printf %s也是打印到\0停止
Sizeof
内存地址的大小和指针指向无关,只和操作系统位数有关。
函数传参不能传数组,编译器会自动把数组转换成指针形式
Volatile
程序读取变量时一般是向寄存器里读值而不是在内存读值(编译器的优化),Volatile告诉程序这个值随时都能变化,需要保证每次执行的时候都从内存里取值。
数组指针
a+1数组下一个值首地址,&a表示数组地址,&a+1为下一个数组首地址
运算符优先级
/±位运算
函数宏
#define MYPOW(x) ((x)(x))
宏名要大写,每个变量都要加括号
内存对齐
隐式转换
…
数据库
事务的特性:原子性、一致性、隔离性、持久性。
联合主键:设置多个字段同时为主键(PRIMARY KEY(Name, Age))
复合主键:多个主键联合形成一个主键组合。(成绩表中的学号、课程标号)
mysql怎么优化
数据库的备份是如何实现的
mysql创建一个学生表,包含id(int)和name(string),主键的创建:CREATE TABLE stu(id INT (5), name VARCHAR (100), PRIMARY KEY (id));
mysql建立索引 CREATE INDEX index_name ON table_name (column_list) CREATE INDEX idx_c4 ON t(c4);
数据库查询10-20行内容:select * from stu limit 10, 10;
查找135开头的电话:select * from table where tel like ‘135%’;
left join, right join和inner join的影响性能的因素。
sql:三表查询、两表查询
…
测试相关
测试理论
白盒测试
白盒测试也称为结构测试或逻辑驱动测试,是针对被测单元内部是如何进行工作的测试。检查程序内部逻辑结构,对所有的逻辑路径进行测试,是一种穷举路径的测试方法,
常见的白盒测试的方法有:语句覆盖,条件覆盖,判定覆盖,条件组合覆盖,基本路径覆盖等等。
优点:可以检测代码的每条分支和路径;可以揭示隐藏在代码中的错误;对代码的测试比较彻底。
缺点:耗费比较大;不能检测到代码中遗漏的逻辑;不能直接验证需求的正确性
黑盒测试
黑盒测试也称功能测试或数据驱动测试,它不看代码内部的逻辑,只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数锯而产生正确的输出信息,并且保持外部信息(如数据库或文件)的完整性。
常见方法有等价类划分法;边界值分析法;因果图法;场景法;正交实验设计法;判定表驱动分析法;错误推测法;功能图分析法。
优点:容易实施,不需要关注内部实现;贴近用户需求。
缺点:覆盖率比较低,因为不知道内部逻辑
单元测试
单元测试:软件组成单元进行测试,其目的是检验软件基本组成单位的正确性,通常情况下是白盒的,能够尽早的发现错误,降低修改成本。
性能测试关注啥
指标:响应时间(RT)、每秒能完成的响应数(TPS)、CPU利用率、内存占用、网络(带宽使用率)、手机app的话还考虑耗电量……
考虑负载加大时,各项指标如何变化,联网的考虑各种不同的网络环境(正常网、超快网、网速慢、断网)时指标的变化
压力测试关注啥
并发用户数和在线用户数的区别
在线用户数:用户同时在一定时间段的在线数量
并发用户数:某一时刻同时向服务器发送请求的用户数
(在线用户只要在线就好了,并发用户计算的是和服务器有交流的用户,一般比例5%-20%)
测试的阶段
测试应该尽早进行。越早就可以花越少的消耗得到越大的回报。
单元测试
单元测试是对软件组成单元进行测试,其目的是检验软件基本组成单位的正确性,测试的对象是软件设计的最小单位:函数、或者类。
项目中的测试类就是测试接口类的,属于单元测试,一般由开发人员测试。
集成测试
集成测试也称综合测试、组装测试、联合测试,将程序模块采用适当的集成策略组装起来,对系统的接口及集成后的功能进行正确性检测的测试工作。其主要目的是检查软件单位之间的接口是否正确,集成测试的对象是已经经过单元测试的模块。
系统测试
系统测试是对整个系统的测试,将硬件、软件、操作人员看作一个整体,检验它是否有不符合系统说明书的地方,主要包括功能测试、界面测试、可靠性测试、易用性测试、性能测试。 功能测试主要针对包括功能可用性、功能实现程度(功能流程&业务流程、数据处理&业务数据处理)方面测试。在集成测试之后。
集成测试和系统测试之间的比较:
1、测试内容:集成测试是测试各个单元模块之间的接口,系统测试是测试整个系统的功能和性能;
2、测试角度:集成测试偏重于技术的角度进行测试,系统测试是偏重于业务的角度进行测试。
验收测试
也称交付测试,是针对用户需求、业务流程进行的正式的测试,以确定系统是否满足验收标准,由用户、客户或其他授权机构决定是否接受系统。
验收测试包括alpha测试和beta测试,alpha测试是由开发者进行的软件测试,beta测试是由用户在脱离开发环境下进行的软件测试。
回归测试
测试的类型
功能测试:关注功能正常(包含兼容性测试),除了下面分类都测;
性能测试:关注(比如前端性能、后端性能);
安全测试:关注传输、存储等安全;
特性测试:特性指平台差异(即部分兼容性测试),如PC端鼠标,键盘操作特性(Tab键等);如手机触屏操作,横竖屏,中断恢复(来电)等
QPS(每秒查询率)
QPS:每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准
用来衡量服务器的机器性能。
QPS和TPS的区别
TPS:Transactions Per Second(每秒传输的事物处理个数),即服务器每秒处理的事务数。TPS包括一条消息入和一条消息出,加上一次用户数据库访问。
是软件测试结果的测量单位。
系统吞吐量
测试生命周期
测试周期是指从测试项目计划建立到BUG提交的整个测试过程。
包括软件项目测试计划,测试需求分析,测试用例设计,测试用例执行,BUG提交五个阶段。 软件测试周期并行与软件生命周期,存在于软件生命周期的各个阶段。
软件生命周期
软件生命周期是指软件的产生直到报废的生命周期。
包括问题的定义及规划,需求分析,软件设计(概要,详细),软件编码,软件测试(单元测试,集成测试,系统测试,验收测试),运行维护
测试用例设计方法
黑盒测试包括:等价类划分、边界值分析、因果图、场景法、正交实验设计法、判定表、驱动分析法、错误推测法、功能图分析法,依据是用户需求规格说明书、详细涉及说明书
白盒测试包括:语句覆盖、判断覆盖、条件覆盖、路径覆盖、条件组合覆盖,依据是代码结构和逻辑
等价类划分:把可能的数据输入集合分为若干子集,每个子集中的子集内的元素对于揭露程序中的错误都是等效的,在每个等价类中取的数据用来测试,比较有代表性。 先划分等价类,“有效等价类”和“无效等价类”,根据划分的等价类编写测试。
边界值分析:选取指定数据集中的边界值进行测试。上点,内点,离点。
设计测试用例的方法
测试用例的组成元素
用例编号
用例标题
功能模块名称
前置条件
输入数据
操作步骤
预期结果
优先级
执行结果
编写人
执行人
其他补充项
BUG描述、评级
对bug的描述尽量简短但要求清晰,对bug出现的条件进行详细的描述,包括输入的测试用例、使用的环境、有没有和其他软件同时运行,以及需要写清bug出现的位置,帮助开发更好定位。
按照用户体验(bug是否很严重的影响用户体验)、影响系统的程度进行评级。
一条bug记录的组成
(1)bug内容
(2)bug发现时间
(3)测试条件(系统配置信息、环境、软件版本、浏览器版本…)
(4)预期结果和实际结果的对比,相关的分析
(5)如何重现这个bug的步骤
(6)这个bug的严重性(会多大程度的影响系统或用户使用)
(7)bug发生的位置
……
瀑布模型和敏捷模型
瀑布模型:
把软件开发模型分为好几个阶段,包括软件计划、需求分析、设计、实现、软件测试、软件运行维护。
具有一种比较明显的分层,每一阶段的结果文档会作为下一阶段的输入,强调文档,整个周期完成的差不多了才能看到结果;
没有迭代和反馈,只能一步一步来,流程没有回头路。不能适应客户不断变化的需求,后期需要改动时成本也比较大
测试比较晚,基本上是在软件完成之后进行的测试
敏捷开发:
按一个短的迭代周期工作,强调“快”,每次迭代交付一些成果,(或者说先做出一个不完美但能实现一定的功能的版本);让客户参与进来,有新需求就,快速响应变化,迭代产生新版本,缩短软件版本的周期。
强调开发软件而不是文档。
特点:让客户参与进来,客户需求的变动和软件有些不符合需求的地方可以第一时间进行了解和改动; 缩短版本周期; 每隔一段时间(一个迭代周期),团队可以在工作方面进行反省和改进,调整自己的行为; 强调开发软件而不是文档,提高编程人员的积极性。
敏捷测试:
以用户需求为中心,在每一个迭代周期都需要进行测试,
基于自动化测试->速度快、敏捷
更强调测试的速度和适应性,侧重计划的不断调整以适应需求的变化
强调面对面的沟通、协作,强调团队的责任,不太关注对缺陷的记录与跟踪。缺陷修复的成本也较低
V模型和W模型
V模型:把测试过程作为在需求分析、系统设计及编码之后的一个阶段,忽视了测试对需求分析,系统设计的验证,需求的满足情况一直到后期的验收测试才被验证。(应该比较多包括系统测试和验收测试)
W模型:测试的活动与软件开发同步进行,测试的对象不仅仅是程序,还包括需求和设计。因为在需求阶段测试就已经介入了,后面每一阶段的开发都需要经过测试,能够尽早发现软件的缺陷,降低debug的成本
Web和app测试的区别
-
首先是web和app的区别:web是b/s架构的,基于浏览器;app是c/s架构的,必须要有客户端。Web测试中只要更新了服务器,客户端就会同步更新,保证每个用户用的客户端一样;app就不能保证完全一致,因为app客户端需要用户主动更新,如果app测试中修改了服务器,就意味着客户端用户使用的所有核心版本都要进行回归测试
-
性能方面:web主要看响应速度;app还看电量、流量、CPU、内存…
-
兼容方面:web基于浏览器,主要看电脑硬件、电脑系统;app依赖于手机或平板,关注的系统主要是安卓和ios,还要关心分辨率、屏幕尺寸
- App比web测试多一些专项测试:弱网测试,安装、卸载、更新,界面操作、触摸手势等
软件测试流程
需求分析;制定测试计划(在研发计划制定时就应该定好测试计划);设计测试用例;执行测试(包括单元测试、集成测试、系统测试、回归测试、验收测试);测试评估(出报告,确认是否可以上线);面向用户
测试一款产品/一个功能
(角度)
功能:
性能:响应速度、CPU占用,联网的话考虑多用户并发/弱网环境,app的话考虑耗电量
易用性
兼容性:多平台/多系统/多版本
安全:用户名密码有没有保存功能,数据往服务器传是不是加密的,有没有防止一些脚本或者SQL注入攻击
UI:符合大众期望,有无错别字,排版和颜色搭配
稳定性:压力测试、极端条件测试
(查看产品的使用说明书)
软件质量模型的6大特性:
功能性,可靠性,易用性,效率,维护性,可移植性
案例/情景题
以百度搜索为例,设计测试方案
从以下几个角度进行测试
功能测试:
输入搜索信息,点击搜索按钮是否能获取搜索结果,跳到结果界面;
搜索结果界面弹出的信息是不是符合我输入的信息
没有输入信息,按搜索看会有什么结果
对输入框能输入的最大字符数进行边界测试,(假设限制是30个字符),那么分别输入20,30,31个字符的文本进行测试,测试超出输入限制会出现的结果
测试输入敏感词时的搜索结果
输入不同国家语言的搜索结果
查询不到搜索结果的情况显示的结果
从搜索结果界面返回的按钮能不能正常返回
点击百度的标签能不能跳到相关的热搜界面
测试百度的图片搜索能不能正常使用
图片拖曳和上传的功能是否均能实现,粘贴图片网址能不能用
如果粘贴的图片网址不存在是否能给出正确的提示反馈
输入特别大的图会发生什么现象
性能测试:
测试搜索时的响应时间能否符合需求
网速慢的条件下还能不能正常搜索
多用户同时访问,或者一个时间点访问量突然增大的情况,对这些特殊情况进行模拟,测试还能不能进行正常搜索
易用性测试:
使用操作是否简单,是不是输入查询信息之后点击搜索按钮就行了;
在输入框输入搜索词的过程中下拉框能否弹出相关的联想搜索(你可能要搜)
输入框有没有保存最近搜索的信息的记录
除了点击搜索按钮进行搜索,测试按回车进行检索的功能
兼容性测试:
多种系统下的多种不同的浏览器下是否能正常显示、正常使用;
在不同的手机浏览器中打开是否能正常显示、正常使用;
各种语言平台下是否都能正常使用
安全性测试:
能不能防止搜索时对数据库的恶意攻击的情况,如SQL注入
UI:
界面设计是否简介,是否符合用户审美
图标能不能正常显示,界面有无错别字
测试用例:上传文件
测试用例:微信扫码点餐
如何测试网站的高并发性(不是很会…)
测试多用户同时访问,访问量的缓慢增加/迅速增加。。。
大量相同类型访问,大量不同类型的访问
服务器角度,能够承受多大的压力(?),客户端角度,数据能否成功得到需要的信息,响应时间怎么样
实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息
一方面保证数据不丢失、一方面保证性能
测试一个前端页面,button按钮不好使,原因,不获取源码的前提下,如何解决(提示接口测试)
因为这是个前端界面,可以按F12打开开发者工具,在network里按钮点击时请求有没有发出去,看状态码,有没有生成新文件之类的,确定是不是连接的问题。
postman模拟发包过去测试也行。
selenium流程、获取元素方法
先import,然后webdriver模拟打开一个浏览器(初始化),获取特定的网址,然后通过获取元素模拟鼠标点击页面上的按钮(或者其他动作,比如在特定的文本框输入特定的内容),(最后quit()一下)
获取元素方法:xpath,css选择器,文本内容……等等,比如find_element_by_xpath、find_element_by_css_selector、find_element_by_link_text
其他
app登录和网页登录的区别
估计美团外卖一天内的全国订单量
淘宝页面价格显示不出来,该怎么测
如果有一部分用户反馈APP的视频加载不出来,你会从哪里方面去定位问题
在一个产品的周期中,你会怎么安排测试工作
岗位理解题
为什么投测试
对测试开发的理解
为什么做测试而不是去做开发
如何处理矛盾
职业规划
你认为测试人员需要具备哪些素质
你的优点和缺点
(完)
转发自:https://www.nowcoder.com/discuss/393011?source_id=discuss_experience_nctrack&channel=-1