【前端】八股?干货?大乱斗

搜集网上内容自己总结的一些知识,有误恳请指正。

框架部分

  1. Vue和react框架最大区别
一句话:vue双向,react单向。vue自动挡,react手动挡。
展开说:
vue单文件组件(SFC),模板拥抱html,vue2声明式编程,vue对数据自动渲染
react使用JSX,jsx拥抱js,react函数式编程,对数据的改变要手动改变,例如用setState改变数据
  1. 简述MVVM
一句话:VM层 (视图模型层)通过接口从后台M层 (Model)请求数据,VM层继而和V (View层)实现数据的双向绑定
展开说:
MVC:M,V,Controller(控件)。最初版本,V会注册为M的观察者,页面发生交互,C决策后将响应传入到M。M和V之间能直接通信。
MVVM:M和V分离,通过M驱动V,开发者只需要关心M就行。
  1. 为什么用key
一句话:通过key,diff操作可以更准确、更快速。
展开说:
key可以让已有元素被复用,使虚拟DOM渲染更加高效。利用key的唯一性生成map对象比渲染时遍历更快。
  1. vue的响应式原理
一句话:通过数据劫持结合发布订阅模式的方式实现, 数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变;
展开说:
1、需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter.
	这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
2、compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,
	添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
3、Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是: 
	①在自身实例化时往属性订阅器(dep)里面添加自己 ②自身必须有一个update()方法 
	③待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
4、MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,
	通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,
	达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
  1. vue的双向绑定
    v-model,相当于v-bind和v-on的组合
  2. 向vue中data的对象属性添加新的属性会发生什么?该如何解决。
发生:新的属性虽然添加了,但视图未更新。因为Vue实例创建时,没有申明新的对象属性的属性名,
	Vue实例就不会将该属性转换为响应式属性,因此不会触发视图更新。
解决:用Vue的$set方法,把新属性处理成响应式的属性
  1. delete和vue.delete区别
对于对象没区别,对数组有区别。
delete会把删除的元素变成了empty/undefined,自然而然数组长度就不变。
Vue.delete是直接删除该元素,长度会变化。
  1. router的钩子
    beforeEachafterEachbeforeEnter
  2. Keep-alive
一句话:保存组件状态不被销毁。
展开说:用keep-alive包裹组件时,组件会被缓存而不会被销毁。可以保存组件状态、避免重复创建重复渲染。
	有三个属性,include 白名单,名称匹配才缓存
	exclude黑名单,匹配的不缓存
	max最多缓存的个数。
  1. vue生命周期
一句话:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed
展开说:beforeCreate:还没有初始化data和methods。可加载动画、页面拦截、动态加载判断。
	created:实例创建完成/模板编译完成,但未挂载渲染,不能操作dom。可使用data、methods。
	beforeMount:将要挂载,不能操作dom。
	mounted:挂载了。可操作dom。
	beforeUpdate:data新,页面旧。
	updated:都更新完。
	beforeDestroy:即将销毁。
	destroyed:已销毁。可销毁监听事件和定时器。
  1. 单页面(SPA)的优劣
一句话:SPA页面切换快,首屏请求慢,不利SEO。多页面相反。
展开说:
单页面应用的页面每次切换跳转时,不需要请求html,减少http发送,所以页面切换快
	首屏的请求不仅需要html,还需要js共两次请求,所以首屏请求慢。
	因为单页面的内容都是js渲染的,搜索引擎识别不到,所以不利于SEO
多页面应用的页面每次切换跳转时,都需要请求html,所以页面切换慢
	首屏的请求只需要请求html,所以首屏请求快
	因为多页面所有的内容都放在html中,所以有利于SEO
  1. computed和watch
一句话:computed依赖其他属性值,并且有缓存,依赖值变化就执行。watch监听的数据每次变化就执行。
展开说:
computed支持缓存,数据变化才执行。
	不支持异步,computed内含异步操作无法监听数据变化。
	必须是data或props的数据。
	如果属性的属性值是函数,则默认使用get方法,返回值就是属性值。数据发生变化调用set方法。
	如果一个属性依赖于其他属性,一般使用computed。
