字节跳动flutter面试题 (字节跳动和阿里怎么选)

2018 年 12 月 ,Google 宣布 Flutter 1.0 版本正式发布。截至目前, Flutter 在 Github 上已获得 88000+ 的关注和 11000+ 的 Fork ,其发展速度相当惊人,是今年移动端最火热的开发框架之一。

Flutter 大火背后的原因是什么?为什么越来越多的企业和开发者会选择使用 Flutter?Flutter 会成为跨平台开发的终极之选吗?

近日,InfoQ 有幸采访到字节跳动移动平台部 Flutter 架构师、知名博客 Gityuan 博主袁辉辉,他针对上述问题作了回应。他表示“ Flutter 并非跨平台终极之选,最初选择 Flutter,不是因为它一定会成为未来终极之选,而是因为它有可能成为不一样的未来。”此外,他还会在即将召开的 QCon 全球软件开发大会 2020(北京站)上分享《字节跳动 Flutter 大规模业务落地与架构优化实战》,感兴趣的读者可以关注。

以下为袁辉辉的采访内容整理。

Flutter 大火的原因

有人说 Flutter 大火主要原因是它选择了 Dart 语言,Dart 有着高性能的表现和可快速分配内存的能力,能同时支持 JIT 和 AOT 模式,允许在带类型的语言中支持形变和有状态热重载,能编译出高效率的 ARM 机器码指令,Dart 作为面向对象的语言也能让绝大多数开发者更快速上手。我认可 Dart 语言有一定的优势,但这样的优势并非 Dart 独有,我想这更不会是大家选择 Flutter 的核心原因,这是因果倒置。事实上,Dart 是 2011 年推出的,在 Flutter 出现之前,Dart 曾一度几乎被人遗忘。正是因为近年来 Flutter 的火爆,才让 Dart 重新进入大众的视线。Flutter 当初选择 Dart,或者仅因为 Google 的 Flutter 和 Dart 这两个团队离得比较近,交流比较方便。

我认为 Flutter 之所以大火,主要是以下几个原因:

一、现有跨平台技术存在缺陷

在移动互联网时代,Android 和 iOS 两大阵营长期共存,再加上体系成熟的 Web 前端技术,导致出现同一个应用需多端重复开发的人力成本问题。正因如此,移动时代下的跨平台技术是一个需要长期研究的课题。如果当下的跨平台技术已经有比较完美的解决方案,可能就没有新技术萌芽的机会。而事实上,目前业界比较成熟的跨平台技术都存在一定的缺陷,比如小程序(WebView)渲染耗时过长,白屏率会影响转化收益,能实现的功能非常受限;再比如 React Native 的性能不足、问题排除难、维护成本高等。而 Flutter 的出现,让这些跨平台开发问题有所改善,它还是 Google 开源的技术,自身也具备一定的热度。另外,一直备受关注且神秘的 Fuchsia 系统在 UI 框架上使用的也是 Flutter,可作为长期战略投入,这也增强了大家对 Flutter 的信心。

二、研发效率就是竞争力

移动互联网进入下半场,出现字节跳动等新巨头,在没有历史包袱的情况下,更愿意尝试技术上限更高的新技术。从校招和社招的难度上不难发现:客户端的人才相比之前更为稀缺,尤其是 iOS 工程师。而下半场会有更多竞争和更为激烈的赛道,比如教育等方向。Flutter 本身非常适合从零开始的没有历史包袱的应用开发,对于新业务尤其是在团队人力紧缺的情况下,在技术选型上考虑 Flutter,能加快产品在多端落地、快速试错。

三、集漂亮与流畅集于一身

Flutter “一出生”就以“UI 漂亮、像素级可控、性能流畅、可媲美原生性能”等特点吸引广大开发者的眼球,自渲染引擎甚至具备开发游戏的能力。移动下半场,没有人口红利,竞争更为激烈,如何能更好地满足用户对高品质、高流畅的需求,便是移动端一种强有力的竞争力。跨平台技术想要拥有更高的流畅度,采用自渲染技术的方案便是更优解,也是一个更为彻底的跨平台技术方向。

字节跳动选择 Flutter 的初心

