小钢经

- HTML和css
  1. HTML5的新特性
    a.标签语义化。如:nav、header、footer等标签。
    b.强大的画布。canvas和SVG
    c. 本地存储。如sessionStorage和localStorage

  2. 未知宽高的盒子居中
    a. 弹性盒模型flex布局
    b. 伪类和空盒子
    c.将块标签转换为表格属性display:table-cell
    d. 利用相对定位和transform

  3. flex布局
    flex: 1代表什么:
    ①第一个参数表示: flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
    ②第二个参数表示: flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
    ③第三个参数表示: flex-basis给上面两个属性分配多余空间之前, 计算项目是否有多余空间, 默认值为 auto, 即项目本身的大小。

  4. BFC
    a.BFC 即 Block Formatting Contexts (块级格式化上下文)。具有BFC特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器所没有的一些特性。
    b.触发BFC的条件
    ① body 根元素
    ② 浮动元素:float 除 none 以外的值
    ③ 绝对定位元素:position (absolute、fixed)
    ④ display 为 inline-block、table-cells、flex
    ⑤ overflow 除了 visible 以外的值 (hidden、auto、scroll)
    c.BFC特性及应用
    ① 同一个 BFC 下外边距会发生折叠
    ② BFC 可以包含浮动的元素(清除浮动)
    ③ BFC 可以阻止元素被浮动元素覆盖。(两列布局)

  5. 回流Reflow和重绘Repaint
    浏览器绘制原理:浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了Render Tree
    a. 当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。(查询宽高也会触发)。
    b. 当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。
    c. 回流一定会重绘,重绘不一定会回流。
    d. 如何避免
    CSS
    ① 尽可能在DOM树的最末端改变class。
    ② 避免设置多层内联样式。
    ③ 将动画效果应用到position属性为absolute或fixed的元素上。

    JavaScript
    ① 避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。
    ② 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。
    ③ 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。
    避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
    ④ 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。

  6. 硬件加速(css 3D 加速)
    transform:translateZ(0)的作用:强制硬件加速的一项技术。
    浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能.
    现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。
    CSS animations, transforms 以及 transitions 不会自动开启GPU加速,而是由浏览器的缓慢的软件渲染引擎来执行。那我们怎样才可以切换到GPU模式呢,很多浏览器提供了某些触发的CSS规则。
    现在,像Chrome, FireFox, Safari, IE9+和最新版本的Opera都支持硬件加速,当它们检测到页面中某个DOM元素应用了某些CSS规则时就会开启,最显著的特征的元素的3D变换。

  7. 自动端自适应方案

  8. rem的原理