watch不支持缓存,数据变化就执行。
	支持异步
	监听接受两个参数,一个是new,一个是old。
	必须是data或props的数据
	immediate:组件加载立即触发watch。deep:深度监听,监听引用类型的内部的变化。
	如果要执行异步等响应不断的变化的时候,一般使用watch
  1. computed和methods
    computed只有依赖发生变化才会执行,methods只要调用就执行
  2. 为什么使用vue-router
    为了解决单页面网站,通过切换浏览器地址路径,来匹配相对应的页面组件。
  3. nextTick()
    在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。即:当数据更新了,在DOM渲染后,自动执行该函数。
  4. 数组操作和视图
//会更新视图的
push()		向数组末尾添加1或n个元素,返回新的长度。
pop()		删除最后一个元素,数组长度减 1,返回删除元素的值。 
shift() 	删除第一个元素,返回删除元素的值。
unshift()	向数组开头添加1或n个元素,返回新的长度。 
splice(第几位开始?(包括他自己也删掉),删几个?,在删除位置(前)加的元素,在删除位置加的元素,......) 	只返回删除值的数组
sort()		对数组的元素进行排序。
reverse() 	颠倒数组中元素的顺序。

//不会更新视图的,返回一个新的数组,使用新数组替换了旧数组
filter() 过滤数组
concat() 连接数组
slice(第几位后?,到第几位?) 浅拷贝
  1. v-if和v-for
    vue2中,v-for优先级高于v-if,vue3中相反。
  2. vue怎么做到局部刷新
    v-if先false再true或绑定key
  3. 事件捕获
1、父元素和子元素同时有点击事件
点击子元素,不想触发父元素的事件,可以采用阻止事件冒泡解决
@click.stop
2、设置捕获事件
父元素和子元素同时有点击事件
希望先触发父元素再触发子元素。
我们可以在父元素的点击事件加上
@click.capture
3、当只有点击自己本身元素才触发事件,忽略冒泡和捕获。
@click.self
4、事件只能触发一次
@click.once
原文链接:https://blog.csdn.net/weixin_42555713/article/details/108660192

HTML

  1. 说说iframe
一句话:iframe 元素会创建包含另外一个文档的内联框架(即行内框架)
展开说:
优点
- 用来加载速度较慢的内容(如广告)
- 可以使脚本并行下载
- 可以实现跨子域通信
缺点
- iframe 会阻塞主页面的 onload 事件
- 无法被一些搜索引擎所识别
- 会产生很多页面,不容易管理
  1. 原生js怎么操作dom
创建节点
1、createElement
2、createTextNode
3、createDocumentFragment
4、createAttribute
获取节点
1、querySelector
2、querySelectorAll
3、getByxxxxxxxx
queryxxx和getByxxx的区别在于,前者是静态的,获取到就不会改变,后者是动态的,会随dom改变而改变。
更新节点
1、innerHTML
2、innerText、textContent
3、style
添加节点
1、innerHTML
2、appendChild
3、insertBefore
4、setAttribute
删除节点
1、remove
2、removeChild
  1. svg和canvas
(1)SVG:
SVG 可缩放矢量图形(Scalable Vector Graphics)是基于可扩展标记语言 XML 描述的 2D 图形的语言,SVG 基于 *XML* 就意味着 SVG DOM 中的每个元素都是可用的,可以为某个元素附加 JavaScript 事件处理器。在 SVG 中,每个被绘制的图形均被视为对象。如果 SVG 对象的属性发生变化,那么浏览器能够自动重现图形。
其特点如下:
- 不依赖分辨率
- 支持事件处理器
- 最适合带有大型渲染区域的应用程序(比如谷歌地图)
- 复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
- 不适合游戏应用
(2)Canvas:
Canvas 是画布,通过 *JavaScript* 来绘制 2D 图形,是逐像素进行渲染的。其位置发生改变,就会重新进行绘制。
其特点如下:
- 依赖分辨率
- 不支持事件处理器
- 弱的文本渲染能力
- 能够以 .png 或 .jpg 格式保存结果图像
- 最适合图像密集型的游戏,其中的许多对象会被频繁重绘
  1. DOM
