前端大厂一面

1 实现左侧固定右侧自适应的布局
<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

(1)flex布局

.container{
      display: flex;
}
.left{
      width: 100px;
      height: 100px;
      background-color: red;
}
.right{
      flex:1;
      background-color: black;
}

(2)grid布局

.container{
      display: grid;
      grid-template-columns:300px 1fr;
}
.left{
      width: 100px;
      height: 100px;
      background-color: red;
}
.right{
      flex:1;
      background-color: black;
}
2 css的权重

(1)id选择器
(2)class选择器、属性选择器、伪类选择器
(3)伪元素选择器、标签选择器
(4)通配符选择器
内联样式和!important具有更高的权重

3 +和~选择器有什么不一样

+匹配最近一个兄弟元素
~匹配后面所有的兄弟元素

4 单双行条纹样式

nth-child(2n)、nth-child(2n+1)

5 伪类和伪元素有什么区别

伪类用于操作DOM树中已存在的元素,伪元素会创建不再DOM树中的元素,并为其添加样式,但实际并不存在DOM文档中
::selection改变选中文字背景

6 跨域及其解决方案

当域名、协议、端口有一个改变时就会产生跨域
解决方案:
(1)CORS
设置http请求头:Access-Control-Allow-Origin
(2)jsonp
动态创建script标签,将json作为回调函数参数
(3)反向代理

7 什么是data URL

将图片转换成base64编码格式,可以减少http请求
jpg、png是二进制,需要进行base64编码
而svg是文本格式,不需要base64编码

8 prefetch和preload的区别
  1. preload加载当前路由必须资源,优先级高
  2. prefetch优先级低,一般用于加载其他路由资源
9 如何禁止复制粘贴

将user-select设置为none

10 如何取消请求的发送

1、使用xhr发送请求
使用XHLHttpRequest发送请求,可以使用XMLHttpRequest.abort()
2、使用fetch发送请求
使用AbortController

const controller=new AbortController()
const signal=controller.signal
fetch('https://somewhere',{signal})
controller.abort()

3、使用axios发送请求
使用CancelToken

var CancelToken=axois.CancelToken()
var source=CancelToken.source()
axios.get('/https://somewhere',{
	cancelToken:source.token
})
source,cancel
11 common JS和esm的区别

1、输出拷贝/输出引用
commonjs使用export输出对象的属性,内部属性的不会变化,esm输出的是值的引用
2、import的read-only
3、esm存在export、import提升

如果在package.json中的main字段是干什么的?
使用import导入时,就会去main字段中查找
exports字段是做什么的?
可以导出commonjs、esm,还可以支持子模块的导出
version是做什么的?
例:1.2.3
^:第一个版本不变,后面两个保持最新
~:前面两个版本不变,最后一个保持最新
说一下devDep
开发依赖
peerDep:安装一个依赖必须要有另一个依赖才能行
比如说我是用vue进行开发的,那么你要用vue的库,那么就需要vue这个环节

12 webpack如何提升构建速度?

1、开启缓存
2、使用thread-loader,开启一些线程,把一些耗时操作在另一个线程进行执行
3、swc-loader替代babel-loader

13 js如何压缩代码

使用terser-webpack-plugin去除空格,将变量名缩短;把一些通过计算获得的值,将表达式换成具体的值

14 tree shaking

Tree shaking指基于ES Module进行静态分析,通过AST将用不到的函数进行移除,从而减小打包体积,如果模块的引入是用commonjs,即用require引入的,tree shaking将不起作用

15 exports和module.exports的区别

一开始,exports和module.exports指向的都是同一块内存

exports.a=18
module.exports.a=18
//最后输出{a:18}

require本质上的引入对象是module.exports,因此,当exports的引用地址变更后,require输出的是module.exports的内容

exports.a=3
module.exports.a=5
//输出结果为{a:5}
16 如何将CommonJS转化成ESM

使用rollup的commonjs的插件

17 浏览器的缓存策略

浏览器的缓存过程如下:
(1)开始加载,域名解析,DNS缓存
(2)本地缓存
(3)http缓存
(4)服务器缓存

DNS缓存
网址包含域名和端口指向的唯一ip地址,通过域名查找ip地址的过程成为dns解析,这一过程会给网络请求带来一定的损耗,所以在第一次获取到ip地址后,会将其缓存起来,当下次再次访问相同ip地址时,会先去本地缓存中查找,如果缓存有效,则直接返回该ip地址,否则会继续查找

