(根據真實事件改編,情節有所誇張,請勿對號入座。)
這是一個風和日麗的星期五下午,Ben 和 Martin 本應該在 Costa 咖啡館喝一杯下午茶,一起聊聊週末的計劃,然而 PM 的一個微信通知打亂了這一切。原來產品出現了一個bug需要緊急修復,下班之前必須要搞定。兩人收到訊息疾步走回到崗位,也沒了心情去喝剛泡好的咖啡,連忙開啟郵箱檢視問題報告。
開始
Ben:看來這不是一個很大的問題,就是處理一個來自於遠端服務的異常。現在的情況是BFF(backend for frontends)在內部的遠端服務有異常,會將異常直接返回到客戶端,這樣只要一個保單出了問題,前端所有的保單也都沒法用了。
Martin:那怎麼解決?
Ben:感覺可以在異常的地方加一個異常處理。這個涉及到RxJava和Java8的stream特性,我不是太熟悉,要不我們一起Pair吧
Martin:好。
兩人喝了一口炙熱的咖啡,擺好鍵盤滑鼠,開啟了IntelliJ工程。幾分鐘後,這個故障重現了。
Martin:可以重現的故障通常比較好解決。我們在這裡先弄個try…catch試試。 兩人似乎很有信心,然而重啟專案後,故障並沒有按照預期停下來。
Ben:hmm,這裡為什麼停不下來呢?
Martin:可能是RxJava的延遲處理,沒有正確的捕捉到。這樣,你在這裡再寫一個邏輯,然後在這裡設個斷點……
焦急
在這個過程中,Martin只是對著螢幕指指點點,時不時看看手機、在微信上聊聊天。Ben對RxJava並不是很熟悉,他想緊緊跟隨Martin的思路,然而增加多個邏輯以後,依然都不能解決問題。15分鐘已經過去,Ben這時候心生懷疑,是不是哪些地方沒弄對?
Ben:我們理一下思路看看?
Martin:恩,來吧,一起看一下程式碼。
Martin領著Ben一起看了一下程式碼,並且一直在旁邊指點Ben進行單步除錯。由於RxJava的延遲特性,使得斷點很難設定。而丟擲異常的呼叫棧會出現在某些莫名其妙的地方,這讓他們根本不知道把try…catch放在哪裡才能奏效。
Ben:可能是要這樣,在這裡加一個OnError看能不能解決。
看似問題能夠解決,其實是又一次的失敗。在兩人的激烈討論中,時間過得很快,一晃眼已經是1個小時以後,咖啡早已經涼了,然而兩個人完全沒有心情,甚至都忘了咖啡的存在。
Ben對Martin的解決方案越來越沒有信心,兩人開始重新討論起解決方案。然而方案是越討論越複雜,看起來想在下班前解決這個問題是不可能了,通宵是必然了。
簡化
Zen是組裡的Tech Lead,今天在忙另外一個事情。這個週五真是不得安寧,恨不得想到美國去過過昨天。
Zen聽到兩個人的討論,雖然並不瞭解這個問題的細節,但直覺上認為是跑偏了。馬上提醒Ben和Martin:
這不是一個很難的問題,我感覺你們想複雜了?是不是走偏了?能給我說一下你們怎麼想的麼?
被Zen打斷的Martin說了一下之前的解決方案,也說試過了其他的方案了,都不行。由於Zen對這個事情也不是很瞭解,所以只是提了一個醒:
“Keep it simple,別把事情整複雜了。”
兩個人的討論依然在繼續,Ben有點無法跟上Martin的思路,艱難地寫著程式碼,但每次都不對。Pair的氣氛猶如冬日裡冰冷的咖啡一樣凝結,不知道孰是孰非。Ben已經有些不高興,Martin則依然在一旁指指點點但並不動手。
Zen一看錶已經3點鐘了,又插了一句嘴:
Martin,既然你對這個更熟悉,你來操刀吧。你來寫程式碼吧。
可能由於之前的討論過於激烈,Martin反駁Zen:
我們在Pair啊,他對RxJava不熟悉,我應該指導他。我看著他寫就可以了。
Zen說,
你們的解決方案是什麼,給我看看。
解釋了一通以後,Zen也沒有更多的想法,就讓他們繼續吧。但Zen建議道:
在這個緊要的關頭,我們應該改變一下Pair的方式。現在不是教授知識,而是要高效的解決問題。在這種壓力的情境下,你可以直接實現自己的思路,帶著別人飛就好了。
分歧
Martin稍微冷靜了下,拿過鍵盤,繼續開始修復問題。Ben這時候在一旁觀察,也適當的休息一下,之前手忙腳亂的按F8、F9的神經也得以緩和。
Ben:看來還是不行。我們再理一下程式碼吧。
Martin:你說的這些我之前都試過,都不行,要這樣才行。
Ben:我說的是這樣做的,既然我們還沒討論清楚,我們再來看一下程式碼吧。
兩人拿出了紙和筆,對著螢幕一邊畫一邊討論,然而Ben並不認可Martin的方案,說要採用另外個方案。Martin則堅持認為這是一個可行的方案,得試試。Ben拿過鍵盤,準備按照Martin的方案寫程式碼,但心裡面頗為不爽,一直在想說服Martin採用他的方案試試。
怒氣
到此時,時間都已經不知不覺過去兩個小時了,然而問題似乎離真相總是忽遠忽近。兩個人已經疲勞不堪,再加上解決方案的不一致,兩人的言語中開始顯露出一些怒氣。
Zen在執行測試的空檔,打斷了兩人的對話,建議道:
既然大家已經產生了分歧,要不然兩個人分開,各自實現一個,看誰能夠先實現,然後再來討論。
Martin對於Zen並不認同,認為Zen指責他和Ben沒有Pair好。
Zen解釋道:
其實我聽出了兩人意見的不統一,言語中已經有一些怒火,這樣下去Pair的效率很低。首先,大家帶著不爽來幹活,互相質疑。更關鍵的是,解決問題已經用去了兩個多小時,大家都比較疲憊,可以適當休息。我讓你們分開的目的是讓大家冷靜一下,在不受打擾的情況下工作一段時間,可能會不一樣。
冷靜
Martin回到了電腦面前,按照他的思路一步一步做下去。Ben去上了個廁所,倒掉了那杯冷冰冰的咖啡,泡了杯熱茶。回到電腦前專注的重新按照他的思路一步一步走下去。
其實兩個人已經接近了真相,只是這之間不停的對話把注意力消耗殆盡。兩人企圖達到一個統一,然而口頭的對話並不能解決問題,反而暫緩了這個過程。
10分鐘後,Ben興高采烈的說已經搞出來了一套可以執行的方案,叫Martin一同過來看看。Ben的臨時解決方案比較簡單好理解,但並不完美。熟悉RxJava的Martin指出了一些可以改進的地方。
然後兩人又開始了新一輪的Pair,重新將這個方案完善。有了這個基礎的解決方案,兩人都很高興,是朝著一個正確的方向大步向前。
尾聲
下午6點半,雖然比正常下班晚了半個多小時,但還好整個解決方案都正常了,交付的任務也順利完成。
Ben和Martin都總結道,我們應該停止結對,當:
- 兩人的思路不統一但無法說服對方時:我們可以考慮分開一陣,安靜一下,各自用可執行的程式碼來證明思路的可行。這裡只需要相對粗糙的程式碼即可。
- 時間已經超過番茄時間而感到疲憊時:人的專注力是有限的,在Pair時非常累,特別是在能力方面存在較大差距的時候。在這時候我們可以試試番茄工作法,讓大腦得到休息。
- 注意力不集中或者有其他事務要處理時:在Pair的時候,彼此要尊重對方,不要玩手機、看其他無關的網頁,除非事先取得別人的同意,否則就要等到停止結對、處理完事務後再繼續。