春招面试面经总结篇

前言

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

由于面试的题目会比较杂,这里不标注问题的来源,只给它们做一个简单的归类。分为以下几个部分:算法、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认证

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值