Tech interview handbook

GitHub - yangshun/tech-interview-handbook: 💯 Algorithms, front end and behavioral content for rocking your coding interview 🆕 Interview Cheatsheet! 🆕
Repo URL: https://github.com/yangshun/tech-interview-handbook
Edited by:
Cover image: Cover image
Share this using: email, Google+, Twitter, Facebook.
Exports: EPUB | MOBI

1 Algorithm Questions

This section dives deep into practical tips for specific topics of algorithms and data structures which appear frequently in coding questions. Many algorithm questions involve techniques that can be applied to questions of similar nature. The more techniques you have in your arsenal, the higher the chances of passing the interview. They may lead you to discover corner cases you might have missed out or even lead you towards the optimal approach!

For each topic, study links are recommended to help you master the topic. There is a list of recommended common questions to practice which in my opinion is highly valuable for mastering the core concepts for the topic.

If you are interested in how data structures are implemented, check out Lago, a Data Structures and Algorithms library for JavaScript. It is pretty much still WIP but I intend to make it into a library that is able to be used in production and also a reference resource for revising Data Structures and Algorithms.

1.1 Contents

1.2 General Tips

Clarify any assumptions you made subconsciously. Many questions are under-specified on purpose.

Always validate input first. Check for invalid/empty/negative/different type input. Never assume you are given the valid parameters. Alternatively, clarify with the interviewer whether you can assume valid input (usually yes), which can save you time from writing code that does input validation.

Are there any time/space complexity requirements/constraints?

Check for off-by-one errors.

In languages where there are no automatic type coercion, check that concatenation of values are of the same type: int/str/list.

After finishing your code, use a few example inputs to test your solution.

Is the algorithm meant to be run multiple times, for example in a web server? If yes, the input is likely to be preprocess-able to improve the efficiency in each call.

Use a mix of functional and imperative programming paradigms:

  • Write pure functions as much as possible.
  • Pure functions are easier to reason about and can help to reduce bugs in your implementation.
  • Avoid mutating the parameters passed into your function especially if they are passed by reference unless you are sure of what you are doing.
  • However, functional programming is usually expensive in terms of space complexity because of non-mutation and the repeated allocation of new objects. On the other hand, imperative code is faster because you operate on existing objects. Hence you will need to achieve a balance between accuracy vs efficiency, by using the right amount of functional and imperative code where appropriate.
  • Avoid relying on and mutating global variables. Global variables introduce state.
  • If you have to rely on global variables, make sure that you do not mutate it by accident.

Generally, to improve the speed of a program, we can either choose a more appropriate data structure/algorithm or use more memory. It’s a classic space/time tradeoff.

Data structures are your weapons. Choosing the right weapon for the right battle is the key to victory. Be very familiar about the strengths of each data structure and the time complexities for its various operations.

Data structures can be augmented to achieve efficient time complexities across different operations. For example, a hash map can be used together with a doubly-linked list to achieve O(1) time complexity for both the get and put operation in an LRU cache.

Hashmaps are probably the most commonly used data structure for algorithm questions. If you are stuck on a question, your last resort can be to enumerate through the possible data structures (thankfully there aren’t that many of them) and consider whether each of them can be applied to the problem. This has worked for me sometimes.

If you are cutting corners in your code, state that out loud to your interviewer and say what you would do in a non-interview setting (no time constraints). E.g., I would write a regex to parse this string rather than using split() which may not cover all cases.

1.3 Sequence

1.3.0.1 Notes

Arrays and strings are considered sequences (a string is a sequence of characters). There are tips relevant for dealing with both arrays and strings which will be covered here.

Are there duplicate values in the sequence, would it affect the answer?

Check for sequence out of bounds.

Be mindful about slicing or concatenating sequences in your code. Typically, slicing and concatenating sequences require O(n) time. Use start and end indices to demarcate a subarray/substring where possible.

Sometimes you can traverse the sequence from the right rather than from the left.

Master the sliding window technique that applies to many substring/subarray problems.

When you are given two sequences to process, it is common to have one index per sequence to traverse/compare the both of them. For example, we use the same approach to merge two sorted arrays.

1.3.0.2 Corner Cases

  • Empty sequence.
  • Sequence with 1 or 2 elements.
  • Sequence with repeated elements.

1.4 Array

1.4.0.1 Notes

Is the array sorted or partially sorted? If it is, some form of binary search should be possible. This also usually means that the interviewer is looking for a solution that is faster than O(n).

Can you sort the array? Sometimes sorting the array first may significantly simplify the problem. Make sure that the order of array elements do not need to be preserved before attempting a sort.

For questions where summation or multiplication of a subarray is involved, pre-computation using hashing or a prefix/suffix sum/product might be useful.

If you are given a sequence and the interviewer asks for O(1) space, it might be possible to use the array itself as a hash table. For example, if the array only has values from 1 to N, where N is the length of the array, negate the value at that index (minus one) to indicate presence of that number.

1.4.0.2 Practice Questions

1.5 Binary

1.5.0.2 Notes

Questions involving binary representations and bitwise operations are asked sometimes and you must be absolutely familiar with how to convert a number from decimal form into binary form (and vice versa) in your chosen programming language.

Some helpful utility snippets:

  • Test k<sup>th</sup> bit is set: num & (1 << k) != 0.
  • Set k<sup>th</sup> bit: num |= (1 << k).
  • Turn off k<sup>th</sup> bit: num &= ~(1 << k).
  • Toggle the k<sup>th</sup> bit: num ^= (1 << k).
  • To check if a number is a power of 2, num & num - 1 == 0.

1.5.0.3 Corner Cases

  • Check for overflow/underflow.
  • Negative numbers.

1.5.0.4 Practice Questions

1.6 Dynamic Programming

1.6.0.2 Notes

Dynamic Programming (DP) is usually used to solve optimization problems. The only way to get better at DP is to practice. It takes some amount of practice to be able to recognize that a problem can be solved by DP.

Sometimes you do not need to store the whole DP table in memory, the last two values or the last two rows of the matrix will suffice.

1.6.0.3 Practice Questions

1.7 Geometry

1.7.0.1 Notes

When comparing euclidean distance between two pairs of points, using dx<sup>2</sup> + dy<sup>2</sup> is sufficient. It is unnecessary to square root the value.

To find out if two circles overlap, check that the distance between the two centers of the circles is less than the sum of their radii.

1.8 Graph

1.8.0.2 Notes

Be familiar with the various graph representations, graph search algorithms and their time and space complexities.

You can be given a list of edges and tasked to build your own graph from the edges to perform a traversal on. The common graph representations are:

  • Adjacency matrix.
  • Adjacency list.
  • Hashmap of hashmaps.

A tree-like diagram could very well be a graph that allows for cycles and a naive recursive solution would not work. In that case you will have to handle cycles and keep a set of visited nodes when traversing.

1.8.0.3 Graph search algorithms:

  • Common - Breadth-first Search, Depth-first Search
  • Uncommon - Topological Sort, Dijkstra’s algorithm
  • Rare - Bellman-Ford algorithm, Floyd-Warshall algorithm, Prim’s algorithm, Kruskal’s algorithm

In coding interviews, graphs are commonly represented as 2-D matrices where cells are the nodes and each cell can traverse to its adjacent cells (up/down/left/right). Hence it is important that you be familiar with traversing a 2-D matrix. When recursively traversing the matrix, always ensure that your next position is within the boundary of the matrix. More tips for doing depth-first searches on a matrix can be found here. A simple template for doing depth-first searches on a matrix goes like this:

def traverse(matrix):
  rows, cols = len(matrix), len(matrix[0])
  visited = set()
  directions = ((0, 1), (0, -1), (1, 0), (-1, 0))
  def dfs(i, j):
    if (i, j) in visited:
      return
    visited.add((i, j))
    # Traverse neighbors
    for direction in directions:
      next_i, next_j = i + direction[0], j + direction[1]
      if 0 <= next_i < rows and 0 <= next_j < cols: # Check boundary
        # Add any other checking here ^
        dfs(next_i, next_j)

  for i in range(rows):
    for j in range(cols):
      dfs(i, j)

1.8.0.4 Corner Cases

  • Empty graph.
  • Graph with one or two nodes.
  • Disjoint graphs.
  • Graph with cycles.

1.8.0.5 Practice Questions

1.9 Interval

1.9.0.1 Notes

Interval questions are questions where you are given an array of two-element arrays (an interval) and the two values represent a start and an end value. Interval questions are considered part of the array family but they involve some common techniques hence they are extracted out to this special section of their own.

An example interval array: [[1, 2], [4, 7]].

Interval questions can be tricky to those who have not tried them before because of the sheer number of cases to consider when they overlap.

Do clarify with the interviewer whether [1, 2] and [2, 3] are considered overlapping intervals as it affects how you will write your equality checks.

A common routine for interval questions is to sort the array of intervals by each interval’s starting value.

Be familiar with writing code to check if two intervals overlap and merging two overlapping intervals:

def is_overlap(a, b):
  return a[0] < b[1] and b[0] < a[1]

def merge_overlapping_intervals(a, b):
  return [min(a[0], b[0]), max(a[1], b[1])]

1.9.0.2 Corner Cases

  • Single interval.
  • Non-overlapping intervals.
  • An interval totally consumed within another interval.
  • Duplicate intervals.

1.9.0.3 Practice Questions

1.10 Linked List

1.10.0.1 Notes

Like arrays, linked lists are used to represent sequential data. The benefit of linked lists is that insertion and deletion from anywhere in the list is O(1) whereas in arrays the following elements will have to be shifted.

Adding a dummy node at the head and/or tail might help to handle many edge cases where operations have to be performed at the head or the tail. The presence of dummy nodes essentially ensures that operations will never have be done on the head or the tail, thereby removing a lot of headache in writing conditional checks to dealing with null pointers. Be sure to remember to remove them at the end of the operation.

Sometimes linked lists problem can be solved without additional storage. Try to borrow ideas from reverse a linked list problem.

For deletion in linked lists, you can either modify the node values or change the node pointers. You might need to keep a reference to the previous element.

For partitioning linked lists, create two separate linked lists and join them back together.

Linked lists problems share similarity with array problems, think about how you would do it for an array and try to apply it to a linked list.

Two pointer approaches are also common for linked lists. For example:

  • Getting the k<sup>th</sup> from last node - Have two pointers, where one is k nodes ahead of the other. When the node ahead reaches the end, the other node is k nodes behind.
  • Detecting cycles - Have two pointers, where one pointer increments twice as much as the other, if the two pointers meet, means that there is a cycle.
  • Getting the middle node - Have two pointers, where one pointer increments twice as much as the other. When the faster node reaches the end of the list, the slower node will be at the middle.

Be familiar with the following routines because many linked list questions make use of one or more of these routines in the solution:

  • Counting the number of nodes in the linked list.
  • Reversing a linked list in-place.
  • Finding the middle node of the linked list using fast/slow pointers.
  • Merging two lists together.

1.10.0.2 Corner Cases

  • Single node.
  • Two nodes.
  • Linked list has cycle. Clarify with the interviewer whether there can be a cycle in the list. Usually the answer is no.

1.10.0.3 Practice Questions

1.11 Math

1.11.0.1 Notes

If code involves division or modulo, remember to check for division or modulo by 0 case.

When a question involves “a multiple of a number”, perhaps modulo might be useful.

Check for and handle overflow/underflow if you are using a typed language like Java and C++. At the very least, mention that overflow/underflow is possible and ask whether you need to handle it.

Consider negative numbers and floating point numbers. This may sound obvious, but under interview pressure, many obvious cases go unnoticed.

If the question asks to implement an operator such as power, squareroot or division and want it to be faster than O(n), binary search is usually the approach to go.

1.11.0.2 Some common formulas:

  • Sum of 1 to N = (n+1) * n/2
  • Sum of GP = 2<sup>0</sup> + 2<sup>1</sup> + 2<sup>2</sup> + 2<sup>3</sup> + … 2<sup>n</sup> = 2<sup>n+1</sup> - 1
  • Permutations of N = N! / (N-K)!
  • Combinations of N = N! / (K! * (N-K)!)

1.11.0.3 Practice Questions

1.12 Matrix

1.12.0.1 Notes

A matrix is a 2-dimensional array. Questions involving matrices are usually related to dynamic programming or graph traversal.

For questions involving traversal or dynamic programming, you almost always want to make a copy of the matrix with the same dimensions that is initialized to empty values to store the visited state or dynamic programming table. Be familiar with such a routine:

rows, cols = len(matrix), len(matrix[0])
copy = [[0 for _ in range(cols)] for _ in range(rows)]

Many grid-based games can be modeled as a matrix, such as Tic-Tac-Toe, Sudoku, Crossword, Connect 4, Battleship, etc. It is not uncommon to be asked to verify the winning condition of the game. For games like Tic-Tac-Toe, Connect 4 and Crosswords, where verification has to be done vertically and horizontally, one trick is to write code to verify the matrix for the horizontal cells, transpose the matrix and reuse the logic for horizontal verification to verify originally vertical cells (which are now horizontal).

Transposing a matrix in Python is simply:

transposed_matrix = zip(*matrix)

1.12.0.2 Corner Cases

  • Empty matrix. Check that none of the arrays are 0 length.
  • 1 x 1 matrix.
  • Matrix with only one row or column.

1.12.0.3 Practice Questions

1.13 Recursion

1.13.0.1 Notes

Recursion is useful for permutation, because it generates all combinations and tree-based questions. You should know how to generate all permutations of a sequence as well as how to handle duplicates.

Remember to always define a base case so that your recursion will end.

Recursion implicitly uses a stack. Hence all recursive approaches can be rewritten iteratively using a stack. Beware of cases where the recursion level goes too deep and causes a stack overflow (the default limit in Python is 1000). You may get bonus points for pointing this out to the interviewer. Recursion will never be O(1) space complexity because a stack is involved, unless there is tail-call optimization (TCO). Find out if your chosen language supports TCO.

1.13.0.2 Practice Questions

1.14 String

1.14.0.1 Notes

Please read the above tips on sequence. They apply to strings too.

Ask about input character set and case sensitivity. Usually the characters are limited to lowercase Latin characters, for example a to z.

When you need to compare strings where the order isn’t important (like anagram), you may consider using a HashMap as a counter. If your language has a built-in Counter class like Python, ask to use that instead.

If you need to keep a counter of characters, a common mistake is to say that the space complexity required for the counter is O(n). The space required for a counter is O(1) not O(n). This is because the upper bound is the range of characters, which is usually a fixed constant of 26. The input set is just lowercase Latin characters.

Common data structures for looking up strings efficiently are

Common string algorithms are

  • Rabin Karp for efficient searching of substring using a rolling hash.
  • KMP for efficient searching of substring.

1.14.0.2 Corner Cases

  • Strings with only one distinct character.

1.14.0.3 Non-repeating Characters

  • Use a 26-bit bitmask to indicate which lower case latin characters are inside the string.
mask = 0
for c in set(word):
  mask |= (1 << (ord(c) - ord('a')))

To determine if two strings have common characters, perform & on the two bitmasks. If the result is non-zero, mask_a & mask_b > 0, then the two strings have common characters.

1.14.1 Anagram

An anagram is word switch or word play. It is the result of re-arranging the letters of a word or phrase to produce a new word or phrase, while using all the original letters only once. In interviews, usually we are only bothered with words without spaces in them.

To determine if two strings are anagrams, there are a few plausible approaches:

  • Sorting both strings should produce the same resulting string. This takes O(nlgn) time and O(lgn) space.
  • If we map each character to a prime number and we multiply each mapped number together, anagrams should have the same multiple (prime factor decomposition). This takes O(n) time and O(1) space.
  • Frequency counting of characters will help to determine if two strings are anagrams. This also takes O(n) time and O(1) space.

1.14.2 Palindrome

A palindrome is a word, phrase, number, or other sequence of characters which reads the same backward as forward, such as madam or racecar.

Here are ways to determine if a string is a palindrome:

  • Reverse the string and it should be equal to itself.
  • Have two pointers at the start and end of the string. Move the pointers inward till they meet. At any point in time, the characters at both pointers should match.

The order of characters within the string matters, so HashMaps are usually not helpful.

When a question is about counting the number of palindromes, a common trick is to have two pointers that move outward, away from the middle. Note that palindromes can be even or odd length. For each middle pivot position, you need to check it twice: Once that includes the character and once without the character.

  • For substrings, you can terminate early once there is no match.
  • For subsequences, use dynamic programming as there are overlapping subproblems. Check out this question.

1.14.2.1 Practice Questions

1.15 Tree

1.15.0.2 Notes

A tree is an undirected and connected acyclic graph.

Recursion is a common approach for trees. When you notice that the subtree problem can be used to solve the entire problem, try using recursion.

When using recursion, always remember to check for the base case, usually where the node is null.

When you are asked to traverse a tree by level, use depth first search.

Sometimes it is possible that your recursive function needs to return two values.

If the question involves summation of nodes along the way, be sure to check whether nodes can be negative.

You should be very familiar with writing pre-order, in-order, and post-order traversal recursively. As an extension, challenge yourself by writing them iteratively. Sometimes interviewers ask candidates for the iterative approach, especially if the candidate finishes writing the recursive approach too quickly.

1.15.0.3 Corner Cases

  • Empty tree.
  • Single node.
  • Two nodes.
  • Very skewed tree (like a linked list).

1.15.1 Binary Tree

In-order traversal of a binary tree is insufficient to uniquely serialize a tree. Pre-order or post-order traversal is also required.

1.15.2 Binary Search Tree (BST)

In-order traversal of a BST will give you all elements in order.

Be very familiar with the properties of a BST and validating that a binary tree is a BST. This comes up more often than expected.

When a question involves a BST, the interviewer is usually looking for a solution which runs faster than O(n).

1.15.2.1 Practice Questions

1.16 Trie

1.16.0.2 Notes

Tries are special trees (prefix trees) that make searching and storing strings more efficient. Tries have many practical applications, such as conducting searches and providing autocomplete. It is helpful to know these common applications so that you can easily identify when a problem can be efficiently solved using a trie.

Sometimes preprocessing a dictionary of words (given in a list) into a trie, will improve the efficiency of searching for a word of length k, among n words. Searching becomes O(k) instead of O(n).

Be familiar with implementing, from scratch, a Trie class and its add, remove and search methods.

1.16.0.3 Practice Questions

1.17 Heap

1.17.0.2 Notes

If you see a top or lowest k being mentioned in the question, it is usually a signal that a heap can be used to solve the problem, such as in Top K Frequent Elements.

If you require the top k elements use a Min Heap of size k. Iterate through each element, pushing it into the heap. Whenever the heap size exceeds k, remove the minimum element, that will guarantee that you have the k largest elements.

1.17.0.3 Practice Questions

1.17.0.3.0.1 References

2 Arrays

  • In an array of arrays, e.g. given [[], [1, 2, 3], [4, 5], [], [], [6, 7], [8], [9, 10], [], []], print: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
  • Implement an iterator that supports hasNext(), next() and remove() methods.
  • Given a list of item prices, find all possible combinations of items that sum a particular value K.
  • Paginate an array with constraints, such as skipping certain items.
  • Implement a circular buffer using an array.
  • Given array of arrays, sort them in ascending order.
  • Given an array of integers, print out a histogram of using said array; include a base layer (all stars)
  • E.g. [5, 4, 0, 3, 4, 1]
*
**  *
** **
** **
** ***
******
  • Given an array and an index, find the product of the elements of the array except the element at that index.
  • Given a set of rectangles represented by a height and an interval along the y-axis, determine the size of its union.
  • Given 2 separate arrays, write a method to find the values that exist in both arrays and return them.
  • Given an array of integers find whether there is a sub-sequence that sums to 0 and return it.
  • E.g. [1, 2, -3, 1] => [1, 2, -3] or [2, -3, 1].
  • Given an input array and another array that describes a new index for each element, mutate the input array so that each element ends up in their new index. Discuss the runtime of the algorithm and how you can be sure there would not be any infinite loops.
  • Given an array of non-negative numbers, find continuous subarray with sum to S.
  • Source.
  • Given an array of numbers list out all triplets that sum to 0. Do so with a running time of less than O(n^3).
  • Source.
  • Given an array of numbers list out all quadruplets that sum to 0. Do so with a running time of less than O(n^4).
  • Given an array of integers, move all the zeroes to the end while preserving the order of the other elements. You have to do it in-place and are not allowed to use any extra storage.
  • Given an array of integers, find the subarray with the largest sum. Can you do it in linear time.
  • Maximum subarray sum problem.
  • You have an array with the heights of an island (at point 1, point 2 etc) and you want to know how much water would remain on this island (without flowing away).
  • Trapping rain water question.
  • Given an array containing only digits 0-9, add one to the number and return the array.
  • E.g. Given [1, 4, 2, 1] which represents 1421, return [1, 4, 2, 2] which represents 1422.
  • Find the second maximum value in an array.
  • Given an array, find the longest arithmetic progression.
  • Rotate an array by an offset of k.
  • Remove duplicates in an unsorted array where the duplicates are at a distance of k or less from each other.
  • Given an unsorted list of integers, return true if the list contains any duplicates within k indices of each element. Do it faster than O(n^2).
  • Given an unsorted list of integers, return true if the list contains any fuzzy duplicates within k indices of each element. A fuzzy duplicate is another integer within d of the original integer. Do it faster than O(n^2).
  • E.g. If d = 4, then 6 is a fuzzy duplicate of 3 but 8 is not.
  • Say you have an unordered list of numbers ranging from 1 to n, and one of the numbers is removed, how do you find that number? What if two numbers are removed?
  • Given an array of string, find the duplicated elements.
  • Source.
  • Given an array of integers, find a maximum sum of non-adjacent elements.
  • E.g. [1, 0, 3, 9, 2] should return 10 (1 + 9).
  • Source
  • Given an array of integers, modify the array by moving all the zeros to the end (right side). The order of other elements doesn’t matter.
  • E.g. [1, 2, 0, 3, 0, 1, 2], the program can output [1, 2, 3, 1, 2, 0, 0].
  • Source.
  • Given an array, return the length of the longest increasing contiguous subarray.
  • E.g., [1, 3, 2, 3, 4, 8, 7, 9], should return 4 because the longest increasing array is [2, 3, 4, 8].
  • Source.
  • Given an array of integers where every value appears twice except one, find the single, non-repeating value. Follow up: do so with O(1) space.
  • E.g., [2, 5, 3, 2, 1, 3, 4, 5, 1] returns 4, because it is the only value that appears in the array only once.

3 Dynamic Programming

  • 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)
  • Given some coin denominations and a target value M, return the coins combination with the minimum number of coins.
  • Time complexity: O(MN), where N is the number of distinct type of coins.
  • Space complexity: O(M).
  • 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.
  • The problem reduces to finding the maximum sum of non-consecutive array elements.
  • E.g.
    ~~~
    // [5, 1, 1, 5] => 10
    The above array would represent an example booking period as follows -
    // Dec 1 - 5
    // Dec 5 - 6
    // Dec 6 - 7
    // Dec 7 - 12

    The answer would be to pick Dec 1-5 (5 days) and then pick Dec 7-12 for a total of 10 days of
    occupancy, at the same time, leaving at least 1-day gap for cleaning between reservations.

    Similarly,
    // [3, 6, 4] => 7
    // [4, 10, 3, 1, 5] => 15
    ~~~
  • 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.

4 Geometry

  • You have a plane with lots of rectangles on it, find out how many of them intersect.
  • Which data structure would you use to query the k-nearest points of a set on a 2D plane?
  • Given many points, find k points that are closest to the origin.
  • How would you triangulate a polygon?

5 Graph

  • Given a list of sorted words from an alien dictionary, find the order of the alphabet.
  • Alien Dictionary Topological Sort question.
  • Find if a given string matches any path in a labeled graph. A path may contain cycles.
  • Given a bipartite graph, separate the vertices into two sets.
  • 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.
  • Given a graph and two nodes, determine if there exists a path between them.
  • Determine if a cycle exists in the graph.

6 Hash Table

  • Describe an implementation of a least-used cache, and big-O notation of it.
  • A question involving an API’s integration with hash map where the buckets of hash map are made up of linked lists.
  • 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().
  • Source.

7 Heap

  • Merge K sorted lists together into a single list.
  • Given a stream of integers, write an efficient function that returns the median value of the integers.

8 Interval

  • Given a list of schedules, provide a list of times that are available for a meeting.
    ```
    [
    [[4,5], [6,10], [12,14]],
    [[4,5], [5,9], [13,16]],
    [[11,14]]
    ]

Example Output:
[[0,4], [11,12], [16,23]]
``- 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. - Interval ranges: - Given 2 interval ranges, create a function to tell me if these ranges intersect. Both start and end are inclusive:[start, end]- E.g.[1, 4]and[5, 6]=>false- E.g.[1, 4]and[3, 6]=>true- Given 2 interval ranges that intersect, now create a function to merge the 2 ranges into a single continuous range. - E.g.[1, 4]and[3, 6]=>[1, 6]- 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. - Now create a function to merge a new interval into a group of sorted, non-intersecting intervals. After the merge, all intervals should remain non-intersecting. - 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. - [Source](http://blog.gainlo.co/index.php/2016/07/12/meeting-room-scheduling-problem/) - If you have a list of intervals, how would you merge them? - E.g.[1, 3], [8, 11], [2, 6]=>[1, 6], [8-11]`

9 Linked List

  • 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.
  • Source
  • Reverse a singly linked list. Implement it recursively and iteratively.
  • Convert a binary tree to a doubly circular linked list.
  • Implement an LRU cache with O(1) runtime for all its operations.
  • Check distance between values in linked list.
  • A question involving an API’s integration with hash map where the buckets of hash map are made up of linked lists.
  • 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.
  • How can you tell if a Linked List is a Palindrome?

10 Math

  • Create a square root function.
  • Given a string such as “123” or “67”, write a function to output the number represented by the string without using casting.
  • 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”).
  • Write a function that parses Roman numerals.
  • E.g. XIV returns 14.
  • Write in words for a given digit.
  • E.g. 123 returns one hundred and twenty three.
  • Given a number N, find the largest number just smaller than N that can be formed using the same digits as N.
  • Compute the square root of N without using any existing functions.
  • Given numbers represented as binary strings, and return the string containing their sum.
  • E.g. add('10010', '101') returns '10111'.
  • Take in an integer and return its english word-format.
  • E.g. 1 -> “one”, -10,203 -> “negative ten thousand two hundred and three”.
  • 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.
  • Source
  • Given a number, how can you get the next greater number with the same set of digits?
  • Source

11 Matrix

  • You’re given a 3 x 3 board of a tile puzzle, with 8 tiles numbered 1 to 8, and an empty spot. You can move any tile adjacent to the empty spot, to the empty spot, creating an empty spot where the tile originally was. The goal is to find a series of moves that will solve the board, i.e. get [[1, 2, 3], [4, 5, 6], [7, 8, - ]] where - is the empty tile.
  • Boggle implementation. Given a dictionary, and a matrix of letters, find all the words in the matrix that are in the dictionary. You can go across, down or diagonally.
  • The values of the matrix will represent numbers of carrots available to the rabbit in each square of the garden. If the garden does not have an exact center, the rabbit should start in the square closest to the center with the highest carrot count. On a given turn, the rabbit will eat the carrots available on the square that it is on, and then move up, down, left, or right, choosing the square that has the most carrots. If there are no carrots left on any of the adjacent squares, the rabbit will go to sleep. You may assume that the rabbit will never have to choose between two squares with the same number of carrots. Write a function which takes a garden matrix and returns the number of carrots the rabbit eats. You may assume the matrix is rectangular with at least 1 row and 1 column, and that it is populated with non-negative integers. For example,
  • Example: [[5, 7, 8, 6, 3], [0, 0, 7, 0, 4], [4, 6, 3, 4, 9], [3, 1, 0, 5, 8]] should return 27.
  • Print a matrix in a spiral fashion.
  • In the Game of life, calculate how to compute the next state of the board. Follow up was to do it if there were memory constraints (board represented by a 1 TB file).
  • Grid Illumination: Given an NxN grid with an array of lamp coordinates. Each lamp provides illumination to every square on their x axis, every square on their y axis, and every square that lies in their diagonal (think of a Queen in chess). Given an array of query coordinates, determine whether that point is illuminated or not. The catch is when checking a query all lamps adjacent to, or on, that query get turned off. The ranges for the variables/arrays were about: 10^3 < N < 10^9, 10^3 < lamps < 10^9, 10^3 < queries < 10^9.
  • You are given a matrix of integers. Modify the matrix such that if a row or column contains a 0, make the values in the entire row or column 0.
  • Given an N x N matrix filled randomly with different colors (no limit on what the colors are), find the total number of groups of each color - a group consists of adjacent cells of the same color touching each other.
  • You have a 4 x 4 board with characters. You need to write a function that finds if a certain word exists in the board. You can only jump to neighboring characters (including diagonally adjacent).
  • Count the number of islands in a binary matrix of 0’s and 1’s.
  • Check a 6 x 7 Connect 4 board for a winning condition.
  • Given a fully-filled Sudoku board, check whether fulfills the Sudoku condition.
  • Implement a function that checks if a player has won tic-tac-toe.
  • Given an N x N matrix of 1’s and 0’s, figure out if all of the 1’s are connected.

12 Object-Oriented Programming

  • How would you design a chess game? What classes and objects would you use? What methods would they have?

13 Permutation

  • 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.
  • Give all possible letter combinations from a phone number.
  • Generate all subsets of a string.
  • Print all possible N pairs of balanced parentheses.
  • E.g. when N is 2, the function should print (()) and ()().
  • E.g. when N is 3, we should get ((())), (()()), (())(), ()(()), ()()().
  • Source
  • Given a list of arrays, return a list of arrays, where each array is a combination of one element in each given array.
  • 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]].

14 Queue

  • Implement a Queue class from scratch with an existing bug, the bug is that it cannot take more than 5 elements.
  • 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).

15 Sorting and Searching

  • Sorting search results on a page given a certain set of criteria.
  • Sort a list of numbers in which each number is at a distance K from its actual position.
  • Given an array of integers, sort the array so that all odd indexes are greater than the even indexes.
  • 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).
  • Search for an element in a sorted and rotated array.
  • Source
  • Sort a list where each element is no more than k positions away from its sorted position.
  • Search for an item in a sorted, but rotated, array.
  • Merge two sorted lists together.
  • Give 3 distinct algorithms to find the K largest values in a list of N items.
  • Find the minimum element in a sorted rotated array in faster than O(n) time.
  • Write a function that takes a number as input and outputs the biggest number with the same set of digits.
  • Source

16 Stack

  • Implementation of an interpreter for a small language that does multiplication/addition/etc.
  • Design a MinStack data structure that supports a min() operation that returns the minimum value in the stack in O(1) time.
  • Write an algorithm to determine if all of the delimiters in an expression are matched and closed.
  • E.g. {ac[bb]}, [dklf(df(kl))d]{} and {[[[]]]} are matched. But {3234[fd and {df][d} are not.
  • Source
  • Sort a stack in ascending order using an additional stack.

17 String

  • Output list of strings representing a page of hostings given a list of CSV strings.
  • Given a list of words, find the word pairs that when concatenated form a palindrome.
  • Find the most efficient way to identify what character is out of place in a non-palindrome.
  • Implement a simple regex parser which, given a string and a pattern, returns a boolean indicating whether the input matches the pattern. By simple, we mean that the regex can only contain special character: * (star), . (dot), + (plus). The star means that there will be zero or more of previous character in that place in the pattern. The dot means any character for that position. The plus means one or more of previous character in that place in the pattern.
  • Find all words from a dictionary that are x edit distance away.
  • Given a string IP and number n, print all CIDR addresses that cover that range.
  • Write a function called eval, which takes a string and returns a boolean. This string is allowed 6 different characters: 0, 1, &, |, (, and ). eval should evaluate the string as a boolean expression, where 0 is false, 1 is true, & is an and, and | is an or.
  • E.g "(0 | (1 | 0)) & (1 & ((1 | 0) & 0))"
  • Given a pattern string like "abba" and an input string like "redbluebluered", return true if and only if there’s a one to one mapping of letters in the pattern to substrings of the input.
  • E.g. "abba" and "redbluebluered" should return true.
  • E.g. "aaaa" and "asdasdasdasd" should return true.
  • E.g. "aabb" and "xyzabcxzyabc" should return false.
  • If you received a file in chunks, calculate when you have the full file. Quite an open-ended question. Can assume chunks come with start and end, or size, etc.
  • Given a list of names (strings) and the width of a line, design an algorithm to display them using the minimum number of lines.
  • Design a spell-checking algorithm.
  • Count and say problem.
  • Longest substring with K unique characters.
  • Source
  • Given a set of random strings, write a function that returns a set that groups all the anagrams together.
  • Source
  • Given a string, find the longest substring without repeating characters. For example, for string 'abccdefgh', the longest substring is 'cdefgh'.
  • Source
  • Given a string, return the string with duplicate characters removed.
  • Write a function that receives a regular expression (allowed chars = from 'a' to 'z', '*', '.') and a string containing lower case english alphabet characters and return true or false whether the string matches the regex.
  • E.g. 'ab*a', 'abbbbba' => true.
  • E.g. 'ab*b.', 'aba' => true.
  • E.g. 'abc*', 'acccc' => false.
  • Given a rectangular grid with letters, search if some word is in the grid.
  • Given two strings representing integer numbers ('123' , '30') return a string representing the sum of the two numbers: '153'.
  • A professor wants to see if two students have cheated when writing a paper. Design a function hasCheated(String s1, String s2, int N) that evaluates to true if two strings have a common substring of length N.
  • Follow up: Assume you don’t have the possibility of using String.contains() and String.substring(). How would you implement this?
  • Print all permutations of a given string.
  • Parse a string containing numbers and '+', '-' and parentheses. Evaluate the expression. -2+(3-5) should return -4.
  • Output a substring with at most K unique characters.
  • E.g. 'aabc' and k = 2 => 'aab'.
  • Ensure that there are a minimum of N dashes between any two of the same characters of a string.
  • E.g. n = 2, string = 'ab-bcdecca' => 'ab--bcdec--ca'.
  • Find the longest palindrome in a string.
  • Give the count and the number following in the series.
  • E.g. 1122344, next: 21221324, next: 12112211121214.
  • Count and say problem.
  • Compress a string by grouping consecutive similar questions together:
  • E.g. 'aaabbbcc' =>‘a3b3c2’`.
  • You have a string consisting of open and closed parentheses, but parentheses may be imbalanced. Make the parentheses balanced and return the new string.
  • Given a set of strings, return the smallest subset that contains prefixes for every string.
  • E.g. ['foo', 'foog', 'food', 'asdf'] => ['foo', 'asdf'].
  • Write a function that would return all the possible words generated when using a phone (pre-smartphone era) numpad to type.
  • Given a dictionary and a word, find the minimum number of deletions needed on the word in order to make it a valid word.
  • Source
  • How to check if a string contains an anagram of another string?
  • Source
  • Find all k-lettered words from a string.
  • Given a string of open and close parentheses, find the minimum number of edits needed to balance a string of parentheses.
  • Run length encoding - Write a string compress function that returns 'R2G1B1' given 'RRGB'.
  • Write a function that finds all the different ways you can split up a word into a concatenation of two other words.

18 Topics

18.1 Arrays

18.2 Strings

  • Prefix trees (Tries)
  • Suffix trees
  • Suffix arrays
  • KMP
  • Rabin-Karp
  • Boyer-Moore

18.3 Sorting

  • Bubble sort
  • Insertion sort
  • Merge sort
  • Quick sort
  • Selection sort
  • Bucket sort
  • Radix sort
  • Counting sort

18.4 Linked Lists

18.5 Stacks

18.6 Queues

18.7 Hash tables

  • Collision resolution algorithms

18.8 Trees

  • BFS
  • DFS (inorder, postorder, preorder)
  • Height

18.9 Binary Search Trees

  • Insert node
  • Delete a node
  • Find element in BST
  • Find min, max element in BST
  • Get successor element in tree
  • Check if a binary tree is a BST or not

18.10 Heaps / Priority Queues

  • Insert
  • Bubble up
  • Extract max
  • Remove
  • Heapify
  • Heap sort

18.11 Graphs

  • Various implementations
  • Adjacency matrix
  • Adjacency list
  • Adjacency map
  • Single-source shortest path
  • Dijkstra
  • Bellman-Ford
  • Topo sort
  • MST
  • Prim algorithm
  • Kruskal’s algorithm
  • Union Find Data Structure
  • Count connected components in a graph
  • List strongly connected components in a graph
  • Check for bipartite graph

18.12 Dynamic Programming

  • Count Change
  • 0-1 Knapsack

18.13 System Design

19 Tree

  • Find the height of a tree.
  • Find the longest path from the root to leaf in a tree.
  • Find the deepest left leaf of a tree.
  • Print all paths of a binary tree.
  • Source
  • Second largest element of a BST.
  • Source
  • Given a binary tree and two nodes, how to find the common ancestor of the two nodes?
  • Source
  • Find the lowest common ancestor of two nodes in a binary search tree.
  • Print the nodes in an n-ary tree level by level, one printed line per level.
  • Given a directory of files and folders (and relevant functions), how would you parse through it to find equivalent files?
  • Write a basic file system and implement the commands ls, pwd, mkdir, create, rm, cd, cat, mv.
  • Compute the intersection of two binary search trees.
  • Given a binary tree, output all the node to leaf paths of it.
  • Given a string of characters without spaces, is there a way to break the string into valid words without leftover characters?
  • Print a binary tree level by level.
  • Determine if a binary tree is “complete” (i.e, if all leaf nodes were either at the maximum depth or max depth-1, and were ‘pressed’ along the left side of the tree).
  • Find the longest path in a binary tree. The path may start and end at any node.
  • Determine if a binary tree is a BST.
  • Given a binary tree, serialize it into a string. Then deserialize it.
  • Print a binary tree by column.
  • Given a node, find the next element in a BST.
  • Find the shortest subtree that consist of all the deepest nodes. The tree is not binary.
  • Print out the sum of each row in a binary tree.
  • Pretty print a JSON object.
  • Convert a binary tree to a doubly circular linked list.
  • Find the second largest number in a binary tree.
  • Given a tree, find the longest branch.
  • Convert a tree to a linked list.
  • Given two trees, write code to find out if tree A is a subtree of tree B.
  • Deepest node in a tree.
  • Source

20 Design Questions

20.1 Guides

20.2 Flow

20.2.0.1 A. Understand the problem and scope

  • Define the use cases, with interviewer’s help.
  • Suggest additional features.
  • Remove items that interviewer deems out of scope.
  • Assume high availability is required, add as a use case.

20.2.0.2 B. Think about constraints

  • Ask how many requests per month.
  • Ask how many requests per second (they may volunteer it or make you do the math).
  • Estimate reads vs. writes percentage.
  • Keep 80/20 rule in mind when estimating.
  • How much data written per second.
  • Total storage required over 5 years.
  • How much data reads per second.

20.2.0.3 C. Abstract design

  • Layers (service, data, caching).
  • Infrastructure: load balancing, messaging.
  • Rough overview of any key algorithm that drives the service.
  • Consider bottlenecks and determine solutions.

Source: https://github.com/jwasham/coding-interview-university#system-design-scalability-data-handling

20.3 Grading Rubrics

  • Problem Solving - How systematic is your approach to solving the problem step-by-step? Break down a problem into its core components.
  • Communication - How well do you explain your idea and communicate it with others?
  • Evaluation - How do you evaluate your system? Are you aware of the trade-offs made? How can you optimize it?
  • Estimation - How fast does your system need to be? How much space does it need? How much load will it experience?

20.4 Specific Topics

21 Collaborative Document Editor

21.1 Variants

  • Design Google docs.
  • Design a collaborative code editor like Coderpad/Codepile.
  • Design a collaborative markdown editor.

21.2 Requirements Gathering

  • What is the intended platform?
  • Web
  • What features are required?
  • Creating a document
  • Editing a document
  • Sharing a document
  • Bonus features
  • Document revisions and reverting
  • Searching
  • Commenting
  • Chatting
  • Executing code (in the case of code editor)
  • What is in a document?
  • Text
  • Images
  • Which metrics should we optimize for?
  • Loading time
  • Synchronization
  • Throughput

21.3 Core Components

  • Front end
  • WebSockets/long polling for real-time communication between front end and back end.
  • Back end services behind a reverse proxy.
  • Reverse proxy will proxy the requests to the right server.
  • Split into a few services for different purposes.
  • The benefit of this is that each service can use different languages that best suits its purpose.
  • API servers for non-collaborative features and endpoints.
  • Ruby/Rails/Django for the server that deals with CRUD operations on data models where performance is not that crucial.
  • WebSocket servers for handling document edits and publishing updates to listeners.
  • Possibly Node/Golang for WebSocket server which will need high performance as updates are frequent.
  • Task queue to persist document updates to the database.
  • ELB in front of back end servers.
  • MySQL database.
  • S3 and CDN for images.

21.4 Data Modeling

  • What kind of database to use?
  • Data is quite structured. Would go with SQL.
  • Design the necessary tables, its columns and its relations.
  • users
    • id
    • name
  • document
    • id
    • owner_id
  • permissions
    • id
    • name
  • document_permissions
    • id
    • document_id
    • user_id

21.5 Collaborative Editing - Client

  • Upon loading of the page and document, the client should connect to the WebSocket server over the WebSocket protocol ws://.
  • Upon connection, perform a time sync with the server, possibly via Network Time Protocol (NTP).
  • The most straightforward way is to send the whole updated document content to the back end, and all users currently viewing the document will receive the updated document. However, there are a few problems with this approach:
  • Race condition. If two users editing the document at the same time, the last one to edit will overwrite the changes by the previous user. One workaround is to lock the document when a user is currently editing it, but that will not make it real-time collaborative.
  • A large payload (the whole document) is being sent to servers and published to users on each change, and the user is likely to already have most of the content. A lot of redundant data being sent.
  • A feasible approach would be to use operational transforms and send just the action deltas to the back end. The back end publishes the action deltas to the listeners. What is considered an action delta?
  • (a) Changing a character/word, (b) inserting a character/word/image, (c) deleting a character/word.
  • With this approach, the payload will contain only small amount of data, such as (a) type of change, (b) character/word, (c) position in document: line/column, (d) timestamp. Why is the timestamp needed? Read on to find out.
  • Updates can also be throttled and batched, to avoid flooding the web server with requests. For example, if a user inserts a

21.6 Back End

The back end is split into a few portions: WebSocket server for receiving and broadcasting document updates, CRUD server for reading and writing non-document-related data, and a task queue for persistence of the document.

21.7 WebSocket Server

  • Languages and frameworks that support async requests and non-blocking I/O will be suitable for the collaborative editor server. Node and Golang comes to my mind.
  • However, the WebSocket server is not stateless, so is it not that straightforward to scale horizontally. One approach would be for a Load Balancer to use Redis to maintain a map of the client to the WebSocket server instance IP, such that subsequent requests from the same client will be routed to the same server.
  • Each document corresponds to a room (more of namespace). Users can subscribe to the events happening within a room.
  • When a action delta is being received, blast it out to the listeners within the room and add it to the task queue.

21.8 CRUD Server

  • Provides APIs for reading and writing non-document-related data, such as users, permissions.

21.9 Task Queue + Worker Service

  • Worker service retrieves messages from the task queue and writes the updated documents to the database in an async fashion.
  • Batch the actions together and perform one larger write that consists of multiple actions. For example, instead of persisting to the database once per addition of a word, combine these additions and write them into the database at once.
  • Publish the save completion event to the WebSocket server to be published to the listeners, informing that the latest version of the document is being saved.
  • Benefit of using a task queue is that as the amount of tasks in the queue goes up, we can scale up the number of worker services to clear the backlog of work faster.

21.10 Document Persistence

TODO

21.10.0.0.0.1 References

22 News Feed

22.1 Variants

  • Design Facebook news feed.
  • Design Twitter news feed.
  • Design Quora feed.
  • Design Instagram feed.

22.2 Requirements Gathering

  • What is the intended platform?
  • Mobile (mobile web or native)? Web? Desktop?
  • What features are required?
  • CRUD posts.
  • Commenting on posts.
  • Sharing posts.
  • Trending posts?
  • Tag people?
  • Hashtags?
  • What is in a news feed post?
  • Author.
  • Content.
  • Media.
  • Tags?
  • Hashtags?
  • Comments/Replies.
  • Operations:
    • CRUD
    • Commenting/replying to a post.
  • What is in a news feed?
  • Sequence of posts.
  • Query pattern: query for a user’s ranked news feed.
  • Operations:
    • Append - Fetch more posts.
    • Delete - I don’t want to see this.
  • Which metrics should we optimize for?
  • User retention.
  • Ads revenue.
  • Fast loading time.
  • Bandwidth.
  • Server costs.

22.3 Core Components

TODO

22.4 Data modeling

  • What kind of database to use?
  • Data is quite structured. Would go with SQL.
  • Design the necessary tables, its columns and its relations.
  • users
  • posts
  • likes
  • follows
  • comments

There are two basic objects: user and feed. For user object, we can store userID, name, registration date and so on so forth. And for feed object, there are feedId, feedType, content, metadata etc., which should support images and videos as well.

If we are using a relational database, we also need to model two relations: user-feed relation and friend relation. The former is pretty straightforward. We can create a user-feed table that stores userID and corresponding feedID. For a single user, it can contain multiple entries if he has published many feeds.

For friend relation, adjacency list is one of the most common approaches. If we see all the users as nodes in a giant graph, edges that connect nodes denote friend relation. We can use a friend table that contains two userIDs in each entry to model the edge (friend relation). By doing this, most operations are quite convenient like fetch all friends of a user, check if two people are friends.

The system will first get all userIDs of friends from friend table. Then it fetches all feedIDs for each friend from user-feed table. Finally, feed content is fetched based on feedID from feed table. You can see that we need to perform 3 joins, which can affect performance.

A common optimization is to store feed content together with feedID in user-feed table so that we don’t need to join the feed table any more. This approach is called denormalization, which means by adding redundant data, we can optimize the read performance (reducing the number of joins).

The disadvantages are obvious:

  • Data redundancy. We are storing redundant data, which occupies storage space (classic time-space trade-off).
  • Data consistency. Whenever we update a feed, we need to update both feed table and user-feed table. Otherwise, there is data inconsistency. This increases the complexity of the system.
  • Remember that there’s no one approach always better than the other (normalization vs denormalization). It’s a matter of whether you want to optimize for read or write.

22.5 Feed Display

  • The most straightforward way is to fetch posts from all the people you follow and render them sorted by time.
  • There can be many posts to fetch. How many posts should you fetch?
  • What are the pagination approaches and the pros and cons of each approach?
  • Offset by page size
  • Offset by time
  • What data should the post contain when you initially fetch them?
  • Lazy loading approach for loading associated data: media, comments, people who liked the post.
  • Media
  • If the post contains media such as images and videos, how should they be handled? Should they be loaded on the spot?
  • A better way would be to fetch images only when they are about to enter the viewport.
  • Videos should not autoplay. Only fetch the thumbnail for the video, and only play the video when user clicks play.
  • If the content is being refetched, the media should be cached and not fetched over the wire again. This is especially important on mobile connections where data can be expensive.
  • Comments
  • Should you fetch all the comments for a post? For posts by celebrities, they can contain a few hundred or thousand comments.
  • Maybe fetch the top few comments and display them under the post, and the user is given the choice to “show all comments”.
  • How does the user request for new content?
  • Infinite scrolling.
  • User has to tap next page.

22.6 Feed Ranking

  • First select features/signals that are relevant and then figure out how to combine them to calculate a final score.
  • How do you show the relevant posts that the user is interested in?
  • Chronological - While a chronological approach works, it may not be the most engaging approach. For example, if a person posts 30 times within the last hour, his followers will have their news feed clogged up with his posts. Maybe set a cap on the number of time a person’s posts can appear within the feed.
  • Popularity - How many likes and comments does the post have? Does the user usually like posts by that person?
  • How do you determine which are the more important posts? A user might be more interested in a few-hour old post from a good friend than a very recent post from an acquaintance.
  • A common strategy is to calculate a post score based on various features and rank posts by its score.
  • Prior to 2013, Facebook was using the EdgeRank algorithm to determine what articles should be displayed in a user’s News Feed.
  • Edge Rank basically is using three signals: affinity score, edge weight and time decay.
  • Affinity score (u) - For each news feed, affinity score evaluates how close you are with this user. For instance, you are more likely to care about feed from your close friends instead of someone you just met once.
  • Edge weight (e) - Edge weight basically reflects importance of each edge. For instance, comments are worth more than likes.
  • Time decay (d) - The older the story, the less likely users find it interesting.
  • Affinity score
  • Various factors can be used to reflect how close two people are. First of all, explicit interactions like comment, like, tag, share, click etc. are strong signals we should use. Apparently, each type of interaction should have different weight. For instance, comments should be worth much more than likes.
  • Secondly, we should also track the time factor. Perhaps you used to interact with a friend quite a lot, but less frequent recently. In this case, we should lower the affinity score. So for each interaction, we should also put the time decay factor.
  • A good ranking system can improve some core metrics - user retention, ads revenue, etc.

22.7 Feed Publishing

TODO. Refer to http://blog.gainlo.co/index.php/2016/04/05/design-news-feed-system-part-2/.

22.8 Additional Features

22.8.0.1 Tagging feature

  • Have a tags table that stores the relation between a post and the people tagged in it.

22.8.0.2 Sharing feature

  • Add a column to posts table called original_post_id.
  • What should happen when the original post is deleted?
  • The shared posts have to be deleted too.

22.8.0.3 Notifications feature

  • When should notifications happen?
  • Can the user subscribe to only certain types of notifications?
  • What constitutes trending? What signals would you look at? What weight would you give to each signal?
  • Most frequent hashtags over the last N hours.
  • Hottest search queries.
  • Fetch the recent most popular feeds and extract some common words or phrases.

22.8.0.5 Search feature

  • How would you index the data?

22.9 Scalability

  • Master-slave replication.
  • Write to master database and read from replica databases/in-memory data store.
  • Post contents are being read more than they are updated. It is acceptable to have a slight lag between a user updating a post and followers seeing the updated content. Tweets are not even editable.
  • Data for real-time queries should be in memory, disk is for writes only.
  • Pre-computation offline.
  • Tracking number of likes and comments.
  • Expensive to do a COUNT on the likes and comments for a post.
  • Use Redis/Memcached for keeping track of how many likes/comments a post has. Increment when there’s new activity, decrement when someone unlikes/deletes the comment.
  • Load balancer in front of your API servers.
  • Partitioning the data.
22.9.0.0.0.1 References

23 Search Engine

23.0.0.0.0.1 References

24 Databases

24.1 General

25 Networking

  • 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).
  • Describe what happens when you enter a url in the web browser.
  • Define UDP/TCP and give an example of both.

26 Security

26.1 Encryption

26.1.0.1 Symmetrical Encryption

  • Symmetrical encryption is a type of encryption where one key can be used to encrypt messages and also decrypt the same message.
  • Symmetrical encryption is usually much less computationally expensive as compared to asymmetric encryption.
  • Often called “shared secret” encryption, or “secret key” encryption.
  • To use a symmetric encryption scheme, the sender and receiver must securely share a key in advance. This sharing can be done via asymmetric encryption.

26.1.0.2 Asymmetric Encryption

  • A pair of keys are required: a private key and a public key. Public keys can be shared with anyone while private keys should be kept secret and known only to the owner.
  • A private key can be used to decrypt a message encrypted by a public key. A successful decryption verifies that the holder possesses the private key.
  • Also known as public key cryptography.

26.2 Public Key Infrastructure

A public key infrastructure (PKI) is a system for the creation, storage, and distribution of digital certificates which are used to verify that a particular public key belongs to a certain entity. The PKI creates digital certificates which map public keys to entities, securely stores these certificates in a central repository and revokes them if needed.

26.2.0.0.0.1 References

26.3 SSH

An SSH session consists of two stages, Negotiating Encryption and User Authentication.

26.3.0.1 Negotiating Encryption

The goal of this stage is for the client and server to agree upon and establish encryption to protect future communication, by generating an identical session key. One possible algorithm to generate the key is the Diffie–Hellman key exchange scheme. Each party generates a public/private key pair and exchanges the public key. After obtaining an authentic copy of each other’s public keys, each party can compute a shared secret offline.

The basis of this procedure for classic Diffie-Hellman is:

  1. Both parties agree on a large prime number, which will serve as a seed value.
  2. Both parties agree on an encryption generator (typically AES), which will be used to manipulate the values in a predefined way.
  3. Independently, each party comes up with another prime number which is kept secret from the other party. This number is used as the private key for this interaction (different than the private SSH key used for authentication).
  4. The generated private key, the encryption generator, and the shared prime number are used to generate a public key that is derived from the private key, but which can be shared with the other party.
  5. Both participants then exchange their generated public keys.
  6. The receiving entity uses their own private key, the other party’s public key, and the original shared prime number to compute a shared secret key.
  7. Although this is independently computed by each party, using opposite private and public keys, it will result in the same shared secret key.
  8. The shared secret is then used to encrypt all communication that follows.

The purpose of the shared secret key is to wrap all further communication in an encrypted tunnel that cannot be deciphered by outsiders.

26.3.0.2 User Authentication

The goal of this stage is to authenticate the user and discover whether access to the server should be granted. There are two approaches for authenticating, either by using passwords, or SSH key pairs.

For password authentication, the server simply prompts the client for the password of the account they are attempting to login with. The password is sent through the negotiated encryption, so it is secure from outside parties.

Authentication using SSH key pairs begins after the symmetric encryption has been established as described in the last section. The procedure happens like this:

  1. The client begins by sending an ID for the key pair it would like to authenticate with to the server.
  2. The server check’s the authorized_keys file of the account that the client is attempting to log into for the key ID.
  3. If a public key with matching ID is found in the file, the server generates a random number and uses the public key to encrypt the number.
  4. The server sends the client this encrypted message.
  5. If the client actually has the associated private key, it will be able to decrypt the message using that key, revealing the original number.
  6. The client combines the decrypted number with the shared session key that is being used to encrypt the communication, and calculates the MD5 hash of this value.
  7. The client then sends this MD5 hash back to the server as an answer to the encrypted number message.
  8. The server uses the same shared session key and the original number that it sent to the client to calculate the MD5 value on its own. It compares its own calculation to the one that the client sent back. If these two values match, it proves that the client was in possession of the private key and the client is authenticated.
26.3.0.2.0.1 References

27 Software Engineering

27.1 What is the difference between an interface and abstract class?

Abstract Class

  • For an abstract class, a method must be declared as abstract. An abstract method doesn’t have an implementation.
  • 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.
  • Abstract classes can contain variables and concrete methods.
  • A class can Inherit only one Abstract class. Hence multiple inheritance is not possible for an Abstract class.
  • 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).
  • Abstract class establishes “is a” relation with concrete classes.

Interface

  • For an interface, all the methods are abstract by default. So one cannot declare variables or concrete methods in interfaces.
  • All methods declared in an interface must be public.
  • Interfaces cannot contain variables and concrete methods except constants.
  • A class can implement many interfaces. Hence multiple interface inheritance is possible.
  • 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.
  • Interface provides “has a” capability for classes.

28 Accessibility

28.1 Glossary

  • Accessibility -
  • WAI-ARIA - Web Accessibility Initiative - Accessible Rich Internet Applications. Commonly shortened to ARIA.

28.2 What is Accessibility?

Making sure that the content and the websites we create are usable to people with impairments or disabilities.

28.3 WebAIM Checklist

The following is a checklist that contains recommendations for implementing HTML-related principles and techniques for those seeking WCAG 2.0 conformance (it is NOT the Web Content Accessibility Guidelines (WCAG) 2.0).

  • Perceivable - Web content is made available to the senses - sight, hearing, and/or touch.
  • Text Alternatives: Provide text alternatives for any non-text content.
  • Time-based Media: Provide alternatives for time-based media.
  • Adaptable: Create content that can be presented in different ways (for example simpler layout) without losing information or structure.
  • Distinguishable: Make it easier for users to see and hear content including separating foreground from background.
  • Operable - Interface forms, controls, and navigation are operable.
  • Keyboard Accessible: Make all functionality available from a keyboard.
  • Enough Time: Provide users enough time to read and use content.
  • Seizures: Do not design content in a way that is known to cause seizures.
  • Navigable: Provide ways to help users navigate, find content, and determine where they are.
  • Understandable - Content and interface are understandable.
  • Readable: Make text content readable and understandable.
  • Predictable: Make Web pages appear and operate in predictable ways.
  • Input Assistance: Help users avoid and correct mistakes.
  • Robust - Content can be used reliably by a wide variety of user agents, including assistive technologies.
  • Compatible: Maximize compatibility with current and future user agents, including assistive technologies.

Source: http://webaim.org/standards/wcag/checklist

28.4 Focus

  • Making sure your application has a sensible tab order is important.
  • HTML forms and inputs are focusable and handle keyboard events by default.
  • Focus tab order relies on the DOM order in the HTML.
  • Be careful when using CSS when changing the order of elements on the screen, it can cause the order to be unintuitive and messy.
  • tabindex attribute:
  • -1: Not in the natural tab order, but programatically focusable using JavaScript with focus() method. Useful for off-screen content which later appears on screen. Children elements are NOT pulled out of the tab order.
  • 0: In the natural tab order and can be programatically focused.
  • 1 (bigger than 1): In the natural tab order but jumped in front of the tab order regardless of where it is in the DOM. It can be considered an anti-pattern.
  • Add focus behavior to interactive controls, like buttons, tabs, dropdowns, stuff that users will interactive with.
  • Use skip links to allow users to skip directly to the main content without having to tab through all the navigation.
  • document.activeElement is useful in tracking the current element that has focus on.

28.5 Semantics

  • Using proper labeling not only helps accessibility but it makes the element easier to target for all users!
  • Use <label> with for attributes for form elements.
  • Use alt attribute for <img> elements. Alt text must describe the image.
  • TODO
  • MacOS comes built-in with VoiceOver. Press <kbd>CMD</kbd> + <kbd>F5</kbd> to activate.
  • Activate Web Rotor with <kbd>Ctrl</kbd> + <kbd>Option</kbd> + <kbd>U</kbd>. Web Rotor displays landmarks, headings, links and more on the page and allows you to jump to them directly.
  • Heading weight should be decided by its importance on the page and not how big it should look, as the heading tag chosen affects the order the headings are listed on screen readers.
  • Use HTML5 semantic tags like <main>, <nav>, <header>, <aside>, <article>, <section>, <footer> to indicate landmarks on the page.

28.7 ARIA

  • Express semantics that HTML can’t express on its own.
  • Accessibility tree = DOM + ARIA.
  • ARIA attributes
  • Allow us to modify the accessibility tree before they are exposed to assistive technologies.
  • DO NOT modify the element apperance.
  • DO NOT modify element behaviour.
  • DO NOT add focusability.
  • DO NOT add keyboard event handling.
  • E.g. for custom checkboxes, adding ARIA attributes is not sufficient, you will need to write your own JavaScript to emulate the native behaviour to synchronize the ARIA attributes and values with the actual visual state, such as toggling using clicks and hitting spacebar. It’s probably not worth it to reinvent the wheel by writing your own custom widgets that already exist in HTML5.
  • ARIA can add semantics to elements that have no native semantics, such as <div>. ARIA can also modify element semantics.
  • ARIA allows developers to create accessible widgets that do not exist in HTML5, such as a tree widget.
  • aria-role attributes tell assistive technologies that the element should follow that role’s accessibility patterns. There are well-defined roles in the HTML spec. Do not define them on your own.
  • tabindex="0" is usually added to it elements that have role added so that it can be focused.
  • Assistive labelling
  • aria-label is useful for labelling buttons where the content is empty or contains only icons.
  • aria-labelledby is similar to <label> elements, and can be used on any elements.

    /* Normal label example */
    <input type="radio" id="coffee-label">
    <label for="coffee-label">Coffee</label>
    
    /* aria-labelledby example */
    <div role="radio" aria-labelledby="coffee-label"></div>
    <span id="coffee-label">Coffee</span>
  • ARIA Relationships
  • ARIA relationship attributes create semantic relationships between elements on the page. The aria-labelledby attribute in the previous example indicates that the <div> is labelled by the element with that id.
  • Possible relationship attributes include aria-activedescendent, aria-describedby, aria-labelledby, aria-owns, aria-posinset and aria-setsize.
  • With ARIA, you can expose only relevant parts of the page to accessibility tree. Elements can be hidden via:
  • Setting visibility: <button style="visibility: hidden">.
  • Setting display: <button style="display: none">.
  • HTML5 hidden attribute: <span hidden>. This makes the element hidden to everyone.
  • aria-hidden attribute: <div aria-hidden="true">. This makes the element hidden to screenreaders too. Note that aria-hidden attribute requires an explicit value of true or false.
  • Technique for screenreader-only text:
    .screenreader { position: absolute; left: -1000px; width: 1px; height: 1px; overflow: hidden; }
  • aria-live attribute can be used to grab the assistive technology’s attention to cause it to announce updates to the user. Practically, include aria-live attributes in the initial page load. The different aria-live values include:
  • off (default) - Updates will not be presented unless the region is currently focused.
  • polite - Assistive technologies should announce updates at the next graceful opportunity, such as at the end of speaking the current sentence on when the user pauses typing. Such as receiving new chat messages.
  • assertive - Highest priority and assistive technologies should notify the user immediately. Examples include server status error alerts.
  • aria-atomic attribute indicates whether the entire region should be presented as a whole when communicating updates. Such as a date widget comprising of multiple <input> fields for day/month/year. When the user changes a field, the full contents of the widget will be read out. It takes in a true or false value.
  • aria-relevant attribute indicates what types of changes should be presented to the user.
  • additions - Element nodes are added to the DOM within the live region.
  • removals - Text or element nodes within the live region are removed from the DOM.
  • text - Text is added to any DOM descendant nodes of the live region.
  • all - Equivalent to the combination of all values, additions removals text.
  • additions text (default) - Equivalent to the combination of values, additions text.
  • aria-busy attribute indicates the assistive technologies should ignore changes to the element, such as when things are loading, for example after a temporary connectivity loss. It takes in true or false. It takes in a true or false value.

28.8 Style

28.8.0.1 Introduction

  • Ensure elements are styled to support the existing accessibility work, such as adding styles for :focus and the various ARIA states.
  • Flexible user interface that can handle being zoomed or scaled up, for users who have trouble reading smaller text.
  • Color choices and the importance of contrast, making sure we are not conveying information just with color alone.

28.8.0.2 Focus

  • As much as possible, leave the default focus in place. Do not remove the :focus styling just because it does not fit into your design or looks odd! - A good technique is to use a similar styling as :hover for :focus.
  • Some CSS resets would kill off the focus styling, so it’s important to be aware of them and get them back.

28.8.0.3 Styling with ARIA

Consider using ARIA attributes in your CSS selectors to reduce some noise in your CSS. For custom toggle buttons, instead of doing this,

<div class="toggle pressed" role="button" tabindex="0" aria-pressed="true"></div> /* On */
<div class="toggle" role="button" tabindex="0" aria-pressed="false"></div> /* Off */

.toggle.pressed {
  ...
}

you can do this instead:

<div class="toggle" role="button" tabindex="0" aria-pressed="true"></div> /* On */
<div class="toggle" role="button" tabindex="0" aria-pressed="false"></div> /* Off */

.toggle[aria-pressed="true"] {
  ...
}

which removes the need for toggling the press class on the element.

28.8.0.4 Responsive Design

Responsive design is also beneficial for accessibility when zooming the page transforms the page into the mobile layout instead.

Use a meta viewport tag:

<meta name="viewport" content="width=device-width initial-scale="1">

user-scalable=no is an anti-pattern for accessibility.

Use relative units like %, em and rem. The differences are as follows:

  • % - Relative to the containing block.
  • em - Relative to the font-size of the parent.
  • rem - Relative to the font-size of the root, which is the <html> element.

Interactive interface elements such as buttons should be large enough, have enough spacing around itself so that they do not overlap with other interactive elements.

28.8.0.5 Color and Contrast

Contrast ratio is the ratio of luminance between the foreground color (such as text) and the background color. For text and images, aim for a large contrast ratio of 7:1 and for larger text (over 18 point or 14 point bold), aim for at least 4.5:1.

Chrome Devtools has an Accessibility audit feature that can flag the contrast issues on your page.

Color should not be used as the sole method of conveying content or distinguishing visual elements, such as only changing the border-color of <input> fields that have error to red. These changes will not be obvious/visible to people with color blindness. An error message below the field will be helpful.

Some users might be using a High Contrast mode which allows a user to invert the background and foreground colors to read text better. Ensure that your page also looks fine on High Contrast mode which you can simulate with a Chrome High Contrast extension.

28.8.0.6 Assessing Impact of Accessibility Issues

Fixing accessibility issues is like fixing bugs; it is best looked at through the lens of impact. How can you have the most impact on users with the least amount of effort?

  • How frequent is this piece of UI used? Is it part of a critical flow?
  • How badly does this accessibility issue affect your users?
  • How expensive is it going to cost to fix?
28.8.0.6.0.1 References

29 Browser

29.1 Glossary

  • BOM - The Browser Object Model (BOM) is a browser-specific convention referring to all the objects exposed by the web browser. The window object is one of them.
  • CSSOM - CSS Object Model.
  • DOM - The Document Object Model (DOM) is a cross-platform and language-independent convention for representing and interacting with objects in HTML, XHTML, and XML documents.
  • Reflow - When the changes affect document contents or structure, or element position, a reflow (or relayout) happens.
  • Repaint - When changing element styles which don’t affect the element’s position on a page (such as background-color, border-color, visibility), the browser just repaints the element again with the new styles applied (that means a “repaint” or “restyle” is happening).
  • Composite - TODO

29.2 Rendering

High level flow of how browsers render a webpage:

  1. DOM
  • The DOM (Document Object Model) is formed from the HTML that is received from a server.
  • Characters -> Tokens -> Nodes -> DOM.
  • DOM construction is incremental.
  • CSS and JS are requested as the respective <link> and <script> tags are encountered.
  1. CSSOM
  • Styles are loaded and parsed, forming the CSSOM (CSS Object Model).
  • Characters -> Tokens -> Nodes -> CSSOM.
  • CSSOM construction is not incremental.
  • Browser blocks page rendering until it receives and processes all the CSS.
  • CSS is render blocking.
  1. Render Tree
  • On top of DOM and CSSOM, a render tree is created, which is a set of objects to be rendered. Render tree reflects the DOM structure except for invisible elements (like the <head> tag or elements that have display: none; set). Each text string is represented in the rendering tree as a separate renderer. Each of the rendering objects contains its corresponding DOM object (or a text block) plus the calculated styles. In other words, the render tree describes the visual representation of a DOM.
  1. Layout
  • For each render tree element, its coordinates are calculated, which is called “layout”. Browsers use a flow method which only required one pass to layout all the elements (tables require more than one pass).
  1. Painting
  • Finally, this gets actually displayed in a browser window, a process called “painting”.
29.2.0.0.0.1 References

29.3 Repaint

When changing element styles which don’t affect the element’s position on a page (such as background-color, border-color, visibility), the browser just repaints the element again with the new styles applied (that means a “repaint” or “restyle” is happening).

29.4 Reflow

When the changes affect document contents or structure, or element position, a reflow (or relayout) happens. These changes are usually triggered by:

  • DOM manipulation (element addition, deletion, altering, or changing element order)
  • Contents changes, including text changes in form fields
  • Calculation or altering of CSS properties
  • Adding or removing style sheets
  • Changing the “class” attribute
  • Browser window manipulation (resizing, scrolling); Pseudo-class activation (:hover)

29.4.0.1 References

30 Caching

WIP.

30.1 Glossary

  • Cookies

30.1.0.1 References

31 CSS

CSS (Cascading Style Sheets) are rules to describe how your HTML elements look. Writing good CSS is hard. It usually takes many years of experience and frustration of shooting yourself in the foot before one is able to write maintainable and scalable CSS. CSS, having a global namespace, is fundamentally designed for web documents, and not really for web apps that favor a components architecture. Hence, experienced front end developers have designed methodologies to guide people on how to write organized CSS for complex projects, such as using SMACSS, BEM, SUIT CSS, etc.

However, the encapsulation of styles that these methodologies bring about are artificially enforced by conventions and guidelines. They break the moment developers do not follow them.

As you might have realized by now, the front end ecosystem is saturated with tools, and unsurprisingly, tools have been invented to partially solve some of the problems with writing CSS at scale. “At scale” means that many developers are working on the same large project and touching the same stylesheets. There is no community-agreed approach on writing CSS in JS at the moment, and we are hoping that one day a winner would emerge, just like Redux did, among all the Flux implementations. For now, I would recommend CSS Modules. CSS modules is an improvement over existing CSS that aims to fix the problem of global namespace in CSS; it enables you to write styles that are local by default and encapsulated to your component. This feature is achieved via tooling. With CSS modules, large teams can write modular and reusable CSS without fear of conflict or overriding other parts of the app. However, at the end of the day, CSS modules are still being compiled into normal globally-namespaced CSS that browsers recognize, and it is still important to learn and understand how raw CSS works.

If you are a total beginner to CSS, Codecademy’s HTML & CSS course will be a good introduction to you. Next, read up on the Sass preprocessor, an extension of the CSS language which adds syntactic improvements and encourages style reusability. Study the CSS methodologies mentioned above, and lastly, CSS modules.

31.1 Glossary

  • Box Model - The CSS box model describes the rectangular boxes that are generated for elements in the document tree and laid out according to the visual formatting model. Each box has a content area (e.g. text, an image, etc.) and optional surrounding padding, border, and margin areas.
  • Specificity - Specificity is how browsers decide which CSS property values are the most relevant to an element and, will therefore be applied. It is a weight that is applied to a given CSS declaration, determined by the number of each selector type in the matching selector.
  • When multiple declarations have equal specificity, the last declaration found in the CSS is applied to the element. It only applies when the same element is targeted by multiple declarations. As per CSS rules, directly targeted elements will always take precedence over rules which an element inherits from its ancestor.
  • Typically used in type selectors/pseduo elements (h1, div, :before), class/attribute selectors (.btn, [type="radio"]), pseudo-classes (:hover) and ID selectors (#someElement).
  • Inline styles added to an element always overwrite any styles in external stylesheets, and thus can be thought of as having the highest specificity.
  • When an important rule (!important) is used on a style declaration, this declaration overrides any other declarations. Try to avoid using !important, as it breaks the natural cascading in the stylesheets. Always look for a way to use specificity before even considering !important, and only use !important on page-specific CSS that overrides foreign CSS (from external libraries, like Bootstrap).
  • Positioning - The position CSS property determines how an element will be positioned in a document. The top, right, bottom, and left properties would later determine the final location of said positioned element.
  • Initial value: static
  • Values that are frequently used: relative, absolute, fixed, sticky
  • Floats - The float CSS property determines where an element should be placed - along the left or right side of its container. This allows text and inline elements to wrap around it. Also note, the element would be removed from the normal flow of the web page, though still remaining a part of the flow (in contrast to position: absolute). For an element to be float, it’s value must not be none.
  • Initial value: none
  • Values that are frequently used: left, right, inline-start, inline-end.
  • Additional Notes: Usually, there would be cases that you may want to move an item below any floated elements. E.g, you may want some elements like your paragraphs to remain adjacent to floats, but force headings and footers to be on their own line. See clear attribute for more examples

31.2 Writing CSS without Side Effects

TODO

31.2.0.0.0.1 References

32 Design Questions

32.1 Autocomplete Widget

Talk me through a full stack implementation of an autocomplete widget. A user can type text into it, and get back results from a server.

  • How would you design a frontend to support the following features:
  • Fetch data from a backend API
  • Render results as a tree (items can have parents/children - it’s not just a flat list)
  • Support for checkbox, radio button, icon, and regular list items - items come in many forms
  • What does the component’s API look like?
  • What does the backend API look like?
  • What perf considerations are there for complete-as-you-type behavior? Are there any edge cases (for example, if the user types fast and the network is slow)?
  • How would you design the network stack and backend in support of fast performance: how do your client/server communicate? How is your data stored on the backend? How do these approaches scale to lots of data and lots of clients?
32.1.0.0.0.1 References

33 DOM

33.1 Glossary

  • Event Delegation - Event delegation refers to the process of using event propagation (bubbling) to handle events at a higher level in the DOM than the element on which the event originated. It allows us to attach a single event listener for elements that exist now or in the future.

33.2 Node API

Here’s a list of the essential and more common DOM Node APIs. It is important to know how to traverse and manipulate the DOM in vanilla JS without jQuery.

Properties

  • Node.childNodes - Returns a live NodeList containing all the children of this node. NodeList being live means that if the children of the Node change, the NodeList object is automatically updated.
  • Node.firstChild
  • Node.lastChild
  • Node.nextSibling - Returns a Node representing the next node in the tree, or null if there isn’t such a node.
  • Node.nodeName - DIV, SPAN, etc. Note that it is in upper case in HTML documents, and has the same value as Element.tagName.
  • Node.parentNode - Returns a Node that is the parent of this node. If there is no such node, like if this node is the top of the tree or if it doesn’t participate in a tree, this property returns null.
  • Node.parentElement - Returns an Element that is the parent of this node. If the node has no parent, or if that parent is not an Element, this property returns null.
  • Node.previousSibling - Returns a Node representing the previous node in the tree, or null if there isn’t such a node.
  • Node.textContent - Returns / Sets the textual content of an element and all its descendants.

Methods

  • Node.appendChild(node) - Adds the specified node argument as the last child to the current node. If the argument referenced an existing node on the DOM tree, the node will be detached from its current position and attached at the new position.
  • Node.cloneNode(node) - Clone a Node, and optionally, all of its contents. By default, it clones the content of the node.
  • Node.contains(node) - Returns a Boolean value indicating whether a node is a descendant of a given node or not.
  • Node.hasChildNodes() - Returns a Boolean indicating if the element has any child nodes, or not.
  • Node.insertBefore(newNode, referenceNode) - Inserts the first Node before the reference node as a child of the current node. If referenceNode is null, the newNode is inserted at the end of the list of child nodes.
  • Node.removeChild(node) - Removes a child node from the current element, which must be a child of the current node.
  • Node.replaceChild(newChild, oldChild) - Replaces one child node of the specified node with another node.

33.3 Element API

Here’s a list of the essential and more common DOM Element APIs. It is important to know how to traverse and manipulate the DOM in vanilla JS without jQuery.

Properties

  • Element.attributes - Returns a NamedNodeMap object containing the assigned attributes of the corresponding HTML element.
  • Element.classList - Returns a DOMTokenList containing the list of class attributes.
  • DOMTokenList.add(String [, String]) - Add specified class values. If these classes already exist in attribute of the element, they are ignored.
  • DOMTokenList.remove(String [, String]) - Remove specified class values.
  • DOMTokenList.toggle(String [, force]) - Toggle specified class value. If second argument is present and evaluates to true, add the class value, else remove it.
  • DOMTokenList.contains(String) - Checks if specified class value exists in class attribute of the element.
  • Element.className - A DOMString representing the class of the element.
  • Element.id
  • Element.innerHTML - Returns a DOMString representing the markup of the element’s content or parse the content string and assigns the resulting nodes as children of the element.
  • Element.tagName - DIV, SPAN, etc. Note that it is in upper case in HTML documents, and has the same value as Node.nodeName.

Methods

  • EventTarget.addEventListener(type, callback, options) - Registers an event handler to a specific event type on the element. Read up more on the options here.
  • EventTarget.removeEventListener(type, callback, options) - Removes an event listener from the element. Read up more on the options here.
  • Element.closest(selectors) - Returns the closest ancestor of the current element (or the current element itself) which matches the selectors given in parameter. If there isn’t such an ancestor, it returns null.
  • Element.getElementsByClassName(classNames)- Returns a live HTMLCollection that contains all descendants of the current element that possess the list of classes given in the parameter.
  • Element.getElementsByTagName(tagName) - Returns a live HTMLCollection containing all descendant elements, of a particular tag name, from the current element.
  • Element.querySelector(selectors) - Returns the first Node which matches the specified selector string relative to the element.
  • Element.querySelectorAll(selectors) - Returns a NodeList of nodes which match the specified selector string relative to the element.
  • ChildNode.remove() - Removes the element from the children list of its parent. TODO: Check whether it’s Element or ChildNode.
  • Element.setAttribute(attrName, value) - Sets the value of a named attribute of the current node.
  • Element.removeAttribute(attrName) - Removes the named attribute from the current node.

33.4 Document API

  • document.getElementById(id) - An Element object, or null if an element with the specified ID is not in the document.

33.5 Window/Document Events

  • document.addEventListener('DOMContentLoaded', callback)
  • The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. Similar to jQuery.ready() but different because $.ready will execute immediately if the DOMContentLoaded event has already fired.
  • This corresponds to document.readyState === 'interactive'.
  • window.onload = function() {}
  • window’s load event is only fired after the DOM and all assets have loaded.
  • This corresponds to document.readyState === 'complete'.

33.6 Questions

What’s the difference between Node.children and Node.childNodes?

Node.children returns a live HTMLCollection of the child elements of Node. Node.childNodes returns a NodeList, an ordered collection of DOM nodes that are children of the current Element. childNodes includes all child nodes, including non-element nodes like text and comment nodes. To get a collection of only elements, use Node.children instead.

What’s the difference between NodeList and HTMLCollection?

A NodeList can contain any node type, but an HTMLCollection is supposed to only contain Element nodes. HTMLCollection is always live and is a superset of NodeList. NodeList need not be live.

How do you convert an HTMLCollection or NodeList into an array?

const nodelist = document.querySelectorAll('div');
// Array.from
const divArray = Array.from(nodelist);
// Array.prototype.slice
const divArray2 = Array.prototype.slice.call(nodelist); // or .apply
// ES2015 Spread
const divArray3 = [...nodeList];

33.7 References

34 HTML

HTML (Hypertext Markup Language) is the structure that all websites are built on. Anyone working on websites and webapps should have a basic understanding of HTML at the very least. A helpful analogy for understanding the importance of HTML is the house scenario. When building a new house, the process can be split into a few key areas; structure (HTML), aesthetics (CSS) and furniture (Content). The HTML is your basic page structure, without the structure, you cannot change how it looks using CSS, or what content is on the page.

34.1 Glossary

  • Doctype

34.2 Deprecated Tags

There are a number of tags from past versions of HTML that have become deprecated over time. This means that while they are no longer considered valid elements, most browsers should still be able to read and render them.

34.3 Script Loading

  • <script> - HTML parsing is blocked, the script is fetched and executed immediately, HTML parsing resumes after the script is executed.
  • <script async> - The script will be fetched in parallel to HTML parsing and executed as soon as it is available (potentially before HTML parsing completes). Use async when the script is independent of any other scripts on the page, for example analytics.
  • <script defer> - The script will be fetched in parallel to HTML parsing and executed when the page has finished parsing. If there are multiple of them, each deferred script is executed in the order they were encoun­tered in the document.

35 Front-end Job Interview Questions

Unlike typical software engineer job interviews, front-end job interviews have less emphasis on algorithms and have more questions on intricate knowledge and expertise about the domain — HTML, CSS, JavaScript, just to name a few areas.

While there are some existing resources to help front end developers in preparing for interviews, they aren’t as abundant as materials for a software engineer interview. Among the existing resources, probably the most helpful question bank would be Front-end Job Interview Questions. Unfortunately, I couldn’t find many complete and satisfactory answers for these questions online, hence here is my attempt at answering them. Being an open source repository, the project can live on with the support of the community as the state of web evolves.

35.1 Table of Contents

  1. HTML Questions
  2. CSS Questions
  3. JS Questions

35.2 HTML Questions

Answers to Front-end Job Interview Questions - HTML Questions. Pull requests for suggestions and corrections are welcome!

35.2.1 What does a doctype do?

doctype is an abbreviation for document type. It is a declaration used in HTML5 to distinguish between a standards-compliant parsing mode and a quirks parsing mode. Hence its presence tells the browser to parse and render the webpage in standards mode.

Moral of the story - just add <!DOCTYPE html> at the start of your page.

35.2.1.0.0.1 References

35.2.2 What’s the difference between full standards mode, almost standards mode and quirks mode?

  • Quirks mode - Layout emulates non-standard behavior in Netscape Navigator 4 and Internet Explorer 5. This is essential in order to support websites that were built before the widespread adoption of web standards. The list of quirks can be found here.
  • Full standards mode - The layout behavior is the one described by the HTML and CSS specifications.
  • Almost standards mode - There are only a very small number of quirks implemented. Differences can be found here.
35.2.2.0.0.1 References

35.2.3 What’s the difference between HTML and XHTML?

XHTML belongs to the family of XML markups languages and is different from HTML. Some of differences are as follows:

  • XHTML documents have to be well-formed, unlike HTML, which is more forgiving.
  • XHTML is case-sensitive for element and attribute names, while HTML is not.
  • Raw < and & characters are not allowed except inside of CDATA Sections (<![CDATA[ ... ]]>). JavaScript typically contains characters which can not exist in XHTML outside of CDATA Sections, such as the < operator. Hence it is tricky to use inline styles or script tags in XHTML and should be avoided.
  • A fatal parse error in XML (such as an incorrect tag structure) causes document processing to be aborted.

Full list of differences can be found on Wikipedia.

35.2.3.0.0.1 References

35.2.4 Are there any problems with serving pages as application/xhtml+xml?

Basically the problems lie in the differences between parsing HTML and XML as mentioned above.

  • XHTML, or rather, XML syntax is less forgiving and if your page isn’t fully XML-compliant, there will be parsing errors and users get unreadable content.
  • Serving your pages as application/xhtml+xml will cause Internet Explorer 8 to show a download dialog box for an unknown format instead of displaying your page, as the first version of Internet Explorer with support for XHTML is Internet Explorer 9.
35.2.4.0.0.1 References

35.2.5 How do you serve a page with content in multiple languages?

The question is a little vague, I will assume that it is asking about the most common case, which is how to serve a page with content available in multiple languages, but the content within the page should be displayed only in one consistent language.

When an HTTP request is made to a server, the requesting user agent usually sends information about language preferences, such as in the Accept-Language header. The server can then use this information to return a version of the document in the appropriate language if such an alternative is available. The returned HTML document should also declare the lang attribute in the <html> tag, such as <html lang="en">...</html>.

In the back end, the HTML markup will contain i18n placeholders and content for the specific language stored in YML or JSON formats. The server then dynamically generates the HTML page with content in that particular language, usually with the help of a back end framework.

35.2.5.0.0.1 References

35.2.6 What kind of things must you be wary of when designing or developing for multilingual sites?

  • Use lang attribute in your HTML.
  • Directing users to their native language - Allow a user to change his country/language easily without hassle.
  • Text in images is not a scalable approach - Placing text in an image is still a popular way to get good-looking, non-system fonts to display on any computer. However to translate image text, each string of text will need to have it’s a separate image created for each language. Anything more than a handful of replacements like this can quickly get out of control.
  • Restrictive words / sentence length - Some content can be longer when written in another language. Be wary of layout or overflow issues in the design. It’s best to avoid designing where the amount of text would make or break a design. Character counts come into play with things like headlines, labels, and buttons. They are less of an issue with free flowing text such as body text or comments.
  • Be mindful of how colors are perceived - Colors are perceived differently across languages and cultures. The design should use color appropriately.
  • Formatting dates and currencies - Calendar dates are sometimes presented in different ways. Eg. “May 31, 2012” in the U.S. vs. “31 May 2012” in parts of Europe.
  • Do not concatenate translated strings - Do not do anything like "The date today is " + date. It will break in languages with different word order. Using template parameters instead.
  • Language reading direction - In English, we read from left-to-right, top-to-bottom, in traditional Japanese, text is read up-to-down, right-to-left.
35.2.6.0.0.1 References

35.2.7 What are data- attributes good for?

Before JavaScript frameworks became popular, front end developers used data- attributes to store extra data within the DOM itself, without other hacks such as non-standard attributes, extra properties on the DOM. It is intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.

These days, using data- attributes is not encouraged. One reason is that users can modify the data attribute easily by using inspect element in the browser. The data model is better stored within JavaScript itself and stay updated with the DOM via data binding possibly through a library or a framework.

35.2.7.0.0.1 References

35.2.8 Consider HTML5 as an open web platform. What are the building blocks of HTML5?

  • Semantics - Allowing you to describe more precisely what your content is.
  • Connectivity - Allowing you to communicate with the server in new and innovative ways.
  • Offline and storage - Allowing webpages to store data on the client-side locally and operate offline more efficiently.
  • Multimedia - Making video and audio first-class citizens in the Open Web.
  • 2D/3D graphics and effects - Allowing a much more diverse range of presentation options.
  • Performance and integration - Providing greater speed optimization and better usage of computer hardware.
  • Device access - Allowing for the usage of various input and output devices.
  • Styling - Letting authors write more sophisticated themes.
35.2.8.0.0.1 References

All the above mentioned technologies are key-value storage mechanisms on the client side. They are only able to store values as strings.

cookie localStorage sessionStorage
Initiator Client or server. Server can use Set-Cookie header Client Client
Expiry Manually set Forever On tab close
Persistent across browser sessions Depends on whether expiration is set Yes No
Have domain associated Yes No No
Sent to server with every HTTP request Cookies are automatically being sent via Cookie header No No
Capacity (per domain) 4kb 5MB 5MB
Accessibility Any window Any window Same tab
35.2.9.0.0.1 References

35.2.10 Describe the difference between <script>, <script async> and <script defer>.

  • <script> - HTML parsing is blocked, the script is fetched and executed immediately, HTML parsing resumes after the script is executed.
  • <script async> - The script will be fetched in parallel to HTML parsing and executed as soon as it is available (potentially before HTML parsing completes). Use async when the script is independent of any other scripts on the page, for example analytics.
  • <script defer> - The script will be fetched in parallel to HTML parsing and executed when the page has finished parsing. If there are multiple of them, each deferred script is executed in the order they were encoun­tered in the document. If a script relies on a fully-parsed DOM, the defer attribute will be useful in ensuring that the HTML is fully parsed before executing. There’s not much difference from putting a normal <script> at the end of <body>. A deferred script must not contain document.write.

Note: The async and defer attrib­utes are ignored for scripts that have no src attribute.

35.2.10.0.0.1 References

Placing <link>s in the <head>

Putting <link>s in the head is part of the specification. Besides that, placing at the top allows the page to render progressively which improves user experience. The problem with putting stylesheets near the bottom of the document is that it prohibits progressive rendering in many browsers, including Internet Explorer. Some browsers block rendering to avoid having to repaint elements of the page if their styles change. The user is stuck viewing a blank white page. It prevents the flash of unstyled contents.

Placing <script>s just before </body>

<script>s block HTML parsing while they are being downloaded and executed. Downloading the scripts at the bottom will allow the HTML to be parsed and displayed to the user first.

An exception for positioning of <script>s at the bottom is when your script contains document.write(), but these days it’s not a good practice to use document.write(). Also, placing <script>s at the bottom means that the browser cannot start downloading the scripts until the entire document is parsed. One possible workaround is to put <script> in the <head> and use the defer attribute.

35.2.11.0.0.1 References

35.2.12 What is progressive rendering?

Progressive rendering is the name given to techniques used to improve performance of a webpage (in particular, improve perceived load time) to render content for display as quickly as possible.

It used to be much more prevalent in the days before broadband internet but it is still useful in modern development as mobile data connections are becoming increasingly popular (and unreliable)!

Examples of such techniques:

  • Lazy loading of images - Images on the page are not loaded all at once. JavaScript will be used to load an image when the user scrolls into the part of the page that displays the image.
  • Prioritizing visible content (or above-the-fold rendering) - Include only the minimum CSS/content/scripts necessary for the amount of page that would be rendered in the users browser first to display as quickly as possible, you can then use deferred scripts or listen for the DOMContentLoaded/load event to load in other resources and content.
  • Async HTML fragments - Flushing parts of the HTML to the browser as the page is constructed on the back end. More details on the technique can be found here.
35.2.12.0.0.1 References

35.2.13 Have you used different HTML templating languages before?

Yes, Pug (formerly Jade), ERB, Slim, Handlebars, Jinja, Liquid, just to name a few. In my opinion, they are more or less the same and provide similar functionality of escaping content and helpful filters for manipulating the data to be displayed. Most templating engines will also allow you to inject your own filters in the event you need custom processing before display.

35.2.14 Other Answers

35.3 CSS Questions

Answers to Front-end Job Interview Questions - CSS Questions. Pull requests for suggestions and corrections are welcome!

35.3.1 What is the difference between classes and IDs in CSS?

  • IDs - Meant to be unique within the document. Can be used to identify an element when linking using a fragment identifier. Elements can only have one id attribute.
  • Classes - Can be reused on multiple elements within the document. Mainly for styling and targeting elements.

35.3.2 What’s the difference between “resetting” and “normalizing” CSS? Which would you choose, and why?

  • Resetting - Resetting is meant to strip all default browser styling on elements. For e.g. margins, paddings, font-sizes of all elements are reset to be the same. You will have to redeclare styling for common typographic elements.
  • Normalizing - Normalizing preserves useful default styles rather than “unstyling” everything. It also corrects bugs for common browser dependencies.

I would choose resetting when I have very a customized or unconventional site design such that I need to do a lot of my own styling do not need any default styling to be preserved.

35.3.2.0.0.1 References

35.3.3 Describe floats and how they work.

Float is a CSS positioning property. Floated elements remain a part of the flow of the page, and will affect the positioning of other elements (e.g. text will flow around floated elements), unlike position: absolute elements, which are removed from the flow of the page.

The CSS clear property can be used to be positioned below left/right/both floated elements.

If a parent element contains nothing but floated elements, its height will be collapsed to nothing. It can be fixed by clearing the float after the floated elements in the container but before the close of the container.

The .clearfix hack uses a clever CSS pseudo selector (:after) to clear floats. Rather than setting the overflow on the parent, you apply an additional class clearfix to it. Then apply this CSS:

.clearfix:after {
  content: ' ';
  visibility: hidden;
  display: block;
  height: 0;
  clear: both;
}

Alternatively, give overflow: auto or overflow: hidden property to the parent element which will establish a new block formatting context inside the children and it will expand to contain its children.

35.3.3.0.0.1 References

35.3.4 Describe z-index and how stacking context is formed.

The z-index property in CSS controls the vertical stacking order of elements that overlap. z-index only effects elements that have a position value which is not static.

Without any z-index value, elements stack in the order that they appear in the DOM (the lowest one down at the same hierarchy level appears on top). Elements with non-static positioning (and their children) will always appear on top of elements with default static positioning, regardless of HTML hierarchy.

A stacking context is an element that contains a set of layers. Within a local stacking context, the z-index values of its children are set relative to that element rather than to the document root. Layers outside of that context — i.e. sibling elements of a local stacking context — can’t sit between layers within it. If an element B sits on top of element A, a child element of element A, element C, can never be higher than element B even if element C has a higher z-index than element B.

Each stacking context is self-contained - after the element’s contents are stacked, the whole element is considered in the stacking order of the parent stacking context. A handful of CSS properties trigger a new stacking context, such as opacity less than 1, filter that is not none, and transform that is notnone`.

35.3.4.0.0.1 References

35.3.5 Describe Block Formatting Context (BFC) and how it works.

A Block Formatting Context (BFC) is part of the visual CSS rendering of a web page in which block boxes are laid out. Floats, absolutely positioned elements, inline-blocks, table-cells, table-captions, and elements with overflow other than visible (except when that value has been propagated to the viewport) establish new block formatting contexts.

A BFC is an HTML box that satisfies at least one of the following conditions:

  • The value of float is not none.
  • The value of position is neither static nor relative.
  • The value of display is table-cell, table-caption, inline-block, flex, or inline-flex.
  • The value of overflow is not visible.

In a BFC, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).

Vertical margins between adjacent block-level boxes in a BFC collapse. Read more on collapsing margins.

35.3.5.0.0.1 References

35.3.6 What are the various clearing techniques and which is appropriate for what context?

  • Empty div method - <div style="clear:both;"></div>.
  • Clearfix method - Refer to the .clearfix class above.
  • overflow: auto or overflow: hidden method - Parent will establish a new block formatting context and expand to contains its floated children.

In large projects, I would write a utility .clearfix class and use them in places where I need it. overflow: hidden might clip children if the children is taller than the parent and is not very ideal.

35.3.7 Explain CSS sprites, and how you would implement them on a page or site.

CSS sprites combine multiple images into one single larger image. It is commonly used technique for icons (Gmail uses it). How to implement it:

  1. Use a sprite generator that packs multiple images into one and generate the appropriate CSS for it.
  2. Each image would have a corresponding CSS class with background-image, background-position and background-size properties defined.
  3. To use that image, add the corresponding class to your element.

Advantages:

  • Reduce the number of HTTP requests for multiple images (only one single request is required per spritesheet). But with HTTP2, loading multiple images is no longer much of an issue.
  • Advance downloading of assets that won’t be downloaded until needed, such as images that only appear upon :hover pseudo-states. Blinking wouldn’t be seen.

35.3.8 What are your favorite image replacement techniques and which do you use when?

CSS image replacement is a technique of replacing a text element (usually a header tag like an <h1>) with an image (often a logo). It has its origins in the time before web fonts and SVG. For years, web developers battled against browser inconsistencies to craft image replacement techniques that struck the right balance between design and accessibility.

It’s not really relevant these days. Check out the link below for all the available techniques.

35.3.8.0.0.1 References

35.3.9 How would you approach fixing browser-specific styling issues?

  • After identifying the issue and the offending browser, use a separate style sheet that only loads when that specific browser is being used. This technique requires server-side rendering though.
  • Use libraries like Bootstrap that already handles these styling issues for you.
  • Use autoprefixer to automatically add vendor prefixes to your code.
  • Use Reset CSS or Normalize.css.

35.3.10 How do you serve your pages for feature-constrained browsers? What techniques/processes do you use?

  • Graceful degradation - The practice of building an application for modern browsers while ensuring it remains functional in older browsers.
  • Progressive enhancement - The practice of building an application for a base level of user experience, but adding functional enhancements when a browser supports it.
  • Use caniuse.com to check for feature support.
  • Autoprefixer for automatic vendor prefix insertion.
  • Feature detection using Modernizr.

35.3.11 What are the different ways to visually hide content (and make it available only for screen readers)?

These techniques are related to accessibility (a11y).

  • visibility: hidden. However the element is still in the flow of the page, and still takes up space.
  • width: 0; height: 0. Make the element not take up any space on the screen at all, resulting in not showing it.
  • position: absolute; left: -99999px. Position it outside of the screen.
  • text-indent: -9999px. This only works on text within the block elements.

I would go with the absolute positioning approach, as it has the least caveats and works for most elements.

35.3.12 Have you ever used a grid system, and if so, what do you prefer?

I like the float-based grid system because it still has the most browser support among the alternative existing systems (flex, grid). It has been used in Bootstrap for years and has been proven to work.

35.3.13 Have you used or implemented media queries or mobile-specific layouts/CSS?

Yes. An example would be transforming a stacked pill navigation into a fixed-bottom tab navigation beyond a certain breakpoint.

35.3.14 Are you familiar with styling SVG?

No… Sadly.

35.3.15 How do you optimize your webpages for print?

  • Create a stylesheet for print or use media queries.
<!-- Main stylesheet on top -->
<link rel="stylesheet" href="/global.css" media="all" />
<!-- Print only, on bottom -->
<link rel="stylesheet" href="/print.css" media="print" />

Make sure to put non-print styles inside @media screen { ... }.

@media print {
  ...
}
  • Deliberately add page breaks.
<style>
.page-break {
  display: none;
  page-break-before: always;
}
</style>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Fusce eu felis. Curabitur sit amet magna. Nullam aliquet. Aliquam ut diam...
<div class="page-break"></div>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit....
35.3.15.0.0.1 References

35.3.16 What are some of the “gotchas” for writing efficient CSS?

Firstly, understand that browsers match selectors from rightmost (key selector) to left. Browsers filter out elements in the DOM according to the key selector, and traverse up its parent elements to determine matches. The shorter the length of the selector chain, the faster the browser can determine if that element matches the selector. Hence avoid key selectors that are tag and universal selectors. They match a large numbers of elements and browsers will have to do more work in determining if the parents do match.

BEM (Block Element Modifier) methodology recommends that everything has a single class, and, where you need hierarchy, that gets baked into the name of the class as well, this naturally makes the selector efficient and easy to override.

Be aware of which CSS properties trigger reflow, repaint and compositing. Avoid writing styles that change the layout (trigger reflow) where possible.

35.3.16.0.0.1 References

35.3.17 What are the advantages/disadvantages of using CSS preprocessors?

Advantages:

  • CSS is made more maintainable.
  • Easy to write nested selectors.
  • Variables for consistent theming. Can share theme files across different projects.
  • Mixins to generate repeated CSS.
  • Splitting your code into multiple files. CSS files can be split up too but doing so will require a HTTP request to download each CSS file.

Disadvantages:

  • Requires tools for preprocessing. Re-compilation time can be slow.

35.3.18 Describe what you like and dislike about the CSS preprocessors you have used.

Likes:

  • Mostly the advantages mentioned above.
  • Less is written in JavaScript, which plays well with Node.

Dislikes:

  • I use Sass via node-sass, which is a binding for LibSass written in C++. I have to frequently recompile it when switching between node versions.
  • In Less, variable names are prefixed with @, which can be confused with native CSS keywords like @media, @import and @font-face rule.

35.3.19 How would you implement a web design comp that uses non-standard fonts?

Use @font-face and define font-family for different font-weights.

35.3.20 Explain how a browser determines what elements match a CSS selector.

This part is related to the above about writing efficient CSS. Browsers match selectors from rightmost (key selector) to left. Browsers filter out elements in the DOM according to the key selector, and traverse up its parent elements to determine matches. The shorter the length of the selector chain, the faster the browser can determine if that element matches the selector.

For example with this selector p span, browsers firstly find all the <span> elements, and traverse up its parent all the way up to the root to find the <p> element. For a particular <span>, as soon as it finds a <p>, it knows that the <span> matches and can stop its matching.

35.3.20.0.0.1 References

35.3.21 Describe pseudo-elements and discuss what they are used for.

A CSS pseudo-element is a keyword added to a selector that lets you style a specific part of the selected element(s). They can be used for decoration (:first-line, :first-letter) or adding elements to the markup (combined with content: ...) without having to modify the markup (:before, :after).

  • :first-line and :first-letter can be used to decorate text.
  • Used in the .clearfix hack as shown above to add a zero-space element with clear: both.
  • Triangular arrows in tooltips use :before and :after. Encourages separation of concerns because the triangle is considered part of styling and not really the DOM. It’s not really possible to draw a triangle with just CSS styles without using an additional HTML element.
35.3.21.0.0.1 References

35.3.22 Explain your understanding of the box model and how you would tell the browser in CSS to render your layout in different box models.

The CSS box model describes the rectangular boxes that are generated for elements in the document tree and laid out according to the visual formatting model. Each box has a content area (e.g. text, an image, etc.) and optional surrounding padding, border, and margin areas.

The CSS box model is responsible for calculating:

  • How much space a block element takes up.
  • Whether or not borders and/or margins overlap, or collapse.
  • A box’s dimensions.

The box model has the following rules:

  • The dimensions of a block element are calculated by width, height, padding, borders, and margins.
  • If no height is specified, a block element will be as high as the content it contains, plus padding (unless there are floats, for which see below).
  • If no width is specified, a non-floated block element will expand to fit the width of its parent minus padding.
  • The height of an element is calculated by the content’s height.
  • The width of an element is calculated by the content’s width.
  • By default, paddings and borders are not part of the width and height of an element.
35.3.22.0.0.1 References

35.3.23 What does * { box-sizing: border-box; } do? What are its advantages?

  • By default, elements have box-sizing: content-box applied, and only the content size is being accounted for.
  • box-sizing: border-box changes how the width and height of elements are being calculated, border and padding are also being included in the calculation.
  • The height of an element is now calculated by the content’s height + vertical padding + vertical border width.
  • The width of an element is now calculated by the content’s width + horizontal padding + horizontal border width.

35.3.24 List as many values for the display property that you can remember.

  • none, block, inline, inline-block, table, table-row, table-cell, list-item.

35.3.25 What’s the difference between inline and inline-block?

I shall throw in a comparison with block for good measure.

block inline-block inline
Size Fills up the width of its parent container. Depends on content. Depends on content.
Positioning Start on a new line and tolerates no HTML elements next to it (except when you add float) Flows along with other content and allows other elements beside. Flows along with other content and allows other elements beside.
Can specify width and height Yes Yes No. Will ignore if being set.
Can be aligned with vertical-align No Yes Yes
Margins and paddings All sides respected. All sides respected. Only horizontal sides respected. Vertical sides, if specified, do not affect layout. Vertical space it takes up depends on line-height, even though the border and padding appear visually around the content.
Float - - Becomes like a block element where you can set vertical margins and paddings.

What’s the difference between a relative, fixed, absolute and static-ally positioned element?

A positioned element is an element whose computed position property is either relative, absolute, fixed or sticky.

  • static - The default position; the element will flow into the page as it normally would. The top, right, bottom, left and z-index properties do not apply.
  • relative - The element’s position is adjusted relative to itself, without changing layout (and thus leaving a gap for the element where it would have been had it not been positioned).
  • absolute - The element is removed from the flow of the page and positioned at a specified position relative to its closest positioned ancestor if any, or otherwise relative to the initial containing block. Absolutely positioned boxes can have margins, and they do not collapse with any other margins. These elements do not affect the position of other elements.
  • fixed - The element is removed from the flow of the page and positioned at a specified position relative to the viewport and doesn’t move when scrolled.
  • sticky - Sticky positioning is a hybrid of relative and fixed positioning. The element is treated as relative positioned until it crosses a specified threshold, at which point it is treated as fixed positioned.
35.3.25.0.0.1 References

35.3.26 The ‘C’ in CSS stands for Cascading. How is priority determined in assigning styles (a few examples)? How can you use this system to your advantage?

Browser determines what styles to show on an element depending on the specificity of CSS rules. We assume that the browser has already determined the rules that match a particular element. Among the matching rules, the specificity, four comma-separate values, a, b, c, d are calculated for each rule based on the following:

  1. a is whether inline styles are being used. If the property declaration is an inline style on the element, a is 1, else 0.
  2. b is the number of ID selectors.
  3. c is the number of classes, attributes and pseudo-classes selectors.
  4. d is the number of tags and pseudo-elements selectors.

The resulting specificity is not a score, but a matrix of values that can be compared column by column. When comparing selectors to determine which has the highest specificity, look from left to right, and compare the highest value in each column. So a value in column b will override values in columns c and d, no matter what they might be. As such, specificity of 0,1,0,0 would be greater than one of 0,0,10,10.

In the cases of equal specificity: the latest rule is the one that counts. If you have written the same rule into your style sheet (regardless of internal or external) twice, then the lower rule in your style sheet is closer to the element to be styled, it is deemed to be more specific and therefore will be applied.

I would write CSS rules with low specificity so that they can be easily overridden if necessary. When writing CSS UI component library code, it is important that they have low specificities so that users of the library can override them without using too complicated CSS rules just for the sake of increasing specificity or resorting to !important.

35.3.26.0.0.1 References

35.3.27 What existing CSS frameworks have you used locally, or in production? How would you change/improve them?

  • Bootstrap - Slow release cycle. Bootstrap 4 has been in alpha for almost 2 years. Add a spinner button component, as it is widely-used.
  • Semantic UI - Source code structure makes theme customization extremely hard to understand. Painful to customize with unconventional theming system. Hardcoded config path within the vendor library. Not well-designed for overriding variables unlike in Bootstrap.
  • Bulma - A lot of non-semantic and superfluous classes and markup required. Not backward compatible. Upgrading versions breaks the app in subtle manners.

35.3.28 Have you played around with the new CSS Flexbox or Grid specs?

Yes. Flexbox is mainly meant for 1-dimensional layouts while Grid is meant for 2-dimensional layouts.

Flexbox solves many common problems in CSS, such as vertical centering of elements within a container, sticky footer, etc. Bootstrap and Bulma are based on Flexbox, and it is probably the recommended way to create layouts these days. Have tried Flexbox before but ran into some browser incompatibility issues (Safari) in using flex-grow, and I had to rewrite my code using inline-blocks and math to calculate the widths in percentages, it wasn’t a nice experience.

Grid is by far the most intuitive approach for creating grid-based layouts (it better be!) but browser support is not wide at the moment.

35.3.28.0.0.1 References

35.3.29 How is responsive design different from adaptive design?

Both responsive and adaptive design attempt to optimize the user experience across different devices, adjusting for different viewport sizes, resolutions, usage contexts, control mechanisms, and so on.

Responsive design works on the principle of flexibility - a single fluid website that can look good on any device. Responsive websites use media queries, flexible grids, and responsive images to create a user experience that flexes and changes based on a multitude of factors. Like a single ball growing or shrinking to fit through several different hoops.

Adaptive design is more like the modern definition of progressive enhancement. Instead of one flexible design, adaptive design detects the device and other features, and then provides the appropriate feature and layout based on a predefined set of viewport sizes and other characteristics. The site detects the type of device used, and delivers the pre-set layout for that device. Instead of a single ball going through several different-sized hoops, you’d have several different balls to use depending on the hoop size.

35.3.29.0.0.1 References

35.3.30 Have you ever worked with retina graphics? If so, when and what techniques did you use?

I tend to use higher resolution graphics (twice the display size) to handle retina display. The better way would be to use a media query like @media only screen and (min-device-pixel-ratio: 2) { ... } and change the background-image.

For icons, I would also opt to use svgs and icon fonts where possible, as they render very crisply regardless of resolution.

Another method would be to use JavaScript to replace the <img> src attribute with higher resolution versions after checking the window.devicePixelRatio value.

35.3.30.0.0.1 References

35.3.31 Is there any reason you’d want to use translate() instead of absolute positioning, or vice-versa? And why?

translate() is a value of CSS transform. Changing transform or opacity does not trigger browser reflow or repaint, only compositions, whereas changing the absolute positioning triggers reflow. transform causes the browser to create a GPU layer for the element but changing absolute positioning properties uses the CPU. Hence translate() is more efficient and will result in shorter paint times for smoother animations.

When using translate(), the element still takes up its original space (sort of like position: relative), unlike in changing the absolute positioning.

35.3.31.0.0.1 References

35.3.32 Other Answers

35.4 JS Questions

Answers to Front-end Job Interview Questions - JS Questions. Pull requests for suggestions and corrections are welcome!

35.4.1 Explain event delegation

Event delegation is a technique involving adding event listeners to a parent element instead of adding them to the descendant elements. The listener will fire whenever the event is triggered on the descendant elements due to event bubbling up the DOM. The benefits of this technique are:

  • Memory footprint goes down because only one single handler is needed on the parent element, rather than having to attach event handlers on each descendant.
  • There is no need to unbind the handler from elements that are removed and to bind the event for new elements.
35.4.1.0.0.1 References

35.4.2 Explain how this works in JavaScript

There’s no simple explanation for this; it is one of the most confusing concepts in JavaScript. A hand-wavey explanation is that the value of this depends on how the function is called. I have read many explanations on this online, and I found Arnav Aggrawal’s explanation to be the clearest. The following rules are applied:

  1. If the new keyword is used when calling the function, this inside the function is a brand new object.
  2. If apply, call, or bind are used to call/create a function, this inside the function is the object that is passed in as the argument.
  3. If a function is called as a method, such as obj.method() — this is the object that the function is a property of.
  4. If a function is invoked as a free function invocation, meaning it was invoked without any of the conditions present above, this is the global object. In a browser, it is the window object. If in strict mode ('use strict'), this will be undefined instead of the global object.
  5. If multiple of the above rules apply, the rule that is higher wins and will set the this value.
  6. If the function is an ES2015 arrow function, it ignores all the rules above and receives the this value of its surrounding scope at the time it is created.

For an in-depth explanation, do check out his article on Medium.

35.4.2.0.0.1 References

35.4.3 Explain how prototypal inheritance works

This is an extremely common JavaScript interview question. All JavaScript objects have a prototype property, that is a reference to another object. When a property is accessed on an object and if the property is not found on that object, the JavaScript engine looks at the object’s prototype, and the prototype’s prototype and so on, until it finds the property defined on one of the prototypes or until it reaches the end of the prototype chain. This behaviour simulates classical inheritance, but it is really more of delegation than inheritance.

35.4.3.0.0.1 References

35.4.4 What do you think of AMD vs CommonJS?

Both are ways to implement a module system, which was not natively present in JavaScript until ES2015 came along. CommonJS is synchronous while AMD (Asynchronous Module Definition) is obviously asynchronous. CommonJS is designed with server-side development in mind while AMD, with its support for asynchronous loading of modules, is more intended for browsers.

I find AMD syntax to be quite verbose and CommonJS is closer to the style you would write import statements in other languages. Most of the time, I find AMD unnecessary, because if you served all your JavaScript into one concatenated bundle file, you wouldn’t benefit from the async loading properties. Also, CommonJS syntax is closer to Node style of writing modules and there is less context-switching overhead when switching between client side and server side JavaScript development.

I’m glad that with ES2015 modules, that has support for both synchronous and asynchronous loading, we can finally just stick to one approach. Although it hasn’t been fully rolled out in browsers and in Node, we can always use transpilers to convert our code.

35.4.4.0.0.1 References

35.4.5 Explain why the following doesn’t work as an IIFE: function foo(){ }();. What needs to be changed to properly make it an IIFE?

IIFE stands for Immediately Invoked Function Expressions. The JavaScript parser reads function foo(){ }(); as function foo(){ } and ();, where the former is a function declaration and the latter (a pair of brackets) is an attempt at calling a function but there is no name specified, hence it throws Uncaught SyntaxError: Unexpected token ).

Here are two ways to fix it that involves adding more brackets: (function foo(){ })() and (function foo(){ }()). These functions are not exposed in the global scope and you can even omit its name if you do not need to reference itself within the body.

35.4.5.0.0.1 References

35.4.6 What’s the difference between a variable that is: null, undefined or undeclared? How would you go about checking for any of these states?

Undeclared variables are created when you assign to a value to an identifier that is not previously created using var, let or const. Undeclared variables will be defined globally, outside of the current scope. In strict mode, a ReferenceError will be thrown when you try to assign to an undeclared variable. Undeclared variables are bad just like how global variables are bad. Avoid them at all cost! To check for them, wrap its usage in a try/catch block.

function foo() {
  x = 1;   // Throws a ReferenceError in strict mode
}

foo()
console.log(x) // 1

A variable that is undefined is a variable that has been declared, but not assigned a value. It is of type undefined. If a function does not return any value as the result of executing it is assigned to a variable, the variable also has the value of undefined. To check for it, compare using the strict equality (===) operator or typeof which will give the 'undefined' string. Note that you should not be using the abstract equality operator to check, as it will also return true if the value is null.

var foo;
console.log(foo); // undefined
console.log(foo === undefined); // true
console.log(typeof foo === 'undefined'); // true

console.log(foo == null); // true. Wrong, don't use this to check!

function bar() {}
var baz = bar();
console.log(baz); // undefined

A variable that is null will have been explicitly assigned to the null value. It represents no value and is different from undefined in the sense that it has been explicitly assigned. To check for null, simply compare using the strict equality operator. Note that like the above, you should not be using the abstract equality operator (==) to check, as it will also return true if the value is undefined.

var foo = null;
console.log(foo === null); // true

console.log(foo == undefined); // true. Wrong, don't use this to check!

As a personal habit, I never leave my variables undeclared or unassigned. I will explicitly assign null to them after declaring, if I don’t intend to use it yet.

35.4.6.0.0.1 References

35.4.7 What is a closure, and how/why would you use one?

A closure is the combination of a function and the lexical environment within which that function was declared. The word “lexical” refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available. Closures are functions that have access to the outer (enclosing) function’s variables—scope chain even after the outer function has returned.

Why would you use one?

35.4.7.0.0.1 References

35.4.8 What’s a typical use case for anonymous functions?

They can be used in IIFEs to encapsulate some code within a local scope so that variables declared in it do not leak to the global scope.

(function() {
  // Some code here.
})();

As a callback that is used once and does not need to be used anywhere else. The code will seem more self-contained and readable when handlers are defined right inside the code calling them, rather than having to search elsewhere to find the function body.

setTimeout(function () {
  console.log('Hello world!');
}, 1000);

Arguments to functional programming constructs or Lodash (similar to callbacks).

const arr = [1, 2, 3];
const double = arr.map(function (el) {
  return el * 2;
});
console.log(double); // [2, 4, 6]
35.4.8.0.0.1 References

35.4.9 How do you organize your code? (module pattern, classical inheritance?)

In the past, I used Backbone for my models which encourages a more OOP approach, creating Backbone models and attaching methods to them.

The module pattern is still great, but these days, I use the Flux architecture based on React/Redux which encourages a single-directional functional programming approach instead. I would represent my app’s models using plain objects and write utility pure functions to manipulate these objects. State is manipulated using actions and reducers like in any other Redux application.

I avoid using classical inheritance where possible. When and if I do, I stick to these rules.

35.4.10 What’s the difference between host objects and native objects?

Native objects are objects that are part of the JavaScript language defined by the ECMAScript specification, such as String, Math, RegExp, Object, Function, etc.

Host objects are provided by the runtime environment (browser or Node), such as window, XMLHTTPRequest, etc.

35.4.10.0.0.1 References

35.4.11 Difference between: function Person(){}, var person = Person(), and var person = new Person()?

This question is pretty vague. My best guess at its intention is that it is asking about constructors in JavaScript. Technically speaking, function Person(){} is just a normal function declaration. The convention is use PascalCase for functions that are intended to be used as constructors.

var person = Person() invokes the Person as a function, and not as a constructor. Invoking as such is a common mistake if it the function is intended to be used as a constructor. Typically, the constructor does not return anything, hence invoking the constructor like a normal function will return undefined and that gets assigned to the variable intended as the instance.

var person = new Person() creates an instance of the Person object using the new operator, which inherits from Person.prototype. An alternative would be to use Object.create, such as: Object.create(Person.prototype).

function Person(name) {
  this.name = name;
}

var person = Person('John');
console.log(person); // undefined
console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined

var person = new Person('John');
console.log(person); // Person { name: "John" }
console.log(person.name); // "john"
35.4.11.0.0.1 References

35.4.12 What’s the difference between .call and .apply?

Both .call and .apply are used to invoke functions and the first parameter will be used as the value of this within the function. However, .call takes in a comma-separated arguments as the next arguments while .apply takes in an array of arguments as the next argument. An easy way to remember this is C for call and comma-separated and A for apply and array of arguments.

function add(a, b) {
  return a + b;
}

console.log(add.call(null, 1, 2)) // 3
console.log(add.apply(null, [1, 2])) // 3

35.4.13 Explain Function.prototype.bind.

Taken word-for-word from MDN:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

In my experience, it is most useful for binding the value of this in methods of classes that you want to pass into other functions. This is frequently done in React components.

35.4.13.0.0.1 References

35.4.14 When would you use document.write()?

document.write() writes a string of text to a document stream opened by document.open(). When document.write() is executed after the page has loaded, it will call document.open which clears the whole document (<head> and <body> removed!) and replaces the contents with the given parameter value in string. Hence it is usually considered dangerous and prone to misuse.

There are some answers online that explain document.write() is being used in analytics code or when you want to include styles that should only work if JavaScript is enabled. It is even being used in HTML5 boilerplate to load scripts in parallel and preserve execution order! However, I suspect those reasons might be outdated and in the modern day, they can be achieved without using document.write(). Please do correct me if I’m wrong about this.

35.4.14.0.0.1 References

35.4.15 What’s the difference between feature detection, feature inference, and using the UA string?

Feature Detection

Feature detection involves working out whether a browser supports a certain block of code, and running different code dependent on whether it does (or doesn’t), so that the browser can always provide a working experience rather crashing/erroring in some browsers. For example:

if ('geolocation' in navigator) {
  // Can use navigator.geolocation
} else {
  // Handle lack of feature
}

Modernizr is a great library to handle feature detection.

Feature Inference

Feature inference checks for a feature just like feature detection, but uses another function because it assumes it will also exist, e.g.:

if (document.getElementsByTagName) {
    element = document.getElementById(id);
}

This is not really recommended. Feature detection is more foolproof.

UA String

This is a browser-reported string that allows the network protocol peers to identify the application type, operating system, software vendor or software version of the requesting software user agent. It can be accessed via navigator.userAgent. However, the string is tricky to parse and can be spoofed. For example, Chrome reports both as Chrome and Safari. So to detect Safari you have to check for the Safari string and the absence of the Chrome string. Avoid this method.

35.4.15.0.0.1 References

35.4.16 Explain Ajax in as much detail as possible.

Ajax (asynchronous JavaScript and XML“) is a set of web development techniques using many web technologies on the client side to create asynchronous web applications. With Ajax, web applications can send data to and retrieve from a server asynchronously (in the background) without interfering with the display and behavior of the existing page. By decoupling the data interchange layer from the presentation layer, Ajax allows for web pages, and by extension web applications, to change content dynamically without the need to reload the entire page. In practice, modern implementations commonly substitute JSON for XML due to the advantages of being native to JavaScript.

The XMLHttpRequest API is frequently used for the asynchronous communication or these days, the fetch API.

35.4.16.0.0.1 References

35.4.17 What are the advantages and disadvantages of using Ajax?

Advantages

  • Better interactivity. New content from the server can be changed dynamically without the need to reload the entire page.
  • Reduce connections to the server since scripts and stylesheets only have to be requested once.
  • State can be maintained on a page. JavaScript variables and DOM state will persist because the main container page was not reloaded.
  • Basically most of the advantages of an SPA.

Disadvantages

  • Dynamic webpages are harder to bookmark.
  • Does not work if JavaScript has been disabled in the browser.
  • Some webcrawlers do not execute JavaScript and would not see content that has been loaded by JavaScript.
  • Basically most of the disadvantages of an SPA.

35.4.18 Explain how JSONP works (and how it’s not really Ajax).

JSONP (JSON with Padding) is a method commonly used to bypass the cross-domain policies in web browsers because Ajax requests from the current page to a cross-origin domain is not allowed.

JSONP works by making a request to a cross-origin domain via a <script> tag and usually with a callback query parameter, for example: https://example.com?callback=printData. The server will then wrap the data within the a function called printData and return it to the client.

<!-- https://mydomain.com -->
<script>
function printData(data) {
  console.log(`My name is ${data.name}!`);
}
</script>

<script src="https://example.com?callback=printData"></script>
// File loaded from https://example.com?callback=printData
printData({ name: 'Yang Shun' });

The client has to have the printData function in its global scope and the function will be executed by the client when the response from the cross-origin domain is received.

JSONP can be unsafe and has some security implications. As JSONP is really JavaScript, it can do everything else JavaScript can do, so you need to trust the provider of the JSONP data.

These days, CORS is the recommended approach and JSONP is seen as a hack.

35.4.18.0.0.1 References

35.4.19 Have you ever used JavaScript templating? If so, what libraries have you used?

Yes. Handlebars, Underscore, Lodash, AngularJS and JSX. I disliked templating in AngularJS because it made heavy use of strings in the directives and typos would go uncaught. JSX is my new favourite as it is closer to JavaScript and there is barely and syntax to be learnt. Nowadays, you can even use ES2015 template string literals as a quick way for creating templates without relying on third-party code.

const template = `<div>My name is: ${name}</div>`;

However, do beware of a potential XSS in the above approach as the contents are not escaped for you, unlike in templating libraries.

35.4.20 Explain “hoisting”.

Hoisting is a term used to explain the behavior of variable declarations in your code. Variables declared or initialized with the var keyword will have their declaration “hoisted” up to the top of the current scope. However, only the declaration is hoisted, the assignment (if there is one), will stay where it is. Let’s explain with a few examples.

// var declarations are hoisted.
console.log(foo); // undefined
var foo = 1;
console.log(foo); // 1

// let/const declarations are NOT hoisted.
console.log(bar); // ReferenceError: bar is not defined
let bar = 2;
console.log(bar); // 2

Function declarations have the body hoisted while the function expressions (written in the form of variable declarations) only has the variable declaration hoisted.

// Function Declaration
console.log(foo); // [Function: foo]
foo(); // 'FOOOOO'
function foo() {
  console.log('FOOOOO');
}
console.log(foo); // [Function: foo]

// Function Expression
console.log(bar); // undefined
bar(); // Uncaught TypeError: bar is not a function
var bar = function() {
  console.log('BARRRR');
}
console.log(bar); // [Function: bar]

35.4.21 Describe event bubbling.

When an event triggers on a DOM element, it will attempt to handle the event if there is a listener attached, then the event is bubbled up to its parent and the same thing happens. This bubbling occurs up the element’s ancestors all the way to the document. Event bubbling is the mechanism behind event delegation.

35.4.22 What’s the difference between an “attribute” and a “property”?

Attributes are defined on the HTML markup but properties are defined on the DOM. To illustrate the difference, imagine we have this text field in our HTML: <input type="text" value="Hello">.

const input = document.querySelector('input');
console.log(input.getAttribute('value')); // Hello
console.log(input.value); // Hello

But after you change the value of the text field by adding “World!” to it, this becomes:

console.log(input.getAttribute('value')); // Hello
console.log(input.value); // Hello World!
35.4.22.0.0.1 References

35.4.23 Why is extending built-in JavaScript objects not a good idea?

Extending a built-in/native JavaScript object means adding properties/functions to its prototype. While this may seem like a good idea at first, it is dangerous in practice. Imagine your code uses a few libraries that both extend the Array.prototype by adding the same contains method, the implementations will overwrite each other and your code will break if the behavior of these two methods are not the same.

The only time you may want to extend a native object is when you want to create a polyfill, essentially providing your own implementation for a method that is part of the JavaScript specification but might not exist in the user’s browser due to it being an older browser.

35.4.23.0.0.1 References

35.4.24 Difference between document load event and document DOMContentLoaded event?

The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.

window’s load event is only fired after the DOM and all dependent resources and assets have loaded.

35.4.24.0.0.1 References

35.4.25 What is the difference between == and ===?

== is the abstract equality operator while === is the strict equality operator. The == operator will compare for equality after doing any necessary type conversions. The === operator will not do type conversion, so if two values are not the same type === will simply return false. When using ==, funky things can happen, such as:

1 == '1' // true
1 == [1] // true
1 == true // true
0 == '' // true
0 == '0' // true
0 == false // true

My advice is never to use the == operator, except for convenience when comparing against null or undefined, where a == null will return true if a is null or undefined.

var a = null;
console.log(a == null); // true
console.log(a == undefined); // true
35.4.25.0.0.1 References

35.4.26 Explain the same-origin policy with regards to JavaScript.

The same-origin policy prevents JavaScript from making requests across domain boundaries. An origin is defined as a combination of URI scheme, hostname, and port number. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page’s Document Object Model.

35.4.26.0.0.1 References

35.4.27 Make this work:

duplicate([1,2,3,4,5]); // [1,2,3,4,5,1,2,3,4,5]
function duplicate(arr) {
  return arr.concat(arr);
}

duplicate([1,2,3,4,5]); // [1,2,3,4,5,1,2,3,4,5]

35.4.28 Why is it called a Ternary expression, what does the word “Ternary” indicate?

“Ternary” indicates three, and a ternary expression accepts three operands, the test condition, the “then” expression and the “else” expression. Ternary expressions are not specific to JavaScript and I’m not sure why it is even in this list.

35.4.28.0.0.1 References

35.4.29 What is "use strict";? What are the advantages and disadvantages to using it?

‘use strict’ is a statement used to enable strict mode to entire scripts or individual functions. Strict mode is a way to opt in to a restricted variant of JavaScript.

Advantages:

  • Makes it impossible to accidentally create global variables.
  • Makes assignments which would otherwise silently fail to throw an exception.
  • Makes attempts to delete undeletable properties throw (where before the attempt would simply have no effect).
  • Requires that function parameter names be unique.
  • this is undefined in the global context.
  • It catches some common coding bloopers, throwing exceptions.
  • It disables features that are confusing or poorly thought out.

Disadvantages:

  • Many missing features that some developers might be used to.
  • No more access to function.caller and function.arguments.
  • Concatenation of scripts written in different strict modes might cause issues.

Overall, I think the benefits outweigh the disadvantages, and I never had to rely on the features that strict mode blocks. I would recommend using strict mode.

35.4.29.0.0.1 References

35.4.30 Create a for loop that iterates up to 100 while outputting “fizz” at multiples of 3, “buzz” at multiples of 5 and “fizzbuzz” at multiples of 3 and 5.

Check out this version of FizzBuzz by Paul Irish.

for (let i = 1; i <= 100; i++) {
  let f = i % 3 == 0, b = i % 5 == 0;
  console.log(f ? (b ? 'FizzBuzz' : 'Fizz') : (b ? 'Buzz' : i));
}

I would not advise you to write the above during interviews though. Just stick with the long but clear approach. For more wacky versions of FizzBuzz, check out the reference link below.

35.4.30.0.0.1 References

35.4.31 Why is it, in general, a good idea to leave the global scope of a website as-is and never touch it?

Every script has access to the global scope, and if everyone is using the global namespace to define their own variables, there will bound to be collisions. Use the module pattern (IIFEs) to encapsulate your variables within a local namespace.

35.4.32 Why would you use something like the load event? Does this event have disadvantages? Do you know any alternatives, and why would you use those?

The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.

The DOM event DOMContentLoaded will fire after the DOM for the page has been constructed, but do not wait for other resources to finish loading. This is preferred in certain cases when you do not need the full page to be loaded before initializing.

TODO.

35.4.32.0.0.1 References

35.4.33 Explain what a single page app is and how to make one SEO-friendly.

The below is taken from the awesome Grab Front End Guide, which coincidentally, is written by me!

Web developers these days refer to the products they build as web apps, rather than websites. While there is no strict difference between the two terms, web apps tend to be highly interactive and dynamic, allowing the user to perform actions and receive a response for their action. Traditionally, the browser receives HTML from the server and renders it. When the user navigates to another URL, a full-page refresh is required and the server sends fresh new HTML for the new page. This is called server-side rendering.

However in modern SPAs, client-side rendering is used instead. The browser loads the initial page from the server, along with the scripts (frameworks, libraries, app code) and stylesheets required for the whole app. When the user navigates to other pages, a page refresh is not triggered. The URL of the page is updated via the HTML5 History API. New data required for the new page, usually in JSON format, is retrieved by the browser via AJAX requests to the server. The SPA then dynamically updates the page with the data via JavaScript, which it has already downloaded in the initial page load. This model is similar to how native mobile apps work.

The benefits:

  • The app feels more responsive and users do not see the flash between page navigations due to full-page refreshes.
  • Fewer HTTP requests are made to the server, as the same assets do not have to be downloaded again for each page load.
  • Clear separation of the concerns between the client and the server; you can easily build new clients for different platforms (e.g. mobile, chatbots, smart watches) without having to modify the server code. You can also modify the technology stack on the client and server independently, as long as the API contract is not broken.

The downsides:

  • Heavier initial page load due to loading of framework, app code, and assets required for multiple pages.
  • There’s an additional step to be done on your server which is to configure it to route all requests to a single entry point and allow client-side routing to take over from there.
  • SPAs are reliant on JavaScript to render content, but not all search engines execute JavaScript during crawling, and they may see empty content on your page. This inadvertently hurts the Search Engine Optimization (SEO) of your app. However, most of the time, when you are building apps, SEO is not the most important factor, as not all the content needs to be indexable by search engines. To overcome this, you can either server-side render your app or use services such as Prerender to “render your javascript in a browser, save the static HTML, and return that to the crawlers”.
35.4.33.0.0.1 References

35.4.34 What is the extent of your experience with Promises and/or their polyfills?

Possess working knowledge of it. A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it’s not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending. Promise users can attach callbacks to handle the fulfilled value or the reason for rejection.

Some common polyfills are $.deferred, Q and Bluebird but not all of them comply to the specification. ES2015 supports Promises out of the box and polyfills are typically not needed these days.

35.4.34.0.0.1 References

35.4.35 What are the pros and cons of using Promises instead of callbacks?

Pros

  • Avoid callback hell which can be unreadable.
  • Makes it easy to write sequential asynchronous code that is readable with .then().
  • Makes it easy to write parallel asynchronous code with Promise.all().

Cons

  • Slightly more complex code (debatable).
  • In older browsers where ES2015 is not supported, you need to load a polyfill in order to use it.

35.4.36 What are some of the advantages/disadvantages of writing JavaScript code in a language that compiles to JavaScript?

Some examples of languages that compile to JavaScript include CoffeeScript, Elm, ClojureScript, PureScript and TypeScript.

Advantages:

  • Fixes some of the longstanding problems in JavaScript and discourages JavaScript anti-patterns.
  • Enables you to write shorter code, by providing some syntactic sugar on top of JavaScript, which I think ES5 lacks, but ES2015 is awesome.
  • Static types are awesome (in the case of TypeScript) for large projects that need to be maintained over time.

Disadvantages:

  • Require a build/compile process as browsers only run JavaScript and your code will need to be compiled into JavaScript before being served to browsers.
  • Debugging can be a pain if your source maps do not map nicely to your pre-compiled source.
  • Most developers are not familiar with these languages and will need to learn it. There’s a ramp up cost involved for your team if you use it for your projects.
  • Smaller community (depends on the language), which means resources, tutorials, libraries and tooling would be harder to find.
  • IDE/editor support might be lacking.
  • These languages will always be behind the latest JavaScript standard.
  • Developers should be cognizant of what their code is being compiled to — because that is what would actually be running, and that is what matters in the end.

Practically, ES2015 has vastly improved JavaScript and made it much nicer to write. I don’t really see the need for CoffeeScript these days.

35.4.36.0.0.1 References

35.4.37 What tools and techniques do you use for debugging JavaScript code?

35.4.37.0.0.1 References

35.4.38 What language constructions do you use for iterating over object properties and array items?

For objects:

  • for loops - for (var property in obj) { console.log(property); }. However, this will also iterate through its inherited properties, and you will add an obj.hasOwnProperty(property) check before using it.
  • Object.keys() - Object.keys(obj).forEach(function (property) { ... }). Object.keys() is a static method that will lists all enumerable properties of the object that you pass it.

For arrays:

  • for loops - for (var i = 0; i < arr.length; i++). The common pitfall here is that var is in the function scope and not the block scope and most of the time you would want block scoped iterator variable. ES2015 introduces let which has block scope and it is recommended to use that instead. So this becomes: for (let i = 0; i < arr.length; i++).
  • forEach - arr.forEach(function (el, index) { ... }). This construct can be more convenient at times because you do not have to use the index if all you need is the array elements. There are also the every and some methods which will allow you to terminate the iteration early.

Most of the time, I would prefer the .forEach method, but it really depends on what you are trying to do. for loops allow more flexibility, such as prematurely terminate the loop using break or incrementing the iterator more than once per loop.

35.4.39 Explain the difference between mutable and immutable objects.

  • What is an example of an immutable object in JavaScript?
  • What are the pros and cons of immutability?
  • How can you achieve immutability in your own code?

TODO

35.4.40 Explain the difference between synchronous and asynchronous functions.

Synchronous functions are blocking while asynchronous functions are not. In synchronous functions, statements complete before the next statement is run. In this case the program is evaluated exactly in order of the statements and execution of the program is paused if one of the statements take a very long time.

Asynchronous functions usually accept a callback as a parameter and execution continues on the next line immediately after the asynchronous function is invoked. The callback is only invoked when the asynchronous operation is complete and the call stack is empty. Heavy duty operations such as loading data from a web server or querying a database should be done asynchronously so that the main thread can continue executing other operations instead of blocking until that long operation to complete (in the case of browsers, the UI will freeze).

35.4.41 What is event loop? What is the difference between call stack and task queue?

The event loop is a single-threaded loop that monitors the call stack and checks if there is any work to be done in the task queue. If the call stack is empty and there are callback functions in the task queue, a function is dequeued and pushed onto the call stack to be executed.

If you haven’t already checked out Philip Robert’s talk on the Event Loop, you should. It is one of the most viewed videos on JavaScript.

35.4.41.0.0.1 References

35.4.42 Explain the differences on the usage of foo between function foo() {} and var foo = function() {}

The former is a function declaration while the latter is a function expression. The key difference is that function declarations have its body hoisted but the bodies of function expressions are not (they have the same hoisting behaviour as variables). For more explanation on hoisting, refer to the question above on hoisting. If you try to invoke a function expression before it is defined, you will get an Uncaught TypeError: XXX is not a function error.

Function Declaration

foo(); // 'FOOOOO'
function foo() {
  console.log('FOOOOO');
}

Function Expression

foo(); // Uncaught TypeError: foo is not a function
var foo = function() {
  console.log('FOOOOO');
}
35.4.42.0.0.1 References

35.4.43 Other Answers

36 JavaScript

WIP.

36.1 Contents

36.2 Glossary

  • Closure - “Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.” - YDKJS
  • Event Loop - The event loop is a single-threaded loop that monitors the call stack and checks if there is any work to be done in the message queue. If the call stack is empty and there are callback functions in the message queue, a message is dequeued and pushed onto the call stack to be executed.
  • Hoisting - “Wherever a var appears inside a scope, that declaration is taken to belong to the entire scope and accessible everywhere throughout.” - YDKJS
  • Promise - “The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.” - MDN
  • Promises can contain an immediate value.
  • Prototype - TBD
  • This - The this keyword does not refer to the function in which this is used or that function’s scope. Javascript uses 4 rules to determine if this will reference an arbitrary object, undefined or the global object inside a particular function call.

36.3 Core Language

36.3.1 Variables

36.3.2 Functions

  • Reference: this & Object Prototypes
  • Declaration vs Expression
  • Closures
  • .call, .apply and .bind
  • Currying
  • Arrow functions and lexical this

36.3.3 Prototypes and Objects

36.3.4 Async

Reference

36.4 Design Patterns

36.5 Strict Mode

  1. Strict mode eliminates some JavaScript silent errors by changing them to throw errors.
  2. Strict mode fixes mistakes that make it difficult for JavaScript engines to perform optimizations. Strict mode code can sometimes be made to run faster than identical code that’s not strict mode.
  3. Strict mode prohibits some syntax likely to be defined in future versions of ECMAScript.

Converting Mistakes into Errors

  • Prevent accidental creation of global variables.
  • Makes assignments which would otherwise silently fail throw an exception.
  • Makes attempts to delete undeletable properties throw errors.
  • Requires that all properties named in an object literal be unique. Duplicate property names are a syntax error in strict mode.
  • Requires that function parameter names be unique. In normal code the last duplicated argument hides previous identically-named arguments.
  • Forbids setting properties on primitive values in ES6. Without strict mode, setting properties is simply ignored (no-op), with strict mode, however, a TypeError is thrown.

Simplifying Variable Uses

  • Prohibits with.
  • eval of strict mode code does not introduce new variables into the surrounding scope.
  • Forbids deleting plain variables. delete name in strict mode is a syntax error: var x; delete x; // !!! syntax error.

Paving the way for future ECMAScript versions

  • Future ECMAScript versions will likely introduce new syntax, and strict mode in ECMAScript 5 applies some restrictions to ease the transition. It will be easier to make some changes if the foundations of those changes are prohibited in strict mode.
  • First, in strict mode a short list of identifiers become reserved keywords. These words are implements, interface, let, package, private, protected, public, static, and yield. In strict mode, then, you can’t name or use variables or arguments with these names.
  • Second, strict mode prohibits function statements not at the top level of a script or function.

36.6 Transpilation: TBD

37 Networking

WIP.

37.1 Glossary

  • JSON
  • RPC
  • HTTP
  • HTTP/2

38 Performance

WIP.

38.1 Glossary

  • Critical Rendering Path -
  • requestAnimationFrame

38.2 General Strategies

  1. Minimize Bytes.
  2. Reduce critical resources.
  3. Reduce CRP length. TODO: Explain what CRP length is.

38.3 Loading

  • Minify, Compress, Cache assets.
  • Browsers have a preloader to load assets ahead of time.

38.4 Rendering

  • Remove whitespace and comments from HTML/CSS/JS file via minification.
  • CSS
  • CSS blocks rendering AND JavaScript execution.
  • Split up CSS for fewer rendering blocking CSS stylesheets by using media attributes.
  • Use Simpler selectors.
  • JavaScript
  • JS blocks HTML parsing. If the script is external, it will have to be downloaded first. This incurs latency in network and execution.
  • Shift <script> tags to the bottom.
  • Async:
    • Scripts that don’t modify the DOM or CSSOM can use the async attribute to tell the browser not to block DOM parsing and does not need to wait for the CSSOM to be ready.
  • Defer JavaScript execution:
    • There is also a defer attribute available. The difference is that with defer, the script waits to execute until after the document has been parsed, whereas async lets the script run in the background while the document is being parsed.
  • Use web workers for long running operations to move into a web worker thread.
  • Use requestAnimationFrame
38.4.0.0.0.1 References

38.5 Measuring

  • Navigation Timing API is a JavaScript API for accurately measuring performance on the web. The API provides a simple way to get accurate and detailed timing statistics natively for page navigation and load events.
  • performance.timing: An object with the timestamps of the various events on the page. Some uses:
    • Network latency: responseEnd - fetchStart.
    • The time taken for page load once the page is received from the server: loadEventEnd - responseEnd.
    • The whole process of navigation and page load: loadEventEnd - navigationStart.

38.6 Tools

  • Yahoo YSlow
  • Google PageSpeed Insights
  • WebPageTest
  • Sitespeed.io
  • Google Lighthouse

38.7 Web Performance Rules

39 Security

39.1 Glossary

  • CORS - Cross-Origin Resource Sharing (CORS).
  • CSRF - Cross-Site request forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated.
  • XSS - Cross-site scripting (XSS).

39.2 CORS

The same-origin policy protects users by disallowing websites to retrieve information from other websites of different origins. An origin is the triple {protocol, host, port}. Two resources are considered to be of the same origin if and only if all these values are exactly the same.

Cross-Origin Resource Sharing allows relaxing of the same-origin policy. CORS defines a way in which a browser and server can interact to determine whether or not it is safe to allow the cross-origin request.

This standard extends HTTP with a new Origin request header and Access-Control-Allow-Origin and Access-Control-Allow-Methods response headers. It allows servers to use a header to explicitly list origins and HTTP methods that may request a file or to use a wildcard and allow a file to be requested by any site. XMLHttpRequests to a target origin from a different source origin will be blocked if the server did not allow CORS for source origin.

39.3 CSRF

XSS vulnerabilities allow attackers to bypass essentially all CSRF preventions.

39.3.0.1 Protection

  • Verifying Same Origin with Standard Headers
  • There are two steps to this check:
    1. Determining the origin the request is coming from (source origin).
    2. Determining the origin the request is going to (target origin).
  • Examine the Origin, Referer and Host Header values.
  • Synchronizer Tokens
  • The CSRF token is added as a hidden field for forms or within the URL.
  • Characteristics of a CSRF Token
    • Unique per user session
    • Large random value
    • Generated by a cryptographically secure random number generator
  • The server rejects the requested action if the CSRF token fails validation.
  • Double Cookie
  • When a user visits a site, the site should generate a (cryptographically strong) pseudorandom value and set it as a cookie on the user’s machine. The site should require every form submission to include this pseudorandom value as a form value and also as a cookie value. When a POST request is sent to the site, the request should only be considered valid if the form value and the cookie value are the same. When an attacker submits a form on behalf of a user, he can only modify the values of the form. An attacker cannot read any data sent from the server or modify cookie values, per the same-origin policy. This means that while an attacker can send any value he wants with the form, he will be unable to modify or read the value stored in the cookie. Since the cookie value and the form value must be the same, the attacker will be unable to successfully submit a form unless he is able to guess the pseudorandom value.
  • The advantage of this approach is that it requires no server state; you simply set the cookie value once, then every HTTP POST checks to ensure that one of the submitted <input> values contains the exact same cookie value. Any difference between the two means a possible XSRF attack.
  • Cookie-to-Header Token
  • On login, the web application sets a cookie containing a random token that remains the same for the whole user session
    • Set-Cookie: Csrf-token=i8XNjC4b8KVok4uw5RftR38Wgp2BFwql; expires=Thu, 23-Jul-2015 10:25:33 GMT; Max-Age=31449600; Path=/
  • JavaScript operating on the client side reads its value and copies it into a custom HTTP header sent with each transactional request
    • X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
  • The server validates presence and integrity of the token.
  • Security of this technique is based on the assumption that only JavaScript running within the same origin will be able to read the cookie’s value.
  • JavaScript running from a rogue file or email will not be able to read it and copy into the custom header. Even though the csrf-token cookie will be automatically sent with the rogue request, the server will be still expecting a valid X-Csrf-Token header.
  • Use of Custom Request Headers
  • An alternate defense which is particularly well suited for AJAX endpoints is the use of a custom request header. This defense relies on the same-origin policy (SOP) restriction that only JavaScript can be used to add a custom header, and only within its origin. By default, browsers don’t allow JavaScript to make cross origin requests. Such a header can be X-Requested-With: XMLHttpRequest.
  • If this is the case for your system, you can simply verify the presence of this header and value on all your server side AJAX endpoints in order to protect against CSRF attacks. This approach has the double advantage of usually requiring no UI changes and not introducing any server side state, which is particularly attractive to REST services. You can always add your own custom header and value if that is preferred.
  • Require user interaction
  • Require a re-authentication, using a one-time token, or requiring users to complete a captcha.
39.3.0.1.0.1 References

39.4 HTTPS

HTTPS is HTTP over SSL/TLS. Servers and clients still speak exactly the same HTTP to each other, but over a secure SSL connection that encrypts and decrypts their requests and responses. The SSL layer has 2 main purposes:

  1. Verifying that you are talking directly to the server that you think you are talking to.
  2. Ensuring that only the server can read what you send it and only you can read what it sends back.

39.4.0.1 TLS Handshake

// TODO. Crosscheck and add in more details.

  1. The client computer sends a ClientHello message to the server with its Transport Layer Security (TLS) version, list of cipher algorithms and compression methods available.
  2. The server replies with a ServerHello message to the client with the TLS version, selected cipher, selected compression methods and the server’s public certificate signed by a CA (Certificate Authority). The certificate contains a public key that will be used by the client to encrypt the rest of the handshake until a symmetric key can be agreed upon.
  3. The client verifies the server digital certificate against its list of trusted CAs. If trust can be established based on the CA, the client generates a string of pseudo-random bytes and encrypts this with the server’s public key. These random bytes can be used to determine the symmetric key.
  4. The server decrypts the random bytes using its private key and uses these bytes to generate its own copy of the symmetric master key.
  5. The client sends a Finished message to the server, encrypting a hash of the transmission up to this point with the symmetric key.
  6. The server generates its own hash, and then decrypts the client-sent hash to verify that it matches. If it does, it sends its own Finished message to the client, also encrypted with the symmetric key.
  7. From now on the TLS session transmits the application (HTTP) data encrypted with the agreed symmetric key.

39.4.0.2 Downsides of HTTPS

  • TLS handshake computational and latency overhead.
  • Encryption and decryption requires more computation power and bandwidth.
39.4.0.2.0.1 References

39.5 XSS

XSS vulnerabilities allow attackers to bypass essentially all CSRF preventions.

const name = "<img src='x' onerror='alert(1)'>";
el.innerHTML = name;

http://shebang.brandonmintern.com/foolproof-html-escaping-in-javascript/

39.6 Session hijacking

39.7 Framebusting

https://seclab.stanford.edu/websec/framebusting/framebust.pdf

39.8 API

https://github.com/shieldfy/API-Security-Checklist

40 Widgets

Here are some commonly seen widgets/components and the considerations we should take into account when designing them.

40.0.1 Autocomplete

Also known as typeahead box.

40.0.1.1 UX

  • Type a minimum number of characters (typically two) for the results to be displayed. This is because short search terms can result in too many matches and irrelevant results may be returned.
  • Number of query suggestions should be kept short and scrollbars should be avoided. Shorter list of results are more manageable and reduces the cognitive load on the user. If you have scrollbars it probably means you are displaying too many results!
  • Highlight the non-search terms (suggested terms) in the results. This helps the user differentiate the autocomplete suggestions, make it easier to compare.
  • Support keyboard shortcuts: Up/down to navigate and enter to search.
  • Show a history of recent searches.
  • Use placeholder text in the input field to educate users, such as “Type to view suggestions”.

40.0.1.2 Performance

  • Use windowing/virtual lists when the search results is too long.
  • Debounce user input and only search when user stops typing for some time (usually 300ms).
40.0.1.2.0.1 References

40.0.2.1 UX

  • Consider preloading a few images to the left/right of the displayed image during idle time so that as the user navigates, he does not have to wait for the image to be downloaded.
  • Allow left/right keyboard navigation of the carousel.

40.0.2.2 Performance

  • Lazy load the images. Only load those that the user has a high likelihood of viewing - Current image and a few to the left and right.
  • Dropdowns that are displayed on hover are not mobile friendly as there is no hover event on mobile.
  • Dropdown positioning can differ based on position of element on screen. If the element is near the edge and the displayed dropdown will be obscured outside of the viewport, the position of the dropdown can and should be changed.
  • If the height of the dropdown is too long, it may extend outside of the screen. Be sure to make the dropdown contents scrollable by setting a max-height.
  • Modals can usually be dismissed by clicking on the backdrop. If the user interacts with the modal content by clicking on it, the backdrop might also receive the click event and be dismissed as a result.
40.0.4.0.0.1 References

40.0.5 Tooltip

  • Tooltips that are displayed on hover are not mobile friendly as there is no hover event on mobile.
  • Tooltip positioning can differ based on position of element on screen. If the element is near the edge and the displayed tooltip will be obscured outside of the viewport, the position of the tooltip can and should be changed.

41 Behavioral

Learn the STAR format. From Wikipedia:

  • Situation - The interviewer wants you to present a recent challenge and situation in which you found yourself.
  • Task - What were you required to achieve? The interviewer will be looking to see what you were trying to achieve from the situation. Some performance development methods[1] use “Target” rather than “Task”. Job interview candidates who describe a “Target” they set themselves instead of an externally imposed “Task” emphasize their own intrinsic motivation to perform and to develop their performance.
  • Action - What did you do? The interviewer will be looking for information on what you did, why you did it and what the alternatives were.
  • Results - What was the outcome of your actions? What did you achieve through your actions and did you meet your objectives? What did you learn from this experience and have you used this learning since?

41.1 General

  • Why do you want to work for X company?
  • Why do you want to leave your current/last company?
  • What are you looking for in your next role?
  • Tell me about a time when you had a conflict with a co-worker.
  • Tell me about a time in which you had a conflict and needed to influence somebody else.
  • What project are you currently working on?
  • What is the most challenging aspect of your current project?
  • What was the most difficult bug that you fixed in the past 6 months?
  • How do you tackle challenges? Name a difficult challenge you faced while working on a project, how you overcame it, and what you learned.
  • What are you excited about?
  • What frustrates you?
  • Imagine it is your first day here at the company. What do you want to work on? What features would you improve on?
  • What are the most interesting projects you have worked on and how might they be relevant to this company’s environment?
  • Tell me about a time you had a disagreement with your manager.
  • Talk about a project you are most passionate about, or one where you did your best work.
  • What does your best day of work look like?
  • What is something that you had to push for in your previous projects?
  • What is the most constructive feedback you have received in your career?
  • What was one thing you had to persevere for multiple months?

41.2 Airbnb

Source: Glassdoor

While loving to travel or appreciating Airbnb’s growth may be good answers, try to demonstrate the deep connection you have with the product.

  • What does “belong anywhere” mean to you?
  • What large problems in the world would you solve today?
  • Why do you like Airbnb?
  • If you had an unlimited budget and you could buy one gift for one person, what would you buy and who would you buy it for?
  • If you had an unlimited budget and you could go somewhere, where would you go?
  • Share one of your trips with us.
  • What is the most challenging project in or out of school that you have worked on in the last 6 months.
  • What is the thing that you don’t want from your last internship/job?
  • Give me an example of when you’ve been a good host.
  • One thing you would like to remove from the Airbnb experience.
  • What is something new that you can teach your interviewer in a few minutes?
  • Tell me about why you want to work here.
  • What is the best gift you have ever given or received?
  • Tell me about a time you were uncomfortable and how you dealt with it.
  • Explain a project that you worked on recently.
  • What do you think of Airbnb?
  • Tell me something about yourself and why you’d be a good fit for the position.
  • Name a situation where you were impressed by a company’s customer service.
  • How did you work with senior management on large projects as well as multiple internal teams?
  • Tell me about a time you had to give someone terrible news.
  • If you were a gerbil, which gerbil would you be?
  • What excites you about the company?
  • How does Airbnb impact our guests and hosts?
  • What part of our mission resonates the most with you?

41.3 Amazon

Source: Glassdoor

  • How do you deal with a failed deadline?
  • Why do you want to work for Amazon?
  • Talked about a situation where you had a conflict with a teammate.
  • In my professional experience have you worked on something without getting approval from your manager?
  • Tell me a situation where you would have done something differently from what you actually did.
  • What is the most exceedingly bad misstep you at any point made?
  • Describe what Human Resource means to you.
  • How would you improve Amazon’s website?

41.4 Dropbox

Source: Glassdoor

  • Talk about your favorite project.
  • If you were hired here what would you do?
  • State an experience about how you solved a technical problem. Be specific about the diagnosis and process.

41.5 Hired

Source: Glassdoor

  • Tell me about yourself.
  • What is your biggest strength and area of growth?
  • Why are you interested in this opportunity?
  • What are your salary expectations?
  • Why are you looking to leave your current company?
  • What is your biggest strength and area of growth?
  • Tell me about a time your work responsibilities got a little overwhelming. What did you do?
  • Give me an example of a time when you had a difference of opinion with a team member. How did you handle that?
  • Tell me about a challenge you faced recently in your role. How did you tackle it? What was the outcome?
  • Where do you want to be in five years?
  • Tell me about a time you needed information from someone who wasn’t responsive. What did you do?

41.6 Lyft

Source: Glassdoor

  • Tell me about your most interesting/challenging project to date.
  • Why Lyft? What are you looking for in the next role?

41.7 Palantir

Source: Glassdoor

  • How do you deal with difficult coworkers? Think about specific instances where you resolved conflicts.
  • How did you win over the difficult employees?
  • Tell me about an analytical problem that you have worked on in the past.
  • What are your three strengths and three weaknesses?
  • If you were in charge of picking projects for Palantir, what problem would you try to solve?
  • What is something 90% of people disagree with you about?
  • What are some of the best and worse things about your current company?
  • What is broken around you?
  • What would your manager say about you?
  • Describe Palantir to your grandmother.
  • Teach me something you’ve learned?
  • Tell me a time when you predicted something?
  • If your supervisors were to rate you on a scale of 1-10 what would they rate you?
  • What was the most fun thing you did recently?
  • Tell me the story of how you became who you are today and what made you apply to Palantir.

41.8 Slack

Source: Glassdoor

  • Tell me something about your internship.
  • Why do you want to join Slack?
  • Tell me about your past projects.
  • Explain me your toughest project and the working architecture.
  • Apart from technical knowledge what did you learn during your internship?
  • If someone has a different viewpoint to do a project like different programming language, how would handle this situation?
  • What are your most interesting subjects and why?
  • Did you find any bug in Slack?
  • What is your favorite feature and why?

41.9 Stack Overflow

Source: Glassdoor

  • What have you built?
  • What is the hardest technical problem you have run into?
  • How did you solve it?
  • Where do you see yourself in 5 years?
  • Why do you want to work here?
  • How do you handle disagreements with coworkers?

41.10 Stripe

Source: Glassdoor

  • How do you stay up to date with the latest technologies?
  • Explain a project that you worked on recently that was difficult.
  • Where do you see yourself in five years?

41.11 Twitter

Source: Glassdoor

  • What would your previous boss say your biggest strength was?

42 Cover Letter

  • A short introduction describing who you are and what you’re looking for.
  • What projects have you enjoyed working on?
  • Which have you disliked? What motivates you?
  • Links to online profiles you use (GitHub, Twitter, etc).
  • A description of your work history (whether as a resume, LinkedIn profile, or prose).

43 Interview Formats

The following interview formats are based on my experience interviewing with Bay Area companies. Formats would differ slightly depending on the roles you are applying to. Many companies like to use CoderPad for collaborative code editing. CoderPad supports running of the program, so you might be asked to fix your code such that it can be run. For front end interviews, many companies like to use CodePen, and it will be worth your time to familiarize yourself with the user interfaces of such web-based coding environments.

For on-site interviews at smaller (non-public) companies, most will allow (and prefer) that you use your own laptop. Hence it is important that you prepare your development environment in advance.

43.1 Companies

43.1.1 Airbnb

  • Recruiter phone screen.
  • Technical phone interview:
  • 1 or 2 x Algorithm/front end on CoderPad/CodePen.
  • On-site (General):
  • 2 x Algorithm coding on CoderPad.
  • 1 x System design/architecture.
  • 1 x Past experience/project.
  • 2 x Cross functional.
  • On-site (Front End):
  • 2 x Front end coding on CodePen. Use any framework/library.
  • 1 x General coding on your own laptop.
  • 1 x Past experience/project.
  • 2 x Cross functional.
  • Tips:
  • All sessions involve coding on your own laptop. Prepare your development environment in advance.
  • You are allowed to look up APIs if you need to.
  • They seem to place high emphasis on compilable, runnable code in all their coding rounds.
  • Cross functional interviews will involve getting Airbnb employees from any discipline to speak with you. These interviews are mostly non-technical but are extremely important to Airbnb because they place a high emphasis on cultural fit. Do look up the Airbnb section of the behavioural questions to know what sort of questions to expect.

43.1.2 Asana

  • Recruiter phone screen.
  • Technical phone interview.
  • On-site (Product Engineer):
  • 3 x Algorithm and system design on whiteboard within the same session.
  • 1 x Algorithm on laptop and system design. This session involves writing code on your own laptop to solve 3 well-defined algorithm problems in around 45 minutes after which an engineer will come in and review the code with you. You are not supposed to run the code while working on the problem.
  • Tips:
  • No front end questions were asked.
  • Asana places high emphasis on System Design and makes heavy use of the whiteboard. You do not necessarily have to write code for the algorithm question of the first three interviews.
  • All 4 sessions involve algorithms and system design. One of the sessions will be conducted by an Engineering Manager.
  • The last session will involve coding on your own laptop. Prepare your development environment in advance.
  • Regardless of Product Engineer or Engineering Generalist position, their interview format and questions are similar.

43.1.3 Dropbox

  • Recruiter phone screen.
  • Technical phone interviews:
  • 2 x Algorithm/front end on CoderPad/CodePen.
  • On-site (Front End):
  • 2 x Front end on CodePen. Only Vanilla JS or jQuery allowed.
  • 1 x General coding on CoderPad.
  • 1 x All around. Meet with an Engineering Manager and discussing past experiences and working style.
  • Tips:
  • You can code on your own laptop and look up APIs.
  • Dropbox recruiters are very nice and will give you helpful information on what kind of questions to expect for the upcoming sessions.
  • One of the front end sessions involve coding up a pixel-perfect version of a real page on www.dropbox.com. You’ll be given a spec of the desired page and you’ll be asked to create a working version during the interview.

43.1.4 Facebook

  • Recruiter phone screen.
  • Technical phone interviews:
  • 1 or 2 x Algorithm/front end on Skype/CoderPad.
  • On-site (Front End):
  • 2 x Technical coding interview on whiteboard (Ninja).
  • 1 x Behavioural (Jedi). Meet with an Engineering Manager and discussing past experiences and working style.
  • 1 x Design/architecture on whiteboard (Pirate).
  • Tips:
  • You are only allowed to use the whiteboard (or wall). No laptops involved.
  • For the Jedi round, you may be asked a technical question at the end of it. Front end candidates will be given a small HTML/CSS problem nearing the end of the session.
  • For the Ninja rounds, you may be asked one to two questions depending on how fast you progress through the question.

43.1.5 Google

  • Recruiter phone screen.
  • Technical phone interview:
  • 1 or 2 x algorithm on Google Doc.
  • On-site (Front End):
  • 3 x Front end on whiteboard. Have to use Vanilla JS (or at the most, jQuery).
  • 2 x Algorithm on whiteboard.
  • Team matching.
  • Speak with managers from different teams who are interested in your profile.
  • Tips:
  • You are only allowed to use the whiteboard. No laptops involved.
  • In rare cases, candidates may even be allowed to skip the phone interview round and advanced to on-site directly.
  • For non-fresh grads, you only receive an offer if you are successfully matched with a team.

43.1.6 Lyft

  • Recruiter phone screen.
  • Technical phone interview:
  • 1 x Algorithm/Front end over JSFiddle.
  • On-site (Front End):
  • 4 x Front end on Coderpad/your own laptop. Use any language/framework.
  • 1 x Behavioural. Meet with an Engineering Manager and go through candidate’s resume.
  • Tips:
  • Can use whiteboard and/or laptop.
  • For front end coding, I opted to use React and had to set up the projects on the spot using create-react-app.

43.1.7 Palantir

  • Recruiter phone screen.
  • Technical phone interview:
  • 1 x Algorithm over HackerRank CodePair and Skype.
  • On-site (General):
  • 2 x Algorithm on whiteboard.
  • 1 x Decomposition (system design) on whiteboard.
  • On-site (Front End):
  • 1 x Front end on your own laptop. This session lasts about 1.5 hours. Use any library/framework.
  • 1 x Decomposition (system design) on whiteboard.
  • Tips:
  • I opted to use React and had to set up projects on the spot using create-react-app.
  • You may be asked to meet with Engineering Managers after the technical sessions and it’s not necessarily a good/bad thing.

43.1.8 WhatsApp

  • Recruiter phone screen.
  • Technical phone interview:
  • 2 x Algorithm over CoderPad.
  • On-site (Web Client Developer):
  • 4 x Algorithm on whiteboard.
  • Tips:
  • No front end questions were asked.
  • 1 of the interviewers is an Engineering Manager.

44 Negotiation

44.0.1 Ten Rules of Negotiation

Key points extracted from “Ten Rules for Negotiating a Job Offer” Part 1 and Part 2 by Haseeb Qureshi.

44.0.1.1 Get everything in writing

Note down EVERYTHING on your phone call with the recruiters as they may be helpful later on. Even if there are things that are not directly monetary, if they relate to the job, write them down. If they tell you “we’re working on porting the front-end to Angular,” write that down. If they say they have 20 employees, write that down. You want as much information as you can. You’ll forget a lot of this stuff, and it’s going to be important in informing your final decision.

44.0.1.2 Always keep the door open

Never give up your negotiating power until you’re absolutely ready to make an informed, deliberate final decision. This means your job is to traverse as many of these decision points as possible without giving up the power to continue negotiating. Very frequently, your interlocutor will try to trick you into making a decision, or tie you to a decision you didn’t commit to. You must keep verbally jiu-jitsu-ing out of these antics until you’re actually ready to make your final decision.

44.0.1.3 Information is power

To protect your power in the negotiation, you must protect information as much as possible. A corollary of this rule is that you should not reveal to companies what you’re currently making. So given this offer, don’t ask for more money or equity or anything of the sort. Don’t comment on any specific details of the offer except to clarify them. Companies will ask about your current compensation at different stages in the process—some before they ever interview you, some after they decide to make you an offer. But be mindful of this, and protect information.

“Yeah, [COMPANY_NAME] sounds great! I really thought this was a good fit, and I’m glad that you guys agree. Right now I’m talking with a few other companies so I can’t speak to the specific details of the offer until I’m done with the process and get closer to making a decision. But I’m sure we’ll be able to find a package that we’re both happy with, because I really would love to be a part of the team.”

44.0.1.4 Always be positive

Even if the offer is bad, it’s extremely important to remain positive and excited about the company. This is because your excitement is one of your most valuable assets in a negotiation.

Despite whatever is happening in the negotiation, give the company the impression that 1) you still like the company, and that 2) you’re still excited to work there, even if the numbers or the money or the timing is not working out. Generally the most convincing thing to signal this is to reiterate you love the mission, the team, or the problem they’re working on, and really want to see things work out.

44.0.1.5 Don’t be the decision maker

Even if you don’t particularly care what your friends/family/husband/mother thinks, by mentioning them, you’re no longer the only person the recruiter needs to win over. There’s no point in them trying to bully and intimidate you; the “true decision-maker” is beyond their reach. This is a classic technique in customer support and remediation. It’s never the person on the phone’s fault, they’re just some poor schmuck doing their job. It’s not their decision to make. This helps to defuse tension and give them more control of the situation.

I’ll look over some of these details and discuss it with my [FAMILY/CLOSE_FRIENDS/SIGNIFICANT_OTHER]. I’ll reach out to you if I have any questions. Thanks so much for sharing the good news with me, and I’ll be in touch!

It’s much harder to pressure someone if they’re not the final decision-maker. So take advantage of that.

44.0.1.6 Have alternatives

If you’re already in the pipeline with other companies (which you should be if you’re doing it right), you should proactively reach out and let them know that you’ve just received an offer. Try to build a sense of urgency. Regardless of whether you know the expiration date, all offers expire at some point, so take advantage of that.

Hello [PERSON],

I just wanted to update you on my own process. I’ve just received an offer from [COMPANY] which is quite strong. That said, I’m really excited about [YOUR AMAZING COMPANY] and really want to see if we can make it work. Since my timeline is now compressed, is there anything you can do to expedite the process?

Should you specifically mention the company that gave you an offer? Depends. If it’s a well-known company or a competitor, then definitely mention it. If it’s a no-name or unsexy company, you should just say you received an offer. If it’s expiring soon, you should mention that as well.

Either way, send out a letter like this to every single company you’re talking to. No matter how hopeless or pointless you think your application is, you want to send this signal to everyone who is considering you in the market.

Companies care that you’ve received other offers. They care because each company knows that their own process is noisy, and the processes of most other companies are also noisy. But a candidate having multiple offers means that they have multiple weak signals in their favor. Combined, these converge into a much stronger signal than any single interview. It’s like knowing that a student has a strong SAT score, and GPA, and won various scholarships. Sure, it’s still possible that they’re a dunce, but it’s much harder for that to be true.

This is not to say that companies respond proportionally to these signals, or that they don’t overvalue credentials and brands. They do. But caring about whether you have other offers and valuing you accordingly is completely rational.

Tell other companies that you’ve received offers. Give them more signals so that they know you’re a valued and compelling candidate. And understand why this changes their mind about whether to interview you.

Your goal should be to have as many offers overlapping at the same time as possible. This will maximize your window for negotiating.

Have a strong BATNA (Best Alternative To a Negotiated Agreement) and communicate it.

I ’ve received another offer from [OTHER CORP] that’s very compelling on salary, but I really love the mission of [YOUR COMPANY] and think that it would overall be a better fit for me.

I’m also considering going back to grad school and getting a Master’s degree in Postmodern Haberdashery. I’m excited about [YOUR COMPANY] though and would love to join the team, but the package has to make sense if I’m going to forego a life of ironic hatmaking.

44.0.1.7 Proclaim reasons for everything

It’s kind of a brain-hack, both for yourself and for your negotiating partner. Just stating a reason (any reason) makes your request feel human and important. It’s not you being greedy, it’s you trying to fulfill your goals.

The more unobjectionable and sympathetic your reason, the better. If it’s medical expenses, or paying off student loans, or taking care of family, you’ll bring tears to their eyes.

Just go with it, state a reason for everything, and you’ll find recruiters more willing to become your advocate.

44.0.1.8 Be motivated by more than just money

You should be motivated by money too of course, but it should be one among many dimensions you’re optimizing for. How much training you get, what your first project will be, which team you join, or even who your mentor will be—these are all things you can and should negotiate.

Of course, to negotiate well you need to understand the other side’s preferences. You want to make the deal better for both of you.

44.0.1.9 Understand what they value

Remember that you can always get salary raises as you continue to work at the company, but there’s only one point at which you can get a signing bonus.

The easiest thing for a company to give though is stock (if the company offers stock). Companies like giving stock because it invests you in the company and aligns interests. It also shifts some of the risk from the company over to you and burns less cash.

44.0.1.10 Be winnable

This is more than just giving the company the impression that you like them (which you continually should). But more so that you must give any company you’re talking to a clear path on how to win you. Don’t bullshit them or play stupid games. Be clear and unequivocal with your preferences and timeline.

Don’t waste their time or play games for your own purposes. Even if the company isn’t your dream company, you must be able to imagine at least some package they could offer you that would make you sign. If not, politely turn them down.

45 Psychological Tricks

Here are some psychological tricks that will help you ace a job interview.

  • Tailor your answers to the interviewer’s age.
  • Generation Y interviewers (between 20 and 30): Bring along visual samples of your work and highlight your ability to multitask.
  • Generation X interviewers (between 30 and 50): Emphasize your creativity and mention how work/life balance contributes to your success.
  • Baby Boomer interviewers (between 50 and 70): Show that you work hard and demonstrate respect for what they’ve achieved.
  • Hold your palms open or steeple your hands.
  • Find something in common with your interviewer.
  • Mirror the interviewer’s body language.
  • Compliment the interviewer and the organization without self-promoting.
  • Specifically, the students who ingratiated themselves praised the organization and indicated their enthusiasm for working there, and complimented the interviewer. They didn’t play up the value of positive events they took credit for or take credit for positive events even if they weren’t solely responsible.
  • Show confidence and deference simultaneously.
  • In a job interview, that means showing deference to your interviewer, while also demonstrating self-confidence. One way to do that is to say something like, “I love your work on [whatever area]. It reminds me of my work on [whatever area].”
  • Emphasize how you took control of events in your previous jobs.
  • To impress your interviewer, you should talk about past work experiences where you took initiative.
  • Be candid about your weaknesses.
  • It’s wiser to say something genuine like, “I’m not always the best at staying organized,” which sounds more honest, and could make your interviewer more inclined to recommend you for the position.
  • Speak expressively.
  • Showcase your potential.
  • You might be tempted to tell your interviewer all about your past accomplishments — but research suggests you should focus more on what you could do in the future, if the organization hires you.
45.0.0.0.0.1 References

46 Questions to Ask

Here are some good questions to ask at the end of the interview, extracted from various sources. The ones in bold are the ones that tend to make the interviewer go “That’s a good question” and pause and think for a bit.

46.0.1 General

  • What are you most proud about in your career so far?
  • What is the most important/valuable thing you have learnt from working here?
  • How do your clients and customers define success?
  • What would you change around here if you could?
  • What are some weaknesses of the organization?
  • What does a typical day look like for you?
  • What do you think the company can improve at?
  • How would you see yourself growing at this company in the next few years?
  • Was there a time where you messed up and how was it handled?
  • Why did you choose to come to this company?
  • When you were last interviewing, what were some of your other options, and what made you choose this company?
  • What was something you wish someone would have told you before you joined?
  • What was your best moment so far at the company?

46.0.2 Culture

  • What is the most frustrating part about working here?
  • What is unique about working at this company that you have not experienced elsewhere?
  • What is something you wish were different about your job?
  • How will the work I will be doing contribute to the organization’s mission?
  • What do you like about working here?
  • What is your policy on working from home/remotely?
  • (If the company is a startup) When was the last time you interacted with a founder? What was it regarding? Generally how involved are the founders in the day-to-day?
  • Does the company culture encourage entrepreneurship? Could you give me any specific examples?

46.0.3 Technical

These questions are suitable for any technical role.

  • What are the engineering challenges that the company/team is facing?
  • What has been the worst technical blunder that has happened in the recent past? How did you guys deal with it? What changes were implemented afterwards to make sure it didn’t happen again?
  • What is the most costly technical decision made early on that the company is living with now?
  • What is the most fulfilling/exciting/technically complex project that you’ve worked on here so far?
  • How do you evaluate new technologies? Who makes the final decisions?
  • How do you know what to work on each day?
  • How would you describe your engineering culture?
  • How has your role changed since joining the company?
  • What is your stack? What is the rationale for/story behind this specific stack?
  • Do you tend to roll your own solutions more often or rely on third party tools? What’s the rationale in a specific case?
  • How does the engineering team balance resources between feature requests and engineering maintenance?
  • What do you measure? What are your most important product metrics?
  • What does the company do to nurture and train its employees?
  • How often have you moved teams? What made you join the team you’re on right now? If you wanted to move teams, what would need to happen?
  • If you hire person, what do you have for him to study product you’re working on and processes in general? Do you have specifications, requirements, documentation?
  • There’s “C++” (or Python, Swift or any other tech) in the job description. How will you estimate my proficiency in this tech in 3 months?

46.0.4 Product

  • Tell me about the main products of your company.
  • What is the current version of product? (If it is v1.0 or similar - there could be a lot of chaos to work with)
  • What products are your main competitors?
  • What makes your product competitive?
  • When are you planning to provide the next release? (If in several months, it would mean a lot of requirements specified in job description are not needed right now)

46.0.5 Management

These questions are suitable for asking Engineering Managers, especially useful for the Team Matching phase of Google interviews or post-offer calls that your recruiters set up with the various team managers.

  • How do you train/ramp up engineers who are new to the team?
  • What does success look like for your team?
  • What qualities do you look out for when hiring for this role?
  • What are the strengths and weaknesses of the current team? What is being done to improve upon the weaknesses?
  • Can you tell me about a time you resolved an interpersonal conflict?
  • How did you become a manager?
  • How do your engineers know what to work on each day?
  • What is your team’s biggest challenge right now?
  • How do you measure individual performance?
  • How often are 1:1s conducted?
  • What is the current team composition like?
  • What opportunities are available to switch roles? How does this work?

46.0.6 Leadership

These questions are intended for senior level management, such as CEO, CTO, VPs. Candidates who interview with startups usually get to speak with senior level management.

  • How are you funded?
  • Are you profitable? If no, what’s your plan for becoming profitable?
  • What assurance do you have that this company will be successful?
  • Tell me about your reporting structure.
  • How does the company decide on what to work on next?

46.0.7 HR

  • How do you see this position evolving in the next three years?
  • Who is your ideal candidate and how can I make myself more like them?
  • What concerns/reservations do you have about me for this position?
  • What can I help to clarify that would make hiring me an easy decision?
  • How does the management team deal with mistakes?
  • If you could hire anyone to join your team, who would that be and why?
  • How long does the average engineer stay at the company?
  • Why have the last few people left?
  • Have you ever thought about leaving? If you were to leave, where would you go?
46.0.7.0.0.1 References

47 Resume

The following content is by Christina Ng and rephrased for the purpose of this handbook. You can follow her on Medium or Quora.

47.1 Table of Contents

  1. How Your Resume is Screened
  2. 10 Ways To Improve Your Resume

47.2 How Your Resume is Screened

While many engineers can be rather qualified for the role they are applying for, they miss out on getting a shot at the interview as they might never get past resume screening. The main issue was that they do not understand how recruiters worked.

Before writing your resume, it is important to understand the recruiting structure and how recruiting is done.

47.2.1 The Skill Set Checklist

Before opening up a position/starting the search for candidates, I usually consult very closely with the team manager/decision maker to find out the specific skill sets that are relevant for the position. These skill sets are typically grouped into “Must have”, “Good to have”, and “Special bonus”.

  • “Must have” — Typically, most of the must-haves include a degree (or not) in a relevant technical field, some years (or not) of experience in a particular programming language or technology.
  • “Good to have” — Includes experience/familiarity with secondary languages/technologies which may not be directly relevant to what the candidate would be working on, but could be required due to some interfacing with other components of the project. It could also include softer skills such as being a good team player, clear communication, etc.
  • “Special bonus” — Recognized skill sets/experiences which are difficult to come by. Probably not a requirement, but would definitely be useful for the position.

Now that I am armed with this list, the search for candidates begin.

Typically, I do not seek that “one perfect candidate”. What I seek for is the “best fit candidate”. The search is essentially a numbers game. I know that for a specific job posting, there would perhaps be X applicants. At each stage of the interview process, some percentage of the candidates will be eliminated, leaving only a final Y% of the initial pool to choose from. Since Y tends to be a rather small number, recruiters will try to maximize X.

47.2.2 The 10 Seconds Glance

When I am looking at your resume, I am doing a keyword match against the skill set checklist. If I see a good amount of the right keywords in your resume, it is a pass. If I need to spend more than 10 seconds trying to figure out what you are writing about, it is a fail. If I see an excessive amount of keywords (much looking like spam), it signals a red flag and goes into the “maybe”. Depending on whether I think I have enough candidates for the day, you could eventually go into the pass or fail stack.

There are lots of articles writing about how recruiters only spend an average of about 10 seconds to screen each resume. The news is, this is true because resume screening is such a menial, robotic and repetitive task. In fact, many applicant tracking systems (ATS) now are so advanced that they can parse your resume automatically, search for specific keywords in your resume, and score your resume based on the weights pre-assigned to each keyword.

Finding a job is a two-way fit — the company wants someone with the relevant skills required, but it is also important for the applicant to fit in the company culture, and be able to gain something out of his stint. Hence, honesty is the single most important criteria in a resume.

There is a delicate balance between finding the right job vs. finding a job. Getting rejected does not always mean you are not good enough. Sometimes, it just means you are not a right fit for what the company is looking for.

When hiring fresh grads, I know that many of them will not have as much experience as someone who has years of industry experience. Hence, I would look out more for soft skills, such as attention to detail, initiative, passion, ability to get things done, etc. Note: this applies only if you have met the minimum threshold of proficiency/competency in the skill set checklist.

47.3 10 Ways To Improve Your Resume

Now that you are aware of how recruiters screen your resume, here are 10 actionable ways you can do to improve your resume.

47.3.0.1 1. Cover letter

I’ve often received resumes with no cover letters, and I am perfectly fine with it. If you ask me, it is better to have no cover letter than to have a bad cover letter, especially if your cover letter is a “templated” content. An effective cover letter needs to highlight the fit between the job requirements and your skills/experiences. Do not just tell me what you have done in your cover letter; Tell me how it is a fit for what I am looking for.

Some small nitpicks:

  • Make sure that the cover letter is addressed to the right person (either the name of the recruiter if it is known, or to a generic hiring manager) and company.
  • Run a spell check.

47.3.0.2 2. Length of resume

Your resume should be kept to 1 page or a MAXIMUM of 2 pages. Include only your most recent and relevant experiences.

Information that a recruiter wants to know:

  • Name, email, contact number.
  • Education details: College, Major, GPA, Sample classes (optional, but if you list, make sure its classes that you scored well in and are relevant to your area of interest), academic awards, availability.
  • If you have studied abroad, you can list that too.
  • Projects that you have worked on.
  • Work experience/co-curricular activities.
  • Skills/other interests.
  • Street cred - GitHub/StackOverflow/LinkedIn profile (optional, but highly recommended).

Information nobody needs to know:

  • Your profile picture.
  • Address, home phone number, gender, religion, race, marital status, etc etc.
  • Elementary, middle, high school.
  • Your low GPA.
  • Anything less recent than 3-4 years unless they are valid job experiences.
  • Anything about your parents/siblings, their names, occupation, etc.
  • Your life story.
  • Anything not relevant to the job you are applying for (e.g. that you have a driving license when you are applying to be a programmer).

Ideally, keep it short, concise, but as detailed as possible.

47.3.0.3 3. GPA does matter

Everyone wants the cream of the crop. In the absence of a standardized test, GPA serves as that indicator. While GPA may not necessarily be a good indication of how well you can code, a high GPA would definitely put you in a more favorable position to the recruiter.

If your GPA is rather low, but you have loads of technical experiences, you can try not listing your GPA in the resume. This kinda “forces” the recruiter to read through your projects/job experience, and perhaps grant you a first interview. If you manage to impress them, who cares about your GPA? But if your GPA is low and you do not have skills for the job… maybe you should work on one of them and revisit job applications later.

In a different scenario, some students have low GPA, but it might be due to some irrelevant classes which they did badly in. E.g. Student X is scoring A for all his programming classes, but did not do well for his language classes. If I am hiring a developer, Student X would still be a suitable candidate despite his low GPA. In such cases, it might even be recommended to attach a transcript along with the resume.

Also, when you list your GPA/results, try to benchmark it. Instead of simply listing 4.6, write 4.6/5.0 (First Class Honors or Summa Cum Laude). To the recruiter, 4.6 does not mean anything if he/she is not familiar with your grading system.

47.3.0.4 4. Be clear about your objectives

Are you looking for a summer internship/full-time employment? What position are you applying for? Read the job description and know the job you are applying for!!

“Work experience” does not mean any work experience; it means relevant work experience. If you are applying for a developer position, the recruiter is not interested to know that you were a student escort for girls walking back to their apartments at night, nor that you were a cashier at Starbucks. You would be better off writing about the project you did for some programming class - yes, even if it was just a school project. Tailor your experiences and projects according to the job you are applying for. Pick relevant details to emphasize on and do not be hesitant to drop stuff completely if they are totally irrelevant. Quality over quantity.

  • Make sure the description is comprehensive. Avoid writing “Software engineering intern - write code”. You are better off not writing anything.
  • Based on my experience, most fresh grads do not have extremely relevant job experience (unless you are lucky to have scored a really rewarding internship). For developer positions, I think it is ok to not have any job experience and just list projects.

47.3.0.5 5. Reverse chronological order

Always list your resume in reverse chronological order - the most recent at the top. Recruiters are more interested in what you have worked on recently than what you worked on 3 years ago. Chances are, you probably forgot the details too anyway.

47.3.0.6 6. Make sure you are contactable

  • Get a proper email account with ideally your first name and last name, eg. " instead of .
  • If you are using your school’s .edu email, try to have an alias like " instead of .
  • Avoid emails like " or “admin@[mycooldomain].com” – because it is very prone to typo errors.
  • Make sure the number you have listed is the best way to reach you. The last thing you want is to miss the call from the recruiter because you typed the wrong number, or you are not available on that number during office hours (most probably the times the recruiter will call).

47.3.0.7 7. Layout/Formatting/Design

  • Be consistent about the way you format your resume. Italics, underline, bold, and how they are used.
  • Keep to a single standard font (avoid fancy fonts like Comic Sans or whatever) and do not have too many varying styles/font sizes/color
  • Be consistent about the way you list your dates (eg. May 2011 - Aug 2011). Avoid using numerals for both month and date due to the difference in style for MMDD and DDMM in different countries. Dates like “Aug 2011 - June 12” just show that you have zero attention to detail.
  • Unless you are applying for a design job, just stick to the standard “table” style for the resume. There is nothing wrong with the standard style, and it helps the recruiter screen your resume more efficiently since they are trained through experience to read that format. It would also help in the automatic scoring by the ATS. The last thing you want is for your application to be rejected because the system could not parse your resume for it to be scored. That said, I am not discouraging you from coming up with your own design. It is nice to read something different. Just be aware of the risks you could be taking.
  • Name your file firstname_lastname_resume.pdf instead of resume.pdf - it is easier for recruiters to search/forward.
  • PDF preferred over Word doc.
  • Be consistent about bullet points.
  • Your resume should not look sparse. (Come on, it is only 1 page!) If you really have trouble filling it up, you are either not thinking hard enough, or not doing enough. In the case of the latter, consider working on your personal projects (i.e. stuff you can post on GitHub). That said, do not write stuff just to fill space. Read point 4.
  • This should be common sense, but do not commit fraud, i.e. apply for the same job using a different name, or using your friend’s resume to apply for the same job. Some ATS issues an indicator if they suspect the application to be a duplicate.
  • It’s important to note the layout of your resume. If you choose to quickly upload your resume via an auto-fill program, understand that the program will read your resume from top to bottom, left to right. This is good to keep in mind when developing the layout of your resume.
  • Try to keep white space down to a minimum. This will also help reduce the length of your resume to one page. Reduce margins and paddings reasonably.

47.3.0.8 8. Listing Your skills

It is useful to list your relevant skills in a quick summary section for easy reading/matching. However, many people make the mistake of listing as many skills/programming languages in the resume as possible. This may get you through the ATS scoring, but it definitely would not leave a good impression on the recruiter - the actual human reading your resume and deciding whether to call you up for an interview!

Ideally, if your resume is good enough, the recruiter should already know what you are proficient in. The skills section is just a quick summary/reiteration. Listing a bunch of technologies you claim you know without actually showing how you have worked with them is pointless.

47.3.0.9 9. Projects

  • Ideally, 1-2 lines about the project, 2-3 lines about your role, what technologies you used, what you did, your learning, etc etc. These can be Final Year Projects, Research projects, projects for a particular class, freelance projects, or just personal projects (ie. GitHub stuff).
  • Ideally, 2 to 3 projects that align with your interests/position you are applying for.
  • Avoid using titles such as “Project for [module code]”. Sorry, the recruiter has no idea what class is represented by the module code.
    Ideally, you want the project section to demonstrate your personality and skills, and be the talking point during the interview.

47.3.0.10 10. Online profile/other interests

Here’s the news - Recruiters do search for your name! Definitely pre-empt that by Googling/Facebook-ing/searching yourself on all forms of social media to see what turns up. Make sure your privacy settings are restricted so your online profile shows only the image you are trying to project.

If you have some space on your resume, it is good to list additional interests outside of coding. Eg. skiing, water sports, soccer, etc etc. Gives the interviewer something to talk to you about. It also shows that you are a well-rounded individual/cool person to hang out with.

47.3.0.10.0.1 References

48 Self Introduction

You can rephrase the question like this:

“Tell me about your journey into tech. How did you get interested in coding, and why was web development a good fit for you? How is that applicable to our _____ role or company goals?”

48.0.1 The Elevator Pitch

The Elevator Pitch is an indispensable tool for you as you move forward in your career. An Elevator Pitch is just that – you pitch yourself to an executive that you want to impress and only have a short elevator ride to do so. Whether you’re at a job fair with hundreds of other candidates and you have limited time or you are simply explaining who you are to a potential connection or client, it is important to be able to clearly and accurately describe your knowledge and skillset quickly and succinctly. Here are some tips to develop a good Elevator Pitch:

  • Sell yourself
  • The whole point of this is to get you a job or make a connection that benefits your career.
  • Tell them who you are, who you work for (or school and major), and what you do.
  • KISS (Keep It Simple, Stupid)
  • Tell them some highlights from your favorite / most impressive projects.
  • Do not delve into the depths of how you reverse engineered a game and decrypted a packet to predict when to use your DKP on a drop. Tell them the executive summary: “I reverse engineered X game by decrypting Y packet to predict Z.” If this catches their interest, they will ask further questions on their own.
  • Why do they want you?
  • This is where you use your knowledge of the company, knowledge of their technology stack(s), your unique talent that they want, etc. in order to solidify your ability to contribute to their company.
  • PRACTICE!
  • Lastly, you must practice your pitch! Having a great, succinct summary of your skills only helps if you can actually deliver it rapidly! You should practice keeping a quick but easy-to-follow pace that won’t overwhelm them but won’t bore them. It’s a precarious balance, but can be ironed out with practice.

Having an Elevator Pitch on hand is a great way to create a network and happen upon new job opportunities. There will often be times when you can’t prepare for an interview or meeting, and it is incredibly handy to have a practiced pitch.

48.0.1.0.0.1 References

49 Preparing for a Coding Interview

49.0.1 Picking a Programming Language

Before anything else, you need to pick a programming language to do your interviews in. Most companies will let you code in any language you want, the only exception I know being Google, where they only allow candidates to pick from Java, C++ or Python for their algorithmic coding interviews. Most of the time, I would recommend that you use a language that you are extremely familiar with rather than picking up a new language just for doing interviews because the company uses that language heavily.

There are some languages which are more suitable than others for coding interviews and some languages you absolutely want to avoid. From my experience interviewing as an interviewer, most candidates pick Python or Java. Other commonly seen languages include JavaScript, Ruby and C++. I would absolutely avoid lower level languages like C or Go, simply because they lack in many standard library functions and data structures.

Personally, Python is my de facto choice for coding algorithms during interviews because it is succinct and has a pretty huge library of functions and data structures available. One of my top reasons for recommending Python is that it uses consistent APIs that operate on different data structures, such as len(), for ... in ... and slicing notation on sequences (strings/lists/tuples). Getting the last element in a sequence is arr[-1] and reversing it is simply arr[::-1]. You can achieve a lot with minimal syntax in Python.

Java is a decent choice too but having to constantly declare types in your code means extra keystrokes which results in slower coding/typing speed. This issue will be more apparent when you have to write on a whiteboard during on-site interviews. The reasons for choosing/not choosing C++ are similar to Java. Ultimately, Python, Java and C++ are decent choices of languages. If you have been using Java at work for a while now and do not have time to be comfortably familiar with another language, I would recommend just sticking to Java instead of picking up Python from scratch just for interviews to avoid having to context switch between languages during work vs interviews. Most of the time, the bottleneck is in the thinking and not the writing.

One exception to the convention of allowing you to “pick any programming language you want” is when you are interviewing for a domain-specific position, such as Front End/iOS/Android Engineer roles, in which you would need to be familiar with coding algorithms in JavaScript, Objective-C/Swift and Java respectively. If you need to use a data structure that the language does not support, such as a Queue or Heap in JavaScript, perhaps try asking the interviewer whether you can assume that you have a data structure that implements certain methods with specified time complexities. If the implementation of that data structure is not crucial to solving the problem, the interviewer will usually allow it. In reality, being aware of existing data structures and selecting the appropriate ones to tackle the problem at hand is more important than knowing the intricate implementation details.

49.0.2 Review your CS101

If you have been out of college for a while, it is highly advisable to review CS fundamentals — Algorithms and Data Structures. Personally, I prefer to review as I practice, so I scan through my college notes and review the various algorithms as I work on algorithm problems from LeetCode and Cracking the Coding Interview.

This interviews repository by Kevin Naughton Jr. served as a quick refresher for me.

The Medium publication basecs by Vaidehi Joshi is also a great and light-hearted resource to recap on the various data structures and algorithms.

If you are interested in how data structures are implemented, check out Lago, a Data Structures and Algorithms library for JavaScript. It is pretty much still WIP but I intend to make it into a library that is able to be used in production and also a reference resource for revising Data Structures and Algorithms.

49.0.3 Mastery through Practice

Next, gain familiarity and mastery of the algorithms and data structures in your chosen programming language:

  1. Practice coding algorithms using your chosen language. While Cracking the Coding Interview is a good resource for practice, I prefer being able to type code, run it and get instant feedback. There are various Online Judges such as LeetCode, HackerRank and CodeForces for you to practice questions online and get used to the language. From experience, LeetCode questions are the most similar to the kind of questions being asked in interviews whereas HackerRank and CodeForces questions are more similar to competitive programming questions. If you practice enough LeetCode questions, there is a good chance that you would have seen/done your actual interview question (or some variant) on LeetCode before.
  2. Learn and understand the time and space complexities of the common operations in your chosen language. For Python, this page will come in handy. Also find out the underlying sorting algorithm that is being used in the language’s sort() function and its time and space complexity (in Python its Timsort which is a hybrid sort). After completing a question on LeetCode, I usually add the time and space complexities of the written code as comments above the function body to remind myself to analyze the algorithm after I am done with the implementation.
  3. Read up on the recommended coding style for your language and stick to it. If you have chosen Python, refer to the PEP 8 Style Guide. If you have chosen Java, refer to Google’s Java Style Guide.
  4. Find out and be familiar with the common pitfalls and caveats of the language. If you point out them out during the interview and intelligently avoid falling into them, you will usually impress the interviewer and that results in bonus points in your feedback, regardless of whether the interviewer is familiar with the language or not.
  5. Gain a broad exposure to questions from various topics. In the second half of the article I mention algorithm topics and practice questions for each topic. Do around 100–200 LeetCode questions and you should be good.

Practice, practice and more practice!

49.0.4 Phases of a Coding Interview

Congratulations, you are ready to put your skills into practice! In a real coding interview, you will be given a technical question by the interviewer, write code in a real-time collaborative editor (phone screen) or on a whiteboard (on-site) to solve the problem within 30–45 minutes. This is where the real fun begins!

Your interviewer will be looking out for signals that you fit the requirements of the role and it is up to you to display those signals to them. Initially it may feel weird to be talking while you are coding as most programmers do not have the habit of explaining out loud as they are typing code. However, it is hard for the interviewer to know what you are thinking just by looking at the code that you type. If you communicate your approach to the interviewer before you start coding, you can validate your approach with them and the both of you can agree upon an acceptable approach.

Before the Interview (Remote)

For phone screens/remote interviews, prepare paper and pen/pencil to jot down and visualize stuff. If you are given a question on trees and graphs, it usually helps if you draw out some examples of the data structure given in the question.

Use earphones and make sure you are in a quiet environment. You definitely do not want to be holding a phone in one hand and only be able to type with the other. Try avoiding using speakers because if the echo is bad, communication is harder and repeating of words will just result in loss of valuable time.

Self Introduction

TODO

Upon Getting the Question

Many candidates jump into coding the moment they hear the question. That is usually a big mistake. Take a moment to repeat the question back at the interviewer and make sure that you understand exactly what they are asking. If you misunderstood and when you repeat back the question, they will clarify.

Always seek clarification about the question upon hearing it even if it you think it is clear to you. You might discover something that you have missed out and it also sends a signal to the interviewer that you are a careful person who pays attention to details. Some interviewers deliberately omit important details to see if you ask the right questions. Consider asking the following questions:

  • How big is the size of the input?
  • How big is the range of values?
  • What kind of values are there? Are there negative numbers? Floating points? Will there be empty inputs?
  • Are there duplicates within the input?
  • What are some extreme cases of the input?
  • How is the input stored? If you are given a dictionary of words, is it a list of strings or a Trie?

After you have sufficiently clarified the scope and intention of the problem, explain your high level approach to the interviewer even if it is a naive solution. If you are stuck, consider various approaches and explain out loud why it will/will not work. Sometimes your interviewer might drop hints and lead you towards the right path.

Start with a brute force approach, communicate it to the interviewer, explain the time and space complexity and why it is bad. It is unlikely that the brute force approach will be one that you will be coding. At this point, the interviewer will usually pop the dreaded “Can we do better?” question, meaning that they are looking for a more optimal approach. In my opinion, this is usually the hardest part of the interview. In general, look for repeated work and try to optimize them by potentially caching the calculated result somewhere and reference it later, rather than having to compute it all over again. There are some tips on tackling topic-specific questions that I dive into details below.

Only start coding after you and your interviewer have agreed on an approach and has given you the green light.

Starting to Code

Write your code with good coding style. Reading code written by others is usually not an enjoyable task. Reading horribly-formatted code by others makes it worse. Your goal is to make your interviewer understand the code you have written so that they can quickly evaluate if your code does what you say it does and whether it solves the given problem. Use clear variable names, avoid single letter names unless they are for iteration. However, if you are coding on a whiteboard, you might not want to use extremely verbose variable names for the sake of reducing the amount you have to write.

Always be explaining what you are currently writing/typing to the interviewer. This is not about literally reading out what you are typing to the interviewer. Talk about the section of the code you are currently implementing at a higher level, explain why it is written as such and what it is trying to achieve.

When you copy and paste code, consider whether it is necessary. Sometimes it is, sometimes it is not. If you find yourself copying and pasting one large chunk of code spanning multiple lines, it is probably an indicator that you can refactor by containing those lines into a function. If it is just a single line you copied, usually it is fine. Do remember to change the respective variables in your copied line of code where relevant. Copy-paste errors are a common source of bugs even in day-to-day coding!

After Coding

After you have finished coding, do not immediately announce to the interviewer that you are done. In most cases, your code is usually not perfect and contains some bugs or syntax errors. What you need to do now is to review your code.

Firstly, look through your code from start to finish as if it is the first time you are seeing it, as if it was written by someone else and you are trying to spot bugs in it. That’s exactly what your interviewer will be doing. Look through and fix any minor issues you may find.

Next, come up with small test cases and step through the code (not your algorithm!) with those sample input. Interviewers like it when you read their mind and what they usually do after you have finished coding would be to get you to write tests. It is a huge plus if you write tests for your code even before prompts from them. You should be emulating a debugger when stepping through and jot down or say out the values of certain variables as you step through the lines of code.

If there are huge duplicated chunks of code in your solution, it would be a good chance to refactor it and demonstrate to the interviewer that you are one who values code quality. Also look out for places where you can do short-circuit evaluation.

Lastly, give the time/space complexity of your code and explain why it is such. You can even annotate certain chunks of your code with the various time/space complexities to demonstrate your understanding of your code and the APIs of your chosen programming language. Explain any trade-offs in your current approach vs alternative approaches, possibly in terms of time/space.

If your interviewer is happy with the solution, the interview usually ends here. It is also not uncommon that the interviewer asks you extension questions, such as how you would handle the problem if the whole input is too large to fit into memory, or if the input arrives as a stream. This is a common follow-up question at Google where they care a lot about scale. The answer is usually a divide-and-conquer approach — perform distributed processing of the data and only read certain chunks of the input from disk into memory, write the output back to disk and combine them later on.

49.0.5 Practicing via Mock Interviews

Interviewing is a skill that you can get better at. The steps mentioned above can be rehearsed over and over again until you have fully internalized them and following those steps become second nature to you. A good way to practice is to find a friend to partner with and the both of you can take turns to interview each other.

A great resource for practicing mock coding interviews would be interviewing.io. interviewing.io provides free, anonymous practice technical interviews with Google and Facebook engineers, which can lead to real jobs and internships. By virtue of being anonymous during the interview, the inclusive interview process is de-biased and low risk. At the end of the interview, both interviewer and interviewees can provide feedback to each other for the purpose of improvement. Doing well in your mock interviews will unlock the jobs page and allow candidates to book interviews (also anonymously) with top companies like Uber, Lyft, Quora, Asana and more. For those who are totally new to technical interviews, you can even view a demo interview on the site (requires sign in). Read more about them here.

I have used interviewing.io both as an interviewer and an interviewee and found the experience to be really great! Aline Lerner, the CEO and co-founder of interviewing.io and her team are passionate about revolutionizing the technical interview process and helping candidates to improve their skills at interviewing. She has also published a number of technical interview-related articles on the interviewing.io blog. interviewing.io is still in beta now but I recommend signing up as early as possible to increase the likelihood of getting an invite.

Another platform that allows you to practice coding interviews is Pramp. Where interviewing.io matches potential job seekers with seasoned technical interviewers, Pramp takes a different approach. Pramp pairs you up with another peer who is also a job seeker and both of you take turns to assume the role of interviewer and interviewee. Pramp also prepares questions for you, along with suggested solutions and prompts to guide the interviewee.

Personally, I am not that fond of Pramp’s approach because if I were to interview someone, I would rather choose a question I am familiar with. Also, many users of the platform do not have the experience of being interviewers and that can result in a horrible interview experience. There was once where my matched peer, as the interviewer, did not have the right understanding of the question and attempted to lead me down the wrong path of solving the question. However, this is more of a problem of the candidate than the platform though.

49.0.6 Conclusion

Coding interviews are tough. But fortunately, you can get better at them by studying and practicing for them, and doing mock interviews.
To recap, to do well in coding interviews:

  1. Decide on a programming language
  2. Study CS fundamentals
  3. Practice solving algorithm questions
  4. Internalize the Do’s and Don’ts of interviews
  5. Practice doing mock interviews
  6. Interview successfully to get the job

By following these steps, you will improve your coding interview skills, and be one step closer (or probably more) to landing your dream job.

All the best!

50 Interview Cheatsheet

This is a straight-to-the-point distilled list of technical interview Do’s and Don’ts, mainly for algorithmic interviews. Some of these may apply to only phone screens on whiteboard interviews but most will apply to both. I revise this list before each of my interviews to remind myself of them and eventually internalized all of them to the point I do not have to rely on it anymore.

For a detailed walkthrough of interview preparation, refer to the “Preparing for a Coding Interview” section.

Legend: ✅ = Do, ❌ = Don’t, ⚠️ = Situational

50.0.1 1. Before Interview

Things
Prepare pen, paper and earphones/headphones.
Find a quiet environment with good Internet connection.
Ensure webcam and audio are working. There were times I had to restart Chrome to get Hangouts to work again.
Request for the option to interview over Hangouts/Skype instead of a phone call; it is easier to send links or text across.
Decide on and be familiar with a programming language.
Familiarize yourself with the coding environment (CoderPad/CodePen). Set up the coding shortcuts, turn on autocompletion, tab spacing, etc.
Prepare answers to the frequently-asked questions in an interview.
Prepare some questions to ask at the end of the interview.
Dress comfortably. Usually you do not need to wear smart clothes, casual should be fine. T-shirts and jeans are acceptable at most places.
Stay calm and composed.
⚠️ Turn off the webcam if possible. Most remote interviews will not require video chat and leaving it on only serves as a distraction.

50.0.2 2. Introduction

Things
Introduce yourself in a few sentences under a minute or two.
Mention interesting points that are relevant to the role you are applying for.
Sound enthusiastic! Speak with a smile and you will naturally sound more engaging.
Spend too long introducing yourself. The more time you spend talk the less time you have to code.

50.0.3 3. Upon Getting the Question

Things
Repeat the question back at the interviewer.
Clarify any assumptions you made subconsciously. Many questions are under-specified on purpose. A tree-like diagram could very well be a graph that allows for cycles and a naive recursive solution would not work.
Clarify input format and range. Ask whether input can be assumed to be well-formed and non-null.
Work through a small example to ensure you understood the question.
Explain a high level approach even if it is a brute force one.
Improve upon the approach and optimize. Reduce duplicated work and cache repeated computations.
Think carefully, then state and explain the time and space complexity of your approaches.
If stuck, think about related problems you have seen before and how they were solved. Check out the tips in this section.
Ignore information given to you. Every piece is important.
Jump into coding straightaway.
Start coding without interviewer’s green light.
Appear too unsure about your approach or analysis.

50.0.4 4. During Coding

Things
Explain what you are coding/typing to the interviewer, what you are trying to achieve.
Practice good coding style. Clear variable names, consistent operator spacing, proper indentation, etc.
Type/write at a reasonable speed.
As much as possible, write actual compilable code, not pseudocode.
Write in a modular fashion. Extract out chunks of repeated code into functions.
Ask for permission to use trivial functions without having to implement them; saves you some time.
Use the hints given by the interviewer.
Demonstrate mastery of your chosen programming language.
Demonstrate technical knowledge in data structures and algorithms.
If you are cutting corners in your code, state that out loud to your interviewer and say what you would do in a non-interview setting (no time constraints). E.g., I would write a regex to parse this string rather than using split() which may not cover all cases.
Practice whiteboard space-management skills.
⚠️ Reasonable defensive coding. Check for nulls, empty collections, etc. Can omit if input validity has been clarified with the interviewer.
Remain quiet the whole time.
Spend too much time writing comments.
Use extremely verbose variable names.
Copy and paste code without checking.
Interrupt your interviewer when they are talking. Usually if they speak, they are trying to give you hints or steer you in the right direction.
Write too big (takes up too much space) or too small (illegible) if on a whiteboard.

50.0.5 5. After Coding

Things
Scan through your code for mistakes as if it was your first time seeing code written by someone else.
Check for off-by-one errors.
Come up with more test cases. Try extreme test cases.
Step through your code with those test cases.
Look out for places where you can refactor.
Reiterate the time and space complexity of your code.
Explain trade-offs and how the code/approach can be improved if given more time.
Immediately announce that you are done coding. Do the above first!
Argue with the interviewer. They may be wrong but that is very unlikely given that they are familiar with the question.

50.0.6 6. Wrap Up

Things
Ask questions. More importantly, ask good and engaging questions that are tailored to the company! Pick some questions from this list.
Thank the interviewer.
⚠️ Ask about your interview performance. It can get awkward.
End the interview without asking any questions.

50.0.7 7. Post Interview

Things
Record the interview questions and answers down as these can be useful for future reference.
⚠️ Send a follow up email to your interviewer(s) thanking them for their time and the opportunity to interview with them.
50.0.7.0.0.1 References

51 Contributor Covenant Code of Conduct

51.1 Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

51.2 Our Standards

Examples of behavior that contributes to creating a positive environment include:

  • Using welcoming and inclusive language
  • Being respectful of differing viewpoints and experiences
  • Gracefully accepting constructive criticism
  • Focusing on what is best for the community
  • Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

  • The use of sexualized language or imagery and unwelcome sexual attention or advances
  • Trolling, insulting/derogatory comments, and personal or political attacks
  • Public or private harassment
  • Publishing others’ private information, such as a physical or electronic address, without explicit permission
  • Other conduct which could reasonably be considered inappropriate in a professional setting

51.3 Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

51.4 Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

51.5 Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at . The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project’s leadership.

51.6 Attribution

This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4

<h1 align=“center”>Tech Interview Handbook</h1>

<div align=“center”>
<a href=“https://dribbble.com/shots/3831443-Tech-Interview-Handbook”>
<img src=“https://cdn.rawgit.com/yangshun/tech-interview-handbook/master/assets/book.svg” alt=“Tech Interview Handbook” width=“400”/>
</a>
<br>
<p>
<em>Credits: <a href=“https://dribbble.com/shots/3831443-Tech-Interview-Handbook”>Illustration</a> by <a href=“https://dribbble.com/yangheng”>@yangheng</a>
</em>
</p>
</div>

51.7 What is this?

Carefully curated content to help you ace your next technical interview, with a focus on algorithms and the front end domain. System design questions are in-progress. Besides the usual algorithm questions, other awesome stuff includes:

This handbook is pretty new and help from you in contributing content would be very much appreciated!

51.8 Why do I want this?

This repository has practical content that covers all phases of a technical interview; from applying for a job to passing the interviews to offer negotiation. Technically competent candidates might still find the non-technical content helpful as well.

51.9 Who is this for?

Anybody who wants to land a job at a tech company but is new to technical interviews, seasoned engineers who have not been on the other side of the interviewing table in a while and wants to get back into the game, or anyone who wants to be better at technical interviewing.

51.10 How is this repository different?

There are so many awesome books like Cracking the Coding Interview and interview-related repositories out there on GitHub, what makes this repository different? The difference is that many existing interview repositories contain mainly links to external resources whereas this repository contains top quality curated content directly for your consumption.

Also, existing resources focus mainly on algorithm questions and lack in coverage for more domain-specific and non-technical questions. This handbook aims to cover content beyond the typical algorithmic coding questions. 😎

51.11 Contents

If you are interested in how data structures are implemented, check out Lago, a Data Structures and Algorithms library for JavaScript. It is pretty much still WIP but I intend to make it into a library that is able to be used in production and also a reference resource for revising Data Structures and Algorithms.

51.13 Contributing

There are no formal contributing guidelines at the moment as things are still in flux and we might find a better approach to structure content as we go along. You are welcome to contribute whatever you think will be helpful to fellow engineers. If you would like to contribute content for different domains, feel free to create an issue or submit a pull request and we can discuss further.

51.14 Maintainers

© https://gittobook.org, 2018. Unauthorized use and/or duplication of this material without express and written permission from this author and/or owner is strictly prohibited. Excerpts and links may be used, provided that full and clear credit is given to this site, with appropriate and specific direction to the original content.
Table