前端进阶题(面试必看)

网络&安全

❓输入URL地址后发生了什么事情?

  1. DNS域名解析,从URL地址中获取域名地址,通过DNS服务器解析为IP地址。先本地缓存(浏览器、操作系统)》ISP网络服务商》根服务器(根域、一级域、二级域、三级域)
  2. 建立TCP连接,HTTP协议是基于TCP协议的,浏览器与服务端通过三次握手建立TCP连接(如果是HTTPS则是四次握手,多了因此SSL握手)。
  3. 下载数据,向服务端发送请求报文(header+body),服务端监听80、443端口,响应HTTP请求,返回页面数据。
  4. 页面解析渲染,解析HTML为DOM树,CSS为规则树,构成渲染树进行布局和渲染。这个过程会重复多次下载、解析渲染,如有其他域名的资源,则会重复前面的步骤。
  5. 断开连接,TCP四次挥手告别!

🔗输入URL后都发生这些事情!

❓说说HTTP和HTTPS

  • TCP:HTTP是建立在TCP协议之上的,TCP协议属于OSI网络模型的传输层协议。建立TCP协议需要经过三次握手:请求》确认》建立连接。
  • HTTP:全称是超文本传输协议,图片、网页、视频、音频、文件都是HTTP的超文本,由浏览器“渲染”出来。优点是简单、灵活、快平台,缺点是无状态、明文传输。
    • HTTP请求响应的结构:首行(请求行、响应状态行)、header、body。
    • 状态码,200正常,3是重定向,4客户端错误,404资源不存在,5**服务端错误。
  • HTTPS:是在HTTP的基础上添加了SSL/TLS安全层,解决数据明文传输的问题。
    • 默认端口443。
    • 4次握手建立链接,在HTTP的基础上,多了一次SSL链接握手。
    • 采用混合加密(公私钥加密秘钥,秘钥加密数据)保障数据安全传输。
    • 采用数据摘要,保障数据不被篡改。
    • 采用CA数字证书防止假冒网站、中间人攻击。CA证书中包含了公钥、网站身份信息等。
    • TLS是SSL的升级版,由国际化IOS组织发布。
  • HTTP1.1与HTTP2.0,HTTP1.1是目前广泛支持和使用的协议版本,HTTP2.0在2015年发布,提升了传输的性能,Header支持压缩和优化,可以多路复用。

🔗HTTP协议图文简述

❓HTTP协议有哪些版本,什么区别?

  • HTTP1.1,比较普及的协议,特点是支持了长链接,可以并行传输。缺点是服务端要排队,存在队头阻塞的现象。
  • HTTP2,基于HTTPS,支持了Header的压缩和优化,在安全性、效率上提升了。服务端也支持了多了复用,并行处理请求。
  • HTTP3,还比较新,基于UDP协议,同时参考了TCP,兼顾效率和可靠。

❓POST和GET有什么区别?

  • 数据位置:GET在URL上,问号后面的参数;POST在body中。
  • 书签/缓存/刷新:GET可书签、缓存,POST的数据不可记录书签、缓存。
  • 数据长度:GET有长度限制,URL长度2048,不同浏览器不同;POST没有限制。
  • 使用场景:GET多用于获取数据,POST多用于新增、删除、修改。

❓什么是跨域?如何实现跨域?

  • 首先起因是由于浏览器的一个安全机制——同源,AJAX只能访问同源的服务端,即协议+域名+端口相同。
  • 但有时候需要跨域访问服务,就有了相应的办法:
    • JSONP利用<script>标签访问,服务端返回一个动态脚本,数据就在脚本里面。
    • CORS(cross origin resource sharing)是为满足跨域资源访问而新增的特性,在Header上带上源地址“origin”字段,由服务端来判断是否同意访问。
    • 其他还有如websocket、iframe、服务端代理等方式。

❓TCP的三次握手和四次挥手

✏️主要是在建立HTTP连接、和断开链接的时候,HTTP协议属于应用层协议,建立在TCP协议基础上。

  • 建立连接时,TCP三次握手:1、客户端发生连接请求,2、服务端响应应答,3、客户端收到并发送确认报文。
  • 断开连接时,TCP四次挥手:1、客户端发送断开请求,2、服务端回复收到,3、服务端验证没有问题发送可以关闭报文,4、客户端发送最后的确认关闭连接报文。客户端等待2MSL(两个最大报文生存周期)后,正式关闭TCP。

❓关于WebSocket

✏️和HTTP一样都属于应用层协议,目的是提供全双工的网络通信,没有跨域的限制。复用HTTP连接建立通道,缺点是需要用心跳机制来确保连接状态。

❓TCP与UDP

✏️都是传输层的协议,TCP需要先建立连接通道,数据传输安全、可靠,当然效率也更低。UDP不用建立连接,直接发送数据,不保证可靠到达,效率高。

❓请求头的keep-alive是什么东西?

✏️keep-alive是HTTP1.1协议中默认开启的长链接,一次建立连接,保持TCP的长链接,后续HTTP请求可以复用,提升了响应效率。
缺点是服务端有队头阻塞的现象,就是服务端必须排队处理每一个请求。可以升级到HTTP2,采用多路复用并行处理的方式,不用依次排队了。

❓什么是中间人攻击?- 欺上瞒下(CA)

✏️就是在服务端、客户端中间截获数据,伪造公私钥,欺上瞒下,从而窃取数据。防范办法就是采用CA证书,客户端会验证CA证书的合法性。
CA证书中包含了公钥、网站身份信息等。

❓跨站脚本攻击XSS(Cross site scripting)

✏️主要是在表单输入的地方注入JS脚本内容(如<script>alert('XSS')</script>),从而攻击当前网站,和SQL注入攻击的路径类似,都是非法输入恶意代码。

  • 对前端输入的内容做验证,如电话号码、邮箱、特殊字符等。
  • 对内容转义,vue中用v-textv-bind、文本插值{{}}绑定都是自动做了转义的,因此谨慎使用v-html

Cross site scripting 的简称为XSS,是因为CSS就重名了。

❓跨站请求伪造CSRF(Cross site request forgery)

✏️钓鱼网站利用已登录的cookie凭证发起非法请求,从而完成攻击。

  • 通常需要用到跨域请求,服务端应该对跨域请求进行白名单验证(referer、origin)。
  • 设置客户端cookie的权限,SameSite:跨站不传输cookie。HTTPOnly,客户端不可访问cookie。
  • 服务端添加token验证,而不仅仅靠cookie
  • 在产品设计上,对一些危险操作,如支付转账,应该加上客户验证步骤。

❓JSONP的安全问题

  • 对于服务端,防止非法访问,验证请求的referer、origin是否在白名单。
  • 对于客户端,防止返回的内容存在跨站脚本,对callback返回的内容进行转义。

❓CSP安全策略配置

✏️CSP(Content Security Policy)网页内容安全策略,相当于配置了一个白名单,告诉浏览器那些外部资源可以加载、执行,具体实现是由浏览器完成的。

  • 通过Header配置:Content-Security-Policy: script-src 'self';
  • 通过HTML的的meta标签:<meta http-equiv="Content-Security-Policy" content="script-src 'self'>

前端工程化

❓模块化

module模块是前端工程化的基础,模块让JS可以拆分封装,实现了代码的隔离和依赖。一个JS文件就是一个模块,是一个独立的作用域,模块之间通过export、import来实现导出、导入。
❓包管理
✏️
打包优化
一个JS文件就是一个模块,


性能优化

❓页面性能优化的基本策略

✏️就是从页面的整个生命周期上全面分析,找出瓶颈点进行优化,这里只针对前端部分的优化,后端还会涉及数据库、服务的优化。
1、网络连接:尽快的连接到服务器

  • DNS域名解析,避免太多第三方域名、dns-prefetch域名预解析等。
  • HTTP连接,TCP握手建立连接,使用长链接、升级HTTP2(压缩、并行)。

2、资源加载:尽快的完成资源的加载

  • 减少资源大小:JS、CSS、图片等文件的压缩,启用gzip,按需加载。
  • 减少资源请求次数,文件合并。
  • 针对图片:
    • 选择合适的文件格式:jpg/png/svg/webp/gif。
    • 使用响应式图片(img srcset / picture),小尺寸设备使用小图片。
    • 小图使用雪碧图合并,或者base64编码嵌入文档。
    • 图片懒加载,使用IntersectionObserver交叉观察器。
  • 合理使用缓存,设置静态资源的HTTP缓存(强缓存、协商缓存)。
  • 增加服务端网络带宽,使用CDN,提升下载速度。

