面试题答案
一键面试性能优化策略
- SQLite 性能优化
- 批量操作:避免每次数据变更都进行单独的 I/O 操作,而是将多个相关操作合并成一个批量操作。例如,在插入多条数据时,使用事务(transaction)将所有插入语句包裹起来,这样只有在事务提交时才会真正进行 I/O 操作,减少磁盘 I/O 的频率。
await database.transaction((txn) async { for (var item in dataList) { await txn.insert('table_name', item.toMap()); } });
- 缓存机制:在内存中创建一个缓存层,对频繁读取的数据进行缓存。当需要读取数据时,先从缓存中查找,如果存在则直接返回,避免直接查询 SQLite 数据库。可以使用 Dart 中的
Map
来实现简单的缓存。例如:
Map<int, User> userCache = {}; Future<User> getUser(int id) async { if (userCache.containsKey(id)) { return userCache[id]; } var result = await database.query('users', where: 'id =?', whereArgs: [id]); if (result.isNotEmpty) { var user = User.fromMap(result.first); userCache[id] = user; return user; } return null; }
- 索引优化:为经常用于查询条件的字段创建索引。例如,如果经常根据
name
字段查询用户数据,就在name
字段上创建索引。
await database.execute('CREATE INDEX idx_name ON users (name)');
- SharedPreferences 性能优化
- 减少写入频率:由于 SharedPreferences 的写入操作会涉及到磁盘 I/O,尽量合并多个数据的写入操作,而不是每次数据变化都调用
set
方法。例如,可以在一个操作完成后,批量更新 SharedPreferences。
final prefs = await SharedPreferences.getInstance(); var batch = prefs.edit(); batch.setString('key1', 'value1'); batch.setInt('key2', 2); await batch.commit();
- 减少写入频率:由于 SharedPreferences 的写入操作会涉及到磁盘 I/O,尽量合并多个数据的写入操作,而不是每次数据变化都调用
数据安全策略
- SQLite 数据安全
- 加密存储:使用支持加密功能的 SQLite 库,如
sqflite
库配合sqlite3_flutter_libs
插件可以实现 SQLite 数据库的加密。在打开数据库时设置加密密钥,这样数据库文件中的数据就会以加密形式存储。
final database = await databaseFactoryFfi.openDatabase( 'path/to/database.db', options: OpenDatabaseOptions( password: 'your_secret_password', ), );
- 权限控制:确保应用对 SQLite 数据库文件的访问权限最小化。在 Android 中,可以通过设置文件权限使得只有应用本身可以访问数据库文件。在
AndroidManifest.xml
中设置android:exported="false"
来限制外部应用对数据库文件的访问。
- 加密存储:使用支持加密功能的 SQLite 库,如
- SharedPreferences 数据安全
- 数据加密:对于敏感数据,在存储到 SharedPreferences 之前先进行加密处理。可以使用 Dart 的加密库,如
pointycastle
库。例如,对用户密码进行加密后再存储。
import 'package:pointycastle/pointycastle.dart'; import 'package:convert/convert.dart'; Future<String> encryptData(String data, String key) async { final keyUtf8 = utf8.encode(key); final iv = Uint8List(16); final keyParameter = KeyParameter(keyUtf8); final ivParameter = ParametersWithIV(keyParameter, iv); final aes = AESFastEngine(); final encryptor = PaddedBlockCipherImpl( BlockCipherMode.cbc, aes, Pkcs7Padding(), ); encryptor.init(true, ivParameter); final dataUtf8 = utf8.encode(data); final encrypted = encryptor.process(dataUtf8); return base64.encode(encrypted); } // 存储加密数据 final prefs = await SharedPreferences.getInstance(); String encryptedPassword = await encryptData('user_password', 'encryption_key'); prefs.setString('encrypted_password', encryptedPassword);
- 防止反编译获取数据:对应用进行混淆处理,在 Android 中可以使用 ProGuard 或 R8 进行代码混淆,使得反编译后的代码难以理解,增加攻击者获取 SharedPreferences 中数据的难度。在
build.gradle
文件中配置混淆:
buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }
- 数据加密:对于敏感数据,在存储到 SharedPreferences 之前先进行加密处理。可以使用 Dart 的加密库,如