拼多多面试

3、如何不发生margin重叠?

单个方块重叠的解决方法:1.浮动。在IE浏览器下(IE8未测过),浮动可以解决margin-top以及margin-bottom重叠的问题。而在Firefox火狐浏览器或是chrome谷歌浏览器下以及opera浏览器下,浮动只能解决同方向上的margin重叠问题。不同方向上的margin重叠的问题依旧存在。
同方向margin重叠的解决方法:1.与清除浮动的方法一致,给外部的box添加清除浮动相同的样式即可。常用的样式代码为:overflow:hidden; zoom:1;但是有问题的是,在IE浏览器下(未测试IE8),应用zoom属性后,似乎发生了水平方向上margin失效的情况。其他表现均一致。
同方向margin重叠的解决方法:2.增加些边缘属性。例如padding值,padding:1px;或是border属性,border:1px solid #cacbcc。此方法在非IE浏览器下效果良好,但是在IE浏览器下,表现很糟糕。
3、相邻的盒模型中,如果其中的一个是浮动的(float),垂直margin不会重叠,并且浮动的盒模型和它的子元素之间也是这样。
4、设置了overflow属性的元素和它的子元素之间的margin不被重叠(overflow取值为visible除外)。
5、设置了绝对定位(position:absolute)的盒模型,垂直margin不会被重叠,并且和他们的子元素之间也是一样。
6、设置了display:inline-block的元素,垂直margin不会重叠,甚至和他们的子元素之间也是一样。
外层元素padding代替
内层元素透明边框 border:1px solid transparent;
内层元素绝对定位 postion:absolute:
外层元素 overflow:hidden;
内层元素 加float:left;或display:inline-block;
内层元素padding:1px;

6、import以及require的区别?

require方法是CommonJs推出的,NodeJs自带了这个功能。而import是ES6推出的


ES6中require和import等价吗?
用ES6开发中,我们的代码中,会多一种模块引入语法,那就是import。import会被转化为commonjs格式或者是AMD格式,所以不要把它认为是一种新的模块引用方式。babel默认会把ES6的模块转化为commonjs规范的,你也不用费劲再把它转成AMD了。
所以如下写法是等价的:
import list from './list';
//等价于
var list = require('./list');


10、VUE生命周期,watch以及computed之间的区别

Vue生命周期,他们是:
beforeCreate
在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。
created
实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount
在挂载开始之前被调用:相关的 render 函数首次被调用。
mounted
el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
beforeUpdate
数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。
updated
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。
该钩子在服务器端渲染期间不被调用。
beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed
Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。


1#computed:计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。
2#methods:methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。
3#watch:是一种更通用的方式来观察和响应 Vue 实例上的数据变动。一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。


通俗来讲,
computed是在HTML DOM加载后马上执行的,如赋值;
而methods则必须要有一定的触发条件才能执行,如点击事件;
watch呢?它用于观察Vue实例上的数据变动。对应一个对象,键是观察表达式,值是对应回调。值也可以是方法名,或者是对象,包含选项。
所以他们的执行顺序为:默认加载的时候先computed再watch,不执行methods;等触发某一事件后,则是:先methods再watch。
下面的例子可以做为说明。
computed 属性 vs watched 属性:Vue 确实提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:watch 属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的想法是使用 computed 属性而不是命令式的 watch 回调。






5. css中的单位有哪些?并简述其计算方法。

