3. 跨域解决方法。
跨域是指在浏览器端,当一个域名的网页通过ajax、dom等方式去请求另一个域名下的资源时,会被浏览器阻止的安全机制。为了解决跨域问题,可以采取以下几种常见的方法:
-
JSONP(JSON with Padding):JSONP是一种利用<script>标签的跨域技术,通过动态创建<script>标签,并设置其src属性为要访问的跨域资源的URL,然后在资源的URL后面加上一个回调函数名,服务器端返回的数据将会作为回调函数的参数。JSONP的缺点是只支持GET请求,且存在安全性风险。
-
CORS(Cross-Origin Resource Sharing):CORS是一种在服务器端进行配置的跨域解决方案,通过设置响应头中的
Access-Control-Allow-Origin字段来允许指定的域名访问资源。服务器端可以设置允许的来源域名、允许的请求方法、允许的自定义头部等,从而实现安全的跨域访问。 -
代理服务器:在同域名下部署一个代理服务器,将跨域请求发送到代理服务器上,由代理服务器转发请求到目标服务器,再将响应返回给客户端。这样就绕过了浏览器的同源策略限制。
-
反向代理:在目标服务器所在的域名下部署一个反向代理服务器,将跨域请求发送到反向代理服务器上,再由反向代理服务器将请求转发到目标服务器。这样客户端发送的请求看起来是同源的,从而避免了跨域问题。
-
跨域资源共享文件上传(CORS file upload):利用HTML5中的FormData对象和XMLHttpRequest Level 2中的新特性,可以实现跨域的文件上传。在服务器端配置CORS来允许跨域文件上传。
-
WebSocket协议:WebSocket协议不受同源策略的限制,可以实现跨域通信。通过在服务器端实现WebSocket服务器来实现跨域通信。
总的来说,针对不同的场景和需求,可以选择适合的跨域解决方案。CORS是目前推荐的跨域解决方案,具有较好的安全性和可靠性,但在一些旧版浏览器上可能存在兼容性问题。JSONP适用于简单的跨域请求,但存在一定的安全风险。代理服务器和反向代理需要额外的服务器资源和配置,适用于复杂的跨域场景。
- 反问。
09/19 笔试
- 第一题不记得了,比较简单
- 第二题:以下数据结构中,id 代表部门编号,name 是部门名称,parentId 是父部门编号,为 0 代表一级部门,现在要求实现一个 convert 方法,把原始 list 转换成树形结构,parentId 为多少就挂载在该 id 的属性 children 数组下,结构如下:
let list =[
{id:1,name:'部门A',parentId:0},
{id:2,name:'部门B',parentId:0},
{id:3,name:'部门C',parentId:1},
{id:4,name:'部门D',parentId:1},
{id:5,name:'部门E',parentId:2},
{id:6,name:'部门F',parentId:3},
{id:7,name:'部门G',parentId:2},
{id:8,name:'部门H',parentId:4}
];
const result = convert(list, ...);
// 转化后
let result = [
{
id: 1,
name: '部门A',
parentId: 0,
children: [
{
id: 3,
name: '部门C',
parentId: 1,
children: [
{
id: 6,
name: '部门F',
parentId: 3
}, {
id: 16,
name: '部门L',
parentId: 3
}
]
},
{
id: 4,
name: '部门D',
parentId: 1,
children: [
{
id: 8,
name: '部门H',
parentId: 4
}
]
}
]
},
···
];
你可以使用递归来实现将原始列表转换为树形结构。以下是一个JavaScript的实现示例:
function convert(list, parentId = 0) {
const tree = [];
list.forEach(item => {
if (item.parentId === parentId) {
const children = convert(list, item.id);
if (children.length > 0) {
item.children = children;
}
tree.push(item);
}
});
return tree;
}
let list =[
{id:1,name:'部门A',parentId:0},
{id:2,name:'部门B',parentId:0},
{id:3,name:'部门C',parentId:1},
{id:4,name:'部门D',parentId:1},
{id:5,name:'部门E',parentId:2},
{id:6,name:'部门F',parentId:3},
{id:7,name:'部门G',parentId:2},
{id:8,name:'部门H',parentId:4}
];
const result = convert(list);
console.log(result);
这个 convert 函数接受一个列表和一个可选的父ID参数(默认为0),然后遍历列表,找到所有父ID等于给定父ID的项,并递归地调用自身来找到它们的子项。然后,将这些子项添加到当前项的 children 属性中,并将当前项添加到树中。最后返回树形结构。
在这个例子中,convert 函数的调用将返回转换后的树形结构,可以直接输出或进一步处理。
09/27 二面
基础八股:
kk1. TCP为什么三次握手,为什么四次挥手
TCP的三次握手和四次挥手是TCP协议用于建立和终止连接时的重要过程,其设计是为了确保通信的可靠性和稳定性。
三次握手(Three-way Handshake):
- 第一次握手:客户端向服务器发送一个SYN(同步)标志位的数据包,请求建立连接。
- 第二次握手:服务器收到客户端的SYN请求后,向客户端发送一个ACK(确认)标志位和一个SYN标志位的数据包,确认请求并表示自己也愿意建立连接。
- 第三次握手:客户端收到服务器的确认后,向服务器发送一个ACK标志位的数据包,表示连接建立成功。
三次握手的目的是确保双方都愿意建立连接,并且都能收到对方的确认。这样可以防止因网络延迟或丢包等原因造成的连接失败或不稳定性。
四次挥手(Four-way Handshake):
- 第一次挥手:当客户端或服务器要断开连接时,发送一个FIN(结束)标志位的数据包,表示自己已经不再发送数据了。
- 第二次挥手:接收到对方的FIN请求后,对方发送一个ACK标志位的数据包,确认收到断开连接的请求。
- 第三次挥手:当服务器或客户端准备好断开连接时,也发送一个FIN标志位的数据包。
- 第四次挥手:对方接收到断开连接的请求后,发送一个ACK标志位的数据包,表示确认收到并同意断开连接。
四次挥手的目的是双方都能确认连接已经断开,确保数据传输完整性和可靠性。因为TCP是全双工的协议,客户端和服务器都可以主动发起断开连接的请求,所以需要四次挥手来完全释放连接。
3. 跨域解决什么问题,为什么script、img等标签还是可以跨域,只对ajax、dom等有跨域限制。(不太懂)
跨域(Cross-Origin)指的是在浏览器端,当一个域名的网页通过ajax、dom等方式去请求另一个域名下的资源时,会被阻止的安全机制。这种安全机制存在的原因是为了保护用户的隐私和安全,防止恶意网站获取用户的敏感信息或进行恶意操作。
跨域问题的根源在于浏览器的同源策略(Same-Origin Policy),同源策略规定了不同域名之间的安全限制。同源策略要求网页的协议、域名、端口必须完全相同,否则就会产生跨域问题。
然而,并非所有的跨域请求都被限制,某些标签和请求方式是允许跨域的。例如:
-
<script>标签:当使用<script>标签引入外部脚本时,例如从CDN加载jQuery库,这样的请求是允许跨域的。这是因为<script>标签的src属性是不受同源策略的限制的,浏览器允许从任何域名加载脚本文件。
-
<img>标签:同样地,当使用<img>标签加载外部图片时,例如从其他网站加载图片,这样的请求也是允许跨域的。因为加载图片不涉及与服务器交互,浏览器不会阻止跨域请求。
-
<link>标签和<a>标签:通过<link>标签引入样式表文件或者<a>标签进行页面跳转时,也是允许跨域的。
这些标签和请求方式之所以允许跨域,是因为它们的行为不会对其他网站产生安全风险,不会导致信息泄露或者恶意操作。而对于需要与服务器交互的ajax请求、DOM操作等,由于可能涉及到用户的敏感信息和重要操作,因此受到同源策略的限制。
- HTTP缓存,强缓存和协商缓存分别节省了哪些东西。 HTTP缓存是一种在Web应用中常用的技术,用于减少网络请求和加快页面加载速度。它通过在客户端和服务器之间缓存资源(如HTML文件、CSS文件、JavaScript文件、图片等),以避免重复的网络请求,提高了用户的访问速度和网站的性能。
在HTTP缓存中,主要包括两种缓存策略:强缓存和协商缓存。
-
强缓存:强缓存是指浏览器直接从本地缓存中获取资源,而不发送请求到服务器。强缓存可以通过设置响应头中的
Cache-Control和Expires字段来实现。当浏览器再次请求相同资源时,如果资源的缓存未过期,则直接从本地缓存中获取,无需发送请求到服务器。强缓存节省了网络带宽和服务器资源,因为浏览器无需发送请求到服务器,而是直接从本地缓存中获取资源。这降低了服务器的负载和网络传输的成本,提高了页面加载速度和用户体验。
-
协商缓存:协商缓存是指浏览器发送请求到服务器,但服务器返回的响应是一个304 Not Modified状态码,表示资源未发生变化,可以继续使用本地缓存。协商缓存可以通过设置响应头中的
Last-Modified和ETag字段来实现。协商缓存节省了服务器的带宽和资源,因为服务器可以根据请求中的
If-Modified-Since和If-None-Match字段判断资源是否发生了变化,只有在资源发生变化时才返回完整的资源内容,否则返回一个304状态码,告诉浏览器可以继续使用本地缓存。
总的来说,强缓存和协商缓存都节省了网络带宽、服务器资源和用户等待时间,提高了页面加载速度和用户体验。强缓存通过直接从本地缓存中获取资源,减少了网络请求和服务器的负载;而协商缓存通过与服务器协商确定资源是否发生变化,避免了不必要的资源传输,进一步提高了缓存的效率。
3. XSS防御方法、CSRF相关
XSS(Cross-Site Scripting)和CSRF(Cross-Site Request Forgery)是常见的Web安全攻击,需要采取相应的防御措施来保护Web应用的安全。
XSS防御方法:
-
输入验证:对用户输入的数据进行验证和过滤,确保用户提交的数据符合预期格式和内容,避免恶意脚本的注入。可以使用白名单过滤或黑名单过滤来防止XSS攻击。
-
输出编码:对用户输入的数据进行合适的编码处理,将特殊字符转义成HTML实体,例如将
<转义为<、>转义为>等,防止恶意脚本的执行。 -
CSP(Content Security Policy):通过CSP设置HTTP头部,限制页面中JavaScript的执行和外部资源的加载,从而减少XSS攻击的可能性。
-
HTTPOnly Cookie:在设置Cookie时使用HTTPOnly属性,防止恶意脚本通过document.cookie获取Cookie的值,减少用户身份信息泄露的风险。
-
安全头部:使用X-XSS-Protection头部和X-Content-Type-Options头部来加强浏览器的安全策略,防止XSS攻击。
CSRF防御方法:
-
CSRF Token:在表单提交或者请求中加入CSRF Token,用于验证请求的合法性。服务器生成一个随机的Token,并将Token嵌入到页面中的表单或者请求参数中,在接收到请求时验证Token的有效性。
-
SameSite Cookie:设置Cookie的SameSite属性为Strict或者Lax,限制Cookie的发送,避免跨站点请求伪造攻击。
-
Referer Check:检查请求的Referer头部,确保请求来自合法的来源。
-
双重Cookie验证:将用户的身份信息存储在Cookie中,并使用第二个Cookie来验证用户身份,例如将Cookie中的用户ID与Session绑定。
-
使用验证码:在涉及到敏感操作的请求(如修改密码、转账等)中,要求用户输入验证码进行二次确认,降低CSRF攻击的风险。
综合来看,XSS和CSRF攻击都是常见的Web安全威胁,需要采取一系列综合的防御措施来保护Web应用的安全性。输入验证、输出编码、CSP、CSRF Token等方法都是有效的防御手段,可以根据具体情况选择合适的方法来提高Web应用的安全性。
3. HTML语义化
HTML语义化是指使用恰当的HTML标签来描述网页文档结构和内容,以及各个部分之间的关系,使得页面的结构和内容对搜索引擎、浏览器和开发者都更具有可读性和可理解性。通过合适的语义标签,可以增强网页的可访问性、搜索引擎优化(SEO)和开发效率。
以下是HTML语义化的一些重要原则和常见实践:
-
选择合适的标签:使用具有明确含义的HTML标签来描述内容,如
<header>、<nav>、<main>、<footer>、<article>、<section>等。 -
避免滥用
<div>和<span>:<div>和<span>是最通用的容器标签,但滥用它们会降低页面的可读性和可维护性。应尽量使用更具语义化的标签来表示内容。 -
结构清晰:使用语义化标签来清晰地组织页面结构,使得页面的层次结构清晰明了,便于阅读和维护。
-
提高可访问性:合适的语义化标签能够提高页面的可访问性,有助于屏幕阅读器和搜索引擎理解页面内容,为视障人士提供更好的浏览体验。
-
SEO优化:搜索引擎能够更好地理解页面内容和结构,从而提高页面在搜索结果中的排名。
-
增强页面意义:语义化标签能够使页面的意义更加明确,减少歧义性,有助于开发者理解和维护页面代码。
举例来说,一个典型的语义化HTML结构可能如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<header>
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
</header>
<main>
<section>
<article>
<h2>Blog Post Title</h2>
<p>Blog post content goes here...</p>
</article>
</section>
<aside>
<h3>Side Bar</h3>
<ul>
<li>Widget 1</li>
<li>Widget 2</li>
<li>Widget 3</li>
</ul>
</aside>
</main>
<footer>
<p>© 2024 My Website</p>
</footer>
</body>
</html>
以上结构清晰,使用了诸如<header>、<nav>、<main>、<section>、<article>、<aside>和<footer>等语义化标签,使得页面的结构和内容更具有可读性和可理解性。
3. TS泛型,有什么作用
TypeScript中的泛型(Generics)是一种在定义函数、类、接口等时,用于增强代码的可重用性、灵活性和类型安全性的特性。泛型允许我们在定义时不指定具体的类型,而是在使用时再确定类型,从而使代码可以适用于多种不同类型的数据,提高了代码的通用性和灵活性。
泛型的作用包括但不限于以下几个方面:
-
代码重用:泛型可以使代码更通用,从而增加代码的可重用性。通过泛型,可以编写与数据类型无关的代码,使其可以适用于不同类型的数据。
-
类型安全:泛型可以在编译时检查类型,提高了代码的类型安全性。通过泛型,可以在编译阶段捕获并预防一些类型错误,避免在运行时出现类型相关的错误。
-
抽象数据类型:泛型可以用于定义抽象数据类型,使代码更具有通用性和抽象性。通过泛型,可以定义与具体类型无关的数据结构和算法,使其可以适用于不同类型的数据。
-
容器类的支持:泛型可以用于定义容器类(如数组、链表、栈、队列等),使其可以存储和操作各种不同类型的数据。
-
提高性能:泛型可以提高代码的性能,减少代码的重复和冗余。通过泛型,可以将通用的逻辑抽象出来,减少重复代码的编写,从而提高了代码的效率和性能。
总的来说,泛型是一种非常强大的特性,它可以使代码更具有通用性、灵活性和类型安全性,从而提高了代码的质量和可维护性。
3. 原型链,es6 class 的编译产物(两次了,看来这个一定得会)
原型链是JavaScript中的一个重要概念,它是实现继承和属性查找的基础。在JavaScript中,每个对象都有一个原型(prototype),而原型又是一个对象,这种关系构成了原型链。
-
原型链的构成:
- 每个对象都有一个原型(prototype),可以通过
__proto__属性访问它的原型对象。 - 每个原型对象也有自己的原型,即原型链上的下一个对象,通过原型对象的
__proto__属性向上查找。 - 原型链的顶端是一个特殊的对象
Object.prototype,它的__proto__属性为null,表示原型链的终点。
- 每个对象都有一个原型(prototype),可以通过
-
原型链的作用:
- 实现继承:当访问对象的属性或方法时,如果对象本身没有定义该属性或方法,则会沿着原型链向上查找,直到找到对应的属性或方法为止。
- 共享属性和方法:原型链上的属性和方法是所有对象共享的,可以节省内存空间。
-
ES6 Class的编译产物:
- ES6引入了Class语法糖来定义类,但实际上JavaScript仍然是基于原型的语言。ES6 Class的编译产物仍然是基于原型的。
- 在ES6 Class中,类的定义会被转换成构造函数和原型方法的组合。
- 类的构造函数对应于ES5中的构造函数,类的原型方法对应于ES5中的原型方法。
下面是一个简单的示例,演示了ES6 Class的编译产物:
// ES6 Class语法
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
// 编译后的ES5代码
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a noise.`);
};
可以看到,ES6中的Class定义被转换成了构造函数和原型方法的组合,从而实现了类的继承和原型链的机制。
3. 垃圾回收机制,引用计数法、标记清楚法。
垃圾回收是一种自动管理内存的机制,用于检测和释放不再被程序使用的内存资源,以避免内存泄漏和提高内存利用率。常见的垃圾回收算法包括引用计数法和标记清除法。
-
引用计数法(Reference Counting):
- 基本原理:为每个对象维护一个引用计数器,记录该对象被引用的次数。当对象被引用时,引用计数器加1;当对象引用失效时,引用计数器减1。当引用计数器为0时,表示该对象不再被程序使用,可以被回收。
- 优点:简单、实时性好,及时回收不再使用的内存。
- 缺点:无法处理循环引用的情况,循环引用会导致对象之间的引用计数永远不为0,从而导致内存泄漏。
-
标记清除法(Mark and Sweep):
- 基本原理:通过根节点(通常是全局对象)开始遍历内存中的所有对象,标记所有被引用的对象。然后,清除所有未被标记的对象,即可被释放的对象。最后,清除所有的标记,以便下一次垃圾回收。
- 优点:能够处理循环引用的情况,通过标记阶段识别循环引用,并在清除阶段将循环引用的对象释放。
- 缺点:会造成程序暂停,影响性能。同时,标记清除法可能会产生内存碎片,降低内存的利用率。
在实际应用中,现代的垃圾回收器通常会综合利用引用计数法和标记清除法的优势,采用更复杂的算法(如标记-整理法、分代垃圾回收等),以提高垃圾回收的效率和性能。
简历项目相关:
- 微前端作用及优势,spa 、mpa优缺点。为什么不用 iframe 而用 qiankun。微前端带来了哪些额外工作。
微前端是一种架构思想,旨在解决单体前端应用在大型项目中的复杂性和耦合性问题。它将一个大型前端应用拆分成多个小型应用,每个小型应用都可以独立开发、部署和运行,最终组合成一个完整的前端应用。微前端的主要作用和优势包括:
-
作用:
- 提高团队的独立性:不同团队可以独立开发、测试和部署各自的模块,减少了团队之间的依赖和沟通成本。
- 加速项目交付速度:各个小型应用可以并行开发和部署,提高了开发效率和项目交付速度。
- 提高系统的可维护性:将大型前端应用拆分成小型应用,降低了代码耦合度,使得系统更易于维护和迭代升级。
-
优势:
- 技术栈灵活性:不同的小型应用可以选择适合自己的技术栈和框架,提高了技术选型的灵活性。
- 增量升级:可以单独更新某个小型应用的版本,而不必重新发布整个系统,降低了升级风险。
- 自治性和可扩展性:各个小型应用可以独立部署和扩展,灵活应对业务变化和流量波动。
对比单页面应用(SPA)和多页面应用(MPA)的优缺点:
-
SPA:
- 优点:
- 用户体验好:页面加载速度快,具有流畅的页面切换和交互体验。
- 前后端分离:前端负责UI展示和交互逻辑,后端负责数据接口和业务逻辑,前后端开发可以并行进行。
- 缺点:
- 首屏加载慢:由于需要加载大量JavaScript和CSS资源,首屏加载速度可能较慢。
- SEO不友好:由于页面内容大部分由JavaScript动态生成,搜索引擎难以抓取和索引页面内容。
- 优点:
-
MPA:
- 优点:
- SEO友好:每个页面都有独立的URL,搜索引擎可以直接抓取和索引页面内容。
- 首屏加载快:每个页面只加载所需的资源,可以减少首屏加载时间。
- 缺点:
- 用户体验差:页面切换需要重新加载整个页面,交互体验较差。
- 开发维护成本高:每个页面都是一个独立的应用,开发和维护成本较高。
- 优点:
为什么不用 iframe 而用 qiankun:
-
性能优化:iframe会导致页面嵌套,影响页面的加载性能和渲染速度,而qiankun使用的是Web Components技术,可以更好地实现页面的性能优化和资源共享。
-
状态管理:qiankun提供了完善的状态管理机制,可以实现各个微前端应用之间的状态共享和通信,而iframe之间的通信较为复杂和受限。
-
路由管理:qiankun提供了统一的路由管理和导航功能,可以实现多个微前端应用之间的无缝路由切换和页面跳转,而iframe需要手动管理路由切换,实现起来较为复杂。
-
安全性:iframe存在一些安全风险,如跨域问题和恶意脚本注入等,而qiankun通过沙箱技术和安全策略,可以有效防止安全漏洞的发生。
微前端带来的额外工作包括:
- 拆分应用:将大型前端应用拆分成多个小型应用,需要进行应用拆分和模块化设计。
- 路由管理:管理各个微前端应用之间的路由跳转和页面切换。
- 状态管理:管理各个微前端应用之间的状态共享和通信。
- 部署和运维:独立部署和运维各个微前端应用,需要建立相应的部署流程和监控系统。
- 集成测试:进行各个微前端应用之间的集成测试,确保整体系统的稳定性和可靠性。
3. webpack 插件相关。打包过程静态资源自动上传 cdn。
实现Webpack插件来自动上传静态资源到CDN的过程可以分为以下几个步骤:
-
配置CDN信息:首先需要在Webpack配置文件中配置CDN的相关信息,包括CDN的域名、认证信息(如Access Key和Secret Key)、上传目录等。
-
编写Webpack插件:编写一个Webpack插件,监听Webpack打包完成的事件,在打包完成后将静态资源上传到CDN。可以通过调用CDN的API或使用CDN提供的CLI工具来实现上传功能。
-
实现上传功能:在Webpack插件中实现上传静态资源到CDN的功能,可以使用CDN提供的SDK或第三方库来实现文件上传。上传前可以对文件进行压缩、加密等处理,确保文件上传到CDN后能够正常使用。
-
配置Webpack插件:将编写的Webpack插件配置到Webpack配置文件中,确保在Webpack打包过程中自动触发上传静态资源到CDN的功能。
-
测试和优化:完成插件编写后,需要进行测试确保上传功能正常运行,并根据实际情况进行优化,如提高上传速度、处理上传失败等异常情况。
下面是一个简单的示例,演示了如何编写一个Webpack插件来实现静态资源自动上传到CDN的过程:
// webpack-cdn-plugin.js
const CDNUploader = require('cdn-uploader'); // 假设存在一个CDN上传工具库
class CDNUploadPlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
compiler.hooks.afterEmit.tapAsync('CDNUploadPlugin', (compilation, callback) => {
// 获取静态资源路径
const assets = Object.keys(compilation.assets).map(asset => compilation.assets[asset].existsAt);
// 上传静态资源到CDN
const uploader = new CDNUploader(this.options);
uploader.upload(assets)
.then(() => {
console.log('静态资源上传到CDN成功!');
callback();
})
.catch(err => {
console.error('静态资源上传到CDN失败:', err);
callback(err);
});
});
}
}
module.exports = CDNUploadPlugin;
然后在Webpack配置文件中引入并配置这个插件:
// webpack.config.js
const CDNUploadPlugin = require('./webpack-cdn-plugin');
module.exports = {
// 其他配置...
plugins: [
new CDNUploadPlugin({
domain: 'https://cdn.example.com',
accessKey: 'your-access-key',
secretKey: 'your-secret-key',
directory: '/assets', // 上传到CDN的目录
})
]
};
这样配置后,在Webpack打包完成后,插件会自动将静态资源上传到配置的CDN上。
3. 通用上传组件重构维护,分片上传并发控制。(这里扯了好久,问异步任务的并发控制有什么意义,不是真正的并发)应用场景、优化的效果等等。
异步任务的并发控制是指在执行异步任务时限制同时执行的任务数量,以避免因过多的并发任务导致系统资源耗尽或性能下降的问题。这在通用上传组件中实现分片上传时尤为重要。
应用场景:
- 上传大文件时,为了避免一次性上传大量数据导致网络拥塞或服务器压力过大,常采用分片上传的方式。每个分片都是一个独立的异步任务,通过并发控制可以控制同时上传的分片数量,避免过多的网络请求同时发送。
优化效果:
- 控制并发上传任务数量可以减少网络负载和服务器压力,提高上传性能和稳定性。
- 通过适当调整并发上传任务数量,可以使系统在上传大文件时保持平衡的性能表现,既能够充分利用网络带宽,又能够避免过度消耗系统资源。
具体实现并发控制可以采用以下方法之一:
- 限制并发数:设置一个最大并发数,保证同时进行的异步任务数量不超过该数值。
- 队列控制:使用队列管理异步任务,当某个任务完成后,从队列中取出下一个任务执行。
- 节流控制:根据系统负载和网络情况动态调整并发数量,保持系统在最佳状态下运行。
在上传组件中应用并发控制能够有效地提高上传性能和稳定性,避免上传过程中出现的各种问题,如网络超时、服务器崩溃等。
- 反问。
感觉最后没答好,等结果了。
10/18 三面
自我介绍
没有八股和简历提问,主要聊了技术视野和对前端技术未来发展方向的探讨,以及为什么选前端、自身的一些特点等等。
泡池子
10/31 更新,状态从面试中变为等待面试结果
作者:s2mple
链接:www.nowcoder.com/discuss/536…
来源:牛客网