Android 开发高频面试题之——Flutter
Android开发高频面试题之——Java基础篇
flutter高频面试题记录
- Flutter
- 1. dart中的作用域与了解吗
- 2. dart中. .. ...分别是什么意思?
- 3. Dart 是不是单线程模型?如何运行的?
- 4. Dart既然是单线程模型支持多线程吗?
- 5. Future是什么
- 6. Stream是什么
- 7. Flutter 如何和原生交互
- 8. 说一下 mixin?
- 9. StatefulWidget 的生命周期
- 10. main()和runApp()函数在flutter的作用分别是什么?有什么关系吗?
- 11. 怎么理解Isolate?
- 12. 简单介绍下Flutter框架,以及它的优缺点?
- 12. 简述Widgets、RenderObjects 和 Elements的关系
- 13. 介绍下Widget、State、Context 概念
- 14. 简述Widget的StatelessWidget和StatefulWidget两种状态组件类
- 15. 什么是状态管理,你了解哪些状态管理框架?
- 16. 简述Flutter的绘制流程
- 17. await for 如何使用?
- 18. 介绍下Flutter的架构
- 19. 介绍下Flutter的FrameWork层和Engine层,以及它们的作用
- 20. Dart中var与dynamic的区别
- 21. const关键字与final关键字的区别
- 22. Flutter在Debug和Release下分别使用什么编译模式,有什么区别?
- 23. 什么是Key?
- 24. future 和steam有什么不一样?
- 25. 什么是widget? 在flutter里有几种类型的widget?
- 26. statefulWidget更新流程了解吗
- 了解哪些状态管理框架
- flutter 原生组件StateFulWidget
- provider
- GetX
- 如何获取app的生命周期
- flutter性能优化
- 使用局部刷新(如:拆分widget,缩小刷新影响范围)
- 减少不必要的build/setState
- 优化ClipPath和ClipRPath
- 能不用Opacity Widget,就尽量不要用
- 多变图层与不变图层分离
- 使用const来修饰永远不需要变更的控件。
- 优先使用StateLessWidget,而不是全部用StateFulWidget
- 使用Visibility控件替换if/else
- ListView 优化
- 卡顿原因
- 优化方案
- 长列表懒加载场景
- 首次进入加载多个item场景
- 取消在途网络请求
- 首页预加载
- 分页预加载
Flutter
1. dart中的作用域与了解吗
默认是public,如需私有只需要在变量名或者方法名前加_
例如
var user = "小王"; //是public
var _user= "小王"; //是private
2. dart中. … …分别是什么意思?
一个点 .
是正常的对象访问
两个点 . .
意思是 「级联操作符」,为了方便配置而使用。「…」和「.」不同的是 调用「…」后返回的相当于是 this, 可以实现对一个对象的连续调用
Paint()..color = thumbColor..style = PaintingStyle.stroke..strokeCap = StrokeCap.round..strokeWidth = tempWidth);
三个点 … 用来拼接集合,如List,Map等
class TestDemo { TestDemo() { var list2 = ['d', 'e', 'f'];var list = ['a', 'b', 'c', ...list2];// 打印结果:// 这里组合后 list就变成[ 'a', 'b', 'c','d', 'e', 'f']var map2 = {'a': 'a', 'b': 'b'};var map = {...map2, 'c': 'c', 'd': 'd'};// 打印结果:// 这里组合后map就变成{'a': 'a', 'b': 'b','c': 'c', 'd': 'd'}}
}
3. Dart 是不是单线程模型?如何运行的?
Dart是单线程模型
Dart在单线程中是以消息循环机制来运行的,其中包含两个任务队列,一个是 “微任务队列” microtask queue,另一个叫做 “事件队列” event queue。微任务队列的执行优先级高于 事件队列。
Dart大致运行原理:先开启app执行入口函数main(),执行完成之后,消息机制启动,先是会按照先进先出的顺序逐个执行微任务队列中的任务microtask,事件任务eventtask 执行完毕后便会退出,但是,在事件任务执行的过程中也可以插入新的微任务和事件任务,在这种情况下,整个线程的执行过程便是一直在循环,不会退出,而Flutter中,主线程的执行过程正是如此,永不终止。
在事件循环中,当某个任务发生异常并没有被捕获时,程序并不会退出,而直接导致的结果是当前任务的后续代码就不会被执行了,也就是说一个任务中的异常是不会影响其它任务执行的。
Dart 中事件的执行顺序:Main > MicroTask > EventQueue
- 通常使用 scheduleMicrotask(…) 或者 Future.microtask(…) 方法向微任务队列插入一个任务。
- 通常使用 Future 向 EventQueue加入事件,也可以使用 async 和 await 向 EventQueue 加入事件。
4. Dart既然是单线程模型支持多线程吗?
多线程语言如Java实现异步的方式是将耗时操作新开子线程去执行。Dart是单线程模型,没有多线程的概念,他是通过Future和Stream来实现异步的。
5. Future是什么
Future是异步函数,它可以在不阻塞当前任务的情况下执行一个任务,并在任务完成后获得相应的结果。
Future实际上是将其中的事件放入到了Event Queue事件队列中执行。
常与async一起使用
Async是Dart中的一个关键字,用于标记异步函数。async函数返回一个Future对象,并且可以使用await关键字来等待函数的执行结果。例如:
Future<String> getData(String url) async {
var response = await http.get(url);
return response.body;
}
6. Stream是什么
Stream 流是一个异步的事件队列。分为单订阅流和广播订阅
- 单订阅流
默认情况下创建的流都是单订阅流,单订阅流只能被订阅一次,第二次监听会报错!监听开始之前的元素不会被订阅。但 Stream 可以通过 transform() 方法(返回另一个 Stream)进行连续调用。通过 Stream.asBroadcastStream() 可以将一个单订阅模式的 Stream 转换成一个多订阅模式的 Stream.isBroadcast 属性可以判断当前 Stream 所处的模式。 - 广播订阅
广播流允许存在任意数量的 listener,并且无论是否存在 listener,它都能产生事件,所以中途加入的 listener 不会侦听到已发生的事件。
单订阅流常用于数据的传递,广播流用于事件的分发。
StreamController 是流控制器的核心接口,包含了流控制器该有的大多数接口方法。其中
- stream 用于向外提供创建的Stream。
- sink 是该控制器关联的流的数据来源。可以使用sink.add 方法向流中添加数据。
- onListen, 当控制器中的流被监听的时候,会回调该方法。
- onPause, 当流的监听主动暂停的时候,会回调该方法。
- onResume, 当流的监听主动恢复监听的时候,会回调该方法。
- onCancel,当流的监听取消监听的时候,会回调该方法。
7. Flutter 如何和原生交互
Flutter 与原生交互使用Platform Channel。Flutter定义了三种不同类型的Channel
- BasicMessageChannel 用于传递字符串和半结构化的信息,可持续通信,收到消息后可以回复此次消息。场景:消息互发(双向有返回值,可持续通信)
- MethodChannel 用于传递方法调用。场景:native与flutter的方法调用(双向有返回值,一次性通信)
- EventChannel 用于事件型的通信,仅支持 native 到 Flutter 的单向传递。场景:通常用于状态端监听,比如网络变化、传感器数据、电量更新或声音改变(仅支持数据单向传递,无返回值)
8. 说一下 mixin?
- mixin 可以理解为对类的一种“增强”,但它与单继承兼容,因为它的继承关系是线性的。
- with 后面的类会覆盖前面的类的同名方法
- 当我们想要在不共享相同类层次结构的多个类之间共享行为时,可以使用 mixin
- on限定了使用mixin组块的宿主必须要继承于某个特定的类;在mixin中可以访问到该特定类的成员和方法。
- 作为mixin的类不能有自定义构造方法
9. StatefulWidget 的生命周期
- initState 初始化阶段回调
- didUpdateWidget build阶段回调 当Widget配置发生变化时,比如父Widget触发重建(即父Widget的状态发生变化时),热重载,系统会调用这个函数。
- didChangeDependencies build阶段回调 state对象依赖关系发生变化后,flutter会进行回调。
- deactivate 不可见时回调
- dispose 销毁时回调
10. main()和runApp()函数在flutter的作用分别是什么?有什么关系吗?
main函数是程序执行的入口。
runApp是Flutter应用启动的入口。runApp中启动了Flutter FrameWork并且完成根widget树的渲染
在runApp中 初始化了WidgetsFlutterBinding这个类混入了七个BindingBase子类。同时调用WidgetsFlutterBinding 将Flutter Framework绑定到Flutter Engine上面
- GestureBinding:绑定手势系统。
- ServicesBinding:主要作用与defaultBinaryMessenger有关,用于和native通讯相关。
- SchedulerBinding:该类主要用于调度帧渲染相关事件。
- PaintingBinding:和painting库绑定,处理图片缓存。
- SemanticsBinding:将语义层和Flutter Engine绑定起来。
- RendererBinding:将渲染树与Flutter Engine绑定起来。
- WidgetsBinding:将Widget层与Flutter Engine绑定起来。
11. 怎么理解Isolate?
isolate 意思是隔离。它可以理解为 Dart 中的线程。isolate与线程的区别就是线程与线程之间是共享内存的,而 isolate 和 isolate 之间是不共享的。因此也不存在锁竞争问题,两个Isolate完全是两条独立的执行线,且每个Isolate都有自己的事件循环,它们之间只能通过发送消息通信,它的资源开销低于线程。
每个 isolate 都拥有自己的事件循环及队列(MicroTask 和 Event)。这意味着在一个 isolate 中运行的代码与另外一个 isolate 不存在任何关联。
isolate之间的通信
由于isolate之间没有共享内存,他们之间的通信唯一方式只能是通过Port进行,而且Dart中的消息传递总是异步的。
- 两个Isolate是通过两对Port对象通信,一对Port分别由用于接收消息的ReceivePort对象,和用于发送消息的SendPort对象构成。
- Flutter 中可以使用compute函数来创建Isolate
- compute中运行的函数,必须是顶级函数或者是static函数,
- compute传参,只能传递一个参数,返回值也只有一个
12. 简单介绍下Flutter框架,以及它的优缺点?
Flutter 是Google开发的一款跨平台方案的开源框架。
优点
- 高性能:自带绘制系统,让Flutter拥有原生级别的性能。
RN、Weex等跨平台开发框架,都选择将绘制任务交给了平台原生的绘制引擎。因此,这些框架在规避了重新开发一套图形机制的同时,也从底层机制上带来了无法调和的性能问题。 - 因为Flutter底层使用和Android原生一样的Skia引擎,所以保证了android和ios两端的UI一致性
- 拥有热更新机制,开发效率比原生更高
- Dart语言比较简单,而且Flutter语法与JectPack库中的Compose接近,容易上手。
缺点
- 生态还不够丰富
- 缺少动态性
12. 简述Widgets、RenderObjects 和 Elements的关系
- Widget :仅用于存储渲染所需要的信息。Widget只是配置信息,相当于Android里的XML布局文件
- RenderObject :负责管理布局、绘制等操作。保存了元素的大小,布局等信息.
- Element :是这颗巨大的控件树上的实体。通过 Widget 的 createElement() 方法,根据 Widget数据生成。如果 widget 有相同的 runtimeType 并且有相同的 key, Element 可以根据新的 widget 进行 update.
Widget会被inflate(填充)到Element,并由Element管理底层渲染树。Widget并不会直接管理状态及渲染,而是通过State这个对象来管理状态。Flutter创建Element的可见树,相对于Widget来说,是可变的,通常界面开发中,我们不用直接操作Element,而是由框架层实现内部逻辑。就如一个UI视图树中,可能包含有多个TextWidget(Widget被使用多次),但是放在内部视图树的视角,这些TextWidget都是填充到一个个独立的Element中。Element会持有renderObject和widget的实例。记住,Widget 只是一个配置,RenderObject 负责管理布局、绘制等操作。
在第一次创建 Widget 的时候,会对应创建一个 Element, 然后将该元素插入树中。如果之后 Widget 发生了变化,则将其与旧的 Widget 进行比较,并且相应地更新 Element。重要的是,Element 不会被重建,只是更新而已。
- 一个Widget一定对应一个Element,但是不一定会有RenderObject
- 只有当Widget被渲染显示出来时才会有RenderObject
13. 介绍下Widget、State、Context 概念
- Widget:在Flutter中,几乎所有东西都是Widget。将一个Widget想象为一个可视化的组件(或与应用可视化方面交互的组件),当你需要构建与布局直接或间接相关的任何内容时,你正在使用Widget。
- Widget树:Widget以树结构进行组织。包含其他Widget的widget被称为父Widget(或widget容器)。包含在父widget中的widget被称为子Widget。
- Context:仅仅是已创建的所有Widget树结构中的某个Widget的位置引用。简而言之,将context作为widget树的一部分,其中context所对应的widget被添加到此树中。一个context只从属于一个widget,它和widget一样是链接在一起的,并且会形成一个context树。
- State:定义了StatefulWidget实例的行为,它包含了用于”交互/干预“Widget信息的行为和布局。应用于State的任何更改都会强制重建Widget。
14. 简述Widget的StatelessWidget和StatefulWidget两种状态组件类
-
StatelessWidget: 一旦创建就不关心任何变化,在下次构建之前都不会改变。它们除了依赖于自身的配置信息(在父节点构建时提供)外不再依赖于任何其他信息。比如典型的Text、Row、Column、Container等,都是StatelessWidget。它的生命周期相当简单:初始化、通过build()渲染。
-
StatefulWidget: 在生命周期内,该类Widget所持有的数据可能会发生变化,这样的数据被称为State,这些拥有动态内部数据的Widget被称为StatefulWidget。比如复选框、Button等。State会与Context相关联,并且此关联是永久性的,State对象将永远不会改变其Context,即使可以在树结构周围移动,也仍将与该context相关联。当state与context关联时,state被视为已挂载。StatefulWidget由两部分组成,在初始化时必须要在createState()时初始化一个与之相关的State对象。<
相关文章:

Android 开发高频面试题之——Flutter
Android开发高频面试题之——Java基础篇 flutter高频面试题记录 Flutter1. dart中的作用域与了解吗2. dart中. .. ...分别是什么意思?3. Dart 是不是单线程模型?如何运行的?4. Dart既然是单线程模型支持多线程吗?5. Future是什么6. Stream是什么7. Flutter 如何和原生交互…...

视频单目标跟踪研究
由于对视频单目标跟踪并不是很熟悉,所以首先得对该领域有个大致的了解。 视频目标跟踪是计算机视觉领域重要的基础性研究问题之一,是指在视频序列第一帧指定目标 后,在后续帧持续跟踪目标,即利用边界框(通常用矩形框表…...

若依vue3.0表格的增删改查文件封装
一、因若依生成的文件没进行封装,维护起来比较麻烦。所以自己简单的进行封装了一下 gitee代码(文件)地址:https://gitee.com/liu_yu_ting09/ruo_yi.git 二、封装的方法(下面绿色按钮进行全局封装一个JeecgListMixin.js…...

【已解决】如何使用JAVA 语言实现二分查找-二分搜索折半查找【算法】手把手学会二分查找【数据结构与算法】
文章目录 前言任务描述编程要求 输出样例:未查找到11元素! 二、代码实现总结理解不了考试的时候直接背下来就好了。 前言 [TOC]二分搜索 任务描述 折半查找(二分搜索) 设a[low..high]是当前的查找区间,首先确定该区间的中点位置…...

ERROR 1524 (HY000): Plugin ‘mysql_native_password‘ is not loaded
你遇到的错误是由于 MySQL 版本不再默认支持 mysql_native_password 认证插件导致的。从 MySQL 8.0 开始,默认的认证插件是 caching_sha2_password,而不是 mysql_native_password。 解释: 错误 ERROR 1524 (HY000): Plugin mysql_native_pa…...

.NET 6.0 WebAPI 使用JWT生成Token的验证授权
1.引入相关程序包JwtBearer注意版本: 2.配置文件appsettings.json写相关配置参数(也可不写,写在程序里面,数据库读取也是一样的) , //JWT加密"JWTToken": {"SecretKey": "jsaduwqe6asdjewejdue7dfmsdfu0sdfmwmsd8wfsd6",…...

M9410A VXT PXI 矢量收发信机,300/600/1200MHz带宽
M9410A PXI 矢量收发信机 -300/600/1200MHz带宽- M9410A VXT PXI 矢量收发信机,300/600/1200MHz带宽支持 5G 的 PXI 矢量收发信机(VXT)是一个 2 插槽模块,具有 1.2 GHz 的瞬时带宽 主要特点 Keysight M9410A VXT PXIe 矢量收发…...

用工厂模式演示springboot三种注入方式 | @Autowired
背景:看了个demo工厂模式,示例代码的工厂类是new出来的,但是实际项目中都是用springboot框架、bean都是会给容器管理的,所以在思考这个工厂类要交给springboot托管要怎么改。以下是总结笔记 依赖注入 1.工厂类用new实现2.工厂类用…...

es查询语法
查询关键词的含义: match: 用于进行全文搜索,分析查询文本并与倒排索引中的词项进行匹配。 term: 精确匹配,适用于非分析字段,如 keyword 类型。用于查找字段值完全相等的文档。 bool: 组合多个查询条件。可以使用 must…...

LabVIEW提高开发效率技巧----合理使用数据流与内存管理
理使用数据流和内存管理是LabVIEW开发中提高性能和稳定性的关键,特别是在处理大数据或高频率信号时,优化可以避免内存消耗过大、程序卡顿甚至崩溃。 1. 使用 Shift Register 进行内存管理 Shift Register(移位寄存器) 是 LabVIE…...

如何在 ECharts 中设置轴标签
在 ECharts 中,轴标签(Axis Label)是指 X 轴或 Y 轴上的刻度标签,用于显示轴上的数据值或分类名称。你可以通过配置 xAxis(X 轴)或 yAxis(Y 轴)的 axisLabel 属性来设置轴标签的样式…...

怎么用gitee做一个图片仓库,在md文档中用这个图片网络地址,然后显示图片
痛因:我为什么要这样做,呃,我一开始图片都是存本地地址的,放在和这个md文档同级的assets文件夹下面,这样子确实当时很方便,复制粘贴什么也不用管,但是想把这个文档分享给别的人的时候࿰…...

Thinkphp(TP)
1.远程命令执行 /index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]system&vars[1][]whoami 2.远程代码执行 /index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]phpinfo&vars[1][]…...

