前端面试2

1、数据双向绑定

http://jixianqianduan.com/frontend-javascript/2015/11/29/js-data-two-ways-binding.html

实现方式:
(1)发布-订阅模式(backbone.js)
http://www.html-js.com/article/Study-of-twoway-data-binding-JavaScript-talk-about-JavaScript-every-day

(2)脏值检查(angular 1.0)
最简单就是使用 setInterval() 定时轮询检测数据变动,Google 是在指定的事件发生时进行检测,如DOM事件,XHR响应事件,Timer事件

(3)数据劫持(+发布-订阅模式)(Vue.js)
Object.defineProperty() 对数据对象做get和set的监听

https://segmentfault.com/a/1190000006599500

2、https的过程?https将什么加密了?

http://blog.csdn.net/wangjun5159/article/details/51510594

  • 客户端发送请求到服务器
  • 服务器返回证书和公开密钥,公开密钥作为证书的一部分而存在
  • 客户端验证证书和公开密钥的有效性,如果有效,则生成共享密钥并使用公开密钥加密发送到服务器
  • 服务器使用私有密钥解密数据,并使用收到的共享密钥加密数据,发送到客户端
  • 客户端使用共享密钥解密数据
  • SSL加密建立

https 加密了共享密钥和数据

对性能的影响:

  • 加密解密消耗了计算机的CPU资源
  • 连接过程中客户端与服务器的通信次数比三次握手多,建立连接的时间花销较大

3、实现 remove 删除 object 的属性

// 如果键名不是字符串,则用一个变量保存键名
Object.prototype.remove = function (attr) {
    delete this[attr];
}

4、实现 map

Array.prototype.myMap = function (callback, context) {
    context = context || window;

    var newArray = [];
    
    if (typeof callback === 'function') {
        for (i = 0; i < this.length; i++) {
            var val = callback.call(context, this[i], i, this);
            newArray[i] = val;
        }
    }
    
    return newArray;
}

5、实现 compose

// 自左到右
var flow = function (...funcs) {
    var length = funcs.length;
    var index = length;
    
    while (index--) {
        if (typeopf funcs[index] !== 'function') {
            throw new TypeError('Expected a function');
        }
    }
    return function (...args) {
        var index = 0;
        var result = length ? funcs[index].apply(this, args) : args[0];
        
        while (++index < length) {
            result = func[index].call(this, result);
        }
        
        return result;
    }
}

// 自右到左
var flowRight = function (...funcs) {
    return flow(funcs.reverse());
}

6、浏览器缓存

http://web.jobbole.com/82997/


7、移动端点击事件的300ms延时

http://blog.csdn.net/qq_34986769/article/details/62046696

  • 禁用缩放
  • 更改视口宽度
  • 使用指针事件(IE10+):touch-action(非标准css)
  • FastClick

点击穿透(使用touchstart代替click时会出现的情况):

假如页面上有两个元素A和B。B元素在A元素之上。我们在B元素的touchstart事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了click事件。

这是因为在移动端浏览器,事件执行的顺序是touchstart > touchend > click。而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转。

8、HTTP状态码

http://www.runoob.com/http/http-status-codes.html

  • 1** :信息,服务器收到请求,需要请求者继续执行操作
  • 2** :成功,操作被成功接收并处理
  • 3** :重定向,需要进一步的操作以完成请求
  • 4** :客户端错误,请求包含语法错误或无法完成请求
  • 5** :服务器错误,服务器在处理请求的过程中发生了错误

200:请求成功

301:永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替

302:临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI

304:未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源

307:临时重定向。与302类似。使用GET请求重定向

400:客户端请求的语法错误,服务器无法理解

401:请求要求用户的身份认证

403:服务器理解请求客户端的请求,但是拒绝执行此请求

404:服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面

410:客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置

500:服务器内部错误,无法完成请求

501:服务器不支持请求的功能,无法完成请求

9、原型链

对象的原型指向原型对象,原型对象的原型又指向其父类的原型...

obj.__proto__ = Object.prototype

10、babel配置, webpack配置,gulp配置

http://www.ruanyifeng.com/blog/2016/01/babel.html

webpack配置:

var path = require('path')
var webpack = require('webpack')

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name: '[name].[ext]?[hash]'
        }
      }
    ]
  },
  devtool: '#eval-source-map'   // 包含dataURL
}