说到这里,先分享一下 Flutter 最初是如何诞生的故事。Flutter 创始人 Eric 之前在 Chrome 团队工作,期间遇到一些难以解决的问题, 希望 Web 中的一部分能够拥有更加平滑的体验, 为此他花了几周时间做了一个实验,不考虑 Web 的兼容方式,删除了大量为了兼容访问的代码和一些 Web 开发者不常用的功能, 删除到有不少 Web 元素的渲染已经不支持了,然后做了一个基准测试,得出结论是某些关注指标的速度快了 20 倍。于是,Eric 决定再做点什么,后面投入了大量研究和开发,便有了现在的 Flutter 。

听到这里给人的感觉是,对于 Web 工程师而言 Flutter 应该容易上手。我跟公司很多正在使用或者调研 Flutter 的业务团队做过沟通,发现客户端比前端的同学对 Flutter 接受度更高,我个人从 Android 端技术出身,的确觉得学习 Flutter 还是非常容易上手的,但公司内前端的同学对 Flutter 使用的吐槽会多一点。所以,我认为 Flutter 更像是以客户端视角的跨平台技术,Flutter 与其说是大前端技术,不如说是大移动端技术。Flutter 发展的 Roadmap 也是先全面支持 Android/iOS 端能力,再进一步完善 Web 端能力支持的。

字节跳动对于客户端技术还是非常重视的,外界也多有调侃“ APP 工厂”,字节跳动有很多客户端工程师,之前客户端深入点的基础技术更多是搞插件化、热修复、性能优化、安全加固等,跨平台方向一直都是前端工程师在不遗余力地推进,属于大前端方向。而 Flutter 是客户端更有主导的跨平台技术方案。另外说明,字节跳动并不是说只有一套跨平台技术栈,公司内部也是多套跨端技术栈并存,也包括自研的方案。

在字节跳动,跨平台技术并没有形成大规模的落地,之前也提到没有历史包袱,所以在面对跨平台技术选型的时候,更关注跨平台技术的技术上限以及发展潜力,自渲染技术的 Flutter 可以理解为更彻底更纯粹的跨平台技术,伴随着媲美原生的流畅度,这便是我们选择 Flutter 的初心。

Flutter 落地过程中的“坑”

截至目前,字节跳动有很多业务落地了 Flutter 技术方案,包括*今条头日**、西瓜视频、皮皮虾等 20 多个业务在使用 Flutter 开发,有纯 Flutter 工程,也有 Flutter 与 Native 的混合工程。如果大家想要了解更多业务落地情况,后续我会在今年的 QCon 北京 2020 大会上分享。

Flutter 虽潜力上限很高,但仍需打磨和雕琢,我们在 Flutter 推动过程中遇到很多问题,比如包体积过大的问题、性能达不到预期、对混合工程的支持不够友好、各宿主 Flutter 引擎版本不一致、基础库不完善、Flutter 改造后各项数据打平等。除此之外,还有很多非技术的困难,比如业务团队并不认可 Flutter 新技术,工程师缺乏 Flutter 经验,担忧审核风险等,都会影响业务方是否采用 Flutter 技术,每一个困难都需要去解决,不然就难以落地。下面就其中两个难点,我来展开聊一下。

一、包体积问题

字节跳动内的大型 APP,比如*今条头日**、抖音等对包体积的增量非常敏感,Flutter 的包体积涉及两个部分,一个是一次性 Flutter 引擎的包体积问题,一个是每次写 Dart 代码比写 OC 代码代码增量的问题。这两个问题对我们来说都非常棘手,我们成立了包体积优化专项进行全力攻坚,同时跟 Google 工程师多次会议沟通,不断精简包体积。最终我们通过一系列优化手段,包含 Data 压缩、编译优化、Skia 裁剪、BoringSSL/ICU 库 / 文字渲染 /libwebp 等库裁剪取得了不少的效果;通过实践我们发现用 OC 代码和 Dart 代码写相同的业务逻辑,Dart 生成的机器码指令比 OC 多,主要在生成的二进制指令头、指令冗余、指令对齐的精简,以及 StackMap 和 CodeSourceMap 的精简等方面。同时我们也向 Google 反馈了这些情况。关于指令精简,可以查看 Issue 进展 https://github.com/flutter/flutter/issues/40345 ,里面有记录详细的推进过程。

二、性能优化问题