%百分比 
百分比不能算是一种单位,可以理解为包含数值和单位的数据,不管离子元素最近的父元素的该属性是什么单位,都是将 数值*百分比+单位 计算出child的属性值。
padding和margin的值为百分比是相对于父元素的width计算的,不管是padding-left,还是padding-top
px像素 (计算机屏幕上的一个点)
em 单位转为像素值,取决于他们使用的字体大小。 此字体大小受从父元素继承过来的字体大小,除非显式重写与一个具体单位。
相对于当前对象内文本的字体尺寸。例如: 
1em 等于当前的字体尺寸; 
2em 等于当前字体尺寸的两倍。 
如果某元素以 12pt 显示,那么 2em 是24pt。 
在 CSS 中,em 是非常有用的单位,因为它可以自动适应用户所使用的字体。
rem 使用rem同em一样皆为相对字体大小单位,不同的是rem相对的是HTML根元素。 
rem中的“r”代表“root”,这意味着设置当前元素的字体大小的基准为根元素,大多数情况下,我们会设置在html元素上。
vh 和 vw
在进行响应式布局时,我们常常会使用百分比来布局,然而CSS的百分比不总是解决每个问题的最佳方案,CSS的宽度相对于离它最近的父元素的宽度。 如果你想使用视口的宽度、高度而不是父元素的宽高,可以使用vh和vw单位。
vh = viewportHeight * 1/100; 
vw = viewportWidth * 1/100;
使用vh、vw就可以保证元素的宽高适应不同设备。
vmin 和 vmax
vw和vh对应于viewport的width和height,而vmin和vmax分别对应于width、height中的最小值和最大值,例如如果浏览器的宽/高被设置为1000px/600px,那么
vmin = 600 * 1/100;
vmax = 1000 * 1/100;
ex 和 ch
ex、ch单位与em、rem相似之处在于都依赖于font-size,但是ex、ch还依赖于font-family,基于font-specific来计算
其他
in英寸
cm厘米
mm毫米
pt磅 (1 pt 等于 1/72 英寸)
pc12 点活字 (1 pc 等于 12 点)


6. css的优先顺序是什么?

!important,使用此标记的CSS属性总是最优先的。 
!important->id->class->tag 
important 比 内联优先级高,但内联比 id 要高;如果两个规则的特殊性相同,那么后定义的会覆盖先定义的;
情况一:1.多重样式优先级 
多重样式(Multiple Styles):如果外部样式、内部样式和内联样式同时应用于同一个元素,就是使多重样式的情况。
一般情况下,优先级如下:
(外部样式)External style sheet <(内部样式)Internal style sheet <(内联样式)Inline style
注意:有个例外的情况,就是如果外部样式放在内部样式的后面,则外部样式将覆盖内部样式。


内联样式表的权值最高 1000; 
ID 选择器的权值为 100 
Class 类选择器的权值为 10 
HTML 标签选择器的权值为 1
(1).css优先级
是由四个级别和各个级别出现的次数决定的,值从左到右,左面的最大,一级大于一级
3.需要注意
!important的优先级是最高的,但出现冲突时则需比较”四位数“
优先级相同时,则采用就近原则
继承得来的属性,其优先级最低


7. 如何实现js的跨域?并简述其原理

(1)jsonp
JSONP 原理是加载一个 script,并执行一段回调 JS ,因为加载 JS 不需要遵循同源策略。使用这种技术服务器会接受回调函数名作为请求参数,并将JSON数据填充进回调函数中去。
但由此也带来了JSONP的一些问题:
无法发送特定的头部
只能是 GET 请求
无法发送 body
(2)window.postMessage
postMessage是HTML5新增在window对象上的方法,目的是为了解决在父子页面上通信的问题。
postMessage方法接受两个参数: 
message: 要传递的对象,只支持字符串信息,因此如果需要发送对象,可以使用JSON.stringify和JSON.parse做处理 
targetOrigin: 目标域,需要注意的是协议,端口和主机名必须与要发送的消息的窗口一致。如果不想限定域,可以使用通配符“*”,但是从安全上考虑,不推荐这样做。
页面源中监听message事件就能正常获取消息了。其中,MessageEvent对象有三个重要属性:data用于获取数据,source用于获取发送消息的窗口对象,origin用于获取发送消息的源。
(3)document.domain
目前,很多大型网站都会使用多个子域名,而浏览器的同源策略对于它们来说就有点过于严格了。如,来自www.a.com想要获取document.a.com中的数据。只要基础域名相同,便可以通过修改document.domain为基础域名的方式来进行通信,但是需要注意的是协议和端口也必须相同。
(4)window.name
window.name这个全局属性主要是用来获取和设置窗口名称的,但是通过结合iframe也可以跨域获取数据。我们知道,每个iframe都有包裹它的window对象,而这个window是最外层窗口的子对象。所以window.name属性就可以被共享。
window对象有一个name属性,该属性有一个特征:即在一个窗口的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每一个页面对window.name都有读写的权限,window.name是持久的存在于一个窗口载入的所有页面中的,并不会因为新的页面的载入而被重置。
源页面新建iframe框架,重定向到目标页面,然后使用iframe.contentWindow.name获取数据。
数据页面中要存放的数据需要存储在window.name 属性中
**var data={msg:"hello world"};  
window.name=JSON.stringify(data);//name属性只支持字符串,支持最大2MB的数据  
(5)CORS
CORS的核心思想是通过一系列新增的HTTP头信息来实现服务器和客户端之间的通信。所以,要支持CORS,服务端都需要做好相应的配置,这样,在保证安全性的同时也更方便了前端的开发。
在服务器端返回允许跨域访问的头。


