前端已经不再是5年前刚开始火爆时候的那种html+css+js+jquery的趋势了,现在需要你完全了解前端开发的同时,还要具备将上线、持续化、闭环、自动化、语义化、封装......等概念熟练运用到工作中的一个职业,甚至用人部门还希望你了解并掌握深度学习及机器学习的相关概念。在面试过程中,各部门交叉面试的时候会提问一些关于后端的知识。假如你想要拿到2.5w+月薪,你的能力应该达到掌握以下全部知识点并有过开发后端接口与数据处理(node、java、c......必须掌握一种)的经验。本文就是结合自己的工作、面试经验,同时为那些想要冲击2w+薪资的1-3年新手们准备的。
需要注意的是,所有大厂的社招会按照你当前工作经验进行+1,+2的难度提升(假设你工作一年,会按照三年工作经验进行招聘,同时二三面会按照你的项目经验进行择优筛选)所以起步是互联网公司的同学占了很大的优势,有些小伙伴在国企工作一年~三年,项目经验的欠缺导致竞争力不足,没别的办法,建议早日跳出自己的舒适圈,之后你会体会到不一样的前端开发。happy hacking!!
1、mock
在前后端分离的开发中,Mock 数据是前端开发中很重要的一个环节,前端可以不必强依赖后端接口,只需要约定好对应的数据接口,前端可以通过 Mock 模拟数据先行开发,在后端接口开发完成后,只需要切换对应的接口地址即可,可以保证项目的同步开发。
本地内容:在mock文件夹下中的index文件中定义好自有的接口路径,再到根目录的service文件夹下生成对应业务模块的js文件。文件内将相应微服务的接口匹配好。暴露出去供业务功能调用。
2、网络请求编码表示
会从你是否关注Request head的哪些内容入手,一般关注点放在statusCode和method上就够用,重点200,304。同时掌握了基础后希望注意的点为文件上传的内容(百度问过断点续传的实现)
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
304:协商缓存
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误)。',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。'
3、axios工作流程
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范,它本身具有以下特征:
1.从浏览器中创建 XMLHttpRequest
2.支持 Promise API
3.客户端支持防止CSRF
4.提供了一些并发请求的接口(重要,方便了很多的操作)
5.从 node.js /java创建 http 请求
6.拦截请求和响应
7.转换请求和响应数据
8.取消请求
9.自动转换JSON数据
防止CSRF:就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。
/**
*
*
* @param {*} params mmsi
* @param {*} callback
*
*
*/
getship_cargo_detail:function(params,callback){
axios.get(server.portAddress+"newshipcargo/newship_pos_detail",{params})
.then(function(res){
callback(res.data);
})
.catch(function(error){
console.log("get_ship_cargo_data_error");
})
},
//调用方法
shipcargoserver.getship_cargo_detail({mmsi:mmsi},data=>{
if(data){
this.setState({
pageNumber:data.,,,,,,,
})
}
})
4、ElementUI(ElementReact)与antdesign和ice-work的比较
使用Element的原因是通过学习饿厂的 Element
其设计原则可以兼容三大框架 (三大框架各有实现):
Vue Element
React Element
Angular Element
整体上 UI 都是一套,但在不同框架中实现方式各异,API 变更较小,如果需要多个框架保持一套风格, Element 是非常好的选择。为了减少学习变更后项目api
antdesign功能极强,主要用来学习与观摩,模仿其语法及代码风格,主要基于React组件库的支持。感觉唯一的不足时在于当时使用时缺少一些在线预览的功能,最近又出了antdvue
飞冰最有意思的是钉钉群实时答疑让p7给你答疑(前提是混入群中)。500+ ICE 使用者在群里问任何层级的前端问题
React 组件。基础组件使用 Fusion,此外根据业务特性等开发了 40+ 业务组件
Playground:可复用模板,用于快速展示效果的业务。
5、WebRequest
API 可以让插件监控 Chrome 的网络请求,甚至重定向请求。例如:临时替换hotfix分支的图片
// background.js
chrome.webRequest.onBeforeRequest.addListener(
function (details) {
const url = details.url;
if (url === 'http://n.sinaimg.cn/news/1_img/upload/7b577cec/576/w778h598/20180820/lSSg-hhxaafy9194151.jpg') {
console.log(22)
return {
redirectUrl: 'https://github.com/welearnmore/chrome-extension-book/raw/master/doc/images/logo_google_developers.png'
}
}
return {cancel: false}
},
{urls: ["<all_urls>"]},
["blocking"]
)
6、减少reflow的方法
- 不要一条一条地修改
DOM
的样式。与其这样,还不如预先定义好css
的class
,然后修改DOM
的className
:
// 不好的写法 var left = 10, top = 10; el.style.left = left + "px"; el.style.top = top + "px"; // 推荐写法 el.className += " theclassname"; - 把 DOM 离线后修改。如:
a>
使用documentFragment
对象在内存里操作DOM
。b>
先把DOM
给display:none
(有一次repaint
),然后你想怎么改就怎么改。比如修改100
次,然后再把他显示出来。c>
clone
一个DOM
节点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。 - 不要把
DOM
节点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性。 - 尽可能的修改层级比较低的
DOM
节点。当然,改变层级比较底的DOM
节点有可能会造成大面积的reflow
,但是也可能影响范围很小。 - 为动画的
HTML
元件使用fixed
或absoult
的position
,那么修改他们的CSS
是会大大减小reflow
。 - 千万不要使用
table
布局。因为可能很小的一个小改动会造成整个table
的重新布局。
参考:
深刻剖析回流与重绘:
7、微任务与宏任务与eventloop
重点记住promise是微任务,执行完同步任务后,在异步中最先执行的就是promise
参考
8、隐式转换全部情况
!![] == true //结果是true
[] == true //结果是false
![] == [] //结果是true
针对[] == true 与!![]的解释参考:
记忆方式
[] 转为字符串是 "" // String([]) 返回""
[] 转为数字是 0 // Number([]) 返回0
[] 转为布尔值是 true // Boolean([]) 返回true
true 转为数字是 1 // Number(true) 返回1
false 转为数字是 0 // Number(false) 返回0
参考全部隐式转化规则
9、webstorage
着重点在于sessionstorage与localstorage的数据存储机制及处理机制。
10、如何使用sessionID判别用户状态
将cookie中放入响应头中携带相应sessionID通过post方式向后端发请求,后端返回结果为用户独特的sessionID与前端匹配,则不用创建新的sessionID,假若不匹配则需要创建一个新的sessionID,归根结底还是由于HTTP的无状态性,web容器生成一个sessionid来标识用户,以便获取该用户对应的session信息。
后台生成一个新sessionid的可能原因:
- 这是一个新用户的第一次请求
- 后端存在清空session的逻辑
- 前端没有将sessionid放到cookie或其他约定的地方传给后端
- 前端传了,但后端没有匹配到对应的sessionid(如果是个分布式服务,负载均衡后,后端服务没有做session同步)
11、OAuth2原理及应用
允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。
应用场景:
原生app授权:app登录请求后台接口,为了安全认证,所有请求都带token信息,如果登录验证、请求后台数据。
前后端分离单页面应用(spa):前后端分离框架,前端请求后台数据,需要进行oauth2安全认证,比如使用vue、react后者h5开发的app。
流程:
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
12、http://socket.io的前端使用
客户端和服务器之间的低延迟双向通信。客户端应用程序可以使用 Javascript的任何 SocketIO 官方客户端库或任何兼容的客户端来建立与服务器的永久连接。
引入http://socket.io的依赖在react框架中进行使用,自己尝试实现了一个聊天室:
testconnect=()=>{
let socket = sockjs("ws://localhost:3900", {
transports: ['websocket']
})
// /不间断尝试重连接
socket.on('reconnect_attempt',()=> {
console.log("reconnect")
socket.transports = ['websocket','polling', 'flashsocket'];
});
// 重连接时出错
socket.on('reconnect_error',(attemptNumber)=> {
console.log(attemptNumber)
});
//连接成功走这个方法
socket.on('connect',()=>{
console.log(socket.connected)
})
//报错时走这个方法
socket.on('connect_error', (error) => {
console.log(error)
});
//连接存活验证
socket.on('ping', (error) => {
console.log('ping_include')
});
// 连接成功的connect方法
socket.on("connect",function(){
// console.log(socket.broadcast)
socket.emit('join',prompt('what is your nickname'));
$('#chat').css('display','block');
socket.on('announcement',(msg)=>{
if(msg){
console.log("announcement did right")
let li = `<li class="announcement">${msg}</li>`
$("#messages").append(li);
}
})
})
// 添加获取信息的方法
$("#form").submit(()=>{
let inputan =$('#input');
console.log("submit success")
this.addmessage('me',inputan.val()) ;
socket.emit('text',inputan.val());
inputan.attr('value');
inputan.focus();
return false
} )
//不要自执行,要在调用后再执行
socket.on('text',this.addmessage)
}
// 将聊天记录添加到首页的每一个字段上
addmessage=(from,text)=>{
if(text){
let li = `<li class="message"><b>${from}</b>:${text}</li>`
$("#messages").append(li);
}
}
13、webpack的作用及核心配置
webpack配置中需要理解几个核心的概念Entry
、Output
、Loaders
、Plugins
、 Chunk
Entry:指定webpack开始构建的入口模块,从该模块开始构建并计算出直接或间接依赖的模块或者库
Output:告诉webpack如何命名输出的文件以及输出的目录
Loaders:由于webpack只能处理javascript,所以我们需要对一些非js文件处理成webpack能够处理的模块,比如sass文件
Plugins:Loaders
将各类型的文件处理成webpack能够处理的模块,plugins
有着很强的能力。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。但也是最复杂的一个。比如对js文件进行压缩优化的UglifyJsPlugin
插件
Chunk:coding split的产物,我们可以对一些代码打包成一个单独的chunk,比如某些公共模块,去重,更好的利用缓存。或者按需加载某些功能模块,优化加载时间。在webpack3及以前我们都利用CommonsChunkPlugin
将一些公共代码分割成一个chunk,实现单独加载。在webpack4 中CommonsChunkPlugin
被废弃,使用SplitChunksPlugin
进阶(具备手撸一个loader、plugins的能力):
14、==与===的比较,===的使用情况
===的使用情况我回答是,一般在比较字符串时来使用。
权威解释:
15、闭包的应用场景
函数防抖,通过立即执行函数在循环中的异步执行能够取到正确的值
权威解答:
16、敏捷开发的全部流程
每次迭代都必须依次完成以下五个步骤。
- 需求分析(requirements analysis)
- 设计(design)
- 编码(coding)
- 测试(testing)
- 部署和评估(deployment / evaluation)
每个迭代大约持续2~6周。
17、webpack+glup/FIS
gulp是基于流的自动化构建工具,但不包括模块化的功能,如果要用到的话,就需要引入外部文件,比如require.js等;而webpack是自动化模块打包工具,本身就具有模块化,并且也具有压缩合并的功能。
三者的比较
定位不同,webpack定位是一个打包工具,模块化。其实自动化的工具更好用gulp之类解决。fis3直接定位为一个全功能工具,官方文档介绍中:解决性能优化,模块化,自动化,甚至包括代码规范,部署等问题。
个人喜欢用webpack,可以更灵活的搭配其它工具使用,且生态系统强大,当然最近比较火的可能是rollup,它打包的文件体积更小。glup+webpack自动化部署参考:
18、git常用的基本命令
最最基础的去参考我自己的文章,进阶版看这篇
19、jar包查看项目进程
到xxx.jar目录下执行:
nohup java -jar xxx.jar > people.log 2>&1 & -- 运行jar包并包日志写入到people.log中
tail -f people.log --查看运行日志
20、mvc与mvvm的区别
mvc
Model(模型)
View(视图)
Controller(控制器)
简单的理解:视图请求数据,将请求发送至控制器,控制器再将请求发送给模型,模型去查找数据,找到之后传给控制器,控制器再传给视图进行渲染。
mvvm
Model 代表数据模型
View 代表UI视图
ViewModel 负责监听 Model 中数据的改变并且控制视图的更新(桥梁,可以理解成mvc中的控制器) 简单理解:视图请求数据,将请求发送至控制器,在控制器的两端具有监听机制,直接调用模型的数据,一端改变全部改变,利用数据劫持,结合订阅者和发布者模式,实现数据的双向绑定
mvvm优点
MVVM比MVC精简很多,不仅简化了业务与界面的依赖,还解决了数据频繁更新的问题,不用再用选择器操作DOM元素。因为在MVVM中,View不知道Model的存在,Model和ViewModel也观察不到View,这种低耦合模式提高代码的可重用性
双向绑定的定义
- 一般只有UI表单控件才存在双向数据绑定,非UI表单控件只有单向数据绑定。
- 单向数据绑定是指:M的变化可以自动更新到ViewModel,但ViewModel的变化需要手动更新到M(通过给表单控件设置事件监听)
- 双向数据绑定是指念:M的变化可以自动更新到ViewModel,ViewModel的变化也可以自动更新到M
- 双向绑定 = 单向绑定 + UI事件监听。双向和单向只不过是框架封装程度上的差异,本质上两者是可以相互转换的。
优缺点:在表单交互较多的情况下,单向数据绑定的优点是数据更易于跟踪管理和维护,缺点是代码量较多比较啰嗦,双向数据绑定的优缺点和单向绑定正好相反。
MVVM模式在react中的对应关系
- M(odel):对应组件的方法或生命周期函数中实现的业务逻辑和this.state中保存的本地数据,如果React集成了redux +react-redux,那么组件中的业务逻辑和本地数据可以完全被解耦出来单独存放当做M层,如业务逻辑放在Reducer和Action中。
- V(iew)-M(odel):对应组件中的JSX,它实质上是Virtual DOM的语法糖。React负责维护 Virtual DOM以及对其进行diff运算,而React-dom 会把Virtual DOM渲染成浏览器中的真实DOM
- View:对应框架在浏览器中基于虚拟DOM生成的真实DOM(并不需要我们自己书写)以及我们书写的CSS
- 绑定器:对应JSX中的命令以及绑定的数据,如className={ http://this.props.xxx }、{http://this.props.xxx}等等
21、html语义化,css模块化
就是尽可能的理解要表达的内容,选择适合的标签,将内容转换成浏览器认识的语言,通过浏览器传达给用户。从这个角度来说,我们更像是“翻译”。
- 除了专业的人外,没人会去看我们的标签是否使用得有语义
- HTML的标签还不足以表达所有可能的语义
- 语义化会需要增加一些额外的代码
HTML5新增的几个标签,更多的补充了目前HTML标签语义上的不足,这点也可以看出语义化是以后发展的一个方向,当然更大的目标是统一的实现标准,语义化只是为了这个目标所使用的一个方法。这可能需要相当的一段时间,而我们正经历着这个过程。
模块化
模块化就是为了减少循环依赖,减少耦合,提高设计的效率。为了做到这一点,我们需要有一个设计规则,所有的模块都在这个规则下进 行设计。良好的设计规则,会把耦合密集的设计参数进行归类作为一个模块,并以此划分工作任务。而模块之间彼此通过一个固定的接口(所谓的可见参数)进行交互,除此之外的内部实现(所谓的隐参数)则由模块的开发团队进行自由发挥。
程序模块化的目的:
1.减少循环依赖
2.减少耦合
3.提高设计效率
css模块化原则
- 分离结构和表现
- 分离容器和内容
22、标准化的javascript
JavaScript 的核心 ECMAScript 描述了该语言的语法和基本对象;
DOM 描述了处理网页内容的方法和接口;
BOM 描述了与浏览器进行交互的方法和接口。
23、前端兼容性问题总结
24、前端性能优化
25、loadash的使用
26、前端预处理器sass的使用
Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库(如 Compass)有助于更好地组织管理样式文件,以及更高效地开发项目。
27、leetcode算法最优解
找不到想要的解答,从这上面搜一下
28、不了解的三种函数写法
29、react源码总结
react在使用时总结不出这么多优点,他帮你解决了面试提问的难题:
30、Flex布局,position,垂直水平居中三种必问前端常识
31、破碎浮点型数据的解决办法
过长的纯数字数组不能通过Number或者parseInt进行转化,这样会产生错误,要使用BigInt来解决。想要计算二元运算需要在二元运算的另一个项上加上n,参考例子与讲解均在里面:
32、中级前端所有手写内容
- 防抖、节流
- 深浅拷贝
- 数组乱序、数组去重(各种时间空间复杂度)
- 数组filter
- 数组flat(平展一层到多层)
- 手写call、bind、apply(及了解这三种的区别)
- 八种继承及各种继承之间的特点
- 实现instanceof
- 实现new的过程
- lazyman
- jsonp的实现
- 函数的柯力化
- promise、promise.all、promise.retry
(其中大厂不排除让你手写ajax的封装(百度),头条(promise.retry)有点变1态了)
参考地址:
33、大厂常问的React全家桶
必须掌握、必须掌握、必须掌握!
react-router:
redux、react-redux:
拓展(强烈建议能手写出来)、几家大厂都在问: