罐头博客罐头博客
面试记录
面试记录
2022-8-19 20:16:30

2022.08.19 量投科技

2022.08.22 鲁班软件

1. TS 泛型的理解

  • 在定义函数、接口或者类的时候,不预先指定具体的类型,而是在使用的时候再指定类型的一种特性。
  • 提高代码可重用性,使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。
function f<T>(arg: T): T {
  return arg;
}

2. html 性能优化

  • HTML 优化 减少 iframes 的使用,
    • 父 html 需要等待所有 iframe 加载完成
  • 压缩空白符
  • 避免节点深层次的嵌套
  • 避免 table 布局
  • 删除注释
  • css&javascript 尽量外链
  • 删除元素默认属性

3. css 性能优化

  • 内联首屏关键 css
  • 异步加载非首屏 css
  • css 文件压缩
  • css 层级嵌套最好不要超过 3 层
  • 删除无用 css 代码
  • 慎用*通配符
  • 小图片用雪碧图,字体图标或者转成 base64
  • 避免使用@import
  • 优化回流和重绘

4. ES6 中的数组方法

  • forEach
  • map
  • filter
  • find
  • every
  • some
  • reduce

5. ajax, axios, fetch 区别

ajax
  • 局部刷新页面,无需重载整个页面。

简单来说,Ajax 是一种思想,XMLHttpRequest 只是实现 Ajax 的一种方式

fetch
  • 使用 promise,不使用回调函数。
  • 采用模块化设计,比如 rep、res 等对象分散开来,比较友好。
  • 通过数据流对象处理数据,可以提高网站性能。
axios

Axios 是一个基于 promise 封装的网络请求库,它是基于 XHR 进行二次封装

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

6. for,forEach 和 map 的区别

  • 在固定长度或者长度不需要计算的时候 for 循环效率高于 foreach 和 map,for 循环中可以通过 break 终止。
  • 在不确定长度或者计算长度有损性能的时候用 foreach 和 map 比较方便
相同点:
  • 都是循环遍历数组中的每一项

  • forEach 和 map 方法里每次执行匿名函数都支持 3 个参数,参数分别是 item(当前每一项),index(索引值),arr(原数组)

  • 匿名函数中的 this 都是指向 window

  • 只能遍历数组

  • 都不会改变原数组

不同点:
  • map 方法返回一个新的数组,数组中的元素为原始数组调用函数处理后的值
  • forEach 方法不会返回新数组
性能:
  • for > forEach > map
  • for 循环当然是最简单的,因为它没有任何额外的函数调用栈和上下文
  • forEach 其次,因为它其实比我们想象得要复杂一些。它不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能;
  • map 最慢,因为它的返回值是一个等长的全新的数组,数组创建和赋值产生的性能开销很大。

7. 性能优化方案

  • 减少 HTTP 请求
  • 使用服务端渲染
  • 静态资源使用 CDN
  • CSS 文件放在头部,JS 文件放在底部
  • 善用缓存,不重复加载相同的资源
  • 压缩文件
  • 图片延迟加载
  • 使用事件委托
  • 使用 Web Workers

2022.08.23 聚水潭

2022.08.29 拼多多

1. 实现 Promise 重试

function runWithRetry(fn, retryTimes) {
  return fn()
    .then((res) => {
      return res;
    })
    .catch((err) => {
      if (retryTimes === 0) {
        return Promise.reject(err);
      }
      return runWithRetry(fn, retryTimes - 1);
    });
}

function asyncApp() {
  return new Promise((resolve, reject) => {
    if (Math.random() > 0.7) {
      resolve('success');
      console.log('success');
    } else {
      reject('failed');
      console.log('failed');
    }
  });
}

runWithRetry(asyncApp, 3);

2. Promise 的输出

function asyncApp() {
    return new Promise((resolve, reject) => {
        reject('failed')
        resolve('success');
    })
}

asyncApp().then(res => {
    console.log('then1', res);
}).then(res => {
    console.log(('then2', res));
}).catch(err => {
    console.log('catch1', err);
}).then(res => {
    console.log('then3', res);
})

// 输出
catch1 failed
then3 underfined

3. 倒计时组件

function CountDown({ process }) {
  const [count, setCount] = useState(process);

  useEffect(() => {
    setCount(process);
  }, [process]);

  useEffect(() => {
    let id = null;

    if (count > 0) {
      id = setTimeout(() => {
        setCount(count - 1);
      }, 1000);
    }

    return () => {
      clearTimeout(id);
    };
  }, [count]);

  return <div>{count}</div>;
}

4. defer 和 async 的区别

  • defer, 当浏览器遇到带有 defer 属性的 script 时,获取该脚本的网络请求也是异步的,不会阻塞浏览器解析 HTML,一旦网络请求回来之后,如果此时 HTML 还没有解析完,浏览器不会暂停解析并执行 JS 代码,而是等待 HTML 解析完毕再执行 JS 代码
  • async, 当浏览器遇到带有 async 属性的 script 时,请求该脚本的网络请求是异步的,不会阻塞浏览器解析 HTML,一旦网络请求回来之后,如果此时 HTML 还没有解析完,浏览器会暂停解析,先让 JS 引擎执行代码,执行完毕后再进行解析

5. flex

  • flex-grow: 定义项目的放大比例,默认为 0,即如果存在剩余空间,也不放大
  • flex-shrink: 定义了项目的缩小比例,默认为 1,即如果空间不足,该项目将缩小
  • flex-basis: 定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为 auto,即项目的本来大小
  • flex-wrap: 定义,如果一条轴线排不下,如何换行

6. CSS 选择器

  • // 同时有a, b两个class
    .a.b {
      color: red;
    }
    
  • // a元素内的所有b子元素
    .a .b {
      color: red;
    }
    
  • // 父级是a元素的b元素
    .a > .b {
      color: red;
    }
    
  • // 紧跟在a元素后的第一个b元素
    .a + .b {
      color: red;
    }
    

7. 用过哪些抓包工具