自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

SevenLee的个人博客

www.7evenlee.xyz

  • 博客(298)
  • 收藏
  • 关注

原创 前端性能工程化:优化策略

一、优化网络传输1.开启HTTP2.02.使用CDN部署静态资源3.使用DNS预解析4.提前建立网络连接5.域名收敛,把页面的静态资源部署在尽可能少的域名下,节省DNS解析、TCP建连等网络成本6.使用brotli压缩,google在15年发布的Brotli压缩算法,比gzip具有更高的压缩比和更快的压缩性能。7.优化https,https多次握手和TLS相关算法会造成额外的开销导致没有优化过的https性能相比http差距较大。、优化方法如下:1.Session Resume,把昂贵的计算

2021-04-08 17:31:50 336

原创 字母异位词分组(leetcode49)

/** * @param {string[]} strs * @return {string[][]} */var groupAnagrams = function(strs) { let map = new Map() let result = [] function sort(str) { return str.split("").sort().join(""); } for (let i = 0; i < strs.lengt.

2021-03-12 14:50:40 175

原创 快乐数(leetcode202)

/** * @param {number} n * @return {boolean} */var isHappy = function(n) { let set = new Set(), sum n += '' while (sum !== 1) { sum = 0 for (let i = 0; i < n.length; i++) { sum += n[i]*n[i] } if (s.

2021-03-12 14:45:51 191

原创 合并区间

/* * function Interval(a, b){ * this.start = a || 0; * this.end = b || 0; * } *//** * * @param intervals Interval类一维数组 * @return Interval类一维数组 */function merge( intervals ) { if (intervals.length<2) return intervals; intervals.

2021-03-08 21:09:40 99

原创 矩阵的最小路径和(机器人dp升级版)

/** * * @param matrix int整型二维数组 the matrix * @return int整型 */function minPathSum( matrix ) { // write code here let m = matrix.length; let n = matrix[0].length; let dp = [] for(let i=0;i<m;i++){ dp[i] = new Array(n) .

2021-03-07 22:34:27 127

原创 二维矩阵查找

/** * * @param matrix int整型二维数组 * @param target int整型 * @return bool布尔型 */function searchMatrix( matrix , target ) { // write code here let m = matrix.length; let n = matrix[0].length; let i = 0 let j = n-1 while(i&l.

2021-03-07 21:55:02 102

原创 广度/深度优先遍历DOM树的结点

function bfs(){ let result = [] let root = document.querySelector('body') let stack = [root] let temp = [] let len while(len=stack.length){ for(let i=0;i<len;i++){ let node = stack.shift() temp.push(node.nodeName) if(node.chi.

2021-03-07 21:00:50 451

原创 找出数组中每个数右边第一个比它大的元素的索引(O(N)解法)

//复杂度为O(n^2)的解法,遍历数组中的每一个后面所有元素,找到第一个大于它的的元素的索引保存在数组中返回即可 //O(N)解法 借助单调栈 function findLargestIndex(arr){ let result = [] let stack = [0] let length = arr.length let index = 1 while(index < length){ if(stack.length && arr[index...

2021-03-07 17:38:33 561

原创 Vue中computed和watch的区别

计算属性computed :1.支持缓存,只有依赖数据发生改变,才会重新进行计算2.不支持异步,当computed内有异步操作时无效,无法监听数据的变化3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就

2021-03-04 23:22:34 145 1

原创 二叉搜索树的第K个结点(剑指offer62)

/* function TreeNode(x) { this.val = x; this.left = null; this.right = null;} */function KthNode(pRoot, k){ let stack = [] let result = [] let current = pRoot while(current || stack.length){ if(current){ .

2021-03-04 17:15:57 105 1

原创 实现一个执行多次的有间隔的定时器函数

//使下面调用代码能正常工作const repeatFunc = repeat(console.log, 4, 3000)repeatFunc("helloworld")//会输出四次helloworld,每次间隔3s答案: function repeat (func, times, wait) { return async function(...arg){ for(let i=0;i<times;i++){ await new Promise(function

2021-03-04 15:20:05 660 1

原创 js定义一个常量属性

1.Object.freeze()(递归)// constantize实现递归freezevar constantize = (obj) => {   Object.freeze(obj);   Object.keys(obj).forEach( key => {      if ( typeof obj[key] === 'object' ) {        constantize( obj[key] );     }   });}var Obj = {   name

2021-03-04 14:03:11 469 1

原创 实现一个延迟执行队列

实现一个延时执行队列, 要求分别在 1,3,4 秒后打印出 “1”, “2”, “ 3"class Queue{ constructor(){ this.taskList = [] } task(delay,fn){ function callback(){ return new Promise(function(res,rej){ setTimeout(() => { fn() res() }, delay); }) } thi

2021-03-02 21:02:51 409

原创 判断是否存在循环引用

var a = { b: null, c: null }; a.b = a; a.c = a.c;function judge (obj){ for(let i in obj){ if(typeof obj[i] === 'object' && obj === obj[i]){ return true } } return false}

2021-03-02 20:41:49 542

原创 手写Vue观察者模式

// 发布者-目标 class Dep { constructor () { // 记录所有的订阅者 this.subs = [] } // 添加订阅者 addSub (sub) { if (sub && sub.update) { this.subs.push(sub) } } // 发布通知 notify ...

2021-03-02 20:07:48 162

转载 异步请求竞态问题(input搜索框实时搜索)

如何解决异步请求的竞态问题1.简单的解决方式,通过给请求编号,然后计数,最后的计数位是否与请求编号相同,否则return结果(比较是否是最后一个请求).但是这样简单的方法在实际使用中并不方便,你总是需要想办法返回一个计数,然后做比较判断,每个请求还都要重写一遍。2.结合了 Promise 和 XHR.abort()XMLHttpRequest 提供的 abort 方法 可以用来将 XMLHttpRequest 的 readyState 置为 0。这样就可以视为请求被 “终止” 了 。只是前端视角

2021-02-28 16:35:10 573

原创 DNS解析过程

1、域名系统概述域名系统DNS(Domain Name System)是因特网使用的命名系统,用来把便于人们使用的机器名字转换成为IP地址。域名系统其实就是名字系统。为什么不叫“名字”而叫“域名”呢?这是因为在这种因特网的命名系统中使用了许多的“域(domain)”,因此就出现了“域名”这个名词。“域名系统”明确地指明这种系统是应用在因特网中。IP地址是由32位的二进制数字组成的。用户与因特网上某台主机通信时,显然不愿意使用很难记忆的长达32位的二进制主机地址。即使是点分十进制IP地址也并不太容易记忆。相

2021-02-28 14:54:37 169

原创 vue中的缓存组件(keep-alive)

当我们进行频换切换,不需要重复渲染的时候,比如tab栏切换,就可以利用keep-alive缓存组件,不需要重复加载,也是提高vue性能的一个方式。keep-alive是什么?keep-alive是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中;使用keep-alive包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。用户在某个列表页面选择筛选条件过滤出一份数据列表,由列表页面进入数据详情页面,再返回该列表页面,我们希望:列表页面可以保留用户的筛选(或选中)状态。keep-al

2021-02-28 00:35:54 3996 1

原创 手写new

function Dog(name){ this.name = name}Dog.prototype.sayName = function(){ console.log(this.name)}// 上面是本身Dogfunction _new(fn,...args){ // ...args为ES6展开符,也可以使用arguments //先用Object创建一个空的对象, const obj = Object.create(fn.prototype) //fn.

2021-02-27 23:25:05 86

原创 对角线遍历

/** * @param {number[][]} matrix * @return {number[]} */var findDiagonalOrder = function(matrix) { if (matrix == null || matrix.length == 0) return [] let m = matrix.length let n = matrix[0].length let i = 0 let j = 0 // 预先创建好固.

2021-02-27 17:44:43 179

原创 长度最小的子数组(滑动窗口)

/** * @param {number} target * @param {number[]} nums * @return {number} */var minSubArrayLen = function(target, nums) { let size = 0; let sum = 0 let result = Infinity for(let i=0,j=0;j<nums.length;j++){ sum+=nums[j] .

2021-02-27 00:57:20 184

原创 合并二叉树

/* * function TreeNode(x) { * this.val = x; * this.left = null; * this.right = null; * } *//** * * @param t1 TreeNode类 * @param t2 TreeNode类 * @return TreeNode类 */function mergeTrees( t1 , t2 ) { // write code here if(!t1&a.

2021-02-26 02:08:31 67

原创 求区间最小数乘区间和的最大值

[3,1,6,4,5,2]对于任意子序列可以计算一个X值,X=sum(subArray) * min(subArray)求最大XX = (6+4+5) * 4 = 60 function fn(arr){ let max = 0 let result = [] while(arr.length){ let num = Math.max(...arr) result.push(...arr.splice(arr.indexOf(num),1)) let mi

2021-02-26 00:19:12 657 1

原创 vue2.0和3.0的区别

1.重构响应式系统,使用Proxy替换Object.defineProperty,使用Proxy优势:•可直接监听数组类型的数据变化•监听的目标为对象本身,不需要像Object.defineProperty一样遍历每个属性,有一定的性能提升•可拦截apply、ownKeys、has等13种方法,而Object.defineProperty不行•直接实现对象属性的新增/删除2.新增Composition API,更好的逻辑复用和代码组织3.重构 Virtual DOM•模板编译时的优化,将一些静

2021-02-24 11:50:10 1203

原创 setTimeout模拟setInterval

var i=0;setTimeout(function () { console.log(i++);//放执行的任务 setTimeout(arguments.callee, 1000);}, 1000);arguments 的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。...

2021-02-24 00:11:56 94

原创 手写异步调度器

class Scheduler {constructor(maxNum) {this.taskList = [];this.count = 0;this.maxNum = maxNum;}async add(promiseCreator) {if (this.count >= this.maxNum) {await new Promise((resolve) => {this.taskList.push(resolve)})}this.count ++;const r.

2021-02-23 23:58:39 279

原创 vue中v-if 和 v-show的区别

1.共同点:v-if 和 v-show 都可以动态地显示DOM元素2.区别(1)手段:v-if 是动态的向DOM树内添加或者删除DOM元素;v-show 是通过设置DOM元素的display样式属性控制显隐;(2)编译过程:v-if 切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;(3)编译条件:v-if 是惰性的,如果初始条件为假,则什么也不做;只有在条件第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再

2021-02-23 21:33:59 3787

原创 手写实现call和apply

// callFunction.prototype.myCall = function(thisArg, ...args) { const fn = Symbol('fn') // 声明一个独有的Symbol属性, 防止fn覆盖已有属性 thisArg = thisArg || window // 若没有传入this, 默认绑定window对象 thisArg[fn] = this // this指向调用call的对象,即我们要改变th

2021-02-23 21:16:21 127

原创 怎样创建一个没有任何属性和方法的空对象

使用: Object.create(null)生成的空对象在原型对象上也没有任何属性和方法.var obj = Object.create(null);obj; // {}obj.toString(); // Error;obj.valueOf(); // Error;

2021-02-23 20:15:34 508

原创 HTTPS的对称加密和非对称加密

非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将公钥公开,需要向甲方发送信息的其他角色(乙方)使用该密钥(甲方的公钥)对机密信息进行加密后再发送给甲方;甲方再用自己私钥对加密后的信息进行解密。甲方想要回复乙方时正好相反,使用乙方的公钥对数据

2021-02-23 10:17:20 324

原创 手写深拷贝

function fn(obj) { if(typeof obj !== 'object' || obj === null) return var newObj = obj instanceof Array ? []:{} for(var key in obj) { if(obj.hasOwnProperty(key)){ if(typeof obj[key] === 'object'){ newObj[key] = fn(obj[key]) }//如果检测某一项是一个对象

2021-02-22 22:48:50 95

原创 前端渲染插入10W条数据

// 插入十万条数据const total = 100000 // 一次插入 20 条,如果觉得性能不好就减少const once = 20 // 渲染数据总共需要几次const loopCount = total / oncelet countOfRender = 0let ul = document.querySelector("ul");function add() { // 优化性能,插入不会造成回流 const fragment = document.

2021-02-21 18:50:54 514

原创 将HTML字符转化为DOM结点

使用HTML字符串动态创建Node1使用innerHTML我们使用document.createElement方法创建新的元素,然后利用innerHTML将字符串注入进去,最后返回firstChild,得到动态创建的Node,添加到文档底部。 function createNode(txt) { const template = `<div class='child'>${txt}</div>`; let tempN

2021-02-21 18:37:42 525

原创 二叉树的右视图

/** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 求二叉树的右视图 * @param xianxu int整型一维数组 先序遍历 * @param zhongxu int整型一维数组 中序遍历 * @return int整型一维数组 */function solve( xianxu , zhongxu ) { // write code here function TreeNode(x){ this.val = x .

2021-02-21 17:03:25 79

原创 扫码登录技术的原理

首先用户打开网站的登录页面的时候,向浏览器的服务器发送获取登录二维码的请求。服务器收到请求后,随机生成一个uuid,将这个id作为key值存入数据库,同时设置一个过期时间,在时间到期后从数据库删除该条记录,用户登录二维码需要进行刷新重新获取。将这个key值和本公司的验证字符串合在一起,通过二维码生成接口,生成一个二维码的图片(二维码生成,网上有很多现成的接口和源码)。然后,将二维码图片和uuid一起返回给用户浏览器。浏览器拿到二维码和uuid后,会每隔一秒向浏览器发送一次,登录是否成功的请求。请求中携.

2021-02-21 13:27:21 158

原创 机器人dp求路径

/** * * @param m int整型 * @param n int整型 * @return int整型 */function uniquePaths( m , n ) { // write code here let dp = [] for(let i=0;i<m;i++){ dp[i] = new Array(n).fill(1) } for(let i=1;i<m;i++){ fo.

2021-02-21 12:46:10 148

原创 版本号排序

JS写版本号排序,如传入参数[‘1.5’,‘2.0’,‘1.7’,‘1.1.5’] 返回 [‘1.1.5’,‘1.5’,‘1.7’,‘2.0’]1.sortlet arr = ['1.5','2.0','1.7','1.1.5']arr.sort(function(a,b){ return a>b?1:-1});console.log(arr) //["1.1.5", "1.5", "1.7", "2.0"]换个case可能存在错误 为什么字符串比较能够轻松的实现排序?sort()对数

2021-02-20 19:22:37 1057

原创 cookie有哪些字段/cookie和session的区别

name  字段为一个cookie的名称。value  字段为一个cookie的值。domain  字段为可以访问此cookie的域名。非顶级域名,如二级域名或者三级域名,设置的cookie的domain只能为顶级域名或者二级域名或者三级域名本身,不能设置其他二级域名的cookie,否则cookie无法生成。顶级域名只能设置domain为顶级域名,不能设置为二级域名或者三级域名,否则cookie无法生成。二级域名能读取设置了domain为顶级域名或者自身的cookie,不能读取其他二级域名doma

2021-02-20 00:33:48 1967

原创 手写事件代理(兼容IE浏览器)

<div id="btns"> <button data-id="1">按钮1</button> <button data-id="2">按钮2</button> <button data-id="3">按钮3</button> <button data-id="4">按钮4</button> <div>666</div> </div>.

2021-02-19 23:11:04 90

原创 容器盛水问题NC128

/** * max water * @param arr int整型一维数组 the array * @return long长整型 */function maxWater( arr ) { // write code here if(!arr) return; let val = 0; let left = 0, right = arr.length -1; let leftMax = 0, rightMax = 0; while(left &lt

2021-02-19 16:41:10 126

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除