if (process.env.NODE_ENV === 'production') {
  module.exports.devtool = '#source-map'   // 只在末尾加上sourcemap文件的地址,需要请求
  module.exports.plugins = [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: true,
      compress: {
        warnings: false
      }
    })
  ]
}
"scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
}
// 导入模块
var gulp = require('gulp');
var cssmin = require('gulp-cssmin');
var uglify = require('gulp-uglify');
var htmlmin = require('gulp-htmlmin');
var rename = require('gulp-rename');    // 改名

// 配置任务
gulp.task('uglify:css', function() {
    gulp.src('css/*.css')
        .pipe(cssmin())        // 压缩
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css'))    // 输出
});
gulp.task('uglify:js', function() {
    gulp.src('js/*.js')
        .pipe(uglify())                    // 压缩
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/js'))    // 输出
});
gulp.task('uglify:html', function() {
  gulp.src('*.html')
      .pipe(htmlmin({                    // 压缩
          collapseWhitespace: true,
          removeComments: true
      }))
      .pipe(gulp.dest('build'))        // 输出
});

gulp.watch('*.*', ['uglify:css', 'uglify:js', 'uglify:html']);

gulp.task('default', ['uglify:css', 'uglify:js', 'uglify:html']);

11、同源策略,跨域方式,手动实现jsonp

同源策略
对于绝对的URIs,源就是{协议,主机,端口}定义的。只有这些值完全一样才认为两个资源是同源的。

同源策略可以保护用户信息,防止用户在A网站的信息被B网站获取到

cookie只有同源的网站可以访问到,可设置document.domain设置同源获取cookie,localstorage和IndexDB不可以通过这种方式获取
cookie 可设置所属域名为一级域名,其二级域名,三级域名等就可以直接获取

iframe和window.open可以通过片段识别符(即url的#后面的内容)修改和获取

window.postMessage可以跨文档通信

http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

跨域方法:

  • jsonp

  • document.domain设置同源

    使用条件:

    • 有其他页面 window 对象的引用。
    • 二级域名相同。
    • 协议相同。
    • 端口相同。
  • window.name

    https://segmentfault.com/a/1190000003642057

  • window.postMessage(HTML5)

  • websocket(里面发出的请求头包含了Origin,指定了请求源)

  • CORS(允许任何类型的转换)

    IE10+

    简单请求和非简单请求,跟正常的ajax调用差不多,关键是服务器实现CORS接口

    http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

手动实现jsonp

function addScriptTag (src) {
    var scriptTag = document.createElement('script');
    scriptTag.setAttribute('type', 'text/javascript');
    scriptTag.src = src;
    document.body.appendChild(scriptTag);
}

window.onload = function () {
    addScriptTag('http://example.com/ip?callback=foo');
}

function foo(data) {
    console.log('Your public Ip address is: ' + data.ip);
}

服务器返回的信息

foo({
    'ip': '8.8.8.8'
});

12、手动实现ajax

http://www.jb51.net/article/104873.htm

function ajax ({url, type = 'GET', data = {}, success, error}) {
    type = type.toUpperCase();
    data = formatData(data);
    var xhr = null;
    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    } else {
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
            var status = xhr.status;
            if (status >= 200 && status < 300) {
                var response = '';
                var type = xhr.getResponseHeader('Content-type');
                if (type.indexOf('xml') !== -1 && xhr.responseXML) {
                    response = xhr.responseXML;
                } else if (type == 'application/json') {
                    response = JSON.parse(xhr.responseText);
                } else {
                    response = xhr.responseText;
                }
                success && success(response);
            } else {
                error && error(response);
            }
        }
    }
    
    if (type === 'GET') {
        xhr.open(type, url + '?' + data, true);
        xhr.send();
    } else {
        xhr.open(type, url, true);
        xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
        xhr.send(data);
    }
    
    function formatData (data) {
        var arr = [];
        for (var name in data) {
            arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
        }
        // 加上一个随机数,防止缓存
        arr.push('v=' + random());
        
        return arr.join('&');
    }
    
    function random () {
        return Math.floor(Math.random() * 10000 + 500);
    }
}

13、渐进增强和优雅降级

渐进增强:一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验

优雅降级:一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用css3的特性构建了一个应用,然后逐步针对各大浏览器进行hack使其能在低版本浏览器上正常浏览。

