前端面试题(五)

面向对象

class与class继承

传统的javascript中只有对象,没有类的概念。它是基于原型的面向对象语言。原型对象特点就是将自身的属性共享给新对象。

ES5中如果要生成一个对象实例,需要先定义一个构造函数,然后通过new操作符来完成。

构造函数生成实例的执行过程:

1.当使用了构造函数,并且new 构造函数(),后台会隐式执行new Object()创建对象;

2.将构造函数的作用域给新对象,(即new Object()创建出的对象),而函数体内的this就代表new Object()出来的对象。

3.执行构造函数的代码。

4.返回新对象(后台直接返回);

ES6中的类

ES6引入了class(类)这个概念,通过class关键字可以定义类。该关键字的出现使得javascript在对象写法上更加清晰,更像是一种面向对象的语言。

注意项:

1.在类中声明方法的时候,千万不要给该方法加上function关键字

2.方法之间不要用逗号分隔,否则会报错

ES5中的继承 (组合继承:原型链继承 + 借用构造函数)

Es5中的继承有:

原型链继承——父类的实例作为子类的原型,易于实现, 只能继承 原型上的方法,不能继承构造函数里的属性和方法

    //   原型链继承
    // 实现:
    //     父类的实例作为子类的原型
    // 优点:
    //     简单,易实现 不限制调用方式
    // 缺点:
    // 	   只能继承 原型上的方法 不能继承构造函数里的属性和方法

    function Person() {
        this.a = true
    }
    Person.prototype.fn = function () {
        console.log('我是父类')
    }

    function Son() {
        this.b = false
    }
    // 这里是关键 创建 Person 的实例 然后赋值给 Son 的原型
    Son.prototype = new Person()
    let xiaoming = new Son()
    xiaoming.fn()
    console.log(xiaoming.a)

构造函数继承——不能继承原型属性/方法,可以实现多继承,可以传参,无法复用,

    构造函数继承
    实现:
     Father.call(this),创建子类实例时调用Father构造函数,
     于是SubType的每个实例都会将Father中的属性复制一份。
    优点:
      解决了子类构造函数向父类构造函数中传递参数
    缺点:
      无法实现复用,不能继承原型属性/方法,只能继承父类的实例属性和方法

    function Father(age, name) {
        this.a = '22'
    }
    function Children() {
        Father.call(this)
    }
    let Class = new Children()
    console.log(Class.a);

组合继承 通过call 对实例属性的继承,原型链对原型方法的继承, 调用多次

   组合继承
    实现:
       组合上述两种方法就是组合继承。用原型链实现对原型属性和方法的继承,用借用构造  函数技术来实现实例属性的继承。
    优点:
       既能调用父类实例属性,又能调用父类原型属性
       调用父类构造函数,继承父类的属性,通过将父类实例作为子类原型,实现函数复用
       可以继承属性和方法,并且可以继承原型的属性和方法 
    缺点:
       缺点就是在使用子类创建实例对象时,其原型中会存在两份相同的属性/方法。
    

    function Father(name) { // 这里的name 就是 Son 传过来的
        this.name = name
        this.colors = [1, 2]
    }

    Father.prototype.sayName = function () {
        alert(this.name)
    }

    function Son(name, age) {
        //继承实例属性,第一次调用Father()
        Father.call(this, name) // 这里通过 call 传过去 name  继承实例属性
        this.age = age
    }
    Son.prototype = new Father() // 继承父类方法,第二次调用 Father
    Son.prototype.ff = function () { // 子类的方法
        console.log('666');
    }
    var aa = new Son('小明', 5)
    aa.colors.push(3)
    console.log(aa); // 打印了 父类的属性 和方法   以及子类的方法
    var bb = new Son('小红', 50)
    aa.colors.push(999999)
    console.log(bb); // 打印了 父类的属性 和方法   以及子类的方法

Es6有class继承: 首先利用class构造一个父类,然后利用extends与super实现子类继承

function MyClass() {
     SuperClass.call(this);
     OtherSuperClass.call(this);
}