10. 请简述web storage和cookie的区别。

1 、与服务器交互 
Web Storage 中的数据仅在存在本地,不与服务器发生交互。 
Cookie 中的数据会在浏览器和服务器中来回传递。 
2 、存储空间 
Web Storage 存储空间更大,可以达到 5M ;Cookie 数据大小不超过 4KB 。 
3 、 接口 
Web Storage 提供 setItem , getItem , removeItem , clear 等方法 
Cookie 需要自己封装 setCookie , getCookie方法 
4 、跨域问题 
cookie 需要指定作用域,不可以跨域调用,但 Web Storage 可以跨域调用 
5、 存储时间 
cookie 中的数据在过期时间之前均有效, Web Storage 则不同, sessionStorage 中的 数据在当前浏览器窗口关闭后自动删除, localStorage 持久存储数据,除非主动删除数据
注: 但 Cookie 是不可以或缺的: Cookie 的作用是与服务器进行交互,作为 HTTP 规范的一部分而存在 ,而 Web Storage 仅仅是为了在本地 “ 存储 ” 更大容量数据而生。


左边固定,右边自适应的两列布局,右面的 DOM 顺序在左边前面,说下实现?

<div class="parent">
<div class="left"><p>left</p></div>
<div class="right"><p>right</p></div>
</div>
左列定宽,右列自适应
1、利用float+margin 实现
.parent{height: 200px;border: 1px dotted black;overflow: hidden;}
.left{border: 1px solid green;width:200px;height: 200px;float: left;}
.right{border: 1px solid red;margin-left:220px;height: 200px;}
//需要注意的是,左列设置左浮动,右列不设置浮动,通过margin 来实现与左列的距离。
2、通过absolute 配合left/right 进行布局:
.parent{position: relative;}
.left{position: absolute;left: 0;width: 100px;}
.right{ position: absolute;left: 120px; //比.left 的left 多出20px,相当于间隔;
right: 0;}
左列不定宽,右列自适应
1、float + BFC:
.left{float: left; width: 100px; margin-right: 20px; //形成20px 的间隔}
.right{overflow: hidden; //通过设置overflow: hidden 来触发BFC 特性}
2、table 布局:
.parent{display: table; width: 100%;table-layout: fixed;}
.left,.right{display: table-cell;}
.left{width: 100px;padding-right: 20px;}
3、flex 布局:
.parent{display: flex;}
.left{ margin-right: 20px;}
.right{ flex: 1;}
.left p{width: 200px;}

CSS box-sizing 的值有哪些?

content-box:
padding和border不被包含在定义的width和height之内。对象的实际宽度等于设置的width值和border、padding之和,即 ( Element width = width + border + padding )
此属性表现为标准模式下的盒模型。
border-box:
padding和border被包含在定义的width和height之内。对象的实际宽度就等于设置的width值,即使定义有border和padding也不会改变对象的实际宽度,即 ( Element width = width )
此属性表现为怪异模式下的盒模型。

JavaScript 的基本数据类型?

字符串string、数字number、布尔boolean、数组array、对象object、Null、Undefined

如何判断 JavaScript 数据类型?

 1) typeof 运算符 typeof 是一元运算符,返回结果是一个说明运算数类型的字符串。如:"number","string","boolean","object","function","undefined"(可用于判断变量是否存在)。 但 typeof 的能力有限,其对于Date、RegExp类型返回的都是"object"。如:typeof {}; // "object"
typeof []; // "object"
typeof new Date(); // "object"
 2)instanceof 运算符。 instanceof 运算符要求其左边的运算数是一个对象,右边的运算数是对象类的名字或构造函数。如果 object 是 class 或构造函数的实例,则 instanceof 运算符返回 true。如果 object 不是指定类或函数的实例,或者 object 为 null,则返回 false。如:
