Tips Interview & Algoritma

6 menit baca

Pengantar

Kamu udah belajar JavaScript dari A-Z. Sekarang saatnya buktikan ke dunia kerja. Interview teknis itu bukan ujian hafalan — ini tentang cara kamu berpikir, memecahkan masalah, dan mengkomunikasikan solusi.

Bab ini berisi:

  • Pola-pola soal yang sering muncul
  • Cara berpikir saat interview (framework)
  • Big O notation (wajib tahu)
  • 20+ soal klasik dengan pembahasan

2.1 Framework Menjawab Soal Interview

Langkah UMPIRE

LangkahAksi
UnderstandPahami soal. Tanya balik kalau ambigu.
MatchCocokkan dengan pola yang kamu tahu
PlanTulis pseudocode / jelaskan approach
ImplementTulis kode
ReviewCek edge case, dry run
EvaluateAnalisis Big O, bisa dioptimasi?

Contoh Penerapan

Soal: "Cari dua angka di array yang jumlahnya sama dengan target."

U: Input array angka + target number. Output: index dua angka. Pertanyaan: Boleh pakai angka yang sama dua kali? (Tidak) Selalu ada solusi? (Asumsikan ya) M: Ini pola "Two Sum" — bisa pakai HashMap P: Loop array, untuk setiap angka cek apakah (target - angka) sudah ada di map. Kalau ada, return. Kalau belum, simpan. I: (tulis kode) R: Edge case — array kosong? Satu elemen? Angka negatif? E: O(n) time, O(n) space — optimal

⚠️ Jebakan Interview

  • Langsung coding tanpa bertanya — interviewer mau lihat kamu berpikir dulu
  • Diam saat stuck — bilang aja "Saya lagi mikirin approach X karena..."
  • Tidak handle edge case — array kosong, null, angka negatif
  • Tidak analisis kompleksitas — selalu sebutkan Big O di akhir

2.2 Big O Notation — Seberapa Cepat Kode Kamu?

Analogi: Cari Nama di Buku Telepon

  • O(1) — Kamu tahu halaman persisnya. Langsung buka.
  • O(log n) — Buka tengah, terlalu jauh? Buka tengah lagi. (Binary search)
  • O(n) — Baca satu-satu dari halaman 1 sampai ketemu.
  • O(n log n) — Urutkan dulu buku yang acak, baru cari.
  • O(n²) — Untuk setiap nama, bandingkan dengan semua nama lain.
  • O(2ⁿ) — Coba semua kemungkinan kombinasi.

Tabel Referensi

Big ONamaContoh1000 data
O(1)ConstantAkses array[i]1 operasi
O(log n)LogarithmicBinary search~10 operasi
O(n)LinearLoop biasa1000 operasi
O(n log n)LinearithmicSort (merge/quick)~10.000 operasi
O(n²)QuadraticNested loop1.000.000 operasi
O(2ⁿ)ExponentialBrute force subset10³⁰⁰ operasi 💀

Cara Menghitung

javascript
// O(1) — tidak tergantung ukuran input
function getFirst(arr) {
  return arr[0];
}

// O(n) — satu loop
function cariMax(arr) {
  let max = arr[0];
  for (let i = 1; i < arr.length; i++) {
    if (arr[i] > max) max = arr[i];
  }
  return max;
}

// O(n²) — nested loop
function cariDuplikat(arr) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] === arr[j]) return true;
    }
  }
  return false;
}

// O(log n) — input dibagi 2 setiap iterasi
function binarySearch(arr, target) {
  let left = 0, right = arr.length - 1;
  while (left <= right) {
    const mid = Math.floor((left + right) / 2);
    if (arr[mid] === target) return mid;
    if (arr[mid] < target) left = mid + 1;
    else right = mid - 1;
  }
  return -1;
}

Space Complexity

Bukan cuma waktu — memori juga dihitung:

javascript
// O(1) space — tidak buat struktur data baru
function jumlah(arr) {
  let total = 0;
  for (const n of arr) total += n;
  return total;
}

// O(n) space — buat array/object baru sebesar input
function duplikat(arr) {
  const seen = new Set();
  for (const n of arr) {
    if (seen.has(n)) return n;
    seen.add(n);
  }
}

2.3 Pola-Pola Soal yang Sering Muncul

Pola 1: Two Pointers

Kapan pakai: Array yang sudah sorted, cari pasangan, palindrome.

javascript
// Contoh: Cek palindrome
function isPalindrome(str) {
  let left = 0;
  let right = str.length - 1;
  
  while (left < right) {
    if (str[left] !== str[right]) return false;
    left++;
    right--;
  }
  return true;
}
// O(n) time, O(1) space
javascript
// Contoh: Two Sum di sorted array
function twoSumSorted(arr, target) {
  let left = 0;
  let right = arr.length - 1;
  
  while (left < right) {
    const sum = arr[left] + arr[right];
    if (sum === target) return [left, right];
    if (sum < target) left++;
    else right--;
  }
  return [-1, -1];
}
// O(n) time, O(1) space

Pola 2: HashMap / Frequency Counter

Kapan pakai: Cari duplikat, hitung frekuensi, Two Sum, anagram.

javascript
// Contoh: Two Sum (unsorted)
function twoSum(nums, target) {
  const map = new Map();
  
  for (let i = 0; i < nums.length; i++) {
    const complement = target - nums[i];
    if (map.has(complement)) {
      return [map.get(complement), i];
    }
    map.set(nums[i], i);
  }
  return [-1, -1];
}
// O(n) time, O(n) space
javascript
// Contoh: Cek anagram
function isAnagram(s, t) {
  if (s.length !== t.length) return false;
  
  const freq = {};
  for (const c of s) freq[c] = (freq[c] || 0) + 1;
  for (const c of t) {
    if (!freq[c]) return false;
    freq[c]--;
  }
  return true;
}
// O(n) time, O(1) space (max 26 huruf)

Pola 3: Sliding Window

Kapan pakai: Subarray/substring dengan kondisi tertentu, max/min dalam range.

javascript
// Contoh: Maximum sum subarray dengan panjang k
function maxSumSubarray(arr, k) {
  let windowSum = 0;
  
  // Hitung sum window pertama
  for (let i = 0; i < k; i++) {
    windowSum += arr[i];
  }
  
  let maxSum = windowSum;
  
  // Geser window: tambah kanan, kurangi kiri
  for (let i = k; i < arr.length; i++) {
    windowSum += arr[i] - arr[i - k];
    maxSum = Math.max(maxSum, windowSum);
  }
  
  return maxSum;
}
// O(n) time, O(1) space
javascript
// Contoh: Longest substring tanpa karakter berulang
function lengthOfLongestSubstring(s) {
  const seen = new Map();
  let maxLen = 0;
  let start = 0;
  
  for (let end = 0; end < s.length; end++) {
    if (seen.has(s[end]) && seen.get(s[end]) >= start) {
      start = seen.get(s[end]) + 1;
    }
    seen.set(s[end], end);
    maxLen = Math.max(maxLen, end - start + 1);
  }
  
  return maxLen;
}
// O(n) time, O(min(n, 26)) space

Pola 4: Rekursi & Dynamic Programming

Kapan pakai: Masalah yang bisa dipecah jadi sub-masalah lebih kecil.

javascript
// Contoh: Fibonacci (naive — O(2ⁿ) ❌)
function fibNaive(n) {
  if (n <= 1) return n;
  return fibNaive(n - 1) + fibNaive(n - 2);
}

// Fibonacci dengan memoization — O(n) ✅
function fibMemo(n, memo = {}) {
  if (n <= 1) return n;
  if (memo[n]) return memo[n];
  memo[n] = fibMemo(n - 1, memo) + fibMemo(n - 2, memo);
  return memo[n];
}

