Clean Coder – Chương 10 – Ước Lượng

Ước lượng là một trong những điều đơn giản nhất, nhưng đó cũng là công việc đáng sợ nhất mà những lập trình viên chuyên nghiệp phải đối mặt. Có quá nhiều giá trị kinh doanh phụ thuộc vào nó. Có quá nhiều uy tín của chúng ta nằm trên nó. Có quá nhiều sự hối hận và thất bại của chúng ta là do nó. Nó là điểm kết nối chính giữa những người kinh doanh và các lập trình viên. Nó là nguồn gốc của gần như tất cả những mối ngờ vực chi phối mối quan hệ đó.

Vào năm 1978, tôi đang là trưởng nhóm phát triển cho một chương trình nhúng dành cho bộ vi xử lý Z-80 32K được viết bằng ngôn ngữ assembly. Chương trình này được đưa vào 32 con chip EEprom 1K x 8 và 32 con chip này thì được đặt vào 3 bo mạch.

Chúng tôi có hàng trăm thiết bị tại hiện trường, được lắp đặt tại những văn phòng trung tâm điện thoại trên khắp nước Mỹ. Bất cứ khi nào chúng tôi sửa được một bug hoặc thêm một chức năng nào, chúng tôi sẽ phải phái những kỹ thuật viên dịch vụ hiện trường tới từng thiết bị một và họ sẽ thay thế tất cả 32 con chip!

Đây là một cơn ác mộng. Những con chip và bo mạch thì rất dễ vỡ. Các chân trên chip có thể bị cong và gãy. Sự uốn cong liên tục của các bo mạch cũng có thể làm hỏng các mối hàn. Những nguy cơ xảy ra gãy vỡ và lỗi cực nhiều. Chi phí này mà công ty chúng tôi phải gánh là quá cao.

Sếp của tôi, Ken Finder, tới gặp tôi và đề nghị tôi tìm cách khắc phục điều này. Điều ông ấy muốn là cách để khi thay đổi một con chip thì tất cả các con chip còn lại không phải thay đổi. Nếu bạn đã từng đọc các quyển sách của tôi, hoặc đã nghe những bài nói chuyện của tôi, thì bạn đã biết rằng tôi nói rất nhiều về khả năng triển khai độc lập. Đây chính là nơi đầu tiên tôi học được bài học đó.

Vấn đề của chúng tôi là phần mềm đó là một chương trình thực thi liên kết đơn. Nếu chỉ cần một dòng code mới được thêm vào chương trình đó thì tất cả các địa chỉ của những dòng code theo sau sẽ thay đổi. Do mỗi con chip chỉ đơn giản nắm giữ 1K không gian địa chỉ, nên nội dung của hầu như tất cả các con chip sẽ thay đổi.

Vấn đề này khá đơn giản. Mỗi con chip phải được tách biệt khỏi những con chip khác. Mỗi con chip phải trở thành một đơn vị được biên dịch độc lập để nó có thể được nạp độc lập khỏi những con chip khác.

Vì vậy tôi đã đo kích thước của tất cả các function trong ứng dụng đó và viết một chương trình đơn giản để làm vừa khớp chúng, giống như trò chơi ghép hình vậy, trong mỗi một con chip đều để dành 100-byte không gian dự trữ để mở rộng. Tại vùng nhớ đầu của mỗi con chip, tôi đặt một bảng các con trỏ tới tất cả các function trên con chip đó. Lúc khởi động những con trỏ này sẽ được di chuyển vào RAM. Tất cả code trong hệ thống này được thay đổi để các function được gọi thông qua địa chỉ trong RAM và không bao giờ được gọi trực tiếp.

Vâng, bạn đã nắm được rồi đấy. Những con chip này là các đối tượng, với các bảng ảo vtable. Tất cả các function đều được triển khai đa hình. Và vâng, đây là cách mà tôi đã học được một số nguyên lý của lập trình hướng đối tượng, rất lâu trước khi tôi biết đến thế nào là một đối tượng.

Các lợi ích của nó thật to lớn. Không chỉ là việc chúng tôi có thể triển khai trên từng con chip riêng, mà chúng tôi còn có thể tạo ra những bản vá tại hiện trường bằng cách di chuyển các function vào RAM và dẫn lại địa chỉ của chúng. Điều này giúp cho việc debug và vá lỗi nóng dễ dàng hơn nhiều.

