web前端经典面试题及答案_web前端面试题

<div id="myDiv">
    <input type="button" value="Click me" id="myBtn">
</div>
<script type="text/javascript">
    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
        document.getElementById("myDiv").innerHTML = "Processing...";
    }
</script>

解决方法如下:

<div id="myDiv">
    <input type="button" value="Click me" id="myBtn">
</div>
<script type="text/javascript">
    var btn = document.getElementById("myBtn");
    btn.onclick = function(){
    btn.onclick = null;
        document.getElementById("myDiv").innerHTML = "Processing...";
    }
</script>

(2)、由于是函数内定义函数,并且内部函数–事件回调的引用外暴了,形成了闭包。闭包可以维持函数内局部变量,使其得不到释放。

实例如下:

function bindEvent(){
    var obj=document.createElement("XXX");
    obj.onclick=function(){
        //Even if it's a empty function
    }
}

解决方法如下:

function bindEvent(){
    var obj=document.createElement("XXX");
    obj.onclick=function(){
         //Even if it's a empty function
    }
    obj=null;
}

在这里分享一个前端面试题库小程序    MST题宝库

javascript面向对象中继承实现?

面向对象的基本特征有:封闭、继承、多态。

在JavaScript中实现继承的方法:

  1. 原型链(prototype chaining)

  2. call()/apply()

  3. 混合方式(prototype和call()/apply()结合)

  4. 对象冒充

继承的方法如下:

1、prototype原型链方式:

2、call()/apply()方法

3、混合方法【prototype,call/apply】

4、对象冒充
javascript相关程序计算题
1、判断一个字符串中出现次数最多的字符,统计这个次数
var str = 'asdfssaaasasasasaa';
var json = {};
for (var i = 0; i < str.length; i++) {
    if(!json[str.charAt(i)]){
       json[str.charAt(i)] = 1;
    }else{
       json[str.charAt(i)]++;
    }
};
var iMax = 0;
var iIndex = '';
for(var i in json){
    if(json[i]>iMax){
         iMax = json[i];
         iIndex = i;
    }
}        
console.log('出现次数最多的是:'+iIndex+'出现'+iMax+'次');
结果如下:出现次数最多的是:a出现9次
JavaScript 数组(Array)对象
1、Array相关的属性和方法

这里只是做了相关的列举,具体的使用方法,请参考网址

​
Array 对象属性

constructor 返回对创建此对象的数组函数的引用。


length 设置或返回数组中元素的数目。

prototype 使您有能力向对象添加属性和方法。


Array 对象方法


concat() 连接两个或更多的数组,并返回结果。

join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔。

pop() 删除并返回数组的最后一个元素。  

shift() 删除并返回数组的第一个元素

push() 向数组的末尾添加一个或更多元素,并返回新的长度。

unshift() 向数组的开头添加一个或更多元素,并返回新的长度。

reverse() 颠倒数组中元素的顺序。

slice() 从某个已有的数组返回选定的元素

sort() 对数组的元素进行排序

splice() 删除元素,并向数组添加新元素。

toSource() 返回该对象的源代码。

toString() 把数组转换为字符串,并返回结果。

toLocaleString() 把数组转换为本地数组,并返回结果。

valueOf() 返回数组对象的原始值

​
2、编写一个方法 去掉一个数组的重复元素

方法一:

var arr = [0,2,3,4,4,0,2];
var obj = {};
var tmp = [];
for(var i = 0 ;i< arr.length;i++){
   if( !obj[arr[i]] ){
      obj[arr[i]] = 1;
      tmp.push(arr[i]);
   }
}
console.log(tmp);
结果如下: [0, 2, 3, 4]

方法二:

var arr = [2,3,4,4,5,2,3,6],
   arr2 = [];
for(var i = 0;i< arr.length;i++){
    if(arr2.indexOf(arr[i]) < 0){
        arr2.push(arr[i]);
    }
}
console.log(arr2);
结果为:[2, 3, 4, 5, 6]

方法三:

var arr = [2,3,4,4,5,2,3,6];
var arr2 = arr.filter(function(element,index,self){
return self.indexOf(element) === index;
});
console.log(arr2);

结果为:[2, 3, 4, 5, 6]

方法四:

var arr = [1,2,3,4,2,3];
var arr2 = [];
for(var i = 0;i< arr.length;i++){
    if(!arr2.includes(arr[i])){
       arr2.push(arr[i]);
    }
} 
console.log(arr2);
结果为:[1, 2, 3, 4]

方法五:ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

function unique(arr) {
  return [...new Set(arr)]
}
var arr = [1,2,3,3,3,2];
unique(arr);
结果为:[1, 2, 3]
3、求数组的最值?

方法一:

  • 求数组最大值:Math.max.apply(null,arr);
var arr = [3,43,23,45,65,90];
var max = Math.max.apply(null,arr);
console.log(max);
// 90
  • 求数组最小值:Math.min.apply(null,arr);
var arr = [3,43,23,45,65,90];
var min = Math.min.apply(null,arr);
console.log(min);
// 3

方法二:Array.max = function(arr){} / Array.min = function(arr){}

var array = [3,43,23,45,65,90];

Array.max = function( array ){ 
   return Math.max.apply( Math, array );
};
Array.min = function( array ){ 
   return Math.min.apply( Math, array );
};

var max = Array.max(array);
console.log(max);  // 90

var min = Array.min(array);
console.log(min);  // 3

方法三:Array.prototype.max = function(){};Array.prototype.min = function(){};

  • 求数组最大值(基本思路:将数组中的第一个值赋值给变量max ,将数组进行循环与max进行比较,将数组中的大值赋给max,最后返回max;)
var arr = [3,43,23,45,65,90];
Array.prototype.max = function() { 
    var max = this[0];
    var len = this.length; 
    for (var i = 0; i < len; i++){ 
        if (this[i] > max) { 
          max = this[i]; 
        } 
    } 
    return max;
}
var max = arr.max();
console.log(max);  // 90
  • 求数组最小值:
var arr = [3,43,23,45,65,90];
Array.prototype.min = function() { 
    var min = this[0];
    var len = this.length;
    for(var i = 0;i< len;i++){
        if(this[i] < min){
            min = this[i];
        }
    }
    return min;
}
var min = arr.min();
console.log(min);  // 3

在这里分享一个前端面试题库小程序    MST题宝库

4、数组排序相关

结合sort和函数排序:

  • 数组由小到大进行排序:sort,sortnum;
var arr = [3,43,23,45,65,90];
function sortnum(a,b){
  return a-b;
}
arr = arr.sort(sortnum);
console.log(arr);
// [3, 23, 43, 45, 65, 90]
  • 数组由大到小进行排序:sort,sortnum;
var arr = [3,43,23,45,65,90];
function sortnum(a,b){
  return a+b;
}
arr = arr.sort(sortnum);
console.log(arr);
// [90, 65, 45, 23, 43, 3]

冒泡排序:即实现数组由小到大进行排序;思路为:每次比较相邻的两个数,如果后一个比前一个小,换位置。如果要实现由大到小排序,使用reverse()即可;

var arr = [3, 1, 4, 6, 5, 7, 2];

function bubbleSort(arr) {
    var len = arr.length;
    for (var i = len; i >= 2; --i) {
        for (var j = 0; j < i - 1; j++) {
            if (arr[j + 1] < arr[j]) {
                var temp;
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    return arr;
}

var arr2 = bubbleSort(arr); 
console.log(arr2);  // [1, 2, 3, 4, 5, 6, 7]
var arr3 = arr2.reverse();
console.log(arr3);  //  [7, 6, 5, 4, 3, 2, 1]

快速排序:

思路:采用二分法,取出中间数,数组每次和中间数比较,小的放到左边,大的放到右边。

var arr = [3, 1, 4, 6, 5, 7, 2];
function quickSort(arr) {
    if(arr.length == 0) {
        return [];  // 返回空数组
    }
    var cIndex = Math.floor(arr.length / 2);
    var c = arr.splice(cIndex, 1);
    var l = [];
    var r = [];

    for (var i = 0; i < arr.length; i++) {
        if(arr[i] < c) {
            l.push(arr[i]);
        } else {
            r.push(arr[i]);
        }
    }
    return quickSort(l).concat(c, quickSort(r));
}
console.log(quickSort(arr));
//[1, 2, 3, 4, 5, 6, 7]
5、数组的翻转(非reverse())

方法一:

var arr = [1,2,3,4];
var arr2 = [];
while(arr.length) {
    var num = arr.pop(); //删除数组最后一个元素并返回被删除的元素
    arr2.push(num);
}
console.log(arr2);
// [4, 3, 2, 1]

方法二:

var arr = [1,2,3,4];
var arr2 = [];
while(arr.length){
    var num = arr.shift(); //删除数组第一个元素并返回被删除的元素
    arr2.unshift(num);
}
console.log(arr2);

jquery相关

1、 jQuery 库中的 $() 是什么?

( ) 函数是 j Q u e r y ( ) 函数的别称。 () 函数是 jQuery() 函数的别称。 ()函数是jQuery()函数的别称。() 函数用于将任何对象包裹成 jQuery 对象,接着你就被允许调用定义在 jQuery 对象上的多个不同方法。你可以将一个选择器字符串传入 $() 函数,它会返回一个包含所有匹配的 DOM 元素数组的 jQuery 对象。

2、如何找到所有 HTML select 标签的选中项

真题解析、进阶学习笔记、最新讲解视频、实战项目源码、学习路线大纲
详情关注公中号【编程进阶路】

$('[name=selectname] :selected')
3、$(this) 和 this 关键字在 jQuery 中有何不同?

$(this) 返回一个 jQuery 对象,你可以对它调用多个 jQuery 方法,比如用 text() 获取文本,用val() 获取值等等。

而 this 代表当前元素,它是 JavaScript 关键词中的一个,表示上下文中的当前 DOM 元素。你不能对它调用 jQuery 方法,直到它被 $() 函数包裹,例如 $(this)。

4、jquery怎么移除标签onclick属性?

获得a标签的onclick属性: $(“a”).attr(“onclick”)

删除onclick属性:$(“a”).removeAttr(“onclick”);

设置onclick属性:$(“a”).attr(“onclick”,“test();”);

5、jquery中addClass,removeClass,toggleClass的使用。

$(selector).addClass(class):为每个匹配的元素添加指定的类名

$(selector).removeClass(class):从所有匹配的元素中删除全部或者指定的类,删除class中某个值;

$(selector).toggleClass(class):如果存在(不存在)就删除(添加)一个类

$(selector).removeAttr(class);删除class这个属性;

6、JQuery有几种选择器?

(1)、基本选择器:#id,class,element,*;

(2)、层次选择器:parent > child,prev + next ,prev ~ siblings

(3)、基本过滤器选择器::first,:last ,:not ,:even ,:odd ,:eq ,:gt ,:lt

(4)、内容过滤器选择器: :contains ,:empty ,:has ,:parent

(5)、可见性过滤器选择器::hidden ,:visible

(6)、属性过滤器选择器:[attribute] ,[attribute=value] ,[attribute!=value] ,[attribute^=value] ,[attribute$=value] ,[attribute*=value]

(7)、子元素过滤器选择器::nth-child ,:first-child ,:last-child ,:only-child

(8)、表单选择器: :input ,:text ,:password ,:radio ,:checkbox ,:submit 等;

(9)、表单过滤器选择器::enabled ,:disabled ,:checked ,:selected

7、jQuery中的Delegate()函数有什么作用?

delegate()会在以下两个情况下使用到:

1、如果你有一个父元素,需要给其下的子元素添加事件,这时你可以使用delegate()了,代码如下:

$("ul").delegate("li", "click", function(){ $(this).hide(); });

2、当元素在当前页面中不可用时,可以使用delegate()

8、$(document).ready()方法和window.onload有什么区别?

(1)、window.onload方法是在网页中所有的元素(包括元素的所有关联文件)完全加载到浏览器后才执行的。

(2)、$(document).ready() 方法可以在DOM载入就绪时就对其进行操纵,并调用执行绑定的函数。

9、如何用jQuery禁用浏览器的前进后退按钮?

实现代码如下:

<script type="text/javascript" language="javascript">
  $(document).ready(function() {
    window.history.forward(1);
      //OR window.history.forward(-1);
  });
</script>
10、 jquery中 . g e t ( ) 提交和 .get()提交和 .get()提交和.post()提交有区别吗?

相同点:都是异步请求的方式来获取服务端的数据;

异同点:

1、请求方式不同: . g e t ( )  方法使用 G E T 方法来进行异步请求的。 .get() 方法使用GET方法来进行异步请求的。 .get() 方法使用GET方法来进行异步请求的。.post() 方法使用POST方法来进行异步请求的。

2、参数传递方式不同:get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的。

3、数据传输大小不同:get方式传输的数据大小不能超过2KB 而POST要大的多

4、安全问题: GET 方式请求的数据会被浏览器缓存起来,因此有安全问题。

11、写出一个简单的$.ajax()的请求方式?
$.ajax({
    url:'http://www.baidu.com',
    type:'POST',
    data:data,
    cache:true,
    headers:{},
    beforeSend:function(){},
    success:function(){},
    error:function(){},
    complete:function(){}
}); 
12、jQuery的事件委托方法bind 、live、delegate、on之间有什么区别?

(1)、bind 【jQuery 1.3之前】

定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

语法:bind(type,[data],function(eventObject));

特点:

(1)、适用于页面元素静态绑定。只能给调用它的时候已经存在的元素绑定事件,不能给未来新增的元素绑定事件。

(2)、当页面加载完的时候,你才可以进行bind(),所以可能产生效率问题。

实例如下:$( “#members li a” ).bind( “click”, function( e ) {} );

(2)、live 【jQuery 1.3之后】

定义和用法:主要用于给选择到的元素上绑定特定事件类型的监听函数;

语法:live(type, [data], fn);

特点:

(1)、live方法并没有将监听器绑定到自己(this)身上,而是绑定到了this.context上了。

(2)、live正是利用了事件委托机制来完成事件的监听处理,把节点的处理委托给了document,新添加的元素不必再绑定一次监听器。

(3)、使用live()方法但却只能放在直接选择的元素后面,不能在层级比较深,连缀的DOM遍历方法后面使用,即 ( “ u l ” " ) . l i v e . . . 可以,但 (“ul”").live...可以,但 (ul”").live...可以,但(“body”).find(“ul”).live…不行;

实例如下:$( document ).on( “click”, “#members li a”, function( e ) {} );

(3)、delegate 【jQuery 1.4.2中引入】

定义和用法:将监听事件绑定在就近的父级元素上

语法:delegate(selector,type,[data],fn)

特点:

(1)、选择就近的父级元素,因为事件可以更快的冒泡上去,能够在第一时间进行处理。

(2)、更精确的小范围使用事件代理,性能优于.live()。可以用在动态添加的元素上。

实例如下:

$(“#info_table”).delegate(“td”,“click”,function(){/*显示更多信息*/});

$(“table”).find(“#info”).delegate(“td”,“click”,function(){/*显示更多信息*/});

(4)、on 【1.7版本整合了之前的三种方式的新事件绑定机制】

定义和用法:将监听事件绑定到指定元素上。

语法:on(type,[selector],[data],fn)

实例如下:$(“#info_table”).on(“click”,“td”,function(){/*显示更多信息*/});参数的位置写法与delegate不一样。

说明:on方法是当前JQuery推荐使用的事件绑定方法,附加只运行一次就删除函数的方法是one()。

总结:.bind(), .live(), .delegate(),.on()分别对应的相反事件为:.unbind(),.die(), .undelegate(),.off()

HTML & CSS:

1、什么是盒子模型?

在网页中,一个元素占有空间的大小由几个部分构成,其中包括元素的内容(content),元素的内边距(padding),元素的边框(border),元素的外边距(margin)四个部分。这四个部分占有的空间中,有的部分可以显示相应的内容,而有的部分只用来分隔相邻的区域或区域。4个部分一起构成了css中元素的盒模型。

2、行内元素有哪些?块级元素有哪些? 空(void)元素有那些?

行内元素:a、b、span、img、input、strong、select、label、em、button、textarea
块级元素:div、ul、li、dl、dt、dd、p、h1-h6、blockquote
空元素:即系没有内容的HTML元素,例如:br、meta、hr、link、input、img

3、CSS实现垂直水平居中

一道经典的问题,实现方法有很多种,以下是其中一种实现:
HTML结构:

<div class="wrapper">
     <div class="content"></div>
</div>
CSS:

.wrapper {
    position: relative;
    width: 500px;
    height: 500px;
    border: 1px solid red; 
 }
.content{
    position: absolute;
    width: 200px;
    height: 200px;
    /*top、bottom、left和right 均设置为0*/
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    /*margin设置为auto*/
    margin:auto;
    border: 1px solid green;    
} 

效果如下:

4、简述一下src与href的区别

href 是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。

src是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。

当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。

5、简述同步和异步的区别

同步是阻塞模式,异步是非阻塞模式。
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。

6、px和em的区别

相同点:px和em都是长度单位;

异同点:px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em。

7、浏览器的内核分别是什么?

IE: trident内核

Firefox:gecko内核

Safari:webkit内核

Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核

Chrome:Blink(基于webkit,Google与Opera Software共同开发)

在这里分享一个前端面试题库小程序    MST题宝库

8、什么叫优雅降级和渐进增强?

渐进增强 progressive enhancement:
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。

优雅降级 graceful degradation:
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。

区别:

a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给

b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要

c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带

9、sessionStorage 、localStorage 和 cookie 之间的区别

共同点:用于浏览器端存储的缓存数据

不同点:

(1)、存储内容是否发送到服务器端:当设置了Cookie后,数据会发送到服务器端,造成一定的宽带浪费;

web storage,会将数据保存到本地,不会造成宽带浪费;

(2)、数据存储大小不同:Cookie数据不能超过4K,适用于会话标识;web storage数据存储可以达到5M;

(3)、数据存储的有效期限不同:cookie只在设置了Cookid过期时间之前一直有效,即使关闭窗口或者浏览器;

sessionStorage,仅在关闭浏览器之前有效;localStorage,数据存储永久有效;

(4)、作用域不同:cookie和localStorage是在同源同窗口中都是共享的;sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;

10、Web Storage与Cookie相比存在的优势:

(1)、存储空间更大:IE8下每个独立的存储空间为10M,其他浏览器实现略有不同,但都比Cookie要大很多。

(2)、存储内容不会发送到服务器:当设置了Cookie后,Cookie的内容会随着请求一并发送的服务器,这对于本地存储的数据是一种带宽浪费。而Web Storage中的数据则仅仅是存在本地,不会与服务器发生任何交互。

(3)、更多丰富易用的接口:Web Storage提供了一套更为丰富的接口,如setItem,getItem,removeItem,clear等,使得数据操作更为简便。cookie需要自己封装。

(4)、独立的存储空间:每个域(包括子域)有独立的存储空间,各个存储空间是完全独立的,因此不会造成数据混乱。

11、Ajax的优缺点及工作原理?

定义和用法:

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。Ajax 是一种用于创建快速动态网页的技术。Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

传统的网页(不使用 Ajax)如果需要更新内容,必须重载整个网页页面。

优点:

1.减轻服务器的负担,按需取数据,最大程度的减少冗余请求

2.局部刷新页面,减少用户心理和实际的等待时间,带来更好的用户体验

3.基于xml标准化,并被广泛支持,不需安装插件等,进一步促进页面和数据的分离

缺点:

1.AJAX大量的使用了javascript和ajax引擎,这些取决于浏览器的支持.在编写的时候考虑对浏览器的兼容性.

2.AJAX只是局部刷新,所以页面的后退按钮是没有用的.

3.对流媒体还有移动设备的支持不是太好等

AJAX的工作原理:

1.创建ajax对象(XMLHttpRequest/ActiveXObject(Microsoft.XMLHttp))

2.判断数据传输方式(GET/POST)

3.打开链接 open()

4.发送 send()

5.当ajax对象完成第四步(onreadystatechange)数据接收完成,判断http响应状态(status)200-300之间或者304(缓存)执行回调函数

12、请指出document load和document ready的区别?

共同点:这两种事件都代表的是页面文档加载时触发。

异同点:

ready 事件的触发,表示文档结构已经加载完成(不包含图片等非文字媒体文件)。

onload 事件的触发,表示页面包含图片等文件在内的所有元素都加载完成。

13、圣杯/双飞翼布局

圣杯布局与双飞翼布局针对的都是三列左右栏固定中间栏边框自适应的网页布局

  • 三列布局,中间宽度自适应,两边定宽
  • 中间栏要在浏览器中优先展示渲染
  • 允许任意列的高度最高

显示如图:

(1)、浮动布局(float+calc)

View Code

(2)、绝对布局(absolute+calc)

View Code

(3)、flex布局;

View Code

正则表达式

1、写一个function,清除字符串前后的空格。(兼容所有浏览器)
function trim(str) {
    if (str && typeof str === "string") {
        return str.replace(/(^\s*)|(\s*)$/g,""); //去除前后空白符
    }
}
2、使用正则表达式验证邮箱格式
var reg = /^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$/;
 var email = "example@qq.com";
 console.log(reg.test(email));  // true  

开发及性能优化

1、规避javascript多人开发函数重名问题
  • 命名空间
  • 封闭空间
  • js模块化mvc(数据层、表现层、控制层)
  • seajs
  • 变量转换成对象的属性
  • 对象化
2、请说出三种减低页面加载时间的方法

刷面试题

刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。

  • 前端字节跳动真题解析

  • 【269页】前端大厂面试题宝典

最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值