汇总

128 阅读9分钟

1.     把一个url拆解成origin、文件名、hash拆解成示例的格式。

// 示例URL

const url = new URL("https://www.example.com/path/to/file.js?v=12345#abcdef");


// 拆解出origin部分

const origin = url.origin;

console.log("Origin:", origin); // 输出:https://www.example.com


// 拆解出文件名

const pathParts = url.pathname.split("/");

const fileName = pathParts[pathParts.length - 1];

console.log("文件名:", fileName); // 输出:file.js


// 拆解出哈希部分

const hash = url.hash.slice(1); // 去除开头的 #

console.log("哈希:", hash); // 输出:abcdef

2.     两个数组合并成一个数组,并进行算法优化。

//将两个数组合并成一个数组的一种常见方法是使用`concat()`方法或扩展运算符(spread operator)。然而,如果你要进行算法优化,可以考虑使用更高效的方法,例如使用指针遍历两个数组并逐个比较元素。

//以下是使用指针遍历优化合并两个已排序数组的示例代码:
function mergeSortedArrays(arr1, arr2) {
    const merged = [];
    let i = 0; // 指向arr1的指针
    let j = 0; // 指向arr2的指针

    while (i < arr1.length && j < arr2.length) {
        if (arr1[i] < arr2[j]) {
            merged.push(arr1[i]);
            i++;
        } else {
            merged.push(arr2[j]);
            j++;
        }
    }

    // 将剩余的元素添加到合并数组中
    while (i < arr1.length) {
        merged.push(arr1[i]);
        i++;
    }

    while (j < arr2.length) {
        merged.push(arr2[j]);
        j++;
    }

    return merged;
}

const array1 = [1, 3, 5, 7];
const array2 = [2, 4, 6, 8];
const mergedArray = mergeSortedArrays(array1, array2);
console.log(mergedArray); // 输出:[1, 2, 3, 4, 5, 6, 7, 8]

3.     设置值的时候是数字,输出的时候变成百分号的格式。

function formatAsPercentage(value) {
    if (typeof value !== 'number') {
        throw new Error('Input must be a number');
    }

    const percentageValue = value * 100;
    const formattedValue = percentageValue.toFixed(2) + '%';
    return formattedValue;
}

const inputValue = 0.75; // 设置的值为 0.75
const formattedOutput = formatAsPercentage(inputValue);
console.log(formattedOutput); // 输出:75.00%

4.     首屏优化的方案,分别从代码、网络和缓存说一下。

首屏优化是指通过优化代码、网络请求和缓存机制,加快网页首次加载时的渲染速度,以提供更好的用户体验。下面我将从代码、网络和缓存三个方面介绍一些首屏优化的方案:

**代码优化:**

1.  **压缩和合并代码:** 使用压缩工具(如UglifyJS)来减小代码体积,并将多个小文件合并成一个大文件,从而减少网络请求次数。
1.  **异步加载脚本:** 将不必要的脚本标记为异步加载,以免阻塞主渲染线程。这可以通过将`<script>`标签的`async``defer`属性设置为实现。
1.  **懒加载:** 对于首屏不必要的内容(如图片、视频等),可以使用懒加载技术,使其在用户滚动到可见区域时再加载。

**网络优化:**

1.  **减少请求次数:** 合并资源、使用雪碧图、将多个小图标合并为字体图标等,可以减少请求次数。
1.  **CDN加速:** 使用内容分发网络(CDN)来将静态资源部署到多个服务器节点,加速资源加载,降低延迟。
1.  **优化图片:** 使用适当的图片格式(如WebP),选择适当的压缩质量,使用图像压缩工具,以减小图片大小。

**缓存优化:**

1.  **浏览器缓存:** 设置适当的HTTP缓存头,如`Cache-Control``Expires`,以便浏览器可以缓存资源,减少重复加载。
1.  **服务端缓存:** 使用服务器端缓存技术,如CDN缓存、页面片段缓存、缓存数据库查询结果等,加快动态内容的加载速度。
1.  **本地存储:** 使用Web StoragelocalStorage、sessionStorage)来缓存用户数据,以减少服务器请求。