DOM树一共有12种节点类型,常用的有4种:
1、Document类型(document节点),不仅是document节点,也是节点树的根节点
2、Element节点(元素节点)——HTML标签,树构建块,所有的HTML elements都是element nodes
3、Text类型(文本节点)——包含文本,HTMLelement内的text内容就是文本节点
4、Comment类型(注释节点)——有时我们可以将一些信息放入其中,它不会显示,但JS可以从DOM中读取它。
  1. a标签打开位置
_blank新窗口
_parent父窗口
_self【默认】在当前页面(注意frame)跳转
_top
  1. 表单
    input有很多type选用
    button、password、text、radio单选、checkbox可选、date输入日期、file选择文件…等等
  2. 表格
<table>包裹,<caption>标题,<tr>行,<td>列,<tr><td></td></tr>
  1. 列表
有序列表<ol><li></li></ol>
无序列表<ul><li></li></ul>
自定义列表<dl><dt><dd></dd></dt></dl>
	<dl>包裹这个列表,<dt>是那一条表的标题,<dd>是那一条表的内容
  1. 可控制音频
    <audio controls>
  2. 报错执行事件视频
    <video onerror="">

CSS

  1. 给文字加下划线
    text-decoration属性和border-bottom
  2. 无限循环动画
    用CSS3的animation中的animation-iteration-count设置为infinite去实现
  3. flex布局
一句话:Flexible Box弹性布局,可以随页面大小自适应
展开说:
1、flex-direction:flex主轴的方向。决定子项的排列方向,比如row,就是按顺序一行过去;column就是按顺序一列下来。
2、justify-content:flex子项的对齐方式。比如flex-start,从头对齐;center,和中间对齐;flex-end,从尾对齐。等等。
3、flex-wrap:flex子项是否换行。
4、align-content:多行情况下的对齐方式。
等等。
  1. 行内元素水平居中
    父元素text-align:center
  2. 解决父容器塌陷
1、父容器添加overflow:hidden
2、父容器的伪元素::after内添加清除浮动clear:both
3、父容器添加inline-block
  1. animation
/*绑定名叫box的动画帧*/
animation-name: box;
/*过渡时间||动画持续时间,默认为0,不设置就会导致动画不能动*/
animation-duration: 1s;
/*动画重复次数,默认为1,infinite是无限循环,注意,是每次重新开始*/
animation-iteration-count: infinite;
/*动画变换的趋向:正常播动画、反向播动画等等*/
animation-direction: alternate;
/*动画播放的方式,线性或是慢速-加速-慢速等等*/
animation-timing-function: linear;
//linear	动画从头到尾的速度是相同的。
//ease	默认。动画以低速开始,然后加快,在结束前变慢。
//ease-in	动画以低速开始。
//ease-out	动画以低速结束。
//ease-in-out	动画以低速开始和结束。
//cubic-bezier(n,n,n,n)	在 cubic-bezier 函数中自己的值。可能的值是从 0 到 1 的数值。
  1. 背景定位属性
    //图源:W3C
    W3C关于此属性的描述
  2. 伪类选择器
:nth-child(),even找偶数,odd找奇数

JS

  1. 堆和栈区别?
一句话:栈自动分配的、内存固定大小、编译器自动分配释放、先进后出(FILO),
	堆动态分配、内存大小不固定、开发者分配释放、按优先级。
展开说:
栈速度快容量小,有序存储,用完就回收
堆速度稍慢容量较大,指针在栈内存,不容易销毁除非没有任何引用变量引用他,系统的垃圾回收机制才会回收。
  1. 介绍Set、Map、WeakSet 和 WeakMap
一句话:Set集合、可存储任何。Map键值对、可存储任何。两者Weak前缀的只能接受对象,而且对象不列入垃圾回收机制
展开说:
Set,成员唯一且无序,有iterator接口。方法:add、delete、has、clear
WeakSet,相较于Set,只接受对象作为成员,并且弱引用
Map,相比于obj更完善的键值对,能记住原始插入顺序。方法:size、get、delete、has、clear
WeakMap,相较于Map,只接受对象作为键名,并且弱引用
  1. 字符串去掉第一个字符
    substring(第几位之后,到第几位) slice(第几位之后,到第几位),splice(第几位开始删除,删几个)
  2. ES6新特性
let和const、解构赋值、Symbol和BigInt、Promise对象和async函数、class语法、Map和Set数据结构
  1. apply和call的区别
