MongoDB 面试题 Q&A
1. 为什么要用 MongoDB?
答:
- 灵活的文档模型:MongoDB 是基于文档的 NoSQL 数据库,采用 BSON 格式存储数据,字段可以是数组、嵌套文档等,非常适合结构不固定或频繁变化的业务场景。
- 高性能:支持嵌入文档,减少了跨表(跨集合)查询,通过索引实现高效查询。
- 高可用:支持副本集(Replica Set),自动故障切换,保证服务持续可用。
- 水平扩展:支持分片(Sharding),可通过添加更多节点来扩展数据量和并发能力。
- 丰富的查询语言:支持复杂的聚合管道、地理空间查询、文本搜索等。
- 开发体验好:面向对象的操作方式,Java 中可以用 POJO 直接映射文档结构。
2. MongoDB 适用于什么场景?
答:
- 内容管理与 CMS 系统:文章、评论、标签等非结构化内容。
- 实时分析日志:物联网设备日志、用户行为日志等。
- 电商产品目录:商品属性不固定(如不同品类有不同规格),适合文档模型。
- 社交应用:用户资料、朋友圈、聊天记录等。
- 缓存层:作为 Redis 的补充,存储较大量但访问频率适中的数据。
- 移动应用后端:适合快速迭代、需求变化频繁的移动端数据存储。
不适合的场景:
- 强事务需求(如银行转账),建议用 MySQL/PostgreSQL。
- 需要跨文档/集合的复杂 JOIN 查询。
3. MongoDB 的默认端口是什么?
答: MongoDB 服务默认监听的端口是 27017。
如果是单节点默认实例,连接字符串类似:
mongodb://localhost:27017
如果是带认证的:
mongodb://username:password@localhost:27017/?authSource=admin
4. MongoDB 和 MySQL 有什么区别?
答:
| 对比维度 | MongoDB | MySQL |
|---|---|---|
| 数据库类型 | NoSQL(文档型) | RDBMS(关系型) |
| 数据模型 | BSON 文档(类似 JSON) | 行与列的二维表 |
| Schema | 灵活,文档结构可以不同 | 固定,需提前定义表结构 |
| 事务支持 | 4.0+ 支持多文档事务,但开销较大 | 原生支持 ACID 事务,更成熟 |
| JOIN 操作 | 不支持传统 JOIN,通过嵌入或 $lookup | 支持标准 SQL JOIN |
| 扩展方式 | 水平扩展(分片)更方便 | 垂直扩展为主,分库分表较复杂 |
| 适用场景 | 灵活结构、快速迭代 | 强一致性、复杂关联查询 |
| SQL 支持 | 使用 MongoDB Query Language (MQL) | 使用标准 SQL |
| 索引 | 支持多种索引类型 | B+Tree 索引为主 |
5. MongoDB 的体系结构都有什么?
答: MongoDB 的体系结构从宏观到微观依次为:
-
Database(数据库)
- 一个 MongoDB 实例可以包含多个数据库。
-
Collection(集合)
- 相当于 MySQL 的 Table,是一组文档的容器。
- 集合中的文档可以有不同的结构(无强制 Schema)。
-
Document(文档)
- 相当于 MySQL 的 Row,以 BSON 格式存储。
- 是 MongoDB 的基本数据单元。
-
Field(域/字段)
- 相当于 MySQL 的 Column。
- 文档中的键值对。
-
其他关键概念:
- BSON:Binary JSON,MongoDB 内部使用的数据序列化格式。
- ObjectId:文档的主键类型,12 字节唯一标识。
- 索引(Index):类似 MySQL,提高查询效率。
- 副本集(Replica Set):实现高可用和数据冗余。
- 分片(Sharding):实现数据的水平分片。
6. MongoDB 的客户端工具你们用的是啥?
答: 常用的 MongoDB 客户端工具有:
-
MongoDB Compass(官方 GUI)
- 图形化界面,支持查询构建、数据可视化、索引管理等,免费版本功能丰富。
-
Navicat for MongoDB
- 商业软件,界面友好,支持数据迁移、图表展示。
-
Robo 3T(原 Robomongo)
- 轻量级免费工具,界面简洁。
-
Studio 3T
- 功能强大的商业客户端,支持 SQL 查询、任务调度等。
-
命令行工具 mongo / mongosh
- Shell 客户端,适合快速调试和脚本执行。
- 新版本推荐使用
mongosh(MongoDB Shell)。
7. 你负责的这块对应的 MongoDB 的集合里都有哪些域?
答: 这是一个根据实际项目来回答的问题,示例如下(假设是用户模块):
{
"_id": ObjectId("..."),
"userId": "U10001",
"username": "zhangsan",
"password": "加密后的密码",
"email": "zhangsan@example.com",
"phone": "13800138000",
"nickname": "小张",
"avatar": "https://xxx.com/avatar.jpg",
"status": 1,
"roles": ["admin", "user"],
"createTime": ISODate("2024-01-01T00:00:00Z"),
"updateTime": ISODate("2024-06-01T12:00:00Z"),
"lastLoginTime": ISODate("2024-06-15T10:30:00Z")
}
回答思路:
- 结合自己负责的业务模块,列出实际集合中的字段。
- 说明每个字段的含义和数据类型。
- 如果文档结构有嵌套或数组,也要说明。
8. MongoDB 的 Java 实体类上最常用的注解叫什么名字?
答:
最常用的注解是 @Document,标注在类上,表示该类对应 MongoDB 中的一个集合。
常用注解一览:
| 注解 | 作用 |
|---|---|
@Document | 标注实体类,对应集合名 |
@Id | 标注主键字段 |
@Field | 标注字段对应的集合域名 |
@Transient | 标注不存储到数据库的字段 |
@Indexed | 标注字段需要建立索引 |
@CompoundIndex | 复合索引 |
@TextIndexed | 全文索引 |
示例:
@Document(collection = "users")
public class User {
@Id
private String id;
@Field("user_name")
private String username;
@Indexed
private String email;
@Transient
private String tempToken; // 不存储到数据库
}
9. MongoDB 用于操作数据的 Java API 类叫什么?
答:
MongoDB 用于操作数据的 Java API 核心类是 MongoTemplate,它是 Spring Data MongoDB 提供的模板类,封装了 CRUD 操作。
常用 API 类/接口:
| 类/接口 | 作用 |
|---|---|
MongoTemplate | 核心操作类,提供 CRUD、聚合等方法 |
MongoRepository | Spring Data 风格的 Repository 接口 |
Query | 构建查询条件 |
Update | 构建更新操作 |
Criteria | 构建查询条件 |
Aggregation | 构建聚合管道 |
示例:
// 使用 MongoTemplate
Query query = new Query(Criteria.where("username").is("zhangsan"));
User user = mongoTemplate.findOne(query, User.class);
// 使用 Repository
public interface UserRepository extends MongoRepository<User, String> {
User findByUsername(String username);
}
总结:在实际 Spring Boot 项目中,MongoTemplate 功能更灵活,MongoRepository 开发更快捷,两者结合使用是常见做法。