总之,首屏优化是一个综合性的工作,需要在代码、网络请求和缓存三个方面做出调整和优化。通过减少请求次数、压缩代码、合理使用缓存等手段,可以显著提升网页的首次加载速度和用户体验。

5.     如果一次性增加100万个用户访问项目,前端角度你会怎么优化。

**1. CDN和静态资源优化:**

-   使用CDN分发静态资源,减轻服务器负担并加速资源加载。
-   压缩和缓存静态资源,减少带宽使用和重复加载。

**2. 前端代码优化:**

-   精简和压缩前端代码,减小页面体积,加快加载速度。
-   使用代码分割和按需加载,仅加载用户需要的部分,减轻初始加载压力。

**3. 前端框架和库选择:**

-   选择轻量级和性能优越的前端框架和库,避免不必要的开销。
-   避免使用过多的第三方插件和库,以减少请求和依赖。

**4. 页面渲染优化:**

-   使用虚拟列表或无限滚动技术,仅渲染用户可见的部分,减少DOM操作和渲染开销。
-   避免复杂的CSS选择器和布局,以减少浏览器重绘和重排。

**5. 数据加载和缓存:**

-   优化数据请求,减少不必要的数据传输和处理。
-   使用浏览器缓存和服务器缓存来减少重复请求。

**6. 响应式设计和移动优化:**

-   确保项目具有良好的响应式设计,适应不同设备和屏幕尺寸。
-   优化移动设备上的性能,避免资源浪费。

**7. 负载均衡和水平扩展:**

-   部署负载均衡来分发流量,防止单一服务器过载。
-   如果需要,考虑水平扩展,添加更多服务器来分担负载。

**8. 性能监测和调优:**

-   使用性能监测工具分析和识别瓶颈,优化关键路径和性能问题。
-   常规性能测试,确保系统能够处理预期的用户量。

**9. 健壮性和错误处理:**

-   设计健壮的前端,处理异常情况和错误,避免因异常而影响用户体验。

**10. 预测和规划:**

-   提前进行容量规划,预测系统在高峰时期的负载,并根据需要做好准备。

综合以上建议,重点是保持代码轻量化、减少资源加载时间、合理利用缓存,以及对性能进行持续监测和调优。同时,与后端团队密切合作,确保整体系统的可扩展性和性能。

6.     分别用es5和es6的方式解决一个继承问题。

// **ES5的构造函数和原型链方式:**
// 基类
function Animal(name) {
    this.name = name;
}

Animal.prototype.sayHello = function() {
    console.log(`Hello, I'm ${this.name}`);
};

// 子类
function Dog(name, breed) {
    Animal.call(this, name);
    this.breed = breed;
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.bark = function() {
    console.log("Woof woof!");
};

// 创建实例并调用方法
const dog = new Dog("Buddy", "Golden Retriever");
dog.sayHello(); // 输出:Hello, I'm Buddy
dog.bark();     // 输出:Woof woof!

// **ES6的类和继承方式:**
// 基类
class Animal {
    constructor(name) {
        this.name = name;
    }

    sayHello() {
        console.log(`Hello, I'm ${this.name}`);
    }
}

// 子类
class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }

    bark() {
        console.log("Woof woof!");
    }
}

// 创建实例并调用方法
const dog = new Dog("Buddy", "Golden Retriever");
dog.sayHello(); // 输出:Hello, I'm Buddy
dog.bark();     // 输出:Woof woof!

7.     session跟jwt的优缺点。

当涉及到用户身份验证和会话管理时,SessionJWTJSON Web Token)是两种常见的方法。它们各自有自己的优点和缺点,下面我会为你详细解释:

**Session 的优点和缺点:**

**优点:**

1.  **安全性较高:** 会话数据存储在服务器端,对于敏感信息比较安全,因为客户端无法直接修改会话数据。
1.  **适用于多种会话管理方式:** 可以使用CookieURL参数来管理会话,也可以结合Token在前端实现会话。
1.  **无需考虑Token生成和解码:** 会话由服务器维护,不需要客户端对Token进行生成和解码操作。

