Tips Interview & Algoritma
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
| Langkah | Aksi |
|---|---|
| Understand | Pahami soal. Tanya balik kalau ambigu. |
| Match | Cocokkan dengan pola yang kamu tahu |
| Plan | Tulis pseudocode / jelaskan approach |
| Implement | Tulis kode |
| Review | Cek edge case, dry run |
| Evaluate | Analisis 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 O | Nama | Contoh | 1000 data |
|---|---|---|---|
| O(1) | Constant | Akses array[i] | 1 operasi |
| O(log n) | Logarithmic | Binary search | ~10 operasi |
| O(n) | Linear | Loop biasa | 1000 operasi |
| O(n log n) | Linearithmic | Sort (merge/quick) | ~10.000 operasi |
| O(n²) | Quadratic | Nested loop | 1.000.000 operasi |
| O(2ⁿ) | Exponential | Brute force subset | 10³⁰⁰ operasi 💀 |
Cara Menghitung
// 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:
// 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.
// 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// 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) spacePola 2: HashMap / Frequency Counter
Kapan pakai: Cari duplikat, hitung frekuensi, Two Sum, anagram.
// 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// 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.
// 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// 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)) spacePola 4: Rekursi & Dynamic Programming
Kapan pakai: Masalah yang bisa dipecah jadi sub-masalah lebih kecil.
// 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;
}// 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) spacePola 5: Stack & Queue
Kapan pakai: Validasi bracket, undo/redo, BFS/DFS.
// 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) spacePola 6: Sorting & Searching
// 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) time2.4 Soal JavaScript Spesifik (Sering Muncul!)
Soal 1: Closures
// 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
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
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 microtaskSoal 4: Prototype & Inheritance
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
// 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
// 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
// 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
// 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())
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
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
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
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
function capitalize(str) {
return str
.split(' ')
.map(word => word[0].toUpperCase() + word.slice(1))
.join(' ');
}6. Remove Duplicates
// 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
function intersection(arr1, arr2) {
const set = new Set(arr1);
return arr2.filter(item => set.has(item));
}8. Implement Array.prototype.map
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
- Latihan di LeetCode/HackerRank — minimal 50 soal easy, 20 medium
- Latihan ngomong sambil coding — record diri sendiri
- Riset perusahaan — tech stack mereka apa? Problem apa yang mereka solve?
- Siapkan pertanyaan balik — "Bagaimana proses code review di tim?"
Saat Interview
- Jangan panik kalau stuck — bilang: "Boleh saya pikir sebentar?"
- Jelaskan approach sebelum coding — interviewer mau lihat cara pikir
- Start dari brute force — lalu optimasi. Lebih baik punya solusi O(n²) daripada tidak ada solusi
- Test dengan contoh — dry run kode kamu dengan input kecil
- Handle edge case — null, empty array, satu elemen, angka negatif
Setelah Interview
- Kirim thank you email dalam 24 jam
- Catat soal yang keluar — untuk latihan selanjutnya
- Jangan menyerah — rejection itu normal. Senior engineer pun pernah ditolak
2.7 Behavioral Questions (Non-Coding)
Sering muncul di interview:
| Pertanyaan | Tips 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
| Platform | Fokus | Gratis? |
|---|---|---|
| LeetCode | Algoritma & DS | Sebagian |
| HackerRank | Skill assessment | Ya |
| Codewars | Gamified challenges | Ya |
| NeetCode | Roadmap LeetCode | Ya |
| JavaScript30 | 30 project JS | Ya |
| Frontend Mentor | UI challenges | Sebagian |
Urutan Belajar yang Disarankan
- Easy LeetCode — 50 soal (Two Sum, Valid Parentheses, Merge Sorted, dll)
- Pola-pola — Kuasai 6 pola di atas
- Medium LeetCode — 30 soal (fokus pola yang lemah)
- Mock interview — Pramp.com (gratis, peer-to-peer)
- 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.
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:
- Konsisten latihan — 1-2 soal per hari lebih baik dari marathon 1 hari
- Pahami pola — bukan hafal solusi
- Komunikasi — jelaskan pikiran kamu
- Jangan menyerah — setiap rejection = data point untuk improve
Good luck! 🚀
Sudah paham materi ini?
Tandai sebagai selesai untuk melacak progress-mu.