首先:CSS 规范规定,每个元素都有 display 属性,确定该元素的类型,每个元素都有默认的 display 值,如 div 的 display 默认值为“block”,则为“块级”元素;span 默认 display 属性值为“inline”,是“行内”元素。
、、...、、、、、、 、 常用的内联元素有: 、、、、、、、、、、 常用的内联块状元素有: 、 知名的空元素: 二、这些浏览器的内核分别是什么? IE: trident 内核 Firefox: gecko 内核 Safari: webkit 内核 Opera: 以前是 presto 内核,Opera 现已改用 GoogleChrome 的 Blink 内核 Chrome: Blink(基于 webkit,Google 与 Opera Software 共同开发) 三、get和post区别 get是从服务器获取数据,post是向服务器传输数据 get它的安全性不高,post相对比较安全因为它通过http post机制加密过 get的数据信息可以在浏览器的地址栏(url)里面看到,post则看不到 get数据量较小,一般是2kb左右,post理论上是没有限定 get执行效率要比post高 四、BFC优化 块格式化上下文, 特性: 使 BFC 内部浮动元素不会到处乱跑; 和浮动元素产生边界。 五、块元素和行内元素的区别 块级元素:内容独占一行.块元素会在内联的方向上扩展并占据父容器在该方向上的所有可用空间. 行内元素:不会产生换行.行内元素只占放置其中内容的宽度,块元素忽视内容占据全行. 块元素中width 和 height 属性可以发挥作用.内边距(padding)外边距(margin)和边框(border)起效. 行内元素width 和 height 属性将不起作用. 行内元素垂直方向的内边距、外边距以及边框会被应用但是不会把其他处于 inline 状态的盒子推开. 行内元素水平方向的内边距、外边距以及边框会被应用且会把其他处于 inline 状态的盒子推开. CSS 一、元素垂直居中方法 方案一: 给容器设置 position:relative; 给子元素设置 position:absolute; left:0; right:0; top:0; bottom:0; margin:auto; 方案二:已知高度 给容器设置 position:relative; 给子元素设置 position:absolute; left:50%; top:50%; margin-left: -元素自身一半; margin-top: -元素自身一半; 方案三:未知高度 给容器设置 position:relative; 给子元素设置 position:absolute; left:50%; top:50%; transform:translate(-50%, -50%); 方案四:弹性布局 给容器设置 display:flex; justify-content:center; align-items:center; 二、CSS优先级(权重) 权重可以使用四位数表示: 标记选择器 0 0 0 1 class选择器 0 0 1 0 id选择器 0 1 0 0 内联样式 1 0 0 0 !important 最大 包含选择器 包含选择器权重之和 通配符 没有权重(通配符对权重没有贡献) 三、CSS层叠: 层叠在css里面表示的是规则 一个标记可以同时被多个选择器或者样式表选中,这个时候有些样式可以同时存在有些之间存在冲突问题,当遇到冲突的时候需要一条规则解决问题,这个规则就是css层叠性 四、为什么会出现浮动和什么时候需要清除浮动?清除浮动的方式 浮动元素碰到包含它的边框或者浮动元素的边框停留。由于浮动元素不在文档流中,所以文档流的块框表现得就像浮动框不存在一样。浮动元素会漂浮在文档流的块框上。 浮动带来的问题: 父元素的高度无法被撑开,影响与父元素同级的元素 与浮动元素同级的非浮动元素(内联元素)会跟随其后 若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构。 清除浮动的方式: 空盒子方法,最后一个浮动元素后加空 div ,并添加样式 clear:both; 给容器设置overflow:hidden; 万能清除法(现在主流方法,推荐使用) .clear{ /*zoom在平时可以起到缩放效果,不过宽高不会有变化*/ zoom: 1; 兼容IE地板的浏览器的,可以触发IE浏览器的机制让其支持clear属性 } .clear::after{ content: ""; display: block; clear: both; visibility: hidden; 为了防止content里有内容 height: 0; 可以不加,不过IE低版本下有问题,不写高的时候会默认有大概18px的高 } 五、link和import区别 本质区别:link是html标记提供的一种方式,import是css提供的一种方式 加载顺序:link的方式可以让结构和样式同时加载,import是先加载结构后加载样式 兼容问题:link没有兼容问题,import一些老的版本的浏览器不支持 控制DOM区别:link可以被DOM控制,而import不能被控制 六、元素隐藏 display:none; 隐藏,理解为消失,没有位置。 visibility:hidden; 占位隐藏,元素消失,但位置还在。理解为隐身,且元素的功能不存在。 opacity:0; 隐藏,占位置的,实际上就是透明为0,让你眼睛看不见它了,但元素的功能存在。 溢出隐藏方式: overflow:hidden; 七、position 的 absolute 与 fixed 共同点与不同点: 共同点: 1.改变行内元素的呈现方式,display 被置为 block; 2.让元素脱离普通流,不占据空间; 3.默认会覆盖到非定位元素上 不同点: absolute 的”根元素“是可以设置的,而 fixed 的”根元素“固定为浏览器窗口。当你滚动网页,fixed 元素与浏览器窗口之间的距离是不变的。 八、阴影: 文字 :text-shadow:5px 5px 5px #FF0000;(水平阴影,垂直阴影,模糊距离,阴影颜色) 盒子 : box-shadow 九、一个满屏品字布局如何设计? 第一种真正的品字: 1.三块高宽是确定的; 2.上面那块用 margin: 0 auto;居中; 3.下面两块用 float 或者 inline-block 不换行; 4.用 margin 调整位置使他们居中。 第二种全屏的品字布局: 上面的 div 设置成 100%,下面的 div 分别宽 50%,然后使用 float 或者 inline 使其不换行。 十、为什么要初始化 CSS 样式 因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对 CSS 初始化往往会出现浏览器之间的页面显示差异。 十一、解释 css sprites ,如何使用? 将一个页面涉及到的所有图片都包含到一张大图中去,然后利用 CSS 的 background-image,background- repeat,background-position 的组合进行背景定位。 利用 CSS Sprites 能很好地减少网页的 http 请求,从而大大的提高页面的性能;CSS Sprites 能减少图片的字节。 十二、样式选择器有哪些 *{}:通用选择器 #X{}:ID选择器 .X{}:类选择器 X{}:元素选择器 X Y {}:后代选择器 X:hover {}:伪类选择器 :hover 移入时元素的状态 :visited 已被访问过后的元素的状态 :active 被点击时元素的状态 X + Y {}:紧邻同胞选择器 X > Y {}:子元素选择器 X ~ Y {}:后续同胞选择器 X[title]:简单属性选择器 [title=“value”] 选取含指定 value 的元素 [title^=“value”] 选取 value 以指定内容开头的元素 [title$=“value”] 选取 value 以指定内容结尾的元素 [title*=“value”] 选取 value 含指定内容的元素 具体可以点击查看详情 JS 一、JavaScript 中常见的几种数据类型,以及判断数据类型的方法 JavaScript 有 简单数据类型:Undefined、Null、Boolean、Number、String、Bigint 和 复杂数据类型 Object、Function、Array ,以及es6语法新增的Symbol数据类型 判断方法有:typeof、instanceof、constructor、Object.prototype.toString 具体可以点击查看详情 二、什么是闭包? 闭包是指有权访问另外一个函数作用域中的局部变量的函数。声明在一个函数中的函数,叫做闭包函数。而且内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变量不会被垃圾回收机制回收 三、什么是jsonp?jsonp的优缺点 jsonp是一个能够跨域的方法,由于ajax受到同源策略的影响,不能进行跨域,而script标签中的src属性中的链接能够访问跨域的js脚本,利用这个特性返回一段调用某个函数的js代码,在src中进行了调用,从而实现跨域 优点:可以跨越同源策略、可以在老版本浏览器中运行、请求完毕后可以通过callback的方式回传结果 缺点:只支持get请求、只支持跨域http请求、安全性差 四、异步操作有哪些? 回调函数 事件监听 promise ajax async setTimeout Generator 五、什么是Promise?我们用Promise来解决什么问题? Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息; 从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。 promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变化。创造promise实例后,它会立即执行。 处理问题: 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象 promise可以支持多个并发的请求,获取并发请求中的数据 这个promise可以解决异步的问题,本身不能说promise是异步的 Promise是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。 Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数: resolve :异步操作执行成功后的回调函数 reject:异步操作执行失败后的回调函数 then:传递状态的方式来使得回调函数能够及时被调用 catch:指定reject的回调,或者在执行resolve时,如果抛出异常,并不会报错卡死js,而是会进到这个catch方法中 all:谁跑的慢,以谁为准执行回调。all接收一个数组参数,里面的值最终都会返回Promise对象。提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。 race:谁跑的快,以谁为准执行回调 六、forEach、 map、 filter 的区别 forEach(): 遍历数组,调用数组的每个元素,利用回调函数对数组进行操作,本质上等同于 for 循环。 forEach 会改变原数组。没有返回值, 不支持continue 和 break return只能跳出当前循环 map() 遍历数组,调用数组的每个元素,利用回调函数对数组进行操作,与 forEach 类似。 不过map是返回一个新数组,原数组不变,新数组的索引结构和原数组一致 map需要return返回值 filter() 遍历数组,返回一个新数组(原数组的子集),回调函数用于逻辑判断 回调函数为 true 则将当前元素添加到新数组中,false 则跳过 不会改变原数组 具体可以点击查看详情 七、for···in··· 和 for···of··· 的区别 for···in···用来遍历数组和对象的键(key) for···of···用来遍历数组的值(value) for···in··是ES5里的标准 for···of···是ES6里的标准 具体可以点击查看详情 八、事件代理/事件委托 利⽤冒泡机制,将⼦元素的事件委托给⽗元素去监听(给⽗元素添加事件),当⼦元素触发事件时, 事件冒泡到⽗级如果希望指定的⼦元素才能触发事件,可以通过事件对象(event)获得事件源 (target),然后通过 条件判断是不是期望的⼦元素,如果是的话,执⾏事件,否则不执⾏ 事件委托的好处:1.实现对未来元素事件的绑定 2.减少事件绑定,提⾼性能 九、AJAX AJAX = Asynchronous JavaScript and XML. AJAX 是一种用于创建快速动态网页的技术。 AJAX 通过在后台与服务器进行少量数据交换,使网页实现异步更新。这意味着可以在不重载整个页面的情况下,对网页的某些部分进行更新。 传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个页面。 简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。 实现 原生AJAX 创建 XMLHttpRequest(xhr) 对象实例(准备手机) 建立连接,调用 xhr.open() 建立连接(查找电话号码,准备拨号) 发送数据,调用 xhr.send() (拨号) 准备处理响应数据(等待接通电话,通话) // 创建核心对象 const xhr = new XMLHttpRequest() // 建立连接 xhr.open(method, url, async) // 发送请求 // 如果为 post 需要在 send 前调用 setRequestHeader() 方法设置请求头 // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhr.send(params) // 处理响应 xhr.onreadystatechange = function() { // 当 readyState 改变时,执行该回调函数 // readyState 属性存有 XMLHttpRequest 的状态信息。 // 可以理解为请求到达哪个阶段了。 // 状态值可取 0-4 的值,4表示请求处理完毕,响应就绪 if(xhr.readyState === 4) { // status 表示的是 HTTP 状态码 // 200 表示 OK (成功) if(xhr.status === 200) { // 从响应中获取返回的数据 let data = xhr.responseText } } } // Promise 封装 ajax const myAjax = function(url) { return Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.send(params) xhr.onreadystatechange = function() { if(xhr.readyState === 4) { if(xhr.status === 200){ let data = JSON.prase(xhr.responseText) resolve(data) } else { reject('error') } } } }) } 十、关于this指向问题 随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,this永远指向的是最后调用它的对象。 this指向的形式 (4种) 如果是一般函数,this 指向全局对象 window 在严格模式 “use strict” 下,为 undefined 对象的方法里调用,this 指向调用该方法的对象 构造函数里的 this ,指向new创建出来的实例 为什么this会指向?首先new关键字会创建一个空的对象,然后会自动调用一个函数apply方法(不一定是这个方法,举例子用的),将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。 当 this 碰到 return 如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么 this 还是指向函数的实例。 注意:虽然null也是对象,但是在这里 this 指向那个函数的实例,因为null 比较特殊。 改变this指向的方式 call:除了第一个参数以外还可以添加多个参数, b.call(a,1,2) apply:与 call 类似,但是不同的是,它第二个参数必须是一个数组, b.apply(a,[1,2]) 注意: 如果 call 和 apply 的第一个参数写的是 null,那么 this 指向的是 window 对象 bind:可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。 总结: call 和 apply 都是改变上下文中的 this 并立即执行这个函数 bind 方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加 十一、关于js类的继承 原型链继承 特点:基于原型链,既是父类的实例,也是子类的实例 缺点:无法实现多继承 构造继承 特点:可以实现多继承 缺点:只能继承父类实例的属性和方法,不能继承原型上的属性和方法 实例继承 为父类实例添加新特性,作为子类实例返回 拷贝继承 拷贝父类元素上的属性和方法 组合继承 特点:可以继承实例属性/方法,也可以继承原型属性/方法 缺点:调用了两次父类构造函数,生成了两份实例 寄生组合继承 特点:通过寄生方式,砍掉父类的实例属性,在调用两次父类的构造时,就不会初始化两次实例方法/属性 具体可以点击查看详情 十二、函数提升和变量提升 1.变量提升只会提升变量名的声明,而不会提升变量的赋值初始化。 2.函数提升的优先级大于变量提升的优先级,即函数提升在变量提升之上。 例子: var a = 10; function a(){} console.log(typeof a) A."number" B."object" C."function" D."undefined" 答案:A 代码等价于: function a(){} var a; a = 10; console.log(typeof a) 十三、原型 / 构造函数 / 实例 原型(prototype): 一个简单的对象,用于实现对象的 属性继承。可以简单的理解成对象的爹。在 Firefox 和 Chrome 中,每个 JavaScript 对象中都包含一个__proto__ (非标准)的属性指向它爹(该对象的原型),可 obj.__proto__ 进行访问。 所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象 所有函数都有一个prototype(原型)属性,属性值是一个普通的对象 所有引用类型的__proto__属性指向它构造函数的prototype 构造函数: 可以通过 new 来 新建一个对象 的函数。 实例: 通过构造函数和 new 创建出来的对象,便是实例。 实例通过__proto__ 指向原型,通过 constructor 指向构造函数 三者的关系: 实例.__proto__ === 原型 原型.constructor === 构造函数 构造函数.prototype === 原型 十四、原型链: 原型链是由原型对象组成,每个对象都有__proto__ 属性,指向了创建该对象的构造函数的原型,__proto__将对象连接起来组成了原型链。是一个用来实现继承和共享属性的有限的对象链。 当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的 __proto__ 隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的 prototype 的 __proto__ 中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。 属性查找机制: 当查找对象的属性时,如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象 Object.prototype,如还是没找到,则输出undefined; 属性修改机制: 只会修改实例对象本身的属性,如果不存在,则进行添加该属性,如果需要修改原型的属性时,则可以用: b.prototype.x = 2;但是这样会造成所有继承于该对象的实例的属性发生改变。 十五、JS 的语言特性 运行在客户端浏览器上; 不用预编译,直接解析执行代码; 是弱类型语言,较为灵活; 与操作系统无关,跨平台的语言; 脚本语言、解释性语言 十六、JS 实现跨域 跨域的原理:指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript 实施的安全限制,那么只要协议、域名、端口有任何一个不同,都被当作是不同的域。跨域原理,即是通过各种方式,避开浏览器的安全限制。 JSONP : 通 过 动 态 创 建 script , 再 请 求 一 个 带 参 网 址 实 现 跨 域 通 信 。 document.domain + iframe 跨域:两个页面都通过 js 强制设置 document.domain为基础主域,就实现了同域。 location.hash + iframe 跨域:a 欲与 b 跨域相互通信,通过中间页 c 来实现。三个页面,不同域之间利用 iframe 的 location.hash 传值,相同域之间直接 js访问来通信。 window.name + iframe 跨域:通过 iframe 的 src 属性由外域转向本地域,跨域数据即由 iframe 的window.name 从外域传递到本地域。 postMessage 跨域:可以跨域操作的 window 属性之一。 CORS:服务端设置 Access-Control-Allow-Origin 即可,前端无须设置,若要带cookie 请求,前后端都需要设置。 代理跨域:启一个代理服务器,实现数据的转发 十七、数组去重 法一:indexOf 循环去重 法二:ES6 Set 去重;Array.from(new Set(array)) 法三:Object 键值对去重;把数组的值存成 Object 的 key 值,比如 Object[value1] = true,在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的。 十八、暂停死区 在代码块内,使用 let、const 命令声明变量之前,该变量都是不可用的。在语法上,称为“暂时性死区” 十九、webpack 用来干什么的 webpack 是 一 个 现 代 JavaScript 应 用 程 序 的 静 态 模 块 打 包 器 (module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。 二十、第一秒打印 1,第二秒打印 2 // 第一个方法:用 let 块级作用域 for(let i = 0; i < 5; i++) { setTimeout(function() { console.log(i + 1) }, 1000 * i) } // 第二个方法:闭包 for(var i = 0; i < 5; i++) { (function(i) { setTimeout(function(){ console.log(i + 1) }, 1000 * i) })(i) } 二十一、简单介绍一下 symbol Symbol 是 ES6 的新增属性,代表用给定名称作为唯一标识,这种类型的值可以这样创建,let id = symbol(“id”) Symbl 确保唯一,即使采用相同的名称,也会产生不同的值,我们创建一个字段,仅为知道对应 symbol 的人能访问,使用 symbol 很有用,symbol 并不是 100%隐藏,有内置方法 Object.getOwnPropertySymbols(obj)可以获得所有的 symbol。也有一个方法 Reflect.ownKeys(obj)返回对象所有的键,包括 symbol。所以并不是真正隐藏,但大多数库内置方法和语法结构遵循通用约定他们是隐藏的。 二十二、浅谈堆和栈的理解? js变量存储有栈存储和堆存储,基本数据类型的变量存储在栈中,引⽤数据类型的变量存储在堆中,引⽤类型数据的地址也存在栈中 当访问基础类型变量时,直接从栈中取值。当访问引⽤类型变量时,先从栈中读取地址,在根据地址到堆中取出数据 二十三、箭头函数与普通函数的区别在于: 箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值,这就意味着如果箭头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的this, 箭头函数没有自己的 arguments 对象,但是可以访问外围函数的 arguments对象 不能通过 new 关键字调用,同样也没有 new.target 值和原型 二十四、简单讲一讲 ES6 的一些新特性 ES6 在变量的声明和定义方面增加了 let、const 声明变量,有局部变量的概念 赋值中有比较吸引人的结构赋值; ES6 对字符串、 数组、正则、对象、函数等拓展了一些方法,如字符串方面的模板字符串、函数方面的默认参数、对象方面属性的简洁表达方式, ES6 也 引入了新的数据类型 symbol,新的数据结构set 和 map,symbol 可以通过 typeof 检测出来 为解决异步回调问题,引入了promise 和 generator, 最为吸引人了实现 Class 和模块,通过 Class 可以更好的面向对象编程,使用模块加载方便模块化编程,当然考虑到 浏览器兼容性,我们在实际开发中需要使用 babel 进行编译 重要的特性: 块级作用域:ES5 只有全局作用域和函数作用域,块级作用域的好处是不再需要立即执行的函数表达式,循环体中的闭包不再有问题 rest 参数:用于获取函数的多余参数,这样就不需要使用 arguments 对象了, promise:一种异步编程的解决方案,比传统的解决方案回调函数和事件更合理强大 模块化:其模块功能主要有两个命令构成,export 和 import,export 命令用于规定模块的对外接口,import 命令用于输入其他模块提供的功能 二十五、call 和 apply 是用来做什么? Call 和 apply 的作用是一模一样的,只是传参的形式有区别而已 1、改变 this 的指向 2、借用别的对象的方法 3、调用函数,因为 apply,call 方法会使函数立即执行 二十六、new 操作符原理 创建一个类的实例:创建一个空对象 obj,然后把这个空对象的__proto__设置为构造函数的 prototype。 初始化实例:构造函数被传入参数并调用,关键字 this 被设定指向该实例obj。 返回实例 obj。 二十八、javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么? 除了正常模式运行外,ECMAscript 5 添加了第二种运行模式:“严格模式”。 作用: 消除 js 不合理,不严谨地方,减少怪异行为 消除代码运行的不安全之处, 提高编译器的效率,增加运行速度 为未来的 js 新版本做铺垫 二十九、对 JSON 的了解? 全称:JavaScript Object Notation JSON 中对象通过“{}”来标识,一个“{}”代表一个对象,如{“AreaId”:”123”},对象的值是键值对的形式(key:value)。JSON 是 JS 的一个严格的子集,一种轻量级的数据交换格式,类似于 xml。数据格式简单,易于读写,占用带宽小。 两个函数: JSON.parse(str) 解析 JSON 字符串 把 JSON 字符串变成 JavaScript 值或对象 JSON.stringify(obj) 将一个 JavaScript 值(对象或者数组)转换为一个 JSON 字符串 eval(‘(‘+json+’)’) 用 eval 方法注意加括号 而且这种方式更容易被攻 三十、同步和异步的区别? 同步的概念在操作系统中:不同进程协同完成某项工作而先后次序调整(通过阻塞、唤醒等方式),同步强调的是顺序性,谁先谁后。异步不存在顺序性。 同步:浏览器访问服务器,用户看到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容之后进行下一步操作。 异步:浏览器访问服务器请求,用户正常操作,浏览器在后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。 三十一、CSS 加载会造成阻塞吗? 先给出结论 CSS 不会阻塞 DOM 解析,但会阻塞 DOM 渲染。CSS 会阻塞 JS 执行,并不会阻塞 JS 文件下载 先讲一讲 CSSOM 作用: 第一个是提供给 JavaScript 操作样式表的能力; 第二个是为布局树的合成提供基础的样式信息。 这个 CSSOM 体现在 DOM 中就是 document.styleSheets。 由之前讲过的浏览器渲染流程我们可以看出: DOM 和 CSSOM 通常是并行构建的,所以「CSS 加载不会阻塞 DOM 的解析」。然而由于 Render Tree 是依赖 DOM Tree 和 CSSOM Tree 的,所以它必须等到两者都加载完毕后,完成相应的构建,才开始渲染,因此,「CSS 加载会阻塞 DOM渲染」。 由于 JavaScript 是可操纵 DOM 和 css 样式 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。因此为了防止渲染出现不可预期的结果,浏览器设置 「GUI 渲染线程与JavaScript 引擎为互斥」的关系。 有个需要注意的点就是: 「有时候 JS 需要等到 CSS 的下载,这是为什么呢?」 仔细思考一下,其实这样做是有道理的,如果脚本的内容是获取元素的样式,宽高等 CSS 控制的属性,浏览器是需要计算的,也就是依赖于 CSS。浏览器也无法感知脚本内容到底是什么,为避免样式获取,因而只好等前面所有的样式下载完后,再执行 JS。JS 文件下载和 CSS 文件下载是并行的,有时候 CSS 文件很大,所以 JS 需要等待。因此,样式表会在后面的 js 执行前先加载执行完毕,所以「css 会阻塞后面 js的执行」。 三十二、为什么 JS 会阻塞页面加载? JS 阻塞 DOM 解析,也就会阻塞页面 这也是为什么说 JS 文件放在最下面的原因,那为什么会阻塞 DOM 解析呢 你可以这样子理解: 由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。 因此为了防止渲染出现不可预期的结果,浏览器设置 「GUI 渲染线程与JavaScript 引擎为互斥」的关系。 当 JavaScript 引擎执行时 GUI 线程会被挂起,GUI 更新会被保存在一个队列中等到引擎线程空闲时立即被执行。 当浏览器在执行 JavaScript 程序的时候,GUI 渲染线程会被保存在一个队列中, 直到 JS 程序执行完成,才会接着执行。因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。 另外 ,如 果 JavaScript 文件 中没 有操 作 DOM 相关 代码 ,就 可以将 该JavaScript 脚本设置为异步加载,通过 async 或 defer 来标记代码。 三十三、JavaScript 判断对象属性是否存在(对象是否包含某个属性) 属性名 in 对象,可以检测自有属性和继承属性 hasOwnProperty() 只能检测自有属性 使用 !== undefined 检测,注意:对象属性不能为 undefined 具体可以点击查看详情 三十四、操作js数组有哪些方法? shift():删除数组的第一个元素,返回删除的值。 unshift(3,4):把一个或多个参数加载数组的前面,返回数组的长度 pop():删除数组的最后一个元素,返回删除的值。 push(3):将参数加载到数组的最后,返回数组的长度 concat([6,7,8],9,10):把两个数组拼接起来。 splice(start,deleteCount,val1,val2,…):从start位置开始删除deleteCount项,并从该位置起插入val1,val2,…,如果deleteCount为0,就表示从start位置开始添加元素。 reverse():将数组反序 sort(orderfunction):按指定的参数对数组进行排序 slice(start,end):返回从原数组中指定开始下标到结束下标之间的项组成的新数组 join():数组的每个元素以指定的字符连接形成新字符串返回; 三十五、数组求和得最快的方法 eval(arr.join(“+”)) 三十六、同步与异步 同步:同步任务是指在主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务。 异步:异步任务是指不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程。 三十七、JavaScript里面0.1+0.2 === 0.3是false 解决办法 const withinErrorMargin = (left, right) => { return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2); } console.log(withinErrorMargin(0.1 + 0.2, 0.3)) // 第二种方法 console.log(parseFloat((0.1 + 0.2).toFixed(10)) === 0.3) 三十八、js常见设计模式详解 具体可以点击查看详情 三十九、什么是作用域? 作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。 ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 的到来,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。 作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。 浏览器、服务端、网络 一、http 和 https 的区别 HTTPS = HTTP + SSL(安全套接字协议) https 有 ca 证书,http 一般没有 http 是超文本传输协议,信息是明文传输。https 则是具有安全性的 ssl 加密传输协议 http 默认 80 端口,https 默认 443 端口。 二、网络分层(OSI)里七层模型 应用层:允许访问 OSI 环境的手段 表示层:对数据进行翻译、加密和压缩 会话层:建立、管理和终止会话 传输层:提供端到端的可靠报文传递和错误恢复 网络层:负责数据包从源到宿的传递和网际互连 数据链路层:定义了如何让格式化数据以帧为单位进行传输 物理层:通过媒介传输比特, 确定机械及电气规范 三、HTTP 状态码知道哪些?分别什么意思? 1xx 表示信息, 服务器收到请求, 需要请求者继续执行操作 2xx 表示成功,处理完毕 3xx 表示需要进一步操作 4xx 表示客户端方面出错 5xx 表示服务器方面出错 2xx (3种) 200 OK:表示从客户端发送给服务器的请求被正常处理并返回; 204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回); 206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。 3xx (5种) 301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL; 302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL; 301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL) 303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源; 302与303的区别:后者明确表示客户端应当采用GET方式获取资源 304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码; 307 Temporary Redirect:临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况); 4xx (4种) 400 Bad Request:表示请求报文中存在语法错误; 401 Unauthorized:未经许可,需要通过HTTP认证; 403 Forbidden:服务器拒绝该次访问(访问权限出现问题) 404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用; 5xx (2种) 500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时; 503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求; 四、请描述⼀下 cookies,sessionStorage 和 localStorage 的区别? 共同点:都是保存在浏览器端,并且是同源的 cookie 可以在浏览器和服务器间来回传递,存储容量小,只有大约4K左右。 作用:1、保存用户登录状态;2、跟踪用户行为。 localStorage ⻓期存储数据,浏览器关闭后数据不会丢失; sessionStorage 数据在浏览器关闭后⾃动删除。 sessionStorage和localStorage优势:存储空间更⼤、有更多丰富易⽤的接⼝、各⾃独⽴的存储空间 五、在浏览器地址栏输⼊ www.baidu.com 后按下回车键会发生什么 DNS域名解析系统 ,把域名解析ip地址 把ip发送到⽹络供应商,进行TCP的三次握⼿ 建⽴连接 开始发送请求 取回⼊⼝⽂件index.html 开始解析⼊⼝⽂件,并且取回需要的资源sources 进入地址前端模块 六、一个页面从输入 URL 到页面加载显示完成,这个过程都发生了什么: 分为 4 个步骤: (1)浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP,向服务器发起请求; (2)浏览器与远程 Web 服务器通过 TCP 三次握手协商来建立一个 TCP/IP 连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。 (3)一旦 TCP/IP 连接建立,浏览器会通过该连接向远程服务器发送 HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源,值为 200 的 HTTP 响应状态表示一个正确的响应。 (4)此时,Web 服务器提供资源服务,客户端开始下载资源。请求返回后,载入解析到的资源文件,渲染页面,便进入了我们关注的前端模块 简述版: DNS解析 TCP连接 发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束 七、token 的含义: Token 的引入:Token 是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。 Token 的定义:Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此 Token 返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。 使用 Token 的目的:Token 的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。 具体可以点击查看详情 八、重绘与回流 当元素的样式发生变化时,浏览器需要触发更新,重新绘制元素。这个过程中,有两种类型的操作,即重绘与回流。 重绘(repaint): 当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此 损耗较少 回流(reflow): 当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。会触发回流的操作: 页面初次渲染 浏览器窗口大小改变 元素尺寸、位置、内容发生改变 元素字体大小变化 添加或者删除可见的 dom 元素 激活 CSS 伪类(例如::hover) 查询某些属性或调用某些方法: clientWidth、clientHeight、clientTop、clientLeft offsetWidth、offsetHeight、offsetTop、offsetLeft scrollWidth、scrollHeight、scrollTop、scrollLeft getComputedStyle() getBoundingClientRect() scrollTo() 回流必定触发重绘,重绘不一定触发回流。重绘的开销较小,回流的代价较高。 最佳实践: css: 避免使用 table 布局 将动画效果应用到 position 属性为 absolute 或 fixed 的元素上 javascript 避免频繁操作样式,可汇总后统一 一次修改 尽量使用 class 进行样式修改 减少 dom 的增删次数,可使用 字符串 或者 documentFragment 一次性插入 极限优化时,修改样式可将其 display: none 后修改 避免多次触发上面提到的那些会触发回流的方法,可以的话尽量用 变量存贮 九、浏览器如何阻止事件传播,阻止默认行为 阻止事件传播(冒泡): e.stopPropagation() 阻止默认行为: e.preventDefault() 十、浏览器事件机制中事件触发三个阶段 事件捕获阶段: 从 dom 树节点往下找到目标节点, 不会触发函数 事件目标处理函数: 到达目标节点 事件冒泡: 最后从目标节点往顶层元素传递, 通常函数在此阶段执行. addEventListener 第三个参数默认false(冒泡阶段执行), true(捕获阶段执行). 十一、什么是跨域?为什么浏览器要使用同源策略?你有几种方式可以解决跨域问题?了解预检请求嘛? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源 防止 XSS、CSFR 等攻击, 协议+域名+端口不同 jsonp; 跨域资源共享(CORS); (Access control); 服务器正向代理等 预检请求: 需预检的请求要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。 十二、进程和线程的区别 进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。 线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。 一个程序至少一个进程,一个进程至少一个线程。 十三、浏览器内核 浏览器内核可以分成两部分: 渲染引擎(layout engineer 或者 Rendering Engine)和 JS 引擎。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。 渲染引擎: 负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入 CSS 等),以及计算网页的显示方式,然后会输出至显示器或打印机。 JS 引擎 解析 Javascript 语言,执行 javascript 语言来实现网页的动态效果。最开始渲染引擎和 JS 引擎并没有区分的很明确,后来 JS 引擎越来越独立,内核就倾向于只指渲染引擎。 十四、描述浏览器渲染过程 DOM Tree 和 CSS RULE Tree 将 html 和 css 解析成树形数据结构,然后 Dom 和 css 合并后生成Render Tree,用 layout 来确定节点的位置以及关系,通过 painting 按照规则来画到屏幕上,由 display 搭建最终看到效果。 十五、什么是 XXS 攻击 Cross-site script,跨站脚本攻击,当其它用户浏览该网站时候,该段 HTML 代码会自动执行,从而达到攻击的目的,如盗取用户的 Cookie,破坏页面结构,重定向到其它网站等。 XSS 类型: 一般可以分为: 持久型 XSS 和非持久性 XSS 持久型 XSS: 就是对客户端攻击的脚本植入到服务器上,从而导致每个正常访问到的用户都会遭到这段 XSS 脚本的攻击。 非持久型 XSS: 是对一个页面的 URL 中的某个参数做文章,把精心构造好的恶意脚本包装在 URL 参数重,再将这个 URL 发布到网上,骗取用户访问,从而进行攻击。 十六、CSRF 攻击 CSRF(Cross-site request forgery), 中文名称:跨站请求伪造 CSRF 可以简单理解为:攻击者盗用了你的身份,以你的名义发送恶意请求,容易造成个人隐私泄露以及财产安全。 防范: post 请求 使用 token 验证码 十七、DDOS 攻击 利用目标系统网络服务功能缺陷或者直接消耗其系统资源,使得该目标系统无法提供正常的服务。 DDoS 攻击通过大量合法的请求占用大量网络资源,以达到瘫痪网络的目的。 具体有几种形式: 通过使网络过载来干扰甚至阻断正常的网络通讯; 通过向服务器提交大量请求,使服务器超负荷; 通过阻断某一用户访问服务器; 通过阻断某服务与特定系统或个人的通讯。 十八、URL 和 URI 有什么区别 URI 是统一资源标识符,相当于一个人身份证号码 Web 上可用的每种资源如 HTML 文档、图像、视频片段、程序等都是一个来 URI来定位的 URI 一般由三部组成 ①访问资源的命名机制 ②存放资源的主机名 ③资源自身的名称,由路径表示,着重强调于资源。 URL 是统一资源定位符,相当于一个人的家庭住址 URL 是 Internet 上用来描述信息资源的字符串,主要用在各种 WWW 客户程序和服务器程序上,特别是著名的 Mosaic。采用 URL 可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。 URL 一般由三部组成 ①协议(或称为服务方式) ②存有该资源的主机 IP 地址(有时也包括端口号) ③主机资源的具体地址。如目录和文件名等。 十九、TCP 三次握手 SYN表示建立连接,ACK表示响应 建立连接前,客户端和服务端需要通过握手来确认对方: 客户端发送 syn(同步序列编号) 请求,进入 syn_send 状态,等待确认 服务端接收并确认 syn 包后发送 syn+ack 包,进入 syn_recv 状态 客户端接收 syn+ack 包后,发送 ack 包,双方进入 established 状态 二十、TCP 四次挥手 SYN表示建立连接,FIN表示关闭连接,ACK表示响应 客户端 – FIN --> 服务端, FIN—WAIT 服务端 – ACK --> 客户端, CLOSE-WAIT 服务端 – ACK,FIN --> 客户端, LAST-ACK 客户端 – ACK 二十一、http协议中数据请求的方法 get::从服务器获取数据 post:向服务器传输数据 put:上传指定的 URL delete:删除指定资源 options:返回服务器支持的 http 方法 head:与 get 类似,但只能获取 http 报头 connect:将请求连接转换到透明的 tcp/ip 通道 二十二、DNS解析 浏览器缓存 操作系统缓存 本地域名服务器 根域名服务器请求解析 顶级域名服务器 VUE 一、v-if vs v-show v-if 是真正的条件渲染,通过节点的销毁、重建来实现 v-if 是惰性的,即初始条件为 false 时,什么也不做,直到条件第一次为 true 才开始渲染 v-show 总会被渲染,只是简单的基于 CSS 来实现样式切换 v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。 总结: v-if 按照条件是否渲染,v-show 是 display 的 block 或 none 二、v-if 与 v-for 一起使用 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。(注意这里是 2.x 的版本,3.x 反之) 不推荐同时使用 v-if 和 v-for。 三、计算属性(computed) VS 方法 计算属性的值会被缓存,计算属性是基于它们的响应式依赖进行缓存的,当依赖项改变时,才重新计算计算属性的值并继续缓存。 方法不会缓存,每调用一次方法,都会重新执行一次方法主体代码块 四、计算属性 VS 侦听器 计算属性的值会被缓存。 侦听器不能被缓存。 通常计算属性是根据一个或多个已有数据,返回一个新的值,侦听器是监听一个数据的变化,可能由一个数据的变化导致其它一个或多个数据的变化,或导致其它一些副作用 五、vue.js 的两个核心是什么? 答:数据驱动、组件系统 六、vue 常用的修饰符? .prevent: 提交事件不再重载页面; .stop: 阻止单击事件冒泡; .self: 当事件发生在该元素本身而不是子元素的时候会触发; .capture: 事件侦听,事件发生的时候会调用 七、vue 中 key 值的作用? 答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟DOM。 八、Vue 组件间的参数传递 父组件与子组件传值: 父组件传给子组件:子组件通过 props 方法接受数据; 子组件传给父组件:$emit 方法传递参数 非父子组件间的数据传递,兄弟组件传值: eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用 VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。) 详情可以看看这个 九、Vue.js 双向绑定的原理 Vue.js 2.0 采用数据劫持(Proxy 模式)结合发布者-订阅者模式(PubSub 模式)的方式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。 1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数 3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图 十、Vue中如何监控某个属性值的变化? 例如现在需要监控data中, obj.a 的变化。Vue中监控对象属性的变化你可以这样: watch: { 'obj.a': { handler (newName, oldName) { console.log('obj.a changed') } } } 另一种方法,利用计算属性(computed) 的特性来实现,当依赖改变时,便会重新计算一个新值。 computed: { a1 () { return this.obj.a } } 十一、虚拟DOM,diff算法 让我们不用直接操作DOM元素,只操作数据便可以重新渲染页面 虚拟dom是为了解决浏览器性能问题而被设计出来的 当操作数据时,将改变的dom元素缓存起来,都计算完后再通过比较映射到真实的dom树上 diff算法比较新旧虚拟dom。如果节点类型相同,则比较数据,修改数据; 如果节点不同,直接干掉节点及所有子节点,插入新的节点; 如果给每个节点都设置了唯一的key,就可以准确的找到需要改变的内容,否则就会出现修改一个地方导致其他地方都改变的情况。例如A-B-C-D, 我要插入新节点A-B-M-C-D,实际上改变了C和D。但是设置了key,就可以准确的找到B C并插入 总结:虚拟dom可以很好的跟踪当前dom状态,因为他会根据当前数据生成一个描述当前dom结构的虚拟dom,然后数据发生变化时,又会生成一个新的虚拟dom,而这两个虚拟dom恰恰保存了变化前后的状态。然后通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些)。可以很明显的提升渲染效率以及用户体验 十二、v-model 是如何实现的,语法糖实际是什么 作用在表单元素上 v-model = "message" 等同于 v-bind:value = "message" v-on:input = "message=event.target.value" 作用在组件上,本质是一个父子组件通信的语法糖,通过 prop 和 .emit 实现, 等同于:value = "message" @input = "$emit('input', $event.target.value)" 十三、data为什么是一个函数而不是对象 JS中的对象是引用类型的数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。 而在Vue中,我们更多的是想要复用组件,那就需要每个组件都有自己的数据,这样组件之间才不会相互干扰。 所以组件的数据不能写成对象的形式,而是要写成函数的形式。数据以函数返回值的形式定义,这样当我们每次复用组件的时候,就会返回一个新的data,也就是说每个组件都有自己的私有数据空间,它们各自维护自己的数据,不会干扰其他组件的正常运行。 十四、vue 生命周期 介绍:每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。 beforecreate (初始化界面前) created (初始化界面后) beforemount (渲染界面前) mounted (渲染界面后) beforeUpdate (更新数据前) updated (更新数据后) beforedestory (卸载组件前) destroyed (卸载组件后) 十五、keep-alive < keep-alive >是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。 < keep-alive > 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 生命周期钩子:actived:激活调用; deactived:停用时调用 属性:include:名称(正则 or 字符串)匹配时调用; exclude:名称不匹配时调用; max:最多缓存数量 十六、Vuex是什么?怎么使用? Vuex是实现组件全局状态(数据)管理的一种机制,可以方便实现组件数据之间的共享; Vuex集中管理共享的数据,易于开发和后期维护; 能够高效的实现组件之间的数据共享,提高开发效率; 存储在 Vuex 的数据是响应式的,能够实时保持页面和数据的同步; Vuex重要核心属性包括:state, mutations, action, getters, modules. state Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。 mutations mutations定义的方法动态修改Vuex 的 store 中的状态或数据。 action actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。 getters 类似vue的计算属性,主要用来过滤一些数据。 modules 项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。 十七、axios 是什么,其特点和常用语法是什么? Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,react/vue 官方都推荐使用 axios 发 ajax 请求 特点: 基于 promise 的异步 ajax 请求库,支持promise所有的API 浏览器端/node 端都可以使用,浏览器中创建XMLHttpRequests 支持请求/响应拦截器 支持请求取消 可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据 批量发送多个请求 安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。 常用语法: axios(config): 通用/最本质的发任意类型请求的方式 axios(url[, config]): 可以只指定 url 发 get 请求 axios.request(config): 等同于 axios(config) axios.get(url[, config]): 发 get 请求 axios.delete(url[, config]): 发 delete 请求 axios.post(url[, data, config]): 发 post 请求 axios.put(url[, data, config]): 发 put 请求 axios.defaults.xxx: 请求的默认全局配置 axios.interceptors.request.use(): 添加请求拦截器 axios.interceptors.response.use(): 添加响应拦截器 axios.create([config]): 创建一个新的 axios(它没有下面的功能) axios.Cancel(): 用于创建取消请求的错误对象 axios.CancelToken(): 用于创建取消请求的 token 对象 axios.isCancel(): 是否是一个取消请求的错误 axios.all(promises): 用于批量执行多个异步请求 axios.spread(): 用来指定接收所有成功数据的回调函数的方法 十八、路由传值的方式有哪几种 1 动态路由传值。例如:path:“/home/:id/name”; 接受的时候通过 this.$route.params 2 query 传值。因为在 url 中 ?后面的参数不会被解析,因此我们可以通过 query 进行传值。接受的时候通过 this.$route.query 3 路由解耦。在配置路由的时候添加 props 属性为 true,在需要接受参数的组件页面通过 props 进行接受 4 编程式导航 this.$router.push({path:"/home",query:{}}); 十九、 $route 和 $router 的区别 $route 是 “路由信息对象”,包括 path,params,hash,query,fullPath, matched,name 等路由信息参数。 $router 是“路由实例”对象包括了路由的跳转方法,钩子函数等。 二十、怎么定义 vue-router 的动态路由?怎么获取传过来的值? 动态路由的创建,主要是使用 path 属性过程中,使用动态路径参数,以冒号开头,如下: { path: '/details/:id' name: 'Details' components: Details } 访问 details 目录下的所有文件,如果 details/a,details/b 等,都会映射到 Details 组件上。当匹配到 /details 下的路由时,参数值会被设置到 this.$route.params 下,所以通过这个属性可以获取动态参数 this.$route.params.id 二十一、vue-router 有哪几种路由守卫? 路由守卫为: 全局守卫:beforeEach 后置守卫:afterEach 全局解析守卫:beforeResolve 路由独享守卫:beforeEnter 二十二、MVC和MVVM的区别 MVC表示“模型-视图-控制器”,MVVM表示“模型-视图-视图模型”; MVVM是由MVC衍生出来的。MVC中,View会直接从Model中读取数据; MVVM各部分的通信是双向的,而MVC各部分通信是单向的; MVVM是真正将页面与数据逻辑分离放到js里去实现,而MVC里面未分离。 具体可以点击查看详情 算法 一、冒泡排序 bubbleSort = arr => { for (let i = 0, l = arr.length; i < l - 1; i++) { for (let j = 0; j < l - 1 - i; j++) { if(arr[j] > arr[j+1]) { let temp = arr[j+1] arr[j+1] = arr[j] arr[j] = temp } } } return arr } console.log('结果:', bubbleSort([5,3,2,4,8])) 二、选择排序 selectSort = arr => { for (let i = 0,l = arr.length; i < l - 1; i++) { for (let j = i+1; j < l; j++) { if(arr[i] > arr[j]) { let temp = arr[i] arr[i] = arr[j] arr[j] = temp } } } return arr } console.log('结果:', selectSort([5,3,2,4])) 三、插入排序 insertSort = arr => { let l = arr.length for(let i = 1; i < l; i++){ let temp = arr[i] let j = i - 1 for(; j >= 0 && arr[j] > temp; j--) { arr[j+1] = arr[j] } arr[j+1] = temp } return arr } console.log(insertSort([3,44,58,2,9,1])) 四、快速排序 quickSort = arr => { let l = arr.length let leftArr = [] let rightArr = [] let a = arr[0] if( l <= 1) { return arr } for(let i = 1; i < l; i++) { if(arr[i] > a) { rightArr.push(arr[i]); } else{ leftArr.push(arr[i]); } } return [].concat(quickSort(leftArr),[a],quickSort(rightArr)) } console.log('结果:', quickSort([5,1,6,7])) 五、全排列 func = arr => { let len = arr.length let res = [] // 所有排列结果 /** * 【全排列算法】 * 说明:arrange用来对arr中的元素进行排列组合,将排列好的各个结果存在新数组中 * @param tempArr:排列好的元素 * @param leftArr:待排列元素 */ let arrange = (tempArr, leftArr) => { if (tempArr.length === len) { // 这里就是递归结束的地方 res.push(tempArr.join('')) // 得到全排列的每个元素都是字符串 } else { leftArr.forEach((item, index) => { let temp = [].concat(leftArr) temp.splice(index, 1) // 此时,第一个参数是当前分离出的元素所在数组;第二个参数temp是传入的leftArr去掉第一个后的结果 arrange(tempArr.concat(item), temp) // 这里使用了递归 }) } } arrange([], arr) return res } console.log('结果:', func(['A', 'B', 'C', 'D'])) 六、js 实现队列 /** 队列思想(FIFO) 先进先出 * enqueue(element):向队列尾部添加一个(或多个)新的项; * dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素; * front():返回队列中的第一个元素——最先被添加,也将是最先被移除的元素。 队列不做任何变动(不移除元素,只返回元素信息与Stack类的peek方法非常类似); * isEmpty():如果队列中不包含任何元素,返回true,否则返回false; * size():返回队列包含的元素个数,与数组的length属性类似; * toString():将队列中的内容,转成字符串形式 */ function Queue() { this.items = [] // enqueue():将元素加入到队列中 Queue.prototype.enqueue = element => { this.items.push(element) } // dequeue():从队列中删除前端元素 Queue.prototype.dequeue = () => { return this.items.shift() } // front():查看前端的元素 Queue.prototype.front = () => { return this.items[0] } // isEmpty:查看队列是否为空 Queue.prototype.isEmpty = () => { return this.items.length === 0 } // size():查看队列中元素的个数 Queue.prototype.size = () => { return this.items.length } // toString():将队列中元素以字符串形式输出 Queue.prototype.toString = () => { let resultString = '' for (let i of this.items){ resultString += i + ' ' } return resultString } } // 创建队列 let queue = new Queue() // 加入队列 queue.enqueue('a') queue.enqueue('b') queue.enqueue('c') console.log(queue) // 从队列中删除 queue.dequeue() console.log(queue) // 查看前端元素 console.log(queue.front()) // 判断是否为空 console.log(queue.isEmpty()) // 查看 size console.log(queue.size()) // 字符串形式输出 console.log(queue.toString()) 七、js 实现栈 /** 栈的思想: 先进后出,后进先出 * enStack(element):添加一个新元素到栈顶位置; * deStack():移除栈顶的元素,同时返回被移除的元素; * peek():返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它); * isEmpty():如果栈里没有任何元素就返回true,否则返回false; * size():返回栈里的元素个数。这个方法和数组的length属性类似; * toString():将栈结构的内容以字符串的形式返回。 * */ function Stack() { this.items = [] // 压栈 Stack.prototype.enStack = element => { this.items.push(element) } // 出栈 Stack.prototype.deStack = () => { return this.items.pop() } // 查看栈顶 Stack.prototype.peek = () => { return this.items[this.items.length-1] } // 判断是否为空 Stack.prototype.isEmpty = () => { return this.items.length === 0 } // 查看栈中元素个数 Stack.prototype.size = () => { return this.items.length } // 以字符串的形式输出 Stack.prototype.toString = () => { let resultString = '' for(let i of this.items) { resultString += i + ' ' } return resultString } } // 创建栈 let stack = new Stack() // 压栈 stack.enStack('a') stack.enStack('b') stack.enStack(3) console.log(stack) // 出栈 console.log(stack.deStack()) // 查看栈顶 console.log(stack.peek()) // 判断是否为空 console.log(stack.isEmpty()) // 查看栈中元素个数 console.log(stack.size()) // 以字符串的形式输出 console.log(stack.toString()) 八、js实现二叉树 // 创建节点 class Node { constructor(key, left = null, right = null) { this.key = key this.left = left this.right = right } } // 方法 class BinarySearchTree { constructor(node) { this.root = node } // 插入节点 insert(newNode, node = this.root) { if (!this.root) { this.root = newNode } else { if (newNode.key < node.key) { if (node.left === null) { node.left = newNode } else { this.insert(newNode, node.left) } } else { if (node.right === null) { node.right = newNode } else { this.insert(newNode, node.right) } } } } // 前序遍历 preOrderTraverse(curNode = this.root) { //可以从指定结点进行 if (!curNode) { return } let arr = []; const preOrderTraverseNode = node => { if (!node) { return } arr.push(node.key) preOrderTraverseNode(node.left) preOrderTraverseNode(node.right) } preOrderTraverseNode(curNode) return arr } // 中序遍历 inOrderTraverse(curNode = this.root) { if (!curNode) { return } let arr = []; const inOrderTraverseNode = node => { if (!node) { return } inOrderTraverseNode(node.left) arr.push(node.key) inOrderTraverseNode(node.right) } inOrderTraverseNode(curNode) return arr } // 后序遍历 postOrderTraverse(curNode = this.root) { if (!curNode) { return } let arr = []; const postOrderTraverseNode = node => { if (!node) { return } postOrderTraverseNode(node.left) postOrderTraverseNode(node.right) arr.push(node.key) } postOrderTraverseNode(curNode) return arr } // 最小节点 minNode(node = this.root) { if (!node.left) { return node.key } return this.minNode(node.left) } // 最大节点 maxNode(node = this.root) { if (!node.right) { return node.key } return this.maxNode(node.right) } // 查找节点 search(key,curNode = this.root) { if(!curNode) { return false } if(key === curNode.key) { return curNode } return this.search(key, key < curNode.key ? curNode.left : curNode.right) } } const tree = new BinarySearchTree(new Node(11)) tree.insert(new Node(15)) tree.insert(new Node(7)) tree.insert(new Node(5)) tree.insert(new Node(3)) tree.insert(new Node(9)) tree.insert(new Node(8)) tree.insert(new Node(10)) tree.insert(new Node(13)) tree.insert(new Node(12)) tree.insert(new Node(14)) tree.insert(new Node(20)) tree.insert(new Node(18)) tree.insert(new Node(25)) console.log(tree.preOrderTraverse()) console.log(tree.inOrderTraverse()) console.log(tree.postOrderTraverse()) console.log(tree.minNode()) console.log(tree.maxNode()) console.log(tree.search(9)) 编程题 一、实现获取所有数据类型的函数 function getType(obj) { if (obj === null) { return String(obj) } const toType = (obj) => { return Object.prototype.toString.call(obj).replace('[object ', '').replace(']', '').toLowerCase() } return typeof obj === 'object' ? toType(obj) : typeof obj } 二、实现一个滑动加载数据的防抖函数 DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> <style> img { display: block; margin-bottom: 50px; width: 400px; height: 400px; background-color: red; } style> head> <body> <div id="div"> <img src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt=""> <img src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> div> <script> function lazyload() { //监听页面滚动事件 var documentHeight = document.documentElement.offsetHeight; //文档总高度 var seeHeight = document.documentElement.clientHeight; //可见区域高度 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滚动条距离顶部高度 if (documentHeight - seeHeight - scrollTop < 30) { var imgElement = document.createElement('img'); imgElement.setAttribute('src', 'http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg'); document.querySelector('#div').appendChild(imgElement); } } // 简单的节流函数 //fun 要执行的函数 //delay 延迟 //time 在time时间内必须执行一次 function throttle(fun, delay, time) { var timeout, startTime = new Date(); return function () { var context = this, args = arguments, curTime = new Date(); clearTimeout(timeout); // 如果达到了规定的触发时间间隔,触发 handler if (curTime - startTime >= time) { fun.apply(context, args); startTime = curTime; // 没达到触发间隔,重新设定定时器 } else { timeout = setTimeout(function () { fun.apply(context, args); }, delay); } }; }; // 采用了节流函数 window.addEventListener('scroll', throttle(lazyload, 500, 1000)); script> body> html> 三、累加 // 累加 reduce addFunc = arr => { return arr.reduce((x, y) => { return x + y }, 0) } console.log(addFunc([8,5,2,1])) // 累加 eval addFunc = arr => { return eval(arr.join('+')) } console.log(addFunc([62,4,3,7])) // 累加 for循环 addFuncFor = arr => { let l = arr.length let sum = 0 for(let i = 0; i < l ; i++) { sum += arr[i] } return sum } console.log(addFuncFor([8,3,47,5])) 四、阶乘 // 阶乘 递归 mulFunc = n => { if(n ===0) { return 1 } else { return n * mulFunc(n-1) } } console.log(mulFunc(4)) // 阶乘 for循环 mulFuncFor = n => { for(let i = n-1; i > 0; i--) { n *= i } return n } console.log(mulFuncFor(5)) 五、字符串转换成数组对象 func = str => { const arr = [] const group = str.split('|') group.forEach((item, index) => { const h = item.split(',')[0] const v = item.split(',')[1] let obj = { h,v } arr.push(obj) }) return arr } console.log(func('10,100|20,200|30,300|40,400')) 总结 根据公司不同,面试的情况也会有所不同,有的公司可能偏向基础,有的公司可能偏向算法(可以到力扣上刷刷题)。 最主要还是面试时要表达清晰,不要太紧张,放平心态,关注前沿技术以及一些底层代码,因为面试官会根据你说的话而延伸话题,答题时要懂得灵活应变。 你可能感兴趣的:(面试题,面试,html,js,vue.js,前端) element实现动态路由+面包屑 软件技术NINI vue案例vue.js前端 el-breadcrumb是ElementUI组件库中的一个面包屑导航组件,它用于显示当前页面的路径,帮助用户快速理解和导航到应用的各个部分。在Vue.js项目中,如果你已经安装了ElementUI,就可以很方便地使用el-breadcrumb组件。以下是一个基本的使用示例:安装ElementUI(如果你还没有安装的话):你可以通过npm或yarn来安装ElementUI。bash复制代码npmi Long类型前后端数据不一致 igotyback 前端 响应给前端的数据浏览器控制台中response中看到的Long类型的数据是正常的到前端数据不一致前后端数据类型不匹配是一个常见问题,尤其是当后端使用Java的Long类型(64位)与前端JavaScript的Number类型(最大安全整数为2^53-1,即16位)进行数据交互时,很容易出现精度丢失的问题。这是因为JavaScript中的Number类型无法安全地表示超过16位的整数。为了解决这个问 swagger访问路径 igotyback swagger Swagger2.x版本访问地址:http://{ip}:{port}/{context-path}/swagger-ui.html{ip}是你的服务器IP地址。{port}是你的应用服务端口,通常为8080。{context-path}是你的应用上下文路径,如果应用部署在根路径下,则为空。Swagger3.x版本对于Swagger3.x版本(也称为OpenAPI3)访问地址:http://{ip html 中如何使用 uniapp 的部分方法 某公司摸鱼前端 htmluni-app前端 示例代码:Documentconsole.log(window);效果展示:好了,现在就可以uni.使用相关的方法了 C#中使用split分割字符串 互联网打工人no1 c# 1、用字符串分隔:usingSystem.Text.RegularExpressions;stringstr="aaajsbbbjsccc";string[]sArray=Regex.Split(str,"js",RegexOptions.IgnoreCase);foreach(stringiinsArray)Response.Write(i.ToString()+"");输出结果:aaabbbc 四章-32-点要素的聚合 彩云飘过 本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers5.3.xapi。源码见1032.html,对应的官网示例https://openlayers.org/en/latest/examples/cluster.htmlhttps://openlayers.org/en/latest/examples/earthquake-clusters. DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理 STU学生网页设计 网页设计期末网页作业html静态网页html5期末大作业网页设计web大作业 ️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程 【华为OD机试真题2023B卷 JAVA&JS】We Are A Team 若博豆 java算法华为javascript 华为OD2023(B卷)机试题库全覆盖,刷题指南点这里WeAreATeam时间限制:1秒|内存限制:32768K|语言限制:不限题目描述:总共有n个人在机房,每个人有一个标号(1<=标号<=n),他们分成了多个团队,需要你根据收到的m条消息判定指定的两个人是否在一个团队中,具体的:1、消息构成为:abc,整数a、b分别代 【加密社】Solidity 中的事件机制及其应用 加密社 闲侃区块链智能合约区块链 加密社引言在Solidity合约开发过程中,事件(Events)是一种非常重要的机制。它们不仅能够让开发者记录智能合约的重要状态变更,还能够让外部系统(如前端应用)监听这些状态的变化。本文将详细介绍Solidity中的事件机制以及如何利用不同的手段来触发、监听和获取这些事件。事件存储的地方当我们在Solidity合约中使用emit关键字触发事件时,该事件会被记录在区块链的交易收据中。具体而言,事件 数组去重 好奇的猫猫猫 整理自js中基础数据结构数组去重问题思考?如何去除数组中重复的项例如数组:[1,3,4,3,5]我们在做去重的时候,一开始想到的肯定是,逐个比较,外面一层循环,内层后一个与前一个一比较,如果是久不将当前这一项放进新的数组,挨个比较完之后返回一个新的去过重复的数组不好的实践方式上述方法效率极低,代码量还多,思考?有没有更好的方法这时候不禁一想当然有了!!!hashtable啊,通过对象的hash办法 关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript 二挡起步 web前端期末大作业javascripthtmlcss旅游风景 ⛵源码获取文末联系✈Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业|游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作|HTML期末大学生网页设计作业,Web大学生网页HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScrip HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动 二挡起步 web前端期末大作业web设计网页规划与设计htmlcssjavascriptdreamweaver前端 Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线 python八股文面试题分享及解析(1) Shawn________ python #1.'''a=1b=2不用中间变量交换a和b'''#1.a=1b=2a,b=b,aprint(a)print(b)结果:21#2.ll=[]foriinrange(3):ll.append({'num':i})print(11)结果:#[{'num':0},{'num':1},{'num':2}]#3.kk=[]a={'num':0}foriinrange(3):#0,12#可变类型,不仅仅改变 MYSQL面试系列-04 king01299 面试mysql面试 MYSQL面试系列-0417.关于redolog和binlog的刷盘机制、redolog、undolog作用、GTID是做什么的?innodb_flush_log_at_trx_commit及sync_binlog参数意义双117.1innodb_flush_log_at_trx_commit该变量定义了InnoDB在每次事务提交时,如何处理未刷入(flush)的重做日志信息(redolog)。它 【JS】执行时长(100分) |思路参考+代码解析(C++) l939035548 JS算法数据结构c++ 题目为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。题目输入第一个参数为GPU一次最多执行的任务个数,取值范围[1,10000]第二个参数为任务数组长度,取值范围[1,10000]第三个参数为任务数组,数字范围 Kafka 消息丢失如何处理? 架构文摘JGWZ 学习 今天给大家分享一个在面试中经常遇到的问题:Kafka消息丢失该如何处理?这个问题啊,看似简单,其实里面藏着很多“套路”。来,咱们先讲一个面试的“真实”案例。面试官问:“Kafka消息丢失如何处理?”小明一听,反问:“你是怎么发现消息丢失了?”面试官顿时一愣,沉默了片刻后,可能有点不耐烦,说道:“这个你不用管,反正现在发现消息丢失了,你就说如何处理。”小明一头雾水:“问题是都不知道怎么丢的,处理起来 每日算法&面试题,大厂特训二十八天——第二十天(树) 肥学 ⚡算法题⚡面试题每日精进java算法数据结构 目录标题导读算法特训二十八天面试题点击直接资料领取导读肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。上一期我们完成了动态规划二十一天现在我们进行下一项对各类算法进行二十八天的一个小总结。还在等什么快来一起肥学进行二十八天挑战吧!!特别介绍小白练手专栏,适合刚入手的新人欢迎订阅编程小白进阶python有趣练手项目里面包括了像《机器人尬聊》《恶搞程序》这样的有趣文章 node.js学习 小猿L node.jsnode.js学习vim node.js学习实操及笔记温故node.js,node.js学习实操过程及笔记~node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记为什么学node.js可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vuereactangular离不开node.jsnode.js是什么官网:node.js是一个开源的、跨平台的运行JavaScript的运行 【华为OD技术面试真题 - 技术面】- python八股文真题题库(4) 算法大师 华为od面试python 华为OD面试真题精选专栏:华为OD面试真题精选目录:2024华为OD面试手撕代码真题目录以及八股文真题目录文章目录华为OD面试真题精选**1.Python中的`with`**用途和功能自动资源管理示例:文件操作上下文管理协议示例代码工作流程解析优点2.\_\_new\_\_和**\_\_init\_\_**区别__new____init__区别总结3.**切片(Slicing)操作**基本切片语法 【华为OD技术面试真题 - 技术面】-测试八股文真题题库(1) 算法大师 华为od面试python算法前端 华为OD面试真题精选专栏:华为OD面试真题精选目录:2024华为OD面试手撕代码真题目录以及八股文真题目录文章目录华为OD面试真题精选1.黑盒测试和白盒测试的区别2.假设我们公司现在开发一个类似于微信的软件1.0版本,现在要你测试这个功能:打开聊天窗口,输入文本,限制字数在200字以内。问你怎么提取测试点。功能测试性能测试安全性测试可用性测试跨平台兼容性测试网络环境测试3.接口测试的工具你了解哪些 【华为OD技术面试真题精选 - 非技术题】 -HR面,综合面_华为od hr面 一个射手座的程序媛 程序员华为od面试职场和发展 最后的话最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!资料预览给大家整理的视频资料:给大家整理的电子书资料:如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化的资料的朋友,可以点击这里获 docker igotyback eureka云原生 Docker容器的文件系统是隔离的,但是可以通过挂载卷(Volumes)或绑定挂载(BindMounts)将宿主机的文件系统目录映射到容器内部。要查看Docker容器的映射路径,可以使用以下方法:查看容器配置:使用dockerinspect命令可以查看容器的详细配置信息,包括挂载的卷。例如:bashdockerinspect在输出的JSON格式中,查找"Mounts"部分,这里会列出所有的挂载信息 【华为OD技术面试真题 - 技术面】- python八股文真题题库(1) 算法大师 华为od面试python 华为OD面试真题精选专栏:华为OD面试真题精选目录:2024华为OD面试手撕代码真题目录以及八股文真题目录文章目录华为OD面试真题精选1.数据预处理流程数据预处理的主要步骤工具和库2.介绍线性回归、逻辑回归模型线性回归(LinearRegression)模型形式:关键点:逻辑回归(LogisticRegression)模型形式:关键点:参数估计与评估:3.python浅拷贝及深拷贝浅拷贝(Shal 在Ubuntu中编译含有JSON的文件出现报错 芝麻糊76 Linuxkill_buglinuxubuntujson 在ubuntu中进行JSON相关学习的时候,我发现了一些小问题,决定与大家进行分享,减少踩坑时候出现不必要的时间耗费截取部分含有JSON部分的代码进行展示char*str="{\"title\":\"JSONExample\",\"author\":{\"name\":\"JohnDoe\",\"age\":35,\"isVerified\":true},\"tags\":[\"json\",\" Xinference如何注册自定义模型 玩人工智能的辣条哥 人工智能AI大模型Xinference 环境:Xinference问题描述:Xinference如何注册自定义模型解决方案:1.写个model_config.json,内容如下{"version":1,"context_length":2048,"model_name":"custom-llama-3","model_lang":["en","ch"],"model_ability":["generate","chat"],"model Java企业面试题3 马龙强_ java 1.break和continue的作用(智*图)break:用于完全退出一个循环(如for,while)或一个switch语句。当在循环体内遇到break语句时,程序会立即跳出当前循环体,继续执行循环之后的代码。continue:用于跳过当前循环体中剩余的部分,并开始下一次循环。如果是在for循环中使用continue,则会直接进行条件判断以决定是否执行下一轮循环。2.if分支语句和switch分 Java面试题精选:消息队列(二) 芒果不是芒 Java面试题精选javakafka 一、Kafka的特性1.消息持久化:消息存储在磁盘,所以消息不会丢失2.高吞吐量:可以轻松实现单机百万级别的并发3.扩展性:扩展性强,还是动态扩展4.多客户端支持:支持多种语言(Java、C、C++、GO、)5.KafkaStreams(一个天生的流处理):在双十一或者销售大屏就会用到这种流处理。使用KafkaStreams可以快速的把销售额统计出来6.安全机制:Kafka进行生产或者消费的时候会 2019考研 | 西交大软件工程 笔者阿蓉 本科背景:某北京211学校电子信息工程互联网开发工作两年录取结果:全日制软件工程学院分数:初试350+复试笔试80+面试85+总排名:100+从五月份开始脱产学习,我主要说一下专业课和复试还有我对非全的一些看法。【数学100+】张宇,张宇,张宇。跟着张宇学习,入门视频刷一遍,真题刷两遍,错题刷三遍。书刷N多遍。从视频开始学习,是最快的学习方法。5-7月份把主要是数学学好,8-9月份开始给自己每个周 Python神器!WEB自动化测试集成工具 DrissionPage 亚丁号 python开发语言 一、前言用requests做数据采集面对要登录的网站时,要分析数据包、JS源码,构造复杂的请求,往往还要应付验证码、JS混淆、签名参数等反爬手段,门槛较高。若数据是由JS计算生成的,还须重现计算过程,体验不好,开发效率不高。使用浏览器,可以很大程度上绕过这些坑,但浏览器运行效率不高。因此,这个库设计初衷,是将它们合而为一,能够在不同须要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率 springboot+vue项目实战一-创建SpringBoot简单项目 苹果酱0567 面试题汇总与解析springboot后端java中间件开发语言 这段时间抽空给女朋友搭建一个个人博客,想着记录一下建站的过程,就当做笔记吧。虽然复制zjblog只要一个小时就可以搞定一个网站,或者用cms系统,三四个小时就可以做出一个前后台都有的网站,而且想做成啥样也都行。但是就是要从新做,自己做的意义不一样,更何况,俺就是专门干这个的,嘿嘿嘿要做一个网站,而且从零开始,首先呢就是技术选型了,经过一番思量决定选择-SpringBoot做后端,前端使用Vue做一 分享100个最新免费的高匿HTTP代理IP mcj8089 代理IP代理服务器匿名代理免费代理IP最新代理IP 推荐两个代理IP网站: 1. 全网代理IP:http://proxy.goubanjia.com/ 2. 敲代码免费IP:http://ip.qiaodm.com/ 120.198.243.130:80,中国/广东省 58.251.78.71:8088,中国/广东省 183.207.228.22:83,中国/ mysql高级特性之数据分区 annan211 java数据结构mongodb分区mysql mysql高级特性 1 以存储引擎的角度分析,分区表和物理表没有区别。是按照一定的规则将数据分别存储的逻辑设计。器底层是由多个物理字表组成。 2 分区的原理 分区表由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们可以直接访问各个分区。存储引擎管理分区的各个底层 表和管理普通表一样(所有底层表都必须使用相同的存储引擎),分区表的索引只是 JS采用正则表达式简单获取URL地址栏参数 chiangfai js地址栏参数获取 GetUrlParam:function GetUrlParam(param){ var reg = new RegExp("(^|&)"+ param +"=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if(r!=null 怎样将数据表拷贝到powerdesigner (本地数据库表) Array_06 powerDesigner ================================================== 1、打开PowerDesigner12,在菜单中按照如下方式进行操作 file->Reverse Engineer->DataBase 点击后,弹出 New Physical Data Model 的对话框 2、在General选项卡中 Model name:模板名字,自 logbackのhelloworld 飞翔的马甲 日志logback 一、概述 1.日志是啥? 当我是个逗比的时候我是这么理解的:log.debug()代替了system.out.print(); 当我项目工作时,以为是一堆得.log文件。 这两天项目发布新版本,比较轻松,决定好好地研究下日志以及logback。 传送门1:日志的作用与方法: http://www.infoq.com/cn/articles/why-and-how-log 上面的作 新浪微博爬虫模拟登陆 随意而生 新浪微博 转载自:http://hi.baidu.com/erliang20088/item/251db4b040b8ce58ba0e1235 近来由于毕设需要,重新修改了新浪微博爬虫废了不少劲,希望下边的总结能够帮助后来的同学们。 现行版的模拟登陆与以前相比,最大的改动在于cookie获取时候的模拟url的请求 synchronized 香水浓 javathread Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然 maven 简单实用教程 AdyZhang maven 1. Maven介绍 1.1. 简介 java编写的用于构建系统的自动化工具。目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本。 1.2. Maven资源 见官方网站;The 5 minute test,官方简易入门文档;Getting Started Tutorial,官方入门文档;Build Coo Android 通过 intent传值获得null aijuans android 我在通过intent 获得传递兑现过的时候报错,空指针,我是getMap方法进行传值,代码如下 1 2 3 4 5 6 7 8 9 public void getMap(View view){ Intent i = apache 做代理 报如下错误:The proxy server received an invalid response from an upstream baalwolf response 网站配置是apache+tomcat,tomcat没有报错,apache报错是: The proxy server received an invalid response from an upstream server. The proxy server could not handle the request GET /. Reason: Error reading fr Tomcat6 内存和线程配置 BigBird2012 tomcat6 1、修改启动时内存参数、并指定JVM时区 (在windows server 2008 下时间少了8个小时) 在Tomcat上运行j2ee项目代码时,经常会出现内存溢出的情况,解决办法是在系统参数中增加系统参数: window下, 在catalina.bat最前面 set JAVA_OPTS=-XX:PermSize=64M -XX:MaxPermSize=128m -Xms5 Karam与TDD bijian1013 KaramTDD 一.TDD 测试驱动开发(Test-Driven Development,TDD)是一种敏捷(AGILE)开发方法论,它把开发流程倒转了过来,在进行代码实现之前,首先保证编写测试用例,从而用测试来驱动开发(而不是把测试作为一项验证工具来使用)。 TDD的原则很简单: a.只有当某个 [Zookeeper学习笔记之七]Zookeeper源代码分析之Zookeeper.States bit1129 zookeeper public enum States { CONNECTING, //Zookeeper服务器不可用,客户端处于尝试链接状态 ASSOCIATING, //??? CONNECTED, //链接建立,可以与Zookeeper服务器正常通信 CONNECTEDREADONLY, //处于只读状态的链接状态,只读模式可以在 【Scala十四】Scala核心八:闭包 bit1129 scala Free variable A free variable of an expression is a variable that’s used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x android发送json并解析返回json ronin47 android package com.http.test; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import 一份IT实习生的总结 brotherlamp PHPphp资料php教程php培训php视频 今天突然发现在不知不觉中自己已经实习了 3 个月了,现在可能不算是真正意义上的实习吧,因为现在自己才大三,在这边撸代码的同时还要考虑到学校的功课跟期末考试。让我震惊的是,我完全想不到在这 3 个月里我到底学到了什么,这是一件多么悲催的事情啊。同时我对我应该 get 到什么新技能也很迷茫。所以今晚还是总结下把,让自己在接下来的实习生活有更加明确的方向。最后感谢工作室给我们几个人这个机会让我们提前出来 据说是2012年10月人人网校招的一道笔试题-给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 将重物放到天平左侧,问在两边如何添加砝码 bylijinnan java public class ScalesBalance { /** * 题目: * 给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 (假设N无限大,但一种重量的砝码只有一个) * 将重物放到天平左侧,问在两边如何添加砝码使两边平衡 * * 分析: * 三进制 * 我们约定括号表示里面的数是三进制,例如 47=(1202 dom4j最常用最简单的方法 chiangfai dom4j 要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip 解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要 简单HBase笔记 chenchao051 hbase 一、Client-side write buffer 客户端缓存请求 描述:可以缓存客户端的请求,以此来减少RPC的次数,但是缓存只是被存在一个ArrayList中,所以多线程访问时不安全的。 可以使用getWriteBuffer()方法来取得客户端缓存中的数据。 默认关闭。 二、Scan的Caching 描述: next( )方法请求一行就要使用一次RPC,即使 mysqldump导出时出现when doing LOCK TABLES daizj mysqlmysqdump导数据 执行 mysqldump -uxxx -pxxx -hxxx -Pxxxx database tablename > tablename.sql 导出表时,会报 mysqldump: Got error: 1044: Access denied for user 'xxx'@'xxx' to database 'xxx' when doing LOCK TABLES 解决 CSS渲染原理 dcj3sjt126com Web 从事Web前端开发的人都与CSS打交道很多,有的人也许不知道css是怎么去工作的,写出来的css浏览器是怎么样去解析的呢?当这个成为我们提高css水平的一个瓶颈时,是否应该多了解一下呢? 一、浏览器的发展与CSS 《阿甘正传》台词 dcj3sjt126com Part Ⅰ: 《阿甘正传》Forrest Gump经典中英文对白 Forrest: Hello! My names Forrest. Forrest Gump. You wanna Chocolate? I could eat about a million and a half othese. My momma always said life was like a box ochocol Java处理JSON dyy_gusi json Json在数据传输中很好用,原因是JSON 比 XML 更小、更快,更易解析。 在Java程序中,如何使用处理JSON,现在有很多工具可以处理,比较流行常用的是google的gson和alibaba的fastjson,具体使用如下: 1、读取json然后处理 class ReadJSON { public static void main(String[] args) win7下nginx和php的配置 geeksun nginx 1. 安装包准备 nginx : 从nginx.org下载nginx-1.8.0.zip php: 从php.net下载php-5.6.10-Win32-VC11-x64.zip, php是免安装文件。 RunHiddenConsole: 用于隐藏命令行窗口 2. 配置 # java用8080端口做应用服务器,nginx反向代理到这个端口即可 p 基于2.8版本redis配置文件中文解释 hongtoushizi redis 转载自: http://wangwei007.blog.51cto.com/68019/1548167 在Redis中直接启动redis-server服务时, 采用的是默认的配置文件。采用redis-server xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务。下面是Redis2.8.9的配置文 第五章 常用Lua开发库3-模板渲染 jinnianshilongnian nginxlua 动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现。而Lua中也有许多模板引擎,如目前我在使用的lua-resty-template,可以渲染很复杂的页面,借助LuaJIT其性能也是可以接受的。 如果学习过JavaEE中的servlet和JSP的话,应该知道JSP模板最终会被翻译成Servlet来执行;而lua-r JZSearch大数据搜索引擎 颠覆者 JavaScript 系统简介: 大数据的特点有四个层面:第一,数据体量巨大。从TB级别,跃升到PB级别;第二,数据类型繁多。网络日志、视频、图片、地理位置信息等等。第三,价值密度低。以视频为例,连续不间断监控过程中,可能有用的数据仅仅有一两秒。第四,处理速度快。最后这一点也是和传统的数据挖掘技术有着本质的不同。业界将其归纳为4个“V”——Volume,Variety,Value,Velocity。大数据搜索引 10招让你成为杰出的Java程序员 pda158 java编程框架 如果你是一个热衷于技术的 Java 程序员, 那么下面的 10 个要点可以让你在众多 Java 开发人员中脱颖而出。 1. 拥有扎实的基础和深刻理解 OO 原则 对于 Java 程序员,深刻理解 Object Oriented Programming(面向对象编程)这一概念是必须的。没有 OOPS 的坚实基础,就领会不了像 Java 这些面向对象编程语言 tomcat之oracle连接池配置 小网客 oracle tomcat版本7.0 配置oracle连接池方式: 修改tomcat的server.xml配置文件: <GlobalNamingResources> <Resource name="utermdatasource" auth="Container" type="javax.sql.DataSou Oracle 分页算法汇总 vipbooks oraclesql算法.net 这是我找到的一些关于Oracle分页的算法,大家那里还有没有其他好的算法没?我们大家一起分享一下! -- Oracle 分页算法一 select * from ( select page.*,rownum rn from (select * from help) page -- 20 = (currentPag 按字母分类: ABCDEFGHIJKLMNOPQRSTUVWXYZ其他
、
、 常用的内联元素有: 、、、、、、、、、、 常用的内联块状元素有: 、 知名的空元素: 二、这些浏览器的内核分别是什么? IE: trident 内核 Firefox: gecko 内核 Safari: webkit 内核 Opera: 以前是 presto 内核,Opera 现已改用 GoogleChrome 的 Blink 内核 Chrome: Blink(基于 webkit,Google 与 Opera Software 共同开发) 三、get和post区别 get是从服务器获取数据,post是向服务器传输数据 get它的安全性不高,post相对比较安全因为它通过http post机制加密过 get的数据信息可以在浏览器的地址栏(url)里面看到,post则看不到 get数据量较小,一般是2kb左右,post理论上是没有限定 get执行效率要比post高 四、BFC优化 块格式化上下文, 特性: 使 BFC 内部浮动元素不会到处乱跑; 和浮动元素产生边界。 五、块元素和行内元素的区别 块级元素:内容独占一行.块元素会在内联的方向上扩展并占据父容器在该方向上的所有可用空间. 行内元素:不会产生换行.行内元素只占放置其中内容的宽度,块元素忽视内容占据全行. 块元素中width 和 height 属性可以发挥作用.内边距(padding)外边距(margin)和边框(border)起效. 行内元素width 和 height 属性将不起作用. 行内元素垂直方向的内边距、外边距以及边框会被应用但是不会把其他处于 inline 状态的盒子推开. 行内元素水平方向的内边距、外边距以及边框会被应用且会把其他处于 inline 状态的盒子推开. CSS 一、元素垂直居中方法 方案一: 给容器设置 position:relative; 给子元素设置 position:absolute; left:0; right:0; top:0; bottom:0; margin:auto; 方案二:已知高度 给容器设置 position:relative; 给子元素设置 position:absolute; left:50%; top:50%; margin-left: -元素自身一半; margin-top: -元素自身一半; 方案三:未知高度 给容器设置 position:relative; 给子元素设置 position:absolute; left:50%; top:50%; transform:translate(-50%, -50%); 方案四:弹性布局 给容器设置 display:flex; justify-content:center; align-items:center; 二、CSS优先级(权重) 权重可以使用四位数表示: 标记选择器 0 0 0 1 class选择器 0 0 1 0 id选择器 0 1 0 0 内联样式 1 0 0 0 !important 最大 包含选择器 包含选择器权重之和 通配符 没有权重(通配符对权重没有贡献) 三、CSS层叠: 层叠在css里面表示的是规则 一个标记可以同时被多个选择器或者样式表选中,这个时候有些样式可以同时存在有些之间存在冲突问题,当遇到冲突的时候需要一条规则解决问题,这个规则就是css层叠性 四、为什么会出现浮动和什么时候需要清除浮动?清除浮动的方式 浮动元素碰到包含它的边框或者浮动元素的边框停留。由于浮动元素不在文档流中,所以文档流的块框表现得就像浮动框不存在一样。浮动元素会漂浮在文档流的块框上。 浮动带来的问题: 父元素的高度无法被撑开,影响与父元素同级的元素 与浮动元素同级的非浮动元素(内联元素)会跟随其后 若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面显示的结构。 清除浮动的方式: 空盒子方法,最后一个浮动元素后加空 div ,并添加样式 clear:both; 给容器设置overflow:hidden; 万能清除法(现在主流方法,推荐使用) .clear{ /*zoom在平时可以起到缩放效果,不过宽高不会有变化*/ zoom: 1; 兼容IE地板的浏览器的,可以触发IE浏览器的机制让其支持clear属性 } .clear::after{ content: ""; display: block; clear: both; visibility: hidden; 为了防止content里有内容 height: 0; 可以不加,不过IE低版本下有问题,不写高的时候会默认有大概18px的高 } 五、link和import区别 本质区别:link是html标记提供的一种方式,import是css提供的一种方式 加载顺序:link的方式可以让结构和样式同时加载,import是先加载结构后加载样式 兼容问题:link没有兼容问题,import一些老的版本的浏览器不支持 控制DOM区别:link可以被DOM控制,而import不能被控制 六、元素隐藏 display:none; 隐藏,理解为消失,没有位置。 visibility:hidden; 占位隐藏,元素消失,但位置还在。理解为隐身,且元素的功能不存在。 opacity:0; 隐藏,占位置的,实际上就是透明为0,让你眼睛看不见它了,但元素的功能存在。 溢出隐藏方式: overflow:hidden; 七、position 的 absolute 与 fixed 共同点与不同点: 共同点: 1.改变行内元素的呈现方式,display 被置为 block; 2.让元素脱离普通流,不占据空间; 3.默认会覆盖到非定位元素上 不同点: absolute 的”根元素“是可以设置的,而 fixed 的”根元素“固定为浏览器窗口。当你滚动网页,fixed 元素与浏览器窗口之间的距离是不变的。 八、阴影: 文字 :text-shadow:5px 5px 5px #FF0000;(水平阴影,垂直阴影,模糊距离,阴影颜色) 盒子 : box-shadow 九、一个满屏品字布局如何设计? 第一种真正的品字: 1.三块高宽是确定的; 2.上面那块用 margin: 0 auto;居中; 3.下面两块用 float 或者 inline-block 不换行; 4.用 margin 调整位置使他们居中。 第二种全屏的品字布局: 上面的 div 设置成 100%,下面的 div 分别宽 50%,然后使用 float 或者 inline 使其不换行。 十、为什么要初始化 CSS 样式 因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对 CSS 初始化往往会出现浏览器之间的页面显示差异。 十一、解释 css sprites ,如何使用? 将一个页面涉及到的所有图片都包含到一张大图中去,然后利用 CSS 的 background-image,background- repeat,background-position 的组合进行背景定位。 利用 CSS Sprites 能很好地减少网页的 http 请求,从而大大的提高页面的性能;CSS Sprites 能减少图片的字节。 十二、样式选择器有哪些 *{}:通用选择器 #X{}:ID选择器 .X{}:类选择器 X{}:元素选择器 X Y {}:后代选择器 X:hover {}:伪类选择器 :hover 移入时元素的状态 :visited 已被访问过后的元素的状态 :active 被点击时元素的状态 X + Y {}:紧邻同胞选择器 X > Y {}:子元素选择器 X ~ Y {}:后续同胞选择器 X[title]:简单属性选择器 [title=“value”] 选取含指定 value 的元素 [title^=“value”] 选取 value 以指定内容开头的元素 [title$=“value”] 选取 value 以指定内容结尾的元素 [title*=“value”] 选取 value 含指定内容的元素 具体可以点击查看详情 JS 一、JavaScript 中常见的几种数据类型,以及判断数据类型的方法 JavaScript 有 简单数据类型:Undefined、Null、Boolean、Number、String、Bigint 和 复杂数据类型 Object、Function、Array ,以及es6语法新增的Symbol数据类型 判断方法有:typeof、instanceof、constructor、Object.prototype.toString 具体可以点击查看详情 二、什么是闭包? 闭包是指有权访问另外一个函数作用域中的局部变量的函数。声明在一个函数中的函数,叫做闭包函数。而且内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变量不会被垃圾回收机制回收 三、什么是jsonp?jsonp的优缺点 jsonp是一个能够跨域的方法,由于ajax受到同源策略的影响,不能进行跨域,而script标签中的src属性中的链接能够访问跨域的js脚本,利用这个特性返回一段调用某个函数的js代码,在src中进行了调用,从而实现跨域 优点:可以跨越同源策略、可以在老版本浏览器中运行、请求完毕后可以通过callback的方式回传结果 缺点:只支持get请求、只支持跨域http请求、安全性差 四、异步操作有哪些? 回调函数 事件监听 promise ajax async setTimeout Generator 五、什么是Promise?我们用Promise来解决什么问题? Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息; 从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。 promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变化。创造promise实例后,它会立即执行。 处理问题: 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象 promise可以支持多个并发的请求,获取并发请求中的数据 这个promise可以解决异步的问题,本身不能说promise是异步的 Promise是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。 Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数: resolve :异步操作执行成功后的回调函数 reject:异步操作执行失败后的回调函数 then:传递状态的方式来使得回调函数能够及时被调用 catch:指定reject的回调,或者在执行resolve时,如果抛出异常,并不会报错卡死js,而是会进到这个catch方法中 all:谁跑的慢,以谁为准执行回调。all接收一个数组参数,里面的值最终都会返回Promise对象。提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。 race:谁跑的快,以谁为准执行回调 六、forEach、 map、 filter 的区别 forEach(): 遍历数组,调用数组的每个元素,利用回调函数对数组进行操作,本质上等同于 for 循环。 forEach 会改变原数组。没有返回值, 不支持continue 和 break return只能跳出当前循环 map() 遍历数组,调用数组的每个元素,利用回调函数对数组进行操作,与 forEach 类似。 不过map是返回一个新数组,原数组不变,新数组的索引结构和原数组一致 map需要return返回值 filter() 遍历数组,返回一个新数组(原数组的子集),回调函数用于逻辑判断 回调函数为 true 则将当前元素添加到新数组中,false 则跳过 不会改变原数组 具体可以点击查看详情 七、for···in··· 和 for···of··· 的区别 for···in···用来遍历数组和对象的键(key) for···of···用来遍历数组的值(value) for···in··是ES5里的标准 for···of···是ES6里的标准 具体可以点击查看详情 八、事件代理/事件委托 利⽤冒泡机制,将⼦元素的事件委托给⽗元素去监听(给⽗元素添加事件),当⼦元素触发事件时, 事件冒泡到⽗级如果希望指定的⼦元素才能触发事件,可以通过事件对象(event)获得事件源 (target),然后通过 条件判断是不是期望的⼦元素,如果是的话,执⾏事件,否则不执⾏ 事件委托的好处:1.实现对未来元素事件的绑定 2.减少事件绑定,提⾼性能 九、AJAX AJAX = Asynchronous JavaScript and XML. AJAX 是一种用于创建快速动态网页的技术。 AJAX 通过在后台与服务器进行少量数据交换,使网页实现异步更新。这意味着可以在不重载整个页面的情况下,对网页的某些部分进行更新。 传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个页面。 简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。 实现 原生AJAX 创建 XMLHttpRequest(xhr) 对象实例(准备手机) 建立连接,调用 xhr.open() 建立连接(查找电话号码,准备拨号) 发送数据,调用 xhr.send() (拨号) 准备处理响应数据(等待接通电话,通话) // 创建核心对象 const xhr = new XMLHttpRequest() // 建立连接 xhr.open(method, url, async) // 发送请求 // 如果为 post 需要在 send 前调用 setRequestHeader() 方法设置请求头 // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhr.send(params) // 处理响应 xhr.onreadystatechange = function() { // 当 readyState 改变时,执行该回调函数 // readyState 属性存有 XMLHttpRequest 的状态信息。 // 可以理解为请求到达哪个阶段了。 // 状态值可取 0-4 的值,4表示请求处理完毕,响应就绪 if(xhr.readyState === 4) { // status 表示的是 HTTP 状态码 // 200 表示 OK (成功) if(xhr.status === 200) { // 从响应中获取返回的数据 let data = xhr.responseText } } } // Promise 封装 ajax const myAjax = function(url) { return Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.send(params) xhr.onreadystatechange = function() { if(xhr.readyState === 4) { if(xhr.status === 200){ let data = JSON.prase(xhr.responseText) resolve(data) } else { reject('error') } } } }) } 十、关于this指向问题 随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,this永远指向的是最后调用它的对象。 this指向的形式 (4种) 如果是一般函数,this 指向全局对象 window 在严格模式 “use strict” 下,为 undefined 对象的方法里调用,this 指向调用该方法的对象 构造函数里的 this ,指向new创建出来的实例 为什么this会指向?首先new关键字会创建一个空的对象,然后会自动调用一个函数apply方法(不一定是这个方法,举例子用的),将this指向这个空对象,这样的话函数内部的this就会被这个空的对象替代。 当 this 碰到 return 如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么 this 还是指向函数的实例。 注意:虽然null也是对象,但是在这里 this 指向那个函数的实例,因为null 比较特殊。 改变this指向的方式 call:除了第一个参数以外还可以添加多个参数, b.call(a,1,2) apply:与 call 类似,但是不同的是,它第二个参数必须是一个数组, b.apply(a,[1,2]) 注意: 如果 call 和 apply 的第一个参数写的是 null,那么 this 指向的是 window 对象 bind:可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。 总结: call 和 apply 都是改变上下文中的 this 并立即执行这个函数 bind 方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加 十一、关于js类的继承 原型链继承 特点:基于原型链,既是父类的实例,也是子类的实例 缺点:无法实现多继承 构造继承 特点:可以实现多继承 缺点:只能继承父类实例的属性和方法,不能继承原型上的属性和方法 实例继承 为父类实例添加新特性,作为子类实例返回 拷贝继承 拷贝父类元素上的属性和方法 组合继承 特点:可以继承实例属性/方法,也可以继承原型属性/方法 缺点:调用了两次父类构造函数,生成了两份实例 寄生组合继承 特点:通过寄生方式,砍掉父类的实例属性,在调用两次父类的构造时,就不会初始化两次实例方法/属性 具体可以点击查看详情 十二、函数提升和变量提升 1.变量提升只会提升变量名的声明,而不会提升变量的赋值初始化。 2.函数提升的优先级大于变量提升的优先级,即函数提升在变量提升之上。 例子: var a = 10; function a(){} console.log(typeof a) A."number" B."object" C."function" D."undefined" 答案:A 代码等价于: function a(){} var a; a = 10; console.log(typeof a) 十三、原型 / 构造函数 / 实例 原型(prototype): 一个简单的对象,用于实现对象的 属性继承。可以简单的理解成对象的爹。在 Firefox 和 Chrome 中,每个 JavaScript 对象中都包含一个__proto__ (非标准)的属性指向它爹(该对象的原型),可 obj.__proto__ 进行访问。 所有引用类型都有一个__proto__(隐式原型)属性,属性值是一个普通的对象 所有函数都有一个prototype(原型)属性,属性值是一个普通的对象 所有引用类型的__proto__属性指向它构造函数的prototype 构造函数: 可以通过 new 来 新建一个对象 的函数。 实例: 通过构造函数和 new 创建出来的对象,便是实例。 实例通过__proto__ 指向原型,通过 constructor 指向构造函数 三者的关系: 实例.__proto__ === 原型 原型.constructor === 构造函数 构造函数.prototype === 原型 十四、原型链: 原型链是由原型对象组成,每个对象都有__proto__ 属性,指向了创建该对象的构造函数的原型,__proto__将对象连接起来组成了原型链。是一个用来实现继承和共享属性的有限的对象链。 当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的 __proto__ 隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的 prototype 的 __proto__ 中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。 属性查找机制: 当查找对象的属性时,如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象 Object.prototype,如还是没找到,则输出undefined; 属性修改机制: 只会修改实例对象本身的属性,如果不存在,则进行添加该属性,如果需要修改原型的属性时,则可以用: b.prototype.x = 2;但是这样会造成所有继承于该对象的实例的属性发生改变。 十五、JS 的语言特性 运行在客户端浏览器上; 不用预编译,直接解析执行代码; 是弱类型语言,较为灵活; 与操作系统无关,跨平台的语言; 脚本语言、解释性语言 十六、JS 实现跨域 跨域的原理:指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript 实施的安全限制,那么只要协议、域名、端口有任何一个不同,都被当作是不同的域。跨域原理,即是通过各种方式,避开浏览器的安全限制。 JSONP : 通 过 动 态 创 建 script , 再 请 求 一 个 带 参 网 址 实 现 跨 域 通 信 。 document.domain + iframe 跨域:两个页面都通过 js 强制设置 document.domain为基础主域,就实现了同域。 location.hash + iframe 跨域:a 欲与 b 跨域相互通信,通过中间页 c 来实现。三个页面,不同域之间利用 iframe 的 location.hash 传值,相同域之间直接 js访问来通信。 window.name + iframe 跨域:通过 iframe 的 src 属性由外域转向本地域,跨域数据即由 iframe 的window.name 从外域传递到本地域。 postMessage 跨域:可以跨域操作的 window 属性之一。 CORS:服务端设置 Access-Control-Allow-Origin 即可,前端无须设置,若要带cookie 请求,前后端都需要设置。 代理跨域:启一个代理服务器,实现数据的转发 十七、数组去重 法一:indexOf 循环去重 法二:ES6 Set 去重;Array.from(new Set(array)) 法三:Object 键值对去重;把数组的值存成 Object 的 key 值,比如 Object[value1] = true,在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的。 十八、暂停死区 在代码块内,使用 let、const 命令声明变量之前,该变量都是不可用的。在语法上,称为“暂时性死区” 十九、webpack 用来干什么的 webpack 是 一 个 现 代 JavaScript 应 用 程 序 的 静 态 模 块 打 包 器 (module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。 二十、第一秒打印 1,第二秒打印 2 // 第一个方法:用 let 块级作用域 for(let i = 0; i < 5; i++) { setTimeout(function() { console.log(i + 1) }, 1000 * i) } // 第二个方法:闭包 for(var i = 0; i < 5; i++) { (function(i) { setTimeout(function(){ console.log(i + 1) }, 1000 * i) })(i) } 二十一、简单介绍一下 symbol Symbol 是 ES6 的新增属性,代表用给定名称作为唯一标识,这种类型的值可以这样创建,let id = symbol(“id”) Symbl 确保唯一,即使采用相同的名称,也会产生不同的值,我们创建一个字段,仅为知道对应 symbol 的人能访问,使用 symbol 很有用,symbol 并不是 100%隐藏,有内置方法 Object.getOwnPropertySymbols(obj)可以获得所有的 symbol。也有一个方法 Reflect.ownKeys(obj)返回对象所有的键,包括 symbol。所以并不是真正隐藏,但大多数库内置方法和语法结构遵循通用约定他们是隐藏的。 二十二、浅谈堆和栈的理解? js变量存储有栈存储和堆存储,基本数据类型的变量存储在栈中,引⽤数据类型的变量存储在堆中,引⽤类型数据的地址也存在栈中 当访问基础类型变量时,直接从栈中取值。当访问引⽤类型变量时,先从栈中读取地址,在根据地址到堆中取出数据 二十三、箭头函数与普通函数的区别在于: 箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值,这就意味着如果箭头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的this, 箭头函数没有自己的 arguments 对象,但是可以访问外围函数的 arguments对象 不能通过 new 关键字调用,同样也没有 new.target 值和原型 二十四、简单讲一讲 ES6 的一些新特性 ES6 在变量的声明和定义方面增加了 let、const 声明变量,有局部变量的概念 赋值中有比较吸引人的结构赋值; ES6 对字符串、 数组、正则、对象、函数等拓展了一些方法,如字符串方面的模板字符串、函数方面的默认参数、对象方面属性的简洁表达方式, ES6 也 引入了新的数据类型 symbol,新的数据结构set 和 map,symbol 可以通过 typeof 检测出来 为解决异步回调问题,引入了promise 和 generator, 最为吸引人了实现 Class 和模块,通过 Class 可以更好的面向对象编程,使用模块加载方便模块化编程,当然考虑到 浏览器兼容性,我们在实际开发中需要使用 babel 进行编译 重要的特性: 块级作用域:ES5 只有全局作用域和函数作用域,块级作用域的好处是不再需要立即执行的函数表达式,循环体中的闭包不再有问题 rest 参数:用于获取函数的多余参数,这样就不需要使用 arguments 对象了, promise:一种异步编程的解决方案,比传统的解决方案回调函数和事件更合理强大 模块化:其模块功能主要有两个命令构成,export 和 import,export 命令用于规定模块的对外接口,import 命令用于输入其他模块提供的功能 二十五、call 和 apply 是用来做什么? Call 和 apply 的作用是一模一样的,只是传参的形式有区别而已 1、改变 this 的指向 2、借用别的对象的方法 3、调用函数,因为 apply,call 方法会使函数立即执行 二十六、new 操作符原理 创建一个类的实例:创建一个空对象 obj,然后把这个空对象的__proto__设置为构造函数的 prototype。 初始化实例:构造函数被传入参数并调用,关键字 this 被设定指向该实例obj。 返回实例 obj。 二十八、javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么? 除了正常模式运行外,ECMAscript 5 添加了第二种运行模式:“严格模式”。 作用: 消除 js 不合理,不严谨地方,减少怪异行为 消除代码运行的不安全之处, 提高编译器的效率,增加运行速度 为未来的 js 新版本做铺垫 二十九、对 JSON 的了解? 全称:JavaScript Object Notation JSON 中对象通过“{}”来标识,一个“{}”代表一个对象,如{“AreaId”:”123”},对象的值是键值对的形式(key:value)。JSON 是 JS 的一个严格的子集,一种轻量级的数据交换格式,类似于 xml。数据格式简单,易于读写,占用带宽小。 两个函数: JSON.parse(str) 解析 JSON 字符串 把 JSON 字符串变成 JavaScript 值或对象 JSON.stringify(obj) 将一个 JavaScript 值(对象或者数组)转换为一个 JSON 字符串 eval(‘(‘+json+’)’) 用 eval 方法注意加括号 而且这种方式更容易被攻 三十、同步和异步的区别? 同步的概念在操作系统中:不同进程协同完成某项工作而先后次序调整(通过阻塞、唤醒等方式),同步强调的是顺序性,谁先谁后。异步不存在顺序性。 同步:浏览器访问服务器,用户看到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容之后进行下一步操作。 异步:浏览器访问服务器请求,用户正常操作,浏览器在后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。 三十一、CSS 加载会造成阻塞吗? 先给出结论 CSS 不会阻塞 DOM 解析,但会阻塞 DOM 渲染。CSS 会阻塞 JS 执行,并不会阻塞 JS 文件下载 先讲一讲 CSSOM 作用: 第一个是提供给 JavaScript 操作样式表的能力; 第二个是为布局树的合成提供基础的样式信息。 这个 CSSOM 体现在 DOM 中就是 document.styleSheets。 由之前讲过的浏览器渲染流程我们可以看出: DOM 和 CSSOM 通常是并行构建的,所以「CSS 加载不会阻塞 DOM 的解析」。然而由于 Render Tree 是依赖 DOM Tree 和 CSSOM Tree 的,所以它必须等到两者都加载完毕后,完成相应的构建,才开始渲染,因此,「CSS 加载会阻塞 DOM渲染」。 由于 JavaScript 是可操纵 DOM 和 css 样式 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。因此为了防止渲染出现不可预期的结果,浏览器设置 「GUI 渲染线程与JavaScript 引擎为互斥」的关系。 有个需要注意的点就是: 「有时候 JS 需要等到 CSS 的下载,这是为什么呢?」 仔细思考一下,其实这样做是有道理的,如果脚本的内容是获取元素的样式,宽高等 CSS 控制的属性,浏览器是需要计算的,也就是依赖于 CSS。浏览器也无法感知脚本内容到底是什么,为避免样式获取,因而只好等前面所有的样式下载完后,再执行 JS。JS 文件下载和 CSS 文件下载是并行的,有时候 CSS 文件很大,所以 JS 需要等待。因此,样式表会在后面的 js 执行前先加载执行完毕,所以「css 会阻塞后面 js的执行」。 三十二、为什么 JS 会阻塞页面加载? JS 阻塞 DOM 解析,也就会阻塞页面 这也是为什么说 JS 文件放在最下面的原因,那为什么会阻塞 DOM 解析呢 你可以这样子理解: 由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。 因此为了防止渲染出现不可预期的结果,浏览器设置 「GUI 渲染线程与JavaScript 引擎为互斥」的关系。 当 JavaScript 引擎执行时 GUI 线程会被挂起,GUI 更新会被保存在一个队列中等到引擎线程空闲时立即被执行。 当浏览器在执行 JavaScript 程序的时候,GUI 渲染线程会被保存在一个队列中, 直到 JS 程序执行完成,才会接着执行。因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。 另外 ,如 果 JavaScript 文件 中没 有操 作 DOM 相关 代码 ,就 可以将 该JavaScript 脚本设置为异步加载,通过 async 或 defer 来标记代码。 三十三、JavaScript 判断对象属性是否存在(对象是否包含某个属性) 属性名 in 对象,可以检测自有属性和继承属性 hasOwnProperty() 只能检测自有属性 使用 !== undefined 检测,注意:对象属性不能为 undefined 具体可以点击查看详情 三十四、操作js数组有哪些方法? shift():删除数组的第一个元素,返回删除的值。 unshift(3,4):把一个或多个参数加载数组的前面,返回数组的长度 pop():删除数组的最后一个元素,返回删除的值。 push(3):将参数加载到数组的最后,返回数组的长度 concat([6,7,8],9,10):把两个数组拼接起来。 splice(start,deleteCount,val1,val2,…):从start位置开始删除deleteCount项,并从该位置起插入val1,val2,…,如果deleteCount为0,就表示从start位置开始添加元素。 reverse():将数组反序 sort(orderfunction):按指定的参数对数组进行排序 slice(start,end):返回从原数组中指定开始下标到结束下标之间的项组成的新数组 join():数组的每个元素以指定的字符连接形成新字符串返回; 三十五、数组求和得最快的方法 eval(arr.join(“+”)) 三十六、同步与异步 同步:同步任务是指在主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务。 异步:异步任务是指不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程。 三十七、JavaScript里面0.1+0.2 === 0.3是false 解决办法 const withinErrorMargin = (left, right) => { return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2); } console.log(withinErrorMargin(0.1 + 0.2, 0.3)) // 第二种方法 console.log(parseFloat((0.1 + 0.2).toFixed(10)) === 0.3) 三十八、js常见设计模式详解 具体可以点击查看详情 三十九、什么是作用域? 作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。 ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 的到来,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。 作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。 浏览器、服务端、网络 一、http 和 https 的区别 HTTPS = HTTP + SSL(安全套接字协议) https 有 ca 证书,http 一般没有 http 是超文本传输协议,信息是明文传输。https 则是具有安全性的 ssl 加密传输协议 http 默认 80 端口,https 默认 443 端口。 二、网络分层(OSI)里七层模型 应用层:允许访问 OSI 环境的手段 表示层:对数据进行翻译、加密和压缩 会话层:建立、管理和终止会话 传输层:提供端到端的可靠报文传递和错误恢复 网络层:负责数据包从源到宿的传递和网际互连 数据链路层:定义了如何让格式化数据以帧为单位进行传输 物理层:通过媒介传输比特, 确定机械及电气规范 三、HTTP 状态码知道哪些?分别什么意思? 1xx 表示信息, 服务器收到请求, 需要请求者继续执行操作 2xx 表示成功,处理完毕 3xx 表示需要进一步操作 4xx 表示客户端方面出错 5xx 表示服务器方面出错 2xx (3种) 200 OK:表示从客户端发送给服务器的请求被正常处理并返回; 204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回); 206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。 3xx (5种) 301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL; 302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL; 301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL) 303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源; 302与303的区别:后者明确表示客户端应当采用GET方式获取资源 304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码; 307 Temporary Redirect:临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况); 4xx (4种) 400 Bad Request:表示请求报文中存在语法错误; 401 Unauthorized:未经许可,需要通过HTTP认证; 403 Forbidden:服务器拒绝该次访问(访问权限出现问题) 404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用; 5xx (2种) 500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时; 503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求; 四、请描述⼀下 cookies,sessionStorage 和 localStorage 的区别? 共同点:都是保存在浏览器端,并且是同源的 cookie 可以在浏览器和服务器间来回传递,存储容量小,只有大约4K左右。 作用:1、保存用户登录状态;2、跟踪用户行为。 localStorage ⻓期存储数据,浏览器关闭后数据不会丢失; sessionStorage 数据在浏览器关闭后⾃动删除。 sessionStorage和localStorage优势:存储空间更⼤、有更多丰富易⽤的接⼝、各⾃独⽴的存储空间 五、在浏览器地址栏输⼊ www.baidu.com 后按下回车键会发生什么 DNS域名解析系统 ,把域名解析ip地址 把ip发送到⽹络供应商,进行TCP的三次握⼿ 建⽴连接 开始发送请求 取回⼊⼝⽂件index.html 开始解析⼊⼝⽂件,并且取回需要的资源sources 进入地址前端模块 六、一个页面从输入 URL 到页面加载显示完成,这个过程都发生了什么: 分为 4 个步骤: (1)浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP,向服务器发起请求; (2)浏览器与远程 Web 服务器通过 TCP 三次握手协商来建立一个 TCP/IP 连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。 (3)一旦 TCP/IP 连接建立,浏览器会通过该连接向远程服务器发送 HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源,值为 200 的 HTTP 响应状态表示一个正确的响应。 (4)此时,Web 服务器提供资源服务,客户端开始下载资源。请求返回后,载入解析到的资源文件,渲染页面,便进入了我们关注的前端模块 简述版: DNS解析 TCP连接 发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束 七、token 的含义: Token 的引入:Token 是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。 Token 的定义:Token 是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此 Token 返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。 使用 Token 的目的:Token 的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。 具体可以点击查看详情 八、重绘与回流 当元素的样式发生变化时,浏览器需要触发更新,重新绘制元素。这个过程中,有两种类型的操作,即重绘与回流。 重绘(repaint): 当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此 损耗较少 回流(reflow): 当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。会触发回流的操作: 页面初次渲染 浏览器窗口大小改变 元素尺寸、位置、内容发生改变 元素字体大小变化 添加或者删除可见的 dom 元素 激活 CSS 伪类(例如::hover) 查询某些属性或调用某些方法: clientWidth、clientHeight、clientTop、clientLeft offsetWidth、offsetHeight、offsetTop、offsetLeft scrollWidth、scrollHeight、scrollTop、scrollLeft getComputedStyle() getBoundingClientRect() scrollTo() 回流必定触发重绘,重绘不一定触发回流。重绘的开销较小,回流的代价较高。 最佳实践: css: 避免使用 table 布局 将动画效果应用到 position 属性为 absolute 或 fixed 的元素上 javascript 避免频繁操作样式,可汇总后统一 一次修改 尽量使用 class 进行样式修改 减少 dom 的增删次数,可使用 字符串 或者 documentFragment 一次性插入 极限优化时,修改样式可将其 display: none 后修改 避免多次触发上面提到的那些会触发回流的方法,可以的话尽量用 变量存贮 九、浏览器如何阻止事件传播,阻止默认行为 阻止事件传播(冒泡): e.stopPropagation() 阻止默认行为: e.preventDefault() 十、浏览器事件机制中事件触发三个阶段 事件捕获阶段: 从 dom 树节点往下找到目标节点, 不会触发函数 事件目标处理函数: 到达目标节点 事件冒泡: 最后从目标节点往顶层元素传递, 通常函数在此阶段执行. addEventListener 第三个参数默认false(冒泡阶段执行), true(捕获阶段执行). 十一、什么是跨域?为什么浏览器要使用同源策略?你有几种方式可以解决跨域问题?了解预检请求嘛? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源 防止 XSS、CSFR 等攻击, 协议+域名+端口不同 jsonp; 跨域资源共享(CORS); (Access control); 服务器正向代理等 预检请求: 需预检的请求要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。 十二、进程和线程的区别 进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。 线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。 一个程序至少一个进程,一个进程至少一个线程。 十三、浏览器内核 浏览器内核可以分成两部分: 渲染引擎(layout engineer 或者 Rendering Engine)和 JS 引擎。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。 渲染引擎: 负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入 CSS 等),以及计算网页的显示方式,然后会输出至显示器或打印机。 JS 引擎 解析 Javascript 语言,执行 javascript 语言来实现网页的动态效果。最开始渲染引擎和 JS 引擎并没有区分的很明确,后来 JS 引擎越来越独立,内核就倾向于只指渲染引擎。 十四、描述浏览器渲染过程 DOM Tree 和 CSS RULE Tree 将 html 和 css 解析成树形数据结构,然后 Dom 和 css 合并后生成Render Tree,用 layout 来确定节点的位置以及关系,通过 painting 按照规则来画到屏幕上,由 display 搭建最终看到效果。 十五、什么是 XXS 攻击 Cross-site script,跨站脚本攻击,当其它用户浏览该网站时候,该段 HTML 代码会自动执行,从而达到攻击的目的,如盗取用户的 Cookie,破坏页面结构,重定向到其它网站等。 XSS 类型: 一般可以分为: 持久型 XSS 和非持久性 XSS 持久型 XSS: 就是对客户端攻击的脚本植入到服务器上,从而导致每个正常访问到的用户都会遭到这段 XSS 脚本的攻击。 非持久型 XSS: 是对一个页面的 URL 中的某个参数做文章,把精心构造好的恶意脚本包装在 URL 参数重,再将这个 URL 发布到网上,骗取用户访问,从而进行攻击。 十六、CSRF 攻击 CSRF(Cross-site request forgery), 中文名称:跨站请求伪造 CSRF 可以简单理解为:攻击者盗用了你的身份,以你的名义发送恶意请求,容易造成个人隐私泄露以及财产安全。 防范: post 请求 使用 token 验证码 十七、DDOS 攻击 利用目标系统网络服务功能缺陷或者直接消耗其系统资源,使得该目标系统无法提供正常的服务。 DDoS 攻击通过大量合法的请求占用大量网络资源,以达到瘫痪网络的目的。 具体有几种形式: 通过使网络过载来干扰甚至阻断正常的网络通讯; 通过向服务器提交大量请求,使服务器超负荷; 通过阻断某一用户访问服务器; 通过阻断某服务与特定系统或个人的通讯。 十八、URL 和 URI 有什么区别 URI 是统一资源标识符,相当于一个人身份证号码 Web 上可用的每种资源如 HTML 文档、图像、视频片段、程序等都是一个来 URI来定位的 URI 一般由三部组成 ①访问资源的命名机制 ②存放资源的主机名 ③资源自身的名称,由路径表示,着重强调于资源。 URL 是统一资源定位符,相当于一个人的家庭住址 URL 是 Internet 上用来描述信息资源的字符串,主要用在各种 WWW 客户程序和服务器程序上,特别是著名的 Mosaic。采用 URL 可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。 URL 一般由三部组成 ①协议(或称为服务方式) ②存有该资源的主机 IP 地址(有时也包括端口号) ③主机资源的具体地址。如目录和文件名等。 十九、TCP 三次握手 SYN表示建立连接,ACK表示响应 建立连接前,客户端和服务端需要通过握手来确认对方: 客户端发送 syn(同步序列编号) 请求,进入 syn_send 状态,等待确认 服务端接收并确认 syn 包后发送 syn+ack 包,进入 syn_recv 状态 客户端接收 syn+ack 包后,发送 ack 包,双方进入 established 状态 二十、TCP 四次挥手 SYN表示建立连接,FIN表示关闭连接,ACK表示响应 客户端 – FIN --> 服务端, FIN—WAIT 服务端 – ACK --> 客户端, CLOSE-WAIT 服务端 – ACK,FIN --> 客户端, LAST-ACK 客户端 – ACK 二十一、http协议中数据请求的方法 get::从服务器获取数据 post:向服务器传输数据 put:上传指定的 URL delete:删除指定资源 options:返回服务器支持的 http 方法 head:与 get 类似,但只能获取 http 报头 connect:将请求连接转换到透明的 tcp/ip 通道 二十二、DNS解析 浏览器缓存 操作系统缓存 本地域名服务器 根域名服务器请求解析 顶级域名服务器 VUE 一、v-if vs v-show v-if 是真正的条件渲染,通过节点的销毁、重建来实现 v-if 是惰性的,即初始条件为 false 时,什么也不做,直到条件第一次为 true 才开始渲染 v-show 总会被渲染,只是简单的基于 CSS 来实现样式切换 v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。 总结: v-if 按照条件是否渲染,v-show 是 display 的 block 或 none 二、v-if 与 v-for 一起使用 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。(注意这里是 2.x 的版本,3.x 反之) 不推荐同时使用 v-if 和 v-for。 三、计算属性(computed) VS 方法 计算属性的值会被缓存,计算属性是基于它们的响应式依赖进行缓存的,当依赖项改变时,才重新计算计算属性的值并继续缓存。 方法不会缓存,每调用一次方法,都会重新执行一次方法主体代码块 四、计算属性 VS 侦听器 计算属性的值会被缓存。 侦听器不能被缓存。 通常计算属性是根据一个或多个已有数据,返回一个新的值,侦听器是监听一个数据的变化,可能由一个数据的变化导致其它一个或多个数据的变化,或导致其它一些副作用 五、vue.js 的两个核心是什么? 答:数据驱动、组件系统 六、vue 常用的修饰符? .prevent: 提交事件不再重载页面; .stop: 阻止单击事件冒泡; .self: 当事件发生在该元素本身而不是子元素的时候会触发; .capture: 事件侦听,事件发生的时候会调用 七、vue 中 key 值的作用? 答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟DOM。 八、Vue 组件间的参数传递 父组件与子组件传值: 父组件传给子组件:子组件通过 props 方法接受数据; 子组件传给父组件:$emit 方法传递参数 非父子组件间的数据传递,兄弟组件传值: eventBus,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。项目比较小时,用这个比较合适。(虽然也有不少人推荐直接用 VUEX,具体来说看需求咯。技术只是手段,目的达到才是王道。) 详情可以看看这个 九、Vue.js 双向绑定的原理 Vue.js 2.0 采用数据劫持(Proxy 模式)结合发布者-订阅者模式(PubSub 模式)的方式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。 1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数 3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图 十、Vue中如何监控某个属性值的变化? 例如现在需要监控data中, obj.a 的变化。Vue中监控对象属性的变化你可以这样: watch: { 'obj.a': { handler (newName, oldName) { console.log('obj.a changed') } } } 另一种方法,利用计算属性(computed) 的特性来实现,当依赖改变时,便会重新计算一个新值。 computed: { a1 () { return this.obj.a } } 十一、虚拟DOM,diff算法 让我们不用直接操作DOM元素,只操作数据便可以重新渲染页面 虚拟dom是为了解决浏览器性能问题而被设计出来的 当操作数据时,将改变的dom元素缓存起来,都计算完后再通过比较映射到真实的dom树上 diff算法比较新旧虚拟dom。如果节点类型相同,则比较数据,修改数据; 如果节点不同,直接干掉节点及所有子节点,插入新的节点; 如果给每个节点都设置了唯一的key,就可以准确的找到需要改变的内容,否则就会出现修改一个地方导致其他地方都改变的情况。例如A-B-C-D, 我要插入新节点A-B-M-C-D,实际上改变了C和D。但是设置了key,就可以准确的找到B C并插入 总结:虚拟dom可以很好的跟踪当前dom状态,因为他会根据当前数据生成一个描述当前dom结构的虚拟dom,然后数据发生变化时,又会生成一个新的虚拟dom,而这两个虚拟dom恰恰保存了变化前后的状态。然后通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些)。可以很明显的提升渲染效率以及用户体验 十二、v-model 是如何实现的,语法糖实际是什么 作用在表单元素上 v-model = "message" 等同于 v-bind:value = "message" v-on:input = "message=event.target.value" 作用在组件上,本质是一个父子组件通信的语法糖,通过 prop 和 .emit 实现, 等同于:value = "message" @input = "$emit('input', $event.target.value)" 十三、data为什么是一个函数而不是对象 JS中的对象是引用类型的数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。 而在Vue中,我们更多的是想要复用组件,那就需要每个组件都有自己的数据,这样组件之间才不会相互干扰。 所以组件的数据不能写成对象的形式,而是要写成函数的形式。数据以函数返回值的形式定义,这样当我们每次复用组件的时候,就会返回一个新的data,也就是说每个组件都有自己的私有数据空间,它们各自维护自己的数据,不会干扰其他组件的正常运行。 十四、vue 生命周期 介绍:每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。 beforecreate (初始化界面前) created (初始化界面后) beforemount (渲染界面前) mounted (渲染界面后) beforeUpdate (更新数据前) updated (更新数据后) beforedestory (卸载组件前) destroyed (卸载组件后) 十五、keep-alive < keep-alive >是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。 < keep-alive > 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 生命周期钩子:actived:激活调用; deactived:停用时调用 属性:include:名称(正则 or 字符串)匹配时调用; exclude:名称不匹配时调用; max:最多缓存数量 十六、Vuex是什么?怎么使用? Vuex是实现组件全局状态(数据)管理的一种机制,可以方便实现组件数据之间的共享; Vuex集中管理共享的数据,易于开发和后期维护; 能够高效的实现组件之间的数据共享,提高开发效率; 存储在 Vuex 的数据是响应式的,能够实时保持页面和数据的同步; Vuex重要核心属性包括:state, mutations, action, getters, modules. state Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。 mutations mutations定义的方法动态修改Vuex 的 store 中的状态或数据。 action actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。 getters 类似vue的计算属性,主要用来过滤一些数据。 modules 项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。 十七、axios 是什么,其特点和常用语法是什么? Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,react/vue 官方都推荐使用 axios 发 ajax 请求 特点: 基于 promise 的异步 ajax 请求库,支持promise所有的API 浏览器端/node 端都可以使用,浏览器中创建XMLHttpRequests 支持请求/响应拦截器 支持请求取消 可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据 批量发送多个请求 安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略。 常用语法: axios(config): 通用/最本质的发任意类型请求的方式 axios(url[, config]): 可以只指定 url 发 get 请求 axios.request(config): 等同于 axios(config) axios.get(url[, config]): 发 get 请求 axios.delete(url[, config]): 发 delete 请求 axios.post(url[, data, config]): 发 post 请求 axios.put(url[, data, config]): 发 put 请求 axios.defaults.xxx: 请求的默认全局配置 axios.interceptors.request.use(): 添加请求拦截器 axios.interceptors.response.use(): 添加响应拦截器 axios.create([config]): 创建一个新的 axios(它没有下面的功能) axios.Cancel(): 用于创建取消请求的错误对象 axios.CancelToken(): 用于创建取消请求的 token 对象 axios.isCancel(): 是否是一个取消请求的错误 axios.all(promises): 用于批量执行多个异步请求 axios.spread(): 用来指定接收所有成功数据的回调函数的方法 十八、路由传值的方式有哪几种 1 动态路由传值。例如:path:“/home/:id/name”; 接受的时候通过 this.$route.params 2 query 传值。因为在 url 中 ?后面的参数不会被解析,因此我们可以通过 query 进行传值。接受的时候通过 this.$route.query 3 路由解耦。在配置路由的时候添加 props 属性为 true,在需要接受参数的组件页面通过 props 进行接受 4 编程式导航 this.$router.push({path:"/home",query:{}}); 十九、 $route 和 $router 的区别 $route 是 “路由信息对象”,包括 path,params,hash,query,fullPath, matched,name 等路由信息参数。 $router 是“路由实例”对象包括了路由的跳转方法,钩子函数等。 二十、怎么定义 vue-router 的动态路由?怎么获取传过来的值? 动态路由的创建,主要是使用 path 属性过程中,使用动态路径参数,以冒号开头,如下: { path: '/details/:id' name: 'Details' components: Details } 访问 details 目录下的所有文件,如果 details/a,details/b 等,都会映射到 Details 组件上。当匹配到 /details 下的路由时,参数值会被设置到 this.$route.params 下,所以通过这个属性可以获取动态参数 this.$route.params.id 二十一、vue-router 有哪几种路由守卫? 路由守卫为: 全局守卫:beforeEach 后置守卫:afterEach 全局解析守卫:beforeResolve 路由独享守卫:beforeEnter 二十二、MVC和MVVM的区别 MVC表示“模型-视图-控制器”,MVVM表示“模型-视图-视图模型”; MVVM是由MVC衍生出来的。MVC中,View会直接从Model中读取数据; MVVM各部分的通信是双向的,而MVC各部分通信是单向的; MVVM是真正将页面与数据逻辑分离放到js里去实现,而MVC里面未分离。 具体可以点击查看详情 算法 一、冒泡排序 bubbleSort = arr => { for (let i = 0, l = arr.length; i < l - 1; i++) { for (let j = 0; j < l - 1 - i; j++) { if(arr[j] > arr[j+1]) { let temp = arr[j+1] arr[j+1] = arr[j] arr[j] = temp } } } return arr } console.log('结果:', bubbleSort([5,3,2,4,8])) 二、选择排序 selectSort = arr => { for (let i = 0,l = arr.length; i < l - 1; i++) { for (let j = i+1; j < l; j++) { if(arr[i] > arr[j]) { let temp = arr[i] arr[i] = arr[j] arr[j] = temp } } } return arr } console.log('结果:', selectSort([5,3,2,4])) 三、插入排序 insertSort = arr => { let l = arr.length for(let i = 1; i < l; i++){ let temp = arr[i] let j = i - 1 for(; j >= 0 && arr[j] > temp; j--) { arr[j+1] = arr[j] } arr[j+1] = temp } return arr } console.log(insertSort([3,44,58,2,9,1])) 四、快速排序 quickSort = arr => { let l = arr.length let leftArr = [] let rightArr = [] let a = arr[0] if( l <= 1) { return arr } for(let i = 1; i < l; i++) { if(arr[i] > a) { rightArr.push(arr[i]); } else{ leftArr.push(arr[i]); } } return [].concat(quickSort(leftArr),[a],quickSort(rightArr)) } console.log('结果:', quickSort([5,1,6,7])) 五、全排列 func = arr => { let len = arr.length let res = [] // 所有排列结果 /** * 【全排列算法】 * 说明:arrange用来对arr中的元素进行排列组合,将排列好的各个结果存在新数组中 * @param tempArr:排列好的元素 * @param leftArr:待排列元素 */ let arrange = (tempArr, leftArr) => { if (tempArr.length === len) { // 这里就是递归结束的地方 res.push(tempArr.join('')) // 得到全排列的每个元素都是字符串 } else { leftArr.forEach((item, index) => { let temp = [].concat(leftArr) temp.splice(index, 1) // 此时,第一个参数是当前分离出的元素所在数组;第二个参数temp是传入的leftArr去掉第一个后的结果 arrange(tempArr.concat(item), temp) // 这里使用了递归 }) } } arrange([], arr) return res } console.log('结果:', func(['A', 'B', 'C', 'D'])) 六、js 实现队列 /** 队列思想(FIFO) 先进先出 * enqueue(element):向队列尾部添加一个(或多个)新的项; * dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素; * front():返回队列中的第一个元素——最先被添加,也将是最先被移除的元素。 队列不做任何变动(不移除元素,只返回元素信息与Stack类的peek方法非常类似); * isEmpty():如果队列中不包含任何元素,返回true,否则返回false; * size():返回队列包含的元素个数,与数组的length属性类似; * toString():将队列中的内容,转成字符串形式 */ function Queue() { this.items = [] // enqueue():将元素加入到队列中 Queue.prototype.enqueue = element => { this.items.push(element) } // dequeue():从队列中删除前端元素 Queue.prototype.dequeue = () => { return this.items.shift() } // front():查看前端的元素 Queue.prototype.front = () => { return this.items[0] } // isEmpty:查看队列是否为空 Queue.prototype.isEmpty = () => { return this.items.length === 0 } // size():查看队列中元素的个数 Queue.prototype.size = () => { return this.items.length } // toString():将队列中元素以字符串形式输出 Queue.prototype.toString = () => { let resultString = '' for (let i of this.items){ resultString += i + ' ' } return resultString } } // 创建队列 let queue = new Queue() // 加入队列 queue.enqueue('a') queue.enqueue('b') queue.enqueue('c') console.log(queue) // 从队列中删除 queue.dequeue() console.log(queue) // 查看前端元素 console.log(queue.front()) // 判断是否为空 console.log(queue.isEmpty()) // 查看 size console.log(queue.size()) // 字符串形式输出 console.log(queue.toString()) 七、js 实现栈 /** 栈的思想: 先进后出,后进先出 * enStack(element):添加一个新元素到栈顶位置; * deStack():移除栈顶的元素,同时返回被移除的元素; * peek():返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它); * isEmpty():如果栈里没有任何元素就返回true,否则返回false; * size():返回栈里的元素个数。这个方法和数组的length属性类似; * toString():将栈结构的内容以字符串的形式返回。 * */ function Stack() { this.items = [] // 压栈 Stack.prototype.enStack = element => { this.items.push(element) } // 出栈 Stack.prototype.deStack = () => { return this.items.pop() } // 查看栈顶 Stack.prototype.peek = () => { return this.items[this.items.length-1] } // 判断是否为空 Stack.prototype.isEmpty = () => { return this.items.length === 0 } // 查看栈中元素个数 Stack.prototype.size = () => { return this.items.length } // 以字符串的形式输出 Stack.prototype.toString = () => { let resultString = '' for(let i of this.items) { resultString += i + ' ' } return resultString } } // 创建栈 let stack = new Stack() // 压栈 stack.enStack('a') stack.enStack('b') stack.enStack(3) console.log(stack) // 出栈 console.log(stack.deStack()) // 查看栈顶 console.log(stack.peek()) // 判断是否为空 console.log(stack.isEmpty()) // 查看栈中元素个数 console.log(stack.size()) // 以字符串的形式输出 console.log(stack.toString()) 八、js实现二叉树 // 创建节点 class Node { constructor(key, left = null, right = null) { this.key = key this.left = left this.right = right } } // 方法 class BinarySearchTree { constructor(node) { this.root = node } // 插入节点 insert(newNode, node = this.root) { if (!this.root) { this.root = newNode } else { if (newNode.key < node.key) { if (node.left === null) { node.left = newNode } else { this.insert(newNode, node.left) } } else { if (node.right === null) { node.right = newNode } else { this.insert(newNode, node.right) } } } } // 前序遍历 preOrderTraverse(curNode = this.root) { //可以从指定结点进行 if (!curNode) { return } let arr = []; const preOrderTraverseNode = node => { if (!node) { return } arr.push(node.key) preOrderTraverseNode(node.left) preOrderTraverseNode(node.right) } preOrderTraverseNode(curNode) return arr } // 中序遍历 inOrderTraverse(curNode = this.root) { if (!curNode) { return } let arr = []; const inOrderTraverseNode = node => { if (!node) { return } inOrderTraverseNode(node.left) arr.push(node.key) inOrderTraverseNode(node.right) } inOrderTraverseNode(curNode) return arr } // 后序遍历 postOrderTraverse(curNode = this.root) { if (!curNode) { return } let arr = []; const postOrderTraverseNode = node => { if (!node) { return } postOrderTraverseNode(node.left) postOrderTraverseNode(node.right) arr.push(node.key) } postOrderTraverseNode(curNode) return arr } // 最小节点 minNode(node = this.root) { if (!node.left) { return node.key } return this.minNode(node.left) } // 最大节点 maxNode(node = this.root) { if (!node.right) { return node.key } return this.maxNode(node.right) } // 查找节点 search(key,curNode = this.root) { if(!curNode) { return false } if(key === curNode.key) { return curNode } return this.search(key, key < curNode.key ? curNode.left : curNode.right) } } const tree = new BinarySearchTree(new Node(11)) tree.insert(new Node(15)) tree.insert(new Node(7)) tree.insert(new Node(5)) tree.insert(new Node(3)) tree.insert(new Node(9)) tree.insert(new Node(8)) tree.insert(new Node(10)) tree.insert(new Node(13)) tree.insert(new Node(12)) tree.insert(new Node(14)) tree.insert(new Node(20)) tree.insert(new Node(18)) tree.insert(new Node(25)) console.log(tree.preOrderTraverse()) console.log(tree.inOrderTraverse()) console.log(tree.postOrderTraverse()) console.log(tree.minNode()) console.log(tree.maxNode()) console.log(tree.search(9)) 编程题 一、实现获取所有数据类型的函数 function getType(obj) { if (obj === null) { return String(obj) } const toType = (obj) => { return Object.prototype.toString.call(obj).replace('[object ', '').replace(']', '').toLowerCase() } return typeof obj === 'object' ? toType(obj) : typeof obj } 二、实现一个滑动加载数据的防抖函数 DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> <style> img { display: block; margin-bottom: 50px; width: 400px; height: 400px; background-color: red; } style> head> <body> <div id="div"> <img src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt=""> <img src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> div> <script> function lazyload() { //监听页面滚动事件 var documentHeight = document.documentElement.offsetHeight; //文档总高度 var seeHeight = document.documentElement.clientHeight; //可见区域高度 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滚动条距离顶部高度 if (documentHeight - seeHeight - scrollTop < 30) { var imgElement = document.createElement('img'); imgElement.setAttribute('src', 'http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg'); document.querySelector('#div').appendChild(imgElement); } } // 简单的节流函数 //fun 要执行的函数 //delay 延迟 //time 在time时间内必须执行一次 function throttle(fun, delay, time) { var timeout, startTime = new Date(); return function () { var context = this, args = arguments, curTime = new Date(); clearTimeout(timeout); // 如果达到了规定的触发时间间隔,触发 handler if (curTime - startTime >= time) { fun.apply(context, args); startTime = curTime; // 没达到触发间隔,重新设定定时器 } else { timeout = setTimeout(function () { fun.apply(context, args); }, delay); } }; }; // 采用了节流函数 window.addEventListener('scroll', throttle(lazyload, 500, 1000)); script> body> html> 三、累加 // 累加 reduce addFunc = arr => { return arr.reduce((x, y) => { return x + y }, 0) } console.log(addFunc([8,5,2,1])) // 累加 eval addFunc = arr => { return eval(arr.join('+')) } console.log(addFunc([62,4,3,7])) // 累加 for循环 addFuncFor = arr => { let l = arr.length let sum = 0 for(let i = 0; i < l ; i++) { sum += arr[i] } return sum } console.log(addFuncFor([8,3,47,5])) 四、阶乘 // 阶乘 递归 mulFunc = n => { if(n ===0) { return 1 } else { return n * mulFunc(n-1) } } console.log(mulFunc(4)) // 阶乘 for循环 mulFuncFor = n => { for(let i = n-1; i > 0; i--) { n *= i } return n } console.log(mulFuncFor(5)) 五、字符串转换成数组对象 func = str => { const arr = [] const group = str.split('|') group.forEach((item, index) => { const h = item.split(',')[0] const v = item.split(',')[1] let obj = { h,v } arr.push(obj) }) return arr } console.log(func('10,100|20,200|30,300|40,400')) 总结 根据公司不同,面试的情况也会有所不同,有的公司可能偏向基础,有的公司可能偏向算法(可以到力扣上刷刷题)。 最主要还是面试时要表达清晰,不要太紧张,放平心态,关注前沿技术以及一些底层代码,因为面试官会根据你说的话而延伸话题,答题时要懂得灵活应变。 你可能感兴趣的:(面试题,面试,html,js,vue.js,前端) element实现动态路由+面包屑 软件技术NINI vue案例vue.js前端 el-breadcrumb是ElementUI组件库中的一个面包屑导航组件,它用于显示当前页面的路径,帮助用户快速理解和导航到应用的各个部分。在Vue.js项目中,如果你已经安装了ElementUI,就可以很方便地使用el-breadcrumb组件。以下是一个基本的使用示例:安装ElementUI(如果你还没有安装的话):你可以通过npm或yarn来安装ElementUI。bash复制代码npmi Long类型前后端数据不一致 igotyback 前端 响应给前端的数据浏览器控制台中response中看到的Long类型的数据是正常的到前端数据不一致前后端数据类型不匹配是一个常见问题,尤其是当后端使用Java的Long类型(64位)与前端JavaScript的Number类型(最大安全整数为2^53-1,即16位)进行数据交互时,很容易出现精度丢失的问题。这是因为JavaScript中的Number类型无法安全地表示超过16位的整数。为了解决这个问 swagger访问路径 igotyback swagger Swagger2.x版本访问地址:http://{ip}:{port}/{context-path}/swagger-ui.html{ip}是你的服务器IP地址。{port}是你的应用服务端口,通常为8080。{context-path}是你的应用上下文路径,如果应用部署在根路径下,则为空。Swagger3.x版本对于Swagger3.x版本(也称为OpenAPI3)访问地址:http://{ip html 中如何使用 uniapp 的部分方法 某公司摸鱼前端 htmluni-app前端 示例代码:Documentconsole.log(window);效果展示:好了,现在就可以uni.使用相关的方法了 C#中使用split分割字符串 互联网打工人no1 c# 1、用字符串分隔:usingSystem.Text.RegularExpressions;stringstr="aaajsbbbjsccc";string[]sArray=Regex.Split(str,"js",RegexOptions.IgnoreCase);foreach(stringiinsArray)Response.Write(i.ToString()+"");输出结果:aaabbbc 四章-32-点要素的聚合 彩云飘过 本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers5.3.xapi。源码见1032.html,对应的官网示例https://openlayers.org/en/latest/examples/cluster.htmlhttps://openlayers.org/en/latest/examples/earthquake-clusters. DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理 STU学生网页设计 网页设计期末网页作业html静态网页html5期末大作业网页设计web大作业 ️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程 【华为OD机试真题2023B卷 JAVA&JS】We Are A Team 若博豆 java算法华为javascript 华为OD2023(B卷)机试题库全覆盖,刷题指南点这里WeAreATeam时间限制:1秒|内存限制:32768K|语言限制:不限题目描述:总共有n个人在机房,每个人有一个标号(1<=标号<=n),他们分成了多个团队,需要你根据收到的m条消息判定指定的两个人是否在一个团队中,具体的:1、消息构成为:abc,整数a、b分别代 【加密社】Solidity 中的事件机制及其应用 加密社 闲侃区块链智能合约区块链 加密社引言在Solidity合约开发过程中,事件(Events)是一种非常重要的机制。它们不仅能够让开发者记录智能合约的重要状态变更,还能够让外部系统(如前端应用)监听这些状态的变化。本文将详细介绍Solidity中的事件机制以及如何利用不同的手段来触发、监听和获取这些事件。事件存储的地方当我们在Solidity合约中使用emit关键字触发事件时,该事件会被记录在区块链的交易收据中。具体而言,事件 数组去重 好奇的猫猫猫 整理自js中基础数据结构数组去重问题思考?如何去除数组中重复的项例如数组:[1,3,4,3,5]我们在做去重的时候,一开始想到的肯定是,逐个比较,外面一层循环,内层后一个与前一个一比较,如果是久不将当前这一项放进新的数组,挨个比较完之后返回一个新的去过重复的数组不好的实践方式上述方法效率极低,代码量还多,思考?有没有更好的方法这时候不禁一想当然有了!!!hashtable啊,通过对象的hash办法 关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript 二挡起步 web前端期末大作业javascripthtmlcss旅游风景 ⛵源码获取文末联系✈Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业|游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作|HTML期末大学生网页设计作业,Web大学生网页HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScrip HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动 二挡起步 web前端期末大作业web设计网页规划与设计htmlcssjavascriptdreamweaver前端 Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线 python八股文面试题分享及解析(1) Shawn________ python #1.'''a=1b=2不用中间变量交换a和b'''#1.a=1b=2a,b=b,aprint(a)print(b)结果:21#2.ll=[]foriinrange(3):ll.append({'num':i})print(11)结果:#[{'num':0},{'num':1},{'num':2}]#3.kk=[]a={'num':0}foriinrange(3):#0,12#可变类型,不仅仅改变 MYSQL面试系列-04 king01299 面试mysql面试 MYSQL面试系列-0417.关于redolog和binlog的刷盘机制、redolog、undolog作用、GTID是做什么的?innodb_flush_log_at_trx_commit及sync_binlog参数意义双117.1innodb_flush_log_at_trx_commit该变量定义了InnoDB在每次事务提交时,如何处理未刷入(flush)的重做日志信息(redolog)。它 【JS】执行时长(100分) |思路参考+代码解析(C++) l939035548 JS算法数据结构c++ 题目为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。题目输入第一个参数为GPU一次最多执行的任务个数,取值范围[1,10000]第二个参数为任务数组长度,取值范围[1,10000]第三个参数为任务数组,数字范围 Kafka 消息丢失如何处理? 架构文摘JGWZ 学习 今天给大家分享一个在面试中经常遇到的问题:Kafka消息丢失该如何处理?这个问题啊,看似简单,其实里面藏着很多“套路”。来,咱们先讲一个面试的“真实”案例。面试官问:“Kafka消息丢失如何处理?”小明一听,反问:“你是怎么发现消息丢失了?”面试官顿时一愣,沉默了片刻后,可能有点不耐烦,说道:“这个你不用管,反正现在发现消息丢失了,你就说如何处理。”小明一头雾水:“问题是都不知道怎么丢的,处理起来 每日算法&面试题,大厂特训二十八天——第二十天(树) 肥学 ⚡算法题⚡面试题每日精进java算法数据结构 目录标题导读算法特训二十八天面试题点击直接资料领取导读肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。上一期我们完成了动态规划二十一天现在我们进行下一项对各类算法进行二十八天的一个小总结。还在等什么快来一起肥学进行二十八天挑战吧!!特别介绍小白练手专栏,适合刚入手的新人欢迎订阅编程小白进阶python有趣练手项目里面包括了像《机器人尬聊》《恶搞程序》这样的有趣文章 node.js学习 小猿L node.jsnode.js学习vim node.js学习实操及笔记温故node.js,node.js学习实操过程及笔记~node.js学习视频node.js官网node.js中文网实操笔记githubcsdn笔记为什么学node.js可以让别人访问我们编写的网页为后续的框架学习打下基础,三大框架vuereactangular离不开node.jsnode.js是什么官网:node.js是一个开源的、跨平台的运行JavaScript的运行 【华为OD技术面试真题 - 技术面】- python八股文真题题库(4) 算法大师 华为od面试python 华为OD面试真题精选专栏:华为OD面试真题精选目录:2024华为OD面试手撕代码真题目录以及八股文真题目录文章目录华为OD面试真题精选**1.Python中的`with`**用途和功能自动资源管理示例:文件操作上下文管理协议示例代码工作流程解析优点2.\_\_new\_\_和**\_\_init\_\_**区别__new____init__区别总结3.**切片(Slicing)操作**基本切片语法 【华为OD技术面试真题 - 技术面】-测试八股文真题题库(1) 算法大师 华为od面试python算法前端 华为OD面试真题精选专栏:华为OD面试真题精选目录:2024华为OD面试手撕代码真题目录以及八股文真题目录文章目录华为OD面试真题精选1.黑盒测试和白盒测试的区别2.假设我们公司现在开发一个类似于微信的软件1.0版本,现在要你测试这个功能:打开聊天窗口,输入文本,限制字数在200字以内。问你怎么提取测试点。功能测试性能测试安全性测试可用性测试跨平台兼容性测试网络环境测试3.接口测试的工具你了解哪些 【华为OD技术面试真题精选 - 非技术题】 -HR面,综合面_华为od hr面 一个射手座的程序媛 程序员华为od面试职场和发展 最后的话最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!资料预览给大家整理的视频资料:给大家整理的电子书资料:如果本文对你有帮助,欢迎点赞、收藏、转发给朋友,让我有持续创作的动力!网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化的资料的朋友,可以点击这里获 docker igotyback eureka云原生 Docker容器的文件系统是隔离的,但是可以通过挂载卷(Volumes)或绑定挂载(BindMounts)将宿主机的文件系统目录映射到容器内部。要查看Docker容器的映射路径,可以使用以下方法:查看容器配置:使用dockerinspect命令可以查看容器的详细配置信息,包括挂载的卷。例如:bashdockerinspect在输出的JSON格式中,查找"Mounts"部分,这里会列出所有的挂载信息 【华为OD技术面试真题 - 技术面】- python八股文真题题库(1) 算法大师 华为od面试python 华为OD面试真题精选专栏:华为OD面试真题精选目录:2024华为OD面试手撕代码真题目录以及八股文真题目录文章目录华为OD面试真题精选1.数据预处理流程数据预处理的主要步骤工具和库2.介绍线性回归、逻辑回归模型线性回归(LinearRegression)模型形式:关键点:逻辑回归(LogisticRegression)模型形式:关键点:参数估计与评估:3.python浅拷贝及深拷贝浅拷贝(Shal 在Ubuntu中编译含有JSON的文件出现报错 芝麻糊76 Linuxkill_buglinuxubuntujson 在ubuntu中进行JSON相关学习的时候,我发现了一些小问题,决定与大家进行分享,减少踩坑时候出现不必要的时间耗费截取部分含有JSON部分的代码进行展示char*str="{\"title\":\"JSONExample\",\"author\":{\"name\":\"JohnDoe\",\"age\":35,\"isVerified\":true},\"tags\":[\"json\",\" Xinference如何注册自定义模型 玩人工智能的辣条哥 人工智能AI大模型Xinference 环境:Xinference问题描述:Xinference如何注册自定义模型解决方案:1.写个model_config.json,内容如下{"version":1,"context_length":2048,"model_name":"custom-llama-3","model_lang":["en","ch"],"model_ability":["generate","chat"],"model Java企业面试题3 马龙强_ java 1.break和continue的作用(智*图)break:用于完全退出一个循环(如for,while)或一个switch语句。当在循环体内遇到break语句时,程序会立即跳出当前循环体,继续执行循环之后的代码。continue:用于跳过当前循环体中剩余的部分,并开始下一次循环。如果是在for循环中使用continue,则会直接进行条件判断以决定是否执行下一轮循环。2.if分支语句和switch分 Java面试题精选:消息队列(二) 芒果不是芒 Java面试题精选javakafka 一、Kafka的特性1.消息持久化:消息存储在磁盘,所以消息不会丢失2.高吞吐量:可以轻松实现单机百万级别的并发3.扩展性:扩展性强,还是动态扩展4.多客户端支持:支持多种语言(Java、C、C++、GO、)5.KafkaStreams(一个天生的流处理):在双十一或者销售大屏就会用到这种流处理。使用KafkaStreams可以快速的把销售额统计出来6.安全机制:Kafka进行生产或者消费的时候会 2019考研 | 西交大软件工程 笔者阿蓉 本科背景:某北京211学校电子信息工程互联网开发工作两年录取结果:全日制软件工程学院分数:初试350+复试笔试80+面试85+总排名:100+从五月份开始脱产学习,我主要说一下专业课和复试还有我对非全的一些看法。【数学100+】张宇,张宇,张宇。跟着张宇学习,入门视频刷一遍,真题刷两遍,错题刷三遍。书刷N多遍。从视频开始学习,是最快的学习方法。5-7月份把主要是数学学好,8-9月份开始给自己每个周 Python神器!WEB自动化测试集成工具 DrissionPage 亚丁号 python开发语言 一、前言用requests做数据采集面对要登录的网站时,要分析数据包、JS源码,构造复杂的请求,往往还要应付验证码、JS混淆、签名参数等反爬手段,门槛较高。若数据是由JS计算生成的,还须重现计算过程,体验不好,开发效率不高。使用浏览器,可以很大程度上绕过这些坑,但浏览器运行效率不高。因此,这个库设计初衷,是将它们合而为一,能够在不同须要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率 springboot+vue项目实战一-创建SpringBoot简单项目 苹果酱0567 面试题汇总与解析springboot后端java中间件开发语言 这段时间抽空给女朋友搭建一个个人博客,想着记录一下建站的过程,就当做笔记吧。虽然复制zjblog只要一个小时就可以搞定一个网站,或者用cms系统,三四个小时就可以做出一个前后台都有的网站,而且想做成啥样也都行。但是就是要从新做,自己做的意义不一样,更何况,俺就是专门干这个的,嘿嘿嘿要做一个网站,而且从零开始,首先呢就是技术选型了,经过一番思量决定选择-SpringBoot做后端,前端使用Vue做一 分享100个最新免费的高匿HTTP代理IP mcj8089 代理IP代理服务器匿名代理免费代理IP最新代理IP 推荐两个代理IP网站: 1. 全网代理IP:http://proxy.goubanjia.com/ 2. 敲代码免费IP:http://ip.qiaodm.com/ 120.198.243.130:80,中国/广东省 58.251.78.71:8088,中国/广东省 183.207.228.22:83,中国/ mysql高级特性之数据分区 annan211 java数据结构mongodb分区mysql mysql高级特性 1 以存储引擎的角度分析,分区表和物理表没有区别。是按照一定的规则将数据分别存储的逻辑设计。器底层是由多个物理字表组成。 2 分区的原理 分区表由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们可以直接访问各个分区。存储引擎管理分区的各个底层 表和管理普通表一样(所有底层表都必须使用相同的存储引擎),分区表的索引只是 JS采用正则表达式简单获取URL地址栏参数 chiangfai js地址栏参数获取 GetUrlParam:function GetUrlParam(param){ var reg = new RegExp("(^|&)"+ param +"=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if(r!=null 怎样将数据表拷贝到powerdesigner (本地数据库表) Array_06 powerDesigner ================================================== 1、打开PowerDesigner12,在菜单中按照如下方式进行操作 file->Reverse Engineer->DataBase 点击后,弹出 New Physical Data Model 的对话框 2、在General选项卡中 Model name:模板名字,自 logbackのhelloworld 飞翔的马甲 日志logback 一、概述 1.日志是啥? 当我是个逗比的时候我是这么理解的:log.debug()代替了system.out.print(); 当我项目工作时,以为是一堆得.log文件。 这两天项目发布新版本,比较轻松,决定好好地研究下日志以及logback。 传送门1:日志的作用与方法: http://www.infoq.com/cn/articles/why-and-how-log 上面的作 新浪微博爬虫模拟登陆 随意而生 新浪微博 转载自:http://hi.baidu.com/erliang20088/item/251db4b040b8ce58ba0e1235 近来由于毕设需要,重新修改了新浪微博爬虫废了不少劲,希望下边的总结能够帮助后来的同学们。 现行版的模拟登陆与以前相比,最大的改动在于cookie获取时候的模拟url的请求 synchronized 香水浓 javathread Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然 maven 简单实用教程 AdyZhang maven 1. Maven介绍 1.1. 简介 java编写的用于构建系统的自动化工具。目前版本是2.0.9,注意maven2和maven1有很大区别,阅读第三方文档时需要区分版本。 1.2. Maven资源 见官方网站;The 5 minute test,官方简易入门文档;Getting Started Tutorial,官方入门文档;Build Coo Android 通过 intent传值获得null aijuans android 我在通过intent 获得传递兑现过的时候报错,空指针,我是getMap方法进行传值,代码如下 1 2 3 4 5 6 7 8 9 public void getMap(View view){ Intent i = apache 做代理 报如下错误:The proxy server received an invalid response from an upstream baalwolf response 网站配置是apache+tomcat,tomcat没有报错,apache报错是: The proxy server received an invalid response from an upstream server. The proxy server could not handle the request GET /. Reason: Error reading fr Tomcat6 内存和线程配置 BigBird2012 tomcat6 1、修改启动时内存参数、并指定JVM时区 (在windows server 2008 下时间少了8个小时) 在Tomcat上运行j2ee项目代码时,经常会出现内存溢出的情况,解决办法是在系统参数中增加系统参数: window下, 在catalina.bat最前面 set JAVA_OPTS=-XX:PermSize=64M -XX:MaxPermSize=128m -Xms5 Karam与TDD bijian1013 KaramTDD 一.TDD 测试驱动开发(Test-Driven Development,TDD)是一种敏捷(AGILE)开发方法论,它把开发流程倒转了过来,在进行代码实现之前,首先保证编写测试用例,从而用测试来驱动开发(而不是把测试作为一项验证工具来使用)。 TDD的原则很简单: a.只有当某个 [Zookeeper学习笔记之七]Zookeeper源代码分析之Zookeeper.States bit1129 zookeeper public enum States { CONNECTING, //Zookeeper服务器不可用,客户端处于尝试链接状态 ASSOCIATING, //??? CONNECTED, //链接建立,可以与Zookeeper服务器正常通信 CONNECTEDREADONLY, //处于只读状态的链接状态,只读模式可以在 【Scala十四】Scala核心八:闭包 bit1129 scala Free variable A free variable of an expression is a variable that’s used inside the expression but not defined inside the expression. For instance, in the function literal expression (x: Int) => (x android发送json并解析返回json ronin47 android package com.http.test; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import 一份IT实习生的总结 brotherlamp PHPphp资料php教程php培训php视频 今天突然发现在不知不觉中自己已经实习了 3 个月了,现在可能不算是真正意义上的实习吧,因为现在自己才大三,在这边撸代码的同时还要考虑到学校的功课跟期末考试。让我震惊的是,我完全想不到在这 3 个月里我到底学到了什么,这是一件多么悲催的事情啊。同时我对我应该 get 到什么新技能也很迷茫。所以今晚还是总结下把,让自己在接下来的实习生活有更加明确的方向。最后感谢工作室给我们几个人这个机会让我们提前出来 据说是2012年10月人人网校招的一道笔试题-给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 将重物放到天平左侧,问在两边如何添加砝码 bylijinnan java public class ScalesBalance { /** * 题目: * 给出一个重物重量为X,另外提供的小砝码重量分别为1,3,9。。。3^N。 (假设N无限大,但一种重量的砝码只有一个) * 将重物放到天平左侧,问在两边如何添加砝码使两边平衡 * * 分析: * 三进制 * 我们约定括号表示里面的数是三进制,例如 47=(1202 dom4j最常用最简单的方法 chiangfai dom4j 要使用dom4j读写XML文档,需要先下载dom4j包,dom4j官方网站在 http://www.dom4j.org/目前最新dom4j包下载地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip 解开后有两个包,仅操作XML文档的话把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的话还需要 简单HBase笔记 chenchao051 hbase 一、Client-side write buffer 客户端缓存请求 描述:可以缓存客户端的请求,以此来减少RPC的次数,但是缓存只是被存在一个ArrayList中,所以多线程访问时不安全的。 可以使用getWriteBuffer()方法来取得客户端缓存中的数据。 默认关闭。 二、Scan的Caching 描述: next( )方法请求一行就要使用一次RPC,即使 mysqldump导出时出现when doing LOCK TABLES daizj mysqlmysqdump导数据 执行 mysqldump -uxxx -pxxx -hxxx -Pxxxx database tablename > tablename.sql 导出表时,会报 mysqldump: Got error: 1044: Access denied for user 'xxx'@'xxx' to database 'xxx' when doing LOCK TABLES 解决 CSS渲染原理 dcj3sjt126com Web 从事Web前端开发的人都与CSS打交道很多,有的人也许不知道css是怎么去工作的,写出来的css浏览器是怎么样去解析的呢?当这个成为我们提高css水平的一个瓶颈时,是否应该多了解一下呢? 一、浏览器的发展与CSS 《阿甘正传》台词 dcj3sjt126com Part Ⅰ: 《阿甘正传》Forrest Gump经典中英文对白 Forrest: Hello! My names Forrest. Forrest Gump. You wanna Chocolate? I could eat about a million and a half othese. My momma always said life was like a box ochocol Java处理JSON dyy_gusi json Json在数据传输中很好用,原因是JSON 比 XML 更小、更快,更易解析。 在Java程序中,如何使用处理JSON,现在有很多工具可以处理,比较流行常用的是google的gson和alibaba的fastjson,具体使用如下: 1、读取json然后处理 class ReadJSON { public static void main(String[] args) win7下nginx和php的配置 geeksun nginx 1. 安装包准备 nginx : 从nginx.org下载nginx-1.8.0.zip php: 从php.net下载php-5.6.10-Win32-VC11-x64.zip, php是免安装文件。 RunHiddenConsole: 用于隐藏命令行窗口 2. 配置 # java用8080端口做应用服务器,nginx反向代理到这个端口即可 p 基于2.8版本redis配置文件中文解释 hongtoushizi redis 转载自: http://wangwei007.blog.51cto.com/68019/1548167 在Redis中直接启动redis-server服务时, 采用的是默认的配置文件。采用redis-server xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务。下面是Redis2.8.9的配置文 第五章 常用Lua开发库3-模板渲染 jinnianshilongnian nginxlua 动态web网页开发是Web开发中一个常见的场景,比如像京东商品详情页,其页面逻辑是非常复杂的,需要使用模板技术来实现。而Lua中也有许多模板引擎,如目前我在使用的lua-resty-template,可以渲染很复杂的页面,借助LuaJIT其性能也是可以接受的。 如果学习过JavaEE中的servlet和JSP的话,应该知道JSP模板最终会被翻译成Servlet来执行;而lua-r JZSearch大数据搜索引擎 颠覆者 JavaScript 系统简介: 大数据的特点有四个层面:第一,数据体量巨大。从TB级别,跃升到PB级别;第二,数据类型繁多。网络日志、视频、图片、地理位置信息等等。第三,价值密度低。以视频为例,连续不间断监控过程中,可能有用的数据仅仅有一两秒。第四,处理速度快。最后这一点也是和传统的数据挖掘技术有着本质的不同。业界将其归纳为4个“V”——Volume,Variety,Value,Velocity。大数据搜索引 10招让你成为杰出的Java程序员 pda158 java编程框架 如果你是一个热衷于技术的 Java 程序员, 那么下面的 10 个要点可以让你在众多 Java 开发人员中脱颖而出。 1. 拥有扎实的基础和深刻理解 OO 原则 对于 Java 程序员,深刻理解 Object Oriented Programming(面向对象编程)这一概念是必须的。没有 OOPS 的坚实基础,就领会不了像 Java 这些面向对象编程语言 tomcat之oracle连接池配置 小网客 oracle tomcat版本7.0 配置oracle连接池方式: 修改tomcat的server.xml配置文件: <GlobalNamingResources> <Resource name="utermdatasource" auth="Container" type="javax.sql.DataSou Oracle 分页算法汇总 vipbooks oraclesql算法.net 这是我找到的一些关于Oracle分页的算法,大家那里还有没有其他好的算法没?我们大家一起分享一下! -- Oracle 分页算法一 select * from ( select page.*,rownum rn from (select * from help) page -- 20 = (currentPag 按字母分类: ABCDEFGHIJKLMNOPQRSTUVWXYZ其他
、、、、、、、、、、
、、、
块格式化上下文, 特性:
方案一:
方案二:已知高度
方案三:未知高度
方案四:弹性布局
权重可以使用四位数表示:
浮动元素碰到包含它的边框或者浮动元素的边框停留。由于浮动元素不在文档流中,所以文档流的块框表现得就像浮动框不存在一样。浮动元素会漂浮在文档流的块框上。
浮动带来的问题:
清除浮动的方式:
.clear{ /*zoom在平时可以起到缩放效果,不过宽高不会有变化*/ zoom: 1; 兼容IE地板的浏览器的,可以触发IE浏览器的机制让其支持clear属性 } .clear::after{ content: ""; display: block; clear: both; visibility: hidden; 为了防止content里有内容 height: 0; 可以不加,不过IE低版本下有问题,不写高的时候会默认有大概18px的高 }
display:none; 隐藏,理解为消失,没有位置。
visibility:hidden; 占位隐藏,元素消失,但位置还在。理解为隐身,且元素的功能不存在。
opacity:0; 隐藏,占位置的,实际上就是透明为0,让你眼睛看不见它了,但元素的功能存在。
溢出隐藏方式: overflow:hidden;
共同点: 1.改变行内元素的呈现方式,display 被置为 block; 2.让元素脱离普通流,不占据空间; 3.默认会覆盖到非定位元素上
不同点: absolute 的”根元素“是可以设置的,而 fixed 的”根元素“固定为浏览器窗口。当你滚动网页,fixed 元素与浏览器窗口之间的距离是不变的。
因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对 CSS 初始化往往会出现浏览器之间的页面显示差异。
将一个页面涉及到的所有图片都包含到一张大图中去,然后利用 CSS 的 background-image,background- repeat,background-position 的组合进行背景定位。
利用 CSS Sprites 能很好地减少网页的 http 请求,从而大大的提高页面的性能;CSS Sprites 能减少图片的字节。
具体可以点击查看详情
JavaScript 有 简单数据类型:Undefined、Null、Boolean、Number、String、Bigint 和 复杂数据类型 Object、Function、Array ,以及es6语法新增的Symbol数据类型
判断方法有:typeof、instanceof、constructor、Object.prototype.toString
闭包是指有权访问另外一个函数作用域中的局部变量的函数。声明在一个函数中的函数,叫做闭包函数。而且内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
闭包有三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
jsonp是一个能够跨域的方法,由于ajax受到同源策略的影响,不能进行跨域,而script标签中的src属性中的链接能够访问跨域的js脚本,利用这个特性返回一段调用某个函数的js代码,在src中进行了调用,从而实现跨域
优点:可以跨越同源策略、可以在老版本浏览器中运行、请求完毕后可以通过callback的方式回传结果
缺点:只支持get请求、只支持跨域http请求、安全性差
回调函数
事件监听
promise
ajax
async
setTimeout
Generator
Promise 是异步编程的一种解决方案:
从语法上讲,promise是一个对象,从它可以获取异步操作的消息;
从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变化。创造promise实例后,它会立即执行。
处理问题:
回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
promise可以支持多个并发的请求,获取并发请求中的数据
这个promise可以解决异步的问题,本身不能说promise是异步的
Promise是一个构造函数,自己身上有all、reject、resolve这几个方法,原型上有then、catch等方法。
Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:
resolve :异步操作执行成功后的回调函数
reject:异步操作执行失败后的回调函数
then:传递状态的方式来使得回调函数能够及时被调用
catch:指定reject的回调,或者在执行resolve时,如果抛出异常,并不会报错卡死js,而是会进到这个catch方法中
all:谁跑的慢,以谁为准执行回调。all接收一个数组参数,里面的值最终都会返回Promise对象。提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。
race:谁跑的快,以谁为准执行回调
forEach():
map()
filter()
实现 原生AJAX
// 创建核心对象 const xhr = new XMLHttpRequest() // 建立连接 xhr.open(method, url, async) // 发送请求 // 如果为 post 需要在 send 前调用 setRequestHeader() 方法设置请求头 // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhr.send(params) // 处理响应 xhr.onreadystatechange = function() { // 当 readyState 改变时,执行该回调函数 // readyState 属性存有 XMLHttpRequest 的状态信息。 // 可以理解为请求到达哪个阶段了。 // 状态值可取 0-4 的值,4表示请求处理完毕,响应就绪 if(xhr.readyState === 4) { // status 表示的是 HTTP 状态码 // 200 表示 OK (成功) if(xhr.status === 200) { // 从响应中获取返回的数据 let data = xhr.responseText } } } // Promise 封装 ajax const myAjax = function(url) { return Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.send(params) xhr.onreadystatechange = function() { if(xhr.readyState === 4) { if(xhr.status === 200){ let data = JSON.prase(xhr.responseText) resolve(data) } else { reject('error') } } } }) }
随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,this永远指向的是最后调用它的对象。
this指向的形式 (4种)
当 this 碰到 return
如果返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象那么 this 还是指向函数的实例。 注意:虽然null也是对象,但是在这里 this 指向那个函数的实例,因为null 比较特殊。
改变this指向的方式
1.变量提升只会提升变量名的声明,而不会提升变量的赋值初始化。
2.函数提升的优先级大于变量提升的优先级,即函数提升在变量提升之上。
例子: var a = 10; function a(){} console.log(typeof a)
A."number" B."object" C."function" D."undefined" 答案:A
代码等价于: function a(){} var a; a = 10; console.log(typeof a)
原型(prototype): 一个简单的对象,用于实现对象的 属性继承。可以简单的理解成对象的爹。在 Firefox 和 Chrome 中,每个 JavaScript 对象中都包含一个__proto__ (非标准)的属性指向它爹(该对象的原型),可 obj.__proto__ 进行访问。
__proto__
obj.__proto__
构造函数: 可以通过 new 来 新建一个对象 的函数。
实例: 通过构造函数和 new 创建出来的对象,便是实例。 实例通过__proto__ 指向原型,通过 constructor 指向构造函数
三者的关系: 实例.__proto__ === 原型 原型.constructor === 构造函数 构造函数.prototype === 原型
实例.__proto__
原型.constructor
构造函数.prototype
原型链是由原型对象组成,每个对象都有__proto__ 属性,指向了创建该对象的构造函数的原型,__proto__将对象连接起来组成了原型链。是一个用来实现继承和共享属性的有限的对象链。
当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的 __proto__ 隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的 prototype 的 __proto__ 中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。
prototype
属性查找机制: 当查找对象的属性时,如果实例对象自身不存在该属性,则沿着原型链往上一级查找,找到时则输出,不存在时,则继续沿着原型链往上一级查找,直至最顶级的原型对象 Object.prototype,如还是没找到,则输出undefined;
Object.prototype
undefined
属性修改机制: 只会修改实例对象本身的属性,如果不存在,则进行添加该属性,如果需要修改原型的属性时,则可以用: b.prototype.x = 2;但是这样会造成所有继承于该对象的实例的属性发生改变。
b.prototype.x = 2;
运行在客户端浏览器上;
不用预编译,直接解析执行代码;
是弱类型语言,较为灵活;
与操作系统无关,跨平台的语言;
脚本语言、解释性语言
跨域的原理:指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript 实施的安全限制,那么只要协议、域名、端口有任何一个不同,都被当作是不同的域。跨域原理,即是通过各种方式,避开浏览器的安全限制。
JSONP : 通 过 动 态 创 建 script , 再 请 求 一 个 带 参 网 址 实 现 跨 域 通 信 。
document.domain + iframe 跨域:两个页面都通过 js 强制设置 document.domain为基础主域,就实现了同域。
location.hash + iframe 跨域:a 欲与 b 跨域相互通信,通过中间页 c 来实现。三个页面,不同域之间利用 iframe 的 location.hash 传值,相同域之间直接 js访问来通信。
window.name + iframe 跨域:通过 iframe 的 src 属性由外域转向本地域,跨域数据即由 iframe 的window.name 从外域传递到本地域。
postMessage 跨域:可以跨域操作的 window 属性之一。
CORS:服务端设置 Access-Control-Allow-Origin 即可,前端无须设置,若要带cookie 请求,前后端都需要设置。
代理跨域:启一个代理服务器,实现数据的转发
法一:indexOf 循环去重
法二:ES6 Set 去重;Array.from(new Set(array))
法三:Object 键值对去重;把数组的值存成 Object 的 key 值,比如 Object[value1] = true,在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的。
在代码块内,使用 let、const 命令声明变量之前,该变量都是不可用的。在语法上,称为“暂时性死区”
webpack 是 一 个 现 代 JavaScript 应 用 程 序 的 静 态 模 块 打 包 器 (module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
// 第一个方法:用 let 块级作用域 for(let i = 0; i < 5; i++) { setTimeout(function() { console.log(i + 1) }, 1000 * i) } // 第二个方法:闭包 for(var i = 0; i < 5; i++) { (function(i) { setTimeout(function(){ console.log(i + 1) }, 1000 * i) })(i) }
Symbol 是 ES6 的新增属性,代表用给定名称作为唯一标识,这种类型的值可以这样创建,let id = symbol(“id”)
Symbl 确保唯一,即使采用相同的名称,也会产生不同的值,我们创建一个字段,仅为知道对应 symbol 的人能访问,使用 symbol 很有用,symbol 并不是 100%隐藏,有内置方法 Object.getOwnPropertySymbols(obj)可以获得所有的 symbol。也有一个方法 Reflect.ownKeys(obj)返回对象所有的键,包括 symbol。所以并不是真正隐藏,但大多数库内置方法和语法结构遵循通用约定他们是隐藏的。
js变量存储有栈存储和堆存储,基本数据类型的变量存储在栈中,引⽤数据类型的变量存储在堆中,引⽤类型数据的地址也存在栈中
当访问基础类型变量时,直接从栈中取值。当访问引⽤类型变量时,先从栈中读取地址,在根据地址到堆中取出数据
Call 和 apply 的作用是一模一样的,只是传参的形式有区别而已 1、改变 this 的指向 2、借用别的对象的方法 3、调用函数,因为 apply,call 方法会使函数立即执行
除了正常模式运行外,ECMAscript 5 添加了第二种运行模式:“严格模式”。
作用:
全称:JavaScript Object Notation JSON 中对象通过“{}”来标识,一个“{}”代表一个对象,如{“AreaId”:”123”},对象的值是键值对的形式(key:value)。JSON 是 JS 的一个严格的子集,一种轻量级的数据交换格式,类似于 xml。数据格式简单,易于读写,占用带宽小。
两个函数:
同步的概念在操作系统中:不同进程协同完成某项工作而先后次序调整(通过阻塞、唤醒等方式),同步强调的是顺序性,谁先谁后。异步不存在顺序性。
同步:浏览器访问服务器,用户看到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容之后进行下一步操作。
异步:浏览器访问服务器请求,用户正常操作,浏览器在后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。
先给出结论 CSS 不会阻塞 DOM 解析,但会阻塞 DOM 渲染。CSS 会阻塞 JS 执行,并不会阻塞 JS 文件下载 先讲一讲 CSSOM 作用: 第一个是提供给 JavaScript 操作样式表的能力; 第二个是为布局树的合成提供基础的样式信息。 这个 CSSOM 体现在 DOM 中就是 document.styleSheets。 由之前讲过的浏览器渲染流程我们可以看出: DOM 和 CSSOM 通常是并行构建的,所以「CSS 加载不会阻塞 DOM 的解析」。然而由于 Render Tree 是依赖 DOM Tree 和 CSSOM Tree 的,所以它必须等到两者都加载完毕后,完成相应的构建,才开始渲染,因此,「CSS 加载会阻塞 DOM渲染」。 由于 JavaScript 是可操纵 DOM 和 css 样式 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。因此为了防止渲染出现不可预期的结果,浏览器设置 「GUI 渲染线程与JavaScript 引擎为互斥」的关系。 有个需要注意的点就是: 「有时候 JS 需要等到 CSS 的下载,这是为什么呢?」 仔细思考一下,其实这样做是有道理的,如果脚本的内容是获取元素的样式,宽高等 CSS 控制的属性,浏览器是需要计算的,也就是依赖于 CSS。浏览器也无法感知脚本内容到底是什么,为避免样式获取,因而只好等前面所有的样式下载完后,再执行 JS。JS 文件下载和 CSS 文件下载是并行的,有时候 CSS 文件很大,所以 JS 需要等待。因此,样式表会在后面的 js 执行前先加载执行完毕,所以「css 会阻塞后面 js的执行」。
JS 阻塞 DOM 解析,也就会阻塞页面 这也是为什么说 JS 文件放在最下面的原因,那为什么会阻塞 DOM 解析呢 你可以这样子理解: 由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。 因此为了防止渲染出现不可预期的结果,浏览器设置 「GUI 渲染线程与JavaScript 引擎为互斥」的关系。 当 JavaScript 引擎执行时 GUI 线程会被挂起,GUI 更新会被保存在一个队列中等到引擎线程空闲时立即被执行。 当浏览器在执行 JavaScript 程序的时候,GUI 渲染线程会被保存在一个队列中, 直到 JS 程序执行完成,才会接着执行。因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。 另外 ,如 果 JavaScript 文件 中没 有操 作 DOM 相关 代码 ,就 可以将 该JavaScript 脚本设置为异步加载,通过 async 或 defer 来标记代码。
eval(arr.join(“+”))
同步:同步任务是指在主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务。 异步:异步任务是指不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程。
const withinErrorMargin = (left, right) => { return Math.abs(left - right) < Number.EPSILON * Math.pow(2, 2); } console.log(withinErrorMargin(0.1 + 0.2, 0.3)) // 第二种方法 console.log(parseFloat((0.1 + 0.2).toFixed(10)) === 0.3)
作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
ES6 之前 JavaScript 没有块级作用域,只有全局作用域和函数作用域。ES6 的到来,为我们提供了‘块级作用域’,可通过新增命令 let 和 const 来体现。
作用域是分层的,内层作用域可以访问外层作用域的变量,反之则不行。
2xx (3种)
3xx (5种)
4xx (4种)
5xx (2种)
共同点:都是保存在浏览器端,并且是同源的
cookie 可以在浏览器和服务器间来回传递,存储容量小,只有大约4K左右。 作用:1、保存用户登录状态;2、跟踪用户行为。
localStorage ⻓期存储数据,浏览器关闭后数据不会丢失;
sessionStorage 数据在浏览器关闭后⾃动删除。
sessionStorage和localStorage优势:存储空间更⼤、有更多丰富易⽤的接⼝、各⾃独⽴的存储空间
分为 4 个步骤: (1)浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP,向服务器发起请求;
(2)浏览器与远程 Web 服务器通过 TCP 三次握手协商来建立一个 TCP/IP 连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
(3)一旦 TCP/IP 连接建立,浏览器会通过该连接向远程服务器发送 HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源,值为 200 的 HTTP 响应状态表示一个正确的响应。
(4)此时,Web 服务器提供资源服务,客户端开始下载资源。请求返回后,载入解析到的资源文件,渲染页面,便进入了我们关注的前端模块
简述版:
当元素的样式发生变化时,浏览器需要触发更新,重新绘制元素。这个过程中,有两种类型的操作,即重绘与回流。
重绘(repaint): 当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此 损耗较少
回流(reflow): 当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。会触发回流的操作:
回流必定触发重绘,重绘不一定触发回流。重绘的开销较小,回流的代价较高。
最佳实践: css:
javascript
阻止事件传播(冒泡): e.stopPropagation()
阻止默认行为: e.preventDefault()
事件捕获阶段: 从 dom 树节点往下找到目标节点, 不会触发函数
事件目标处理函数: 到达目标节点
事件冒泡: 最后从目标节点往顶层元素传递, 通常函数在此阶段执行. addEventListener 第三个参数默认false(冒泡阶段执行), true(捕获阶段执行).
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源
防止 XSS、CSFR 等攻击, 协议+域名+端口不同
jsonp; 跨域资源共享(CORS); (Access control); 服务器正向代理等
预检请求: 需预检的请求要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
一个程序至少一个进程,一个进程至少一个线程。
浏览器内核可以分成两部分: 渲染引擎(layout engineer 或者 Rendering Engine)和 JS 引擎。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
渲染引擎: 负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入 CSS 等),以及计算网页的显示方式,然后会输出至显示器或打印机。
JS 引擎 解析 Javascript 语言,执行 javascript 语言来实现网页的动态效果。最开始渲染引擎和 JS 引擎并没有区分的很明确,后来 JS 引擎越来越独立,内核就倾向于只指渲染引擎。
DOM Tree 和 CSS RULE Tree 将 html 和 css 解析成树形数据结构,然后 Dom 和 css 合并后生成Render Tree,用 layout 来确定节点的位置以及关系,通过 painting 按照规则来画到屏幕上,由 display 搭建最终看到效果。
Cross-site script,跨站脚本攻击,当其它用户浏览该网站时候,该段 HTML 代码会自动执行,从而达到攻击的目的,如盗取用户的 Cookie,破坏页面结构,重定向到其它网站等。
XSS 类型: 一般可以分为: 持久型 XSS 和非持久性 XSS
持久型 XSS: 就是对客户端攻击的脚本植入到服务器上,从而导致每个正常访问到的用户都会遭到这段 XSS 脚本的攻击。
非持久型 XSS: 是对一个页面的 URL 中的某个参数做文章,把精心构造好的恶意脚本包装在 URL 参数重,再将这个 URL 发布到网上,骗取用户访问,从而进行攻击。
CSRF(Cross-site request forgery), 中文名称:跨站请求伪造 CSRF 可以简单理解为:攻击者盗用了你的身份,以你的名义发送恶意请求,容易造成个人隐私泄露以及财产安全。
防范: post 请求 使用 token 验证码
利用目标系统网络服务功能缺陷或者直接消耗其系统资源,使得该目标系统无法提供正常的服务。 DDoS 攻击通过大量合法的请求占用大量网络资源,以达到瘫痪网络的目的。
具体有几种形式:
URI 是统一资源标识符,相当于一个人身份证号码 Web 上可用的每种资源如 HTML 文档、图像、视频片段、程序等都是一个来 URI来定位的 URI 一般由三部组成 ①访问资源的命名机制 ②存放资源的主机名 ③资源自身的名称,由路径表示,着重强调于资源。
URL 是统一资源定位符,相当于一个人的家庭住址 URL 是 Internet 上用来描述信息资源的字符串,主要用在各种 WWW 客户程序和服务器程序上,特别是著名的 Mosaic。采用 URL 可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。 URL 一般由三部组成 ①协议(或称为服务方式) ②存有该资源的主机 IP 地址(有时也包括端口号) ③主机资源的具体地址。如目录和文件名等。
SYN表示建立连接,ACK表示响应
建立连接前,客户端和服务端需要通过握手来确认对方:
客户端发送 syn(同步序列编号) 请求,进入 syn_send 状态,等待确认
服务端接收并确认 syn 包后发送 syn+ack 包,进入 syn_recv 状态
客户端接收 syn+ack 包后,发送 ack 包,双方进入 established 状态
SYN表示建立连接,FIN表示关闭连接,ACK表示响应
客户端 – FIN --> 服务端, FIN—WAIT 服务端 – ACK --> 客户端, CLOSE-WAIT 服务端 – ACK,FIN --> 客户端, LAST-ACK 客户端 – ACK
答:数据驱动、组件系统
.prevent
.stop
.self
.capture
答:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key 的作用主要是为了高效的更新虚拟DOM。
父组件与子组件传值:
非父子组件间的数据传递,兄弟组件传值:
详情可以看看这个
Vue.js 2.0 采用数据劫持(Proxy 模式)结合发布者-订阅者模式(PubSub 模式)的方式,通过 Object.defineProperty()来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。 1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数 3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
例如现在需要监控data中, obj.a 的变化。Vue中监控对象属性的变化你可以这样:
watch: { 'obj.a': { handler (newName, oldName) { console.log('obj.a changed') } } }
另一种方法,利用计算属性(computed) 的特性来实现,当依赖改变时,便会重新计算一个新值。
computed: { a1 () { return this.obj.a } }
总结:虚拟dom可以很好的跟踪当前dom状态,因为他会根据当前数据生成一个描述当前dom结构的虚拟dom,然后数据发生变化时,又会生成一个新的虚拟dom,而这两个虚拟dom恰恰保存了变化前后的状态。然后通过diff算法,计算出两个前后两个虚拟dom之间的差异,得出一个更新的最优方法(哪些发生改变,就更新哪些)。可以很明显的提升渲染效率以及用户体验
作用在表单元素上 v-model = "message" 等同于 v-bind:value = "message" v-on:input = "message=event.target.value" 作用在组件上,本质是一个父子组件通信的语法糖,通过 prop 和 .emit 实现, 等同于:value = "message" @input = "$emit('input', $event.target.value)"
v-model = "message"
v-bind:value = "message" v-on:input = "message=event.target.value"
:value = "message" @input = "$emit('input', $event.target.value)"
JS中的对象是引用类型的数据,当多个实例引用同一个对象时,只要一个实例对这个对象进行操作,其他实例中的数据也会发生变化。 而在Vue中,我们更多的是想要复用组件,那就需要每个组件都有自己的数据,这样组件之间才不会相互干扰。 所以组件的数据不能写成对象的形式,而是要写成函数的形式。数据以函数返回值的形式定义,这样当我们每次复用组件的时候,就会返回一个新的data,也就是说每个组件都有自己的私有数据空间,它们各自维护自己的数据,不会干扰其他组件的正常运行。
介绍:每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。在这个过程中,他经历了从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。
beforecreate (初始化界面前) created (初始化界面后) beforemount (渲染界面前) mounted (渲染界面后) beforeUpdate (更新数据前) updated (更新数据后) beforedestory (卸载组件前) destroyed (卸载组件后)
< keep-alive >是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
< keep-alive > 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
生命周期钩子:actived:激活调用; deactived:停用时调用
属性:include:名称(正则 or 字符串)匹配时调用; exclude:名称不匹配时调用; max:最多缓存数量
Vuex是实现组件全局状态(数据)管理的一种机制,可以方便实现组件数据之间的共享; Vuex集中管理共享的数据,易于开发和后期维护; 能够高效的实现组件之间的数据共享,提高开发效率; 存储在 Vuex 的数据是响应式的,能够实时保持页面和数据的同步; Vuex重要核心属性包括:state, mutations, action, getters, modules.
state Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
mutations mutations定义的方法动态修改Vuex 的 store 中的状态或数据。
action actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。
getters 类似vue的计算属性,主要用来过滤一些数据。
modules 项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,react/vue 官方都推荐使用 axios 发 ajax 请求
特点:
常用语法:
1 动态路由传值。例如:path:“/home/:id/name”; 接受的时候通过 this.$route.params
this.$route.params
2 query 传值。因为在 url 中 ?后面的参数不会被解析,因此我们可以通过 query 进行传值。接受的时候通过 this.$route.query
this.$route.query
3 路由解耦。在配置路由的时候添加 props 属性为 true,在需要接受参数的组件页面通过 props 进行接受
props
4 编程式导航 this.$router.push({path:"/home",query:{}});
this.$router.push({path:"/home",query:{}});
$route
$router
$route 是 “路由信息对象”,包括 path,params,hash,query,fullPath, matched,name 等路由信息参数。
$router 是“路由实例”对象包括了路由的跳转方法,钩子函数等。
动态路由的创建,主要是使用 path 属性过程中,使用动态路径参数,以冒号开头,如下:
{ path: '/details/:id' name: 'Details' components: Details }
访问 details 目录下的所有文件,如果 details/a,details/b 等,都会映射到 Details 组件上。当匹配到 /details 下的路由时,参数值会被设置到 this.$route.params 下,所以通过这个属性可以获取动态参数 this.$route.params.id
this.$route.params.id
路由守卫为: 全局守卫:beforeEach 后置守卫:afterEach 全局解析守卫:beforeResolve 路由独享守卫:beforeEnter
bubbleSort = arr => { for (let i = 0, l = arr.length; i < l - 1; i++) { for (let j = 0; j < l - 1 - i; j++) { if(arr[j] > arr[j+1]) { let temp = arr[j+1] arr[j+1] = arr[j] arr[j] = temp } } } return arr } console.log('结果:', bubbleSort([5,3,2,4,8]))
selectSort = arr => { for (let i = 0,l = arr.length; i < l - 1; i++) { for (let j = i+1; j < l; j++) { if(arr[i] > arr[j]) { let temp = arr[i] arr[i] = arr[j] arr[j] = temp } } } return arr } console.log('结果:', selectSort([5,3,2,4]))
insertSort = arr => { let l = arr.length for(let i = 1; i < l; i++){ let temp = arr[i] let j = i - 1 for(; j >= 0 && arr[j] > temp; j--) { arr[j+1] = arr[j] } arr[j+1] = temp } return arr } console.log(insertSort([3,44,58,2,9,1]))
quickSort = arr => { let l = arr.length let leftArr = [] let rightArr = [] let a = arr[0] if( l <= 1) { return arr } for(let i = 1; i < l; i++) { if(arr[i] > a) { rightArr.push(arr[i]); } else{ leftArr.push(arr[i]); } } return [].concat(quickSort(leftArr),[a],quickSort(rightArr)) } console.log('结果:', quickSort([5,1,6,7]))
func = arr => { let len = arr.length let res = [] // 所有排列结果 /** * 【全排列算法】 * 说明:arrange用来对arr中的元素进行排列组合,将排列好的各个结果存在新数组中 * @param tempArr:排列好的元素 * @param leftArr:待排列元素 */ let arrange = (tempArr, leftArr) => { if (tempArr.length === len) { // 这里就是递归结束的地方 res.push(tempArr.join('')) // 得到全排列的每个元素都是字符串 } else { leftArr.forEach((item, index) => { let temp = [].concat(leftArr) temp.splice(index, 1) // 此时,第一个参数是当前分离出的元素所在数组;第二个参数temp是传入的leftArr去掉第一个后的结果 arrange(tempArr.concat(item), temp) // 这里使用了递归 }) } } arrange([], arr) return res } console.log('结果:', func(['A', 'B', 'C', 'D']))
/** 队列思想(FIFO) 先进先出 * enqueue(element):向队列尾部添加一个(或多个)新的项; * dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素; * front():返回队列中的第一个元素——最先被添加,也将是最先被移除的元素。 队列不做任何变动(不移除元素,只返回元素信息与Stack类的peek方法非常类似); * isEmpty():如果队列中不包含任何元素,返回true,否则返回false; * size():返回队列包含的元素个数,与数组的length属性类似; * toString():将队列中的内容,转成字符串形式 */ function Queue() { this.items = [] // enqueue():将元素加入到队列中 Queue.prototype.enqueue = element => { this.items.push(element) } // dequeue():从队列中删除前端元素 Queue.prototype.dequeue = () => { return this.items.shift() } // front():查看前端的元素 Queue.prototype.front = () => { return this.items[0] } // isEmpty:查看队列是否为空 Queue.prototype.isEmpty = () => { return this.items.length === 0 } // size():查看队列中元素的个数 Queue.prototype.size = () => { return this.items.length } // toString():将队列中元素以字符串形式输出 Queue.prototype.toString = () => { let resultString = '' for (let i of this.items){ resultString += i + ' ' } return resultString } } // 创建队列 let queue = new Queue() // 加入队列 queue.enqueue('a') queue.enqueue('b') queue.enqueue('c') console.log(queue) // 从队列中删除 queue.dequeue() console.log(queue) // 查看前端元素 console.log(queue.front()) // 判断是否为空 console.log(queue.isEmpty()) // 查看 size console.log(queue.size()) // 字符串形式输出 console.log(queue.toString())
/** 栈的思想: 先进后出,后进先出 * enStack(element):添加一个新元素到栈顶位置; * deStack():移除栈顶的元素,同时返回被移除的元素; * peek():返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它); * isEmpty():如果栈里没有任何元素就返回true,否则返回false; * size():返回栈里的元素个数。这个方法和数组的length属性类似; * toString():将栈结构的内容以字符串的形式返回。 * */ function Stack() { this.items = [] // 压栈 Stack.prototype.enStack = element => { this.items.push(element) } // 出栈 Stack.prototype.deStack = () => { return this.items.pop() } // 查看栈顶 Stack.prototype.peek = () => { return this.items[this.items.length-1] } // 判断是否为空 Stack.prototype.isEmpty = () => { return this.items.length === 0 } // 查看栈中元素个数 Stack.prototype.size = () => { return this.items.length } // 以字符串的形式输出 Stack.prototype.toString = () => { let resultString = '' for(let i of this.items) { resultString += i + ' ' } return resultString } } // 创建栈 let stack = new Stack() // 压栈 stack.enStack('a') stack.enStack('b') stack.enStack(3) console.log(stack) // 出栈 console.log(stack.deStack()) // 查看栈顶 console.log(stack.peek()) // 判断是否为空 console.log(stack.isEmpty()) // 查看栈中元素个数 console.log(stack.size()) // 以字符串的形式输出 console.log(stack.toString())
// 创建节点 class Node { constructor(key, left = null, right = null) { this.key = key this.left = left this.right = right } } // 方法 class BinarySearchTree { constructor(node) { this.root = node } // 插入节点 insert(newNode, node = this.root) { if (!this.root) { this.root = newNode } else { if (newNode.key < node.key) { if (node.left === null) { node.left = newNode } else { this.insert(newNode, node.left) } } else { if (node.right === null) { node.right = newNode } else { this.insert(newNode, node.right) } } } } // 前序遍历 preOrderTraverse(curNode = this.root) { //可以从指定结点进行 if (!curNode) { return } let arr = []; const preOrderTraverseNode = node => { if (!node) { return } arr.push(node.key) preOrderTraverseNode(node.left) preOrderTraverseNode(node.right) } preOrderTraverseNode(curNode) return arr } // 中序遍历 inOrderTraverse(curNode = this.root) { if (!curNode) { return } let arr = []; const inOrderTraverseNode = node => { if (!node) { return } inOrderTraverseNode(node.left) arr.push(node.key) inOrderTraverseNode(node.right) } inOrderTraverseNode(curNode) return arr } // 后序遍历 postOrderTraverse(curNode = this.root) { if (!curNode) { return } let arr = []; const postOrderTraverseNode = node => { if (!node) { return } postOrderTraverseNode(node.left) postOrderTraverseNode(node.right) arr.push(node.key) } postOrderTraverseNode(curNode) return arr } // 最小节点 minNode(node = this.root) { if (!node.left) { return node.key } return this.minNode(node.left) } // 最大节点 maxNode(node = this.root) { if (!node.right) { return node.key } return this.maxNode(node.right) } // 查找节点 search(key,curNode = this.root) { if(!curNode) { return false } if(key === curNode.key) { return curNode } return this.search(key, key < curNode.key ? curNode.left : curNode.right) } } const tree = new BinarySearchTree(new Node(11)) tree.insert(new Node(15)) tree.insert(new Node(7)) tree.insert(new Node(5)) tree.insert(new Node(3)) tree.insert(new Node(9)) tree.insert(new Node(8)) tree.insert(new Node(10)) tree.insert(new Node(13)) tree.insert(new Node(12)) tree.insert(new Node(14)) tree.insert(new Node(20)) tree.insert(new Node(18)) tree.insert(new Node(25)) console.log(tree.preOrderTraverse()) console.log(tree.inOrderTraverse()) console.log(tree.postOrderTraverse()) console.log(tree.minNode()) console.log(tree.maxNode()) console.log(tree.search(9))
function getType(obj) { if (obj === null) { return String(obj) } const toType = (obj) => { return Object.prototype.toString.call(obj).replace('[object ', '').replace(']', '').toLowerCase() } return typeof obj === 'object' ? toType(obj) : typeof obj }
DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> <style> img { display: block; margin-bottom: 50px; width: 400px; height: 400px; background-color: red; } style> head> <body> <div id="div"> <img src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> <img src="http://ww1.sinaimg.cn/large/006y8mN6gw1fa7kaed2hpj30sg0l9q54.jpg" alt=""> <img src="http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg" alt=""> div> <script> function lazyload() { //监听页面滚动事件 var documentHeight = document.documentElement.offsetHeight; //文档总高度 var seeHeight = document.documentElement.clientHeight; //可见区域高度 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滚动条距离顶部高度 if (documentHeight - seeHeight - scrollTop < 30) { var imgElement = document.createElement('img'); imgElement.setAttribute('src', 'http://ww4.sinaimg.cn/large/006y8mN6gw1fa5obmqrmvj305k05k3yh.jpg'); document.querySelector('#div').appendChild(imgElement); } } // 简单的节流函数 //fun 要执行的函数 //delay 延迟 //time 在time时间内必须执行一次 function throttle(fun, delay, time) { var timeout, startTime = new Date(); return function () { var context = this, args = arguments, curTime = new Date(); clearTimeout(timeout); // 如果达到了规定的触发时间间隔,触发 handler if (curTime - startTime >= time) { fun.apply(context, args); startTime = curTime; // 没达到触发间隔,重新设定定时器 } else { timeout = setTimeout(function () { fun.apply(context, args); }, delay); } }; }; // 采用了节流函数 window.addEventListener('scroll', throttle(lazyload, 500, 1000)); script> body> html>
// 累加 reduce addFunc = arr => { return arr.reduce((x, y) => { return x + y }, 0) } console.log(addFunc([8,5,2,1])) // 累加 eval addFunc = arr => { return eval(arr.join('+')) } console.log(addFunc([62,4,3,7])) // 累加 for循环 addFuncFor = arr => { let l = arr.length let sum = 0 for(let i = 0; i < l ; i++) { sum += arr[i] } return sum } console.log(addFuncFor([8,3,47,5]))
// 阶乘 递归 mulFunc = n => { if(n ===0) { return 1 } else { return n * mulFunc(n-1) } } console.log(mulFunc(4)) // 阶乘 for循环 mulFuncFor = n => { for(let i = n-1; i > 0; i--) { n *= i } return n } console.log(mulFuncFor(5))
func = str => { const arr = [] const group = str.split('|') group.forEach((item, index) => { const h = item.split(',')[0] const v = item.split(',')[1] let obj = { h,v } arr.push(obj) }) return arr } console.log(func('10,100|20,200|30,300|40,400'))
根据公司不同,面试的情况也会有所不同,有的公司可能偏向基础,有的公司可能偏向算法(可以到力扣上刷刷题)。 最主要还是面试时要表达清晰,不要太紧张,放平心态,关注前沿技术以及一些底层代码,因为面试官会根据你说的话而延伸话题,答题时要懂得灵活应变。