[] instanceof Array; // true
[] instanceof Object; // true
[] instanceof RegExp; // false
new Date instanceof Date; // true
3)constructor 属性。 JavaScript中,每个对象都有一个constructor属性,它引用了初始化该对象的构造函数,常用于判断未知对象的类型。如给定一个求知的值 通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。所以判断数组的函数也可以这样写:
function isArray(arr){
    return typeof arr == "object" && arr.constructor == Array;
}
很多情况下,我们可以使用instanceof运算符或对象的constructor属性来检测对象是否为数组。例如很多JavaScript框架就是使用这两种方法来判断对象是否为数组类型。 但是检测在跨框架(cross-frame)页面中的数组时,会失败。原因就是在不同框架(iframe)中创建的数组不会相互共享其prototype属性。

如何给元素添加事件?

给元素添加事件使用 JS  函数: attachEvent(),  如: attachEvent("on"+事件名称,响应函数名)
给元素添加事件使用 JS  函数: addEventListener(),  如: addEventListener(事件名称,响应函数名,false)

如何阻止事件冒泡、阻止默认行为?

防止冒泡:
w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true
stopPropagation也是事件对象(Event)的一个方法,作用是阻止目标元素的冒泡事件,但是会不阻止默认行为。什么是冒泡事件?如在一个按钮是绑定一个”click”事件,那么”click”事件会依次在它的父级元素中被触发 。stopPropagation就是阻止目标元素的事件冒泡到父级元素。
阻止默认行为:
w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;
preventDefault它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。既然是说默认行为,当然是元素必须有默认行为才能被取消,如果元素本身就没有默认行为,调用当然就无效了。什么元素有默认行为呢?如链接<a>,提交按钮<input type=”submit”>等。当Event 对象的 cancelable为false时,表示没有默认行为,这时即使有默认行为,调用preventDefault也是不会起作用的。
return false
javascript的return false只会阻止默认行为,而是用jQuery的话则既阻止默认行为又防止对象冒泡。

Header 头 Set-cookie: http-only 是干什么用的?

cookies.HTTP-Only背后的意思是告之浏览器该cookie绝不应该通过Javascript的document.cookie属性访问。设计该特征意在提供一个安全措施来帮助阻止通过Javascript发起的跨站脚本攻击(XSS)窃取cookie的行为。一旦设定这个标记,通过documen.coookie则不能再访问该cookie。IE同时更近一步并且不允许通过XMLHttpRequest的getAllResponseHeaders()或getResponseHeader()方法访问cookie,然而其它浏览器则允许此行为。你不能通过JavaScript设置HTTP-only cookies,因为你不能再通过JavaScript读取这些cookies,这是情理之中的事情。

React 组件的生命周期?父子组件之间如何通信?子组件之间如何通信?

实例化  ● componmentWillMount :
该方法会在完成首次渲染之前被执行,这也是在render方法调用前可以修改组件state的最后一次机会。
● render :
在这里你会创建一个虚拟DOM,用来表示组件的输出。对于一个组件来说,render是唯一一个必须的犯法,并且有特定的规则。render方法需要满足以下几个条件。 ○ 只能通过this.props和this.state访问数据 ○ 可以返回null、false或者任何的React组件 ○ 只能出现一个顶级组件,不能返回一组元素 ○ 必须纯净,意味着不能改变组件的状态或者修改DOM的输出
● componmentDidMount :
render方法成功执行之后,会渲染出来真实的DOM,你可以在该方法中使用this.getDOMNode()方法访问原生DOM。
存在期● componmentWillUpdate:
和componmentWillMount方法类似,组件会在接收到新的props或者state进行渲染之前,调用该方法。需要注意的是,不能在该方法中更新state或者props,而应该借助componmentWillReceiveProps方法在运行时更新state。
● componmentDidUpdate:
和componmentDidMount方法一样,我们可以在这里对已经渲染好的DOM进行更改操作。
销毁 & 清理期
● componmentWillUnmount : 在这里进行组件移除以后的一些操作。
父子组件之间如何通信?react中state改变了,组件才会update。父写好state和处理该state的函数,同时将函数名通过props属性值的形式传入子,子调用父的函数,同时引起state变化。子组件要写在父组件之前。

前端性能优化?

 content 方面
