Israel Bagrut Computer Science 5 Units common mistakes
Israel Bagrut Computer Science 5 Units · Understand the traps and how to avoid them.
When asked to write a recursive method (e.g., sum of array, count of nodes in a binary tree, or a backtracking search), the candidate writes a loop instead, or writes a recursion that has no base case for the empty structure (empty array, null child, empty string), so the method throws StackOverflowError or returns a wrong value on the empty input.
Candidates learn iteration first and reach for it automatically; recursion is taught late and practiced little. The base case for the degenerate/empty structure is the part teachers most often skip when demonstrating on a non-empty example, so the student memorizes the recursive step but not the termination condition.
What to do instead
For every recursive method, write the base-case line first and test it in isolation: call the method on an empty array, a null child, an empty string, and a one-element input before writing the recursive step. Practice the standard patterns (linear recursion on an array index, recursion on a linked list's next, recursion on left/right children) until the empty-structure case is automatic. On the exam, trace your recursion by hand on the smallest input and on an input of size 2.
In efficiency questions the candidate gives only the final complexity (e.g., "O(n^2)") without the derivation, or states a bound that is wrong by a factor (calls a single loop over an n×n matrix O(n) because "it runs n times"), or confuses the complexity of one call with the complexity of the whole algorithm including its nested calls.
Students memorize complexity labels for known algorithms but never learn to count operations from code. They also confuse the size of the input with the value of the input (a loop for i=1..n is O(n) in the value n, but if n is given in binary the input size is log n). Without a counting habit, the answer is a guess.
What to do instead
Always write the count: identify the input-size parameter, count how many times the innermost statement executes as a function of that parameter, then drop constants and lower-order terms. For nested loops multiply the iteration counts; for a loop whose bound halves each time, write the recurrence T(n)=T(n/2)+c and solve it. Distinguish input size from input value explicitly and state which one your bound uses. Practice on matrix traversal, binary search, merge sort, and a loop inside a recursive call.
In object-oriented design questions the candidate makes every field public, or writes a class with getters and setters for every field and calls that encapsulation, or puts business logic in a class that should only hold data (or vice versa), and fails to use inheritance/polymorphism where the problem clearly asks for a family of types (e.g., different shapes, different employee kinds).
Beginners equate "a class with fields" with OOP and have not internalized that encapsulation means controlling invariants, not just adding accessors. Polymorphism is hard to see as a design tool until the student has written an if/else chain over a type field and been shown the alternative. Exam pressure pushes toward the first structure that compiles.
What to do instead
Before coding, list the class's invariants (what must always be true of a valid object) and make the fields private with the constructor enforcing them; add setters only where change is genuinely allowed. When the problem names several kinds of one thing, define a base class or interface with the shared operation and override it per subtype instead of switching on a type tag. Justify each design choice in one sentence - examiners award design marks for stated reasoning.
When implementing a linked list, stack, queue, or binary search tree, the candidate loses nodes during insertion or deletion: forgetting to reconnect the previous node's next pointer, updating the head/tail reference in the wrong order, or in a BST deletion forgetting the case of a node with two children (replacing it with its in-order successor or predecessor). The structure then silently drops elements or loops forever.
Pointer manipulation requires holding several references in mind at once, and the order of assignments matters. Students copy a template without understanding which invariants (head points to first, tail to last, size matches the count) must hold after each operation, so they never check them.
What to do instead
State the invariants of the structure (head/tail/size, BST ordering, no cycles) and after writing each operation, hand-trace it on a list of 0, 1, 2, and 3 elements, drawing the boxes and arrows. For deletion, enumerate the cases explicitly: no children, one child, two children. Use a temporary reference before overwriting a pointer. Verify size and head/tail consistency after every trace.
In formal-languages questions the candidate builds a finite automaton or regular expression for a language without covering the empty word and boundary cases, or claims a language is regular when it requires unbounded counting (e.g., equal numbers of 0s and 1s), or writes a grammar that generates strings outside the language because a nonterminal is never constrained.
Students test their construction on one or two typical strings and stop. The empty word and the "just over the boundary" strings are exactly where constructions fail. The regularity claim comes from not having internalized the pumping lemma or the closure/Myhill-Nerode intuition that unbounded counting needs memory.
What to do instead
For every automaton or grammar, test the empty word, a one-symbol word, and words just inside and just outside the boundary of the language. Before claiming regularity, ask: does acceptance require counting without bound? If yes, it is not regular, and cite the pumping lemma argument. For grammars, check that every nonterminal is reachable and that every production preserves the language's constraint.
In the project (software-engineering) component the candidate submits code that works on the happy path but has no input validation, no handling of file-not-found or malformed data, and no tests; the written documentation describes what the program does but not the design decisions, the data structures chosen, or the complexity of the main algorithms.
School projects are usually graded on a demo, so students optimize for the demo and treat robustness and documentation as afterthoughts. They also have not been taught to write the design rationale, only the user manual.
What to do instead
Adopt a checklist before submission: every input read is validated, every file/network operation is wrapped with error handling, and there is at least one test per public method including edge cases (empty, one element, maximum size). In the design document, for each major class state its responsibility and for each major algorithm state its complexity and why that structure was chosen. Run the program with deliberately bad input and record the result.
When asked to convert between number bases or explain two's-complement representation, the candidate converts the magnitude and forgets the sign, or negates a two's-complement number by flipping all bits without adding one, or confuses the range of an n-bit signed integer (−2^(n−1) to 2^(n−1)−1) with the unsigned range.
Base conversion is taught as an arithmetic procedure separate from representation, so the sign bit is treated as an afterthought. The "flip and add one" rule is memorized as a phrase without being tied to why it works (the sum of a number and its complement is all ones, i.e., −1).
What to do instead
Always state the bit width and whether the representation is signed or unsigned before converting. For negation, do flip-then-add-one and verify by adding the result back to the original: the sum must be zero in n bits. Memorize the signed range and check that your answer lies inside it; if it does not, the answer is an overflow, not a valid encoding.
In ethics and information-security questions the candidate answers with a slogan ("it is wrong to steal data") instead of applying a named principle to the concrete scenario, or confuses security goals (confidentiality vs. integrity vs. availability) and mislabels a threat (calls phishing a denial-of-service attack, or says encryption provides integrity).
Ethics is often taught as a list of values rather than as an analytical method, and security terminology is learned as vocabulary without being tied to concrete attacks. Under time pressure the student writes the first moral intuition that comes to mind.
What to do instead
Use a fixed structure for ethics answers: identify the stakeholders, state the conflicting values, apply a named principle (e.g., informed consent, least privilege, proportionality, the harm principle), and reach a justified conclusion that acknowledges the cost to the losing side. For security, classify each scenario by which goal is violated (confidentiality, integrity, availability) and which mechanism addresses it (encryption, hashing/MAC, backups/redundancy), and name the attack precisely.
In algorithm-design questions that ask for an efficient solution (e.g., find a pair summing to a target, count occurrences, find duplicates), the candidate writes the brute-force O(n^2) double loop even when the problem statement or mark allocation signals that a better solution is expected, and never considers sorting first, using a hash set/map, or two pointers.
The brute force is the first correct idea and compiles quickly, so it feels safe. Students do not have a repertoire of standard techniques to reach for, and they do not read the constraints (input size) as a hint about the required complexity.
What to do instead
Before coding, read the input-size constraint and translate it into a target complexity (n up to ~10^5 means O(n log n) or O(n); n up to ~10^3 permits O(n^2)). Then run through a short checklist: can sorting help? can a hash structure turn a search into a lookup? can two pointers replace a nested loop? can binary search replace a linear scan? Write the technique you chose and its complexity next to the solution.
When tracing code by hand (especially loops with break/continue, nested loops, or methods that modify an array in place), the candidate writes only the final output and skips the intermediate variable states, so an off-by-one or an aliasing bug (two references to the same array) goes unnoticed; alternatively the candidate writes a trace table but copies values from the previous row without applying the update.
Hand-tracing is treated as a formality rather than a debugging tool, and students have not been taught to record every variable that changes. Aliasing is invisible unless the student draws references rather than values.
What to do instead
Use a trace table with one column per variable plus the output, and fill every row by applying the loop body literally, including the loop counter's final value that fails the condition. When arrays or objects are involved, draw references as arrows to a single box rather than copying values, so aliasing becomes visible. After tracing, compare against the expected result and, if they differ, find the first row where they diverge.