100道最常见的校招前端面试题(更新中)

发布时间:2018-09-24 17:00  浏览次数:40

*
Http协议中Post和Get方法的区别?

Get请求比Post执行更有效率,是因为浏览器在发送Post请求时,会先将请求头发送给服务器确认,服务器返回100
continue响应后,浏览器才开始发送数据。

*
如何利用CSS实现三角形?

将一个div的宽度和高度,都设置为0,设置div四个边框的宽度,并利用transparent属性隐藏三个边框,只留下一个边框,就可得到一个三角形?如果是直角三角形,则隐藏2个相邻的边框,剩下2个相邻的边框就拼成了一个直角三角形。

*
常见的跨域技术有哪些?
通过img标签的src属性
通过JSONP动态插入script标签,执行回调函数
通过跨域资源共享(CORS)发送AJAX请求,普通跨域请求只需在服务端设置Access-Control-Allow-Origin
即可。而带有cookie的跨域请求,还需在服务端设置Access-Control-Allow-Credentials,且前端设置xhr对象的
withCredentials属性为true。
通过配置代理服务器,如nginx反向代理proxy_pass字段,nodejs中间件,webpackserver的proxy属性等。
通过websocket进行跨域
通过HTML5API PostMessage实现多页面,多窗口以及iframe之间的的通信

*
如何利用CSS2实现元素水平垂直居中?
利用绝对定位 + margin: auto实现,设置top left bottom right为0
利用绝对定位,设置top left为50%,并设置transform: translate(-50%,-50%)实现
行内元素,使用text-align: center,并将line-height值设置为父元素高度
利用flex进行布局,设置align-items: center; justify-content: center;实现居中
将元素设置为table-cell,使用vertical-align: middle 以及text-align: center实现居中

*
rem和em的区别?
rem是根据html根元素的字体大小进行换算的,而em是根据父元素的字体大小进行换算的

*
闭包是什么?有什么用?
闭包是指有权访问另一函数作用域中变量的函数,创建闭包的常用方式就是在一个函数内部定义另一个函数。
闭包可以创建私有变量和方法,为setTimeout等方法传递参数等
闭包的缺点是,其让变量一直保存在内存中,容易造成内存泄露

*
图像懒加载的原理是什么?

页面加载时,将图片加载的链接,保存在img标签的自定义属性中,src属性为空,并监听窗口的scroll事件。当img标签出现在视口中时,利用js将图片加载编写填写至src属性中,实现动态加载图片。

*
git pull 和 git fetch方法的区别?
git fetch origin master:tmp是从远程仓库获取最新数据到本地,但其不会主动合并,需要你调用git merge
命令才会与当前分支合并,在此之前你可以调用git diff查看其与当前分支的差异,选择是否合并
而git pull是获取数据后,直接将其合并到当前分支

*
Https的主要特点?
https = http + 完整性保护(报文摘要) + 认证 + 加密
HTTPS只是HTTP通信接口部分用SSL或TLS等协议代替而已。当通信时,HTTP先与SSL通信,再由SSL和TCP进行通信。
https使用混合加密机制,首先使用非对称加密换取对称加密密钥,再使用对称加密传输数据信息
https使用数字证书认证机构(CA)和其相关机构颁发的公开密钥证书,可以使客户端验证服务器公开密钥的真实性。
https在发送数据时,会附加MAC报文摘要,从而防止报文在传输过程中遭遇篡改

*
position属性有哪些?
static: 默认值,位于文档流之中,正常布局
relative:位于文档流之中,可以使用top和left等属性,使其相对于原位置进行偏移
absolute:绝对定位,元素脱离文档流,相对于其包含块定位(第一个非static值的父元素)
fixed:与absolute类似,不过其包含块为页面。
inherit:从父元素那继承position属性
initial:默认样式
unset:未设置,若该样式可继承,则相当于inherit,若不可继承,则相当于initial

*
xss和crsf是什么?各有什么防御手段?

xss为跨站脚本攻击,攻击者向web网页中恶意植入代码,用户访问该页面时,就会受到攻击。防御手段:对输入(和URL参数)进行过滤并对输出进行编码,例如单双引号、反斜线、大于和小于号。如果
script、img、link以及background等标签或属性为动态内容,要确保这些url是安全的。在服务端对cookie设置http only
,防止攻击者窃取cookie值。
crsf为跨站请求伪造,指攻击者通过设置好的陷阱,强制对已完成认证的用户进行非预期的个人信息或设定信息等某些状态更新。防御手段:验证HTTP
Refer(缺点:老版的浏览器可可以篡改Refer),toke验证(在http请求中加入随机产生的toke,服务端进行合法性验证,缺点对每个请求都加入token比较麻烦,且token可能会被refer属性暴露),自定义HTTP属性头(通过XMLHttpRequest这个类,给http请求加上属性头,缺点为只限于ajax)

*
说一下vue实例的生命周期?
new Vue() > 初始化事件和生命周期 > beforeCreate > 数据绑定 > created > 如果有el属性,则编译模板 >
beforeMount > 添加$el属性,并替换掉挂载的DOM元素 > mounted > 数据更新 > beforeUpdate >
重新编译模板并渲染DOM >updated > 调用$destoryed > beforeDestory > 销毁vue实例 > destroyed

*
react中props和state有什么区别?

react是单向数据流,props是一个父组件传递给子组件的数据流接口,可以一直的被传递到子孙组件中,在组件内部的props是只读的。而state是组件内部私有的状态,通过修改state会触发组件的重新渲染。

*
如何解决float属性引起的父元素塌陷问题?
给父元素设置overflow: hidden属性
给父元素添加一个高度
通过伪类,给这个伪类添加clear: both 和 display: block

*
实现一个防抖函数和节流函数?
函数节流: 频繁触发,但只在特定的时间内才执行一次代码
函数防抖: 频繁触发,但只在特定的时间内没有触发执行条件才执行一次代码
//防抖函数 function debounce(fn, time){ return function(){ var context = this;
clearTimeout(timeId); timeId = setTimeout(function(){ fn.apply(context,
arguements); }, time); }; } //节流函数 function throttle(fn,time){ var last = 0;
return function(){ var context = this; var now = Date.now(); if (now - last >=
time){ fn.apply(this, arguments); last = now; } }; }
* Js中常见的对象继承方式? //原型链继承 SubType.prototype = new SuperType(); //构造函数继承 function
SubType(){ SuperType.call(this); }

原型链继承的缺点在于,当父类存在引用型属性时,该属性会被所有实例共享,因此修改某个实例的该属性,会影响到其他实例。而构造函数的缺点在于,每次调用构造函数,对象方法都会被创建一次,无法达到函数复用。因此在实际工作中,是结合两者进行使用,原型链继承方法,而构造函数继承属性。

* new操作符做了哪些事情? const a = new Foo(); //以下为new 操作符干的事情 var o = new Object();
//新建一个空对象 o.__proto__ = Foo.prototype; //将该空对象的原型指向构造函数的原型对象 Foo.call(o);
//在空对象上调用构造函数 a = o; //赋值给变量
* 说一说Js事件循环?
https://www.jianshu.com/p/12b9f73c5a4f <https://www.jianshu.com/p/12b9f73c5a4f>
https://www.cnblogs.com/cangqinglang/p/8967268.html
<https://www.cnblogs.com/cangqinglang/p/8967268.html>
https://www.cnblogs.com/jasonxuli/p/6074231.html
<https://www.cnblogs.com/jasonxuli/p/6074231.html>
* promise的原理是什么?
https://segmentfault.com/a/1190000009478377
<https://segmentfault.com/a/1190000009478377>
* CommonJS,AMD,CMD以及ES6 import的区别是什么?
CommonJS是运行时加载,ES6是编译时输出接口
CommonJS是输出的一个值的复制,而ES6输出的是值的引用
AMD
异步模块定义,通过define函数声明依赖模块(数组)和回调函数,特点是依赖前置,其加载模块完成后就会执行该模块,所有模块都加载执行完后会进入回调函数,执行主逻辑,这样的效果就是依赖模块的执行顺序和书写顺序不一定一致,看网络速度,哪个先下载下来,哪个先执行,但是主逻辑一定在所有依赖加载完成后才执行。
CMD
同样为异步加载,区别在于其为就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块,其加载完某个依赖模块后并不执行,只是下载而已,在所有依赖模块加载完成后进入主逻辑,遇到require语句的时候才执行对应的模块,这样模块的执行顺序和书写顺序是完全一致的。
* 说一下TCP的3次握手连接和4次挥手断开连接,为什么一个是3次,一个是4次?
三次握手:客户端向服务端发送一个SYN报文,服务端收到报文确认后,发送一个SYN-ACK报文,客户端收到服务器的报文后,返回一个ACK报文,连接建立。

四次挥手:客户端向服务端发送一个FIN报文,服务端收到报文后,立即发送一个ACK报文,随即通知本地服务启动清理工作,当清理完成时,发送一个FIN报文给客户端,客户端收到后返回一个ACK报文,连接关闭。
https://blog.csdn.net/zjw_python/article/details/79207185
<https://blog.csdn.net/zjw_python/article/details/79207185>
由于服务端接受到客户端关闭连接请求时,可能一些数据还没有发送完成,因此不能立刻关闭连接,因此多了一次挥手。
* DNS的解析过程是什么?

首先检查浏览器缓存中以及操作系统缓存中有没有对应的已解析过的结果(hosts文件),若没有则请求本地域名服务器(LDNS)来解析这个域名,若未成功解析,则跳转到根域名服务器,根域名服务器给予一个主域名服务器地址,然后本地域名服务器再去请求主域名服务器地址,接着主域名服务器会返回网站注册域名的服务器Name
server的地址,本地服务器又去访问Name server,最终找到ip地址并返回给本地域名服务器,然后缓存该ip地址,解析结束。
* CSS各选择器的优先级?
!important > 行内样式>ID选择器 > 类选择器/属性/伪类 > 标签 > 通配符 > 继承 > 浏览器默认属性
* 说一下浏览器从发起请求到呈现页面的整个过程?
DNS解析ip地址 > TCP三次握手连接 > 发送HTTP请求 > 服务器处理,返回HTTP响应 > 浏览器解析响应 >
构建DOM树、CSSrule树,合并生成render树,计算布局并绘制
* 高阶函数是什么?有什么用?
一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
高阶函数广泛应用于js中,例如map、sort、setTimeout等
* 说一下meta标签有什么用?

元素可提供有关页面的元信息(meta-information),比如针对搜索引擎、更新频度、cookie的描述和关键词。元数据总是以名称/值对的形式表示,名称有两种类型:
name和http-equiv。其中当名称为http-equiv,会将值关联到HTTP头部。常见的类型如下 <meta http-equiv="Refresh"
content="5;url=http://blog.yangchen123h.cn" /> 5秒跳转 <meta name="viewport"
content="width=device-width, initial-scale=1.0"> 页面适配 <meta http-equiv="charset"
content="iso-8859-1"> 声明字符集 <meta http-equiv="expires" content="31 Dec 2008">
声明过期时间
* HTML文档有哪几种文档类型?为什么要进行类型声明?
严格型(strict)、过渡型(transitional)和框架型(Frameset)
严格型不包括框架集、一些废弃的元素标签,过渡型包含废弃的元素标签,但不允许框架集。而框架型等同于过渡型,且允许框架。
作用:只有进行正确的类型声明,浏览器才能正确的解析html文档。
* bootstrap栅格系统的原理是什么?
媒体查询 + 百分比宽度 @media (min-width: 768px) {/*当宽度大于768px时触发*/ .container { width:
750px; } } @media (min-width: 992px) {/*当宽度大于992px时触发*/ .container { width:
970px; } } @media (min-width: 1200px) {/*当宽度大于1200px时触发*/ .container { width:
1170px; } }
*
vue的数据绑定是怎么实现的?
vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter
,在数据变动时发布消息给订阅者,触发相应的监听回调。
https://segmentfault.com/a/1190000006599500
<https://segmentfault.com/a/1190000006599500>