二者都会改变this的指向并执行函数。不同的是apply接受的参数是一个数组,而call接受的参数是逐个传入的。
  1. JS的作用域
一句话:变量与函数的可访问范围,控制着变量与函数的可见性和生命周期。分为全局作用域和局部作用域。
展开说:内部作用域可以访问外部作用域,反之不行。
	访问变量、函数、对象时,采用就近原则。
  1. async和await可以分开用吗?
    await必须在async函数内使用。
  2. 原型和原型链
函数是一等公民。__proto__ === [[Prototype]],后面这个是浏览器显示的写法,和__proto__是一个含义。
所有的引用类型都只有__proto__这个指针,指针指下去的是对应的构造他的prototype原型对象,
这个原型对象里包含的__proto__指针,又会指向对应的prototype,然后再顺着__proto__,
最后找到Object.prototype原型对象,他的终点__proto__是null,这一串下来就是原型链。

以函数new一个实例为例子:
函数new的实例的__proto__指针指向的是他对应的构造函数的prototype原型对象。
而这个prototype对象包含的__proto__指针,指向的是Function的prototype原型对象,
在Function的prototype中,他的__proto__指向Object.prototype。这个Object.prototype的__proto__指向null,即终点。
prototype(原型对象)是函数特有的,我们可以在上面添加属性,通过new的方式去继承这些属性。
  1. js垃圾回收机制
一句话:垃圾回收机制主要分为引用计数和标记清除。
展开说:
引用计数:当一个变量进行声明时它的标记就会+1,当他被使用之后就会-1,当这个变量的标记为0时候,就会被系统自动回收。
		但引用计数无法解决循环引用的问题,所以需要标记清除算法。
标记清除:当一个变量被创建之后进入一个使用环境就会被标记,当他被使用之后退出这个使用环境之后就会被系统自动清除。
  1. hash和history
hash 通过监听浏览器 onhashchange 事件变化,查找对应路由应用。通过改变 location.hash 改变页面路由。
history 利用 html5 的history Interface 中新增的 pushState() 和 replaceState() 方法,改变页面路径。
  1. 深拷贝和浅拷贝
一句话:对于基本数据类型,深浅都是new一份。对于引用数据类型,深拷贝new一份,浅拷贝复制地址。
展开说:浅拷贝时,原始对象和拷贝对象共享相同的引用,对其中一个进行修改都会影响到另一个,
	所以有的时候需要深拷贝new一份避免影响。深拷贝需要使用JSON.parse(JSON.stringify(obj))或者lodash库的cloneDeep
  1. 函数有哪些创建方式
一句话:普通函数、匿名函数、箭头函数、构造函数
展开说:
普通函数-function f(){}、var f = function(){}、var f = new Function(参数,函数体)-this指向全局
匿名函数-function(){}-this指向全局(触发事件的元素)
构造函数-function f(){this.参数=参数}- this指向new的对象
箭头函数-()=>{}-this指向离他最近的this(捕获事件处理中的上下文)
  1. 箭头函数优劣
它的优点是:
(1)简洁的语法、
(2)隐式返回,如 下面的代码可以去掉return,代码移到一行,减少代码量numbers.map((number)=>number*2)
(3)解决了this的指向问题,原生的写法this指向的是调用者,箭头函数this绑定的是定义时的那个对象。如果有对象嵌套的情况,则this绑定到最近的一层对象上
它的缺点是:
(1)作为构造函数的时候不能使用箭头函数
(2)真正需要this的时候如给元素绑定click事件的 时候,执行的回调函数不能使用箭头函数。
(3)我们需要使用arguments对象的时候不能使箭头函数。箭头函数中没有arguments对象。
(4)对象的方法也不可以使用箭头函数
  1. 函数传参
    js只有值传递,对象就给指针,基本数据类型就给复制的值。
  2. 0.1+0.2=0.3吗,为什么?
    因为二进制,所以不等于。通过toFixed(num) 方法(0.1+0.2).toFixed(1)把他四舍五入保留一位小数,或(0.1*10+0.2*10)/10,使计算正确。
  3. JS类型转换
