2021 Web 前端热点笔试面试题总结【更新版】

2023-11-12

提醒:我只是答案的搬运工,如果在浏览中发现有错误,欢迎评论中提出来,我好修改,谢谢!

简述异步和同步的区别:

同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作

异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容

简述JavaScript基本数据类型,也称为原始类型

  • number 用于任何类型的数字:整数或浮点数,在 ±(253-1) 范围内的整数。
  • bigint 用于任意长度的整数。
  • string 用于字符串:一个字符串可以包含 0 个或多个字符,所以没有单独的单字符类型。
  • boolean 用于 true 和 false
  • null 用于未知的值 —— 只有一个 null 值的独立类型。
  • undefined 用于未定义的值 —— 只有一个 undefined 值的独立类型。
  • symbol 用于唯一的标识符。

简述div元素和span元素的区别

DIV(division)是一个块级元素,可以包含段落、标题、表格,乃至诸如章节、摘要和备注等。

SPAN 是行内元素,SPAN 的前后是不会换行的,它没有结构的意义,纯粹是应用样式,当其他行内元素都不合适时,可以使用SPAN。块元素相当于内嵌元素在前后各加一个换行。其实,块元素和行内元素也不是一成不变的,只要给块元素定义display:inline,块元素就成了内嵌元素,同样地,给内嵌元素定义了display:block就成了块元素了。 

什么是css预处理器|后处理器

CSS预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。通俗的说,CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件。CSS 后处理器是对 CSS 进行处理,并最终生成 CSS 的预处理器,它属于广义上的 CSS 预处理器。

Css优先级算法如何计算

通配符选择器:0  元素选择符:1  关系选择器:1  伪元素选择器:1  类选择符:10  属性选择器:10 伪类选择器:10  id选择器:100  内联样式:1000  !important声明的样式优先级最高

This指向问题

this 的值是在程序运行时得到的。

  • 一个函数在声明时,可能就使用了 this,但是这个 this 只有在函数被调用时才会有值。
  • 可以在对象之间复制函数。
  • 以“方法”的语法调用函数时:object.method(),调用过程中的 this 值是 object

请注意箭头函数有些特别:它们没有 this。在箭头函数内部访问到的 this 都是从外部获取的。

Display有哪些值及作用

  1. block :块对象的默认值。用该值为对象之后添加新行
  2. none :隐藏对象。与visibility属性的hidden值不同,其不为被隐藏的对象保留其物理空间
  3. inline :内联对象的默认值。用该值将从对象中删除行
  4. compact :分配对象为块对象或基于内容之上的内联对象
  5. marker :指定内容在容器对象之前或之后。要使用此参数,对象必须和:after及:before 伪元素一起使用
  6. inline-table :将表格显示为无前后换行的内联对象或内联容器
  7. list-item :将块对象指定为列表项目。并可以添加可选项目标志
  8. run-in :分配对象为块对象或基于内容之上的内联对象
  9. table :将对象作为块元素级的表格显示

position的值

  1. static(默认):该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 toprightbottomleft 和 z-index 属性无效。
  2. relative(相对定位):该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效。
  3. absolute(绝对定位):元素会被移出正常文档流,并不为元素预留空间,通过指定元素相对于最近的非 static 定位祖先元素的偏移,来确定元素位置。绝对定位的元素可以设置外边距(margins),且不会与其他边距合并。
  4. fixed(固定定位):元素会被移出正常文档流,并不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed 属性会创建新的层叠上下文。当元素祖先的 transformperspective 或 filter 属性非 none 时,容器由视口改为该祖先。
  5. sticky(粘性定位):

    元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor)和 containing block (最近块级祖先 nearest block-level ancestor),包括table-related元素,基于toprightbottom, 和 left的值进行偏移。偏移值不会影响任何其他元素的位置。

    该值总是创建一个新的层叠上下文(stacking context)。注意,一个sticky元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的overflow 是 hiddenscrollauto, 或 overlay时),即便这个祖先不是最近的真实可滚动祖先。

介绍JavaScript有哪些内置对象

1.ObjectJavaScript中所有对象的父对象

2.标准的内置对象例如 ArrayBooleanDateErrorFunctionJSONMathNumberObjectRegExpStringMapSetWeakMap , WeakSet 以及其他对象

JavaScript作用域链

JS引擎中,通过标识符查找标识符的值,会从当前作用域向上查找,直到作用域找到第一个匹配的标识符位置。就是JS的作用域链。

模块化的好处及实现方式

解决命名冲突;提供复用性;提高代码可维护性

立即执行函数;AMDCMDCommonjsES Module

什么是window对象,什么是document对象

window它是一个顶层对象,而不是另一个对象的属性即浏览器的窗口。

document对象是window对象的一个对象属性

Document.writeinnerHTML的区别

document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。

innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。你可以精确到某一个具体的元素来进行更改。如果想修改document的内容,则需要修改document.documentElement.innerElement。

innerHTML将内容写入某个DOM节点,不会导致页面全部重绘;innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。

Map,filter,reduce各自有什么作用

  1. map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
  2. filter() 方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。
  3. reduce() 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。

写出一个图片懒加载的实现步骤

先将img标签的src链接设为同一张图片(比如空白图片),然后给img标签设置自定义属性(比如 data-src),然后将真正的图片地址存储在data-src中,当JS监听到该图片元素进入可视窗口时,将自定义属性中的地址存储到src属性中。达到懒加载的效果。

Doctype作用,标准模式和兼容模式的区别

DOCTYPEdocument type (文档类型) 的缩写。<!DOCTYPE >声明位于文档的最前面,处于标签之前,它不是html标签。主要作用是告诉浏览器的解析器使用哪种HTML规范或者XHTML规范来解析页面。

标准模式和兼容模式都是浏览器的呈现模式,浏览器究竟使用兼容模式还是标准模式呈现页面与网页中的DTD(文件类型定义)有关,DTD里面包含了文档的规则。

标准模式是指浏览器按照W3C标准来解析代码,呈现页面;兼容模式,是指浏览器按照自己的方式来解析代码,使用一种比较宽松的向后兼容的方式来显示页面。

介绍下您对浏览器内核的理解

使用Trident内核的浏览器:IE、Maxthon、TT、The World等;使用Gecko内核的浏览器:Netcape6及以上版本、FireFox、MozillaSuite/SeaMonkey;使用Presto内核的浏览器:Opera7及以上版本;使用Webkit内核的浏览器:Safari、Chrome

简述一下对HTML语义化的理解

用正确的标签做正确的事情;html语义化就是让页面的内容结构化,便于对浏览器、搜索引擎解析;在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的;搜索引擎的爬虫依赖于标记来确定上下文和各个关键字的权重,利于SEO;使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。

Iframe有哪些缺点

iframe会阻塞主页面的Onload事件;搜索引擎的检索程序无法解读这种页面,不利于SEO;iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载;使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript动态给iframe添加src属性值,这样可以绕开以上两个问题。

块级元素有哪些;行内元素有哪些;空(void)元素有哪些

块级元素:div ul ol li dl dt dd h1 h2 h3 h4

行内元素:a b span img input select strong

空元素:br hr img input link meta

Display:nonevisibility:hidden的区别

display:none 不显示对应的元素,在文档布局中不再分配空间(回流+重绘)

visibility:hidden 隐藏对应元素,在文档布局中仍保留原来的空间(重绘)

简单的介绍下弹性盒子模型的属性和属性值

flex-direction

row:横向从左到右排列(左对齐),默认的排列方式。

