程序员也要学会说不:如何与产品经理相处(附 Spring Boot 实战避坑指南)
大家好,我是阿哲,211计算机专业研二在读,同时也是个写了三年技术博客的“老油条”。今天这篇教程有点特别——它不是教你怎么写代码,而是教你怎么在不撕破脸的前提下,优雅地对产品经理说“不”。
你可能会问:“这和简历、面试题挑战、Spring Boot 有啥关系?”
别急,等你看到最后就会明白:会写代码只是基础,会沟通才是高阶技能。尤其是在校招面试中,越来越多公司开始问“你有没有和产品/测试起过冲突?你怎么处理的?”这种软技能问题。
更现实的是:如果你连需求都接不住,天天被产品经理当“人肉编译器”使唤,那你的 Spring Boot 写得再漂亮,简历上也只配写“CRUD 工程师”。
所以,本文将从实战角度出发,用一个真实的 Spring Boot 小项目为例,手把手教你:
- 如何识别不合理需求
- 如何用技术语言“反杀”模糊需求
- 如何在代码层面设置“防火墙”
- 最后,还能顺手写出一段能放进简历的亮点项目!
一、为什么程序员必须学会“说不”?
我当初实习时,遇到一个产品经理,张口就来:“这个功能很简单,加个按钮就行。”
结果点开需求文档,发现要改三个微服务、加两个审批流、还要兼容五年前的老数据格式。
新手误区:不敢拒绝,怕显得“不配合”、“技术不行”。
真相:产品经理往往不懂技术边界,他们只关心“能不能做”,而你要负责“值不值得做”、“怎么做才合理”。
记住一句话:你不是需求接收器,你是解决方案提供者。
二、环境准备:别让工具成为你的借口
要演示“如何用技术反制不合理需求”,我们先搭个最小可用环境。
所需工具清单:
| 工具 | 版本建议 | 用途 |
|---|---|---|
| JDK | 17+ | Java 运行环境 |
| Maven | 3.8+ | 依赖管理 |
| IntelliJ IDEA | 最新版 | 开发 IDE |
| Postman | 任意 | 接口测试 |
创建 Spring Boot 项目(5 分钟搞定)
- 访问 https://start.spring.io
- 选择:
- Project: Maven
- Language: Java
- Spring Boot: 3.2.x
- Dependencies: Spring Web, Spring Data JPA, H2 Database
- 点击 “Generate” 下载 ZIP,解压后用 IDEA 打开
⚠️ 新手常见错误:用错 JDK 版本导致启动失败。Spring Boot 3.x 要求 JDK 17+,别再用 JDK 8 了!
三、核心概念:用技术语言“翻译”产品需求
产品经理常说的话:
- “用户点一下就能看到所有数据”
- “这个功能明天上线”
- “就改一点点,很快的吧?”
你的应对策略:把模糊需求转为可量化、可验证、有边界的技术任务。
举个栗子 🌰
产品说:“我们要做一个‘一键导出用户数据’的功能。”
听起来简单?但你要立刻反问:
- 导出哪些字段?(字段清单)
- 数据量多大?(100 条还是 100 万条?)
- 导出格式?(Excel / CSV / JSON?)
- 是否需要权限控制?
- 超时怎么处理?失败要不要重试?
如果产品答不上来——恭喜你,需求不完整,不能开发!
四、实战项目:用 Spring Boot 做一个“防坑型”导出接口
我们就以“用户数据导出”为例,写一个自带防御机制的接口。
第一步:定义清晰的数据模型
// User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private LocalDateTime createdAt;
// getters and setters
}
第二步:限制导出范围(关键!)
绝对不要写 SELECT * FROM user!
这是新手最容易踩的坑——产品没说数量,你就默认全量导出,结果数据库直接被打挂。
// UserService.java
public List<User> exportUsers(int limit) {
if (limit > 1000) {
throw new IllegalArgumentException("单次导出不得超过1000条");
}
return userRepository.findTopLimit(limit);
}
// UserRepository.java
public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u ORDER BY u.id LIMIT :limit")
List<User> findTopLimit(@Param("limit") int limit);
}
第三步:接口设计——明确契约
// UserController.java
@GetMapping("/export")
public ResponseEntity<byte[]> exportUsers(
@RequestParam(defaultValue = "100") Integer limit
) {
try {
List<User> users = userService.exportUsers(limit);
byte[] csvData = convertToCsv(users); // 自行实现 CSV 转换
return ResponseEntity.ok()
.header("Content-Disposition", "attachment; filename=users.csv")
.body(csvData);
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().build();
}
}
第四步:写清楚接口文档(甩锅神器)
在代码注释或 Swagger 中明确写:
/**
* 导出用户数据
* @param limit 最大导出条数,默认100,上限1000
* @return CSV 格式字节流
* @throws 400 当 limit > 1000 或 < 1
*/
💡 职场技巧:只要接口文档写清楚了,产品再说“怎么不能导10万条?”,你就回:“看文档第3行。”
五、进阶:把“说不”变成简历亮点
你以为这就完了?不!你可以把这段经历写进简历:
项目名称:用户数据安全导出系统
技术栈:Spring Boot 3 + JPA + H2
亮点:
- 设计带限流的导出接口,防止全表扫描导致 DB 雪崩
- 通过参数校验 + 清晰文档,减少 80% 的模糊需求返工
- 支持 CSV 格式,兼容 Excel 打开
看,你不仅写了代码,还解决了协作问题——这比“用 Redis 做缓存”更有故事性!
六、常见问题 & 避坑指南
❓Q1:产品经理非要我做“不合理”的事怎么办?
答:不要直接说“不做”,而是提供替代方案。
比如:“全量导出会拖垮数据库,我们可以改成异步导出,用户提交后邮件通知下载链接,您看行吗?”
❓Q2:需求评审时怎么提意见才不显得杠精?
答:用“风险+成本”说话。
模板:“这个方案技术上可行,但需要额外 3 天开发 + 可能影响现有支付流程,建议分两期做。”
❓Q3:面试被问“和产品冲突怎么办”怎么答?
答:讲一个你成功引导需求的故事。
比如:“上次产品要实时统计在线人数,我建议用定时聚合代替实时查询,性能提升10倍,产品也接受了。”
✅ 重点:体现你有技术判断力 + 沟通能力 + 结果导向
七、学习建议:下一步该学什么?
深入 Spring Boot 异常处理
学会统一返回格式,让前端/产品知道“哪里错了”,而不是看到 500 Internal Error。掌握 Swagger/OpenAPI
自动生成接口文档,让产品自己看参数要求,少来找你问。了解领域驱动设计(DDD)
学会用“限界上下文”划分系统边界,从根本上避免“这个功能很简单”的陷阱。刷“软技能”面试题
在 LeetCode 刷算法的同时,也准备几个“跨团队协作”的案例,写在简历“项目经验”里。
结语:你不是工具人,你是技术决策者
我当初学 Spring Boot 时,以为只要代码跑起来就行。直到被产品经理连续三天凌晨打电话催上线,才发现:技术只是手段,沟通才是生产力。
下次当产品再说“就改一点点”时,请微笑着打开你的接口文档,指着那行 limit <= 1000 说:
“亲,不是我不做,是代码不允许呀~”
记住:会写代码的人很多,但能让产品尊重技术边界的人,才是真正的工程师。
作者简介:阿哲,211 CS 研究生,专注 Spring Cloud 与分布式系统,已帮助 300+ 新人拿到大厂 Offer。关注我的博客,回复“简历模板”,送你一份含“协作能力”描述的 Java 简历范例。

评论 0