dart面试题
Dart 面试题与参考答案
适合 Flutter/Dart 面试复习。内容覆盖 Dart 基础语法、类型系统、空安全、面向对象、异步机制、集合、函数、扩展能力、并发模型和工程实践。
一、Dart 基础
1. Dart 是什么?
Dart 是 Google 推出的编程语言,常用于 Flutter 应用开发。它支持面向对象、泛型、空安全、异步编程和 AOT/JIT 编译。
Dart 在 Flutter 中主要负责:
- 编写业务逻辑。
- 描述 UI。
- 管理状态。
- 调用平台能力。
2. Dart 和 JavaScript 有什么区别?
Dart 是强类型语言,支持静态类型检查;JavaScript 是动态类型语言。
Dart 支持 JIT 和 AOT 编译,Flutter 开发阶段使用 JIT 支持热重载,发布阶段使用 AOT 提升性能。
JavaScript 主要运行在浏览器或 Node.js 环境中,而 Dart 在 Flutter 中可以编译到 Android、iOS、Web、桌面等平台。
3. Dart 是单线程的吗?
Dart 的主 isolate 是单线程执行的,Flutter UI 通常运行在主 isolate。
但 Dart 支持多个 isolate。每个 isolate 有独立内存,不能直接共享对象,只能通过消息通信。
4. main() 方法的作用是什么?
main() 是 Dart 程序入口。
普通 Dart 程序:
void main() {
print('Hello Dart');
}
Flutter 应用中通常会调用:
void main() {
runApp(const MyApp());
}
5. Dart 中变量如何声明?
常见方式:
var name = '张三';
String city = '北京';
final age = 18;
const pi = 3.14;
dynamic value = 'hello';
Object object = 'world';
var 会根据初始值推断类型,显式类型声明更适合公共 API 和需要表达清楚意图的场景。
6. final 和 const 的区别?
final 表示变量只能赋值一次,值可以在运行时确定。
const 表示编译期常量,值必须在编译期确定。
final now = DateTime.now(); // 可以
const appName = 'Demo'; // 可以
不能写:
const now = DateTime.now(); // 错误
因为当前时间不是编译期常量。
7. var、dynamic、Object 的区别?
var 是类型推断,类型确定后不能随意改变。
var name = '张三';
name = '李四';
// name = 123; // 编译错误
dynamic 会关闭静态类型检查,运行时才知道是否正确。
dynamic value = 'hello';
value = 123;
value.notExistMethod(); // 编译可能通过,运行时报错
Object 可以接收非 null 对象,但只能使用 Object 本身的方法。
Object value = 'hello';
// value.length; // 编译错误
if (value is String) {
print(value.length);
}
8. Dart 中 late 的作用和风险是什么?
late 表示变量稍后初始化。
late String token;
void init() {
token = 'abc';
}
风险是:如果赋值前访问,会抛出 LateInitializationError。
late String name;
print(name); // 运行时报错
9. Dart 支持哪些注释?
单行注释:
// 单行注释
多行注释:
/*
多行注释
*/
文档注释:
/// 用户模型
class User {}
文档注释可以被 Dart 文档工具识别。
10. Dart 中字符串如何拼接?
推荐使用字符串插值:
final name = '张三';
final age = 18;
print('姓名:$name,年龄:$age');
复杂表达式使用 ${}:
print('明年年龄:${age + 1}');
二、类型系统与空安全
1. Dart 的空安全是什么?
空安全用于在编译期减少空指针问题。
默认类型不可为 null:
String name = '张三';
// name = null; // 编译错误
如果允许为空,需要使用 ?:
String? nickname;
2. ?、!、??、?. 分别是什么意思?
? 表示可空类型:
String? name;
! 表示强制断言非空:
print(name!.length);
如果实际为 null,会运行时报错。
?? 表示为空时使用默认值:
final displayName = name ?? '匿名用户';
?. 表示对象非空时才调用:
print(name?.length);
3. required 的作用是什么?
required 用于命名参数,表示该参数必须传入。
class User {
final String name;
final int age;
const User({
required this.name,
required this.age,
});
}
调用:
final user = User(name: '张三', age: 18);
4. is 和 as 有什么区别?
is 用于类型判断:
if (value is String) {
print(value.length);
}
as 用于类型转换:
final text = value as String;
如果转换失败,as 会抛异常。
5. runtimeType 是什么?
runtimeType 用于获取对象运行时类型。
final value = 'hello';
print(value.runtimeType); // String
调试时可以使用,但业务逻辑中不建议过度依赖 runtimeType。
6. typedef 有什么用?
typedef 可以给函数类型起别名,提高可读性。
typedef ValueChanged<T> = void Function(T value);
void handle(ValueChanged<String> onChanged) {
onChanged('hello');
}
Flutter 中很多回调类型都使用了类似思想。
7. Dart 中泛型有什么作用?
泛型用于提高类型安全和复用性。
class ApiResponse<T> {
final int code;
final T data;
ApiResponse({
required this.code,
required this.data,
});
}
使用:
final response = ApiResponse<User>(
code: 0,
data: User(name: '张三'),
);
这样 data 的类型就是 User,不需要频繁强转。
8. List<Object> 和 List<dynamic> 有什么区别?
List<Object> 中的元素至少是非 null 对象,使用时保留静态类型检查。
List<dynamic> 中的元素可以是任意类型,调用方法时静态检查更弱。
List<Object> a = ['hello', 1];
List<dynamic> b = ['hello', 1, null];
业务代码中应尽量避免大量使用 dynamic。
9. Never 类型是什么?
Never 表示函数永远不会正常返回。
例如:
Never fail(String message) {
throw Exception(message);
}
它常用于异常、不可达分支和类型推断。
10. Dart 中 Object?、Object、dynamic 如何选择?
如果值可以为任意类型且可能为 null,用 Object?。
如果值可以为任意非 null 对象,用 Object。
如果确实需要关闭类型检查,例如 JSON 边界数据,可以用 dynamic,但进入业务层后应尽快转成明确类型。
三、面向对象
1. Dart 是面向对象语言吗?
是。Dart 中几乎所有东西都是对象,包括数字、字符串、函数、集合等。
Dart 支持类、继承、抽象类、接口、mixin、扩展方法和泛型。
2. Dart 如何定义类?
class User {
final String name;
final int age;
User(this.name, this.age);
void sayHello() {
print('你好,我是 $name');
}
}
使用:
final user = User('张三', 18);
user.sayHello();
3. Dart 的构造函数有哪些写法?
普通构造函数:
class User {
final String name;
User(this.name);
}
命名构造函数:
class User {
final String name;
User(this.name);
User.guest() : name = '游客';
}
工厂构造函数:
class User {
final String name;
User(this.name);
factory User.fromJson(Map<String, dynamic> json) {
return User(json['name'] as String);
}
}
4. factory 构造函数有什么特点?
factory 构造函数不一定创建新对象,可以返回已有对象、子类对象或缓存对象。
class Logger {
static final Logger _instance = Logger._internal();
Logger._internal();
factory Logger() {
return _instance;
}
}
适合单例、缓存和复杂对象创建。
5. Dart 如何继承?
使用 extends:
class Animal {
void eat() {
print('吃东西');
}
}
class Dog extends Animal {
void bark() {
print('汪汪');
}
}
Dog 可以调用 eat() 和 bark()。
6. super 的作用是什么?
super 用于调用父类构造函数、方法或属性。
class Person {
final String name;
Person(this.name);
}
class Student extends Person {
final String school;
Student(String name, this.school) : super(name);
}
重写方法时也可以调用父类逻辑:
@override
void init() {
super.init();
print('子类初始化');
}
7. abstract class 有什么用?
抽象类用于定义通用能力或约束,不能直接实例化。
abstract class Shape {
double area();
}
class Circle extends Shape {
final double radius;
Circle(this.radius);
@override
double area() {
return 3.14 * radius * radius;
}
}
8. Dart 中接口如何实现?
Dart 没有单独的 interface 关键字,普通类和抽象类都可以作为接口使用。
使用 implements:
abstract class JsonSerializable {
Map<String, dynamic> toJson();
}
class User implements JsonSerializable {
final String name;
User(this.name);
@override
Map<String, dynamic> toJson() {
return {'name': name};
}
}
implements 要实现接口中的所有成员。
9. extends 和 implements 的区别?
extends 表示继承父类,可以复用父类实现。
implements 表示实现接口,只遵守结构约束,通常需要自己实现所有成员。
extends:我是某个父类的子类。
implements:我承诺实现某种能力。
10. mixin 是什么?
mixin 用于在不增加继承层级的情况下复用一组能力。
mixin Logger {
void log(String message) {
print('[Log] $message');
}
}
class UserService with Logger {
void login() {
log('用户登录');
}
}
Flutter 中常见:
class _PageState extends State<Page>
with SingleTickerProviderStateMixin {}
11. with 和 on 在 mixin 中有什么作用?
with 用于混入 mixin:
class Dog with RunAbility {}
on 用于限制 mixin 只能用于某类或其子类:
mixin LoadingMixin<T extends StatefulWidget> on State<T> {
bool loading = false;
void showLoading() {
setState(() {
loading = true;
});
}
}
这里 LoadingMixin 只能混入 State<T>,所以内部可以安全调用 setState()。
12. extension 是什么?
extension 可以给已有类型扩展方法或 getter,而不修改原类型源码。
extension StringExt on String {
bool get isPhone {
return RegExp(r'^1\d{10}$').hasMatch(this);
}
String maskPhone() {
if (length != 11) return this;
return '${substring(0, 3)}****${substring(7)}';
}
}
使用:
print('13800138000'.isPhone);
print('13800138000'.maskPhone());
四、函数与闭包
1. Dart 中函数是一等公民是什么意思?
函数可以像普通对象一样赋值、作为参数传递、作为返回值返回。
void sayHello() {
print('hello');
}
final callback = sayHello;
callback();
2. 箭头函数适合什么场景?
箭头函数适合只有一个表达式的函数。
int add(int a, int b) => a + b;
等价于:
int add(int a, int b) {
return a + b;
}
3. 位置参数和命名参数有什么区别?
位置参数按顺序传:
void login(String username, String password) {}
login('admin', '123456');
命名参数按名字传,可读性更好:
void login({
required String username,
required String password,
}) {}
login(username: 'admin', password: '123456');
4. 可选参数如何声明?
可选位置参数使用 []:
void say(String name, [String? message]) {}
可选命名参数使用 {}:
void say({
required String name,
String message = '你好',
}) {}
5. 闭包是什么?
闭包是函数捕获并使用其外部作用域变量的能力。
Function makeCounter() {
int count = 0;
return () {
count++;
return count;
};
}
void main() {
final counter = makeCounter();
print(counter()); // 1
print(counter()); // 2
}
内部函数捕获了外部变量 count。
6. 回调函数在 Flutter 中有什么用?
回调函数用于把子组件事件通知给父组件。
class SubmitButton extends StatelessWidget {
final VoidCallback onSubmit;
const SubmitButton({
super.key,
required this.onSubmit,
});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onSubmit,
child: const Text('提交'),
);
}
}
7. Function 和具体函数类型有什么区别?
Function 太宽泛,类型约束弱。
不推荐:
final Function callback;
推荐:
final void Function(String value) onChanged;
或者使用 Flutter 提供的:
final ValueChanged<String> onChanged;
具体函数类型更安全、更清晰。
8. async 函数返回值是什么?
被 async 标记的函数会返回 Future。
Future<String> fetchName() async {
return '张三';
}
即使直接返回字符串,也会被包装成 Future<String>。
9. sync* 和 async* 是什么?
sync* 用于同步生成 Iterable:
Iterable<int> numbers() sync* {
yield 1;
yield 2;
yield 3;
}
async* 用于异步生成 Stream:
Stream<int> countStream() async* {
yield 1;
await Future.delayed(const Duration(seconds: 1));
yield 2;
}
10. yield 的作用是什么?
yield 用于生成一个值,但不会像 return 那样结束整个生成函数。
Iterable<int> range(int max) sync* {
for (var i = 0; i < max; i++) {
yield i;
}
}
五、集合与常用操作
1. Dart 中常用集合有哪些?
常用集合:
List<String> names = ['张三', '李四'];
Set<int> ids = {1, 2, 3};
Map<String, dynamic> json = {'name': '张三'};
List 有序可重复,Set 无重复元素,Map 保存键值对。
2. List 常用方法有哪些?
常见方法:
final list = [1, 2, 3];
list.add(4);
list.remove(2);
list.contains(3);
list.map((e) => e * 2);
list.where((e) => e > 1);
list.first;
list.last;
3. map、where、forEach 的区别?
map 用于转换:
final result = [1, 2, 3].map((e) => e * 2).toList();
where 用于过滤:
final result = [1, 2, 3].where((e) => e > 1).toList();
forEach 用于遍历执行副作用:
[1, 2, 3].forEach(print);
4. Iterable 和 List 有什么区别?
Iterable 表示可迭代对象,不一定支持下标访问。
List 是有序集合,支持下标访问和长度。
很多集合操作如 map、where 返回的是 Iterable,如果需要列表,要调用:
toList()
5. Set 有什么特点?
Set 不允许重复元素。
final ids = {1, 2, 2, 3};
print(ids); // {1, 2, 3}
适合去重、成员判断等场景。
6. Map 如何遍历?
final user = {
'name': '张三',
'age': 18,
};
user.forEach((key, value) {
print('$key: $value');
});
也可以:
for (final entry in user.entries) {
print('${entry.key}: ${entry.value}');
}
7. Dart 中扩展运算符 ... 有什么用?
用于展开集合:
final a = [1, 2];
final b = [0, ...a, 3];
print(b); // [0, 1, 2, 3]
可空展开使用 ...?:
List<int>? a;
final b = [0, ...?a, 3];
8. collection if 和 collection for 是什么?
集合中可以直接写条件和循环。
final isLogin = true;
final menus = [
'首页',
if (isLogin) '个人中心',
];
循环:
final widgets = [
for (final item in items) Text(item.title),
];
Flutter UI 中非常常用。
9. 如何避免访问空列表报错?
不要直接对可能为空的列表调用 first。
可以判断:
if (list.isNotEmpty) {
print(list.first);
}
也可以封装扩展:
extension IterableExt<T> on Iterable<T> {
T? get firstOrNull {
if (isEmpty) return null;
return first;
}
}
10. 如何将 JSON 转成 Dart Model?
手写:
class User {
final String name;
final int age;
User({
required this.name,
required this.age,
});
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'] as String,
age: json['age'] as int,
);
}
Map<String, dynamic> toJson() {
return {
'name': name,
'age': age,
};
}
}
大型项目常使用 json_serializable 或 freezed 生成代码。
六、异步编程
1. Future 是什么?
Future 表示未来某个时间完成的一次异步结果。
Future<String> fetchName() async {
await Future.delayed(const Duration(seconds: 1));
return '张三';
}
适合网络请求、文件读取、数据库查询等一次性异步任务。
2. Stream 是什么?
Stream 表示一系列异步事件。
Stream<int> countStream() async* {
yield 1;
yield 2;
yield 3;
}
适合聊天消息、定位更新、下载进度、WebSocket、计时器等连续事件。
3. Future 和 Stream 的区别?
Future 是一次结果。
Stream 是多次结果。
Future:一次网络请求。
Stream:持续接收消息。
4. async / await 的作用是什么?
async 让函数返回 Future。
await 等待异步任务完成后继续执行,不会阻塞 UI 线程。
Future<void> load() async {
final user = await fetchUser();
print(user.name);
}
5. 如何捕获异步异常?
使用 try-catch:
try {
final user = await fetchUser();
print(user.name);
} catch (e, stackTrace) {
print(e);
}
也可以使用:
fetchUser().catchError((error) {
print(error);
});
6. Dart 事件循环执行顺序是什么?
通常顺序:
同步代码
Microtask Queue
Event Queue
示例:
void main() {
print('1');
Future(() => print('2 Future'));
Future.microtask(() => print('3 Microtask'));
print('4');
}
输出:
1
4
3 Microtask
2 Future
7. Microtask 和 Event Queue 有什么区别?
Microtask 优先级更高,会在当前同步代码结束后、Event Queue 之前执行。
普通 Future(() {})、Timer、I/O、用户事件通常进入 Event Queue。
如果不断创建 Microtask,可能导致 Event Queue 长时间得不到执行。
8. Future.microtask 和 Future(() {}) 的区别?
Future.microtask 进入 Microtask Queue。
Future(() {}) 进入 Event Queue。
Future.microtask(() => print('microtask'));
Future(() => print('event'));
microtask 通常先输出。
9. StreamController 有什么作用?
StreamController 用于手动创建和控制 Stream。
final controller = StreamController<int>();
controller.stream.listen((value) {
print(value);
});
controller.add(1);
controller.add(2);
await controller.close();
注意使用完成后要 close(),避免资源泄漏。
10. await for 有什么用?
await for 用于异步遍历 Stream。
await for (final value in countStream()) {
print(value);
}
它会等待每个事件到来并依次处理。
11. isolate 是什么?
isolate 是 Dart 的并发执行单元,每个 isolate 拥有独立内存。
主 isolate 通常负责 UI,耗时计算可以放到其他 isolate,避免阻塞界面。
final result = await Isolate.run(() {
return heavyCalculate();
});
12. isolate 和线程有什么区别?
线程通常可以共享内存,需要锁处理并发问题。
isolate 不共享内存,只能通过消息通信,因此减少了共享内存带来的数据竞争问题。
七、相等性与对象身份
1. == 和 identical() 的区别?
== 判断相等性,可以被重写。
identical() 判断是否是同一个对象引用。
class User {
final String name;
User(this.name);
}
void main() {
final a = User('张三');
final b = User('张三');
final c = a;
print(a == b); // false,未重写 ==
print(identical(a, b)); // false
print(identical(a, c)); // true
}
2. 如何重写 ==?
class User {
final String name;
User(this.name);
@override
bool operator ==(Object other) {
return other is User && other.name == name;
}
@override
int get hashCode => name.hashCode;
}
重写 == 时必须同时重写 hashCode。
3. 为什么重写 == 要同时重写 hashCode?
因为 Set、Map 等哈希集合依赖 hashCode 查找对象。
如果两个对象 == 为 true,但 hashCode 不一致,会导致集合行为异常。
4. const 对象和 identical() 有什么关系?
相同参数的 const 对象可能被规范化为同一个实例。
class User {
final String name;
const User(this.name);
}
void main() {
const a = User('张三');
const b = User('张三');
print(identical(a, b)); // true
}
非 const 创建通常是不同实例。
5. 什么是不可变对象?
不可变对象创建后内部状态不能改变。
class User {
final String name;
final int age;
const User({
required this.name,
required this.age,
});
}
不可变对象更适合状态管理、缓存、比较和多处共享。
八、Dart 与 Flutter 实战问题
1. 为什么 Flutter 中推荐使用 const?
const 可以创建编译期常量对象,减少重复创建 Widget 配置对象。
在 Flutter 中:
const Text('固定文字')
如果参数不变,多次 build 可以复用同一个 Widget 实例,降低更新成本。
2. mounted 有什么用?
mounted 表示当前 State 是否仍然挂载在 Widget 树上。
异步后如果要调用 setState() 或使用 context,应判断:
if (!mounted) return;
setState(() {
loading = false;
});
避免页面销毁后继续更新 UI。
3. 为什么不建议在 build() 中做耗时操作?
build() 可能频繁执行。
如果在里面做网络请求、复杂计算或创建重量级对象,会造成性能问题和重复请求。
耗时逻辑应放到状态层、initState()、异步任务或 isolate 中。
4. Dart 如何区分开发和生产环境配置?
可以使用 --dart-define:
flutter run --dart-define=ENV=dev
flutter build apk --dart-define=ENV=prod
代码中读取:
class Env {
static const env = String.fromEnvironment(
'ENV',
defaultValue: 'dev',
);
}
5. String.fromEnvironment 是运行时读取吗?
不是。它读取的是编译期环境常量。
打包后值已经确定,不能在 App 运行过程中动态改变。
6. JSON 中为什么常用 Map<String, dynamic>?
因为 JSON 的 value 可能是字符串、数字、布尔值、数组、对象或 null。
final Map<String, dynamic> json = {
'name': '张三',
'age': 18,
'vip': true,
};
但业务层不建议长期使用 dynamic,应尽快转成明确 Model。
7. 如何避免 Dart 中的运行时类型错误?
常见方式:
- 尽量使用明确类型。
- 减少
dynamic。 - JSON 转 Model。
- 使用泛型。
- 使用
is判断后再使用。 - 避免滥用
as强转。
8. Dart 中如何实现单例?
常见写法:
class AppConfig {
AppConfig._internal();
static final AppConfig instance = AppConfig._internal();
}
也可以使用 factory:
class Logger {
static final Logger _instance = Logger._internal();
Logger._internal();
factory Logger() => _instance;
}
9. Dart 中如何处理资源释放?
需要手动关闭或释放的资源,应在合适生命周期中处理。
例如:
final controller = StreamController<int>();
void dispose() {
controller.close();
}
Flutter 中常见需要释放:
TextEditingControllerScrollControllerAnimationControllerFocusNode- Stream 订阅
- Timer
10. Dart 中如何做代码生成?
常见工具:
build_runnerjson_serializablefreezedretrofit
常见命令:
flutter pub run build_runner build
或:
dart run build_runner build
如果遇到冲突文件:
dart run build_runner build --delete-conflicting-outputs
九、高频追问题
1. Dart 为什么适合 Flutter?
Dart 同时支持 JIT 和 AOT。
开发阶段使用 JIT 支持热重载,发布阶段使用 AOT 编译成机器码提升性能。
同时 Dart 的声明式 UI 写法、异步模型、空安全和强类型系统都适合构建 Flutter 应用。
2. AOT 和 JIT 的区别?
JIT(Just In Time)是运行时编译,适合开发调试和热重载。
AOT(Ahead Of Time)是提前编译,适合发布模式,启动更快、运行性能更好。
debug:JIT,开发效率高。
release:AOT,性能更好。
3. Dart 的事件循环为什么重要?
Flutter UI 在主 isolate 上运行。如果主 isolate 被耗时同步任务阻塞,界面就会卡顿。
理解同步代码、Microtask Queue 和 Event Queue 的顺序,有助于分析异步执行顺序和 UI 卡顿问题。
4. 什么时候使用 isolate?
当任务是 CPU 密集型,并且可能阻塞 UI 时,可以考虑 isolate。
例如:
- 大 JSON 解析。
- 图片处理。
- 加密计算。
- 大量数据排序。
普通网络请求通常不需要 isolate,因为它本身就是异步 I/O。
5. Dart 中如何写出更安全的代码?
建议:
- 使用空安全。
- 使用明确类型。
- 少用
dynamic。 - 优先不可变对象。
- 异步后检查
mounted。 - 捕获异常并上报。
- 对外部输入做校验。
- 使用单元测试覆盖核心逻辑。
6. dynamic 可以不用吗?
不能完全不用。JSON、平台通道、第三方动态数据中经常会遇到 dynamic。
但应该把 dynamic 限制在边界层,进入业务逻辑前转成明确类型。
7. 为什么推荐 Model 使用 final 字段?
final 字段让对象更接近不可变,减少被意外修改的风险。
状态更新时通常创建新对象,而不是直接改旧对象,这有利于状态管理和 UI 更新判断。
8. copyWith 有什么用?
copyWith 用于基于旧对象创建一个修改部分字段的新对象。
class User {
final String name;
final int age;
const User({
required this.name,
required this.age,
});
User copyWith({
String? name,
int? age,
}) {
return User(
name: name ?? this.name,
age: age ?? this.age,
);
}
}
使用:
final user = User(name: '张三', age: 18);
final newUser = user.copyWith(age: 19);
9. Dart 中异常如何处理?
使用 try-catch-finally:
try {
await request();
} catch (e, stackTrace) {
print(e);
} finally {
print('结束');
}
可以抛出异常:
throw Exception('请求失败');
10. 面试中如何回答 Dart 的核心优势?
可以这样回答:
Dart 是一门适合 Flutter 的现代强类型语言,支持空安全、泛型、异步编程、扩展方法、mixin 和 AOT/JIT 编译。开发阶段 JIT 支持热重载,发布阶段 AOT 编译提升性能。它的语法和声明式 UI 风格结合得很好,同时强类型和空安全能减少大量运行时错误。
十、复习建议
建议优先掌握:
final、const、var、dynamic、Object。- 空安全:
?、!、??、?.。 - 类、继承、抽象类、接口、mixin、extension。
- Future、Stream、async/await、事件循环。
- List、Map、Set 和常用集合操作。
==、hashCode、identical()。- AOT/JIT、isolate、
--dart-define。
如果时间有限,优先把「类型系统」「空安全」「异步机制」「面向对象」「Dart 与 Flutter 的关系」讲清楚,面试命中率最高。

浙公网安备 33010602011771号