Junior Programmer study materials
Junior Programmer study resources

Junior Programmer cheat sheet

Junior Programmer · Keep the key ideas within reach.

Quick reference

Programming fundamentals: syntax, variables, data types, operators, expressions

  • A variable binds a name to a value; assignment (=) rebinds the name to a new value, while equality comparison uses == (value) or === (value and type in JavaScript).

  • Primitive types are typically integer, floating point, boolean, character, and null/none; strings, arrays, and objects are usually reference types whose variables hold a pointer, not the data itself.

  • Integer division truncates toward zero (7 / 2 == 3 in Java int math; 7 // 2 == 3 in Python); the modulo operator a % b returns the remainder.

  • Operator precedence, highest to lowest: parentheses, exponent, unary (! -), multiplicative (* / %), additive (+ -), comparison, logical NOT, logical AND, logical OR; parentheses always override this order.

  • String concatenation versus numeric addition: in JavaScript '5' + 3 evaluates to '53' but '5' - 3 evaluates to 2; in Python '5' + 3 raises TypeError instead of coercing.

  • Falsy values include false, 0, 0.0, empty string, null, undefined, and NaN; Python additionally treats empty list, tuple, dict, set, and None as falsy.

  • Short-circuit evaluation: A && B does not evaluate B when A is falsy, and A || B does not evaluate B when A is truthy; Python's and/or return an operand, not necessarily a boolean.

  • Immutability: Python strings and tuples cannot be modified in place, so s += 'x' inside a loop allocates a new string each iteration, giving O(n squared) total copying.

  • Naming conventions: camelCase for variables and methods in Java/JavaScript, snake_case in Python, UPPER_CASE for constants; a leading underscore marks internal use by convention only.

Quick reference

Control flow: conditionals, loops, and logical decision making

  • if/elif/else chains evaluate top-down and execute only the first true branch; a later elif is never tested once an earlier branch matched.

  • Conditions need not be boolean in Python and JavaScript: any truthy value passes; in Java the condition of an if must be an actual boolean expression.

  • A while loop tests its condition before each iteration, so it can run zero times; a do-while loop runs the body once before the first test.

  • range(a, b) yields a up to but excluding b; range(a, b, step) with a negative step counts downward, and range(len(x)) yields indices 0 through len(x) - 1.

  • break exits only the innermost enclosing loop; continue jumps to the next iteration of that loop; return exits the entire function from any nesting depth.

  • C-family switch falls through to the next case unless break is used; Python's match/case does not fall through and compares by pattern, not by identity.

  • De Morgan's laws: !(A && B) is equivalent to !A || !B, and !(A || B) is equivalent to !A && !B.

  • Off-by-one rule: an array of n elements has valid indices 0 to n - 1, so a full traversal uses index < n, never index <= n.

  • Nested loops over m and n items perform m * n iterations, so a doubly nested scan of the same n-element list is O(n squared).

Quick reference

Functions, parameters, scope, and modular code organization

  • A parameter is the name in the function definition; an argument is the value supplied at the call site. Positional arguments match by order, keyword arguments by name.

  • In Python, default parameter values are evaluated once when the function is defined, so a mutable default such as [] is shared across every call that omits the argument.

  • Passing follows pass-by-object-reference: rebinding a parameter inside the function does not affect the caller, but mutating a passed list or dict is visible outside.

  • Assignment inside a function creates a local variable that shadows an outer name; Python requires global or nonlocal to rebind an enclosing name.

  • return ends function execution and hands back a value; a function without a return statement yields None in Python and undefined in JavaScript.

  • A pure function's output depends only on its arguments and it has no side effects, which makes it deterministic and directly testable.

  • A module is a file of definitions imported by name; Python's if name == 'main' guard runs a block only when the file is executed directly, not when imported.

  • Recursion requires a base case plus a recursive call that moves toward it; each pending call consumes stack space, and Python's default recursion limit is about 1000 frames.

Quick reference

Data structures and strings: arrays/lists, dictionaries/maps, iteration and manipulation

  • Array/list access by index is O(1); appending at the end is amortized O(1); inserting or deleting at the front is O(n) because later elements shift.

  • Python slicing a[start:stop:step] includes start, excludes stop, and accepts negative indices, where -1 is the last element; the slice creates a new list.

  • A dict/map stores key-value pairs with average O(1) lookup; keys must be hashable and therefore immutable, so lists cannot be keys but tuples can.

  • Iterating a Python dict yields keys; use .items() for key-value pairs, .values() for values, and .get(key, default) to avoid KeyError on missing keys.

  • Strings are immutable character sequences: len, upper/lower, strip, split(sep), join(list), replace, find, startswith, and endswith are the standard operations; str.join is preferred over repeated += in loops.

  • A set holds unordered unique elements; membership testing is average O(1) versus O(n) for a list, with union |, intersection &, and difference - operators.

  • Python sorts with sorted(iterable, key=...) or list.sort(key=...), where the key function returns the value to compare; JavaScript's array.sort() compares as strings unless a comparator is passed.

  • A stack is LIFO via append/pop; a queue is FIFO and is implemented with collections.deque popleft, because list.pop(0) is O(n) per call.

  • Membership tests: 'x in list' scans linearly in O(n), while 'x in set' or 'key in dict' hashes the value in average O(1).

Quick reference

Object-oriented programming basics: classes, objects, attributes, methods, inheritance

  • A class is a blueprint defining attributes and methods; an object (instance) is a concrete value produced by calling the class, and each instance has its own attribute storage.

  • Constructors initialize new instances: init(self, ...) in Python, or a method named after the class in Java; Python's self and Java's this refer to the current instance.

  • Instance attributes are set per object (usually in the constructor) and are independent; class attributes are defined on the class and shared by all instances unless shadowed.

  • A method is a function defined inside a class; Python passes the instance as the first parameter self explicitly, while Java and JavaScript supply this implicitly.

  • Inheritance: class Child(Parent) or class Child extends Parent gives the child all parent attributes and methods; a subclass overrides a method by redefining it with the same name.

  • super() or super references the parent implementation, typically called at the start of an overridden constructor or method to reuse rather than replace parent behavior.

  • Encapsulation restricts direct access to internal state: Python uses _ and __ naming conventions, Java uses private/protected modifiers, and access goes through getters and setters.

  • Polymorphism lets the same method call behave differently per class; Python resolves it by duck typing at runtime, Java by method dispatch on the declared type hierarchy.

  • Composition (has-a: an object holding another object) is often preferred to deep inheritance (is-a), since long chains make behavior hard to trace and change.

Quick reference

Error handling, debugging, and basic testing practices

  • Structure: try/except/finally in Python and try/catch/finally in Java and JavaScript; the finally block always runs, even when an exception propagates or a return executes.

  • Catch the most specific exception type first and order handlers from specific to general; a bare except or catch (Exception) swallows bugs and hides the real failure site.

  • raise or throw signals an error deliberately; catching, logging, and re-raising preserves the original traceback and stack context.

  • Common runtime errors: NameError or ReferenceError (undefined name), TypeError (wrong type), IndexError or out-of-range (bad index), KeyError (missing dict key), ZeroDivisionError, NullPointerException.

  • A traceback is read bottom-up: the final line gives the exception type and message, and the lines above list the call stack with the innermost frame last.

  • Debugging techniques: print or log intermediate values, assert invariants, and bisect either the code (comment out blocks) or the history (git bisect) to find the first failing point.

  • A unit test follows arrange-act-assert: set up inputs, call exactly one behavior, and compare the result with an expected value; tests must be independent and deterministic.

  • assert condition, message raises AssertionError when the condition is false; Python disables asserts under the -O flag, so they must not be used for input validation.

  • Test edge cases: empty input, a single element, duplicates, negatives, zero, and maximum size; line coverage only shows executed code, not whether behavior is correct.

Quick reference

File handling and use of standard libraries

  • open(path, mode) modes: 'r' read (default, fails if missing), 'w' truncate or create, 'a' append, 'x' create and fail if it exists; append 'b' for binary and 't' for text.

  • Use a context manager, with open(path) as f:, so the file is closed automatically on normal exit and on exception; otherwise call f.close() explicitly.

  • Reading: f.read() returns the whole file as one string, f.readline() one line, and iterating over f yields lines that still contain the trailing newline, so call .strip().

  • Writing: f.write(text) returns the number of characters written and adds no newline; f.writelines(list) writes strings back to back without inserting separators.

  • Pass encoding='utf-8' explicitly when opening text files; binary mode returns bytes objects, which must be decoded before string operations.

  • Build paths with os.path.join or pathlib.Path rather than hard-coded '/' or backslash; relative paths resolve against the process's current working directory, not the script's folder.

  • Frequently used standard modules: math, random, datetime, json, csv, re, collections (deque, Counter, defaultdict), os, sys, and pathlib.

  • sys.argv is the list of command-line arguments, where sys.argv[0] is the script name and sys.argv[1:] are the user-supplied arguments.

  • JSON: json.dumps returns a string and json.dump writes to a file object; json.loads parses a string and json.load reads a file; objects that are not JSON-serializable raise TypeError.

Quick reference

Algorithms and problem solving: searching, sorting, and simple complexity reasoning

  • Linear search checks elements in order, runs in O(n), and works on unsorted data; binary search runs in O(log n) but requires the data to be sorted first.

  • Binary search maintains low and high indices, compares the target with the element at the midpoint, and moves one boundary past the midpoint; the loop continues while low <= high.

  • Bubble, selection, and insertion sort are O(n squared) comparison sorts; insertion sort degrades to O(n) when the input is already nearly sorted.

  • Merge sort is divide-and-conquer with O(n log n) time in all cases, is stable, and needs O(n) auxiliary space; quicksort averages O(n log n) but degrades to O(n squared) with bad pivots on sorted input.

  • Big-O keeps the dominant term and drops constants and lower-order terms, so 3n squared + 5n + 7 becomes O(n squared); it describes growth, not absolute speed.

  • Growth order from fastest to slowest: O(1) < O(log n) < O(n) < O(n log n) < O(n squared) < O(2 to the n) < O(n factorial).

  • Hash map operations average O(1) but degrade to O(n) per operation when many keys collide or the load factor grows, which is why tables resize.

  • Space complexity counts extra memory beyond the input: in-place sorts use O(1) auxiliary space, merge sort uses O(n), and recursion uses stack space proportional to depth.

  • Naive recursive Fibonacci recomputes subproblems and runs in O(2 to the n); caching results (memoization) reduces it to O(n) time with O(n) space.

Quick reference

Development tooling and version control basics

  • git init creates a repository, git clone copies a remote one including history, and git status reports staged, unstaged, and untracked changes.

  • The staging area (index) is what a commit records: git add stages changes, git commit -m 'message' snapshots them, git diff shows unstaged changes, and git diff --staged shows staged ones.

  • Branches are movable pointers to commits: git branch lists them, git switch -c name (or git checkout -b name) creates and switches, and HEAD points at the current branch's tip.

  • git merge joins branches and creates a merge commit when histories diverged, preserving both lines; git rebase replays commits onto a new base and rewrites their hashes, so shared branches should not be rebased.

  • git pull is git fetch followed by a merge; git push uploads local commits; merge conflicts appear between <<<<<<<, =======, and >>>>>>> markers and are resolved by editing and re-running git add.

  • .gitignore lists patterns of untracked files Git should skip; files already tracked stay tracked until removed with git rm --cached.

  • History tools: git log --oneline lists commits, git revert creates a new commit that undoes an earlier one safely, and git reset --hard moves the branch pointer and discards uncommitted work.

  • Every commit is identified by a SHA hash of its content and metadata; a detached HEAD means HEAD points directly at a commit rather than at a branch.

  • Dependency isolation: a Python venv or Node node_modules folder keeps per-project packages separate, with versions pinned in requirements.txt or package.json.