某日我闲的无聊, 很无聊很无聊, 很无聊很无聊很无聊, 于是用 ChatGPT 尝试回答各位被吊打和拷问时的问题, 于是有了这一篇文章
以下内容由 ChatGPT 生成, 全文仅供参考, 可能存在误导, 内容不要完全相信
第一批被吊打的面试官们来自: 复盘:前端岗位的寒冬,用这3点进行自救 - 掘金 (juejin.cn)
把一个url拆解成origin、文件名、hash拆解成示例的格式。
const url = '<https://www.example.com/some/path/file.html#hash>';
const { origin, pathname, hash } = new URL(url);
const fileName = pathname.split('/').pop();
console.log(origin); // "<https://www.example.com>"
console.log(fileName); // "file.html"
console.log(hash); // "#hash"
两个数组合并成一个数组,并进行算法优化。
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const mergedArray = [...arr1, ...arr2];
console.log(mergedArray); // [1, 2, 3, 4, 5, 6]
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
} else {
const pivot = arr[0];
const left = [];
const right = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
}
const unsortedArray = [6, 5, 3, 1, 8, 7, 2, 4];
const sortedArray = quickSort(unsortedArray);
console.log(sortedArray); // [1, 2, 3, 4, 5, 6, 7, 8]
设置值的时候是数字,输出的时候变成百分号的格式。
const percentage = 0.75;
const formattedPercentage = `${(percentage * 100).toFixed(2)}%`;
console.log(formattedPercentage); // "75.00%"
首屏优化的方案,分别从代码、网络和缓存说一下。
- 代码方面,可以压缩代码、减少HTTP请求、懒加载资源等。
- 网络方面,可以使用CDN、减少请求大小、启用HTTP/2等。
- 缓存方面,可以使用浏览器缓存、服务端缓存等。
如果一次性增加100万个用户访问项目,前端角度你会怎么优化。
- 使用CDN分发静态资源
- 启用HTTP/2
- 减少请求大小
- 使用缓存技术
- 使用懒加载
- 减少DOM操作
- 优化JavaScript代码
分别用es5和es6的方式解决一个继承问题
ES5
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log(this.name);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const myDog = new Dog("Fido", "Labrador");
myDog.sayName(); // "Fido"
console.log(myDog instanceof Animal); // true
console.log(myDog instanceof Dog); // true
ES6
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
}
const myDog = new Dog("Fido", "Labrador");
myDog.sayName(); // "Fido"
console.log(myDog instanceof Animal); // true
console.log(myDog instanceof Dog); // true
XSS 攻击的前端预防
XSS攻击是通过注入恶意代码来篡改网页内容,可以采取以下预防措施:
- 输入验证:对用户输入进行过滤,删除恶意脚本和标签,只保留必要信息。
- 转义字符:将特殊字符转义成文本,例如把
<转义成<。 - 使用HTTP-only cookie:防止cookie被JavaScript读取。
- CSP头:设置Content-Security-Policy头,限制页面加载的资源和脚本。
session & JWT
Session 实现细节
Session 是一种服务器端的会话管理方式。当用户访问服务器时,服务器会为每个会话生成一个唯一的 session ID。在客户端每次请求时,都会将 session ID 发送给服务器,服务器通过 session ID 获取用户的 session 数据。session 数据通常存储在服务器端的内存或数据库中。
JWT 实现细节
JWT 的全称是 JSON Web Token。
JWT 是一种在客户端和服务器间传递用户身份信息的方式。JWT 由三部分组成:Header、Payload、Signature。其中,Header 和 Payload 都是 Base64 编码的 JSON 数据,Signature 是将 Header 和 Payload 通过密钥进行加密生成的。
在客户端登录成功后,服务器会生成一个 JWT 并将其发送给客户端,客户端每次请求时都会将 JWT 发送给服务器。服务器通过验证 JWT 的 Signature 来确认用户的身份信息。由于 JWT 中已经包含了用户的身份信息,所以不需要像 Session 那样在服务器端存储用户的 session 数据。
Session 和 JWT 的优势与劣势
| Session | JWT | |
|---|---|---|
| 优点 | 易于实现、易于管理 | 无需在服务器上存储信息,易于在分布式系统中使用 |
| 缺点 | 需要在服务器上存储信息,占用资源,不适合分布式系统 | 需要在客户端存储信息,存在安全风险 |
JWT 的实现流程
- 客户端发送登录请求,服务器验证用户身份,生成 JWT 并返回给客户端。
- 客户端收到 JWT,将其存储在本地(例如 localStorage 或 cookie)。
- 客户端每次请求时,都将 JWT 发送给服务器。
- 服务器端通过验证 JWT 的 Signature 来确认用户的身份信息。
JWT 的安全性如何保障
在使用JWT时需要注意以下安全问题:
- 加密算法的选择:需要选择安全性高的加密算法,例如HS256。
- 密钥管理:需要妥善管理密钥,避免密钥泄露。
- JWT的有效期:需要根据实际情况设置JWT的有效期,避免JWT被恶意使用。
- 避免将敏感信息存储在JWT中:JWT虽然可以传递用户身份信息,但不应该存储敏感信息,例如密码等。
- 在使用非对称加密时,需要保证公钥的安全性。
const url = '<https://www.example.com/some/path/file.html#hash>';
const { origin, pathname, hash } = new URL(url);
const fileName = pathname.split('/').pop();
console.log(origin); // "<https://www.example.com>"
console.log(fileName); // "file.html"
console.log(hash); // "#hash"
两个数组合并成一个数组,并进行算法优化。
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const mergedArray = [...arr1, ...arr2];
console.log(mergedArray); // [1, 2, 3, 4, 5, 6]
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
} else {
const pivot = arr[0];
const left = [];
const right = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
}
const unsortedArray = [6, 5, 3, 1, 8, 7, 2, 4];
const sortedArray = quickSort(unsortedArray);
console.log(sortedArray); // [1, 2, 3, 4, 5, 6, 7, 8]
设置值的时候是数字,输出的时候变成百分号的格式。
const percentage = 0.75;
const formattedPercentage = `${(percentage * 100).toFixed(2)}%`;
console.log(formattedPercentage); // "75.00%"
首屏优化的方案,分别从代码、网络和缓存说一下。
- 代码方面,可以压缩代码、减少HTTP请求、懒加载资源等。
- 网络方面,可以使用CDN、减少请求大小、启用HTTP/2等。
- 缓存方面,可以使用浏览器缓存、服务端缓存等。
如果一次性增加100万个用户访问项目,前端角度你会怎么优化。
- 使用CDN分发静态资源
- 启用HTTP/2
- 减少请求大小
- 使用缓存技术
- 使用懒加载
- 减少DOM操作
- 优化JavaScript代码
分别用es5和es6的方式解决一个继承问题
ES5
function Animal(name) {
this.name = name;
}
Animal.prototype.sayName = function() {
console.log(this.name);
};
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const myDog = new Dog("Fido", "Labrador");
myDog.sayName(); // "Fido"
console.log(myDog instanceof Animal); // true
console.log(myDog instanceof Dog); // true
ES6
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
}
const myDog = new Dog("Fido", "Labrador");
myDog.sayName(); // "Fido"
console.log(myDog instanceof Animal); // true
console.log(myDog instanceof Dog); // true
XSS 攻击的前端预防
XSS攻击是通过注入恶意代码来篡改网页内容,可以采取以下预防措施:
- 输入验证:对用户输入进行过滤,删除恶意脚本和标签,只保留必要信息。
- 转义字符:将特殊字符转义成文本,例如把
<转义成<。 - 使用HTTP-only cookie:防止cookie被JavaScript读取。
- CSP头:设置Content-Security-Policy头,限制页面加载的资源和脚本。
session & JWT
Session 实现细节
Session 是一种服务器端的会话管理方式。当用户访问服务器时,服务器会为每个会话生成一个唯一的 session ID。在客户端每次请求时,都会将 session ID 发送给服务器,服务器通过 session ID 获取用户的 session 数据。session 数据通常存储在服务器端的内存或数据库中。
JWT 实现细节
JWT 的全称是 JSON Web Token。
JWT 是一种在客户端和服务器间传递用户身份信息的方式。JWT 由三部分组成:Header、Payload、Signature。其中,Header 和 Payload 都是 Base64 编码的 JSON 数据,Signature 是将 Header 和 Payload 通过密钥进行加密生成的。
在客户端登录成功后,服务器会生成一个 JWT 并将其发送给客户端,客户端每次请求时都会将 JWT 发送给服务器。服务器通过验证 JWT 的 Signature 来确认用户的身份信息。由于 JWT 中已经包含了用户的身份信息,所以不需要像 Session 那样在服务器端存储用户的 session 数据。
Session 和 JWT 的优势与劣势
| Session | JWT | |
|---|---|---|
| 优点 | 易于实现、易于管理 | 无需在服务器上存储信息,易于在分布式系统中使用 |
| 缺点 | 需要在服务器上存储信息,占用资源,不适合分布式系统 | 需要在客户端存储信息,存在安全风险 |
JWT 的实现流程
- 客户端发送登录请求,服务器验证用户身份,生成 JWT 并返回给客户端。
- 客户端收到 JWT,将其存储在本地(例如 localStorage 或 cookie)。
- 客户端每次请求时,都将 JWT 发送给服务器。
- 服务器端通过验证 JWT 的 Signature 来确认用户的身份信息。
JWT 的安全性如何保障
在使用JWT时需要注意以下安全问题:
- 加密算法的选择:需要选择安全性高的加密算法,例如HS256。
- 密钥管理:需要妥善管理密钥,避免密钥泄露。
- JWT的有效期:需要根据实际情况设置JWT的有效期,避免JWT被恶意使用。
- 避免将敏感信息存储在JWT中:JWT虽然可以传递用户身份信息,但不应该存储敏感信息,例如密码等。
- 在使用非对称加密时,需要保证公钥的安全性。
JS 事件循环
JavaScript 事件循环是一种机制,可以让 JavaScript 执行非阻塞 I/O 操作。它通过不断检查调用栈中的新任务并逐个执行它们来工作。任务可以添加到任务队列中,并在事件循环的后续迭代中执行。这使得 JavaScript 可以在不阻塞主线程的情况下同时处理多个任务。
宏任务与微任务
JavaScript 中的任务分为两种类型:宏任务和微任务。
宏任务包括以下几种:
- 解析 HTML 标记
- 执行主线程代码
- 执行 setTimeout 和 setInterval 回调函数
- 执行 I/O 操作
微任务包括以下几种:
- 执行 Promise 的 then 方法
- 执行 MutationObserver 回调函数
- 执行 process.nextTick
在事件循环中,所有的宏任务都会被依次执行,而微任务则会在每个宏任务执行完毕后依次执行。
这意味着微任务可以先于下一个宏任务执行。
闭包
下面是一个输出 5 个 5 的闭包示例代码:
function createPrintFunction() {
const result = [];
for (let i = 0; i < 5; i++) {
result.push(function() {
console.log(i);
});
}
return result;
}
const printFunctions = createPrintFunction();
printFunctions.forEach(func => func()); // 输出 5 个 5
这个例子中,createPrintFunction 函数返回一个包含 5 个函数的数组。每个函数都会输出外部函数的变量 i 的值。由于 i 在循环中是使用 let 声明的,每次循环都会创建一个新的变量。而且,由于闭包的特性,每个函数都引用了不同的变量,因此每个函数输出的值都是 5。所以最终输出的结果是 5 个 5。
如何实现路由懒加载
- 路由懒加载是一种优化前端性能的方式
- 它可以延迟加载页面中的 JavaScript 代码
- 它的实现方式是将每个路由对应的组件文件单独打包成一个 JavaScript 文件
- 当用户访问该路由时再动态加载该文件
- 这可以通过 webpack 的
import()方法来实现
示例代码:
const Home = () => import("./views/Home.vue");
const About = () => import("./views/About.vue");
const routes = [
{ path: "/", component: Home },
{ path: "/about", component: About }
];
- 在页面加载时一次性加载所有组件会导致页面加载速度变慢,使用路由懒加载可以避免这个问题
- Webpack 会动态加载该文件并将其添加到页面中
- 这样可以避免在页面加载时一次性加载所有组件,从而提高页面加载速度