减少HTTP 请求:合并文件、CSS 精灵、inline Image
减少DNS 查询:DNS 查询完成之前浏览器不能从这个主机下载任何任何文件。方法:
DNS 缓存、将资源分布到恰当数量的主机名,平衡并行下载和DNS 查询
避免重定向:多余的中间访问
使Ajax 可缓存
非必须组件延迟加载
未来所需组件预加载
减少DOM 元素数量
将资源放到不同的域下:浏览器同时从一个域下载资源的数目有限,增加域可以提高并
行下载量
减少iframe 数量
不要404
 Server 方面
使用CDN
添加Expires 或者Cache-Control 响应头
对组件使用Gzip 压缩
配置ETag
Flush Buffer Early
Ajax 使用GET 进行请求
避免空src 的img 标签
Cookie 方面
减小cookie 大小
引入资源的域名不要包含cookie
 css 方面
将样式表放到页面顶部
不使用CSS 表达式
使用不使用@import
不使用IE 的Filter
Javascript 方面
将脚本放到页面底部
将javascript 和css 从外部引入
压缩javascript 和css
删除不需要的脚本
减少DOM 访问
合理设计事件监听器
 图片方面
优化图片:根据实际颜色需要选择色深、压缩
优化css 精灵
不要在HTML 中拉伸图片
保证favicon.ico 小并且可缓存
移动方面
保证组件小于25k

http 缓存原理?

①浏览器第一次访问服务器资源 /index.html
在浏览器中没有缓存文件,直接向服务器发送请求。
服务器返回  200 OK,实体中返回 index.html文件内容,并设置一个缓存过期时间,一个文件修改时间,一个根据index.html内容计算出来的实体标记Entity Tag,简称Etag。
浏览器将/index.html路径的请求缓存到本地。
②浏览器第二次访问服务器资源 /index.html
由于本地已经有了此路径下的缓存文件,所以这一次就不直接向服务器发送请求了。
首先,进行缓存过期判断。浏览器根据①中设置缓存过期时间判断缓存文件是否过期。
情景一:若没有过期,则不向服务器发送请求,直接使用缓存中的结果,此时我们在浏览器控制台中可以看到  200 OK(from cache) ,此时的情况就是完全使用缓存,浏览器和服务器没有任何交互的。
情景二:若已过期,则向服务器发送请求,此时请求中会带上①中设置的文件修改时间,和Etag
然后,进行资源更新判断。服务器根据浏览器传过来的文件修改时间,判断自浏览器上一次请求之后,文件是不是没有被修改过;根据Etag,判断文件内容自上一次请求之后,有没有发生变化
情形一:若两种判断的结论都是文件没有被修改过,则服务器就不给浏览器发index.html的内容了,直接告诉它,文件没有被修改过,你用你那边的缓存吧—— 304 Not Modified,此时浏览器就会从本地缓存中获取index.html的内容。此时的情况叫协议缓存,浏览器和服务器之间有一次请求交互。
情形二:若修改时间和文件内容判断有任意一个没有通过,则服务器会受理此次请求,之后的操作同①

JavaScript 的垃圾回收机制?

Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。
JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。
不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量,全局变量的生命周期直至浏览器卸载页面才会结束。局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后在函数中使用这些变量,直至函数结束,而闭包中由于内部函数的原因,外部函数并不能算是结束。

CSS BFC 原理?

BFC是Block Formatting Context的简写,中文直译为块级格式上下文。BFC就是一种布局方式,他是页面中的一块渲染区域,并且有一套的渲染规则,他决定了其子元素如何定位,以及和其他元素的关系和相互作用。通俗一点,可以把BFC理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。
触发BFC的方式(一下任意一条就可以)
1.float不为none;
2.overflow不为visibile
3.display:table-cell、table-caption、inline-block
4.posttion不为static、relative
BFC常见的四种情况
   1.浮动的元素会被父级计算高度,即清除内部浮动(父级触发了BFC)
   2.非浮动元素不会覆盖浮动元素位置,即创建自适应两栏布局(非浮动元素触发了BFC)
   3.margin不会传递给父级,即父子不齐下(父级触发了BFC)
   4.两个相邻元素上下margin会重叠,即垂直margin合并(给其中一个元素增加一个父级,然后让他的父级触发BFC)

