Nhiều bạn mới học lập trình thường rơi vào một vòng lặp quen thuộc. Cuối tuần ngồi giải hàng chục bài liền tay, sang thứ Hai thì gần như quên sạch. Chúng tôi đã gặp chuyện này rất nhiều lần, và chính đội ngũ cũng từng đi qua con đường đó khi mới bắt đầu. Vì vậy, nếu bạn đang tự hỏi luyện thuật toán mỗi ngày thế nào để kiến thức không bị bốc hơi, bài viết này sẽ kể lại những gì chúng tôi rút ra sau nhiều năm hướng dẫn người học.
Học dồn kiểu cuối tuần không hẳn là sai. Tuy nhiên, trí nhớ của chúng ta không được thiết kế để giữ kiến thức chỉ sau một lần nạp. Thông tin không được nhắc lại sẽ mờ dần khá nhanh. Cách khắc phục đơn giản nhất là lặp lại đều đặn, dù mỗi lần chỉ vài phút. Nói cách khác, bạn nên ưu tiên sự đều đặn hơn là một buổi học dài.
Có một tình huống khác cũng rất thường gặp. Bạn mở đề bài ra, đọc hai lần mà vẫn chưa biết nên bắt đầu từ đâu. Cảm giác bế tắc ấy khiến nhiều người kết luận mình không có năng khiếu. Thực tế, đây là trạng thái bình thường khi học một kỹ năng mới. Một khung luyện tập hợp lý sẽ giúp bạn vượt qua giai đoạn này mà không bị nản.
Mục tiêu nên đặt ra không phải là làm thật nhiều bài trong một tháng. Chúng tôi thường khuyên học viên chọn vài bài mỗi ngày, làm kỹ, rồi quay lại nghĩ về cách mình đã làm. Cách này cho kết quả tốt hơn hẳn việc ngồi làm vài chục bài trong một buổi tối rồi tắt máy.
Khung 45 phút mỗi ngày: nhìn tổng quan
Chúng tôi đề xuất chia 45 phút thành bốn phần: đọc đề 5 phút, tự giải 25 phút, đối chiếu 10 phút và viết lại 5 phút. Con số này không có gì huyền bí. Nó đủ dài để bạn đi sâu vào một bài, nhưng cũng đủ ngắn để bạn không kiệt sức sau vài ngày liên tiếp. Khi bắt đầu, bạn có thể thấy khung này hơi gò bó, nhưng sau một tuần thì nhịp học sẽ tự nhiên hơn.
Giới hạn thời gian đóng vai trò quan trọng hơn người ta tưởng. Khi biết chắc mình sẽ dừng sau 45 phút, việc bắt đầu trở nên dễ dàng hơn. Điều cốt lõi là hình thành một thói quen có thể lặp lại mỗi ngày, chứ không phải một buổi học cố sức đến mức sau đó phải nghỉ dài.
Nếu hôm nào bạn chỉ có 20 đến 30 phút, hãy rút phần tự giải xuống còn khoảng 15 phút và bỏ bớt phần viết lại. Đừng bỏ phần đối chiếu. Đây là phần giúp bạn không học sai, và học sai một lần đôi khi tốn nhiều thời gian sửa hơn cả việc học chậm.
Bước 1: Đọc đề đúng cách
Đọc đề nghe đơn giản đến mức nhiều người lướt qua. Thế nhưng, đây lại là bước sai sót nhiều nhất. Hãy tự hỏi đầu vào là gì, đầu ra cần trả về là gì, và có ràng buộc nào về thời gian hay bộ nhớ không. Phần lớn lỗi về sau bắt nguồn từ việc hiểu sai đề ngay từ đầu.
Một mẹo nhỏ mà chúng tôi hay dùng là viết lại đề bằng lời của chính mình. Ví dụ, khi bài yêu cầu tìm hai số có tổng bằng một giá trị cho trước, bạn có thể diễn đạt lại: cho một danh sách số, hãy tìm hai vị trí mà giá trị tại đó cộng lại bằng đích. Sau đó, tự nghĩ ra một ví dụ nhỏ với năm đến sáu phần tử, rồi xác định trước kết quả mong đợi. Làm vậy, bạn sẽ có một thước đo rõ ràng để kiểm tra ý tưởng của mình sau này.
Trong lúc đọc, hãy để ý các trường hợp đặc biệt. Đầu vào có thể rỗng không? Có số âm hay số trùng lặp không? Đề yêu cầu trả về một đáp án hay tất cả đáp án? Mỗi câu hỏi trả lời được sẽ loại bỏ một nhóm lỗi tiềm ẩn. Đây là thói quen nhỏ nhưng tiết kiệm rất nhiều thời gian gỡ lỗi về sau.
Nhận ra bài thuộc dạng nào cũng giúp định hướng tư duy rất nhiều. Nếu đề mô tả một dãy có thứ tự và yêu cầu tìm kiếm nhanh, rất có thể bạn đang đối diện với bài toán về mảng và tìm kiếm nhị phân. Nếu đề nói về các thành phố nối với nhau bằng đường đi, đó gần như chắc chắn là bài toán đồ thị. Nhận diện dạng bài không tự cho bạn lời giải, nhưng nó thu hẹp đáng kể hướng đi.
Bước 2: Tự giải, đừng mở lời giải quá sớm
Đây là 25 phút quan trọng nhất trong cả khung, và cũng là lúc dễ bỏ cuộc nhất. Đừng vội mở đáp án khi trong đầu chưa có ý tưởng nào. Thói quen đó khiến bạn học thuộc lời giải thay vì học cách suy nghĩ. Đến lúc gặp đề mới, bạn sẽ thấy mình như người chưa từng học gì.
Hãy bắt đầu bằng cách giải theo kiểu thô nhất, thường gọi là brute force. Với bài tìm hai số có tổng bằng đích, bạn có thể duyệt qua từng cặp. Cách này chậm, nhưng đúng, và nó cho bạn một mốc để so sánh về sau. Khi đã có lời giải thô, bạn mới bắt đầu tìm cách tối ưu. Chẳng hạn, bạn có thể nghĩ đến việc dùng bảng băm để tra cứu phần bù của mỗi số, từ đó giảm đáng kể thời gian tìm kiếm.
Quy tắc 25 phút rất hữu ích. Nếu sau 25 phút vẫn bế tắc, đừng vội nhìn đáp án. Hãy ghi lại chính xác bạn đang mắc ở đâu. Có thể bạn đã hiểu đúng đề nhưng chưa nghĩ ra cấu trúc dữ liệu phù hợp. Cũng có thể bạn đã có ý tưởng nhưng không chắc về các trường hợp biên. Việc xác định điểm mắc kẹt giúp bạn nhớ bài lâu hơn nhiều so với đọc thẳng lời giải, bởi lúc này bạn đang học đúng chỗ mình còn thiếu.
Hãy viết ý tưởng ra giấy, kể cả khi nó còn lộn xộn. Ghi lại không chỉ giúp bạn theo dõi quá trình suy nghĩ, mà còn cho thấy những chỗ mình thường lạc hướng. Khi xem lại sau vài tuần, bạn sẽ ngạc nhiên vì có những lỗi cứ lặp đi lặp lại.
Bước 3: Đối chiếu và phân tích lời giải
Khi đã tự làm xong, hoặc khi hết thời gian, hãy so sánh cách làm của mình với lời giải tham khảo. Đừng dừng lại ở việc xem đúng hay sai. Câu hỏi quan trọng hơn là vì sao cách kia hiệu quả, và vì sao cách của bạn chậm hơn hoặc dễ sai hơn.
Kiểm tra các trường hợp biên là việc nhiều người bỏ qua nhất. Mảng rỗng, mảng chỉ có một phần tử, số âm và các giá trị rất lớn thường là nơi lời giải lộ lỗi. Bạn nên tự viết ba đến năm bộ dữ liệu thử cho những trường hợp này rồi chạy thử. Ví dụ, với bài tìm hai số có tổng bằng đích, nếu danh sách chỉ có một phần tử thì điều gì xảy ra? Nếu cùng một giá trị xuất hiện hai lần thì sao? Những câu hỏi nhỏ như vậy thường cứu bạn khỏi nhiều lỗi về sau.
Đo độ phức tạp của cả hai cách cũng rất cần thiết. Cách brute force thường có độ phức tạp bậc hai theo số phần tử, trong khi cách dùng bảng băm có thể giảm xuống bậc một trung bình cho mỗi lần tra cứu. Hiểu được chênh lệch này sẽ giúp bạn biết vì sao cùng một bài lại có nhiều cách giải, và tự tin hơn khi gặp câu hỏi về độ phức tạp. Nếu muốn hiểu sâu hơn về các cấu trúc dữ liệu có sẵn trong ngôn ngữ, bạn có thể đọc thêm Collections trong Java: interface, lớp và thuật toán.
Bước 4: Viết lại lời giải từ đầu
Năm phút cuối có thể là phần giúp bạn nhớ bài lâu nhất. Hãy đóng hết tài liệu và tự viết lại lời giải từ đầu. Nếu viết được mà không cần nhìn, nghĩa là bạn đã thật sự hiểu. Nếu vấp ở chỗ nào, đó chính là chỗ cần quay lại ôn.
Sau mỗi bài, hãy ghi chú ngắn vào sổ tay cá nhân. Ví dụ: tìm hai số có tổng bằng đích, dùng bảng băm để tra phần bù. Một dòng ghi chú như vậy hữu ích hơn bạn tưởng khi gặp lại dạng bài tương tự sau vài tuần, vì bạn nhớ ngay hướng tiếp cận thay vì bắt đầu từ con số không.
Hãy đánh dấu những bài cần ôn lại sau 3 ngày và 7 ngày. Đây là cách ôn tập ngắt quãng khá đơn giản. Nhờ được nhắc lại đúng lúc, kiến thức dần chuyển từ trí nhớ ngắn hạn sang trí nhớ dài hạn, và bạn không phải học lại từ đầu mỗi khi gặp một dạng bài quen thuộc.
Lập kế hoạch luyện tập theo tuần
Một lịch tham khảo mà nhiều học viên của chúng tôi áp dụng khá hiệu quả là mỗi ngày tập trung vào một chủ đề. Thứ Hai làm về mảng, thứ Ba về chuỗi, thứ Tư về ngăn xếp và hàng đợi. Các ngày còn lại tiếp tục theo vòng này, còn cuối tuần dành riêng để ôn lại những bài đã đánh dấu. Cách sắp xếp này giúp bạn không nhảy lung tung giữa các dạng bài, và những mẫu chung giữa các bài cùng loại sẽ được củng cố rõ hơn.
Dựa trên kinh nghiệm hướng dẫn học viên, chúng tôi thường gợi ý khối lượng luyện tập theo trình độ. Đây chỉ là con số tham khảo, vì thời gian thực tế phụ thuộc nhiều vào nền tảng và thói quen học của mỗi người:
- Người mới: khoảng 1 bài mỗi ngày, mỗi bài thường mất từ 35 đến 45 phút.
- Trung cấp: khoảng 2 bài mỗi ngày, mỗi bài thường mất từ 15 đến 20 phút.
- Nâng cao: 2 đến 3 bài mỗi ngày, nhiều khi chỉ cần 10 đến 15 phút cho mỗi bài.
Khi lịch bị phá vỡ vì công việc hay việc đột xuất, đừng cố bù lại bằng cách làm gấp đôi vào hôm sau. Điều đó thường dẫn đến kiệt sức và bỏ luôn cả tuần. Hãy chỉ làm đúng một bài nhỏ trong ngày hôm đó, rồi quay lại nhịp bình thường. Sự đều đặn luôn quan trọng hơn cường độ.
Công cụ và nguồn luyện tập phổ biến
Hiện có khá nhiều nền tảng luyện thuật toán, và phần lớn đều chia bài theo mức dễ, trung bình và khó. Với người mới, nên bắt đầu từ nhóm bài dễ để làm quen với cách đọc đề và cách kiểm thử. Khi đã quen tay, bạn mới tăng dần độ khó để tránh cảm giác bị ngợp. Bạn cũng có thể tham khảo thêm LeetCode như một nguồn bài tập quen thuộc với nhiều lập trình viên.
Phần lớn các nền tảng này dùng giao diện tiếng Anh, nên bạn sẽ gặp các từ khóa lặp lại như array, string hay graph. Bạn không cần hiểu hết thuật ngữ ngay từ đầu. Chỉ cần nắm đề bài và các ví dụ đi kèm là đủ để bắt đầu, phần còn lại sẽ quen dần theo thời gian.
Một bảng tính đơn giản là đủ để theo dõi tiến độ. Hãy ghi lại ngày, tên bài, dạng bài, thời gian làm và cột đánh dấu cần ôn lại hay không. Sau khoảng một tháng, bạn sẽ thấy rõ dạng nào mình yếu và cần ưu tiên. Đây là công cụ rất rẻ nhưng hiệu quả hơn nhiều người nghĩ.
Những sai lầm thường gặp khi luyện thuật toán mỗi ngày
Sai lầm đầu tiên là chỉ đọc lời giải mà không tự viết code. Đọc đáp án thì thấy mình hiểu, nhưng khi đối diện đề mới lại không biết bắt đầu từ đâu. Hãy luôn tự viết code, kể cả khi nó chạy sai nhiều lần. Chính những lần sai đó mới dạy cho bạn điều cần học.
Sai lầm thứ hai là nhảy quá nhanh giữa nhiều dạng bài. Hôm nay làm đồ thị, mai làm quy hoạch động, kia lại chuyển sang chuỗi. Não bộ cần thời gian để nhận ra mẫu chung giữa các bài cùng loại. Vì vậy, hãy đi sâu vào một dạng trước khi chuyển sang dạng khác, dù điều đó đôi khi khiến bạn thấy hơi chậm.
Sai lầm thứ ba là chỉ làm bài dễ để có cảm giác mình đang tiến bộ. Cảm giác làm nhanh và đúng khá dễ chịu, nhưng nó không đẩy bạn đi xa hơn. Thỉnh thoảng hãy dám thử một bài khó hơn một chút, dù có thể mất nhiều thời gian hơn. Đó là cách năng lực thực sự được mở rộng.
Giữ thói quen luyện tập lâu dài
Cách hiệu quả nhất mà chúng tôi thấy là gắn giờ luyện tập vào một thói quen đã có sẵn trong ngày, chẳng hạn ngay sau khi uống cà phê buổi sáng hoặc trước khi đi ngủ. Khi thói quen mới được đặt cạnh thói quen cũ, bạn sẽ ít phải dựa vào ý chí hơn. Đây là mẹo đơn giản nhưng giúp nhiều người duy trì nhịp học suốt nhiều tháng.
Theo dõi chuỗi ngày học liên tiếp có thể tạo động lực, nhưng đừng để nó thành áp lực. Nếu lỡ bỏ một ngày, cảm giác tự trách có thể khiến bạn nghỉ cả tuần. Hãy xem chuỗi ngày như công cụ nhắc nhở, không phải thước đo giá trị bản thân. Lỡ một ngày thì hôm sau quay lại là được.
Tham gia một nhóm học cùng người khác cũng giúp ích rất nhiều. Có người nhắc bạn khi quên, có người để bạn chia sẻ lời giải và nhận góp ý. Đôi khi, chính việc giải thích một lời giải cho người khác lại giúp bạn hiểu sâu hơn bất cứ điều gì tự đọc.
Nếu bạn muốn hệ thống lại kiến thức nền trước khi luyện thuật toán sâu hơn, hãy bắt đầu từ lộ trình học lập trình cho người mới, nơi chúng tôi sắp xếp các bước từ nền tảng đến dự án đầu tiên. Bạn cũng có thể đọc thêm cấu trúc dữ liệu cần nắm trước khi đi làm lập trình để biết nên ưu tiên học những gì trước. Ngoài ra, nếu đang phân vân về các phương pháp tiếp cận bài toán, bài giải thuật cho người mới tiếp cận bài toán từng bước sẽ là gợi ý tiếp theo phù hợp.
Câu hỏi thường gặp
Mỗi ngày nên làm bao nhiêu bài là vừa?
Với người mới, một bài mỗi ngày là đủ và bền vững. Điều quan trọng là bạn có thể duy trì đều đặn trong nhiều tháng, thay vì làm thật nhiều trong một hôm rồi nghỉ cả tuần. Khi đã quen nhịp, bạn có thể tăng dần số lượng.
Người mới nên bắt đầu từ dạng bài nào?
Chúng tôi thường khuyên bắt đầu từ mảng và chuỗi, vì đây là nền tảng cho hầu hết các dạng bài khác. Khi đã quen với việc duyệt mảng, dùng con trỏ và bảng băm, bạn sẽ tiếp thu các chủ đề nâng cao dễ hơn nhiều.
Nếu chỉ có 20 phút mỗi ngày thì có nên học không?
Vẫn nên học. Hai mươi phút mỗi ngày tích lũy sau một tháng đã là khoảng thời gian đáng kể. Hãy giảm độ dài bài và giữ lại phần đối chiếu để tránh học sai.
Khi nào thì nên chuyển sang bài khó hơn?
Khi bạn có thể tự giải khoảng bảy đến tám phần mười số bài ở mức hiện tại trong thời gian hợp lý, bạn có thể thử bài khó hơn một bậc. Nếu bí quá lâu, hãy quay lại củng cố nền tảng thêm một thời gian rồi thử lại. Không cần vội, chỉ cần đi đều là được.