OAE Computer Science common mistakes
OAE Computer Science · Understand the traps and how to avoid them.
When tracing a short recursive function on paper, the candidate writes only the first two or three call frames and then jumps straight to the final return value, skipping the unwinding of the stack and losing track of what each frame returns to its caller.
Recursion is usually learned by reading finished code rather than by simulating it. Under time pressure the candidate pattern-matches the base case and assumes the answer 'comes back up' correctly, so intermediate values that depend on the return of deeper calls are never computed.
What to do instead
Adopt a fixed trace template: draw one column per active call, record the argument on entry, leave a blank for the return value, and fill blanks only on the way back up, right to left. Practise on functions such as a recursive sum over an array, a binary-search recursion, and a naive Fibonacci, and check each trace against a hand-run of the iterative version.
The candidate evaluates postfix or infix expressions and Boolean expressions by scanning left to right and applying operators in the order encountered, ignoring precedence and associativity, and mis-handles short-circuit evaluation of AND/OR.
Everyday arithmetic intuition overrides the formal rules, and short-circuiting is treated as an optimisation detail rather than a defined semantic. Candidates also forget that a stack-based postfix evaluation must pop the right operand before the left.
What to do instead
Before evaluating, annotate the expression with precedence levels and parenthesise it fully, then evaluate inside-out. For postfix, rehearse the rule 'push operands, on an operator pop right then left'. Drill truth tables for short-circuit cases where the right operand would divide by zero or index out of bounds, since those questions test whether the right side is evaluated at all.
The candidate converts between binary, decimal, and hexadecimal by memorising a few examples, then makes place-value errors on larger values, and confuses two's-complement negation with simple bit inversion without adding one.
Base conversion is often practised only on small round numbers, so the positional weighting of higher bits is not internalised. Two's complement is remembered as 'flip the bits' because the plus-one step is the part most easily dropped.
What to do instead
Work in 4-bit groups: convert binary to hex nibble by nibble and hex to binary digit by digit, and only go through decimal when a question demands it. For two's complement, always write the width explicitly, invert, add one, and verify by adding the result back to the original to get zero in that width.
On code-output and debugging questions the candidate reasons about what the program is intended to do rather than executing it line by line, so off-by-one loop bounds, integer division, and pre- versus post-increment produce a confidently wrong answer.
Reading for intent is a strong habit in real code review and a liability in exams. Familiar idioms are skimmed, and the candidate supplies the correct behaviour from memory instead of the behaviour written.
What to do instead
Maintain a variable table with one column per live variable and update it for every iteration of short loops. Circle every loop bound and every division or increment operator before answering. Deliberately practise snippets where changing < to <= changes the output, and where integer division truncates toward zero for negatives.
The candidate treats parameters as if passed by reference when the language passes primitives by value, or assumes reassigning an object reference inside a method mutates the caller's variable, and so predicts the wrong final state after a function call.
The distinction between mutating an object and rebinding a reference is subtle and is rarely made explicit in introductory courses. Candidates also carry habits from one language into another, for example assuming arrays are always copied.
What to do instead
For each call, draw the caller's variables and the callee's parameters as separate boxes, with arrows for references. Apply the rule: reassigning a parameter never affects the caller; mutating through a shared reference does. Test understanding with a swap function that fails on primitives and a list-append function that succeeds.
The candidate writes pseudocode or a short program that omits initialisation of accumulators and loop counters, mishandles the empty-input case, or returns from inside a loop after the first iteration, and does not trace the submitted answer against a boundary input.
Exam code is written to look plausible rather than to run. Without a compiler, missing initialisation and early returns are invisible, and the candidate budgets no time to test the answer after writing it.
What to do instead
Use a fixed skeleton: declare and initialise every accumulator and counter before the loop, handle the empty or single-element case first, and place the return after the loop unless an early exit is intended. Reserve the last minute of each coding item to hand-run the algorithm on an empty input, a one-element input, and a typical input.
When asked for the complexity of a nested-loop or recursive routine, the candidate counts the visible loops and reports O(n squared) without checking whether the inner bound depends on the outer index, whether work halves each step, or what the recursion's recurrence actually is.
Big-O is often reduced to a lookup table of loop shapes. Candidates also drop the dominant term incorrectly or keep constants, and they confuse the cost of the algorithm with the cost of one operation inside it.
What to do instead
Derive the count symbolically: write the number of iterations of each loop as a function of the outer variable, sum it, and simplify. For recursion, write the recurrence, for example T(n) = 2T(n/2) + n, and identify the pattern rather than guessing. Sanity-check by asking what happens to the running time when n doubles.
The candidate selects a data structure by name recognition rather than by the operations required, for example choosing an array-backed list for frequent front insertions, or claiming a hash table supports ordered range queries.
Structures are memorised with a single headline complexity, such as 'hash tables are O(1)', without the conditions attached, such as expected time, good hashing, and no ordering. The question's access pattern is read quickly and not mapped to operations.
What to do instead
Before choosing, list the operations the scenario needs with their frequencies, then compare candidates on each: indexed access, search, insert and delete at ends or middle, ordered traversal, and worst-case guarantees. Memorise the trade-off table for array, linked list, stack, queue, hash table, balanced tree, and heap, including which support ordered iteration.
The candidate confuses cache with main memory and virtual memory with secondary storage when reasoning about a memory-hierarchy question, and so misidentifies which level a miss or a page fault is served from.
The terms overlap in casual use, and the hierarchy is studied as a diagram to label rather than as a latency ordering. Candidates also forget that a TLB miss is not necessarily a page fault.
What to do instead
Memorise the hierarchy as an ordered list by latency, from registers through cache levels, main memory, and disk, and attach one sentence to each transition describing what triggers a fetch. Distinguish explicitly: a cache miss goes to the next level down, a TLB miss goes to the page table, and a page fault goes to secondary storage.
The candidate answers network and security items by matching a keyword in the question to a protocol name, for example equating TLS with encryption of data at rest, or confusing authentication with authorisation and symmetric with asymmetric key use.
Protocols are learned as acronym lists with one-line definitions, so the layer, direction, and purpose of each are not fixed in memory. Security vocabulary is especially prone to being learned as slogans.
What to do instead
Build a layer-by-layer map placing each protocol at its layer with the problem it solves, and for security separate the questions: who are you (authentication), what may you do (authorisation), how is confidentiality provided (encryption in transit versus at rest), and how is integrity or origin proven (hashing, MAC, digital signature). For each, state which key type is used and by whom.