Belajar DSA tanpa evaluasi berkala seperti berlayar tanpa kompas: kita merasa sudah jauh, tetapi tidak tahu apakah arahnya benar. Self-assessment terstruktur membantu kita menjawab dua pertanyaan kunci — di mana posisi kita sekarang, dan apa yang harus dikerjakan minggu depan. Pada Chapter ini kita akan menyusun rubrik evaluasi dua dimensi: baris adalah topik (array, linked list, tree, graph, DP, dst.), kolom adalah level proficiency (beginner, intermediate, advanced). Setelah mengisi rubrik, kita dapat melihat peta kekuatan dan kelemahan secara visual, lalu menyusun action plan berbasis hasil.

Kerangka Evaluasi 2-Dimensi #

Rubrik kita menggunakan dua sumbu berikut:

  1. Topik — area materi DSA yang ingin diukur. Kita pakai 12 topik inti.
  2. Level proficiency — tiga tingkat penguasaan: beginner, intermediate, advanced.

Setiap sel diisi tanda centang bila sudah dicapai, atau kosong bila belum.

Level Proficiency — Definisi #

Setiap level memiliki kriteria konkret sehingga kita tidak menilai diri sendiri terlalu longgar.

LevelKriteria
BeginnerMengerti konsep dasar; bisa solve soal Easy dalam 30 menit dengan referensi
IntermediateBisa solve soal Medium dalam 25 menit tanpa referensi; mengerti kompleksitas
AdvancedBisa solve soal Hard dalam 40 menit; bisa menjelaskan trade-off beberapa pendekatan

12 Topik Inti #

Topik berikut mencakup sebagian besar kurikulum DSA:

  1. Array & String — manipulasi dasar, two pointers, sliding window.
  2. Linked List — single, double, cycle detection, merge.
  3. Stack & Queue — operasi dasar, monotonic stack, sliding window max.
  4. Hashing — hash table, collision, counting freq, two-sum.
  5. Tree — BST, traversal, balanced tree, LCA.
  6. Heap / Priority Queue — min/max heap, top-k, merge streams.
  7. Graph — BFS, DFS, connected component, topological sort.
  8. Shortest Path — Dijkstra, Bellman-Ford, Floyd-Warshall.
  9. Disjoint Set Union — union-find, Kruskal, dynamic connectivity.
  10. Greedy — interval scheduling, Huffman, fractional knapsack.
  11. Dynamic Programming — knapsack, LCS, edit distance, DP on tree.
  12. String Algorithms — KMP, Rabin-Karp, Z-algorithm.

Template Self-Assessment #

Salin tabel berikut ke notes pribadi, lalu isi tanda centang pada sel yang sesuai dengan kondisi kita saat ini. Jadwalkan evaluasi ulang setiap 4 minggu untuk melihat progress.

#TopikBeginnerIntermediateAdvanced
1Array & String☐☐☐
2Linked List☐☐☐
3Stack & Queue☐☐☐
4Hashing☐☐☐
5Tree☐☐☐
6Heap / Priority Queue☐☐☐
7Graph☐☐☐
8Shortest Path☐☐☐
9Disjoint Set Union☐☐☐
10Greedy☐☐☐
11Dynamic Programming☐☐☐
12String Algorithms☐☐☐

Total maksimum: 36 centang (12 topik × 3 level). Untuk soal wawancara tingkat menengah, target realistis adalah 24+ centang, dengan minimal Intermediate di semua topik kecuali 2–3 topik advanced.

Kode: Kalkulator Skor Evaluasi #

Program berikut membaca status proficiency (0 = belum, 1 = beginner, 2 = intermediate, 3 = advanced) untuk setiap topik, lalu menghitung total skor, persentase, dan rekomendasi fokus. Data dimasukkan sebagai array; bila ingin mengevaluasi ulang, cukup ganti nilainya.

cpp
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
using namespace std;

struct TopicScore {
    string name;
    int level;          // 0=belum, 1=beginner, 2=intermediate, 3=advanced
};

vector<TopicScore> assessment() {
    // Contoh: nilai setelah 8 minggu belajar
    return {
        {"Array & String",        3},
        {"Linked List",           2},
        {"Stack & Queue",         2},
        {"Hashing",               3},
        {"Tree",                  2},
        {"Heap / Priority Queue", 2},
        {"Graph",                 1},
        {"Shortest Path",         1},
        {"Disjoint Set Union",    0},
        {"Greedy",                1},
        {"Dynamic Programming",   1},
        {"String Algorithms",     0},
    };
}