// 继承一个类
MyClass.prototype = Object.create(SuperClass.prototype);
// 混合其它
Object.assign(MyClass.prototype, OtherSuperClass.prototype);
// 重新指定constructor
MyClass.prototype.constructor = MyClass;

MyClass.prototype.myMethod = function() {
     // do something
};
Object.assign会把  OtherSuperClass原型上的函数拷贝到 MyClass原型上,使 MyClass 的所有实例都可用 OtherSuperClass 的方法。
8ES6类继承extends
extends关键字主要用于类声明或者类表达式中,以创建一个类,该类是另一个类的子类。其中constructor表示构造函数,一个类中只能有一个构造函数,有多个会报出SyntaxError错误,如果没有显式指定构造方法,则会添加默认的 constructor方法,使用例子如下。
class Rectangle {
    // constructor
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }
    
    // Getter
    get area() {
        return this.calcArea()
    }
    
    // Method
    calcArea() {
        return this.height * this.width;
    }
}

const rectangle = new Rectangle(10, 20);
console.log(rectangle.area);
// 输出 200

-----------------------------------------------------------------
// 继承
class Square extends Rectangle {

  constructor(length) {
    super(length, length);
    
    // 如果子类中存在构造函数,则需要在使用“this”之前首先调用 super()。
    this.name = 'Square';
  }

  get area() {
    return this.height * this.width;
  }
}

const square = new Square(10);
console.log(square.area);
// 输出 100

proto和prototype

  1. 每个函数都有一个prototype属性,被称为显示原型
  2. 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型
  3. 每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype
  4. 每个prototype原型都有一个constructor属性,指向它关联的构造函数。

原型链

获取对象属性时,如果对象本身没有这个属性,那就会去他的原型__proto__上去找,如果还查不到,就去找原型的原型,一直找到最 顶层(Object.prototype)为止。Object.prototype对象也有__proto__属性值为null。

javascript 创建对象的几种方式

1、我们一般使用字面量的形式直接创建对象

(1)第一种是工厂模式,工厂模式的主要工作原理是用函数来封装创建对象的细节,从而通过调用函数来达到复用的目的。

(2)第二种是构造函数模式。js 中每一个函数都可以作为构造函数,只要一个函数是通过 new 来调用的,那么我们就可以把它称为构造函数。

(3)第三种模式是原型模式,因为每一个函数都有一个 prototype 属性,这个属性是一个对象,它包含了通过构造函数创建的所有实例都能共享的属性和方法。

(4)第四种模式是组合使用构造函数模式和原型模式,这是创建自定义类型的最常见方式。

设计模式

什么是设计模式?

计模式是一套被反复使用的代码,设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 设计模式让代码变得工程化,设计模式是软件工程的基石。

1、js工厂模式,去做同样的事情,实现同样的效果,解决多个相似的问题这时候需要使用工厂模式

4、发布订阅模式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

5、单例模式 单例模式 保证一个类仅有一个实例,并提供一个访问它的全局访问点

OOP(面向对象编程) 和 OPP(面向过程编程) 的异同点及系统总结

一、面向过程:面向过程就是分析出实现需求所需要的步骤,通过函数一步一步实现这些步骤,接着依次调用即可。

二、面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程:

优点:性能上它是优于面向对象的,因为类在调用的时候需要实例化,开销过大。

缺点:不易维护、复用、扩展

用途:单片机、嵌入式开发、Linux/Unix等对性能要求较高的地方

面向对象:

面向对象有三大特性:封装,继承,多态。

优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护 。

缺点:性能比面向过程低

什么是函数的静态成员和实例成员。【考核知识点:构造函数属性】

实例成员就是构造函数内部通过this添加的成员,,实例成员只能通过实例化的对象来访问。 静态成员 在构造函数本身上添加的成员 静态成员只能通过构造函数来访问

扩展面试题

1、 Vue与Angular以及React的区别

▍Angular

