CVTE前端面经
- 项目介绍(重点)
- 在数据B中找到数组A对应的值,并把数组B对应的值放在数据最前面
- css
-
- 1 定位
- 2 外边距
- 3 css高级应用
-
- 2. 浮动
-
- 3. html5语义标签
- 4. 实现圣杯布局的两种方式
-
- 5. 两栏布局
- 6. 水平垂直居中
-
- 6.1 水平居中
- 6.2 垂直居中
- 6.3 水平垂直居中
- JS
-
- 1. es6新增的数据类型
- 2. 数据类型的判别
- 3. 栈和堆的区别,为什么栈可以保存基础数据类型,为什么可以频繁操作
- 4. 手写深拷贝
- 5. 重绘和重排,怎么减少重排?
- 6. 垃圾回收机制
- 7. promise是什么 promise 有哪些方法,promise.all 和 promise.race 的区别(这两者里面的promise的执行顺序) 实现一个20个请求的串行和并行 promise(我讲了链式调用 但是面试官并不太满意,更优雅的方式)
- 8. Promise如何用来进行限定并发请求个数的功能,说下思路?
- 9. 浏览器加载原理
- VUE
-
- 1. React和VUE的区别
- 2. vue3有什么更新,为什么项目用vue2
- 浏览器
-
- 1. 浏览器如何渲染
- 2. 输入google会发生什么
- 3. 浏览器事件循环机制
- 4. 常见网络攻击
- 5. 浏览器本地化存储 cookie sessionStorage localStorage indexDB
- 6. 就比如那个promise,他问你怎么一张一张图片发,常规就是一直.then()下去,也可以用all去减少then的层级,用promise第一次请求的结果和第二次请求放到all数组里面,但面试官应该是想听到async await, await 请求一 await请求二 用同步的方式写异步,代码可读性可维护性都好。。
- 你说到了用gzip压缩请求数据,那你还了解其他相关的content-coding方式么?
- 计算机网络
-
- 1. https和http的区别
- 2. HTTP2有哪些特性
- 网页优化
-
- 1. 性能优化方式
- 2. 首屏优化方式
- 3. 首屏加载速度可以怎么改善
- 4. 如何提高页面加载速度
- 5. cookie 有什么值(似乎把 secure 和 httponly 弄混了)
- 设计模式
-
- 1. 简单说一下设计模式
- 2. 项目中用到了什么设计模式
- 数据结构
-
- 1. 常见的排序,堆排序
- 2. 平衡二叉树
- 3. 使用两个栈模仿队列
项目介绍(重点)
在数据B中找到数组A对应的值,并把数组B对应的值放在数据最前面
数组的遍历
- for …of:遍历数组项,可以随时使用break语句停止遍历
- for 循环使用递增的索引变量遍历数组项
- array.forEach():方法通过在每个数组项上调用callback函数来遍历数组项
- array.map(callback)方法通过在每个数组项上使用callback调用结果来创建一个新的数组。
- array.from()方法通过在每个数据项上使用callback调用结果来创建一个新数组
- array.reduce()可以进行累加求和。
- 数组的拷贝
- array.concat()将一个或多个数组连接到原始数组。连接两个数组
- array.slice()返回数组的一个片段,该片段从fromIndex开始,toIndex结尾(但不包括toIndex本身)
- array.slice())是另一种拷贝数组的方法。
- 查找数组
- array.includes()返回一个布尔值,判断是否包含itemToSearch。
- array.find()方法返回数组中满足提供的测试函数的第一个元素的值,否则返回undefined
- array.indexOf()返回array中第一个出现的itemToSearch的索引。
- 查询数组
- array.every(),遍历每一个数组,是否都通过callback的检查,返回结果是boolean
- array.som(),只要有一个通过callback的检查,就会返回true。
- 数组过滤
- array.filter()方法创建一个新数组,其包含所有通过callback测试的所有元素。
- 数组的插入
- array.push()将一个或多个项目追加到数组的末尾
- array.unshift()将一个或多个项追加到数组的开头,返回数组的新长度
- 删除数组元素
- array.pop()从数组中删除最后的一个元素
- array.shift()从数组中删除第一个元素
- array.splice()从数组中删除元素,并插入新的元素
- 清空数组
- array.length=0 删除数组中所有的项目
- array.splice()从数组中删除元素,并插入新的元素
- 数组扁平化:array.flat()
css
css中有三种基本定位机制:普通文档流、浮动、定位
1 定位
static(静态定位)、relative (相对定位)、absolute (绝对定位)、fixed(固定定位)。
静态定位:元素 默认的定位方式,无法通过位置偏移属性(top、bottom、left或right)来改变元素的位置。
相对定位:是普通文档流的一部分,相对于本元素在文档原来出现位置的左上角进行定位,可以通过位置偏移属性改变元素的位置。虽然其移动到其他位置,但该元素仍占据原来未移动时的位置,该元素移动后会导致其覆盖其他的框元素。
- 代码展示:
.he1 {
height: 100px;
width: 100px;
background-color: rgb(164, 175, 219);
}
.he2 {
position: relative;
top: -10px;
right: -20px;
height: 100px;
width: 100px;
background-color: rgb(238, 177, 197);
}
"he1">
盒子1
"he2">
盒子2
如果给盒子2加上 z-index:-1的话,可以使得盒子2在盒子1的下面
绝对定位:脱离文档流,不占据原来未移动时的位置,相对于父级元素或更 高的祖先元素中有relative。(也可以是absolute,开absolute会开启BFC,所以效果可能会跟设置relative不一样)
固定定位:是绝对定位的一种特殊形式,以浏览器窗口作为参照物来定义网页元素。当position属性的取值为fixed时,即可将元素的定位模式设置为固定定位。会脱离文档流控制
,始终依据浏览器窗口的左上角来定义自己的显示位置。不管浏览器滚动条如何滚动,也不管浏览器窗口的大小如何变化,该元素都会始终显示在浏览器窗口的固定位置。
2 外边距
margin外边距合并有以下原则:
(1)块级元素的垂直相邻外边距会合并,且其垂直相邻外边距合并之后的值为上元素的下外边距和下元素的上外边距的较大值。
(2)行内元素实际上不占上下外边距,行内元素的左右外边距不会合并。
(3)浮动元素的外边距不会合并。
3 css高级应用
3.1. 过渡
过渡是使元素从一种样式转变为另一种样式时添加的效果,如渐显、渐弱、 动面快慢等
过渡通过以下属性实现:
(1)transition-property属性:规定设置过渡效果的CSS属性的名称。
(2)transition-duration属性:规定完成过渡效果需要多少秒或毫秒。
(3)transition-timing-function属性:规定速度效果的速度曲线。
(4)transition-delay属性:定义过渡效果何时开始。
3.2. 变形
transform:如:平移、旋转、缩放和倾斜,每个效果都被称为变形函数
"one">
"two">
"three">
"four">
2. 浮动
2.1 浮动元素特点
- CSS 的 Float(浮动),会使元素向左或向右移动,使元素共享一行,类似于给元素加了inline-block的作用
- 由于浮动框不在普通文档流之中,所以文档普通流中的块元素表现的像浮动框不存在一样。
- 浮动会将行内元素和行内块元素转化为块元素
- 浮动元素比标准文档流的元素层级要高,会将标准文档流的元素遮挡住。
- 浮动元素会遇到父元素的边缘或者浮动元素或者块元素就停止了浮动。
- 浮动起来的元素不会影响上面的布局,影响的是下面的布局
如下面代码所示
<style>
.container {
width: 400px;
border: 1px solid deeppink;
overflow: hidden;
}
.top {
height: 100px;
width: 100px;
background-color: rgb(223, 162, 162);
}
.main {
height: 100px;
width: 100px;
float: left;
z-index: -1;
background-color: rgb(151, 211, 229);
}
.footer {
height: 100px;
width: 100px;
float: left;
background-color: rgb(207, 182, 240);
}
style>
<div class="container">
<div class="top">Topdiv>
<div class="main">Maindiv>
<div class="footer">Footerdiv>
div>
从下图中我们可以验证上面的两个规则:
- 浮动元素比标准文档流的元素层级要高,会将标准文档流的元素遮挡住。因为Main盒子把Footer盒子遮盖住了,说明加了浮动的Main的盒子的层级更高。
- 浮动起来的元素不会影响上面的布局,影响的是下面的布局。因为加了浮动的是第二个元素,他在遇到Top盒子的时候并没有选择去覆盖掉他,而是老老实实的在Top的下面,但他下面的Footer盒子,跑到上面来了。所以影响了下面盒子的布局。
2. 2 清除浮动
为什么要清除浮动
- 因为浮动的元素会影响到下面元素
- 会造成父盒子高度塌陷
清除浮动的3中方式:
- 方式1:给浮动的元素父元素设置一个固定的高度,从视觉上看到浮动的元素在父元素包裹之内。
- 方式2:要使用这个clear属性必须创建一个新的div元素,创建新的div元素不能放置任何内容,它只能做一个件事情,那就是清除浮动并且将这个新创建的div元素放在最后一个浮动元素的后面才会生效。
- 方式3:使用属性为overflow并且属性值为hidden来清除浮动,必须将这个属性设置在浮动元素的父元素身上。
3. html5语义标签
- header标签:页面或页面中某一个区块,通常是一些引导和导航信息
- nav标签:可以作为页面导航的链接组
- section标签:页面中的一个内容区块,通常由内容及其标题组成
- aside标签:非正文的内容,与页面的主要内容分开的,被删除而不会影响到网页的内容
- article标签:代表一个独立的、完整的一个区块,可独立于页面其他内容使用
- footer标签:页面或页面中的某一个脚注
- main标签:h5的语义化标签,除了单词不一样,本质上就是一个div
4. 实现圣杯布局的两种方式
圣杯布局:header、footer定高,left和right定宽,center宽度自适应
4.1 定位+浮动
<div class="header">headerdiv>
<div class="container">
<div class="center column">centerdiv>
<div class="left column" >leftdiv>
<div class="right column" >rightdiv>
div>
<div class="footer">footerdiv>
- 首先给header、footer、container一个固定的高度,宽度100%;给left、right一个固定的宽度,高度为container的定高;center宽度100%。
- 然后给container内的三个子元素float:left;浮动,但是因为center的宽度是container的100%所以left和right并没有与center浮动在一行。(注意这里不要给container盒子加宽度,要让left、right、center自己撑开盒子的宽度)
- 为了使left和right浮动与center一行,可以使用margin-left属性,给left(margin-left:-100%)这样left就覆盖在center的左边;给right(margin-left:-【right的宽度】)这样子right就覆盖在了center的右边。
- 虽然container的子元素现在都在一行上面,但是center内容的宽度还是container的100%,所以给container一个padding,左右分别与left和right等宽。
- 这时候left和right还是覆盖在center上,所以可以给container开启相对定位,然后将left和right分别移动对应的宽度,这样container的子元素刚好占满container 的宽度。
4.2 flex布局
<div class="header">headerdiv>
<div class="container">
<div class="left column" >leftdiv>
<div class="center column">centerdiv>
<div class="right column" >rightdiv>
div>
<div class="footer">footerdiv>
- 设置好所需要的header、footer的高度,以及left、right的宽度,然后对中间的container容器开启display:flex,center宽度:flex:1
5. 两栏布局
一栏定宽,一栏自适应
- float:left;+margin-left;float使左边的元素脱离文档流,右边的元素可以和左边的元素显示在同一行,设置margin-left让右边的元素不覆盖掉左边的元素。
- float:left;+overflow:hidden;给要自适应的盒子加overflow:hidden;会触发块级格式化上下文(BFC),利用了BFC 不会重叠浮动元素的特点。
- position: absolute + margin-left;左边绝对定位,右边设置margin-left
- flex布局;flex布局可以使两个子元素显示在同一行,只要左边的宽度固定,就可以实现效果,
6. 水平垂直居中
6.1 水平居中
- 行内元素:首先看它的父元素是不是块级元素,如果是,则直接给父元素设置 text-align: center;
- 块级元素
- 需要谁居中,给其设置 margin: 0 auto; (作用:使盒子自己居中)
- 首先设置父元素为相对定位,再设置子元素为绝对定位,设置子元素的left:50%,即让子元素的左上角水平居中;然后设置绝对子元素的 margin-left: -元素宽度的一半px; 或者设置transform: translateX(-50%);
- 使用flex布局实现(宽度定不定都可以):只需要给待处理的块状元素的父元素添加属性 display: flex; justify-content: center;
6.2 垂直居中
- 单行的行内元素:只需要设置单行行内元素的"行高等于盒子的高"即可;
- 块级元素:
- 首先设置父元素为相对定位,再设置子元素为绝对定位,设置子元素的top: 50%,即让子元素的左上角垂直居中;然后设置绝对子元素的 margin-top: -元素高度的一半px; 或者设置transform: translateY(-50%);
- 使用flexbox布局实现(高度定不定都可以):给待处理的块状元素的父元素添加属性 display: flex; align-items: center;
6.3 水平垂直居中
- 设置父元素为相对定位,给子元素设置绝对定位,top: 0; right: 0; bottom: 0; left: 0; margin: auto;
- left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%);
- left: 50%; top: 50%; margin-left: --元素宽度的一半px; margin-top: --元素高度的一半px;
- 设置父元素为flex定位,justify-content: center; align-items: center;
JS
1. es6新增的数据类型
- Symbol
Symbol是一种基本数据类型,Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法,每一个Symbol()函数的值都是唯一的。
- BigInt
BigInt是一种内置对象,用来表示大于2^53 - 1的整数,它可以表示任意大的整数,如果有小数的话会向下取整。
let big = BigInt(1) // 1n
- Set(在使用instanceof检测的时候是Object类型)
集合就是一组值,与数组类似。但是与数组不同的是,集合没有索引或顺序,也不允许重复
常用api:
注意:
- Set类是可迭代的,可以for of遍历,也可以使用…扩展操作符
- 集合中不会出现重复数据的判断
- 因为通过add操作返回的是集合本身,所以可以使用add(1).add(2)
- Map
Map对象表示一组被称为键(key)的值,其中每个键都关联着(或映射到)另一个值,它的key可以为引用数据类型
- WeakMap和WeakSet
- 弱映射不是可迭代对象,它只实现了set()、get()、has()、delete()方法
- 弱映射的主要用途是实现值与对象的关联,因为它容易被垃圾回收,所以不会造成内存泄漏
- 弱映射的key只能为引用数据类型,value可以为任意类型
2. 数据类型的判别
JS的基本数据类型:Undefined、Null、Boolean、Number、String
引用数据类型:Array、Object、Function、Data、RegExp
判断js数据类型的方法:
- typeOf:可以对除了null、数组、对象都会被判断为object,其他判断正确
- instanceof可以正确判断对象的类型,其内部运行机制是判断在其原型链能否找到该类型的原型
- constructor:对象实例可以通过constructor对象访问他的构造函数。
- Object.prototype.toString.call():使用的是Object对象的原型方法toStrig来判断数据类型;
3. 栈和堆的区别,为什么栈可以保存基础数据类型,为什么可以频繁操作
栈(stack)会自动分配内存空间,会自动释放。堆(heap)动态分配的内存,大小不定也不会自动释放。
基本类型:简单的数据段,存放在栈内存中,占据固定大小的空间。
引用类型:指那些可能由多个值构成的对象,保存在堆内存中,包含引用类型的变量实际上保存的不是变量本身,二十指向该对象的指针
4. 手写深拷贝
三种方式:
- 使用JSON.stringify和JSON.parse()
- 手写实现
function deepcope(obj) {
if (!obj || typeof obj !== 'object') return obj;
let newObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
newObj[key] = typeof obj === 'object' ? deepcope(obj[key]) : obj[key]
}
return newObj
}
let obj = {
a: 1,
b: {
c: 1
}
}
5. 重绘和重排,怎么减少重排?
重排:
通过构造渲染树,将可见DOM节点以及它对应的样式结合起来,计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是重排。
重绘:
我们通过构造渲染树和回流阶段,知道了哪些节点是可见的,以及可见节点的样式和具体的几何信息(位置、大小),那么我们就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘节点。
何时发生重排呢?
回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。比如以下情况:
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
- 页面一开始渲染的时候(这肯定避免不了)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
如何减少回流与重排呢?
- 批量修改元素样式
- 对于复杂的动画效果,可以先采用绝对定位,使其脱离文档流。否则会引起父元素以及后续元素频繁的回流。
- css3硬件加速(GPU加速)
参考博客:https://www.cnblogs.com/wangguoxinyue/p/16253671.html
6. 垃圾回收机制
- 标记清除:标记阶段需要从根节点遍历内存中的所有对象,并为可达的对象做上标记,清除阶段则把没有标记的对象(非可达对象)销毁。
- 引用计数:引用计数主要记录对象有没有被其他对象引用,如果没有引用,将会被垃圾回收机制收回。跟踪记录每个变量值被使用的次数,当变量引用次数为0时,垃圾回收机制就会把它清除掉。
什么情况会引起内存泄漏?
7. promise是什么 promise 有哪些方法,promise.all 和 promise.race 的区别(这两者里面的promise的执行顺序) 实现一个20个请求的串行和并行 promise(我讲了链式调用 但是面试官并不太满意,更优雅的方式)
then、catch方法,all、race方法。
- 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)
promise.all 和 promise.race 的区别:
- Promise.all方法会接收一个数组作为参数,并且返回一个新的promise实例,这个新实例的状态取决于数组中所有promise实例,如果所有实例都成功,则该新的promise实例的状态也为成功;通过then方法可以按顺序打印出对应promise的值
- Promise.race(arr)也会接收一个promise实例数组作为参数,含方法会返回一个新的Promise对象,该promise的状态取决于最先返回的那个promise的状态
实现一个20个请求的串行和并行 promise
我的思路是:
- 可以借助async和await方法实现并行和串行操作
- 并行可以采用.all方法
8. Promise如何用来进行限定并发请求个数的功能,说下思路?
参考博客
假设每次只能并发请求10个,即同一时刻最多只能有10个正在发送的请求。
每当10个之中有一个请求完成,则从待请求的接口中再取出来一个发送,保证当前并发度仍旧为10.
思路:
- 设定一个数组(命名为:pool),用于后续Promise.all的使用
- 当limitedRequest被调用的时候,首先一次性发出10个请求,并放入到pool中
- 每一个请求完成后的回调函数中继续触发下一个请求,而下一个请求返回-Promise,他的回调函数继续绑定同样的回调函数,即循环调用。
- 直到全部请求完成,停止。
9. 浏览器加载原理
VUE
1. React和VUE的区别
2. vue3有什么更新,为什么项目用vue2
浏览器
1. 浏览器如何渲染
2. 输入google会发生什么
3. 浏览器事件循环机制
4. 常见网络攻击
5. 浏览器本地化存储 cookie sessionStorage localStorage indexDB
6. 就比如那个promise,他问你怎么一张一张图片发,常规就是一直.then()下去,也可以用all去减少then的层级,用promise第一次请求的结果和第二次请求放到all数组里面,但面试官应该是想听到async await, await 请求一 await请求二 用同步的方式写异步,代码可读性可维护性都好。。
你说到了用gzip压缩请求数据,那你还了解其他相关的content-coding方式么?
计算机网络
1. https和http的区别
2. HTTP2有哪些特性
网页优化
1. 性能优化方式
2. 首屏优化方式
3. 首屏加载速度可以怎么改善
4. 如何提高页面加载速度
5. cookie 有什么值(似乎把 secure 和 httponly 弄混了)
设计模式
1. 简单说一下设计模式
2. 项目中用到了什么设计模式
数据结构
1. 常见的排序,堆排序
2. 平衡二叉树
3. 使用两个栈模仿队列