row-reverse:反转横向排列(右对齐,从后往前排,最后一项排在最前面。

column:纵向排列。

column-reverse:反转纵向排列,从后往前排,最后一项排在最上面。

flex-wrap

nowrap(默认):不换行。

wrap:换行,第一行在上方。

wrap-reverse:换行,第一行在下方。

flex-flow

flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap

justify-content

flex-start:从左到右排列

flex-end:从右到左排列

center:中间开始排列

space-between:平分

space-around:平分,且两边占1/2

align-items

flex-start:交叉轴的起点对齐。

flex-end:交叉轴的终点对齐。

center:交叉轴的中点对齐。

baseline: 项目的第一行文字的基线对齐。

stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

align-content

flex-start:与交叉轴的起点对齐。

flex-end:与交叉轴的终点对齐。

center:与交叉轴的中点对齐。

space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。

space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。

stretch(默认值):轴线占满整个交叉轴。

px、em、rem、%、vw、vh、vm这些单位的区别

Px 就是pixel的缩写,意为像素。px就是一张图片最小的一个点,一张位图就是千千万万的这样的点构成的,比如常常听到的电脑像素是1024x768的,表示的是水平方向是1024个像素点,垂直方向是768个像素点。

Em 参考物是父元素的font-size,具有继承的特点。如果自身定义了font-size按自身来计算(浏览器默认字体是16px),整个页面内1em不是一个固定的值。

Rem  css3新单位,相对于根元素html(网页)的font-size,不会像em那样,依赖于父元素的字体大小,而造成混乱。

% 一般广泛的讲是相对于父元素,但是并不是十分准确。

1、对于普通定位元素就是我们理解的父元素

2、对于position: absolute;的元素是相对于已定位的父元素

3、对于position: fixed;的元素是相对于 ViewPort(可视窗口)

Vw css3新单位,viewpoint width的缩写,视窗宽度,1vw等于视窗宽度的1%。

举个例子:浏览器宽度1200px, 1 vw = 1200px/100 = 12 px。

Vh css3新单位,viewpoint height的缩写,视窗高度,1vh等于视窗高度的1%。

举个例子:浏览器高度900px, 1 vh = 900px/100 = 9 px。

Vm css3新单位,相对于视口的宽度或高度中较小的那个。其中最小的那个被均分为100单位的vm

举个例子:浏览器高度900px,宽度1200px,取最小的浏览器高度, 1 vm = 900px/100 = 9 px。

说明cookie,session的概念与区别,另外说出你知道的浏览器缓存方式

cookie是客户端记录保存用户身份信息;session是服务器记录用户信息的

cookie是保存在客户端的,而session是保存在服务器的;

cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session

session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE

单个cookie在客户端的限制是4K,就是说一个站点在客户端存放的COOKIE不能超过4K。

将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中。

  1. http缓存是基于HTTP协议的浏览器文件级缓存机制。即针对文件的重复请求情况下,浏览器可以根据协议头判断从服务器端请求文件还是从本地读取文件,chrome控制台下的Frames即展示的是浏览器的http文件级缓存。
  2. IndexedDB 是一个为了能够在客户端存储可观数量的结构化数据,并且在这些数据上使用索引进行高性能检索的 API
  3. Cookie(或者Cookies),指一般网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。
  4. localStorage是html5的一种新的本地缓存方案,目前用的比较多,一般用来存储ajax返回的数据,加快下次页面打开时的渲染速度。
  5. sessionStoragelocalstorage类似,但是浏览器关闭则会全部删除,apilocalstorage相同,实际项目中使用较少。
  6. application cahce是将大部分图片资源、jscss等静态资源放在manifest文件配置中。当页面打开时通过manifest文件来读取本地文件或是请求服务器文件。
  7. Flash缓存主要基于flash有读写浏览器端本地目录的功能,同时也可以向js提供调用的api,则页面可以通过js调用flash去读写特定的磁盘目录,达到本地数据缓存的目的

Ajax实现机制,简述ajax跨域问题并提出解决方案

创建XMLHttpRequest对象。设置请求方式。调用回调函数。发送请求。

主流的前后端分离模式下,当前端调用后台接口时,由于是在非同一个域下的请求,从而会引发浏览器的自我安全保护机制,最终结果是接口成功请求并响应,但前端不能正常处理该返回数据。因此,当同时满足以下三个条件的情况下,就会出现跨域问题:浏览器限制;非同源请求(跨域);发送的是 XHR ( XMLHttpRequest ) 请求

通过jsonp跨域;document.domain + iframe跨域;location.hash + iframe跨域;window.name + iframe跨域;postMessage跨域;跨域资源共享(CORS);nginx代理跨域;nodejs中间件代理跨域;WebSocket协议跨域

静态链接与动态链接的区别,为什么需要动态链接

静态链接和动态链接两者最大的区别就在于链接的时机不一样,静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时

动态链接出现的原因就是为了解决静态链接中提到的两个问题,一方面是空间浪费,另外一方面是更新困难。

从浏览器地址栏输入url到网页彻底打开,中间发送了什么

  1. DNS解析:客户端输入域名后,由DNS服务器来将域名解析成对应服务器的IP地址;

浏览器DNS缓存;系统DNS缓存;路由器DNS缓存;网络运营商DNS缓存。

  1. TCP连接:获得服务器IP之后,就需要三次握手的协议才能建立连接;

第一次握手:由浏览器发起请求,告诉服务器我要发起请求了;

第二次握手:由服务器发起,告诉浏览器我准备接收了,发送吧;

第三次握手:有浏览器发起,告诉服务器马上发,准备接收。

  1. 发送请求:与服务器建立连接之后,就可以向服务器发送请求了,请求需要遵循http协议;
  2. 接受响应:被请求的服务器解析用户请求的有哪些资源,通过服务器返回数据给客户端;
  3. 给客户端返回请求的状态码,通过状态码可以知道服务器端的处理是否正常;
  4. 渲染页面:返回成功之后,浏览器拿到请求页面的代码,将其解析渲染出来;

遇见HTML标记,浏览器调用HTML解析器解析成Token并构建成DOM树

遇见style/link标记,浏览器调用CSS解析器,处理css标记并构建CSSOM树

遇见Script标记,调用JavaScript解析器,处理script代码(绑定事件,修改DOM树CSSOM树)

将DOM树和CSSOM树合并成一个渲染树

根据渲染树来计算布局,计算每个节点的几何信息(布局)

将各个节点颜色绘制到屏幕上(渲染)

  1. 断开连接:数据传输完毕,需要断开tcp连接,此时tcp发起4次挥手;

第一次挥手:由浏览器发起,发送给服务器,资源发送完毕(请求报文),你准备关闭吧

第二次挥手:由服务器发起,告诉浏览器资源接受完毕(请求报文),我准备关闭,你也准备吧

第三次挥手:由服务器发起,告诉浏览器我资源发送完毕(响应报文),你准备关闭吧

第四次挥手:由浏览器发起,告诉服务器资源接受完毕,我准备关闭(响应报文),你也准备吧

JavaScript的prototype原型的作用是什么

prototype允许我们在创建对象之后来改变对象或类的行为,并且这些通过prototype属性添加的字段或方法所有对象实例是共享的。

列出几个为浏览器兼容而做的处理

1.不同浏览器的标签默认的外补丁( margin )和内补丁(padding)不同?解决方案: css 里增加通配符 * { margin: 0; padding: 0; }

2.IE6双边距问题;在 IE6中设置了float , 同时又设置margin , 就会出现边距问题?解决方案:设置display:inline;

3.当标签的高度设置小于10px,在IE6、IE7中会超出自己设置的高度?解决方案:超出高度的标签设置overflow:hidden,或者设置line-height的值小于你的设置高度

4.图片默认有间距?解决方案:使用float 为img 布局

5.边距重叠问题;当相邻两个元素都设置了margin 边距时,margin 将取最大值,舍弃最小值;?解决方案:为了不让边重叠,可以给子元素增加一个父级元素,并设置父级元素为overflow:hidden

6.cursor:hand 显示手型在safari 上不支持?解决方案:统一使用 cursor:pointer

7.两个块级元素,父元素设置了overflow:auto;子元素设置了position:relative ;且高度大于父元素,在IE6、IE7会被隐藏而不是溢出?解决方案:父级元素设置position:relative

简述事件传播的各个阶段

1.捕获阶段:事件传播由目标节点的祖先节点逐级传播到目标节点。先由文档的根节点document(window)开始触发对象,最后传播到目标节点,从外向内捕获事件对象;

2.目标阶段:事件到达目标对象,事件触发,如果事件不允许冒泡,事件会在这一阶段停止传播。

3.冒泡阶段:从目标节点逐级传播到document节点。

position 属性值的含义

Static:元素框正常生成。块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。

Relative:元素框偏移某个距离。元素仍保持其未定位前的形状,它原本所占的空间仍保留。

Absolute:元素框从文档流完全删除,并相对于其包含块定位。包含块可能是文档中的另一个元素或者是初始包含块。元素原先在正常文档流中所占的空间会关闭,就好像元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。

Fixed:元素框的表现类似于将 position 设置为 absolute,不过其包含块是视窗本身。

http请求中的8种请求方法

1、GET方法:发送一个请求来取得服务器上的某一资源

2、POST方法:向URL指定的资源提交数据或附加新的数据

3、PUT方法:跟POST方法很像,也是想服务器提交数据。但是,它们之间有不同。PUT指定了资源在服务器上的位置,而POST没有

4、HEAD方法:只请求页面的首部

5、DELETE方法:删除服务器上的某资源

6、OPTIONS方法:它用于获取当前URL所支持的方法。如果请求成功,会有一个Allow的头包含类似“GET,POST”这样的信息

7、TRACE方法:TRACE方法被用于激发一个远程的,应用层的请求消息回路

8、CONNECT方法:把请求连接转换到透明的TCP/IP通道

GET和POST提交的区别

GET产生一个TCP数据包;POST产生两个TCP数据包(Firefox只发送一次)。GET在浏览器回退时是无害的,而POST会再次提交请求。GET产生的URL地址可以被Bookmark,而POST不可以。GET请求会被浏览器主动cache,而POST不会,除非手动设置。GET请求只能进行url编码,而POST支持多种编码方式。GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。GET请求在URL中传送的参数是有长度限制的,而POST没有。对参数的数据类型,GET只接受ASCII字符,而POST没有限制。GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。GET参数通过URL传递,POST放在Request body中。

为什么JavaScript里面0.1+0.2 === 0.3是false

JavaScript 中的 number 类型就是浮点型,JavaScript 中的浮点数采用IEEE-754 格式的规定,这是一种二进制表示法,可以精确地表示分数,比如 1/2,1/8,1/1024,每个浮点数占 64 位。但是,二进制浮点数表示法并不能精确的表示类似 0.1 这样的简单的数字,会有舍入误差。由于采用二进制,JavaScript 也不能有限表示 1/10、1/2 等这样的分数。在二进制中,1/10(0.1)被表示为 0.00110011001100110011…… 注意 0011 是无限重复的,这是舍入误差造成的,所以对于 0.1 + 0.2 这样的运算,操作数会先被转成二进制,然后再计算。

let,const,var有什么区别

let 和 const 定义的变量不会出现变量提升,而 var 定义的变量会提升;let 和 const 是JS中的块级作用域;let 和 const 不允许重复声明(会抛出错误);let 和 const 定义的变量在定义语句之前,如果使用会抛出错误(形成了暂时性死区),而 var 不会;const 声明一个只读的常量,一旦声明,常量的值就不能改变(如果声明是一个对象,那么不能改变的是对象的引用地址)。

Webpack如何实现打包

WebPack是一个模块打包工具,你可以使用WebPack管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包Web开发中所用到的HTML、Javascript、CSS以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack有对应的模块加载器。webpack模块打包器会分析模块间的依赖关系,最后生成了优化且合并后的静态资源。

Promise详解

Promise有三种状态:pengding(),resolved(已完成),rejected(已失败);Promise从Pending状态开始,如果成功就转到成功态,并执行resolve回调函数;如果失败就转到失败状态并执行reject回调函数。

优点:一旦状态改变,就不会再变,任何时候都可以得到这个结果;可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

缺点:无法取消 Promise;当处于pending状态时,无法得知目前进展到哪一个阶段。

JavaScript基本规范

  1. 不要在同一行声明多个变量;
  2. 请使用 ===/!==来比较true/false或者数值;
  3. 使用对象字面量替代new Array这种形 式;
  4. 不要使用全局函数;Switch语句必须带有default分支;
  5. 函数不应该有时候有返回值,有时候没有返回值;
  6. For循环必须使用大括号;
  7. If语句必须使用大括号;
  8. for-in循环中的变量应该使用var关键字明确限定作用域,从而 避免作用域污染;
  9. 命名规则中构造器函数首字母大写,如function Person(){};
  10. 写注释。

Async/await的用法及优缺点

async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。

async 和 await 相比直接使用 Promise 来说,优势在于处理 then 的调用链,能够更清晰准确的写出代码。缺点在于滥用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性。

深浅拷贝的区别

浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

JQuery中$.get()提交和$.post()提交区别

相同点:都是异步请求的方式来获取服务端的数据

不同点:请求方式不同:$.get() 方法使用GET方法来进行异步请求的。$.post() 方法使用POST方法来进行异步请求的;参数传递方式不同:get请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给Web服务器的,这种传递是对用户不可见的;数据传输大小不同:get方式传输的数据大小不能超过2KB 而POST要大的多;安全问题: GET 方式请求的数据会被浏览器缓存起来,因此有安全问题。

XMLHttpRequest:XMLHttpRequest.readyState;状态码的意思

状态0(请求未初始化):(XMLHttpRequest)对象已经创建或已被abort()方法重置,但还没有调用open()方法;

状态1(载入服务器连接已建立):已经调用open() 方法,但是send()方法未调用,尚未发送请求;

状态2(载入完成,请求已接收):send()方法已调用,HTTP请求已发送到web服务器,请求已经发送完成,未接收到响应;

状态3(交互,请求处理中):所有响应头部都已经接收到。响应体开始接收但未完成,即可以接收到部分响应数据;

状态4(请求完成,且相应已就绪):已经接收到了全部数据,并且连接已经关闭。

XSS攻击

就是攻击者想尽一切办法将可以执行的代码注入到网页中。

持久型也就是攻击的代码被服务端写入进数据库中;非持久型相比于前者危害就小的多了,一般通过修改 URL 参数的方式加入攻击代码,诱导用户访问链接从而进行攻击。

转义输入输出的内容,对于引号、尖括号、斜杠进行转义;建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。

CSRF攻击

攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。

对 Cookie 设置 SameSite 属性,表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容;验证 Referer 来判断该请求是否为第三方网站发起的;服务器下发一个随机 Token,每次发起请求时将 Token 携带上,服务器验证 Token 是否有效。

HTTP请求构成

HTTP 请求由三部分构成,分别为:请求行、首部、实体

请求行:基本由请求方法、URL、协议版本组成;首部:分为请求首部和响应首部

设计模式有哪几种

  1. 工厂模式、单列模式的核心就是保证全局只有一个对象可以访问
  2. 适配器模式用来解决两个接口不兼容的情况,不需要改变已有的接口,通过包装一层的方式实现两个接口的正常协作
  3. 装饰模式作用是给对象添加功能
  4. 代理模式是为了控制对对象的访问,不让外部直接访问到对象
  5. 发布-订阅模式通过一对一或者一对多的依赖关系,当对象发生改变时,订阅方都会收到通知
  6. 外观模式提供了一个接口,隐藏了内部的逻辑,更加方便外部调用

标准盒子模型与IE盒子模型的不同

标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin

低版本IE盒子模型:宽度=内容宽度(content+border+padding)+ margin

CSS3有哪些新特性

RGBA和透明度;  background-image background-origin(content-box/padding-box/border-box) background-size background-repeat;  word-wrap(对长的不可分割单词换行)word-wrap:break-word;  文字阴影:text-shadow: 5px 5px 5px #FF0000;(水平阴影,垂直阴影,模糊距离,阴影颜色);  font-face属性:定义自己的字体;  圆角(边框半径):border-radius 属性用于创建圆角;  边框图片:border-image: url(border.png) 30 30 round;  盒阴影:box-shadow: 10px 10px 5px #888888;  媒体查询:定义两套css,当浏览器的尺寸变化时会采用不同的属性

用纯CSS创建一个三角形的原理是什么

首先,需要把元素的宽度、高度设为0。然后设置边框样式。

width: 0;

height: 0;

border-top: 40px solid transparent;

border-left: 40px solid transparent;

border-right: 40px solid transparent;

border-bottom: 40px solid #ff0000;

为什么会出现浮动和什么时候需要清除浮动?清除浮动的方式

浮动元素碰到包含它的边框或者浮动元素的边框停留。由于浮动元素不在文档流中,所以文档流的块框表现得就像浮动框不存在一样。浮动元素会漂浮在文档流的块框上。

浮动带来的问题:父元素的高度无法被撑开,影响与父元素同级的元素;与浮动元素同级的非浮动元素(内联元素)会跟随其后;若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构。

清除浮动的方式:

  • 父级div定义height:给父级DIV定义固定高度(height),能解决父级DIV 无法获取高度得问题。优点:代码简洁缺点:高度被固定死了,是适合内容固定不变的模块。
  • 最后一个浮动元素后加空div标签 并添加样式clear:both:添加一对空的DIV标签,利用css的clear:both属性清除浮动,让父级DIV能够获取高度。优点:浏览器支持好缺点:多出了很多空的DIV标签,如果页面中浮动模块多的话,就会出现很多的空置DIV了,这样感觉视乎不是太令人满意。
  • 包含浮动元素的父标签添加样式overflow为hidden或auto:这个方法的关键在于触发了BFC。在IE6中还需要触发 hasLayout(zoom:1)优点:代码简介,不存在结构和语义化问题缺点:无法显示需要溢出的元素
  • 父级div定义zoom:

.clearfix:after{

     content:'.';

     display:block;

     height:0;

     clear:both;

     visibility:hidden;

}

.clearfix {zoom:1;}

  • 父级div定义 display:table:将div属性强制变成表格优点:不解缺点:会产生新的未知问题。

什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的IE?

响应式网站设计(Responsive Web design)是一个网站能够兼容多个终端,而不是为每一个终端做一个特定的版本。

基本原理是通过媒体查询检测不同的设备屏幕尺寸做处理。

页面头部必须有meta声明的viewport。

<meta name=’viewport’ content=”width=device-width, initial-scale=1. maximum-scale=1,user-scalable=no”>

渐进增强和优雅降级

优雅降级观点认为应该针对那些最高级、最完善的浏览器来设计网站。

渐进增强观点则认为应关注于内容本身,优先考虑低版本。

请阐述块格式化上下文(Block Formatting Context)及其工作原理

块格式上下文(BFC)是 Web 页面的可视化 CSS 渲染的部分,是块级盒布局发生的区域,也是浮动元素与其他元素交互的区域。

一个 HTML 盒(Box)满足以下任意一条,会创建块格式化上下文:float的值不是none、  position的值不是static或relative、  display的值是table-cell、table-caption、inline-block、flex、或inline-flex、  overflow的值不是visible。

在 BFC 中,每个盒的左外边缘都与其包含的块的左边缘相接。

Vue、React、Angular 介绍

MVC模式【Model(模型)+View(视图)+controller(控制器)】

View通过Controller来和Model联系,Controller是View和Model的协调者,View和Model不直接联系,基本联系都是单向的。用户User通过控制器Controller来操作模板Model从而达到视图View的变化

MVP模式【是从MVC模式演变而来的,都是通过Controller/Presenter负责逻辑的处理+Model提供数据+View负责显示】

在MVP中,Presenter完全把View和Model进行了分离,主要的程序逻辑在Presenter里实现。

并且,Presenter和View是没有直接关联的,是通过定义好的接口进行交互,从而使得在变更View的时候可以保持Presenter不变。

MVVM模式【Model+View+ViewModel】

MVVM是把MVC里的Controller和MVP里的Presenter改成了ViewModel;View的变化会自动更新到ViewModel,ViewModel的变化也会自动同步到View上显示。这种自动同步是因为ViewModel中的属性实现了Observer,当属性变更时都能触发对应的操作。

Vue框架【MVVM】

优点:轻量级框架,语法简单,学习成本低;双向数据绑定;组件化开发;数据和结构的分离;虚拟DOM;运行速度快;灵活渐进式框架

缺点:不支持IE8;生态环境差,不如angular和react;不适合偏大型的项目

应用场景:小型应用

React框架【MVC】

优点:jsx语法创建虚拟DOM,极速的渲染性能;组件化开发,组件独立,方便重复使用;单向数据流;组件生命周期;跨浏览器兼容性好

缺点:不适合单独做一个完整的框架

应用场景:个性化需求、中型应用

Angular框架

优点:模板功能强大丰富,并且是声明式的,自带了丰富的Angular指令;是一个比较完善的前端框架,包含服务,模板,数据双向绑定,模块化,路由,过滤器,依赖注入等所有功能;自定义指令,自定义指令后可以在项目中多次使用。ng模块化比较大胆的引入了Java的一些东西(依赖注入);双向绑定(脏检查机制)

缺点:验证功能错误信息显示比较薄弱,需要写很多模板标签;ng提倡在控制器里面不要有操作DOM的代码,对于一些jQuery 插件的使用,如果想不破坏代码的整洁性,需要写一些directive去封装插件;从1.0.X升级到1.2.X,貌似有比较大的调整,没有完美兼容低版本,升级之后可能会导致一个兼容性的BUG;AngularJS 太笨重了,没有让用户选择一个轻量级的版本,当然1.2.X后,Angular也在做一些更改,比如把route,animate等模块独立出去,让用户自己去选择。

应用场景:在大型超大型web应用开发上。

Vue与React的区别

相同点:组件化开发和Virtual DOM;支持props进行父子组件间数据通信;支持数据驱动视图,不直接操作真实DOM,更新状态数据界面就自动更新;支持服务端渲染;支持native的方案,react的React Native,Vue的Weex。

不同点:Vue支持双向数据流,React单向数据流;组件写法React推荐JSX,就是把HTML和css全都写进JavaScript中,Vue推荐是webpack+vue+loader单文件组件格式,就是HTML、css、JavaScript都写进一个文件;state对象在React应用中不可变,需要使用setState方法更新状态,在Vue中,state对象不是必须得,数据有data属性在vue对象中管理;Virtual DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树,而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,及React中会需要shouldComponentUpdata这个生命周期函数方法来进行控制;React严格上只针对MVC的view层,而Vue则是MVVM模式

Vue与Angular的区别

相同点:都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;都支持双向数据绑定;都不支持低端浏览器;vue和angular绑定都可以用{{}}

不同点:vue相当于angular要变得小巧很多,运行速度比angular快;vue指令用v-xxx,angular用ng-xxx;vue中数据放在data对象里面,angular数据绑定在$scope上面;vue有组件化概念,angular中没有;AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢,Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的

React与Angular的区别

相同点:都是单向数据流

不同点:React中没有指令,Angular提供了丰富的指令

React中,并不是父子关系的组件,如何实现相互的数据通信

使用父组件,通过props将变量传入子组件(如通过refs,父组件获取一个子组件的方法,简单包装后,将包装后的方法通过props传入另一个子组件)

Vue生命周期理解

生命周期是从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程。

各个生命周期的作用

beforeCreate: 组件实例被创建之初,组件的属性生效之前

created: 组件实例已经完全创建,属性也绑定,但真实 dom 还没有生成,$el 还不可用

beforeMount: 在挂载开始之前被调用:相关的 render 函数首次被调用

mounted: el被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子

beforeUpdate: 组件数据更新之前调用,发生在虚拟 DOM 打补丁之前

update: 组件数据更新之后

activated: keep-alive 专属,组件被激活时调用

deadctivated: keep-alive 专属,组件被销毁时调用

beforeDestory: 组件销毁前调用

destroyed: 组件销毁后调用

v-if和v-show的区别

v-if 的话就得说到 Vue 底层的编译了。当属性初始为 false 时,组件就不会被渲染,直到条件为 true,并且切换条件时会触发销毁/挂载组件,所以总的来说在切换时开销更高,更适合不经常切换的场景。并且基于 v-if 的这种惰性渲染机制,可以在必要的时候才去渲染组件,减少整个页面的初始渲染开销。

v-show 只是在 display: none 和 display: block 之间切换。无论初始条件是什么都会被渲染出来,后面只需要切换 CSS,DOM 还是一直保留着的。所以总的来说 v-show 在初始渲染时有更高的开销,但是切换开销很小,更适合于频繁切换的场景。

Vue 的双向绑定数据的原理

vue 实现数据双向绑定主要是:采用数据劫持结合“发布者 - 订阅者”模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter、 getter,在数据变动时发布消息给订阅者,触发相应监听回调。

简述Vue的响应式原理

当一个Vue实例创建时,vue会遍历data选项的属性,用 Object.defineProperty 将它们转为getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。 每个组件实例都有相应的watcher程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用时,会通知watcher重新计算,从而致使它关联的组件得以更新。

生命周期示意图

说说Vue组件间通信方式

通信种类:父组件向子组件通信、子组件向父组件通信、隔代组件间通信、兄弟组件通信

实现通信方式:props、vue自定义事件、消息订阅与发布、vuex、slot

Props方式:通过一般属性实现父向子通信;通过函数属性实现子向父通信;缺点是隔代组件和兄弟组件间通信比较麻烦

Vue自定义事件:vue内置实现,可以代替函数类型的props(绑定监听:<MyComp @eventName=”callback”>;触发事件:this.$emit(“eventName”,data));缺点是只适合子向父通信

消息订阅与发布:需要引入消息订阅与发布的实现库,如pubsub-js(订阅消息:PubSub.subscript(‘msg’,(msg,data)=>{}),发布消息:PubSub.publish(‘msg’,data));优点是此方式可实现任意关系组件间通信

Vuex:vuex是vue官方提供的集中式管理vue多组件共享状态数据的vue插件;优点是对组件间关系没有限制,且相比于pubsub库管理更集中,更方便

Slot:专门用来实现父向子传递数据的标签;注意通信的标签模板是在父组件中解析好后再传递给子组件的

vue父子通信

通过props来传值:静态传值就是直接通过props来传递;动态传值是通过v-bind来绑定一个要传递值的key,然后后面跟要传递的内容,不过这个内容是可以改变的。

通过ref来传值:在父组件引用的子组件中采用ref=’要传递的值的key’

emit是子组件向父组件的传值方式:子组件可以使用 $emit 触发父组件的自定义事件

Slot:父组件向子组件传递模板采用slot,如果父组件没传递模板,slot里面有内容的话,就会显示内容,如果有多个模板要进行传递,这需要在slot中通过命名(name)来区分。

computed 和 watch 区别和运用场景

computed 是计算属性,依赖其他属性计算值,并且 computed 的值有缓存,只有当计算值变化才会返回内容;watch 监听到值的变化就会执行回调,在回调中可以进行一些逻辑操作。

运用场景:

当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;

当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

keep-alive 组件有什么作用

如果你需要在组件切换的时候,保存一些组件的状态防止多次渲染,就可以使用 keep-alive 组件包裹需要保存的组件。

对于 keep-alive 组件来说,它拥有两个独有的生命周期钩子函数,分别为 activated 和 deactivated 。用 keep-alive 包裹的组件在切换时不会进行销毁,而是缓存到内存中并执行 deactivated 钩子函数,命中缓存渲染后会执行 actived 钩子函数。

简述Vuex及五个核心概念

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

State:一般在Vue组件中在计算属性computed中返回一个某个状态;

getter:是 store 的计算属性, getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算;

mutation:包含多个直接更新state的方法(回调函数)的对象;

action:包含多个时间回调函数的对象;

module:Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。

说说您对SPA单页面应用的理解,它的优缺点分别是是什么?

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。

优点:

用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;基于上面一点,SPA 相对对服务器压力小;前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理。

缺点:

初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。

Vue 的父组件和子组件生命周期钩子函数执行顺序

Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:

加载渲染过程

父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted

子组件更新过程

父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated

父组件更新过程

父 beforeUpdate -> 父 updated

销毁过程

父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

$route 和 $router 的区别

$router 为 VueRouter 实例,想要导航到不同 URL,则使用 $router.push 方法。

$route 为当前 router 跳转对象里面可以获取 name 、 path 、 query 、 params 等。

Vue 中 key 的作用

key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。

有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。

Proxy 与 Object.defineProperty 优劣对比

Proxy 的优势如下:

Proxy 可以直接监听对象而非属性;

Proxy 可以直接监听数组的变化;

Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;

Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;

Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

Object.defineProperty 的优势如下:

兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。

虚拟 DOM 的优缺点

优点

保证性能下限: 框架的虚拟 DOM 需要适配任何上层 API 可能产生的操作,它的一些 DOM 操作的实现必须是普适的,所以它的性能并不是最优的;但是比起粗暴的 DOM 操作性能要好很多,因此框架的虚拟 DOM 至少可以保证在你不需要手动优化的情况下,依然可以提供还不错的性能,即保证性能的下限;

无需手动操作 DOM: 我们不再需要手动去操作 DOM,只需要写好 View-Model 的代码逻辑,框架会根据虚拟 DOM 和 数据双向绑定,帮我们以可预期的方式更新视图,极大提高我们的开发效率;

跨平台: 虚拟 DOM 本质上是 JavaScript 对象,而 DOM 与平台强相关,相比之下虚拟 DOM 可以进行更方便地跨平台操作,例如服务器渲染、weex 开发等等。

缺点:

无法进行极致优化: 虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。

Webpack四个核心概念

entry(入口)entry point,入口起点(可以有多个),webpack会从该起点出发,找出哪些文件时入口文件所依赖的,从而构建内部依赖关系图,并处理后输出到称之为bundles的文件中。

output(输出)指定经entry point处理后的bundles文件的输出路径(path)和名字(filename)。

loader(加载器)webpack 自身只能识别js文件,但是开发中会有css,图片等静态文件,webpack虽然自身不能识别,但是可以通过loader来处理;实现css、图片等文件的打包。

plugins(插件):从打包优化和压缩,一直到重新定义环境中的变量。

Redux管理状态的机制

Redux基本理解:Redux是一个独立专门用于做状态管理的JS库,不是React插件库;它可以用在React,Angular,Vue等项目中,但基本与React配合使用;作用是集中式管理React应用中多个组件共享的状态和从后台获取的数据

如何实现数组的随机排序

第一种、利用数组自带的sort方法

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const foo = (arr) => {

    let cloneArr = arr.concat();

    cloneArr.sort((n1, n2) => Math.random() - 0.5)

    return cloneArr;

}

console.log(foo(arr));

第二种、利用递归函数对比

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const foo = (arr) => {

 let result = [];

 let cloneArr = arr.concat();

 (function(){

     if (!cloneArr.length) { return }

     let index = Math.floor(Math.random() * cloneArr.length);

     result = result.concat(cloneArr.splice(index, 1));

     arguments.callee();

  })()

  return result;

}

console.log(foo(arr));

第三种、洗牌算法

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

const foo = (arr) => {

    let cloneArr = arr.concat();

    let len = cloneArr.length;

    for (let i = 0; i < len; i++) {

        let index = Math.floor(Math.random() * cloneArr.length);

        let temp = cloneArr[index];

        cloneArr[index] = cloneArr[i];

        cloneArr[i] = temp;

    }

    return cloneArr;

}

console.log(foo(arr));

垂直上下居中的方法

第一种:知道元素的宽和高

div.box{

    weight:200px;

    height:400px;

    position:absolute;

    left:50%;

    top:50%;

    margin-left:-100px;

    margin-top:-200px;

 }

第二种:不知道元素的宽和高

div.box{

    weight:200px;

    height:400px;

    position:absolute;

    left:50%;

    top:50%;

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

}

第三种:flex布局

父级元素:{

   display:flex;

   flex-direction:row;

   justify-content:center;

   align-items:center;

}

子级元素:{

    flex:1

}

简述JavaScript实现继承的几种方式

组合继承核心是在子类的构造函数中通过 Parent.call(this) 继承父类的属性,然后改变子类的原型为 new Parent() 来继承父类的函数

function Parent(value) {

    this.val = value;

}

Parent.prototype.getValue = function () {

    console.log(this.val);

}


function Child(value) {

    Parent.call(this, value);

}

Child.prototype = new Parent();

const child = new Child(1);

child.getValue(); // 1

child instanceof Parent; // true

寄生组合继承核心就是将父类的原型赋值给了子类,并且将构造函数设置为子类,这样既解决了无用的父类属性问题,还能正确的找到子类的构造函数

function Parent(value) {

    this.val = value;

}

Parent.prototype.getValue = function () {

    console.log(this.val);

}


function Child(value) {

    Parent.call(this, value);

}

Child.prototype = Object.create(Parent.prototype, {

    constructor: {

        value: Child,

        enumerable: false,

        writable: true,

        configurable: true

    }

})

const child = new Child(1);

child.getValue(); // 1

child instanceof Parent; // true

Class 继承核心在于使用 extends 表明继承自哪个父类,并且在子类构造函数中必须调用 super,因为这段代码可以看成 Parent.call(this, value)

class Parent {

    constructor(value) {

        this.val = value;

    }

    getValue() {

        console.log(this.val);

    }

}

class Child extends Parent {

    constructor(value) {

        super(value);

    }

}

let child = new Child(1);

child.getValue(); // 1

child instanceof Parent; // true

数组去重

第一种:Array.filter() + indexOf

const distinct = (a, b) => {

    let arr = a.concat(b);

    return arr.filter((item, index)=> arr.indexOf(item) === index)

}

第二种:双重 for 循环

const distinct = (a, b) => {

    let arr = a.concat(b);

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

        for (let j=i+1; j<len; j++) {

            if (arr[i] == arr[j]) {

                arr.splice(j, 1);

                // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一

                len--;

                j--;

            }

        }

    }

    return arr

}

