Professional Documents
Culture Documents
Giới thiệu
Một lập trình viên thành công muốn giỏi hơn thì cần xây dựng thói quen đọc
code hàng ngày.
Nếu như một ngày, bạn thức dậy và quyết tâm trở thành một nhà văn giỏi, bạn chắc hẳn đã
nghe tới 2 lời khuyên: viết thật nhiều vào và đọc nhiều hơn cả viết nữa.
JavaScript Front-End
Trong lập trình, nhiều người viết code nhưng hiếm có người dành thời gian đọc code, đặc
biệt là những dòng code ngoài phần công việc của họ. Đó thật sự là một sai lầm lớn. Khi
còn chưa muộn, hãy hành động giống như một coder đầy tham vọng và đọc thật nhiều code
vào.
Đọc nhiều và đọc thường xuyên là điều khác biệt giữa một software engineer bình thường
và một software engineer giỏi.
Bí quyết thành công trong ngành IT không phải từ tấm bằng đại học
Nguyên tắc '5 giờ' - Bí quyết thành công của các tỷ phú Bill Gates,
Warren Buffett, Oprah Winfrey
Những nhà văn vĩ đại đều học từ những nhà văn mà họ đã từng đọc. Ví dụ như Joan Didion,
người đã viết những câu trong Hemingway ở tuổi 16 để học cách viết câu. Hay như
Abraham Lincoln, người đã làm thơ trữ tình dựa trên cuốn kinh thánh King James mà ông
yêu thích.
Tương tự như thế, nhìn nhiều code thực tế sẽ mở mang kiến thức của bạn để có thể tự viết
code. Đọc code của người khác sẽ thấy được chức năng của các ngôn ngữ lập trình mới và
nhiều thể loại code khác nhau.
Đọc dependencies của bạn sẽ giúp bạn làm việc năng suất hơn. Bạn sẽ biết được đầy đủ
chức năng mà dependencies của bạn cung cấp. Bạn sẽ biết chính xác cách chúng hoạt động
và chúng đang tradeoff cái gì. Bạn sẽ biết nơi để debug khi có lỗi xảy ra.
Đọc code một cách thoải mái cũng hạn chế bớt sự “ảo tưởng” đối với code của chính bạn.
Bạn đọc càng nhiều, bạn càng cảm thấy code của người khác thú vị, thì bạn càng muốn làm
code của bạn tốt hơn. Sự thay đổi này sẽ làm giảm khả năng bạn bị mắc hội chứng “not
invented here”.
Chú thích: “Hội Chứng Not Invented Here” là khuynh hướng của một nhóm chủ thể
quá tin tưởng vào những kiến thức độc đoán trong lĩnh vực của mình, từ đó chối bỏ
những ý tưởng mới từ cá thể bên ngoài, đến mức tổn hại cả năng lực hoạt động của
chính bản thân nó.
Xem tiếp...
Nếu bạn là một người lập trình web, một data engineer hay một nhà mật mã học, trau dồi
việc đọc thường xuyên sẽ dạy bạn các công cụ và sản phẩm khác với những công việc
thường ngày của mình.
Đối với một web front-end, đọc một phần nhỏ codebase của raytracer sẽ đưa bạn đến một
loạt các ràng buộc khác nhau. Đối với một database engineer, đọc code web trừu tượng cao
có thể cho bạn biết người dùng của mình đang nghĩ gì. Còn đối với tất cả các kỹ sư phần
mềm, bạn sẽ tìm được giá trị trong việc đọc ngôn ngữ lập trình khác với ngôn ngữ mà bạn
đang dùng.
Như Donald Knuth nhấn mạnh: “đọc code thực sự đáng giá vì những thứ nó đem lại. Bạn
đọc càng nhiều code từ người khác, bạn càng có khả năng phát minh ra nhiều thứ trong
tương lai…”
Dưới đây là cách đọc code “không đau đớn” và năng suất nhất có thể dành cho bạn.
Đọc từ đầu nghĩa là bỏ qua context quan trọng và không có ý nghĩa đối với cấu trúc sau
này. Đọc thụ động – bạn sẽ không thể kiểm tra hoặc sửa lỗi – sẽ cản trở bạn thực sự đi sâu
vào các dòng code.
Không giống một cuốn sách, hầu hết những người bạn của mình đấu tranh để đọc code mà
không có mục tiêu cụ thể. Trước khi đọc một codebase mới, hãy chắc chắn rằng bạn có
mục tiêu muốn đạt được. Điều này sẽ làm cho codebase trở nên dễ quản lý hơn và tạo động
lực để vượt qua khi bạn thấy nó khó quá.
Mẹo vượt qua "ác mộng" khi làm việc với code của người khác
Mình sử dụng phương pháp RSDW để đọc bất cứ codebase khó hiểu nào:
Kiểm tra Structure: học cấu trúc level cao và xem các bài test tích hợp quan trọng.
Dive in: theo các luồng chính và đọc các cấu trúc dữ liệu quan trọng.
Write tests: Viết thử và ưu tiên các tính năng đơn giản và sửa lỗi.
Phương pháp RSDW chỉ là khởi động, nhưng về sau, bạn nên tự tìm cách riêng cho mình.
Một vài người thề chỉ viết test và sửa lỗi, trong khi người khác luôn thích bắt đầu bằng việc
xem các test tích hợp trước.
Thôi thì quay lại với phương pháp RSDW của mình nhé.
Run
Bước đầu trong việc đọc code không hẳn là đọc cho lắm. Chúng ta cần phải sử dụng phần
mềm.
Đọc code chỉ khi bạn hiểu chức năng phần mềm cung cấp. Trong giai đoạn này, bạn nên
nhìn tổng quan code và hiểu input và output có gì.
Sử dụng phần mềm bắt bạn phải làm nó chạy. Điều đó cũng có nghĩa là theo dõi các
dependencies và, đối với một vài ngôn ngữ nhất định là phải dịch code. Đối với các thư viện,
nó có nghĩa là gọi một vài chức năng phổ biến. Đây là thời điểm chạy thử nghiệm và xem
các thông báo đầu ra.
Nếu bạn gặp vấn đề khi hệ thống chạy lần đầu, đó là thời điểm tốt nhất để ghi lại cho người
khác cần những gì để chạy phần mềm.
Structure
Tiếp đến là xác định các phần quan trọng nhất của code. Quá trình này khác xa so với việc
đọc sách. Thay vì bắt đầu lúc bắt đầu, bạn phải đi xung quanh để tìm các mối quan hệ
chính trong code.
Bắt đầu với việc hiểu cấu trúc của code. Tối thiểu có thể chạy một vài tool tự động (như
tree và cloc) để tìm ra ngôn ngữ và file của codebase.
Để xác định các file chính, nhìn vào các file nhiều sửa đổi nhất và sử dụng bất kỳ tool nâng
cao nào khác cũng được. Xem lại các bài test tích hợp quan trọng, liệt kê các chức năng có
thể gọi tên. Đánh dấu các bài test này để sau.
Có 1 cách dễ dàng để rút ngắn quá trình này: Tìm một ai đó đã từng làm việc với loại code
này trước đây.
Hiểu cấu trúc là nhiệm vụ đầu tiên cho việc đọc code.
Deep Dives
Khi bạn đã có đất rồi, thì đào thôi.
Khi đọc code, bạn nên nhìn vào code flow (Nhìn các action đang được tạo ra) và cấu trúc dữ
liệu / các đối tượng (nơi mà kết quả chạy được lưu trữ)
Chọn từ 3-5 dòng quan trọng bạn thấy từ bài test tích hợp chính, PRs quan trọng hoặc lúc
bạn xem lại tệp nguồn. Sau đó đào sâu hơn. Bắt đầu từ đỉnh của một action đặc biệt và cứ
đi theo các dòng code. Một vài lập trình viên thích dùng các trình gỡ lỗi. Những người khác
thì thích tạo sơ đồ UML hay đồ thị flame hơn.
Đồ thị Flame
Nguồn: Wikimedia
UML Data Structure
Lần khác mình sẽ dừng tại điểm smack dab ở giữa một chức năng quan trọng, và tìm cách
đi đến stack để hiểu cách làm sao mình đến được đó. Nếu bạn quyết định làm theo code
một cách thủ công, nhớ thiết lập sẵn trình soạn thảo của bạn cho phép bạn sử dụng “go to
definition” và “find all references” một cách nhanh chóng.
Đối với cấu trúc dữ liệu, xem lại loại dữ liệu và khi nào các biến chính được bật. Sử dụng
trình gỡ lỗi để truy vấn những cấu trúc dữ liệu này vào những thời điểm quan trọng.
Ngoài các bài test tích hợp, cách tốt để tiếp cận một codebase mới chính là review lại các
pull request quan trọng. PRs thường dễ hiểu hơn, vì chúng gói gọn trong một tính năng tách
biệt. PRs cũng cung cấp nền tảng narrative ngoài lý do và cách bổ sung code.
Trong quá trình đào sâu này, mình mở 2 doc markdown. Doc đầu là “level up my coding” nơi
mình liệt kê các cú pháp mới mà mình thấy và các mẫu code mình thích khi tự học (người
khác gọi nó là bảng kê). Cái doc thứ 2 để liệt kê các câu hỏi quan trọng mình dành cho
những lập trình viên của codebase mình đang đọc. Ở giai đoạn này, mình cũng thêm vào
documentation khi tôi thấy gaps.
Quá trình deep dives này thường sẽ hiệu quả hơn nếu bạn thực hiện cùng với một người nào
đó biết về code. Nếu mình chỉ có ít thời gian với một lập trình viên trên project, mình luôn
để họ theo dõi mình qua các flow chính. Khi mình đã hiểu căn bản một ít dòng chính, sẽ dễ
dàng hơn khi mình tự đào.
Write Code
Không giống trong văn chương, nơi đọc và viết là 2 cái tách biệt, một phần quan trọng của
đọc code chính là viết code. Nếu không viết code, bạn không thể hiểu được một codebase. 2
cách tiếp cận dễ dàng để bắt đầu là viết test và giải quyết các feature/bug.
Viết test thử là một hình thức đọc tích cực, bắt bạn phải chú ý đến input và output của một
tương tác cụ thể. Viết code giúp hằn sâu code trong đầu bạn – cái mà việc đọc không thôi
thì không thể làm được.
Đối với mình, test từng phần là cách dễ dàng để bắt đầu. Khi mình thành thạo một số base,
mình có thể chuyển sang test tích hợp để hiểu hơn về codebase. Thỉnh thoảng mình sẽ viết
lại một test tích hợp đã có, để thử xem mình có hiểu cách một call quan trọng hoạt động
hay không.
Một cách tiếp cận khác dễ dàng hơn đó là viết tính năng đơn giản hoặc address những lỗi
dễ. Cả 2 cách này không yêu cầu bạn phải có kiến thức đầy đủ về codebase, nhưng vẫn bắt
bạn phải “đối đầu” với code. Đóng góp cách sửa bug và tài liệu liên quan cũng là một cách
dễ dàng để trả lại dependencies.
Những phương pháp này giúp bạn nhanh chóng hoàn thành khi bận đang cần. Bằng cách áp
dụng RSDW nhiều hơn với một vài bài học mở rộng, việc đọc code sẽ đỡ khó khăn hơn
nhiều.
Mặc dù vậy, phương pháp RSDW cũng là cách tiếp cận tốt khi bạn thấy code mới. Nó cũng
kích thích sự thú vị khi đọc code, có thể là viết test hoặc chủ động sử dụng một trình gỡ lỗi
để truy vấn cấu trúc dữ liệu. Quá trình đọc code khác xa so với quá trình đọc một cuốn
sách.
Bạn cũng sẽ tìm đọc code mới một cách hứng thú. Bạn lưu lại các dòng code và cố gắng giữ
đồng thời hàng chục cấu trúc dữ liệu và chức năng mới trong đầu. Đừng ngại nghỉ giải lao 1
tí khi bạn gặp một codebase mới. Khi mình bắt đầu với 1 codebase mới, một vài giờ rảnh
trong ngày để đọc là tất cả những gì mình cần để năng suất hơn.
Mặc dù nó rất quan trọng để phát triển các kỹ năng đọc tốt, nhưng cũng quan trọng không
kém khi suy nghĩ về những gì bạn đã đọc.
Cách dễ nhất để bắt đầu đọc, và với ROI cao nhất, là học các dependency của bạn. Nội bộ
hoá cách dependency của bạn làm việc để bạn dễ debug hơn trên toàn bộ hệ thống.
Một cách khác giúp mang lại năng suất cao khác là chọn một hệ thống quan trọng ở công ty
của bạn mà bạn giao tiếp, và thử đọc qua nó. Điều này không chỉ đem lại giá trị cho công
việc của bạn, mà các codebase chuyên nghiệp thì khác với codebase nguồn mở.
Ngoài các hệ thống mà bạn tương tác trực tiếp, hãy luôn sẵn sàng để đọc nhiều hơn nữa.
Những ngày đầu trong sự nghiệp của mình, mình khuyên các bạn nên dành 1 giờ đồng hồ
mỗi sáng hoặc mỗi tối để đọc code ngoài công việc hằng ngày của bạn. Nghe khá đau đớn
vì sau một ngày làm việc mệt mỏi rồi, nhưng hãy cố gắng lượm nhặt codebase bạn thích và
đào sâu vào nó trong 1 tuần thử nhé.
Ví dụ, Redis là nguồn nổi tiếng để bắt đầu học C. Để dễ đọc hơn và đọc được nhiều
codebase phức tạp hơn, cách đơn giản là bắt đầu đọc từ subsystem cụ thể.
Các dự án phụ cũng là một cách tốt để đọc code, vì chúng buộc bạn phải học một thế giới
khác. Bạn sẽ cần đọc nhiều dependency mới và khám phá những codebase khác nhau để
biết mình đang build cái gì. Mặc dù không có vẻ là đọc cho lắm, nhưng đó là dự án mà có
thể bắt bạn chủ động đọc những thứ bạn sẽ dùng.
Ngoài công việc, bạn nên đọc nhiều tools khác với những gì bạn đang làm. Nếu bạn đã quen
với abstraction level cao, hãy học 1 (hoặc 3) abstraction level thấp hơn. Nếu bạn đang làm
việc với 1 ngôn ngữ, chọn một ngôn ngữ khác để đọc vào lúc rảnh.Nếu bạn luôn nghĩ về 1
constraint (vd: thời gian để làm mới màn hình tiếp theo trong graphics programming), tìm
một constraint khác (vd: tiết kiệm tuổi thọ pin cho lập trình mobile).
Một cách tiếp cận tốt khác để đọc code đó là đọc và viết lại từ những coder và bạn yêu
thích. Trường hợp của Didion hồi trẻ đã viết nên Hemingway hoặc Hunter Thompson viết
Great Gatsby, hoặc code của antirez/ gaearon/ mrdoob bắt đầu với 1 thư viện đơn giản. Đọc
code khác của họ. Luôn cập nhật công việc gần đây nhất của họ.
Stephen King nói với các nhà văn rằng: “Nếu bạn không dành thời gian để đọc, bạn sẽ
không có thời gian (hoặc công cụ) để viết, đơn giản vậy thôi”. Cũng tương tự thế đối với các
kỹ sư phần mềm, viết code sạch có lẽ là điều vui nhất, nhưng chủ động đọc code mới là
điều khiến bạn bứt phá ra khỏi vỏ bọc trước giờ.
Ask Hacker News: How to understand the large codebase of an open-source project?
Sách
Code Reading: The Open Source Perspective (book)
Codebase để đọc
Good Python codebases to read
Xem thêm việc làm Developer hấp dẫn lương cao tại TopDev!
TopDev
Ban Biên Tập Blog TopDev. Nice to meet you