春招面试面经总结篇

news2024/7/6 20:26:46

目录

  • 前言
  • 一,算法篇
    • 1.1 平拍数组
    • 1.2 括号匹配
    • 1.3 打家劫舍
    • 1.4 删除最少使字符串平衡
    • 1.5 爬楼梯
  • 二,数据结构篇
    • 2.1 二叉树
    • 2.2 链表
  • 三,HTML篇
    • 3.1 H5新的语义标签
    • 3.2 href和src
  • 四,CSS篇
    • 4.1 居中
    • 4.2 父元素塌陷解决
    • 4.3 外边距塌陷
    • 4.4 CSS3盒子模型、怪异盒子模型
    • 4.5 CSS三角
    • 4.6 CSS响应式实现方法
    • 4.7 CSS预处理器
    • 4.8 CSS选择器和优先级
    • 4.9 CSS定位
    • 4.10 回流和重绘
    • 4.11 link和@import的区别
  • 五,js篇
    • 5.1 事件循环
    • 5.2 本地存储
    • 5.3 js的new发生了什么
    • 5.4 js改变this指向
    • 5.5 js原型链
    • 5.6 js实现防抖和节流
  • 六,计网篇
    • 6.1 http
    • 6.2 http1.0和http2.0区别
    • 6.3 http和https的区别
    • 6.4 强制缓存和协商缓存
    • 6.5 浏览器中输入一个url会发生什么
    • 6.6 post和get请求区别
    • 6.7 options请求--跨域预检
    • 6.8 跨域及解决跨域
    • 6.9 身份验证
    • 6.10 web攻击
    • 6.11 浏览器存储
    • 6.12 oAuth认证

前言

这是一篇关于春招的面试面经,涵盖了我整理的大部分面试考题。在春招结束后发出,希望能帮助到需要的朋友。

由于面试的题目会比较杂,这里不标注问题的来源,只给它们做一个简单的归类。分为以下几个部分:算法、HTML、CSS、JS、Vue、计算机网络、代码题目、性能优化、脚手架。

一,算法篇

算法,考的比较多的是动态规划,也有数据结构的应用。

1.1 平拍数组

// 平铺对象
let obj = {
        a: 1,
        b: 2,
        c: 3,
        d: {
            e: 4,
            f: 5
        }
    }
let showObject = (obj) => {
    for(let i in obj) {
        if(obj[i] instanceof Object) {
            showObject(obj[i])
        } else {
            console.log(obj[i])
        }
    }
}
showObject(obj)

// 平铺数组
let arr = [1, 2, 3, [4, 2, 4, [3, 3, 3]]]
let arr1 = []
let showArray = (array) => {
    array.forEach((item) => {
        if(Array.isArray(item)) {
            showArray(item)
        } else {
            arr1.push(item)
        }
    })
}
showArray(arr)
console.log(arr1)

1.2 括号匹配

let str = '({[]}}'
// 括号堆栈
let fn = (str) => {
    // 先转化为数组
    let arr = []
    arr = str.split('')
    // 设置一个堆栈
    let arr1 = []
    for(let i in arr) {
        arr1.push(arr[i])
        if((arr1[arr1.length - 1] == ')' && arr1[arr1.length - 2] == '(') || (arr1[arr1.length - 1] == ']' && arr1[arr1.length - 2] == '[') || (arr1[arr1.length - 1 ] == '}' && arr1[arr1.length - 2] == '{')) {
            arr1.pop()
            arr1.pop()
        }
    }
    console.log(arr1.length)
}
fn(str)

1.3 打家劫舍

var rob = function(nums) {
    let dp = []
    dp[0] = nums[0]
    dp[1] = Math.max(nums[0], nums[1])
    for(let i = 2; i < nums.length; i++) {
        dp[i] = Math.max(nums[i] + dp[i - 2], dp[i - 1] )
    }
    return dp[nums.length - 1]
};

1.4 删除最少使字符串平衡

