Lưu trữ cho từ khóa: lập trình

Clean Coder – Phụ Lục A – Công Cụ

Vào năm 1978, tôi đang làm việc tại Teradyne trong hệ thống kiểm tra điện thoại mà tôi đã mô tả trước đây. Hệ thống này có khoảng 80 nghìn dòng code ngôn ngữ assembly M365. Chúng tôi lưu giữ source code trên những cuộn băng từ.

Những cuộn băng từ này tương tự như các cuộn băng ca nhạc stereo 8 bài rất phổ biến trong những năm 70. Cuộn băng này là một vòng lặp vô hạn, và đầu đọc băng chỉ có thể di chuyển theo một hướng. Các cuộn băng này có độ dài 10’, 25’, 50’, và 100’. Băng càng dài thì nó càng mất nhiều thời gian để “tua lại” do đầu đọc băng phải di chuyển nó về phía trước đến khi nó tìm được “điểm nạp”. Một cuộn băng 100’ mất 5 phút để đi tới điểm nạp, vì vậy chúng tôi phải lựa chọn chiều dài của các cuộn băng rất thận trọng[1].

Về mặt logic, các cuộn băng được chia thành những file. Bạn có thể có nhiều file trên một cuộn băng nếu nó chứa vừa. Để tìm một file, bạn phải nạp cuộn băng và sau đó tiến dần qua từng file cho đến khi bạn tìm thấy file bạn muốn. Chúng tôi giữ một danh sách thư mục source code trên tường để chúng tôi có thể biết được bao nhiêu file cần được bỏ qua cho đến khi chúng tôi tới được file mong muốn.

Có một cuộn băng chủ 100’ chứa bản copy của source code trên một giá trong phòng thí nghiệm. Nó được dán nhãn MASTER. Khi chúng tôi muốn sửa một file, chúng tôi nạp cuộn băng nguồn MASTER này vào một đầu đọc và một cuộn băng 10’ trống vào một đầu đọc khác. Chúng tôi tìm trên cuộn băng MASTER cho đến khi chúng tôi tới được file cần. Sau đó chúng tôi copy file đó sang cuộn băng trống đó. Rồi chúng tôi “tua lại” cả hai cuộn băng và đặt lại cuộn MASTER trở lại giá.

Có một danh sách thư mục đặc biệt của cuộn MASTER nằm trên bảng thông báo trong phòng thí nghiệm. Mỗi khi chúng tôi tạo một bản copy của những file chúng tôi cần chỉnh sửa, chúng tôi lại đặt một ghim màu lên bảng ngay cạnh tên của file đó. Đó là cách chúng tôi check out file!

Chúng tôi chỉnh sửa các cuộn băng trên một màn hình. Phần mềm chỉnh sửa văn bản của chúng tôi, ED-402, thực sự là rất tốt. Nó rất giống với vi[2]. Chúng tôi phải đọc một “trang” trong cuộn băng, chỉnh sửa nội dung, và sau đó ghi trang đó ra và đọc trang tiếp theo. Một trang thông thường dài khoảng 50 dòng code. Bạn không thể nhìn phía trên cuộn băng để biết được những trang nào đang tới, và bạn cũng không thể quay lại cuộn băng để xem trang nào bạn vừa chỉnh sửa. Vì vậy chúng tôi đã dùng các danh sách.

Quả thực là chúng tôi phải đánh dấu các danh sách của chúng tôi với tất cả những thay đổi chúng tôi muốn thực hiện, và sau đó chúng tôi chỉnh sửa file theo như danh sách đó. Không ai ghi hoặc chỉnh sửa code trực tiếp tại đầu cuối! Bởi đó là tự sát.

Một khi những thay đổi được thực hiện cho tất cả các file cần phải chỉnh sửa, chúng tôi kết hợp những file này với cuộn băng MASTER để tạo ra một cuộn băng làm việc. Đây là cuộn băng chúng tôi dùng để chạy biên dịch và các bài test.

Một khi chúng tôi hoàn tất kiểm tra và chắc chắn những thay đổi của chúng tôi đều hoạt động, chúng tôi nhìn vào bảng. Nếu không có ghim nào mới trên bảng thì chúng tôi chỉ cần dán nhãn lại cuộn băng đang dùng là MASTER và bỏ ghim trên bảng của chúng tôi xuống. Nếu đã xuất hiện ghim mới trên bảng, chúng tôi sẽ bỏ ghim của chúng tôi đi và trao cuộn băng đang dùng của chúng tôi cho người đã gắn ghim mới lên bảng. Họ sẽ phải thực hiện việc kết hợp.

Ba bọn tôi, mỗi người có một màu ghim riêng, vì vậy chúng tôi có thể dễ dàng biết ai đang kiểm tra file nào. Và do tất cả chúng tôi đều làm việc tại cùng một phòng và luôn trao đổi với nhau nên chúng tôi luôn nhớ được trạng thái của tấm bảng đó trong đầu mình. Vì vậy thường thì tấm bảng đó khá thừa thãi, và chúng tôi không sử dụng nó thường xuyên lắm.

Các công cụ

Ngày nay các lập trình viên phần mềm có rất nhiều công cụ để lựa chọn. Phần lớn đều không đáng để động tới, nhưng cũng có vài công cụ mà mọi lập trình viên phần mềm bắt buộc phải thành thạo. Chương này sẽ mô tả bộ công cụ cá nhân hiện tại của tôi. Tôi không thực hiện một cuộc khảo sát toàn diện về tất cả các công cụ có ngoài đó, vì vậy đây không nên xem như một đánh giá toàn diện. Nó chỉ đơn giản là những thứ tôi đang dùng.

Quản lý source code

Khi nghĩ tới quản lý source code, các công cụ mã nguồn mở luôn luôn là sự lựa chọn tốt nhất của tôi. Tại sao? Bởi vì chúng được viết bởi các lập trình viên và dành cho các lập trình viên. Các công cụ mã nguồn mở là thứ các lập trình viên viết cho chính họ khi họ cần sử dụng một công cụ nào đó.

Ngoài ra, cũng có một số ít một số hệ thống quản lý source code phiên bản “enterprise”, thương mại và đắt đỏ. Tôi thấy những công cụ này không để bán cho các lập trình viên mà chủ yếu để bán cho những người quản lý, những người điều hành, và các “nhóm công cụ”. Danh sách chức năng của chúng rất ấn tượng và hấp dẫn. Không may thay, chúng thường không có những chức năng mà các lập trình viên thực sự cần. Đứng đầu trong đó là tốc độ.

Hệ thống quản lý source code “enterprise”

Có thể công ty của bạn đầu tư một khoản ngân sách nhỏ vào một hệ thống quản lý source code “enterprise”. Nếu như vậy, tôi xin chia buồn. Có lẽ về mặt chính trị sẽ không thích hợp nếu bạn đi xung quanh và nói với mọi người rằng “Bác Bob nói là không nên dùng nó.” Tuy nhiên, có một giải pháp dễ dàng.

Bạn có thể lấy source code của bạn trong hệ thống “enterprise” đó vào cuối mỗi chu kỳ (chu kỳ hai tuần hoặc tương tự) và dùng một trong những hệ thống mã nguồn mở ở khoảng giữa mỗi chu kỳ. Điều này giúp cho mọi người đều vui vẻ, bạn không vi phạm bất cứ quy định nào của tổ chức, và vẫn giữ cho năng suất của bạn được đảm bảo.

Khóa bi quan Vs Khóa lạc quan

Khóa bi quan dường như là một ý tưởng tốt vào những năm 80. Sau cùng thì cách đơn giản nhất để kiểm soát các vấn đề về việc cập nhật đồng thời là hãy xếp nối tiếp chúng. Vì vậy nếu tôi chỉnh sửa một file, bạn tốt hơn hết là không. Quả thực là hệ thống các ghim màu sắc mà tôi đã dùng vào cuối những năm 70 là một dạng của khóa bi quan. Nếu có một ghim ở một file nào đó thì bạn không được chỉnh sửa file đó.

Dĩ nhiên, khóa bi quan cũng có vấn đề của nó. Nếu tôi khóa một file và sau đó đi du lịch thì những người khác muốn chỉnh sửa file đó sẽ bị ách tắc. Quả thực, ngay cả nếu tôi chỉ khóa file đó trong một hoặc hai ngày, thì như vậy cũng đủ để làm trễ những người khác cần thay đổi.

Các công cụ của chúng ta bay giờ đã tốt hơn rất nhiều trong việc kết hợp các file source code được chỉnh sửa cùng lúc. Nó thực sự đáng kinh ngạc nếu bạn suy nghĩ về nó. Các công cụ đó nhìn vào hai file khác nhau và vào file gốc của hai file đó, và sau đó chúng dùng nhiều thuật toán để tìm ra cách kết hợp những thay đổi đồng thời đó. Và chúng làm công việc đó khá tốt.

Vì vậy kỷ nguyên của khóa bi quan đã kết thúc. Chúng ta không cần phải khóa file khi chúng ta lấy source code về nữa. Chúng ta hoàn toàn không phải bận tâm tới việc lấy từng file đơn lẻ về nữa. Chúng ta chỉ việc lấy source code của cả hệ thống và chỉnh sửa bất cứ file nào mà chúng ta cần.

Khi chúng ta sẵn sàng đưa những thay đổi của chúng ta vào hệ thống, chúng ta sẽ thực hiện một quá trình “cập nhật”. Nó sẽ nói cho chúng ta xem có ai đó khác đã đưa source code mới vào trước chúng ta không, nó tự động kết hợp các thay đổi, tìm những xung đột, và giúp chúng ta làm nốt công việc kết hợp còn lại. Sau đó chúng ta commit phần code đã kết hợp lên hệ thống.

Tôi sẽ có nhiều điều để nói về vai trò mà các bài test tự động và hệ thống tích hợp liên tục CI tham gia cùng với quy trình này sau trong chương này. Vào lúc này, tôi chỉ muốn nói là chúng ta không bao giờ được đưa code vào hệ thống nếu nó chưa vượt qua được tất cả các bài test. Không bao giờ được làm như vậy.

CVS/SVN

Một hệ thống quản lý source code đã cổ là CVS. Nó khá tốt khi được dùng trước đây nhưng không còn phù hợp đối với những dự án ngày nay. Mặc dù nó rất tốt trong việc xử lý những file và thư mục riêng lẻ, nhưng nó không được tốt trong việc đổi tên file hoặc xóa thư mục. Và… Thôi, nói càng ít về nó thì càng tốt.

Subversion SVN, mặt khác, thì hoạt động rất tốt. Nó cho phép bạn lấy về toàn bộ source code chỉ với một thao tác. Bạn có thể dễ dàng cập nhật, kết hợp, và đưa code lên hệ thống. Nếu bạn không làm việc với các nhánh thì hệ thống SVN khá đơn giản để quản lý.

Rẽ nhánh

Mãi đến năm 2008, tôi đã tránh tất cả từ dạng đơn giản nhất của việc rẽ nhánh. Nếu một lập trình viên tạo ra một nhánh, thì nhánh đó phải được mang trở lại nhánh chính trước khi kết thúc chu kỳ làm việc. Quả thực là tôi khắt khe về việc rẽ nhánh đến nỗi rất hiếm khi thực hiện rẽ nhánh trong các dự án mà tôi tham gia.

Nếu bạn đang dùng SVN, thì tôi vẫn nghĩ đó là một chính sách tốt. Tuy nhiên, có một vài công cụ mới đã thay đổi cuộc chơi hoàn toàn. Chúng là các hệ thống quản lý source code phân tán. Trong đó, git là hệ thống quản lý source code phân tán ưa thích của tôi. Hãy để tôi nói với bạn về nó.

git

Tôi bắt đầu dùng git vào cuối năm 2008, và nó đã thay đổi mọi thứ về cách mà tôi thường quản lý source code. Hiểu được tại sao công cụ này lại là một thứ thay đổi cuộc chơi như vậy thì nằm ngoài phạm vi của cuốn sách này. Nhưng việc so sánh Hình A-1 và Hình A-2 có thể đáng với vài từ mà tôi không định nói ra ở đây.

Hình A-1 chỉ ra những gì được phát triển trong vài tuần đối với dự án FitNesse khi mà nó vẫn được quản lý bởi SVN. Bạn có thể nhìn thấy hiệu quả của quy định không rẽ nhánh khắt khe của tôi. Chúng tôi chỉ đơn giản là không rẽ nhánh. Thay vào đó, chúng tôi thực hiện việc cập nhật, kết hợp, và đẩy code vào nhánh chính rất thường xuyên.

Hình A-1. FitNesse dưới sự quản lý của Subversion
Hình A‑2. FitNesse dưới sự quản lý của git

Hình A-2 chỉ ra những gì được phát triển trong vài tuần của cùng dự án đó nhưng dùng git. Như bạn có thể thấy, chúng tôi rẽ nhánh và kết hợp code ở mọi nơi. Đây không phải là bởi tôi buông lỏng chính sách không rẽ nhánh của tôi; mà nó đơn giản trở thành cách rõ ràng và thuận tiện nhất để làm việc. Các lập trình viên riêng lẻ có thể tạo ra những nhánh rất ngắn và sau đó kết hợp chúng với code của những người khác.

Cũng lưu ý rằng bạn không thể thấy một nhánh chính thực sự. Đó là bởi vì không có cái nào như vậy. Khi bạn dùng git thì không có thứ gì được gọi là kho chứa trung tâm, hoặc nhánh chính. Mỗi lập trình viên giữ một bản copy của toàn bộ lịch sử của dự án trên máy tính cục bộ của họ. Họ check in và check out bản copy cục bộ đó, và sau đó kết hợp nó với những người khác khi cần.

Sự thực là tôi có giữ một kho chứa đặc biệt mà tôi đẩy tất cả các phiên bản đã phát hành và các bản build tạm thời vào đó. Nhưng để gọi kho chứa này là nhánh chính sẽ là một điểm thiếu sót. Nó thực sự chỉ là một bản sao thuận tiện toàn bộ lịch sử mà mỗi lập trình viên lưu cục bộ mà thôi.

Nếu bạn không hiểu điều này, thì cũng không sao. git là thứ khá khó hiểu ban đầu. Bạn phải làm quen với cách nó làm việc. Nhưng hãy để tôi nói với bạn điều này: git, và các công cụ tương tự như vậy sẽ là tương lai của quản lý source code.

IDE/Trình soạn thảo

Là những lập trình viên, chúng ta dùng thời gian nhiều nhất để đọc và chỉnh sửa code. Các công cụ chúng ta dùng cho mục đích này đã thay đổi lớn lao qua nhiều thập niên. Một số hết sức mạnh mẽ, và một số chỉ thay đổi chút ít so với những năm 70.

vi

Bạn sẽ nghĩ rằng những ngày dùng vi làm trình soạn thảo code chính đã qua từ lâu. Ngày nay có rất nhiều công cụ vượt xa vi, và các trình soạn thảo văn bản đơn giản giống như nó. Nhưng sự thực là vi đã được sử dụng phổ biến lại đáng kể bởi sự đơn giản, dễ dùng, tốc độ, và linh hoạt của nó. vi có thể không mạnh mẽ như Emacs, hay eclipse, nhưng nó vẫn là một trình soạn thảo nhanh và mạnh mẽ.

Phải nói rằng, tôi không phải là một người dùng vi nhiều nữa. Đã có thời gian tôi được biết đến như là một “thánh” vi, nhưng những ngày đó đã trôi qua lâu rồi. Thỉnh thoảng tôi vẫn dùng vi nếu tôi cần phải chỉnh sửa nhanh một file văn bản. Tôi thậm chí gần đây vẫn còn dùng nó để sửa nhanh các file source code Java trong môi trường làm việc từ xa. Nhưng lượng code thực sự mà tôi đã viết bằng vi trong 10 năm gần đây là rất nhỏ.

Emacs

Emacs vẫn là một trong những trình soạn thảo mạnh mẽ nhất hiện nay, và có lẽ sẽ vẫn duy trì như vậy trong nhiều thập niên tới. Mô hình lisp bên trong của nó đảm bảo cho điều đó. Là một công cụ chỉnh sửa đa mục đích, không có công cụ nào khác có thể làm được như nó. Nhưng mặt khác, tôi nghĩ Emacs không thể thực sự cạnh tranh được với các IDE chuyên dụng hiện đang thống trị. Việc sửa code không phải là một công việc chỉnh sửa đa dụng.