【艾思科蓝】前端框架巅峰对决:React、Vue与Angular的全面解析与实战指南
【JPCS独立出版】第三届能源与动力工程国际学术会议(EPE 2024)_艾思科蓝_学术一站式服务平台 更多学术会议请看:https://ais.cn/u/nuyAF3 引言 在快速发展的前端技术领域,选择合适的框架或库对于项目的成功至关重要。React、Vu…...

IT行业的未来:技术变革与创新的持续推动
IT行业的未来:技术变革与创新的持续推动 随着数字化进程的不断加速,信息技术(IT)行业正迈入一个快速变革的时代。新兴技术如人工智能(AI)、5G、物联网(IoT)和区块链,正在…...

Python PDF转图片自定义输出
PDF转图片自定义输出 一、引入必要库 1 2import fitz import os也可以检查一下版本就是了:print(fitz.__doc__) 上一篇文章已经介绍过要使用的库,和写代码要用到的思路了。我们直接开始: 二、找到文件 首先是我们要获取用户的输入&#x…...

Git 常用操作命令说明
Git 常用操作命令 1. 初始化和克隆仓库 1.1 初始化仓库 git init在当前目录初始化一个新的 Git 仓库。 1.2 克隆仓库 git clone <repository-url>从远程仓库克隆项目到本地。 示例: git clone https://github.com/user/repo.git2. 查看状态和日志 2.1…...

