如何向外行解释产品经理频繁更改需求为什么会令程序员烦恼?读后感

前几天在微信朋友圈中看到了这篇文章,立即就转发了,看完后感触还是很多的。

作者“猫爱吃鱼不吃耗子”,以餐馆点餐为例,说明了定制化产品在研发过程中遇到的种种问题,这些问题,在实际过程中都或多或少的遇到过,但如果在一个产品中,全部遇到,那真是“我日了狗啊”。

这篇文章主要描述的是,一个不懂开发、没有产品经验的需求管理人员(产品经理),在遇到奇葩客户的时候,虽然积极应对需求变更,但忽略了客户的实际需求,没有了解需求后真正的原因,最终产出了看似达到用户需求的产品,但用户各种不满意,开发人员不满意,产品经理各种挫败感。

neohope原创(www.neohope.com)

如果换一个有经验的产品经理,差不多是这个样子的:

你去饭店,坐下来。
“服务员,给我来份宫保鸡丁!”
“好的!我们店的宫保鸡丁做法是。。。”
——————根据客户实际情况,介绍自己的产品,客户越不了解自己的需求,这里越重要,要明白客户要什么,要知道,不少时候客户其实是想要鱼香肉丝。引导用户,搞清楚真正的需求。

服务员:“您是否有其他要求?咸淡?是否加辣?”
“最近没食欲,加点儿辣椒”
“微辣,中辣,还是重辣?”
“中辣好了”
。。。。。。
——————逐步细化用户需求,开工前一定要确认。有经验的产品经理+有经验的用户,这里是最快的,比如用户很可能直接说(“来个宫保鸡丁盖浇饭,只要一半饭,中辣,打包”)。用户没有经验时,这里是要下工夫搞清楚的。

服务员:“要米饭吗?来点儿啤酒不?”
“来两碗米饭,要开车不能喝酒”
。。。。。。
——————了解自己有哪些产品,可以一起卖给客户,组合套餐全家桶

服务员:“现在用餐高峰期,根据您的要求,30分钟之内上齐,加米饭共30元”(其实会预估为20分钟)
“不能快点儿吗,饿了”
“好的,尽量给您催”
——————与用户沟通工期,给自己留余地,取得用户理解(客户催促时,告诉他已经沟通过工期,而且你自己还有一点儿余地可以退让)

厨房:
“宫保鸡丁一份,中辣,不要花椒,米饭两碗,客户要20分钟上齐”
厨师:“好滴”
——————要描述清楚需求,多多沟通

餐厅:
“服务员,我想在菜里加腐竹”
“以前也有客户加腐竹来自,我自己尝过,难吃的要死,要不您来份本店的凉拌腐竹,小碟免费”
“那好啊”
——————要清楚自己的产品线及成本,通过其他案例的经验教训,引导用户到正确的道路上来,提出合理的解决方案。腐竹这类凉菜,相当与公司成熟的小应用,解决具体的实际问题。但要考虑成本的,成本低没问题,但如果客户要个肘子,不好意思,加钱。

餐厅:
“服务员,我要在菜里加花生,去皮的,必须加”
“那我问下厨房”
——————总有新需求无法拒绝,自己清楚的可以许诺,但不清楚的要和研发沟通

厨房:
大厨:“花生去皮要先泡,先吃不上,要不换腰果,但口感不一样,而且要加钱咯”
服务员:“我去问问看,你先别下锅”
——————多方沟通,获取可行解决方案,并进行评估

餐厅:
“花生去皮的话,要多等半小时,我们厨师建议你换腰果试试,就是贵点儿”
“腰果就腰果,还没吃过这样的呢”
“好的,我去说一下”
——————与客户沟通可行方案,但要有主有次,有引导性

餐厅:
“要不我还是要带皮的花生吧”
“对不起,菜已经下锅了,我们大厨说了保证好吃”
“那好吧”
——————客户在某一功能点摇摆不定时,帮助他坚定信念

餐厅:
“上菜咯,外加米饭两碗”
“还不错,上菜挺快,腰果也不错吗”
——————尽量在约定时间内给客户解决问题

在实际做项目的时候,首先要了解清楚用户的实际需求,然后多方进行沟通,避免返工及重复劳动,完成自己对客户的承诺。这才是向合格的产品经理迈进了一大步呢。

其实,真正做项目的时候,都有无法预知的问题,但产品经理就要见招拆招,知道自己的底线在哪里,沟通沟通再沟通,这样才能保证事情顺利进行。