Vào những năm thập niên 90, tôi đã là một tín đồ của Emacs. Tôi đã định không dùng bất cứ thứ gì khác nữa. Các trình soạn thảo trỏ-và-nhấn ngày nay là các món đồ chơi đáng cười mà không một lập trình viên nào sử dụng một cách nghiêm túc. Nhưng vào đầu thập niên 00, tôi đã được giới thiệu IntelliJ, lựa chọn IDE hiện tại của tôi, và tôi sẽ không bao giờ phải hối tiếc.

Eclipse/IntelliJ

Tôi là một người dùng IntelliJ. Tôi yêu nó. Tôi dùng nó để viết Java, Ruby, Clojure, Scala, Javascript, và nhiều ngôn ngữ khác. Công cụ này được viết bởi những lập trình viên hiểu những lập trình viên cần gì khi viết code. Trải qua nhiều năm, họ hiếm khi làm tôi thất vọng và hầu như luôn luôn làm tôi hài lòng.

Eclipse cũng tương đương về sức mạnh và phạm vi như IntelliJ. Cả hai đơn giản là bước nhảy vọt và trên tầm Emacs khi nói đến code Java. Cũng có những IDE khác trong danh mục này, nhưng tôi sẽ không đề cập chúng ở đây bởi vì tôi chưa có trải nghiệm trực tiếp với chúng.

Các chức năng mà đặt những IDE này trên tầm những công cụ như Emacs bao gồm các cách cực kỳ mạnh mẽ trong việc giúp bạn thao tác với code. Trong IntelliJ, lấy ví dụ, bạn có thể trích xuất một superclass từ một class với chỉ một lệnh. Bạn có thể đổi tên biến, trích xuất các method, và chuyển đổi kế thừa thành composition, ngoài ra còn nhiều chức năng tuyệt vời khác.

Với những công cụ này, việc sửa code không còn chỉ là thao tác với dòng và ký tự mà nó còn gồm nhiều thao tác phức tạp khác. Thay vì nghĩ về những ký tự tiếp theo và những dòng mà bạn cần phải gõ, thì bạn hãy nghĩ về những chuyển đổi mà bạn cần phải thực hiện tiếp theo. Nói ngắn gọn, mô hình lập trình đã cực kỳ khác và có năng suất rất cao.

Dĩ nhiên, sức mạnh này cũng đi với cái giá của nó. Để sử dụng thành thạo được những IDE này sẽ cần nhiều thời gian và thời gian thiết lập môi trường cho một dự án cũng không ít. Những công cụ này cũng không hề nhẹ. Chúng cần rất nhiều tài nguyên máy tính để chạy.

TextMate

TextMate là một trình soạn thảo nhẹ và mạnh mẽ. Nó không thể thực hiện những thao tác tuyệt vời như IntelliJ và Eclipse có thể làm. Nó không có engine lisp và thư viện mạnh mẽ như Emacs. Nó không có được tốc độ và sự nuột nà như vi. Nhưng nó lại có ưu điểm là thời gian làm quen ngắn, và các thao tác làm việc trực quan.

Tôi thỉnh thoảng vẫn sử dụng TextMate, đặc biệt là khi code C++. Tôi sẽ dùng Emacs cho một dự án C++ lớn, nhưng tôi sẽ không cần phải bận tâm tới Emacs cho những nhiệm vụ ngắn code C++ mà tôi có.

Theo dõi vấn đề

Hiện tại tôi đang dùng Pivotal Tracker. Nó là một hệ thống gọn gàng và đơn giản để sử dụng. Nó rất phù hợp với Agile/cách tiếp cận vòng lặp. Nó cho phép tất cả các bên và các lập trình viên giao tiếp với nhau nhanh chóng. Tôi rất hài lòng với nó.

Đối với các dự án rất nhỏ, tôi thỉnh thoảng dùng Lighthouse. Nó rất dễ dàng và nhanh chóng để thiết lập và sử dụng. Nhưng các chức năng của nó không đủ mạnh để theo dõi vấn đề.

Tôi cũng đơn giản dùng wiki. Các wiki tốt cho các dự án nội bộ. Chúng cho phép bạn thiết lập bất cứ kế hoạch nào mà bạn muốn. Bạn không bị buộc phải theo một quy trình nhất định hoặc một cấu trúc cứng nhắc. Chúng rất dễ hiểu và dễ dùng.

Đôi khi hệ thống theo dõi vấn đề tốt nhất tất cả chỉ là một bộ thẻ và một bảng thông báo. Bảng thông báo được chia thành các cột như “Cần Làm”, “Đang Thực Hiện”, và “Hoàn Thành”. Các lập trình viên chỉ đơn giản di chuyển những tấm thẻ từ cột này sang cột bên cạnh khi thích hợp. Quả thực, đây có thể là hệ thống theo dõi vấn đề phổ biến nhất được dùng bởi các nhóm agile ngày nay.

Lời khuyên tôi đưa ra cho các khách hàng là hãy bắt đầu với một hệ thống thủ công bằng bảng thông báo trước khi bạn mua một công cụ theo dõi. Một khi bạn làm chủ được hệ thống thủ công này, thì bạn sẽ có kiến thức bạn cần để lựa chọn ra một công cụ thích hợp. Và quả thực lựa chọn phù hợp có thể chỉ đơn giản là tiếp tục dùng hệ thống thủ công này.

Đếm bug

Các nhóm lập trình viên chắc chắn cần một danh sách các vấn đề để làm việc. Những vấn đề này bao gồm các nhiệm vụ mới và các chức năng cũng như các bug. Đối với bất cứ một nhóm cỡ vừa nào (từ 5 tới 12 lập trình viên) thì kích thước của danh sách đó có thể từ vài chục cho tới vài trăm. Nếu không phải là hàng nghìn.

Nếu bạn có tới hàng nghìn bug, thì tức là có gì đó đang sai sai. Nếu bạn có hàng nghìn chức năng và/hoặc các nhiệm vụ thì cũng tức là có gì đó đang sai sai. Nói chung thì danh sách các vấn đề cần phải tương đối nhỏ, và do đó mới có thể quản lý được với một công cụ nhẹ như wiki, Lighthouse hoặc Pivotal Tracker.

Có một vài công cụ thương mại có vẻ như khá tốt. Tôi đã nhìn thấy một vài khách hàng dùng chúng nhưng vẫn chưa có cơ hội để làm việc với chúng trực tiếp. Tôi không phản đối những công cụ như thế này, miễn là số lượng các vấn đề cần được giữ ở một con số nhỏ và quản lý được. Khi các công cụ theo dõi vấn đề bị buộc phải theo dõi hàng nghìn vấn đề, thì từ “theo dõi” đã mất đi ý nghĩa của nó. Chúng sẽ trở thành “những đống vấn đề” (và thường thì nó cũng bốc mùi như đống rác).

Build liên tục

Mới gần đây tôi đã dùng Jenkins làm hệ thống Build Liên Tục của tôi. Nó nhẹ, đơn giản, và hầu như không phải mất thời gian để học sử dụng. Bạn tải nó xuống, chạy, thực hiện một vài cấu hình nhanh chóng và đơn giản, đã xong và bạn chạy được hệ thống. Rất tuyệt.

Triết lý của tôi về hệ thống build liên tục rất đơn giản: Kết nối nó với hệ thống quản lý source code. Bất cứ khi nào ai đó check in code thì nó cần phải tự động build và sau đó báo cáo lại trạng thái cho cả nhóm.

Nhóm bắt buộc lúc nào cũng phải duy trì quá trình build. Nếu một lần build bị lỗi, nó cần phải là một sự kiện khẩn cấp “dừng máy dập” và nhóm cần phải họp để giải quyết vấn đề nhanh chóng. Không một hoàn cảnh nào được phép để cho một lần build lỗi tồn tại quá một ngày.

Đối với dự án FitNesse tôi yêu cầu mỗi lập trình viên chạy một script build liên tục trước khi họ commit code. Mỗi lần build mất dưới 5 phút, vì vậy nó không phải việc gì quá nặng nề. Nếu có vấn đề gì, những lập trình viên sẽ phải giải quyết chúng trước khi commit code. Vì vậy mỗi lần build tự động hiếm khi có vấn đề gì xảy ra. Nguyên nhân phổ biến nhất của việc build tự động bị lỗi thường do các vấn đề liên quan đến môi trường do môi trường build tự động của tôi khá khác biệt so với môi trường phát triển của các lập trình viên.

các công cụ unit test

Mỗi ngôn ngữ đều có một công cụ để thực hiện unit test riêng. Những công cụ ưa thích của tôi là JUnit cho Java, RSPEC cho Ruby, NUnit cho .Net, Midje cho Clojure, CppUTest cho C và C++.

Dù công cụ unit test nào mà bạn lựa chọn, thì tất cả chúng đều phải hỗ trợ một vài chức năng cơ bản sau.

  1. Nó cần phải nhanh và dễ dàng để chạy các test. Cho dù nó được thực hiện thông qua các plugin của IDE hay các công cụ dòng lệnh đơn giản thì điều này không quan trọng, miễn là các lập trình viên có thể chạy những bài test một cách nhanh chóng. Thao tác để chạy các bài test cần phải rất nhanh chóng. Lấy ví dụ, tôi chạy các bài test CppUTest bằng cách gõ command-M trong TextMate. Tôi đã thiết lập lệnh này để chạy makefile của tôi, file này tự động chạy các bài test và in báo cáo một dòng nếu tất cả các bài test đều vượt qua. Cả JUnit và RSPEC đều được hỗ trợ trong IntelliJ, vì vậy tất cả tôi phải làm là nhấn nút. Đối với NUnit, việc sử dụng plugin ReSharper cho phép tôi có được một nút test.
  2. Công cụ này cần phải cho bạn một dấu hiệu pass/fail một cách trực quan rõ ràng. Không quan trọng việc nó là một thanh màu xanh lá đồ họa hay một thông báo trên màn hình nói là “Tất cả các bài test đều đã pass”. Mấu chốt là việc bạn phải có thể biết tất cả các bài test đã được pass một cách nhanh chóng và rõ ràng. Nếu bạn phải đọc một báo cáo nhiều dòng, hay tệ hơn là phải so sánh đầu ra của 2 file với nhau mới biết được các bài test có pass hay không thì bạn đã thất bại ở điểm này.
  3. Công cụ này cần phải cho bạn một chỉ thị tiến độ trực quan rõ ràng. Không quan trong việc nó có dạng thanh tiến trình đồ họa hoặc một chuỗi các dấu chấm miến là bạn có thể biết rằng tiến trình vẫn đang diễn ra và các bài test không bị dừng lại hoặc bị hủy bỏ.
  4. Các công cụ này cần phải ngăn cản các bài test riêng lẻ giao tiếp lẫn nhau. JUnit thực hiện việc này bằng cách tạo một đối tượng mới của test class đối với mỗi test method, nhờ đó ngăn chặn các bài test khỏi việc dùng các biến của đối tượng để liên lạc với những bài test khác. Các công cụ khác sẽ chạy các test method theo thứ tự ngẫu nhiên để bạn không thể phụ thuộc vào việc bài test này thực hiện trước bài test kia. Dù là bất cứ cơ chế nào, công cụ này cũng cần phải giúp bạn giữ cho các bài test được độc lập khỏi những bài test khác. Các bài test bị phụ thuộc là một cạm bẫy sâu mà bạn không bao giờ muốn bị rơi vào đó.
  5. Công cụ này cần phải giúp bạn rất dễ dàng viết được các bài test. JUnit thực hiện việc này bằng cách cung cấp các API thuận tiện để làm các kiểm tra đánh giá. Nó cũng dùng các thuộc tính của Java để phân biệt các function test với các function bình thường. Điều này cho phép một IDE tốt có thể tự động xác định được tất cả các bài test của bạn, loại bỏ được sự phức tạp của việc tạo các bộ test và tạo ra danh sách các bài test vốn rất

dễ xảy ra lỗi.

Các công cụ component test

Các công cụ này được dùng để test các component ở cấp độ API. Vai trò của chúng là đảm bảo rằng hành vi của một component được thể hiện bằng một ngôn ngữ mà cả khách hàng và nhóm QA đều có thể hiểu được. Quả thực là trong trường hợp lý tưởng thì những người phân tích nghiệp vụ và QA có thể viết các bài test đó bằng công cụ này.

Định nghĩa Hoàn thành

Hơn bất cứ công cụ nào khác, công cụ component test được dùng để chúng ta xác định hoàn thành nghĩa là gì. Khi những người phân tích nghiệp vụ và QA cộng tác để tạo ra một bộ tiêu chuẩn định nghĩa hành vi của một component, và khi tiêu chuẩn đó có thể được thực hiện như một bộ các bài test có thể pass hoặc fail, thì từ hoàn thành có một ý nghĩa rất rõ ràng: “Tất cả các bài test đều phải pass.”

FitNesse

Công cụ component test ưa thích của tôi là FitNesse. Tôi đã viết phần lớn nó, và tôi là người đóng góp chính. Chính vì vậy nó là đứa con tinh thần của tôi.

FitNesse là một hệ thống dựa trên wiki cho phép các người phân tích nghiệp vụ và QA viết các bài test ở dạng bảng rất đơn giản. Những bảng này tương tự như bảng Parnas cả về hình thức lẫn mục đích. Những bài test này có thể được ghép nhanh chóng thành các bộ test, và các bộ test này có thể chạy một cách nhanh chóng.

FitNesse được viết bằng Java nhưng nó có thể kiểm tra các hệ thống được viết bằng bất cứ ngôn ngữ nào bởi vì nó liên lạc với hệ thống kiểm tra nằm bên dưới, hệ thống này có thể được viết bằng bất cứ ngôn ngữ nào. Các ngôn ngữ được hỗ trợ bao gồm Java, C#/.NET, C, C++, Python, Ruby, PHP, Delphi, và nhiều ngôn ngữ khác.

Có hai hệ thống kiểm tra làm nền tảng cho FitNesse: Fit và Slim. Fit được viết bởi Ward Cunningham và là cảm hứng ban đầu của FitNesse. Slim thì là một hệ thống kiểm tra đơn giản và linh động hơn nhiều, đây là những đặc điểm được yêu thích bởi những người dùng FitNesse hiện nay.

Các công cụ khác

Tôi có biết một vài công cụ khác mà có thể phân loại là các công cụ component test.

  • RobotFX là một công cụ được phát triển bởi các kỹ sư Nokia. Nó dùng dạng bảng tương tự như FitNesse, nhưng không phải dựa trên wiki. Công cụ này đơn giản là chạy trên các file được chuẩn bị bằng Excel hoặc phần mềm tương tự. Công cụ này được viết bằng Python nhưng có thể kiểm tra các hệ thống ở bất cứ ngôn ngữ nào bằng cách dùng các cầu nối phù hợp.
  • Green Pepper là một công cụ thương mại hóa có một số tính năng tương tự như FitNesse. Nó dựa trên confluence wiki phổ biến.
  • Cucumber là một công cụ văn bản thuần túy được điều khiển bởi Ruby engine, nhưng nó cũng có khả năng kiểm tra nhiều nền tảng khác nhau. Ngôn ngữ của Cucumber có phong cách Given/When/Then quen thuộc.
  • JBehave tương tự như Cucumber. Nó được viết bằng Java.

Các công cụ integration test

Các công cụ component test cũng có thể được dùng đối với nhiều bài integration test, nhưng chúng ít phù hợp cho những bài test được thực hiện thông qua UI.

Nói chung, chúng ta không muốn thực hiện quá nhiều bài test thông qua UI bởi vì UI là thành phần rất hay thay đổi. Việc hay thay đổi đó làm cho những bài test thực hiện qua UI rất mong manh. Nhưng cũng phải nói rằng, có những bài test bắt buộc phải thông qua UI – quan trọng nhất là các bài test của UI. Ngoài ra, có một số bài test đầu-cuối cũng cần phải đi qua toàn bộ hệ thống hoàn thiện, bao gồm cả UI.

Các công cụ tôi thích nhất để test UI là Selenium và Watir.

UML/MDA

Vào đầu những năm 90, tôi rất hy vọng rằng các công cụ CASE[3] sẽ tạo ra một thay đổi căn bản cách mà các lập trình viên làm việc. Khi tôi liên tưởng trong những ngày đó, tôi đã nghĩ rằng mọi người sẽ code bằng biểu đồ ở một cấp độ trừu tượng cao hơn và việc code bằng ký tự sẽ là điều thuộc về quá khứ.

