永久白嫖!前端开发面试题,请低调使用

永久白嫖!前端开发面试题,请低调使用

首页休闲益智2048内卷正版更新时间:2024-05-13

面试造火箭,工作拧螺丝!

在IT技术圈里,只有百分之十的人能够进入大厂,剩下的百分之九十的小伙伴只能在普通的公司,厌烦一些标题党,动不动就能进入BAT等大厂。抛开那些夺人眼球的词语,回归到面试本质,关注面试本身,总结最近3年里长文的web前端开发工程师面试题(不涉及具体很细节的知识点,适合初中级前端开发工程师)。

1、HTML(5)和CSS3方面

1、前端与后端数据交互的格式有哪些,为什么大部分现在都用json而不用xml?

XML:<person><name>蛋糕哥</name><age>3岁</age></person>

JSON:{ “name”:”蛋糕哥”,”age”:3}

从上可以看出,JSON书写更方便节省字节、更轻量,前后都有直接解析JSON的方法(JSON.stringfity/parse)使用方便。

2. 说一下CSS盒模型

CSS的盒模型包含了以下几个内容:

margin,padding,border,content

在计算盒子宽高的时候,IE和Chrome会有一些区别。IE算到border,Chrome的宽度只包含content区域,因此CSS3提供了box-sizing这个属性来修改。

3. 请用5种方式实现元素垂直居中

1)flex

.wrap{

height:100%;

position:relative;

display:flex;

justify-content:center;

align-items:center;

}

2)Tranform

.static{

position:absolute;

top:50%;

left:50%;

transform:translate(-50%,-50%);

}

3)定位 margin负值

.static{

position:absolute;

left:50%;

top:50%;

margin-top:-100px;

margin-left:-100px;

}

4)定位 margin:auto

.static{

position:absolute;

left:0;

right:0;

bottom:0;

top:0;

margin:auto;

}

5)JS动态计算top、left值

4、什么是BFC?垂直margin重叠是为什么?怎么解决这个问题?

答:BFC又称块级格式上下文,通俗来说是一个独立的布局环境,也可以理解为是一个箱子,箱子内部的元素无论发生怎样的变化都不会对外部造成影响。并且,在一个BFC中,块元素与行元素都会垂直地沿着其父元素的边框进行排列。

如何触发BFC:

a. 浮动元素,float除none以外的值;

b. position的值不为static或者relative;

c. display不为none;

d. overflow除了visible以外的值。

BFC的应用:

a. 解决浮动塌陷问题;

b. 自适应两栏布局(运用BFC可以阻止元素被浮动元素覆盖的特性来实现自适应两栏布局,方法:给没有浮动的元素加overflow:hidden)

c. 解决设置margin值重叠问题。

5. 简单描述http或https协议,以及为什么要三次握手?什么是长链接

答:http/https是超文本传输协议,基础TCP请求与相应的模式,是目前主流的web传输协议,一般包含请求头,请求体和响应头等。

https相较于http更安全,增加了证书ssl加密,端口是433。

三次握手也就是三次网络连接,客户端携带SYN=1,SEQ = x信息给服务端,服务端接收到后,就知道有一个客户端想要连接,然后服务端就会开启一个TCP socket的端口,然后返回数据给前端也是SYN=1,SEQ=Y,ACK = x 1,客户端接收到后,再发送一个seq和ACK 1(防止开启无用的链接或者网络延迟丢包),服务器无法确定到底客户端有没有收到消息。

6. 什么是reflow与repain?哪些操作会触发reflow,如何避免

reflow:回流。当元素的尺寸,DOM结构发生变化时,浏览器会重新渲染页面,称为回流。

repain:重绘。当元素的样式发生变化(结构不发生变化)时,以下常见的操作都会触发:

浏览器窗口大小改变;

元素尺寸、位置、内容发生改变;

元素字体大小变化;

添加或者删除可见的dom元素;

激活CSS伪类(例如:hover)等;