Nhưng tôi đã lạc đề. Khi Ken gặp tôi và đề nghị tôi sửa chữa vấn đề này, anh ấy đã đề nghị điều gì đó về các con trỏ tới các function. Tôi đã dành một hoặc hai ngày để hình thành nên ý tưởng và sau đó trình bày với ông ấy với một bản kế hoạch chi tiết. Ông ấy đã hỏi tôi nó mất bao nhiêu thời gian, và tôi đã đáp rằng nó sẽ mất khoảng một tháng.

Thực tế nó đã mất tới ba tháng.

Tôi chỉ có hai lần say xỉn trong cuộc đời mình, và chỉ có một lần thực sự say. Đó là tại bữa tiệc Giáng Sinh tại Teradyne vào năm 1978. Khi đó tôi 26 tuổi.

Bữa tiệc được tổ chức tại văn phòng Teradyne, phần lớn là không gian mở. Mọi người đến đó sớm, và sau đó có một trận bão tuyết lớn đã ngăn cản ban nhạc và người phục vụ ăn uống đến đó. May thay ở đó có rất nhiều rượu.

Tôi không nhớ lắm buổi tối hôm đó. Và điều duy nhất tôi nhớ được thì tôi lại ước tôi sẽ không nhớ. Nhưng tôi sẽ chia sẻ với bạn về khoảnh khắc thấm thía đó của tôi.

Tôi đang ngồi khoanh chân trên sàn nhà với Ken (sếp tôi, khi đó 29 tuổi và không say) nói về chuyện công việc thực hiện cải tiến của tôi sẽ hết bao nhiêu thời gian. Rượu đã giải phóng nỗi sợ hãi và bất an bị dồn nén của tôi về ước lượng của mình. Tôi không nghĩ đầu tôi nằm trong lòng ông ấy nhưng ký ức của tôi không rõ ràng lắm về chi tiết kiểu như vậy.

Tôi nhớ rằng đã hỏi ông ấy rằng ông ấy liệu có phát điên với tôi không và nghĩ thế nào nếu công việc đó kéo quá dài. Mặc dù ký ức buổi tối hôm đó đã lu mờ nhưng lời ông ấy vẫn còn rõ ràng nguyên vẹn trong tôi qua hàng thập kỷ. Ông ấy nói “Có, tôi nghĩ cậu sẽ mất một khoảng thời gian dài, nhưng tôi có thể thấy cậu đang làm việc chăm chỉ về nó, và đang có tiến triển tốt. Đó là điều chúng ta thực sự cần. Vì vậy, không, tôi sẽ không phát điên.”

Ước lượng là gì?

Chúng ta sẽ xem việc ước lượng theo những góc nhìn khác nhau. Khách hàng thì thích quan điểm việc ước lượng như là một lời cam kết. Lập trình viên thì thích quan điểm việc ước lượng chỉ như là một sự phỏng đoán. Sự khác biệt này là rất lớn.

Lời cam kết

Lời cam kết là thứ mà bạn bắt buộc phải đạt được. Nếu bạn cam kết hoàn thành thứ gì đó vào một ngày cụ thể, thì bạn đơn giản là phải hoàn thành nó vào ngày đó. Nếu điều đó có nghĩa là bạn phải làm 12 giờ một ngày, làm cả vào cuối tuần, bỏ qua những kỳ nghỉ với gia đình, thì sẽ phải như vậy. Bạn đã đưa ra cam kết, và bạn phải giữ lời bằng cả danh dự của mình.

Những lập trình viên chuyên nghiệp không đưa ra lời cam kết trừ khi họ biết họ có thể đạt được nó. Nó thực sự đơn giản là như vậy. Nếu bạn được đề nghị cam kết một điều gì mà bạn không chắc bạn có thể làm được, thì danh dự của bạn sẽ bị giảm sút. Nếu bạn được đề nghị cam kết hoàn thành vào một ngày mà bạn có thể đạt được, nhưng lại cần phải làm thêm giờ, làm cuối tuần, và bỏ qua những kỳ nghỉ với gia đình, thì lựa chọn đó là của bạn; nhưng bạn tốt hơn là sẵn sàng làm những gì cần làm.

Lời cam kết phải là điều chắc chắn. Những người khác sẽ chấp nhận lời cam kết của bạn và xây dựng kế hoạch của họ dựa trên lời cam kết đó. Cái giá của việc không giữ cam kết, đối với họ, và cho thanh danh của bạn, là khổng lồ. Việc không giữ cam kết là một hành động không trung thực, nó chỉ nhẹ hơn một chút so với việc nói dối công khai.

