【无标题】

1、vue2和vue3的主要区别


1、性能优化:Vue3对虚拟DOM进行了优化,例如使用了更高效的算法,缩减了代码量。此外,Vue3还利用Proxy代理优化了响应式系统,提高了性能。

2、新特性:Vue3引入了Composition API,是一种函数式API。Composition API使得组合逻辑更加容易,能够更好地重用组件逻辑。

3、Tree-shaking:Vue3支持更好的Tree-shaking(摇树优化)能力,使得项目打包后更加精简,加载速度更快。

4、Typescript支持:Vue3对Typescript支持更完善,使用Typescript编写Vue3应用可以获得更好的类型安全和开发体验。

5、小巧的包:Vue3的核心库包大小比Vue2更小,在使用上更加灵活。

2、vue3组件通信流程


Vue3中组件通信的流程可以用以下方式表述:

1、父组件向子组件传递数据

父组件通过props属性将需要传递的数据传递给子组件,在子组件中定义props属性接收父组件传递的数据
子组件通过props属性访问父组件传递过来的数据
2、子组件向父组件传递数据

子组件通过e m i t 方法触发父组件的事件,子组件在 emit方法触发父组件的事件,子组件在emit方法触发父组件的事件,子组件在emit方法中传递需要传递的数据
父组件中监听子组件的事件,在监听方法中获取子组件传递过来的数据
3、setup中的返回值

在setup函数中定义需要传递的数据或方法返回一个对象或数组
在子组件中使用props属性获取父组件传递过来的数据,子组件通过setup函数提供的数据或方法来使用
4、provide / inject

provide在父组件中提供需要传递的数据
inject在子组件中获取提供的数据
可以在组件树中遥远的组件之间进行传递
在Vue3中,父子组件之间的通信需要通过props和$emit方法、setup函数以及provide / inject来进行。这些方式的选择需根据实际情况和项目需求和组织结构而定。需要注意的一点是,过于频繁的组件通信也可能导致应用的耦合度过高,因此,在使用时需要权衡其利弊。

3、Apply/call/bind的原理是什么?


·apply()·, ·call()·, ·bind()· 是 JavaScript 中函数对象的方法,它们的作用是改变函数的执行上下文,即函数内部的 this 指向。

在 JavaScript 中,函数是一类特殊的对象。它们具有 call, apply, bind 等内置方法。这些方法利用了 JavaScript 中函数是对象的性质,在函数运行时临时绑定了一个新的执行上下文,从而改变了函数内部 this 关键字的指向。

call() 方法和 apply() 方法都可以改变函数的执行上下文,并且接受的参数也不同。apply() 方法接受的是一个数组参数,而 call() 方法则接受一个或多个单独的参数。这两个方法的本质区别在于参数的传递方式不同,但作用一致。
bind() 方法则是将原函数和指定的对象绑定,返回一个新的函数,新函数的执行上下文为绑定对象。bind() 方法只返回对函数的绑定,并不会立即执行函数。
这三个方法的核心机制是通过改变函数的作用域链来改变 this 的指向,进而控制函数的执行上下文。在使用 call(), apply(), bind() 来改变函数执行上下文时,我们需要显式地指定需要绑定的对象,从而避免了因为 this 指向问题而造成的函数执行错误。

4、说说你对原型和原型链的理解?


在JavaScript中,每个对象都有一个关联的原型对象,也称为原型。原型对象是一个普通对象,它具有一组属性和方法,它可以被用来继承这些属性和方法。每当你创建一个新的对象时,它都会自动关联到它的构造函数的原型对象上。

原型链是一种机制,它使得对象之间可以通过它们各自的原型对象相互关联起来。一个对象的原型对象又可以有自己的原型对象,这样就形成了一个原型链。当你试图访问一个对象上的属性或方法时,JavaScript会首先在对象自身上查找,如果没有找到,它就会去该对象的原型对象上查找,如果还没有找到,它就会继续沿着原型链向上查找,直到找到该属性或方法或者到达原型链的顶部,即Object.prototype。如果最终还是没有找到该属性或方法,JavaScript会返回undefined。

