Lập trình cũng giống như giải một bài toán

Problem-solving-620-620x397

Hẳn là trong cuộc đời học sinh – sinh viên, bạn đã phải giải rất nhiều bài toán, dù bạn có yêu thích môn toán hay không. Thực tế thì cuộc sống đơn giản là bao gồm những bài toán cần giải quyết, và số phận mỗi người phụ thuộc vào việc anh ta giải bài toán đó như thế nào. Ví dụ như bài toán “làm sao để cưa được em hot girl gần nhà”, là một bài toán gây nhiều cơn đau đầu cho các thanh niên từ hàng trăm năm qua. Để giải quyết được bài toán này yêu cầu không chỉ từ việc nắm rõ đối tượng cần giải quyết (em gái kia), mà còn phụ thuộc rất nhiều vào chiến thuật, lợi thế bản thân (đẹp zai khoai to, nhiều $), và cả may mắn nữa.

Lan man như vậy đủ rồi 🙂 Chủ đề hôm nay sẽ bàn về sự tương tự giữa giải toán và lập trình. Người viết bài này đã code để kiếm cơm cũng được một thời gian rồi, và nhận thấy là có nhiều điểm chung giữa 2 lĩnh vực nêu trên.

Đầu tiên bạn sẽ nhận được một yêu cầu, bạn gọi nó là đề bài, bạn có thể phải phân tích để hiểu rõ đề bài, tránh khỏi bị lạc đề. Đơn cử như trường hợp bạn ra khỏi phòng thi với tâm trạng rất hồ hởi vì bạn đã làm được tất cả các câu. Oh yeah!!! Nhưng… ngay sau đó bạn chợt nhận ra mình đã lạc đề, ôi thôi, bạn chỉ còn biết “nước mắt giàn dụa” và tự trách mình bởi đã không đọc kỹ đề bài trước khi khởi bút, và bởi vậy bạn đã “tạch” trong khi khả năng của bạn là thừa sức “pass”. Để tránh tình trạng éo le nêu trên, việc phân tích yêu cầu bài toán là hết sức quan trọng. Nó quan trọng không kém việc tìm hiểu “nàng” trước khi rước nàng về dinh. Trong lĩnh vực phần mềm thì có một vị trí chuyên trách về mảng này, gọi là BA (Business analysis) hay chuyên gia phân tích nghiệp vụ, anh này hàng ngày liên lạc với khách hàng để tìm hiểu yêu cầu, và thương thảo với họ để có công việc và hợp đồng có lợi nhất, đồng thời đảm bảo sản phẩm làm ra sẽ làm khách hàng “sướng”. Đối với một DEV cùi thông thường thì có thể họ không trực tiếp tiếp xúc với khách hàng, mà là các bài toán lập trình cụ thể. Nhưng như vậy không làm giảm yêu cầu của việc hiểu rõ yêu cầu bài toán được giao. Thực tế năng suất của một lập trình viên có kinh nghiệm có thể gấp nhiều lần một lập trình viên “non tơ” mới vào nghề là bởi “gã” có kinh nghiệm sẽ biết dành thời gian nhiều hơn cho việc phân tích yêu cầu, cũng như có nhiều kinh nghiệm hơn để có thể hiểu rõ yêu cầu đó. Việc cắm đầu vào code khi chưa rõ vấn đề là cách tệ nhất và cũng không ít DEV đã phạm phải sai lầm này, nhất là các DEV còn non kinh nghiệm, điều này dẫn đến sự lãng phí thời gian và công sức một cách không cần thiết, đồng nghĩa là năng suất bị kéo tụt đi rất nhiều.

16508972_2431554433735766_2774536399728293578_n
Làm sao để cưa em hot girl mà bạn đang say đắm – bài toán khó của các thanh niên FA từ hàng trăm năm qua