框架比较成熟完整,过于庞大,上手难; 指令以ng-xxx开头; 由谷歌开发和维护; 版本1比较适合PC端开发,版本2在往移动端靠; 不支持低版本浏览器; 内置指令和自定义指令; 内置过滤器和自定义过滤器; 支持双向数据绑定;

▍Vue

它是一个轻量级框架,其核心库只关注视图层,简单小巧、易学易上手; 指令以v-xxx开头; 个人维护项目; 适合于移动端开发; 不支持低版本浏览器; 内置指令和自定义指令; 内置过滤器和自定义过滤器; 支持双向数据绑定; 使用DOM模板。中心思想:一切都是组件,组件实例之间可以嵌套; 核心库不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载; 基于依赖追踪的观察系统,并且异步队列更新。

▍React

依赖虚拟DOM; 采用特殊的JSX语法; 中心思想:一切都是组件,组件实例之间可以嵌套; 核心库不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载。

git常用命令

\1. git init 初始化git仓库 (mac中Command+Shift+. 可以显示隐藏文件)

\2. git status 查看文件状态

\3. git add 文件列表 追踪文件

\4. git commit -m 提交信息 向仓库中提交代码

\5. git log 查看提交记录

1.分支明细

(1)主分支(master):第一次向 git 仓库中提交更新记录时自动产生的一个分支。

(2)开发分支(develop):作为开发的分支,基于 master 分支创建。

(3)功能分支(feature):作为开发具体功能的分支,基于开发分支创建

2.分支命令

(1)git branch 查看分支

(2)git branch 分支名称 创建分支

(3)git checkout 分支名称 切换分支

(4)git merge 来源分支 合并分支 (备注:必须在master分支上才能合并develop分支)

(5)git branch -d 分支名称 删除分支(分支被合并后才允许删除)(-D 强制删除)

3.暂时保存更改

(1)存储临时改动:git stash

(2)恢复改动:git stash pop

多人冲突:

是当前修改是左箭头方向,传入的是右箭头的方向,中间用等于号分割,等号上边是当前修改,下边是传入的修改。

两人同时提交可能会出现冲突,解决办法是手动修改冲突

前端有哪些页面优化方法?

- 减少 HTTP请求数
- 从设计实现层面简化页面
- 合理设置 HTTP缓存
- 资源合并与压缩
- 合并 CSS图片,减少请求数的又一个好办法。
- 将外部脚本置底(将脚本内容在页面信息内容加载后再加载)
- 多图片网页使用图片懒加载。
- 在js中尽量减少闭包的使用
- 尽量合并css和js文件
- 尽量使用字体图标或者SVG图标,来代替传统的PNG等格式的图片
- 减少对DOM的操作
- 在JS中避免“嵌套循环”和 “死循环”
- 尽可能使用事件委托(事件代理)来处理事件绑定的操作
- 浏览器缓存
- 防抖、节流
- 资源懒加载、预加载
- 开启Nginx gzip压缩
三个方面来说明前端性能优化
一: webapck优化与开启gzip压缩
    1.babel-loader用 include 或 exclude 来帮我们避免不必要的转译,不转译node_moudules中的js文件
    其次在缓存当前转译的js文件,设置loader: 'babel-loader?cacheDirectory=true'
    2.文件采用按需加载等等
    3.具体的做法非常简单,只需要你在你的 request headers 中加上这么一句:
    accept-encoding:gzip
    4.图片优化,采用svg图片或者字体图标
    5.浏览器缓存机制,它又分为强缓存和协商缓存
二:本地存储——从 CookieWeb StorageIndexedDB
    说明一下SessionStoragelocalStorage还有cookie的区别和优缺点
三:代码优化
    1.事件代理
    2.事件的节流和防抖
    3.页面的回流和重绘
    4.EventLoop事件循环机制
    5.代码优化等等

"dependencies","devDependencies"是什么?-g、--save、--save-dev、-D、-S的区别?

