Flutter求职、面试20+面试官总结:Dart篇

Dart 是不是单线程模型?是如何运行的?

是,异步 IO + 事件循环

I/O 模型

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态

  • 阻塞式调用: 调用结果返回之前,当前线程会被挂起,调用线程只有在得到调用结果之后才会继续执行。
  • 非阻塞式调用: 调用执行之后,当前线程不会停止执行,只需要过一段时间来检查一下有没有结果返回即可。

事件循环(Event Loop)

Dart事件循环机制由一个消息循环(event looper)和两个消息队列构成,其中,两个消息队列是指事件队列(event queue)和微任务队列(Microtask queue)。该机制运行原理为:

  • 首先,Dart程序从main函数开始运行,待main函数执行完毕后,event looper开始工作;
  • 然后,event looper优先遍历执行Microtask队列所有事件,直到Microtask队列为空;
  • 接着,event looper才遍历执行Event队列中的所有事件,直到Event队列为空;
  • 最后,视情况退出循环。

Dart 是如何实现多任务并行的?

尽管 Dart 是基于单线程模型的,但为了进一步利用多核 CPU,Dart 也提供了多线程机制,即 Isolate

每个 Isolate 都有自己的 Event Loop 与 Queue,Isolate 之间不共享任何资源,只能依靠消息机制通信,因此也就没有资源抢占问题。

receivePort(接收端口)和sendPort(发送端口),它们是成对出现的

假如不同的Isolate需要通信(单向/双向),就只能通过向对方的事件循环队列里写入任务,并且它们之间的通讯方式是通过port(端口)实现的,其中,Port又分为receivePort(接收端口)和sendPort(发送端口),它们是成对出现的。Isolate之间通信过程:

  • 首先,当前Isolate创建一个ReceivePort对象,并获得对应的SendPort对象;
ini 复制代码
 var receivePort = ReceivePort();
 var sendPort = receivePort.sendPort;
  • 其次,创建一个新的Isolate,并实现新Isolate要执行的异步任务,同时,将当前Isolate的SendPort对象传递给新的Isolate,以便新Isolate使用这个SendPort对象向原来的Isolate发送事件;
csharp 复制代码
// 调用Isolate.spawn创建一个新的Isolate
// 这是一个异步操作,因此使用await等待执行完毕
var anotherIsolate = await Isolate.spawn(otherIsolateInit, receivePort.sendPort);

// 新Isolate要执行的异步任务
// 即调用当前Isolate的sendPort向其receivePort发送消息
void otherIsolateInit(SendPort sendPort) async {
  value = "Other Thread!";
  sendPort.send("BB");
}
  • 然后,调用当前Isolate#receivePort的listen方法监听新的Isolate传递过来的数据。Isolate之间什么数据类型都可以传递,不必做任何标记
lua 复制代码
receivePort.listen((date) {
    print("Isolate 1 接受消息:data = $date");
});
  • 最后,消息传递完毕,关闭新创建的Isolate。
ini 复制代码
anotherIsolate?.kill(priority: Isolate.immediate);
anotherIsolate =null;

Future与isolate的区别

  • future是异步编程,调用本身立即返回,并在稍后的某个时候执行完成时再获得返回结果。在普通代码中可以使用await 等待一个异步调用结束。
  • isolate是并发编程,Dartm有并发时的共享状态,所有Dart代码都在isolate中运行,包括最初的main()。每个isolate都有它自己的堆内存,意味着其中所有内存数据,包括全局数据,都仅对该isolate可见,它们之间的通信只能通过传递消息的机制完成,消息则通过端口(port)收发。isolate只是一个概念,具体取决于如何实现,比如在Dart VM中一个isolate可能会是一个线程,在Web中可能会是一个Web Worker

FutureStream 的异同

  • 1、Future只能接受一次返回值,stream可以接受多次,可以监听事件流
  • 2、stream支持暂停和恢复

简单说一下在Flutter里async和await?Stream? Future和Stream 的异同

在Flutter中,异步编程是通过Future、Stream和async/await等机制来处理的。这些机制允许在执行长时间操作(如网络请求、文件读写等)时不阻塞应用程序的主线程,从而保持应用的响应性。

async await

  • async:标记一个函数为异步函数。异步函数可以包含 await 表达式,等待异步操作的结果。
  • await:用于暂停异步函数的执行,直到 Future 完成并返回结果。

Future

  • 定义:表示一个异步操作的结果,这个结果在将来的某个时刻会返回。
  • 特点Future 只能完成一次,返回一个单一的结果或错误。
  • 用法:常用于网络请求、文件读取等一次性操作。
csharp 复制代码
Future<String> fetchUsername() async {
  await Future.delayed(Duration(seconds: 1));
  return 'User123';
}

void main() async {
  String username = await fetchUsername();
  print(username);
}

Stream

  • 定义:表示一系列异步数据的序列,可以是多个值或错误。
  • 特点Stream 可以多次发出数据,类似于异步的数据流。
  • 用法:常用于需要多次更新的数据,如实时数据流、用户输入事件等。
