ArturoYi
面试

Flutter面试题2

高频面试题 1
渲染管线、引擎线程、Channel、卡顿、混合栈与启动体积。

和 高频面试题 1 重叠的概念,这里只写引擎 / 工程视角。

一帧怎么上屏

  • 三棵树: Widget 是配置,Element 是实例,RenderObject 做布局和绘制指令。
  • 一帧: build → layout → paint(只记指令)→ composite → raster 上屏。
  • 和原生差别: Flutter 默认自绘。PlatformView 是例外。
布局 / 绘制合成 / GPU
对应DevTools UI 条Raster 条
贵在树深、build 范围大saveLayer、大图、离屏
面试点:Widget → Element → RenderObject → Layer → GPU。paint 不等于已经上屏。

vsync 和 SchedulerBinding

  • vsync: 对齐刷新。60Hz 约 16.6ms,超时掉帧。
  • 调度: 动画用 Ticker;画帧走 drawFrame;量尺寸用 addPostFrameCallback。
  • 别用 Timer 做动画: 对不齐刷新。跟的是屏,类似 CADisplayLink / Choreographer。
面试点:不要在 build 里量 size,用 LayoutBuilder 或帧后再读。

UI Isolate 和引擎线程

  • UI Isolate: Widget、setState、业务、Channel 的 Dart 回调
  • Platform: Activity / AppDelegate、plugin
  • IO: 网络、部分解码
  • Raster: Layer → 像素(旧称 GPU 线程)

Isolate.run 是再开一个 Dart 堆,不是 Raster。DevTools:UI 条长查 Dart,Raster 条长查绘制。

面试点:卡 UI 和卡 GPU 不是同一根条。

三种 Channel

MethodChannelEventChannelBasicMessageChannel
语义一次问一次答持续推流双向消息
典型支付、权限传感器自定义协议

Pigeon 不是第四种通道,只是给 Method 这类 RPC 生成类型。大图传路径或纹理 id,别传像素。

面试点:先选语义,再说 codec。都要过主线程和序列化。

卡顿怎么分层

先看 DevTools 的 UI 条和 Raster 条,没分层不谈优化。

  • UI 长: setState 太高、列表没 builder、layout 太深、Intrinsic*
  • Raster 长: Opacity、裁剪、阴影、saveLayer、超大图
  • RepaintBoundary: 重绘确实局部才加,不是万能的
面试点:profile 下看。FPS 是平均数,jank 是单帧超没超预算。

热重载保什么

定义见 高频面试题 1。这里只记状态。

  • 能保: 改 build、改方法体。runtimeType + Key 对得上就复用 State。
  • 保不住: initState / main / static、类型变化、原生代码。
  • 改了没变: 先怀疑旧 State,不是框架坏了。
热重载热重启
状态尽量保 Element / State清空,重跑 main()
何时UI、方法体入口、类型、全局
面试点:initState 不重走,改初始化必须热重启。

PlatformView

原生视图嵌进 Flutter,合成更贵。WebView、地图、播放器才值得嵌。

  • 页面级(FlutterBoost):整页是 Flutter 还是原生
  • 组件级(PlatformView):一页里嵌一块
  • 坑: 手势、圆角、透明 → 花屏、穿透
能用 Flutter 画的就不要嵌。别把混合栈和 PlatformView 说成一件事。

启动慢、包体积大

两条线,别混。

  • 启动: 先问慢在闪屏、首帧,还是首屏数据。别等网络才 runApp。
  • 体积: 先问是 debug 还是 release、几个 ABI。只比 release。
启动体积
先砍过早初始化、首屏等网络多 ABI、原图、全量字体、符号
面试点:冷 / 热启动分开说。Debug 包不进对比。
Copyright © 2026