请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

快捷登录

手机动态码快速登录

手机号快速注册登录

2022-9-26 20:26:05 · 音箱设备

Web前端面试题整合,持续更新【建议收藏】

饭后闲来无事,把这几年带学生用的一些面试题整合一下,供上!拿走,不客气!应付一般公司的一面、二面基本上是够用了。祝你早日拿到心仪的offer。


css相关


1. 万能居中
1.margin: 0 auto;水平
2.text-align: center;水平
3.行高,垂直
4.表格,center,middle;水平垂直
5.display:table-cell;模拟表格,all
6.绝对定位,50%减自身宽高
7.绝对定位,上下左右全0,margin:auto
8.绝对定位加相对定位。不需要知道宽高
9.IE6,IE7:给父元素设一个font-size:高度/1.14,vertical-align:middle
2. BFC优化
块格式化上下文, 特性:
•    使 BFC 内部浮动元素不会到处乱跑(清除浮动);
•    和浮动元素产生边界(在非浮动元素加margin)。
3. 盒模型哪两种模式?什么区别?如何设置
•    标准模式: box-sizing: content-box(默认); 宽高不包括内边距和边框
•    怪异模式: box-sizing: border-box
4. 常用清除浮动的方法,如不清除浮动会怎样?
当父元素不给高度的时候,内部元素不浮动时会撑开, 而浮动的时候,父元素变成一条线, 造成塌陷.
•    额外标签法(在最后一个浮动标签后,新加一个标签,给其设置clear:both;)(不推荐)
•    父元素添加overflow:hidden; (触发BFC)
•    使用after伪元素清除浮动(推荐使用)
•    使用before和after双伪元素清除浮动
5. 删格化的原理
比如antd的row和col, 将一行等分为24份, col是几就占几份, 底层按百分比实现; 结合媒体查询, 可以实现响应式
6. 纯css实现三角形
// 通过设置border.box
        {
            width:0px;
            height:0px;
            border-top:50px solid rgba(0,0,0,0);
            border-right:50px solid  rgba(0,0,0,0);
            border-bottom:50px solid green;
            border-left:50px solid  rgba(0,0,0,0);
            }
7. 高度不定,宽100%,内一div高不确定,如何实现垂直居中?
•    verticle-align: middle;
•    绝对定位50%加translateY(-50%)
•    绝对定位,上下左右全0,margin:auto
8. 至少两种方式实现自适应布局
•    rem, em
•    vh, vw
•    百分比
•    媒体查询
•    bs, antd等的栅格布局
9. 设置一段文字的大小为6px
•    谷歌最小12px, 其他浏览器可以更小
•    通过transform: scale实现
10. css菊花图
四个小圆点一直旋转
// 父标签
animation: antRotate 1.2s infinite linear;// 子标签
animation: antSpin 1s infinite linear;@keyframe antSpin {
  to {
    opacity: 1
  }}@keyframe antRotate {
  to {
    transform: rotate(405)
  }}// animation-delay: 逐个延迟0.4s
11. 关于em
<div style="font-size: 20px">
      123
      <div style="font-size: 2em;width: 2em">456</div>
</div>
// 此时子元素的font-size为40px, 宽度为80px(还要乘以子元素font-size的系数)
12. 关于vh, vw
vw:viewpoint width,视窗宽度,1vw等于视窗宽度的1%。
vh:viewpoint height,视窗高度,1vh等于视窗高度的1%。
vmin:vw和vh中较小的那个。
vmax:vw和vh中较大的那个。
13. Flex布局
•    flex-direction控制主副轴
•    flex-wrap控制换行(默认不换行)
•    flex-flow是上两个的结合
•    justify-content主轴对齐方式
•    align-items交叉轴对齐方式
14. overflow原理
•    overflow: hidden能清除块内子元素的浮动影响. 因为该属性进行超出隐藏时需要计算盒子内所有元素的高度, 所以会隐式清除浮动
•    创建BFC条件(满足一个):
o    float的值不为none;
o    overflow的值不为visible;
o    position的值为fixed / absolute;
o    display的值为table-cell / table-caption / inline-block / flex / inline-flex。
15. 实现自适应的正方形:
•    使用vw, vh
•    width百分比, height: 0, padding-top(bottom): 50%
16. 标准模式和怪异模式
•    document.compatMode属性可以判断是否是标准模式,当 document.compatMode为“CSS1Compat”,是标准模式,“BackCompat”是怪异模式。
•    怪异模式是为了兼容旧版本的浏览器, 因为IE低版本document.documentElement.clientWidth获取不到
•    怪异模式盒模型: box-sizing: border-box; 标准模式: box-sizing: content-box
17. CSS3实现环形进度条
两个对半矩形遮罩, 使用rotate以及overflow: hidden进行旋转
18. css优先级
选择器的特殊性值表述为4个部分,用0,0,0,0表示。
•    ID选择器的特殊性值,加0,1,0,0。
•    类选择器、属性选择器或伪类,加0,0,1,0。
•    元素和伪元素,加0,0,0,1。
•    通配选择器*对特殊性没有贡献,即0,0,0,0。
•    最后比较特殊的一个标志!important(权重),它没有特殊性值,但它的优先级是最高的,为了方便记忆,可以认为它的特殊性值为1,0,0,0,0。

JS相关



1. ES5和ES6继承方式区别
•    ES5定义类以函数形式, 以prototype来实现继承
•    ES6以class形式定义类, 以extend形式继承
2. Generator了解
ES6 提供的一种异步编程解决方案, Generator 函数是一个状态机,封装了多个内部状态。
function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';}
var hw = helloWorldGenerator();
调用后返回指向内部状态的指针, 调用next()才会移向下一个状态, 参数:
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
3. 手写Promise实现
var myPromise = new Promise((resolve, reject) => {
  // 需要执行的代码
  ...
  if (/* 异步执行成功 */) {
    resolve(value)
  } else if (/* 异步执行失败 */) {
    reject(error)
  }})
myPromise.then((value) => {
  // 成功后调用, 使用value值}, (error) => {
  // 失败后调用, 获取错误信息error})
4. Promise优缺点
•    优点: 解决回调地狱, 对异步任务写法更标准化与简洁化
•    缺点: 首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消; 其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部; 第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成).
极简版promise封装:
function promise () {
  this.msg = '' // 存放value和error
  this.status = 'pending'
  var that = this
  var process = arguments[0]
  process (function () {
    that.status = 'fulfilled'
    that.msg = arguments[0]
  }, function () {
    that.status = 'rejected'
    that.msg = arguments[0]
  })
  return this}
promise.prototype.then = function () {
  if (this.status === 'fulfilled') {
    arguments[0](this.msg)
  } else if (this.status === 'rejected' && arguments[1]) {
    arguments[1](this.msg)
  }}
5. 观察者模式
又称发布-订阅模式, 举例子说明.
实现: 发布者管理订阅者队列, 并有新消息推送功能. 订阅者仅关注更新就行
6. 手写实现bind
Function.prototype.bind = function () {
   // 保存原函数
  var self = this
  // 取出第一个参数作为上下文, 相当于[].shift.call(arguments)
  var context = Array.prototype.shift.call(arguments)
  // 取剩余的参数作为arg; 因为arguments是伪数组, 所以要转化为数组才能使用数组方法
  var arg = Array.prototype.slice.call(arguments)
  // 返回一个新函数
  return function () {
    // 绑定上下文并传参
    self.apply(context, Array.prototype.concat.call(arg, Array.prototype.slice.call(arguments)))
  }}
7. 手写实现4种继承
function Father () {}function Child () {}// 1. 原型继承
Child.prototype = new Father()// 2. 构造继承function Child (name) {
  Father.call(this, name)}// 3. 组合继承function Child (name) {
  Father.call(this, name)}
Child.prototype = new Father()// 4. 寄生继承function cloneObj (o) {
  var clone = object.create(o)
  clone.sayName = ...
  return clone}// 5. 寄生组合继承// 6. ES6 class extend继承
9. http状态码
•    1**: 服务器收到请求, 需请求者进一步操作
•    2**: 请求成功
•    3**: 重定向, 资源被转移到其他URL了
•    4**: 客户端错误, 请求语法错误或没有找到相应资源
•    5**: 服务端错误, server error
•    304: Not Modified. 指定日期后未修改, 不返回资源
10. Object.create实现(原型式继承,特点:实例的proto指向构造函数本身)
11. async和await:(ES8)
•    Generator函数的语法糖,将*改成async,将yield换成await。
•    是对Generator函数的改进, 返回promise。
•    异步写法同步化,遇到await先返回,执行完异步再执行接下来的.
•    内置执行器, 无需next()
12. 算法和数据结构:
•    算法:
解决具体问题所需要的解决方法。执行效率最快的最优算法。时间复杂度。输入,输出,有穷性,确定性,可行性。冒泡排序,二叉树遍历,最长回文,二分查找,指针,链表等,堆栈,队列等。力扣,codewar,算法导论。
•    数据结构:
逻辑结构:集合、线性、树形、图形结构
物理结构:顺序、链式存储结构
13. 封装JSONP

jsonp
function jsonp ({url, param, callback}) {
  return new Promise((resolve, reject) => {
    var script = document.createElement('script')
    window.callback = function (data) {
      resolve(data)
      document.body.removeChild('script')
    }
    var param = {...param, callback}
    var arr = []
    for (let key in param) {
      arr.push(`${key}=${param[key]}`)
    }
    script.src = `${url}?${arr.join('&')}`
    document.body.appendChild(script)
  })}
14. 手动实现map(forEach以及filter也类似)
// for循环实现Array.prototype.myMap = function () {
  var arr = this
  var [fn, thisValue] = Array.prototype.slice.call(arguments)
  var result = []
  for (var i = 0; i < arr.length; i++) {
    result.push(fn.call(thisValue, arr, i, arr))
  }
  return result}var arr0 = [1, 2, 3]
console.log(arr0.myMap(v => v + 1))
// forEach实现(reduce类似)Array.prototype.myMap = function (fn, thisValue) {
  var result = []
  this.forEach((v, i, arr) => {
    result.push(fn.call(thisValue, v, i, arr))
  })
  return result}var arr0 = [1, 2, 3]
console.log(arr0.myMap(v => v + 1))
15. js实现checkbox全选以及反选
<body>
    <button id="other">反选</button>
    <input type="checkbox" id="all" />全选
    <input type="checkbox" class="check" />1
    <input type="checkbox" class="check" />2
    <input type="checkbox" class="check" />3
    <script>
      var checkbox = document.getElementsByClassName('check')
      var checkAll = document.getElementById('all')
      var checkOther = document.getElementById('other')
      checkAll.onclick = function() {
        var flag = true
        for (var i = 0; i < checkbox.length; i++) {
          if (!checkbox.checked) flag = false
        }
        if (flag) {
          for (var i = 0; i < checkbox.length; i++) {
            checkbox.checked = false
          }
        } else {
          for (var i = 0; i < checkbox.length; i++) {
            checkbox.checked = true
          }
        }
      }
      checkOther.onclick = function() {
        for (var i = 0; i < checkbox.length; i++) {
          checkbox.checked = !checkbox.checked
        }
      }
    </script>
  </body>
16. 对原型链的理解?prototype上都有哪些属性
•    在js里,继承机制是原型继承。继承的起点是 对象的原型(Object prototype)。
•    一切皆为对象,只要是对象,就会有 proto 属性,该属性存储了指向其构造的指针。
•    Object prototype也是对象,其 proto 指向null。
•    对象分为两种:函数对象和普通对象,只有函数对象拥有『原型』对象(prototype)。
•    prototype的本质是普通对象。
•    Function prototype比较特殊,是没有prototype的函数对象。
•    new操作得到的对象是普通对象。
•    当调取一个对象的属性时,会先在本身查找,若无,就根据 proto 找到构造原型,若无,继续往上找。最后会到达顶层Object prototype,它的 proto 指向null,均无结果则返回undefined,结束。
•    由 proto 串起的路径就是『原型链』。
•    通过prototype可以给所有子类共享属性
•    函数(Function)才有prototype属性,对象(除Object)拥有proto
•    实例的proto等于构造函数的prototype
•    实例的constructor指向构造函数
17. 为什么使用继承
通常在一般的项目里不需要,因为应用简单,但你要用纯js做一些复杂的工具或框架系统就要用到了,比如webgis、或者js框架如jquery、ext什么的,不然一个几千行代码的框架不用继承得写几万行,甚至还无法维护
18. setTimeout时间延迟为何不准
单线程, 先执行同步主线程, 再执行异步任务队列
19. 事件循环述,宏任务和微任务有什么区别?
•    先主线程后异步任务队列
•    先微任务再宏任务
20. let const var作用域
块级作用域, 暂时性死区
21. 节流和防抖
•    函数节流是指一定时间内js方法只跑一次。比如人的眨眼睛,就是一定时间内眨一次。这是函数节流最形象的解释。
// 函数节流   滚动条滚动var canRun = true;
document.getElementById("throttle").onscroll = function(){
    if(!canRun){
        // 判断是否已空闲,如果在执行中,则直接return
        return;
    }
    canRun = false;
    setTimeout(function(){
        console.log("函数节流");
        canRun = true;
    }, 300);};
•    函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次。比如生活中的坐公交,就是一定时间内,如果有人陆续刷卡上车,司机就不会开车。只有别人没刷卡了,司机才开车。
// 函数防抖var timer = false;
document.getElementById("debounce").onscroll = function(){
    clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
    timer = setTimeout(function(){
        console.log("函数防抖");
    }, 300);};  
22. 实现一个sleep函数
// 这种实现方式是利用一个伪死循环阻塞主线程。因为JS是单线程的。所以通过这种方式可以实现真正意义上的sleep()。function sleep(delay) {
  var start = (new Date()).getTime();
  while ((new Date()).getTime() - start < delay) {
    continue;
  }}
function test() {
  console.log('111');
  sleep(2000);
  console.log('222');}