void printRubric(const vector<TopicScore>& scores) {
    cout << left << setw(4) << "#" << setw(25) << "Topik"
         << setw(12) << "Level" << "Status\n";
    cout << string(70, '-') << "\n";
    const vector<string> labels = {"Belum", "Beginner", "Intermediate", "Advanced"};
    for (size_t i = 0; i < scores.size(); ++i) {
        const auto& s = scores[i];
        cout << left << setw(4) << (i + 1)
             << setw(25) << s.name
             << setw(12) << labels[s.level];
        if (s.level == 0) cout << "[FOKUS]";
        else if (s.level == 1) cout << "[Berkembang]";
        else if (s.level == 2) cout << "[Solid]";
        else cout << "[Kuat]";
        cout << "\n";
    }
}

void summary(const vector<TopicScore>& scores) {
    int total = 0, maxPossible = (int)scores.size() * 3;
    int byLevel[4] = {0, 0, 0, 0};
    for (const auto& s : scores) {
        total += s.level;
        byLevel[s.level]++;
    }
    double pct = 100.0 * total / maxPossible;

    cout << "\n=== Ringkasan Skor ===\n";
    cout << "Total skor: " << total << " / " << maxPossible
         << " (" << fixed << setprecision(1) << pct << "%)\n\n";

    cout << "Distribusi level:\n";
    cout << "  Belum        : " << byLevel[0] << " topik\n";
    cout << "  Beginner     : " << byLevel[1] << " topik\n";
    cout << "  Intermediate : " << byLevel[2] << " topik\n";
    cout << "  Advanced     : " << byLevel[3] << " topik\n";
}

void actionPlan(const vector<TopicScore>& scores) {
    cout << "\n=== Action Plan 4 Minggu ===\n";
    cout << "Prioritas 1 (level 0 -> harus diangkat ke Beginner):\n";
    for (const auto& s : scores) {
        if (s.level == 0) {
            cout << "  - " << s.name
                 << ": baca materi dasar, kerjakan 3 soal Easy\n";
        }
    }
    cout << "\nPrioritas 2 (level 1 -> dorong ke Intermediate):\n";
    for (const auto& s : scores) {
        if (s.level == 1) {
            cout << "  - " << s.name
                 << ": 5 soal Medium, fokus pola wawancara\n";
        }
    }
    cout << "\nPrioritas 3 (level 2 -> sustains dengan 1 soal Hard/minggu):\n";
    for (const auto& s : scores) {
        if (s.level == 2) {
            cout << "  - " << s.name << "\n";
        }
    }
    cout << "\nPertahankan (level 3 -> review bulanan):\n";
    for (const auto& s : scores) {
        if (s.level == 3) {
            cout << "  - " << s.name << "\n";
        }
    }
}

int main() {
    auto scores = assessment();
    cout << "=== Evaluasi Kemampuan DSA ===\n\n";
    printRubric(scores);
    summary(scores);
    actionPlan(scores);
    return 0;
}

Output yang Dihasilkan:

text
=== Evaluasi Kemampuan DSA ===

#   Topik                    Level       Status
----------------------------------------------------------------------
1   Array & String           Advanced    [Kuat]
2   Linked List              Intermediate[Solid]
3   Stack & Queue            Intermediate[Solid]
4   Hashing                  Advanced    [Kuat]
5   Tree                     Intermediate[Solid]
6   Heap / Priority Queue    Intermediate[Solid]
7   Graph                    Beginner    [Berkembang]
8   Shortest Path            Beginner    [Berkembang]
9   Disjoint Set Union       Belum       [FOKUS]
10  Greedy                   Beginner    [Berkembang]
11  Dynamic Programming      Beginner    [Berkembang]
12  String Algorithms        Belum       [FOKUS]

=== Ringkasan Skor ===
Total skor: 18 / 36 (50.0%)

Distribusi level:
  Belum        : 2 topik
  Beginner     : 4 topik
  Intermediate : 4 topik
  Advanced     : 2 topik

=== Action Plan 4 Minggu ===
Prioritas 1 (level 0 -> harus diangkat ke Beginner):
  - Disjoint Set Union: baca materi dasar, kerjakan 3 soal Easy
  - String Algorithms: baca materi dasar, kerjakan 3 soal Easy

Prioritas 2 (level 1 -> dorong ke Intermediate):
  - Graph: 5 soal Medium, fokus pola wawancara
  - Shortest Path: 5 soal Medium, fokus pola wawancara
  - Greedy: 5 soal Medium, fokus pola wawancara
  - Dynamic Programming: 5 soal Medium, fokus pola wawancara

Prioritas 3 (level 2 -> sustains dengan 1 soal Hard/minggu):
  - Linked List
  - Stack & Queue
  - Tree
  - Heap / Priority Queue

Pertahankan (level 3 -> review bulanan):
  - Array & String
  - Hashing

