Tại sao lại có bài viết này?
Chào mọi người! Mình hiện là một iOS Developer đang làm việc tại VTI. Trước khi tới VTI làm việc thì mình có bươn trải kiếm sống ở một vài công ty khác: Tiki, Up, Zalo, VTC,.. cũng từng có thời gian làm việc cho một số công ty ở Singapore và US. Được tiếp xúc với khá nhiều lập trình viên tới từ khắp thế giới, mình thấy khác biệt rất lớn giữa đa số các developer của Việt nam và nước ngoài là về tư duy giải thuật. Bài viết này có mục đích nêu quan điểm cá nhân của mình về tầm quan trọng hoặc vô dụng của thuật toán trong lập trình, dưới quan điểm của một Mobile Developer, đồng thời kết hợp với kiến thức trong quá trình mình có theo học Master DS khi còn đi học đại học! Chính vì thế bài viết này sẽ nói khá nhiều về mảng lập trình ứng dụng di động! Hy vọng bài viết sẽ gây nhiều tranh cãi!
Học thuật toán được và mất gì?
Thuật toán là cái quái gì?
Trước hết, thuật toán là gì mà lại cần nó? Theo wikipedia:
Thuật toán, còn gọi là giải thuật, là một tập hợp hữu hạn hay một dãy các quy tắc chặt chẽ của các chỉ thị, phương cách hay 1 trình tự các thao tác trên một đối tượng cụ thể được xác định và định nghĩa rõ ràng cho việc hoàn tất một số sự việc từ một trạng thái ban đầu cho trước; khi các chỉ thị này được áp dụng triệt để thì sẽ dẫn đến kết quả sau cùng như đã dự đoán trước.
Các trường phái
Nói về hiện trạng hiện tại, mình đang thấy có 2 bên với các quan điểm trái ngược:
1. Cần vẹo gì thuật toán? Mình code app bao nhiêu năm nay mà có cần biết cái thuật toán nào đâu?
2. Không có thuật toán thì làm được cái gì? Bắt buộc phải giỏi thuật toán rồi làm gì thì làm!
Vấn đề này, tới nay vẫn chưa có kết quả, vẫn là hàng loạt các cuộc tranh cãi giữa các dev. Tuy nhiên, thay vì hỏi "Có cần thuật toán không?" hãy thay đổi một chút, "Thuật toán giúp ích được gì?
Nhận định về 2 quan điểm trên, theo mình cả 2 đều có ý đúng, tuy nhiên cũng có nhiều ý sai. Để nhận định chính xác hơn, chúng ta nên đi vào việc học thuật toán được gì, đồng thời cần bỏ ra cái gì, lúc đó sẽ có một cách nhìn tổng quát hơn!
Vậy học thuật toán được gì?
Chúng ta nhìn thấy ngay 2 lợi ích rõ ràng của thuật toán:
- Điểm cộng khi tham gia phỏng vấn
- Tăng tư duy logic về giải quyết vấn đề
Về ý đầu tiên, đa phần các công ty ở Việt nam sẽ chỉ hỏi về các thuật toán: sắp xếp, đệ quy, đôi khi có được hỏi về quy hoạch động. Các thuật toán này rất cơ bản, chủ yếu mang tính tổng quan để đánh giá hiểu biết về giải thuật của ứng viên. Mình có vài người bạn, hiện đang làm cho Microsoft, G+, Amazon,.. mình có được họ chia sẻ rằng khi phỏng vấn họ bị hỏi khá nhiều về queue, stack, BFS, DFS,.. cùng với các bài toán Real code đơn giản như tìm xâu con đối xứng dài nhất, tìm cách sắp xếp vị trí ngồi và thứ tự lên máy bay của hành khách,... Tuy nhiên, không chỉ ở G+ hay Facebook, ngay ở VN, các công ty như Zalo hay Viettel cũng rất quan tâm tới thuật toán, lần gần nhất khi mình interview ở Zalo, mình có khoảng 1 tiếng để trả lời câu hỏi về các thuật toán cơ bản, sau đó là 1 tiếng để Real code với bài toán từ phía Zalo. Một tip trick khi bạn không quá tự tin về thuật toán là bạn có thể tham khảo huyền thoại phỏng vấn này: Cracking the Coding Interview
Vậy nhìn lại, chưa tính tới lợi ích về học thuật, chúng ta đã có một lý do khá chính đáng để nghiên cứu một vài thuật toán cơ bản, coi như đã ăn chắc một phần khi đi phỏng vấn!
Tuy nhiên, thứ mình thật sự quan tâm khi nhắc tới thuật toán là việc nó giúp cho các lập trình viên có tư duy logic và nhanh nhạy hơn trong giải quyết vấn đề. Trong cuộc sống hằng ngày, chúng ta gặp rất nhiều vấn đề mà trong vô thức chúng ta đã sử dụng thuật toán để giải quyết: cần đi qua 5 địa điểm, làm sao để đi nhanh nhất có thể? Hay khi đi ăn buffet, làm sao để ăn được nhiều đồ mà đảm bảo không lỗ tiền? Khi gặp những vẫn đề này, bộ não sẽ tự tìm cách để tính toán ra các phương án và lựa chọn cách phù hợp nhất mà nó cho là đúng. Đây chính là thuật toán, một cách đơn giản, thuật toán là cách giải quyết một vấn đề đã được common hoá lại, nhằm mục đích truyền đạt cách thức để giải quyết vấn đề thông qua kinh nghiệm (nghiên cứu) của người đi trước, chính vì thế chúng dần được đặt tên để dễ ghi nhớ và học tập hơn. Dần dần, khi đã quen với cách giải quyết vấn đề, bộ não sẽ dần hình thành tư duy cho các vấn đề tương tự, đây là sự kỳ diệu của não bộ. Nó sẽ khá giống với một khái niệm đang rất hot gần đây Machine Learning
Lợi ích nhiều như vậy, tại sao developer vẫn ghét việc học thuật toán
Mình là một ví dụ cho dạng người thấy được tác dụng to lớn của thuật toán nhưng lại rất lười tìm hiểu. Time travel một chút, khi mình còn 12 tuổi, lúc mình cố gắng lập trình để con robot có thể ra khỏi mê cung, mình đã rất hăng say khi đọc source code C++ dùng Heuristic Algorithm để giải quyết bài toán này, lý do lúc đó mình cảm thấy hăng say và không lười khi phải đọc thuật toán đó là do mình cần 1 giải pháp để giải quyết vấn đề của mình, đồng thời khi đó mình chưa hề có khái niệm về cái gọi là thuật toán. Đây là 1 trong những lý do cơ bản khiến mọi người dần xa cách với thuật toán hơn : Chúng ta học thuật toán để biết thuật toán đó chứ không phải để áp dụng vào thực tế! Ngoài lý do đó, mình cũng thấy có một vài lý do khác như sau:
- Các ngôn ngữ lập trình bậc cao, các thuật toán dần được đóng gói thành các High Order Function làm cho mọi người dần dần không còn phải tự triển khai, dẫn tới thói quen ngày càng phụ thuộc vào ngôn ngữ lập trình hơn, trong khi chúng ta mới là người sử dụng các ngôn ngữ đó.
- Thuật toán thường được giới thiệu khá khô khan, đa phần các bài toán thường lặp đi lặp lại như: sắp xếp, tìm phần tử lớn nhất, nhỏ nhất,... Dần dần nó làm cho mọi người không còn thấy được giá trị thực tế của thuật toán.
- Thuật toán có tác dụng tăng cường khả năng tư duy logic. Tuy nhiên đôi khi lại yêu cầu khả năng suy luận đủ tốt thì mới tiếp thu và hiểu được cách thuật toán đang hoạt động.
- Đa phần các chương trình đạo tạo hiện tại chỉ tập trung vào phần ngôn ngữ lập trình, phần thuật toán đào tạo khá miên man, không có đủ thời gian để tập trung vào các yếu tố ứng dụng của thuật toán mà chỉ mới dừng lại ở mức kiến thức cơ bản lý thuyết, do đó gây cho sinh viên sự nhàm chán.
- Các công ty outsource khi tuyển các vị trí developer không quá coi trọng thuật toán mà chỉ tập trung vào các công nghệ cũng như ngôn ngữ lập trình.
Nhiều lợi ích nhưng không giỏi thuật toán có được không?
Như đã nói ở phía trên, ngoài công việc như một mobile developer trên công ty, mình cũng có làm thêm các research để đáp ứng cho công việc học tập và làm việc như 1 Data scientist Type B của mình. Vì vậy, mình sẽ nêu ý kiến đứng trên quan điểm trung gian giữa cả 2 lĩnh vực này:
- Một điều chắc chắn, bạn không cần giỏi thuật toán để làm ra một phần mềm tốt, việc này đã được chứng mình qua một thời gian dài phát triển của các công ty Outsourcing.
- Tuy nhiên, khi không có kiến thức về thuật toán, sẽ khá khó khi tiếp xúc với các phần mềm yêu cầu độ phức tạp trong tính toán hoặc cần triển khai nhiều logic theo từng use case người dùng. Bạn sẽ không dùng một thuật toán rõ ràng nào tuy nhiên thuật toán vẫn sẽ góp phần giúp bạn triển khai các trường hợp này một cách đơn giản hơn thông qua tư duy logic cũng như các gợi ý từ giải pháp của thuật toán mang lại.
- Một quan niệm khá sai lầm rằng muốn học hay làm được các công nghê như AI, ML, DL hay DS thì phải thật giỏi thuật toán. Mình nghĩ rằng, việc này là tương đối vô căn cứ, hiện tại, làm cùng mình có khá nhiều bạn theo lĩnh vực AI nhưng thuật toán cũng chỉ dừng lại ở mức cơ bản, trong quá trình làm việc, công việc của mọi người là dùng các thuật toán cơ bản này để tối ưu hoá các framework hay các công cụ đang có sẵn, rất ít người phải tự xây dựng thuật toán từ đầu nên việc yêu cầu một level cao của kiến thức giải thuật là không thật sự chính xác.
Như vậy, có thể không cần giỏi thuật toán khi muốn làm một developer tốt, tuy nhiên khi muốn phát triển cao hơn, để trở thành Senior Developer hay TechLead thì bạn sẽ không thể trốn tránh được việc tiếp xúc với các kiến thức giải thuật này. Vậy nên, không có lý do gì mà không trau dồi kiến thức về các thuật toán cơ bản một cách vững vàng, vì theo phân tích, nó không đem lại tác hại gì cả :)))
Vậy câu hỏi cần hỏi lúc này phải là: "Làm sao để vượt qua được các lý do vừa được nêu trong phần Lợi ích nhiều như vậy, tại sao developer vẫn ghét việc học thuật toán để thật sự tận hưởng và chơi đùa với các thuật toán hiện tại"
Học và dùng thuật toán thế nào?
Mình được nghe rất nhiều lời khuyên từ nhiều người cho các bạn fresher, khi muốn bắt đầu học thuật toán thì nên bắt đầu từ các ngôn ngữ lập trình, sau đó tới các kiến thức liên quan tới Cấu trúc dữ liệu và giải thuật , các thông tin này hoàn toàn đúng, tuy nhiên khó mà vượt qua được các rào cản khi học theo cách này, vì vậy, bài viết này sẽ là mở đầu cho một series về các thuật toán thú vị mình sử dụng trong Data Science, tuy nhiên sẽ được mô tả bằng ngôn ngữ của lập trình di động hay web,.., thay vì sử dụng C/C++ đã quá phổ biến trong học thuật hiện đại. Đồng thời sẽ giải quyết các bài toán khá phổ biến hiện tại và có nhiều ứng dụng như: tìm đường đi ngắn nhất giữa các địa điểm, tìm tốt hợp tốt nhất trong một không gian tổ hợp,.... như vậy chúng ta sẽ thấy được giá trị thật sự của thuật toán thay vì chỉ nhìn thấy mặt học thuật của nó!
Series sẽ có tên: Fun code - Chơi đùa cùng các thuật toán thú vị!
và bài đầu tiên sẽ là Fun code - Sử dụng Swift giải bài toán TSP với giải thuật GA
Hy vọng bài viết sẽ giúp bạn hứng thú hơn một chút với các kiến thức về giải thuật hiện đại, chỉ khi muốn tìm hiểu thì nó mới có giá trị, nên chuỗi bài viết này mình hy vọng sẽ cho mọi người thêm hứng thú hơn với lĩnh vực này!
Leave a Reply