test()
23. 闭包
•    概念: 内层函数能够访问外层函数作用域的变量
•    缺点: 引起内存泄漏(释放内存)
•    作用:
o    保护this指向
o    使用闭包修正打印值
o    实现柯里化
o    实现node commonJs 模块化, 实现私有变量
o    保持变量与函数活性, 可延迟回收和执行
24. Immutable.js
Facebook出品, 倡导数据的不可变性, 用的最多就是List和Map.
25. js实现instanceof
// 检测l的原型链(__proto__)上是否有r.prototype,若有返回true,否则falsefunction myInstanceof (l, r) {
  var R = r.prototype
  while (l.__proto__) {
    if (l.__proto__ === R) return true
  }
  return false}
27. ES6的模块引入和CommonJs区别
28. 严格模式
// 严格模式下, 隐式绑定丢失后this不会指向window, 而是指向undefined
      'use strict'
      var a = 2
      var obj = {
        a: 1,
        b: function() {
          // console.log(this.a)
          console.log(this)
        }
      }
      var c = obj.b
      c() // undefined
30. typescript缺点
•    并不是严格意义的js的超集, 与js不完全兼容, 会报错
•    更多的限制, 是一种桎梏
•    有些js第三方库没有dts, 有问题
31. 构造函数实现原理(new操作符做了什么)
•    构造函数中没有显示的创建Object对象, 实际上后台自动创建了一个空对象
•    直接给this对象赋值属性和方法, this即指向创建的对象
•    没有return返回值, 后台自动返回了该对象
•    该对象继承构造函数的原型
// 模拟构造函数实现var Book = function(name) {
  this.name = name;};
//正常用法var java = new Book(‘Master Java’);
        //使用代码模拟,在非IE浏览器中测试,IE浏览器不支持var python = {};
python.__proto__ = Book.prototype;Book.call(python, 'Master Python');
32. for in 和 for of区别
•    for in遍历数组会遍历到数组原型上的属性和方法, 更适合遍历对象
•    forEach不支持break, continue, return等
•    使用for of可以成功遍历数组的值, 而不是索引, 不会遍历原型
•    for in 可以遍历到myObject的原型方法method,如果不想遍历原型方法和属性的话,可以在循环内部判断一下,hasOwnPropery方法可以判断某属性是否是该对象的实例属性
33. JS实现并发控制:
使用消息队列以及setInterval或promise进行入队和出队
34. ajax和axios、fetch的区别
35. promise.finally实现
Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value  => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );};
36. 实现symbol
(function() {
    var root = this;
    var SymbolPolyfill = function Symbol(description) {
        // Symbol函数前不能使用new命令
        if (this instanceof SymbolPolyfill) throw new TypeError('Symbol is not a constructor')
        // 参数是对象,则调用toString
        var descString = description === undefined ? undefined : String(description)
        var symbol = Object.create({
            // 显示转为字符串
            toString: function() {
                return 'Symbol(' + this.description ')'
            },
            // 不能参与运算
            valueOf: function() {
                throw new Error('Cannot convert a Symbol value')
            }
        })
        // 作为对象键名时,生成一个独一无二名称
        // ES2019新增
        symbol.prototype.description = descString
        // 返回一个新对象 由于指针不同  所以两两不等
        return symbol;
    }
    root.SymbolPolyfill = SymbolPolyfill;})();
Object.create()创建对象
37. ES6装饰器
•    提案经过大幅修改,没有定案,可能会变
•    是一种函数,用于改变类或方法的功能,起到注释作用
•    函数:
@decoratorclass A {}
// 等同于
class A {}
A = decorator(A) || A;
•    方法:
function readonly(target, name, descriptor){
  // descriptor对象原来的值如下
  // {
  //   value: specifiedFunction,
  //   enumerable: false,
  //   configurable: true,
  //   writable: true
  // };
  descriptor.writable = false;
  return descriptor;}
readonly(Person.prototype, 'name', descriptor);// 类似于
Object.defineProperty(Person.prototype, 'name', descriptor);
•    先从外到内进入,经过 reverse 倒序后,然后由内向外执行。
38. 实现fetch abort
const controller = new AbortController()setTimeout(() => controller.abort(), 1000);
fetch(url, {
    signal: controller.signal}).then(res => {
    ...   }, err => {
    console.log(err) // AbortError})
39. 使用xhr实现fetch
•    fetch是ajax替代品,基于promise。
•    类似于jquey ajax,但不是ajax封装,而是原生js,,没有使用XHR对象
•    比ajax方便,但仍然不完善,建议使用axios库
•    fetch有而axios没有的问题:
o    兼容性问题
o    默认不带cookie,需要手动设置credentials
o    跨域问题,需要手动设置mode
o    返回400、500不识别为reject
o    无法abort和timeout
•    用XHR实现fetch:
// 先实现ajaxfunction ajax(method,url,data,suc,fail) {
    var xhr = new XMLHttpRequest();
    xhr.open(method, url, true);
    xhr.onreadystatechange = function () {
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                suc(xhr.responseText)
            } else {
                console.log(err);
                fail(xhr.responseText);
            }
        }
    };
    xhr.send(data);}
// 再实现promisefunction promise () {
  this.msg = '' // 存放value和error
  this.status = 'pending'
  var that = this
  var process = arguments[0]
  process (function () {
    that.status = 'fulfilled'
    that.msg = arguments[0]
  }, function () {
    that.status = 'rejected'
    that.msg = arguments[0]
  })
  return this}
promise.prototype.then = function () {
  if (this.status === 'fulfilled') {
    arguments[0](this.msg)
  } else if (this.status === 'rejected' && arguments[1]) {
    arguments[1](this.msg)
  }}
// 最后实现fetchfunction fetch(method, url, data) {
    return new promise(function (resolve,reject) {
        ajax(method, url, data, function (res) {
            resolve(res);
        },function (err) {
            reject(err);
        })
    })}
40. JS中数值存储
•    javascript 中所有的数值类型都是双精度存储的,使用 64bit,64bit 等于 8byte
•    中文占2个字节(byte) 中文里标点也占2个字节(byte) 英文里的子母不分大小写,一个子母占1个字节(字节) 英文里的标点占1个字节。 1字节(byte)=8位(bits)
•    当任何数字在进行位运算时 js 内部会将其转换成32位有符号整型
41. this指向:
•    谁调用了方法,该方法的this就指向谁;
•    优先级:箭头函数 > new绑定 > 显示绑定 > 隐式绑定

浏览器网络相关



1. reflow(回流)和repaint(重绘)优化

render
•    浏览器渲染过程: DOM tree, CSS tree --> Render tree --> Paint
•    DOM tree根节点为html
•    渲染从浏览器左上角到右下角
•    第一次打开页面至少触发一次重绘和回流, 结构如宽高位置变化时, 触发reflow回流;非结构如背景色变化时, 触发repaint重绘. 二者都会造成体验不佳
•    如何减少重绘和回流?
o    通过classname或cssText一次性修改样式, 而非一个一个改
o    离线模式: 克隆要操作的结点, 操作后再与原始结点交换, 类似于虚拟DOM
o    避免频繁直接访问计算后的样式, 而是先将信息保存下来
o    绝对布局的DOM, 不会造成大量reflow
o    div不要嵌套太深, 不要超过六层
2.一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?
•    浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求;
•    服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等);
•    浏览器对加载到的资源(HTML、JS、CSS等)进行语法解析,建立相应的内部数据结构(如HTML的DOM Tree);
•    载入解析到的资源文件,渲染页面,完成。
3.localStorage 与 sessionStorage 与cookie的区别总结
•    共同点: 都保存在浏览器端, 且同源
•    localStorage 与 sessionStorage 统称webStorage,保存在浏览器,不参与服务器通信,大小为5M
•    生命周期不同: localStorage永久保存, sessionStorage当前会话, 都可手动清除
•    作用域不同: 不同浏览器不共享local和session, 不同会话不共享session
•    Cookie: 设置的过期时间前一直有效, 大小4K.有个数限制, 各浏览器不同, 一般为20个.携带在HTTP头中, 过多会有性能问题.可自己封装, 也可用原生
4.浏览器如何阻止事件传播,阻止默认行为
•    阻止事件传播(冒泡): e.stopPropagation()
•    阻止默认行为: e.preventDefault()
5.虚拟DOM方案相对原生DOM操作有什么优点,实现上是什么原理?
虚拟DOM可提升性能, 无须整体重新渲染, 而是局部刷新.
JS对象, diff算法
6.浏览器事件机制中事件触发三个阶段
•    事件捕获阶段: 从dom树节点往下找到目标节点, 不会触发函数
•    事件目标处理函数: 到达目标节点
•    事件冒泡: 最后从目标节点往顶层元素传递, 通常函数在此阶段执行.
addEventListener第三个参数默认false(冒泡阶段执行),true(捕获阶段执行).
阻止冒泡见以上方法
7.什么是跨域?为什么浏览器要使用同源策略?你有几种方式可以解决跨域问题?了解预检请求嘛?
•    跨域是指一个域下的文档或脚本试图去请求另一个域下的资源
•    防止XSS、CSFR等攻击, 协议+域名+端口不同
•   
jsonp; 跨域资源共享(CORS)(Access control); 服务器正向代理等
•   

•   
jsonp封装
•   
•    预检请求: 需预检的请求要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响
8.了解浏览器缓存机制吗?
•    浏览器缓存就是把一个已经请求过的资源拷贝一份存储起来,当下次需要该资源时,浏览器会根据缓存机制决定直接使用缓存资源还是再次向服务器发送请求.
•    作用: 减少网络传输的损耗以及降低服务器压力。
•    缓存位置优先级:Service Worker > Memory Cache > Disk Cache > Push Cache. 都没有命中,就会向服务器发请求
•    策略优先级: 强制缓存 > 协商缓存; cache-control > Expires > Etag > Last-modified
9.为什么操作 DOM 慢?
DOM本身是一个js对象, 操作这个对象本身不慢, 但是操作后触发了浏览器的行为, 如repaint和reflow等浏览器行为, 使其变慢
10.什么情况会阻塞渲染?
•    js脚本同步执行
•    css和图片虽然是异步加载, 但js文件执行需依赖css, 所以css也会阻塞渲染
11.如何判断js运行在浏览器中还是node中?
判断有无全局对象global和window
12.关于web以及浏览器处理预加载有哪些思考?
图片等静态资源在使用之前就提前请求
资源使用到的时候能从缓存中加载, 提升用户体验
页面展示的依赖关系维护
13.http多路复用
•    Keep-Alive: Keep-Alive解决的核心问题:一定时间内,同一域名多次请求数据,只建立一次HTTP请求,其他请求可复用每一次建立的连接通道,以达到提高请求效率的问题。这里面所说的一定时间是可以配置的,不管你用的是Apache还是nginx。
•    解决两个问题: 串行文件传输(采用二进制数据帧); 连接数过多(采用流, 并行传输)
14. http和https:
•    http: 最广泛网络协议,BS模型,浏览器高效。
•    https: 安全版,通过SSL加密,加密传输,身份认证,密钥
1.    https相对于http加入了ssl层, 加密传输, 身份认证;
2.    需要到ca申请收费的证书;
3.    安全但是耗时多,缓存不是很好;
4.    注意兼容http和https;
5.    连接方式不同, 端口号也不同, http是80, https是443
15. CSRF和XSS区别及防御
16. cookie可设置哪些属性?httponly?
chrome控制台的application下可查看:

cookie
•    name 字段为一个cookie的名称。
•    value 字段为一个cookie的值。
•    domain 字段为可以访问此cookie的域名。
•    path 字段为可以访问此cookie的页面路径。 比如domain是abc.com,path是/test,那么只有/test路径下的页面可以读取此cookie。
•    expires/Max-Age 字段为此cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,意思是cookie会和session一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。
•    Size 字段 此cookie大小。
•    http 字段 cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie。
•    secure 字段 设置是否只能通过https来传递此条cookie
17. 登录后,前端做了哪些工作,如何得知已登录
•    前端存放服务端下发的cookie, 简单说就是写一个字段在cookie中表明已登录, 并设置失效日期
•    或使用后端返回的token, 每次ajax请求将token携带在请求头中, 这也是防范csrf的手段之一
18. http状态码
•    1**: 服务器收到请求, 需请求者进一步操作
•    2**: 请求成功
•    3**: 重定向, 资源被转移到其他URL了
•    4**: 客户端错误, 请求语法错误或没有找到相应资源
•    5**: 服务端错误, server error
•    301: 资源(网页等)被永久转移到其他URL, 返回值中包含新的URL, 浏览器会自动定向到新URL
•    302: 临时转移. 客户端应访问原有URL
•    304: Not Modified. 指定日期后未修改, 不返回资源
•    403: 服务器拒绝执行请求
•    404: 请求的资源(网页等)不存在
•    500: 内部服务器错误
19. Http请求头缓存设置方法
Cache-control, expire, last-modify
20. 实现页面回退刷新
•    旧: window.history.back() + window.location.href=document.referrer;
•    新: HTML5的新API扩展了window.history,使历史记录点更加开放了。可以存储当前历史记录点、替换当前历史记录点、监听历史记录点onpopstate, replaceState
21. 正向代理和反向代理
•   
正向代理:
•   