如果任务不可行的时候,那就应该说不可行,宁可不做,也不要把团队带入需求的泥潭。长期在泥潭里,士气会很快低落,人心散了,队伍就没法呆了。

加油吧!

===============================================================
上面说的是定制化产品开发,但大家有没有考虑过成熟产品是如何处理的呢。

你去KFC点餐。
“服务员,给我来个香辣鸡腿堡套餐,打包!”
“好的!”
——————成熟的产品,都是定位特定人群,通过配置而不是开发来达到用户的目的的。其通用性会很高,一半通过搭配,可以解决绝大多数客户的问题。但对于少数用户的奇葩需求并不会处理。而这些也是通过长期的积累,把经验变成了需求,变成了产品的一部分来做到的。

在这里,实施人员成了KFC的配餐员,产品经理是KFC新产品的需求采集人员,研发人员是设计出这些产品的幕后工作者,销售人员是新产品的推广者。

具体情况,大家可以看看Google、MS、亚马逊、阿里的一些开发流程,会发现不少好玩的事情呢。

好啦,先写到这里啦。

如何向外行解释产品经理频繁更改需求为什么会令程序员烦恼?


如何向外行解释产品经理频繁更改需求为什么会令程序员烦恼?
作者:猫爱吃鱼不吃耗子(转自知乎)

你去饭店,坐下来。
“服务员,给我来份宫保鸡丁!”
“好嘞!”
——————这叫原始需求

大厨做到一半。
“服务员,菜里不要放肉。”
“不放肉怎么做啊?”
“不放肉就行了,其它按正常程序做,不就行了,难吗?”
“好的您稍等”
——————中途需求变更

厨房:
大厨:“你大爷,我肉都回锅了”
服务员:“顾客非要要求的嘛,你把肉挑出来不就行了吗”
大厨:“行你大爷”
然而还是一点点挑出来了
——————改动太大,部分重构

餐厅:
“服务员,菜里能给我加点腐竹吗?”
“行,这个应该简单。”
——————低估改动成本

厨房:
大厨:“你TMD,不知道腐竹得提前泡水?炒到一半才说?跟他说,想吃腐竹就多等半天”
服务员:“啊你怎么不早说?”
大厨:“早说你MLGB我怎么知道他要往宫保鸡丁里放腐竹”
然而还是去泡腐竹了
——————新需求引入了新研发成本

餐厅:
“服务员,还是把肉加回去吧”
“您不是刚说不要肉吗”
“现在又想要了”
“…好的您稍等”
——————某一功能点摇摆不定

厨房:
大厨:“日你啊,菜都炒过火了你让我放肉?还好肉我没扔”
服务员:“客户提的要求你日我干嘛?”
大厨:“你就不能拒绝他啊?啊?”
服务员:“人家是客户嘛。”
——————甲方是大爷

餐厅:
“服务员!服务员!”
“来了来了,你好?”
“怎么这么半天啊?”
“稍等我给您催催啊”
——————改动开始导致工期延误

厨房:
大厨:“催你M催,腐竹没泡好,我还得重新放油,他要想吃老的也行,没法保质保量”
——————开发者请求重新排期

餐厅:
服务员:“抱歉,加腐竹的话得多等半天,您别着急哈”
“我靠要等那么久?我现在就要吃,你们能快点吗?”
“行…您稍等”
——————甲方催活

厨房:
大厨:“我日他仙人板板,中途改需求又想按期交付,逗我玩呢?”
服务员:“那我问问,要不让他们换个菜?”
大厨:“再换我就死了”
——————开发者开始和中间人pk

餐厅:
“服务员,这样吧,腐竹不要了,换成蒜毫能快点吗?对了,顺便加点番茄酱”
——————因工期过长再次改动需求

厨房:
大厨:“我日了狗啊,你TM不知道蒜毫也得焯水啊?还有你让我怎么往热菜里放番茄酱啊??”
服务员:“焯水也比等腐竹强吧,番茄酱往里一倒不就行了吗?很难吗?”
大厨:“草。腐竹我还得接着泡,万一这孙子一会又想要了呢。”
——————频繁改动开始导致大量冗余

餐厅:“服务员,菜里加茄丁了没有?我去其它饭店吃可都是有茄丁的”
“好好好您稍等您稍等”
——————奇葩需求