dependencies 与 devDependencies
i 是 install 的简写
-g 是全局安装,不带 -g 会安装在个人文件夹
-S 生产阶段的依赖 与 --save 的简写,安装包信息会写入 dependencies 中
-D 开发阶段的依赖 与 --save-dev 的简写,安装包写入 devDependencies 中
dependencies 与 devDependencies
dependencies 生产阶段的依赖,也就是项目运行时的依赖
devDependencies 开发阶段的依赖,就是我们在开发过程中需要的依赖,只在开发阶段起作用的

你写 ES6 代码,需要 babel 转换成 es5 ,转换完成后,我们只需要转换后的代码,上线的时候,直接把转换后的代码部署到生产环境,不需要 bebal 了,生产环境不需要。这就可以安装到 devDependencies ,再比如说代码提示工具,也可以安装到 devDependencies 。

如果你用了 Element-UI,由于发布到生产后还是依赖 Element-UI,这就可以安装到 dependencies 。


使用 npm i 【包名】 --save-dev 安装的包,会被写入到 devDependencies 对象里面去;
而使用 npm i 【包名】 --save 安装的包,则被写入到 dependencies 对象里面去。
那么 package.json 文件里面的 devDependencies  和 dependencies 对象有什么区别呢?
devDependencies  里面的插件(比如各种loader,babel全家桶及各种webpack的插件等)只用于开发环境,不用于生产环境,因此不需要打

Sass配置

安装node-sass sass-loader npm install node-sass sass-loader --save

使用lang=”scss”

Rem、vm/vh设置

\1. 通过安装cnpm install lib-flexible postcss-pxtorem --save-dev

\2. Main.js 中导入插件

3. 根目录创建.postcssrc.js配置

Webpack配置

配置跨域、路径别名、打包分析、cdn映入、去掉console.log、单独打包第三方模块、ie兼容、eslint规范、图片压缩)

1、什么是axios

基于promise的http库,可以用在浏览器和node.js,支持promiseAPI

request拦截器:请求的时候会进行触发!发送一个 axios 请求就会触发! 做的loading 加载 和数据的权限验证,数据预加载

response拦截:在 loading 加载和数据加载需要整体的结束,马上发给数据前端的时候进行隐藏和结束

转换请求数据和响应数据、响应数据、取消请求、自动转换json数据

当然用 axios 拦截也可以配置公用地址,以及对于跨域问题解决,这个就是用 axios 拦截实现的功能。

客户端支持防御xsrf

跨站请求伪造攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的

2、Node是什么

Node是一个基于Chrome V8引擎的JavaScript代码运行环境。

浏览器(软件)能够运行JavaScript代码,浏览器就是JavaScript代码的运行环境

Node(软件)能够运行JavaScript代码,Node就是JavaScript代码的运行环境

3、模块化的意义

一句话:降低软件的复杂性。使其可控,可维护,可扩展。

一个功能就是一个模板,多个模板可以组成完整应用,抽离一个模板不会影响其他功能的运行

4、网站的组成

网站应用程序主要分为两大部分:客户端和服务器端。客户端:在浏览器中运行的部分,就是用户看到并与之交互的界面程序。使用HTML、CSS、JavaScript构建。服务器端:在服务器中运行的部分,负责存储数据和处理应用逻辑。

5、为什么要用node

简单强大,轻量可扩展。

简单体现在node使用的是javascript,json来进行编码,强大体现在非阻塞IO,可以适应分块传输数据,较慢的网络环境,尤其擅长高并发访问,轻量体现在node本身既是代码,又是服务器,前后端使用统一语言;可扩展体现在可以轻松应对多实例,多服务器架构,同时有海量的第三方应用组件。

6、node中的异步和同步怎么理解?

node是单线程的,异步是通过一次次的循环事件队列来实现的.同步则是说阻塞式的IO,这在高并发环境会是一个很大的性能问题,所以同步一般只在基础框架的启动时使用,用来加载配置文件,初始化程序什么的.

7、什么是npm?Npm的使用场景?

NPM是随同NodeJS一起安装的包管理工具,能解决NodeJS代码部署上的很多问题。

使用场景:

a. 允许用户从NPM服务器下载别人编写的第三方包到本地使用。

b. 允许用户从NPM服务器下载并安装别人编写的命令行程序到本地使用。

