2025-01-14面试总结

简述一下JS的原型链

在 JavaScript 中,每个对象都有一个原型对象。原型对象可以被其他对象共享,并且可以用于实现继承。当一个对象访问一个属性时,如果该对象本身没有该属性,JavaScript 会沿着原型链向上查找,直到找到该属性或到达原型链的顶端。
 
原型链的顶端是 Object.prototype ,它是所有对象的原型。当访问一个对象的属性时,如果该对象本身没有该属性,JavaScript 会首先查找该对象的原型对象,如果原型对象也没有该属性,JavaScript 会继续向上查找原型对象的原型对象,直到找到该属性或到达 Object.prototype 。
 
原型链的概念对于理解 JavaScript 的继承和对象的属性查找非常重要。通过原型链,对象可以继承其他对象的属性和方法,从而实现代码的复用和扩展。

浏览器拿到html页面之后,事件循环怎么去进行一个渲染

  1. 解析 HTML:浏览器会解析 HTML 页面,构建 DOM 树。
  2. 加载资源:浏览器会加载页面中引用的 CSS、JavaScript 和其他资源。
  3. 执行 JavaScript:浏览器会执行页面中的 JavaScript 代码,可能会修改 DOM 树和样式。
  4. 渲染页面:浏览器会根据 DOM 树和样式信息,渲染页面。
  5. 事件循环:浏览器会启动事件循环,等待用户交互和其他事件。
  6. 处理事件:当用户交互或其他事件发生时,浏览器会将事件添加到事件队列中。
  7. 执行事件处理程序:浏览器会从事件队列中取出事件,并执行相应的事件处理程序。
  8. 更新页面:事件处理程序可能会修改 DOM 树和样式,浏览器会根据修改后的信息更新页面。
  9. 重复步骤 6-8:浏览器会不断地从事件队列中取出事件,并执行相应的事件处理程序,直到事件队列为空。

函数柯里化的使用场景

参数复用

当某个函数被多次调用且部分参数保持不变时,可以使用柯里化来减少重复传递这些不变的参数。例如,在Web开发中,可能需要根据协议和域名拼接出多个URL。使用柯里化,可以固定协议和域名,只传递变化的路径部分。

延迟执行

柯里化允许逐步传递参数,并在所有参数都提供后才执行函数体。这种特性可以用于实现延迟执行,即只有在所有必要的参数都传入后才执行函数。

高阶函数的动态策略

在构建高阶函数时,柯里化可以提供更灵活的策略选择。例如,可以实现一个折扣策略函数,通过柯里化传递不同的折扣率来计算实际金额。

函数组合和链式调用

柯里化使得函数更容易被组合在一起,实现链式调用。这在数据处理和变换中特别有用,可以通过一系列小函数逐步构建复杂的操作。

数据验证和API封装

在数据验证和API封装中,柯里化可以用于创建通用的验证函数或API客户端,通过固定部分参数来简化调用。

配置上下文

柯里化还可以用于提前配置一些参数,实现上下文的提前配置,以便复用。例如,在日志记录中,可以固定日志级别,避免每次记录日志时都要传递级别参数。

http2.0新增了哪些属性

二进制分帧层

  • HTTP/2.0在应用层与传送层之间增加了一个二进制分帧层,所有的传输信息被分割为更小的消息和帧,并采用二进制格式编码。
  • 帧类型包括DATA(用于传输HTTP消息体)、HEADERS(用于传输首部字段)、SETTINGS(用于约定客户端和服务端的配置数据)、WINDOW_UPDATE(用于调整个别流或个别连接的流量)、PRIORITY(用于指定或重新指定引用资源的优先级)、RST_STREAM(用于通知流的非正常终止)、PUSH_PROMISE(服务端推送许可)、PING(用于计算往返时间,执行“活性”检活)以及GOAWAY(用于通知对端停止在当前连接中创建流)等。
  • 二进制分帧层使得HTTP/2.0能够在不改动HTTP的语义、方法、状态码、URI以及首部字段的情况下,突破HTTP/1.1的性能限制。

多路复用

  • HTTP/2.0允许通过单一的HTTP/2.0连接发起多重的请求-响应消息,这意味着所有通信都在一个连接上完成,该连接可以承载任意数量的双向数据流。
  • 多路复用解决了HTTP/1.1中的队首阻塞问题,并减少了TCP连接数,对服务器性能有很大的提升。

请求优先级

  • 每个HTTP/2.0的流都有一个优先值,这个优先值确定着客户端跟服务器处理不同的流采取不同的优先级策略。
  • 客户端可以明确指定优先级,服务端可以根据这个优先级作为依据交互数据。

服务端推送

  • HTTP/2.0新增了服务端推送功能,服务端可以根据客户端的请求,提前返回多个响应,推送额外的资源给客户端。
  • 客户端也有权利选择是否接收推送的资源。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。

首部压缩

  • HTTP/2.0在客户端和服务端之间使用“首部表”来跟踪和存储之前发送的键-值对,避免了每次通信都需要再携带首部。
  • HTTP/2.0还使用了HPACK算法对首部进行压缩,使得报头更紧凑、更快速传输,有利于移动网络环境。

http有哪些属性

HTTP(HyperText Transfer Protocol,超文本传输协议)是用于在计算机网络中分发超文本信息的基础协议,具有以下关键属性:

一、基础属性

  1. 应用层协议:HTTP是万维网(World Wide Web)的核心协议之一,位于TCP/IP协议栈的最上层,依赖于底层的传输层协议(通常是TCP)来传输数据。
  2. 客户端-服务器模型:HTTP采用客户端-服务器模型,客户端(例如浏览器)发送请求到服务器,服务器处理请求并返回响应。客户端和服务器之间的通信是通过请求和响应报文来完成的。
  3. 无状态协议:HTTP是无状态的应用层协议,每个请求和响应都是独立的,与之前的请求和响应没有直接的联系。服务器不会保存客户端的状态信息,每次请求都被视为全新的请求。不过,可以通过使用Cookies或其他机制来模拟状态。

二、报文结构

  1. 请求报文

    • 请求行:包含请求方法、URL和HTTP版本。例如,“GET /index.html HTTP/1.1”。
    • 请求头:包含元数据,如Host、User-Agent、Accept等,用于提供请求的附加信息。
    • 请求体:POST、PUT等方法可以携带请求体,包含要发送到服务器的数据,例如表单数据或文件内容。
  2. 响应报文

    • 状态行:包含HTTP版本、状态码和状态消息。例如,“HTTP/1.1 200 OK”。
    • 响应头:包含元数据,如Content-Type、Content-Length等,用于提供响应的附加信息。
    • 响应体:包含实际返回给客户端的数据,例如HTML文档、图片等。

三、请求方法

HTTP定义了几种请求方法,最常用的包括:

  1. GET:请求从服务器获取资源。GET请求通常是幂等的(即多次请求不会产生不同的结果),并且可以被缓存和保存在浏览器历史中。
  2. POST:向服务器提交数据,通常用于表单提交、上传文件等。POST请求可能会导致服务器的状态发生变化,并且不会被缓存。
  3. PUT:上传文件或更新资源,通常是幂等的。客户端发送的数据将替换目标资源的所有当前表示。
  4. DELETE:请求服务器删除指定资源,通常是幂等的。
  5. HEAD:与GET请求类似,但服务器只返回响应头,不返回实际内容。常用于检查资源可用性及获取资源元数据(如最后修改日期)。
  6. OPTIONS:请求服务器返回其支持的HTTP方法。可以用来检查服务器的能力。
  7. PATCH:对资源应用部分修改。不同于PUT,它不是完全替换资源,而是应用一些更改到资源上。
  8. CONNECT:用于建立到服务器的隧道连接,通常用于HTTPS通过代理的请求。
  9. TRACE:用于回显服务器收到的请求,主要用于测试或诊断。

四、状态码

响应状态码由三位数字组成,表示服务器处理请求的结果。常见的状态码分类包括:

  1. 1xx(信息响应状态码):请求已收到,继续处理。
  2. 2xx(成功状态码):请求成功,服务器已处理并返回资源。
  3. 3xx(重定向状态码):请求需要进一步操作才能完成,通常是客户端需要进行重定向。
  4. 4xx(客户端错误状态码):请求有误,服务器无法处理。
  5. 5xx(服务器错误状态码):服务器内部错误,无法完成请求。

五、版本与特性

  1. HTTP/1.1

    • 改进了早期版本中的性能问题。
    • 引入了持久连接(Keep-Alive),允许在一个TCP连接中发送多个请求。
    • 提供了管线化技术,可以在前一个响应未完成时发出后续请求。
    • 添加了Host头部,支持虚拟主机。
    • 引入了分块传输编码(chunked transfer coding),允许服务器逐步发送数据。
  2. HTTP/2

    • 采用了二进制传输数据,而非之前的文本格式,大大提高了传输效率。
    • 引入了流控制和帧压缩等机制,进一步提升了数据传输的性能。
    • 支持并发请求,服务器可以同时处理多个请求。
    • 采用了TLS 1.2或更高版本的加密协议,提供了更强的安全性保护。
    • 采用了头压缩技术,通过使用字典来压缩请求和响应头信息。
    • 支持多个请求和响应在同一个连接上同时进行(多路复用)。
    • 引入了服务器推送机制,服务器可以在客户端请求之前主动向客户端推送数据。
  3. HTTP/3

    • 使用QUIC协议代替传统的TCP,基于UDP实现更快速且可靠的传输。
    • 解决了TCP层面的队头阻塞问题,进一步优化了性能。
    • HTTP/3不是HTTP/2的直接升级,而是一个全新的协议,旨在解决不同网络条件下的传输挑战。

六、其他特性

  1. 资源标识:在HTTP中,所有事物都被视为资源,并且每个资源都有一个唯一的标识符,通常是URL(统一资源定位符)。
  2. 安全性:HTTPS是HTTP的安全版本,通过SSL/TLS加密技术确保数据的安全性和完整性。
  3. 持久连接:允许在一个TCP连接上发送多个请求和响应,减少了建立新连接的开销。
  4. 缓存机制:HTTP支持缓存机制,可以减少网络流量,提高访问速度。浏览器和其他客户端可以存储响应副本,在满足一定条件下直接使用这些副本,而不必每次都向服务器请求新的内容。

简述一下JS的栈跟堆

在 JavaScript 中,栈和堆是两种不同的内存数据结构,它们用于存储不同类型的数据。
 
栈是一种线性数据结构,它按照后进先出(LIFO)的原则存储和访问数据。在栈中,数据被存储在一个连续的内存块中,并且只能在栈顶进行插入和删除操作。栈通常用于存储函数调用、局部变量和其他临时数据。
 
堆是一种非线性数据结构,它按照键值对的方式存储和访问数据。在堆中,数据被存储在一个不连续的内存块中,并且可以通过键来访问数据。堆通常用于存储对象、数组和其他复杂数据类型。
 
在 JavaScript 中,基本数据类型(如数字、字符串、布尔值等)通常存储在栈中,而引用数据类型(如对象、数组、函数等)通常存储在堆中。当一个函数被调用时,它的局部变量和参数被存储在栈中,而函数中创建的对象和数组则被存储在堆中。
 
需要注意的是,JavaScript 中的栈和堆是由 JavaScript 引擎自动管理的,开发人员不需要手动分配和释放内存。但是,了解栈和堆的概念可以帮助开发人员更好地理解 JavaScript 中的内存管理和性能优化。

栈(Stack)

栈是一种线性数据结构,遵循先进后出(FILO)的原则。它主要用于存储函数调用、局部变量、函数参数以及程序执行的上下文。栈的特点包括:

  • 先进后出(FILO)‌:最后压入栈的元素最先弹出。
  • 有限大小‌:栈的大小是有限的,当栈空间耗尽时会发生栈溢出(stack overflow)。
  • 快速访问‌:由于栈是一种简单的数据结构,访问和操作栈的速度非常快。
  • 快速分配和释放内存‌:分配和释放栈内存的操作非常高效,不会出现内存碎片问题‌。

堆(Heap)

堆是一种用于动态内存分配的数据结构,用于存储复杂的数据结构和对象。堆的特点包括:

  • 动态分配‌:堆内存的大小是动态分配的,不受限于栈的大小限制。
  • 手动管理‌:堆内存需要手动分配和释放,否则会导致内存泄漏(memory leak)。
  • 无序存储‌:堆中存储的数据是无序的,数据之间的关系由指针来表示。
  • 全局性‌:堆内存中的数据可以在全局作用域中访问,适合存储长期保存的数据和共享数据‌。

区别和联系

  • 内存管理‌:栈内存由编译器自动分配和释放,而堆内存需要程序员手动管理。如果程序员不释放堆内存,可能会导致内存泄漏‌2。
  • 数据类型‌:栈内存中存放的是基础数据类型(如Number、String等),而堆内存中存放的是引用数据类型(如对象、数组等)‌23。
  • 生命周期‌:栈内存中的数据随着函数的执行结束而销毁,而堆内存中的对象即使函数执行结束也可能被其他引用变量引用,因此不会被销毁‌

JS普通函数与箭头函数的一个区别

在 JavaScript 中,普通函数和箭头函数都是用于定义函数的方式,它们之间的主要区别包括:
 
1.语法:箭头函数使用箭头(=>)来定义函数,而普通函数使用 function 关键字来定义函数。
2.this 指向:在箭头函数中,this 的指向是固定的,它指向定义箭头函数时所在的上下文环境。而在普通函数中,this 的指向是动态的,它取决于函数的调用方式。
3.原型:箭头函数没有 prototype 属性,因此不能使用 new 关键字来创建实例。而普通函数有 prototype 属性,可以使用 new 关键字来创建实例。
4.arguments 对象:在箭头函数中,没有 arguments 对象,因此不能使用 arguments 来获取函数的参数。而在普通函数中,可以使用 arguments 对象来获取函数的参数。
5.构造函数:箭头函数不能用作构造函数,因此不能使用 new 关键字来调用箭头函数。而普通函数可以用作构造函数,可以使用 new 关键字来调用普通函数。
6.函数表达式:箭头函数可以用作函数表达式,而普通函数也可以用作函数表达式。
 
