css部分
1 标准盒子模型与低版本ie盒子模型的不同
标准盒子模型:宽度=内容的宽度(content)+border+padding+margin
低版本ie盒子模型:宽度=内容宽度(content+border+padding)+margin
2 box-sizing属性
用来控制元素的盒子模型的解析模式,默认为content-box
content-box:w3c的标准盒子模型,设置元素的height/width属性指的是content部分的宽高
border-box:ie传统盒子模型,设置元素的height/width属性指的是border+padding+content部分宽高
3 重排(reflow)和重绘(repaint)的理解
- 重排:无论通过什么方式影响了元素的几何信息(元素在视口的位置和尺寸大小),浏览器需要重新计算在视口内的几何属性,这个过程叫重排
- 重绘:通过构造渲染树和重排(回流)阶段,我们知道了那些节点是可见的,以及可见节点的样式和具体的几何信息(元素在视口内的位置和尺寸大小),接下来就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘。
如何减少重排和重绘
- 减少重排和重绘,比如样式集中改变,使用添加新样式类名
.class
或cssText - 批量操作DOM,比如读取某个元素offsetWidth属性存到一个临时变量,再去使用,而不是频繁使用这个计算属性;又比如利用
document.createDocumentFragment()来添加要添加的节点,处理完之后再插入到实际DOM中
- 使
**absolute**
或者**fixed**
使元素脱离文档流,这再制作复杂的动画时对性能的影响比较明显
4 BFC的理解
BFC即块级格式化上下文,根据盒模型可知,每个元素都被定义为一个矩形盒子,然而盒子的布局会受到尺寸,定位,盒子的子元素或兄弟元素,视口的尺寸等因素决定,所以这里有一个浏览器计算的过程,计算的规则就是由一个叫做视觉格式化模型的东西定义,BFC就是来自这个概念,他是css视觉渲染的一部分,用于决定块级盒的布局及浮动相互影响范围的一个区域
BFC的特性
- 块级元素会再垂直方向一个接一个的排列,和文档流的排列方式一致
- 在BFC中上下相邻的两个容器的margin会重叠,创建新的BFC可以避免外边距重叠
- 计算BFC的高度时,需要计算浮动元素的高度
- BFC区域不会与浮动的容器发生重叠
- BFC是独立的容器,容器内部元素不会影响外部元素
- 每个元素的左margin值和容器的左border相接触
利用这些特性,我们可以解决以下问题:
- 利用4和6,我们可以实现三栏(或两栏)自适应布局
- 利用2,我们可以避免margin重叠问题
- 利用3,我们可以避免高度崩塌问题
创建BFC的方法
- 绝对定位元素(position为fixed或absolute)
- 行内元素,即display为inline-block
- overflow的值不为visible
5 实现两栏布局
现在有以下DOM结构
<div class="outer">
<div class="left">左侧</div>
<div class="right">右侧</div>
</div>
-
利用浮动,左边元素宽度固定,设置向左浮动,将右边元素的margin-left设置为固定宽度。注意,因为右边元素的width默认为auto,所以会自动撑满父元素。
.outer{ height:100px; } .left{ float:left; width:200px; height:100%; background:lightcoral; } .right{ margin-left:200px; height:100%; background:lightseagreen; }
-
同样利用浮动,左边元素宽度固定,设置向左浮动。右侧元素设置overflow:hidden;这样右边就触发BFC,BFC的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠
.outer{ height:100px; } .left{ float:left; width:200px; height:100%; background:lightcoral; } .right{ overflow:hidden; height:100%; background:lightseagreen; }
-
利用flex布局,左边元素固定宽度,右边的元素设置flex:1
.outer{ display:flex; height:100px; } .left{ width:200px; height:100%; background:lightcoral; } .right{ flex:1; height:100%; background:lightseagreen; }
-
利用绝对定位,父元素设为相对定位。左边元素absolute定位,宽度固定,右边元素的margin-left的值设为左边元素的宽度值
.outer{ position:relative; height:100px; } .left{ position:absolute; width:200px; height:100%; background:lightcoral; } .right{ margin-left:200px; height:100%; background:lightseagreen; }
-
利用绝对定位,父元素设为相对定位,左边元素宽度固定,右边元素absolute定位,left为宽度大小,其余方向定位为0
.outer{ position:relative; height:100px; } .left{ width:200px; height:100%; background:lightcoral; } .right{ position:absolute; left:200px; top:0px; right:0px; bottom:0px; height:100%; background:lightseagreen; }
6 水平垂直居中多种实现方式
-
利用绝对定位,设置left:50%和top:50% 现将子元素左上角移到父元素中心位置,然后再通过translate来调整子元素的中心点到父元素中心,该方法可以不定宽高
.father{ position:relative; } .son{ position:absolute; left:50%; right:50%; transform:translate(-50%,-50%) }
-
利用绝对定位,子元素所有方向都设置为0,将margin设置auto,由于宽高固定,对应方向实现平分,该方法必须盒子有宽高
.father{ position:relative; } .son{ position:absolute; top:0; left:0; right:0; bottom:0px; margin:auto; height:100px; width:100px; }
-
利用绝对定位,设置left:50%和top:50% 现将子元素左上角移到父元素中心位置,然后再通过margin-left和margin-top以子元素自己的一半宽高进行负值赋值,该方法必须定宽高
.father{ position:relative; } .son{ position:absolute; left:50%; top:50%; width:200px; height:200px; margin-left:-100px; margin-top:-100px; }
-
利用flex
.father{ display:flex; justify-content:center; align-items:center; }
js基础
1 基本数据类型介绍,及值类型和引用类型的理解
在js中共有8种基础的数据类型,分别为:undefined,null,boolean,number,string,object,symbol,bigint
其中Symbol和BigInt是es6新增的数据类型
- Symbol代表独一无二的值,最大的用法是用来定义对象的唯一属性名
- BigInt可以表示任意大小的整数
值类型的赋值变动过程
let a=100
let b=a
a=200
console.log(b) //100
引用类型的赋值变动过程如下
let a={age:20}
let b=a
b.age=30
console.log(a.age) //30
2 数据类型的判断
-
typeof:能判断所有值类型,函数。不可对null、对象、数组进行精确判断,因为都返回object
console.log(typeof undefined) //undefined console.log(typeof 2) //number console.log(typeof true) //boolean console.log(typeof 'str') //string console.log(typeof Symbol('foo')) //Symbol console.log(typeof 12134434n) //bigint console.log(typeof function(){}) //function //不能判断 console.log(typeof []) //object console.log(typeof {}) //object console.log(typeof null) //object
-
instanceof:能判断对象类型,不能判断基本类型,其内部运行机制是判断在其原型链中能否找到该类型的原型
Array.isArray(arr) //true arr._proto_===Array.prototype //true arr instanceof Array //true
3 深拷贝
/**
*深拷贝
* @param {Object} obj 要拷贝的对象
* @param {Map} map 用于存储循环引用对象的地址
*/
function deepClone(obj={},map=new Map()){
if(typeof obj!=="object"){
return obj
}
if(map.get(obj)){
return map.get(obj)
}
let rusult={}
//初始化返回结果
if(obj instanceof Array ||Object.prototype.toString(obj)==="[object Array]"){
result=[]
}
// 防止循环引用
map.set(obj,result)
for(let key in obj){
//保证key不是原型属性
if(obj.hasOwnProperty(key)){
result[key]=deepClone(obj[key],map)
}
}
//返回结果
return result
}
4 原型和原型链
- 原型:每一个javaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型’‘继承’‘属性,其实就是prototype对象
- 原型链:由相互关联的原型组成的链式结构就是原型链
5 作用域与作用域链
- 作用域:规定了如何查找变量,也就是确认当前执行代码对变量的访问权限。换句话说,作用域决定了代码区块中变量和其他资源的可见性。(全局作用域,函数作用域,块级作用域)
- 作用域链:从当前作用域开始一层层往上找某个变量,如果找到全局作用域还没找到,就放弃寻找。这种层级关系就是作用域链。
6 执行上下文
总结:当JavaScript代码执行一段可执行代码时,会创建对应的执行上下文,对于每个执行上下文,都有三个重要属性:
- 变量对象(VO)
- 作用域链
- this指向(JavaScript的this原理)
7 闭包
根据MDN中文的定义
在JavaScript中,每当创建一个函数,闭包就会在函数创建的同时被创建出来,可以在一个内层函数中访问到其外层函数的作用域
也可以这样说
闭包是指那些能够访问自由变量的函数,自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。闭包=函数+函数能够访问的自由变量
在某个内部函数的执行上下文创建时,会将父级函数的活动对象加到内部函数的[[scope]]中,形成作用域链,所以即使父级函数的执行上下文销毁(即执行上下文栈弹出父级函数的执行上下文),但是因为其活动对象还是实际存储在内存中可被内部函数访问到的,从而实现了闭包
闭包应用:函数作为参数被传递
function print(fn){
const a=200;
fn();
}
const a=100;
function fn(){
console.log(a)
}
print(fn) //100
函数作为返回值被返回:
function create(){
const a=100;
return function(){
console.log(a)
}
}
const fn=create()
const a=200;
fn(); //100
闭包:自由变量的查找,是在函数定义的地方,向上级作用域查找。不是在执行的地方
应用实例:比如缓存工具,隐藏数据,只提供API
function createCache(){
const data={} //闭包中被隐藏的数据,不被外界访问
return {
set:function(key,val){
data[key]=val
},
get:function(key){
return data[key]
}
}
}
const c=createCache()
c.set("a",100)
console.log(c.get("a")) //100
8 call,apply,bind实现
call
call()方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法
var obj={
value:'vortesnail'
}
function fn(){
console.log(this.value)
}
fn.call(obj) //vortesnail
通过call方法我们可以做到以下两点:
- call改变了this的指向,指向到obj
- fn函数执行了
var obj={
value:'vortesnail',
fn:function(){
console.log(this.value)
}
}
obj.fn() //vartesnail
这时候this就指向了obj,但是这样做我们手动给obj添加了一个fn属性,这显然是不行的,不用担心,我们执行完再使用队形属性的删除方法(delete)不就行了
obj.fn=fn
obj.fn()
delete.obj.fn;
根据这个思路
Function.prototype.myCall=function(context){
//判读调用对象
if(typeof this!=='function'){
throw new Error('Type error')
}
//首先获取参数
let args=[...arguments].slice(1)
let result=null
//判断context是否传入,如果没有传入就设置为window
context=context||window
//将被调用的方法设置为context的属性
//this 即为我们要调用的方法
context.fn=this
//执行要调用的方法
result=context.fn(...args)
//删除手动增加的属性方法
delete context.fn
//将执行结果返回
return result
}
apply
apply相对call,没有什么区别,只是传参的方式不同
Function.prototype.myApply=function(context){
if(typeof this!=='function'){
throw new Error('Type error')
}
let result=null
context=context||window
//与上面代码相比,我们使用Symbol来保证属性唯一
//也就是保证不会重写用户自己原来定义在context中的同名属性
const fnSymbol=Symbol()
context[fnSymbol]=this
//执行要被调用的方法
if(arguments[1]){
result=context[fnSymbol](...arguments[1])
}else{
result=context[fnSymbol]()
}
delete context[fnSymbol]
return result
}
bind
bind返回的是一个函数
Function.prototype.myBind=function(context){
//判断调用对象是否为函数
if(typeof this!=='function'){
throw new Error('Type error')
}
//获取参数
const args=[...arguments].silce(1)
const fn=this
return function Fn(){
return fn.apply(this instanceof Fn?this:context,args.concat(...arguments))
}
}
9 new 实现
-
首先创一个新的空对象
-
根据原型链,设置空对象的
_proto_
为构造函数的prototype -
构造函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
-
判断函数的返回值类型,如果是引用类型,就返回这个引用类型的对象
function myNew(context){ const obj=new Object() obj._proto_=context.prototype const res=context.apply(obj,[...arguments].slice(1)) return typeof res==='object'?res:obj }
10 async/await和Promise的关系
- async/await是消灭异步回调的终极武器
- 但和Promise并不互斥,反而相辅相成
- 执行async函数,返回的一定是Promise对象
- await相当于Promise的then
- try...catch可以捕获异常,替代了Promise的catch
11 浏览器的垃圾回收机制
- 标记清除:标记阶段即为所有活动对象做上标记,清除阶段则把没有标记销毁
- 引用计数:它把对象师傅不再需要简化定义为对象有没有其他对象引用到它,如果没有引用指向该对象(引用计数为0),对象将被垃圾回收机制回收
12 web存储
-
cookie。
-
-
本身用于浏览器和server通信
-
被’借用‘到本地存储来的
-
可用document。cookie=’...‘来修改
-
其缺点:
-
- 存储大小限制为4kb
- http请求时需要发送到服务端,增加请求数量
- 只能用document.cookie=’...‘来修改,太过简陋
-
-
localStorage和sessionStorage
- HTML5专门为存储来设计的,最大可存5M
- API简单易用,setItem getItem
- 不会随着http请求被发送到服务器
他们的区别:
-
- localStorage数据会永久存储,除非代码删除或手动删除
- sessionStorage数据只会在于当前会话,浏览器关闭则清空
- 一般用于localStorage会多一些
13 http
1.1状态码分类
- 1xx - 服务器收到请求
- 2xx - 请求成功 如200
- 3xx - 重定向 如302
- 4xx - 客户端错误 如 404
- 5xx - 服务器错误,如500
1.2常见状态码
- 200 - 成功
- 301 - 永久重定向
- 302 - 临时重定向
- 304 -资源未被修改
- 403 - 没权限
- 404 - 资源未找到
- 500 - 服务器错误
- 504 - 网关超时
14 性能优化
代码层面
- 防抖和节流
- 减少回流和重绘
- 事件委托
- 减少DOM操作
- 按需加载
构建方面
- 压缩代码文件
- 开启gzip压缩
- 常用的第三方库使用CDN服务
15 EventLoop
JS
是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列,异步队列又分为宏任务队列和微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优于宏任务队列。微任务队列代表Promise.then
,宏任务队列代表setTimeout,setInterval
16 原生ajax
ajax是一种异步通信的方法,从服务端获取数据,达到局部刷新页面的效果
- 创建XMLHttpRequest对象
- 调用open方法传入三个参数,请求方式(GET/POST)、url、同步异步(true/false)
- 监听onreadystatechange事件,当readystate等于4时返回responseText
- 调用send方法传递参数
17 ES6新增
- 新增symbol类型 代表独一无二的值,用来定义独一无二的对象属性名
- const/let 都是用来声明变量,不可重复声明,具有块级作用域。存在暂时性死区,也就是不存在变量提升(const一般用于声明常量)
- 变量的解构复制(包含数组,对象,字符串,数字及布尔值,函数参数)
- 模板字符串
- 扩展运算符(数组,对象)
- Set和Map数据结构
- Proxy/Reflect
- Promise
- async函数
- Class
- Module语法(import/export)
18 防抖
//定义:触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间
//搜索框搜索输入。只需要用户最后一次输入完,再发送请求
//手机号、邮箱验证输入检测onchange oninput事件
//窗口大小Resize,只需窗口调整完成后,计算窗口大小。防止重新渲染
const debounce=(fn,wait,immediate)=>{
let timer=null
return function(...args){
if(timer) clearTimout(timer)
if(immediate&&!timer){
fn.call(this,args)
}
timer=setTimeout(()=>{
fn.call(this,args)
},awit)
}
}
19 节流
//定义:当持续触发事件时,保证隔间时间触发一次事件
//1.懒加载、滚动加载、加载更多或监听滚动条位置
//2.百度搜索框、搜索联想功能
//3.防止高频点击提交,防止表单重复提交
function throttle(fn,awit){
let pre=0
reutrn function(...args){
let now=Date.now()
if(now-pre>=awit){
fn.apply(this,args)
pre=now
}
}
}
20 数组去重,数组对象去重
//数组
const arr=[2,7,5,7,2,8,9]
console.log([...new Set(arr)])
//对象
const list=[{age:18,name:'张三'},{age:18,name:'李四'},{age:18,name:'王五'}]
let hash={}
const newArr=arr.reduce((item,next)=>{
hash[next.age]?'':hash[next.age]=true&&item.push(next)
return item
},[])
console.log(list)
21 es6里的set和map
- Map对象保存键值对,任何值(对象或者原始值)都可以作为一个键或一个值。构造函数Map可以接受一个数组作为参数
- Set对象允许你存储任何类型的值,无论是原始值或者是对象引用,它类似于数组,但是成员的值都是唯一的,没有重复的值
22 普通函数和箭头函数的区别
- 箭头函数是匿名函数,不能作为构造函数,不能使用new
- 箭头函数不能绑定arguments,取而代之用rest参数。。。解决
- 箭头函数不能绑定this,会
Vue
1 MVVM简述
MVVM是Model-view-ViewModel缩写,也就是把MVC中的Controller演变成ViewModel层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据
2 vue生命周期的理解
每个vue实例在创建时都会经过一系列的初始化过程,vue的生命周期钩子:
create阶段
:vue实例被创建beforeCreate:创建前,此时data和methods中的数据都还没有初始化。create:创建完毕,data,methods中的数据能被访问,未挂载DOM上mount阶段
:vue实例被挂载到真实DOM节点beforeMount:可以发起服务端请求,去数据,mounted:此时可以操作DOMupdate阶段
:当vue实例里面的data数据变化时,触发组件的重新渲染beforeUpdate,updateddestroy阶段
:vue实例被销毁beforeDestroy:实例被销毁前,此时可以手动销毁一些方法destroyed
3 computed与watch
watch属性监听
是一个对象,键是需要观察的属性,值是对应回调函数,主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作,监听属性的变化,需要在数据变化时执行异步或开销比较大的操作时使用
computed计算属性
属性的结果会被缓存,当computed中的函数所依赖的属性没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取,除非依赖的响应式属性变化时才会重新计算,主要当做属性来使用computed中的函数必须用return
返回最终结果
使用场景:computed:当一个属性受到多个属性影响的时候使用,例如:购物车商品结算功能,watch:当一条数据影响多条数据的时候使用,例如搜索数据
4 v-for中key的作用
- key的作用主要是为了更高效的对比虚拟DOM中每个节点是否是相同节点
Vue在patch
过程中判断两个节点是否是相同节点,key是一个必要条件,渲染一组列表时,key往往是唯一标识。影响性能- Vue判断两个节点是否相同时主要判断两者的key和元素类型等,如果不设置key,他的值就是undefined,则可能永远认为这是两个相同的节点,只能去做更新操作,这样造成大量给dom更新操作
5 vue组件的通信方式
父子组件通信
父->子 props
,子->父$on、$emit获取父子组件实例
parent、children Ref获取实例的方式调用组件的属性或者方法 Provide、inject 官方不推荐使用,但是写组件库时很常用
兄弟组件通信
Event Bus
实现跨组件通信 Vue.prototype.$bus=new Vue() Vuex
跨组件通信
$attrs,$listeners
, Provide,inject
6 双向绑定实现原理
当一个Vue实例创建时,Vue会遍历data选项的属性,用Object.defineProperty将他们转为getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的watcher程序实例,它会s在组件渲染的过程中把属性记录为依赖,之后当依赖香的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新
7 v-model的实现以及它的实现原理
- vue中双向绑定是一个指令v-model,可以绑定一个动态值到视图,同时视图中变化能改变该值。v-model是语法糖,默认情况下相于:value和@input
- 使用v-model可以减少大量繁杂的事件处理代码,提高开发效率,代码可读性也更好。
- 通常在表单项上使用v-model
- 原生的表单项可以直接使用v-moel,自定义组件上如果要使用它需要在组件内绑定value并处理输入事件
8 nextTick的实现
- nextTick是vue提供的一个全局api,是在下次DOM更新循环结束之后执行延迟回调,在修改数据之后使用$nextTick,则可以在回调中获取更新后的DOM
- vue在更新DOM时是异步执行的,只是侦听到数据变化,vue将开启1个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个watcher被多次触发,只会被推入到队列中一次。这种在缓冲时去掉重复数据对于避免不必要的计算和DOM操作是非常重要的,nextTick方法会在队列中加入一个回调函数,确保该函数在前面的dom操作完成后才调用
9 vnode的理解,compiler和patch的过程
vnode 虚拟DOM节点创建
export function Vnode(){
return {
tag:'div',
children:'span',
attr:'',
text:'你好'
}
}
10 new Vue后整个的流程
- initProxy:作用域代理,拦截组件内访问其它组件的数据
- initialLifefecycle:建立父子组件关系,在当前组件实例上添加一些属性和生命周期标识。
- initEvents:对父组件传入的事件添加监听,事件是谁创建谁监听,子组件创建事件子组件监听
- initRender:声明slots和createElement
- initInjections:注入数据,初始化inject,一般用于组件更深层次之间的通信
- initState:数据响应式:初始化状态。
- initProvide:提供数据注入
11 keep-alive的实现
作用:实现组件缓存
钩子函数
activated 组件渲染后调用
deactivated 组件销毁后调用
原理:vue.js内部将DOM节点抽象成为一个个的VNode节点,keep-alive组件的缓存也是基于VNode节点的,而不是直接存储DOM结构,它将满足条件的组件在cache对象中缓存起来,需要重新渲染时再将VNode节点从cache对象中取出来并渲染
配置属性
include:字符串或正则表达式。只有名称匹配的组件会被缓存
exclude:字符串或正则表达式,任何名称匹配的组件都不会被缓存
max 数字、最多可以缓存多少组件实例
12 vuex,vue-router实现原理
vuex是一个专门为vue.js应用程序开发的状态管理库。核心概念:
- state(单一状态树)getter/Mutation显示提交更改state
- Action类似Mutation,提交Mutation,可以包含任意异步操作
- module()当应用变得庞大复杂,拆分store为具体的module模块
13 vue的性能优化
编码阶段
尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher
v-if和v-for不能连用
如果需要使用v-for给每项元素绑定事件时使用事件代理
SPA页面采用keep-alive缓存组件
在更多的情况下,使用v-if替代v-show
key保证唯一
使用路由懒加载、异步组件
防抖、节流
第三方模块按需导入
长列表滚动到可视区域动态加载
图片懒加载
SEO优化
预渲染
服务器渲染SSR
打包优化
压缩代码
使用cdn加载第三方模块
服务器开启gzip压缩
14 vue3的新特性,优缺点
- 性能提升
更小巧、更快捷支持自定义渲染器 支持摇树优化:一种在打包时去除无用代码
的优化手段 支持Fragments和跨组件渲染
- API变动
模板语法99%保持不变 原生支持基于class的组件,并且无需借助任何编译及各种stage阶段的特性 在设计时也考虑typescript的类型推断特性重新虚拟DOM。
- 不兼容ie11
检查机制更见全面、精准、高效,更具可调试式的响应式跟踪
15 实现双向绑定Proxy与Object.definePropperty相比优缺点
- Object.defineProperty的作用是劫持一个对象的属性,劫持属性的getter和setter方法,在对象的属性发生变化时特定的操作。而Proxy劫持的是整个对象
- Proxy会返回一个代理对象,我们只需要操作新对象即可,而Object.defineProperty只能遍历对象属性直接修改
- Object.defineProperty不支持数组,更准确的说是不支持数组的各种API,因为如果仅仅考虑arr[i]=value这种情况,是可以劫持的,但是这种劫持意义不大。而Proxy可以支持数组的各种API
- 尽管Object.defineProperty有居多缺陷,但是兼容性要好于Proxy
网络安全、http协议
1 TCP UDP区别
1.‘TCP’向上层提供面向连接的可靠服务,‘UDP’向上层提供无连接不可靠服务
2 虽然‘UDP’并没有‘TCP’传输来的准确,但是也能在很多实时性要求高的地方有所作为
3.对数据准确性要求高,速度可以相对较慢的,可以选用‘TCP’
2 http 和https区别
1.‘http’的URL 以http:// 开头,而https 的URL 以 https:// 开头
2.‘http’是不安全的,而https是安全的
3.‘http’标准端口是80,而https的标准端口是443
4.‘在OSI’网络模型中,HTTP工作于应用层,而HTTPS的安全传输机制工作在传输层
5.‘HTTP’无法加密,而‘HTTPS’对传输的数据进行加密
6.‘HTTP’无需证书,而‘HTTPS’需要CA机构wosgin的颁发的SSL证书
3 GET和POST区别
- GET在浏览器回退不会再次请求,POST会再次提交请求
- GET请求会被浏览器主动缓存,POST不会,要手动设置
- GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会
- GET请求在URL中传递的参数是有长度限制的,而POST没有限制
- GET参数通过URL传递,POST放在Request body中
- GET参数暴露在地址栏不安全,POST放在报文内部更加安全
- GET一般用于查询信息,POST一般用于信息的提交操作
4 输入url后http请求的完整过程
建立TCP连接 ->发送请求行 - > 发送请求头 ->(到达服务器)发送状态行 -> 发送响应头 ->发送响应数据 ->断开TCP连接
5 前端性能优化的几种方法
1.浏览器缓存
2.防抖、节流
3.资源懒加载、预加载
4。开启Nginx gzip压缩
一、webapck优化与开gzip压缩
1.babel-loader用include或exclude来帮我们避免不必要的转义
2.文件采用按需加载
3.图片优化,采用svg图片或字体图标
4.浏览器缓存机制,它分为强缓存和协商缓存
二、代码优化
1.事件代理
2.事件的节流和防抖
3.页面的回流和重绘
4.Eventloop事件循环机制
6 跨域通信的方法
- jsonp(利用script标签没有跨域限制的漏洞实现。缺点:只支持GET请求)
- CORS(设置Access-Control-Allow-Origin:指定可访问资源的域名)
- postMessage(message,targetOrigin,[transfer])(HTML5新增API用于多窗口消息、页面内嵌iframe消息传递),通过onmessage监听传递过来的数据
- websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案
- Node中间件代理
- Nginx反向代理