第三种:for...of + includes()

const distinct = (a, b) => {

    let arr = a.concat(b)

    let result = []

    for (let i of arr) {

        !result.includes(i) && result.push(i)

    }

    return result

}

第四种:Array.sort()

const distinct = (a, b) => {

    let arr = a.concat(b)

    arr = arr.sort()

    let result = [arr[0]]

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

        arr[i] !== arr[i-1] && result.push(arr[i])

    }

    return result

}

第五种:new Set()

const distinct = (a, b) =>  Array.from(new Set([...a, ...b]));

第六种:for...of + Object

const distinct = (a, b) => {

    let arr = a.concat(b)

    let result = []

    let obj = {}

    for (let i of arr) {

        if (!obj[i]) {

            result.push(i)

            obj[i] = 1

        }

    }

    return result

}

找出字符串中出现次数最多的字符,并统计次数

let str = "asddfssssaasswef";

let obj = {};

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

    if (!obj[str.charAt(i)]) {

        obj[str.charAt(i)] = 1;

    } else {

        obj[str.charAt(i)]++;

    }

}

console.log(obj);

let max = 0;

let charmax;

for (let key in obj) {

    if (obj[key] > max) {

        max = obj[key];

        charmax = key;

    }

}

console.log(`出现最多的字符是${charmax},出现了${max}次`);