- javascript基础
  1. 闭包
    我的闭包的总结
    a. 闭包就是一个保护罩,一切阻止变量回收机制的形式,都可以称为闭包。

  2. arguments转化为数组
    a.借用数组方法Array.prototype.slice.apply(arguments)
    b.循环赋值

  3. 继承
    a. class中用extends的关键字,在constructor中调用super方法。
    b.原型的继承。子类的prototype指向父类的实例。

    function SuperClass(){
    	this.name = "super";
    }
    SuperClass.prototype.getName = function(){
    	return this.name;
    }
    function SubClass(){
    	this.subName = "sub";
    }
    SubClass.prototype = new SuperClass();
    

    c. 对象冒充,不能继承原型上的方法

    function SuperClass(){
    	this.name = "super";
    }
    function SubClass(){
    	this.subName = "sub";
    	SuperClass.call(this,null);
    }
    

    d.混合继承

    function SuperClass(){
    	this.name = "super";
    }
    SuperClass.prototype.getName = function(){
    	return this.name;
    }
    function SubClass(){
    	this.subName = "sub";
    	SuperClass.call(this,null);
    }
    SubClass.prototype = new SuperClass();
    

    e.原型式继承 - 原型继承的封装

    function inheritObject(o){
    	//过渡对象
    	function F(){};
    	//过渡对象的原型继承父对象
    	F.prototype = o;
    	//返回过渡对象的实例
    	return new F();
    }
    //父对象
    var book = {
    	name:"你还好吗?",
    	like:["css","yys"]
    }
    //子对象
    var newBook = inheritObject(book);
    
  4. Promise
    a. Promise.all
    多个请求同时返回。失败的时候是第一个失败的结果。
    b. Promise.race
    任意一个返回成功就算执行完成。用于判断异步操作是否超时。
    c. async/await
    异步操作的同步写法,并发时,需要用promise。
    d.手写一个Promise.all。利用一个计数器实现。

    function promiseAll(promises) {
    	return new Promise((resolve,  reject) => {
    		// 校验是数组
    		if (!Array.isArray(promises)) {
    			return Error('不是数组');
    		}
    		let allNum = promises.length;
    		let compNum = 0;
    		let resArr = [];
    		for (let i = 0; i < allNum; i++) {
    			promises[i].then(res => {
    				compNum++;
    				resArr[i] = res;
    				if (compNum === allNum) {
    					resolve(resArr);
    				}
    			}).catch(e => {
    				reject(e);
    			});
    		}
    	});
    };
    
  5. 事件循环
    a. 宏任务队列macrotask
    如:setTimeout、MessageChannel、postMessage、setImmediate。
    setTimeout的回调函数放到宏任务队列里,等到执行栈清空以后执行。
    b. 微任务队列microtask
    如:promise
    promise.then里的回调函数会放到相应宏任务的微任务队列里,等宏任务里面的同步代码执行完再执行
    async函数表示函数里面可能会有异步方法,await后面跟一个表达式
    async方法执行时,遇到await会立即执行表达式,然后把表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行
    c. 基础题1

    creatMicroTask(function() {
      console.log('mic1');
    })();
    
    creatMacroTask(function() {
      console.log('mac1');
    })();
    
    creatMicroTask(function() {
      console.log('mic2');
    })();
    
    creatMacroTask(function() {
      console.log('mac2');
    })();
    
    creatMicroTask(function() {
      console.log('mic3');
    })();
    
    creatMacroTask(function() {
      console.log('mac3');
    })();
    console.log('task');
    

    d.基础题2

    console.log('begin');
    setTimeout(() => {
      console.log('setTimeout 1');
      Promise.resolve()
        .then(() => {
          console.log('promise 1');
          setTimeout(() => {
            console.log('set2 between promise1&2');
          });
        })
        .then(() => {
          console.log('promise 2');
        });
    }, 0);
    console.log('end');
    

    结果是begin、end、setTimeout 1、promise 1、promise 2、set2 between promise1&2
    e.基础题3

	async function async1() {
	  console.log('async1 start');
	  await async2();
	  console.log('async1 end');
	}
	async function async2() {
	  new Promise(function (resolve) {
	    console.log('promise1');
	    resolve();
	  }).then(function () {
	    console.log('promise2');
	  });
	}
	
	console.log('script start');
	
	setTimeout(function () {
	  console.log('setTimeout');
	}, 0)
	
	async1();
	
	new Promise(function (resolve) {
	  console.log('promise3');
	  resolve();
	}).then(function () {
	  console.log('promise4');
	});
	
	console.log('script end');
  1. 原型链
    每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。这就是所谓的原型链的基本概念。——摘自《javascript高级程序设计》
    在这里插入图片描述

  2. require 和 import
    a.CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
    b.CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
    c.CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段
    d.写法不一样。

  3. ES6和ES7
    a. let const 声明
    b.箭头函数
    c.解构赋值
    d.for of循环
    e.import和export
    f.class
    g.Set和Map
    h.async、await、promise
    i. Symbol

  4. 变量提升

var定义的变量, 其 声明阶段和初始化阶段 会被提升至所在作用域最前端执行
let定义的变量, 其 声明阶段 会被提升至所在作用域的最前端进行
函数会在其被定义的作用域最顶部完成声明,初始化和赋值三个阶段

var a = 10;
function say() { 
	console.log(a);
	var a = 20;
	// let a = 20;
	console.log(a);
};
say();

上面运行结果是undefined和20

var a = 10;
function say() { 
	console.log(a);
	let a = 20;
	console.log(a);
};
say();

上面的结果是抛出错误。