http://www.jianshu.com/p/d313f1108862

14、HTTP长连接,keep-alive

Connection: keep-alive
keep-alive: 20ms

保持TCP的长连接不断开,20ms 后断开连接,TCP的keep-alive是检查当前TCP连接是否还活着,两者概念不一样,使用Content-Length(静态)或Transfer-Encoding(动态,chunk模式)判断消息内容的大小

http://www.cnblogs.com/skynet/archive/2010/12/11/1903347.html

15、从输入url到看到页面发生了什么

http://www.cnblogs.com/xianyulaodi/p/6547807.html

  • 输入地址
  • 浏览器查找域名的IP地址
  • 浏览器向web服务器发送一个HTTP请求
  • 服务器的永久重定向响应
  • 浏览器跟踪重定向地址
  • 服务器处理请求
  • 服务器返回一个HTTP响应
  • 浏览器显示HTML
  • 浏览器发送请求获取嵌在HTML中的资源(如图片,音频,视频,JS,CSS等)

16、前端性能优化

https://www.cnblogs.com/liulilin/p/7245125.html

17、深拷贝

http://blog.csdn.net/sysuzhyupeng/article/details/70340598

18、前端安全

http://blog.csdn.net/fengyinchao/article/details/52303118

http://www.cnblogs.com/vajoy/p/4176908.html

19、类数组

具有length属性,其他属性为非负整数,不具备数组所具有的方法

类数组:arguments,以及DOM操作返回的结果

20、for...in..

  • 循环计数器是字符串,不是数字
  • 会遍历原型上的方法和属性,不适合遍历数组

21、forEach

forEach 无法使用return终止

22、HTML5 新特性

http://blog.csdn.net/gane_cheng/article/details/52819118

23、IE盒子和W3C盒子

IE5.5以下:width = content + padding + border

W3C: width = content

避免IE盒子的方法:头部加上

24、实现斐波那契序列

// 递归,时间复杂度O(2^n),空间复杂度O(n)
function fib (n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    
    return fib(n - 1) + fib(n - 2);
}

// 非递归,时间复杂度O(n),空间复杂度O(n)
function fib (n) {
    var ret = [1, 1];
    if (n == 1 || n == 2) {
        return 1;
    }
    for (var i = 2; i < n; i++) {
        ret[i] = ret[i - 1] + ret[i - 2];
    }
    
    return ret[n - 1];
}

// 非递归,时间复杂度O(n),空间复杂度O(1)
function fib (n) {
    var res, a, b;
    a = b = 1;
    if (n == 1 || n == 2) {
        return 1;
    }
    for (var i = 3; i <= n; i++) {
        res = a + b;
        a = b;
        b = res;
    }
    
    return res;
}

25、盒子模型的折叠问题

http://blog.csdn.net/zerlinda_c/article/details/50054639

margin塌陷:http://www.cnblogs.com/hugejinfan/p/5901320.html

水平方向不会坍塌

26、块级元素和行级元素

http://www.cnblogs.com/asqq/archive/2012/10/04/3194956.html

27、Less特性

http://blog.csdn.net/u014695532/article/details/50957356

28、git 命令

http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html

30、面经回答

http://blog.csdn.net/bossmango/article/details/77369805

https://segmentfault.com/a/1190000008644536

31、行内元素设置行高

display或者float

32、requireJS 解决循环依赖

http://www.cnblogs.com/terrylin/p/3347073.html

33、实现垂直居中

http://blog.csdn.net/wolinxuebin/article/details/7615098

  • 行内文字:line-height
  • display:table-cell;vertical-align:middle;
  • position和margin(负数)
  • position和stretch
  • 设置相同padding-top和padding-bottom
  • display:flex;aling-items:center;

34、伪类和伪元素

http://www.cnblogs.com/ihardcoder/p/5294927.html

35、AMD 和 CMD的区别

http://blog.csdn.net/jackwen110200/article/details/52105493

36、event loop

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

37、DOCTYPE

声明不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令

38、强缓存和协商缓存

http://caibaojian.com/browser-cache.html

39、https与http

https比http长3倍的时间

优化:

  • CDN加速,拉进节点
  • 服务器硬件加速,释放CPU
  • 远程解密,使用CPU负载较低的服务器

http://blog.csdn.net/hherima/article/details/52469787

你可能感兴趣的:(前端面试2)