通过class的方式集中改样式,documentFragment缓存节点,避免使用table、calc,做动画的节点脱离文档流(新创建图层)。

总结:减少DOM操作!

7.什么是浏览器缓存(强缓存和协商缓存)?

当浏览器访问咨询后,会被浏览器缓存到本地,当下次访问页面时,如果没有过期,会直接读取缓存,加快浏览器的加载效率。

http缓存机制:

1)Expires:通过设置最大缓存时间,当时间超过了就去服务器下载;

2)http1.1,cache-control:max-age=time,当time过期后,检测etag带上etag往服务器发请求,如果etag没变,直接告诉浏览器读本地缓存,如果没有etag就会检测Last-Modified,判断如果上一次更改的时候,距离本次访问时间比较久,说明文件没有发生改变,返回304。

强缓存就是当前访问时间还在设置的最大时间范围内。

协商缓存就是时间过了,通过检查etag或者last-modifed来使用缓存的机制。

8. 说一下浏览器垃圾回收机制

老:标记清除算法,GC会检测当前对象有没有被变量所引用,如果没有就回收。

新:Scavenge,把内存空间分为两部分,分别为From空间和To空间。当一个空间满了以后,会把空间中活动对象转移到另外一个空间,这样互换。

9.什么是事件委托

事件委托本质上是利用浏览器事件冒泡机制,因为事件在冒泡过程中会上传到父节点,并且父节点可以通过事件对象获取到目标节点。因此,可以把子节点的监听函数定义在父节点上。由于父节点的监听函数统一处理过个子元素的事件,这种方式成为事件代理。采用事件代理,我们可以不必要为每个子元素都绑定一个监听事件,这样减少了内存上的消耗,也是常见的JS性能优化点。

10.什么是响应式布局?如何实现

书写一套CSS样式,适用于PC和移动端能够正常浏览显示。

注意:响应式不能使用固定单位,需使用max-width、min-width等能自动缩放的单位。

2、JS方面(ES6/ES7)

1. 在JS中什么是面向对象程序设计,面向对象设计优点?

在JS中面向对象更多说的是通过构造函数或者class封装一个独立的功能,以达到代码的复用。

面向对象的三个特点:

封装:通过对象把属性和方法封装起来,相似对象的话采用构造函数或者类new得到。

继承:通过混合继承(构造函数和原型)的方式,可以达到属性和方法的复用。

多态:通过对象属性覆盖,可以让继承的对象拥有更多行为。

面向对象的程序设计是组织代码的方式,能提升开发效率和代码的可维护性。

2. 什么是作用域以及作用域链?
作用域是指程序源代码中定义变量的区域,限定一个变量可访问范围的,作用域的本质是对象。JS采用的词法作用域,在书写代码的时候就已经确定好了。

在ES6环境下,包含3个作用域:全局globel、函数作用域、快级作用域( {} )(eval)

作用域链:当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,则会从父级执行上下文的变量对象中查找,直到找到全局上下文的变量对象(全局对象)。

这种由多个执行上下文的变量对象构成的链表就叫做作用域链,目的是保证对执行环境有权访问的所有变量和函数进行有序访问;本质是为执行上下文的scope属性,存储所有的变量,包括局部和全局控制变量的使用顺序。

3. 什么是闭包,闭包的好处和坏处分别是?

当函数可以记住并访问外部作用域时,我不作用域就称为闭包。

形成的原因:外层函数的作用域对象无法释放。

作用:为了封装对象的私有属性和方法,避免全局变量的污染。

缺点:使用不当会造成内存泄露。

4.什么是Ajax,如何封装一个Ajax?Get请求与Post请求的区别?

Ajax全称是异步js与xml技术,通过它与后台服务器进行数据交换,可以使网页实现异步更新。换言之,在不同重新加载整个页面的情况下的,对网页进行局部更新。

1)nex xmlhttprequset对象

2)open(method,url,true)

3)绑定redaystatechange事件

4)调用send方法,如果是post请求,可以传递参数

前端的请求方式除了常用Get和Post,还有update,delete,put等(restful api设计)