// Fibonacci iteratif — O(n) time, O(1) space ✅✅
function fibIterative(n) {
  if (n <= 1) return n;
  let prev = 0, curr = 1;
  for (let i = 2; i <= n; i++) {
    [prev, curr] = [curr, prev + curr];
  }
  return curr;
}
javascript
// Contoh: Climbing Stairs (berapa cara naik n tangga, 1 atau 2 langkah)
function climbStairs(n) {
  if (n <= 2) return n;
  let prev = 1, curr = 2;
  for (let i = 3; i <= n; i++) {
    [prev, curr] = [curr, prev + curr];
  }
  return curr;
}
// Sama kayak Fibonacci! O(n) time, O(1) space

Pola 5: Stack & Queue

Kapan pakai: Validasi bracket, undo/redo, BFS/DFS.

javascript
// Contoh: Valid Parentheses
function isValid(s) {
  const stack = [];
  const pairs = { ')': '(', ']': '[', '}': '{' };
  
  for (const char of s) {
    if ('([{'.includes(char)) {
      stack.push(char);
    } else {
      if (stack.pop() !== pairs[char]) return false;
    }
  }
  
  return stack.length === 0;
}
// O(n) time, O(n) space

Pola 6: Sorting & Searching

javascript
// Contoh: Cari elemen terbesar ke-k
function findKthLargest(nums, k) {
  nums.sort((a, b) => b - a);
  return nums[k - 1];
}
// O(n log n) — bisa dioptimasi pakai QuickSelect ke O(n) average

// Contoh: Merge dua sorted array
function mergeSorted(arr1, arr2) {
  const result = [];
  let i = 0, j = 0;
  
  while (i < arr1.length && j < arr2.length) {
    if (arr1[i] <= arr2[j]) result.push(arr1[i++]);
    else result.push(arr2[j++]);
  }
  
  return [...result, ...arr1.slice(i), ...arr2.slice(j)];
}
// O(n + m) time

2.4 Soal JavaScript Spesifik (Sering Muncul!)

Soal 1: Closures

javascript
// Apa output-nya?
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Output: 3, 3, 3 (bukan 0, 1, 2!)
// Kenapa: var tidak punya block scope, i sudah jadi 3 saat setTimeout jalan

// Fix 1: pakai let
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Output: 0, 1, 2 ✅

// Fix 2: pakai IIFE
for (var i = 0; i < 3; i++) {
  ((j) => setTimeout(() => console.log(j), 100))(i);
}

Soal 2: this

javascript
const obj = {
  nama: "Budi",
  sapa: function() {
    console.log(`Halo, ${this.nama}`);
  },
  sapaArrow: () => {
    console.log(`Halo, ${this.nama}`);
  }
};

obj.sapa();       // "Halo, Budi" ✅
obj.sapaArrow();  // "Halo, undefined" ❌ (arrow function ambil this dari luar)

const sapa = obj.sapa;
sapa();           // "Halo, undefined" ❌ (this = window/global)
sapa.call(obj);   // "Halo, Budi" ✅ (paksa this = obj)

Soal 3: Event Loop

javascript
console.log("1");

setTimeout(() => console.log("2"), 0);

Promise.resolve().then(() => console.log("3"));

console.log("4");

// Output: 1, 4, 3, 2
// Kenapa:
// - "1" dan "4" = synchronous, langsung jalan
// - "3" = microtask (Promise), jalan setelah sync selesai
// - "2" = macrotask (setTimeout), jalan setelah microtask

Soal 4: Prototype & Inheritance

javascript
function Animal(name) {
  this.name = name;
}
Animal.prototype.speak = function() {
  return `${this.name} makes a sound`;
};

function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
  return `${this.name} barks!`;
};