c. 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用。

8、get与post请求有什么区别

  1. get是从服务器上获取数据,post是向服务器传送数据。

  2. POST比GET安全,因为数据在地址栏上不可见。

  3. get方式提交的数据最多只能有1024字节,而post则没有此限制。

  4. GET使用URL或Cookie传参。而POST将数据放在request BODY中。

  5. GET与POST都有自己的语义,不能随便混用。

  6. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基

    本可以无视。而在网 络环境差的情况下,两次包的TCP在验证数据包完整 性上,有非常大的优点。post 发送两次,get 只发送一次。

  7. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

9、什么是ajax?ajax有什么优缺点?

ajax不是语言,ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术

优点

1、最大的一点是页面无刷新,用户的体验非常好。

2、使用异步方式与服务器通信,具有更加迅速的响应能力。

缺点

1、ajax不支持浏览器back按钮。

2、安全问题 AJAX暴露了与服务器交互的细节。

3、对搜索引擎的支持比较弱。

4、破坏了程序的异常机制。

5、不容易调试

10、原生Ajax的创建过程

 创建ajax原生实例 *XMLHttpRequest*
  调用open准备发送(有三个参数) 什么请求 url true 异步  false 同步
  如果是post请求,必须设置请求头
  调用send发送请求(不需要参数的话就写null)
 onload 监听异步回调

1.创建xhr 核心对象
var xhr=new XMLHttpRequest();

2.调用open 准备发送
参数一:请求方式
参数二: 请求地址
参数三:true异步,false 同步
xhr.open('post','http://www.baidu.com/api/search',true)

3.如果是post请求,必须设置请求头。
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

4.调用send 发送请求 (如果不需要参数,就写null)
xhr.send('user=tom&age=10&sex=女')