Ước lượng

Ước lượng là sự dự đoán. Không bao gồm một cam kết nào. Không một lời hứa nào được đưa ra. Việc ước lượng sai không phải là một điều gì làm mất danh dự. Nguyên nhân chúng ta ước lượng là bởi vì chúng ta không biết một việc gì đó phải làm mất bao nhiêu thời gian.

Không may thay, phần lớn các lập trình viên phần mềm là những người ước lượng tệ. Điều này không phải là do cần phải có một kỹ năng bí truyền nào đó để ước lượng – thực tế là không có kỹ năng nào như vậy. Nguyên nhân chúng ta thường ước lượng rất tệ là bởi vì chúng ta không hiểu được bản chất thực sự của ước lượng.

Ước lượng không phải là một con số. Ước lượng là một sự phân bố xác suất. Bạn hãy xem ví dụ bên dưới:

            Mike:   “Ước lượng của anh để hoàn thành nhiệm vụ của Frazzle như thế nào?”

            Peter:   “Ba ngày nhé.”

Liệu Peter có thực sự sẽ hoàn thành trong ba ngày không? Nó có thể được, nhưng khả năng xảy ra là bao nhiêu? Câu trả lời cho điều đó là: Chúng ta không biết được. Điều gì mà ý Peter muốn nói, và Mike đã biết được điều gì? Nếu Mike trở lại sau ba ngày, cậu ta có ngạc nhiên không nếu Peter vẫn chưa hoàn thành? Tại sao anh ấy lại như vậy? Peter không hề đưa ra một lời cam kết. Peter đã không nói rằng khả năng hoàn thành trong ba ngày so với bốn ngày hoặc năm ngày là bao nhiêu.

Điều gì sẽ xảy ra nếu Mike hỏi Peter khả năng chính xác của ước lượng ba ngày của anh ấy là bao nhiêu?

            Mike:   “Khả năng cậu hoàn thành trong ba ngày là bao nhiêu?”

            Peter:   “Tôi khá chắc chắn.”

            Mike:   “Cậu có thể cho một con số cụ thể được không?”

            Peter:   “Khoảng 50 hoặc 60%”

            Mike:   “Vậy thì nhiều khả năng cậu sẽ mất 4 ngày đấy.”

            Peter:   “Ừ, thực tế thì tôi có thể mất 5 hoặc 6 ngày, nhưng tôi không tin vào điều đó lắm.”

            Mike:   “Cậu không tin vào điều đó khoảng bao nhiêu?

            Peter:   “Ồ, tôi không biết. Tôi chắc chắn 45% là tôi sẽ hoàn thành trước 6 ngày.”

            Mike:   “Ý cậu là có thể mất 7 ngày à?”

            Peter:   “Ừ, chỉ khi mọi thứ đi không đúng thôi. Chết tiệt, nếu mọi thứ đi không đúng, thì tôi có thể mất 10 hoặc thậm chí 11 ngày cũng nên. Nhưng không có nhiều khả năng sẽ xảy ra sai sót như vậy đâu.”

Bây giờ chúng ta bắt đầu phân tích sự thật. Ước lượng của Peter là một sự phân bố xác suất. Trong đầu của anh ấy, Peter thấy khả năng của việc hoàn thành như những gì chỉ ra trong Hình 10-1.

Bạn có thể thấy tại sao Peter đưa ra ước lượng ban đầu là 3 ngày. Đó chính là thanh cao nhất trong biểu đồ. Vì vậy trong tâm trí Peter thì đó là khoảng thời gian thực hiện khả thi nhất cho nhiệm vụ này. Nhưng Mike thì lại thấy thứ khác. Anh ấy nhìn vào phần đuôi bên phải của đồ thị và lo lắng rằng Peter có thể thực sự cần tới 11 ngày để hoàn thành.

Hình 10-1. Biểu đồ phân bố xác suất

Mike có cần phải lo lắng về điều này không? Dĩ nhiên! Luật Murphy[1] cũng có thể xảy ra với Peter, vì vậy điều gì đó cũng có khả năng xảy ra sai sót.

Lời cam kết ngầm

