[关闭]
@pspgbhu 2018-11-09T07:11:05.000000Z 字数 12076 阅读 883

知识点

Basic


CSS 相关

box-sizing 的应用场景

个人感觉 border-box 的设计更合理,尤其是当你需要为一个 width: 100% 的盒子添加一个内边距的时候,border-box 的优势就显示了出来。

了解的 FLEX 弹性布局

flex: flex-grow flex-shrink flex-basis
flex: 1; === 1 1 0%
flex: auto; === 1 1 auto
flex: none; === 0 0 auto

自适应的正方形

  1. 100vw
  2. margin-bottom
  1. { width: 100%; padding-bottom: 100%}
  1. 利用伪类元素的 margin-top 顶起来

圣杯布局

一个未知宽高元素怎么上下左右垂直居中

  1. 父元素 table-cell
  2. 绝对定位 + transform
  3. flex
  4. b 元素高度 100%, vertical: middle

BFC & IFC

Box 是 CSS 布局的基本单位,直观的来说一个页面是由很多不同的 Box 组成的,不同类型的 Box 会参与不同的 Formatting Context,因此 Box 内的元素会以不同的方式来渲染

它是页面中的一块渲染区域,有一套渲染规则,决定了其子元素将如何定位,以及和其他元素的相互作用。

CSS2.1 中只有 BFC 和 IFC,CSS3 中添加了 GFC, FFC

布局规则

Retina 1px 边框问题

  1. 媒体查询
  1. @media (-webkit-min-device-pixel-ratio: 2) {
  2. div {
  3. border-width: 0.5px
  4. }
  5. }

DOM & BOM

DOM 事件的绑定的几种方式

  1. document.querySelector('#target').onclick = function() {
  2. }
  1. var el = document.querySelector('#target');
  2. el.addEventListener('click', handleFn);

同一元素绑定多次事件

事件流

DOM 事件中的target 和 currentTarget 的区别

requestAnimationFrame

是浏览器用于定时循环的一个接口,主要用途是按帧对网页进行重绘。

Page Visibility API

  1. document.addEventListener('visibilitychange', function() {
  2. if (document.hidden) {
  3. console.log('hidden')
  4. } else {
  5. console.log('shown')
  6. }
  7. })

IE 9


网络

HTTP 协议

HTTP 的特性

HTTP 报文

HTTP 报文分为三个部分:请求行,请求头,请求体
结构如下:

  1. <method> <request-url> <version>
  2. <headers>
  3. <body>

统一资源标识符 URI (Uniform Resource Identifier) 用于标识互联网上资源地址。

Restful API 风格下的 HTTP 最基本的四种请求方式

关于 POST 和 PUT 的创建资源的不同:

响应报文

HTTP 响应报文和 HTTP 请求报文相似,是由状态行,响应头,响应体组成的。

HTTP keep-alive

TCP 协议

注意:TCP 并不能保证数据一定会被对方接收到,因为这是不可能的。TCP 能够做到的是,如果有可能,就把数据递送到接收方,否则就(通过放弃重传并且中断连接这一手段)通知用户。因此准确说 TCP 也不是 100% 可靠的协议,它所能提供的是数据的可靠递送或故障的可靠通知。

三次握手 & 四次挥手

三次握手目的是连接服务器端指定窗口,建立 TCP 连接

中断 TCP 连接需要经过四次挥手,客户端或服务器均可主动发起挥手动作

TCP KeepAlive

它不同于 HTTP 的 keep-alive,TCP 连接建立之后,连接的双方并不知道彼此是否还存活着,在一方掉线后,另一方却还维持着 TCP 连接。为了避免这种情况,当超过一定的时间没有发送数据后,TCP 会自动发送一个数据为空的报文给对方,来探测对方的是否存活,如果连续发送多次后都没有回应,则认为连接丢失,没有必要保持连接。

HTTPS 协议

HTTP + SSL = HTTPS

先建立 SSL 通信,SSL 建立成功的基础上再建立 HTTP 协议。

HTTPS 采用混合加密的机制

建立通讯的时候,采用公开秘钥加密(非对称加密),通讯建立成功后采用共享秘钥加密(对称加密)。因为非对称加密成本大,因此 HTTPS 采用这种混合加密的形式。

