被吊打的面试官-1

628 阅读2分钟

某日我闲的无聊, 很无聊很无聊, 很无聊很无聊很无聊, 于是用 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攻击是通过注入恶意代码来篡改网页内容,可以采取以下预防措施:

  • 输入验证:对用户输入进行过滤,删除恶意脚本和标签,只保留必要信息。
  • 转义字符:将特殊字符转义成文本,例如把<转义成&lt;
  • 使用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 的优势与劣势

SessionJWT
优点易于实现、易于管理无需在服务器上存储信息,易于在分布式系统中使用
缺点需要在服务器上存储信息,占用资源,不适合分布式系统需要在客户端存储信息,存在安全风险

JWT 的实现流程

  1. 客户端发送登录请求,服务器验证用户身份,生成 JWT 并返回给客户端。
  2. 客户端收到 JWT,将其存储在本地(例如 localStorage 或 cookie)。
  3. 客户端每次请求时,都将 JWT 发送给服务器。
  4. 服务器端通过验证 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攻击是通过注入恶意代码来篡改网页内容,可以采取以下预防措施:

  • 输入验证:对用户输入进行过滤,删除恶意脚本和标签,只保留必要信息。
  • 转义字符:将特殊字符转义成文本,例如把<转义成&lt;
  • 使用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 的优势与劣势

SessionJWT
优点易于实现、易于管理无需在服务器上存储信息,易于在分布式系统中使用
缺点需要在服务器上存储信息,占用资源,不适合分布式系统需要在客户端存储信息,存在安全风险

JWT 的实现流程

  1. 客户端发送登录请求,服务器验证用户身份,生成 JWT 并返回给客户端。
  2. 客户端收到 JWT,将其存储在本地(例如 localStorage 或 cookie)。
  3. 客户端每次请求时,都将 JWT 发送给服务器。
  4. 服务器端通过验证 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 会动态加载该文件并将其添加到页面中
  • 这样可以避免在页面加载时一次性加载所有组件,从而提高页面加载速度