稳定的排序和不稳定的排序?

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;否则称为不稳定的。
综上,得出结论: 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法
1)冒泡排序
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
(2)选择排序
选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n - 1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
(3)插入排序 
插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
(4)快速排序 
快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j,交换a[i]和a[j],重复上面的过程,直到i > j。 交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为5 3 3 4 3 8 9 10 11,现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j] 交换的时刻。
(5)归并排序 
归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。
(6)基数排序 
基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以其是稳定的排序算法。
(7)希尔排序(shell) 
希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小, 插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比O(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。
(8)堆排序 
我们知道堆的结构是节点i的孩子为2 * i和2 * i + 1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n 的序列,堆排序的过程是从第n / 2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n / 2 - 1, n / 2 - 2, ... 1这些个父节点选择元素时,就会破坏稳定性。有可能第n / 2个父节点交换把后面一个元素交换过去了,而第n / 2 - 1个父节点把后面一个相同的元素没 有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。
 





2. 请在ES5下实现一个继承,Child继承Parent。要求:Child要继承Parent的所有方法和属性。

答案如下:
//寄生组合式继承
function Child(){
  Parent.call(this);
}
function inheritPrototype(subType,superType) {
    var prototype = object(superType.prototype);  //创建对象
    prototype.constructor = subType; //增强对象
    subType.prototype = prototype;  //指定对象
}
function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}
inheritPrototype(Child,Parent);


9. 请编写一个Java Script函数 parseQueryString,它的用途是把URL参数解析为一个对象,如: var url =“http://witmax.cn/index.php?key0=0&key1=1&key2=2”

function parseQueryString(argu){
  var str = argu.split('?')[1];
  var result = {};
  var temp = str.split('&');
  for(var i=0; i<temp.length; i++)
  {
    var temp2 = temp[i].split('=');
    result[temp2[0]] = temp2[1];
  }
  return result;
}
var str = parseQueryString1('http://witmax.cn/index.php?key0=0&key1=1&key2=2');
console.log(str);


13. 请实现简单类型的两个数组去重,并把去重后的数据放入一个新的数组中。
var arr1 =[1, 2,  3, '0','2', '测试','重复',NaN, false];
var arr2 =[3,'1',NaN,'重复', false];

function removeDulMergeArr(arr1,arr2) {
  var arr = arr1.concat(arr2);
  arr.sort();
  console.log(arr);
  var temp = [];
  while(arr.length>0) {
    if(Object.is(arr[0],arr[1])){//ES6中严格判断两个变量是否相等,比===更严格
      arr.shift();
    }else{
      temp.push(arr.shift());
    }
  }
   console.log(temp);
}
removeDulMergeArr(arr1,arr2);


14. 封装一个函数,作用是判断一个div在当前屏幕中,可以使用jquery操作符$(提示:一个div在屏幕中可以认为是他的左边或右边在屏幕中,以及上边或下边在屏幕中)

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    #display{
      width: 50px;
      height: 50px;
      position: fixed;
      top:10px;
      background-color: yellow;
      font-size: 12px;
    }
    body{
      height: 17000px;
      width: 17000px;
    }
  </style>
  <script>
    window.onload = function(event) {
      var display = document.getElementById("display");
      var ele = document.getElementById("secend");
     window.onscroll = function () {
        var rect = ele.getBoundingClientRect();
        if (rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
          rect.bottom >=0 &&
          rect.right  >=0  &&
          rect.left<= (window.innerWidth || document.documentElement.clientWidth)) {
          display.innerHTML = "div在可视范围";
        } else {
          display.innerHTML = "div不在可视范围";
        }
      }
    }
  </script>
</head>
<body>
<div id="display"></div>
<div id="first" style="height: 700px;width: 700px;background: green"></div>
<div id="secend" style="height: 200px;width: 200px;background: red"></div>
</body>
</html>


16. 画出一个内半径为10px,外边框白色1px的纯红色圆圈,请写出css代码,className随意。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <style>
    .container{
      width: 10px;
      height: 10px;
      border: 1px solid white;
      border-radius:50%;//生成圆
      background-color: red;
      background-clip: padding-box;/*主要考察背景颜色不填充边框,应该使用的属性*/
    }
  </style>
</head>
<body>
   <div class="container">
   </div>
</body>
</html>
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值