var a = 10;
{ 
  console.log(a);
  var a = 20;
  // let a = 20;
  console.log(a);
};

上面运行结果是10和20

var a = 10;
{ 
  console.log(a);
  let a = 20;
  console.log(a);
};

结果:Uncaught ReferenceError: a is not defined

  1. this指向考题
const a = 1;
const b = () => {
  console.log(this.a);
}
const obj = {
  a: 10,
  b: function() {
    console.log(this.a);
  }
}
const c = obj.b;

b(); // undefined
obj.b(); // 10
c(); // undefined
  1. 进程和线程的区别
    进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。

3. 网络

3.1 http1.0、http1.1和http2.0
  1. http简介
    a. HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写。
    b. HTTP是一个基于TCP/IP通信协议来传递数据。
    c. HTTP是一个属于应用层的面向对象的协议。

  2. OSI七层模型
    OSI中的层 功能 TCP/IP协议族
    应用层 文件传输,电子邮件,文件服务,虚拟终端 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet
    表示层 数据格式化,代码转换,数据加密 没有协议
    会话层 解除或建立与别的接点的联系 没有协议
    传输层 提供端对端的接口 TCP,UDP
    网络层 为数据包选择路由 IP,ICMP,RIP,OSPF,BGP,IGMP
    数据链路层 传输有地址的帧以及错误检测功能 SLIP,CSLIP,PPP,ARP,RARP,MTU
    物理层 以二进制数据形式在物理媒体上传输数据 ISO2110,IEEE802,IEEE802.2

  3. 特点
    a. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。使得HTTP服务器的程序规模小,因而通信速度很快。
    b. 灵活:HTTP允许传输任意类型的数据对象。
    c.无连接:无连接的含义是限制每次连接只处理一个请求。
    d.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。

  4. http报文
    a. 第一部分:请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本.
    b. 第二部分:请求头部,紧接着请求行之后的部分,用来说明服务器要使用的附加信息
    c. 第三部分:空行,请求头部后面的空行是必须的
    d. 第四部分:请求数据也叫主体,可以添加任意的其他数据

  5. 状态码

100 continue
200 OK
301 永久重定向,
302 临时重定向
304 协商缓存未修改
400 Bad Request 坏请求
401 Unauthorized 未授权
403 Forbidden 禁止
404 Not Found 未找到
500 Internal Server Error 内部服务器错误)
502 网关故障 (nginx)
503 Server Unavailable 未提供此服务
504 Gateway Timeout(网关超时)

  1. HTTP1.0 HTTP 1.1区别
    a. 长连接
    (1)HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接,而HTTP1.1默认支持长连接。

    (2)HTTP是基于TCP/IP协议的,创建一个TCP连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用个长连接来发多个请求。

    b.节约带宽
    HTTP 1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接受到100,才开始把请求body发送到服务器。

    这样当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽。

    HTTP还支持传送内容的一部分。这样当客户端已经有一部分的资源后,只需要跟服务器请求另外的部分资源即可。这是支持文件断点续传的基础。

    c.HOST域

    现在可以web server例如tomat,设置虚拟站点是非常常见的,也即是说,web server上的多个虚拟站点可以共享同一个ip和端口。HTTP1.0是没有host域的,HTTP1.1才支持这个参数。

  2. HTTP1.1 HTTP 2.0主要区别
    a.多路复用
    HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。

    HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。

    b.数据压缩
    HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。

    c.服务器推送
    对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源。

    服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然是快很多。

3.2 https及加密原理
  1. 非对称加密
    如DES、RSA 和jwt非对称加密
    公钥:匣子的锁。
    私钥:开锁的钥匙。在这里插入图片描述

  2. CA数字证书与数字签名
    防止中间人劫持

3.3 TCP和UDP
  1. 面向无连接
    首先 UDP 是不需要和 TCP一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。
  2. 有单播,多播,广播的功能
    UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
  3. UDP是面向报文的
    发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文
  4. 不可靠性
    首先不可靠性体现在无连接上,通信都不需要建立连接,想发就发,这样的情况肯定不可靠。