这是我们遇到的棘手问题之一,我们用 Flutter 官方提供的性能分析工具 Timeline 来分析一个比较诡异的性能问题,始终无法发现任何异常。困扰已久,后来干脆重新撸了一遍 Timeline 整个性能分析工具的源码,最终找到了其缺陷,并向 Flutter 社区提及,合入了 10 个 PR ,基于此让我有幸成为了 Flutter Member ,后续会持续向社区贡献更多力量。

https://github.com/flutter/flutter/issues/47771

Flutter 是一个自渲染的跨平台技术,有着很高的性能上限,但并不代表现在性能各方面都很优秀,毕竟 Flutter 作为一个“新生儿”,还是有一些需要进一步改造的地方。除性能工具改造之外,其实在 Flutter 落地场景中,我们也解决了不少性能问题,同时优化了自身的引擎,比如 UI 预加载策略、Flutter Turbo 技术、Vsync 调度策略等,让引擎提速,争取让 Flutter 性能发挥到极致。

Flutter 在业务层面的发展阻力

引入 Flutter 之后,在公司的业务也创造了不少价值。主要体现在这几个方面:其一,Flutter 多端一致性上表现良好,能做到所见即所得,无需针对某一平台做额外适配工作;其二,热重载技术使得设计团队和工程团队可以非常快速的修改和调试 UI,设计师只需要关注一个平台实现,UI 验收效率明显提高,跨端开发可以提高工程师的人效(有团队初步估算人效大致提升了 1.8 倍);其三,性能流畅度提升,相较于 H5 版本首屏时间有较大提升,最后,产品商业化数据都有明显的收益,能直观地看到 Flutter 给公司带来的创收。

不过,现阶段 Flutter 的发展仍有一些阻力:

一、Flutter 采用的是 Dart 语言,没能引入前端成熟的生态体系

作为前端工程师可能更希望是 Flutter 上层采用的是 JavaScript 或者 TypeScript,未来可考虑提供高性能的 Dart 与 JS 互转能力。另外,Flutter 开发对于前端开发工程师而言,还是有一些挑战的,纯前端不一定能 Cover 的技术,比如 Flutter 的一个硬件相关的 Plugin 只在某款手机出现 Bug,如果社区没有现存解决方案,可能就需要花比较大的时间成本去学习 Native 技术,或者请教客户端工程师。

二、开源库相对比较欠缺,更新频次不足

Flutter 生态还不够完善,新业务接入需要自己造轮子,尤其是在业务团队对 Flutter 掌握不够熟练的情况下,会增加额外的成本,Flutter 在大中型企业会更容易推广起来,有人力可以去造轮子让公司内其他的业务复用;另外,Flutter 文档有点少,能借鉴的经验不多,未来需加强和鼓励更多开发者加入到生态共建。

三、跟原生系统生态存在着一定的竞争关系

有朋友跟我说起过这样一件事,看到 Flutter 这么火,Android 开发团队就问他,“大家为什么要用 Flutter 开发 App,我们 Android 哪一点不好,告诉我们,我们可以改进它”。姑且不说他们对跨平台理解不够,但至少能看出原生平台对跨端技术的担忧,不少 Android 团队在推出 Kotlin Multiplatform ,希望能争夺更多市场。

另外,苹果商店的审核风险也是大家所担忧的,官方的公告原意是说应用程序的核心特性和功能必须包含在软件的二进制文件中,而不是通过类似 HTML5 的技术来实现动态更新,苹果要*压打**的是动态更新技术,考虑到 Flutter 的合规性,Google 主动把 Flutter 的 iOS 动态化能力去掉了,Flutter 最终打包生成的产物就是 IPA,Flutter 其实是完全符合规范的,甚至还有使用 Flutter 开发的应用还被 Apple 推荐过。相反,React Native、Weex、H5 等技术都是一种动态化解决方案,这正是苹果要管控的,目前苹果的态度更多的是不提倡,但也不保证不封杀。即便如此,苹果不希望原生开发生态被其他跨平台技术抢占,苹果也在不断推行 SwiftUI 框架,力图抵挡 Flutter 等跨平台技术对原生开发的餐食。Flutter 未来要加强推进步伐,让更多的大型 App 通过 Flutter 技术得到收益,只有用户群体上来,未来的地位和话语权才会更高,就像现在小程序,原则上是不符合苹果的审核要求的,但各大型应用基本都上线了小程序功能,目前来看不至于说苹果把小程序直接干掉。

Flutter 并非跨平台终极之选

