This chapter gives full model answers to all technical questions of three BIBM Assistant Programmer written exams. Solutions for maths, English, translation and Focus Writing are in separate chapters. The questions were compiled from candidates' memory, so some wording was incomplete. Where an interpretation had to be assumed, it is stated clearly in the answer.
1.1Combined 5 Bank — Assistant Programmer (03.02.2023)
| Item | Details |
|---|---|
| Date | 03.02.2023 |
| Set by | BIBM |
| Pattern | 80 MCQ (IT 75 + maths and GK 25); written 200 = IT 150 + 4 maths questions (20) + Focus 10 + translation B/E 20 |
| Topics | Heap, SQL join, UML class diagram, Function Point, array function, TLS, CRC, graph representation, browser security, LRU |
Extract-Root: Return the root (maximum value). Move the last element to the root and sift-down: swap with the larger child (children: 2i+1, 2i+2).
| Step | Operation | What happens | Heap (array) | Returned |
|---|---|---|---|---|
| a | Insert 5 | Heap is empty; 5 becomes the root | [5] | — |
| b | Insert 6 | 6 goes to the end; parent 5 < 6, so swap | [6, 5] | — |
| c | Insert 8 | 8 goes to index 2; parent 6 < 8, so swap | [8, 5, 6] | — |
| d | Extract-Root | 8 is removed; last element 6 moves to the root; child 5 < 6, so nothing changes | [6, 5] | 8 |
| e | Insert 4 | 4 goes to index 2; parent 6 > 4, so it stays | [6, 5, 4] | — |
| f | Insert 11 | 11 goes to index 3; swap with parent 5, then swap with root 6 | [11, 6, 4, 5] | — |
| g | Extract-Root | 11 is removed; 5 moves to the root; swap with the larger child 6 | [6, 5, 4] | 11 |
| h | Insert 7 | 7 goes to index 3; swap with parent 5, then swap with root 6 | [7, 6, 4, 5] | — |
| i | Extract-Root | 7 is removed; 5 moves to the root; swap with the larger child 6 | [6, 5, 4] | 7 |
| j | Extract-Root | 6 is removed; 4 moves to the root; child 5 > 4, so swap | [5, 4] | 6 |
Answer: The Extract-Root operations return 8, 11, 7, 6 in order. The heap finally holds [5, 4].
Logic: An S-record and a U-record are related only when a common T-record (tid) exists such that R has (sid, tid) and Q has (tid, uid). So join R and Q on tid.
-- Short form (R.sid and Q.uid are foreign keys, so joining S and U is optional)
SELECT R.sid, Q.uid
FROM R
JOIN Q ON R.tid = Q.tid;
-- Full form (also confirms that the records really exist in S and U)
SELECT S.sid, U.uid
FROM S
JOIN R ON S.sid = R.sid
JOIN Q ON R.tid = Q.tid
JOIN U ON Q.uid = U.uid;
"Composed of" means Composition (filled diamond ◆). The part cannot exist apart from the whole: if the book is deleted, its parts, chapters and sections are deleted too. Multiplicity is 1 on the whole side and 1..* on the part side ("several").
Write this explanation: (1) four classes and the attributes of each; (2) the relationships are composition, because a chapter exists only inside one part; (3) the multiplicity of every relationship is 1 → 1..*. You may also add operations, such as Book.addPart() or Chapter.getSections().
Step 1: FP = 180 × 0.87 = 156.6
Step 2: Assume "performance factor 4" means productivity, i.e. 4 FP per person-day.
Effort = 156.6 ÷ 4 = 39.15 ≈ 40 person-days
Logic: Treat the first element as min. Loop once over the remaining elements; if one is smaller than min, update min. Time O(n), extra space O(1).
/* C */
#include <stdio.h>
int findMin(int arr[], int n) {
int min = arr[0];
for (int i = 1; i < n; i++)
if (arr[i] < min)
min = arr[i];
return min;
}
int main(void) {
int a[] = {34, -7, 19, 0, 8};
int n = sizeof(a) / sizeof(a[0]);
printf("Smallest = %d\n", findMin(a, n));
return 0;
}
/* Output: Smallest = -7 */
// Java
public class MinFinder {
static int findMin(int[] arr) {
if (arr == null || arr.length == 0)
throw new IllegalArgumentException("empty");
int min = arr[0];
for (int i = 1; i < arr.length; i++)
if (arr[i] < min) min = arr[i];
return min;
}
public static void main(String[] args) {
int[] a = {34, -7, 19, 0, 8};
System.out.println("Smallest = " + findMin(a));
}
}
// Output: Smallest = -7
In C, passing an array actually passes a pointer, so the size (n) must be passed as a separate parameter. In Java, the size comes from arr.length.
The server proves "I am the real site" using the private key that pairs with the public key in its certificate. If this key is stolen, the attacker can do the following:
- Impersonate the server: Run a fake site with the genuine, valid certificate. If users are redirected there by DNS spoofing, ARP spoofing or a fake Wi-Fi, the browser shows no warning.
- Active Man-in-the-Middle: Sit between the client and the real server and terminate the TLS connection on both sides. The attacker can read passwords, OTPs and card numbers, and can change the amount or destination account of a transaction.
- Decrypt recorded traffic (passive): If the server uses RSA key exchange (a non-forward-secret cipher suite of TLS 1.2), the session key comes from the premaster secret sent by the client, encrypted with that public key. So previously recorded sessions and all future sessions can be decrypted.
If (EC)DHE is used (Forward Secrecy, mandatory in TLS 1.3), the private key is used only for signing in the handshake. Then past recorded traffic cannot be decrypted, but an active MitM (point 2) is still possible. - Sign in the server's name: If the same key was also used to sign something else (such as code or messages), the attacker can forge signatures in the server's name.
| Prevention and remedy | Why |
|---|---|
| Revoke the certificate immediately (CRL/OCSP) and generate a new key pair | The stolen key can no longer gain trust |
| Allow only ECDHE/TLS 1.3 | Ensures forward secrecy |
| Keep the private key in an HSM | The key cannot be extracted from the HSM |
| Certificate Transparency monitoring | Fake certificates get detected |
| Short-lived certificates, regular key rotation | Even if stolen, the damage window is short |
The generator has 11 bits, so its degree is r = 11 − 1 = 10 (the CRC remainder is 10 bits).
| Burst length L | Detection probability |
|---|---|
| L ≤ r | 100% (all detected) |
| L = r + 1 | 1 − (1/2)r−1 |
| L > r + 1 | 1 − (1/2)r |
Here L = 10 and r = 10, so L ≤ r. The highest and lowest (x0) bits of the generator are both 1, so every burst error is detected; detection probability = 1 (100%).
For comparison: if L = 11, probability = 1 − 1/29 ≈ 0.998; if L ≥ 12, probability = 1 − 1/210 ≈ 0.999.
| Aspect | Adjacency List | Adjacency Matrix |
|---|---|---|
| Space | O(V + E): good for sparse graphs | O(V²) |
| Find all neighbours of u | O(out-degree(u)) | O(V), must scan the whole row |
| Is edge (u, v) present? | O(out-degree(u)) | O(1) |
| BFS / DFS | O(V + E) | O(V²) |
| Find in-degree | O(V + E) | O(V), one column |
Faster with a list: In a sparse graph of 1 million nodes and 5 million edges (such as a bank customer transaction network), finding all reachable nodes by BFS/DFS, or counting the out-degree of every node. With a list this takes O(V + E); with a matrix, O(V²).
Faster with a matrix: Repeatedly asking "is there a direct edge from u to v?" (O(1) lookup), Floyd–Warshall all-pairs shortest path on a dense graph, or checking in O(V) time whether a vertex is a universal sink (in-degree V−1, out-degree 0).
This question is about the browser's frame navigation policy. Current browsers follow the Descendant Policy: a frame may navigate only its own descendant frames to another URL.
- Pixel delegation argument: If B is inside the display area of A, that part of the screen was given by A itself. A could already show its own content there, remove B, or draw something over it. So allowing A to navigate B to another origin gives A no new power and does not reduce security.
- Same-Origin Policy stays intact: By navigating, A cannot read B's DOM, cookies or data; it only decides what loads in B's place. So confidentiality is not broken.
- Risk of a permissive policy: If any frame could navigate any frame (permissive policy), an attacker frame could send a login or payment frame inside another site to a fake page (frame hijacking / Guninski attack). The user would see the address of the real site, but the data would go to the attacker.
- Hence the limit: "Whoever owns the screen controls it." A can change only frames inside its own area. It cannot change frames of other origins beside or above it.
In LRU (Least Recently Used), on a page fault the page that has not been used for the longest time is replaced. F = fault, H = hit.
| Ref | 1 | 2 | 3 | 4 | 2 | 3 | 4 | 1 | 2 | 1 | 1 | 3 | 1 | 4 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Frame 1 | 1 | 1 | 1 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 3 | 3 | 3 |
| Frame 2 | – | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| Frame 3 | – | – | 3 | 3 | 3 | 3 | 3 | 3 | 2 | 2 | 2 | 2 | 2 | 4 |
| F/H | F | F | F | F | H | H | H | F | F | H | H | F | H | F |
Replacement decisions:
- At ref 4, 1 is the oldest, so 1 is replaced.
- At ref 1 (8th), the order is 2, 3, 4 (2 is the oldest), so 2 is replaced.
- At ref 2 (9th), the order is 3, 4, 1, so 3 is replaced.
- At ref 3 (12th), the order is 4, 2, 1, so 4 is replaced.
- At ref 4 (14th), the order is 2, 3, 1, so 2 is replaced.
Answer: Page faults = 8, hits = 6; fault rate = 8/14 ≈ 57%.
1.2Bangladesh Bank — Assistant Programmer (03.02.2023)
| Item | Details |
|---|---|
| Date | 03.02.2023 (1 hour MCQ + 2 hours written) |
| Set by | BIBM |
| Pattern | 80 MCQ; written = 9 subjective questions (150) + 4 maths questions (20) + Focus (10) + translation B/E (20) |
| Topics | Hashing, graph representation, LCM program, SQL, UML, overriding/hiding, CIA and E2E encryption, Diffie-Hellman MitM |
| Key | h(k) = k mod 13 | Probe sequence | Final slot |
|---|---|---|---|
| 10 | 10 | 10 is empty | 10 |
| 3 | 3 | 3 is empty | 3 |
| 5 | 5 | 5 is empty | 5 |
| 6 | 6 | 6 is empty | 6 |
| 16 | 3 | 3 (occupied by 3) → 4 is empty | 4 |
| 17 | 4 | 4 (16) → 5 (5) → 6 (6) → 7 is empty | 7 |
| 19 | 6 | 6 (6) → 7 (17) → 8 is empty | 8 |
| Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Key | – | – | – | 3 | 16 | 5 | 6 | 17 | 19 | – | 10 | – | – |
Total collisions: 1 for 16, 3 for 17, 2 for 19, total 6. The continuous filled run from index 3 to 8 is an example of primary clustering, the main weakness of linear probing. Remedies are quadratic probing or double hashing. Load factor α = 7/13 ≈ 0.54.
With binary-heap numbering, the children of vertex i are 2i and 2i+1, and its parent is ⌊i/2⌋. The tree is treated as an undirected graph.
Adjacency List
1 → 2 → 3
2 → 1 → 4 → 5
3 → 1 → 6 → 7
4 → 2
5 → 2
6 → 3
7 → 3
If treated as directed (parent → child): 1→2,3; 2→4,5; 3→6,7; and the lists of 4–7 are empty.
Adjacency Matrix (symmetric)
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
|---|---|---|---|---|---|---|---|
| 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 2 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
| 3 | 1 | 0 | 0 | 0 | 0 | 1 | 1 |
| 4 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 5 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| 6 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
| 7 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Number of edges = V − 1 = 6. The list has 2 × 6 = 12 entries in total; the matrix has 7 × 7 = 49 cells, of which only 12 are 1. The tree is sparse, so the list saves more space here.
To avoid overflow, compute in the order (a / gcd) * b. This divides first, then multiplies.
/* C */
#include <stdio.h>
#include <stdlib.h>
long long gcd(long long a, long long b) {
while (b != 0) {
long long t = a % b;
a = b;
b = t;
}
return a;
}
int main(void) {
long long a, b;
printf("Enter A and B: ");
scanf("%lld %lld", &a, &b);
a = llabs(a); b = llabs(b);
if (a == 0 || b == 0) {
printf("LCM = 0\n");
return 0;
}
long long lcm = (a / gcd(a, b)) * b;
printf("LCM = %lld\n", lcm);
return 0;
}
/* Input: 12 18 -> LCM = 36 */
// Java
import java.util.Scanner;
public class LCM {
static long gcd(long a, long b) {
while (b != 0) {
long t = a % b;
a = b;
b = t;
}
return a;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long a = Math.abs(sc.nextLong());
long b = Math.abs(sc.nextLong());
long lcm = (a == 0 || b == 0) ? 0
: (a / gcd(a, b)) * b;
System.out.println("LCM = " + lcm);
}
}
// Input: 12 18 -> LCM = 36
Trace (12, 18): gcd(12, 18) → gcd(18, 12) → gcd(12, 6) → gcd(6, 0) = 6; LCM = 12/6 × 18 = 36. Time complexity O(log min(A, B)).
Logic: "Romantic comedy" means the same movie has two genres: Romance and Comedy. Each genre is in a separate row of HasGenre, so the two conditions cannot be matched in a single row.
-- Method 1: GROUP BY + HAVING (cleanest)
SELECT COUNT(*) AS romantic_comedy_count
FROM (
SELECT hg.mid
FROM HasGenre hg
JOIN Genres g ON g.gid = hg.gid
WHERE g.genre IN ('Romance', 'Comedy')
GROUP BY hg.mid
HAVING COUNT(DISTINCT g.genre) = 2
) AS rc;
-- Method 2: two IN subqueries
SELECT COUNT(*) AS romantic_comedy_count
FROM Movies m
WHERE m.mid IN (SELECT hg.mid FROM HasGenre hg JOIN Genres g ON g.gid = hg.gid
WHERE g.genre = 'Romance')
AND m.mid IN (SELECT hg.mid FROM HasGenre hg JOIN Genres g ON g.gid = hg.gid
WHERE g.genre = 'Comedy');
WHERE genre = 'Romance' AND genre = 'Comedy' always returns 0, because one row's genre cannot be two values at the same time. Writing OR also counts movies that are only romance or only comedy. If the database has a single genre named "Romantic Comedy", the simple WHERE g.genre = 'Romantic Comedy' is enough. State this assumption in your answer.
| Sentence | What it means in the model |
|---|---|
| "LAN consists of nodes; circular configuration" | LAN ◆— Node, composition, multiplicity 1 → 2..*; the ring is formed by a self-association |
| "Every node has a unique name and refers to its next node" | Node has name {unique}; self-association next, multiplicity 1 |
| "Different kinds of nodes" | Node is an abstract superclass; Workstation, Server and Printer are its subclasses (generalization) |
| "Workstations are originators of messages" | Workstation 1 —originates→ 0..* Packet |
| "Servers and printers can receive messages" | Server and Printer have a receive(p: Packet) operation |
| "Packets contain originator, destination and content" | Packet attributes or associations: originator (Workstation), destination (Node), content |
public class A {
public void m1() {}
public void m2() {}
public void m3(int i) {}
public void m4(String i) {}
}
public class B extends A {
public static void m1() {}
public void m2() {}
public void m3(int i) {}
public static void m4(String i) {}
}| Concept | Condition | When it is resolved |
|---|---|---|
| Overloading | Same name, different parameter list (in the same class or a subclass) | Compile time |
| Overriding | An instance method with the same signature in the subclass; the parent's method is also an instance method | Runtime (dynamic dispatch) |
| Hiding | Both parent and child methods are static, with the same signature | Compile time (based on the reference type) |
| Method | In A | In B | Result |
|---|---|---|---|
| m1() | instance | static | Compile error: "m1() in B cannot override m1() in A; overriding method is static". A static method cannot hide an instance method. |
| m2() | instance | instance, same signature | Overridden |
| m3(int) | instance | instance, same signature | Overridden |
| m4(String) | instance | static | Compile error (same reason as m1) |
Conclusion: m2 and m3 are overridden. m1 and m4 will not compile, so no hiding happens here. No method has a different parameter list, so there is no overloading either. Also fix two problems in the code: extends a must be extends A, and one .java file cannot contain two public classes, so put them in two separate files.
When hiding and overloading would occur: If A's m1 were public static void m1(), B's static m1() would hide it. If B had public void m3(double d), it would overload A's m3(int).
class A {
public static void s() { System.out.println("A.s"); }
public void m() { System.out.println("A.m"); }
}
class B extends A {
public static void s() { System.out.println("B.s"); } // hiding
@Override public void m(){ System.out.println("B.m"); } // overriding
public void m(int x) { System.out.println("B.m(int)"); } // overloading
}
public class Demo {
public static void main(String[] args) {
A ref = new B();
ref.m(); // B.m : at runtime, uses the object's type (B)
ref.s(); // A.s : at compile time, uses the reference's type (A), i.e. hiding
}
}
CIA Triad:
- Confidentiality: Unauthorized parties cannot read the information.
- Integrity: Information cannot be changed without authorization.
- Availability: Authorized users get the information when they need it.
End-to-end encryption (E2EE) mainly ensures confidentiality and, with a MAC or AEAD, integrity.
Answer: Application Layer (Layer 7).
| Layer | Example | Is it E2E? | Cost and maintenance |
|---|---|---|---|
| Network (L3) | IPsec | No; it protects host-to-host or gateway-to-gateway, not user-to-user | Needs OS and router configuration; needs experts |
| Transport (L4) | TLS | No; it is decrypted at every hop (server, proxy, load balancer), so the server sees plaintext | Easy, but does not meet the goal |
| Application (L7) | Signal Protocol, PGP, libsodium | Yes; only the sender's and receiver's apps hold the keys | Ready-made libraries; no network infrastructure change |
Reasons:
- Development time: Tested libraries (OpenSSL, libsodium, Bouncy Castle) can be used directly in the app code. No need to touch the kernel or network devices.
- Maintainability: The encryption logic stays inside the app. Nothing needs to change if the network, cloud provider or ISP changes, and updates ship like any normal software release.
- Development cost: No cost for special hardware (VPN concentrator) or for configuring every router.
- True end-to-end: Only at this layer can intermediate servers, even the company's own servers, not read the data. So confidentiality holds even if data leaks.
Limitations: it must be implemented separately in each app, and key management (key exchange, backup) must be designed carefully. In practice, TLS is also kept underneath Application-layer E2EE (defense in depth).
Core weakness: Basic Diffie-Hellman has no authentication. Nobody verifies that a received public key really belongs to the other party. Public values: prime q and primitive root α.
Attack steps (attacker Darth, as described by Stallings):
- Darth picks two private keys XD1 and XD2 and computes the matching public keys: YD1 = αXD1 mod q, YD2 = αXD2 mod q.
- Alice sends YA to Bob. Darth intercepts it, sends YD1 to Bob, and computes K2 = YAXD2 mod q.
- Bob receives YD1 and computes K1 = YD1XB mod q.
- Bob sends YB to Alice. Darth intercepts it, sends YD2 to Alice, and computes K1 = YBXD1 mod q.
- Alice receives YD2 and computes K2 = YD2XA mod q.
Result: Alice and Darth share the same key K2, and Bob and Darth share the same key K1. Alice and Bob think they share a secret key with each other. Darth can decrypt and read or modify every message, then re-encrypt it and forward it.
Darth: XD1 = 3 → YD1 = 125 mod 23 = 10 | XD2 = 7 → YD2 = 57 mod 23 = 17
Alice: K2 = 176 mod 23 = 12 | Darth: K2 = 87 mod 23 = 12 ✔
Bob: K1 = 1015 mod 23 = 5 | Darth: K1 = 193 mod 23 = 5 ✔
Without the attack, Alice and Bob would get the same key: 196 mod 23 = 815 mod 23 = 2.
Prevention:
- Authenticate the public keys: DH with digital signatures or certificates (Station-to-Station protocol, signed ECDHE in TLS).
- Compare key fingerprints over a separate channel (e.g. Signal's safety number).
- Use a pre-shared key or PKI.
1.3Combined 5 Bank (Job ID 10198) — Assistant Programmer (09.02.2024)
| Item | Details |
|---|---|
| Banks | Sonali Bank, BKB, Karmasangsthan Bank, ICB, etc. |
| Date | 09.02.2024 (1 hour MCQ + 2 hours written) |
| Question setter | BIBM |
| Type | 80 MCQ (IT 50 + Math and GK 20); written = 10 subjective (150) + 4 math (20) + Focus (20) + Letter (10) |
| Feature | Programming-heavy: 3 programs to write, 1 output to find, 3 SQL queries, then theory and a question about your own project |
Logic: x is prime if x ≥ 2 and no number from 2 to √x divides x. Using the loop condition d * d <= x avoids the need for a sqrt function. Each number costs O(√x), total O(n√n). For large n, the Sieve of Eratosthenes is faster: O(n log log n).
/* C */
#include <stdio.h>
int isPrime(int x) {
if (x < 2) return 0;
for (int d = 2; d * d <= x; d++)
if (x % d == 0) return 0;
return 1;
}
int main(void) {
int n;
printf("Enter n: ");
scanf("%d", &n);
printf("Primes between 1 and %d:\n", n);
for (int i = 2; i <= n; i++)
if (isPrime(i))
printf("%d ", i);
printf("\n");
return 0;
}
// Java
import java.util.Scanner;
public class Primes {
static boolean isPrime(int x) {
if (x < 2) return false;
for (int d = 2; d * d <= x; d++)
if (x % d == 0) return false;
return true;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter n: ");
int n = sc.nextInt();
for (int i = 2; i <= n; i++)
if (isPrime(i))
System.out.print(i + " ");
System.out.println();
}
}
Sample: Enter n: 30 → 2 3 5 7 11 13 17 19 23 29. 1 is not prime, so the loop starts at 2.
Pattern: The differences between adjacent terms are 1, 2, 3, 4, …. So each term is the previous term plus k (k = 1, 2, 3, …).
Check: t5 = 1 + 5·4/2 = 11 ✔; S5 = 5 + 4·5·6/6 = 5 + 20 = 25 = 1 + 2 + 4 + 7 + 11 ✔
/* C */
#include <stdio.h>
int main(void) {
int n;
long long term = 1, sum = 0;
printf("Enter n: ");
scanf("%d", &n);
for (int k = 1; k <= n; k++) {
printf("%lld%s", term, k < n ? " + " : "");
sum += term;
term += k; /* next term = term + k */
}
printf("\nSum = %lld\n", sum);
return 0;
}
// Java
import java.util.Scanner;
public class SeriesSum {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter n: ");
int n = sc.nextInt();
long term = 1, sum = 0;
for (int k = 1; k <= n; k++) {
System.out.print(term + (k < n ? " + " : ""));
sum += term;
term += k;
}
System.out.println("\nSum = " + sum);
// closed form check:
long f = n + (long)(n - 1) * n * (n + 1) / 6;
System.out.println("Formula = " + f);
}
}
Sample: n = 5 → 1 + 2 + 4 + 7 + 11, Sum = 25. For n = 7 the terms go up to 16 and 22, Sum = 63 (by formula 7 + 6·7·8/6 = 63 ✔).
1
01
101
0101
10101Pattern analysis: Row i has i digits. Odd rows start with 1 and even rows start with 0, then 1 and 0 alternate. Both rules combine into one: if (i + j) is even print 1, if odd print 0 (i and j counted from 1).
/* C */
#include <stdio.h>
int main(void) {
int n;
printf("Enter n: ");
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++)
printf("%d", (i + j) % 2 == 0 ? 1 : 0);
printf("\n");
}
return 0;
}
// Java
import java.util.Scanner;
public class BinaryFloyd {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
for (int i = 1; i <= n; i++) {
StringBuilder row = new StringBuilder();
for (int j = 1; j <= i; j++)
row.append((i + j) % 2 == 0 ? 1 : 0);
System.out.println(row);
}
}
}
Check: i = 1: j = 1 → 2 is even → "1". i = 2: 3 → 0, 4 → 1 → "01". i = 4: 5, 6, 7, 8 → "0101". Matches the sample in the question exactly ✔. If you want the usual number-based Floyd's triangle (1 / 2 3 / 4 5 6 …), keep a counter and write printf("%d ", c++) each time.
#include <stdio.h>
int fun(int i) {
if (i <= 0) return;
printf("%d, ", i--);
fun(--i);
printf("%d, ", i);
}
int main() {
fun(5);
}Remember: i-- (post-decrement) uses the value first, then decrements. --i (pre-decrement) decrements first, then uses the value. So in each call, i decreases by 2 in total. The second printf runs after the recursive call returns, so those values print in reverse order.
| Call | First printf | Change in i | Recursive call | Second printf after return |
|---|---|---|---|---|
| fun(5) | "5, " | i-- → 4, --i → 3 | fun(3) | "3, " (last) |
| fun(3) | "3, " | i-- → 2, --i → 1 | fun(1) | "1, " |
| fun(1) | "1, " | i-- → 0, --i → −1 | fun(−1) | "−1, " |
| fun(−1) | — | i ≤ 0, so it returns without printing anything | ||
Order: going down: 5, 3, 1 → fun(−1) returns → coming back up: −1 (fun(1)), 1 (fun(3)), 3 (fun(5)).
int fun() is a non-void function, yet return; has no value and there is no return at the end. In C99/C11 this is a constraint violation or a warning, but since the returned value is never used, most compilers (gcc) give a warning and still produce the output above. The "I", "Printf" and "Ø" in the question paper are OCR or typing errors; they are taken as i, printf and 0.
CREATE TABLE Department (DeptCode INT, DeptName VARCHAR(20), Location VARCHAR(20));
CREATE TABLE Employee (EmpCode INT, EmpFname VARCHAR(20), Salary INT,
Commission INT, DeptCode VARCHAR(20));
(a) Select every EmpFname with total salary (total salary = salary + commission). (b) Select EmpFname and Location of employees whose salary is greater than the average salary, ordered by EmpFname. (c) Select EmpFname and the count of employees, ordered by the employee count ascending.Schema correction (mention in the answer): The type of Employee's DeptCode should be INT, the same as Department's DeptCode, so that the join and foreign key work properly. In the original DDL there is no comma after Commission INT and there is an extra comma at the end; both are syntax errors.
CREATE TABLE Department (
DeptCode INT PRIMARY KEY,
DeptName VARCHAR(20),
Location VARCHAR(20)
);
CREATE TABLE Employee (
EmpCode INT PRIMARY KEY,
EmpFname VARCHAR(20),
Salary INT,
Commission INT,
DeptCode INT REFERENCES Department(DeptCode)
);
-- (a) Total salary; if Commission is NULL, treat it as 0
SELECT EmpFname,
Salary + COALESCE(Commission, 0) AS TotalSalary
FROM Employee;
-- (b) Name and Location of those who earn more than the average salary
SELECT e.EmpFname, d.Location
FROM Employee e
JOIN Department d ON e.DeptCode = d.DeptCode
WHERE e.Salary > (SELECT AVG(Salary) FROM Employee)
ORDER BY e.EmpFname;
-- (c) Number of employees for each EmpFname, in order of count
SELECT EmpFname, COUNT(EmpCode) AS EmpCount
FROM Employee
GROUP BY EmpFname
ORDER BY EmpCount ASC;
NULL + number = NULL, so without COALESCE (or IFNULL in MySQL, ISNULL in SQL Server), an employee with no commission would show a NULL total salary.(b):
AVG() cannot be used directly in WHERE, so a subquery is needed.(c): The question is ambiguous. If a non-aggregate column (EmpFname) is kept with an aggregate, it must be in GROUP BY. Above, it is taken as "how many employees share the same name". If the intent is the number of employees in each department:
SELECT d.DeptName, COUNT(e.EmpCode) AS EmpCount
FROM Department d LEFT JOIN Employee e ON e.DeptCode = d.DeptCode
GROUP BY d.DeptName
ORDER BY EmpCount ASC;
And to show the total number of employees beside each name, use a window function: SELECT EmpFname, COUNT(*) OVER () AS TotalEmp FROM Employee ORDER BY EmpCode;. Write your own interpretation in one line on the answer sheet.
| Aspect | Stack | Queue |
|---|---|---|
| Principle | LIFO (Last In First Out) | FIFO (First In First Out) |
| Ends | One end (top). Both insert and delete happen here | Two ends: insert at rear, delete at front |
| Operations | push, pop, peek | enqueue, dequeue, front |
| Pointer | top | front and rear |
| Complexity | push/pop O(1) | enqueue/dequeue O(1) (in a circular array or linked list) |
| Variants | — | Circular queue, priority queue, deque |
| Real-life example | A pile of plates | A line at a bank counter |
- Call stack for function calls and recursion, holding return addresses and local variables.
- Expression evaluation and infix → postfix conversion; checking balanced parentheses.
- (Extra) Undo/Redo, browser Back button, DFS.
- CPU scheduling (Round Robin ready queue) and printer spooling.
- BFS traversal; packet buffer in a network router.
- (Extra) Bank token system, message queues (RabbitMQ, Kafka).
Definition: Polymorphism (poly = many, morph = form) means using the same interface or name to get different behavior from objects of different types. It is one of the four pillars of OOP; the other three are encapsulation, inheritance and abstraction.
| Type | Other name | How | Binding |
|---|---|---|---|
| Compile-time | Static polymorphism | Method overloading (same name, different parameters); operator overloading in C++ | Early/static binding |
| Runtime | Dynamic polymorphism | Method overriding + upcasting (parent reference, child object); virtual functions in C++ | Late/dynamic binding |
| Parametric | Generics / Templates | Java's List<T>, C++ templates. The same code works with different types | Compile time |
// Compile-time: overloading
class Calculator {
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
int add(int a, int b, int c) { return a + b + c; }
}
// Runtime: overriding
abstract class Account {
abstract double interest(double balance);
}
class Savings extends Account {
@Override double interest(double b) { return b * 0.05; }
}
class FixedDeposit extends Account {
@Override double interest(double b) { return b * 0.09; }
}
public class Bank {
public static void main(String[] args) {
Calculator c = new Calculator();
System.out.println(c.add(2, 3)); // 5 (int version)
System.out.println(c.add(2.5, 3.5)); // 6.0 (double version)
Account[] list = { new Savings(), new FixedDeposit() };
for (Account a : list) // same call, different behavior
System.out.println(a.interest(10000)); // 500.0, 900.0
}
}
Benefits: Adding a new account type does not require changing Bank's loop (Open–Closed principle). Code becomes reusable and extensible.
In the ER model, a relationship is an association between two or more entities. It is classified in three ways.
(a) By cardinality (mapping)
| Type | Meaning | Example | Implementation in tables |
|---|---|---|---|
| One-to-One (1:1) | One record of A relates to at most one of B | Customer — NID; Employee — Desk | UNIQUE foreign key on either side |
| One-to-Many (1:N) | One record of A relates to many of B | Branch — Accounts; Department — Employees | Foreign key in the "many" side table |
| Many-to-One (N:1) | 1:N seen from the opposite side | Accounts — Branch | Same |
| Many-to-Many (M:N) | Many on both sides | Customer — Account (joint account); Student — Course | Junction (bridge) table, composite PK from the two FKs, like R and Q in Question 2 |
(b) By degree
- Unary (recursive): An entity is related to itself, e.g. Employee manages Employee, or Node next Node (token ring).
- Binary: Two entities, e.g. Customer holds Account. This is the most common.
- Ternary: Three entities together, e.g. Doctor–Patient–Medicine (prescribes), or Supplier–Part–Project.
(c) By participation
- Total (mandatory): Every record must take part in the relationship, e.g. every Loan must have a Borrower. In an ER diagram it is shown with a double line.
- Partial (optional): Not every record needs to take part, e.g. not every Customer has a Loan.
If "relation" means a table: base relation (stored table), view (virtual relation) and query result (derived relation). Add this in one line at the end of the answer if needed.
Model answer (adapt it to your own project):
1. Project overview: "Micro-Loan Management System" — a web application that manages loan applications, approval, installment collection and reports for an NGO or microfinance institution. About 50 field workers and 10 branch managers use it; about 20,000 customer records.
2. Technology and my role: Java (Spring Boot) REST API, MySQL, React frontend, Git and Docker. As backend developer, I built the database design, the installment calculation module and reporting. Work followed Agile (2-week sprints).
| Challenge | Cause | Solution |
|---|---|---|
| Same installment posted twice (double posting) | On a weak network, field workers pressed Submit repeatedly; concurrent requests | Used transactions (@Transactional) and row-level locks; an idempotency key on every payment; disabled the button after a click |
| Monthly report very slow (about 40 seconds) | Full table scan on large tables; N+1 queries | Analyzed with EXPLAIN; composite index on (branch_id, due_date); JOIN FETCH; summary table updated by a nightly batch. Time dropped below 2 seconds |
| Requirements kept changing | Interest rates and penalty rules differ by branch | Kept the rules in a configuration table instead of hard-coding them; took feedback with a demo at the end of every sprint |
| Security | Sensitive financial and personal data | Password hashing with bcrypt; role-based access (RBAC); prepared statements to prevent SQL injection; HTTPS; audit log |
| "It works on my PC but not on the server" in deployment | Environment differences | Docker image, CI pipeline (GitHub Actions) and automated unit and integration tests |
3. Result and lessons: A real-time dashboard replaced paper registers, and calculation errors fell to almost zero. Lessons: ensure data integrity (transactions, constraints) from the start, measure performance before optimizing, and keep regular communication with users. As a bank Assistant Programmer, this experience applies directly to building CBS-adjacent apps or internal tools.