•   
正向代理
•   
(1)访问原来无法访问的资源,如google
(2) 可以做缓存,加速访问资源
(3)对客户端访问授权,上网进行认证
(4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
•   
•   
•   
•    反向代理:

•   
反向代理
•   
(1)保证内网的安全,可以使用反向代理提供WAF功能,阻止web攻击大型网站,通常将反向代理作为公网访问地址,Web服务器是内网。
(2)负载均衡,通过反向代理服务器来优化网站的负载
•   
22. 关于预检请求
在非简单请求且跨域的情况下,浏览器会自动发起options预检请求。
23. 三次握手四次挥手
•    开启连接用三次握手, 关闭用四次挥手
24. TCP和UDP协议
•    TCP(Transmission Control Protocol:传输控制协议;面向连接,可靠传输
•    UDP(User Datagram Protocol):用户数据报协议;面向无连接,不可靠传输
25. 进程和线程的区别
•    进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
•    线程:是进程的一个执行单元,是进程内科调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
•    一个程序至少一个进程,一个进程至少一个线程。

vue相关



1. 生命周期

生命周期
2 .双向数据绑定v-model。这个最好也是自己实现一下 理解更深
通过v-model
VUE实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。
// 依赖收集// 简化版var obj = { }var name //第一个参数:定义属性的对象。//第二个参数:要定义或修改的属性的名称。//第三个参数:将被定义或修改的属性描述符。
Object.defineProperty(obj, "data", {
  //获取值
  get: function () {
    return name
  },
  //设置值
  set: function (val) {
    name = val
    console.log(val)
  }})//赋值调用set
obj.data = 'aaa'//取值调用get
console.log(obj.data)
// 详细版
myVue.prototype._obverse = function (obj) { // obj = {number: 0}
    var value;
    for (key in obj) {  //遍历obj对象
      if (obj.hasOwnProperty(key)) {
        value = obj[key];
        if (typeof value === 'object') {  //如果值是对象,则递归处理
          this._obverse(value);
        }
        Object.defineProperty(this.$data, key, {  //关键
          enumerable: true,
          configurable: true,
          get: function () {
            console.log(`获取${value}`);
            return value;
          },
          set: function (newVal) {
            console.log(`更新${newVal}`);
            if (value !== newVal) {
              value = newVal;
            }
          }
        })
      }
    }
  }
3.vue父子组件传递参数
•    父 -->子: 通过props
•    子 -->父: 通过 $$refs 或 $emit
4.vue传递参数方法
•    父子组件传参如上, v-bind : v-on @
•    兄弟组件传参:(通过EventBus事件总线实现)
// 1. 新建eventBus.jsimport Vue from 'vue'export default new Vue// 或直接在main.js中初始化EventBus(全局)
Vue.prototype.$EventBus = new Vue()
// 2. 发射与接收// 如果是定义在eventBus.js中import eventBus from 'eventBus.js'
eventBus.$emit()
eventBus.$on()
// 如果是定义在main.js中this.bus.$emit()this.bus.$on()
// 3. 移除监听
eventBus.$off()
5.vue自定义组件
可以使用独立可复用的自定义组件来构成大型应用, 采用帕斯卡命名法或横线连接, 通过以上方式进行组件间通信. 每一个组件都是Vue实例, 可以使用生命周期钩子.
6. vue自定义指令
•    除核心指令之外的指令, 使用directive进行注册.
•    指令自定义钩子函数: bind, inserted, update, componentUpdated, unbind
7.vuex组成和原理
•    组成: 组件间通信, 通过store实现全局存取
•    修改: 唯一途径, 通过commit一个mutations(同步)或dispatch一个actions(异步)
•    简写: 引入mapState、mapGetters、mapActions
8.vue-router的原理,例如hashhistory和History interface这些东西要弄明白。其实看一下源码就好了,看不懂可以直接看解析的相关技术博客。
•    vue-router用法:
在router.js或者某一个路由分发页面配置path, name, component对应关系
o    每个按钮一个value, 在watch功能中使用this.$router.push实现对应跳转, 类似react的this.history.push
o    或直接用router-link to去跳转, 类似react的link to
•    vue-router原理: 通过hash和History interface两种方式实现前端路由
o    HashHistory: 利用URL中的hash(“#”);replace()方法与push()方法不同之处在于,它并不是将新路由添加到浏览器访问历史的栈顶,而是替换掉当前的路由
o    History interface: 是浏览器历史记录栈提供的接口,通过back(), forward(), go()等方法,我们可以读取浏览器历史记录栈的信息,进行各种跳转操作. pushState(), replaceState() 这下不仅是读取了,还可以对浏览器历史记录栈进行修改
9.vue的seo问题
seo关系到网站排名, vue搭建spa做前后端分离不好做seo, 可通过其他方法解决:
•    SSR服务端渲染: 将同一个组件渲染为服务器端的 HTML 字符串.利于seo且更快.
•    vue-meta-info, nuxt, prerender-spa-plugin页面预渲染等
10.预渲染和ssr
以上
11.生命周期内create和mounted的区别
•    created: 在模板渲染成html前调用,即通常初始化某些数据,然后再渲染成视图。
•    mounted: 在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作和方法。
12.监听watch
对应一个对象,键是观察表达式,值是对应回调。值也可以是methods的方法名,或者是对象,包含选项。在实例化时为每个键调用 $watch()
13.登录验证拦截(通过router)
•    先设置requireAuth:
routes = [
    {
        name: 'detail',
        path: '/detail',
        meta: {
            requireAuth: true
        }
    },
    {
        name: 'login',
        path: '/login'
    }
]
•    再配置router.beforeEach:
router.beforeEach((from, to, next) => {
    if (to.meta.requireAuth) { // 判断跳转的路由是否需要登录
        if (store.state.token) { // vuex.state判断token是否存在
            next() // 已登录
        } else {
            next({
                path: '/login',
                query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由
            })
        }
    } else {
       next()
    }})
14. v-for key值
不写key值会报warning, 和react的array渲染类似. 根据diff算法, 修改数组后, 写key值会复用, 不写会重新生成, 造成性能浪费或某些不必要的错误
15. vue3.0的更新和defineProperty优化
•    放弃 Object.defineProperty ,使用更快的原生 Proxy (访问对象拦截器, 也称代理器)
•    提速, 降低内存使用, Tree-shaking更友好
•    支持IE11等
•    使用Typescript
15. vue使用this获取变量
正常要通过vm. root传参取值
16. jQuery的优缺点,与vue的不同,vue的优缺点?
•    jq优点: 比原生js更易书写, 封装了很多api, 有丰富的插件库; 缺点: 每次升级与之前版本不兼容, 只能手动开发, 操作DOM很慢, 不方便, 变量名污染, 作用域混淆等.
•    vue优缺点: 双向绑定, 虚拟DOM, diff算法, MVVM, 组件化, 通信方便, 路由分发等
17. vue解除双向绑定
let obj = JSON.parse(JSON.stringify(this.temp1));
18. vue异步组件
为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染
Vue.component(
  'async-webpack-example',
  // 这个 `import` 函数会返回一个 `Promise` 对象。
  () => import('./my-async-component'))
19. MVC与MVVM
•    model-数据层 view-视图层 controller-控制层
•    MVC的目的是实现M和V的分离,单向通信,必须通过C来承上启下
•    MVVM中通过VM(vue中的实例化对象)的发布者-订阅者模式实现双向绑定,数据绑定,dom事件监听
•    区别:MVC和MVVM的区别并不是VM完全取代了C,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。也就是说MVVM实现的是业务逻辑组件的重用
20. vue渐进式
小到可以只使用核心功能,比如单文件组件作为一部分嵌入;大到使用整个工程,vue init webpack my-project来构建项目;VUE的核心库及其生态系统也可以满足你的各式需求(core+vuex+vue-route)

react相关



1. 新旧生命周期
•    旧: will, did; mount, update...
•    新: 16版本之后:
o    getDerivedStateFromProps: 虚拟dom之后,实际dom挂载之前, 每次获取新的props或state之后, 返回新的state, 配合didUpdate可以替代willReceiveProps
o    getSnapshotBeforeUpdate: update发生的时候,组件更新前触发, 在render之后,在组件dom渲染之前;返回一个值,作为componentDidUpdate的第三个参数;配合componentDidUpdate, 可以覆盖componentWillUpdate的所有用法
o    componentDidCatch: 错误处理
•    对比: 弃用了三个will, 新增两个get来代替will, 不能混用, 17版本会彻底删除. 新增错误处理
2. react核心
•    虚拟DOM, Diff算法, 遍历key值
•    react-dom: 提供了针对DOM的方法,比如:把创建的虚拟DOM,渲染到页面上 或 配合ref来操作DOM
•    react-router
3. fiber核心(react 16)
•    旧: 浏览器渲染引擎单线程, 计算DOM树时锁住整个线程, 所有行为同步发生, 有效率问题, 期间react会一直占用浏览器主线程,如果组件层级比较深,相应的堆栈也会很深,长时间占用浏览器主线程, 任何其他的操作(包括用户的点击,鼠标移动等操作)都无法执行
•    新: 重写底层算法逻辑, 引入fiber时间片, 异步渲染, react会在渲染一部分树后检查是否有更高优先级的任务需要处理(如用户操作或绘图), 处理完后再继续渲染, 并可以更新优先级, 以此管理渲染任务. 加入fiber的react将组件更新分为两个时期(phase 1 && phase 2),render前的生命周期为phase1,render后的生命周期为phase2, 1可以打断, 2不能打断一次性更新. 三个will生命周期可能会重复执行, 尽量避免使用
4. 渲染一个react
•    分为首次渲染和更新渲染
•    生命周期, 建立虚拟DOM, 进行diff算法
•    对比新旧DOM, 节点对比, 将算法复杂度从O(n^3)降低到O(n)
•    key值优化, 避免用index作为key值, 兄弟节点中唯一就行
5. 高阶组件
高阶组件就是一个函数,且该函数(wrapper)接受一个组件作为参数,并返回一个新的组件。
高阶组件并不关心数据使用的方式和原因,而被包裹的组件也不关心数据来自何处.
•    react-dnd: 根组件, source, target等
export default DragSource(type, spec, collect)(MyComponent)
•    重构代码库使用HOC提升开发效率
6. hook(v16.7测试)
在无状态组件(如函数式组件)中也能操作state以及其他react特性, 通过useState
7. redux和vuex以及dva:
•    redux: 通过store存储,通过action唯一更改,reducer描述如何更改。dispatch一个action
•    dva: 基于redux,结合redux-saga等中间件进行封装
•    vuex:类似dva,集成化。action异步,mutation非异步
8. react和vue的区别
•    数据是否可变: react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流,推崇结合immutable来实现数据不可变; vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。总之,react的性能优化需要手动去做,而vue的性能优化是自动的,但是vue的响应式机制也有问题,就是当state特别多的时候,Watcher也会很多,会导致卡顿,所以大型应用(状态特别多的)一般用react,更加可控。
•    通过js来操作一切,还是用各自的处理方式: react的思路是all in js,通过js来生成html,所以设计了jsx,还有通过js来操作css,社区的styled-component、jss等; vue是把html,css,js组合到一起,用各自的处理方式,vue有单文件组件,可以把html、css、js写到一个文件中,html提供了模板引擎来处理。
•    类式的组件写法,还是声明式的写法: react是类式的写法,api很少; 而vue是声明式的写法,通过传入各种options,api和参数都很多。所以react结合typescript更容易一起写,vue稍微复杂。
•    扩展不同: react可以通过高阶组件(Higher Order Components--HOC)来扩展,而vue需要通过mixins来扩展
•    什么功能内置,什么交给社区去做: react做的事情很少,很多都交给社区去做,vue很多东西都是内置的,写起来确实方便一些,
比如 redux的combineReducer就对应vuex的modules,
比如reselect就对应vuex的getter和vue组件的computed,
vuex的mutation是直接改变的原始数据,而redux的reducer是返回一个全新的state,所以redux结合immutable来优化性能,vue不需要。
9. react单向数据流怎么理解
React是单向数据流,数据主要从父节点传递到子节点(通过props)。如果顶层(父级)的某个props改变了,React会重渲染所有的子节点。
10. React算法复杂度优化
react树对比是按照层级去对比的, 他会给树编号0,1,2,3,4.... 然后相同的编号进行比较。 所以复杂度是n,这个好理解。
关键是传统diff的复杂度是怎么算的? 传统的diff需要出了上面的比较之外,还需要跨级比较。 他会将两个树的节点,两两比较,这就有n^2的复杂度了。 然后还需要编辑树,编辑的树可能发生在任何节点,需要对树进行再一次遍历操作,因此复杂度为n。加起来就是n^3了。
11. React优点
声明式, 组件化, 一次学习, 随处编写. 灵活, 丰富, 轻巧, 高效
12. React事件机制
•    合成事件:
o    根据事件类型,采用不同的SyntheticEvent来构造不同的合成事件
o    syntheticEvent 和原生浏览器事件一样拥有同样的接口,也支持事件冒泡机制。可以通过stopPropgation和preventDefault中断
o    如果需要访问原生事件对象,可以使用nativeEvent属性
•    实现机制:
o    react 的事件机制利用了事件委托机制
o    没有绑定在真实的dom节点上,而是把事件都绑定在结构的最外层document,统一由这个监听器分发
o    注册:组件挂载和更新时,将绑定事件分类放入EventPluginHub事件池
o    触发:根据事件产生的Event对象找到触发事件的组件,再通过组件标识和事件类型从事件池里找到对应的事件监听回调并执行
•    react中使用原生
o    在didmount中对真实dom进行原生绑定,在unmount解绑,防止内存泄漏
o    syntheticEvent的stopPropgation无法阻止原生事件的冒泡,但原生可以组织合成,所以尽量不要混用,除非使用e.target判断
•    异步回调使用syntheticEvent:
o    合成事件里,回调执行后会销毁事件对象
o    异步回调需使用event.persist()告诉react不要回收
•    与原生冒泡捕获对比:
o    原生的捕获机制并不常用,且具有 ie 的不兼容问题
o    react仅实现冒泡机制,无兼容问题,只有document节点上才有 DOM 事件也节约了内存
•    事件执行:
1.    找到事件触发的DOM和React Component,调用findParent方法
2.    遍历得到所有父组件,存在数组中
3.    从该组件直到最后一个父组件,根据之前事件存储,用 React 事件名 + 组件 key,找到对应绑定回调方法

移动端相关



1. 移动端兼容适配
•    <meta name="viewport" content="width=device-width, initial-scale=1.0">
•    rem, em, 百分比
•    框架的栅格布局
•    media query媒体查询
•    手淘团队的一套flexible.js, 自动判断dpr进行整个布局视口的放缩
2. flexible如何实现自动判断dpr
判断机型, 找出样本机型去适配. 比如iphone以6为样本, 宽度375px, dpr是2
3. 为什么以iPhone6为标准的设计稿的尺寸是以750px宽度来设计的呢?
iPhone6的满屏宽度是375px,而iPhone6采用的视网膜屏的物理像素是满屏宽度的2倍,也就是dpr(设备像素比)为2, 并且设计师所用的PS设计软件分辨率和像素关系是1:1。所以为了做出的清晰的页面,设计师一般给出750px的设计图,我们再根据需求对元素的尺寸设计和压缩。
4. 如何处理异形屏iphone X
•    safe area: 默认放置在安全区域以避免遮挡, 但会压缩
•    在meta中添加viewport-fit=cover: 告诉浏览器要讲整个页面渲染到浏览器中,不管设备是圆角与否,这个时候会造成页面的元素被圆角遮挡
•    padding: constant(env): 解决遮挡问题
5. 移动端首屏优化
•    采用服务器渲染ssr
•    按需加载配合webpack分块打包, 通过entry和commonChunkPlugin
•    很有必要将script标签➕异步
•    有轮播图 最好给个默认 另外要处理图片懒加载
•    打包线上也要注意去掉map 文件
•    组件, 路由懒加载
•    webpack的一切配置 肯定是必须的
•    压缩图片 https://tinypng.com/
•    建议还是用webpack的图片压缩插件
•    骨架屏
•    Loading页面
6. PWA全称Progressive Web App,即渐进式WEB应用
一个 PWA 应用首先是一个网页, 可以通过 Web 技术编写出一个网页应用. 随后添加上 App Manifest 和 Service Worker 来实现 PWA 的安装和离线等功能
解决了哪些问题?
•    可以添加至主屏幕,点击主屏幕图标可以实现启动动画以及隐藏地址栏
•    实现离线缓存功能,即使用户手机没有网络,依然可以使用一些离线功能
•    实现了消息推送
它解决了上述提到的问题,这些特性将使得 Web 应用渐进式接近原生 App。
7. 离线包方案
现在 web 页面在移动端的地位越来越高,大部分主流 App 采用 native + webview 的 hybrid 模式,加载远程页面受限于网络,本地 webview 引擎,经常会出现渲染慢导致的白屏现象,体验很差,于是离线包方案应运而生。动态下载的离线包可以使得我们不需要走完整的 App 审核发布流程就完成了版本的更新
8. 自适应和响应式布局的区别
1.   
自适应布局通过检测视口分辨率,来判断当前访问的设备是:pc端、平板、手机,从而请求服务层,返回不同的页面;响应式布局通过检测视口分辨率,针对不同客户端在客户端做代码处理,来展现不同的布局和内容。
2.   
3.   
自适应布局需要开发多套界面,而响应式布局只需要开发一套界面就可以了。
4.   
5.   
自适应对页面做的屏幕适配是在一定范围:比如pc端一般要大于1024像素,手机端要小于768像素。而响应式布局是一套页面全部适应。
6.   
7.   
自适应布局如果屏幕太小会发生内容过于拥挤。而响应式布局正是为了解决这个问题而衍生出的概念,它可以自动识别屏幕宽度并做出相应调整的网页设计。
8.   

插件及工具相关



1. babel和polyfill
•   
Babel: Babel 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码。注意:Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API
•   
•   
Polyfill: Polyfill的准确意思为,用于实现浏览器并不支持的原生API的代码。
•   
2. jpg, jpeg和png区别
•    jpg是jpeg的缩写, 二者一致
•    PNG就是为取代GIF而生的, 无损压缩, 占用内存多
•    jpg牺牲图片质量, 有损, 占用内存小
•    PNG格式可编辑。如图片中有字体等,可利用PS再做更改。JPG格式不可编辑
3. git rebase和merge区别

git rebase

git merge

前端性能优化



1.    减少HTTP请求(合并css、js,雪碧图/base64图片)
2.    压缩(css、js、图片皆可压缩,使用webpack uglify和 svg)
3.    样式表放头部,脚本放底部
4.    使用CDN(这部分,不少前端都不用考虑,负责发布的兄弟可能会负责搞好)
5.    http缓存
6.    bosify图片压缩: 根据具体情况修改图片后缀或格式 后端根据格式来判断存储原图还是缩略图
7.    懒加载, 预加载
8.    替代方案: 骨架屏, SSR
9.    webpack优化

原生通信



1.JSBridge通信原理, 有哪几种实现的方式?
JsBridge给JavaScript提供了调用Native功能,Native也能够操控JavaScript。这样前端部分就可以方便使用地理位置、摄像头以及登录支付等Native能力啦。JSBridge构建 Native和非Native间消息通信的通道,而且是 双向通信的通道。
•    JS 向 Native 发送消息 : 调用相关功能、通知 Native 当前 JS 的相关状态等。
•    Native 向 JS 发送消息 : 回溯调用结果、消息推送、通知 JS 当前 Native 的状态等。
2.实现一个简单的 JSBridge,设计思路?

算法相关



1. 二分查找和冒泡排序
•    二分查找: 递归(分左右, 传递start,end参数)和非递归(使用while(l < h));要求有序数组
•    冒泡排序: 两个for循环
2. 快速排序
function quickSort (arr) {
  if (arr.length < 2) return arr
  var middle = Math.floor(arr.length / 2)
  var flag = arr.splice(middle, 1)[0]
  var left = [],
        right = []
  for (var i = 0; i < arr.length; i++) {
    if (arr < flag) {
      left.push(arr)
    } else {
      right.push(arr)
    }
  }
  return quickSort(left).concat([flag], quickSort(right))}
3. 最长公共子串
function findSubStr(str1, str2) {
        if (str1.length > str2.length) {
          [str1, str2] = [str2, str1]
        }
        var result = ''
        var len = str1.length
        for (var j = len; j > 0; j--) {
          for (var i = 0; i < len - j; i++) {
            result = str1.substr(i, j)
            if (str2.includes(result)) return result
          }
        }
      }
      console.log(findSubStr('aabbcc11', 'ppooiiuubcc123'))
4. 最长公共子序列(LCS动态规划)
另一篇
// dp[j] 计算去最大长度,记住口诀:相等左上角加一,不等取上或左最大值function LCS(str1, str2){
        var rows =  str1.split("")
        rows.unshift("")
        var cols =  str2.split("")
        cols.unshift("")
        var m = rows.length
        var n = cols.length
        var dp = []
        for(var i = 0; i < m; i++){
            dp = []
            for(var j = 0; j < n; j++){
                if(i === 0 || j === 0){
                    dp[j] = 0
                    continue
                }

                if(rows === cols[j]){
                    dp[j] = dp[i-1][j-1] + 1 //对角+1
                }else{
                    dp[j] = Math.max( dp[i-1][j], dp[j-1]) //对左边,上边取最大
                }
            }
            console.log(dp.join(""))//调试
        }
        return dp[i-1][j-1]
    }//!!!如果它来自左上角加一,则是子序列,否则向左或上回退。//findValue过程,其实就是和 就是把T[j]的计算反过来。// 求最长子序列function findValue(input1,input2,n1,n2,T){
    var i = n1-1,j=n2-1;
    var result = [];//结果保存在数组中
    console.log(i);
    console.log(j);
    while(i>0 && j>0){
        if(input1 == input2[j]){
            result.unshift(input1);
            i--;
            j--;
        }else{
            //向左或向上回退
            if(T[i-1][j]>T[j-1]){
                //向上回退
                i--;
            }else{
                //向左回退
                j--;
            }
        }
    }
    console.log(result);}
5. 数组去重,多种方法
•    双for循环, splice剔除并i--回退
•    indexOf等于index
•    filter indexOf === index
•    新数组indexOf === index
•    使用空对象等
6. 实现一个函数功能:sum(1,2,3,4..n)转化为 sum(1)(2)(3)(4)…(n)
// 使用柯里化 + 递归function curry ( fn ) {
  var c = (...arg) => (fn.length === arg.length) ?
          fn (...arg) : (...arg1) => c(...arg, ...arg1)
  return c}