一句话:显式类型转换(toString等方法)、隐式类型转换(各种运算符,包括==)
展开说:类型转换实际上只有三种类型的转换。1.变string,2.变boolean,3.变number。在这三种变化的基础上,又分为显式和隐式。
显式类型转换
	1.变string:
		number:3+2变'5'、0x12变'18'、NaN变'NaN'等等
		其他的原始类型都是按相应语义变成string。false变'false'、null变'null'等等
	2.变number:
		string:'0o70'变56、'034'或'  34'这种带空格的变34、不认识的表达式或者英语等等的变NaN
		null变0,false和true对应01,undefined变NaN
	3.变boolean:
		非空非0非NaN变true
		0、-0、NaN、null、undefined、""变false
隐式类型转换
	这篇博客 https://www.freecodecamp.org/chinese/news/javascript-implicit-type-conversion/#1-
	
  1. instanceof
判断原型链中是否能找到该类型,只适用于判断引用类型。
//手写实现
function test(left,right){
	// 对于左侧参数如果是非对象直接返回false
	if (Object(left) !== left) return false
    // 对于右侧参数可以认为只能为函数且不能没有Prototype属性
    if (typeof right !== 'function' || !right.prototype) throw new TypeError('Right-hand side of 'instanceof' is not an object')
    // 声明一个变量获取对象的__proto__
    let link = left.__proto__
    // 做循环(当link最终指向null,如果指向null的情况下都找不到那就返回false)
    while (link !== null) {
        // 如果找到说明right.prototype在left的原型链上,即返回true
        if(link === right.prototype) return true
        // 逐级向下
        link = link.__proto__
    }
    return false
}
test(1,Number)	//false
test([],Array)	//true
  1. 闭包
原理:作用域链,当前作用域可以访问上级作用域中的变量。
展开说:在一个函数内部创建另一个函数。
实现私有变量并且使上下文变量不会被垃圾处理机制回收。
私有变量可以通过写一个特权方法放到函数的原型上,通过特权方法访问私有变量。
缺点在于:常驻内存会增大内存使用量,使用不当会造成内存泄漏。
  1. this的指向
1)函数作为方法调用,this指向全局
2)函数作为对象属性,this指向对象
3)函数作为构造函数,this指向new的对象
4)箭头函数的this指向上一级作用域的this
5)apply,call,bind
优先级:3 > apply,call,bind > 2> 1
  1. promise的前身、promise解决什么问题、promise常用api
一句话:deferred。解决回调地狱问题:代码可读性、信任。promise.resolve、promise.reject、promise.then、promise.all、promise.race
展开说:promise的前身是deferred对象,随着jq1.5之后引入deferred后被广为人知。
	它解决了三个问题,回调地狱重点在于回调,它的嵌套是异步的嵌套。主要表现在 对代码可读性不好、并产生信任问题
可读性不必赘述,信任问题表现在回调时候,回调早了回调晚了回调多了回调没了等等,而promise只会决议一次,一旦状态变了就不会再变。
	.then为Promise实例添加状态改变时的回调函数,返回新的Promise实例,.catch是发生错误的时候用的。
	.all将多个Promise实例包装成一个新的Promise实例。全部成功返回结果数组,一个失败就直接返回失败的错误信息
	.race将多个Promise实例包装成一个新的Promise实例。一个成功就返回成功的结果状态。
  1. async函数
    用于声明异步函数,直到await的事情做完返回promise的实例
  2. JS查找元素的方法
getElementById、getElementsByClassName、getElementsByTagName
querySelector、querySelectorAll
  1. JS标准事件模型的顺序
    事件捕获->事件处理->事件冒泡
  2. JS内置对象
1、String:处理字符串
2、Number: 处理数字
3、Boolean;处理布尔值
4、Date: 处理日期
5、Math:计算和处理数字
6、REgEx:匹配文本的字符串模式
  1. websocket
WebSocket 是 HTML5 新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道。
服务器可以在任意时刻发送消息给浏览器。不同于http的要啥就要请求,没有请求服务器不能主动发送信息。
websocket中,浏览器和服务器只需要做一个握手的动作。
websocket客户端基于事件的编程模型与 node 类似。
  1. 跨域问题
跨域问题是由于浏览器的同源协议导致的。
当前页面中的某个接口请求的地址和当前页面的地址如果协议、域名、端口其中有一项不同,说明该接口跨域了。
解决办法:
1、后端配置cors设置允许跨域
2、前端配置proxy代理服务器
3、niginx反向代理
  1. 手写typeof