厨房:
大厨:“我去他二大爷他吃的是斯里兰卡三流技校炒的宫保鸡丁吗?宫保鸡丁里放茄丁??”
服务员:“茄丁抄好了扔里边不就行了吗?”
大厨:“那TM还能叫菜吗?哪个系的?”
服务员:“客户要,你就给炒了吧。”
大厨:“MB你顺道问问他腐竹还要不要,我这盆腐竹还占着地方呢不要我就扔了”
——————奇葩你也得做

餐厅:
“服务员,还要多久能好啊”
“很快,很快…”
“再给我来杯西瓜汁。”
“…好”
“我再等10分钟,还不好我就走了,反正还没给钱。”
“很快,很快…”
——————黑暗前的最后黎明10分钟后

“咦,我上次吃的不是这个味啊?”
从厨房杀出来的大厨:“我TM就日了你的狗…”
——————最终决战

——————
你=客户
服务员=客户经理+产品经理
大厨=码农
请自行转换…
——————
注:以上场景已极度夸张,实际生产生活中码农和PM是和睦友好的相亲相爱的一家人
——————
注:对于做2C产品的公司,你=公司大boss

转自知乎,原文链接

产品管理模式演化

==========================================================
最开始的时候,公司产品管理比较混乱,几乎对每一个客户都进行了定制,出现了大量的分支。
后面发现维护成本太高,开始合并各版本之间的功能,但最终仍有十几个版本。

PS:后来公司换了老板,初期很多有经验的研发及实施人员都流失了,很可惜。

==========================================================
2009年,项目比较小,我们采用的是按功能划分的方式进行分工的,经常一个项目就一个人,或一个项目拆为几大块,每人一块来进行。这个模式持续了一段时间。

现在回过头来看这段时间的一些产品,产品功能不多,但需求做的很好,产品定位比较准确,符合客户要求,后期移交其他同事维护后,架构上和界面上都没有大的变化。对于小规模的开发,这种方式还是适用的。

==========================================================
2010年底到2011年,公司开始了电子病历项目的开发,投入了不少的人力。由于项目变的比较复杂,现在变成了十来个人一起扑到一个项目上。第一次引入了需求、测试人员。本人甚至客串了一段时间的美工+前端(惨不忍睹)。

这段时间是架构转型的时间,时间紧任务重,语言也刚开始学,加了很多班,好在项目最终验收了。

后来由于很多原因,整个产品线被砍掉了,又流失了不少人。

==========================================================
2012年,开始了平台项目,初期核心团队不大,产品已经有了原型,加上前面的积累,整个任务还算顺利,但仍然是加了很多班。

架构为简单的SSH,后台逻辑为主,前端现在看来惨不忍睹。

花了很多时间,补充平台应用。

==========================================================
2013年,团队人员增加了很多,引入了MVN,开始有了较好的任务分工,架构变的明晰。

花了很多时间,把其他缺失的部分补上来,逐渐形成了一个产品线。

开始使用快速原型法。

开始引入ESB。

==========================================================
2014年,团队人员再次增加了很多,同时加上很多水平不错的同事加入,有了较好的发展。

开始推进单元测试,产品流程越来越规范,快速原型法使用的越来越多,大量使用交互稿。

很多地方开始务实,产品定位进行了调整,很多项目都开始使用ESB。

部分项目,前后端开始分离。

==========================================================
2015年,团队人员有些变动,核心团队还比较稳定。

开始推进高并发,更加关注代码质量。

补充了很多ESB的接口。

前端团队飞速成长,前后端彻底分离。

==========================================================
顺便说一下,我在2009加入公司时,研发中心除了总监,只有我一个人。初期从其他部门调来几个人员,加上招的一些人,也不足10人,现在研发中心已经接近150了。

致新人,差距是如何产生的(01)

今年,我们组来了很多的java新人(编程经验小于一年的小朋友)。

对于他们,我都会做下面的事情:

1、让他们自己列出自己的知识架构,从而告知其不断积累的重要性

90%的人只用过java语言,只知道SSH。

这里,我会结合他们大学课程、实际经验,给他们补充一部分知识架构,拓展一下视野。

并告诉他们如何去对比的学习新知识,如何找到一种适合自己的学习方式,并要找到适合自己的知识积累方式。

2、以一个很简单的例子,告诉他们应多考虑原理,而不只是用

在一个网站中,在只用了一个框架,比如struts2或spring mvc的情况下,前端登录页面的用户名、密码,是如何发送到后台,并返回验证结果到前台的。

所有人,都直接提到了action如何获取用户名及密码,但只有很少人考虑了,浏览器是如何找到服务器/容器的,也只有很少人知道,容器是如何定位到哪个应用、哪个action的。