*
说一下diff算法?


首先比较旧结点和新结点的标签,属性是否相同,若不同,则没有可比性,直接全部替换。若相同,则比较开始比较子节点,若老结点没有子节点,新结点有,则创建子节点并插入到老结点中。若老结点有子节点,而新结点没有,则删除老结点的子节点。若两者都有子节点,则依次比较,比较方法如下
https://segmentfault.com/a/1190000008782928
<https://segmentfault.com/a/1190000008782928>

简单来说老子结点和新子结点各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互比较,一共有4种比较方式。如果4种比较都没匹配,如果设置了key,就会用key进行比较,在比较的过程中,变量会往中间靠,一旦StartIdx>EndIdx表明老结点和新结点至少有一个已经遍历完了,就会结束比较。
四种情况包括:
1 、老子节点的StartIdx和新子节点的StartIdx可比,则不移动dom,StartIdx均加1。
2 、老子节点的EndIdx和新子节点的EndIdx可比,则不移动dom,EndIdx均减1
3
、老子节点的StartIdx和新子节点的EndIdx可比,则将老子节点StartIdx指向的元素移到老子节点EndIdx的后面,老子节点StartIdx加1,新子节点的EndIdx减1
4、
老子节点的EndIdx和新子节点的StartIdx可比,则将老子节点EndIdx指向的元素移到老子节点StartIdx的前面,老子节点EndIdx减1,新子节点的StartIdx加1

*
vh和vw单位是什么?
vw:视窗宽度的百分比(1vw 代表视窗的宽度为 1%)
vh:视窗高度的百分比
vmin:当前 vw 和 vh 中较小的一个值
vmax:当前 vw 和 vh 中较大的一个值

*
说一下圣杯和双飞翼布局?
https://blog.csdn.net/zjw_python/article/details/82597078
<https://blog.csdn.net/zjw_python/article/details/82597078>

*
CSS可继承的属性
不可继承的:display、margin、border、padding、background、height、min-height、max-
height、width、min-width、max-width、overflow、position、left、right、top、
bottom、z-index、float、clear、table-layout、vertical-align、page-break-after、
page-bread-before和unicode-bidi
所有元素可继承:visibility和cursor
内联元素可继承:letter-spacing、word-spacing、white-space、line-height、color、font、
font-family、font-size、font-style、font-variant、font-weight、text-
decoration、text-transform、direction
块状元素可继承:text-indent和text-align
列表元素可继承:list-style、list-style-type、list-style-position、list-style-image
表格元素可继承:border-collapse

*
CSS选择器解析的方向是什么?为什么?
从右往左解析,因为这样可以提前过滤掉大部分不符合规则的元素,效率更高
https://blog.csdn.net/jinboker/article/details/52126021
<https://blog.csdn.net/jinboker/article/details/52126021>

*
js对象的深拷贝?
function deepClone(obj){ if (obj instanceof Object){ var newObj = Array.isArray
(obj)? []:{}; for (var key in obj){ if (obj[key] instanceof Object){ newObj[key]
= deepClone(obj[key]); }else{ newObj[key] = obj[key]; } } }else{ var newObj =
obj; } return newObjl }
* 长轮询和短轮询是什么?
短轮询指浏览器向服务器发送一个请求,询问是否有数据更新,服务里立刻返回响应。一段时间后浏览器又发起一个到服务器的新请求。

