自我介绍
面试官你好,我叫xxx,9x年2x周岁,xx大学18届毕业生
目前在公司研发部任职前端开发工程师,从事前端研发工作有2年了
我们公司的主要业务是关于企业融资和企业贷款这方面的
我目前主要负责公司官网的研发和维护,主要使用的技术栈是 Vue
在公司官网开发中具体负责项目的管理,网站页面结构的搭建,企业管理,融资申请这两个主要模块的开发,网站的测试以及性能方面的优化
在上家公司的话,工作任务是偏测试和后端的,平时主要负责公司产品的功能性测试,一些文档手册的撰写,参与开发过公司的一个爬虫项目
大概一年之后就主要负责web前端这一块儿的研发
前端方面的话,
基本的HTML,CSS,JS都有掌握
ES6的语法也基本熟悉
对Vue相关的Vue-Router,Vuex,Axios,Scss也基本都有了解
另外的就是对爬虫开发也有一定的心得
问题
- get和post请求的区别
- get 获取数据,post 发送数据(表单验证)
- get数据在 url 上,post数据在请求体中
- get 请求的数据会被浏览器缓存,post不会
- post 比 get 更安全
- 面试官又问:get请求参数的长度有限制吗,我说有,post没有限制
- 面试官问:什么限制?不知道
- 页面渲染流程
- 面试官提示:从接受服务端的html文档开始,发生了什么
- 我说变接受的同时边根据现有的文档渲染dom,同时异步加载css,img等资源,同步加载js文件
- 面试官追问:css样式是怎么渲染到dom节点上的?这个我也不知道
- 跨域问题,我说了4种,面试官说第3,4是1种
- jsonp:html标签script,img等标签有天然的跨域能力,jsonp就是利用这种特性,但是只能用于get请求
- 同源策略:服务端请求头设置一个 Access…origin 属性,具体没打答上来,因为这个是后端同学要做的,拉夸
- 客户端和服务端有跨域,服务端和服务端是没有的,webpack-dev-server就是利用这种特性解决了跨域
- Nginx和Appche实现反向代理
- 面试官说,webpack-dev-server 也是反向代理
- Vue 常用的修饰符
- 我前面以为是 v-for,v-model,v-if 什么的
- 后来又跟面试官确认了一下,是鼠标,键盘事件的系统修饰符
- 我只说出了:stop,prevent,once 三个
- Vue如何实现视图(Dom)的更新
- 我问是不是指 Vue 的双向绑定原理,面试官说是
- 我回答了2点
- 数据劫持:Object.defineProperty 进行数据劫持
- 发布-订阅模式,收集依赖,通知更新
- 面试官问有没有看过Vue源码,我说没有,但是看过一些博主手写Vue源码的教程
- 面试官就没再问下去了
- 因为简历中有些项目性能优化,面试官又开始问 webpack 的东西
- 我说我对这个的了解也只限于根据官方文档照猫画虎,不懂原理,面试官说问不会问原理的
- 问:loader根plugin的区别
- 我说,loader 加载器,将css,vue文件转换成webpack能识别的js文件
- plugin 插件,扩展 webpack 的功能,比如单独打包 html,css 文件,代码压缩,树摇什么的
- 问:css,img 文件是经过 loader 还是 plugin
- 我说可能都有:css-loader,style-loader 会将css代码转换成 style 标签包裹的嵌入页面,还有一个插件可以单独打包CSS文件
- img图片也会有 url-loader 或 file-loader 去解析,也可能会有一些压缩图片的插件
- 问:url-loader 打包图片
- 问:你是怎么通过 webpack 做性能优化的
- Vue,Vue-Router,Axios等外部的插件或库,不打包到 dist 目录里面,而是配置成外部 CDN 引入资源
- 大一点的图片,字体资源等,放置在另外的静态服务器上,额外请求(前面提过img是异步加载)
- 用一个插件将代码压缩成 gzip 这样的格式,减小包的体积,这个需要后端配合(面试官好向没用过这个,他印象中的压缩要做应该是去除代码中无用的注释,空行,制表,空格等)
- 前面还问了dom的事件机制,我没get到,问他是不是指 事件流(事件捕获+事件触发+事件冒泡),面试官说是
- 事件捕获->事件触发->事件冒泡,这是一个循环机制,另外就再没答出来
- 面试官又问IE浏览器的事件机制,我只知道IE浏览器好像是基于事件冒泡实现的,DOM2和DOM3好像已经都支持事件冒泡和事件捕获了,面试官就再没问
- 其他
- load 和 DOMContentLoaded 的区别,从名字上看,后一个应该是DOM节点加载完成之后定义的行为,这个没打出来,我说我只用过load
- bind,call,apply的区别,都是改变this指向,bind不会立即执行,另外两个会;call和apply参数个数上有差别,他们第一个参数都是调用函数的实际对象,apply第二个参数是函数参数的数组,apply也只有这2个参数,call可以有多个参数,除第一个参数外其他参数都是函数的参数,二者传参形式上有差别;另外我说call的速度比apply快一些
- .vue文件里的template标签怎么编译,我只说应该是Vue实例里的template属性,属性值应该是文件template里的内容的字符串
- 还问了CommonJS和es6的模块化的区别。这个有点盲区了,我跟面试官确认,CommonJS是不是node里面的require这种形式,es6的话是指import,面试官说是,我就瞎几把搂了一点,我说require加载的模块使用moudlu.export导出,import加载的模块使用export或者export default的形式导出,面试官说导出方式不一样是吧,我说嗯,另外的话就是import导入好像会发送网络请求,尤大的vite就是根据这个实现的,require应该不会,这个问题我就只能答到这么多,拉跨
- 跟前端无关的
- 之前上家公司做过一个爬虫项目,所以面试官问爬虫项目做了什么东西?我说全国酒店,航班 ,小区,企业信息的爬取。面试官用的是python嘛,我说对的。后面就没再问了
- 还问我项目中遇到最大的挑战是什么,我说就是这个公司官网,vue都是从零开始,很多时候都答不到领导的要求,就不断地学习不断的改。这个问题着实答得非常拉跨
- 我是有点紧张的,也不知道自己说了啥,后面复盘感觉自己答的一塌糊涂,下面就是编程题了
编程题
题一
class Animal {
sayName = () => { throw new Error('你应该自己实现这个方法');
} }
class Monkey extends Animal {
sayName() { console.log('I love coding');
} }
const monkey = new Monkey();
monkey.sayName();
- 输出:
Uncaught Error: 你应该自己实现这个方法
- 我的回答是Animal的sayName是定义在monkey 实例上的,Monkey 的 sayName 是定义在原型链上的
- 面试官说我蒙对了,但是没回答到点上,这题主要考察箭头函数 this 指向的问题,现在还没弄明白
题二
描述:最长递增子序列意思是在一组数字中,找出最长一串递增的数字,比如
0, 3, 4, 17, 2, 8, 6, 10,对于以上这串数字来说,最长递增子序列就是 0, 3, 4, 8, 10。
- 下面是我瞎几把蒙出来的,做个参考,英语太差拼音代替,引以为戒
function maxDizengXulie(arr) {
const result = []
const dp = new Array(arr.length).fill(1)
dp[0] = [arr[0]]
for(let i=1; i<arr.length; i++) {
if(dp[i-1][dp[i-1].length-1] <= arr[i]) {
const prev = [...dp[i-1]]
prev.push(arr[i])
dp[i] = prev
} else {
let flag = true
let maxLen = 0
let maxLenArr = []
for(let j=i-1; j>=0; j--) {
if(dp[j][dp[j].length-1] <= arr[i] && maxLen < dp[j].length) {
flag = false
maxLen = dp[j].length
maxLenArr = dp[j]
}
}
if(flag) dp[i] = [arr[i]]
else {
const prev = [...maxLenArr]
prev.push(arr[i])
dp[i] = prev
}
}
}
console.log(dp)
return result
}
const testArr = [0, 3, 4, 17, 2, 8, 6, 10]
console.log(maxDizengXulie(testArr))
最后
- 最后面试管问我你还有什么想问我的吗,我说我想了解一下您这边对我的这次面试的印象
- 面试官说后面会跟hr交流,让我等待
- 一面结束,心慌意乱,估计要凉