Khi có người bảo tôi “học cấu trúc dữ liệu và giải thuật đi”, thì chính xác ý của họ là gì?

Khi tôi bảo rằng cậu phải học cấu trúc dữ liệu và giải thuật đi, thì ý của tôi là:

Cậu Phải Tìm Hiểu Bài Toán Đi.

Không, cậu không cần phải học thuộc lòng các thuật toán và các cấu trúc dữ liệu đến mức có thể viết hết chúng lên bảng ngay được.

Không ai cần cậu nhớ hết từng đấy thứ, trừ lúc đang đi phỏng vấn.

Nếu cậu thực sự muốn lập trình ở một mức độ xuất chúng, thứ cậu cần phải học là CÁC BÀI TOÁN.

Ví dụ đầu tiên nhé.

Tôi có một tập hợp lớn các điểm trong không gian.

Tôi chọn một điểm bất kỳ, và hỏi cậu, cậu tìm ngay cho tôi tập k điểm gần với điểm tôi vừa chọn nhất.

Cậu có nhiều cách trả lời câu hỏi này.

Cậu có thể giơ hai tay lên đầu hàng và chả biết bắt đầu làm từ đâu.

Hoặc cậu đơn giản là tính khoảng cách giữa điểm tôi vừa chọn với tất cả các điểm trong tập hợp đấy. Nếu cậu làm thế thì cậu có một danh sách các khoảng cách, và cậu sắp xếp lại để có k điểm mà tôi yêu cầu.

Một hướng tiếp cận khác là chia không gian đề bài ra thành các ô nhỏ, và cậu sẽ nhanh chóng xác định được điểm tôi chọn thuộc ô nào. Sau đó cậu sẽ tìm ra theo các ô lân cận đến khi đủ k điểm cho tôi.

Và tôi chắc là cậu sẽ nghĩ ra được nhiều cách khác để giải quyết vấn đề này.

Hoặc – có một cách hay hơn cả – đó là cậu bảo ngay với tôi đây là bài toán K-Láng giềng (K Nearest Neighbor).

Thế là cậu bắt đầu Google và đọc những nghiên cứu mới nhất về bài toán này, và cậu biết rằng đã có sẵn vài tá thuật toán để giải nó rồi.

Có thể cậu sẽ tìm được trang này, nó đã đo hiệu năng của một vài thư viện đã được lập trình sẵn.

Và từ đó cậu lại đọc được bài báo này, tác giả đã đề cập chi tiết cách tiếp cận của họ – đồ thị Định hướng Phân tầng trong Thế giới nhỏ (Hierarchical Navigable Small World graph) – là thuật toán ứng dụng nhanh nhất hiện tại với một tập dữ liệu 3500 điểm cụ thể.

Và cậu chưa từng nghe đến thuật toán này bao giờ. Bởi bài báo này mới chỉ được viết năm 2016 và cập nhật lại năm 2018!

Đây là nơi tôi sẽ chỉ ra điểm mấu chốt của câu trả lời này:

Nhận ra được bài toán cần giải quan trọng hơn ghi nhớ thuật toán để giải nó.

Đó là bởi thuật toán “tối ưu nhất” để giải bất cứ bài toán nào hôm nay có thể còn chưa được phát minh ra ngày hôm qua.

Tôi đưa ra một ví dụ nữa nhé.

Cho tôi tên thuật toán nhanh nhất để tìm một chuỗi ký tự trong một chuỗi ký tự khác.

Có thể cậu chẳng biết phải làm thế nào.

Có thể cậu sẽ viết một thuật toán đọc qua từng ký tự một trong chuỗi ký tự ban đầu.

Hoặc nếu cậu là một sinh viên khoa học máy tính, chắc cậu sẽ biết rằng thuật toán Boyer-Moore là thuật toán tìm chuỗi con “tối ưu” nhất.

Thế này. Chẳng có cái gì gọi là nhanh nhất cả.

Có lẽ, nếu cậu đã biết tên bài toán, cậu sẽ tìm được một thứ gọi là Turbo-BM. Hoặc Apostolico-Giancarlo. Cả 2 thuật toán này đều thời gian xấu nhất (worst-case scenario) và/hoặc thời gian trung bình vượt trội hơn hẳn so với thuật toán Boyer-Moore.

Và chẳng ông bạn siêu lập trình viên nào của cậu biết đến sự tồn tại của các thuật toán này đâu!

Thế nên Học Về Các Bài Toán lại quan trọng đến thế. Nếu cậu biết về bài toán này, thường được gọi là So khớp chuỗi (string matching), thì cậu sẽ không chỉ tìm được những lời giải nổi tiếng thường được dạy trong nhà trường, mà còn cả những lời giải khó nhằn hơn, nhưng hiện đại hơn và nhanh hơn mà vẫn chưa được đưa vào chương trình giảng dạy.

Và – cho những lập trình viên hàng đầu – có lẽ cậu sẽ là người đọc tất cả những bài báo lê thê này trước khi tìm được một lời giải còn tuyệt diệu hơn mà chưa ai từng nghĩ đến trước đây.

Nếu công việc của cậu chỉ là giải những bài toán doanh nghiệp thông thường, thì chắc chỉ cần một tập hợp các thuật toán cơ bản, một thư viện C++ tiêu chuẩn là thừa đủ để làm tất cả mọi thứ.

Nhưng nếu cậu muốn viết những đoạn code nhanh đến chóng mặt, hoặc những đoạn code để giải những bài toán cực kỳ đặc thù, không gì bì được với việc tự tìm hiểu các bài nghiên cứu hàn lâm.

Và các bài toán hàn lâm, theo đúng bản chất, không phải là những thứ cậu học vẹt nổi chỉ để đi phỏng vấn.

Nhất là với những câu hỏi về lập trình từ lớn đến bé, thì khả năng Tìm hiểu Bài toán sẽ là cực hữu dụng để cậu tìm được thuật toán tốt nhất hiện có.

Leave a Reply

Your email address will not be published. Required fields are marked *