# 面经——纷享销客

# 前言

首先……

写面经的目的,实际上倒不是分享什么面试经验,反而是总结这次面试的一些见闻,以及更多地记录本次面试遇到的问题和自我总结。

因为是第一次面试,所以还是比较的……没什么经验吧(不算什么各种面试社团之类的活的话)

可能描述的过程有点偏差,但是内容大体上应该不会偏差太多

# 简述

面试公司:纷享销客

面试岗位:前端开发实习岗

面试流程:一面技术面、二面(应该是二面……也应该是算技术面?)、三面

小吐槽:

一面的技术大佬长得又帅、声音又柔和好听、而且看着很年轻……这就是人生赢家

二面应该是主管之类的……可能也是技术大佬,没有自我介绍所以不清楚是什么岗位……但是看着也感觉好强

整个面试的内容感觉还是比较充实的,算下来好像也就一个小时左右……

# 面试前

在BOSS上找到的公司,我现在发现了个经验……就是……HR挂着的招聘……基本沟通都是已读不会……然后工程师挂着的招聘……一沟通立马回话……

所以我觉得找工作应该可以优先考虑先沟通那些工程师挂着的岗位

当然这种岗位应该都会要求尽快到岗。

之前发过一份简历,然后没有通过,问了下原因——没有项目经验,然后询问了项目的定义、范围,大佬也是很耐心做了反馈,半成品、较小的项目也是可以写进项目经验的,但是最好还是要有完成的项目产出,便问了过几天修改简历之后,该岗位还在招聘的话能否再投,得到了同意,便做了一下简历的修改,再次投递。

再次投递的那个下午……很快啊,问我要不要去面试,然后很快啊,说当天晚上吧。

然后算了下时间,过去应该来得及,不过可能比较赶了。

修改了下时间改了第二天的下午两点半。

实际上因为也比较突然,再加上我个人在学习上的理念是“在战争中学习战争”,所以很少看所谓“面试题”和“面经”,基本上也就看文档、翻github、翻B站看教程,所以在这些内容的准备上,应该是挺不足的。

面试当天因为怕迷路或者通勤塞车之类的,加上先熟悉环境,下午两点半开始的面试,从十一点四十出发接近两个小时的路程,一点半左右就先到了。

我觉得也应该这样,提前一些时间到达面试地点,时间比较充足,不会太匆忙,安排好自己的时间

不过就是从龙岗到南山这趟路……真的累……

等大佬回消息,就在楼下逛了逛,然后就接到消息上去面试。

一开始递简历,做了下自我介绍,常规开局讲了一些自己的基本信息。

# 关于项目

开始说了一些关于项目的事情。

简历上的项目经验写了两个项目,都写了github仓库、githubPage链接和文档地址,做了一些简单的描述,占了半页纸……

在各种吃教训、吃瘪、踩雷的情况下,把文档写的挺多,写的挺长,被夸了,有点高兴

(然后依旧吃瘪)

然后就这个文档谈到了“写文档的目的”,我就说明了两个项目的文档编写的情况。

“第一个项目的文档是只写了初步的设计做个大概然后就开始开发,因为这样子所以导致了很多偏差以及错误,吃了很多教训,之后是边开发边补文档的。所以第二个项目写文档的时候就做了比较详细的规划和设计,包括数据方面的、结构方面的,都先做了设计然后才进行开发,虽然途中也有偏差……”

接着问了一些项目的开发情况,其中第一个项目是一个类似于论坛、用于分享文件、资料的网站,然后我说明了这个网站一个是因为有点大,一个是可能会有版权的问题,所以暂时处于停摆的个人练习项目的状态,然后就问了:现在要开发好这个网站版权问题要怎么解决

这一点我我在做项目的时候也有思考过,关于版权方面的问题,在用户上传文件的时候,需要进行审核,检查文件是否有版权问题、著作权问题,是否为用户原创等,如果有著作权问题的,退回或者和著作权持有者沟通等。我觉得算是比较一般的思路吧,央妈那种大企直接版权库

然后另外一个项目是一个升级版的待办事项toDoList,界面和功能做了丰富,因为没有后端的原因,所以采用的是本地存储 localStorage

各种被矫正英语发音感觉失分点最大的怕是这个

然后就问了 localStorage 的特点,我回答了一个可以长久存储,然后大佬问了“在其他页面能不能调出这个内容

我想起我在写项目的过程中,使用的是本地服务器开启页面,在打包之后直接是用本地打开,然后是部署到github page上,在本地服务器打开的项目保存的数据并没有在 本地打开的项目或者在github page中被调用,所以便回答了“不能被调出来”

