微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!
前端面试(算法篇) - 二分法
前段时间换了份工作,也经历了很多面试,最终通常都会扑在算法上虽说前端是所有程序员中,对于算法的要求最低的一个岗位,但算法依旧是进阶的必修课于是决定记录一下与算法相关的面试题,以后拿去面别人 一、面试题问:有一个一百层的高楼,现在给你两个完全一样的玻璃球,去测出在哪一层楼把球扔出去,刚好能把玻璃球砸碎?答:emmmmmm问:球碎了就没法用了答:那如果没碎呢?问:emmmmmm答:啊哈,那就拿着球从一楼往上,一层一层的试呗~问:好,那现在不限制球的数量,但要求用最少的次数,去找到这个临界点答:二分法!从中间的楼层开始扔球,如果碎了就在下面的楼层中继续找问:没错,二分法是最快的解决方案,但如果遇到最差的情况,需要用几个球呢?答:我数一数问:……答:……问:算了,下一个问题吧 二、二分法使用二分法的前提是,目标数组的元素必须是有序排列的,所以二分法属于有序查找算法二分法又称为“折半查找”,从数组的中间节点开始查找,将数组分为两部分如果目标元素和中间节点不相等,就通过比较两者的大小,确定接下来查找数组的前半部分还是后半部分然后递归查找,直到找到目标元素,或者发现目标元素不在数组内在最坏的情况下,需要的次数为:(log2 n)+1 ,其中 log2n 向下取整function BinarySearch(arr, target) {let s = 0;let e = arr.length - 1;let m = Math.floor((s + e) / 2);let trun = arr[s] <= arr[e]; //确定排序顺序while (s < e && arr[m] !== target) {if (arr[m] > target) {trun ? (e = m - 1) : (s = m + 1)} else {trun ? (s = m + 1) : (e = m - 1)}m = Math.floor((s + e) / 2);}if (arr[m] == target) {console.log('找到了,位置%s', m, t);return m;} else {console.log('没找到', t);return -1;}} 三、问题拓展1. 用二分法遇到最坏的情况,需要 6 次 还是 7 次?2. 如果只有两个球,怎么才能用最少的次数,找到临界点? 
前端面试(算法篇) - 约塞夫环
在上一篇《前端面试 - 算法篇(二分法)》的评论中,有朋友提出了一个“循环杀人游戏”就在我为之苦恼的时候,一位同事在我身旁经过,突然说了一句:“咦,这不是约塞夫问题吗?” 一、面试题原题目不太明朗(一号到底杀不杀?)于是把题目优化一下,更接近于原本的约塞夫问题假设有100人,分别编号 1~100从 1 号开始报数,报数到 3 号时,3 号就被淘汰,然后由下一人从 1 报数,以此类推最后谁会活下来? 二、面向过程最开始我按照自己的思路,模拟了整个过程虽然能解决问题,但一旦遇到较大的数据量,查询的次数太多,性能太低不过这种方法最容易理解/*** 面向过程的约塞夫环解决办法* @param {Array} peoples 参与游戏的数组* @param {Number} kill 淘汰的报数数字* @return {Object} 幸存者*/function killer(peoples, kill) {let flag = 0 // 初始化报数while(peoples.length > 1) { // 只剩下一个人时,循环结束let len = peoples.length // 剩余人数let out = 0 // 已淘汰的人数for (let i = 0; i < len; i++) {flag++ // 报数+1if (kill == flag) { // 当报数到指定数字,淘汰该玩家// 淘汰后剩余人数(数组)会发生变化,所以被淘汰玩家下标应为 i-outpeoples.splice(i-out, 1)flag = 0 // 重置报数out++ // 淘汰人数+1}}}return peoples[0]} 二、面向对象在数据结构中,具有链式存储结构的线性表被称为链表其特点是每个数据元素在存储本身的信息之外,还要存储其直接后继的信息数据元素之间不要求在存储空间中连续而当这些数据元素构成一个逻辑上的环,任意元素都有一个前驱和后继,这就构成了一个循环链表 在这个游戏中,可以将玩家抽象成一个对象,然后由玩家组成了一个环根据循环链表的特性,每个玩家除了存储本身的信息(编号),还需要存储前后的编号class Player { // 创建玩家constructor(n) {this.index = n; // 玩家编号this.before = {}; // 前一个玩家this.after = {}; // 后一个玩家}} 然后分析整个环,除了构造函数之外,还应当具备淘汰玩家、开始游戏的功能为了保证环的完整,需要一个起点和一个终点,这两个点在逻辑上是相邻的在整个游戏过程中,我们只需要关心环的完整(起点、终点、玩家的前驱与后继)就可以了/*** 面向对象的约塞夫环解决办法* @param {Number} length 玩家总数* @param {Number} kill 淘汰的报数数字* @return*/class Cycle { // 创建循环链表constructor (length) {this.count = 0; // 玩家总数this.start = new Player(1) // 链表起点this.end = new Player(length) // 链表终点for(let i = 1; i <= length; i++) {// 创建玩家let player = new Player(i)this.count++if (this.count <= 1) {// 只有一个玩家的时候,起点和终点为同一个玩家this.start = this.end = player} else {// 新创建的玩家一定位于链表终点之后this.end.after = playerplayer.before = this.end// 而该玩家即为新的链表终点this.start.before = playerplayer.after = this.startthis.end = player}}}delete (player) {if (this.count <= 1) { // 错误校验this.start = this.end = nullreturn} else {// 将前后的玩家关联起来player.before.after = player.afterplayer.after.before = player.before// 如果处于终点或起点,则修改相关信息if (player == this.start) {this.start = player.after} else if(player == this.end) {this.end = player.before}}// 淘汰该玩家player = nullthis.count--}play (kill) {let flag = 0 // 初始化报数let k = this.start // 从起点开始游戏while (this.count > 1) { // 只剩一个玩家,循环结束flag++if (flag == kill) { // 报数到目标数字,淘汰玩家flag = 0this.delete(k)}// 无论淘汰与否,让下一个玩家报数k = k.after}return `幸存者:${k.index}`}}new Cycle(100).play(3)  三、递归算法 在吃透了整个游戏规则之后。。。function Joseph(sum, value, n) {if ( n==1 ) {return ( sum + value - 1) % sum;} else {return ( Joseph( sum - 1, value, n - 1) + value ) % sum;}}console.log("剩下的人号数为:" + (Joseph(100, 3, 100) + 1))emmmmmmmmmm难怪《美丽心里》里开头就说,是数学家改变了世界  四、问题拓展1. 如何用 js 快速创建一个 1~100 的数组?2. 如果报数到 2 就淘汰,最后剩下谁?
前端面试(原生js篇) - DOM
根据我的面试经历,一般小公司的面试环节,比较关心框架的熟练程度,以及独立开发组件的能力但大厂通常有五轮以上的面试,而且对 js 基础语法很是看重于是我总结了一些关于 js 基础的面试对话,有的当时没答上来,就在总结的时候就加了点料忽然觉得又该读一遍犀牛书了... 一、面试对话问:你知道 js 是由哪三部分构成的么?答:有 js 的语法核心 ECMAScript,还有文档对象模型 DOM,以及浏览器对象模型 BOM。问:那你觉得 dom 的作用是什么?答:喵喵喵???问:我换一个问法吧,如果没有 DOM,会对开发有什么影响?答:那根本没法开发啊。前端的主要工作有两个,一个是高保真的实现 UI 设计稿,一个是高效率的从后端获取数据并渲染到页面上。如果没有 DOM,就不能渲染页面了。问:但实际上所谓的渲染页面,就是返回一堆 html,你觉得 html 和 DOM 有区别么?答:html 说穿了就是一个字符串,浏览器解析 html 并抽象成一个树结构的文档对象,以方便 js 操作,这个文档对象这就是 dom。问:好的,现在我有一个 <ul> 标签,里面有 5 个 <li> 标签,怎样才能在最后一个 <li> 标签后再插入一个 <li> 标签?答:用 getElementById 或者 getElementsByClassName 之类的方法获取 <ul> 节点,然后用 append() 插入 <li> 标签。问:append() 是 jQuery 的方法吧,如果不用 jQuery 呢?答:啊咧?append() 是 jQuery 的方法么?答:哦哦,那就用 appendChild() 方法,而且得先用 createElement() 创建标签。问:如果要加在第一个 <li> 前面呢?答:那就用 prepend() 问:嗯?答:哎呀,prepend() 也是 jQuery 的方法,应该用 prependChild() 问:喵喵喵??你特么在逗我?有这个方法吗?答:开个玩笑开个玩笑,其实是 insertBefore() 方法。问:没错,insertBefore() 可以在目标元素前面插入一个新元素,如果要把元素放在目标元素之后呢?答:emmmmm... insertAfter() ?问:js 中并没有这个方法!再好好想想?答:还是用 insertBefore() 方法,第二个参数传入目标元素的下一个元素,也就是 targetElement.nextSibling问:dom 操作挺熟练哈,工作中经常这么搞么?答:(擦一擦汗)没有没有,工作中 vue 用的比较多,数据驱动,不怎么关心 DOM问:常用 vue,那你一定知道虚拟 DOM 了吧?说说看呢答:每一次 DOM 的变动,浏览器就得重新渲染一次页面。为了提高页面的性能,就应该尽量减少 DOM 的变更次数。现代框架通常会用一个对象来保存目标 DOM 节点的标签名、属性、内容、子节点等信息,也就是用 js 的对象结构来表示 DOM 树的结构,这个 js 对象就是虚拟 DOM。当状态变更的时候,js 会先更新虚拟 DOM,再通过 diff 算法比较虚拟 DOM 和真实 DOM 的差异,找出最少变更的方案,最后一并更新到真实 DOM 中。问:(邪魅一笑)所以使用虚拟 DOM 的主要目的是为了提高性能是吧?答:对啊,vue 的优点之一就是轻量化,渲染速度快,就是因为采用了虚拟 DOM。问:但是虚拟 DOM 最终同样也是操作真实 DOM,为什么会更快呢?答:如果全程操作真实 DOM 的话,任何一个状态的变更,都会导致页面重绘,这个环节就非常耗性能了。采用虚拟 DOM 的话,就能避免这个问题。而且如果 diff 算法效率高的话,总是能用最少的改动来更新 DOM。总的来说,就是不会出现频繁的、大面积的 DOM 操作,从而提升了页面性能。问:让我们进入下一个问题...  二、注释  1. DOM:Document Object Model  文档对象模型 2. BOM:Browser Object Model  浏览器对象模型 3. insertBefore() 方法:该方法需要父元素 parentElement 调用,并接收两个参数,第一个参数是需要插入的元素 newElement,第二个是目标元素 targetElement。parentElement.insertBefore(newElement, targetElement)
前端面试(原生js篇) - 精确运算
一、面试题问:开发的时候有用到过 Math 吗?答:很多啊。比如生成 GUID 的时候,就会用到 Math.random() 来生成随机数。问:别的呢?比如向下取整、向上取整?答:向下取整是 floor(),向上取整是 ceil()。另外还可以用 round() 方法进行四舍五入的取整。问:如果我需要四舍五入并保留两位小数,应该怎么处理呢?答:可以直接用 toFixed() 方法,然后在方法中传入 2,以保留两位小数。问:那数字 1.335 通过 toFixed(2) 计算后,结果是什么呢?答:1.34 啊。问:哦?那 0.1 + 0.2 等于多少呢?答:阿咧?难道不是 0.3 么...问:emmmmmm...答:......问:js 在处理十进制计算的时候,会先转为二进制,计算之后再转回十进制。如果这个数是浮点数,就很容易出现误差。   答:原来如此!问:在了解了这个情况之后,你能写一个精确计算的方法么? 二、优化 toFixed()由于二进制的原因,如果只是简单的放大缩小倍率,得到的结果都是不完美的比如很多人推荐的:Math.formatFloat = function (f, digit) {var m = Math.pow(10, digit);return Math.round(f * m, 10) / m;}在处理 8716.425 这个数的时候就会出错 经过多次尝试和查阅资料,我强烈推荐 Scott 大神的 toFixed() 方法,原链接:http://www.chengfeilong.com/toFixed可以先手动找到舍入位,如果该位置大于5,则手动进位,并去掉舍入位及其后面的所有字符Number.prototype.toFixed = function(length) {var carry = 0; //存放进位标志var num,multiple; //num为原浮点数放大multiple倍后的数,multiple为10的length次方var str = this + ''; //将调用该方法的数字转为字符串var dot = str.indexOf("."); //找到小数点的位置if(str.substr(dot+length+1,1)>=5) carry=1; //找到要进行舍入的数的位置,手动判断是否大于等于5,满足条件进位标志置为1multiple = Math.pow(10,length); //设置浮点数要扩大的倍数num = Math.floor(this * multiple) + carry; //去掉舍入位后的所有数,然后加上我们的手动进位数var result = num/multiple + ''; //将进位后的整数再缩小为原浮点数/** 处理进位后无小数*/dot = result.indexOf(".");if(dot < 0){result += '.';dot = result.indexOf(".");}/** 处理多次进位*/var len = result.length - (dot+1);if(len < length){for(var i = 0; i < length - len; i++){result += 0;}}return result;}这个方法我暂时没有发现有错误处理的数字。如果有小伙伴发现了,一定留言告诉我在进行浮点数运算的时候,即使计算结果不精确,也可以用这个方法对结果进行四舍五入操作,得到最终结果 三、大数相加在 js 中,对于超大整数的运算,还存在格式问题当数字超出某个范围的时候,数字会自动转为科学计数法这个时候如果还需要输出常规格式,就需要将数字转为字符串,然后实现一个字符串加法function sumNumber(a, b) {var res = '', temp = 0;a = a.split('');b = b.split('');while (a.length || b.length || temp) {temp += ~~a.pop() + ~~b.pop();res = (temp % 10) + res;temp = temp > 9;}return res.replace(/^0+/, '');}来源:https://www.cnblogs.com/kindofblue/p/4672129.html这个方法的入参必须为整型的字符串,然后从个位开始,逐位相加,最后返回字符串 相关:http://0.30000000000000004.com/ 
web前端知识点1
1. input属于窗体元素,层级显示比flash、其它元素都高。请判断这句话的正确与否。 错误层级显示优先级: frameset > 表单元素 > 非表单元素在html中,帧元素(frameset)的优先级最高,表单元素比非表单元素的优先级要高。表单元素包括:文本输入框,密码输入框,单选框,复选框,文本输入域,列表框等等;非表单元素包括:链接(a),div,table,span等。所有的html元素又可以根据其显示分成两类:有窗口元素以及无窗口元素。有窗口元 素总是显示在无窗口元素的前面。有窗口元素包括:select元素,object元素,以及frames元素等等。无窗口元素:大部分html元素都是无窗口元素。2.栅格系统的标准用法(使用规则)1) 数据行(.row)必须包含在容器(.container)中,以便为其赋予合适的对齐方式和内边距。2) 在行(.row)中可以添加列(.column),但列数之和不能超过平分的总列数,比如12。3) 具体内容应当放置在列容器之内,而且只有列才可以作为行容器(.row)的直接子元素4) 通过设置内边距从而创建列与列之间的间距。然后通过为第一列和最后一列设置负值的外距来抵消内距的影响3. html5标签<audio> 标签定义声音,比如音乐或其他音频流<video> 标签定义视频,比如电影片段或其他视频流。<canvas> 标签定义图形,比如图表和其他图像。<canvas> 标签只是图形容器,您必须使用脚本来绘制图形。<article> 标签规定独立的自包含内容。一篇文章应有其自身的意义,应该有可能独立于站点的其余部分对其进行分发。<article> 元素的潜在来源:l 论坛帖子l 报纸文章l 博客条目l 用户评论command 元素表示用户能够调用的命令。<command> 标签可以定义命令按钮,比如单选按钮、复选框或按钮。只有当 command 元素位于 menu 元素内时,该元素才是可见的。否则不会显示这个 元素,但是可以用它规定键盘快捷键。<menu> 标签定义命令的列表或菜单。<menu> 标签用于上下文菜单、工具栏以及用于列出表单控件和命令。4. CSS3新增属性用法整理box-shadow(阴影效果)border-color(为边框设置多种颜色)border-image(图片边框)text-shadow(文本阴影)text-overflow(文本截断)word-wrap(自动换行)border-radius(圆角边框)opacity(透明度)box-sizing(控制盒模型的组成模式)resize(元素缩放)outline(外边框)background-size(指定背景图片尺寸)background-origin(指定背景图片从哪里开始显示)background-clip(指定背景图片从什么位置开始裁剪)background(为一个元素指定多个背景)hsl(通过色调、饱和度、亮度来指定颜色颜色值)hsla(在hsl的基础上增加透明度设置)rgba(基于rgb设置颜色,a设置透明度)5. 关于http协议简介 HTTP协议(Hyper Text Transfer Protocol,超文本传输协议),是用于从 万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协 议。HTTP基于TCP/IP通信协议来传递数据。HTTP基于客户端/服务端(C/S)架构模型,通过一个可靠的链接来交换信息, 是一个无状态的请求/响应协议。特点 (1)HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。服务 器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可 以节省传输时间。(2)HTTP是媒体独立的:只要客户端和服务器知道如何处理的数据内容, 任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的 MIME-type内容类型。(3)HTTP是无状态:无状态是指协议对于事务处理没有记忆能力。缺少状 态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次 连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就 较快。通信流程 消息结构 HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和 建立连接。一旦建立连接后,数据消息就通过类似Internet邮件所使用的格 式[RFC5322]和多用途Internet邮件扩展(MIME)[RFC2045]来传送。客户端请求消息:请求行、请求头部、空行和请求数据。GET /hello.txt HTTP/1.1 User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3 Host: www.example.com Accept-Language: en, mi 服务端响应消息:状态行、消息报头、空行和响应正文。HTTP/1.1 200 OKDate: Mon, 27 Jul 2009 12:28:53 GMTServer: ApacheLast-Modified: Wed, 22 Jul 2009 19:15:56 GMTETag: "34aa387-d-1568eb00"Accept-Ranges: bytesContent-Length: 51Vary: Accept-EncodingContent-Type: text/plain请求方法 GET 请求指定的页面信息,并返回实体主体。HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取 报头POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。 数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资 源的修改。PUT 从客户端向服务器传送的数据取代指定的文档的内容。DELETE 请求服务器删除指定的页面。CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。OPTIONS允许客户端查看服务器的性能。TRACE  回显服务器收到的请求,主要用于测试或诊断。状态码 HTTP状态码分类 1** 信息,服务器收到请求,需要请求者继续执行操作2** 成功,操作被成功接收并处理3** 重定向,需要进一步的操作以完成请求4** 客户端错误,请求包含语法错误或无法完成请求5** 服务器错误,服务器在处理请求的过程中发生了错HTTP状态码列表 100 Continue    继续。客户端应继续其请求101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。 只能切换到更高级的协议,例如,切换到HTTP的新版本协议200 OK  请求成功。一般用于GET与POST请求 201 Created 已创建。成功请求并创建了新的资源202 Accepted    已接受。已经接受请求,但未处理完成203 Non-Authoritative Information   非授权信息。请求成功。但返回 的meta信息不在原始的服务器,而是一个副本204 No Content  无内容。服务器成功处理,但未返回内容。在未更新网 页的情况下,可确保浏览器继续显示当前文档205 Reset Content   重置内容。服务器处理成功,用户终端(例如:浏 览器)应重置文档视图。可通过此返回码清除浏览器的表单域206 Partial Content 部分内容。服务器成功处理了部分GET请求300 Multiple Choices    多种选择。请求的资源可包括多个位置,相应 可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择301 Moved Permanently   永久移动。请求的资源已被永久的移动到新URI, 返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求 都应使用新的URI代替 302 Found   临时移动。与301类似。但资源只是临时被移动。客户端应 继续使用原有URI303 See Other   查看其它地址。与301类似。使用GET和POST请求查看304 Not Modified    未修改。所请求的资源未修改,服务器返回此状态 码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个 头信息指出客户端希望只返回在指定日期之后修改的资源 305 Use Proxy   使用代理。所请求的资源必须通过代理访问306 Unused  已经被废弃的HTTP状态码307 Temporary Redirect  临时重定向。与302类似。使用GET请求重定 向 400 Bad Request 客户端请求的语法错误,服务器无法理解401 Unauthorized    请求要求用户的身份认证402 Payment Required    保留,将来使用403 Forbidden   服务器理解请求客户端的请求,但是拒绝执行此请求404 Not Found   服务器无法根据客户端的请求找到资源(网页)。通过 此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 405 Method Not Allowed  客户端请求中的方法被禁止406 Not Acceptable  服务器无法根据客户端请求的内容特性完成请求407 Proxy Authentication Required   请求要求代理的身份认证,与401 类似,但请求者应当使用代理进行授权408 Request Time-out    服务器等待客户端发送的请求时间过长,超时409 Conflict    服务器完成客户端的PUT请求是可能返回此代码,服务 器处理请求时发生了冲突410 Gone    客户端请求的资源已经不存在。410不同于404,如果资源 以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指 定资源的新位置411 Length Required 服务器无法处理客户端发送的不带Content-Length 的请求信息412 Precondition Failed 客户端请求信息的先决条件错误413 Request Entity Too Large    由于请求的实体过大,服务器无法处 理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如 果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息414 Request-URI Too Large   请求的URI过长(URI通常为网址),服务 器无法处理415 Unsupported Media Type  服务器无法处理请求附带的媒体格式416 Requested range not satisfiable 客户端请求的范围无效417 Expectation Failed  服务器无法满足Expect的请求头信息500 Internal Server Error   服务器内部错误,无法完成请求 501 Not Implemented 服务器不支持请求的功能,无法完成请求502 Bad Gateway 充当网关或代理的服务器,从远端服务器接收到了一个无 效的请求503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客 户端的请求。延时的长度可包含在服务器的Retry-After头信息中504 Gateway Time-out    充当网关或代理的服务器,未及时从远端服务 器获取请求505 HTTP Version not supported  服务器不支持请求的HTTP协议的版本, 无法完成处理6.关于盒子模型 盒模型从里向外由content,padding,border,margin组成。盒模型是有两种标准的,一个是标准盒模型,一个是IE盒模型。标准模型的宽高是内容(content)的宽高,IE模型的宽高是内容(content)+内边距(padding)+边框(border)的总宽高。7. Bootstrap情景文
web前端常见面试题
1、什么是盒子模型?CSS 盒模型(Box Model),又称框模型。它包括:content、padding、border、margin,所有HTML元素都可以看作盒子。注: 当通过CSS指定一个元素的宽度和高度属性时,只是设置了实际内容区域的宽度和高度。一旦为页面设置了恰当的 DTD,浏览器会使用标准盒模型(标准模式),而DTD缺失则在ie6,ie7,ie8下将会使用IE盒模型(怪异模式)。标准盒模型 元素总宽度 = width + (padding + border + margin)* 2IE盒模型   元素总宽度 = width + margin * 2 2、行内元素有哪些?块级元素有哪些? 空(void)元素有那些?行内元素:a、b、span、img、input、strong、select、label、em、button、textarea块级元素:div、form、ul、li、dl、dt、dd、p、h1-h6、blockquote空元素:即系没有内容的HTML元素,例如: meta、link 、br、hr、input、img 3、CSS实现垂直水平居中方法一:给元素设置一个显示宽度,并设置左右margin为auto方法二:父元素设置相对定位position: relative;子元素设置绝对定位,并设置top、left、margin-top、margin-left等属性       position:absolute;       top:50%;       left:50%       margin-top:-(高度 / 2)       margin-left:-(宽度 / 2)方法三:父元素设置相对定位position: relative;子元素设置绝对定位,并设置top、left、margin-top、margin-left等属性       position:absolute;       top:50%;       left:50%       transform:translate(-50%, -50%);      // translate的参数会以自身的长宽做参考方法四:内联元素水平居中利用 text-align:center; 可以实现在块级元素内部的内联元素水平居中。此方法对内联元素(inline), 内联块(inline-block), 内联表(inline-table), inline-flex元素水平居中都有效。 4、简述一下src与href的区别href (Hypertext Reference) 超文本引用,用在link和a等元素上,指向网络资源所在位置,建立与当前元素或当前文档之间的超链接。src指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。  补充:link和@import的区别两者都是外部引用CSS的方式,但是存在一定的区别。区别1:link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。区别2:link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。区别3:link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。区别4:link支持使用Javascript控制DOM去改变样式;而@import不支持。 5、什么是CSS Hack?一般来说是针对不同的浏览器写不同的CSS,就是 CSS Hack。IE浏览器Hack一般又分为三种,条件Hack、属性级Hack、选择符Hack(详细参考CSS文档:css文档)。例如:    // 1、条件Hack   <!--[if IE]>      <style>            .test{color:red;}      </style>   <![endif]-->   // 2、属性Hack    .test{    color:#0909; /* For IE8+ */    *color:#f00;  /* For IE7 and earlier */    _color:#ff0;  /* For IE6 and earlier */    }   // 3、选择符Hack    * html .test{color:#090;}       /* For IE6 and earlier */    * + html .test{color:#ff0;}     /* For IE7 */6、简述同步和异步的区别同步是阻塞模式,异步是非阻塞模式。同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。7、px和em的区别px和em都是长度单位,区别是,px的值是固定的,指定是多少就是多少,计算比较容易。em的值不是固定的,并且em会继承父级元素的字体大小。浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em8、什么叫优雅降级和渐进增强?渐进增强 progressive enhancement:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。优雅降级 graceful degradation:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。区别:a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带 9、浏览器的内核分别是什么?IE: trident内核Firefox:gecko内核Safari:webkit内核Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核Chrome:Blink(基于webkit,Google与Opera Software共同开发) 10、怎样添加、移除、移动、复制、创建和查找节点?1)创建新节点createDocumentFragment() //创建一个DOM片段createElement() //创建一个具体的元素createTextNode() //创建一个文本节点2)添加、移除、替换、插入parentnode.appendChild(newnode) //添加parentnode.removeChild(oldnode) //移除parentnode.replaceChild(newnode, oldnode) //替换parentnode.insertBefore(newnode, oldnode) //插入3)查找getElementsByTagName() //通过标签名称getElementsByName() //通过元素的Name属性的值getElementById() //通过元素Id,唯一性 11、如何消除一个数组里面重复的元素?方法一:var arr1 =[1,2,2,2,3,3,3,4,5,6], arr2 = [];    for (var i = 0, len = arr1.length; i < len; i++ ) {       if (arr2.indexOf(arr1[i]) < 0) {           arr2.push(arr1[i]);       }}console.log(arr2);     var arr1 =[1,2,2,2,3,3,3,4,5,6], arr2 = [];   arr1.forEach(function (item, index) {       if (arr2.indexOf(item) < 0) {           arr2.push(item);       }})console.log(arr2);方法二:var arr1 =[1,2,2,2,3,3,3,4,5,6], arr2 = [];   arr1.sort(function (a, b) {       return a - b;   })    for (var i = 0, len = arr1.length; i < len; i++) {       if (arr1[i] != arr1[i + 1]) {           arr2.push(arr1[i]);       }   }   console.log(arr2); 12、实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制。typeof能返回六种数据类型,undefined、number、string、boolean、object、function    function clone(obj) {       var o;       switch(typeof obj) {           case "undefined":                break;           case "string":                o = obj;                break;           case "number":                o = obj;                break;           case "boolean":                o = obj;                break;           case "object":                if (obj === null) {                    o = null;                } else if(obj.constructor === Array) {                    o = [];                    obj.forEach(function (item, index) {                        o[index] = clone(item);                    })                } else {                    o = {};                    for (var key in obj) {                        o[key] =clone(obj[key]);                    }                }                break;           default:                o = obj;                break;       }       return o;   } 13、javascript中的call、apply、bind参考:https://www.cnblogs.com/coco1s/p/4833199.htmlapply 、 call 、bind 三者都是用来改变函数的this对象的指向;apply 、 call 、bi