11

看哭了!一个前端自学者从面试被吊打,到拿 offer 的心路历程

 3 years ago
source link: https://zhuanlan.zhihu.com/p/359006330
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

看哭了!一个前端自学者从面试被吊打,到拿 offer 的心路历程

关注微信公众号:web前端学习圈,领取85G前端全套系统教程

1. 前言

先交代下博主是在二线城市,所以也面不了什么大厂自然也就没什么大厂面经(就算有我也没有这个实力),昨天面试了一家中小型的公司,这里就不透露名字了,总共面了两轮总结后写下了这篇文章,我相信也是有很多和我在二线城市的小伙伴需要这些常见的面试题的,我是刚毕业出来实习,所以马上要出去找实习的小伙伴可以看看,参考下。

2. 面试之前准备什么?

老实说,我面这家公司的时候之前没有复习!早上第一面,下午就通知第二面了,几乎是裸面的状态(当然过程也非常惨)。

所以建议大家如果准备面试的话,还是需要提前复习下,做好准备,时间方面自己把握下,建议一周内就行了,主要把写在简历上的项目搞透,从项目的结构、所用到的技术、难点、亮点都要知道,要能够自己描述出项目中用了哪些,自己完成了哪些。

  1. 刷面经 看一看最近的面经文,了解现在公司都在面什么类型的题,准备一些常见题,自己背一背。
  2. 项目 把你写在简历上的的项目从技术架构到源码都要做到足够了解,至少面试的时候不要被面试官问住了。
  3. 亮点 准备一些自己的亮点,因为面试的问题你不可能每个都回答上来,但是在面试的过程中一定要有亮点,不然问你的一些问题都是回答的一般般,让面试官感觉不到你那方面比较擅长(你就会得到反馈,面试官说你还行,但是没有过~), 你可以准备几个点,每个点都保证可以吹上个半小时。另外一定要了解的很深入,一定要能够流畅的表达出来!
  4. 练手 先找几家不太想去的公司(规模差不多但离你住的地方比较远等等原因。。)练练手,如果第一次面试就去心仪的公司面试,淘汰率会非常高。特别是实习生还没有面试过的,建议多面几家再去综合考虑去哪家,我见过太多我身边的朋友因为毕业着急找工作随便投简历,面试通过了就入职了,干了一两周就说不想去了,跑路又重新找,这样的话其实非常得不偿失,时间也花了也没找到心仪的工作。
  5. 心态 最后就是你的心态了,心态很重要!!!面试不过很正常,不证明你不优秀,只是不适合,总结面试经验,为下一次做准备。像我第一次面的第一家公司问的很多问题都回答不上来,boss上写的招实习生,最后面试我的人尽问一些奇葩问题,前端不需要写页面,后端也不需要写接口,最后说公司需要中级前端,我目前只能是个初级前端,不符合公司要求。我就纳闷了招中级前端写招聘实习生???整个面试下来10分钟不到,到时我都快气炸了。也有点影响后面的面试,所以一定要有个好的心态面对面试结果。

3. 还能记住的面试题

方便读者阅读我将面试题进行了个分类,这篇主要写跟vue和项目相关的面试题,因为我简历上写了三个项目,所以大部问题都是从项目开始切入的,有些记不住,回答的也不是太好。。。我会把网上的详细文章贴出来,让读者能更详细的学习。

vue相关

  1. Vue实例的生命周期讲一下, mounted阶段真实DOM存在了嘛?

Vue实例从创建到销毁的过程,就是生命周期。

也就是:开始创建->初始化数据->编译模板->挂载dom->数据更新重新渲染虚拟 dom->最后销毁。这一系列的过程就是vue的生命周期。所以在mounted阶段真实的DOM就已经存在了。

  • beforeCreate:vue实例的挂载元素el和数据对象data都还没有进行初始化,还是一个 undefined状态
  • created: 此时vue实例的数据对象data已经有了,可以访问里面的数据和方法, el还没有,也没有挂载dom
  • beforeMount: 在这里vue实例的元素el和数据对象都有了,只不过在挂载之前还是虚拟的dom节点
  • mounted: vue实例已经挂在到真实的dom上,可以通过对 dom操作来获取dom节点
  • beforeUpdate: 响应式数据更新时调用,发生在虚拟dom打补丁之前,适合在更新之前访问现有的 dom,比如手动移除已添加的事件监听器
  • updated: 虚拟dom重新渲染和打补丁之后调用,组成新的 dom已经更新,避免在这个钩子函数中操作数据,防止死循环。
  • beforeDestory: vue实例在销毁前调用,在这里还可以使用,通过this也能访问到实例,可以在这里对一些不用的定时器进行清除,解绑事件。
  • destoryed:vue实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁。
  1. Vue中的的通信方式有几种?隔代组件的通信你用那种方式解决?