3.4 性能优化
  1. 输入一个url会有以下流程:
    a.浏览器单独开启一个http请求线程。
    b.dns域名查询,建立http连接。
    c.返回html页面,浏览器渲染dom树,css规则树渲染页面。

  2. 优化dns域名查询时间
    浏览器DNS查找顺序一般是这样的:浏览器缓存→系统缓存→路由器缓存→ISP DNS 缓存→递归搜索。

    可以利用浏览器对DNS预取:

    <link rel="dns-prefetch" href="//fonts.googleapis.com">
    

    设置dns-prefetch

  3. 优化http请求次数
    每一个http请求都是需要时间的,尽量减少http请求次数。
    a.合并小图标,也就是平常说的雪碧图。
    b.压缩和混淆js和css文件,使用一些打包和压缩工具。
    c.将部分css和js写到html页面里面。淘宝网将部分的css直接写在html里面。

  4. 利用http缓存
    a.Cache-Control 控制缓存

    // 后台设置类似于下面:
    header("Content-type:text/html;charset=utf-8");
    //用Cache-Control告诉浏览器有效期 5秒
    header("Cache-Control:max-age=15");
    

    b.使用响应头Expires控制缓存

    //设置10秒的有效期,时间格式是GMT
    //时间是当前服务器时间 + 10秒
    $expires = gmdate('D, d M Y H:i:s', time() + 10) . ' GMT';
    header("Expires:$expires");
    

    expires的弊端是有效期是以服务器时间来设置,如果客户端的时间和服务端时间有一定的时间差,缓存的控制就有问题了。
    Cache-Control(支持) 和 expires 同时设置有效期,以 Cache-Control设置的有效期为准。

    设置expires和cache-control都是属于强缓存,对于已经缓存,且未过期的图片,不会再发起http请求。

    c. 通过HTTP 304是协商缓存,
    在这里插入图片描述
    图上写的有问题,如果有eTag用eTag判断,没有则用lastModify判断。
    补充:
    ① 强缓存: 200 from disk cache和from memory cache。
    ② 协商缓存: 304协商缓存,Last-Modify/If-Modified-Since 和 ETag/If-None-Match判断。
    a.只用Last-Modify存在两个问题:Last-Modify只能精确到秒,同一个文件多次生成也会修改Last-Modify。
    ③ F5刷新 强缓存无效,协商缓存有效。Ctrl+F5刷新缓存均失效。
    d.其他缓存
    其他缓存为服务器端缓存,数据库缓存。如代理服务器缓存,redis缓存等。缓存规则是能用缓存,则先用缓存。

    e. 静态资源放到其他域名下
    将静态资源放到其他服务器有两点原因:

    (1) 减轻服务器的压力,显然两台服务器更快。

    (2) 因为跨域问题,静态请求不会携带cookie,提高了传输效率。

  5. http请求长连接
    http1.0默认是短连接,每发一次请求,建立一次连接。在请求很多的情况下,增加了请求时长。

    使用http1.1 ,http1.1是默认长连接,HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果。
    或者在http1.0设置求头

  6. 优先使用get请求

  7. 使用gzip压缩

  8. 使用jsonp

  9. css外链放在head里面,js外链放在body后面

  10. 懒加载

3.5 web安全
  1. xss攻击
    xss过滤
  2. csrf攻击
    httponliy和token
  3. css攻击
    谨慎使用第三方npm库
  4. npm攻击
    谨慎使用第三方npm库
  5. 爬虫攻击
    签名,ip,加密,验证码

4. vue

4.1 双向绑定
  1. defineProperty极简单的双向绑定
<input oninput="input(this)" id="input1" />
<input oninput="input(this)" id="input2" />
<script type="text/javascript">
	var dom = { msg: '' };
  	var _val;
	Object.defineProperty(dom, 'msg', {
		get() {
			return _val;
		},
    	set(val) {
      		input2.value = val;
      		input1.value = val;
      		_val = val;
    	}
	});
  	function input(obj) {
    	dom.msg = obj.value;
  	}
  	dom.msg = 4;
</script>
  1. Proxy
var target = { name: '张三' };
var handler = {
  get(target, key) {
    console.log(`${key} 被读取`);
    return target[key];
  },
  set(target, key, value) {
    console.log(`${key} 被设置为 ${value}`);
    target[key] = value;
  }
};
var proxy = new Proxy(target, handler);
proxy.name;
proxy.name = '李四';
4.2 vue原理
  1. 数据驱动
  2. 组件系统
  3. 节流
// 节流throttle代码(定时器):
var throttle = function(func, delay) {            
    var timer = null;            
    return function() {                
        var context = this;               
        var args = arguments;                
        if (!timer) {                    
            timer = setTimeout(function() {                        
                func.apply(context, args);                        
                timer = null;                    
            }, delay);                
        }            
    }        
}        
function handle() {            
    console.log(Math.random());        
}        
window.addEventListener('scroll', throttle(handle, 1000));
  1. 防抖
function debounce(fn, wait) {    
    var timeout = null;    
    return function() {        
        if(timeout !== null)   clearTimeout(timeout);        
        timeout = setTimeout(fn, wait);    
    }
}
// 处理函数
function handle() {    
    console.log(Math.random()); 
}
// 滚动事件
window.addEventListener('scroll', debounce(handle, 1000));
  1. 比较 vue 和 react , React 代码与 Vue 代码互转和复用。
    复用:
    a. Mixin
    b. slot
    c. props
    Vue和react
    a. Vue双向绑定, React单向
    b. Vue组件用template, React用jsx(Vue也可以用jsx)
    c. Vue状态管理用Vuex,React用Redux
    d. 都有路由
    e. 都有虚拟dom
4.3 diff算法
  1. react 的 diff 算法。

    diff策略
    React用 三大策略 将O(n^3)复杂度 转化为 O(n)复杂度

    策略一(tree diff):
    Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计。

    策略二(component diff):
    拥有相同类的两个组件 生成相似的树形结构,shouldComponentUpdate判断。
    拥有不同类的两个组件 生成不同的树形结构。

    策略三(element diff):
    对于同一层级的一组子节点,通过唯一id区分。key的作用是节点id区分。

4.4 虚拟dom
  1. 虚拟 dom 的优缺点
    优点:
    a.保证性能下限
    b.跨平台

    缺点:
    无法进行极致优化: 虽然虚拟 DOM + 合理的优化,足以 应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。
    首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。

4.5 react
  1. react生命周期
    a. componentWillMount 在渲染前调用,在客户端也在服务端。
    b. componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。
    c.componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。
    d.shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
    可以在你确认不需要更新组件时使用。
    e.componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
    f.componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
    g.componentWillUnmount在组件从 DOM 中移除之前立刻被调用

  2. redux 的优缺点

  3. react 中 render props 适用场景(类组件和函数组件的区别)

  4. react setState 什么时候同步什么时候异步

  5. render props 和 HOC 优缺点

5. webpack
  1. webpack插件
    a.一个简单的插件的构成
    b. webpack构建流程
    c. Tapable是如何把各个插件串联到一起的
    d. compiler以及compilation对象的使用以及它们对应的事件钩子。
  2. webpack打包机制
6.算法
  1. 递归
  2. 链表排序(冒泡、 选择、插入、快排、归并、希尔、堆排序)
// 冒泡排序法
function bubbleSort(list) {
	let len = list.length;
	for (let i = 0; i < len; i++) {
		for (let j = 0; j < len - 1 - i; j++) {
			if (list[j] > list[j+1]) {
				let temp = list[j];
				list[j] = list[j+1];
				list[j+1] = temp;
			}
		}
	}
	return list;
};
// 快速排序
function quickSort(arr) {
  if (arr.length <= 1) { return arr; }
  var pivotIndex = Math.floor(arr.length / 2);
  var pivot = arr.splice(pivotIndex, 1)[0];
  var left = [];
  var right = [];
  for (var i = 0; i < arr.length; i++){
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat([pivot], quickSort(right));
};
  1. 版本号排序

  2. 时间复杂度
    在这里插入图片描述

  3. 函数柯里化。
    柯里化封装:

// 支持多参数传递
function currying(fn, args) {
    var _this = this
    var len = fn.length;
    var args = args || [];

    return function() {
        var _args = Array.prototype.slice.call(arguments);
        Array.prototype.push.apply(args, _args);
        // 如果参数个数小于最初的fn.length,则递归调用,继续收集参数
        if (_args.length < len) {
            return currying.call(_this, fn, _args);
        }
        // 参数收集完毕,则执行fn
        return fn.apply(this, _args);
    }
}
// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
function add() {
   // 第一次执行时,定义一个数组专门用来存储所有的参数
   var _args = Array.prototype.slice.call(arguments);
    // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
    var _adder = function() {
        _args.push(...arguments);
        return _adder;
    };
    // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    _adder.toString = function () {
        return _args.reduce(function (a, b) {
            return a + b;
        });
    }
    return _adder;
}

