一、vue异步处理

  1. 概念
    • 在 Vue 中,异步操作极为关键,常用于应对如数据获取、耗时任务等场景,其核心目的在于防止阻塞主线程,以此提升用户体验。例如,在组件的 created 或 mounted 生命周期钩子内发起网络请求以获取数据,而实际操作中,常借助 axios 或原生的 fetch 这类异步函数达成。
  1. 示例
export default {
  created() {
    axios.get('https://api.example.com/data')
    .then(response => {
        this.data = response.data;
      })
    .catch(error => {
        console.error('Error fetching data:', error);
      });
  }
}
  • 在此组件创建之际,运用 axios 异步获取数据,一旦成功,便将数据赋值给组件实例的 data 属性;倘若失败,则在控制台打印错误信息。通过这种异步处理模式,页面在等待数据的时段,能够正常渲染其他部分内容,待数据成功返回后,再针对性地更新相应区域。

二、浏览器缓存策略

  1. 缓存类型
    • 强缓存
      • 浏览器会直接依据本地缓存读取资源,此过程不会向服务器发起请求,其控制手段主要依托 Cache-Control(如借助 max-age 来指定缓存有效期)以及 Expires 头部字段。例如,设定 Cache-Control: max-age=3600,这意味着在 1 小时内,浏览器可径直从缓存中获取资源。
    • 协商缓存
      • 浏览器首先向服务器发送请求,并携带资源的标识,诸如 Last-Modified 和 ETag。服务器依据这些标识判别资源是否有更新,若资源未更新,便返回 304 Not Modified,此时浏览器会启用本地缓存。举例来说,服务器首次响应时附上 Last-Modified 时间戳,下次请求时浏览器则带上 If-Modified-Since 字段,服务器通过对比时间来决定是否返回全新资源。
  1. 应用场景
    • 针对静态资源,像是样式表、脚本、图片等,可设置相对较长的强缓存时间,以此减少重复加载的频次;而对于那些频繁更新的 API 数据,通常会禁用缓存或者设定较短的缓存时间,以此确保数据的及时性。合理且巧妙地运用缓存策略,不但能够加快页面的加载速度,还能有效减轻服务器的压力。

三、 同源策略

  1. 定义
  1. 限制范围
    • 其限制范畴覆盖了 DOM 访问、AJAX 请求、Cookie 读写等多个关键领域。不过,同源策略并非完全杜绝跨源交互,借助一些合规的机制,诸如 CORS(跨域资源共享)、JSONP 等,能够实现安全可靠的跨域操作。

四、解决跨域

  1. CORS 方式
    • 服务器在响应头中设置 Access-Control-Allow-Origin 字段,以此明确指定允许跨域访问的源。例如:
Access-Control-Allow-Origin: https://client.example.com
  • 如此一来,客户端发起的跨域 AJAX 请求便能顺利接收响应。与此同时,还能够配置诸如 Access-Control-Allow-Methods 等其他字段,用以限制允许使用的 HTTP 方法。
  1. JSONP
    • 充分利用script标签不受同源策略限制的特性,客户端动态创建script标签,并使其指向跨域服务器所提供的一个附带回调函数名的 URL,随后服务器返回包裹于回调函数内的数据,以此实现跨域数据的获取。这种方式常用于旧浏览器的兼容场景,不过需要注意的是,它仅能发起 GET 请求。
  1. 代理服务器
    • 在同源的后端服务器设置代理,前端请求首先发送至同源代理,再由代理将请求转发至目标跨域服务器,最后把结果返还给前端,这般操作巧妙地隐藏了跨域的实际过程,在开发环境配置中较为常用,例如 webpack-dev-server 中的 proxy 选项便是典型应用。

五、 前端常见的安全问题

  1. XSS(跨站脚本攻击)
    • 攻击者蓄意将恶意脚本注入目标网站,进而窃取用户信息等重要数据。预防此类攻击的关键举措包括对用户输入输出内容进行转义、过滤处理,例如可运用 DOMPurify 库来净化 HTML 内容,坚决避免直接将用户输入嵌入页面代码之中。
  1. CSRF(跨站请求伪造)
    • 当用户登录受信任网站 A 后,在访问恶意网站 B 时,网站 B 会诱导用户浏览器向网站 A 发起请求,借此利用用户的登录态执行非预期操作。防范该风险的有效手段是在表单或 AJAX 请求中添加随机 Token,服务器通过验证 Token 的合法性,确保请求源自真实用户的操作。

六、水平垂直居中

  1. CSS 方法
    • 对于已知宽高的元素:
.center {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 200px;
  height: 100px;
  margin-top: -50px; /* 高度的一半 */
  margin-left: -100px; /* 宽度的一半 */
}
  • 采用绝对定位结合负 margin 的方式,能够精准实现居中效果。通过将元素的左上角定位至父容器的中心位置(即 top: 50%; left: 50%;),再利用负 margin 抵消元素自身宽高的一半,从而达成水平垂直居中。
  • 使用 flexbox 布局:
