抖音前端三面面经

概括

过去一年跳槽了两次,最近的一年都在面试,失败了很多次,也拿了很多offer,腾讯,字节,虾皮,滴滴都oc,最终人生的第三方份工作选择了腾讯,工作空闲之余,把最近一年的面经整理一下。

联系我:Chan-FE 可 腾讯内推~

抖音三面面经title list

  1. 介绍一个项目难点,如何解决的
  2. 介绍一下webpack tapable模块
  3. loader pitch有使用过吗,介绍一个它的应用
  4. style-loader原理
  5. 简单介绍一下SSR的原理
  6. SSR内存泄漏的话如何排查
  7. 项目FCP、CLS的统计标准是什么,具体做了什么使得CLS指标得到下降
  8. 除了技术上的优化,业务上有什么设计使得整体架构更合理吗(结合技术和业务来说)
  9. https的主动推送主要推送什么资源,需要全部都推送吗
  10. 怎么检测客户端是否兼容webp格式
  11. 技术选型
  12. React fiber的优势在哪里
  13. loadsh get的实现
  14. 实现一个const
  15. 1万张图片,并发下载10张,最快的方法下载完成

项目+八股

1.介绍一个项目难点,如何解决的

项目打包过慢,排查原因:输出缓存的tapable同步钩子报错,导致缓存失效

2.介绍一下webpack tapable模块

3.loader pitch有使用过吗,介绍一个它的应用

  • 四种loader: post、inline、normal、pre
  • 两种执行阶段 pitching和normal阶段
  • Pitching 阶段: loader 上的 pitch 方法,按照 后置(post)、行内(inline)、普通(normal)、前置(pre) 的顺序调用。
  • Normal 阶段: loader 上的 常规方法,按照 前置(pre)、普通(normal)、行内(inline)、后置(post) 的顺序调用。模块源码的转换, 发生在这个阶段
  • 应用style-loader
  • 参考:https://juejin.cn/post/7037696103973650463

4.style-loader原理

css-loader 负责解析 CSS 文件的 @importurl() 依赖,并将 CSS 转换为 JavaScript 模块;style-loader 则负责将模块内容注入 DOM。如果不使用pitch,style得到的入参将是js代码,而不是处理好的css代码,style-loader 通过 Webpack 的 pitch 方法实现熔断。默认情况下,loader 从右向左执行(如 css-loader → style-loader),但 pitch 方法允许从左向右执行。style-loader 的 pitch 方法会先执行,先直接跳过后续 loader 的默认处理流程,转而通过 require 手动调用 css-loader 获取 CSS 内容(后面loader将通过inline loader的形式执行)

5.简单介绍一下SSR的原理

将传统单页面应用(SPA)的渲染过程从客户端转移到服务器端,通过动态生成完整的 HTML 页面解决首屏加载性能与 SEO 问题。服务器在渲染可以执行组件定义的 数据预取逻辑,将异步获取的数据直接嵌入 HTML 中。客户端收到 HTML 后,会先快速展示静态内容(提升首屏速度),随后加载客户端 JavaScript 文件。框架通过 Hydration 机制 将事件绑定、状态管理等逻辑“注入”已渲染的静态 DOM,使其具备交互能力。

6.SSR内存泄漏的话如何排查

比较堆栈信息,第三方工具实时监控内存变化

7.项目FCP、CLS的统计标准是什么,具体做了什么使得CLS指标得到下降

  • FCP:用户首次看到页面中元素的时间
  • CLS:页面渲染过程中非预期布局波动的计算分数
  • 降低cls

8.除了技术上的优化,业务上有什么设计使得整体架构更合理吗(结合技术和业务来说)

业务:

  • 关键资源去配置化,减少网络请求
  • 简化业务流程

技术:

  • 优化打包机制,均衡切割chunk
  • 合并接口,减少网络请求
  • 整合全局token,减少非必要的鉴权校验
  • https做资源推送,搭配容器做缓存

9.https的主动推送主要推送什么资源,需要全部都推送吗

  • 首屏关键资源(字体、样式等),动态资源需要谨慎推送
  • 若推送的资源已被浏览器缓存,会造成重复传输。
  • 推送过多资源会占用带宽,反而拖慢页面加载速度。

10.怎么检测客户端是否兼容webp格式

11.技术选型

  • hybird架构
  • RN原生控件渲染
  • flutter自研渲染引擎
  • 其他跨段方案

12.React fiber的优势在哪里

  • 大任务拆分成小任务
  • 两颗diff树相互引用,减少diff导致的崩溃
  • 增加指针指向父元素、兄弟元素,空间换时间
  • 闭包+链表使得函数组件拥有了数据持久化的能力,hook开始发展

算法

13.loadsh get的实现

//lodash的get方法
function get(object, path, defaultValue = 'undefined') {
    //构造数组,将'['和']'替换成'.'
    let newPath = [];
    newPath = path.replace(/\[/g, '.').replace(/\]/g, '').split('.');

    return newPath.reduce((a, b) => {
        return (a || {})[b]
    }, object) || defaultValue
}

//测试
const obj = {
    a: {
        b: [{
            c: 1
        }]
    }
}


console.log(get(obj, 'a.b[0].c[1].e[2][1].e', 0));
console.log(get(obj, 'a.b[0].c', 0));
console.log(get(obj, 'a.b.c', 0));
console.log(get(obj, 'a', 0));

14.实现一个const

function _const(key, value) {
    const desc = {
        value,
        writable:false
    };

    Object.defineProperty(window, key, desc);

}

_const('obj', {a: 1});   //定义obj
obj.b = 2;               //可以正常给obj的属性赋值
obj = {}                //抛出错误,提示对象read-only

15.1万张图片,并发下载10张,最快的方法下载完成

const data = [
  {
    url: '/a',
    time: 200
  },
  {
    url: '/b',
    time: 1000
  },
  {
    url: '/c',
    time: 100
  },
  {
    url: '/d',
    time: 800
  },
  {
    url: '/e',
    time: 300
  },
]

const loadUrl = (item) => {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, item.time, item.url);
  });
}

const downLoad = (data, limit) => {
  // 截取前 limit 个数据, 
  const promiseList = data.splice(0, limit).map((item, index) => {
    return loadUrl(item).then((res) => {
      console.log(res);
      return index;
    });
  });

  (async () => {
    let p = Promise.race(promiseList);
    for(let i = 0; i < data.length; i++) {
      p = p.then(index => {
        promiseList[index] = loadUrl(data[i]).then((res) => {
          console.log(res);
          return index;
        });
        return Promise.race(promiseList);
      })
    }
  })()
}

downLoad(data, 2);

搞了个公 众 号*********,感兴趣的可以关注一下~

#面经#
全部评论
太强了
点赞 回复 分享
发布于 昨天 22:16 湖北

相关推荐

评论
点赞
13
分享

创作者周榜

更多
牛客网
牛客企业服务