const rex = new Dog("Rex", "German Shepherd");
rex.speak(); // "Rex makes a sound" (dari Animal)
rex.bark();  // "Rex barks!" (dari Dog)

Soal 5: Debounce & Throttle

javascript
// Debounce: tunggu user berhenti mengetik baru jalankan
function debounce(fn, delay) {
  let timer;
  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

// Throttle: jalankan maksimal sekali per interval
function throttle(fn, interval) {
  let lastTime = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastTime >= interval) {
      lastTime = now;
      fn.apply(this, args);
    }
  };
}

Soal 6: Deep Clone

javascript
// Shallow copy (SALAH untuk nested object)
const copy1 = { ...original }; // level 1 saja

// Deep clone (cara modern)
const copy2 = structuredClone(original);

// Deep clone manual (interview favorite)
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof Array) return obj.map(item => deepClone(item));
  
  const clone = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key]);
    }
  }
  return clone;
}

Soal 7: Promise

javascript
// Implement Promise.all sendiri
function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    const results = [];
    let completed = 0;
    
    if (promises.length === 0) return resolve([]);
    
    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then(value => {
          results[index] = value;
          completed++;
          if (completed === promises.length) resolve(results);
        })
        .catch(reject);
    });
  });
}

Soal 8: Flatten Array

javascript
// Flatten nested array
function flatten(arr) {
  return arr.reduce((acc, item) => {
    return acc.concat(Array.isArray(item) ? flatten(item) : item);
  }, []);
}

// Atau pakai built-in
[1, [2, [3, [4]]]].flat(Infinity); // [1, 2, 3, 4]

2.5 Soal Coding Challenge Klasik

1. Reverse String (tanpa .reverse())

javascript
function reverseString(str) {
  let result = '';
  for (let i = str.length - 1; i >= 0; i--) {
    result += str[i];
  }
  return result;
}
// Atau: str.split('').reverse().join('')

2. FizzBuzz

javascript
function fizzBuzz(n) {
  for (let i = 1; i <= n; i++) {
    if (i % 15 === 0) console.log("FizzBuzz");
    else if (i % 3 === 0) console.log("Fizz");
    else if (i % 5 === 0) console.log("Buzz");
    else console.log(i);
  }
}

3. Cari Karakter yang Paling Sering Muncul

javascript
function mostFrequentChar(str) {
  const freq = {};
  let maxChar = '';
  let maxCount = 0;
  
  for (const char of str) {
    freq[char] = (freq[char] || 0) + 1;
    if (freq[char] > maxCount) {
      maxCount = freq[char];
      maxChar = char;
    }
  }
  
  return maxChar;
}

4. Array Chunk

javascript
function chunk(arr, size) {
  const result = [];
  for (let i = 0; i < arr.length; i += size) {
    result.push(arr.slice(i, i + size));
  }
  return result;
}
// chunk([1,2,3,4,5], 2) → [[1,2], [3,4], [5]]

5. Capitalize Setiap Kata

javascript
function capitalize(str) {
  return str
    .split(' ')
    .map(word => word[0].toUpperCase() + word.slice(1))
    .join(' ');
}

6. Remove Duplicates

javascript
// Cara 1: Set
const unique = [...new Set(arr)];

// Cara 2: filter
const unique2 = arr.filter((item, index) => arr.indexOf(item) === index);

7. Intersection of Two Arrays

javascript
function intersection(arr1, arr2) {
  const set = new Set(arr1);
  return arr2.filter(item => set.has(item));
}

8. Implement Array.prototype.map

javascript
Array.prototype.myMap = function(callback) {
  const result = [];
  for (let i = 0; i < this.length; i++) {
    result.push(callback(this[i], i, this));
  }
  return result;
};

2.6 Tips Non-Teknis

Sebelum Interview

  1. Latihan di LeetCode/HackerRank — minimal 50 soal easy, 20 medium
  2. Latihan ngomong sambil coding — record diri sendiri
  3. Riset perusahaan — tech stack mereka apa? Problem apa yang mereka solve?
  4. Siapkan pertanyaan balik — "Bagaimana proses code review di tim?"