为了保证在建立连接时,客户端使用的公钥就是服务器发送出去的公钥,而非被中间人替换过的,因此引进了证书机制来验证公钥的合法性。

HTTP 状态码的含义

网络七层模型和四层模型

网络模型

websocket

UDP 协议

XSS

跨站脚本攻击(Cross Site Scripting)

CSRF

欺骗用户在浏览器上访问一个自己曾经认证过的网站并执行一些操作。

例子
假如一家银行用以执行转账操作的URL地址如下:

  1. http://www.examplebank.com/withdraw?account=AccoutName&amount=1000&for=PayeeName

那么,一个恶意攻击者可以在另一个网站上放置如下代码:

  1. <img src="http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">

如果有账户名为Alice的用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会损失1000资金。

这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务器端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。

透过例子能够看出,攻击者并不能通过CSRF攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户浏览器,让其以用户的名义执行操作。

防御:

前端工具和前端工程化

谈谈你对前端工程化的理解

关于 webpack 的配置

webpack 的热更新

使用 webpack-dev-server 开发项目

  1. devtool: 'inline-source-map',
  2. devServer: {
  3. hot: true
  4. },

webpack loader 的原理

loader 的原理无非就是输入与输出

  1. // base loader
  2. module.exports = function(source) {
  3. return source;
  4. };

loader 之前可以链式处理,但还是要求 loader 之间彼此独立。

webpack 的工作原理流程

Babel 转换代码的原理和机制

babel 组件的作用: 如 transform-runtime 以及 stage-n

tranform-runtime

因为 babel 实现一些最新的语法往往需要一些工具函数,不使用 transform-runtime 的话,babel 会在每一个使用新语法的地方生成对应的工具函数,而 transform-runtime 就统一的提供了这些公用的工具函数,而再遇见新语法的地方,直接引用这些工具函数就可以了,这样可以起到减小文件体积的作用。

stage-n

任何人都可以向标准委员会(又称 TC39 委员会)提案,要求修改语言标准。

一种新的语法从提案到变成正式标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准。

一个提案只要能进入 Stage 2,就差不多肯定会包括在以后的正式标准里面。ECMAScript 当前的所有提案,可以在 TC39 的官方网站

webpack.optimize.UglifyJsPlugin 如何提升压缩速度

  1. module.exports = {
  2. resolve: {
  3. extensions: ['.js', '.vue', '.json'],
  4. modules: [
  5. resolve('src'),
  6. resolve('node_modules')
  7. ],
  8. alias: {
  9. 'vue$': 'vue/dist/vue.common.js',
  10. 'src': resolve('src'),
  11. 'assets': resolve('src/assets'),
  12. 'components': resolve('src/components'),
  13. // ...
  14. 'store': resolve('src/store')
  15. }
  16. },
  17. }

平时解决跨域的方式,以及JSONP的原理及cors怎么设置

1. 同源策略:

同域, 同协议, 同端口.

2. 跨域方式

JSONP:
利用了 script 标签 src 属性没有跨域的限制,地址指向API地址,并提供一个回调函数名来接受数据,浏览器会返回一个执行包含json数据的回调函数的脚本。

JSONP只能满足GET请求

图片ping
只能get,同时不能收取数据

CORS
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。


ECMAScript

原型链,对象,构造函数之间的一些联系

深拷贝的实现及其原理

  1. JSON.stringify 和 JSON.parse 实现,其缺点是对象下面不能有 function
  2. 尾递归实现深拷贝

尾调用优化

概念非常简单,就是某个函数的最后一步是对另一个函数的调用。

  1. function f(x) {
  2. return g(x);
  3. }

以下的情况不属于尾调用

  1. // 情况一
  2. function f(x){
  3. let y = g(x);
  4. return y;
  5. }
  6. // 情况二
  7. function f(x){
  8. return g(x) + 1;
  9. }

函数中调用函数,会保留所有的调用记录,形成一个调用栈。
尾调用由于是函数的最后一步,调用位置,内部变量等信息都不会再用到了,直接使用内层的调用记录取代外层的调用记录就可以了。

  1. function f() {
  2. let m = 1;
  3. let n = 2;
  4. return g(m + n);
  5. }
  6. f();
  7. // 等同于
  8. function f() {
  9. return g(3);
  10. }
  11. f();
  12. // 等同于
  13. g(3);

