University

Computer Science 101 Practice Exam — Free

Generate a realistic AI practice exam with worked solutions

Generate Your Free Practice Exam

Introductory Computer Science covers fundamental programming concepts, algorithms, basic data structures, and computational thinking. Exams test tracing through code, writing simple programs, and understanding recursion and algorithmic complexity. Practice problems in varied formats build the flexibility needed for exam-day surprises.

Crameleon generates your practice exam from your own course materials — lecture notes, syllabi, past exams, or any combination. Upload what you have and get a fully formatted exam with the same structure as your professor's actual tests: multiple choice, short answer, and worked problems, all with step-by-step solutions (first 2 free; all with Premium).

Unlike generic question banks, every Crameleon exam reflects the specific framing, terminology, and difficulty level of your course. You'll practise answering questions that look and feel like the real thing — which is exactly what the research on retrieval practice says you should be doing. Students who test themselves with practice exams consistently outperform students who re-read notes, regardless of study time. The generation takes under 2 minutes and your first exam is completely free.

Topics typically tested

  • Variables, control flow & functions
  • Recursion & recursive tracing
  • Sorting algorithms (bubble, merge, quick)
  • Basic data structures (arrays, lists)
  • Big-O complexity analysis
  • Problem decomposition & algorithm design

Sample Computer Science 101 exam questions

Three original questions in the style of a real Computer Science 101 exam, each with a worked solution. Your own practice exam can be built from your course's notes and syllabus.

Question 1Multiple choiceRecursion & recursive tracing

Consider the Python function

def f(n):
    if n < 2:
        return 1
    return f(n - 1) + 2 * f(n - 2)

What value does f(5) return?

  1. A.

    21

  2. B.

    11

  3. C.

    8

  4. D.

    43

Worked solution
Answer:A

Trace upward from the base cases rather than expanding the whole call tree. The base case covers n=0n = 0 and n=1n = 1, both returning 1.

  • f(2)=f(1)+2f(0)=1+2=3f(2) = f(1) + 2f(0) = 1 + 2 = 3
  • f(3)=f(2)+2f(1)=3+2=5f(3) = f(2) + 2f(1) = 3 + 2 = 5
  • f(4)=f(3)+2f(2)=5+6=11f(4) = f(3) + 2f(2) = 5 + 6 = 11
  • f(5)=f(4)+2f(3)=11+10=21f(5) = f(4) + 2f(3) = 11 + 10 = 21

Check with the closed form: the recurrence an=an−1+2an−2a_n = a_{n-1} + 2a_{n-2} has characteristic equation r2−r−2=(r−2)(r+1)=0r^2 - r - 2 = (r-2)(r+1) = 0, so an=α2n+β(−1)na_n = \alpha 2^n + \beta(-1)^n. The base cases give α+β=1\alpha + \beta = 1 and 2α−β=12\alpha - \beta = 1, so α=2/3\alpha = 2/3 and β=1/3\beta = 1/3, and a5=23(32)+13(−1)=64−13=21a_5 = \tfrac{2}{3}(32) + \tfrac{1}{3}(-1) = \tfrac{64 - 1}{3} = 21.

Option B (11) is the most tempting error: it is f(4)f(4), the result of stopping one level early, and it is also what you get by wrongly taking f(0)=0f(0) = 0. Option C (8) is the plain Fibonacci value obtained by dropping the factor of 2. Option D (43) is f(6)f(6), one level too far.

Note that the call count grows quickly: f(5)f(5) makes 15 calls in total, because every call with n≥2n \ge 2 spawns two more, which is why memoization matters for recurrences like this one.

f(5) = 21 (option A).

Question 2Short answerVariables, control flow & functions

What does this Python program print?

total = 0
for i in range(1, 20):
    if i % 3 == 0 and i % 2 != 0:
        total += i
    elif i % 7 == 0:
        total -= i
print(total)
Worked solution
Answer:

6

range(1, 20) produces the integers 1 through 19; the upper bound 20 is excluded. For each ii the first test asks whether ii is a multiple of 3 and odd; only when that test fails does the elif ask whether ii is a multiple of 7.