总共有7种,当时是只回答了4种

  • props/$emit 适用父子组件通信
  • ref与parent/children适用父子组件通信
  • EventBus(事件总线) 适用于父子、隔代、兄弟组件通信
  • attrs/listeners 适用于隔代组件通信
  • provide/inject 适用于隔代组件通信
  • vuex 适用于父子、隔代、兄弟组件通信
  • slot插槽方式

参考这篇文章

  1. Vue中的常见指令有那些??

v-text/v-html/v-for/v-show/v-if/v-else/v-cloak/v-bind/v-on/v-model/v-slot...

vue的指令还是得都记住的,这里是按照我的记忆方式排列的,大家可以有自己的记忆方式。

参考vue文档

  1. v-show和v-if有什么区别??

v-show是css切换,v-if是完整的销毁和重新创建,如果频繁切换时用v-show,运行时较少改变用v-if

  1. 谈谈你对vuex的理解?

vuex是一个专门为vue.js开发的状态管理模式,每一个vuex应用核心就是store(仓库)。store基本上就是一个容器,它包含着你的应用中大部分的state(状态)

  • vuex的状态存储是响应式的,当 vue组件中store中读取状态时候,若store中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  • 改变store中的状态的唯一途径就是显示 commit(提交)mutation,这样使得我们可以方便地跟踪每一个状态的变化。

主要有以下几个模块:

  • State: 定义了应用状态的数据结构,可以在这里设置默认的初始状态
  • Getter: 允许组件从Stroe中获取数据, mapGetters辅助函数仅仅是将store中的getter映射到计算属性。
  • Mutation: 唯一更改store中状态的方法,且必须是同步函数。
  • Action: 用于提交muatation, 而不是直接变更状态,可以包含任意异步操作。
  • Module: 允许将单一的store拆分为多个 sotre且同时保存在单一的状态树中
  1. vuex中state存储的数据如果页面刷新此时数据还会有吗?

当时没想清楚就回答了有,面试官说没有让我回去可以试一下,其实过后我就知道是没有了,在项目中有遇到过这个问题。。。

项目地址:高仿小米商城,github地址感兴趣的朋友可以clone下来学习下,如果感觉不错的话可以欢迎大家点个start。

在这个项目中我用到了vuex来管理用户名和购物车数量,当时我的设想是用户即使没有登录也可以访问首页,当用户将商品加入购物车再让用户跳转到登录页,所以就存在这么一个问题,当用户登录之后我通过vuex来存储用户名和购物车数量,当用户跳转其他页面再回到首页的时候此时vuex中state中的数据已经没有了导致用户名和购物车数量都为空,当时的解决方案是在app.vue中 mounted这个钩子通过cookie中有没有存储用户的id来判断用户是否登录,如果登录重新发送请求再通过dispatch触发 action来提交mutation中的方法重新存储用户名和购物车数量到 state

  1. v-bind和v-model的区别, v-model原理知道吗?
  • v-bind用来绑定数据和属性以及表达式
  • v-model使用在表单中,实现双向数据绑定的,在表单元素外不起使用。

v-model原理:我们在vue项目中主要使用v-model指令在表单 input、textarea、select、等表单元素上创建双向数据绑定, v-model本质上就是vue的语法糖,v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • texttextarea元素使用value属性和input事件
  • checkboxradio使用checked属性和change事件
  • slect字段将 value作为prop并将change作用事件

「举个栗子」

<input v-model="something">
本质上相当于这样
<input v-bind:value="something" v-on:input="something = $event.target.value">
其实就是通过绑定一个something属性,通过监听input事件,当用户改变输入框数据的时候,
通过事件传递过来的事件对象中的target找到事件源,value属性表示事件源的值,从而实现双向数据绑定的效果

其他的实现可以参考文章v-model源码解析(超详细)

  1. MVC和MVVM有什么区别??

「MVC」

  • M - Model:模型,是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据
  • V - View: 视图,是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的。
  • C - Controller: 控制器, 是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

图示

流程

  • View 接受用户交互请求
  • View 将请求转交给Controller处理
  • Controller 操作Model进行数据更新保存
  • 数据更新保存之后,Model会通知View更新
  • View 更新变化数据使用户得到反馈

「MVVM」

  • M - Model,Model 代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑
  • V - View,View 代表 UI 组件,它负责将数据模型转化为 UI 展现出来
  • VM - ViewModel,ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步 View 和 Model 的对象,连接 Model 和 View