**缺点:**

1.  **服务器存储压力:** 会话数据存储在服务器内存或数据库中,大量会话可能导致服务器存储压力增加。
1.  **扩展性:** 会话可能需要跨多个服务器进行共享,需要实现分布式会话管理机制。
1.  **性能:** 由于需要在服务器端查找会话状态,会导致一定的性能开销。
1.  **不适用于无状态API:** 会话需要在服务器端存储状态,不适用于无状态的API架构。

**JWT 的优点和缺点:**

**优点:**

1.  **无需服务器存储:** JWT将所有会话数据存储在Token中,服务器无需保存会话状态,减轻服务器压力。
1.  **适用于分布式系统:** 由于Token自包含,适用于分布式系统和微服务架构。
1.  **无状态:** JWT是无状态的,可以用于设计RESTful风格的无状态API1.  **可扩展性:** 可在Token中添加自定义声明来实现功能扩展。

**缺点:**

1.  **安全性考虑:** Token存储在客户端,需要确保数据不被篡改,通常需要使用HTTPS协议来保障传输安全性。
1.  **不适用于敏感信息:** 虽然Token可以加密,但仍然不建议将敏感信息存储在Token中。
1.  **Token的过期和刷新:** 需要考虑Token的过期策略和刷新机制,以及处理Token的续期问题。

综合考虑,选择使用Session还是JWT取决于项目需求和架构设计。如果需要更高的安全性和敏感信息存储,以及传统的会话管理,Session可能更适合。如果需要无状态、可扩展性、分布式系统,或者构建无状态APIJWT可能更合适。

8.     jwt的整个流程怎么实现的,实现过程中有哪些难题。

JWTJSON Web Token)是一种用于在网络中传递信息的开放标准。它由三部分组成:HeaderPayloadSignatureJWT的整个流程包括创建和验证Token。以下是JWT的实现流程以及可能遇到的难题:

**JWT的创建流程:**

1.  **创建Header:** Header包含Token的类型和使用的签名算法。通常是一个包含两个字段(`alg``typ`)的JSON对象,通过Base64编码转换为字符串。
1.  **创建Payload:** Payload是包含要传递的信息的部分,也是一个JSON对象。它包含Claim,可以是预定义的标准Claim(如IssuerExpiration等)或自定义Claim1.  **生成Signature:** Signature是对HeaderPayload进行签名的结果,使用指定的密钥和签名算法(如HMACRSA等)。
1.  **合并三部分:** 将Base64编码后的HeaderPayloadSignature以点号(.)连接起来,形成一个完整的JWT。

**JWT的验证流程:**

1.  **解析Token:** 将JWT按点号分隔成三部分,分别对Base64解码,得到HeaderPayload1.  **验证Signature:** 使用相同的密钥和签名算法对HeaderPayload重新计算签名,与原来的Signature进行比较,验证Token的完整性和真实性。
1.  **验证Payload Claims:** 根据业务需求,验证Payload中的各个Claim(如过期时间、发行者等)。

**可能的难题:**

1.  **Token安全性:** 使用合适的密钥管理和算法,以及使用HTTPS来保障Token的安全性,避免泄露。
1.  **过期策略和刷新:** 设计合适的Token过期策略,以及Token刷新机制,确保用户体验和安全性。
1.  **Token存储:** 客户端通常将Token存储在CookielocalStorage中,需要考虑XSS攻击等风险。
1.  **业务逻辑安全性:** 在验证Token时,要确保业务逻辑的安全性,避免越权访问和数据泄露。
1.  **Payload大小和信息:** 不宜将敏感信息直接存储在Token中,因为TokenBase64编码的,可能会增加Payload的大小。
1.  **密钥管理:** 安全管理密钥,特别是在分布式系统中,可能涉及到密钥的分发、更新等问题。
1.  **JWT库选择:** 使用可信任的JWT库来生成和验证Token,避免自行实现可能带来的安全风险。

总之,JWT是一种有用的身份验证和授权机制,但在实现过程中需要关注安全性、过期策略、业务逻辑等多个方面,以确保系统的安全和可靠性。