请用JavaScript写一个方法:要求实现格式化输出,比如输入9999999,输出为9,999,999

function splitNum(n) {

    let b = parseInt(n).toString();

    let len = b.length;

    if (len < 3) { return b }

    let r = len % 3,

    b1 = b.slice(0, r) + "," + b.slice(r, len).match(/\d{3}/g).join(","),

    b2 = b.slice(r, len).match(/\d{3}/g).join(",")

    return r > 0 ? b1 : b2;

}

console.log(splitNum(9999999));

JavaScript中的闭包,及几种写法和用途

闭包是密闭的容器,类似于set、map容器,存储数据的;且是一个对象,存放数据的格式是key:value

形成的条件是函数嵌套,内部函数引用外部函数的局部变量

第一种:给函数添加一些属性

function Circle(r) {  

      this.r = r;  

}  

Circle.PI = 3.14159;  

Circle.prototype.area = function() {  

  return Circle.PI * this.r * this.r;  

}  

let c = new Circle(1.0);

alert(c.area());

第二种:声明一个变量,将一个函数当作值赋给变量

let Circle = function() {  

   let obj = new Object();  

   obj.PI = 3.14159;  

   obj.area = function( r ) {  

       return this.PI * r * r;  

   }  

   return obj;  

}  

let c = new Circle();  

alert( c.area( 1.0 ) );

第三种:new 一个对象,然后给对象添加属性和方法

let Circle = new Object();  

Circle.PI = 3.14159;  

Circle.Area = function( r ) {  

       return this.PI * r * r;  

}

alert( Circle.Area( 1.0 ) );

第四种:let obj = {}就是声明一个空的对象

let Circle={  

   "PI":3.14159,  

 "area":function(r){  

          return this.PI * r * r;  

        }  

};  

alert( Circle.area(1.0) );

用途可以读取函数内部的变量;让变量的值始终保持在内存中

在JavaScript中实现不可变对象

const obj = {

    num: 10,

    obj: {

        content: "mutable object"

    }

}

function deepFreeze(obj) {

    let propNames = Object.getOwnPropertyNames(obj);

    propNames.forEach(function (name) {

        let prop = obj[name];

        if (typeof prop == 'object' && prop !== null) {

            deepFreeze(prop);

        }

    });

    return Object.freeze(obj);

}

deepFreeze(obj);

obj.num = 5;

obj.obj = { content: "changed!" }

console.log(obj);

如何阻止冒泡

const stopBubble = (e) => {

    if ( e && e.stopPropagation ){

        e.stopPropagation();

    }else {

        window.event.cancelBubble = true;

    }

}