三分方面来说:能不能缓存,传参数方式,传参大小

GET请求可被缓存,保留在浏览器历史记录中 ,请求的参数是直接跟在URL上,因此不应传递敏感数据。

GET请求有长度限制(2048字符),IE和Safari浏览器限制2k;Opera限制4k;Firefox,Chrome限制8k 。

GET请求通常只应当用于从后台获取数据。

POST请求不会被缓存,不会保留在浏览器历史记录中

POST请求对数据长度没有要求。

POST请求通常用于往后台提交数据。

5.说一些ES6、ES7新特性

let/const定义变量(块级作用域);结构,从对象和数组中提取值;箭头函数;字符串模版;扩展运算符...;对象的简写;module;promise(async);class;对原生对象的扩展(新增加了很多方法) ;for-of (Object.keys,values,entries等);Symbal();

不常用的proxy,reflect,generate函数,map和set

6. 什么是跨域,解决跨域问题常用的方式有哪些?

跨域是浏览器端行为,根据同源策略,当请求的协议、域名、端口只有一个不同,就会跨域,跨域是浏览器为了安全存在的机制,浏览器会把跨域请求的数据去掉,同时报错。

在实际开发难免会出现跨域的情况,解决方案通常有

1)JSONP技术,利用了script的src属性没有跨域限制,img的src也没有跨域限制

2)CORS,当在相应头信息中添加access-control-allow-origain属性,浏览器读取到就会允许返回数据。后台配置,或者下一个浏览器插件即可。

3)后台代理(Node)

4)Iframe域的提升(很少)

7. 前端安全你有了解吗?什么是XSS攻击和CSRF 跨站请求伪造?怎么预防?

在工作中会注意以下前端安排问题:

1)XSS跨站脚本漏洞攻击,通常不信任用户的输入,转义输入输出内容(encodeURIComponent),括号、尖括号等。利用用户对站点的信任。

2)CSRF跨站请求伪造

一种挟制用户在当前已登录的web应用中执行非本意的攻击,简而言之就是利用用户登录发起恶意请求。

预防:

1)添加验证码不让第三方访问cookie对cookie设置samesite,请求验证加token(用户体验稍差)。

2)密码问题:对密码进行加密(MD5等)。

8. JS加载会阻塞页面渲染吗?会的话该怎么解决呢?CSS呢

会。

因为JS可以操作DOM,浏览器为了防止渲染过程中出现不可预期的结果,让GUI渲染线程和JS引擎线程互斥,即解析器在遇到<script>标记时,会立即解析并执行脚本。

defer:并行下载,在页面解析完后执行,会按照script的顺序执行,代码有依赖顺序依赖的时候选用。

async:异步下载代码,下载完后立即执行,不会按照页面的script顺序。CSS的加载不会阻止DOM解析,页面的绘制会等待CSS解析完成才执行。

3、框架方面

1.什么是vdom(虚拟DOM)?为何要使用vdom?简单地描述一下什么是diff算法?

浏览器最费操作的就是DOM操作,结构复杂,属性太多,节点与节点之间还相互关联。Vdom是一类技术栈,使用JS对象来模拟DOM结构,将ODM变化的对比放到JS层来做,提高效率。

Diff算法是对比新旧两个虚拟DOM节点,只修改变化的地方,其他节点不动。大概实现思路为遍历新节点:与旧节点同级比较,如果节点相同,再比较属性值,再递归比较子节点,直到全部比较完,再进行下一次同级比较。当遇到不相同的地方记录下来,下一次事件循环的时候统一更新节点。

2. 简单说一下对MVC、MVVM的理解?

1)M:model数据源,一个列表的数据、表单数据等;V:view视图,HTML CSS;C:controllor控制器,控制视图或者数据的变化。

2)MVVM,在MVC模式上算是一个微创新,M和V和上面一样的,VM:viewmodel,相对于M/V之间的一个桥,view通过事件绑定影响到model,model可以通过数据监听来影响视图,这样就让View和Model分离了更加利于视图的复用。