var minimumDeletions = function (s) {
    let arr = s.split("")
    // 删除左侧B
    let leftB = 0
    // 删除右侧A
    let rightA = 0
    // 对应的删除次数
    let dp = []
    for (let i in arr) {
        if (arr[i] == 'b') leftB++
        if (arr[i] == 'a') rightA++
    }
    dp[0] = 0 + rightA
    dp[arr.length + 1] = leftB + 0
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] == 'a') {
            dp[i + 1] = dp[i] - 1
        } else {
            dp[i + 1] = dp[i] + 1
        }
    }
    dp.sort((a, b) => {
        return a - b
    })
    console.log(dp)
    return dp[0]
};
let s = "baababb"
minimumDeletions(s)

1.5 爬楼梯

var climbStairs = function (n) {
    let dp = [] // dp[i]为还剩几步时有几种情况
    dp[0] = 0
    dp[1] = 1
    dp[2] = 2
    if (n == 1) {
        console.log(dp[1])
        return dp[1]
    } else if (n == 2) {
        console.log(dp[2])
        return dp[2]
    } else {
        for(let i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2]
        }
        console.log(dp[n])
        return dp[n]
    }
}

climbStairs(5)

二,数据结构篇

2.1 二叉树

遍历二叉树

2.2 链表

三,HTML篇

3.1 H5新的语义标签

header-头部标签
nav-导航标签
content-内容标签
section-某个区域标签
aside-侧边栏标签
footer–尾部标签

3.2 href和src

href:超文本引用,用于建立文档与资源的联系,常用有link、a;
src:将所指向的资源下载并应用到当前页,常用的有script、img。

四,CSS篇

4.1 居中

1.水平居中:

        /* 采用auto */
        /* margin: 200px auto; */

        /* 作为父亲盒子在页面水平,也可以结合定位+平移 */
        /* position: relative;
        left: 50%;
        transform: translateX(-50%); */

        /* margin配合平移 */
        /* margin-left: 50%;
        transform: translateX(-50%); */

文字的水平居中还可以用到text-align: center

2.垂直居中

        /* position: absolute;
        top: 50%;
        transform: translateY(-50%); */

        /* 这个方法要注意,父亲需要解决高度塌陷的问题 */
        /* margin-top: 50%;
        transform: translateY(-50%); */

        /* flex */
        /* 父亲:justify-content:center */

        /* 行内元素为父亲高度 */
        /* line-height: 100px; */
        

3.水平垂直居中
达到样式:
在这里插入图片描述
方法一:父亲flex布局

        display: flex;
        flex-direction: column; 
        justify-content: center;
        align-items: center;

方法二:定位+位移

        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);

方法三:margin,这个方法父亲要防止高度塌陷

        /* position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%); */

4.2 父元素塌陷解决

前提:父元素高度由子元素撑开,当子元素设置浮动,父元素高度塌陷。

原因:子元素浮动,和父元素不在一个BFC中了(浮动的元素的z-index大于父),父元素不再被子元素撑开,高度又不固定,因此塌陷。

原:
在这里插入图片描述
塌陷:
在这里插入图片描述
解决方法:

1.给父元素设置高度,但是设置高度会导致,父亲不会随着子元素高度而扩大,不建议使用;

2.添加一个空的子元素,利用clear:both清楚浮动;或者给父元素加一个伪类元素,清除浮动;

3.给父元素添加overflow: hidden;

4.3 外边距塌陷

外边距塌陷一般是因为使用了margin,尽量使用padding即可避免。

解决方法:

1.给父元素设置透明边框;

2.尽可能使用padding+盒子模型;

3.给父元素使用overflow: hidden;

4.4 CSS3盒子模型、怪异盒子模型

box-sizing来控制,content-box是默认模式:

宽度 = padding + border + 元素本身宽度
高度 = padding + border + 元素本身高度

一旦设置box-sizing为===border-box=属性,则:

宽度 = 元素本身宽度
高度 = 元素本身高度

4.5 CSS三角

先画一个这样的正方形:
在这里插入图片描述
css代码:

    .sanjiao {
        width: 0;
        height: 0;
        border: 100px solid;
        border-color: orangered skyblue gold yellowgreen;
    }

如果要上三角:
在这里插入图片描述
加上这三句:

        border-top: 100px solid transparent;
        border-left: 100px solid transparent;
        border-right: 100px solid transparent;

