面试题积累1

130 阅读8分钟

三维家

2024-08-11

  1. 对于 new 出来的对象 a 的属性查找的顺序 person = new Person(); person.a

    答:先从 Person 上找,找不到,去找 Person 的原型链,找不到,到顶层 找不到 返回 undefined

    G:当你用 new 创建对象时,属性查找顺序是:首先在对象自身查找属性,如果没找到,就查找对象的原型(__proto__),然后是原型的原型,以此类推,直到找到属性或到达 Object.prototype。如果最终还是没找到,则返回 undefined

  2. ts 与 js 的区别

    答: (1) 数据系统 ts 是强类型语言,在开发是定义数据类型 js 是弱类型语言,变量的类型是在运行时决定的 (2) 编译 ts: 需要经过编译,所有的 ts 编译成 js 文件才能在浏览器或者 node 环境中运行 js: 不需要编译,直接在浏览器或 node 环境中运行

  3. ajax(Asynchronous JavaScript and XML) 和 axios 区别,axios 有那些优势

    答: (1) axios 是基于 promise 封装的,ajax 是基于 XHR(XMLHttpRequest)封装的

    G: ajax 是一种技术,实际是使用 js 进行异步请求的技术集合 特点: 原生支持:XMLHttpRequest 是浏览器原生就支持的技术 使用复杂性:使用 XHR 进行请求时,代码很冗长,处理异步操作和错误需要更多的手动控制 回调函数:原生的 AJAX 使用回调函数处理异步请求的响应,可能会导致回调地狱 示例:

    var xhr = new XMLHttpRequest()
    xhr.open('get', 'https://api.example.com/data', true) // truei表示开启异步请求
    xhr.onreadystatechange = function () {
    	if (xhr.readyState === 4 && xhr.readyState === 200) {
    		console.log(xhr.responseText)
    	}
    }
    xhr.send()
    

    axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 node,封装了对 XMLHttpRequest 的 API 使用 特点: 基于 Promise: 对异步请求和处理更加的简洁 简洁的 API:支持配置请求头、请求参数、响应拦截器等 请求和响应拦截器: 支持配置请求和响应拦截器,允许在请求前和响应后做一些处理 自动转换 JSON:自动将 JSON 响转换成 JS 对象 取消请求:提供取消请求的功能,在请求发出后根据需要取消请求 处理请求超时:支持配置请求超时的时间 Axios 优势: 简化代码:对异步请求和处理都很简洁 基于 Promise 请求和响应拦截器 自动转换 JSON 取消请求 处理请求超时 总结: AJAX 是一种技术,用于实现异步请求,XMLHttpReauest 是其实现方式之一 Axios 是一个功能丰富的 HTTP 客户端库,提供了基于 Promise 的接口、拦截器、自动转换 JSON 等功能 发散: AJAX 怎么处理请求的响应的?

    // 1. 创建 XMLHttpRequest 对象
    var xhr = new XMLHttpRequest()
    // 2. 配置请求
    // 设置请求的类型(GET、POST等)和目标 URL。可以选择是否异步(true 为异步)。
    xhr.open('GET', 'https://api.example.com/data', true)
    // 3. 设置回调函数
    // 使用 onreadystatechange 事件来监听请求状态变化。请求完成时(readyState 为 4),检查状态码(status 为 200)以确保请求成功。
    xhr.onreadystatechange = function () {
    	if (xhr.readyState === 4) {
    		// 请求完成
    		if (xhr.status === 200) {
    			// 请求成功
    			// 处理响应数据
    			console.log(xhr.responseText)
    		} else {
    			// 处理错误
    			console.error('Error:', xhr.statusText)
    		}
    	}
    }
    // 4. 发送请求
    xhr.send()
    // 5. 处理响应数据
    // 根据需要解析响应数据。对于文本响应,可以直接使用 xhr.responseText,对于 JSON 响应,则需要使用 JSON.parse() 解析。
    var responseData = JSON.parse(xhr.responseText)
    console.log(responseData)
    

    Axios 怎么处理请求的响应的?

    // 1. 发送请求
        // 使用 axios 方法(如 axios.get、axios.post 等)发送请求。
            axios.get('https://api.example.com/data')
            .then(response => {
            // 处理成功响应
            console.log(response.data);
            })
            .catch(error => {
            // 处理错误
            console.error("Error:", error);
            });
        //2. 响应处理
            // Axios 会自动将响应数据解析为 JSON 对象(如果响应头中的 Content-Type 是 application/json),并将其封装在 response 对象中。
    
            //3. 请求和响应拦截器
            // Axios 允许设置拦截器,用于在请求发送前或响应接收后处理数据。例如,添加认证 token 或处理错误:
            // 请求拦截器
            axios.interceptors.request.use(config => {
            // 在请求发送之前做些什么
            config.headers['Authorization'] = 'Bearer token';
            return config;
            }, error => {
            return Promise.reject(error);
            });
    
            // 响应拦截器
            axios.interceptors.response.use(response => {
            // 对响应数据做些什么
            return response;
            }, error => {
            // 对响应错误做些什么
            return Promise.reject(error);
            });
            // 4. 错误处理
            // 如果请求失败(如网络错误或状态码不是 2xx),catch 方法会捕获异常:
            axios.get('https://api.example.com/data')
            .then(response => {
            // 处理成功响应
            console.log(response.data);
            })
            .catch(error => {
            // 处理错误
            console.error("Error:", error.message);
            });
    
    
  4. 面向对象的特征

    答:

    G:

    封装: js 的对象、闭包可以实现定义私有属性和私有方法 es6 的类

    class Person {
        constructor(name, age) {
            this.name = name; // 公共属性
            let _age = age; // 私有属性,无法直接访问
    
            this.getAge = function() {
                return _age;
            };
        }
    
        greet() {
            console.log(`Hello, my name is ${this.name}`);
        }
    }
    
    const john = new Person('John', 30);
    john.greet(); // "Hello, my name is John"
    console.log(john.getAge()); // 30
    
    

    继承: js 的原型继承 类的 extends 继承

    class Animal {
        constructor(name) {
            this.name = name;
        }
    
        speak() {
            console.log(`${this.name} makes a noise.`);
        }
    }
    
    class Dog extends Animal {
        speak() {
            console.log(`${this.name} barks.`);
        }
    }
    
    const dog = new Dog('Rex');
    dog.speak(); // "Rex barks."
    
    

    多态: 子类重写父类的方法

    class Shape {
        draw() {
            console.log('Drawing a shape');
        }
    }
    
    class Circle extends Shape {
        draw() {
            console.log('Drawing a circle');
        }
    }
    
    class Square extends Shape {
        draw() {
            console.log('Drawing a square');
        }
    }
    
    const shapes = [new Circle(), new Square()];
    shapes.forEach(shape => shape.draw());
    // "Drawing a circle"
    // "Drawing a square"
    
    

    抽象:

    js 定义抽象类,抽象类不能实例化,只能通过子类继承,子类完成实例化

    class AbstractVehicle {
        constructor() {
            if (new.target === AbstractVehicle) {
                throw new Error('Cannot instantiate an abstract class.');
            }
        }
    
        startEngine() {
            throw new Error('You have to implement the method startEngine!');
        }
    }
    
    class Car extends AbstractVehicle {
        startEngine() {
            console.log('Car engine started.');
        }
    }
    
    const myCar = new Car();
    myCar.startEngine(); // "Car engine started."
    
    
  5. 你熟悉的设计模式

    答:

  6. 介绍下 HTTP

    答:

    G:HTTP(HyperHText Transfer Protocol,超文本传输协议)是用于在客户端和服务器之间传输超文本数据的协议。它是 Web 通信的基础

    (1) 基本概念

    • 客户端与服务器: HTTP 是基于客户端-服务器模型的协议。客户端(通常是浏览器)发起请求,服务器接收请求并返回响应。服务器提供资源,客户端通过 HTTP 请求这些资源。
    • 请求与响应: 每次 HTTP 通信包括一次请求和一次响应。客户端通过 HTTP 请求资源,服务器处理请求并返回响应,包括请求的资源或状态信息。

    (2) HTTP 方法

    • GET: 请求指定资源。GET 请求通常用于请求数据而不改变服务器上的资源。
    • POST: 向服务器提交数据,用于创建或更新资源。POST 通常用于表单提交。
    • PUT: 向服务器上传资源,通常用于更新资源。
    • DELETE: 删除指定资源。
    • HEAD: 类似于 GET 请求,但不返回响应体,只获取响应头部。
    • OPTIONS: 获取服务器支持的请求方法。
    • PATCH: 对资源进行部分修改。

    (3) HTTP 状态码

    • 1xx(信息性状态码): 表示请求已接收,继续处理。
    • 2xx(成功状态码): 表示请求已成功处理。例如,200 OK 表示请求成功,服务器返回了请求的资源。
    • 3xx(重定向状态码): 表示资源已被移动,需要客户端采取进一步的操作。例如,301 Moved Permanently 表示资源已永久移动。
    • 4xx(客户端错误状态码): 表示客户端请求有错误。例如,404 Not Found 表示请求的资源在服务器上不存在。
    • 5xx(服务器错误状态码): 表示服务器端出现错误,无法完成请求。例如,500 Internal Server Error 表示服务器遇到未知错误。

    (4) HTTP 头

    • HTTP 头包含了客户端和服务器之间传输的元数据,用于描述请求或响应的属性。
    • 请求头: 例如 User-Agent(浏览器信息)、Accept(客户端接受的媒体类型)、Authorization(身份验证信息)。
    • 响应头: 例如 Content-Type(响应内容类型)、Set-Cookie(服务器设置的 cookie)、Cache-Control(缓存指令)。

    (5) HTTP 版本

    • HTTP/1.0: 是最初的版本,每次请求都需要建立一个新的连接。
    • HTTP/1.1: 改进了性能,支持持久连接、管道化请求和更多的缓存控制机制。
    • HTTP/2: 引入了二进制协议、多路复用、压缩头等特性,大大提升了性能。
    • HTTP/3: 基于 QUIC 协议,进一步减少了延迟并改善了安全性和连接恢复。

    (6) 无状态协议

    • HTTP 是一种无状态协议,即每个请求都是独立的,不依赖于之前的请求或响应。每次请求和响应都是全新的。这种无状态特性简化了服务器的设计,但需要通过额外的机制(如 cookies、session、token)来维护状态信息。
  7. UDP和TCP的区别

    答:

    (1) 可靠性 UDP 不可靠 TCP 可靠 UDP 不经过确认只是发送信息,不在乎信息是否传达了,TCP 经过三次握手,确保信息传达的可靠性

    G:

    (1) 连接性

    TCP需要面链接的协议,传输前三次握手,四次挥手,UDP无连接协议,直接将数据包发到目方

    (2) 可靠性

    UDP不可靠。TCP可靠。丢包会自动从传

    (3) 传输速度

    UDP快,TCP慢

    (4) 传输数据

    TCP以字节流的形式传输,UDP是面向数据包的协议

    (5) 应用场景

    TCP: 网页浏览、文件传输、电子邮件、远程登录

    UDP:实时视频或音频传输,在线游戏,DNS查询

  8. 算法题:用队列实现一个栈 队头 1 2 3 4 5 队尾 先进先出 栈顶 5 4 3 2 1 栈底 先进后出

/*
 * @Author: Kvon
 * @Date: 2024-08-11 19:12:45
 * @Description:
 */
class MyStack {
	constructor() {
		this.queue1 = []
		this.queue2 = []
	}
	push(v) {
		this.queue2.push(v)
		while (this.queue1.length > 0) {
			this.queue2.push(this.queue1.shift()) // 队1 暂存值 永远保持空
		}
		;[this.queue1, this.queue2] = [this.queue2, this.queue1] // 队1 一把拿到值
	}
	pop() {
		return this.queue1.shift()
	}
	top() {
		return this.queue1[0]
	}
	empty() {
		return this.queue1.length === 0
	}
}
const stack = new MyStack()
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
stack.push(5)
while (!stack.empty()) {
	console.log(stack.pop())
}