Tôi đã sai. Không chỉ giấc mơ này không thành hiện thức, mà mọi nỗ lực để đi theo hướng đó đều thất bại nặng nề. Không phải bởi vì không có các công cụ và hệ thống nào chứng minh được tiềm năng này; nó đơn giản là do các công cụ này không thực sự hiện thực hóa giấc mơ đó, và hiếm có ai dường như muốn dùng chúng.

Giấc mơ về việc các lập trình viên phần mềm có thể không cần quan tâm chi tiết tới phần code ký tự và có thể xây dựng hệ thống ở một cấp độ ngôn ngữ cao hơn là các biểu đồ. Quả thực là nếu giấc mơ đó tới, chúng ta có thể hoàn toàn không cần tới các lập trình viên nữa. Các kiến trúc sư có thể tạo ra toàn bộ hệ thống từ các biểu đồ UML. Các cỗ máy to lớn, lạnh lùng và vô cảm với cảnh ngộ của những lập trình viên thuần túy, sẽ biến đổi những biểu đồ đó thành code thực thi. Đó là giấc mơ vĩ đại về Kiến Trúc Định Hướng Mô Hình (Model Driven Architecture – MDA).

Không may thay, giấc mơ vĩ đại này có một thiếu sót rất rất nhỏ. MDA xem vấn đề là code. Nhưng code không phải là vấn đề. Nó không bao giờ là vấn đề. Vấn đề là ở chi tiết.

Chi tiết

Các lập trình viên là những người quản lý chi tiết. Đó là những gì chúng ta làm. Chúng ta chỉ ra hành vi chi tiết của hệ thống. Chúng ta dùng ngôn ngữ văn bản cho điều này (code) bởi vì ngôn ngữ văn bản đặc biệt thuận tiện (lấy ví dụ như tiếng Anh).

Chúng ta quản lý loại chi tiết gì?

Bạn biết sự khác biệt giữa hai ký tự \n và \r không? Cái đầu tiên, \n, được gọi là line feed. Cái thứ hai, \r, được gọi là carriage return. Vậy carriage là cái gì?

Trong những năm 60 và đầu những năm 70, một trong những thiết bị đầu ra ngày càng phổ biến của máy vi tính là máy điện báo đánh chữ. Mẫu ASR-33[4] là loại phổ biến nhất.

Thiết bị này bao gồm một đầu in mà nó có thể in được 10 ký tự mỗi giây. Đầu in này bao gồm một xylanh nhỏ với các ký tự nổi lên trên nó. Xylanh sẽ quay và nâng lên để cho ký tự tiếp xúc với mặt giấy, và sau đó một búa nhỏ sẽ đập xylanh vào mặt giấy. Có một băng mực ở giữa xylanh và giấy, và mực được truyền vào giấy theo hình dạng của ký tự.

Các đầu in này nằm trên một carriage. Với mỗi ký tự, carriage này di chuyển một khoảng về bên phải, mang theo đầu in với nó. Khi carriage tới điểm cuối của dòng 72 ký tự, bạn phải đưa carriage về bằng cách gửi ký tự carriage return (\r = 0 x 0D), nếu không đầu in sẽ vẫn tiếp tục in các ký tự ở cột thứ 72, biến vùng đó thành một hình chữ hình màu đen bẩn bẩn.

Dĩ nhiên, như vậy là chưa đủ. Việc đưa carriage về không giúp nâng tấm giấy lên dòng tiếp theo. Nếu bạn đưa carriage về mà không gửi một ký tự line feed (\n = 0 x 0A) thì dòng mới sẽ vẫn in trên dòng cũ.

Bởi vậy, đối với máy điện báo đánh chữ ASR-33 thì chuỗi hết dòng là “\r\n”. Thực tế là bạn phải cẩn thận về việc đó do carriage có thể mất hơn 100ms để trở về. Nếu bạn gửi “\n\r” thì ký tự tiếp theo có thể bị in trong khi carriage đang trở về, do đó nó sẽ tạo ra một ký tự mờ mờ ở giữa dòng. Để an toàn, chúng tôi thường thêm vào chuỗi ký tự hết dòng với 1 hoặc 2 ký tự rubout[5] (0 x FF).

Trong những năm 70, máy điện báo đánh chữ dần dần biến mất, các hệ điều hành như UNIX đã làm ngắn bớt chuỗi kết thúc dòng thành đơn giản chỉ là “\n”. Tuy nhiên, các hệ điều hành khác, như DOS, vẫn tiếp tục dùng quy ước “\r\n”.

Lần cuối cùng bạn phải xử lý những file văn bản dùng “sai” quy ước này là khi nào? Tôi gặp phải vấn đề này ít nhất là mỗi năm một lần. Hai file source code tương tự nhau nhưng khi so sánh lại không giống nhau và không tạo ra được checksum[6] như nhau, chỉ bởi vì chúng dùng các quy ước kết thúc dòng khác nhau. Các trình xử lý văn bản không word-wrap chính xác, hoặc bị nhân đôi khoảng cách ký tự bởi vì kết thúc dòng “sai”. Các chương trình không mong muốn dòng trống bị thoát ra ngoài bởi vì chúng dịch “\r\n” là hai dòng. Một số chương trình nhận biết “\r\n” nhưng không nhận biết được “\n\r”. Và nhiều vấn đề khác.

Đó chính là thứ mà tôi muốn nói về chi tiết ở đây. Bạn hãy thử code một luồng logic kinh khủng để phân loại kết thúc dòng bằng UML xem!

Không hy vọng, không thay đổi

Hy vọng của phong trào MDA là có thể loại bỏ một lượng lớn phần chi tiết bằng cách dùng biểu đồ thay vì code. Hy vọng đó cho đến nay đã được chứng minh là không còn. Nó đã chỉ ra rằng chúng ta không loại bỏ được quá nhiều phần code chi tiết nhúng bên trong hình ảnh. Hơn thế nữa, hình ảnh còn chứa những chi tiết thừa của bản thân chúng nữa. Hình ảnh có ngữ pháp, cú pháp, quy tắc và ràng buộc riêng. Vì vậy, cuối cùng, sự khác biệt về chi tiết là không thể xóa được.

Hy vọng về MDA đó là các biểu đồ sẽ chứng minh nó sẽ là một cấp trừu tượng cao hơn code, cũng giống như Java là một cấp trừu tượng cao hơn ngôn ngữ assembly. Nhưng lại một lần nữa, hy vọng đó cho đến nay đã được chứng minh là không đúng chỗ. Sự khác biệt về mức độ trừu tượng là rất nhỏ.

Và cuối cùng, chúng ta hãy nói rằng một ngày nào đó ai đó sẽ phát minh ra một ngôn ngữ biểu đồ thực sự hữu ích. Không phải là các kiến trúc sư sẽ vẽ ra những biểu đồ đó, mà sẽ là những lập trình viên. Biểu đồ đó sẽ đơn giản trở thành một loại code mới, và những lập trình viên sẽ cần vẽ code bởi vì, cuối cùng, tất cả là về chi tiết, và các lập trình viên là những người quản lý chi tiết.

Kết luận

Các công cụ phần mềm đã trở nên mạnh mẽ và phong phú hơn rất nhiều kể từ khi tôi bắt đầu lập trình. Bộ công cụ hiện giờ của tôi là một tập con đơn giản của một số lượng khổng lồ các công cụ đó. Tôi dùng git để quản lý source code, Pivotal Tracker để quản lý vấn đề, Jenkin để build liên tục, IntelliJ làm IDE, XUnit để test, và FitNesse để thực hiện component test. Chiếc máy làm việc của tôi là Macbook Pro, 2,8Ghz Intel Core i7, với màn hình 17-inch, RAM 8GB, ổ SSD 512GB, và 2 màn hình phụ.


[1] Những cuộn băng này chỉ có thể di chuyển theo một hướng. Vì vậy khi nó đọc lỗi, không có cách nào để đầu đọc lùi lại và đọc lại lần nữa. Bạn phải dừng việc bạn đang làm, cho cuộn băng lùi trở lại điểm nạp và sau đó bắt đầu lại lần nữa. Điều này xảy ra 2 hoặc 3 lần một ngày. Việc ghi lỗi cũng rất phổ biến, và thiết bị này không có cách nào để phát hiện ra được chúng. Vì vậy chúng tôi luôn ghi băng thành từng cặp và sau đó kiểm tra cặp này sau khi hoàn thành. Nếu một cuộn băng bị lỗi, chúng tôi lập tức tạo một bản copy. Nếu cả hai bị lỗi, điều này hiếm khi xảy ra, thì chúng tôi sẽ phải bắt đầu lại toàn bộ quá trình từ đầu. Đó là cuộc sống vào những năm 70.

[2] vi: tên gọi một phần mềm chỉnh sửa văn bản phổ biến trên hệ điều hành Linux.

[3] CASE: Computer-Aided Software Engineering, hệ thống các công cụ được sử dụng để thiết kế và phát triển phần mềm dưới sự hỗ trợ của máy tính.

[4] http://en.wikipedia.org/wiki/ASR-33_Teletype

[5] Ký tự rubout rất hữu ích để chỉnh sửa các băng giấy. Về quy tắc thì các ký tự rubout sẽ được bỏ qua. Code của nó là 0 x FF, nghĩa là mọi lỗ trên hàng của băng giấy đó đã được bấm. Điều này nghĩa là bất cứ ký tự nào có thể được chuyển thành một rubout bằng cách đục lộ nó. Do đó, nếu bạn gõ nhầm chương trình của bạn thì bạn có thể lùi lại và ấn rubout, sau đó tiếp tục gõ.

[6] checksum: giá trị tổng kiểm.

Clean Coder – Chương 14 – Đào Tạo, Học Việc, Và Nhà Nghề

Tôi luôn bị thất vọng về chất lượng của ngành đào tạo CS[1]. Không phải là những người tốt nghiệp không sáng dạ hoặc tài năng, mà đó là việc họ không được dạy lập trình thực sự là cái gì.

Chứng chỉ của thất bại

Một lần tôi phỏng vấn một cô gái trẻ đang lấy bằng thạc sỹ về khoa học máy tính của một trường đại học lớn. Cô ấy ứng tuyển vào vị trí thực tập sinh mùa hè. Tôi đã đề nghị cô ấy viết một ít code cho tôi xem, và cô ấy đã nói rằng “Tôi không thực sự viết code.”

Vui lòng đọc lại đoạn trước lần nữa, và sau đó bỏ qua đoạn này để sang đoạn tiếp.

Tôi hỏi cô ấy khóa học lập trình nào mà cô đã tham gia để theo đuổi tấm bằng thạc sỹ. Cô ấy đã nói rằng mình không tham gia khóa học nào cả.

Có lẽ bạn sẽ muốn bắt đầu lại từ đầu chương này chỉ để chắc rằng bạn không phải đang rơi vào một vũ trụ nào khác hoặc chỉ là để thức dậy từ một con ác mộng.

Vào lúc đó tôi tự hỏi bản thân làm sao một sinh viên trong một chương trình thạc sỹ khoa học máy tính mà lại có thể tránh được một khóa học lập trình. Tôi băn khoăn như vậy vào thời điểm đó. Và đến bây giờ tôi vẫn đang băn khoăn, chưa có câu trả lời.

Dĩ nhiên, đó là trường hợp thất vọng cùng cực trong một chuỗi các thất vọng mà tôi có khi phỏng vấn những sinh viên tốt nghiệp. Không phải tất cả những sinh viên tốt nghiệp CS đều gây thất vọng – hãy còn xa! Tuy nhiên, tôi chú ý thấy rằng những người không gây thất vọng đều có một điểm chung: Gần như tất cả bọn họ đều tự học lập trình trước khi họ vào đại học và tiếp tục tự học khi đang còn học trong trường.

Bây giờ đừng hiểu sai ý tôi. Tôi nghĩ là có thể có được một nền giáo dục hoàn hảo tại một ngôi trường đại học. Chỉ có điều tôi cũng nghĩ là hoàn toàn có thể ung dung học hết hệ thống này và ra ngoài với một tấm bằng, và không có gì khác.

Và ở đó cũng có một vấn đề khác. Ngay cả chương trình cấp chứng chỉ CS tốt nhất thường cũng không chuẩn bị cho những sinh viên tốt nghiệp trẻ tuổi về những thứ họ sẽ gặp thực tế trong ngành công nghiệp này. Đây không phải là một bảng cáo trạng cho các chương trình cấp chứng chỉ này bởi vì nó là thực tế của gần như tất các ngành. Cái bạn học trong nhà trường và cái bạn thấy thực tế trong công việc thường là những thứ rất khác nhau.

Đào tạo

Chúng ta học cách lập trình như thế nào? Hãy để tôi kể cho bạn câu chuyện của tôi về cách tôi được đào tạo.

Digi-Comp I, chiếc máy tính đầu tiên của tôi

Vào năm 1964, mẹ tôi đưa cho tôi một chiếc máy tính bằng nhựa nhỏ cho lần sinh nhật thứ 12 của tôi. Nó được gọi là Digi-Comp I[2]. Nó có 3 flip-flop[3] và 6 cổng and[4] bằng nhựa. Bạn có thể kết nối đầu ra của flip-flop với đầu vào của cổng and. Bạn cũng có thể kết nối đầu ra của các cổng and với đầu vào của flip-flop. Nói ngắn gọn thì nó cho phép bạn tạo ra một chiếc máy trạng thái hữu hạn 3-bit.

Bộ thiết bị này đi kèm với một bản hướng dẫn cho phép bạn chạy được vài chương trình. Bạn lập trình chiếc máy này bằng cách đẩy những ống nhỏ (những đoạn ngắn của các ống hút soda) vào những chốt nhỏ nhô lên khỏi các flip-flop. Bản hướng dẫn này nói cho bạn chính xác nơi nào đặt từng chiếc ống, mà không nói là những ống đấy dùng để làm gì. Tôi thấy điều này rất bực mình!

Tôi nhìn vào chiếc máy đó hàng giờ liền và quyết tâm xem cách thức mà nó làm việc ở cấp độ thấp nhất; nhưng tôi không thể, trong cả cuộc đời của tôi, hình dung ra làm thế nào mà nó thực hiện được những gì tôi muốn nó thực hiện. Trang cuối trong bản hướng dẫn đó có nói với tôi rằng gửi cho họ 1 đô-la và họ sẽ gửi lại một bản hướng dẫn nói cho tôi cách để lập trình chiếc máy đó.[5]

Tôi đã gửi cho họ đồng đô-la của tôi và chờ đợi họ với một sự thiếu kiên nhẫn của một đứa bé tuổi 12. Ngày mà bản hướng dẫn được gửi đến, tôi đã ngấu nghiến nó. Nó chỉ là một bản lý thuyết đơn giản về đại số boole, bao gồm những kiến thức cơ bản của các phương trình boole, các định luật kết hợp và phân tán, và lý thuyết của DeMorgan. Bản hướng dẫn đó chỉ cách biểu diễn một vấn đề thành một chuỗi các phương trình boole. Nó cũng mô tả cách để tối giản những phương trình đó sao cho vừa với 6 cổng and.

Tôi đã nhận thức được chương trình đầu tiên của mình. Tôi vẫn nhớ cái tên: Cổng Điều Khiển Bằng Máy Tính của Mr Patternson. Tôi đã viết các phương trình, cắt giảm chúng, và ánh xạ chúng thành những ống và chốt của chiếc máy. Và nó hoạt động được!

Khi đang viết những từ này, nó vẫn khiến tôi bây giờ cảm thấy phấn khích. Sự phấn khích mà tôi đã trải qua vào năm 12 tuổi gần nửa thế kỷ trước. Tôi đã bị cắn câu. Cuộc đời tôi nếu không có ngày hôm đó thì có lẽ đã không như bây giờ.

Bạn có nhớ thời điểm chương trình đầu tiên của bạn làm việc không? Nó có thay đổi cuộc đời bạn hay đặt bạn vào một tiến trình mà bạn không thể quay lưng lại không?

Tôi đã không phải tự mình tìm hiểu được hết. Tôi đã được đào tạo. Một vài người rất tốt bụng và rất giỏi (tôi nợ những người này một món nợ lớn lòng biết ơn) đã dành thời gian để viết một bản lý thuyết về đại số boole mà một đứa trẻ 12 tuổi có thể hiểu được. Họ đã kết nối lý thuyết toán học với một chiếc máy vi tính bằng nhựa nhỏ bé và trao cho tôi quyền khiến cho chiếc máy tính đó thực hiện theo những điều mà tôi muốn nó phải làm.

