JavaScript
-
js的基本类型有哪些?引用类型有哪些?null和undefined的区别。
-
如何判断一个变量是Array类型?如何判断一个变量是Number类型?(都不止一种)
-
Object是引用类型嘛?引用类型和基本类型有什么区别?哪个是存在堆哪一个是存在栈上面的?
-
JS常见的dom操作api
-
解释一下事件冒泡和事件捕获
-
事件委托(手写例子),事件冒泡和捕获,如何阻止冒泡?如何组织默认事件?
-
对闭包的理解?什么时候构成闭包?闭包的实现方法?闭包的优缺点?
-
this有哪些使用场景?跟C,Java中的this有什么区别?如何改变this的值?
-
call,apply,bind
-
显示原型和隐式原型,手绘原型链,原型链是什么?为什么要有原型链
-
创建对象的多种方式
-
实现继承的多种方式和优缺点
-
new 一个对象具体做了什么
-
手写Ajax,XMLHttpRequest
-
变量提升
-
举例说明一个匿名函数的典型用例
-
指出JS的宿主对象和原生对象的区别,为什么扩展JS内置对象不是好的做法?有哪些内置对象和内置函数?
-
attribute和property的区别
-
document load和document DOMContentLoaded两个事件的区别
-
JS代码调试
-
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
(具体可以看我的这篇文章:JSONP原理及实现:https://www.jianshu.com/p/88bb82718517)
2. 浏览器为什么要跨域?如果是因为安全的话那小程序或者其他的为什么没有跨域?
跨域的产生来源于现代浏览器所通用的同源策略
,所谓同源策略,是指只有在地址的:
-
协议名
-
域名
-
端口名
均一样的情况下,才允许访问相同的cookie、localStorage,以及访问页面的DOM
或是发送Ajax
请求。若在不同源的情况下访问,就称为跨域。
例如以下为同源:
http://www.example.com:8080/index.html
http://www.example.com:8080/home.html
以下为跨域:
http://www.example.com:8080/index.html
http://www3.example.com:8080/index.html
注意⚠️:
但是有两种情况:http
默认的端口号为80
,https
默认端口号为443
。
所以:
http://www.example.com:80 === http://www.example.com
https://www.example.com:443 === https://www.example.com
「为什么浏览器会禁止跨域?」
「简答」:
首先,跨域只存在于浏览器端,因为我们知道浏览器的形态是很开放的,所以我们需要对它有所限制。
其次,同源策略主要是为了保证用户信息的安全,可分为两种:Ajax
同源策略和DOM
同源策略。
Ajax
同源策略主要是使得不同源的页面不能获取cookie
且不能发起Ajax
请求,这样在一定程度上防止了CSRF
攻击。
DOM
同源策略也一样,它限制了不同源页面不能获取DOM
,这样可以防止一些恶意网站在自己的网站中利用iframe
嵌入正规的网站并迷惑用户,以此来达到窃取用户信息。
「深答」:
-
首先,跨域只存在于浏览器端。浏览器它为
web
提供了访问入口,并且访问的方式很简单,在地址栏输入要访问的地址或者点击某个链接就可以了,正是这种**「开放的形态」**,所以我们需要对它有所限制。 -
所以同源策略它的产生主要是为了保证用户信息的安全,防止恶意的网站窃取数据。分为两种:
Ajax
同源策略与DOM
同源策略:
同源策略它算是浏览器安全的第一层屏障吧,因为就像CSRF
攻击,它只能限制不同源页面cookie
的获取,但是攻击者还可能通过其它的方式来达到攻击效果。
(注,上面提到的iframe
限制DOM
查询,案例如下)
// HTML
// JS
// 由于没有同源策略的限制,钓鱼网站可以直接拿到别的网站的Dom
const iframe = window.frames[‘yinhang’]
const node = iframe.document.getElementById(‘你输入账号密码的Input’)
console.log(拿到了这个${node},我还拿不到你刚刚输入的账号密码吗
)
-
Ajax
同源策略它主要做了这两种限制:1.不同源页面不能获取cookie
;2.不同源页面不能发起Ajax
请求。我认为它是防止CSRF
攻击的一种方式吧。因为我们知道cookie
这个东西它主要是为了解决浏览器与服务器会话状态的问题,它本质上是存储在浏览器或本地文件中一个小小的文本文件,那么它里面一般都会存储了用户的一些信息,包括隐私信息。如果没有Ajax
同源策略,恶意网站只需要一段脚本就可以获取你的cookie
,从而冒充你的身份去给其它网站发送恶意的请求。
-
DOM
同源策略也一样,它限制了不同源页面不能获取DOM
。例如一个假的网站利用iframe
嵌套了一个银行网站mybank.com,并把宽高或者其它部分调整的和原银行网站一样,仅仅只是地址栏上的域名不同,若是用户没有注意的话就以为这个是个真的网站。如果这时候用户在里面输入了账号密码,如果没有同源策略,那么这个恶意网站就可以获取到银行网站中的DOM
,也就能拿到用户的输入内容以此来达到窃取用户信息的攻击。
参考:
-
https://segmentfault.com/a/1190000015597029
-
https://juejin.im/post/5cad99796fb9a068ab40a29a
3. CORS跨域的原理
跨域资源共享(CORS
)是一种机制,是W3C标准。它允许浏览器向跨源服务器,发出XMLHttpRequest
或Fetch
请求。并且整个CORS
通信过程都是浏览器自动完成的,不需要用户参与。
而使用这种跨域资源共享
的前提是,浏览器必须支持这个功能,并且服务器端也必须同意这种"跨域"
请求。因此实现CORS
的关键是服务器需要服务器。通常是有以下几个配置:
-
「Access-Control-Allow-Origin」
-
「Access-Control-Allow-Methods」
-
「Access-Control-Allow-Headers」
-
「Access-Control-Allow-Credentials」
-
「Access-Control-Max-Age」
具体可看:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
过程分析:
「简单回答」:
-
当我们发起跨域请求时,「如果是非简单请求」,浏览器会帮我们自动触发预检请求,也就是 OPTIONS 请求,用于确认目标资源是否支持跨域。「如果是简单请求,则不会触发预检,直接发出正常请求。」
-
浏览器会根据服务端响应的 header 自动处理剩余的请求,如果响应支持跨域,则继续发出正常请求,如果不支持,则在控制台显示错误。
「详细回答」:
-
浏览器先根据同源策略对前端页面和后台交互地址做匹配,若同源,则直接发送数据请求;若不同源,则发送跨域请求。
-
服务器收到浏览器跨域请求后,根据自身配置返回对应文件头。若未配置过任何允许跨域,则文件头里不包含
Access-Control-Allow-origin
字段,若配置过域名,则返回Access-Control-Allow-origin + 对应配置规则里的域名的方式
。 -
浏览器根据接受到的 响应头里的
Access-Control-Allow-origin
字段做匹配,若无该字段,说明不允许跨域,从而抛出一个错误;若有该字段,则对字段内容和当前域名做比对,如果同源,则说明可以跨域,浏览器接受该响应;若不同源,则说明该域名不可跨域,浏览器不接受该响应,并抛出一个错误。
在CORS
中有简单请求
和非简单请求
,简单请求是不会触发CORS
的预检请求的,而非简单请求会。
“需预检的请求”
要求必须首先使用 OPTIONS
方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
(关于更多CORS的内容可以看我的另一篇文章:CORS原理及实现:https://www.jianshu.com/p/b2bdf55e1bf5)
4. CORS预请求OPTIONS就一定是安全的吗?
5. 在深圳的网页上输入百度,是怎么把这个请求发到北京的
这个当时面试官和我说的是,中间会经过很多的站点,比如会经过湖南,或者其它城市,由各个城市的这些站点一层一层分发下去。
6. 输入URL到页面的呈现
7. Vue的响应式原理
8. 那在这个响应式中一个数据改变它是怎么通知要更新的,也就是如何把数据和页面关联起来?
面的最惨的一次…因为这次面试是当天下午6点才去面的,在这之前呆呆已经经过了3轮面试的折磨,所以身心疲惫很不在状态。当然最主要的是自己确实准备的还不够充分,其实现在回过头来看看这些题都不太难的…
当天也小小的自闭了一下,整理好状态第二天好好总结吧 ???。
深圳某海外直播公司
4月28日
(当时是电话面,一个小时20分钟,问了我大概五六十道题,我能想到的一共是50题,还有一些记不起来了)
1. CommonJS和ES6模块的区别
-
CommonJS模块是运行时加载,ES6 Modules是编译时输出接口
-
CommonJS输出是值的拷贝;ES6 Modules输出的是值的引用,被输出模块的内部的改变会影响引用的改变
-
CommonJs导入的模块路径可以是一个表达式,因为它使用的是
require()
方法;而ES6 Modules只能是字符串 -
CommonJS
this
指向当前模块,ES6 Modulesthis
指向undefined
-
且ES6 Modules中没有这些顶层变量:
arguments
、require
、module
、exports
、__filename
、__dirname
关于第一个差异,是因为CommonJS 加载的是一个对象(即module.exports
属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。
(具体可以看我的这篇文章:https://juejin.im/post/5eaacd175188256d4345ea3a)
2. 模块的异步加载
模块的异步加载可以使用AMD
或者CMD
规范。
(具体可以看我的这篇文章:https://juejin.im/post/5eaacd175188256d4345ea3a)
3. 开发一个模块要考虑哪些问题?
封闭开放式原则、安全性
(应该还有,但是没想到)
4. 实现一个一组异步请求按顺序执行你有哪些方法?
-
利用
reduce
,初始值传入一个Promise.resolve()
,之后往里面不停的叠加.then()
。(类似于这里https://juejin.im/post/5e58c618e51d4526ed66b5cf#heading-51) -
利用
forEach
,本质和reduce
原理相同。(类似于这里https://juejin.im/post/5e58c618e51d4526ed66b5cf#heading-53) -
还可以用
ES9
中的for...await...of
来实现。
5. Promise.all()是并发的还是串行的?
并发的。不过Promise.all().then()
结果中数组的顺序和Promise.all()
接收到的数组顺序一致。
6. 平时写过哪些正则表达式
-
之前有用过用正则去除输入框的首尾空格,正则表达式为:
var trimReg = /(^\s+)|(\s+$)/g
;不过后来由于Vue
中有一个修饰符.trim
,使用起来更方便(如v-model.trim="msg"
)就用这种方式多一些;再或者也可以用ES10
新出的trimStart
和trimEnd
来去除首尾空格。 -
用于校验手机号的正则:
var phoneReg = /^1[3456789]\d{9}$/g
。 -
用正则写一个根据name获取cookie中的值的方法:
function getCookie(name) {
var match = document.cookie.match(new RegExp(‘(^| )’ + name + ‘=([^;]*)’));
if (match) return unescape(match[2]);
}
详细介绍可以看这里:每日一题-JS篇-根据name获取cookie中值的方法:https://github.com/LinDaiDai/niubility-coding-js/blob/master/%E6%AF%8F%E6%97%A5%E4%B8%80%E9%A2%98/%E6%AF%8F%E6%97%A5%E4%B8%80%E9%A2%98-JS%E7%AF%87.md#%E7%94%A8%E6%AD%A3%E5%88%99%E5%86%99%E4%B8%80%E4%B8%AA%E6%A0%B9%E6%8D%AEname%E8%8E%B7%E5%8F%96cookie%E4%B8%AD%E7%9A%84%E5%80%BC%E7%9A%84%E6%96%B9%E6%B3%95
7. 正则里的非如何实现的
^
要是放在[]
里的话就表示"除了^后面的内容都能匹配"
,也就是非的意思。
例如:
(除了l
,其它都变成了"帅"
)
var str = ‘lindaidai’;
console.log(str.replace(/[^l]/g, ‘帅’));
// l帅帅帅帅帅帅帅帅
反之,如果是不在[]
里的话则表示开头匹配:
(只有l
变成了"帅"
)
var str = ‘lindaidai’;
console.log(str.replace(/^l/g, ‘帅’));
8. webpack几种hash的实现原理
-
hash
是跟整个项目的构建相关,只要项目里有文件更改,整个项目构建的hash
值都会更改,并且全部文件都共用相同的hash
值。(粒度整个项目) -
chunkhash
是根据不同的入口进行依赖文件解析,构建对应的chunk
(模块),生成对应的hash
值。只有被修改的chunk
(模块)在重新构建之后才会生成新的hash
值,不会影响其它的chunk
。(粒度entry
的每个入口文件) -
contenthash
是跟每个生成的文件有关,每个文件都有一个唯一的hash
值。当要构建的文件内容发生改变时,就会生成新的hash
值,且该文件的改变并不会影响和它同一个模块下的其它文件。(粒度每个文件的内容)
(具体可以看我简书上的这篇文章:https://www.jianshu.com/p/486453d81088)
这里只是说明了三种hash
的不同…至于原理暂时没了解。
9. webpack如果使用了hash命名,那是每次都会重写生成hash吗
这个问题在上一个问题中已经说明了,要看webpack
的配置。
有三种情况:
-
如果是
hash
的话,是和整个项目有关的,有一处文件发生更改则所有文件的hash
值都会发生改变且它们共用一个hash
值; -
如果是
chunkhash
的话,只和entry
的每个入口文件有关,也就是同一个chunk
下的文件有所改动该chunk
下的文件的hash
值就会发生改变 -
如果是
contenthash
的话,和每个生成的文件有关,只有当要构建的文件内容发生改变时才会给该文件生成新的hash
值,并不会影响其它文件。
10. webpack中如何处理图片的?
在webpack
中有两种处理图片的loader
:
-
file-loader
:解决CSS
等中引入图片的路径问题;(解决通过url
,import/require()
等引入图片的问题) -
url-loader
:当图片小于设置的limit
参数值时,url-loader
将图片进行base64
编码(当项目中有很多图片,通过url-loader
进行base64
编码后会减少http
请求数量,提高性能),大于limit参数值,则使用file-loader
拷贝图片并输出到编译目录中;
详细使用可以查看这里:霖呆呆的webpack之路-loader篇:https://github.com/LinDaiDai/niubility-coding-js/blob/master/%E5%89%8D%E7%AB%AF%E5%B7%A5%E7%A8%8B%E5%8C%96/webpack/%E9%9C%96%E5%91%86%E5%91%86%E7%9A%84webpack%E4%B9%8B%E8%B7%AF-loader%E7%AF%87.md#file-loader
11. 说一下回流和重绘
「回流」:
触发条件:
当我们对 DOM 结构的修改引发 DOM 几何尺寸变化的时候,会发生回流
的过程。
例如以下操作会触发回流:
-
一个 DOM 元素的几何属性变化,常见的几何属性有
width
、height
、padding
、margin
、left
、top
、border
等等, 这个很好理解。 -
使 DOM 节点发生
增减
或者移动
。 -
读写
offset
族、scroll
族和client
族属性的时候,浏览器为了获取这些值,需要进行回流操作。 -
调用
window.getComputedStyle
方法。
回流过程:由于DOM的结构发生了改变,所以需要从生成DOM这一步开始,重新经过样式计算
、生成布局树
、建立图层树
、再到生成绘制列表
以及之后的显示器显示这整一个渲染过程走一遍,开销是非常大的。
「重绘」:
触发条件:
当 DOM 的修改导致了样式的变化,并且没有影响几何属性的时候,会导致重绘
(repaint
)。
重绘过程:由于没有导致 DOM 几何属性的变化,因此元素的位置信息不需要更新,所以当发生重绘的时候,会跳过生存布局树
和建立图层树
的阶段,直接到生成绘制列表
,然后继续进行分块、生成位图等后面一系列操作。
「如何避免触发回流和重绘」:
-
避免频繁使用 style,而是采用修改
class
的方式。 -
将动画效果应用到
position
属性为absolute
或fixed
的元素上。 -
也可以先为元素设置
display: none
,操作结束后再把它显示出来。因为在display
属性为none
的元素上进行的DOM操作不会引发回流和重绘 -
使用
createDocumentFragment
进行批量的 DOM 操作。 -
对于 resize、scroll 等进行防抖/节流处理。
-
避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
-
利用 CSS3 的
transform
、opacity
、filter
这些属性可以实现合成的效果,也就是CPU
加速。
参考来源:https://juejin.im/post/5df5bcea6fb9a016091def69#heading-57
12. 盒模型及如何转换
box-sizing: content-box
(W3C盒模型,又名标准盒模型):元素的宽高大小表现为内容的大小。
box-sizing: border-box
(IE盒模型,又名怪异盒模型):元素的宽高表现为内容 + 内边距 + 边框的大小。背景会延伸到边框的外沿。
13. 实现水平垂直居中的几种方式
这里我是按照子弈的总结答的:https://juejin.im/post/5d690c726fb9a06b155dd40d#heading-81
- Flex布局(子元素是块级元素)
.box {
display: flex;
width: 100px;
height: 100px;
background-color: pink;
}
.box-center{
margin: auto;
background-color: greenyellow;
}
- Flex布局
.box {
display: flex;
width: 100px;
height: 100px;
background-color: pink;
justify-content: center;
align-items: center;
}
.box-center{
background-color: greenyellow;
}
- 绝对定位实现(定位元素定宽定高)
.box {
position: relative;
height: 100px;
width: 100px;
background-color: pink;
}
.box-center{
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
width: 50px;
height: 50px;
background-color: greenyellow;
}
14. flex的兼容性怎样
「简单回答:」
IE6~9
不支持,IE10~11
部分支持flex的2012版
,但是需要-ms-
前缀。
其它的主流浏览器包括安卓和IOS
基本上都支持了。
「详细回答:」
-
IE10部分支持2012,需要-ms-前缀
-
Android4.1/4.2-4.3部分支持2009 ,需要-webkit-前缀
-
Safari7/7.1/8部分支持2012, 需要-webkit-前缀
-
IOS Safari7.0-7.1/8.1-8.3部分支持2012,需要-webkit-前缀
15. 你知道到哪里查看兼容性吗
可以到Can I use
上去查看,官网地址为:https://caniuse.com/
16. 移动端中css你是使用什么单位
「比较常用的」:
-
em
:定义字体大小时以父级的字体大小为基准;定义长度单位时以当前字体大小为基准。例父级font-size: 14px
,则子级font-size: 1em;
为font-size: 14px;
;若定义长度时,子级的字体大小如果为14px
,则子级width: 2em;
为width: 24px
。 -
rem
:以根元素的字体大小为基准。例如html
的font-size: 14px
,则子级1rem = 14px
。 -
%
:以父级的宽度为基准。例父级width: 200px
,则子级width: 50%;height:50%;
为width: 100px;height: 100px;
-
vw和vh
:基于视口的宽度和高度(视口不包括浏览器的地址栏工具栏和状态栏)。例如视口宽度为1000px
,则60vw = 600px;
-
vmin和vmax
:vmin
为当前vw
和vh
中较小的一个值;vmax
为较大的一个值。例如视口宽度375px
,视口高度812px
,则100vmin = 375px;
,100vmax = 812px;
「不常用的:」
ex和ch
:ex
以字符"x"
的高度为基准;例如1ex
表示和字符"x"
一样长。ch
以数字"0"
的宽度为基准;例如2ch
表示和2个数字"0"
一样长。
「移动端布局总结」:
-
移动端布局的方式主要使用rem和flex,可以结合各自的优点,比如flex布局很灵活,但是字体的大小不好控制,我们可以使用rem和媒体查询控制字体的大小,媒体查询视口的大小,然后不同的上视口大小下设置设置html的font-size。
-
可单独制作移动端页面也可响应式pc端移动端共用一个页面。没有好坏,视情况而定,因势利导
(总结来源:玲珑)
17. rem和em的区别
「em:」
定义字体大小时以父级的字体大小为基准;定义长度单位时以当前字体大小为基准。例父级font-size: 14px
,则子级font-size: 1em;
为font-size: 14px;
;若定义长度时,子级的字体大小如果为14px
,则子级width: 2em;
为width: 24px
。
「rem:」
以根元素的字体大小为基准。例如html
的font-size: 14px
,则子级1rem = 14px
。
18. 在移动端中怎样初始化根元素的字体大小
一个简易版的初始化根元素字体大小。
页面开头处引入下面这段代码,用于动态计算font-size
:
(假设你需要的1rem = 20px
)
(function () {
var html = document.documentElement;
function onWindowResize() {
html.style.fontSize = html.getBoundingClientRect().width / 20 + ‘px’;
}
window.addEventListener(‘resize’, onWindowResize);
onWindowResize();
})();
-
document.documentElement
:获取document
的根元素 -
html.getBoundingClientRect().width
:获取html
的宽度(窗口的宽度) -
监听
window
的resize
事件
一般还需要配合一个meta
头:
19. 移动端中不同手机html默认的字体大小都是一样的吗
如果没有人为去改变根元素字体大小的话,默认是1rem = 16px
;根元素默认的字体大小是16px
。
20. 你做过哪些动画效果
实话实说没太做过。
21. 如果让你实现一个一直旋转的动画你会如何做
css代码:
html代码:
22. animation介绍一下
语法:
animation: name duration timing-function delay iteration-count direction;
| 值 | 描述 |
| — | — |
| animation-name | 规定需要绑定到选择器的 keyframe 名称。(mymove) |
| animation-duration | 规定完成动画所花费的时间,以秒或毫秒计。(2s) |
| animation-timing-function | 规定动画的速度曲线。(ease|linear|ease-in|cubic-bezier(n,n,n,n)) |
| animation-delay | 规定在动画开始之前的延迟。(2s) |
| animation-iteration-count | 规定动画应该播放的次数。(n | infinite) n次/无限 |
| animation-direction | 规定是否应该轮流反向播放动画。(normal | alternate) 正常/反向 |
23. animation有一个steps()功能符知道吗?
一句话介绍:steps()
功能符可以让动画不连续。
地位和作用:和贝塞尔曲线(cubic-bezier()
修饰符)一样,都可以作为animation
的第三个属性值。
和贝塞尔曲线的区别:贝塞尔曲线像是滑梯且有4个关键字(参数),而steps
像是楼梯坡道且只有number
和position
两个关键字。
语法:
steps(number, position)
-
number: 数值,表示把动画分成了多少段
-
position: 表示动画是从时间段的开头连续还是末尾连续。支持
start
和end
两个关键字,含义分别如下: -
start
:表示直接开始。
-
end
:表示戛然而止。是默认值。
具体可以看这里:https://www.zhangxinxu.com/wordpress/2018/06/css3-animation-steps-step-start-end/
24. 用过哪些移动端的调试工具
-
Chrome
浏览器 ->more tools
->Remote devices
->chrome://inspect/#devices
-
Mac
+IOS
+Safari
25. 说一下原型链
26. 详细说一下instanceof
27. V8的垃圾回收是发生在什么时候?
V8引擎帮助我们实现了自动的垃圾回收管理,「利用浏览器渲染页面的空闲时间进行垃圾回收。」
28. 具体说一下垃圾回收机制
(这里我用的是:https://juejin.im/post/5e8b261ae51d4546c0382ab4#heading-20 里的总结)
「栈内存的回收:」
栈内存调用栈上下文切换后就被回收,比较简单。
「堆内存的回收:」
V8的堆内存分为新生代内存和老生代内存,新生代内存是临时分配的内存,存在时间短,老生代内存存在时间长。
新生代内存回收机制:
- 新生代内存容量小,64位系统下仅有32M。新生代内存分为**「From、To」**两部分,进行垃圾回收时,先扫描From,将非存活对象回收,将存活对象顺序复制到To中,之后调换From/To,等待下一次回收
老生代内存回收机制
-
「晋升」:如果新生代的变量经过多次回收依然存在,那么就会被放入老生代内存中
-
「标记清除」:老生代内存会先遍历所有对象并打上标记,然后对正在使用或被强引用的对象取消标记,回收被标记的对象
-
「整理内存碎片」:把对象挪到内存的一端
(当然想要详细了解的话也可以看我的这篇文章:JavaScript进阶-内存机制(表情包初探))
29. 在项目中如何把http的请求换成https
由于我在项目中是会对axios
做一层封装,所以每次请求的域名也是写在配置文件中,有一个baseURL
字段专门用于存储它,所以只要改这个字段就可以达到替换所有请求http
为https
了。
当然后面我也有了解到:
利用meta
标签把http
请求换为https
:
30. 知道meta标签有把http换成https的功能吗?
参考上一题???。
31. http请求可以怎么拦截
在浏览器和服务器进行传输的时候,可以被nginx
代理所拦截,也可以被网关拦截。
32. https的加密方式
HTTPS主要是采用对称密钥加密和非对称密钥加密组合而成的混合加密机制进行传输。
也就是发送密文的一方用"对方的公钥"进行加密处理"对称的密钥",然后对方在收到之后使用自己的私钥进行解密得到"对称的密钥",这在确保双发交换的密钥是安全的前提下使用对称密钥方式进行通信。
33. 混合加密的好处
对称密钥加密和非对称密钥加密都有它们各种的优缺点,而混合加密机制就是将两者结合利用它们各自的优点来进行加密传输。
比如既然对称密钥的优点是加解密效率快,那么在客户端与服务端确定了连接之后就可以用它来进行加密传输。不过前提是得解决双方都能安全的拿到这把对称密钥。这时候就可以利用非对称密钥加密来传输这把对称密钥,因为我们知道非对称密钥加密的优点就是能保证传输的内容是安全的。
所以它的好处是即保证了对称密钥能在双方之间安全的传输,又能使用对称加密方式进行通信,这比单纯的使用非对称加密通信快了很多。以此来解决了HTTP中内容可能被窃听的问题。
其它HTTP相关的问题:
如:
-
HTTPS的工作流程
-
混合加密机制的好处
-
数字签名
-
ECDHE握手和RSA握手
-
向前安全性
这些问题都可以看到我的这篇文章:HTTPS面试问答:https://github.com/LinDaiDai/niubility-coding-js/blob/master/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/HTTPS%E9%9D%A2%E8%AF%95%E9%97%AE%E7%AD%94.md
34. 浏览器如何验证服务器的身份
这道题主要可以从数字签名
和数字证书
上来答。
当时我答的时候就把证书的颁发流程
、HTTPS
数字证书的验证过程完整的说了一遍就算过了。
具体可以看「HTTPS面试」???问答中的第5、6、7
问。
35. ETag首部字段说一下
这个无非就是配合If-None-Match
来达到一个协商缓存
的作用。值为服务器某个资源的唯一标识。
具体可以看我的这篇文章:霖呆呆你来说说浏览器缓存吧
36. 你们的token一般是存放在哪里的
Token
其实就是**「访问资源的凭证」**。
一般是用户通过用户名和密码登录成功之后,服务器将登陆凭证做数字签名,加密之后得到的字符串作为token
。
它在用户登录成功之后会返回给客户端,客户端主要有这么几种存储方式:
-
存储在
localStorage
中,每次调用接口的时候都把它当成一个字段传给后台 -
存储在
cookie
中,让它自动发送,不过缺点就是不能跨域 -
拿到之后存储在
localStorage
中,每次调用接口的时候放在HTTP
请求头的Authorization
字段里
(很明显我答的不够专业,欢迎补充,感谢???)
37. token会不会被伪造?
(很明显我答的不够专业,欢迎补充,感谢???)
38. redis中一般用来存什么
用户登录成功之后的一些信息
(很明显我答的不够专业,欢迎补充,感谢???)
39. 前后端如何验证一个用户是否下线了
(很明显我答的不够专业,欢迎补充,感谢???)
40. CSP白名单知道吗?
(很明显我答的不够专业,欢迎补充,感谢???)
41. nginx有配置过吗?
只会配置一些跨域方面的问题。
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://localhost:8887;
add_header Access-Control-Allow-Origin *;
}
}
}
利用ngnix跨域的关键就是在配置文件中设置server
项,然后设置其中的location
属性,proxy_pass
:需要代理的服务器地址,add_header:给响应报文中添加首部字段,例如Access-Control-Allow-Origin
设置为*
,即允许所有的请求源请求。
具体可以看:Yiming君-面试题:nginx有配置过吗?反向代理知道吗?
https://juejin.im/post/5eb0f8aaf265da7ba65f7ba2
42. 反向代理知道吗?
我们将请求发送到服务器,然后服务器对我们的请求进行转发,我们只需要和代理服务器进行通信就好。所以对于客户端来说,是感知不到服务器的。
43. 有用过抓包工具吗?
唔…没有…
44. 你平常用的电脑是Mac吗?
(…在电话那头默默的点头)
45. Fiddler有用过吗?
唔…知道…
46. Vue的diff算法
这里我是按照:
https://mp.weixin.qq.com/s/2xyP4jVevuXrGov_VsWfvA
中的第13题答的。
47. Vue中computed和methods的区别
48. 例如要获取当前时间你会放到computed还是methods里?
放在methods
中,因为computed
会有惰性,并不能知道new Date()
的改变。
49. 你们的权限功能是怎么做的?
小小的写了一篇文章,可以看这里:数据权限如何控制
https://github.com/LinDaiDai/niubility-coding-js/blob/master/other/%E6%95%B0%E6%8D%AE%E6%9D%83%E9%99%90%E5%A6%82%E4%BD%95%E6%8E%A7%E5%88%B6.md
50. 那你在判断权限的时候是用的字符串匹配还是位运算?
和面试官扯了一堆我数据权限判断的具体过程,其中可能有多个权限:并的情况000011110001&000011110002
,或的情况000011110001|000011110002
,以及如何做的权限匹配。最后面试官:
"所以那还是用的字符串匹配咯?"
尬…我比较low
…用的字符串匹配…
(哇,真的绝了…1个小时20分钟50多道题,答的我口渴???,不过也可以看出有很多移动端的我都没有答上来,面试官也表示理解,毕竟我主要是以PC端为主,所以竟然也算是过了,很感谢这位面试官细心的帮我分析一些问题)
后来有了解这位面试官近期也跳槽去腾讯了,果然面完呆呆之后他就去大厂了,好人一生平安???。
深圳某国内直播公司
这家公司其实是上家公司的总部,因为面完上家之后,HR也知道我的顾虑,想要去一个大点的团队,所以就把我推荐去了他们的总部。非常Nice的HR小姐姐,好感动,就算你看不到我的文章,我也还是要感谢你 ???。
5月8日
一面(前端副总监)
1. 输入URL到页面呈现
(必问…)
看三元的《(1.6w字)浏览器灵魂之问,请问你能接得住几个?》
https://juejin.im/post/5df5bcea6fb9a016091def69
分别从网络,解析,渲染来说
2. 为什么说script标签建议放在body下面?
JS
代码在加载完之后是立即执行的,且JS
代码执行时会阻塞页面的渲染。
3. 为什么说script标签会阻塞页面的渲染呢?渲染线程和js引擎线程不是分开的吗?
JS属于单线程,当我们在加载script
标签内容的时候,渲染线程会被暂停,因为script
标签里可能会操作DOM
的,所以如果你加载script
标签又同时渲染页面肯定就冲突了,因此说渲染线程(GUI
)和js引擎线程互斥。
4. 协商缓存说一下
Last-Modefied
配合If-Modified-Since
ETag
配合If-None-Match
也是个常见的问题了,不了解的小伙伴可以看我的这篇文章:霖呆呆你来说说浏览器缓存吧
(当时面试官还重复了一下我说的这4个头部字段,自己回顾了一下我说的对不对,好可爱~)
5. HTTP中的Keep-Alive有了解过吗?
Keep-Alive
是HTTP
的一个头部字段Connection
中的一个值,它是保证我们的HTTP
请求能建立一个持久连接。也就是说建立一次TCP
连接即可进行多次请求和响应的交互。它的特点就是只要有一方没有明确的提出断开连接,则保持TCP
连接状态,减少了TCP
连接和断开造成的额外开销。
另外,在HTTP/1.1
中所有的连接默认都是持久连接的,但是HTTP/1.0
并未标准化。
6. 跨域有了解吗?如何解决跨域?
我工作中碰到主要是利用CORS
来解决跨域问题,说了一下它的原理以及后台需要如何做。
另外说到了JSONP
的原理,以及它的优点:兼容性好;缺点:只能进行GET
请求,且有安全问题。
还有说到了ngnix
反向代理来解决跨域。
-
CORS原理及实现:https://www.jianshu.com/p/b2bdf55e1bf5
-
JSONP原理及实现:https://www.jianshu.com/p/88bb82718517
-
面试题:nginx有配置过吗?反向代理知道吗?:https://juejin.im/post/5eb0f8aaf265da7ba65f7ba2
其它的,我当时说我有看过一篇文章里面详细的介绍10多种跨域解决方案,但是自己没有过多的去了解。
哈哈,其实也就是秋风大大的这篇文章10种跨域解决方案(附终极大招)
7. WebSocket有了解过吗?它也可以跨域的
这个当时答的没用过。
我知道它是能使得客户端和服务器之间存在持久的连接,而且双方都可以随时开始发送数据,这种方式本质没有使用 HTTP 的响应头,因此也没有跨域的限制。
(多的不会了)
8. 前端安全方面?XSS?CSRF?
(必问…)
(以下回答参考子弈小哥哥的面试分享:两年工作经验成功面试阿里P6总结:https://juejin.im/post/5d690c726fb9a06b155dd40d#heading-60
以及蔡徐坤小哥哥的2万字 | 前端基础拾遗90问:https://juejin.im/post/5e8b261ae51d4546c0382ab4#heading-48
「XSS」
XSS(Cross Site Script)跨站脚本攻击。指的是攻击者向网页注入恶意的客户端代码,通过恶意的脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式。
主要是分为三种:
「存储型」:即攻击被存储在服务端,常见的是在评论区插入攻击脚本,如果脚本被储存到服务端,那么所有看见对应评论的用户都会受到攻击。
「反射型」:攻击者将脚本混在URL里,服务端接收到URL将恶意代码当做参数取出并拼接在HTML里返回,浏览器解析此HTML后即执行恶意代码
「DOM型」:将攻击脚本写在URL中,诱导用户点击该URL,如果URL被解析,那么攻击脚本就会被运行。和前两者的差别主要在于DOM型攻击不经过服务端
如何防御XSS攻击
-
「输入检查」:对输入内容中的
script
和<iframe>
等标签进行转义或者过滤 -
「设置httpOnly」:很多XSS攻击目标都是窃取用户cookie伪造身份认证,设置此属性可防止JS获取cookie
-
「开启CSP」,即开启白名单,可阻止白名单以外的资源加载和运行
「CSRF」
CSRF攻击(Cross-site request forgery)跨站请求伪造。是一种劫持受信任用户向服务器发送非预期请求的攻击方式,通常情况下,它是攻击者借助受害者的 Cookie 骗取服务器的信任,但是它并不能拿到Cookie,也看不到Cookie的内容,它能做的就是给服务器发送请求,然后执行请求中所描述的命令,以此来改变服务器中的数据,也就是并不能窃取服务器中的数据。
防御主要有三种:
验证Token
:浏览器请求服务器时,服务器返回一个token,每个请求都需要同时带上token和cookie才会被认为是合法请求
验证Referer
:通过验证请求头的Referer来验证来源站点,但请求头很容易伪造
设置SameSite
:设置cookie的SameSite,可以让cookie不随跨站请求发出,但浏览器兼容不一
「点击挟持」
-
诱使用户点击看似无害的按钮(实则点击了透明 iframe 中的按钮).
-
监听鼠标移动事件,让危险按钮始终在鼠标下方.
-
使用 HTML5 拖拽技术执行敏感操作(例如 deploy key).
预防策略:
-
服务端添加 X-Frame-Options 响应头,这个 HTTP 响应头是为了防御用 iframe 嵌套的点击劫持攻击。这样浏览器就会阻止嵌入网页的渲染。
-
JS 判断顶层视口的域名是不是和本页面的域名一致,不一致则不允许操作,
top.location.hostname === self.location.hostname
; -
敏感操作使用更复杂的步骤(验证码、输入项目名称以删除)。
(这个来源于LuckyWinty: http://www.imooc.com/article/295400)
9. setTimeout的执行原理(EventLoop)
(必问…)
(回答参考:https://juejin.im/post/5e621f5fe51d452700567c32)
setTimeout
的运行机制:执行该语句时,是立即把当前定时器代码推入事件队列,当定时器在事件列表中满足设置的时间值时将传入的函数加入任务队列,之后的执行就交给任务队列负责。但是如果此时任务队列不为空,则需等待,所以执行定时器内代码的时间可能会大于设置的时间
说了一下它属于异步任务,然后说了一下还有哪些宏任务以及微任务,最后说了一下EventLoop
的执行过程。
-
一开始整个脚本作为一个宏任务执行
-
执行过程中同步代码直接执行,宏任务进入宏任务队列,微任务进入微任务队列
-
当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完
-
执行浏览器UI线程的渲染工作
-
检查是否有
Web Worker
任务,有则执行 -
执行完本轮的宏任务,回到2,依此循环,直到宏任务和微任务队列都为空
(具体可以看这里:https://juejin.im/post/5e58c618e51d4526ed66b5cf#heading-1)
10. requestAnimationFrame有了解过吗?
(啪啪啪,不长记性,其实之前面试有被问过,但是忘了再去了解了,这就吃亏了,没答上来)
requestAnimationFrame
是浏览器用于定时循环操作的一个接口,类似于setTimeout
,主要用途是按帧对网页进行重绘。对于JS
动画,用requestAnimationFrame
会比 setInterval
效果更好。
具体可以看:https://juejin.im/post/5e621f5fe51d452700567c32
11. requestAnimationFrame和setTimeout的区别?
同上…
12. 平常工作中ES6+主要用到了哪些?
(下面看着很多,但我肯定不是全答哈,挑了几个来回答)
ES6
:
-
Class
-
模块
import
和export
-
箭头函数
-
函数默认参数
-
...
扩展运输符允许展开数组 -
解构
-
字符串模版
-
Promise
-
let const
-
Proxy、Map、Set
-
对象属性同名能简写
ES7
:
-
includes
-
**
求幂运算符
ES8
:
-
async/await
-
Object.values()和Object.entries()
-
padStart()和padEnd()
-
Object.getOwnPropertyDescriptors()
-
函数参数允许尾部
,
ES9
:
-
for...await...of
-
...
展开符合允许展开对象收集剩余参数 -
Promise.finally()
-
正则中的四个新功能
ES10
:
-
flat()
-
flatMap()
-
fromEntries()
-
trimStart
和trimEnd
-
matchAll
-
BigInt
-
try/catch
中报错允许没有err
异常参数 -
Symbol.prototype.description
-
Function.toString()
调用时呈现原本源码的样子
还不了解的小伙伴可以看看浪里哥的这篇:盘点ES7、ES8、ES9、ES10新特性
https://juejin.im/post/5dda2b5e6fb9a07a83691766
13. 如何在前端实现一个图片压缩
实话实话没做过,但是后来面试官告诉我:可以使用canvas
来实现。具体做法等我写篇文章哈。
(当时我还反问了一句面试官:那批量图片压缩要怎么做呢?把他惊的…然后他和我说挺复杂的…
16. 项目中有碰到什么难的问题吗?如何解决的?
例举了我最经典的bpmn.js
,以此来引出我写了很多关于这方面的教材,以及建立了微信群,为国内的bpmn.js
社区贡献了一份力量…怎么高大上怎么来…
当然也有提到我GitHub
上的bpmn-chinese-document
项目只有100
多的Star
,他说理解,毕竟这东西用的人不是很多。
17. 期望薪资多少?
喊了个挺高的数,老哥笑了笑,你这个工作年限我们可能给不到,然后扯了点别的。
18. 还有什么想要问我的吗?
-
团队人员分布情况
-
技术栈
总结
大厂面试问深度,小厂面试问广度,如果有同学想进大厂深造一定要有一个方向精通的惊艳到面试官,还要平时遇到问题后思考一下问题的本质,找方法解决是一个方面,看到问题本质是另一个方面。还有大家一定要有目标,我在很久之前就想着以后一定要去大厂,然后默默努力,每天看一些大佬们的文章,总是觉得只有再学深入一点才有机会,所以才有恒心一直学下去。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】