Evidence Based Scheduling - 2
Obsessive-compulsive disorder[15] not required
What do you do about the boss who interrupts you all the time with long-winded[16] stories about his fishing trips? Or the sales meetings you’re forced to go to even though you have no reason to be there? Coffee breaks? Spending half a day helping the new guy get his dev environment set up?
When Brett and I were developing this technique at Fog Creek, we worried a lot about things that take real time but can’t be predicted in advance. Sometimes, this all adds up to more time than writing code. Should you have estimates for this stuff too, and track it on a time sheet?
不需要有強迫症
你的老闆總是喋喋不休他的釣魚記,你總是被強迫去參加你根本不需要去的銷售會議?下午茶呢?還是花上半天的時間幫助新人設定他的開發環境?…當Brett跟我在開發Fog Creek時,我們很困擾於這些令人分神的事情無法事前預知,而且這些"小事"加總起來都已經超過寫code的時間了,我們也應該把這些時間也加總到我們的實際工時去嗎?
Well, yeah, you can, if you want. And Evidence Based Scheduling will work.
But you don’t have to.
It turns out that EBS works so well that all you have to do is keep the clock running on whatever task you were doing when the interruption occurred. As disconcerting[17] as this may sound, EBS produces the best results when you do this.
是啊,你可以這麼做,如果你想要的話。而且,EBS一樣可以用。
但是你不需要真的這麼做。
EBS只要求你一件事:「確保時鐘不停歇」。也就是在執行工項的實際耗時,有確實被記錄下來,不管有什麼中斷或打擾插入。僅管這聽起來有點不合理,但EBS就是能產生最好的預測結果。
Let me walk you through a quick example. To make this example as simple as possible, I’m going to imagine a very predictable programmer, John, whose whole job is writing those one-line getter and setter functions that inferior[18] programming languages require. All day long this is all he does:
讓我給你展示一個很簡單的範例。為了說明這個案例,我們來假設一個很有生產力,估計時程能力很好的工程師叫做John,他今天的工作就是要把以下的源碼寫完:
private int width;
public int getWidth () { return width; }
public void setWidth (int _width} { width = _width; }
I know, I know… it’s a deliberately[19] dumb example, but you know you’ve met someone like this.
Anyway. Each getter or setter takes him 2 hours. So his task estimates look like this:
好好,我知道,這完全就是一個刻意為之的傻範例,但你也知道,你就是有機會碰上這種鳥事。基本上這段程式很容易預估會耗時多久,所以他的工時資料會是這樣分布的:
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, … }
Now, this poor guy has a boss who interrupts him every once in a while with a two-hour conversation about marlin fishing. Now, of course, John could have a task on his schedule called “Painful conversations about marlin,” and put that on his timesheet, but this might not be politically prudent[20]. Instead, John just keeps the clock running. So his actual times look like this:
鳥事發生了。這可憐的傢伙被老闆叫住,"談"了2小時關於怎麼釣馬林魚的對話。當然,John可以在實際的耗時工作表上記下「關於馬林魚的痛苦的2小時」,但這可能不是個很厚道的職場禮儀。所以,在「確保時鐘不停歇」的前提下,他的實際工時就是這樣分布的:
{2, 2, 2, 2, 4, 2, 2, 2, 2, 4, 2, … }
And his velocities are:
所以他的速度分布變成是這樣:
{1, 1, 1, 1, 0.5, 1, 1, 1, 1, 0.5, 1, … }
Now think about what happens. In the Monte Carlo simulation, the probability that each estimate will be divided by 0.5 is exactly the same as the probability that John’s boss would interrupt him during any given feature. So EBS produces a correct schedule!
接下來讓我們看看會發生什麼事。在蒙地卡羅模擬中,每個工項都有機率會除以0.5的速度(工時就變成2倍),而這件事確實就是有機率,在John的任何一個工項中發生。因此在多次模擬的結果下,EBS正確的產出了受影響的時程預估。
In fact, EBS is far more likely to have accurate evidence about these interruptions than even the most timesheet-obsessive developer. Which is exactly why it works so well. Here’s how I explain this to people. When developers get interrupted, they can either
make a big stink[21] about putting the interruption on their timesheet and in their estimates, so management can see just how much time is being wasted on fishing conversation, or
make a big stink about refusing to put it on their timesheet, just letting the feature they were working on slip, because they refuse to pad their estimates which were perfectly correct with stupid conversation about fishing expeditions to which they weren’t even invited,
… and in either case, EBS gives the same, exactly correct results, no matter which type of passive-aggressive[22] developer you have.
事實上,EBS比那些最執著於耗時表的工程師,還要能表達出這些中斷干擾造成的影響。它之所以能運作的這麼準確,這裡有兩個解釋可以跟人們說明。當開發者被干擾的時候,他們通常會有這兩個反應:
對這些干擾大肆抱怨,然後將干擾造成的耗時成本記入耗時表,讓管理層知道討論釣魚這件事浪費了開發者多少時間。
對這些干擾大肆抱怨,但堅持不將這些干擾造成的耗時成本記入耗時表,然後就讓他們的工項規格開天窗。因為他們不想要讓那個愚蠢的釣魚故事(對話),破壞原本完美估計地好好的時程。
所以,不管是哪一種反應,EBS都會給出一致正確的預估結果,不管是多消極反抗的工程師都一樣。
4) Manage your projects actively
Once you’ve got this set up, you can actively manage projects to ship on time. For example, if you sort features out[23] into different priorities, it’s easy to see how much it would help the schedule if you could cut the lower priority features.
更積極地管理你的專案
一但你可以把這些事情都設置的很好,你可以更積極的管理你的專案,讓交付更為準時。例如,若是你可以對所有功能都給予優先權,並予以排序,把低重要度的功能放下,你就可以很輕鬆的讓時程壓力更小。
You can also look at the distribution of possible ship dates for each developer:
當然,你也可以回頭看一下每個開發者的交付日期分布在哪裡:
Some developers (like Milton in this picture) may be causing problems because their ship dates are so uncertain: they need to work on learning to estimate better. Other developers (like Jane) have very precise ship dates that are just too late: they need to have some of their work taken off their plate. Other developers (me! yay!) are not on the critical path at all, and can be left in peace[24].
有些開發者(像圖中的Milton)可能就是會造成交付日期不穩定的因子,因為他的交付時程太不穩定了,他需要做更好的預估。其他的開發者(像是Jane)雖然有準確的交付日期預估,但她的日期根本就確定會造成整個產品的delay,我們需要拿掉一些她的工項。再看看另一個開發者(就是我啦),他似乎不在關鍵路徑(Critical Path)上,那我們就可以不用特別管他了。
Scope creep [25]
Assuming you had everything planned down to the last detail when you started work, EBS works great. To be honest, though, you may do some features that you hadn’t planned. You get new ideas, your salespeople sell features you don’t have, and somebody on the board of directors comes up with a cool new idea to make your golf cart GPS application monitor EKGs[26] while golfers are buzzing around[27] the golf course. All this leads to delays that could not have been predicted when you did the original schedule.
範疇蔓延
假設你把所有的事情都計劃的很詳盡,EBS當然可以運作的很好。但老實說,你一定就是會有東西不是事先就可以規劃得到的。總是會有新的想法,不論是來自你自己或是董事會的總監想出來的。也總是會有銷售人員"賣"出了你根本沒有的功能,甚至會有人異想天開地要求要在高爾夫球車的app上,新增可以監控跑來跑去的球手的心電圖。這些都是會導致專案交付日期延遲的事情,而且都不是你原來的預估中可以事前計劃到的。
Ideally, you have a bunch of buffer for this. In fact, go ahead and build buffer into your original schedule for:
New feature ideas
Responding to the competition
Integration (getting everyone’s code to work together when it’s merged)
Debugging time
Usability testing (and incorporating[28] the results of those tests into the product).
Beta tests
So now, when new features come up, you can slice off[29] a piece of the appropriate buffer and use it for the new feature.
理想情況下,你會需要準備一些緩衝空間(buffer)來應付這些狀況。沒錯,實務上就是有這個需求。儘管去保留一些緩衝空間吧,因為實際上就是會用在這些地方:
新的功能和想法
對競品的應對措施
實作整合(就是把大家寫好的東西合併起來)
除錯
可用性測試(以及把最終的結果整合到產品身上)
上市前測試(Beta Test)
所以一但有一些新的狀況出現,你就可以把準備好的緩衝時間,一塊塊切下來應付這些臨時的需求。
What happens if you’re still adding features and you’ve run out of buffer? Well, now the ship dates you get out of[30] EBS start slipping. You should take a snapshot of the ship date confidence distribution every night, so that you can track this over time:
如果你已經用完了緩衝時間,還一直加入新的功能要實作的話,會發生什麼事?嗯,當然你EBS估計的日期會開始跑掉。這時你該做的,就是每晚把EBS重新估算的交付日期圖給快照一份下來,這樣你可以不斷的追蹤其變化:
The x-axis is when the calculation was done; the y-axis is the ship date. There are three curves here: the top one is the 95% probability date, the middle is 50% and the bottom is 5%. So, the closer the curves are to one another, the narrower the range of possible ship dates.
If you see ship date getting later and later (rising curves), you’re in trouble. If it’s getting later by more than one day per day, you’re adding work faster than you’re completing work, and you’ll never be done. You can also look and see if the ship date confidence distribution is getting tighter (the curves are converging), which it should be if you’re really converging[31] on a date.
X軸是每天重新估算EBS的時間點,Y軸是EBS預估的交付日期。因為EBS估算出來的交付日期是一個「區間」,而這個區間中的每個時間點都有「成真率」。上圖目前有三條線,意思是說同一天重新估算EBS,就可以得到這個區間中三個可能的交付日期,假設最上面的「成真率」是95%(也就是說,在2007年5月到6月間第一次重新估算EBS時,最有可能的交付日期是在2008年9月左右),中間的成真率是50%,最下面是5%。所以,在不同的時間重新估算EBS時,得到的區間不同,曲線的聚合程度不同,所以若是曲線彼此間越是靠近,就代表EBS重新估算出來的交付日期區間越小。
我們可以看到,在2007年7月由EBS重新估算出來的交付日期,在2009月1月有95%的成真率,在2008年11月有50%,在2008年3月有5%,這個區間有10個月;比起2007年5月左右,EBS重新估算得到的交付區間是2007年11月到2009年6月的19個月相比,幾乎差了3個「季」那麼多(不是3個月)。
如果你看到交付日期越來越晚(曲線越來越徒),你就知道你麻煩大了。如果你估算出來的交付時程結果總是一天比一天晚,就代表你增加工項的速度超過你能做完的速度,所以你是永遠都趕不上,也做不完的。反過來看,如果就像上圖所述,不同成真率呈現的區間範圍越來越小,曲線越靠越近,那就代表你越來越有足夠的信心,確信能趕得上最終估算出來的交付時程。
While we’re at it
Here are a few more things I’ve learned over the years about schedules.
Only the programmer doing the work can create the estimate. Any system where management writes a schedule and hands it off to programmers is doomed to fail. Only the programmer who is going to implement a feature can figure out what steps they will need to take to implement that feature.
Fix bugs as you find them, and charge the time back[31] to the original task. You can’t schedule a single bug fix in advance, because you don’t know what bugs you’re going to have. When bugs are found in new code, charge the time to the original task that you implemented incorrectly. This will help EBS predict the time it takes to get fully debugged code, not just working code.
Don’t let managers badger[32] developers into shorter estimates. Many rookie software managers think that they can “motivate” their programmers to work faster by giving them nice, “tight” (unrealistically short) schedules. I think this kind of motivation is brain-dead. When I’m behind schedule, I feel doomed and depressed and unmotivated. When I’m working ahead of schedule, I’m cheerful and productive. The schedule is not the place to play psychological games.
當我們在實作EBS的時候
這裡有一些這幾年我在建立時程預估時學到的事:
只有實際要做這件事的程式設計師可以決定「預估耗時」。任何由管理層寫好,拿來要求程式設計師的時程,一定是準備爆炸的版本。只有要實作這個功能的程式設計師才能搞懂,做這個功能需要的所有步驟。
當找到問題(bug)的時候,就馬上修正它,而且要把這段時間回饋到原工項的耗時去。因為你不知道會遇到什麼問題,自然你不能預先排出修正問題所需的耗時。發現問題並把時間回加到原先預估的耗時,才能幫助EBS預估出完整除錯後的源碼,而不是「只是會動」的版本。
別讓管理者要求開發者開出更短的耗時預估。許多新手管理者會天真的以為,訂出更緊密的(通常就是不合理的)時程,可以"激勵"開發者有更快的開發效率,我認為這完全是腦子壞掉才想得出來的"激勵"法。當我無法趕上時程的時候,我只會覺得我把事情搞砸了,而且會很沮喪,完全沒有"被激勵"的效果。只有當我一切順利,比原訂的時程更快時,我才會感到愉悅,也更有生產力。時程預估不是拿來玩心理遊戲的。
Why do managers try this?
When the project begins, the technical managers go off[33], meet with the business people, and come up with a list of features they think would take about three months, but which would really take twelve. When you think of writing code without thinking about all the steps you have to take, it always seems like it will take n time, when in reality it will probably take more like 4n time. When you do a real schedule, you add up all the tasks and realize that the project is going to take much longer than originally thought. The business people are unhappy.
Inept[34] managers try to address this by figuring out how to get people to work faster. This is not very realistic. You might be able to hire more people, but they need to get up to[35] speed and will probably be working at 50% efficiency for several months (and dragging down the efficiency of the people who have to mentor them).
You might be able to get 10% more raw code out of people temporarily at the cost of having them burn out 100% in a year. Not a big gain, and it’s a bit like eating your seed corn[36]. Of course, when you overwork people, debugging time doubles and a late project becomes later. Splendid karma.
But you can never get 4n from n, ever, and if you think you can, please email me the stock symbol for your company so I can short it.
為什麼管理者會嘗試這麼做?
當專案開跑之後,技術管理者也開始會見一些商務人員,然後會聽到一系列的需求,此時他們就會開出一系列"他認為"可以3個月完成的功能,但實際上會花12個月。當你沒有想過實際上開發這個功能所需要經過的所有步驟時,你以為花費的時間是n,但實際上它可能耗時達4n的時間。而當你真的把這些工項搞清楚了,也把所需耗時的時程搞清楚了之後,比你一開始預計更長的時程,這件事就會讓商務人員開心不起來了。
無能的管理者可能會嘗試讓開發者做的更快,來解決這個問題,而這完全是不切實際的。他們也許會僱用更多的人,但這些新人要達到可以"全速運行"之前,大概會有幾個月的時間只能有50%的開發效率(而且他們還會把其他人的開發效率給拉下來,因為要指導這些新人…)。
就算你要求這些開發者全年加班,也只能暫時得到額外10%的源碼產出,沒什麼太大的效果,只是寅吃卯糧罷了。當然,當你要求開發者加班趕工,你還會額外獲得加倍的除錯時間,以及延遲的更嚴重的交付時程。多美好的業力啊,簡直就是惡性循環。
所以,你絕對不可能讓開發效率從n變成4n,如果你覺得你辦得到,請告訴我你公司的股票代碼,好讓我去放空你的公司。
4) A schedule is a box of wood blocks. If you have a bunch of wood blocks, and you can’t fit them into a box, you have two choices: get a bigger box, or remove some blocks. If you wanted to ship in six months, but you have twelve months on the schedule, you are either going to have to delay shipping, or find some features to delete. You just can’t shrink the blocks, and if you pretend you can, then you are merely depriving yourself of[37] a useful opportunity to actually see into the future by lying to yourself about what you see there.
Now that I mention it, one of the great benefits of realistic schedules is that you are forced to delete features. Why is this good?
Suppose you have two features in mind. One is really useful and will make your product really great. The other is really easy and the programmers can’t wait to code it up (”Look! !”), but it serves no useful purpose.
If you don’t make a schedule, the programmers will do the easy/fun feature first. Then they’ll run out of time, and you will have no choice but to slip the schedule to do the useful/important feature.
If you do make a schedule, even before you start working, you’ll realize that you have to cut something, so you’ll cut the easy/fun feature and just do the useful/important feature. By forcing yourself to chose some features to cut, you wind up[38] making a more powerful, better product with a better mix of good features that ships sooner.
時程就是一個要裝下所有木塊的箱子
如果你有一些大小不一的木塊,發現無法全部裝進一個箱子裡,你只有兩個選擇:找一個更大的箱子,不然就是減少要放進去的木塊。如果你想要在6個月後交付產品,但你有12個月份的工作要做,要嘛你不是要讓交付日期開天窗,要嘛你就是要砍掉一些功能別做。你無法做到的就是把木塊縮小,而且若你以為你可以,你只是用謊言在欺騙自己,喪失一個能展望未來的好機會。
就像剛剛提的,一個真實可靠的時程能帶給你最大的好處就是,它可以強迫你去砍掉一些功能別做。可這有什麼好的?
如果在你心中有兩個功能都很重要,一個是真正有用,能讓你的產品變得偉大的功能,另一個則是很簡單,開發者也很喜歡的"閃亮(很炫)"功能,但它並沒有辦法為產品帶來更大的價值。
此時,如果你沒有訂好時程,工程師就會先去做那個簡單或有趣的功能。他們在順手完成功能的同時,也會"順手"花光僅有的時間。此時你幾乎沒有選擇,只能讓時程開天窗,補做那些真正有用或該做的功能。
如果你有確實訂好時程,甚至可以在動工之前,就可以理解你必須準備砍掉一些規格。所以你會先拿那些簡單/有趣的規格開刀,然後專心做那些有用/重要的規格。籍由強迫你自己去砍掉一些規格,你最終會更快的,真正的創建出更多有用功能,更好的產品。
Way back when I was working on Excel 5, our initial feature list was huge and would have gone way over schedule. “Oh my!” we thought. “Those are all super important features! How can we live without a macro editing wizard?”
As it turns out, we had no choice, and we cut what we thought was “to the bone” to make the schedule. Everybody felt unhappy about the cuts. To make people feel better, we told ourselves that we weren’t cutting the features, we were simply deferring them to Excel 6.
As Excel 5 was nearing completion, I started working on the Excel 6 spec with a colleague, Eric Michelman. We sat down to go through the list of “Excel 6” features that had been punted[39] from the Excel 5 schedule. Guess what? It was the shoddiest[40] list of features you could imagine. Not one of those features was worth doing. I don’t think a single one of them ever was. The process of culling features to fit a schedule was the best thing we could have done. If we hadn’t done this, Excel 5 would have taken twice as long and included 50% useless crap features that would have had to be supported, for backwards compatibility, until the end of time.
回到當時我們還在做Excel 5的時候,一開始我們開出來的功能,所需要的時間就遠超過時程非常多。「天啊!這些都是超級重要的功能啊,我們怎麼可以沒有巨集編輯精靈!?」
當然,當時我們沒有選擇,我們只能把想做的功能清單砍到見骨,來符合上市的時程需求。每個人都很不開心,為了讓大家心理好受一點,我們跟大家說,我們並不是"砍掉"這些功能,我們只是把這些"驚喜"延到Excel 6再做。
當Excel 5告一段落後,我開始跟同事Eric Michelman坐下來,好好討論Excel 6的功能規格,尤其是那些被我們剔除的那些。你猜怎麼著?Excel 6的功能清單和Excel 5想做的相比,簡直是寒酸到不行。但是,沒有任何一個Excel 5當時覺得「一定要有」的功能,值得加到Excel 6,我們很確定沒有任何一個值得花時間去做。當時回頭去砍掉那些"重要"功能的過程,肯定是我們在做Excel 5的過程中最重要的一件事,如果我們沒這麼做,Excel 5肯定會比預期的時間多出2倍的時間,而且還會含入50%沒有的垃圾規格,更別說後續還要繼續支援,或是要解決相容性問題之類的。
Summary
Using Evidence-Based Scheduling is pretty easy: it will take you a day or two at the beginning of every iteration to produce detailed estimates, and it’ll take a few seconds every day to record when you start working on a new task on a timesheet. The benefits, though, are huge: realistic schedules.
Realistic schedules are the key to creating good software. It forces you to do the best features first and allows you to make the right decisions about what to build. Which makes your product better, your boss happier, delights your customers, and—best of all—lets you go home at five o’clock.
總結
使用「證據式時程」是蠻容易的一件事:只要花個一、兩天,在每個工項開始執行的前後,都確實的產出預估和實際的耗時。而這麼做的回報非常非常大:一個真實的時程估計。
真實的時程估計,是創建好軟體產品的關鍵。它能讓你先做最好的功能,決定該先做什麼功能,因此能讓你的產品更好,讓你的老闆更快樂,也讓你的顧客更開心,最重要的是,能讓你準時在5點下班回家。
a striking or amusing remark.↩︎
a fit of giggles: something or someone that provokes amusement ↩︎
good-humored cheerfulness↩︎
post-mortem: an examination of a dead body to determine the cause of death.↩︎
extremely amusing.↩︎
bang for the buck: More value for one's money, a greater return on an investment.↩︎
pain in the butt: A nuisance; a source of trouble or annoyance.↩︎
grouch: voice one's discontent ill-temperedly; grumble.↩︎
careless and unsystematic; excessively casual.↩︎
hand-wavy: Hand-waving (with various spellings) is a pejorative label for attempting to be seen as effective.↩︎
of little depth↩︎
wind up with: to end up having someone or something.↩︎
take into account someone: To think about, consider, or keep in mind someone or something regarding the future.↩︎
done with or employing great care and thoroughness↩︎
obsessive-compulsive disorder: a common mental health condition where a person has obsessive thoughts and compulsive behaviours↩︎
(of speech or writing) continuing at tedious length.↩︎
To frustrate (plans, for example) by throwing into disorder; disarrange.↩︎
Low or lower in order, degree, or rank.↩︎
Done with or marked by full consciousness of the nature and effects; intentional:↩︎
Careful or wise in handling practical matters.↩︎
make or raise a great deal of trouble; 大吵大鬧; 惹事生非↩︎
passive-aggressive: 消極反抗↩︎
sort out: arrange things systematically in groups or according to type.↩︎
leave someone in peace: To not bother someone or something. ↩︎
refers to changes, continuous or uncontrolled growth in a project’s scope, at any point after the project begins. 範疇蔓延↩︎
EKG: Electrocardiography; 心電圖↩︎
buzz around: to move around quickly↩︎
take in or contain (something) as part of a whole; include.↩︎
slice off: to remove (something) by cutting↩︎
get out of: contrive to avoid or escape a duty or responsibility.↩︎
chargeback: A chargeback is a return of money to a payer of some transaction, especially a credit card transaction.↩︎
repeatedly ask (someone) to do something↩︎
go off: (of a gun, bomb, or similar device) explode or fire.↩︎
having or showing no skill; clumsy.↩︎
get up to: be involved in something, especially something illicit or surprising.↩︎
eat the seed corn: a desparate measure, since it only postpones disaster.↩︎
deprive of: to take (something) away from (someone or something)↩︎
wind up: to bring to a conclusion↩︎
To cease doing something; give up: ↩︎
shoddy: Of poor quality or craft.↩︎