柯里化参考我的另一篇
7. 反转二叉树
此题充满了嘲讽。。
var invertTree = function (root) {
  if (root !== null) {
    [root.left, root.right] = [root.right, root.left]
    invertTree(root.left)
    invertTree(root.right)
  }
  return root}
8. 贪心算法解决背包问题
问题:给定背包容积,如何存放不同重量和价值物品,能获得最大价值?
var items = ['A','B','C','D'] // 物品编号var values = [50,220,60,60] // 物品价值var weights = [5,20,10,12] // 物品重量var capacity = 32 // 背包容积
greedy(values, weights, capacity) // 320
function greedy(values, weights, capacity) {
        var result = 0
        var rest = capacity
        var sortArray = []
        var num = 0
        values.forEach((v, i) => {
          sortArray.push({
            value: v,
            weight: weights,
            ratio: v / weights
          })
        })
        // 按照性价比降序排序
        sortArray.sort((a, b) => b.ratio - a.ratio)
        sortArray.forEach((v, i) => {
          num = parseInt(rest / v.weight)
          rest -= num * v.weight
          result += num * v.value
        })
        return result
      }
9. 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
function FindNumbersWithSum(array, sum){
    var index = 0
    for (var i = 0; i < array.length - 1 && array < sum / 2; i++) {
        for (var j = i + 1; j < array.length; j++) {
            if (array + array[j] === sum) return [array, array[j]]
        }
        //index = array.indexOf(sum - array, i + 1)
       // if (index !== -1) {
       //     return [array, array[index]]
        //}
    }
    return []
10. 二叉树各种(层序)遍历
深度广度遍历
// 根据前序和中序重建二叉树/* function TreeNode(x) {
    this.val = x;
    this.left = null;
    this.right = null;
} */function reConstructBinaryTree(pre, vin){
    var result = null
    if (pre.length === 1) {
        result = {
            val: pre[0],
            left: null,
            right: null
        }
    } else if (pre.length > 1) {
        var root = pre[0]
        var vinRootIndex = vin.indexOf(root)
        var vinLeft = vin.slice(0, vinRootIndex)
        var vinRight = vin.slice(vinRootIndex + 1, vin.length)
        pre.shift()
        var preLeft = pre.slice(0, vinLeft.length)
        var preRight = pre.slice(vinLeft.length, pre.length)
        result = {
            val: root,
            left: reConstructBinaryTree(preLeft, vinLeft),
            right: reConstructBinaryTree(preRight, vinRight)
        }
    }
    return result}
// 递归// 前序遍历function prevTraverse (node) {
  if (node === null) return;
  console.log(node.data);
  prevTraverse(node.left);
  prevTraverse(node.right);}
// 中序遍历function middleTraverse (node) {
  if (node === null) return;
  middleTraverse(node.left);
  console.log(node.data);
  middleTraverse(node.right);}
// 后序遍历function lastTraverse (node) {
  if (node === null) return;
  lastTraverse(node.left);
  lastTraverse(node.right);
  console.log(node.data);}
// 非递归// 前序遍历function preTraverse(tree) {
        var arr = [],
          node = null
        arr.unshift(tree)
        while (arr.length) {
          node = arr.shift()
          console.log(node.root)
          if (node.right) arr.unshift(node.right)
          if (node.left) arr.unshift(node.left)
        }
      }
// 中序遍历function middleTraverseUnRecursion (root) {
  let arr = [],
      node = root;
  while (arr.length !== 0 || node !== null) {
    if (node === null) {
      node = arr.shift();
      console.log(node.data);
      node = node.right;
    } else {
      arr.unshift(node);
      node = node.left;
    }
  }
}
// 广度优先-层序遍历// 递归var result = []var stack = [tree]var count = 0var bfs = function () {
  var node = stack[count]
  if (node) {
    result.push(node.value)
    if (node.left) stack.push(node.left)
    if (node.right) stack.push(node.right)
    count++
    bfs()
  }}bfs()
console.log(result)// 非递归function bfs (node) {
  var result = []
  var queue = []
  queue.push(node)
  while (queue.length) {
    node = queue.shift()
    result.push(node.value)
    node.left && queue.push(node.left)
    node.right && queue.push(node.right)
  }
  return result}
11. 各种排序
// 插入排序function insertSort(arr) {
        var temp
        for (var i = 1; i < arr.length; i++) {
          temp = arr
          for (var j = i; j > 0 && temp < arr[j - 1]; j--) {
            arr[j] = arr[j - 1]
          }
          arr[j] = temp
        }
        return arr
      }
      console.log(insertSort([3, 1, 8, 2, 5]))
// 归并排序function mergeSort(array) {
        var result = array.slice(0)
        function sort(array) {
          var length = array.length
          var mid = Math.floor(length * 0.5)
          var left = array.slice(0, mid)
          var right = array.slice(mid, length)
          if (length === 1) return array
          return merge(sort(left), sort(right))
        }
        function merge(left, right) {
          var result = []
          while (left.length || right.length) {
            if (left.length && right.length) {
              if (left[0] < right[0]) {
                result.push(left.shift())
              } else {
                result.push(right.shift())
              }
            } else if (left.length) {
              result.push(left.shift())
            } else {
              result.push(right.shift())
            }
          }
          return result
        }
        return sort(result)
      }
      console.log(mergeSort([5, 2, 8, 3, 6]))
// 二分插入排序function twoSort(array) {
        var len = array.length,
          i,
          j,
          tmp,
          low,
          high,
          mid,
          result
        result = array.slice(0)
        for (i = 1; i < len; i++) {
          tmp = result
          low = 0
          high = i - 1
          while (low <= high) {
            mid = parseInt((high + low) / 2, 10)
            if (tmp < result[mid]) {
              high = mid - 1
            } else {
              low = mid + 1
            }
          }
          for (j = i - 1; j >= high + 1; j--) {
            result[j + 1] = result[j]
          }
          result[j + 1] = tmp
        }
        return result
      }
      console.log(twoSort([4, 1, 7, 2, 5]))
12. 使用尾递归对斐波那契优化
递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。
// 传统递归斐波那契, 会造成超时或溢出function Fibonacci (n) {
  if ( n <= 1 ) {return 1};
  return Fibonacci(n - 1) + Fibonacci(n - 2);}