function _typeof(value) {
    let str = Object.prototype.toString.call(value)
    str中的字符串是'[object 类型]',所以要把无关的去掉。
    let substring = str.substring(8, str.length -1).toLowerCase()
    return substring
}
  1. 手写instanceof
function _instanceof(left,right){
	// 左侧如果是非对象直接返回false
	if (Object(left) !== left) return false
    // 右侧只能为函数且不能没有Prototype属性
    if (typeof right !== 'function' || !right.prototype) throw new TypeError('Right-hand side of 'instanceof' is not an object')
    // 声明一个变量获取对象的__proto__
    let temp = left.__proto__
    // 做循环(当temp最终指向null,如果指向null的情况下都找不到那就返回false)
    while (temp!== null) {
        // 如果找到说明right.prototype在left的原型链上,即返回true
        if(temp=== right.prototype) return true
        // 逐级向下
        temp = temp.__proto__
    }
    return false
}
  1. Array.from()
    他可以接收三个参数。第一个是操作的目标,可以是类对象和数组。类对象就比如Set或者键为数字注明length的对象。第二个参数类似map操作,可以写value=>value*2这种。第三个参数是第二个参数函数的this
  2. Array.property.join()
    数组转换为字符串并且在连接处加字符。join(‘加的东西’)
  3. 阻止冒泡事件
监听dom元素的操作,例如点击等操作。这些操作触发的事件就是冒泡事件。
通过设置stopPropagation(),代码如下。
dom.addEventListener('click',e=>{
            e.stopPropagation()
        })
  1. 阻止默认事件
监听dom元素的操作,例如点击等操作。这些操作有的会触发默认事件,例如多选框的取消选择。
通过设置preventDefault(),代码如下
dom.addEventListener('click',e=>{
            e.preventDefault()
        })
  1. 获取当前页面url地址
    window.location.href
  2. DOM0、DOM2、DOM3事件模型
DOM0原始事件模型,js中html元素都有一个对应的对象,这个对象的属性对应那个html元素的性质,所以可以用js代码添加事件监听函数。
	说白了,DOM0就是onxxx的api,比如onclick
DOM1没有定义事件相关内容,所以DOM1事件模型不存在。
DOM2事件模型增加了addEventListener()这类方法。
	包括三个阶段。捕获阶段、目标阶段和冒泡阶段。
	捕获阶段事件从最外层逐级向下到达目标节点,冒泡阶段相反。这两个阶段都可以绑定事件处理函数。只支持事件冒泡的事件处理。
DOM3事件模型支持更多的事件类型,并且支持事件捕获的事件处理
  1. 生成随机数
Math.floor(Math.random() * (max - min)) + min; //不含最大值最小值
Math.floor(Math.random() * (max - min + 1)) + min; //含最大值最小值

前端工程化

  1. webpack和vite区别
    webpack使用Node.js 编写的打包器从入口点开始逐步构建一个依赖图,然后将项目中所需的模块组合成一个或多个bundle文件,即逐级递归识别依赖,构建依赖图谱 ;
    vite无需进行bundle操作,源文件之间的依赖关系通过浏览器对ESM规范的支持来解析,将应用中的模块区分为 依赖(node_modules) 和 源码(项目代码) 两类;

  2. webpack的loader
    loader分为三种,未配置enforce的默认normal-loader和enforce:'pre’前置pre-loader、enforce:'post’后置post-loader。除了这三种还有一个是loader内的pitch-loader。如果没有配置enforce,就按照从右到左/从下到上的顺序执行这些loader。而pitch-loader是loader运行过程中执行的。

  3. loader的运行过程-参考
    在运行时,会先执行pitch-loader(读取资源文件)再执行normal-loader(处理资源文件)。normal-loader按照先后顺序执行,pitch执行顺序和normal相反。如果pitch有返回值,就会舍弃自己和之后的normal-loader(熔断),然后执行上一个normal-loader(这里打个问号,没懂)
    以vue-loader为例,运行过程粗略分为两个阶段:预处理和内容处理。
    预处理:动态修改webpack配置,注入vue-loader专用的rules,先初始化pitcher对象,确保pitch-loader在normal-loader前运行。然后复制rules列表进行修改配置。
    内容处理:对代码内容进行转换。例如原始代码是导入某某路径的vue内容,命中了vue-loader,先进行第一次转化,生成结果A,再对结果A进行转换,调用pitcher(pitch-loader)生成结果B,最后由结果B命中具体的loader(style-loader、css-loader等等)直接进行处理

  4. webpack的优化

