Bí kíp luyện Kỹ sư phần mềm: Đọc code!
Tác giả: Nemil Dalal
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.
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.
Tại sao tôi phải đọc code?
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ó.
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.
Hướng dẫn đọc code
Tiếp cận một nguồn code như cách mà bạn đọc một cuốn sách – Đọc từ đầu đến cuối – và nó thường không thành công (trớ trêu thay đây lại là cách duy nhất máy tính tự đọc code)
Đọ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ình sử dụng phương pháp RSDW để đọc bất cứ codebase khó hiểu nào:
- Run: dịch, chạy thử và hiểu code đang làm gì
- 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: FlameGraph Repository
Sơ đồ UML của Process Flow
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.
Xem ngay những tin đăng tuyển lập trình viên fresher
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ột vài tips đọc
Phương pháp RSDW không phải là duy nhất. Các engineer có thể tìm ra cách riêng mà họ thích để đào sâu vào một codebase mới (Quá trình đọc cũng thay đổi đáng kể tuỳ theo ngôn ngữ, các tool có sẵn và loại codebase bạn đang muốn)
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.
Bạn nên đọc code gì?
Khi bắt đầu sự nghiệp, mình tin rằng 60% thời gian của bạn nên dành cho việc đọc code. Có thể 1/3 trong số đó là code khác với codebase bạn sẽ build. Chắc hẳn là phải tốn rất nhiều thời gian, vậy chúng ta nên đọc gì?
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ờ.
Bài viết gốc được đăng tải tại Hackernoon
Có thể bạn muốn xem thêm:
- “Code dễ đọc” là như thế nào?
- Làm sao để nâng cao khả năng code?
- Kinh nghiệm học coding dành cho dân trái ngành
Xem thêm việc làm Developer hấp dẫn lương cao tại TopDev!
- G Giải Quyết Bài Toán Kinh Doanh Bằng Big Data và AI
- B BenQ RD Series – Dòng Màn Hình Lập Trình 4k+ Đầu Tiên Trên Thế Giới
- F Framework nào tốt nhất cho dự án của bạn? – Checklist chi tiết
- K Kinh nghiệm xử lý responsive table hiệu quả
- S Stackoverflow là gì? Bí kíp tận dụng Stack Overflow hiệu quả
- 7 7 kinh nghiệm hữu ích khi làm việc với GIT trong dự án
- B Bài tập Python từ cơ bản đến nâng cao (có lời giải)
- B Bảo mật API là gì? Một số nguyên tắc và kỹ thuật cần biết
- H Hướng dẫn cài đặt và tự học lập trình Python cơ bản từ A-Z
- C Chinh Phục Phân Tích Dữ Liệu Với Pandas Trong Python: Hướng Dẫn Từng Bước