Multiples of 3 in range: 3, 6, 9, 12, 15, 18. The odd ones are 3, 9 and 15, so the first branch adds 3+9+15=273+9+15 = 27. The even multiples 6, 12 and 18 fail the first test and then fail the elif (none is a multiple of 7), so they contribute nothing.

Multiples of 7 in range: 7 and 14. Neither is a multiple of 3, so each reaches the elif and is subtracted: 27−7−14=627-7-14 = 6. The value 21 would satisfy both tests, but it lies outside the range.

So the program prints 6.

Check by running the loop in order and watching total: after i=3i = 3 it is 3; after 7 it is −4; after 9 it is 5; after 14 it is −9; after 15 it is 6; no later value of ii changes it.

Common slips: including i=20i = 20 (the range is exclusive at the top), forgetting the != 0 odd test and adding all six multiples of 3 (which would give 42), or subtracting 21.

6

Question 3Worked problemSorting algorithms (bubble, merge, quick)

The following partition routine is used by quicksort:

def partition(a, lo, hi):
    pivot = a[hi]
    i = lo - 1
    for j in range(lo, hi):
        if a[j] <= pivot:
            i += 1
            a[i], a[j] = a[j], a[i]
    a[i + 1], a[hi] = a[hi], a[i + 1]
    return i + 1

It is called as partition(a, 0, 6) on a = [7, 2, 9, 4, 3, 8, 6]. (a) Show the array after every swap, then give the final array and the returned index. (b) How many key comparisons (a[j] <= pivot) are made? (c) Which two subarrays does quicksort recurse on next, and what kind of input makes this quicksort run in O(n2)O(n^2) time?

Worked solution
Answer:

(a) [2, 7, 9, 4, 3, 8, 6] → [2, 4, 9, 7, 3, 8, 6] → [2, 4, 3, 7, 9, 8, 6] → final [2, 4, 3, 6, 9, 8, 7], returns 3; (b) 6 comparisons; (c) [2, 4, 3] and [9, 8, 7]; an already-sorted (or reverse-sorted) input

The pivot is a[6] = 6, and i starts at −1. The loop invariant is that a[lo..i] holds keys at most the pivot and a[i+1..j-1] holds keys greater than it.

  • j = 0: 7 ≤ 6 is false; no swap.
  • j = 1: 2 ≤ 6 is true; i becomes 0; swap a[0] and a[1]: [2, 7, 9, 4, 3, 8, 6].
  • j = 2: 9 ≤ 6 is false.
  • j = 3: 4 ≤ 6 is true; i becomes 1; swap a[1] and a[3]: [2, 4, 9, 7, 3, 8, 6].
  • j = 4: 3 ≤ 6 is true; i becomes 2; swap a[2] and a[4]: [2, 4, 3, 7, 9, 8, 6].
  • j = 5: 8 ≤ 6 is false.

After the loop, swap a[i+1] = a[3] with the pivot at a[6]: [2, 4, 3, 6, 9, 8, 7], and the function returns 3. Check the invariant: everything left of index 3 (2, 4, 3) is at most 6 and everything right of it (9, 8, 7) is greater, so 6 is in its final sorted position.

(b) The loop runs for j = 0 to j = 5, one comparison each: 6 comparisons, which is n−1n-1 for n=7n = 7 elements.

(c) Quicksort recurses on a[0..2] = [2, 4, 3] and a[4..6] = [9, 8, 7]. If the input is already sorted (or reverse sorted), the last element is always the largest (or smallest) key, so every partition splits the array into n−1n-1 elements and 0 elements. The comparisons then total (n−1)+(n−2)+⋯+1=n(n−1)/2(n-1) + (n-2) + \dots + 1 = n(n-1)/2, which is O(n2)O(n^2), versus the O(nlog⁡n)O(n \log n) average when the pivots split the array roughly evenly.

(a) Final array [2, 4, 3, 6, 9, 8, 7], returned index 3; (b) 6 comparisons; (c) subarrays [2, 4, 3] and [9, 8, 7]; sorted or reverse-sorted input gives O(n2)O(n^2).

Used by 3,000+ students across Canadian universities·Step-by-step solutions (first 2 free)·Works for any course

Ready to practice?

Generate Your Free Computer Science 101 Practice Exam

Your first exam is free — just sign in, no credit card.