长轮询指浏览器向服务器发送一个请求,服务一直保持连接打开,直到有数据可发送,发送完数据后,浏览器关闭连接,随即又发起一个到服务器的新请求。(使用XHR对象和setTimeout()实现)
* 原生js读取和修改cookie? function getCookie(name){ var cookies = document.cookie.
split(";"); var value = null; for (var i =0; i<cookies.length;i++){ if (cookies[
i].indexOf(name+'=') > 0){ value = cookies[i].split("=")[1]; } } return value; }
function setCookie(name, value, expires, path, domain, secure){ var cookieText =
name+ '=' + value + ';'; if (expires){ cookieText += "expires= " + expires.
toGMTString() + ';'; } if (path){ cookieText += "path= " + path + ';'; } if (
domain){ cookieText += "domain= " + domain + ';'; } if (secure){ cookieText +=
"secure"; } document.cookie = cookieText; } function delCookie(name,path,domain,
secure){ setCookie(name, "", new Date(0), path, domain, secure); }
*
HTTP2有什么特点?
HTTP/2采用二进制格式而非文本格式。
在应用层(HTTP/2)和传输层(TCP or
UDP)之间增加一个二进制分帧层。在该二进制分帧层中,HTTP2.0将传输的消息划分为更小的消息和帧,并采用二进制编码。其中HTTP1.1的首部信息被封装到HEADER
frame,而请求实体被封装到DATA frame中。
HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个连接即可实现并行
使用报头压缩,HTTP/2降低了开销(采用了HPACK压缩算法)
HTTP/2让服务器可以将响应主动“推送”到客户端缓存中

*
实现一个两栏布局,左边固定宽度,右边自适应?
https://www.cnblogs.com/wangzhenyu666/p/7904522.html
<https://www.cnblogs.com/wangzhenyu666/p/7904522.html>

*
cookie、localStorage、sessionStorage的区别是什么?
共同点:都是保存在浏览器端、且同源的
区别:

1、cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下

2、存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大

3、数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭

4、作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
5、web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
6、web Storage的api接口使用更方便

*
分别列举几个HTTP请求头字段和响应头字段?
https://blog.csdn.net/zjw_python/article/details/79305173
<https://blog.csdn.net/zjw_python/article/details/79305173>

*
call、apply、bind方法的区别是什么?

三种方法都能在运行时改变this的指向,区别在于call,apply用于执行函数,bind用于返回一个新函数。call方法的参数项需要一个个列出来,而apply参数项则是一个列表,bind后面接的参数用于函数柯里化。

*
ES6 map和对象的区别?
map的键可以是任意数据结构,而对象只能是字符串。
map可以通过size属性,无需遍历,即可获取键值对的个数。

*
HTTP强缓存和协商缓存是什么?
https://www.cnblogs.com/wonyun/p/5524617.html
<https://www.cnblogs.com/wonyun/p/5524617.html>

*
webworker的作用以及使用方式?
https://blog.csdn.net/zjw_python/article/details/80277375
<https://blog.csdn.net/zjw_python/article/details/80277375>

*
如何计算首屏和白屏时间
http://www.bubuko.com/infodetail-2265464.html
<http://www.bubuko.com/infodetail-2265464.html>

*
前端页面如何优化?
1、减少HTTP请求次数
2、使用缓存、内容分发网络CDN(使用多个不同的域名存储资源,突破浏览器的并发限制,老版IE6并发连接为2个,而现代浏览器大多为6次)
3、图片懒加载、css spirte(background-position,background-image)
4、使用事件委托、防抖节流等技术
5、尽可能使用CSS动画
6、压缩css、js、图片等文件
7、避免DOM深层次嵌套,减少对DOM的访问次数
8、将外部脚本置底
9、减少重绘和回流次数

*
DPR是什么?
https://www.cnblogs.com/liujn0829/p/7909218.html
<https://www.cnblogs.com/liujn0829/p/7909218.html>
https://blog.csdn.net/letterTiger/article/details/81536104
<https://blog.csdn.net/letterTiger/article/details/81536104>

*
伪类和伪元素的区别?
https://segmentfault.com/a/1190000000484493
<https://segmentfault.com/a/1190000000484493>

*
写一个匹配邮箱的正则表达式?
/^[a-zA-Z0-9_.-][email protected][a-zA-Z0-9-]+(\.[a-zA-Z0-9-])*\.[a-zA-Z0-9]{2,6}$/
/^(\w)+(\.\w+)*@(\w)+((\.\w{2,3}){1,3})$/
*
js中null和undefined的区别是什么?
Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。
Null类型也只有一个值,即null。null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。从逻辑角度看,null值表示一个空对象指针