自学前端的正确姿势是...
师傅带进门,修行在个人。 在前端自学成才的道路上,有些人走的很快,有些人却举步维艰。 为什么会这样子呢?因为他们没有掌握自学前端的正确姿势。 在介绍应该要怎样自学前端之前,首先来看下,自学前端容易…...

C/C++语言基础--C++构造函数、析构函数、深拷贝与浅拷贝等等相关知识讲解
本专栏目的 更新C/C的基础语法,包括C的一些新特性 前言 周末休息了,没有更新,请大家见谅哈;构造函数、析构函数可以说便随着C每一个程序,故学构造函数、析构函数是必要的;C语言后面也会继续更新知识点&am…...

json格式互相转换
您提供的字符串已经是一个JSON格式的字符串,但是JSON标准要求键名必须用双引号括起来,而不是单引号。因此,您需要将字符串中的单引号替换为双引号。以下是转换后的JSON字符串: {"图片描述": "高速公路上发生了严重…...

Linux下共享内存详解
共享内存是Linux中一种高效的进程间通信(IPC)方式,它允许多个进程共享同一段内存,从而实现数据的快速传递。共享内存通常比其他IPC机制(如管道或消息队列)更快,因为数据直接存储在内存中&#x…...

MySQL篇(管理工具)
目录 一、系统数据库 二、常用工具 1. mysql 2. mysqladmin 3. mysqlbinlog 4. mysqlshow 5. mysqldump 6. mysqlimport/source 6.1 mysqlimport 6.2 source 一、系统数据库 MySQL数据库安装完成后,自带了一下四个数据库,具体作用如下…...

redis学习笔记(六)
redis每种数据结构的应用场景 1. 字符串 (String) 应用场景 : 缓存:存储频繁访问的数据,如网页缓存、会话信息等。计数器:实现统计和计数功能,如访问计数、统计数据等。键值存储:简单的键值对存储…...

spring与springmvc整合
文章目录 spring与springmvc整合重复创建bean容器关系获取spring容器上下文 spring与springmvc整合 在项目中使用springmvc的时候,由于spring和springmvc是同源的,有时候大家会把所有的配置都扔到springmvc的配置文件中,而不去区分spring和s…...

如何使用Optuna在PyTorch中进行超参数优化
所有神经网络在训练过程中都需要选择超参数,而这些超参数对收敛速度和最终性能有着非常显著的影响。 这些超参数需要特别调整,以充分发挥模型的潜力。超参数调优过程是神经网络训练中不可或缺的一部分,某种程度上,它是一个主要基于梯度优化问题中的“无梯度”部分。 在这…...

2.Spring-容器-注入
注册:将组件放入容器中; 注入:让容器按需进行操作; 一、Autowired:自动注入组件 原理:Spring调用容器的getBean 二、Qualifier 精确指定 精确指定:如果容器中组件存在多个,则使用…...

在uboot中添加自定义命令
有时候为了方便测试,我们需要在Uboot中添加自己的命令,这时可以通过下面的步骤实现: 1、在common目录下添加自己的命令文件“cmd_命令名.c”,如cmd_test.c,内容如下(参考模版): …...

AngularJS 模块
AngularJS 模块 AngularJS,作为一个强大且灵活的前端框架,其核心特性之一就是模块化。模块在AngularJS中扮演着至关重要的角色,它们是组织代码的主要方式,使得开发者能够创建可复用、可维护且易于测试的代码结构。本文将深入探讨AngularJS模块的概念、用途、创建方式以及最…...

[yotroy.cool] MGT 388 - Finance for Engineers - notes 笔记
个人博客https://www.yotroy.cool/,感谢关注~ 图片资源可能显示不全,请前往博客查看哦! ============================================================ Lecture 1 What is Accounting? The process of identifying, measuring and communicating economic informati…...

2024年9月python二级易错题和难题大全(附详细解析)(三)
2024年9月python二级易错题和难题大全(附详细解析)(三) 第1题第2题第3题第4题第5题第6题第7题第8题第9题第10题第11题第12题第13题第14题第15题第16题第17题第18题第19题第20题第1题 1、以下程序的输出结果是() L1 = [4, 5, 6, 8].reverse() print(L1)A、[8, 6, 5, 4]&…...