.container {
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
}
  • 借助 flexbox 布局的强大特性,只需简单设置容器的 display 为 flex,并运用 justify-content 和 align-items 属性分别控制水平和垂直方向的对齐方式,即可自动实现容器内元素的居中效果,且无需提前知晓子元素的尺寸,适用于多种复杂场景。
  1. JavaScript 方法(不常用但特殊场景)
    • 通过 JavaScript 获取元素的尺寸以及窗口尺寸,依据这些数据动态计算并设置元素的 style.top 和 style.left 属性,以此实现居中效果。不过,这种方式会带来较大的性能开销,因此在实际应用中,优先考虑采用 CSS 方案。

七、box-sizing属性

  1. 属性值含义
    • content-box(默认)
      • 元素的宽度和高度仅仅涵盖内容区域,边框和内边距会额外向外扩展,这就导致实际占据的空间会大于所设置的值。例如,当设置 width: 100px,并添加 2px 的边框和 10px 的内边距后,实际宽度将变为 124px。
    • border-box
      • 此时元素的宽度和高度包含内容、边框以及内边距,所设置的值即为元素最终占据的空间大小,这极大地方便了布局计算。以设置 width: 100px 为例,即便添加了边框和内边距,元素的总宽依然固定为 100px,内容区宽度会自动进行适应性调整。
  1. 应用场景
    • 在响应式设计或是复杂布局构建过程中,border-box 属性能够确保元素尺寸在添加各类样式后保持稳定,有效规避因样式调整引发的意外布局错乱问题。鉴于此,建议在 CSS 初始化阶段,全局设置 box-sizing: border-box。

八、看代码回答问题

2024-12-24T01:39:27.png

九、手写css实现无限旋转

.rotate {
  animation: rotateAnimation 2s linear infinite;
}

@keyframes rotateAnimation {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
  • 将 rotate 类赋予需要旋转的元素,充分利用 CSS 动画的 animation 属性,精准指定动画名称为 rotateAnimation、持续时间设定为 2s、运动方式采用线性 linear 并设置为无限循环 infinite。同时,借助 @keyframes 规则明确定义起始(0 度)与结束(360 度)的旋转状态,通过这般设置,即可顺利实现元素的无限旋转效果,此效果在加载提示等场景中应用颇为广泛。

十、看代码回答问题

2024-12-24T01:39:52.png

十一、事件循环机制

  1. 概念
    • JavaScript 作为一门单线程语言,却得益于浏览器提供的异步执行能力,而事件循环正是用于协调同步与异步任务执行的关键机制。它主要包含一个执行栈(用于存放同步任务)以及一个任务队列(用于存放异步任务的回调)。主线程率先执行同步任务,待同步任务执行完毕后,便会从任务队列中取出异步任务的回调,并将其放入执行栈中执行。
  1. 示例
console.log('start');
setTimeout(() => {
  console.log('timeout');
}, 0);
Promise.resolve().then(() => {
  console.log('promise');
});
console.log('end');
  • 上述代码的输出顺序为 start -> end -> promise -> timeout。原因在于 setTimeout 的回调属于宏任务,即便延迟时间设置为 0,它也需在当前执行栈为空且微任务队列执行完毕之后,才会进入执行栈执行;而 Promise.then 的回调属于微任务,会在当前执行栈的同步任务结束后即刻执行。

十二、宏任务和微任务和执行机制

  1. 宏任务
    • 涵盖 setTimeout、setInterval、I/O 操作、script 整体代码等诸多类型。每当一个宏任务执行结束后,都会对微任务队列进行检查,并将其中的微任务全部清空执行。
  1. 微任务
    • 诸如 Promise.then、MutationObserver 回调等皆属于微任务范畴。它们会在当前宏任务执行结束后的下一个微任务检查点执行,并且优先于下一个宏任务执行,以此确保异步任务能够依照优先级有序推进,避免阻塞主线程过长时间,进而维持页面的良好响应性能。
  1. 执行流程
    • 同步任务 -> 微任务队列(全部执行完) -> 宏任务队列(取出一个执行,再重复检查微任务队列),如此循环往复,有条不紊地保障了 JavaScript 代码在浏览器环境中的高效运行。

十三、看代码回答问题

2024-12-24T01:40:13.png

十四、手写js合并有序数组

function mergeSortedArrays(arr1, arr2) {
  const result = [];
  let i = 0, j = 0;
  while (i < arr1.length && j < arr2.length) {
    if (arr1[i] < arr2[j]) {
      result.push(arr1[i++]);
    } else {
      result.push(arr2[j++]);
    }
  }
  return result.concat(i < arr1.length? arr1.slice(i) : []).concat(j < arr2.length? arr2.slice(j) : []);
}

const array1 = [1, 3, 5];
const array2 = [2, 4, 6];
console.log(mergeSortedArrays(array1, array2)); 
// 输出: [1, 2, 3, 4, 5, 6]
  • 通过双指针法,分别对两个有序数组进行遍历。在遍历过程中,持续比较当前指针指向元素的大小,将较小值优先放入结果数组,并相应地移动指针。待其中一个数组遍历完毕后,将剩余未遍历完的数组部分通过 concat 方法拼接到结果数组,以此实现高效合并有序数组。该算法的时间复杂度为 O(m+n) ,其中 m 、n 分别代表两个数组的长度,空间复杂度同样为 O(m+n) ,主要用于存储结果数组。

十五、分析代码的时间复杂度空间复杂度

标签: none

添加新评论