数组的排序方式

第一种:arrayObject.sort(sortby)

const sortNum = (a, b) => a - b;

let arr = [524, 684, 5, 69, 15];

let res = arr.sort(sortNum);

console.log(res);

第二种:冒泡排序

const bubbleSort = (arr) => {

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

        for (let j = 0; j < arr.length; j++) {

            if (arr[i] < arr[j]) {

                let temp = arr[j];

                arr[j] = arr[i];

                arr[i] = temp;

            }

        }

    }

    return arr;

}

let arr = [524, 684, 5, 69, 15];

console.log(bubbleSort(arr));

第三种:快速排序

const quickSort = (arr) => {

    if (arr.length <= 1) {

        return arr;

    }

    let pivotIndex = Math.floor(arr.length / 2),

    pivot = arr.splice(pivotIndex, 1)[0],

    lef = [],

    rig = [];

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

        (arr[i] < pivot) ? lef.push(arr[i]) : rig.push(arr[i]);

    }

    return quickSort(lef).concat(pivot, quickSort(rig));

}

let arr = [524, 684, 5, 69, 15];

console.log(quickSort(arr));

第四种:插入排序

const insertSort = (arr, a) => {

    for (let i = 1; i < arr.length; i++) {

        if (arr[i] >= a) {

            for (let j = arr.length; j > i; j--) {

                arr[j] = arr[j - 1];

            }

            arr[i] = a;

            break;

        }

    }

    return arr;

}

let arr = [5, 15, 69, 524, 684];

console.log(insertSort(arr, 92));

写一个function ,清除字符串前后的空格

第一种:重写trim方法

let str=’   abc    ’;

if(!String.prototype.trim){

    String.prototype.trim = function(){

        return this.replace(/^\s+/,"").replace(/\s+$/,"");

}

};

console.log(str.trim());

第二种:写fntrim去掉左右空格

let str=’   abc   ’;

const fntrim = (str) => str.replace(/^\s+/,"").replace(/\s+$/,"");

Console.log(fntrim(str));

多行文本超出隐藏

overflow:hidden; //超出文本隐藏

text-overflow:ellipsis; //溢出省略号显示

display:-webkit-box; //将对象作为弹性伸缩盒子

-webkit-box-orient:vertical; //设置伸缩盒子的子元素排列方式-从上到下垂直排列

-webkit-line-clamp:2; //这个属性不是css的规范属性,需要组合上面两个属性,数组代表显示的行数。

数组快速反转

const reverse = (arr) => {

let num=parseInt(arr.length/2);

    for(let i=0; i<num; i++){

        let temp = arr[i];

    arr[i] = arr[arr.length-i-1];

    arr[arr.length-i-1] = temp;

    }

      return arr;

}

var A=[1,10,5,13,26,50,2];

console.log(reverse(A));

用JavaScript实现随机选取10-100之间的10个数,存入一个数组并排序

let iArray=[];

function getRandom(istart,iend){

let iChoice=iend-istart+1,

res=Math.floor(Math.random()*iChoice+istart);

return res;

}

for(let i=0;i<10;i++){

iArray.push(getRandom(10,100));

}

iArray.sort((a,b)=>a>b);

console.log(iArray);

手动实现promise函数

function Promise(fn) {

    let data = undefined, reason = undefined;

    let succallbacks = [];

    let failcallbacks = [];

    let status = "pending";

    this.then = function (fulfilled, rejected) {

        return new Promise(function(resolve,reject) {    //返回一个新的promise

            function suc(value) {   //成功

                let ret = typeof fulfilled === 'function' && fulfilled(value) || value;

                if( ret && typeof ret ['then'] == 'function'){    //判断 then中的 返回的是否是promise对象,如果是注册then方法

                    ret.then(function(value){

                        resolve(value);

                    });

                } else {

                    resolve(ret);

                }

            }

            function errback(reason) {  //失败

                reason = typeof rejected === 'function'  && rejected(reason) || reason;

                reject(reason);

            }

            if (status === 'pending') {

                succallbacks.push(suc);

                failcallbacks.push(errback);

            } else if(status === 'fulfilled'){

                suc(data);

            } else {

                errback(reason);

            }

        })

    }

    function resolve(value) {

        setTimeout(function () {   //加入延时

            status = "fulfilled";

            data = value;

            succallbacks.forEach((callback) => {

                callback(value);

            })

        }, 0)

    }

    function reject(value) {

        setTimeout(function () {

            status = "rejected";

            reason = value;

            failcallbacks.forEach((callback) => {

                callback(value);

            })

        }, 0)

    }

    fn(resolve, reject);

}

let p = new Promise((resolve, reject) => {

                setTimeout(() => {

                resolve(1);

            }, 1000)

        }) ;

p.then(data =>{

    return  new Promise((resolve,reject) => {    //then 方法返回的是一个promise对象,故执行 promise中的then注册该结果,在resolve

               setTimeout(() => { resolve(2);},1000)})

}).then(data =>{

    console.log(data);

})

Promise 实现了链式调用,也就是说每次调用 then 之后返回的都是一个 Promise,并且是一个全新的 Promise,原因也是因为状态不可变。如果你在 then 中 使用了 return,那么 return 的值会被 Promise.resolve() 包装

浅拷贝Object.assign()

let obj = { a: {a: "kobe", b: 39} };

var initalObj = Object.assign({}, obj);

initalObj.a.a = "wade";

console.log(obj.a.a);

浅拷贝Array.prototype.concat()

let arr = [1, 3, {

    username: 'kobe'

    }];

let arr2=arr.concat();    

arr2[2].username = 'wade';

console.log(arr);

浅拷贝Array.prototype.slice()

let arr = [1, 3, {

    username: ' kobe'

    }];

let arr3 = arr.slice();

arr3[2].username = 'wade'

console.log(arr);

深拷贝JSON.parse(JSON.stringify())

let arr = [1, 3, {

    username: ' kobe'

}];

let arr4 = JSON.parse(JSON.stringify(arr));

arr4[2].username = 'duncan';

console.log(arr, arr4);

深拷贝递归

function deepClone(initalObj, finalObj) {    

  let obj = finalObj || {};    

  for (var i in initalObj) {        

    let prop = initalObj[i];

    if(prop === obj) {            

      continue;

    }        

    if (typeof prop === 'object') {

      obj[i] = (prop.constructor === Array) ? [] : {};            

      arguments.callee(prop, obj[i]);

    } else {

      obj[i] = prop;

    }

  }    

  return obj;

}

深拷贝函数库lodash

let _ = require('lodash');

let obj1 = {

    a: 1,

    b: { f: { g: 1 } },

    c: [1, 2, 3]

};

let obj2 = _.cloneDeep(obj1);

console.log(obj1.b.f === obj2.b.f);

深拷贝jquery的$.extend

let $ = require('jquery');

let obj1 = {

    a: 1,

    b: { f: { g: 1 } },

    c: [1, 2, 3]

};

let obj2 = $.extend(true, {}, obj1);

obj1.b.f === obj2.b.f;