Tôi vừa lôi xuống bản copy của bản hướng dẫn định mệnh đó. Tôi giữ nó trong một túi khóa zip. Vậy mà, năm tháng cũng đã làm cho những trang giấy trở nên vàng ố và dễ rách. Nhưng sức mạnh của những câu từ ghi trong đó đối với tôi vẫn tỏa sáng. Lời mô tả súc tích về đại số boole của họ chỉ chiếm ba trang giấy. Lời hướng dẫn từng bước một về các phương trình của mỗi chương trình gốc vẫn đầy lôi cuốn. Nó là sản phẩm của một bậc thầy điêu luyện. Nó là sản phẩm đã thay đổi cuộc đời của ít nhất một chàng trai trẻ. Tôi chỉ tiếc một điều là có lẽ tôi sẽ không bao giờ biết được tên của những tác giả của bản hướng dẫn đó.

Chiếc máy tính ECP-18 tại trường trung học

Ở tuổi 15, là một học sinh năm thứ nhất tại trường trung học, tôi thích loanh quanh ở khoa toán. (Hình dung xem!) Một ngày nọ họ chuyển tới một chiếc máy có kích thước của một chiếc bàn cưa. Nó là một chiếc máy tính dạy học được chế tạo cho các trường trung học, được gọi là ECP-18.Trường của chúng tôi có được 2 tuần để dùng demo nó.

Tôi đứng đằng sau khi các giáo viên và các kỹ thuật viên nói chuyện. Chiếc máy này có 15-bit word (word là cái gì nhỉ?) và một bộ nhớ trống 1024-word. (lúc đó tôi đã biết bộ nhớ trống là gì, nhưng chỉ biết khái niệm).

Khi họ bật chiếc máy lên, nó tạo ra một tiếng rít làm gợi nhớ đến tiếng của một chiếc máy bay phản lực hạ cánh. Tôi đã đoán tiếng đó là do chiếc trống đang quay. Một khi đã đủ tốc độ rồi, thì nó lại tương đối yên lặng.

Chiếc máy này thật đáng yêu. Nó về cơ bản là một chiếc bàn văn phòng với một bảng điều khiển kỳ diệu nổi ở phía trên trông giống như chiếc cầu của một chiến hạm. Bảng điều khiển này được tô điểm bởi những dãy đèn mà đó cũng chính là những nút nhấn. Ngồi tại chiếc bàn đó cũng giống như đang ngồi ở chiếc ghế của thuyền trưởng Kirk[6] vậy.

Khi tôi nhìn những kỹ thuật viên nhấn những chiếc nút đó, tôi đã chú ý thấy chúng sáng lên khi được nhấn, và bạn có thể nhấn chúng lại lần nữa để tắt. Tôi cũng chú ý thấy có những nút nhấn khác mà họ đang nhấn; những nút có tên như gửi chạy.

Những nút trong mỗi hàng được nhóm thành năm cụm, mỗi cụm ba nút. Chiếc máy Digi Comp đồ chơi của tôi cũng có 3 bit, vì vậy tôi có thể đọc được số octal[7] khi nó thể hiện dưới dạng nhị phân. Đó không phải việc gì quá khó để nhận ra rằng nó chỉ gồm 5 số octal.

Khi các kỹ thuật viên nhấn nút tôi còn có thể nghe thấy họ lẩm bẩm. Họ nhấn 1, 5, 2, 0, 4 trong hàng bộ nhớ đệm trong khi lẩm bẩm “lưu ở 204”. Họ nhấn 1, 0, 2, 1, 3 và lẩm bẩm “nạp 213 vào bộ tổng tích lũy”. Ở đó có một hàng nút tên là bộ tổng tích lũy!

Mười phút trôi qua và nó khá rõ ràng đối với đầu óc của một cậu thiếu niên 15 tuổi như tôi rằng 15 nghĩa là lưu và 10 nghĩa là nạp, bộ tổng tích lũy là thứ được lưu hay nạp, và các con số khác là các số của một trong 1024 word trên trống. (Vậy đó là thứ gọi là một word!)

Tâm trí háo hức của tôi gắn từng bit một (đây không phải là tôi đang chơi chữ) vào các mã lệnh và khái niệm. Cho đến khi các kỹ thuật viên rời đi, tôi đã biết cơ bản cỗ máy đó hoạt động như thế nào.

Buổi chiều hôm đó, trong suốt giờ học trên giảng đường, tôi rón rén đi vào phòng thí nghiệm toán học và bắt đầu nghịch chiếc máy tính đó. Tôi đã học được từ lâu rằng tốt nhất là xin tha lỗi còn hơn là xin phép! Tôi bật một chương trình nhỏ để nhân bộ cộng tích lũy với 2 và cộng 1. Tôi bật 6 vào bộ cộng tích lũy, chạy chương trình này và thấy con số 13 trong bộ cộng tích lũy! Nó đã hoạt động!

Tôi đã bật vài chương trình đơn giản khác giống như thế và tất cả chúng đều hoạt động như ý muốn. Tôi đúng là chủ nhân của vũ trụ này!

Những ngày sau đó tôi đã nhận ra tôi đã ngu ngốc và may mắn như thế nào. Tôi tìm thấy một tờ hướng dẫn nằm đâu đó trong phòng thí nghiệm toán học. Nó chỉ ra tất cả các câu lệnh và các op-code[8] khác nhau, bao gồm nhiều cái tôi chưa học được khi quan sát các kỹ thuật viên. Tôi hài lòng với việc tôi đã dịch được những thứ tôi đã biết một cách chính xác và vui thích với những cái khác mới mẻ. Tuy nghiên, một trong những câu lệnh mới là HLT. Tờ hướng dẫn đã chỉ ra rằng câu lệnh halt (dừng)là một word gồm tất cả đều là 0. Và nó cũng chỉ ra rằng tôi có thể đặt một word có tất cả đều là 0 vào cuối mỗi chương trình để tôi có thể nạp nó vào bộ cộng tích lũy để xóa nó đi. Khái niệm về từ “halt” đơn giản là tôi không có. Tôi chỉ biết được chương trình sẽ dừng khi nó hoàn thành!

Tôi nhớ có lúc tôi ngồi trong phòng thí nghiệm toán quan sát một trong những giáo viên cố gắng làm cho một chương trình hoạt động. Ông ấy đang cố gắng gõ 2 số nguyên trên bàn phím gắn kèm, và sau đó in ra tổng. Bất cứ ai cố gắng viết một chương trình giống như vậy bằng ngôn ngữ máy trên một máy tính mini đều biết rằng nó không phải là chuyện tầm thường. Bạn phải đọc các ký tự, chuyển chúng thành số, sau đó chuyển sang dạng nhị phân, cộng chúng lại, chuyển trở lại số nguyên và mã hóa nó trở lại thành các ký tự. Và, hãy tin tôi, sẽ tệ hơn nhiều nếu bạn nhập chương trình nhị phân thông qua bảng điều khiển máy!

Tôi đã xem ông ấy đặt một lệnh “halt” trong chương trình của ông ấy và sau đó chạy cho đến khi nó dừng lại. (Ồ! Đó là một ý tưởng hay!) Kiểu breakpoint nguyên thủy này cho phép ông ấy kiểm tra được nội dung của các thanh ghi để xem xem chương trình đã làm được những gì. Tôi nhớ ông ấy đã lẩm nhẩm “Wow, nhanh thật đấy!” Anh bạn, tôi có tin tức cho anh đây!

Tôi không hiểu thuật toán của ông ấy như thế nào. Dạng lập trình đó vẫn là một phép màu đối với tôi. Và ông ấy không bao giờ nói gì với tôi trong khi tôi quan sát qua vai của ông ấy. Quả thực là không ai nói với tôi về chiếc máy tính này. Tôi nghĩ họ xem tôi như mối phiền toái không đáng quan tâm, lăng xăng quanh phòng thí nghiệm như một con ngài. Điều đó đủ để có thể nói rằng cả học sinh và giáo viên đều không được phát triển kỹ năng xã hội ở mức độ cao.

Cuối cùng ông ấy cũng làm cho chương trình của mình hoạt động được. Trông nó thật đáng kinh ngạc. Ông ấy gõ chậm 2 con số bởi vì, theo như quả quyết ban đầu của ông ấy, chiếc máy tính đó không chạy nhanh (hãy liên tưởng tới việc đọc các word liên tục từ một trống quay vào năm 1967). Khi ông ấy gõ “return” sau con số thứ hai, chiếc máy tính nhấp nháy nhanh một lúc và sau đó bắt đầu in kết quả. Nó mất khoảng 1 giây mỗi chữ số. Nó đã in được tất cả nhưng với chữ số cuối cùng thì nó nhấp nháy thậm chí còn nhiều hơn trong 5 giây, và sau đó mới in ra chữ số cuối cùng và dừng lại.

Tại sao chữ số cuối cùng lại bị tạm dừng một lúc? Tôi không bao giờ tìm được lý do. Nhưng nó làm tôi nhận ra rằng cách tiếp cận một vấn đề có thể có hiệu quả sâu sắc tới người dùng. Mặc dù chương trình tạo ra câu trả lời đúng, nhưng nó vẫn có cái gì đó sai sai.

Đây chính là quá trình đào tạo. Chắc chắn đây không phải là kiểu đào tạo mà tôi mong muốn. Sẽ thật tuyệt vời nếu một trong những giáo viên này dìu dắt tôi và làm việc với tôi. Nhưng cũng không quan trọng lắm, bởi vì tôi đã quan sát được họ và học hỏi được với những bước tiến nhanh chóng.

Đào tạo không chính quy

Tôi kể với bạn về hai câu truyện này bởi vì chúng mô tả hai dạng rất khác nhau của việc đào tạo, cả hai đều không phải là kiểu mà từ “đào tạo” thường ngụ ý. Trong trường hợp đầu tiên, tôi đã học từ được từ những tác giả của một bản hướng dẫn viết rất tuyệt vời. Trong trường hợp thứ hai, tôi đã học được bằng cách quan sát người ta khi mà họ đã cố tình phớt lờ mình đi. Trong cả hai trường hợp những kiến thức thu được đều sâu sắc và làm nền tảng cho tôi sau này.

Dĩ nhiên, tôi cũng có những kiểu đào tạo khác nữa. Đó là những hàng xóm tốt bụng làm việc tại Teletype, họ đã mang cho tôi một hộp 30 cái rơ-le điện thoại để nghịch. Để tôi cho bạn biết điều này, hãy đưa cho một chàng trai vài chiếc rơ-le và một biến áp tàu điện và anh ấy có thể chinh phục thế giới!

Đó là người hàng xóm tốt bụng, anh ấy là một người vận hành vô tuyến điện nghiệp dư đã chỉ cho tôi cách dùng máy đo vạn năng (cái mà tôi đã nhanh chóng làm hỏng). Đó là một chủ cửa hiệu văn phòng phẩm đã cho phép tôi tới và “chơi” với chiếc máy tính lập trình được rất đắt tiền của anh ấy. Đó là văn phòng kinh doanh của tập đoàn Digital Equipment Corporation đã cho phép tôi tới và “chơi” với những chiếc máy PDP-8 và PDP-10 của họ.

Rồi đó là Jim Carlin lớn, một lập trình viên BAL người đã cứu tôi khỏi bị đuổi việc trong công việc lập trình đầu tiên của tôi bằng cách giúp đỡ tôi debug một chương trình Cobol vượt quá khả năng của tôi khi đó. Anh ấy đã dạy tôi cách đọc kết xuất bộ nhớ (core dump), và cách để định dạng code với những dòng trống, những dòng ngôi sao, và bình luận thích hợp. Anh ấy đã trao cho tôi những bước đi đầu tiên để trở thành một chuyên gia. Tôi lấy làm tiếc là tôi đã không thể trả ơn khi ông chủ không hài lòng về anh ấy một năm sau đó.

Nhưng thành thực mà nói, quan trọng nhất vẫn là bản thân tôi. Vào những năm đầu thập niên 70 thì không có quá nhiều các lập trình viên lâu năm. Ở mọi nơi khác mà tôi đã từng làm việc, tôi đều đã trở thành kỳ cựu. Không ai giúp tôi hình dung ra công việc lập trình chuyên nghiệp thực sự là cái gì. Không có hình mẫu nào dạy tôi cách ứng xử hay tạo giá trị cái gì. Những thứ này tôi phải tự học hỏi lấy, và nó không hề dễ dàng chút nào.

Kiến thức thực tế

Như tôi đã nói với bạn trước đây, thực tế, tôi đã bị sa thải khỏi công việc tự động hóa nhà máy vào năm 1976. Mặc dù tôi có trình độ về mặt kỹ thuật, nhưng tôi đã không được học cách quan tâm tới doanh nghiệp hoặc các mục tiêu của doanh nghiệp. Ngày tháng và các deadline không có ý nghĩa gì với tôi. Tôi đã quên một buổi demo quan trọng vào sáng thứ Hai, để cho hệ thống bị hỏng vào thứ Sáu, và còn đi làm muộn vào thứ Hai, khiến mọi người nhìn tôi chằm chằm giận dữ.

Sếp tôi đã gửi một lá thư cảnh cáo tôi rằng tôi phải thay đổi ngay lập tức hoặc sẽ bị đuổi việc. Đây là một lời thức tỉnh lớn lao đối với tôi. Tôi đã đánh giá lại cuộc đời và sự nghiệp của mình và bắt đầu tạo ra những thay đổi lớn trong hành vi của mình – một vài thứ mà bạn đang đọc trong cuốn sách này. Nhưng nó quá nhỏ bé, quá muộn màng. Khi mà tất cả đang theo đà lệch hướng thì những thứ nhỏ nhặt trước đây lại trở nên nghiêm trọng. Vì vậy, mặc dù tôi đã cố gắng rất nhiều, cuối cùng họ vẫn tống cổ tôi ra khỏi công ty đó.

Không cần phải nói, việc mang cái tin đó về nhà cho người vợ đang bầu và một bé gái hai tuổi không hề vui chút nào. Nhưng tôi đã đứng dậy và mang bài học cuộc đời lớn lao đó sang công việc tiếp theo của tôi – công việc mà tôi đã làm trong 15 năm và nó đã hình thành nên nền tảng thực sự cho sự nghiệp hiện tại của tôi.

Cuối cùng, tôi đã tồn tại và phát triển. Nhưng chắc chắn là phải có cách tốt hơn. Tôi sẽ tốt hơn nhiều nếu tôi có một người thầy thực sự, một ai đó dạy tôi các cách vào và các cách ra. Một ai đó tôi có thể quan sát trong khi tôi giúp đỡ những công việc nhỏ, và một ai đó soát lại và hướng dẫn công việc ban đầu của tôi. Một ai đó đóng vai trò là một hình mẫu và dạy tôi những giá trị và cách phản ứng một cách phù hợp. Một người thầy. Một bậc thầy. Một người cố vấn.

Học việc

Những bác sỹ làm gì? Bạn có nghĩ các bệnh viện thuê những sinh viên y khoa mới ra trường và ném họ ngay vào phòng phẫu thuật để thực hiện một ca phẫu thuật tim vào ngày đầu tiên làm việc của họ không? Dĩ nhiên là không.
Ngành y đã phát triển một kỷ luật được hướng dẫn kỹ lưỡng về nghi thức và được bôi trơn bằng truyền thống của ngành. Ngành y giám sát các trường đại học và đảm bảo rằng các sinh viên ra trường được đào tạo tốt nhất có thể. Quá trình đào tạo đó bao gồm khoảng thời gian gần như ngang nhau giữa việc học trên lớp và các hoạt động điều trị thực tế tại các bệnh viện và được làm việc với những người chuyên nghiệp.

Khi tốt nghiệp, và trước khi họ có thể lấy được bằng, các bác sỹ tương lai được yêu cầu phải dành một năm thực hành và luyện tập dưới sự giám sát mà còn được gọi là thực tập sinh. Đây là quá trình đào tạo bằng công việc thực tế khắc nghiệt. Xung quanh những thực tập sinh đó là những người hình mẫu của công việc và các giáo viên.