然后,会告诉他们,希望他们可以在一年之后,用最复杂的解释,告诉我,这个流程是如何运作的。两年之后,把整个流程变简单,并可以自己去实现一个简单的框架。

3、送给他们一本《程序员的职业素养》,让他们自己去领悟其中的内容

4、探讨他们的职业发展道路

5、开始安排培训,并开始逐步解除新项目

因为,在我看来,程序员在前三年的时候,是个明显的分水岭,所用的学习方式,直接决定了他是程序员还是码农还是该转行。

2015至2016年会讲话

平台组的发言

2015年,对于我们来说是重要的一年。这一年中,一方面,我们积极配合前方的实施团队,力保项目顺利进行。在这里,需要感谢实施组、技术支持组与管理组的同事,给予我们大量的理解与支持(很多现场同事,利用了自己私人的时间,帮我们梳理流程、复现问题、复测程序,陪我们加了很多班),大家帮我们做了太多太多,我就不一一答谢了。我们计划在16年给实施、技术支持组的同事一份大礼,让大家的工作变得更加高效。

另一方面,我们在产品化及服务化方面,进行了大量的工作,并取得了一定的进展。
比如:为了解决横向扩展问题,我们引进了NginX、Redis、消息中间件。让单节点故障对项目的影响降到了最低;再配合虚拟化技术,这样可以更加高效的利用硬件资源;
再比如:为了解决文件检索问题,我们引进了NOSQL技术,(XML数据库、BSON数据库),正在引入大数据存储及计算技术,让互联网的新技术为我们服务,推动我们的产品进步,并最终让技术成为用户的价值。在这里很感谢PACS组同事,向我们分享了很多好的建议,我们有很多好的想法,都是从他们这边来的。
再比如:很感谢视觉设计组+前端组同事,改变了前后台开发的配合方式,帮我们承担了JS+CSS+HTML的调试工作,让后端的程序员专注于后端业务逻辑,让大家去处理各自擅长的事情,大量减少了后端程序员调试JS+CSS的痛苦。

很开心我们组很多同事都有了进步,有些是在技术上有了很大的进步 ,有些人成为团队的主力,有些人已经可以独当一面。这些是一点一滴积累起来的,可能自己还没有意识到。我相信,不积跬步,无以致千里;不积小流,无以成江海。我们做的每一件小事,都是最终引发质变的必要原因;我们遇到的每次困难,都是我们成长的精神食粮。我们真正需要的就是,用心做事,把事做好。不忘初心,方能长久。
我们软件人员大多很内向,话不多。但我感觉在咱们这个大家庭里,充满了温暖。能和各位一步步走来,一起进步,我感觉~真好。

浏览器插件的演化

浏览器插件,主要使用了两种,一种是微软的ActiveX插件,一种是Java Applet。

说实话,两种插件的引入,主要是为了突破浏览器的本地访问限制。而且,很多控件都是内网使用,是自签名的,你懂的。

ActiveX插件,主要用于了调用WindowsAPI,调用本地EXE等。
这种模式,在2013年-2014年,逐步被CS+BS的模式所替代。

Applet插件,主要用于了多线程下载控制,调用JS等。总体来说,JVM对Applet的沙盒控制还是越来越严格了。
在2013年引入了Java Web Star,但效果也一般。

BS架构的演化

==========================================================
2010年下半年,公司开始BS开发,主要语言为java。以Sevlet+JSP为主,只用了Struts1框架。

2011年,引入三大框架Struts2、Hibernate、Spring。

2012年-2013年,以后台通信业务为主,主要使用了Hibernate、Spring。负载均衡采用了APACHE+TOMCAT的方式。

2013年-2014年,引入了Maven及模块式开发,引入了ESB,开始推行单元测试。Struts2逐步切换到SpringMVC,Hibernate逐步切换到MyBatis,并进行了二次封装。

2015年,引入监控机制,版本发布机制,开始抽离SQL语句。引入Reids+Nginx,引入MongoDB,引入消息中间件。

2016年,引入CI,引入eXistDB。

==========================================================
自从2010年开始使用C#以来,也有不少BS项目是C#开发的。

2010年-2014年,主要采用ASPX+ADO.net的开发模式。

2015年,引入了EntityFramwork+MVC的开发模式

2016年,引入单元测试及CI。

CS架构的演化

最开始,公司的CS开发语言,主要有三类:BCB、VC、C#。SVN及自动更新功能已经完善。

2009年,我们组采用的开发工具为VS2008,UI框架为MFC,没有任何框架,为纯Native的C++开发,通过ODBC直连数据库。