Saat Interview

  1. Jangan panik kalau stuck — bilang: "Boleh saya pikir sebentar?"
  2. Jelaskan approach sebelum coding — interviewer mau lihat cara pikir
  3. Start dari brute force — lalu optimasi. Lebih baik punya solusi O(n²) daripada tidak ada solusi
  4. Test dengan contoh — dry run kode kamu dengan input kecil
  5. Handle edge case — null, empty array, satu elemen, angka negatif

Setelah Interview

  1. Kirim thank you email dalam 24 jam
  2. Catat soal yang keluar — untuk latihan selanjutnya
  3. Jangan menyerah — rejection itu normal. Senior engineer pun pernah ditolak

2.7 Behavioral Questions (Non-Coding)

Sering muncul di interview:

PertanyaanTips Jawab
"Ceritakan tentang diri kamu"30 detik: background → skill → kenapa apply
"Project paling challenging?"Pakai format STAR: Situation, Task, Action, Result
"Pernah conflict sama tim?"Jujur, fokus ke solusi bukan drama
"Kenapa mau kerja di sini?"Riset perusahaan, hubungkan dengan goal kamu
"Kelemahan kamu apa?"Jujur + tunjukkan cara kamu improve

Format STAR

S (Situation): "Di project X, deadline mepet 2 minggu..." T (Task): "Saya harus implement fitur payment gateway..." A (Action): "Saya breakdown jadi task kecil, prioritaskan MVP..." R (Result): "Selesai tepat waktu, zero bug di production..."

2.8 Resources untuk Latihan

PlatformFokusGratis?
LeetCodeAlgoritma & DSSebagian
HackerRankSkill assessmentYa
CodewarsGamified challengesYa
NeetCodeRoadmap LeetCodeYa
JavaScript3030 project JSYa
Frontend MentorUI challengesSebagian

Urutan Belajar yang Disarankan

  1. Easy LeetCode — 50 soal (Two Sum, Valid Parentheses, Merge Sorted, dll)
  2. Pola-pola — Kuasai 6 pola di atas
  3. Medium LeetCode — 30 soal (fokus pola yang lemah)
  4. Mock interview — Pramp.com (gratis, peer-to-peer)
  5. System design (untuk mid-senior) — Grokking System Design

🏋️ Challenge

Challenge 1: Two Sum

Tulis fungsi twoSum(nums, target) yang return index dua angka yang jumlahnya = target. Pakai HashMap (O(n)).

Challenge 2: Valid Anagram

Tulis fungsi isAnagram(s, t) yang return true kalau t adalah anagram dari s.

Challenge 3: Maximum Subarray (Kadane's Algorithm)

Tulis fungsi maxSubArray(nums) yang return sum terbesar dari subarray contiguous.

Challenge 4: Implement Debounce

Tulis fungsi debounce(fn, delay) yang menunda eksekusi fn sampai delay ms setelah panggilan terakhir.

Challenge 5: Flatten Object

Tulis fungsi flattenObject(obj) yang mengubah nested object jadi flat dengan dot notation key.

javascript
flattenObject({ a: { b: 1, c: { d: 2 } } })
// { 'a.b': 1, 'a.c.d': 2 }

Penutup

Interview itu skill yang bisa dilatih. Orang yang lolos bukan yang paling pintar — tapi yang paling terlatih. Kunci:

  1. Konsisten latihan — 1-2 soal per hari lebih baik dari marathon 1 hari
  2. Pahami pola — bukan hafal solusi
  3. Komunikasi — jelaskan pikiran kamu
  4. Jangan menyerah — setiap rejection = data point untuk improve

Good luck! 🚀

Sudah paham materi ini?

Tandai sebagai selesai untuk melacak progress-mu.