HTML
1、行内元素有哪些?块级元素有哪些?空元素有哪些?
行内元素:span、img、input、em、i、label...
块级元素:p、h1、div、ol、ul、table、form...
行内块元素:img、input(可以设置宽高)
空元素:br、hr、meta、img、link
涉及元素之间的转换:display属性
2、link和@import的区别
link是html的标签,@import是css的样式规则。
link能加载样式文件、图片等资源,@import只能加载引用样式
link与引入的css被同时加载*(并行),@import页面后加载(串行)。
后者兼容性差。
3、title与h1,strong与b的区别,i与em的区别
title是网页标题,h1是内容。网站seo(网站搜索优化)层面上,title级别更高
加粗:语义化区别,b只是加粗,strong且有强调(阅读器)作用。
倾斜:i多用在做图标,em也有强调作用。
4、img的title和alt属性的区别
title:鼠标移入图片时显示。
alt:图片不加载时显示。
5、jpg、png、gif的区别
jpg:适合大图片,同样的图片相对用png体积更小。(失帧)
png:适合小图标,同样的图片体积更大。(失帧小)
gif:动态图
6、DOCTYPE作用
DOCTYPE是一种文档类型声明,它的目的是告诉浏览器(解析器)应该以什么样(html或xhtml)的文档类型定义来解析文档。它必须声明在HTML⽂档的第⼀⾏。
浏览器渲染页面的两种模式:标准模式和怪异模式。
7、meta标签的理解
meta标签由name和content属性组成,用来描述网页文档的属性。
charset,用来描述HTML文档的编码类型。
name:keywords、description、viewpoint
8、input和texarea的区别
input是单行文本框,通过size属性限制字符长度,可以设置宽高,但始终是一行。
texarea是多行文本输入框,使用cols和rows规定尺寸。
9、src和href的区别
src:source的缩写,直接加载出引入的资源。img、style、video、audio。
当浏览器解析到该元素时,会暂停其他资源的下载和处理,进行资源请求。
href:建立与外部资源的连接通道。a、link。
10、语义化标签
语义化就是用合适的标签用在最恰当的内容上。
1、没有样式情况下,语义化标签呈现清晰结构,方便机器和工作人员阅读代码。
2、有利于seo,提高关键字权重,使爬虫抓取更多有效信息,提高搜索引擎名次。
3、方便盲人阅读器等设备渲染页面。
11、HTML5新增标签
header:网页头部,footer:网页底部,nav:网页导航,section:区段
article:独立内容,aside:侧边栏。
12、HTML5新特性——
1、各种新增表单类型:email、number、date、week、search、range、color
datalist、option:选择表单
2、音视频——video、audio
controls="controls"用户控制音乐, loop="loop"循环播放, preload="auto"自动播放。
3、画布——Canvas+SVG
Canvas:画布,位置发生改变会重新绘制。getElementById——getContext
SVG:可缩放矢量图,基于XML。
4、本地存储——localstorage、sessionstorage
5、可编辑属性:contenteditable
广泛应用在用在网页编辑器、编辑状态。在标签内部加入contenteditable=“true”
5、Web worker
在执行脚本时,页面的状态是不可相应的,直到脚本执行完成后,页面才变成可相应。
6、drag拖放事件
7、地理位置API
13、svg是什么?怎么使用?
svg是可伸缩矢量图形,图形在放大或者改变尺寸的情况下图形质量不会损失。
画图:rect(矩形),polygon(多边形)、circle(圆形,cx和cy定圆心)、ellipse(椭圆)
结合css的animation产生动画效果。
14、canvas是什么,怎么使用?
html添加Canvas标签,设置ID、宽度和高度
js通过getElementById获得canvas标签,使用getContext确定图片类型。
//绘制三角 function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(50, 50); ctx.lineTo(200, 50); ctx.lineTo(200, 200); ctx.closePath(); //虽然我们只绘制了两条线段,但是closePath会closePath,仍然是一个3角形 ctx.stroke(); //描边。stroke不会自动closePath() } draw();
css
1、css盒子模型
盒子模型:标准盒子模型、IE盒子模型
标准:margin+border+padding+content。
IE:margin+content(border、padding、content)
盒子模型转换:box-sizing:content-box(标准),border-box(IE盒子)
1、盒子塌陷与解决方案
盒子塌陷:内部盒子跑到父盒子的外部
原因:内部盒子脱离文档流
解决:清楚内部盒子浮动、父亲盒子高度写死。
2、line-height和height的区别
line-height:每行文字的高度,如果文字换行则整个盒子高度增大(行数*每行高)
height:盒子的纯高度。
line-height:height值,文字垂直居中。
3、css选择器有哪些?哪些属性可以继承
通配符选择器(*),id选择器(#),类选择器(.),标签选择器。
相邻选择器(+匹配一个,~匹配多个),后代选择器(空格),并集选择器(,),子元素选择器(>),
属性选择器(input[disabled])
可继承样式:字体font系列,文本line-height、color、text-align,list-style。不可继承:border、margin、width、height
3、伪类选择器和伪元素选择器
伪类
状态伪类:lvha
否定选择器:div:not(span)选中出来除了括号里的其他元素其他:div:first-child div:last-child div:nth-child() div:nth-of-type(锁定类型)
伪元素
div::after
div::before
div::selection 设置选中文本的样式
4、css优先级算法
!important>内联样式>id选择器>类选择器(属性、伪类)>标签选择器(伪元素选择器)>通配符
权重:max 1000 100 10 1 0
5、画三角形(用border)
width和height设置为0
border一个边设置为:100px solid 颜色
另外三个边框设置为:100px solid transparent(透明)。
6、水平垂直居中
display:inline-block;margin:0 auto(水平居中)
1、用flex布局给父元素设置:
display:flex;
justify-content:center;
align-items:center
2、grid布局:
父:display:grid
align-items:center
justify-items:center
或者直接写place-items:center
3、用定位动画给自己设置
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%)
4、table-cell
display: table-cell;
text-align: center;
vertical-align: middle;
flex布局
弹性布局,
父元素:
子元素:
order:排列顺序
flex:2 相当于 flex:2 1 0%。flex-grow为2,flex-shrink为1(可伸缩),flex-basis为0
gird布局
grid-template-columns: 200px 200px 200px;三列宽度
grid-template-columns: repeat(3,200px);
grid-gap: 5px;每个单元格间距定义区域,子元素grid-area匹配
7、BFC
BFC:块级格式化上下文,就是将这容器变成完全独立的个体,不会影响到外面的元素。
可以触发bfc的条件有:
float不为none,
overflow不为visible,
display:inline-block,table-cell
position为absolute、fixed。
常用:overflow:hidden
8、清除浮动影响的方式
1、触发BFC,例如用overflow:hidden
2、ul:after{
dispaly:block;
content:"";
clear:both
}
9、position定位
static:默认值,不定位。
relative:相对定位,相对于原来自己进行定位。(对其他元素不太影响,不脱离文档流)
absolute:绝对定位,相对于已定位的父元素进行定位(没有的话就是浏览器大框)。
fixed:固定定位,相对于浏览器大框进行定位。
sticky:粘性定位,在屏幕范围(viewport)时该元素的位置并不受到定位影响(设置是top、left等属性无效),当该元素的位置将要移出偏移范围时,定位又会变成fixed,根据设置的left、top等属性成固定位置的效果。(页面变化+relative+fixed)
边偏移属性:top:100px(向下移动100px),right,left,bottom。
(relative如果有上下左右,只要上和左的,absolute则全有)
10、双飞翼布局(左右200宽,中间自适应,先加载中间)
1、中左右顺序设置模块,给左设置margin-left:-100%,给右设置margin-left:-200px
2、子项目设置flex-shrink属性,0为固定,1为可伸缩,自适应的设置flex:1
11、什么是 css reset
reset.css,是css一个css文件,重置css样式。
例如还有normalize.css,同样也是。
12、css sprite是什么?优缺点?(雪碧图、精灵图)
sprite是把多个小图标合并成一个大图片。
使用:ps或者第三方工具CSS sprites generator
优点:减少http请求次数,提升了性能。
缺点,维护性比较差(如果内容更改)
13、进程和线程
进程:一个进程就是一个程序运行,启动程序,系统会为它创建一个内存,程序的一个运行任务会在一个线程,任务所在的大运行环境叫做进程。
线程:程序执行的最小单位。
线程依附于进程
进程的任意一个线程执行出错,都会导致整个进程的崩溃,其他线程不能运行。
一个大程序有多个进程,其中一个崩溃不影响其他的
浏览器进程:浏览器每一个页签都是一个独立的进程,进程内的线程只会影响自己。
渲染进程:将html、css、js渲染成网页,浏览器回为每一个Tab标签创建要给渲染进程。(包括GUI渲染线程、js线程,定时器线程)
13、浏览器渲染线程
根据url,通过网络请求,得到服务器传来的代码,返回文本文件,浏览器将文件转成html。
根据html解析器对html文件解析根据节点生成DOM树,
根据CSS解析器对css文件解析生成cssom。
将DOM和CSSOM整合形成render tree(计算布局数据)
根据render tree开始绘画渲染(重绘)、布局展示(回流)
(布局进行分层,每个图层生成绘制列表,图层分成块,光栅化图块转换成位图)
分层为了提高渲染性能,例如动画渲染不影响其他图层。
光栅化目的是将不需要的图块不做渲染。
提升图层:will-change:transform
遇到link、script时,去请求响应文件。
js文件最好写在最后,不然会阻塞渲染,
14、display:none和visibility:hidden的区别。
display:none,隐藏后不占用原位置。产生重绘与回流。
visibility:hidden,隐藏后占用原位置。产生重绘,不会回流。
宽高都设置为0
原理:浏览器渲染过程↑ +重绘与回流(重排)↓
14、隐藏某个内容的方法
1、opacity:0;
2、visibility:hidden;
3、display:none
15、重绘与回流(重排)
回流(重排):当render tree的元素改变了自身的宽高、布局、显示或隐藏,或者文字结构改变,产生回流。
重绘:只是改变各元素的外观(颜色等),产生重绘
回流必有重绘。
优化,避免回流:
不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。
定位使用absolute或者fixed脱离文档流。
transform 代替 top,left ,margin-top, margin-left... 这些位移属性。
16、透明:opacity与rgba的区别
都是实现透明的效果。
opacity:取值0-1,0表示完全透明,1表示完全不透明。会继承给子元素
rgba:(red,green,blue,透明度取值0-1),不会继承。
17、position、display、overflow和float的优先级
position:absolute/fixed优先级最高,有他们在时,float不起作用,display值需要调整。float 或者absolute定位的元素,只能是块元素或表格。
18、解决上下margin重合的问题
在其中一个盒子外包一个div,并对其触发BFC
19、伪元素,::before 和 :after中双冒号和单冒号有什么区别?解释一下这2个伪元素的作用
css3规范使用双冒号,单冒号是hover等伪类。
css3新特性
border-radius、transition、transform、animation、
渐变:background:linear-gradient
transform
20、css实现动画
transition常见属性
transition-property:设置的属性名如height
transition-duration:过渡时间
transition-delay:延迟时间
transition-time-function:速度变化,默认ease(缓冲)
(四个可以合并使用。)
缺点:一次性,不能重复发生。需要事件出发,不能在网页加载时自动发送。只能定义在一个对象上。只有开始和结束状态。
animation可以实现上面缺点
除了上方四个属性,还有:
animation-name:给动画起名字
animation-iteration-count:循环次数
结合@keyframes name{ }使用。
21、实现loading图(加载图),四分之三圆并旋转。
1、设置border-radius:50%产生一个圆,再设置其中一条border为透明色。
2、动画:为设置的四分之三圆设置rotate旋转动画,用infinite设置无限循环
22、Flex布局
父级:
flex-direction:主轴方向
justify-content:主轴上对齐方式(水平)
align-items:侧轴上对齐方式
flex-wrap:是否换行
子级:
align-self:子元素在侧轴对齐方式
order:排序,越小越靠前
flex:flex-grow(占比几份)、flex-shrink(0固定、1自适应)、flex-basis(auto)
23、px、em、rem、vh、vw区别
px:像素单位
em:font-size的大小,默认1em=16px,会继承。em值对font-size变化而变化。决定部分
rem:根据html根的font-size大小决定。1rem=16px。rem值固定,可以调整整体文字。决定所有
vw、vh:宽高的1%
24、让超出宽度的文字显示省略号
white-space:nowrap。设置为不换行
overflow:超出隐藏
text-overflow:显示...
25、瀑布流布局
box:flex+column+wrap+height:100vh
item:calc(100%/n)
26、postcss
提供了一系列插件,对css内容进行转换,npm后配置各种官方提供的属性插件,比如可以加浏览器前缀来兼容不同浏览器。
27、z-index失效情况
父元素设置为relative,子元素z-index失效。(解决:父元素改为absolute)
设置float,该元素z-index失效
28、requestAnimationframe是什么
浏览器自带api,用于执行连续的动画,减少页面卡顿,提高动画性能。
js实现动画通常是调整元素style结合定时器。但是动画多,会卡顿,因为定时器是异步任务(要等主线程任务完成)。而且好像会有丢帧现象(刷新频率)
requestAnimationframe执行动画的时间由系统的刷新频率决定。传参是函数。
JS
1、延迟加载js有哪些方式
延迟加载:async、defer(无论js的位置在哪里)
两者区别:
async:异步加载,此时js的下载和html的解析一起走,但不确定js的执行顺序。
defer(最好): 异步加载并推迟执行,再执行js文件代码,顺次执行js脚本。
2、js数据类型有哪些?
基本数据类型:string、number、Boolean、null、undefined、symbol、bigint
引用数据类型:object(array、function)
数据类型转换:
toString()转化成字符串。
Number()转换成数字。有一个字符不是数值就返回NaN
parseInt()转化成数字。第一个字符不是数字就返回NaN
Boolean()转化成布尔值
2、symbol和bigint
symbol:
可以给对象设置一个私密属性,别人访问不到。属性值不会被改写或者覆盖。
let id1 = Symbol('id');symbol同一个变量生成的值也不相等。for in和object.keys都访问不到,可以用getOwnPropertySymbols访问
bigint:大整数、提供一个表示大于2^53-1的整数。
number只能支持-2^53-1到2^53-1的数,超过就会失去精度,被四舍五入。
var bigInt = BigInt("9007199254740999")
2、如何判断一个数是整数
1、toString+正则
2、parseInt结果与原值比较
3、Number.isInteger()
4、对1取余是否为0
2、数据类型判断:数据类型的判断_在寒夜等候光明的博客-CSDN博客_判断数据类型的方法
typeof:判断类型number, string, boolean, function, undefined,object(对象或者null)
instanceof:一般用来判断引用数据类型的判断,如:Object,Function,Array,Date,RegExp等。原理:右边变量的 prototype 在左边变量的原型链上。
constructor:当一个函数被定义时,JS会为函数添加prototype原型,然后再在prototype上添加一个constructor属性,并让其指向F的引用。
object.prototype.tostring.call()精准判断
3、null和undefined的区别
作者先设计的null,后设计的undefined。但是null==undefined,null===null,undefined===undefined
null是“空”,undefined是“未赋值”。
typeof(null)结果是object,number(null)为0。
typeof(undefined)为undefined ,number(undefined)为NaN
false == undefined是false,因为会被转化为数字:null 被转化为 0,undefined 被转化为 NaN。
4、==和===的区别
==:比较的是值
其中原理是原型的valueof隐式转换,在内部自动调用,不会显式改变。
===:比较的是值和数据类型。
4、隐式转换和显式转换
隐式转换:自动转换数据类型(转换了但是不显示),==判断、运算
显示转换:强制转换。number()、boolean()、parseInt()
5、js的执行机制。
JavaScript是单线程的语言,前一个任务执行完执行下一个任务。
同步任务:主线程上排队执行的任务。
异步任务:不进入主线程,进入任务队列。主线程任务完成,执行异步任务。
js代码执行顺序是:同步任务=》进入任务队列的异步任务进行事件循环(微任务全部完成=》宏任务)
同步:clg,for循环,promise紧跟着的代码。
微任务:promise.then,async的await。
宏任务:setTimeout,ajax请求
6、关于作用域、变量提升:JavaScript函数作用域 - Web前端工程师面试题讲解_哔哩哔哩_bilibili
只有函数才会有作用域,for循环可没有。
作用域分为全局作用域、局部作用域、块级作用域。
函数内部可以访问外部的变量,但是外部不能访问内部的变量。
优先查找内部的变量,内部没有,再去外部找。(作用域链)
js的var有声明提升,函数也会声明提升,函数的提升高于变量的提升。
7、js对象考题
1、对象是new出来的,所以相同对象不相等。【1,2,3】==【1,2,3】结果是false。
2、对象是引用数据类型,数据在堆内存的一个共同的内存地址中。
3、对象的key值都是字符串类型。
4、对象查找属性/方法的顺序:
对象自身——构造函数自身——对象原型——构造函数原型——object
7、object的api有哪些
Object.defineproperty(obj,prop,属性描述符)
直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
Object.keys(obj)
返回给定对象的自身可枚举属性的数组
Object.values(obj)
返回给定对象的自身可枚举属性值的数组
Object.entries(obj)
返回给定对象的自身可枚举属性和属性值的双层数组
Object.assign(obj1,obj2)
合并对象
Object.getPrototypeOf()
读取对象的原型对象
7、面向对象的三个特征
封装:可以隐藏实现细节,使得代码模块化
继承:可以扩展已存在的代码模块,为了代码重用
多态:相同的事物,调用其相同的方法,参数也相同时,但表现的行为却不同。
7、模块化的CommonJs和es6的区别
都是js模块化、
node,前者是module.exports+require方式的模块化,输出的是一个模块的拷贝,运行时加载
js,后者是import 、exportt(export default)方式的模块化,输出的是模块的引用,编译时加载
amd:异步加载模块
7、es6新特性
let、const关键字
箭头函数
模板字符串
扩展运算符
解构赋值
数组方法
字符串方法
8、如何判断变量是不是数组?有几种办法?
方法一:Array.isAarray(arr)
方法二:arr instanceof Array
instancof实现原理:prototype 在左边变量的原型链上
方法三:原型:Array.prototype.isPrototypeOf(obj).
方法四:构造函数:arr.constructor.toString().indexOf("Array")>-1
9、slice和splice是干嘛的,splice是否会改变原数组
slice是切片,截取。
arr.slice(a,b):a参数是开始索引,b参数是结束索引。没有b参数就一直到最后。
返回的是截取出来的数组。
splice:数组插值
arr.splcie(a,b,c):a参数是开始索引,b参数是选择个数,,c参数是要替换的内容。
返回的是删除掉的元素。
两者都会改变原数组。
10、数组去重
1、set+扩展运算符(使用于数组对象字符串)
2、循环+indexof(新数组中-1时推到新数组)
3、filter+indexof当前元素等于当前索引
11、new操作符具体做了什么?
1、创建了一个空的对象
2、使空对象的原型指向构造函数的原型。
3、改变this指向,指向该对象实例
4、对构造函数的return做出判断。若return一个基本类型则无影响,return对象会改变为这个对象。
12、闭包
js有全局变量和局部变量,函数内部可以访问函数外部的变量,但是函数外部无法读取函数内部的局部变量。
但是闭包可以做到,闭包是定义在一个函数内部的子函数,有权访问这个函数作用域中的变量。我的理解闭包是函数内部和函数外部连接起来的桥梁。
优点:函数外访问函数内的值,可以封装对象的私有属性和私有方法。避免变量被垃圾回收。
缺点:变量会驻留在内存中,造成内存损耗。(解决:数据设置为null)
原理:基本数据类型在栈内存,用完就销毁,引用数据类型在堆内存,有引用地址。
12、内存损耗的几种情况
闭包
未被清空的定时器
未被销毁的事件监听
DOM引流
13、原型和原型链
所有的函数都有prototype属性(原型),数组和对象没有,prototype上可以设置属性和方法来继承给实例。实例对象都有__proto__属性,对象的_proto_指向构造函数的prototype。逐层深入直到Object对象的原型,这样就形成了原型链。
对象查找属性/方法的顺序:
对象自身——构造函数自身——对象原型——构造函数原型——object
13、call、apply和bind
三个方法都是用来改变this指向,
call、apply可以立即执行,bind不会立即执行,可以赋值给一个对象。
call和bind的第二个参数和后面参数依次写,apply的参数是数组。
14、浅拷贝和深拷贝
都是copy复制的意思
浅拷贝:只复制引用地址,不复制真正的值。要改变一起改变。
场景1:var arr=[1,2,3] var arr2=arr
场景2:arr.slice()和arr.splice()
场景3:引入lodash库,使用clone方法
场景4:Array.from()类数组转为真数组。
深拷贝:复制真正的值。
场景1:obj2=Json.parse(Json.stringify(obj1))
场景2:arr2=[...arr1]和Object.assign(对象来说,一层是深拷贝,多层是浅拷贝)
场景3:lodash库的cloneDeep()方法
15、localStorage、sessionStorage、cookie的区别
都是在客户端存储数据
localStorage:当前浏览器关闭,永久保存,设置的数据(setitem)也会存在。存储不能超过5M
sessionStorage:当前浏览器关闭,设置的数据也会消失。存储不能超过5M
cookie:可以设置过期时间,过期前一直保存。存储不能超过4k
16、cookie、session、token、jwt区别
cookie和session:在用户登录后,服务器会创建一个session对象,存储用户的登录状态和一些用户信息。然后,服务器会给客户端发送一个包含session id的cookie。当客户端再次发送请求时,会自动带上这个cookie,服务器就可以通过session id找到对应的session对象,从而识别用户。
token和jwt:token是一种基于令牌的身份验证方式,它可以在客户端和服务器之间传输,用于验证用户的身份。jwt(Json Web Token)是一种特殊的token,它是一种基于JSON的开放标准(RFC 7519),用于在各方之间安全地传输信息。jwt由三部分组成:头部(header)、载荷(payload)和签名(signature)。头部通常包含类型(JWT)和加密算法;载荷包含数据;签名是对头部和载荷进行加密的结果。前端请求头传Authorization
16、怎么让Chrome支持小于12px的文字?
Chrome的默认字体是16px,
可以通过将span元素设置属性
(display行内块并进行动画缩放。)
17、移动端:如何禁止ios&Android长按时触发系统菜单、长按时下载图片、用户选中文字
禁止移动端长按时触发系统菜单:
全局设置:
禁止移动端长按时下载图片:
全局设置:
禁止移动端用户选中文字:
全局设置:
18、自适应(不同手机型号自适应内容)
引用移动端meta
引入淘宝无限适配的js文件
布局单位使用rem
19、响应式、媒体查询
响应式就是一个URL可以适配移动端和pc端中调整。
语法结构:
关键词:only:只支持媒体查询的浏览器
screen:设备
max-width丨max-height min-width丨min-height
响应式图片:对图片尺寸进行优化。使用source标签(可替换他图片)
20、布局方案
使用响应式布局的情况:
数据不是很多,用户量不是很大的展示类页面
例如:公司官网、专题页面
大网站若采用大量响应式,会造成网页加载缓慢。
pc+移动双端网站使用的布局:
pc是一个URL,会加入一些响应式。
移动端是另一个URL,会使用自适应的布局方式。
21、var、let、const的区别
三者都是用来声明变量。
区别1:var有变量提升,let和const没有。
区别2:var可以声明覆盖同一变量,let和const会报错。
区别3:var和let声明的变量可以改变,const声明的常量不可修改。
区别4:let和const会产生块级作用域,var没有。
21、暂时性死区
let和const会有他们所在的作用域,进入作用域时,声明的变量已经存在了,但是不可获取,只有等到声明变量的那一行时,才可以获取和使用变量。
var声明提升,所有没有暂时性死区,未达到时为undefined。
22、箭头函数和普通函数的区别
1、this指向:
箭头函数this指向=该箭头函数外层第一个普通函数的this,且this不可修改
普通函数或方法:谁调用this指向谁
匿名函数的this:匿名函数具有全局性,指向window
2、箭头函数不能new(不能当做构造函数)
3、箭头函数没有prototype。
4、箭头函数没有arguments。
22、关于arguments的相关问题
函数传参时,js会把所传的参数全部存到一个名为arguments的类数组对象中。
有了这个对象我们以后写函数的时候,就不用给所有的形参指定参数名,直接使用arguments对象来获取实参。
23、回调函数和回调地狱
回调函数:作为实参进入另一个函数,并在此函数中被调用。解决异步问题。
回调地狱:多个回调函数嵌套的话,使代码看起来很混乱,不利于维护。
24、set、map的区别(new map,new set)还有weekset和weekmap呢?
set:是一组不重复数据的集合,可以用于数组去重。
(两个空对象不重复,是两个值,因为内存地址不同。)
方法:可以遍历(set.keys()),size长度,add添加,has判断是否有
map:(类似python的字典)是存放键值对的集合,键和值都可以是任意数据类型
通过map实例.set()的方法给map添加键值对。
可以遍历,方法get、has等。
weekset:对象的集合,成员都是对象。
不能遍历,方法有
add、delete、has
weekmap:键名只能为对象,不能遍历,对象只作为键、不被引用的话自动清除,不计入垃圾回收机制,上同。方法有
get、set、has、delete
25、什么是函数的柯里化?怎么解决?
柯里化:把一个多参数的函数转化成单参数函数的方法,多参数各分一个函数。
核心:函数里面返回函数
作用:参数依次延迟执行。
实例:js中经常使用的bind,实现的机制就是Currying
26、数组和伪数组(类数组)的区别
数组是特殊对象,有各种从原型中继承的数组方法。
类数组是简单对象,有length属性,但不能调用数组方法。(arguments对象、getelementbyid等获得的),对象也算是伪数组。
类数组转换成真数组:
1、Array.from()
2、[...伪数组]
3、Array.prototype.forEach()。属性遍历并组成新的数组
26、各种数组方法:Javascript常用的数组方法_Humor_Mr的博客-CSDN博客_js数组常用方法
增删、find、循环、includes、filter、sort、reverse、slice、splice、join
27、了解es6的Proxy吗?
proxy,代理。产生对象前,对其拦截包装操作
28、js继承
1、原型继承:父类的实例作为子类的原型。
缺点:引用类型改变后会被共享。
2、构造函数继承,var a=new A()
缺点:子类不能访问父类原型上的属性
3、上面两个组合继承。
缺点:调用两份一样的父类的属性方法。影响性能。
4、寄生组合继承:
5、es6的Class类继承:extend+super
29、图片懒加载:js实现图片懒加载原理_tomorrownan的博客-CSDN博客_图片懒加载
图片按需加载,如果页面没到该图片,则不加载
实现办法:
加载完页面,使用data-src存储每个img标签的src值。
获取图片上边界getBoundingClientRect().top和浏览器可视高度clientheight,并比较
通过把data-src的值赋值给img的src属性。
然后img生效。
最简单方法:设置属性loading="lazy"
30、DOM原生操作
创建新节点:createElement:创建一个具体元素。
添加:appendChild()
移除:removeChild()
替换:repalceChild()
插入:insertBefore()
克隆:cloneNode()
设置和获取属性:setAttribute("属性名","属性值"),getAttribute("属性名")
30、BOM是什么?
浏览器对象模型。也就是浏览器操作
history:back()、forward()、go(1、-1)
navigator :
location:属性:href地址、host域名、port端口、pathname路径、search参数
alert、confirm、open
30、事件冒泡和事件捕获
事件冒泡:事件向上传导。子事件的点击事件被触发,祖先元素的点击事件依次会被触发。
事件捕获:与冒泡相反,从父到子。
addeventlistener,第三个参数默认false冒泡
event.stopPropagation()组织冒泡
event.preventDefault()阻止默认事件
@click.stop=
30、js内置对象
Set、Map、Math、RegExp、Number、Array、Boolean、Object。
31、对于Json的了解
Json是一种数据交换格式,采用键值对,键值都是字符串。
32、js的垃圾回收机制(主要是堆内存)
垃圾回收:找到不再使用的变量,释放掉其占用的内存。
标记清除:函数中的变量被标记,当函数执行完,将变量的内存释放,其他的先复制进空闲区域。
引用计数:内存变量被引用就+1,变量用完-1,直到0释放。
var a=1;a=100,1的空间不用了,垃圾回收。
32、避免内存泄露的方式
导致内存泄露有:定时器未清除、闭包、脱离DOM引用
尽可能少地创建全局变量(因为一直在,不会被垃圾回收)
手动清除定时器
少用闭包
清除DOM引用
使用弱引用weakMap和weakSet(垃圾回收时不会将创建的键值考虑进去)
33、严格模式
使用:use strict
概念:消除js语法中的不合理、不严谨、不安全的地方,减少怪异行为,保证代码正常运行
限制:全局下的this指向undefined。
构造函数必须加new。
函数不能有重名的参数。
34、mvc和mvvm的理解?
MVC:模型-视图-控制器
view传送指令到controller
controller完成逻辑后,通知model改变状态
model发送新数据给view,完成视图更新。
MVVM:model-view-viewmodel
model:数据访问、数据存储
view:ui界面
viewmodel:view和model的信息转换
35、异步编程的实现方式
1、回调函数
2、事件监听
3、promise
4、generator
function和函数名之间有星号
内部使用 yield定义不同状态,类似于await
5、asyac、await
35、谈谈对Promise的理解
promise是异步编程的一种解决方案,可以解决回调地狱。
有三种状态:pending(啥也没发生的初始状态、进行中),resolved(完成),reject(失败)
有resolve、reject两个结果,分别传递对应两种参数。
继续用then链式调用,异常用catch,还有finally。
promise.all():等待机制,所有成功再执行,promise是数组,返回结果也是数组。
传参数组为空,立即执行resolve
promise.race():赛跑机制,有一个操作完成就可以执行。
传参数组为空,不会执行。
36、什么是async和await?
async将函数标记为异步函数,返回的是promise对象
实现异步函数同步执行
await承接一个promise实例,直接得到promise.then成功的结果,await遇到具体值,就是promise.resolve(这个值)
第一个await之前的代码会同步执行。await之后的代码会异步执行(后执行)。
37、onclick和addEventListener的区别
onclick可以写在标签中,addEventListener只能写在js代码中。
onclick只能绑定点击事件,addEventListener可以绑定各种事件。
onclick绑定多个事件会覆盖,addEventListener不会。
addEventListener第三个参数false是冒泡事件,true是捕获事件。
38、event事件对象
事件对象:当事件对应的函数触发时,浏览器都会将事件的相关信息传递给响应函数
事件对象包括的信息:鼠标坐标(e.clientX、e.clientY)、键盘键位、滚轮方向……
e.target:返回触发事件的对象
e.preventDefault:阻止默认行为
e.stopPropagation:阻止冒泡
clientWidth:元素可视区域宽度,宽度+边距+边框。offsetwidth:加上滚动条
clientHeight:元素可视区域高度。
scrollTop:垂直滚动距离
clienttop:元素上边框宽度。
clientleft:元素左边框的宽度。
39、js实现页面跳转
window.location.href=" "
window.open()
history.go(-1)
window.navigate()
40、Object.assign(a,b)?
合并:实现对象的合并
覆盖:如果已有属性重名,b覆盖a。
复制:复制的是属性值,即引用地址,(浅拷贝)。
41、for of和for in
for of适合遍历数组,for in适合遍历对象。
for of遍历对象会报错。
for in遍历的是数组的索引,对象的属性,以及原型链上的属性。
42、js小知识点
- !!双重取反,不为false布尔值时为true。
- ??是合并运算符,当左边不为null和undefined时,返回左边,否则返回右边
- 判断对象是否有某个属性,x in obj返回布尔值,hasownproperty()
- 高阶函数:将函数作为输入或返回值的函数。
- event.target是发生事件的元素或触发事件的元素。
- eval()函数可以接受一个字符串str作为参数,并把此str当做一段javascript代码去执行
- void运算会忽略掉求值的结果,直接返回 undefined、
- Object.entries() 方法返回一个给定对象自身可枚举属性的键值对数组。
- 数组方法arr.at(index),返回index的元素。
- 数组方法arr.includes(元素),判断数组是否有某个元素。
- 数组扁平化:flat(2或infinity):递归深度遍历数组,并合并成新数组(多层变一层)。(会移除空的项)
- 判断字符串是否以某个字符串开头或者结尾:startwith、endwit
- Array.of(1,2,3)=[1,2,3],将传入值变成数组
- decorator,装饰器,扩展类型的属性和方法
43、js手写前端面试手撕题整理(自用)_笔经面经_牛客网
手写一个promise的sleep
手写并封装一个ajax请求
手写instanceof
44、大文件上传
45、clientWidth、clientHeight、scrollTop、
clientWidth:元素可视区域宽度,宽度+边距+边框。offsetwidth:加上滚动条
clientHeight:元素可视区域高度。
scrollTop:垂直滚动距离
clienttop:元素上边框宽度。
clientleft:元素左边框的宽度。
46、单点登录
47、webworker
浏览器是一个线程,而且只有一个主线程。如果有一些复杂计算,主线程执行会很慢。
webworker独立于主线程。允许可以在浏览器后台线程中运行js代码,不影响页面的响应。
可以进行图形处理、复杂数据计算。
但是无法访问dom和bom,不能访问本地存储。
需要使用postMessage和onmessage结合使用
使用:
service worker
一种脚本运行在独立于主JavaScript线程的背景下,提供了一种方式来拦截和处理网络请求,实现离线缓存、消息推送等功能。Service Workers使得开发者能够以更精细的方式控制缓存,是构建Progressive Web Apps(PWA)的关键技术之一
pwa是什么
将网页作为应用程序安装在智能设备上的技术。
48、three.js
再浏览器创建3D图形。
三要素:场景、相机、渲染器
场景:要显示在3d的对象。new three.scene()创建场景实例,并设置属性(颜色等)
相机:视角和范围
渲染器:结合场景和相机
添加物体添加光源:Three.pointLight,在scene.add
Vue
1、vue生命周期有哪些?
1、系统自带的八个有:
beforecreate、created、beforemount、mounted、beforeupdate、updated、beforedestroy、destroyed。
2、进入页面,执行的生命周期有:
beforecreate、created、beforemount、mounted。
3、created产生数据(vue有@data),mounted开始挂载DOM(有@el),组件初始化完毕,数据可以使用。
4、当有keep-alive时,多两个生命周期:deactivated、activated
当有keep-alive时,第一次进入组件执行的生命周期:
beforecreate、created、beforemount、mounted、activated
当有keep-alive时,不是第一次进入组件执行的生命周期:
只执行activated
deactivated 在keep-alive组件激活之后当隐藏缓存组件时触发
keep-alive组件的使用
keep-alive 可以使被包含的组件保留状态,缓存组件,避免被销毁。
原理:写了要给render函数存储需要缓存的组件数据,再路由函数beforeRouteEnter获取数据。
vue组件的data为什么必须是一个函数?
vue对象中,data写成一个函数实际就是形成一个闭包。
数据return出来,相当于每个组件实例都有自己的私有属性。
如果不写成对象,一个data的某个值改变,其他组件的data也会受影响。
2、谈谈你对keep-alive的了解
keep-alive是系统自带的一个组件,切换组件时,把切换出去的组件保留在内存中。
防止重复渲染DOM,提升性能。
(组件被包裹在keep-alive标签中。)
3、v-if和v-show的区别
v-if 为false时,此DOM节点直接消失。
v-show为false是,DOM依然存在,样式改为display:none。
v-if更高的消耗。v-show适合频繁切换。
v-if和v-for的优先级
在vue源码里,v-for比v-if先进行判断,所以v-for的优先级更高。
写在一个标签里会报错,
解决:外层包裹一层div或者template加上v-if。
4、nextTick干嘛用的?
在data()中的数据修改后,页面中无法获取data修改后的数据。
使用$nextTick时,当data中的数据修改后,可以获得实时的渲染页面。
(nextTick是页面渲染后执行的函数)
(后面用箭头函数,this指向vue)
使用场景:created想要获取dom、更新列表后的高度。
5、props和data的优先级谁高?
props>data
6、computed、watch有什么区别
watch:监听属性,监听一个已经存在的属性,值改变时,会调用对应的方法。无缓存
computed:计算属性,根据已有的属性改变时,计算出一个新的属性。有缓存。
7、事件修饰符和按键修饰符有哪些
事件修饰符
@click.prevent=“事件名” ,阻止默认行为
@click.stop=“事件名” ,阻止冒泡
once:只触发一次
按键修饰符
@keyup.enter="事件名",enter键触发事件
@keyup.13="事件名",空格键触发事件
表单修饰符
v-model.trim=
v-model.number=
v-loader是什么,它的用途?
webpack的loader
vue文件的一个加载器,将template、js、style转换成js模块。
用途:js可以写es6、style样式
key的作用
作为每一个dom元素的唯一标识,来区别不同dom,同时通过diff算法更新dom时更加高效。
如果以index为key值,逆序删除时可能会导致渲染bug。可以用唯一性id作为key比如手机号。
diff算法和虚拟dom
虚拟dom:框架会根据dom结构创建虚拟dom节点树,状态改变时,diff算法会将两个虚拟dom进行对比,根据对比结果计算出变化然后应用到真实dom中。
diff 算法根据 key 复用 dom 节点,通过移动节点而不是创建新节点来减少 dom 操作。(双指针),比较两个虚拟dom树
对于每个新的 vnode,在旧的 vnode 中根据 key 查找一下,如果没查找到,那就新增 dom 节点,如果查找到了,那就可以复用。
复用的话要不要移动要判断下下标,如果下标在 lastIndex 之后,就不需要移动,因为本来就在后面,反之就需要移动。
最后,把旧的 vnode 中在新 vnode 中没有的节点从 dom 树中删除,形成新的虚拟dom。
vue的双向数据绑定如何实现的?试题-Vue实现数据双向绑定的原理是什么? - 校招VIP
(对于表单元素,v-model绑定数据+input触发相应函数,使数据更新。)
实现一个监听器Observer,用来劫持并监听所有属性,如果属性发生变化,就通知订阅者;
实现一个订阅者Watcher,用来收到属性的变化通知并执行相应的方法,从而更新视图;
实现一个解析器Compile,用来解析每个节点的指令,对模板数据和订阅器进行初始化;
响应式原理
vue的响应式是通过Object.defineProperty()方法(Vue2)或者Proxy方法(Vue3)实现的,通过Object.defineProperty()或Proxy劫持各个数据属性的setter和getter。当数据变动时会发布消息给订阅器,触发相应的监听事件渲染视图。
Object.defineproperty(obj,prop,属性描述符)
直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
proxy,代理。产生对象前,对其拦截包装操作
为什么Object.defineProperty()不可以监听数组,Proxy可以
1、
Object.defineProperty()
方法允许你定义或修改一个对象的属性,并且可以对这些属性进行枚举和配置。然而,这个方法只能作用于对象的具体属性,而不能作用于整个对象,尤其是不能递归地作用于对象的子属性,比如数组的元素。2、
Proxy
可以让你拦截并定义特定操作的自定义行为,可以在数组上工作,递归地代理对对象或数组的操作。
spa(单页面应用)和mpa(多页面应用)的区别及缺点
spa指只有一个主页面的应用,浏览器一开始就加载所有的js、html、css,所有的页面内容都在这个主页面中,写的时候还是分开写。单页面的页面跳转只刷新局部资源。
mpa:一个应用的资源分布在不同页面,页面跳转就整页刷新。
spa优缺点:
优点:不用重新加载用户体验好。不用整个刷新服务器压力小。
缺点:前进后退导航不可用。第一次加载资源过多
解决spa首屏加载慢
例如vue项目首屏加载
1、路由动态写成箭头函数,动态加载,
2、静态资源本地缓存。以后请求直接拿缓存。
3、按需引入ui组件库
4、压缩图片资源
vue中事件绑定加括号和不加括号的区别
@click=“fun”
不带括号、不写实参的fun默认传event (事件对象)@click=“fun(value)”
只要加括号,无论是否传值,都属于传实参给函数,event (事件对象)就接收不到。@click=“fun($event, value)”
如果需要实参、又需要event
改变深层数组
vue.set(对象名,属性,属性值)、vue.set(数组名、索引、值)
也可以使用数组方法push等
v-model实现原理
v-model双向绑定实际上做了两步动作:
1、绑定数据value
2、触发输入事件input;也就是说,v-model等同于:<template>
为什么style要加个scoped
style 标签中添加 scoped 属性后,vue 就会为当前组件中的 DOM 元素添加唯一的一个自定义属性 v-data-xxx。防止样式冲突。
mixin混入
局部混入,
在export default外部命名变量对象(里面写vue语法),再在vue里引入
全局混入,(可以写插件)
vue过滤器
vue.filter用于文本格式化、数据转换,vue3移除。
父子组件传数据
8、refs(子传父)
父:
9、 props(父传子)
父:
子:
10、 emit(子给父)
子:
父:
兄弟组件传数据
12、全局事件总线
beforeCreate() {Vue.prototype.$bus = this //安装全局事件总线},
$bus.$emit给
$bus.$on拿
$bus.$off
13、v-slot插槽
父组件写dom插入给子组件。
默认插槽:父里写div,子里写slot来接受
具名插槽:div里写属性slot=a,子里写name=a
作用域插槽:携带数据用于dom中,父组件接受数据:v-slot:slot名="data"或者#slot名="data"
14、vue脚手架的src目录的文件夹和文件的作用?
assets放静态资源,components放组件,router放路由相关配置,app.vue是应用主组件
main.js是入口文件。
祖孙组件传值:projec和inject
provide函数,return数据。结构类似data
indect:['parent']
vue3:provide('parent',data)
let a=indect('parent')
vue和ssr服务端渲染
ssr服务端生成解析html内容发送到客户端、提高首屏渲染速度,提高seo。
以egg为例,主要依赖vue-server-renderer为例,在控制器配置插件属性。
vuex(状态管理)
1、vuex有哪些属性?
state(data)、mutations(methods)、getters(computed)、actions
state:this.$store.state
mutations:方法参数为state,this.$store.commit("方法名",参数)
getters:方法参数为state,this.$store.getters.计算属性名
actions:方法参数为context,this.$store.dispatch()
vue-router
1、两种mode模式是什么?区别、原理
hash:url会显示#,回车刷新会加载到对应页面
原理:(a标签触发锚点使hash值变化,浏览器hashchange事件监听值的变化,来改变页面内容,url中有#)
history:无#,回车刷新会404
原理:history.pushState和replaceState方法传参,添加历史记录而不会触发页面重新加载,url中无#
2、怎么定义vue-router的动态路由?怎么获取传过来的值
在router目录下的index.js文件中,对path属性加上/:id。 使用router对象的params.id
3、vue-router的路由守卫有哪些?
全局:
前置守卫:beforeEach((to,form,next)=>{})
后置守卫:afterEach
路由内:beforeEnter
组件内:
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
作用:对于路由跳转进行拦截并操作。
4、如何配置404页面
5、路由跳转有哪些方式?
声明式:router-link router-view
编程式:router.push
6、$router 和$route有什么区别?
$router:router的总实例,;路由器对象,有很多属性和子对象。
$route:当前的路由信息,只有name、path、mode、query(当前路由信息参数)等属性。
Vue3
vue3相比vue2发生了哪些变化?
1、响应式
vue2的响应式是基于Object.defineProperty来监听数据对象的变化,但监听不到对象属性的增删、数组元素和长度的变化。(通过set设置)
vue3采用了proxy代理来代替,可以做到监听对象属性的增删和数组元素和长度的修改,还实现了惰性的监听。
2、组合式api,vue2是options
vue3用的是composition组合式api,函数式编程,代码集中化,方便去梳理,组合式api就是一个setup函数,组件的变量、方法、watch、computed、生命周期函数都在setup中
3、vue3函数式编程。computed和watch变成了函数形式
4、vue3体积更小,computed等属性,用到了才会打包。
vue3带来了好处?
1、性能提升,包括打包速度、内存占用、渲染速度
2、使用proxy代替defineproperty实现响应式
3、支持typescript
4、组合式api——都用import引入,对渲染友好。方法和data写在一起容易维护。api可以单独封装复用。
如何实现mvvm
vue是采用数据劫持结合发布者-订阅者模式的方式实现mvvm的。
vue2通过object.defineProperty()来劫持各个属性的。
- setter、getter在数据变动时发布消息给订阅者,触发相应的监听回调,对视图进行更新。
- 实现一个监听器Observer,用来劫持并监听所有属性,如果有变动,就通知给订阅者。
- 实现一个订阅者watcher,可以收到属性的变化通知并执行相应的更新函数,从而更新视图
- 实现一个解析器compile,可以扫描和解析每个结点的相关指令,并初始化模板数据以及初始化相应的订阅器
组合式api有哪些?有什么作用?
setup
ref(定义响应式基本数据类型,value取值)
reactive(定义复杂数据类型)
toRef(对象中的某个属性单独提供给外部使用时)
toRefs(可以批量创建多个 ref 对象)
computed:
watch:监听特定的响应式引用或计算属性,接受两个参数,分别是监听数据和执行的回调
watchEffect:直接接受一个回调函数,跟踪和监听任何变化
vue3生命周期函数有哪些
beforecreate、created、beforemount、mounted、beforeupdate、update、beforeunmount、unmounted
vue3新组件
1、fragment
vue2组件必须有一个根标签,
vue3组件可以没有根标签,内部会将多个标签包含在一个fragment虚拟元素中。
好处:减少标签层级,减小内存占用。
2、teleport
teleport是一种能够将我们的组件html结构移动到指定位置的技术。
<teleport to="移动位置">3、suspense
处理异步组件,等待异步组件或者异步数据时。会出现一个加载指示。
综合题
什么是cdn
cdn是内容网络分发,根据用户位置请求最近的cdn节点来请求对应网站的内容。
解决了跨地域访问资源的问题,降低延迟。提高访问速度
axios是什么?怎样使用它?
axios是什么?怎样使用它?
axios 的是一种基于promise的ajax异步请求库,安装npm install axios --save 即可使用,请求中包括get,post,put, patch ,delete等五种请求方式。
ajax+promise
ajax(异步请求)
核心是js的XmlHttpRequest(new->open->send->onreadystatechange)
xhr请求步骤:
1、创建对象 let xhr=new XMLHttpRequest
2、设置请求 xhr.open(‘方法’,‘路径’)
3、发送请求 xhr.send(参数)
4、监听成功后的响应数据。 xhr.onreadystatechange=function(){if(xhr.readystae==4&&xhr.status==200)}
(判断readystate是否等于4,代表数据是否响应完成,)
获取:responseText
fetch请求
fetch完全和ajax和axios没关系,他是xhr的升级版分,更加简洁易用。原生js+promise
fetch(url,参数对象).then(res=>res.json())
参数对象:
{
method:post、
headers:{}请求头
data:传参
}
css预处理器——less、sass的异同
less和sass都是css预处理器,他们可以进行变量赋值、混入、嵌套、运算、函数等。
区别:
less定义赋值是用@,sass用的是$
性能优化的手段有哪些?
1、减少请求数量
图片处理——雪碧图(精灵图,定长宽+定位图片内容位置来“裁剪”)、字体图标、base64代替图片。
不使用@import (会造成额外的请求)
避免使用空的src和href,如a和img
静态资源使用cdn引入
图片懒加载
2、优化资源加载
SSR服务器端渲染,内容在服务器生成,浏览器直接显示html
尽可能将css文件外链引入head,js文件写在body底部,
使用defer或async异步加载script标签。
3、减少重绘回流
不使用table布局
不要使用 js 代码对dom 元素设置多条样式,选择用一个 className 代替之。
定位使用absolute或者fixed脱离文档流。
transform 代替 top,left ,margin-top, margin-left... 这些位移属性。
防抖与节流
4、webpack打包优化
压缩js代码
压缩css代码
压缩图片、文件
防抖与节流
防抖:输入框实时搜索,定时器时间内不触发第二次。
解决:settimeout+判断
节流:窗口滚动,通过判断间隔时间来决定是否触发事件
正则表达式
常用限定符:
^:匹配字符串的起始位置
$:匹配字符串结束位置
?:匹配0或1次字符
*:匹配0或多个字符
+:重复1次或多次
{2,6}:匹配2到6次之间
(ab):匹配ab在一起的
a|b:匹配a或者b
[a-z]:匹配所有单个小写字母
[a-z]+:匹配所有小写字母字符串
括号的^:取反
元字符:
.:任意字符
\w:任意字母、数字、下划线、汉字。(\W取反,下同)
\s:任意空白符
\d:数字
HTTP
osi七层模型
应用层
应用层:HTTP
表现层:snmp
会话层:DNS
之间:SSL、TLS
传输层
传输层:tcp、udp
网络层
网络层:ip、icmp
数据链路层
数据链路层
物理层
http和https有什么区别?
https有ca证书(第三方机构的安全认证证书),http一般没有,
http默认端口是80,https默认端口是443
http是超文本传输协议,无状态协议,信息是明文传输,https则是另外具有SSL协议提供安全基础
ssl协议:对称加密(加解密都是一个密钥)、非对称加密(一个公钥一个私钥。)
通常是两者结合的混合加密
http1.0和http2.0有什么区别?
- 主流是http1.1
- 连接
1.0一个tcp一个请求,每次请求/响应结束后都会关闭连接,都要经历握手和挥手
1.1长连接,一个tcp多个请求(但是要排队一个个进行,容易队头阻塞),
2.0多用复路和二进制分帧,不会互相影响:减少tcp连接次数,解决了tcp传输数据慢问题。
- 多路复用的方式消除队头阻塞的问题():客户端可以发送多个请求。
客户端的不同的请求分成多个帧,同一请求的帧的id相同。
响应根据相同id的帧合并为一条完整数据,同时按照优先级(例如script>图片)
浏览器根据id将数据给请求位置。
- 更多优化
1.1:添加新的请求方法,put、delete。引入更多缓存头控制缓存
2.0:服务器可主动推资源给客户端。另外,请求html文件时,一并响应回css和JavaScript
2.0:头部压缩,第一次发送所有头部字段,后续请求之发送差异数据。
GET和POST的区别?
get请求时,表示要获取内容,不会修改服务器的数据。对数据类型和数据类型有限制,参数携带在url上,会被缓存,服务器响应200。
post请求时,表示要提交内容,会修改服务器的数据。数据长度和类型没有限制,参数写成对象,不会被缓存,更安全(因为参数不会被显示在url且不会保存在浏览器历史)。(浏览器先发送header,服务器响应100continue,再发送data,服务器响应200ok。)
URL从输入到渲染的全过程从输入URL到页面渲染的整个过程 - 个人笔记_公孙元二的博客-CSDN博客_url从输入到页面渲染全流程
输入了一个域名。
浏览器解析url,提取url的信息(协议、域名、端口、路径)
DNS查询(先检查缓存有没有,没有则向操作系统查询,仍然没有就查询dns服务器)找到这个域名对应的服务器地址(ip),
通过TCP请求建立链接服务(三次握手),
发送请求通过WEB服务器(apache)返回数据,
浏览器渲染,根据返回数据构建DOM树、css树,构建render tree进行布局和渲染,遇到js下载并执行脚本。
关闭tcp连接(四次挥手)。
常见的状态码有哪些?
100:响应继续
200:请求成功
301:网页被永久转移到气他URL
302:临时移动
304:未修改。(协商缓存,请求的网页没有变化)
400:客户端请求的语法错误。
401:需要用户的身份认证。
404:请求的网页不存在,找不到资源
500:内部服务器错误
504:网关超时
505:服务器不支持该http版本。
tcp三次握手(建立连接)、四次挥手(断开连接)
三次握手(在吗-在-好的)
客户端发送syn报文,seq=x 给服务器
服务器发送syn和ack报文,seq=y,并确认序列x+1
客户端发送adk报文,seq=z,并确认序列y+1
为什么三次挥手:
为了客户端和服务器建立连接,但是网络有延迟,保证客户端未超时,防止客户端没有接收到数据。但是次数过多还会造成浪费。
四次挥手(我走了-好的+拜拜-拜拜)
客户端发送fin报文,seq=u,并停止再发数据,关闭TCP连接。
服务器发送ack报文,并确认u+1
服务器发送fin报文,seq=w
客户端发送ack报文,seq=w+1
为什么:
确保数据完成发送、完整性,防止网络原因的防止错误关闭。
http头部字段有哪些?
常见请求头:
Accept:可接受的内容类型。
Connection:keep-alive tcp长连接
User-Agent:表示发起访问的是什么浏览器,不写的话就判定爬虫,直接拒绝。
Cookie:用户登录信息。用户登录,服务器将登陆信息存储在客户端
Referer:请求的来源点。
orgin:请求的域名来源
常见响应头:
Cache-Control:缓存机制,例如no-cache 防止从缓存中获取过期资源
Content-type:资源文件的类型
Content-length:响应body的大小
Access-Control-Allow-Origin:* 允许跨域
Access-Control-Allow-Methods:允许访问的方法(get?post?)
status
cookie的httponly。
js写入cookie,docement.cookie=xxx
如果cookie写入httponly,代表只能通过http协议来访问,不能被js脚本修改(上面那行),防止xss攻击,安全。
强缓存和协商缓存
(首次访问都会返回文件,不会考虑缓存)
都是对返回资源进行浏览器缓存
强缓存
响应头返回Cache-Control
max-age=date(s),缓存的内容在该时间后失效。
no-cache :对比文件,不变的话返回304(未修改)
no-store:彻底禁用缓存
public:所有都被缓存(客户端+代理服务器)。
private:只缓存客户端,不缓存在代理服务器。
协商缓存
etag(优先级高)——http1.1
缓存过期时,若响应头有etag,则请求头带上if-none-match去服务器的etag标识对比,若文件相同返回304
last-modified ——http1.0
缓存过期(max-age)时,若响应头有last-modified,则请求头带上if-modified-since与last-modified对比,对比的是修改时间。
tcp和udp的区别
tcp:面向连接(有三次握手四次挥手)、效率低、字节流、全双工(两个方向)可靠、文件传输、局域网(电话)
udp:面向无连接、效率高、报文、不可靠易丢包、视频语音、广域网(短信)
restful风格
接口命名规范,资源/版本/执行的操作。config/v1/getPwd。
获取用get,新增用post,修改用put,删除用delete。
响应体用json格式返回。
webSocket
双向实时通信,不需要客户端主动请求。
前提:
轮询:客户端定期发送请求的服务器
长轮询:客户端发送请求,保持连接打开,等待数据返回后停止。
优点:连接只需要建立初始的那一次。同时可以降低延迟请求更快。
过程:
首先发送一个常规的get请求,请求头加上upgrage:websoket
前端:
心跳机制:客户端和服务器直接通过心跳包(定期发送空数据)维持连接,防止长时间没有数据传输而断开。
限制:本身没有加密,需要加设安全措施。兼容性差,不支持老浏览器。较多消耗后端资源
解决跨域
跨域产生原因:同源策略拦截跨域
跨域:请求地址和当前地址的协议、域名、端口不同
浏览器允许发起跨域请求,也会返回数据,但是,返回的数据会被浏览器拦截,无法被页面获取到。
JSONP(前端解决跨域)
原理:通过script标签的src属性,请求跨域的接口,并通过?callback=回调函数接收接口响应的数据。<script> 标签可以跨域加载外部脚本文件。
需要后端将数据传参给该回调i函数。
缺点:只支持get请求,不支持post请求
(通过jQuery和ajax,只需要请求中加dataType:"jsonp")
CORS(后端解决跨域)
CORS 是一个 W3C 标准,全称是"跨域资源共享",
解决跨域问题,就是在服务器端给响应添加头信息
Access-Control-Allow-Origin:* #则允许所有域名的脚本访问该资源。 Access-Control-Allow-Origin:https://www.fujieace.com #允许特定的域名访问。
postMessage
h5的API,通过postmessage方法,iframe用addEventListener监听事件
代理服务器
Git
常见的git(版本管理)工作流程
初始化:git init
新增文件的命令:git add
将需要进行版本管理的文件放入暂存区域:git commit
将暂存区域的文件提交到git仓库:git push
git管理的文件有三种状态:已修改(modified),已暂存(staged),已提交(committed)
团队内部协作开发的流程
首先在github上创建一个项目,然后为小组成员添加权限,给小组长搭好框架,把本地项目上传到远程项目 ,新建一个开发分支,所有成员都切换到开发分支中,在开发分支中进行开发,最后小组长将开发分支合并到master分支上,并解决一些冲突。
git冲突怎么解决
微信小程序
微信小程序原理
利用WXML、WXSS、js三种技术开发,本质是单页面开发,所有页面渲染和事件处理都是在一个页面内进行,但又可以调用各种微信提供的原生接口。
微信小程序的双向绑定和vue有什么不一样
小程序直接用this.data的属性是不可以同步到视图上的,必须调用setData接口明确指定同步哪些值到视图层才会触发。
vue是通过对数据对象使用v-model或者进行监听,只要属性值更改就会立即触发视图的更新。
wxss和wxml和正常的有哪些不同?
wxss的尺寸单位是rpx,rpx是响应式像素,可以根据屏幕宽度自适应。
wxss不支持:first-child、:active,没有body、html等dom,不支持keyframe动画。
WXML的a、p、span等标签都成龙view、text。img成了image
微信小程序页面之间传递数据
1、在js文件中定义全局变量globalData,放入存储的信息。使用getApp()拿到数据。
或者2、使用
wx.navigateTo
与wx.redirectTo
的时候,可以将部分数据放在url
里面,并在新页面onLoad
的时候初始化。
微信小程序的生命周期
onLoad()、onShow()、onReady()、onHide()、onUnload()
如何实现下拉刷新
- 首先在全局
config
中的window
配置enablePullDownRefresh
- 在
Page
中定义onPullDownRefresh
钩子函数,到达下拉刷新条件后,该钩子函数执行,发起请求方法- 请求返回后,调用
wx.stopPullDownRefresh
停止下拉刷新
bindtap和catchtap的区别是什么?
相同点:两者都是点击事件
区别:catchtap会阻止事件冒泡。
Uniapp
条件编译uni-app的条件编译_与宇宙对视的博客-CSDN博客_uniapp 条件编译
#indef APP-PLUS 写代码 #endef :仅APP平台编译的代码
#inndef H5 写代码 #endef :除了H5,其他平台都可编译出
#indef APP-PLUS||H5 写代码 #endef :
获取地理位置的api
uni.getLocation
uniapp如何监听页面滚动
onPageScroll事件
如何让图片宽度不变,高度自动变化,保持原图宽高比不变?
给image标签添加mode="widthFix"
uniapp和原生开发相比的优缺点
- 用的是vue语法,小程序组件、标签和生命周期(小程序单页面),两者结合便于开发。
- 有uniapp自己的api和各种插件可以直接饮用,更加便捷
- 支持less、sass,原生不支持
webpack
webpack的作用和工作原理
webpack是打包工具,把一切都视为模块:不管是 css、JS、Image 还是 html 都可以互相引用,通过定义 entry.js,对所有依赖的文件进行跟踪,将各个模块通过 loader 和 plugins 处理,然后打包在一起。
mode:development,production(生产环境会压缩代码)
webpack打包过程
1、初始化:解析weboack.config.js配置文件,读取合并参数
2、加载模块:加载所有配置的插件
3、编译构建:从入口(entry)开始,调用loader对模块进行编译,并根据递归找到依赖模块继续编译。得到编译模块和依赖关系。
4、输出:根据依赖关系,对编译后的module组合成chunk
5、写入文件:根据output配置把chunk文件内容写入文件系统。
loader?有哪些loader?
webpack默认只能打包js文件,配置里的module的rules数组配置了一组规则,要有loader处理,告诉 Webpack 在遇到哪些文件时使用哪些 Loader 去加载和转换打包成js。loader去处理转换各种文件。
babel-loader,转换es6到标准js
css-loader读取 合并CSS 文件,
style-loader把 CSS 内容注入到 JavaScript 里,
less-loader 解析less文件url-loader和file-loader一样,处理png图片或其他文件
plugin?有哪些plugin?
配置再plugins里,plugin是插件扩展器,解决loader无法实现的事,可以打包优化、资源管理,需要require引入。
HtmlWbpackPlugin自动在打包结束后生成html文件,并引入bundle.js
cleanwebPackPlugin打包自动删除上次打包文件MiniCssExtractPlugin:抽离压缩css文件。
loader运行在打包文件之前,plugins再整个编译周期都起作用。
什么是bundle、什么是chunk、什么是module?
bundle:是由webpack打包出来的js文件
chunk:是指webpack在进行模块依赖分析的时候,生成的中间文件,代表模块集合
module:是开发中的单个模块
devserver:webpack之devServer配置_hdchangchang的博客-CSDN博客_devserver
用于开发过程中实时查看和调试应用。
多种配置
自动刷新
proxy代理请求,避免跨域。
热更新。
热更新
不用每次都打包编译。自动实时更新效果。
devserver:{hot:true}
优化webpack打包速度/性能优化
优化打包速度:
loader:
在一些较大的loader前面加上cache-loader,进行缓存
tree-shaking,消除死代码,exports里,通过配置optimization.usedExports为true来启用Tree Shaking,只包含使用的代码,减小bundle体积。
插件:
减少不必要的插件的引入。
使用
TerserPlugin
插件来压缩JavaScript代码,减小bundle体积。使用MiniCssExtractPlugin插件压缩css代码,减小bundle体积。
引入dllPlugin插件,将一些文件(第三方库)进行打包成单独的文件,避免重新打包。
合理使用sourcemap(会减慢速度)
webpack来性能优化
包括以上打包速度优化,
使用HtmlWebpackPlugin 插件来生成HTML 的模板时候,通过配置属性minify优化html
webpack图片压缩
压缩jpeg,options里配置mozejpeg:{progressive:true,quality:80}
压缩img,配置optipng:{enabled:true}
压缩img,webp:{quality:80}
source map
为了保证报错的行数和源代码的行数保持一致
在mode同级别写 devtool:‘eval-source-map’
生产环境下要省略devtool选项,防止原始代码通过source map的形式暴露给用户。
最佳实践: 开发环境(development):设置devtool:‘eval-source-map’’
生产环境(production) :设置devtool:‘nosources-source-map’
webpack和vite的区别和比较,还有rollup
两者都是现代化打包工具
打包方式:
- webpack:分析各模块之间依赖→编译打包→服务器渲染出打包结果。问题:模块增多,bundle体积大,hot热更新速度慢。
- vite:启动服务器=》按需动态编译模块显示(请求某个模块时再对该模块进行实时编译)。
- rollup:更轻量级,专注于库的打包,更快,优化体积,内置tree-shaking去除未使用代码
vite优点:
- vite打包快,因为启动时不需要打包,不懂编译
- 默认支持热更新,热更新也更快,因为按需编译。
但是vite生态没有webpack完善
Typescript
ts和js的区别,为什么要使用ts,好处是什么?
js难以维护,没有泛型、接口、枚举等工具,不利于大型项目。所有有效的JavaScript 代码都是有效的 TypeScript 代码,将 .js 文件重命名为 .ts 不会改变任何内容。
原因:因为js写的代码很多如果不运行,就会有很多语法错误。ts类型控制,让编译的时候就能发现并避免错误。而且有类型定义、接口规范,使代码结构更清晰,和保持一致性。
ts重要语法
ts有三种原始数据类型,string、number、Boolean
定义变量:拥有多个类型:let y:number | string,任意类型 let z:any
定义数组:let arr :number[]=[1,23,3,4] let arr:any[]=[1,2,"dada"](约束数组的参数)
定义函数:可以结合接口进行数据类型限制,
any和unknown:都是任意类型,但any彻底放弃类型检查,unknown的变量实例只能赋值给any和unknown的变量。
void和never:void表示函数返回值为空(null和undefined),never代表不会有返回值
元组(tuple,类似列表):let tup1:[string,number?,number];tup1=["a",3]
枚举(enum,各种情况的语义化),互相映射,可以做常量集合:
类(对象携带属性和方法):数据结合带上数据类型写。继承extend。public,protected(类和子类可以访问)、private修饰符属性
泛型: 一个代理的泛称,代码更加灵活,
接口: 用于对对象的形状进行描述(一种事先约束)。
(可选属性加?。任意属性[propName:string]:any表示属性名和属性值都是任意类型)
自定义类型:type 类型名=类型内容。
ts数组和元组有什么区别
数组可以有多个类型,但元组虽然有不同类型,但类型和顺序是固定的。
数组可以变化、增删改。但元组长度固定,数量不可变,
数组定义 let arr:number[]=[1,2],元组定义:let temp:[number,string]=[1,'2']
对类型断言的理解
两种写法:尖括号语法和as语法
它可以让我们在编译时指定变量的类型,以便在运行时避免出现类型错误
ts的interface和type的区别
对类型的定义。
interface主要定义对象的结构和规范,支持接口合并、接口继承和extend扩展,可以被类实现。
type只是给类型起别名。可以描述多种类型,包括对象、联合类型、交叉类型等。
ts关键字,控制成员可见性的方法
关键字
public:都能访问
protected:受保护。自己和子类可访问
private:私有,只有自己能访问
ts抽象类
abstract
关键字进行声明。抽象类可以包含抽象方法、普通方法和属性
- 不能直接实例化,只能被继承。
- 可以包含抽象方法、普通方法和属性。
- 抽象方法必须在派生类中实现。
前端网络安全
CSRF攻击:跨站请求伪造
过程:用户登录CSRF漏洞网站(恶意网站)时,攻击者盗用身份信息(cookie等),以此名义发送进行恶意操作(危险服务器携带cookie模拟用户请求接口)
防范:
1、验证HTTP Referer字段,可知请求来源,来拒绝未知的跨域请求
2、添加token(客户端令牌)验证:第一次登录后,服务器生成一个token给客户端,客户号以后带上token请求数据。(如果客户端带的token和服务器的不一致,则拒绝请求)
3、验证码,类似2
XSS攻击:跨站脚本攻击
过程:用户通过表单提交一段js脚本给服务器,服务器处理后会影响网页,形成漏洞
危害:网页布局和运行受影响、cookie被盗取、location恶意跳转
防范:
1、浏览器有XSS筛选器
2、对输入的script、img、a标签进行过滤
3、对<>符号进行转换编码。
4、cookie写入httponly
点击劫持攻击
过程:用户点击一些“虚伪”链接或按钮,但其实链接上方有一个通过z-index设置的“透明”的小组件,例如可以是“点赞”按钮或链接,以达到网站非法目的。
防范:
1、服务器添加X-Frame-Option响应头
2、判断top.location和self.location是否一致,不一致不允许操作(也可以用作防止其他网站嵌套自己的iframe)
sql注入
输入里插入sql代码,操作数据库。
设计模式
设计模式:对软件设计开发过程中反复出现的某类问题的通用解决方案,框架底层设计。
工厂模式
简单工厂模式:
写多个小产品类(方法),在大工厂类中通过实例在判断逻辑中选择具体产品类。
优点:因此客户端只需要知道具体参数即可。
缺点:增加了系统的复杂度和理解难度,一旦增加新产品就不得不修改逻辑。
单例模式
单例模式:
定义且只使用一个实例。
指的是创建的总是同一个实例,使用类创建的实例始终是相同的。唯一性
需要使用return,每次return的是同一个对象
外观模式
外观模式:
解决兼容性问题
适配器模式
适配器模式:
调节使用(转换器),对格式或者接口进行转换。
发布订阅模式(观察者模式)(村长通知村民)
观察者模式:例如订阅主播,会有内容更新的推送。当观察对象状态改变时,通过调用观察者的某个方法将这些变化通知到观察者。
观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。
策略模式:会员折扣机制。map存储。通过map匹配执行任务
代理模式:proxy,代理操作。+
Node.js
express和koa2的区别
前者通过回调函数的方式处理异步,后者是通过async/await的方式处理处理异步
前者的中间件是线性模型(一个接一个),后者是洋葱模型()
前者自带router和static,后者需要安装
express的使用
node的fs模块
文件的读写,常用方法:读取,写入,拷贝,创建目录
读取:fs.readFileSync,默认读成buffer,异步读取fs.readFile
写入:fs.writeFileSync,异步写入同理如下
追加写入:appendFileSync
拷贝:copyFileSync
创建目录:mkdirSync
什么是路由?express中如何管理路由
路由是web服务器中,对用户的请求进行分发,交给对应的业务处理函数进行业务受理的一种操作模式。express的路由为了将代码逻辑更加清晰。
express中包含了入口模块中的主路由express(),以及模块化拆分后的子路由对象express.Router(),创建的子路由对象使用固定语法user()函数完成子路由的注册和使用。
使用:放一起的用router.get/router.post正常写,在路由里面引入并用app.use()传参引入
什么是中间件,express中有哪些不同的中间件
中间件是工作在客户端和服务器之间的中间组件,主要用于拦截请求和响应,对请求和响应进行功能扩展的中间组件。
express主要包含三种中间件,分别是内置中间件、第三方中间件以及自定义中间件。