3. 简单说一下对Vue模板的理解

模版、字符串、有逻辑、可以嵌入JS变量。模版会被编译成render函数,执行render后返回的是vdom(vnode)。

Vue的vdom是借鉴了snabbdom,在updateComponent中实现vdom的patch,首次渲染是会执行updateCompoent,在data每次修改的时候,执行updateComponent。

4.Vue2.x如何实现数据的双向绑定的?

Vue通过数据劫持(Object.DefineProperty()) 订阅发布模式

监听器 Observer:用来劫持并通过Object.defineProperty监听所有属性(转变成setter/getter形式),如果属性发生变化,就通知订阅者。

订阅器 Dep:用来收集订阅者,对监听器 Observer 和 订阅者 Watcher 进行统一管理。

订阅者 Watcher:监听器Observer和解析器Compile之间通信的桥梁;如果收到属性的变化通知,就会执行相应的方法,从而更新视图。

解析器Compile:可以解析每个节点的相关指令,对模板数据和订阅器进行初始化。

主要做的事情:

1)在自身实例化时往属性订阅器(dep)里面添加自己。

2)自身有一个update()方法。

3)待属性变动dep.notice()通知时,能调用自身的update()方法,并触发解析器(Compile)中绑定的回调。

总结:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

5. Vue,React子父组件如何通讯?

由于单项数据流的规范,Vue和react都遵循通讯机制。

vue和react都是使用prop传递数据给子组件,vue需要提前在子组件中提前使用props声明,react不用。

React中子组件传递数据到父组件(状态提升),同样是通过父组件给子组件传递属性,区别是属性值为一个函数函数引用(需要绑定函数的this),然后在子组件中调用这个函数即可,传递相应的参数。

Vue中子到父,是通过在使用子组件的时候绑定自定义事件,在子组件内部拿到事件名称,再通过this.$emit(‘事件名’)触发并传递参数。

其他方式:全局$bus,provide/inject,$refs/$parent/$children ,$attrs/$listeners ,仓库,storage,url,1.x还有brodercast/dispatch 广播/派发已过时。

6.简述Vue和React的框架的特点以及区别

Vue(MVVM)和react都是组件化、数据驱动型的框架,现在基本都差不多了。

区别:

体积:vue独立一个 30K ,react 160K

学习成本:vue是面向模版编程易学,react函数式编程,需要提前学习ES6 。

效率:vue初始化渲染是比较慢的,是因为vue要把所有的属性都使用object.defineproperty劫持,react就不需要。但是在运行时,vue要快一点,只有数据发生变化就会执行set,再通知指令去更新视图,而react需要执行setState函数,进行diff的比较。

7.Vue-router路由传参的方式有哪些?

1)js导航的xx.push({path:”/user”,query:{ }})

2)动态路由 {path:”/user/:id” name:”user”}

3)meta

4)Storage/仓库

8.不用vue-cli如何搭建一个vue项目?

答:需要使用构建工具webpack(当然还有其他工具gulp,browserify),通过entry配置入口文件;output配置打包输出;module配置loader(loader是用来处理文件的),一般配置处理less/sass,二进制图片或字体等,babel-loader处理ES6/7等,还需要配置vue-loader处理.vue文件;通过plugins配置插件;还需要通过devServer(端口,代理,historyApiFallback,刷新浏览器等)配置开发服务器,配合使用webpack-dev-server。还有一些杂项可以通过resolve来配置(别名,去掉扩展名等)。

9.Vue3有了解过吗?谈谈你对Vue3的理解

大概地学的一下,我觉得这次升级的主要的composition API为了解决代码复用问题,从3个方面来理解:

1)性能。使用proxy代理替换掉了defineProperty劫持,由于defineProperty的局限性无法检查对象属性的改变,同时默认递归data里面的数据做响应式。Proxy是懒递归,当我们操作数据是对象的时候才会去递归代理。