Fibonacci(10) // 89Fibonacci(100) // 超时Fibonacci(500) // 超时
// 使用尾递归优化, 可规避风险function Fibonacci2 (n , ac1 = 1 , ac2 = 1) {
  if( n <= 1 ) {return ac2};
  return Fibonacci2 (n - 1, ac2, ac1 + ac2);}
Fibonacci2(100) // 573147844013817200000Fibonacci2(1000) // 7.0330367711422765e+208Fibonacci2(10000) // Infinity
13. 两个升序数组合并为一个升序数组
function sort (A, B) {
  var i = 0, j = 0, p = 0, m = A.length, n = B.length, C = []
  while (i < m || j < n) {
    if (i < m && j < n) {
      C[p++] = A < B[j] ? A[i++] : B[j++]
    } else if (i < m) {
      C[p++] = A[i++]
    } else {
      C[p++] = B[j++]
    }
  }
  return C}

node相关



1. node的router是什么
2. 数据库索引是啥
•    狭义上: 索引是数据库针对每条数据自动生成的内部唯一id标识, 用以快速搜索定位数据
•    广义上: 是数据库根据每条数据形成的关键字, 将划分为树形结构, 便于sql语句对数据的查找, 使算法复杂度降低到O(logn)
3. 浏览器的事件循环和node事件循环有什么区别?
微任务执行时机不同:
Node环境:微任务在事件循环的各个阶段的 空隙(中间)执行
浏览器:微任务在事件循环的宏任务执行完后执行
4. 关于buffer
•    node中的核心对象:Buffer.from(str)
•    用来存储二进制数据的类数组
•    用两位十六进制数表示一个字符的unicode编码
•    连续存储空间,快
•    1 byte = 8 bit
•    英文字符1 byte, 中文字符2 byte

计算机基础



•    硬件:
o    CPU是人的大脑,负责运算
o    内存是人的记忆,负责临时存储
o    硬盘是人的笔记本,负责永久存储
o    输入设备是人的耳朵或眼睛,负责接受外部的信息传给CPU
o    以上所有的设备都通过总线连接,总线相当于人的神经
•    数据结构与算法:
o    算法:
    定义:解决具体问题所需要的解决方法。
    最优算法:执行效率最快的,时间复杂度最低。
    特征:输入,输出,有穷性,确定性,可行性。
    类型:冒泡排序,二叉树遍历,最长回文,二分查找,指针,链表等,堆栈,队列等。
    途径:力扣,codewar,算法导论。
o    数据结构:
    逻辑结构:集合、线性、树形、图形结构
    物理结构:顺序、链式存储结构
•    操作系统:
o    定义:管理计算机硬件与软件资源的计算机程序,同时也是计算机系统的内核与基石
o    功能:
    管理与配置内存
    决定系统资源供需的优先次序
    控制输入设备与输出设备
    操作网络
    管理文件系统
•    数据库:
o    关系型数据库比如MySQL、SQLServer、Oracle
o    非关系型数据库mongodb
•    计算机组成原理:硬件和软件
•    计算机网络:
o    定义:一些相互连接的、以共享资源为目的的、自治的计算机的集合
o    组成:计算机、网络操作系统、传输介质以及相应的应用软件四部分
o    功能:数据通信、资源共享、集中管理、分布式处理、负载均衡
o    分类:局域网LAN、无线网
o    网络协议TCP/IP