*
请列举几种确定js数据类型的方法?
1、typeof 可能的值为number, boolean, string, undefined, object, function
2、instanceof 后接可能的数据类型,如 Number,String,Object,Array,Date,Function,RegExp
3、使用constructor属性,例如obj.constructor === Array
4、使用prototype,例如Object.prototype.toString.call(a) === '[object String]')
https://www.cnblogs.com/dushao/p/5999563.html
<https://www.cnblogs.com/dushao/p/5999563.html>

*
webpack的工作流程是什么?
1、合并shell和webpack.config.js中的配置参数,并将其传入webpack对象的构造函数中,对应entry-option阶段
2、在构造函数内部会初始化compiler对象,其具有一个run方法,是webpack的实际入口。调用该方法,会构建出compilation
对象,该对象内部包含了每个构建环节和输出环节中所需要的方法,例如addEntry() , _addModuleChain() , buildModule() ,
seal() , createChunkAssets()等,对应compile阶段
3、通过调用addEntry() 方法,会根据Entry字段寻找入口js文件,并调用私有方法 _addModuleChain开始构建模块,对应make阶段
4、构建过程中利用各种loader整合资源,生成js module,利用acorn将js module转换为抽象语法树AST,并遍历AST,将
require() 中的模块通过 addDependency() 添加到数组中,当前模块构建完成后,webpack 调用
processModuleDependencies() 开始递归处理依赖的 module,对应build-module阶段
5、在所有模块及其依赖模块构建完成后,webpack 会监听 seal 事件调用各插件对构建后的结果进行封装,并逐次对每个 module 和 chunk
进行整理,生成编译后的源码,合并,拆分,生成 hash ,对应seal阶段
6、webpack 会调用 Compilation 中的 createChunkAssets
方法根据template进行打包后代码的生成,在此过程中会将源代码里的require()调用替换成webpack模块加载代码,对应emit阶段
。最后一步,webpack 调用 Compiler 中的emitAssets() ,按照 output 中的配置项将文件输出到了对应的 path 中,从而
webpack 整个打包过程结束。
https://github.com/youngwind/blog/issues/99
<https://github.com/youngwind/blog/issues/99>
https://www.jianshu.com/p/e24ed38d89fd <https://www.jianshu.com/p/e24ed38d89fd>
https://segmentfault.com/a/1190000006814420
<https://segmentfault.com/a/1190000006814420>
http://taobaofed.org/blog/2016/09/09/webpack-flow/
<http://taobaofed.org/blog/2016/09/09/webpack-flow/>
https://lihuanghe.github.io/2016/05/30/webpack-event.html
<https://lihuanghe.github.io/2016/05/30/webpack-event.html>


*
说说OSI 7层模型及各层的作用?

OSI模型,即开放式通信系统互联参考模型,是国际标准化组织提出的一个试图是各种计算机或者通信系统在世界范围内互联为网络的标准框架。整个模型分为七层,物理层,数据链路层,网络层,传输层,会话层,表示层,应用层。
https://blog.csdn.net/zhangyi_1027/article/details/80022493
<https://blog.csdn.net/zhangyi_1027/article/details/80022493>

*
说一下CSS中的BFC是什么?有什么用?
BFC即块状格式化上下文,BFC
是一个独立的布局环境,可以理解为一个容器,在这个容器中按照一定规则进行物品摆放,并且不会影响其它环境中的物品。如果一个元素符合触发 BFC 的条件,则 BFC
中的元素布局不受外部影响。
创建BFC的方法:浮动元素 、绝对定位元素、display值为 inline-block | flex | inline-flex |
table-cell 或 table-caption、overflow值为hidden,auto,scroll
用处:避免外边距折叠,包含浮动元素(防止高度塌陷),避免浮动元素覆盖(防止文字环绕)
https://segmentfault.com/a/1190000013647777
<https://segmentfault.com/a/1190000013647777>
https://www.cnblogs.com/chen-cong/p/7862832.html
<https://www.cnblogs.com/chen-cong/p/7862832.html>

其他工具相关

标签

归档

阅读排行