将一个单向链表反转

let reverseList = function(head) {

    if (!head || !head.next) return head

    let pre = null;

    let current = head;

    let next;

    while(current) {

        next = current.next;

        current.next = pre;

        pre = current;

        current = next;

    }

    return pre;

};

函数防抖(debounce)函数节流(throttle)的实现方法

函数防抖:一个需要频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效

函数节流:一个函数执行一次后,只有大于设定的执行周期后才会执行第二次

function debounceOrThrottle ({ fn, wait = 300, immediate = false, executeOncePerWait = false }) {

  if (typeof fn !== 'function') {

    throw new Error('fn is expected to be a function');

  }

  let tId = null;

  let context = null;

  let args = null;

  let lastTriggerTime = null;

  let result = null;

  let lastExecutedTime = null;

  const later = function() {

    const last = Date.now() - (executeOncePerWait ? lastExecutedTime : lastTriggerTime);

    if(last < wait && last > 0) {

      setTimeout(later, wait - last)

    } else {

      if (!immediate) {

        executeOncePerWait && (lastExecutedTime = Date.now());

        result = fn.apply(context, args);

        context = args = null;

      }

      tId = null;

    }

  }

  return function() {

    context = this;

    args = arguments;

    !executeOncePerWait && (lastTriggerTime = Date.now());

    const callNow = immediate && !tId;

    if(!tId) {

      executeOncePerWait && (lastExecutedTime = Date.now());

      tId = setTimeout(later, wait);

    }

    if (callNow) {

      executeOncePerWait && (lastExecutedTime = Date.now());

      result = fn.apply(context, args);

      context = args = null;

    }

    return result;

  }

}

const debounce = ({ fn, wait, immediate }) =>

  debounceOrThrottle({

    fn,

    wait,

    immediate

  })

const throttle = ({ fn, wait, immediate = true }) =>

  debounceOrThrottle({

    fn,

    wait,

    immediate,

    executeOncePerWait: true

  })

Call、apply、bind的实现

Call

function.prototype.call = function(thisArg){

   // this指向调用call的对象

    if (typeof this !== 'function') { // 调用call的若不是函数则报错

        throw new TypeError('Error')

    }

  //若thisArg不是函数,或者不存在,thisArg指向window

  thisArg = thisArg || window

  thisArg.fn = this   // 将调用call函数的函数对象添加到thisArg的属性中

  //去除参数的第一个值后执行这个添加的函数

  const res = thisArg.fn(...arguments.slice(1))

  delete thisArg.fn   // 删除该属性

  return res;

}

Apply

function.prototype.apply = function(thisArg,args){

   // this指向调用call的对象

    if (typeof this !== 'function') { // 调用call的若不是函数则报错

        throw new TypeError('Error')

    }

  //若thisArg不是函数,或者不存在,thisArg指向window

  thisArg = thisArg || window

  thisArg.fn = this   // 将调用call函数的函数对象添加到thisArg的属性中

  //去除参数的第一个值后执行这个添加的函数

  const res = thisArg.fn(...args)

  delete thisArg.fn   // 删除该属性

  return res;

}

Bind

function.prototype.bind = function(oThis){

      if(typeof this !== 'function'){

          throw new TypeError('被绑定的对象需要是函数')

      }

      let self = this

      let args = arguments.slice(1);

      fBound = function(){ //this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用

          return self.apply(this instanceof fBound ? this : oThis, args.concat([].slice.call(arguments)))

      }

      let func = function(){}

      //维护原型关系

      if(this.prototype){

          func.prototype = this.prototype;

      }

      //使fBound.prototype是func的实例,返回的fBound若作为new的构造函数,新对象的__proto__就是func的实例

      fBound.prototype = new func();

      return fBound;

}

实现一个lazyman

class _LazyMan {

  constructor(name) {

    this.tasks = [];

    const task = () => {

      console.log(`Hi! This is ${name}`);

      this.next();

    }

    this.tasks.push(task);

    setTimeout(() => {               // 把 this.next() 放到调用栈清空之后执行

      this.next();

    }, 0);

  }

  next() {

    const task = this.tasks.shift(); // 取第一个任务执行

    task && task();

  }

  sleep(time) {

    this._sleepWrapper(time, false);

    return this;                     // 链式调用

  }

  sleepFirst(time) {

    this._sleepWrapper(time, true);

    return this;

  }

  _sleepWrapper(time, first) {

    const task = () => {

      setTimeout(() => {

        console.log(`Wake up after ${time}`);

        this.next();

      }, time * 1000)

    }

    if (first) {

      this.tasks.unshift(task);     // 放到任务队列顶部

    } else {

      this.tasks.push(task);        // 放到任务队列尾部

    }

  }

  eat(name) {

    const task = () => {

      console.log(`Eat ${name}`);

      this.next();

    }

    this.tasks.push(task);

    return this;

  }

}

function LazyMan(name) {

  return new _LazyMan(name);

}

Class 与 Style 如何动态绑定?

Class 可以通过对象语法和数组语法进行动态绑定:

对象语法:

<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>

data: {

  isActive: true,

  hasError: false

}

数组语法:

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

data: {

  activeClass: 'active',

  errorClass: 'text-danger'

}

Style 也可以通过对象语法和数组语法进行动态绑定:

对象语法:

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

data: {

  activeColor: 'red',

  fontSize: 30

}

数组语法:

<div v-bind:style="[styleColor, styleSize]"></div>

data: {

  styleColor: {

     color: 'red'

   },

  styleSize:{

     fontSize:'23px'

  }

}

vue-router 路由模式有几种

vue-router 有 3 种路由模式:hash、history、abstract,对应的源码如下所示:

switch (mode) {

  case 'history':

this.history = new HTML5History(this, options.base)

break

  case 'hash':

this.history = new HashHistory(this, options.base, this.fallback)

break

  case 'abstract':

this.history = new AbstractHistory(this, options.base)

break

  default:

if (process.env.NODE_ENV !== 'production') {

  assert(false, `invalid mode: ${mode}`)

}

}

其中,3 种路由模式的说明如下:

hash:  使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;

history :  依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式;