第一部分:HTML问答题
1.简述一下你对HTML语义化的理解?
用正确的标签做正确的事情。
html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;即使在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的;
搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO;
使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。
2.Label的作用是什么?是怎么用的?
label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。
<label for="Name">Number:</label>
<input type=“text“name="Name" id="Name"/>
<label>Date:<input type="text" name="B"/></label>
3.iframe有那些缺点?
*iframe会阻塞主页面的Onload事件;
*搜索引擎的检索程序无法解读这种页面,不利于SEO;
*iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。
使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript。动态给iframe添加src属性值,这样可以绕开以上两个问题。
4.HTML与XHTML —— 二者有什么区别,你觉得应该使用哪一个并说出理由。
1.XHTML 元素必须被正确地嵌套。
错误:<p><span>this is example.</p></span>
正确:<p><span>this is example.</span></p>
2.XHTML 元素必须被关闭。
错误:<p>this is example.
正确:<p>this is example.</p>
3.标签名必须用小写字母。
错误:<P>this is example.<P>
正确:<p>this is example.</p>
3.1空标签也必须被关闭
错误:<br>
正确:<br/>
4.XHTML 文档必须拥有根元素。
所有的 XHTML 元素必须被嵌套于 <html> 根元素中。
5.常见的浏览器内核有哪些?
Trident内核:IE,MaxThon,TT,The World,360,搜狗浏览器等。[又称MSHTML]
Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等
Presto内核:Opera7及以上。      [Opera内核原为:Presto,现为:Blink;]
Webkit内核:Safari,Chrome等。   [ Chrome的:Blink(WebKit的分支)]
6.简述一下你对HTML语义化的理解?
用正确的标签做正确的事情。
html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;
即使在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的;
搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO;
使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。
7.HTML5的form如何关闭自动完成功能?
给不想要提示的 form 或某个 input 设置为 autocomplete=off。
8.实现不使用 border 画出1px高的线,在不同浏览器的标准模式与怪异模式下都能保持一致的效果。
<div style="height:1px;overflow:hidden;background:red"></div>
9.title与h1的区别、b与strong的区别、i与em的区别?
title属性没有明确意义只表示是个标题,H1则表示层次明确的标题,对页面信息的抓取也有很大的影响;
strong是标明重点内容,有语气加强的含义,使用阅读设备阅读网络时:<strong>会重读,而<B>是展示强调内容。
i内容展示为斜体,em表示强调的文本;
Physical Style Elements -- 自然样式标签
b, i, u, s, pre
Semantic Style Elements -- 语义样式标签
strong, em, ins, del, code
应该准确使用语义样式标签, 但不能滥用, 如果不能确定时首选使用自然样式标签。
10.请描述下SEO中的TDK?
在SEO中,所谓的TDK其实就是title、description、keywords这三个标签,这三个标签在网站的优化过程中
title标题标签,description描述标签,keywords关键词标签
11.简单书写HTML代码:请写出一个html网站代码,内容为一个图片,链接到“http://www.baidu.com”,图片路径为“./img/logo.png”,为图片设置替换文本”webfoss”,新网页在新窗口打开;
答: <a href=”http://www.baidu.com” alt=”webfoss” target=”_blank”><img src=”./img/logo.png”></a>
12.标签上title与alt属性的区别是什么?
alt是给搜索引擎识别,在图像无法显示时的替代文本;title是关于元素的注释信息,主要是给用户解读。当鼠标放到文字或是图片上时有title文字显示。(因为IE不标准)在IE浏览器中alt起到了title的作用,变成文字提示。在定义img对象时,将alt和title属性写全,可以保证在各种浏览器中都能正常使用。
13.前端页面有哪三层构成,分别是什么?作用是什么?
分成:结构层、表示层、行为层。
结构层(structural layer)
由 HTML 或 XHTML之类的标记语言负责创建。标签,也就是那些出现在尖括号里的单词,对网页内容的语义含义做出了描述,但这些标签不包含任何关于如何显示有关内容的信息。例如,P标签表达了这样一种语义:“这是一个文本段。”
表示层(presentation layer)
由 CSS 负责创建。 CSS对“如何显示有关内容”的问题做出了回答。
行为层(behaviorlayer)
负责回答“内容应该如何对事件做出反应”这一问题。这是 Javascript 语言和 DOM主宰的领域。
14.每个HTML文件头里都有个很重要的东西,Doctype,知道这是干什么的么?
<!DOCTYPE> 声明位于文档中的最前面的位置,处于 <html> 标签之前。
作用:
1.告知浏览器文档使用哪种 HTML 或 XHTML 规范。
2.告诉浏览器按照何种规范解析页(如果你的页面没有DOCTYPE的声明,那么compatMode默认就是BackCompat,浏览器按照自己的方式解析渲染页面)
15.DIV+CSS布局较table有什么优势?
1、速率更快,页面体积变小,浏览速度变快,这就使得对于某些控制主机流量的网站来说是最大的优势了;
2、更好地被搜索引擎收录,大部分html页面的样式写入了CSS文件中,便于被搜索引擎采集收录;
3、对浏览者和浏览器更具优势,由于CSS富含丰富的样式,使页面更加灵活性,它可以根据不同的浏览器,而达到显示效果的统一和不变形;
4、修改更有效率,由于使用了DIV+CSS制作方法,在修改页面的时候更加容易省时,提高工作效率;
16.为什么用多个域名存储网站资源更有效?
1、CDN缓存更方便
2、突破浏览器并发限制
3、节约cookie带宽
4、节约主域名的连接数,优化页面响应速度
5、防止不必要的安全问题
17.简要说明一下做好SEO需要考虑哪些方面?
1.TDK
2.图片+alt
3.友情链接
4.站点地图
第二部分:HTML单选题
1.以下描述错误的是(A)
1.    html需要先编译之后才能执行
2.    html需要存放在应用服务器端,客户端请求后才会将html程序返回给客户端
3.    html是需要浏览器解析的
4.    html语言就是把我们需要的内容显示在浏览器,但是html语言本身不显示
2.以下描述错误的是(C)
A.html分为<html><head><body>三个基本标记结构
B.head头标签,可以添加关键字描述网站优化网站
C.通常我们显示的内容都会放在<body>标签,通常html只能使用一次
D.<!DOCTYPE>属于HTML标签,它是一种标准通用标记语言的文档类型声明
3.在HTML语言中,设置表格单元格之间距离的是(B)和单元格和文字之间距离的是(C)
A.border
B.cellspacing
C.cellpadding
D.width
4.以下对标签描述正确的(多选)(ABC)
A.h1,h2,h3,h4,h5,h6标签是显示标题从h1到h6从大到小的过程
B.b标签呈现粗体文本
C.I标签呈现斜体文字
5.以下描述错误的是(D)
1.    html分为 <html> <head> <body>三个基本标记结构。
2.    head头标签可以加关键字、描述网站、优化网站
3.    通常我们显示的内容都会放在<body>标签,通常html只能使用一次。
4.    <!DOCTYPE> : 属于html标签,它是一种标准通用标记语言的文档类型声明。
6.以下说法错误的是(D)
A.<p> 标签 : 标签定义段落
B.<br> : 简单的换行
C.<dl>标签: 自定义列表
D.<dd>: 自定义标题
7.以下对标签描述正确的(多选)(A,C,D)
A.h1,h2,h3,h4,h5,h6 标签是显示标题从h1到h6,从大到小的过程
B.tt标签对表格的限定标签
C.b 标签呈现粗体文本
D.i 标签呈现斜体文字
8.在HTML语言中,设置表格单元格之间距离的标签是( B )和单元格内文字与边框的距离 的标签是(C)
A.<table border=””>
B.<table cellspacing=””>
C.<table cellpadding=””>
D.<table width=””>
第三部分:CSS问答题
1.介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的?
(1)有两种, IE 盒子模型、W3C 盒子模型;
(2)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border);
(3)区  别: IE的content部分把 border 和 padding计算了进去;
2.CSS选择符有哪些?哪些属性可以继承?
1.id选择器( # myid)
2.类选择器(.myclassname)
3.标签选择器(div, h1, p)
4.相邻选择器(h1 + p)
5.子选择器(ul > li)
6.后代选择器(li a)
7.通配符选择器( * )
8.属性选择器(a[rel = "external"])
9.伪类选择器(a:hover, li:nth-child)
可继承的样式: font-size font-family color, UL LI DL DD DT;
不可继承的样式:border padding margin width height
3.css定义的权重
标签的权重为1,class的权重为10,id的权重为100
4.如果需要手动写动画,你认为最小时间间隔是多久,为什么?
多数显示器默认频率是60Hz,即1秒刷新60次,所以理论上最小间隔为1/60*1000ms = 16.7ms
5.简单介绍下CSS的盒子模型,他都包含哪些属性?
  width,height,margin,padding,border
6.宽高都200px的div在浏览器窗口居中(水平垂直都居中)
  position:fixed;width:200px;height:200px;left:50%;top:50%;
  margin-left:-100px;margin-top:-100px;
7.一个满屏 品 字布局 如何设计?
   <div style=”margin:0 auto;width:50%;”></div>    <div>
<div style=”width:50%;float:left;”></div>
<div style=”width:50%;float:left;”></div>
   </div>
8.超链接访问过后hover样式就不出现了 被点击访问过的超链接样式不在具有hover和active了解决方法是改变CSS属性的排列顺序:
  L-V-H-A :  a:link {} a:visited {} a:hover {} a:active {}
9.display:none;跟visibility:hidden;的区别是啥?
  display:none;不占位,visibility:hidden;占位
10.低版本浏览器不支持display:inline-block属性,请问怎么兼容
*display:inline;*zoom:1;
11.在使用display:inline-block时,inline-block元素会有4px左右的空隙,这是什么原因导致的以及解决方法
(1) 取消换行和空格
(2) 设置父元素的font-size为0,在给子元素设置自身的字体大小
12.写出下面三个的区别?
*height{}
_height{}
+height{}
* IE7及以下
_IE6
+IE7
13.Inline-block默认的对其方式是什么?在使用inline-block时在内容不同的时候想要保持内容水平对齐,说一下你采用的方法?
默认对齐方式:base-line
水平对齐:vertical-align:top;
14.简明说一下CSS link于@import的区别和用法
link是XHTML标签,除了加载CSS外,还可以定义RSS等其他事务;@import属于CSS范畴,只能加载CSS。
link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。
link支持使用Javascript控制DOM去改变样式;而@import不支持。
第四部分:JS问答题
1、JS的数据类型有哪些?typeof运算符的执行结果都有哪些数据类型?
数据类型主要包括两部分:
基本数据类型: Undefined、Null、Boolean、Number和String
引用数据类型: Array 、Object
typeof运算符的结果类型:
number,string,boolean,object,function,undefined
2.null,undefined 的区别?
null        表示一个对象被定义了,值为“空值”;
undefined   表示不存在这个值。
3.怎么判断一个变量没有被定义
typeof bianliang ==”undefined”
4.怎么判断一个变量arr的话是否为数组(此题用typeof不行)
Arr instanceof Array
5.事件委托是什么
事件委托就是事件目标自身不处理事件,而是把处理任务委托给其父元素或者祖先元素,甚至根元素(document)。
6.描述下JSON对象的两个很重要的方法
JSON.parse() //JSON字符串转换为JSON对象
JSON.stringify() //JSON对象转化为字符串
7.写一个函数getRandomNumber(startNum,endNum),去除startNum到endNum之间的任意随机数
function getRandomNumber(startNum,endNum){
        var endRand = endNum - startNum + 1;
        //0~1中间的16位数字
        var randNum = Math.random();
        //随机取出来0~9之间的任意一个数字
        randNum = Math.floor(randNum * endRand);
        return randNum+startNum;
}
8.写一个通用的去除字符串左右空格的函数?
String.prototype.strim = function(){
return this.replace(/(^\s|\s$)/g,””);
}
9.a = [1,2,3,4];b=a;a.push(2);b.push(3);请问,最终a,b的结果分别是多少?
a为[1,2,3,4,2,3],b为[1,2,3,4,2,3]
10.检测浏览器的两种方式
功能检测 “touchstart” in document
特征检测  navigator.userAgent
11.“ ===”、“ ==”的区别?
==,当且仅当两个运算数相等时,它返回 true,即不检查数据类型
===,只有在无需类型转换运算数就相等的情况下,才返回 true,需要检查数据类型
12.原型、原型链?
每个由构造函数new出来的实例化对象都自带一个_proto_属性,该属性指向创建它的构造函数的prototype对象。而prototype对象因为是实例,也有自己的_proto_属性,指向它的原型对象。当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,
于是就这样一直找下去,也就是我们平时所说的原型链的概念。
关系:instance.constructor.prototype = instance.__proto__
13.eval是做什么的?
它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)。
由JSON字符串转换为JSON对象的时候可以用eval,var obj =eval('('+ str +')');
14.["1", "2", "3"].map(parseInt) 答案是多少?
[1, NaN, NaN] 因为 parseInt 需要两个参数 (val, radix),
其中 radix 表示解析时用的基数。
map 传了 3 个 (element, index, array),对应的 radix 不合法导致解析失败。
15.简单语言测试:有数组dataarray,值为-100到100的整数,求出数组中大于0的数的和;
var x=0;
for(var i=0;i<dataarray.length;i++){
if(dataarray>0){
x+=dataarray;
}
}
16.简单jQuery:请写出代码,ul标签下面有1000个li,写一个性能最高的方式实现,在点击li后,输出li的内容
$(“ul”).on(“click”,”li”,function(){
$(this).html(“hit”);
})
17.用fetch方法构造一个Get请求,要求把当前页面cookie传过去,请写出代码;
fetch(url,{
    method:"GET",
credentials:"include",
    body:document.cookie
})
18.简述下为何通过ajax发送的请求会出现乱码问题,如何解决?
乱码的问题就是编码格式冲突,我们需要传输中文数据前面加一个encodeURI()编码,例如:encodeURI(j$("#fk_info").val());在接受参数的页面对传过来的编码过后的内容用后端语言进行解码
19.简述DOM,HTMLDOM的区别和联系
DOM分为三部分:
(1)核心DOM:遍历DOM树、添加新节点、删除节点、修改节点
(2)HTML DOM:以一种简便的方法访问DOM树
(3)XML DOM:准用于操作XML文档
核心DOM与HTML DOM的区别:
核心DOM :
对象:Document,Node,   ElementNode,TextNode,AttributeNode,CommentNode,NodeList
核心DOM提供了统一的操作接口,如:createElement、appendChild、setAttribute等
核心DOM创建新元素:var newNode=document.createElement("img")
给元素添加属性:e.setAttribure()、e.setAttribureNode()
适用场合:核心DOM适合操作节点,如创建,删除,查找等
HTML DOM:
对象:image,Table,Form,Input,Select等等HTML标签对象化
HTML DOM提供了封装好的各种对象,如:Select、Option等等
适用场合:HTML DOM适合操作属性,如读取或修改属性的值
20.什么是事件流
DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。DOM同时支持两种事件模型:捕获型事件和冒泡型事件
21.JavaScript原型继承是如何运作的?
每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去(知道找到null为止),也就是我们平时所说的原型链的概念。
22.CORS是什么?对于跨域请求,如何将附带凭证(HTTP Cookie 及 HTTP认证信息)的请求发送至服务器端?
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。只需要服务器端的Response header 设置下Access-Control-Allow-Origin即可。
只需把相应的cookie信息和认证信息作为post请求发送给服务器端即可。
23.DOM元素Attribute与Property的区别是什么?
1、 property是DOM中的属性,是JavaScript里的对象;而attribute是HTML标签上的特性,它的值只能够是字符串;
2、DOM对象初始化时会在创建默认的基本property;只有在HTML标签中定义的attribute才会被保存在property的attributes属性中;
3、attribute会初始化property中的同名属性,但自定义的attribute不会出现在property中;
4、propety是对象,而attribute的值都是字符串;
5、最关键的两句话:
attribute(特性),是我们赋予某个事物的特质或对象。
property(属性),是早已存在的不需要外界赋予的特质。
24.Long-Polling、WebSocket、SSE(Server-Sent Events)之间有什么差异?请写出WebSocket在浏览器端如何发送及接收消息的相关代码实现(需要考虑传输一场并根据返回数据的格式做不同处理)
Long-Polling 自己主动请求数据来获知文件知否发生变化  缺点:会有很多无效请求
SSE 服务器端通知客户端数据变化 服务器端客户端保持一个长连接 缺点:保持长连接需要占用大量的服务器端只要
WebSocket 实时通信 缺点:浏览器支持情况没有上面两种方法好
25.实现以下函数:
add(10,10);==>20
add(10)(10);==>20
function add(num){
    if(arguments.length==1){
     return function(num1){
           return num+num1;
        }
    }else{
        var sum = 0;
        for(var i=0;i<arguments.length;i++){
         sum += arguments;
        }
        return sum;
   }
}
26.实现以下代码:
[a,b,3,4,5].copy();==>[a,b,3,4,5, a,b,3,4,5]
var array = ['a','b',3,4,5];
Array.prototype.copy = function(){
return this.concat(this);
}
console.log(array.copy());
27.指出下面代码的区别
function Order(){
}
var order = Order();  (1)
var order = new Order();(2)
代码(1)是将函数Order()作为一个普通函数去调用的,代码(2)是将Order()作为一个构造函数去调用的;当函数Order的方法体中有this关键之的时候,作为普通函数this指的是window对象,作为构造函数存在的时候this指代的是本对象
28.var foo = "Hello";
(function (){
var bar = "World";
alert(foo+bar);
})();
alert(foo+bar);
以上语句会产生什么样的结果?
(1)HelloWorld
(2)undefined
29.函数call和apply的区别:
相同点:两个方法产生的作用是完全一样的
不同点:方法传递的参数不同,call是参数往后累加,apply是把所有参数合并为一个数组传给函数的第二个参数
30.语句(window.foo||(window.foo=”bar”));执行后,window.foo的值是多少?
Bar
31.使用jquery做一次ajax请求,请求类型为post,传入参数是json格式,url为http://xxx.com,传入参数是{username:“abc”},请求成功返回一个数组例如[1,2,3,4,5]然后对这个数组进行处理后得到一个新的数组,[1,2,3,4,5, 1,2,3,4,5]并输出到日志
Array.prototype.copy = function(){
return this.concat(this);
}
$.ajax({
url:“http://xxx.com”,
type:'post',
dataType:“json”,
data: {username:“abc”},
success:function(data){
console.log(data.copy());
}
});
32.以下语句结果a,m的值
var a = "15.56";
var b = 20.23;
var a = parseInt(a)+parseInt(b);
var m = parseFloat(a);
a:35  m:35
33.var numberArray = [ 3,6,2,4,1,5 ],
(1)实现对该数组的倒排 ,输出[5,1,4,2,6,3]
var result = numberArray.reverse( );
alert(result);
(2)实现对该数组的降序排列,输出[6、5、4、3、2、1]
var result = numberArray.sort(function(a,b){return b-a});
alert(result);
34.$(document).ready()是个什么函数?为什么要用它。
问题一: $(document).ready()这个函数是用来取代页面中的window.onload; 不同的是onload()的方法是在页面加载完成后才发生,这包括DOM元素和其他页面元素(例如图片)的加载,因此,使用document.ready()方法的执行速度比onload()的方法要快。
问题二:Javascript 只有在DOM元素已经定义以后才可以对其执行某种操作,jQuery使用document.ready来保证所要执行的代码是在DOM元素被加载完成的情况下执行。
35.读下面代码:
window.color = 'red';
var o= {color:'blue'};
function sayColor(){
   alert(this.color);
}
请在每行末尾写出该行的输出:
sayColor();   
sayColor.call(this);
sayColor.call(window)
sayColor.call(o)
答案:  red 、red、red、blue
36.请写一个正则,匹配输入的字符:第一个必须是字母或下划线开头,后面就是字母和数字或下划线构成,长度5-20.
答案: /^[A-Za-z_]\w{4,19}$/
37.JS中原型链最上层的对象是  object 的原型对象,该对象的_proto_指针指向  null    的原型对象。
38.JS中使用 Object 对象的 defineProperty    函数定义对象属性的访问器。
39.如何对一篇文章进行敏感词替换?假如有几千个敏感词。(写一下思路即可)
将这篇文章以字符串的形式赋给一个变量。定义一个正则表达式,以全局匹配的方式查找所有敏感词,并用replace方法替换掉
40.添加、删除、更改、插入节点的方法
appendChild
removeChild
replaceChild
insertBefore
41.在javascript编程中,请至少说出三种异步操作的使用场景?
回调函数
事件监听
Promise对象
Nodejs的异步方法
42.请用闭包的方式写一个方法,第一次执行返回999,第二次返回1000.
function bb(){
var num = 999;
return function(){
return num++;
}
}
var fun = bb();
fun();
fun();
43.现在有一个数组[1,4,5,8,100],请写一个方法,每秒输出数组的第一个元素,知道整个数组输出完毕
var arr = [1,4,5,8,100];
function output(){
setTimeout(function(){
console.log(arr.splice(0,1)[0]);
if(arr.length>0){
output();
}
   },1000);
}
output();
44.请给Array本地对象的prototype添加一个原型方法,它的作用是剔除重复的条目,并将新数组返回
Array.prototype.unique = function(){//数组去除重复
  var res = [];
   var json = {};
   for(var i = 0; i < this.length; i++){
    if(!json[this]){
       res.push(this);
       json[this] = 1;
    }
   }
   return res;
}
第五部分:JS单选题
1、 下列JavaScript的循环语句中(D)是正确的
A、 if(var i < 10;i++)
B、 for(var i = 0;i < 10)
C、 for var i = 1 to 10
D、 for(var i = 0;i <= 10;i++)
2、 下列的哪一个表达式将会返回假(B)
A、 !(3<1)
B、 (4>=4)&&(5<=2)
C、 (“a”==”a”)&&(“C”!=”d”)
D、 (2<3)||(3<2)
3、 下列选项中,(D)不是网页事件
A、 onclick
B、 onmouseover
C、 onsubmit
D、 Onp
4、 有语句“var x = 0;while(   )x+=2;”,要使while循环体执行10次,空白的循环判断式应该为(D )
A、 x < 10;
B、 x <= 10;
C、 x < 20;
D、 x <= 20;
5、 以下说法中错误的是(D )
A、 var a = 111;
B、 var a = “张三”;
C、 var _name = “小明”;
D、 var &_id = “1”;
6、 下列JS的判断语句中(A)是正确的
A、 if( i == 0)
B、 if( i = 0)
7、下列JavaScript的循环语句中()是正确的
A.if(var i < 10; i++)
B.for(var i = 0;i < 10)
C.for var i = 1 to 10
D.for(var i=0; i<10; i++)
答案:D
8、下列的哪一个表达式将会返回假()
1.    !(3 <= 1)
2.    (4 >= 4) && (5 <= 2)
3.    ( “a” == “a”) && (“C” != “d”)
4.    (2<3) || (3<2)
答案:B
9、下列选项中,()不是网页中的事件
1.    onclick
2.    onmouseover
3.    onsubmit
4.    onp
答案:D
10、有语句“var x = 0; while( )x+2;”,要是while循环体执行10次,空白的循环判定式应该为()
1.    x < 10
2.    x <= 10
3.    x < 20
4.    x <= 20;
答案:C
11、以下说法错误的是()
1.    var a = 111;
2.    VAR a = ‘张三’;
3.    var _name = “小明”;
4.    var &_id=1;
答案:BD
12、以下JS的判断语句中()是正确的
1.    if (i == 0)
2.    if (i =0)
答案:A
13、以下不是引入js的方式选项的是(D)
A.使用script标签
B引入外部的js文件  
C在事件中编写js  
D使用<link></link>引入
14、Js语句
var a1 = 10;
var a2 = 20;
alert("a1+a2="+a1+a2)将显示的结果是(B)
A.a1+a2=30
B.a1+a2=1020
C.a1+a2=a1+a2
D.a1+a2=30+a1+a2
15.var a=document.getElementById(“id”);
a.onclick = fun1;
a.onclick = fun2;
对象a被绑定的点击事件执行函数是什么?(B)
1.    fun1
2.    fun2
3.    执行错误
4.    两个函数都被绑定
16.以下那条会产生运行错误(A)
1.    var obj = ()
2.    var obj = []
3.    var obj = 11
4.    var obj
17.以下说法正确的是(C)
A.数字+字符=数字 (字符)
B.数字+boolean = true;(数字)
C. 数字+null = 数字
D.数字+undefined = isNaN   (NaN)
18.以下不是引入javascript的方式 的选项是? (D)
1.    使用script标签
2.    引入外部的javascript文件
3.    在事件中编写javascript
4.    使用<link></link>引入
第六部分:HTML5+CSS3
1.HTML5、CSS3里面都新增了那些新特性?
新的语义标签
本地存储
离线存储
Websocket
2d,3d变换
Transition,animation
媒体查询
新的单位(rem,vw,vh等)
2.HTML5 为什么只需要写 <!DOCTYPE HTML>?
HTML5 不基于 SGML(标准通用标记语言),因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行);
而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。
3.如何处理HTML5新标签的浏览器兼容问题?
IE8/IE7/IE6支持通过document.createElement方法产生的标签,
可以利用这一特性让这些浏览器支持HTML5新标签,
浏览器支持新标签后,还需要添加标签默认的样式。
<!--[if lt IE 9]>
<script type="text/javascript" src="js/html5shiv.js"></script>
<![endif]-->
将上代码复制到head部分,记住一定要是head部分(因为IE必须在元素解析前知道这个元素,所以这个js文件不能在其他位置调用,否则失效)
最后在css里面加上这段:
article,aside,dialog,footer,header,section,footer,nav,figure,menu{display:block}
主要是让这些html5标签成块状,像div那样。
4.cookies,sessionStorage 和 localStorage 的区别?
cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。
cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。
sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
存储大小:
cookie数据大小不能超过4k。
sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
生命周期:
localStorage    存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage  数据在当前浏览器窗口关闭后自动删除。
cookie         设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
5.什么叫优雅降级和渐进增强?
优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会针对旧版本的IE进行降级处理了,使之在旧式浏览器上以某种形式降级体验却不至于完全不能用。
如:border-shadow
渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新版本浏览器才支持的功能,向页面增加不影响基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。
如:默认使用flash上传,但如果浏览器支持 HTML5 的文件上传功能,则使用HTML5实现更好的体验;
6.transition和animation的区别
transition是过渡,animation是动画。transition只能从一种状态过渡到另外一种状态,animation可以定制复杂动画,可以定义动画的区间等。
transition必须通过一些行为才能触发(js或者伪类来触发),animation的话直接就可以触发。
7.HTML5的form如何关闭自动完成功能?
给不想要提示的 form 或某个 input 设置为 autocomplete=off。
8.margin-left:calc(-100%-100px) 代码中用到了一个calc(),这个函数的作用是什么?
答:通过计算来确定CSS属性值。
calc是英文单词calculate(计算)的缩写,是css3的一个新增的功能,你可以使用calc()给元素的border、margin、pading、font-size和width等属性设置动态值。calc()可以使用数学运算中的简单加(+)、减(-)、乘(*)和除(/)来解决问题,而且还可以根据单位如px,em,rem和百分比来转化计算
9.简述HTML5新增的canvas、audio、svg标签的作用
canvas被称作画布,canvas 元素使用 JavaScript 在网页上绘制图像。 画布是一个矩形区域,可以控制其每一像素。
audio标签可以引用音频资源,在页面上播放音乐
svg用XML格式定义图形,可以用来制作矢量图形。
10.简述如何通过CSS进行响应式布局的方式
响应式布局使用媒体查询@media 定义多个分辨率下的样式,使页面在不同的分辨率下显示不同的样式
11.CSS的单位中,设定元素的长度或宽度与父元素字体大小相关的单位是什么?与html文档元素大小相关的单位是什么?
em 、rem
13.在CSS中使用 media 关键字判断不同的屏幕使用不同CSS文件,使用 @media   个关键字判断不同屏幕使用不同的CSS样式类。
14.CSS3实现一段阴影文本持续淡入淡出?
HTML结构 :  <div class=”box”>文本</div>
CSS样式:
       .box {
            text-shadow : 1px 1px 2px #F00;
            -moz-animation:fade 1s infinite;
            -webkit-animation:fade 1s infinite;
            -o-animation:fade 1s infinite;
            animation:fade 1s infinite;
        }
        @keyframes fade {
            0% { opacity: 0;}
            50% { opacity: 100;}
            100% { opacity: 0;}
        }
        @-webkit-keyframes fade {
            0% { opacity: 0;}
            50% { opacity: 100;}
            100% { opacity: 0;}
        }
        @-moz-keyframes fade {
            0% { opacity: 0;}
            50% { opacity: 100;}
            100% { opacity: 0;}
        }
        @-o-keyframes fade {
            0% { opacity: 0;}
            50% { opacity: 100;}
            100% { opacity: 0;}
        }
