Hãy đọc mã nguồn, đừng chỉ đọc tài liệu
Suốt hai năm đầu, tôi coi mã nguồn mở là thứ người khác viết còn tôi thì tiêu thụ. Tài liệu là để học; mã nguồn là việc của những người bảo trì. Đó là một sai lầm, và sửa nó đã thay đổi tốc độ tiến bộ của tôi nhiều hơn bất cứ điều gì khác tôi làm một cách có chủ đích.
Thứ tài liệu không nói được cho bạn
Tài liệu nói một hàm làm gì. Nó hiếm khi nói:
- Nó tốn gì. Có phải O(n) không? Nó có cấp phát không? Nó có lấy khóa không?
- Nó làm gì ở trường hợp biên mà tác giả không nghĩ tới việc ghi vào tài liệu.
- Vì sao API lại có hình dạng đó, thứ thường là điều hữu ích nhất để biết.
- Nó làm gì khi hỏng, ngoài câu “ném ra một lỗi”.
Cả bốn đều nằm trong mã nguồn, và cái thứ tư là thứ tiết kiệm cho tôi nhiều thời gian nhất. “Ném ra một lỗi” so với “trả về nil sau khi ghi log” so với “sập” là ba thứ hoàn toàn khác nhau để thiết kế xung quanh, còn tài liệu của cùng một hàm sẽ mô tả cả ba là “xử lý đầu vào không hợp lệ”.
Bắt đầu từ cái nhỏ
Sai lầm là cố đọc cả một codebase. Chẳng ai đọc cả một codebase. Đơn vị hiệu quả là một hàm mà bạn vốn đã dùng.
Cụ thể:
- Chọn một thứ bạn đã gọi trong tuần này.
Array.append.String.split.URLSession.data(for:). - Command-click vào nó trong Xcode để thấy phần khai báo.
- Tìm phần cài đặt thật — với thư viện chuẩn của Swift thì đó là repo
apple/swift, thư mụcstdlib/public/core/. - Đọc nó, lần xuống một tầng, rồi dừng.
Hai mươi phút. Lần đầu tôi làm việc này với Array.append, tôi rốt cuộc đã hiểu copy-on-write —
isKnownUniquelyReferenced, cái vùng đệm, cách sức chứa tăng lên — sau cả một năm đọc các bài blog
đều nói đúng một đoạn văn giống nhau.
Thứ gì đáng đọc
Thư viện chuẩn của Swift. Dễ đọc một cách đáng ngạc nhiên, chú thích tử tế, và đó là đoạn code
bạn dùng nhiều nhất. Array, String, Optional, Sequence. Các chú thích giải thích quyết định
thiết kế chứ không chỉ giải thích hành vi.
Các đề xuất Swift Evolution. Đây không phải mã nguồn nhưng chúng là thứ gần nhất với một bản lý
giải thiết kế mà ta có. Mọi tính năng ngôn ngữ đều có một cái, và nó bao gồm cả những phương án đã bị
loại cùng lý do. Đọc các đề xuất về async/await dạy tôi về concurrency có cấu trúc nhiều hơn mọi
bài hướng dẫn.
Bất kỳ phụ thuộc nào bạn đã phải gỡ lỗi hai lần. Nếu một thư viện đã làm bạn rối trí hơn một lần thì một giờ đọc mã nguồn của nó rẻ hơn lần rối trí thứ ba.
Thư viện chuẩn của Rust, nếu bạn viết Rust. Nó được chú thích rất kỹ và riêng các adapter
Iterator thì rất đáng đọc — chúng là minh chứng rõ ràng nhất tôi biết về việc các lớp trừu tượng
chi phí bằng không thật sự hoạt động ra sao.
Mẹo
Hãy đọc các bài test trước khi đọc phần cài đặt. Bộ test của một thư viện là tài liệu chạy được về mọi trường hợp biên mà tác giả nghĩ ra, và nó thường ngắn hơn phần cài đặt nhiều. Với câu hỏi “cái này làm gì khi đầu vào rỗng”, file test trả lời nhanh hơn mã nguồn.
Ba thứ giúp việc đó dễ hơn
Dùng git log và git blame trên phần khó hiểu. Một dòng trông kỳ quặc thường có một thông điệp
commit giải thích nó, và thường kèm một số hiệu issue. Cái dòng đó kỳ quặc là vì một con bug mà bạn
chưa đụng phải.
Đi theo một đường, đừng đi theo cấu trúc. Đừng cố hiểu cả module. Hãy chọn một điểm vào rồi lần theo một chuỗi lời gọi đi xuống. Hiểu được một đường xuyên qua một hệ thống dạy bạn nhiều hơn một tấm bản đồ các file của nó.
Chấp nhận rằng bạn không hiểu phần lớn nó. Tôi đọc những phần của thư viện chuẩn mà tôi cần rồi bỏ qua phần còn lại, kể cả những thứ đã hạ tôi hai lần. Đó là chuyện bình thường và không phải một thất bại — mục tiêu là trả lời một câu hỏi, không phải thấu hiểu một codebase.
Nó không phải để làm gì
Tôi không lập luận rằng bạn nên đọc mã nguồn thay cho tài liệu. Tài liệu nhanh hơn cho câu “các tham số là gì” và “có hàm nào làm X không”, và đó là phần lớn thứ bạn cần trong phần lớn các ngày.
Mã nguồn dành cho những câu hỏi mà tài liệu không trả lời được, và có một khoảnh khắc cụ thể mà cú chuyển ấy sinh lãi: khi hành vi được ghi trong tài liệu và hành vi quan sát được bất đồng với nhau. Tại thời điểm đó, mỗi phút đọc thêm tài liệu là một phút phí, vì tài liệu mô tả ý định còn bạn thì đang nhìn phần cài đặt.
Nhận ra khoảnh khắc đó cho nhanh chính là phần lớn kỹ năng. Phần còn lại là sẵn lòng mở cái file ra.