abstract :  支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2021 Web 前端热点笔试面试题总结【更新版】 的相关文章

  • react-router 里的 Link 标签和 a 标签有什么区别?

    相同点 从最终渲染的 DOM 来看 这两者都是链接 都是 a 标签 区别 是 react router 里实现路由跳转的链接 一般配合 a
  • 转化为布尔值的规则

    对于基本类型的数据 null和undefined直接转化为false 字符串 空字符串转化为false 其他全为true 数字 0和NaN转化为false 其他全为true 对于引用类型数据 全为true 所以 的结果是true 分析 中
  • 前端面试题收集整合

    面试题 一 在css布局中 什么场景下出现元素高度塌陷 如何解决元素高度塌陷问题 父元素的所有子元素设置浮动后会出现元素高度塌陷问题 1 父元素设置高度 2 父元素设置浮动 3 修改父元素的类型 display inline block t
  • 多益前端笔试题

    1 svg画四边形 四个点的坐标分别是 220 100 300 210 170 250 123 234
  • 模块化及模块化规范

    什么是模块化 将一个项目拆分为若干块 每块之间以一定的形式进行通信 而每块内部的内容都是独立的 前端没有模块化会造成什么问题 耦合性高 不利于代码维护 污染全局的命名空间 造成代码冲突 模块化的优点 减少命名冲突 功能独立 可以按需加载 大
  • 2023年CSS面试题集合

    文章目录 一 H5的新特性有哪些 二 CSS3的新特性有哪些 三 如何实现一个盒子水平垂直居中 方法一 利用定位 常用方法 推荐 方法二 利用 margin auto 方法三 利用 display table cell 方法四 利用 dis
  • 最新前端面试题整理

    前端技术 常见浏览器的内核分别是什么 IE浏览器 Trident 内核 Firefox浏览器 Gecko内核 Safari浏览器 Webkit内核 Opera浏览器 最初是Presto内核 后来是Webkit 现在是Blink内核 Chro
  • Vue 中如何实现监测数组变化

    vue中响应式数据的原理是通过Object defineProperty控制getter和setter 并利用观察者模式完成的响应式设计 数组考虑性能原因没有用defineProperty对数组的每一项进行拦截 而是选择重写数组api方法
  • 2023最新Web前端经典面试试题及答案-史上最全前端面试题(含答案)

    近期总结一一些面试题 都是企业的面试题笔记题 感觉薪资10k 15k的常见面试题 个人录制的最新Vue项目学习视频 B站 Vue2 第二版 后台管理系统项目实战 vue element ui vue经典全套系统案例讲解 哔哩哔哩 bilib
  • js实现数组扁平化的几种方式

    数组扁平化 数组的扁平化就是将一个嵌套多层的数组转换为只有一层的数组 扁平化也是面试中常见的考题 举个简单的例子 假设有个名为 flatDeep 的函数能实现数组扁平化效果 代码运行效果如下面 var array 1 2 3 4 5 con
  • 前端面试题集锦(7)

    目录 1 常见的跨域方式 2 对象的遍历方法 3 数组扁平化 4 typeof 原理 5 介绍类型转化 6 闭包的问题和优化 7 浏览器和Node事件循环的区别 1 常见的跨域方式 JSONP JSONP 是利用外链脚本 没有跨源限制的特点
  • 【面试题】Javascript的这些运算符,你都都掌握哪些?

    前端面试题库 面试必备 推荐 地址 前端面试题库 国庆头像 国庆爱国 程序员头像 总有一款适合你 theme devui blue highlight a11y light 无论是JavaScript还是其他语言 运算符是基础 表达式和语句
  • 2021 Web 前端热点笔试面试题总结【更新版】

    提醒 我只是答案的搬运工 如果在浏览中发现有错误 欢迎评论中提出来 我好修改 谢谢 简述异步和同步的区别 同步 浏览器访问服务器请求 用户看得到页面刷新 重新发请求 等请求完 页面刷新 新内容出现 用户看到新内容 进行下一步操作 异步 浏览
  • token 应该存在 Cookie、SessionStorage 还是 LocalStorage 中?

    在Web开发中 token 令牌 可以存储在多个地方 包括cookie sessionStorage和localStorage 每种存储方式都有其优点和缺点 选择哪种方式取决于你的应用需求 1 Cookie 将token存储在cookie中
  • 蘑菇街前端面试

    vue与jquery的区别 为什么现在很多人使用vue vue怎样实现双向数据绑定 内部原理 1 jQuery首先要获取到dom对象 然后对dom对象进行进行值的修改等操作 2 Vue是首先把值和js对象进行绑定 然后修改js对象的值 Vu
  • 让HTML img垂直居中的三种办法:

    声明 原文来自DIVCSS5 其次原文代码存在一些引起误解的地方 已经进行修改和测试 下文会注明引起误解的地方 主要收藏为方便下次阅读 故进行转发 如有侵权 请私聊本人 定立即删除 原文连接 DIVCSS5 让html img垂直居中的三种
  • No2.7 前端面试题 1. token 2. 浏览器页面渲染的过程 3. SVG格式 4. 精灵图和base64

    1 token 什么是token token是验证身份的令牌 一般是用户通过账号密码登录后 服务端把这些凭证通过加密等一系列操作后得到的字符串 token都存在哪里 有什么区别 存localstorage里 后期每次请求接口时都需要把它当做
  • 【面试题】前端开发中如何高效渲染大数据量?

    前端面试题库 面试必备 推荐 地址 前端面试题库 国庆头像 国庆爱国 程序员头像 总有一款适合你 在日常工作中 较少的能遇到一次性往页面中插入大量数据的场景 数栈的离线开发 以下简称离线 产品中 就有类似的场景 本文将分享一个实际场景中的前
  • ES6数组及编程题

    1 forEach var arr 1 2 3 4 arr forEach item index arr gt console log item 结果为1 2 3 4 数组的遍历方法 无返回值 不改变原数组 2 map var arr 1
  • 前端面试题:一个200*200的div在不同分辨率屏幕上下左右居中,用css实现。

随机推荐

  • 【目标检测-YOLO】YOLOv5-5.0v-损失函数(第四篇)

    YOLO Input Backbone Neck Head 置信度Loss 坐标回归Loss 分类Loss v1 448 448 GoogleNet FC 2 MSE v2 32x D
  • mod_jk 分析

    mod jk 分析 1 mod jk 模块的总体功能 由于 tomcat 的 HTTP 处理部分都由 Java 所写 5 5 12 版本以后出现了 native 库 用以 提高其 I O 和 SSL 的性能 1 在高并发的情况下负载较高 而
  • 误解#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)

    define GPIOA BASE AHB1PERIPH BASE 0x0000 typedef struct IO uint32 t MODER lt GPIO port mode register Address offset 0x00
  • python+opencv最简单的人脸识别入门

    0前置操作 安装python 最新3 10即可 安装pycharm 社区版即可 安装opencv python cmd输入pip install opencv python即可 嫌慢用国内镜像也可以 后续也需要安装opencv contri
  • 利用Scrum敏捷工具管理敏捷产品迭代Sprint Backlog

    什么是Sprint Backlog Sprint Backlog是Scrum的主要工件之一 在Scrum中 团队按照迭代的方式工作 每个迭代称为一个Sprint 在Sprint开始之前 PO会准备好产品Backlog 准备好的产品Backl
  • 数据本地存储方法

    存储到本地的数据类型有 数组 字典 字符串 对象类型的 1 字符串的本地存储 NSString str dsadasd NSArray arr NSSearchPathForDirectoriesInDomains NSLibraryDir
  • opencv-python中的腐蚀与膨胀函数

    1 图像的腐蚀 就像土壤侵蚀一样 这个操作会把前景物体的边界腐蚀掉 但是前景仍然是白色 这是怎么做到的呢 卷积核沿着图像滑动 如果与卷积核对应的原图像的所有像素值都是1 那么中心元素就保持原来的像素值 否则就变为零 这回产生什么影响呢 根据
  • Vision-Centric BEV Perception: A Survey (以视觉为中心的BEV感知综述)论文笔记

    原文链接 https arxiv org abs 2208 02797 1 引言 BEV表达包含了丰富的语义信息 精确定位和绝对尺度 可直接应用于下游任务如行为预测和运动规划 此外 BEV表达为融合不同视角 模态 时间和智能体的信息提供了物
  • nginx配置文件root和alias区别

    总结 alias指定的目录是准确的 root是指定目录的上级目录 并且该上级目录要含有location指定名称的同名目录 root的处理结果是 root路径 location路径 http后面的地址 alias的处理结果是 使用alias路
  • R语言的包bnlearn生成的概率图模型如何进行后续的检验和验证是否合理?有相关示例和论文吗?...

    bnlearn 包生成的概率图模型可以通过多种方法进行后续检验和验证 具体来说 可以考虑以下几种方法 对模型进行统计检验 以评估模型是否符合数据的分布 例如 可以使用Kolmogorov Smirnov检验 Lilliefors检验等 对模
  • condition update在分布式系统中设计

    condition update在分布式系统中设计 1 定义 condition update称为条件更新 用于分布式系统中数据一致性 能够保证在并发操作数据时的正确性 2 方式 1 可以通过version来保证condition upda
  • 解决pgAdmin4启动失败方法

    1 问题现象 有时pgadmin 4启动仅显示启动界面 或者 点击图标一直都没反应 启动界面用鼠标点击下就消失了 然后过很长时间就保错 the application server could not be contect 错误 比如一直出
  • python安装anaconda_安装Anaconda后,python出现import Error

    背景 Win10 VSCode下安装了Python3 6 4和一些package 有的package在site package路径下 在已经安装了Python3 6 4之后 又安装了Anaconda 安装设置都是默认的 Error出现 这时
  • qt控件学习笔记

    QToolBox控件 QToolBox控件 类似于下拉列表控件 头文件 include
  • Jenkins持续集成demo

    1 下载Jenkins的war包 官网地址 https jenkins io 点击下载 将jenkins war 部署到Tomcat中 本文使用的是Tomcat8 5 35 注意Tomcat需要配置账号密码 Tomcat7 是 manage
  • MySQL、Oracle中去重并保留最新的一条数据

    MySQL select from my table where id in select id from select id name group code max create time mt from my table group b
  • IDEA的设置

    terminal wsl2 setting gt tools gt Termianl gt shell path 填写wsl exe的绝对路 绝对路径的查找 wsl2 安装 https docs microsoft com en us wi
  • LA@向量组线性相关性

    文章目录 向量组线性相关性 线性相关 线性无关 多向量向量组线性相关 单向量向量组的线性相关性 单位向量向量组线性相关性 双向量向量组的线性相关性 双向量线性相关的几何意义 三向量线性相关的几何意义 包含零向量的向量组线性相关 概念迁移 线
  • STC89C51——中断系统

    前言 本文介绍基于常见的51单片机 即如下图的芯片 STC89C51具备5个中断源 中断源 优先级 中断请求标志位 中断允许控制位 外部中断0 0 IE0 EX0 定时器中断0 1 TF0 ET0 外部中断1 2 IE1 EX1 定时器中断
  • 2021 Web 前端热点笔试面试题总结【更新版】

    提醒 我只是答案的搬运工 如果在浏览中发现有错误 欢迎评论中提出来 我好修改 谢谢 简述异步和同步的区别 同步 浏览器访问服务器请求 用户看得到页面刷新 重新发请求 等请求完 页面刷新 新内容出现 用户看到新内容 进行下一步操作 异步 浏览