尾调用对递归非常重要,如果不适用尾调用,就会导致所有的调用记录都被保存,有可能造成栈溢出。

ES6的尾调用优化只在严格模式下开启,正常模式是无效的。

这是因为在正常模式下,函数内部有两个变量,可以跟踪函数的调用栈。

尾调用优化发生时,函数的调用栈会改写,因此上面两个变量就会失真。严格模式禁用这两个变量,所以尾调用模式仅在严格模式下生效。

Event Loop

Node.js Event Loop:

调用顺序 nextTick > promise > setTimeout > Immeditate

async 本质上还是可以理解为 promise。

async await, Promise, setTimeout 的执行顺序

  1. async function async1() {
  2. console.log("a");
  3. await async2(); //执行这一句后,await会让出当前线程,将后面的代码加到任务队列中,然后继续执行函数后面的同步代码
  4. console.log("b");
  5. }
  6. async function async2() {
  7. console.log( 'c');
  8. }
  9. console.log("d");
  10. setTimeout(function () {
  11. console.log("e");
  12. },0);
  13. async1();
  14. new Promise(function (resolve) {
  15. console.log("f");
  16. resolve();
  17. }).then(function () {
  18. console.log("g");
  19. });
  20. console.log('h');

macro-task 和 micro-task

https://www.zhihu.com/question/36972010

macrotask 和 microtask,这表示异步任务的两种分类。在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

  1. setTimeout(function() {
  2. console.log('timeout1');
  3. Promise.resolve().then(() => {
  4. console.log('promise1');
  5. });
  6. });
  7. setTimeout(function() {
  8. console.log('timeout2');
  9. Promise.resolve().then(() => {
  10. console.log('promise2');
  11. });
  12. });
  13. Promise.resolve().then(() => console.log('promise3'));
  14. Promise.resolve().then(() => console.log('promise4'));

手写一个 js bind

  1. var fn = target.bind(ctx);
  1. if (!Function.prototype.bind) {
  2. Function.prototype.bind = function() {
  3. if (typeof this !== 'function') {
  4. throw new Error();
  5. }
  6. var fn = this;
  7. var ctx = arguments[0];
  8. var args = [].slice.call(arguments, 1);
  9. var fNOP = function() {};
  10. var fBound = function() {
  11. // this instanceof fNOP === true时,说明返回的fBound被当做new的构造函数调用
  12. var context = this instanceof fBound
  13. ? this
  14. : ctx;
  15. return fn.apply(context, args.concat([].slice.call(arguments)));
  16. }
  17. // 维护原型关系
  18. if (this.prototype) {
  19. fNOP.prototype = this.prototype;
  20. }
  21. // 下行的代码使fBound.prototype是fNOP的实例,因此
  22. // 返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
  23. fBound.prototype = new fNOP();
  24. return fBound;
  25. }
  26. }

继承

将原型链和借用构造函数的技术组合在一起,从而发挥二者长处的一种继承模式

  1. function SuperType(name) {
  2. this.name = name;
  3. }
  4. SuperType.prototype.sayName = function() {
  5. alert(this.name);
  6. }
  7. function SubType(name, age) {
  8. // 继承属性
  9. SuperType.call(this, name);
  10. this.age = age;
  11. }
  12. // 继承方法
  13. SubType.prototype = new SuperType();
  14. SubType.prototype.constructor = SubType;

但是,这里调用了两次超类的构造函数

  1. function object(o) {
  2. function F() {};
  3. F.prototype = o;
  4. return new F();
  5. }
  6. var person = {
  7. name: 'hc';
  8. friends: ['a', 'b']
  9. }
  10. var anotherPerson = object(person);
  11. anotherPerson.name = 'zz';

object 方法将传入的 o 对象变成了新实例的原型对象。并且所有使用 o 和 object 创建出来的对象都将共享一个原型对象。