Vì vậy bây giờ Mike có một vấn đề. Anh ấy không chắc chắn về thời gian cần để Peter hoàn thành được nhiệm vụ. Để giảm tối đa sự không chắc chắn đó, anh ấy có thể đề nghị Peter một lời cam kết. Đây là điều mà Peter không có cách nào khác là phải đưa ra.

            Mike:   “Peter, cậu có thể cho tôi một ngày cụ thể khi nào cậu sẽ hoàn thành không?”

            Peter:   “Không được, Mike. Như tôi nói đấy, nó có thể hoàn thành trong 3, cũng có thể là 4 ngày.”

            Mike:   “Chúng ta có thể chốt là 4 ngày không?”

            Peter:   “Không được, nó cũng có thể là 5 hoặc 6 ngày.”

Cho tới lúc này, mọi người đều cư xử một cách ngang bằng. Mike đề nghị một lời cam kết và Peter thì cẩn thận từ chối đưa ra một cam kết cụ thể. Vì vậy Mike đã thử một cách khác:

            Mike:   “OK, Peter, nhưng cậu có thể cố gắng hoàn thành nó trong không quá 6 ngày không?”

Lời của Mike nghe thật chân thành, và Mike chắc chắn là không có ý định xấu nào. Nhưng chính xác điều gì mà Mike đang đề nghị Peter làm? Từ “cố gắng” có nghĩa là gì?

Chúng ta trước đây đã nói về điều này rồi, nó nằm trong Chương 2. Từ “cố gắng” là một từ nặng nề. Nếu Peter đồng ý “cố gắng” thì có nghĩa là anh ấy đang cam kết sẽ hoàn thành trong 6 ngày. Không còn có cách giải thích nào khác được. Đồng ý cố gắng tức là đồng ý hoàn thành.

Liệu có cách giải thích nào khác không? Chính xác là điều gì mà Peter sẽ làm để “cố gắng”? Anh ấy sẽ làm việc hơn 8 tiếng ư? Điều đó rõ ràng đã được ngụ ý. Anh ấy sẽ làm thêm vào cuối tuần ư? Đúng vậy, điều đó cũng đã được ngụ ý. Anh ấy sẽ phải hoãn kỳ nghỉ với gia đình ư? Đúng vậy, đó cũng là một phần của điều ngụ ý. Tất cả những điều này đều là một phần của “cố gắng”. Nếu Peter không làm những điều này, thì Mike có thể buộc tội anh ấy đã không đủ nỗ lực.

Những lập trình viên chuyên nghiệp vạch ra một sự phân biệt rõ ràng giữa ước lượng và lời cam kết. Họ sẽ không cam kết trừ khi họ biết chắc chắn rằng họ sẽ thành công. Họ sẽ cẩn thận không đưa ra bất cứ một lời cam kết ngầm nào. Họ sẽ trình bày về sự phân bố xác suất những ước lượng của họ rõ ràng nhất có thể, để cho người quản lý có thể lập kế hoạch cho phù hợp.

PERT

Năm 1957, PERT (Program Evaluation and Review Technique – Kỹ Thuật Đánh Giá và Ước Lượng Chương Trình) được tạo để hỗ trợ cho dự án tàu ngầm Polaris của hải quân Mỹ. Một trong những thành phần của PERT là cách tính toán ước lượng. Chương trình cung cấp một cách rất đơn giản, nhưng cũng rất hiệu quả để biến đổi các ước lượng thành sự phân bố xác suất phù hợp cho những người quản lý.

Khi bạn muốn ước lượng một nhiệm vụ, bạn cần cung cấp 3 con số. Đây được gọi là phân tích tam biến (trivariate analysis):

  • O: Ước lượng lạc quan (Optimistic Estimate). Con số này là sự lạc quan tối đa. Bạn chỉ có thể hoàn thành được nhiệm vụ nhanh như vậy nếu mọi thứ đều đi đúng hướng. Thực tế là để cho công thức chạy được, con số này phải ít hơn 1% khả năng xảy ra[2]. Trong trường hợp của Peter, nó sẽ là 1 ngày, như thấy ở hình 10-1.
  • N:Ước lượng danh nghĩa (Nominal Estimate). Đây là ước lượng với khả năng cao nhất để thành công. Nếu bạn vẽ một biểu đồ cột, nó sẽ là cột cao nhất, như thấy ở Hình 10-1, nó là 3 ngày.
  • P: Ước lượng bi quan (Pessimistic Estimate). Một lần nữa con số này lại là sự bi quan tối đa. Nó cần phải bao gồm mọi thứ ngoại trừ bão tố, chiến tranh hạt nhân, lỗ đen vũ trụ, và các thảm họa khác. Một lần nữa, công thức toán chỉ chạy được nếu con số này ít hơn 1% khả năng xảy ra. Trong trường hợp của Peter, con số này nằm ngoài biểu đồ ở phía bên phải. Đó là 12 ngày.

Cho ba con số ước lượng này, chúng ta có thể mô tả phân bố xác suất bằng công thức sau:

µ là khoảng thời gian hoàn thành mong đợi của nhiệm vụ. Trong trường hợp của Peter, nó là (1+12+12)/6, hay khoảng 4,2 ngày. Đối với phần lớn các nhiệm vụ, đây sẽ là một con số bi quan bởi vì phần đuôi bên phải của biểu đồ phân bố dài hơn bên phần đuôi bên trái[3].

σ là độ lệch chuẩn[4] của phân bố xác suất đối với nhiệm vụ đó. Nó là phép đo xem sự không chắc chắn của nhiệm vụ là bao nhiêu. Nếu con số này lớn, thì sự không chắc chắn cũng lớn. Đối với Peter thì con số này là (12–1)/6, tương đương với khoảng 1,8 ngày.

Với ước lượng của Peter đưa ra là 4,2/1,8 Mike sẽ hiểu rằng nhiệm vụ này nhiều khả năng sẽ hoàn thành trong vòng 5 ngày nhưng nó cũng có thể mất 6 hoặc thậm chí là 9 ngày để hoàn thành.

Nhưng Mike không chỉ phải quản lý một nhiệm vụ. Anh ấy quản lý một dự án có nhiều nhiệm vụ. Peter có 3 nhiệm vụ phải làm trong danh sách này. Peter đã ước lượng những nhiệm vụ này như chỉ ra ở Bảng 10-1.

Nhiệm vụLạc quanDanh nghĩaBi quanμσ
Alpha13124,21,8
Beta11,5143,52,2
Gamma36,25116,51,3
Bảng 10-1

Có điều gì với nhiệm vụ “Beta”? Có vẻ như Peter khá tự tin về nó, nhưng điều nào đó có thể sai sót khiến cho anh ấy có ước lượng bi quan khá lớn. Mike cần phải hiểu điều này như thế nào? Mike nên lập kế hoạch cho Peter để hoàn thành cả ba nhiệm vụ này như thế nào?

Thực ra, chỉ cần vài phép tính đơn giản, Mike có thể kết hợp tất cả những nhiệm vụ của Peter và có được một phân bố xác suất cho toàn bộ công việc của Peter. Phép toán này rất đơn giản:

Đối với bất cứ chuỗi công việc nào thì khoảng thời gian mong đợi của chuỗi đó đơn giản bằng tổng tất cả các khoảng thời gian mong đợi của các nhiệm vụ trong chuỗi đó. Vì vậy nếu Peter có 3 nhiệm vụ phải hoàn thành, và ước lượng của chúng lần lượt là 4,2/1,8; 3,5/2,2; và 6,5/1,3; thì Peter nhiều khả năng sẽ hoàn thành tất cả ba nhiệm vụ trong khoảng 14 ngày: 4,2 + 3,5 + 6,5.

Độ lệch chuẩn của chuỗi bằng căn bậc hai của tổng bình phương độ lệch chuẩn của các nhiệm vụ. Vì vậy độ lệch chuẩn đối với ba nhiệm vụ của Peter sẽ xấp xỉ bằng 3.

(1,82 + 2,22 + 1,32)1/2 =

(3,24 + 2,48 + 1,69)1/2 =

9,771/2 = ~ 3,13

Con số này cho Mike biết các nhiệm vụ của Peter nhiều khả năng sẽ mất khoảng 14 ngày, nhưng cũng có khả năng mất 17 ngày (1σ) hoặc thậm chí có khả năng mất tới 20 ngày (2σ). Nó có thể còn kéo dài hơn nữa nhưng điều đó gần như không xảy ra.

Quay trở lại bảng ước lượng. Bạn có cảm thấy áp lực để hoàn thành cả 3 nhiệm vụ này trong 5 ngày không? Dù sao thì ước lượng trường hợp tốt đẹp nhất là 1, 1 và 3. Ngay cả các ước lượng danh nghĩa cũng có tổng là 10 ngày. Làm cách nào chúng ta có thể hoàn thành tất cả trong 14 ngày, với khả năng có thể là 17 hoặc 20 ngày? Câu trả lời là sự không chắc chắn trong việc kết hợp các nhiệm vụ đó sẽ bổ sung thêm tính thực tế cho kế hoạch.