图示

流程

  • View 接收用户交互请求
  • View 将请求转交给ViewModel
  • ViewModel 操作Model数据更新
  • Model 更新完数据,通知ViewModel数据发生变化
  • ViewModel 更新View数据

「两者的区别」

  • ViewModel 替换了Controller在UI层之下
  • ViewModel 向View暴露了它所需要的数据和指令
  • ViewModel 接收来自Model的数据

概括起来就是,MVVM由MVC发展而来,通过在Model之上而在View之下增加一个非视觉的组件将来自Model的数据映射到View中。

  1. Vue中的组件data为什么必须是函数??

因为组件是可以复用的,js里对象是引用关系,如果组件data是一个对象,那么子组件中的data属性值会互相污染,产生不必要的麻烦。所以一个组件中的data必须是一个函数,因此每个实例可以维护一份被返回对象独立的拷贝。也因为new Vue的实例是不会被复用,所以不存在以上问题。官方文档讲的很详细,想要深入了解可以看下文档中的解释。

vue官方文档

其他

  1. 前端的异常处理有做过嘛??做过哪些?

遇到这个问题我是蒙的,说实话真本地没想过面实习会问到我异常处理问题。我当时只讲了

  • js中的编码错误异常
  • http请求异常
  • Promise异常的处理

其实还有很多种,我连window.error来捕获运行错误都没讲

如何优雅处理前端异常?

  1. cookie、SessionStroage、LocalStroage这三者的区别。

回答这个问题的时候我没答好,讲到最后自己都没听明白,之间自己还做过笔记(可见复习的重要性,做过的笔记一定要多看,不然也就没有意义了)

Cookie4K, Stroage5M

  • 存储有效期

Cookie有有效期的限制,而Storage没有,sessionStorage只在窗口关闭会消失 LocalStorage始终有效即使浏览器关闭也有,是存储在硬盘中的。存储位置:C:\Users\你的计算机名\AppData\Local\Google\Chrome\User Data\Default\Local Storage\leveldb

  • 作用域不同

sessionStorage不在不同的浏览器窗口共享,即使是同一个页面,LocalStorage在所有同源窗口中都是共享的,cookie也是在所以同源窗口共享。

Cookie、LocalStorage 与 SessionStorage的区别在哪里?

  1. 对于http请求有了解过嘛?常见的状态码都有那些?405是什么?

HTTP网络状态码(STATUS) 根据状态码能够清楚的反映出当前交互的结果及原因

  • 200 OK 成功(最理想的状态)
  • 301 Moved Permanently 永久转移(永久重定向)
  • 302 Move temporarily 临时转移
  • 304 Not Modified 设置缓存
  • 400 Bad Request 请求参数错误
  • 401 Unauthorized 无权限访问
  • 404 Not Found 找不到资源(最不理想的状态)
  • 405 Method Not Allowed 请求行中指定的请求方法不能被用于请求相应的资源,但是该响应必须返回一个Allow头信息来表示出当前资源能够接受请求方法的列表。
  • 500 Internal Server Error 未知的服务器错误
  • 503 Service Unavailable 服务器超负荷

2xx状态码一般是前端人员的锅,5xx一般是后台人员的锅,学会看问题出在哪里很重要,对以后工作中的甩锅有很大帮助。

  1. 浏览器缓存知道吗?

浏览器缓存也就是HTTP缓存机制,其机制是根据HTTP报文的缓存标识进行的,缓存分为两种:

「强制缓存」

当浏览器向服务器发送请求的时候,服务器会将缓存规则放入HTTP响应的报文的HTTP头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Conctrol的优先级比Expires高。

「协商缓存」

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

强制缓存优先于协商缓存进行,若强制缓存生效则直接使用缓存,若不生效则进行协商缓存,协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存

浏览器缓存机制

  1. 原生Ajax和axios的区别,Ajax怎么发送http请求的?

原生Ajax是根据 XMLHttpRequest发HTTP请求,而axios是根据Ajax进行封装的插件,其内部利用Promise实现,很好的解决的异步请求回调地狱的问题。

后者的问题其实就是问Ajax发送请求的五个步骤,这个过于基础就不讲了。

  1. get请求和post请求有什么区别??

「GET」

  • 一般用于获取数据
  • 基于URL地址传参,所以有个长度限制(一般在8KB左右),如果超过就会被截掉
  • 因为GET请求基于问号传参容易被劫持,所以相对不安全。
  • 会产生不可控制的缓存,POST不会