2010年,开发工具切换到VS2010,UI框架直接切换到了WPF,程序功能开始进行切分,将后台功能从前端UI分离,封装为Windows服务,但仍然为纯Native的C++开发,仍然通过ODBC直连数据库。

2011年~2014年,个人转战BS,公司CS期间架构相对稳定。

2015年,开始组件式开发,转型很痛苦。

2015年,开始混用CS及BS,将两层CS架构,转换为CBS架构。

2016年,引入应用中间层,将两层CS架构,转换为三层CS架构,开始面向接口编程。

MBP调整硬盘分区(后记)

总结了一下,应该的流程为:

1、在MBP下,用Win7自带功能缩小分区
2、MBP的硬盘取下,调整为移动硬盘,接到虚拟机上,直接Ghost备份
3、MBP硬盘安回去,到MAC下调整分区
4、MBP的硬盘取下,调整为移动硬盘,接到虚拟机上,直接Ghost还原
5、用PE修复Win7的启动项
6、MBP硬盘安回去,就可以进入Win7了
7、进入MAC,备份原装硬盘的数据
8、删除分区
9、进入Win7,扩展分区
10、进入MAC,调整GPT分区表

这样就搞定了,而且不用处理光驱问题。

MBP调整硬盘分区

我的MBP,是2011 Early,如果你体验过它的妖娆,你就懂得,为什么我不想重装。
(安装Win7必须是原装光驱在光驱位)

以前是300G的一块硬盘,后来加了500G的SSD(SSD在硬盘位,原装硬盘在光驱位),在SSD上安装了MAC和Win7。

但最近,MAC盘彻底满了,而Win7的系统盘还有不少空间,于是准备调整一下Win7系统盘的大小。

首先Win7安装了Ghost15,做了个备份,是v2i格式的。

然后重启到MAC系统,删掉Win7分区,用Bootcamp向导平分了整个SSD。

关机,将SSD拿下来,放到移动硬盘盒里,连到另一台笔记本上,准备Ghost回来。

靠,Ghost了两次,都失败了。。。

心里哇凉哇凉的啊。

放回MAC里发现,文件的确可以看得见,但明显不对啊,250G空间,用了200G,还有 150G。

靠,坑爹啊,Windows干脆不认。。。

估计是直接按原来的硬盘分区恢复的,现在硬盘分区变小了,当然放不下,但Ghost大哥,你好歹提示一下啊,欲哭无泪
(如果先把Win7分区缩小,再备份,再还原,应该就可以了)

现在没招了,直接文件恢复吧

直接将v2i备份中的全部文件,还原到新的分区,测试了一下,认不到Win7。

实在不想把光驱恢复,于是想了下,用VMWare,建了个虚拟机,连上移动硬盘,光盘启动。

进入Win7修复界面,

bootrec /FixMbr
...OK

bootrec /FixBoot
...找不到元素

这算啥啊,网上找了下,用diskpart命令将Win7分区设为Active。

bootrec /FixBoot
...ok

bootrec /RebuildBcd
...找不到设备

bcdedit /export C:\bcdbackup
...找不到设备

我靠,你都能看到C盘,你告诉我找不到设备

直接修复启动,还是不行。

疯了。

最后一搏,不用虚拟机,直接将原装光驱换上,光盘启动,修复。
直接提示启动项有问题
修复后重启,好了。

进入系统后,office2010报告无法安装字体文件,直接修复安装,OK。

原装硬盘以前划分了部分空间给MAC,先在MAC系统下数据备份出来,删除分区。
到Windows下,直接扩展了分区。
到MAC下,用gdisk,调整了GPT的分区表。
终于搞定了!

结果,周末没陪老婆,被骂了。。。
哄老婆去了。。。

PS:
1、用老毛桃的PE,换了多个版本,U盘版本无法启动,硬盘版本启动后,找不到设备
2、用一键Ghost,也很挫,硬盘版启动后认不到U盘,U盘版本无法启动
3、其实,虚拟机里,提示过Win7启动项有问题,但我忽略了,否则有可能不需要换光驱
4、下一次可以试一下,直接用虚拟机备份还原,应该前面两个工具就都能用了

此外:
1、Win7驱动有问题,连接移动硬盘后,经常被认成键盘鼠标,移除后就只能强制关机了
2、不知道什么原因,使用iPhone耳机连接后,只有一个声道的声音,而用小米的耳机就有两个声道,不知道哪里的原因,好烦