1)缩小loader的文件范围:在modules.rules中,使用include和exclude、test给以文件范围。
2)优化resolve:resolve.modules指定查找的目录
							resolve.alias定义文件目录的别名,例如常见的@
							resolve.extensions给没有文件名后缀的文件添加后缀
3)通过相关插件压缩CSS、HTML
等等,很多,列举了一些用过的

网页相关

  1. 网址到网页全过程
一句话:域名解析-发起请求-返回数据-接收文件-文件解析-载入数据-渲染界面
展开说:
解析url:分析使用的协议和请求的路径。检查url是否出现非法字符
查看缓存:判断本地是否缓存,若有则判断是否新鲜
DNS解析:依次判断缓存
获取MAC地址
TCP三次握手
返回数据
页面渲染
TCP四次挥手
  1. 如何优化网页性能
1、减少http请求:文件合并、压缩文件、本地缓存
2、使用CDN
3、防抖节流,懒加载预加载按需加载
4、减少重排重绘:CSS3动画、transform、opacity、避免频繁dom操作
  1. 网页安全

计算机网络

  1. HTTP1.0、1.1、2.0协议的特性及区别
1.0:无状态,服务器不跟踪不记录请求过的状态
	无连接,浏览器每次请求都需要建立tcp连接。
1.1:长连接:保持连接不断开
	支持请求管道化
2.0:二进制分帧
	多路复用
	服务器推送
	头部压缩
  1. http协议
HTTP是基于TCP协议之上的应用层协议
HTTP是超文本传输协议
HTTP1.1才有cache-control
HTTP协议的ETAG响应头主要用于信息的过期验证
HTTP协议必不可少的三项内容:请求行,请求头,空行
HTTP请求方法在服务器中即使部分实现了,考虑到安全问题,也不一定会用
  1. http状态码
    牛客评论区
    301永久、302临时
    400语法错误、401未认证、403无权限、404找不到
  2. TCP和UDP区别
TCP是有连接的可靠的传输控制协议,适用可靠传输应用,例如文件传输
TCP需要三次握手(客-服-客)四次挥手(客-服 服-客),只支持单播
TCP面向字节流,所以可以实现可靠传输,流量控制,拥塞控制
UDP是无连接不可靠的用户数据报协议,适用实时应用,例如腾讯会议
UDP可以直接进行数据传输,支持单播、多播、广播
UDP面向应用层报文
  1. 计算机网络模型

  2. websocket
    即时通讯,替代轮询

websocket是全双工通信的协议,建立在TCP上,只需要一次握手。

计算机基础

  1. 正则表达式基础知识-例如/^\$\d{1,3}(,\d{3})*(\.\d{2})?$/
\d表示数字 
\w表示字母数字下划线 
\s表示任何空白字符
他们的大写表示规则相反

.表示除换行符外所有的字符
[A-Z]表示这个闭区间内的所有字符
[abcde]表示这些字符

?表示0或1,在量词后还表示尽可能少地匹配
+表示1或更多
*表示0或更多
{n}表示n个 {n,}表示大于等于n个 {n,m}表示n到m个

^表示从头匹配,放在匹配字符的前面,例如^\w
$表示从尾匹配,放在匹配字符的后面,例如\w$
\b表示匹配空格前的\w
\B表示匹配\w前的\w

先行断言(?=正则表达式):某个位置之后的内容满足一定的条件,但并不实际消耗匹配的字符。
非捕获表达式(?:正则表达式):将一组匹配的子模式作为一个整体进行处理,但不会捕获或分组保存匹配的结果
  1. test、exec、match
    test返回匹配的Boolean结果
    exec以数组形式返回匹配结果,如果指定了参数g,下次的匹配会从上次匹配的lastIndex开始。
    match是String对象的方法,上面的test和exec是test(str),而match是str.match(reg)。如果指定了参数g,会一次性返回所有的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值