这种原型继承的机制在JavaScript中非常强大,因为它使得我们可以轻松地在对象之间共享代码。例如,如果你创建了一个构造函数,它有一些方法和属性,你可以将这些方法和属性添加到它的原型对象上,这样每个从该构造函数创建的对象都可以访问这些方法和属性,这样可以大大节省内存空间。此外,原型链还允许我们实现更高级的继承和多态性,这些是面向对象编程中非常有用的概念。

5、说说你对ES6中Generator的理解


ES6引入了一个新的概念——生成器(Generator)。生成器是一种可以暂停执行的函数,可以用来惰性地生成一系列值。相比普通函数,生成器有以下几个特点:

生成器函数使用function*关键字定义,内部使用yield关键字可以将函数的执行暂停,将控制权交回给调用者。

生成器函数的返回值是一个生成器对象,这个对象同时也是一个可迭代对象,可以使用for…of语句进行迭代。

在每次调用生成器对象的next()方法时,生成器会从上一次暂停的位置开始执行,直到遇到下一个yield表达式或函数结束。

可以使用yield表达式向生成器对象返回一个值,在下一次调用next()方法时可以继续从上一次暂停的位置开始执行,并在yield表达式处暂停。

生成器函数内部可以使用yield*表达式调用另一个生成器函数或可迭代对象的迭代器。

生成器函数内部可以使用return语句返回最终的值,并终止生成器的执行。

通过使用生成器,可以方便地实现异步操作、惰性计算、迭代器等功能,同时避免了回调地狱和复杂的异步操作处理。

6、说说你对Event Loop的理解


当JavaScript代码执行时,它将被放置在执行栈中,按照先进先出的顺序执行。如果当前执行的任务是一个异步任务(例如,定时器、事件监听器、网络请求等),则它将被添加到任务队列(Event Queue)中,等待执行。

当执行栈中的所有任务完成时,事件循环开始工作。它从任务队列中取出一个任务,将其放置在执行栈中执行。执行栈再次为空时,事件循环再次从任务队列中取出一个任务,并将其放置在执行栈中执行。这个过程循环重复,直到任务队列为空。

JavaScript的事件循环采用单线程的方式执行,即每个时刻只有一个任务在执行。由于JavaScript是单线程的,因此在处理长时间运行的任务时,它会阻塞事件循环,导致其他任务不能及时得到执行。因此,JavaScript提供了一些异步编程模式,例如Promise和回调函数,以允许长时间运行的任务在后台执行,不会阻塞事件循环。

总之,事件循环是JavaScript异步编程的基础,它通过任务队列和执行栈来协调任务的执行顺序,保证了JavaScript代码的执行顺序和异步事件的处理。

7、说说Promise和async/await 的区别?


Promise 和 async/await 都是处理异步操作的方式,但它们在语法和使用上有一些区别。

Promise 是一个用于处理异步操作的对象,它代表了一个尚未完成的操作,并提供了一种可以在操作完成时执行回调函数的方式。Promise 提供了 then() 方法,可以在异步操作完成后执行成功和失败的回调函数。

async/await 是在 ES6 中引入的一种处理异步操作的语法糖,它提供了一种更简洁的方式来编写异步代码。使用 async 关键字标记一个函数为异步函数,异步函数中可以使用 await 关键字等待 Promise 对象完成,并返回 Promise 的结果。

下面是 Promise 和 async/await 的一些区别:

语法:Promise 通过链式调用 then() 方法来处理异步操作的结果,而 async/await 利用 async 和 await 关键字来处理异步操作的结果,使得代码更加简洁易懂。

错误处理:在 Promise 中,错误处理通常使用 catch() 方法来捕获 Promise 返回的错误,而在 async/await 中,可以使用 try/catch 语句来捕获异步操作中的错误。

控制流:在 Promise 中,如果有多个异步操作需要依次执行,可以使用链式调用 then() 方法来处理。而在 async/await 中,可以使用 async/await 结合 for…of 循环来处理异步操作的顺序执行。

可读性:由于 async/await 使用了同步代码的风格,所以它通常比 Promise 更加易读和易于理解。但是,当出现多个异步操作需要依次执行时,使用 Promise 可能会更加简洁明了。

总之,Promise 和 async/await 都是处理异步操作的方式,具体使用哪种方式取决于开发者的个人偏好和具体应用场景。

8、说说浏览器事件循环和nodeJs的事件循环的区别?


虽然浏览器和Node.js都使用事件循环来处理异步任务,但它们的事件循环实现方式有所不同。