Nếu bạn là một lập trình viên có kinh nghiệm, bạn nhiều khả năng đã thấy những dự án đã được ước lượng quá lạc quan, và nó đã kéo dài lâu hơn 3 hoặc 5 lần so với hy vọng ban đầu. Phương pháp PERT đơn giản này đã chỉ ra một cách hợp lý để giúp bạn ngăn ngừa những mong đợi quá lạc quan. Những lập trình viên chuyên nghiệp đều rất cẩn trọng khi đặt ra những ước lượng hợp lý mặc cho những áp lực phải “cố gắng” đi nhanh.

Nhiệm vụ ước lượng

Mike và Peter đang làm một sai lầm nghiêm trọng. Mike thì hỏi Peter mất bao lâu để hoàn thành nhiệm vụ. Peter thì đưa ra những câu trả lời tam điểm thành thực, nhưng còn những ý kiến của các thành viên khác trong nhóm thì sao? Họ có thể cũng có ý kiến khác chứ?

­Tài nguyên để ước lượng quan trọng nhất mà bạn có là những người xung quanh bạn. Họ có thể nhìn thấy điều mà bạn không thấy. Họ có thể giúp bạn ước lượng nhiệm vụ của bạn chính xác hơn bạn tự ước lượng chúng.

Wideband Delphi

Vào những năm 1970, Barry Boehm giới thiệu cho chúng tôi một kỹ thuật ước lượng gọi là “wideband delphi”. Đã có nhiều biến thể của kỹ thuật này trong nhiều năm qua. Một số chính quy, một số không chính quy; nhưng tất cả chúng đều có một điểm chung là: sự nhất trí.

Chiến thuật này rất đơn giản. Một nhóm người tập hợp, thảo luận một vấn đề, ước lượng nhiệm vụ, và lặp lại việc thảo luận và ước lượng cho đến khi họ đạt được sự đồng thuận.

Cách tiếp cận gốc được Boehm đưa ra liên quan đến nhiều việc họp hành và tài liệu, đối với tôi thì nó có quá nhiều nghi thức và lãng phí. Vì vậy tôi thích cách tiếp cận đơn giản ít lãng phí hơn như sau.

Những ngón tay bay

Mọi người ngồi quanh bàn. Nhiệm vụ được thảo luận từng cái một. Đối với mỗi nhiệm vụ thì cần phải thảo luận cả về những nhiệm vụ liên quan, điều gì có thể gây khó khăn hoặc làm phức tạp vấn đế, và cách mà nó có thể được triển khai. Sau đó những người tham gia đặt bàn tay của họ dưới bàn và giơ từ 0 tới 5 ngón tay lên tùy theo họ nghĩ nhiệm vụ sẽ mất bao lâu. Người chủ trì cuộc họp sẽ đếm 1-2-3, và tất cả những người tham gia đưa bàn tay của họ ra cùng một lúc.

Nếu mọi người đều đồng ý, thì họ sẽ tiếp tục nhiệm vụ tiếp theo. Ngược lại họ sẽ tiếp tục thảo luận để xác định xem tại sao họ bất đồng. Họ sẽ lặp lại cho đến khi họ nhất trí.

Sự nhất trí không nhất thiết phải tuyệt đối. Miễn là các ước lượng xấp xỉ nhau là được. Lấy ví dụ, chênh lệch ít giữa 3 và 4 có thể coi là nhất trí. Tuy nhiên nếu mọi người đều giơ 4 ngón tay ngoại trừ một người chỉ giơ 1 ngón tay thì tức là họ sẽ có điều phải bàn.

Thang đo ước lượng đã được quyết định từ lúc bắt đầu cuộc họp. Nó có thể là số ngày để hoàn thành một nhiệm vụ, hoặc có thể là một thang đó thú vị hơn chẳng hạn như “mỗi ngón tay nhân gấp ba” hoặc “bình phương các ngón tay”.

Sự đồng thời khi giơ các ngón tay cũng là điều quan trọng. Chúng ta không muốn ai thay đổi ước lượng của họ dựa trên những gì họ thấy người khác làm.

Planning Poker