ES5 新增了 Object.create() 方法规范化了原型式继承。Object.create 接受两个参数,第一个参数是用作新对象的原型对象,第二个参数是一个为新对象定义额外属性的对象。当只传入第一个参数时,其作用于上面的 object 方法相同。

  1. function createAnother (original) {
  2. var clone = object(original); // Object.create
  3. clone.sayHi = function() {
  4. alert('hi');
  5. }
  6. return clone;
  7. }
  1. function SuperType(name) {
  2. this.name = name
  3. }
  4. SuperType.prototype.sayName = function() {
  5. alert(this.name);
  6. }
  7. function SubType(name, age) {
  8. Super.call(this, name);
  9. this.age = age;
  10. }
  11. inheritPrototype(SubType, SuperType) // 继承原型
  12. SubType.prototype.sayAge = function() {}
  13. function inheritPrototype(subType, superType) {
  14. var prototype = object(superType.prototype) // 创建对象
  15. prototype.constructor = subType; // 增强对象
  16. subType.prototype = prototype; // 指定对象
  17. }

算法

去重

  1. ES6:
  1. [...new Set(arr)]
  2. // or
  3. Array.from(new Set(arr))
    2.
  1. [arr].filter((item, index, array) => index === array.indexOf(item));

3.

  1. function quchong(arr) {
  2. var rst = [];
  3. for (var i = 0; i < arr.length; i ++) {
  4. var repeat = false;
  5. for (var j = 0; j < rst.length; i ++) {
  6. if (arr[i] === rst[j]) {
  7. repeat = true;
  8. break;
  9. }
  10. }
  11. if (!repeat) {
  12. rst.push(arr[i]);
  13. continue;
  14. }
  15. }
  16. return rst;
  17. }

冒泡排序

快速排序

有一个楼梯总共n个台阶,只能往上走,每次只能上1个、2个台阶,总共有多少种走法。


进阶

持续集成

ES6 的箭头函数及其this问题,以及拓展运算符

箭头函数的特性

拓展运算符

仅可遍历对象可用

JS 模块化 Commonjs UMD CMD 规范的了解,以及ES6模块化规范跟其他几种的区别,以及出现的意义。

  1. //c.js 依赖a.js b.js
  2. define(['a', 'b'], function(a, b) {
  3. ....
  4. });

AMD规范允许输出模块兼容CommonJS规范,这时define方法如下

  1. define(function (require, exports, module) {
  2. var reqModule = require("./a.js");
  3. requModule.mix();
  4. exports.asplode = function () {
  5. ...
  6. }
  7. });
  1. //AMD写法
  2. define(['./a','./b'], function (a, b) {
  3. //依赖一开始就写好
  4. a.mix();
  5. b.show();
  6. });
  7. //CMD写法
  8. define(function (requie, exports, module) {
  9. //依赖可以就近书写
  10. var a = require('./a');
  11. a.mix();
  12. if (...) {
  13. var b = requie('./b');
  14. b.show();
  15. }
  16. });
  1. (function (root, factory) {
  2. if (typeof define === 'function' && define.amd) {
  3. // AMD
  4. define(['jquery'], factory);
  5. } else if (typeof exports === 'object') {
  6. // Node, CommonJS-like
  7. module.exports = factory(require('jquery'));
  8. } else {
  9. // Browser globals (root is window)
  10. root.returnExports = factory(root.jQuery);
  11. }
  12. }(this, function ($) {
  13. // methods
  14. function myFunc(){};
  15. // exposed public method
  16. return myFunc;
  17. }));

应用UMD规范的js文件其实就是一个立即执行函数。函数有两个参数,第一个参数是当前运行时环境,第二个参数是模块的定义体。在执行UMD规范时,会优先判断是当前环境是否支持AMD环境,然后再检验是否支持CommonJS环境,否则认为当前环境为浏览器环境( window )

二分查找的时间复杂度怎么求

XSS是什么,攻击原理,怎么预防

线性顺序存储结构和链式存储结构有什么区别,以及优缺点。

简述CSRF token 使用的弊端

防范中间人攻击

简述闭包中的GC,画出内存图

简述MVVM实现原理,并分 React 和 Vue 画出流程图

禁止使用JS,请写一个CSS样式实现按钮根据颜色改变

typescript

场景

比如百度的一个服务不想让京东用,如果识别是京东的请求就会跳转到404或者其他,如何解决?

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注