add(1)(2)(3)                // 6
add(1, 2, 3)(4)             // 10
add(1)(2)(3)(4)(5)          // 15
add(2, 6)(1)                // 9
  1. 动态规划求解最多有几种方案求解硬币找零问题。
  2. 给了一个数组求两数相加和等于 m 总共有多少种可能性。
  3. 请实现 DOM2JSON 一个函数,可以把一个 DOM 节点输出 JSON 的格式,例如下 面的例子。
    <div>
    	<span>
    		<a></a>
    	</span>
    	<span> 
    		<a></a><a></a>
    	</span>
    </div> 
    
    {
      tag: 'DIV',
      children: [
        {
          tag: 'SPAN',
          children: [{ tag: 'A', children: [] }]
        }
      ]
    } 
    
    解题:
    function dom2Json(domtree) {
      let obj = {}
      obj.name = domtree.tagName
      obj.children = []
      domtree.childNodes.forEach(
        child => obj.children.push(dom2Json(child))
        )
      return obj
    }
    
7. 项目优化
  1. 缓存http,CDN
  2. js和资源拆小
  3. vue预渲染
  4. 骨架屏
  5. keepAlive
  6. 静态服务器
  7. html拆分

详细移步下面文章【白屏问题全鉴】

8.JAVA基础
  1. 面向对象的三大特性
    封装、继承、多态
  2. 重载和重写区别
    重载是函数名相同,参数和返回值不同。
    重写是对方法覆盖。
  3. 反射机制
    在运行状态中,对任意一个类,都能够知道这个类的所有属性和方法,对于任何一个对象,都能够调用它的任意一个属性和方法。
  4. 包管理: maven
  5. spring
    ①容器提供单例模式支持。② 提供了AOP技术,可以拦截。
    依赖注入控制反转
    当某个角色需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者。
9. PHP基础
  1. 包管理: Composer
  2. 框架:thinkphp
  3. 优点:快速、简单
  4. 缺点:一般用于简单的单应用。
10. python基础
  1. 包管理: pip
  2. 爬虫
  3. web构建: Flask
11. nodejs基础
  1. 包管理:npm
  2. 应用于聚合层
  3. 优点:异步操作,性能高
  4. 缺点:单线程,不适用于CPU密集型,对和关系型数据支撑不好。
12. 安全
  1. xss
    ① 存储型 ② 反射型
    攻击原理:利用html插入、a标签点击、后端渲染等执行恶意代码。
    预防:v-html不用,链接配置白名单,前端渲染。

  2. csrf
    跨站请求伪造
    ① get请求型 ②表单提交型 ③ a链接型
    攻击原理:利用已经登录和访问过网站,诱导用户发送携带cookie的请求。
    预防:token验证、签名验证、关键表单提交再验证。

  3. 第三方依赖安全
    80%的第三方依赖都有安全问题。
    预防:代码依赖扫描

  4. 恶意爬虫
    预防:IP限制、签名验证、token验证、交互验证码、限制访问次数、无头浏览器限制。

  5. 中间人攻击
    利用代理,劫持请求。
    预防:使用https、要求用户安装安全工具。

12. 微前端
  1. 优点:解决iframe的性能、通信、友好等问题。
  2. 框架:qiankun
  3. 沙箱隔离
    ① window对象劫持
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三和小钢炮

谢谢客官~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值