本地缓存
几乎所有网络请求的相关资源都会被浏览器自动加入到本地缓存中,当数据量过大时,即使网页不关闭,缓存依然失效
HTTP缓存:强缓存和协商缓存
强缓存:在第一次访问服务器获取到数据后,在过期时间之内不会再去重复请求

在http1.0中,通过expires设置强缓存的过期时间,在http1.1中,通过cache-content响应头实现,它包含以下值:

  • private:客户端可以缓存
  • public:客户端和代理服务器都可以缓存
  • max-age:缓存的有效时间
  • no-cache:是否需要协商缓存验证是否过期
  • no-store:不可缓存

强缓存只有在首次请求才会和服务器通信,读取缓存资源时不会发出任何请求,资源的状态码为200

协商缓存:协商缓存每次读取数据都要和服务器进行通信,并且会增加缓存标识。当首次请求服务器时,服务器会返回数据和数据的缓存标识,一起存在浏览器的缓存数据库。当再次请求资源时,浏览器先将缓存标识发送给服务器,服务器首先判断缓存标识是否匹配,如果匹配,返回304状态码,则直接从本地缓存中读取数据,如果不匹配,则说明资源发生了更新,返回新的资源和新的缓存标识

在http1.0中,使用Last-modified来设置响应头的缓存标识,并把资源的最后修改时间作为值填入,再次请求时,浏览器会带上If-Modified-Since请求头去访问服务器,如果时间匹配,返回304状态码,从本地缓存中读取资源,如果不匹配说明资源发生变化,返回新的资源,更新Last-Modified的值并返回给浏览器。

在http1.1中,服务器通过Etag来设置响应头缓存标识,在首次请求时,服务器会将资源和Etag值一并返回给浏览器,当浏览器再次请求时,浏览器会将Etag信息放到If-None-Match请求头中去访问服务器。

18 cookie、sessionstorage、localstorage的区别

1、存储大小不一样,cookie最大存储4kb,localstorage、sessionstorage最大存储5mb
2、存储的时间有效期不一样,cookie的有效期可以设置,默认关闭浏览器失效,sessionstorage仅当前窗口有效,关闭会话和浏览器失效,localstorage不手动删除则永久有效
3、cookie与服务器通信每次被包含在http请求头中,而sesionstorage、localstorage不参与与服务器的通信

19 如何利用cookie实现登录功能
20 cookie如何实现跨域

设置access-control-alow-origin为*,withcreadential为true

module.exports=function(){
	return async fucntion cors(ctx,next){
		ctx.set('Access-Control-Allow-Methods','GET,POST,PUT,OPTIONS,DELETE')
		ctx.set('Access-Control-Allow-Origin','*')
		ctx.set('Access-Control-Allow-Headers',ctx.get('access-control-request-headers'))
		
		if(ctx.method==="OPTIONS"){
			ctx.status=204
			await next()
		}else{
			await next()
		}
	}
}
21 什么是重绘和回流,如何减少?

重绘是指页面元素的样式,如颜色等发生改变,但并不影响页面的布局,这就叫重绘

回流是指页面元素样式的改变引起页面布局的变化

1、将需要多次改变样式的元素,合并为一次操作
2、对需要进行复杂操作的元素,可以先给它一个display:none,最后在让其显示
3、对多次引起回流的元素,可以给他一个position:absolute或fixed

22 浏览器的渲染过程是怎样的?

1、将html标签转化为DOM树
2、解析CSS样式,转化为CSSOM树
3、DOM树和CSSOM树合并构建render树
4、根据渲染树将内容渲染至显示屏

23 v-if和v-for标签为什么不建议用在同一个标签上

因为v-for的优先级大于v-if,那么每次循环时都要进行v-if判断,会造成性能的消耗,可以在v-for外面写一层template加上v-if,这样可以避免性能的消耗

24 vue-router的实现原理

路由映射表存储了url和组件的映射关系,利用栈记录url的访问记录(history),访问url的时候,访问url时,根据匹配去查映射表对应的组件并返回渲染,记录到history钟,通过前进/后退访问url的时候,优先到history中找,就可以实现不同url映射到不同的组件