想要什么就去掉其他,以此类推。需要注意的是,该元素的宽度应当设置为0

4.6 CSS响应式实现方法

1.媒体查询;
2.宽度百分比高度自适应;
3.vw,vh实现;(视口长度,视口宽度)
4.flex布局;
5.栅格布局,layout布局;
6.rem,em;(rem针对根元素,em针对父元素)

4.7 CSS预处理器

scss、less写法类似。

4.8 CSS选择器和优先级

继承(*)> 类选择器(伪类选择器)> id选择器 > 行内样式 > !important

4.9 CSS定位

relative-相对定位-相对于自己的原来位置-不脱标
absolute-绝对定位-无祖先则以浏览器,有祖先以最近一级为参考-脱标大于浮动

固定定位fixed和粘性对比sticky的比对
固定定位:相对于浏览器视口固定-脱标(会挡住文档,要预留空间)
粘性定位:没滚到边界时相当于fixed,滚到边界时相当于relative,相当于relative+fixed-不脱标(不会挡住文档,无需预留空间)

4.10 回流和重绘

重绘:重新绘画,给一个元素更换亚瑟、背景。不影响页面布局,但是颜色,背景变了,就会重新渲染页面;

回流:增加或删除DOM节点,改变页面布局,就会重新构造DOM。

关系:有回流就会有重绘,但有重绘不一定会有回流。

4.11 link和@import的区别

link可以在head中用,而@import是CSS固定的样式。

link会和页面同时加载,@import会等页面加载完再加载。

link支持使用JS去控制DOM改变样式,@import不支持。

五,js篇

5.1 事件循环

这里重要的是顺序,因为在面试中常考。

同步优先,异步时机到运行;
异步分为宏任务、微任务。微任务优先宏任务;

微任务种类:nextTick优先Promise
宏任务种类:setTimeout、setInterval、setImmediate

这里注意new Promise(()=<{})是构造函数,是同步的,但是.then是异步的,且setImmediate比其他定时器先执行。

5.2 本地存储

分为localStorage和sessionStorage。localStorage是永久的,除非手动删除;sessionStorage当浏览器删除其删除。

5.3 js的new发生了什么

创建一个空对象
把构造函数中的prototype单独拿出,创建一个对象,让新的对象的this指向这个单独拿出的原型对象;

5.4 js改变this指向

call: obj.fn.call(obj1, str1, str2…)
是把obj的fn方法的this指向改为了obj1,并以str1,str2作为fn的参数;(自动调用)

apply: obj.fn.apply(thisArg, [argsArr])
是把obj的fn方法的this指向改为了obj1,并以argsArr数组中的每一项作为参数;(自动调用)

bind: obj.fn.bind(obj1, str1, str2…)
是把obj的fn方法的this指向改为了obj1,并以str1,str2作为fn的参数;(手动调用)

5.5 js原型链

在这里插入图片描述

5.6 js实现防抖和节流

防抖:多次点击,仅响应最后一次;
节流:高频触发,规定时间内,只执行第一次

防抖实现:

    let btn = document.querySelector(".btn")
    let timeout = null
    btn.addEventListener("click", async () => {
        // 删除定时器
        clearTimeout(timeout)
        timeout = setTimeout(() => {
            alert("111")
        }, 1000)
    })

节流实现:

    // 节流,规定时间内,只触发第一次
    let btn1 = document.querySelector(".btn1")
    let flag = true
    btn1.addEventListener("click", () => {
        if(flag) {
            alert('222')
            flag = false
            setTimeout(() => {
                flag = true
            }, 1000)
        }
    })

六,计网篇

6.1 http

超文本传输协议,用于从服务器与浏览器通讯,是一种应用层协议,基于TPC/IP通信协议来传递数据;
HTTP1、HTTP2均为TCP实现;HTTP3基于UDP实现。

6.2 http1.0和http2.0区别

http1.0的每个请求都需要建立一个新的TCP连接,请求结束后立即关闭。而http2.0引入多路由服用技术,允许在同一个TCP连接上发送多个请求和响应;
头部压缩,http2.0压缩了请求头和响应头,加强了传输效率;
http2.0服务器可以在客户端请求之前主动推送相关资源,提高页面加载速度;

