0
点赞
收藏
分享

微信扫一扫

十大排序算法C++实现

color_小浣熊 2023-11-07 阅读 39
前端

1. vue性能优化

  1. v-if和v-show使用:频繁切换使用v-show(display样式),反之使用v-if(删除与新值DOM)
  2. v-for必须加key,不能使用index当作key(使用index,如果数组发生变化,key会变化、重新渲染)
  3. v-for和v-if不要同时使用,v-for优先级高于v-if,可能导致不必要渲染的元素也v-for循环一遍
  4. 图片资源的懒加载 vue-lazyload
  5. 路由懒加载
  6. watcher的数量(不要过多),可以使用计算属性代替 或者vue的$watch
  7. 事件的及时销毁,addEventListener不会及时销毁,在beforeDestory或者destoryed手动进行remove,避免内存泄漏
  8. 首屏的渲染优化:路由懒加载、首页loading动画、预渲染、服务端渲染
  9. 图片进行压缩,压缩图片大小、纯静态文件可以无损压缩(静态资源)
  10. CDN可以通过不同域名加载图片、文件(CDN加数)
  11. 上线打包,不要生成反编译(.map)文件,经常使用的组件、函数进行封装
  12. 内置组件,keep-alive页面缓存,避免每次重新渲染、提高性能
  13. 启用浏览器缓存,减少重复的网络请求
  14. 获取DOM节点,可以使用ref,来减少销毁,Object.freeze处理data属性
  15. 重绘和回流,可以适当使用
    • 重绘(repaint): 渲染树节点发生改变,但不影响该节点在页面当中的空间位置及大小。譬如某个div标签节点的背景颜色、字体颜色等等发生改变,但是该div标签节点的宽、高、内外边距并不发生变化,此时触发浏览器重绘(repaint)。
    • 重排(reflow): 也有称回流,当渲染树节点发生改变,影响了节点的几何属性(如宽、高、内边距、外边距、或是float、position、display:none;等等),导致节点位置发生变化,此时触发浏览器重排(reflow),需要重新生成渲染树。譬如JS为某个p标签节点添加新的样式:“display:none;”。导致该p标签被隐藏起来,该p标签之后的所有节点位置都会发生改变。此时浏览器需要重新生成渲染树,重新布局,即重排(reflow)。
    • 理论上,每一次的dom更改或者css几何属性更改,都会引起一次浏览器的重排/重绘过程,而如果是css的非几何属性更改,则只会引起重绘过程。所以说重排一定会引起重绘,而重绘不一定会引起重排。
    • 何时会引起重排?
      (1)页面首次渲染(2)添加、删除元素(3)改变元素大小(内外边距、边框、宽高)(4)改变元素位置——display、float、position、overflow等等;(5)改变元素内容——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;(6)改变字体大小(7)跳转浏览器窗口大小(8)查询某些属性或调用某些方法
    • 减少重排,优化性能
      (1)避免频繁操作样式——一次性改变style属性、增减class属性(2)避免频繁操作DOM——脱离文档流 修改 放回、文档碎片使用DocumentFragment将需要多次修改的DOM元素缓存,最后一次性append到真实DOM中渲染、隐藏 显示 修改(可以将需要多次修改的DOM元素设置display:none,操作完再显示。因为隐藏元素不在render树内,因此修改隐藏元素不会触发回流重绘)(3)避免多次访问一下属性或方法——clientTop、offsetTop、scrollTop、getComputedStyle()、getBoundClientRect()(4)复杂动画——使用绝对定位或者fixed属性,脱离文档流 不影响其他元素的布局(5)触发css3硬件加速——transform、opacity、filters这些动画不会引起回流重绘
  16. 重绘和重排(回流)解释
    ⭐重绘:当元素的一部分属性发生改变,如外观、背景、颜色等不会引起布局变化,只需要浏览器根据元素的新属性重新绘制,使元素呈现新的外观叫做重绘。
    ⭐重排(回流):当 render 树中的一部分或者全部因为大小边距等问题发生改变而需要 DOM 树重新计算的过程。
    🛰️重绘不一定需要重排(比如颜色的改变),重排必然导致重绘(比如改变网页位置)。

🛰️方法:
(1) 需要要对元素进行复杂的操作时,可以先隐藏(display:“none”),操作完成后再显示
(2)需要创建多个 DOM 节点时,使用 DocumentFragment 创建完后一次性的加入 document,缓存 Layout 属性值,如:var left = elem.offsetLeft; 这样,多次使用 left 只产生一次回流
(3)尽量避免用 table 布局(table 元素一旦触发回流就会导致 table 里所有的其它元素回流)
(4)避免使用 css 表达式(expression),因为每次调用都会重新计算值(包括加载页面)
(5)尽量使用 css 属性简写,如:用 border 代替 border-width, border-style, border-color
(6)批量修改元素样式:elem.className 和 elem.style.cssText 代替 elem.style.xxx

2. this指向问题

  1. 普通函数:
  • this总是代表着他的直接调用者,例如obj.fun(),那么fun()中的this就是obj;
  • 调用的时候,没有任何前缀,则指向window,new的时候,指向new出来的对象;
  • 在默认情况下(非严格模式),没找到直接调动者,则this指向window;
  • 在严格模式下,没有直接调用者的函数中的this是undefined;
  • 使用call、apply、bind绑定的,this指向绑定的对象。
  • 在 Node 中,指向 Global
  • 在定时器中,this指向window
  1. 箭头函数(继承外层普通函数的this):
  • this对象,就是定义时所在的对象,而不是使用时所在的对象;!!!
  • 不可以当做构造函数,即不能使用new;
  • 不可以使用arguments对象,该对象在函数体内不存在,如果要用可以rest参数替代;
  • 不可以使用yield命令,因此箭头函数不能使用Generator函数;
  • 返回对象时必须在对象外面加上括号。
    普通函数this指向可变,但是箭头函数是固定的。

3. JavaScript垃圾回收机制(是什么?哪种最常用?实现原理?)

  1. 在JavaScript中,垃圾回收(Garbage Collection)是一种自动内存管理机制,它可以自动地识别不再使用的变量和对象并将它们从内存中清除,以释放内存空间。为了防止内存泄漏
    JavaScript中的垃圾回收器会定期扫描内存中的对象,标记那些可达对象和不可达对象。
    可达对象指的是当前代码中正在被使用的对象
    不可达对象指的是已经不再被引用的对象。
    垃圾回收器会将不可达对象标记为垃圾对象,并将它们从内存中清除。
  2. JavaScript中的垃圾回收机制主要有两种:
    标记清除(Mark-and-Sweep)和引用计数(Reference Counting)。
    标记清除是JavaScript中主流的垃圾回收算法,而引用计数则已经很少被使用。
  3. 标记清除(Mark-and-Sweep)
    • 标记清除的工作原理是:垃圾回收器会定期扫描内存中的对象,从根对象开始遍历内存中的所有对象,对于可达对象,通过标记它们来标识它们是可达对象;对于未被标记的对象,就说明它们是不可达对象,需要被清除。该算法的优点是可以处理循环引用的情况,但在执行时间上可能会比较长,影响程序的性能。例如,有一个对象A,其中包含一个指向对象B的引用,而对象B也包含一个指向对象A的引用。此时,如果我们不手动清除这两个对象,垃圾回收器就会通过标记清除算法自动识别这两个对象并清除它们。
    • 实现标记清除(Mark-and-Sweep)算法的主要步骤如下:(1)创建一个根对象,例如window对象;(2)遍历根对象及其所有引用的对象,并标记它们是可达对象;(3)遍历内存中所有对象,如果发现某个对象未被标记,就将其清除。(4)在JavaScript中,标记清除算法是由浏览器自动完成的,开发者无需手动实现。

4. 事件循环eventLoop

微任务和宏任务的执行顺序是先执行同步任务,先执行同步后异步,异步分为宏任务和微任务两种,异步遇到微任务先执行微任务,执行完后如果没有微任务,就执行下一个宏任务。
一般的JavaScript代码(同步)的属于宏任务,定时器相关的异步代码,包括setTimeOut、setInterval等也属于宏任务

  1. 事件循环,是JavaScript或node为解决单线程代码不阻塞主进程的一种机制,也就是异步原理。
  • 从宏任务的头部取出一个任务执行;
  • 执行过程中若遇到微任务则将其添加到微任务的队列中
  • 宏任务执行完毕后,微任务的队列中是否存在任务,若存在,则挨个儿出去执行,直到执行完毕;
  • GUI 渲染;
  • 回到步骤 1,直到宏任务执行完毕;这 4 步构成了一个事件的循环检测机制,即我们所称的eventloop。
  1. 执行栈和任务队列
  • 执行栈是什么
    用于按执行顺序存放同步代码;
    按序执行,执行完毕后弹出执行栈;
    如果在执行过程中遇到异步操作,就交给其他线程处理。
  • 任务队列
    用于按序排放异步操作执行结束后的回调函数;
    任务队列中的函数等待执行栈执行结束后取出执行。
  1. 宏任务和微任务:先执行宏任务,再检查有没有微任务,如果有就执行微任务,然后渲染dom,最后进入下一次事件循环。
  • 宏任务:setTimeout、setInterval、DOM操作回调函数、Ajax网络请求。每次准备取出第一个宏任务队列前,都要将所有微任务一个一个取出来执行
  • 微任务:promise、mutations

5. 深拷贝、浅拷贝、赋值

  1. 浅拷贝的实现方式:
  • object.assign()
  • lodash 里面的 _.clone
  • …扩展运算符
  • Array.prototype.concat
  • Array.prototype.slice
  1. 深拷贝的实现方式-不会影响原本的对象
  • JSON.parse(JSON.stringify())
  • 递归操作
  • cloneDeep:lodash中 _.cloneDeep
  • Jquery.extend()

递归实现深拷贝:

function deepClone(o, obj) {
for (let k in obj) {
if (obj[k] instanceof Array) {
o[k] = [];
deepClone(o[k], obj[k]);
} else if (obj[k] instanceof Object) {
o[k] = {};
deepClone(o[k], obj[k]);
} else {
o[k] = obj[k]
}
}
}

6. get(1024KB) 和 post 的区别

  1. 区别
  • GET在浏览器回退不会再次请求,POST会再次提交请求
  • GET请求会被浏览器主动缓存,POST不会,要手动设置
  • GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会
  • GET请求在URL中传送的参数是有长度限制的,而POST没有限制
  • GET参数通过URL传递,POST放在Request body中
  • GET参数暴露在地址栏不安全,POST放在报文内部、更安全
  • GET一般用于查询信息,POST一般用于提交某种信息进行某些修改操作
  • GET产生一个TCP数据包;POST产生两个TCP数据包
  1. Get和post的选择:
  • 私密性的信息请求使用post(如注册、登陆)。
  • 查询信息使用get。

7. 进程和线程

进程:是指系统正在运行的一个应用程序(手机上可以理解为一个App,PC上可以理解为程序),是系统进行资源分配和调度的基本单位。一个程序或者应用至少有一个进程。
线程:线程呢则是CPU调度最小(比进程更小)的能独立运行的执行单元,也是有限的系统资源。
两者之间的关系:一个进程之间至少包含一个或多个线程,(包含的关系)进程有一个独立的运行空间,其中的线程共享此空间,也拥有此进程的全部资源,因此可以并发(并行)执行。

8. watch、methods、computed

在官方文档中,强调了computed区别于method最重要的两点:
1 . computed是属性调用,而methods是函数调用
2 . computed带有缓存功能,而methods不会被缓存
属性调用:
1 .computed定义的方法我们是以属性访问的形式调用,{{computedTest}}
2 .methods定义的方法,我们必须要加上()来调用
{{methodTest()}}
缓存功能:
1️⃣计算属性具有缓存:只有当计算属性所依赖的属性发生改变时,才会重新去计算
2️⃣methods不会被缓存:方法每次都会去重新计算结果。
🎁缓存好处:
相比大家都知道HTTP缓存,其核心作用就是对一些服务端未更新的资源进行复用,避免一些无谓的请求,优化了用户的体验。
🌞🌞watch是观察某一个属性的变化,重新计算属性值。computed是通过所依赖的属性的变化重新计算属性值。在这里插入代码片,大部分情况下watch和computed几乎没有差别。但如果要在数据变化的同时进行异步操作或者是比较大的开销,那么watch为最佳选择。
⭐⭐Watch是属性监听,监听属性的变化;computed是计算属性,通过属性计算而得来的属性。 watch需要在数据变化时执行异步或开销较大的操作时使用。 computed 属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。

9. localStorage 、sessionStorage 和 cookie的区别

  1. 共同点:都是保存在浏览器端、且同源的
  2. 🌞🌞区别:
    1️⃣cookie 数据始终在同源的 http 请求中携带(即使不需要),即 cookie 在浏览器和服务器间来回传递,而 sessionStorage 和 localStorage 不会自动把数据发送给服务器,仅在本地保存。cookie 数据还有路径(path)的概念,可以限制 cookie 只属于某个路径下。
    2️⃣存储大小限制也不同,cookie 数据不能超过 4K,同时因为每次 http 请求都会携带cookie、所以 cookie 只适合保存很小的数据,如会话标识。sessionStorage 和 localStorage虽然也有存储大小的限制,但比 cookie 大得多,可以达到 5M 或更大。
    3️⃣数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的 cookie 过期时间之前有效,即使窗口关闭或浏览器关闭。
    4️⃣作用域不同,sessionStorage 不在不同的浏览器窗口中共享,即使是同一个页面;localstorage 在所有同源窗口中都是共享的;cookie 也是在所有同源窗口中都是共享的。
    🖐🏻web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。
    6️⃣web Storage 的 api 接口使用更方便。

10. 如何解决跨域

  1. 同源策略
    同源策略(same origin policy)是netScape(网景)提出的一个安全策略,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。具体表现为浏览器在执行脚本前,会判断脚本是否与打开的网页是同源的,判断 协议、域名、端口是否都相同,相同则表示同源。 其中一项不相同就表示跨域访问、会在控制台报一个CORS异常,目的是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。
    浏览器采用同源策略,在没有明确授权的情况下,禁止页面加载或执行与自身不同源的任何脚本。
  2. ⭐解决方式⭐
    (1) jsonp 仅支持GET请求
    原理:动态创建一个 script 标签。利用 script 标签的 src 属性不受同源策略限制。因为所有 的 src 属性和 href 属性都不受同源策略限制。可以请求第三方服务器数据内容。
    (2)CORS:跨域资源共享 只需后端配置,前端不需要配置
    原理:服务器设置 Access-Control-Allow-OriginHTTP 响应头之后,浏览器将会允许跨域请求。res.setHeader('Access-Control-Allow-Origin', origin)
    (3)反向代理
    (4)window+iframe
举报

相关推荐

0 条评论