2)复用。原来的optionsAPI,同一个业务逻辑分散在不同的配置项中,跨组件复用起来很麻烦(2.x采用mixins),现在可以封装在函数里面,哪里需要了,就直接导入。

3)对TS的支持。复用的功能多半是函数,再定义接口和类型就很方便了。

目前的缺陷就是兼容性差一些,IE11都不支持。

10.谈谈你是如何实现前端权限验证的?

我知道的前端的权限验证有两个:

1)路由权限:不同的权限对应着不同的路由页面,同时侧边栏也需要根据不同的权限来异步生成。

2)按钮权限:(使用一个指令,传递权限标识,然后和当前用户的权限比较,如果不匹配就隐藏节点) 比如有些按钮可能只有主管才能使用。

路由权限流程:

登录:当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(我会将这个token存贮到cookie中,保证刷新页面后能记住用户登录状态),前端会根据token再去拉取一个 userinfo 的接口来获取用户的详细信息(如用户权限,用户名等信息)。

权限验证:通过token获取用户对应的 role,动态根据用户的 role 算出其对应有权限的路由,通过 router.addRoutes 动态挂载这些路由。

4、工具方面

1.使用过哪些前端工具?

了解过gulp,但是好像现在已经过时了。目前在开发工程中都使用webpack。

2.有了解过webpack吗?常用的配置项有哪些?

webpack称为模块打包机。它将资源都看成是一个模块,并且把页面逻辑当作一个整体,通过一个给定的入口文件,webpack从这个文件开始,找到所有的依赖文件,将各个依赖文件模块通过loader和plugins处理后,然后打包在一起,最后输出一个浏览器可识别的JS文件。

常见的配置包括:

mode:配置webpack环境,包含development和production环境 (4 )

entry:配置项目的入口文件

output:打包后的文件名,存放的地址,chunk的名字。。。

module:loader test use指定loader

plugins:插件

devserver:配置webpack-dev-server

resolve:杂项,别名,文件的扩展名。。。

devtools:soure-map

3.webpack常用的插件有哪些?分别的作用什么?

MiniCssExtractPlugin :抽离css从js中

DefinePlugin:定义全局变量

htmlWebpackPlugin 设置模版 会自动帮我们打包好的文件路径注入模版

PurifyCSSPlugin:去掉没用的css样式

CopyWebpackPlugin:拷贝静态资源

HotModuleReplacementPlugin:组件热更新

4.git与svn的区别在哪里?

答:git 和svn最大的区别在于git是分布式的,而svn是集中式的。因此我们不能在离线的情况下使用svn。如果服务器出现问题,我们就没有办法使用svn来提交我们的代码。

5、常规算法方面

1、JS中数据结构与算法

数组,对象集合,set,Map

栈LIFO、队列、链表、字典、树

2、排序(冒泡,选择,插入,快排)

选择排序,选假设一个最大,与剩下的比较,如果比max大就交换

function select_sort(A){

for(let i = 0;i<A.length;i ){

let max = A[i];//假设第一个最大

for(let j = i 1;j < A.length;j ){

if (max < A[j]) {

max = A[j];

let mid = A[j];

A[j] = A[i]

A[i] = mid;

} }}}

插入,准备一个新数组,然后依次去原数组中取值,先取一个放到数组里,再取第二个跟新数组里面的进行比较,如果大于就放到后面,小于就再往前找一个,直到找到比当前要小的数,并把它插入后面。

function insert(data,i,t){ //假设data为有序数组,插入

//data有序数组,i数组最大的索引,t要插入的节点

let p = i-1;//p为下一个要比较的元素的索引值

while(p>=0 && data[p] > t){ //data[p] > t 当比较的元素比传进来的元素大

data[p 1] = data[p]; //错位,把当前元素赋值给下一个元素

p-- //p往前走

}

data[p 1] = t //写入空位

}

function insert_sort(data){

for (var i = 0; i < data.length; i ) {

insert(data,i,data[i])

}}

快排,利用递归