在浏览器中,事件循环包括主线程、任务队列和微任务队列。当浏览器遇到异步任务时,它将其添加到任务队列中,等待下一次事件循环迭代时执行。当主线程完成当前执行栈中的任务时,它会检查微任务队列是否有任务需要执行,如果有,则按顺序执行微任务队列中的任务。然后,它会从任务队列中取出一个任务,并将其添加到执行栈中执行。这个过程循环重复,直到任务队列和微任务队列都为空。

在Node.js中,事件循环包括主线程、任务队列、微任务队列和观察者(Watchers)。观察者用于监听操作系统的事件,例如文件I/O、网络I/O等。当Node.js遇到异步任务时,它将其添加到任务队列中,等待下一次事件循环迭代时执行。当主线程完成当前执行栈中的任务时,它会检查微任务队列是否有任务需要执行,如果有,则按顺序执行微任务队列中的任务。然后,它会执行观察者中的回调函数,处理相应的事件。这个过程循环重复,直到任务队列和微任务队列都为空,并且没有活动的观察者为止。

因此,浏览器和Node.js的事件循环机制在微任务队列和观察者方面存在一些区别。在浏览器中,微任务队列只包括Promise和MutationObserver回调,而在Node.js中,微任务队列还包括process.nextTick回调。另外,Node.js的事件循环还包括观察者,用于处理底层的操作系统事件。

9、说说你对浏览器缓存机制的理解


浏览器缓存机制是指浏览器在向服务器请求资源时,会先在本地缓存中查找该资源,如果缓存中存在该资源且没有过期,则直接使用缓存中的资源,否则向服务器请求资源。

浏览器缓存机制可以分为两种类型:强制缓存和协商缓存。

强制缓存:强制缓存是指在浏览器向服务器请求资源时,先检查本地缓存中是否存在该资源,如果存在且没有过期,则直接使用缓存中的资源。可以使用 HTTP 头信息中的 Expires 和 Cache-Control 字段来控制缓存的过期时间。缺点是如果资源在缓存期间发生了变化,浏览器无法检测到,依然会使用缓存中的旧资源。

协商缓存:协商缓存是指在浏览器向服务器请求资源时,先向服务器发送一个请求,询问该资源是否有更新。服务器收到请求后,会比较该资源的最后修改时间或者 ETag 值,如果资源有更新,则返回新的资源,否则返回一个状态码 304 Not Modified,并告诉浏览器直接使用缓存中的资源。可以使用 HTTP 头信息中的 Last-Modified 和 ETag 字段来实现协商缓存。

需要注意的是,浏览器缓存机制仅适用于静态资源,对于动态资源或者需要实时更新的内容,缓存机制并不适用。此外,开发者也可以通过设置 HTTP 头信息来控制浏览器缓存,以达到更好的缓存效果。

10、说说你对浏览器内核的理解


浏览器内核是指浏览器用来渲染网页的核心程序。它主要负责将网页的HTML、CSS和JavaScript等前端代码转换成可视化的网页。

常见的浏览器内核包括:

Trident内核:是Microsoft开发的浏览器内核,被用于Internet Explorer浏览器。

Gecko内核:是Mozilla开发的浏览器内核,被用于Firefox浏览器。

WebKit内核:是苹果公司开发的浏览器内核,被用于Safari浏览器和Chrome浏览器的早期版本。

Blink内核:是由Google基于WebKit内核开发的浏览器内核,被用于Chrome浏览器和Opera浏览器。

浏览器内核的性能和特性对浏览器的速度、兼容性、安全性等方面都有影响。不同的内核在处理网页的方式、渲染效果、支持的标# 11、说说你对Vue的响应式原理的理解

11、说说你对Vue的响应式原理的理解


Vue的响应式原理是指当Vue监测到数据变化时,它会自动更新与该数据相关联的视图,从而实现数据驱动视图的目的。

具体来说,当我们在Vue中定义一个数据对象时,Vue会将该对象转换成响应式对象。当我们改变响应式对象的属性时,Vue会自动更新与该属性相关联的视图。

实现这个功能的核心是Vue的侦听器和观察者机制。Vue使用侦听器来监测数据的变化,并将变化通知给相关的观察者。观察者会接收到通知后,再执行相应的更新操作。

这种响应式原理的实现,使得我们在使用Vue开发应用时可以更加专注于数据的处理,而不用关心视图的更新。同时,也让我们能够更方便地进行组件化开发,提高了代码的可复用性和可维护性。

12、Methods watch computed区别是什么


在Vue.js中,“methods”,"watch"和"computed"都是用来处理Vue实例中数据和状态的方式,但它们各自有不同的用途和适用场景。

Methods(方法): methods是Vue实例中的函数,通常用于响应用户事件或其他触发器。methods可以修改Vue实例的状态,从而影响UI的呈现。例如,一个方法可以在用户输入后切换组件的可见性或更新一个计数器。

Watch(观察): Watch是Vue.js的一个功能,它允许您对特定的数据属性进行反应式监视,并在该属性发生更改时执行一些操作。当您在一个属性上定义一个watch时,Vue.js会自动在该属性发生更改时调用一个回调函数,传入该属性的新旧值作为参数。Watches通常用于比简单的computed属性或methods更复杂的逻辑。

Computed(计算属性): Computed属性是基于已有的属性(响应式)计算得出的属性,它们可以根据一个或多个已有的属性进行计算,并在依赖的属性发生变化时自动重新计算。这些计算属性可以被看做是对状态的一种派生或衍生,并且它们通常用于根据已有的状态计算出一些衍生的状态或属性,例如计算一个数值或格式化一个字符串。

因此,方法(methods)用于响应用户事件或其他触发器,Watch(观察)用于响应响应式属性的变化,Computed(计算属性)用于基于已有的响应式属性计算得出新的属性。在使用Vue.js时,您可以根据需要选择使用这些功能的组合,以满足您的特定需求。

13、说说你对Virtual DOM的理解?


传统的DOM操作在更新页面时需要重新计算和渲染整个页面,这样会导致页面更新的性能较低,而且会产生大量的性能瓶颈。而Virtual DOM可以通过比较新旧两个虚拟DOM之间的差异,然后只对需要更新的部分进行操作,从而减少了页面的渲染次数和计算量,提高了页面的渲染性能。

Virtual DOM的实现原理可以简单描述为:

每次数据变化后,生成一个新的虚拟DOM树。

将新的虚拟DOM树和旧的虚拟DOM树进行比较,找出两个树之间的差异。

根据差异,只对需要更新的部分进行DOM操作,从而更新页面。

需要注意的是,由于Virtual DOM是通过JavaScript对象来描述页面结构的,因此它的操作速度非常快。同时,由于Virtual DOM只更新需要更新的部分,因此它可以减少不必要的页面渲染和计算,提高了页面的性能和响应速度。

14、说说你对nextTick的理解和作用


在Vue中,nextTick是一个异步执行的方法,它用于在当前DOM更新周期结束之后执行一些操作。

具体来说,当我们在Vue中修改数据时,Vue会立即更新虚拟DOM,并计划在下一个时间片执行DOM更新操作。如果我们需要在DOM更新完成后执行一些操作,比如获取更新后的DOM元素或者调用一些依赖于DOM的方法,那么就可以使用nextTick方法。

nextTick方法的作用是将回调函数推迟到下一个DOM更新周期之后执行。这样可以保证回调函数在DOM更新完成之后执行,从而避免了因为DOM更新尚未完成而导致的操作错误。同时,由于nextTick是异步执行的,所以它也不会阻塞UI线程,保证了页面的流畅性和响应速度。

在使用nextTick方法时,可以通过传入一个回调函数作为参数来执行需要延迟执行的操作。回调函数中可以访问更新后的DOM元素和数据,从而进行一些操作,比如计算DOM元素的尺寸、位置等信息,或者触发一些事件。

总之,nextTick是一个非常实用的工具方法,在Vue的开发中非常常见,可以帮助我们更加灵活地处理DOM更新和操作。

15、说说你对webpack的理解


Webpack是一个现代化的前端打包工具,它可以将多个源文件打包成一个或多个文件,以便于在浏览器中进行加载和执行。Webpack可以处理JavaScript、CSS、HTML和其他各种资源,并提供了丰富的插件和工具来支持各种前端开发场景。

Webpack的核心概念是“模块”,它支持各种模块化规范,包括CommonJS、AMD、ES6模块等。通过模块化的方式,Webpack可以将各种源文件组织成模块,并进行依赖管理和打包。Webpack的主要功能包括:

模块化支持:Webpack支持各种模块化规范,并提供了丰富的加载器和插件来处理各种不同类型的模块。

打包和压缩:Webpack可以将多个源文件打包成一个或多个文件,并且可以对打包后的文件进行压缩和优化,以便于在生产环境中使用。

开发服务器:Webpack提供了一个开发服务器,可以在本地启动一个Web服务器,并支持热更新和自动刷新等功能,方便开发调试。

代码分离:Webpack支持将代码分离成多个文件,以便于在需要的时候进行按需加载,从而提高页面加载速度。

插件系统:Webpack提供了一个强大的插件系统,可以通过各种插件来扩展Webpack的功能,比如添加静态资源、优化代码等。

总之,Webpack是一个非常强大和灵活的前端打包工具,可以大大提高前端开发效率和性能。它在现代化前端开发中已经成为必不可少的工具之一。

16、谈谈GET和POST的区别


GET和POST是HTTP协议中最常见的两种请求方式,它们在传输数据的方式、安全性、适用场景等方面有所不同。

数据传输方式:GET请求将请求参数附加在URL的末尾,以?号分隔,参数之间用&符号连接,比如http://localhost:8080/index?param1=value1&param2=value2。而POST请求则将请求参数放在请求体中进行传输,不会暴露在URL中。

安全性:GET请求的参数暴露在URL中,容易被其他人看到或者截获,因此不适合传输敏感信息。而POST请求的请求体内容不会暴露在URL中,相对来说更加安全。

适用场景:GET请求通常用于请求数据,比如查询数据、获取资源等,因为它的请求速度快、简单易用,但不适合传输大量数据和敏感信息。而POST请求通常用于提交数据,比如登录、注册、表单提交等,因为它可以传输大量数据,并且更加安全。

缓存:GET请求可以被缓存,从而提高性能,而POST请求无法被缓存,每次提交都会产生新的请求。

总之,GET和POST请求各有优缺点,应根据实际需求进行选择。如果是获取数据或者查询资源,可以使用GET请求,如果是提交数据或者敏感信息,应该使用POST请求。同时,为了保证数据的安全性,不应该将敏感信息放在URL中,而应该使用POST请求。

17、说说HTTP和HTTPS的区别,HTTPS加密原理是?


HTTP和HTTPS都是网络传输协议,主要用于浏览器和服务器之间的数据传输,但它们在数据传输的安全性、加密方式、端口等方面有所不同。

数据传输的安全性:HTTP是明文传输,数据不加密,容易被黑客窃听、篡改或者伪造,存在安全隐患。而HTTPS使用了SSL/TLS加密协议对数据进行加密和认证,数据传输更加安全可靠。

加密方式:HTTPS使用SSL/TLS协议对数据进行加密和认证,而HTTP不加密,所以在使用HTTP协议传输数据时,数据很容易被中间人拦截、修改或者伪造。

端口:HTTP使用的默认端口是80,而HTTPS使用的默认端口是443,这是因为HTTPS需要使用SSL/TLS协议进行加密和认证,需要使用一个单独的端口来避免和HTTP协议混淆。

HTTPS加密原理:HTTPS使用了SSL/TLS协议对数据进行加密和认证,主要包括以下几个步骤:

握手阶段:客户端向服务器发送一个加密通信请求,服务器回应一个数字证书。客户端通过数字证书验证服务器的身份,然后生成一个共享的密钥,用于后续的加密通信。

加密阶段:客户端和服务器使用共享密钥进行加密通信,客户端将请求数据加密后发送给服务器,服务器解密后进行处理,然后将响应数据加密后发送给客户端,客户端解密后进行处理。

断开连接:通信完成后,客户端和服务器断开连接。

总之,HTTPS通过加密和认证技术保证数据传输的安全性,是一种更加安全可靠的网络传输协议,比HTTP更适合传输敏感信息和保护用户隐私。

18、TCP为什么要三次握手?


TCP协议采用三次握手(three-way handshake)的方式建立连接,这是为了确保连接的可靠性和安全性。

三次握手的过程如下:

客户端向服务器发送一个SYN(同步)报文,请求建立连接。该报文包括一个随机的序列号x。

服务器收到客户端的SYN报文后,向客户端发送一个SYN+ACK(同步+确认)报文,表示可以建立连接。该报文包括一个随机的序列号y,以及一个确认号x+1。

客户端收到服务器的SYN+ACK报文后,向服务器发送一个ACK(确认)报文,表示连接已经建立。该报文包括一个确认号y+1。

三次握手的目的是为了确保连接的可靠性和安全性:

确保双方都能收到对方的数据包。在第一次握手时,客户端向服务器发送SYN报文,如果服务器没有收到该报文,会认为客户端没有请求建立连接,不会做出响应;在第二次握手时,服务器向客户端发送SYN+ACK报文,如果客户端没有收到该报文,会认为服务器没有响应,不会发送ACK报文,连接不会建立。

防止连接被第三方劫持。在第三次握手时,客户端向服务器发送ACK报文,确认连接已经建立。如果连接被第三方劫持,客户端发送的ACK报文会被第三方拦截,服务器不会收到该报文,连接不会建立。

总之,TCP采用三次握手的方式建立连接,是为了确保连接的可靠性和安全性,防止数据包丢失或者被第三方劫持。

19、说说Proxy代理的原理?


在JavaScript中,Proxy代理可以用来创建一个代理对象,该对象可以代替另一个对象进行一些操作。代理对象可以拦截对另一个对象的访问,对访问进行一些控制和修改,从而实现一些高级的功能。

Proxy代理的原理是利用了JavaScript中的“元编程”能力,即能够对代码进行动态修改和增强的能力。通过创建一个代理对象,我们可以拦截并修改对目标对象的访问,包括读取、赋值、删除等操作。代理对象可以在这些操作发生之前或之后进行一些自定义的处理,从而实现对目标对象的控制和修改。

在使用Proxy代理时,我们需要定义一个“处理器”(handler)对象,该对象包含一些拦截方法,用于拦截对代理对象的操作。处理器对象可以拦截的方法包括get、set、has、deleteProperty、apply等等。通过定义这些方法,我们可以对代理对象的访问进行拦截和修改,从而实现一些高级的功能,比如数据绑定、属性拦截等等。

需要注意的是,Proxy代理只能对ES6标准中定义的对象进行代理,对于一些内置对象如Array、Date等,可以通过使用Reflect对象中的方法来进行操作。同时,由于Proxy代理的性能比直接访问对象要慢一些,因此在一些需要高性能的场景中,需要谨慎使用。

20、说说内存泄漏的理解?内存泄漏的情况有哪些?


内存泄漏指的是程序中申请的内存空间没有被正确释放,从而导致系统的内存资源被浪费或者耗尽的现象。当一个对象没有被程序再次使用时,占用的内存空间应该被立即释放,但是如果程序中存在一些不当的内存使用方式,就会导致内存泄漏。

内存泄漏的情况包括:

循环引用:在程序中存在两个或多个对象之间的相互引用关系,而这些对象中至少有一个不再被程序使用,但是由于相互引用关系,导致这些对象无法被垃圾回收机制回收,从而造成内存泄漏。

内存泄漏的DOM元素:在JavaScript中,DOM元素是非常常见的内存泄漏来源,因为DOM元素的创建和销毁是由浏览器控制的,如果程序中存在对DOM元素的引用,但是没有及时释放,就会导致内存泄漏。

定时器:如果程序中存在一些没有被正确清理的定时器,就会导致内存泄漏。例如,如果一个定时器在页面销毁之前没有被清除,就会一直占用内存空间,从而导致内存泄漏。

闭包:闭包是一种非常强大的编程技巧,但是如果不小心使用会导致内存泄漏。当一个函数返回一个内部函数时,内部函数会保留对外部函数的引用,如果这个内部函数被存储或者传递给其他对象,就会导致外部函数无法被垃圾回收机制回收,从而造成内存泄漏。

资源未释放:在程序中使用一些系统资源,如文件、网络连接、数据库连接等,如果这些资源在使用完毕后没有被正确释放,就会导致内存泄漏。

为避免内存泄漏,我们需要遵循良好的编程习惯,及时释放不再使用的对象和资源,避免循环引用、不合理的定时器使用、合理使用闭包等方式。另外,使用一些工具如内存检测工具、代码分析工具等也可以帮助我们及时发现内存泄漏问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值