vue-router有两种模式:

  • hash:hash虽然出现在url中,但并不会包含在http请求中,因此改变hash不会重载页面
  • history:利用pushstate和replacestate方法,当它们执行修改时,虽然改变了url,但浏览器不会刷新页面,但是一旦发生刷新,如果服务器没有相应的资源,则会返回404
25 说一下TCP三次握手和四次挥手

(1)三次握手

  • 一次握手:客户端发送连接请求,SYN=1,seq=x
  • 二次握手:服务器接受连接后,返回应答报文ACK=1,设置Acknowledgement number=x+1,同时服务器发送SYN=1,设置seq=y
  • 三次握手:客户端接收到ACK报文后,检查ACK number是否正确,如果正确,发送ack=1和ack number=y+1,客户端收到后,确认ack number

(2)四次挥手

  • 客户端发送一个FIN,用来关闭连接,服务器处于FIN_WAIT_1状态
  • 服务器收到FIN后,返回一个ACK给客户端,客户端处于CLOSE_WAIT状态
  • 服务器发送一个FIN关闭连接,服务器处于LAST_ACK状态
  • 客户端收到FIN后,进入TIMEWAIT状态,发送ACK给服务器,服务器进入CLOSED状态,完成四次握手
26 数据类型检测方法?说一下instanceof的原理

typeof、instanceof、Object.prototype.toString.call

  • typeof判断null、object、array都是object
  • instaceof无法判断简单数据类型,且对数组和obj做判断时结果都为true

instanceof的原理:遍历左侧实例的原型链判断是否有属性和右侧的构造函数的prototype属性一样,一样返回true,否则返回false

27 cdn如何实现加速

当用户发送请求到达服务器时,服务器会根据用户的区域信息,为用户分配最近的cdn服务器,而cdn就近的网络节点,不仅能提高用户的访问速度,也能减少服务器的带宽消耗,降低负载

28 Map和Set的区别
MapSet
对象,键可以是任何数据类型类似数组,内部元素自动去重,不具有顺序
一般用map存储经常变动的数据set用于去重
在内存固定时,map可比object节约50%,添加、删除、大量查找速度优于object

weakMap:
1、只接受对象作为键名
2、解决了map无引用自动垃圾回收的情况,Weakmap键名所指向对象不计入垃圾回收机制,在用delete删除后,key会被垃圾回收

29 vue中的data为什么是一个函数?

为了组件中的数据不相互影响。因为组件可能被用来创建多个实例,如果data是一个纯粹的对象,那么所有实例将共享引用同一个对象。

30 vue中的key有什么作用?

给元素打上唯一标识,用于diff算法中。当不包含key时,diff算法是将新增数据插入到尾部;当有key时,diff算法是插入到指定位置

31 vue2.0如何实现对象和数组的监听?

使用ObjectdefinePrototype对对象进行监听,使用shift、unshift、splice、pop、reverse、push、sort对数组进行监听

32 不应该使用箭头函数的一些情况
  • 不能用箭头函数作为构造函数
  • 箭头函数不能改变this指向
  • 无法使用calll、apply、bind改变this指向
33 怎样选择合适的缓存策略

通常会先走强缓存判断,如果没有命中强缓存回去判断是否满足协商缓存,如果都不满足则重新请求数据

如果是不怎么替换的lib文件,使用强缓存,js、png、css使用协商缓存

32 对象数组如何去重
 let data=[
      {id:1,time:'1'},
      {id:2,time:'2'},
      {id:2,time:'3'}
	]
let arr=[]
let newArr=[]
for(let i=0;i<data.length;i++){
	if(arr.indexOf(data[i].id)==-1){
		arr.push(data[i].id)
		newArr.push(data[i])
	}
}
33 观察者模式和发布者-订阅者模式的区别、用处
观察者模式发布者-订阅者模式
当属性发送变化,就会通知所有的观察者去更新当属性发送变化时,发布者并不直接通知订阅者,而是通过事件中心Broken,订阅者不关注发布者是谁,而是关注于事件本身
vue的响应式vue的生命周期,消息队列
34 说说for…in和for…of的区别
for…infor…of
遍历数组或对象的属性遍历数组或具有Symbo.iterator属性的对象
同步遍历异步遍历
会遍历原型链上可读属性不可遍历对象上的原型链上的属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值