抖音前端一面面经

概括

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

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

抖音一面面经

  1. Taro升级
  2. 为什么要升级,两个技术版本的本质区别
  3. 升级遇到了什么问题
  4. 升级如何记录新框架的异常情况,如果自己实现一个监控系统,要怎么做
  5. 多端方案的区别和优劣势
  6. hybird架构里面h5与原生通信的手段
  7. 常见的优化手段中容器端的优化策略
  8. http123的区别
  9. 实现一个订阅发布者函数
  10. 数组转树
  11. lc198原题

项目

1.背景,升级过程(用了什么工具、原理是什么)

taro1兼容性比较差,公司业务需求需要拓展多平台。使用了jscodeshift进行代码自动化重构,其原理是将 JS/TS 代码解析为抽象语法树,并提供一系列用于访问和修改 AST 的 API 以实现自动化的代码重构。通过正则识别匹配抽象语法树的节点,将一些导入规则、配置项给替换、移除等。

jscodeshift

2.为什么要升级,两个技术版本的本质区别

Taro 1/2 属于编译型架构,主要通过对类 React 代码进行语法编译转换地方式,得到各个端可以运行的代码,再配合非常轻量的运行时适配,以及根据标准组件库、API 进行差异抹平,从而实现多端适配的目的。Taro 3 可以大致理解为运行时或解释型架构,主要通过在小程序端模拟实现 DOM、BOM API 来让前端框架直接运行在小程序环境中,从而达到小程序和 H5 统一的目的。

3.升级遇到了什么问题

新框架兼容性较好,没遇到什么大的问题,主要一些流程规范性问题,比如新技术升级要循序渐进,先在个别渠道进行升级,做好边界处理,测试没问题再逐步开量推广。

4.升级如何记录新框架的异常情况,如果自己实现一个监控系统,要怎么做

基于ams的监控体系。如果自己实现一个监控系统,可以注重关注用户行为、页面性能、稳定性等几方面,且数据上报的时候要注意进行数据脱敏,有一些数据比如具体接口数据等,可以根据业务情况避免前后端重复上报。

八股

5.多端方案的区别和优劣势

  • 原生app方案:开发成本高
  • 自研渲染引擎的fluter方案: 开发成本较高,国内生态一般
  • rn方案:依赖原生控件,通过js桥接,可能有性能损耗
  • hybird架构:开发成本最低,基于WebView容器加载H5页面,通过桥接调用原生功能,但是渲染效率低,弱网环境体验差

6.hybird架构里面h5与原生通信的手段

native调用js:

  • 通过webview的loadUrl
  • 通过webview的evaluateJavascript

js调用native

  • 通过webview的addjavascriptInterface注入api, 进行对象映射
  • shouldOverrideUrlLoding方法拦截特定的协议调用
  • 弹窗拦截
  • 桥接,通过windows对象,基于发布订阅模式进行各种监听回调

7.常见的优化手段中容器端的优化策略

  • 预热容器:提前准备下一个页面的容器
  • 容器复用
  • 容器层级做网络请求拦截和缓存

8.http123的区别

  • 0.9 只有 GET 命令,没有 HEADER 等描述数据的信息
  • 1.0 增加了很多命令,如 POST、PUT 等,增加了状态码和 HEADER 相关信息,增加了缓存
  • 1.1 持久连接,增加了 pipeline,可以在同一个 TCP 连接里面发送多个 http 请求,但是串行的,增加了头部 host。
  • 2.0 头部信息压缩、多路复用、二进制分帧、主动推送,但是还是存在tcp队头阻塞
  • 3.0 基于udp,增加quic流帧的概念,解决tcp阻塞的痛点

算法

9.实现一个订阅发布者函数

class EventEmitter {
    constructor() {
        this.events = {};
    }

    // 订阅事件
    on(event, listener) {
        if (!this.events[event]) {
            this.events[event] = [];
        }
        this.events[event].push(listener);
    }

    // 取消订阅事件
    off(event, listener) {
        if (!this.events[event]) return;
        this.events[event] = this.events[event].filter(l => l !== listener);
    }

    // 触发事件
    trigger(event, ...args) {
        if (!this.events[event]) return;
        this.events[event].forEach(listener => listener(...args));
    }