Một khi hoàn thành thời gian thực tập, mỗi chuyên ngành y khoa lại đòi hỏi từ 3 tới 5 năm nữa để thực tập và rèn luyện có giám sát nhiều hơn nữa và nó được gọi là nội trú. Người nội trú có được sự tự tin bằng cách nhận những trách nhiệm lớn hơn trong khi vẫn được giám sát xung quanh bởi các bác sỹ kỳ cựu.

Nhiều chuyên ngành còn đòi hỏi từ 1 tới 3 năm nghiên cứu nữa trong đó sinh viên tiếp tục có các khóa đào tạo đặc biệt và thực hành dưới sự giám sát.

sau đó họ mới đủ tư cách để làm các bài thi của họ và được hội đồng giám khảo chứng nhận.

Những mô tả về ngành y này phần nào đã được lý tưởng hóa, và có thể không chính xác hoàn toàn. Nhưng thực tế vẫn còn nguyên là khi nhu cầu tăng cao, chúng ta đã không đưa những sinh viên mới tốt nghiệp vào phòng, thỉnh thoảng ném miếng thịt vào, và hy vọng những điều tốt đẹp sẽ xuất hiện. Vậy thì tại sao chúng ta lại làm điều này với phần mềm?

Sự thực là có tương đối ít người bị chết vì các bug phần mềm. Nhưng đã có những tổn thất về tiền bạc rất lớn. Nhiều công ty đã mất những khoản tiền khổng lồ bởi việc thiếu đào tạo những lập trình viên phần mềm của họ.

Không hiểu vì sao ngành công nghiệp phát triển phần mềm này lại suy nghĩ rằng lập trình viên là lập trình viên, và một khi bạn đã tốt nghiệp thì bạn cũng có thể code. Quả thực là không phải tất cả các công ty đều thuê những đứa trẻ mới ra trường, tập hợp chúng thành “những nhóm”, và đề nghị chúng xây dựng những hệ thống quan trọng nhất. Điều đó thật điên rồ!

Các thợ sơn không làm vậy. Các thợ nước cũng không. Các thợ điện cũng không. Quỷ thật, tôi thậm chí không nghĩ các đầu bếp đồ ăn nhanh cư xử theo cách này! Đối với tôi, các công ty thuê những sinh viên tốt nghiệp khoa học máy tính có thể phải đầu tư đào tạo họ nhiều hơn là việc McDonald đầu tư vào hệ thống máy chủ của họ.

Bạn đừng tự đùa rằng điều này không quan trọng. Có rất nhiều thứ nguy hiểm. Nền văn minh của chúng ta đang chạy trên phần mềm. Phần mềm là thứ di chuyển và xử lý thông tin tràn ngập cuộc sống của chúng ta. Phần mềm điều khiển động cơ, hộp số, và phanh trên ô-tô. Nó duy trì số dư ngân hàng của chúng ta, gửi cho chúng ta hóa đơn, và chấp nhận sự thanh toán của chúng ta. Phần mềm giặt quần áo của chúng ta và cho chúng ta biết thời gian. Nó đưa hình ảnh lên TV, gửi tin nhắn của chúng ta, cho phép chúng ta gọi điện thoại, và giúp chúng ta giải trí khi chúng ta thấy buồn chán. Phần mềm ở mọi nơi.

Với việc chúng ta giao phó cho các lập trình viên phần mềm tất cả các khía cạnh của cuộc sống chúng ta, từ những điều vặt vãnh cho tới những điều quan trọng, thì việc tôi đề nghị một khoảng thời gian hợp lý để đào tạo và thực hành có giám sát cho các lập trình viên không phải là không hợp lý.

Học việc phần mềm

Vậy ngành phần mềm cần phải dẫn dắt những sinh viên trẻ mới tốt nghiệp tiến vào cấp độ chuyên nghiệp như thế nào? Họ cần phải tuân theo những bước nào? Họ cần phải gặp những thử thách nào? Họ cần phải đạt được những mục tiêu nào? Chúng ta hãy làm việc ngược lại.

Bậc thầy

Đó là những lập trình viên đảm nhận vai trò trưởng nhóm của nhiều hơn một dự án phần mềm lớn. Thông thường họ sẽ có trên 10 năm kinh nghiệm và đã từng làm việc với nhiều loại hệ thống, ngôn ngữ, và hệ điều hành khác nhau. Họ biết cách để dẫn dắt và điều phối nhiều nhóm, họ là những kiến trúc sư và thiết kế tài giỏi, và có thể code xoay quanh mọi người khác mà không đổ một giọt mồ hôi. Họ đã được mời các chức vụ quản lý, nhưng hoặc là họ từ chối, hoặc là quay trở lại sau khi chấp nhận, hoặc tích hợp vai trò quản lý với vai trò kỹ thuật chính của họ. Họ giữ vững được vai trò kỹ thuật bằng cách đọc, học tập, rèn luyện, làm việc, và chỉ bảo. Đó là một người thầy mà công ty sẽ giao trách nhiệm kỹ thuật đối với một dự án.

Người thạo việc

Những lập trình viên này được đào tạo, có trình độ, và nhiệt huyết. Trong quãng thời gian này của sự nghiệp, họ sẽ học cách làm việc tốt trong một nhóm và trở thành những trưởng nhóm. Họ có kiến thức về những công nghệ hiện tại nhưng thường thiếu kinh nghiệm với nhiều kiểu hệ thống khác nhau. Họ có khuynh hướng biết một ngôn ngữ, một hệ thống, một nền tảng; nhưng họ vẫn đang học tiếp. Mức kinh nghiệm của họ thay đổi nhiều tùy theo cấp bậc của họ, nhưng thường thì khoảng 5 năm. Ở phía xa mức trung bình, chúng ta có những bậc thầy; ở phía gần chúng ta có những người học việc.

Những người thạo việc được giám sát bởi những bậc thầy, hoặc những người thạo việc kỳ cựu hơn. Những người thạo việc trẻ hiếm khi được cho phép tự hoạt động. Công việc của họ được giám sát chặt chẽ. Code của họ được xem xét kỹ lưỡng. Khi họ có kinh nghiệm, thì quyền tự chủ của họ sẽ lớn dần. Sự giám sát sẽ trở nên ít trực tiếp và tinh tế hơn. Cuối cùng thì nó chuyển thành đánh giá ngang hàng.

Người học việc/Thực tập sinh

Những sinh viên mới ra trường bắt đầu sự nghiệp của họ là những người học việc. Những người học việc không có quyền tự chủ. Họ được giám sát rất chặt bởi những người thạo việc. Đầu tiên, họ chưa nhận một nhiệm vụ nào cả, họ chỉ đơn giản hỗ trợ cho những người thạo việc. Đây là khoảng thời gian lập trình ghép đôi rất khắc nghiệt. Đây là khi họ học được và trau dồi các kỷ luật làm việc. Đây là khi nền tảng của các giá trị được tạo ra.

Những người thạo việc là những giáo viên. Họ đảm bảo rằng người học việc biết được các nguyên lý thiết kế, design pattern, kỷ luật, và các cách thức. Những người thạo việc dạy TDD, cách refactor, ước lượng.v.v. Họ giao nghiệm vụ đọc, các bài tập và bài thực hành cho những người học việc; họ đánh giá tiến triển của những người học việc.

Vị trí học việc có thể mất một năm. Trong thời gian đó, nếu những người thạo việc sẵn sàng chấp nhận người học việc ở cấp bậc của họ, họ sẽ đưa đề xuất cho các bậc thầy. Các bậc thầy sẽ kiểm tra người học việc bởi cả việc phỏng vấn và việc đánh giá những thành quả của họ. Nếu các bậy thầy đồng ý, thì những người học việc sẽ trở thành những người thạo việc.

Thực tế

Một lần nữa, tất cả những điều này chỉ là lý tưởng và có tính giả thuyết. Tuy nhiên, nếu bạn thay đổi những cách gọi này và nhìn chằm chằm vào những từ đó thì bạn sẽ nhận ra nó không khác so với cách mà bây giờ chúng ta mong muốn mọi người làm việc. Những sinh viên mới ra trường được giám sát bởi những trưởng nhóm trẻ tuổi, người này lại được giám sát bởi các trưởng dự án.v.v. Vấn đề là, trong phần lớn các trường hợp, vai trò giám sát không phải là về kỹ thuật! Phần lớn các công ty đều hoàn toàn không có vị trí giám sát kỹ thuật. Các lập trình viên phát triển và cuối cùng được thăng chức bởi vì đó là cách làm của bạn với những lập trình viên.

Sự khác biệt giữa cái chúng ta đang làm hôm nay và chương trình học việc lý tưởng của tôi là sự tập trung vào việc dạy, đào tạo, giám sát, và đánh giá về kỹ thuật. Sự khác biệt này rất rõ ràng rằng những giá trị chuyên nghiệp và nhạy bén kỹ thuật bắt buộc phải được dạy dỗ, được nuôi dưỡng, được ấp ủ, được nâng niu và được chăm bón. Điều thiếu sót trong cách tiếp cận của chúng ta hiện nay đó là trách nhiệm của những người thâm niên phải dạy dỗ cho thế hệ trẻ.

Tính nhà nghề

Bây giờ chúng ta tới vị trí để định nghĩa từ này: tính nhà nghề. Nó là cái gì nhỉ? Để hiểu được, chúng ta hãy nhìn vào từ người nhà nghề. Từ này trong tâm trí chúng ta gắn liền với kỹ năng và chất lượng. Nó gợi liên tưởng về một người đầy kinh nghiệm và năng lực. Một người nhà nghề là người có thể làm việc nhanh chóng, mà không vội vàng, là người đưa ra những ước lượng hợp lý và giữ đúng cam kết. Một người nhà nghề biết khi nào nói không, nhưng cũng rất nỗ lực để nói có. Một người nhà nghề là một người chuyên nghiệp.

Tính nhà nghề chính là tư duy của những người nhà nghề. Tính nhà nghề là một khái niệm bao gồm tất cả các giá trị, kỷ luật, kỹ thuật, thái độ và các câu trả lời.

Tính nhà nghề được truyền từ người này sang người khác. Nó được những người thâm niên dạy lại cho những người trẻ. Nó là sự trao đổi giữa những người ngang cấp. Nó cũng được quan sát và học hỏi ngược lại, như khi những người thâm niên quan sát học hỏi những người trẻ. Tính nhà nghề có khả năng lây truyền, nó là một dạng của virus tinh thần. Bạn nắm bắt được nó bằng cách quan sát những người khác và để cho bạn nắm giữ được quan niệm đó.

Thuyết phục người khác

Bạn không thể thuyết phục người khác trở thành những người nhà nghề được. Bạn không thể thuyết phục họ chấp nhận tính nhà nghề được. Những lý luận không hiệu quả. Dữ liệu không hợp lý. Trường hợp thực tiễn không có ý nghĩa gì cả. Việc chấp nhận một quan niệm thường không phải là quyết định dựa trên lý trí mà chủ yếu dựa trên cảm xúc. Đây là một điều rất bình thường của một con người.

Vậy làm cách nào bạn khiến người khác áp dụng tính nhà nghề? Hãy nhớ rằng mọi quan niệm có tính lây truyền, nhưng chỉ khi nó có thể quan sát được. Vì vậy bạn hãy làm quan niệm đó quan sát được. Bạn hãy cư xử như một tấm gương. Bạn hãy trở thành một người nhà nghề trước, và để tính nhà nghề của bạn được thể hiện. Sau đó chỉ để cho quan niệm đó làm nốt phần việc còn lại.

Kết luận

Trường học có thể dạy về lý thuyết lập trình máy tính. Nhưng trường học không, và không thể dạy kỷ luật, thực tiễn, và kỹ năng để trở thành một người nhà nghề. Những điều này sẽ được đúc kết qua nhiều năm bản thân bạn được kèm cặp và dạy bảo. Đã đến lúc những người trong ngành công nghiệp phần mềm phải đối mặt với thực tế rằng việc hướng dẫn một khóa lập trình viên phần mềm tiếp theo để họ trưởng thành sẽ là trách nhiệm của chúng ta, không phải thuộc về các trường đại học. Đã đến lúc chúng ta áp dụng một chương trình dài hạn của những người học việc, thực tập sinh, và những người dẫn hướng.


[1] CS: Computer Science – Khoa Học Máy Tính.

[2] Vẫn còn có nhiều website cung cấp các chương trình mô phỏng loại máy tính này.

[3] flip-flop: là một thiết bị điện tử có thể lưu trữ thông tin trạng thái 1-bit.

[4] cổng and (and-gate) là loại thiết bị điện tử thực hiện phép logic AND với hai hoặc nhiều đầu vào.

[5] Tôi vẫn còn giữ bản hướng dẫn này. Nó nằm ở một vị trí danh dự trên một trong những giá sách của tôi.

[6] Thuyền trưởng Kirk là một nhân vật trong phim Star Trek.

[7] octal: hệ bát phân.

[8] op-code: các mã lệnh của hợp ngữ assembly.

Clean Coder – Chương 13 – Nhóm Và Dự Án

Điều gì xảy ra nếu bạn có rất nhiều dự án con phải hoàn thành? Bạn phân chia những dự án đó cho các lập trình viên như thế nào? Điều gì xảy ra nếu bạn có một dự án thực sự lớn phải hoàn thành?

Nó có bị trộn lẫn không?

Tôi đã từng tư vấn cho một số các ngân hàng và công ty bảo hiểm nhiều năm qua. Họ dường như có điểm chúng một điều đó là cách thức kỳ lạ mà họ phân chia các dự án.

Thông thường một dự án tại ngân hàng sẽ là một công việc tương đối nhỏ chỉ cần một hoặc hai lập trình viên làm trong vài tuần. Dự án này sẽ thường được giao cho một quản lý dự án, người này cũng quản lý các dự án khác. Nó sẽ bao gồm một người phân tích nghiệp vụ, người này cũng sẽ cung cấp những yêu cầu phần mềm cho các dự án khác. Nó sẽ bao gồm vài lập trình viên cũng đang làm việc cho các dự án khác. Một hoặc hai người kiểm tra sẽ được giao nhiệm vụ, và họ cũng sẽ làm việc ở các dự án khác.

Bạn nhìn thấy cách làm việc ở đây chưa? Dự án đó quá nhỏ để giao cho một cá nhân nào đó làm toàn thời gian. Mỗi người sẽ làm việc tại dự án đó 50% hoặc thậm chí 25% thời gian của họ.

Hiện tại có một quy tắc là: Không có thứ gì gọi là nửa người cả.

Không có ý nghĩa gì khi nói với một lập trình viên là dành nửa thời gian của họ cho dự án A và phần thời gian còn lại của họ cho dự án B, đặc biệt là khi hai dự án này có hai người quản lý dự án khác nhau, những người phân tích nghiệp vụ khác nhau, những lập trình viên khác nhau, và những người kiểm tra khác nhau. Sao có thể gọi một đội hình quái dị như vậy là một nhóm được? Đó không phải là một nhóm, đó là thứ gì đó chui ra từ một máy xay sinh tố.

Nhóm gắn kết

Để một nhóm hình thành thì cần thời gian. Các thành viên trong nhóm bắt đầu hình thành mối quan hệ. Họ học cách để cộng tác với những người khác. Họ học thói quen, điểm mạnh, và điểm yếu của người khác. Cuối cùng thì nhóm đó mới bắt đầu gắn kết được.

Có một vài phép màu thực sự đối với một nhóm gắn kết. Họ có thể làm ra những điều kỳ diệu. Họ đoán trước được những người khác, che chở cho nhau, hỗ trợ lẫn nhau, và đòi hỏi những người khác phải làm những gì tốt nhất. Họ thực hiện được mọi thứ.

Một nhóm gắn kết thường bao gồm khoảng một chục người. Nhiều thì nó có thể là 20 người hoặc ít thì là 3 người, nhưng con số tốt nhất có lẽ là ở quanh con số 12. Nhóm cần phải bao gồm các lập trình viên, người kiểm tra, và người phân tích nghiệp vụ. Và nó cũng cần phải có một người quản lý dự án.

Tỷ lệ của lập trình viên trên người kiểm tra và người phân tích nghiệp vụ có thể thay đổi lớn, nhưng tỷ lệ 2:1 là một con số ổn. Vậy nên một nhóm gắn kết đẹp 12 người có thể có 7 lập trình viên, 2 người kiểm tra, 2 người phân tích nghiệp vụ, và 1 người quản lý dự án.