然后就引申出了跨域的问题,localStorage的数据调用不能跨域。

谈谈对跨域的理解。

标准答案:当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

我的回答:写了两个网址——百度和163,划了两条横线,“百度和163域名不一致,跨域”……虽然很口语化,但是我感觉这个理解不算错【扶额

我也补充了关于这个项目之后的计划——开发后端,能够进行账号登陆和云同步的功能

总结来说

面试官确实会根据项目去问的,面试官直接打开了我提供的项目的地址看的。

所以在写上项目经验的时候,一定要确保所做的描述能够匹配自己确实开发的内容,以及对自己项目所使用的技术和一些细节足够了解。

要能够描述自己在开发项目中所开发的内容、经验、思路、构思等内容

有文档方面的内容,我感觉应该是加分项

中止线

先写到这……已经很晚了,先休息,起来再继续补充……

现在已经是凌晨2:40了……阴间作息人……可以……很程序猿

睡个觉,恰个饭,我们继续写

项目方面大概讲了二十分钟左右,会问一些关于项目的情况,如实回答了之后,进入面试题阶段

# 面试题

这里先列一个知识点清单,方便各位整理一下思路,这个清单没有顺序,因为我也忘了问的先后顺序,欸嘿

  1. 数组方法
  2. 数据类型
  3. 原型与原型链
  4. 异步请求
  5. http协议
  6. 盒模型、怪异盒模型
  7. CSS单位
  8. 响应式
  9. 垂直水平居中
  10. git
  11. 简述Vue——MVVM
  12. 双向绑定

实际上我觉得我面试题答得稀烂,不怎么看面试题和不怎么记概念吃了巨亏

而且很多题目我想复杂了,当然我觉得这也没办法,紧张的时候日常忘知识点

# 1.数组方法

题目:在一个长度为100的数组中,以无序的方式,存储1~100,现需要删除50,并返回一个长度为99的数组

当时的解题思路:(特别傻……)

先是看到数组,看到无序找到50。

学过算法的同学们告诉我……这三个关键字放一起……很难不拒绝快速排序以及二分查找法带来的神奇脑回路……

然后我就直接开始分治法了。

然后面试官:“没那么复杂……

然后我:“……”

然后我就被打断施法,随便想了一下……先是通过some()判断50的存在,然后获取索引值,for循环遍历把50之后的往前套,然后pop()出栈掉最后一个元素。

但是这个思路出了个致命错误,就是ES5的方法 some() 返回的是布尔值,不是索引,虽然可以传参获取索引值,但是这个方法显然不适用,而通过for循环把50之后的元素往前挨个套,和pop()出栈的思路是没有问题的……当且仅当只有这个方法的情况下

因为JS中有特别方便的方法,以至于这道题只需要一句

不过我还是在面试之后,顺着我的那个思考,完善了一下(然而并没有任何卵用的东西)

// 因为长度100太长了,这里就缩略为10
let arr = [3, 6, 4, 1, 2, 5, 7, 9, 8, 10]
let arr2 = arr
for (i = 0; i < 10; i++) {
	console.log(i)
	if (arr3[i] === 5) {
		getArr(i)
		break
	}
}

function getArr(index) {
	for (let i = index; i < 10 - 1; i++) {
		arr2[i] = arr2[i + 1]
	}
	arr2.pop()
}
console.log(arr2)

// 这是我当时的思路,描述上出了大毛病
// 时间复杂度恒定 O(n)
// 当然,这个方法很暴力破解直接了当,一点也不优雅

面试官提示下的答案:

let arr = [3,6,4,1,2,5,7,9,8,10]
let arr2 = arr
arr2.splice(arr2.indexOf(5), 1)
console.log(arr2)
// 使用了slice删除元素,通过indexOf获取元素索引
// 实际上我是因为只记住了indexOf可以用于匹配字符串
// 而忘记了字符串也算是数组,该方法也可以用来匹配数组元素
// slice()我也用的少,所以没记住,但是提醒了之后我才想起这个方法
// 然后也想起我的项目也可以用上这个方法,可谓是非常优雅的写法

// 但是,出于一开始抱着算法解题的思路
// 所以我去查了一下 indexOf() 和 splice() 这两个方法的时间复杂度
// 当然,这种经过时间考验的方法一般都十分优秀
// 然后……查了源码,发现思路基本一致……
// 核算下来时间复杂度也是O(n)
// 合计着我已经是在写源码了【?

