Skip to content

Commit 7f4b625

Browse files
author
Jessica Yung
committed
feat: add programming flashcards and delete prev crude version
1 parent c9fea54 commit 7f4b625

9 files changed

+266
-4
lines changed

flashcards/algorithms.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
What is a binary search algorithm?; 1. Start with the middle item. Is it bigger or smaller than our target item? Since the list is sorted, this tells us if the target is in the first or second half of our list. 2. Rule out the half of the list that doesn’t contain the target item. 3. Repeat the same approach on the new half-size problem. Do it again and again until we either find the item or rule out the whole set.
2+
3+
4+
What is the runtime complexity of a binary search algorithm?; For a sorted array: O(lg n).
5+
6+
7+
Code an iterative binary search algorithm; def binary_search(target, nums): floor_index = -1 \ ceiling_index = len(nums) \ while floor_index + 1 < ceiling_index: distance = ceiling_index - floor_index \ half_distance = distance / 2 \ guess_index = floor_index + half_distance \ guess_value = nums[guess_index] \ if guess_value == target: return True \ if guess_value > target: ceiling_index = guess_index \ else: floor_index = guess_index \\ return False
8+
9+
10+
Code a recursive binary search algorithm;
11+
12+
13+
When can’t we use binary search to our usual effect?; When the input list is not yet sorted.
14+
15+
16+
How many binary searches would it take to find an element out of a list of 100 sorted items?; 7. (Check.)
17+
18+
19+
Counting Sort
20+
What is a counting sort algorithm?; (1) Allocate a list nums_to_counts where the indices represent numbers from our input list and the values represent how many times the index number appears. Start each value at 0. (2) In one pass of the input list, update nums_to_counts as you go, so that at the end the values in nums_to_counts are correct. (3) Allocate a list sorted_list where we'll store our sorted numbers. (4) In one in-order pass of nums_to_counts put each number, the correct number of times, into sorted_list.
21+
22+
23+
Runtime and space complexity of counting sort algorithm; O(n) for both time and space.
24+
25+
26+
What does counting sort exploit?; The O(1) time insertions and lookups in a list.
27+
28+
29+
Can we use counting sort when our input items aren’t integers bound by constants?; Yes. We can first write a function that maps our items to integers from 0 to some constant such that different items will always map to different integers. This allows us to use counting sort.

flashcards/bitwise-manipulation.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
How are Negative numbers typically represented in binary?; Using two's complement encoding. In two's complement, the leftmost digit is negative, and the rest of the digits are positive. E.g. 1011 would be -8+2+1 = -5.
2+
3+
4+
What is two’s complement encoding?; The leftmost digit is negative, and the rest of the digits are positive. It’s a way of representing negative numbers in binary.
5+
6+
Why is two’s complement used to represent binary numbers (as opposed to one’s complement or sign and magnitude encodings)?; (1) There is only one way to represent zero. (2) Basic operations like addition, subtraction, and multiplication are the same regardless of whether the numbers involved are positive or negative.
7+
8+
9+
Bitwise AND; takes two sets of bits and for each pair of bits (the two bits at the same index in each set) returns 11 if both bits are 11. E.g. `5 & 6` is `0101 & 0110` which returns 0100 = 4.
10+
11+
12+
Bitwise 5 | 6; 7, since 0101 or 0110 gives 0111.
13+
14+
15+
Bitwise ~ 5 (NOT 5); -6, since ~ 0000 0101 (5) = 1111 1010 (-6).
16+
17+
18+
Bitwise 5 ^ 6 (5 XOR 6); 3, since 0101 XOR 0110 gives 0011 = 3.
19+
20+
21+
Bit shifting; Moves each digit in a set of bits left or right. The last bit in the direction of the shift is lost, and a 00 bit is inserted on the other end. E.g. ` 0010 << 1` -> 0100, `1011 >> 1` -> 0101.
22+
23+
24+
What do n left shifts do to a binary number?; They multiply the number by 2^n.
25+
26+
27+
What do n right shifts do to a binary number?; They divide the number by 2^n, throwing out any remainders.

flashcards/c.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
What does `str = malloc(15)` mean in C?; Make a string that can hold 15 characters.
2+
3+

flashcards/data-structures.txt

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
What is an array?; An array is a low-level data structure that holds an ordered collection of elements. Each position in the array has an index, starting with 0. E.g. in Java: `int gasPrices = new int[10]` -> array to hold ten integers.
2+
3+
4+
What is the time complexity of looking up elements in an array?; O(1). If you know the address where an array starts in memory, it’s simple math to find the address of any index.
5+
6+
7+
What is array slicing?; Taking a subset from an array and allocating a new array with those elements. E.g. my_list[start_index:end_index]. You are (1) allocating a new list, (2) copying the elements from the original list to the new list, which takes O(n) time and space, where n is the number of elements in the resulting list.
8+
9+
10+
What is the space and time complexity of `my_list[start_index:end_index]`?; O(n) time and O(n) space, where n is the number of elements in the resulting list. You are (1) allocating a new list, (2) copying the elements from the original list to the new list. See also array slicing.
11+
12+
13+
What is a dynamic array?; I.e. a ‘list’ in Python. It doesn’t require you to specify the length and allows you to seamlessly (although sometimes with time and space costs) insert and delete elements at any index.
14+
15+
16+
What are strings usually implemented as?; Arrays of characters.
17+
18+
19+
What is a hash table? (hash, hash map, map, unordered map); A data structure that pairs keys to values. Also called a dictionary. It is unordered (keys are not guaranteed to stay in the same order). It can use many types of objects as keys (commonly strings).
20+
21+
22+
What is the average time complexity for insertions and lookups in hash tables?; O(1) on average.
23+
24+
25+
Can you use more than one type of objects as keys in a hash table?; Yes.
26+
27+
28+
What are hash tables built on?; Arrays.
29+
30+
31+
What is the worst case lookup cost for a hash table and why?; O(n) because of hash collisions and rebalancing. But usually in industry we assume hashing and resizing algorithms are clever enough that collisions are rare and cheap. So on average it is O(1).
32+
33+
34+
What is a linked list?; A low-level data structure. It stores an ordered list of items in individual "node" objects that have pointers to other nodes. In a singly linked list, the nodes each have one pointer to the next node.
35+
36+
37+
Advantages of linked lists compared with arrays; (1) constant-time insertions and deletions in any position (you just change some pointers). Arrays require O(n) time to do the same thing, because you'd have to "shift" all the subsequent items over 1 index. (2) Linked lists can continue to expand as long as there is space on the machine. Arrays (in low-level languages) must have their size specified ahead of time. Even in languages with "dynamic arrays" that automatically resize themselves when they run out of space (like Python, Ruby and JavaScript), the operation to resize a dynamic array has a large cost which can make a single insertion unexpectedly expensive.
38+
39+
40+
Disadvantages of linked lists compared with arrays; To access or edit an item in a linked list, you have to take O(i)O(i) time to walk from the head of the list to the iith item (unless of course you already have a pointer directly to that item). Arrays have constant-time lookups and edits to the iith item.
41+
42+
43+
Typically, what are our connections to linked lists?; Often, our only connection to the list itself is a variable pointing to the head. From there we can walk down the list to all the other nodes.
44+
45+
46+
Write a singly linked list node class; class LinkedListNode: def __init__(self, value): self.value = value \ self.next = None
47+
48+
49+
Write a doubly linked list node class; class LinkedListNode: def __init__(self, value): self.value = value
50+
51+
52+
What is a queue?; A first in, first out (FIFO) data structure. The item that we put in the longest ago is the first item that comes out. It has two main methods enqueue() (adds an item), dequeue (removes and returns the next item in line). It can also include some utility methods peek() (returns the item at the front of the queue without removing it) and is_empty().
53+
54+
55+
What are the two main methods in a queue?; (1) enqueue() (adds an item), (2) dequeue (removes and returns the next item in line).
56+
57+
58+
Write a queue class;
59+
60+
61+
What is a stack?; It's a "last in, first out" (LIFO) data structure, which means the item that was put in the stack most recently is the first item that comes out. It has two main methods: push() (adds an item) and pop() (removes and returns the top item). It can also include utility methods peek() (returns the item on the top of the stack without removing it) and is_empty().
62+
63+
64+
Write a stack class;
65+
66+
67+
What is a binary tree?; A tree where every node has two or fewer children. The children are usually called left and right.
68+
69+
70+
What is a perfect binary tree?; A binary tree where every level of the tree is completely full. There are no "gaps."
71+
72+
73+
What are two interesting properties of perfect binary trees?; (1): the number of total nodes on each "level" doubles as we move down the tree. (2): the number of nodes on the last level is equal to the sum of the number of nodes on all other levels (plus 1). In other words, about half of our nodes are on the last level.
74+
75+
76+
What is the relationship between height h (0-indexed) and total nodes n in a perfect binary tree?; log​(n+1)/log2=h. That is, n = 1 + 2 + … + 2^(h-1) = 2^h - 1.
77+
78+
79+
Write a binary tree node class; class BinaryTreeNode: def __init__(self, value): self.value = value // self.left = None // self.right = None

flashcards/programming-knowledge.txt

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
What is the call stack?; A stack data structure that stores information about the active subroutines of a computer program.
2+
3+
4+
What is a stack overflow error?; The call stack gets too big and runs out of space. See also tail call optimisation (TCO), which optimises some recursive functions to avoid building up a tall call stack. TCO is NOT used by Python.
5+
6+
7+
What is tail call optimisation (TCO)?; Optimizes some recursive functions to avoid building up a tall call stack. Python and Java decidedly do not use TCO. Some Ruby implementations do, but most don't. Some C implementations do, and the JavaScript spec recently allowed TCO. Scheme is one of the few languages that guarantee TCO in all implementations. In general, best not to assume your compiler/interpreter will do this work for you.
8+
9+
10+
What is lazy evaluation?; Saving work for the last minute or avoid unnecessary work altogether. For example, if we had a conditional ‘if A and B: do C’. The Python interpreter’s lazy evaluation strategy wouldn’t bother checking the value of B if A was false.
11+
12+
13+
How might we use lazy evaluation in Python to avoid KeyErrors?; if ‘Becky’ in friends and friends[‘Becky’].is_free_this_friday(): invite_to_board_game_night(friends[‘Becky’])
14+
15+
16+
Does Python use lazy evaluation? If so, give examples.; Yes. (1) ‘if A and B: do C’. (2) Python generators, e.g. xrange() in Python 2.7, range() in Python 3.
17+
18+
19+
How does range(1,n) work in Python 2.7 and why might it be problematic?; Python generates a list of numbers in a specific range whose size is O(n). That could be a lot of space. -> Use a generator instead.
20+
21+
22+
What is a generator?; It behaves like a list in that we can loop through it, but instead of building up all of its contents at once, it simply generates the next element right when it's needed (lazily)! E.g. xrange() in Python 2 or range() in Python 3.
23+
24+
25+
What is a garbage collector?; Automatically frees up memory that a program is no longer using. Python has this, C does not. So you have to manually free up memory we’re not using any more by coding `free(str)` after `str = malloc(15)`. (manual memory management)
26+
27+
28+
What memory management does C++ have?; In the past, C++, like C, required programmers to manually manage memory. However, more recent revisions to C++ have introduced smart pointers, which are automatically freed when no longer needed. Using smart pointers makes it much easier to write exception-safe code, since allocated resources are automatically freed if an exception is thrown.
29+
30+
31+
Name and compare the two flavours of smart pointers C++ has with respect to memory management; Unique pointers and shared pointers. Both provide automatic freeing of memory when there are no more references to the shared resource. The main difference between the two lies in how many references to the pointer can exist. A unique pointer is the exclusive reference to an allocated resource - as soon as the unique pointer goes out of scope, the resource can be deallocated. By contrast, multiple shared pointers may reference the same resource - only when all of the references have gone out of scope can the resource be freed
32+
33+
34+
What is integer overflow?; When we have an integer that does fit in 32 or 64 bits, but the result after we add to it (or multiply it by something, or do another operation) does not fit in the original 32 or 64 bits.
35+
36+
37+
How do different languages handle integer overflow?; (1) In a high-level language like Python, the interpreter might notice this is about to happen and throw an error. Python and Ruby will also automatically use larger int types (`long` in Python) if your program needs them. (2) In a lower-level language like C, the processor will sort of "do its best" with the bits it has, which can cause some pretty nasty bugs. In our example above, when adding 01 to 11, the processor might take the true result 100 and throw out the highest bit, leaving 00, or it might say "this number can't go any higher" and just return 11.
38+
39+
40+
How do you reduce the risk of integer overflow?; Use larger integer types (like `long long int` in C and C++ or `BigInteger` in Java). Other modern languages will automatically use larger integer types if your program needs them (like `long` in Python and `Bignum` in Ruby).
41+
42+
43+
What is a closure?; a function that accesses a variable "outside" itself. Often in JS. For example: var message = ‘The British are coming.’; function sayMessage() { alert(message); }
44+
45+
46+
Give an example of creating an instance variable with a closure; This makes `nextGeneratedId` private, which prevents accidental changes from the outside world. Var getUniqueId = (function() { var nextGenerateId = 0; return function(element) { if (!element.id) { element.id = ‘generate-uid-’ + nextGeneratedId; nextGeneratedId++; } return element.id; }; })();
47+
48+
49+
What is a hash function?; It takes data (like a string or a file’s contents) and outputs a hash, a fixed-size string or number. We can think of a hash as a fingerprint. We can trust that a given file will always have the same hash, but we can’t go from the hash back to the original file.
50+
51+
52+
What is hash collision?; Multiple files having the same hash value.
53+
54+
55+
What are examples of hash functions?; MD5 hash, sha1.
56+
57+
58+
What are two uses for hashing?; (1) Dictionaries and (2) preventing man-in-the-middle attacks. (Dictionaries: want a list-like data structure with constant-time lookups, but we want to look up values based on arbitrary "keys," not just sequential "indices." We could allocate a list, and use a hash function to translate keys into list indices.)
59+
60+
61+
Mutable vs immutable objects; A mutable object can be changed after it's created (can make changes in-place -> all refs to that object will now reflect the change), and an immutable object can't. Python lists are mutable. Python tuples are not mutable: int_tuple[0] = 1 -> TypeError: ‘tuple’ object does not support item assignment.
62+
63+
64+
Are Python lists mutable?; Yes.
65+
66+
67+
Are Python tuples mutable?; No.
68+
69+
70+
Are strings mutable in Python? Javascript? Ruby? C++?; Immutable in Python and Javascript. Mutable in Ruby. Mutable or immutable in C++ depending on whether the string is declared with the `const` modifier (with which it is immutable)
71+
72+
73+
What is an in-place algorithm?; An in-place algorithm operates directly on its input and changes it, instead of creating and returning a new object. This is sometimes called destructive, since the original input is "destroyed" when it's edited to create the new output. (Careful: "In-place" does not mean "without creating any additional variables"! Rather, it means "without creating a new copy of the input." In general, an in-place function will only create additional variables that are O(1) space.)
74+
75+
76+
Does in-place mean "without creating any additional variables"?; No. It means "without creating a new copy of the input." In general, an in-place function will only create additional variables that are O(1) space.
77+
78+
79+
Write code that squares elements in a list in-place; ` for index, element in enumerate(int_list): int_list[index] *= element`.
80+
81+
82+
Why might you work in-place?; It saves space. Generally O(1) space cost.
83+
84+
85+
Why might you not work in-place?; It can cause side effects. Your input is "destroyed" or "altered," which can affect code outside of your function. E.g. `original_list` is the same as `squared_list=square_list_in_place(original_list)`. You should only use in-place if you’re v space constrained or if you’re positive you don’t need the original input any more, even for debugging.

flashcards/python.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
In range(a,b), is each entry inclusive or exclusive?; First entry is inclusive, second entry is exclusive.
2+
3+
4+
Get the index and element in a list; enumerate(). E.g. for index, element in enumerate(list): pass.
5+
6+
7+
Add an element to a list; list.append(element)
8+
9+
10+
Does list[:i] include the ith element?; No.
11+
12+
13+
Does list[i:] include the ith element?; Yes.
14+
15+
16+
What does list[-1] return?; The last element of the list.
17+
18+

flashcards/strategies.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
What does it mean for a problem to have overlapping subproblems?; Finding its solution involves solving the same subproblem multiple times. E.g. If we define fib(n) recursively, when calling fib(5), we end up calling the subproblem fib(2) three times.
2+
3+
4+
How do we tackle overlapping subproblems?; Memoization, i.e. keeping a record of the results for given inputs (usually in a dictionary).
5+
6+
7+
Code a function to compute the nth Fibonacci number; class Fibber: def __init__(self): self.memo = {} \\ def fib(self, n): if n < 0: raise Exception(“Index was negative. No such thing as a negative index in a series.”) \\ elif n in [0,1]: return n \\ if n in self.memo: print(“grabbing memo[%i]” % n \\ return self.memo[n] \\\ print(“computing fib(%i)” % n \\ result = self.fib(n-1) + self.fib(n-2) \\ self.memo[n] = result \\ return result
8+
9+
10+
Dynamic programming problems; problems where the solution is composed of solutions to the same problem with smaller inputs (as with the fibonacci problem, above).
11+
12+
13+
Two common strategies for dynamic programming; (1) Memoization and (2) Going bottom-up.
14+
15+
16+
What is a bottom-up algorithm?; A bottom-up algorithm "starts from the beginning," while a recursive algorithm often "starts from the end and works backwards."
17+
18+
19+
Code a bottom-up style function for calculating the product of 1 to n; def product_1_to_n(n): result = 1 \ for num in range(1,n+1): result *= num \\ return result
20+
21+
22+
What is a potential problem with recursive functions (e.g. for calculating the product of 1...n)?; It may build up a call stack of size O(n), which makes our total memory cost O(n). This makes it vulnerable to a stack overflow error, where the call stack gets too big and runs out of space. See also tail call optimisation (TCO), which optimises some recursive functions to avoid building up a tall call stack. TCO is NOT used by Python.
23+
24+
25+
What is an example of using a lazy approach vs an ‘eager’ approach in system design?; TempTracker class lazily (or ‘just in time’) calculating the max whenever it’s requested vs eagerly keeping the max up to date whenever we insert a new temperature. Depends on how often you expect to run get_max().

programming-flashcards.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

python-flashcards.txt

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)