Những người phân tích nghiệp vụ sẽ xây dựng các yêu cầu phần mềm và viết các bài acceptance test tự động cho nhóm. Những người kiểm tra cũng viết các bài acceptance test tự động. Sự khác biệt giữa hai nhóm đó là ở góc nhìn. Cả hai đều viết yêu cầu hệ thống. Nhưng những người phân tích nghiệp vụ tập trung vào giá trị doanh nghiệp; còn người kiểm tra thì tập trung vào tính chính xác. Người phân tích nghiệp vụ viết các bài test của các trường hợp “happy path”; còn người kiểm tra lo về những gì có thể xảy ra sai sót, và viết các bài test của trường hợp lỗi và các giới hạn biên.

Người quản lý dự án theo dõi tiến độ của nhóm, và đảm bảo rằng nhóm hiểu rõ lịch làm việc và thứ tự ưu tiên.

Mỗi thành viên của nhóm có thể chơi một vai trò phụ là huấn luyện viên, hoặc thầy dạy, với trách nhiệm bảo vệ quy trình và các kỷ luật của nhóm. Họ đóng vai trò thức tỉnh nhóm khi nhóm có dấu hiệu đi lệch quy trình do áp lực về lịch trình làm việc.

Sự lên men

Cần phải có thời gian để một nhóm như vậy thấy được sự khác biệt của họ, thống nhất với nhau và thực sự gắn kết. Việc này có thể mất 6 tháng. Nó có thể thậm chí mất 1 năm. Nhưng một khi điều này xảy ra, đó sẽ là một phép màu. Một nhóm gắn kết sẽ lập kế hoạch cùng nhau, giải quyết vấn đề cùng nhau, đối mặt với các vấn đề cùng nhau, và hoàn thành mọi thứ.

Một khi điều này xảy ra, sẽ thật lố bịch khi phá vỡ nhóm chỉ bởi vì một dự án sắp kết thúc. Tốt nhất là hãy giữ nhóm đó lại với nhau và tiếp tục dự án.

Điều gì tới trước, Nhóm hay Dự án?

Các ngân hàng và các công ty bảo hiểm luôn cố gắng hình thành các nhóm xoay quanh các dự án. Đây là một cách tiếp cận xuẩn ngốc. Những nhóm như vậy đơn giản là không thể gắn kết. Các cá nhân chỉ làm việc với dự án trong một thời gian ngắn, và chỉ trong một phần trăm thời gian của họ, và do đó họ không bao giờ học được cách làm việc với những người khác.

Các tổ chức phát triển phần mềm chuyên nghiệp phân bố các dự án cho những nhóm gắn kết đang có, họ không dựng nên các nhóm xoay quanh các dự án. Một nhóm gắn kết có thể chấp nhận nhiều dự án đồng thời và sẽ phân chia công việc dựa theo ý kiến, kỹ năng và khả năng của chính họ. Một nhóm gắn kết sẽ hoàn thành được các dự án.

Nhưng bạn làm cách nào để quản lý được nhóm đó?

Mỗi nhóm có một tốc độ riêng. Tốc độ của nhóm đơn giản là khối lượng công việc mà nó có thể hoàn thành trong một khoảng thời gian cố định. Một số nhóm đo lường tốc độ của họ bằng điểm mỗi tuần, trong đó điểm là một đơn vị của mức độ phức tạp. Họ chia nhỏ các chức năng của mỗi dự án mà họ đang làm và ước lượng chúng thành các điểm số. Sau đó họ đo xem họ đã hoàn thành được bao nhiêu điểm mỗi tuần.

Tốc độ là một con số đo lường thống kê. Một nhóm có thể đạt được 38 điểm hoàn thành 1 tuần, 42 điểm vào tuần tiếp theo, và 25 điểm vào tuần tiếp nữa. Tính trung bình các con số này trong một khoảng thời gian sẽ ra tốc độ trung bình.

Người quản lý có thể đặt mục tiêu cho mỗi dự án mà nhóm phụ trách. Lấy ví dụ, nếu tốc độ trung bình của một nhóm là 50 và họ có 3 dự án đang làm, thì người quản lý có thể đề nghị họ phân chia tốc độ cho mỗi dự án là 15, 15, và 20.

Bên cạnh việc có một nhóm gắn kết làm việc trong các dự án của bạn, ưu điểm của cách làm này là trong trường hợp khẩn cấp, công ty có thể nói “Dự án B đang gặp khủng hoảng; hãy dành 100% sức lực của các cậu vào dự án đó trong 3 tuần tiếp theo nhé.”

Phân bố lại mức độ ưu tiên một cách nhanh chóng là điều gần như không thể với những nhóm sinh ra theo kiểu máy xay, nhưng các nhóm gắn kết đang làm việc trong hai hoặc ba dự án đồng thời thì có thể thực hiện được điều này trong một nốt nhạc.

Song đề chủ dự án

Một trong những khó chịu đối với cách tiếp cận mà tôi đang ủng hộ đó là các chủ dự án sẽ mất đi an tâm và quyền lực. Các chủ dự án có một nhóm chuyên tâm cho dự án của họ thì họ có thể dựa vào nỗ lực của nhóm đó. Họ biết điều đó bởi vì việc hình thành và giải tán một nhóm là một hành động đắt giá, công ty sẽ không loại bỏ nhóm đó vì những lý do ngắn hạn.

Mặt khác, nếu các dự án được đưa cho những nhóm gắn kết, và nếu những nhóm này chạy vài dự án cùng một lúc, thì công ty sẽ không phải thay đổi mức độ ưu tiên khi cần. Điều này có thể làm cho người chủ dự án không an tâm về tương lai. Các tài nguyên mà người chủ dự án phụ thuộc vào có thể đột nhiên bị lấy mất.

Thành thực mà nói thì tôi thích tình huống sau hơn. Công ty sẽ không bị trói tay bởi những khó khăn trong việc hình thành và giải tán các nhóm. Nếu công ty quyết định rằng một dự án có mức độ ưu tiên cao hơn dự án khác, nó có thể phân bố lại tài nguyên một cách nhanh chóng. Trách nhiệm của người chủ dự án là phải tạo điều kiện cho dự án của anh ta.

Kết luận

Các nhóm làm việc khó để xây dựng được hơn là các dự án. Bởi vậy tốt hơn hết là hãy hình thành những nhóm làm việc đi cùng nhau lâu dài từ dự án này sang dự án khác và có thể đảm nhận nhiều hơn một dự án vào một thời điểm. Mục tiêu trong việc hình thành một nhóm đó là tạo điều kiện cho họ có đủ thời gian để gắn kết, và sau đó giữ họ lại với nhau để trở thành một cỗ máy giúp cho nhiều dự án được hoàn thành.

Tham khảo

[RCM2003]: Robert C. Martin, Agile Software Development: Principles, Patterns, and Practices, Upper Saddle River, NJ: Prentice Hall, 2003.

[COHN2006]: Mike Cohn, Agile Estimating and Planning, Upper Saddle River, NJ: Prentice Hall, 2006.

Clean Coder – Chương 12 – Cộng Tác

Phần lớn phần mềm được tạo ra bởi các nhóm làm việc. Nhóm làm việc hiệu quả nhất khi các thành viên trong nhóm đó cộng tác với nhau một cách chuyên nghiệp. Thật thiếu chuyên nghiệp khi là một kẻ cô đơn hoặc một kẻ xa lánh trong nhóm.

Vào năm 1974, khi đó tôi 22 tuổi. Đám cưới của tôi với người vợ tuyệt vời của tôi, Ann Marie, khi đó mới được 6 tháng. Ngày sinh của đứa con đầu lòng của tôi, Angela, vẫn còn một năm nữa mới tới. Và tôi đang làm việc cho một chi nhánh của Teradyne được biết với cái tên Chicago Laser Systems.

Làm việc ngay cạnh tôi là cậu bạn thời trung học của tôi, Tim Conrad. Tim và tôi đã làm được một vài thứ khá kỳ diệu trong thời đại của chúng tôi. Chúng tôi đã cùng nhau dựng ra những chiếc máy vi tính trong tầng hầm nhà anh ấy. Chúng tôi đã xây những chiếc thang của Jacob trong nhà tôi. Chúng tôi đã dạy nhau cách để lập trình những chiếc máy PDP-8 và cách để nối các mạch tích hợp với các transistor vào các máy tính chức năng.

Chúng tôi là những lập trình viên đang làm việc trong một hệ thống dùng tia laser để cắt các bộ phận điện tử như điện trở và tụ điện với độ chính xác cực kỳ cao. Lấy ví dụ, chúng tôi đã cắt tinh thể cho chiếc đồng hồ kỹ thuật số đầu tiên, Motorola Pulsar.

Chiếc máy vi tính chúng tôi lập trình là chiếc M365, một bản sao chiếc PDP-8 của Teradyne. Chúng tôi đã viết bằng ngôn ngữ assembly, và source code của chúng tôi được lưu giữ trên các cuộn băng từ. Mặc dù chúng tôi có thể sửa chữa code trên màn hình, nhưng quy trình đó khá rắc rối, vì vậy chúng tôi đã dùng các danh sách in cho phần lớn code của chúng tôi để đọc và sửa sơ bộ.

Chúng tôi không có phương tiện nào để tìm kiếm trên toàn bộ code base. Không có cách nào để tìm tất cả những nơi mà một function đã được gọi hoặc một hằng số đã được dùng. Như bạn có thể tưởng tượng, điều này gây khá nhiều trở ngại.

Vì vậy vào một ngày Tim và tôi quyết định là chúng tôi sẽ viết một chương trình tạo tham khảo chéo (cross-reference generator). Chương trình này sẽ đọc các cuộn băng mã nguồn của chúng tôi và in ra một danh sách của tất cả các ký hiệu, kèm với file và số dòng nơi mà ký hiệu đó được dùng.

Chương trình này ban đầu khá đơn giản để viết. Nó đơn giản là chỉ đọc trong các cuộn băng mã nguồn, phân tích cú pháp ngôn ngữ assembly, tạo ra một bảng ký hiệu, và thêm các tham chiếu vào các đầu nhập. Nó hoạt động tuyệt vời nhưng lại chậm kinh khủng. Nó phải mất hơn một giờ để xử lý Chương Trình Vận Hành Chủ (Master Operating Program – MOP) của chúng tôi.

Nguyên nhân nó chậm như vậy là do chúng tôi để bảng ký hiệu đang lớn dần trong một vùng nhớ đệm đơn. Bất cứ khi nào chúng tôi tìm thấy một tham chiếu mới, chúng tôi lại chèn nó vào trong bộ đệm đó, di chuyển phần còn lại của bộ đệm xuống vài byte để tạo không gian.

Tim và tôi không phải là những chuyên gia về cấu trúc dữ liệu và thuật toán. Khi đó chúng tôi chưa bao giờ nghe về các hash table[1] hay binary search[2]. Chúng tôi không có manh mối gì để tìm ra được một thuật toán nhanh hơn. Chúng tôi chỉ biết rằng thứ mà chúng tôi đang làm quá chậm.

Vì vậy chúng tôi đã thử hết cách này đến cách khác. Chúng tôi đã cố gắng đặt các tham chiếu vào trong các linked list[3]. Chúng tôi thử để những khoảng trống trong dãy dữ liệu và chỉ mở rộng vùng đệm khi những khoảng trống này đã đầy. Chúng tôi thử tạo ra những linked list của khoảng trống. Chúng tôi thử tất cả các loại ý tưởng điên rồ.

Chúng tôi đứng trước bảng trong văn phòng của chúng tôi và vẽ vài sơ đồ mô tả cấu trúc dữ liệu và thực hiện tính toán để dự đoán hiệu năng. Chúng tôi tới văn phòng mỗi ngày với một ý tưởng mới khác. Chúng tôi đã cộng tác với nhau giống như những người bạn.

Một vài thứ mà chúng tôi thử cũng giúp tăng hiệu năng. Một số thì còn làm chậm đi. Điều đó thật đáng buồn. Đây là lần đầu tiên tôi phát hiện ra việc tối ưu phần mềm khó như thế nào, và quy trình này không trực quan tý nào.

Cuối cùng thì chúng tôi cũng làm cho thời gian chạy giảm xuống dưới 15 phút, nó rất gần với khoảng thời gian cần để đọc một cuộn băng mã nguồn. Vì vậy chúng tôi khá hài lòng.

Lập trình viên Vs Mọi người

Chúng tôi không trở thành các lập trình viên bởi vì chúng tôi thích làm việc với con người. Như là một quy luật, chúng tôi thấy mối quan hệ giữa con người với nhau rất lộn xộn và khó đoán. Chúng tôi thích hoạt động gọn gàng và đoán biết trước được của những cỗ máy mà chúng tôi lập trình. Chúng tôi là những người hạnh phúc nhất khi chúng tôi ở một mình trong phòng nhiều giờ, tập trung cao độ vào một vài vấn đề thực sự thú vị.

OK, đó là một sự tổng quát hóa quá lớn và có vô số các trường hợp ngoại lệ. Có rất nhiều những lập trình viên giỏi trong việc làm việc với mọi người và thích thú với thử thách đó. Nhưng nhóm trung bình vẫn có khuynh hướng như tôi đã đề cập. Chúng tôi, những lập trình viên, thích được cảm giác yên lặng và chui mình vào trong tổ kén của sự tập trung.

Lập trình viên Vs Ông chủ

Trong những thập niên 70 và 80, khi đang làm việc lập trình ở Teradyne, tôi đã rèn luyện để trở thành thực sự giỏi việc debug. Tôi yêu thử thách này và sẽ dấn thân vào những vấn đề bằng tất cả đam mê và nhiệt tình. Không bug nào có thể trốn lâu dài được đối với tôi!

Khi tôi giải quyết được một bug, nó có cảm giác giống như giành được một chiến thắng, hay như tiêu diệt được Jabberwock[4]! Tôi sẽ tới gặp sếp tôi, Ken Finder, với lưỡi dao Vorpa[5] trên tay, và mô tả hăng say với ông ấy bug đó thú vị như thế nào. Một ngày nọ, Ken cuối cùng cũng đã bộc bạch trong thất vọng của tôi: “Các bug chẳng thú vị gì hết. Bug chỉ cần được sửa mà thôi!”

Tôi đã học được vài điều từ ngày hôm đó. Việc đam mê về những thứ chúng ta làm cũng là điều tốt. Nhưng bạn cũng cần để ý tới mục tiêu của những người trả tiền cho bạn.

Trách nhiệm đầu tiên của lập trình viên chuyên nghiệp là đáp ứng được yêu cầu của ông chủ. Điều đó có nghĩa là hãy cộng tác với những người quản lý, những người phân tích nghiệp vụ, những người kiểm tra, và những thành viên khác trong nhóm để hiểu sâu sắc về mục tiêu của công ty. Điều này không có nghĩa bạn phải trở thành một người am hiểu về kinh doanh. Nó có nghĩa là bạn cần hiểu tại sao bạn đang viết code, và cái công ty đã thuê bạn đó sẽ được lợi ích gì từ nó.

Điều tệ nhất mà một lập trình viên có thể làm là chôn vùi anh ta sung sướng trong một hầm mộ công nghệ trong khi mà công ty của anh ta thì đang lao đao và sắp bốc cháy rừng rực ngay bên cạnh. Công việc của bạn là phải giữ cho công ty đó không bị chết chìm!

Vì vậy, những lập trình viên chuyên nghiệp sẽ dành thời gian để hiểu về công ty của mình. Họ nói chuyện với người dùng về phần mềm mà họ đang sử dụng. Họ nói chuyện với nhân viên bán hàng và marketing về những vấn đề mà họ đang gặp phải. Họ nói chuyện với quản lý của họ để hiểu về các mục tiêu ngắn và dài hạn của nhóm.

Nói ngắn gọn, họ quan tâm tới con thuyền mà họ đang chèo trên đó.

Chỉ có một lần tôi bị đuổi việc khỏi công việc lập trình là vào năm 1976. Vào thời điểm đó, tôi đang làm việc cho tập đoàn Outboard Marine Corp. Tôi có nhiệm vụ viết một hệ thống tự động hóa nhà máy bằng các hệ thống máy tính IBM System/7 để theo dõi hàng tá những máy đúc nhôm trong nhà xưởng.

Về mặt kỹ thuật thì đây là một công việc thử thách và đáng làm. Kiến trúc của hệ thống System/7 thật hấp dẫn, và hệ thống tự động hóa nhà máy bản thân nó đã thực sự rất thú vị rồi.