「POST」

  • 一般用于新增数据
  • 基于请求传参,理论上没有任何限制(真实项目中会自己做大小限制,防止上传过在信息导致请求迟迟完不成)
  • PSOT请求基于请求主体传参,相对来说不好被劫持,比较安全
  1. http和https有什么区别??

这个问题要回答起来能回答半个小时,每个人回答的方向不一样。

我的回答是:HTTP为超文本传输协议,HTTPS为安全超文本传输协议,后者是前者的升级,相对比较安全,通过数据加密传输的方式,安全系数比较高,HTTPS也会作为网站的搜索权重指标,所以HTTPS的网站在排名中也更有优势。

  1. 后端能删除前端设置的cookie吗?

我回答是不可以的,我也不知道是不是对的,百度了一圈也没有答案。。。有知道的大佬可以在评论区回答下。

  1. 常见布局有几种方式?
  • 弹性布局(rem/em)
  • 栅格化布局
  • 百分比布局

网上有很多种,可以自己去搜,这里就不多讲了。

  1. rem和em有区别嘛? 1em等于多少像素

rem和em单位一样,都是一个相对单位,不同的是em是相对于元素的父元素的font-size进行计算,rem是相对于 根元素html的font-size进行计算。

1em相当于当前元素父元素的font-size

举个栗子

<style>
 .box {
   font-size: 18px;
 }
 .box .children {
   width: 2rem; // 相当于2 * 18 = 36px
 }
</style>
  <div class="box">
  <span class="children">里面</span>
</div> 
  1. git用过吧?常见的命令有哪些?如果让你来负责一个项目你怎么让管理你的仓库?

「常用命令」

# 创建版本库:
- git clone
- git init

# 查看配置
git config -l // 查看全部
git conig --global -l // 查看仓库中人员名和邮箱
git config user.name xxx // 设置
git config user.email xxx // 设置

# 修改和提交
git status
git diff // 查看变更内容
git add .
git mv
git rm
git commmit -m

# 查看提交历史
git log
git log <file> // 查看该文件每次提交的记录
分支操作
git branch // 查看当前分支
git checkout -b // 添加一个新分支并切换过去

# 远程操作
git remote -v // 查看远程分支
git remote add <remoteURL> // 添加远程分支

最后说了下我管理库的方式:首先我会在gitHub上创建一个仓库,为当前项目中每位开发人员取一个对应的分支,让其在对应的分支开发。然后clone我这个仓库。当队员需要向gitHub上传代码时,需要先将自己的代码同步到自己远程仓库对应的分支中,再切换到要本地的主分支将自己本地开发的分支代码进行合并,如果有冲突先在本地解决,最后再同步到远程的主分支 复制代码`

场景题

  1. 如果有一张很大的图片放到线上, 显示要很久, 你会怎么优化?

我当时只回答了这两点,其他的我也不知道。。。

  • 用延迟加载技术
  • 优化图片的大小
  1. 如果让你对element-ui中的表单进行二次动态封装,你会怎么做?

对于这种题我回答的贼差,不敢误人子弟,这里分享一个错的文章 组件化页面:封装el-form

  1. 项目中遇到过那些复杂的业务场景,怎么解决的?

这个就看个人回答了,不同的项目遇到的问题也不一样。

  1. 封装组件你有什么好的想法

对于这个问题我是蒙的,可能是因为我简历上写了很好的组件化开发思想吧(说实话当时的回答有点打脸),我是从代码方面回答的。

通过vue.extend,vue.component注册这种方式找到项目通用的模块,指定通用部分代码,props传值,并且通过slot来自由定制内容,然后创建vue文件。

对于这种问题网上也没有好的回答,欢迎大佬在下方评论交流。

  1. 在众多表单中都需要用到点击查询按钮根据参数的不同来弹出一个查询框,里面有个小列表,查到数据后点一行再回显, 你怎么封装这个组件? (就是多个页面中需要查询显示数据列表)

我说下我的大概思路,首先分析需求:需要什么?

  • 一个form表单,一个table,分页
  • n个条件框,查询按钮、重置按钮、其他功能按钮。。

需要实现的功能

  • 点击分页后查询数据
  • 选中一行后拿到数据
  • 其他功能的触发

最后确定那些数据是需要外部传入就ok了。

  1. 你觉得你这个防小米商城项目中最大的亮点是什么??

在订单确认页面,使用自行封装dialog通过slot自由定制内容的方式来实现,新增、编辑、删除收货地址的对应元素,用户点击的不同实现对应功能

原作者姓名:前端自学驿站
原出处:掘金
原文链接:https://juejin.im/post/5ef498c1e51d4534bc721e0d


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK