Mock Exam 3Mock Exam 3

The final full-length paper in the real BUET MSc CSE format: 30 questions, 10 marks each, 90 minutes — mixed difficulty, just like the real exam. আসল BUET MSc CSE format-এ শেষ full-length paper: ৩০টা প্রশ্ন, প্রতিটা ১০ marks, ৯০ মিনিট — আসল exam-এর মতোই mixed difficulty।

Exam format and rules. This mock copies the real written test: 30 questions × 10 marks = 300 marks, time limit 1 hour 30 minutes. That is only about 3 minutes per question, so speed matters. All questions are fully written/descriptive — no options to guess from. This final set mixes quick definition questions with longer multi-step calculations, exactly like the real paper — learn to bank the quick marks fast. Do it like this:
  1. Set a 90-minute timer before you look at the questions.
  2. Write every answer on paper, just like the exam hall.
  3. Do not open any solution while the timer runs.
  4. After time is up, open the solutions and check yourself.
Partial credit is real in this exam. Even if you cannot finish a question, write the formula and the steps you know — steps earn marks.
Exam format আর নিয়ম। এই mock টা আসল written test-এর copy: ৩০টা প্রশ্ন × ১০ marks = ৩০০ marks, time limit ১ ঘণ্টা ৩০ মিনিট। মানে প্রতি প্রশ্নে মাত্র ৩ মিনিট, তাই speed খুব জরুরি। সব প্রশ্ন fully written/descriptive — guess করার মতো option নেই। এই শেষ set-এ ছোট definition question আর লম্বা multi-step calculation দুটোই মেশানো, ঠিক আসল paper-এর মতো — সহজ marks-গুলো তাড়াতাড়ি তুলে নিতে শিখুন। এভাবে করুন:
  1. প্রশ্ন দেখার আগে ৯০ মিনিটের timer set করুন।
  2. Exam hall-এর মতো প্রতিটা answer কাগজে লিখুন।
  3. Timer চলার সময় কোনো solution খুলবেন না।
  4. সময় শেষ হলে solution খুলে নিজেকে check করুন।
এই exam-এ partial credit সত্যিই দেওয়া হয়। কোনো প্রশ্ন পুরো না পারলেও formula আর যে step-গুলো জানেন সেগুলো লিখুন — step-এও marks আসে।
Why English only? The real exam paper is in English, so the questions and solutions below are kept in English only — exactly the way you will face them. The page frame stays bilingual as usual. Every question has a chapter link like [Ch 06] — revise there if you get stuck.
শুধু English কেন? আসল exam paper English-এ হয়, তাই নিচের প্রশ্ন আর solution শুধু English-এ রাখা হয়েছে — ঠিক যেভাবে exam hall-এ পাবেন। Page-এর frame আগের মতোই bilingual। প্রতিটা প্রশ্নে [Ch 06]-এর মতো chapter link আছে — আটকে গেলে সেখান থেকে revise করুন।

Questions 1–10Questions 1–10

Q1. On a machine where char takes 1 byte, int takes 4 bytes, and every type must sit at an address that is a multiple of its own size:
struct P { char a; int b; char c; };
struct Q { int b; char a; char c; };
(a) Compute sizeof(struct P) and sizeof(struct Q), drawing the byte-by-byte memory layout of each. (b) Why does the compiler insert padding at all? (c) State the general rule for ordering members to waste the least space, and give sizeof of an array struct P arr[10]. (10 marks) [Ch 01]
Show SolutionSolution দেখুন

(a) struct P = 12 bytes. Layout byte by byte:

offset: 0     1  2  3   4  5  6  7   8     9  10 11
        a     [pad....]  b  b  b  b   c     [pad.....]
  • a sits at offset 0. The next member b is an int, so it must start at a multiple of 4 → offsets 1–3 become 3 padding bytes, and b occupies 4–7.
  • c sits at offset 8. Then the struct's total size must be a multiple of the largest alignment (4), so 3 tail padding bytes (9–11) are added → size 12. (Tail padding exists so that in an array, every element's b stays aligned.)

struct Q = 8 bytes. Layout:

offset: 0  1  2  3   4     5     6  7
        b  b  b  b   a     c     [pad]

b fills 0–3, a at 4, c at 5, and only 2 tail padding bytes (6–7) round the size up to a multiple of 4. Same members, 12 vs 8 bytes — only the order changed.

(b) Hardware reads memory in aligned chunks. A 4-byte int at a misaligned address needs two memory reads (or, on some CPUs, causes a fault). Padding keeps every member at its natural alignment so access stays fast and legal.

(c) Rule: order members from largest to smallest (or group same-size members together) — big aligned members first leave no gaps, and the small ones pack at the end. sizeof(arr) = 10 × 12 = 120 bytes — arrays multiply the padded size, so the waste multiplies too.

Q2. A 4-bit Johnson (twisted-ring) counter is built from four D flip-flops Q3 Q2 Q1 Q0 shifting right, with the complement of Q0 fed back into Q3. It starts at 0000. (a) List the full count sequence for 8 clock pulses in a table. (b) How many states does an n-bit Johnson counter use, and compare with a plain ring counter and a binary counter for n = 4. (c) Give one decoding advantage of the Johnson counter and one practical problem with its unused states. (10 marks) [Ch 12]
Show SolutionSolution দেখুন

(a) Each clock: shift right (Q3→Q2→Q1→Q0) and load Q3 with Q0′:

ClockQ3Q2Q1Q0
0 (start)0000
11000
21100
31110
41111
50111
60011
70001
80000

The 1s "fill up" from the left, then "drain out" — after 8 clocks it is back at 0000, so it is a MOD-8 counter.

(b) An n-bit Johnson counter cycles through 2n states. For n = 4: Johnson = 8 states, ring counter = n = 4 states (a single circulating 1), binary counter = 2n = 16 states. Johnson doubles the ring counter's states with the same 4 flip-flops.

(c) Advantage: every state can be decoded with a single 2-input AND gate (e.g. state 1100 is Q2·Q1′), and only one flip-flop changes per clock, so decoding is glitch-free — no need for the n-input gates a binary counter's decoder uses. Problem: 24 − 8 = 8 states are unused. Noise can knock the counter into one of them, and it will then cycle among invalid states forever — a practical design adds self-correcting logic to force it back into the main loop.

Q3. A web server receives requests at an average rate of 3 requests per minute, following a Poisson distribution. For a randomly chosen minute, find: (a) the probability of receiving no request at all, (b) the probability of exactly 2 requests, (c) the probability of at least 2 requests, and state the mean and variance of the distribution. (Use \( e^{-3} \approx 0.0498 \).) (10 marks) [Ch 04]
Show SolutionSolution দেখুন

Poisson with rate \( \lambda = 3 \):

\[ P(X = k) = \frac{e^{-\lambda} \lambda^k}{k!} \]

(a) \( P(X = 0) = e^{-3} \dfrac{3^0}{0!} = e^{-3} \approx \mathbf{0.0498} \) — about a 5% chance of a silent minute.

(b) \( P(X = 2) = e^{-3} \dfrac{3^2}{2!} = e^{-3} \times \dfrac{9}{2} = 4.5 \times 0.0498 \approx \mathbf{0.224} \).

(c) Use the complement — "at least 2" means not 0 and not 1:

\[ P(X \geq 2) = 1 - P(0) - P(1) = 1 - e^{-3} - 3e^{-3} = 1 - 4e^{-3} \approx 1 - 0.199 = \mathbf{0.801} \]

(\( P(1) = e^{-3} \times 3 \approx 0.149 \).) So roughly 80% of minutes bring 2 or more requests.

For a Poisson distribution the mean and the variance are both equal to λ: \( E[X] = \mathrm{Var}(X) = 3 \). This equality is the quick signature of a Poisson model in exam questions.

Q4. A sender uses CRC error detection with generator \( G = x^3 + 1 \) (bit pattern 1001) on the data block D = 101110. (a) Compute the CRC remainder with modulo-2 (XOR) long division, showing every step, and write the transmitted frame. (b) Show the check the receiver performs on an error-free frame. (c) The third bit from the left flips during transmission — show that the receiver detects it. (10 marks) [Ch 09]
Show SolutionSolution দেখুন

(a) G has degree 3, so append three 0s: divide 101110000 by 1001 using XOR (no borrows):

1 0 1 1 1 0 0 0 0
1 0 0 1             ← XOR at the leading 1
-------
0 0 1 0 1 0 0 0 0
    1 0 0 1         ← next leading 1
    -------
0 0 0 0 1 1 0 1 0   (bits 2-5: 1010 ⊕ 1001 = 0011)
        1 0 0 1
        -------
0 0 0 0 0 1 0 1 1   (bits 4-7: 1100 ⊕ 1001 = 0101)
          1 0 0 1
          -------
0 0 0 0 0 0 0 1 1   (bits 5-8: 1010 ⊕ 1001 = 0011)

No leading 1 with 4 bits left → stop. Remainder = last 3 bits = 011.

Transmitted frame = data + remainder = 101110 011101110011 (the appended zeros are replaced by the CRC).

(b) The receiver divides the whole received frame 101110011 by 1001. By construction the frame is an exact multiple of G, so the remainder comes out 000 → frame accepted.

(c) Flipping the 3rd bit gives 100110011. Dividing by 1001 leaves remainder 001 ≠ 000, so the receiver rejects the frame and asks for retransmission. In polynomial terms the error added \( x^6 \), which is not divisible by \( x^3 + 1 \) — any single-bit error is caught because G has more than one term.

Q5. What is the output of this C++ program? Explain the order in which the overloaded operators run. Then answer: why would the expression 2 * b not compile here, and what change fixes it? (10 marks) [Ch 02]
#include <iostream>
using namespace std;

class Vec {
public:
    int x, y;
    Vec(int x = 0, int y = 0) : x(x), y(y) {}
    Vec operator+(const Vec &o) { return Vec(x + o.x, y + o.y); }
    Vec operator*(int k)        { return Vec(x * k, y * k); }
    Vec& operator++()           { x++; y++; return *this; }
};

int main() {
    Vec a(1, 2), b(3, 4);
    Vec c = a + b * 2;
    ++c;
    cout << c.x << " " << c.y << endl;
    return 0;
}
Show SolutionSolution দেখুন

Output: 8 11

  • Overloaded operators keep the normal precedence: * binds tighter than +. So a + b * 2 means a + (b * 2).
  • b * 2 calls b.operator*(2) → Vec(3×2, 4×2) = (6, 8).
  • a + (6, 8) calls a.operator+(...) → Vec(1+6, 2+8) = (7, 10), copied into c.
  • ++c calls the prefix operator++ → c becomes (8, 11). It returns *this by reference, the standard prefix style (a postfix version would take a dummy int parameter and return the old value by copy).

Why 2 * b fails: a member operator is called on the left operand. 2 * b would need 2.operator*(b) — but 2 is an int, not a Vec, and an int has no members. The compiler cannot convert the left side for a member call.

Fix: add a non-member (often friend) overload whose first parameter is the int:

friend Vec operator*(int k, const Vec &v) { return Vec(v.x * k, v.y * k); }

Now both b * 2 (member) and 2 * b (non-member) work. Rule: when the left operand is not your class, the operator must be a free function.

Q6. (a) Write \( \dfrac{1}{k(k+1)} \) as partial fractions. (b) Using that, evaluate \( \displaystyle\sum_{k=1}^{n} \frac{1}{k(k+1)} \) in closed form (telescoping), and compute the exact value for n = 99. (c) What does the sum approach as \( n \to \infty \)? Justify in one line. (10 marks) [Ch 03]
Show SolutionSolution দেখুন

(a) Set \( \frac{1}{k(k+1)} = \frac{A}{k} + \frac{B}{k+1} \). Then \( 1 = A(k+1) + Bk \). Put k = 0 → A = 1; put k = −1 → B = −1:

\[ \frac{1}{k(k+1)} = \frac{1}{k} - \frac{1}{k+1} \]

(b) The sum telescopes — every middle term cancels with its neighbour:

\[ \sum_{k=1}^{n}\left(\frac{1}{k} - \frac{1}{k+1}\right) = \left(1 - \tfrac{1}{2}\right) + \left(\tfrac{1}{2} - \tfrac{1}{3}\right) + \cdots + \left(\tfrac{1}{n} - \tfrac{1}{n+1}\right) = 1 - \frac{1}{n+1} = \frac{n}{n+1} \]

Only the very first term (1) and the very last term (−1/(n+1)) survive.

For n = 99: \( \dfrac{99}{100} = \mathbf{0.99} \). Quick check with n = 2: \( \frac{1}{1\cdot2} + \frac{1}{2\cdot3} = \frac{1}{2} + \frac{1}{6} = \frac{2}{3} = \frac{2}{2+1} \) ✓.

(c) As \( n \to \infty \), \( \frac{1}{n+1} \to 0 \), so the sum approaches \( \mathbf{1} \). (An infinite series of positive terms that stays below 1 and gets arbitrarily close to it — a convergent series with sum exactly 1.)

Q7. A spam filter is trained on 10 emails: 4 spam and 6 ham (not spam). The word "free" appears in 3 of the spam emails and 1 of the ham emails. The word "meeting" appears in 0 of the spam emails and 3 of the ham emails. A new email contains both "free" and "meeting". (a) Show what goes wrong if you apply Naive Bayes with no smoothing. (b) Classify the email using Laplace (add-1) smoothing (each word is a yes/no feature, so add 2 to each denominator). (c) Compute the posterior probability of each class. (10 marks) [Ch 15]
Show SolutionSolution দেখুন

Priors: \( P(\text{spam}) = 4/10 = 0.4 \), \( P(\text{ham}) = 6/10 = 0.6 \).

(a) Zero-frequency problem. Without smoothing, \( P(\text{"meeting"}\mid\text{spam}) = 0/4 = 0 \). The whole spam score becomes \( 0.4 \times \frac{3}{4} \times 0 = 0 \) — one unseen word vetoes the class completely, no matter how spammy the rest of the email is. That is why raw counts are never used.

(b) With Laplace smoothing (add 1 to the count, add 2 to the denominator for a binary feature):

  • \( P(\text{free}\mid\text{spam}) = \frac{3+1}{4+2} = \frac{4}{6} = \frac{2}{3} \),   \( P(\text{meeting}\mid\text{spam}) = \frac{0+1}{4+2} = \frac{1}{6} \)
  • \( P(\text{free}\mid\text{ham}) = \frac{1+1}{6+2} = \frac{1}{4} \),   \( P(\text{meeting}\mid\text{ham}) = \frac{3+1}{6+2} = \frac{1}{2} \)

Naive Bayes multiplies (features assumed independent given the class):

\[ \text{score(spam)} = 0.4 \times \tfrac{2}{3} \times \tfrac{1}{6} = \tfrac{2}{45} \approx 0.0444 \qquad \text{score(ham)} = 0.6 \times \tfrac{1}{4} \times \tfrac{1}{2} = \tfrac{3}{40} = 0.075 \]

0.075 > 0.0444 → classify as ham. ("meeting" is strong ham evidence; "free" leans spam but not enough.)

(c) Normalize the two scores:

\[ P(\text{spam}\mid\text{email}) = \frac{0.0444}{0.0444 + 0.075} \approx 0.372, \qquad P(\text{ham}\mid\text{email}) \approx 0.628 \]

So the filter says ham with about 63% confidence — smoothing kept the decision sensible instead of collapsing to zero.

Q8. Given the tables:
Student(sid, name, dept)          Enrolled(sid, cid, grade)
(1, 'Rina',   'CSE')              (1, 'C101', 'A')
(2, 'Karim',  'EEE')              (1, 'C102', 'B')
(3, 'Salma',  'CSE')              (2, 'C101', 'A')
(4, 'Tanvir', 'ME')               (3, 'C102', 'A')
                                  (4, 'C103', 'B')
(a) Write an SQL query equivalent to the relational algebra expression \[ \pi_{name}\big( \sigma_{dept='CSE'}(Student) \bowtie \sigma_{grade='A'}(Enrolled) \big) \] and give its exact result on this data. (b) Write the relational algebra expression equivalent to SELECT DISTINCT dept FROM Student s JOIN Enrolled e ON s.sid = e.sid WHERE e.grade = 'B'; and give its result. (10 marks) [Ch 08]
Show SolutionSolution দেখুন

(a) The RA says: keep CSE students, keep A-grade enrollments, natural-join on sid, project the name. In SQL:

SELECT DISTINCT s.name
FROM   Student s JOIN Enrolled e ON s.sid = e.sid
WHERE  s.dept = 'CSE' AND e.grade = 'A';

(DISTINCT matches the set behavior of π.) Evaluate step by step:

  • CSE students: sid 1 (Rina), sid 3 (Salma).
  • A-grade rows: (1, C101), (2, C101), (3, C102).
  • Join on sid → sid 1 and sid 3 survive.

Result: Rina, Salma (2 rows). Karim has an A but is EEE; Tanvir is ME with a B.

(b) The SQL joins, filters grade = 'B', and projects dept. In relational algebra:

\[ \pi_{dept}\big( Student \bowtie \sigma_{grade='B'}(Enrolled) \big) \]

B-grade rows: (1, C102), (4, C103) → students 1 (CSE) and 4 (ME). Result: {CSE, ME}. Note π automatically removes duplicates, which is why the SQL needs DISTINCT to match — a favourite exam point about the bag-vs-set difference between SQL and relational algebra.

Q9. Merge sort runs on an array of n = 16 elements. (a) Draw or describe the recursion tree: how many levels does it have, and how many function calls in total? (b) Merging two runs of size s each needs at most 2s − 1 comparisons. Compute the worst-case total number of comparisons level by level for n = 16. (c) Use the tree to explain why merge sort is \( O(n \log n) \), and compare your count with bubble sort's worst case on the same 16 elements. (10 marks) [Ch 06]
Show SolutionSolution দেখুন

(a) The array halves each level: sizes 16 → 8 → 4 → 2 → 1. That is \( \log_2 16 = 4 \) levels of splitting, i.e. 5 levels of nodes counting the root. Calls: 1 + 2 + 4 + 8 + 16 = 31 calls (in general \( 2n - 1 \)).

(b) Count the merges bottom-up (a merge producing size 2s costs at most 2s − 1):

Level (result size)MergesCost eachTotal
2818
44312
82714
1611515
\[ 8 + 12 + 14 + 15 = \mathbf{49} \text{ comparisons (worst case)} \]

(c) Every level of the tree touches all n elements once, doing at most n comparisons per level, and there are \( \log_2 n \) merging levels → \( O(n \log n) \). Here: ≈ 16 × 4 = 64 is the rough bound and 49 is the exact worst case (each level is a bit under n because every merge saves at least one comparison).

Bubble sort worst case: \( \frac{n(n-1)}{2} = \frac{16 \times 15}{2} = 120 \) comparisons — about 2.4× worse at n = 16, and the gap explodes as n grows (for n = 1024: ~10 240 vs ~523 776).

Q10. Four processes all arrive at time 0 with CPU bursts — P1: 6, P2: 3, P3: 8, P4: 3. (a) Draw the Gantt chart and compute the average waiting time for non-preemptive SJF (break ties by process number). (b) Do the same for Round Robin with quantum 2 (ready queue order P1, P2, P3, P4). (c) SJF wins on average waiting time — so why do real interactive systems still use Round Robin? Support your answer with the first-response times from your two charts. (10 marks) [Ch 14]
Show SolutionSolution দেখুন

(a) SJF: shortest bursts first: P2 (3), P4 (3, tie → higher number after P2), P1 (6), P3 (8).

| P2 | P4 | P1   | P3     |
0    3    6     12       20

Waiting = start − arrival: P2 = 0, P4 = 3, P1 = 6, P3 = 12 → average = 21/4 = 5.25.

(b) RR, q = 2:

| P1 | P2 | P3 | P4 | P1 | P2 | P3 | P4 | P1 | P3 | P3 |
0    2    4    6    8   10   11   13   14   16   18   20

(P2 finishes at 11 using only 1 unit of its second slice; P4 finishes at 14.) Completion: P1 = 16, P2 = 11, P3 = 20, P4 = 14. Waiting = completion − burst (arrival 0): P1 = 10, P2 = 8, P3 = 12, P4 = 11 → average = 41/4 = 10.25.

(c) SJF nearly halves the average wait (5.25 vs 10.25), but look at first response (first time each process gets the CPU):

P1P2P3P4Worst
SJF6012312
RR02466

Under SJF the longest job (P3) sits untouched for 12 units — on a desktop that is a frozen app. RR guarantees every process is served within (n−1)q, gives smooth interactive response, and needs no knowledge of burst lengths (which SJF must predict). SJF also risks starvation of long jobs if short ones keep arriving. So: batch throughput → SJF; interactivity and fairness → RR.

Questions 11–20Questions 11–20

Q11. Consider the language \( L = \{ a^n b^{2n} : n \geq 0 \} \) — every string has twice as many b's as a's, with all a's first. (a) Argue carefully why no DFA can accept L. (b) Design a PDA for L: list its moves in words (what is pushed/popped on each input). (c) Trace your PDA on the string aabbbb, showing the stack at every step. (10 marks) [Ch 07]
Show SolutionSolution দেখুন

(a) A DFA has a fixed, finite number of states — say p of them. While it reads \( a^p \) it visits p + 1 states, so some state repeats (pigeonhole). That means two different prefixes \( a^i \) and \( a^j \) (i ≠ j) land in the same state, and from there the DFA treats them identically. But \( a^i b^{2i} \in L \) while \( a^j b^{2i} \notin L \) — the DFA must accept both or reject both, contradiction. Accepting L needs unbounded counting of the a's, which finite memory cannot do.

(b) PDA (accept by empty stack + end of input, start symbol Z on stack):

  • Reading an a (still in the a-phase): push two X's onto the stack.
  • Reading a b: pop one X. Once the first b is read, switch to the b-phase — any later a rejects (wrong order).
  • At end of input: accept iff only Z remains (every pushed X was matched by exactly one b). n = 0 (empty string) accepts immediately.

Each a deposits 2 tokens and each b spends 1, so acceptance forces #b = 2·#a — exactly L.

(c) Trace of aabbbb (stack shown top-first, Z at bottom):

Input readActionStack after
apush XXX X Z
apush XXX X X X Z
bpop XX X X Z
bpop XX X Z
bpop XX Z
bpop XZ

Input finished, stack back to Z → accept ✓. (For aabbb an X would remain → reject; for aabbbbb a b would find no X → reject.)

Q12. Using the Vigenère cipher with keyword CODE: (a) encrypt the message ATTACK, showing the letter-by-letter arithmetic (A = 0 … Z = 25). (b) Show the decryption of your ciphertext back to the message. (c) The plaintext letter T appears twice — what happens to it in the ciphertext, why does this make Vigenère stronger than a Caesar cipher, and what classical technique still breaks Vigenère? (10 marks) [Ch 10]
Show SolutionSolution দেখুন

(a) Repeat the key under the message and add mod 26 (\( C_i = (M_i + K_i) \bmod 26 \)):

MessageA (0)T (19)T (19)A (0)C (2)K (10)
KeyC (2)O (14)D (3)E (4)C (2)O (14)
Sum mod 26233→7224424
CipherCHWEEY

Ciphertext: CHWEEY

(b) Decrypt with \( M_i = (C_i - K_i) \bmod 26 \): C−C = 0→A; H−O = 7−14 = −7 ≡ 19→T; W−D = 22−3 = 19→T; E−E = 0→A; E−C = 2→C; Y−O = 24−14 = 10→K → ATTACK ✓.

(c) The two T's encrypt to different letters (H and W), because they line up with different key letters (O and D). A Caesar cipher shifts every letter by the same amount, so letter frequencies pass straight through — count the most common ciphertext letter and you have likely found E. Vigenère is polyalphabetic: it smears each plaintext letter over several ciphertext letters, flattening the frequency histogram.

It still falls to the Kasiski examination: repeated plaintext fragments that align with the same key position produce repeated ciphertext fragments; the distances between repeats reveal the key length m. Then the ciphertext splits into m interleaved Caesar ciphers, each broken by ordinary frequency analysis.

Q13. A circular queue is stored in an array of capacity 5 (indices 0–4), with front pointing to the first element, rear to the last, and a counter for size. Perform, in order: enqueue(A), enqueue(B), enqueue(C), enqueue(D), dequeue, dequeue, enqueue(E), enqueue(F), enqueue(G), dequeue. (a) Show the array, front, and rear after every operation. (b) Where exactly does the wraparound happen? (c) After all operations, is the queue full? Explain why circular queues need either a counter or one always-empty slot. (10 marks) [Ch 05]
Show SolutionSolution দেখুন

(a) Enqueue: rear = (rear + 1) % 5; dequeue: front = (front + 1) % 5. Dashes are free slots:

Operation01234frontrearsize
enqueue AA001
enqueue BAB012
enqueue CABC023
enqueue DABCD034
dequeue → ABCD133
dequeue → BCD232
enqueue ECDE243
enqueue FFCDE204
enqueue GFGCDE215
dequeue → CFGDE314

(b) At enqueue(F): rear was 4, and (4 + 1) % 5 = 0 — the rear pointer wraps from the end of the array back to index 0, reusing the slot A freed earlier. That reuse is the whole point of the circular design; a linear queue would have declared the array full despite two free slots.

(c) After enqueue(G) the queue was full (size 5); after the last dequeue it holds 4 elements (D, E, F, G from front to rear: indices 3, 4, 0, 1) — not full. The counter is needed because with pure pointers, full and empty look identical: both give front == (rear + 1) % 5 / coincident pointers depending on convention. The two standard fixes: keep a size counter (as here), or sacrifice one slot and call the queue full when (rear + 2) % capacity == front-style condition — either removes the ambiguity.

Q14. A paged system has a TLB with 10 ns access time, main memory with 100 ns access time, and a single-level page table stored in main memory. (a) Write the formula for the effective memory-access time (EAT) and compute it for a TLB hit ratio of 90%. (b) Recompute for a 98% hit ratio. (c) Compare both with the no-TLB case, and explain why a small TLB reaches such high hit ratios in practice. (10 marks) [Ch 13]
Show SolutionSolution দেখুন

On a TLB hit: TLB lookup + one memory access = 10 + 100 = 110 ns. On a miss: TLB lookup + page-table access + data access = 10 + 100 + 100 = 210 ns.

(a) With hit ratio h:

\[ EAT = h(10 + 100) + (1 - h)(10 + 200) \]

For h = 0.90: \( EAT = 0.9 \times 110 + 0.1 \times 210 = 99 + 21 = \mathbf{120 \text{ ns}} \).

(b) For h = 0.98: \( EAT = 0.98 \times 110 + 0.02 \times 210 = 107.8 + 4.2 = \mathbf{112 \text{ ns}} \).

(c) Without a TLB every access needs two memory trips (page table + data) = 200 ns. So the TLB gives speedup 200/120 ≈ 1.67 at 90% and 200/112 ≈ 1.79 at 98% — paging's overhead falls from 100% to about 12%. Note the EAT can never beat 110 ns: the TLB only removes the translation access, not the data access.

A TLB of just 64–512 entries hits so often because of locality of reference: a program spends long stretches inside a few pages (current code page, stack page, active data pages), so the same translations are used again and again. Each TLB entry covers a whole page (e.g. 4 KB), so a handful of entries covers the entire working set.

Q15. An online form takes an integer mark from 0 to 100 and prints a grade: 80–100 → A, 60–79 → B, 40–59 → C, 0–39 → F. Using black-box techniques: (a) list all equivalence classes (valid and invalid) and give one test value for each. (b) List the boundary-value tests. (c) Why do equivalence partitioning and boundary-value analysis together find more bugs than random testing with the same number of tests? Give a concrete off-by-one bug your boundary tests would catch. (10 marks) [Ch 11]
Show SolutionSolution দেখুন

(a) Equivalence classes — inputs the program should treat identically:

#ClassTypeSample testExpected
10–39valid25F
240–59valid50C
360–79valid70B
480–100valid90A
5below 0invalid−5error message
6above 100invalid150error message
7not an integerinvalid"abc" / 55.5error message

Seven classes → 7 tests cover every behavior once.

(b) Boundary values — each edge of each range, plus one step outside the valid domain:

  • Domain edges: −1, 0 and 100, 101
  • F/C edge: 39, 40  ·  C/B edge: 59, 60  ·  B/A edge: 79, 80

That is 10 focused tests: −1, 0, 39, 40, 59, 60, 79, 80, 100, 101.

(c) Random tests pile up in the middle of big ranges — dozens of values like 47, 52, 68 all exercise the same code path, adding no new information. EP guarantees every path is hit at least once, and BVA aims exactly where programmers err: comparison operators. Concrete catch: if the code says if (mark > 80) grade = 'A' instead of >=, every mid-range random test passes, but the boundary test mark = 80 returns B instead of A — bug found immediately. Same for 39/40, 59/60, and 100/101 (accepting 101 shows a missing upper check).

Q16. Consider this C function:
void f(int n) {
    if (n == 0) return;
    printf("%d ", n);
    f(n - 1);
    printf("%d ", n);
}
(a) What exactly does f(3) print? Trace the calls. (b) How many calls to f happen in total (count f(0) too)? (c) Describe the output of f(n) for a general n, and explain which printed half comes from the "winding" phase and which from the "unwinding" phase of the call stack. (10 marks) [Ch 01]
Show SolutionSolution দেখুন

(a) Output: 3 2 1 1 2 3

Trace (indent = recursion depth):

f(3): print 3 → call f(2)
  f(2): print 2 → call f(1)
    f(1): print 1 → call f(0)
      f(0): returns immediately
    f(1): print 1 → return
  f(2): print 2 → return
f(3): print 3 → return

(b) Calls: f(3), f(2), f(1), f(0) → 4 calls (in general n + 1).

(c) For general n the output is the palindrome:

\[ n,\ n-1,\ \ldots,\ 2,\ 1,\ 1,\ 2,\ \ldots,\ n-1,\ n \]

The descending half (n … 1) comes from the printf placed before the recursive call — it runs while the stack is winding up, each frame printing on its way in. The ascending half (1 … n) comes from the printf after the call — those statements are frozen on the stack and only run as the frames pop, i.e. while the stack is unwinding, in reverse order of creation (LIFO). This "code after the recursive call runs backwards" behavior is the standard exam trick — for example, it is exactly how you print a linked list or a number's binary digits in reverse.

Q17. A laptop (192.168.1.20/24, gateway 192.168.1.1) with empty DNS and ARP caches opens www.example.com in a browser. The configured DNS server is 8.8.8.8, and www.example.com resolves to 93.184.216.34. (a) List, in exact order, every protocol step from the click until the first TCP SYN leaves the laptop — name each protocol and what it asks/answers. (b) The laptop needs a MAC address at two points — whose MAC does it ARP for, and why never for 8.8.8.8's or 93.184.216.34's own MAC? (c) Which steps disappear when the user reloads the page a minute later, and thanks to which caches? (10 marks) [Ch 09]
Show SolutionSolution দেখুন

(a) In order:

  1. DNS cache check — empty, so the laptop must ask 8.8.8.8.
  2. Routing decision: 8.8.8.8 AND-ed with mask /24 gives 8.8.8.0 ≠ 192.168.1.0 → the DNS server is off-subnet → next hop is the gateway 192.168.1.1.
  3. ARP request (broadcast): "Who has 192.168.1.1? Tell 192.168.1.20." — sent to MAC ff:ff:ff:ff:ff:ff.
  4. ARP reply (unicast): the gateway answers with its MAC. The laptop stores it in the ARP cache.
  5. DNS query (UDP, port 53): frame has destination MAC = gateway's, but destination IP = 8.8.8.8. The gateway forwards it toward the Internet.
  6. DNS response: A record — www.example.com → 93.184.216.34. Cached with its TTL.
  7. TCP SYN to 93.184.216.34 port 443/80 — again off-subnet, again framed to the gateway's MAC (ARP cache hit this time, no new ARP).

(b) The laptop ARPs only for the gateway's MAC (both times a MAC is needed, it is the same gateway). ARP works by broadcast, and broadcasts do not cross routers — a link-layer address is only meaningful on the local segment. 8.8.8.8 and 93.184.216.34 sit on distant networks; their MACs would be useless here anyway, because each hop of the path rewrites the frame with the next hop's MAC while the IP addresses stay end-to-end. Rule: MAC = next hop, IP = final destination.

(c) On reload: steps 1 (lookup now hits the DNS cache, if TTL unexpired) and 3–4 (the ARP cache still holds the gateway's MAC) disappear. The laptop goes straight to the TCP connection — this is why the second visit to any site feels snappier.

Q18. A BCD adder adds two decimal digits stored in 4-bit BCD. (a) State the correction rule: exactly when must 0110 be added to the raw binary sum? (b) Work through 7 + 6 and 8 + 9 completely in binary, showing the raw sum, the correction, and the final BCD digit + carry for each. (c) Describe the hardware: how many 4-bit adders per digit, and write the Boolean expression that detects "correction needed" from the raw sum bits Z8 Z4 Z2 Z1 and carry K. (10 marks) [Ch 12]
Show SolutionSolution দেখুন

(a) Add 0110 (6) when the raw 4-bit sum is greater than 9 (1010–1111) or the 4-bit addition produced a carry out (sum ≥ 16). Reason: BCD skips the six codes 1010–1111, so crossing 9 must jump ahead by 6 to land on the right BCD digit.

(b) 7 + 6:

  0111   (7)
+ 0110   (6)
------
  1101   raw sum = 13 → invalid BCD (> 9), no carry
+ 0110   correction
------
1 0011   → carry 1, digit 0011

Result: carry 1, digit 3 → 13 ✓.

8 + 9:

  1000   (8)
+ 1001   (9)
------
1 0001   raw sum: carry K = 1, low nibble 0001 (raw value 17)
  0001
+ 0110   correction (because K = 1)
------
  0111   → digit 0111, carry stays 1

Result: carry 1, digit 7 → 17 ✓. Note the two cases trigger differently: 13 was caught by "> 9", 17 by "carry out" (its low nibble 0001 looks innocent).

(c) Per decimal digit: two 4-bit binary adders — the first adds the digits, the second adds 0000 or 0110 chosen by the correction signal. Detection: sums 10–15 have Z8 with Z4 or Z8 with Z2 set, so

\[ C = K + Z_8 Z_4 + Z_8 Z_2 \]

C is also the decimal carry to the next digit stage. (Check: 1101 → Z8Z4 = 1 ✓; 1010 → Z8Z2 = 1 ✓; 1001 = 9 → neither ✓; 17 → K = 1 ✓.)

Q19. Eight measurements of a server's response time (in ms) are: 4, 8, 6, 5, 3, 7, 9, 6. (a) Compute the mean, median, and mode. (b) Compute the population variance and standard deviation. (c) Compute the sample variance, and explain in one or two lines why it divides by n − 1 instead of n. (10 marks) [Ch 04]
Show SolutionSolution দেখুন

(a) Sum = 4 + 8 + 6 + 5 + 3 + 7 + 9 + 6 = 48 → mean = 48/8 = 6. Sorted: 3, 4, 5, 6, 6, 7, 8, 9 → n even, median = average of the 4th and 5th values = (6 + 6)/2 = 6. Mode = 6 (appears twice, all others once). All three equal — a nicely symmetric dataset.

(b) Squared deviations from the mean 6:

x48653796
(x−6)²44019190

Sum of squares = 28.

\[ \sigma^2 = \frac{28}{8} = 3.5, \qquad \sigma = \sqrt{3.5} \approx 1.87 \text{ ms} \]

(c) Sample variance:

\[ s^2 = \frac{28}{n - 1} = \frac{28}{7} = 4 \]

We divide by n − 1 (Bessel's correction) because the deviations are measured from the sample mean, which was itself computed from the same data — the data sit closer to their own mean than to the true population mean, so dividing by n would underestimate the real variance on average. Losing one degree of freedom (the mean is fixed by the data) and dividing by n − 1 makes \( s^2 \) an unbiased estimator.

Q20. A hash table of size m = 11 (slots 0–10) uses double hashing with \( h_1(k) = k \bmod 11 \) and \( h_2(k) = 7 - (k \bmod 7) \); the i-th probe is \( (h_1 + i \cdot h_2) \bmod 11 \). Insert the keys 14, 25, 36, 47, 58 in that order. (a) Show every probe for every key and the final table. (b) What probe sequence would linear probing have produced for the same keys, and what problem does that show? (c) Why must \( h_2(k) \) never be 0, and why is a prime table size important for double hashing? (10 marks) [Ch 05]
Show SolutionSolution দেখুন

(a) All five keys have \( h_1 = k \bmod 11 = 3 \) — a worst-case collision chain on slot 3:

Keyh1h2 = 7 − (k mod 7)ProbesPlaced at
1437 − 0 = 73 (free)3
2537 − 4 = 33 ✗ → (3+3) = 66
3637 − 1 = 63 ✗ → (3+6) = 99
4737 − 5 = 23 ✗ → (3+2) = 55
5837 − 2 = 53 ✗ → (3+5) = 88

Final table: slot 3 → 14, slot 5 → 47, slot 6 → 25, slot 8 → 58, slot 9 → 36 (others empty). Every colliding key resolved in just one extra probe.

(b) Linear probing tries 3, 4, 5, 6, … for every key: 14→3, 25→4, 36→5, 47→6, 58→7. The keys pile into the contiguous run 3–7: primary clustering. Every future key hashing anywhere into that run must scan to its end, and the cluster keeps growing — probe costs degrade badly. Double hashing avoids this because each key jumps with its own step size (7, 3, 6, 2, 5 here), scattering the chain across the table.

(c) If \( h_2 = 0 \), the probe sequence is \( h_1, h_1, h_1, \ldots \) — it never moves, an infinite loop on one slot; the formula 7 − (k mod 7) gives values 1–7, never 0, exactly to prevent that. The table size m should be prime (or at least coprime to every possible \( h_2 \)) so that stepping by \( h_2 \) visits all m slots before repeating: with gcd(h2, m) = 1 the sequence is a full cycle. If m = 12 and h2 = 4, only 3 slots would ever be probed and the insert could fail with the table nearly empty.

Questions 21–30Questions 21–30

Q21. (a) What is the output of this C++ program?
#include <iostream>
using namespace std;

class Box {
    int w;
public:
    Box(int w) : w(w) {}
    friend int wider(Box a, Box b);
};

int wider(Box a, Box b) {
    return (a.w > b.w) ? a.w : b.w;
}

int main() {
    Box p(3), q(7);
    cout << wider(p, q) << endl;
    return 0;
}
(b) Explain what a friend function is and why wider compiles even though w is private. Is wider a member of Box? (c) State whether friendship is mutual, inherited, or transitive, and give one classic situation where a friend function is the right design. (10 marks) [Ch 02]
Show SolutionSolution দেখুন

(a) Output: 7wider compares the private widths 3 and 7 directly and returns the larger.

(b) A friend function is a non-member function that a class explicitly grants access to its private and protected members. The declaration friend int wider(Box, Box); inside Box is that grant — it is the class's own decision, so encapsulation is loosened only where the class author chooses. wider is not a member: it is a free function (called as wider(p, q), not p.wider(q)), it has no this pointer, and the public:/private: label where the friend declaration sits is irrelevant.

(c) Friendship is:

  • Not mutual — Box trusting wider (or class A trusting B) gives Box no access back.
  • Not inherited — a class derived from Box does not inherit Box's friends, and a friend of a base is not a friend of the derived class.
  • Not transitive — a friend of my friend is a stranger.

Classic use: stream output, friend ostream& operator<<(ostream& os, const Box& b) — it cannot be a member of Box because the left operand is the stream, yet it needs Box's private data. Same story for symmetric binary operators like operator+ on two objects, or int * Vec style mixed-type operators.

Q22. A process references pages in the order 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5 under FIFO replacement. (a) Trace the faults with 3 frames. (b) Trace again with 4 frames. (c) Compare the two fault counts and name the phenomenon you just demonstrated. Why can it never happen with LRU? (10 marks) [Ch 14]
Show SolutionSolution দেখুন

(a) 3 frames (F = fault, H = hit; frames listed oldest → newest):

Ref123412512345
Frames11 21 2 32 3 43 4 14 1 21 2 51 2 51 2 52 5 35 3 45 3 4
F/HFFFFFFFHHFFH

9 faults (hits on the 1, 2 after 5 arrives, and on the final 5).

(b) 4 frames:

Ref123412512345
Frames11 21 2 31 2 3 41 2 3 41 2 3 42 3 4 53 4 5 14 5 1 25 1 2 31 2 3 42 3 4 5
F/HFFFFHHFFFFFF

10 faults — after page 5 evicts page 1, every following reference misses.

(c) More frames gave more faults (10 > 9): this is Belady's anomaly, and this reference string is the classic demonstration. Intuitively, with 4 frames FIFO kept the early pages "too long", so its eviction order fell exactly out of phase with the reuse pattern.

LRU cannot show the anomaly because it is a stack algorithm: at every instant, the set of pages LRU keeps in k frames (the k most recently used pages) is always a subset of what it would keep in k + 1 frames. A hit with k frames is therefore automatically a hit with k + 1 — fault counts can only stay equal or fall as memory grows. FIFO's content depends on arrival order, not recency, so the inclusion property fails.

Q23. Consider the classic "dangling else" grammar:
S → if E then S
S → if E then S else S
S → a
(a) Show that the string if E then if E then a else a is ambiguous by describing its two parse trees. (b) When an SLR/LR parser is built for this grammar, a conflict appears — name the conflict type, say exactly at which input symbol it occurs, and describe the parser's two competing actions. (c) How do real parsers (like C's) resolve it, and which of the two readings does that choose? (10 marks) [Ch 07]
Show SolutionSolution দেখুন

(a) Two readings of if E₁ then if E₂ then a else a:

  • Tree 1 (else with the inner if): S → if E₁ then [ if E₂ then a else a ]. The outer if has no else.
  • Tree 2 (else with the outer if): S → if E₁ then [ if E₂ then a ] else a. The inner if has no else.

Both are valid derivations of the same string — the grammar is ambiguous, and the two trees genuinely mean different programs (if E₁ is false, Tree 1 runs nothing while Tree 2 runs the else-branch).

(b) A shift–reduce conflict, occurring exactly when the lookahead is else. At that moment the parser has if E then S sitting on top of its stack (the inner if is complete) and must choose between:

  • Reduce by S → if E then S — close the inner if now, leaving the else for the outer if (Tree 2), or
  • Shift the else — keep growing the inner if into the longer production S → if E then S else S (Tree 1).

Since else ∈ FOLLOW(S) (an S can be followed by else in the second production), both actions land in the same table cell — SLR, LALR, and LR(1) all keep this conflict, because it comes from real ambiguity, not weak lookahead.

(c) Standard resolution: prefer shift over reduce for this conflict (Yacc/Bison's default, plus a suppressed warning). Shifting attaches each else to the nearest unmatched if — Tree 1 — which is exactly the rule C, C++, and Java define. (The alternative fix is rewriting the grammar into "matched"/"unmatched" statements, which is unambiguous but clumsier; languages like Python sidestep the issue with indentation, and others require explicit end if.)

Q24. Both a MAC (message authentication code) and a digital signature protect a message. Compare them fully: (a) how each is generated and verified, and with what kind of key; (b) a comparison table over integrity, authentication, non-repudiation, speed, and example algorithms; (c) two banks exchange transfer orders over a private shared key, while an e-commerce site needs customers' orders to be provable in court — which mechanism fits each case and, precisely, why can a MAC never give non-repudiation? (10 marks) [Ch 10]
Show SolutionSolution দেখুন

(a)

  • MAC: sender computes tag = MAC(K, message) with a shared symmetric key K and appends it. The receiver recomputes the tag with the same K and compares. Example: HMAC-SHA256.
  • Digital signature: sender hashes the message and encrypts the hash with their private key; anyone verifies by decrypting the signature with the sender's public key and comparing against a fresh hash. Example: RSA or DSA signatures.

(b)

PropertyMACDigital signature
Key typeone shared secret keyprivate/public key pair
IntegrityYesYes
AuthenticationYes (proves: someone with K)Yes (proves: the key owner)
Non-repudiationNoYes
Who can verifyonly holders of Kanyone with the public key
Speedfast (symmetric/hash ops)slow (public-key math, ~1000× )
ExamplesHMAC, CMACRSA-PSS, DSA, ECDSA

(c) The two banks already share K and trust each other's infrastructure — a MAC is the right fit: fast enough for thousands of orders per second and verifiable by the only party who matters (the other bank). The e-commerce site needs digital signatures: a customer's order signed with the customer's private key can be shown to a judge and verified with the public key.

Why a MAC can never give non-repudiation: the shared key K is held by both parties, and a valid tag only proves "someone holding K made this". The receiving bank could have forged the very tag it presents as evidence — so the sender can always plausibly deny it, and no third party can tell who computed it. A signature binds the message to the one private key that only the signer holds, which is exactly what a court needs.

Q25. A build system has five tasks with dependency edges A → C, B → C, C → D, C → E (X → Y means X must finish before Y). (a) Run Kahn's algorithm: give the in-degree table and show how the algorithm proceeds. (b) List every valid topological ordering and state the total count, explaining the counting. (c) A careless engineer adds the edge D → B. What happens to the topological sort, and how does Kahn's algorithm report it? (10 marks) [Ch 06]
Show SolutionSolution দেখুন

(a) In-degrees: A = 0, B = 0, C = 2 (from A, B), D = 1 (from C), E = 1 (from C).

  1. Queue starts with the zero in-degree nodes {A, B}. Remove one (say A): C drops to 1.
  2. Remove B: C drops to 0 → C enters the queue.
  3. Remove C: D and E both drop to 0 → both enter the queue.
  4. Remove D, then E (either order). All 5 nodes output → done.

One possible output: A, B, C, D, E.

(b) Structure of every valid order: A and B (in either order) must both precede C; D and E (in either order) must both follow C. With 5 positions, C is forced into the middle position, {A, B} fill the first two slots, {D, E} the last two:

\[ 2! \times 1 \times 2! = 4 \text{ orderings} \]
  • A, B, C, D, E
  • A, B, C, E, D
  • B, A, C, D, E
  • B, A, C, E, D

(Kahn's algorithm exposes the same count: 2 choices at step 1, then forced, then 2 choices after C.)

(c) D → B creates the cycle B → C → D → B: B needs to run before C, C before D, and now D before B — impossible, so no topological order exists (a topological sort is defined only for DAGs). Kahn's algorithm detects it cleanly: after outputting A, the remaining nodes B, C, D, E all have in-degree ≥ 1 (B now has in-degree 1 from D), the queue becomes empty, and the algorithm stops having output fewer than 5 nodes. "Output count < node count" is precisely Kahn's cycle report — which is how build tools print "circular dependency detected".

Q26. Consider the letters of the word DISCRETE. (a) How many distinct arrangements of all 8 letters are there? (b) In how many of them do the two E's stand next to each other? (c) In how many arrangements do all three vowels (I, E, E) stand together as one block? Show the reasoning for every count. (10 marks) [Ch 03]
Show SolutionSolution দেখুন

DISCRETE has 8 letters: D, I, S, C, R, E, T, E — the letter E repeats twice, everything else is distinct.

(a) Permutations of a multiset — divide by the repeats:

\[ \frac{8!}{2!} = \frac{40320}{2} = \mathbf{20160} \]

(Dividing by 2! kills the double-counting from swapping the two identical E's.)

(b) Glue the two E's into one block [EE]. Now we arrange 7 objects: [EE], D, I, S, C, R, T — all distinct (and the two E's inside the block are identical, so the block has only 1 internal arrangement):

\[ 7! = \mathbf{5040} \]

Sanity check: the fraction of arrangements with the E's together is 5040/20160 = 1/4 — and directly, the two E's occupy 2 of \( \binom{8}{2} = 28 \) position pairs, of which 7 are adjacent: 7/28 = 1/4 ✓.

(c) Glue I, E, E into one vowel block. Objects to arrange: [vowels], D, S, C, R, T = 6 distinct objects → 6! ways. Inside the block the three vowels arrange in \( \frac{3!}{2!} = 3 \) distinguishable ways (IEE, EIE, EEI):

\[ 6! \times \frac{3!}{2!} = 720 \times 3 = \mathbf{2160} \]

Pattern to remember: "together" → treat the group as one object, multiply by the group's internal arrangements, and keep dividing by factorials of identical letters.

Q27. A disk controller uses DMA with cycle stealing to move data into memory at 8000 bytes/second, one byte per steal. Each stolen memory cycle takes 1 µs, during which the CPU is held off the memory bus. (a) Explain what cycle stealing means and how it differs from burst-mode DMA. (b) Compute the fraction of CPU cycles stolen during a transfer (assume the CPU would otherwise use the bus every cycle). (c) With programmed I/O the CPU would spend 20 µs per byte on polling and copying. Compute that overhead, compare, and state the fundamental advantage of DMA. (10 marks) [Ch 13]
Show SolutionSolution দেখুন

(a) In cycle stealing, the DMA controller takes the memory bus for one cycle at a time, transfers one word/byte, and immediately returns the bus to the CPU — the CPU is delayed by single cycles, "stolen" between its own accesses, and barely notices. In burst mode, the DMA controller seizes the bus and moves a whole block back-to-back — faster for the device, but the CPU stalls for the entire burst. Cycle stealing suits slow-to-medium devices; burst mode suits fast ones (disk block into a full buffer).

(b) Stolen time per second = 8000 steals × 1 µs = 8000 µs = 8 ms. Fraction:

\[ \frac{8\,000 \times 1\,\mu s}{1\,\text{s}} = 0.008 = \mathbf{0.8\%} \]

The CPU loses under 1% of its cycles — effectively it runs at 99.2% speed while the transfer streams in the background.

(c) Programmed I/O cost = 8000 bytes × 20 µs = 160 000 µs = 0.16 s per second:

\[ 0.16 = \mathbf{16\%} \text{ of the CPU} \quad (20\times \text{ worse than DMA's } 0.8\%) \]

Fundamental advantage: DMA moves data without executing CPU instructions per byte — the CPU sets up the transfer once (address, count, direction), does useful work meanwhile, and takes a single interrupt when the whole block is done. Programmed I/O burns instruction cycles on every byte (poll status, read register, store, loop), so its overhead scales with the data rate and would swallow the CPU entirely for fast devices.

Q28. Two transactions run the following schedules on data items X and Y (r = read, w = write; the subscript is the transaction):

S1: r1(X), w1(X), r2(X), w2(X), r2(Y), w2(Y), r1(Y), w1(Y)

S2: r1(X), w1(X), r2(X), r1(Y), w2(X), w1(Y)

For each schedule: (a) list every conflicting pair of operations, (b) draw/describe the precedence graph, and (c) decide whether it is conflict-serializable, giving the equivalent serial order where one exists. (10 marks) [Ch 08]
Show SolutionSolution দেখুন

Two operations conflict when they belong to different transactions, touch the same item, and at least one is a write.

S1 — conflicts:

  • On X: r1(X)→w2(X), w1(X)→r2(X), w1(X)→w2(X) — all give edge T1 → T2.
  • On Y: r2(Y)→w1(Y), w2(Y)→r1(Y), w2(Y)→w1(Y) — all give edge T2 → T1.

Graph: T1 → T2 and T2 → T1 — a cycle. So S1 is not conflict-serializable: T1 must come before T2 (they fought over X in that order) but also after T2 (they fought over Y in the other order) — no serial order satisfies both. Intuitively, each transaction read the other's "middle" state.

S2 — conflicts:

  • On X: r1(X)→w2(X), w1(X)→r2(X), w1(X)→w2(X) — all edges T1 → T2.
  • On Y: only T1 touches Y (r1, w1) — no conflict.

Graph: a single edge T1 → T2 — acyclic. S2 is conflict-serializable, equivalent to the serial order T1, then T2. (Check: swapping the non-conflicting neighbours r1(Y) and w2(X) turns S2 into r1(X), w1(X), r1(Y), w1(Y)?, … — repeatedly swapping non-conflicting adjacent operations pushes all of T1 before all of T2, which is the definition of conflict equivalence.)

Method summary: precedence-graph test — build one node per transaction, add an edge Ti → Tj for every conflict where Ti acts first; the schedule is conflict-serializable iff the graph has no cycle, and any topological order of the graph is a valid equivalent serial schedule.

Q29. A perceptron outputs 1 when \( w_1x_1 + w_2x_2 + b \geq 0 \), else 0. (a) Show that the weights \( w_1 = w_2 = 0.6 \), \( b = -1 \) compute the AND function, by evaluating all four inputs. (b) Prove that no single perceptron can compute XOR, using the four inequalities the weights would have to satisfy. (c) A perceptron with \( w_1 = 0.1, w_2 = 0.6, b = -0.2 \) and learning rate \( \eta = 0.1 \) is being trained for AND and receives the sample \( x = (0, 1) \), target 0. Apply one step of the perceptron learning rule and give the updated weights. (10 marks) [Ch 15]
Show SolutionSolution দেখুন

(a)

x1x20.6x1 + 0.6x2 − 1OutputAND
00−100 ✓
10−0.400 ✓
01−0.400 ✓
110.211 ✓

All four rows match — the line \( 0.6x_1 + 0.6x_2 = 1 \) separates (1,1) from the other three points.

(b) Suppose weights \( w_1, w_2, b \) computed XOR. The four cases demand:

  • (0,0) → 0: \( b < 0 \)
  • (1,0) → 1: \( w_1 + b \geq 0 \)
  • (0,1) → 1: \( w_2 + b \geq 0 \)
  • (1,1) → 0: \( w_1 + w_2 + b < 0 \)

Add the middle two: \( w_1 + w_2 + 2b \geq 0 \), so \( w_1 + w_2 + b \geq -b \). Since \( b < 0 \), \( -b > 0 \), giving \( w_1 + w_2 + b > 0 \) — directly contradicting the fourth inequality. No weights exist: XOR's 1-points (1,0),(0,1) and 0-points (0,0),(1,1) sit on the diagonals of a square and no single straight line separates them (not linearly separable). This is why XOR needs a hidden layer — a multi-layer network.

(c) Forward pass: \( 0.1(0) + 0.6(1) - 0.2 = 0.4 \geq 0 \) → prediction \( \hat{y} = 1 \), but target t = 0 → error \( t - \hat{y} = -1 \). Update rule \( w_i \leftarrow w_i + \eta(t - \hat{y})x_i \), \( b \leftarrow b + \eta(t - \hat{y}) \):

  • \( w_1 = 0.1 + 0.1(-1)(0) = \mathbf{0.1} \) (unchanged — its input was 0)
  • \( w_2 = 0.6 + 0.1(-1)(1) = \mathbf{0.5} \)
  • \( b = -0.2 + 0.1(-1) = \mathbf{-0.3} \)

The step pushes the boundary the right way ((0,1) now scores 0.5 − 0.3 = 0.2, still wrong but closer to negative). Repeated passes keep shrinking it, and the perceptron convergence theorem guarantees a correct separator is reached — AND, unlike XOR, is linearly separable.

Q30. (a) Describe the V-model of software development and how it differs from the classic waterfall model, including the specific pairing between each development phase and its test level. (b) A company builds pacemaker firmware: requirements are fixed by medical regulators, and failures can kill. Which of the two models fits better, and why — name at least three concrete reasons. (c) State one weakness both models share, and which kind of project exposes it. (10 marks) [Ch 11]
Show SolutionSolution দেখুন

(a) The V-model bends waterfall's straight line into a V: development phases go down the left arm, testing phases climb the right arm, and each test level is planned against its mirror phase while that phase is still running:

Left arm (build)Right arm (verify)
User/business requirementsAcceptance testing
System requirementsSystem testing
Architecture (high-level design)Integration testing
Module (detailed) designUnit testing

Key difference from waterfall: waterfall treats testing as one late phase after coding; the V-model makes verification a parallel activity — acceptance criteria are written with the requirements, unit test cases with the module design. Defects in the requirements are caught while writing their tests, not months later, and every artifact has a defined check against it. The phase discipline (documents, sign-offs, no phase overlap) stays the same as waterfall.

(b) The V-model. Reasons:

  1. Requirements are stable and regulator-fixed — the model's main weakness (handling change) never bites, and its strength (rigor) pays fully.
  2. Traceability: regulators (e.g. IEC 62304 for medical software) demand proof that every requirement maps to design, code, and a passed test — the V's phase-to-test pairing produces exactly that evidence chain.
  3. Early test design reviews the requirements themselves: writing acceptance tests against "shock within 5 s of fibrillation detection" exposes vague or untestable requirements before any code exists — vital when a late defect is life-threatening.
  4. (Also: complete documentation for audits, and validation at every level rather than one big late test.)

(c) Shared weakness: both assume the requirements are known, complete, and frozen up front; working software appears only at the very end, and feedback arrives too late to steer. A project with fast-changing or initially unclear requirements — a consumer app or startup product hunting for market fit — exposes this immediately: by delivery time the requirements have moved. Such projects need iterative/agile models that ship small increments and absorb change every cycle.

How to grade yourself. For each question give yourself marks out of 10 like a real examiner:
  • ~4 marks for method — right formula, right approach, correct setup (tables, diagrams, definitions).
  • ~4 marks for correctness — the calculations and the final answer are right.
  • ~2 marks for clarity — steps shown in order, units and labels written, readable presentation.
Add everything up out of 300. A score of 200+ (about 67%) means you are strong and exam-ready in these topics; 150–200 means revise the chapters where you lost marks; below 150 means go back to those chapters, redo their practice questions, and retake the mock where you scored lowest. Be honest — a wrong final answer with a fully correct method still earns the method marks, but a lucky answer with no steps does not earn full marks.
নিজেকে কীভাবে grade করবেন। আসল examiner-এর মতো প্রতিটা প্রশ্নে ১০-এ marks দিন:
  • Method-এ ~৪ marks — ঠিক formula, ঠিক approach, ঠিক setup (table, diagram, definition)।
  • Correctness-এ ~৪ marks — calculation আর final answer ঠিক আছে কি না।
  • Clarity-তে ~২ marks — step-গুলো order-এ লেখা, unit আর label দেওয়া, presentation পরিষ্কার।
সব যোগ করে ৩০০-তে score বের করুন। ২০০+ (প্রায় ৬৭%) মানে আপনি strong আর এই topic-গুলোতে exam-ready; ১৫০–২০০ মানে যেসব chapter-এ marks হারিয়েছেন সেগুলো revise করুন; ১৫০-এর নিচে মানে সেই chapter-গুলোতে ফিরে গিয়ে practice question আবার করুন, আর যে mock-এ সবচেয়ে কম score পেয়েছেন সেটা আবার দিন। সৎ থাকুন — method পুরো ঠিক কিন্তু final answer ভুল হলে method-এর marks পাবেন, কিন্তু step ছাড়া lucky answer-এ full marks হয় না।