function querySort(arr){

if (!Array.isArray(arr)) return

if(arr.length <= 1){

return arr

}

var mid = arr.splice(Math.floor(arr.length/2),1)[0]

var left = [], right = [];

for(let i=0,len = arr.length;i<len;i ){

if (arr[i] >= mid){

right.push(arr[i])

}else{

left.push(arr[i])

}

}

return querySort(left).concat([mid],querySort(right))

}

3.数组的flat拉平

function flat(arr){

var arr1 = [];//闭包缓存

function _flat(arr){ //[2,3]

for (var i = arr.length - 1; i >= 0; i--) {

if (Array.isArray(arr[i])) {

_flat(arr[i])

}else{

arr1.push(arr[i])

} }}

_flat(arr)

return arr1

}

function flat(arr) {

arr.toString().split(',')

return arr

}

4、实现一个方法,找出一个数组中重复的元素

一:Array.prototype.repeNum = function(){

let new_arr = this.sort(); //先排序

let res = [] ;

for( let i = 0 ; i < new_arr.length ; i ){

if(new_arr[i] == new_arr[i 1] && //判断是否重复,是否已经放入容器

new_arr[i] !=new_arr[i-1]){

res.push(new_arr[i]);

}}

return res

}

二:Array.prototype.repeNum = function(){//不排序,利用对象的key

function arrMore(arr){

if (!arr.length) return

let obj = {};

for (var i = 0,len=arr.length; i < len; i ) {

var val = obj[arr[i]];

if(!val){

obj[arr[i]] = 1

}else{

obj[arr[i]] = 1

} }

var arr = [];

for (let [key, value] of Object.entries(obj)) {

if(value>1){

arr.push(key-0)

}}

return arr

}}

三:Array.prototype.repeNum = function(){

if (!arr.length) return

var ret = arr.filter((val, index) => arr.indexOf(val) != index);//先找到有重复的

return [...new Set(ret)];

6、其他问题6.1、技术方面

1、最近做什么项目?在项目遇到什么问题?如何解决的呢?

结合自己的实际情况进行回答,面试前可以好好准备一下。如果是应届生,把自己平时学习的知识和练习的项目总结好。

2、最近在学什么技术?

该问题的目的可能是想考查你平时是否爱学习,对新技术有没有一定的敏感度。不一定要了解多深刻,了解核心内容即可,但不建议说没有。

3、平时喜欢逛什么社区或者技术论坛?

主要是想了解你平时都是通过哪些途径学习,前端开发比如像掘金,阮一峰老师博客,github等。

4、你对加班怎么看?

根据自己的实际情况进行回答。需要提醒的是,互联网企业,IT技术岗位,不加班是几乎不可能的。

5、你还有什么想了解的吗?

技术面的时候不建议问薪资福利,技术面如果没问题,这些后期hr会进行沟通。可以问团队正在做的项目类型等技术方面的问题。

6.2、HR方面

你会发现,有的小伙伴技术能力并不差,一面、二面技术面试都没问题,但hr面试后便没有下文。对于HR面试环节,很多小伙伴不是很重视,尤其是刚毕业的小伙伴,殊不知HR也有决定权。所以,在HR面试环节也需要稍微准备一下。

1、为什么要换工作?

换工作无非于那三个原因,钱给得不够、干得不开心、公司没有上升空间。只要大家的原因积极正向一点,别说前公司的坏话就好了,其它自由发挥。

谨记:哪怕公司再内卷,也千万不能说公司坏话。

2、对薪水有什么期望?

可以根据当前岗位给定的范围,比如10K-15K,可以要个13K,不要超过,也不要低于最小值。

3、对未来有什么规划?

回答不要太空泛,可以从近期规划和长远规划两个方面出发进行讲解。

如:近期规划:深入地学习前端面向对象OOP,函数式编程等;长远规划:未来3-5年都在前端技术方向等。

4、你还有什么想了解的吗?

现在可以充分了解公司的福利、待遇、公司环境等。面试到这里也不必羞涩了,有什么想了解的尽管问。

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved