├── .travis.yml ├── front-end └── README.md ├── design ├── search-engine.md ├── README.md ├── collaborative-editor.md └── news-feed.md ├── algorithms ├── heap.md ├── geometry.md ├── bit-manipulation.md ├── queue.md ├── oop.md ├── hash-table.md ├── stack.md ├── graph.md ├── permutation.md ├── linked-list.md ├── sorting-searching.md ├── math.md ├── interval.md ├── dynamic-programming.md ├── topics.md ├── tree.md ├── matrix.md ├── string.md └── array.md ├── utilities ├── python │ ├── tree_mirror.py │ ├── tree_equal.py │ ├── is_subsequence.py │ ├── char_prime_map.py │ ├── graph_topo_sort.py │ ├── union_find.py │ ├── graph_dfs.py │ ├── tree_traversal.py │ ├── rabin_karp_hash.py │ ├── heap.py │ ├── quick_select.py │ ├── binary_search.py │ ├── trie.py │ └── linked_list.py └── javascript │ ├── treeMirror.js │ ├── treeEqual.js │ ├── matrixTranspose.js │ ├── isSubsequence.js │ ├── binToInt.js │ ├── matrixClone.js │ ├── intToBin.js │ ├── intervalsMerge.js │ ├── intervalsIntersect.js │ ├── binarySearch.js │ ├── matrixTraverse.js │ ├── graphTopoSort.js │ ├── deepEqual.js │ └── mergeSort.js ├── .editorconfig ├── CODE_OF_CONDUCT.md ├── domain ├── databases.md ├── networking.md ├── software-engineering.md ├── async-loading │ └── index.html ├── snake-game │ └── snake-game.md ├── security.md ├── pagination-sorting │ ├── index.html │ └── data.js └── tic-tac-toe │ └── index.html ├── non-technical ├── cover-letter.md ├── psychological-tricks.md ├── self-introduction.md ├── interview-formats.md ├── negotiation.md ├── questions-to-ask.md ├── behavioral.md └── resume.md ├── CONTRIBUTING.md ├── LICENSE ├── interviewers └── basics.md ├── README.md ├── assets └── book.svg └── preparing ├── cheatsheet.md └── README.md /.travis.yml: -------------------------------------------------------------------------------- 1 | install: 2 | - gem install awesome_bot 3 | 4 | script: 5 | - awesome_bot **/*.md --allow-dupe --allow-redirect --allow 429 --skip-save-results 6 | -------------------------------------------------------------------------------- /front-end/README.md: -------------------------------------------------------------------------------- 1 | # Front-end Job Interview Questions 2 | 3 | Front-end Job Interview Questions have been migrated [here](https://github.com/yangshun/front-end-interview-handbook). 4 | -------------------------------------------------------------------------------- /design/search-engine.md: -------------------------------------------------------------------------------- 1 | Search Engine 2 | == 3 | 4 | ###### References 5 | 6 | - [How Do Search Engines Work?](http://www.makeuseof.com/tag/how-do-search-engines-work-makeuseof-explains/) 7 | -------------------------------------------------------------------------------- /algorithms/heap.md: -------------------------------------------------------------------------------- 1 | Heap 2 | == 3 | 4 | - Merge `K` sorted lists together into a single list. 5 | - Given a stream of integers, write an efficient function that returns the median value of the integers. 6 | -------------------------------------------------------------------------------- /utilities/python/tree_mirror.py: -------------------------------------------------------------------------------- 1 | def tree_mirror(node): 2 | if not node: 3 | return 4 | node.left, node.right = node.right, node.left 5 | tree_mirror(node.left) 6 | tree_mirror(node.right) 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | [*.{js,py}] 9 | charset = utf-8 10 | indent_style = space 11 | indent_size = 4 12 | -------------------------------------------------------------------------------- /utilities/javascript/treeMirror.js: -------------------------------------------------------------------------------- 1 | function treeMirror(node) { 2 | if (!node) { 3 | return; 4 | } 5 | let temp = node.left; 6 | node.left = node.right; 7 | node.right = temp; 8 | treeMirror(node.left); 9 | treeMirror(node.right); 10 | } 11 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | We have adopted the same Code of Conduct as Facebook that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated. 4 | -------------------------------------------------------------------------------- /domain/databases.md: -------------------------------------------------------------------------------- 1 | Databases 2 | == 3 | 4 | ## General 5 | 6 | - How should you store passwords in a database? 7 | - http://www.geeksforgeeks.org/store-password-database/ 8 | - https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/ 9 | -------------------------------------------------------------------------------- /domain/networking.md: -------------------------------------------------------------------------------- 1 | Networking 2 | == 3 | 4 | - Given an IPv4 IP address p and an integer n, return a list of CIDR strings that most succinctly represents the range of IP addresses from p to (p + n). 5 | - Describe what happens when you enter a url in the web browser. 6 | - Define UDP/TCP and give an example of both. 7 | -------------------------------------------------------------------------------- /utilities/python/tree_equal.py: -------------------------------------------------------------------------------- 1 | def tree_equal(node1, node2): 2 | if not node1 and not node2: 3 | return True 4 | if not node1 or not node2: 5 | return False 6 | return node1.val == node2.val and \ 7 | tree_equal(node1.left, node2.left) and \ 8 | tree_equal(node1.right, node2.right) 9 | -------------------------------------------------------------------------------- /algorithms/geometry.md: -------------------------------------------------------------------------------- 1 | Geometry 2 | == 3 | 4 | - You have a plane with lots of rectangles on it, find out how many of them intersect. 5 | - Which data structure would you use to query the k-nearest points of a set on a 2D plane? 6 | - Given many points, find k points that are closest to the origin. 7 | - How would you triangulate a polygon? 8 | -------------------------------------------------------------------------------- /utilities/javascript/treeEqual.js: -------------------------------------------------------------------------------- 1 | function treeEqual(node1, node2) { 2 | if (!node1 && !node2) { 3 | return true; 4 | } 5 | if (!node1 || !node2) { 6 | return false; 7 | } 8 | return node1.val == node2.val && 9 | treeEqual(node1.left, node2.left) && 10 | treeEqual(node1.right, node2.right); 11 | } 12 | -------------------------------------------------------------------------------- /algorithms/bit-manipulation.md: -------------------------------------------------------------------------------- 1 | Bit Manipulation 2 | == 3 | 4 | - How do you verify if an interger is a power of 2? 5 | - Write a program to print the binary representation of an integer. 6 | - Write a program to print out the number of 1 bits in a given integer. 7 | - Write a program to determine the largest possible integer using the same number of 1 bits in a given number. 8 | -------------------------------------------------------------------------------- /non-technical/cover-letter.md: -------------------------------------------------------------------------------- 1 | Cover Letter 2 | == 3 | 4 | - A short introduction describing who you are and what you're looking for. 5 | - What projects have you enjoyed working on? 6 | - Which have you disliked? What motivates you? 7 | - Links to online profiles you use (GitHub, Twitter, etc). 8 | - A description of your work history (whether as a resume, LinkedIn profile, or prose). 9 | -------------------------------------------------------------------------------- /utilities/python/is_subsequence.py: -------------------------------------------------------------------------------- 1 | def is_subsequence(s, t): 2 | """ 3 | :type s: str 4 | :type t: str 5 | :rtype: bool 6 | """ 7 | if len(s) > len(t): 8 | return False 9 | matched_s = 0 10 | for char in t: 11 | if matched_s < len(s) and s[matched_s] == char: 12 | matched_s += 1 13 | return matched_s == len(s) 14 | -------------------------------------------------------------------------------- /algorithms/queue.md: -------------------------------------------------------------------------------- 1 | Queue 2 | == 3 | 4 | - Implement a Queue class from scratch with an existing bug, the bug is that it cannot take more than 5 elements. 5 | - Implement a Queue using two stacks. You may only use the standard `push()`, `pop()`, and `peek()` operations traditionally available to stacks. You do not need to implement the stack yourself (i.e. an array can be used to simulate a stack). 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | When contributing to this repository, if it is a non-trivial change, please first discuss the change you wish to make via creating an issue in this repository. 4 | 5 | As much as possible, try to follow the existing format of markdown and code. JavaScript code should adopt [Standard style](https://standardjs.com/). 6 | 7 | Please note we have a Code of Conduct, please follow it in all your interactions with the project. 8 | -------------------------------------------------------------------------------- /utilities/javascript/matrixTranspose.js: -------------------------------------------------------------------------------- 1 | function matrixTranspose(matrix) { 2 | return matrix[0].map((col, i) => matrix.map(row => row[i])); 3 | } 4 | 5 | const deepEqual = require('./deepEqual'); 6 | 7 | console.log(deepEqual(matrixTranspose([[1]]), [[1]])); 8 | console.log(deepEqual(matrixTranspose([[1, 2]]), [[1], [2]])); 9 | console.log(deepEqual(matrixTranspose([[1, 2], [1, 4]]), [[1, 1], [2, 4]])); 10 | console.log(deepEqual(matrixTranspose([[1, 2, 3], [4, 5, 6]]), [[1, 4], [2, 5], [3, 6]])); 11 | 12 | -------------------------------------------------------------------------------- /algorithms/oop.md: -------------------------------------------------------------------------------- 1 | Object-Oriented Programming 2 | == 3 | 4 | - How would you design a chess game? What classes and objects would you use? What methods would they have? 5 | - How would you design the data structures for a book keeping system for a library? 6 | - Explain how you would design a HTTP server? Give examples of classes, methods, and interfaces. What are the challenges here? 7 | - Discuss algorithms and data structures for a garbage collector? 8 | - How would you implement an HR system to keep track of employee salaries and benefits? 9 | -------------------------------------------------------------------------------- /algorithms/hash-table.md: -------------------------------------------------------------------------------- 1 | Hash Table 2 | == 3 | 4 | - Describe an implementation of a least-used cache, and big-O notation of it. 5 | - A question involving an API's integration with hash map where the buckets of hash map are made up of linked lists. 6 | - Implement data structure `Map` storing pairs of integers (key, value) and define following member functions in O(1) runtime: `void insert(key, value)`, `void delete(key)`, `int get(key)`, `int getRandomKey()`. 7 | - [Source](http://blog.gainlo.co/index.php/2016/08/14/uber-interview-question-map-implementation/). 8 | -------------------------------------------------------------------------------- /algorithms/stack.md: -------------------------------------------------------------------------------- 1 | Stack 2 | == 3 | 4 | - Implementation of an interpreter for a small language that does multiplication/addition/etc. 5 | - Design a `MinStack` data structure that supports a `min()` operation that returns the minimum value in the stack in O(1) time. 6 | - Write an algorithm to determine if all of the delimiters in an expression are matched and closed. 7 | - E.g. `{ac[bb]}`, `[dklf(df(kl))d]{}` and `{[[[]]]}` are matched. But `{3234[fd` and `{df][d}` are not. 8 | - [Source](http://blog.gainlo.co/index.php/2016/09/30/uber-interview-question-delimiter-matching/) 9 | - Sort a stack in ascending order using an additional stack. 10 | -------------------------------------------------------------------------------- /utilities/python/char_prime_map.py: -------------------------------------------------------------------------------- 1 | # For mapping a lowercase character to a prime number. 2 | # Useful for checking whether two strings are anagram or permutations of each other. 3 | primes = { 4 | 'a': 2, 'b': 3, 'c': 5, 'd': 7, 'e': 11, 'f': 13, 5 | 'g': 17, 'h': 19, 'i': 23, 'j': 29, 'k': 31, 'l': 37, 6 | 'm': 41, 'n': 43, 'o': 47, 'p': 53, 'q': 59, 'r': 61, 7 | 's': 67, 't': 71, 'u': 73, 'v': 79, 'w': 83, 'x': 89, 8 | 'y': 97, 'z': 101, ' ': 103, 9 | } 10 | 11 | import functools 12 | 13 | def mul(seq): 14 | return functools.reduce(lambda a, b: a * b, seq, 1) 15 | 16 | def prime_value_of_string(string): 17 | return mul([primes[c] for c in string]) 18 | 19 | print(prime_value_of_string('abcde')) 20 | -------------------------------------------------------------------------------- /utilities/javascript/isSubsequence.js: -------------------------------------------------------------------------------- 1 | function isSubsequence(s, t) { 2 | if (s.length > t.length) { 3 | return false; 4 | } 5 | let matchedLength = 0; 6 | for (let i = 0; i < t.length; i++) { 7 | if (matchedLength < s.length && s[matchedLength] === t[i]) { 8 | matchedLength += 1; 9 | } 10 | } 11 | return matchedLength === s.length; 12 | } 13 | 14 | console.log(isSubsequence('abc', 'abcde') === true); 15 | console.log(isSubsequence('abd', 'abcde') === true); 16 | console.log(isSubsequence('abf', 'abcde') === false); 17 | console.log(isSubsequence('abef', 'abcde') === false); 18 | console.log(isSubsequence('abcdef', 'abcde') === false); 19 | console.log(isSubsequence('a', 'abcde') === true); 20 | -------------------------------------------------------------------------------- /utilities/javascript/binToInt.js: -------------------------------------------------------------------------------- 1 | // Does not handle negative binary numbers. 2 | function binToInt(binary) { 3 | let res = 0; 4 | for (let i = 0; i < binary.length; i++) { 5 | res = res * 2 + (+binary[i]); 6 | } 7 | return res; 8 | } 9 | 10 | console.log(binToInt('0') === parseInt('0', 2) && parseInt('0', 2) === 0); 11 | console.log(binToInt('1') === parseInt('1', 2) && parseInt('1', 2) === 1); 12 | console.log(binToInt('10') === parseInt('10', 2) && parseInt('10', 2) === 2); 13 | console.log(binToInt('11') === parseInt('11', 2) && parseInt('11', 2) === 3); 14 | console.log(binToInt('101') === parseInt('101', 2) && parseInt('101', 2) === 5); 15 | console.log(binToInt('1100011') === parseInt('1100011', 2) && parseInt('1100011', 2) === 99); 16 | -------------------------------------------------------------------------------- /utilities/javascript/matrixClone.js: -------------------------------------------------------------------------------- 1 | function matrixClone(matrix, defaultValue) { 2 | return matrix.map(row => { 3 | return defaultValue === undefined ? row.slice(0) : Array(row.length).fill(defaultValue); 4 | }); 5 | } 6 | 7 | const deepEqual = require('./deepEqual'); 8 | 9 | // Test clone. 10 | const a = [[1, 2], [1, 4]]; 11 | console.log(deepEqual(matrixClone(a), [[1, 2], [1, 4]])); 12 | a[0][0] = 4; 13 | console.log(deepEqual(matrixClone(a), [[1, 2], [1, 4]]) === false); 14 | console.log(deepEqual(matrixClone([[1]]), [[1]])); 15 | 16 | // Test clone with default value. 17 | console.log(deepEqual(matrixClone([[1, 2], [1, 4]], 1), [[1, 1], [1, 1]])); 18 | console.log(deepEqual(matrixClone([[1, 2], [1, 4]], null), [[null, null], [null, null]])); 19 | -------------------------------------------------------------------------------- /algorithms/graph.md: -------------------------------------------------------------------------------- 1 | Graph 2 | == 3 | 4 | - Given a list of sorted words from an alien dictionary, find the order of the alphabet. 5 | - Alien Dictionary Topological Sort question. 6 | - Find if a given string matches any path in a labeled graph. A path may contain cycles. 7 | - Given a bipartite graph, separate the vertices into two sets. 8 | - You are a thief trying to sneak across a rectangular 100 x 100m field. There are alarms placed on the fields and they each have a circular sensing radius which will trigger if anyone steps into it. Each alarm has its own radius. Determine if you can get from one end of the field to the other end. 9 | - Given a graph and two nodes, determine if there exists a path between them. 10 | - Determine if a cycle exists in the graph. 11 | -------------------------------------------------------------------------------- /utilities/javascript/intToBin.js: -------------------------------------------------------------------------------- 1 | // Does not handle negative numbers. 2 | function intToBin(number) { 3 | if (number === 0) { 4 | return '0'; 5 | } 6 | let res = ''; 7 | while (number > 0) { 8 | res = String(number % 2) + res; 9 | number = parseInt(number / 2, 10); 10 | } 11 | return res; 12 | } 13 | 14 | console.log(intToBin(0) === 0..toString(2) && 0..toString(2) === '0'); 15 | console.log(intToBin(1) === 1..toString(2) && 1..toString(2) === '1'); 16 | console.log(intToBin(2) === 2..toString(2) && 2..toString(2) === '10'); 17 | console.log(intToBin(3) === 3..toString(2) && 3..toString(2) === '11'); 18 | console.log(intToBin(5) === 5..toString(2) && 5..toString(2) === '101'); 19 | console.log(intToBin(99) === 99..toString(2) && 99..toString(2) === '1100011'); 20 | -------------------------------------------------------------------------------- /utilities/javascript/intervalsMerge.js: -------------------------------------------------------------------------------- 1 | // Interval: [start, end]. 2 | // Merges two overlapping intervals into one. 3 | function intervalsMerge(a, b) { 4 | return [Math.min(a[0], b[0]), Math.max(a[1], b[1])]; 5 | } 6 | 7 | const deepEqual = require('./deepEqual'); 8 | 9 | console.log(deepEqual(intervalsMerge([1, 2], [1, 4]), [1, 4])); 10 | console.log(deepEqual(intervalsMerge([1, 2], [0, 4]), [0, 4])); 11 | console.log(deepEqual(intervalsMerge([1, 2], [0, 2]), [0, 2])); 12 | console.log(deepEqual(intervalsMerge([1, 2], [0, 1.5]), [0, 2])); 13 | console.log(deepEqual(intervalsMerge([1, 4], [1, 2]), [1, 4])); 14 | console.log(deepEqual(intervalsMerge([0, 4], [1, 2]), [0, 4])); 15 | console.log(deepEqual(intervalsMerge([0, 2], [1, 2]), [0, 2])); 16 | console.log(deepEqual(intervalsMerge([0, 1.5], [1, 2]), [0, 2])); 17 | -------------------------------------------------------------------------------- /utilities/python/graph_topo_sort.py: -------------------------------------------------------------------------------- 1 | def graph_topo_sort(num_nodes, edges): 2 | from collections import deque 3 | nodes, order, queue = {}, [], deque() 4 | for node_id in range(num_nodes): 5 | nodes[node_id] = { 'in': 0, 'out': set() } 6 | for node_id, pre_id in edges: 7 | nodes[node_id]['in'] += 1 8 | nodes[pre_id]['out'].add(node_id) 9 | for node_id in nodes.keys(): 10 | if nodes[node_id]['in'] == 0: 11 | queue.append(node_id) 12 | while len(queue): 13 | node_id = queue.pop() 14 | for outgoing_id in nodes[node_id]['out']: 15 | nodes[outgoing_id]['in'] -= 1 16 | if nodes[outgoing_id]['in'] == 0: 17 | queue.append(outgoing_id) 18 | order.append(node_id) 19 | return order if len(order) == num_nodes else [] 20 | 21 | print(graph_topo_sort(3, [[0, 1], [0, 2]])) 22 | -------------------------------------------------------------------------------- /utilities/javascript/intervalsIntersect.js: -------------------------------------------------------------------------------- 1 | // Interval: [start, end]. 2 | function intervalsIntersect(a, b) { 3 | return a[0] < b[1] && b[0] < a[1]; 4 | } 5 | 6 | console.log(intervalsIntersect([1, 2], [3, 4]) === false); 7 | console.log(intervalsIntersect([1, 2], [2, 4]) === false); 8 | console.log(intervalsIntersect([1, 2], [1, 4]) === true); 9 | console.log(intervalsIntersect([1, 2], [0, 4]) === true); 10 | console.log(intervalsIntersect([1, 2], [0, 2]) === true); 11 | console.log(intervalsIntersect([1, 2], [0, 1.5]) === true); 12 | console.log(intervalsIntersect([3, 4], [1, 2]) === false); 13 | console.log(intervalsIntersect([2, 4], [1, 2]) === false); 14 | console.log(intervalsIntersect([1, 4], [1, 2]) === true); 15 | console.log(intervalsIntersect([0, 4], [1, 2]) === true); 16 | console.log(intervalsIntersect([0, 2], [1, 2]) === true); 17 | console.log(intervalsIntersect([0, 1.5], [1, 2]) === true); 18 | -------------------------------------------------------------------------------- /utilities/javascript/binarySearch.js: -------------------------------------------------------------------------------- 1 | function binarySearch(arr, target) { 2 | let left = 0; 3 | let right = arr.length - 1; 4 | while (left <= right) { 5 | const mid = left + Math.floor((right - left) / 2); 6 | if (arr[mid] === target) { 7 | return mid; 8 | } 9 | if (arr[mid] < target) { 10 | left = mid + 1; 11 | } else { 12 | right = mid - 1; 13 | } 14 | } 15 | return -1; 16 | } 17 | 18 | console.log(binarySearch([1, 2, 3, 10], 1) === 0); 19 | console.log(binarySearch([1, 2, 3, 10], 2) === 1); 20 | console.log(binarySearch([1, 2, 3, 10], 3) === 2); 21 | console.log(binarySearch([1, 2, 3, 10], 10) === 3); 22 | console.log(binarySearch([1, 2, 3, 10], 9) === -1); 23 | console.log(binarySearch([1, 2, 3, 10], 4) === -1); 24 | console.log(binarySearch([1, 2, 3, 10], 0) === -1); 25 | console.log(binarySearch([1, 2, 3, 10], 11) === -1); 26 | console.log(binarySearch([5, 7, 8, 10], 3) === -1); 27 | -------------------------------------------------------------------------------- /utilities/javascript/matrixTraverse.js: -------------------------------------------------------------------------------- 1 | function traverse(matrix) { 2 | const DIRECTIONS = [[0, 1], [0, -1], [1, 0], [-1, 0]]; 3 | const rows = matrix.length, cols = matrix[0].length; 4 | const visited = matrix.map(row => Array(row.length).fill(false)); 5 | function dfs(i, j) { 6 | if (visited[i][j]) { 7 | return; 8 | } 9 | visited[i][j] = true; 10 | DIRECTIONS.forEach(dir => { 11 | const row = i + dir[0], col = j + dir[1]; 12 | // Boundary check. 13 | if (row < 0 || row >= rows || col < 0 || col >= cols) { 14 | return; 15 | } 16 | // Valid neighbor check. 17 | if (matrix[row][col] !== 1) { 18 | return; 19 | } 20 | dfs(row, col); 21 | }); 22 | } 23 | for (let i = 0; i < rows; i++) { 24 | for (let j = 0; j < cols; j++) { 25 | dfs(i, j); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /algorithms/permutation.md: -------------------------------------------------------------------------------- 1 | Permutation 2 | == 3 | 4 | - You are given a 7 digit phone number, and you should find all possible letter combinations based on the digit-to-letter mapping on numeric pad and return only the ones that have valid match against a given dictionary of words. 5 | - Give all possible letter combinations from a phone number. 6 | - Generate all subsets of a string. 7 | - Print all possible `N` pairs of balanced parentheses. 8 | - E.g. when `N` is `2`, the function should print `(())` and `()()`. 9 | - E.g. when `N` is `3`, we should get `((()))`, `(()())`, `(())()`, `()(())`, `()()()`. 10 | - [Source](http://blog.gainlo.co/index.php/2016/12/23/uber-interview-questions-permutations-parentheses/) 11 | - Given a list of arrays, return a list of arrays, where each array is a combination of one element in each given array. 12 | - E.g. If the input is `[[1, 2, 3], [4], [5, 6]]`, the output should be `[[1, 4, 5], [1, 4, 6], [2, 4, 5], [2, 4, 6], [3, 4, 5], [3, 4, 6]]`. 13 | -------------------------------------------------------------------------------- /algorithms/linked-list.md: -------------------------------------------------------------------------------- 1 | Linked List 2 | == 3 | 4 | - Given a linked list, in addition to the next pointer, each node has a child pointer that can point to a separate list. With the head node, flatten the list to a single-level linked list. 5 | - [Source](http://blog.gainlo.co/index.php/2016/06/12/flatten-a-linked-list/) 6 | - Reverse a singly linked list. Implement it recursively and iteratively. 7 | - Convert a binary tree to a doubly circular linked list. 8 | - Implement an LRU cache with O(1) runtime for all its operations. 9 | - Check distance between values in linked list. 10 | - A question involving an API's integration with hash map where the buckets of hash map are made up of linked lists. 11 | - Given a singly linked list (a list which can only be traversed in one direction), find the item that is located at 'k' items from the end. So if the list is a, b, c, d and k is 2 then the answer is 'c'. The solution should not search the list twice. 12 | - How can you tell if a Linked List is a Palindrome? 13 | -------------------------------------------------------------------------------- /utilities/javascript/graphTopoSort.js: -------------------------------------------------------------------------------- 1 | function graphTopoSort(numberNodes, edges) { 2 | const nodes = new Map(); 3 | const order = []; 4 | const queue = []; 5 | for (let i = 0; i < numberNodes; i++) { 6 | nodes.set(i, { in: 0, out: new Set() }); 7 | } 8 | 9 | edges.forEach(edge => { 10 | const [node_id, pre_id] = edge; 11 | nodes.get(node_id).in += 1; 12 | nodes.get(pre_id).out.add(node_id); 13 | }); 14 | 15 | for (let [node_id, value] of nodes.entries()) { 16 | if (value.in === 0) { 17 | queue.push(node_id); 18 | } 19 | } 20 | 21 | while (queue.length) { 22 | const node_id = queue.shift(); 23 | for (let outgoing_id of nodes.get(node_id).out) { 24 | nodes.get(outgoing_id).in -= 1; 25 | if (nodes.get(outgoing_id).in === 0) { 26 | queue.push(outgoing_id); 27 | } 28 | } 29 | order.push(node_id); 30 | } 31 | 32 | return order.length == numberNodes ? order : []; 33 | } 34 | 35 | console.log(graphTopoSort(3, [[0, 1], [0, 2]])); 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-Present Yangshun Tay 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /utilities/javascript/deepEqual.js: -------------------------------------------------------------------------------- 1 | function deepEqual(val1, val2) { 2 | if (typeof val1 !== typeof val2) { 3 | return false; 4 | } 5 | 6 | // Array comparison. 7 | if (Array.isArray(val1) && Array.isArray(val2)) { 8 | if (val1.length !== val2.length) { 9 | return false; 10 | } 11 | for (let i = 0; i < val1.length; i++) { 12 | if (!deepEqual(val1[i], val2[i])) { 13 | return false; 14 | } 15 | } 16 | return true; 17 | } 18 | 19 | // Object comparison. 20 | if (typeof val1 === 'object' && typeof val2 === 'object' && val1 !== null) { 21 | const keys1 = Object.keys(val1), keys2 = Object.keys(val2); 22 | if (keys1.length !== keys2.length) { 23 | return false; 24 | } 25 | for (let i = 0; i < keys1.length; i++) { 26 | if (!deepEqual(val1[keys1[i]], val2[keys2[i]])) { 27 | return false; 28 | } 29 | } 30 | return true; 31 | } 32 | 33 | // Primitive comparison. 34 | return val1 === val2; 35 | } 36 | 37 | module.exports = deepEqual; 38 | -------------------------------------------------------------------------------- /algorithms/sorting-searching.md: -------------------------------------------------------------------------------- 1 | Sorting and Searching 2 | == 3 | 4 | - Sorting search results on a page given a certain set of criteria. 5 | - Sort a list of numbers in which each number is at a distance `K` from its actual position. 6 | - Given an array of integers, sort the array so that all odd indexes are greater than the even indexes. 7 | - Given users with locations in a list and a logged-in user with locations, find their travel buddies (people who shared more than half of your locations). 8 | - Search for an element in a sorted and rotated array. 9 | - [Source](http://blog.gainlo.co/index.php/2017/01/12/rotated-array-binary-search/) 10 | - Sort a list where each element is no more than k positions away from its sorted position. 11 | - Search for an item in a sorted, but rotated, array. 12 | - Merge two sorted lists together. 13 | - Give 3 distinct algorithms to find the K largest values in a list of N items. 14 | - Find the minimum element in a sorted rotated array in faster than O(n) time. 15 | - Write a function that takes a number as input and outputs the biggest number with the same set of digits. 16 | - [Source](http://blog.gainlo.co/index.php/2017/01/20/arrange-given-numbers-to-form-the-biggest-number-possible/) 17 | -------------------------------------------------------------------------------- /utilities/python/union_find.py: -------------------------------------------------------------------------------- 1 | ## Union-Find data structure 2 | ## https://en.wikipedia.org/wiki/Disjoint-set_data_structure 3 | 4 | parents = [0, 1, 2, 3, 4, 5, 6] # parent[i] is the parent of i 5 | weights = [1, 1, 1, 1, 1, 1, 1] 6 | 7 | def find_root(parents, p): 8 | '''Average: O(log n)''' 9 | root = p 10 | while parents[root] != root: 11 | root = parents[root] 12 | # Flatten tree 13 | while parents[p] != p: 14 | parents[p], p = root, parents[p] 15 | return root 16 | 17 | def union(parents, p, q): 18 | '''Average: O(log n)''' 19 | p = find_root(parents, p) 20 | q = find_root(parents, q) 21 | # Link the smaller node to the larger node 22 | if weights[p] > weights[q]: 23 | parents[q] = p 24 | weights[p] += weights[q] 25 | else: 26 | parents[p] = q 27 | weights[q] += weights[p] 28 | 29 | 30 | 31 | # Start with all elements separate 32 | # -> [0], [1], [2], [3], [4], [5], [6] 33 | print(find_root(parents, 2) == 2) 34 | 35 | # Merge 1, 2, 3 and 4, 5, 6 36 | # -> [0], [1, 2, 3], [4, 5, 6] 37 | union(parents, 1, 2) 38 | union(parents, 2, 3) 39 | union(parents, 4, 5) 40 | union(parents, 4, 6) 41 | 42 | # Roots of 1, 2, 3 and 4, 5, 6 are the same 43 | print(find_root(parents, 0)) 44 | print(list(find_root(parents, i) for i in (1, 2, 3))) 45 | print(list(find_root(parents, i) for i in (4, 5, 6))) 46 | 47 | # Merge 2, 4 48 | # -> [0], [1, 2, 3, 4, 5, 6] 49 | union(parents, 2, 4) 50 | print(list(find_root(parents, i) for i in (1, 2, 3, 4, 5, 6))) 51 | -------------------------------------------------------------------------------- /algorithms/math.md: -------------------------------------------------------------------------------- 1 | Math 2 | == 3 | 4 | - Create a square root function. 5 | - Given a string such as "123" or "67", write a function to output the number represented by the string without using casting. 6 | - Make a program that can print out the text form of numbers from 1 - 1000 (ex. 20 is "twenty", 105 is "one hundred and five"). 7 | - Write a function that parses Roman numerals. 8 | - E.g. `XIV` returns `14`. 9 | - Write in words for a given digit. 10 | - E.g. `123` returns `one hundred and twenty three`. 11 | - Given a number `N`, find the largest number just smaller than `N` that can be formed using the same digits as `N`. 12 | - Compute the square root of `N` without using any existing functions. 13 | - Given numbers represented as binary strings, and return the string containing their sum. 14 | - E.g. `add('10010', '101')` returns `'10111'`. 15 | - Take in an integer and return its english word-format. 16 | - E.g. 1 -> "one", -10,203 -> "negative ten thousand two hundred and three". 17 | - Write a function that returns values randomly, according to their weight. Suppose we have 3 elements with their weights: A (1), B (1) and C (2). The function should return A with probability 25%, B with 25% and C with 50% based on the weights. 18 | - [Source](http://blog.gainlo.co/index.php/2016/11/11/uber-interview-question-weighted-random-numbers/) 19 | - Given a number, how can you get the next greater number with the same set of digits? 20 | - [Source](http://blog.gainlo.co/index.php/2017/01/20/arrange-given-numbers-to-form-the-biggest-number-possible/) 21 | -------------------------------------------------------------------------------- /utilities/javascript/mergeSort.js: -------------------------------------------------------------------------------- 1 | function mergeSort(arr) { 2 | if (arr.length < 2) { 3 | // Arrays of length 0 or 1 are sorted by definition. 4 | return arr; 5 | } 6 | 7 | const left = arr.slice(0, Math.floor(arr.length / 2)); 8 | const right = arr.slice(Math.floor(arr.length / 2), Math.floor(arr.length)); 9 | 10 | return merge(mergeSort(left), mergeSort(right)); 11 | } 12 | 13 | function merge(arr1, arr2) { 14 | const merged = []; 15 | let i = 0, j = 0; 16 | 17 | while (i < arr1.length && j < arr2.length) { 18 | if (arr1[i] <= arr2[j]) { 19 | merged.push(arr1[i]); 20 | i++; 21 | } else if (arr2[j] < arr1[i]) { 22 | merged.push(arr2[j]); 23 | j++; 24 | } 25 | } 26 | 27 | merged.push(...arr1.slice(i), ...arr2.slice(j)); 28 | return merged; 29 | } 30 | 31 | const deepEqual = require('./deepEqual'); 32 | 33 | console.log(deepEqual( 34 | mergeSort([]), 35 | [], 36 | )); 37 | console.log(deepEqual( 38 | mergeSort([1]), 39 | [1], 40 | )); 41 | console.log(deepEqual( 42 | mergeSort([2, 1]), 43 | [1, 2], 44 | )); 45 | console.log(deepEqual( 46 | mergeSort([7, 2, 4, 3, 1, 2]), 47 | [1, 2, 2, 3, 4, 7], 48 | )); 49 | console.log(deepEqual( 50 | mergeSort([1, 2, 3, 4, 5, 0]), 51 | [0, 1, 2, 3, 4, 5], 52 | )); 53 | console.log(deepEqual( 54 | mergeSort([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]), 55 | [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 56 | )); 57 | console.log(deepEqual( 58 | mergeSort([98322, 3242, 876, -234, 34, 12331]), 59 | [-234, 34, 876, 3242, 12331, 98322], 60 | )); 61 | -------------------------------------------------------------------------------- /algorithms/interval.md: -------------------------------------------------------------------------------- 1 | Interval 2 | == 3 | 4 | - Given a list of schedules, provide a list of times that are available for a meeting. 5 | ``` 6 | [ 7 | [[4,5], [6,10], [12,14]], 8 | [[4,5], [5,9], [13,16]], 9 | [[11,14]] 10 | ] 11 | 12 | Example Output: 13 | [[0,4], [11,12], [16,23]] 14 | ``` 15 | - You have a number of meetings (with their start and end times). You need to schedule them using the minimum number of rooms. Return the list of meetings in every room. 16 | - Interval ranges: 17 | - Given 2 interval ranges, create a function to tell me if these ranges intersect. Both start and end are inclusive: `[start, end]` 18 | - E.g. `[1, 4]` and `[5, 6]` => `false` 19 | - E.g. `[1, 4]` and `[3, 6]` => `true` 20 | - Given 2 interval ranges that intersect, now create a function to merge the 2 ranges into a single continuous range. 21 | - E.g. `[1, 4]` and `[3, 6]` => `[1, 6]` 22 | - Now create a function that takes a group of unsorted, unorganized intervals, merge any intervals that intersect and sort them. The result should be a group of sorted, non-intersecting intervals. 23 | - Now create a function to merge a new interval into a group of sorted, non-intersecting intervals. After the merge, all intervals should remain 24 | non-intersecting. 25 | - Given a list of meeting times, check if any of them overlap. The follow-up question is to return the minimum number of rooms required to accommodate all the meetings. 26 | - [Source](http://blog.gainlo.co/index.php/2016/07/12/meeting-room-scheduling-problem/) 27 | - If you have a list of intervals, how would you merge them? 28 | - E.g. `[1, 3], [8, 11], [2, 6]` => `[1, 6], [8-11]` 29 | -------------------------------------------------------------------------------- /algorithms/dynamic-programming.md: -------------------------------------------------------------------------------- 1 | Dynamic Programming 2 | == 3 | 4 | - Given a flight itinerary consisting of starting city, destination city, and ticket price (2D list) - find the optimal price flight path to get from start to destination. (A variation of Dynamic Programming Shortest Path) 5 | - Given some coin denominations and a target value `M`, return the coins combination with the minimum number of coins. 6 | - Time complexity: `O(MN)`, where N is the number of distinct type of coins. 7 | - Space complexity: `O(M)`. 8 | - Given a set of numbers in an array which represent a number of consecutive days of Airbnb reservation requested, as a host, pick the sequence which maximizes the number of days of occupancy, at the same time, leaving at least a 1-day gap in-between bookings for cleaning. 9 | - The problem reduces to finding the maximum sum of non-consecutive array elements. 10 | - E.g. 11 | ~~~ 12 | // [5, 1, 1, 5] => 10 13 | The above array would represent an example booking period as follows - 14 | // Dec 1 - 5 15 | // Dec 5 - 6 16 | // Dec 6 - 7 17 | // Dec 7 - 12 18 | 19 | The answer would be to pick Dec 1-5 (5 days) and then pick Dec 7-12 for a total of 10 days of 20 | occupancy, at the same time, leaving at least 1-day gap for cleaning between reservations. 21 | 22 | Similarly, 23 | // [3, 6, 4] => 7 24 | // [4, 10, 3, 1, 5] => 15 25 | ~~~ 26 | - Given a list of denominations (e.g., `[1, 2, 5]` means you have coins worth $1, $2, and $5) and a target number `k`, find all possible combinations, if any, of coins in the given denominations that add up to `k`. You can use coins of the same denomination more than once. 27 | -------------------------------------------------------------------------------- /utilities/python/graph_dfs.py: -------------------------------------------------------------------------------- 1 | def graph_dfs(matrix): 2 | rows, cols = len(matrix), len(matrix[0]) 3 | visited = set() 4 | directions = ((0, 1), (0, -1), (1, 0), (-1, 0)) 5 | def dfs(i, j): 6 | if (i, j) in visited: 7 | return 8 | visited.add((i, j)) 9 | # Traverse neighbors. 10 | for direction in directions: 11 | next_i, next_j = i + direction[0], j + direction[1] 12 | if 0 <= next_i < rows and 0 <= next_j < cols: # Check boundary. 13 | # Add any other checking here ^ 14 | dfs(next_i, next_j) 15 | 16 | for i in range(rows): 17 | for j in range(cols): 18 | dfs(i, j) 19 | 20 | # Follow up: 21 | # 1) Diagonal cells are considered neighbors 22 | # 2) View the matrix like Earth, right boundary is adjacent to the left boundary, top adjacent to left, etc. 23 | def graph_dfs_diagonals_and_boundary_wrap(matrix): 24 | rows, cols = len(matrix), len(matrix[0]) 25 | visited = set() 26 | # Change 1: Add 4 more diagonal directions. 27 | directions = ((0, 1), (0, -1), (1, 0), (-1, 0), (-1, -1), (1, 1), (1, -1), (-1, 1)) 28 | def dfs(i, j): 29 | if (i, j) in visited: 30 | return 31 | visited.add((i, j)) 32 | for direction in directions: 33 | # Change 2: No more boundary, use modulo to allow traversal that exceed boundaries to wrap around. 34 | next_i, next_j = (i + direction[0] + rows) % rows, (j + direction[1] + cols) % cols 35 | dfs(next_i, next_j) 36 | 37 | for i in range(rows): 38 | for j in range(cols): 39 | dfs(i, j) 40 | 41 | graph_dfs([ 42 | [1, 2, 3, 4], 43 | [5, 6, 7, 8], 44 | [9, 10, 11, 12], 45 | ]) 46 | -------------------------------------------------------------------------------- /utilities/python/tree_traversal.py: -------------------------------------------------------------------------------- 1 | # Various iterative ways of traversing a tree. 2 | def inorder_traversal(root): 3 | """ 4 | :type root: TreeNode 5 | :rtype: List[int] 6 | """ 7 | if not root: 8 | return [] 9 | result = [] 10 | stack = [root] 11 | while len(stack) > 0: 12 | curr_node = stack.pop() 13 | if curr_node.left: 14 | stack.append(curr_node) 15 | stack.append(curr_node.left) 16 | curr_node.left = None 17 | else: 18 | result.append(curr_node.val) 19 | if curr_node.right: 20 | stack.append(curr_node.right) 21 | return result 22 | 23 | def preorder_traversal(root): 24 | """ 25 | :type root: TreeNode 26 | :rtype: List[int] 27 | """ 28 | if not root: 29 | return [] 30 | result = [] 31 | stack = [root] 32 | while len(stack) > 0: 33 | curr_node = stack.pop() 34 | result.append(curr_node.val) 35 | if curr_node.right: 36 | stack.append(curr_node.right) 37 | if curr_node.left: 38 | stack.append(curr_node.left) 39 | return result 40 | 41 | def postorder_traversal(root): 42 | """ 43 | :type root: TreeNode 44 | :rtype: List[int] 45 | """ 46 | if not root: 47 | return [] 48 | result = [] 49 | stack = [root] 50 | while len(stack) > 0: 51 | curr_node = stack.pop() 52 | if curr_node.left: 53 | stack.append(curr_node) 54 | stack.append(curr_node.left) 55 | curr_node.left = None 56 | elif curr_node.right: 57 | stack.append(curr_node) 58 | stack.append(curr_node.right) 59 | curr_node.right = None 60 | else: 61 | result.append(curr_node.val) 62 | return result 63 | -------------------------------------------------------------------------------- /domain/software-engineering.md: -------------------------------------------------------------------------------- 1 | Software Engineering 2 | == 3 | 4 | ## What is the difference between an interface and abstract class? 5 | 6 | **Abstract Class** 7 | 8 | - For an abstract class, a method must be declared as abstract. An abstract method doesn't have an implementation. 9 | - The Abstract methods can be declared with Access modifiers like public, internal, protected, etc. When implementing these methods in a subclass, you must define them with the same (or a less restricted) visibility. 10 | - Abstract classes can contain variables and concrete methods. 11 | - A class can Inherit only one Abstract class. Hence multiple inheritance is not possible for an Abstract class. 12 | - Abstract is object-oriented. It offers the basic data an 'object' should have and/or functions it should be able to do. It is concerned with the object's basic characteristics: what it has and what it can do. Hence objects which inherit from the same abstract class share the basic characteristics (generalization). 13 | - Abstract class establishes "is a" relation with concrete classes. 14 | 15 | **Interface** 16 | 17 | - For an interface, all the methods are abstract by default. So one cannot declare variables or concrete methods in interfaces. 18 | - All methods declared in an interface must be public. 19 | - Interfaces cannot contain variables and concrete methods except constants. 20 | - A class can implement many interfaces. Hence multiple interface inheritance is possible. 21 | - Interface is functionality-oriented. It defines functionalities an object should have. Regardless what object it is, as long as it can do these functionalities, which are defined in the interface, it's fine. It ignores everything else. An object/class can contain several (groups of) functionalities; hence it is possible for a class to implement multiple interfaces. 22 | - Interface provides "has a" capability for classes. 23 | -------------------------------------------------------------------------------- /algorithms/topics.md: -------------------------------------------------------------------------------- 1 | Topics 2 | == 3 | 4 | ## Arrays 5 | 6 | ## Strings 7 | 8 | - Prefix trees (Tries) 9 | - Suffix trees 10 | - Suffix arrays 11 | - KMP 12 | - Rabin-Karp 13 | - Boyer-Moore 14 | 15 | ## Sorting 16 | 17 | - Bubble sort 18 | - Insertion sort 19 | - Merge sort 20 | - Quick sort 21 | - Selection sort 22 | - Bucket sort 23 | - Radix sort 24 | - Counting sort 25 | 26 | ## Linked Lists 27 | 28 | ## Stacks 29 | 30 | ## Queues 31 | 32 | ## Hash tables 33 | 34 | - Collision resolution algorithms 35 | 36 | ## Trees 37 | 38 | - BFS 39 | - DFS (inorder, postorder, preorder) 40 | - Height 41 | 42 | ## Binary Search Trees 43 | 44 | - Insert node 45 | - Delete a node 46 | - Find element in BST 47 | - Find min, max element in BST 48 | - Get successor element in tree 49 | - Check if a binary tree is a BST or not 50 | 51 | ## Heaps / Priority Queues 52 | 53 | - Insert 54 | - Bubble up 55 | - Extract max 56 | - Remove 57 | - Heapify 58 | - Heap sort 59 | 60 | ## Graphs 61 | 62 | - Various implementations 63 | - Adjacency matrix 64 | - Adjacency list 65 | - Adjacency map 66 | - Single-source shortest path 67 | - Dijkstra 68 | - Bellman-Ford 69 | - Topo sort 70 | - MST 71 | - Prim algorithm 72 | - Kruskal's algorithm 73 | - Union Find Data Structure 74 | - Count connected components in a graph 75 | - List strongly connected components in a graph 76 | - Check for bipartite graph 77 | 78 | ## Dynamic Programming 79 | 80 | - Count Change 81 | - 0-1 Knapsack 82 | 83 | ## System Design 84 | 85 | - http://www.hiredintech.com/system-design/ 86 | - https://www.quora.com/How-do-I-prepare-to-answer-design-questions-in-a-technical-interview?redirected_qid=1500023 87 | - http://blog.gainlo.co/index.php/2015/10/22/8-things-you-need-to-know-before-system-design-interviews/ 88 | - https://github.com/donnemartin/system-design-primer 89 | - https://github.com/jwasham/coding-interview-university/blob/master/extras/cheat%20sheets/system-design.pdf 90 | -------------------------------------------------------------------------------- /domain/async-loading/index.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 8 | 9 | 10 |