Qua giai đoạn phân tích yêu cầu, tiếp đến bạn cần vạch ra các bước để giải quyết bài toán. Đối với bài toán tán gái nêu trên, sau khi đã nắm được thông tin về thân thế sở thích của nàng, giờ là lúc để bắt đầu hành động. Kế hoạch sẽ là đăng ký khóa học tiếng Anh buổi tối mà nàng đang tham gia, xin số điện thoại để liên lạc, hay mời nàng đi ăn thịt chó vì đây là món khoái khẩu của nàng… Với một kế hoạch rõ ràng và cộng với một chút may mắn, khả năng cao là nàng sẽ đổ trước sự quan tâm không biết mệt mỏi của bạn. Còn nếu không? thì hãy chuyển sang mục tiêu tiếp theo, và chúc bạn may mắn lần sau. Có thể gọi bước này là phương pháp luận (methodology), là cách giải quyết bài toán đến từ việc phân tích bài toán trước đó. Lúc này bạn đã phân loại được bài toán và tìm ra một hướng đi nào đó để tiếp tục. Bạn có thể lập một dàn ý bao gồm các bước tổng quan để giải bài toán đã đề cập, trong lập trình ta gọi bước này là viết mã giả code (pseudo code). Nhiều bạn coi việc làm này là thừa thãi, không cần thiết vì chưa nhìn thấy được hiệu quả mà nó mang lại sau này. Thực tế khi có một plan tổng thể, ta sẽ có một cái nhìn tổng quan về vấn đề và đánh giá được xem phương pháp đã chọn có thực sự phù hợp. Hơn nữa sửa một dòng lệnh pseudo code thì dễ dàng hơn nhiều là đi sửa hàng chục, hàng trăm dòng code thực sự. Pseudo code đã viết có thể được tái sử dụng thành các dòng comment cho source code, giúp tăng tốc quá trình coding.

Cuối cùng, khi đã hoàn thành xong việc coding, bạn coi như đã giải quyết cơ bản được bài toán. Nói như vậy có nghĩa là công việc của bạn vẫn chưa xong đâu nhé. Thông thường thì phần mềm nào cũng sẽ có bug, chỉ là ít hay nhiều mà thôi. Có bug là do bạn nhầm lẫn trong logic tính toán, sai giá trị tham số truyền vào, hay do bạn chưa lường hết tất cả các trường hợp; cũng có bug là do chính bản thân yêu cầu bài toán có vấn đề, hoặc do bug của thư viện hoặc bug trong code của người khác mà bạn tái sử dụng. Như vậy khi tester thông báo có lỗi xảy ra trong chương trình, bạn sẽ lại lao đầu vào tìm nguyên nhân bug và fix nó. Công việc fix bug có khi nhẹ nhàng cũng có khi rất gian nan, nó tùy thuộc vào bản chất của bug và khả năng của bạn, cộng thêm yếu tố may mắn nữa 🙂 Có nhiều dự án thuộc loại maintain source code, có nghĩa là công việc của bạn chỉ là tìm bug và fix, nghe có vẻ nhàm chán đối với đa phần các coder, tuy vậy công việc fix bug là không thể nào tránh khỏi và là một phần tất yếu của công việc lập trình. Việc tìm bug và fix cũng lại là một bài toán, bạn cần có kỹ năng của một thám tử tư để truy tìm các dấu vết, dự đoán nguyên nhân, thủ phạm và biết cách bắt gọn đối tượng. Ngoài tư duy logic, các công cụ “phá án” là vô cùng cần thiết, có vai trò rất lớn tới khả năng giải quyết bài toán. Rất may mắn cho chúng ta là hiện nay có vô số công cụ hữu ích trợ giúp cho việc tìm và diệt bug, đối với web developer là Inspector, firebug, fidder…, đối với backend developer là Postman, DHC REST Client… cùng với các công cụ debug có sẵn trong IDE vốn rất mạnh mẽ. Nắm được cách vận hành và sử dụng đúng công cụ là coi như bạn đã nắm trong tay một sức mạnh to lớn trong lĩnh vực lập trình.

Nói tóm lại, ta có thể thấy mối liên quan rất hiển nhiên giữa lập trình và giải toán, và vì vậy khi đối diện với một công việc phát triển phần mềm, hãy xác định tâm thức như đang giải một bài toán. Hãy làm sáng tỏ bài toán, phân tích từng bước và hoàn thiện dần bài toán một cách nhanh chóng và mất ít công sức nhất. Khi tư duy như vậy, thì số lượng dòng code không còn là vấn đề quan trọng nữa, và tốt nhất là bạn có thể giải quyết một phần hay cả bài toán mà không cần gõ một dòng lệnh nào – đồng nghĩa là bạn sẽ không tốn thời gian để fix bug 😉

Leave a comment