Chúng tôi cũng có một nhóm thật tuyệt. Trưởng nhóm, John, là một người có trình độ và nhiệt tình. Hai đồng đội lập trình của tôi cũng là những người dễ thương và sẵn lòng giúp đỡ. Chúng tôi có một phòng thí nghiệm được dành riêng cho dự án, và tất cả chúng tôi đều làm việc trong phòng thí nghiệm đó. Đối tác kinh doanh của công ty cũng tham gia vào và làm việc trong phòng thí nghiệm đó với chúng tôi. Người quản lý chúng tôi, Ralph, là một người giỏi chuyên môn, tập trung, và chịu trách nhiệm.

Mọi thứ lẽ ra phải rất tuyệt vời. Vấn đề ở đây là tôi. Tôi có đủ đam mê về dự án này, và về công nghệ, nhưng ở tuổi 24 tôi đơn giản là không có chút quan tâm nào tới công ty và về cấu trúc chính trị nội bộ của nó.

Sai lầm đầu tiên của tôi là vào ngày đầu tiên đi làm. Tôi đã ra mắt mà không đeo cà-vạt. Tôi đã đeo khi đi phỏng vấn, và tôi đã thấy mọi người khác đều đeo cà-vạt, nhưng tôi đã không kết nối được với việc đó. Vì vậy vào ngày đầu tiên đi làm, Ralph đã gặp tôi và nói rõ rằng “Ở đây chúng ta phải đeo cà-vạt.”

Tôi không thể nói với bạn tôi bực tức về điều đó như thế nào. Nó làm tôi bực mình tới tận óc. Sau đó hằng ngày tôi đều đeo cà-vạt, và tôi ghét nó. Nhưng tại sao? Tôi biết tôi đang làm việc ở đâu. Tôi biết quy tắc họ đặt ra. Tại sao tôi lại bực mình nhỉ? Bởi vì tôi là một kẻ ti tiện đáng khinh nhỏ bé, chỉ yêu bản thân và ích kỷ.

Tôi không hoàn thành công việc đúng hạn. Và tôi nghĩ như vậy cũng chẳng sao. Sau cùng thì tôi cũng đang làm “tốt công việc”. Và đó là sự thực, tôi làm rất tốt công việc viết chương trình của tôi. Tôi dễ dàng trở thành lập trình viên kỹ thuật tốt nhất trong nhóm. Tôi có thể viết code nhanh hơn và tốt hơn bất cứ ai khác. Tôi có thể chẩn đoán và giải quyết các vấn đề nhanh hơn. Tôi biết là tôi rất có giá trị. Vì vậy thời gian và ngày tháng không quan trọng nhiều lắm đối với tôi.

Quyết định sa thải được đưa ra một ngày sau khi tôi không hoàn thành đúng thời hạn một cột mốc của dự án. John đã nói rõ với tất cả chúng tôi là anh ấy cần một bản demo của các chức năng đang hoạt động vào thứ Hai tới. Tôi chắc chắn là tôi biết về điều này, nhưng ngày tháng và thời gian đơn giản là không quan trọng đối với tôi.

Chúng tôi tích cực phát triển. Hệ thống vẫn chưa đưa vào hoạt động thực tế. Không có lý do gì để hệ thống chạy khi mà không có ai ở trong phòng thí nghiệm. Tôi lại là người cuối cùng rời khỏi đó vào thứ Sáu, và tôi rõ ràng đã để hệ thống đó ở trạng thái không hoạt động. Thực tế thì việc thứ Hai là một ngày quan trọng không hề nằm trong đầu tôi.

Tôi đã đi muộn một giờ vào ngày thứ Hai đó và nhìn mọi người tập trung ủ rũ xung quanh một hệ thống không hoạt động. John hỏi tôi, “Tại sao hôm nay hệ thống này không hoạt động, Bob?”. Câu trả lời của tôi: “Tôi không biết.” Và tôi ngồi xuống để debug nó. Tôi vẫn không hề suy nghĩ về buổi demo thứ Hai, nhưng tôi có thể biết có điều gì đó không ổn bằng ngôn ngữ cơ thể của những người khác xung quanh. Sau đó John tiến lại và thì thầm vào tai tôi, “Điều gì sẽ xảy ra nếu Stenberg quyết định ghé thăm nơi đây?” Sau đó ông ấy đi ra ngoài trong sự chán ghét.

Stenberg là VP[6] phụ trách tự động hóa. Ngày nay chúng ta gọi ông ấy là CIO[7]. Câu hỏi đó không có ý nghĩa gì đối với tôi cả. “Vậy thì sao chứ?” Tôi đã nghĩ. “Hệ thống này chưa đưa vào hoạt động, làm gì mà ghê gớm vậy?”

Tôi nhận được lá thư cảnh cáo đầu tiên vào ngày hôm sau. Bức thư viết rằng tôi phải thay đổi thái độ làm việc của tôi ngay lập tức hoặc “kết quả sẽ là việc chấm dứt hợp đồng nhanh chóng.” Tôi đã bị choáng váng!

Tôi dành một chút thời gian để phân tích cách hành xử của mình và bắt đầu nhận ra điều mà tôi đã làm sai. Tôi nói chuyện với John và Ralph về điều đó. Tôi quyết tâm thay đổi bản thân và công việc của mình.

Và tôi đã làm được! Tôi thôi không đi muộn. Tôi bắt đầu chú ý tới chính trị nội bộ. Tôi bắt đầu hiểu tại sao John rất lo lắng về Stenberg. Tôi bắt đầu hình dung ra tình huống xấu mà tôi đã đặt ông ấy vào khi không làm cho hệ thống hoạt động được vào ngày thứ Hai.

Nhưng những thứ đó là quá nhỏ bé, quá trễ rồi. Khuôn đã đúc xong. Tôi nhận một lá thứ cảnh cáo thứ hai một tháng sau đó vì một lỗi vặt mà tôi đã phạm phải. Tôi đã nhận ra rằng tại thời điểm đó, lá thư này chỉ mang tính thủ tục và quyết định chấm dứt hợp đồng với tôi đã được soạn sẵn. Nhưng tôi vẫn quyết tâm cứu vãn tình thế. Vì vậy tôi thậm chí đã làm việc chăm chỉ hơn.

Buổi họp chấm dứt hợp đồng diễn ra vài tuần sau đó.

Tôi đi về nhà ngày hôm đó với người vợ 22 tuổi đang bầu và phải nói với cô ấy rằng tôi đã bị đuổi việc. Đó là một trải nghiệm mà tôi không bao giờ muốn lặp lại lần nào nữa.

Lập trình viên Vs Lập trình viên

Các lập trình viên thường khó làm việc gần gũi với các lập trình viên khác. Điều này dẫn tới một số vấn đề thực sự kinh khủng.

Sở hữu code

Một trong những biểu hiện tệ nhất của một nhóm bất thường là khi mỗi lập trình viên xây một bức tường quanh code của anh ta và từ chối để những lập trình viên khác đụng vào nó. Tôi đã từng ở những nơi mà các lập trình viên thậm chí còn không cho lập trình viên khác xem code của họ. Đây là một công thức cho thảm họa.

Một lần tôi đã tư vấn cho một công ty mà nó đang phát triển các loại máy in cao cấp. Những chiếc máy này có nhiều bộ phận khác nhau như bộ cấp, bộ in, bộ xếp, bộ ghim, bộ cắt.v.v. Công ty này định giá mỗi thiết bị này khác nhau. Bộ cấp quan trọng hơn bộ xếp, và không gì quan trọng hơn bộ in.

Mỗi lập trình viên làm việc trên thiết bị của anh ta. Một tay viết code cho bộ cấp, một tay khác viết code cho bộ ghim. Mỗi người bọn họ nắm giữ công nghệ của họ và ngăn cho những người khác đụng vào code của họ. Ảnh hưởng chính trị mà những lập trình viên này nắm giữ thậm chí có ảnh hưởng trực tiếp tới việc công ty này định giá thiết bị mà họ phụ trách. Cậu lập trình viên làm việc với bộ in là bất khả xâm phạm.

Đây là một thảm họa đối với công nghệ. Là một nhà tư vấn tôi có thể thấy một số lượng khổng lồ code bị lặp lại và các interface giữa các module thì hoàn toàn lệch lạc. Nhưng không một lời khuyên nào của tôi có thể thuyết phục được những lập trình viên đó (hoặc công ty đó) thay đổi cách làm việc của họ. Dù gì thì việc đánh giá tiền lương của họ cũng gắn liền với mức độ quan trọng của thiết bị mà họ phụ trách mà.

Sở hữu tập thể

Tốt hơn nhiều nếu chúng ta phá vỡ tất cả các bức tường của việc sở hữu code và để cho nhóm là đối tượng sở hữu tất cả phần code đó. Tôi thích những nhóm mà bất cứ thành viên nào trong nhóm cũng có thể lấy về bất cứ module nào và tạo ra những thay đổi mà họ nghĩ là phù hợp. Tôi muốn nhóm sở hữu code, không phải là từng cá nhân.

Những lập trình viên chuyên nghiệp không ngăn chặn người khác làm việc trong code họ viết. Họ không dựng nên những bức tường chủ sở hữu quanh code họ viết. Thay vào đó, họ cùng nhau làm việc trên hệ thống đó nhiều nhất có thể. Họ học hỏi lẫn nhau bằng cách làm việc với những người khác trong những phần khác nhau của hệ thống.

Ghép đôi

Nhiều lập trình viên không thích ý thưởng lập trình ghép đôi. Tôi thấy lạ là phần lớn các lập trình viên sẽ ghép đôi trong trường hợp khẩn cấp. Tại sao? Bởi vì rõ ràng đó là cách hiệu quả nhất để giải quyết vấn đề. Nó chỉ đơn giản là cách làm theo câu châm ngôn cổ: Hai cái đầu thì tốt hơn là một cái đầu. Nhưng nếu ghép đôi là cách hiệu quả nhất để giải quyết một vấn đề trong trường hợp khẩn cấp, thì tại sao đó không phải là cách hiệu quả nhất để giải quyết vấn đề lúc bình thường?

Tôi sẽ không trích dẫn các nghiên cứu cho bạn, mặc dù tôi có thể đưa ra một vài cái. Tôi sẽ không kể cho bạn bất cứ giai thoại nào, mặc dù tôi có thể kể nhiều câu chuyện. Tôi thậm chí sẽ không nói cho bạn rằng bạn nên ghép đôi bao lâu. Tất cả điều tôi muốn nói với bạn đó là những lập trình viên chuyên nghiệp thì sẽ ghép đôi. Tại sao? Bởi vì ít nhất đối với một vài vấn đề thì đó là cách hiệu quả nhất để giải quyết. Nhưng đó không hẳn là nguyên nhân duy nhất.

Những lập trình viên chuyên nghiệp cũng ghép đôi bởi vì đó là cách tốt nhất để chia sẻ kiến thức với người khác. Những lập trình viên chuyên nghiệp không tạo ra những hầm chứa kiến thức. Thay vào đó, họ học những phần khác nhau của hệ thống và của công ty bằng cách ghép đôi với những người khác. Họ nhận thấy rằng mặc dù tất cả các thành viên trong nhóm đều có một vị trí chơi riêng, nhưng tất các thành viên trong nhóm cũng cần có thể chơi ở những vị trí khác trên sân.

Những người chuyên nghiệp ghép đôi bởi vì đó là cách tốt nhất để soát lại code. Không hệ thống nào mà lại chứa code chưa được soát lại bởi những lập trình viên khác. Có nhiều cách để tiến hành soát lại code; phần lớn chúng đều cực kỳ không hiệu quả. Cách hiệu quả nhất để soát lại code đó là cộng tác với nhau trong khi đang viết nó.

Tiểu não

Tôi đi trên chuyến tàu tại Chicago vào một buổi sáng năm 2000 trong thời kỳ cao trào của bong bóng “dot com” bị vỡ. Khi tôi bước xuống tàu trên sân ga, đập vào mắt tôi là một bảng thông cáo khổng lồ treo ở phía trên các cổng ra. Bảng hiệu này là của một công ty phần mềm danh tiếng đang tuyển dụng lập trình viên. Nó ghi: Hãy đến sử dụng tiểu não với những người giỏi nhất.

Tôi lập tức bị ấn tượng bởi sự ngu ngốc của một bảng hiệu như thế. Những người quảng cáo thiếu hiểu biết đang cố gắng thu hút một bộ phận các lập trình viên có kiến thức, thông minh, và kỹ thuật cao. Đây là loại người chắc chưa từng trải qua sự ngu xuẩn nào. Những người quảng cáo này đang có gắng gợi lên hình ảnh của việc chia sẻ kiến thức với những người rất thông minh khác. Không may thay, họ lại ám chỉ sai phần của bộ não, tiểu não, nó xử lý các điều khiển cơ bắp, chứ không phải là trí thông minh. Vì vậy rất nhiều người mà họ đang cố gắng thu hút đã giễu cợt một lỗi ngu ngốc như vậy.

Nhưng một điều khác đã kích thích tôi về bảng hiệu này. Nó làm tôi nghĩ về một nhóm người đang cố gắng sử dụng tiểu não. Do tiểu não ở đằng sau của bộ não, nên cách tốt nhất để sử dụng tiểu não là quay mặt lại người khác. Tôi tưởng tượng một nhóm các lập trình viên trong văn phòng, mỗi người ngồi một góc, quay lưng lại với người khác, nhìn chằm chằm vào màn hình trong khi đang đeo tai nghe. Đó là cách bạn sử dụng tiểu não đấy. Đó cũng không phải là một nhóm làm việc.

Những người chuyên nghiệp làm việc cùng nhau. Bạn không thể làm việc cùng nhau trong khi bạn ngồi tại một góc đeo tai nghe. Vậy nên tôi muốn bạn ngồi quanh bàn đối diện với những người khác. Tôi muốn bạn có thể đánh hơi thấy nỗi sợ hãi của người khác. Tôi muốn bạn có thể nghe thấy những lời lẩm bẩm bực bội của người khác. Tôi muốn có những giao tiếp thường xuyên, cả bằng miệng và bằng ngôn ngữ cơ thể. Tôi muốn bạn giao tiếp như một thực thể.

Có thể bạn tin rằng bạn làm việc tốt hơn khi bạn làm việc một mình. Điều đó có thể đúng, nhưng điều đó không có nghĩa là nhóm của bạn làm việc tốt hơn khi bạn làm việc một mình. Và, trong thực tế, rất khó có khả năng là bạn làm việc tốt hơn khi bạn làm việc một mình.

Có những lúc khi làm việc một mình là điều nên làm. Có những lúc bạn cần suy nghĩ lâu và kỹ lưỡng về một vấn đề. Có những lúc công việc vặt vãnh đến nỗi sẽ là lãng phí nếu phải thêm một người khác làm việc cùng bạn. Nhưng, nói chung, tốt nhất là bạn hãy cộng tác chặt chẽ với những người khác và ghép đôi với họ trong phần lớn thời gian.

Kết luận

Có lẽ chúng ta không thích công việc lập trình phải làm việc với con người. Thật may mắn cho chúng ta. Làm lập trình thì có nghĩa là phải làm việc với con người. Chúng ta cần làm việc với khách hàng, và chúng ta cần làm việc với người khác. Tôi biết, tôi biết. Không phải thật tuyệt với ư nếu họ chỉ việc giam họ trong phòng với 6 màn hình khổng lồ, một dãy các bộ vi xử lý siêu nhanh chạy song song, RAM và ổ đĩa không giới hạn, và nguồn cung cấp vô hạn coca ăn kiêng và snack ngô cay? Lạy chúa, nó không phải như vậy. Nếu chúng ta thực sự muốn dành thời gian của chúng ta để lập trình, chúng ta sẽ phải học cách để nói chuyện với – con người.


[1] hash table: bảng băm, một loại cấu trúc dữ liệu.

[2] binary search: tìm kiếm nhị phân, một thuật toán tìm kiếm nhanh chóng.

[3] linked list: danh sách kết nối, một loại cấu trúc dữ liệu.

[4] Jabberwock: một con quái vật trong chuyện Alice ở xứ sở thần tiên.

[5] Vorpa: vũ khí của Alice trong chuyện.

[6] VP: Vice President – Phó Chủ Tịch.

[7] CIO: Chief Information Officer – Giám đốc Công nghệ thông tin.