从 Hybrid App 到 React Native,再到 Flutter,跨平台技术层出不穷。目前来看,Flutter 是跨平台开发的最热门技术,但我并不认为 Flutter 就一定是跨平台开发的终极之选,它有着历史局限性,我只能说 Flutter 可能是当下最有潜力的跨平台技术。如果你对性能流畅度有高要求,或者有多个产品希望快速在多端试错迭代,我会推荐你尝试 Flutter。

未来一段时间,还应该是多套跨平台技术并存的时代, 目前 Flutter 也没有全面做到可以碾压其他跨平台技术,可根据团队以及业务特点来考虑更适合的方案。 有一定客户端经验的同学入手 Flutter 会更快一些,如果团队在 React Native 上有很好落地,业务没有遇到性能等瓶颈,且团队缺少客户端能力,建议先做技术调研和沉淀,不要盲目追求新技术,只有当团队有能力且业务有需求的情况下,建议再考虑切换技术栈。

我们前面提到过,一直备受关注且神秘的 Fuchsia 系统在 UI 框架上使用的也是 Flutter。Fuchsia 是 Google 开发的下一代操作系统。Fuchsia 是采用全新模块化设计思想、跨平台框架技术的系统。它能支持快捷裁剪定制,更能适应未来的多元化设备,包含手机、平板、笔记本、路由器、智能设备、机器人等,Fuchsia 有可能成为一个全新的跨全平台的通用操作系统。

在现阶段,开始尝试探索和积累沉淀 Flutter 技术能力,并在业务上使用 Flutter 技术的应用,从战略上来将已经处于领先。选择 Flutter,正可谓是“进可攻退可守”,往前进一步,Flutter 应用未来可无缝迁移到 Fuchsia 系统,借用 Fuchsia 系统的能量扩展到更广泛的用户场景;退一步,Flutter 技术自身在 Android/iOS 平台的表现相比其他跨平台技术已经是很优秀。

最初选择 Flutter,不是因为它一定会成为未来终极之选,而是它有可能成为不一样的未来。

Flutter 展望:终将走向多端一体化

回顾整移动操作系统的演变历程,从塞班功能机到 Android/iOS 智能机,从小屏手机到全面屏、刘海屏、水滴屏。任何系统的演变最终体现在输入和输出两个环节,接收到输入信号后经过操作系统处理后输出信息给用户。从按键式交互到触屏式交互,伴随着塞班系统到 Android 系统的转变,未来的交互方式一定会更加生物智能化,当下的触屏交互可以理解成人类的触觉输入方式,未来将朝着人们更常见的听觉(语音)输入和视觉(身体姿势、表情等)输入,甚至嗅觉(气味变化)输入,这些都会伴随着新的操作系统而诞生。屏幕从小尺寸到大尺寸,并没有引发操作系统变革,因为技术创新是非连续性,非连续性才会引发第二曲线,诞生新技术。从 1960 年大型机,到 1990 年个人笔记本,再到现在的智能手机,设备本身越来越小。未来的设备如果发展非连续变革,可能不再需要实体硬件,随处可输出,一张白纸、一面墙,到那时操作系统的 UI 架构必然会有全新的变化。

随着科技的发展,5G 时代的到来,人工智能的日趋成熟,端到底会有哪些变化?是否会出现新的操作系统?系统的 UI 架构是否会出现新的变革?Android/iOS 平台是否能与之并存?搭载 Flutter UI 框架的 Fuchsia 系统能否在 IOT 领域以及新的交互方式大放异彩,再领风骚?是否有万物互联互通的超级平台出现?

技术在不断演变中螺旋前进,平台自身也随之演进,未来 Flutter 会朝着多端一体化的方向发展,能支持更多的端(包括平板、笔记本、智能设备等)。作为一套跨平台的 UI 框架,Flutter 采用自渲染的技术方案,是一个上限很高的跨平台技术,但 Flutter 更重要的是需要提升工程化能力以及生态圈的建设,才能吸引更多的开发者加入。

采访嘉宾介绍:

袁辉辉,就职于字节跳动,在移动平台部担任 Flutter 架构师,主要负责 Flutter 性能架构。曾在小米、联想、IBM 任职,从事 Android 系统框架底层优化与开发工作。他是知名博客 Gityuan 的博主,对 Android/Flutter 有着深刻的理解,编写了近 200 篇高质量相关原创技术文章。