    // 订阅一次事件,触发后自动取消订阅
    once(event, listener) {
        const onceListener = (...args) => {
            listener(...args);
            this.off(event, onceListener);
        };
        this.on(event, onceListener);
    }
}

// 使用示例
const emitter = new EventEmitter();

// 订阅事件
emitter.on('hello', (name) => {
    console.log(`Hello, ${name}!`);
});

// 订阅一次事件
emitter.once('goodbye', (name) => {
    console.log(`Goodbye, ${name}. You will not see this message again.`);
});

// 触发事件
emitter.trigger('hello', 'Alice'); // 输出: Hello, Alice!
emitter.trigger('hello', 'Bob');   // 输出: Hello, Bob!

emitter.trigger('goodbye', 'Charlie'); // 输出: Goodbye, Charlie. You will not see this message again.
emitter.trigger('goodbye', 'David');   // 不会输出任何内容

10.数组转树

function arrayToTreeV3(list, root) {
  return list
    .filter(item => item.parent_id === root)
    .map(item => ({ ...item, children: arrayToTreeV3(list, item.id) }))
}
const arr = [
  { "id": 12, "parentId": 1, "name": "朝阳区" },
  { "id": 241, "parentId": 24, "name": "田林街道" },
  { "id": 31, "parentId": 3, "name": "广州市" },
  { "id": 13, "parentId": 1, "name": "昌平区" },
  { "id": 2421, "parentId": 242, "name": "上海科技绿洲" },
  { "id": 21, "parentId": 2, "name": "静安区" },
  { "id": 242, "parentId": 24, "name": "漕河泾街道" },
  { "id": 22, "parentId": 2, "name": "黄浦区" },
  { "id": 11, "parentId": 1, "name": "顺义区" },
  { "id": 2, "parentId": 0, "name": "上海市" },
  { "id": 24, "parentId": 2, "name": "徐汇区" },
  { "id": 1, "parentId": 0, "name": "北京市" },
  { "id": 2422, "parentId": 242, "name": "漕河泾开发区" },
  { "id": 32, "parentId": 3, "name": "深圳市" },
  { "id": 33, "parentId": 3, "name": "东莞市" },
  { "id": 3, "parentId": 0, "name": "广东省" }
];
// 调用
arrayToTree(arr, 0);

11.lc198原题

搞了个公主号,感兴趣的可以关注一下~《FE前端指南》

#字节##腾讯##前端面经##面经#
全部评论
搜不到微信呀
1 回复 分享
发布于 03-15 21:20 湖北

相关推荐

部门是社区工程部-社区技术项目&自我介绍 略八股:Ref 和reactive的区别,什么场景下用reactive比较好什么时候用Ref 和reactive, 什么情况下用父子传值比如props, emits;用户数据应该怎么传值CSS怎么进行水平居中?为什么left之后还要margin-left微调?行内文本比如text怎么进行垂直居中(line-height父子一致高度)怎么对图片进行旋转45度(transform: rotate(45deg))首屏加载时 图片后加载会有一个跳现的问题,怎么解决=》骨架屏占位骨架屏占位时,图片大小不一,移动端怎么知道这个图片多大=〉固定比例,锁定比例和宽高了解互动渲染相关吗(不了解,那就不问了)手撕:防抖已知敌人坐标数组,发射中心数组,发射范围,最多攻击人数,写一个函数 输出被攻击的人的坐标反问:有什么建议:挺好的,可以去了解一下互动渲染相关组的技术栈:vue3( h5) + rn + Lottie + Canvas 2D + Babylon.js(3d)组是做什么的:主要做小红书的宠物小伙伴小游戏,还有一些社区相关的比如感想:社区工程相关似乎都喜欢问CSS和性能相关,毕竟业务跟这方面关系很大。面试官非常温暖,一直在说“自家人,不用紧张”。认识我的前mentor和同事们,看到简历就知道我之前是在哪个组实习了(虽然我没有写出来)。中途面试间时间到了我被赶出来重新找面试间,也没有生气。体验最好的一集
查看8道真题和解析
点赞 评论 收藏
分享
评论
4
25
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务