Bedah Kode Baris-per-Baris #

  1. struct TopicScore { string name; int level; }: model data sederhana untuk satu topik. Field level sebagai int (0–3) lebih fleksibel daripada enum untuk kode pendek seperti ini.
  2. vector<TopicScore> assessment(): mengembalikan snapshot kondisi terkini. Memisahkan data dari logika — bila kita ingin evaluasi ulang bulan depan, cukup ganti angka level di satu tempat.
  3. const vector<string> labels = {"Belum", "Beginner", ...}: pemetaan dari angka ke label. Indexing dengan s.level langsung memberikan label teks yang siap dicetak.
  4. for (size_t i = 0; i < scores.size(); ++i): pakai size_t karena membandingkan dengan .size() (return size_t). Loop tradisional dipakai karena kita butuh indeks i untuk nomor baris.
  5. int byLevel[4] = {0,0,0,0}: array C-style berukuran tetap untuk histogram distribusi. Lebih ringan daripada vector<int> bila ukuran sudah diketahui statis.
  6. double pct = 100.0 * total / maxPossible: cast eksplisit 100.0 agar pembagian floating-point. Tanpa .0, 100 * total / maxPossible adalah integer division yang membuang pecahan.
  7. cout << fixed << setprecision(1) << pct: format dua angka di belakang koma. fixed menjamin notasi desimal (bukan scientific); setprecision(1) membatasi 1 angka pecahan.
  8. if (s.level == 0) … else if (s.level == 1) …: action plan dibagi per level. Topik level 0 mendapat prioritas tertinggi; level 3 hanya di-review bulanan.

Cara Mengidentifikasi Area Lemah #

Selain skor numerik, kita perlu validasi kualitatif. Tiga metode berikut saling melengkapi:

MetodeCaraSinyal Lemah
Soal latihan timerKerjakan 3 soal Medium per topik dalam 25 menit>1 soal timeout, atau <2 soal AC
Penjelasan lisanRekam diri menjelaskan konsep topikBanyak blank, salah istilah, lupa edge case
Review kode sendiriBaca kode lama 1 bulan laluTidak mengerti apa yang ditulis, atau bisa refactor signifikan

Action Plan Berdasarkan Hasil #

Berdasarkan skor akhir, susun rencana 4 minggu berikut. Rumus distribusi waktu:

  • Level 0 → Beginner: 40% waktu belajar minggu ini, fokus materi dasar.
  • Level 1 → Intermediate: 30% waktu, 5 soal Medium bertema pola wawancara.
  • Level 2 → Advanced: 20% waktu, 1 soal Hard per minggu untuk dorong level.
  • Level 3 (sustain): 10% waktu, review bulanan, 1 soal acak agar tidak lupa.

Contoh Jadwal Mingguan (10 jam/minggu) #

HariAktivitasDurasi
SeninBelajar teori topik level 02 jam
Selasa2 soal Easy topik level 01.5 jam
Rabu1 soal Medium topik level 11.5 jam
KamisBelajar teori topik level 02 jam
Jumat2 soal Medium topik level 12 jam
Sabtu1 soal Hard topik level 21 jam
MingguReview + 1 soal acak sustain0 jam bila tidak ada level 3, atau 1 jam bila ada

Tracking Progress Antar-Siklus #

Simpan snapshot rubrik setiap 4 minggu. Pola progress yang sehat:

  • Minggu 0 → Minggu 4: minimal 2 topik naik level.
  • Minggu 4 → Minggu 8: minimal 2 topik lagi naik level, atau 1 topik naik 2 level.
  • Minggu 8 → Minggu 12: minimal 1 topik baru mencapai Advanced.

Bila tidak ada kemajuan dalam 4 minggu, salah satu hal berikut biasanya penyebabnya:

  1. Belajar pasif — terlalu banyak baca, terlalu sedikit solve.
  2. Tidak ada timer — soal Medium dikerjakan 60 menit, bukan 25 menit.
  3. Tidak baca editorial — soal salah tidak dianalisis penyebabnya.

Ringkasan #

  • Rubrik evaluasi 2-dimensi (12 topik × 3 level) memberikan peta kekuatan dan kelemahan.
  • Level proficiency: Beginner (Easy + referensi), Intermediate (Medium tanpa referensi), Advanced (Hard + bisa menjelaskan trade-off).
  • Skor total maksimum 36; target realistis untuk wawancara tingkat menengah adalah 24+ centang.
  • Action plan 4 minggu distribusikan: level 0 (40%), level 1 (30%), level 2 (20%), level 3 (10%).
  • Evaluasi ulang setiap 4 minggu; bila tidak ada progress, audit metode belajar.