# 2.数据类型

问题:JavaScript中的数据类型有哪些?

我的回答:Number、String、Object、Boolean、undefined、NaN(错误)

因为把NaN和null记混了,我当时还是直接评了NaN,傻了……


问题:ES6新增了哪些数据类型呢?

我没有答上来,实际上我也不清楚ES6新增了什么数据类型

虽说知道有个symbol,但是不确定是不是啊……

答案:

  • Symbol
  • Set
  • Map
  • WeakSet
  • WeakMap
  • TypedArray

问题:引用类型数据是怎样的一个数据,会有什么影响?

实际上比起 引用类型数据 ,我个人是用 传址调用数据 来称呼的,这个称呼应该是出自C语言……

也正如我的称呼,传址调用,传的是什么,是地址哒!

和传值数据不同,传值数据传的的是它的数据而传址传的是它的引用地址

let a = 10;
let b = a;	// 这里是将 a 的值 赋值给 b
let obj = {
	name: '张三'
}
let obj2 = obj	// 这里是将obj的引用地址,传给obj2

传的引用地址会有什么影响?

obj2.name = '罗翔'
console.log(obj.name)
// 结果是什么?是'罗翔'
// 因为obj2获得的,是obj的引用地址
// 修改obj2的属性,也会修改到obj,因为二者的地址是一致的
// 这就是引用类型数据会造成的影响

当然,这个影响可以反向利用,来提高我们的代码可读性

// 假设我们现在有这么一个对象
// 修改自我的一个项目
mattersList = {
    userID: 0,
    classifications: [
        {
            label: '是不是有点晕了?',
            matters: [
                {
                    label: '还不够呢!好吧,到这差不多了'
                }
            ]
        }
    ]
}
// 实际上这种写法会被打死2333
// 当然也会有这种对象+数组互相嵌套的情况,用来作为表示列表等用法
// 现在我们要进行修改……
mattersList.classifications[0].matters[0].label = "太长了"
// 很长,很难读
// 所以……
const classification = mattersList.classifications[0]
classification.matters[0].label = '1'
classification.matters[1].label = '2'
// 诸如此类,直接简化

# 3.原型与原型链

问题:关于Js中的原型与原型链,你是怎样理解的

这个问题问的比较的广……我觉得,描述起来也有点麻烦,主要还是考核理解?

我是直接拟定了一个对象,然后画了一个原型链,主要起到一个继承的作用

原型是什么?——一个对象,称prototype为原型对象

原型的作用是什么?——共享方法

构造函数通过原型分配的函数 是所有对象所共享的

JavaScript规定,每一个构造函数都有一个prototype属性,指向另一个对象。

关于这个知识点,可以查看以下两个文档

🔗 5.构造函数和原型

🔗 原型与原型链

# 4.异步请求

这个问题提出来的有点突然,如果没记错的话是根据我的项目提出的。

提到了使用什么发送请求的方法

我回答了用axios

然后提问了:“为什么现在都用第三方库第三方工具来发送异步请求?有没有尝试过使用原生的方法进行发送?”

关于第一个问题我是不清楚的,面试官也没有给出答案。

第二个问题我也是懵的,没有回答,而且本身我很少写到与后端的交互,所以这些内容我很少用到

后来翻文档才发现,我学AJAX那些东西的时候写的那些部分算是原生方法发送请求了……

关于AJAX的学习,可以看到以下文档:

🔗 学习资料——AJAX

# 5.http协议

问题:后端往往需要获取到用户的信息,需要通过怎样的方式获取?

回答:post

正确答案: cookie

post的信息在控制台中也能够看到,所以存在安全隐患,cookie更加安全一些

(主要是我当时只想起get和post……)

# 6.盒模型、怪异盒模型

div{
    width: 100%;
    padding: 30px;
}

请问这个div的情况是怎样?

这道题我在答的时候,和圣杯布局搞混了,所以答的是塌缩

但实际上是我把圣杯布局记错了……对于这个盒模型的知识点没记错【扶额

【说白了想复杂了

正确答案是:扩展

因为在标准的盒模型中,width只是内容区,而不包括padding、border、margin

因为padding:30px,是在原本width:100%的基础上,四周撑开元素30px

同时这道题也考察了如果是怪异盒模型,会怎么样?

怪异盒模型,也称IE盒模型,通过box-sizing:border-box设置

其 width 指的是:content + padding + border

如果是怪异盒模型,则该div的内容区会塌缩

# 7.CSS单位

问题:在CSS中有哪些单位?