6.3 http和https的区别

1.https协议需要申请证书,需要花钱;
2.http是超文本协议,信息明文传输,https则会进行加密;
3.端口不一样;
4.http连接是无状态的,https协议是SSL+HTTP构建的加密传输,有身份认证和其他玩过协议,比http协议更安全;

6.4 强制缓存和协商缓存

强制缓存,由服务器去设置,仅针对get请求。缓存的内容放在客户端。如果下次发起请求,这个内容没有过期,则可以从客户端中直接拿到。

协商缓存,第一次请求资源,服务器会对返回的资源以及资源标识,下次请求时,比对资源标识,如若一致则返回状态码304,不用返回资源,如果不一致,则会返回资源和新的资源标识。

6.5 浏览器中输入一个url会发生什么

分两种情况

第一次请求url,会先判断客户端有没有缓存,因为没有,所以会发起get请求,但是在发起get请求之前,需要建立http连接,会先进行三次握手,确保服务器和客户端都能够正常收发内容。发起get请求,服务器返回数据,客户端接收数据之后想要关闭连接,这个时候会进行四次挥手,四次挥手结束,整个过程也随之结束,浏览器此时可以渲染页面。

如果有缓存,则也需要先建立其http连接,然后发起get请求。发起get请求后服务器会返回状态码304,不会给客户端返回数据,客户端从缓存中拿到数据,然后渲染页面。

6.6 post和get请求区别

1.用法上,get请求经常用于获取数据,post用于发送数据;
2.长度上,get请求对参数长度有一定限制,post请求用于发送请求;
3.安全性上,get请求一般会在url后携带请求参数,post请求的参数存储在body中。因此get请求会更加安全;
4.get请求的内容存在缓存(强制缓存和协商缓存),post请求没有;
5.get请求可以在历史记录中看到,post不行。

6.7 options请求–跨域预检

在发起一个需要跨域的请求时,服务器会先向浏览器发起一个跨域预检请求。如果服务器支持跨域请求,则会接着发起get或者post请求(发起正式的http连接),如果不支持,则cors会返回失败。

6.8 跨域及解决跨域

说起跨域,就要聊到同源策略。同源策略,针对于两个url源,说的详细些,可以用于浏览器和服务器在发起请求之前的规则统一。

同源策略:两个url,如果它们的id,域名,端口号相同,则称它们同源;其中一个不同,则不同源。

浏览器向服务器发起请求,服务器传输数据给浏览器,要遵循同源策略。如果不遵循,则会跨域。

接下来介绍跨域请求的解决方式和其中的原理。

方式一:Jsonp。jsonp利用的是,script标签可以不遵循同源策略获取外部资源,只能用作前端的get请求。

方式二:cors。这个就需要前端去联系后端,后端设置服务器的响应头解决问题;

方式三:proxy正向代理。在前端创建一个虚拟服务器,其域名各方面跟前端保持一致。因为同源策略只针对浏览器,不针对服务器,服务器与服务器之间是可以直接发送信息。因此前端发起请求,与自己的服务器对接(不存在跨域),正向虚拟服务器与后端服务器对接(不遵循跨域),拿到请求后,代理服务器再传回数据,解决跨域;

方法四:Nginx反向代理,与正向原理类似。

6.9 身份验证

身份验证的三大块:session、cookie、token。

都用于维持用户登录状态信息。

一般情况下,用户第一次登陆网站,网站会为其开辟一个session空间,并给用户传回信息session_id。用户存储在浏览器的cookie中,下次登陆携带session_id,服务器拿到之后会进行比对,找到属于用户的session空间。

经常会考,session和cookie的区别:
1.session存储在服务器中,而cookie存储在浏览器中;
2.cookie的存储大小有一定限制,而session的存储空间相对较大;
3.cookie因为存储在浏览器中,可以通过抓包等手段获取,安全性不如session。

token的好处:
1.cookie不允许跨域访问,token可以;
2.token在服务端不需要存储session机制,因为token包含了所有登陆用户的信息,只需要在客户端的cookie或者本地存储状态信息;

6.10 web攻击