总之,箭头函数和普通函数在语法、this 指向、原型、arguments 对象、构造函数和函数表达式等方面存在一些区别。在实际开发中,需要根据具体的需求和场景来选择使用箭头函数还是普通函数。

js的设计模式

一、创建型模式(Creational Patterns)

创建型模式侧重于对象创建机制,提供以灵活和可控的方式实例化对象的方法。

  1. 单例模式(Singleton Pattern)

    • 定义:确保一个类只有一个实例,并提供一个全局访问点。
    • 用途:常用于限制某个类的实例化次数,确保在整个应用中只存在一个实例,如登录浮窗、vuex和redux中的store等。
    • 实现:可以通过闭包、类静态属性或代理等方式实现。
  2. 工厂模式(Factory Pattern)

    • 定义:提供一种封装对象创建过程的方式,使得代码无需关心具体的实例化过程。
    • 用途:封装对象的创建过程,提高代码的灵活性和可维护性。常用于处理对象的创建和组装逻辑。
    • 实现:定义一个工厂类,并在其中实现创建对象的方法。
  3. 抽象工厂模式(Abstract Factory Pattern)

    • 定义:提供一种创建相关对象的接口,而无需指定具体类。
    • 用途:创建一系列相关或相互依赖的对象,而无需指定它们的具体类。
    • 实现:通常通过定义抽象工厂和具体工厂类来实现。
  4. 建造者模式(Builder Pattern)

    • 定义:用于构建复杂对象,将构建过程与表示分离,以便相同的构建过程可以创建不同的表示。
    • 用途:构建复杂对象,逐步构建对象并返回最终产品。
    • 实现:通常通过定义一个建造者接口和具体建造者类来实现。
  5. 原型模式(Prototype Pattern)

    • 定义:基于现有对象克隆创建新对象,避免了直接实例化。
    • 用途:通过原型对象创建新对象,实现属性和方法的共享,节省内存。
    • 实现:在JavaScript中,原型模式是实现继承的基础,可以通过原型链来实现。

二、结构型模式(Structural Patterns)

结构型模式侧重于组织和组合对象以形成更大的结构。它们促进了对象的组合,定义了它们之间的关系,并提供了灵活的方法来操纵它们的结构。

  1. 适配器模式(Adapter Pattern)

    • 定义:用于将不兼容的接口转换为可兼容的接口。
    • 用途:使原本由于接口不兼容而不能一起工作的类可以一起工作。
    • 实现:通常通过创建一个适配器类来实现接口转换。
  2. 装饰器模式(Decorator Pattern)

    • 定义:允许在不修改原始对象的情况下给对象添加新功能。
    • 用途:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更为灵活。
    • 实现:通过定义一个装饰器接口和具体装饰器类来实现。
  3. 代理模式(Proxy Pattern)

    • 定义:提供一个代理对象来控制对实际对象的访问,并可以通过代理对象添加额外的功能。
    • 用途:为其他对象提供一种代理以控制对这个对象的访问。
    • 实现:通过定义一个代理类并在其中封装对实际对象的访问来实现。

三、行为型模式(Behavioral Patterns)

行为型模式侧重于对象之间的交互和责任的分配。它们为对象之间的通信、协调和协作提供解决方案。

  1. 观察者模式(Observer Pattern)/发布-订阅模式(Publish-Subscribe Pattern)

    • 定义:定义了一种一对多的依赖关系,使得多个观察者对象可以同时监听一个主题对象;允许多个订阅者订阅特定事件,当事件发生时,发布者会通知所有订阅者。
    • 用途:实现对象之间的松耦合通信,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。
    • 实现:通常通过定义一个主题类和观察者类来实现。
  2. 策略模式(Strategy Pattern)

    • 定义:定义了一系列可以互相替换的算法,并使得算法的选择与使用独立于客户端。
    • 用途:使算法可以独立于使用它的客户端而变化。
    • 实现:通过定义一个策略接口和具体策略类来实现。
  3. 状态模式(State Pattern)

    • 定义:允许对象在内部状态改变时改变其行为,使对象看起来似乎修改了其类。
    • 用途:让对象在内部状态改变时其行为也随之改变。
    • 实现:通常通过定义一个状态接口和具体状态类来实现。
  4. 迭代器模式(Iterator Pattern)

    • 定义:提供一种访问聚合对象元素的方法,而不需要暴露聚合对象的内部结构。
    • 用途:顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的内部结构。
    • 实现:通过定义一个迭代器接口和具体迭代器类来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值