csharp 复制代码
Stream<int> numberStream() async* {
  for (int i = 1; i <= 5; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

void main() {
  numberStream().listen((number) {
    print(number);
  });
}
Stream的种类
  • "Single-subscription" streams 单订阅流:单个订阅流在流的整个生命周期内仅允许有一个listener
  • "broadcast" streams 多订阅流:广播流允许任意数量的收听者,且无论是否有收听者,他都能产生事件。所以中途进来的收听者将不会收到之前的消息。

FutureStream 的异同

特性 Future Stream
返回值次数 一次 多次
完成状态 完成一次后结束 可以多次返回数据,直到结束
用途 一次性异步操作,如网络请求、文件读取 多次更新的数据,如实时数据、用户输入事件
监听机制 awaitthen()处理单一结果 listen()处理数据流
错误处理 catchError()或 try-catch 捕获 onError捕获错误,使用 try-catch捕获
暂停和恢复 不支持 支持暂停和恢复(pauseresume

函数

Dart是一门面向对象的语言,所以函数也是对象,并且函数的类型是Function

函数的参数可以分成两类: 必须参数和可选参数

可选参数可以分为 命名可选参数 和 位置可选参数

dart 复制代码
命名可选参数: {param1, param2, ...}
位置可选参数: [param1, param2, ...]
必传参赛: {@required int age,String name}
默认值是编译时常量:[String interests,String sex = "男"]

getter setter 重写

Dart 中所有的基础类型、类等都继承 Object ,默认值是 NULL, 自带 gettersetter ,而如果是 final 或者 const 的话,那么它只有一个 getter 方法,Object 都支持 getter、setter 重写:

kotlin 复制代码
  @override
  Size get preferredSize {
    return Size.fromHeight(kTabHeight + indicatorWeight);
  }

级联符号(..)表示什么意思?

Dart 当中的 「..」意思是 「级联操作符」,为了方便配置而使用。「..」和「.」不同的是 调用「..」后返回的相当于是 this,而「.」返回的则是该方法返回的值 。

它允许你在同一个对象上连续调用多个方法或访问多个成员变量,而无需在每次调用后重新指定对象名。这种做法通常被称为"级联表达式"或 "链式调用"

ini 复制代码
someObject  
  ..method1()  
  ..property1 = value1  
  ..method2();

Dart 的作用域

Dart 没有 「public」「private」等关键字,默认就是公开的,私有变量使用 下划线 _开头。

变量 dynamic,var,object三者的区别

  • 1、var声明的变量一经赋值后,数据类型就已经确定,不可以接收其他的数据类型
  • 2、dynamic声明的变量在第一次赋值后,可以继续接收其他的数据类型,可以使用变量运行时的属性跟方法
  • 3、Object声明的变量只能使用Object本身的属性以及方法

final与const声明常量

  • 1、const与final 都用于声明常量,而且已经赋值都不可以被修改
  • 2、const声明常量时,必须赋值明确的值,final声明的常量可以在运行时再赋值

简述Dart语言特性

  • 1、Dart 属于是强类型语言 , 以用var或 dynamic来声明一个变量,Dart会自动推断其数据类型,dynamic类似c#没有赋初值的变量都会有默认值null
  • 2、在Dart中,一切都是对象,所有的对象都是继承自Object

Dart是值传递还是引用传递

dart是引用传递

每次调用函数,传递过去的都是对象的内存地址,而不是这个对象的复制。

Dart 中的 extends / with / implements

  • extends 表示继承。Dart 中的继承和 Java 一样。

    • 使用关键字 extends 继承一个类
    • 子类继承父类可见的属性和方法,不会继承父类的构造方法
    • 子类可以覆写父类的方法,方法上要加 @override
    • 子类可以调用父类的方法,用 super 关键字
    • 单继承,多态性
  • with 表示 mixins (混入),就是在类中混入其他功能。使用 mixins 可以实现类似于多继承的功能。mixins 和接口完全不一样,是一个全新的特性。

    • mixins 只能继承 Object
    • mixins 没有构造函数
    • mixins 和接口实现一样可以在 with 后面使用多个 mixins,用逗号隔开
  • implements 表示接口实现。Dart 不使用 interface 关键字,但是 Dart 中每个类都是一个隐性的接口,这个隐性的接口里面包含了类的所有成员变量和方法。如果一个类被当做接口来用,那么实现这个接口的类必须实现接口所有的成员变量和方法

dart是单继承还是多继承?

单继承

dart如何达到多继承的效果?

Dart中使用Mixins,可以达到多继承的效果

mixin混入有什么特点

  • 1、作为mixins的类只能继承自Object,不能继承其他类
  • 2、作为mixins的类不能有构造函数
  • 3、一个类可以mixins多个mixins类
  • 4、mixins绝不是继承,也不是接口,而是一种全新的特性

混入相同方法的多个混入,最终会执行哪一个?

后面的类中的方法将前面的类中相同的方法覆盖


String扩展一个方法

使用关键字extension ... on为String定义一个扩展类

dart 复制代码
extension StringExt on String{
  // 2. 扩展方法
  int add(int x, int y){
    return x + y;
  }
}
相关推荐
惜.己11 分钟前
Jmeter中的配置原件
java·前端·数据库
家有狸花25 分钟前
CSS笔记(一)炉石传说卡牌设计1
前端·css·笔记
liuweni27 分钟前
Next.js 独立开发教程(三):CSS 样式的完整指南
开发语言·前端·javascript·css·react.js·职场和发展·前端框架
xiaoduyyy1 小时前
【Android】RecyclerView回收复用机制
android
林北芒大果1 小时前
【Flutter】搭建Flutter开发环境,安卓开发
android·flutter
小二·1 小时前
layui树形组件点击树节点后高亮的解决方案
前端·javascript·layui
Minions_Fatman1 小时前
【layui】table的switch、edit修改
前端·javascript·layui
槑带可乐1 小时前
[可乐的随手记 - 6] 并发控制上传大量的文件 (worker + yield )
前端·javascript
小孙姐1 小时前
4——单页面应用程序,vue-cli脚手架
前端·javascript·vue.js
生椰拿铁You1 小时前
15 —— Webpack中的优化——前端项目使用CDN技术
前端·webpack