Clean Coder – Chương 11 – Áp Lực

Tưởng tượng rằng bạn có một trải nghiệm thoát xác, quan sát bản thân mình nằm trên bàn phẫu thuật trong khi một bác sỹ phẫu thuật đang thực hiện phẫu thuật mổ tim trên người bạn. Bác sỹ phẫu thuật đó đang cố gắng cứu mạng sống của bạn, nhưng thời gian có hạn cho nên ông ấy đang phẫu thuật trong một deadline – một deadline theo đúng nghĩa đen.

Bạn muốn bác sỹ phải cư xử với bạn như thế nào khi đó? Bạn có muốn ông ấy trông bình tĩnh và tự chủ không? Bạn có muốn ông ấy báo rõ ràng và chính xác các yêu cầu cho đội hỗ trợ ông ấy không? Bạn có muốn ông ấy thực hiện theo những gì ông ấy được huấn luyện và bám theo những kỷ luật nghề nghiệp của ông ấy không?

Hay liệu bạn có muốn ông ấy toát mồ hôi hột và chửi thề không? Liệu bạn có muốn ông ấy đập mạnh và ném các dụng cụ không? Liệu bạn có muốn ông ấy than trách những người quản lý vì những mong muốn không thực tế và liên tục phàn nàn về thời gian không? Bạn muốn ông ấy hành xử như một người chuyên nghiệp, hay như là một người bình thường?

Những lập trình viên chuyên nghiệp rất bình tĩnh và kiên cường dưới áp lực. Khi áp lực tăng, họ gắn chặt mình vào việc rèn luyện và tính kỷ luật của mình, họ biết rằng chúng là cách tốt nhất để đạt được deadline và đạt được các cam kết đang gây áp lực lớn cho họ.

Vào năm 1988, tôi đang làm việc tại Clear Communications. Đây là một công ty khởi nghiệp nhưng chưa bao giờ hoàn toàn được khởi động. Chúng tôi đã qua được vòng tài chính ban đầu và sau đó tiến vào vòng hai, và sau đó là vòng ba.

Tầm nhìn của sản phẩm ban đầu nghe có vẻ hay, nhưng cấu trúc sản phẩm đó có vẻ không bao giờ có cơ sở. Đầu tiên, sản phẩm bao gồm cả phần mềm và phần cứng. Sau đó nó chỉ gồm có phần mềm. Nền tảng phần mềm đã thay đổi từ PC sang Sparcstations. Các khách hàng đã thay đổi từ cao cấp sang thấp cấp. Cuối cùng, ngay cả mục đích ban đầu của sản phẩm cũng bị trôi luôn khi mà công ty cố gắng tìm kiếm thứ gì đó có thể sinh ra lợi nhuận. Tôi đã dành gần bốn năm ở đó, và tôi không nghĩ rằng công ty đó thấy được một chút lợi nhuận nào cả.

Không cần phải nói, những lập trình viên chúng tôi đã phải chịu áp lực khủng khiếp. Đã có khá nhiều đêm rất dài, và thậm chí cả những ngày cuối tuần dài đằng đẵng trong văn phòng tại một đầu cuối. Các function được viết bằng ngôn ngữ C dài 3.000 dòng. Đã có những cuộc tranh cãi kèm những tiếng la hét và kêu tên. Đã có cả những vận động ngầm và những luận điệu lẩn tránh. Đã có những cú đấm thùm thụp vào tường, những chiếc bút bị ném đầy giận dữ vào bảng, những hình châm biếm của những tay đồng nghiệp khó chịu được vẽ lên tường bằng bút chì, và ở đó là một nguồn cung cấp những cơn giận dữ và căng thẳng không bao giờ chấm dứt.

Deadline được đưa ra dựa theo các sự kiện. Các chức năng phải được sẵn sàng cho các hội chợ thương mại hoặc các buổi demo cho khách hàng. Bất cứ điều gì mà khách hàng đề nghị, không quan tâm là nó ngu ngốc như thế nào thì chúng tôi cũng vẫn phải sẵn sàng cho lần demo tiếp theo. Thời gian thì luôn quá gấp. Công việc thì luôn chạy đằng sau. Lịch làm việc thì luôn quá tải.

Nếu bạn làm 80 giờ một tuần, bạn có thể trở thành người hùng. Nếu bạn hack được một mớ hỗn độn để nó có thể dùng demo cho khách hàng, bạn có thể trở thành người hùng. Nếu bạn làm đủ, bạn có thể được thăng chức. Nếu bạn làm không đủ, bạn có thể bị đuổi việc. Đó là một công ty khởi nghiệp, tất cả đều là “công bằng lao động”. Và vào năm 1988, với gần 20 năm kinh nghiệm dắt lưng, tôi đã tham gia vào công ty đó.

Tôi với vai trò là người quản lý phát triển, đã nói với các lập trình viên đang làm việc cho tôi là họ phải làm nhiều hơn và nhanh hơn. Tôi là một trong những tay làm 80 giờ một tuần, viết function ngôn ngữ C dài 3.000 dòng vào 2 giờ sáng trong khi những đứa trẻ nhà tôi đang ngủ ở nhà mà không có cha mình bên cạnh. Tôi là người đã ném bút và gào thét. Tôi là người đã sa thải những người không làm đúng theo ý tôi. Điều đó thật tồi tệ. Tôi thật tồi tệ.

Rồi cũng tới cái ngày khi vợ tôi buộc tôi nhìn chằm chằm vào gương. Tôi không hề thích cái hình ảnh mà tôi trông thấy. Cô ấy nói với tôi là gần đây tôi không được tốt. Tôi phải đồng ý về điều đó. Nhưng tôi không thích như vậy, nên tôi đã lao ra khỏi nhà trong giận dữ và bắt đầu bước đi vô định. Tôi đi bộ trong khoảng 30 phút, lòng vẫn sôi sục khi sải bước; và sau đó trời bắt đầu đổ mưa.

Và một điều gì đó đã nảy ra trong đầu tôi. Tôi bắt đầu cười. Tôi cười những hành động điên rồ của mình. Tôi cười sự căng thẳng của mình. Tôi cười vào người đàn ông trong gương, một kẻ đáng thương đang làm cho cuộc sống của chính ông ta và những người khác phải khốn khổ vì cái gì?

Mọi thứ thay đổi kể từ ngày hôm đó. Tôi đã ngừng những giờ phút điên rồ của mình. Tôi đã dừng lối sống căng thẳng cao độ đó. Tôi đã dừng ném bút và viết các function ngôn ngữ C dài 3.000 dòng. Tôi đã xác định rằng tôi sẽ tận hưởng sự nghiệp của mình bằng cách làm tốt hơn, chứ không phải làm một cách ngu ngốc.

Tôi đã rời công việc đó một cách chuyên nghiệp nhất mà tôi có thể, và tôi đã trở thành một tư vấn viên. Từ ngày đó, tôi không bao giờ gọi một người nào khác là “sếp” nữa.

Trốn tránh áp lực

Cách tốt nhất để có thể bình tĩnh trước áp lực là tránh các tình huống gây ra áp lực. Việc trốn tránh này không loại bỏ được hoàn toàn áp lực, nhưng nó có thể hướng tới việc tối thiểu hóa và làm ngắn được những chu kỳ áp lực cao.

Lời cam kết

Như chúng ta đã khám phá ở Chương 10, quan trọng là chúng ta phải tránh các cam kết deadline nếu chúng ta thấy không chắc có thể đạt được. Công ty sẽ luôn muốn những lời cam kết bởi vì họ muốn loại bỏ rủi ro. Điều chúng ta phải làm là đảm bảo rằng rủi ro này đã được lượng hóa và trình bày cho công ty để họ có thể quản lý nó một cách thích hợp. Việc chấp nhận cam kết những điều phi lý sẽ làm cản trở mục tiêu này và nó sẽ báo hại cho cả công ty và chúng ta.

Đôi khi lời cam kết lại được tự tạo ra cho chúng ta. Thỉnh thoảng chúng ta sẽ thấy công ty đưa ra lời hứa với khách hàng mà họ không hề tham khảo ý kiến của chúng ta. Khi điều này xảy ra, chúng ta rất vinh dự được buộc phải giúp công ty tìm cách đạt được những cam kết này. Tuy nhiên, chúng ta không vinh dự khi buộc phải chấp nhận những cam kết này.

Sự khác biệt này là rất quan trọng. Những người chuyên nghiệp sẽ luôn giúp công ty mình tìm cách để đạt được mục tiêu của nó. Nhưng những người chuyên nghiệp không cần phải chấp nhận những cam kết được tạo ra cho họ bởi công ty mình. Cuối cùng, nếu chúng ta không thể tìm ra cách nào để đạt được lời hứa mà công ty đã đưa ra thì người đã đưa ra lời hứa đó bắt buộc phải chịu trách nhiệm.

Điều này nói thì dễ. Nhưng khi công ty của bạn thất bại, và lương của bạn bị trễ bởi vì thiếu cam kết, thật khó để không cảm thấy áp lực được. Nhưng nếu bạn cư xử một cách chuyên nghiệp, thì ít nhất bạn vẫn có thể ngẩng cao đầu khi tìm một công việc mới.

Luôn gọn gàng, sạch sẽ

Cách để đi nhanh và giữ cho deadline trong phạm vi có thể, đó là luôn gọn gàng, sạch sẽ. Những người chuyên nghiệp không chấp nhận đánh đổi việc đi nhanh bằng cách tạo ra những mớ hỗn độn. Những người chuyên nghiệp nhận ra rằng “nhanh và bẩn” luôn là hai khái niệm ngược nhau. Bẩn luôn luôn nghĩa là chậm!

Chúng ta có thể tránh áp lực bằng cách giữ cho hệ thống của chúng ta, code của chúng ta, và thiết kế của chúng ta càng sạch càng tốt. Điều này không có nghĩa là chúng ta phải dùng quá nhiều thời gian để “đánh bóng” code. Nó đơn giản là chúng ta không chấp nhận những mớ code hỗn độn. Chúng ta biết rằng những mớ hỗn độn đó sẽ làm chậm chúng ta, làm cho chúng ta trễ hẹn và phá vỡ những cam kết. Vì vậy chúng ta làm tốt nhất có thể và giữ cho được đầu ra của chúng ta gọn gàng, sạch sẽ nhất mà chúng ta có thể.

Kỷ luật khủng hoảng

Bạn sẽ biết bạn tin tưởng vào điều gì khi bạn quan sát chính mình trong một cuộc khủng hoảng. Nếu trong khủng hoảng, bạn vẫn tuân thủ những kỷ luật của mình, thì có nghĩa là bạn thực sự tin vào những kỷ luật đó. Mặt khác, nếu bạn thay đổi hành vi của mình trong khủng hoảng, thì có nghĩa là bạn không thực sự tin vào những hành vi thường ngày của mình.

Nếu bạn tuân thủ các kỷ luật của TDD trong thời kỳ không khủng hoảng nhưng lại từ bỏ nó trong khi khủng hoảng thì có nghĩa là bạn không thực sự tin rằng TDD có ích. Nếu bạn giữ cho code của mình sạch trong khi bình thường nhưng lại làm ra những mớ code hỗn độn trong khi khủng hoảng thì có nghĩa là bạn không thực sự tin rằng mớ hỗn độn đó sẽ làm bạn chậm lại. Nếu bạn lập trình ghép đôi trong khủng hoảng nhưng bình thường bạn không ghép đôi thì có nghĩa là bạn tin rằng việc ghép đôi hiệu quả hơn so với không ghép đôi.

Lựa chọn những kỷ luật mà bạn cảm thấy thoải mái tuân theo trong khi khủng hoảng. Và sau đó luôn tuân thủ theo chúng mọi lúc. Việc tuân thủ những kỷ luật này là cách tốt nhất để tránh bị rơi vào khủng hoảng.

Đừng thay đổi hành vi của bạn khi khủng hoảng tới. Nếu kỷ luật của bạn là cách tốt nhất để làm việc, thì chúng cần được tuân thủ ngay cả khi bạn đang chìm trong khủng hoảng.

Giải quyết áp lực

Đón đầu, giảm nhẹ, và loại bỏ áp lực được là điều tốt, nhưng đôi lúc áp lực đến mặc cho những nỗ lực ngăn chặn nhất có thể của bạn. Đôi khi dự án mất nhiều thời gian hơn mọi người đã nghĩ ban đầu. Đôi khi thiết kế ban đầu sai và bắt buộc phải làm lại. Đôi khi bạn mất một thành viên nhóm có giá trị hoặc khách hàng. Đôi khi bạn đưa ra một cam kết mà bạn không thể giữ được. Nếu điều đó xảy ra thì sao?

Đừng sợ hãi

Bạn hãy kiểm soát sự căng thẳng của mình. Những đêm không ngủ không hề giúp bạn hoàn thành công việc nhanh hơn chút nào. Ngồi đó và day dứt cũng không thể giúp được gì. Và điều tệ nhất mà bạn có thể làm là vội vàng! Bạn hãy ngăn sự xúi giục đó bằng mọi giá. Việc vội vàng sẽ chỉ đưa bạn vào trong hố sâu hơn mà thôi.

Thay vào đó, hãy chậm lại. Hãy nghĩ kỹ về vấn đề. Hãy vẽ ra một tiến trình cho kết quả tốt nhất có thể, và sau đó hướng về kết quả đó với một tốc độ hợp lý và vững chắc.

Trao đổi

Bạn hãy để cho nhóm của bạn và quản lý của bạn biết rằng bạn đang gặp vấn đề. Hãy nói với họ về kế hoạch tốt nhất có thể có của bạn để thoát khỏi vấn đề đó. Hãy đề nghị họ đưa ra những lời khuyên và hướng dẫn. Hãy tránh tạo ra những bất ngờ. Không gì khiến người ta giận dữ hơn và mất lý trí hơn là những bất ngờ. Những bất ngờ chỉ làm áp lực nhân lên gấp 10 lần.

Dựa vào kỷ luật của bạn

Khi gặp khó khăn, bạn hãy tin tưởng vào những kỷ luật của bạn. Nguyên nhân bạn những kỷ luật là để dẫn đường cho bạn qua những lúc gặp áp lực cao. Đó là những lúc cần phải đặc biệt chú ý tới tất cả các kỷ luật của bạn. Đó không phải là lúc để đặt câu hỏi hay từ bỏ chúng.

Thay vì tìm kiếm thứ gì đó xung quanh trong sợ hãi, bất cứ thứ gì giúp bạn hoàn thành nhanh hơn, bạn hãy trở nên thận trọng và tận tâm tuân thủ những kỷ luật đã chọn của mình. Nếu bạn tuân thủ TDD, thì thậm chí hãy viết nhiều bài test hơn bình thường. Nếu bạn là một người hay refactor không thương tiếc, thì thậm chí hãy refactor nhiều hơn. Nếu bạn luôn giữ cho các function của mình nhỏ thì thậm chí hãy giữ cho chúng nhỏ hơn. Chỉ có cách duy nhất để thoát ra được áp lực của cái nồi áp suất đó là dựa vào những điều bạn biết là có tác dụng – những kỷ luật của bạn.

Nhận sự giúp đỡ

Hãy ghép đôi! Khi nhiệt đã nóng lên, hãy tìm một người hợp tác sẵn sàng để lập trình ghép đôi với bạn. Bạn sẽ hoàn thành nhanh hơn, với ít lỗi hơn. Cộng sự ghép đôi của bạn sẽ giúp bạn giữ được kỷ luật của bạn và giúp bạn khỏi hoảng sợ. Cộng sự của bạn sẽ chỉ ra những điều bạn quên, sẽ có những ý tưởng hữu ích, và sẽ nhận ra sự uể oải khi bạn mất tập trung.

Vì lẽ ấy, khi bạn nhìn thấy ai khác đang chịu áp lực, hãy ngỏ lời ghép đôi với họ. Hãy giúp họ thoát khỏi cái hố mà họ đang ở trong đó.

Kết luận

Mẹo để giải quyết áp lực là hãy tránh nó khi bạn có thể, và vượt qua nó khi bạn không thể. Bạn tránh nó bằng cách kiểm soát những cam kết, tuân thủ những kỷ luật của bạn, và giữ mọi thứ luôn gọn gàng, sạch sẽ. Bạn vượt qua nó bằng cách giữ bình tĩnh, trao đổi, tuân thủ những kỷ luật của bạn, và nhận lấy sự giúp đỡ.