Năm 2002, James Grenning đã viết một bài báo thú vị[5] mô tả “Planning Poker”. Đây là một dạng của wideband delphi được dùng phổ biến đến nỗi một vài công ty đã dùng ý tưởng này để làm marketing quà tặng dưới dạng bộ bài planning poker[6]. Thậm chí có cả một web site tên là planningpoker.com để bạn có thể dùng planning poker trên mạng với các nhóm phân tán.

Ý tưởng này rất đơn giản. Mỗi thành viên của nhóm ước lượng, chia các lá bài trên tay với các số khác nhau trên đó. Số từ 0 tới 5 là đủ để thực hiện được tốt, và giúp cho hệ thống này về logic tương đương với cách những ngón tay bay.

Lấy một nhiệm vụ và thảo luận nó. Tại một thời điểm nào đó, người chủ trì cuộc họp sẽ đề nghị mọi người lấy một lá bài. Các thành viên của nhóm lấy ra một lá bài khớp với ước lượng của họ và giữ cho mặt lưng của lá bài hướng ra để không ai có thể nhìn thấy giá trị lá bài của họ. Sau đó người chủ trì nói với mọi người giơ lá bài của họ ra.

Phần còn lại sẽ giống với cách những ngón tay bay. Nếu đồng ý, thì ước lượng đó được chấp nhận. Ngược lại các lá bài sẽ trở về tay người tham gia và mọi người tiếp tục thảo luận nhiệm vụ.

Nhiều “nghiên cứu khoa học” đã được thực hiện để chọn ra được những giá trị lá bài chuẩn trên tay người tham gia. Một vài người còn đi xa tới mức họ còn dùng các lá bài dựa trên chuỗi số Fibonacci. Một số khác còn bao gồm những lá bài thể hiện số vô hạn và dấu hỏi. Cá nhân tôi thì tôi nghĩ năm lá bài đánh nhãn 0, 1, 3, 5, 10 là đủ.

Ước lượng quan hệ

Tôi đã thấy một dạng đặc biệt của wideband delphi vài năm trước nhờ Lowell Lindstrom. Tôi đã khá may mắn nhờ sử dụng cách tiếp cận này với một vài khách hàng và nhóm khác nhau.

Tất cả các nhiệm vụ được viết lên những thẻ mà không đưa ra bất cứ ước lượng nào. Nhóm ước lượng đứng quanh một cái bàn hoặc một bức tường với những tấm thẻ rải rác ngẫu nhiên. Các thành viên trong nhóm không nói, họ đơn giản là bắt đầu sắp xếp các thẻ tương đối với cái khác. Những nhiệm vụ mất nhiều thời gian hơn sẽ được chuyển sang bên phải. Những nhiệm vụ nhỏ hơn được chuyển sang bên trái.

Bất cứ thành viên nhóm nào cũng có thể di chuyển bất cứ tấm thẻ nào vào bất cứ thời điểm nào, ngay cả khi nó đã được di chuyển bởi một thành viên khác. Bất cứ tấm thẻ nào bị di chuyên nhiều hơn n lần thì sẽ bị đặt sang một bên để thảo luận.

Cuối cùng quá trình sắp xếp im lặng dừng lại và cuộc thảo luận có thể bắt đầu. Những bất đồng về việc sắp xếp các tấm thẻ được đưa ra. Buổi họp cũng có thể dành một chút thời gian để thiết kế sơ lược hoặc vẽ tay bộ khung thiết kế của phần mềm để giúp đạt được sự nhất trí.

Bước tiếp theo là vẽ các đường giữa các tấm thẻ để thể hiện kích thước của cái thùng. Những thùng này có thể tính bằng ngày, tuần hoặc điểm. Năm thùng trong chuỗi số Fibonacci (1, 2, 3, 5, 8) là cách làm truyền thống.

Ước lượng tam điểm

Các kỹ thuật wideband delphi hiệu quả khi chỉ lựa chọn một ước lượng danh nghĩa cho một nhiệm vụ. Nhưng như chúng ta đã nói ban đầu, phần lớn các trường hợp chúng ta cần có ba ước lượng để chúng ta có thể tạo ra một phân bố xác suất. Các giá trị lạc quan và bi quan của mỗi nhiệm vụ có thể được tạo ra nhanh chóng bằng cách dùng bất cứ dạng nào của wideband delphi. Lấy ví dụ, nếu bạn đang dùng planning poker, bạn chỉ cần đơn giản đề nghị nhóm giơ ra những lá bài thể hiện ước lượng bi quan của họ và sau đó lấy ra số lớn nhất. Bạn cũng làm tương tự đối với ước lượng lạc quan và lấy ra số thấp nhất.