5.监听异步回调 onreadystatechange
判断readyState 为4 表示请求完成
判断status 状态码 为 200 表示接口请求成功
responeseText 为相应数据。字符串类型。
xhr.onreadystatechange=function(){
	if(xhr.readyState==4){ 
		if(xhr.status==200){
            console.log(xhr.responseText);
            var res=JSON.parse(xhr.responseText);
            console.log(res);
            if(res.code==1){
            modal.modal('hide');
           location.reload();
       }
    }
            
            
备注:如果是post请求,想要传json格式数据。
设置请求头

1.xhr.setRequestHeader('Content-Type', 'application/json')

open发送数据
2.xhr.open({_id:xxx,user:xxxx,age:xxxx})

网络安全、HTTP协议

web安全及防护

1.XSS攻击原理:

**XSS(Cross-Site Scripting,跨站脚本攻击)**是一种代码注入攻击。攻击者在目标网站上注入恶意代码,当被攻击者登陆网站时就会执行这些恶意代码,这些脚本可以读取 **cookie,**session tokens,或者其它敏感的网站信息,对用户进行钓鱼欺诈,甚至发起蠕虫攻击等。

XSS避免方式:

  1. url参数使用encodeURIComponent方法转义
  2. 尽量不是有InnerHtml插入HTML内容
  3. 使用特殊符号、标签转义符。

2.CSRF攻击(跨站请求伪造):

CSRFCross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

CSRF避免方式:

  1. 添加验证码
  2. 使用token
    • 服务端给用户生成一个token,加密后传递给用户
    • 用户在提交请求时,需要携带这个token
    • 服务端验证token是否正确

3.SQL注入攻击

就是通过吧SQL命令插入到Web表单递交或输入域名,最终达到欺骗服务器执行恶意的SQL命令。

解决:表单输入时通过正则表达式将一些特殊字符进行转换

4.DDoS攻击

DDoS又叫分布式拒绝服务,全称 Distributed Denial of Service,其原理就是利用大量的请求造成资源过载,导致服务不可用。

解决:

  1. 限制单IP请求频率。
  2. 防火墙等防护设置禁止ICMP包等
  3. 检查特权端口的开放

使用基于token的登录流程

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 LocalStorage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

状态码

http状态码分类:

100-199 提示信息 – 表示请求正在处理 200-299 成功 – 表示请求正常处理完毕 300-399 重定向 – 要完成请求必须进行更进一步的处理 400-499 客户端错误 – 请求有语法错误或请求无法实现 500-599 服务器端错误 – 服务器处理请求出错

比如:
    200响应成功
    301永久重定向
    302临时重定向
    304资源缓存
    403服务器禁止访问
    404服务器资源未找到
    500 502服务器内部错误
    504 服务器繁忙
    1xx	Informational(信息状态码)	  接受请求正在处理
    2xx	Success(成功状态码)            请求正常处理完毕
    3xx	Redirection(重定向状态码)		 需要附加操作已完成请求
    4xx	Client Error(客户端错误状态码)	服务器无法处理请求
    5xx	Server Error(服务器错误状态码)	服务器处理请求出错

什么是跨域,以及jsonp的原理?

**1、跨域的概念:**不同协议,不同域名,不同端口以及域名和 ip 地址的访问都会产生跨域。

2、jsonp的原理:ajax 请求受同源策略影响,不允许进行跨域请求,我们利用 script 标签的 src 属性不受同源策略的约束

3 . nginx是代理 前后端通常通过 nginx 实现反向代理,优点就是轻量级、启动快、高并发。

4.CORS(跨域资源共享) CORS 全称叫跨域资源共享,主要是后台工程师设置后端代码来达到前端跨域请求的

优点: 功能强大支持各种 HTTP Method 缺点: 兼容性不如 JSONP

注:现在主流框架都是用代理和 CORS 跨域实现的

jsonp 的原理

ajax 请求受同源策略影响,不允许进行请求,我们利用 script 标签的 src 属性不受同源策略的约束,利用这个特性jsonp需要以下步骤:

使用 document.createElement('script') 创建script 标签 ,写一个fn函数用来接收返回的数据 设置 src 属性 src 中要包含参数 callback= "函数名字" , 将创建好的 script 标签插入到页面中,后端会返回回调函数执行并包裹参数callback(data)

服务端不再返回JSON格式的数据,而是返回回调函数包裹数据(fn({name:'tom',age:18}),在src中进行了调用,这样实现了跨域

为什么会有同源策略?

JavaScript访问资源,处于安全方面考虑,要限制JS的访问能力,不允许跨域访问资源。如果没有同源限制存在浏览器中的cookie等其他数据可以任意读取,不同域下DOM任意操作,

ajax任意请求的话如果浏览了恶意网站那么就会泄漏这些隐私数据。

(再次强调)同源策略:同协议、同域名、同端口。

浏览器从输入url到渲染页面,发生了什么?

浏览器的地址栏输入URL并按下回车,

查找当前的URL是否存在缓存,并比较缓存是否过期,

DNS解析URL对应的IP,

根据IP建立TCP连接(三次握手),

HTTP发起请求,服务器处理请求,浏览器接收HTTP响应,

渲染页面,构建DOM树,

关闭TCP连接(四次挥手)。

TCP UDP 区别

1.`TCP`向上层提供面向连接的可靠服务 ,`UDP`向上层提供无连接不可靠服务。
2.虽然 `UDP` 并没有 `TCP` 传输来的准确,但是也能在很多实时性要求高的地方有所作为
3.对数据准确性要求高,速度可以相对较慢的,可以选用`TCP`
区别UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
连接对象个数支持一对一,一对多,多对一和多对多交互通信只能是一对一通信
传输方式面向报文面向字节流
首部开销首部开销小,仅8字节首部最小20字节,最大60字节
适用场景适用于实时应用(IP电话、视频会议、直播等)适用于要求可靠传输的应用,例如文件传输

Http和Https区别(高频)

1.`HTTP`URLhttp:// 开头,而HTTPS 的URL 以https:// 开头
2.`HTTP` 是不安全的,而 HTTPS 是安全的
3.`HTTP` 标准端口是80 ,而 HTTPS 的标准端口是443
4.`在OSI` 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
5.`HTTP` 无法加密,而HTTPS 对传输的数据进行加密,证的网络协议,安全性高于HTTP协议。
6.`HTTP`无需证书,而HTTPS 需要CA机构wosign的颁发的SSL证书,一般免费证书少,因而需要一定费用。

GET和POST区别(高频)

1.GET在浏览器回退不会再次请求,POST会再次提交请求
2.GET请求会被浏览器主动缓存,POST不会,要手动设置
3.GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会
4.GET请求在URL中传送的参数是有长度限制的,而POST没有限制
5.GET参数通过URL传递,POST放在Request body中
6.GET参数暴露在地址栏不安全,POST放在报文内部更安全
7.GET一般用于查询信息,POST一般用于提交某种信息进行某些修改操作
8.GET产生一个TCP数据包;POST产生两个TCP数据包
Ge和post的选择:
1.私密性的信息请求使用post(如注册、登陆)。
2.查询信息使用get。


get是从服务器上获取数据,post是向服务器传送数据。
POSTGET安全,因为数据在地址栏上不可见。
get方式提交的数据最多只能有1024字节,而post则没有此限制。
GET使用URLCookie传参。而POST将数据放在request BODY中。
GETPOST都有自己的语义,不能随便混用。
post 发送两次包,get 只发送一次。并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。网络环境好的情况下一次和两次一样

三次握手和四次挥手

三次握手

第一次:建立连接时,客户端发送syn包到服务器,等待服务端确认

第二次:服务器收到syn包,必须确认客户的syn,同时也发送一个syn包,即syn+ACK包

第三次:客户端收到服务器的syn和ack包,向服务器发送确认包ack,发送完毕,客户端和服务端连接成功,完成三次握手

四次挥手:

第一次:浏览器发送完数据后,发送fin请求断开连接

第二次:服务器发送ack到客户端,确认客户端的断开请求

第三次:服务器请求断开fin的请求

第四次:客户端确认服务器的断开ack

http1.0、http1.1、http2.0的区别

  1. 1和1.0相比,1.1可以一次传输多个文件
  2. http1.x解析基于文本,http2.0采用二进制格式,新增特性 多路复用、header压缩、服务端推送(静态html资源)

http如何实现缓存

  1. 强缓存==>Expires(过期时间)/Cache-Control(no-cache)(优先级高) 协商缓存 ==>Last-Modified/Etag(优先级高)Etag适用于经常改变的小文件 Last-Modefied适用于不怎么经常改变的大文件
  2. 强缓存策略和协商缓存策略在缓存命中时都会直接使用本地的缓存副本,区别只在于协商缓存会向服务器发送一次请求。它们缓存不命中时,都会向服务器发送请求来获取资源。在实际的缓存机制中,强缓存策略和协商缓存策略是一起合作使用的。浏览器首先会根据请求的信息判断,强缓存是否命中,如果命中则直接使用资源。如果不命中则根据头信息向服务器发起请求,使用协商缓存,如果协商缓存命中的话,则服务器不返回资源,浏览器直接使用本地资源的副本,如果协商缓存不命中,则浏览器返回最新的资源给浏览器。

能不能说一说浏览器的本地存储?各自优劣如何?

浏览器的本地存储主要分为Cookie、WebStorage和IndexDB, 其中WebStorage又可以分为localStorage和sessionStorage

共同点: 都是保存在浏览器端、且同源的

不同点:

  1. cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下sessionStoragelocalStorage不会自动把数据发送给服务器,仅在本地保存。
  2. 存储大小限制也不同,
  • cookie数据不能超过4K,sessionStorage和localStorage可以达到5M
  • sessionStorage:仅在当前浏览器窗口关闭之前有效;
  • localStorage:始终有效,窗口或浏览器关闭也一直保存,本地存储,因此用作持久数据;
  • cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
  1. 作用域不同
  • sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;
  • localstorage:在所有同源窗口中都是共享的;也就是说只要浏览器不关闭,数据仍然存在
  • cookie: 也是在所有同源窗口中都是共享的.也就是说只要浏览器不关闭,数据仍然存在