15.简述如何通过CSS进行响应式布局的方式。
meta标签定义: 使网页适配设备宽度。
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" />
使用Media Queries适配对应样式
16.如何使用Canvas来画一条简单的线?
var canvas=document.getElementById("canvas");
var cxt=canvas.getContext('2d');
cxt.beginPath();
cxt.lineWidth=10;
cxt.strokeStyle="#00ff00";
cxt.moveTo(20,20);
cxt.lineTo(100,20);
cxt.stroke();
cxt.closePath();
17.rgba和opacity的透明效果有什么不同?
opacity会继承父元素的 opacity 属性,而RGBA设置的元素的后代元素不会继承不透明属性。比如rgba的话,内部的文字透明度不会发生变化,而opacity的话,会影响到内部的文字
18.FontAwesome和iconfont是什么?他们有什么异同,问什么要使用它,有什么弊端?
两个都是图标字体。Font Awesome 是一套完美的图标字体,主要目的是和 Bootstrap 搭配使用
Iconfont是阿里的字体库,可以定制自己要的字体图标。
优势:
1、轻量性:一个图标字体比一系列的图像(特别是在Retina屏中使用双倍图像)要小。一旦图标字体加载了,图标就会马上渲染出来,不需要下载一个图像。可以减少HTTP请求,还可以配合HTML5离线存储做性能优化。
2、灵活性:图标字体可以用过font-size属性设置其任何大小,还可以加各种文字效果,包括颜色、Hover状态、透明度、阴影和翻转等效果。可以在任何背景下显示。使用位图的话,必须得为每个不同大小和不同效果的图像输出一个不同文件。
3、兼容性:网页字体支持所有现代浏览器,包括IE低版本。详细兼容性可以点击这里。
弊端:
只能单色
跨域问题
字体图标库似乎体积显得有些过大
19.什么是响应式设计?
它是关于网站的制作或网页制作的工作。不同的设备有不同的尺寸和不同的功能。响应式设计是让所有的人能在这些设备上让网站运行正常。一部分是媒体查询和不同的视觉效果。一部分是不同的资源(如不同的Javascript来处理触摸与点击自动适应屏幕的对比)。
20.解释下这个CSS选择器什么发生什么?
[role=navigation] > ul a:not([href^=mailto]) {}
定义了role属性,并且值为navigation的任何元素,其子元素列表下的除邮箱链接之外的所有链接元素。
能够用语言表达清楚这个选择器,证明你理解他们和可以使用他们做一些技术交流。
第七部分:必考题
HTML+CSS篇:
1.如何处理HTML5新标签的浏览器兼容问题?(自己需要试试)
<!--[if lt IE 9]>
<script type="text/javascript" src="js/html5shiv.js"></script>
<![endif]-->
将上代码复制到head部分,记住一定要是head部分(因为IE必须在元素解析前知道这个元素,所以这个js文件不能在其他位置调用,否则失效)
最后在css里面加上这段:
article,aside,dialog,footer,header,section,footer,nav,figure,menu{display:block}
主要是让这些html5标签成块状,像div那样。
2.简单介绍下CSS的盒子模型,他都包含哪些属性?
width,height,margin,padding,border
3.宽高都200px的div在浏览器窗口居中(水平垂直都居中)?
position:fixed;width:200px;height:200px;left:50%;top:50%;margin-left:-100px;margin-top:-100px;
4.经常遇到的浏览器的兼容性有哪些?原因,解决方法是什么,常用hack的技巧 ?
不同浏览器都会带有自己的浏览器默认样式,一般我们需要把这些浏览器默认自带的样式给清楚,一般我们借助reset.css(我们公司里开发前端页面都用这个来清楚浏览器默认样式)
display:inline-block(IE7及以下不支持)
需要对低版本IE特殊处理:{display:inline-block;*display:inline;*zoom:1;}
display:inline-block 什么时候会显示间隙?怎样消除间隙?
父元素font-size设置成0,子元素重新设置font-size
display:inline-block滥用容易出现布局方面的问题,尤其在左中右、左右等布局方面的问题尤为突出。因此如果是左右布局的话,尽量都用浮动来代替
z-index在IE7及以下版本的话,有时会发现不是谁z-index设置的越高谁就显示在最上面。碰到这种问题需要设置父元素有相对定位属性元素的z-index。先比较父元素的z-index再比较子元素的
IE6双边距
IE6中,元素向左浮动并且设置了左侧的外边距出现了这样的双边距bug。同理,元素向右浮动并且设置右边距也会出现同样的情况。同一行如果有多个浮动元素,第一个浮动元素会出现这个双边距bug,其它的浮动元素则不会。只需要给浮动元素加上display:inline;这样的CSS属性就可以了。
margin-top,margin-bottom的bug
父元素的第一个子元素设置了margin-top,会作用于父元素(值为父元素的margin-top与该margin-top两者中的最大值),而子元素和父元素的边距则没有发生变化。
5.IE8-(IE8及以下)rgba模式不兼容的解决方案
IE8以及以下用滤镜, filter:Alpha(opacity=20); 6.CSS Hack
什么是CSS hack
由于不同厂商的流览器或某浏览器的不同版本(如IE6-IE11,Firefox/Safari/Opera/Chrome等),对CSS的支持、解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果。这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的CSS样式,我们把这个针对不同的浏览器/不同版本写相应的CSS code的过程,叫做CSS hack!
CSS hack的原理
由于不同的浏览器和浏览器各版本对CSS的支持及解析结果不一样,以及CSS优先级对浏览器展现效果的影响,我们可以据此针对不同的浏览器情景来应用不同的CSS。
CSS hack分类
科普
lte:就是Less than or equal to的简写,也就是小于或等于的意思。
lt :就是Less than的简写,也就是小于的意思。
gte:就是Greater than or equal to的简写,也就是大于或等于的意思。
gt :就是Greater than的简写,也就是大于的意思。
! :就是不等于的意思,跟javascript里的不等于判断符相同
CSS Hack大致有3种表现形式,CSS属性前缀法、选择器前缀法以及IE条件注释法(即HTML头部引用if IE)Hack,实际项目中CSS Hack大部分是针对IE浏览器不同版本之间的表现差异而引入的。
属性前缀法(即类内部Hack):例如 IE6能识别下划线""和星号" * ",IE7能识别星号" * ",但不能识别下划线"",IE6~IE10都认识"\9",但firefox前述三个都不能认识.
.all IE{property:value\9;} .gte IE 8{property:value\0;} .lte IE 7{*property:value;} .IE 8/9{property:value\0;} .IE 9{property:value\9\0;} .IE 7{+property:value;} .IE 6{_property:value;} .not IE{property//:value;}
选择器前缀法(即选择器Hack):例如 IE6能识别html .class{},IE7能识别+html .class{}或者*:first-child+html .class{}。
IE条件注释法(即HTML条件注释Hack):针对所有IE(注:IE10+已经不再支持条件注释): <!--[if IE]>IE浏览器显示的内容 <![endif]-->,针对IE6及以下版本: <!--[if lt IE 6]>只在IE6-显示的内容 <![endif]-->。这类Hack不仅对CSS生效,对写在判断语句里面的所有代码都会生效。
只在IE下生效 <!--[if IE]> 这段文字只在IE浏览器显示 <![endif]-->
只在IE6下生效 <!--[if IE 6]> 这段文字只在IE6浏览器显示 <![endif]-->
只在IE6以上版本生效 <--[if gte IE 6]> 这段文字只在IE6以上(包括)版本IE浏览器显示 <![endif]-->
只在IE8上不生效 <!--[if ! IE 8]> 这段文字在非IE8浏览器显示 <![endif]-->
非IE浏览器生效 <!--[if !IE]> 这段文字只在非IE浏览器显示 <![endif]-->
7.让学生写一个CSS3动画?并让描述transition和animation的区别
transition是过渡,animation是动画。transition只能从一种状态过渡到另外一种状态,animation可以定制复杂动画,可以定义动画的区间等。
transition必须通过一些行为才能触发(js或者伪类来触发),animation的话不需要直接就可以触发。
JS篇:
1.    知道不知道事件冒泡?知不知道阻止浏览器的默认行为?对应的原生兼容性写法该怎么写
知道事件冒泡,一般我们需要阻止事件冒泡。
事件冒泡
父元素和子元素上面的话都添加的有click(不仅仅是click事件,只要保证是同一个事件即可)。子元素的click事件触发的时候,会导致该click事件冒泡到它的父元素上面,为了阻止父元素的事件触发,我们一般需要给子元素的事件里写上阻止事件冒泡的方法
场景:(下拉菜单)点击空白区域关闭下拉菜单
兼容性写法:
if(event.stopPropagation){
    event.stopPropagation();
}else if(event.cancelBubble){
    event.cancelBubble = true;
}
阻止浏览器默认行为
当我们不希望一些浏览器默认行为触发的时候,就需要给对应的事件添加上阻止浏览器默认行为。
场景:
禁止a链接的点击后发生跳转
禁止UC等手机浏览器左右滑动切换到前一页或者下一页(我们可以通过给document的touchmove事件加上阻止浏览器默认行为的方法)
1.    知不知道用没用过事件委托?它的好处是啥?
1, 提高性能。
2, 新添加的元素还会有之前的事件。
详见:http://www.jb51.net/article/88425.htm
1>提高性能 2>新添加的元素还会有之前的事件
1.    什么是闭包(closure),为什么要用它?
闭包就是能够读取其他函数内部变量的函数,如果一个函数内部又定义了一个内部函数,并将该内部函数作为返回值返回或者存储在某个对象的属性里,这时就会形成一个闭包。
使用场景:1.匿名自执行函数2缓存 3实现封装(封装的方式有很多,闭包只是其中一种,不是说到封装就一定会用闭包)
闭包的优缺点
闭包的优点:
1.缓存
2.面向对象中的对象
3.实现封装,防止变量跑到外层作用域中,发生命名冲突
4.匿名自执行函数,匿名自执行函数可以减小内存消耗
闭包的缺点:
1.闭包有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅因为它常驻内存,更重要的是,对闭包的使用不当的话会造成无效内存的产生
2.性能问题 使用闭包时,会涉及到跨作用域访问,每次访问都会导致性能损失。
因此在脚本中,最好小心使用闭包,它同时会涉及到内存和速度问题。不过我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响。
1.    知道原型和原型链么,一般什么时候需要用?
原型:
主要作用是用于继承
原型的作用是为函数对象声明通用的变量或者函数,构造函数的实例都会从原型上继承属性和方法。
每个对象中都有__proto__属性,这个属性指向的就是它基于的原型对象。
原型链:
var person = function(name){
   this.name = name
  };
  person.prototype.getName = function(){
     return this.name;
  }
  var zjh = new person(‘zhangjiahao’);
  zjh.getName(); //zhangjiahao
JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。以上面的例子为例:
  console.log(zjh.__proto__ === person.prototype) //true
同样,person.prototype对象也有__proto__属性,它指向创建它的函数对象(Object)的prototype
  console.log(person.prototype.__proto__ === Object.prototype) //true
继续,Object.prototype对象也有__proto__属性,但它比较特殊,为null
  console.log(Object.prototype.__proto__) //null
我们把这个有__proto__串起来的直到Object.prototype.__proto__为null的链叫做原型链
我们调用一个对象的属性或者方法的时候,会存在一个优先级的问题。优先级为:
构造函数内定义的属性>构造函数的原型上定义的属性>沿着__proto__指定的原型(原型链)一直往上找,直到找到null为止。任何一步一旦找到就立马停止,不会继续往下找。
1.    有没有封装过插件,你一般怎么封装呢
逼格低点的话这样说:
封装过,以前我主要是把一些公共的功能封装成函数来实现简单封装,比如tab切换封装的时候我会定义一个叫tab的函数,选项卡节点和内容节点作为函数tab的参数。假如我一个页面有多个tab切换,我只需要执行函数的时候给函数传入不同的参数即可。
逼格高点的这样说:
封装过,我们主要用面向对象中的混合模式来封装插件,把可变的属性或者方法(通常都是属性)在构造函数内定义,把一些不变的属性或者方法(通常是方法)定义在函数的原型上面。我们封装好的插件通常会放在一个匿名自执行函数里面,这样做的目的是为了避免变量冲突。
1.    怎么判断一个变量str是否被赋值?
typeof str == “undefined”
1.    怎么判断一个变量arr的话是否为数组(此题用typeof不行)
instanceof arr Array
1.    Ajax和jsonp的原理?
Ajax的原理(最次最次也得把XMLHttpRequest对象说出来)
Ajax基于XMLHttpRequest对象与Web服务器端进行异步数据通信。
首先基于这个对象的open方法创建一个浏览器跟服务器端连接,通过send方法从浏览器向服务器端发送请求。我们可以通过这个对象的onreadystatechange事件来监听请求的状态,当请求成功之后的话,我可以获取到这个对象responseText等方法获取到请求过来的数据,然后通过js对这些数据进行解析
Jsonp原理
Ajax不能跨域,但是script标签和img标签都可以跨域。jsonp的话就是动态创建一个script标签,把jsonp数据格式(callback(json))的接口的地址赋值给我们的script标签的src属性。每一次发送jsonp请求的时候都会创建一个全局的回调函数,全局回调函数名称跟我们jsonp接口里面的函数名称是一致的。全局函数里面写的就是对请求过来数据的操作。
Ajax不能跨域,JSONP可以跨域。
移动篇:
1.你们移动端怎么开发的?用的什么单位、js框架呢、怎么真机调试你们程序、怎么解决前缀问题呢
首先我们移动端用的是rem这个单位,移动端实际上还新增了vw,vh等一些单位,但是相对于rem来说,他们的兼容性都不好。rem是一个相对单位,是相对于根节点的font-size的比例。我们还会引用一个外部的js,这个js可以通过屏幕宽度动态计算根节点的font-size值。
我们移动端用的JS框架是zepto.js,因为相应来说它的的体积的话要小很多。而且我们项目中有时会需要使用一些触屏事件,比如滑动事件,那么我们还会调用它里面的touch模块
我们webapp的话都是基于gulp搭建的前端工程来开发,因为利用gulp起一个webserver特别简单,并且我还可以实现livereload功能(当我监控的文件发生变化的时候,可以触发浏览器的自动刷新功能),而且在css3里面加前缀的话是一个很头疼的问题,我们现在只需要用autoprefixer模块就可以很容易实现自动加css3前缀这个功能了。
2. 移动端兼容性?
1>ios移动端click事件300ms的延迟响应. 用fastclick来解决
2>zepto的touch模块的tap事件有点透的问题,也是用fastclick来解决
3>一些情况下对非可点击元素如(label,span)监听click事件,ios下不会触发,css增加cursor:pointer就搞定了
4>ios下取消input在输入的时候英文首字母的默认大写
<input autocapitalize="off" autocorrect="off" />
5>fixed定位缺陷
ios下fixed元素容易定位出错,软键盘弹出时,影响fixed元素定位
android下fixed表现要比iOS更好,软键盘弹出时,不会影响fixed元素定位
ios4下不支持position:fixed
解决方案: 可用iScroll插件解决这个问题
6>Input 的placeholder会出现文本位置偏上的情况
input 的placeholder会出现文本位置偏上的情况:PC端设置line-height等于height能够对齐,而移动端仍然是偏上,解决是设置line-height:normal
7>calc的兼容性处理
CSS3中的calc变量在iOS6浏览器中必须加-webkit-前缀,目前的FF浏览器已经无需-moz-前缀。
Android浏览器目前仍然不支持calc,所以要在之前增加一个保守尺寸:
div {
    width: 95%;
    width: -webkit-calc(100% - 50px);
    width: calc(100% - 50px);
}
8>在移动端修改难看的点击的高亮效果,iOS和安卓下都有效:
* {-webkit-tap-highlight-color:rgba(0,0,0,0);}
9>阻止旋转屏幕时自动调整字体大小
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {-webkit-text-size-adjust:none;}
3.谈谈你对bootstrap的认识,用它做过项目么?
用Bootstrap主要用来做一些响应式的网站,它里面栅格化这块比较强大,我可以针对不同的屏幕尺寸定制不同页面结构。
我还用它做过后台管理系统,因为它里面集成的有风格标准统一的组件、插件、全局样式等,是我们做后台管理系统的话,不用再花大精力去布局页面了。而且甚至产品给我们一个原型图我们就可以开始开发,大大提高了开发效率。
综合:
1.    网页前端性能优化的方式有哪些?
1.压缩css,js,图片
2.减少http请求次数,  合并css,js   合并图片(雪碧图)
3.使用CDN
4.减少dom元素数量
5.图片懒加载
6.静态资源另外用无cookie的域名
7.减少dom的访问(缓存dom)
8.巧用事件委托
9.样式表置顶、脚本置低
1.    简单描述一下你做过的项目研发流程?
1>约定规范(目录结构、命名规范、代码书写规范)
2>由我们组长(公司有的叫组长有的叫leader)给我们搭建前端工程gulp(最起码把browsersync模块能说出来,用它创建一个局域网server并实现监控文件有变化就自动刷新功能)(另外搭建前端工程的时候就会把我们会用到的库或者插件放进去)、拆分不同的前端模块给我们开发
3>正式开发(我们通过git工具来进行)
4>代码review(由我们组长来帮我们做)
5>交付给后端开发工程师,需要帮他们联调的话到时再帮他们联调
1.    看你简历上面写的你会nodejs还有gulp,能给我描述下你都用这俩东西做过什么东西么?
nodejs可以做一些服务器端的应用,比如我们可以用它搭建一个webserver(基于express框架可以实现)。我本人呢nodejs搭建webserver这块主要也是从网上看到一些文档自学的,谈不上精通。
我们公司的话主要用gulp来实现我们前端自动化。比如以前我们公司做webapp的项目有这样的需求,我们会用sass这个预编译器,我们写css3属性的时候我们经常还会用autoprefixer这个插件,我们发布上线的时候还需要把css文件进行压缩,如果没有一个很好的工具能帮我们管理并自动实现上面的操作的话,还是挺麻烦的。现在我们就可以用gulp来实现这些操作的自动化
1.    你有跟后端合作的经验是吧,你们都怎么协作的呀?
第一种回答:(smarty啥都描述不出来,ajax交互这块特别特别差的学生,但这限定了你能就业的公司,因为大部分公司还是希望他招的人是很全面的人才,所以这个不推荐)
我们公司前端代码做完之后,直接就把前端代码的话交给后端了,页面绑定数据和ajax这块基本上都是后端开发工程师来完成的。除非他们碰到一些复杂点的js特别难写或者有些js的话需要处理样式这块的话会来让我们弄。
第二种回答:(适合大部分同学,前提你得理清楚)
我们公司的话,后端用的php语言,平时的话我们也会套一些smarty模板,只要我们前后端约定一下数据格式,然后我按照smarty模板的一些语法把数据解析成最终的HTML。
另外我们公司ajax这块的话一般都由我们前端来做,而且后端做的ajax这块我们通常也会去看下,尤其是ajax调用成功还需要js操作css样式这块的情况。Ajax接口这块的话,我们会事先约定下数据格式,我们公司的接口一般都是json格式的,而且我们有个文档是专门描述这个接口(里面通常会描述下返回结果是对象还是数组,对应里面的每一项又都是啥),我们前端只需要把json格式的数据结合上html渲染到我们也没对应的位置即可。我们拿到数据的话,现在一般很少直接用js拼接html了,一般会借助js模板引擎(handlerbars)来做这方面工作。
其他:
1.平常碰到问题一般都是怎么解决的呢?
百度、看一些博客(csdn、博客园cnblogs)、去论坛提问(比如知乎)、开发者问答社区(segmentfault)、会加一些qq技术交流群
看前端大牛的博客
玉伯 kissy框架(PC端淘宝、天猫),sea.js(前端模块加载器)
司徒正美 avalon(前端MVC框架)
阮一峰(翻译了很多国外文档)
张鑫旭(写了大量的博客,用生活化的例子来解释难点)
大漠穷秋(angular1,angular2慕课网视频教程)
徐飞(技术栈)
朴灵
寸志
2.专业宽度方面:最近在学习哪些新技术呀,以后准备往哪方面发展?
我最近在学习react。。。
我最近在学习sea.js。。。
我最近在学require.js。。。
我最近正在恶补node.js。。。
技术方向:高级前端开发工程师、全栈工程师(前端+后端nodejs)、前端架构师
管理方向:前端leader(前端主管、前端经理)、项目经理、CTO
3.你都做过什么项目呢?让他具体聊某一个项目中运用的技术
注意:用心找自己做的项目中自己感觉最拿出来手的(复杂度最高,用的技术最多的项目),描述的时候尽可能往里面添加一些技术名词
布局我们用html5+css3
我们会用reset.css重置浏览器的默认样式
JS框架的话我们选用的是jQuery(也可能是Zepto)
我们用版本控制工具git来协同开发
我们会基于gulp搭建的前端自动化工程来开发(里面包含有我们的项目结构、我们需要引用的第三方库等一些信息,我们还实现了sass编译、CSS3加前缀等的自动化)
我们的项目中还用到了表单验证validate插件、图片懒加载Lazyload插件
4.为啥要离开上家单位呀(或者从前从事的不是计算机相关,为啥改行了)?
1.千万别说这行工资高之类的
2.要说,自己对这个很感兴趣,大学的时候加入的有这个社团,跟着学长学了这个东西,越学越感兴趣,于是利用大学课余时间自学了前端的知识(也可以把这个东西说成自己亲戚)
5.我们这边的话会有加班的情况,不知道你能接受不?
可以,个人愿意与公司一块成长的,而且也有了解这行会有加班,会配合公司把项目用心完成的。
6.有没有什么问题要问我?
1.别问加班和啥时候调工资之类的
2.社保、公积金交么(千万别说基数是多少)
3.问公司做的项目主要是哪方面呢,我擅长的技术****(具体技术)不知道公司需不需要
注意:如果去的是国企,国企很强调奉献,尽量往这方面靠
面试公司前最好搜索下公司是干什么的,能把他们产品说上来点就更好了(上市公司、国企尤其得这样)
第八部分:前端MVC框架
1、Angular的数据绑定采用什么机制?详述原理。
脏检查机制。
双向数据绑定是 AngularJS 的核心机制之一。当 view 中有任何数据变化时,会更新到 model ,当 model 中数据有变化时,view 也会同步更新,显然,这需要一个监控。
原理就是,Angular 在 scope 模型上设置了一个 监听队列,用来监听数据变化并更新 view 。每次绑定一个东西到 view 上时 AngularJS 就会往 $watch 队列里插入一条$watch ,用来检测它监视的 model 里是否有变化的东西。当浏览器接收到可以被 angular context 处理的事件时, $digest 循环就会触发,遍历所有的 $watch ,最后更新 dom。
第九部分:优化
1.sprites是什么,它的作用是什么?
雪碧图
减少http请求
2.前端优化常用技巧?
1.压缩css,js,图片
2.减少http请求次数,  合并css,js   合并图片(雪碧图)
3.使用CDN
4.减少dom元素数量
5.图片懒加载
6.静态资源另外用无cookie的域名
7.减少dom的访问(缓存dom)
8.巧用事件委托
9.样式表置顶、脚本置低
3.如果已经开发完一个web应用用于手机端访问,请问需要在哪方面优化页面?
按需加载
静态资源压缩
巧用图标字体
保证首屏相应速度
动画能用css3实现的尽量用css3实现
移动端事件优化(fastclick)

举报

全部评论 0

热门推荐
您需要登录后才可以回帖 立即登录 手机动态码快速登录
说说你的想法......
0
0
0
返回顶部