Định luật những con số lớn

Ước lượng luôn đi kèm với đầy những sai số. Đó là lý do tại sao chúng được gọi là ước lượng. Một cách để kiểm soát những sai số này là tận dụng Định Luật Những Con Số Lớn (Law of Large Numbers[7]). Hàm ý của định luật này là nếu bạn chia nhỏ một nhiệm vụ lớn thành nhiều nhiệm vụ nhỏ hơn thì nó sẽ chính xác hơn là việc ước lượng một lần cho nhiệm vụ lớn đó. Nguyên nhân của việc tăng độ chính xác là do những sai số trong các nhiệm vụ nhỏ có khuynh hướng bù cho nhau.

Thành thực mà nói thì điều này là một sự lạc quan. Sai số trong các ước lượng có khuynh hướng bị đánh giá quá thấp và không phải là bị đánh giá quá cao, nên việc bù lẫn nhau này khó mà chuẩn được. Nói như vậy nhưng việc chia nhiệm vụ lớn thành những nhiệm vụ nhỏ hơn và ước lượng những nhiệm vụ nhỏ đó một cách độc lập vẫn là một kỹ thuật tốt. Một vài sai số sẽ bù lẫn nhau và những nhiệm vụ được chia nhỏ sẽ là một cách tốt để có thể hiểu được nhiệm vụ đó tốt hơn và tìm ra những điều gây bất ngờ.

Kết luận

Các lập trình viên phần mềm biết cách để cung cấp cho khách hàng những ước lượng thực tế mà khách hàng có thể dùng để lập kế hoạch của họ. Họ không đưa ra lời hứa mà họ không thể giữ, và họ không đưa ra lời cam kết mà họ không chắc chắn họ có thể thực hiện được.

Khi những người lập trình viên chuyên nghiệp đưa ra lời cam kết, họ sẽ cung cấp những con số cụ thể, và sau đó thực hiện theo những con số này. Tuy nhiên, trong phần lớn các trường hợp, các lập trình viên không đưa ra những cam kết như vậy. Thay vào đó, họ cung cấp ước lượng theo xác suất thể hiện thời gian hoàn thành mong đợi và những thay đổi có thể xảy ra.

Những lập trình viên chuyên nghiệp làm việc với những thành viên khác trong nhóm của họ để đạt được sự nhất trí về những ước lượng này rồi mới đưa cho người quản lý.

Các kỹ thuật được mô tả trong chương này là những ví dụ về một vài cách khác nhau mà những lập trình viên chuyên nghiệp tính toán ước lượng thực tế. Đây không phải là những kỹ thuật duy nhất đang có và càng không phải là cách tốt nhất. Chúng chỉ đơn giản là những kỹ thuật mà tôi thấy có hiệu quả trong công việc của tôi.

Tham khảo

[McConnell2006]: Steve McConnell, Software Estimation: Demystifying the Black Art, Redmond, WA: Microsoft Press, 2006.

[Boehm81]: Barry W. Boehm, Software Engineering Economics, Upper Saddle River, NJ: Prentice Hall, 1981.

[Grenning2002]: James Grenning, “Planning Poker or How to Avoid Analysis Paralysis while Release Planning, ” April 2002,http://renaissancesoftware. net/papers/14-papers/44-planing-poker.html


[1] Luật Murphy nói rằng nếu cái gì có thể sai thì nó sẽ có lúc sai.

[2] Con số chính xác đối với một phân bố xác suất bình thường là 1:769, hay 0,13%, hoặc 3 sigma. Tỷ lệ một phần nghìn có lẽ là an toàn.

[3] PERT xem đây xấp xỉ với một phân bố beta. Điều này có lý vì khoảng thời gian ít nhất để hoàn thành một nhiệm vụ thường chắc chắn hơn nhiều so với khoảng thời gian lâu nhất.

[4] Nếu bạn không biết độ lệch chuẩn là gì, bạn nên tìm hiểu sơ lược về xác suất và thống kê. Khái niệm này không khó để hiểu, và nó sẽ giúp ích cho bạn rất nhiều.

[5] [Grenning2002]

[6] http://store.mountaingoatsoftware.com/products/planning-poker-cards

[7] http://en.wikipedia.org/wiki/Law_of_large_numbers

Trả lời

Email của bạn sẽ không được hiển thị công khai.