通用软件项目技术报告 - 第一章节检测
试卷一 (难度:基础级)
一、 选择题 (每题2分,共20分)
-
下列哪个是关系型数据库的典型代表?
A. MongoDB
B. Redis
C. PostgreSQL
D. Cassandra -
在PostgreSQL中,用于唯一标识表中每一行的列通常设置为什么约束?
A. FOREIGN KEY
B. UNIQUE
C. PRIMARY KEY
D. NOT NULL -
MongoDB中存储数据的基本单元是什么?
A. 表 (Table)
B. 行 (Row)
C. 文档 (Document)
D. 模式 (Schema) -
ORM代表什么?
A. 对象关系映射 (Object-Relational Mapping)
B. 操作资源管理 (Operation Resource Management)
C. 开放路由模型 (Open Routing Model)
D. 对象读取机制 (Object Reading Mechanism) -
在数据库迁移中,“应用迁移脚本”的目的是什么?
A. 生成描述数据库结构变化的代码
B. 将数据库结构变化实际应用到数据库上
C. 回滚数据库到上一个版本
D. 检查数据库当前结构 -
数据库连接池的主要作用是什么?
A. 增加数据库的存储容量
B. 提高单次数据库连接的加密强度
C. 复用数据库连接,提高性能和资源利用率
D. 自动备份数据库 -
下列哪种索引类型最常用于加速基于等值和范围条件的查询?
A. Hash 索引
B. B-Tree 索引
C. GIN 索引
D. GiST 索引 -
EXPLAIN
命令在数据库查询优化中的主要作用是?
A. 执行查询并返回结果
B. 显示数据库如何计划执行一个查询
C. 自动优化查询语句
D. 备份查询结果 -
数据库备份的主要目的是什么?
A. 提高查询速度
B. 增加存储空间
C. 防止数据丢失并支持数据恢复
D. 实时同步数据到多个服务器 -
在PostgreSQL中,
VARCHAR(255)
表示什么类型的数据?
A. 一个最大长度为255的整数
B. 一个最大长度为255的文本字符串
C. 一个精确到255位小数的数字
D. 一个日期类型
二、 判断题 (每题1分,共10分)
- MongoDB是一种关系型数据库。 ( )
- 在PostgreSQL中,外键约束用于保证引用完整性。 ( )
- ORM工具的主要目的是让开发者直接编写更复杂的SQL语句。 ( )
- 数据库迁移脚本一旦生成就不能修改。 ( )
- 增加数据库连接池的最大连接数总能提高应用性能。 ( )
- 为表中的每一列都创建索引是提高查询性能的最佳实践。 ( )
pg_dump
是MongoDB的备份工具。 ( )- Lazy Loading(延迟加载)策略总是在加载关联数据时比Eager Loading(即时加载)更高效。 ( )
- 在PostgreSQL中,
JSONB
类型比JSON
类型存储效率更高,查询性能也更好。 ( ) - RPO (Recovery Point Objective) 指的是系统从故障到恢复服务所需的最长时间。 ( )
三、 简答题 (每题10分,共50分)
- 简述什么是数据库Schema?
- 列出至少三种在PostgreSQL中常用的列约束及其作用。
- 什么是ORM?使用ORM有什么好处?
- 简述数据库连接池的工作原理。
- 什么是数据库备份?为什么它很重要?
四、 解答题 (共70分)
- (9分) 在设计一个电商网站的
products
(商品)表时,请列出至少5个你认为必要的字段,并为每个字段建议一个合适的PostgreSQL数据类型。 - (9分) 什么是数据库索引?请举例说明在什么情况下应该为表的某个列创建索引。
- (12分) 简述数据库迁移(Schema Evolution)是什么,以及为什么在软件开发过程中需要进行数据库迁移。
- (12分) 请解释RPO(恢复点目标)和RTO(恢复时间目标)这两个概念在数据库备份与恢复策略中的含义。
- (13分) 假设有一个
orders
(订单)表和一个users
(用户)表,一个用户可以有多个订单,一个订单只属于一个用户。这种关系在关系型数据库(如PostgreSQL)中通常如何实现?请描述涉及的关键表和字段。 - (15分) 简述逻辑备份和物理备份的区别及其各自的优缺点。
试卷二 (难度:理解级)
一、 选择题 (每题2分,共20分)
-
在MongoDB中,当需要频繁地将相关数据一起查询出来,并且“多”的一方数量有限时,通常推荐使用哪种方式处理数据关系?
A. 引用 (Referencing)
B. 嵌入 (Embedding)
C. 创建关联集合 (Association Collection)
D. 使用外键约束 -
Alembic是一个主要用于哪个ORM框架的数据库迁移工具?
A. Django ORM
B. TypeORM
C. SQLAlchemy
D. Hibernate -
在HikariCP连接池配置中,
maximumPoolSize
参数的作用是什么?
A. 连接池中保持的最小空闲连接数
B. 连接池中允许存在的最大连接总数
C. 单个连接在池中的最大空闲时间
D. 客户端等待获取连接的最长时间 -
当一个PostgreSQL查询的
WHERE
子句中包含对函数结果的过滤(例如WHERE LOWER(username) = 'admin'
),哪种类型的索引最能优化这个查询?
A. B-Tree 索引
B. GIN 索引
C. 函数索引 (Functional Index)
D. 部分索引 (Partial Index) -
在PostgreSQL中,
ON DELETE CASCADE
用在外键约束上时,表示什么行为?
A. 如果父表记录被删除,子表对应记录的外键字段被设为NULL
B. 阻止父表记录被删除,如果它被子表记录引用
C. 如果父表记录被删除,所有引用它的子表记录也会被自动删除
D. 父表记录删除时,子表外键字段被设为其默认值 -
下列哪个操作通常不是幂等的?
A.GET /users/1
B.PUT /users/1
(用完整数据更新)
C.DELETE /users/1
D.POST /users
(创建新用户) -
在ORM中,Lazy Loading(延迟加载)可能导致什么性能问题?
A. 首次查询数据过慢
B. N+1 查询问题
C. 数据库连接过早释放
D. 内存占用过高 -
TTL索引(Time-To-Live Index)在MongoDB中的主要作用是什么?
A. 加速对时间范围的查询
B. 自动删除集合中过期的文档
C. 限制集合中文档的总数量
D. 为时间戳字段提供全文搜索能力 -
数据库分区(Partitioning)的主要目的是什么?
A. 提高单条记录的写入速度
B. 减少数据库的总存储空间
C. 提高对大表的查询性能和管理效率
D. 自动加密敏感数据 -
在数据库备份策略中,“增量备份”指的是什么?
A. 备份整个数据库的所有数据
B. 只备份自上次全量备份以来发生变化的数据
C. 只备份自上次任何类型备份(全量或增量)以来发生变化的数据
D. 备份数据库的事务日志
二、 判断题 (每题1分,共10分)
- 在MongoDB中,
_id
字段的值必须由用户手动指定。 ( ) - 使用ORM可以完全避免编写任何SQL语句。 ( )
- 数据库迁移的回滚操作总是能够完美地恢复所有数据和结构变更。 ( )
- 连接池的
idleTimeout
参数设置得越长,对系统性能越有利。 ( ) - 覆盖索引(Covering Index)可以避免回表查询,从而提升性能。 ( )
- RPO为零意味着不允许任何数据丢失。 ( )
- 在PostgreSQL中,
JSONB
类型的索引通常使用B-Tree索引。 ( ) - 多阶段构建(Multi-stage builds)在Dockerfile中的主要目的是增加最终镜像的功能。 ( )
- Capped Collection是MongoDB中一种大小固定的集合,新数据会覆盖旧数据。 ( )
- 数据库的物理备份通常比逻辑备份恢复速度更快。 ( )
三、 简答题 (每题10分,共50分)
- 简述在PostgreSQL中实现多对多关系的常用方法。
- 解释ORM中的“模型类定义与Schema映射”指的是什么过程。
- 在数据库迁移过程中,“审查和编辑迁移脚本”这一步骤为什么重要?
- 说明数据库连接池中“连接验证”的机制和目的。
- 什么是PostgreSQL中的全文搜索(FTS)?它与简单的
LIKE '%keyword%'
查询有何不同?
四、 解答题 (共70分)
- (9分) 为一个“事件日志”集合(MongoDB)设计Schema,至少包含5个核心字段,并说明每个字段的类型和用途。
- (9分) 解释什么是N+1查询问题,以及在ORM中通常如何通过Eager Loading来避免它。
- (12分) 描述一个标准的数据库迁移工作流程,至少包含4个主要步骤。
- (12分) 假设一个PostgreSQL表
transactions
有一个transaction_time
(TIMESTAMP WITH TIME ZONE) 列和一个status
(VARCHAR) 列。你希望优化对“过去一个月内所有状态为’completed’的交易”的查询。你会考虑创建哪种类型的索引(或组合)?简述理由。 - (13分) 讨论在PostgreSQL中使用分区表(Partitioning)的优势和一种常见的分区策略(如范围分区)。
- (15分) 为什么在PostgreSQL中推荐使用
JSONB
而不是JSON
类型来存储JSON数据?并简述如何为JSONB
列中的特定键值对查询创建合适的索引。
试卷三 (难度:应用级)
一、 选择题 (每题2分,共20分)
-
在PostgreSQL中,如果你希望一个外键在引用的主表记录被删除时,自动将该外键字段设置为NULL,应使用哪个
ON DELETE
子句?
A.CASCADE
B.RESTRICT
C.SET NULL
D.NO ACTION
-
使用SQLAlchemy的Alembic进行数据库迁移时,
alembic revision --autogenerate
命令的作用是?
A. 将数据库升级到最新版本
B. 比较当前模型与数据库状态,自动生成迁移脚本
C. 创建一个空的迁移脚本供手动编辑
D. 回滚上一个迁移版本 -
对于HikariCP连接池,如果设置
minimumIdle
等于maximumPoolSize
,这将形成一个什么类型的连接池?
A. 动态大小连接池
B. 固定大小连接池
C. 懒加载连接池
D. 无限制连接池 -
在PostgreSQL中,为
tsvector
列创建哪种类型的索引最适合全文搜索查询?
A. B-Tree
B. Hash
C. GIN
D. BRIN -
以下哪项是MongoDB中Capped Collection的特性?
A. 文档大小可以动态增长
B. 可以对单个文档进行删除操作
C. 数据按插入顺序存储,并在达到上限时覆盖旧数据
D. 支持Sharding -
在ORM中,哪种加载策略最有可能在获取关联数据时使用
JOIN
语句?
A.lazy='select'
B.lazy='joined'
C.lazy='subquery'
D. 默认的Lazy Loading -
PostgreSQL中的物化视图(Materialized View)与普通视图(View)的主要区别在于?
A. 物化视图不能被查询
B. 物化视图存储了查询的物理结果,需要刷新
C. 普通视图的查询性能总是优于物化视图
D. 物化视图不能基于多个表创建 -
在MongoDB Schema设计中,对于“一对非常多”(one-to-bazillions)的关系,比如用户和他的操作日志,通常推荐哪种处理方式?
A. 将所有日志嵌入到用户文档中
B. 在用户文档中存储日志ID的数组,并在日志集合中存储日志详情(引用)
C. 在日志文档中存储用户ID(引用),并在用户文档中不存储直接引用
D. 为每个用户创建一个单独的日志集合 -
以下哪个不是PostgreSQL推荐的Schema设计最佳实践?
A. 积极使用CHECK
约束强制数据完整性
B. 为所有文本类型字段默认使用TEXT
类型,除非有明确长度限制
C. 将包含大量NULL值的稀疏列考虑使用JSONB
存储
D. 对非常大的表考虑使用分区 -
在数据库的备份恢复策略中,恢复时间目标 (RTO) 指的是:
A. 备份操作完成所需的时间
B. 从故障发生到系统恢复服务所需的最长时间
C. 两次全量备份之间的最大时间间隔
D. 最多可以容忍丢失的数据量
二、 判断题 (每题1分,共10分)
- 在PostgreSQL中,
JSONB
类型的数据在存储时会保留原始JSON文本的空格和键的顺序。 ( ) - TypeORM主要用于Python项目,而SQLAlchemy主要用于TypeScript项目。 ( )
- “扩展-收缩模式”(Expand-Contract Pattern)是实现数据库零停机迁移的一种策略。( )
- HikariCP的
validationTimeout
参数应设置为大于connectionTimeout
。 ( ) - 在PostgreSQL中,Hash索引通常比B-Tree索引更适合范围查询。 ( )
- 数据库的逻辑备份通常包含了数据库的物理文件结构。 ( )
- Alembic迁移工具不支持迁移分支和合并。 ( )
- MongoDB的TTL索引可以用于自动归档过期数据到另一个集合。 ( )
- 使用ORM时,模型类之间的多对多关系如果关联表有额外字段,则需要将关联表也定义为一个模型类。 ( )
- 在PostgreSQL中,为经常用于
ORDER BY
子句的列创建索引可以提升排序性能。 ( )
三、 简答题 (每题10分,共50分)
- 讨论在MongoDB中“嵌入(Embedding)”和“引用(Referencing)”处理数据关系的优缺点及适用场景。
- 解释SQLAlchemy中
lazy='joined'
和lazy='subquery'
两种Eager Loading策略的区别及其对查询性能的潜在影响。 - 在多环境(如开发、测试、生产)进行数据库迁移时,为什么强调数据兼容性的重要性?并简述一种处理策略。
- 简述PostgreSQL中的部分索引(Partial Index)的原理和适用场景。
- 描述数据库备份中全量备份、增量备份和差分备份的定义及其在恢复过程中的关系。
四、 解答题 (共70分)
- (9分) 假设你正在使用PostgreSQL,需要为一个博客系统设计
posts
表和tags
表,以及它们之间的多对多关系。请写出这三个表的关键字段定义(包括主键、外键和必要的约束)。 - (9分) 简述HikariCP连接池中
idleTimeout
和maxLifetime
两个参数的作用,并解释为什么通常建议maxLifetime
要小于数据库或网络设备强制关闭连接的时间。 - (12分) 解释PostgreSQL的
EXPLAIN ANALYZE
命令的输出中,哪些关键信息可以帮助你诊断一个慢查询?并举例说明如何根据这些信息进行可能的优化。 - (12分) 你正在为一个需要存储大量时间序列数据(例如,每秒传感器读数)的PostgreSQL数据库设计
sensor_readings
表。讨论为什么分区表(Partitioning)可能是一个好的选择,并描述一种基于时间范围的分区策略的关键步骤。 - (13分) 假设你有一个使用SQLAlchemy的Python应用,
User
模型有一个profile
属性,它与UserProfile
模型是一对一关系。请简述如何在模型类中定义这种关系,并说明在查询User
对象时,如何配置才能即时加载(Eager Load)关联的UserProfile
对象。 - (15分) 设计一个PostgreSQL数据库的备份与恢复策略,考虑到以下需求:RPO为1小时,RTO为4小时,数据量约为500GB,需要支持时间点恢复(PITR)。详细说明你选择的备份类型、工具、频率、保留周期以及恢复测试的关键步骤。
试卷四 (难度:设计级)
一、 选择题 (每题2分,共20分)
-
在PostgreSQL中,哪种索引最适合优化包含多个可选过滤条件(如
WHERE (status = 'active' AND type = 'A') OR (status = 'pending' AND type = 'B')
)的复杂查询?
A. 单独为status和type列创建B-Tree索引
B. 创建一个(status, type)
的复合B-Tree索引
C. 创建多个针对不同条件组合的部分索引
D. 创建一个GIN索引包含status和type列 -
在MongoDB中,如果一个字段的值是一个数组,并且你需要频繁地根据数组中的某个元素值进行查询,应该考虑创建哪种类型的索引?
A. 复合索引 (Compound Index)
B. 多键索引 (Multikey Index)
C. 地理空间索引 (Geospatial Index)
D. 哈希索引 (Hashed Index) -
Alembic的
env.py
文件中target_metadata
变量通常指向什么?
A. 数据库连接字符串
B. Alembic的配置对象
C. SQLAlchemy模型的元数据集合 (如Base.metadata
)
D. 当前数据库的Schema快照 -
HikariCP连接池的
leakDetectionThreshold
参数的主要作用是什么?
A. 检测连接泄露并自动关闭泄露的连接
B. 设置连接池中允许的最大泄露连接数
C. 当连接借出超过设定时间仍未归还时,记录一条警告日志
D. 自动增加连接池大小以应对连接泄露 -
对于PostgreSQL中一个包含
JSONB
类型列的表,如果经常需要查询该JSONB列中特定路径下的值是否等于某个常量(例如WHERE (data->'attributes'->>'color') = 'red'
),以下哪种索引策略最为高效?
A. 对整个JSONB
列创建标准的B-Tree索引
B. 对整个JSONB
列创建GIN索引,并使用@>
操作符查询
C. 创建一个针对表达式(data->'attributes'->>'color')
的函数索引(B-Tree)
D. 创建一个Hash索引在该JSONB
列上 -
在进行数据库零停机迁移,需要修改一个列的数据类型,并且这个修改不向后兼容时,以下哪个步骤最不可能出现在“扩展-收缩模式”(Expand-Contract Pattern)中?
A. 部署能够同时读写新旧列的应用程序代码
B. 添加新列,允许旧列和新列并存一段时间
C. 立即删除旧列,并强制所有应用实例重启
D. 编写数据迁移脚本将旧列数据转换并填充到新列 -
在MongoDB中,设计一个包含用户地址的Schema,如果用户的地址数量非常少(例如最多2-3个),且地址信息总是和用户信息一起被读取,但很少被独立查询或更新,那么最合适的建模方式是?
A. 将地址作为独立集合,并在用户文档中存储地址ID数组(引用)
B. 将地址文档直接嵌入到用户文档的地址数组字段中
C. 为每个地址创建一个独立的用户文档副本
D. 创建一个用户-地址关联集合 -
如果一个SQLAlchemy模型A通过
relationship
与模型B建立了多对多关系,并配置了cascade="all, delete-orphan"
,当从模型A的一个实例的关联集合中移除一个模型B的实例(且该B实例不再被其他A实例引用)并提交session后,通常会发生什么?
A. 模型B的实例在数据库中会被删除
B. 只是解除了A与B之间的关联关系,B实例本身不受影响
C. 会抛出完整性错误,因为delete-orphan
不适用于多对多
D. 模型A的实例会被删除 -
以下哪项关于PostgreSQL的
pg_basebackup
和WAL归档的描述是错误的?
A.pg_basebackup
用于创建数据库的物理基础备份。
B. WAL归档允许将数据库恢复到任意特定时间点 (PITR)。
C. WAL归档与逻辑备份(如pg_dump
)不能同时使用。
D. 要实现PITR,必须有基础备份和从该备份点开始的所有WAL归档文件。 -
在设计数据库Schema时,将货币金额存储为浮点数类型(如
FLOAT
或DOUBLE
)的主要风险是什么?
A. 存储空间占用过大
B. 查询性能下降
C. 可能导致精度丢失和舍入误差累积
D. 不支持负值
二、 判断题 (每题1分,共10分)
- PostgreSQL的GIN索引比GiST索引在更新性能上通常更有优势。 ( )
- MongoDB的
explain()
命令输出中的IXSCAN
表示查询使用了索引。 ( ) - 数据库迁移中的“回滚”操作总能保证100%恢复到变更前的状态,包括所有数据。 ( )
- 在ORM中,
select_inload
(SQLAlchemy) 通常比joinedload
更适合优化一对多关系的N+1问题,因为它避免了主对象的重复。 ( ) - 连接池中的“连接泄露”是指敏感数据通过数据库连接被窃取。 ( )
- PostgreSQL的
VACUUM FULL
操作会阻塞对表的并发读写。 ( ) - 在设计RESTful API时,PUT请求的请求体必须包含资源的完整表示,而PATCH请求只需包含要修改的字段。 ( )
- Alembic的
--sql
选项允许在不实际执行迁移的情况下生成SQL语句。 ( ) - 在Cassandra Schema设计中,为每个查询优化设计单独的表(允许数据冗余)是推荐的做法。 ( )
- 数据库的RTO(恢复时间目标)通常比RPO(恢复点目标)更容易通过技术手段缩短。 ( )
三、 简答题 (每题10分,共50分)
- 讨论在PostgreSQL中,何时应该考虑使用函数索引(Functional Index)和部分索引(Partial Index),并分别举例说明其适用场景。
- 解释SQLAlchemy ORM中
session.add()
,session.commit()
,session.rollback()
,session.flush()
这些核心方法的作用和它们之间的关系。 - 在进行数据库Schema迁移时,如果一个迁移脚本执行失败(例如,因为意外的数据库约束或数据问题),标准的处理流程和最佳实践是什么?
- 分析在高并发场景下,数据库连接池的
maximumPoolSize
参数设置过小或过大分别可能带来哪些问题。并简述一种确定合适值的调优方法。 - 详细解释PostgreSQL中分区表(Partitioning)如何通过“分区裁剪(Partition Pruning)”来提升查询性能,并讨论选择分区键的关键考虑因素。
四、 解答题 (共70分)
- (9分) 假设你有一个PostgreSQL数据库,其中有一个
events
表,包含一个payload
列,类型为JSONB
。payload
中可能包含一个嵌套的键user_info.user_id
(字符串类型)。请写出创建能高效查询特定user_info.user_id
值的GIN索引的SQL语句,并写出一个利用该索引进行查询的示例SQL。 - (9分) 设计一个MongoDB Schema来存储公司组织结构(部门、员工)。一个部门可以有多个子部门和多个员工,一个员工只属于一个部门。需要考虑高效查询某个部门下的所有直属员工和所有子部门。请描述你的Schema设计思路(集合、文档结构、嵌入/引用选择)并简要说明理由。
- (12分) 描述在使用Alembic进行数据库迁移时,如何处理“迁移分支”(当多个开发者并行开发不同功能并都产生了数据库变更)的情况,以及如何最终合并这些分支迁移。
- (12分) 详细阐述在PostgreSQL中,从一个大表(例如,
logs
表,包含数十亿行数据)迁移到分区表的关键步骤和注意事项,特别是在生产环境中如何尽量减少服务中断时间。 - (13分) 假设你的应用需要一个严格符合“恰好一次处理”(Exactly-once Semantics)的消息队列消费者。讨论为什么这在分布式系统中很难实现,并结合数据库(如PostgreSQL)和消息队列(如RabbitMQ或Kafka),设计一种尽可能接近“恰好一次处理”的幂等消费策略,详细描述其关键步骤和所需的技术组件(如事务、唯一ID、状态存储)。
- (15分) 某大型电商系统,其
orders
表(PostgreSQL)数据量巨大,包含了近5年的订单数据。当前,按订单创建时间created_at
范围查询历史订单的性能非常差。请你设计一个全面的优化方案,可以包括但不限于索引策略、分区策略、物化视图应用、查询语句重写等。详细说明你的方案、每个优化点的理由,以及如何验证优化效果。