面试题答案
一键面试设计思路
- 批量插入优化:为了提高插入性能,将100条日志记录分批次插入,而不是逐条插入。这减少了数据库I/O操作的次数。
- 处理数据库锁:在Perl中使用
DBI
模块与SQLite交互,DBI
会自动处理大部分常见的数据库锁情况。但在批量插入时,可能会遇到锁争用,此时需要设置合理的超时时间。 - 处理I/O异常:使用
eval
块来捕获在数据库操作过程中可能出现的异常,如I/O错误、SQL语法错误等,并进行相应的错误处理。 - 定时统计:利用
Time::HiRes
模块精确控制时间,每隔1分钟进行一次特定关键词记录的统计。
关键代码片段
#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use Time::HiRes qw(sleep);
# 数据库连接
my $dbh = DBI->connect('dbi:SQLite:dbname=test.db', '', '', { RaiseError => 1 })
or die "Could not connect to database: ". $DBI::errstr;
# 创建logs表(如果不存在)
$dbh->do('CREATE TABLE IF NOT EXISTS logs (
log_id INTEGER PRIMARY KEY AUTOINCREMENT,
log_time INTEGER,
log_message TEXT
)');
# 插入数据并统计关键词
my $batch_size = 100;
my $total_time = 10 * 60; # 10分钟
my $count_interval = 60; # 1分钟
my $start_time = time();
my $insert_sth = $dbh->prepare('INSERT INTO logs (log_time, log_message) VALUES (?,?)');
while (time() - $start_time < $total_time) {
my @batch;
for (my $i = 0; $i < $batch_size; $i++) {
my $log_time = time();
my $log_message = "Some log message ". rand(10000); # 模拟日志消息
push @batch, [$log_time, $log_message];
}
eval {
$dbh->begin_work;
for my $row (@batch) {
$insert_sth->execute(@$row);
}
$dbh->commit;
};
if ($@) {
$dbh->rollback;
warn "Insertion error: $@";
}
if ((time() - $start_time) % $count_interval == 0) {
my $count_sth = $dbh->prepare('SELECT COUNT(*) FROM logs WHERE log_message LIKE \'%error%\'');
$count_sth->execute();
my ($count) = $count_sth->fetchrow_array;
print "Number of records with 'error' at ". time(). " is: $count\n";
}
sleep(1);
}
$insert_sth->finish;
$dbh->disconnect;
上述代码实现了每秒插入100条日志记录,持续10分钟,并每隔1分钟统计包含'error'关键词的记录数。在插入过程中通过批量插入和事务处理优化性能,并使用eval
块处理可能的异常。