3、浏览器解析渲染:尽快的完成页面渲染

  • 根据情况合理使用async、defer,避免阻塞Dom解析。
  • CSS少使用通配符,减少层数。支持GPU加速的CSS:transform、opacity、filter、will-change。
  • 避免频繁的DOM操作引发的页面回流、重绘,图片规定高度、脱离文档流、使用transform等。
  • 事件的防抖和节流,避免无效的操作。

❓Vue的优化策略?

  • Object.freeze()冻结不会变的数据。
  • v-once申明不会更新的数据绑定。
  • v-if/v-show,频繁切换的场景用v-show
  • v-for设置唯一key,避免和v-if同时用,此时可用computed计算属性先过来集合。
  • 合理使用<keep-alive>组件缓存。
  • 路由懒加载:component: () => import('@/views/Home.vue')
  • 尽量避免大量数据的的加载渲染:
    • 拆分数据,避免一次性加载太多数据,如分页、滚动加载、树的懒加载等。
    • 采用虚拟化技术,如vue-virtual-scroller,只渲染可见部分的数据。


✏️


设计模式

设计模式是编程中的最佳实践,用于解决一些复杂的代码问题,可以让你的代码更简洁、更高效,高内聚、低耦合。在JS中结合TS实现会更优优雅,需要用到接口、类、泛型。

  • 单一职责模式:一段代码(类、函数)只有一个职责,高内聚、低耦合,避免各种功能堆积在一起。
  • 开闭原则:对扩展开发,对修改关闭,就封装不变的,开放可扩展的接口。策略模式、
  • 里氏替换原则:子类可以替换父类,继承的关系。
  • 依赖倒转原则:依赖于抽象接口,而不是具体的实现,具体实现可以。策略模式、抽象工厂。
  • 接口隔离原则:采用最小接口原则,不同功能用不同接口定义。

❓单例模式:全局唯一实例

✏️用类的静态方法实现,获取的时候判断是否已存在,不存在就new一个实例。用TS的话还可以用泛型,实现一个通用的单例工厂。

class MySingle {
  constructor() {
    //创建实例
  }
  static getInstance() {
    //静态方法属于类本身,这里的this也就指向类本身
    if (!this.instance)
      this.instance = new MySingle()
    return this.instance;
  }
}
//使用
MySingle.getInstance()

❓策略模式:将策略算法和策略的执行器分开,可灵活扩展策略。

✏️封装一个策略的执行器,然后策略算法可以灵活的扩展添加。

//计算薪资,根据员工绩效等级(A、B、C)计算薪资
const salaryCenter = {
  //计算薪资
  getSalary(value, mode) {
    return this[mode](value);
  },
  //添加绩效等级及其策略
  addStrategy(mode, strategyFunc) {
    this[mode] = strategyFunc;
  }
}

//添加不同绩效等级的策略,这就是对扩展开放
salaryCenter.addStrategy('A', function (value) {
  return value * 1.2;
});
salaryCenter.addStrategy('B', function (value) {
  return value * 1;
});
salaryCenter.addStrategy('C', function (value) {
  return value - 200;
});

//使用
salaryCenter.getSalary(100,'A')

❓工厂模式:把new()封装起来,面向抽象编程。

✏️根据一个标识来创建实例,TS中可以用接口来约束创建的实例。

//工厂模式
class AnimateFactory {
  static Create(type) {
    switch (type) {
      case 'bird':
        return new Bird();
      case 'duck':
        return new Duck();
      default:
        console.log('type not exist:' + type);
    }
  }
}

❓发布订阅模式:发布消息-订阅消息事件

✏️由一个消息中心来管理订阅的消息事件,通过发送消息来触发事件。用于不同组件之间的通信。

//消息中心
class EventCenter {
  constructor() {
    this.task = {};
  }
  //订阅消息,注册消息处理回调
  registry(type, func) {
    this.task[type] ??= [];
    //支持重复注册
    this.task[type].push(func);
  }
  // 发送消息,触发消息回调的执行
  emit(type, ...args) {
    if (!this.task[type]) return;
    this.task[type].forEach(func => {
      func.apply(this, args);
    })
  }
  //用单例返回消息中心实例
  static getInstance() {
    this.instance ??= new EventCenter();
    return this.instance;
  }
}

//使用,注册、发布
EventCenter.getInstance().registry('ele', (food) => {
  console.log('饿了,开始做' + food);
})
EventCenter.getInstance().emit('ele', '面条')

❓观察者模式:对一个目标对象进行观察(监测),当目标变化时触发响应回调。

✏️Vue2的双向绑定,监听数据变化就是拦截属性的get、set,观察数据的变更。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值