在群里看到一个据说是阿里校招的面试题的图片,不得不感慨阿里的面试问的内容之广,前端,算法,数据结构,数学知识,网络,服务器等都有包含到。大量的题目都是自己的知识盲区或者答不全,所以花了两个星期对除了后端语言和mySql的题都做了一遍,收获不少,记录于此。
1.列举几个css中可继承和不可继承的元素
参考 www.jianshu.com/p/fbfc6c751…
css样式表继承指的是,特定的css属性向下传递到后代元素
可继承的属性:
1.字体系列属性:font, font-family, font-weight, font-size, font-style, font-variant, font-stretch, font-size-adjust...
2.文本系列属性:text-indent, text-align, line-height, word-spacing, letter-spacing, direction, color...
3.元素可见性:visibility
4.表格布局属性:caption-side、border-collapse、border-spacing、empty-cells、table-layout...
5.列表属性:list-style-type、list-style-image、list-style-position、list-style...
6.生成内容属性:quotes
7.光标属性:cursor
可以继承到所有元素的属性:
元素可见性, 光标属性
可以继承到内联元素的属性:
字体系列属性, 除text-indent、text-align之外的文本系列属性
可以继承到块级元素的属性:
1、text-indent、text-align
不可继承的属性:
1、display
2、文本属性:vertical-align,text-decoration,text-shadow,white-space,unicode-bidi
3、盒子模型的属性:宽度、高度、内外边距、边框等
4、背景属性:背景图片、颜色、位置等
5、定位属性:浮动、清除浮动、定位position等
6、生成内容属性:content、counter-reset、counter-increment
7、轮廓样式属性:outline-style、outline-width、outline-color、outline
8、页面样式属性:size、page-break-before、page-break-after
2.用CSS选中列表的第二项
- 使用nth-child() 选择器:
li:nth-child(2)
{
...
}
3.伪类和伪元素的区别
- 伪类存在的意义是为了通过选择器找到那些不存在与DOM树中的信息以及不能被常规CSS选择器获取到的信息。例如: :focus, :hover
- 伪元素在DOM树中创建了一些抽象元素,这些抽象元素是不存在于文档语言里的(可以理解为html源码)。
- 总结: 伪元素是创建了一个抽象的有内容的虚拟容器, 伪类则是找到那些常规选择器找不到的元素
- 可以同时使用多个伪类,而只能同时使用一个伪元素;
4.H5中的字体大小自适应
- css3属性单位: vw(按宽度的百分比), vh(按高度的百分比)
5.介绍rpx, rem, vx
- rpx 是微信小程序解决自适应屏幕尺寸的尺寸单位。微信小程序规定屏幕的宽度为750rpx。
- rem是CSS3新增的相对长度单位,是指相对于根元素html的font-size计算值的大小。
- vx是窗口宽度的百分比。
6.什么情况下css会使用GPU加速
css硬件加速触发原因:
很多浏览器提供了某些触发的CSS规则。
现在,像Chrome, FireFox, Safari, IE9+和最新版本的Opera都支持GPU加速,当它们检测到页面中某个DOM元素应用了某些CSS规则时就会开启,最显著的特征的元素的3D变换。
们可能不想对元素应用3D变换,可我们一样可以开启3D引擎。例如我们可以用transform: translateZ(0); 来开启硬件加速
我们可以加入以下代码来触发硬件加速:
.cube {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
/* Other transform properties here */
}
7. css filter是什么
filter 属性定义了元素(通常是)的可视效果(例如:模糊与饱和度)。 简单来说就是滤镜。filter函数对应了不同的滤镜
filter: none | blur() | brightness() | contrast() | drop-shadow() | grayscale() | hue-rotate() | invert() | opacity() | saturate() | sepia() | url();
所有滤镜的展示效果: www.runoob.com/try/try.php…
8. 网页如何自适应宽度
- 在网页代码的头部,加入一行viewport元标签,网页初始大小占屏幕面积的100%。
<meta name="viewport" content="width=device-width,initial-scale=1" />
- 网页中的元素都用相对宽度: %,rem,vx,
- 有网格类的布局时用float来让它超出宽度自动换行
详解meta的作用
一、meta标签的定义和作用:
meta标签是head部的一个辅助性标签,提供关于 HTML 文档的元数据。它并不会显示在页面上,但对于机器是可读的。可用于浏览器(如何显示内容或重新加载页面),搜索引擎(SEO),或其他 web 服务。
meta标签里的数据是供机器解读的,其主要作用有:搜索引擎优化(SEO),定义页面使用语言,自动刷新并指向新的页面,实现网页转换时的动态效果,控制页面缓冲,网页定级评价,控制网页显示的窗口等等。
meta的可选属性
http-equiv属性
- charset
说明:用以说明网页制作所使用的文字以及语言
- expires
说明:设置网页的过期时间,一旦过期则必须到服务器上重新获取。需要注意的是必须使用GMT时间格式
- refres
说明:定时让网页在指定的时间n内,跳转到页面
- set-cookie
Cookie设定,如果网页过期,存盘的cookie将被删除。需要注意的也是必须使用GMT时间格式;
- pragma
说明:用于设定禁止浏览器从本地计算机的缓存中访问页面内容
- windows-target
说明:用于设定强制页面在窗口中以独立页面显示,防止自己的网页被别人当作一个frame页调用
- page-enter,page-exit
说明:用于设定页面进入和离开时的过渡效果,注意被添加的页面不能在一个frame中
name属性
- keywords
说明:keywords用来告诉搜索引擎你网页的关键字是什么。
- description
说明:description用来告诉搜索引擎你的网站主要内容。
- robots
说明:robots用来告诉搜索机器人哪些页面需要索引,哪些页面不需要索引
- copyright
说明:generator用于说明网站版权信息
- viewport
说明:viewport用于说明移动端网站的宽高缩放比例等信息
property="og"
og是一种新的HTTP头部标记,即Open Graph Protocol,这种协议可以让网页成为一个“富媒体对象"。用了property=og标签,就是你同意了网页内容可以被其他社会化网站引用等,目前这种协议被SNS网站如Fackbook、renren采用
常见用法
<!-- 设定字符集 -->
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- 页面关键词 keywords -->
<meta name="keywords" content="your keywords">
<!-- 页面描述内容 description -->
<meta name="description" content="your description">
<!-- 定义网页作者 author -->
<meta name="author" content="author,email address">
<!-- 定义网页搜索引擎索引方式,robotterms 是一组使用英文逗号「,」分割的值,通常有如下几种取值:none,noindex,nofollow,all,index和follow。 -->
<meta name="robots" content="index,follow">
<!-- 优先使用最新的chrome版本 -->
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<!-- 禁止自动翻译 -->
<meta name="google" value="notranslate">
<!-- 禁止转码 -->
<meta http-equiv="Cache-Control" content="no-transform">
<!-- 选择使用的浏览器解析内核 -->
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<!-- 移动端 -->
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection"content="telephone=no, email=no" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" /><!-- 删除苹果默认的工具栏和菜单栏 -->
<meta name="apple-mobile-web-app-status-bar-style" content="black" /><!-- 设置苹果工具栏颜色 -->
<meta name="format-detection" content="telphone=no, email=no" /><!-- 忽略页面中的数字识别为电话,忽略email识别 -->
<!-- 启用360浏览器的极速模式(webkit) -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 -->
<meta name="HandheldFriendly" content="true">
<!-- 微软的老式浏览器 -->
<meta name="MobileOptimized" content="320">
<!-- uc强制竖屏 -->
<meta name="screen-orientation" content="portrait">
<!-- QQ强制竖屏 -->
<meta name="x5-orientation" content="portrait">
<!-- UC强制全屏 -->
<meta name="full-screen" content="yes">
<!-- QQ强制全屏 -->
<meta name="x5-fullscreen" content="true">
<!-- UC应用模式 -->
<meta name="browsermode" content="application">
<!-- QQ应用模式 -->
<meta name="x5-page-mode" content="app">
<!-- windows phone 点击无高光 -->
<meta name="msapplication-tap-highlight" content="no">
10.position默认值和所有可能值
- static
默认值。没有定位,元素出现在正常的流中
- absolute
生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位。
- fixed
生成绝对定位的元素,相对于浏览器窗口进行定位
- relative
生成相对定位的元素,相对于其正常位置进行定位。 因此,"left:20" 会向元素的 LEFT 位置添加 20 像素。
- inherit
规定应该从父元素继承 position 属性的值
11.什么是sass和less
两个对css进行扩展的预处理语言
12.css动画的最小间隔
最小间隔为显示器每一帧的时间
13.什么是shadow DOM
Shadow DOM是HTML的一个规范 ,它允许浏览器开发者封装自己的HTML标签、CSS样式和特定的javascript代码,同时也可以让开发人员创建类似video这样的自定义一级标签,创建这些新标签内容和相关的的API被称为Web Component。
14.svg和canvas的概念和区别
SVG:
SVG 是一种使用 XML 描述 2D 图形的语言。
SVG 基于 XML,这意味着 SVG DOM 中的每个元素都是可用的。您可以为某个元素附加 JavaScript 事件处理器。
在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形
Canvas:
Canvas 通过 JavaScript 来绘制 2D 图形。
Canvas 是逐像素进行渲染的。
在 canvas 中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。
15.canvas图层怎么用
- canvas的context上有globalAlpha属性可以调节透明度,默认为0
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = 'rgba(280,187,188,1)';
context.fillRect(10,10,100,100);
context.globalAlpha = 0.5;//透明度为0.5
- globalCompositionOperation 参数设置图层之间的图形结合方式
context.fillStyle = 'rgba(280,187,188,1)';
context.fillRect(150,150,100,100);
context.globalCompositeOperation = 'source-in';//重叠部分可见,其他透明。
source-over(默认):后绘制图层位于前图层上方。
source-in:图层重叠部分可见,其他透明。
source-out:图层不重叠部分可见,先绘制层透明。
source-atop:图层重叠部分可见,先绘制不受影响。
destination-over:后绘制图层位于前图层下方。
destination-in:后绘制图层位于前图层下方,不重叠部分透明。
destination-out:后绘制图形擦除与先绘制图形重叠部分。
destination-atop:后绘制图层位于下方,不重叠部分,先绘制层透明。
16.dom渲染的性能损耗在哪里
dom渲染的性能损耗主要在dom的改变引起了dom树的重排和重绘;
重绘:是一个元素外观的改变所触发的浏览器行为,例如改变visibility、outline、背景色等属性(上面说到的其他属性)。浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。重绘不会带来重新布局,并不一定伴随重排。
重排:当DOM的变化影响了元素的几何属性(宽或高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。重排一定伴随着重绘。(重排次数多可能会导致浏览器垮掉而页面闪烁)
优化方法:
- 尽量不要在布局信息改变时做查询(会导致渲染队列强制刷新)
- 同一个DOM的多个属性改变可以写在一起(减少DOM访问,同时把强制渲染队列刷新的风险降为0)
- 如果要批量添加DOM,可以先让元素脱离文档流,操作完后再带入文档流,这样只会触发一次重排(fragment元素的应用)
- 将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
17.如何高效地从一千个div中删除10个div
为了减少重排重绘,可以先让元素脱离文档流,操作完后再带入文档流,这样只会触发一次重排。 具体方法:
- 隐藏元素,具体修改,然后再显示它
- 将原始元素拷贝到一个脱离文档的节点中,修改副本,然后覆盖元素
18. 如何监听img加载完成
给img添加onload事件
如果是监听大量的图片加载完成,则在父元素上添加load事件捕获
19.浏览器里除了js还能运行什么
- webAssembly
通过WebAssembly 可以在浏览器中扩展C/C++/Rust语言。 预计会推出的语言有Go,Java和C#
- actionScript
一个被淘汰的浏览器语言
20.promise的三种状态
pending、fulfilled、rejected(未决定,履行,拒绝)
-
初始化,状态:pending
-
当调用resolve(成功),状态:pengding=>fulfilled
-
当调用reject(失败),状态:pending=>rejected
21.promise如何捕获错误
- reject 作为失败的回调
- then后的catch作为异常的捕获
22.promise可以串联吗?
可以,promise可以链式调用,源码的then方法返回的是promise对象本身,所以可以实现链式调用。
23.vue都可以解决什么问题
- VUE通过关注视图层,用数据操作的方式来替代了dom操作
- vue通过响应式的数据绑定实现了更好的数据和视图的操作
- vue通过组件化开发让工程结构更加明确,更易于维护
- vue通过虚拟dom,优化了dom操作,实现了性能提高
- vue拥有自己的vue-cli脚手架工具,具有良好的工程化性能
24.虚拟dom如何进行diff操作
虚拟dom
虚拟dom就是用js的对象模拟dom中的节点,使用虚拟dom可以减少页面元素的修改次数,减少页面的重排重绘,提高性能。
实现步骤:
- 用JavaScript对象模拟DOM
- 把此虚拟DOM转成真实DOM并插入页面中
- 如果有事件发生修改了虚拟DOM
- 比较两棵虚拟DOM树的差异,得到差异对象
- 把差异对象应用到真正的DOM树上
代码实现
- 定义虚拟dom对象:
class crtateElement {
constructor (el, attr, child) {
this.el = el
this.attrs = attr
this.child = child || []
}
render () {
let virtualDOM = document.createElement(this.el)
// attr是个对象所以要遍历渲染
for (var attr in this.attrs) {
virtualDOM.setAttribute(attr, this.attrs[attr])
}
// 深度遍历child
this.child.forEach(el => {
//如果子节点是一个元素的话,就调用它的render方法创建子节点的真实DOM,如果是一个字符串的话,创建一个文件节点就可以了
// 判断一个对象是否是某个对象的实力
let childElement = (el instanceof crtateElement) ? el.render() : document.createTextNode(el);
virtualDOM.appendChild(childElement);
});
return virtualDOM
}
}
let ul = new crtateElement('div',myobj,[
'我是文字',
element('div',{'id': 'xiao'},['1']),
element('div',{'id': 'xiao1'},['2']),
element('div',{'id': 'xiao2'},['3']),
])
- 比较两颗dom树的差异,diff算法,diff算法的比较方式为同级比较,不会跨越层级
- 比较的结果可能有四种:
- 节点被移除
- 节点属性被改变
- 文本内容被改变
- 节点被整个替换
let utils = require('./utils');
let keyIndex = 0;
function diff(oldTree, newTree) {
//记录差异的空对象。key就是老节点在原来虚拟DOM树中的序号,值就是一个差异对象数组
let patches = {};
keyIndex = 0; // 儿子要起另外一个标识
let index = 0; // 父亲的表示 1 儿子的标识就是1.1 1.2
walk(oldTree, newTree, index, patches);
return patches;
}
//遍历
function walk(oldNode, newNode, index, patches) {
let currentPatches = [];//这个数组里记录了所有的oldNode的变化
if (!newNode) {//如果新节点没有了,则认为此节点被删除了
currentPatches.push({ type: utils.REMOVE, index });
//如果说老节点的新的节点都是文本节点的话
} else if (utils.isString(oldNode) && utils.isString(newNode)) {
//如果新的字符符值和旧的不一样
if (oldNode != newNode) {
///文本改变
currentPatches.push({ type: utils.TEXT, content: newNode });
}
} else if (oldNode.tagName == newNode.tagName) {
//比较新旧元素的属性对象
let attrsPatch = diffAttr(oldNode.attrs, newNode.attrs);
//如果新旧元素有差异 的属性的话
if (Object.keys(attrsPatch).length > 0) {
//添加到差异数组中去
currentPatches.push({ type: utils.ATTRS, attrs: attrsPatch });
}
//自己比完后再比自己的儿子们
diffChildren(oldNode.children, newNode.children, index, patches, currentPatches);
} else {
currentPatches.push({ type: utils.REPLACE, node: newNode });
}
if (currentPatches.length > 0) {
patches[index] = currentPatches;
}
}
//老的节点的儿子们 新节点的儿子们 父节点的序号 完整补丁对象 当前旧节点的补丁对象
function diffChildren(oldChildren, newChildren, index, patches, currentPatches) {
oldChildren.forEach((child, idx) => {
walk(child, newChildren[idx], ++keyIndex, patches);
});
}
function diffAttr(oldAttrs, newAttrs) {
let attrsPatch = {};
for (let attr in oldAttrs) {
//如果说老的属性和新属性不一样。一种是值改变 ,一种是属性被删除 了
if (oldAttrs[attr] != newAttrs[attr]) {
attrsPatch[attr] = newAttrs[attr];
}
}
for (let attr in newAttrs) {
if (!oldAttrs.hasOwnProperty(attr)) {
attrsPatch[attr] = newAttrs[attr];
}
}
return attrsPatch;
}
module.exports = diff;
- 获取到了补丁,就要把补丁打到相应的dom上,代码如下
let keyIndex = 0;
let utils = require('./utils');
let allPatches;//这里就是完整的补丁包
function patch(root, patches) {
allPatches = patches;
walk(root);
}
function walk(node) {
let currentPatches = allPatches[keyIndex++];
(node.childNodes || []).forEach(child => walk(child));
if (currentPatches) {
doPatch(node, currentPatches);
}
}
function doPatch(node, currentPatches) {
currentPatches.forEach(patch => {
switch (patch.type) {
case utils.ATTRS:
for (let attr in patch.attrs) {
let value = patch.attrs[attr];
if (value) {
utils.setAttr(node, attr, value);
} else {
node.removeAttribute(attr);
}
}
break;
case utils.TEXT:
node.textContent = patch.content;
break;
case utils.REPLACE:
let newNode = (patch.node instanceof Element) ? path.node.render() : document.createTextNode(path.node);
node.parentNode.replaceChild(newNode, node);
break;
case utils.REMOVE:
node.parentNode.removeChild(node);
break;
}
});
}
module.exports = patch;
25.vue中的Data为什么是函数不是对象
组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果
26.为什么需要浅拷贝
js变量中的引用类型再复制的操作中会复制地址,导致两个变量指向同一份数据。
深拷贝和浅拷贝都是针对引用类型,防止地址复制的,浅拷贝只进行了一层的拷贝,深拷贝利用递归进行了无数层。
所有在需要复制一个复杂对象进行操作且不希望影响影响原对象的时候,应该采取深拷贝。
27.简述指针是什么
指针就是内存地址,在js中,引用类型如对象和数组,他们的值都是指向对应的地址,在赋值传递的过程中为地址传递
28.简述nodeJs是什么
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
node.js可以作为一个让js运行在服务端的开发平台
29.进程和线程的区别
-
一个程序可以有多个进程;
-
一个进程可以有多个线程;
-
进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。;
-
多个线程之间可以相互通信;
-
每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线 程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
-
从逻辑角度来看,多线程的意 义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现 进程的调度和管理以及资源分配。这就是进程和线程的重要区别。
-
从chrome浏览器来理解进程个线程https://blog.csdn.net/Donspeng/article/details/82970503
31. 如何监听未处理的异常
- try..catch
1、无法捕捉到语法错误,只能捕捉运行时错误;
2、可以拿到出错的信息,堆栈,出错的文件、行号、列号;
4、需要借助工具把所有的function块以及文件块加入try,catch,可以在这个阶段打入更多的静态信息
- window.onerror
由于try..catch只能捕获块里面的错误,全局的一些错误可以用window.onerror来捕捉
34.http和https的区别
- http工作在TCP协议的80端口,HTTP所封装的信息是明文的,通过抓包工具可以分析其信息内容,所以包含危险。
- https工作在TCP协议的443端口,它队传输的信息和url都做了加密处理,更加安全。
35.为什么https不会被截获信息
1) 完成TCP三次同步握手 2) 客户端验证服务器数字证书,通过,进入步骤3 3) DH算法协商对称加密算法的密钥、hash算法的密钥 4) SSL安全加密隧道协商完成 5)网页以加密的方式传输,用协商的对称加密算法和密钥加密,保证数据机密性;用协商的hash算法进行数据完整性保护,保证数据不被篡改
36. 量子计算机能否破接非堆成加密
现有的量子计算机的能力无法破解公钥私钥结合的非对称加密,但是随着量子计算技术的发展,总有一天会对现有密码构成实际威胁。
国际上从2006年开始举办"抗量子计算密码学术会议(PostQuantum Cryptography)",每两年举行一次,至今已举办了4届。已经产生了一批重要的研究成果,让人们看到了抗量子计算密码的新曙光。
37. 量子计算机的原理
量子计算机通过量子力学的量子比特的两种量子态来表示经典比特状态0,1。 现代量子计算机模型的核心技术便是态叠加原理,属于量子力学的一个基本原理。一个体系中,每一种可能的运动方式就被称作态。在微观体系中,量子的运动状态无法确定,呈现统计性,与宏观体系确定的运动状态相反。量子态就是微观体系的态。
38.浏览器是如何缓存的
HTML Meta标签控制缓存
浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires; Cache-control等)。但是也有非HTTP协议定义的缓存机制,如使用HTML Meta 标签,Web开发者可以在HTML页面的节点中加入标签,代码如下:
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
告诉浏览器当前页面不被缓存
HTTP头信息控制缓存
-
Expires(过期时间): 这个属性告诉缓存器:相关副本在多长时间内是新鲜的。过了这个时间,缓存器就会向源服务器发送请求
-
Cache-Control响应头信息:
1) no-cache:表示必须先与服务器确认返回的响应是否被更改。
2) no-store:更加简单,直接禁止浏览器和所有中继缓存存储返回的任何版本的响应
3) max-age:该指令指定从当前请求开始,允许获取的响应被重用的最长时间(单位为秒)
4) s-maxage=[秒]: 类似于max-age属性,除了他应用于共享(如:代理服务器)缓存。
5) public : 标记认证内容也可以被缓存
39. 详述http1.0 1.1 2.0的区别
内容较多,详情参考链接 www.cnblogs.com/heluan/p/86…
40. TCP协议如何保证传输的可靠性
详细参考:
TCP协议保证数据传输可靠性的方式主要有:
校验和
发送的数据包的二进制相加然后取反,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
确认应答+序列号
序列号:TCP传输时将每个字节的数据都进行了编号,这就是序列号。
确认应答:TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。
序列号的作用不仅仅是应答的作用,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据,这也是TCP传输可靠性的保证之一。
超时重传
当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
流量控制
TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议。
拥塞控制
TCP引入了慢启动的机制,在开始发送数据时,先发送少量的数据探路。探清当前的网络状态如何,再决定多大的速度进行传输。这时候就引入一个叫做拥塞窗口的概念。发送刚开始定义拥塞窗口为1,每次收到ACK应答,拥塞窗口加 1。在发送数据之前,首先将拥塞窗口与接收端反馈的窗口大小比对,取较小的值作为实际发送的窗口。
拥塞窗口的增长是指数级别的。慢启动的机制只是说明在开始的时候发送的少,发送的慢,但是增长的速度是非常快的。为了控制拥塞窗口的增长,不能使拥塞窗口单纯的加倍,设置一个拥塞窗口的阈值,当拥塞窗口大小超过阈值时,不能再按照指数来增长,而是线性的增长。在慢启动开始的时候,慢启动的阈值等于窗口的最大值,一旦造成网络拥塞,发生超时重传时,慢启动的阈值会为原来的一半(这里的原来指的是发生网络拥塞时拥塞窗口的大小),同时拥塞窗口重置为 1。
拥塞控制是TCP在传输时尽可能快的将数据传输,并且避免拥塞造成的一系列问题。是可靠性的保证,同时也是维护了传输的高效性。
拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生,4)快速恢复。
TCP的连接管理
- TCP是面向有连接的数据通信,也就说在进行实际的数据包的收发之前,会先做好通信两端主机的准备工作:TCP三次握手!
- 在双端主机进行数据的交互完成过之后,会进行TCP连接的断开处理
滑动窗口
TCP引入了窗口这个概念,即使在往返时间比较长的情况下,它也能够控制网络性能的下降。确认应答包不再以每个段为单位进行确认了,而是以更大的单位进行确认,转发时间将会被大幅度的缩短。也就是说,发送端主机在发送了一个段之后,没必要一直等待对端主机的确认应答信号,而是继续发送。
窗口大小,指的就是无需等待接收端主机的确认应答信号而可以持续发送的数据的最大值,或者说段的最大值
在滑动窗口以外的数据,包括尚未发送出去的数据,以及已经确认对端收到的数据,当发送端确认对端已经收到数据包之后,此数据包就可以从缓冲区中清除了。
当收到确认应答信号过之后,会把滑动窗口的位置滑动到确认应答的序列号的位置,这样就可以顺序的将多个段同时发送以提高通信功能了。这就是滑动窗口控制。
41. UDP和TCP协议的区别
UDP(User Datagram Protocol)
UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务。并且它是将应用程序发来的数据在收到的那一刻,立刻按照原样发送到网络上的一种机制。 即使是出现网络拥堵的情况下,UDP也无法进行流量控制等避免网络拥塞的行为。此外,传输途中如果出现了丢包,UDO也不负责重发。甚至当出现包的到达顺序乱掉时也没有纠正的功能。如果需要这些细节控制,那么不得不交给由采用UDO的应用程序去处理。换句话说,UDP将部分控制转移到应用程序去处理,自己却只提供作为传输层协议的最基本功能。UDP有点类似于用户说什么听什么的机制,但是需要用户充分考虑好上层协议类型并制作相应的应用程序。
UDP应用场景:
- 面向数据报方式
- 网络数据大多为短消息
- 拥有大量Client
- 对数据安全性无特殊要求
- 网络负担非常重,但对响应速度要求高
TCP(Transmission Control Protocol)
TCP充分实现了数据传输时各种控制功能,可以进行丢包的重发控制,还可以对次序乱掉的分包进行顺序控制。而这些在UDP中都没有。此外,TCP作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。TCP通过检验、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。
一个例子
我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。而损失了多少数据就是丢包率
推荐一个借魔兽世界游戏服务器来说明两种协议各自的优缺点的文章
42.为什么使用UDP
UDP在相应速度上是优于TCP,安全性和数据可靠性上不如TCP
所以,UDP一般用在网络负担非常重,但对响应速度要求高,数据类型都是短消息的情况下。
一个有意思的例子
如果你写一个有肢体触碰的即时动作对战游戏,那就应该用UDP,因为需要快速的物理碰撞检测反应
如果dota类游戏,则应该使用TCP,可以更好地保证数据可靠和减少丢包。
43. WebSoket是基于什么协议的连接
- WebSoket是HTML5的协议,基于http1.1协议的扩展.
- WebSoket是一种可以实现服务端主动向客户端发送消息的连接,相比于ajax轮询和long poll,具有更好的处理效率和和更低的服务器资源消耗。
- 一句话说明就是: WebSoket的TCP连接不会中断,可以监听服务端的主动消息,执行回调。
44.冒泡算法和快速排序的时间复杂度
- 冒泡排序进行了两层循环,时间复杂度O(n²)
- 快速排序是两分递归的排序方法,平均时间复杂度O(nlg(n)),最糟的情况复杂度是O(n²),最好情况是O(nlog2(n))
快速排序时间复杂度的证明
最优情况每次均分,最差情况每次分到极值
45. 分布式系统用什么算法排序
什么是分布式系统
分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。
什么是分布式排序
分布式排序是指,在p台已经斌于序号的计算机C1,C2,……,Cp上,对一组给定的数据分布X={X1,X2,……,Xp}进行全局排序,得到一个新的数据分布Y={Y1,Y2,……,Yp},使得每个Yi(1≤i≤p)有序,并且Yi的每个元素不大于Yj的任何元素,i≤j。
分布式排序的分类
- 单节点排序(SNS)
- 多节点归并排序(MNMS)
- 多节点分区排序(MPS)
详细见文章
46.深度搜索和广度搜索的应用
- 深度搜索和广度搜索都是针对树,图等可联通对象的遍历方法。
- 广度搜索遵循同级遍历的原则,常被用来搜索最短路径或最佳路径,广度优先搜索空间复杂度大。
- 深度搜索遵循一条路走到底再找另一条的原则,深度优先搜索特别适用于那些探索所有的可能性的这些问题,问题解决的可能性是非常多的,所以需要去探索所有的可能性,从而找到所有能够满足问题的解决方案或者是解决方案中最优的那一个。
- 深搜和广搜时间复杂度一样,但是空间复杂度广度搜索要大
47. 广度搜索的数据结构
- 广度搜索的实现借助了数据结构队列
- 通过队列的特性确保了完成一层的遍历再进入下一层
48.链式求导是什么
- 链式求导是微积分中复合函数的求导法则
- 深度学习神经网络中有用到相关内容
49.矩阵的秩是什么
矩阵的秩是线性代数中的一个概念。在线性代数中,一个矩阵A的列秩是A的线性独立的纵列的极大数,通常表示为r(A),rk(A)或rank A
50. 梯度和倒数,偏导
都是一些微积分的基本概念,推荐阅读
51.信息熵
- 信息量度量的是一个具体事件发生了所带来的信息,而熵则是在结果出来之前对可能产生的信息量的期望——考虑该随机变量的所有可能取值,即所有可能发生事件所带来的信息量的期望。
- 信息熵还可以作为一个系统复杂程度的度量,如果系统越复杂,出现不同情况的种类越多,那么他的信息熵是比较大的。 如果一个系统越简单,出现情况种类很少(极端情况为1种情况,那么对应概率为1,那么对应的信息熵为0),此时的信息熵较小。