答:px、rem、em、vh、vw、百分比

实际上除了上述这几者,还有cm、mm、in、pt、pc、ex、ch、vmin、vmax

不过可能用的比较少……

问:px是怎样一个定义?

答:像素


问:rem是怎样的一个定义?

答:相对于根元素的字体大小


问:那rem是不是固定的?

答:不是,平时情况下1rem可能 = 14px,但是根据设备不同,1rem的值也会不一样


问:这种设计的目的是什么?

答:在不同的设备上,元素以不同的大小显示,能够使得网页适配不同的设备,起到响应式布局的作用

(大概也是这个意思,然后就从这个问题引出下一个问题)

# 8.响应式

问:除了刚刚说到的rem之外,还有什么可以进行响应式布局的?

答:vw和vh,以及百分比,这三个我都用得比较多

vw是指相对视口宽度的1%

vh是指相对视口高度的1%

问:你说到百分比用的多,那你开发的时候是开着浏览器然后按照感觉调百分比还是……?

答:较大的组件我一般都会先画一个大体的设计图,然后算好比例之后直接得到百分比值,比较小的组件我就是凭着感觉微调

问:那除了刚刚说的这些单位,CSS还有什么能够支持响应式?

答:媒体监听 @media(实际上得叫媒体查询……)

使用 @media 查询,可以针对不同媒体类型定义不同的样式,从而起到响应式布局的效果

# 9.垂直水平居中

这个问题我答得比较模糊……没记住

1.定位

/* 已知宽高 */
.center {
    width: 100px;
    height: 100px;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}
/* 或 */
.center {
    width: 100px;
    height: 100px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -50px 0 0 -50px
}

/* 宽高未知 */
.center {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%)
}

2.flex布局

<div class="wrap">
    <div class="item">test</div>
</div>
.warp {
    width: 100%;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}
.item: {

}

3.使用伪类

<div class="wrap">
    <div class="item">test</div>
</div>
.warp {
    width: 100%;
    height: 100%;
    text-align: center;
    position: absolute;
    top: 0;
    left: 0;
}
.warp::after{
    display: inline-block;
    content: '';
    width: 0;
    height: 100%;
    vertical-align: middle;
}
.item {
    display: inline-block;
    vertical-align: middle;
}

4.使用表格

<div class="warp">
    <div class="item">test</div>
</div>
.warp {
    width: 100%;
    height: 100vh;
    display: table;
}
.item {
    display: table-cell;
    vertical-align: middle;
    text-align: center;
}

# 10.git

关于git的使用问的很少,甚至不能算是有问什么东西。

不是询问了有没有使用过版本管理工具,以及有没有多人合作使用过

# 11.Vue——MVVM

问:你的两个项目,都是基于Vue开发的,Vue是一个什么样的框架

答: MVVM--Model、View、ViewModel

Model与View并没有直接的练习,而是通过ViewModel进行交互。

Model和ViewModel之间的交互式双向的,因此View数据的变化会同步到Model中,而Model数据的变化,也会立即反应到View上。

ViewModel通过双向绑定把View层和Model层链接起来,而View和Model之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM,不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM来统一管理。

# 12.双向绑定

问:那能否通过原生JS的方式,写一个双向绑定

这道题我没有答出来,我只是说了一个很模糊的概念

似乎有一个方法是 Object.defineProperty() 可以用于实现双向绑定

这个方法是用来定义一个新属性或者修改一个对象的现有属性,并返回这个对象?

这个我需要回头仔细研究一下

总结

总的来说……问的都非常基础……

以至于一不小心想复杂了就和原题偏差太远

当然一大原因也在于自己不怎么看面试题和概念,很多时候都是用到某个方法的时候再现场查文档……

答得马马虎虎,有的答得很偏【扶额

面试题看点比较好……以及不要把问题想太复杂,然后按照题意想到什么方法解题是最好的。

# 二面

二面的内容比较一般,主要是问学习和学校方面的事项,没有太多要点……

# 三面

三面是电话面,据说是HR去北京出差了。

打了电话过来,讲了公司的情况。

没有太多的其他事项,也就询问了能够到职的时间,没有其他。

我问了一些有关薪酬和福利,以及上班时间之类的内容……

本科生日薪200,八小时弹性工时,HR说不怎么加班,不让实习生加班……

双休,只有晚餐,没有住房补贴……

实际上算下来,一个月的基础薪酬是4400.比我预期的低了些……

嘛……且看……

更新时间: 7/8/2021, 1:01:08 AM