1.xss攻击
恶意穿插链接,点击该链接,加载脚本文件,可能会出现token和cookie等信息的泄漏;(反射型)
访问某个链接时,携带自身的cookie和token,传给后端。(存储型)

2.csrf攻击
用户登陆信任网站,新人网站返回session_id并产生cookie在用户的浏览器中;
用户在没有退出A的情况下,访问危险网站B。B要求访问第三方站点A,发起一个请求。而这个请求,会携带着原本的cookie。A接收到了cookie,根据用户请求达成协议,

6.11 浏览器存储

分为localStorage(永久存储)和sessionStorage(短暂存储)。两者使用方法类似,不过sessionStorage仅在当前会话下有效,关闭页面或者浏览器后被清楚。

6.12 oAuth认证

分为四种:
授权码认证、客户端认证、密码认证、隐式授权认证、刷新密钥。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1857587.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于SpringBoot的实习管理系统设计与实现

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; SpringBoot框架&#xff0c;B/S模式 工具&#xff1a; MyEclipse&#xff0c;Tomcat 系统展示 …

dockercompose部署redis哨兵模式并集成springboot

第一步 编写compose文件 docker-compose.yml version: 3.8networks:redis-network:driver: bridgeservices:redis-master:image: redis:7.2.4container_name: redis-mastercommand: ["sh", "-c", "redis-server --protected-mode no --slave-announ…

WSL安装的Ubuntu与docker desktop集成

WSL安装的Ubuntu与docker desktop集成 最近因为项目需要&#xff0c;要在本地利用WSL搭建一个docker和Ubuntu的部署环境。一开始并不知道docker desktop与Ubuntu可以集成使用&#xff0c;所以在Ubuntu上独立安装了docker引擎&#xff0c;但在安装docker-compose的时候出现以下…

av1支持的CU划分

av1只有4叉划分支持递归划分 只有四叉允许递归划分&#xff0c;其余划分只划分到本层。最大编码单元也扩展到128x128&#xff0c;最小编码单元4x4。

“流处理引擎” RisingWave 的三种经典交互方式

作为流数据库&#xff0c;RisingWave 在大数据生态中通常扮演着流处理引擎的角色。它从各种数据源读取数据&#xff0c;并将其写入不同的目的地。在此过程中&#xff0c;RisingWave 清洗、转换和聚合数据&#xff0c;最终得出计算的结果。 RisingWave 为用户提供了丰富的交互和…

flask-socket的实践

1.长连接和短连接的由来 1&#xff09;TCP在真正的读写操作之前&#xff0c;server与client之间必须建立一个连接&#xff0c; 当读写操作完成后&#xff0c;双方不再需要这个连接时它们可以释放这个连接&#xff0c; 连接的建立通过三次握手&#xff0c;释放则需要四次握手…

哪种无线麦克风比较好?一文读懂什么品牌的无线麦克风比较好!

​在这个信息爆炸的时代&#xff0c;网络直播和短视频成为了人们获取信息、娱乐和社交的重要方式。作为自媒体人&#xff0c;拥有一款优秀的领夹式无线麦克风是必不可少的。它不仅能够帮助你在各种环境中保持清晰的声音&#xff0c;还能提升你的作品质量和专业度。然而&#xf…

中霖教育:二级建造师报名后缺考有影响吗?

在完成二级建造师的报名程序后&#xff0c;考生无法进行退考。如果是不参加考试&#xff0c;可以选择弃考。弃考对个人并没有负面影响&#xff0c;缺席考试的话也不会被记录在个人诚信档案中。当然&#xff0c;如果弃考的话此次考试的成绩将被记为0&#xff0c;下一年参加考试按…

极验行为式验证码适配Harmony 鸿蒙SDK下载

现阶段&#xff0c;越来越多的开发者正在积极加入鸿蒙生态系统。随着更多开发者的参与&#xff0c;早在去年9月&#xff0c;极验就成为首批拥有鸿蒙NEXT内测版本和手机系统测试机会的验证码供应商。 为了提高各开发者及企业客户集成鸿蒙版本行为验4.0的效率&#xff0c;方便大家…

CodeFuse 开源官网上线啦~

Hello ! 这里是 CodeFuse ~ CodeFuse 的使命是开发专门设计用于支持整个软件开发生命周期的大型代码语言模型&#xff08;Code LLMs&#xff09;&#xff0c;涵盖设计、需求、编码、测试、部署、运维等关键阶段。我们致力于打造创新的解决方案&#xff0c;让软件开发者们在研发…

web开发学习(web简单入门)

前言&#xff1a; 从我刚接触博客没多久我就萌发了搭建一个个人博客网站的想法&#xff08;用来装逼&#xff09;&#xff0c;但碍于学校屁事太多迟迟没有开始&#xff0c;最近学校课已经都差不多结课了&#xff0c;距离期末还有一段时间&#xff0c;我也得以抽出时间来学习我一…

设计模式原则——迪米特法则原则

设计模式原则 设计模式示例代码库地址&#xff1a; https://gitee.com/Jasonpupil/designPatterns 迪米特法则原则&#xff1a; 意义在于降低类之间的耦合。由于每个对象尽量减少对于其他对象的了解&#xff0c;因此&#xff0c;很容易使得系统的功能模块功能独立&#xff…

【产品经理】订单处理8-智能分仓

在电商ERP系统中&#xff0c;通常智能分仓策略是系统中最重要的功能之一&#xff0c;大公司若仓库较多时&#xff0c;智能分仓策略中也会加入大数据团队&#xff0c;通过算法来计算最优仓库。 本次讲解的智能分仓适用于中小公司&#xff0c;适合拥有2个以上10个以下仓库的公司…

『FPGA通信接口』LVDS接口(2)硬件设计

文章目录 1.LVDS原理2.xilinx器件对于LVDS的支持3.LVDS信号PCB布线要求4.传送门 1.LVDS原理 如上图所LVDS的工作原理示意图&#xff0c;其Driver驱动器由一个恒流源是LVDS发送端&#xff08;通常为 3.5mA&#xff09;驱动一对差分信号线组成。驱动状态会翻转就产生正负电压的变…

【分布式事务】分布式事务理论

CAP 理论 一致性&#xff08;Consistency&#xff09; 分布式系统中所有数据备份&#xff0c;在同一时刻是否是同样的值 可用性&#xff08;Availability&#xff09; 集群中一部分节点故障后&#xff0c;集群整体是否还能响应客户端的读写请求 分区容错性&#xff08;Partit…

【机器学习 复习】第5章 朴素贝叶斯分类器

一、概念 1.贝叶斯定理&#xff1a; &#xff08;1&#xff09;就是“某个特征”属于“某种东西”的概率&#xff0c;公式就是最下面那个公式。 2.朴素贝叶斯算法概述 &#xff08;1&#xff09;是为数不多的基于概率论的分类算法&#xff0c;即通过考虑特征概率来预测分类。 …

数字化转型中的数据资产价值发现之旅:通过深度挖掘与分析,释放数据资产的巨大潜力,为企业开拓更多商业机会,引领业务创新与发展

一、引言 随着信息技术的飞速发展&#xff0c;数字化转型已成为企业不可逆转的趋势。在这一转型过程中&#xff0c;数据资产作为核心驱动力&#xff0c;正逐渐展现出其巨大的商业价值。然而&#xff0c;如何有效挖掘和利用这些数据资产&#xff0c;将其转化为实际的生产力和创…

高位图像的增强处理 DR图像等

输入16位图像 经过增强算法处理后的输出&#xff1a;

vscode使用内置插件断点调试vue2项目

1、首先项目中要开启source-map 在vue.config.js 文件中 module.exports {configureWebpack: {devtool: process.env.NODE_ENV ! "production" ? "source-map" : ,} }2、项目根目录新建.vscode/launch.js文件 {"configurations": [{"ty…

五、在Qt下加载QVTKWidget控件(VTK8.2.0),生成Visual Studio项目,显示点云(C++)

前言&#xff1a;因为项目需要通过Qt进行显示点云&#xff0c;参考了很多博文&#xff0c;但是并没有全部正确的&#xff0c;东拼西凑算是实现了&#xff0c;花费了两天时间&#xff0c;时间有点久&#xff0c;能力还有有待提升~~ 为此写篇博文记录一下。感谢各位大佬&#xff…