通过朋友介绍,经过了有赞的内部推荐,算是经历了完整的面试流程,写在掘金上分享一下,本人大概状况:掘金小透明,前端技术废,欢迎留言拍砖,分享记得署名转载地址。若是对我技术感兴趣的话,欢迎发来邀请,期待与你共事。javascript
第一次在掘金发文,若是文章格式不规范或者文章中存在形成歧义的地方,先行道歉,请您告知我,配图大多来源于网络,形成侵权的话会当即删除,期待你的修改建议。php
有赞的面试流程是内推流程过了后,会有电话面试的人跟你约你方便的时间,约好时间就会在当天收到电话面试。css
如下是一些问题,时间不分前后。
1.http协议中301和302的区别
http协议中,301表明资源的永久重定向,302表明资源的临时重定向,当时还举了一个Restful的例子,观察到不少的第三方受权,受权事后的回跳地址常常会使用301形式,改变浏览器的回跳地址。html
2.介绍下Restful
当时被问到这个问题感受太笼统了,就介绍了下Restful的集中请求格式,GET从服务器取出资源,POST在服务器新建一个资源,PUT在服务器更新资源,PATCH在服务器部分更新资源,DELETE从服务器删除资源。前端
3.描述如下POST和PUT的区别
POST经常使用于提交数据至服务端,新建资源时使用。PUT用于修改更新已存在的资源时使用。多说了如下关于GET和POST的区别,GET请求多数采用查询数据时使用,不推荐对资源的更新及新建,容易形成服务器数据泄漏,或者XSS或者CSRF攻击。vue
4.XSS攻击的场景能描述一个么?
表单提交过程当中,须要对提交的数据进行引号,尖括号,斜杠进行转义,防止标签或者是eval()的恶意代码注入。java
5.介绍下304过程。
a.浏览器请求资源时首先命中资源的Expires 和 Cache-Control,Expires 受限于本地时间,若是修改了本地时间,可能会形成缓存失效,能够经过Cache-control: max-age指定最大生命周期,状态仍然返回200,但不会请求数据,在浏览器中能明显看到from cache字样
b.强缓存失效,进入协商缓存阶段,首先验证ETagETag能够保证每个资源是惟一的,资源变化都会致使ETag变化。服务器根据客户端上送的If-None-Match值来判断是否命中缓存。
c.协商缓存Last-Modify/If-Modify-Since阶段,客户端第一次请求资源时,服务服返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间。再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存以前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。node
6.说一下浏览器中的事件机制。
刚被问的时候有点懵,确认了下是否是问关于事件冒泡和捕获方面的知识。
我举了一个点击事件传递的例子,从root往事件触发处传播,遇到注册的捕获事件会触发,传播到事件触发处时触发注册的事件,从事件触发处往root传播,遇到注册的冒泡事件会触发,若是给一个目标节点(触发节点)同时注册冒泡和捕获事件,事件触发会按照注册的顺序执行。python
[fix 1.0.2]感谢评论区一只小生
对上边表述的校验。
将当同一控件即绑定冒泡又绑定捕获事件时,事件触发会按照绑定的顺序执行
修改成若是给一个目标节点(触发节点)同时注册冒泡和捕获事件,事件触发会按照注册的顺序执行
webpack
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<div id="root">root
<p id="parent">parent
<span id="child">child</span>
</p>
</div>
<script> let parentNode = document.getElementById('parent') // 由于触发标签不一样,致使输出顺序不一样 // 点击parent会输出冒泡,捕获,由于目标节点按照绑定顺序输出 // 点击child会输出捕获,冒泡,由于非目标节点正常按照浏览器事件机制执行 parentNode.addEventListener( 'click', event => { console.log('冒泡') }, false ) parentNode.addEventListener( 'click', event => { console.log('捕获 ') }, true ) </script>
</body>
</html>
复制代码
7.简述一下防抖和截流,并口述一下防抖模拟的大体流程
防抖动是将屡次执行变为最后一次执行,节流是将屡次执行变成每隔一段时间执行。
设置定时器,并判断当前函数是否须要当即执行,若是须要则当即执行。不然进入正常的防抖逻辑,设置setTimeout定时器,同时缓存这个定时器,在定时器倒计时阶段,判断timer是否为null,若是不为空缓存当前执行上下文,重复调用则重复更新,直到保存到执行的那一刻。若是为空,则开始下一轮的防抖计时。
8.简述下浏览器的Event loop
javascript是非阻塞
的单线程
语言,浏览器的javascript运行环境将js分红两种任务,分别为宏任务和微任务,一个正常的Event loop执行顺序大概是:
9.请简述==机制
这个问题涉及到对象的类型若转换,其实判断对象相等实际上调用的是对象的toPrimitive方法,就是对象转基本类型,展开说一下Symbol.toPrimitive方法,其中包含三种判断,分别是转化成数字型、字符串型以及默认转换。
let obj = {
[Symbol.toPrimitive](hint) {
switch (hint) {
case 'number':
return 123;
case 'string':
return 'str';
case 'default':
return 'default';
default:
throw new Error();
}
}
};
// [防爬虫标识-沙海听雨]
2 * obj // 246
3 + obj // '3default'
obj == 'default' // true
String(obj) // 'str'
复制代码
而后又举了[] == ![]
这个经典的例子,大体的转化过程以下:
[] == ![]
[] == false
[] == ToNumber(false)
[] == 0
ToPrimitive([]) == 0
'' == 0
0 == 0 // -> true
复制代码
10.请简述js中的this指针绑定
这个几乎是常问到的知识点,我在看《你不知道的javascript》书中有过很详细的描述。js中的this指针绑定总结下包含四种形式:默认绑定,隐式绑定,显式绑定,new绑定,优先级从小到大,有分别阐述了四种形式的代码。
// 默认绑定
function foo(){
console.info(this.a)
}
var a = 'hello'
foo()
// 隐式绑定
// 调用位置是否有上下文对象
function foo() {
console.info(this.a)
}
var obj = {
a: 1,
foo: foo
}
obj.foo()
// 显式绑定
// 对应apply call bind
// 其中bind又叫硬绑定
// bind(..) 会返回一个硬编码的新函数,它会把参数设置为this 的上下文并调用原始函数。
// [防爬虫标识-沙海听雨]
// new绑定
// 使用new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操做。
// 1. 建立(或者说构造)一个全新的对象。
// 2. 这个新对象会被执行[[ 原型]] 链接。
// 3. 这个新对象会绑定到函数调用的this。
// 4. 若是函数没有返回其余对象,那么new 表达式中的函数调用会自动返回这个新对象。
复制代码
11.请简述原型链 这个问题,每一个人都有本身心理的原型链,一图胜千言,我就不详细描述,下图是跟我同组的人员作的一些讨论。基本达成了共识:
12.说说你理解的闭包
这个问题几乎前端的面试都会有所涉及,只不过问法不一样,个人答案:函数嵌套保护内部函数不会被外部函数干扰而造成的一个隔离。
比较经常使用的闭包,能够举出随处可见的数据请求,同时也能说出使用匿名函数回调函数形成的this指针丢失问题。
// 以axios举例
// 外部this指针暂存
var _self = this
this.$http.get(`/xxx`).then(function (res) {
// 此处this指针丢失,须要使用暂存的_self
if (res.data.rc === 0) {
// 操做
} else {
// 异常处理
}
}).catch(error => {
console.info(error)
})
// 使用箭头函数则this指针仍然可用
this.$http.get(`/xxx`).then(res => {
// 箭头函数内部的this指针指向外层this
if (res.data.rc === 0) {
// 操做
} else {
// 异常处理
}
}).catch(error => {
console.info(error)
})
复制代码
另外,有一个特别经典的保护内部变量的问题是Vue框架下,为何data必须是一个函数,这个问题是当时酷家乐电话面试问的,真是问了个措手不及,反思了下,知识点不能学死板了,灵活串起来容易记忆,传送门data 必须是一个函数
13.箭头函数
箭头函数算是一个特殊的函数,常常看书可能会答得模模糊糊的,其实箭头函数没有this指针,它的this指向了外层不是箭头函数的this。
function foo () {
// this
() = > {
() => {
// ...
// [防爬虫标识-掘金-沙海听雨]
// 无论嵌套几层,一直往上找到不是箭头函数的位置,箭头函数内部的this就指向它
}
}
}
复制代码
14.ES5继承实现
口述实现了一下定义一个MyData类的过程
function MyData() {}
MyData.prototype.test = function () {
return this.getTime()
}
let d = new Date()
Object.setPrototypeOf(d, MyData.prototype)
Object.setPrototypeOf(MyData.prototype, Date.prototype)
复制代码
15.说一下virtual Dom中key的做用
实际的标签中可能存在两个如出一辙的两个节点,可是在virtual Dom中没法体现这个区别,另外一方面为了加快diff算法的速度,一个区别节点的变量的需求变得很是必要。
virtual Dom中须要给每一个节点一个标识,做为判断是同一个节点的依据。因此这也是 Vue 和 React 中官方推荐列表里的节点使用惟一的 key 来保证性能。
其中在diff算法中,大量使用了利用tagName和key组合判断节点之间差别的逻辑代码。
16.Vue 3.0有没有过了解
关于Vue 3.0有幸看过尤大的关于3.0版本的RFC Vue Function-based API RFC。 大体说了三个点,第一个是关于提出的新API setup()
函数,第二个说了对于Typescript的支持,最后说了关于替换Object.defineProperty为Proxy的支持。
详细说了下关于Proxy代替带来的性能上的提高,由于传统的原型链拦截的方法,没法检测对象及数组的一些更新操做,但使用Proxy又带来了浏览器兼容问题。
17.Electron
问了下关于这个的使用经验,这个我看过好多的文章,详细的使用过程我没有具体说,最近也在尝试这个解决方案。就说了下原理,由于大学在实验室作了3年的C#,对浏览器内核嵌入客户端程序有过一些实践经验,这种将B/S程序编译成C/S程序大体相同,原理是Electron经过将Chromium和Node.js合并到同一个运行时环境中,并将其打包为Mac,Windows和Linux系统下可运行的客户端程序。
18.看了下个人简历(听到翻纸的声音),问了下React和Node有实际项目经验
这个是个人弱势吧,以前公司不大,敏捷开发为主,Vue仍是自学的,源码啃的乱七八糟的。React和node我跟技术总监申请了无数回尝试计划,碍于实施成本无限次pass,有点无奈。
就简单说了下,我作React和node计划申请的计划,node的话,以前筹备了移动端首屏页面的服务器渲染和SEO方案,以及微服务框架下利用node作中间层的一些尝试,打算用在实际的项目中使用。
React的话也是没有过实际的项目经验,练手的应该不能算经验吧,以前一直想把公司的一个老项目微页重构了,老项目的性能和维护成本愈来愈大了,可是公司小一些的话,能用为主,有点无奈吧。
这种问题这个问题答得很差,其余同窗引觉得戒吧,多说说本身的亮点和优点啊,加分问题被我答成了减分问题。
19.项目经验
这个聊了七七八八吧,大概就是最后简述说一下项目的一些事情,摸一下底,我给上家公司招聘过程当中也发现好多培训出来的孩子太会面试了,实际操做和经验年限有些许的水分,我是不排斥培训出来的人,可是但愿面试者都实实在在的吧,这个摸底是必须的吧,问的越详细越好,至少别等入职以后耽误了项目进度再从新招人,如今互联网行业工期都太紧张了。
20.有什么想问的
这个问题我基本都问关于面试过程当中的感觉,面试官说了一些,简述的话就是基础尚可,框架经验单一,可是电话面试仍是比较喜欢基础好一些的候选人,跟我想的差很少,就结束了本次电话面试,总体过程仍是挺好的。
有一些比较细碎的问题我记得不是太清楚了,若是能记起来我会再补充一下。
电话面试2-3天左右很快就有了答复,告诉我经过了,约了复试,电话面试的小哥很负责,陆陆续续打了2个电话反复沟通。
1.非覆盖式发布
这个问题我回答了很久,一边回忆一边说,由于当时配置好以后就全权交给运维去作了,后期维护的一些改变运维方面我没有及时去看,一直在看产出的报告,致使这个问题我答得磕磕巴巴的,面试以前千万千万要回顾并熟知每个细节,不然就是给本身挖坑,下面是我面试时+面试后从新梳理。
首先简单介绍了覆盖发布和非覆盖发布的区别
[id].[chunkhash].js
的形式,这样更新文件后,新文件不会影响旧文件的存在。覆盖式发布的缺点:
新页面里加载旧的资源
,页面和资源对应不上,会有页面混乱,还有执行会报错。旧的页面加载新资源
。不管如何,覆盖式发布都是能被用户感知到的,因此部分公司的发布是晚上上线
。其中若是使用vue-cli直接生成webpack配置打包的话,直接发布dist文件夹下资源就会产生这种特殊的替换问题,由于在build.js文件中存在这么一行代码,初衷应该是防止dist文件夹愈来愈大,可是rimraf模块会递归删除目录全部文件,没有详细了解过vue-cli生成编译环境的人,就默认的采用了这种旧资源删除新资源生成。
// build.js
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
...
})
复制代码
接下来说了下,我更新的发布模式。
更新了nginx的静态文件缓存策略
nginx能够对不一样文件进行不一样的缓存策略,大体配置以下(须要注意location匹配的优先级):
location ~ .*\.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$
{
expires 7d;
}
location ~ .*\.(?:js|css)$
{
expires 7d;
}
location ~ .*\.(?:htm|html)$
{
add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
}
复制代码
而后发布的时候先将除html文件移动至发布路径,同名文件默认跳过,新生成的文件会产生新的hash,新旧文件不会冲突,共存在发布路径。
html文件的更新当时作了两种方案
由于node经验匮乏,当时第二种方案用了python写了一个服务,配置manifest.[chunkhash].js
及vendor.[chunkhash].js
,若是项目中存在首页骨架屏,那么还须要替换html文件body中的内容,用户服务进来后直接加载这个渲染后的页面。
最后的最后,被一个问题弄的有些头大,面试个人TL反复对我第一种在html中写文件名的方法提出质疑,我当时是真的有点记不清那个plugin的名字了,回到家review了一下项目,那个plugin的名称是html-webpack-plugin,这个问题大概卡了接近10分钟,不知道为何须要追问这个点,也是本身有点差劲,细节没记得那么清楚。
2.python发布
我就知道我提到了python就会被问这个问题,但没有问服务器渲染的问题,而是问了我django发布的问题,我上一个django项目是两年前的事情了,也多是第一个问题耗掉了好多经历,思绪有些切换不过来了,表述的很差。
当时只记得是wsgi+apache进行配置的,可能面试个人TL对python了解也很少,又问我这种发布模式不会形成异常中断,说python是即时编译型的语言,这种发布会不会形成异常致使服务所有宕机。我说不会的,这种模式的咱们当初采用的定时任务偶尔会挂掉,可是主服务不会的。
我可能有点被TL的思路绕进去了,表述的很差,回来总结事后有了些印象。
3.cdn
答很差什么就会一直往下问,面试若是发现状态不对的话,尽可能别被牵着鼻子走吧,这个问题我中间说错了一个环节,致使有点崩,我当时说了我当时部署的项目一部分文件是不走cdn的,可能耐心值达到红色线了,这个是答得是有歧义的。
分场景的话:
cdn的配置经验我比较少,公司的业务场景暂时没有提供cdn功能,全部的图片走的是七牛云的cdn,而服务器的css/js文件方面的cdn部署,没有相关的使用经验,面试回到家后一直在找相关的解决方案,若是你有比较好的科普性质的博文,欢迎在评论区留言。
4.项目经验,我的角色
可能前面的问题答得有些失误,为了缓和睦氛问了这个问题。由于我以前一直作公司的web前端负责人,因此这个问题聊的比较迅速。我以前的公司是刚开始是没有前端的,我算是半路出家,公司从30人发展到500人,前端团队由2我的发展到接近10我的。而后说了下我主要负责的项目,以及一些团队协做,风险评估,需求评审,代码质量保证的一些事情,可能我作的工做有点low,TL的表情反馈有些平静。
5.gzip编码协议
这个看过一些,大概就是和缓存策略同样,须要在服务器进行配置,同时须要浏览器的支持。
http {
...
gzip on; // 开启gzip
gzip_min_length 1k; // 最小1k的文件才使用gzip
gzip_buffers 4 8k; // 表明以8k为单位,按照原始数据大小以8k为单位的4倍申请内存
gzip_comp_level 5; // 1 压缩比最小处理速度最快,9 压缩比最大但处理最慢(传输快但比较消耗cpu)
gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; // 支持的文件类型
gzip_disable "MSIE [1-6]\."; // IE6一下 Gzip支持的很差,故不实用gzip
...
}
复制代码
服务器配置以后,会在浏览器请求接口后的response header的Content-Encoding字段看到gzip。
客户端请求数据时,请求头中有个Accept-Encoding声明浏览器支持的压缩方式,当客户端请求到服务端的时候,服务器解析请求头,若是客户端支持gzip压缩,响应时对请求的资源进行压缩并返回给客户端,浏览器按照本身的方式解析。
而后拓展问了下,若是传输的数据但愿后端压缩,可是算法没有声明如何启用后端算法。我就模拟了下这个流程,客户端利用header头部的自定义字段将能够容忍的压缩算法告诉服务端,服务端配置容许发送这个自定义header,逐个匹配服务器上当前的算法,匹配到则发送成功结果,没法匹配则告知客服端数据没法进行压缩,等待接下来的操做。
6.用javascript的知识介绍C++的指针
应该是看了我刚毕业的工做是嵌入式方向提出这个问题,这个问题是有点不是好类比的,由于javascript的设计缘由,跟传统的编译型语言有很大的不一样。我用的是原型链的知识解释的C++指针寻址过程,其中二级指针及三级指针的解释真的须要对两种语言理解很深刻才能回答上来。原型链的东西已经在电话一章节阐述,此处相似,再也不阐述,对C++有兴趣的话,推荐多看一下大学课本相似的书籍,干货不少。
7.高精度计时器
算是一个解决方案的问题,面试官列举了一个有赞整点抢单的业务场景,如何同步全部客户端的时间。因为setTimeout相似的计时器没法高精度还原时间,我提出的想法是利用socket保持和服务器的长连接,利用推送的模式,按期给客户端发送当前服务器时间做为校验基准,可是因为HTTP传输的时间没法保证,因此也只能尽量的同步两端的时间。
面试官又问了这个服务器推送的频率你认为大概须要多少,由于没有相关业务经验,只能按照逻辑推理,这个个人描述是当前服务器时间 = 服务器系统返回时间 + 网络传输时间 + 前端渲染时间 + 校准常量(可选)
,因此这个推送的频率采用变频的思路,就是离活动时间有一段时间,那么推送频率大概1分钟2次左右,立刻快开始就须要频繁推送了,socket性能问题须要经过不断的矫正才能达到最好的效果,可是若是想100%实现高级度的计时器,以我目前的知识面看,仍是存在不少问题的。
其实这个问题我在C++中就时间过,若是想测试超高级度的定时器,须要中间没有阻塞线程或者进程,以及防止计算机优先级较高的任务中断,这个知识涉及到操做系统的好多知识,大概就说到这。
对于这个问题我仍是很感兴趣的,由于我面试后发现不少这种活动都有这个时间偏差的问题,或大或小。若是你有过相关的业务场景,欢迎留言区分享你的思路。
8.提取最长有效数字
技术面试过程的最后感受本身可能没戏了,没想到还被问了一个现场编码的题目,大体题意以下:
Input:
'1024word'
' -1024word'
'word1024'
'10word24'
Output:
1024
-1024
0
10
程序大概写了不到5分钟吧,印象不是太深入了,代码写的有点多,能够更简单,欢迎在评论区写出你耳目一新的代码段。
function parseInt (value) {
// 输入值校验合法性
if (!value) { return 0; }
// 本需求对于空格须要剔除
let temp = value.toString().trim();
// 拦截全空字符串问题
if (temp.length === 0) {
return 0;
}
// 收集符号位
let result = temp[0] === '+' || temp[0] === '-' ? temp[0] : '';
// 设置开始索引
let i = result.length > 0 ? 1 : 0;
// 遍历,此处使用for循环为了方便中断遍历减小时间复杂度
for (;i < temp.length; i++) {
if (temp[i] >= '0' && temp[i] <= '9') {
result += temp[i]
} else {
break;
}
}
// [防爬虫标识-掘金-沙海听雨]
// 判断存在result为符号位形成Number('+')输出NaN问题
return result && (result === '+' || result === '-') ? 0 : Number(result)
}
复制代码
问了能不能换种方法实现,我想了一下,说正则提取能够作到,可是当时就给了10分钟不到的时间,就没再继续了,实际上是以前的问题把思路打乱了,一直在回忆以前没答好的问题。
[补充1.0.1]
根据评论区Akihi09
大佬的正则表达式启发,想出了一个正则表达式写法
function parseInt (val) {
if (typeof val !== 'string') { return 0; }
let match = val.toString().trim().match(/[+|-]{0,1}[0-9]*/g)[0];
if (!match) {
return 0;
}
return Number(match)
}
复制代码
[补充1.0.3]
附录评论区liuyu322
的正则表达式,
function parseInt (val) {
if (!val || typeof val !== 'string') { return 0; }
return +val.toString().replace(/^\s*([-+]?\d+)?.*$/, ($0, $1) => $1 || 0)
}
复制代码
这个表达是里面用到的概念有点多,一直没有时间更新,其中几个关键点,在此处分析一下。
^
以什么为开始
\s
匹配任意的空白符
*
只匹配出现 0 次及以上 * 前的字符
()
分组 []
匹配方括号内的任意字符
?
以前字符可选
\d
匹配数字
+
只匹配出现 1 次及以上 + 前的字符 .
匹配任意字符除了换行符和回车符(贪婪匹配)
了解这个概念应该就对上边的公式有所了解,附上一篇我认为比较好的正则匹配文章多是最好的正则表达式的教程笔记了吧
9.最后聊了一会骨架屏
好文推荐:饿了么的 PWA 升级实践
聊天内容大可能是根据这篇文章我进行的一些尝试,可是没有脱离文章的中心。
10.面试的反馈
前端方面接触面过于窄,告诉我能够多拓展一下好比React和Node的一些实践经历,其余还有一些关于职业发展的方向,比较琐碎。
原本感受结束了,总体单方面被虐,没想到TL说等一下,让hr来找我聊聊,有点意外,等了大概10分钟吧,hr小姐姐就过来进行人事面。
这个面试流程我就基本精炼一下:
hr面试让我内心有些释怀,一扫以前技术面的紧张感,出门的时候如释重负吧,算是一个小阶段的结束,为了这个面试大概准备了1个多月,后来可能太紧张又是杭州梅雨季,回到家有些低烧,都是小插曲了。
最后的最后,等了大概一周多吧,仍是没有消息,我对面试仍是特别有诚意的,想等到结果再进行下一步,就问了内推个人朋友,得知面试被淘汰了,没接到正式婉拒通知有点小意外,可能各类缘由,当个经历继续前行吧。
看了yck大大总结的前端知识点小结,在掘金应该是有掘金小册,有条件的话能够购买,我平时看成javascript基础的概括总结大纲查缺补漏,有好多点都有被问到。
yuchengkai.cn/docs/fronte…
还有一本书挺好的,《你不知道的javascript》一共分3册,有些点描述的挺深入的,是个常读常新的好书。
其余就是多看多总结,每一个开发者都有个本身的小知识库吧,我大多都是写在云笔记里面了,最近打算整理一下不按期发布出来。
这方面的话没有过多的准备,基本都是平时移动端+PC端开发过程当中实际编码的经验,但有一些点不是太好钻进去,在这里简单说下。
css动画效果,这个彻底看本身平时的业务场景,也可能看一些源码库,推荐animate.css这个开源库,很经典代码结构也很清晰
github.com/daneden/ani…
关于webGL这方面的知识,这个真的随缘,有过相关业务的话,面试过程应该不至于冷场想要突击的话,不是太适合。
另外css3有本书也不错,《css揭秘》,可能当字典看。特别基础的css知识,推荐MDN或者一些写的比较好的文档了。
看源码,看开源社区,有不少优质的文章值得花费时间去阅读。
这里写一个个人一个小技巧吧,由于以前写后段比较多,并且调试的经验也超级多,一直想能不能前端代码调整也能那么智能一些,还真被我找到了一个小技巧。
WebStrom对Karma单体测试支持特别好,能够看到临时变量以及代码段步入,对框架源码某处不懂,写一个小的测试用例提升测试覆盖率,就能很容易的理解源码中晦涩难懂的一些代码段了,上一张截图,用了都说好。
// 首先定义一个xxx.spec.js
// [防爬虫标识-掘金-沙海听雨]
import Vue from 'vue'
describe('dom render', () => {
it('render a easy template', () => {
const el = document.createElement('div')
el.setAttribute('id', 'app')
el.innerHTML = '<span>{{message}}</span>'
document.body.appendChild(el)
const vm = new Vue({
data: { message: 'Hello Vue!' },
el: '#app',
template: `<div id="app">{{ message }}</div>`
})
})
})
复制代码
这方面总结的东西比较多,推荐从本身的简历经验上多提炼一下,在掘金上看到一篇文章比较好,大型项目前端架构浅谈能够在里面找到一些启发,并从你的项目经历中提炼出一些关键点。
经历了完整的大企业面试算是对本身的一个自我认知的过程,虽然中间经历仍是比较曲折的,可是算是成长吧,今年逆形式找工做仍是有些吃力的,可是仍是期待大公司的工做机会吧。
若是你以为本文对你有些许的帮助,或者能博您深思,别忘点个赞加个关注或是留下你的见解和看法。
同时期待能与您共事,欢迎并期待从新出发的机会,简历的话欢迎留下您的邮箱索取。
辛苦阅读本文
以上
沙海听雨(Wordsworth)
参考文章:
[1] InterviewMap-yck yuchengkai.cn/docs/fronte…
[2] HTTP强缓存和协商缓存-puhongru segmentfault.com/a/119000000…