锦囊妙计(三)

  1. form表单是怎么上传文件的?你了解它的原理吗?

简单来说就是把文件转换为字节流,然后使用http进行传输,后端接受后吧二进制转化为原先的文件格式;

  • HTML表单中,可以上传文件的唯一控件是<input type="file">
    当一个表单包含<input type="file">时,表单的enctype必须指定为multipart/form-data(表明表单需要上传二进制数据),method必须指定为post,浏览器才能正确编码并以 multipart/form-data 格式发送表单的数据。multiple="multiple"说明可以同时上传多个文件。accept 限制上传文件格式,以,分隔
    通常,上传的文件都由服务器处理,js可以在提交表单的时候对文件扩展名进行检查
var  f = document.getElementById('test-file-input');
var filename = f.value;
if(!filename || !(filename.endWith('.jpg') || (filename.endWith('.png') || (filename.endWith('.gif') )){
	console.log('Can only upload image file');
	return false;
}

File API

js无法读取上传文件的内容,HTML5新增的File API允许JS读取文件内容,获取文件信息
File API主要提供:File (获取文件信息)和 FIleReader(读取文件) 两个对象

//图片上传和预览
var fileInput = document.getElementById('test-image-file'),
    info = document.getElementById('test-file-info'),
    preview = document.getElementById('test-image-preview');
fileInput.addEventListener('change',function(){
	preview.style.backgroundImage = '';
	if(!fileInput.value){
		info.innerHTML = '没有选择文件'return
	}
	var file = fileImput.files[0];
	info.innerHTML =  '文件: ' + file.name + '<br>' +
                     '大小: ' + file.size + '<br>' +
                     '修改: ' + file.lastModifiedDate;
    if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
        alert('不是有效的图片文件!');
        return;
    }
    // 读取文件:
    var reader = new FileReader();
    reader.onload = function(e) {
        var
            data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...'            
        preview.style.backgroundImage = 'url(' + data + ')';
    };
    // 以DataURL的形式读取文件:
    reader.readAsDataURL(file);
})
  1. 用过flex吗?简要说说你对它的理解

采用flex布局的元素成为flex容器,子元素称为flex项目(flex布局中,float、clear、vertical-align属性失效
容器属性:flex-derection(主轴)、flex-wrap(换行)、flex-flow(主轴/换行)、justify-content(主轴对齐)、align-items(交叉轴对齐)、align-content(多行主轴对齐)
项目属性:flow-grow(放大比例)、flow-shrink(缩小比例)、flow-basic(初始大小)、flow(放大/缩小/初始)、align-self(对齐方式)、order(排序位置)
深入理解Flex布局

  1. form表单提交时为什么会刷新页面?怎么预防刷新?

  2. 说说你对CDN的理解,使用过程中有没有遇到过问题?
    参考:https://www.cnblogs.com/shamo89/p/9234705.html

  3. 什么叫事件委托?优点是?

事件委托:利用事件冒泡指定一个时间处理程序,来管理某一类型的所有事件
作用:利用冒泡的原理,将事件加到父级身上,触发执行效果,这样只在内存中开辟一块空间,既节省资源又减少DOM操作,提高性能;动态添加的元素也可以绑定事件
步骤:第一步:给父元素绑定事件(给元素ul添加绑定事件,通过addEventListener为父元素绑定事件

第二步:监听子元素的冒泡事件(点击子元素li会向上冒泡)
第三步:找到是哪个子元素的事件(通过匿名回调函数的参数e用来接收事件对象,通过target获取触发事件的目标)

  1. document的load和ready的区别

load表示页面资源加载完成;ready表示dom加载完成

  1. web workers有用过吗?能帮我们解决哪些问题?

  2. 你了解过HTML5的地理定位吗?怎么使用?

  3. 网站被劫持植入广告该怎么办?如何防止?

  4. 什么是视差滚动?如何实现视差滚动的效果?

  5. 写出4个使用this的典型例子

  6. JSONP的原理是什么?解决什么问题?

JS动态插入script并将src指向后端API,后台返回json并使用协定的callback函数把json封装,浏览器以js内容解析执行返回的内容,回调函数被调用并传入返回的json对象
解决跨域问题,但不支持post请求

function JSONP(url, params, callback) {
    const script = document.createElement("script");
    script.src = url + parseObjToParams({...params, callback: "jsonpCallback"});
    document.body.appendChild(script);
    window.jsonpCallback = callback;
    script.onload = () => {
        document.body.removeChild(script)
    }
}

JSONP("http://localhost:3019/asd", {name: "vijay"}, (data) => {
    console.log(data);
});

//server
app.use("/asd", (req, res, next) => {
    res.jsonp({ user: 'tobi' })
});
  1. HTML5的download属性你了解吗?

只有 Firefox 和 Chrome 支持 download 属性

<a href='' download="filename">
  1. 请说下你对__proto__和prototype的理解
  • 只有函数对象才有prototype属性;prototype对象上存放共用的方法和属性
  • 对象都有__proto__属性,__proto__是指向该对象构造函数的原型属性(即prototype)
function Parent(name){
  this.name = name
}
Parent.prototype = {
  contructor:Parent,
  speak:function(){
    console.log(`我是${this.name}`)
  }
}
var children = new Parent('xiaoming')
children.name  // xiaoming
children.speak() // 我是xiaoming
children.__proto__ ===Parent.prototype  // true       
Parent.prototype.__proto__ === Object.prototype  // true  
children.toString()  // "[object Object]"

上面可以看出通过__proto__属性我们可以拿到Object原型对象上的属性和方法,原型对象上的__proto__又指向该构造函数的prototype,从而形成了一条原型链。上面children能够使用toString方法的原因。

  1. 说说你对WebGL的理解

WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等

  1. 对IPV6的理解

ipv6增加了海量的网络地址,使物联网成为可能。ipv4提供的2的32次方的地址根本不够无数的家用设备使用。而2的128次方的地址可为飞速增加的物联网设备提供足够的地址。如今到来的5G时代,ipv6在底层上可谓功不可没。

  1. 怎样把一个div居中?怎样把一个浮动元素居中?怎样把绝对定位的div居中?
  • text-alin: center;
  • margin: 0 auto;
  • position: relative | absolute; left: 50%;
  • vertical-align: middle;
  • transform: translate(-50%);
  1. 有用过HTML5的WebWork吗?它主要解决了什么问题?

  2. 说说你对同构和SSR的理解

  3. 手动写动画最小时间间隔是多少,为什么?
    一般浏览器的刷新频率为每秒60次,所以最小时间间隔是1000ms/60FPS = 16.667ms/FPS

  4. 有使用过HTML5的拖放API吗?说说你对它的理解

图片默认自带拖拽功能,非图片元素设置draggable属性为true即可拖拽。

  • 被拖拽元素的事件:
    ondragstart 拖拽的一瞬间触发
    ondrag 拖拽期间连续触发
    ondragend 拖拽结束触发
  • 目标元素事件(将拖拽元素释放的地方):
    ondragenter 进入目标元素触发(鼠标光标进入)
    ondragover 进入离开目标元素连续触发
    ondragleave 离开目标元素触发
    ondrop 在目标元素上释放鼠标触发
    默认状态下,一个元素不能放在另一个元素上面,需要在ondragover上阻止默认事件。
  1. 设计模式是什么?常用的设计模式有哪些?

设计模式:让代码可重用、可扩展、可解耦的拟物化思维
常用:创建型(原型、单例、工厂等)、结构型(适配器、组合等)、行为型(观察者、中介者等)、技巧型(参与者、委托等)、架构型(同步模块、异步模块、mvc,mvvm等)

  1. 举例说明JS的变量声明提升和函数声明提升

变量声明只提升声明 不提升赋值操作,函数声明 函数体整体被提升。

var getName = function(){
  console.log(4)
}

function getName() {
  console.log(5)
}
//不是4的优先级是高于5, 而是5的优先级高于4,
//5先声明, 但是后来它被4覆盖而已
getName() // 4 函数声明优先级高于var声明,  故 4 覆盖了 5
  1. 如何让(a == 1 && a == 2 && a == 3)的值为true,把"== “换成” ==="后还能为true吗?

=== 严格相等,会比较两个值的类型和值
== 抽象相等,比较时,会先进行类型转换,然后再比较值

“==” 转化规则:
首先通过valueOf 转换,即 obj.valueOf()方法的返回值
如果 obj.valueOf()方法的返回值是原始类型,那么直接返回
如果不是,再通过 obj.toString()方法转换
如果obj.toString()返回的是原始类型,直接返回该值
如果还不是原始类型,抛出不能转换异常。

const a = { value : 0 };
a.valueOf = function() {
    return this.value += 1;
};

console.log(a==1 && a==2 && a==3); //true
  1. 数据类型转换:显式转换和隐式转换

  2. html直接输入多个空格为什么只显示一个?

该行为由CSS 中的 white-space 控制,其默认值 normal的表现即为多个空格压缩为1个
设置为pre-wrap,pre等属性值,是可以解决这个问题的

  1. 请解释下什么是cookie隔离?为什么要隔离?如何隔离?

如果静态文件放在后台(前后端不分离时候),那静态文件请求的时候都带有的cookie的数据提交给server的,非常浪费流量,
cookie有域的限制,因此不能跨域提交请求,故使用非主要域名的时候,请求头中就不会带有cookie数据,
这样可以降低请求头的大小,降低请求时间,从而达到降低整体请求延时的目的。
同时这种方式不会将cookie传入Web Server,也减少了Web Server对cookie的处理分析环节,
提高了webserver的http请求的解析速度。

  1. 元素竖向的百分比设置是相对容器的高度吗?
    不是,一般是根据宽度来的,例如padding-top、padding-bottom

    因为高度百分比的话CSS没办法处理,比如子元素的高度设置为200%,那父元素是不是被撑开了,然后父元素变化了,子元素的200%是不是相对又变化了,所以会造成一个死循环,在CSS里面是没办法处理高度百分比的,高度都是auto。

    如果想要实现等比例的盒子模型,可以通过上面的padding-top,padding-bottom属性来实现。
    元素竖向的百分比设置高度是相对父级的高度,但是margin 和padding 是参照父级的宽度来设置的。
    父级非 auto 的 height 时,子级百分比的 height 才有效。
    即使父级有 min-height 或其他子级撑起的高度,子级百分比 height 依旧无效。

  2. 页面添加了<! DOCTYPE html>说明该页面采用了W3C标准,如果不加则页面会根据浏览器自身的解析标准来解析,这可能会导致页面在不同的浏览器呈现出不同的效果。

  3. 说说你对js隐式类型转换的理解

  • 等于判断:等于判断时,是会去先转为相同数据类型,再判断的:Array -> String -> Number -> Boolean 有顺序的。
0 == '0';   // true,转为 0 == 0
0 == [];    // true,转为 0 == '' 再转 0 == 0
'0' == [];  // false,转为 '0' == ''
'0' == true  // false,转为 0 == true 再转 false == true
  • 大小判断
  • 运算时类型转换等
  1. js动画和css动画有啥区别?
  • 代码复杂度,js 动画代码相对复杂一些
  • 动画运行时,对动画的控制程度上,js 能够让动画,暂停,取消,终止,css动画不能添加事件
  • 动画性能看,js 动画多了一个js 解析的过程,性能不如 css 动画好
  1. formData主要是用来做什么的?它的操作方法有哪些?
  • 将form表单元素的name与value进行组合
  • 异步上传文件
  1. 图片格式
  • jpg, 色彩复杂图片
  • png, 色彩简单图片
  • gif, 动图, 或者色彩极简的icon等
  • webp, 判断能使用webp的浏览器就是用webp
  1. 为什么浏览器会有兼容的问题呢?
    因为各家浏览器厂家实现的W3C标准各不相同

  2. 说说你对base64的理解,它的使用场景有哪些?

base64不会发起网络请求,所以,很多以前需要雪碧图解决的问题,用base64解决也挺好的

  • 上传图片时 先将图片转化为base64 然后上传
  • 对于小质量的图片 我们可以转化为base64 在页面展示
  • url 通过base64加密
  1. get 请求和post请求的区别
    (1) get:
  • GET请求会将参数跟在URL后进行传递,也就是会在url中显示
  • GET请求有数据长度限制,一般在2000个字符,而POST没有。
  • GET方式请求的数据会被浏览器缓存起来,POST没有
  • GET在某些情况下会有安全问题,POST没有。
  • 在客户端使用get请求时,服务器端使用Request.QueryString来获取参数
  • get请求参数会在url中显示,容易被他人窃取,post在请求体中,不会被窃取

(2) post:

  • POST请求是作为HTTP消息的实体内容发送给WEB服务器。
  • 客户端使用post请求时,服务器端使用Request.Form来获取参数。
  • post一般用于修改服务器上的资源,对所发送的信息没有限制。
  • post比get更加安全
  • post需要设置请求头
  1. html的a标签属性rel='nofollow’有什么作用?
    告诉爬虫,别往下走了,防止爬虫跳出自己的站点。
    爬虫默认遇见链接,会继续爬取链接的内容。

  2. 说说你对深浅拷贝的理解。并实现一个对数组和对象的深拷贝方法
    因为对象是引用类型,所以赋值时的操作仅是赋予相同的地址,当对其中一个对象进行操作时,就会影响其他的对象。解决这个问题就需要拷贝了。

  • 浅拷贝
    使用原生的Object.assign()方法就可以实现浅拷贝
    数组浅拷贝的方法还可以用 Array.from()
    但是如果拷贝的源对象当中包含对象时,OBject.assign()方法只会拷贝对象的引用地址
var obj1={
    value: 'a'
}
var obj2 = Object.assign({},obj1);
obj2.value='b';
console.log(obj1);//{ value: 'a' }
  • 深拷贝
    如果要拷贝的对象中包含对象,就需要深拷贝了,一般使用原生的方法JSON.parse(JSON.stringify(obj))
j1={
    value: 'a',
    obj3:{
        value2: 'c'
    },
    arr:[1,2,3]
}
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.obj3.value2='b';
obj2.arr[0]= "a";
console.log(obj2);//{ value: 'a', obj3:{ value2: 'b' }, arr:['a',2,3] }
console.log(obj1);//{ value: 'a', obj3:{ value2: 'c' }, arr:[1,2,3] } 没有发生改变
  • 实现一个对数组和对象深拷贝的方法
var obj={
    name: 'znl',
    age: 18,
    friend:{
        name: 'borys',
        age: 20
    },
    arr:[1,2,[3,4]]
}

function copy(obj){
    var type=Object.prototype.toString.call(obj);
    if(!(type == '[object Array]' || type == '[object Object]')){
        return 'Type Error!';
    }
    return JSON.parse(JSON.stringify(obj));
}

var obj2= copy(obj);
console.log(obj.friend === obj2.friend)//false
console.log(obj.arr === obj2.arr)//false
  1. 你对响应式设计的理解是什么?知道它基本的原理是吗?要想兼容低版本的IE怎么做呢?
  • 理解:在不同系统,不同设备,不同尺寸的界面,有良好的用户体验,舒适的阅读体验,交互体验。
  • 原理:根据不同设备尺寸,浏览器自动调整或通过样式调整,来保证用户体验。
  • 兼容:Respond.js
  1. 移动端点击事件延时原因:等待300ms判断用户是点击还是双击缩放
    解决:禁止缩放、设置默认视口宽度为设备宽度、设置css touch-action:none等;直接(设置viewpoint)

  2. 在实际编写css中你有遇到过哪些浏览器兼容性的问题?怎么解决的?

  3. favicon.ico有什么作用?怎么在页面中引用?常用尺寸有哪些?可以修改后缀名吗?

  • 作用:收藏夹图标,不仅是网站的头像,也是其可以让浏览器的收藏夹中除了显示相应的标题外,还以图标的方式区分不同的网站
  • 引用:<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
  • 尺寸:1616 3232
  1. 在a标签上4个伪类的执行顺序是什么
    执行顺序::link -> :hover-> :visited -> :active
    书写顺序::link -> :visited -> :hover -> :active
    (因为存在样式层叠问题,调整书写顺序需要,把类似hover这种瞬时状态覆盖link这种常态)

  2. js中=、== 、===三个的区别是什么?并说明它们各自的工作过程

  • =赋值操作符。执行顺序是从右到左, 比如 a = b = c,先执行 b = c,再执行 a = b。结合其它算术运算符就是复合赋值运算符比如: +=,-=,*=。a += b 等价于 a = a + b,其它复合赋值运算符类似。

  • == 在 js 中叫 不严格等于。js 中的 也==是用来比较左右操作数是否相等,但是它在比较时会自动进行类型转换,不严格。举个例子 ‘’ == false 返回的结果是 true,左右都被转换成数字进行比较 Number(’’) 和 Number(false) 都返回 0,所以相等。

  • ===在 js 中叫 严格等于。就是严格比较左右两个操作数的相等性,0 === false 结果是 false。

  1. 请你解释下什么是浮动和它的工作原理是什么?同时浮动会引起什么问题?
  • 浮动:布局方法之一
  • 原理:使元素脱离文档流,让元素可以左右浮动,直到遇到另一个浮动元素的边缘才停止
  • 引发问题:浮动元素会造成父级元素无法自动获取高度、导致父级元素塌陷,布局混乱;浮动元素没有设置宽度,默认收缩为内容宽度
  1. html文件各部分内容解惑:https://github.com/Amery2010/HEAD

  2. 你对web服务器有了解吗?都用过那些?
    最主流的三个Web服务器是 Apache、 Nginx 、IIS 吧
    所以暂时面对的需求,除了配端口指向不同文件夹外暂时还没啥别的尝试。
    那么,直接在服务器上跑 npm 的 anywhere 或 http-server 好像也阔以。但这些顶多算上web容器

  3. 说说instanceOf和typeOf的实现原理,模拟实现一个instanceOf

  • typeof 获取数据底层的类型标签,返回 ‘string’, ‘number’, ‘undefined’, ‘boolean’, ‘object’, ‘function’, ‘symbol’。
  • instanceof 利用原型链判断“父级”的原型(prototype)对象是否在“实例”的原型链上,返回Boolean
    模拟实现:
function new_instance_of(leftVaule, rightVaule) { 
    let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
    leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
    while (true) {
    	if (leftVaule === null) {
            return false;	
        }
        if (leftVaule === rightProto) {
            return true;	
        } 
        leftVaule = leftVaule.__proto__ 
    }
}
  1. 你会抓包吗?都用过什么抓包工具?
    用过Fiddler,可以用来拦截请求头和响应头,然后对请求头或响应头进行伪造,解决跨域等问题;
    wireshark、whistle

  2. 运算符 + 的implicit type conversion规则:

若任何一侧是 string 或 object 则两边转换为 string 进行连接
否则均转换为 number 并进行相加
注意symbol 相加会 throw TypeError

  • a = 1;b = {“a”:1} a+b=NaN
  • a = 1;c = [1,2] a+c = “11,2”
  • a = 1;d = function(){return 1} a+d = “1function(){return 1}”
  1. 请问display:inline-block在什么时候会显示间隙?
  • 在标签中会回车符,回车符相当于空白符,多个连续的空白符会合并成一个空白符,而产生“空白间隙”。
  • 解决方法: 设置父元素的font-size: 0; letter-spaceing: -4px;或者取消两个div之间的空格,设置vertical-align:bottom消除底部缝隙
  1. 说说你对HTML5的img标签属性srcset和sizes的理解?都有哪些应用场景?
  • sizes 属性规定被链接资源的尺寸。只有当被链接资源是图标时 (rel=“icon”),才能使用该属性。
  • srcset 属性用于浏览器根据宽、高和像素密度来加载相应的图片资源。可以适应不同屏幕,加载不同大小的图片。
    应用场景:多用于响应式图片或不同像素密度设备的图片适配;
    响应式图片的几种解决方案
  1. 你有使用过JWT吗?说说你对它的理解

JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案。服务器认证以后,生成一个 JSON 对象,由客户端保存,每次服务端通信只要但是这个json对象就可以。方便服务器拓展。
JWT 由三部分组成Header(头部),Payload(负载),Signature(签名)。Header(头部),Payload(负载)都是json对象。Signature 部分是对前两部分的签名。

  1. 举例说明数组和对象的迭代方法分别有哪些?
  • 数组
  • forEach((item, index)) :无返回值,不可中断
  • map((item,index)) :map 不会修改原数组,返回一个新的数组。如果忘记写 return 就会返回 undefined
  • filter((item,index)) : filter 根据输入的条件将返回值为 true 的项重新组成数组返回出去
  • some((item, index)) / every((item, index)) :都是对输入的条件进行判断,some 只要有一个满足就返回 true; every 是需要所有项都满足才返回 true
  • reduce((prev,cur, index)) / reduceRight((prev, cur, index)) :汇总的意思,允许我们对数组前一项和当前项进行操作,自定义返回值类型
  • for (let value of arr) {}
  • for (let index in arr) {}
  • 对象
  • Object.keys(obj) :获取键值,然后遍历键值来遍历数组
  • Object.values(obj) :直接获取到对象所有的value值
  • Object.getOwnPropertyNames(obj) :
  • Object.entries(obj) :获取到对象的键值对数组,然后遍历数组就能遍历对象了
  • for (let value of arr) {}
  • for (let index in arr) {}
  1. 你有用过HTML5中的datalist标签吗?说说你对它的理解
  • 定义:H5中新标签,配合 “自动完成”的特性,给用户的选项列表
  • 使用:中排列选项,并与input绑定(中list与中id选项值相同)
  • 兼容:ie9以上
<input list="browsers">
<datalist id="browsers">
  <option value="Internet Explorer">
  <option value="Firefox">
  <option value="Chrome">
  <option value="Opera">
  <option value="Safari">
</datalist>
  1. 举例说明什么是IIFEs?它有什么好处?

立即自执行匿名函数,我一般用它来 1. 独立作用域,2. 直接递归,3. 节约变量

// 我经常这样子来写异步递归,不用单写函数和变量然后调用
(function loop(min, max) {
  if (++min > max) return;
  // ......
  loop(min, max);
}(1, 10);

var getInfo = (function() {
  var info = null;
  return function(callback) {
    if (info) callback();
    ajax(api, function(res){
      info = res.data; callback();
    });
  }
})();

//通过立即执行函数来创造一个新的作用域并缓存变量,来解决闭包带来的副作用问题
for (var i=0;i<10;i++) {
     (function(i){
          setTimeout(function(){
               console.log(i);
          }, 100*i);
     })(i)
}
  1. 说说你对BEM规范的理解,同时举例说明常见的CSS规范有哪些?
    BEM:block(块)、element(元素)、modifier(修饰符),一种命名约定,可以让代码更易理解
    如:.card
    .card__body
    .card__button–primary

还有OOCSS,面向对象的CSS书写规范。
不管哪种,解决问题,同时团队大家共同维护遵守的,才是好的规范和执行。

  1. HTML5的应用程序缓存与浏览器缓存有什么不同?

应用程序缓存是 HTML5 的重要特性之一,提供了离线使用的功能,让应用程序可以获取本地的网站内容,例如 HTML、CSS、图片以及 JavaScript。这个特性可以提高网站性能,它的实现借助于 manifest 文件,与传统浏览器缓存相比,它不强制用户访问的网站内容被缓存

  1. 你知道什么是websocket吗?它有什么应用场景?

相对于HTTP这种非持久的协议来说WebSocket是一个持久化的协议,允许服务端主动向客户端推送数据。
应用场景:社交订阅、多玩家游戏、协同合作、在线聊天、实时获取股票数据等

  1. 写例子说明如何强制(自动)中、英文换行与不换行

word-break:break-all;只对英文起作用,以字母作为换行依据
word-wrap:break-word; 只对英文起作用,以单词作为换行依据
white-space:pre-wrap; 只对中文起作用,强制换行
white-space:nowrap; 强制不换行,都起作用
white-space:nowrap; overflow:hidden; text-overflow:ellipsis;不换行,超出部分隐藏且以省略号形式出现(部分浏览器支持)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值